Commit 3fc6c082e3aad85addf25d36740030982963c0c8

Authored by bellard
1 parent 2f636b45

preliminary patch to support more PowerPC CPUs (Jocelyn Mayer)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1489 c046a42c-6fe2-441c-8c8c-71466251a162

Too many changes to show.

To preserve performance only 12 of 13 files are displayed.

Makefile.target
@@ -468,6 +468,7 @@ endif @@ -468,6 +468,7 @@ endif
468 ifeq ($(TARGET_ARCH), ppc) 468 ifeq ($(TARGET_ARCH), ppc)
469 op.o: op.c op_template.h op_mem.h 469 op.o: op.c op_template.h op_mem.h
470 op_helper.o: op_helper_mem.h 470 op_helper.o: op_helper_mem.h
  471 +translate.o: translate.c translate_init.c
471 endif 472 endif
472 473
473 ifeq ($(TARGET_ARCH), mips) 474 ifeq ($(TARGET_ARCH), mips)
gdbstub.c
@@ -253,14 +253,14 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) @@ -253,14 +253,14 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
253 } 253 }
254 /* nip, msr, ccr, lnk, ctr, xer, mq */ 254 /* nip, msr, ccr, lnk, ctr, xer, mq */
255 registers[96] = tswapl(env->nip); 255 registers[96] = tswapl(env->nip);
256 - registers[97] = tswapl(_load_msr(env)); 256 + registers[97] = tswapl(do_load_msr(env));
257 tmp = 0; 257 tmp = 0;
258 for (i = 0; i < 8; i++) 258 for (i = 0; i < 8; i++)
259 tmp |= env->crf[i] << (32 - ((i + 1) * 4)); 259 tmp |= env->crf[i] << (32 - ((i + 1) * 4));
260 registers[98] = tswapl(tmp); 260 registers[98] = tswapl(tmp);
261 registers[99] = tswapl(env->lr); 261 registers[99] = tswapl(env->lr);
262 registers[100] = tswapl(env->ctr); 262 registers[100] = tswapl(env->ctr);
263 - registers[101] = tswapl(_load_xer(env)); 263 + registers[101] = tswapl(do_load_xer(env));
264 registers[102] = 0; 264 registers[102] = 0;
265 265
266 return 103 * 4; 266 return 103 * 4;
@@ -282,13 +282,13 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) @@ -282,13 +282,13 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
282 } 282 }
283 /* nip, msr, ccr, lnk, ctr, xer, mq */ 283 /* nip, msr, ccr, lnk, ctr, xer, mq */
284 env->nip = tswapl(registers[96]); 284 env->nip = tswapl(registers[96]);
285 - _store_msr(env, tswapl(registers[97])); 285 + do_store_msr(env, tswapl(registers[97]));
286 registers[98] = tswapl(registers[98]); 286 registers[98] = tswapl(registers[98]);
287 for (i = 0; i < 8; i++) 287 for (i = 0; i < 8; i++)
288 env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF; 288 env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
289 env->lr = tswapl(registers[99]); 289 env->lr = tswapl(registers[99]);
290 env->ctr = tswapl(registers[100]); 290 env->ctr = tswapl(registers[100]);
291 - _store_xer(env, tswapl(registers[101])); 291 + do_store_xer(env, tswapl(registers[101]));
292 } 292 }
293 #elif defined (TARGET_SPARC) 293 #elif defined (TARGET_SPARC)
294 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) 294 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
hw/ppc_chrp.c
@@ -235,6 +235,7 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, @@ -235,6 +235,7 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
235 int ret, linux_boot, i; 235 int ret, linux_boot, i;
236 unsigned long bios_offset; 236 unsigned long bios_offset;
237 uint32_t kernel_base, kernel_size, initrd_base, initrd_size; 237 uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
  238 + ppc_def_t *def;
238 PCIBus *pci_bus; 239 PCIBus *pci_bus;
239 const char *arch_name; 240 const char *arch_name;
240 241
@@ -286,7 +287,26 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, @@ -286,7 +287,26 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
286 initrd_size = 0; 287 initrd_size = 0;
287 } 288 }
288 /* Register CPU as a 74x/75x */ 289 /* Register CPU as a 74x/75x */
289 - cpu_ppc_register(cpu_single_env, 0x00080000); 290 + /* XXX: CPU model (or PVR) should be provided on command line */
  291 + // ppc_find_by_name("750gx", &def); // Linux boot OK
  292 + // ppc_find_by_name("750fx", &def); // Linux boot OK
  293 + /* Linux does not boot on 750cxe (and probably other 750cx based)
  294 + * because it assumes it has 8 IBAT & DBAT pairs as it only have 4.
  295 + */
  296 + // ppc_find_by_name("750cxe", &def);
  297 + // ppc_find_by_name("750p", &def);
  298 + // ppc_find_by_name("740p", &def);
  299 + ppc_find_by_name("750", &def);
  300 + // ppc_find_by_name("740", &def);
  301 + // ppc_find_by_name("G3", &def);
  302 + // ppc_find_by_name("604r", &def);
  303 + // ppc_find_by_name("604e", &def);
  304 + // ppc_find_by_name("604", &def);
  305 + if (def == NULL) {
  306 + cpu_abort(cpu_single_env, "Unable to find PowerPC CPU definition\n");
  307 + }
  308 + cpu_ppc_register(cpu_single_env, def);
  309 +
290 /* Set time-base frequency to 10 Mhz */ 310 /* Set time-base frequency to 10 Mhz */
291 cpu_ppc_tb_init(cpu_single_env, 10UL * 1000UL * 1000UL); 311 cpu_ppc_tb_init(cpu_single_env, 10UL * 1000UL * 1000UL);
292 312
hw/ppc_prep.c
@@ -527,6 +527,7 @@ static void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device, @@ -527,6 +527,7 @@ static void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
527 int ret, linux_boot, i, nb_nics1; 527 int ret, linux_boot, i, nb_nics1;
528 unsigned long bios_offset; 528 unsigned long bios_offset;
529 uint32_t kernel_base, kernel_size, initrd_base, initrd_size; 529 uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
  530 + ppc_def_t *def;
530 PCIBus *pci_bus; 531 PCIBus *pci_bus;
531 532
532 sysctrl = qemu_mallocz(sizeof(sysctrl_t)); 533 sysctrl = qemu_mallocz(sizeof(sysctrl_t));
@@ -582,7 +583,14 @@ static void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device, @@ -582,7 +583,14 @@ static void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
582 } 583 }
583 584
584 /* Register CPU as a 604 */ 585 /* Register CPU as a 604 */
585 - cpu_ppc_register(cpu_single_env, 0x00040000); 586 + /* XXX: CPU model (or PVR) should be provided on command line */
  587 + // ppc_find_by_name("604r", &def);
  588 + // ppc_find_by_name("604e", &def);
  589 + ppc_find_by_name("604", &def);
  590 + if (def == NULL) {
  591 + cpu_abort(cpu_single_env, "Unable to find PowerPC CPU definition\n");
  592 + }
  593 + cpu_ppc_register(cpu_single_env, def);
586 /* Set time-base frequency to 100 Mhz */ 594 /* Set time-base frequency to 100 Mhz */
587 cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL); 595 cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL);
588 596
linux-user/main.c
@@ -700,10 +700,11 @@ void cpu_loop(CPUPPCState *env) @@ -700,10 +700,11 @@ void cpu_loop(CPUPPCState *env)
700 info._sifields._sigfault._addr = env->nip - 4; 700 info._sifields._sigfault._addr = env->nip - 4;
701 queue_signal(info.si_signo, &info); 701 queue_signal(info.si_signo, &info);
702 case EXCP_DSI: 702 case EXCP_DSI:
703 - fprintf(stderr, "Invalid data memory access: 0x%08x\n", env->spr[DAR]); 703 + fprintf(stderr, "Invalid data memory access: 0x%08x\n",
  704 + env->spr[SPR_DAR]);
704 if (loglevel) { 705 if (loglevel) {
705 fprintf(logfile, "Invalid data memory access: 0x%08x\n", 706 fprintf(logfile, "Invalid data memory access: 0x%08x\n",
706 - env->spr[DAR]); 707 + env->spr[SPR_DAR]);
707 } 708 }
708 switch (env->error_code & 0xF) { 709 switch (env->error_code & 0xF) {
709 case EXCP_DSI_TRANSLATE: 710 case EXCP_DSI_TRANSLATE:
@@ -1243,7 +1244,25 @@ int main(int argc, char **argv) @@ -1243,7 +1244,25 @@ int main(int argc, char **argv)
1243 } 1244 }
1244 #elif defined(TARGET_PPC) 1245 #elif defined(TARGET_PPC)
1245 { 1246 {
  1247 + ppc_def_t *def;
1246 int i; 1248 int i;
  1249 +
  1250 + /* Choose and initialise CPU */
  1251 + /* XXX: CPU model (or PVR) should be provided on command line */
  1252 + // ppc_find_by_name("750gx", &def);
  1253 + // ppc_find_by_name("750fx", &def);
  1254 + // ppc_find_by_name("750p", &def);
  1255 + ppc_find_by_name("750", &def);
  1256 + // ppc_find_by_name("G3", &def);
  1257 + // ppc_find_by_name("604r", &def);
  1258 + // ppc_find_by_name("604e", &def);
  1259 + // ppc_find_by_name("604", &def);
  1260 + if (def == NULL) {
  1261 + cpu_abort(cpu_single_env,
  1262 + "Unable to find PowerPC CPU definition\n");
  1263 + }
  1264 + cpu_ppc_register(cpu_single_env, def);
  1265 +
1247 for (i = 0; i < 32; i++) { 1266 for (i = 0; i < 32; i++) {
1248 if (i != 12 && i != 6 && i != 13) 1267 if (i != 12 && i != 6 && i != 13)
1249 env->msr[i] = (regs->msr >> i) & 1; 1268 env->msr[i] = (regs->msr >> i) & 1;
target-ppc/cpu.h
1 /* 1 /*
2 - * PPC emulation cpu definitions for qemu. 2 + * PowerPC emulation cpu definitions for qemu.
3 * 3 *
4 - * Copyright (c) 2003 Jocelyn Mayer 4 + * Copyright (c) 2003-2005 Jocelyn Mayer
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
@@ -20,64 +20,403 @@ @@ -20,64 +20,403 @@
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 "config.h"
  24 +
23 #define TARGET_LONG_BITS 32 25 #define TARGET_LONG_BITS 32
24 26
25 #include "cpu-defs.h" 27 #include "cpu-defs.h"
26 28
27 -#include "config.h"  
28 #include <setjmp.h> 29 #include <setjmp.h>
29 30
30 #include "softfloat.h" 31 #include "softfloat.h"
31 32
32 #define TARGET_HAS_ICE 1 33 #define TARGET_HAS_ICE 1
33 34
  35 +/*****************************************************************************/
  36 +/* PVR definitions for most known PowerPC */
  37 +enum {
  38 + /* PowerPC 401 cores */
  39 + CPU_PPC_401A1 = 0x00210000,
  40 + CPU_PPC_401B2 = 0x00220000,
  41 + CPU_PPC_401C2 = 0x00230000,
  42 + CPU_PPC_401D2 = 0x00240000,
  43 + CPU_PPC_401E2 = 0x00250000,
  44 + CPU_PPC_401F2 = 0x00260000,
  45 + CPU_PPC_401G2 = 0x00270000,
  46 + CPU_PPC_IOP480 = 0x40100000,
  47 + /* PowerPC 403 cores */
  48 + CPU_PPC_403GA = 0x00200000,
  49 + CPU_PPC_403GB = 0x00200100,
  50 + CPU_PPC_403GC = 0x00200200,
  51 + CPU_PPC_403GCX = 0x00201400,
  52 + /* PowerPC 405 cores */
  53 + CPU_PPC_405 = 0x40110000,
  54 + CPU_PPC_405EP = 0x51210000,
  55 + CPU_PPC_405GPR = 0x50910000,
  56 + CPU_PPC_405D2 = 0x20010000,
  57 + CPU_PPC_405D4 = 0x41810000,
  58 + CPU_PPC_NPE405H = 0x41410000,
  59 + CPU_PPC_NPE405L = 0x41610000,
  60 +#if 0
  61 + CPU_PPC_STB02 = xxx,
  62 +#endif
  63 + CPU_PPC_STB03 = 0x40310000,
  64 +#if 0
  65 + CPU_PPC_STB04 = xxx,
  66 +#endif
  67 + CPU_PPC_STB25 = 0x51510000,
  68 +#if 0
  69 + CPU_PPC_STB130 = xxx,
  70 +#endif
  71 + /* PowerPC 440 cores */
  72 + CPU_PPC_440EP = 0x42220000,
  73 + CPU_PPC_440GP = 0x40120400,
  74 + CPU_PPC_440GX = 0x51B20000,
  75 + /* PowerPC MPC 8xx cores */
  76 + CPU_PPC_8540 = 0x80200000,
  77 + CPU_PPC_8xx = 0x00500000,
  78 + CPU_PPC_8240 = 0x00810100,
  79 + CPU_PPC_8245 = 0x00811014,
  80 + /* PowerPC 6xx cores */
  81 + CPU_PPC_601 = 0x00010000,
  82 + CPU_PPC_602 = 0x00050000,
  83 + CPU_PPC_603 = 0x00030000,
  84 + CPU_PPC_603E = 0x00060000,
  85 + CPU_PPC_603EV = 0x00070000,
  86 + CPU_PPC_603R = 0x00071000,
  87 + CPU_PPC_G2 = 0x80810000,
  88 + CPU_PPC_G2LE = 0x80820000,
  89 + CPU_PPC_604 = 0x00040000,
  90 + CPU_PPC_604E = 0x00090000,
  91 + CPU_PPC_604R = 0x000a0000,
  92 + /* PowerPC 74x/75x cores (aka G3) */
  93 + CPU_PPC_74x = 0x00080000,
  94 + CPU_PPC_755 = 0x00083000,
  95 + CPU_PPC_74xP = 0x10080000,
  96 + CPU_PPC_750CXE22 = 0x00082202,
  97 + CPU_PPC_750CXE24 = 0x00082214,
  98 + CPU_PPC_750CXE24b = 0x00083214,
  99 + CPU_PPC_750CXE31 = 0x00083211,
  100 + CPU_PPC_750CXE31b = 0x00083311,
  101 +#define CPU_PPC_750CXE CPU_PPC_750CXE31b
  102 + CPU_PPC_750FX = 0x70000000,
  103 + CPU_PPC_750GX = 0x70020000,
  104 + /* PowerPC 74xx cores (aka G4) */
  105 + CPU_PPC_7400 = 0x000C0000,
  106 + CPU_PPC_7410 = 0x800C0000,
  107 + CPU_PPC_7441 = 0x80000200,
  108 + CPU_PPC_7450 = 0x80000000,
  109 + CPU_PPC_7451 = 0x80000203,
  110 + CPU_PPC_7455 = 0x80010000,
  111 + CPU_PPC_7457 = 0x80020000,
  112 + CPU_PPC_7457A = 0x80030000,
  113 + /* 64 bits PowerPC */
  114 + CPU_PPC_620 = 0x00140000,
  115 + CPU_PPC_630 = 0x00400000,
  116 + CPU_PPC_631 = 0x00410000,
  117 + CPU_PPC_POWER4 = 0x00350000,
  118 + CPU_PPC_POWER4P = 0x00380000,
  119 + CPU_PPC_POWER5 = 0x003A0000,
  120 + CPU_PPC_POWER5P = 0x003B0000,
  121 + CPU_PPC_970 = 0x00390000,
  122 + CPU_PPC_970FX = 0x003C0000,
  123 + CPU_PPC_RS64 = 0x00330000,
  124 + CPU_PPC_RS64II = 0x00340000,
  125 + CPU_PPC_RS64III = 0x00360000,
  126 + CPU_PPC_RS64IV = 0x00370000,
  127 + /* Original POWER */
  128 + /* XXX: should be POWER (RIOS), RSC3308, RSC4608,
  129 + * POWER2 (RIOS2) & RSC2 (P2SC) here
  130 + */
  131 +#if 0
  132 + CPU_POWER = xxx,
  133 +#endif
  134 +#if 0
  135 + CPU_POWER2 = xxx,
  136 +#endif
  137 +};
  138 +
  139 +/* System version register (used on MPC 8xx) */
  140 +enum {
  141 + PPC_SVR_8540 = 0x80300000,
  142 + PPC_SVR_8541E = 0x807A0000,
  143 + PPC_SVR_8555E = 0x80790000,
  144 + PPC_SVR_8560 = 0x80700000,
  145 +};
  146 +
  147 +/*****************************************************************************/
34 /* Instruction types */ 148 /* Instruction types */
35 enum { 149 enum {
36 - PPC_NONE = 0x0000,  
37 - PPC_INTEGER = 0x0001, /* CPU has integer operations instructions */  
38 - PPC_FLOAT = 0x0002, /* CPU has floating point operations instructions */  
39 - PPC_FLOW = 0x0004, /* CPU has flow control instructions */  
40 - PPC_MEM = 0x0008, /* CPU has virtual memory instructions */  
41 - PPC_RES = 0x0010, /* CPU has ld/st with reservation instructions */  
42 - PPC_CACHE = 0x0020, /* CPU has cache control instructions */  
43 - PPC_MISC = 0x0040, /* CPU has spr/msr access instructions */  
44 - PPC_EXTERN = 0x0080, /* CPU has external control instructions */  
45 - PPC_SEGMENT = 0x0100, /* CPU has memory segment instructions */  
46 - PPC_CACHE_OPT= 0x0200,  
47 - PPC_FLOAT_OPT= 0x0400,  
48 - PPC_MEM_OPT = 0x0800, 150 + PPC_NONE = 0x00000000,
  151 + /* integer operations instructions */
  152 + /* flow control instructions */
  153 + /* virtual memory instructions */
  154 + /* ld/st with reservation instructions */
  155 + /* cache control instructions */
  156 + /* spr/msr access instructions */
  157 + PPC_INSNS_BASE = 0x00000001,
  158 +#define PPC_INTEGER PPC_INSNS_BASE
  159 +#define PPC_FLOW PPC_INSNS_BASE
  160 +#define PPC_MEM PPC_INSNS_BASE
  161 +#define PPC_RES PPC_INSNS_BASE
  162 +#define PPC_CACHE PPC_INSNS_BASE
  163 +#define PPC_MISC PPC_INSNS_BASE
  164 + /* floating point operations instructions */
  165 + PPC_FLOAT = 0x00000002,
  166 + /* more floating point operations instructions */
  167 + PPC_FLOAT_EXT = 0x00000004,
  168 + /* external control instructions */
  169 + PPC_EXTERN = 0x00000008,
  170 + /* segment register access instructions */
  171 + PPC_SEGMENT = 0x00000010,
  172 + /* Optional cache control instructions */
  173 + PPC_CACHE_OPT = 0x00000020,
  174 + /* Optional floating point op instructions */
  175 + PPC_FLOAT_OPT = 0x00000040,
  176 + /* Optional memory control instructions */
  177 + PPC_MEM_TLBIA = 0x00000080,
  178 + PPC_MEM_TLBIE = 0x00000100,
  179 + PPC_MEM_TLBSYNC = 0x00000200,
  180 + /* eieio & sync */
  181 + PPC_MEM_SYNC = 0x00000400,
  182 + /* PowerPC 6xx TLB management instructions */
  183 + PPC_6xx_TLB = 0x00000800,
  184 + /* Altivec support */
  185 + PPC_ALTIVEC = 0x00001000,
  186 + /* Time base support */
  187 + PPC_TB = 0x00002000,
  188 + /* Embedded PowerPC dedicated instructions */
  189 + PPC_4xx_COMMON = 0x00004000,
  190 + /* PowerPC 40x exception model */
  191 + PPC_40x_EXCP = 0x00008000,
  192 + /* PowerPC 40x specific instructions */
  193 + PPC_40x_SPEC = 0x00010000,
  194 + /* PowerPC 405 Mac instructions */
  195 + PPC_405_MAC = 0x00020000,
  196 + /* PowerPC 440 specific instructions */
  197 + PPC_440_SPEC = 0x00040000,
  198 + /* Specific extensions */
  199 + /* Power-to-PowerPC bridge (601) */
  200 + PPC_POWER_BR = 0x00080000,
  201 + /* PowerPC 602 specific */
  202 + PPC_602_SPEC = 0x00100000,
  203 + /* Deprecated instructions */
  204 + /* Original POWER instruction set */
  205 + PPC_POWER = 0x00200000,
  206 + /* POWER2 instruction set extension */
  207 + PPC_POWER2 = 0x00400000,
  208 + /* Power RTC support */
  209 + PPC_POWER_RTC = 0x00800000,
  210 + /* 64 bits PowerPC instructions */
  211 + /* 64 bits PowerPC instruction set */
  212 + PPC_64B = 0x01000000,
  213 + /* 64 bits hypervisor extensions */
  214 + PPC_64H = 0x02000000,
  215 + /* 64 bits PowerPC "bridge" features */
  216 + PPC_64_BRIDGE = 0x04000000,
49 }; 217 };
50 218
51 -#define PPC_COMMON (PPC_INTEGER | PPC_FLOAT | PPC_FLOW | PPC_MEM | \  
52 - PPC_RES | PPC_CACHE | PPC_MISC | PPC_SEGMENT)  
53 -/* PPC 604 */  
54 -#define PPC_604 (PPC_INTEGER | PPC_FLOAT | PPC_FLOW | PPC_MEM | \  
55 - PPC_RES | PPC_CACHE | PPC_MISC | PPC_EXTERN | PPC_SEGMENT \  
56 - PPC_MEM_OPT)  
57 -/* PPC 740/745/750/755 (aka G3) has external access instructions */  
58 -#define PPC_750 (PPC_INTEGER | PPC_FLOAT | PPC_FLOW | PPC_MEM | \  
59 - PPC_RES | PPC_CACHE | PPC_MISC | PPC_EXTERN | PPC_SEGMENT) 219 +/* CPU run-time flags (MMU and exception model) */
  220 +enum {
  221 + /* MMU model */
  222 +#define PPC_FLAGS_MMU_MASK (0x0000000F)
  223 + /* Standard 32 bits PowerPC MMU */
  224 + PPC_FLAGS_MMU_32B = 0x00000000,
  225 + /* Standard 64 bits PowerPC MMU */
  226 + PPC_FLAGS_MMU_64B = 0x00000001,
  227 + /* PowerPC 601 MMU */
  228 + PPC_FLAGS_MMU_601 = 0x00000002,
  229 + /* PowerPC 6xx MMU with software TLB */
  230 + PPC_FLAGS_MMU_SOFT_6xx = 0x00000003,
  231 + /* PowerPC 4xx MMU with software TLB */
  232 + PPC_FLAGS_MMU_SOFT_4xx = 0x00000004,
  233 + /* PowerPC 403 MMU */
  234 + PPC_FLAGS_MMU_403 = 0x00000005,
  235 + /* Exception model */
  236 +#define PPC_FLAGS_EXCP_MASK (0x000000F0)
  237 + /* Standard PowerPC exception model */
  238 + PPC_FLAGS_EXCP_STD = 0x00000000,
  239 + /* PowerPC 40x exception model */
  240 + PPC_FLAGS_EXCP_40x = 0x00000010,
  241 + /* PowerPC 601 exception model */
  242 + PPC_FLAGS_EXCP_601 = 0x00000020,
  243 + /* PowerPC 602 exception model */
  244 + PPC_FLAGS_EXCP_602 = 0x00000030,
  245 + /* PowerPC 603 exception model */
  246 + PPC_FLAGS_EXCP_603 = 0x00000040,
  247 + /* PowerPC 604 exception model */
  248 + PPC_FLAGS_EXCP_604 = 0x00000050,
  249 + /* PowerPC 7x0 exception model */
  250 + PPC_FLAGS_EXCP_7x0 = 0x00000060,
  251 + /* PowerPC 7x5 exception model */
  252 + PPC_FLAGS_EXCP_7x5 = 0x00000070,
  253 + /* PowerPC 74xx exception model */
  254 + PPC_FLAGS_EXCP_74xx = 0x00000080,
  255 + /* PowerPC 970 exception model */
  256 + PPC_FLAGS_EXCP_970 = 0x00000090,
  257 +};
  258 +
  259 +#define PPC_MMU(env) (env->flags & PPC_FLAGS_MMU_MASK)
  260 +#define PPC_EXCP(env) (env->flags & PPC_FLAGS_EXCP_MASK)
  261 +
  262 +/*****************************************************************************/
  263 +/* Supported instruction set definitions */
  264 +/* This generates an empty opcode table... */
  265 +#define PPC_INSNS_TODO (PPC_NONE)
  266 +#define PPC_FLAGS_TODO (0x00000000)
  267 +
  268 +/* PowerPC 40x instruction set */
  269 +#define PPC_INSNS_4xx (PPC_INSNS_BASE | PPC_MEM_TLBSYNC | PPC_4xx_COMMON)
  270 +/* PowerPC 401 */
  271 +#define PPC_INSNS_401 (PPC_INSNS_TODO)
  272 +#define PPC_FLAGS_401 (PPC_FLAGS_TODO)
  273 +/* PowerPC 403 */
  274 +#define PPC_INSNS_403 (PPC_INSNS_4xx | PPC_MEM_SYNC | PPC_MEM_TLBIA | \
  275 + PPC_40x_EXCP | PPC_40x_SPEC)
  276 +#define PPC_FLAGS_403 (PPC_FLAGS_MMU_403 | PPC_FLAGS_EXCP_40x)
  277 +/* PowerPC 405 */
  278 +#define PPC_INSNS_405 (PPC_INSNS_4xx | PPC_MEM_SYNC | PPC_CACHE_OPT | \
  279 + PPC_MEM_TLBIA | PPC_TB | PPC_40x_SPEC | PPC_40x_EXCP | \
  280 + PPC_405_MAC)
  281 +#define PPC_FLAGS_405 (PPC_FLAGS_MMU_SOFT_4xx | PPC_FLAGS_EXCP_40x)
  282 +/* PowerPC 440 */
  283 +#define PPC_INSNS_440 (PPC_INSNS_4xx | PPC_CACHE_OPT | PPC_405_MAC | \
  284 + PPC_440_SPEC)
  285 +#define PPC_FLAGS_440 (PPC_FLAGS_TODO)
  286 +/* Non-embedded PowerPC */
  287 +#define PPC_INSNS_COMMON (PPC_INSNS_BASE | PPC_FLOAT | PPC_MEM_SYNC | \
  288 + PPC_SEGMENT | PPC_MEM_TLBIE)
  289 +/* PowerPC 601 */
  290 +#define PPC_INSNS_601 (PPC_INSNS_COMMON | PPC_EXTERN | PPC_POWER_BR)
  291 +#define PPC_FLAGS_601 (PPC_FLAGS_MMU_601 | PPC_FLAGS_EXCP_601)
  292 +/* PowerPC 602 */
  293 +#define PPC_INSNS_602 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_6xx_TLB | \
  294 + PPC_MEM_TLBSYNC | PPC_TB)
  295 +#define PPC_FLAGS_602 (PPC_FLAGS_MMU_SOFT_6xx | PPC_FLAGS_EXCP_602)
  296 +/* PowerPC 603 */
  297 +#define PPC_INSNS_603 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_6xx_TLB | \
  298 + PPC_MEM_TLBSYNC | PPC_EXTERN | PPC_TB)
  299 +#define PPC_FLAGS_603 (PPC_FLAGS_MMU_SOFT_6xx | PPC_FLAGS_EXCP_603)
  300 +/* PowerPC G2 */
  301 +#define PPC_INSNS_G2 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_6xx_TLB | \
  302 + PPC_MEM_TLBSYNC | PPC_EXTERN | PPC_TB)
  303 +#define PPC_FLAGS_G2 (PPC_FLAGS_MMU_SOFT_6xx | PPC_FLAGS_EXCP_603)
  304 +/* PowerPC 604 */
  305 +#define PPC_INSNS_604 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_EXTERN | \
  306 + PPC_MEM_TLBSYNC | PPC_TB)
  307 +#define PPC_FLAGS_604 (PPC_FLAGS_MMU_32B | PPC_FLAGS_EXCP_604)
  308 +/* PowerPC 740/750 (aka G3) */
  309 +#define PPC_INSNS_7x0 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_EXTERN | \
  310 + PPC_MEM_TLBSYNC | PPC_TB)
  311 +#define PPC_FLAGS_7x0 (PPC_FLAGS_MMU_32B | PPC_FLAGS_EXCP_7x0)
  312 +/* PowerPC 745/755 */
  313 +#define PPC_INSNS_7x5 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_EXTERN | \
  314 + PPC_MEM_TLBSYNC | PPC_TB | PPC_6xx_TLB)
  315 +#define PPC_FLAGS_7x5 (PPC_FLAGS_MMU_SOFT_6xx | PPC_FLAGS_EXCP_7x5)
  316 +/* PowerPC 74xx (aka G4) */
  317 +#define PPC_INSNS_74xx (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_ALTIVEC | \
  318 + PPC_MEM_TLBSYNC | PPC_TB)
  319 +#define PPC_FLAGS_74xx (PPC_FLAGS_MMU_32B | PPC_FLAGS_EXCP_74xx)
  320 +
  321 +/* Default PowerPC will be 604/970 */
  322 +#define PPC_INSNS_PPC32 PPC_INSNS_604
  323 +#define PPC_FLAGS_PPC32 PPC_FLAGS_604
  324 +#if 0
  325 +#define PPC_INSNS_PPC64 PPC_INSNS_970
  326 +#define PPC_FLAGS_PPC64 PPC_FLAGS_970
  327 +#endif
  328 +#define PPC_INSNS_DEFAULT PPC_INSNS_604
  329 +#define PPC_FLAGS_DEFAULT PPC_FLAGS_604
  330 +typedef struct ppc_def_t ppc_def_t;
60 331
  332 +/*****************************************************************************/
  333 +/* Types used to describe some PowerPC registers */
  334 +typedef struct CPUPPCState CPUPPCState;
  335 +typedef struct opc_handler_t opc_handler_t;
61 typedef struct ppc_tb_t ppc_tb_t; 336 typedef struct ppc_tb_t ppc_tb_t;
  337 +typedef struct ppc_spr_t ppc_spr_t;
  338 +typedef struct ppc_dcr_t ppc_dcr_t;
  339 +typedef struct ppc_avr_t ppc_avr_t;
  340 +
  341 +/* SPR access micro-ops generations callbacks */
  342 +struct ppc_spr_t {
  343 + void (*uea_read)(void *opaque, int spr_num);
  344 + void (*uea_write)(void *opaque, int spr_num);
  345 + void (*oea_read)(void *opaque, int spr_num);
  346 + void (*oea_write)(void *opaque, int spr_num);
  347 + const unsigned char *name;
  348 +};
  349 +
  350 +/* Altivec registers (128 bits) */
  351 +struct ppc_avr_t {
  352 + uint32_t u[4];
  353 +};
62 354
63 -/* Supervisor mode registers */  
64 -/* Machine state register */  
65 -#define MSR_POW 18  
66 -#define MSR_ILE 16  
67 -#define MSR_EE 15  
68 -#define MSR_PR 14  
69 -#define MSR_FP 13  
70 -#define MSR_ME 12  
71 -#define MSR_FE0 11  
72 -#define MSR_SE 10  
73 -#define MSR_BE 9  
74 -#define MSR_FE1 8  
75 -#define MSR_IP 6  
76 -#define MSR_IR 5  
77 -#define MSR_DR 4  
78 -#define MSR_RI 1  
79 -#define MSR_LE 0 355 +/* Software TLB cache */
  356 +typedef struct ppc_tlb_t ppc_tlb_t;
  357 +struct ppc_tlb_t {
  358 + /* Physical page number */
  359 + target_phys_addr_t RPN;
  360 + /* Virtual page number */
  361 + target_ulong VPN;
  362 + /* Page size */
  363 + target_ulong size;
  364 + /* Protection bits */
  365 + int prot;
  366 + int is_user;
  367 + uint32_t private;
  368 + uint32_t flags;
  369 +};
  370 +
  371 +/*****************************************************************************/
  372 +/* Machine state register bits definition */
  373 +#define MSR_SF 63 /* Sixty-four-bit mode */
  374 +#define MSR_ISF 61 /* Sixty-four-bit interrupt mode on 630 */
  375 +#define MSR_HV 60 /* hypervisor state */
  376 +#define MSR_VR 25 /* altivec available */
  377 +#define MSR_AP 23 /* Access privilege state on 602 */
  378 +#define MSR_SA 22 /* Supervisor access mode on 602 */
  379 +#define MSR_KEY 19 /* key bit on 603e */
  380 +#define MSR_POW 18 /* Power management */
  381 +#define MSR_WE 18 /* Wait state enable on embedded PowerPC */
  382 +#define MSR_TGPR 17 /* TGPR usage on 602/603 */
  383 +#define MSR_TLB 17 /* TLB on ? */
  384 +#define MSR_CE 17 /* Critical interrupt enable on embedded PowerPC */
  385 +#define MSR_ILE 16 /* Interrupt little-endian mode */
  386 +#define MSR_EE 15 /* External interrupt enable */
  387 +#define MSR_PR 14 /* Problem state */
  388 +#define MSR_FP 13 /* Floating point available */
  389 +#define MSR_ME 12 /* Machine check interrupt enable */
  390 +#define MSR_FE0 11 /* Floating point exception mode 0 */
  391 +#define MSR_SE 10 /* Single-step trace enable */
  392 +#define MSR_DWE 10 /* Debug wait enable on 405 */
  393 +#define MSR_BE 9 /* Branch trace enable */
  394 +#define MSR_DE 9 /* Debug interrupts enable on embedded PowerPC */
  395 +#define MSR_FE1 8 /* Floating point exception mode 1 */
  396 +#define MSR_AL 7 /* AL bit on POWER */
  397 +#define MSR_IP 6 /* Interrupt prefix */
  398 +#define MSR_IR 5 /* Instruction relocate */
  399 +#define MSR_IS 5 /* Instruction address space on embedded PowerPC */
  400 +#define MSR_DR 4 /* Data relocate */
  401 +#define MSR_DS 4 /* Data address space on embedded PowerPC */
  402 +#define MSR_PE 3 /* Protection enable on 403 */
  403 +#define MSR_EP 3 /* Exception prefix on 601 */
  404 +#define MSR_PX 2 /* Protection exclusive on 403 */
  405 +#define MSR_PMM 2 /* Performance monitor mark on POWER */
  406 +#define MSR_RI 1 /* Recoverable interrupt */
  407 +#define MSR_LE 0 /* Little-endian mode */
  408 +#define msr_sf env->msr[MSR_SF]
  409 +#define msr_isf env->msr[MSR_ISF]
  410 +#define msr_hv env->msr[MSR_HV]
  411 +#define msr_vr env->msr[MSR_VR]
  412 +#define msr_ap env->msr[MSR_AP]
  413 +#define msr_sa env->msr[MSR_SA]
  414 +#define msr_key env->msr[MSR_KEY]
80 #define msr_pow env->msr[MSR_POW] 415 #define msr_pow env->msr[MSR_POW]
  416 +#define msr_we env->msr[MSR_WE]
  417 +#define msr_tgpr env->msr[MSR_TGPR]
  418 +#define msr_tlb env->msr[MSR_TLB]
  419 +#define msr_ce env->msr[MSR_CE]
81 #define msr_ile env->msr[MSR_ILE] 420 #define msr_ile env->msr[MSR_ILE]
82 #define msr_ee env->msr[MSR_EE] 421 #define msr_ee env->msr[MSR_EE]
83 #define msr_pr env->msr[MSR_PR] 422 #define msr_pr env->msr[MSR_PR]
@@ -85,58 +424,72 @@ typedef struct ppc_tb_t ppc_tb_t; @@ -85,58 +424,72 @@ typedef struct ppc_tb_t ppc_tb_t;
85 #define msr_me env->msr[MSR_ME] 424 #define msr_me env->msr[MSR_ME]
86 #define msr_fe0 env->msr[MSR_FE0] 425 #define msr_fe0 env->msr[MSR_FE0]
87 #define msr_se env->msr[MSR_SE] 426 #define msr_se env->msr[MSR_SE]
  427 +#define msr_dwe env->msr[MSR_DWE]
88 #define msr_be env->msr[MSR_BE] 428 #define msr_be env->msr[MSR_BE]
  429 +#define msr_de env->msr[MSR_DE]
89 #define msr_fe1 env->msr[MSR_FE1] 430 #define msr_fe1 env->msr[MSR_FE1]
  431 +#define msr_al env->msr[MSR_AL]
90 #define msr_ip env->msr[MSR_IP] 432 #define msr_ip env->msr[MSR_IP]
91 #define msr_ir env->msr[MSR_IR] 433 #define msr_ir env->msr[MSR_IR]
  434 +#define msr_is env->msr[MSR_IS]
92 #define msr_dr env->msr[MSR_DR] 435 #define msr_dr env->msr[MSR_DR]
  436 +#define msr_ds env->msr[MSR_DS]
  437 +#define msr_pe env->msr[MSR_PE]
  438 +#define msr_ep env->msr[MSR_EP]
  439 +#define msr_px env->msr[MSR_PX]
  440 +#define msr_pmm env->msr[MSR_PMM]
93 #define msr_ri env->msr[MSR_RI] 441 #define msr_ri env->msr[MSR_RI]
94 #define msr_le env->msr[MSR_LE] 442 #define msr_le env->msr[MSR_LE]
95 443
96 -/* Segment registers */  
97 -typedef struct CPUPPCState { 444 +/*****************************************************************************/
  445 +/* The whole PowerPC CPU context */
  446 +struct CPUPPCState {
  447 + /* First are the most commonly used resources
  448 + * during translated code execution
  449 + */
  450 +#if TARGET_LONG_BITS > HOST_LONG_BITS
  451 + /* temporary fixed-point registers
  452 + * used to emulate 64 bits target on 32 bits hosts
  453 + */
  454 + target_ulong t0, t1, t2;
  455 +#endif
98 /* general purpose registers */ 456 /* general purpose registers */
99 - uint32_t gpr[32];  
100 - /* floating point registers */  
101 - float64 fpr[32];  
102 - /* segment registers */  
103 - uint32_t sdr1;  
104 - uint32_t sr[16]; 457 + target_ulong gpr[32];
  458 + /* LR */
  459 + target_ulong lr;
  460 + /* CTR */
  461 + target_ulong ctr;
  462 + /* condition register */
  463 + uint8_t crf[8];
105 /* XER */ 464 /* XER */
106 - uint8_t xer[4]; 465 + /* XXX: We use only 5 fields, but we want to keep the structure aligned */
  466 + uint8_t xer[8];
107 /* Reservation address */ 467 /* Reservation address */
108 - uint32_t reserve; 468 + target_ulong reserve;
  469 +
  470 + /* Those ones are used in supervisor mode only */
109 /* machine state register */ 471 /* machine state register */
110 - uint8_t msr[32];  
111 - /* condition register */  
112 - uint8_t crf[8];  
113 - /* floating point status and control register */  
114 - uint8_t fpscr[8];  
115 - uint32_t nip;  
116 - /* special purpose registers */  
117 - uint32_t lr;  
118 - uint32_t ctr;  
119 - /* BATs */  
120 - uint32_t DBAT[2][8];  
121 - uint32_t IBAT[2][8];  
122 - /* all others */  
123 - uint32_t spr[1024];  
124 - /* qemu dedicated */ 472 + uint8_t msr[64];
  473 + /* temporary general purpose registers */
  474 + target_ulong tgpr[4]; /* Used to speed-up TLB assist handlers */
  475 +
  476 + /* Floating point execution context */
125 /* temporary float registers */ 477 /* temporary float registers */
126 float64 ft0; 478 float64 ft0;
127 float64 ft1; 479 float64 ft1;
128 float64 ft2; 480 float64 ft2;
129 float_status fp_status; 481 float_status fp_status;
  482 + /* floating point registers */
  483 + float64 fpr[32];
  484 + /* floating point status and control register */
  485 + uint8_t fpscr[8];
130 486
131 - int interrupt_request;  
132 - jmp_buf jmp_env;  
133 - int exception_index;  
134 - int error_code; 487 + /* soft mmu support */
  488 + /* 0 = kernel, 1 = user (may have 2 = kernel code, 3 = user code ?) */
  489 + CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
  490 + CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];
135 int access_type; /* when a memory exception occurs, the access 491 int access_type; /* when a memory exception occurs, the access
136 type is stored here */ 492 type is stored here */
137 - int user_mode_only; /* user mode only simulation */  
138 - struct TranslationBlock *current_tb; /* currently executing TB */  
139 - /* soft mmu support */  
140 /* in order to avoid passing too many arguments to the memory 493 /* in order to avoid passing too many arguments to the memory
141 write helpers, we store some rarely used information in the CPU 494 write helpers, we store some rarely used information in the CPU
142 context) */ 495 context) */
@@ -144,17 +497,71 @@ typedef struct CPUPPCState { @@ -144,17 +497,71 @@ typedef struct CPUPPCState {
144 written */ 497 written */
145 unsigned long mem_write_vaddr; /* target virtual addr at which the 498 unsigned long mem_write_vaddr; /* target virtual addr at which the
146 memory was written */ 499 memory was written */
147 - /* 0 = kernel, 1 = user (may have 2 = kernel code, 3 = user code ?) */  
148 - CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];  
149 - CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];  
150 500
151 - /* ice debug support */  
152 - uint32_t breakpoints[MAX_BREAKPOINTS];  
153 - int nb_breakpoints;  
154 - int singlestep_enabled; /* XXX: should use CPU single step mode instead */ 501 + /* MMU context */
  502 + /* Address space register */
  503 + target_ulong asr;
  504 + /* segment registers */
  505 + target_ulong sdr1;
  506 + target_ulong sr[16];
  507 + /* BATs */
  508 + int nb_BATs;
  509 + target_ulong DBAT[2][8];
  510 + target_ulong IBAT[2][8];
155 511
  512 + /* Other registers */
  513 + /* Special purpose registers */
  514 + target_ulong spr[1024];
  515 + /* Altivec registers */
  516 + ppc_avr_t avr[32];
  517 + uint32_t vscr;
  518 +
  519 + /* Internal devices resources */
156 /* Time base and decrementer */ 520 /* Time base and decrementer */
157 ppc_tb_t *tb_env; 521 ppc_tb_t *tb_env;
  522 + /* Device control registers */
  523 + int (*dcr_read)(ppc_dcr_t *dcr_env, int dcr_num, target_ulong *val);
  524 + int (*dcr_write)(ppc_dcr_t *dcr_env, int dcr_num, target_ulong val);
  525 + ppc_dcr_t *dcr_env;
  526 +
  527 + /* PowerPC TLB registers (for 4xx and 60x software driven TLBs) */
  528 + int nb_tlb;
  529 + int nb_ways, last_way;
  530 + ppc_tlb_t tlb[128];
  531 + /* Callbacks for specific checks on some implementations */
  532 + int (*tlb_check_more)(CPUPPCState *env, struct ppc_tlb_t *tlb, int *prot,
  533 + target_ulong vaddr, int rw, int acc_type,
  534 + int is_user);
  535 + /* 403 dedicated access protection registers */
  536 + target_ulong pb[4];
  537 +
  538 + /* Those resources are used during exception processing */
  539 + /* CPU model definition */
  540 + uint64_t msr_mask;
  541 + uint32_t flags;
  542 +
  543 + int exception_index;
  544 + int error_code;
  545 + int interrupt_request;
  546 +
  547 + /* Those resources are used only during code translation */
  548 + /* Next instruction pointer */
  549 + target_ulong nip;
  550 + /* SPR translation callbacks */
  551 + ppc_spr_t spr_cb[1024];
  552 + /* opcode handlers */
  553 + opc_handler_t *opcodes[0x40];
  554 +
  555 + /* Those resources are used only in Qemu core */
  556 + jmp_buf jmp_env;
  557 + int user_mode_only; /* user mode only simulation */
  558 + struct TranslationBlock *current_tb; /* currently executing TB */
  559 + uint32_t hflags;
  560 +
  561 + /* ice debug support */
  562 + target_ulong breakpoints[MAX_BREAKPOINTS];
  563 + int nb_breakpoints;
  564 + int singlestep_enabled; /* XXX: should use CPU single step mode instead */
158 565
159 /* Power management */ 566 /* Power management */
160 int power_mode; 567 int power_mode;
@@ -164,8 +571,9 @@ typedef struct CPUPPCState { @@ -164,8 +571,9 @@ typedef struct CPUPPCState {
164 571
165 /* user data */ 572 /* user data */
166 void *opaque; 573 void *opaque;
167 -} CPUPPCState; 574 +};
168 575
  576 +/*****************************************************************************/
169 CPUPPCState *cpu_ppc_init(void); 577 CPUPPCState *cpu_ppc_init(void);
170 int cpu_ppc_exec(CPUPPCState *s); 578 int cpu_ppc_exec(CPUPPCState *s);
171 void cpu_ppc_close(CPUPPCState *s); 579 void cpu_ppc_close(CPUPPCState *s);
@@ -181,12 +589,38 @@ void cpu_loop_exit(void); @@ -181,12 +589,38 @@ void cpu_loop_exit(void);
181 589
182 void dump_stack (CPUPPCState *env); 590 void dump_stack (CPUPPCState *env);
183 591
184 -uint32_t _load_xer (CPUPPCState *env);  
185 -void _store_xer (CPUPPCState *env, uint32_t value);  
186 -uint32_t _load_msr (CPUPPCState *env);  
187 -void _store_msr (CPUPPCState *env, uint32_t value); 592 +target_ulong do_load_ibatu (CPUPPCState *env, int nr);
  593 +target_ulong do_load_ibatl (CPUPPCState *env, int nr);
  594 +void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value);
  595 +void do_store_ibatl (CPUPPCState *env, int nr, target_ulong value);
  596 +target_ulong do_load_dbatu (CPUPPCState *env, int nr);
  597 +target_ulong do_load_dbatl (CPUPPCState *env, int nr);
  598 +void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value);
  599 +void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value);
  600 +
  601 +target_ulong do_load_nip (CPUPPCState *env);
  602 +void do_store_nip (CPUPPCState *env, target_ulong value);
  603 +target_ulong do_load_sdr1 (CPUPPCState *env);
  604 +void do_store_sdr1 (CPUPPCState *env, target_ulong value);
  605 +target_ulong do_load_asr (CPUPPCState *env);
  606 +void do_store_asr (CPUPPCState *env, target_ulong value);
  607 +target_ulong do_load_sr (CPUPPCState *env, int srnum);
  608 +void do_store_sr (CPUPPCState *env, int srnum, target_ulong value);
  609 +uint32_t do_load_cr (CPUPPCState *env);
  610 +void do_store_cr (CPUPPCState *env, uint32_t value, uint32_t mask);
  611 +uint32_t do_load_xer (CPUPPCState *env);
  612 +void do_store_xer (CPUPPCState *env, uint32_t value);
  613 +target_ulong do_load_msr (CPUPPCState *env);
  614 +void do_store_msr (CPUPPCState *env, target_ulong value);
  615 +float64 do_load_fpscr (CPUPPCState *env);
  616 +void do_store_fpscr (CPUPPCState *env, float64 f, uint32_t mask);
  617 +
  618 +void do_compute_hflags (CPUPPCState *env);
188 619
189 -int cpu_ppc_register (CPUPPCState *env, uint32_t pvr); 620 +int ppc_find_by_name (const unsigned char *name, ppc_def_t **def);
  621 +int ppc_find_by_pvr (uint32_t apvr, ppc_def_t **def);
  622 +void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
  623 +int cpu_ppc_register (CPUPPCState *env, ppc_def_t *def);
190 624
191 /* Time-base and decrementer management */ 625 /* Time-base and decrementer management */
192 #ifndef NO_CPU_IO_DEFS 626 #ifndef NO_CPU_IO_DEFS
@@ -201,132 +635,276 @@ void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value); @@ -201,132 +635,276 @@ void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value);
201 #define TARGET_PAGE_BITS 12 635 #define TARGET_PAGE_BITS 12
202 #include "cpu-all.h" 636 #include "cpu-all.h"
203 637
  638 +/*****************************************************************************/
  639 +/* Registers definitions */
204 #define ugpr(n) (env->gpr[n]) 640 #define ugpr(n) (env->gpr[n])
205 -#define fprd(n) (env->fpr[n])  
206 -#define fprs(n) ((float)env->fpr[n])  
207 -#define fpru(n) ((uint32_t)env->fpr[n])  
208 -#define fpri(n) ((int32_t)env->fpr[n])  
209 -  
210 -#define SPR_ENCODE(sprn) \  
211 -(((sprn) >> 5) | (((sprn) & 0x1F) << 5))  
212 641
213 -/* User mode SPR */  
214 -#define spr(n) env->spr[n]  
215 #define XER_SO 31 642 #define XER_SO 31
216 #define XER_OV 30 643 #define XER_OV 30
217 #define XER_CA 29 644 #define XER_CA 29
  645 +#define XER_CMP 8
218 #define XER_BC 0 646 #define XER_BC 0
219 -#define xer_so env->xer[3]  
220 -#define xer_ov env->xer[2]  
221 -#define xer_ca env->xer[1] 647 +#define xer_so env->xer[4]
  648 +#define xer_ov env->xer[6]
  649 +#define xer_ca env->xer[2]
  650 +#define xer_cmp env->xer[1]
222 #define xer_bc env->xer[0] 651 #define xer_bc env->xer[0]
223 652
224 -#define MQ SPR_ENCODE(0)  
225 -#define XER SPR_ENCODE(1)  
226 -#define RTCUR SPR_ENCODE(4)  
227 -#define RTCLR SPR_ENCODE(5)  
228 -#define LR SPR_ENCODE(8)  
229 -#define CTR SPR_ENCODE(9)  
230 -/* VEA mode SPR */  
231 -#define V_TBL SPR_ENCODE(268)  
232 -#define V_TBU SPR_ENCODE(269)  
233 -/* supervisor mode SPR */  
234 -#define DSISR SPR_ENCODE(18)  
235 -#define DAR SPR_ENCODE(19)  
236 -#define RTCUW SPR_ENCODE(20)  
237 -#define RTCLW SPR_ENCODE(21)  
238 -#define DECR SPR_ENCODE(22)  
239 -#define SDR1 SPR_ENCODE(25)  
240 -#define SRR0 SPR_ENCODE(26)  
241 -#define SRR1 SPR_ENCODE(27)  
242 -#define SPRG0 SPR_ENCODE(272)  
243 -#define SPRG1 SPR_ENCODE(273)  
244 -#define SPRG2 SPR_ENCODE(274)  
245 -#define SPRG3 SPR_ENCODE(275)  
246 -#define SPRG4 SPR_ENCODE(276)  
247 -#define SPRG5 SPR_ENCODE(277)  
248 -#define SPRG6 SPR_ENCODE(278)  
249 -#define SPRG7 SPR_ENCODE(279)  
250 -#define ASR SPR_ENCODE(280)  
251 -#define EAR SPR_ENCODE(282)  
252 -#define O_TBL SPR_ENCODE(284)  
253 -#define O_TBU SPR_ENCODE(285)  
254 -#define PVR SPR_ENCODE(287)  
255 -#define IBAT0U SPR_ENCODE(528)  
256 -#define IBAT0L SPR_ENCODE(529)  
257 -#define IBAT1U SPR_ENCODE(530)  
258 -#define IBAT1L SPR_ENCODE(531)  
259 -#define IBAT2U SPR_ENCODE(532)  
260 -#define IBAT2L SPR_ENCODE(533)  
261 -#define IBAT3U SPR_ENCODE(534)  
262 -#define IBAT3L SPR_ENCODE(535)  
263 -#define DBAT0U SPR_ENCODE(536)  
264 -#define DBAT0L SPR_ENCODE(537)  
265 -#define DBAT1U SPR_ENCODE(538)  
266 -#define DBAT1L SPR_ENCODE(539)  
267 -#define DBAT2U SPR_ENCODE(540)  
268 -#define DBAT2L SPR_ENCODE(541)  
269 -#define DBAT3U SPR_ENCODE(542)  
270 -#define DBAT3L SPR_ENCODE(543)  
271 -#define IBAT4U SPR_ENCODE(560)  
272 -#define IBAT4L SPR_ENCODE(561)  
273 -#define IBAT5U SPR_ENCODE(562)  
274 -#define IBAT5L SPR_ENCODE(563)  
275 -#define IBAT6U SPR_ENCODE(564)  
276 -#define IBAT6L SPR_ENCODE(565)  
277 -#define IBAT7U SPR_ENCODE(566)  
278 -#define IBAT7L SPR_ENCODE(567)  
279 -#define DBAT4U SPR_ENCODE(568)  
280 -#define DBAT4L SPR_ENCODE(569)  
281 -#define DBAT5U SPR_ENCODE(570)  
282 -#define DBAT5L SPR_ENCODE(571)  
283 -#define DBAT6U SPR_ENCODE(572)  
284 -#define DBAT6L SPR_ENCODE(573)  
285 -#define DBAT7U SPR_ENCODE(574)  
286 -#define DBAT7L SPR_ENCODE(575)  
287 -#define UMMCR0 SPR_ENCODE(936)  
288 -#define UPMC1 SPR_ENCODE(937)  
289 -#define UPMC2 SPR_ENCODE(938)  
290 -#define USIA SPR_ENCODE(939)  
291 -#define UMMCR1 SPR_ENCODE(940)  
292 -#define UPMC3 SPR_ENCODE(941)  
293 -#define UPMC4 SPR_ENCODE(942)  
294 -#define MMCR0 SPR_ENCODE(952)  
295 -#define PMC1 SPR_ENCODE(953)  
296 -#define PMC2 SPR_ENCODE(954)  
297 -#define SIA SPR_ENCODE(955)  
298 -#define MMCR1 SPR_ENCODE(956)  
299 -#define PMC3 SPR_ENCODE(957)  
300 -#define PMC4 SPR_ENCODE(958)  
301 -#define SDA SPR_ENCODE(959)  
302 -#define DMISS SPR_ENCODE(976)  
303 -#define DCMP SPR_ENCODE(977)  
304 -#define DHASH1 SPR_ENCODE(978)  
305 -#define DHASH2 SPR_ENCODE(979)  
306 -#define IMISS SPR_ENCODE(980)  
307 -#define ICMP SPR_ENCODE(981)  
308 -#define RPA SPR_ENCODE(982)  
309 -#define TCR SPR_ENCODE(984)  
310 -#define IBR SPR_ENCODE(986)  
311 -#define ESASRR SPR_ENCODE(987)  
312 -#define SEBR SPR_ENCODE(990)  
313 -#define SER SPR_ENCODE(991)  
314 -#define HID0 SPR_ENCODE(1008)  
315 -#define HID1 SPR_ENCODE(1009)  
316 -#define IABR SPR_ENCODE(1010)  
317 -#define HID2 SPR_ENCODE(1011)  
318 -#define DABR SPR_ENCODE(1013)  
319 -#define L2PM SPR_ENCODE(1016)  
320 -#define L2CR SPR_ENCODE(1017)  
321 -#define ICTC SPR_ENCODE(1019)  
322 -#define THRM1 SPR_ENCODE(1020)  
323 -#define THRM2 SPR_ENCODE(1021)  
324 -#define THRM3 SPR_ENCODE(1022)  
325 -#define SP SPR_ENCODE(1021)  
326 -#define SPR_LP SPR_ENCODE(1022)  
327 -#define DABR_MASK 0xFFFFFFF8  
328 -#define FPECR SPR_ENCODE(1022)  
329 -#define PIR SPR_ENCODE(1023) 653 +/* SPR definitions */
  654 +#define SPR_MQ (0x000)
  655 +#define SPR_XER (0x001)
  656 +#define SPR_601_VRTCU (0x004)
  657 +#define SPR_601_VRTCL (0x005)
  658 +#define SPR_601_UDECR (0x006)
  659 +#define SPR_LR (0x008)
  660 +#define SPR_CTR (0x009)
  661 +#define SPR_DSISR (0x012)
  662 +#define SPR_DAR (0x013)
  663 +#define SPR_601_RTCU (0x014)
  664 +#define SPR_601_RTCL (0x015)
  665 +#define SPR_DECR (0x016)
  666 +#define SPR_SDR1 (0x019)
  667 +#define SPR_SRR0 (0x01A)
  668 +#define SPR_SRR1 (0x01B)
  669 +#define SPR_440_PID (0x030)
  670 +#define SPR_440_DECAR (0x036)
  671 +#define SPR_CSRR0 (0x03A)
  672 +#define SPR_CSRR1 (0x03B)
  673 +#define SPR_440_DEAR (0x03D)
  674 +#define SPR_440_ESR (0x03E)
  675 +#define SPR_440_IVPR (0x03F)
  676 +#define SPR_8xx_EIE (0x050)
  677 +#define SPR_8xx_EID (0x051)
  678 +#define SPR_8xx_NRE (0x052)
  679 +#define SPR_58x_CMPA (0x090)
  680 +#define SPR_58x_CMPB (0x091)
  681 +#define SPR_58x_CMPC (0x092)
  682 +#define SPR_58x_CMPD (0x093)
  683 +#define SPR_58x_ICR (0x094)
  684 +#define SPR_58x_DER (0x094)
  685 +#define SPR_58x_COUNTA (0x096)
  686 +#define SPR_58x_COUNTB (0x097)
  687 +#define SPR_58x_CMPE (0x098)
  688 +#define SPR_58x_CMPF (0x099)
  689 +#define SPR_58x_CMPG (0x09A)
  690 +#define SPR_58x_CMPH (0x09B)
  691 +#define SPR_58x_LCTRL1 (0x09C)
  692 +#define SPR_58x_LCTRL2 (0x09D)
  693 +#define SPR_58x_ICTRL (0x09E)
  694 +#define SPR_58x_BAR (0x09F)
  695 +#define SPR_VRSAVE (0x100)
  696 +#define SPR_USPRG0 (0x100)
  697 +#define SPR_USPRG4 (0x104)
  698 +#define SPR_USPRG5 (0x105)
  699 +#define SPR_USPRG6 (0x106)
  700 +#define SPR_USPRG7 (0x107)
  701 +#define SPR_VTBL (0x10C)
  702 +#define SPR_VTBU (0x10D)
  703 +#define SPR_SPRG0 (0x110)
  704 +#define SPR_SPRG1 (0x111)
  705 +#define SPR_SPRG2 (0x112)
  706 +#define SPR_SPRG3 (0x113)
  707 +#define SPR_SPRG4 (0x114)
  708 +#define SPR_SCOMC (0x114)
  709 +#define SPR_SPRG5 (0x115)
  710 +#define SPR_SCOMD (0x115)
  711 +#define SPR_SPRG6 (0x116)
  712 +#define SPR_SPRG7 (0x117)
  713 +#define SPR_ASR (0x118)
  714 +#define SPR_EAR (0x11A)
  715 +#define SPR_TBL (0x11C)
  716 +#define SPR_TBU (0x11D)
  717 +#define SPR_SVR (0x11E)
  718 +#define SPR_440_PIR (0x11E)
  719 +#define SPR_PVR (0x11F)
  720 +#define SPR_HSPRG0 (0x130)
  721 +#define SPR_440_DBSR (0x130)
  722 +#define SPR_HSPRG1 (0x131)
  723 +#define SPR_440_DBCR0 (0x134)
  724 +#define SPR_IBCR (0x135)
  725 +#define SPR_440_DBCR1 (0x135)
  726 +#define SPR_DBCR (0x136)
  727 +#define SPR_HDEC (0x136)
  728 +#define SPR_440_DBCR2 (0x136)
  729 +#define SPR_HIOR (0x137)
  730 +#define SPR_MBAR (0x137)
  731 +#define SPR_RMOR (0x138)
  732 +#define SPR_440_IAC1 (0x138)
  733 +#define SPR_HRMOR (0x139)
  734 +#define SPR_440_IAC2 (0x139)
  735 +#define SPR_HSSR0 (0x13A)
  736 +#define SPR_440_IAC3 (0x13A)
  737 +#define SPR_HSSR1 (0x13B)
  738 +#define SPR_440_IAC4 (0x13B)
  739 +#define SPR_LPCR (0x13C)
  740 +#define SPR_440_DAC1 (0x13C)
  741 +#define SPR_LPIDR (0x13D)
  742 +#define SPR_DABR2 (0x13D)
  743 +#define SPR_440_DAC2 (0x13D)
  744 +#define SPR_440_DVC1 (0x13E)
  745 +#define SPR_440_DVC2 (0x13F)
  746 +#define SPR_440_TSR (0x150)
  747 +#define SPR_440_TCR (0x154)
  748 +#define SPR_440_IVOR0 (0x190)
  749 +#define SPR_440_IVOR1 (0x191)
  750 +#define SPR_440_IVOR2 (0x192)
  751 +#define SPR_440_IVOR3 (0x193)
  752 +#define SPR_440_IVOR4 (0x194)
  753 +#define SPR_440_IVOR5 (0x195)
  754 +#define SPR_440_IVOR6 (0x196)
  755 +#define SPR_440_IVOR7 (0x197)
  756 +#define SPR_440_IVOR8 (0x198)
  757 +#define SPR_440_IVOR9 (0x199)
  758 +#define SPR_440_IVOR10 (0x19A)
  759 +#define SPR_440_IVOR11 (0x19B)
  760 +#define SPR_440_IVOR12 (0x19C)
  761 +#define SPR_440_IVOR13 (0x19D)
  762 +#define SPR_440_IVOR14 (0x19E)
  763 +#define SPR_440_IVOR15 (0x19F)
  764 +#define SPR_IBAT0U (0x210)
  765 +#define SPR_IBAT0L (0x211)
  766 +#define SPR_IBAT1U (0x212)
  767 +#define SPR_IBAT1L (0x213)
  768 +#define SPR_IBAT2U (0x214)
  769 +#define SPR_IBAT2L (0x215)
  770 +#define SPR_IBAT3U (0x216)
  771 +#define SPR_IBAT3L (0x217)
  772 +#define SPR_DBAT0U (0x218)
  773 +#define SPR_DBAT0L (0x219)
  774 +#define SPR_DBAT1U (0x21A)
  775 +#define SPR_DBAT1L (0x21B)
  776 +#define SPR_DBAT2U (0x21C)
  777 +#define SPR_DBAT2L (0x21D)
  778 +#define SPR_DBAT3U (0x21E)
  779 +#define SPR_DBAT3L (0x21F)
  780 +#define SPR_IBAT4U (0x230)
  781 +#define SPR_IBAT4L (0x231)
  782 +#define SPR_IBAT5U (0x232)
  783 +#define SPR_IBAT5L (0x233)
  784 +#define SPR_IBAT6U (0x234)
  785 +#define SPR_IBAT6L (0x235)
  786 +#define SPR_IBAT7U (0x236)
  787 +#define SPR_IBAT7L (0x237)
  788 +#define SPR_DBAT4U (0x238)
  789 +#define SPR_DBAT4L (0x239)
  790 +#define SPR_DBAT5U (0x23A)
  791 +#define SPR_DBAT5L (0x23B)
  792 +#define SPR_DBAT6U (0x23C)
  793 +#define SPR_DBAT6L (0x23D)
  794 +#define SPR_DBAT7U (0x23E)
  795 +#define SPR_DBAT7L (0x23F)
  796 +#define SPR_440_INV0 (0x370)
  797 +#define SPR_440_INV1 (0x371)
  798 +#define SPR_440_INV2 (0x372)
  799 +#define SPR_440_INV3 (0x373)
  800 +#define SPR_440_IVT0 (0x374)
  801 +#define SPR_440_IVT1 (0x375)
  802 +#define SPR_440_IVT2 (0x376)
  803 +#define SPR_440_IVT3 (0x377)
  804 +#define SPR_440_DNV0 (0x390)
  805 +#define SPR_440_DNV1 (0x391)
  806 +#define SPR_440_DNV2 (0x392)
  807 +#define SPR_440_DNV3 (0x393)
  808 +#define SPR_440_DVT0 (0x394)
  809 +#define SPR_440_DVT1 (0x395)
  810 +#define SPR_440_DVT2 (0x396)
  811 +#define SPR_440_DVT3 (0x397)
  812 +#define SPR_440_DVLIM (0x398)
  813 +#define SPR_440_IVLIM (0x399)
  814 +#define SPR_440_RSTCFG (0x39B)
  815 +#define SPR_440_DCBTRL (0x39C)
  816 +#define SPR_440_DCBTRH (0x39D)
  817 +#define SPR_440_ICBTRL (0x39E)
  818 +#define SPR_440_ICBTRH (0x39F)
  819 +#define SPR_UMMCR0 (0x3A8)
  820 +#define SPR_UPMC1 (0x3A9)
  821 +#define SPR_UPMC2 (0x3AA)
  822 +#define SPR_USIA (0x3AB)
  823 +#define SPR_UMMCR1 (0x3AC)
  824 +#define SPR_UPMC3 (0x3AD)
  825 +#define SPR_UPMC4 (0x3AE)
  826 +#define SPR_USDA (0x3AF)
  827 +#define SPR_40x_ZPR (0x3B0)
  828 +#define SPR_40x_PID (0x3B1)
  829 +#define SPR_440_MMUCR (0x3B2)
  830 +#define SPR_4xx_CCR0 (0x3B3)
  831 +#define SPR_405_IAC3 (0x3B4)
  832 +#define SPR_405_IAC4 (0x3B5)
  833 +#define SPR_405_DVC1 (0x3B6)
  834 +#define SPR_405_DVC2 (0x3B7)
  835 +#define SPR_MMCR0 (0x3B8)
  836 +#define SPR_PMC1 (0x3B9)
  837 +#define SPR_40x_SGR (0x3B9)
  838 +#define SPR_PMC2 (0x3BA)
  839 +#define SPR_40x_DCWR (0x3BA)
  840 +#define SPR_SIA (0x3BB)
  841 +#define SPR_405_SLER (0x3BB)
  842 +#define SPR_MMCR1 (0x3BC)
  843 +#define SPR_405_SU0R (0x3BC)
  844 +#define SPR_PMC3 (0x3BD)
  845 +#define SPR_405_DBCR1 (0x3BD)
  846 +#define SPR_PMC4 (0x3BE)
  847 +#define SPR_SDA (0x3BF)
  848 +#define SPR_403_VTBL (0x3CC)
  849 +#define SPR_403_VTBU (0x3CD)
  850 +#define SPR_DMISS (0x3D0)
  851 +#define SPR_DCMP (0x3D1)
  852 +#define SPR_DHASH1 (0x3D2)
  853 +#define SPR_DHASH2 (0x3D3)
  854 +#define SPR_4xx_ICDBDR (0x3D3)
  855 +#define SPR_IMISS (0x3D4)
  856 +#define SPR_40x_ESR (0x3D4)
  857 +#define SPR_ICMP (0x3D5)
  858 +#define SPR_40x_DEAR (0x3D5)
  859 +#define SPR_RPA (0x3D6)
  860 +#define SPR_40x_EVPR (0x3D6)
  861 +#define SPR_403_CDBCR (0x3D7)
  862 +#define SPR_TCR (0x3D8)
  863 +#define SPR_40x_TSR (0x3D8)
  864 +#define SPR_IBR (0x3DA)
  865 +#define SPR_40x_TCR (0x3DA)
  866 +#define SPR_ESASR (0x3DB)
  867 +#define SPR_40x_PIT (0x3DB)
  868 +#define SPR_403_TBL (0x3DC)
  869 +#define SPR_403_TBU (0x3DD)
  870 +#define SPR_SEBR (0x3DE)
  871 +#define SPR_40x_SRR2 (0x3DE)
  872 +#define SPR_SER (0x3DF)
  873 +#define SPR_40x_SRR3 (0x3DF)
  874 +#define SPR_HID0 (0x3F0)
  875 +#define SPR_40x_DBSR (0x3F0)
  876 +#define SPR_HID1 (0x3F1)
  877 +#define SPR_IABR (0x3F2)
  878 +#define SPR_40x_DBCR0 (0x3F2)
  879 +#define SPR_601_HID2 (0x3F2)
  880 +#define SPR_HID2 (0x3F3)
  881 +#define SPR_440_DBDR (0x3F3)
  882 +#define SPR_40x_IAC1 (0x3F4)
  883 +#define SPR_DABR (0x3F5)
  884 +#define DABR_MASK (~(target_ulong)0x7)
  885 +#define SPR_40x_IAC2 (0x3F5)
  886 +#define SPR_601_HID5 (0x3F5)
  887 +#define SPR_40x_DAC1 (0x3F6)
  888 +#define SPR_40x_DAC2 (0x3F7)
  889 +#define SPR_L2PM (0x3F8)
  890 +#define SPR_750_HID2 (0x3F8)
  891 +#define SPR_L2CR (0x3F9)
  892 +#define SPR_IABR2 (0x3FA)
  893 +#define SPR_40x_DCCR (0x3FA)
  894 +#define SPR_ICTC (0x3FB)
  895 +#define SPR_40x_ICCR (0x3FB)
  896 +#define SPR_THRM1 (0x3FC)
  897 +#define SPR_403_PBL1 (0x3FC)
  898 +#define SPR_SP (0x3FD)
  899 +#define SPR_THRM2 (0x3FD)
  900 +#define SPR_403_PBU1 (0x3FD)
  901 +#define SPR_LT (0x3FE)
  902 +#define SPR_THRM3 (0x3FE)
  903 +#define SPR_FPECR (0x3FE)
  904 +#define SPR_403_PBL2 (0x3FE)
  905 +#define SPR_PIR (0x3FF)
  906 +#define SPR_403_PBU2 (0x3FF)
  907 +#define SPR_601_HID15 (0x3FF)
330 908
331 /* Memory access type : 909 /* Memory access type :
332 * may be needed for precise access rights control and precise exceptions. 910 * may be needed for precise access rights control and precise exceptions.
@@ -348,7 +926,7 @@ enum { @@ -348,7 +926,7 @@ enum {
348 /* Exceptions */ 926 /* Exceptions */
349 enum { 927 enum {
350 EXCP_NONE = -1, 928 EXCP_NONE = -1,
351 - /* PPC hardware exceptions : exception vector / 0x100 */ 929 + /* PowerPC hardware exceptions : exception vector / 0x100 */
352 EXCP_RESET = 0x01, /* System reset */ 930 EXCP_RESET = 0x01, /* System reset */
353 EXCP_MACHINE_CHECK = 0x02, /* Machine check exception */ 931 EXCP_MACHINE_CHECK = 0x02, /* Machine check exception */
354 EXCP_DSI = 0x03, /* Impossible memory access */ 932 EXCP_DSI = 0x03, /* Impossible memory access */
target-ppc/exec.h
1 /* 1 /*
2 - * PPC emulation definitions for qemu. 2 + * PowerPC emulation definitions for qemu.
3 * 3 *
4 - * Copyright (c) 2003 Jocelyn Mayer 4 + * Copyright (c) 2003-2005 Jocelyn Mayer
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
@@ -119,15 +119,6 @@ static inline uint32_t rotl (uint32_t i, int n) @@ -119,15 +119,6 @@ static inline uint32_t rotl (uint32_t i, int n)
119 void do_raise_exception_err (uint32_t exception, int error_code); 119 void do_raise_exception_err (uint32_t exception, int error_code);
120 void do_raise_exception (uint32_t exception); 120 void do_raise_exception (uint32_t exception);
121 121
122 -void do_load_cr (void);  
123 -void do_store_cr (uint32_t mask);  
124 -void do_load_xer (void);  
125 -void do_store_xer (void);  
126 -void do_load_msr (void);  
127 -void do_store_msr (void);  
128 -void do_load_fpscr (void);  
129 -void do_store_fpscr (uint32_t mask);  
130 -  
131 void do_sraw(void); 122 void do_sraw(void);
132 123
133 void do_fctiw (void); 124 void do_fctiw (void);
@@ -143,20 +134,9 @@ void do_fcmpo (void); @@ -143,20 +134,9 @@ void do_fcmpo (void);
143 134
144 void do_check_reservation (void); 135 void do_check_reservation (void);
145 void do_icbi (void); 136 void do_icbi (void);
146 -void do_store_sr (uint32_t srnum);  
147 -void do_store_ibat (int ul, int nr);  
148 -void do_store_dbat (int ul, int nr);  
149 void do_tlbia (void); 137 void do_tlbia (void);
150 void do_tlbie (void); 138 void do_tlbie (void);
151 139
152 -void dump_state (void);  
153 -void dump_rfi (void);  
154 -void dump_store_sr (int srnum);  
155 -void dump_store_ibat (int ul, int nr);  
156 -void dump_store_dbat (int ul, int nr);  
157 -void dump_store_tb (int ul);  
158 -void dump_update_tb(uint32_t param);  
159 -  
160 static inline void env_to_regs(void) 140 static inline void env_to_regs(void)
161 { 141 {
162 } 142 }
target-ppc/helper.c
1 /* 1 /*
2 - * PPC emulation helpers for qemu. 2 + * PowerPC emulation helpers for qemu.
3 * 3 *
4 - * Copyright (c) 2003 Jocelyn Mayer 4 + * Copyright (c) 2003-2005 Jocelyn Mayer
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
@@ -26,7 +26,7 @@ @@ -26,7 +26,7 @@
26 //#define ACCURATE_TLB_FLUSH 26 //#define ACCURATE_TLB_FLUSH
27 27
28 /*****************************************************************************/ 28 /*****************************************************************************/
29 -/* PPC MMU emulation */ 29 +/* PowerPC MMU emulation */
30 30
31 /* Perform BAT hit & translation */ 31 /* Perform BAT hit & translation */
32 static int get_bat (CPUState *env, uint32_t *real, int *prot, 32 static int get_bat (CPUState *env, uint32_t *real, int *prot,
@@ -580,7 +580,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -580,7 +580,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
580 if (rw) 580 if (rw)
581 error_code |= EXCP_DSI_STORE; 581 error_code |= EXCP_DSI_STORE;
582 /* Store fault address */ 582 /* Store fault address */
583 - env->spr[DAR] = address; 583 + env->spr[SPR_DAR] = address;
584 } 584 }
585 #if 0 585 #if 0
586 printf("%s: set exception to %d %02x\n", 586 printf("%s: set exception to %d %02x\n",
@@ -593,25 +593,239 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -593,25 +593,239 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
593 return ret; 593 return ret;
594 } 594 }
595 595
596 -uint32_t _load_xer (CPUState *env) 596 +/*****************************************************************************/
  597 +/* BATs management */
  598 +#if !defined(FLUSH_ALL_TLBS)
  599 +static inline void do_invalidate_BAT (CPUPPCState *env,
  600 + target_ulong BATu, target_ulong mask)
  601 +{
  602 + target_ulong base, end, page;
  603 + base = BATu & ~0x0001FFFF;
  604 + end = base + mask + 0x00020000;
  605 +#if defined (DEBUG_BATS)
  606 + if (loglevel != 0)
  607 + fprintf(logfile, "Flush BAT from %08x to %08x (%08x)\n", base, end, mask);
  608 +#endif
  609 + for (page = base; page != end; page += TARGET_PAGE_SIZE)
  610 + tlb_flush_page(env, page);
  611 +#if defined (DEBUG_BATS)
  612 + if (loglevel != 0)
  613 + fprintf(logfile, "Flush done\n");
  614 +#endif
  615 +}
  616 +#endif
  617 +
  618 +static inline void dump_store_bat (CPUPPCState *env, char ID, int ul, int nr,
  619 + target_ulong value)
  620 +{
  621 +#if defined (DEBUG_BATS)
  622 + if (loglevel != 0) {
  623 + fprintf(logfile, "Set %cBAT%d%c to 0x%08lx (0x%08lx)\n",
  624 + ID, nr, ul == 0 ? 'u' : 'l', (unsigned long)value,
  625 + (unsigned long)env->nip);
  626 + }
  627 +#endif
  628 +}
  629 +
  630 +target_ulong do_load_ibatu (CPUPPCState *env, int nr)
  631 +{
  632 + return env->IBAT[0][nr];
  633 +}
  634 +
  635 +target_ulong do_load_ibatl (CPUPPCState *env, int nr)
  636 +{
  637 + return env->IBAT[1][nr];
  638 +}
  639 +
  640 +void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
  641 +{
  642 + target_ulong mask;
  643 +
  644 + dump_store_bat(env, 'I', 0, nr, value);
  645 + if (env->IBAT[0][nr] != value) {
  646 + mask = (value << 15) & 0x0FFE0000UL;
  647 +#if !defined(FLUSH_ALL_TLBS)
  648 + do_invalidate_BAT(env, env->IBAT[0][nr], mask);
  649 +#endif
  650 + /* When storing valid upper BAT, mask BEPI and BRPN
  651 + * and invalidate all TLBs covered by this BAT
  652 + */
  653 + mask = (value << 15) & 0x0FFE0000UL;
  654 + env->IBAT[0][nr] = (value & 0x00001FFFUL) |
  655 + (value & ~0x0001FFFFUL & ~mask);
  656 + env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) |
  657 + (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
  658 +#if !defined(FLUSH_ALL_TLBS)
  659 + do_invalidate_BAT(env, env->IBAT[0][nr], mask);
  660 +#endif
  661 +#if defined(FLUSH_ALL_TLBS)
  662 + tlb_flush(env, 1);
  663 +#endif
  664 + }
  665 +}
  666 +
  667 +void do_store_ibatl (CPUPPCState *env, int nr, target_ulong value)
  668 +{
  669 + dump_store_bat(env, 'I', 1, nr, value);
  670 + env->IBAT[1][nr] = value;
  671 +}
  672 +
  673 +target_ulong do_load_dbatu (CPUPPCState *env, int nr)
  674 +{
  675 + return env->DBAT[0][nr];
  676 +}
  677 +
  678 +target_ulong do_load_dbatl (CPUPPCState *env, int nr)
  679 +{
  680 + return env->DBAT[1][nr];
  681 +}
  682 +
  683 +void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value)
  684 +{
  685 + target_ulong mask;
  686 +
  687 + dump_store_bat(env, 'D', 0, nr, value);
  688 + if (env->DBAT[0][nr] != value) {
  689 + /* When storing valid upper BAT, mask BEPI and BRPN
  690 + * and invalidate all TLBs covered by this BAT
  691 + */
  692 + mask = (value << 15) & 0x0FFE0000UL;
  693 +#if !defined(FLUSH_ALL_TLBS)
  694 + do_invalidate_BAT(env, env->DBAT[0][nr], mask);
  695 +#endif
  696 + mask = (value << 15) & 0x0FFE0000UL;
  697 + env->DBAT[0][nr] = (value & 0x00001FFFUL) |
  698 + (value & ~0x0001FFFFUL & ~mask);
  699 + env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) |
  700 + (env->DBAT[1][nr] & ~0x0001FFFF & ~mask);
  701 +#if !defined(FLUSH_ALL_TLBS)
  702 + do_invalidate_BAT(env, env->DBAT[0][nr], mask);
  703 +#else
  704 + tlb_flush(env, 1);
  705 +#endif
  706 + }
  707 +}
  708 +
  709 +void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
  710 +{
  711 + dump_store_bat(env, 'D', 1, nr, value);
  712 + env->DBAT[1][nr] = value;
  713 +}
  714 +
  715 +static inline void invalidate_all_tlbs (CPUPPCState *env)
  716 +{
  717 + /* XXX: this needs to be completed for sotware driven TLB support */
  718 + tlb_flush(env, 1);
  719 +}
  720 +
  721 +/*****************************************************************************/
  722 +/* Special registers manipulation */
  723 +target_ulong do_load_nip (CPUPPCState *env)
  724 +{
  725 + return env->nip;
  726 +}
  727 +
  728 +void do_store_nip (CPUPPCState *env, target_ulong value)
  729 +{
  730 + env->nip = value;
  731 +}
  732 +
  733 +target_ulong do_load_sdr1 (CPUPPCState *env)
  734 +{
  735 + return env->sdr1;
  736 +}
  737 +
  738 +void do_store_sdr1 (CPUPPCState *env, target_ulong value)
  739 +{
  740 +#if defined (DEBUG_MMU)
  741 + if (loglevel != 0) {
  742 + fprintf(logfile, "%s: 0x%08lx\n", __func__, (unsigned long)value);
  743 + }
  744 +#endif
  745 + if (env->sdr1 != value) {
  746 + env->sdr1 = value;
  747 + invalidate_all_tlbs(env);
  748 + }
  749 +}
  750 +
  751 +target_ulong do_load_sr (CPUPPCState *env, int srnum)
  752 +{
  753 + return env->sr[srnum];
  754 +}
  755 +
  756 +void do_store_sr (CPUPPCState *env, int srnum, target_ulong value)
  757 +{
  758 +#if defined (DEBUG_MMU)
  759 + if (loglevel != 0) {
  760 + fprintf(logfile, "%s: reg=%d 0x%08lx %08lx\n",
  761 + __func__, srnum, (unsigned long)value, env->sr[srnum]);
  762 + }
  763 +#endif
  764 + if (env->sr[srnum] != value) {
  765 + env->sr[srnum] = value;
  766 +#if !defined(FLUSH_ALL_TLBS) && 0
  767 + {
  768 + target_ulong page, end;
  769 + /* Invalidate 256 MB of virtual memory */
  770 + page = (16 << 20) * srnum;
  771 + end = page + (16 << 20);
  772 + for (; page != end; page += TARGET_PAGE_SIZE)
  773 + tlb_flush_page(env, page);
  774 + }
  775 +#else
  776 + invalidate_all_tlbs(env);
  777 +#endif
  778 + }
  779 +}
  780 +
  781 +uint32_t do_load_cr (CPUPPCState *env)
  782 +{
  783 + return (env->crf[0] << 28) |
  784 + (env->crf[1] << 24) |
  785 + (env->crf[2] << 20) |
  786 + (env->crf[3] << 16) |
  787 + (env->crf[4] << 12) |
  788 + (env->crf[5] << 8) |
  789 + (env->crf[6] << 4) |
  790 + (env->crf[7] << 0);
  791 +}
  792 +
  793 +void do_store_cr (CPUPPCState *env, uint32_t value, uint32_t mask)
  794 +{
  795 + int i, sh;
  796 +
  797 + for (i = 0, sh = 7; i < 8; i++, sh --) {
  798 + if (mask & (1 << sh))
  799 + env->crf[i] = (value >> (sh * 4)) & 0xFUL;
  800 + }
  801 +}
  802 +
  803 +uint32_t do_load_xer (CPUPPCState *env)
597 { 804 {
598 return (xer_so << XER_SO) | 805 return (xer_so << XER_SO) |
599 (xer_ov << XER_OV) | 806 (xer_ov << XER_OV) |
600 (xer_ca << XER_CA) | 807 (xer_ca << XER_CA) |
601 - (xer_bc << XER_BC); 808 + (xer_bc << XER_BC) |
  809 + (xer_cmp << XER_CMP);
602 } 810 }
603 811
604 -void _store_xer (CPUState *env, uint32_t value) 812 +void do_store_xer (CPUPPCState *env, uint32_t value)
605 { 813 {
606 xer_so = (value >> XER_SO) & 0x01; 814 xer_so = (value >> XER_SO) & 0x01;
607 xer_ov = (value >> XER_OV) & 0x01; 815 xer_ov = (value >> XER_OV) & 0x01;
608 xer_ca = (value >> XER_CA) & 0x01; 816 xer_ca = (value >> XER_CA) & 0x01;
609 - xer_bc = (value >> XER_BC) & 0x3f; 817 + xer_cmp = (value >> XER_CMP) & 0xFF;
  818 + xer_bc = (value >> XER_BC) & 0x3F;
610 } 819 }
611 820
612 -uint32_t _load_msr (CPUState *env) 821 +target_ulong do_load_msr (CPUPPCState *env)
613 { 822 {
614 - return (msr_pow << MSR_POW) | 823 + return (msr_vr << MSR_VR) |
  824 + (msr_ap << MSR_AP) |
  825 + (msr_sa << MSR_SA) |
  826 + (msr_key << MSR_KEY) |
  827 + (msr_pow << MSR_POW) |
  828 + (msr_tlb << MSR_TLB) |
615 (msr_ile << MSR_ILE) | 829 (msr_ile << MSR_ILE) |
616 (msr_ee << MSR_EE) | 830 (msr_ee << MSR_EE) |
617 (msr_pr << MSR_PR) | 831 (msr_pr << MSR_PR) |
@@ -621,41 +835,141 @@ uint32_t _load_msr (CPUState *env) @@ -621,41 +835,141 @@ uint32_t _load_msr (CPUState *env)
621 (msr_se << MSR_SE) | 835 (msr_se << MSR_SE) |
622 (msr_be << MSR_BE) | 836 (msr_be << MSR_BE) |
623 (msr_fe1 << MSR_FE1) | 837 (msr_fe1 << MSR_FE1) |
  838 + (msr_al << MSR_AL) |
624 (msr_ip << MSR_IP) | 839 (msr_ip << MSR_IP) |
625 (msr_ir << MSR_IR) | 840 (msr_ir << MSR_IR) |
626 (msr_dr << MSR_DR) | 841 (msr_dr << MSR_DR) |
  842 + (msr_pe << MSR_PE) |
  843 + (msr_px << MSR_PX) |
627 (msr_ri << MSR_RI) | 844 (msr_ri << MSR_RI) |
628 (msr_le << MSR_LE); 845 (msr_le << MSR_LE);
629 } 846 }
630 847
631 -void _store_msr (CPUState *env, uint32_t value) 848 +void do_compute_hflags (CPUPPCState *env)
632 { 849 {
633 -#ifdef ACCURATE_TLB_FLUSH  
634 - if (((value >> MSR_IR) & 0x01) != msr_ir ||  
635 - ((value >> MSR_DR) & 0x01) != msr_dr) 850 + /* Compute current hflags */
  851 + env->hflags = (msr_pr << MSR_PR) | (msr_le << MSR_LE) |
  852 + (msr_fp << MSR_FP) | (msr_fe0 << MSR_FE0) | (msr_fe1 << MSR_FE1) |
  853 + (msr_vr << MSR_VR) | (msr_ap << MSR_AP) | (msr_sa << MSR_SA) |
  854 + (msr_se << MSR_SE) | (msr_be << MSR_BE);
  855 +}
  856 +
  857 +void do_store_msr (CPUPPCState *env, target_ulong value)
636 { 858 {
637 - /* Flush all tlb when changing translation mode or privilege level */ 859 + value &= env->msr_mask;
  860 + if (((value >> MSR_IR) & 1) != msr_ir ||
  861 + ((value >> MSR_DR) & 1) != msr_dr) {
  862 + /* Flush all tlb when changing translation mode
  863 + * When using software driven TLB, we may also need to reload
  864 + * all defined TLBs
  865 + */
638 tlb_flush(env, 1); 866 tlb_flush(env, 1);
  867 + env->interrupt_request |= CPU_INTERRUPT_EXITTB;
639 } 868 }
  869 +#if 0
  870 + if (loglevel != 0) {
  871 + fprintf(logfile, "%s: T0 %08lx\n", __func__, value);
  872 + }
  873 +#endif
  874 + msr_vr = (value >> MSR_VR) & 1;
  875 + msr_ap = (value >> MSR_AP) & 1;
  876 + msr_sa = (value >> MSR_SA) & 1;
  877 + msr_key = (value >> MSR_KEY) & 1;
  878 + msr_pow = (value >> MSR_POW) & 1;
  879 + msr_tlb = (value >> MSR_TLB) & 1;
  880 + msr_ile = (value >> MSR_ILE) & 1;
  881 + msr_ee = (value >> MSR_EE) & 1;
  882 + msr_pr = (value >> MSR_PR) & 1;
  883 + msr_fp = (value >> MSR_FP) & 1;
  884 + msr_me = (value >> MSR_ME) & 1;
  885 + msr_fe0 = (value >> MSR_FE0) & 1;
  886 + msr_se = (value >> MSR_SE) & 1;
  887 + msr_be = (value >> MSR_BE) & 1;
  888 + msr_fe1 = (value >> MSR_FE1) & 1;
  889 + msr_al = (value >> MSR_AL) & 1;
  890 + msr_ip = (value >> MSR_IP) & 1;
  891 + msr_ir = (value >> MSR_IR) & 1;
  892 + msr_dr = (value >> MSR_DR) & 1;
  893 + msr_pe = (value >> MSR_PE) & 1;
  894 + msr_px = (value >> MSR_PX) & 1;
  895 + msr_ri = (value >> MSR_RI) & 1;
  896 + msr_le = (value >> MSR_LE) & 1;
  897 + do_compute_hflags(env);
  898 +}
  899 +
  900 +float64 do_load_fpscr (CPUPPCState *env)
  901 +{
  902 + /* The 32 MSB of the target fpr are undefined.
  903 + * They'll be zero...
  904 + */
  905 + union {
  906 + float64 d;
  907 + struct {
  908 + uint32_t u[2];
  909 + } s;
  910 + } u;
  911 + int i;
  912 +
  913 +#ifdef WORDS_BIGENDIAN
  914 +#define WORD0 0
  915 +#define WORD1 1
  916 +#else
  917 +#define WORD0 1
  918 +#define WORD1 0
640 #endif 919 #endif
641 - msr_pow = (value >> MSR_POW) & 0x03;  
642 - msr_ile = (value >> MSR_ILE) & 0x01;  
643 - msr_ee = (value >> MSR_EE) & 0x01;  
644 - msr_pr = (value >> MSR_PR) & 0x01;  
645 - msr_fp = (value >> MSR_FP) & 0x01;  
646 - msr_me = (value >> MSR_ME) & 0x01;  
647 - msr_fe0 = (value >> MSR_FE0) & 0x01;  
648 - msr_se = (value >> MSR_SE) & 0x01;  
649 - msr_be = (value >> MSR_BE) & 0x01;  
650 - msr_fe1 = (value >> MSR_FE1) & 0x01;  
651 - msr_ip = (value >> MSR_IP) & 0x01;  
652 - msr_ir = (value >> MSR_IR) & 0x01;  
653 - msr_dr = (value >> MSR_DR) & 0x01;  
654 - msr_ri = (value >> MSR_RI) & 0x01;  
655 - msr_le = (value >> MSR_LE) & 0x01;  
656 - /* XXX: should enter PM state if msr_pow has been set */ 920 + u.s.u[WORD0] = 0;
  921 + u.s.u[WORD1] = 0;
  922 + for (i = 0; i < 8; i++)
  923 + u.s.u[WORD1] |= env->fpscr[i] << (4 * i);
  924 + return u.d;
657 } 925 }
658 926
  927 +void do_store_fpscr (CPUPPCState *env, float64 f, uint32_t mask)
  928 +{
  929 + /*
  930 + * We use only the 32 LSB of the incoming fpr
  931 + */
  932 + union {
  933 + double d;
  934 + struct {
  935 + uint32_t u[2];
  936 + } s;
  937 + } u;
  938 + int i, rnd_type;
  939 +
  940 + u.d = f;
  941 + if (mask & 0x80)
  942 + env->fpscr[0] = (env->fpscr[0] & 0x9) | ((u.s.u[WORD1] >> 28) & ~0x9);
  943 + for (i = 1; i < 7; i++) {
  944 + if (mask & (1 << (7 - i)))
  945 + env->fpscr[i] = (u.s.u[WORD1] >> (4 * (7 - i))) & 0xF;
  946 + }
  947 + /* TODO: update FEX & VX */
  948 + /* Set rounding mode */
  949 + switch (env->fpscr[0] & 0x3) {
  950 + case 0:
  951 + /* Best approximation (round to nearest) */
  952 + rnd_type = float_round_nearest_even;
  953 + break;
  954 + case 1:
  955 + /* Smaller magnitude (round toward zero) */
  956 + rnd_type = float_round_to_zero;
  957 + break;
  958 + case 2:
  959 + /* Round toward +infinite */
  960 + rnd_type = float_round_up;
  961 + break;
  962 + default:
  963 + case 3:
  964 + /* Round toward -infinite */
  965 + rnd_type = float_round_down;
  966 + break;
  967 + }
  968 + set_float_rounding_mode(rnd_type, &env->fp_status);
  969 +}
  970 +
  971 +/*****************************************************************************/
  972 +/* Exception processing */
659 #if defined (CONFIG_USER_ONLY) 973 #if defined (CONFIG_USER_ONLY)
660 void do_interrupt (CPUState *env) 974 void do_interrupt (CPUState *env)
661 { 975 {
@@ -675,7 +989,7 @@ void do_interrupt (CPUState *env) @@ -675,7 +989,7 @@ void do_interrupt (CPUState *env)
675 int excp; 989 int excp;
676 990
677 excp = env->exception_index; 991 excp = env->exception_index;
678 - msr = _load_msr(env); 992 + msr = do_load_msr(env);
679 #if defined (DEBUG_EXCEPTIONS) 993 #if defined (DEBUG_EXCEPTIONS)
680 if ((excp == EXCP_PROGRAM || excp == EXCP_DSI) && msr_pr == 1) 994 if ((excp == EXCP_PROGRAM || excp == EXCP_DSI) && msr_pr == 1)
681 { 995 {
@@ -715,29 +1029,29 @@ void do_interrupt (CPUState *env) @@ -715,29 +1029,29 @@ void do_interrupt (CPUState *env)
715 * when the fault has been detected 1029 * when the fault has been detected
716 */ 1030 */
717 msr &= ~0xFFFF0000; 1031 msr &= ~0xFFFF0000;
718 - env->spr[DSISR] = 0; 1032 + env->spr[SPR_DSISR] = 0;
719 if ((env->error_code & 0x0f) == EXCP_DSI_TRANSLATE) 1033 if ((env->error_code & 0x0f) == EXCP_DSI_TRANSLATE)
720 - env->spr[DSISR] |= 0x40000000; 1034 + env->spr[SPR_DSISR] |= 0x40000000;
721 else if ((env->error_code & 0x0f) == EXCP_DSI_PROT) 1035 else if ((env->error_code & 0x0f) == EXCP_DSI_PROT)
722 - env->spr[DSISR] |= 0x08000000; 1036 + env->spr[SPR_DSISR] |= 0x08000000;
723 else if ((env->error_code & 0x0f) == EXCP_DSI_NOTSUP) { 1037 else if ((env->error_code & 0x0f) == EXCP_DSI_NOTSUP) {
724 - env->spr[DSISR] |= 0x80000000; 1038 + env->spr[SPR_DSISR] |= 0x80000000;
725 if (env->error_code & EXCP_DSI_DIRECT) 1039 if (env->error_code & EXCP_DSI_DIRECT)
726 - env->spr[DSISR] |= 0x04000000; 1040 + env->spr[SPR_DSISR] |= 0x04000000;
727 } 1041 }
728 if (env->error_code & EXCP_DSI_STORE) 1042 if (env->error_code & EXCP_DSI_STORE)
729 - env->spr[DSISR] |= 0x02000000; 1043 + env->spr[SPR_DSISR] |= 0x02000000;
730 if ((env->error_code & 0xF) == EXCP_DSI_DABR) 1044 if ((env->error_code & 0xF) == EXCP_DSI_DABR)
731 - env->spr[DSISR] |= 0x00400000; 1045 + env->spr[SPR_DSISR] |= 0x00400000;
732 if (env->error_code & EXCP_DSI_ECXW) 1046 if (env->error_code & EXCP_DSI_ECXW)
733 - env->spr[DSISR] |= 0x00100000; 1047 + env->spr[SPR_DSISR] |= 0x00100000;
734 #if defined (DEBUG_EXCEPTIONS) 1048 #if defined (DEBUG_EXCEPTIONS)
735 if (loglevel) { 1049 if (loglevel) {
736 fprintf(logfile, "DSI exception: DSISR=0x%08x, DAR=0x%08x\n", 1050 fprintf(logfile, "DSI exception: DSISR=0x%08x, DAR=0x%08x\n",
737 - env->spr[DSISR], env->spr[DAR]); 1051 + env->spr[SPR_DSISR], env->spr[SPR_DAR]);
738 } else { 1052 } else {
739 printf("DSI exception: DSISR=0x%08x, DAR=0x%08x nip=0x%08x\n", 1053 printf("DSI exception: DSISR=0x%08x, DAR=0x%08x nip=0x%08x\n",
740 - env->spr[DSISR], env->spr[DAR], env->nip); 1054 + env->spr[SPR_DSISR], env->spr[SPR_DAR], env->nip);
741 } 1055 }
742 #endif 1056 #endif
743 goto store_next; 1057 goto store_next;
@@ -777,7 +1091,7 @@ void do_interrupt (CPUState *env) @@ -777,7 +1091,7 @@ void do_interrupt (CPUState *env)
777 case EXCP_ALIGN: 1091 case EXCP_ALIGN:
778 /* Store exception cause */ 1092 /* Store exception cause */
779 /* Get rS/rD and rA from faulting opcode */ 1093 /* Get rS/rD and rA from faulting opcode */
780 - env->spr[DSISR] |= 1094 + env->spr[SPR_DSISR] |=
781 (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16; 1095 (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
782 /* data location address has been stored 1096 /* data location address has been stored
783 * when the fault has been detected 1097 * when the fault has been detected
@@ -858,14 +1172,14 @@ void do_interrupt (CPUState *env) @@ -858,14 +1172,14 @@ void do_interrupt (CPUState *env)
858 return; 1172 return;
859 store_current: 1173 store_current:
860 /* SRR0 is set to current instruction */ 1174 /* SRR0 is set to current instruction */
861 - env->spr[SRR0] = (uint32_t)env->nip - 4; 1175 + env->spr[SPR_SRR0] = (uint32_t)env->nip - 4;
862 break; 1176 break;
863 store_next: 1177 store_next:
864 /* SRR0 is set to next instruction */ 1178 /* SRR0 is set to next instruction */
865 - env->spr[SRR0] = (uint32_t)env->nip; 1179 + env->spr[SPR_SRR0] = (uint32_t)env->nip;
866 break; 1180 break;
867 } 1181 }
868 - env->spr[SRR1] = msr; 1182 + env->spr[SPR_SRR1] = msr;
869 /* reload MSR with correct bits */ 1183 /* reload MSR with correct bits */
870 msr_pow = 0; 1184 msr_pow = 0;
871 msr_ee = 0; 1185 msr_ee = 0;
@@ -879,6 +1193,7 @@ void do_interrupt (CPUState *env) @@ -879,6 +1193,7 @@ void do_interrupt (CPUState *env)
879 msr_dr = 0; 1193 msr_dr = 0;
880 msr_ri = 0; 1194 msr_ri = 0;
881 msr_le = msr_ile; 1195 msr_le = msr_ile;
  1196 + do_compute_hflags(env);
882 /* Jump to handler */ 1197 /* Jump to handler */
883 env->nip = excp << 8; 1198 env->nip = excp << 8;
884 env->exception_index = EXCP_NONE; 1199 env->exception_index = EXCP_NONE;
target-ppc/op.c
1 /* 1 /*
2 - * PPC emulation micro-operations for qemu. 2 + * PowerPC emulation micro-operations for qemu.
3 * 3 *
4 - * Copyright (c) 2003 Jocelyn Mayer 4 + * Copyright (c) 2003-2005 Jocelyn Mayer
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
@@ -130,7 +130,7 @@ @@ -130,7 +130,7 @@
130 #define REG 31 130 #define REG 31
131 #include "op_template.h" 131 #include "op_template.h"
132 132
133 -/* PPC state maintenance operations */ 133 +/* PowerPC state maintenance operations */
134 /* set_Rc0 */ 134 /* set_Rc0 */
135 PPC_OP(set_Rc0) 135 PPC_OP(set_Rc0)
136 { 136 {
@@ -223,7 +223,7 @@ PPC_OP(load_srin) @@ -223,7 +223,7 @@ PPC_OP(load_srin)
223 223
224 PPC_OP(store_srin) 224 PPC_OP(store_srin)
225 { 225 {
226 - do_store_sr(T1 >> 28); 226 + do_store_sr(env, ((uint32_t)T1 >> 28), T0);
227 RETURN(); 227 RETURN();
228 } 228 }
229 229
@@ -235,7 +235,7 @@ PPC_OP(load_sdr1) @@ -235,7 +235,7 @@ PPC_OP(load_sdr1)
235 235
236 PPC_OP(store_sdr1) 236 PPC_OP(store_sdr1)
237 { 237 {
238 - regs->sdr1 = T0; 238 + do_store_sdr1(env, T0);
239 RETURN(); 239 RETURN();
240 } 240 }
241 241
@@ -247,13 +247,13 @@ PPC_OP(exit_tb) @@ -247,13 +247,13 @@ PPC_OP(exit_tb)
247 /* Load/store special registers */ 247 /* Load/store special registers */
248 PPC_OP(load_cr) 248 PPC_OP(load_cr)
249 { 249 {
250 - do_load_cr(); 250 + T0 = do_load_cr(env);
251 RETURN(); 251 RETURN();
252 } 252 }
253 253
254 PPC_OP(store_cr) 254 PPC_OP(store_cr)
255 { 255 {
256 - do_store_cr(PARAM(1)); 256 + do_store_cr(env, T0, PARAM(1));
257 RETURN(); 257 RETURN();
258 } 258 }
259 259
@@ -279,25 +279,25 @@ PPC_OP(load_xer_bc) @@ -279,25 +279,25 @@ PPC_OP(load_xer_bc)
279 279
280 PPC_OP(load_xer) 280 PPC_OP(load_xer)
281 { 281 {
282 - do_load_xer(); 282 + T0 = do_load_xer(env);
283 RETURN(); 283 RETURN();
284 } 284 }
285 285
286 PPC_OP(store_xer) 286 PPC_OP(store_xer)
287 { 287 {
288 - do_store_xer(); 288 + do_store_xer(env, T0);
289 RETURN(); 289 RETURN();
290 } 290 }
291 291
292 PPC_OP(load_msr) 292 PPC_OP(load_msr)
293 { 293 {
294 - do_load_msr(); 294 + T0 = do_load_msr(env);
295 RETURN(); 295 RETURN();
296 } 296 }
297 297
298 PPC_OP(store_msr) 298 PPC_OP(store_msr)
299 { 299 {
300 - do_store_msr(); 300 + do_store_msr(env, T0);
301 RETURN(); 301 RETURN();
302 } 302 }
303 303
@@ -378,9 +378,20 @@ PPC_OP(load_ibat) @@ -378,9 +378,20 @@ PPC_OP(load_ibat)
378 T0 = regs->IBAT[PARAM(1)][PARAM(2)]; 378 T0 = regs->IBAT[PARAM(1)][PARAM(2)];
379 } 379 }
380 380
381 -PPC_OP(store_ibat) 381 +void op_store_ibatu (void)
382 { 382 {
383 - do_store_ibat(PARAM(1), PARAM(2)); 383 + do_store_ibatu(env, PARAM1, T0);
  384 + RETURN();
  385 +}
  386 +
  387 +void op_store_ibatl (void)
  388 +{
  389 +#if 1
  390 + env->IBAT[1][PARAM1] = T0;
  391 +#else
  392 + do_store_ibatl(env, PARAM1, T0);
  393 +#endif
  394 + RETURN();
384 } 395 }
385 396
386 PPC_OP(load_dbat) 397 PPC_OP(load_dbat)
@@ -388,21 +399,32 @@ PPC_OP(load_dbat) @@ -388,21 +399,32 @@ PPC_OP(load_dbat)
388 T0 = regs->DBAT[PARAM(1)][PARAM(2)]; 399 T0 = regs->DBAT[PARAM(1)][PARAM(2)];
389 } 400 }
390 401
391 -PPC_OP(store_dbat) 402 +void op_store_dbatu (void)
  403 +{
  404 + do_store_dbatu(env, PARAM1, T0);
  405 + RETURN();
  406 +}
  407 +
  408 +void op_store_dbatl (void)
392 { 409 {
393 - do_store_dbat(PARAM(1), PARAM(2)); 410 +#if 1
  411 + env->DBAT[1][PARAM1] = T0;
  412 +#else
  413 + do_store_dbatl(env, PARAM1, T0);
  414 +#endif
  415 + RETURN();
394 } 416 }
395 417
396 /* FPSCR */ 418 /* FPSCR */
397 PPC_OP(load_fpscr) 419 PPC_OP(load_fpscr)
398 { 420 {
399 - do_load_fpscr(); 421 + FT0 = do_load_fpscr(env);
400 RETURN(); 422 RETURN();
401 } 423 }
402 424
403 PPC_OP(store_fpscr) 425 PPC_OP(store_fpscr)
404 { 426 {
405 - do_store_fpscr(PARAM(1)); 427 + do_store_fpscr(env, FT0, PARAM1);
406 RETURN(); 428 RETURN();
407 } 429 }
408 430
@@ -1362,17 +1384,13 @@ PPC_OP(check_reservation) @@ -1362,17 +1384,13 @@ PPC_OP(check_reservation)
1362 /* Return from interrupt */ 1384 /* Return from interrupt */
1363 PPC_OP(rfi) 1385 PPC_OP(rfi)
1364 { 1386 {
1365 - regs->nip = regs->spr[SRR0] & ~0x00000003; 1387 + regs->nip = regs->spr[SPR_SRR0] & ~0x00000003;
1366 #if 1 // TRY 1388 #if 1 // TRY
1367 - T0 = regs->spr[SRR1] & ~0xFFF00000; 1389 + T0 = regs->spr[SPR_SRR1] & ~0xFFF00000;
1368 #else 1390 #else
1369 - T0 = regs->spr[SRR1] & ~0xFFFF0000;  
1370 -#endif  
1371 - do_store_msr();  
1372 -#if defined (DEBUG_OP)  
1373 - dump_rfi(); 1391 + T0 = regs->spr[SPR_SRR1] & ~0xFFFF0000;
1374 #endif 1392 #endif
1375 - // do_tlbia(); 1393 + do_store_msr(env, T0);
1376 do_raise_exception(EXCP_RFI); 1394 do_raise_exception(EXCP_RFI);
1377 RETURN(); 1395 RETURN();
1378 } 1396 }
@@ -1420,3 +1438,9 @@ PPC_OP(tlbie) @@ -1420,3 +1438,9 @@ PPC_OP(tlbie)
1420 do_tlbie(); 1438 do_tlbie();
1421 RETURN(); 1439 RETURN();
1422 } 1440 }
  1441 +
  1442 +void op_store_pir (void)
  1443 +{
  1444 + env->spr[SPR_PIR] = T0 & 0x0000000FUL;
  1445 + RETURN();
  1446 +}
target-ppc/op_helper.c
1 /* 1 /*
2 - * PPC emulation helpers for qemu. 2 + * PowerPC emulation helpers for qemu.
3 * 3 *
4 - * Copyright (c) 2003 Jocelyn Mayer 4 + * Copyright (c) 2003-2005 Jocelyn Mayer
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
@@ -67,91 +67,6 @@ void do_raise_exception (uint32_t exception) @@ -67,91 +67,6 @@ void do_raise_exception (uint32_t exception)
67 67
68 /*****************************************************************************/ 68 /*****************************************************************************/
69 /* Helpers for "fat" micro operations */ 69 /* Helpers for "fat" micro operations */
70 -/* Special registers load and store */  
71 -void do_load_cr (void)  
72 -{  
73 - T0 = (env->crf[0] << 28) |  
74 - (env->crf[1] << 24) |  
75 - (env->crf[2] << 20) |  
76 - (env->crf[3] << 16) |  
77 - (env->crf[4] << 12) |  
78 - (env->crf[5] << 8) |  
79 - (env->crf[6] << 4) |  
80 - (env->crf[7] << 0);  
81 -}  
82 -  
83 -void do_store_cr (uint32_t mask)  
84 -{  
85 - int i, sh;  
86 -  
87 - for (i = 0, sh = 7; i < 8; i++, sh --) {  
88 - if (mask & (1 << sh))  
89 - env->crf[i] = (T0 >> (sh * 4)) & 0xF;  
90 - }  
91 -}  
92 -  
93 -void do_load_xer (void)  
94 -{  
95 - T0 = (xer_so << XER_SO) |  
96 - (xer_ov << XER_OV) |  
97 - (xer_ca << XER_CA) |  
98 - (xer_bc << XER_BC);  
99 -}  
100 -  
101 -void do_store_xer (void)  
102 -{  
103 - xer_so = (T0 >> XER_SO) & 0x01;  
104 - xer_ov = (T0 >> XER_OV) & 0x01;  
105 - xer_ca = (T0 >> XER_CA) & 0x01;  
106 - xer_bc = (T0 >> XER_BC) & 0x3f;  
107 -}  
108 -  
109 -void do_load_msr (void)  
110 -{  
111 - T0 = (msr_pow << MSR_POW) |  
112 - (msr_ile << MSR_ILE) |  
113 - (msr_ee << MSR_EE) |  
114 - (msr_pr << MSR_PR) |  
115 - (msr_fp << MSR_FP) |  
116 - (msr_me << MSR_ME) |  
117 - (msr_fe0 << MSR_FE0) |  
118 - (msr_se << MSR_SE) |  
119 - (msr_be << MSR_BE) |  
120 - (msr_fe1 << MSR_FE1) |  
121 - (msr_ip << MSR_IP) |  
122 - (msr_ir << MSR_IR) |  
123 - (msr_dr << MSR_DR) |  
124 - (msr_ri << MSR_RI) |  
125 - (msr_le << MSR_LE);  
126 -}  
127 -  
128 -void do_store_msr (void)  
129 -{  
130 -#if 1 // TRY  
131 - if (((T0 >> MSR_IR) & 0x01) != msr_ir ||  
132 - ((T0 >> MSR_DR) & 0x01) != msr_dr ||  
133 - ((T0 >> MSR_PR) & 0x01) != msr_pr)  
134 - {  
135 - do_tlbia();  
136 - }  
137 -#endif  
138 - msr_pow = (T0 >> MSR_POW) & 0x03;  
139 - msr_ile = (T0 >> MSR_ILE) & 0x01;  
140 - msr_ee = (T0 >> MSR_EE) & 0x01;  
141 - msr_pr = (T0 >> MSR_PR) & 0x01;  
142 - msr_fp = (T0 >> MSR_FP) & 0x01;  
143 - msr_me = (T0 >> MSR_ME) & 0x01;  
144 - msr_fe0 = (T0 >> MSR_FE0) & 0x01;  
145 - msr_se = (T0 >> MSR_SE) & 0x01;  
146 - msr_be = (T0 >> MSR_BE) & 0x01;  
147 - msr_fe1 = (T0 >> MSR_FE1) & 0x01;  
148 - msr_ip = (T0 >> MSR_IP) & 0x01;  
149 - msr_ir = (T0 >> MSR_IR) & 0x01;  
150 - msr_dr = (T0 >> MSR_DR) & 0x01;  
151 - msr_ri = (T0 >> MSR_RI) & 0x01;  
152 - msr_le = (T0 >> MSR_LE) & 0x01;  
153 -}  
154 -  
155 /* shift right arithmetic helper */ 70 /* shift right arithmetic helper */
156 void do_sraw (void) 71 void do_sraw (void)
157 { 72 {
@@ -175,77 +90,6 @@ void do_sraw (void) @@ -175,77 +90,6 @@ void do_sraw (void)
175 } 90 }
176 91
177 /* Floating point operations helpers */ 92 /* Floating point operations helpers */
178 -void do_load_fpscr (void)  
179 -{  
180 - /* The 32 MSB of the target fpr are undefined.  
181 - * They'll be zero...  
182 - */  
183 - union {  
184 - double d;  
185 - struct {  
186 - uint32_t u[2];  
187 - } s;  
188 - } u;  
189 - int i;  
190 -  
191 -#ifdef WORDS_BIGENDIAN  
192 -#define WORD0 0  
193 -#define WORD1 1  
194 -#else  
195 -#define WORD0 1  
196 -#define WORD1 0  
197 -#endif  
198 - u.s.u[WORD0] = 0;  
199 - u.s.u[WORD1] = 0;  
200 - for (i = 0; i < 8; i++)  
201 - u.s.u[WORD1] |= env->fpscr[i] << (4 * i);  
202 - FT0 = u.d;  
203 -}  
204 -  
205 -void do_store_fpscr (uint32_t mask)  
206 -{  
207 - /*  
208 - * We use only the 32 LSB of the incoming fpr  
209 - */  
210 - union {  
211 - double d;  
212 - struct {  
213 - uint32_t u[2];  
214 - } s;  
215 - } u;  
216 - int i, rnd_type;  
217 -  
218 - u.d = FT0;  
219 - if (mask & 0x80)  
220 - env->fpscr[0] = (env->fpscr[0] & 0x9) | ((u.s.u[WORD1] >> 28) & ~0x9);  
221 - for (i = 1; i < 7; i++) {  
222 - if (mask & (1 << (7 - i)))  
223 - env->fpscr[i] = (u.s.u[WORD1] >> (4 * (7 - i))) & 0xF;  
224 - }  
225 - /* TODO: update FEX & VX */  
226 - /* Set rounding mode */  
227 - switch (env->fpscr[0] & 0x3) {  
228 - case 0:  
229 - /* Best approximation (round to nearest) */  
230 - rnd_type = float_round_nearest_even;  
231 - break;  
232 - case 1:  
233 - /* Smaller magnitude (round toward zero) */  
234 - rnd_type = float_round_to_zero;  
235 - break;  
236 - case 2:  
237 - /* Round toward +infinite */  
238 - rnd_type = float_round_up;  
239 - break;  
240 - default:  
241 - case 3:  
242 - /* Round toward -infinite */  
243 - rnd_type = float_round_down;  
244 - break;  
245 - }  
246 - set_float_rounding_mode(rnd_type, &env->fp_status);  
247 -}  
248 -  
249 void do_fctiw (void) 93 void do_fctiw (void)
250 { 94 {
251 union { 95 union {
@@ -254,7 +98,7 @@ void do_fctiw (void) @@ -254,7 +98,7 @@ void do_fctiw (void)
254 } p; 98 } p;
255 99
256 /* XXX: higher bits are not supposed to be significant. 100 /* XXX: higher bits are not supposed to be significant.
257 - * to make tests easier, return the same as a real PPC 750 (aka G3) 101 + * to make tests easier, return the same as a real PowerPC 750 (aka G3)
258 */ 102 */
259 p.i = float64_to_int32(FT0, &env->fp_status); 103 p.i = float64_to_int32(FT0, &env->fp_status);
260 p.i |= 0xFFF80000ULL << 32; 104 p.i |= 0xFFF80000ULL << 32;
@@ -269,7 +113,7 @@ void do_fctiwz (void) @@ -269,7 +113,7 @@ void do_fctiwz (void)
269 } p; 113 } p;
270 114
271 /* XXX: higher bits are not supposed to be significant. 115 /* XXX: higher bits are not supposed to be significant.
272 - * to make tests easier, return the same as a real PPC 750 (aka G3) 116 + * to make tests easier, return the same as a real PowerPC 750 (aka G3)
273 */ 117 */
274 p.i = float64_to_int32_round_to_zero(FT0, &env->fp_status); 118 p.i = float64_to_int32_round_to_zero(FT0, &env->fp_status);
275 p.i |= 0xFFF80000ULL << 32; 119 p.i |= 0xFFF80000ULL << 32;
@@ -455,116 +299,3 @@ void do_tlbie (void) @@ -455,116 +299,3 @@ void do_tlbie (void)
455 tlb_flush_page(env, T0); 299 tlb_flush_page(env, T0);
456 } 300 }
457 301
458 -void do_store_sr (uint32_t srnum)  
459 -{  
460 -#if defined (DEBUG_OP)  
461 - dump_store_sr(srnum);  
462 -#endif  
463 -#if 0 // TRY  
464 - {  
465 - uint32_t base, page;  
466 -  
467 - base = srnum << 28;  
468 - for (page = base; page != base + 0x100000000; page += 0x1000)  
469 - tlb_flush_page(env, page);  
470 - }  
471 -#else  
472 - tlb_flush(env, 1);  
473 -#endif  
474 - env->sr[srnum] = T0;  
475 -}  
476 -  
477 -/* For BATs, we may not invalidate any TLBs if the change is only on  
478 - * protection bits for user mode.  
479 - */  
480 -void do_store_ibat (int ul, int nr)  
481 -{  
482 -#if defined (DEBUG_OP)  
483 - dump_store_ibat(ul, nr);  
484 -#endif  
485 -#if 0 // TRY  
486 - {  
487 - uint32_t base, length, page;  
488 -  
489 - base = env->IBAT[0][nr];  
490 - length = (((base >> 2) & 0x000007FF) + 1) << 17;  
491 - base &= 0xFFFC0000;  
492 - for (page = base; page != base + length; page += 0x1000)  
493 - tlb_flush_page(env, page);  
494 - }  
495 -#else  
496 - tlb_flush(env, 1);  
497 -#endif  
498 - env->IBAT[ul][nr] = T0;  
499 -}  
500 -  
501 -void do_store_dbat (int ul, int nr)  
502 -{  
503 -#if defined (DEBUG_OP)  
504 - dump_store_dbat(ul, nr);  
505 -#endif  
506 -#if 0 // TRY  
507 - {  
508 - uint32_t base, length, page;  
509 - base = env->DBAT[0][nr];  
510 - length = (((base >> 2) & 0x000007FF) + 1) << 17;  
511 - base &= 0xFFFC0000;  
512 - for (page = base; page != base + length; page += 0x1000)  
513 - tlb_flush_page(env, page);  
514 - }  
515 -#else  
516 - tlb_flush(env, 1);  
517 -#endif  
518 - env->DBAT[ul][nr] = T0;  
519 -}  
520 -  
521 -/*****************************************************************************/  
522 -/* Special helpers for debug */  
523 -void dump_state (void)  
524 -{  
525 - // cpu_dump_state(env, stdout, fprintf, 0);  
526 -}  
527 -  
528 -void dump_rfi (void)  
529 -{  
530 -#if 0  
531 - printf("Return from interrupt => 0x%08x\n", env->nip);  
532 - // cpu_dump_state(env, stdout, fprintf, 0);  
533 -#endif  
534 -}  
535 -  
536 -void dump_store_sr (int srnum)  
537 -{  
538 -#if 0  
539 - printf("%s: reg=%d 0x%08x\n", __func__, srnum, T0);  
540 -#endif  
541 -}  
542 -  
543 -static void _dump_store_bat (char ID, int ul, int nr)  
544 -{  
545 - printf("Set %cBAT%d%c to 0x%08x (0x%08x)\n",  
546 - ID, nr, ul == 0 ? 'u' : 'l', T0, env->nip);  
547 -}  
548 -  
549 -void dump_store_ibat (int ul, int nr)  
550 -{  
551 - _dump_store_bat('I', ul, nr);  
552 -}  
553 -  
554 -void dump_store_dbat (int ul, int nr)  
555 -{  
556 - _dump_store_bat('D', ul, nr);  
557 -}  
558 -  
559 -void dump_store_tb (int ul)  
560 -{  
561 - printf("Set TB%c to 0x%08x\n", ul == 0 ? 'L' : 'U', T0);  
562 -}  
563 -  
564 -void dump_update_tb(uint32_t param)  
565 -{  
566 -#if 0  
567 - printf("Update TB: 0x%08x + %d => 0x%08x\n", T1, param, T0);  
568 -#endif  
569 -}  
570 -  
target-ppc/op_template.h
1 /* 1 /*
2 - * PPC emulation micro-operations for qemu. 2 + * PowerPC emulation micro-operations for qemu.
3 * 3 *
4 - * Copyright (c) 2003 Jocelyn Mayer 4 + * Copyright (c) 2003-2005 Jocelyn Mayer
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
@@ -175,7 +175,7 @@ void OPPROTO glue(op_load_sr, REG)(void) @@ -175,7 +175,7 @@ void OPPROTO glue(op_load_sr, REG)(void)
175 175
176 void OPPROTO glue(op_store_sr, REG)(void) 176 void OPPROTO glue(op_store_sr, REG)(void)
177 { 177 {
178 - do_store_sr(REG); 178 + do_store_sr(env, REG, T0);
179 RETURN(); 179 RETURN();
180 } 180 }
181 #endif 181 #endif
target-ppc/translate.c
1 /* 1 /*
2 - * PPC emulation for qemu: main translation routines. 2 + * PowerPC emulation for qemu: main translation routines.
3 * 3 *
4 - * Copyright (c) 2003 Jocelyn Mayer 4 + * Copyright (c) 2003-2005 Jocelyn Mayer
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
@@ -141,16 +141,17 @@ typedef struct DisasContext { @@ -141,16 +141,17 @@ typedef struct DisasContext {
141 int supervisor; 141 int supervisor;
142 #endif 142 #endif
143 int fpu_enabled; 143 int fpu_enabled;
  144 + ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
144 } DisasContext; 145 } DisasContext;
145 146
146 -typedef struct opc_handler_t { 147 +struct opc_handler_t {
147 /* invalid bits */ 148 /* invalid bits */
148 uint32_t inval; 149 uint32_t inval;
149 /* instruction type */ 150 /* instruction type */
150 uint32_t type; 151 uint32_t type;
151 /* handler */ 152 /* handler */
152 void (*handler)(DisasContext *ctx); 153 void (*handler)(DisasContext *ctx);
153 -} opc_handler_t; 154 +};
154 155
155 #define RET_EXCP(ctx, excp, error) \ 156 #define RET_EXCP(ctx, excp, error) \
156 do { \ 157 do { \
@@ -173,6 +174,11 @@ RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG) @@ -173,6 +174,11 @@ RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
173 #define RET_MTMSR(ctx) \ 174 #define RET_MTMSR(ctx) \
174 RET_EXCP((ctx), EXCP_MTMSR, 0) 175 RET_EXCP((ctx), EXCP_MTMSR, 0)
175 176
  177 +static inline void RET_STOP (DisasContext *ctx)
  178 +{
  179 + RET_EXCP(ctx, EXCP_MTMSR, 0);
  180 +}
  181 +
176 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \ 182 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
177 static void gen_##name (DisasContext *ctx); \ 183 static void gen_##name (DisasContext *ctx); \
178 GEN_OPCODE(name, opc1, opc2, opc3, inval, type); \ 184 GEN_OPCODE(name, opc1, opc2, opc3, inval, type); \
@@ -186,6 +192,7 @@ typedef struct opcode_t { @@ -186,6 +192,7 @@ typedef struct opcode_t {
186 unsigned char pad[1]; 192 unsigned char pad[1];
187 #endif 193 #endif
188 opc_handler_t handler; 194 opc_handler_t handler;
  195 + const unsigned char *oname;
189 } opcode_t; 196 } opcode_t;
190 197
191 /*** Instruction decoding ***/ 198 /*** Instruction decoding ***/
@@ -226,7 +233,13 @@ EXTRACT_HELPER(crbD, 21, 5); @@ -226,7 +233,13 @@ EXTRACT_HELPER(crbD, 21, 5);
226 EXTRACT_HELPER(crbA, 16, 5); 233 EXTRACT_HELPER(crbA, 16, 5);
227 EXTRACT_HELPER(crbB, 11, 5); 234 EXTRACT_HELPER(crbB, 11, 5);
228 /* SPR / TBL */ 235 /* SPR / TBL */
229 -EXTRACT_HELPER(SPR, 11, 10); 236 +EXTRACT_HELPER(_SPR, 11, 10);
  237 +static inline uint32_t SPR (uint32_t opcode)
  238 +{
  239 + uint32_t sprn = _SPR(opcode);
  240 +
  241 + return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
  242 +}
230 /*** Get constants ***/ 243 /*** Get constants ***/
231 EXTRACT_HELPER(IMM, 12, 8); 244 EXTRACT_HELPER(IMM, 12, 8);
232 /* 16 bits signed immediate value */ 245 /* 16 bits signed immediate value */
@@ -282,12 +295,17 @@ static inline uint32_t MASK (uint32_t start, uint32_t end) @@ -282,12 +295,17 @@ static inline uint32_t MASK (uint32_t start, uint32_t end)
282 return ret; 295 return ret;
283 } 296 }
284 297
  298 +#if HOST_LONG_BITS == 64
  299 +#define OPC_ALIGN 8
  300 +#else
  301 +#define OPC_ALIGN 4
  302 +#endif
285 #if defined(__APPLE__) 303 #if defined(__APPLE__)
286 #define OPCODES_SECTION \ 304 #define OPCODES_SECTION \
287 - __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (8) )) 305 + __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
288 #else 306 #else
289 #define OPCODES_SECTION \ 307 #define OPCODES_SECTION \
290 - __attribute__ ((section(".opcodes"), unused, aligned (8) )) 308 + __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
291 #endif 309 #endif
292 310
293 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \ 311 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \
@@ -301,6 +319,7 @@ OPCODES_SECTION opcode_t opc_##name = { \ @@ -301,6 +319,7 @@ OPCODES_SECTION opcode_t opc_##name = { \
301 .type = _typ, \ 319 .type = _typ, \
302 .handler = &gen_##name, \ 320 .handler = &gen_##name, \
303 }, \ 321 }, \
  322 + .oname = stringify(name), \
304 } 323 }
305 324
306 #define GEN_OPCODE_MARK(name) \ 325 #define GEN_OPCODE_MARK(name) \
@@ -314,6 +333,7 @@ OPCODES_SECTION opcode_t opc_##name = { \ @@ -314,6 +333,7 @@ OPCODES_SECTION opcode_t opc_##name = { \
314 .type = 0x00, \ 333 .type = 0x00, \
315 .handler = NULL, \ 334 .handler = NULL, \
316 }, \ 335 }, \
  336 + .oname = stringify(name), \
317 } 337 }
318 338
319 /* Start opcode list */ 339 /* Start opcode list */
@@ -1344,7 +1364,7 @@ static GenOpFunc1 *gen_op_stsw[] = { @@ -1344,7 +1364,7 @@ static GenOpFunc1 *gen_op_stsw[] = {
1344 #endif 1364 #endif
1345 1365
1346 /* lswi */ 1366 /* lswi */
1347 -/* PPC32 specification says we must generate an exception if 1367 +/* PowerPC32 specification says we must generate an exception if
1348 * rA is in the range of registers to be loaded. 1368 * rA is in the range of registers to be loaded.
1349 * In an other hand, IBM says this is valid, but rA won't be loaded. 1369 * In an other hand, IBM says this is valid, but rA won't be loaded.
1350 * For now, I'll follow the spec... 1370 * For now, I'll follow the spec...
@@ -1965,169 +1985,54 @@ GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC) @@ -1965,169 +1985,54 @@ GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
1965 #endif 1985 #endif
1966 } 1986 }
1967 1987
  1988 +#if 0
  1989 +#define SPR_NOACCESS ((void *)(-1))
  1990 +#else
  1991 +static void spr_noaccess (void *opaque, int sprn)
  1992 +{
  1993 + sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
  1994 + printf("ERROR: try to access SPR %d !\n", sprn);
  1995 +}
  1996 +#define SPR_NOACCESS (&spr_noaccess)
  1997 +#endif
  1998 +
1968 /* mfspr */ 1999 /* mfspr */
1969 -GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC) 2000 +static inline void gen_op_mfspr (DisasContext *ctx)
1970 { 2001 {
  2002 + void (*read_cb)(void *opaque, int sprn);
1971 uint32_t sprn = SPR(ctx->opcode); 2003 uint32_t sprn = SPR(ctx->opcode);
1972 2004
1973 -#if defined(CONFIG_USER_ONLY)  
1974 - switch (check_spr_access(sprn, 0, 0))  
1975 -#else  
1976 - switch (check_spr_access(sprn, 0, ctx->supervisor)) 2005 +#if !defined(CONFIG_USER_ONLY)
  2006 + if (ctx->supervisor)
  2007 + read_cb = ctx->spr_cb[sprn].oea_read;
  2008 + else
1977 #endif 2009 #endif
1978 - {  
1979 - case -1:  
1980 - RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);  
1981 - return;  
1982 - case 0: 2010 + read_cb = ctx->spr_cb[sprn].uea_read;
  2011 + if (read_cb != NULL) {
  2012 + if (read_cb != SPR_NOACCESS) {
  2013 + (*read_cb)(ctx, sprn);
  2014 + gen_op_store_T0_gpr(rD(ctx->opcode));
  2015 + } else {
  2016 + /* Privilege exception */
  2017 + printf("Trying to read priviledged spr %d %03x\n", sprn, sprn);
1983 RET_PRIVREG(ctx); 2018 RET_PRIVREG(ctx);
1984 - return;  
1985 - default:  
1986 - break;  
1987 } 2019 }
1988 - switch (sprn) {  
1989 - case XER:  
1990 - gen_op_load_xer();  
1991 - break;  
1992 - case LR:  
1993 - gen_op_load_lr();  
1994 - break;  
1995 - case CTR:  
1996 - gen_op_load_ctr();  
1997 - break;  
1998 - case IBAT0U:  
1999 - gen_op_load_ibat(0, 0);  
2000 - break;  
2001 - case IBAT1U:  
2002 - gen_op_load_ibat(0, 1);  
2003 - break;  
2004 - case IBAT2U:  
2005 - gen_op_load_ibat(0, 2);  
2006 - break;  
2007 - case IBAT3U:  
2008 - gen_op_load_ibat(0, 3);  
2009 - break;  
2010 - case IBAT4U:  
2011 - gen_op_load_ibat(0, 4);  
2012 - break;  
2013 - case IBAT5U:  
2014 - gen_op_load_ibat(0, 5);  
2015 - break;  
2016 - case IBAT6U:  
2017 - gen_op_load_ibat(0, 6);  
2018 - break;  
2019 - case IBAT7U:  
2020 - gen_op_load_ibat(0, 7);  
2021 - break;  
2022 - case IBAT0L:  
2023 - gen_op_load_ibat(1, 0);  
2024 - break;  
2025 - case IBAT1L:  
2026 - gen_op_load_ibat(1, 1);  
2027 - break;  
2028 - case IBAT2L:  
2029 - gen_op_load_ibat(1, 2);  
2030 - break;  
2031 - case IBAT3L:  
2032 - gen_op_load_ibat(1, 3);  
2033 - break;  
2034 - case IBAT4L:  
2035 - gen_op_load_ibat(1, 4);  
2036 - break;  
2037 - case IBAT5L:  
2038 - gen_op_load_ibat(1, 5);  
2039 - break;  
2040 - case IBAT6L:  
2041 - gen_op_load_ibat(1, 6);  
2042 - break;  
2043 - case IBAT7L:  
2044 - gen_op_load_ibat(1, 7);  
2045 - break;  
2046 - case DBAT0U:  
2047 - gen_op_load_dbat(0, 0);  
2048 - break;  
2049 - case DBAT1U:  
2050 - gen_op_load_dbat(0, 1);  
2051 - break;  
2052 - case DBAT2U:  
2053 - gen_op_load_dbat(0, 2);  
2054 - break;  
2055 - case DBAT3U:  
2056 - gen_op_load_dbat(0, 3);  
2057 - break;  
2058 - case DBAT4U:  
2059 - gen_op_load_dbat(0, 4);  
2060 - break;  
2061 - case DBAT5U:  
2062 - gen_op_load_dbat(0, 5);  
2063 - break;  
2064 - case DBAT6U:  
2065 - gen_op_load_dbat(0, 6);  
2066 - break;  
2067 - case DBAT7U:  
2068 - gen_op_load_dbat(0, 7);  
2069 - break;  
2070 - case DBAT0L:  
2071 - gen_op_load_dbat(1, 0);  
2072 - break;  
2073 - case DBAT1L:  
2074 - gen_op_load_dbat(1, 1);  
2075 - break;  
2076 - case DBAT2L:  
2077 - gen_op_load_dbat(1, 2);  
2078 - break;  
2079 - case DBAT3L:  
2080 - gen_op_load_dbat(1, 3);  
2081 - break;  
2082 - case DBAT4L:  
2083 - gen_op_load_dbat(1, 4);  
2084 - break;  
2085 - case DBAT5L:  
2086 - gen_op_load_dbat(1, 5);  
2087 - break;  
2088 - case DBAT6L:  
2089 - gen_op_load_dbat(1, 6);  
2090 - break;  
2091 - case DBAT7L:  
2092 - gen_op_load_dbat(1, 7);  
2093 - break;  
2094 - case SDR1:  
2095 - gen_op_load_sdr1();  
2096 - break;  
2097 - case V_TBL:  
2098 - gen_op_load_tbl();  
2099 - break;  
2100 - case V_TBU:  
2101 - gen_op_load_tbu();  
2102 - break;  
2103 - case DECR:  
2104 - gen_op_load_decr();  
2105 - break;  
2106 - default:  
2107 - gen_op_load_spr(sprn);  
2108 - break; 2020 + } else {
  2021 + /* Not defined */
  2022 + printf("Trying to read invalid spr %d %03x\n", sprn, sprn);
  2023 + RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
2109 } 2024 }
2110 - gen_op_store_T0_gpr(rD(ctx->opcode));  
2111 } 2025 }
2112 2026
2113 -/* mftb */  
2114 -GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MISC) 2027 +GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
2115 { 2028 {
2116 - uint32_t sprn = SPR(ctx->opcode);  
2117 -  
2118 - /* We need to update the time base before reading it */  
2119 - switch (sprn) {  
2120 - case V_TBL:  
2121 - gen_op_load_tbl();  
2122 - break;  
2123 - case V_TBU:  
2124 - gen_op_load_tbu();  
2125 - break;  
2126 - default:  
2127 - RET_INVAL(ctx);  
2128 - return; 2029 + gen_op_mfspr(ctx);
2129 } 2030 }
2130 - gen_op_store_T0_gpr(rD(ctx->opcode)); 2031 +
  2032 +/* mftb */
  2033 +GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_TB)
  2034 +{
  2035 + gen_op_mfspr(ctx);
2131 } 2036 }
2132 2037
2133 /* mtcrf */ 2038 /* mtcrf */
@@ -2158,184 +2063,28 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC) @@ -2158,184 +2063,28 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
2158 /* mtspr */ 2063 /* mtspr */
2159 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC) 2064 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
2160 { 2065 {
  2066 + void (*write_cb)(void *opaque, int sprn);
2161 uint32_t sprn = SPR(ctx->opcode); 2067 uint32_t sprn = SPR(ctx->opcode);
2162 2068
2163 -#if 0  
2164 - if (loglevel > 0) {  
2165 - fprintf(logfile, "MTSPR %d src=%d (%d)\n", SPR_ENCODE(sprn),  
2166 - rS(ctx->opcode), sprn);  
2167 - }  
2168 -#endif  
2169 -#if defined(CONFIG_USER_ONLY)  
2170 - switch (check_spr_access(sprn, 1, 0))  
2171 -#else  
2172 - switch (check_spr_access(sprn, 1, ctx->supervisor)) 2069 +#if !defined(CONFIG_USER_ONLY)
  2070 + if (ctx->supervisor)
  2071 + write_cb = ctx->spr_cb[sprn].oea_write;
  2072 + else
2173 #endif 2073 #endif
2174 - {  
2175 - case -1:  
2176 - RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);  
2177 - break;  
2178 - case 0: 2074 + write_cb = ctx->spr_cb[sprn].uea_write;
  2075 + if (write_cb != NULL) {
  2076 + if (write_cb != SPR_NOACCESS) {
  2077 + gen_op_load_gpr_T0(rS(ctx->opcode));
  2078 + (*write_cb)(ctx, sprn);
  2079 + } else {
  2080 + /* Privilege exception */
  2081 + printf("Trying to write priviledged spr %d %03x\n", sprn, sprn);
2179 RET_PRIVREG(ctx); 2082 RET_PRIVREG(ctx);
2180 - break;  
2181 - default:  
2182 - break;  
2183 } 2083 }
2184 - gen_op_load_gpr_T0(rS(ctx->opcode));  
2185 - switch (sprn) {  
2186 - case XER:  
2187 - gen_op_store_xer();  
2188 - break;  
2189 - case LR:  
2190 - gen_op_store_lr();  
2191 - break;  
2192 - case CTR:  
2193 - gen_op_store_ctr();  
2194 - break;  
2195 - case IBAT0U:  
2196 - gen_op_store_ibat(0, 0);  
2197 - RET_MTMSR(ctx);  
2198 - break;  
2199 - case IBAT1U:  
2200 - gen_op_store_ibat(0, 1);  
2201 - RET_MTMSR(ctx);  
2202 - break;  
2203 - case IBAT2U:  
2204 - gen_op_store_ibat(0, 2);  
2205 - RET_MTMSR(ctx);  
2206 - break;  
2207 - case IBAT3U:  
2208 - gen_op_store_ibat(0, 3);  
2209 - RET_MTMSR(ctx);  
2210 - break;  
2211 - case IBAT4U:  
2212 - gen_op_store_ibat(0, 4);  
2213 - RET_MTMSR(ctx);  
2214 - break;  
2215 - case IBAT5U:  
2216 - gen_op_store_ibat(0, 5);  
2217 - RET_MTMSR(ctx);  
2218 - break;  
2219 - case IBAT6U:  
2220 - gen_op_store_ibat(0, 6);  
2221 - RET_MTMSR(ctx);  
2222 - break;  
2223 - case IBAT7U:  
2224 - gen_op_store_ibat(0, 7);  
2225 - RET_MTMSR(ctx);  
2226 - break;  
2227 - case IBAT0L:  
2228 - gen_op_store_ibat(1, 0);  
2229 - RET_MTMSR(ctx);  
2230 - break;  
2231 - case IBAT1L:  
2232 - gen_op_store_ibat(1, 1);  
2233 - RET_MTMSR(ctx);  
2234 - break;  
2235 - case IBAT2L:  
2236 - gen_op_store_ibat(1, 2);  
2237 - RET_MTMSR(ctx);  
2238 - break;  
2239 - case IBAT3L:  
2240 - gen_op_store_ibat(1, 3);  
2241 - RET_MTMSR(ctx);  
2242 - break;  
2243 - case IBAT4L:  
2244 - gen_op_store_ibat(1, 4);  
2245 - RET_MTMSR(ctx);  
2246 - break;  
2247 - case IBAT5L:  
2248 - gen_op_store_ibat(1, 5);  
2249 - RET_MTMSR(ctx);  
2250 - break;  
2251 - case IBAT6L:  
2252 - gen_op_store_ibat(1, 6);  
2253 - RET_MTMSR(ctx);  
2254 - break;  
2255 - case IBAT7L:  
2256 - gen_op_store_ibat(1, 7);  
2257 - RET_MTMSR(ctx);  
2258 - break;  
2259 - case DBAT0U:  
2260 - gen_op_store_dbat(0, 0);  
2261 - RET_MTMSR(ctx);  
2262 - break;  
2263 - case DBAT1U:  
2264 - gen_op_store_dbat(0, 1);  
2265 - RET_MTMSR(ctx);  
2266 - break;  
2267 - case DBAT2U:  
2268 - gen_op_store_dbat(0, 2);  
2269 - RET_MTMSR(ctx);  
2270 - break;  
2271 - case DBAT3U:  
2272 - gen_op_store_dbat(0, 3);  
2273 - RET_MTMSR(ctx);  
2274 - break;  
2275 - case DBAT4U:  
2276 - gen_op_store_dbat(0, 4);  
2277 - RET_MTMSR(ctx);  
2278 - break;  
2279 - case DBAT5U:  
2280 - gen_op_store_dbat(0, 5);  
2281 - RET_MTMSR(ctx);  
2282 - break;  
2283 - case DBAT6U:  
2284 - gen_op_store_dbat(0, 6);  
2285 - RET_MTMSR(ctx);  
2286 - break;  
2287 - case DBAT7U:  
2288 - gen_op_store_dbat(0, 7);  
2289 - RET_MTMSR(ctx);  
2290 - break;  
2291 - case DBAT0L:  
2292 - gen_op_store_dbat(1, 0);  
2293 - RET_MTMSR(ctx);  
2294 - break;  
2295 - case DBAT1L:  
2296 - gen_op_store_dbat(1, 1);  
2297 - RET_MTMSR(ctx);  
2298 - break;  
2299 - case DBAT2L:  
2300 - gen_op_store_dbat(1, 2);  
2301 - RET_MTMSR(ctx);  
2302 - break;  
2303 - case DBAT3L:  
2304 - gen_op_store_dbat(1, 3);  
2305 - RET_MTMSR(ctx);  
2306 - break;  
2307 - case DBAT4L:  
2308 - gen_op_store_dbat(1, 4);  
2309 - RET_MTMSR(ctx);  
2310 - break;  
2311 - case DBAT5L:  
2312 - gen_op_store_dbat(1, 5);  
2313 - RET_MTMSR(ctx);  
2314 - break;  
2315 - case DBAT6L:  
2316 - gen_op_store_dbat(1, 6);  
2317 - RET_MTMSR(ctx);  
2318 - break;  
2319 - case DBAT7L:  
2320 - gen_op_store_dbat(1, 7);  
2321 - RET_MTMSR(ctx);  
2322 - break;  
2323 - case SDR1:  
2324 - gen_op_store_sdr1();  
2325 - RET_MTMSR(ctx);  
2326 - break;  
2327 - case O_TBL:  
2328 - gen_op_store_tbl();  
2329 - break;  
2330 - case O_TBU:  
2331 - gen_op_store_tbu();  
2332 - break;  
2333 - case DECR:  
2334 - gen_op_store_decr();  
2335 - break;  
2336 - default:  
2337 - gen_op_store_spr(sprn);  
2338 - break; 2084 + } else {
  2085 + /* Not defined */
  2086 + printf("Trying to write invalid spr %d %03x\n", sprn, sprn);
  2087 + RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR);
2339 } 2088 }
2340 } 2089 }
2341 2090
@@ -2514,7 +2263,7 @@ GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT) @@ -2514,7 +2263,7 @@ GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
2514 /*** Lookaside buffer management ***/ 2263 /*** Lookaside buffer management ***/
2515 /* Optional & supervisor only: */ 2264 /* Optional & supervisor only: */
2516 /* tlbia */ 2265 /* tlbia */
2517 -GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_OPT) 2266 +GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
2518 { 2267 {
2519 #if defined(CONFIG_USER_ONLY) 2268 #if defined(CONFIG_USER_ONLY)
2520 RET_PRIVOPC(ctx); 2269 RET_PRIVOPC(ctx);
@@ -2624,510 +2373,41 @@ GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN) @@ -2624,510 +2373,41 @@ GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
2624 /* End opcode list */ 2373 /* End opcode list */
2625 GEN_OPCODE_MARK(end); 2374 GEN_OPCODE_MARK(end);
2626 2375
2627 -/*****************************************************************************/  
2628 -#include <stdlib.h>  
2629 -#include <string.h>  
2630 -  
2631 -int fflush (FILE *stream);  
2632 -  
2633 -/* Main ppc opcodes table:  
2634 - * at init, all opcodes are invalids  
2635 - */  
2636 -static opc_handler_t *ppc_opcodes[0x40];  
2637 -  
2638 -/* Opcode types */  
2639 -enum {  
2640 - PPC_DIRECT = 0, /* Opcode routine */  
2641 - PPC_INDIRECT = 1, /* Indirect opcode table */  
2642 -};  
2643 -  
2644 -static inline int is_indirect_opcode (void *handler)  
2645 -{  
2646 - return ((unsigned long)handler & 0x03) == PPC_INDIRECT;  
2647 -}  
2648 -  
2649 -static inline opc_handler_t **ind_table(void *handler)  
2650 -{  
2651 - return (opc_handler_t **)((unsigned long)handler & ~3);  
2652 -}  
2653 -  
2654 -/* Instruction table creation */  
2655 -/* Opcodes tables creation */  
2656 -static void fill_new_table (opc_handler_t **table, int len)  
2657 -{  
2658 - int i;  
2659 -  
2660 - for (i = 0; i < len; i++)  
2661 - table[i] = &invalid_handler;  
2662 -}  
2663 -  
2664 -static int create_new_table (opc_handler_t **table, unsigned char idx)  
2665 -{  
2666 - opc_handler_t **tmp;  
2667 -  
2668 - tmp = malloc(0x20 * sizeof(opc_handler_t));  
2669 - if (tmp == NULL)  
2670 - return -1;  
2671 - fill_new_table(tmp, 0x20);  
2672 - table[idx] = (opc_handler_t *)((unsigned long)tmp | PPC_INDIRECT);  
2673 -  
2674 - return 0;  
2675 -}  
2676 -  
2677 -static int insert_in_table (opc_handler_t **table, unsigned char idx,  
2678 - opc_handler_t *handler)  
2679 -{  
2680 - if (table[idx] != &invalid_handler)  
2681 - return -1;  
2682 - table[idx] = handler;  
2683 -  
2684 - return 0;  
2685 -}  
2686 -  
2687 -static int register_direct_insn (opc_handler_t **ppc_opcodes,  
2688 - unsigned char idx, opc_handler_t *handler)  
2689 -{  
2690 - if (insert_in_table(ppc_opcodes, idx, handler) < 0) {  
2691 - printf("*** ERROR: opcode %02x already assigned in main "  
2692 - "opcode table\n", idx);  
2693 - return -1;  
2694 - }  
2695 -  
2696 - return 0;  
2697 -}  
2698 -  
2699 -static int register_ind_in_table (opc_handler_t **table,  
2700 - unsigned char idx1, unsigned char idx2,  
2701 - opc_handler_t *handler)  
2702 -{  
2703 - if (table[idx1] == &invalid_handler) {  
2704 - if (create_new_table(table, idx1) < 0) {  
2705 - printf("*** ERROR: unable to create indirect table "  
2706 - "idx=%02x\n", idx1);  
2707 - return -1;  
2708 - }  
2709 - } else {  
2710 - if (!is_indirect_opcode(table[idx1])) {  
2711 - printf("*** ERROR: idx %02x already assigned to a direct "  
2712 - "opcode\n", idx1);  
2713 - return -1;  
2714 - }  
2715 - }  
2716 - if (handler != NULL &&  
2717 - insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {  
2718 - printf("*** ERROR: opcode %02x already assigned in "  
2719 - "opcode table %02x\n", idx2, idx1);  
2720 - return -1;  
2721 - }  
2722 -  
2723 - return 0;  
2724 -}  
2725 -  
2726 -static int register_ind_insn (opc_handler_t **ppc_opcodes,  
2727 - unsigned char idx1, unsigned char idx2,  
2728 - opc_handler_t *handler)  
2729 -{  
2730 - int ret;  
2731 -  
2732 - ret = register_ind_in_table(ppc_opcodes, idx1, idx2, handler);  
2733 -  
2734 - return ret;  
2735 -}  
2736 -  
2737 -static int register_dblind_insn (opc_handler_t **ppc_opcodes,  
2738 - unsigned char idx1, unsigned char idx2,  
2739 - unsigned char idx3, opc_handler_t *handler)  
2740 -{  
2741 - if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {  
2742 - printf("*** ERROR: unable to join indirect table idx "  
2743 - "[%02x-%02x]\n", idx1, idx2);  
2744 - return -1;  
2745 - }  
2746 - if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,  
2747 - handler) < 0) {  
2748 - printf("*** ERROR: unable to insert opcode "  
2749 - "[%02x-%02x-%02x]\n", idx1, idx2, idx3);  
2750 - return -1;  
2751 - }  
2752 -  
2753 - return 0;  
2754 -}  
2755 -  
2756 -static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)  
2757 -{  
2758 - if (insn->opc2 != 0xFF) {  
2759 - if (insn->opc3 != 0xFF) {  
2760 - if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,  
2761 - insn->opc3, &insn->handler) < 0)  
2762 - return -1;  
2763 - } else {  
2764 - if (register_ind_insn(ppc_opcodes, insn->opc1,  
2765 - insn->opc2, &insn->handler) < 0)  
2766 - return -1;  
2767 - }  
2768 - } else {  
2769 - if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0)  
2770 - return -1;  
2771 - }  
2772 -  
2773 - return 0;  
2774 -}  
2775 -  
2776 -static int test_opcode_table (opc_handler_t **table, int len)  
2777 -{  
2778 - int i, count, tmp;  
2779 -  
2780 - for (i = 0, count = 0; i < len; i++) {  
2781 - /* Consistency fixup */  
2782 - if (table[i] == NULL)  
2783 - table[i] = &invalid_handler;  
2784 - if (table[i] != &invalid_handler) {  
2785 - if (is_indirect_opcode(table[i])) {  
2786 - tmp = test_opcode_table(ind_table(table[i]), 0x20);  
2787 - if (tmp == 0) {  
2788 - free(table[i]);  
2789 - table[i] = &invalid_handler;  
2790 - } else {  
2791 - count++;  
2792 - }  
2793 - } else {  
2794 - count++;  
2795 - }  
2796 - }  
2797 - }  
2798 -  
2799 - return count;  
2800 -}  
2801 -  
2802 -static void fix_opcode_tables (opc_handler_t **ppc_opcodes)  
2803 -{  
2804 - if (test_opcode_table(ppc_opcodes, 0x40) == 0)  
2805 - printf("*** WARNING: no opcode defined !\n");  
2806 -}  
2807 -  
2808 -#define SPR_RIGHTS(rw, priv) (1 << ((2 * (priv)) + (rw)))  
2809 -#define SPR_UR SPR_RIGHTS(0, 0)  
2810 -#define SPR_UW SPR_RIGHTS(1, 0)  
2811 -#define SPR_SR SPR_RIGHTS(0, 1)  
2812 -#define SPR_SW SPR_RIGHTS(1, 1)  
2813 -  
2814 -#define spr_set_rights(spr, rights) \  
2815 -do { \  
2816 - spr_access[(spr) >> 1] |= ((rights) << (4 * ((spr) & 1))); \  
2817 -} while (0)  
2818 -  
2819 -static void init_spr_rights (uint32_t pvr)  
2820 -{  
2821 - /* XER (SPR 1) */  
2822 - spr_set_rights(XER, SPR_UR | SPR_UW | SPR_SR | SPR_SW);  
2823 - /* LR (SPR 8) */  
2824 - spr_set_rights(LR, SPR_UR | SPR_UW | SPR_SR | SPR_SW);  
2825 - /* CTR (SPR 9) */  
2826 - spr_set_rights(CTR, SPR_UR | SPR_UW | SPR_SR | SPR_SW);  
2827 - /* TBL (SPR 268) */  
2828 - spr_set_rights(V_TBL, SPR_UR | SPR_SR);  
2829 - /* TBU (SPR 269) */  
2830 - spr_set_rights(V_TBU, SPR_UR | SPR_SR);  
2831 - /* DSISR (SPR 18) */  
2832 - spr_set_rights(DSISR, SPR_SR | SPR_SW);  
2833 - /* DAR (SPR 19) */  
2834 - spr_set_rights(DAR, SPR_SR | SPR_SW);  
2835 - /* DEC (SPR 22) */  
2836 - spr_set_rights(DECR, SPR_SR | SPR_SW);  
2837 - /* SDR1 (SPR 25) */  
2838 - spr_set_rights(SDR1, SPR_SR | SPR_SW);  
2839 - /* SRR0 (SPR 26) */  
2840 - spr_set_rights(SRR0, SPR_SR | SPR_SW);  
2841 - /* SRR1 (SPR 27) */  
2842 - spr_set_rights(SRR1, SPR_SR | SPR_SW);  
2843 - /* SPRG0 (SPR 272) */  
2844 - spr_set_rights(SPRG0, SPR_SR | SPR_SW);  
2845 - /* SPRG1 (SPR 273) */  
2846 - spr_set_rights(SPRG1, SPR_SR | SPR_SW);  
2847 - /* SPRG2 (SPR 274) */  
2848 - spr_set_rights(SPRG2, SPR_SR | SPR_SW);  
2849 - /* SPRG3 (SPR 275) */  
2850 - spr_set_rights(SPRG3, SPR_SR | SPR_SW);  
2851 - /* ASR (SPR 280) */  
2852 - spr_set_rights(ASR, SPR_SR | SPR_SW);  
2853 - /* EAR (SPR 282) */  
2854 - spr_set_rights(EAR, SPR_SR | SPR_SW);  
2855 - /* TBL (SPR 284) */  
2856 - spr_set_rights(O_TBL, SPR_SW);  
2857 - /* TBU (SPR 285) */  
2858 - spr_set_rights(O_TBU, SPR_SW);  
2859 - /* PVR (SPR 287) */  
2860 - spr_set_rights(PVR, SPR_SR);  
2861 - /* IBAT0U (SPR 528) */  
2862 - spr_set_rights(IBAT0U, SPR_SR | SPR_SW);  
2863 - /* IBAT0L (SPR 529) */  
2864 - spr_set_rights(IBAT0L, SPR_SR | SPR_SW);  
2865 - /* IBAT1U (SPR 530) */  
2866 - spr_set_rights(IBAT1U, SPR_SR | SPR_SW);  
2867 - /* IBAT1L (SPR 531) */  
2868 - spr_set_rights(IBAT1L, SPR_SR | SPR_SW);  
2869 - /* IBAT2U (SPR 532) */  
2870 - spr_set_rights(IBAT2U, SPR_SR | SPR_SW);  
2871 - /* IBAT2L (SPR 533) */  
2872 - spr_set_rights(IBAT2L, SPR_SR | SPR_SW);  
2873 - /* IBAT3U (SPR 534) */  
2874 - spr_set_rights(IBAT3U, SPR_SR | SPR_SW);  
2875 - /* IBAT3L (SPR 535) */  
2876 - spr_set_rights(IBAT3L, SPR_SR | SPR_SW);  
2877 - /* DBAT0U (SPR 536) */  
2878 - spr_set_rights(DBAT0U, SPR_SR | SPR_SW);  
2879 - /* DBAT0L (SPR 537) */  
2880 - spr_set_rights(DBAT0L, SPR_SR | SPR_SW);  
2881 - /* DBAT1U (SPR 538) */  
2882 - spr_set_rights(DBAT1U, SPR_SR | SPR_SW);  
2883 - /* DBAT1L (SPR 539) */  
2884 - spr_set_rights(DBAT1L, SPR_SR | SPR_SW);  
2885 - /* DBAT2U (SPR 540) */  
2886 - spr_set_rights(DBAT2U, SPR_SR | SPR_SW);  
2887 - /* DBAT2L (SPR 541) */  
2888 - spr_set_rights(DBAT2L, SPR_SR | SPR_SW);  
2889 - /* DBAT3U (SPR 542) */  
2890 - spr_set_rights(DBAT3U, SPR_SR | SPR_SW);  
2891 - /* DBAT3L (SPR 543) */  
2892 - spr_set_rights(DBAT3L, SPR_SR | SPR_SW);  
2893 - /* FPECR (SPR 1022) */  
2894 - spr_set_rights(FPECR, SPR_SR | SPR_SW);  
2895 - /* Special registers for PPC 604 */  
2896 - if ((pvr & 0xFFFF0000) == 0x00040000) {  
2897 - /* IABR */  
2898 - spr_set_rights(IABR , SPR_SR | SPR_SW);  
2899 - /* DABR (SPR 1013) */  
2900 - spr_set_rights(DABR, SPR_SR | SPR_SW);  
2901 - /* HID0 */  
2902 - spr_set_rights(HID0, SPR_SR | SPR_SW);  
2903 - /* PIR */  
2904 - spr_set_rights(PIR, SPR_SR | SPR_SW);  
2905 - /* PMC1 */  
2906 - spr_set_rights(PMC1, SPR_SR | SPR_SW);  
2907 - /* PMC2 */  
2908 - spr_set_rights(PMC2, SPR_SR | SPR_SW);  
2909 - /* MMCR0 */  
2910 - spr_set_rights(MMCR0, SPR_SR | SPR_SW);  
2911 - /* SIA */  
2912 - spr_set_rights(SIA, SPR_SR | SPR_SW);  
2913 - /* SDA */  
2914 - spr_set_rights(SDA, SPR_SR | SPR_SW);  
2915 - }  
2916 - /* Special registers for MPC740/745/750/755 (aka G3) & IBM 750 */  
2917 - if ((pvr & 0xFFFF0000) == 0x00080000 ||  
2918 - (pvr & 0xFFFF0000) == 0x70000000) {  
2919 - /* HID0 */  
2920 - spr_set_rights(HID0, SPR_SR | SPR_SW);  
2921 - /* HID1 */  
2922 - spr_set_rights(HID1, SPR_SR | SPR_SW);  
2923 - /* IABR */  
2924 - spr_set_rights(IABR, SPR_SR | SPR_SW);  
2925 - /* ICTC */  
2926 - spr_set_rights(ICTC, SPR_SR | SPR_SW);  
2927 - /* L2CR */  
2928 - spr_set_rights(L2CR, SPR_SR | SPR_SW);  
2929 - /* MMCR0 */  
2930 - spr_set_rights(MMCR0, SPR_SR | SPR_SW);  
2931 - /* MMCR1 */  
2932 - spr_set_rights(MMCR1, SPR_SR | SPR_SW);  
2933 - /* PMC1 */  
2934 - spr_set_rights(PMC1, SPR_SR | SPR_SW);  
2935 - /* PMC2 */  
2936 - spr_set_rights(PMC2, SPR_SR | SPR_SW);  
2937 - /* PMC3 */  
2938 - spr_set_rights(PMC3, SPR_SR | SPR_SW);  
2939 - /* PMC4 */  
2940 - spr_set_rights(PMC4, SPR_SR | SPR_SW);  
2941 - /* SIA */  
2942 - spr_set_rights(SIA, SPR_SR | SPR_SW);  
2943 - /* SDA */  
2944 - spr_set_rights(SDA, SPR_SR | SPR_SW);  
2945 - /* THRM1 */  
2946 - spr_set_rights(THRM1, SPR_SR | SPR_SW);  
2947 - /* THRM2 */  
2948 - spr_set_rights(THRM2, SPR_SR | SPR_SW);  
2949 - /* THRM3 */  
2950 - spr_set_rights(THRM3, SPR_SR | SPR_SW);  
2951 - /* UMMCR0 */  
2952 - spr_set_rights(UMMCR0, SPR_UR | SPR_UW);  
2953 - /* UMMCR1 */  
2954 - spr_set_rights(UMMCR1, SPR_UR | SPR_UW);  
2955 - /* UPMC1 */  
2956 - spr_set_rights(UPMC1, SPR_UR | SPR_UW);  
2957 - /* UPMC2 */  
2958 - spr_set_rights(UPMC2, SPR_UR | SPR_UW);  
2959 - /* UPMC3 */  
2960 - spr_set_rights(UPMC3, SPR_UR | SPR_UW);  
2961 - /* UPMC4 */  
2962 - spr_set_rights(UPMC4, SPR_UR | SPR_UW);  
2963 - /* USIA */  
2964 - spr_set_rights(USIA, SPR_UR | SPR_UW);  
2965 - }  
2966 - /* MPC755 has special registers */  
2967 - if (pvr == 0x00083100) {  
2968 - /* SPRG4 */  
2969 - spr_set_rights(SPRG4, SPR_SR | SPR_SW);  
2970 - /* SPRG5 */  
2971 - spr_set_rights(SPRG5, SPR_SR | SPR_SW);  
2972 - /* SPRG6 */  
2973 - spr_set_rights(SPRG6, SPR_SR | SPR_SW);  
2974 - /* SPRG7 */  
2975 - spr_set_rights(SPRG7, SPR_SR | SPR_SW);  
2976 - /* IBAT4U */  
2977 - spr_set_rights(IBAT4U, SPR_SR | SPR_SW);  
2978 - /* IBAT4L */  
2979 - spr_set_rights(IBAT4L, SPR_SR | SPR_SW);  
2980 - /* IBAT5U */  
2981 - spr_set_rights(IBAT5U, SPR_SR | SPR_SW);  
2982 - /* IBAT5L */  
2983 - spr_set_rights(IBAT5L, SPR_SR | SPR_SW);  
2984 - /* IBAT6U */  
2985 - spr_set_rights(IBAT6U, SPR_SR | SPR_SW);  
2986 - /* IBAT6L */  
2987 - spr_set_rights(IBAT6L, SPR_SR | SPR_SW);  
2988 - /* IBAT7U */  
2989 - spr_set_rights(IBAT7U, SPR_SR | SPR_SW);  
2990 - /* IBAT7L */  
2991 - spr_set_rights(IBAT7L, SPR_SR | SPR_SW);  
2992 - /* DBAT4U */  
2993 - spr_set_rights(DBAT4U, SPR_SR | SPR_SW);  
2994 - /* DBAT4L */  
2995 - spr_set_rights(DBAT4L, SPR_SR | SPR_SW);  
2996 - /* DBAT5U */  
2997 - spr_set_rights(DBAT5U, SPR_SR | SPR_SW);  
2998 - /* DBAT5L */  
2999 - spr_set_rights(DBAT5L, SPR_SR | SPR_SW);  
3000 - /* DBAT6U */  
3001 - spr_set_rights(DBAT6U, SPR_SR | SPR_SW);  
3002 - /* DBAT6L */  
3003 - spr_set_rights(DBAT6L, SPR_SR | SPR_SW);  
3004 - /* DBAT7U */  
3005 - spr_set_rights(DBAT7U, SPR_SR | SPR_SW);  
3006 - /* DBAT7L */  
3007 - spr_set_rights(DBAT7L, SPR_SR | SPR_SW);  
3008 - /* DMISS */  
3009 - spr_set_rights(DMISS, SPR_SR | SPR_SW);  
3010 - /* DCMP */  
3011 - spr_set_rights(DCMP, SPR_SR | SPR_SW);  
3012 - /* DHASH1 */  
3013 - spr_set_rights(DHASH1, SPR_SR | SPR_SW);  
3014 - /* DHASH2 */  
3015 - spr_set_rights(DHASH2, SPR_SR | SPR_SW);  
3016 - /* IMISS */  
3017 - spr_set_rights(IMISS, SPR_SR | SPR_SW);  
3018 - /* ICMP */  
3019 - spr_set_rights(ICMP, SPR_SR | SPR_SW);  
3020 - /* RPA */  
3021 - spr_set_rights(RPA, SPR_SR | SPR_SW);  
3022 - /* HID2 */  
3023 - spr_set_rights(HID2, SPR_SR | SPR_SW);  
3024 - /* L2PM */  
3025 - spr_set_rights(L2PM, SPR_SR | SPR_SW);  
3026 - }  
3027 -}  
3028 -  
3029 -/*****************************************************************************/  
3030 -/* PPC "main stream" common instructions (no optional ones) */  
3031 -  
3032 -typedef struct ppc_proc_t {  
3033 - int flags;  
3034 - void *specific;  
3035 -} ppc_proc_t;  
3036 -  
3037 -typedef struct ppc_def_t {  
3038 - unsigned long pvr;  
3039 - unsigned long pvr_mask;  
3040 - ppc_proc_t *proc;  
3041 -} ppc_def_t;  
3042 -  
3043 -static ppc_proc_t ppc_proc_common = {  
3044 - .flags = PPC_COMMON,  
3045 - .specific = NULL,  
3046 -};  
3047 -  
3048 -static ppc_proc_t ppc_proc_G3 = {  
3049 - .flags = PPC_750,  
3050 - .specific = NULL,  
3051 -};  
3052 -  
3053 -static ppc_def_t ppc_defs[] =  
3054 -{  
3055 - /* MPC740/745/750/755 (G3) */  
3056 - {  
3057 - .pvr = 0x00080000,  
3058 - .pvr_mask = 0xFFFF0000,  
3059 - .proc = &ppc_proc_G3,  
3060 - },  
3061 - /* IBM 750FX (G3 embedded) */  
3062 - {  
3063 - .pvr = 0x70000000,  
3064 - .pvr_mask = 0xFFFF0000,  
3065 - .proc = &ppc_proc_G3,  
3066 - },  
3067 - /* Fallback (generic PPC) */  
3068 - {  
3069 - .pvr = 0x00000000,  
3070 - .pvr_mask = 0x00000000,  
3071 - .proc = &ppc_proc_common,  
3072 - },  
3073 -};  
3074 -  
3075 -static int create_ppc_proc (opc_handler_t **ppc_opcodes, unsigned long pvr)  
3076 -{  
3077 - opcode_t *opc, *start, *end;  
3078 - int i, flags;  
3079 -  
3080 - fill_new_table(ppc_opcodes, 0x40);  
3081 - for (i = 0; ; i++) {  
3082 - if ((ppc_defs[i].pvr & ppc_defs[i].pvr_mask) ==  
3083 - (pvr & ppc_defs[i].pvr_mask)) {  
3084 - flags = ppc_defs[i].proc->flags;  
3085 - break;  
3086 - }  
3087 - }  
3088 -  
3089 - if (&opc_start < &opc_end) {  
3090 - start = &opc_start;  
3091 - end = &opc_end;  
3092 - } else {  
3093 - start = &opc_end;  
3094 - end = &opc_start;  
3095 - }  
3096 - for (opc = start + 1; opc != end; opc++) {  
3097 - if ((opc->handler.type & flags) != 0)  
3098 - if (register_insn(ppc_opcodes, opc) < 0) {  
3099 - printf("*** ERROR initializing PPC instruction "  
3100 - "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,  
3101 - opc->opc3);  
3102 - return -1;  
3103 - }  
3104 - }  
3105 - fix_opcode_tables(ppc_opcodes);  
3106 -  
3107 - return 0;  
3108 -}  
3109 - 2376 +#include "translate_init.c"
3110 2377
3111 /*****************************************************************************/ 2378 /*****************************************************************************/
3112 -/* Misc PPC helpers */  
3113 - 2379 +/* Misc PowerPC helpers */
3114 void cpu_dump_state(CPUState *env, FILE *f, 2380 void cpu_dump_state(CPUState *env, FILE *f,
3115 int (*cpu_fprintf)(FILE *f, const char *fmt, ...), 2381 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
3116 int flags) 2382 int flags)
3117 { 2383 {
  2384 +#if defined(TARGET_PPC64) || 1
  2385 +#define FILL ""
  2386 +#define REGX "%016llx"
  2387 +#define RGPL 4
  2388 +#define RFPL 4
  2389 +#else
  2390 +#define FILL " "
  2391 +#define REGX "%08llx"
  2392 +#define RGPL 8
  2393 +#define RFPL 4
  2394 +#endif
  2395 +
3118 int i; 2396 int i;
3119 2397
3120 - cpu_fprintf(f, "nip=0x%08x LR=0x%08x CTR=0x%08x XER=0x%08x "  
3121 - "MSR=0x%08x\n", env->nip, env->lr, env->ctr,  
3122 - _load_xer(env), _load_msr(env)); 2398 + cpu_fprintf(f, "NIP " REGX " LR " REGX " CTR " REGX "\n",
  2399 + env->nip, env->lr, env->ctr);
  2400 + cpu_fprintf(f, "MSR " REGX FILL " XER %08x TB %08x %08x DECR %08x\n",
  2401 + do_load_msr(env), do_load_xer(env), cpu_ppc_load_tbu(env),
  2402 + cpu_ppc_load_tbl(env), cpu_ppc_load_decr(env));
3123 for (i = 0; i < 32; i++) { 2403 for (i = 0; i < 32; i++) {
3124 - if ((i & 7) == 0)  
3125 - cpu_fprintf(f, "GPR%02d:", i);  
3126 - cpu_fprintf(f, " %08x", env->gpr[i]);  
3127 - if ((i & 7) == 7) 2404 + if ((i & (RGPL - 1)) == 0)
  2405 + cpu_fprintf(f, "GPR%02d", i);
  2406 + cpu_fprintf(f, " " REGX, env->gpr[i]);
  2407 + if ((i & (RGPL - 1)) == (RGPL - 1))
3128 cpu_fprintf(f, "\n"); 2408 cpu_fprintf(f, "\n");
3129 } 2409 }
3130 - cpu_fprintf(f, "CR: 0x"); 2410 + cpu_fprintf(f, "CR ");
3131 for (i = 0; i < 8; i++) 2411 for (i = 0; i < 8; i++)
3132 cpu_fprintf(f, "%01x", env->crf[i]); 2412 cpu_fprintf(f, "%01x", env->crf[i]);
3133 cpu_fprintf(f, " ["); 2413 cpu_fprintf(f, " [");
@@ -3141,65 +2421,22 @@ void cpu_dump_state(CPUState *env, FILE *f, @@ -3141,65 +2421,22 @@ void cpu_dump_state(CPUState *env, FILE *f,
3141 a = 'E'; 2421 a = 'E';
3142 cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' '); 2422 cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
3143 } 2423 }
3144 - cpu_fprintf(f, " ] ");  
3145 - cpu_fprintf(f, "TB: 0x%08x %08x\n", cpu_ppc_load_tbu(env),  
3146 - cpu_ppc_load_tbl(env));  
3147 - for (i = 0; i < 16; i++) {  
3148 - if ((i & 3) == 0)  
3149 - cpu_fprintf(f, "FPR%02d:", i); 2424 + cpu_fprintf(f, " ] " FILL "RES " REGX "\n", env->reserve);
  2425 + for (i = 0; i < 32; i++) {
  2426 + if ((i & (RFPL - 1)) == 0)
  2427 + cpu_fprintf(f, "FPR%02d", i);
3150 cpu_fprintf(f, " %016llx", *((uint64_t *)&env->fpr[i])); 2428 cpu_fprintf(f, " %016llx", *((uint64_t *)&env->fpr[i]));
3151 - if ((i & 3) == 3) 2429 + if ((i & (RFPL - 1)) == (RFPL - 1))
3152 cpu_fprintf(f, "\n"); 2430 cpu_fprintf(f, "\n");
3153 } 2431 }
3154 - cpu_fprintf(f, "SRR0 0x%08x SRR1 0x%08x DECR=0x%08x\n",  
3155 - env->spr[SRR0], env->spr[SRR1], cpu_ppc_load_decr(env));  
3156 - cpu_fprintf(f, "reservation 0x%08x\n", env->reserve);  
3157 -}  
3158 -  
3159 -CPUPPCState *cpu_ppc_init(void)  
3160 -{  
3161 - CPUPPCState *env;  
3162 -  
3163 - cpu_exec_init();  
3164 -  
3165 - env = qemu_mallocz(sizeof(CPUPPCState));  
3166 - if (!env)  
3167 - return NULL;  
3168 -// env->spr[PVR] = 0; /* Basic PPC */  
3169 - env->spr[PVR] = 0x00080100; /* G3 CPU */  
3170 -// env->spr[PVR] = 0x00083100; /* MPC755 (G3 embedded) */  
3171 -// env->spr[PVR] = 0x00070100; /* IBM 750FX */  
3172 - tlb_flush(env, 1);  
3173 -#if defined (DO_SINGLE_STEP)  
3174 - /* Single step trace mode */  
3175 - msr_se = 1;  
3176 -#endif  
3177 - msr_fp = 1; /* Allow floating point exceptions */  
3178 - msr_me = 1; /* Allow machine check exceptions */  
3179 -#if defined(CONFIG_USER_ONLY)  
3180 - msr_pr = 1;  
3181 - cpu_ppc_register(env, 0x00080000);  
3182 -#else  
3183 - env->nip = 0xFFFFFFFC;  
3184 -#endif  
3185 - cpu_single_env = env;  
3186 - return env;  
3187 -}  
3188 -  
3189 -int cpu_ppc_register (CPUPPCState *env, uint32_t pvr)  
3190 -{  
3191 - env->spr[PVR] = pvr;  
3192 - if (create_ppc_proc(ppc_opcodes, env->spr[PVR]) < 0)  
3193 - return -1;  
3194 - init_spr_rights(env->spr[PVR]); 2432 + cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX " " FILL FILL FILL
  2433 + "SDR1 " REGX "\n",
  2434 + env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
3195 2435
3196 - return 0;  
3197 -}  
3198 -  
3199 -void cpu_ppc_close(CPUPPCState *env)  
3200 -{  
3201 - /* Should also remove all opcode tables... */  
3202 - free(env); 2436 +#undef REGX
  2437 +#undef RGPL
  2438 +#undef RFPL
  2439 +#undef FILL
3203 } 2440 }
3204 2441
3205 /*****************************************************************************/ 2442 /*****************************************************************************/
@@ -3219,6 +2456,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, @@ -3219,6 +2456,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3219 ctx.nip = pc_start; 2456 ctx.nip = pc_start;
3220 ctx.tb = tb; 2457 ctx.tb = tb;
3221 ctx.exception = EXCP_NONE; 2458 ctx.exception = EXCP_NONE;
  2459 + ctx.spr_cb = env->spr_cb;
3222 #if defined(CONFIG_USER_ONLY) 2460 #if defined(CONFIG_USER_ONLY)
3223 ctx.mem_idx = msr_le; 2461 ctx.mem_idx = msr_le;
3224 #else 2462 #else
@@ -3226,7 +2464,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, @@ -3226,7 +2464,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3226 ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le; 2464 ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
3227 #endif 2465 #endif
3228 ctx.fpu_enabled = msr_fp; 2466 ctx.fpu_enabled = msr_fp;
3229 -#if defined (DO_SINGLE_STEP) 2467 +#if defined (DO_SINGLE_STEP) && 0
3230 /* Single step trace mode */ 2468 /* Single step trace mode */
3231 msr_se = 1; 2469 msr_se = 1;
3232 #endif 2470 #endif
@@ -3264,7 +2502,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, @@ -3264,7 +2502,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3264 } 2502 }
3265 #endif 2503 #endif
3266 ctx.nip += 4; 2504 ctx.nip += 4;
3267 - table = ppc_opcodes; 2505 + table = env->opcodes;
3268 handler = table[opc1(ctx.opcode)]; 2506 handler = table[opc1(ctx.opcode)];
3269 if (is_indirect_opcode(handler)) { 2507 if (is_indirect_opcode(handler)) {
3270 table = ind_table(handler); 2508 table = ind_table(handler);
@@ -3322,9 +2560,13 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, @@ -3322,9 +2560,13 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3322 RET_EXCP(ctxp, EXCP_TRACE, 0); 2560 RET_EXCP(ctxp, EXCP_TRACE, 0);
3323 } 2561 }
3324 /* if we reach a page boundary, stop generation */ 2562 /* if we reach a page boundary, stop generation */
3325 - if ((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) 2563 + if ((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) {
3326 break; 2564 break;
3327 } 2565 }
  2566 +#if defined (DO_SINGLE_STEP)
  2567 + break;
  2568 +#endif
  2569 + }
3328 if (ctx.exception == EXCP_NONE) { 2570 if (ctx.exception == EXCP_NONE) {
3329 gen_op_b((unsigned long)ctx.tb, ctx.nip); 2571 gen_op_b((unsigned long)ctx.tb, ctx.nip);
3330 } else if (ctx.exception != EXCP_BRANCH) { 2572 } else if (ctx.exception != EXCP_BRANCH) {