Commit e80cfcfc8884400e826328b772971913a14d0f44

Authored by bellard
1 parent 9772c73b

SPARC merge


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1179 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
@@ -50,7 +50,7 @@ install: all @@ -50,7 +50,7 @@ install: all
50 install -m 644 pc-bios/bios.bin pc-bios/vgabios.bin \ 50 install -m 644 pc-bios/bios.bin pc-bios/vgabios.bin \
51 pc-bios/vgabios-cirrus.bin \ 51 pc-bios/vgabios-cirrus.bin \
52 pc-bios/ppc_rom.bin \ 52 pc-bios/ppc_rom.bin \
53 - pc-bios/proll.bin \ 53 + pc-bios/proll.elf \
54 pc-bios/linux_boot.bin "$(datadir)" 54 pc-bios/linux_boot.bin "$(datadir)"
55 mkdir -p "$(docdir)" 55 mkdir -p "$(docdir)"
56 install -m 644 qemu-doc.html qemu-tech.html "$(docdir)" 56 install -m 644 qemu-doc.html qemu-tech.html "$(docdir)"
@@ -107,7 +107,7 @@ tarbin: @@ -107,7 +107,7 @@ tarbin:
107 $(datadir)/vgabios.bin \ 107 $(datadir)/vgabios.bin \
108 $(datadir)/vgabios-cirrus.bin \ 108 $(datadir)/vgabios-cirrus.bin \
109 $(datadir)/ppc_rom.bin \ 109 $(datadir)/ppc_rom.bin \
110 - $(datadir)/proll.bin \ 110 + $(datadir)/proll.elf \
111 $(datadir)/linux_boot.bin \ 111 $(datadir)/linux_boot.bin \
112 $(docdir)/qemu-doc.html \ 112 $(docdir)/qemu-doc.html \
113 $(docdir)/qemu-tech.html \ 113 $(docdir)/qemu-tech.html \
Makefile.target
@@ -175,6 +175,7 @@ endif @@ -175,6 +175,7 @@ endif
175 175
176 ifeq ($(CONFIG_DARWIN),yes) 176 ifeq ($(CONFIG_DARWIN),yes)
177 OP_CFLAGS+= -mdynamic-no-pic 177 OP_CFLAGS+= -mdynamic-no-pic
  178 +LIBS+=-lmx
178 endif 179 endif
179 180
180 ######################################################### 181 #########################################################
@@ -300,7 +301,7 @@ VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o @@ -300,7 +301,7 @@ VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
300 VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o mixeng.o 301 VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o mixeng.o
301 endif 302 endif
302 ifeq ($(TARGET_ARCH), sparc) 303 ifeq ($(TARGET_ARCH), sparc)
303 -VL_OBJS+= sun4m.o tcx.o lance.o iommu.o sched.o m48t08.o magic-load.o timer.o 304 +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
304 endif 305 endif
305 ifdef CONFIG_GDBSTUB 306 ifdef CONFIG_GDBSTUB
306 VL_OBJS+=gdbstub.o 307 VL_OBJS+=gdbstub.o
cpu-exec.c
@@ -261,7 +261,7 @@ int cpu_exec(CPUState *env1) @@ -261,7 +261,7 @@ int cpu_exec(CPUState *env1)
261 } 261 }
262 #elif defined(TARGET_SPARC) 262 #elif defined(TARGET_SPARC)
263 if (interrupt_request & CPU_INTERRUPT_HARD) { 263 if (interrupt_request & CPU_INTERRUPT_HARD) {
264 - do_interrupt(0, 0, 0, 0, 0); 264 + do_interrupt(env->interrupt_index, 0, 0, 0, 0);
265 env->interrupt_request &= ~CPU_INTERRUPT_HARD; 265 env->interrupt_request &= ~CPU_INTERRUPT_HARD;
266 } else if (interrupt_request & CPU_INTERRUPT_TIMER) { 266 } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
267 //do_interrupt(0, 0, 0, 0, 0); 267 //do_interrupt(0, 0, 0, 0, 0);
@@ -9,9 +9,7 @@ @@ -9,9 +9,7 @@
9 #include "disas.h" 9 #include "disas.h"
10 10
11 /* Filled in by elfload.c. Simplistic, but will do for now. */ 11 /* Filled in by elfload.c. Simplistic, but will do for now. */
12 -unsigned int disas_num_syms;  
13 -void *disas_symtab;  
14 -const char *disas_strtab; 12 +struct syminfo *syminfos = NULL;
15 13
16 /* Get LENGTH bytes from info's buffer, at target address memaddr. 14 /* Get LENGTH bytes from info's buffer, at target address memaddr.
17 Transfer them to myaddr. */ 15 Transfer them to myaddr. */
@@ -203,19 +201,23 @@ const char *lookup_symbol(void *orig_addr) @@ -203,19 +201,23 @@ const char *lookup_symbol(void *orig_addr)
203 { 201 {
204 unsigned int i; 202 unsigned int i;
205 /* Hack, because we know this is x86. */ 203 /* Hack, because we know this is x86. */
206 - Elf32_Sym *sym = disas_symtab;  
207 -  
208 - for (i = 0; i < disas_num_syms; i++) {  
209 - if (sym[i].st_shndx == SHN_UNDEF  
210 - || sym[i].st_shndx >= SHN_LORESERVE)  
211 - continue;  
212 -  
213 - if (ELF_ST_TYPE(sym[i].st_info) != STT_FUNC)  
214 - continue;  
215 -  
216 - if ((long)orig_addr >= sym[i].st_value  
217 - && (long)orig_addr < sym[i].st_value + sym[i].st_size)  
218 - return disas_strtab + sym[i].st_name; 204 + Elf32_Sym *sym;
  205 + struct syminfo *s;
  206 +
  207 + for (s = syminfos; s; s = s->next) {
  208 + sym = s->disas_symtab;
  209 + for (i = 0; i < s->disas_num_syms; i++) {
  210 + if (sym[i].st_shndx == SHN_UNDEF
  211 + || sym[i].st_shndx >= SHN_LORESERVE)
  212 + continue;
  213 +
  214 + if (ELF_ST_TYPE(sym[i].st_info) != STT_FUNC)
  215 + continue;
  216 +
  217 + if ((long)orig_addr >= sym[i].st_value
  218 + && (long)orig_addr < sym[i].st_value + sym[i].st_size)
  219 + return s->disas_strtab + sym[i].st_name;
  220 + }
219 } 221 }
220 return ""; 222 return "";
221 } 223 }
@@ -9,7 +9,11 @@ void monitor_disas(target_ulong pc, int nb_insn, int is_physical, int flags); @@ -9,7 +9,11 @@ void monitor_disas(target_ulong pc, int nb_insn, int is_physical, int flags);
9 const char *lookup_symbol(void *orig_addr); 9 const char *lookup_symbol(void *orig_addr);
10 10
11 /* Filled in by elfload.c. Simplistic, but will do for now. */ 11 /* Filled in by elfload.c. Simplistic, but will do for now. */
12 -extern unsigned int disas_num_syms;  
13 -extern void *disas_symtab; /* FIXME: includes are a mess --RR */  
14 -extern const char *disas_strtab; 12 +extern struct syminfo {
  13 + unsigned int disas_num_syms;
  14 + void *disas_symtab;
  15 + const char *disas_strtab;
  16 + struct syminfo *next;
  17 +} *syminfos;
  18 +
15 #endif /* _QEMU_DISAS_H */ 19 #endif /* _QEMU_DISAS_H */
gdbstub.c
@@ -298,11 +298,7 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) @@ -298,11 +298,7 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
298 } 298 }
299 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ 299 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
300 registers[64] = tswapl(env->y); 300 registers[64] = tswapl(env->y);
301 - tmp = (0<<28) | (4<<24) | env->psr \  
302 - | (env->psrs? PSR_S : 0) \  
303 - | (env->psrs? PSR_PS : 0) \  
304 - | (env->psret? PSR_ET : 0) \  
305 - | env->cwp; 301 + tmp = GET_PSR(env);
306 registers[65] = tswapl(tmp); 302 registers[65] = tswapl(tmp);
307 registers[66] = tswapl(env->wim); 303 registers[66] = tswapl(env->wim);
308 registers[67] = tswapl(env->tbr); 304 registers[67] = tswapl(env->tbr);
@@ -317,7 +313,7 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) @@ -317,7 +313,7 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
317 313
318 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) 314 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
319 { 315 {
320 - uint32_t *registers = (uint32_t *)mem_buf, tmp; 316 + uint32_t *registers = (uint32_t *)mem_buf;
321 int i; 317 int i;
322 318
323 /* fill in g0..g7 */ 319 /* fill in g0..g7 */
@@ -334,12 +330,7 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) @@ -334,12 +330,7 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
334 } 330 }
335 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ 331 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
336 env->y = tswapl(registers[64]); 332 env->y = tswapl(registers[64]);
337 - tmp = tswapl(registers[65]);  
338 - env->psr = tmp & ~PSR_ICC;  
339 - env->psrs = (tmp & PSR_S)? 1 : 0;  
340 - env->psrps = (tmp & PSR_PS)? 1 : 0;  
341 - env->psret = (tmp & PSR_ET)? 1 : 0;  
342 - env->cwp = (tmp & PSR_CWP); 333 + PUT_PSR(env, tswapl(registers[65]));
343 env->wim = tswapl(registers[66]); 334 env->wim = tswapl(registers[66]);
344 env->tbr = tswapl(registers[67]); 335 env->tbr = tswapl(registers[67]);
345 env->pc = tswapl(registers[68]); 336 env->pc = tswapl(registers[68]);
@@ -495,8 +486,10 @@ static void gdb_vm_stopped(void *opaque, int reason) @@ -495,8 +486,10 @@ static void gdb_vm_stopped(void *opaque, int reason)
495 /* disable single step if it was enable */ 486 /* disable single step if it was enable */
496 cpu_single_step(cpu_single_env, 0); 487 cpu_single_step(cpu_single_env, 0);
497 488
498 - if (reason == EXCP_DEBUG) 489 + if (reason == EXCP_DEBUG) {
  490 + tb_flush(cpu_single_env);
499 ret = SIGTRAP; 491 ret = SIGTRAP;
  492 + }
500 else 493 else
501 ret = 0; 494 ret = 0;
502 snprintf(buf, sizeof(buf), "S%02x", ret); 495 snprintf(buf, sizeof(buf), "S%02x", ret);
hw/fdc.c
@@ -21,6 +21,10 @@ @@ -21,6 +21,10 @@
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE. 22 * THE SOFTWARE.
23 */ 23 */
  24 +/*
  25 + * The controller is used in Sun4m systems in a slightly different
  26 + * way. There are changes in DOR register and DMA is not available.
  27 + */
24 #include "vl.h" 28 #include "vl.h"
25 29
26 /********************************************************/ 30 /********************************************************/
@@ -90,6 +94,16 @@ typedef struct fdrive_t { @@ -90,6 +94,16 @@ typedef struct fdrive_t {
90 uint8_t ro; /* Is read-only */ 94 uint8_t ro; /* Is read-only */
91 } fdrive_t; 95 } fdrive_t;
92 96
  97 +#ifdef TARGET_SPARC
  98 +#define DMA_read_memory(a,b,c,d)
  99 +#define DMA_write_memory(a,b,c,d)
  100 +#define DMA_register_channel(a,b,c)
  101 +#define DMA_hold_DREQ(a)
  102 +#define DMA_release_DREQ(a)
  103 +#define DMA_get_channel_mode(a) (0)
  104 +#define DMA_schedule(a)
  105 +#endif
  106 +
93 static void fd_init (fdrive_t *drv, BlockDriverState *bs) 107 static void fd_init (fdrive_t *drv, BlockDriverState *bs)
94 { 108 {
95 /* Drive */ 109 /* Drive */
@@ -455,6 +469,18 @@ static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value) @@ -455,6 +469,18 @@ static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value)
455 } 469 }
456 } 470 }
457 471
  472 +static CPUReadMemoryFunc *fdctrl_mem_read[3] = {
  473 + fdctrl_read,
  474 + fdctrl_read,
  475 + fdctrl_read,
  476 +};
  477 +
  478 +static CPUWriteMemoryFunc *fdctrl_mem_write[3] = {
  479 + fdctrl_write,
  480 + fdctrl_write,
  481 + fdctrl_write,
  482 +};
  483 +
458 static void fd_change_cb (void *opaque) 484 static void fd_change_cb (void *opaque)
459 { 485 {
460 fdrive_t *drv = opaque; 486 fdrive_t *drv = opaque;
@@ -473,7 +499,7 @@ fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, @@ -473,7 +499,7 @@ fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
473 BlockDriverState **fds) 499 BlockDriverState **fds)
474 { 500 {
475 fdctrl_t *fdctrl; 501 fdctrl_t *fdctrl;
476 -// int io_mem; 502 + int io_mem;
477 int i; 503 int i;
478 504
479 FLOPPY_DPRINTF("init controller\n"); 505 FLOPPY_DPRINTF("init controller\n");
@@ -504,11 +530,8 @@ fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, @@ -504,11 +530,8 @@ fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
504 fdctrl_reset(fdctrl, 0); 530 fdctrl_reset(fdctrl, 0);
505 fdctrl->state = FD_CTRL_ACTIVE; 531 fdctrl->state = FD_CTRL_ACTIVE;
506 if (mem_mapped) { 532 if (mem_mapped) {
507 - FLOPPY_ERROR("memory mapped floppy not supported by now !\n");  
508 -#if 0  
509 - io_mem = cpu_register_io_memory(0, fdctrl_mem_read, fdctrl_mem_write);  
510 - cpu_register_physical_memory(base, 0x08, io_mem);  
511 -#endif 533 + io_mem = cpu_register_io_memory(0, fdctrl_mem_read, fdctrl_mem_write, fdctrl);
  534 + cpu_register_physical_memory(io_base, 0x08, io_mem);
512 } else { 535 } else {
513 register_ioport_read(io_base + 0x01, 5, 1, &fdctrl_read, fdctrl); 536 register_ioport_read(io_base + 0x01, 5, 1, &fdctrl_read, fdctrl);
514 register_ioport_read(io_base + 0x07, 1, 1, &fdctrl_read, fdctrl); 537 register_ioport_read(io_base + 0x07, 1, 1, &fdctrl_read, fdctrl);
hw/iommu.c
@@ -117,8 +117,6 @@ typedef struct IOMMUState { @@ -117,8 +117,6 @@ typedef struct IOMMUState {
117 uint32_t iostart; 117 uint32_t iostart;
118 } IOMMUState; 118 } IOMMUState;
119 119
120 -static IOMMUState *ps;  
121 -  
122 static uint32_t iommu_mem_readw(void *opaque, target_phys_addr_t addr) 120 static uint32_t iommu_mem_readw(void *opaque, target_phys_addr_t addr)
123 { 121 {
124 IOMMUState *s = opaque; 122 IOMMUState *s = opaque;
@@ -187,25 +185,61 @@ static CPUWriteMemoryFunc *iommu_mem_write[3] = { @@ -187,25 +185,61 @@ static CPUWriteMemoryFunc *iommu_mem_write[3] = {
187 iommu_mem_writew, 185 iommu_mem_writew,
188 }; 186 };
189 187
190 -uint32_t iommu_translate(uint32_t addr) 188 +uint32_t iommu_translate_local(void *opaque, uint32_t addr)
191 { 189 {
192 - uint32_t *iopte = (void *)(ps->regs[1] << 4), pa; 190 + IOMMUState *s = opaque;
  191 + uint32_t *iopte = (void *)(s->regs[1] << 4), pa;
193 192
194 - iopte += ((addr - ps->iostart) >> PAGE_SHIFT);  
195 - cpu_physical_memory_rw((uint32_t)iopte, (void *) &pa, 4, 0); 193 + iopte += ((addr - s->iostart) >> PAGE_SHIFT);
  194 + cpu_physical_memory_read((uint32_t)iopte, (void *) &pa, 4);
196 bswap32s(&pa); 195 bswap32s(&pa);
197 pa = (pa & IOPTE_PAGE) << 4; /* Loose higher bits of 36 */ 196 pa = (pa & IOPTE_PAGE) << 4; /* Loose higher bits of 36 */
198 return pa + (addr & PAGE_MASK); 197 return pa + (addr & PAGE_MASK);
199 } 198 }
200 199
201 -void iommu_init(uint32_t addr) 200 +static void iommu_save(QEMUFile *f, void *opaque)
  201 +{
  202 + IOMMUState *s = opaque;
  203 + int i;
  204 +
  205 + qemu_put_be32s(f, &s->addr);
  206 + for (i = 0; i < sizeof(struct iommu_regs); i += 4)
  207 + qemu_put_be32s(f, &s->regs[i]);
  208 + qemu_put_be32s(f, &s->iostart);
  209 +}
  210 +
  211 +static int iommu_load(QEMUFile *f, void *opaque, int version_id)
  212 +{
  213 + IOMMUState *s = opaque;
  214 + int i;
  215 +
  216 + if (version_id != 1)
  217 + return -EINVAL;
  218 +
  219 + qemu_get_be32s(f, &s->addr);
  220 + for (i = 0; i < sizeof(struct iommu_regs); i += 4)
  221 + qemu_put_be32s(f, &s->regs[i]);
  222 + qemu_get_be32s(f, &s->iostart);
  223 +
  224 + return 0;
  225 +}
  226 +
  227 +static void iommu_reset(void *opaque)
  228 +{
  229 + IOMMUState *s = opaque;
  230 +
  231 + memset(s->regs, 0, sizeof(struct iommu_regs));
  232 + s->iostart = 0;
  233 +}
  234 +
  235 +void *iommu_init(uint32_t addr)
202 { 236 {
203 IOMMUState *s; 237 IOMMUState *s;
204 int iommu_io_memory; 238 int iommu_io_memory;
205 239
206 s = qemu_mallocz(sizeof(IOMMUState)); 240 s = qemu_mallocz(sizeof(IOMMUState));
207 if (!s) 241 if (!s)
208 - return; 242 + return NULL;
209 243
210 s->addr = addr; 244 s->addr = addr;
211 245
@@ -213,6 +247,8 @@ void iommu_init(uint32_t addr) @@ -213,6 +247,8 @@ void iommu_init(uint32_t addr)
213 cpu_register_physical_memory(addr, sizeof(struct iommu_regs), 247 cpu_register_physical_memory(addr, sizeof(struct iommu_regs),
214 iommu_io_memory); 248 iommu_io_memory);
215 249
216 - ps = s; 250 + register_savevm("iommu", addr, 1, iommu_save, iommu_load, s);
  251 + qemu_register_reset(iommu_reset, s);
  252 + return s;
217 } 253 }
218 254
hw/lance.c
@@ -147,6 +147,7 @@ struct lance_init_block { @@ -147,6 +147,7 @@ struct lance_init_block {
147 }; 147 };
148 148
149 #define LEDMA_REGS 4 149 #define LEDMA_REGS 4
  150 +#define LEDMA_MAXADDR (LEDMA_REGS * 4 - 1)
150 #if 0 151 #if 0
151 /* Structure to describe the current status of DMA registers on the Sparc */ 152 /* Structure to describe the current status of DMA registers on the Sparc */
152 struct sparc_dma_registers { 153 struct sparc_dma_registers {
@@ -157,32 +158,28 @@ struct sparc_dma_registers { @@ -157,32 +158,28 @@ struct sparc_dma_registers {
157 }; 158 };
158 #endif 159 #endif
159 160
160 -typedef struct LEDMAState {  
161 - uint32_t addr;  
162 - uint32_t regs[LEDMA_REGS];  
163 -} LEDMAState;  
164 -  
165 typedef struct LANCEState { 161 typedef struct LANCEState {
166 - uint32_t paddr;  
167 NetDriverState *nd; 162 NetDriverState *nd;
168 uint32_t leptr; 163 uint32_t leptr;
169 uint16_t addr; 164 uint16_t addr;
170 uint16_t regs[LE_MAXREG]; 165 uint16_t regs[LE_MAXREG];
171 uint8_t phys[6]; /* mac address */ 166 uint8_t phys[6]; /* mac address */
172 int irq; 167 int irq;
173 - LEDMAState *ledma; 168 + unsigned int rxptr, txptr;
  169 + uint32_t ledmaregs[LEDMA_REGS];
174 } LANCEState; 170 } LANCEState;
175 171
176 -static unsigned int rxptr, txptr;  
177 -  
178 static void lance_send(void *opaque); 172 static void lance_send(void *opaque);
179 173
180 -static void lance_reset(LANCEState *s) 174 +static void lance_reset(void *opaque)
181 { 175 {
  176 + LANCEState *s = opaque;
182 memcpy(s->phys, s->nd->macaddr, 6); 177 memcpy(s->phys, s->nd->macaddr, 6);
183 - rxptr = 0;  
184 - txptr = 0; 178 + s->rxptr = 0;
  179 + s->txptr = 0;
  180 + memset(s->regs, 0, LE_MAXREG * 2);
185 s->regs[LE_CSR0] = LE_C0_STOP; 181 s->regs[LE_CSR0] = LE_C0_STOP;
  182 + memset(s->ledmaregs, 0, LEDMA_REGS * 4);
186 } 183 }
187 184
188 static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr) 185 static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
@@ -190,7 +187,7 @@ static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr) @@ -190,7 +187,7 @@ static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
190 LANCEState *s = opaque; 187 LANCEState *s = opaque;
191 uint32_t saddr; 188 uint32_t saddr;
192 189
193 - saddr = addr - s->paddr; 190 + saddr = addr & LE_MAXREG;
194 switch (saddr >> 1) { 191 switch (saddr >> 1) {
195 case LE_RDP: 192 case LE_RDP:
196 return s->regs[s->addr]; 193 return s->regs[s->addr];
@@ -208,7 +205,7 @@ static void lance_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val @@ -208,7 +205,7 @@ static void lance_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val
208 uint32_t saddr; 205 uint32_t saddr;
209 uint16_t reg; 206 uint16_t reg;
210 207
211 - saddr = addr - s->paddr; 208 + saddr = addr & LE_MAXREG;
212 switch (saddr >> 1) { 209 switch (saddr >> 1) {
213 case LE_RDP: 210 case LE_RDP:
214 switch(s->addr) { 211 switch(s->addr) {
@@ -292,7 +289,7 @@ static CPUWriteMemoryFunc *lance_mem_write[3] = { @@ -292,7 +289,7 @@ static CPUWriteMemoryFunc *lance_mem_write[3] = {
292 static int lance_can_receive(void *opaque) 289 static int lance_can_receive(void *opaque)
293 { 290 {
294 LANCEState *s = opaque; 291 LANCEState *s = opaque;
295 - void *dmaptr = (void *) (s->leptr + s->ledma->regs[3]); 292 + uint32_t dmaptr = s->leptr + s->ledmaregs[3];
296 struct lance_init_block *ib; 293 struct lance_init_block *ib;
297 int i; 294 int i;
298 uint16_t temp; 295 uint16_t temp;
@@ -303,7 +300,7 @@ static int lance_can_receive(void *opaque) @@ -303,7 +300,7 @@ static int lance_can_receive(void *opaque)
303 ib = (void *) iommu_translate(dmaptr); 300 ib = (void *) iommu_translate(dmaptr);
304 301
305 for (i = 0; i < RX_RING_SIZE; i++) { 302 for (i = 0; i < RX_RING_SIZE; i++) {
306 - cpu_physical_memory_read(&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1); 303 + cpu_physical_memory_read((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1);
307 temp &= 0xff; 304 temp &= 0xff;
308 if (temp == (LE_R1_OWN)) { 305 if (temp == (LE_R1_OWN)) {
309 #ifdef DEBUG_LANCE 306 #ifdef DEBUG_LANCE
@@ -323,7 +320,7 @@ static int lance_can_receive(void *opaque) @@ -323,7 +320,7 @@ static int lance_can_receive(void *opaque)
323 static void lance_receive(void *opaque, const uint8_t *buf, int size) 320 static void lance_receive(void *opaque, const uint8_t *buf, int size)
324 { 321 {
325 LANCEState *s = opaque; 322 LANCEState *s = opaque;
326 - void *dmaptr = (void *) (s->leptr + s->ledma->regs[3]); 323 + uint32_t dmaptr = s->leptr + s->ledmaregs[3];
327 struct lance_init_block *ib; 324 struct lance_init_block *ib;
328 unsigned int i, old_rxptr, j; 325 unsigned int i, old_rxptr, j;
329 uint16_t temp; 326 uint16_t temp;
@@ -333,23 +330,23 @@ static void lance_receive(void *opaque, const uint8_t *buf, int size) @@ -333,23 +330,23 @@ static void lance_receive(void *opaque, const uint8_t *buf, int size)
333 330
334 ib = (void *) iommu_translate(dmaptr); 331 ib = (void *) iommu_translate(dmaptr);
335 332
336 - old_rxptr = rxptr;  
337 - for (i = rxptr; i != ((old_rxptr - 1) & RX_RING_MOD_MASK); i = (i + 1) & RX_RING_MOD_MASK) {  
338 - cpu_physical_memory_read(&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1); 333 + old_rxptr = s->rxptr;
  334 + for (i = s->rxptr; i != ((old_rxptr - 1) & RX_RING_MOD_MASK); i = (i + 1) & RX_RING_MOD_MASK) {
  335 + cpu_physical_memory_read((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1);
339 if (temp == (LE_R1_OWN)) { 336 if (temp == (LE_R1_OWN)) {
340 - rxptr = (rxptr + 1) & RX_RING_MOD_MASK; 337 + s->rxptr = (s->rxptr + 1) & RX_RING_MOD_MASK;
341 temp = size; 338 temp = size;
342 bswap16s(&temp); 339 bswap16s(&temp);
343 - cpu_physical_memory_write(&ib->brx_ring[i].mblength, (void *) &temp, 2); 340 + cpu_physical_memory_write((uint32_t)&ib->brx_ring[i].mblength, (void *) &temp, 2);
344 #if 0 341 #if 0
345 - cpu_physical_memory_write(&ib->rx_buf[i], buf, size); 342 + cpu_physical_memory_write((uint32_t)&ib->rx_buf[i], buf, size);
346 #else 343 #else
347 for (j = 0; j < size; j++) { 344 for (j = 0; j < size; j++) {
348 - cpu_physical_memory_write(((void *)&ib->rx_buf[i]) + j, &buf[j], 1); 345 + cpu_physical_memory_write(((uint32_t)&ib->rx_buf[i]) + j, &buf[j], 1);
349 } 346 }
350 #endif 347 #endif
351 temp = LE_R1_POK; 348 temp = LE_R1_POK;
352 - cpu_physical_memory_write(&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1); 349 + cpu_physical_memory_write((uint32_t)&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1);
353 s->regs[LE_CSR0] |= LE_C0_RINT | LE_C0_INTR; 350 s->regs[LE_CSR0] |= LE_C0_RINT | LE_C0_INTR;
354 if ((s->regs[LE_CSR0] & LE_C0_INTR) && (s->regs[LE_CSR0] & LE_C0_INEA)) 351 if ((s->regs[LE_CSR0] & LE_C0_INTR) && (s->regs[LE_CSR0] & LE_C0_INEA))
355 pic_set_irq(s->irq, 1); 352 pic_set_irq(s->irq, 1);
@@ -364,7 +361,7 @@ static void lance_receive(void *opaque, const uint8_t *buf, int size) @@ -364,7 +361,7 @@ static void lance_receive(void *opaque, const uint8_t *buf, int size)
364 static void lance_send(void *opaque) 361 static void lance_send(void *opaque)
365 { 362 {
366 LANCEState *s = opaque; 363 LANCEState *s = opaque;
367 - void *dmaptr = (void *) (s->leptr + s->ledma->regs[3]); 364 + uint32_t dmaptr = s->leptr + s->ledmaregs[3];
368 struct lance_init_block *ib; 365 struct lance_init_block *ib;
369 unsigned int i, old_txptr, j; 366 unsigned int i, old_txptr, j;
370 uint16_t temp; 367 uint16_t temp;
@@ -375,18 +372,18 @@ static void lance_send(void *opaque) @@ -375,18 +372,18 @@ static void lance_send(void *opaque)
375 372
376 ib = (void *) iommu_translate(dmaptr); 373 ib = (void *) iommu_translate(dmaptr);
377 374
378 - old_txptr = txptr;  
379 - for (i = txptr; i != ((old_txptr - 1) & TX_RING_MOD_MASK); i = (i + 1) & TX_RING_MOD_MASK) {  
380 - cpu_physical_memory_read(&ib->btx_ring[i].tmd1_bits, (void *) &temp, 1); 375 + old_txptr = s->txptr;
  376 + for (i = s->txptr; i != ((old_txptr - 1) & TX_RING_MOD_MASK); i = (i + 1) & TX_RING_MOD_MASK) {
  377 + cpu_physical_memory_read((uint32_t)&ib->btx_ring[i].tmd1_bits, (void *) &temp, 1);
381 if (temp == (LE_T1_POK|LE_T1_OWN)) { 378 if (temp == (LE_T1_POK|LE_T1_OWN)) {
382 - cpu_physical_memory_read(&ib->btx_ring[i].length, (void *) &temp, 2); 379 + cpu_physical_memory_read((uint32_t)&ib->btx_ring[i].length, (void *) &temp, 2);
383 bswap16s(&temp); 380 bswap16s(&temp);
384 temp = (~temp) + 1; 381 temp = (~temp) + 1;
385 #if 0 382 #if 0
386 - cpu_physical_memory_read(&ib->tx_buf[i], pkt_buf, temp); 383 + cpu_physical_memory_read((uint32_t)&ib->tx_buf[i], pkt_buf, temp);
387 #else 384 #else
388 for (j = 0; j < temp; j++) { 385 for (j = 0; j < temp; j++) {
389 - cpu_physical_memory_read(((void *)&ib->tx_buf[i]) + j, &pkt_buf[j], 1); 386 + cpu_physical_memory_read((uint32_t)&ib->tx_buf[i] + j, &pkt_buf[j], 1);
390 } 387 }
391 #endif 388 #endif
392 389
@@ -395,8 +392,8 @@ static void lance_send(void *opaque) @@ -395,8 +392,8 @@ static void lance_send(void *opaque)
395 #endif 392 #endif
396 qemu_send_packet(s->nd, pkt_buf, temp); 393 qemu_send_packet(s->nd, pkt_buf, temp);
397 temp = LE_T1_POK; 394 temp = LE_T1_POK;
398 - cpu_physical_memory_write(&ib->btx_ring[i].tmd1_bits, (void *) &temp, 1);  
399 - txptr = (txptr + 1) & TX_RING_MOD_MASK; 395 + cpu_physical_memory_write((uint32_t)&ib->btx_ring[i].tmd1_bits, (void *) &temp, 1);
  396 + s->txptr = (s->txptr + 1) & TX_RING_MOD_MASK;
400 s->regs[LE_CSR0] |= LE_C0_TINT | LE_C0_INTR; 397 s->regs[LE_CSR0] |= LE_C0_TINT | LE_C0_INTR;
401 } 398 }
402 } 399 }
@@ -404,24 +401,20 @@ static void lance_send(void *opaque) @@ -404,24 +401,20 @@ static void lance_send(void *opaque)
404 401
405 static uint32_t ledma_mem_readl(void *opaque, target_phys_addr_t addr) 402 static uint32_t ledma_mem_readl(void *opaque, target_phys_addr_t addr)
406 { 403 {
407 - LEDMAState *s = opaque; 404 + LANCEState *s = opaque;
408 uint32_t saddr; 405 uint32_t saddr;
409 406
410 - saddr = (addr - s->addr) >> 2;  
411 - if (saddr < LEDMA_REGS)  
412 - return s->regs[saddr];  
413 - else  
414 - return 0; 407 + saddr = (addr & LEDMA_MAXADDR) >> 2;
  408 + return s->ledmaregs[saddr];
415 } 409 }
416 410
417 static void ledma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) 411 static void ledma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
418 { 412 {
419 - LEDMAState *s = opaque; 413 + LANCEState *s = opaque;
420 uint32_t saddr; 414 uint32_t saddr;
421 415
422 - saddr = (addr - s->addr) >> 2;  
423 - if (saddr < LEDMA_REGS)  
424 - s->regs[saddr] = val; 416 + saddr = (addr & LEDMA_MAXADDR) >> 2;
  417 + s->ledmaregs[saddr] = val;
425 } 418 }
426 419
427 static CPUReadMemoryFunc *ledma_mem_read[3] = { 420 static CPUReadMemoryFunc *ledma_mem_read[3] = {
@@ -436,33 +429,61 @@ static CPUWriteMemoryFunc *ledma_mem_write[3] = { @@ -436,33 +429,61 @@ static CPUWriteMemoryFunc *ledma_mem_write[3] = {
436 ledma_mem_writel, 429 ledma_mem_writel,
437 }; 430 };
438 431
  432 +static void lance_save(QEMUFile *f, void *opaque)
  433 +{
  434 + LANCEState *s = opaque;
  435 + int i;
  436 +
  437 + qemu_put_be32s(f, &s->leptr);
  438 + qemu_put_be16s(f, &s->addr);
  439 + for (i = 0; i < LE_MAXREG; i ++)
  440 + qemu_put_be16s(f, &s->regs[i]);
  441 + qemu_put_buffer(f, s->phys, 6);
  442 + qemu_put_be32s(f, &s->irq);
  443 + for (i = 0; i < LEDMA_REGS; i ++)
  444 + qemu_put_be32s(f, &s->ledmaregs[i]);
  445 +}
  446 +
  447 +static int lance_load(QEMUFile *f, void *opaque, int version_id)
  448 +{
  449 + LANCEState *s = opaque;
  450 + int i;
  451 +
  452 + if (version_id != 1)
  453 + return -EINVAL;
  454 +
  455 + qemu_get_be32s(f, &s->leptr);
  456 + qemu_get_be16s(f, &s->addr);
  457 + for (i = 0; i < LE_MAXREG; i ++)
  458 + qemu_get_be16s(f, &s->regs[i]);
  459 + qemu_get_buffer(f, s->phys, 6);
  460 + qemu_get_be32s(f, &s->irq);
  461 + for (i = 0; i < LEDMA_REGS; i ++)
  462 + qemu_get_be32s(f, &s->ledmaregs[i]);
  463 + return 0;
  464 +}
  465 +
439 void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr) 466 void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr)
440 { 467 {
441 LANCEState *s; 468 LANCEState *s;
442 - LEDMAState *led;  
443 int lance_io_memory, ledma_io_memory; 469 int lance_io_memory, ledma_io_memory;
444 470
445 s = qemu_mallocz(sizeof(LANCEState)); 471 s = qemu_mallocz(sizeof(LANCEState));
446 if (!s) 472 if (!s)
447 return; 473 return;
448 474
449 - s->paddr = leaddr;  
450 s->nd = nd; 475 s->nd = nd;
451 s->irq = irq; 476 s->irq = irq;
452 477
453 lance_io_memory = cpu_register_io_memory(0, lance_mem_read, lance_mem_write, s); 478 lance_io_memory = cpu_register_io_memory(0, lance_mem_read, lance_mem_write, s);
454 cpu_register_physical_memory(leaddr, 8, lance_io_memory); 479 cpu_register_physical_memory(leaddr, 8, lance_io_memory);
455 480
456 - led = qemu_mallocz(sizeof(LEDMAState));  
457 - if (!led)  
458 - return;  
459 -  
460 - s->ledma = led;  
461 - led->addr = ledaddr;  
462 - ledma_io_memory = cpu_register_io_memory(0, ledma_mem_read, ledma_mem_write, led); 481 + ledma_io_memory = cpu_register_io_memory(0, ledma_mem_read, ledma_mem_write, s);
463 cpu_register_physical_memory(ledaddr, 16, ledma_io_memory); 482 cpu_register_physical_memory(ledaddr, 16, ledma_io_memory);
464 483
465 lance_reset(s); 484 lance_reset(s);
466 qemu_add_read_packet(nd, lance_can_receive, lance_receive, s); 485 qemu_add_read_packet(nd, lance_can_receive, lance_receive, s);
  486 + register_savevm("lance", leaddr, 1, lance_save, lance_load, s);
  487 + qemu_register_reset(lance_reset, s);
467 } 488 }
468 489
hw/m48t08.c
@@ -32,19 +32,14 @@ @@ -32,19 +32,14 @@
32 #define NVRAM_PRINTF(fmt, args...) do { } while (0) 32 #define NVRAM_PRINTF(fmt, args...) do { } while (0)
33 #endif 33 #endif
34 34
35 -#define NVRAM_MAX_MEM 0xfff0 35 +#define NVRAM_MAX_MEM 0x1ff0
  36 +#define NVRAM_MAXADDR 0x1fff
36 37
37 struct m48t08_t { 38 struct m48t08_t {
38 - /* Hardware parameters */  
39 - int mem_index;  
40 - uint32_t mem_base;  
41 - uint16_t size;  
42 /* RTC management */ 39 /* RTC management */
43 time_t time_offset; 40 time_t time_offset;
44 time_t stop_time; 41 time_t stop_time;
45 /* NVRAM storage */ 42 /* NVRAM storage */
46 - uint8_t lock;  
47 - uint16_t addr;  
48 uint8_t *buffer; 43 uint8_t *buffer;
49 }; 44 };
50 45
@@ -83,14 +78,13 @@ static void set_time (m48t08_t *NVRAM, struct tm *tm) @@ -83,14 +78,13 @@ static void set_time (m48t08_t *NVRAM, struct tm *tm)
83 } 78 }
84 79
85 /* Direct access to NVRAM */ 80 /* Direct access to NVRAM */
86 -void m48t08_write (m48t08_t *NVRAM, uint32_t val) 81 +void m48t08_write (m48t08_t *NVRAM, uint32_t addr, uint8_t val)
87 { 82 {
88 struct tm tm; 83 struct tm tm;
89 int tmp; 84 int tmp;
90 85
91 - if (NVRAM->addr > NVRAM_MAX_MEM && NVRAM->addr < 0x2000)  
92 - NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, NVRAM->addr, val);  
93 - switch (NVRAM->addr) { 86 + addr &= NVRAM_MAXADDR;
  87 + switch (addr) {
94 case 0x1FF8: 88 case 0x1FF8:
95 /* control */ 89 /* control */
96 NVRAM->buffer[0x1FF8] = (val & ~0xA0) | 0x90; 90 NVRAM->buffer[0x1FF8] = (val & ~0xA0) | 0x90;
@@ -167,25 +161,18 @@ void m48t08_write (m48t08_t *NVRAM, uint32_t val) @@ -167,25 +161,18 @@ void m48t08_write (m48t08_t *NVRAM, uint32_t val)
167 } 161 }
168 break; 162 break;
169 default: 163 default:
170 - /* Check lock registers state */  
171 - if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))  
172 - break;  
173 - if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))  
174 - break;  
175 - if (NVRAM->addr < NVRAM_MAX_MEM ||  
176 - (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {  
177 - NVRAM->buffer[NVRAM->addr] = val & 0xFF;  
178 - } 164 + NVRAM->buffer[addr] = val & 0xFF;
179 break; 165 break;
180 } 166 }
181 } 167 }
182 168
183 -uint32_t m48t08_read (m48t08_t *NVRAM) 169 +uint8_t m48t08_read (m48t08_t *NVRAM, uint32_t addr)
184 { 170 {
185 struct tm tm; 171 struct tm tm;
186 - uint32_t retval = 0xFF; 172 + uint8_t retval = 0xFF;
187 173
188 - switch (NVRAM->addr) { 174 + addr &= NVRAM_MAXADDR;
  175 + switch (addr) {
189 case 0x1FF8: 176 case 0x1FF8:
190 /* control */ 177 /* control */
191 goto do_read; 178 goto do_read;
@@ -225,65 +212,36 @@ uint32_t m48t08_read (m48t08_t *NVRAM) @@ -225,65 +212,36 @@ uint32_t m48t08_read (m48t08_t *NVRAM)
225 retval = toBCD(tm.tm_year); 212 retval = toBCD(tm.tm_year);
226 break; 213 break;
227 default: 214 default:
228 - /* Check lock registers state */  
229 - if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))  
230 - break;  
231 - if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))  
232 - break;  
233 - if (NVRAM->addr < NVRAM_MAX_MEM ||  
234 - (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {  
235 - do_read:  
236 - retval = NVRAM->buffer[NVRAM->addr];  
237 - } 215 + do_read:
  216 + retval = NVRAM->buffer[addr];
238 break; 217 break;
239 } 218 }
240 - if (NVRAM->addr > NVRAM_MAX_MEM + 1 && NVRAM->addr < 0x2000)  
241 - NVRAM_PRINTF("0x%08x <= 0x%08x\n", NVRAM->addr, retval);  
242 -  
243 return retval; 219 return retval;
244 } 220 }
245 221
246 -void m48t08_set_addr (m48t08_t *NVRAM, uint32_t addr)  
247 -{  
248 - NVRAM->addr = addr;  
249 -}  
250 -  
251 -void m48t08_toggle_lock (m48t08_t *NVRAM, int lock)  
252 -{  
253 - NVRAM->lock ^= 1 << lock;  
254 -}  
255 -  
256 static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) 222 static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
257 { 223 {
258 m48t08_t *NVRAM = opaque; 224 m48t08_t *NVRAM = opaque;
259 225
260 - addr -= NVRAM->mem_base;  
261 - if (addr < NVRAM_MAX_MEM)  
262 - NVRAM->buffer[addr] = value; 226 + m48t08_write(NVRAM, addr, value);
263 } 227 }
264 228
265 static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t value) 229 static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
266 { 230 {
267 m48t08_t *NVRAM = opaque; 231 m48t08_t *NVRAM = opaque;
268 232
269 - addr -= NVRAM->mem_base;  
270 - if (addr < NVRAM_MAX_MEM) {  
271 - NVRAM->buffer[addr] = value >> 8;  
272 - NVRAM->buffer[addr + 1] = value;  
273 - } 233 + m48t08_write(NVRAM, addr, value);
  234 + m48t08_write(NVRAM, addr + 1, value >> 8);
274 } 235 }
275 236
276 static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t value) 237 static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
277 { 238 {
278 m48t08_t *NVRAM = opaque; 239 m48t08_t *NVRAM = opaque;
279 240
280 - addr -= NVRAM->mem_base;  
281 - if (addr < NVRAM_MAX_MEM) {  
282 - NVRAM->buffer[addr] = value >> 24;  
283 - NVRAM->buffer[addr + 1] = value >> 16;  
284 - NVRAM->buffer[addr + 2] = value >> 8;  
285 - NVRAM->buffer[addr + 3] = value;  
286 - } 241 + m48t08_write(NVRAM, addr, value);
  242 + m48t08_write(NVRAM, addr + 1, value >> 8);
  243 + m48t08_write(NVRAM, addr + 2, value >> 16);
  244 + m48t08_write(NVRAM, addr + 3, value >> 24);
287 } 245 }
288 246
289 static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr) 247 static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)
@@ -291,10 +249,7 @@ static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr) @@ -291,10 +249,7 @@ static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)
291 m48t08_t *NVRAM = opaque; 249 m48t08_t *NVRAM = opaque;
292 uint32_t retval = 0; 250 uint32_t retval = 0;
293 251
294 - addr -= NVRAM->mem_base;  
295 - if (addr < NVRAM_MAX_MEM)  
296 - retval = NVRAM->buffer[addr];  
297 - 252 + retval = m48t08_read(NVRAM, addr);
298 return retval; 253 return retval;
299 } 254 }
300 255
@@ -303,12 +258,8 @@ static uint32_t nvram_readw (void *opaque, target_phys_addr_t addr) @@ -303,12 +258,8 @@ static uint32_t nvram_readw (void *opaque, target_phys_addr_t addr)
303 m48t08_t *NVRAM = opaque; 258 m48t08_t *NVRAM = opaque;
304 uint32_t retval = 0; 259 uint32_t retval = 0;
305 260
306 - addr -= NVRAM->mem_base;  
307 - if (addr < NVRAM_MAX_MEM) {  
308 - retval = NVRAM->buffer[addr] << 8;  
309 - retval |= NVRAM->buffer[addr + 1];  
310 - }  
311 - 261 + retval = m48t08_read(NVRAM, addr) << 8;
  262 + retval |= m48t08_read(NVRAM, addr + 1);
312 return retval; 263 return retval;
313 } 264 }
314 265
@@ -317,14 +268,10 @@ static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr) @@ -317,14 +268,10 @@ static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr)
317 m48t08_t *NVRAM = opaque; 268 m48t08_t *NVRAM = opaque;
318 uint32_t retval = 0; 269 uint32_t retval = 0;
319 270
320 - addr -= NVRAM->mem_base;  
321 - if (addr < NVRAM_MAX_MEM) {  
322 - retval = NVRAM->buffer[addr] << 24;  
323 - retval |= NVRAM->buffer[addr + 1] << 16;  
324 - retval |= NVRAM->buffer[addr + 2] << 8;  
325 - retval |= NVRAM->buffer[addr + 3];  
326 - }  
327 - 271 + retval = m48t08_read(NVRAM, addr) << 24;
  272 + retval |= m48t08_read(NVRAM, addr + 1) << 16;
  273 + retval |= m48t08_read(NVRAM, addr + 2) << 8;
  274 + retval |= m48t08_read(NVRAM, addr + 3);
328 return retval; 275 return retval;
329 } 276 }
330 277
@@ -340,12 +287,42 @@ static CPUReadMemoryFunc *nvram_read[] = { @@ -340,12 +287,42 @@ static CPUReadMemoryFunc *nvram_read[] = {
340 &nvram_readl, 287 &nvram_readl,
341 }; 288 };
342 289
  290 +static void nvram_save(QEMUFile *f, void *opaque)
  291 +{
  292 + m48t08_t *s = opaque;
  293 +
  294 + qemu_put_be32s(f, (uint32_t *)&s->time_offset);
  295 + qemu_put_be32s(f, (uint32_t *)&s->stop_time);
  296 + qemu_put_buffer(f, s->buffer, 0x2000);
  297 +}
  298 +
  299 +static int nvram_load(QEMUFile *f, void *opaque, int version_id)
  300 +{
  301 + m48t08_t *s = opaque;
  302 +
  303 + if (version_id != 1)
  304 + return -EINVAL;
  305 +
  306 + qemu_get_be32s(f, (uint32_t *)&s->time_offset);
  307 + qemu_get_be32s(f, (uint32_t *)&s->stop_time);
  308 + qemu_get_buffer(f, s->buffer, 0x2000);
  309 + return 0;
  310 +}
  311 +
  312 +static void m48t08_reset(void *opaque)
  313 +{
  314 + m48t08_t *s = opaque;
  315 +
  316 + s->time_offset = 0;
  317 + s->stop_time = 0;
  318 +}
  319 +
  320 +
343 /* Initialisation routine */ 321 /* Initialisation routine */
344 -m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size, uint8_t *macaddr) 322 +m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size)
345 { 323 {
346 m48t08_t *s; 324 m48t08_t *s;
347 - int i;  
348 - unsigned char tmp = 0; 325 + int mem_index;
349 326
350 s = qemu_mallocz(sizeof(m48t08_t)); 327 s = qemu_mallocz(sizeof(m48t08_t));
351 if (!s) 328 if (!s)
@@ -355,25 +332,13 @@ m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size, uint8_t *macaddr) @@ -355,25 +332,13 @@ m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size, uint8_t *macaddr)
355 qemu_free(s); 332 qemu_free(s);
356 return NULL; 333 return NULL;
357 } 334 }
358 - s->size = size;  
359 - s->mem_base = mem_base;  
360 - s->addr = 0;  
361 if (mem_base != 0) { 335 if (mem_base != 0) {
362 - s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);  
363 - cpu_register_physical_memory(mem_base, 0x4000, s->mem_index); 336 + mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
  337 + cpu_register_physical_memory(mem_base, 0x2000, mem_index);
364 } 338 }
365 - s->lock = 0;  
366 339
367 - i = 0x1fd8;  
368 - s->buffer[i++] = 0x01;  
369 - s->buffer[i++] = 0x80; /* Sun4m OBP */  
370 - memcpy(&s->buffer[i], macaddr, 6);  
371 -  
372 - /* Calculate checksum */  
373 - for (i = 0x1fd8; i < 0x1fe7; i++) {  
374 - tmp ^= s->buffer[i];  
375 - }  
376 - s->buffer[0x1fe7] = tmp; 340 + register_savevm("nvram", mem_base, 1, nvram_save, nvram_load, s);
  341 + qemu_register_reset(m48t08_reset, s);
377 return s; 342 return s;
378 } 343 }
379 344
hw/m48t08.h
@@ -3,10 +3,8 @@ @@ -3,10 +3,8 @@
3 3
4 typedef struct m48t08_t m48t08_t; 4 typedef struct m48t08_t m48t08_t;
5 5
6 -void m48t08_write (m48t08_t *NVRAM, uint32_t val);  
7 -uint32_t m48t08_read (m48t08_t *NVRAM);  
8 -void m48t08_set_addr (m48t08_t *NVRAM, uint32_t addr);  
9 -void m48t08_toggle_lock (m48t08_t *NVRAM, int lock);  
10 -m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size, uint8_t *macaddr); 6 +void m48t08_write (m48t08_t *NVRAM, uint32_t addr, uint8_t val);
  7 +uint8_t m48t08_read (m48t08_t *NVRAM, uint32_t addr);
  8 +m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size);
11 9
12 #endif /* !defined (__M48T08_H__) */ 10 #endif /* !defined (__M48T08_H__) */
hw/magic-load.c
1 #include "vl.h" 1 #include "vl.h"
2 #include "disas.h" 2 #include "disas.h"
  3 +#include "exec-all.h"
  4 +
  5 +struct exec
  6 +{
  7 + uint32_t a_info; /* Use macros N_MAGIC, etc for access */
  8 + uint32_t a_text; /* length of text, in bytes */
  9 + uint32_t a_data; /* length of data, in bytes */
  10 + uint32_t a_bss; /* length of uninitialized data area, in bytes */
  11 + uint32_t a_syms; /* length of symbol table data in file, in bytes */
  12 + uint32_t a_entry; /* start address */
  13 + uint32_t a_trsize; /* length of relocation info for text, in bytes */
  14 + uint32_t a_drsize; /* length of relocation info for data, in bytes */
  15 +};
  16 +
  17 +#ifdef BSWAP_NEEDED
  18 +static void bswap_ahdr(struct exec *e)
  19 +{
  20 + bswap32s(&e->a_info);
  21 + bswap32s(&e->a_text);
  22 + bswap32s(&e->a_data);
  23 + bswap32s(&e->a_bss);
  24 + bswap32s(&e->a_syms);
  25 + bswap32s(&e->a_entry);
  26 + bswap32s(&e->a_trsize);
  27 + bswap32s(&e->a_drsize);
  28 +}
  29 +#else
  30 +#define bswap_ahdr(x) do { } while (0)
  31 +#endif
  32 +
  33 +#define N_MAGIC(exec) ((exec).a_info & 0xffff)
  34 +#define OMAGIC 0407
  35 +#define NMAGIC 0410
  36 +#define ZMAGIC 0413
  37 +#define QMAGIC 0314
  38 +#define _N_HDROFF(x) (1024 - sizeof (struct exec))
  39 +#define N_TXTOFF(x) \
  40 + (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
  41 + (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
  42 +#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? TARGET_PAGE_SIZE : 0)
  43 +#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
  44 +#define _N_SEGMENT_ROUND(x) (((x) + TARGET_PAGE_SIZE - 1) & ~(TARGET_PAGE_SIZE - 1))
  45 +
  46 +#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
  47 +
  48 +#define N_DATADDR(x) \
  49 + (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
  50 + : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
  51 +
3 52
4 #define ELF_CLASS ELFCLASS32 53 #define ELF_CLASS ELFCLASS32
5 #define ELF_DATA ELFDATA2MSB 54 #define ELF_DATA ELFDATA2MSB
@@ -103,27 +152,27 @@ static void *find_shdr(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint3 @@ -103,27 +152,27 @@ static void *find_shdr(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint3
103 return NULL; 152 return NULL;
104 } 153 }
105 154
106 -static int find_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab) 155 +static void *find_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)
107 { 156 {
108 int retval; 157 int retval;
109 158
110 retval = lseek(fd, ehdr->e_shoff + sizeof(struct elf_shdr) * symtab->sh_link, SEEK_SET); 159 retval = lseek(fd, ehdr->e_shoff + sizeof(struct elf_shdr) * symtab->sh_link, SEEK_SET);
111 if (retval < 0) 160 if (retval < 0)
112 - return -1; 161 + return NULL;
113 162
114 retval = read(fd, shdr, sizeof(*shdr)); 163 retval = read(fd, shdr, sizeof(*shdr));
115 if (retval < 0) 164 if (retval < 0)
116 - return -1; 165 + return NULL;
117 bswap_shdr(shdr); 166 bswap_shdr(shdr);
118 if (shdr->sh_type == SHT_STRTAB) 167 if (shdr->sh_type == SHT_STRTAB)
119 return qemu_malloc(shdr->sh_size);; 168 return qemu_malloc(shdr->sh_size);;
120 - return 0; 169 + return NULL;
121 } 170 }
122 171
123 -static int read_program(int fd, struct elf_phdr *phdr, void *dst) 172 +static int read_program(int fd, struct elf_phdr *phdr, void *dst, uint32_t entry)
124 { 173 {
125 int retval; 174 int retval;
126 - retval = lseek(fd, 0x4000, SEEK_SET); 175 + retval = lseek(fd, phdr->p_offset + entry - phdr->p_vaddr, SEEK_SET);
127 if (retval < 0) 176 if (retval < 0)
128 return -1; 177 return -1;
129 return read(fd, dst, phdr->p_filesz); 178 return read(fd, dst, phdr->p_filesz);
@@ -178,6 +227,7 @@ static void load_symbols(struct elfhdr *ehdr, int fd) @@ -178,6 +227,7 @@ static void load_symbols(struct elfhdr *ehdr, int fd)
178 { 227 {
179 struct elf_shdr symtab, strtab; 228 struct elf_shdr symtab, strtab;
180 struct elf_sym *syms; 229 struct elf_sym *syms;
  230 + struct syminfo *s;
181 int nsyms, i; 231 int nsyms, i;
182 char *str; 232 char *str;
183 233
@@ -196,20 +246,19 @@ static void load_symbols(struct elfhdr *ehdr, int fd) @@ -196,20 +246,19 @@ static void load_symbols(struct elfhdr *ehdr, int fd)
196 goto error_freesyms; 246 goto error_freesyms;
197 247
198 /* Commit */ 248 /* Commit */
199 - if (disas_symtab)  
200 - qemu_free(disas_symtab); /* XXX Merge with old symbols? */  
201 - if (disas_strtab)  
202 - qemu_free(disas_strtab);  
203 - disas_symtab = syms;  
204 - disas_num_syms = nsyms;  
205 - disas_strtab = str; 249 + s = qemu_mallocz(sizeof(*s));
  250 + s->disas_symtab = syms;
  251 + s->disas_num_syms = nsyms;
  252 + s->disas_strtab = str;
  253 + s->next = syminfos;
  254 + syminfos = s;
206 return; 255 return;
207 error_freesyms: 256 error_freesyms:
208 qemu_free(syms); 257 qemu_free(syms);
209 return; 258 return;
210 } 259 }
211 260
212 -int load_elf(const char * filename, uint8_t *addr) 261 +int load_elf(const char *filename, uint8_t *addr)
213 { 262 {
214 struct elfhdr ehdr; 263 struct elfhdr ehdr;
215 struct elf_phdr phdr; 264 struct elf_phdr phdr;
@@ -227,12 +276,13 @@ int load_elf(const char * filename, uint8_t *addr) @@ -227,12 +276,13 @@ int load_elf(const char * filename, uint8_t *addr)
227 276
228 if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E' 277 if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E'
229 || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F' 278 || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F'
230 - || ehdr.e_machine != EM_SPARC) 279 + || (ehdr.e_machine != EM_SPARC
  280 + && ehdr.e_machine != EM_SPARC32PLUS))
231 goto error; 281 goto error;
232 282
233 if (find_phdr(&ehdr, fd, &phdr, PT_LOAD)) 283 if (find_phdr(&ehdr, fd, &phdr, PT_LOAD))
234 goto error; 284 goto error;
235 - retval = read_program(fd, &phdr, addr); 285 + retval = read_program(fd, &phdr, addr, ehdr.e_entry);
236 if (retval < 0) 286 if (retval < 0)
237 goto error; 287 goto error;
238 288
@@ -245,17 +295,45 @@ int load_elf(const char * filename, uint8_t *addr) @@ -245,17 +295,45 @@ int load_elf(const char * filename, uint8_t *addr)
245 return -1; 295 return -1;
246 } 296 }
247 297
248 -int load_kernel(const char *filename, uint8_t *addr) 298 +int load_aout(const char *filename, uint8_t *addr)
249 { 299 {
250 - int fd, size; 300 + int fd, size, ret;
  301 + struct exec e;
  302 + uint32_t magic;
251 303
252 fd = open(filename, O_RDONLY | O_BINARY); 304 fd = open(filename, O_RDONLY | O_BINARY);
253 if (fd < 0) 305 if (fd < 0)
254 return -1; 306 return -1;
255 - /* load 32 bit code */  
256 - size = read(fd, addr, 16 * 1024 * 1024); 307 +
  308 + size = read(fd, &e, sizeof(e));
257 if (size < 0) 309 if (size < 0)
258 goto fail; 310 goto fail;
  311 +
  312 + bswap_ahdr(&e);
  313 +
  314 + magic = N_MAGIC(e);
  315 + switch (magic) {
  316 + case ZMAGIC:
  317 + case QMAGIC:
  318 + case OMAGIC:
  319 + lseek(fd, N_TXTOFF(e), SEEK_SET);
  320 + size = read(fd, addr, e.a_text + e.a_data);
  321 + if (size < 0)
  322 + goto fail;
  323 + break;
  324 + case NMAGIC:
  325 + lseek(fd, N_TXTOFF(e), SEEK_SET);
  326 + size = read(fd, addr, e.a_text);
  327 + if (size < 0)
  328 + goto fail;
  329 + ret = read(fd, addr + N_DATADDR(e), e.a_data);
  330 + if (ret < 0)
  331 + goto fail;
  332 + size += ret;
  333 + break;
  334 + default:
  335 + goto fail;
  336 + }
259 close(fd); 337 close(fd);
260 return size; 338 return size;
261 fail: 339 fail:
@@ -263,64 +341,3 @@ int load_kernel(const char *filename, uint8_t *addr) @@ -263,64 +341,3 @@ int load_kernel(const char *filename, uint8_t *addr)
263 return -1; 341 return -1;
264 } 342 }
265 343
266 -typedef struct MAGICState {  
267 - uint32_t addr;  
268 - uint32_t saved_addr;  
269 - int magic_state;  
270 - char saved_kfn[1024];  
271 -} MAGICState;  
272 -  
273 -static uint32_t magic_mem_readl(void *opaque, target_phys_addr_t addr)  
274 -{  
275 - int ret;  
276 - MAGICState *s = opaque;  
277 -  
278 - if (s->magic_state == 0) {  
279 - ret = load_elf(s->saved_kfn, (uint8_t *)s->saved_addr);  
280 - if (ret < 0)  
281 - ret = load_kernel(s->saved_kfn, (uint8_t *)s->saved_addr);  
282 - if (ret < 0) {  
283 - fprintf(stderr, "qemu: could not load kernel '%s'\n",  
284 - s->saved_kfn);  
285 - }  
286 - s->magic_state = 1; /* No more magic */  
287 - tb_flush();  
288 - return bswap32(ret);  
289 - }  
290 - return 0;  
291 -}  
292 -  
293 -static void magic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)  
294 -{  
295 -}  
296 -  
297 -  
298 -static CPUReadMemoryFunc *magic_mem_read[3] = {  
299 - magic_mem_readl,  
300 - magic_mem_readl,  
301 - magic_mem_readl,  
302 -};  
303 -  
304 -static CPUWriteMemoryFunc *magic_mem_write[3] = {  
305 - magic_mem_writel,  
306 - magic_mem_writel,  
307 - magic_mem_writel,  
308 -};  
309 -  
310 -void magic_init(const char *kfn, int kloadaddr, uint32_t addr)  
311 -{  
312 - int magic_io_memory;  
313 - MAGICState *s;  
314 -  
315 - s = qemu_mallocz(sizeof(MAGICState));  
316 - if (!s)  
317 - return;  
318 -  
319 - strcpy(s->saved_kfn, kfn);  
320 - s->saved_addr = kloadaddr;  
321 - s->magic_state = 0;  
322 - s->addr = addr;  
323 - magic_io_memory = cpu_register_io_memory(0, magic_mem_read, magic_mem_write, s);  
324 - cpu_register_physical_memory(addr, 4, magic_io_memory);  
325 -}  
326 -  
hw/sched.c deleted 100644 โ†’ 0
1 -/*  
2 - * QEMU interrupt controller emulation  
3 - *  
4 - * Copyright (c) 2003-2004 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 -//#define DEBUG_IRQ_COUNT  
26 -  
27 -/* These registers are used for sending/receiving irqs from/to  
28 - * different cpu's.  
29 - */  
30 -struct sun4m_intreg_percpu {  
31 - unsigned int tbt; /* Intrs pending for this cpu, by PIL. */  
32 - /* These next two registers are WRITE-ONLY and are only  
33 - * "on bit" sensitive, "off bits" written have NO affect.  
34 - */  
35 - unsigned int clear; /* Clear this cpus irqs here. */  
36 - unsigned int set; /* Set this cpus irqs here. */  
37 -};  
38 -/*  
39 - * djhr  
40 - * Actually the clear and set fields in this struct are misleading..  
41 - * according to the SLAVIO manual (and the same applies for the SEC)  
42 - * the clear field clears bits in the mask which will ENABLE that IRQ  
43 - * the set field sets bits in the mask to DISABLE the IRQ.  
44 - *  
45 - * Also the undirected_xx address in the SLAVIO is defined as  
46 - * RESERVED and write only..  
47 - *  
48 - * DAVEM_NOTE: The SLAVIO only specifies behavior on uniprocessor  
49 - * sun4m machines, for MP the layout makes more sense.  
50 - */  
51 -struct sun4m_intreg_master {  
52 - unsigned int tbt; /* IRQ's that are pending, see sun4m masks. */  
53 - unsigned int irqs; /* Master IRQ bits. */  
54 -  
55 - /* Again, like the above, two these registers are WRITE-ONLY. */  
56 - unsigned int clear; /* Clear master IRQ's by setting bits here. */  
57 - unsigned int set; /* Set master IRQ's by setting bits here. */  
58 -  
59 - /* This register is both READ and WRITE. */  
60 - unsigned int undirected_target; /* Which cpu gets undirected irqs. */  
61 -};  
62 -  
63 -#define SUN4M_INT_ENABLE 0x80000000  
64 -#define SUN4M_INT_E14 0x00000080  
65 -#define SUN4M_INT_E10 0x00080000  
66 -  
67 -#define SUN4M_HARD_INT(x) (0x000000001 << (x))  
68 -#define SUN4M_SOFT_INT(x) (0x000010000 << (x))  
69 -  
70 -#define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */  
71 -#define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */  
72 -#define SUN4M_INT_M2S_WRITE 0x20000000 /* write buffer error */  
73 -#define SUN4M_INT_ECC 0x10000000 /* ecc memory error */  
74 -#define SUN4M_INT_FLOPPY 0x00400000 /* floppy disk */  
75 -#define SUN4M_INT_MODULE 0x00200000 /* module interrupt */  
76 -#define SUN4M_INT_VIDEO 0x00100000 /* onboard video */  
77 -#define SUN4M_INT_REALTIME 0x00080000 /* system timer */  
78 -#define SUN4M_INT_SCSI 0x00040000 /* onboard scsi */  
79 -#define SUN4M_INT_AUDIO 0x00020000 /* audio/isdn */  
80 -#define SUN4M_INT_ETHERNET 0x00010000 /* onboard ethernet */  
81 -#define SUN4M_INT_SERIAL 0x00008000 /* serial ports */  
82 -#define SUN4M_INT_SBUSBITS 0x00003F80 /* sbus int bits */  
83 -  
84 -#define SUN4M_INT_SBUS(x) (1 << (x+7))  
85 -#define SUN4M_INT_VME(x) (1 << (x))  
86 -  
87 -typedef struct SCHEDState {  
88 - uint32_t addr, addrg;  
89 - uint32_t intreg_pending;  
90 - uint32_t intreg_enabled;  
91 - uint32_t intregm_pending;  
92 - uint32_t intregm_enabled;  
93 -} SCHEDState;  
94 -  
95 -static SCHEDState *ps;  
96 -  
97 -#ifdef DEBUG_IRQ_COUNT  
98 -static uint64_t irq_count[32];  
99 -#endif  
100 -  
101 -static uint32_t intreg_mem_readl(void *opaque, target_phys_addr_t addr)  
102 -{  
103 - SCHEDState *s = opaque;  
104 - uint32_t saddr;  
105 -  
106 - saddr = (addr - s->addr) >> 2;  
107 - switch (saddr) {  
108 - case 0:  
109 - return s->intreg_pending;  
110 - break;  
111 - default:  
112 - break;  
113 - }  
114 - return 0;  
115 -}  
116 -  
117 -static void intreg_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)  
118 -{  
119 - SCHEDState *s = opaque;  
120 - uint32_t saddr;  
121 -  
122 - saddr = (addr - s->addr) >> 2;  
123 - switch (saddr) {  
124 - case 0:  
125 - s->intreg_pending = val;  
126 - break;  
127 - case 1: // clear  
128 - s->intreg_enabled &= ~val;  
129 - break;  
130 - case 2: // set  
131 - s->intreg_enabled |= val;  
132 - break;  
133 - default:  
134 - break;  
135 - }  
136 -}  
137 -  
138 -static CPUReadMemoryFunc *intreg_mem_read[3] = {  
139 - intreg_mem_readl,  
140 - intreg_mem_readl,  
141 - intreg_mem_readl,  
142 -};  
143 -  
144 -static CPUWriteMemoryFunc *intreg_mem_write[3] = {  
145 - intreg_mem_writel,  
146 - intreg_mem_writel,  
147 - intreg_mem_writel,  
148 -};  
149 -  
150 -static uint32_t intregm_mem_readl(void *opaque, target_phys_addr_t addr)  
151 -{  
152 - SCHEDState *s = opaque;  
153 - uint32_t saddr;  
154 -  
155 - saddr = (addr - s->addrg) >> 2;  
156 - switch (saddr) {  
157 - case 0:  
158 - return s->intregm_pending;  
159 - break;  
160 - case 1:  
161 - return s->intregm_enabled;  
162 - break;  
163 - default:  
164 - break;  
165 - }  
166 - return 0;  
167 -}  
168 -  
169 -static void intregm_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)  
170 -{  
171 - SCHEDState *s = opaque;  
172 - uint32_t saddr;  
173 -  
174 - saddr = (addr - s->addrg) >> 2;  
175 - switch (saddr) {  
176 - case 0:  
177 - s->intregm_pending = val;  
178 - break;  
179 - case 1:  
180 - s->intregm_enabled = val;  
181 - break;  
182 - case 2: // clear  
183 - s->intregm_enabled &= ~val;  
184 - break;  
185 - case 3: // set  
186 - s->intregm_enabled |= val;  
187 - break;  
188 - default:  
189 - break;  
190 - }  
191 -}  
192 -  
193 -static CPUReadMemoryFunc *intregm_mem_read[3] = {  
194 - intregm_mem_readl,  
195 - intregm_mem_readl,  
196 - intregm_mem_readl,  
197 -};  
198 -  
199 -static CPUWriteMemoryFunc *intregm_mem_write[3] = {  
200 - intregm_mem_writel,  
201 - intregm_mem_writel,  
202 - intregm_mem_writel,  
203 -};  
204 -  
205 -void pic_info(void)  
206 -{  
207 - term_printf("per-cpu: pending 0x%08x, enabled 0x%08x\n", ps->intreg_pending, ps->intreg_enabled);  
208 - term_printf("master: pending 0x%08x, enabled 0x%08x\n", ps->intregm_pending, ps->intregm_enabled);  
209 -}  
210 -  
211 -void irq_info(void)  
212 -{  
213 -#ifndef DEBUG_IRQ_COUNT  
214 - term_printf("irq statistic code not compiled.\n");  
215 -#else  
216 - int i;  
217 - int64_t count;  
218 -  
219 - term_printf("IRQ statistics:\n");  
220 - for (i = 0; i < 32; i++) {  
221 - count = irq_count[i];  
222 - if (count > 0)  
223 - term_printf("%2d: %lld\n", i, count);  
224 - }  
225 -#endif  
226 -}  
227 -  
228 -static const unsigned int intr_to_mask[16] = {  
229 - 0, 0, 0, 0, 0, 0, SUN4M_INT_ETHERNET, 0,  
230 - 0, 0, 0, 0, 0, 0, 0, 0,  
231 -};  
232 -  
233 -void pic_set_irq(int irq, int level)  
234 -{  
235 - if (irq < 16) {  
236 - unsigned int mask = intr_to_mask[irq];  
237 - ps->intreg_pending |= 1 << irq;  
238 - if (ps->intregm_enabled & mask) {  
239 - cpu_single_env->interrupt_index = irq;  
240 - cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);  
241 - }  
242 - }  
243 -#ifdef DEBUG_IRQ_COUNT  
244 - if (level == 1)  
245 - irq_count[irq]++;  
246 -#endif  
247 -}  
248 -  
249 -void sched_init(uint32_t addr, uint32_t addrg)  
250 -{  
251 - int intreg_io_memory, intregm_io_memory;  
252 - SCHEDState *s;  
253 -  
254 - s = qemu_mallocz(sizeof(SCHEDState));  
255 - if (!s)  
256 - return;  
257 - s->addr = addr;  
258 - s->addrg = addrg;  
259 -  
260 - intreg_io_memory = cpu_register_io_memory(0, intreg_mem_read, intreg_mem_write, s);  
261 - cpu_register_physical_memory(addr, 3, intreg_io_memory);  
262 -  
263 - intregm_io_memory = cpu_register_io_memory(0, intregm_mem_read, intregm_mem_write, s);  
264 - cpu_register_physical_memory(addrg, 5, intregm_io_memory);  
265 -  
266 - ps = s;  
267 -}  
268 -  
hw/slavio_intctl.c 0 โ†’ 100644
  1 +/*
  2 + * QEMU Sparc SLAVIO interrupt controller emulation
  3 + *
  4 + * Copyright (c) 2003-2004 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 +//#define DEBUG_IRQ_COUNT
  26 +
  27 +/*
  28 + * Registers of interrupt controller in sun4m.
  29 + *
  30 + * This is the interrupt controller part of chip STP2001 (Slave I/O), also
  31 + * produced as NCR89C105. See
  32 + * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
  33 + *
  34 + * There is a system master controller and one for each cpu.
  35 + *
  36 + */
  37 +
  38 +#define MAX_CPUS 16
  39 +
  40 +typedef struct SLAVIO_INTCTLState {
  41 + uint32_t intreg_pending[MAX_CPUS];
  42 + uint32_t intregm_pending;
  43 + uint32_t intregm_disabled;
  44 + uint32_t target_cpu;
  45 +#ifdef DEBUG_IRQ_COUNT
  46 + uint64_t irq_count[32];
  47 +#endif
  48 +} SLAVIO_INTCTLState;
  49 +
  50 +#define INTCTL_MAXADDR 0xf
  51 +#define INTCTLM_MAXADDR 0xf
  52 +
  53 +// per-cpu interrupt controller
  54 +static uint32_t slavio_intctl_mem_readl(void *opaque, target_phys_addr_t addr)
  55 +{
  56 + SLAVIO_INTCTLState *s = opaque;
  57 + uint32_t saddr;
  58 + int cpu;
  59 +
  60 + cpu = (addr & (MAX_CPUS - 1) * TARGET_PAGE_SIZE) >> 12;
  61 + saddr = (addr & INTCTL_MAXADDR) >> 2;
  62 + switch (saddr) {
  63 + case 0:
  64 + return s->intreg_pending[cpu];
  65 + default:
  66 + break;
  67 + }
  68 + return 0;
  69 +}
  70 +
  71 +static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
  72 +{
  73 + SLAVIO_INTCTLState *s = opaque;
  74 + uint32_t saddr;
  75 + int cpu;
  76 +
  77 + cpu = (addr & (MAX_CPUS - 1) * TARGET_PAGE_SIZE) >> 12;
  78 + saddr = (addr & INTCTL_MAXADDR) >> 2;
  79 + switch (saddr) {
  80 + case 1: // clear pending softints
  81 + if (val & 0x4000)
  82 + val |= 80000000;
  83 + val &= 0xfffe0000;
  84 + s->intreg_pending[cpu] &= ~val;
  85 + break;
  86 + case 2: // set softint
  87 + val &= 0xfffe0000;
  88 + s->intreg_pending[cpu] |= val;
  89 + break;
  90 + default:
  91 + break;
  92 + }
  93 +}
  94 +
  95 +static CPUReadMemoryFunc *slavio_intctl_mem_read[3] = {
  96 + slavio_intctl_mem_readl,
  97 + slavio_intctl_mem_readl,
  98 + slavio_intctl_mem_readl,
  99 +};
  100 +
  101 +static CPUWriteMemoryFunc *slavio_intctl_mem_write[3] = {
  102 + slavio_intctl_mem_writel,
  103 + slavio_intctl_mem_writel,
  104 + slavio_intctl_mem_writel,
  105 +};
  106 +
  107 +// master system interrupt controller
  108 +static uint32_t slavio_intctlm_mem_readl(void *opaque, target_phys_addr_t addr)
  109 +{
  110 + SLAVIO_INTCTLState *s = opaque;
  111 + uint32_t saddr;
  112 +
  113 + saddr = (addr & INTCTLM_MAXADDR) >> 2;
  114 + switch (saddr) {
  115 + case 0:
  116 + return s->intregm_pending;
  117 + case 1:
  118 + return s->intregm_disabled;
  119 + case 4:
  120 + return s->target_cpu;
  121 + default:
  122 + break;
  123 + }
  124 + return 0;
  125 +}
  126 +
  127 +static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
  128 +{
  129 + SLAVIO_INTCTLState *s = opaque;
  130 + uint32_t saddr;
  131 +
  132 + saddr = (addr & INTCTLM_MAXADDR) >> 2;
  133 + switch (saddr) {
  134 + case 2: // clear (enable)
  135 + // Force unused bits
  136 + val |= 0x7fb2007f;
  137 + s->intregm_disabled &= ~val;
  138 + break;
  139 + case 3: // set (disable, clear pending)
  140 + // Force unused bits
  141 + val &= ~0x7fb2007f;
  142 + s->intregm_disabled |= val;
  143 + s->intregm_pending &= ~val;
  144 + break;
  145 + case 4:
  146 + s->target_cpu = val & (MAX_CPUS - 1);
  147 + break;
  148 + default:
  149 + break;
  150 + }
  151 +}
  152 +
  153 +static CPUReadMemoryFunc *slavio_intctlm_mem_read[3] = {
  154 + slavio_intctlm_mem_readl,
  155 + slavio_intctlm_mem_readl,
  156 + slavio_intctlm_mem_readl,
  157 +};
  158 +
  159 +static CPUWriteMemoryFunc *slavio_intctlm_mem_write[3] = {
  160 + slavio_intctlm_mem_writel,
  161 + slavio_intctlm_mem_writel,
  162 + slavio_intctlm_mem_writel,
  163 +};
  164 +
  165 +void slavio_pic_info(void *opaque)
  166 +{
  167 + SLAVIO_INTCTLState *s = opaque;
  168 + int i;
  169 +
  170 + for (i = 0; i < MAX_CPUS; i++) {
  171 + term_printf("per-cpu %d: pending 0x%08x\n", i, s->intreg_pending[i]);
  172 + }
  173 + term_printf("master: pending 0x%08x, disabled 0x%08x\n", s->intregm_pending, s->intregm_disabled);
  174 +}
  175 +
  176 +void slavio_irq_info(void *opaque)
  177 +{
  178 +#ifndef DEBUG_IRQ_COUNT
  179 + term_printf("irq statistic code not compiled.\n");
  180 +#else
  181 + SLAVIO_INTCTLState *s = opaque;
  182 + int i;
  183 + int64_t count;
  184 +
  185 + term_printf("IRQ statistics:\n");
  186 + for (i = 0; i < 32; i++) {
  187 + count = s->irq_count[i];
  188 + if (count > 0)
  189 + term_printf("%2d: %lld\n", i, count);
  190 + }
  191 +#endif
  192 +}
  193 +
  194 +static const uint32_t intbit_to_level[32] = {
  195 + 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
  196 + 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 0, 0,
  197 +};
  198 +
  199 +/*
  200 + * "irq" here is the bit number in the system interrupt register to
  201 + * separate serial and keyboard interrupts sharing a level.
  202 + */
  203 +void slavio_pic_set_irq(void *opaque, int irq, int level)
  204 +{
  205 + SLAVIO_INTCTLState *s = opaque;
  206 +
  207 + if (irq < 32) {
  208 + uint32_t mask = 1 << irq;
  209 + uint32_t pil = intbit_to_level[irq];
  210 + if (pil > 0) {
  211 + if (level) {
  212 + s->intregm_pending |= mask;
  213 + s->intreg_pending[s->target_cpu] |= 1 << pil;
  214 + }
  215 + else {
  216 + s->intregm_pending &= ~mask;
  217 + s->intreg_pending[s->target_cpu] &= ~(1 << pil);
  218 + }
  219 + if (level &&
  220 + !(s->intregm_disabled & mask) &&
  221 + !(s->intregm_disabled & 0x80000000) &&
  222 + (pil == 15 || (pil > cpu_single_env->psrpil && cpu_single_env->psret == 1))) {
  223 +#ifdef DEBUG_IRQ_COUNT
  224 + if (level == 1)
  225 + s->irq_count[pil]++;
  226 +#endif
  227 + cpu_single_env->interrupt_index = TT_EXTINT | pil;
  228 + cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);
  229 + }
  230 + }
  231 + }
  232 +}
  233 +
  234 +static void slavio_intctl_save(QEMUFile *f, void *opaque)
  235 +{
  236 + SLAVIO_INTCTLState *s = opaque;
  237 + int i;
  238 +
  239 + for (i = 0; i < MAX_CPUS; i++) {
  240 + qemu_put_be32s(f, &s->intreg_pending[i]);
  241 + }
  242 + qemu_put_be32s(f, &s->intregm_pending);
  243 + qemu_put_be32s(f, &s->intregm_disabled);
  244 + qemu_put_be32s(f, &s->target_cpu);
  245 +}
  246 +
  247 +static int slavio_intctl_load(QEMUFile *f, void *opaque, int version_id)
  248 +{
  249 + SLAVIO_INTCTLState *s = opaque;
  250 + int i;
  251 +
  252 + if (version_id != 1)
  253 + return -EINVAL;
  254 +
  255 + for (i = 0; i < MAX_CPUS; i++) {
  256 + qemu_get_be32s(f, &s->intreg_pending[i]);
  257 + }
  258 + qemu_get_be32s(f, &s->intregm_pending);
  259 + qemu_get_be32s(f, &s->intregm_disabled);
  260 + qemu_get_be32s(f, &s->target_cpu);
  261 + return 0;
  262 +}
  263 +
  264 +static void slavio_intctl_reset(void *opaque)
  265 +{
  266 + SLAVIO_INTCTLState *s = opaque;
  267 + int i;
  268 +
  269 + for (i = 0; i < MAX_CPUS; i++) {
  270 + s->intreg_pending[i] = 0;
  271 + }
  272 + s->intregm_disabled = 0xffffffff;
  273 + s->intregm_pending = 0;
  274 + s->target_cpu = 0;
  275 +}
  276 +
  277 +void *slavio_intctl_init(uint32_t addr, uint32_t addrg)
  278 +{
  279 + int slavio_intctl_io_memory, slavio_intctlm_io_memory, i;
  280 + SLAVIO_INTCTLState *s;
  281 +
  282 + s = qemu_mallocz(sizeof(SLAVIO_INTCTLState));
  283 + if (!s)
  284 + return NULL;
  285 +
  286 + for (i = 0; i < MAX_CPUS; i++) {
  287 + slavio_intctl_io_memory = cpu_register_io_memory(0, slavio_intctl_mem_read, slavio_intctl_mem_write, s);
  288 + cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_MAXADDR, slavio_intctl_io_memory);
  289 + }
  290 +
  291 + slavio_intctlm_io_memory = cpu_register_io_memory(0, slavio_intctlm_mem_read, slavio_intctlm_mem_write, s);
  292 + cpu_register_physical_memory(addrg, INTCTLM_MAXADDR, slavio_intctlm_io_memory);
  293 +
  294 + register_savevm("slavio_intctl", addr, 1, slavio_intctl_save, slavio_intctl_load, s);
  295 + qemu_register_reset(slavio_intctl_reset, s);
  296 + slavio_intctl_reset(s);
  297 + return s;
  298 +}
  299 +
hw/slavio_serial.c 0 โ†’ 100644
  1 +/*
  2 + * QEMU Sparc SLAVIO serial port emulation
  3 + *
  4 + * Copyright (c) 2003-2004 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 +//#define DEBUG_SERIAL
  27 +
  28 +/* debug keyboard */
  29 +//#define DEBUG_KBD
  30 +
  31 +/* debug keyboard : only mouse */
  32 +//#define DEBUG_MOUSE
  33 +
  34 +/*
  35 + * This is the serial port, mouse and keyboard part of chip STP2001
  36 + * (Slave I/O), also produced as NCR89C105. See
  37 + * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
  38 + *
  39 + * The serial ports implement full AMD AM8530 or Zilog Z8530 chips,
  40 + * mouse and keyboard ports don't implement all functions and they are
  41 + * only asynchronous. There is no DMA.
  42 + *
  43 + */
  44 +
  45 +typedef struct ChannelState {
  46 + int irq;
  47 + int reg;
  48 + int rxint, txint;
  49 + uint8_t rx, tx, wregs[16], rregs[16];
  50 + CharDriverState *chr;
  51 +} ChannelState;
  52 +
  53 +struct SerialState {
  54 + struct ChannelState chn[2];
  55 +};
  56 +
  57 +#define SERIAL_MAXADDR 7
  58 +
  59 +static void slavio_serial_update_irq(ChannelState *s)
  60 +{
  61 + if ((s->wregs[1] & 1) && // interrupts enabled
  62 + (((s->wregs[1] & 2) && s->txint == 1) || // tx ints enabled, pending
  63 + ((((s->wregs[1] & 0x18) == 8) || ((s->wregs[1] & 0x18) == 0x10)) &&
  64 + s->rxint == 1) || // rx ints enabled, pending
  65 + ((s->wregs[15] & 0x80) && (s->rregs[0] & 0x80)))) { // break int e&p
  66 + pic_set_irq(s->irq, 1);
  67 + } else {
  68 + pic_set_irq(s->irq, 0);
  69 + }
  70 +}
  71 +
  72 +static void slavio_serial_reset_chn(ChannelState *s)
  73 +{
  74 + int i;
  75 +
  76 + s->reg = 0;
  77 + for (i = 0; i < SERIAL_MAXADDR; i++) {
  78 + s->rregs[i] = 0;
  79 + s->wregs[i] = 0;
  80 + }
  81 + s->wregs[4] = 4;
  82 + s->wregs[9] = 0xc0;
  83 + s->wregs[11] = 8;
  84 + s->wregs[14] = 0x30;
  85 + s->wregs[15] = 0xf8;
  86 + s->rregs[0] = 0x44;
  87 + s->rregs[1] = 6;
  88 +
  89 + s->rx = s->tx = 0;
  90 + s->rxint = s->txint = 0;
  91 +}
  92 +
  93 +static void slavio_serial_reset(void *opaque)
  94 +{
  95 + SerialState *s = opaque;
  96 + slavio_serial_reset_chn(&s->chn[0]);
  97 + slavio_serial_reset_chn(&s->chn[1]);
  98 +}
  99 +
  100 +static void slavio_serial_mem_writeb(void *opaque, uint32_t addr, uint32_t val)
  101 +{
  102 + SerialState *ser = opaque;
  103 + ChannelState *s;
  104 + uint32_t saddr;
  105 + int newreg, channel;
  106 +
  107 + val &= 0xff;
  108 + saddr = (addr & 3) >> 1;
  109 + channel = (addr & SERIAL_MAXADDR) >> 2;
  110 + s = &ser->chn[channel];
  111 + switch (saddr) {
  112 + case 0:
  113 + newreg = 0;
  114 + switch (s->reg) {
  115 + case 0:
  116 + newreg = val & 7;
  117 + val &= 0x38;
  118 + switch (val) {
  119 + case 8:
  120 + s->reg |= 0x8;
  121 + break;
  122 + case 0x20:
  123 + s->rxint = 0;
  124 + break;
  125 + case 0x28:
  126 + s->txint = 0;
  127 + break;
  128 + default:
  129 + break;
  130 + }
  131 + break;
  132 + case 1 ... 8:
  133 + case 10 ... 15:
  134 + s->wregs[s->reg] = val;
  135 + break;
  136 + case 9:
  137 + switch (val & 0xc0) {
  138 + case 0:
  139 + default:
  140 + break;
  141 + case 0x40:
  142 + slavio_serial_reset_chn(&ser->chn[1]);
  143 + return;
  144 + case 0x80:
  145 + slavio_serial_reset_chn(&ser->chn[0]);
  146 + return;
  147 + case 0xc0:
  148 + slavio_serial_reset(ser);
  149 + return;
  150 + }
  151 + break;
  152 + default:
  153 + break;
  154 + }
  155 + if (s->reg == 0)
  156 + s->reg = newreg;
  157 + else
  158 + s->reg = 0;
  159 + break;
  160 + case 1:
  161 + if (s->wregs[5] & 8) { // tx enabled
  162 + s->tx = val;
  163 + if (s->chr)
  164 + qemu_chr_write(s->chr, &s->tx, 1);
  165 + s->txint = 1;
  166 + }
  167 + break;
  168 + default:
  169 + break;
  170 + }
  171 +}
  172 +
  173 +static uint32_t slavio_serial_mem_readb(void *opaque, uint32_t addr)
  174 +{
  175 + SerialState *ser = opaque;
  176 + ChannelState *s;
  177 + uint32_t saddr;
  178 + uint32_t ret;
  179 + int channel;
  180 +
  181 + saddr = (addr & 3) >> 1;
  182 + channel = (addr & SERIAL_MAXADDR) >> 2;
  183 + s = &ser->chn[channel];
  184 + switch (saddr) {
  185 + case 0:
  186 + ret = s->rregs[s->reg];
  187 + s->reg = 0;
  188 + return ret;
  189 + case 1:
  190 + s->rregs[0] &= ~1;
  191 + return s->rx;
  192 + default:
  193 + break;
  194 + }
  195 + return 0;
  196 +}
  197 +
  198 +static int serial_can_receive(void *opaque)
  199 +{
  200 + ChannelState *s = opaque;
  201 + if (((s->wregs[3] & 1) == 0) // Rx not enabled
  202 + || ((s->rregs[0] & 1) == 1)) // char already available
  203 + return 0;
  204 + else
  205 + return 1;
  206 +}
  207 +
  208 +static void serial_receive_byte(ChannelState *s, int ch)
  209 +{
  210 + s->rregs[0] |= 1;
  211 + s->rx = ch;
  212 + s->rxint = 1;
  213 + slavio_serial_update_irq(s);
  214 +}
  215 +
  216 +static void serial_receive_break(ChannelState *s)
  217 +{
  218 + s->rregs[0] |= 0x80;
  219 + slavio_serial_update_irq(s);
  220 +}
  221 +
  222 +static void serial_receive1(void *opaque, const uint8_t *buf, int size)
  223 +{
  224 + ChannelState *s = opaque;
  225 + serial_receive_byte(s, buf[0]);
  226 +}
  227 +
  228 +static void serial_event(void *opaque, int event)
  229 +{
  230 + ChannelState *s = opaque;
  231 + if (event == CHR_EVENT_BREAK)
  232 + serial_receive_break(s);
  233 +}
  234 +
  235 +static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
  236 + slavio_serial_mem_readb,
  237 + slavio_serial_mem_readb,
  238 + slavio_serial_mem_readb,
  239 +};
  240 +
  241 +static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
  242 + slavio_serial_mem_writeb,
  243 + slavio_serial_mem_writeb,
  244 + slavio_serial_mem_writeb,
  245 +};
  246 +
  247 +static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
  248 +{
  249 + qemu_put_be32s(f, &s->irq);
  250 + qemu_put_be32s(f, &s->reg);
  251 + qemu_put_be32s(f, &s->rxint);
  252 + qemu_put_be32s(f, &s->txint);
  253 + qemu_put_8s(f, &s->rx);
  254 + qemu_put_8s(f, &s->tx);
  255 + qemu_put_buffer(f, s->wregs, 16);
  256 + qemu_put_buffer(f, s->rregs, 16);
  257 +}
  258 +
  259 +static void slavio_serial_save(QEMUFile *f, void *opaque)
  260 +{
  261 + SerialState *s = opaque;
  262 +
  263 + slavio_serial_save_chn(f, &s->chn[0]);
  264 + slavio_serial_save_chn(f, &s->chn[1]);
  265 +}
  266 +
  267 +static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
  268 +{
  269 + if (version_id != 1)
  270 + return -EINVAL;
  271 +
  272 + qemu_get_be32s(f, &s->irq);
  273 + qemu_get_be32s(f, &s->reg);
  274 + qemu_get_be32s(f, &s->rxint);
  275 + qemu_get_be32s(f, &s->txint);
  276 + qemu_get_8s(f, &s->rx);
  277 + qemu_get_8s(f, &s->tx);
  278 + qemu_get_buffer(f, s->wregs, 16);
  279 + qemu_get_buffer(f, s->rregs, 16);
  280 + return 0;
  281 +}
  282 +
  283 +static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
  284 +{
  285 + SerialState *s = opaque;
  286 + int ret;
  287 +
  288 + ret = slavio_serial_load_chn(f, &s->chn[0], version_id);
  289 + if (ret != 0)
  290 + return ret;
  291 + ret = slavio_serial_load_chn(f, &s->chn[1], version_id);
  292 + return ret;
  293 +
  294 +}
  295 +
  296 +SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2)
  297 +{
  298 + int slavio_serial_io_memory;
  299 + SerialState *s;
  300 +
  301 + s = qemu_mallocz(sizeof(SerialState));
  302 + if (!s)
  303 + return NULL;
  304 + s->chn[0].irq = irq;
  305 + s->chn[1].irq = irq;
  306 + s->chn[0].chr = chr1;
  307 + s->chn[1].chr = chr2;
  308 +
  309 + slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
  310 + cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
  311 +
  312 + if (chr1) {
  313 + qemu_chr_add_read_handler(chr1, serial_can_receive, serial_receive1, &s->chn[0]);
  314 + qemu_chr_add_event_handler(chr1, serial_event);
  315 + }
  316 + if (chr2) {
  317 + qemu_chr_add_read_handler(chr2, serial_can_receive, serial_receive1, &s->chn[1]);
  318 + qemu_chr_add_event_handler(chr2, serial_event);
  319 + }
  320 + register_savevm("slavio_serial", base, 1, slavio_serial_save, slavio_serial_load, s);
  321 + qemu_register_reset(slavio_serial_reset, s);
  322 + slavio_serial_reset(s);
  323 + return s;
  324 +}
  325 +
  326 +static void sunkbd_event(void *opaque, int ch)
  327 +{
  328 + ChannelState *s = opaque;
  329 + // XXX: PC -> Sun Type 5 translation?
  330 + serial_receive_byte(s, ch);
  331 +}
  332 +
  333 +static void sunmouse_event(void *opaque,
  334 + int dx, int dy, int dz, int buttons_state)
  335 +{
  336 + ChannelState *s = opaque;
  337 + int ch;
  338 +
  339 + // XXX
  340 + ch = 0x42;
  341 + serial_receive_byte(s, ch);
  342 +}
  343 +
  344 +void slavio_serial_ms_kbd_init(int base, int irq)
  345 +{
  346 + int slavio_serial_io_memory;
  347 + SerialState *s;
  348 +
  349 + s = qemu_mallocz(sizeof(SerialState));
  350 + if (!s)
  351 + return;
  352 + s->chn[0].irq = irq;
  353 + s->chn[1].irq = irq;
  354 + s->chn[0].chr = NULL;
  355 + s->chn[1].chr = NULL;
  356 +
  357 + slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read, slavio_serial_mem_write, s);
  358 + cpu_register_physical_memory(base, SERIAL_MAXADDR, slavio_serial_io_memory);
  359 +
  360 + qemu_add_kbd_event_handler(sunkbd_event, &s->chn[0]);
  361 + qemu_add_mouse_event_handler(sunmouse_event, &s->chn[1]);
  362 + qemu_register_reset(slavio_serial_reset, s);
  363 + slavio_serial_reset(s);
  364 +}
hw/slavio_timer.c 0 โ†’ 100644
  1 +/*
  2 + * QEMU Sparc SLAVIO timer controller emulation
  3 + *
  4 + * Copyright (c) 2003-2004 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 +//#define DEBUG_TIMER
  27 +
  28 +/*
  29 + * Registers of hardware timer in sun4m.
  30 + *
  31 + * This is the timer/counter part of chip STP2001 (Slave I/O), also
  32 + * produced as NCR89C105. See
  33 + * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
  34 + *
  35 + * The 31-bit counter is incremented every 500ns by bit 9. Bits 8..0
  36 + * are zero. Bit 31 is 1 when count has been reached.
  37 + *
  38 + */
  39 +
  40 +typedef struct SLAVIO_TIMERState {
  41 + uint32_t limit, count, counthigh;
  42 + int64_t count_load_time;
  43 + int64_t expire_time;
  44 + int64_t stop_time, tick_offset;
  45 + QEMUTimer *irq_timer;
  46 + int irq;
  47 + int reached, stopped;
  48 + int mode; // 0 = processor, 1 = user, 2 = system
  49 +} SLAVIO_TIMERState;
  50 +
  51 +#define TIMER_MAXADDR 0x1f
  52 +#define CNT_FREQ 2000000
  53 +#define MAX_CPUS 16
  54 +
  55 +// Update count, set irq, update expire_time
  56 +static void slavio_timer_get_out(SLAVIO_TIMERState *s)
  57 +{
  58 + int out;
  59 + int64_t diff, ticks, count;
  60 + uint32_t limit;
  61 +
  62 + // There are three clock tick units: CPU ticks, register units
  63 + // (nanoseconds), and counter ticks (500 ns).
  64 + if (s->mode == 1 && s->stopped)
  65 + ticks = s->stop_time;
  66 + else
  67 + ticks = qemu_get_clock(vm_clock) - s->tick_offset;
  68 +
  69 + out = (ticks >= s->expire_time);
  70 + if (out)
  71 + s->reached = 0x80000000;
  72 + if (!s->limit)
  73 + limit = 0x7fffffff;
  74 + else
  75 + limit = s->limit;
  76 +
  77 + // Convert register units to counter ticks
  78 + limit = limit >> 9;
  79 +
  80 + // Convert cpu ticks to counter ticks
  81 + diff = muldiv64(ticks - s->count_load_time, CNT_FREQ, ticks_per_sec);
  82 +
  83 + // Calculate what the counter should be, convert to register
  84 + // units
  85 + count = diff % limit;
  86 + s->count = count << 9;
  87 + s->counthigh = count >> 22;
  88 +
  89 + // Expire time: CPU ticks left to next interrupt
  90 + // Convert remaining counter ticks to CPU ticks
  91 + s->expire_time = ticks + muldiv64(limit - count, ticks_per_sec, CNT_FREQ);
  92 +
  93 +#ifdef DEBUG_TIMER
  94 + term_printf("timer: irq %d limit %d reached %d d %lld count %d s->c %x diff %lld stopped %d mode %d\n", s->irq, limit, s->reached?1:0, (ticks-s->count_load_time), count, s->count, s->expire_time - ticks, s->stopped, s->mode);
  95 +#endif
  96 + if (s->mode != 1)
  97 + pic_set_irq(s->irq, out);
  98 +}
  99 +
  100 +// timer callback
  101 +static void slavio_timer_irq(void *opaque)
  102 +{
  103 + SLAVIO_TIMERState *s = opaque;
  104 +
  105 + if (!s->irq_timer)
  106 + return;
  107 + slavio_timer_get_out(s);
  108 + if (s->mode != 1)
  109 + qemu_mod_timer(s->irq_timer, s->expire_time);
  110 +}
  111 +
  112 +static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr)
  113 +{
  114 + SLAVIO_TIMERState *s = opaque;
  115 + uint32_t saddr;
  116 +
  117 + saddr = (addr & TIMER_MAXADDR) >> 2;
  118 + switch (saddr) {
  119 + case 0:
  120 + // read limit (system counter mode) or read most signifying
  121 + // part of counter (user mode)
  122 + if (s->mode != 1) {
  123 + // clear irq
  124 + pic_set_irq(s->irq, 0);
  125 + s->count_load_time = qemu_get_clock(vm_clock);
  126 + s->reached = 0;
  127 + return s->limit;
  128 + }
  129 + else {
  130 + slavio_timer_get_out(s);
  131 + return s->counthigh & 0x7fffffff;
  132 + }
  133 + case 1:
  134 + // read counter and reached bit (system mode) or read lsbits
  135 + // of counter (user mode)
  136 + slavio_timer_get_out(s);
  137 + if (s->mode != 1)
  138 + return (s->count & 0x7fffffff) | s->reached;
  139 + else
  140 + return s->count;
  141 + case 3:
  142 + // read start/stop status
  143 + return s->stopped;
  144 + case 4:
  145 + // read user/system mode
  146 + return s->mode & 1;
  147 + default:
  148 + return 0;
  149 + }
  150 +}
  151 +
  152 +static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
  153 +{
  154 + SLAVIO_TIMERState *s = opaque;
  155 + uint32_t saddr;
  156 +
  157 + saddr = (addr & TIMER_MAXADDR) >> 2;
  158 + switch (saddr) {
  159 + case 0:
  160 + // set limit, reset counter
  161 + s->count_load_time = qemu_get_clock(vm_clock);
  162 + // fall through
  163 + case 2:
  164 + // set limit without resetting counter
  165 + if (!val)
  166 + s->limit = 0x7fffffff;
  167 + else
  168 + s->limit = val & 0x7fffffff;
  169 + slavio_timer_irq(s);
  170 + break;
  171 + case 3:
  172 + // start/stop user counter
  173 + if (s->mode == 1) {
  174 + if (val & 1) {
  175 + s->stop_time = qemu_get_clock(vm_clock);
  176 + s->stopped = 1;
  177 + }
  178 + else {
  179 + if (s->stopped)
  180 + s->tick_offset += qemu_get_clock(vm_clock) - s->stop_time;
  181 + s->stopped = 0;
  182 + }
  183 + }
  184 + break;
  185 + case 4:
  186 + // bit 0: user (1) or system (0) counter mode
  187 + if (s->mode == 0 || s->mode == 1)
  188 + s->mode = val & 1;
  189 + break;
  190 + default:
  191 + break;
  192 + }
  193 +}
  194 +
  195 +static CPUReadMemoryFunc *slavio_timer_mem_read[3] = {
  196 + slavio_timer_mem_readl,
  197 + slavio_timer_mem_readl,
  198 + slavio_timer_mem_readl,
  199 +};
  200 +
  201 +static CPUWriteMemoryFunc *slavio_timer_mem_write[3] = {
  202 + slavio_timer_mem_writel,
  203 + slavio_timer_mem_writel,
  204 + slavio_timer_mem_writel,
  205 +};
  206 +
  207 +static void slavio_timer_save(QEMUFile *f, void *opaque)
  208 +{
  209 + SLAVIO_TIMERState *s = opaque;
  210 +
  211 + qemu_put_be32s(f, &s->limit);
  212 + qemu_put_be32s(f, &s->count);
  213 + qemu_put_be32s(f, &s->counthigh);
  214 + qemu_put_be64s(f, &s->count_load_time);
  215 + qemu_put_be64s(f, &s->expire_time);
  216 + qemu_put_be64s(f, &s->stop_time);
  217 + qemu_put_be64s(f, &s->tick_offset);
  218 + qemu_put_be32s(f, &s->irq);
  219 + qemu_put_be32s(f, &s->reached);
  220 + qemu_put_be32s(f, &s->stopped);
  221 + qemu_put_be32s(f, &s->mode);
  222 +}
  223 +
  224 +static int slavio_timer_load(QEMUFile *f, void *opaque, int version_id)
  225 +{
  226 + SLAVIO_TIMERState *s = opaque;
  227 +
  228 + if (version_id != 1)
  229 + return -EINVAL;
  230 +
  231 + qemu_get_be32s(f, &s->limit);
  232 + qemu_get_be32s(f, &s->count);
  233 + qemu_get_be32s(f, &s->counthigh);
  234 + qemu_get_be64s(f, &s->count_load_time);
  235 + qemu_get_be64s(f, &s->expire_time);
  236 + qemu_get_be64s(f, &s->stop_time);
  237 + qemu_get_be64s(f, &s->tick_offset);
  238 + qemu_get_be32s(f, &s->irq);
  239 + qemu_get_be32s(f, &s->reached);
  240 + qemu_get_be32s(f, &s->stopped);
  241 + qemu_get_be32s(f, &s->mode);
  242 + return 0;
  243 +}
  244 +
  245 +static void slavio_timer_reset(void *opaque)
  246 +{
  247 + SLAVIO_TIMERState *s = opaque;
  248 +
  249 + s->limit = 0;
  250 + s->count = 0;
  251 + s->count_load_time = qemu_get_clock(vm_clock);;
  252 + s->stop_time = s->count_load_time;
  253 + s->tick_offset = 0;
  254 + s->reached = 0;
  255 + s->mode &= 2;
  256 + s->stopped = 1;
  257 + slavio_timer_get_out(s);
  258 +}
  259 +
  260 +static void slavio_timer_init_internal(uint32_t addr, int irq, int mode)
  261 +{
  262 + int slavio_timer_io_memory;
  263 + SLAVIO_TIMERState *s;
  264 +
  265 + s = qemu_mallocz(sizeof(SLAVIO_TIMERState));
  266 + if (!s)
  267 + return;
  268 + s->irq = irq;
  269 + s->mode = mode;
  270 + s->irq_timer = qemu_new_timer(vm_clock, slavio_timer_irq, s);
  271 +
  272 + slavio_timer_io_memory = cpu_register_io_memory(0, slavio_timer_mem_read,
  273 + slavio_timer_mem_write, s);
  274 + cpu_register_physical_memory(addr, TIMER_MAXADDR, slavio_timer_io_memory);
  275 + register_savevm("slavio_timer", addr, 1, slavio_timer_save, slavio_timer_load, s);
  276 + qemu_register_reset(slavio_timer_reset, s);
  277 + slavio_timer_reset(s);
  278 +}
  279 +
  280 +void slavio_timer_init(uint32_t addr1, int irq1, uint32_t addr2, int irq2)
  281 +{
  282 + int i;
  283 +
  284 + for (i = 0; i < MAX_CPUS; i++) {
  285 + slavio_timer_init_internal(addr1 + i * TARGET_PAGE_SIZE, irq1, 0);
  286 + }
  287 +
  288 + slavio_timer_init_internal(addr2, irq2, 2);
  289 +}
hw/sun4m.c
@@ -25,29 +25,32 @@ @@ -25,29 +25,32 @@
25 #include "m48t08.h" 25 #include "m48t08.h"
26 26
27 #define KERNEL_LOAD_ADDR 0x00004000 27 #define KERNEL_LOAD_ADDR 0x00004000
28 -#define MMU_CONTEXT_TBL 0x00003000  
29 -#define MMU_L1PTP (MMU_CONTEXT_TBL + 0x0400)  
30 -#define MMU_L2PTP (MMU_CONTEXT_TBL + 0x0800)  
31 -#define PROM_ADDR 0xffd04000 28 +#define PROM_ADDR 0xffd00000
32 #define PROM_FILENAMEB "proll.bin" 29 #define PROM_FILENAMEB "proll.bin"
33 #define PROM_FILENAMEE "proll.elf" 30 #define PROM_FILENAMEE "proll.elf"
34 -#define PROLL_MAGIC_ADDR 0x20000000  
35 -#define PHYS_JJ_EEPROM 0x71200000 /* [2000] MK48T08 */ 31 +#define PHYS_JJ_EEPROM 0x71200000 /* m48t08 */
36 #define PHYS_JJ_IDPROM_OFF 0x1FD8 32 #define PHYS_JJ_IDPROM_OFF 0x1FD8
37 #define PHYS_JJ_EEPROM_SIZE 0x2000 33 #define PHYS_JJ_EEPROM_SIZE 0x2000
38 -#define PHYS_JJ_IOMMU 0x10000000 /* First page of sun4m IOMMU */ 34 +// IRQs are not PIL ones, but master interrupt controller register
  35 +// bits
  36 +#define PHYS_JJ_IOMMU 0x10000000 /* I/O MMU */
39 #define PHYS_JJ_TCX_FB 0x50800000 /* Start address, frame buffer body */ 37 #define PHYS_JJ_TCX_FB 0x50800000 /* Start address, frame buffer body */
40 -#define PHYS_JJ_TCX_0E 0x5E000000 /* Top address, one byte used. */  
41 -#define PHYS_JJ_IOMMU 0x10000000 /* First page of sun4m IOMMU */  
42 -#define PHYS_JJ_LEDMA 0x78400010 /* ledma, off by 10 from unused SCSI */  
43 -#define PHYS_JJ_LE 0x78C00000 /* LANCE, typical sun4m */  
44 -#define PHYS_JJ_LE_IRQ 6  
45 -#define PHYS_JJ_CLOCK 0x71D00000  
46 -#define PHYS_JJ_CLOCK_IRQ 10  
47 -#define PHYS_JJ_CLOCK1 0x71D10000  
48 -#define PHYS_JJ_CLOCK1_IRQ 14  
49 -#define PHYS_JJ_INTR0 0x71E00000 /* CPU0 interrupt control registers */ 38 +#define PHYS_JJ_LEDMA 0x78400010 /* Lance DMA controller */
  39 +#define PHYS_JJ_LE 0x78C00000 /* Lance ethernet */
  40 +#define PHYS_JJ_LE_IRQ 16
  41 +#define PHYS_JJ_CLOCK 0x71D00000 /* Per-CPU timer/counter, L14 */
  42 +#define PHYS_JJ_CLOCK_IRQ 7
  43 +#define PHYS_JJ_CLOCK1 0x71D10000 /* System timer/counter, L10 */
  44 +#define PHYS_JJ_CLOCK1_IRQ 19
  45 +#define PHYS_JJ_INTR0 0x71E00000 /* Per-CPU interrupt control registers */
50 #define PHYS_JJ_INTR_G 0x71E10000 /* Master interrupt control registers */ 46 #define PHYS_JJ_INTR_G 0x71E10000 /* Master interrupt control registers */
  47 +#define PHYS_JJ_MS_KBD 0x71000000 /* Mouse and keyboard */
  48 +#define PHYS_JJ_MS_KBD_IRQ 14
  49 +#define PHYS_JJ_SER 0x71100000 /* Serial */
  50 +#define PHYS_JJ_SER_IRQ 15
  51 +#define PHYS_JJ_SCSI_IRQ 18
  52 +#define PHYS_JJ_FDC 0x71400000 /* Floppy */
  53 +#define PHYS_JJ_FLOPPY_IRQ 22
51 54
52 /* TSC handling */ 55 /* TSC handling */
53 56
@@ -57,13 +60,73 @@ uint64_t cpu_get_tsc() @@ -57,13 +60,73 @@ uint64_t cpu_get_tsc()
57 } 60 }
58 61
59 void DMA_run() {} 62 void DMA_run() {}
60 -void SB16_run() {}  
61 -int serial_can_receive(SerialState *s) { return 0; }  
62 -void serial_receive_byte(SerialState *s, int ch) {}  
63 -void serial_receive_break(SerialState *s) {}  
64 63
65 static m48t08_t *nvram; 64 static m48t08_t *nvram;
66 65
  66 +static void nvram_init(m48t08_t *nvram, uint8_t *macaddr)
  67 +{
  68 + unsigned char tmp = 0;
  69 + int i, j;
  70 +
  71 + i = 0x1fd8;
  72 + m48t08_write(nvram, i++, 0x01);
  73 + m48t08_write(nvram, i++, 0x80); /* Sun4m OBP */
  74 + j = 0;
  75 + m48t08_write(nvram, i++, macaddr[j++]);
  76 + m48t08_write(nvram, i++, macaddr[j++]);
  77 + m48t08_write(nvram, i++, macaddr[j++]);
  78 + m48t08_write(nvram, i++, macaddr[j++]);
  79 + m48t08_write(nvram, i++, macaddr[j++]);
  80 + m48t08_write(nvram, i, macaddr[j]);
  81 +
  82 + /* Calculate checksum */
  83 + for (i = 0x1fd8; i < 0x1fe7; i++) {
  84 + tmp ^= m48t08_read(nvram, i);
  85 + }
  86 + m48t08_write(nvram, 0x1fe7, tmp);
  87 +}
  88 +
  89 +static void *slavio_intctl;
  90 +
  91 +void pic_info()
  92 +{
  93 + slavio_pic_info(slavio_intctl);
  94 +}
  95 +
  96 +void irq_info()
  97 +{
  98 + slavio_irq_info(slavio_intctl);
  99 +}
  100 +
  101 +void pic_set_irq(int irq, int level)
  102 +{
  103 + slavio_pic_set_irq(slavio_intctl, irq, level);
  104 +}
  105 +
  106 +static void *tcx;
  107 +
  108 +void vga_update_display()
  109 +{
  110 + tcx_update_display(tcx);
  111 +}
  112 +
  113 +void vga_invalidate_display()
  114 +{
  115 + tcx_invalidate_display(tcx);
  116 +}
  117 +
  118 +void vga_screen_dump(const char *filename)
  119 +{
  120 + tcx_screen_dump(tcx, filename);
  121 +}
  122 +
  123 +static void *iommu;
  124 +
  125 +uint32_t iommu_translate(uint32_t addr)
  126 +{
  127 + return iommu_translate_local(iommu, addr);
  128 +}
  129 +
67 /* Sun4m hardware initialisation */ 130 /* Sun4m hardware initialisation */
68 void sun4m_init(int ram_size, int vga_ram_size, int boot_device, 131 void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
69 DisplayState *ds, const char **fd_filename, int snapshot, 132 DisplayState *ds, const char **fd_filename, int snapshot,
@@ -72,42 +135,50 @@ void sun4m_init(int ram_size, int vga_ram_size, int boot_device, @@ -72,42 +135,50 @@ void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
72 { 135 {
73 char buf[1024]; 136 char buf[1024];
74 int ret, linux_boot; 137 int ret, linux_boot;
75 - unsigned long bios_offset; 138 + unsigned long vram_size = 0x100000, prom_offset;
76 139
77 linux_boot = (kernel_filename != NULL); 140 linux_boot = (kernel_filename != NULL);
78 141
79 /* allocate RAM */ 142 /* allocate RAM */
80 cpu_register_physical_memory(0, ram_size, 0); 143 cpu_register_physical_memory(0, ram_size, 0);
81 - bios_offset = ram_size;  
82 144
83 - iommu_init(PHYS_JJ_IOMMU);  
84 - sched_init(PHYS_JJ_INTR0, PHYS_JJ_INTR_G);  
85 - tcx_init(ds, PHYS_JJ_TCX_FB); 145 + iommu = iommu_init(PHYS_JJ_IOMMU);
  146 + slavio_intctl = slavio_intctl_init(PHYS_JJ_INTR0, PHYS_JJ_INTR_G);
  147 + tcx = tcx_init(ds, PHYS_JJ_TCX_FB, phys_ram_base + ram_size, ram_size, vram_size);
86 lance_init(&nd_table[0], PHYS_JJ_LE_IRQ, PHYS_JJ_LE, PHYS_JJ_LEDMA); 148 lance_init(&nd_table[0], PHYS_JJ_LE_IRQ, PHYS_JJ_LE, PHYS_JJ_LEDMA);
87 - nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE, &nd_table[0].macaddr);  
88 - timer_init(PHYS_JJ_CLOCK, PHYS_JJ_CLOCK_IRQ);  
89 - timer_init(PHYS_JJ_CLOCK1, PHYS_JJ_CLOCK1_IRQ);  
90 - magic_init(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR, PROLL_MAGIC_ADDR); 149 + nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE);
  150 + nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr);
  151 + slavio_timer_init(PHYS_JJ_CLOCK, PHYS_JJ_CLOCK_IRQ, PHYS_JJ_CLOCK1, PHYS_JJ_CLOCK1_IRQ);
  152 + slavio_serial_ms_kbd_init(PHYS_JJ_MS_KBD, PHYS_JJ_MS_KBD_IRQ);
  153 + slavio_serial_init(PHYS_JJ_SER, PHYS_JJ_SER_IRQ, serial_hds[0], serial_hds[1]);
  154 + fdctrl_init(PHYS_JJ_FLOPPY_IRQ, 0, 1, PHYS_JJ_FDC, fd_table);
91 155
92 - /* We load Proll as the kernel and start it. It will issue a magic  
93 - IO to load the real kernel */  
94 - if (linux_boot) { 156 + prom_offset = ram_size + vram_size;
  157 +
  158 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE);
  159 + ret = load_elf(buf, phys_ram_base + prom_offset);
  160 + if (ret < 0) {
95 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB); 161 snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB);
96 - ret = load_kernel(buf,  
97 - phys_ram_base + KERNEL_LOAD_ADDR); 162 + ret = load_image(buf, phys_ram_base + prom_offset);
  163 + }
  164 + if (ret < 0) {
  165 + fprintf(stderr, "qemu: could not load prom '%s'\n",
  166 + buf);
  167 + exit(1);
  168 + }
  169 + cpu_register_physical_memory(PROM_ADDR, (ret + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK,
  170 + prom_offset | IO_MEM_ROM);
  171 +
  172 + if (linux_boot) {
  173 + ret = load_elf(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
  174 + if (ret < 0)
  175 + ret = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
  176 + if (ret < 0)
  177 + ret = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
98 if (ret < 0) { 178 if (ret < 0) {
99 fprintf(stderr, "qemu: could not load kernel '%s'\n", 179 fprintf(stderr, "qemu: could not load kernel '%s'\n",
100 - buf);  
101 - exit(1); 180 + kernel_filename);
  181 + exit(1);
102 } 182 }
103 } 183 }
104 - /* Setup a MMU entry for entire address space */  
105 - stl_raw(phys_ram_base + MMU_CONTEXT_TBL, (MMU_L1PTP >> 4) | 1);  
106 - stl_raw(phys_ram_base + MMU_L1PTP, (MMU_L2PTP >> 4) | 1);  
107 - stl_raw(phys_ram_base + MMU_L1PTP + (0x01 << 2), (MMU_L2PTP >> 4) | 1); // 01.. == 00..  
108 - stl_raw(phys_ram_base + MMU_L1PTP + (0xff << 2), (MMU_L2PTP >> 4) | 1); // ff.. == 00..  
109 - stl_raw(phys_ram_base + MMU_L1PTP + (0xf0 << 2), (MMU_L2PTP >> 4) | 1); // f0.. == 00..  
110 - /* 3 = U:RWX S:RWX */  
111 - stl_raw(phys_ram_base + MMU_L2PTP, (3 << PTE_ACCESS_SHIFT) | 2);  
112 - stl_raw(phys_ram_base + MMU_L2PTP, ((0x01 << PTE_PPN_SHIFT) >> 4 ) | (3 << PTE_ACCESS_SHIFT) | 2);  
113 } 184 }
hw/tcx.c
@@ -25,179 +25,254 @@ @@ -25,179 +25,254 @@
25 25
26 #define MAXX 1024 26 #define MAXX 1024
27 #define MAXY 768 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
28 #define XSZ (8*80) 34 #define XSZ (8*80)
29 #define YSZ (24*11) 35 #define YSZ (24*11)
30 #define XOFF (MAXX-XSZ) 36 #define XOFF (MAXX-XSZ)
31 #define YOFF (MAXY-YSZ) 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
32 44
33 typedef struct TCXState { 45 typedef struct TCXState {
34 uint32_t addr; 46 uint32_t addr;
35 DisplayState *ds; 47 DisplayState *ds;
36 uint8_t *vram; 48 uint8_t *vram;
  49 + unsigned long vram_offset;
  50 + uint8_t r[256], g[256], b[256];
37 } TCXState; 51 } TCXState;
38 52
39 -static TCXState *ts;  
40 -  
41 -void vga_update_display() 53 +static void tcx_draw_line32(TCXState *s1, uint8_t *d,
  54 + const uint8_t *s, int width)
42 { 55 {
43 - dpy_update(ts->ds, 0, 0, XSZ, YSZ); 56 + int x;
  57 + uint8_t val;
  58 +
  59 + for(x = 0; x < width; x++) {
  60 + val = *s++;
  61 + *d++ = s1->r[val];
  62 + *d++ = s1->g[val];
  63 + *d++ = s1->b[val];
  64 + d++;
  65 + }
44 } 66 }
45 67
46 -void vga_invalidate_display() {} 68 +static void tcx_draw_line24(TCXState *s1, uint8_t *d,
  69 + const uint8_t *s, int width)
  70 +{
  71 + int x;
  72 + uint8_t val;
47 73
48 -static uint32_t tcx_mem_readb(void *opaque, target_phys_addr_t addr) 74 + for(x = 0; x < width; x++) {
  75 + val = *s++;
  76 + *d++ = s1->r[val];
  77 + *d++ = s1->g[val];
  78 + *d++ = s1->b[val];
  79 + }
  80 +}
  81 +
  82 +static void tcx_draw_line8(TCXState *s1, uint8_t *d,
  83 + const uint8_t *s, int width)
49 { 84 {
50 - TCXState *s = opaque;  
51 - uint32_t saddr;  
52 - unsigned int x, y;  
53 -  
54 - saddr = addr - s->addr - YOFF*MAXX - XOFF;  
55 - y = saddr / MAXX;  
56 - x = saddr - y * MAXX;  
57 - if (x < XSZ && y < YSZ) {  
58 - return s->vram[y * XSZ + x]; 85 + int x;
  86 + uint8_t val;
  87 +
  88 + for(x = 0; x < width; x++) {
  89 + val = *s++;
  90 + /* XXX translate between palettes? */
  91 + *d++ = val;
59 } 92 }
60 - return 0;  
61 } 93 }
62 94
63 -static uint32_t tcx_mem_readw(void *opaque, target_phys_addr_t addr) 95 +/* Fixed line length 1024 allows us to do nice tricks not possible on
  96 + VGA... */
  97 +void tcx_update_display(void *opaque)
64 { 98 {
65 - uint32_t v;  
66 -#ifdef TARGET_WORDS_BIGENDIAN  
67 - v = tcx_mem_readb(opaque, addr) << 8;  
68 - v |= tcx_mem_readb(opaque, addr + 1); 99 + TCXState *ts = opaque;
  100 + uint32_t page;
  101 + int y, page_min, page_max, y_start, dd, ds;
  102 + uint8_t *d, *s;
  103 + void (*f)(TCXState *s1, uint8_t *d, const uint8_t *s, int width);
  104 +
  105 + if (ts->ds->depth == 0)
  106 + return;
  107 +#ifdef LD_BYPASS_OK
  108 + page = ts->vram_offset + YOFF*MAXX;
69 #else 109 #else
70 - v = tcx_mem_readb(opaque, addr);  
71 - v |= tcx_mem_readb(opaque, addr + 1) << 8; 110 + page = ts->addr + YOFF*MAXX;
72 #endif 111 #endif
73 - return v; 112 + y_start = -1;
  113 + page_min = 0x7fffffff;
  114 + page_max = -1;
  115 + d = ts->ds->data;
  116 + s = ts->vram + YOFF*MAXX + XOFF;
  117 + dd = ts->ds->linesize;
  118 + ds = 1024;
  119 +
  120 + switch (ts->ds->depth) {
  121 + case 32:
  122 + f = tcx_draw_line32;
  123 + break;
  124 + case 24:
  125 + f = tcx_draw_line24;
  126 + break;
  127 + default:
  128 + case 8:
  129 + f = tcx_draw_line8;
  130 + break;
  131 + case 0:
  132 + return;
  133 + }
  134 +
  135 + for(y = 0; y < YSZ; y += 4, page += TARGET_PAGE_SIZE) {
  136 + if (cpu_physical_memory_is_dirty(page)) {
  137 + if (y_start < 0)
  138 + y_start = y;
  139 + if (page < page_min)
  140 + page_min = page;
  141 + if (page > page_max)
  142 + page_max = page;
  143 + f(ts, d, s, XSZ);
  144 + d += dd;
  145 + s += ds;
  146 + f(ts, d, s, XSZ);
  147 + d += dd;
  148 + s += ds;
  149 + f(ts, d, s, XSZ);
  150 + d += dd;
  151 + s += ds;
  152 + f(ts, d, s, XSZ);
  153 + d += dd;
  154 + s += ds;
  155 + } else {
  156 + if (y_start >= 0) {
  157 + /* flush to display */
  158 + dpy_update(ts->ds, 0, y_start,
  159 + XSZ, y - y_start);
  160 + y_start = -1;
  161 + }
  162 + d += dd * 4;
  163 + s += ds * 4;
  164 + }
  165 + }
  166 + if (y_start >= 0) {
  167 + /* flush to display */
  168 + dpy_update(ts->ds, 0, y_start,
  169 + XSZ, y - y_start);
  170 + }
  171 + /* reset modified pages */
  172 + if (page_max != -1) {
  173 + cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE);
  174 + }
74 } 175 }
75 176
76 -static uint32_t tcx_mem_readl(void *opaque, target_phys_addr_t addr) 177 +void tcx_invalidate_display(void *opaque)
77 { 178 {
78 - uint32_t v;  
79 -#ifdef TARGET_WORDS_BIGENDIAN  
80 - v = tcx_mem_readb(opaque, addr) << 24;  
81 - v |= tcx_mem_readb(opaque, addr + 1) << 16;  
82 - v |= tcx_mem_readb(opaque, addr + 2) << 8;  
83 - v |= tcx_mem_readb(opaque, addr + 3); 179 + TCXState *s = opaque;
  180 + int i;
  181 +
  182 + for (i = 0; i < MAXX*MAXY; i += TARGET_PAGE_SIZE) {
  183 +#ifdef LD_BYPASS_OK
  184 + cpu_physical_memory_set_dirty(s->vram_offset + i);
84 #else 185 #else
85 - v = tcx_mem_readb(opaque, addr);  
86 - v |= tcx_mem_readb(opaque, addr + 1) << 8;  
87 - v |= tcx_mem_readb(opaque, addr + 2) << 16;  
88 - v |= tcx_mem_readb(opaque, addr + 3) << 24; 186 + cpu_physical_memory_set_dirty(s->addr + i);
89 #endif 187 #endif
90 - return v; 188 + }
91 } 189 }
92 190
93 -static void tcx_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) 191 +static void tcx_save(QEMUFile *f, void *opaque)
94 { 192 {
95 TCXState *s = opaque; 193 TCXState *s = opaque;
96 - uint32_t saddr;  
97 - unsigned int x, y;  
98 - char *sptr;  
99 -  
100 - saddr = addr - s->addr - YOFF*MAXX - XOFF;  
101 - y = saddr / MAXX;  
102 - x = saddr - y * MAXX;  
103 - if (x < XSZ && y < YSZ) {  
104 - sptr = s->ds->data;  
105 - if (sptr) {  
106 - if (s->ds->depth == 24 || s->ds->depth == 32) {  
107 - /* XXX need to do CLUT translation */  
108 - sptr[y * s->ds->linesize + x*4] = val & 0xff;  
109 - sptr[y * s->ds->linesize + x*4+1] = val & 0xff;  
110 - sptr[y * s->ds->linesize + x*4+2] = val & 0xff;  
111 - }  
112 - else if (s->ds->depth == 8) {  
113 - sptr[y * s->ds->linesize + x] = val & 0xff;  
114 - }  
115 - }  
116 - cpu_physical_memory_set_dirty(addr);  
117 - s->vram[y * XSZ + x] = val & 0xff;  
118 - } 194 +
  195 + qemu_put_be32s(f, (uint32_t *)&s->addr);
  196 + qemu_put_be32s(f, (uint32_t *)&s->vram);
  197 + qemu_put_buffer(f, s->r, 256);
  198 + qemu_put_buffer(f, s->g, 256);
  199 + qemu_put_buffer(f, s->b, 256);
119 } 200 }
120 201
121 -static void tcx_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) 202 +static int tcx_load(QEMUFile *f, void *opaque, int version_id)
122 { 203 {
123 -#ifdef TARGET_WORDS_BIGENDIAN  
124 - tcx_mem_writeb(opaque, addr, (val >> 8) & 0xff);  
125 - tcx_mem_writeb(opaque, addr + 1, val & 0xff);  
126 -#else  
127 - tcx_mem_writeb(opaque, addr, val & 0xff);  
128 - tcx_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);  
129 -#endif 204 + TCXState *s = opaque;
  205 +
  206 + if (version_id != 1)
  207 + return -EINVAL;
  208 +
  209 + qemu_get_be32s(f, (uint32_t *)&s->addr);
  210 + qemu_get_be32s(f, (uint32_t *)&s->vram);
  211 + qemu_get_buffer(f, s->r, 256);
  212 + qemu_get_buffer(f, s->g, 256);
  213 + qemu_get_buffer(f, s->b, 256);
  214 + return 0;
130 } 215 }
131 216
132 -static void tcx_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) 217 +static void tcx_reset(void *opaque)
133 { 218 {
134 -#ifdef TARGET_WORDS_BIGENDIAN  
135 - tcx_mem_writeb(opaque, addr, (val >> 24) & 0xff);  
136 - tcx_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff);  
137 - tcx_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff);  
138 - tcx_mem_writeb(opaque, addr + 3, val & 0xff);  
139 -#else  
140 - tcx_mem_writeb(opaque, addr, val & 0xff);  
141 - tcx_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);  
142 - tcx_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);  
143 - tcx_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff); 219 + TCXState *s = opaque;
  220 +
  221 + /* Initialize palette */
  222 + memset(s->r, 0, 256);
  223 + memset(s->g, 0, 256);
  224 + memset(s->b, 0, 256);
  225 + s->r[255] = s->g[255] = s->b[255] = 255;
  226 + memset(s->vram, 0, MAXX*MAXY);
  227 +#ifdef LD_BYPASS_OK
  228 + cpu_physical_memory_reset_dirty(s->vram_offset, s->vram_offset + MAXX*MAXY - 1);
144 #endif 229 #endif
145 } 230 }
146 231
147 -static CPUReadMemoryFunc *tcx_mem_read[3] = {  
148 - tcx_mem_readb,  
149 - tcx_mem_readw,  
150 - tcx_mem_readl,  
151 -};  
152 -  
153 -static CPUWriteMemoryFunc *tcx_mem_write[3] = {  
154 - tcx_mem_writeb,  
155 - tcx_mem_writew,  
156 - tcx_mem_writel,  
157 -};  
158 -  
159 -void tcx_init(DisplayState *ds, uint32_t addr) 232 +void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base,
  233 + unsigned long vram_offset, int vram_size)
160 { 234 {
161 TCXState *s; 235 TCXState *s;
162 - int tcx_io_memory;  
163 236
164 s = qemu_mallocz(sizeof(TCXState)); 237 s = qemu_mallocz(sizeof(TCXState));
165 if (!s) 238 if (!s)
166 - return; 239 + return NULL;
167 s->ds = ds; 240 s->ds = ds;
168 s->addr = addr; 241 s->addr = addr;
169 - ts = s;  
170 - tcx_io_memory = cpu_register_io_memory(0, tcx_mem_read, tcx_mem_write, s);  
171 - cpu_register_physical_memory(addr, 0x100000,  
172 - tcx_io_memory);  
173 - s->vram = qemu_mallocz(XSZ*YSZ); 242 + s->vram = vram_base;
  243 + s->vram_offset = vram_offset;
  244 +
  245 + cpu_register_physical_memory(addr, vram_size, vram_offset);
  246 +
  247 + register_savevm("tcx", addr, 1, tcx_save, tcx_load, s);
  248 + qemu_register_reset(tcx_reset, s);
  249 + tcx_reset(s);
174 dpy_resize(s->ds, XSZ, YSZ); 250 dpy_resize(s->ds, XSZ, YSZ);
  251 + return s;
175 } 252 }
176 253
177 -void vga_screen_dump(const char *filename) 254 +void tcx_screen_dump(void *opaque, const char *filename)
178 { 255 {
179 - TCXState *s = ts; 256 + TCXState *s = opaque;
180 FILE *f; 257 FILE *f;
181 - uint8_t *d, *d1;  
182 - unsigned int v; 258 + uint8_t *d, *d1, v;
183 int y, x; 259 int y, x;
184 260
185 f = fopen(filename, "wb"); 261 f = fopen(filename, "wb");
186 if (!f) 262 if (!f)
187 - return -1;  
188 - fprintf(f, "P6\n%d %d\n%d\n",  
189 - XSZ, YSZ, 255);  
190 - d1 = s->vram; 263 + return;
  264 + fprintf(f, "P6\n%d %d\n%d\n", XSZ, YSZ, 255);
  265 + d1 = s->vram + YOFF*MAXX + XOFF;
191 for(y = 0; y < YSZ; y++) { 266 for(y = 0; y < YSZ; y++) {
192 d = d1; 267 d = d1;
193 for(x = 0; x < XSZ; x++) { 268 for(x = 0; x < XSZ; x++) {
194 v = *d; 269 v = *d;
195 - fputc((v) & 0xff, f);  
196 - fputc((v) & 0xff, f);  
197 - fputc((v) & 0xff, f); 270 + fputc(s->r[v], f);
  271 + fputc(s->g[v], f);
  272 + fputc(s->b[v], f);
198 d++; 273 d++;
199 } 274 }
200 - d1 += XSZ; 275 + d1 += MAXX;
201 } 276 }
202 fclose(f); 277 fclose(f);
203 return; 278 return;
hw/timer.c deleted 100644 โ†’ 0
1 -/*  
2 - * QEMU Sparc timer controller emulation  
3 - *  
4 - * Copyright (c) 2003-2004 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 -/*  
27 - * Registers of hardware timer in sun4m.  
28 - */  
29 -struct sun4m_timer_percpu {  
30 - volatile unsigned int l14_timer_limit; /* Initial value is 0x009c4000 */  
31 - volatile unsigned int l14_cur_count;  
32 -};  
33 -  
34 -struct sun4m_timer_global {  
35 - volatile unsigned int l10_timer_limit;  
36 - volatile unsigned int l10_cur_count;  
37 -};  
38 -  
39 -typedef struct TIMERState {  
40 - uint32_t addr;  
41 - uint32_t timer_regs[2];  
42 - int irq;  
43 -} TIMERState;  
44 -  
45 -static uint32_t timer_mem_readl(void *opaque, target_phys_addr_t addr)  
46 -{  
47 - TIMERState *s = opaque;  
48 - uint32_t saddr;  
49 -  
50 - saddr = (addr - s->addr) >> 2;  
51 - switch (saddr) {  
52 - default:  
53 - return s->timer_regs[saddr];  
54 - break;  
55 - }  
56 - return 0;  
57 -}  
58 -  
59 -static void timer_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)  
60 -{  
61 - TIMERState *s = opaque;  
62 - uint32_t saddr;  
63 -  
64 - saddr = (addr - s->addr) >> 2;  
65 - switch (saddr) {  
66 - default:  
67 - s->timer_regs[saddr] = val;  
68 - break;  
69 - }  
70 -}  
71 -  
72 -static CPUReadMemoryFunc *timer_mem_read[3] = {  
73 - timer_mem_readl,  
74 - timer_mem_readl,  
75 - timer_mem_readl,  
76 -};  
77 -  
78 -static CPUWriteMemoryFunc *timer_mem_write[3] = {  
79 - timer_mem_writel,  
80 - timer_mem_writel,  
81 - timer_mem_writel,  
82 -};  
83 -  
84 -void timer_init(uint32_t addr, int irq)  
85 -{  
86 - int timer_io_memory;  
87 - TIMERState *s;  
88 -  
89 - s = qemu_mallocz(sizeof(TIMERState));  
90 - if (!s)  
91 - return;  
92 - s->addr = addr;  
93 - s->irq = irq;  
94 -  
95 - timer_io_memory = cpu_register_io_memory(0, timer_mem_read, timer_mem_write, s);  
96 - cpu_register_physical_memory(addr, 2, timer_io_memory);  
97 -}  
linux-user/elfload.c
@@ -841,6 +841,7 @@ static void load_symbols(struct elfhdr *hdr, int fd) @@ -841,6 +841,7 @@ static void load_symbols(struct elfhdr *hdr, int fd)
841 unsigned int i; 841 unsigned int i;
842 struct elf_shdr sechdr, symtab, strtab; 842 struct elf_shdr sechdr, symtab, strtab;
843 char *strings; 843 char *strings;
  844 + struct syminfo *s;
844 845
845 lseek(fd, hdr->e_shoff, SEEK_SET); 846 lseek(fd, hdr->e_shoff, SEEK_SET);
846 for (i = 0; i < hdr->e_shnum; i++) { 847 for (i = 0; i < hdr->e_shnum; i++) {
@@ -866,24 +867,27 @@ static void load_symbols(struct elfhdr *hdr, int fd) @@ -866,24 +867,27 @@ static void load_symbols(struct elfhdr *hdr, int fd)
866 867
867 found: 868 found:
868 /* Now know where the strtab and symtab are. Snarf them. */ 869 /* Now know where the strtab and symtab are. Snarf them. */
869 - disas_symtab = malloc(symtab.sh_size);  
870 - disas_strtab = strings = malloc(strtab.sh_size);  
871 - if (!disas_symtab || !disas_strtab) 870 + s = malloc(sizeof(*s));
  871 + s->disas_symtab = malloc(symtab.sh_size);
  872 + s->disas_strtab = strings = malloc(strtab.sh_size);
  873 + if (!s->disas_symtab || !s->disas_strtab)
872 return; 874 return;
873 875
874 lseek(fd, symtab.sh_offset, SEEK_SET); 876 lseek(fd, symtab.sh_offset, SEEK_SET);
875 - if (read(fd, disas_symtab, symtab.sh_size) != symtab.sh_size) 877 + if (read(fd, s->disas_symtab, symtab.sh_size) != symtab.sh_size)
876 return; 878 return;
877 879
878 #ifdef BSWAP_NEEDED 880 #ifdef BSWAP_NEEDED
879 for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++) 881 for (i = 0; i < symtab.sh_size / sizeof(struct elf_sym); i++)
880 - bswap_sym(disas_symtab + sizeof(struct elf_sym)*i); 882 + bswap_sym(s->disas_symtab + sizeof(struct elf_sym)*i);
881 #endif 883 #endif
882 884
883 lseek(fd, strtab.sh_offset, SEEK_SET); 885 lseek(fd, strtab.sh_offset, SEEK_SET);
884 if (read(fd, strings, strtab.sh_size) != strtab.sh_size) 886 if (read(fd, strings, strtab.sh_size) != strtab.sh_size)
885 return; 887 return;
886 - disas_num_syms = symtab.sh_size / sizeof(struct elf_sym); 888 + s->disas_num_syms = symtab.sh_size / sizeof(struct elf_sym);
  889 + s->next = syminfos;
  890 + syminfos = s;
887 } 891 }
888 892
889 static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, 893 static int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
linux-user/main.c
@@ -497,6 +497,8 @@ void cpu_loop (CPUSPARCState *env) @@ -497,6 +497,8 @@ void cpu_loop (CPUSPARCState *env)
497 case TT_WIN_UNF: /* window underflow */ 497 case TT_WIN_UNF: /* window underflow */
498 restore_window(env); 498 restore_window(env);
499 break; 499 break;
  500 + case 0x100: // XXX, why do we get these?
  501 + break;
500 default: 502 default:
501 printf ("Unhandled trap: 0x%x\n", trapnr); 503 printf ("Unhandled trap: 0x%x\n", trapnr);
502 cpu_dump_state(env, stderr, fprintf, 0); 504 cpu_dump_state(env, stderr, fprintf, 0);
linux-user/signal.c
@@ -1354,13 +1354,14 @@ struct target_rt_signal_frame { @@ -1354,13 +1354,14 @@ struct target_rt_signal_frame {
1354 __siginfo_fpu_t fpu_state; 1354 __siginfo_fpu_t fpu_state;
1355 }; 1355 };
1356 1356
1357 -#define UREG_O0 0  
1358 -#define UREG_O6 6  
1359 -#define UREG_I0 16  
1360 -#define UREG_I1 17  
1361 -#define UREG_I2 18  
1362 -#define UREG_I6 22  
1363 -#define UREG_I7 23 1357 +#define UREG_O0 16
  1358 +#define UREG_O6 22
  1359 +#define UREG_I0 0
  1360 +#define UREG_I1 1
  1361 +#define UREG_I2 2
  1362 +#define UREG_I6 6
  1363 +#define UREG_I7 7
  1364 +#define UREG_L0 8
1364 #define UREG_FP UREG_I6 1365 #define UREG_FP UREG_I6
1365 #define UREG_SP UREG_O6 1366 #define UREG_SP UREG_O6
1366 1367
@@ -1385,23 +1386,20 @@ setup___siginfo(__siginfo_t *si, CPUState *env, target_ulong mask) @@ -1385,23 +1386,20 @@ setup___siginfo(__siginfo_t *si, CPUState *env, target_ulong mask)
1385 { 1386 {
1386 int err = 0, i; 1387 int err = 0, i;
1387 1388
1388 - fprintf(stderr, "2.a %lx psr: %lx regs: %lx\n", si, env->psr, si->si_regs.psr);  
1389 err |= __put_user(env->psr, &si->si_regs.psr); 1389 err |= __put_user(env->psr, &si->si_regs.psr);
1390 - fprintf(stderr, "2.a1 pc:%lx\n", si->si_regs.pc);  
1391 err |= __put_user(env->pc, &si->si_regs.pc); 1390 err |= __put_user(env->pc, &si->si_regs.pc);
1392 err |= __put_user(env->npc, &si->si_regs.npc); 1391 err |= __put_user(env->npc, &si->si_regs.npc);
1393 err |= __put_user(env->y, &si->si_regs.y); 1392 err |= __put_user(env->y, &si->si_regs.y);
1394 - fprintf(stderr, "2.b\n");  
1395 for (i=0; i < 7; i++) { 1393 for (i=0; i < 7; i++) {
1396 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]); 1394 err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);
1397 } 1395 }
1398 for (i=0; i < 7; i++) { 1396 for (i=0; i < 7; i++) {
1399 - err |= __put_user(env->regwptr[i+16], &si->si_regs.u_regs[i+8]); 1397 + err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);
1400 } 1398 }
1401 - fprintf(stderr, "2.c\n");  
1402 err |= __put_user(mask, &si->si_mask); 1399 err |= __put_user(mask, &si->si_mask);
1403 return err; 1400 return err;
1404 } 1401 }
  1402 +
1405 static int 1403 static int
1406 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/ 1404 setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1407 CPUState *env, unsigned long mask) 1405 CPUState *env, unsigned long mask)
@@ -1434,6 +1432,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, @@ -1434,6 +1432,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
1434 sf = (struct target_signal_frame *) 1432 sf = (struct target_signal_frame *)
1435 get_sigframe(ka, env, sigframe_size); 1433 get_sigframe(ka, env, sigframe_size);
1436 1434
  1435 + //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1437 #if 0 1436 #if 0
1438 if (invalid_frame_pointer(sf, sigframe_size)) 1437 if (invalid_frame_pointer(sf, sigframe_size))
1439 goto sigill_and_return; 1438 goto sigill_and_return;
@@ -1451,13 +1450,11 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, @@ -1451,13 +1450,11 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
1451 } 1450 }
1452 1451
1453 for (i = 0; i < 7; i++) { 1452 for (i = 0; i < 7; i++) {
1454 - err |= __put_user(env->regwptr[i + 8], &sf->ss.locals[i]); 1453 + err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);
1455 } 1454 }
1456 for (i = 0; i < 7; i++) { 1455 for (i = 0; i < 7; i++) {
1457 - err |= __put_user(env->regwptr[i + 16], &sf->ss.ins[i]); 1456 + err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);
1458 } 1457 }
1459 - //err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],  
1460 - // sizeof(struct reg_window));  
1461 if (err) 1458 if (err)
1462 goto sigsegv; 1459 goto sigsegv;
1463 1460
@@ -1486,13 +1483,15 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, @@ -1486,13 +1483,15 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
1486 1483
1487 /* Flush instruction space. */ 1484 /* Flush instruction space. */
1488 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); 1485 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1489 - //tb_flush(env); 1486 + tb_flush(env);
1490 } 1487 }
  1488 + //cpu_dump_state(env, stderr, fprintf, 0);
1491 return; 1489 return;
1492 1490
1493 sigill_and_return: 1491 sigill_and_return:
1494 force_sig(TARGET_SIGILL); 1492 force_sig(TARGET_SIGILL);
1495 sigsegv: 1493 sigsegv:
  1494 + //fprintf(stderr, "force_sig\n");
1496 force_sig(TARGET_SIGSEGV); 1495 force_sig(TARGET_SIGSEGV);
1497 } 1496 }
1498 static inline int 1497 static inline int
@@ -1542,13 +1541,16 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka, @@ -1542,13 +1541,16 @@ static void setup_rt_frame(int sig, struct emulated_sigaction *ka,
1542 long do_sigreturn(CPUState *env) 1541 long do_sigreturn(CPUState *env)
1543 { 1542 {
1544 struct target_signal_frame *sf; 1543 struct target_signal_frame *sf;
1545 - unsigned long up_psr, pc, npc; 1544 + uint32_t up_psr, pc, npc;
1546 target_sigset_t set; 1545 target_sigset_t set;
  1546 + sigset_t host_set;
1547 __siginfo_fpu_t *fpu_save; 1547 __siginfo_fpu_t *fpu_save;
1548 - int err; 1548 + int err, i;
1549 1549
1550 - sf = (struct new_signal_frame *) env->regwptr[UREG_FP];  
1551 - fprintf(stderr, "sigreturn sf: %lx\n", &sf); 1550 + sf = (struct target_signal_frame *) env->regwptr[UREG_FP];
  1551 + fprintf(stderr, "sigreturn\n");
  1552 + fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
  1553 + //cpu_dump_state(env, stderr, fprintf, 0);
1552 1554
1553 /* 1. Make sure we are not getting garbage from the user */ 1555 /* 1. Make sure we are not getting garbage from the user */
1554 #if 0 1556 #if 0
@@ -1567,36 +1569,41 @@ long do_sigreturn(CPUState *env) @@ -1567,36 +1569,41 @@ long do_sigreturn(CPUState *env)
1567 goto segv_and_exit; 1569 goto segv_and_exit;
1568 1570
1569 /* 2. Restore the state */ 1571 /* 2. Restore the state */
1570 - up_psr = env->psr;  
1571 - //err |= __copy_from_user(regs, &sf->info.si_regs, sizeof (struct pt_regs)  
1572 - //); 1572 + err |= __get_user(up_psr, &sf->info.si_regs.psr);
  1573 +
1573 /* User can only change condition codes and FPU enabling in %psr. */ 1574 /* User can only change condition codes and FPU enabling in %psr. */
1574 env->psr = (up_psr & ~(PSR_ICC /* | PSR_EF */)) 1575 env->psr = (up_psr & ~(PSR_ICC /* | PSR_EF */))
1575 | (env->psr & (PSR_ICC /* | PSR_EF */)); 1576 | (env->psr & (PSR_ICC /* | PSR_EF */));
1576 - fprintf(stderr, "psr: %lx\n", env->psr); 1577 + fprintf(stderr, "psr: %x\n", env->psr);
  1578 + env->pc = pc-4;
  1579 + env->npc = pc;
  1580 + err |= __get_user(env->y, &sf->info.si_regs.y);
  1581 + for (i=0; i < 7; i++) {
  1582 + err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
  1583 + }
  1584 + for (i=0; i < 7; i++) {
  1585 + err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
  1586 + }
1577 1587
1578 err |= __get_user(fpu_save, &sf->fpu_save); 1588 err |= __get_user(fpu_save, &sf->fpu_save);
1579 1589
1580 - if (fpu_save)  
1581 - err |= restore_fpu_state(env, fpu_save); 1590 + //if (fpu_save)
  1591 + // err |= restore_fpu_state(env, fpu_save);
1582 1592
1583 /* This is pretty much atomic, no amount locking would prevent 1593 /* This is pretty much atomic, no amount locking would prevent
1584 * the races which exist anyways. 1594 * the races which exist anyways.
1585 */ 1595 */
1586 err |= __get_user(set.sig[0], &sf->info.si_mask); 1596 err |= __get_user(set.sig[0], &sf->info.si_mask);
1587 - //err |= __copy_from_user(&set.sig[1], &sf->extramask,  
1588 - // (_NSIG_WORDS-1) * sizeof(unsigned int)); 1597 + for(i = 1; i < TARGET_NSIG_WORDS; i++) {
  1598 + err |= (__get_user(set.sig[i], &sf->extramask[i - 1]));
  1599 + }
  1600 +
  1601 + target_to_host_sigset_internal(&host_set, &set);
  1602 + sigprocmask(SIG_SETMASK, &host_set, NULL);
1589 1603
1590 if (err) 1604 if (err)
1591 goto segv_and_exit; 1605 goto segv_and_exit;
1592 1606
1593 -#if 0  
1594 - sigdelsetmask(&set, ~_BLOCKABLE);  
1595 - spin_lock_irq(&current->sigmask_lock);  
1596 - current->blocked = set;  
1597 - recalc_sigpending(current);  
1598 - spin_unlock_irq(&current->sigmask_lock);  
1599 -#endif  
1600 fprintf(stderr, "returning %lx\n", env->regwptr[0]); 1607 fprintf(stderr, "returning %lx\n", env->regwptr[0]);
1601 return env->regwptr[0]; 1608 return env->regwptr[0];
1602 1609
pc-bios/proll.bin deleted 100644 โ†’ 0
No preview for this file type
pc-bios/proll.elf 0 โ†’ 100644
No preview for this file type
pc-bios/proll.patch
1 -diff -ru proll_18.orig/mrcoffee/main.c proll_18/mrcoffee/main.c  
2 ---- proll_18.orig/mrcoffee/main.c 2002-09-13 16:16:59.000000000 +0200  
3 -+++ proll_18/mrcoffee/main.c 2004-09-26 11:52:23.000000000 +0200  
4 -@@ -101,6 +101,7 @@  
5 - le_probe();  
6 - init_net(); 1 +diff -ruN proll_18.orig/Makefile proll-patch4/Makefile
  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
  4 +@@ -4,6 +4,7 @@
  5 + make -C krups-ser all
  6 + make -C espresso all
  7 + make -C espresso-ser all
  8 ++ make -C qemu all
7 9
  10 + clean:
  11 + make -C mrcoffee clean
  12 +@@ -11,3 +12,4 @@
  13 + make -C krups-ser clean
  14 + make -C espresso clean
  15 + make -C espresso-ser clean
  16 ++ make -C qemu clean
  17 +diff -ruN proll_18.orig/qemu/head.S proll-patch4/qemu/head.S
  18 +--- 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 @@
  21 ++/**
  22 ++ ** Standalone startup code for Linux PROM emulator.
  23 ++ ** Copyright 1999 Pete A. Zaitcev
  24 ++ ** This code is licensed under GNU General Public License.
  25 ++ **/
  26 ++/*
  27 ++ * $Id: proll.patch,v 1.2 2004-12-19 23:18:01 bellard Exp $
  28 ++ */
  29 ++
  30 ++#include <psr.h>
  31 ++#include <asi.h>
  32 ++#include <crs.h>
  33 ++/* #include <asm/head.h> */ /* Trap entries. Do not use. */
  34 ++#include "phys_jj.h"
  35 ++
  36 ++#define C_LABEL(name) name
  37 ++#define REGWIN_SZ 0x40
  38 ++
  39 ++#define WRITE_PAUSE nop; nop; nop; /* Have to do this after %wim/%psr chg */
  40 ++
  41 ++ /* 22 is 24-2, (va)>>(SRMMU_PGDIR_SHIFT-PTESIZESHFT) */
  42 ++#define VATOPGDOFF(va) (((va)>>22)&0x3FC)
  43 ++#define VATOPMDOFF(va) (((va)>>16)&0xFC)
  44 ++
  45 ++#define NOP_INSN 0x01000000 /* Used to patch sparc_save_state */
  46 ++
  47 ++/* Here are some trap goodies */
  48 ++
  49 ++#if 0
  50 ++/* Generic trap entry. */
  51 ++#define TRAP_ENTRY(type, label) \
  52 ++ rd %psr, %l0; b label; rd %wim, %l3; nop;
  53 ++#endif
  54 ++
  55 ++/* Data/text faults. */
  56 ++#define SRMMU_TFAULT rd %psr, %l0; rd %wim, %l3; b C_LABEL(srmmu_fault); mov 1, %l7;
  57 ++#define SRMMU_DFAULT rd %psr, %l0; rd %wim, %l3; b C_LABEL(srmmu_fault); mov 0, %l7;
  58 ++
  59 ++#if 0
  60 ++/* This is for traps we should NEVER get. */
  61 ++#define BAD_TRAP(num) \
  62 ++ rd %psr, %l0; mov num, %l7; b bad_trap_handler; rd %wim, %l3;
  63 ++
  64 ++/* This is for traps when we want just skip the instruction which caused it */
  65 ++#define SKIP_TRAP(type, name) \
  66 ++ jmpl %l2, %g0; rett %l2 + 4; nop; nop;
  67 ++
  68 ++/* Notice that for the system calls we pull a trick. We load up a
  69 ++ * different pointer to the system call vector table in %l7, but call
  70 ++ * the same generic system call low-level entry point. The trap table
  71 ++ * entry sequences are also HyperSparc pipeline friendly ;-)
  72 ++ */
  73 ++
  74 ++/* Software trap for Linux system calls. */
  75 ++#define LINUX_SYSCALL_TRAP \
  76 ++ sethi %hi(C_LABEL(sys_call_table)), %l7; \
  77 ++ or %l7, %lo(C_LABEL(sys_call_table)), %l7; \
  78 ++ b linux_sparc_syscall; \
  79 ++ rd %psr, %l0;
  80 ++
  81 ++/* Software trap for SunOS4.1.x system calls. */
  82 ++#define SUNOS_SYSCALL_TRAP \
  83 ++ rd %psr, %l0; \
  84 ++ sethi %hi(C_LABEL(sunos_sys_table)), %l7; \
  85 ++ b linux_sparc_syscall; \
  86 ++ or %l7, %lo(C_LABEL(sunos_sys_table)), %l7;
  87 ++
  88 ++/* Software trap for Slowaris system calls. */
  89 ++#define SOLARIS_SYSCALL_TRAP \
  90 ++ b solaris_syscall; \
  91 ++ rd %psr, %l0; \
  92 ++ nop; \
  93 ++ nop;
  94 ++
  95 ++#define INDIRECT_SOLARIS_SYSCALL(x) \
  96 ++ mov x, %g1; \
  97 ++ b solaris_syscall; \
  98 ++ rd %psr, %l0; \
  99 ++ nop;
  100 ++
  101 ++#define BREAKPOINT_TRAP \
  102 ++ b breakpoint_trap; \
  103 ++ rd %psr,%l0; \
  104 ++ nop; \
  105 ++ nop;
  106 ++
  107 ++/* Software trap for Sparc-netbsd system calls. */
  108 ++#define NETBSD_SYSCALL_TRAP \
  109 ++ sethi %hi(C_LABEL(sys_call_table)), %l7; \
  110 ++ or %l7, %lo(C_LABEL(sys_call_table)), %l7; \
  111 ++ b bsd_syscall; \
  112 ++ rd %psr, %l0;
  113 ++
  114 ++/* The Get Condition Codes software trap for userland. */
  115 ++#define GETCC_TRAP \
  116 ++ b getcc_trap_handler; mov %psr, %l0; nop; nop;
  117 ++
  118 ++/* The Set Condition Codes software trap for userland. */
  119 ++#define SETCC_TRAP \
  120 ++ b setcc_trap_handler; mov %psr, %l0; nop; nop;
  121 ++
  122 ++/* This is for hard interrupts from level 1-14, 15 is non-maskable (nmi) and
  123 ++ * gets handled with another macro.
  124 ++ */
  125 ++#define TRAP_ENTRY_INTERRUPT(int_level) \
  126 ++ mov int_level, %l7; rd %psr, %l0; b real_irq_entry; rd %wim, %l3;
  127 ++
  128 ++/* NMI's (Non Maskable Interrupts) are special, you can't keep them
  129 ++ * from coming in, and basically if you get one, the shows over. ;(
  130 ++ * On the sun4c they are usually asynchronous memory errors, on the
  131 ++ * the sun4m they could be either due to mem errors or a software
  132 ++ * initiated interrupt from the prom/kern on an SMP box saying "I
  133 ++ * command you to do CPU tricks, read your mailbox for more info."
  134 ++ */
  135 ++#define NMI_TRAP \
  136 ++ rd %wim, %l3; b linux_trap_nmi_sun4c; mov %psr, %l0; nop;
  137 ++
  138 ++#endif
  139 ++
  140 ++/* Window overflows/underflows are special and we need to try to be as
  141 ++ * efficient as possible here....
  142 ++ */
  143 ++#define WINDOW_SPILL \
  144 ++ rd %psr, %l0; rd %wim, %l3; b spill_window_entry; nop;
  145 ++
  146 ++#define WINDOW_FILL \
  147 ++ rd %psr, %l0; rd %wim, %l3; b fill_window_entry; nop;
  148 ++
  149 ++#define STUB_TRAP ba stub_trap; nop; nop; nop;
  150 ++
  151 ++#define TRAP_ENTRY(a,b) STUB_TRAP
  152 ++#define SKIP_TRAP(a,b) STUB_TRAP
  153 ++#define SUNOS_SYSCALL_TRAP STUB_TRAP
  154 ++#define SOLARIS_SYSCALL_TRAP STUB_TRAP
  155 ++#define NETBSD_SYSCALL_TRAP STUB_TRAP
  156 ++#define LINUX_SYSCALL_TRAP STUB_TRAP
  157 ++#define BREAKPOINT_TRAP STUB_TRAP
  158 ++#define NMI_TRAP STUB_TRAP
  159 ++#define GETCC_TRAP STUB_TRAP
  160 ++#define SETCC_TRAP STUB_TRAP
  161 ++#define BAD_TRAP(n) STUB_TRAP
  162 ++#define TRAP_ENTRY_INTERRUPT(i) STUB_TRAP
  163 ++#define INDIRECT_SOLARIS_SYSCALL(i) STUB_TRAP
  164 ++
  165 ++ .section ".text"
  166 ++ .globl start, _start
  167 ++_start:
  168 ++start:
  169 ++ .globl spill_window_entry, fill_window_entry
  170 ++C_LABEL(trapbase):
  171 ++t_zero: b goprol; nop; nop; nop;
  172 ++t_tflt: SRMMU_TFAULT /* Inst. Access Exception */
  173 ++t_bins: TRAP_ENTRY(0x2, bad_instruction) /* Illegal Instruction */
  174 ++t_pins: TRAP_ENTRY(0x3, priv_instruction) /* Privileged Instruction */
  175 ++t_fpd: TRAP_ENTRY(0x4, fpd_trap_handler) /* Floating Point Disabled */
  176 ++t_wovf: WINDOW_SPILL /* Window Overflow */
  177 ++t_wunf: WINDOW_FILL /* Window Underflow */
  178 ++t_mna: TRAP_ENTRY(0x7, mna_handler) /* Memory Address Not Aligned */
  179 ++t_fpe: TRAP_ENTRY(0x8, fpe_trap_handler) /* Floating Point Exception */
  180 ++t_dflt: SRMMU_DFAULT /* Data Miss Exception */
  181 ++t_tio: TRAP_ENTRY(0xa, do_tag_overflow) /* Tagged Instruction Ovrflw */
  182 ++t_wpt: TRAP_ENTRY(0xb, do_watchpoint) /* Watchpoint Detected */
  183 ++t_badc: BAD_TRAP(0xc) BAD_TRAP(0xd) BAD_TRAP(0xe) BAD_TRAP(0xf) BAD_TRAP(0x10)
  184 ++t_irq1: TRAP_ENTRY_INTERRUPT(1) /* IRQ Software/SBUS Level 1 */
  185 ++t_irq2: TRAP_ENTRY_INTERRUPT(2) /* IRQ SBUS Level 2 */
  186 ++t_irq3: TRAP_ENTRY_INTERRUPT(3) /* IRQ SCSI/DMA/SBUS Level 3 */
  187 ++t_irq4: TRAP_ENTRY_INTERRUPT(4) /* IRQ Software Level 4 */
  188 ++t_irq5: TRAP_ENTRY_INTERRUPT(5) /* IRQ SBUS/Ethernet Level 5 */
  189 ++t_irq6: TRAP_ENTRY_INTERRUPT(6) /* IRQ Software Level 6 */
  190 ++t_irq7: TRAP_ENTRY_INTERRUPT(7) /* IRQ Video/SBUS Level 5 */
  191 ++t_irq8: TRAP_ENTRY_INTERRUPT(8) /* IRQ SBUS Level 6 */
  192 ++t_irq9: TRAP_ENTRY_INTERRUPT(9) /* IRQ SBUS Level 7 */
  193 ++t_irq10:TRAP_ENTRY_INTERRUPT(10) /* IRQ Timer #1 (one we use) */
  194 ++t_irq11:TRAP_ENTRY_INTERRUPT(11) /* IRQ Floppy Intr. */
  195 ++t_irq12:TRAP_ENTRY_INTERRUPT(12) /* IRQ Zilog serial chip */
  196 ++t_irq13:TRAP_ENTRY_INTERRUPT(13) /* IRQ Audio Intr. */
  197 ++t_irq14:TRAP_ENTRY_INTERRUPT(14) /* IRQ Timer #2 */
  198 ++t_nmi: NMI_TRAP /* Level 15 (NMI) */
  199 ++t_racc: TRAP_ENTRY(0x20, do_reg_access) /* General Register Access Error */
  200 ++t_iacce:BAD_TRAP(0x21) /* Instr Access Error */
  201 ++t_bad22:BAD_TRAP(0x22) BAD_TRAP(0x23)
  202 ++t_cpdis:TRAP_ENTRY(0x24, do_cp_disabled) /* Co-Processor Disabled */
  203 ++t_uflsh:SKIP_TRAP(0x25, unimp_flush) /* Unimplemented FLUSH inst. */
  204 ++t_bad26:BAD_TRAP(0x26) BAD_TRAP(0x27)
  205 ++t_cpexc:TRAP_ENTRY(0x28, do_cp_exception) /* Co-Processor Exception */
  206 ++t_dacce:SRMMU_DFAULT /* Data Access Error */
  207 ++t_hwdz: TRAP_ENTRY(0x2a, do_hw_divzero) /* Division by zero, you lose... */
  208 ++t_dserr:BAD_TRAP(0x2b) /* Data Store Error */
  209 ++t_daccm:BAD_TRAP(0x2c) /* Data Access MMU-Miss */
  210 ++t_bad2d: BAD_TRAP(0x2d) BAD_TRAP(0x2e) BAD_TRAP(0x2f)
  211 ++ BAD_TRAP(0x30) BAD_TRAP(0x31) BAD_TRAP(0x32) BAD_TRAP(0x33)
  212 ++ BAD_TRAP(0x34) BAD_TRAP(0x35) BAD_TRAP(0x36) BAD_TRAP(0x37)
  213 ++ BAD_TRAP(0x38) BAD_TRAP(0x39) BAD_TRAP(0x3a) BAD_TRAP(0x3b)
  214 ++t_iaccm:BAD_TRAP(0x3c) /* Instr Access MMU-Miss */
  215 ++ BAD_TRAP(0x3d) BAD_TRAP(0x3e) BAD_TRAP(0x3f)
  216 ++ BAD_TRAP(0x40) BAD_TRAP(0x41) BAD_TRAP(0x42) BAD_TRAP(0x43)
  217 ++ BAD_TRAP(0x44) BAD_TRAP(0x45) BAD_TRAP(0x46) BAD_TRAP(0x47)
  218 ++ BAD_TRAP(0x48) BAD_TRAP(0x49) BAD_TRAP(0x4a) BAD_TRAP(0x4b)
  219 ++ BAD_TRAP(0x4c) BAD_TRAP(0x4d) BAD_TRAP(0x4e) BAD_TRAP(0x4f)
  220 ++ BAD_TRAP(0x50) BAD_TRAP(0x51) BAD_TRAP(0x52) BAD_TRAP(0x53)
  221 ++ BAD_TRAP(0x54) BAD_TRAP(0x55) BAD_TRAP(0x56) BAD_TRAP(0x57)
  222 ++ BAD_TRAP(0x58) BAD_TRAP(0x59) BAD_TRAP(0x5a) BAD_TRAP(0x5b)
  223 ++ BAD_TRAP(0x5c) BAD_TRAP(0x5d) BAD_TRAP(0x5e) BAD_TRAP(0x5f)
  224 ++ BAD_TRAP(0x60) BAD_TRAP(0x61) BAD_TRAP(0x62) BAD_TRAP(0x63)
  225 ++ BAD_TRAP(0x64) BAD_TRAP(0x65) BAD_TRAP(0x66) BAD_TRAP(0x67)
  226 ++ BAD_TRAP(0x68) BAD_TRAP(0x69) BAD_TRAP(0x6a) BAD_TRAP(0x6b)
  227 ++ BAD_TRAP(0x6c) BAD_TRAP(0x6d) BAD_TRAP(0x6e) BAD_TRAP(0x6f)
  228 ++ BAD_TRAP(0x70) BAD_TRAP(0x71) BAD_TRAP(0x72) BAD_TRAP(0x73)
  229 ++ BAD_TRAP(0x74) BAD_TRAP(0x75) BAD_TRAP(0x76) BAD_TRAP(0x77)
  230 ++ BAD_TRAP(0x78) BAD_TRAP(0x79) BAD_TRAP(0x7a) BAD_TRAP(0x7b)
  231 ++ BAD_TRAP(0x7c) BAD_TRAP(0x7d) BAD_TRAP(0x7e) BAD_TRAP(0x7f)
  232 ++t_sunos:SUNOS_SYSCALL_TRAP /* SunOS System Call */
  233 ++t_sbkpt:BREAKPOINT_TRAP /* Software Breakpoint/KGDB */
  234 ++t_divz: BAD_TRAP(0x82) /* Divide by zero trap */
  235 ++t_flwin:TRAP_ENTRY(0x83, do_flush_windows) /* Flush Windows Trap */
  236 ++t_clwin:BAD_TRAP(0x84) /* Clean Windows Trap */
  237 ++t_rchk: BAD_TRAP(0x85) /* Range Check */
  238 ++t_funal:BAD_TRAP(0x86) /* Fix Unaligned Access Trap */
  239 ++t_iovf: BAD_TRAP(0x87) /* Integer Overflow Trap */
  240 ++t_slowl:SOLARIS_SYSCALL_TRAP /* Slowaris System Call */
  241 ++t_netbs:NETBSD_SYSCALL_TRAP /* Net-B.S. System Call */
  242 ++t_bad8a:BAD_TRAP(0x8a) BAD_TRAP(0x8b) BAD_TRAP(0x8c) BAD_TRAP(0x8d)
  243 ++ BAD_TRAP(0x8e) BAD_TRAP(0x8f)
  244 ++t_linux:LINUX_SYSCALL_TRAP /* Linux System Call */
  245 ++t_bad91:BAD_TRAP(0x91) BAD_TRAP(0x92) BAD_TRAP(0x93)
  246 ++ BAD_TRAP(0x94) BAD_TRAP(0x95) BAD_TRAP(0x96) BAD_TRAP(0x97)
  247 ++ BAD_TRAP(0x98) BAD_TRAP(0x99) BAD_TRAP(0x9a) BAD_TRAP(0x9b) BAD_TRAP(0x9c) BAD_TRAP(0x9d) BAD_TRAP(0x9e) BAD_TRAP(0x9f)
  248 ++t_getcc:GETCC_TRAP /* Get Condition Codes */
  249 ++t_setcc:SETCC_TRAP /* Set Condition Codes */
  250 ++t_bada2:BAD_TRAP(0xa2) BAD_TRAP(0xa3)
  251 ++ BAD_TRAP(0xa4) BAD_TRAP(0xa5) BAD_TRAP(0xa6)
  252 ++t_slowi:INDIRECT_SOLARIS_SYSCALL(156)
  253 ++ BAD_TRAP(0xa8) BAD_TRAP(0xa9) BAD_TRAP(0xaa) BAD_TRAP(0xab)
  254 ++ BAD_TRAP(0xac) BAD_TRAP(0xad) BAD_TRAP(0xae) BAD_TRAP(0xaf)
  255 ++ BAD_TRAP(0xb0) BAD_TRAP(0xb1) BAD_TRAP(0xb2) BAD_TRAP(0xb3)
  256 ++ BAD_TRAP(0xb4) BAD_TRAP(0xb5) BAD_TRAP(0xb6) BAD_TRAP(0xb7)
  257 ++ BAD_TRAP(0xb8) BAD_TRAP(0xb9) BAD_TRAP(0xba) BAD_TRAP(0xbb)
  258 ++ BAD_TRAP(0xbc) BAD_TRAP(0xbd) BAD_TRAP(0xbe) BAD_TRAP(0xbf)
  259 ++t_badc0:BAD_TRAP(0xc0) BAD_TRAP(0xc1) BAD_TRAP(0xc2) BAD_TRAP(0xc3)
  260 ++ BAD_TRAP(0xc4) BAD_TRAP(0xc5) BAD_TRAP(0xc6) BAD_TRAP(0xc7)
  261 ++ BAD_TRAP(0xc8) BAD_TRAP(0xc9) BAD_TRAP(0xca) BAD_TRAP(0xcb)
  262 ++ BAD_TRAP(0xcc) BAD_TRAP(0xcd) BAD_TRAP(0xce) BAD_TRAP(0xcf)
  263 ++ BAD_TRAP(0xd0) BAD_TRAP(0xd1) BAD_TRAP(0xd2) BAD_TRAP(0xd3)
  264 ++t_badd4:BAD_TRAP(0xd4) BAD_TRAP(0xd5) BAD_TRAP(0xd6) BAD_TRAP(0xd7)
  265 ++ BAD_TRAP(0xd8) BAD_TRAP(0xd9) BAD_TRAP(0xda) BAD_TRAP(0xdb)
  266 ++ BAD_TRAP(0xdc) BAD_TRAP(0xdd) BAD_TRAP(0xde) BAD_TRAP(0xdf)
  267 ++ BAD_TRAP(0xe0) BAD_TRAP(0xe1) BAD_TRAP(0xe2) BAD_TRAP(0xe3)
  268 ++ BAD_TRAP(0xe4) BAD_TRAP(0xe5) BAD_TRAP(0xe6) BAD_TRAP(0xe7)
  269 ++t_bade8:BAD_TRAP(0xe8) BAD_TRAP(0xe9) BAD_TRAP(0xea) BAD_TRAP(0xeb)
  270 ++ BAD_TRAP(0xec) BAD_TRAP(0xed) BAD_TRAP(0xee) BAD_TRAP(0xef)
  271 ++ BAD_TRAP(0xf0) BAD_TRAP(0xf1) BAD_TRAP(0xf2) BAD_TRAP(0xf3)
  272 ++ BAD_TRAP(0xf4) BAD_TRAP(0xf5) BAD_TRAP(0xf6) BAD_TRAP(0xf7)
  273 ++ BAD_TRAP(0xf8) BAD_TRAP(0xf9) BAD_TRAP(0xfa) BAD_TRAP(0xfb)
  274 ++t_badfc:BAD_TRAP(0xfc) BAD_TRAP(0xfd)
  275 ++dbtrap: BAD_TRAP(0xfe) /* Debugger/PROM breakpoint #1 */
  276 ++dbtrap2:BAD_TRAP(0xff) /* Debugger/PROM breakpoint #2 */
  277 ++
  278 ++stub_trap:
  279 ++ set (PHYS_JJ_TCX_FB + 0xbf0), %g5 /* 2 cells from side */
  280 ++ set 0x00ffffff, %g4
  281 ++ sta %g4, [%g5] ASI_M_BYPASS
  282 ++1: ba 1b; nop
  283 ++
  284 ++ .section ".bss"
  285 ++ .align 8
  286 ++bss_start:
  287 ++ .align 0x1000 ! PAGE_SIZE
  288 ++ .globl C_LABEL(bootup_user_stack)
  289 ++ .type bootup_user_stack,#object
  290 ++ .size bootup_user_stack,0x2000
  291 ++C_LABEL(bootup_user_stack): .skip 0x2000
  292 ++
  293 ++ .section ".text"
  294 ++
  295 ++goprol:
  296 ++ ! %g1 contains end of memory
  297 ++ ! map PROLDATA to PROLBASE+PROLSIZE to end of ram
  298 ++ set PROLSIZE+0x1000-PROLDATA+PROLBASE, %g2 ! add 0x1000 for temp tables
  299 ++ sub %g1, %g2, %g2 ! start of private memory
  300 ++ srl %g2, 0x4, %g7 ! ctx table at s+0x0
  301 ++ add %g2, 0x400, %g3 ! l1 table at s+0x400
  302 ++ srl %g3, 0x4, %g3
  303 ++ or %g3, 0x1, %g3
  304 ++ sta %g3, [%g2] ASI_M_BYPASS
  305 ++ add %g2, 0x400, %g2 ! s+0x400
  306 ++ add %g2, 0x800, %g3 ! l2 table for ram (00xxxxxx) at s+0x800
  307 ++ srl %g3, 0x4, %g3
  308 ++ or %g3, 0x1, %g3
  309 ++ sta %g3, [%g2] ASI_M_BYPASS
  310 ++ add %g2, 0x500, %g3 ! l2 table for rom (ffxxxxxx) at s+0x900
  311 ++ add %g2, 0x3fc, %g2 ! s+0x7fc
  312 ++ srl %g3, 0x4, %g3
  313 ++ or %g3, 0x1, %g3
  314 ++ sta %g3, [%g2] ASI_M_BYPASS
  315 ++ add %g2, 0x4, %g2 ! s+0x800
  316 ++ set ((7 << 2) | 2), %g3 ! 7 = U: --- S: RWX (main memory)
  317 ++ sta %g3, [%g2] ASI_M_BYPASS
  318 ++ add %g2, 0x200, %g3 ! l3 table for rom at s+0xa00
  319 ++ add %g2, 0x1d0, %g2 ! s+0x9d0
  320 ++ srl %g3, 0x4, %g3
  321 ++ or %g3, 0x1, %g3
  322 ++ sta %g3, [%g2] ASI_M_BYPASS
  323 ++ add %g2, 0x30, %g2 ! s+0xa00
  324 ++
  325 ++ set PROLBASE, %g3
  326 ++ set 0x1000, %g5
  327 ++ set (PROLDATA-PROLBASE)/0x1000, %g6 ! # of .text pages
  328 ++1: srl %g3, 0x4, %g4
  329 ++ or %g4, ((7 << 2) | 2), %g4 ! 4 = U: --X S: --X (rom, execute only)
  330 ++ sta %g4, [%g2] ASI_M_BYPASS
  331 ++ add %g2, 4, %g2
  332 ++ add %g3, %g5, %g3
  333 ++ deccc %g6
  334 ++ bne 1b
  335 ++ nop
  336 ++#if 0
  337 ++ set (PROLDATA-PROLRODATA)/0x1000, %g6 ! # of .rodata pages
  338 ++1: srl %g3, 0x4, %g4
  339 ++ or %g4, ((0 << 2) | 2), %g4 ! 0 = U: R-- S: R-- (rom, read only)
  340 ++ sta %g4, [%g2] ASI_M_BYPASS
  341 ++ add %g2, 4, %g2
  342 ++ add %g3, %g5, %g3
  343 ++ deccc %g6
  344 ++ bne 1b
  345 ++ nop
  346 ++#endif
  347 ++ set (PROLBASE+PROLSIZE-PROLDATA)/0x1000, %g6 ! # of .bss pages
  348 ++ set 0x1000, %g4
  349 ++ sll %g7, 0x4, %g3
  350 ++ add %g4, %g3, %g3
  351 ++1: srl %g3, 0x4, %g4
  352 ++ or %g4, ((7 << 2) | 2), %g4 ! 5 = U: R-- S: RW- (data area, read/write)
  353 ++ sta %g4, [%g2] ASI_M_BYPASS
  354 ++ add %g2, 4, %g2
  355 ++ add %g3, %g5, %g3
  356 ++ deccc %g6
  357 ++ bne 1b
  358 ++ nop
  359 ++
  360 ++ mov %g1, %g3
  361 ++
  362 ++ set AC_M_CTPR, %g2
  363 ++ sta %g7, [%g2] ASI_M_MMUREGS ! set ctx table ptr
  364 ++ set 1, %g1
  365 ++ sta %g1, [%g0] ASI_M_MMUREGS ! enable mmu
  366 ++
  367 ++ /*
  368 ++ * The code which enables traps is a simplified version of
  369 ++ * kernel head.S.
  370 ++ *
  371 ++ * We know number of windows as 8 so we do not calculate them.
  372 ++ * The deadwood is here for any case.
  373 ++ */
  374 ++
  375 ++ /* Turn on Supervisor, EnableFloating, and all the PIL bits.
  376 ++ * Also puts us in register window zero with traps off.
  377 ++ */
  378 ++ set (PSR_PS | PSR_S | PSR_PIL | PSR_EF), %g2
  379 ++ wr %g2, 0x0, %psr
  380 ++ WRITE_PAUSE
  381 ++
  382 ++ /* I want a kernel stack NOW! */
  383 ++ set C_LABEL(bootup_user_stack), %g1
  384 ++ set (0x2000 - REGWIN_SZ), %g2
  385 ++ add %g1, %g2, %sp
  386 ++ mov 0, %fp /* And for good luck */
  387 ++
  388 ++ /* Zero out our BSS section. */
  389 ++ set C_LABEL(bss_start) , %o0 ! First address of BSS
  390 ++ set C_LABEL(end) , %o1 ! Last address of BSS
  391 ++ ba 2f
  392 ++ nop
  393 ++1:
  394 ++ st %g0, [%o0]
  395 ++2:
  396 ++ subcc %o0, %o1, %g0
  397 ++ bl 1b
  398 ++ add %o0, 0x4, %o0
  399 ++
  400 ++ sethi %hi( C_LABEL(ram_size) ), %o0
  401 ++ st %g3, [%o0 + %lo( C_LABEL(ram_size) )]
  402 ++
  403 ++ mov 2, %g1
  404 ++ wr %g1, 0x0, %wim ! make window 1 invalid
  405 ++ WRITE_PAUSE
  406 ++
  407 ++#if 0
  408 ++ wr %g0, 0x0, %wim
  409 ++ WRITE_PAUSE
  410 ++ save
  411 ++ rd %psr, %g3
  412 ++ restore
  413 ++ and %g3, PSR_CWP, %g3
  414 ++ add %g3, 0x1, %g3
  415 ++#else
  416 ++ or %g0, 8, %g3
  417 ++#endif
  418 ++
  419 ++#if 0
  420 ++ sethi %hi( C_LABEL(cputyp) ), %o0
  421 ++ st %g7, [%o0 + %lo( C_LABEL(cputyp) )]
  422 ++
  423 ++ sethi %hi( C_LABEL(nwindows) ), %g4
  424 ++ st %g3, [%g4 + %lo( C_LABEL(nwindows) )]
  425 ++
  426 ++ sub %g3, 0x1, %g3
  427 ++ sethi %hi( C_LABEL(nwindowsm1) ), %g4
  428 ++ st %g3, [%g4 + %lo( C_LABEL(nwindowsm1) )]
  429 ++#endif
  430 ++
  431 ++ /* Here we go, start using Linux's trap table... */
  432 ++ set C_LABEL(trapbase), %g3
  433 ++ wr %g3, 0x0, %tbr
  434 ++ WRITE_PAUSE
  435 ++
  436 ++ /* Finally, turn on traps so that we can call c-code. */
  437 ++ rd %psr, %g3
  438 ++ wr %g3, 0x0, %psr
  439 ++ WRITE_PAUSE
  440 ++
  441 ++ wr %g3, PSR_ET, %psr
  442 ++ WRITE_PAUSE
  443 ++
  444 ++ .globl prolmain
  445 ++ call C_LABEL(prolmain)
  446 ++ nop
  447 ++
  448 ++3:
  449 ++ b 3b
  450 ++ nop
  451 ++
  452 ++/*
  453 ++ * Memory access trap handler
  454 ++ * %l0 program %psr from trap table entry
  455 ++ * %l1 program %pc from hardware
  456 ++ * %l2 program %npc from hardware
  457 ++ * %l3 program %wim from trap table entry
  458 ++ * %l4
  459 ++ * %l5
  460 ++ * %l6
  461 ++ * %l7 text flag from trap table entry
  462 ++ */
  463 ++
  464 ++ .section ".text"
  465 ++ .globl srmmu_fault
  466 ++C_LABEL(srmmu_fault):
  467 ++
  468 ++ set AC_M_SFAR, %l6
  469 ++ set AC_M_SFSR, %l5
  470 ++ lda [%l6] ASI_M_MMUREGS, %l6
  471 ++ lda [%l5] ASI_M_MMUREGS, %l5
  472 ++
  473 ++ set ignore_fault, %l5
  474 ++ ld [%l5], %l5
  475 ++ subcc %l5, %g0, %g0 /* NULL pointer trap faults always */
  476 ++ be 3f
  477 ++ nop
  478 ++ subcc %l5, %l6, %g0
  479 ++ be 2f
  480 ++ nop
  481 ++3:
  482 ++
  483 ++ set (PHYS_JJ_TCX_FB + 0xbf0), %g5 /* 2 cells from side */
  484 ++ set 0x00ffffff, %g4
  485 ++ sta %g4, [%g5] ASI_M_BYPASS
  486 ++ add %g5, 8, %g5 /* On right side */
  487 ++ sta %g4, [%g5] ASI_M_BYPASS
  488 ++1: ba 1b; nop
  489 ++
  490 ++2:
  491 ++ set C_LABEL(fault_ignored), %l5
  492 ++ mov 1, %l6
  493 ++ st %l6, [%l5]
  494 ++
  495 ++ /*
  496 ++ * Skip the faulting instruction.
  497 ++ * I think it works when next instruction is a branch even.
  498 ++ */
  499 ++ or %l2, 0, %l1
  500 ++ add %l2, 4, %l2
  501 ++
  502 ++ wr %l0, 0, %psr
  503 ++ WRITE_PAUSE
  504 ++ jmp %l1
  505 ++ rett %l2
  506 ++
  507 ++/*
  508 ++ * Slow external versions of st_bypass and ld_bypass.
  509 ++ * rconsole.c uses inlines. We call these in places which are not speed
  510 ++ * critical, to avoid compiler bugs.
  511 ++ */
  512 ++ .globl C_LABEL(st_bypass)
  513 ++C_LABEL(st_bypass):
  514 ++ retl
  515 ++ sta %o1, [%o0] ASI_M_BYPASS
  516 ++ .globl C_LABEL(ld_bypass)
  517 ++C_LABEL(ld_bypass):
  518 ++ retl
  519 ++ lda [%o0] ASI_M_BYPASS, %o0
  520 ++ .globl C_LABEL(sth_bypass)
  521 ++C_LABEL(sth_bypass):
  522 ++ retl
  523 ++ stha %o1, [%o0] ASI_M_BYPASS
  524 ++ .globl C_LABEL(ldh_bypass)
  525 ++C_LABEL(ldh_bypass):
  526 ++ retl
  527 ++ lduha [%o0] ASI_M_BYPASS, %o0
  528 ++ .globl C_LABEL(stb_bypass)
  529 ++C_LABEL(stb_bypass):
  530 ++ retl
  531 ++ stba %o1, [%o0] ASI_M_BYPASS
  532 ++ .globl C_LABEL(ldb_bypass)
  533 ++C_LABEL(ldb_bypass):
  534 ++ retl
  535 ++ lduba [%o0] ASI_M_BYPASS, %o0
  536 +diff -ruN proll_18.orig/qemu/main.c proll-patch4/qemu/main.c
  537 +--- 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 @@
  540 ++/**
  541 ++ ** Proll (PROM replacement)
  542 ++ ** Copyright 1999 Pete Zaitcev
  543 ++ ** This code is licensed under GNU General Public License.
  544 ++ **/
  545 ++#include <stdarg.h>
  546 ++
  547 ++// #include <asm/contregs.h>
  548 ++#include <asi.h>
  549 ++#include "pgtsrmmu.h"
  550 ++#include "iommu.h" /* Typical SBus IOMMU for sun4m */
  551 ++#include "phys_jj.h"
  552 ++#include "vconsole.h"
  553 ++#include "version.h"
  554 ++#include <general.h> /* __P() */
  555 ++#include <net.h> /* init_net() */
  556 ++#include <romlib.h> /* we are a provider for part of this. */
  557 ++#include <netpriv.h> /* myipaddr */
  558 ++#include <arpa.h>
  559 ++#include <system.h> /* our own prototypes */
  560 ++
  561 ++static void init_idprom(void);
  562 ++static void makepages_q(struct phym *t, unsigned int highbase);
  563 ++
  564 ++struct vconterm dp0;
  565 ++struct mem cmem; /* Current memory, virtual */
  566 ++struct mem cio; /* Current I/O space */
  567 ++struct phym pmem; /* Current phys. mem. */
  568 ++struct iommu ciommu; /* Our IOMMU on sun4m */
  569 ++
  570 ++static char *hw_idprom;
  571 ++int ignore_fault, fault_ignored, ram_size;
  572 ++
  573 ++/*
  574 ++ */
  575 ++void prolmain()
  576 ++{
  577 ++ //static const char fname[14] = "00000000.PROL";
  578 ++ static struct banks bb;
  579 ++ unsigned int hiphybas;
  580 ++ const void *romvec;
  581 ++
  582 ++ vcon_init(&dp0, PHYS_JJ_TCX_FB);
  583 ++ printk("PROLL %s QEMU\n", PROLL_VERSION_STRING);
  584 ++ printk("%d MB total\n", ram_size/(1024*1024));
  585 ++
  586 ++ bb.nbanks = 1;
  587 ++ bb.bankv[0].start = 0;
  588 ++ bb.bankv[0].length = ram_size;
  589 ++
  590 ++ hiphybas = ram_size - PROLSIZE;
  591 ++
  592 ++ mem_init(&cmem, (char *) &_end, (char *)(PROLBASE+PROLSIZE));
  593 ++ makepages_q(&pmem, hiphybas);
  594 ++ init_mmu_swift((unsigned int)pmem.pctp - PROLBASE + hiphybas);
  595 ++
  596 ++ mem_init(&cio, (char *)(PROLBASE+PROLSIZE),
  597 ++ (char *)(PROLBASE+PROLSIZE+IOMAPSIZE));
  598 ++
  599 ++ iommu_init(&ciommu, hiphybas);
  600 ++
  601 ++ /*
  602 ++ */
  603 ++ init_idprom();
  604 ++ sched_init();
  605 ++ le_probe();
  606 ++ init_net();
  607 ++
  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
  626 ++
  627 ++ romvec = init_openprom(bb.nbanks, bb.bankv, hiphybas);
  628 ++
  629 ++ printk("Memory used: virt 0x%x:0x%x[%dK] iomap 0x%x:0x%x\n",
  630 ++ PROLBASE, (int)cmem.curp, ((unsigned) cmem.curp - PROLBASE)/1024,
  631 ++ (int)cio.start, (int)cio.curp);
  632 ++ //set_timeout(5); while (!chk_timeout()) { } /* P3: let me read */
  633 ++
  634 ++ {
  635 ++ void (*entry)(const void *, int, int, int, int) = (void (*)(const void*, int, int, int, int)) LOADBASE;
  636 ++ entry(romvec, 0, 0, 0, 0);
  637 ++ }
  638 ++
  639 ++ mem_fini(&cmem);
  640 ++ vcon_fini(&dp0);
  641 ++}
  642 ++
  643 ++/*
  644 ++ * dvma_alloc over iommu_alloc.
  645 ++ */
  646 ++void *dvma_alloc(int size, unsigned int *pphys)
  647 ++{
  648 ++ return iommu_alloc(&ciommu, size, pphys);
  649 ++}
  650 ++
  651 ++/*
  652 ++ */
  653 ++void udelay(unsigned long usecs)
  654 ++{
  655 ++ int i, n;
  656 ++ n = usecs*50;
  657 ++ for (i = 0; i < n; i++) { }
  658 ++}
  659 ++
  660 ++static void init_idprom()
  661 ++{
  662 ++ char *va_prom;
  663 ++
  664 ++ if ((va_prom = map_io(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE)) == NULL) {
  665 ++ printk("init_idprom: cannot map eeprom\n");
  666 ++ fatal();
  667 ++ }
  668 ++ bcopy(va_prom + PHYS_JJ_IDPROM_OFF, idprom, IDPROM_SIZE);
  669 ++ /*
  670 ++ * hw_idprom is not used anywhere.
  671 ++ * It's just as we hate to leave hanging pointers (I/O page here).
  672 ++ */
  673 ++ hw_idprom = va_prom;
  674 ++}
  675 ++
  676 ++/*
  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.
  681 ++ */
  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 ++
  688 ++ ctp = mem_zalloc(&cmem, NCTX_SWIFT*sizeof(int), NCTX_SWIFT*sizeof(int));
  689 ++ l1 = mem_zalloc(&cmem, 256*sizeof(int), 256*sizeof(int));
  690 ++
  691 ++ pte = SRMMU_ET_PTD | (((unsigned int)l1 - PROLBASE + highbase) >> 4);
  692 ++ for (i = 0; i < NCTX_SWIFT; i++) {
  693 ++ ctp[i] = pte;
  694 ++ }
  695 ++
  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 ++ }
  706 ++
  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 ++ }
  713 ++
  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 ++#
  730 ++
  731 ++CC = gcc
  732 ++
  733 ++#CROSS = /usr/local/sparc/bin/sparc-sun-linux-
  734 ++CROSS = sparc-unknown-linux-gnu-
  735 ++
  736 ++CROSSCC = $(CROSS)gcc
  737 ++CROSSLD = $(CROSS)ld
  738 ++CROSSNM = $(CROSS)nm
  739 ++
  740 ++RM = /bin/rm -f
  741 ++ELFTOAOUT = elftoaout
  742 ++
  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 ++};
  929 ++
  930 ++#if 1 /* Zaitcev */
  931 ++static const int pixfreq = 0x03dfd240;
  932 ++static const int hbporch = 0xa0;
  933 ++static const int vfreq = 0x3c;
  934 ++#endif
  935 ++#if 0 /* Kevin Boone - 70Hz refresh */
  936 ++static const int pixfreq = 0x047868C0;
  937 ++static const int hbporch = 0x90;
  938 ++static const int vfreq = 0x46;
  939 ++#endif
  940 ++
  941 ++static const int vbporch = 0x1d;
  942 ++static const int vsync = 0x6;
  943 ++static const int hsync = 0x88;
  944 ++static const int vfporch = 0x3;
  945 ++static const int hfporch = 0x18;
  946 ++static const int height = 0x300;
  947 ++static const int width = 0x400;
  948 ++static const int linebytes = 0x400;
  949 ++static const int depth = 8;
  950 ++static const int tcx_intr[] = { 5, 0 };
  951 ++static const int tcx_interrupts = 5;
  952 ++static const struct property propv_sbus_tcx[] = {
  953 ++ {"name", "SUNW,tcx", sizeof("SUNW,tcx")},
  954 ++ {"vbporch", (char*)&vbporch, sizeof(int)},
  955 ++ {"hbporch", (char*)&hbporch, sizeof(int)},
  956 ++ {"vsync", (char*)&vsync, sizeof(int)},
  957 ++ {"hsync", (char*)&hsync, sizeof(int)},
  958 ++ {"vfporch", (char*)&vfporch, sizeof(int)},
  959 ++ {"hfporch", (char*)&hfporch, sizeof(int)},
  960 ++ {"pixfreq", (char*)&pixfreq, sizeof(int)},
  961 ++ {"vfreq", (char*)&vfreq, sizeof(int)},
  962 ++ {"height", (char*)&height, sizeof(int)},
  963 ++ {"width", (char*)&width, sizeof(int)},
  964 ++ {"linebytes", (char*)&linebytes, sizeof(int)},
  965 ++ {"depth", (char*)&depth, sizeof(int)},
  966 ++ {"reg", (char*)&prop_tcx_regs[0], sizeof(prop_tcx_regs)},
  967 ++ {"tcx-8-bit", (char*)&prop_true, 0},
  968 ++ {"intr", (char*)&tcx_intr[0], sizeof(tcx_intr)},
  969 ++ {"interrupts", (char*)&tcx_interrupts, sizeof(tcx_interrupts)},
  970 ++ {"device_type", "display", sizeof("display")},
  971 ++ {NULL, NULL, -1}
  972 ++};
  973 ++
  974 ++static const int prop_cs4231_reg[] = {
  975 ++ 0x3, 0x0C000000, 0x00000040
  976 ++};
  977 ++static const int cs4231_interrupts = 5;
  978 ++static const int cs4231_intr[] = { 5, 0 };
  979 ++
  980 ++static const struct property propv_sbus_cs4231[] = {
  981 ++ {"name", "SUNW,CS4231", sizeof("SUNW,CS4231") },
  982 ++ {"intr", (char*)&cs4231_intr[0], sizeof(cs4231_intr) },
  983 ++ {"interrupts", (char*)&cs4231_interrupts, sizeof(cs4231_interrupts) },
  984 ++ {"reg", (char*)&prop_cs4231_reg[0], sizeof(prop_cs4231_reg) },
  985 ++ {"device_type", "serial", sizeof("serial") },
  986 ++ {"alias", "audio", sizeof("audio") },
  987 ++ {NULL, NULL, -1}
  988 ++};
  989 ++
  990 ++static const int cpu_nctx = NCTX_SWIFT;
  991 ++static const int cpu_cache_line_size = 0x20;
  992 ++static const int cpu_cache_nlines = 0x200;
  993 ++static const struct property propv_cpu[] = {
  994 ++ {"name", "STP1012PGA", sizeof("STP1012PGA") },
  995 ++ {"device_type", "cpu", 4 },
  996 ++ {"mmu-nctx", (char*)&cpu_nctx, sizeof(int)},
  997 ++ {"cache-line-size", (char*)&cpu_cache_line_size, sizeof(int)},
  998 ++ {"cache-nlines", (char*)&cpu_cache_nlines, sizeof(int)},
  999 ++ {NULL, NULL, -1}
  1000 ++};
  1001 ++
  1002 ++static const int prop_obio_ranges[] = {
  1003 ++ 0x0, 0x0, 0x0, 0x71000000, 0x01000000,
  1004 ++};
  1005 ++static const struct property propv_obio[] = {
  1006 ++ {"name", "obio", 5 },
  1007 ++ {"ranges", (char*)&prop_obio_ranges[0], sizeof(prop_obio_ranges) },
  1008 ++ {NULL, NULL, -1}
  1009 ++};
  1010 ++
  1011 ++static const int prop_auxio_reg[] = {
  1012 ++ 0x0, 0x00900000, 0x00000001,
  1013 ++};
  1014 ++static const struct property propv_obio_auxio[] = {
  1015 ++ {"name", "auxio", sizeof("auxio") },
  1016 ++ {"reg", (char*)&prop_auxio_reg[0], sizeof(prop_auxio_reg) },
  1017 ++ {NULL, NULL, -1}
  1018 ++};
  1019 ++
  1020 ++static const int prop_int_reg[] = {
  1021 ++ 0x0, 0x00e00000, 0x00000010,
  1022 ++ 0x0, 0x00e10000, 0x00000010,
  1023 ++};
  1024 ++static const struct property propv_obio_int[] = {
  1025 ++ {"name", "interrupt", sizeof("interrupt")},
  1026 ++ {"reg", (char*)&prop_int_reg[0], sizeof(prop_int_reg) },
  1027 ++ {NULL, NULL, -1}
  1028 ++};
  1029 ++
  1030 ++static const int prop_cnt_reg[] = {
  1031 ++ 0x0, 0x00d00000, 0x00000010,
  1032 ++ 0x0, 0x00d10000, 0x00000010,
  1033 ++};
  1034 ++static const struct property propv_obio_cnt[] = {
  1035 ++ {"name", "counter", sizeof("counter")},
  1036 ++ {"reg", (char*)&prop_cnt_reg[0], sizeof(prop_cnt_reg) },
  1037 ++ {NULL, NULL, -1}
  1038 ++};
  1039 ++
  1040 ++static const int prop_eeprom_reg[] = {
  1041 ++ 0x0, 0x00200000, 0x00002000,
  1042 ++};
  1043 ++static const struct property propv_obio_eep[] = {
  1044 ++ {"name", "eeprom", sizeof("eeprom")},
  1045 ++ {"reg", (char*)&prop_eeprom_reg[0], sizeof(prop_eeprom_reg) },
  1046 ++ {"model", "mk48t08", sizeof("mk48t08")},
  1047 ++ {NULL, NULL, -1}
  1048 ++};
  1049 ++
  1050 ++static const int prop_su_reg[] = {
  1051 ++ 0x0, 0x003002f8, 0x00000008,
  1052 ++};
  1053 ++static const struct property propv_obio_su[] = {
  1054 ++ {"name", "su", sizeof("su")},
  1055 ++ {"reg", (char*)&prop_su_reg[0], sizeof(prop_su_reg) },
  1056 ++ {NULL, NULL, -1}
  1057 ++};
  1058 ++
  1059 ++static const int prop_zs_intr[] = { 0x26, 0x0 };
  1060 ++static const int prop_zs_reg[] = {
  1061 ++ 0x4, 0x00000000, 0x0000000f,
  1062 ++};
  1063 ++static const int prop_zs_slave[] = { 0x1 };
  1064 ++static const struct property propv_obio_zs[] = {
  1065 ++ {"name", "zs", sizeof("zs")},
  1066 ++ {"reg", (char*)&prop_zs_reg[0], sizeof(prop_zs_reg) },
  1067 ++ {"reg", (char*)&prop_zs_slave[0], sizeof(prop_zs_slave) },
  1068 ++ {"device_type", "serial", sizeof("serial") },
  1069 ++ {NULL, NULL, -1}
  1070 ++};
  1071 ++
  1072 ++static const int prop_zs1_intr[] = { 0x26, 0x0 };
  1073 ++static const int prop_zs1_reg[] = {
  1074 ++ 0x4, 0x00100000, 0x0000000f,
  1075 ++};
  1076 ++static const int prop_zs1_slave[] = { 0x0 };
  1077 ++static const struct property propv_obio_zs1[] = {
  1078 ++ {"name", "zs", sizeof("zs")},
  1079 ++ {"reg", (char*)&prop_zs1_reg[0], sizeof(prop_zs1_reg) },
  1080 ++ {"reg", (char*)&prop_zs1_slave[0], sizeof(prop_zs1_slave) },
  1081 ++ {"device_type", "serial", sizeof("serial") },
  1082 ++ {NULL, NULL, -1}
  1083 ++};
  1084 ++
  1085 ++static const int prop_ledma_reg[] = {
  1086 ++ 0x4, 0x08400010, 0x00000020,
  1087 ++};
  1088 ++static const int prop_ledma_burst = 0x3f;
  1089 ++static const struct property propv_sbus_ledma[] = {
  1090 ++ {"name", "ledma", sizeof("ledma")},
  1091 ++ {"reg", (char*)&prop_ledma_reg[0], sizeof(prop_ledma_reg) },
  1092 ++ {"burst-sizes", (char*)&prop_ledma_burst, sizeof(int) },
  1093 ++ {NULL, NULL, -1}
  1094 ++};
  1095 ++
  1096 ++static const int prop_le_reg[] = {
  1097 ++ 0x4, 0x08c00000, 0x00000004,
  1098 ++};
  1099 ++static const int prop_le_busmaster_regval = 0x7;
  1100 ++static const int prop_le_intr[] = { 0x26, 0x0 };
  1101 ++static const struct property propv_sbus_ledma_le[] = {
  1102 ++ {"name", "le", sizeof("le")},
  1103 ++ {"reg", (char*)&prop_le_reg[0], sizeof(prop_le_reg) },
  1104 ++ {"busmaster-regval", (char*)&prop_le_busmaster_regval, sizeof(int)},
  1105 ++ {"intr", (char*)&prop_le_intr[0], sizeof(prop_le_intr) },
  1106 ++ {NULL, NULL, -1}
  1107 ++};
  1108 ++
  1109 ++static const struct node nodes[] = {
  1110 ++ { &null_properties, 1, 0 }, /* 0 = big brother of root */
  1111 ++ { propv_root, 0, 2 }, /* 1 "/" */
  1112 ++ { propv_iommu, 8, 3 }, /* 2 "/iommu" */
  1113 ++ { propv_sbus, 0, 4 }, /* 3 "/iommu/sbus" */
  1114 ++ { propv_sbus_tcx, 5, 0 }, /* 4 "/iommu/sbus/SUNW,tcx" */
  1115 ++ { propv_sbus_ledma, 7, 6 }, /* 5 "/iommu/sbus/ledma" */
  1116 ++ { propv_sbus_ledma_le, 0, 0 }, /* 6 "/iommu/sbus/ledma/le" */
  1117 ++ { propv_sbus_cs4231, 0, 0 }, /* 7 "/iommu/sbus/SUNW,CS4231 */
  1118 ++ { propv_cpu, 9, 0 }, /* 8 "/STP1012PGA" */
  1119 ++ { propv_obio, 0, 10 }, /* 9 "/obio" */
  1120 ++ { propv_obio_int, 11, 0 }, /* 10 "/obio/interrupt" */
  1121 ++ { propv_obio_cnt, 12, 0 }, /* 11 "/obio/counter" */
  1122 ++ { propv_obio_eep, 13, 0 }, /* 12 "/obio/eeprom" */
  1123 ++ { propv_obio_su, 14, 0 }, /* 13 "/obio/su" */
  1124 ++ { propv_obio_auxio, 0, 0 }, /* 14 "/obio/auxio" */
  1125 ++ { propv_obio_zs, 0, 0 }, /* 14 "/obio/zs@0,0" */
  1126 ++ { propv_obio_zs1, 0, 0 }, /* 14 "/obio/zs@0,100000" */
  1127 ++};
  1128 ++
  1129 ++static struct linux_mlist_v0 totphys[MAX_BANKS];
  1130 ++static struct linux_mlist_v0 totmap[1];
  1131 ++static struct linux_mlist_v0 totavail[MAX_BANKS];
  1132 ++
  1133 ++static struct linux_mlist_v0 *ptphys;
  1134 ++static struct linux_mlist_v0 *ptmap;
  1135 ++static struct linux_mlist_v0 *ptavail;
  1136 ++
  1137 ++static const struct linux_nodeops nodeops0 = {
  1138 ++ obp_nextnode, /* int (*no_nextnode)(int node); */
  1139 ++ obp_child, /* int (*no_child)(int node); */
  1140 ++ obp_proplen, /* int (*no_proplen)(int node, char *name); */
  1141 ++ obp_getprop, /* int (*no_getprop)(int node,char *name,char *val); */
  1142 ++ obp_setprop, /* int (*no_setprop)(int node, char *name,
  1143 ++ char *val, int len); */
  1144 ++ obp_nextprop /* char * (*no_nextprop)(int node, char *name); */
  1145 ++};
  1146 ++
  1147 ++static const char arg_nfsroot[] = "console=ttyS0 ip=bootp root=nfs";
  1148 ++
  1149 ++static const struct linux_arguments_v0 obp_arg = {
  1150 ++ { "le()", arg_nfsroot, NULL, NULL, NULL, NULL, NULL, NULL },
  1151 ++ { "" },
  1152 ++ { 'l', 'e' }, 0, 0, 0, NULL,
  1153 ++ NULL
  1154 ++};
  1155 ++static const struct linux_arguments_v0 * const obp_argp = &obp_arg;
  1156 ++
  1157 ++static const void * const synch_hook = NULL;
  1158 ++#if 0
  1159 ++static const char obp_stdin = PROMDEV_KBD;
  1160 ++static const char obp_stdout = PROMDEV_SCREEN;
  1161 ++#else
  1162 ++static const char obp_stdin = PROMDEV_TTYA;
  1163 ++static const char obp_stdout = PROMDEV_TTYA;
  1164 ++#endif
  1165 ++
  1166 ++static int obp_nbgetchar(void);
  1167 ++static int obp_nbputchar(int ch);
  1168 ++static void obp_reboot(char *);
  1169 ++static void obp_abort(void);
  1170 ++static void obp_halt(void);
  1171 ++static int obp_devopen(char *str);
  1172 ++static int obp_devclose(int dev_desc);
  1173 ++static int obp_rdblkdev(int dev_desc, int num_blks, int blk_st, char *buf);
  1174 ++
  1175 ++static void doublewalk(unsigned ptab1, unsigned va)
  1176 ++{
  1177 ++unsigned int proc_tablewalk(int ctx, unsigned int va);
  1178 ++unsigned int mem_tablewalk(unsigned int pa, unsigned int va);
  1179 ++
  1180 ++ proc_tablewalk(0, va);
  1181 ++ if (ptab1 != 0) mem_tablewalk(ptab1, va);
  1182 ++}
  1183 ++
8 +#ifdef ORIG 1184 +#ifdef ORIG
9 - #if 0 /* RARP */  
10 - if (rarp() != 0) fatal();  
11 - /* printrarp(); */  
12 -@@ -117,13 +118,20 @@  
13 - xtoa(myipaddr, fname, 8);  
14 - if (load(boot_rec.bp_siaddr, fname) != 0) fatal(); 1185 ++static const struct linux_romvec romvec0 = {
  1186 ++ LINUX_OPPROM_MAGIC, /* pv_magic_cookie */
  1187 ++ 0, /* pv_romvers - Format selector! */
  1188 ++ 77, /* pv_plugin_revision */
  1189 ++ 0x10203, /* pv_printrev */
  1190 ++ { /* pv_v0mem */
  1191 ++ &ptphys, /* v0_totphys */
  1192 ++ &ptmap, /* v0_prommap */
  1193 ++ &ptavail /* v0_available */
  1194 ++ },
  1195 ++ &nodeops0, /* struct linux_nodeops *pv_nodeops; */
  1196 ++ (void*)doublewalk, /* P3 */ /* char **pv_bootstr; */
  1197 ++ { /* struct linux_dev_v0_funcs pv_v0devops; */
  1198 ++ &obp_devopen, /* v0_devopen */
  1199 ++ &obp_devclose, /* v0_devclose */
  1200 ++ &obp_rdblkdev, /* v0_rdblkdev */
  1201 ++ NULL, /* v0_wrblkdev */
  1202 ++ NULL, /* v0_wrnetdev */
  1203 ++ NULL, /* v0_rdnetdev */
  1204 ++ NULL, /* v0_rdchardev */
  1205 ++ NULL, /* v0_wrchardev */
  1206 ++ NULL /* v0_seekdev */
  1207 ++ },
  1208 ++ &obp_stdin, /* char *pv_stdin */
  1209 ++ &obp_stdout, /* char *pv_stdout; */
  1210 ++ obp_nbgetchar, /* int (*pv_getchar)(void); */
  1211 ++ obp_nbputchar, /* void (*pv_putchar)(int ch); */
  1212 ++ obp_nbgetchar, /* int (*pv_nbgetchar)(void); */
  1213 ++ obp_nbputchar, /* int (*pv_nbputchar)(int ch); */
  1214 ++ NULL, /* void (*pv_putstr)(char *str, int len); */
  1215 ++ obp_reboot, /* void (*pv_reboot)(char *bootstr); */
  1216 ++ NULL, /* void (*pv_printf)(__const__ char *fmt, ...); */
  1217 ++ obp_abort, /* void (*pv_abort)(void); */
  1218 ++ NULL, /* __volatile__ int *pv_ticks; */
  1219 ++ obp_halt, /* void (*pv_halt)(void); */
  1220 ++ (void *)&synch_hook, /* void (**pv_synchook)(void); */
  1221 ++
  1222 ++#if 0
  1223 ++ /* Evaluate a forth string, not different proto for V0 and V2->up. */
  1224 ++ union {
  1225 ++ void (*v0_eval)(int len, char *str);
  1226 ++ void (*v2_eval)(char *str);
  1227 ++ } pv_fortheval;
  1228 ++#endif
  1229 ++ { 0 }, /* pv_fortheval */
  1230 ++
  1231 ++ &obp_argp, /* struct linux_arguments_v0 **pv_v0bootargs; */
  1232 ++ NULL, /* pv_enaddr */
  1233 ++ { /* pv_v2bootargs */
  1234 ++ NULL, /* char **bootpath; */
  1235 ++ NULL, /* char **bootargs; */
  1236 ++ NULL, /* fd_stdin; */
  1237 ++ NULL, /* fd_stdout */
  1238 ++ },
  1239 ++ { /* pv_v2devops */
  1240 ++ NULL, /* v2_inst2pkg */
  1241 ++ NULL, /* v2_dumb_mem_alloc */
  1242 ++ NULL, /* v2_dumb_mem_free */
  1243 ++ NULL, /* v2_dumb_mmap */
  1244 ++ NULL, /* v2_dumb_munmap */
  1245 ++ NULL, /* v2_dev_open */
  1246 ++ NULL, /* v2_dev_close */
  1247 ++ NULL, /* v2_dev_read */
  1248 ++ NULL, /* v2_dev_write */
  1249 ++ NULL, /* v2_dev_seek */
  1250 ++ NULL, /* v2_wheee2 */
  1251 ++ NULL, /* v2_wheee3 */
  1252 ++ },
  1253 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* filler[15] */
  1254 ++ NULL, /* pv_setctxt */
  1255 ++ NULL, /* v3_cpustart */
  1256 ++ NULL, /* v3_cpustop */
  1257 ++ NULL, /* v3_cpuidle */
  1258 ++ NULL /* v3_cpuresume */
  1259 ++};
  1260 ++#endif
  1261 ++
  1262 ++static struct linux_romvec romvec0;
  1263 ++
  1264 ++void *
  1265 ++init_openprom(int bankc, struct bank *bankv, unsigned hiphybas)
  1266 ++{
  1267 ++ int i;
  1268 ++
  1269 ++ /*
  1270 ++ * Avoid data segment allocations
  1271 ++ */
  1272 ++ ptphys = totphys;
  1273 ++ ptmap = totmap;
  1274 ++ ptavail = totavail;
  1275 ++ /*
  1276 ++ * Form memory descriptors.
  1277 ++ */
  1278 ++ for (i = 0; i < bankc; i++) {
  1279 ++ totphys[i].theres_more = &totphys[i+1];
  1280 ++ totphys[i].start_adr = (char*) bankv[i].start;
  1281 ++ totphys[i].num_bytes = bankv[i].length;
  1282 ++ }
  1283 ++ totphys[i-1].theres_more = 0;
  1284 ++
  1285 ++ /*
  1286 ++ * XXX Merged in normal PROM when full banks touch.
  1287 ++ */
  1288 ++ for (i = 0; i < bankc; i++) {
  1289 ++ unsigned bankbase = bankv[i].start;
  1290 ++ unsigned banksize = bankv[i].length;
  1291 ++ if (hiphybas > bankbase &&
  1292 ++ hiphybas < bankbase + banksize) {
  1293 ++ banksize = hiphybas - bankbase;
  1294 ++ }
  1295 ++ totavail[i].theres_more = &totavail[i+1];
  1296 ++ totavail[i].start_adr = (char*) bankbase;
  1297 ++ totavail[i].num_bytes = banksize;
  1298 ++ }
  1299 ++ totavail[i-1].theres_more = 0;
  1300 ++
  1301 ++ totmap[0].theres_more = 0;
  1302 ++ totmap[0].start_adr = (char*) PROLBASE;
  1303 ++ totmap[0].num_bytes = PROLSIZE;
  1304 ++
  1305 ++ /*
  1306 ++ * idprom
  1307 ++ */
  1308 ++ bcopy(idprom, obp_idprom, IDPROM_SIZE);
  1309 ++
  1310 ++ // Linux wants a R/W romvec table
  1311 ++ romvec0.pv_magic_cookie = LINUX_OPPROM_MAGIC;
  1312 ++ romvec0.pv_plugin_revision = 77;
  1313 ++ romvec0.pv_printrev = 0x10203;
  1314 ++ romvec0.pv_v0mem.v0_totphys = &ptphys;
  1315 ++ romvec0.pv_v0mem.v0_prommap = &ptmap;
  1316 ++ romvec0.pv_v0mem.v0_available = &ptavail;
  1317 ++ romvec0.pv_nodeops = &nodeops0;
  1318 ++ romvec0.pv_bootstr = (void *)doublewalk;
  1319 ++ romvec0.pv_stdin = &obp_stdin;
  1320 ++ romvec0.pv_stdout = &obp_stdout;
  1321 ++ romvec0.pv_getchar = obp_nbgetchar;
  1322 ++ romvec0.pv_putchar = obp_nbputchar;
  1323 ++ romvec0.pv_nbgetchar = obp_nbgetchar;
  1324 ++ romvec0.pv_nbputchar = obp_nbputchar;
  1325 ++ romvec0.pv_reboot = obp_reboot;
  1326 ++ romvec0.pv_abort = obp_abort;
  1327 ++ romvec0.pv_halt = obp_halt;
  1328 ++ romvec0.pv_synchook = &synch_hook;
  1329 ++ romvec0.pv_v0bootargs = &obp_argp;
  1330 ++ return &romvec0;
  1331 ++}
  1332 ++
  1333 ++static const struct property *find_property(int node,char *name)
  1334 ++{
  1335 ++ const struct property *prop = &nodes[node].properties[0];
  1336 ++ while (prop && prop->name) {
  1337 ++ if (bcmp(prop->name, name, 128) == 0) return prop;
  1338 ++ prop++;
  1339 ++ }
  1340 ++ return NULL;
  1341 ++}
  1342 ++
  1343 ++static int obp_nextnode(int node)
  1344 ++{
  1345 ++ return nodes[node].sibling;
  1346 ++}
  1347 ++
  1348 ++static int obp_child(int node)
  1349 ++{
  1350 ++ return nodes[node].child;
  1351 ++}
  1352 ++
  1353 ++static int obp_proplen(int node, char *name)
  1354 ++{
  1355 ++ const struct property *prop = find_property(node,name);
  1356 ++ if (prop) return prop->length;
  1357 ++ return -1;
  1358 ++}
  1359 ++
  1360 ++static int obp_getprop(int node, char *name, char *value)
  1361 ++{
  1362 ++ const struct property *prop;
  1363 ++
  1364 ++ prop = find_property(node,name);
  1365 ++ if (prop) {
  1366 ++ memcpy(value,prop->value,prop->length);
  1367 ++ //printk("obp_getprop '%s'= %s\n", name, value);
  1368 ++ return prop->length;
  1369 ++ }
  1370 ++ //printk("obp_getprop: not found\n");
  1371 ++ return -1;
  1372 ++}
  1373 ++
  1374 ++static int obp_setprop(int node, char *name, char *value, int len)
  1375 ++{
  1376 ++ return -1;
  1377 ++}
  1378 ++
  1379 ++static const char *obp_nextprop(int node,char *name)
  1380 ++{
  1381 ++ const struct property *prop = find_property(node,name);
  1382 ++ if (prop) return prop[1].name;
  1383 ++ return NULL;
  1384 ++}
  1385 ++
  1386 ++#if 0
  1387 ++static unsigned char calc_idprom_cksum(struct idprom *idprom)
  1388 ++{
  1389 ++ unsigned char cksum, i, *ptr = (unsigned char *)idprom;
  1390 ++
  1391 ++ for (i = cksum = 0; i <= 0x0E; i++)
  1392 ++ cksum ^= *ptr++;
  1393 ++
  1394 ++ return cksum;
  1395 ++}
  1396 ++#endif
  1397 ++
  1398 ++static int obp_nbgetchar(void) {
  1399 ++ return -1;
  1400 ++}
  1401 ++
  1402 ++static int obp_nbputchar(int ch) {
  1403 ++ extern struct vconterm dp0;
  1404 ++ char buf = ch;
  1405 ++
  1406 ++ /* We do not use printk() in order to reduce stack depth. */
  1407 ++ vcon_write(&dp0, &buf, 1);
  1408 ++ return 0;
  1409 ++}
  1410 ++
  1411 ++static void obp_reboot(char *str) {
  1412 ++ printk("rebooting (%s): not implemented, freezing\n", str);
  1413 ++ for (;;) {}
  1414 ++}
  1415 ++
  1416 ++static void obp_abort() {
  1417 ++ printk("abort, freezing\n");
  1418 ++ for (;;) {}
  1419 ++}
  1420 ++
  1421 ++static void obp_halt() {
  1422 ++ printk("halt, freezing\n");
  1423 ++ for (;;) {}
  1424 ++}
  1425 ++
  1426 ++static int obp_devopen(char *str) {
  1427 ++ //printk("open %s\n", str);
  1428 ++ return 0;
  1429 ++}
  1430 ++
  1431 ++static int obp_devclose(int dev_desc) {
  1432 ++ //printk("close %d\n", dev_desc);
  1433 ++ return 0;
  1434 ++}
  1435 ++
  1436 ++static int obp_rdblkdev(int dev_desc, int num_blks, int blk_st, char *buf) {
  1437 ++ //printk("rdblkdev: fd %d, num_blks %d, blk_st %d, buf 0x%x\n", dev_desc, num_blks, blk_st, buf);
  1438 ++ //buf[8] = 'L';
  1439 ++ return num_blks;
  1440 ++}
  1441 +diff -ruN proll_18.orig/src/arp.c proll-patch4/src/arp.c
  1442 +--- proll_18.orig/src/arp.c 2001-12-24 05:12:31.000000000 +0000
  1443 ++++ proll-patch4/src/arp.c 2004-11-13 15:50:49.000000000 +0000
  1444 +@@ -45,7 +45,7 @@
  1445 + #endif
  1446 + static struct arp_cache arp_list[ARPNUM]; /* ARP address cache */
  1447 + static int next_arp; /* next table entry */
  1448 +-static t_ipaddr def_gw = IP_ANY; /* default routing */
  1449 ++static t_ipaddr def_gw; /* default routing */
  1450 +
  1451 +
  1452 +
  1453 +@@ -144,7 +144,7 @@
  1454 + *
  1455 + * Resolve IP address and return pointer to hardware address.
  1456 + */
  1457 +-unsigned char *ip_resolve(ip)
  1458 ++const unsigned char *ip_resolve(ip)
  1459 + t_ipaddr ip;
  1460 + {
  1461 + int i;
  1462 +@@ -230,14 +230,11 @@
  1463 + */
  1464 + int init_arp()
  1465 + {
  1466 +- /* Set name of module for error messages */
  1467 +- net_module_name = "arp";
  1468 +-
  1469 + #ifndef NOARP
  1470 + /* Register ARP packet type and set send buffer pointer */
  1471 + if ((arpbuf = (struct arphdr *)reg_type(htons(ETH_P_ARP), arp_recv)) == NULL)
  1472 + return(FALSE);
15 #endif 1473 #endif
  1474 +-
  1475 ++ def_gw = IP_ANY;
  1476 + return(TRUE);
  1477 + }
  1478 +diff -ruN proll_18.orig/src/arp.h proll-patch4/src/arp.h
  1479 +--- proll_18.orig/src/arp.h 1999-03-18 03:39:43.000000000 +0000
  1480 ++++ proll-patch4/src/arp.h 2004-11-13 15:50:49.000000000 +0000
  1481 +@@ -104,7 +104,7 @@
  1482 + extern int init_arp __P((void));
  1483 +
  1484 + /* Resolve IP address and return pointer to hardware address */
  1485 +-extern unsigned char *ip_resolve __P((t_ipaddr ip));
  1486 ++extern const unsigned char *ip_resolve __P((t_ipaddr ip));
  1487 +
  1488 + /* Add a new antry to the ARP cache */
  1489 + extern void addcache __P((unsigned char *ha, t_ipaddr ip));
  1490 +diff -ruN proll_18.orig/src/hconsole.c proll-patch4/src/hconsole.c
  1491 +--- proll_18.orig/src/hconsole.c 2002-07-23 05:52:48.000000000 +0000
  1492 ++++ proll-patch4/src/hconsole.c 2004-11-13 15:50:49.000000000 +0000
  1493 +@@ -42,7 +42,11 @@
  1494 + * No probing sequence or argument passing, hardcode everything. XXX
  1495 + */
  1496 + raster8_cons_a(q, 768, 1024, (char *)a0);
  1497 ++#if 1
  1498 + raster_cons_2(r, q, 768-(24*11)-1, 1024-(8*80)-1, (24*11), (8*80));
  1499 ++#else
  1500 ++ raster_cons_2(r, q, 0, 0, 768, 1024);
16 +#endif 1501 +#endif
  1502 + t->r_ = r;
  1503 + t->r0_ = q;
  1504 + t->f_ = &f_master;
  1505 +diff -ruN proll_18.orig/src/lat7_2.bm proll-patch4/src/lat7_2.bm
  1506 +--- proll_18.orig/src/lat7_2.bm 1999-02-27 05:48:54.000000000 +0000
  1507 ++++ proll-patch4/src/lat7_2.bm 2004-11-13 15:50:49.000000000 +0000
  1508 +@@ -1,6 +1,6 @@
  1509 + #define lat7_2_width 128
  1510 + #define lat7_2_height 88
  1511 +-static unsigned char lat7_2_bits[] = {
  1512 ++static unsigned const char lat7_2_bits[] = {
  1513 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1514 + 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x12, 0x1e, 0x0c, 0x02, 0x70, 0x18,
  1515 + 0x22, 0x22, 0x18, 0x00, 0x00, 0x18, 0x18, 0xff, 0x18, 0x00, 0x12, 0x02,
  1516 +diff -ruN proll_18.orig/src/lat7_2_swapped.bm proll-patch4/src/lat7_2_swapped.bm
  1517 +--- proll_18.orig/src/lat7_2_swapped.bm 1970-01-01 00:00:00.000000000 +0000
  1518 ++++ proll-patch4/src/lat7_2_swapped.bm 2004-11-13 15:50:49.000000000 +0000
  1519 +@@ -0,0 +1,121 @@
  1520 ++#define lat7_2_width 128
  1521 ++#define lat7_2_height 88
  1522 ++static unsigned const char lat7_2_bits[] = {
  1523 ++ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
  1524 ++ 0x55, 0x00, 0x2a, 0x00, 0x55, 0x00, 0x2a, 0x00, 0x55, 0x00, 0x00, 0x48,
  1525 ++ 0x48, 0x78, 0x48, 0x5f, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x78, 0x40,
  1526 ++ 0x70, 0x40, 0x4f, 0x08, 0x0e, 0x08, 0x08, 0x00, 0x00, 0x30, 0x40, 0x40,
  1527 ++ 0x40, 0x3e, 0x09, 0x0e, 0x0a, 0x09, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40,
  1528 ++ 0x7f, 0x08, 0x0e, 0x08, 0x08, 0x00, 0x00, 0x0e, 0x0a, 0x0e, 0x00, 0x00,
  1529 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00,
  1530 ++ 0x7e, 0x00, 0x00, 0x00, 0x00, 0x44, 0x64, 0x54, 0x4c, 0x54, 0x10, 0x10,
  1531 ++ 0x10, 0x1f, 0x00, 0x00, 0x44, 0x44, 0x44, 0x28, 0x1f, 0x04, 0x04, 0x04,
  1532 ++ 0x04, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00,
  1533 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x00,
  1534 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00,
  1535 ++ 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
  1536 ++ 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00,
  1537 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
  1538 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1539 ++ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1540 ++ 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1541 ++ 0x00, 0x00, 0xff, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18,
  1542 ++ 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18,
  1543 ++ 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00,
  1544 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x00,
  1545 ++ 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00,
  1546 ++ 0x06, 0x0c, 0x18, 0x30, 0x18, 0x6c, 0x36, 0x18, 0x0c, 0x00, 0x00, 0x60,
  1547 ++ 0x30, 0x18, 0x0c, 0x18, 0x36, 0x6c, 0x18, 0x30, 0x00, 0x00, 0x7f, 0x36,
  1548 ++ 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x7e,
  1549 ++ 0x18, 0x7e, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x36, 0x30, 0x78,
  1550 ++ 0x30, 0x72, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
  1551 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
  1552 ++ 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1553 ++ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x00,
  1554 ++ 0x00, 0x00, 0x00, 0x66, 0x66, 0x22, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
  1555 ++ 0x00, 0x00, 0x36, 0x7f, 0x36, 0x36, 0x36, 0x7f, 0x36, 0x00, 0x00, 0x00,
  1556 ++ 0x00, 0x66, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00,
  1557 ++ 0x72, 0x56, 0x6c, 0x18, 0x36, 0x6a, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x18,
  1558 ++ 0x24, 0x28, 0x30, 0x4a, 0x44, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
  1559 ++ 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x18,
  1560 ++ 0x18, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x18, 0x18,
  1561 ++ 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0x7e, 0x3c,
  1562 ++ 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18,
  1563 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
  1564 ++ 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
  1565 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
  1566 ++ 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x40, 0x00, 0x00, 0x00,
  1567 ++ 0x00, 0x3c, 0x46, 0x4e, 0x5a, 0x72, 0x62, 0x3c, 0x00, 0x00, 0x00, 0x00,
  1568 ++ 0x18, 0x38, 0x58, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x3c,
  1569 ++ 0x66, 0x06, 0x0c, 0x18, 0x32, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
  1570 ++ 0x06, 0x1c, 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
  1571 ++ 0x66, 0x7e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x60, 0x7c, 0x66,
  1572 ++ 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x60, 0x7c, 0x66, 0x66,
  1573 ++ 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x46, 0x06, 0x0c, 0x18, 0x30,
  1574 ++ 0x30, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x3c,
  1575 ++ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x3c, 0x00,
  1576 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00,
  1577 ++ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x08, 0x10, 0x00,
  1578 ++ 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00,
  1579 ++ 0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
  1580 ++ 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
  1581 ++ 0x06, 0x0c, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x5e,
  1582 ++ 0x56, 0x5e, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 0x66,
  1583 ++ 0x7e, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x66,
  1584 ++ 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66,
  1585 ++ 0x3c, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c,
  1586 ++ 0x00, 0x00, 0x00, 0x00, 0x7e, 0x62, 0x60, 0x78, 0x60, 0x62, 0x7e, 0x00,
  1587 ++ 0x00, 0x00, 0x00, 0x7e, 0x62, 0x60, 0x78, 0x60, 0x60, 0x60, 0x00, 0x00,
  1588 ++ 0x00, 0x00, 0x3c, 0x66, 0x60, 0x6e, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00,
  1589 ++ 0x00, 0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
  1590 ++ 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x7e,
  1591 ++ 0x46, 0x06, 0x06, 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6c,
  1592 ++ 0x78, 0x70, 0x78, 0x6c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x60,
  1593 ++ 0x60, 0x60, 0x62, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x41, 0x63, 0x77, 0x7f,
  1594 ++ 0x6b, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x76, 0x7e, 0x6e,
  1595 ++ 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66,
  1596 ++ 0x3c, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60,
  1597 ++ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x6e, 0x3c, 0x02,
  1598 ++ 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x00, 0x00,
  1599 ++ 0x00, 0x00, 0x3c, 0x66, 0x60, 0x3c, 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00,
  1600 ++ 0x00, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
  1601 ++ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x66,
  1602 ++ 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63,
  1603 ++ 0x63, 0x6b, 0x6b, 0x7f, 0x36, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x3c,
  1604 ++ 0x18, 0x3c, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x3c,
  1605 ++ 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x46, 0x0c, 0x18, 0x30,
  1606 ++ 0x62, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
  1607 ++ 0x3c, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02,
  1608 ++ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00,
  1609 ++ 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1610 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
  1611 ++ 0x00, 0x08, 0x10, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1612 ++ 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x60,
  1613 ++ 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1614 ++ 0x3c, 0x66, 0x60, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06,
  1615 ++ 0x3e, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
  1616 ++ 0x7e, 0x60, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0x78,
  1617 ++ 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x66, 0x66,
  1618 ++ 0x3e, 0x06, 0x3c, 0x00, 0x00, 0x60, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66,
  1619 ++ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x1c, 0x00,
  1620 ++ 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38,
  1621 ++ 0x00, 0x00, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x7c, 0x66, 0x00, 0x00, 0x00,
  1622 ++ 0x00, 0x60, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
  1623 ++ 0x00, 0x00, 0x76, 0x7f, 0x6b, 0x6b, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00,
  1624 ++ 0x00, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1625 ++ 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
  1626 ++ 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x66,
  1627 ++ 0x66, 0x66, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x72, 0x60,
  1628 ++ 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x60, 0x3c, 0x06,
  1629 ++ 0x3c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x78, 0x30, 0x30, 0x36, 0x1c,
  1630 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3a, 0x00,
  1631 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00,
  1632 ++ 0x00, 0x00, 0x00, 0x00, 0x63, 0x6b, 0x6b, 0x6b, 0x36, 0x00, 0x00, 0x00,
  1633 ++ 0x00, 0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00,
  1634 ++ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x3c, 0x00, 0x00, 0x00,
  1635 ++ 0x00, 0x7e, 0x0c, 0x18, 0x30, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18,
  1636 ++ 0x18, 0x30, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18,
  1637 ++ 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x30, 0x18, 0x18, 0x0c,
  1638 ++ 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0x00, 0x00, 0x00,
  1639 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x42, 0x00, 0x00, 0x00, 0x00,
  1640 ++ 0x00, 0x00, 0x00, 0x00};
  1641 +diff -ruN proll_18.orig/src/le.c proll-patch4/src/le.c
  1642 +--- proll_18.orig/src/le.c 2002-07-23 05:52:49.000000000 +0000
  1643 ++++ proll-patch4/src/le.c 2004-11-13 15:50:49.000000000 +0000
  1644 +@@ -185,8 +185,6 @@
  1645 + unsigned short rap; /* register address port */
  1646 + };
  1647 +
  1648 +-int sparc_lance_debug = 2;
  1649 +-
  1650 + /* The Lance uses 24 bit addresses */
  1651 + /* On the Sun4c the DVMA will provide the remaining bytes for us */
  1652 + /* On the Sun4m we have to instruct the ledma to provide them */
  1653 +diff -ruN proll_18.orig/src/netinit.c proll-patch4/src/netinit.c
  1654 +--- proll_18.orig/src/netinit.c 2002-09-13 21:53:33.000000000 +0000
  1655 ++++ proll-patch4/src/netinit.c 2004-11-13 15:50:49.000000000 +0000
  1656 +@@ -49,13 +49,20 @@
  1657 + unsigned char myhwaddr[ETH_ALEN]; /* my own hardware addr */
  1658 + t_ipaddr myipaddr; /* my own IP address */
  1659 + t_ipaddr mynetmask; /* my own netmask */
  1660 +- char *net_module_name; /* name of init module */
  1661 + t_ipaddr servaddr; /* IP of RARP&TFTP server */
  1662 +
  1663 + /* Broadcast hardware address */
  1664 +-unsigned char bcasthw[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  1665 ++const unsigned char bcasthw[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  1666 +
  1667 +
  1668 ++unsigned int seed;
  1669 ++
  1670 ++/* This is taken from x86 to be used in network kernel. Returns 15 bits. */
  1671 ++short int random()
  1672 ++{
  1673 ++ seed = (seed + 23968)*0x015A4E35 >> 1;
  1674 ++ return seed & 0x7FFF;
  1675 ++}
  1676 +
  1677 + /*
  1678 + **************************************************************************
  1679 +@@ -104,10 +111,17 @@
  1680 + */
  1681 + void init_net()
  1682 + {
  1683 ++ /* Avoid data segment allocations */
  1684 ++ seed = 151;
  1685 ++
  1686 + /* Initialize the different network layer modules */
  1687 + init_packet();
  1688 +- if (!init_arp() || !init_udp()) {
  1689 +- printf("\nERROR: init_%s\n", net_module_name);
  1690 ++ if (!init_arp()) {
  1691 ++ printf("\nERROR: init_arp\n");
  1692 ++ fatal();
  1693 ++ }
  1694 ++ if (!init_udp()) {
  1695 ++ printf("\nERROR: init_udp\n");
  1696 + fatal();
  1697 + }
  1698 + }
  1699 +diff -ruN proll_18.orig/src/netpriv.h proll-patch4/src/netpriv.h
  1700 +--- proll_18.orig/src/netpriv.h 1999-04-27 05:39:37.000000000 +0000
  1701 ++++ proll-patch4/src/netpriv.h 2004-11-13 15:50:49.000000000 +0000
  1702 +@@ -130,10 +130,9 @@
  1703 + *
  1704 + */
  1705 + extern unsigned char myhwaddr[ETH_ALEN]; /* my own hardware address */
  1706 +-extern unsigned char bcasthw[ETH_ALEN]; /* broadcast hardware addr */
  1707 ++extern const unsigned char bcasthw[ETH_ALEN]; /* broadcast hardware addr */
  1708 + extern t_ipaddr myipaddr; /* my own IP address */
  1709 + extern t_ipaddr mynetmask; /* netmask for my network */
  1710 +-extern char *net_module_name; /* initialized module's name */
  1711 + extern t_ipaddr servaddr; /* server IP address */
  1712 +
  1713 +
  1714 +@@ -150,7 +149,7 @@
  1715 + extern unsigned char *reg_type __P((int typeval, int (* receive)()));
  1716 +
  1717 + /* Write a packet to the network */
  1718 +-extern int write_packet __P((int bufsize, int typeval, unsigned char *addr));
  1719 ++extern int write_packet __P((int bufsize, int typeval, const unsigned char *addr));
  1720 +
  1721 + /* Empty read buffer */
  1722 + extern void empty_buf __P((void));
  1723 +diff -ruN proll_18.orig/src/openprom.h proll-patch4/src/openprom.h
  1724 +--- proll_18.orig/src/openprom.h 2002-07-14 02:26:30.000000000 +0000
  1725 ++++ proll-patch4/src/openprom.h 2004-11-13 15:50:49.000000000 +0000
  1726 +@@ -54,20 +54,20 @@
  1727 + };
  1728 +
  1729 + struct linux_mem_v0 {
  1730 +- struct linux_mlist_v0 **v0_totphys;
  1731 +- struct linux_mlist_v0 **v0_prommap;
  1732 +- struct linux_mlist_v0 **v0_available; /* What we can use */
  1733 ++ struct linux_mlist_v0 * const *v0_totphys;
  1734 ++ struct linux_mlist_v0 * const *v0_prommap;
  1735 ++ struct linux_mlist_v0 * const *v0_available; /* What we can use */
  1736 + };
  1737 +
  1738 + /* Arguments sent to the kernel from the boot prompt. */
  1739 + struct linux_arguments_v0 {
  1740 +- char *argv[8];
  1741 ++ const char *argv[8];
  1742 + char args[100];
  1743 + char boot_dev[2];
  1744 + int boot_dev_ctrl;
  1745 + int boot_dev_unit;
  1746 + int dev_partition;
  1747 +- char *kernel_file_name;
  1748 ++ const char *kernel_file_name;
  1749 + void *aieee1; /* XXX */
  1750 + };
17 1751
18 - romvec = init_openprom(bb.nbanks, bb.bankv, hiphybas); 1752 +@@ -91,13 +91,13 @@
  1753 + struct linux_mem_v0 pv_v0mem;
19 1754
20 - printk("Memory used: virt 0x%x:0x%x[%dK] iomap 0x%x:0x%x\n",  
21 - PROLBASE, (int)cmem.curp, ((unsigned) cmem.curp - PROLBASE)/1024,  
22 - (int)cio.start, (int)cio.curp); 1755 + /* Node operations. */
  1756 +- struct linux_nodeops *pv_nodeops;
  1757 ++ const struct linux_nodeops *pv_nodeops;
  1758 +
  1759 + char **pv_bootstr;
  1760 + struct linux_dev_v0_funcs pv_v0devops;
  1761 +
  1762 +- char *pv_stdin;
  1763 +- char *pv_stdout;
  1764 ++ const char *pv_stdin;
  1765 ++ const char *pv_stdout;
  1766 + #define PROMDEV_KBD 0 /* input from keyboard */
  1767 + #define PROMDEV_SCREEN 0 /* output to screen */
  1768 + #define PROMDEV_TTYA 1 /* in/out to ttya */
  1769 +@@ -127,7 +127,7 @@
  1770 + void (*v2_eval)(char *str);
  1771 + } pv_fortheval;
  1772 +
  1773 +- struct linux_arguments_v0 **pv_v0bootargs;
  1774 ++ const struct linux_arguments_v0 * const *pv_v0bootargs;
  1775 +
  1776 + /* Get ether address. */
  1777 + unsigned int (*pv_enaddr)(int d, char *enaddr);
  1778 +@@ -175,7 +175,7 @@
  1779 + int (*no_proplen)(int node, char *name);
  1780 + int (*no_getprop)(int node, char *name, char *val);
  1781 + int (*no_setprop)(int node, char *name, char *val, int len);
  1782 +- char * (*no_nextprop)(int node, char *name);
  1783 ++ const char * (*no_nextprop)(int node, char *name);
  1784 + };
  1785 +
  1786 + /* More fun PROM structures for device probing. */
  1787 +diff -ruN proll_18.orig/src/packet.c proll-patch4/src/packet.c
  1788 +--- proll_18.orig/src/packet.c 2000-02-11 04:56:45.000000000 +0000
  1789 ++++ proll-patch4/src/packet.c 2004-11-13 15:50:49.000000000 +0000
  1790 +@@ -41,7 +41,7 @@
  1791 + int aligner;
  1792 + } wbuf;
  1793 + static struct sk_buff *rskb;
  1794 +-static int nqskb = 0;
  1795 ++static int nqskb;
  1796 +
  1797 +
  1798 + void init_packet()
  1799 +@@ -62,6 +62,8 @@
  1800 + for (i = 0; i < MAXSKBS; i++) {
  1801 + skev[i].skb.allocn = i;
  1802 + }
  1803 ++
  1804 ++ nqskb = 0;
  1805 + }
  1806 +
  1807 + unsigned char *reg_type(int ptype, int (*func)())
  1808 +@@ -81,7 +83,7 @@
  1809 + return wbuf.s;
  1810 + }
  1811 +
  1812 +-int write_packet(int leng, int type, unsigned char *dst)
  1813 ++int write_packet(int leng, int type, const unsigned char *dst)
  1814 + {
  1815 + struct sk_buff *skb;
  1816 + unsigned char *s;
  1817 +diff -ruN proll_18.orig/src/printf.c proll-patch4/src/printf.c
  1818 +--- proll_18.orig/src/printf.c 1999-03-19 07:03:59.000000000 +0000
  1819 ++++ proll-patch4/src/printf.c 2004-11-13 15:50:49.000000000 +0000
  1820 +@@ -19,7 +19,7 @@
  1821 + static void printn(struct prf_fp *, unsigned long, unsigned int);
  1822 + static void putchar(char, struct prf_fp *);
  1823 +
  1824 +-static char hextab[] = "0123456789ABCDEF";
  1825 ++static const char hextab[] = "0123456789ABCDEF";
  1826 +
  1827 + /*
  1828 + * Scaled down version of C Library printf.
  1829 +@@ -41,7 +41,7 @@
  1830 + void
  1831 + prf(struct prf_fp *filog, char *fmt, va_list adx)
  1832 + {
  1833 +- register c;
  1834 ++ register int c;
  1835 + char *s;
  1836 +
  1837 + for(;;) {
  1838 +@@ -60,7 +60,7 @@
  1839 + putchar(va_arg(adx,unsigned), filog);
  1840 + } else if(c == 's') {
  1841 + s = va_arg(adx,char*);
  1842 +- while(c = *s++)
  1843 ++ while((c = *s++))
  1844 + putchar(c,filog);
  1845 + } else if (c == 'l' || c == 'O') {
  1846 + printn(filog, (long)va_arg(adx,long), c=='l'?10:8);
  1847 +diff -ruN proll_18.orig/src/rconsole.c proll-patch4/src/rconsole.c
  1848 +--- proll_18.orig/src/rconsole.c 1999-01-16 07:16:55.000000000 +0000
  1849 ++++ proll-patch4/src/rconsole.c 2004-11-13 15:50:49.000000000 +0000
  1850 +@@ -28,12 +28,18 @@
  1851 + * move to California. Only plain lat7 survived.
  1852 + * I recreated lat7-1 changes in lat7-2. --zaitcev
  1853 + */
23 +#ifdef ORIG 1854 +#ifdef ORIG
24 - set_timeout(5); while (!chk_timeout()) { } /* P3: let me read */ 1855 + #include "lat7_2.bm" /* lat7_1.bm */
25 +#else 1856 +#else
26 -+ printk("loading kernel:");  
27 -+ i = ld_bypass(0x20000000);  
28 -+ printk(" done, size %d\n", i); 1857 ++#include "lat7_2_swapped.bm" /* lat7_1.bm */
29 +#endif 1858 +#endif
  1859 + #define LAT7_NCHARS 128
  1860 + #define LAT7_HEIGHT 11
  1861 + #define LAT7_WIDTH 8
30 1862
31 - {  
32 - void (*entry)(void *, int) = (void (*)(void*, int)) LOADBASE;  
33 -diff -ru proll_18.orig/mrcoffee/openprom.c proll_18/mrcoffee/openprom.c  
34 ---- proll_18.orig/mrcoffee/openprom.c 2002-09-13 16:17:03.000000000 +0200  
35 -+++ proll_18/mrcoffee/openprom.c 2004-09-21 21:27:16.000000000 +0200  
36 -@@ -144,10 +144,14 @@  
37 - }; 1863 ++#ifdef ORIG
  1864 + static Rf_scan lat7_body[ LAT7_NCHARS*LAT7_HEIGHT ];
  1865 ++#endif
38 1866
39 - static int cpu_nctx = NCTX_SWIFT;  
40 -+static int cpu_cache_line_size = 0x20;  
41 -+static int cpu_cache_nlines = 0x200;  
42 - static struct property propv_cpu[] = {  
43 - {"name", "STP1012PGA", sizeof("STP1012PGA") },  
44 - {"device_type", "cpu", 4 },  
45 - {"mmu-nctx", (char*)&cpu_nctx, sizeof(int)},  
46 -+ {"cache-line-size", (char*)&cpu_cache_line_size, sizeof(int)},  
47 -+ {"cache-nlines", (char*)&cpu_cache_nlines, sizeof(int)},  
48 - {NULL, NULL, -1} 1867 + #if 1
  1868 + /*
  1869 +@@ -94,6 +100,7 @@
  1870 +
  1871 + #endif
  1872 +
  1873 ++#ifdef ORIG
  1874 + static inline int swapbits(int w0)
  1875 + {
  1876 + int w1 = 0;
  1877 +@@ -105,13 +112,16 @@
  1878 + }
  1879 + return w1;
  1880 + }
  1881 ++#endif
  1882 +
  1883 + void font_cons_7(struct rfont *p)
  1884 + {
  1885 ++#ifdef ORIG
  1886 + int x;
  1887 + int col = 0;
  1888 + int row = 0;
  1889 + int erow = 0;
  1890 ++
  1891 + for (x = 0; x < LAT7_NCHARS*LAT7_HEIGHT; x++ ) {
  1892 + lat7_body[ (erow * lat7_2_width/8 + col) * LAT7_HEIGHT + row ] =
  1893 + swapbits(lat7_2_bits[x]) & 0xFF;
  1894 +@@ -124,6 +134,9 @@
  1895 + }
  1896 + }
  1897 + p->body_ = lat7_body;
  1898 ++#else
  1899 ++ p->body_ = lat7_2_bits;
  1900 ++#endif
  1901 + p->nchars_ = LAT7_NCHARS;
  1902 + p->width_ = LAT7_WIDTH;
  1903 + p->height_ = LAT7_HEIGHT;
  1904 +diff -ruN proll_18.orig/src/rconsole.h proll-patch4/src/rconsole.h
  1905 +--- proll_18.orig/src/rconsole.h 1999-01-16 05:00:59.000000000 +0000
  1906 ++++ proll-patch4/src/rconsole.h 2004-11-13 15:50:49.000000000 +0000
  1907 +@@ -13,10 +13,10 @@
  1908 + */
  1909 +
  1910 + #define RF_MAXWIDTH 16
  1911 +-typedef unsigned short Rf_scan; /* __w16 to be used */
  1912 ++typedef unsigned char Rf_scan; /* __w16 to be used */
  1913 +
  1914 + struct rfont {
  1915 +- Rf_scan *body_;
  1916 ++ const Rf_scan *body_;
  1917 + int nchars_; /* 128 for ASCII ... 65536 for Unicode */
  1918 + int width_; /* [Pixels]. Maximum size is 16. */
  1919 + int height_; /* [Pixels == scan lines]. */
  1920 +diff -ruN proll_18.orig/src/romlib.h proll-patch4/src/romlib.h
  1921 +--- proll_18.orig/src/romlib.h 1999-04-20 04:26:45.000000000 +0000
  1922 ++++ proll-patch4/src/romlib.h 2004-11-13 15:50:49.000000000 +0000
  1923 +@@ -73,12 +73,12 @@
  1924 + #define memcpy(dst, src, len) bcopy(src, dst, len)
  1925 + #define memcmp(x1, x2, len) bcmp(x1, x2, len)
  1926 + #define memset(p, len, zero) bzero(p, len)
  1927 +-extern void bcopy(void *b1, void *b2, int length);
  1928 +-extern int bcmp(void *b1, void *b2, int length);
  1929 ++extern void bcopy(const void *b1, void *b2, int length);
  1930 ++extern int bcmp(const void *b1, const void *b2, int length);
  1931 + extern void bzero(void *b, int c);
  1932 + /* gcc complains about "conflicting types for builtin function strlen". */
  1933 + #define strlen(s) ssize(s)
  1934 +-extern int ssize(char *s);
  1935 ++extern int ssize(const char *s);
  1936 +
  1937 +
  1938 + /*
  1939 +diff -ruN proll_18.orig/src/sched_4m.c proll-patch4/src/sched_4m.c
  1940 +--- proll_18.orig/src/sched_4m.c 1999-04-27 05:48:51.000000000 +0000
  1941 ++++ proll-patch4/src/sched_4m.c 2004-11-13 15:50:49.000000000 +0000
  1942 +@@ -108,7 +108,7 @@
  1943 + static int set_bolt; /* Tick counter limit */
  1944 + static struct handsc hndv[16];
  1945 +
  1946 +-static unsigned int intr_to_mask[16] = {
  1947 ++static unsigned const int intr_to_mask[16] = {
  1948 + 0, 0, 0, 0, 0, 0, SUN4M_INT_ETHERNET, 0,
  1949 + 0, 0, 0, 0, 0, 0, 0, 0,
49 }; 1950 };
  1951 +diff -ruN proll_18.orig/src/swap.c proll-patch4/src/swap.c
  1952 +--- proll_18.orig/src/swap.c 1970-01-01 00:00:00.000000000 +0000
  1953 ++++ proll-patch4/src/swap.c 2004-11-13 15:50:49.000000000 +0000
  1954 +@@ -0,0 +1,21 @@
  1955 ++// Convert the lat7 font so that no conversion is needed at runtime.
  1956 ++#define ORIG
  1957 ++#include "rconsole.c"
  1958 ++
  1959 ++#include <stdio.h>
  1960 ++
  1961 ++int main()
  1962 ++{
  1963 ++ struct rfont p;
  1964 ++ int i;
  1965 ++
  1966 ++ font_cons_7(&p);
  1967 ++
  1968 ++ printf(" ");
  1969 ++ for (i = 0; i < LAT7_NCHARS*LAT7_HEIGHT; i++) {
  1970 ++ printf("0x%02x, ", p.body_[i]);
  1971 ++ if ((i % 12) == 11)
  1972 ++ printf("\n ");
  1973 ++ }
  1974 ++ printf("\n");
  1975 ++}
  1976 +diff -ruN proll_18.orig/src/system.c proll-patch4/src/system.c
  1977 +--- proll_18.orig/src/system.c 2002-07-23 05:52:49.000000000 +0000
  1978 ++++ proll-patch4/src/system.c 2004-11-13 15:50:49.000000000 +0000
  1979 +@@ -298,8 +298,8 @@
  1980 + }
  1981 +
  1982 + /* We need to start from LOADBASE, but kernel wants PAGE_SIZE. */
  1983 +- pa = PAGE_SIZE;
  1984 +- for (va = PAGE_SIZE; va < LOWMEMSZ; va += PAGE_SIZE) {
  1985 ++ pa = 0;
  1986 ++ for (va = 0; va < LOWMEMSZ; va += PAGE_SIZE) {
  1987 + map_page(l1, va, pa, 0, highbase);
  1988 + pa += PAGE_SIZE;
  1989 + }
  1990 +@@ -518,12 +518,12 @@
  1991 + while (len--) *((char *)s)++ = 0;
  1992 + }
  1993 +
  1994 +-void bcopy(void *f, void *t, int len) {
  1995 ++void bcopy(const void *f, void *t, int len) {
  1996 + while (len--) *((char *)t)++ = *((char *)f)++;
  1997 + }
  1998 +
  1999 + /* Comparison is 7-bit */
  2000 +-int bcmp(void *s1, void *s2, int len)
  2001 ++int bcmp(const void *s1, const void *s2, int len)
  2002 + {
  2003 + int i;
  2004 + char ch;
  2005 +@@ -538,8 +538,8 @@
  2006 + return 0;
  2007 + }
  2008 +
  2009 +-int strlen(char *s) {
  2010 +- char *p;
  2011 ++int strlen(const char *s) {
  2012 ++ const char *p;
  2013 + for (p = s; *p != 0; p++) { }
  2014 + return p - s;
  2015 + }
  2016 +@@ -560,14 +560,6 @@
  2017 + va_end(x1);
  2018 + }
  2019 +
  2020 +-/* This is taken from x86 to be used in network kernel. Returns 15 bits. */
  2021 +-short int random()
  2022 +-{
  2023 +- static unsigned int seed = 151;
  2024 +- seed = (seed + 23968)*0x015A4E35 >> 1;
  2025 +- return seed & 0x7FFF;
  2026 +-}
  2027 +-
  2028 + void fatal()
  2029 + {
  2030 + printk("fatal.");
  2031 +diff -ruN proll_18.orig/src/system.h proll-patch4/src/system.h
  2032 +--- proll_18.orig/src/system.h 2002-09-13 21:53:32.000000000 +0000
  2033 ++++ proll-patch4/src/system.h 2004-11-13 15:50:49.000000000 +0000
  2034 +@@ -16,7 +16,7 @@
  2035 + #define IOMAPSIZE (1*1024*1024) /* 1 Meg maximum: we do not map framebuffer. */
  2036 + #define NCTX_SWIFT 0x100
  2037 +
  2038 +-#define MAX_BANKS 3 /* Allocation for all machines */
  2039 ++#define MAX_BANKS 8 /* Allocation for all machines */
  2040 +
  2041 + #ifndef __ASSEMBLY__
  2042 + struct bank {
  2043 +diff -ruN proll_18.orig/src/udp.c proll-patch4/src/udp.c
  2044 +--- proll_18.orig/src/udp.c 2001-12-24 05:12:53.000000000 +0000
  2045 ++++ proll-patch4/src/udp.c 2004-11-13 15:50:49.000000000 +0000
  2046 +@@ -81,7 +81,7 @@
  2047 + int source;
  2048 + int dest;
  2049 + {
  2050 +- register unsigned char *addr;
  2051 ++ const register unsigned char *addr;
50 2052
  2053 + /* Set global variables */
  2054 + usource = source;
  2055 +@@ -299,9 +299,6 @@
  2056 + */
  2057 + int init_udp()
  2058 + {
  2059 +- /* Set module name for error handling */
  2060 +- net_module_name = "udp";
  2061 +-
  2062 + /* Register IP packet type and set write buffer pointer */
  2063 + if ((writebuf = reg_type(htons(ETH_P_IP), ip_recv)) == NULL)
  2064 + return(FALSE);
qemu-doc.texi
@@ -1099,6 +1099,29 @@ Set the initial VGA graphic mode. The default is 800x600x15. @@ -1099,6 +1099,29 @@ Set the initial VGA graphic mode. The default is 800x600x15.
1099 More information is available at 1099 More information is available at
1100 @url{http://jocelyn.mayer.free.fr/qemu-ppc/}. 1100 @url{http://jocelyn.mayer.free.fr/qemu-ppc/}.
1101 1101
  1102 +@chapter Sparc System emulator invocation
  1103 +
  1104 +Use the executable @file{qemu-system-sparc} to simulate a JavaStation
  1105 +(sun4m architecture). The emulation is far from complete.
  1106 +
  1107 +QEMU emulates the following sun4m peripherials:
  1108 +
  1109 +@itemize @minus
  1110 +@item
  1111 +IOMMU
  1112 +@item
  1113 +TCX Frame buffer
  1114 +@item
  1115 +Lance (Am7990) Ethernet
  1116 +@item
  1117 +Non Volatile RAM M48T08
  1118 +@item
  1119 +Slave I/O: timers, interrupt controllers, Zilog serial ports
  1120 +@end itemize
  1121 +
  1122 +QEMU uses the Proll, a PROM replacement available at
  1123 +@url{http://people.redhat.com/zaitcev/linux/}.
  1124 +
1102 @chapter QEMU User space emulator invocation 1125 @chapter QEMU User space emulator invocation
1103 1126
1104 @section Quick Start 1127 @section Quick Start
qemu-tech.texi
@@ -126,7 +126,7 @@ maximum performances. @@ -126,7 +126,7 @@ maximum performances.
126 126
127 @itemize 127 @itemize
128 128
129 -@item Full PowerPC 32 bit emulation, including priviledged instructions, 129 +@item Full PowerPC 32 bit emulation, including privileged instructions,
130 FPU and MMU. 130 FPU and MMU.
131 131
132 @item Can run most PowerPC Linux binaries. 132 @item Can run most PowerPC Linux binaries.
@@ -137,7 +137,8 @@ FPU and MMU. @@ -137,7 +137,8 @@ FPU and MMU.
137 137
138 @itemize 138 @itemize
139 139
140 -@item SPARC V8 user support, except FPU instructions. 140 +@item Somewhat complete SPARC V8 emulation, including privileged
  141 +instructions, FPU and MMU.
141 142
142 @item Can run some SPARC Linux binaries. 143 @item Can run some SPARC Linux binaries.
143 144
target-sparc/cpu.h
@@ -10,23 +10,42 @@ @@ -10,23 +10,42 @@
10 /* trap definitions */ 10 /* trap definitions */
11 #define TT_ILL_INSN 0x02 11 #define TT_ILL_INSN 0x02
12 #define TT_PRIV_INSN 0x03 12 #define TT_PRIV_INSN 0x03
  13 +#define TT_NFPU_INSN 0x04
13 #define TT_WIN_OVF 0x05 14 #define TT_WIN_OVF 0x05
14 #define TT_WIN_UNF 0x06 15 #define TT_WIN_UNF 0x06
15 #define TT_FP_EXCP 0x08 16 #define TT_FP_EXCP 0x08
16 #define TT_DIV_ZERO 0x2a 17 #define TT_DIV_ZERO 0x2a
17 #define TT_TRAP 0x80 18 #define TT_TRAP 0x80
  19 +#define TT_EXTINT 0x10
18 20
19 #define PSR_NEG (1<<23) 21 #define PSR_NEG (1<<23)
20 #define PSR_ZERO (1<<22) 22 #define PSR_ZERO (1<<22)
21 #define PSR_OVF (1<<21) 23 #define PSR_OVF (1<<21)
22 #define PSR_CARRY (1<<20) 24 #define PSR_CARRY (1<<20)
23 #define PSR_ICC (PSR_NEG|PSR_ZERO|PSR_OVF|PSR_CARRY) 25 #define PSR_ICC (PSR_NEG|PSR_ZERO|PSR_OVF|PSR_CARRY)
  26 +#define PSR_EF (1<<12)
  27 +#define PSR_PIL 0xf00
24 #define PSR_S (1<<7) 28 #define PSR_S (1<<7)
25 #define PSR_PS (1<<6) 29 #define PSR_PS (1<<6)
26 #define PSR_ET (1<<5) 30 #define PSR_ET (1<<5)
27 #define PSR_CWP 0x1f 31 #define PSR_CWP 0x1f
28 /* Fake impl 0, version 4 */ 32 /* Fake impl 0, version 4 */
29 -#define GET_PSR(env) ((0<<28) | (4<<24) | env->psr | (env->psrs? PSR_S : 0) | (env->psrs? PSR_PS : 0) |(env->psret? PSR_ET : 0) | env->cwp) 33 +#define GET_PSR(env) ((0 << 28) | (4 << 24) | env->psr | \
  34 + (env->psref? PSR_EF : 0) | \
  35 + (env->psrpil << 8) | \
  36 + (env->psrs? PSR_S : 0) | \
  37 + (env->psrs? PSR_PS : 0) | \
  38 + (env->psret? PSR_ET : 0) | env->cwp)
  39 +
  40 +#define PUT_PSR(env, val) do { int _tmp = val; \
  41 + env->psr = _tmp & ~PSR_ICC; \
  42 + env->psref = (_tmp & PSR_EF)? 1 : 0; \
  43 + env->psrpil = (_tmp & PSR_PIL) >> 8; \
  44 + env->psrs = (_tmp & PSR_S)? 1 : 0; \
  45 + env->psrps = (_tmp & PSR_PS)? 1 : 0; \
  46 + env->psret = (_tmp & PSR_ET)? 1 : 0; \
  47 + set_cwp(_tmp & PSR_CWP & (NWINDOWS - 1)); \
  48 + } while (0)
30 49
31 /* Trap base register */ 50 /* Trap base register */
32 #define TBR_BASE_MASK 0xfffff000 51 #define TBR_BASE_MASK 0xfffff000
@@ -65,6 +84,9 @@ @@ -65,6 +84,9 @@
65 #define FSR_FTT1 (1<<15) 84 #define FSR_FTT1 (1<<15)
66 #define FSR_FTT0 (1<<14) 85 #define FSR_FTT0 (1<<14)
67 #define FSR_FTT_MASK (FSR_FTT2 | FSR_FTT1 | FSR_FTT0) 86 #define FSR_FTT_MASK (FSR_FTT2 | FSR_FTT1 | FSR_FTT0)
  87 +#define FSR_FTT_IEEE_EXCP (1 << 14)
  88 +#define FSR_FTT_UNIMPFPOP (3 << 14)
  89 +#define FSR_FTT_INVAL_FPR (6 << 14)
68 90
69 #define FSR_FCC1 (1<<11) 91 #define FSR_FCC1 (1<<11)
70 #define FSR_FCC0 (1<<10) 92 #define FSR_FCC0 (1<<10)
@@ -106,6 +128,8 @@ typedef struct CPUSPARCState { @@ -106,6 +128,8 @@ typedef struct CPUSPARCState {
106 int psrs; /* supervisor mode (extracted from PSR) */ 128 int psrs; /* supervisor mode (extracted from PSR) */
107 int psrps; /* previous supervisor mode */ 129 int psrps; /* previous supervisor mode */
108 int psret; /* enable traps */ 130 int psret; /* enable traps */
  131 + int psrpil; /* interrupt level */
  132 + int psref; /* enable fpu */
109 jmp_buf jmp_env; 133 jmp_buf jmp_env;
110 int user_mode_only; 134 int user_mode_only;
111 int exception_index; 135 int exception_index;
@@ -144,6 +168,8 @@ typedef struct CPUSPARCState { @@ -144,6 +168,8 @@ typedef struct CPUSPARCState {
144 CPUSPARCState *cpu_sparc_init(void); 168 CPUSPARCState *cpu_sparc_init(void);
145 int cpu_sparc_exec(CPUSPARCState *s); 169 int cpu_sparc_exec(CPUSPARCState *s);
146 int cpu_sparc_close(CPUSPARCState *s); 170 int cpu_sparc_close(CPUSPARCState *s);
  171 +void cpu_get_fp64(uint64_t *pmant, uint16_t *pexp, double f);
  172 +double cpu_put_fp64(uint64_t mant, uint16_t exp);
147 173
148 struct siginfo; 174 struct siginfo;
149 int cpu_sparc_signal_handler(int hostsignum, struct siginfo *info, void *puc); 175 int cpu_sparc_signal_handler(int hostsignum, struct siginfo *info, void *puc);
target-sparc/exec.h
@@ -40,6 +40,9 @@ void do_interrupt(int intno, int is_int, int error_code, @@ -40,6 +40,9 @@ void do_interrupt(int intno, int is_int, int error_code,
40 void raise_exception_err(int exception_index, int error_code); 40 void raise_exception_err(int exception_index, int error_code);
41 void raise_exception(int tt); 41 void raise_exception(int tt);
42 void memcpy32(uint32_t *dst, const uint32_t *src); 42 void memcpy32(uint32_t *dst, const uint32_t *src);
  43 +uint32_t mmu_probe(uint32_t address, int mmulev);
  44 +void dump_mmu(void);
  45 +void helper_debug();
43 46
44 /* XXX: move that to a generic header */ 47 /* XXX: move that to a generic header */
45 #if !defined(CONFIG_USER_ONLY) 48 #if !defined(CONFIG_USER_ONLY)
target-sparc/fop_template.h
@@ -51,18 +51,6 @@ void OPPROTO glue(op_store_FT2_fpr_fpr, REGNAME)(void) @@ -51,18 +51,6 @@ void OPPROTO glue(op_store_FT2_fpr_fpr, REGNAME)(void)
51 } 51 }
52 52
53 /* double floating point registers moves */ 53 /* double floating point registers moves */
54 -#if 0  
55 -#define CPU_DOUBLE_U_DEF  
56 -typedef union {  
57 - double d;  
58 - struct {  
59 - uint32_t lower;  
60 - uint32_t upper;  
61 - } l;  
62 - uint64_t ll;  
63 -} CPU_DoubleU;  
64 -#endif /* CPU_DOUBLE_U_DEF */  
65 -  
66 void OPPROTO glue(op_load_fpr_DT0_fpr, REGNAME)(void) 54 void OPPROTO glue(op_load_fpr_DT0_fpr, REGNAME)(void)
67 { 55 {
68 CPU_DoubleU u; 56 CPU_DoubleU u;
target-sparc/helper.c
@@ -19,7 +19,8 @@ @@ -19,7 +19,8 @@
19 */ 19 */
20 #include "exec.h" 20 #include "exec.h"
21 21
22 -#define DEBUG_PCALL 22 +//#define DEBUG_PCALL
  23 +//#define DEBUG_MMU
23 24
24 /* Sparc MMU emulation */ 25 /* Sparc MMU emulation */
25 int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, 26 int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
@@ -108,80 +109,71 @@ static const int rw_table[2][8] = { @@ -108,80 +109,71 @@ static const int rw_table[2][8] = {
108 { 0, 1, 0, 1, 0, 0, 0, 0 } 109 { 0, 1, 0, 1, 0, 0, 0, 0 }
109 }; 110 };
110 111
111 -  
112 -/* Perform address translation */  
113 -int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,  
114 - int is_user, int is_softmmu) 112 +int get_physical_address (CPUState *env, uint32_t *physical, int *prot,
  113 + int *access_index, uint32_t address, int rw,
  114 + int is_user)
115 { 115 {
116 - int exception = 0;  
117 - int access_perms = 0, access_index = 0;  
118 - uint8_t *pde_ptr; 116 + int access_perms = 0;
  117 + target_phys_addr_t pde_ptr;
119 uint32_t pde, virt_addr; 118 uint32_t pde, virt_addr;
120 - int error_code = 0, is_dirty, prot, ret = 0;  
121 - unsigned long paddr, vaddr, page_offset;  
122 -  
123 - if (env->user_mode_only) {  
124 - /* user mode only emulation */  
125 - ret = -2;  
126 - goto do_fault;  
127 - } 119 + int error_code = 0, is_dirty;
  120 + unsigned long page_offset;
128 121
129 virt_addr = address & TARGET_PAGE_MASK; 122 virt_addr = address & TARGET_PAGE_MASK;
130 if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */ 123 if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
131 - paddr = address;  
132 - page_offset = address & (TARGET_PAGE_SIZE - 1);  
133 - prot = PAGE_READ | PAGE_WRITE;  
134 - goto do_mapping; 124 + *physical = address;
  125 + *prot = PAGE_READ | PAGE_WRITE;
  126 + return 0;
135 } 127 }
136 128
137 /* SPARC reference MMU table walk: Context table->L1->L2->PTE */ 129 /* SPARC reference MMU table walk: Context table->L1->L2->PTE */
138 /* Context base + context number */ 130 /* Context base + context number */
139 - pde_ptr = phys_ram_base + (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4);  
140 - pde = ldl_raw(pde_ptr); 131 + pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4);
  132 + cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
  133 + bswap32s(&pde);
141 134
142 /* Ctx pde */ 135 /* Ctx pde */
143 switch (pde & PTE_ENTRYTYPE_MASK) { 136 switch (pde & PTE_ENTRYTYPE_MASK) {
  137 + default:
144 case 0: /* Invalid */ 138 case 0: /* Invalid */
145 - error_code = 1;  
146 - goto do_fault;  
147 - case 2: /* PTE, maybe should not happen? */ 139 + return 1;
  140 + case 2: /* L0 PTE, maybe should not happen? */
148 case 3: /* Reserved */ 141 case 3: /* Reserved */
149 - error_code = 4;  
150 - goto do_fault;  
151 - case 1: /* L1 PDE */  
152 - pde_ptr = phys_ram_base + ((address >> 22) & ~3) + ((pde & ~3) << 4);  
153 - pde = ldl_raw(pde_ptr); 142 + return 4;
  143 + case 1: /* L0 PDE */
  144 + pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
  145 + cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
  146 + bswap32s(&pde);
154 147
155 switch (pde & PTE_ENTRYTYPE_MASK) { 148 switch (pde & PTE_ENTRYTYPE_MASK) {
  149 + default:
156 case 0: /* Invalid */ 150 case 0: /* Invalid */
157 - error_code = 1;  
158 - goto do_fault; 151 + return 1;
159 case 3: /* Reserved */ 152 case 3: /* Reserved */
160 - error_code = 4;  
161 - goto do_fault;  
162 - case 1: /* L2 PDE */  
163 - pde_ptr = phys_ram_base + ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);  
164 - pde = ldl_raw(pde_ptr); 153 + return 4;
  154 + case 1: /* L1 PDE */
  155 + pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
  156 + cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
  157 + bswap32s(&pde);
165 158
166 switch (pde & PTE_ENTRYTYPE_MASK) { 159 switch (pde & PTE_ENTRYTYPE_MASK) {
  160 + default:
167 case 0: /* Invalid */ 161 case 0: /* Invalid */
168 - error_code = 1;  
169 - goto do_fault; 162 + return 1;
170 case 3: /* Reserved */ 163 case 3: /* Reserved */
171 - error_code = 4;  
172 - goto do_fault;  
173 - case 1: /* L3 PDE */  
174 - pde_ptr = phys_ram_base + ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);  
175 - pde = ldl_raw(pde_ptr); 164 + return 4;
  165 + case 1: /* L2 PDE */
  166 + pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
  167 + cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
  168 + bswap32s(&pde);
176 169
177 switch (pde & PTE_ENTRYTYPE_MASK) { 170 switch (pde & PTE_ENTRYTYPE_MASK) {
  171 + default:
178 case 0: /* Invalid */ 172 case 0: /* Invalid */
179 - error_code = 1;  
180 - goto do_fault; 173 + return 1;
181 case 1: /* PDE, should not happen */ 174 case 1: /* PDE, should not happen */
182 case 3: /* Reserved */ 175 case 3: /* Reserved */
183 - error_code = 4;  
184 - goto do_fault; 176 + return 4;
185 case 2: /* L3 PTE */ 177 case 2: /* L3 PTE */
186 virt_addr = address & TARGET_PAGE_MASK; 178 virt_addr = address & TARGET_PAGE_MASK;
187 page_offset = (address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1); 179 page_offset = (address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1);
@@ -201,40 +193,58 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -201,40 +193,58 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
201 /* update page modified and dirty bits */ 193 /* update page modified and dirty bits */
202 is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK); 194 is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
203 if (!(pde & PG_ACCESSED_MASK) || is_dirty) { 195 if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
  196 + uint32_t tmppde;
204 pde |= PG_ACCESSED_MASK; 197 pde |= PG_ACCESSED_MASK;
205 if (is_dirty) 198 if (is_dirty)
206 pde |= PG_MODIFIED_MASK; 199 pde |= PG_MODIFIED_MASK;
207 - stl_raw(pde_ptr, pde); 200 + tmppde = bswap32(pde);
  201 + cpu_physical_memory_write(pde_ptr, (uint8_t *)&tmppde, 4);
208 } 202 }
209 -  
210 /* check access */ 203 /* check access */
211 - access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1); 204 + *access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1);
212 access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT; 205 access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
213 - error_code = access_table[access_index][access_perms]; 206 + error_code = access_table[*access_index][access_perms];
214 if (error_code) 207 if (error_code)
215 - goto do_fault; 208 + return error_code;
216 209
217 /* the page can be put in the TLB */ 210 /* the page can be put in the TLB */
218 - prot = PAGE_READ; 211 + *prot = PAGE_READ;
219 if (pde & PG_MODIFIED_MASK) { 212 if (pde & PG_MODIFIED_MASK) {
220 /* only set write access if already dirty... otherwise wait 213 /* only set write access if already dirty... otherwise wait
221 for dirty access */ 214 for dirty access */
222 if (rw_table[is_user][access_perms]) 215 if (rw_table[is_user][access_perms])
223 - prot |= PAGE_WRITE; 216 + *prot |= PAGE_WRITE;
224 } 217 }
225 218
226 /* Even if large ptes, we map only one 4KB page in the cache to 219 /* Even if large ptes, we map only one 4KB page in the cache to
227 avoid filling it too fast */ 220 avoid filling it too fast */
228 - virt_addr = address & TARGET_PAGE_MASK;  
229 - paddr = ((pde & PTE_ADDR_MASK) << 4) + page_offset; 221 + *physical = ((pde & PTE_ADDR_MASK) << 4) + page_offset;
  222 + return 0;
  223 +}
  224 +
  225 +/* Perform address translation */
  226 +int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
  227 + int is_user, int is_softmmu)
  228 +{
  229 + int exception = 0;
  230 + uint32_t virt_addr, paddr;
  231 + unsigned long vaddr;
  232 + int error_code = 0, prot, ret = 0, access_index;
230 233
231 - do_mapping:  
232 - vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1)); 234 + if (env->user_mode_only) {
  235 + /* user mode only emulation */
  236 + error_code = -2;
  237 + goto do_fault_user;
  238 + }
233 239
234 - ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);  
235 - return ret; 240 + error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
  241 + if (error_code == 0) {
  242 + virt_addr = address & TARGET_PAGE_MASK;
  243 + vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
  244 + ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);
  245 + return ret;
  246 + }
236 247
237 - do_fault:  
238 if (env->mmuregs[3]) /* Fault status register */ 248 if (env->mmuregs[3]) /* Fault status register */
239 env->mmuregs[3] = 1; /* overflow (not read before another fault) */ 249 env->mmuregs[3] = 1; /* overflow (not read before another fault) */
240 env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2; 250 env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2;
@@ -242,7 +252,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -242,7 +252,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
242 252
243 if (env->mmuregs[0] & MMU_NF || env->psret == 0) // No fault 253 if (env->mmuregs[0] & MMU_NF || env->psret == 0) // No fault
244 return 0; 254 return 0;
245 - 255 + do_fault_user:
246 env->exception_index = exception; 256 env->exception_index = exception;
247 env->error_code = error_code; 257 env->error_code = error_code;
248 return error_code; 258 return error_code;
@@ -289,13 +299,14 @@ void do_interrupt(int intno, int is_int, int error_code, @@ -289,13 +299,14 @@ void do_interrupt(int intno, int is_int, int error_code,
289 count, intno, error_code, is_int, 299 count, intno, error_code, is_int,
290 env->pc, 300 env->pc,
291 env->npc, env->regwptr[6]); 301 env->npc, env->regwptr[6]);
292 -#if 0 302 +#if 1
293 cpu_dump_state(env, logfile, fprintf, 0); 303 cpu_dump_state(env, logfile, fprintf, 0);
294 { 304 {
295 int i; 305 int i;
296 uint8_t *ptr; 306 uint8_t *ptr;
  307 +
297 fprintf(logfile, " code="); 308 fprintf(logfile, " code=");
298 - ptr = env->pc; 309 + ptr = (uint8_t *)env->pc;
299 for(i = 0; i < 16; i++) { 310 for(i = 0; i < 16; i++) {
300 fprintf(logfile, " %02x", ldub(ptr + i)); 311 fprintf(logfile, " %02x", ldub(ptr + i));
301 } 312 }
@@ -305,11 +316,18 @@ void do_interrupt(int intno, int is_int, int error_code, @@ -305,11 +316,18 @@ void do_interrupt(int intno, int is_int, int error_code,
305 count++; 316 count++;
306 } 317 }
307 #endif 318 #endif
  319 +#if !defined(CONFIG_USER_ONLY)
  320 + if (env->psret == 0) {
  321 + fprintf(logfile, "Trap while interrupts disabled, Error state!\n");
  322 + qemu_system_shutdown_request();
  323 + return;
  324 + }
  325 +#endif
308 env->psret = 0; 326 env->psret = 0;
309 cwp = (env->cwp - 1) & (NWINDOWS - 1); 327 cwp = (env->cwp - 1) & (NWINDOWS - 1);
310 set_cwp(cwp); 328 set_cwp(cwp);
311 - env->regwptr[9] = env->pc;  
312 - env->regwptr[10] = env->npc; 329 + env->regwptr[9] = env->pc - 4; // XXX?
  330 + env->regwptr[10] = env->pc;
313 env->psrps = env->psrs; 331 env->psrps = env->psrs;
314 env->psrs = 1; 332 env->psrs = 1;
315 env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4); 333 env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
@@ -322,3 +340,106 @@ void raise_exception_err(int exception_index, int error_code) @@ -322,3 +340,106 @@ void raise_exception_err(int exception_index, int error_code)
322 { 340 {
323 raise_exception(exception_index); 341 raise_exception(exception_index);
324 } 342 }
  343 +
  344 +uint32_t mmu_probe(uint32_t address, int mmulev)
  345 +{
  346 + target_phys_addr_t pde_ptr;
  347 + uint32_t pde;
  348 +
  349 + /* Context base + context number */
  350 + pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4);
  351 + cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
  352 + bswap32s(&pde);
  353 + switch (pde & PTE_ENTRYTYPE_MASK) {
  354 + default:
  355 + case 0: /* Invalid */
  356 + case 2: /* PTE, maybe should not happen? */
  357 + case 3: /* Reserved */
  358 + return 0;
  359 + case 1: /* L1 PDE */
  360 + if (mmulev == 3)
  361 + return pde;
  362 + pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
  363 + cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
  364 + bswap32s(&pde);
  365 +
  366 + switch (pde & PTE_ENTRYTYPE_MASK) {
  367 + default:
  368 + case 0: /* Invalid */
  369 + case 3: /* Reserved */
  370 + return 0;
  371 + case 2: /* L1 PTE */
  372 + return pde;
  373 + case 1: /* L2 PDE */
  374 + if (mmulev == 2)
  375 + return pde;
  376 + pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
  377 + cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
  378 + bswap32s(&pde);
  379 +
  380 + switch (pde & PTE_ENTRYTYPE_MASK) {
  381 + default:
  382 + case 0: /* Invalid */
  383 + case 3: /* Reserved */
  384 + return 0;
  385 + case 2: /* L2 PTE */
  386 + return pde;
  387 + case 1: /* L3 PDE */
  388 + if (mmulev == 1)
  389 + return pde;
  390 + pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
  391 + cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
  392 + bswap32s(&pde);
  393 +
  394 + switch (pde & PTE_ENTRYTYPE_MASK) {
  395 + default:
  396 + case 0: /* Invalid */
  397 + case 1: /* PDE, should not happen */
  398 + case 3: /* Reserved */
  399 + return 0;
  400 + case 2: /* L3 PTE */
  401 + return pde;
  402 + }
  403 + }
  404 + }
  405 + }
  406 + return 0;
  407 +}
  408 +
  409 +void dump_mmu(void)
  410 +{
  411 +#ifdef DEBUG_MMU
  412 + uint32_t pa, va, va1, va2;
  413 + int n, m, o;
  414 + target_phys_addr_t pde_ptr;
  415 + uint32_t pde;
  416 +
  417 + printf("MMU dump:\n");
  418 + pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4);
  419 + cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
  420 + bswap32s(&pde);
  421 + printf("Root ptr: 0x%08x, ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]);
  422 + for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
  423 + pde_ptr = mmu_probe(va, 2);
  424 + if (pde_ptr) {
  425 + pa = cpu_get_phys_page_debug(env, va);
  426 + printf("VA: 0x%08x, PA: 0x%08x PDE: 0x%08x\n", va, pa, pde_ptr);
  427 + for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
  428 + pde_ptr = mmu_probe(va1, 1);
  429 + if (pde_ptr) {
  430 + pa = cpu_get_phys_page_debug(env, va1);
  431 + printf(" VA: 0x%08x, PA: 0x%08x PDE: 0x%08x\n", va1, pa, pde_ptr);
  432 + for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
  433 + pde_ptr = mmu_probe(va2, 0);
  434 + if (pde_ptr) {
  435 + pa = cpu_get_phys_page_debug(env, va2);
  436 + printf(" VA: 0x%08x, PA: 0x%08x PTE: 0x%08x\n", va2, pa, pde_ptr);
  437 + }
  438 + }
  439 + }
  440 + }
  441 + }
  442 + }
  443 + printf("MMU dump ends\n");
  444 +#endif
  445 +}
target-sparc/op.c
@@ -524,13 +524,7 @@ void OPPROTO op_rdpsr(void) @@ -524,13 +524,7 @@ void OPPROTO op_rdpsr(void)
524 524
525 void OPPROTO op_wrpsr(void) 525 void OPPROTO op_wrpsr(void)
526 { 526 {
527 - int cwp;  
528 - env->psr = T0 & ~PSR_ICC;  
529 - env->psrs = (T0 & PSR_S)? 1 : 0;  
530 - env->psrps = (T0 & PSR_PS)? 1 : 0;  
531 - env->psret = (T0 & PSR_ET)? 1 : 0;  
532 - cwp = (T0 & PSR_CWP) & (NWINDOWS - 1);  
533 - set_cwp(cwp); 527 + PUT_PSR(env,T0);
534 FORCE_RET(); 528 FORCE_RET();
535 } 529 }
536 530
@@ -602,10 +596,27 @@ void OPPROTO op_trapcc_T0(void) @@ -602,10 +596,27 @@ void OPPROTO op_trapcc_T0(void)
602 FORCE_RET(); 596 FORCE_RET();
603 } 597 }
604 598
605 -void OPPROTO op_debug(void) 599 +void OPPROTO op_trap_ifnofpu(void)
  600 +{
  601 + if (!env->psref) {
  602 + env->exception_index = TT_NFPU_INSN;
  603 + cpu_loop_exit();
  604 + }
  605 + FORCE_RET();
  606 +}
  607 +
  608 +void OPPROTO op_fpexception_im(void)
606 { 609 {
607 - env->exception_index = EXCP_DEBUG; 610 + env->exception_index = TT_FP_EXCP;
  611 + env->fsr &= ~FSR_FTT_MASK;
  612 + env->fsr |= PARAM1;
608 cpu_loop_exit(); 613 cpu_loop_exit();
  614 + FORCE_RET();
  615 +}
  616 +
  617 +void OPPROTO op_debug(void)
  618 +{
  619 + helper_debug();
609 } 620 }
610 621
611 void OPPROTO op_exit_tb(void) 622 void OPPROTO op_exit_tb(void)
target-sparc/op_helper.c
@@ -2,6 +2,8 @@ @@ -2,6 +2,8 @@
2 #include <fenv.h> 2 #include <fenv.h>
3 #include "exec.h" 3 #include "exec.h"
4 4
  5 +//#define DEBUG_MMU
  6 +
5 #ifdef USE_INT_TO_FLOAT_HELPERS 7 #ifdef USE_INT_TO_FLOAT_HELPERS
6 void do_fitos(void) 8 void do_fitos(void)
7 { 9 {
@@ -33,6 +35,13 @@ void do_fcmps (void) @@ -33,6 +35,13 @@ void do_fcmps (void)
33 { 35 {
34 if (isnan(FT0) || isnan(FT1)) { 36 if (isnan(FT0) || isnan(FT1)) {
35 T0 = FSR_FCC1 | FSR_FCC0; 37 T0 = FSR_FCC1 | FSR_FCC0;
  38 + env->fsr &= ~(FSR_FCC1 | FSR_FCC0);
  39 + env->fsr |= T0;
  40 + if (env->fsr & FSR_NVM) {
  41 + raise_exception(TT_FP_EXCP);
  42 + } else {
  43 + env->fsr |= FSR_NVA;
  44 + }
36 } else if (FT0 < FT1) { 45 } else if (FT0 < FT1) {
37 T0 = FSR_FCC0; 46 T0 = FSR_FCC0;
38 } else if (FT0 > FT1) { 47 } else if (FT0 > FT1) {
@@ -47,6 +56,13 @@ void do_fcmpd (void) @@ -47,6 +56,13 @@ void do_fcmpd (void)
47 { 56 {
48 if (isnan(DT0) || isnan(DT1)) { 57 if (isnan(DT0) || isnan(DT1)) {
49 T0 = FSR_FCC1 | FSR_FCC0; 58 T0 = FSR_FCC1 | FSR_FCC0;
  59 + env->fsr &= ~(FSR_FCC1 | FSR_FCC0);
  60 + env->fsr |= T0;
  61 + if (env->fsr & FSR_NVM) {
  62 + raise_exception(TT_FP_EXCP);
  63 + } else {
  64 + env->fsr |= FSR_NVA;
  65 + }
50 } else if (DT0 < DT1) { 66 } else if (DT0 < DT1) {
51 T0 = FSR_FCC0; 67 T0 = FSR_FCC0;
52 } else if (DT0 > DT1) { 68 } else if (DT0 > DT1) {
@@ -59,55 +75,131 @@ void do_fcmpd (void) @@ -59,55 +75,131 @@ void do_fcmpd (void)
59 75
60 void helper_ld_asi(int asi, int size, int sign) 76 void helper_ld_asi(int asi, int size, int sign)
61 { 77 {
62 - switch(asi) { 78 + uint32_t ret;
  79 +
  80 + switch (asi) {
63 case 3: /* MMU probe */ 81 case 3: /* MMU probe */
64 - T1 = 0;  
65 - return; 82 + {
  83 + int mmulev;
  84 +
  85 + mmulev = (T0 >> 8) & 15;
  86 + if (mmulev > 4)
  87 + ret = 0;
  88 + else {
  89 + ret = mmu_probe(T0, mmulev);
  90 + //bswap32s(&ret);
  91 + }
  92 +#ifdef DEBUG_MMU
  93 + printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
  94 +#endif
  95 + }
  96 + break;
66 case 4: /* read MMU regs */ 97 case 4: /* read MMU regs */
67 { 98 {
68 - int temp, reg = (T0 >> 8) & 0xf; 99 + int reg = (T0 >> 8) & 0xf;
69 100
70 - temp = env->mmuregs[reg]; 101 + ret = env->mmuregs[reg];
71 if (reg == 3 || reg == 4) /* Fault status, addr cleared on read*/ 102 if (reg == 3 || reg == 4) /* Fault status, addr cleared on read*/
72 - env->mmuregs[reg] = 0;  
73 - T1 = temp; 103 + env->mmuregs[4] = 0;
74 } 104 }
75 - return; 105 + break;
76 case 0x20 ... 0x2f: /* MMU passthrough */ 106 case 0x20 ... 0x2f: /* MMU passthrough */
77 - {  
78 - int temp;  
79 -  
80 - cpu_physical_memory_read(T0, (void *) &temp, size);  
81 - bswap32s(&temp);  
82 - T1 = temp;  
83 - }  
84 - return; 107 + cpu_physical_memory_read(T0, (void *) &ret, size);
  108 + if (size == 4)
  109 + bswap32s(&ret);
  110 + else if (size == 2)
  111 + bswap16s(&ret);
  112 + break;
85 default: 113 default:
86 - T1 = 0;  
87 - return; 114 + ret = 0;
  115 + break;
88 } 116 }
  117 + T1 = ret;
89 } 118 }
90 119
91 void helper_st_asi(int asi, int size, int sign) 120 void helper_st_asi(int asi, int size, int sign)
92 { 121 {
93 switch(asi) { 122 switch(asi) {
94 case 3: /* MMU flush */ 123 case 3: /* MMU flush */
95 - return; 124 + {
  125 + int mmulev;
  126 +
  127 + mmulev = (T0 >> 8) & 15;
  128 + switch (mmulev) {
  129 + case 0: // flush page
  130 + tlb_flush_page(cpu_single_env, T0 & 0xfffff000);
  131 + break;
  132 + case 1: // flush segment (256k)
  133 + case 2: // flush region (16M)
  134 + case 3: // flush context (4G)
  135 + case 4: // flush entire
  136 + tlb_flush(cpu_single_env, 1);
  137 + break;
  138 + default:
  139 + break;
  140 + }
  141 + dump_mmu();
  142 + return;
  143 + }
96 case 4: /* write MMU regs */ 144 case 4: /* write MMU regs */
97 { 145 {
98 - int reg = (T0 >> 8) & 0xf; 146 + int reg = (T0 >> 8) & 0xf, oldreg;
  147 +
  148 + oldreg = env->mmuregs[reg];
99 if (reg == 0) { 149 if (reg == 0) {
100 env->mmuregs[reg] &= ~(MMU_E | MMU_NF); 150 env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
101 env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF); 151 env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
102 } else 152 } else
103 env->mmuregs[reg] = T1; 153 env->mmuregs[reg] = T1;
  154 + if (oldreg != env->mmuregs[reg]) {
  155 +#if 0
  156 + // XXX: Only if MMU mapping change, we may need to flush?
  157 + tlb_flush(cpu_single_env, 1);
  158 + cpu_loop_exit();
  159 + FORCE_RET();
  160 +#endif
  161 + }
  162 + dump_mmu();
104 return; 163 return;
105 } 164 }
  165 + case 0x17: /* Block copy, sta access */
  166 + {
  167 + // value (T1) = src
  168 + // address (T0) = dst
  169 + // copy 32 bytes
  170 + int src = T1, dst = T0;
  171 + uint8_t temp[32];
  172 +
  173 + bswap32s(&src);
  174 +
  175 + cpu_physical_memory_read(src, (void *) &temp, 32);
  176 + cpu_physical_memory_write(dst, (void *) &temp, 32);
  177 + }
  178 + return;
  179 + case 0x1f: /* Block fill, stda access */
  180 + {
  181 + // value (T1, T2)
  182 + // address (T0) = dst
  183 + // fill 32 bytes
  184 + int i, dst = T0;
  185 + uint64_t val;
  186 +
  187 + val = (((uint64_t)T1) << 32) | T2;
  188 + bswap64s(&val);
  189 +
  190 + for (i = 0; i < 32; i += 8, dst += 8) {
  191 + cpu_physical_memory_write(dst, (void *) &val, 8);
  192 + }
  193 + }
  194 + return;
106 case 0x20 ... 0x2f: /* MMU passthrough */ 195 case 0x20 ... 0x2f: /* MMU passthrough */
107 { 196 {
108 int temp = T1; 197 int temp = T1;
109 -  
110 - bswap32s(&temp); 198 + if (size == 4)
  199 + bswap32s(&temp);
  200 + else if (size == 2)
  201 + bswap16s(&temp);
  202 +
111 cpu_physical_memory_write(T0, (void *) &temp, size); 203 cpu_physical_memory_write(T0, (void *) &temp, size);
112 } 204 }
113 return; 205 return;
@@ -116,27 +208,6 @@ void helper_st_asi(int asi, int size, int sign) @@ -116,27 +208,6 @@ void helper_st_asi(int asi, int size, int sign)
116 } 208 }
117 } 209 }
118 210
119 -#if 0  
120 -void do_ldd_raw(uint32_t addr)  
121 -{  
122 - T1 = ldl_raw((void *) addr);  
123 - T0 = ldl_raw((void *) (addr + 4));  
124 -}  
125 -  
126 -#if !defined(CONFIG_USER_ONLY)  
127 -void do_ldd_user(uint32_t addr)  
128 -{  
129 - T1 = ldl_user((void *) addr);  
130 - T0 = ldl_user((void *) (addr + 4));  
131 -}  
132 -void do_ldd_kernel(uint32_t addr)  
133 -{  
134 - T1 = ldl_kernel((void *) addr);  
135 - T0 = ldl_kernel((void *) (addr + 4));  
136 -}  
137 -#endif  
138 -#endif  
139 -  
140 void helper_rett() 211 void helper_rett()
141 { 212 {
142 int cwp; 213 int cwp;
@@ -166,3 +237,22 @@ void helper_ldfsr(void) @@ -166,3 +237,22 @@ void helper_ldfsr(void)
166 break; 237 break;
167 } 238 }
168 } 239 }
  240 +
  241 +void cpu_get_fp64(uint64_t *pmant, uint16_t *pexp, double f)
  242 +{
  243 + int exptemp;
  244 +
  245 + *pmant = ldexp(frexp(f, &exptemp), 53);
  246 + *pexp = exptemp;
  247 +}
  248 +
  249 +double cpu_put_fp64(uint64_t mant, uint16_t exp)
  250 +{
  251 + return ldexp((double) mant, exp - 53);
  252 +}
  253 +
  254 +void helper_debug()
  255 +{
  256 + env->exception_index = EXCP_DEBUG;
  257 + cpu_loop_exit();
  258 +}
target-sparc/op_mem.h
@@ -43,12 +43,8 @@ void OPPROTO glue(op_swap, MEMSUFFIX)(void) @@ -43,12 +43,8 @@ void OPPROTO glue(op_swap, MEMSUFFIX)(void)
43 43
44 void OPPROTO glue(op_ldd, MEMSUFFIX)(void) 44 void OPPROTO glue(op_ldd, MEMSUFFIX)(void)
45 { 45 {
46 -#if 1  
47 T1 = glue(ldl, MEMSUFFIX)((void *) T0); 46 T1 = glue(ldl, MEMSUFFIX)((void *) T0);
48 T0 = glue(ldl, MEMSUFFIX)((void *) (T0 + 4)); 47 T0 = glue(ldl, MEMSUFFIX)((void *) (T0 + 4));
49 -#else  
50 - glue(do_ldd, MEMSUFFIX)(T0);  
51 -#endif  
52 } 48 }
53 49
54 /*** Floating-point store ***/ 50 /*** Floating-point store ***/
target-sparc/translate.c
@@ -646,6 +646,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -646,6 +646,7 @@ static void disas_sparc_insn(DisasContext * dc)
646 switch (xop) { 646 switch (xop) {
647 case 0x0: 647 case 0x0:
648 case 0x1: /* UNIMPL */ 648 case 0x1: /* UNIMPL */
  649 + case 0x5: /*CBN+x */
649 default: 650 default:
650 goto illegal_insn; 651 goto illegal_insn;
651 case 0x2: /* BN+x */ 652 case 0x2: /* BN+x */
@@ -657,16 +658,24 @@ static void disas_sparc_insn(DisasContext * dc) @@ -657,16 +658,24 @@ static void disas_sparc_insn(DisasContext * dc)
657 } 658 }
658 case 0x6: /* FBN+x */ 659 case 0x6: /* FBN+x */
659 { 660 {
  661 +#if !defined(CONFIG_USER_ONLY)
  662 + gen_op_trap_ifnofpu();
  663 +#endif
660 target <<= 2; 664 target <<= 2;
661 target = sign_extend(target, 22); 665 target = sign_extend(target, 22);
662 do_fbranch(dc, target, insn); 666 do_fbranch(dc, target, insn);
663 goto jmp_insn; 667 goto jmp_insn;
664 } 668 }
665 case 0x4: /* SETHI */ 669 case 0x4: /* SETHI */
666 - gen_movl_imm_T0(target << 10);  
667 - gen_movl_T0_reg(rd);  
668 - break;  
669 - case 0x5: /*CBN+x */ 670 +#define OPTIM
  671 +#if defined(OPTIM)
  672 + if (rd) { // nop
  673 +#endif
  674 + gen_movl_imm_T0(target << 10);
  675 + gen_movl_T0_reg(rd);
  676 +#if defined(OPTIM)
  677 + }
  678 +#endif
670 break; 679 break;
671 } 680 }
672 break; 681 break;
@@ -691,14 +700,24 @@ static void disas_sparc_insn(DisasContext * dc) @@ -691,14 +700,24 @@ static void disas_sparc_insn(DisasContext * dc)
691 gen_movl_reg_T0(rs1); 700 gen_movl_reg_T0(rs1);
692 if (IS_IMM) { 701 if (IS_IMM) {
693 rs2 = GET_FIELD(insn, 25, 31); 702 rs2 = GET_FIELD(insn, 25, 31);
  703 +#if defined(OPTIM)
694 if (rs2 != 0) { 704 if (rs2 != 0) {
695 - gen_movl_imm_T1(rs2);  
696 - gen_op_add_T1_T0(); 705 +#endif
  706 + gen_movl_imm_T1(rs2);
  707 + gen_op_add_T1_T0();
  708 +#if defined(OPTIM)
697 } 709 }
  710 +#endif
698 } else { 711 } else {
699 rs2 = GET_FIELD(insn, 27, 31); 712 rs2 = GET_FIELD(insn, 27, 31);
700 - gen_movl_reg_T1(rs2);  
701 - gen_op_add_T1_T0(); 713 +#if defined(OPTIM)
  714 + if (rs2 != 0) {
  715 +#endif
  716 + gen_movl_reg_T1(rs2);
  717 + gen_op_add_T1_T0();
  718 +#if defined(OPTIM)
  719 + }
  720 +#endif
702 } 721 }
703 save_state(dc); 722 save_state(dc);
704 cond = GET_FIELD(insn, 3, 6); 723 cond = GET_FIELD(insn, 3, 6);
@@ -707,6 +726,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -707,6 +726,7 @@ static void disas_sparc_insn(DisasContext * dc)
707 dc->is_br = 1; 726 dc->is_br = 1;
708 goto jmp_insn; 727 goto jmp_insn;
709 } else { 728 } else {
  729 + gen_cond(cond);
710 gen_op_trapcc_T0(); 730 gen_op_trapcc_T0();
711 } 731 }
712 } else if (xop == 0x28) { 732 } else if (xop == 0x28) {
@@ -741,7 +761,10 @@ static void disas_sparc_insn(DisasContext * dc) @@ -741,7 +761,10 @@ static void disas_sparc_insn(DisasContext * dc)
741 gen_movl_T0_reg(rd); 761 gen_movl_T0_reg(rd);
742 break; 762 break;
743 #endif 763 #endif
744 - } else if (xop == 0x34 || xop == 0x35) { /* FPU Operations */ 764 + } else if (xop == 0x34) { /* FPU Operations */
  765 +#if !defined(CONFIG_USER_ONLY)
  766 + gen_op_trap_ifnofpu();
  767 +#endif
745 rs1 = GET_FIELD(insn, 13, 17); 768 rs1 = GET_FIELD(insn, 13, 17);
746 rs2 = GET_FIELD(insn, 27, 31); 769 rs2 = GET_FIELD(insn, 27, 31);
747 xop = GET_FIELD(insn, 18, 26); 770 xop = GET_FIELD(insn, 18, 26);
@@ -770,6 +793,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -770,6 +793,8 @@ static void disas_sparc_insn(DisasContext * dc)
770 gen_op_fsqrtd(); 793 gen_op_fsqrtd();
771 gen_op_store_DT0_fpr(rd); 794 gen_op_store_DT0_fpr(rd);
772 break; 795 break;
  796 + case 0x2b: /* fsqrtq */
  797 + goto nfpu_insn;
773 case 0x41: 798 case 0x41:
774 gen_op_load_fpr_FT0(rs1); 799 gen_op_load_fpr_FT0(rs1);
775 gen_op_load_fpr_FT1(rs2); 800 gen_op_load_fpr_FT1(rs2);
@@ -782,6 +807,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -782,6 +807,8 @@ static void disas_sparc_insn(DisasContext * dc)
782 gen_op_faddd(); 807 gen_op_faddd();
783 gen_op_store_DT0_fpr(rd); 808 gen_op_store_DT0_fpr(rd);
784 break; 809 break;
  810 + case 0x43: /* faddq */
  811 + goto nfpu_insn;
785 case 0x45: 812 case 0x45:
786 gen_op_load_fpr_FT0(rs1); 813 gen_op_load_fpr_FT0(rs1);
787 gen_op_load_fpr_FT1(rs2); 814 gen_op_load_fpr_FT1(rs2);
@@ -794,6 +821,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -794,6 +821,8 @@ static void disas_sparc_insn(DisasContext * dc)
794 gen_op_fsubd(); 821 gen_op_fsubd();
795 gen_op_store_DT0_fpr(rd); 822 gen_op_store_DT0_fpr(rd);
796 break; 823 break;
  824 + case 0x47: /* fsubq */
  825 + goto nfpu_insn;
797 case 0x49: 826 case 0x49:
798 gen_op_load_fpr_FT0(rs1); 827 gen_op_load_fpr_FT0(rs1);
799 gen_op_load_fpr_FT1(rs2); 828 gen_op_load_fpr_FT1(rs2);
@@ -806,6 +835,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -806,6 +835,8 @@ static void disas_sparc_insn(DisasContext * dc)
806 gen_op_fmuld(); 835 gen_op_fmuld();
807 gen_op_store_DT0_fpr(rd); 836 gen_op_store_DT0_fpr(rd);
808 break; 837 break;
  838 + case 0x4b: /* fmulq */
  839 + goto nfpu_insn;
809 case 0x4d: 840 case 0x4d:
810 gen_op_load_fpr_FT0(rs1); 841 gen_op_load_fpr_FT0(rs1);
811 gen_op_load_fpr_FT1(rs2); 842 gen_op_load_fpr_FT1(rs2);
@@ -818,32 +849,16 @@ static void disas_sparc_insn(DisasContext * dc) @@ -818,32 +849,16 @@ static void disas_sparc_insn(DisasContext * dc)
818 gen_op_fdivd(); 849 gen_op_fdivd();
819 gen_op_store_DT0_fpr(rd); 850 gen_op_store_DT0_fpr(rd);
820 break; 851 break;
821 - case 0x51:  
822 - gen_op_load_fpr_FT0(rs1);  
823 - gen_op_load_fpr_FT1(rs2);  
824 - gen_op_fcmps();  
825 - break;  
826 - case 0x52:  
827 - gen_op_load_fpr_DT0(rs1);  
828 - gen_op_load_fpr_DT1(rs2);  
829 - gen_op_fcmpd();  
830 - break;  
831 - case 0x55: /* fcmpes */  
832 - gen_op_load_fpr_FT0(rs1);  
833 - gen_op_load_fpr_FT1(rs2);  
834 - gen_op_fcmps(); /* XXX */  
835 - break;  
836 - case 0x56: /* fcmped */  
837 - gen_op_load_fpr_DT0(rs1);  
838 - gen_op_load_fpr_DT1(rs2);  
839 - gen_op_fcmpd(); /* XXX */  
840 - break; 852 + case 0x4f: /* fdivq */
  853 + goto nfpu_insn;
841 case 0x69: 854 case 0x69:
842 gen_op_load_fpr_FT0(rs1); 855 gen_op_load_fpr_FT0(rs1);
843 gen_op_load_fpr_FT1(rs2); 856 gen_op_load_fpr_FT1(rs2);
844 gen_op_fsmuld(); 857 gen_op_fsmuld();
845 gen_op_store_DT0_fpr(rd); 858 gen_op_store_DT0_fpr(rd);
846 break; 859 break;
  860 + case 0x6e: /* fdmulq */
  861 + goto nfpu_insn;
847 case 0xc4: 862 case 0xc4:
848 gen_op_load_fpr_FT1(rs2); 863 gen_op_load_fpr_FT1(rs2);
849 gen_op_fitos(); 864 gen_op_fitos();
@@ -854,6 +869,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -854,6 +869,8 @@ static void disas_sparc_insn(DisasContext * dc)
854 gen_op_fdtos(); 869 gen_op_fdtos();
855 gen_op_store_FT0_fpr(rd); 870 gen_op_store_FT0_fpr(rd);
856 break; 871 break;
  872 + case 0xc7: /* fqtos */
  873 + goto nfpu_insn;
857 case 0xc8: 874 case 0xc8:
858 gen_op_load_fpr_FT1(rs2); 875 gen_op_load_fpr_FT1(rs2);
859 gen_op_fitod(); 876 gen_op_fitod();
@@ -864,6 +881,14 @@ static void disas_sparc_insn(DisasContext * dc) @@ -864,6 +881,14 @@ static void disas_sparc_insn(DisasContext * dc)
864 gen_op_fstod(); 881 gen_op_fstod();
865 gen_op_store_DT0_fpr(rd); 882 gen_op_store_DT0_fpr(rd);
866 break; 883 break;
  884 + case 0xcb: /* fqtod */
  885 + goto nfpu_insn;
  886 + case 0xcc: /* fitoq */
  887 + goto nfpu_insn;
  888 + case 0xcd: /* fstoq */
  889 + goto nfpu_insn;
  890 + case 0xce: /* fdtoq */
  891 + goto nfpu_insn;
867 case 0xd1: 892 case 0xd1:
868 gen_op_load_fpr_FT1(rs2); 893 gen_op_load_fpr_FT1(rs2);
869 gen_op_fstoi(); 894 gen_op_fstoi();
@@ -874,13 +899,85 @@ static void disas_sparc_insn(DisasContext * dc) @@ -874,13 +899,85 @@ static void disas_sparc_insn(DisasContext * dc)
874 gen_op_fdtoi(); 899 gen_op_fdtoi();
875 gen_op_store_FT0_fpr(rd); 900 gen_op_store_FT0_fpr(rd);
876 break; 901 break;
  902 + case 0xd3: /* fqtoi */
  903 + goto nfpu_insn;
877 default: 904 default:
878 goto illegal_insn; 905 goto illegal_insn;
879 } 906 }
880 - } else { 907 + } else if (xop == 0x35) { /* FPU Operations */
  908 +#if !defined(CONFIG_USER_ONLY)
  909 + gen_op_trap_ifnofpu();
  910 +#endif
881 rs1 = GET_FIELD(insn, 13, 17); 911 rs1 = GET_FIELD(insn, 13, 17);
882 - gen_movl_reg_T0(rs1);  
883 - if (IS_IMM) { /* immediate */ 912 + rs2 = GET_FIELD(insn, 27, 31);
  913 + xop = GET_FIELD(insn, 18, 26);
  914 + switch (xop) {
  915 + case 0x51:
  916 + gen_op_load_fpr_FT0(rs1);
  917 + gen_op_load_fpr_FT1(rs2);
  918 + gen_op_fcmps();
  919 + break;
  920 + case 0x52:
  921 + gen_op_load_fpr_DT0(rs1);
  922 + gen_op_load_fpr_DT1(rs2);
  923 + gen_op_fcmpd();
  924 + break;
  925 + case 0x53: /* fcmpq */
  926 + goto nfpu_insn;
  927 + case 0x55: /* fcmpes */
  928 + gen_op_load_fpr_FT0(rs1);
  929 + gen_op_load_fpr_FT1(rs2);
  930 + gen_op_fcmps(); /* XXX should trap if qNaN or sNaN */
  931 + break;
  932 + case 0x56: /* fcmped */
  933 + gen_op_load_fpr_DT0(rs1);
  934 + gen_op_load_fpr_DT1(rs2);
  935 + gen_op_fcmpd(); /* XXX should trap if qNaN or sNaN */
  936 + break;
  937 + case 0x57: /* fcmpeq */
  938 + goto nfpu_insn;
  939 + default:
  940 + goto illegal_insn;
  941 + }
  942 +#if defined(OPTIM)
  943 + } else if (xop == 0x2) {
  944 + // clr/mov shortcut
  945 +
  946 + rs1 = GET_FIELD(insn, 13, 17);
  947 + if (rs1 == 0) {
  948 + // or %g0, x, y -> mov T1, x; mov y, T1
  949 + if (IS_IMM) { /* immediate */
  950 + rs2 = GET_FIELDs(insn, 19, 31);
  951 + gen_movl_imm_T1(rs2);
  952 + } else { /* register */
  953 + rs2 = GET_FIELD(insn, 27, 31);
  954 + gen_movl_reg_T1(rs2);
  955 + }
  956 + gen_movl_T1_reg(rd);
  957 + } else {
  958 + gen_movl_reg_T0(rs1);
  959 + if (IS_IMM) { /* immediate */
  960 + // or x, #0, y -> mov T1, x; mov y, T1
  961 + rs2 = GET_FIELDs(insn, 19, 31);
  962 + if (rs2 != 0) {
  963 + gen_movl_imm_T1(rs2);
  964 + gen_op_or_T1_T0();
  965 + }
  966 + } else { /* register */
  967 + // or x, %g0, y -> mov T1, x; mov y, T1
  968 + rs2 = GET_FIELD(insn, 27, 31);
  969 + if (rs2 != 0) {
  970 + gen_movl_reg_T1(rs2);
  971 + gen_op_or_T1_T0();
  972 + }
  973 + }
  974 + gen_movl_T0_reg(rd);
  975 + }
  976 +#endif
  977 + } else if (xop < 0x38) {
  978 + rs1 = GET_FIELD(insn, 13, 17);
  979 + gen_movl_reg_T0(rs1);
  980 + if (IS_IMM) { /* immediate */
884 rs2 = GET_FIELDs(insn, 19, 31); 981 rs2 = GET_FIELDs(insn, 19, 31);
885 gen_movl_imm_T1(rs2); 982 gen_movl_imm_T1(rs2);
886 } else { /* register */ 983 } else { /* register */
@@ -901,10 +998,10 @@ static void disas_sparc_insn(DisasContext * dc) @@ -901,10 +998,10 @@ static void disas_sparc_insn(DisasContext * dc)
901 gen_op_logic_T0_cc(); 998 gen_op_logic_T0_cc();
902 break; 999 break;
903 case 0x2: 1000 case 0x2:
904 - gen_op_or_T1_T0();  
905 - if (xop & 0x10)  
906 - gen_op_logic_T0_cc();  
907 - break; 1001 + gen_op_or_T1_T0();
  1002 + if (xop & 0x10)
  1003 + gen_op_logic_T0_cc();
  1004 + break;
908 case 0x3: 1005 case 0x3:
909 gen_op_xor_T1_T0(); 1006 gen_op_xor_T1_T0();
910 if (xop & 0x10) 1007 if (xop & 0x10)
@@ -964,9 +1061,14 @@ static void disas_sparc_insn(DisasContext * dc) @@ -964,9 +1061,14 @@ static void disas_sparc_insn(DisasContext * dc)
964 default: 1061 default:
965 goto illegal_insn; 1062 goto illegal_insn;
966 } 1063 }
967 - gen_movl_T0_reg(rd); 1064 + gen_movl_T0_reg(rd);
968 } else { 1065 } else {
969 switch (xop) { 1066 switch (xop) {
  1067 + case 0x20: /* taddcc */
  1068 + case 0x21: /* tsubcc */
  1069 + case 0x22: /* taddcctv */
  1070 + case 0x23: /* tsubcctv */
  1071 + goto illegal_insn;
970 case 0x24: /* mulscc */ 1072 case 0x24: /* mulscc */
971 gen_op_mulscc_T1_T0(); 1073 gen_op_mulscc_T1_T0();
972 gen_movl_T0_reg(rd); 1074 gen_movl_T0_reg(rd);
@@ -1021,56 +1123,72 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1021,56 +1123,72 @@ static void disas_sparc_insn(DisasContext * dc)
1021 } 1123 }
1022 break; 1124 break;
1023 #endif 1125 #endif
1024 - case 0x38: /* jmpl */  
1025 - {  
1026 - gen_op_add_T1_T0();  
1027 - gen_op_movl_npc_T0();  
1028 - if (rd != 0) {  
1029 - gen_op_movl_T0_im((long) (dc->pc));  
1030 - gen_movl_T0_reg(rd);  
1031 - }  
1032 - dc->pc = dc->npc;  
1033 - dc->npc = DYNAMIC_PC;  
1034 - }  
1035 - goto jmp_insn;  
1036 -#if !defined(CONFIG_USER_ONLY)  
1037 - case 0x39: /* rett */  
1038 - {  
1039 - if (!supervisor(dc))  
1040 - goto priv_insn;  
1041 - gen_op_add_T1_T0();  
1042 - gen_op_movl_npc_T0();  
1043 - gen_op_rett();  
1044 -#if 0  
1045 - dc->pc = dc->npc;  
1046 - dc->npc = DYNAMIC_PC; 1126 + default:
  1127 + goto illegal_insn;
  1128 + }
  1129 + }
  1130 + } else {
  1131 + rs1 = GET_FIELD(insn, 13, 17);
  1132 + gen_movl_reg_T0(rs1);
  1133 + if (IS_IMM) { /* immediate */
  1134 + rs2 = GET_FIELDs(insn, 19, 31);
  1135 +#if defined(OPTIM)
  1136 + if (rs2) {
1047 #endif 1137 #endif
1048 - }  
1049 -#if 0  
1050 - goto jmp_insn; 1138 + gen_movl_imm_T1(rs2);
  1139 + gen_op_add_T1_T0();
  1140 +#if defined(OPTIM)
  1141 + }
1051 #endif 1142 #endif
1052 - break; 1143 + } else { /* register */
  1144 + rs2 = GET_FIELD(insn, 27, 31);
  1145 +#if defined(OPTIM)
  1146 + if (rs2) {
  1147 +#endif
  1148 + gen_movl_reg_T1(rs2);
  1149 + gen_op_add_T1_T0();
  1150 +#if defined(OPTIM)
  1151 + }
1053 #endif 1152 #endif
1054 - case 0x3b: /* flush */  
1055 - gen_op_add_T1_T0();  
1056 - gen_op_flush_T0();  
1057 - break;  
1058 - case 0x3c: /* save */  
1059 - save_state(dc);  
1060 - gen_op_add_T1_T0();  
1061 - gen_op_save();  
1062 - gen_movl_T0_reg(rd);  
1063 - break;  
1064 - case 0x3d: /* restore */  
1065 - save_state(dc);  
1066 - gen_op_add_T1_T0();  
1067 - gen_op_restore();  
1068 - gen_movl_T0_reg(rd);  
1069 - break;  
1070 - default:  
1071 - goto illegal_insn;  
1072 - }  
1073 } 1153 }
  1154 + switch (xop) {
  1155 + case 0x38: /* jmpl */
  1156 + {
  1157 + gen_op_movl_npc_T0();
  1158 + if (rd != 0) {
  1159 + gen_op_movl_T0_im((long) (dc->pc));
  1160 + gen_movl_T0_reg(rd);
  1161 + }
  1162 + dc->pc = dc->npc;
  1163 + dc->npc = DYNAMIC_PC;
  1164 + }
  1165 + goto jmp_insn;
  1166 +#if !defined(CONFIG_USER_ONLY)
  1167 + case 0x39: /* rett */
  1168 + {
  1169 + if (!supervisor(dc))
  1170 + goto priv_insn;
  1171 + gen_op_movl_npc_T0();
  1172 + gen_op_rett();
  1173 + }
  1174 + break;
  1175 +#endif
  1176 + case 0x3b: /* flush */
  1177 + gen_op_flush_T0();
  1178 + break;
  1179 + case 0x3c: /* save */
  1180 + save_state(dc);
  1181 + gen_op_save();
  1182 + gen_movl_T0_reg(rd);
  1183 + break;
  1184 + case 0x3d: /* restore */
  1185 + save_state(dc);
  1186 + gen_op_restore();
  1187 + gen_movl_T0_reg(rd);
  1188 + break;
  1189 + default:
  1190 + goto illegal_insn;
  1191 + }
1074 } 1192 }
1075 break; 1193 break;
1076 } 1194 }
@@ -1081,14 +1199,24 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1081,14 +1199,24 @@ static void disas_sparc_insn(DisasContext * dc)
1081 gen_movl_reg_T0(rs1); 1199 gen_movl_reg_T0(rs1);
1082 if (IS_IMM) { /* immediate */ 1200 if (IS_IMM) { /* immediate */
1083 rs2 = GET_FIELDs(insn, 19, 31); 1201 rs2 = GET_FIELDs(insn, 19, 31);
  1202 +#if defined(OPTIM)
1084 if (rs2 != 0) { 1203 if (rs2 != 0) {
  1204 +#endif
1085 gen_movl_imm_T1(rs2); 1205 gen_movl_imm_T1(rs2);
1086 gen_op_add_T1_T0(); 1206 gen_op_add_T1_T0();
  1207 +#if defined(OPTIM)
1087 } 1208 }
  1209 +#endif
1088 } else { /* register */ 1210 } else { /* register */
1089 rs2 = GET_FIELD(insn, 27, 31); 1211 rs2 = GET_FIELD(insn, 27, 31);
1090 - gen_movl_reg_T1(rs2);  
1091 - gen_op_add_T1_T0(); 1212 +#if defined(OPTIM)
  1213 + if (rs2 != 0) {
  1214 +#endif
  1215 + gen_movl_reg_T1(rs2);
  1216 + gen_op_add_T1_T0();
  1217 +#if defined(OPTIM)
  1218 + }
  1219 +#endif
1092 } 1220 }
1093 if (xop < 4 || (xop > 7 && xop < 0x14) || \ 1221 if (xop < 4 || (xop > 7 && xop < 0x14) || \
1094 (xop > 0x17 && xop < 0x20)) { 1222 (xop > 0x17 && xop < 0x20)) {
@@ -1116,8 +1244,10 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1116,8 +1244,10 @@ static void disas_sparc_insn(DisasContext * dc)
1116 gen_op_ldst(ldstub); 1244 gen_op_ldst(ldstub);
1117 break; 1245 break;
1118 case 0x0f: /* swap register with memory. Also atomically */ 1246 case 0x0f: /* swap register with memory. Also atomically */
  1247 + gen_movl_reg_T1(rd);
1119 gen_op_ldst(swap); 1248 gen_op_ldst(swap);
1120 break; 1249 break;
  1250 +#if !defined(CONFIG_USER_ONLY)
1121 case 0x10: /* load word alternate */ 1251 case 0x10: /* load word alternate */
1122 if (!supervisor(dc)) 1252 if (!supervisor(dc))
1123 goto priv_insn; 1253 goto priv_insn;
@@ -1157,11 +1287,18 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1157,11 +1287,18 @@ static void disas_sparc_insn(DisasContext * dc)
1157 case 0x1f: /* swap reg with alt. memory. Also atomically */ 1287 case 0x1f: /* swap reg with alt. memory. Also atomically */
1158 if (!supervisor(dc)) 1288 if (!supervisor(dc))
1159 goto priv_insn; 1289 goto priv_insn;
  1290 + gen_movl_reg_T1(rd);
1160 gen_op_swapa(insn, 1, 4, 0); 1291 gen_op_swapa(insn, 1, 4, 0);
1161 break; 1292 break;
  1293 +#endif
  1294 + default:
  1295 + goto illegal_insn;
1162 } 1296 }
1163 gen_movl_T1_reg(rd); 1297 gen_movl_T1_reg(rd);
1164 } else if (xop >= 0x20 && xop < 0x24) { 1298 } else if (xop >= 0x20 && xop < 0x24) {
  1299 +#if !defined(CONFIG_USER_ONLY)
  1300 + gen_op_trap_ifnofpu();
  1301 +#endif
1165 switch (xop) { 1302 switch (xop) {
1166 case 0x20: /* load fpreg */ 1303 case 0x20: /* load fpreg */
1167 gen_op_ldst(ldf); 1304 gen_op_ldst(ldf);
@@ -1169,11 +1306,14 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1169,11 +1306,14 @@ static void disas_sparc_insn(DisasContext * dc)
1169 break; 1306 break;
1170 case 0x21: /* load fsr */ 1307 case 0x21: /* load fsr */
1171 gen_op_ldfsr(); 1308 gen_op_ldfsr();
  1309 + gen_op_store_FT0_fpr(rd);
1172 break; 1310 break;
1173 case 0x23: /* load double fpreg */ 1311 case 0x23: /* load double fpreg */
1174 gen_op_ldst(lddf); 1312 gen_op_ldst(lddf);
1175 gen_op_store_DT0_fpr(rd); 1313 gen_op_store_DT0_fpr(rd);
1176 break; 1314 break;
  1315 + default:
  1316 + goto illegal_insn;
1177 } 1317 }
1178 } else if (xop < 8 || (xop >= 0x14 && xop < 0x18)) { 1318 } else if (xop < 8 || (xop >= 0x14 && xop < 0x18)) {
1179 gen_movl_reg_T1(rd); 1319 gen_movl_reg_T1(rd);
@@ -1192,6 +1332,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1192,6 +1332,7 @@ static void disas_sparc_insn(DisasContext * dc)
1192 gen_movl_reg_T2(rd + 1); 1332 gen_movl_reg_T2(rd + 1);
1193 gen_op_ldst(std); 1333 gen_op_ldst(std);
1194 break; 1334 break;
  1335 +#if !defined(CONFIG_USER_ONLY)
1195 case 0x14: 1336 case 0x14:
1196 if (!supervisor(dc)) 1337 if (!supervisor(dc))
1197 goto priv_insn; 1338 goto priv_insn;
@@ -1214,24 +1355,37 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1214,24 +1355,37 @@ static void disas_sparc_insn(DisasContext * dc)
1214 gen_movl_reg_T2(rd + 1); 1355 gen_movl_reg_T2(rd + 1);
1215 gen_op_stda(insn, 0, 8, 0); 1356 gen_op_stda(insn, 0, 8, 0);
1216 break; 1357 break;
  1358 +#endif
  1359 + default:
  1360 + goto illegal_insn;
1217 } 1361 }
1218 } else if (xop > 0x23 && xop < 0x28) { 1362 } else if (xop > 0x23 && xop < 0x28) {
  1363 +#if !defined(CONFIG_USER_ONLY)
  1364 + gen_op_trap_ifnofpu();
  1365 +#endif
1219 switch (xop) { 1366 switch (xop) {
1220 case 0x24: 1367 case 0x24:
1221 gen_op_load_fpr_FT0(rd); 1368 gen_op_load_fpr_FT0(rd);
1222 gen_op_ldst(stf); 1369 gen_op_ldst(stf);
1223 break; 1370 break;
1224 case 0x25: 1371 case 0x25:
  1372 + gen_op_load_fpr_FT0(rd);
1225 gen_op_stfsr(); 1373 gen_op_stfsr();
1226 break; 1374 break;
1227 case 0x27: 1375 case 0x27:
1228 gen_op_load_fpr_DT0(rd); 1376 gen_op_load_fpr_DT0(rd);
1229 gen_op_ldst(stdf); 1377 gen_op_ldst(stdf);
1230 break; 1378 break;
  1379 + case 0x26: /* stdfq */
  1380 + default:
  1381 + goto illegal_insn;
1231 } 1382 }
1232 } else if (xop > 0x33 && xop < 0x38) { 1383 } else if (xop > 0x33 && xop < 0x38) {
1233 /* Co-processor */ 1384 /* Co-processor */
  1385 + goto illegal_insn;
1234 } 1386 }
  1387 + else
  1388 + goto illegal_insn;
1235 } 1389 }
1236 } 1390 }
1237 /* default case for non jump instructions */ 1391 /* default case for non jump instructions */
@@ -1246,17 +1400,24 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1246,17 +1400,24 @@ static void disas_sparc_insn(DisasContext * dc)
1246 dc->pc = dc->npc; 1400 dc->pc = dc->npc;
1247 dc->npc = dc->npc + 4; 1401 dc->npc = dc->npc + 4;
1248 } 1402 }
1249 - jmp_insn:; 1403 + jmp_insn:
1250 return; 1404 return;
1251 illegal_insn: 1405 illegal_insn:
1252 save_state(dc); 1406 save_state(dc);
1253 gen_op_exception(TT_ILL_INSN); 1407 gen_op_exception(TT_ILL_INSN);
1254 dc->is_br = 1; 1408 dc->is_br = 1;
1255 return; 1409 return;
  1410 +#if !defined(CONFIG_USER_ONLY)
1256 priv_insn: 1411 priv_insn:
1257 save_state(dc); 1412 save_state(dc);
1258 gen_op_exception(TT_PRIV_INSN); 1413 gen_op_exception(TT_PRIV_INSN);
1259 dc->is_br = 1; 1414 dc->is_br = 1;
  1415 + return;
  1416 +#endif
  1417 + nfpu_insn:
  1418 + save_state(dc);
  1419 + gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
  1420 + dc->is_br = 1;
1260 } 1421 }
1261 1422
1262 static inline int gen_intermediate_code_internal(TranslationBlock * tb, 1423 static inline int gen_intermediate_code_internal(TranslationBlock * tb,
@@ -1271,6 +1432,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, @@ -1271,6 +1432,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
1271 dc->tb = tb; 1432 dc->tb = tb;
1272 pc_start = tb->pc; 1433 pc_start = tb->pc;
1273 dc->pc = pc_start; 1434 dc->pc = pc_start;
  1435 + last_pc = dc->pc;
1274 dc->npc = (target_ulong) tb->cs_base; 1436 dc->npc = (target_ulong) tb->cs_base;
1275 #if defined(CONFIG_USER_ONLY) 1437 #if defined(CONFIG_USER_ONLY)
1276 dc->mem_idx = 0; 1438 dc->mem_idx = 0;
@@ -1285,8 +1447,13 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, @@ -1285,8 +1447,13 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
1285 if (env->nb_breakpoints > 0) { 1447 if (env->nb_breakpoints > 0) {
1286 for(j = 0; j < env->nb_breakpoints; j++) { 1448 for(j = 0; j < env->nb_breakpoints; j++) {
1287 if (env->breakpoints[j] == dc->pc) { 1449 if (env->breakpoints[j] == dc->pc) {
1288 - gen_debug(dc, dc->pc);  
1289 - break; 1450 + if (dc->pc != pc_start)
  1451 + save_state(dc);
  1452 + gen_op_debug();
  1453 + gen_op_movl_T0_0();
  1454 + gen_op_exit_tb();
  1455 + dc->is_br = 1;
  1456 + goto exit_gen_loop;
1290 } 1457 }
1291 } 1458 }
1292 } 1459 }
@@ -1310,8 +1477,18 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, @@ -1310,8 +1477,18 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
1310 /* if the next PC is different, we abort now */ 1477 /* if the next PC is different, we abort now */
1311 if (dc->pc != (last_pc + 4)) 1478 if (dc->pc != (last_pc + 4))
1312 break; 1479 break;
  1480 + /* if single step mode, we generate only one instruction and
  1481 + generate an exception */
  1482 + if (env->singlestep_enabled) {
  1483 + gen_op_jmp_im(dc->pc);
  1484 + gen_op_movl_T0_0();
  1485 + gen_op_exit_tb();
  1486 + break;
  1487 + }
1313 } while ((gen_opc_ptr < gen_opc_end) && 1488 } while ((gen_opc_ptr < gen_opc_end) &&
1314 (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32)); 1489 (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
  1490 +
  1491 + exit_gen_loop:
1315 if (!dc->is_br) { 1492 if (!dc->is_br) {
1316 if (dc->pc != DYNAMIC_PC && 1493 if (dc->pc != DYNAMIC_PC &&
1317 (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) { 1494 (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
@@ -1338,7 +1515,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, @@ -1338,7 +1515,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
1338 } 1515 }
1339 #endif 1516 #endif
1340 } else { 1517 } else {
1341 - tb->size = dc->npc - pc_start; 1518 + tb->size = last_pc + 4 - pc_start;
1342 } 1519 }
1343 #ifdef DEBUG_DISAS 1520 #ifdef DEBUG_DISAS
1344 if (loglevel & CPU_LOG_TB_IN_ASM) { 1521 if (loglevel & CPU_LOG_TB_IN_ASM) {
@@ -1366,14 +1543,10 @@ int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb) @@ -1366,14 +1543,10 @@ int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
1366 return gen_intermediate_code_internal(tb, 1, env); 1543 return gen_intermediate_code_internal(tb, 1, env);
1367 } 1544 }
1368 1545
1369 -CPUSPARCState *cpu_sparc_init(void)  
1370 -{  
1371 - CPUSPARCState *env;  
1372 -  
1373 - cpu_exec_init(); 1546 +extern int ram_size;
1374 1547
1375 - if (!(env = malloc(sizeof(CPUSPARCState))))  
1376 - return (NULL); 1548 +void cpu_reset(CPUSPARCState *env)
  1549 +{
1377 memset(env, 0, sizeof(*env)); 1550 memset(env, 0, sizeof(*env));
1378 env->cwp = 0; 1551 env->cwp = 0;
1379 env->wim = 1; 1552 env->wim = 1;
@@ -1381,14 +1554,24 @@ CPUSPARCState *cpu_sparc_init(void) @@ -1381,14 +1554,24 @@ CPUSPARCState *cpu_sparc_init(void)
1381 #if defined(CONFIG_USER_ONLY) 1554 #if defined(CONFIG_USER_ONLY)
1382 env->user_mode_only = 1; 1555 env->user_mode_only = 1;
1383 #else 1556 #else
1384 - /* Emulate Prom */  
1385 env->psrs = 1; 1557 env->psrs = 1;
1386 - env->pc = 0x4000; 1558 + env->pc = 0xffd00000;
  1559 + env->gregs[1] = ram_size;
  1560 + env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */
1387 env->npc = env->pc + 4; 1561 env->npc = env->pc + 4;
1388 - env->mmuregs[0] = (0x10<<24) | MMU_E; /* Impl 1, ver 0, MMU Enabled */  
1389 - env->mmuregs[1] = 0x3000 >> 4; /* MMU Context table */  
1390 #endif 1562 #endif
  1563 +}
  1564 +
  1565 +CPUSPARCState *cpu_sparc_init(void)
  1566 +{
  1567 + CPUSPARCState *env;
  1568 +
  1569 + cpu_exec_init();
  1570 +
  1571 + if (!(env = malloc(sizeof(CPUSPARCState))))
  1572 + return (NULL);
1391 cpu_single_env = env; 1573 cpu_single_env = env;
  1574 + cpu_reset(env);
1392 return (env); 1575 return (env);
1393 } 1576 }
1394 1577
@@ -1436,11 +1619,24 @@ void cpu_dump_state(CPUState *env, FILE *f, @@ -1436,11 +1619,24 @@ void cpu_dump_state(CPUState *env, FILE *f,
1436 cpu_fprintf(f, "fsr: 0x%08x\n", env->fsr); 1619 cpu_fprintf(f, "fsr: 0x%08x\n", env->fsr);
1437 } 1620 }
1438 1621
  1622 +#if defined(CONFIG_USER_ONLY)
1439 target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) 1623 target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1440 { 1624 {
1441 return addr; 1625 return addr;
1442 } 1626 }
1443 1627
  1628 +#else
  1629 +target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
  1630 +{
  1631 + uint32_t phys_addr;
  1632 + int prot, access_index;
  1633 +
  1634 + if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, 0) != 0)
  1635 + return -1;
  1636 + return phys_addr;
  1637 +}
  1638 +#endif
  1639 +
1444 void helper_flush(target_ulong addr) 1640 void helper_flush(target_ulong addr)
1445 { 1641 {
1446 addr &= ~7; 1642 addr &= ~7;
@@ -2214,10 +2214,74 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) @@ -2214,10 +2214,74 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
2214 #elif defined(TARGET_SPARC) 2214 #elif defined(TARGET_SPARC)
2215 void cpu_save(QEMUFile *f, void *opaque) 2215 void cpu_save(QEMUFile *f, void *opaque)
2216 { 2216 {
  2217 + CPUState *env = opaque;
  2218 + int i;
  2219 + uint32_t tmp;
  2220 +
  2221 + for(i = 1; i < 8; i++)
  2222 + qemu_put_be32s(f, &env->gregs[i]);
  2223 + tmp = env->regwptr - env->regbase;
  2224 + qemu_put_be32s(f, &tmp);
  2225 + for(i = 1; i < NWINDOWS * 16 + 8; i++)
  2226 + qemu_put_be32s(f, &env->regbase[i]);
  2227 +
  2228 + /* FPU */
  2229 + for(i = 0; i < 32; i++) {
  2230 + uint64_t mant;
  2231 + uint16_t exp;
  2232 + cpu_get_fp64(&mant, &exp, env->fpr[i]);
  2233 + qemu_put_be64(f, mant);
  2234 + qemu_put_be16(f, exp);
  2235 + }
  2236 + qemu_put_be32s(f, &env->pc);
  2237 + qemu_put_be32s(f, &env->npc);
  2238 + qemu_put_be32s(f, &env->y);
  2239 + tmp = GET_PSR(env);
  2240 + qemu_put_be32s(f, &tmp);
  2241 + qemu_put_be32s(f, &env->fsr);
  2242 + qemu_put_be32s(f, &env->cwp);
  2243 + qemu_put_be32s(f, &env->wim);
  2244 + qemu_put_be32s(f, &env->tbr);
  2245 + /* MMU */
  2246 + for(i = 0; i < 16; i++)
  2247 + qemu_put_be32s(f, &env->mmuregs[i]);
2217 } 2248 }
2218 2249
2219 int cpu_load(QEMUFile *f, void *opaque, int version_id) 2250 int cpu_load(QEMUFile *f, void *opaque, int version_id)
2220 { 2251 {
  2252 + CPUState *env = opaque;
  2253 + int i;
  2254 + uint32_t tmp;
  2255 +
  2256 + for(i = 1; i < 8; i++)
  2257 + qemu_get_be32s(f, &env->gregs[i]);
  2258 + qemu_get_be32s(f, &tmp);
  2259 + env->regwptr = env->regbase + tmp;
  2260 + for(i = 1; i < NWINDOWS * 16 + 8; i++)
  2261 + qemu_get_be32s(f, &env->regbase[i]);
  2262 +
  2263 + /* FPU */
  2264 + for(i = 0; i < 32; i++) {
  2265 + uint64_t mant;
  2266 + uint16_t exp;
  2267 +
  2268 + qemu_get_be64s(f, &mant);
  2269 + qemu_get_be16s(f, &exp);
  2270 + env->fpr[i] = cpu_put_fp64(mant, exp);
  2271 + }
  2272 + qemu_get_be32s(f, &env->pc);
  2273 + qemu_get_be32s(f, &env->npc);
  2274 + qemu_get_be32s(f, &env->y);
  2275 + qemu_get_be32s(f, &tmp);
  2276 + PUT_PSR(env, tmp);
  2277 + qemu_get_be32s(f, &env->fsr);
  2278 + qemu_get_be32s(f, &env->cwp);
  2279 + qemu_get_be32s(f, &env->wim);
  2280 + qemu_get_be32s(f, &env->tbr);
  2281 + /* MMU */
  2282 + for(i = 0; i < 16; i++)
  2283 + qemu_get_be32s(f, &env->mmuregs[i]);
  2284 + tlb_flush(env, 1);
2221 return 0; 2285 return 0;
2222 } 2286 }
2223 #else 2287 #else
@@ -2388,7 +2452,7 @@ void qemu_system_shutdown_request(void) @@ -2388,7 +2452,7 @@ void qemu_system_shutdown_request(void)
2388 2452
2389 static void main_cpu_reset(void *opaque) 2453 static void main_cpu_reset(void *opaque)
2390 { 2454 {
2391 -#ifdef TARGET_I386 2455 +#if defined(TARGET_I386) || defined(TARGET_SPARC)
2392 CPUState *env = opaque; 2456 CPUState *env = opaque;
2393 cpu_reset(env); 2457 cpu_reset(env);
2394 #endif 2458 #endif
@@ -261,7 +261,7 @@ typedef void QEMUTimerCB(void *opaque); @@ -261,7 +261,7 @@ typedef void QEMUTimerCB(void *opaque);
261 Hz. */ 261 Hz. */
262 extern QEMUClock *rt_clock; 262 extern QEMUClock *rt_clock;
263 263
264 -/* Rge virtual clock is only run during the emulation. It is stopped 264 +/* The virtual clock is only run during the emulation. It is stopped
265 when the virtual machine is stopped. Virtual timers use a high 265 when the virtual machine is stopped. Virtual timers use a high
266 precision clock, usually cpu cycles (use ticks_per_sec). */ 266 precision clock, usually cpu cycles (use ticks_per_sec). */
267 extern QEMUClock *vm_clock; 267 extern QEMUClock *vm_clock;
@@ -672,25 +672,38 @@ void sun4m_init(int ram_size, int vga_ram_size, int boot_device, @@ -672,25 +672,38 @@ void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
672 DisplayState *ds, const char **fd_filename, int snapshot, 672 DisplayState *ds, const char **fd_filename, int snapshot,
673 const char *kernel_filename, const char *kernel_cmdline, 673 const char *kernel_filename, const char *kernel_cmdline,
674 const char *initrd_filename); 674 const char *initrd_filename);
  675 +uint32_t iommu_translate(uint32_t addr);
675 676
676 /* iommu.c */ 677 /* iommu.c */
677 -void iommu_init(uint32_t addr);  
678 -uint32_t iommu_translate(uint32_t addr); 678 +void *iommu_init(uint32_t addr);
  679 +uint32_t iommu_translate_local(void *opaque, uint32_t addr);
679 680
680 /* lance.c */ 681 /* lance.c */
681 void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr); 682 void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr);
682 683
683 /* tcx.c */ 684 /* tcx.c */
684 -void tcx_init(DisplayState *ds, uint32_t addr);  
685 -  
686 -/* sched.c */  
687 -void sched_init(); 685 +void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base,
  686 + unsigned long vram_offset, int vram_size);
  687 +void tcx_update_display(void *opaque);
  688 +void tcx_invalidate_display(void *opaque);
  689 +void tcx_screen_dump(void *opaque, const char *filename);
  690 +
  691 +/* slavio_intctl.c */
  692 +void *slavio_intctl_init();
  693 +void slavio_pic_info(void *opaque);
  694 +void slavio_irq_info(void *opaque);
  695 +void slavio_pic_set_irq(void *opaque, int irq, int level);
688 696
689 /* magic-load.c */ 697 /* magic-load.c */
690 -void magic_init(const char *kfn, int kloadaddr, uint32_t addr); 698 +int load_elf(const char *filename, uint8_t *addr);
  699 +int load_aout(const char *filename, uint8_t *addr);
  700 +
  701 +/* slavio_timer.c */
  702 +void slavio_timer_init(uint32_t addr1, int irq1, uint32_t addr2, int irq2);
691 703
692 -/* timer.c */  
693 -void timer_init(uint32_t addr, int irq); 704 +/* slavio_serial.c */
  705 +SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2);
  706 +void slavio_serial_ms_kbd_init(int base, int irq);
694 707
695 /* NVRAM helpers */ 708 /* NVRAM helpers */
696 #include "hw/m48t59.h" 709 #include "hw/m48t59.h"