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 468 ifeq ($(TARGET_ARCH), ppc)
469 469 op.o: op.c op_template.h op_mem.h
470 470 op_helper.o: op_helper_mem.h
  471 +translate.o: translate.c translate_init.c
471 472 endif
472 473  
473 474 ifeq ($(TARGET_ARCH), mips)
... ...
gdbstub.c
... ... @@ -253,14 +253,14 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
253 253 }
254 254 /* nip, msr, ccr, lnk, ctr, xer, mq */
255 255 registers[96] = tswapl(env->nip);
256   - registers[97] = tswapl(_load_msr(env));
  256 + registers[97] = tswapl(do_load_msr(env));
257 257 tmp = 0;
258 258 for (i = 0; i < 8; i++)
259 259 tmp |= env->crf[i] << (32 - ((i + 1) * 4));
260 260 registers[98] = tswapl(tmp);
261 261 registers[99] = tswapl(env->lr);
262 262 registers[100] = tswapl(env->ctr);
263   - registers[101] = tswapl(_load_xer(env));
  263 + registers[101] = tswapl(do_load_xer(env));
264 264 registers[102] = 0;
265 265  
266 266 return 103 * 4;
... ... @@ -282,13 +282,13 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
282 282 }
283 283 /* nip, msr, ccr, lnk, ctr, xer, mq */
284 284 env->nip = tswapl(registers[96]);
285   - _store_msr(env, tswapl(registers[97]));
  285 + do_store_msr(env, tswapl(registers[97]));
286 286 registers[98] = tswapl(registers[98]);
287 287 for (i = 0; i < 8; i++)
288 288 env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
289 289 env->lr = tswapl(registers[99]);
290 290 env->ctr = tswapl(registers[100]);
291   - _store_xer(env, tswapl(registers[101]));
  291 + do_store_xer(env, tswapl(registers[101]));
292 292 }
293 293 #elif defined (TARGET_SPARC)
294 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 235 int ret, linux_boot, i;
236 236 unsigned long bios_offset;
237 237 uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
  238 + ppc_def_t *def;
238 239 PCIBus *pci_bus;
239 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 287 initrd_size = 0;
287 288 }
288 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 310 /* Set time-base frequency to 10 Mhz */
291 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 527 int ret, linux_boot, i, nb_nics1;
528 528 unsigned long bios_offset;
529 529 uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
  530 + ppc_def_t *def;
530 531 PCIBus *pci_bus;
531 532  
532 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 583 }
583 584  
584 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 594 /* Set time-base frequency to 100 Mhz */
587 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 700 info._sifields._sigfault._addr = env->nip - 4;
701 701 queue_signal(info.si_signo, &info);
702 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 705 if (loglevel) {
705 706 fprintf(logfile, "Invalid data memory access: 0x%08x\n",
706   - env->spr[DAR]);
  707 + env->spr[SPR_DAR]);
707 708 }
708 709 switch (env->error_code & 0xF) {
709 710 case EXCP_DSI_TRANSLATE:
... ... @@ -1243,7 +1244,25 @@ int main(int argc, char **argv)
1243 1244 }
1244 1245 #elif defined(TARGET_PPC)
1245 1246 {
  1247 + ppc_def_t *def;
1246 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 1266 for (i = 0; i < 32; i++) {
1248 1267 if (i != 12 && i != 6 && i != 13)
1249 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 6 * This library is free software; you can redistribute it and/or
7 7 * modify it under the terms of the GNU Lesser General Public
... ... @@ -20,64 +20,403 @@
20 20 #if !defined (__CPU_PPC_H__)
21 21 #define __CPU_PPC_H__
22 22  
  23 +#include "config.h"
  24 +
23 25 #define TARGET_LONG_BITS 32
24 26  
25 27 #include "cpu-defs.h"
26 28  
27   -#include "config.h"
28 29 #include <setjmp.h>
29 30  
30 31 #include "softfloat.h"
31 32  
32 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 148 /* Instruction types */
35 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 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 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 420 #define msr_ile env->msr[MSR_ILE]
82 421 #define msr_ee env->msr[MSR_EE]
83 422 #define msr_pr env->msr[MSR_PR]
... ... @@ -85,58 +424,72 @@ typedef struct ppc_tb_t ppc_tb_t;
85 424 #define msr_me env->msr[MSR_ME]
86 425 #define msr_fe0 env->msr[MSR_FE0]
87 426 #define msr_se env->msr[MSR_SE]
  427 +#define msr_dwe env->msr[MSR_DWE]
88 428 #define msr_be env->msr[MSR_BE]
  429 +#define msr_de env->msr[MSR_DE]
89 430 #define msr_fe1 env->msr[MSR_FE1]
  431 +#define msr_al env->msr[MSR_AL]
90 432 #define msr_ip env->msr[MSR_IP]
91 433 #define msr_ir env->msr[MSR_IR]
  434 +#define msr_is env->msr[MSR_IS]
92 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 441 #define msr_ri env->msr[MSR_RI]
94 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 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 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 467 /* Reservation address */
108   - uint32_t reserve;
  468 + target_ulong reserve;
  469 +
  470 + /* Those ones are used in supervisor mode only */
109 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 477 /* temporary float registers */
126 478 float64 ft0;
127 479 float64 ft1;
128 480 float64 ft2;
129 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 491 int access_type; /* when a memory exception occurs, the access
136 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 493 /* in order to avoid passing too many arguments to the memory
141 494 write helpers, we store some rarely used information in the CPU
142 495 context) */
... ... @@ -144,17 +497,71 @@ typedef struct CPUPPCState {
144 497 written */
145 498 unsigned long mem_write_vaddr; /* target virtual addr at which the
146 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 520 /* Time base and decrementer */
157 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 566 /* Power management */
160 567 int power_mode;
... ... @@ -164,8 +571,9 @@ typedef struct CPUPPCState {
164 571  
165 572 /* user data */
166 573 void *opaque;
167   -} CPUPPCState;
  574 +};
168 575  
  576 +/*****************************************************************************/
169 577 CPUPPCState *cpu_ppc_init(void);
170 578 int cpu_ppc_exec(CPUPPCState *s);
171 579 void cpu_ppc_close(CPUPPCState *s);
... ... @@ -181,12 +589,38 @@ void cpu_loop_exit(void);
181 589  
182 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 625 /* Time-base and decrementer management */
192 626 #ifndef NO_CPU_IO_DEFS
... ... @@ -201,132 +635,276 @@ void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value);
201 635 #define TARGET_PAGE_BITS 12
202 636 #include "cpu-all.h"
203 637  
  638 +/*****************************************************************************/
  639 +/* Registers definitions */
204 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 642 #define XER_SO 31
216 643 #define XER_OV 30
217 644 #define XER_CA 29
  645 +#define XER_CMP 8
218 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 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 909 /* Memory access type :
332 910 * may be needed for precise access rights control and precise exceptions.
... ... @@ -348,7 +926,7 @@ enum {
348 926 /* Exceptions */
349 927 enum {
350 928 EXCP_NONE = -1,
351   - /* PPC hardware exceptions : exception vector / 0x100 */
  929 + /* PowerPC hardware exceptions : exception vector / 0x100 */
352 930 EXCP_RESET = 0x01, /* System reset */
353 931 EXCP_MACHINE_CHECK = 0x02, /* Machine check exception */
354 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 6 * This library is free software; you can redistribute it and/or
7 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 119 void do_raise_exception_err (uint32_t exception, int error_code);
120 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 122 void do_sraw(void);
132 123  
133 124 void do_fctiw (void);
... ... @@ -143,20 +134,9 @@ void do_fcmpo (void);
143 134  
144 135 void do_check_reservation (void);
145 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 137 void do_tlbia (void);
150 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 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 6 * This library is free software; you can redistribute it and/or
7 7 * modify it under the terms of the GNU Lesser General Public
... ... @@ -26,7 +26,7 @@
26 26 //#define ACCURATE_TLB_FLUSH
27 27  
28 28 /*****************************************************************************/
29   -/* PPC MMU emulation */
  29 +/* PowerPC MMU emulation */
30 30  
31 31 /* Perform BAT hit & translation */
32 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 580 if (rw)
581 581 error_code |= EXCP_DSI_STORE;
582 582 /* Store fault address */
583   - env->spr[DAR] = address;
  583 + env->spr[SPR_DAR] = address;
584 584 }
585 585 #if 0
586 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 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 805 return (xer_so << XER_SO) |
599 806 (xer_ov << XER_OV) |
600 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 814 xer_so = (value >> XER_SO) & 0x01;
607 815 xer_ov = (value >> XER_OV) & 0x01;
608 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 829 (msr_ile << MSR_ILE) |
616 830 (msr_ee << MSR_EE) |
617 831 (msr_pr << MSR_PR) |
... ... @@ -621,41 +835,141 @@ uint32_t _load_msr (CPUState *env)
621 835 (msr_se << MSR_SE) |
622 836 (msr_be << MSR_BE) |
623 837 (msr_fe1 << MSR_FE1) |
  838 + (msr_al << MSR_AL) |
624 839 (msr_ip << MSR_IP) |
625 840 (msr_ir << MSR_IR) |
626 841 (msr_dr << MSR_DR) |
  842 + (msr_pe << MSR_PE) |
  843 + (msr_px << MSR_PX) |
627 844 (msr_ri << MSR_RI) |
628 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 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 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 973 #if defined (CONFIG_USER_ONLY)
660 974 void do_interrupt (CPUState *env)
661 975 {
... ... @@ -675,7 +989,7 @@ void do_interrupt (CPUState *env)
675 989 int excp;
676 990  
677 991 excp = env->exception_index;
678   - msr = _load_msr(env);
  992 + msr = do_load_msr(env);
679 993 #if defined (DEBUG_EXCEPTIONS)
680 994 if ((excp == EXCP_PROGRAM || excp == EXCP_DSI) && msr_pr == 1)
681 995 {
... ... @@ -715,29 +1029,29 @@ void do_interrupt (CPUState *env)
715 1029 * when the fault has been detected
716 1030 */
717 1031 msr &= ~0xFFFF0000;
718   - env->spr[DSISR] = 0;
  1032 + env->spr[SPR_DSISR] = 0;
719 1033 if ((env->error_code & 0x0f) == EXCP_DSI_TRANSLATE)
720   - env->spr[DSISR] |= 0x40000000;
  1034 + env->spr[SPR_DSISR] |= 0x40000000;
721 1035 else if ((env->error_code & 0x0f) == EXCP_DSI_PROT)
722   - env->spr[DSISR] |= 0x08000000;
  1036 + env->spr[SPR_DSISR] |= 0x08000000;
723 1037 else if ((env->error_code & 0x0f) == EXCP_DSI_NOTSUP) {
724   - env->spr[DSISR] |= 0x80000000;
  1038 + env->spr[SPR_DSISR] |= 0x80000000;
725 1039 if (env->error_code & EXCP_DSI_DIRECT)
726   - env->spr[DSISR] |= 0x04000000;
  1040 + env->spr[SPR_DSISR] |= 0x04000000;
727 1041 }
728 1042 if (env->error_code & EXCP_DSI_STORE)
729   - env->spr[DSISR] |= 0x02000000;
  1043 + env->spr[SPR_DSISR] |= 0x02000000;
730 1044 if ((env->error_code & 0xF) == EXCP_DSI_DABR)
731   - env->spr[DSISR] |= 0x00400000;
  1045 + env->spr[SPR_DSISR] |= 0x00400000;
732 1046 if (env->error_code & EXCP_DSI_ECXW)
733   - env->spr[DSISR] |= 0x00100000;
  1047 + env->spr[SPR_DSISR] |= 0x00100000;
734 1048 #if defined (DEBUG_EXCEPTIONS)
735 1049 if (loglevel) {
736 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 1052 } else {
739 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 1056 #endif
743 1057 goto store_next;
... ... @@ -777,7 +1091,7 @@ void do_interrupt (CPUState *env)
777 1091 case EXCP_ALIGN:
778 1092 /* Store exception cause */
779 1093 /* Get rS/rD and rA from faulting opcode */
780   - env->spr[DSISR] |=
  1094 + env->spr[SPR_DSISR] |=
781 1095 (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
782 1096 /* data location address has been stored
783 1097 * when the fault has been detected
... ... @@ -858,14 +1172,14 @@ void do_interrupt (CPUState *env)
858 1172 return;
859 1173 store_current:
860 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 1176 break;
863 1177 store_next:
864 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 1180 break;
867 1181 }
868   - env->spr[SRR1] = msr;
  1182 + env->spr[SPR_SRR1] = msr;
869 1183 /* reload MSR with correct bits */
870 1184 msr_pow = 0;
871 1185 msr_ee = 0;
... ... @@ -879,6 +1193,7 @@ void do_interrupt (CPUState *env)
879 1193 msr_dr = 0;
880 1194 msr_ri = 0;
881 1195 msr_le = msr_ile;
  1196 + do_compute_hflags(env);
882 1197 /* Jump to handler */
883 1198 env->nip = excp << 8;
884 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 6 * This library is free software; you can redistribute it and/or
7 7 * modify it under the terms of the GNU Lesser General Public
... ... @@ -130,7 +130,7 @@
130 130 #define REG 31
131 131 #include "op_template.h"
132 132  
133   -/* PPC state maintenance operations */
  133 +/* PowerPC state maintenance operations */
134 134 /* set_Rc0 */
135 135 PPC_OP(set_Rc0)
136 136 {
... ... @@ -223,7 +223,7 @@ PPC_OP(load_srin)
223 223  
224 224 PPC_OP(store_srin)
225 225 {
226   - do_store_sr(T1 >> 28);
  226 + do_store_sr(env, ((uint32_t)T1 >> 28), T0);
227 227 RETURN();
228 228 }
229 229  
... ... @@ -235,7 +235,7 @@ PPC_OP(load_sdr1)
235 235  
236 236 PPC_OP(store_sdr1)
237 237 {
238   - regs->sdr1 = T0;
  238 + do_store_sdr1(env, T0);
239 239 RETURN();
240 240 }
241 241  
... ... @@ -247,13 +247,13 @@ PPC_OP(exit_tb)
247 247 /* Load/store special registers */
248 248 PPC_OP(load_cr)
249 249 {
250   - do_load_cr();
  250 + T0 = do_load_cr(env);
251 251 RETURN();
252 252 }
253 253  
254 254 PPC_OP(store_cr)
255 255 {
256   - do_store_cr(PARAM(1));
  256 + do_store_cr(env, T0, PARAM(1));
257 257 RETURN();
258 258 }
259 259  
... ... @@ -279,25 +279,25 @@ PPC_OP(load_xer_bc)
279 279  
280 280 PPC_OP(load_xer)
281 281 {
282   - do_load_xer();
  282 + T0 = do_load_xer(env);
283 283 RETURN();
284 284 }
285 285  
286 286 PPC_OP(store_xer)
287 287 {
288   - do_store_xer();
  288 + do_store_xer(env, T0);
289 289 RETURN();
290 290 }
291 291  
292 292 PPC_OP(load_msr)
293 293 {
294   - do_load_msr();
  294 + T0 = do_load_msr(env);
295 295 RETURN();
296 296 }
297 297  
298 298 PPC_OP(store_msr)
299 299 {
300   - do_store_msr();
  300 + do_store_msr(env, T0);
301 301 RETURN();
302 302 }
303 303  
... ... @@ -378,9 +378,20 @@ PPC_OP(load_ibat)
378 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 397 PPC_OP(load_dbat)
... ... @@ -388,21 +399,32 @@ PPC_OP(load_dbat)
388 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 418 /* FPSCR */
397 419 PPC_OP(load_fpscr)
398 420 {
399   - do_load_fpscr();
  421 + FT0 = do_load_fpscr(env);
400 422 RETURN();
401 423 }
402 424  
403 425 PPC_OP(store_fpscr)
404 426 {
405   - do_store_fpscr(PARAM(1));
  427 + do_store_fpscr(env, FT0, PARAM1);
406 428 RETURN();
407 429 }
408 430  
... ... @@ -1362,17 +1384,13 @@ PPC_OP(check_reservation)
1362 1384 /* Return from interrupt */
1363 1385 PPC_OP(rfi)
1364 1386 {
1365   - regs->nip = regs->spr[SRR0] & ~0x00000003;
  1387 + regs->nip = regs->spr[SPR_SRR0] & ~0x00000003;
1366 1388 #if 1 // TRY
1367   - T0 = regs->spr[SRR1] & ~0xFFF00000;
  1389 + T0 = regs->spr[SPR_SRR1] & ~0xFFF00000;
1368 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 1392 #endif
1375   - // do_tlbia();
  1393 + do_store_msr(env, T0);
1376 1394 do_raise_exception(EXCP_RFI);
1377 1395 RETURN();
1378 1396 }
... ... @@ -1420,3 +1438,9 @@ PPC_OP(tlbie)
1420 1438 do_tlbie();
1421 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 6 * This library is free software; you can redistribute it and/or
7 7 * modify it under the terms of the GNU Lesser General Public
... ... @@ -67,91 +67,6 @@ void do_raise_exception (uint32_t exception)
67 67  
68 68 /*****************************************************************************/
69 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 70 /* shift right arithmetic helper */
156 71 void do_sraw (void)
157 72 {
... ... @@ -175,77 +90,6 @@ void do_sraw (void)
175 90 }
176 91  
177 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 93 void do_fctiw (void)
250 94 {
251 95 union {
... ... @@ -254,7 +98,7 @@ void do_fctiw (void)
254 98 } p;
255 99  
256 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 103 p.i = float64_to_int32(FT0, &env->fp_status);
260 104 p.i |= 0xFFF80000ULL << 32;
... ... @@ -269,7 +113,7 @@ void do_fctiwz (void)
269 113 } p;
270 114  
271 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 118 p.i = float64_to_int32_round_to_zero(FT0, &env->fp_status);
275 119 p.i |= 0xFFF80000ULL << 32;
... ... @@ -455,116 +299,3 @@ void do_tlbie (void)
455 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 6 * This library is free software; you can redistribute it and/or
7 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 175  
176 176 void OPPROTO glue(op_store_sr, REG)(void)
177 177 {
178   - do_store_sr(REG);
  178 + do_store_sr(env, REG, T0);
179 179 RETURN();
180 180 }
181 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 6 * This library is free software; you can redistribute it and/or
7 7 * modify it under the terms of the GNU Lesser General Public
... ... @@ -141,16 +141,17 @@ typedef struct DisasContext {
141 141 int supervisor;
142 142 #endif
143 143 int fpu_enabled;
  144 + ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
144 145 } DisasContext;
145 146  
146   -typedef struct opc_handler_t {
  147 +struct opc_handler_t {
147 148 /* invalid bits */
148 149 uint32_t inval;
149 150 /* instruction type */
150 151 uint32_t type;
151 152 /* handler */
152 153 void (*handler)(DisasContext *ctx);
153   -} opc_handler_t;
  154 +};
154 155  
155 156 #define RET_EXCP(ctx, excp, error) \
156 157 do { \
... ... @@ -173,6 +174,11 @@ RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG)
173 174 #define RET_MTMSR(ctx) \
174 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 182 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
177 183 static void gen_##name (DisasContext *ctx); \
178 184 GEN_OPCODE(name, opc1, opc2, opc3, inval, type); \
... ... @@ -186,6 +192,7 @@ typedef struct opcode_t {
186 192 unsigned char pad[1];
187 193 #endif
188 194 opc_handler_t handler;
  195 + const unsigned char *oname;
189 196 } opcode_t;
190 197  
191 198 /*** Instruction decoding ***/
... ... @@ -226,7 +233,13 @@ EXTRACT_HELPER(crbD, 21, 5);
226 233 EXTRACT_HELPER(crbA, 16, 5);
227 234 EXTRACT_HELPER(crbB, 11, 5);
228 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 243 /*** Get constants ***/
231 244 EXTRACT_HELPER(IMM, 12, 8);
232 245 /* 16 bits signed immediate value */
... ... @@ -282,12 +295,17 @@ static inline uint32_t MASK (uint32_t start, uint32_t end)
282 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 303 #if defined(__APPLE__)
286 304 #define OPCODES_SECTION \
287   - __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (8) ))
  305 + __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
288 306 #else
289 307 #define OPCODES_SECTION \
290   - __attribute__ ((section(".opcodes"), unused, aligned (8) ))
  308 + __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
291 309 #endif
292 310  
293 311 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \
... ... @@ -301,6 +319,7 @@ OPCODES_SECTION opcode_t opc_##name = { \
301 319 .type = _typ, \
302 320 .handler = &gen_##name, \
303 321 }, \
  322 + .oname = stringify(name), \
304 323 }
305 324  
306 325 #define GEN_OPCODE_MARK(name) \
... ... @@ -314,6 +333,7 @@ OPCODES_SECTION opcode_t opc_##name = { \
314 333 .type = 0x00, \
315 334 .handler = NULL, \
316 335 }, \
  336 + .oname = stringify(name), \
317 337 }
318 338  
319 339 /* Start opcode list */
... ... @@ -1344,7 +1364,7 @@ static GenOpFunc1 *gen_op_stsw[] = {
1344 1364 #endif
1345 1365  
1346 1366 /* lswi */
1347   -/* PPC32 specification says we must generate an exception if
  1367 +/* PowerPC32 specification says we must generate an exception if
1348 1368 * rA is in the range of registers to be loaded.
1349 1369 * In an other hand, IBM says this is valid, but rA won't be loaded.
1350 1370 * For now, I'll follow the spec...
... ... @@ -1965,169 +1985,54 @@ GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
1965 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 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 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 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 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 2038 /* mtcrf */
... ... @@ -2158,184 +2063,28 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
2158 2063 /* mtspr */
2159 2064 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
2160 2065 {
  2066 + void (*write_cb)(void *opaque, int sprn);
2161 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 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 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 2263 /*** Lookaside buffer management ***/
2515 2264 /* Optional & supervisor only: */
2516 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 2268 #if defined(CONFIG_USER_ONLY)
2520 2269 RET_PRIVOPC(ctx);
... ... @@ -2624,510 +2373,41 @@ GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
2624 2373 /* End opcode list */
2625 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 2380 void cpu_dump_state(CPUState *env, FILE *f,
3115 2381 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
3116 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 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 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 2408 cpu_fprintf(f, "\n");
3129 2409 }
3130   - cpu_fprintf(f, "CR: 0x");
  2410 + cpu_fprintf(f, "CR ");
3131 2411 for (i = 0; i < 8; i++)
3132 2412 cpu_fprintf(f, "%01x", env->crf[i]);
3133 2413 cpu_fprintf(f, " [");
... ... @@ -3141,65 +2421,22 @@ void cpu_dump_state(CPUState *env, FILE *f,
3141 2421 a = 'E';
3142 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 2428 cpu_fprintf(f, " %016llx", *((uint64_t *)&env->fpr[i]));
3151   - if ((i & 3) == 3)
  2429 + if ((i & (RFPL - 1)) == (RFPL - 1))
3152 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 2456 ctx.nip = pc_start;
3220 2457 ctx.tb = tb;
3221 2458 ctx.exception = EXCP_NONE;
  2459 + ctx.spr_cb = env->spr_cb;
3222 2460 #if defined(CONFIG_USER_ONLY)
3223 2461 ctx.mem_idx = msr_le;
3224 2462 #else
... ... @@ -3226,7 +2464,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3226 2464 ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
3227 2465 #endif
3228 2466 ctx.fpu_enabled = msr_fp;
3229   -#if defined (DO_SINGLE_STEP)
  2467 +#if defined (DO_SINGLE_STEP) && 0
3230 2468 /* Single step trace mode */
3231 2469 msr_se = 1;
3232 2470 #endif
... ... @@ -3264,7 +2502,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3264 2502 }
3265 2503 #endif
3266 2504 ctx.nip += 4;
3267   - table = ppc_opcodes;
  2505 + table = env->opcodes;
3268 2506 handler = table[opc1(ctx.opcode)];
3269 2507 if (is_indirect_opcode(handler)) {
3270 2508 table = ind_table(handler);
... ... @@ -3322,9 +2560,13 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3322 2560 RET_EXCP(ctxp, EXCP_TRACE, 0);
3323 2561 }
3324 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 2564 break;
3327 2565 }
  2566 +#if defined (DO_SINGLE_STEP)
  2567 + break;
  2568 +#endif
  2569 + }
3328 2570 if (ctx.exception == EXCP_NONE) {
3329 2571 gen_op_b((unsigned long)ctx.tb, ctx.nip);
3330 2572 } else if (ctx.exception != EXCP_BRANCH) {
... ...