Commit a541f297a37e64673aac52abc858e0904e316b48

Authored by bellard
1 parent df475d18

PowerPC system emulation fixes (Jocelyn Mayer)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@722 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
@@ -16,8 +16,12 @@ DYNGEN=../dyngen$(EXESUF) @@ -16,8 +16,12 @@ DYNGEN=../dyngen$(EXESUF)
16 QEMU_USER=qemu-$(TARGET_ARCH) 16 QEMU_USER=qemu-$(TARGET_ARCH)
17 # system emulator name 17 # system emulator name
18 ifdef CONFIG_SOFTMMU 18 ifdef CONFIG_SOFTMMU
  19 +ifeq ($(TARGET_ARCH), i386)
19 QEMU_SYSTEM=qemu$(EXESUF) 20 QEMU_SYSTEM=qemu$(EXESUF)
20 else 21 else
  22 +QEMU_SYSTEM=qemu-system-$(TARGET_ARCH)$(EXESUF)
  23 +endif
  24 +else
21 QEMU_SYSTEM=qemu-fast 25 QEMU_SYSTEM=qemu-fast
22 endif 26 endif
23 27
@@ -222,14 +226,23 @@ ifeq ($(ARCH),alpha) @@ -222,14 +226,23 @@ ifeq ($(ARCH),alpha)
222 endif 226 endif
223 227
224 # must use static linking to avoid leaving stuff in virtual address space 228 # must use static linking to avoid leaving stuff in virtual address space
225 -VL_OBJS=vl.o osdep.o block.o monitor.o \  
226 - ide.o ne2000.o pckbd.o vga.o sb16.o dma.o oss.o \  
227 - fdc.o mc146818rtc.o serial.o i8259.o i8254.o pc.o  
228 -ifdef CONFIG_GDBSTUB  
229 -VL_OBJS+=gdbstub.o 229 +VL_OBJS=vl.o osdep.o block.o monitor.o
  230 +
  231 +ifeq ($(TARGET_ARCH), i386)
  232 +# Hardware support
  233 +VL_OBJS+= ide.o ne2000.o pckbd.o vga.o sb16.o dma.o oss.o
  234 +VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pc.o
230 endif 235 endif
231 ifeq ($(TARGET_ARCH), ppc) 236 ifeq ($(TARGET_ARCH), ppc)
232 -VL_OBJS+= hw.o 237 +# Generic PPC support
  238 +VL_OBJS+= ppc.o
  239 +# PREP hardware support
  240 +VL_OBJS+= ide.o ne2000.o pckbd.o vga.o sb16.o dma.o oss.o
  241 +VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o ppc_prep.o
  242 +#VL_OBJS+= hw.o of.o setup.o
  243 +endif
  244 +ifdef CONFIG_GDBSTUB
  245 +VL_OBJS+=gdbstub.o
233 endif 246 endif
234 ifdef CONFIG_SDL 247 ifdef CONFIG_SDL
235 VL_OBJS+=sdl.o 248 VL_OBJS+=sdl.o
configure
@@ -27,7 +27,7 @@ ar="ar" @@ -27,7 +27,7 @@ ar="ar"
27 make="make" 27 make="make"
28 strip="strip" 28 strip="strip"
29 cpu=`uname -m` 29 cpu=`uname -m`
30 -target_list="i386-user i386 i386-softmmu arm-user sparc-user ppc-user" 30 +target_list="i386-user i386 i386-softmmu arm-user sparc-user ppc-user ppc-softmmu"
31 case "$cpu" in 31 case "$cpu" in
32 i386|i486|i586|i686|i86pc|BePC) 32 i386|i486|i586|i686|i86pc|BePC)
33 cpu="i386" 33 cpu="i386"
cpu-exec.c
@@ -190,7 +190,7 @@ int cpu_exec(CPUState *env1) @@ -190,7 +190,7 @@ int cpu_exec(CPUState *env1)
190 (env->eflags & IF_MASK) && 190 (env->eflags & IF_MASK) &&
191 !(env->hflags & HF_INHIBIT_IRQ_MASK)) { 191 !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
192 int intno; 192 int intno;
193 - intno = cpu_x86_get_pic_interrupt(env); 193 + intno = cpu_get_pic_interrupt(env);
194 if (loglevel & CPU_LOG_TB_IN_ASM) { 194 if (loglevel & CPU_LOG_TB_IN_ASM) {
195 fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno); 195 fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
196 } 196 }
exec-all.h
@@ -578,7 +578,13 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) @@ -578,7 +578,13 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
578 #endif 578 #endif
579 if (__builtin_expect(env->tlb_read[is_user][index].address != 579 if (__builtin_expect(env->tlb_read[is_user][index].address !=
580 (addr & TARGET_PAGE_MASK), 0)) { 580 (addr & TARGET_PAGE_MASK), 0)) {
  581 +#if defined (TARGET_PPC)
  582 + env->access_type = ACCESS_CODE;
  583 + ldub_code((void *)addr);
  584 + env->access_type = ACCESS_INT;
  585 +#else
581 ldub_code((void *)addr); 586 ldub_code((void *)addr);
  587 +#endif
582 } 588 }
583 return addr + env->tlb_read[is_user][index].addend - (unsigned long)phys_ram_base; 589 return addr + env->tlb_read[is_user][index].addend - (unsigned long)phys_ram_base;
584 } 590 }
@@ -914,7 +914,7 @@ static void tb_reset_jump_recursive(TranslationBlock *tb) @@ -914,7 +914,7 @@ static void tb_reset_jump_recursive(TranslationBlock *tb)
914 breakpoint is reached */ 914 breakpoint is reached */
915 int cpu_breakpoint_insert(CPUState *env, uint32_t pc) 915 int cpu_breakpoint_insert(CPUState *env, uint32_t pc)
916 { 916 {
917 -#if defined(TARGET_I386) 917 +#if defined(TARGET_I386) || defined(TARGET_PPC)
918 int i; 918 int i;
919 919
920 for(i = 0; i < env->nb_breakpoints; i++) { 920 for(i = 0; i < env->nb_breakpoints; i++) {
@@ -935,7 +935,7 @@ int cpu_breakpoint_insert(CPUState *env, uint32_t pc) @@ -935,7 +935,7 @@ int cpu_breakpoint_insert(CPUState *env, uint32_t pc)
935 /* remove a breakpoint */ 935 /* remove a breakpoint */
936 int cpu_breakpoint_remove(CPUState *env, uint32_t pc) 936 int cpu_breakpoint_remove(CPUState *env, uint32_t pc)
937 { 937 {
938 -#if defined(TARGET_I386) 938 +#if defined(TARGET_I386) || defined(TARGET_PPC)
939 int i; 939 int i;
940 for(i = 0; i < env->nb_breakpoints; i++) { 940 for(i = 0; i < env->nb_breakpoints; i++) {
941 if (env->breakpoints[i] == pc) 941 if (env->breakpoints[i] == pc)
@@ -957,7 +957,7 @@ int cpu_breakpoint_remove(CPUState *env, uint32_t pc) @@ -957,7 +957,7 @@ int cpu_breakpoint_remove(CPUState *env, uint32_t pc)
957 CPU loop after each instruction */ 957 CPU loop after each instruction */
958 void cpu_single_step(CPUState *env, int enabled) 958 void cpu_single_step(CPUState *env, int enabled)
959 { 959 {
960 -#if defined(TARGET_I386) 960 +#if defined(TARGET_I386) || defined(TARGET_PPC)
961 if (env->singlestep_enabled != enabled) { 961 if (env->singlestep_enabled != enabled) {
962 env->singlestep_enabled = enabled; 962 env->singlestep_enabled = enabled;
963 /* must flush all the translated code to avoid inconsistancies */ 963 /* must flush all the translated code to avoid inconsistancies */
gdbstub.c
@@ -220,42 +220,49 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) @@ -220,42 +220,49 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
220 } 220 }
221 221
222 #elif defined (TARGET_PPC) 222 #elif defined (TARGET_PPC)
223 -static void to_le32(uint8_t *p, int v) 223 +static void to_le32(uint32_t *buf, uint32_t v)
224 { 224 {
  225 + uint8_t *p = (uint8_t *)buf;
225 p[3] = v; 226 p[3] = v;
226 p[2] = v >> 8; 227 p[2] = v >> 8;
227 p[1] = v >> 16; 228 p[1] = v >> 16;
228 p[0] = v >> 24; 229 p[0] = v >> 24;
229 } 230 }
230 231
  232 +static uint32_t from_le32 (uint32_t *buf)
  233 +{
  234 + uint8_t *p = (uint8_t *)buf;
  235 +
  236 + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
  237 +}
  238 +
231 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) 239 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
232 { 240 {
233 - uint32_t tmp; 241 + uint32_t *registers = (uint32_t *)mem_buf, tmp;
234 int i; 242 int i;
235 243
236 /* fill in gprs */ 244 /* fill in gprs */
237 - for(i = 0; i < 8; i++) {  
238 - to_le32(mem_buf + i * 4, env->gpr[i]); 245 + for(i = 0; i < 32; i++) {
  246 + to_le32(&registers[i], env->gpr[i]);
239 } 247 }
240 /* fill in fprs */ 248 /* fill in fprs */
241 for (i = 0; i < 32; i++) { 249 for (i = 0; i < 32; i++) {
242 - to_le32(mem_buf + (i * 2) + 32, *((uint32_t *)&env->fpr[i]));  
243 - to_le32(mem_buf + (i * 2) + 33, *((uint32_t *)&env->fpr[i] + 1)); 250 + to_le32(&registers[(i * 2) + 32], *((uint32_t *)&env->fpr[i]));
  251 + to_le32(&registers[(i * 2) + 33], *((uint32_t *)&env->fpr[i] + 1));
244 } 252 }
245 /* nip, msr, ccr, lnk, ctr, xer, mq */ 253 /* nip, msr, ccr, lnk, ctr, xer, mq */
246 - to_le32(mem_buf + 96, tswapl(env->nip));  
247 - to_le32(mem_buf + 97, tswapl(_load_msr()));  
248 - to_le32(mem_buf + 98, 0); 254 + to_le32(&registers[96], (uint32_t)env->nip/* - 4*/);
  255 + to_le32(&registers[97], _load_msr(env));
249 tmp = 0; 256 tmp = 0;
250 for (i = 0; i < 8; i++) 257 for (i = 0; i < 8; i++)
251 - tmp |= env->crf[i] << (32 - (i * 4));  
252 - to_le32(mem_buf + 98, tmp);  
253 - to_le32(mem_buf + 99, tswapl(env->lr));  
254 - to_le32(mem_buf + 100, tswapl(env->ctr));  
255 - to_le32(mem_buf + 101, tswapl(_load_xer()));  
256 - to_le32(mem_buf + 102, 0);  
257 -  
258 - return 102; 258 + tmp |= env->crf[i] << (32 - ((i + 1) * 4));
  259 + to_le32(&registers[98], tmp);
  260 + to_le32(&registers[99], env->lr);
  261 + to_le32(&registers[100], env->ctr);
  262 + to_le32(&registers[101], _load_xer(env));
  263 + to_le32(&registers[102], 0);
  264 +
  265 + return 103 * 4;
259 } 266 }
260 267
261 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) 268 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
@@ -265,22 +272,22 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) @@ -265,22 +272,22 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
265 272
266 /* fill in gprs */ 273 /* fill in gprs */
267 for (i = 0; i < 32; i++) { 274 for (i = 0; i < 32; i++) {
268 - env->gpr[i] = tswapl(registers[i]); 275 + env->gpr[i] = from_le32(&registers[i]);
269 } 276 }
270 /* fill in fprs */ 277 /* fill in fprs */
271 for (i = 0; i < 32; i++) { 278 for (i = 0; i < 32; i++) {
272 - *((uint32_t *)&env->fpr[i]) = tswapl(registers[(i * 2) + 32]);  
273 - *((uint32_t *)&env->fpr[i] + 1) = tswapl(registers[(i * 2) + 33]); 279 + *((uint32_t *)&env->fpr[i]) = from_le32(&registers[(i * 2) + 32]);
  280 + *((uint32_t *)&env->fpr[i] + 1) = from_le32(&registers[(i * 2) + 33]);
274 } 281 }
275 /* nip, msr, ccr, lnk, ctr, xer, mq */ 282 /* nip, msr, ccr, lnk, ctr, xer, mq */
276 - env->nip = tswapl(registers[96]);  
277 - _store_msr(tswapl(registers[97]));  
278 - registers[98] = tswapl(registers[98]); 283 + env->nip = from_le32(&registers[96]);
  284 + _store_msr(env, from_le32(&registers[97]));
  285 + registers[98] = from_le32(&registers[98]);
279 for (i = 0; i < 8; i++) 286 for (i = 0; i < 8; i++)
280 - env->crf[i] = (registers[98] >> (32 - (i * 4))) & 0xF;  
281 - env->lr = tswapl(registers[99]);  
282 - env->ctr = tswapl(registers[100]);  
283 - _store_xer(tswapl(registers[101])); 287 + env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
  288 + env->lr = from_le32(&registers[99]);
  289 + env->ctr = from_le32(&registers[100]);
  290 + _store_xer(env, from_le32(&registers[101]));
284 } 291 }
285 #else 292 #else
286 293
hw/fdc.c
@@ -83,7 +83,6 @@ typedef struct fdrive_t { @@ -83,7 +83,6 @@ typedef struct fdrive_t {
83 uint8_t dir; /* Direction */ 83 uint8_t dir; /* Direction */
84 uint8_t rw; /* Read/write */ 84 uint8_t rw; /* Read/write */
85 /* Media */ 85 /* Media */
86 - fdisk_type_t disk; /* Disk type */  
87 fdisk_flags_t flags; 86 fdisk_flags_t flags;
88 uint8_t last_sect; /* Nb sector per track */ 87 uint8_t last_sect; /* Nb sector per track */
89 uint8_t max_track; /* Nb of tracks */ 88 uint8_t max_track; /* Nb of tracks */
@@ -102,7 +101,6 @@ static void fd_init (fdrive_t *drv, BlockDriverState *bs) @@ -102,7 +101,6 @@ static void fd_init (fdrive_t *drv, BlockDriverState *bs)
102 drv->drflags = 0; 101 drv->drflags = 0;
103 drv->perpendicular = 0; 102 drv->perpendicular = 0;
104 /* Disk */ 103 /* Disk */
105 - drv->disk = FDRIVE_DISK_NONE;  
106 drv->last_sect = 0; 104 drv->last_sect = 0;
107 drv->max_track = 0; 105 drv->max_track = 0;
108 } 106 }
@@ -171,26 +169,113 @@ static void fd_recalibrate (fdrive_t *drv) @@ -171,26 +169,113 @@ static void fd_recalibrate (fdrive_t *drv)
171 drv->rw = 0; 169 drv->rw = 0;
172 } 170 }
173 171
  172 +/* Recognize floppy formats */
  173 +typedef struct fd_format_t {
  174 + fdrive_type_t drive;
  175 + fdisk_type_t disk;
  176 + uint8_t last_sect;
  177 + uint8_t max_track;
  178 + uint8_t max_head;
  179 + const unsigned char *str;
  180 +} fd_format_t;
  181 +
  182 +static fd_format_t fd_formats[] = {
  183 + /* First entry is default format */
  184 + /* 1.44 MB 3"1/2 floppy disks */
  185 + { FDRIVE_DRV_144, FDRIVE_DISK_144, 18, 80, 1, "1.44 MB 3\"1/2", },
  186 + { FDRIVE_DRV_144, FDRIVE_DISK_144, 20, 80, 1, "1.6 MB 3\"1/2", },
  187 + { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 80, 1, "1.68 MB 3\"1/2", },
  188 + { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 82, 1, "1.72 MB 3\"1/2", },
  189 + { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 83, 1, "1.74 MB 3\"1/2", },
  190 + { FDRIVE_DRV_144, FDRIVE_DISK_144, 22, 80, 1, "1.76 MB 3\"1/2", },
  191 + { FDRIVE_DRV_144, FDRIVE_DISK_144, 23, 80, 1, "1.84 MB 3\"1/2", },
  192 + { FDRIVE_DRV_144, FDRIVE_DISK_144, 24, 80, 1, "1.92 MB 3\"1/2", },
  193 + /* 2.88 MB 3"1/2 floppy disks */
  194 + { FDRIVE_DRV_288, FDRIVE_DISK_288, 36, 80, 1, "2.88 MB 3\"1/2", },
  195 + { FDRIVE_DRV_288, FDRIVE_DISK_288, 39, 80, 1, "3.12 MB 3\"1/2", },
  196 + { FDRIVE_DRV_288, FDRIVE_DISK_288, 40, 80, 1, "3.2 MB 3\"1/2", },
  197 + { FDRIVE_DRV_288, FDRIVE_DISK_288, 44, 80, 1, "3.52 MB 3\"1/2", },
  198 + { FDRIVE_DRV_288, FDRIVE_DISK_288, 48, 80, 1, "3.84 MB 3\"1/2", },
  199 + /* 720 kB 3"1/2 floppy disks */
  200 + { FDRIVE_DRV_144, FDRIVE_DISK_720, 9, 80, 1, "720 kB 3\"1/2", },
  201 + { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 80, 1, "800 kB 3\"1/2", },
  202 + { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 82, 1, "820 kB 3\"1/2", },
  203 + { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 83, 1, "830 kB 3\"1/2", },
  204 + { FDRIVE_DRV_144, FDRIVE_DISK_720, 13, 80, 1, "1.04 MB 3\"1/2", },
  205 + { FDRIVE_DRV_144, FDRIVE_DISK_720, 14, 80, 1, "1.12 MB 3\"1/2", },
  206 + /* 1.2 MB 5"1/4 floppy disks */
  207 + { FDRIVE_DRV_120, FDRIVE_DISK_288, 15, 80, 1, "1.2 kB 5\"1/4", },
  208 + { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 80, 1, "1.44 MB 5\"1/4", },
  209 + { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 82, 1, "1.48 MB 5\"1/4", },
  210 + { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 83, 1, "1.49 MB 5\"1/4", },
  211 + { FDRIVE_DRV_120, FDRIVE_DISK_288, 20, 80, 1, "1.6 MB 5\"1/4", },
  212 + /* 720 kB 5"1/4 floppy disks */
  213 + { FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 80, 1, "720 kB 5\"1/4", },
  214 + { FDRIVE_DRV_120, FDRIVE_DISK_288, 11, 80, 1, "880 kB 5\"1/4", },
  215 + /* 360 kB 5"1/4 floppy disks */
  216 + { FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 40, 1, "360 kB 5\"1/4", },
  217 + { FDRIVE_DRV_120, FDRIVE_DISK_288, 9, 40, 0, "180 kB 5\"1/4", },
  218 + { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 41, 1, "410 kB 5\"1/4", },
  219 + { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 42, 1, "420 kB 5\"1/4", },
  220 + /* 320 kB 5"1/4 floppy disks */
  221 + { FDRIVE_DRV_120, FDRIVE_DISK_288, 8, 40, 1, "320 kB 5\"1/4", },
  222 + { FDRIVE_DRV_120, FDRIVE_DISK_288, 8, 40, 0, "160 kB 5\"1/4", },
  223 + /* 360 kB must match 5"1/4 better than 3"1/2... */
  224 + { FDRIVE_DRV_144, FDRIVE_DISK_720, 9, 80, 0, "360 kB 3\"1/2", },
  225 + /* end */
  226 + { FDRIVE_DRV_NONE, FDRIVE_DISK_NONE, -1, -1, 0, NULL, },
  227 +};
  228 +
174 /* Revalidate a disk drive after a disk change */ 229 /* Revalidate a disk drive after a disk change */
175 static void fd_revalidate (fdrive_t *drv) 230 static void fd_revalidate (fdrive_t *drv)
176 { 231 {
177 - int64_t nb_sectors; 232 + fd_format_t *parse;
  233 + int64_t nb_sectors, size;
  234 + int i, first_match, match;
178 int nb_heads, max_track, last_sect, ro; 235 int nb_heads, max_track, last_sect, ro;
179 236
180 FLOPPY_DPRINTF("revalidate\n"); 237 FLOPPY_DPRINTF("revalidate\n");
181 drv->drflags &= ~FDRIVE_REVALIDATE; 238 drv->drflags &= ~FDRIVE_REVALIDATE;
182 -  
183 - /* if no drive present, cannot do more */  
184 - if (!drv->bs)  
185 - return;  
186 -  
187 - if (bdrv_is_inserted(drv->bs)) { 239 + if (drv->bs != NULL && bdrv_is_inserted(drv->bs)) {
188 ro = bdrv_is_read_only(drv->bs); 240 ro = bdrv_is_read_only(drv->bs);
189 - bdrv_get_geometry_hint(drv->bs, &max_track, &nb_heads, &last_sect); 241 + bdrv_get_geometry_hint(drv->bs, &nb_heads, &max_track, &last_sect);
190 if (nb_heads != 0 && max_track != 0 && last_sect != 0) { 242 if (nb_heads != 0 && max_track != 0 && last_sect != 0) {
191 - drv->disk = FDRIVE_DISK_USER;  
192 printf("User defined disk (%d %d %d)", 243 printf("User defined disk (%d %d %d)",
193 nb_heads - 1, max_track, last_sect); 244 nb_heads - 1, max_track, last_sect);
  245 + } else {
  246 + bdrv_get_geometry(drv->bs, &nb_sectors);
  247 + match = -1;
  248 + first_match = -1;
  249 + for (i = 0;; i++) {
  250 + parse = &fd_formats[i];
  251 + if (parse->drive == FDRIVE_DRV_NONE)
  252 + break;
  253 + if (drv->drive == parse->drive ||
  254 + drv->drive == FDRIVE_DRV_NONE) {
  255 + size = (parse->max_head + 1) * parse->max_track *
  256 + parse->last_sect;
  257 + if (nb_sectors == size) {
  258 + match = i;
  259 + break;
  260 + }
  261 + if (first_match == -1)
  262 + first_match = i;
  263 + }
  264 + }
  265 + if (match == -1) {
  266 + if (first_match == -1)
  267 + match = 1;
  268 + else
  269 + match = first_match;
  270 + parse = &fd_formats[match];
  271 + }
  272 + nb_heads = parse->max_head + 1;
  273 + max_track = parse->max_track;
  274 + last_sect = parse->last_sect;
  275 + drv->drive = parse->drive;
  276 + printf("%s floppy disk (%d h %d t %d s) %s\n", parse->str,
  277 + nb_heads, max_track, last_sect, ro ? "ro" : "rw");
  278 + }
194 if (nb_heads == 1) { 279 if (nb_heads == 1) {
195 drv->flags &= ~FDISK_DBL_SIDES; 280 drv->flags &= ~FDISK_DBL_SIDES;
196 } else { 281 } else {
@@ -198,236 +283,9 @@ static void fd_revalidate (fdrive_t *drv) @@ -198,236 +283,9 @@ static void fd_revalidate (fdrive_t *drv)
198 } 283 }
199 drv->max_track = max_track; 284 drv->max_track = max_track;
200 drv->last_sect = last_sect; 285 drv->last_sect = last_sect;
201 - } else {  
202 - bdrv_get_geometry(drv->bs, &nb_sectors);  
203 - switch (nb_sectors) {  
204 - /* 2.88 MB 3"1/2 drive disks */  
205 - case 7680:  
206 - printf("3.84 Mb 3\"1/2 disk (1 80 48)");  
207 - drv->drive = FDRIVE_DRV_288;  
208 - drv->disk = FDRIVE_DISK_288;  
209 - drv->last_sect = 48;  
210 - drv->max_track = 80;  
211 - drv->flags |= FDISK_DBL_SIDES;  
212 - break;  
213 - case 7040:  
214 - printf("3.52 Mb 3\"1/2 disk (1 80 44)");  
215 - drv->drive = FDRIVE_DRV_288;  
216 - drv->disk = FDRIVE_DISK_288;  
217 - drv->last_sect = 44;  
218 - drv->max_track = 80;  
219 - drv->flags |= FDISK_DBL_SIDES;  
220 - break;  
221 - case 6400:  
222 - printf("3.2 Mb 3\"1/2 disk (1 80 40)");  
223 - drv->drive = FDRIVE_DRV_288;  
224 - drv->disk = FDRIVE_DISK_288;  
225 - drv->last_sect = 40;  
226 - drv->max_track = 80;  
227 - drv->flags |= FDISK_DBL_SIDES;  
228 - break;  
229 - case 6240:  
230 - printf("3.12 Mb 3\"1/2 disk (1 80 39)");  
231 - drv->drive = FDRIVE_DRV_288;  
232 - drv->disk = FDRIVE_DISK_288;  
233 - drv->last_sect = 39;  
234 - drv->max_track = 80;  
235 - drv->flags |= FDISK_DBL_SIDES;  
236 - break;  
237 - case 5760:  
238 - printf("2.88 Mb 3\"1/2 disk (1 80 36)");  
239 - drv->drive = FDRIVE_DRV_288;  
240 - drv->disk = FDRIVE_DISK_288;  
241 - drv->last_sect = 36;  
242 - drv->max_track = 80;  
243 - drv->flags |= FDISK_DBL_SIDES;  
244 - break;  
245 -  
246 - /* 1.44 MB 3"1/2 drive disks */  
247 - case 3840:  
248 - printf("1.92 Mb 3\"1/2 disk (1 80 24)");  
249 - drv->drive = FDRIVE_DRV_144;  
250 - drv->disk = FDRIVE_DISK_144;  
251 - drv->last_sect = 24;  
252 - drv->max_track = 80;  
253 - drv->flags |= FDISK_DBL_SIDES;  
254 - break;  
255 - case 3680:  
256 - printf("1.84 Mb 3\"1/2 disk (1 80 23)");  
257 - drv->drive = FDRIVE_DRV_144;  
258 - drv->disk = FDRIVE_DISK_144;  
259 - drv->last_sect = 23;  
260 - drv->max_track = 80;  
261 - drv->flags |= FDISK_DBL_SIDES;  
262 - break;  
263 - case 3520:  
264 - printf("1.76 Mb 3\"1/2 disk (1 80 22)");  
265 - drv->drive = FDRIVE_DRV_144;  
266 - drv->disk = FDRIVE_DISK_144;  
267 - drv->last_sect = 22;  
268 - drv->max_track = 80;  
269 - drv->flags |= FDISK_DBL_SIDES;  
270 - break;  
271 - case 3486:  
272 - printf("1.74 Mb 3\"1/2 disk (1 83 21)");  
273 - drv->drive = FDRIVE_DRV_144;  
274 - drv->disk = FDRIVE_DISK_144;  
275 - drv->last_sect = 21;  
276 - drv->max_track = 83;  
277 - drv->flags |= FDISK_DBL_SIDES;  
278 - break;  
279 - case 3444:  
280 - printf("1.72 Mb 3\"1/2 disk (1 82 21)");  
281 - drv->drive = FDRIVE_DRV_144;  
282 - drv->disk = FDRIVE_DISK_144;  
283 - drv->last_sect = 21;  
284 - drv->max_track = 82;  
285 - drv->flags |= FDISK_DBL_SIDES;  
286 - break;  
287 - case 3360:  
288 - printf("1.68 Mb 3\"1/2 disk (1 80 21)");  
289 - drv->drive = FDRIVE_DRV_144;  
290 - drv->disk = FDRIVE_DISK_144;  
291 - drv->last_sect = 21;  
292 - drv->max_track = 80;  
293 - drv->flags |= FDISK_DBL_SIDES;  
294 - break;  
295 - case 3200:  
296 - printf("1.6 Mb 3\"1/2 disk (1 80 20)");  
297 - drv->drive = FDRIVE_DRV_144;  
298 - drv->disk = FDRIVE_DISK_144;  
299 - drv->last_sect = 20;  
300 - drv->max_track = 80;  
301 - drv->flags |= FDISK_DBL_SIDES;  
302 - break;  
303 - case 2880:  
304 - default:  
305 - printf("1.44 Mb 3\"1/2 disk (1 80 18)");  
306 - drv->drive = FDRIVE_DRV_144;  
307 - drv->disk = FDRIVE_DISK_144;  
308 - drv->last_sect = 18;  
309 - drv->max_track = 80;  
310 - drv->flags |= FDISK_DBL_SIDES;  
311 - break;  
312 -  
313 - /* 720 kB 3"1/2 drive disks */  
314 - case 2240:  
315 - printf("1.12 Mb 3\"1/2 disk (1 80 14)");  
316 - drv->drive = FDRIVE_DRV_144;  
317 - drv->disk = FDRIVE_DISK_720;  
318 - drv->last_sect = 14;  
319 - drv->max_track = 80;  
320 - drv->flags |= FDISK_DBL_SIDES;  
321 - break;  
322 - case 2080:  
323 - printf("1.04 Mb 3\"1/2 disk (1 80 13)");  
324 - drv->drive = FDRIVE_DRV_144;  
325 - drv->disk = FDRIVE_DISK_720;  
326 - drv->last_sect = 13;  
327 - drv->max_track = 80;  
328 - drv->flags |= FDISK_DBL_SIDES;  
329 - break;  
330 - case 1660:  
331 - printf("830 kb 3\"1/2 disk (1 83 10)");  
332 - drv->drive = FDRIVE_DRV_144;  
333 - drv->disk = FDRIVE_DISK_720;  
334 - drv->last_sect = 10;  
335 - drv->max_track = 83;  
336 - drv->flags |= FDISK_DBL_SIDES;  
337 - break;  
338 - case 1640:  
339 - printf("820 kb 3\"1/2 disk (1 82 10)");  
340 - drv->drive = FDRIVE_DRV_144;  
341 - drv->disk = FDRIVE_DISK_720;  
342 - drv->last_sect = 10;  
343 - drv->max_track = 82;  
344 - drv->flags |= FDISK_DBL_SIDES;  
345 - break;  
346 - case 1600:  
347 - printf("800 kb 3\"1/2 disk (1 80 10)");  
348 - drv->drive = FDRIVE_DRV_144;  
349 - drv->disk = FDRIVE_DISK_720;  
350 - drv->last_sect = 10;  
351 - drv->max_track = 80;  
352 - drv->flags |= FDISK_DBL_SIDES;  
353 - break;  
354 - case 1440:  
355 - printf("720 kb 3\"1/2 disk (1 80 9)");  
356 - drv->drive = FDRIVE_DRV_144;  
357 - drv->disk = FDRIVE_DISK_720;  
358 - drv->last_sect = 9;  
359 - drv->max_track = 80;  
360 - drv->flags |= FDISK_DBL_SIDES;  
361 - break;  
362 -  
363 - /* 1.2 MB 5"1/4 drive disks */  
364 - case 2988:  
365 - printf("1.49 Mb 5\"1/4 disk (1 83 18)");  
366 - drv->drive = FDRIVE_DRV_120;  
367 - drv->disk = FDRIVE_DISK_144; /* ? */  
368 - drv->last_sect = 18;  
369 - drv->max_track = 83;  
370 - drv->flags |= FDISK_DBL_SIDES;  
371 - break;  
372 - case 2952:  
373 - printf("1.48 Mb 5\"1/4 disk (1 82 18)");  
374 - drv->drive = FDRIVE_DRV_120;  
375 - drv->disk = FDRIVE_DISK_144; /* ? */  
376 - drv->last_sect = 18;  
377 - drv->max_track = 82;  
378 - drv->flags |= FDISK_DBL_SIDES;  
379 - break;  
380 - case 2400:  
381 - printf("1.2 Mb 5\"1/4 disk (1 80 15)");  
382 - drv->drive = FDRIVE_DRV_120;  
383 - drv->disk = FDRIVE_DISK_144; /* ? */  
384 - drv->last_sect = 15;  
385 - drv->max_track = 80;  
386 - drv->flags |= FDISK_DBL_SIDES;  
387 - break;  
388 -  
389 - case 1760:  
390 - printf("880 kb 5\"1/4 disk (1 80 11)");  
391 - drv->drive = FDRIVE_DRV_120;  
392 - drv->disk = FDRIVE_DISK_144; /* ? */  
393 - drv->last_sect = 11;  
394 - drv->max_track = 80;  
395 - drv->flags |= FDISK_DBL_SIDES;  
396 - break;  
397 -  
398 - /* 360 kB 5"1/4 drive disks */  
399 - case 840:  
400 - /* 420 kB 5"1/4 disk */  
401 - printf("420 kb 5\"1/4 disk (1 42 10)");  
402 - drv->drive = FDRIVE_DRV_120;  
403 - drv->disk = FDRIVE_DISK_144; /* ? */  
404 - drv->last_sect = 10;  
405 - drv->max_track = 42;  
406 - drv->flags |= FDISK_DBL_SIDES;  
407 - case 820:  
408 - /* 410 kB 5"1/4 disk */  
409 - printf("410 kb 5\"1/4 disk (1 41 10)");  
410 - drv->drive = FDRIVE_DRV_120;  
411 - drv->disk = FDRIVE_DISK_144; /* ? */  
412 - drv->last_sect = 10;  
413 - drv->max_track = 41;  
414 - drv->flags |= FDISK_DBL_SIDES;  
415 - case 720:  
416 - /* 360 kB 5"1/4 disk */  
417 - printf("360 kb 5\"1/4 disk (1 40 9)");  
418 - drv->drive = FDRIVE_DRV_120;  
419 - drv->disk = FDRIVE_DISK_144; /* ? */  
420 - drv->last_sect = 9;  
421 - drv->max_track = 40;  
422 - drv->flags |= FDISK_DBL_SIDES;  
423 - break;  
424 - }  
425 - printf(" %s\n", ro == 0 ? "rw" : "ro");  
426 - }  
427 drv->ro = ro; 286 drv->ro = ro;
428 } else { 287 } else {
429 printf("No disk in drive\n"); 288 printf("No disk in drive\n");
430 - drv->disk = FDRIVE_DISK_NONE;  
431 drv->last_sect = 0; 289 drv->last_sect = 0;
432 drv->max_track = 0; 290 drv->max_track = 0;
433 drv->flags &= ~FDISK_DBL_SIDES; 291 drv->flags &= ~FDISK_DBL_SIDES;
@@ -544,20 +402,29 @@ static uint32_t fdctrl_read (void *opaque, uint32_t reg) @@ -544,20 +402,29 @@ static uint32_t fdctrl_read (void *opaque, uint32_t reg)
544 fdctrl_t *fdctrl = opaque; 402 fdctrl_t *fdctrl = opaque;
545 uint32_t retval; 403 uint32_t retval;
546 404
547 - if (reg == fdctrl->io_base + 0x01) 405 + switch (reg & 0x07) {
  406 + case 0x01:
548 retval = fdctrl_read_statusB(fdctrl); 407 retval = fdctrl_read_statusB(fdctrl);
549 - else if (reg == fdctrl->io_base + 0x02) 408 + break;
  409 + case 0x02:
550 retval = fdctrl_read_dor(fdctrl); 410 retval = fdctrl_read_dor(fdctrl);
551 - else if (reg == fdctrl->io_base + 0x03) 411 + break;
  412 + case 0x03:
552 retval = fdctrl_read_tape(fdctrl); 413 retval = fdctrl_read_tape(fdctrl);
553 - else if (reg == fdctrl->io_base + 0x04) 414 + break;
  415 + case 0x04:
554 retval = fdctrl_read_main_status(fdctrl); 416 retval = fdctrl_read_main_status(fdctrl);
555 - else if (reg == fdctrl->io_base + 0x05) 417 + break;
  418 + case 0x05:
556 retval = fdctrl_read_data(fdctrl); 419 retval = fdctrl_read_data(fdctrl);
557 - else if (reg == fdctrl->io_base + 0x07) 420 + break;
  421 + case 0x07:
558 retval = fdctrl_read_dir(fdctrl); 422 retval = fdctrl_read_dir(fdctrl);
559 - else 423 + break;
  424 + default:
560 retval = (uint32_t)(-1); 425 retval = (uint32_t)(-1);
  426 + break;
  427 + }
561 428
562 return retval; 429 return retval;
563 } 430 }
@@ -566,14 +433,22 @@ static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value) @@ -566,14 +433,22 @@ static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value)
566 { 433 {
567 fdctrl_t *fdctrl = opaque; 434 fdctrl_t *fdctrl = opaque;
568 435
569 - if (reg == fdctrl->io_base + 0x02) 436 + switch (reg & 0x07) {
  437 + case 0x02:
570 fdctrl_write_dor(fdctrl, value); 438 fdctrl_write_dor(fdctrl, value);
571 - else if (reg == fdctrl->io_base + 0x03) 439 + break;
  440 + case 0x03:
572 fdctrl_write_tape(fdctrl, value); 441 fdctrl_write_tape(fdctrl, value);
573 - else if (reg == fdctrl->io_base + 0x04) 442 + break;
  443 + case 0x04:
574 fdctrl_write_rate(fdctrl, value); 444 fdctrl_write_rate(fdctrl, value);
575 - else if (reg == fdctrl->io_base + 0x05) 445 + break;
  446 + case 0x05:
576 fdctrl_write_data(fdctrl, value); 447 fdctrl_write_data(fdctrl, value);
  448 + break;
  449 + default:
  450 + break;
  451 + }
577 } 452 }
578 453
579 static void fd_change_cb (void *opaque) 454 static void fd_change_cb (void *opaque)
@@ -581,7 +456,6 @@ static void fd_change_cb (void *opaque) @@ -581,7 +456,6 @@ static void fd_change_cb (void *opaque)
581 fdrive_t *drv = opaque; 456 fdrive_t *drv = opaque;
582 457
583 FLOPPY_DPRINTF("disk change\n"); 458 FLOPPY_DPRINTF("disk change\n");
584 - /* TODO: use command-line parameters to force geometry */  
585 fd_revalidate(drv); 459 fd_revalidate(drv);
586 #if 0 460 #if 0
587 fd_recalibrate(drv); 461 fd_recalibrate(drv);
@@ -606,7 +480,7 @@ fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, @@ -606,7 +480,7 @@ fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
606 fdctrl->irq_lvl = irq_lvl; 480 fdctrl->irq_lvl = irq_lvl;
607 fdctrl->dma_chann = dma_chann; 481 fdctrl->dma_chann = dma_chann;
608 fdctrl->io_base = io_base; 482 fdctrl->io_base = io_base;
609 - fdctrl->config = 0x40; /* Implicit seek, polling & FIFO enabled */ 483 + fdctrl->config = 0x60; /* Implicit seek, polling & FIFO enabled */
610 if (fdctrl->dma_chann != -1) { 484 if (fdctrl->dma_chann != -1) {
611 fdctrl->dma_en = 1; 485 fdctrl->dma_en = 1;
612 DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl); 486 DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
@@ -634,9 +508,10 @@ fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, @@ -634,9 +508,10 @@ fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
634 register_ioport_write(io_base + 0x01, 5, 1, &fdctrl_write, fdctrl); 508 register_ioport_write(io_base + 0x01, 5, 1, &fdctrl_write, fdctrl);
635 register_ioport_write(io_base + 0x07, 1, 1, &fdctrl_write, fdctrl); 509 register_ioport_write(io_base + 0x07, 1, 1, &fdctrl_write, fdctrl);
636 } 510 }
637 - for (i = 0; i < MAX_FD; i++) { 511 + for (i = 0; i < 2; i++) {
638 fd_revalidate(&fdctrl->drives[i]); 512 fd_revalidate(&fdctrl->drives[i]);
639 } 513 }
  514 +
640 return fdctrl; 515 return fdctrl;
641 } 516 }
642 517
hw/i8259.c
@@ -174,7 +174,7 @@ static inline void pic_intack(PicState *s, int irq) @@ -174,7 +174,7 @@ static inline void pic_intack(PicState *s, int irq)
174 s->irr &= ~(1 << irq); 174 s->irr &= ~(1 << irq);
175 } 175 }
176 176
177 -int cpu_x86_get_pic_interrupt(CPUState *env) 177 +int cpu_get_pic_interrupt(CPUState *env)
178 { 178 {
179 int irq, irq2, intno; 179 int irq, irq2, intno;
180 180
hw/m48t59.c 0 โ†’ 100644
  1 +/*
  2 + * QEMU M48T59 NVRAM emulation for PPC PREP platform
  3 + *
  4 + * Copyright (c) 2003-2004 Jocelyn Mayer
  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 +
  25 +#include <stdlib.h>
  26 +#include <stdio.h> /* needed by vl.h */
  27 +#include <stdint.h>
  28 +#include <string.h>
  29 +#include <time.h>
  30 +
  31 +#include "vl.h"
  32 +
  33 +//#define NVRAM_DEBUG
  34 +
  35 +#if defined(NVRAM_DEBUG)
  36 +#define NVRAM_PRINTF(fmt, args...) do { printf(fmt , ##args); } while (0)
  37 +#else
  38 +#define NVRAM_PRINTF(fmt, args...) do { } while (0)
  39 +#endif
  40 +
  41 +typedef struct m48t59_t {
  42 + /* Hardware parameters */
  43 + int IRQ;
  44 + uint32_t io_base;
  45 + uint16_t size;
  46 + /* RTC management */
  47 + time_t time_offset;
  48 + time_t stop_time;
  49 + /* Alarm & watchdog */
  50 + time_t alarm;
  51 + struct QEMUTimer *alrm_timer;
  52 + struct QEMUTimer *wd_timer;
  53 + /* NVRAM storage */
  54 + uint16_t addr;
  55 + uint8_t *buffer;
  56 +} m48t59_t;
  57 +
  58 +static m48t59_t *NVRAMs;
  59 +static int nb_NVRAMs;
  60 +
  61 +/* Fake timer functions */
  62 +/* Generic helpers for BCD */
  63 +static inline uint8_t toBCD (uint8_t value)
  64 +{
  65 + return (((value / 10) % 10) << 4) | (value % 10);
  66 +}
  67 +
  68 +static inline uint8_t fromBCD (uint8_t BCD)
  69 +{
  70 + return ((BCD >> 4) * 10) + (BCD & 0x0F);
  71 +}
  72 +
  73 +/* RTC management helpers */
  74 +static void get_time (m48t59_t *NVRAM, struct tm *tm)
  75 +{
  76 + time_t t;
  77 +
  78 + t = time(NULL) + NVRAM->time_offset;
  79 + localtime_r(&t, tm);
  80 +}
  81 +
  82 +static void set_time (m48t59_t *NVRAM, struct tm *tm)
  83 +{
  84 + time_t now, new_time;
  85 +
  86 + new_time = mktime(tm);
  87 + now = time(NULL);
  88 + NVRAM->time_offset = new_time - now;
  89 +}
  90 +
  91 +/* Alarm management */
  92 +static void alarm_cb (void *opaque)
  93 +{
  94 + struct tm tm, tm_now;
  95 + uint64_t next_time;
  96 + m48t59_t *NVRAM = opaque;
  97 +
  98 + pic_set_irq(NVRAM->IRQ, 1);
  99 + if ((NVRAM->buffer[0x1FF5] & 0x80) == 0 &&
  100 + (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
  101 + (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
  102 + (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
  103 + /* Repeat once a month */
  104 + get_time(NVRAM, &tm_now);
  105 + memcpy(&tm, &tm_now, sizeof(struct tm));
  106 + tm.tm_mon++;
  107 + if (tm.tm_mon == 13) {
  108 + tm.tm_mon = 1;
  109 + tm.tm_year++;
  110 + }
  111 + next_time = mktime(&tm);
  112 + } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
  113 + (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
  114 + (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
  115 + (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
  116 + /* Repeat once a day */
  117 + next_time = 24 * 60 * 60 + mktime(&tm_now);
  118 + } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
  119 + (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
  120 + (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
  121 + (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
  122 + /* Repeat once an hour */
  123 + next_time = 60 * 60 + mktime(&tm_now);
  124 + } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
  125 + (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
  126 + (NVRAM->buffer[0x1FF3] & 0x80) != 0 &&
  127 + (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
  128 + /* Repeat once a minute */
  129 + next_time = 60 + mktime(&tm_now);
  130 + } else {
  131 + /* Repeat once a second */
  132 + next_time = 1 + mktime(&tm_now);
  133 + }
  134 + qemu_mod_timer(NVRAM->alrm_timer, next_time * 1000);
  135 + pic_set_irq(NVRAM->IRQ, 0);
  136 +}
  137 +
  138 +
  139 +static void get_alarm (m48t59_t *NVRAM, struct tm *tm)
  140 +{
  141 + localtime_r(&NVRAM->alarm, tm);
  142 +}
  143 +
  144 +static void set_alarm (m48t59_t *NVRAM, struct tm *tm)
  145 +{
  146 + NVRAM->alarm = mktime(tm);
  147 + if (NVRAM->alrm_timer != NULL) {
  148 + qemu_del_timer(NVRAM->alrm_timer);
  149 + NVRAM->alrm_timer = NULL;
  150 + }
  151 + if (NVRAM->alarm - time(NULL) > 0)
  152 + qemu_mod_timer(NVRAM->alrm_timer, NVRAM->alarm * 1000);
  153 +}
  154 +
  155 +/* Watchdog management */
  156 +static void watchdog_cb (void *opaque)
  157 +{
  158 + m48t59_t *NVRAM = opaque;
  159 +
  160 + NVRAM->buffer[0x1FF0] |= 0x80;
  161 + if (NVRAM->buffer[0x1FF7] & 0x80) {
  162 + NVRAM->buffer[0x1FF7] = 0x00;
  163 + NVRAM->buffer[0x1FFC] &= ~0x40;
  164 + // reset_CPU();
  165 + } else {
  166 + pic_set_irq(NVRAM->IRQ, 1);
  167 + pic_set_irq(NVRAM->IRQ, 0);
  168 + }
  169 +}
  170 +
  171 +static void set_up_watchdog (m48t59_t *NVRAM, uint8_t value)
  172 +{
  173 + uint64_t interval; /* in 1/16 seconds */
  174 +
  175 + if (NVRAM->wd_timer != NULL) {
  176 + qemu_del_timer(NVRAM->wd_timer);
  177 + NVRAM->wd_timer = NULL;
  178 + }
  179 + NVRAM->buffer[0x1FF0] &= ~0x80;
  180 + if (value != 0) {
  181 + interval = (1 << (2 * (value & 0x03))) * ((value >> 2) & 0x1F);
  182 + qemu_mod_timer(NVRAM->wd_timer, ((uint64_t)time(NULL) * 1000) +
  183 + ((interval * 1000) >> 4));
  184 + }
  185 +}
  186 +
  187 +/* Direct access to NVRAM */
  188 +void m48t59_write (void *opaque, uint32_t val)
  189 +{
  190 + m48t59_t *NVRAM = opaque;
  191 + struct tm tm;
  192 + int tmp;
  193 +
  194 + if (NVRAM->addr > 0x1FF8 && NVRAM->addr < 0x2000)
  195 + NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, NVRAM->addr, val);
  196 + switch (NVRAM->addr) {
  197 + case 0x1FF0:
  198 + /* flags register : read-only */
  199 + break;
  200 + case 0x1FF1:
  201 + /* unused */
  202 + break;
  203 + case 0x1FF2:
  204 + /* alarm seconds */
  205 + tmp = fromBCD(val & 0x7F);
  206 + if (tmp >= 0 && tmp <= 59) {
  207 + get_alarm(NVRAM, &tm);
  208 + tm.tm_sec = tmp;
  209 + NVRAM->buffer[0x1FF2] = val;
  210 + set_alarm(NVRAM, &tm);
  211 + }
  212 + break;
  213 + case 0x1FF3:
  214 + /* alarm minutes */
  215 + tmp = fromBCD(val & 0x7F);
  216 + if (tmp >= 0 && tmp <= 59) {
  217 + get_alarm(NVRAM, &tm);
  218 + tm.tm_min = tmp;
  219 + NVRAM->buffer[0x1FF3] = val;
  220 + set_alarm(NVRAM, &tm);
  221 + }
  222 + break;
  223 + case 0x1FF4:
  224 + /* alarm hours */
  225 + tmp = fromBCD(val & 0x3F);
  226 + if (tmp >= 0 && tmp <= 23) {
  227 + get_alarm(NVRAM, &tm);
  228 + tm.tm_hour = tmp;
  229 + NVRAM->buffer[0x1FF4] = val;
  230 + set_alarm(NVRAM, &tm);
  231 + }
  232 + break;
  233 + case 0x1FF5:
  234 + /* alarm date */
  235 + tmp = fromBCD(val & 0x1F);
  236 + if (tmp != 0) {
  237 + get_alarm(NVRAM, &tm);
  238 + tm.tm_mday = tmp;
  239 + NVRAM->buffer[0x1FF5] = val;
  240 + set_alarm(NVRAM, &tm);
  241 + }
  242 + break;
  243 + case 0x1FF6:
  244 + /* interrupts */
  245 + NVRAM->buffer[0x1FF6] = val;
  246 + break;
  247 + case 0x1FF7:
  248 + /* watchdog */
  249 + NVRAM->buffer[0x1FF7] = val;
  250 + set_up_watchdog(NVRAM, val);
  251 + break;
  252 + case 0x1FF8:
  253 + /* control */
  254 + NVRAM->buffer[0x1FF8] = (val & ~0xA0) | 0x90;
  255 + break;
  256 + case 0x1FF9:
  257 + /* seconds (BCD) */
  258 + tmp = fromBCD(val & 0x7F);
  259 + if (tmp >= 0 && tmp <= 59) {
  260 + get_time(NVRAM, &tm);
  261 + tm.tm_sec = tmp;
  262 + set_time(NVRAM, &tm);
  263 + }
  264 + if ((val & 0x80) ^ (NVRAM->buffer[0x1FF9] & 0x80)) {
  265 + if (val & 0x80) {
  266 + NVRAM->stop_time = time(NULL);
  267 + } else {
  268 + NVRAM->time_offset += NVRAM->stop_time - time(NULL);
  269 + NVRAM->stop_time = 0;
  270 + }
  271 + }
  272 + NVRAM->buffer[0x1FF9] = val & 0x80;
  273 + break;
  274 + case 0x1FFA:
  275 + /* minutes (BCD) */
  276 + tmp = fromBCD(val & 0x7F);
  277 + if (tmp >= 0 && tmp <= 59) {
  278 + get_time(NVRAM, &tm);
  279 + tm.tm_min = tmp;
  280 + set_time(NVRAM, &tm);
  281 + }
  282 + break;
  283 + case 0x1FFB:
  284 + /* hours (BCD) */
  285 + tmp = fromBCD(val & 0x3F);
  286 + if (tmp >= 0 && tmp <= 23) {
  287 + get_time(NVRAM, &tm);
  288 + tm.tm_hour = tmp;
  289 + set_time(NVRAM, &tm);
  290 + }
  291 + break;
  292 + case 0x1FFC:
  293 + /* day of the week / century */
  294 + tmp = fromBCD(val & 0x07);
  295 + get_time(NVRAM, &tm);
  296 + tm.tm_wday = tmp;
  297 + set_time(NVRAM, &tm);
  298 + NVRAM->buffer[0x1FFC] = val & 0x40;
  299 + break;
  300 + case 0x1FFD:
  301 + /* date */
  302 + tmp = fromBCD(val & 0x1F);
  303 + if (tmp != 0) {
  304 + get_time(NVRAM, &tm);
  305 + tm.tm_mday = tmp;
  306 + set_time(NVRAM, &tm);
  307 + }
  308 + break;
  309 + case 0x1FFE:
  310 + /* month */
  311 + tmp = fromBCD(val & 0x1F);
  312 + if (tmp >= 1 && tmp <= 12) {
  313 + get_time(NVRAM, &tm);
  314 + tm.tm_mon = tmp - 1;
  315 + set_time(NVRAM, &tm);
  316 + }
  317 + break;
  318 + case 0x1FFF:
  319 + /* year */
  320 + tmp = fromBCD(val);
  321 + if (tmp >= 0 && tmp <= 99) {
  322 + get_time(NVRAM, &tm);
  323 + tm.tm_year = fromBCD(val);
  324 + set_time(NVRAM, &tm);
  325 + }
  326 + break;
  327 + default:
  328 + if (NVRAM->addr < 0x1FF0 ||
  329 + (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {
  330 + NVRAM->buffer[NVRAM->addr] = val & 0xFF;
  331 + }
  332 + break;
  333 + }
  334 +}
  335 +
  336 +uint32_t m48t59_read (void *opaque)
  337 +{
  338 + m48t59_t *NVRAM = opaque;
  339 + struct tm tm;
  340 + uint32_t retval = 0xFF;
  341 +
  342 + switch (NVRAM->addr) {
  343 + case 0x1FF0:
  344 + /* flags register */
  345 + goto do_read;
  346 + case 0x1FF1:
  347 + /* unused */
  348 + retval = 0;
  349 + break;
  350 + case 0x1FF2:
  351 + /* alarm seconds */
  352 + goto do_read;
  353 + case 0x1FF3:
  354 + /* alarm minutes */
  355 + goto do_read;
  356 + case 0x1FF4:
  357 + /* alarm hours */
  358 + goto do_read;
  359 + case 0x1FF5:
  360 + /* alarm date */
  361 + goto do_read;
  362 + case 0x1FF6:
  363 + /* interrupts */
  364 + goto do_read;
  365 + case 0x1FF7:
  366 + /* A read resets the watchdog */
  367 + set_up_watchdog(NVRAM, NVRAM->buffer[0x1FF7]);
  368 + goto do_read;
  369 + case 0x1FF8:
  370 + /* control */
  371 + goto do_read;
  372 + case 0x1FF9:
  373 + /* seconds (BCD) */
  374 + get_time(NVRAM, &tm);
  375 + retval = (NVRAM->buffer[0x1FF9] & 0x80) | toBCD(tm.tm_sec);
  376 + break;
  377 + case 0x1FFA:
  378 + /* minutes (BCD) */
  379 + get_time(NVRAM, &tm);
  380 + retval = toBCD(tm.tm_min);
  381 + break;
  382 + case 0x1FFB:
  383 + /* hours (BCD) */
  384 + get_time(NVRAM, &tm);
  385 + retval = toBCD(tm.tm_hour);
  386 + break;
  387 + case 0x1FFC:
  388 + /* day of the week / century */
  389 + get_time(NVRAM, &tm);
  390 + retval = NVRAM->buffer[0x1FFC] | tm.tm_wday;
  391 + break;
  392 + case 0x1FFD:
  393 + /* date */
  394 + get_time(NVRAM, &tm);
  395 + retval = toBCD(tm.tm_mday);
  396 + break;
  397 + case 0x1FFE:
  398 + /* month */
  399 + get_time(NVRAM, &tm);
  400 + retval = toBCD(tm.tm_mon + 1);
  401 + break;
  402 + case 0x1FFF:
  403 + /* year */
  404 + get_time(NVRAM, &tm);
  405 + retval = toBCD(tm.tm_year);
  406 + break;
  407 + default:
  408 + if (NVRAM->addr < 0x1FF0 ||
  409 + (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {
  410 + do_read:
  411 + retval = NVRAM->buffer[NVRAM->addr];
  412 + }
  413 + break;
  414 + }
  415 + if (NVRAM->addr > 0x1FF9 && NVRAM->addr < 0x2000)
  416 + NVRAM_PRINTF("0x%08x <= 0x%08x\n", NVRAM->addr, retval);
  417 +
  418 + return retval;
  419 +}
  420 +
  421 +void m48t59_set_addr (void *opaque, uint32_t addr)
  422 +{
  423 + m48t59_t *NVRAM = opaque;
  424 +
  425 + NVRAM->addr = addr;
  426 +}
  427 +
  428 +/* IO access to NVRAM */
  429 +static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val)
  430 +{
  431 + m48t59_t *NVRAM = opaque;
  432 +
  433 + addr -= NVRAM->io_base;
  434 + switch (addr) {
  435 + case 0:
  436 + NVRAM->addr &= ~0x00FF;
  437 + NVRAM->addr |= val;
  438 + break;
  439 + case 1:
  440 + NVRAM->addr &= ~0xFF00;
  441 + NVRAM->addr |= val << 8;
  442 + break;
  443 + case 3:
  444 + m48t59_write(NVRAM, val);
  445 + NVRAM->addr = 0x0000;
  446 + break;
  447 + default:
  448 + break;
  449 + }
  450 +}
  451 +
  452 +static uint32_t NVRAM_readb (void *opaque, uint32_t addr)
  453 +{
  454 + m48t59_t *NVRAM = opaque;
  455 +
  456 + if (addr == NVRAM->io_base + 3)
  457 + return m48t59_read(NVRAM);
  458 +
  459 + return 0xFF;
  460 +}
  461 +
  462 +/* Initialisation routine */
  463 +void *m48t59_init (int IRQ, uint32_t io_base, uint16_t size)
  464 +{
  465 + m48t59_t *tmp;
  466 +
  467 + tmp = realloc(NVRAMs, (nb_NVRAMs + 1) * sizeof(m48t59_t));
  468 + if (tmp == NULL)
  469 + return NULL;
  470 + NVRAMs = tmp;
  471 + tmp[nb_NVRAMs].buffer = malloc(size);
  472 + if (tmp[nb_NVRAMs].buffer == NULL)
  473 + return NULL;
  474 + memset(tmp[nb_NVRAMs].buffer, 0, size);
  475 + tmp[nb_NVRAMs].IRQ = IRQ;
  476 + tmp[nb_NVRAMs].size = size;
  477 + tmp[nb_NVRAMs].io_base = io_base;
  478 + tmp[nb_NVRAMs].addr = 0;
  479 + register_ioport_read(io_base, 0x04, 1, NVRAM_readb, &NVRAMs[nb_NVRAMs]);
  480 + register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, &NVRAMs[nb_NVRAMs]);
  481 + tmp[nb_NVRAMs].alrm_timer = qemu_new_timer(vm_clock, &alarm_cb,
  482 + &tmp[nb_NVRAMs]);
  483 + tmp[nb_NVRAMs].wd_timer = qemu_new_timer(vm_clock, &watchdog_cb,
  484 + &tmp[nb_NVRAMs]);
  485 + return &NVRAMs[nb_NVRAMs++];
  486 +}
hw/m48t59.h 0 โ†’ 100644
  1 +#if !defined (__M48T59_H__)
  2 +#define __M48T59_H__
  3 +
  4 +void m48t59_write (void *opaque, uint32_t val);
  5 +uint32_t m48t59_read (void *opaque);
  6 +void m48t59_set_addr (void *opaque, uint32_t addr);
  7 +void *m48t59_init (int IRQ, uint32_t io_base, uint16_t size);
  8 +
  9 +#endif /* !defined (__M48T59_H__) */
hw/ne2000.c
@@ -146,6 +146,10 @@ static void ne2000_update_irq(NE2000State *s) @@ -146,6 +146,10 @@ static void ne2000_update_irq(NE2000State *s)
146 { 146 {
147 int isr; 147 int isr;
148 isr = s->isr & s->imr; 148 isr = s->isr & s->imr;
  149 +#if defined(DEBUG_NE2000)
  150 + printf("NE2000: Set IRQ line %d to %d (%02x %02x)\n",
  151 + s->irq, isr ? 1 : 0, s->isr, s->imr);
  152 +#endif
149 if (isr) 153 if (isr)
150 pic_set_irq(s->irq, 1); 154 pic_set_irq(s->irq, 1);
151 else 155 else
hw/ppc.c 0 โ†’ 100644
  1 +/*
  2 + * QEMU generic PPC hardware System Emulator
  3 + *
  4 + * Copyright (c) 2003-2004 Jocelyn Mayer
  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 +
  25 +#include <stdio.h>
  26 +#include "vl.h"
  27 +
  28 +void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
  29 + DisplayState *ds, const char **fd_filename, int snapshot,
  30 + const char *kernel_filename, const char *kernel_cmdline,
  31 + const char *initrd_filename);
  32 +
  33 +void ppc_init (int ram_size, int vga_ram_size, int boot_device,
  34 + DisplayState *ds, const char **fd_filename, int snapshot,
  35 + const char *kernel_filename, const char *kernel_cmdline,
  36 + const char *initrd_filename)
  37 +{
  38 + /* For now, only PREP is supported */
  39 + return ppc_prep_init(ram_size, vga_ram_size, boot_device, ds, fd_filename,
  40 + snapshot, kernel_filename, kernel_cmdline,
  41 + initrd_filename);
  42 +}
target-ppc/hw.c renamed to hw/ppc_prep.c
1 /* 1 /*
2 - * Hardware simulation for PPC target.  
3 - * For now, this is only a 'minimal' collection of hacks needed to boot Linux. 2 + * QEMU PPC PREP hardware System Emulator
  3 + *
  4 + * Copyright (c) 2003-2004 Jocelyn Mayer
  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.
4 */ 23 */
5 -  
6 #include <stdlib.h> 24 #include <stdlib.h>
7 #include <stdio.h> 25 #include <stdio.h>
8 #include <stdarg.h> 26 #include <stdarg.h>
9 #include <string.h> 27 #include <string.h>
10 -#include <ctype.h>  
11 -#include <unistd.h>  
12 -#include <fcntl.h> 28 +#include <getopt.h>
13 #include <inttypes.h> 29 #include <inttypes.h>
14 #include <unistd.h> 30 #include <unistd.h>
  31 +#include <sys/mman.h>
  32 +#include <fcntl.h>
  33 +#include <signal.h>
15 #include <time.h> 34 #include <time.h>
  35 +#include <sys/time.h>
  36 +#include <malloc.h>
  37 +#include <termios.h>
  38 +#include <sys/poll.h>
  39 +#include <errno.h>
  40 +#include <sys/wait.h>
  41 +#include <netinet/in.h>
16 42
17 #include "cpu.h" 43 #include "cpu.h"
18 #include "vl.h" 44 #include "vl.h"
  45 +#include "m48t59.h"
19 46
20 //#define HARD_DEBUG_PPC_IO 47 //#define HARD_DEBUG_PPC_IO
21 -#define DEBUG_PPC_IO 48 +//#define DEBUG_PPC_IO
22 49
23 extern int loglevel; 50 extern int loglevel;
24 extern FILE *logfile; 51 extern FILE *logfile;
@@ -47,24 +74,68 @@ do { \ @@ -47,24 +74,68 @@ do { \
47 #define PPC_IO_DPRINTF(fmt, args...) do { } while (0) 74 #define PPC_IO_DPRINTF(fmt, args...) do { } while (0)
48 #endif 75 #endif
49 76
50 -#if defined (USE_OPEN_FIRMWARE)  
51 -#include "of.h"  
52 -#else  
53 -#define NVRAM_SIZE 0x2000  
54 -#endif 77 +#define BIOS_FILENAME "ppc_rom.bin"
  78 +#define LINUX_BOOT_FILENAME "linux_boot.bin"
  79 +
  80 +#define KERNEL_LOAD_ADDR 0x00000000
  81 +#define KERNEL_STACK_ADDR 0x00400000
  82 +#define INITRD_LOAD_ADDR 0x00800000
  83 +
  84 +int load_kernel(const char *filename, uint8_t *addr,
  85 + uint8_t *real_addr)
  86 +{
  87 + int fd, size;
  88 + int setup_sects;
  89 +
  90 + fd = open(filename, O_RDONLY);
  91 + if (fd < 0)
  92 + return -1;
  93 +
  94 + /* load 16 bit code */
  95 + if (read(fd, real_addr, 512) != 512)
  96 + goto fail;
  97 + setup_sects = real_addr[0x1F1];
  98 + if (!setup_sects)
  99 + setup_sects = 4;
  100 + if (read(fd, real_addr + 512, setup_sects * 512) !=
  101 + setup_sects * 512)
  102 + goto fail;
  103 +
  104 + /* load 32 bit code */
  105 + size = read(fd, addr, 16 * 1024 * 1024);
  106 + if (size < 0)
  107 + goto fail;
  108 + close(fd);
  109 + return size;
  110 + fail:
  111 + close(fd);
  112 + return -1;
  113 +}
  114 +
  115 +static const int ide_iobase[2] = { 0x1f0, 0x170 };
  116 +static const int ide_iobase2[2] = { 0x3f6, 0x376 };
  117 +static const int ide_irq[2] = { 13, 13 };
  118 +
  119 +#define NE2000_NB_MAX 6
  120 +
  121 +static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
  122 +static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
55 123
56 /* IO ports emulation */ 124 /* IO ports emulation */
57 #define PPC_IO_BASE 0x80000000 125 #define PPC_IO_BASE 0x80000000
58 126
59 -static void PPC_io_writeb (uint32_t addr, uint32_t value) 127 +static void PPC_io_writeb (uint32_t addr, uint32_t value, uint32_t vaddr)
60 { 128 {
61 /* Don't polute serial port output */ 129 /* Don't polute serial port output */
  130 +#if 0
62 if ((addr < 0x800003F0 || addr > 0x80000400) && 131 if ((addr < 0x800003F0 || addr > 0x80000400) &&
63 (addr < 0x80000074 || addr > 0x80000077) && 132 (addr < 0x80000074 || addr > 0x80000077) &&
64 (addr < 0x80000020 || addr > 0x80000021) && 133 (addr < 0x80000020 || addr > 0x80000021) &&
65 (addr < 0x800000a0 || addr > 0x800000a1) && 134 (addr < 0x800000a0 || addr > 0x800000a1) &&
66 (addr < 0x800001f0 || addr > 0x800001f7) && 135 (addr < 0x800001f0 || addr > 0x800001f7) &&
67 - (addr < 0x80000170 || addr > 0x80000177)) { 136 + (addr < 0x80000170 || addr > 0x80000177))
  137 +#endif
  138 + {
68 PPC_IO_DPRINTF("0x%08x => 0x%02x\n", addr - PPC_IO_BASE, value); 139 PPC_IO_DPRINTF("0x%08x => 0x%02x\n", addr - PPC_IO_BASE, value);
69 } 140 }
70 cpu_outb(NULL, addr - PPC_IO_BASE, value); 141 cpu_outb(NULL, addr - PPC_IO_BASE, value);
@@ -74,20 +145,23 @@ static uint32_t PPC_io_readb (uint32_t addr) @@ -74,20 +145,23 @@ static uint32_t PPC_io_readb (uint32_t addr)
74 { 145 {
75 uint32_t ret = cpu_inb(NULL, addr - PPC_IO_BASE); 146 uint32_t ret = cpu_inb(NULL, addr - PPC_IO_BASE);
76 147
  148 +#if 0
77 if ((addr < 0x800003F0 || addr > 0x80000400) && 149 if ((addr < 0x800003F0 || addr > 0x80000400) &&
78 (addr < 0x80000074 || addr > 0x80000077) && 150 (addr < 0x80000074 || addr > 0x80000077) &&
79 (addr < 0x80000020 || addr > 0x80000021) && 151 (addr < 0x80000020 || addr > 0x80000021) &&
80 (addr < 0x800000a0 || addr > 0x800000a1) && 152 (addr < 0x800000a0 || addr > 0x800000a1) &&
81 (addr < 0x800001f0 || addr > 0x800001f7) && 153 (addr < 0x800001f0 || addr > 0x800001f7) &&
82 (addr < 0x80000170 || addr > 0x80000177) && 154 (addr < 0x80000170 || addr > 0x80000177) &&
83 - (addr < 0x8000060 || addr > 0x8000064)) {  
84 -// PPC_IO_DPRINTF("0x%08x <= 0x%02x\n", addr - PPC_IO_BASE, ret); 155 + (addr < 0x8000060 || addr > 0x8000064))
  156 +#endif
  157 + {
  158 + PPC_IO_DPRINTF("0x%08x <= 0x%02x\n", addr - PPC_IO_BASE, ret);
85 } 159 }
86 160
87 return ret; 161 return ret;
88 } 162 }
89 163
90 -static void PPC_io_writew (uint32_t addr, uint32_t value) 164 +static void PPC_io_writew (uint32_t addr, uint32_t value, uint32_t vaddr)
91 { 165 {
92 if ((addr < 0x800001f0 || addr > 0x800001f7) && 166 if ((addr < 0x800001f0 || addr > 0x800001f7) &&
93 (addr < 0x80000170 || addr > 0x80000177)) { 167 (addr < 0x80000170 || addr > 0x80000177)) {
@@ -108,7 +182,7 @@ static uint32_t PPC_io_readw (uint32_t addr) @@ -108,7 +182,7 @@ static uint32_t PPC_io_readw (uint32_t addr)
108 return ret; 182 return ret;
109 } 183 }
110 184
111 -static void PPC_io_writel (uint32_t addr, uint32_t value) 185 +static void PPC_io_writel (uint32_t addr, uint32_t value, uint32_t vaddr)
112 { 186 {
113 PPC_IO_DPRINTF("0x%08x => 0x%08x\n", addr - PPC_IO_BASE, value); 187 PPC_IO_DPRINTF("0x%08x => 0x%08x\n", addr - PPC_IO_BASE, value);
114 cpu_outl(NULL, addr - PPC_IO_BASE, value); 188 cpu_outl(NULL, addr - PPC_IO_BASE, value);
@@ -138,9 +212,9 @@ static CPUReadMemoryFunc *PPC_io_read[] = { @@ -138,9 +212,9 @@ static CPUReadMemoryFunc *PPC_io_read[] = {
138 uint32_t pic_intack_read(CPUState *env); 212 uint32_t pic_intack_read(CPUState *env);
139 213
140 /* Read-only register (?) */ 214 /* Read-only register (?) */
141 -static void _PPC_ioB_write (uint32_t addr, uint32_t value) 215 +static void _PPC_ioB_write (uint32_t addr, uint32_t value, uint32_t vaddr)
142 { 216 {
143 - PPC_IO_DPRINTF("0x%08x => 0x%08x\n", addr, value); 217 + // printf("%s: 0x%08x => 0x%08x\n", __func__, addr, value);
144 } 218 }
145 219
146 static uint32_t _PPC_ioB_read (uint32_t addr) 220 static uint32_t _PPC_ioB_read (uint32_t addr)
@@ -149,7 +223,7 @@ static uint32_t _PPC_ioB_read (uint32_t addr) @@ -149,7 +223,7 @@ static uint32_t _PPC_ioB_read (uint32_t addr)
149 223
150 if (addr == 0xBFFFFFF0) 224 if (addr == 0xBFFFFFF0)
151 retval = pic_intack_read(NULL); 225 retval = pic_intack_read(NULL);
152 - PPC_IO_DPRINTF("0x%08x <= 0x%08x\n", addr, retval); 226 + // printf("%s: 0x%08x <= %d\n", __func__, addr, retval);
153 227
154 return retval; 228 return retval;
155 } 229 }
@@ -184,20 +258,23 @@ static CPUReadMemoryFunc *PPC_io3_read[] = { @@ -184,20 +258,23 @@ static CPUReadMemoryFunc *PPC_io3_read[] = {
184 static uint8_t PREP_fake_io[2]; 258 static uint8_t PREP_fake_io[2];
185 static uint8_t NVRAM_lock; 259 static uint8_t NVRAM_lock;
186 260
187 -static void PREP_io_write (CPUState *env, uint32_t addr, uint32_t val) 261 +static void PREP_io_write (void *opaque, uint32_t addr, uint32_t val)
188 { 262 {
  263 + PPC_IO_DPRINTF("0x%08x => 0x%08x\n", addr - PPC_IO_BASE, val);
189 PREP_fake_io[addr - 0x0398] = val; 264 PREP_fake_io[addr - 0x0398] = val;
190 } 265 }
191 266
192 -static uint32_t PREP_io_read (CPUState *env, uint32_t addr) 267 +static uint32_t PREP_io_read (void *opaque, uint32_t addr)
193 { 268 {
  269 + PPC_IO_DPRINTF("0x%08x <= 0x%08x\n", addr - PPC_IO_BASE, PREP_fake_io[addr - 0x0398]);
194 return PREP_fake_io[addr - 0x0398]; 270 return PREP_fake_io[addr - 0x0398];
195 } 271 }
196 272
197 static uint8_t syscontrol; 273 static uint8_t syscontrol;
198 274
199 -static void PREP_io_800_writeb (CPUState *env, uint32_t addr, uint32_t val) 275 +static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
200 { 276 {
  277 + PPC_IO_DPRINTF("0x%08x => 0x%08x\n", addr - PPC_IO_BASE, val);
201 switch (addr) { 278 switch (addr) {
202 case 0x0092: 279 case 0x0092:
203 /* Special port 92 */ 280 /* Special port 92 */
@@ -242,7 +319,7 @@ static void PREP_io_800_writeb (CPUState *env, uint32_t addr, uint32_t val) @@ -242,7 +319,7 @@ static void PREP_io_800_writeb (CPUState *env, uint32_t addr, uint32_t val)
242 } 319 }
243 } 320 }
244 321
245 -static uint32_t PREP_io_800_readb (CPUState *env, uint32_t addr) 322 +static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
246 { 323 {
247 uint32_t retval = 0xFF; 324 uint32_t retval = 0xFF;
248 325
@@ -281,281 +358,171 @@ static uint32_t PREP_io_800_readb (CPUState *env, uint32_t addr) @@ -281,281 +358,171 @@ static uint32_t PREP_io_800_readb (CPUState *env, uint32_t addr)
281 default: 358 default:
282 break; 359 break;
283 } 360 }
  361 + PPC_IO_DPRINTF("0x%08x <= 0x%08x\n", addr - PPC_IO_BASE, retval);
284 362
285 return retval; 363 return retval;
286 } 364 }
287 365
288 -/* M48T59 NVRAM/RTC emulation */  
289 -static uint8_t NVRAM[NVRAM_SIZE]; 366 +#define NVRAM_SIZE 0x2000
  367 +#define NVRAM_END 0x1FF0
  368 +#define NVRAM_OSAREA_SIZE 512
  369 +#define NVRAM_CONFSIZE 1024
290 370
291 -/* RTC */  
292 -static time_t time_offset; 371 +static inline void NVRAM_set_byte (void *opaque, uint32_t addr, uint8_t value)
  372 +{
  373 + m48t59_set_addr(opaque, addr);
  374 + m48t59_write(opaque, value);
  375 +}
  376 +
  377 +static inline uint8_t NVRAM_get_byte (void *opaque, uint32_t addr)
  378 +{
  379 + m48t59_set_addr(opaque, addr);
  380 + return m48t59_read(opaque);
  381 +}
  382 +
  383 +static inline void NVRAM_set_word (void *opaque, uint32_t addr, uint16_t value)
  384 +{
  385 + m48t59_set_addr(opaque, addr);
  386 + m48t59_write(opaque, value >> 8);
  387 + m48t59_set_addr(opaque, addr + 1);
  388 + m48t59_write(opaque, value & 0xFF);
  389 +}
293 390
294 -time_t get_time (void) 391 +static inline uint16_t NVRAM_get_word (void *opaque, uint32_t addr)
295 { 392 {
296 - return time(NULL) + time_offset; 393 + uint16_t tmp;
  394 +
  395 + m48t59_set_addr(opaque, addr);
  396 + tmp = m48t59_read(opaque) << 8;
  397 + m48t59_set_addr(opaque, addr + 1);
  398 + tmp |= m48t59_read(opaque);
  399 +
  400 + return tmp;
297 } 401 }
298 402
299 -void set_time_offset (time_t new_time) 403 +static inline void NVRAM_set_lword (void *opaque, uint32_t addr,
  404 + uint32_t value)
300 { 405 {
301 - time_t now = time(NULL); 406 + m48t59_set_addr(opaque, addr);
  407 + m48t59_write(opaque, value >> 24);
  408 + m48t59_set_addr(opaque, addr + 1);
  409 + m48t59_write(opaque, (value >> 16) & 0xFF);
  410 + m48t59_set_addr(opaque, addr + 2);
  411 + m48t59_write(opaque, (value >> 8) & 0xFF);
  412 + m48t59_set_addr(opaque, addr + 3);
  413 + m48t59_write(opaque, value & 0xFF);
  414 +}
302 415
303 - time_offset = new_time - now; 416 +static inline uint32_t NVRAM_get_lword (void *opaque, uint32_t addr)
  417 +{
  418 + uint32_t tmp;
  419 +
  420 + m48t59_set_addr(opaque, addr);
  421 + tmp = m48t59_read(opaque) << 24;
  422 + m48t59_set_addr(opaque, addr + 1);
  423 + tmp |= m48t59_read(opaque) << 16;
  424 + m48t59_set_addr(opaque, addr + 2);
  425 + tmp |= m48t59_read(opaque) << 8;
  426 + m48t59_set_addr(opaque, addr + 3);
  427 + tmp |= m48t59_read(opaque);
  428 +
  429 + return tmp;
304 } 430 }
305 431
306 -static void NVRAM_init (void) 432 +static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
307 { 433 {
  434 + uint16_t tmp;
  435 + uint16_t pd, pd1, pd2;
  436 +
  437 + tmp = prev >> 8;
  438 + pd = prev ^ value;
  439 + pd1 = pd & 0x000F;
  440 + pd2 = ((pd >> 4) & 0x000F) ^ pd1;
  441 + tmp ^= (pd1 << 3) | (pd1 << 8);
  442 + tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
  443 +
  444 + return tmp;
  445 +}
  446 +
  447 +static void NVRAM_set_crc (void *opaque, uint32_t addr,
  448 + uint32_t start, uint32_t count)
  449 +{
  450 + uint32_t i;
  451 + uint16_t crc = 0xFFFF;
  452 + int odd = 0;
  453 +
  454 + if (count & 1)
  455 + odd = 1;
  456 + count &= ~1;
  457 + for (i = 0; i != count; i++) {
  458 + crc = NVRAM_crc_update(crc, NVRAM_get_word(opaque, start + i));
  459 + }
  460 + if (odd) {
  461 + crc = NVRAM_crc_update(crc, NVRAM_get_byte(opaque, start + i) << 8);
  462 + }
  463 + NVRAM_set_word(opaque, addr, crc);
  464 +}
  465 +
  466 +static void prep_NVRAM_init (void)
  467 +{
  468 + void *opaque;
  469 +
  470 + opaque = m48t59_init(8, 0x0074, NVRAM_SIZE);
308 /* NVRAM header */ 471 /* NVRAM header */
309 /* 0x00: NVRAM size in kB */ 472 /* 0x00: NVRAM size in kB */
310 - NVRAM[0x00] = (NVRAM_SIZE >> 12) & 0xFF;  
311 - NVRAM[0x01] = (NVRAM_SIZE >> 10) & 0xFF; 473 + NVRAM_set_word(opaque, 0x00, NVRAM_SIZE >> 10);
312 /* 0x02: NVRAM version */ 474 /* 0x02: NVRAM version */
313 - NVRAM[0x02] = 0x01; 475 + NVRAM_set_byte(opaque, 0x02, 0x01);
314 /* 0x03: NVRAM revision */ 476 /* 0x03: NVRAM revision */
315 - NVRAM[0x03] = 0x00;  
316 - /* 0x04: checksum 0 => OS area */  
317 - /* 0x06: checksum of config area */ 477 + NVRAM_set_byte(opaque, 0x03, 0x01);
318 /* 0x08: last OS */ 478 /* 0x08: last OS */
319 - NVRAM[0x08] = 0x00; /* Unknown */ 479 + NVRAM_set_byte(opaque, 0x08, 0x00); /* Unknown */
320 /* 0x09: endian */ 480 /* 0x09: endian */
321 - NVRAM[0x09] = 'B'; 481 + NVRAM_set_byte(opaque, 0x09, 'B'); /* Big-endian */
  482 + /* 0x0A: OSArea usage */
  483 + NVRAM_set_byte(opaque, 0x0A, 0x00); /* Empty */
322 /* 0x0B: PM mode */ 484 /* 0x0B: PM mode */
323 - NVRAM[0x0B] = 0x00; 485 + NVRAM_set_byte(opaque, 0x0B, 0x00); /* Normal */
324 /* Restart block description record */ 486 /* Restart block description record */
325 /* 0x0C: restart block version */ 487 /* 0x0C: restart block version */
326 - NVRAM[0x0C] = 0x00;  
327 - NVRAM[0x0D] = 0x01; 488 + NVRAM_set_word(opaque, 0x0C, 0x01);
328 /* 0x0E: restart block revision */ 489 /* 0x0E: restart block revision */
329 - NVRAM[0x0E] = 0x00;  
330 - NVRAM[0x0F] = 0x00;  
331 - /* 0x1C: checksum of restart block */ 490 + NVRAM_set_word(opaque, 0x0E, 0x01);
332 /* 0x20: restart address */ 491 /* 0x20: restart address */
333 - NVRAM[0x20] = 0x00;  
334 - NVRAM[0x21] = 0x00;  
335 - NVRAM[0x22] = 0x00;  
336 - NVRAM[0x23] = 0x00; 492 + NVRAM_set_lword(opaque, 0x20, 0x00);
337 /* 0x24: save area address */ 493 /* 0x24: save area address */
338 - NVRAM[0x24] = 0x00;  
339 - NVRAM[0x25] = 0x00;  
340 - NVRAM[0x26] = 0x00;  
341 - NVRAM[0x27] = 0x00; 494 + NVRAM_set_lword(opaque, 0x24, 0x00);
342 /* 0x28: save area length */ 495 /* 0x28: save area length */
343 - NVRAM[0x28] = 0x00;  
344 - NVRAM[0x29] = 0x00;  
345 - NVRAM[0x2A] = 0x00;  
346 - NVRAM[0x2B] = 0x00; 496 + NVRAM_set_lword(opaque, 0x28, 0x00);
  497 + /* 0x1C: checksum of restart block */
  498 + NVRAM_set_crc(opaque, 0x1C, 0x0C, 32);
  499 +
347 /* Security section */ 500 /* Security section */
348 /* Set all to zero */ 501 /* Set all to zero */
349 /* 0xC4: pointer to global environment area */ 502 /* 0xC4: pointer to global environment area */
350 - NVRAM[0xC4] = 0x00;  
351 - NVRAM[0xC5] = 0x00;  
352 - NVRAM[0xC6] = 0x01;  
353 - NVRAM[0xC7] = 0x00; 503 + NVRAM_set_lword(opaque, 0xC4, 0x0100);
354 /* 0xC8: size of global environment area */ 504 /* 0xC8: size of global environment area */
355 - NVRAM[0xC8] = 0x00;  
356 - NVRAM[0xC9] = 0x00;  
357 - NVRAM[0xCA] = 0x07;  
358 - NVRAM[0xCB] = 0x00; 505 + NVRAM_set_lword(opaque, 0xC8,
  506 + NVRAM_END - NVRAM_OSAREA_SIZE - NVRAM_CONFSIZE - 0x0100);
359 /* 0xD4: pointer to configuration area */ 507 /* 0xD4: pointer to configuration area */
360 - NVRAM[0xD4] = 0x00;  
361 - NVRAM[0xD5] = 0x00;  
362 - NVRAM[0xD6] = 0x08;  
363 - NVRAM[0xD7] = 0x00; 508 + NVRAM_set_lword(opaque, 0xD4, NVRAM_END - NVRAM_CONFSIZE);
364 /* 0xD8: size of configuration area */ 509 /* 0xD8: size of configuration area */
365 - NVRAM[0xD8] = 0x00;  
366 - NVRAM[0xD9] = 0x00;  
367 - NVRAM[0xDA] = 0x08;  
368 - NVRAM[0xDB] = 0x00; 510 + NVRAM_set_lword(opaque, 0xD8, NVRAM_CONFSIZE);
369 /* 0xE8: pointer to OS specific area */ 511 /* 0xE8: pointer to OS specific area */
370 - NVRAM[0xE8] = 0x00;  
371 - NVRAM[0xE9] = 0x00;  
372 - NVRAM[0xEA] = 0x10;  
373 - NVRAM[0xEB] = 0x00; 512 + NVRAM_set_lword(opaque, 0xE8,
  513 + NVRAM_END - NVRAM_CONFSIZE - NVRAM_OSAREA_SIZE);
374 /* 0xD8: size of OS specific area */ 514 /* 0xD8: size of OS specific area */
375 - NVRAM[0xEC] = 0x00;  
376 - NVRAM[0xED] = 0x00;  
377 - NVRAM[0xEE] = 0x0F;  
378 - NVRAM[0xEF] = 0xF0;  
379 - /* CRC */  
380 - /* RTC init */  
381 - NVRAM[0x1FFC] = 0x50;  
382 -}  
383 -  
384 -static uint16_t NVRAM_addr;  
385 -  
386 -/* Direct access to NVRAM */  
387 -void NVRAM_write (CPUState *env, uint32_t addr, uint32_t val)  
388 -{  
389 - switch (addr) {  
390 - case 0x1FF0:  
391 - /* flags register */  
392 - break;  
393 - case 0x1FF1:  
394 - /* unused */  
395 - break;  
396 - case 0x1FF2:  
397 - /* alarm seconds */  
398 - break;  
399 - case 0x1FF3:  
400 - /* alarm minutes */  
401 - break;  
402 - case 0x1FF4:  
403 - /* alarm hours */  
404 - break;  
405 - case 0x1FF5:  
406 - /* alarm date */  
407 - break;  
408 - case 0x1FF6:  
409 - /* interrupts */  
410 - break;  
411 - case 0x1FF7:  
412 - /* watchdog */  
413 - break;  
414 - case 0x1FF8:  
415 - /* control */  
416 - break;  
417 - case 0x1FF9:  
418 - /* seconds (BCD) */  
419 - break;  
420 - case 0x1FFA:  
421 - /* minutes (BCD) */  
422 - break;  
423 - case 0x1FFB:  
424 - /* hours (BCD) */  
425 - break;  
426 - case 0x1FFC:  
427 - /* day of the week / century */  
428 - NVRAM[0x1FFC] = val & 0x50;  
429 - break;  
430 - case 0x1FFD:  
431 - /* date */  
432 - break;  
433 - case 0x1FFE:  
434 - /* month */  
435 - break;  
436 - case 0x1FFF:  
437 - /* year */  
438 - break;  
439 - default:  
440 - if (addr < NVRAM_SIZE)  
441 - NVRAM[addr] = val & 0xFF;  
442 - break;  
443 - }  
444 -}  
445 -  
446 -uint32_t NVRAM_read (CPUState *env, uint32_t addr)  
447 -{  
448 - struct tm tm;  
449 - time_t t;  
450 - uint32_t retval = 0xFF;  
451 -  
452 - switch (addr) {  
453 - case 0x1FF0:  
454 - /* flags register */  
455 - break;  
456 - case 0x1FF1:  
457 - /* unused */  
458 - break;  
459 - case 0x1FF2:  
460 - /* alarm seconds */  
461 - break;  
462 - case 0x1FF3:  
463 - /* alarm minutes */  
464 - break;  
465 - case 0x1FF4:  
466 - /* alarm hours */  
467 - break;  
468 - case 0x1FF5:  
469 - /* alarm date */  
470 - break;  
471 - case 0x1FF6:  
472 - /* interrupts */  
473 - break;  
474 - case 0x1FF7:  
475 - /* watchdog */  
476 - break;  
477 - case 0x1FF8:  
478 - /* control */  
479 - break;  
480 - case 0x1FF9:  
481 - /* seconds (BCD) */  
482 - t = get_time();  
483 - localtime_r(&t, &tm);  
484 - retval = ((tm.tm_sec / 10) << 4) | (tm.tm_sec % 10);  
485 -// printf("return seconds=%d\n", tm.tm_sec);  
486 - break;  
487 - case 0x1FFA:  
488 - /* minutes (BCD) */  
489 - t = get_time();  
490 - localtime_r(&t, &tm);  
491 - retval = ((tm.tm_min / 10) << 4) | (tm.tm_min % 10);  
492 - break;  
493 - case 0x1FFB:  
494 - /* hours (BCD) */  
495 - t = get_time();  
496 - localtime_r(&t, &tm);  
497 - retval = ((tm.tm_hour / 10) << 4) | (tm.tm_hour % 10);  
498 - break;  
499 - case 0x1FFC:  
500 - /* day of the week / century */  
501 - t = get_time();  
502 - localtime_r(&t, &tm);  
503 - retval = (NVRAM[0x1FFC] & 0x50) | tm.tm_wday;  
504 - break;  
505 - case 0x1FFD:  
506 - /* date */  
507 - t = get_time();  
508 - localtime_r(&t, &tm);  
509 - retval = ((tm.tm_mday / 10) << 4) | (tm.tm_mday % 10);  
510 - break;  
511 - case 0x1FFE:  
512 - /* month */  
513 - t = get_time();  
514 - localtime_r(&t, &tm);  
515 - retval = ((tm.tm_mon / 10) << 4) | (tm.tm_mon % 10);  
516 - break;  
517 - case 0x1FFF:  
518 - /* year */  
519 - t = get_time();  
520 - localtime_r(&t, &tm);  
521 - retval = ((tm.tm_year / 10) << 4) | (tm.tm_year % 10);  
522 - break;  
523 - default:  
524 - if (NVRAM_addr < NVRAM_SIZE)  
525 - retval = NVRAM[NVRAM_addr];  
526 - break;  
527 - } 515 + NVRAM_set_lword(opaque, 0xEC, NVRAM_OSAREA_SIZE);
528 516
529 - return retval;  
530 -}  
531 -  
532 -/* IO access to NVRAM */  
533 -static void NVRAM_writeb (CPUState *env, uint32_t addr, uint32_t val)  
534 -{  
535 - switch (addr) {  
536 - case 0x74:  
537 - NVRAM_addr &= ~0x00FF;  
538 - NVRAM_addr |= val;  
539 - break;  
540 - case 0x75:  
541 - NVRAM_addr &= ~0xFF00;  
542 - NVRAM_addr |= val << 8;  
543 - break;  
544 - case 0x77:  
545 - NVRAM_write(env, NVRAM_addr, val);  
546 - NVRAM_addr = 0x0000;  
547 - break;  
548 - default:  
549 - break;  
550 - }  
551 -}  
552 -  
553 -static uint32_t NVRAM_readb (CPUState *env, uint32_t addr)  
554 -{  
555 - if (addr == 0x77)  
556 - return NVRAM_read(env, NVRAM_addr); 517 + /* Configuration area */
  518 + /* RTC init */
  519 + // NVRAM_set_lword(opaque, 0x1FFC, 0x50);
557 520
558 - return 0xFF; 521 + /* 0x04: checksum 0 => OS area */
  522 + NVRAM_set_crc(opaque, 0x04, 0x00,
  523 + NVRAM_END - NVRAM_CONFSIZE - NVRAM_OSAREA_SIZE);
  524 + /* 0x06: checksum of config area */
  525 + NVRAM_set_crc(opaque, 0x06, NVRAM_END - NVRAM_CONFSIZE, NVRAM_CONFSIZE);
559 } 526 }
560 527
561 int load_initrd (const char *filename, uint8_t *addr) 528 int load_initrd (const char *filename, uint8_t *addr)
@@ -591,7 +558,7 @@ static void put_long (void *addr, uint32_t l) @@ -591,7 +558,7 @@ static void put_long (void *addr, uint32_t l)
591 /* bootloader infos are in the form: 558 /* bootloader infos are in the form:
592 * uint32_t TAG 559 * uint32_t TAG
593 * uint32_t TAG_size (from TAG to next TAG). 560 * uint32_t TAG_size (from TAG to next TAG).
594 - * datas 561 + * data
595 * .... 562 * ....
596 */ 563 */
597 #if !defined (USE_OPEN_FIRMWARE) 564 #if !defined (USE_OPEN_FIRMWARE)
@@ -621,9 +588,10 @@ static boot_dev_t boot_devs[] = @@ -621,9 +588,10 @@ static boot_dev_t boot_devs[] =
621 { 588 {
622 { "/dev/fd0", 2, 0, }, 589 { "/dev/fd0", 2, 0, },
623 { "/dev/fd1", 2, 1, }, 590 { "/dev/fd1", 2, 1, },
624 - { "/dev/hda1", 3, 1, }, 591 + { "/dev/hda", 3, 1, },
625 // { "/dev/ide/host0/bus0/target0/lun0/part1", 3, 1, }, 592 // { "/dev/ide/host0/bus0/target0/lun0/part1", 3, 1, },
626 - { "/dev/hdc", 22, 0, }, 593 +// { "/dev/hdc", 22, 0, },
  594 + { "/dev/hdc", 22, 1, },
627 { "/dev/ram0 init=/linuxrc", 1, 0, }, 595 { "/dev/ram0 init=/linuxrc", 1, 0, },
628 }; 596 };
629 597
@@ -671,7 +639,7 @@ static void VGA_printf (uint8_t *s) @@ -671,7 +639,7 @@ static void VGA_printf (uint8_t *s)
671 uint16_t arg, digit, nibble; 639 uint16_t arg, digit, nibble;
672 uint8_t c; 640 uint8_t c;
673 641
674 - arg_ptr = (uint16_t *)(&s); 642 + arg_ptr = (uint16_t *)((void *)&s);
675 in_format = 0; 643 in_format = 0;
676 format_width = 0; 644 format_width = 0;
677 while ((c = *s) != '\0') { 645 while ((c = *s) != '\0') {
@@ -690,9 +658,9 @@ static void VGA_printf (uint8_t *s) @@ -690,9 +658,9 @@ static void VGA_printf (uint8_t *s)
690 for (i = 0; i < format_width; i++) { 658 for (i = 0; i < format_width; i++) {
691 nibble = (arg >> (4 * digit)) & 0x000f; 659 nibble = (arg >> (4 * digit)) & 0x000f;
692 if (nibble <= 9) 660 if (nibble <= 9)
693 - PPC_io_writeb(PPC_IO_BASE + 0x500, nibble + '0'); 661 + PPC_io_writeb(PPC_IO_BASE + 0x500, nibble + '0', 0);
694 else 662 else
695 - PPC_io_writeb(PPC_IO_BASE + 0x500, nibble + 'A'); 663 + PPC_io_writeb(PPC_IO_BASE + 0x500, nibble + 'A', 0);
696 digit--; 664 digit--;
697 } 665 }
698 in_format = 0; 666 in_format = 0;
@@ -701,7 +669,7 @@ static void VGA_printf (uint8_t *s) @@ -701,7 +669,7 @@ static void VGA_printf (uint8_t *s)
701 // in_format = 0; 669 // in_format = 0;
702 // } 670 // }
703 } else { 671 } else {
704 - PPC_io_writeb(PPC_IO_BASE + 0x500, c); 672 + PPC_io_writeb(PPC_IO_BASE + 0x500, c, 0);
705 } 673 }
706 s++; 674 s++;
707 } 675 }
@@ -711,48 +679,46 @@ static void VGA_init (void) @@ -711,48 +679,46 @@ static void VGA_init (void)
711 { 679 {
712 /* Basic VGA init, inspired by plex86 VGAbios */ 680 /* Basic VGA init, inspired by plex86 VGAbios */
713 printf("Init VGA...\n"); 681 printf("Init VGA...\n");
  682 +#if 1
714 /* switch to color mode and enable CPU access 480 lines */ 683 /* switch to color mode and enable CPU access 480 lines */
715 - PPC_io_writeb(PPC_IO_BASE + 0x3C2, 0xC3); 684 + PPC_io_writeb(PPC_IO_BASE + 0x3C2, 0xC3, 0);
716 /* more than 64k 3C4/04 */ 685 /* more than 64k 3C4/04 */
717 - PPC_io_writeb(PPC_IO_BASE + 0x3C4, 0x04);  
718 - PPC_io_writeb(PPC_IO_BASE + 0x3C5, 0x02); 686 + PPC_io_writeb(PPC_IO_BASE + 0x3C4, 0x04, 0);
  687 + PPC_io_writeb(PPC_IO_BASE + 0x3C5, 0x02, 0);
  688 +#endif
719 VGA_printf("PPC VGA BIOS...\n"); 689 VGA_printf("PPC VGA BIOS...\n");
720 } 690 }
721 691
722 -void PPC_init_hw (CPUPPCState *env, uint32_t mem_size, 692 +extern CPUPPCState *global_env;
  693 +
  694 +void PPC_init_hw (/*CPUPPCState *env,*/ uint32_t mem_size,
723 uint32_t kernel_addr, uint32_t kernel_size, 695 uint32_t kernel_addr, uint32_t kernel_size,
724 - uint32_t stack_addr, int boot_device) 696 + uint32_t stack_addr, int boot_device,
  697 + const unsigned char *initrd_file)
725 { 698 {
  699 + CPUPPCState *env = global_env;
726 char *p; 700 char *p;
727 #if !defined (USE_OPEN_FIRMWARE) 701 #if !defined (USE_OPEN_FIRMWARE)
728 char *tmp; 702 char *tmp;
729 uint32_t tmpi[2]; 703 uint32_t tmpi[2];
730 #endif 704 #endif
731 - int PPC_io_memory;  
732 - 705 +
  706 + printf("RAM size: %u 0x%08x (%u)\n", mem_size, mem_size, mem_size >> 20);
733 #if defined (USE_OPEN_FIRMWARE) 707 #if defined (USE_OPEN_FIRMWARE)
734 setup_memory(env, mem_size); 708 setup_memory(env, mem_size);
735 #endif 709 #endif
736 - /* Register 64 kB of IO space */  
737 - PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write);  
738 - cpu_register_physical_memory(0x80000000, 0x10000, PPC_io_memory);  
739 - /* Register fake IO ports for PREP */  
740 - register_ioport_read(0x398, 2, PREP_io_read, 1);  
741 - register_ioport_write(0x398, 2, PREP_io_write, 1);  
742 - /* System control ports */  
743 - register_ioport_write(0x0092, 0x1, PREP_io_800_writeb, 1);  
744 - register_ioport_read(0x0800, 0x52, PREP_io_800_readb, 1);  
745 - register_ioport_write(0x0800, 0x52, PREP_io_800_writeb, 1);  
746 - /* PCI intack location */  
747 - PPC_io_memory = cpu_register_io_memory(0, PPC_ioB_read, PPC_ioB_write);  
748 - cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);  
749 - /* NVRAM ports */  
750 - NVRAM_init();  
751 - register_ioport_read(0x0074, 0x04, NVRAM_readb, 1);  
752 - register_ioport_write(0x0074, 0x04, NVRAM_writeb, 1);  
753 710
754 /* Fake bootloader */ 711 /* Fake bootloader */
755 - env->nip = kernel_addr + (3 * sizeof(uint32_t)); 712 + {
  713 +#if 1
  714 + uint32_t offset =
  715 + *((uint32_t *)((uint32_t)phys_ram_base + kernel_addr));
  716 +#else
  717 + uint32_t offset = 12;
  718 +#endif
  719 + env->nip = kernel_addr + offset;
  720 + printf("Start address: 0x%08x\n", env->nip);
  721 + }
756 /* Set up msr according to PREP specification */ 722 /* Set up msr according to PREP specification */
757 msr_ee = 0; 723 msr_ee = 0;
758 msr_fp = 1; 724 msr_fp = 1;
@@ -786,11 +752,10 @@ void PPC_init_hw (CPUPPCState *env, uint32_t mem_size, @@ -786,11 +752,10 @@ void PPC_init_hw (CPUPPCState *env, uint32_t mem_size,
786 env->gpr[1] -= 32; 752 env->gpr[1] -= 32;
787 /* Pretend there are no residual data */ 753 /* Pretend there are no residual data */
788 env->gpr[3] = 0; 754 env->gpr[3] = 0;
789 -#if 1  
790 - { 755 + if (initrd_file != NULL) {
791 int size; 756 int size;
792 - env->gpr[4] = 0x00800000;  
793 - size = load_initrd("initrd", 757 + env->gpr[4] = (kernel_addr + kernel_size + 4095) & ~4095;
  758 + size = load_initrd(initrd_file,
794 (void *)((uint32_t)phys_ram_base + env->gpr[4])); 759 (void *)((uint32_t)phys_ram_base + env->gpr[4]));
795 if (size < 0) { 760 if (size < 0) {
796 /* No initrd */ 761 /* No initrd */
@@ -799,11 +764,11 @@ void PPC_init_hw (CPUPPCState *env, uint32_t mem_size, @@ -799,11 +764,11 @@ void PPC_init_hw (CPUPPCState *env, uint32_t mem_size,
799 env->gpr[5] = size; 764 env->gpr[5] = size;
800 boot_device = 'e'; 765 boot_device = 'e';
801 } 766 }
802 - printf("Initrd loaded at 0x%08x (%d)\n", env->gpr[4], env->gpr[5]); 767 + printf("Initrd loaded at 0x%08x (%d) (0x%08x 0x%08x)\n",
  768 + env->gpr[4], env->gpr[5], kernel_addr, kernel_size);
  769 + } else {
  770 + env->gpr[4] = env->gpr[5] = 0;
803 } 771 }
804 -#else  
805 - env->gpr[4] = env->gpr[5] = 0;  
806 -#endif  
807 /* We have to put bootinfos after the BSS 772 /* We have to put bootinfos after the BSS
808 * The BSS starts after the kernel end. 773 * The BSS starts after the kernel end.
809 */ 774 */
@@ -825,11 +790,11 @@ void PPC_init_hw (CPUPPCState *env, uint32_t mem_size, @@ -825,11 +790,11 @@ void PPC_init_hw (CPUPPCState *env, uint32_t mem_size,
825 sprintf(p + 0x1000, "console=ttyS0,9600 root=%02x%02x mem=%dM", 790 sprintf(p + 0x1000, "console=ttyS0,9600 root=%02x%02x mem=%dM",
826 boot_devs[boot_device - 'a'].major, 791 boot_devs[boot_device - 'a'].major,
827 boot_devs[boot_device - 'a'].minor, 792 boot_devs[boot_device - 'a'].minor,
828 - phys_ram_size >> 20); 793 + mem_size >> 20);
829 #else 794 #else
830 - sprintf(p + 0x1000, "console=ttyS0,9600 console=tty0 root=%s mem=%dM load_ramdisk=1", 795 + sprintf(p + 0x1000, "console=ttyS0,9600 console=tty0 root=%s mem=%dM",
831 boot_devs[boot_device - 'a'].name, 796 boot_devs[boot_device - 'a'].name,
832 - phys_ram_size >> 20); 797 + mem_size >> 20);
833 #endif 798 #endif
834 env->gpr[6] = (uint32_t)p + 0x1000 - (uint32_t)phys_ram_base; 799 env->gpr[6] = (uint32_t)p + 0x1000 - (uint32_t)phys_ram_base;
835 env->gpr[7] = env->gpr[6] + strlen(p + 0x1000); 800 env->gpr[7] = env->gpr[6] + strlen(p + 0x1000);
@@ -847,10 +812,10 @@ void PPC_init_hw (CPUPPCState *env, uint32_t mem_size, @@ -847,10 +812,10 @@ void PPC_init_hw (CPUPPCState *env, uint32_t mem_size,
847 (void *)(env->gpr[6] + (uint32_t)phys_ram_base)); 812 (void *)(env->gpr[6] + (uint32_t)phys_ram_base));
848 /* BI_MEM_SIZE */ 813 /* BI_MEM_SIZE */
849 tmp = (void *)tmpi; 814 tmp = (void *)tmpi;
850 - tmp[0] = (phys_ram_size >> 24) & 0xFF;  
851 - tmp[1] = (phys_ram_size >> 16) & 0xFF;  
852 - tmp[2] = (phys_ram_size >> 8) & 0xFF;  
853 - tmp[3] = phys_ram_size & 0xFF; 815 + tmp[0] = (mem_size >> 24) & 0xFF;
  816 + tmp[1] = (mem_size >> 16) & 0xFF;
  817 + tmp[2] = (mem_size >> 8) & 0xFF;
  818 + tmp[3] = mem_size & 0xFF;
854 p = set_bootinfo_tag(p, 0x1017, 4, tmpi); 819 p = set_bootinfo_tag(p, 0x1017, 4, tmpi);
855 /* BI_INITRD */ 820 /* BI_INITRD */
856 tmp[0] = (env->gpr[4] >> 24) & 0xFF; 821 tmp[0] = (env->gpr[4] >> 24) & 0xFF;
@@ -862,6 +827,7 @@ void PPC_init_hw (CPUPPCState *env, uint32_t mem_size, @@ -862,6 +827,7 @@ void PPC_init_hw (CPUPPCState *env, uint32_t mem_size,
862 tmp[6] = (env->gpr[5] >> 8) & 0xFF; 827 tmp[6] = (env->gpr[5] >> 8) & 0xFF;
863 tmp[7] = env->gpr[5] & 0xFF; 828 tmp[7] = env->gpr[5] & 0xFF;
864 p = set_bootinfo_tag(p, 0x1014, 8, tmpi); 829 p = set_bootinfo_tag(p, 0x1014, 8, tmpi);
  830 + env->gpr[4] = env->gpr[5] = 0;
865 /* BI_LAST */ 831 /* BI_LAST */
866 p = set_bootinfo_tag(p, 0x1011, 0, 0); 832 p = set_bootinfo_tag(p, 0x1011, 0, 0);
867 #else 833 #else
@@ -915,21 +881,127 @@ void PPC_init_hw (CPUPPCState *env, uint32_t mem_size, @@ -915,21 +881,127 @@ void PPC_init_hw (CPUPPCState *env, uint32_t mem_size,
915 /* Set up RTAS service */ 881 /* Set up RTAS service */
916 RTAS_init(); 882 RTAS_init();
917 /* Command line: let's put it just over the stack */ 883 /* Command line: let's put it just over the stack */
  884 +#if 0
  885 +#if 0
  886 + p = (void *)(((uint32_t)phys_ram_base + kernel_addr +
  887 + kernel_size + (1 << 20) - 1) & ~((1 << 20) - 1));
  888 +#else
  889 + p = (void *)((uint32_t)phys_ram_base + kernel_addr + 0x400000);
  890 +#endif
918 #if 1 891 #if 1
919 sprintf(p, "console=ttyS0,9600 root=%02x%02x mem=%dM", 892 sprintf(p, "console=ttyS0,9600 root=%02x%02x mem=%dM",
920 boot_devs[boot_device - 'a'].major, 893 boot_devs[boot_device - 'a'].major,
921 boot_devs[boot_device - 'a'].minor, 894 boot_devs[boot_device - 'a'].minor,
922 - phys_ram_size >> 20); 895 + mem_size >> 20);
923 #else 896 #else
924 sprintf(p, "console=ttyS0,9600 root=%s mem=%dM ne2000=0x300,9", 897 sprintf(p, "console=ttyS0,9600 root=%s mem=%dM ne2000=0x300,9",
925 boot_devs[boot_device - 'a'].name, 898 boot_devs[boot_device - 'a'].name,
926 - phys_ram_size >> 20); 899 + mem_size >> 20);
927 #endif 900 #endif
928 OF_register_bootargs(p); 901 OF_register_bootargs(p);
929 #endif 902 #endif
  903 +#endif
930 } 904 }
931 905
932 void PPC_end_init (void) 906 void PPC_end_init (void)
933 { 907 {
934 VGA_init(); 908 VGA_init();
935 } 909 }
  910 +
  911 +/* PC hardware initialisation */
  912 +void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
  913 + DisplayState *ds, const char **fd_filename, int snapshot,
  914 + const char *kernel_filename, const char *kernel_cmdline,
  915 + const char *initrd_filename)
  916 +{
  917 + char buf[1024];
  918 + int PPC_io_memory;
  919 + int ret, linux_boot, initrd_size, i, nb_nics1, fd;
  920 +
  921 + linux_boot = (kernel_filename != NULL);
  922 +
  923 + /* allocate RAM */
  924 + cpu_register_physical_memory(0, ram_size, 0);
  925 +
  926 + if (linux_boot) {
  927 + /* now we can load the kernel */
  928 + ret = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
  929 + if (ret < 0) {
  930 + fprintf(stderr, "qemu: could not load kernel '%s'\n",
  931 + kernel_filename);
  932 + exit(1);
  933 + }
  934 + /* load initrd */
  935 + initrd_size = 0;
  936 +#if 0
  937 + if (initrd_filename) {
  938 + initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
  939 + if (initrd_size < 0) {
  940 + fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
  941 + initrd_filename);
  942 + exit(1);
  943 + }
  944 + }
  945 +#endif
  946 + PPC_init_hw(/*env,*/ ram_size, KERNEL_LOAD_ADDR, ret,
  947 + KERNEL_STACK_ADDR, boot_device, initrd_filename);
  948 + } else {
  949 + /* allocate ROM */
  950 + // snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
  951 + snprintf(buf, sizeof(buf), "%s", BIOS_FILENAME);
  952 + printf("load BIOS at %p\n", phys_ram_base + 0x000f0000);
  953 + ret = load_image(buf, phys_ram_base + 0x000f0000);
  954 + if (ret != 0x10000) {
  955 + fprintf(stderr, "qemu: could not load PPC bios '%s' (%d)\n%m\n",
  956 + buf, ret);
  957 + exit(1);
  958 + }
  959 + }
  960 +
  961 + /* init basic PC hardware */
  962 + vga_initialize(ds, phys_ram_base + ram_size, ram_size,
  963 + vga_ram_size);
  964 + rtc_init(0x70, 8);
  965 + pic_init();
  966 + // pit_init(0x40, 0);
  967 +
  968 + fd = serial_open_device();
  969 + serial_init(0x3f8, 4, fd);
  970 +#if 1
  971 + nb_nics1 = nb_nics;
  972 + if (nb_nics1 > NE2000_NB_MAX)
  973 + nb_nics1 = NE2000_NB_MAX;
  974 + for(i = 0; i < nb_nics1; i++) {
  975 + ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
  976 + }
  977 +#endif
  978 +
  979 + for(i = 0; i < 2; i++) {
  980 + ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
  981 + bs_table[2 * i], bs_table[2 * i + 1]);
  982 + }
  983 + kbd_init();
  984 + AUD_init();
  985 + DMA_init();
  986 + // SB16_init();
  987 +
  988 + fdctrl_init(6, 2, 0, 0x3f0, fd_table);
  989 +
  990 + /* Register 64 kB of IO space */
  991 + PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write);
  992 + cpu_register_physical_memory(0x80000000, 0x10000, PPC_io_memory);
  993 + /* Register fake IO ports for PREP */
  994 + register_ioport_read(0x398, 2, 1, &PREP_io_read, NULL);
  995 + register_ioport_write(0x398, 2, 1, &PREP_io_write, NULL);
  996 + /* System control ports */
  997 + register_ioport_write(0x0092, 0x1, 1, &PREP_io_800_writeb, NULL);
  998 + register_ioport_read(0x0800, 0x52, 1, &PREP_io_800_readb, NULL);
  999 + register_ioport_write(0x0800, 0x52, 1, &PREP_io_800_writeb, NULL);
  1000 + /* PCI intack location (0xfef00000 / 0xbffffff0) */
  1001 + PPC_io_memory = cpu_register_io_memory(0, PPC_ioB_read, PPC_ioB_write);
  1002 + cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);
  1003 + // cpu_register_physical_memory(0xFEF00000, 0x4, PPC_io_memory);
  1004 + prep_NVRAM_init();
  1005 +
  1006 + PPC_end_init();
  1007 +}
linux-user/main.c
@@ -94,15 +94,15 @@ int cpu_inl(CPUState *env, int addr) @@ -94,15 +94,15 @@ int cpu_inl(CPUState *env, int addr)
94 return 0; 94 return 0;
95 } 95 }
96 96
97 -#ifdef TARGET_I386  
98 -/***********************************************************/  
99 -/* CPUX86 core interface */  
100 -  
101 -int cpu_x86_get_pic_interrupt(CPUState *env) 97 +int cpu_get_pic_interrupt(CPUState *env)
102 { 98 {
103 return -1; 99 return -1;
104 } 100 }
105 101
  102 +#ifdef TARGET_I386
  103 +/***********************************************************/
  104 +/* CPUX86 core interface */
  105 +
106 static void write_dt(void *ptr, unsigned long addr, unsigned long limit, 106 static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
107 int flags) 107 int flags)
108 { 108 {
@@ -441,7 +441,6 @@ void cpu_loop (CPUSPARCState *env) @@ -441,7 +441,6 @@ void cpu_loop (CPUSPARCState *env)
441 #endif 441 #endif
442 442
443 #ifdef TARGET_PPC 443 #ifdef TARGET_PPC
444 -  
445 void cpu_loop(CPUPPCState *env) 444 void cpu_loop(CPUPPCState *env)
446 { 445 {
447 target_siginfo_t info; 446 target_siginfo_t info;
@@ -769,6 +768,8 @@ void cpu_loop(CPUPPCState *env) @@ -769,6 +768,8 @@ void cpu_loop(CPUPPCState *env)
769 case EXCP_INTERRUPT: 768 case EXCP_INTERRUPT:
770 /* Don't know why this should ever happen... */ 769 /* Don't know why this should ever happen... */
771 break; 770 break;
  771 + case EXCP_DEBUG:
  772 + break;
772 default: 773 default:
773 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", 774 fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
774 trapnr); 775 trapnr);
linux-user/syscall.c
@@ -2475,6 +2475,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2475,6 +2475,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2475 } 2475 }
2476 #endif 2476 #endif
2477 break; 2477 break;
  2478 +#ifdef TARGET_NR_getdents64
2478 case TARGET_NR_getdents64: 2479 case TARGET_NR_getdents64:
2479 { 2480 {
2480 struct dirent64 *dirp = (void *)arg2; 2481 struct dirent64 *dirp = (void *)arg2;
@@ -2498,6 +2499,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -2498,6 +2499,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
2498 } 2499 }
2499 } 2500 }
2500 break; 2501 break;
  2502 +#endif /* TARGET_NR_getdents64 */
2501 case TARGET_NR__newselect: 2503 case TARGET_NR__newselect:
2502 ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4, 2504 ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4,
2503 (void *)arg5); 2505 (void *)arg5);
monitor.c
@@ -530,6 +530,47 @@ typedef struct MonitorDef { @@ -530,6 +530,47 @@ typedef struct MonitorDef {
530 int (*get_value)(struct MonitorDef *md); 530 int (*get_value)(struct MonitorDef *md);
531 } MonitorDef; 531 } MonitorDef;
532 532
  533 +#if defined(TARGET_PPC)
  534 +static int monitor_get_ccr (struct MonitorDef *md)
  535 +{
  536 + unsigned int u;
  537 + int i;
  538 +
  539 + u = 0;
  540 + for (i = 0; i < 8; i++)
  541 + u |= cpu_single_env->crf[i] << (32 - (4 * i));
  542 +
  543 + return u;
  544 +}
  545 +
  546 +static int monitor_get_msr (struct MonitorDef *md)
  547 +{
  548 + return (cpu_single_env->msr[MSR_POW] << MSR_POW) |
  549 + (cpu_single_env->msr[MSR_ILE] << MSR_ILE) |
  550 + (cpu_single_env->msr[MSR_EE] << MSR_EE) |
  551 + (cpu_single_env->msr[MSR_PR] << MSR_PR) |
  552 + (cpu_single_env->msr[MSR_FP] << MSR_FP) |
  553 + (cpu_single_env->msr[MSR_ME] << MSR_ME) |
  554 + (cpu_single_env->msr[MSR_FE0] << MSR_FE0) |
  555 + (cpu_single_env->msr[MSR_SE] << MSR_SE) |
  556 + (cpu_single_env->msr[MSR_BE] << MSR_BE) |
  557 + (cpu_single_env->msr[MSR_FE1] << MSR_FE1) |
  558 + (cpu_single_env->msr[MSR_IP] << MSR_IP) |
  559 + (cpu_single_env->msr[MSR_IR] << MSR_IR) |
  560 + (cpu_single_env->msr[MSR_DR] << MSR_DR) |
  561 + (cpu_single_env->msr[MSR_RI] << MSR_RI) |
  562 + (cpu_single_env->msr[MSR_LE] << MSR_LE);
  563 +}
  564 +
  565 +static int monitor_get_xer (struct MonitorDef *md)
  566 +{
  567 + return (cpu_single_env->xer[XER_SO] << XER_SO) |
  568 + (cpu_single_env->xer[XER_OV] << XER_OV) |
  569 + (cpu_single_env->xer[XER_CA] << XER_CA) |
  570 + (cpu_single_env->xer[XER_BC] << XER_BC);
  571 +}
  572 +#endif
  573 +
533 static MonitorDef monitor_defs[] = { 574 static MonitorDef monitor_defs[] = {
534 #ifdef TARGET_I386 575 #ifdef TARGET_I386
535 { "eax", offsetof(CPUState, regs[0]) }, 576 { "eax", offsetof(CPUState, regs[0]) },
@@ -542,6 +583,65 @@ static MonitorDef monitor_defs[] = { @@ -542,6 +583,65 @@ static MonitorDef monitor_defs[] = {
542 { "esi", offsetof(CPUState, regs[7]) }, 583 { "esi", offsetof(CPUState, regs[7]) },
543 { "eflags", offsetof(CPUState, eflags) }, 584 { "eflags", offsetof(CPUState, eflags) },
544 { "eip|pc", offsetof(CPUState, eip) }, 585 { "eip|pc", offsetof(CPUState, eip) },
  586 +#elif defined(TARGET_PPC)
  587 + { "r0", offsetof(CPUState, gpr[0]) },
  588 + { "r1", offsetof(CPUState, gpr[1]) },
  589 + { "r2", offsetof(CPUState, gpr[2]) },
  590 + { "r3", offsetof(CPUState, gpr[3]) },
  591 + { "r4", offsetof(CPUState, gpr[4]) },
  592 + { "r5", offsetof(CPUState, gpr[5]) },
  593 + { "r6", offsetof(CPUState, gpr[6]) },
  594 + { "r7", offsetof(CPUState, gpr[7]) },
  595 + { "r8", offsetof(CPUState, gpr[8]) },
  596 + { "r9", offsetof(CPUState, gpr[9]) },
  597 + { "r10", offsetof(CPUState, gpr[10]) },
  598 + { "r11", offsetof(CPUState, gpr[11]) },
  599 + { "r12", offsetof(CPUState, gpr[12]) },
  600 + { "r13", offsetof(CPUState, gpr[13]) },
  601 + { "r14", offsetof(CPUState, gpr[14]) },
  602 + { "r15", offsetof(CPUState, gpr[15]) },
  603 + { "r16", offsetof(CPUState, gpr[16]) },
  604 + { "r17", offsetof(CPUState, gpr[17]) },
  605 + { "r18", offsetof(CPUState, gpr[18]) },
  606 + { "r19", offsetof(CPUState, gpr[19]) },
  607 + { "r20", offsetof(CPUState, gpr[20]) },
  608 + { "r21", offsetof(CPUState, gpr[21]) },
  609 + { "r22", offsetof(CPUState, gpr[22]) },
  610 + { "r23", offsetof(CPUState, gpr[23]) },
  611 + { "r24", offsetof(CPUState, gpr[24]) },
  612 + { "r25", offsetof(CPUState, gpr[25]) },
  613 + { "r26", offsetof(CPUState, gpr[26]) },
  614 + { "r27", offsetof(CPUState, gpr[27]) },
  615 + { "r28", offsetof(CPUState, gpr[28]) },
  616 + { "r29", offsetof(CPUState, gpr[29]) },
  617 + { "r30", offsetof(CPUState, gpr[30]) },
  618 + { "r31", offsetof(CPUState, gpr[31]) },
  619 + { "lr", offsetof(CPUState, lr) },
  620 + { "ctr", offsetof(CPUState, ctr) },
  621 + { "decr", offsetof(CPUState, decr) },
  622 + { "ccr", 0, &monitor_get_ccr, },
  623 + { "msr", 0, &monitor_get_msr, },
  624 + { "xer", 0, &monitor_get_xer, },
  625 + { "tbu", offsetof(CPUState, tb[0]) },
  626 + { "tbl", offsetof(CPUState, tb[1]) },
  627 + { "sdr1", offsetof(CPUState, sdr1) },
  628 + { "sr0", offsetof(CPUState, sr[0]) },
  629 + { "sr1", offsetof(CPUState, sr[1]) },
  630 + { "sr2", offsetof(CPUState, sr[2]) },
  631 + { "sr3", offsetof(CPUState, sr[3]) },
  632 + { "sr4", offsetof(CPUState, sr[4]) },
  633 + { "sr5", offsetof(CPUState, sr[5]) },
  634 + { "sr6", offsetof(CPUState, sr[6]) },
  635 + { "sr7", offsetof(CPUState, sr[7]) },
  636 + { "sr8", offsetof(CPUState, sr[8]) },
  637 + { "sr9", offsetof(CPUState, sr[9]) },
  638 + { "sr10", offsetof(CPUState, sr[10]) },
  639 + { "sr11", offsetof(CPUState, sr[11]) },
  640 + { "sr12", offsetof(CPUState, sr[12]) },
  641 + { "sr13", offsetof(CPUState, sr[13]) },
  642 + { "sr14", offsetof(CPUState, sr[14]) },
  643 + { "sr15", offsetof(CPUState, sr[15]) },
  644 + /* Too lazy to put BATs and SPRs ... */
545 #endif 645 #endif
546 { NULL }, 646 { NULL },
547 }; 647 };
target-ppc/cpu.h
@@ -20,9 +20,6 @@ @@ -20,9 +20,6 @@
20 #if !defined (__CPU_PPC_H__) 20 #if !defined (__CPU_PPC_H__)
21 #define __CPU_PPC_H__ 21 #define __CPU_PPC_H__
22 22
23 -#include <endian.h>  
24 -#include <asm/byteorder.h>  
25 -  
26 #define TARGET_LONG_BITS 32 23 #define TARGET_LONG_BITS 32
27 24
28 #include "cpu-defs.h" 25 #include "cpu-defs.h"
@@ -157,14 +154,26 @@ typedef struct CPUPPCState { @@ -157,14 +154,26 @@ typedef struct CPUPPCState {
157 int error_code; 154 int error_code;
158 int access_type; /* when a memory exception occurs, the access 155 int access_type; /* when a memory exception occurs, the access
159 type is stored here */ 156 type is stored here */
  157 +#if 0 /* TODO */
  158 + uint32_t pending_exceptions; /* For external & decr exception,
  159 + * that can be delayed */
  160 +#else
160 uint32_t exceptions; /* exception queue */ 161 uint32_t exceptions; /* exception queue */
161 - uint32_t errors[16]; 162 + uint32_t errors[32];
  163 +#endif
162 int user_mode_only; /* user mode only simulation */ 164 int user_mode_only; /* user mode only simulation */
163 struct TranslationBlock *current_tb; /* currently executing TB */ 165 struct TranslationBlock *current_tb; /* currently executing TB */
164 /* soft mmu support */ 166 /* soft mmu support */
165 - /* 0 = kernel, 1 = user */ 167 + /* 0 = kernel, 1 = user (may have 2 = kernel code, 3 = user code ?) */
166 CPUTLBEntry tlb_read[2][CPU_TLB_SIZE]; 168 CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
167 CPUTLBEntry tlb_write[2][CPU_TLB_SIZE]; 169 CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];
  170 +
  171 + /* ice debug support */
  172 + uint32_t breakpoints[MAX_BREAKPOINTS];
  173 + int nb_breakpoints;
  174 + int brkstate;
  175 + int singlestep_enabled;
  176 +
168 /* user data */ 177 /* user data */
169 void *opaque; 178 void *opaque;
170 } CPUPPCState; 179 } CPUPPCState;
@@ -179,14 +188,21 @@ struct siginfo; @@ -179,14 +188,21 @@ struct siginfo;
179 int cpu_ppc_signal_handler(int host_signum, struct siginfo *info, 188 int cpu_ppc_signal_handler(int host_signum, struct siginfo *info,
180 void *puc); 189 void *puc);
181 190
182 -void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags); 191 +void do_interrupt (CPUPPCState *env);
183 void cpu_loop_exit(void); 192 void cpu_loop_exit(void);
  193 +
  194 +void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags);
184 void dump_stack (CPUPPCState *env); 195 void dump_stack (CPUPPCState *env);
185 -uint32_t _load_xer (void);  
186 -void _store_xer (uint32_t value);  
187 -uint32_t _load_msr (void);  
188 -void _store_msr (uint32_t value);  
189 -void do_interrupt (CPUPPCState *env); 196 +
  197 +uint32_t _load_xer (CPUPPCState *env);
  198 +void _store_xer (CPUPPCState *env, uint32_t value);
  199 +uint32_t _load_msr (CPUPPCState *env);
  200 +void _store_msr (CPUPPCState *env, uint32_t value);
  201 +
  202 +void PPC_init_hw (uint32_t mem_size,
  203 + uint32_t kernel_addr, uint32_t kernel_size,
  204 + uint32_t stack_addr, int boot_device,
  205 + const unsigned char *initrd_file);
190 206
191 #define TARGET_PAGE_BITS 12 207 #define TARGET_PAGE_BITS 12
192 #include "cpu-all.h" 208 #include "cpu-all.h"
@@ -277,14 +293,6 @@ void do_interrupt (CPUPPCState *env); @@ -277,14 +293,6 @@ void do_interrupt (CPUPPCState *env);
277 #define TARGET_PAGE_BITS 12 293 #define TARGET_PAGE_BITS 12
278 #include "cpu-all.h" 294 #include "cpu-all.h"
279 295
280 -CPUPPCState *cpu_ppc_init(void);  
281 -int cpu_ppc_exec(CPUPPCState *s);  
282 -void cpu_ppc_close(CPUPPCState *s);  
283 -void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags);  
284 -void PPC_init_hw (CPUPPCState *env, uint32_t mem_size,  
285 - uint32_t kernel_addr, uint32_t kernel_size,  
286 - uint32_t stack_addr, int boot_device);  
287 -  
288 /* Memory access type : 296 /* Memory access type :
289 * may be needed for precise access rights control and precise exceptions. 297 * may be needed for precise access rights control and precise exceptions.
290 */ 298 */
@@ -351,12 +359,14 @@ enum { @@ -351,12 +359,14 @@ enum {
351 /* flags for EXCP_DSI */ 359 /* flags for EXCP_DSI */
352 EXCP_DSI_DIRECT = 0x10, 360 EXCP_DSI_DIRECT = 0x10,
353 EXCP_DSI_STORE = 0x20, 361 EXCP_DSI_STORE = 0x20,
354 - EXCP_ECXW = 0x40, 362 + EXCP_DSI_ECXW = 0x40,
355 /* Exception subtypes for EXCP_ISI */ 363 /* Exception subtypes for EXCP_ISI */
356 EXCP_ISI_TRANSLATE = 0x01, /* Code address can't be translated */ 364 EXCP_ISI_TRANSLATE = 0x01, /* Code address can't be translated */
357 EXCP_ISI_NOEXEC = 0x02, /* Try to fetch from a data segment */ 365 EXCP_ISI_NOEXEC = 0x02, /* Try to fetch from a data segment */
358 EXCP_ISI_GUARD = 0x03, /* Fetch from guarded memory */ 366 EXCP_ISI_GUARD = 0x03, /* Fetch from guarded memory */
359 EXCP_ISI_PROT = 0x04, /* Memory protection violation */ 367 EXCP_ISI_PROT = 0x04, /* Memory protection violation */
  368 + EXCP_ISI_DIRECT = 0x05, /* Trying to fetch from *
  369 + * a direct store segment */
360 /* Exception subtypes for EXCP_ALIGN */ 370 /* Exception subtypes for EXCP_ALIGN */
361 EXCP_ALIGN_FP = 0x01, /* FP alignment exception */ 371 EXCP_ALIGN_FP = 0x01, /* FP alignment exception */
362 EXCP_ALIGN_LST = 0x02, /* Unaligned mult/extern load/store */ 372 EXCP_ALIGN_LST = 0x02, /* Unaligned mult/extern load/store */
target-ppc/exec.h
@@ -36,7 +36,11 @@ register uint32_t T2 asm(AREG3); @@ -36,7 +36,11 @@ register uint32_t T2 asm(AREG3);
36 #define FTS1 ((float)env->ft1) 36 #define FTS1 ((float)env->ft1)
37 #define FTS2 ((float)env->ft2) 37 #define FTS2 ((float)env->ft2)
38 38
  39 +#if defined (DEBUG_OP)
  40 +#define RETURN() __asm__ __volatile__("nop");
  41 +#else
39 #define RETURN() __asm__ __volatile__(""); 42 #define RETURN() __asm__ __volatile__("");
  43 +#endif
40 44
41 #include "cpu.h" 45 #include "cpu.h"
42 #include "exec-all.h" 46 #include "exec-all.h"
@@ -149,6 +153,7 @@ void do_icbi (void); @@ -149,6 +153,7 @@ void do_icbi (void);
149 void do_tlbia (void); 153 void do_tlbia (void);
150 void do_tlbie (void); 154 void do_tlbie (void);
151 155
  156 +void dump_state (void);
152 void dump_rfi (void); 157 void dump_rfi (void);
153 void dump_store_sr (int srnum); 158 void dump_store_sr (int srnum);
154 void dump_store_ibat (int ul, int nr); 159 void dump_store_ibat (int ul, int nr);
target-ppc/helper.c
@@ -21,6 +21,7 @@ @@ -21,6 +21,7 @@
21 21
22 #include "exec.h" 22 #include "exec.h"
23 #if defined (USE_OPEN_FIRMWARE) 23 #if defined (USE_OPEN_FIRMWARE)
  24 +#include <time.h>
24 #include "of.h" 25 #include "of.h"
25 #endif 26 #endif
26 27
@@ -28,7 +29,7 @@ @@ -28,7 +29,7 @@
28 //#define DEBUG_BATS 29 //#define DEBUG_BATS
29 //#define DEBUG_EXCEPTIONS 30 //#define DEBUG_EXCEPTIONS
30 31
31 -extern FILE *logfile, *stderr; 32 +extern FILE *logfile, *stdout, *stderr;
32 void exit (int); 33 void exit (int);
33 void abort (void); 34 void abort (void);
34 35
@@ -74,6 +75,9 @@ int check_exception_state (CPUState *env) @@ -74,6 +75,9 @@ int check_exception_state (CPUState *env)
74 75
75 /*****************************************************************************/ 76 /*****************************************************************************/
76 /* PPC MMU emulation */ 77 /* PPC MMU emulation */
  78 +int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
  79 + int is_user, int is_softmmu);
  80 +
77 /* Perform BAT hit & translation */ 81 /* Perform BAT hit & translation */
78 static int get_bat (CPUState *env, uint32_t *real, int *prot, 82 static int get_bat (CPUState *env, uint32_t *real, int *prot,
79 uint32_t virtual, int rw, int type) 83 uint32_t virtual, int rw, int type)
@@ -88,8 +92,6 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot, @@ -88,8 +92,6 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot,
88 fprintf(logfile, "%s: %cBAT v 0x%08x\n", __func__, 92 fprintf(logfile, "%s: %cBAT v 0x%08x\n", __func__,
89 type == ACCESS_CODE ? 'I' : 'D', virtual); 93 type == ACCESS_CODE ? 'I' : 'D', virtual);
90 } 94 }
91 - printf("%s: %cBAT v 0x%08x\n", __func__,  
92 - type == ACCESS_CODE ? 'I' : 'D', virtual);  
93 #endif 95 #endif
94 switch (type) { 96 switch (type) {
95 case ACCESS_CODE: 97 case ACCESS_CODE:
@@ -106,8 +108,6 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot, @@ -106,8 +108,6 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot,
106 fprintf(logfile, "%s...: %cBAT v 0x%08x\n", __func__, 108 fprintf(logfile, "%s...: %cBAT v 0x%08x\n", __func__,
107 type == ACCESS_CODE ? 'I' : 'D', virtual); 109 type == ACCESS_CODE ? 'I' : 'D', virtual);
108 } 110 }
109 - printf("%s...: %cBAT v 0x%08x\n", __func__,  
110 - type == ACCESS_CODE ? 'I' : 'D', virtual);  
111 #endif 111 #endif
112 base = virtual & 0xFFFC0000; 112 base = virtual & 0xFFFC0000;
113 for (i = 0; i < 4; i++) { 113 for (i = 0; i < 4; i++) {
@@ -121,10 +121,6 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot, @@ -121,10 +121,6 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot,
121 fprintf(logfile, "%s: %cBAT%d v 0x%08x BATu 0x%08x BATl 0x%08x\n", 121 fprintf(logfile, "%s: %cBAT%d v 0x%08x BATu 0x%08x BATl 0x%08x\n",
122 __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual, 122 __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
123 *BATu, *BATl); 123 *BATu, *BATl);
124 - } else {  
125 - printf("%s: %cBAT%d v 0x%08x BATu 0x%08x BATl 0x%08x\n",  
126 - __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,  
127 - *BATu, *BATl);  
128 } 124 }
129 #endif 125 #endif
130 if ((virtual & 0xF0000000) == BEPIu && 126 if ((virtual & 0xF0000000) == BEPIu &&
@@ -135,7 +131,7 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot, @@ -135,7 +131,7 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot,
135 /* Get physical address */ 131 /* Get physical address */
136 *real = (*BATl & 0xF0000000) | 132 *real = (*BATl & 0xF0000000) |
137 ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) | 133 ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
138 - (virtual & 0x0001FFFF); 134 + (virtual & 0x0001F000);
139 if (*BATl & 0x00000001) 135 if (*BATl & 0x00000001)
140 *prot = PROT_READ; 136 *prot = PROT_READ;
141 if (*BATl & 0x00000002) 137 if (*BATl & 0x00000002)
@@ -145,10 +141,6 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot, @@ -145,10 +141,6 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot,
145 fprintf(logfile, "BAT %d match: r 0x%08x prot=%c%c\n", 141 fprintf(logfile, "BAT %d match: r 0x%08x prot=%c%c\n",
146 i, *real, *prot & PROT_READ ? 'R' : '-', 142 i, *real, *prot & PROT_READ ? 'R' : '-',
147 *prot & PROT_WRITE ? 'W' : '-'); 143 *prot & PROT_WRITE ? 'W' : '-');
148 - } else {  
149 - printf("BAT %d match: 0x%08x => 0x%08x prot=%c%c\n",  
150 - i, virtual, *real, *prot & PROT_READ ? 'R' : '-',  
151 - *prot & PROT_WRITE ? 'W' : '-');  
152 } 144 }
153 #endif 145 #endif
154 ret = 0; 146 ret = 0;
@@ -181,7 +173,7 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot, @@ -181,7 +173,7 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot,
181 static int find_pte (uint32_t *RPN, int *prot, uint32_t base, uint32_t va, 173 static int find_pte (uint32_t *RPN, int *prot, uint32_t base, uint32_t va,
182 int h, int key, int rw) 174 int h, int key, int rw)
183 { 175 {
184 - uint32_t pte0, pte1, keep = 0; 176 + uint32_t pte0, pte1, keep = 0, access = 0;
185 int i, good = -1, store = 0; 177 int i, good = -1, store = 0;
186 int ret = -1; /* No entry found */ 178 int ret = -1; /* No entry found */
187 179
@@ -189,85 +181,97 @@ static int find_pte (uint32_t *RPN, int *prot, uint32_t base, uint32_t va, @@ -189,85 +181,97 @@ static int find_pte (uint32_t *RPN, int *prot, uint32_t base, uint32_t va,
189 pte0 = ldl_raw((void *)((uint32_t)phys_ram_base + base + (i * 8))); 181 pte0 = ldl_raw((void *)((uint32_t)phys_ram_base + base + (i * 8)));
190 pte1 = ldl_raw((void *)((uint32_t)phys_ram_base + base + (i * 8) + 4)); 182 pte1 = ldl_raw((void *)((uint32_t)phys_ram_base + base + (i * 8) + 4));
191 #if defined (DEBUG_MMU) 183 #if defined (DEBUG_MMU)
192 - printf("Load pte from 0x%08x => 0x%08x 0x%08x\n", base + (i * 8),  
193 - pte0, pte1); 184 + if (loglevel > 0) {
  185 + fprintf(logfile, "Load pte from 0x%08x => 0x%08x 0x%08x "
  186 + "%d %d %d 0x%08x\n", base + (i * 8), pte0, pte1,
  187 + pte0 >> 31, h, (pte0 >> 6) & 1, va);
  188 + }
194 #endif 189 #endif
195 /* Check validity and table match */ 190 /* Check validity and table match */
196 if (pte0 & 0x80000000 && (h == ((pte0 >> 6) & 1))) { 191 if (pte0 & 0x80000000 && (h == ((pte0 >> 6) & 1))) {
197 -#if defined (DEBUG_MMU)  
198 - printf("PTE is valid and table matches... compare 0x%08x:%08x\n",  
199 - pte0 & 0x7FFFFFBF, va);  
200 -#endif  
201 /* Check vsid & api */ 192 /* Check vsid & api */
202 if ((pte0 & 0x7FFFFFBF) == va) { 193 if ((pte0 & 0x7FFFFFBF) == va) {
203 -#if defined (DEBUG_MMU)  
204 - printf("PTE match !\n");  
205 -#endif  
206 if (good == -1) { 194 if (good == -1) {
207 good = i; 195 good = i;
208 keep = pte1; 196 keep = pte1;
209 } else { 197 } else {
210 /* All matches should have equal RPN, WIMG & PP */ 198 /* All matches should have equal RPN, WIMG & PP */
211 if ((keep & 0xFFFFF07B) != (pte1 & 0xFFFFF07B)) { 199 if ((keep & 0xFFFFF07B) != (pte1 & 0xFFFFF07B)) {
212 - printf("Bad RPN/WIMG/PP\n"); 200 + if (loglevel > 0)
  201 + fprintf(logfile, "Bad RPN/WIMG/PP\n");
213 return -1; 202 return -1;
214 } 203 }
215 } 204 }
216 /* Check access rights */ 205 /* Check access rights */
217 if (key == 0) { 206 if (key == 0) {
218 - *prot = PROT_READ; 207 + access = PROT_READ;
219 if ((pte1 & 0x00000003) != 0x3) 208 if ((pte1 & 0x00000003) != 0x3)
220 - *prot |= PROT_WRITE; 209 + access |= PROT_WRITE;
221 } else { 210 } else {
222 switch (pte1 & 0x00000003) { 211 switch (pte1 & 0x00000003) {
223 case 0x0: 212 case 0x0:
224 - *prot = 0; 213 + access = 0;
225 break; 214 break;
226 case 0x1: 215 case 0x1:
227 case 0x3: 216 case 0x3:
228 - *prot = PROT_READ; 217 + access = PROT_READ;
229 break; 218 break;
230 case 0x2: 219 case 0x2:
231 - *prot = PROT_READ | PROT_WRITE; 220 + access = PROT_READ | PROT_WRITE;
232 break; 221 break;
233 } 222 }
234 } 223 }
235 - if ((rw == 0 && *prot != 0) ||  
236 - (rw == 1 && (*prot & PROT_WRITE))) { 224 + if (ret < 0) {
  225 + if ((rw == 0 && (access & PROT_READ)) ||
  226 + (rw == 1 && (access & PROT_WRITE))) {
237 #if defined (DEBUG_MMU) 227 #if defined (DEBUG_MMU)
238 - printf("PTE access granted !\n"); 228 + if (loglevel > 0)
  229 + fprintf(logfile, "PTE access granted !\n");
239 #endif 230 #endif
240 good = i; 231 good = i;
241 keep = pte1; 232 keep = pte1;
242 ret = 0; 233 ret = 0;
243 - } else if (ret == -1) {  
244 - ret = -2; /* Access right violation */ 234 + } else {
  235 + /* Access right violation */
  236 + ret = -2;
245 #if defined (DEBUG_MMU) 237 #if defined (DEBUG_MMU)
246 - printf("PTE access rejected\n"); 238 + if (loglevel > 0)
  239 + fprintf(logfile, "PTE access rejected\n");
247 #endif 240 #endif
248 } 241 }
  242 + *prot = access;
  243 + }
249 } 244 }
250 } 245 }
251 } 246 }
252 if (good != -1) { 247 if (good != -1) {
253 *RPN = keep & 0xFFFFF000; 248 *RPN = keep & 0xFFFFF000;
254 #if defined (DEBUG_MMU) 249 #if defined (DEBUG_MMU)
255 - printf("found PTE at addr 0x%08x prot=0x%01x ret=%d\n", 250 + if (loglevel > 0) {
  251 + fprintf(logfile, "found PTE at addr 0x%08x prot=0x%01x ret=%d\n",
256 *RPN, *prot, ret); 252 *RPN, *prot, ret);
  253 + }
257 #endif 254 #endif
258 /* Update page flags */ 255 /* Update page flags */
259 if (!(keep & 0x00000100)) { 256 if (!(keep & 0x00000100)) {
  257 + /* Access flag */
260 keep |= 0x00000100; 258 keep |= 0x00000100;
261 store = 1; 259 store = 1;
262 } 260 }
263 - if (rw) {  
264 if (!(keep & 0x00000080)) { 261 if (!(keep & 0x00000080)) {
  262 + if (rw && ret == 0) {
  263 + /* Change flag */
265 keep |= 0x00000080; 264 keep |= 0x00000080;
266 store = 1; 265 store = 1;
  266 + } else {
  267 + /* Force page fault for first write access */
  268 + *prot &= ~PROT_WRITE;
267 } 269 }
268 } 270 }
269 - if (store)  
270 - stl_raw((void *)(base + (good * 2) + 1), keep); 271 + if (store) {
  272 + stl_raw((void *)((uint32_t)phys_ram_base + base + (good * 8) + 4),
  273 + keep);
  274 + }
271 } 275 }
272 276
273 return ret; 277 return ret;
@@ -290,29 +294,37 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot, @@ -290,29 +294,37 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot,
290 294
291 sr = env->sr[virtual >> 28]; 295 sr = env->sr[virtual >> 28];
292 #if defined (DEBUG_MMU) 296 #if defined (DEBUG_MMU)
293 - printf("Check segment v=0x%08x %d 0x%08x nip=0x%08x lr=0x%08x ir=%d dr=%d "  
294 - "pr=%d t=%d\n", virtual, virtual >> 28, sr, env->nip,  
295 - env->lr, msr_ir, msr_dr, msr_pr, type); 297 + if (loglevel > 0) {
  298 + fprintf(logfile, "Check segment v=0x%08x %d 0x%08x nip=0x%08x "
  299 + "lr=0x%08x ir=%d dr=%d pr=%d %d t=%d\n",
  300 + virtual, virtual >> 28, sr, env->nip,
  301 + env->lr, msr_ir, msr_dr, msr_pr, rw, type);
  302 + }
296 #endif 303 #endif
297 - key = ((sr & 0x20000000) && msr_pr == 1) ||  
298 - ((sr & 0x40000000) && msr_pr == 0) ? 1 : 0; 304 + key = (((sr & 0x20000000) && msr_pr == 1) ||
  305 + ((sr & 0x40000000) && msr_pr == 0)) ? 1 : 0;
299 if ((sr & 0x80000000) == 0) { 306 if ((sr & 0x80000000) == 0) {
300 #if defined (DEBUG_MMU) 307 #if defined (DEBUG_MMU)
301 - printf("pte segment: key=%d n=0x%08x\n", key, sr & 0x10000000); 308 + if (loglevel > 0)
  309 + fprintf(logfile, "pte segment: key=%d n=0x%08x\n",
  310 + key, sr & 0x10000000);
302 #endif 311 #endif
303 /* Check if instruction fetch is allowed, if needed */ 312 /* Check if instruction fetch is allowed, if needed */
304 if (type != ACCESS_CODE || (sr & 0x10000000) == 0) { 313 if (type != ACCESS_CODE || (sr & 0x10000000) == 0) {
305 /* Page address translation */ 314 /* Page address translation */
306 vsid = sr & 0x00FFFFFF; 315 vsid = sr & 0x00FFFFFF;
307 pgidx = (virtual >> 12) & 0xFFFF; 316 pgidx = (virtual >> 12) & 0xFFFF;
308 - sdr = env->spr[SDR1];  
309 - hash = ((vsid ^ pgidx) & 0x07FFFF) << 6; 317 + sdr = env->sdr1;
  318 + hash = ((vsid ^ pgidx) & 0x0007FFFF) << 6;
310 mask = ((sdr & 0x000001FF) << 16) | 0xFFC0; 319 mask = ((sdr & 0x000001FF) << 16) | 0xFFC0;
311 pg_addr = get_pgaddr(sdr, hash, mask); 320 pg_addr = get_pgaddr(sdr, hash, mask);
312 ptem = (vsid << 7) | (pgidx >> 10); 321 ptem = (vsid << 7) | (pgidx >> 10);
313 #if defined (DEBUG_MMU) 322 #if defined (DEBUG_MMU)
314 - printf("0 sdr1=0x%08x vsid=0x%06x api=0x%04x hash=0x%07x "  
315 - "pg_addr=0x%08x\n", sdr, vsid, pgidx, hash, pg_addr); 323 + if (loglevel > 0) {
  324 + fprintf(logfile, "0 sdr1=0x%08x vsid=0x%06x api=0x%04x "
  325 + "hash=0x%07x pg_addr=0x%08x\n", sdr, vsid, pgidx, hash,
  326 + pg_addr);
  327 + }
316 #endif 328 #endif
317 /* Primary table lookup */ 329 /* Primary table lookup */
318 ret = find_pte(real, prot, pg_addr, ptem, 0, key, rw); 330 ret = find_pte(real, prot, pg_addr, ptem, 0, key, rw);
@@ -321,25 +333,27 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot, @@ -321,25 +333,27 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot,
321 hash = (~hash) & 0x01FFFFC0; 333 hash = (~hash) & 0x01FFFFC0;
322 pg_addr = get_pgaddr(sdr, hash, mask); 334 pg_addr = get_pgaddr(sdr, hash, mask);
323 #if defined (DEBUG_MMU) 335 #if defined (DEBUG_MMU)
324 - printf("1 sdr1=0x%08x vsid=0x%06x api=0x%04x hash=0x%05x "  
325 - "pg_addr=0x%08x\n", sdr, vsid, pgidx, hash, pg_addr); 336 + if (virtual != 0xEFFFFFFF && loglevel > 0) {
  337 + fprintf(logfile, "1 sdr1=0x%08x vsid=0x%06x api=0x%04x "
  338 + "hash=0x%05x pg_addr=0x%08x\n", sdr, vsid, pgidx,
  339 + hash, pg_addr);
  340 + }
326 #endif 341 #endif
327 ret2 = find_pte(real, prot, pg_addr, ptem, 1, key, rw); 342 ret2 = find_pte(real, prot, pg_addr, ptem, 1, key, rw);
328 if (ret2 != -1) 343 if (ret2 != -1)
329 ret = ret2; 344 ret = ret2;
330 } 345 }
331 - if (ret != -1)  
332 - *real |= (virtual & 0x00000FFF);  
333 - if (ret == -2 && type == ACCESS_CODE && (sr & 0x10000000))  
334 - ret = -3;  
335 } else { 346 } else {
336 #if defined (DEBUG_MMU) 347 #if defined (DEBUG_MMU)
337 - printf("No access allowed\n"); 348 + if (loglevel > 0)
  349 + fprintf(logfile, "No access allowed\n");
338 #endif 350 #endif
  351 + ret = -3;
339 } 352 }
340 } else { 353 } else {
341 #if defined (DEBUG_MMU) 354 #if defined (DEBUG_MMU)
342 - printf("direct store...\n"); 355 + if (loglevel > 0)
  356 + fprintf(logfile, "direct store...\n");
343 #endif 357 #endif
344 /* Direct-store segment : absolutely *BUGGY* for now */ 358 /* Direct-store segment : absolutely *BUGGY* for now */
345 switch (type) { 359 switch (type) {
@@ -393,9 +407,10 @@ int get_physical_address (CPUState *env, uint32_t *physical, int *prot, @@ -393,9 +407,10 @@ int get_physical_address (CPUState *env, uint32_t *physical, int *prot,
393 if (loglevel > 0) { 407 if (loglevel > 0) {
394 fprintf(logfile, "%s\n", __func__); 408 fprintf(logfile, "%s\n", __func__);
395 } 409 }
  410 +
396 if ((access_type == ACCESS_CODE && msr_ir == 0) || msr_dr == 0) { 411 if ((access_type == ACCESS_CODE && msr_ir == 0) || msr_dr == 0) {
397 /* No address translation */ 412 /* No address translation */
398 - *physical = address; 413 + *physical = address & ~0xFFF;
399 *prot = PROT_READ | PROT_WRITE; 414 *prot = PROT_READ | PROT_WRITE;
400 ret = 0; 415 ret = 0;
401 } else { 416 } else {
@@ -406,6 +421,10 @@ int get_physical_address (CPUState *env, uint32_t *physical, int *prot, @@ -406,6 +421,10 @@ int get_physical_address (CPUState *env, uint32_t *physical, int *prot,
406 ret = get_segment(env, physical, prot, address, rw, access_type); 421 ret = get_segment(env, physical, prot, address, rw, access_type);
407 } 422 }
408 } 423 }
  424 + if (loglevel > 0) {
  425 + fprintf(logfile, "%s address %08x => %08x\n",
  426 + __func__, address, *physical);
  427 + }
409 428
410 return ret; 429 return ret;
411 } 430 }
@@ -448,18 +467,17 @@ target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) @@ -448,18 +467,17 @@ target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
448 NULL, it means that the function was called in C code (i.e. not 467 NULL, it means that the function was called in C code (i.e. not
449 from generated code or from helper.c) */ 468 from generated code or from helper.c) */
450 /* XXX: fix it to restore all registers */ 469 /* XXX: fix it to restore all registers */
451 -void tlb_fill(unsigned long addr, int is_write, int flags, void *retaddr) 470 +void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr)
452 { 471 {
453 TranslationBlock *tb; 472 TranslationBlock *tb;
454 - int ret, is_user;  
455 - unsigned long pc;  
456 CPUState *saved_env; 473 CPUState *saved_env;
  474 + unsigned long pc;
  475 + int ret;
457 476
458 /* XXX: hack to restore env in all cases, even if not called from 477 /* XXX: hack to restore env in all cases, even if not called from
459 generated code */ 478 generated code */
460 saved_env = env; 479 saved_env = env;
461 env = cpu_single_env; 480 env = cpu_single_env;
462 - is_user = flags & 0x01;  
463 { 481 {
464 unsigned long tlb_addrr, tlb_addrw; 482 unsigned long tlb_addrr, tlb_addrw;
465 int index; 483 int index;
@@ -474,7 +492,7 @@ void tlb_fill(unsigned long addr, int is_write, int flags, void *retaddr) @@ -474,7 +492,7 @@ void tlb_fill(unsigned long addr, int is_write, int flags, void *retaddr)
474 tlb_addrr & (TARGET_PAGE_MASK | TLB_INVALID_MASK)); 492 tlb_addrr & (TARGET_PAGE_MASK | TLB_INVALID_MASK));
475 #endif 493 #endif
476 } 494 }
477 - ret = cpu_handle_mmu_fault(env, addr, is_write, flags, 1); 495 + ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, is_user, 1);
478 if (ret) { 496 if (ret) {
479 if (retaddr) { 497 if (retaddr) {
480 /* now we have a real cpu fault */ 498 /* now we have a real cpu fault */
@@ -506,7 +524,7 @@ void tlb_fill(unsigned long addr, int is_write, int flags, void *retaddr) @@ -506,7 +524,7 @@ void tlb_fill(unsigned long addr, int is_write, int flags, void *retaddr)
506 env = saved_env; 524 env = saved_env;
507 } 525 }
508 526
509 -void cpu_ppc_init_mmu(CPUPPCState *env) 527 +void cpu_ppc_init_mmu(CPUState *env)
510 { 528 {
511 /* Nothing to do: all translation are disabled */ 529 /* Nothing to do: all translation are disabled */
512 } 530 }
@@ -514,59 +532,36 @@ void cpu_ppc_init_mmu(CPUPPCState *env) @@ -514,59 +532,36 @@ void cpu_ppc_init_mmu(CPUPPCState *env)
514 532
515 /* Perform address translation */ 533 /* Perform address translation */
516 int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, 534 int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
517 - int flags, int is_softmmu) 535 + int is_user, int is_softmmu)
518 { 536 {
519 uint32_t physical; 537 uint32_t physical;
520 int prot; 538 int prot;
521 int exception = 0, error_code = 0; 539 int exception = 0, error_code = 0;
522 - int is_user, access_type; 540 + int access_type;
523 int ret = 0; 541 int ret = 0;
524 542
525 // printf("%s 0\n", __func__); 543 // printf("%s 0\n", __func__);
526 - is_user = flags & 0x01;  
527 access_type = env->access_type; 544 access_type = env->access_type;
528 if (env->user_mode_only) { 545 if (env->user_mode_only) {
529 /* user mode only emulation */ 546 /* user mode only emulation */
530 ret = -1; 547 ret = -1;
531 goto do_fault; 548 goto do_fault;
532 } 549 }
  550 + /* NASTY BUG workaround */
  551 + if (access_type == ACCESS_CODE && rw) {
  552 + // printf("%s: ERROR WRITE CODE ACCESS\n", __func__);
  553 + access_type = ACCESS_INT;
  554 + }
533 ret = get_physical_address(env, &physical, &prot, 555 ret = get_physical_address(env, &physical, &prot,
534 address, rw, access_type); 556 address, rw, access_type);
535 if (ret == 0) { 557 if (ret == 0) {
536 - ret = tlb_set_page(env, address, physical, prot, is_user, is_softmmu); 558 + ret = tlb_set_page(env, address & ~0xFFF, physical, prot,
  559 + is_user, is_softmmu);
537 } else if (ret < 0) { 560 } else if (ret < 0) {
538 do_fault: 561 do_fault:
539 #if defined (DEBUG_MMU) 562 #if defined (DEBUG_MMU)
540 - printf("%s 5\n", __func__);  
541 - printf("nip=0x%08x LR=0x%08x CTR=0x%08x MSR=0x%08x TBL=0x%08x\n",  
542 - env->nip, env->lr, env->ctr, /*msr*/0, env->tb[0]);  
543 - {  
544 - int i;  
545 - for (i = 0; i < 32; i++) {  
546 - if ((i & 7) == 0)  
547 - printf("GPR%02d:", i);  
548 - printf(" %08x", env->gpr[i]);  
549 - if ((i & 7) == 7)  
550 - printf("\n");  
551 - }  
552 - printf("CR: 0x");  
553 - for (i = 0; i < 8; i++)  
554 - printf("%01x", env->crf[i]);  
555 - printf(" [");  
556 - for (i = 0; i < 8; i++) {  
557 - char a = '-';  
558 - if (env->crf[i] & 0x08)  
559 - a = 'L';  
560 - else if (env->crf[i] & 0x04)  
561 - a = 'G';  
562 - else if (env->crf[i] & 0x02)  
563 - a = 'E';  
564 - printf(" %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');  
565 - }  
566 - printf(" ] ");  
567 - }  
568 - printf("TB: 0x%08x %08x\n", env->tb[1], env->tb[0]);  
569 - printf("SRR0 0x%08x SRR1 0x%08x\n", env->spr[SRR0], env->spr[SRR1]); 563 + if (loglevel > 0)
  564 + cpu_ppc_dump_state(env, logfile, 0);
570 #endif 565 #endif
571 if (access_type == ACCESS_CODE) { 566 if (access_type == ACCESS_CODE) {
572 exception = EXCP_ISI; 567 exception = EXCP_ISI;
@@ -580,13 +575,13 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -580,13 +575,13 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
580 error_code = EXCP_ISI_PROT; 575 error_code = EXCP_ISI_PROT;
581 break; 576 break;
582 case -3: 577 case -3:
  578 + /* No execute protection violation */
583 error_code = EXCP_ISI_NOEXEC; 579 error_code = EXCP_ISI_NOEXEC;
584 break; 580 break;
585 case -4: 581 case -4:
586 /* Direct store exception */ 582 /* Direct store exception */
587 /* No code fetch is allowed in direct-store areas */ 583 /* No code fetch is allowed in direct-store areas */
588 - exception = EXCP_ISI;  
589 - error_code = EXCP_ISI_NOEXEC; 584 + error_code = EXCP_ISI_DIRECT;
590 break; 585 break;
591 } 586 }
592 } else { 587 } else {
@@ -612,15 +607,15 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -612,15 +607,15 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
612 /* lwarx, ldarx or srwcx. */ 607 /* lwarx, ldarx or srwcx. */
613 exception = EXCP_DSI; 608 exception = EXCP_DSI;
614 error_code = EXCP_DSI_NOTSUP | EXCP_DSI_DIRECT; 609 error_code = EXCP_DSI_NOTSUP | EXCP_DSI_DIRECT;
615 - if (rw)  
616 - error_code |= EXCP_DSI_STORE;  
617 break; 610 break;
618 case ACCESS_EXT: 611 case ACCESS_EXT:
619 /* eciwx or ecowx */ 612 /* eciwx or ecowx */
620 exception = EXCP_DSI; 613 exception = EXCP_DSI;
621 - error_code = EXCP_DSI_NOTSUP | EXCP_DSI_DIRECT | EXCP_ECXW; 614 + error_code = EXCP_DSI_NOTSUP | EXCP_DSI_DIRECT |
  615 + EXCP_DSI_ECXW;
622 break; 616 break;
623 default: 617 default:
  618 + printf("DSI: invalid exception (%d)\n", ret);
624 exception = EXCP_PROGRAM; 619 exception = EXCP_PROGRAM;
625 error_code = EXCP_INVAL | EXCP_INVAL_INVAL; 620 error_code = EXCP_INVAL | EXCP_INVAL_INVAL;
626 break; 621 break;
@@ -628,27 +623,8 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -628,27 +623,8 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
628 } 623 }
629 if (rw) 624 if (rw)
630 error_code |= EXCP_DSI_STORE; 625 error_code |= EXCP_DSI_STORE;
631 - /* Should find a better solution:  
632 - * this will be invalid for some exception if more than one  
633 - * exception occurs for one instruction  
634 - */  
635 - env->spr[DSISR] = 0;  
636 - if (error_code & EXCP_DSI_DIRECT) {  
637 - env->spr[DSISR] |= 0x80000000;  
638 - if (access_type == ACCESS_EXT ||  
639 - access_type == ACCESS_RES)  
640 - env->spr[DSISR] |= 0x04000000;  
641 - }  
642 - if ((error_code & 0xF) == EXCP_DSI_TRANSLATE)  
643 - env->spr[DSISR] |= 0x40000000;  
644 - if (error_code & EXCP_DSI_PROT)  
645 - env->spr[DSISR] |= 0x08000000;  
646 - if (error_code & EXCP_DSI_STORE)  
647 - env->spr[DSISR] |= 0x02000000;  
648 - if ((error_code & 0xF) == EXCP_DSI_DABR)  
649 - env->spr[DSISR] |= 0x00400000;  
650 - if (access_type == ACCESS_EXT)  
651 - env->spr[DSISR] |= 0x00100000; 626 + /* Store fault address */
  627 + env->spr[DAR] = address;
652 } 628 }
653 #if 0 629 #if 0
654 printf("%s: set exception to %d %02x\n", 630 printf("%s: set exception to %d %02x\n",
@@ -656,15 +632,13 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -656,15 +632,13 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
656 #endif 632 #endif
657 env->exception_index = exception; 633 env->exception_index = exception;
658 env->error_code = error_code; 634 env->error_code = error_code;
659 - /* Store fault address */  
660 - env->spr[DAR] = address;  
661 ret = 1; 635 ret = 1;
662 } 636 }
663 637
664 return ret; 638 return ret;
665 } 639 }
666 640
667 -uint32_t _load_xer (void) 641 +uint32_t _load_xer (CPUState *env)
668 { 642 {
669 return (xer_so << XER_SO) | 643 return (xer_so << XER_SO) |
670 (xer_ov << XER_OV) | 644 (xer_ov << XER_OV) |
@@ -672,7 +646,7 @@ uint32_t _load_xer (void) @@ -672,7 +646,7 @@ uint32_t _load_xer (void)
672 (xer_bc << XER_BC); 646 (xer_bc << XER_BC);
673 } 647 }
674 648
675 -void _store_xer (uint32_t value) 649 +void _store_xer (CPUState *env, uint32_t value)
676 { 650 {
677 xer_so = (value >> XER_SO) & 0x01; 651 xer_so = (value >> XER_SO) & 0x01;
678 xer_ov = (value >> XER_OV) & 0x01; 652 xer_ov = (value >> XER_OV) & 0x01;
@@ -680,7 +654,7 @@ void _store_xer (uint32_t value) @@ -680,7 +654,7 @@ void _store_xer (uint32_t value)
680 xer_bc = (value >> XER_BC) & 0x1f; 654 xer_bc = (value >> XER_BC) & 0x1f;
681 } 655 }
682 656
683 -uint32_t _load_msr (void) 657 +uint32_t _load_msr (CPUState *env)
684 { 658 {
685 return (msr_pow << MSR_POW) | 659 return (msr_pow << MSR_POW) |
686 (msr_ile << MSR_ILE) | 660 (msr_ile << MSR_ILE) |
@@ -699,8 +673,13 @@ uint32_t _load_msr (void) @@ -699,8 +673,13 @@ uint32_t _load_msr (void)
699 (msr_le << MSR_LE); 673 (msr_le << MSR_LE);
700 } 674 }
701 675
702 -void _store_msr (uint32_t value) 676 +void _store_msr (CPUState *env, uint32_t value)
703 { 677 {
  678 + if (((T0 >> MSR_IR) & 0x01) != msr_ir ||
  679 + ((T0 >> MSR_DR) & 0x01) != msr_dr) {
  680 + /* Flush all tlb when changing translation mode or privilege level */
  681 + do_tlbia();
  682 + }
704 msr_pow = (value >> MSR_POW) & 0x03; 683 msr_pow = (value >> MSR_POW) & 0x03;
705 msr_ile = (value >> MSR_ILE) & 0x01; 684 msr_ile = (value >> MSR_ILE) & 0x01;
706 msr_ee = (value >> MSR_EE) & 0x01; 685 msr_ee = (value >> MSR_EE) & 0x01;
@@ -729,47 +708,16 @@ void do_interrupt (CPUState *env) @@ -729,47 +708,16 @@ void do_interrupt (CPUState *env)
729 /* Dequeue PPC exceptions */ 708 /* Dequeue PPC exceptions */
730 if (excp < EXCP_PPC_MAX) 709 if (excp < EXCP_PPC_MAX)
731 env->exceptions &= ~(1 << excp); 710 env->exceptions &= ~(1 << excp);
732 - msr = _load_msr(); 711 + msr = _load_msr(env);
733 #if defined (DEBUG_EXCEPTIONS) 712 #if defined (DEBUG_EXCEPTIONS)
734 - if (excp != EXCP_DECR && excp == EXCP_PROGRAM && excp < EXCP_PPC_MAX) 713 + if ((excp == EXCP_PROGRAM || excp == EXCP_DSI) && msr_pr == 1)
735 { 714 {
736 if (loglevel > 0) { 715 if (loglevel > 0) {
737 fprintf(logfile, "Raise exception at 0x%08x => 0x%08x (%02x)\n", 716 fprintf(logfile, "Raise exception at 0x%08x => 0x%08x (%02x)\n",
738 env->nip, excp << 8, env->error_code); 717 env->nip, excp << 8, env->error_code);
739 - } else {  
740 - printf("Raise exception at 0x%08x => 0x%08x (%02x)\n",  
741 - env->nip, excp << 8, env->error_code);  
742 - }  
743 - printf("nip=0x%08x LR=0x%08x CTR=0x%08x MSR=0x%08x DECR=0x%08x\n",  
744 - env->nip, env->lr, env->ctr, msr, env->decr);  
745 - {  
746 - int i;  
747 - for (i = 0; i < 32; i++) {  
748 - if ((i & 7) == 0)  
749 - printf("GPR%02d:", i);  
750 - printf(" %08x", env->gpr[i]);  
751 - if ((i & 7) == 7)  
752 - printf("\n");  
753 - }  
754 - printf("CR: 0x");  
755 - for (i = 0; i < 8; i++)  
756 - printf("%01x", env->crf[i]);  
757 - printf(" [");  
758 - for (i = 0; i < 8; i++) {  
759 - char a = '-';  
760 - if (env->crf[i] & 0x08)  
761 - a = 'L';  
762 - else if (env->crf[i] & 0x04)  
763 - a = 'G';  
764 - else if (env->crf[i] & 0x02)  
765 - a = 'E';  
766 - printf(" %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');  
767 } 718 }
768 - printf(" ] ");  
769 - }  
770 - printf("TB: 0x%08x %08x\n", env->tb[1], env->tb[0]);  
771 - printf("XER 0x%08x SRR0 0x%08x SRR1 0x%08x\n",  
772 - _load_xer(), env->spr[SRR0], env->spr[SRR1]); 719 + if (loglevel > 0)
  720 + cpu_ppc_dump_state(env, logfile, 0);
773 } 721 }
774 #endif 722 #endif
775 /* Generate informations in save/restore registers */ 723 /* Generate informations in save/restore registers */
@@ -812,26 +760,63 @@ void do_interrupt (CPUState *env) @@ -812,26 +760,63 @@ void do_interrupt (CPUState *env)
812 /* data location address has been stored 760 /* data location address has been stored
813 * when the fault has been detected 761 * when the fault has been detected
814 */ 762 */
815 - goto store_current; 763 + msr &= ~0xFFFF0000;
  764 + env->spr[DSISR] = 0;
  765 + if (env->error_code & EXCP_DSI_TRANSLATE)
  766 + env->spr[DSISR] |= 0x40000000;
  767 + else if (env->error_code & EXCP_DSI_PROT)
  768 + env->spr[DSISR] |= 0x08000000;
  769 + else if (env->error_code & EXCP_DSI_NOTSUP) {
  770 + env->spr[DSISR] |= 0x80000000;
  771 + if (env->error_code & EXCP_DSI_DIRECT)
  772 + env->spr[DSISR] |= 0x04000000;
  773 + }
  774 + if (env->error_code & EXCP_DSI_STORE)
  775 + env->spr[DSISR] |= 0x02000000;
  776 + if ((env->error_code & 0xF) == EXCP_DSI_DABR)
  777 + env->spr[DSISR] |= 0x00400000;
  778 + if (env->error_code & EXCP_DSI_ECXW)
  779 + env->spr[DSISR] |= 0x00100000;
  780 +#if defined (DEBUG_EXCEPTIONS)
  781 + if (loglevel) {
  782 + fprintf(logfile, "DSI exception: DSISR=0x%08x, DAR=0x%08x\n",
  783 + env->spr[DSISR], env->spr[DAR]);
  784 + } else {
  785 + printf("DSI exception: DSISR=0x%08x, DAR=0x%08x nip=0x%08x\n",
  786 + env->spr[DSISR], env->spr[DAR], env->nip);
  787 + }
  788 +#endif
  789 + goto store_next;
816 case EXCP_ISI: 790 case EXCP_ISI:
817 /* Store exception cause */ 791 /* Store exception cause */
  792 + msr &= ~0xFFFF0000;
818 if (env->error_code == EXCP_ISI_TRANSLATE) 793 if (env->error_code == EXCP_ISI_TRANSLATE)
819 msr |= 0x40000000; 794 msr |= 0x40000000;
820 else if (env->error_code == EXCP_ISI_NOEXEC || 795 else if (env->error_code == EXCP_ISI_NOEXEC ||
821 - env->error_code == EXCP_ISI_GUARD) 796 + env->error_code == EXCP_ISI_GUARD ||
  797 + env->error_code == EXCP_ISI_DIRECT)
822 msr |= 0x10000000; 798 msr |= 0x10000000;
823 else 799 else
824 msr |= 0x08000000; 800 msr |= 0x08000000;
  801 +#if defined (DEBUG_EXCEPTIONS)
  802 + if (loglevel) {
  803 + fprintf(logfile, "ISI exception: msr=0x%08x, nip=0x%08x\n",
  804 + msr, env->nip);
  805 + } else {
  806 + printf("ISI exception: msr=0x%08x, nip=0x%08x tbl:0x%08x\n",
  807 + msr, env->nip, env->spr[V_TBL]);
  808 + }
  809 +#endif
825 goto store_next; 810 goto store_next;
826 case EXCP_EXTERNAL: 811 case EXCP_EXTERNAL:
827 if (msr_ee == 0) { 812 if (msr_ee == 0) {
828 #if defined (DEBUG_EXCEPTIONS) 813 #if defined (DEBUG_EXCEPTIONS)
829 if (loglevel > 0) { 814 if (loglevel > 0) {
830 fprintf(logfile, "Skipping hardware interrupt\n"); 815 fprintf(logfile, "Skipping hardware interrupt\n");
831 - } else {  
832 - printf("Skipping hardware interrupt\n");  
833 } 816 }
834 #endif 817 #endif
  818 + /* Requeue it */
  819 + do_queue_exception(EXCP_EXTERNAL);
835 return; 820 return;
836 } 821 }
837 goto store_next; 822 goto store_next;
@@ -863,6 +848,7 @@ void do_interrupt (CPUState *env) @@ -863,6 +848,7 @@ void do_interrupt (CPUState *env)
863 env->fpscr[7] |= 0x4; 848 env->fpscr[7] |= 0x4;
864 break; 849 break;
865 case EXCP_INVAL: 850 case EXCP_INVAL:
  851 + printf("Invalid instruction at 0x%08x\n", env->nip);
866 msr |= 0x00080000; 852 msr |= 0x00080000;
867 break; 853 break;
868 case EXCP_PRIV: 854 case EXCP_PRIV:
@@ -888,8 +874,17 @@ void do_interrupt (CPUState *env) @@ -888,8 +874,17 @@ void do_interrupt (CPUState *env)
888 goto store_next; 874 goto store_next;
889 case EXCP_SYSCALL: 875 case EXCP_SYSCALL:
890 #if defined (DEBUG_EXCEPTIONS) 876 #if defined (DEBUG_EXCEPTIONS)
891 - printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n",  
892 - env->gpr[0], env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]); 877 + if (msr_pr) {
  878 + if (loglevel) {
  879 + fprintf(logfile, "syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n",
  880 + env->gpr[0], env->gpr[3], env->gpr[4],
  881 + env->gpr[5], env->gpr[6]);
  882 + } else {
  883 + printf("syscall %d from 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
  884 + env->gpr[0], env->nip, env->gpr[3], env->gpr[4],
  885 + env->gpr[5], env->gpr[6]);
  886 + }
  887 + }
893 #endif 888 #endif
894 goto store_next; 889 goto store_next;
895 case EXCP_TRACE: 890 case EXCP_TRACE:
@@ -898,20 +893,16 @@ void do_interrupt (CPUState *env) @@ -898,20 +893,16 @@ void do_interrupt (CPUState *env)
898 goto store_next; 893 goto store_next;
899 case EXCP_MTMSR: 894 case EXCP_MTMSR:
900 /* Nothing to do */ 895 /* Nothing to do */
901 -#if defined (DEBUG_EXCEPTIONS)  
902 - printf("%s: escape EXCP_MTMSR\n", __func__);  
903 -#endif  
904 return; 896 return;
905 case EXCP_BRANCH: 897 case EXCP_BRANCH:
906 /* Nothing to do */ 898 /* Nothing to do */
907 -#if defined (DEBUG_EXCEPTIONS)  
908 - printf("%s: escape EXCP_BRANCH\n", __func__);  
909 -#endif  
910 return; 899 return;
911 case EXCP_RFI: 900 case EXCP_RFI:
912 /* Restore user-mode state */ 901 /* Restore user-mode state */
  902 + tb_flush(env);
913 #if defined (DEBUG_EXCEPTIONS) 903 #if defined (DEBUG_EXCEPTIONS)
914 - printf("%s: escape EXCP_RFI\n", __func__); 904 + if (msr_pr == 1)
  905 + printf("Return from exception => 0x%08x\n", (uint32_t)env->nip);
915 #endif 906 #endif
916 return; 907 return;
917 store_current: 908 store_current:
target-ppc/op.c
@@ -18,11 +18,11 @@ @@ -18,11 +18,11 @@
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
  21 +//#define DEBUG_OP
  22 +
21 #include "config.h" 23 #include "config.h"
22 #include "exec.h" 24 #include "exec.h"
23 25
24 -//#define DEBUG_OP  
25 -  
26 #define regs (env) 26 #define regs (env)
27 #define Ts0 (int32_t)T0 27 #define Ts0 (int32_t)T0
28 #define Ts1 (int32_t)T1 28 #define Ts1 (int32_t)T1
@@ -226,6 +226,17 @@ PPC_OP(process_exceptions) @@ -226,6 +226,17 @@ PPC_OP(process_exceptions)
226 } 226 }
227 } 227 }
228 228
  229 +PPC_OP(debug)
  230 +{
  231 + env->nip = PARAM(1);
  232 + env->brkstate = 1;
  233 +#if defined (DEBUG_OP)
  234 + dump_state();
  235 +#endif
  236 + do_queue_exception(EXCP_DEBUG);
  237 + RETURN();
  238 +}
  239 +
229 /* Segment registers load and store with immediate index */ 240 /* Segment registers load and store with immediate index */
230 PPC_OP(load_srin) 241 PPC_OP(load_srin)
231 { 242 {
@@ -1443,10 +1454,9 @@ PPC_OP(fneg) @@ -1443,10 +1454,9 @@ PPC_OP(fneg)
1443 } 1454 }
1444 1455
1445 /* Load and store */ 1456 /* Load and store */
1446 -#if defined(CONFIG_USER_ONLY)  
1447 #define MEMSUFFIX _raw 1457 #define MEMSUFFIX _raw
1448 #include "op_mem.h" 1458 #include "op_mem.h"
1449 -#else 1459 +#if !defined(CONFIG_USER_ONLY)
1450 #define MEMSUFFIX _user 1460 #define MEMSUFFIX _user
1451 #include "op_mem.h" 1461 #include "op_mem.h"
1452 1462
@@ -1460,8 +1470,11 @@ PPC_OP(rfi) @@ -1460,8 +1470,11 @@ PPC_OP(rfi)
1460 T0 = regs->spr[SRR1] & ~0xFFFF0000; 1470 T0 = regs->spr[SRR1] & ~0xFFFF0000;
1461 do_store_msr(); 1471 do_store_msr();
1462 do_tlbia(); 1472 do_tlbia();
  1473 +#if defined (DEBUG_OP)
1463 dump_rfi(); 1474 dump_rfi();
  1475 +#endif
1464 regs->nip = regs->spr[SRR0] & ~0x00000003; 1476 regs->nip = regs->spr[SRR0] & ~0x00000003;
  1477 + do_queue_exception(EXCP_RFI);
1465 if (env->exceptions != 0) { 1478 if (env->exceptions != 0) {
1466 do_check_exception_state(); 1479 do_check_exception_state();
1467 } 1480 }
target-ppc/op_helper.c
@@ -20,10 +20,9 @@ @@ -20,10 +20,9 @@
20 #include <math.h> 20 #include <math.h>
21 #include "exec.h" 21 #include "exec.h"
22 22
23 -#if defined(CONFIG_USER_ONLY)  
24 #define MEMSUFFIX _raw 23 #define MEMSUFFIX _raw
25 #include "op_helper_mem.h" 24 #include "op_helper_mem.h"
26 -#else 25 +#if !defined(CONFIG_USER_ONLY)
27 #define MEMSUFFIX _user 26 #define MEMSUFFIX _user
28 #include "op_helper_mem.h" 27 #include "op_helper_mem.h"
29 #define MEMSUFFIX _kernel 28 #define MEMSUFFIX _kernel
@@ -122,8 +121,7 @@ void do_load_msr (void) @@ -122,8 +121,7 @@ void do_load_msr (void)
122 void do_store_msr (void) 121 void do_store_msr (void)
123 { 122 {
124 if (((T0 >> MSR_IR) & 0x01) != msr_ir || 123 if (((T0 >> MSR_IR) & 0x01) != msr_ir ||
125 - ((T0 >> MSR_DR) & 0x01) != msr_dr ||  
126 - ((T0 >> MSR_PR) & 0x01) != msr_pr) { 124 + ((T0 >> MSR_DR) & 0x01) != msr_dr) {
127 /* Flush all tlb when changing translation mode or privilege level */ 125 /* Flush all tlb when changing translation mode or privilege level */
128 do_tlbia(); 126 do_tlbia();
129 } 127 }
@@ -371,44 +369,18 @@ void do_tlbie (void) @@ -371,44 +369,18 @@ void do_tlbie (void)
371 369
372 /*****************************************************************************/ 370 /*****************************************************************************/
373 /* Special helpers for debug */ 371 /* Special helpers for debug */
  372 +extern FILE *stdout;
  373 +
  374 +void dump_state (void)
  375 +{
  376 + cpu_ppc_dump_state(env, stdout, 0);
  377 +}
  378 +
374 void dump_rfi (void) 379 void dump_rfi (void)
375 { 380 {
376 #if 0 381 #if 0
377 - printf("Return from interrupt\n");  
378 - printf("nip=0x%08x LR=0x%08x CTR=0x%08x MSR=0x%08x\n",  
379 - env->nip, env->lr, env->ctr,  
380 - (msr_pow << MSR_POW) | (msr_ile << MSR_ILE) | (msr_ee << MSR_EE) |  
381 - (msr_pr << MSR_PR) | (msr_fp << MSR_FP) | (msr_me << MSR_ME) |  
382 - (msr_fe0 << MSR_FE0) | (msr_se << MSR_SE) | (msr_be << MSR_BE) |  
383 - (msr_fe1 << MSR_FE1) | (msr_ip << MSR_IP) | (msr_ir << MSR_IR) |  
384 - (msr_dr << MSR_DR) | (msr_ri << MSR_RI) | (msr_le << MSR_LE));  
385 - {  
386 - int i;  
387 - for (i = 0; i < 32; i++) {  
388 - if ((i & 7) == 0)  
389 - printf("GPR%02d:", i);  
390 - printf(" %08x", env->gpr[i]);  
391 - if ((i & 7) == 7)  
392 - printf("\n");  
393 - }  
394 - printf("CR: 0x");  
395 - for (i = 0; i < 8; i++)  
396 - printf("%01x", env->crf[i]);  
397 - printf(" [");  
398 - for (i = 0; i < 8; i++) {  
399 - char a = '-';  
400 - if (env->crf[i] & 0x08)  
401 - a = 'L';  
402 - else if (env->crf[i] & 0x04)  
403 - a = 'G';  
404 - else if (env->crf[i] & 0x02)  
405 - a = 'E';  
406 - printf(" %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');  
407 - }  
408 - printf(" ] ");  
409 - }  
410 - printf("TB: 0x%08x %08x\n", env->tb[1], env->tb[0]);  
411 - printf("SRR0 0x%08x SRR1 0x%08x\n", env->spr[SRR0], env->spr[SRR1]); 382 + printf("Return from interrupt %d => 0x%08x\n", pos, env->nip);
  383 + // cpu_ppc_dump_state(env, stdout, 0);
412 #endif 384 #endif
413 } 385 }
414 386
target-ppc/translate.c
@@ -2168,22 +2168,48 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC) @@ -2168,22 +2168,48 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
2168 /* dcbf */ 2168 /* dcbf */
2169 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE) 2169 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE)
2170 { 2170 {
  2171 + if (rA(ctx->opcode) == 0) {
  2172 + gen_op_load_gpr_T0(rB(ctx->opcode));
  2173 + } else {
  2174 + gen_op_load_gpr_T0(rA(ctx->opcode));
  2175 + gen_op_load_gpr_T1(rB(ctx->opcode));
  2176 + gen_op_add();
  2177 + }
  2178 + op_ldst(lbz);
2171 } 2179 }
2172 2180
2173 /* dcbi (Supervisor only) */ 2181 /* dcbi (Supervisor only) */
2174 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE) 2182 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
2175 { 2183 {
2176 -#if !defined(CONFIG_USER_ONLY)  
2177 - if (!ctx->supervisor)  
2178 -#endif  
2179 - { 2184 +#if defined(CONFIG_USER_ONLY)
  2185 + RET_PRIVOPC();
  2186 +#else
  2187 + if (!ctx->supervisor) {
2180 RET_PRIVOPC(); 2188 RET_PRIVOPC();
2181 } 2189 }
  2190 + if (rA(ctx->opcode) == 0) {
  2191 + gen_op_load_gpr_T0(rB(ctx->opcode));
  2192 + } else {
  2193 + gen_op_load_gpr_T0(rA(ctx->opcode));
  2194 + gen_op_load_gpr_T1(rB(ctx->opcode));
  2195 + gen_op_add();
  2196 + }
  2197 + op_ldst(lbz);
  2198 + op_ldst(stb);
  2199 +#endif
2182 } 2200 }
2183 2201
2184 /* dcdst */ 2202 /* dcdst */
2185 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE) 2203 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
2186 { 2204 {
  2205 + if (rA(ctx->opcode) == 0) {
  2206 + gen_op_load_gpr_T0(rB(ctx->opcode));
  2207 + } else {
  2208 + gen_op_load_gpr_T0(rA(ctx->opcode));
  2209 + gen_op_load_gpr_T1(rB(ctx->opcode));
  2210 + gen_op_add();
  2211 + }
  2212 + op_ldst(lbz);
2187 } 2213 }
2188 2214
2189 /* dcbt */ 2215 /* dcbt */
@@ -2863,7 +2889,7 @@ void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags) @@ -2863,7 +2889,7 @@ void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags)
2863 2889
2864 fprintf(f, "nip=0x%08x LR=0x%08x CTR=0x%08x XER=0x%08x " 2890 fprintf(f, "nip=0x%08x LR=0x%08x CTR=0x%08x XER=0x%08x "
2865 "MSR=0x%08x\n", env->nip, env->lr, env->ctr, 2891 "MSR=0x%08x\n", env->nip, env->lr, env->ctr,
2866 - _load_xer(), _load_msr()); 2892 + _load_xer(env), _load_msr(env));
2867 for (i = 0; i < 32; i++) { 2893 for (i = 0; i < 32; i++) {
2868 if ((i & 7) == 0) 2894 if ((i & 7) == 0)
2869 fprintf(f, "GPR%02d:", i); 2895 fprintf(f, "GPR%02d:", i);
@@ -2894,8 +2920,8 @@ void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags) @@ -2894,8 +2920,8 @@ void cpu_ppc_dump_state(CPUPPCState *env, FILE *f, int flags)
2894 if ((i & 3) == 3) 2920 if ((i & 3) == 3)
2895 fprintf(f, "\n"); 2921 fprintf(f, "\n");
2896 } 2922 }
2897 - fprintf(f, "SRR0 0x%08x SRR1 0x%08x\n",  
2898 - env->spr[SRR0], env->spr[SRR1]); 2923 + fprintf(f, "SRR0 0x%08x SRR1 0x%08x DECR=0x%08x excp:0x%08x\n",
  2924 + env->spr[SRR0], env->spr[SRR1], env->decr, env->exceptions);
2899 fprintf(f, "reservation 0x%08x\n", env->reserve); 2925 fprintf(f, "reservation 0x%08x\n", env->reserve);
2900 fflush(f); 2926 fflush(f);
2901 } 2927 }
@@ -2934,6 +2960,7 @@ CPUPPCState *cpu_ppc_init(void) @@ -2934,6 +2960,7 @@ CPUPPCState *cpu_ppc_init(void)
2934 #if defined(CONFIG_USER_ONLY) 2960 #if defined(CONFIG_USER_ONLY)
2935 msr_pr = 1; 2961 msr_pr = 1;
2936 #endif 2962 #endif
  2963 + env->access_type = ACCESS_INT;
2937 2964
2938 return env; 2965 return env;
2939 } 2966 }
@@ -2977,6 +3004,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, @@ -2977,6 +3004,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
2977 /* Single step trace mode */ 3004 /* Single step trace mode */
2978 msr_se = 1; 3005 msr_se = 1;
2979 #endif 3006 #endif
  3007 + env->access_type = ACCESS_CODE;
2980 /* Set env in case of segfault during code fetch */ 3008 /* Set env in case of segfault during code fetch */
2981 while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) { 3009 while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) {
2982 if (search_pc) { 3010 if (search_pc) {
@@ -3073,9 +3101,8 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, @@ -3073,9 +3101,8 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3073 ctx.exception = EXCP_TRACE; 3101 ctx.exception = EXCP_TRACE;
3074 } 3102 }
3075 } 3103 }
3076 - /* if too long translation, stop generation too */  
3077 - if (gen_opc_ptr >= gen_opc_end ||  
3078 - ((uint32_t)ctx.nip - pc_start) >= (TARGET_PAGE_SIZE - 32)) { 3104 + /* if we reach a page boundary, stop generation */
  3105 + if (((uint32_t)ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) {
3079 if (ctx.exception == EXCP_NONE) { 3106 if (ctx.exception == EXCP_NONE) {
3080 gen_op_b((long)ctx.tb, (uint32_t)ctx.nip); 3107 gen_op_b((long)ctx.tb, (uint32_t)ctx.nip);
3081 ctx.exception = EXCP_BRANCH; 3108 ctx.exception = EXCP_BRANCH;
@@ -3111,6 +3138,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, @@ -3111,6 +3138,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3111 } else { 3138 } else {
3112 tb->size = (uint32_t)ctx.nip - pc_start; 3139 tb->size = (uint32_t)ctx.nip - pc_start;
3113 } 3140 }
  3141 + env->access_type = ACCESS_INT;
3114 #ifdef DEBUG_DISAS 3142 #ifdef DEBUG_DISAS
3115 if (loglevel > 0) { 3143 if (loglevel > 0) {
3116 fprintf(logfile, "---------------- excp: %04x\n", ctx.exception); 3144 fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
translate-all.c
@@ -230,6 +230,9 @@ int cpu_restore_state(TranslationBlock *tb, @@ -230,6 +230,9 @@ int cpu_restore_state(TranslationBlock *tb,
230 CASE3(lfs): 230 CASE3(lfs):
231 type = ACCESS_FLOAT; 231 type = ACCESS_FLOAT;
232 break; 232 break;
  233 + CASE3(lwarx):
  234 + type = ACCESS_RES;
  235 + break;
233 CASE3(stwcx): 236 CASE3(stwcx):
234 type = ACCESS_RES; 237 type = ACCESS_RES;
235 break; 238 break;
@@ -68,6 +68,8 @@ extern void __sigaction(); @@ -68,6 +68,8 @@ extern void __sigaction();
68 68
69 #include "exec-all.h" 69 #include "exec-all.h"
70 70
  71 +//#define DO_TB_FLUSH
  72 +
71 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" 73 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
72 74
73 //#define DEBUG_UNUSED_IOPORT 75 //#define DEBUG_UNUSED_IOPORT
@@ -1201,6 +1203,9 @@ int qemu_loadvm(const char *filename) @@ -1201,6 +1203,9 @@ int qemu_loadvm(const char *filename)
1201 goto the_end; 1203 goto the_end;
1202 } 1204 }
1203 for(;;) { 1205 for(;;) {
  1206 +#if defined (DO_TB_FLUSH)
  1207 + tb_flush();
  1208 +#endif
1204 len = qemu_get_byte(f); 1209 len = qemu_get_byte(f);
1205 if (feof(f)) 1210 if (feof(f))
1206 break; 1211 break;
@@ -1380,6 +1385,15 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) @@ -1380,6 +1385,15 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
1380 return 0; 1385 return 0;
1381 } 1386 }
1382 1387
  1388 +#elif defined(TARGET_PPC)
  1389 +void cpu_save(QEMUFile *f, void *opaque)
  1390 +{
  1391 +}
  1392 +
  1393 +int cpu_load(QEMUFile *f, void *opaque, int version_id)
  1394 +{
  1395 + return 0;
  1396 +}
1383 #else 1397 #else
1384 1398
1385 #warning No CPU save/restore functions 1399 #warning No CPU save/restore functions
@@ -1706,6 +1720,7 @@ int main(int argc, char **argv) @@ -1706,6 +1720,7 @@ int main(int argc, char **argv)
1706 const char *kernel_filename, *kernel_cmdline; 1720 const char *kernel_filename, *kernel_cmdline;
1707 DisplayState *ds = &display_state; 1721 DisplayState *ds = &display_state;
1708 int cyls, heads, secs; 1722 int cyls, heads, secs;
  1723 + int start_emulation = 1;
1709 uint8_t macaddr[6]; 1724 uint8_t macaddr[6];
1710 1725
1711 #if !defined(CONFIG_SOFTMMU) 1726 #if !defined(CONFIG_SOFTMMU)
@@ -1744,7 +1759,7 @@ int main(int argc, char **argv) @@ -1744,7 +1759,7 @@ int main(int argc, char **argv)
1744 nd_table[i].fd = -1; 1759 nd_table[i].fd = -1;
1745 1760
1746 for(;;) { 1761 for(;;) {
1747 - c = getopt_long_only(argc, argv, "hm:d:n:sp:L:", long_options, &long_index); 1762 + c = getopt_long_only(argc, argv, "hm:d:n:sp:L:S", long_options, &long_index);
1748 if (c == -1) 1763 if (c == -1)
1749 break; 1764 break;
1750 switch(c) { 1765 switch(c) {
@@ -1915,6 +1930,9 @@ int main(int argc, char **argv) @@ -1915,6 +1930,9 @@ int main(int argc, char **argv)
1915 case 'L': 1930 case 'L':
1916 bios_dir = optarg; 1931 bios_dir = optarg;
1917 break; 1932 break;
  1933 + case 'S':
  1934 + start_emulation = 0;
  1935 + break;
1918 } 1936 }
1919 } 1937 }
1920 1938
@@ -2121,7 +2139,9 @@ int main(int argc, char **argv) @@ -2121,7 +2139,9 @@ int main(int argc, char **argv)
2121 ds, fd_filename, snapshot, 2139 ds, fd_filename, snapshot,
2122 kernel_filename, kernel_cmdline, initrd_filename); 2140 kernel_filename, kernel_cmdline, initrd_filename);
2123 #elif defined(TARGET_PPC) 2141 #elif defined(TARGET_PPC)
2124 - ppc_init(); 2142 + ppc_init(ram_size, vga_ram_size, boot_device,
  2143 + ds, fd_filename, snapshot,
  2144 + kernel_filename, kernel_cmdline, initrd_filename);
2125 #endif 2145 #endif
2126 2146
2127 /* launched after the device init so that it can display or not a 2147 /* launched after the device init so that it can display or not a
@@ -2142,6 +2162,7 @@ int main(int argc, char **argv) @@ -2142,6 +2162,7 @@ int main(int argc, char **argv)
2142 } 2162 }
2143 } else 2163 } else
2144 #endif 2164 #endif
  2165 + if (start_emulation)
2145 { 2166 {
2146 vm_start(); 2167 vm_start();
2147 } 2168 }