Revision 6f7e9aec

b/Makefile.target
338 338
VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o mixeng.o
339 339
endif
340 340
ifeq ($(TARGET_BASE_ARCH), sparc)
341
VL_OBJS+= sun4m.o tcx.o lance.o iommu.o m48t08.o magic-load.o slavio_intctl.o slavio_timer.o slavio_serial.o fdc.o
341
VL_OBJS+= sun4m.o tcx.o lance.o iommu.o m48t08.o magic-load.o slavio_intctl.o slavio_timer.o slavio_serial.o fdc.o esp.o
342 342
endif
343 343
ifdef CONFIG_GDBSTUB
344 344
VL_OBJS+=gdbstub.o 
b/TODO
3 3
- debug option in 'configure' script + disable -fomit-frame-pointer
4 4
- Precise VGA timings for old games/demos (malc patch)
5 5
- merge PIC spurious interrupt patch
6
- merge VNC keyboard patch
7 6
- merge Solaris patch
8 7
- warning for OS/2: must not use 128 MB memory (merge bochs cmos patch ?)
9 8
- config file (at least for windows/Mac OS X)
b/hw/esp.c
1
/*
2
 * QEMU ESP emulation
3
 * 
4
 * Copyright (c) 2005 Fabrice Bellard
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
#include "vl.h"
25

  
26
/* debug ESP card */
27
#define DEBUG_ESP
28

  
29
#ifdef DEBUG_ESP
30
#define DPRINTF(fmt, args...) \
31
do { printf("ESP: " fmt , ##args); } while (0)
32
#else
33
#define DPRINTF(fmt, args...)
34
#endif
35

  
36
#define ESPDMA_REGS 4
37
#define ESPDMA_MAXADDR (ESPDMA_REGS * 4 - 1)
38
#define ESP_MAXREG 0x3f
39

  
40
typedef struct ESPState {
41
    BlockDriverState **bd;
42
    uint8_t regs[ESP_MAXREG];
43
    int irq;
44
    uint32_t espdmaregs[ESPDMA_REGS];
45
} ESPState;
46

  
47
static void esp_reset(void *opaque)
48
{
49
    ESPState *s = opaque;
50
    memset(s->regs, 0, ESP_MAXREG);
51
    s->regs[0x0e] = 0x4; // Indicate fas100a
52
    memset(s->espdmaregs, 0, ESPDMA_REGS * 4);
53
}
54

  
55
static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
56
{
57
    ESPState *s = opaque;
58
    uint32_t saddr;
59

  
60
    saddr = (addr & ESP_MAXREG) >> 2;
61
    switch (saddr) {
62
    default:
63
	break;
64
    }
65
    DPRINTF("esp: read reg[%d]: 0x%2.2x\n", saddr, s->regs[saddr]);
66
    return s->regs[saddr];
67
}
68

  
69
static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
70
{
71
    ESPState *s = opaque;
72
    uint32_t saddr;
73

  
74
    saddr = (addr & ESP_MAXREG) >> 2;
75
    DPRINTF("esp: write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->regs[saddr], val);
76
    switch (saddr) {
77
    case 3:
78
	// Command
79
	switch(val & 0x7f) {
80
	case 0:
81
	    DPRINTF("esp: NOP (%2.2x)\n", val);
82
	    break;
83
	case 2:
84
	    DPRINTF("esp: Chip reset (%2.2x)\n", val);
85
	    esp_reset(s);
86
	    break;
87
	case 3:
88
	    DPRINTF("esp: Bus reset (%2.2x)\n", val);
89
	    break;
90
	case 0x1a:
91
	    DPRINTF("esp: Set ATN (%2.2x)\n", val);
92
	    break;
93
	case 0x42:
94
	    DPRINTF("esp: Select with ATN (%2.2x)\n", val);
95
	    s->regs[4] = 0x1a; // Status: TCNT | TDONE | CMD
96
	    s->regs[5] = 0x20; // Intr: Disconnect, nobody there
97
	    s->regs[6] = 0x4;  // Seq: Cmd done
98
	    pic_set_irq(s->irq, 1);
99
	    break;
100
	}
101
	break;
102
    case 4 ... 7:
103
    case 9 ... 0xf:
104
	break;
105
    default:
106
	s->regs[saddr] = val;
107
	break;
108
    }
109
}
110

  
111
static CPUReadMemoryFunc *esp_mem_read[3] = {
112
    esp_mem_readb,
113
    esp_mem_readb,
114
    esp_mem_readb,
115
};
116

  
117
static CPUWriteMemoryFunc *esp_mem_write[3] = {
118
    esp_mem_writeb,
119
    esp_mem_writeb,
120
    esp_mem_writeb,
121
};
122

  
123
static uint32_t espdma_mem_readl(void *opaque, target_phys_addr_t addr)
124
{
125
    ESPState *s = opaque;
126
    uint32_t saddr;
127

  
128
    saddr = (addr & ESPDMA_MAXADDR) >> 2;
129
    return s->espdmaregs[saddr];
130
}
131

  
132
static void espdma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
133
{
134
    ESPState *s = opaque;
135
    uint32_t saddr;
136

  
137
    saddr = (addr & ESPDMA_MAXADDR) >> 2;
138
    s->espdmaregs[saddr] = val;
139
}
140

  
141
static CPUReadMemoryFunc *espdma_mem_read[3] = {
142
    espdma_mem_readl,
143
    espdma_mem_readl,
144
    espdma_mem_readl,
145
};
146

  
147
static CPUWriteMemoryFunc *espdma_mem_write[3] = {
148
    espdma_mem_writel,
149
    espdma_mem_writel,
150
    espdma_mem_writel,
151
};
152

  
153
static void esp_save(QEMUFile *f, void *opaque)
154
{
155
    ESPState *s = opaque;
156
    
157
}
158

  
159
static int esp_load(QEMUFile *f, void *opaque, int version_id)
160
{
161
    ESPState *s = opaque;
162
    
163
    if (version_id != 1)
164
        return -EINVAL;
165

  
166
    return 0;
167
}
168

  
169
void esp_init(BlockDriverState **bd, int irq, uint32_t espaddr, uint32_t espdaddr)
170
{
171
    ESPState *s;
172
    int esp_io_memory, espdma_io_memory;
173

  
174
    s = qemu_mallocz(sizeof(ESPState));
175
    if (!s)
176
        return;
177

  
178
    s->bd = bd;
179
    s->irq = irq;
180

  
181
    esp_io_memory = cpu_register_io_memory(0, esp_mem_read, esp_mem_write, s);
182
    cpu_register_physical_memory(espaddr, ESP_MAXREG*4, esp_io_memory);
183

  
184
    espdma_io_memory = cpu_register_io_memory(0, espdma_mem_read, espdma_mem_write, s);
185
    cpu_register_physical_memory(espdaddr, 16, espdma_io_memory);
186

  
187
    esp_reset(s);
188

  
189
    register_savevm("esp", espaddr, 1, esp_save, esp_load, s);
190
    qemu_register_reset(esp_reset, s);
191
}
192

  
b/hw/fdc.c
94 94
    uint8_t ro;               /* Is read-only           */
95 95
} fdrive_t;
96 96

  
97
#ifdef TARGET_SPARC
98
/* XXX: suppress those hacks */
99
#define DMA_read_memory(a,b,c,d)
100
#define DMA_write_memory(a,b,c,d)
101
void DMA_register_channel (int nchan,
102
                           DMA_transfer_handler transfer_handler,
103
                           void *opaque)
104
{
105
}
106
#define DMA_hold_DREQ(a)
107
#define DMA_release_DREQ(a)
108
#define DMA_get_channel_mode(a) (0)
109
#define DMA_schedule(a)
110
#endif
111

  
112 97
static void fd_init (fdrive_t *drv, BlockDriverState *bs)
113 98
{
114 99
    /* Drive */
......
423 408
    uint32_t retval;
424 409

  
425 410
    switch (reg & 0x07) {
411
#ifdef TARGET_SPARC
412
    case 0x00:
413
	// Identify to Linux as S82078B
414
	retval = fdctrl_read_statusB(fdctrl);
415
	break;
416
#endif
426 417
    case 0x01:
427 418
	retval = fdctrl_read_statusB(fdctrl);
428 419
	break;
......
577 568

  
578 569
static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status)
579 570
{
571
#ifdef TARGET_SPARC
572
    // Sparc mutation
573
    if (!fdctrl->dma_en) {
574
	fdctrl->state &= ~FD_CTRL_BUSY;
575
	fdctrl->int_status = status;
576
	return;
577
    }
578
#endif
580 579
    if (~(fdctrl->state & FD_CTRL_INTR)) {
581 580
        pic_set_irq(fdctrl->irq_lvl, 1);
582 581
        fdctrl->state |= FD_CTRL_INTR;
......
980 979
        len = dma_len - fdctrl->data_pos;
981 980
        if (len + rel_pos > FD_SECTOR_LEN)
982 981
            len = FD_SECTOR_LEN - rel_pos;
983
        FLOPPY_DPRINTF("copy %d bytes (%d %d %d) %d pos %d %02x %02x "
984
                       "(%d-0x%08x 0x%08x)\n", len, size, fdctrl->data_pos,
982
        FLOPPY_DPRINTF("copy %d bytes (%d %d %d) %d pos %d %02x "
983
                       "(%d-0x%08x 0x%08x)\n", len, dma_len, fdctrl->data_pos,
985 984
                       fdctrl->data_len, fdctrl->cur_drv, cur_drv->head,
986 985
                       cur_drv->track, cur_drv->sect, fd_sector(cur_drv),
987
                       fd_sector(cur_drv) * 512, addr);
986
                       fd_sector(cur_drv) * 512);
988 987
        if (fdctrl->data_dir != FD_DIR_WRITE ||
989 988
	    len < FD_SECTOR_LEN || rel_pos != 0) {
990 989
            /* READ & SCAN commands and realign to a sector for WRITE */
......
1045 1044
	    FLOPPY_DPRINTF("seek to next sector (%d %02x %02x => %d) (%d)\n",
1046 1045
			   cur_drv->head, cur_drv->track, cur_drv->sect,
1047 1046
			   fd_sector(cur_drv),
1048
			   fdctrl->data_pos - size);
1047
			   fdctrl->data_pos - len);
1049 1048
            /* XXX: cur_drv->sect >= cur_drv->last_sect should be an
1050 1049
               error in fact */
1051 1050
            if (cur_drv->sect >= cur_drv->last_sect ||
b/hw/sun4m.c
36 36
// IRQs are not PIL ones, but master interrupt controller register
37 37
// bits
38 38
#define PHYS_JJ_IOMMU	0x10000000	/* I/O MMU */
39
#define PHYS_JJ_TCX_FB	0x50800000	/* Start address, frame buffer body */
39
#define PHYS_JJ_TCX_FB	0x50000000	/* TCX frame buffer */
40
#define PHYS_JJ_ESPDMA  0x78400000      /* ESP DMA controller */
41
#define PHYS_JJ_ESP     0x78800000      /* ESP SCSI */
42
#define PHYS_JJ_ESP_IRQ    18
40 43
#define PHYS_JJ_LEDMA   0x78400010      /* Lance DMA controller */
41 44
#define PHYS_JJ_LE      0x78C00000      /* Lance ethernet */
42 45
#define PHYS_JJ_LE_IRQ     16
......
50 53
#define PHYS_JJ_MS_KBD_IRQ    14
51 54
#define PHYS_JJ_SER	0x71100000	/* Serial */
52 55
#define PHYS_JJ_SER_IRQ    15
53
#define PHYS_JJ_SCSI_IRQ   18
54 56
#define PHYS_JJ_FDC	0x71400000	/* Floppy */
55 57
#define PHYS_JJ_FLOPPY_IRQ 22
56 58

  
......
61 63
    return qemu_get_clock(vm_clock);
62 64
}
63 65

  
64
void DMA_run() {}
66
int DMA_get_channel_mode (int nchan)
67
{
68
    return 0;
69
}
70
int DMA_read_memory (int nchan, void *buf, int pos, int size)
71
{
72
    return 0;
73
}
74
int DMA_write_memory (int nchan, void *buf, int pos, int size)
75
{
76
    return 0;
77
}
78
void DMA_hold_DREQ (int nchan) {}
79
void DMA_release_DREQ (int nchan) {}
80
void DMA_schedule(int nchan) {}
81
void DMA_run (void) {}
82
void DMA_init (int high_page_enable) {}
83
void DMA_register_channel (int nchan,
84
                           DMA_transfer_handler transfer_handler,
85
                           void *opaque)
86
{
87
}
88

  
89
static void nvram_set_word (m48t08_t *nvram, uint32_t addr, uint16_t value)
90
{
91
    m48t08_write(nvram, addr++, (value >> 8) & 0xff);
92
    m48t08_write(nvram, addr++, value & 0xff);
93
}
94

  
95
static void nvram_set_lword (m48t08_t *nvram, uint32_t addr, uint32_t value)
96
{
97
    m48t08_write(nvram, addr++, value >> 24);
98
    m48t08_write(nvram, addr++, (value >> 16) & 0xff);
99
    m48t08_write(nvram, addr++, (value >> 8) & 0xff);
100
    m48t08_write(nvram, addr++, value & 0xff);
101
}
102

  
103
static void nvram_set_string (m48t08_t *nvram, uint32_t addr,
104
                       const unsigned char *str, uint32_t max)
105
{
106
    unsigned int i;
107

  
108
    for (i = 0; i < max && str[i] != '\0'; i++) {
109
        m48t08_write(nvram, addr + i, str[i]);
110
    }
111
    m48t08_write(nvram, addr + max - 1, '\0');
112
}
65 113

  
66 114
static m48t08_t *nvram;
67 115

  
68
static void nvram_init(m48t08_t *nvram, uint8_t *macaddr, const char *cmdline)
116
extern int nographic;
117

  
118
static void nvram_init(m48t08_t *nvram, uint8_t *macaddr, const char *cmdline,
119
		       int boot_device, uint32_t RAM_size,
120
		       uint32_t kernel_size,
121
		       int width, int height, int depth)
69 122
{
70 123
    unsigned char tmp = 0;
71 124
    int i, j;
72 125

  
73
    i = 0x40;
126
    // Try to match PPC NVRAM
127
    nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16);
128
    nvram_set_lword(nvram,  0x10, 0x00000001); /* structure v1 */
129
    // NVRAM_size, arch not applicable
130
    m48t08_write(nvram, 0x2F, nographic & 0xff);
131
    nvram_set_lword(nvram,  0x30, RAM_size);
132
    m48t08_write(nvram, 0x34, boot_device & 0xff);
133
    nvram_set_lword(nvram,  0x38, KERNEL_LOAD_ADDR);
134
    nvram_set_lword(nvram,  0x3C, kernel_size);
74 135
    if (cmdline) {
75
	uint32_t cmdline_len;
76

  
77 136
	strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
78
	m48t08_write(nvram, i++, CMDLINE_ADDR >> 24);
79
	m48t08_write(nvram, i++, (CMDLINE_ADDR >> 16) & 0xff);
80
	m48t08_write(nvram, i++, (CMDLINE_ADDR >> 8) & 0xff);
81
	m48t08_write(nvram, i++, CMDLINE_ADDR & 0xff);
82

  
83
	cmdline_len = strlen(cmdline);
84
	m48t08_write(nvram, i++, cmdline_len >> 24);
85
	m48t08_write(nvram, i++, (cmdline_len >> 16) & 0xff);
86
	m48t08_write(nvram, i++, (cmdline_len >> 8) & 0xff);
87
	m48t08_write(nvram, i++, cmdline_len & 0xff);
137
	nvram_set_lword(nvram,  0x40, CMDLINE_ADDR);
138
        nvram_set_lword(nvram,  0x44, strlen(cmdline));
88 139
    }
140
    // initrd_image, initrd_size passed differently
141
    nvram_set_word(nvram,   0x54, width);
142
    nvram_set_word(nvram,   0x56, height);
143
    nvram_set_word(nvram,   0x58, depth);
89 144

  
145
    // Sun4m specific use
90 146
    i = 0x1fd8;
91 147
    m48t08_write(nvram, i++, 0x01);
92 148
    m48t08_write(nvram, i++, 0x80); /* Sun4m OBP */
......
155 211
    char buf[1024];
156 212
    int ret, linux_boot;
157 213
    unsigned int i;
158
    unsigned long vram_size = 0x100000, prom_offset, initrd_size;
214
    long vram_size = 0x100000, prom_offset, initrd_size, kernel_size;
159 215

  
160 216
    linux_boot = (kernel_filename != NULL);
161 217

  
......
164 220

  
165 221
    iommu = iommu_init(PHYS_JJ_IOMMU);
166 222
    slavio_intctl = slavio_intctl_init(PHYS_JJ_INTR0, PHYS_JJ_INTR_G);
167
    tcx = tcx_init(ds, PHYS_JJ_TCX_FB, phys_ram_base + ram_size, ram_size, vram_size);
223
    tcx = tcx_init(ds, PHYS_JJ_TCX_FB, phys_ram_base + ram_size, ram_size, vram_size, graphic_width, graphic_height);
168 224
    lance_init(&nd_table[0], PHYS_JJ_LE_IRQ, PHYS_JJ_LE, PHYS_JJ_LEDMA);
169 225
    nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE);
170
    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline);
171 226
    slavio_timer_init(PHYS_JJ_CLOCK, PHYS_JJ_CLOCK_IRQ, PHYS_JJ_CLOCK1, PHYS_JJ_CLOCK1_IRQ);
172 227
    slavio_serial_ms_kbd_init(PHYS_JJ_MS_KBD, PHYS_JJ_MS_KBD_IRQ);
173 228
    slavio_serial_init(PHYS_JJ_SER, PHYS_JJ_SER_IRQ, serial_hds[0], serial_hds[1]);
174 229
    fdctrl_init(PHYS_JJ_FLOPPY_IRQ, 0, 1, PHYS_JJ_FDC, fd_table);
230
    esp_init(bs_table, PHYS_JJ_ESP_IRQ, PHYS_JJ_ESP, PHYS_JJ_ESPDMA);
175 231

  
176 232
    prom_offset = ram_size + vram_size;
177 233

  
......
189 245
    cpu_register_physical_memory(PROM_ADDR, (ret + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK, 
190 246
                                 prom_offset | IO_MEM_ROM);
191 247

  
248
    kernel_size = 0;
192 249
    if (linux_boot) {
193
        ret = load_elf(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
194
        if (ret < 0)
195
	    ret = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
196
	if (ret < 0)
197
	    ret = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
198
        if (ret < 0) {
250
        kernel_size = load_elf(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
251
        if (kernel_size < 0)
252
	    kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
253
	if (kernel_size < 0)
254
	    kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
255
        if (kernel_size < 0) {
199 256
            fprintf(stderr, "qemu: could not load kernel '%s'\n", 
200 257
                    kernel_filename);
201 258
	    exit(1);
......
222 279
	    }
223 280
        }
224 281
    }
282
    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, boot_device, ram_size, kernel_size, graphic_width, graphic_height, graphic_depth);
225 283
}
b/hw/tcx.c
1 1
/*
2
 * QEMU Sun4m System Emulator
2
 * QEMU TCX Frame buffer
3 3
 * 
4
 * Copyright (c) 2003-2004 Fabrice Bellard
4
 * Copyright (c) 2003-2005 Fabrice Bellard
5 5
 * 
6 6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 7
 * of this software and associated documentation files (the "Software"), to deal
......
25 25

  
26 26
#define MAXX 1024
27 27
#define MAXY 768
28
/*
29
 * Proll uses only small part of display, we need to switch to full
30
 * display when we get linux framebuffer console or X11 running. For
31
 * now it's just slower and awkward.
32
*/
33
#if 1
34
#define XSZ (8*80)
35
#define YSZ (24*11)
36
#define XOFF (MAXX-XSZ)
37
#define YOFF (MAXY-YSZ)
38
#else
39
#define XSZ MAXX
40
#define YSZ MAXY
41
#define XOFF 0
42
#define YOFF 0
43
#endif
28
#define TCX_DAC_NREGS 16
44 29

  
45 30
typedef struct TCXState {
46 31
    uint32_t addr;
47 32
    DisplayState *ds;
48 33
    uint8_t *vram;
49 34
    unsigned long vram_offset;
35
    uint16_t width, height;
50 36
    uint8_t r[256], g[256], b[256];
37
    uint8_t dac_index, dac_state;
51 38
} TCXState;
52 39

  
53 40
static void tcx_draw_line32(TCXState *s1, uint8_t *d, 
......
58 45

  
59 46
    for(x = 0; x < width; x++) {
60 47
	val = *s++;
61
	*d++ = s1->r[val];
62
	*d++ = s1->g[val];
63 48
	*d++ = s1->b[val];
49
	*d++ = s1->g[val];
50
	*d++ = s1->r[val];
64 51
	d++;
65 52
    }
66 53
}
......
73 60

  
74 61
    for(x = 0; x < width; x++) {
75 62
	val = *s++;
76
	*d++ = s1->r[val];
77
	*d++ = s1->g[val];
78 63
	*d++ = s1->b[val];
64
	*d++ = s1->g[val];
65
	*d++ = s1->r[val];
79 66
    }
80 67
}
81 68

  
......
104 91

  
105 92
    if (ts->ds->depth == 0)
106 93
	return;
107
    page = ts->vram_offset + YOFF*MAXX;
94
    page = ts->vram_offset;
108 95
    y_start = -1;
109 96
    page_min = 0x7fffffff;
110 97
    page_max = -1;
111 98
    d = ts->ds->data;
112
    s = ts->vram + YOFF*MAXX + XOFF;
99
    s = ts->vram;
113 100
    dd = ts->ds->linesize;
114 101
    ds = 1024;
115 102

  
......
128 115
	return;
129 116
    }
130 117
    
131
    for(y = 0; y < YSZ; y += 4, page += TARGET_PAGE_SIZE) {
118
    for(y = 0; y < ts->height; y += 4, page += TARGET_PAGE_SIZE) {
132 119
	if (cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG)) {
133 120
	    if (y_start < 0)
134 121
                y_start = y;
......
136 123
                page_min = page;
137 124
            if (page > page_max)
138 125
                page_max = page;
139
	    f(ts, d, s, XSZ);
126
	    f(ts, d, s, ts->width);
140 127
	    d += dd;
141 128
	    s += ds;
142
	    f(ts, d, s, XSZ);
129
	    f(ts, d, s, ts->width);
143 130
	    d += dd;
144 131
	    s += ds;
145
	    f(ts, d, s, XSZ);
132
	    f(ts, d, s, ts->width);
146 133
	    d += dd;
147 134
	    s += ds;
148
	    f(ts, d, s, XSZ);
135
	    f(ts, d, s, ts->width);
149 136
	    d += dd;
150 137
	    s += ds;
151 138
	} else {
152 139
            if (y_start >= 0) {
153 140
                /* flush to display */
154 141
                dpy_update(ts->ds, 0, y_start, 
155
                           XSZ, y - y_start);
142
                           ts->width, y - y_start);
156 143
                y_start = -1;
157 144
            }
158 145
	    d += dd * 4;
......
162 149
    if (y_start >= 0) {
163 150
	/* flush to display */
164 151
	dpy_update(ts->ds, 0, y_start, 
165
		   XSZ, y - y_start);
152
		   ts->width, y - y_start);
166 153
    }
167 154
    /* reset modified pages */
168 155
    if (page_max != -1) {
......
187 174
    
188 175
    qemu_put_be32s(f, (uint32_t *)&s->addr);
189 176
    qemu_put_be32s(f, (uint32_t *)&s->vram);
177
    qemu_put_be16s(f, (uint16_t *)&s->height);
178
    qemu_put_be16s(f, (uint16_t *)&s->width);
190 179
    qemu_put_buffer(f, s->r, 256);
191 180
    qemu_put_buffer(f, s->g, 256);
192 181
    qemu_put_buffer(f, s->b, 256);
182
    qemu_put_8s(f, &s->dac_index);
183
    qemu_put_8s(f, &s->dac_state);
193 184
}
194 185

  
195 186
static int tcx_load(QEMUFile *f, void *opaque, int version_id)
......
201 192

  
202 193
    qemu_get_be32s(f, (uint32_t *)&s->addr);
203 194
    qemu_get_be32s(f, (uint32_t *)&s->vram);
195
    qemu_get_be16s(f, (uint16_t *)&s->height);
196
    qemu_get_be16s(f, (uint16_t *)&s->width);
204 197
    qemu_get_buffer(f, s->r, 256);
205 198
    qemu_get_buffer(f, s->g, 256);
206 199
    qemu_get_buffer(f, s->b, 256);
200
    qemu_get_8s(f, &s->dac_index);
201
    qemu_get_8s(f, &s->dac_state);
207 202
    return 0;
208 203
}
209 204

  
......
219 214
    memset(s->vram, 0, MAXX*MAXY);
220 215
    cpu_physical_memory_reset_dirty(s->vram_offset, s->vram_offset + MAXX*MAXY,
221 216
                                    VGA_DIRTY_FLAG);
217
    s->dac_index = 0;
218
    s->dac_state = 0;
219
}
220

  
221
static uint32_t tcx_dac_readl(void *opaque, target_phys_addr_t addr)
222
{
223
    return 0;
224
}
225

  
226
static void tcx_dac_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
227
{
228
    TCXState *s = opaque;
229
    uint32_t saddr;
230

  
231
    saddr = (addr & (TCX_DAC_NREGS - 1)) >> 2;
232
    switch (saddr) {
233
    case 0:
234
	s->dac_index = val >> 24;
235
	s->dac_state = 0;
236
	break;
237
    case 1:
238
	switch (s->dac_state) {
239
	case 0:
240
	    s->r[s->dac_index] = val >> 24;
241
	    s->dac_state++;
242
	    break;
243
	case 1:
244
	    s->g[s->dac_index] = val >> 24;
245
	    s->dac_state++;
246
	    break;
247
	case 2:
248
	    s->b[s->dac_index] = val >> 24;
249
	default:
250
	    s->dac_state = 0;
251
	    break;
252
	}
253
	break;
254
    default:
255
	break;
256
    }
257
    return;
222 258
}
223 259

  
260
static CPUReadMemoryFunc *tcx_dac_read[3] = {
261
    tcx_dac_readl,
262
    tcx_dac_readl,
263
    tcx_dac_readl,
264
};
265

  
266
static CPUWriteMemoryFunc *tcx_dac_write[3] = {
267
    tcx_dac_writel,
268
    tcx_dac_writel,
269
    tcx_dac_writel,
270
};
271

  
224 272
void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base,
225
	      unsigned long vram_offset, int vram_size)
273
	       unsigned long vram_offset, int vram_size, int width, int height)
226 274
{
227 275
    TCXState *s;
276
    int io_memory;
228 277

  
229 278
    s = qemu_mallocz(sizeof(TCXState));
230 279
    if (!s)
......
233 282
    s->addr = addr;
234 283
    s->vram = vram_base;
235 284
    s->vram_offset = vram_offset;
285
    s->width = width;
286
    s->height = height;
236 287

  
237
    cpu_register_physical_memory(addr, vram_size, vram_offset);
288
    cpu_register_physical_memory(addr + 0x800000, vram_size, vram_offset);
289
    io_memory = cpu_register_io_memory(0, tcx_dac_read, tcx_dac_write, s);
290
    cpu_register_physical_memory(addr + 0x200000, TCX_DAC_NREGS, io_memory);
238 291

  
239 292
    register_savevm("tcx", addr, 1, tcx_save, tcx_load, s);
240 293
    qemu_register_reset(tcx_reset, s);
241 294
    tcx_reset(s);
242
    dpy_resize(s->ds, XSZ, YSZ);
295
    dpy_resize(s->ds, width, height);
243 296
    return s;
244 297
}
245 298

  
......
253 306
    f = fopen(filename, "wb");
254 307
    if (!f)
255 308
        return;
256
    fprintf(f, "P6\n%d %d\n%d\n", XSZ, YSZ, 255);
257
    d1 = s->vram + YOFF*MAXX + XOFF;
258
    for(y = 0; y < YSZ; y++) {
309
    fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
310
    d1 = s->vram;
311
    for(y = 0; y < s->height; y++) {
259 312
        d = d1;
260
        for(x = 0; x < XSZ; x++) {
313
        for(x = 0; x < s->width; x++) {
261 314
            v = *d;
262 315
            fputc(s->r[v], f);
263 316
            fputc(s->g[v], f);
b/pc-bios/proll.patch
1
diff -ruN proll_18.orig/Makefile proll-patch4/Makefile
1
diff -ruN proll_18.orig/Makefile proll-patch7/Makefile
2 2
--- proll_18.orig/Makefile	2002-09-13 14:16:59.000000000 +0000
3
+++ proll-patch4/Makefile	2004-11-13 15:50:49.000000000 +0000
3
+++ proll-patch7/Makefile	2004-11-13 15:50:49.000000000 +0000
4 4
@@ -4,6 +4,7 @@
5 5
 	make -C krups-ser    all
6 6
 	make -C espresso     all
......
14 14
 	make -C espresso     clean
15 15
 	make -C espresso-ser clean
16 16
+	make -C qemu clean
17
diff -ruN proll_18.orig/qemu/head.S proll-patch4/qemu/head.S
17
diff -ruN proll_18.orig/qemu/Makefile proll-patch7/qemu/Makefile
18
--- proll_18.orig/qemu/Makefile	1970-01-01 00:00:00.000000000 +0000
19
+++ proll-patch7/qemu/Makefile	2005-03-02 16:41:50.000000000 +0000
20
@@ -0,0 +1,122 @@
21
+#
22
+# proll:
23
+# qemu/Makefile - make PROLL for QEMU
24
+# $Id: proll.patch,v 1.3 2005-03-13 09:43:36 bellard Exp $
25
+#
26
+# Copyright 1999 Pete Zaitcev
27
+# This is Free Software is licensed under terms of GNU General Public License.
28
+#
29
+
30
+CC = gcc
31
+
32
+#CROSS = /usr/local/sparc/bin/sparc-sun-linux-
33
+CROSS = sparc-unknown-linux-gnu-
34
+
35
+CROSSCC = $(CROSS)gcc
36
+CROSSLD = $(CROSS)ld
37
+CROSSNM = $(CROSS)nm
38
+
39
+RM = /bin/rm -f
40
+ELFTOAOUT = elftoaout
41
+
42
+#
43
+SRC = ../src
44
+
45
+# Due to remapping algorithm PROLBASE should be algned on PMD.
46
+# We make PROLBASE a define instead of using _start because we
47
+# want to shift it to form a PGD entry. A relocatable label will not work.
48
+# Linux kernel expects us to be at LINUX_OPPROM_BEGVM <asm-sparc/openprom.h>.
49
+PROLBASE =   0xffd00000
50
+PROLRODATA = 0xffd07000
51
+PROLDATA =   0xffd09000
52
+PROLSIZE = 240*1024
53
+
54
+# Linux
55
+# Fixed %g6 is for arch/sparc/kernel/head.S, it seems ok w/o -ffixed-g6.
56
+# Kernel uses -fcall-used-g5 -fcall-used-g7, we probably do not need them.
57
+# __ANSI__ is supposed to be on by default but it is not.
58
+CFLAGS = -O2 -Wall -DPROLBASE=$(PROLBASE) -DPROLDATA=$(PROLDATA) -DPROLRODATA=$(PROLRODATA) -D__ANSI__=1 -I$(SRC) -mcpu=hypersparc -g -DQEMU
59
+ASFLAGS = -D__ASSEMBLY__ -I$(SRC) -DPROLRODATA=$(PROLRODATA) -DPROLDATA=$(PROLDATA) -DPROLSIZE=$(PROLSIZE) -g
60
+# Solaris or Linux/i386 cross compilation
61
+#CFLAGS = -Iinclude -O
62
+
63
+LDFLAGS = -N -Ttext $(PROLBASE) --section-start .rodata=$(PROLRODATA) -Tdata $(PROLDATA) -Tbss $(PROLDATA)
64
+
65
+ALL = proll.aout
66
+PROLLEXE = proll.elf
67
+
68
+OBJS = head.o wuf.o wof.o main.o $(CONSOLE) \
69
+ printf.o le.o system_qemu.o iommu.o \
70
+ arp.o netinit.o bootp.o packet.o tftp.o udp.o sched_4m.o openprom.o \
71
+ vconsole.o hconsole.o rconsole.o vcons_zs.o
72
+
73
+all:           $(ALL)
74
+
75
+$(PROLLEXE):   $(OBJS)
76
+	$(CROSSLD) $(LDFLAGS) -o $(PROLLEXE) $(OBJS)
77
+
78
+head.o:         head.S $(SRC)/phys_jj.h \
79
+  $(SRC)/asi.h $(SRC)/psr.h $(SRC)/crs.h
80
+	$(CROSSCC) $(ASFLAGS) -DPROLBASE=$(PROLBASE) -o $*.o -c $*.S
81
+
82
+main.o:         main.c $(SRC)/asi.h $(SRC)/pgtsrmmu.h $(SRC)/iommu.h \
83
+  $(SRC)/phys_jj.h $(SRC)/vconsole.h $(SRC)/version.h $(SRC)/general.h \
84
+  $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arpa.h $(SRC)/system.h
85
+	$(CROSSCC) $(CFLAGS) -c $*.c
86
+openprom.o:	openprom.c $(SRC)/openprom.h $(SRC)/general.h $(SRC)/romlib.h \
87
+  $(SRC)/vconsole.h $(SRC)/system.h $(SRC)/phys_jj.h
88
+	$(CROSSCC) $(CFLAGS) -c $*.c
89
+
90
+system_qemu.o:       system_qemu.c $(SRC)/vconsole.h $(SRC)/pgtsrmmu.h \
91
+  $(SRC)/timer.h $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/asi.h \
92
+  $(SRC)/netpriv.h $(SRC)/arpa.h $(SRC)/system.h $(SRC)/crs.h
93
+	$(CROSSCC) $(CFLAGS) -c $*.c
94
+iommu.o:        $(SRC)/iommu.c $(SRC)/pgtsrmmu.h $(SRC)/phys_jj.h $(SRC)/iommu.h \
95
+ $(SRC)/vconsole.h $(SRC)/general.h $(SRC)/romlib.h $(SRC)/system.h $(SRC)/asi.h
96
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
97
+vconsole.o:	$(SRC)/vconsole.c $(SRC)/vconsole.h $(SRC)/hconsole.h
98
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
99
+vcons_zs.o:	$(SRC)/vcons_zs.c $(SRC)/vconsole.h $(SRC)/system.h
100
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
101
+hconsole.o:	$(SRC)/hconsole.c $(SRC)/hconsole.h $(SRC)/rconsole.h $(SRC)/phys_jj.h
102
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
103
+rconsole.o:	$(SRC)/rconsole.c $(SRC)/rconsole.h
104
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
105
+printf.o:       $(SRC)/printf.c
106
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
107
+le.o:		$(SRC)/le.c $(SRC)/dma.h $(SRC)/system.h $(SRC)/netpriv.h $(SRC)/romlib.h $(SRC)/general.h $(SRC)/net.h $(SRC)/phys_jj.h
108
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
109
+
110
+arp.o:		$(SRC)/arp.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arp.h
111
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
112
+netinit.o:	$(SRC)/netinit.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arp.h $(SRC)/ip.h $(SRC)/udp.h
113
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
114
+tftp.o:		$(SRC)/tftp.c $(SRC)/general.h $(SRC)/net.h $(SRC)/arpa.h $(SRC)/romlib.h $(SRC)/tftp.h
115
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
116
+udp.o:		$(SRC)/udp.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arp.h $(SRC)/ip.h $(SRC)/udp.h
117
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
118
+packet.o:	$(SRC)/packet.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h
119
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
120
+sched_4m.o:	$(SRC)/sched_4m.c $(SRC)/system.h $(SRC)/general.h $(SRC)/romlib.h $(SRC)/phys_jj.h
121
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
122
+bootp.o:	$(SRC)/bootp.c $(SRC)/general.h $(SRC)/net.h \
123
+  $(SRC)/arpa.h $(SRC)/romlib.h $(SRC)/system.h $(SRC)/bootp.h
124
+	$(CROSSCC) $(CFLAGS) -DNOBPEXT=1 -c $(SRC)/$*.c
125
+
126
+wuf.o:		$(SRC)/wuf.S
127
+	$(CROSSCC) $(ASFLAGS) -o $*.o -c $(SRC)/$*.S
128
+wof.o:		$(SRC)/wof.S
129
+	$(CROSSCC) $(ASFLAGS) -o $*.o -c $(SRC)/$*.S
130
+
131
+#genlab.o:      genlab.c
132
+#	$(CC) -c $*.c
133
+#
134
+#genlab:        genlab.o
135
+#	$(CC) -o genlab genlab.o
136
+
137
+clean:
138
+	$(RM) $(OBJS)
139
+	$(RM) $(PROLLEXE) proll.aout
140
+
141
+proll.aout:	$(PROLLEXE)
142
+	$(ELFTOAOUT) -o proll.aout $(PROLLEXE)
143
diff -ruN proll_18.orig/qemu/head.S proll-patch7/qemu/head.S
18 144
--- proll_18.orig/qemu/head.S	1970-01-01 00:00:00.000000000 +0000
19
+++ proll-patch4/qemu/head.S	2004-11-13 15:50:49.000000000 +0000
20
@@ -0,0 +1,515 @@
145
+++ proll-patch7/qemu/head.S	2005-03-02 15:30:47.000000000 +0000
146
@@ -0,0 +1,539 @@
21 147
+/**
22 148
+ ** Standalone startup code for Linux PROM emulator.
23 149
+ ** Copyright 1999 Pete A. Zaitcev
24 150
+ ** This code is licensed under GNU General Public License.
25 151
+ **/
26 152
+/*
27
+ * $Id: proll.patch,v 1.2 2004-12-19 23:18:01 bellard Exp $
153
+ * $Id: proll.patch,v 1.3 2005-03-13 09:43:36 bellard Exp $
28 154
+ */
29 155
+
30 156
+#include <psr.h>
......
167 293
+_start:
168 294
+start:
169 295
+	.globl spill_window_entry, fill_window_entry
296
+
297
+#define	EXPORT_TRAP(trap) \
298
+	.globl trap; \
299
+	.type trap,function; \
300
+	.size trap, 16
301
+
302
+EXPORT_TRAP(t_zero)
303
+EXPORT_TRAP(t_wovf)
304
+EXPORT_TRAP(t_wunf)
305
+EXPORT_TRAP(t_irq1)
306
+EXPORT_TRAP(t_irq2)
307
+EXPORT_TRAP(t_irq3)
308
+EXPORT_TRAP(t_irq4)
309
+EXPORT_TRAP(t_irq5)
310
+EXPORT_TRAP(t_irq6)
311
+EXPORT_TRAP(t_irq7)
312
+EXPORT_TRAP(t_irq8)
313
+EXPORT_TRAP(t_irq9)
314
+EXPORT_TRAP(t_irq10)
315
+EXPORT_TRAP(t_irq11)
316
+EXPORT_TRAP(t_irq12)
317
+EXPORT_TRAP(t_irq13)
318
+EXPORT_TRAP(t_irq14)
319
+EXPORT_TRAP(t_irq15)
320
+
170 321
+C_LABEL(trapbase):
171 322
+t_zero:	b goprol; nop; nop; nop;
172 323
+t_tflt:	SRMMU_TFAULT                        /* Inst. Access Exception        */
......
294 445
+
295 446
+goprol:
296 447
+	! %g1 contains end of memory
448
+	set	PHYS_JJ_EEPROM + 0x30, %g1
449
+	lda	[%g1] ASI_M_BYPASS, %g1
297 450
+	! map PROLDATA to PROLBASE+PROLSIZE to end of ram
298 451
+	set	PROLSIZE+0x1000-PROLDATA+PROLBASE, %g2	! add 0x1000 for temp tables
299 452
+	sub	%g1, %g2, %g2			! start of private memory
......
397 550
+	bl	1b
398 551
+	 add	%o0, 0x4, %o0
399 552
+
400
+	sethi	%hi( C_LABEL(ram_size) ), %o0
401
+	st	%g3, [%o0 + %lo( C_LABEL(ram_size) )]
402
+
403 553
+	mov	2, %g1
404 554
+	wr	%g1, 0x0, %wim			! make window 1 invalid
405 555
+	WRITE_PAUSE
......
533 683
+C_LABEL(ldb_bypass):
534 684
+	retl
535 685
+	 lduba [%o0] ASI_M_BYPASS, %o0
536
diff -ruN proll_18.orig/qemu/main.c proll-patch4/qemu/main.c
686
diff -ruN proll_18.orig/qemu/main.c proll-patch7/qemu/main.c
537 687
--- proll_18.orig/qemu/main.c	1970-01-01 00:00:00.000000000 +0000
538
+++ proll-patch4/qemu/main.c	2004-11-23 19:05:34.000000000 +0000
539
@@ -0,0 +1,178 @@
688
+++ proll-patch7/qemu/main.c	2005-03-02 20:08:23.000000000 +0000
689
@@ -0,0 +1,173 @@
540 690
+/**
541 691
+ ** Proll (PROM replacement)
542 692
+ ** Copyright 1999 Pete Zaitcev
......
558 708
+#include <arpa.h>
559 709
+#include <system.h>		/* our own prototypes */
560 710
+
711
+void *init_openprom_qemu(int bankc, struct bank *bankv, unsigned hiphybas, const char *cmdline, char boot_device, int nographic);
712
+int vcon_zs_init(struct vconterm *t, unsigned int a0);
713
+int vcon_zs_write(struct vconterm *t, char *data, int leng);
714
+
561 715
+static void init_idprom(void);
562
+static void makepages_q(struct phym *t, unsigned int highbase);
563 716
+
564 717
+struct vconterm dp0;
565 718
+struct mem cmem;		/* Current memory, virtual */
......
567 720
+struct phym pmem;		/* Current phys. mem. */
568 721
+struct iommu ciommu;		/* Our IOMMU on sun4m */
569 722
+
570
+static char *hw_idprom;
571
+int ignore_fault, fault_ignored, ram_size;
723
+static struct {
724
+    const char id[16];
725
+    unsigned int version;
726
+    char pad1[0x1c]; // Pad to 0x30
727
+    unsigned int ram_size;
728
+    char boot_device;
729
+    unsigned int load_addr, kernel_size;
730
+    unsigned int cmdline, cmdline_len;
731
+    char pad2[0x0c]; // Pad to 0x54
732
+    unsigned short width, height, depth;
733
+} *hw_idprom;
734
+
735
+int ignore_fault, fault_ignored;
736
+void *printk_fn;
737
+unsigned int q_height, q_width;
572 738
+
573 739
+/*
574 740
+ */
575 741
+void prolmain()
576 742
+{
577
+	//static const char fname[14] = "00000000.PROL";
743
+	static char fname[14];
578 744
+	static struct banks bb;
579 745
+	unsigned int hiphybas;
580 746
+	const void *romvec;
747
+	unsigned int ram_size;
748
+	char nographic;
749
+
750
+	nographic = ldb_bypass(PHYS_JJ_EEPROM + 0x2F);
751
+	if (!nographic) {
752
+	    q_width = ldh_bypass(PHYS_JJ_EEPROM + 0x54);
753
+	    q_height = ldh_bypass(PHYS_JJ_EEPROM + 0x56);
754
+	    vcon_init(&dp0, PHYS_JJ_TCX_FB);
755
+	    printk_fn = vcon_write;
756
+	}
757
+	else {
758
+	    vcon_zs_init(&dp0, 0x71100000);
759
+	    printk_fn = vcon_zs_write;
760
+	}
761
+
581 762
+
582
+	vcon_init(&dp0, PHYS_JJ_TCX_FB);
583 763
+	printk("PROLL %s QEMU\n", PROLL_VERSION_STRING);
764
+	ram_size = ld_bypass(PHYS_JJ_EEPROM + 0x30);
584 765
+	printk("%d MB total\n", ram_size/(1024*1024));
585 766
+
586 767
+	bb.nbanks = 1;
......
590 771
+	hiphybas = ram_size - PROLSIZE;
591 772
+
592 773
+	mem_init(&cmem, (char *) &_end, (char *)(PROLBASE+PROLSIZE));
593
+	makepages_q(&pmem, hiphybas);
774
+	makepages(&pmem, hiphybas);
594 775
+	init_mmu_swift((unsigned int)pmem.pctp - PROLBASE + hiphybas);
595 776
+
596 777
+	mem_init(&cio, (char *)(PROLBASE+PROLSIZE),
......
601 782
+	/*
602 783
+	 */
603 784
+	init_idprom();
785
+	printk("NVRAM: id %s version %d\n", hw_idprom->id, hw_idprom->version);
786
+	if (!nographic)
787
+	    printk("Prom console: TCX %dx%d\n", q_width, q_height);
788
+	else
789
+	    printk("Prom console: serial\n");
604 790
+	sched_init();
605 791
+	le_probe();
606 792
+	init_net();
607 793
+
608
+#if 0
609
+#if 0 /* RARP */
610
+	if (rarp() != 0) fatal();
611
+	/* printrarp(); */
612
+	xtoa(myipaddr, fname, 8);
613
+	if (load(servaddr, fname) != 0) fatal();
614
+#else
615
+	if (bootp() != 0) fatal();
616
+	/*
617
+	 * boot_rec.bp_file cannot be used because system PROM
618
+	 * uses it to locate ourselves. If we load from boot_rec.bp_file,
619
+	 * we will loop reloading PROLL over and over again.
620
+	 * Thus we use traditional PROLL scheme HEXIPADDR.PROL (single L).
621
+	 */
622
+	xtoa(myipaddr, fname, 8);
623
+	if (load(boot_rec.bp_siaddr, fname) != 0) fatal();
624
+#endif
625
+#endif
794
+	printk("Boot device: %c\n", hw_idprom->boot_device);
795
+	if (hw_idprom->boot_device == 'n') {
796
+	    if (bootp() != 0) fatal();
797
+	    /*
798
+	     * boot_rec.bp_file cannot be used because system PROM
799
+	     * uses it to locate ourselves. If we load from boot_rec.bp_file,
800
+	     * we will loop reloading PROLL over and over again.
801
+	     * Thus we use traditional PROLL scheme HEXIPADDR.PROL (single L).
802
+	     */
803
+	    xtoa(myipaddr, fname, 8);
804
+	    fname[9] = '.';
805
+	    fname[10] = 'P';
806
+	    fname[11] = 'R';
807
+	    fname[12] = 'O';
808
+	    fname[13] = 'L';
809
+	    fname[14] = 0;
810
+	    
811
+	    if (load(boot_rec.bp_siaddr, fname) != 0) fatal();
812
+	}
626 813
+
627
+	romvec = init_openprom(bb.nbanks, bb.bankv, hiphybas);
814
+	romvec = init_openprom_qemu(bb.nbanks, bb.bankv, hiphybas,
815
+				    (void *)hw_idprom->cmdline, hw_idprom->boot_device, nographic);
628 816
+
629 817
+	printk("Memory used: virt 0x%x:0x%x[%dK] iomap 0x%x:0x%x\n",
630 818
+	    PROLBASE, (int)cmem.curp, ((unsigned) cmem.curp - PROLBASE)/1024,
631 819
+	    (int)cio.start, (int)cio.curp);
632
+	//set_timeout(5);  while (!chk_timeout()) { }  /* P3: let me read */
633 820
+
634 821
+	{
635
+	        void (*entry)(const void *, int, int, int, int) = (void (*)(const void*, int, int, int, int)) LOADBASE;
822
+	    void (*entry)(const void *, int, int, int, int) = (void *) hw_idprom->load_addr;
823
+		printk("Kernel loaded at 0x%x, size %dK, command line = '%s'\n",
824
+		       *entry, hw_idprom->kernel_size/1024, hw_idprom->cmdline);
636 825
+		entry(romvec, 0, 0, 0, 0);
637 826
+	}
638 827
+
......
652 841
+ */
653 842
+void udelay(unsigned long usecs)
654 843
+{
655
+	int i, n;
656
+	n = usecs*50;
657
+	for (i = 0; i < n; i++) { }
844
+    // Qemu hardware is perfect and does not need any delays!
658 845
+}
659 846
+
660 847
+static void init_idprom()
661 848
+{
662
+	char *va_prom;
849
+	void *va_prom;
663 850
+
664 851
+	if ((va_prom = map_io(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE)) == NULL) {
665 852
+		printk("init_idprom: cannot map eeprom\n");
......
673 860
+	hw_idprom = va_prom; 
674 861
+}
675 862
+
863
diff -ruN proll_18.orig/qemu/openprom.c proll-patch7/qemu/openprom.c
864
--- proll_18.orig/qemu/openprom.c	1970-01-01 00:00:00.000000000 +0000
865
+++ proll-patch7/qemu/openprom.c	2005-03-02 20:09:57.000000000 +0000
866
@@ -0,0 +1,646 @@
676 867
+/*
677
+ * Make CPU page tables.
678
+ * Returns pointer to context table.
679
+ * Here we ignore memory allocation errors which "should not happen"
680
+ * because we cannot print anything anyways if memory initialization fails.
868
+ * PROM interface support
869
+ * Copyright 1996 The Australian National University.
870
+ * Copyright 1996 Fujitsu Laboratories Limited
871
+ * Copyright 1999 Pete A. Zaitcev
872
+ * This software may be distributed under the terms of the Gnu
873
+ * Public License version 2 or later
681 874
+ */
682
+void makepages_q(struct phym *t, unsigned int highbase)
683
+{
684
+	unsigned int *ctp, *l1, pte;
685
+	int i;
686
+	unsigned int pa, va;
687 875
+
688
+	ctp = mem_zalloc(&cmem, NCTX_SWIFT*sizeof(int), NCTX_SWIFT*sizeof(int));
689
+	l1 = mem_zalloc(&cmem, 256*sizeof(int), 256*sizeof(int));
876
+#include <openprom.h>
877
+#include <general.h>
878
+#include <romlib.h>
879
+#include <system.h>
880
+#include <vconsole.h>
881
+#include "phys_jj.h"
690 882
+
691
+	pte = SRMMU_ET_PTD | (((unsigned int)l1 - PROLBASE + highbase) >> 4);
692
+	for (i = 0; i < NCTX_SWIFT; i++) {
693
+		ctp[i] = pte;
694
+	}
883
+//#define DEBUG_OBP
695 884
+
696
+	pa = PROLBASE;
697
+	for (va = PROLBASE; va < PROLDATA; va += PAGE_SIZE) {
698
+	        map_page(l1, va, pa, 0, highbase);
699
+		pa += PAGE_SIZE;
700
+	}
701
+	pa = highbase + PROLDATA - PROLBASE;
702
+	for (va = PROLDATA; va < PROLBASE + PROLSIZE; va += PAGE_SIZE) {
703
+		map_page(l1, va, pa, 0, highbase);
704
+		pa += PAGE_SIZE;
705
+	}
885
+struct property {
886
+	const char *name;
887
+	const char *value;
888
+	const int length;
889
+};
706 890
+
707
+	/* We need to start from LOADBASE, but kernel wants PAGE_SIZE. */
708
+	pa = 0;
709
+	for (va = 0; va < LOWMEMSZ; va += PAGE_SIZE) {
710
+		map_page(l1, va, pa, 0, highbase);
711
+		pa += PAGE_SIZE;
712
+	}
891
+struct node {
892
+	const struct property *properties;
893
+	/* short */ const int sibling;
894
+	/* short */ const int child;
895
+};
713 896
+
714
+	t->pctp = ctp;
715
+	t->pl1 = l1;
716
+	t->pbas = highbase;
717
+}
718
diff -ruN proll_18.orig/qemu/Makefile proll-patch4/qemu/Makefile
719
--- proll_18.orig/qemu/Makefile	1970-01-01 00:00:00.000000000 +0000
720
+++ proll-patch4/qemu/Makefile	2004-11-13 15:50:49.000000000 +0000
721
@@ -0,0 +1,119 @@
722
+#
723
+# proll:
724
+# qemu/Makefile - make PROLL for QEMU
725
+# $Id: proll.patch,v 1.2 2004-12-19 23:18:01 bellard Exp $
726
+#
727
+# Copyright 1999 Pete Zaitcev
728
+# This is Free Software is licensed under terms of GNU General Public License.
729
+#
897
+static int obp_nextnode(int node);
898
+static int obp_child(int node);
899
+static int obp_proplen(int node, char *name);
900
+static int obp_getprop(int node, char *name, char *val);
901
+static int obp_setprop(int node, char *name, char *val, int len);
902
+static const char *obp_nextprop(int node, char *name);
730 903
+
731
+CC = gcc
904
+static char obp_idprom[IDPROM_SIZE];
905
+static const struct property null_properties = { NULL, NULL, -1 };
906
+static const int prop_true = -1;
732 907
+
733
+#CROSS = /usr/local/sparc/bin/sparc-sun-linux-
734
+CROSS = sparc-unknown-linux-gnu-
908
+static const struct property propv_root[] = {
909
+	{"name",	"SUNW,JavaStation-1", sizeof("SUNW,JavaStation-1") },
910
+	{"idprom",	obp_idprom, IDPROM_SIZE},
911
+	{"banner-name", "JavaStation", sizeof("JavaStation")},
912
+	{"compatible",	"sun4m", 6},
913
+	{NULL, NULL, -1}
914
+};
735 915
+
736
+CROSSCC = $(CROSS)gcc
737
+CROSSLD = $(CROSS)ld
738
+CROSSNM = $(CROSS)nm
916
+static const int prop_iommu_reg[] = {
917
+	0x0, 0x10000000, 0x00000300,
918
+};
919
+static const struct property propv_iommu[] = {
920
+	{"name",	"iommu", sizeof("iommu")},
921
+	{"reg",		(char*)&prop_iommu_reg[0], sizeof(prop_iommu_reg) },
922
+	{NULL, NULL, -1}
923
+};
739 924
+
740
+RM = /bin/rm -f
741
+ELFTOAOUT = elftoaout
925
+static const int prop_sbus_ranges[] = {
926
+	0x0, 0x0, 0x0, 0x30000000, 0x10000000,
927
+	0x1, 0x0, 0x0, 0x40000000, 0x10000000,
928
+	0x2, 0x0, 0x0, 0x50000000, 0x10000000,
929
+	0x3, 0x0, 0x0, 0x60000000, 0x10000000,
930
+	0x4, 0x0, 0x0, 0x70000000, 0x10000000,
931
+};
932
+static const struct property propv_sbus[] = {
933
+	{"name",	"sbus", 5},
934
+	{"ranges",	(char*)&prop_sbus_ranges[0], sizeof(prop_sbus_ranges)},
935
+	{"device_type",	"hierarchical", sizeof("hierarchical") },
936
+	{NULL, NULL, -1}
937
+};
742 938
+
743
+#
744
+SRC = ../src
745
+
746
+# Due to remapping algorithm PROLBASE should be algned on PMD.
747
+# We make PROLBASE a define instead of using _start because we
748
+# want to shift it to form a PGD entry. A relocatable label will not work.
749
+# Linux kernel expects us to be at LINUX_OPPROM_BEGVM <asm-sparc/openprom.h>.
750
+PROLBASE =   0xffd00000
751
+PROLRODATA = 0xffd07000
752
+PROLDATA =   0xffd09000
753
+PROLSIZE = (240*1024)
754
+
755
+# Linux
756
+# Fixed %g6 is for arch/sparc/kernel/head.S, it seems ok w/o -ffixed-g6.
757
+# Kernel uses -fcall-used-g5 -fcall-used-g7, we probably do not need them.
758
+# __ANSI__ is supposed to be on by default but it is not.
759
+CFLAGS = -O2 -Wall -DPROLBASE=$(PROLBASE) -DPROLDATA=$(PROLDATA) -DPROLRODATA=$(PROLRODATA) -D__ANSI__=1 -I$(SRC) -mcpu=hypersparc -g
760
+ASFLAGS = -D__ASSEMBLY__ -I$(SRC) -DPROLRODATA=$(PROLRODATA) -DPROLDATA=$(PROLDATA) -DPROLSIZE=$(PROLSIZE) -g
761
+# Solaris or Linux/i386 cross compilation
762
+#CFLAGS = -Iinclude -O
763
+
764
+LDFLAGS = -N -Ttext $(PROLBASE) --section-start .rodata=$(PROLRODATA) -Tdata $(PROLDATA) -Tbss $(PROLDATA)
765
+
766
+ALL = proll.aout
767
+PROLLEXE = proll.elf
768
+
769
+OBJS = head.o wuf.o wof.o main.o vconsole.o hconsole.o rconsole.o \
770
+ printf.o le.o system.o iommu.o \
771
+ arp.o netinit.o bootp.o packet.o tftp.o udp.o sched_4m.o openprom.o
772
+
773
+all:           $(ALL)
774
+
775
+$(PROLLEXE):   $(OBJS)
776
+	$(CROSSLD) $(LDFLAGS) -o $(PROLLEXE) $(OBJS)
777
+
778
+head.o:         head.S $(SRC)/phys_jj.h \
779
+  $(SRC)/asi.h $(SRC)/psr.h $(SRC)/crs.h
780
+	$(CROSSCC) $(ASFLAGS) -DPROLBASE=$(PROLBASE) -o $*.o -c $*.S
781
+
782
+main.o:         main.c $(SRC)/asi.h $(SRC)/pgtsrmmu.h $(SRC)/iommu.h \
783
+  $(SRC)/phys_jj.h $(SRC)/vconsole.h $(SRC)/version.h $(SRC)/general.h \
784
+  $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arpa.h $(SRC)/system.h
785
+	$(CROSSCC) $(CFLAGS) -c $*.c
786
+openprom.o:	openprom.c $(SRC)/openprom.h $(SRC)/general.h $(SRC)/romlib.h \
787
+  $(SRC)/vconsole.h $(SRC)/system.h $(SRC)/phys_jj.h
788
+	$(CROSSCC) $(CFLAGS) -c $*.c
789
+
790
+system.o:       $(SRC)/system.c $(SRC)/vconsole.h $(SRC)/pgtsrmmu.h \
791
+  $(SRC)/timer.h $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/asi.h \
792
+  $(SRC)/netpriv.h $(SRC)/arpa.h $(SRC)/system.h $(SRC)/crs.h
793
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
794
+iommu.o:        $(SRC)/iommu.c $(SRC)/pgtsrmmu.h $(SRC)/phys_jj.h $(SRC)/iommu.h \
795
+ $(SRC)/vconsole.h $(SRC)/general.h $(SRC)/romlib.h $(SRC)/system.h $(SRC)/asi.h
796
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
797
+vconsole.o:	$(SRC)/vconsole.c $(SRC)/vconsole.h $(SRC)/hconsole.h
798
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
799
+hconsole.o:	$(SRC)/hconsole.c $(SRC)/hconsole.h $(SRC)/rconsole.h $(SRC)/phys_jj.h
800
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
801
+rconsole.o:	$(SRC)/rconsole.c $(SRC)/rconsole.h
802
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
803
+printf.o:       $(SRC)/printf.c
804
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
805
+le.o:		$(SRC)/le.c $(SRC)/dma.h $(SRC)/system.h $(SRC)/netpriv.h $(SRC)/romlib.h $(SRC)/general.h $(SRC)/net.h $(SRC)/phys_jj.h
806
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
807
+
808
+arp.o:		$(SRC)/arp.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arp.h
809
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
810
+netinit.o:	$(SRC)/netinit.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arp.h $(SRC)/ip.h $(SRC)/udp.h
811
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
812
+tftp.o:		$(SRC)/tftp.c $(SRC)/general.h $(SRC)/net.h $(SRC)/arpa.h $(SRC)/romlib.h $(SRC)/tftp.h
813
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
814
+udp.o:		$(SRC)/udp.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h $(SRC)/arp.h $(SRC)/ip.h $(SRC)/udp.h
815
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
816
+packet.o:	$(SRC)/packet.c $(SRC)/general.h $(SRC)/net.h $(SRC)/romlib.h $(SRC)/netpriv.h
817
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
818
+sched_4m.o:	$(SRC)/sched_4m.c $(SRC)/system.h $(SRC)/general.h $(SRC)/romlib.h $(SRC)/phys_jj.h
819
+	$(CROSSCC) $(CFLAGS) -c $(SRC)/$*.c
820
+bootp.o:	$(SRC)/bootp.c $(SRC)/general.h $(SRC)/net.h \
821
+  $(SRC)/arpa.h $(SRC)/romlib.h $(SRC)/system.h $(SRC)/bootp.h
822
+	$(CROSSCC) $(CFLAGS) -DNOBPEXT=1 -c $(SRC)/$*.c
823
+
824
+wuf.o:		$(SRC)/wuf.S
825
+	$(CROSSCC) $(ASFLAGS) -o $*.o -c $(SRC)/$*.S
826
+wof.o:		$(SRC)/wof.S
827
+	$(CROSSCC) $(ASFLAGS) -o $*.o -c $(SRC)/$*.S
828
+
829
+#genlab.o:      genlab.c
830
+#	$(CC) -c $*.c
831
+#
832
+#genlab:        genlab.o
833
+#	$(CC) -o genlab genlab.o
834
+
835
+clean:
836
+	$(RM) $(OBJS)
837
+	$(RM) $(PROLLEXE) proll.aout
838
+
839
+proll.aout:	$(PROLLEXE)
840
+	$(ELFTOAOUT) -o proll.aout $(PROLLEXE)
841
diff -ruN proll_18.orig/qemu/openprom.c proll-patch4/qemu/openprom.c
842
--- proll_18.orig/qemu/openprom.c	1970-01-01 00:00:00.000000000 +0000
843
+++ proll-patch4/qemu/openprom.c	2004-11-23 19:14:05.000000000 +0000
844
@@ -0,0 +1,596 @@
845
+/*
846
+ * PROM interface support
847
+ * Copyright 1996 The Australian National University.
848
+ * Copyright 1996 Fujitsu Laboratories Limited
849
+ * Copyright 1999 Pete A. Zaitcev
850
+ * This software may be distributed under the terms of the Gnu
851
+ * Public License version 2 or later
852
+ */
853
+
854
+#include <openprom.h>
855
+#include <general.h>
856
+#include <romlib.h>
857
+#include <system.h>
858
+#include <vconsole.h>
859
+#include "phys_jj.h"
860
+
861
+struct property {
862
+	const char *name;
863
+	const char *value;
864
+	const int length;
865
+};
866
+
867
+struct node {
868
+	const struct property *properties;
869
+	/* short */ const int sibling;
870
+	/* short */ const int child;
871
+};
872
+
873
+static int obp_nextnode(int node);
874
+static int obp_child(int node);
875
+static int obp_proplen(int node, char *name);
876
+static int obp_getprop(int node, char *name, char *val);
877
+static int obp_setprop(int node, char *name, char *val, int len);
878
+static const char *obp_nextprop(int node, char *name);
879
+
880
+static char obp_idprom[IDPROM_SIZE];
881
+static const struct property null_properties = { NULL, NULL, -1 };
882
+static const int prop_true = -1;
883
+
884
+static const struct property propv_root[] = {
885
+	{"name",	"SUNW,JavaStation-1", sizeof("SUNW,JavaStation-1") },
886
+	{"idprom",	obp_idprom, IDPROM_SIZE},
887
+	{"banner-name", "JavaStation", sizeof("JavaStation")},
888
+	{"compatible",	"sun4m", 6},
889
+	{NULL, NULL, -1}
890
+};
891
+
892
+static const int prop_iommu_reg[] = {
893
+	0x0, 0x10000000, 0x00000300,
894
+};
895
+static const struct property propv_iommu[] = {
896
+	{"name",	"iommu", sizeof("iommu")},
897
+	{"reg",		(char*)&prop_iommu_reg[0], sizeof(prop_iommu_reg) },
898
+	{NULL, NULL, -1}
899
+};
900
+
901
+static const int prop_sbus_ranges[] = {
902
+	0x0, 0x0, 0x0, 0x30000000, 0x10000000,
903
+	0x1, 0x0, 0x0, 0x40000000, 0x10000000,
904
+	0x2, 0x0, 0x0, 0x50000000, 0x10000000,
905
+	0x3, 0x0, 0x0, 0x60000000, 0x10000000,
906
+	0x4, 0x0, 0x0, 0x70000000, 0x10000000,
907
+};
908
+static const struct property propv_sbus[] = {
909
+	{"name",	"sbus", 5},
910
+	{"ranges",	(char*)&prop_sbus_ranges[0], sizeof(prop_sbus_ranges)},
911
+	{NULL, NULL, -1}
912
+};
913
+
914
+static const int prop_tcx_regs[] = {
915
+	0x2, 0x00800000, 0x00100000,
916
+	0x2, 0x02000000, 0x00000001,
917
+	0x2, 0x04000000, 0x00800000,
918
+	0x2, 0x06000000, 0x00800000,
919
+	0x2, 0x0a000000, 0x00000001,
920
+	0x2, 0x0c000000, 0x00000001,
921
+	0x2, 0x0e000000, 0x00000001,
922
+	0x2, 0x00700000, 0x00001000,
923
+	0x2, 0x00200000, 0x00000004,
924
+	0x2, 0x00300000, 0x0000081c,
925
+	0x2, 0x00000000, 0x00010000,
926
+	0x2, 0x00240000, 0x00000004,
927
+	0x2, 0x00280000, 0x00000001,
928
+};
939
+static const int prop_tcx_regs[] = {
940
+	0x2, 0x00800000, 0x00100000,
941
+	0x2, 0x02000000, 0x00000001,
942
+	0x2, 0x04000000, 0x00800000,
943
+	0x2, 0x06000000, 0x00800000,
944
+	0x2, 0x0a000000, 0x00000001,
945
+	0x2, 0x0c000000, 0x00000001,
946
+	0x2, 0x0e000000, 0x00000001,
947
+	0x2, 0x00700000, 0x00001000,
948
+	0x2, 0x00200000, 0x00000004,
949
+	0x2, 0x00300000, 0x0000081c,
950
+	0x2, 0x00000000, 0x00010000,
951
+	0x2, 0x00240000, 0x00000004,
952
+	0x2, 0x00280000, 0x00000001,
953
+};
929 954
+
930 955
+#if 1	/* Zaitcev */
931 956
+static const int pixfreq = 0x03dfd240;
......
1005 1030
+static const struct property propv_obio[] = {
1006 1031
+	{"name",	"obio", 5 },
1007 1032
+	{"ranges",	(char*)&prop_obio_ranges[0], sizeof(prop_obio_ranges) },
1033
+	{"device_type",	"hierarchical", sizeof("hierarchical") },
1008 1034
+	{NULL, NULL, -1}
1009 1035
+};
1010 1036
+
......
1056 1082
+	{NULL, NULL, -1}
1057 1083
+};
1058 1084
+
1059
+static const int prop_zs_intr[] = { 0x26, 0x0 };
1085
+static const int prop_zs_intr[] = { 12, 0x0 };
1060 1086
+static const int prop_zs_reg[] = {
1061
+	0x4, 0x00000000, 0x0000000f,
1087
+	0x0, 0x00000000, 0x00000008,
1062 1088
+};
1063
+static const int prop_zs_slave[] = { 0x1 };
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff