Commit 76a66253e5e48f1744f689041c1c21cedcaff630

Authored by j_mayer
1 parent 1c7b3754

Great PowerPC emulation code resynchronisation and improvments:

- Add status file to make regression tracking easier
- Move all micro-operations helpers definitions into a separate header:
  should never be seen outside of op.c
- Update copyrights
- Add new / missing PowerPC CPU definitions
- Add definitions for PowerPC BookE
- Add support for PowerPC 6xx/7xx software driven TLBs
  Allow use of PowerPC 603 as an example
- Add preliminary code for POWER, POWER2, PowerPC 403, 405, 440, 601, 602
  and BookE support
- Avoid compiling priviledged only resources support for user-mode emulation
- Remove unused helpers / micro-ops / dead code
- Add instructions usage statistics dump: useful to figure which instructions
  need strong optimizations.
- Micro-operation fixes:
  * add missing RETURN in some micro-ops
  * fix prototypes
  * use softfloat routines for all floating-point operations
  * fix tlbie instruction
  * move some huge micro-operations into helpers
- emulation fixes:
  * fix inverted opcodes for fcmpo / fcmpu
  * condition register update is always to be done after the whole
    instruction has completed
  * add missing NIP updates when calling helpers that may generate an
    exception
- optimizations and improvments:
  * optimize very often used instructions (li, mr, rlwixx...)
  * remove specific micro-ops for rarely used instructions
  * add routines for addresses computations to avoid bugs due to multiple
    different implementations
  * fix TB linking: do not reset T0 at the end of every TB.


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

Too many changes to show.

To preserve performance only 12 of 19 files are displayed.

cpu-all.h
@@ -759,6 +759,9 @@ CPUState *cpu_copy(CPUState *env); @@ -759,6 +759,9 @@ CPUState *cpu_copy(CPUState *env);
759 void cpu_dump_state(CPUState *env, FILE *f, 759 void cpu_dump_state(CPUState *env, FILE *f,
760 int (*cpu_fprintf)(FILE *f, const char *fmt, ...), 760 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
761 int flags); 761 int flags);
  762 +void cpu_dump_statistics (CPUState *env, FILE *f,
  763 + int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
  764 + int flags);
762 765
763 void cpu_abort(CPUState *env, const char *fmt, ...); 766 void cpu_abort(CPUState *env, const char *fmt, ...);
764 extern CPUState *first_cpu; 767 extern CPUState *first_cpu;
gdbstub.c
@@ -307,7 +307,7 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) @@ -307,7 +307,7 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
307 registers[98] = tswapl(tmp); 307 registers[98] = tswapl(tmp);
308 registers[99] = tswapl(env->lr); 308 registers[99] = tswapl(env->lr);
309 registers[100] = tswapl(env->ctr); 309 registers[100] = tswapl(env->ctr);
310 - registers[101] = tswapl(do_load_xer(env)); 310 + registers[101] = tswapl(ppc_load_xer(env));
311 registers[102] = 0; 311 registers[102] = 0;
312 312
313 return 103 * 4; 313 return 103 * 4;
@@ -335,7 +335,7 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) @@ -335,7 +335,7 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
335 env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF; 335 env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
336 env->lr = tswapl(registers[99]); 336 env->lr = tswapl(registers[99]);
337 env->ctr = tswapl(registers[100]); 337 env->ctr = tswapl(registers[100]);
338 - do_store_xer(env, tswapl(registers[101])); 338 + ppc_store_xer(env, tswapl(registers[101]));
339 } 339 }
340 #elif defined (TARGET_SPARC) 340 #elif defined (TARGET_SPARC)
341 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) 341 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
hw/ppc.c
1 /* 1 /*
2 * QEMU generic PPC hardware System Emulator 2 * QEMU generic PPC hardware System Emulator
3 * 3 *
4 - * Copyright (c) 2003-2004 Jocelyn Mayer 4 + * Copyright (c) 2003-2007 Jocelyn Mayer
5 * 5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy 6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal 7 * of this software and associated documentation files (the "Software"), to deal
@@ -41,7 +41,7 @@ static inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env) @@ -41,7 +41,7 @@ static inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env)
41 { 41 {
42 /* TB time in tb periods */ 42 /* TB time in tb periods */
43 return muldiv64(qemu_get_clock(vm_clock) + tb_env->tb_offset, 43 return muldiv64(qemu_get_clock(vm_clock) + tb_env->tb_offset,
44 - tb_env->tb_freq, ticks_per_sec); 44 + tb_env->tb_freq, ticks_per_sec);
45 } 45 }
46 46
47 uint32_t cpu_ppc_load_tbl (CPUState *env) 47 uint32_t cpu_ppc_load_tbl (CPUState *env)
@@ -52,14 +52,14 @@ uint32_t cpu_ppc_load_tbl (CPUState *env) @@ -52,14 +52,14 @@ uint32_t cpu_ppc_load_tbl (CPUState *env)
52 tb = cpu_ppc_get_tb(tb_env); 52 tb = cpu_ppc_get_tb(tb_env);
53 #ifdef DEBUG_TB 53 #ifdef DEBUG_TB
54 { 54 {
55 - static int last_time;  
56 - int now;  
57 - now = time(NULL);  
58 - if (last_time != now) {  
59 - last_time = now;  
60 - printf("%s: tb=0x%016lx %d %08lx\n",  
61 - __func__, tb, now, tb_env->tb_offset);  
62 - } 55 + static int last_time;
  56 + int now;
  57 + now = time(NULL);
  58 + if (last_time != now) {
  59 + last_time = now;
  60 + printf("%s: tb=0x%016lx %d %08lx\n",
  61 + __func__, tb, now, tb_env->tb_offset);
  62 + }
63 } 63 }
64 #endif 64 #endif
65 65
@@ -75,6 +75,7 @@ uint32_t cpu_ppc_load_tbu (CPUState *env) @@ -75,6 +75,7 @@ uint32_t cpu_ppc_load_tbu (CPUState *env)
75 #ifdef DEBUG_TB 75 #ifdef DEBUG_TB
76 printf("%s: tb=0x%016lx\n", __func__, tb); 76 printf("%s: tb=0x%016lx\n", __func__, tb);
77 #endif 77 #endif
  78 +
78 return tb >> 32; 79 return tb >> 32;
79 } 80 }
80 81
@@ -117,6 +118,7 @@ uint32_t cpu_ppc_load_decr (CPUState *env) @@ -117,6 +118,7 @@ uint32_t cpu_ppc_load_decr (CPUState *env)
117 #if defined(DEBUG_TB) 118 #if defined(DEBUG_TB)
118 printf("%s: 0x%08x\n", __func__, decr); 119 printf("%s: 0x%08x\n", __func__, decr);
119 #endif 120 #endif
  121 +
120 return decr; 122 return decr;
121 } 123 }
122 124
@@ -146,7 +148,7 @@ static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr, @@ -146,7 +148,7 @@ static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
146 if (is_excp) 148 if (is_excp)
147 next += tb_env->decr_next - now; 149 next += tb_env->decr_next - now;
148 if (next == now) 150 if (next == now)
149 - next++; 151 + next++;
150 tb_env->decr_next = next; 152 tb_env->decr_next = next;
151 /* Adjust timer */ 153 /* Adjust timer */
152 qemu_mod_timer(tb_env->decr_timer, next); 154 qemu_mod_timer(tb_env->decr_timer, next);
@@ -154,7 +156,7 @@ static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr, @@ -154,7 +156,7 @@ static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
154 * raise an exception. 156 * raise an exception.
155 */ 157 */
156 if ((value & 0x80000000) && !(decr & 0x80000000)) 158 if ((value & 0x80000000) && !(decr & 0x80000000))
157 - cpu_ppc_decr_excp(env); 159 + cpu_ppc_decr_excp(env);
158 } 160 }
159 161
160 void cpu_ppc_store_decr (CPUState *env, uint32_t value) 162 void cpu_ppc_store_decr (CPUState *env, uint32_t value)
@@ -177,20 +179,64 @@ ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq) @@ -177,20 +179,64 @@ ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq)
177 return NULL; 179 return NULL;
178 env->tb_env = tb_env; 180 env->tb_env = tb_env;
179 if (tb_env->tb_freq == 0 || 1) { 181 if (tb_env->tb_freq == 0 || 1) {
180 - tb_env->tb_freq = freq;  
181 - /* Create new timer */  
182 - tb_env->decr_timer = 182 + tb_env->tb_freq = freq;
  183 + /* Create new timer */
  184 + tb_env->decr_timer =
183 qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env); 185 qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env);
184 - /* There is a bug in 2.4 kernels:  
185 - * if a decrementer exception is pending when it enables msr_ee,  
186 - * it's not ready to handle it...  
187 - */  
188 - _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0); 186 + /* There is a bug in Linux 2.4 kernels:
  187 + * if a decrementer exception is pending when it enables msr_ee,
  188 + * it's not ready to handle it...
  189 + */
  190 + _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
189 } 191 }
190 192
191 return tb_env; 193 return tb_env;
192 } 194 }
193 195
  196 +/* Specific helpers for POWER & PowerPC 601 RTC */
  197 +ppc_tb_t *cpu_ppc601_rtc_init (CPUState *env)
  198 +{
  199 + return cpu_ppc_tb_init(env, 7812500);
  200 +}
  201 +
  202 +void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value)
  203 +__attribute__ (( alias ("cpu_ppc_store_tbu") ));
  204 +
  205 +uint32_t cpu_ppc601_load_rtcu (CPUState *env)
  206 +__attribute__ (( alias ("cpu_ppc_load_tbu") ));
  207 +
  208 +void cpu_ppc601_store_rtcl (CPUState *env, uint32_t value)
  209 +{
  210 + cpu_ppc_store_tbl(env, value & 0x3FFFFF80);
  211 +}
  212 +
  213 +uint32_t cpu_ppc601_load_rtcl (CPUState *env)
  214 +{
  215 + return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
  216 +}
  217 +
  218 +/* Embedded PowerPC timers */
  219 +target_ulong load_40x_pit (CPUState *env)
  220 +{
  221 + /* XXX: TODO */
  222 + return 0;
  223 +}
  224 +
  225 +void store_40x_pit (CPUState *env, target_ulong val)
  226 +{
  227 + /* XXX: TODO */
  228 +}
  229 +
  230 +void store_booke_tcr (CPUState *env, target_ulong val)
  231 +{
  232 + /* XXX: TODO */
  233 +}
  234 +
  235 +void store_booke_tsr (CPUState *env, target_ulong val)
  236 +{
  237 + /* XXX: TODO */
  238 +}
  239 +
194 #if 0 240 #if 0
195 /*****************************************************************************/ 241 /*****************************************************************************/
196 /* Handle system reset (for now, just stop emulation) */ 242 /* Handle system reset (for now, just stop emulation) */
@@ -264,6 +310,7 @@ uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr) @@ -264,6 +310,7 @@ uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr)
264 tmp |= m48t59_read(nvram, addr + 1) << 16; 310 tmp |= m48t59_read(nvram, addr + 1) << 16;
265 tmp |= m48t59_read(nvram, addr + 2) << 8; 311 tmp |= m48t59_read(nvram, addr + 2) << 8;
266 tmp |= m48t59_read(nvram, addr + 3); 312 tmp |= m48t59_read(nvram, addr + 3);
  313 +
267 return tmp; 314 return tmp;
268 } 315 }
269 316
@@ -316,10 +363,10 @@ uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count) @@ -316,10 +363,10 @@ uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count)
316 odd = count & 1; 363 odd = count & 1;
317 count &= ~1; 364 count &= ~1;
318 for (i = 0; i != count; i++) { 365 for (i = 0; i != count; i++) {
319 - crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i)); 366 + crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
320 } 367 }
321 if (odd) { 368 if (odd) {
322 - crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8); 369 + crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
323 } 370 }
324 371
325 return crc; 372 return crc;
linux-user/main.c
@@ -670,18 +670,23 @@ void cpu_ppc_store_tbl (CPUState *env, uint32_t value) @@ -670,18 +670,23 @@ void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
670 { 670 {
671 cpu_ppc_store_tb(env, ((uint64_t)cpu_ppc_load_tbl(env) << 32) | value); 671 cpu_ppc_store_tb(env, ((uint64_t)cpu_ppc_load_tbl(env) << 32) | value);
672 } 672 }
673 -  
674 -uint32_t cpu_ppc_load_decr (CPUState *env) 673 +
  674 +void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value)
  675 +__attribute__ (( alias ("cpu_ppc_store_tbu") ));
  676 +
  677 +uint32_t cpu_ppc601_load_rtcu (CPUState *env)
  678 +__attribute__ (( alias ("cpu_ppc_load_tbu") ));
  679 +
  680 +void cpu_ppc601_store_rtcl (CPUState *env, uint32_t value)
675 { 681 {
676 - /* TO FIX */  
677 - return -1; 682 + cpu_ppc_store_tbl(env, value & 0x3FFFFF80);
678 } 683 }
679 -  
680 -void cpu_ppc_store_decr (CPUState *env, uint32_t value) 684 +
  685 +uint32_t cpu_ppc601_load_rtcl (CPUState *env)
681 { 686 {
682 - /* TO FIX */ 687 + return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
683 } 688 }
684 - 689 +
685 void cpu_loop(CPUPPCState *env) 690 void cpu_loop(CPUPPCState *env)
686 { 691 {
687 target_siginfo_t info; 692 target_siginfo_t info;
monitor.c
@@ -331,6 +331,17 @@ static void do_info_history (void) @@ -331,6 +331,17 @@ static void do_info_history (void)
331 } 331 }
332 } 332 }
333 333
  334 +#if defined(TARGET_PPC)
  335 +/* XXX: not implemented in other targets */
  336 +static void do_info_cpu_stats (void)
  337 +{
  338 + CPUState *env;
  339 +
  340 + env = mon_get_cpu();
  341 + cpu_dump_statistics(env, NULL, &monitor_fprintf, 0);
  342 +}
  343 +#endif
  344 +
334 static void do_quit(void) 345 static void do_quit(void)
335 { 346 {
336 exit(0); 347 exit(0);
@@ -1303,6 +1314,10 @@ static term_cmd_t info_cmds[] = { @@ -1303,6 +1314,10 @@ static term_cmd_t info_cmds[] = {
1303 "", "show which guest mouse is receiving events" }, 1314 "", "show which guest mouse is receiving events" },
1304 { "vnc", "", do_info_vnc, 1315 { "vnc", "", do_info_vnc,
1305 "", "show the vnc server status"}, 1316 "", "show the vnc server status"},
  1317 +#if defined(TARGET_PPC)
  1318 + { "cpustats", "", do_info_cpu_stats,
  1319 + "", "show CPU statistics", },
  1320 +#endif
1306 { NULL, NULL, }, 1321 { NULL, NULL, },
1307 }; 1322 };
1308 1323
target-ppc/STATUS 0 โ†’ 100644
  1 +PowerPC emulation status.
  2 +The goal of this file is to provide a reference status to avoid regressions.
  3 +
  4 +===============================================================================
  5 +PowerPC core emulation status
  6 +
  7 +PowerPC CPU known to work (ie booting at least Linux 2.4):
  8 +* main stream PowerPC cores
  9 +- PowerPC 603 & derivatives
  10 +- PowerPC 604 & derivatives
  11 +- PowerPC 740 & derivatives
  12 +- PowerPC 750 & derivatives
  13 +
  14 +PowerPC that should work but are not supported by standard Linux kernel
  15 +(then remain mostly untested)
  16 +- PowerPC 745
  17 +- PowerPC 755
  18 +
  19 +Work in progress:
  20 +* embedded PowerPC cores
  21 +- PowerPC 405
  22 +- BookE PowerPC
  23 +- e500 core (Freescale PowerQUICC)
  24 +* main stream PowerPC cores
  25 +- PowerPC 601
  26 +- PowerPC 602
  27 +
  28 +TODO:
  29 +* embedded PowerPC cores
  30 +- PowerPC 401
  31 +- PowerPC 403
  32 +- PowerPC 440
  33 +- PowerPC 460
  34 +* main stream PowerPC cores
  35 +- PowerPC 7400 (aka G4)
  36 +- PowerPC 7410
  37 +- PowerPC 7450
  38 +- PowerPC 7455
  39 +- PowerPC 7457
  40 +- PowerPC 7457A
  41 +* original POWER
  42 +- POWER
  43 +- POWER2
  44 +* 64 bits PowerPC cores
  45 +- PowerPC 620
  46 +- PowerPC 630 (aka POWER3)
  47 +- PowerPC 631 (aka POWER3+)
  48 +- POWER4
  49 +- POWER4+
  50 +- POWER5
  51 +- POWER5+
  52 +- PowerPC 970
  53 +* RS64 series
  54 +- RS64
  55 +- RS64-II
  56 +- RS64-III
  57 +- RS64-IV
  58 +
  59 +===============================================================================
  60 +PowerPC microcontrollers emulation status
  61 +
  62 +TODO:
  63 +- PowerPC 40x microcontrollers emulation
  64 +- PowerQUICC microcontrollers emulation
  65 +
  66 +===============================================================================
  67 +PowerPC based platforms emulation status
  68 +
  69 +* PREP platform (RS/6000 7043...) - TO BE CHECKED (broken)
  70 +- Gentoo Linux live CDROM 1.4
  71 +- Debian Linux 3.0
  72 +- Mandrake Linux 9
  73 +
  74 +* heathrow PowerMac platform (beige PowerMac) - TO BE CHECKED (broken)
  75 +- Gentoo Linux live CDROM 1.4
  76 +- Debian Linux 3.0
  77 +- Mandrake Linux 9
  78 +
  79 +* mac99 platform (white and blue PowerMac, ...)
  80 +- Gentoo Linux live CDROM 1.4 - boots, compiles linux kernel
  81 +- Debian Linux woody - boots from CDROM and HDD
  82 +- Mandrake Linux 9 - boots from CDROM, freezes during install
  83 +
  84 +TODO:
  85 +- MCA based RS/6000 emulation
  86 +- CHRP emulation (not PowerMac)
  87 +- PPAR emulation
  88 +- misc PowerPC reference boards emulation
  89 +
  90 +===============================================================================
  91 +(to be completed)
target-ppc/cpu.h
1 /* 1 /*
2 * PowerPC emulation cpu definitions for qemu. 2 * PowerPC emulation cpu definitions for qemu.
3 * 3 *
4 - * Copyright (c) 2003-2005 Jocelyn Mayer 4 + * Copyright (c) 2003-2007 Jocelyn Mayer
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
@@ -21,8 +21,22 @@ @@ -21,8 +21,22 @@
21 #define __CPU_PPC_H__ 21 #define __CPU_PPC_H__
22 22
23 #include "config.h" 23 #include "config.h"
  24 +#include <stdint.h>
24 25
  26 +#if defined (TARGET_PPC64)
  27 +typedef uint64_t ppc_gpr_t;
  28 +#define TARGET_LONG_BITS 64
  29 +#define REGX "%016" PRIx64
  30 +#elif defined(TARGET_E500)
  31 +/* GPR are 64 bits: used by vector extension */
  32 +typedef uint64_t ppc_gpr_t;
25 #define TARGET_LONG_BITS 32 33 #define TARGET_LONG_BITS 32
  34 +#define REGX "%08" PRIx32
  35 +#else
  36 +typedef uint32_t ppc_gpr_t;
  37 +#define TARGET_LONG_BITS 32
  38 +#define REGX "%08" PRIx32
  39 +#endif
26 40
27 #include "cpu-defs.h" 41 #include "cpu-defs.h"
28 42
@@ -32,7 +46,11 @@ @@ -32,7 +46,11 @@
32 46
33 #define TARGET_HAS_ICE 1 47 #define TARGET_HAS_ICE 1
34 48
35 -#define ELF_MACHINE EM_PPC 49 +#if defined (TARGET_PPC64)
  50 +#define ELF_MACHINE EM_PPC64
  51 +#else
  52 +#define ELF_MACHINE EM_PPC
  53 +#endif
36 54
37 /* XXX: this should be tunable: PowerPC 601 & 64 bits PowerPC 55 /* XXX: this should be tunable: PowerPC 601 & 64 bits PowerPC
38 * have different cache line sizes 56 * have different cache line sizes
@@ -42,6 +60,7 @@ @@ -42,6 +60,7 @@
42 60
43 /* XXX: put this in a common place */ 61 /* XXX: put this in a common place */
44 #define likely(x) __builtin_expect(!!(x), 1) 62 #define likely(x) __builtin_expect(!!(x), 1)
  63 +#define unlikely(x) __builtin_expect(!!(x), 0)
45 64
46 /*****************************************************************************/ 65 /*****************************************************************************/
47 /* PVR definitions for most known PowerPC */ 66 /* PVR definitions for most known PowerPC */
@@ -54,72 +73,155 @@ enum { @@ -54,72 +73,155 @@ enum {
54 CPU_PPC_401E2 = 0x00250000, 73 CPU_PPC_401E2 = 0x00250000,
55 CPU_PPC_401F2 = 0x00260000, 74 CPU_PPC_401F2 = 0x00260000,
56 CPU_PPC_401G2 = 0x00270000, 75 CPU_PPC_401G2 = 0x00270000,
57 - CPU_PPC_IOP480 = 0x40100000, 76 +#define CPU_PPC_401 CPU_PPC_401G2
  77 + CPU_PPC_IOP480 = 0x40100000, /* 401B2 ? */
  78 + CPU_PPC_COBRA = 0x10100000, /* IBM Processor for Network Resources */
58 /* PowerPC 403 cores */ 79 /* PowerPC 403 cores */
59 - CPU_PPC_403GA = 0x00200000, 80 + CPU_PPC_403GA = 0x00200011,
60 CPU_PPC_403GB = 0x00200100, 81 CPU_PPC_403GB = 0x00200100,
61 CPU_PPC_403GC = 0x00200200, 82 CPU_PPC_403GC = 0x00200200,
62 CPU_PPC_403GCX = 0x00201400, 83 CPU_PPC_403GCX = 0x00201400,
  84 +#define CPU_PPC_403 CPU_PPC_403GCX
63 /* PowerPC 405 cores */ 85 /* PowerPC 405 cores */
64 - CPU_PPC_405 = 0x40110000,  
65 - CPU_PPC_405EP = 0x51210000,  
66 - CPU_PPC_405GPR = 0x50910000, 86 + CPU_PPC_405CR = 0x40110145,
  87 +#define CPU_PPC_405GP CPU_PPC_405CR
  88 + CPU_PPC_405EP = 0x51210950,
  89 + CPU_PPC_405GPR = 0x50910951,
67 CPU_PPC_405D2 = 0x20010000, 90 CPU_PPC_405D2 = 0x20010000,
68 CPU_PPC_405D4 = 0x41810000, 91 CPU_PPC_405D4 = 0x41810000,
69 - CPU_PPC_NPE405H = 0x41410000,  
70 - CPU_PPC_NPE405L = 0x41610000, 92 +#define CPU_PPC_405 CPU_PPC_405D4
  93 + CPU_PPC_NPE405H = 0x414100C0,
  94 + CPU_PPC_NPE405H2 = 0x41410140,
  95 + CPU_PPC_NPE405L = 0x416100C0,
  96 + /* XXX: missing 405LP, LC77700 */
  97 + /* IBM STBxxx (PowerPC 401/403/405 core based microcontrollers) */
  98 +#if 0
  99 + CPU_PPC_STB01000 = xxx,
  100 +#endif
71 #if 0 101 #if 0
72 - CPU_PPC_STB02 = xxx, 102 + CPU_PPC_STB01010 = xxx,
  103 +#endif
  104 +#if 0
  105 + CPU_PPC_STB0210 = xxx,
73 #endif 106 #endif
74 CPU_PPC_STB03 = 0x40310000, 107 CPU_PPC_STB03 = 0x40310000,
75 #if 0 108 #if 0
76 - CPU_PPC_STB04 = xxx, 109 + CPU_PPC_STB043 = xxx,
77 #endif 110 #endif
78 - CPU_PPC_STB25 = 0x51510000, 111 +#if 0
  112 + CPU_PPC_STB045 = xxx,
  113 +#endif
  114 + CPU_PPC_STB25 = 0x51510950,
79 #if 0 115 #if 0
80 CPU_PPC_STB130 = xxx, 116 CPU_PPC_STB130 = xxx,
81 #endif 117 #endif
  118 + /* Xilinx cores */
  119 + CPU_PPC_X2VP4 = 0x20010820,
  120 +#define CPU_PPC_X2VP7 CPU_PPC_X2VP4
  121 + CPU_PPC_X2VP20 = 0x20010860,
  122 +#define CPU_PPC_X2VP50 CPU_PPC_X2VP20
82 /* PowerPC 440 cores */ 123 /* PowerPC 440 cores */
83 - CPU_PPC_440EP = 0x42220000,  
84 - CPU_PPC_440GP = 0x40120400,  
85 - CPU_PPC_440GX = 0x51B20000,  
86 - /* PowerPC MPC 8xx cores */  
87 - CPU_PPC_8540 = 0x80200000, 124 + CPU_PPC_440EP = 0x422218D3,
  125 +#define CPU_PPC_440GR CPU_PPC_440EP
  126 + CPU_PPC_440GP = 0x40120481,
  127 + CPU_PPC_440GX = 0x51B21850,
  128 + CPU_PPC_440GXc = 0x51B21892,
  129 + CPU_PPC_440GXf = 0x51B21894,
  130 + CPU_PPC_440SP = 0x53221850,
  131 + CPU_PPC_440SP2 = 0x53221891,
  132 + CPU_PPC_440SPE = 0x53421890,
  133 + /* XXX: missing 440GRX */
  134 + /* PowerPC 460 cores - TODO */
  135 + /* PowerPC MPC 5xx cores */
  136 + CPU_PPC_5xx = 0x00020020,
  137 + /* PowerPC MPC 8xx cores (aka PowerQUICC) */
88 CPU_PPC_8xx = 0x00500000, 138 CPU_PPC_8xx = 0x00500000,
89 - CPU_PPC_8240 = 0x00810100,  
90 - CPU_PPC_8245 = 0x00811014, 139 + /* PowerPC MPC 8xxx cores (aka PowerQUICC-II) */
  140 + CPU_PPC_82xx_HIP3 = 0x00810101,
  141 + CPU_PPC_82xx_HIP4 = 0x80811014,
  142 + CPU_PPC_827x = 0x80822013,
  143 + /* eCores */
  144 + CPU_PPC_e200 = 0x81120000,
  145 + CPU_PPC_e500v110 = 0x80200010,
  146 + CPU_PPC_e500v120 = 0x80200020,
  147 + CPU_PPC_e500v210 = 0x80210010,
  148 + CPU_PPC_e500v220 = 0x80210020,
  149 +#define CPU_PPC_e500 CPU_PPC_e500v220
  150 + CPU_PPC_e600 = 0x80040010,
91 /* PowerPC 6xx cores */ 151 /* PowerPC 6xx cores */
92 - CPU_PPC_601 = 0x00010000,  
93 - CPU_PPC_602 = 0x00050000,  
94 - CPU_PPC_603 = 0x00030000,  
95 - CPU_PPC_603E = 0x00060000,  
96 - CPU_PPC_603EV = 0x00070000,  
97 - CPU_PPC_603R = 0x00071000,  
98 - CPU_PPC_G2 = 0x80810000,  
99 - CPU_PPC_G2LE = 0x80820000, 152 + CPU_PPC_601 = 0x00010001,
  153 + CPU_PPC_602 = 0x00050100,
  154 + CPU_PPC_603 = 0x00030100,
  155 + CPU_PPC_603E = 0x00060101,
  156 + CPU_PPC_603P = 0x00070000,
  157 + CPU_PPC_603E7v = 0x00070100,
  158 + CPU_PPC_603E7v2 = 0x00070201,
  159 + CPU_PPC_603E7 = 0x00070200,
  160 + CPU_PPC_603R = 0x00071201,
  161 + CPU_PPC_G2 = 0x00810011,
  162 + CPU_PPC_G2H4 = 0x80811010,
  163 + CPU_PPC_G2gp = 0x80821010,
  164 + CPU_PPC_G2ls = 0x90810010,
  165 + CPU_PPC_G2LE = 0x80820010,
  166 + CPU_PPC_G2LEgp = 0x80822010,
  167 + CPU_PPC_G2LEls = 0xA0822010,
100 CPU_PPC_604 = 0x00040000, 168 CPU_PPC_604 = 0x00040000,
101 - CPU_PPC_604E = 0x00090000,  
102 - CPU_PPC_604R = 0x000a0000, 169 + CPU_PPC_604E = 0x00090100, /* Also 2110 & 2120 */
  170 + CPU_PPC_604R = 0x000a0101,
103 /* PowerPC 74x/75x cores (aka G3) */ 171 /* PowerPC 74x/75x cores (aka G3) */
104 CPU_PPC_74x = 0x00080000, 172 CPU_PPC_74x = 0x00080000,
105 - CPU_PPC_755 = 0x00083000, 173 + CPU_PPC_740E = 0x00080100,
  174 + CPU_PPC_750E = 0x00080200,
  175 + CPU_PPC_755_10 = 0x00083100,
  176 + CPU_PPC_755_11 = 0x00083101,
  177 + CPU_PPC_755_20 = 0x00083200,
  178 + CPU_PPC_755D = 0x00083202,
  179 + CPU_PPC_755E = 0x00083203,
  180 +#define CPU_PPC_755 CPU_PPC_755E
106 CPU_PPC_74xP = 0x10080000, 181 CPU_PPC_74xP = 0x10080000,
107 - CPU_PPC_750CXE22 = 0x00082202, 182 + CPU_PPC_750CXE21 = 0x00082201,
  183 + CPU_PPC_750CXE22 = 0x00082212,
  184 + CPU_PPC_750CXE23 = 0x00082203,
108 CPU_PPC_750CXE24 = 0x00082214, 185 CPU_PPC_750CXE24 = 0x00082214,
109 CPU_PPC_750CXE24b = 0x00083214, 186 CPU_PPC_750CXE24b = 0x00083214,
110 CPU_PPC_750CXE31 = 0x00083211, 187 CPU_PPC_750CXE31 = 0x00083211,
111 CPU_PPC_750CXE31b = 0x00083311, 188 CPU_PPC_750CXE31b = 0x00083311,
112 #define CPU_PPC_750CXE CPU_PPC_750CXE31b 189 #define CPU_PPC_750CXE CPU_PPC_750CXE31b
113 - CPU_PPC_750FX = 0x70000000,  
114 - CPU_PPC_750GX = 0x70020000, 190 + CPU_PPC_750CXR = 0x00083410,
  191 + CPU_PPC_750FX10 = 0x70000100,
  192 + CPU_PPC_750FX20 = 0x70000200,
  193 + CPU_PPC_750FX21 = 0x70000201,
  194 + CPU_PPC_750FX22 = 0x70000202,
  195 + CPU_PPC_750FX23 = 0x70000203,
  196 +#define CPU_PPC_750FX CPU_PPC_750FX23
  197 + CPU_PPC_750FL = 0x700A0203,
  198 + CPU_PPC_750GX10 = 0x70020100,
  199 + CPU_PPC_750GX11 = 0x70020101,
  200 + CPU_PPC_750GX12 = 0x70020102,
  201 +#define CPU_PPC_750GX CPU_PPC_750GX12
  202 + CPU_PPC_750GL = 0x70020102,
  203 + CPU_PPC_750L30 = 0x00088300,
  204 + CPU_PPC_750L32 = 0x00088302,
  205 + CPU_PPC_750CL = 0x00087200,
115 /* PowerPC 74xx cores (aka G4) */ 206 /* PowerPC 74xx cores (aka G4) */
116 - CPU_PPC_7400 = 0x000C0000,  
117 - CPU_PPC_7410 = 0x800C0000,  
118 - CPU_PPC_7441 = 0x80000200,  
119 - CPU_PPC_7450 = 0x80000000, 207 + CPU_PPC_7400 = 0x000C0100,
  208 + CPU_PPC_7410C = 0x800C1102,
  209 + CPU_PPC_7410D = 0x800C1103,
  210 + CPU_PPC_7410E = 0x800C1104,
  211 + CPU_PPC_7441 = 0x80000210,
  212 + CPU_PPC_7445 = 0x80010100,
  213 + CPU_PPC_7447 = 0x80020100,
  214 + CPU_PPC_7447A = 0x80030101,
  215 + CPU_PPC_7448 = 0x80040100,
  216 + CPU_PPC_7450 = 0x80000200,
  217 + CPU_PPC_7450b = 0x80000201,
120 CPU_PPC_7451 = 0x80000203, 218 CPU_PPC_7451 = 0x80000203,
121 - CPU_PPC_7455 = 0x80010000,  
122 - CPU_PPC_7457 = 0x80020000, 219 + CPU_PPC_7451G = 0x80000210,
  220 + CPU_PPC_7455 = 0x80010201,
  221 + CPU_PPC_7455F = 0x80010303,
  222 + CPU_PPC_7455G = 0x80010304,
  223 + CPU_PPC_7457 = 0x80020101,
  224 + CPU_PPC_7457C = 0x80020102,
123 CPU_PPC_7457A = 0x80030000, 225 CPU_PPC_7457A = 0x80030000,
124 /* 64 bits PowerPC */ 226 /* 64 bits PowerPC */
125 CPU_PPC_620 = 0x00140000, 227 CPU_PPC_620 = 0x00140000,
@@ -130,7 +232,21 @@ enum { @@ -130,7 +232,21 @@ enum {
130 CPU_PPC_POWER5 = 0x003A0000, 232 CPU_PPC_POWER5 = 0x003A0000,
131 CPU_PPC_POWER5P = 0x003B0000, 233 CPU_PPC_POWER5P = 0x003B0000,
132 CPU_PPC_970 = 0x00390000, 234 CPU_PPC_970 = 0x00390000,
133 - CPU_PPC_970FX = 0x003C0000, 235 + CPU_PPC_970FX10 = 0x00391100,
  236 + CPU_PPC_970FX20 = 0x003C0200,
  237 + CPU_PPC_970FX21 = 0x003C0201,
  238 + CPU_PPC_970FX30 = 0x003C0300,
  239 + CPU_PPC_970FX31 = 0x003C0301,
  240 +#define CPU_PPC_970FX CPU_PPC_970FX31
  241 + CPU_PPC_970MP10 = 0x00440100,
  242 + CPU_PPC_970MP11 = 0x00440101,
  243 +#define CPU_PPC_970MP CPU_PPC_970MP11
  244 + CPU_PPC_CELL10 = 0x00700100,
  245 + CPU_PPC_CELL20 = 0x00700400,
  246 + CPU_PPC_CELL30 = 0x00700500,
  247 + CPU_PPC_CELL31 = 0x00700501,
  248 +#define CPU_PPC_CELL32 CPU_PPC_CELL31
  249 +#define CPU_PPC_CELL CPU_PPC_CELL32
134 CPU_PPC_RS64 = 0x00330000, 250 CPU_PPC_RS64 = 0x00330000,
135 CPU_PPC_RS64II = 0x00340000, 251 CPU_PPC_RS64II = 0x00340000,
136 CPU_PPC_RS64III = 0x00360000, 252 CPU_PPC_RS64III = 0x00360000,
@@ -147,12 +263,28 @@ enum { @@ -147,12 +263,28 @@ enum {
147 #endif 263 #endif
148 }; 264 };
149 265
150 -/* System version register (used on MPC 8xx) */ 266 +/* System version register (used on MPC 8xxx) */
151 enum { 267 enum {
152 PPC_SVR_8540 = 0x80300000, 268 PPC_SVR_8540 = 0x80300000,
153 - PPC_SVR_8541E = 0x807A0000,  
154 - PPC_SVR_8555E = 0x80790000,  
155 - PPC_SVR_8560 = 0x80700000, 269 + PPC_SVR_8541E = 0x807A0010,
  270 + PPC_SVR_8543v10 = 0x80320010,
  271 + PPC_SVR_8543v11 = 0x80320011,
  272 + PPC_SVR_8543v20 = 0x80320020,
  273 + PPC_SVR_8543Ev10 = 0x803A0010,
  274 + PPC_SVR_8543Ev11 = 0x803A0011,
  275 + PPC_SVR_8543Ev20 = 0x803A0020,
  276 + PPC_SVR_8545 = 0x80310220,
  277 + PPC_SVR_8545E = 0x80390220,
  278 + PPC_SVR_8547E = 0x80390120,
  279 + PPC_SCR_8548v10 = 0x80310010,
  280 + PPC_SCR_8548v11 = 0x80310011,
  281 + PPC_SCR_8548v20 = 0x80310020,
  282 + PPC_SVR_8548Ev10 = 0x80390010,
  283 + PPC_SVR_8548Ev11 = 0x80390011,
  284 + PPC_SVR_8548Ev20 = 0x80390020,
  285 + PPC_SVR_8555E = 0x80790010,
  286 + PPC_SVR_8560v10 = 0x80700010,
  287 + PPC_SVR_8560v20 = 0x80700020,
156 }; 288 };
157 289
158 /*****************************************************************************/ 290 /*****************************************************************************/
@@ -197,7 +329,7 @@ enum { @@ -197,7 +329,7 @@ enum {
197 /* Time base support */ 329 /* Time base support */
198 PPC_TB = 0x00002000, 330 PPC_TB = 0x00002000,
199 /* Embedded PowerPC dedicated instructions */ 331 /* Embedded PowerPC dedicated instructions */
200 - PPC_4xx_COMMON = 0x00004000, 332 + PPC_EMB_COMMON = 0x00004000,
201 /* PowerPC 40x exception model */ 333 /* PowerPC 40x exception model */
202 PPC_40x_EXCP = 0x00008000, 334 PPC_40x_EXCP = 0x00008000,
203 /* PowerPC 40x specific instructions */ 335 /* PowerPC 40x specific instructions */
@@ -225,12 +357,20 @@ enum { @@ -225,12 +357,20 @@ enum {
225 PPC_64H = 0x02000000, 357 PPC_64H = 0x02000000,
226 /* 64 bits PowerPC "bridge" features */ 358 /* 64 bits PowerPC "bridge" features */
227 PPC_64_BRIDGE = 0x04000000, 359 PPC_64_BRIDGE = 0x04000000,
  360 + /* BookE (embedded) PowerPC specification */
  361 + PPC_BOOKE = 0x08000000,
  362 + /* eieio */
  363 + PPC_MEM_EIEIO = 0x10000000,
  364 + /* e500 vector instructions */
  365 + PPC_E500_VECTOR = 0x20000000,
  366 + /* PowerPC 4xx dedicated instructions */
  367 + PPC_4xx_COMMON = 0x40000000,
228 }; 368 };
229 369
230 /* CPU run-time flags (MMU and exception model) */ 370 /* CPU run-time flags (MMU and exception model) */
231 enum { 371 enum {
232 /* MMU model */ 372 /* MMU model */
233 -#define PPC_FLAGS_MMU_MASK (0x0000000F) 373 + PPC_FLAGS_MMU_MASK = 0x0000000F,
234 /* Standard 32 bits PowerPC MMU */ 374 /* Standard 32 bits PowerPC MMU */
235 PPC_FLAGS_MMU_32B = 0x00000000, 375 PPC_FLAGS_MMU_32B = 0x00000000,
236 /* Standard 64 bits PowerPC MMU */ 376 /* Standard 64 bits PowerPC MMU */
@@ -243,8 +383,10 @@ enum { @@ -243,8 +383,10 @@ enum {
243 PPC_FLAGS_MMU_SOFT_4xx = 0x00000004, 383 PPC_FLAGS_MMU_SOFT_4xx = 0x00000004,
244 /* PowerPC 403 MMU */ 384 /* PowerPC 403 MMU */
245 PPC_FLAGS_MMU_403 = 0x00000005, 385 PPC_FLAGS_MMU_403 = 0x00000005,
  386 + /* Freescale e500 MMU model */
  387 + PPC_FLAGS_MMU_e500 = 0x00000006,
246 /* Exception model */ 388 /* Exception model */
247 -#define PPC_FLAGS_EXCP_MASK (0x000000F0) 389 + PPC_FLAGS_EXCP_MASK = 0x000000F0,
248 /* Standard PowerPC exception model */ 390 /* Standard PowerPC exception model */
249 PPC_FLAGS_EXCP_STD = 0x00000000, 391 PPC_FLAGS_EXCP_STD = 0x00000000,
250 /* PowerPC 40x exception model */ 392 /* PowerPC 40x exception model */
@@ -277,32 +419,42 @@ enum { @@ -277,32 +419,42 @@ enum {
277 #define PPC_FLAGS_TODO (0x00000000) 419 #define PPC_FLAGS_TODO (0x00000000)
278 420
279 /* PowerPC 40x instruction set */ 421 /* PowerPC 40x instruction set */
280 -#define PPC_INSNS_4xx (PPC_INSNS_BASE | PPC_MEM_TLBSYNC | PPC_4xx_COMMON) 422 +#define PPC_INSNS_EMB (PPC_INSNS_BASE | PPC_MEM_TLBSYNC | PPC_EMB_COMMON)
281 /* PowerPC 401 */ 423 /* PowerPC 401 */
282 #define PPC_INSNS_401 (PPC_INSNS_TODO) 424 #define PPC_INSNS_401 (PPC_INSNS_TODO)
283 #define PPC_FLAGS_401 (PPC_FLAGS_TODO) 425 #define PPC_FLAGS_401 (PPC_FLAGS_TODO)
284 /* PowerPC 403 */ 426 /* PowerPC 403 */
285 -#define PPC_INSNS_403 (PPC_INSNS_4xx | PPC_MEM_SYNC | PPC_MEM_TLBIA | \  
286 - PPC_40x_EXCP | PPC_40x_SPEC) 427 +#define PPC_INSNS_403 (PPC_INSNS_EMB | PPC_MEM_SYNC | PPC_MEM_EIEIO | \
  428 + PPC_MEM_TLBIA | PPC_4xx_COMMON | PPC_40x_EXCP | \
  429 + PPC_40x_SPEC)
287 #define PPC_FLAGS_403 (PPC_FLAGS_MMU_403 | PPC_FLAGS_EXCP_40x) 430 #define PPC_FLAGS_403 (PPC_FLAGS_MMU_403 | PPC_FLAGS_EXCP_40x)
288 /* PowerPC 405 */ 431 /* PowerPC 405 */
289 -#define PPC_INSNS_405 (PPC_INSNS_4xx | PPC_MEM_SYNC | PPC_CACHE_OPT | \  
290 - PPC_MEM_TLBIA | PPC_TB | PPC_40x_SPEC | PPC_40x_EXCP | \ 432 +#define PPC_INSNS_405 (PPC_INSNS_EMB | PPC_MEM_SYNC | PPC_MEM_EIEIO | \
  433 + PPC_CACHE_OPT | PPC_MEM_TLBIA | PPC_TB | \
  434 + PPC_4xx_COMMON | PPC_40x_SPEC | PPC_40x_EXCP | \
291 PPC_405_MAC) 435 PPC_405_MAC)
292 #define PPC_FLAGS_405 (PPC_FLAGS_MMU_SOFT_4xx | PPC_FLAGS_EXCP_40x) 436 #define PPC_FLAGS_405 (PPC_FLAGS_MMU_SOFT_4xx | PPC_FLAGS_EXCP_40x)
293 /* PowerPC 440 */ 437 /* PowerPC 440 */
294 -#define PPC_INSNS_440 (PPC_INSNS_4xx | PPC_CACHE_OPT | PPC_405_MAC | \  
295 - PPC_440_SPEC) 438 +#define PPC_INSNS_440 (PPC_INSNS_EMB | PPC_CACHE_OPT | PPC_BOOKE | \
  439 + PPC_4xx_COMMON | PPC_405_MAC | PPC_440_SPEC)
296 #define PPC_FLAGS_440 (PPC_FLAGS_TODO) 440 #define PPC_FLAGS_440 (PPC_FLAGS_TODO)
  441 +/* Generic BookE PowerPC */
  442 +#define PPC_INSNS_BOOKE (PPC_INSNS_EMB | PPC_BOOKE | PPC_MEM_EIEIO | \
  443 + PPC_FLOAT | PPC_FLOAT_OPT | PPC_CACHE_OPT)
  444 +#define PPC_FLAGS_BOOKE (PPC_FLAGS_MMU_SOFT_4xx | PPC_FLAGS_EXCP_40x)
  445 +/* e500 core */
  446 +#define PPC_INSNS_E500 (PPC_INSNS_EMB | PPC_BOOKE | PPC_MEM_EIEIO | \
  447 + PPC_CACHE_OPT | PPC_E500_VECTOR)
  448 +#define PPC_FLAGS_E500 (PPC_FLAGS_MMU_SOFT_4xx | PPC_FLAGS_EXCP_40x)
297 /* Non-embedded PowerPC */ 449 /* Non-embedded PowerPC */
298 #define PPC_INSNS_COMMON (PPC_INSNS_BASE | PPC_FLOAT | PPC_MEM_SYNC | \ 450 #define PPC_INSNS_COMMON (PPC_INSNS_BASE | PPC_FLOAT | PPC_MEM_SYNC | \
299 - PPC_SEGMENT | PPC_MEM_TLBIE) 451 + PPC_MEM_EIEIO | PPC_SEGMENT | PPC_MEM_TLBIE)
300 /* PowerPC 601 */ 452 /* PowerPC 601 */
301 #define PPC_INSNS_601 (PPC_INSNS_COMMON | PPC_EXTERN | PPC_POWER_BR) 453 #define PPC_INSNS_601 (PPC_INSNS_COMMON | PPC_EXTERN | PPC_POWER_BR)
302 #define PPC_FLAGS_601 (PPC_FLAGS_MMU_601 | PPC_FLAGS_EXCP_601) 454 #define PPC_FLAGS_601 (PPC_FLAGS_MMU_601 | PPC_FLAGS_EXCP_601)
303 /* PowerPC 602 */ 455 /* PowerPC 602 */
304 #define PPC_INSNS_602 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_6xx_TLB | \ 456 #define PPC_INSNS_602 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_6xx_TLB | \
305 - PPC_MEM_TLBSYNC | PPC_TB) 457 + PPC_MEM_TLBSYNC | PPC_TB | PPC_602_SPEC)
306 #define PPC_FLAGS_602 (PPC_FLAGS_MMU_SOFT_6xx | PPC_FLAGS_EXCP_602) 458 #define PPC_FLAGS_602 (PPC_FLAGS_MMU_SOFT_6xx | PPC_FLAGS_EXCP_602)
307 /* PowerPC 603 */ 459 /* PowerPC 603 */
308 #define PPC_INSNS_603 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_6xx_TLB | \ 460 #define PPC_INSNS_603 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_6xx_TLB | \
@@ -348,13 +500,17 @@ typedef struct ppc_tb_t ppc_tb_t; @@ -348,13 +500,17 @@ typedef struct ppc_tb_t ppc_tb_t;
348 typedef struct ppc_spr_t ppc_spr_t; 500 typedef struct ppc_spr_t ppc_spr_t;
349 typedef struct ppc_dcr_t ppc_dcr_t; 501 typedef struct ppc_dcr_t ppc_dcr_t;
350 typedef struct ppc_avr_t ppc_avr_t; 502 typedef struct ppc_avr_t ppc_avr_t;
  503 +typedef struct ppc_tlb_t ppc_tlb_t;
  504 +
351 505
352 /* SPR access micro-ops generations callbacks */ 506 /* SPR access micro-ops generations callbacks */
353 struct ppc_spr_t { 507 struct ppc_spr_t {
354 void (*uea_read)(void *opaque, int spr_num); 508 void (*uea_read)(void *opaque, int spr_num);
355 void (*uea_write)(void *opaque, int spr_num); 509 void (*uea_write)(void *opaque, int spr_num);
  510 +#if !defined(CONFIG_USER_ONLY)
356 void (*oea_read)(void *opaque, int spr_num); 511 void (*oea_read)(void *opaque, int spr_num);
357 void (*oea_write)(void *opaque, int spr_num); 512 void (*oea_write)(void *opaque, int spr_num);
  513 +#endif
358 const unsigned char *name; 514 const unsigned char *name;
359 }; 515 };
360 516
@@ -364,46 +520,42 @@ struct ppc_avr_t { @@ -364,46 +520,42 @@ struct ppc_avr_t {
364 }; 520 };
365 521
366 /* Software TLB cache */ 522 /* Software TLB cache */
367 -typedef struct ppc_tlb_t ppc_tlb_t;  
368 struct ppc_tlb_t { 523 struct ppc_tlb_t {
369 - /* Physical page number */  
370 - target_phys_addr_t RPN;  
371 - /* Virtual page number */  
372 - target_ulong VPN;  
373 - /* Page size */  
374 - target_ulong size;  
375 - /* Protection bits */  
376 - int prot;  
377 - int is_user;  
378 - uint32_t private;  
379 - uint32_t flags; 524 + target_ulong pte0;
  525 + target_ulong pte1;
  526 + target_ulong EPN;
  527 + target_ulong PID;
  528 + int size;
380 }; 529 };
381 530
382 /*****************************************************************************/ 531 /*****************************************************************************/
383 /* Machine state register bits definition */ 532 /* Machine state register bits definition */
384 -#define MSR_SF 63 /* Sixty-four-bit mode */ 533 +#define MSR_SF 63 /* Sixty-four-bit mode hflags */
385 #define MSR_ISF 61 /* Sixty-four-bit interrupt mode on 630 */ 534 #define MSR_ISF 61 /* Sixty-four-bit interrupt mode on 630 */
386 -#define MSR_HV 60 /* hypervisor state */  
387 -#define MSR_VR 25 /* altivec available */  
388 -#define MSR_AP 23 /* Access privilege state on 602 */  
389 -#define MSR_SA 22 /* Supervisor access mode on 602 */ 535 +#define MSR_HV 60 /* hypervisor state hflags */
  536 +#define MSR_UCLE 26 /* User-mode cache lock enable on e500 */
  537 +#define MSR_VR 25 /* altivec available hflags */
  538 +#define MSR_SPE 25 /* SPE enable on e500 hflags */
  539 +#define MSR_AP 23 /* Access privilege state on 602 hflags */
  540 +#define MSR_SA 22 /* Supervisor access mode on 602 hflags */
390 #define MSR_KEY 19 /* key bit on 603e */ 541 #define MSR_KEY 19 /* key bit on 603e */
391 #define MSR_POW 18 /* Power management */ 542 #define MSR_POW 18 /* Power management */
392 #define MSR_WE 18 /* Wait state enable on embedded PowerPC */ 543 #define MSR_WE 18 /* Wait state enable on embedded PowerPC */
393 #define MSR_TGPR 17 /* TGPR usage on 602/603 */ 544 #define MSR_TGPR 17 /* TGPR usage on 602/603 */
394 -#define MSR_TLB 17 /* TLB on ? */ 545 +#define MSR_TLB 17 /* TLB update on ? */
395 #define MSR_CE 17 /* Critical interrupt enable on embedded PowerPC */ 546 #define MSR_CE 17 /* Critical interrupt enable on embedded PowerPC */
396 #define MSR_ILE 16 /* Interrupt little-endian mode */ 547 #define MSR_ILE 16 /* Interrupt little-endian mode */
397 #define MSR_EE 15 /* External interrupt enable */ 548 #define MSR_EE 15 /* External interrupt enable */
398 -#define MSR_PR 14 /* Problem state */  
399 -#define MSR_FP 13 /* Floating point available */ 549 +#define MSR_PR 14 /* Problem state hflags */
  550 +#define MSR_FP 13 /* Floating point available hflags */
400 #define MSR_ME 12 /* Machine check interrupt enable */ 551 #define MSR_ME 12 /* Machine check interrupt enable */
401 -#define MSR_FE0 11 /* Floating point exception mode 0 */  
402 -#define MSR_SE 10 /* Single-step trace enable */ 552 +#define MSR_FE0 11 /* Floating point exception mode 0 hflags */
  553 +#define MSR_SE 10 /* Single-step trace enable hflags */
403 #define MSR_DWE 10 /* Debug wait enable on 405 */ 554 #define MSR_DWE 10 /* Debug wait enable on 405 */
404 -#define MSR_BE 9 /* Branch trace enable */ 555 +#define MSR_UBLE 10 /* User BTB lock enable on e500 */
  556 +#define MSR_BE 9 /* Branch trace enable hflags */
405 #define MSR_DE 9 /* Debug interrupts enable on embedded PowerPC */ 557 #define MSR_DE 9 /* Debug interrupts enable on embedded PowerPC */
406 -#define MSR_FE1 8 /* Floating point exception mode 1 */ 558 +#define MSR_FE1 8 /* Floating point exception mode 1 hflags */
407 #define MSR_AL 7 /* AL bit on POWER */ 559 #define MSR_AL 7 /* AL bit on POWER */
408 #define MSR_IP 6 /* Interrupt prefix */ 560 #define MSR_IP 6 /* Interrupt prefix */
409 #define MSR_IR 5 /* Instruction relocate */ 561 #define MSR_IR 5 /* Instruction relocate */
@@ -415,42 +567,45 @@ struct ppc_tlb_t { @@ -415,42 +567,45 @@ struct ppc_tlb_t {
415 #define MSR_PX 2 /* Protection exclusive on 403 */ 567 #define MSR_PX 2 /* Protection exclusive on 403 */
416 #define MSR_PMM 2 /* Performance monitor mark on POWER */ 568 #define MSR_PMM 2 /* Performance monitor mark on POWER */
417 #define MSR_RI 1 /* Recoverable interrupt */ 569 #define MSR_RI 1 /* Recoverable interrupt */
418 -#define MSR_LE 0 /* Little-endian mode */ 570 +#define MSR_LE 0 /* Little-endian mode hflags */
419 #define msr_sf env->msr[MSR_SF] 571 #define msr_sf env->msr[MSR_SF]
420 #define msr_isf env->msr[MSR_ISF] 572 #define msr_isf env->msr[MSR_ISF]
421 #define msr_hv env->msr[MSR_HV] 573 #define msr_hv env->msr[MSR_HV]
  574 +#define msr_ucle env->msr[MSR_UCLE]
422 #define msr_vr env->msr[MSR_VR] 575 #define msr_vr env->msr[MSR_VR]
  576 +#define msr_spe env->msr[MSR_SPE]
423 #define msr_ap env->msr[MSR_AP] 577 #define msr_ap env->msr[MSR_AP]
424 #define msr_sa env->msr[MSR_SA] 578 #define msr_sa env->msr[MSR_SA]
425 #define msr_key env->msr[MSR_KEY] 579 #define msr_key env->msr[MSR_KEY]
426 -#define msr_pow env->msr[MSR_POW] 580 +#define msr_pow env->msr[MSR_POW]
427 #define msr_we env->msr[MSR_WE] 581 #define msr_we env->msr[MSR_WE]
428 #define msr_tgpr env->msr[MSR_TGPR] 582 #define msr_tgpr env->msr[MSR_TGPR]
429 #define msr_tlb env->msr[MSR_TLB] 583 #define msr_tlb env->msr[MSR_TLB]
430 #define msr_ce env->msr[MSR_CE] 584 #define msr_ce env->msr[MSR_CE]
431 -#define msr_ile env->msr[MSR_ILE]  
432 -#define msr_ee env->msr[MSR_EE]  
433 -#define msr_pr env->msr[MSR_PR]  
434 -#define msr_fp env->msr[MSR_FP]  
435 -#define msr_me env->msr[MSR_ME]  
436 -#define msr_fe0 env->msr[MSR_FE0]  
437 -#define msr_se env->msr[MSR_SE] 585 +#define msr_ile env->msr[MSR_ILE]
  586 +#define msr_ee env->msr[MSR_EE]
  587 +#define msr_pr env->msr[MSR_PR]
  588 +#define msr_fp env->msr[MSR_FP]
  589 +#define msr_me env->msr[MSR_ME]
  590 +#define msr_fe0 env->msr[MSR_FE0]
  591 +#define msr_se env->msr[MSR_SE]
438 #define msr_dwe env->msr[MSR_DWE] 592 #define msr_dwe env->msr[MSR_DWE]
439 -#define msr_be env->msr[MSR_BE] 593 +#define msr_uble env->msr[MSR_UBLE]
  594 +#define msr_be env->msr[MSR_BE]
440 #define msr_de env->msr[MSR_DE] 595 #define msr_de env->msr[MSR_DE]
441 -#define msr_fe1 env->msr[MSR_FE1] 596 +#define msr_fe1 env->msr[MSR_FE1]
442 #define msr_al env->msr[MSR_AL] 597 #define msr_al env->msr[MSR_AL]
443 -#define msr_ip env->msr[MSR_IP]  
444 -#define msr_ir env->msr[MSR_IR] 598 +#define msr_ip env->msr[MSR_IP]
  599 +#define msr_ir env->msr[MSR_IR]
445 #define msr_is env->msr[MSR_IS] 600 #define msr_is env->msr[MSR_IS]
446 -#define msr_dr env->msr[MSR_DR] 601 +#define msr_dr env->msr[MSR_DR]
447 #define msr_ds env->msr[MSR_DS] 602 #define msr_ds env->msr[MSR_DS]
448 #define msr_pe env->msr[MSR_PE] 603 #define msr_pe env->msr[MSR_PE]
449 #define msr_ep env->msr[MSR_EP] 604 #define msr_ep env->msr[MSR_EP]
450 #define msr_px env->msr[MSR_PX] 605 #define msr_px env->msr[MSR_PX]
451 #define msr_pmm env->msr[MSR_PMM] 606 #define msr_pmm env->msr[MSR_PMM]
452 -#define msr_ri env->msr[MSR_RI]  
453 -#define msr_le env->msr[MSR_LE] 607 +#define msr_ri env->msr[MSR_RI]
  608 +#define msr_le env->msr[MSR_LE]
454 609
455 /*****************************************************************************/ 610 /*****************************************************************************/
456 /* The whole PowerPC CPU context */ 611 /* The whole PowerPC CPU context */
@@ -465,7 +620,7 @@ struct CPUPPCState { @@ -465,7 +620,7 @@ struct CPUPPCState {
465 target_ulong t0, t1, t2; 620 target_ulong t0, t1, t2;
466 #endif 621 #endif
467 /* general purpose registers */ 622 /* general purpose registers */
468 - target_ulong gpr[32]; 623 + ppc_gpr_t gpr[32];
469 /* LR */ 624 /* LR */
470 target_ulong lr; 625 target_ulong lr;
471 /* CTR */ 626 /* CTR */
@@ -482,10 +637,10 @@ struct CPUPPCState { @@ -482,10 +637,10 @@ struct CPUPPCState {
482 /* machine state register */ 637 /* machine state register */
483 uint8_t msr[64]; 638 uint8_t msr[64];
484 /* temporary general purpose registers */ 639 /* temporary general purpose registers */
485 - target_ulong tgpr[4]; /* Used to speed-up TLB assist handlers */ 640 + ppc_gpr_t tgpr[4]; /* Used to speed-up TLB assist handlers */
486 641
487 /* Floating point execution context */ 642 /* Floating point execution context */
488 - /* temporary float registers */ 643 + /* temporary float registers */
489 float64 ft0; 644 float64 ft0;
490 float64 ft1; 645 float64 ft1;
491 float64 ft2; 646 float64 ft2;
@@ -529,9 +684,12 @@ struct CPUPPCState { @@ -529,9 +684,12 @@ struct CPUPPCState {
529 ppc_dcr_t *dcr_env; 684 ppc_dcr_t *dcr_env;
530 685
531 /* PowerPC TLB registers (for 4xx and 60x software driven TLBs) */ 686 /* PowerPC TLB registers (for 4xx and 60x software driven TLBs) */
532 - int nb_tlb;  
533 - int nb_ways, last_way;  
534 - ppc_tlb_t tlb[128]; 687 + int nb_tlb; /* Total number of TLB */
  688 + int tlb_per_way; /* Speed-up helper: used to avoid divisions at run time */
  689 + int nb_ways; /* Number of ways in the TLB set */
  690 + int last_way; /* Last used way used to allocate TLB in a LRU way */
  691 + int id_tlbs; /* If 1, MMU has separated TLBs for instructions & data */
  692 + ppc_tlb_t *tlb; /* TLB is optional. Allocate them only if needed */
535 /* Callbacks for specific checks on some implementations */ 693 /* Callbacks for specific checks on some implementations */
536 int (*tlb_check_more)(CPUPPCState *env, struct ppc_tlb_t *tlb, int *prot, 694 int (*tlb_check_more)(CPUPPCState *env, struct ppc_tlb_t *tlb, int *prot,
537 target_ulong vaddr, int rw, int acc_type, 695 target_ulong vaddr, int rw, int acc_type,
@@ -568,6 +726,16 @@ struct CPUPPCState { @@ -568,6 +726,16 @@ struct CPUPPCState {
568 int (*osi_call)(struct CPUPPCState *env); 726 int (*osi_call)(struct CPUPPCState *env);
569 }; 727 };
570 728
  729 +/* Context used internally during MMU translations */
  730 +typedef struct mmu_ctx_t mmu_ctx_t;
  731 +struct mmu_ctx_t {
  732 + target_phys_addr_t raddr; /* Real address */
  733 + int prot; /* Protection bits */
  734 + target_phys_addr_t pg_addr[2]; /* PTE tables base addresses */
  735 + target_ulong ptem; /* Virtual segment ID | API */
  736 + int key; /* Access key */
  737 +};
  738 +
571 /*****************************************************************************/ 739 /*****************************************************************************/
572 CPUPPCState *cpu_ppc_init(void); 740 CPUPPCState *cpu_ppc_init(void);
573 int cpu_ppc_exec(CPUPPCState *s); 741 int cpu_ppc_exec(CPUPPCState *s);
@@ -583,6 +751,7 @@ void cpu_loop_exit(void); @@ -583,6 +751,7 @@ void cpu_loop_exit(void);
583 751
584 void dump_stack (CPUPPCState *env); 752 void dump_stack (CPUPPCState *env);
585 753
  754 +#if !defined(CONFIG_USER_ONLY)
586 target_ulong do_load_ibatu (CPUPPCState *env, int nr); 755 target_ulong do_load_ibatu (CPUPPCState *env, int nr);
587 target_ulong do_load_ibatl (CPUPPCState *env, int nr); 756 target_ulong do_load_ibatl (CPUPPCState *env, int nr);
588 void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value); 757 void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value);
@@ -591,23 +760,17 @@ target_ulong do_load_dbatu (CPUPPCState *env, int nr); @@ -591,23 +760,17 @@ target_ulong do_load_dbatu (CPUPPCState *env, int nr);
591 target_ulong do_load_dbatl (CPUPPCState *env, int nr); 760 target_ulong do_load_dbatl (CPUPPCState *env, int nr);
592 void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value); 761 void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value);
593 void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value); 762 void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value);
594 -  
595 -target_ulong do_load_nip (CPUPPCState *env);  
596 -void do_store_nip (CPUPPCState *env, target_ulong value);  
597 target_ulong do_load_sdr1 (CPUPPCState *env); 763 target_ulong do_load_sdr1 (CPUPPCState *env);
598 void do_store_sdr1 (CPUPPCState *env, target_ulong value); 764 void do_store_sdr1 (CPUPPCState *env, target_ulong value);
599 target_ulong do_load_asr (CPUPPCState *env); 765 target_ulong do_load_asr (CPUPPCState *env);
600 void do_store_asr (CPUPPCState *env, target_ulong value); 766 void do_store_asr (CPUPPCState *env, target_ulong value);
601 target_ulong do_load_sr (CPUPPCState *env, int srnum); 767 target_ulong do_load_sr (CPUPPCState *env, int srnum);
602 void do_store_sr (CPUPPCState *env, int srnum, target_ulong value); 768 void do_store_sr (CPUPPCState *env, int srnum, target_ulong value);
603 -uint32_t do_load_cr (CPUPPCState *env);  
604 -void do_store_cr (CPUPPCState *env, uint32_t value, uint32_t mask);  
605 -uint32_t do_load_xer (CPUPPCState *env);  
606 -void do_store_xer (CPUPPCState *env, uint32_t value); 769 +#endif
  770 +uint32_t ppc_load_xer (CPUPPCState *env);
  771 +void ppc_store_xer (CPUPPCState *env, uint32_t value);
607 target_ulong do_load_msr (CPUPPCState *env); 772 target_ulong do_load_msr (CPUPPCState *env);
608 void do_store_msr (CPUPPCState *env, target_ulong value); 773 void do_store_msr (CPUPPCState *env, target_ulong value);
609 -float64 do_load_fpscr (CPUPPCState *env);  
610 -void do_store_fpscr (CPUPPCState *env, float64 f, uint32_t mask);  
611 774
612 void do_compute_hflags (CPUPPCState *env); 775 void do_compute_hflags (CPUPPCState *env);
613 776
@@ -645,261 +808,294 @@ void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value); @@ -645,261 +808,294 @@ void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value);
645 #define xer_bc env->xer[0] 808 #define xer_bc env->xer[0]
646 809
647 /* SPR definitions */ 810 /* SPR definitions */
648 -#define SPR_MQ (0x000)  
649 -#define SPR_XER (0x001)  
650 -#define SPR_601_VRTCU (0x004)  
651 -#define SPR_601_VRTCL (0x005)  
652 -#define SPR_601_UDECR (0x006)  
653 -#define SPR_LR (0x008)  
654 -#define SPR_CTR (0x009)  
655 -#define SPR_DSISR (0x012)  
656 -#define SPR_DAR (0x013)  
657 -#define SPR_601_RTCU (0x014)  
658 -#define SPR_601_RTCL (0x015)  
659 -#define SPR_DECR (0x016)  
660 -#define SPR_SDR1 (0x019)  
661 -#define SPR_SRR0 (0x01A)  
662 -#define SPR_SRR1 (0x01B)  
663 -#define SPR_440_PID (0x030)  
664 -#define SPR_440_DECAR (0x036)  
665 -#define SPR_CSRR0 (0x03A)  
666 -#define SPR_CSRR1 (0x03B)  
667 -#define SPR_440_DEAR (0x03D)  
668 -#define SPR_440_ESR (0x03E)  
669 -#define SPR_440_IVPR (0x03F)  
670 -#define SPR_8xx_EIE (0x050)  
671 -#define SPR_8xx_EID (0x051)  
672 -#define SPR_8xx_NRE (0x052)  
673 -#define SPR_58x_CMPA (0x090)  
674 -#define SPR_58x_CMPB (0x091)  
675 -#define SPR_58x_CMPC (0x092)  
676 -#define SPR_58x_CMPD (0x093)  
677 -#define SPR_58x_ICR (0x094)  
678 -#define SPR_58x_DER (0x094)  
679 -#define SPR_58x_COUNTA (0x096)  
680 -#define SPR_58x_COUNTB (0x097)  
681 -#define SPR_58x_CMPE (0x098)  
682 -#define SPR_58x_CMPF (0x099)  
683 -#define SPR_58x_CMPG (0x09A)  
684 -#define SPR_58x_CMPH (0x09B)  
685 -#define SPR_58x_LCTRL1 (0x09C)  
686 -#define SPR_58x_LCTRL2 (0x09D)  
687 -#define SPR_58x_ICTRL (0x09E)  
688 -#define SPR_58x_BAR (0x09F)  
689 -#define SPR_VRSAVE (0x100)  
690 -#define SPR_USPRG0 (0x100)  
691 -#define SPR_USPRG4 (0x104)  
692 -#define SPR_USPRG5 (0x105)  
693 -#define SPR_USPRG6 (0x106)  
694 -#define SPR_USPRG7 (0x107)  
695 -#define SPR_VTBL (0x10C)  
696 -#define SPR_VTBU (0x10D)  
697 -#define SPR_SPRG0 (0x110)  
698 -#define SPR_SPRG1 (0x111)  
699 -#define SPR_SPRG2 (0x112)  
700 -#define SPR_SPRG3 (0x113)  
701 -#define SPR_SPRG4 (0x114)  
702 -#define SPR_SCOMC (0x114)  
703 -#define SPR_SPRG5 (0x115)  
704 -#define SPR_SCOMD (0x115)  
705 -#define SPR_SPRG6 (0x116)  
706 -#define SPR_SPRG7 (0x117)  
707 -#define SPR_ASR (0x118)  
708 -#define SPR_EAR (0x11A)  
709 -#define SPR_TBL (0x11C)  
710 -#define SPR_TBU (0x11D)  
711 -#define SPR_SVR (0x11E)  
712 -#define SPR_440_PIR (0x11E)  
713 -#define SPR_PVR (0x11F)  
714 -#define SPR_HSPRG0 (0x130)  
715 -#define SPR_440_DBSR (0x130)  
716 -#define SPR_HSPRG1 (0x131)  
717 -#define SPR_440_DBCR0 (0x134)  
718 -#define SPR_IBCR (0x135)  
719 -#define SPR_440_DBCR1 (0x135)  
720 -#define SPR_DBCR (0x136)  
721 -#define SPR_HDEC (0x136)  
722 -#define SPR_440_DBCR2 (0x136)  
723 -#define SPR_HIOR (0x137)  
724 -#define SPR_MBAR (0x137)  
725 -#define SPR_RMOR (0x138)  
726 -#define SPR_440_IAC1 (0x138)  
727 -#define SPR_HRMOR (0x139)  
728 -#define SPR_440_IAC2 (0x139)  
729 -#define SPR_HSSR0 (0x13A)  
730 -#define SPR_440_IAC3 (0x13A)  
731 -#define SPR_HSSR1 (0x13B)  
732 -#define SPR_440_IAC4 (0x13B)  
733 -#define SPR_LPCR (0x13C)  
734 -#define SPR_440_DAC1 (0x13C)  
735 -#define SPR_LPIDR (0x13D)  
736 -#define SPR_DABR2 (0x13D)  
737 -#define SPR_440_DAC2 (0x13D)  
738 -#define SPR_440_DVC1 (0x13E)  
739 -#define SPR_440_DVC2 (0x13F)  
740 -#define SPR_440_TSR (0x150)  
741 -#define SPR_440_TCR (0x154)  
742 -#define SPR_440_IVOR0 (0x190)  
743 -#define SPR_440_IVOR1 (0x191)  
744 -#define SPR_440_IVOR2 (0x192)  
745 -#define SPR_440_IVOR3 (0x193)  
746 -#define SPR_440_IVOR4 (0x194)  
747 -#define SPR_440_IVOR5 (0x195)  
748 -#define SPR_440_IVOR6 (0x196)  
749 -#define SPR_440_IVOR7 (0x197)  
750 -#define SPR_440_IVOR8 (0x198)  
751 -#define SPR_440_IVOR9 (0x199)  
752 -#define SPR_440_IVOR10 (0x19A)  
753 -#define SPR_440_IVOR11 (0x19B)  
754 -#define SPR_440_IVOR12 (0x19C)  
755 -#define SPR_440_IVOR13 (0x19D)  
756 -#define SPR_440_IVOR14 (0x19E)  
757 -#define SPR_440_IVOR15 (0x19F)  
758 -#define SPR_IBAT0U (0x210)  
759 -#define SPR_IBAT0L (0x211)  
760 -#define SPR_IBAT1U (0x212)  
761 -#define SPR_IBAT1L (0x213)  
762 -#define SPR_IBAT2U (0x214)  
763 -#define SPR_IBAT2L (0x215)  
764 -#define SPR_IBAT3U (0x216)  
765 -#define SPR_IBAT3L (0x217)  
766 -#define SPR_DBAT0U (0x218)  
767 -#define SPR_DBAT0L (0x219)  
768 -#define SPR_DBAT1U (0x21A)  
769 -#define SPR_DBAT1L (0x21B)  
770 -#define SPR_DBAT2U (0x21C)  
771 -#define SPR_DBAT2L (0x21D)  
772 -#define SPR_DBAT3U (0x21E)  
773 -#define SPR_DBAT3L (0x21F)  
774 -#define SPR_IBAT4U (0x230)  
775 -#define SPR_IBAT4L (0x231)  
776 -#define SPR_IBAT5U (0x232)  
777 -#define SPR_IBAT5L (0x233)  
778 -#define SPR_IBAT6U (0x234)  
779 -#define SPR_IBAT6L (0x235)  
780 -#define SPR_IBAT7U (0x236)  
781 -#define SPR_IBAT7L (0x237)  
782 -#define SPR_DBAT4U (0x238)  
783 -#define SPR_DBAT4L (0x239)  
784 -#define SPR_DBAT5U (0x23A)  
785 -#define SPR_DBAT5L (0x23B)  
786 -#define SPR_DBAT6U (0x23C)  
787 -#define SPR_DBAT6L (0x23D)  
788 -#define SPR_DBAT7U (0x23E)  
789 -#define SPR_DBAT7L (0x23F)  
790 -#define SPR_440_INV0 (0x370)  
791 -#define SPR_440_INV1 (0x371)  
792 -#define SPR_440_INV2 (0x372)  
793 -#define SPR_440_INV3 (0x373)  
794 -#define SPR_440_IVT0 (0x374)  
795 -#define SPR_440_IVT1 (0x375)  
796 -#define SPR_440_IVT2 (0x376)  
797 -#define SPR_440_IVT3 (0x377)  
798 -#define SPR_440_DNV0 (0x390)  
799 -#define SPR_440_DNV1 (0x391)  
800 -#define SPR_440_DNV2 (0x392)  
801 -#define SPR_440_DNV3 (0x393)  
802 -#define SPR_440_DVT0 (0x394)  
803 -#define SPR_440_DVT1 (0x395)  
804 -#define SPR_440_DVT2 (0x396)  
805 -#define SPR_440_DVT3 (0x397)  
806 -#define SPR_440_DVLIM (0x398)  
807 -#define SPR_440_IVLIM (0x399)  
808 -#define SPR_440_RSTCFG (0x39B)  
809 -#define SPR_440_DCBTRL (0x39C)  
810 -#define SPR_440_DCBTRH (0x39D)  
811 -#define SPR_440_ICBTRL (0x39E)  
812 -#define SPR_440_ICBTRH (0x39F)  
813 -#define SPR_UMMCR0 (0x3A8)  
814 -#define SPR_UPMC1 (0x3A9)  
815 -#define SPR_UPMC2 (0x3AA)  
816 -#define SPR_USIA (0x3AB)  
817 -#define SPR_UMMCR1 (0x3AC)  
818 -#define SPR_UPMC3 (0x3AD)  
819 -#define SPR_UPMC4 (0x3AE)  
820 -#define SPR_USDA (0x3AF)  
821 -#define SPR_40x_ZPR (0x3B0)  
822 -#define SPR_40x_PID (0x3B1)  
823 -#define SPR_440_MMUCR (0x3B2)  
824 -#define SPR_4xx_CCR0 (0x3B3)  
825 -#define SPR_405_IAC3 (0x3B4)  
826 -#define SPR_405_IAC4 (0x3B5)  
827 -#define SPR_405_DVC1 (0x3B6)  
828 -#define SPR_405_DVC2 (0x3B7)  
829 -#define SPR_MMCR0 (0x3B8)  
830 -#define SPR_PMC1 (0x3B9)  
831 -#define SPR_40x_SGR (0x3B9)  
832 -#define SPR_PMC2 (0x3BA)  
833 -#define SPR_40x_DCWR (0x3BA)  
834 -#define SPR_SIA (0x3BB)  
835 -#define SPR_405_SLER (0x3BB)  
836 -#define SPR_MMCR1 (0x3BC)  
837 -#define SPR_405_SU0R (0x3BC)  
838 -#define SPR_PMC3 (0x3BD)  
839 -#define SPR_405_DBCR1 (0x3BD)  
840 -#define SPR_PMC4 (0x3BE)  
841 -#define SPR_SDA (0x3BF)  
842 -#define SPR_403_VTBL (0x3CC)  
843 -#define SPR_403_VTBU (0x3CD)  
844 -#define SPR_DMISS (0x3D0)  
845 -#define SPR_DCMP (0x3D1)  
846 -#define SPR_DHASH1 (0x3D2)  
847 -#define SPR_DHASH2 (0x3D3)  
848 -#define SPR_4xx_ICDBDR (0x3D3)  
849 -#define SPR_IMISS (0x3D4)  
850 -#define SPR_40x_ESR (0x3D4)  
851 -#define SPR_ICMP (0x3D5)  
852 -#define SPR_40x_DEAR (0x3D5)  
853 -#define SPR_RPA (0x3D6)  
854 -#define SPR_40x_EVPR (0x3D6)  
855 -#define SPR_403_CDBCR (0x3D7)  
856 -#define SPR_TCR (0x3D8)  
857 -#define SPR_40x_TSR (0x3D8)  
858 -#define SPR_IBR (0x3DA)  
859 -#define SPR_40x_TCR (0x3DA)  
860 -#define SPR_ESASR (0x3DB)  
861 -#define SPR_40x_PIT (0x3DB)  
862 -#define SPR_403_TBL (0x3DC)  
863 -#define SPR_403_TBU (0x3DD)  
864 -#define SPR_SEBR (0x3DE)  
865 -#define SPR_40x_SRR2 (0x3DE)  
866 -#define SPR_SER (0x3DF)  
867 -#define SPR_40x_SRR3 (0x3DF)  
868 -#define SPR_HID0 (0x3F0)  
869 -#define SPR_40x_DBSR (0x3F0)  
870 -#define SPR_HID1 (0x3F1)  
871 -#define SPR_IABR (0x3F2)  
872 -#define SPR_40x_DBCR0 (0x3F2)  
873 -#define SPR_601_HID2 (0x3F2)  
874 -#define SPR_HID2 (0x3F3)  
875 -#define SPR_440_DBDR (0x3F3)  
876 -#define SPR_40x_IAC1 (0x3F4)  
877 -#define SPR_DABR (0x3F5) 811 +#define SPR_MQ (0x000)
  812 +#define SPR_XER (0x001)
  813 +#define SPR_601_VRTCU (0x004)
  814 +#define SPR_601_VRTCL (0x005)
  815 +#define SPR_601_UDECR (0x006)
  816 +#define SPR_LR (0x008)
  817 +#define SPR_CTR (0x009)
  818 +#define SPR_DSISR (0x012)
  819 +#define SPR_DAR (0x013)
  820 +#define SPR_601_RTCU (0x014)
  821 +#define SPR_601_RTCL (0x015)
  822 +#define SPR_DECR (0x016)
  823 +#define SPR_SDR1 (0x019)
  824 +#define SPR_SRR0 (0x01A)
  825 +#define SPR_SRR1 (0x01B)
  826 +#define SPR_BOOKE_PID (0x030)
  827 +#define SPR_BOOKE_DECAR (0x036)
  828 +#define SPR_CSRR0 (0x03A)
  829 +#define SPR_CSRR1 (0x03B)
  830 +#define SPR_BOOKE_DEAR (0x03D)
  831 +#define SPR_BOOKE_ESR (0x03E)
  832 +#define SPR_BOOKE_EVPR (0x03F)
  833 +#define SPR_8xx_EIE (0x050)
  834 +#define SPR_8xx_EID (0x051)
  835 +#define SPR_8xx_NRE (0x052)
  836 +#define SPR_58x_CMPA (0x090)
  837 +#define SPR_58x_CMPB (0x091)
  838 +#define SPR_58x_CMPC (0x092)
  839 +#define SPR_58x_CMPD (0x093)
  840 +#define SPR_58x_ICR (0x094)
  841 +#define SPR_58x_DER (0x094)
  842 +#define SPR_58x_COUNTA (0x096)
  843 +#define SPR_58x_COUNTB (0x097)
  844 +#define SPR_58x_CMPE (0x098)
  845 +#define SPR_58x_CMPF (0x099)
  846 +#define SPR_58x_CMPG (0x09A)
  847 +#define SPR_58x_CMPH (0x09B)
  848 +#define SPR_58x_LCTRL1 (0x09C)
  849 +#define SPR_58x_LCTRL2 (0x09D)
  850 +#define SPR_58x_ICTRL (0x09E)
  851 +#define SPR_58x_BAR (0x09F)
  852 +#define SPR_VRSAVE (0x100)
  853 +#define SPR_USPRG0 (0x100)
  854 +#define SPR_USPRG4 (0x104)
  855 +#define SPR_USPRG5 (0x105)
  856 +#define SPR_USPRG6 (0x106)
  857 +#define SPR_USPRG7 (0x107)
  858 +#define SPR_VTBL (0x10C)
  859 +#define SPR_VTBU (0x10D)
  860 +#define SPR_SPRG0 (0x110)
  861 +#define SPR_SPRG1 (0x111)
  862 +#define SPR_SPRG2 (0x112)
  863 +#define SPR_SPRG3 (0x113)
  864 +#define SPR_SPRG4 (0x114)
  865 +#define SPR_SCOMC (0x114)
  866 +#define SPR_SPRG5 (0x115)
  867 +#define SPR_SCOMD (0x115)
  868 +#define SPR_SPRG6 (0x116)
  869 +#define SPR_SPRG7 (0x117)
  870 +#define SPR_ASR (0x118)
  871 +#define SPR_EAR (0x11A)
  872 +#define SPR_TBL (0x11C)
  873 +#define SPR_TBU (0x11D)
  874 +#define SPR_SVR (0x11E)
  875 +#define SPR_BOOKE_PIR (0x11E)
  876 +#define SPR_PVR (0x11F)
  877 +#define SPR_HSPRG0 (0x130)
  878 +#define SPR_BOOKE_DBSR (0x130)
  879 +#define SPR_HSPRG1 (0x131)
  880 +#define SPR_BOOKE_DBCR0 (0x134)
  881 +#define SPR_IBCR (0x135)
  882 +#define SPR_BOOKE_DBCR1 (0x135)
  883 +#define SPR_DBCR (0x136)
  884 +#define SPR_HDEC (0x136)
  885 +#define SPR_BOOKE_DBCR2 (0x136)
  886 +#define SPR_HIOR (0x137)
  887 +#define SPR_MBAR (0x137)
  888 +#define SPR_RMOR (0x138)
  889 +#define SPR_BOOKE_IAC1 (0x138)
  890 +#define SPR_HRMOR (0x139)
  891 +#define SPR_BOOKE_IAC2 (0x139)
  892 +#define SPR_HSSR0 (0x13A)
  893 +#define SPR_BOOKE_IAC3 (0x13A)
  894 +#define SPR_HSSR1 (0x13B)
  895 +#define SPR_BOOKE_IAC4 (0x13B)
  896 +#define SPR_LPCR (0x13C)
  897 +#define SPR_BOOKE_DAC1 (0x13C)
  898 +#define SPR_LPIDR (0x13D)
  899 +#define SPR_DABR2 (0x13D)
  900 +#define SPR_BOOKE_DAC2 (0x13D)
  901 +#define SPR_BOOKE_DVC1 (0x13E)
  902 +#define SPR_BOOKE_DVC2 (0x13F)
  903 +#define SPR_BOOKE_TSR (0x150)
  904 +#define SPR_BOOKE_TCR (0x154)
  905 +#define SPR_BOOKE_IVOR0 (0x190)
  906 +#define SPR_BOOKE_IVOR1 (0x191)
  907 +#define SPR_BOOKE_IVOR2 (0x192)
  908 +#define SPR_BOOKE_IVOR3 (0x193)
  909 +#define SPR_BOOKE_IVOR4 (0x194)
  910 +#define SPR_BOOKE_IVOR5 (0x195)
  911 +#define SPR_BOOKE_IVOR6 (0x196)
  912 +#define SPR_BOOKE_IVOR7 (0x197)
  913 +#define SPR_BOOKE_IVOR8 (0x198)
  914 +#define SPR_BOOKE_IVOR9 (0x199)
  915 +#define SPR_BOOKE_IVOR10 (0x19A)
  916 +#define SPR_BOOKE_IVOR11 (0x19B)
  917 +#define SPR_BOOKE_IVOR12 (0x19C)
  918 +#define SPR_BOOKE_IVOR13 (0x19D)
  919 +#define SPR_BOOKE_IVOR14 (0x19E)
  920 +#define SPR_BOOKE_IVOR15 (0x19F)
  921 +#define SPR_E500_SPEFSCR (0x200)
  922 +#define SPR_E500_BBEAR (0x201)
  923 +#define SPR_E500_BBTAR (0x202)
  924 +#define SPR_BOOKE_ATBL (0x20E)
  925 +#define SPR_BOOKE_ATBU (0x20F)
  926 +#define SPR_IBAT0U (0x210)
  927 +#define SPR_E500_IVOR32 (0x210)
  928 +#define SPR_IBAT0L (0x211)
  929 +#define SPR_E500_IVOR33 (0x211)
  930 +#define SPR_IBAT1U (0x212)
  931 +#define SPR_E500_IVOR34 (0x212)
  932 +#define SPR_IBAT1L (0x213)
  933 +#define SPR_E500_IVOR35 (0x213)
  934 +#define SPR_IBAT2U (0x214)
  935 +#define SPR_IBAT2L (0x215)
  936 +#define SPR_E500_L1CFG0 (0x215)
  937 +#define SPR_IBAT3U (0x216)
  938 +#define SPR_E500_L1CFG1 (0x216)
  939 +#define SPR_IBAT3L (0x217)
  940 +#define SPR_DBAT0U (0x218)
  941 +#define SPR_DBAT0L (0x219)
  942 +#define SPR_DBAT1U (0x21A)
  943 +#define SPR_DBAT1L (0x21B)
  944 +#define SPR_DBAT2U (0x21C)
  945 +#define SPR_DBAT2L (0x21D)
  946 +#define SPR_DBAT3U (0x21E)
  947 +#define SPR_DBAT3L (0x21F)
  948 +#define SPR_IBAT4U (0x230)
  949 +#define SPR_IBAT4L (0x231)
  950 +#define SPR_IBAT5U (0x232)
  951 +#define SPR_IBAT5L (0x233)
  952 +#define SPR_IBAT6U (0x234)
  953 +#define SPR_IBAT6L (0x235)
  954 +#define SPR_IBAT7U (0x236)
  955 +#define SPR_IBAT7L (0x237)
  956 +#define SPR_DBAT4U (0x238)
  957 +#define SPR_DBAT4L (0x239)
  958 +#define SPR_DBAT5U (0x23A)
  959 +#define SPR_E500_MCSRR0 (0x23A)
  960 +#define SPR_DBAT5L (0x23B)
  961 +#define SPR_E500_MCSRR1 (0x23B)
  962 +#define SPR_DBAT6U (0x23C)
  963 +#define SPR_E500_MCSR (0x23C)
  964 +#define SPR_DBAT6L (0x23D)
  965 +#define SPR_E500_MCAR (0x23D)
  966 +#define SPR_DBAT7U (0x23E)
  967 +#define SPR_DBAT7L (0x23F)
  968 +#define SPR_E500_MAS0 (0x270)
  969 +#define SPR_E500_MAS1 (0x271)
  970 +#define SPR_E500_MAS2 (0x272)
  971 +#define SPR_E500_MAS3 (0x273)
  972 +#define SPR_E500_MAS4 (0x274)
  973 +#define SPR_E500_MAS6 (0x276)
  974 +#define SPR_E500_PID1 (0x279)
  975 +#define SPR_E500_PID2 (0x27A)
  976 +#define SPR_E500_TLB0CFG (0x2B0)
  977 +#define SPR_E500_TLB1CFG (0x2B1)
  978 +#define SPR_440_INV0 (0x370)
  979 +#define SPR_440_INV1 (0x371)
  980 +#define SPR_440_INV2 (0x372)
  981 +#define SPR_440_INV3 (0x373)
  982 +#define SPR_440_IVT0 (0x374)
  983 +#define SPR_440_IVT1 (0x375)
  984 +#define SPR_440_IVT2 (0x376)
  985 +#define SPR_440_IVT3 (0x377)
  986 +#define SPR_440_DNV0 (0x390)
  987 +#define SPR_440_DNV1 (0x391)
  988 +#define SPR_440_DNV2 (0x392)
  989 +#define SPR_440_DNV3 (0x393)
  990 +#define SPR_440_DVT0 (0x394)
  991 +#define SPR_440_DVT1 (0x395)
  992 +#define SPR_440_DVT2 (0x396)
  993 +#define SPR_440_DVT3 (0x397)
  994 +#define SPR_440_DVLIM (0x398)
  995 +#define SPR_440_IVLIM (0x399)
  996 +#define SPR_440_RSTCFG (0x39B)
  997 +#define SPR_440_DCBTRL (0x39C)
  998 +#define SPR_440_DCBTRH (0x39D)
  999 +#define SPR_440_ICBTRL (0x39E)
  1000 +#define SPR_440_ICBTRH (0x39F)
  1001 +#define SPR_UMMCR0 (0x3A8)
  1002 +#define SPR_UPMC1 (0x3A9)
  1003 +#define SPR_UPMC2 (0x3AA)
  1004 +#define SPR_USIA (0x3AB)
  1005 +#define SPR_UMMCR1 (0x3AC)
  1006 +#define SPR_UPMC3 (0x3AD)
  1007 +#define SPR_UPMC4 (0x3AE)
  1008 +#define SPR_USDA (0x3AF)
  1009 +#define SPR_40x_ZPR (0x3B0)
  1010 +#define SPR_E500_MAS7 (0x3B0)
  1011 +#define SPR_40x_PID (0x3B1)
  1012 +#define SPR_440_MMUCR (0x3B2)
  1013 +#define SPR_4xx_CCR0 (0x3B3)
  1014 +#define SPR_405_IAC3 (0x3B4)
  1015 +#define SPR_405_IAC4 (0x3B5)
  1016 +#define SPR_405_DVC1 (0x3B6)
  1017 +#define SPR_405_DVC2 (0x3B7)
  1018 +#define SPR_MMCR0 (0x3B8)
  1019 +#define SPR_PMC1 (0x3B9)
  1020 +#define SPR_40x_SGR (0x3B9)
  1021 +#define SPR_PMC2 (0x3BA)
  1022 +#define SPR_40x_DCWR (0x3BA)
  1023 +#define SPR_SIA (0x3BB)
  1024 +#define SPR_405_SLER (0x3BB)
  1025 +#define SPR_MMCR1 (0x3BC)
  1026 +#define SPR_405_SU0R (0x3BC)
  1027 +#define SPR_PMC3 (0x3BD)
  1028 +#define SPR_405_DBCR1 (0x3BD)
  1029 +#define SPR_PMC4 (0x3BE)
  1030 +#define SPR_SDA (0x3BF)
  1031 +#define SPR_403_VTBL (0x3CC)
  1032 +#define SPR_403_VTBU (0x3CD)
  1033 +#define SPR_DMISS (0x3D0)
  1034 +#define SPR_DCMP (0x3D1)
  1035 +#define SPR_HASH1 (0x3D2)
  1036 +#define SPR_HASH2 (0x3D3)
  1037 +#define SPR_4xx_ICDBDR (0x3D3)
  1038 +#define SPR_IMISS (0x3D4)
  1039 +#define SPR_40x_ESR (0x3D4)
  1040 +#define SPR_ICMP (0x3D5)
  1041 +#define SPR_40x_DEAR (0x3D5)
  1042 +#define SPR_RPA (0x3D6)
  1043 +#define SPR_40x_EVPR (0x3D6)
  1044 +#define SPR_403_CDBCR (0x3D7)
  1045 +#define SPR_TCR (0x3D8)
  1046 +#define SPR_40x_TSR (0x3D8)
  1047 +#define SPR_IBR (0x3DA)
  1048 +#define SPR_40x_TCR (0x3DA)
  1049 +#define SPR_ESASR (0x3DB)
  1050 +#define SPR_40x_PIT (0x3DB)
  1051 +#define SPR_403_TBL (0x3DC)
  1052 +#define SPR_403_TBU (0x3DD)
  1053 +#define SPR_SEBR (0x3DE)
  1054 +#define SPR_40x_SRR2 (0x3DE)
  1055 +#define SPR_SER (0x3DF)
  1056 +#define SPR_40x_SRR3 (0x3DF)
  1057 +#define SPR_HID0 (0x3F0)
  1058 +#define SPR_40x_DBSR (0x3F0)
  1059 +#define SPR_HID1 (0x3F1)
  1060 +#define SPR_IABR (0x3F2)
  1061 +#define SPR_40x_DBCR0 (0x3F2)
  1062 +#define SPR_601_HID2 (0x3F2)
  1063 +#define SPR_E500_L1CSR0 (0x3F2)
  1064 +#define SPR_HID2 (0x3F3)
  1065 +#define SPR_E500_L1CSR1 (0x3F3)
  1066 +#define SPR_440_DBDR (0x3F3)
  1067 +#define SPR_40x_IAC1 (0x3F4)
  1068 +#define SPR_E500_MMUCSR0 (0x3F4)
  1069 +#define SPR_DABR (0x3F5)
878 #define DABR_MASK (~(target_ulong)0x7) 1070 #define DABR_MASK (~(target_ulong)0x7)
879 -#define SPR_40x_IAC2 (0x3F5)  
880 -#define SPR_601_HID5 (0x3F5)  
881 -#define SPR_40x_DAC1 (0x3F6)  
882 -#define SPR_40x_DAC2 (0x3F7)  
883 -#define SPR_L2PM (0x3F8)  
884 -#define SPR_750_HID2 (0x3F8)  
885 -#define SPR_L2CR (0x3F9)  
886 -#define SPR_IABR2 (0x3FA)  
887 -#define SPR_40x_DCCR (0x3FA)  
888 -#define SPR_ICTC (0x3FB)  
889 -#define SPR_40x_ICCR (0x3FB)  
890 -#define SPR_THRM1 (0x3FC)  
891 -#define SPR_403_PBL1 (0x3FC)  
892 -#define SPR_SP (0x3FD)  
893 -#define SPR_THRM2 (0x3FD)  
894 -#define SPR_403_PBU1 (0x3FD)  
895 -#define SPR_LT (0x3FE)  
896 -#define SPR_THRM3 (0x3FE)  
897 -#define SPR_FPECR (0x3FE)  
898 -#define SPR_403_PBL2 (0x3FE)  
899 -#define SPR_PIR (0x3FF)  
900 -#define SPR_403_PBU2 (0x3FF)  
901 -#define SPR_601_HID15 (0x3FF) 1071 +#define SPR_E500_BUCSR (0x3F5)
  1072 +#define SPR_40x_IAC2 (0x3F5)
  1073 +#define SPR_601_HID5 (0x3F5)
  1074 +#define SPR_40x_DAC1 (0x3F6)
  1075 +#define SPR_40x_DAC2 (0x3F7)
  1076 +#define SPR_E500_MMUCFG (0x3F7)
  1077 +#define SPR_L2PM (0x3F8)
  1078 +#define SPR_750_HID2 (0x3F8)
  1079 +#define SPR_L2CR (0x3F9)
  1080 +#define SPR_IABR2 (0x3FA)
  1081 +#define SPR_40x_DCCR (0x3FA)
  1082 +#define SPR_ICTC (0x3FB)
  1083 +#define SPR_40x_ICCR (0x3FB)
  1084 +#define SPR_THRM1 (0x3FC)
  1085 +#define SPR_403_PBL1 (0x3FC)
  1086 +#define SPR_SP (0x3FD)
  1087 +#define SPR_THRM2 (0x3FD)
  1088 +#define SPR_403_PBU1 (0x3FD)
  1089 +#define SPR_LT (0x3FE)
  1090 +#define SPR_THRM3 (0x3FE)
  1091 +#define SPR_FPECR (0x3FE)
  1092 +#define SPR_403_PBL2 (0x3FE)
  1093 +#define SPR_PIR (0x3FF)
  1094 +#define SPR_403_PBU2 (0x3FF)
  1095 +#define SPR_601_HID15 (0x3FF)
  1096 +#define SPR_E500_SVR (0x3FF)
902 1097
  1098 +/*****************************************************************************/
903 /* Memory access type : 1099 /* Memory access type :
904 * may be needed for precise access rights control and precise exceptions. 1100 * may be needed for precise access rights control and precise exceptions.
905 */ 1101 */
@@ -977,7 +1173,7 @@ enum { @@ -977,7 +1173,7 @@ enum {
977 #define EXCP_PPC_MAX 0x4000 1173 #define EXCP_PPC_MAX 0x4000
978 /* Qemu exceptions: special cases we want to stop translation */ 1174 /* Qemu exceptions: special cases we want to stop translation */
979 #define EXCP_MTMSR 0x11000 /* mtmsr instruction: */ 1175 #define EXCP_MTMSR 0x11000 /* mtmsr instruction: */
980 - /* may change privilege level */ 1176 + /* may change privilege level */
981 #define EXCP_BRANCH 0x11001 /* branch instruction */ 1177 #define EXCP_BRANCH 0x11001 /* branch instruction */
982 #define EXCP_SYSCALL_USER 0x12000 /* System call in user mode only */ 1178 #define EXCP_SYSCALL_USER 0x12000 /* System call in user mode only */
983 #define EXCP_INTERRUPT_CRITICAL 0x13000 /* critical IRQ */ 1179 #define EXCP_INTERRUPT_CRITICAL 0x13000 /* critical IRQ */
target-ppc/exec.h
1 /* 1 /*
2 * PowerPC emulation definitions for qemu. 2 * PowerPC emulation definitions for qemu.
3 * 3 *
4 - * Copyright (c) 2003-2005 Jocelyn Mayer 4 + * Copyright (c) 2003-2007 Jocelyn Mayer
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
@@ -24,15 +24,34 @@ @@ -24,15 +24,34 @@
24 24
25 #include "dyngen-exec.h" 25 #include "dyngen-exec.h"
26 26
27 -#define TARGET_LONG_BITS 32 27 +#include "cpu.h"
  28 +#include "exec-all.h"
28 29
29 register struct CPUPPCState *env asm(AREG0); 30 register struct CPUPPCState *env asm(AREG0);
30 -register uint32_t T0 asm(AREG1);  
31 -register uint32_t T1 asm(AREG2);  
32 -register uint32_t T2 asm(AREG3); 31 +#if TARGET_LONG_BITS > HOST_LONG_BITS
  32 +/* no registers can be used */
  33 +#define T0 (env->t0)
  34 +#define T1 (env->t1)
  35 +#define T2 (env->t2)
  36 +#else
  37 +/* This may be more efficient if HOST_LONG_BITS > TARGET_LONG_BITS
  38 + * To be set to one when we'll be sure it does not cause bugs....
  39 + */
  40 +#if 0
  41 +register unsigned long T0 asm(AREG1);
  42 +register unsigned long T1 asm(AREG2);
  43 +register unsigned long T2 asm(AREG3);
  44 +#else
  45 +register target_ulong T0 asm(AREG1);
  46 +register target_ulong T1 asm(AREG2);
  47 +register target_ulong T2 asm(AREG3);
  48 +#endif
  49 +#endif
33 50
  51 +/* XXX: to clean: remove this mess */
34 #define PARAM(n) ((uint32_t)PARAM##n) 52 #define PARAM(n) ((uint32_t)PARAM##n)
35 #define SPARAM(n) ((int32_t)PARAM##n) 53 #define SPARAM(n) ((int32_t)PARAM##n)
  54 +
36 #define FT0 (env->ft0) 55 #define FT0 (env->ft0)
37 #define FT1 (env->ft1) 56 #define FT1 (env->ft1)
38 #define FT2 (env->ft2) 57 #define FT2 (env->ft2)
@@ -43,14 +62,28 @@ register uint32_t T2 asm(AREG3); @@ -43,14 +62,28 @@ register uint32_t T2 asm(AREG3);
43 # define RETURN() __asm__ __volatile__("" : : : "memory"); 62 # define RETURN() __asm__ __volatile__("" : : : "memory");
44 #endif 63 #endif
45 64
46 -#include "cpu.h"  
47 -#include "exec-all.h" 65 +static inline target_ulong rotl8 (target_ulong i, int n)
  66 +{
  67 + return (((uint8_t)i << n) | ((uint8_t)i >> (8 - n)));
  68 +}
  69 +
  70 +static inline target_ulong rotl16 (target_ulong i, int n)
  71 +{
  72 + return (((uint16_t)i << n) | ((uint16_t)i >> (16 - n)));
  73 +}
48 74
49 -static inline uint32_t rotl (uint32_t i, int n) 75 +static inline target_ulong rotl32 (target_ulong i, int n)
50 { 76 {
51 - return ((i << n) | (i >> (32 - n))); 77 + return (((uint32_t)i << n) | ((uint32_t)i >> (32 - n)));
52 } 78 }
53 79
  80 +#if defined(TARGET_PPC64)
  81 +static inline target_ulong rotl64 (target_ulong i, int n)
  82 +{
  83 + return (((uint64_t)i << n) | ((uint64_t)i >> (64 - n)));
  84 +}
  85 +#endif
  86 +
54 #if !defined(CONFIG_USER_ONLY) 87 #if !defined(CONFIG_USER_ONLY)
55 #include "softmmu_exec.h" 88 #include "softmmu_exec.h"
56 #endif /* !defined(CONFIG_USER_ONLY) */ 89 #endif /* !defined(CONFIG_USER_ONLY) */
@@ -58,23 +91,14 @@ static inline uint32_t rotl (uint32_t i, int n) @@ -58,23 +91,14 @@ static inline uint32_t rotl (uint32_t i, int n)
58 void do_raise_exception_err (uint32_t exception, int error_code); 91 void do_raise_exception_err (uint32_t exception, int error_code);
59 void do_raise_exception (uint32_t exception); 92 void do_raise_exception (uint32_t exception);
60 93
61 -void do_sraw(void);  
62 -  
63 -void do_fctiw (void);  
64 -void do_fctiwz (void);  
65 -void do_fnmadd (void);  
66 -void do_fnmsub (void);  
67 -void do_fsqrt (void);  
68 -void do_fres (void);  
69 -void do_frsqrte (void);  
70 -void do_fsel (void);  
71 -void do_fcmpu (void);  
72 -void do_fcmpo (void); 94 +int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong vaddr,
  95 + int rw, int access_type, int check_BATs);
73 96
74 -void do_check_reservation (void);  
75 -void do_icbi (void);  
76 -void do_tlbia (void);  
77 -void do_tlbie (void); 97 +void ppc6xx_tlb_invalidate_all (CPUState *env);
  98 +void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
  99 + int is_code);
  100 +void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
  101 + target_ulong pte0, target_ulong pte1);
78 102
79 static inline void env_to_regs(void) 103 static inline void env_to_regs(void)
80 { 104 {
@@ -84,7 +108,7 @@ static inline void regs_to_env(void) @@ -84,7 +108,7 @@ static inline void regs_to_env(void)
84 { 108 {
85 } 109 }
86 110
87 -int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, 111 +int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
88 int is_user, int is_softmmu); 112 int is_user, int is_softmmu);
89 113
90 #endif /* !defined (__PPC_H__) */ 114 #endif /* !defined (__PPC_H__) */
target-ppc/helper.c
1 /* 1 /*
2 * PowerPC emulation helpers for qemu. 2 * PowerPC emulation helpers for qemu.
3 * 3 *
4 - * Copyright (c) 2003-2005 Jocelyn Mayer 4 + * Copyright (c) 2003-2007 Jocelyn Mayer
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
@@ -30,6 +30,7 @@ @@ -30,6 +30,7 @@
30 30
31 //#define DEBUG_MMU 31 //#define DEBUG_MMU
32 //#define DEBUG_BATS 32 //#define DEBUG_BATS
  33 +//#define DEBUG_SOFTWARE_TLB
33 //#define DEBUG_EXCEPTIONS 34 //#define DEBUG_EXCEPTIONS
34 //#define FLUSH_ALL_TLBS 35 //#define FLUSH_ALL_TLBS
35 36
@@ -55,26 +56,307 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -55,26 +56,307 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
55 } 56 }
56 env->exception_index = exception; 57 env->exception_index = exception;
57 env->error_code = error_code; 58 env->error_code = error_code;
  59 +
58 return 1; 60 return 1;
59 } 61 }
60 -target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) 62 +
  63 +target_ulong cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
61 { 64 {
62 return addr; 65 return addr;
63 } 66 }
64 #else 67 #else
  68 +/* Common routines used by software and hardware TLBs emulation */
  69 +static inline int pte_is_valid (target_ulong pte0)
  70 +{
  71 + return pte0 & 0x80000000 ? 1 : 0;
  72 +}
  73 +
  74 +static inline void pte_invalidate (target_ulong *pte0)
  75 +{
  76 + *pte0 &= ~0x80000000;
  77 +}
  78 +
  79 +#define PTE_PTEM_MASK 0x7FFFFFBF
  80 +#define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
  81 +
  82 +static int pte_check (mmu_ctx_t *ctx,
  83 + target_ulong pte0, target_ulong pte1, int h, int rw)
  84 +{
  85 + int access, ret;
  86 +
  87 + access = 0;
  88 + ret = -1;
  89 + /* Check validity and table match */
  90 + if (pte_is_valid(pte0) && (h == ((pte0 >> 6) & 1))) {
  91 + /* Check vsid & api */
  92 + if ((pte0 & PTE_PTEM_MASK) == ctx->ptem) {
  93 + if (ctx->raddr != (target_ulong)-1) {
  94 + /* all matches should have equal RPN, WIMG & PP */
  95 + if ((ctx->raddr & PTE_CHECK_MASK) != (pte1 & PTE_CHECK_MASK)) {
  96 + if (loglevel > 0)
  97 + fprintf(logfile, "Bad RPN/WIMG/PP\n");
  98 + return -3;
  99 + }
  100 + }
  101 + /* Compute access rights */
  102 + if (ctx->key == 0) {
  103 + access = PAGE_READ;
  104 + if ((pte1 & 0x00000003) != 0x3)
  105 + access |= PAGE_WRITE;
  106 + } else {
  107 + switch (pte1 & 0x00000003) {
  108 + case 0x0:
  109 + access = 0;
  110 + break;
  111 + case 0x1:
  112 + case 0x3:
  113 + access = PAGE_READ;
  114 + break;
  115 + case 0x2:
  116 + access = PAGE_READ | PAGE_WRITE;
  117 + break;
  118 + }
  119 + }
  120 + /* Keep the matching PTE informations */
  121 + ctx->raddr = pte1;
  122 + ctx->prot = access;
  123 + if ((rw == 0 && (access & PAGE_READ)) ||
  124 + (rw == 1 && (access & PAGE_WRITE))) {
  125 + /* Access granted */
  126 +#if defined (DEBUG_MMU)
  127 + if (loglevel > 0)
  128 + fprintf(logfile, "PTE access granted !\n");
  129 +#endif
  130 + ret = 0;
  131 + } else {
  132 + /* Access right violation */
  133 +#if defined (DEBUG_MMU)
  134 + if (loglevel > 0)
  135 + fprintf(logfile, "PTE access rejected\n");
  136 +#endif
  137 + ret = -2;
  138 + }
  139 + }
  140 + }
  141 +
  142 + return ret;
  143 +}
  144 +
  145 +static int pte_update_flags (mmu_ctx_t *ctx, target_ulong *pte1p,
  146 + int ret, int rw)
  147 +{
  148 + int store = 0;
  149 +
  150 + /* Update page flags */
  151 + if (!(*pte1p & 0x00000100)) {
  152 + /* Update accessed flag */
  153 + *pte1p |= 0x00000100;
  154 + store = 1;
  155 + }
  156 + if (!(*pte1p & 0x00000080)) {
  157 + if (rw == 1 && ret == 0) {
  158 + /* Update changed flag */
  159 + *pte1p |= 0x00000080;
  160 + store = 1;
  161 + } else {
  162 + /* Force page fault for first write access */
  163 + ctx->prot &= ~PAGE_WRITE;
  164 + }
  165 + }
  166 +
  167 + return store;
  168 +}
  169 +
  170 +/* Software driven TLB helpers */
  171 +static int ppc6xx_tlb_getnum (CPUState *env, target_ulong eaddr,
  172 + int way, int is_code)
  173 +{
  174 + int nr;
  175 +
  176 + /* Select TLB num in a way from address */
  177 + nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1);
  178 + /* Select TLB way */
  179 + nr += env->tlb_per_way * way;
  180 + /* 6xx have separate TLBs for instructions and data */
  181 + if (is_code && env->id_tlbs == 1)
  182 + nr += env->nb_tlb;
  183 +
  184 + return nr;
  185 +}
  186 +
  187 +void ppc6xx_tlb_invalidate_all (CPUState *env)
  188 +{
  189 + ppc_tlb_t *tlb;
  190 + int nr, max;
  191 +
  192 +#if defined (DEBUG_SOFTWARE_TLB) && 0
  193 + if (loglevel != 0) {
  194 + fprintf(logfile, "Invalidate all TLBs\n");
  195 + }
  196 +#endif
  197 + /* Invalidate all defined software TLB */
  198 + max = env->nb_tlb;
  199 + if (env->id_tlbs == 1)
  200 + max *= 2;
  201 + for (nr = 0; nr < max; nr++) {
  202 + tlb = &env->tlb[nr];
  203 +#if !defined(FLUSH_ALL_TLBS)
  204 + tlb_flush_page(env, tlb->EPN);
  205 +#endif
  206 + pte_invalidate(&tlb->pte0);
  207 + }
  208 +#if defined(FLUSH_ALL_TLBS)
  209 + tlb_flush(env, 1);
  210 +#endif
  211 +}
  212 +
  213 +static inline void __ppc6xx_tlb_invalidate_virt (CPUState *env,
  214 + target_ulong eaddr,
  215 + int is_code, int match_epn)
  216 +{
  217 + ppc_tlb_t *tlb;
  218 + int way, nr;
  219 +
  220 +#if !defined(FLUSH_ALL_TLBS)
  221 + /* Invalidate ITLB + DTLB, all ways */
  222 + for (way = 0; way < env->nb_ways; way++) {
  223 + nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code);
  224 + tlb = &env->tlb[nr];
  225 + if (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) {
  226 +#if defined (DEBUG_SOFTWARE_TLB)
  227 + if (loglevel != 0) {
  228 + fprintf(logfile, "TLB invalidate %d/%d %08x\n",
  229 + nr, env->nb_tlb, eaddr);
  230 + }
  231 +#endif
  232 + pte_invalidate(&tlb->pte0);
  233 + tlb_flush_page(env, tlb->EPN);
  234 + }
  235 + }
  236 +#else
  237 + /* XXX: PowerPC specification say this is valid as well */
  238 + ppc6xx_tlb_invalidate_all(env);
  239 +#endif
  240 +}
  241 +
  242 +void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
  243 + int is_code)
  244 +{
  245 + __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
  246 +}
  247 +
  248 +void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
  249 + target_ulong pte0, target_ulong pte1)
  250 +{
  251 + ppc_tlb_t *tlb;
  252 + int nr;
  253 +
  254 + nr = ppc6xx_tlb_getnum(env, EPN, way, is_code);
  255 + tlb = &env->tlb[nr];
  256 +#if defined (DEBUG_SOFTWARE_TLB)
  257 + if (loglevel != 0) {
  258 + fprintf(logfile, "Set TLB %d/%d EPN %08lx PTE0 %08lx PTE1 %08lx\n",
  259 + nr, env->nb_tlb, (unsigned long)EPN,
  260 + (unsigned long)pte0, (unsigned long)pte1);
  261 + }
  262 +#endif
  263 + /* Invalidate any pending reference in Qemu for this virtual address */
  264 + __ppc6xx_tlb_invalidate_virt(env, EPN, is_code, 1);
  265 + tlb->pte0 = pte0;
  266 + tlb->pte1 = pte1;
  267 + tlb->EPN = EPN;
  268 + tlb->PID = 0;
  269 + tlb->size = 1;
  270 + /* Store last way for LRU mechanism */
  271 + env->last_way = way;
  272 +}
  273 +
  274 +static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx,
  275 + target_ulong eaddr, int rw, int access_type)
  276 +{
  277 + ppc_tlb_t *tlb;
  278 + int nr, best, way;
  279 + int ret;
  280 +
  281 + best = -1;
  282 + ret = -1; /* No TLB found */
  283 + for (way = 0; way < env->nb_ways; way++) {
  284 + nr = ppc6xx_tlb_getnum(env, eaddr, way,
  285 + access_type == ACCESS_CODE ? 1 : 0);
  286 + tlb = &env->tlb[nr];
  287 + /* This test "emulates" the PTE index match for hardware TLBs */
  288 + if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {
  289 +#if defined (DEBUG_SOFTWARE_TLB)
  290 + if (loglevel != 0) {
  291 + fprintf(logfile, "TLB %d/%d %s [%08x %08x] <> %08x\n",
  292 + nr, env->nb_tlb,
  293 + pte_is_valid(tlb->pte0) ? "valid" : "inval",
  294 + tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);
  295 + }
  296 +#endif
  297 + continue;
  298 + }
  299 +#if defined (DEBUG_SOFTWARE_TLB)
  300 + if (loglevel != 0) {
  301 + fprintf(logfile, "TLB %d/%d %s %08x <> %08x %08x %c %c\n",
  302 + nr, env->nb_tlb,
  303 + pte_is_valid(tlb->pte0) ? "valid" : "inval",
  304 + tlb->EPN, eaddr, tlb->pte1,
  305 + rw ? 'S' : 'L', access_type == ACCESS_CODE ? 'I' : 'D');
  306 + }
  307 +#endif
  308 + switch (pte_check(ctx, tlb->pte0, tlb->pte1, 0, rw)) {
  309 + case -3:
  310 + /* TLB inconsistency */
  311 + return -1;
  312 + case -2:
  313 + /* Access violation */
  314 + ret = -2;
  315 + best = nr;
  316 + break;
  317 + case -1:
  318 + default:
  319 + /* No match */
  320 + break;
  321 + case 0:
  322 + /* access granted */
  323 + /* XXX: we should go on looping to check all TLBs consistency
  324 + * but we can speed-up the whole thing as the
  325 + * result would be undefined if TLBs are not consistent.
  326 + */
  327 + ret = 0;
  328 + best = nr;
  329 + goto done;
  330 + }
  331 + }
  332 + if (best != -1) {
  333 + done:
  334 +#if defined (DEBUG_SOFTWARE_TLB)
  335 + if (loglevel > 0) {
  336 + fprintf(logfile, "found TLB at addr 0x%08lx prot=0x%01x ret=%d\n",
  337 + ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
  338 + }
  339 +#endif
  340 + /* Update page flags */
  341 + pte_update_flags(ctx, &env->tlb[best].pte1, ret, rw);
  342 + }
  343 +
  344 + return ret;
  345 +}
  346 +
65 /* Perform BAT hit & translation */ 347 /* Perform BAT hit & translation */
66 -static int get_bat (CPUState *env, uint32_t *real, int *prot,  
67 - uint32_t virtual, int rw, int type) 348 +static int get_bat (CPUState *env, mmu_ctx_t *ctx,
  349 + target_ulong virtual, int rw, int type)
68 { 350 {
69 - uint32_t *BATlt, *BATut, *BATu, *BATl;  
70 - uint32_t base, BEPIl, BEPIu, bl; 351 + target_ulong *BATlt, *BATut, *BATu, *BATl;
  352 + target_ulong base, BEPIl, BEPIu, bl;
71 int i; 353 int i;
72 int ret = -1; 354 int ret = -1;
73 355
74 #if defined (DEBUG_BATS) 356 #if defined (DEBUG_BATS)
75 if (loglevel > 0) { 357 if (loglevel > 0) {
76 fprintf(logfile, "%s: %cBAT v 0x%08x\n", __func__, 358 fprintf(logfile, "%s: %cBAT v 0x%08x\n", __func__,
77 - type == ACCESS_CODE ? 'I' : 'D', virtual); 359 + type == ACCESS_CODE ? 'I' : 'D', virtual);
78 } 360 }
79 #endif 361 #endif
80 switch (type) { 362 switch (type) {
@@ -90,7 +372,7 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot, @@ -90,7 +372,7 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot,
90 #if defined (DEBUG_BATS) 372 #if defined (DEBUG_BATS)
91 if (loglevel > 0) { 373 if (loglevel > 0) {
92 fprintf(logfile, "%s...: %cBAT v 0x%08x\n", __func__, 374 fprintf(logfile, "%s...: %cBAT v 0x%08x\n", __func__,
93 - type == ACCESS_CODE ? 'I' : 'D', virtual); 375 + type == ACCESS_CODE ? 'I' : 'D', virtual);
94 } 376 }
95 #endif 377 #endif
96 base = virtual & 0xFFFC0000; 378 base = virtual & 0xFFFC0000;
@@ -113,18 +395,18 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot, @@ -113,18 +395,18 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot,
113 if ((msr_pr == 0 && (*BATu & 0x00000002)) || 395 if ((msr_pr == 0 && (*BATu & 0x00000002)) ||
114 (msr_pr == 1 && (*BATu & 0x00000001))) { 396 (msr_pr == 1 && (*BATu & 0x00000001))) {
115 /* Get physical address */ 397 /* Get physical address */
116 - *real = (*BATl & 0xF0000000) | 398 + ctx->raddr = (*BATl & 0xF0000000) |
117 ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) | 399 ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
118 (virtual & 0x0001F000); 400 (virtual & 0x0001F000);
119 if (*BATl & 0x00000001) 401 if (*BATl & 0x00000001)
120 - *prot = PAGE_READ; 402 + ctx->prot = PAGE_READ;
121 if (*BATl & 0x00000002) 403 if (*BATl & 0x00000002)
122 - *prot = PAGE_WRITE | PAGE_READ; 404 + ctx->prot = PAGE_WRITE | PAGE_READ;
123 #if defined (DEBUG_BATS) 405 #if defined (DEBUG_BATS)
124 if (loglevel > 0) { 406 if (loglevel > 0) {
125 fprintf(logfile, "BAT %d match: r 0x%08x prot=%c%c\n", 407 fprintf(logfile, "BAT %d match: r 0x%08x prot=%c%c\n",
126 - i, *real, *prot & PAGE_READ ? 'R' : '-',  
127 - *prot & PAGE_WRITE ? 'W' : '-'); 408 + i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-',
  409 + ctx->prot & PAGE_WRITE ? 'W' : '-');
128 } 410 }
129 #endif 411 #endif
130 ret = 0; 412 ret = 0;
@@ -153,189 +435,154 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot, @@ -153,189 +435,154 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot,
153 } 435 }
154 436
155 /* PTE table lookup */ 437 /* PTE table lookup */
156 -static int find_pte (uint32_t *RPN, int *prot, uint32_t base, uint32_t va,  
157 - int h, int key, int rw) 438 +static int find_pte (mmu_ctx_t *ctx, int h, int rw)
158 { 439 {
159 - uint32_t pte0, pte1, keep = 0, access = 0;  
160 - int i, good = -1, store = 0;  
161 - int ret = -1; /* No entry found */ 440 + target_ulong base, pte0, pte1;
  441 + int i, good = -1;
  442 + int ret;
162 443
  444 + ret = -1; /* No entry found */
  445 + base = ctx->pg_addr[h];
163 for (i = 0; i < 8; i++) { 446 for (i = 0; i < 8; i++) {
164 pte0 = ldl_phys(base + (i * 8)); 447 pte0 = ldl_phys(base + (i * 8));
165 pte1 = ldl_phys(base + (i * 8) + 4); 448 pte1 = ldl_phys(base + (i * 8) + 4);
166 #if defined (DEBUG_MMU) 449 #if defined (DEBUG_MMU)
167 if (loglevel > 0) { 450 if (loglevel > 0) {
168 - fprintf(logfile, "Load pte from 0x%08x => 0x%08x 0x%08x "  
169 - "%d %d %d 0x%08x\n", base + (i * 8), pte0, pte1,  
170 - pte0 >> 31, h, (pte0 >> 6) & 1, va);  
171 - }  
172 -#endif  
173 - /* Check validity and table match */  
174 - if (pte0 & 0x80000000 && (h == ((pte0 >> 6) & 1))) {  
175 - /* Check vsid & api */  
176 - if ((pte0 & 0x7FFFFFBF) == va) {  
177 - if (good == -1) {  
178 - good = i;  
179 - keep = pte1;  
180 - } else {  
181 - /* All matches should have equal RPN, WIMG & PP */  
182 - if ((keep & 0xFFFFF07B) != (pte1 & 0xFFFFF07B)) {  
183 - if (loglevel > 0)  
184 - fprintf(logfile, "Bad RPN/WIMG/PP\n");  
185 - return -1;  
186 - }  
187 - }  
188 - /* Check access rights */  
189 - if (key == 0) {  
190 - access = PAGE_READ;  
191 - if ((pte1 & 0x00000003) != 0x3)  
192 - access |= PAGE_WRITE;  
193 - } else {  
194 - switch (pte1 & 0x00000003) {  
195 - case 0x0:  
196 - access = 0;  
197 - break;  
198 - case 0x1:  
199 - case 0x3:  
200 - access = PAGE_READ;  
201 - break;  
202 - case 0x2:  
203 - access = PAGE_READ | PAGE_WRITE;  
204 - break;  
205 - }  
206 - }  
207 - if (ret < 0) {  
208 - if ((rw == 0 && (access & PAGE_READ)) ||  
209 - (rw == 1 && (access & PAGE_WRITE))) {  
210 -#if defined (DEBUG_MMU)  
211 - if (loglevel > 0)  
212 - fprintf(logfile, "PTE access granted !\n");  
213 -#endif  
214 - good = i;  
215 - keep = pte1;  
216 - ret = 0;  
217 - } else {  
218 - /* Access right violation */  
219 - ret = -2;  
220 -#if defined (DEBUG_MMU)  
221 - if (loglevel > 0)  
222 - fprintf(logfile, "PTE access rejected\n"); 451 + fprintf(logfile, "Load pte from 0x%08x => 0x%08x 0x%08x "
  452 + "%d %d %d 0x%08x\n", base + (i * 8), pte0, pte1,
  453 + pte0 >> 31, h, (pte0 >> 6) & 1, ctx->ptem);
  454 + }
223 #endif 455 #endif
224 - }  
225 - *prot = access;  
226 - }  
227 - } 456 + switch (pte_check(ctx, pte0, pte1, h, rw)) {
  457 + case -3:
  458 + /* PTE inconsistency */
  459 + return -1;
  460 + case -2:
  461 + /* Access violation */
  462 + ret = -2;
  463 + good = i;
  464 + break;
  465 + case -1:
  466 + default:
  467 + /* No PTE match */
  468 + break;
  469 + case 0:
  470 + /* access granted */
  471 + /* XXX: we should go on looping to check all PTEs consistency
  472 + * but if we can speed-up the whole thing as the
  473 + * result would be undefined if PTEs are not consistent.
  474 + */
  475 + ret = 0;
  476 + good = i;
  477 + goto done;
228 } 478 }
229 } 479 }
230 if (good != -1) { 480 if (good != -1) {
231 - *RPN = keep & 0xFFFFF000; 481 + done:
232 #if defined (DEBUG_MMU) 482 #if defined (DEBUG_MMU)
233 if (loglevel > 0) { 483 if (loglevel > 0) {
234 - fprintf(logfile, "found PTE at addr 0x%08x prot=0x%01x ret=%d\n",  
235 - *RPN, *prot, ret);  
236 - } 484 + fprintf(logfile, "found PTE at addr 0x%08x prot=0x%01x ret=%d\n",
  485 + ctx->raddr, ctx->prot, ret);
  486 + }
237 #endif 487 #endif
238 /* Update page flags */ 488 /* Update page flags */
239 - if (!(keep & 0x00000100)) {  
240 - /* Access flag */  
241 - keep |= 0x00000100;  
242 - store = 1;  
243 - }  
244 - if (!(keep & 0x00000080)) {  
245 - if (rw && ret == 0) {  
246 - /* Change flag */  
247 - keep |= 0x00000080;  
248 - store = 1;  
249 - } else {  
250 - /* Force page fault for first write access */  
251 - *prot &= ~PAGE_WRITE;  
252 - }  
253 - }  
254 - if (store) {  
255 - stl_phys_notdirty(base + (good * 8) + 4, keep);  
256 - } 489 + pte1 = ctx->raddr;
  490 + if (pte_update_flags(ctx, &pte1, ret, rw) == 1)
  491 + stl_phys_notdirty(base + (good * 8) + 4, pte1);
257 } 492 }
258 493
259 return ret; 494 return ret;
260 } 495 }
261 496
262 -static inline uint32_t get_pgaddr (uint32_t sdr1, uint32_t hash, uint32_t mask) 497 +static inline target_phys_addr_t get_pgaddr (target_phys_addr_t sdr1,
  498 + target_phys_addr_t hash,
  499 + target_phys_addr_t mask)
263 { 500 {
264 return (sdr1 & 0xFFFF0000) | (hash & mask); 501 return (sdr1 & 0xFFFF0000) | (hash & mask);
265 } 502 }
266 503
267 /* Perform segment based translation */ 504 /* Perform segment based translation */
268 -static int get_segment (CPUState *env, uint32_t *real, int *prot,  
269 - uint32_t virtual, int rw, int type) 505 +static int get_segment (CPUState *env, mmu_ctx_t *ctx,
  506 + target_ulong eaddr, int rw, int type)
270 { 507 {
271 - uint32_t pg_addr, sdr, ptem, vsid, pgidx;  
272 - uint32_t hash, mask;  
273 - uint32_t sr;  
274 - int key; 508 + target_phys_addr_t sdr, hash, mask;
  509 + target_ulong sr, vsid, pgidx;
275 int ret = -1, ret2; 510 int ret = -1, ret2;
276 511
277 - sr = env->sr[virtual >> 28]; 512 + sr = env->sr[eaddr >> 28];
278 #if defined (DEBUG_MMU) 513 #if defined (DEBUG_MMU)
279 if (loglevel > 0) { 514 if (loglevel > 0) {
280 - fprintf(logfile, "Check segment v=0x%08x %d 0x%08x nip=0x%08x "  
281 - "lr=0x%08x ir=%d dr=%d pr=%d %d t=%d\n",  
282 - virtual, virtual >> 28, sr, env->nip,  
283 - env->lr, msr_ir, msr_dr, msr_pr, rw, type); 515 + fprintf(logfile, "Check segment v=0x%08x %d 0x%08x nip=0x%08x "
  516 + "lr=0x%08x ir=%d dr=%d pr=%d %d t=%d\n",
  517 + eaddr, eaddr >> 28, sr, env->nip,
  518 + env->lr, msr_ir, msr_dr, msr_pr, rw, type);
284 } 519 }
285 #endif 520 #endif
286 - key = (((sr & 0x20000000) && msr_pr == 1) ||  
287 - ((sr & 0x40000000) && msr_pr == 0)) ? 1 : 0; 521 + ctx->key = (((sr & 0x20000000) && msr_pr == 1) ||
  522 + ((sr & 0x40000000) && msr_pr == 0)) ? 1 : 0;
288 if ((sr & 0x80000000) == 0) { 523 if ((sr & 0x80000000) == 0) {
289 #if defined (DEBUG_MMU) 524 #if defined (DEBUG_MMU)
290 - if (loglevel > 0)  
291 - fprintf(logfile, "pte segment: key=%d n=0x%08x\n",  
292 - key, sr & 0x10000000); 525 + if (loglevel > 0)
  526 + fprintf(logfile, "pte segment: key=%d n=0x%08x\n",
  527 + ctx->key, sr & 0x10000000);
293 #endif 528 #endif
294 /* Check if instruction fetch is allowed, if needed */ 529 /* Check if instruction fetch is allowed, if needed */
295 if (type != ACCESS_CODE || (sr & 0x10000000) == 0) { 530 if (type != ACCESS_CODE || (sr & 0x10000000) == 0) {
296 /* Page address translation */ 531 /* Page address translation */
  532 + pgidx = (eaddr >> TARGET_PAGE_BITS) & 0xFFFF;
297 vsid = sr & 0x00FFFFFF; 533 vsid = sr & 0x00FFFFFF;
298 - pgidx = (virtual >> 12) & 0xFFFF;  
299 - sdr = env->sdr1;  
300 hash = ((vsid ^ pgidx) & 0x0007FFFF) << 6; 534 hash = ((vsid ^ pgidx) & 0x0007FFFF) << 6;
  535 + /* Primary table address */
  536 + sdr = env->sdr1;
301 mask = ((sdr & 0x000001FF) << 16) | 0xFFC0; 537 mask = ((sdr & 0x000001FF) << 16) | 0xFFC0;
302 - pg_addr = get_pgaddr(sdr, hash, mask);  
303 - ptem = (vsid << 7) | (pgidx >> 10); 538 + ctx->pg_addr[0] = get_pgaddr(sdr, hash, mask);
  539 + /* Secondary table address */
  540 + hash = (~hash) & 0x01FFFFC0;
  541 + ctx->pg_addr[1] = get_pgaddr(sdr, hash, mask);
  542 + ctx->ptem = (vsid << 7) | (pgidx >> 10);
  543 + /* Initialize real address with an invalid value */
  544 + ctx->raddr = (target_ulong)-1;
  545 + if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
  546 + /* Software TLB search */
  547 + ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
  548 + } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
  549 + /* XXX: TODO */
  550 + } else {
304 #if defined (DEBUG_MMU) 551 #if defined (DEBUG_MMU)
305 - if (loglevel > 0) {  
306 - fprintf(logfile, "0 sdr1=0x%08x vsid=0x%06x api=0x%04x "  
307 - "hash=0x%07x pg_addr=0x%08x\n", sdr, vsid, pgidx, hash,  
308 - pg_addr);  
309 - } 552 + if (loglevel > 0) {
  553 + fprintf(logfile, "0 sdr1=0x%08x vsid=0x%06x api=0x%04x "
  554 + "hash=0x%07x pg_addr=0x%08x\n", sdr, vsid, pgidx,
  555 + hash, ctx->pg_addr[0]);
  556 + }
310 #endif 557 #endif
311 - /* Primary table lookup */  
312 - ret = find_pte(real, prot, pg_addr, ptem, 0, key, rw);  
313 - if (ret < 0) {  
314 - /* Secondary table lookup */  
315 - hash = (~hash) & 0x01FFFFC0;  
316 - pg_addr = get_pgaddr(sdr, hash, mask); 558 + /* Primary table lookup */
  559 + ret = find_pte(ctx, 0, rw);
  560 + if (ret < 0) {
  561 + /* Secondary table lookup */
317 #if defined (DEBUG_MMU) 562 #if defined (DEBUG_MMU)
318 - if (virtual != 0xEFFFFFFF && loglevel > 0) {  
319 - fprintf(logfile, "1 sdr1=0x%08x vsid=0x%06x api=0x%04x "  
320 - "hash=0x%05x pg_addr=0x%08x\n", sdr, vsid, pgidx,  
321 - hash, pg_addr);  
322 - } 563 + if (eaddr != 0xEFFFFFFF && loglevel > 0) {
  564 + fprintf(logfile,
  565 + "1 sdr1=0x%08x vsid=0x%06x api=0x%04x "
  566 + "hash=0x%05x pg_addr=0x%08x\n", sdr, vsid,
  567 + pgidx, hash, ctx->pg_addr[1]);
  568 + }
323 #endif 569 #endif
324 - ret2 = find_pte(real, prot, pg_addr, ptem, 1, key, rw);  
325 - if (ret2 != -1)  
326 - ret = ret2; 570 + ret2 = find_pte(ctx, 1, rw);
  571 + if (ret2 != -1)
  572 + ret = ret2;
  573 + }
327 } 574 }
328 } else { 575 } else {
329 #if defined (DEBUG_MMU) 576 #if defined (DEBUG_MMU)
330 - if (loglevel > 0)  
331 - fprintf(logfile, "No access allowed\n"); 577 + if (loglevel > 0)
  578 + fprintf(logfile, "No access allowed\n");
332 #endif 579 #endif
333 - ret = -3; 580 + ret = -3;
334 } 581 }
335 } else { 582 } else {
336 #if defined (DEBUG_MMU) 583 #if defined (DEBUG_MMU)
337 if (loglevel > 0) 584 if (loglevel > 0)
338 - fprintf(logfile, "direct store...\n"); 585 + fprintf(logfile, "direct store...\n");
339 #endif 586 #endif
340 /* Direct-store segment : absolutely *BUGGY* for now */ 587 /* Direct-store segment : absolutely *BUGGY* for now */
341 switch (type) { 588 switch (type) {
@@ -356,7 +603,7 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot, @@ -356,7 +603,7 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot,
356 /* Should make the instruction do no-op. 603 /* Should make the instruction do no-op.
357 * As it already do no-op, it's quite easy :-) 604 * As it already do no-op, it's quite easy :-)
358 */ 605 */
359 - *real = virtual; 606 + ctx->raddr = eaddr;
360 return 0; 607 return 0;
361 case ACCESS_EXT: 608 case ACCESS_EXT:
362 /* eciwx or ecowx */ 609 /* eciwx or ecowx */
@@ -370,8 +617,8 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot, @@ -370,8 +617,8 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot,
370 "address translation\n"); 617 "address translation\n");
371 return -4; 618 return -4;
372 } 619 }
373 - if ((rw == 1 || key != 1) && (rw == 0 || key != 0)) {  
374 - *real = virtual; 620 + if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) {
  621 + ctx->raddr = eaddr;
375 ret = 2; 622 ret = 2;
376 } else { 623 } else {
377 ret = -2; 624 ret = -2;
@@ -381,8 +628,44 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot, @@ -381,8 +628,44 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot,
381 return ret; 628 return ret;
382 } 629 }
383 630
384 -static int get_physical_address (CPUState *env, uint32_t *physical, int *prot,  
385 - uint32_t address, int rw, int access_type) 631 +static int check_physical (CPUState *env, mmu_ctx_t *ctx,
  632 + target_ulong eaddr, int rw)
  633 +{
  634 + int in_plb, ret;
  635 +
  636 + ctx->raddr = eaddr;
  637 + ctx->prot = PAGE_READ;
  638 + ret = 0;
  639 + if (unlikely(msr_pe != 0 && PPC_MMU(env) == PPC_FLAGS_MMU_403)) {
  640 + /* 403 family add some particular protections,
  641 + * using PBL/PBU registers for accesses with no translation.
  642 + */
  643 + in_plb =
  644 + /* Check PLB validity */
  645 + (env->pb[0] < env->pb[1] &&
  646 + /* and address in plb area */
  647 + eaddr >= env->pb[0] && eaddr < env->pb[1]) ||
  648 + (env->pb[2] < env->pb[3] &&
  649 + eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0;
  650 + if (in_plb ^ msr_px) {
  651 + /* Access in protected area */
  652 + if (rw == 1) {
  653 + /* Access is not allowed */
  654 + ret = -2;
  655 + }
  656 + } else {
  657 + /* Read-write access is allowed */
  658 + ctx->prot |= PAGE_WRITE;
  659 + }
  660 + } else {
  661 + ctx->prot |= PAGE_WRITE;
  662 + }
  663 +
  664 + return ret;
  665 +}
  666 +
  667 +int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
  668 + int rw, int access_type, int check_BATs)
386 { 669 {
387 int ret; 670 int ret;
388 #if 0 671 #if 0
@@ -393,46 +676,46 @@ static int get_physical_address (CPUState *env, uint32_t *physical, int *prot, @@ -393,46 +676,46 @@ static int get_physical_address (CPUState *env, uint32_t *physical, int *prot,
393 if ((access_type == ACCESS_CODE && msr_ir == 0) || 676 if ((access_type == ACCESS_CODE && msr_ir == 0) ||
394 (access_type != ACCESS_CODE && msr_dr == 0)) { 677 (access_type != ACCESS_CODE && msr_dr == 0)) {
395 /* No address translation */ 678 /* No address translation */
396 - *physical = address & ~0xFFF;  
397 - *prot = PAGE_READ | PAGE_WRITE;  
398 - ret = 0; 679 + ret = check_physical(env, ctx, eaddr, rw);
399 } else { 680 } else {
400 /* Try to find a BAT */ 681 /* Try to find a BAT */
401 - ret = get_bat(env, physical, prot, address, rw, access_type); 682 + ret = -1;
  683 + if (check_BATs)
  684 + ret = get_bat(env, ctx, eaddr, rw, access_type);
402 if (ret < 0) { 685 if (ret < 0) {
403 /* We didn't match any BAT entry */ 686 /* We didn't match any BAT entry */
404 - ret = get_segment(env, physical, prot, address, rw, access_type); 687 + ret = get_segment(env, ctx, eaddr, rw, access_type);
405 } 688 }
406 } 689 }
407 #if 0 690 #if 0
408 if (loglevel > 0) { 691 if (loglevel > 0) {
409 - fprintf(logfile, "%s address %08x => %08x\n",  
410 - __func__, address, *physical); 692 + fprintf(logfile, "%s address %08x => %08lx\n",
  693 + __func__, eaddr, ctx->raddr);
411 } 694 }
412 -#endif 695 +#endif
  696 +
413 return ret; 697 return ret;
414 } 698 }
415 699
416 -target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) 700 +target_ulong cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
417 { 701 {
418 - uint32_t phys_addr;  
419 - int prot; 702 + mmu_ctx_t ctx;
420 703
421 - if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT) != 0) 704 + if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT, 1) != 0))
422 return -1; 705 return -1;
423 - return phys_addr; 706 +
  707 + return ctx.raddr & TARGET_PAGE_MASK;
424 } 708 }
425 709
426 /* Perform address translation */ 710 /* Perform address translation */
427 int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, 711 int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
428 int is_user, int is_softmmu) 712 int is_user, int is_softmmu)
429 { 713 {
430 - uint32_t physical;  
431 - int prot; 714 + mmu_ctx_t ctx;
432 int exception = 0, error_code = 0; 715 int exception = 0, error_code = 0;
433 int access_type; 716 int access_type;
434 int ret = 0; 717 int ret = 0;
435 - 718 +
436 if (rw == 2) { 719 if (rw == 2) {
437 /* code access */ 720 /* code access */
438 rw = 0; 721 rw = 0;
@@ -444,35 +727,39 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -444,35 +727,39 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
444 access_type = ACCESS_INT; 727 access_type = ACCESS_INT;
445 // access_type = env->access_type; 728 // access_type = env->access_type;
446 } 729 }
447 - if (env->user_mode_only) {  
448 - /* user mode only emulation */  
449 - ret = -2;  
450 - goto do_fault;  
451 - }  
452 - ret = get_physical_address(env, &physical, &prot,  
453 - address, rw, access_type); 730 + ret = get_physical_address(env, &ctx, address, rw, access_type, 1);
454 if (ret == 0) { 731 if (ret == 0) {
455 - ret = tlb_set_page(env, address & ~0xFFF, physical, prot,  
456 - is_user, is_softmmu); 732 + ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
  733 + ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
  734 + is_user, is_softmmu);
457 } else if (ret < 0) { 735 } else if (ret < 0) {
458 - do_fault:  
459 #if defined (DEBUG_MMU) 736 #if defined (DEBUG_MMU)
460 - if (loglevel > 0)  
461 - cpu_dump_state(env, logfile, fprintf, 0); 737 + if (loglevel > 0)
  738 + cpu_dump_state(env, logfile, fprintf, 0);
462 #endif 739 #endif
463 if (access_type == ACCESS_CODE) { 740 if (access_type == ACCESS_CODE) {
464 exception = EXCP_ISI; 741 exception = EXCP_ISI;
465 switch (ret) { 742 switch (ret) {
466 case -1: 743 case -1:
467 - /* No matches in page tables */  
468 - error_code = 0x40000000; 744 + /* No matches in page tables or TLB */
  745 + if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
  746 + exception = EXCP_I_TLBMISS;
  747 + env->spr[SPR_IMISS] = address;
  748 + env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
  749 + error_code = 1 << 18;
  750 + goto tlb_miss;
  751 + } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
  752 + /* XXX: TODO */
  753 + } else {
  754 + error_code = 0x40000000;
  755 + }
469 break; 756 break;
470 case -2: 757 case -2:
471 /* Access rights violation */ 758 /* Access rights violation */
472 error_code = 0x08000000; 759 error_code = 0x08000000;
473 break; 760 break;
474 case -3: 761 case -3:
475 - /* No execute protection violation */ 762 + /* No execute protection violation */
476 error_code = 0x10000000; 763 error_code = 0x10000000;
477 break; 764 break;
478 case -4: 765 case -4:
@@ -490,8 +777,28 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -490,8 +777,28 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
490 exception = EXCP_DSI; 777 exception = EXCP_DSI;
491 switch (ret) { 778 switch (ret) {
492 case -1: 779 case -1:
493 - /* No matches in page tables */  
494 - error_code = 0x40000000; 780 + /* No matches in page tables or TLB */
  781 + if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
  782 + if (rw == 1) {
  783 + exception = EXCP_DS_TLBMISS;
  784 + error_code = 1 << 16;
  785 + } else {
  786 + exception = EXCP_DL_TLBMISS;
  787 + error_code = 0;
  788 + }
  789 + env->spr[SPR_DMISS] = address;
  790 + env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
  791 + tlb_miss:
  792 + error_code |= ctx.key << 19;
  793 + env->spr[SPR_HASH1] = ctx.pg_addr[0];
  794 + env->spr[SPR_HASH2] = ctx.pg_addr[1];
  795 + /* Do not alter DAR nor DSISR */
  796 + goto out;
  797 + } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
  798 + /* XXX: TODO */
  799 + } else {
  800 + error_code = 0x40000000;
  801 + }
495 break; 802 break;
496 case -2: 803 case -2:
497 /* Access rights violation */ 804 /* Access rights violation */
@@ -514,7 +821,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -514,7 +821,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
514 error_code = 0x04100000; 821 error_code = 0x04100000;
515 break; 822 break;
516 default: 823 default:
517 - printf("DSI: invalid exception (%d)\n", ret); 824 + printf("DSI: invalid exception (%d)\n", ret);
518 exception = EXCP_PROGRAM; 825 exception = EXCP_PROGRAM;
519 error_code = EXCP_INVAL | EXCP_INVAL_INVAL; 826 error_code = EXCP_INVAL | EXCP_INVAL_INVAL;
520 break; 827 break;
@@ -528,10 +835,11 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -528,10 +835,11 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
528 } 835 }
529 if (exception == EXCP_DSI && rw == 1) 836 if (exception == EXCP_DSI && rw == 1)
530 error_code |= 0x02000000; 837 error_code |= 0x02000000;
531 - /* Store fault address */  
532 - env->spr[SPR_DAR] = address; 838 + /* Store fault address */
  839 + env->spr[SPR_DAR] = address;
533 env->spr[SPR_DSISR] = error_code; 840 env->spr[SPR_DSISR] = error_code;
534 } 841 }
  842 + out:
535 #if 0 843 #if 0
536 printf("%s: set exception to %d %02x\n", 844 printf("%s: set exception to %d %02x\n",
537 __func__, exception, error_code); 845 __func__, exception, error_code);
@@ -540,9 +848,9 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -540,9 +848,9 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
540 env->error_code = error_code; 848 env->error_code = error_code;
541 ret = 1; 849 ret = 1;
542 } 850 }
  851 +
543 return ret; 852 return ret;
544 } 853 }
545 -#endif  
546 854
547 /*****************************************************************************/ 855 /*****************************************************************************/
548 /* BATs management */ 856 /* BATs management */
@@ -551,11 +859,14 @@ static inline void do_invalidate_BAT (CPUPPCState *env, @@ -551,11 +859,14 @@ static inline void do_invalidate_BAT (CPUPPCState *env,
551 target_ulong BATu, target_ulong mask) 859 target_ulong BATu, target_ulong mask)
552 { 860 {
553 target_ulong base, end, page; 861 target_ulong base, end, page;
  862 +
554 base = BATu & ~0x0001FFFF; 863 base = BATu & ~0x0001FFFF;
555 end = base + mask + 0x00020000; 864 end = base + mask + 0x00020000;
556 #if defined (DEBUG_BATS) 865 #if defined (DEBUG_BATS)
557 - if (loglevel != 0)  
558 - fprintf(logfile, "Flush BAT from %08x to %08x (%08x)\n", base, end, mask); 866 + if (loglevel != 0) {
  867 + fprintf(logfile, "Flush BAT from %08x to %08x (%08x)\n",
  868 + base, end, mask);
  869 + }
559 #endif 870 #endif
560 for (page = base; page != end; page += TARGET_PAGE_SIZE) 871 for (page = base; page != end; page += TARGET_PAGE_SIZE)
561 tlb_flush_page(env, page); 872 tlb_flush_page(env, page);
@@ -608,8 +919,7 @@ void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value) @@ -608,8 +919,7 @@ void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
608 (env->IBAT[1][nr] & ~0x0001FFFF & ~mask); 919 (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
609 #if !defined(FLUSH_ALL_TLBS) 920 #if !defined(FLUSH_ALL_TLBS)
610 do_invalidate_BAT(env, env->IBAT[0][nr], mask); 921 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
611 -#endif  
612 -#if defined(FLUSH_ALL_TLBS) 922 +#else
613 tlb_flush(env, 1); 923 tlb_flush(env, 1);
614 #endif 924 #endif
615 } 925 }
@@ -663,24 +973,8 @@ void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value) @@ -663,24 +973,8 @@ void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
663 env->DBAT[1][nr] = value; 973 env->DBAT[1][nr] = value;
664 } 974 }
665 975
666 -static inline void invalidate_all_tlbs (CPUPPCState *env)  
667 -{  
668 - /* XXX: this needs to be completed for sotware driven TLB support */  
669 - tlb_flush(env, 1);  
670 -}  
671 -  
672 /*****************************************************************************/ 976 /*****************************************************************************/
673 /* Special registers manipulation */ 977 /* Special registers manipulation */
674 -target_ulong do_load_nip (CPUPPCState *env)  
675 -{  
676 - return env->nip;  
677 -}  
678 -  
679 -void do_store_nip (CPUPPCState *env, target_ulong value)  
680 -{  
681 - env->nip = value;  
682 -}  
683 -  
684 target_ulong do_load_sdr1 (CPUPPCState *env) 978 target_ulong do_load_sdr1 (CPUPPCState *env)
685 { 979 {
686 return env->sdr1; 980 return env->sdr1;
@@ -695,7 +989,7 @@ void do_store_sdr1 (CPUPPCState *env, target_ulong value) @@ -695,7 +989,7 @@ void do_store_sdr1 (CPUPPCState *env, target_ulong value)
695 #endif 989 #endif
696 if (env->sdr1 != value) { 990 if (env->sdr1 != value) {
697 env->sdr1 = value; 991 env->sdr1 = value;
698 - invalidate_all_tlbs(env); 992 + tlb_flush(env, 1);
699 } 993 }
700 } 994 }
701 995
@@ -724,34 +1018,13 @@ void do_store_sr (CPUPPCState *env, int srnum, target_ulong value) @@ -724,34 +1018,13 @@ void do_store_sr (CPUPPCState *env, int srnum, target_ulong value)
724 tlb_flush_page(env, page); 1018 tlb_flush_page(env, page);
725 } 1019 }
726 #else 1020 #else
727 - invalidate_all_tlbs(env); 1021 + tlb_flush(env, 1);
728 #endif 1022 #endif
729 } 1023 }
730 } 1024 }
  1025 +#endif /* !defined (CONFIG_USER_ONLY) */
731 1026
732 -uint32_t do_load_cr (CPUPPCState *env)  
733 -{  
734 - return (env->crf[0] << 28) |  
735 - (env->crf[1] << 24) |  
736 - (env->crf[2] << 20) |  
737 - (env->crf[3] << 16) |  
738 - (env->crf[4] << 12) |  
739 - (env->crf[5] << 8) |  
740 - (env->crf[6] << 4) |  
741 - (env->crf[7] << 0);  
742 -}  
743 -  
744 -void do_store_cr (CPUPPCState *env, uint32_t value, uint32_t mask)  
745 -{  
746 - int i, sh;  
747 -  
748 - for (i = 0, sh = 7; i < 8; i++, sh --) {  
749 - if (mask & (1 << sh))  
750 - env->crf[i] = (value >> (sh * 4)) & 0xFUL;  
751 - }  
752 -}  
753 -  
754 -uint32_t do_load_xer (CPUPPCState *env) 1027 +uint32_t ppc_load_xer (CPUPPCState *env)
755 { 1028 {
756 return (xer_so << XER_SO) | 1029 return (xer_so << XER_SO) |
757 (xer_ov << XER_OV) | 1030 (xer_ov << XER_OV) |
@@ -760,7 +1033,7 @@ uint32_t do_load_xer (CPUPPCState *env) @@ -760,7 +1033,7 @@ uint32_t do_load_xer (CPUPPCState *env)
760 (xer_cmp << XER_CMP); 1033 (xer_cmp << XER_CMP);
761 } 1034 }
762 1035
763 -void do_store_xer (CPUPPCState *env, uint32_t value) 1036 +void ppc_store_xer (CPUPPCState *env, uint32_t value)
764 { 1037 {
765 xer_so = (value >> XER_SO) & 0x01; 1038 xer_so = (value >> XER_SO) & 0x01;
766 xer_ov = (value >> XER_OV) & 0x01; 1039 xer_ov = (value >> XER_OV) & 0x01;
@@ -769,40 +1042,58 @@ void do_store_xer (CPUPPCState *env, uint32_t value) @@ -769,40 +1042,58 @@ void do_store_xer (CPUPPCState *env, uint32_t value)
769 xer_bc = (value >> XER_BC) & 0x3F; 1042 xer_bc = (value >> XER_BC) & 0x3F;
770 } 1043 }
771 1044
772 -target_ulong do_load_msr (CPUPPCState *env) 1045 +/* Swap temporary saved registers with GPRs */
  1046 +static inline void swap_gpr_tgpr (CPUPPCState *env)
773 { 1047 {
774 - return (msr_vr << MSR_VR) |  
775 - (msr_ap << MSR_AP) |  
776 - (msr_sa << MSR_SA) |  
777 - (msr_key << MSR_KEY) |  
778 - (msr_pow << MSR_POW) |  
779 - (msr_tlb << MSR_TLB) |  
780 - (msr_ile << MSR_ILE) |  
781 - (msr_ee << MSR_EE) |  
782 - (msr_pr << MSR_PR) |  
783 - (msr_fp << MSR_FP) |  
784 - (msr_me << MSR_ME) |  
785 - (msr_fe0 << MSR_FE0) |  
786 - (msr_se << MSR_SE) |  
787 - (msr_be << MSR_BE) |  
788 - (msr_fe1 << MSR_FE1) |  
789 - (msr_al << MSR_AL) |  
790 - (msr_ip << MSR_IP) |  
791 - (msr_ir << MSR_IR) |  
792 - (msr_dr << MSR_DR) |  
793 - (msr_pe << MSR_PE) |  
794 - (msr_px << MSR_PX) |  
795 - (msr_ri << MSR_RI) |  
796 - (msr_le << MSR_LE); 1048 + ppc_gpr_t tmp;
  1049 +
  1050 + tmp = env->gpr[0];
  1051 + env->gpr[0] = env->tgpr[0];
  1052 + env->tgpr[0] = tmp;
  1053 + tmp = env->gpr[1];
  1054 + env->gpr[1] = env->tgpr[1];
  1055 + env->tgpr[1] = tmp;
  1056 + tmp = env->gpr[2];
  1057 + env->gpr[2] = env->tgpr[2];
  1058 + env->tgpr[2] = tmp;
  1059 + tmp = env->gpr[3];
  1060 + env->gpr[3] = env->tgpr[3];
  1061 + env->tgpr[3] = tmp;
797 } 1062 }
798 1063
799 -void do_compute_hflags (CPUPPCState *env) 1064 +/* GDBstub can read and write MSR... */
  1065 +target_ulong do_load_msr (CPUPPCState *env)
800 { 1066 {
801 - /* Compute current hflags */  
802 - env->hflags = (msr_pr << MSR_PR) | (msr_le << MSR_LE) |  
803 - (msr_fp << MSR_FP) | (msr_fe0 << MSR_FE0) | (msr_fe1 << MSR_FE1) |  
804 - (msr_vr << MSR_VR) | (msr_ap << MSR_AP) | (msr_sa << MSR_SA) |  
805 - (msr_se << MSR_SE) | (msr_be << MSR_BE); 1067 + return
  1068 +#if defined (TARGET_PPC64)
  1069 + (msr_sf << MSR_SF) |
  1070 + (msr_isf << MSR_ISF) |
  1071 + (msr_hv << MSR_HV) |
  1072 +#endif
  1073 + (msr_ucle << MSR_UCLE) |
  1074 + (msr_vr << MSR_VR) | /* VR / SPE */
  1075 + (msr_ap << MSR_AP) |
  1076 + (msr_sa << MSR_SA) |
  1077 + (msr_key << MSR_KEY) |
  1078 + (msr_pow << MSR_POW) | /* POW / WE */
  1079 + (msr_tlb << MSR_TLB) | /* TLB / TGPE / CE */
  1080 + (msr_ile << MSR_ILE) |
  1081 + (msr_ee << MSR_EE) |
  1082 + (msr_pr << MSR_PR) |
  1083 + (msr_fp << MSR_FP) |
  1084 + (msr_me << MSR_ME) |
  1085 + (msr_fe0 << MSR_FE0) |
  1086 + (msr_se << MSR_SE) | /* SE / DWE / UBLE */
  1087 + (msr_be << MSR_BE) | /* BE / DE */
  1088 + (msr_fe1 << MSR_FE1) |
  1089 + (msr_al << MSR_AL) |
  1090 + (msr_ip << MSR_IP) |
  1091 + (msr_ir << MSR_IR) | /* IR / IS */
  1092 + (msr_dr << MSR_DR) | /* DR / DS */
  1093 + (msr_pe << MSR_PE) | /* PE / EP */
  1094 + (msr_px << MSR_PX) | /* PX / PMM */
  1095 + (msr_ri << MSR_RI) |
  1096 + (msr_le << MSR_LE);
806 } 1097 }
807 1098
808 void do_store_msr (CPUPPCState *env, target_ulong value) 1099 void do_store_msr (CPUPPCState *env, target_ulong value)
@@ -812,10 +1103,7 @@ void do_store_msr (CPUPPCState *env, target_ulong value) @@ -812,10 +1103,7 @@ void do_store_msr (CPUPPCState *env, target_ulong value)
812 value &= env->msr_mask; 1103 value &= env->msr_mask;
813 if (((value >> MSR_IR) & 1) != msr_ir || 1104 if (((value >> MSR_IR) & 1) != msr_ir ||
814 ((value >> MSR_DR) & 1) != msr_dr) { 1105 ((value >> MSR_DR) & 1) != msr_dr) {
815 - /* Flush all tlb when changing translation mode  
816 - * When using software driven TLB, we may also need to reload  
817 - * all defined TLBs  
818 - */ 1106 + /* Flush all tlb when changing translation mode */
819 tlb_flush(env, 1); 1107 tlb_flush(env, 1);
820 env->interrupt_request |= CPU_INTERRUPT_EXITTB; 1108 env->interrupt_request |= CPU_INTERRUPT_EXITTB;
821 } 1109 }
@@ -824,35 +1112,52 @@ void do_store_msr (CPUPPCState *env, target_ulong value) @@ -824,35 +1112,52 @@ void do_store_msr (CPUPPCState *env, target_ulong value)
824 fprintf(logfile, "%s: T0 %08lx\n", __func__, value); 1112 fprintf(logfile, "%s: T0 %08lx\n", __func__, value);
825 } 1113 }
826 #endif 1114 #endif
827 - msr_vr = (value >> MSR_VR) & 1;  
828 - msr_ap = (value >> MSR_AP) & 1;  
829 - msr_sa = (value >> MSR_SA) & 1;  
830 - msr_key = (value >> MSR_KEY) & 1;  
831 - msr_pow = (value >> MSR_POW) & 1;  
832 - msr_tlb = (value >> MSR_TLB) & 1;  
833 - msr_ile = (value >> MSR_ILE) & 1;  
834 - msr_ee = (value >> MSR_EE) & 1;  
835 - msr_pr = (value >> MSR_PR) & 1;  
836 - msr_fp = (value >> MSR_FP) & 1;  
837 - msr_me = (value >> MSR_ME) & 1;  
838 - msr_fe0 = (value >> MSR_FE0) & 1;  
839 - msr_se = (value >> MSR_SE) & 1;  
840 - msr_be = (value >> MSR_BE) & 1;  
841 - msr_fe1 = (value >> MSR_FE1) & 1;  
842 - msr_al = (value >> MSR_AL) & 1;  
843 - msr_ip = (value >> MSR_IP) & 1;  
844 - msr_ir = (value >> MSR_IR) & 1;  
845 - msr_dr = (value >> MSR_DR) & 1;  
846 - msr_pe = (value >> MSR_PE) & 1;  
847 - msr_px = (value >> MSR_PX) & 1;  
848 - msr_ri = (value >> MSR_RI) & 1;  
849 - msr_le = (value >> MSR_LE) & 1; 1115 + switch (PPC_EXCP(env)) {
  1116 + case PPC_FLAGS_EXCP_602:
  1117 + case PPC_FLAGS_EXCP_603:
  1118 + if (((value >> MSR_TGPR) & 1) != msr_tgpr) {
  1119 + /* Swap temporary saved registers with GPRs */
  1120 + swap_gpr_tgpr(env);
  1121 + }
  1122 + break;
  1123 + default:
  1124 + break;
  1125 + }
  1126 +#if defined (TARGET_PPC64)
  1127 + msr_sf = (value >> MSR_SF) & 1;
  1128 + msr_isf = (value >> MSR_ISF) & 1;
  1129 + msr_hv = (value >> MSR_HV) & 1;
  1130 +#endif
  1131 + msr_ucle = (value >> MSR_UCLE) & 1;
  1132 + msr_vr = (value >> MSR_VR) & 1; /* VR / SPE */
  1133 + msr_ap = (value >> MSR_AP) & 1;
  1134 + msr_sa = (value >> MSR_SA) & 1;
  1135 + msr_key = (value >> MSR_KEY) & 1;
  1136 + msr_pow = (value >> MSR_POW) & 1; /* POW / WE */
  1137 + msr_tlb = (value >> MSR_TLB) & 1; /* TLB / TGPR / CE */
  1138 + msr_ile = (value >> MSR_ILE) & 1;
  1139 + msr_ee = (value >> MSR_EE) & 1;
  1140 + msr_pr = (value >> MSR_PR) & 1;
  1141 + msr_fp = (value >> MSR_FP) & 1;
  1142 + msr_me = (value >> MSR_ME) & 1;
  1143 + msr_fe0 = (value >> MSR_FE0) & 1;
  1144 + msr_se = (value >> MSR_SE) & 1; /* SE / DWE / UBLE */
  1145 + msr_be = (value >> MSR_BE) & 1; /* BE / DE */
  1146 + msr_fe1 = (value >> MSR_FE1) & 1;
  1147 + msr_al = (value >> MSR_AL) & 1;
  1148 + msr_ip = (value >> MSR_IP) & 1;
  1149 + msr_ir = (value >> MSR_IR) & 1; /* IR / IS */
  1150 + msr_dr = (value >> MSR_DR) & 1; /* DR / DS */
  1151 + msr_pe = (value >> MSR_PE) & 1; /* PE / EP */
  1152 + msr_px = (value >> MSR_PX) & 1; /* PX / PMM */
  1153 + msr_ri = (value >> MSR_RI) & 1;
  1154 + msr_le = (value >> MSR_LE) & 1;
850 do_compute_hflags(env); 1155 do_compute_hflags(env);
851 1156
852 enter_pm = 0; 1157 enter_pm = 0;
853 switch (PPC_EXCP(env)) { 1158 switch (PPC_EXCP(env)) {
854 case PPC_FLAGS_EXCP_7x0: 1159 case PPC_FLAGS_EXCP_7x0:
855 - if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00E00000) != 0) 1160 + if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00E00000) != 0)
856 enter_pm = 1; 1161 enter_pm = 1;
857 break; 1162 break;
858 default: 1163 default:
@@ -866,75 +1171,16 @@ void do_store_msr (CPUPPCState *env, target_ulong value) @@ -866,75 +1171,16 @@ void do_store_msr (CPUPPCState *env, target_ulong value)
866 } 1171 }
867 } 1172 }
868 1173
869 -float64 do_load_fpscr (CPUPPCState *env) 1174 +void do_compute_hflags (CPUPPCState *env)
870 { 1175 {
871 - /* The 32 MSB of the target fpr are undefined.  
872 - * They'll be zero...  
873 - */  
874 - union {  
875 - float64 d;  
876 - struct {  
877 - uint32_t u[2];  
878 - } s;  
879 - } u;  
880 - int i;  
881 -  
882 -#ifdef WORDS_BIGENDIAN  
883 -#define WORD0 0  
884 -#define WORD1 1  
885 -#else  
886 -#define WORD0 1  
887 -#define WORD1 0 1176 + /* Compute current hflags */
  1177 + env->hflags = (msr_pr << MSR_PR) | (msr_le << MSR_LE) |
  1178 + (msr_fp << MSR_FP) | (msr_fe0 << MSR_FE0) | (msr_fe1 << MSR_FE1) |
  1179 + (msr_vr << MSR_VR) | (msr_ap << MSR_AP) | (msr_sa << MSR_SA) |
  1180 + (msr_se << MSR_SE) | (msr_be << MSR_BE);
  1181 +#if defined (TARGET_PPC64)
  1182 + env->hflags |= (msr_sf << MSR_SF) | (msr_hv << MSR_HV);
888 #endif 1183 #endif
889 - u.s.u[WORD0] = 0;  
890 - u.s.u[WORD1] = 0;  
891 - for (i = 0; i < 8; i++)  
892 - u.s.u[WORD1] |= env->fpscr[i] << (4 * i);  
893 - return u.d;  
894 -}  
895 -  
896 -void do_store_fpscr (CPUPPCState *env, float64 f, uint32_t mask)  
897 -{  
898 - /*  
899 - * We use only the 32 LSB of the incoming fpr  
900 - */  
901 - union {  
902 - double d;  
903 - struct {  
904 - uint32_t u[2];  
905 - } s;  
906 - } u;  
907 - int i, rnd_type;  
908 -  
909 - u.d = f;  
910 - if (mask & 0x80)  
911 - env->fpscr[0] = (env->fpscr[0] & 0x9) | ((u.s.u[WORD1] >> 28) & ~0x9);  
912 - for (i = 1; i < 7; i++) {  
913 - if (mask & (1 << (7 - i)))  
914 - env->fpscr[i] = (u.s.u[WORD1] >> (4 * (7 - i))) & 0xF;  
915 - }  
916 - /* TODO: update FEX & VX */  
917 - /* Set rounding mode */  
918 - switch (env->fpscr[0] & 0x3) {  
919 - case 0:  
920 - /* Best approximation (round to nearest) */  
921 - rnd_type = float_round_nearest_even;  
922 - break;  
923 - case 1:  
924 - /* Smaller magnitude (round toward zero) */  
925 - rnd_type = float_round_to_zero;  
926 - break;  
927 - case 2:  
928 - /* Round toward +infinite */  
929 - rnd_type = float_round_up;  
930 - break;  
931 - default:  
932 - case 3:  
933 - /* Round toward -infinite */  
934 - rnd_type = float_round_down;  
935 - break;  
936 - }  
937 - set_float_rounding_mode(rnd_type, &env->fp_status);  
938 } 1184 }
939 1185
940 /*****************************************************************************/ 1186 /*****************************************************************************/
@@ -944,17 +1190,18 @@ void do_interrupt (CPUState *env) @@ -944,17 +1190,18 @@ void do_interrupt (CPUState *env)
944 { 1190 {
945 env->exception_index = -1; 1191 env->exception_index = -1;
946 } 1192 }
947 -#else 1193 +#else /* defined (CONFIG_USER_ONLY) */
948 static void dump_syscall(CPUState *env) 1194 static void dump_syscall(CPUState *env)
949 { 1195 {
950 - fprintf(logfile, "syscall r0=0x%08x r3=0x%08x r4=0x%08x r5=0x%08x r6=0x%08x nip=0x%08x\n", 1196 + fprintf(logfile, "syscall r0=0x%08x r3=0x%08x r4=0x%08x "
  1197 + "r5=0x%08x r6=0x%08x nip=0x%08x\n",
951 env->gpr[0], env->gpr[3], env->gpr[4], 1198 env->gpr[0], env->gpr[3], env->gpr[4],
952 env->gpr[5], env->gpr[6], env->nip); 1199 env->gpr[5], env->gpr[6], env->nip);
953 } 1200 }
954 1201
955 void do_interrupt (CPUState *env) 1202 void do_interrupt (CPUState *env)
956 { 1203 {
957 - target_ulong msr, *srr_0, *srr_1, tmp; 1204 + target_ulong msr, *srr_0, *srr_1;
958 int excp; 1205 int excp;
959 1206
960 excp = env->exception_index; 1207 excp = env->exception_index;
@@ -967,7 +1214,7 @@ void do_interrupt (CPUState *env) @@ -967,7 +1214,7 @@ void do_interrupt (CPUState *env)
967 if (loglevel != 0) { 1214 if (loglevel != 0) {
968 fprintf(logfile, "Raise exception at 0x%08lx => 0x%08x (%02x)\n", 1215 fprintf(logfile, "Raise exception at 0x%08lx => 0x%08x (%02x)\n",
969 (unsigned long)env->nip, excp, env->error_code); 1216 (unsigned long)env->nip, excp, env->error_code);
970 - cpu_dump_state(env, logfile, fprintf, 0); 1217 + cpu_dump_state(env, logfile, fprintf, 0);
971 } 1218 }
972 } 1219 }
973 #endif 1220 #endif
@@ -978,7 +1225,7 @@ void do_interrupt (CPUState *env) @@ -978,7 +1225,7 @@ void do_interrupt (CPUState *env)
978 msr_pow = 0; 1225 msr_pow = 0;
979 /* Generate informations in save/restore registers */ 1226 /* Generate informations in save/restore registers */
980 switch (excp) { 1227 switch (excp) {
981 - /* Generic PowerPC exceptions */ 1228 + /* Generic PowerPC exceptions */
982 case EXCP_RESET: /* 0x0100 */ 1229 case EXCP_RESET: /* 0x0100 */
983 if (PPC_EXCP(env) != PPC_FLAGS_EXCP_40x) { 1230 if (PPC_EXCP(env) != PPC_FLAGS_EXCP_40x) {
984 if (msr_ip) 1231 if (msr_ip)
@@ -993,7 +1240,7 @@ void do_interrupt (CPUState *env) @@ -993,7 +1240,7 @@ void do_interrupt (CPUState *env)
993 if (msr_me == 0) { 1240 if (msr_me == 0) {
994 cpu_abort(env, "Machine check exception while not allowed\n"); 1241 cpu_abort(env, "Machine check exception while not allowed\n");
995 } 1242 }
996 - if (PPC_EXCP(env) == PPC_FLAGS_EXCP_40x) { 1243 + if (unlikely(PPC_EXCP(env) == PPC_FLAGS_EXCP_40x)) {
997 srr_0 = &env->spr[SPR_40x_SRR2]; 1244 srr_0 = &env->spr[SPR_40x_SRR2];
998 srr_1 = &env->spr[SPR_40x_SRR3]; 1245 srr_1 = &env->spr[SPR_40x_SRR3];
999 } 1246 }
@@ -1004,26 +1251,26 @@ void do_interrupt (CPUState *env) @@ -1004,26 +1251,26 @@ void do_interrupt (CPUState *env)
1004 /* data location address has been stored 1251 /* data location address has been stored
1005 * when the fault has been detected 1252 * when the fault has been detected
1006 */ 1253 */
1007 - msr &= ~0xFFFF0000; 1254 + msr &= ~0xFFFF0000;
1008 #if defined (DEBUG_EXCEPTIONS) 1255 #if defined (DEBUG_EXCEPTIONS)
1009 - if (loglevel) {  
1010 - fprintf(logfile, "DSI exception: DSISR=0x%08x, DAR=0x%08x\n",  
1011 - env->spr[SPR_DSISR], env->spr[SPR_DAR]);  
1012 - } else {  
1013 - printf("DSI exception: DSISR=0x%08x, DAR=0x%08x\n",  
1014 - env->spr[SPR_DSISR], env->spr[SPR_DAR]);  
1015 - } 1256 + if (loglevel) {
  1257 + fprintf(logfile, "DSI exception: DSISR=0x%08x, DAR=0x%08x\n",
  1258 + env->spr[SPR_DSISR], env->spr[SPR_DAR]);
  1259 + } else {
  1260 + printf("DSI exception: DSISR=0x%08x, DAR=0x%08x\n",
  1261 + env->spr[SPR_DSISR], env->spr[SPR_DAR]);
  1262 + }
1016 #endif 1263 #endif
1017 goto store_next; 1264 goto store_next;
1018 case EXCP_ISI: /* 0x0400 */ 1265 case EXCP_ISI: /* 0x0400 */
1019 /* Store exception cause */ 1266 /* Store exception cause */
1020 - msr &= ~0xFFFF0000; 1267 + msr &= ~0xFFFF0000;
1021 msr |= env->error_code; 1268 msr |= env->error_code;
1022 #if defined (DEBUG_EXCEPTIONS) 1269 #if defined (DEBUG_EXCEPTIONS)
1023 - if (loglevel != 0) {  
1024 - fprintf(logfile, "ISI exception: msr=0x%08x, nip=0x%08x\n",  
1025 - msr, env->nip);  
1026 - } 1270 + if (loglevel != 0) {
  1271 + fprintf(logfile, "ISI exception: msr=0x%08x, nip=0x%08x\n",
  1272 + msr, env->nip);
  1273 + }
1027 #endif 1274 #endif
1028 goto store_next; 1275 goto store_next;
1029 case EXCP_EXTERNAL: /* 0x0500 */ 1276 case EXCP_EXTERNAL: /* 0x0500 */
@@ -1039,7 +1286,7 @@ void do_interrupt (CPUState *env) @@ -1039,7 +1286,7 @@ void do_interrupt (CPUState *env)
1039 } 1286 }
1040 goto store_next; 1287 goto store_next;
1041 case EXCP_ALIGN: /* 0x0600 */ 1288 case EXCP_ALIGN: /* 0x0600 */
1042 - if (PPC_EXCP(env) != PPC_FLAGS_EXCP_601) { 1289 + if (likely(PPC_EXCP(env) != PPC_FLAGS_EXCP_601)) {
1043 /* Store exception cause */ 1290 /* Store exception cause */
1044 /* Get rS/rD and rA from faulting opcode */ 1291 /* Get rS/rD and rA from faulting opcode */
1045 env->spr[SPR_DSISR] |= 1292 env->spr[SPR_DSISR] |=
@@ -1063,7 +1310,7 @@ void do_interrupt (CPUState *env) @@ -1063,7 +1310,7 @@ void do_interrupt (CPUState *env)
1063 printf("Ignore floating point exception\n"); 1310 printf("Ignore floating point exception\n");
1064 #endif 1311 #endif
1065 return; 1312 return;
1066 - } 1313 + }
1067 msr |= 0x00100000; 1314 msr |= 0x00100000;
1068 /* Set FX */ 1315 /* Set FX */
1069 env->fpscr[7] |= 0x8; 1316 env->fpscr[7] |= 0x8;
@@ -1071,21 +1318,21 @@ void do_interrupt (CPUState *env) @@ -1071,21 +1318,21 @@ void do_interrupt (CPUState *env)
1071 if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) & 1318 if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) &
1072 ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3))) 1319 ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3)))
1073 env->fpscr[7] |= 0x4; 1320 env->fpscr[7] |= 0x4;
1074 - break; 1321 + break;
1075 case EXCP_INVAL: 1322 case EXCP_INVAL:
1076 - // printf("Invalid instruction at 0x%08x\n", env->nip); 1323 + // printf("Invalid instruction at 0x%08x\n", env->nip);
1077 msr |= 0x00080000; 1324 msr |= 0x00080000;
1078 - break; 1325 + break;
1079 case EXCP_PRIV: 1326 case EXCP_PRIV:
1080 msr |= 0x00040000; 1327 msr |= 0x00040000;
1081 - break; 1328 + break;
1082 case EXCP_TRAP: 1329 case EXCP_TRAP:
1083 msr |= 0x00020000; 1330 msr |= 0x00020000;
1084 break; 1331 break;
1085 default: 1332 default:
1086 /* Should never occur */ 1333 /* Should never occur */
1087 - break;  
1088 - } 1334 + break;
  1335 + }
1089 msr |= 0x00010000; 1336 msr |= 0x00010000;
1090 goto store_current; 1337 goto store_current;
1091 case EXCP_NO_FP: /* 0x0800 */ 1338 case EXCP_NO_FP: /* 0x0800 */
@@ -1125,7 +1372,7 @@ void do_interrupt (CPUState *env) @@ -1125,7 +1372,7 @@ void do_interrupt (CPUState *env)
1125 cpu_abort(env, "Floating point assist exception " 1372 cpu_abort(env, "Floating point assist exception "
1126 "is not implemented yet !\n"); 1373 "is not implemented yet !\n");
1127 goto store_next; 1374 goto store_next;
1128 - /* 64 bits PowerPC exceptions */ 1375 + /* 64 bits PowerPC exceptions */
1129 case EXCP_DSEG: /* 0x0380 */ 1376 case EXCP_DSEG: /* 0x0380 */
1130 /* XXX: TODO */ 1377 /* XXX: TODO */
1131 cpu_abort(env, "Data segment exception is not implemented yet !\n"); 1378 cpu_abort(env, "Data segment exception is not implemented yet !\n");
@@ -1141,14 +1388,16 @@ void do_interrupt (CPUState *env) @@ -1141,14 +1388,16 @@ void do_interrupt (CPUState *env)
1141 /* Requeue it */ 1388 /* Requeue it */
1142 env->interrupt_request |= CPU_INTERRUPT_TIMER; 1389 env->interrupt_request |= CPU_INTERRUPT_TIMER;
1143 #endif 1390 #endif
1144 - return; 1391 + return;
1145 } 1392 }
1146 - cpu_abort(env,  
1147 - "Hypervisor decrementer exception is not implemented yet !\n"); 1393 + /* XXX: TODO */
  1394 + cpu_abort(env, "Hypervisor decrementer exception is not implemented "
  1395 + "yet !\n");
1148 goto store_next; 1396 goto store_next;
1149 /* Implementation specific exceptions */ 1397 /* Implementation specific exceptions */
1150 case 0x0A00: 1398 case 0x0A00:
1151 - if (PPC_EXCP(env) != PPC_FLAGS_EXCP_602) { 1399 + if (likely(env->spr[SPR_PVR] == CPU_PPC_G2 ||
  1400 + env->spr[SPR_PVR] == CPU_PPC_G2LE)) {
1152 /* Critical interrupt on G2 */ 1401 /* Critical interrupt on G2 */
1153 /* XXX: TODO */ 1402 /* XXX: TODO */
1154 cpu_abort(env, "G2 critical interrupt is not implemented yet !\n"); 1403 cpu_abort(env, "G2 critical interrupt is not implemented yet !\n");
@@ -1186,9 +1435,10 @@ void do_interrupt (CPUState *env) @@ -1186,9 +1435,10 @@ void do_interrupt (CPUState *env)
1186 case PPC_FLAGS_EXCP_602: 1435 case PPC_FLAGS_EXCP_602:
1187 case PPC_FLAGS_EXCP_603: 1436 case PPC_FLAGS_EXCP_603:
1188 /* ITLBMISS on 602/603 */ 1437 /* ITLBMISS on 602/603 */
1189 - msr &= ~0xF00F0000;  
1190 - msr_tgpr = 1;  
1191 goto store_gprs; 1438 goto store_gprs;
  1439 + case PPC_FLAGS_EXCP_7x5:
  1440 + /* ITLBMISS on 745/755 */
  1441 + goto tlb_miss;
1192 default: 1442 default:
1193 cpu_abort(env, "Invalid exception 0x1000 !\n"); 1443 cpu_abort(env, "Invalid exception 0x1000 !\n");
1194 break; 1444 break;
@@ -1198,8 +1448,8 @@ void do_interrupt (CPUState *env) @@ -1198,8 +1448,8 @@ void do_interrupt (CPUState *env)
1198 switch (PPC_EXCP(env)) { 1448 switch (PPC_EXCP(env)) {
1199 case PPC_FLAGS_EXCP_40x: 1449 case PPC_FLAGS_EXCP_40x:
1200 /* FIT on 4xx */ 1450 /* FIT on 4xx */
1201 - cpu_abort(env, "40x FIT exception is not implemented yet !\n");  
1202 /* XXX: TODO */ 1451 /* XXX: TODO */
  1452 + cpu_abort(env, "40x FIT exception is not implemented yet !\n");
1203 goto store_next; 1453 goto store_next;
1204 default: 1454 default:
1205 cpu_abort(env, "Invalid exception 0x1010 !\n"); 1455 cpu_abort(env, "Invalid exception 0x1010 !\n");
@@ -1230,9 +1480,10 @@ void do_interrupt (CPUState *env) @@ -1230,9 +1480,10 @@ void do_interrupt (CPUState *env)
1230 case PPC_FLAGS_EXCP_602: 1480 case PPC_FLAGS_EXCP_602:
1231 case PPC_FLAGS_EXCP_603: 1481 case PPC_FLAGS_EXCP_603:
1232 /* DLTLBMISS on 602/603 */ 1482 /* DLTLBMISS on 602/603 */
1233 - msr &= ~0xF00F0000;  
1234 - msr_tgpr = 1;  
1235 goto store_gprs; 1483 goto store_gprs;
  1484 + case PPC_FLAGS_EXCP_7x5:
  1485 + /* DLTLBMISS on 745/755 */
  1486 + goto tlb_miss;
1236 default: 1487 default:
1237 cpu_abort(env, "Invalid exception 0x1100 !\n"); 1488 cpu_abort(env, "Invalid exception 0x1100 !\n");
1238 break; 1489 break;
@@ -1249,37 +1500,44 @@ void do_interrupt (CPUState *env) @@ -1249,37 +1500,44 @@ void do_interrupt (CPUState *env)
1249 case PPC_FLAGS_EXCP_602: 1500 case PPC_FLAGS_EXCP_602:
1250 case PPC_FLAGS_EXCP_603: 1501 case PPC_FLAGS_EXCP_603:
1251 /* DSTLBMISS on 602/603 */ 1502 /* DSTLBMISS on 602/603 */
1252 - msr &= ~0xF00F0000;  
1253 - msr_tgpr = 1;  
1254 store_gprs: 1503 store_gprs:
  1504 + /* Swap temporary saved registers with GPRs */
  1505 + swap_gpr_tgpr(env);
  1506 + msr_tgpr = 1;
1255 #if defined (DEBUG_SOFTWARE_TLB) 1507 #if defined (DEBUG_SOFTWARE_TLB)
1256 if (loglevel != 0) { 1508 if (loglevel != 0) {
1257 - fprintf(logfile, "6xx %sTLB miss: IM %08x DM %08x IC %08x "  
1258 - "DC %08x H1 %08x H2 %08x %08x\n",  
1259 - excp == 0x1000 ? "I" : excp == 0x1100 ? "DL" : "DS",  
1260 - env->spr[SPR_IMISS], env->spr[SPR_DMISS],  
1261 - env->spr[SPR_ICMP], env->spr[SPR_DCMP],  
1262 - env->spr[SPR_DHASH1], env->spr[SPR_DHASH2], 1509 + const unsigned char *es;
  1510 + target_ulong *miss, *cmp;
  1511 + int en;
  1512 + if (excp == 0x1000) {
  1513 + es = "I";
  1514 + en = 'I';
  1515 + miss = &env->spr[SPR_IMISS];
  1516 + cmp = &env->spr[SPR_ICMP];
  1517 + } else {
  1518 + if (excp == 0x1100)
  1519 + es = "DL";
  1520 + else
  1521 + es = "DS";
  1522 + en = 'D';
  1523 + miss = &env->spr[SPR_DMISS];
  1524 + cmp = &env->spr[SPR_DCMP];
  1525 + }
  1526 + fprintf(logfile, "6xx %sTLB miss: %cM %08x %cC %08x "
  1527 + "H1 %08x H2 %08x %08x\n", es, en, *miss, en, *cmp,
  1528 + env->spr[SPR_HASH1], env->spr[SPR_HASH2],
1263 env->error_code); 1529 env->error_code);
1264 } 1530 }
1265 #endif 1531 #endif
1266 - /* Swap temporary saved registers with GPRs */  
1267 - tmp = env->gpr[0];  
1268 - env->gpr[0] = env->tgpr[0];  
1269 - env->tgpr[0] = tmp;  
1270 - tmp = env->gpr[1];  
1271 - env->gpr[1] = env->tgpr[1];  
1272 - env->tgpr[1] = tmp;  
1273 - tmp = env->gpr[2];  
1274 - env->gpr[2] = env->tgpr[2];  
1275 - env->tgpr[2] = tmp;  
1276 - tmp = env->gpr[3];  
1277 - env->gpr[3] = env->tgpr[3];  
1278 - env->tgpr[3] = tmp; 1532 + goto tlb_miss;
  1533 + case PPC_FLAGS_EXCP_7x5:
  1534 + /* DSTLBMISS on 745/755 */
  1535 + tlb_miss:
  1536 + msr &= ~0xF83F0000;
1279 msr |= env->crf[0] << 28; 1537 msr |= env->crf[0] << 28;
1280 msr |= env->error_code; /* key, D/I, S/L bits */ 1538 msr |= env->error_code; /* key, D/I, S/L bits */
1281 /* Set way using a LRU mechanism */ 1539 /* Set way using a LRU mechanism */
1282 - msr |= (env->last_way ^ 1) << 17; 1540 + msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
1283 goto store_next; 1541 goto store_next;
1284 default: 1542 default:
1285 cpu_abort(env, "Invalid exception 0x1200 !\n"); 1543 cpu_abort(env, "Invalid exception 0x1200 !\n");
@@ -1324,6 +1582,7 @@ void do_interrupt (CPUState *env) @@ -1324,6 +1582,7 @@ void do_interrupt (CPUState *env)
1324 switch (PPC_EXCP(env)) { 1582 switch (PPC_EXCP(env)) {
1325 case PPC_FLAGS_EXCP_602: 1583 case PPC_FLAGS_EXCP_602:
1326 /* Watchdog on 602 */ 1584 /* Watchdog on 602 */
  1585 + /* XXX: TODO */
1327 cpu_abort(env, 1586 cpu_abort(env,
1328 "602 watchdog exception is not implemented yet !\n"); 1587 "602 watchdog exception is not implemented yet !\n");
1329 goto store_next; 1588 goto store_next;
target-ppc/mfrom_table.c 0 โ†’ 100644
  1 +static const uint8_t mfrom_ROM_table[602] =
  2 +{
  3 + 77, 77, 76, 76, 75, 75, 74, 74,
  4 + 73, 73, 72, 72, 71, 71, 70, 70,
  5 + 69, 69, 68, 68, 68, 67, 67, 66,
  6 + 66, 65, 65, 64, 64, 64, 63, 63,
  7 + 62, 62, 61, 61, 61, 60, 60, 59,
  8 + 59, 58, 58, 58, 57, 57, 56, 56,
  9 + 56, 55, 55, 54, 54, 54, 53, 53,
  10 + 53, 52, 52, 51, 51, 51, 50, 50,
  11 + 50, 49, 49, 49, 48, 48, 47, 47,
  12 + 47, 46, 46, 46, 45, 45, 45, 44,
  13 + 44, 44, 43, 43, 43, 42, 42, 42,
  14 + 42, 41, 41, 41, 40, 40, 40, 39,
  15 + 39, 39, 39, 38, 38, 38, 37, 37,
  16 + 37, 37, 36, 36, 36, 35, 35, 35,
  17 + 35, 34, 34, 34, 34, 33, 33, 33,
  18 + 33, 32, 32, 32, 32, 31, 31, 31,
  19 + 31, 30, 30, 30, 30, 29, 29, 29,
  20 + 29, 28, 28, 28, 28, 28, 27, 27,
  21 + 27, 27, 26, 26, 26, 26, 26, 25,
  22 + 25, 25, 25, 25, 24, 24, 24, 24,
  23 + 24, 23, 23, 23, 23, 23, 23, 22,
  24 + 22, 22, 22, 22, 21, 21, 21, 21,
  25 + 21, 21, 20, 20, 20, 20, 20, 20,
  26 + 19, 19, 19, 19, 19, 19, 19, 18,
  27 + 18, 18, 18, 18, 18, 17, 17, 17,
  28 + 17, 17, 17, 17, 16, 16, 16, 16,
  29 + 16, 16, 16, 16, 15, 15, 15, 15,
  30 + 15, 15, 15, 15, 14, 14, 14, 14,
  31 + 14, 14, 14, 14, 13, 13, 13, 13,
  32 + 13, 13, 13, 13, 13, 12, 12, 12,
  33 + 12, 12, 12, 12, 12, 12, 12, 11,
  34 + 11, 11, 11, 11, 11, 11, 11, 11,
  35 + 11, 11, 10, 10, 10, 10, 10, 10,
  36 + 10, 10, 10, 10, 10, 9, 9, 9,
  37 + 9, 9, 9, 9, 9, 9, 9, 9,
  38 + 9, 9, 8, 8, 8, 8, 8, 8,
  39 + 8, 8, 8, 8, 8, 8, 8, 8,
  40 + 7, 7, 7, 7, 7, 7, 7, 7,
  41 + 7, 7, 7, 7, 7, 7, 7, 7,
  42 + 7, 6, 6, 6, 6, 6, 6, 6,
  43 + 6, 6, 6, 6, 6, 6, 6, 6,
  44 + 6, 6, 6, 6, 5, 5, 5, 5,
  45 + 5, 5, 5, 5, 5, 5, 5, 5,
  46 + 5, 5, 5, 5, 5, 5, 5, 5,
  47 + 5, 5, 5, 4, 4, 4, 4, 4,
  48 + 4, 4, 4, 4, 4, 4, 4, 4,
  49 + 4, 4, 4, 4, 4, 4, 4, 4,
  50 + 4, 4, 4, 4, 4, 4, 4, 3,
  51 + 3, 3, 3, 3, 3, 3, 3, 3,
  52 + 3, 3, 3, 3, 3, 3, 3, 3,
  53 + 3, 3, 3, 3, 3, 3, 3, 3,
  54 + 3, 3, 3, 3, 3, 3, 3, 3,
  55 + 3, 3, 3, 3, 3, 2, 2, 2,
  56 + 2, 2, 2, 2, 2, 2, 2, 2,
  57 + 2, 2, 2, 2, 2, 2, 2, 2,
  58 + 2, 2, 2, 2, 2, 2, 2, 2,
  59 + 2, 2, 2, 2, 2, 2, 2, 2,
  60 + 2, 2, 2, 2, 2, 2, 2, 2,
  61 + 2, 2, 2, 2, 2, 2, 2, 2,
  62 + 2, 2, 2, 2, 2, 2, 1, 1,
  63 + 1, 1, 1, 1, 1, 1, 1, 1,
  64 + 1, 1, 1, 1, 1, 1, 1, 1,
  65 + 1, 1, 1, 1, 1, 1, 1, 1,
  66 + 1, 1, 1, 1, 1, 1, 1, 1,
  67 + 1, 1, 1, 1, 1, 1, 1, 1,
  68 + 1, 1, 1, 1, 1, 1, 1, 1,
  69 + 1, 1, 1, 1, 1, 1, 1, 1,
  70 + 1, 1, 1, 1, 1, 1, 1, 1,
  71 + 1, 1, 1, 1, 1, 1, 1, 1,
  72 + 1, 1, 1, 1, 1, 1, 1, 1,
  73 + 1, 1, 1, 1, 1, 1, 1, 1,
  74 + 1, 1, 1, 1, 1, 1, 1, 1,
  75 + 1, 1, 1, 1, 1, 1, 1, 1,
  76 + 1, 1, 1, 1, 1, 1, 1, 1,
  77 + 1, 1, 1, 1, 1, 1, 1, 1,
  78 + 1, 0,
  79 +};
target-ppc/mfrom_table_gen.c 0 โ†’ 100644
  1 +#define _GNU_SOURCE
  2 +#include <stdint.h>
  3 +#include <stdio.h>
  4 +#include <math.h>
  5 +
  6 +int main (void)
  7 +{
  8 + double d;
  9 + uint8_t n;
  10 + int i;
  11 +
  12 + printf("static const uint8_t mfrom_ROM_table[602] =\n{\n ");
  13 + for (i = 0; i < 602; i++) {
  14 + /* Extremly decomposed:
  15 + * -T0 / 256
  16 + * T0 = 256 * log10(10 + 1.0) + 0.5
  17 + */
  18 + d = -i;
  19 + d /= 256.0;
  20 + d = exp10(d);
  21 + d += 1.0;
  22 + d = log10(d);
  23 + d *= 256;
  24 + d += 0.5;
  25 + n = d;
  26 + printf("%3d, ", n);
  27 + if ((i & 7) == 7)
  28 + printf("\n ");
  29 + }
  30 + printf("\n};\n");
  31 +
  32 + return 0;
  33 +}
target-ppc/op.c
1 /* 1 /*
2 * PowerPC emulation micro-operations for qemu. 2 * PowerPC emulation micro-operations for qemu.
3 * 3 *
4 - * Copyright (c) 2003-2005 Jocelyn Mayer 4 + * Copyright (c) 2003-2007 Jocelyn Mayer
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,9 @@ @@ -22,7 +22,9 @@
22 22
23 #include "config.h" 23 #include "config.h"
24 #include "exec.h" 24 #include "exec.h"
  25 +#include "op_helper.h"
25 26
  27 +/* XXX: this is to be suppressed */
26 #define regs (env) 28 #define regs (env)
27 #define Ts0 (int32_t)T0 29 #define Ts0 (int32_t)T0
28 #define Ts1 (int32_t)T1 30 #define Ts1 (int32_t)T1
@@ -32,7 +34,8 @@ @@ -32,7 +34,8 @@
32 #define FT1 (env->ft1) 34 #define FT1 (env->ft1)
33 #define FT2 (env->ft2) 35 #define FT2 (env->ft2)
34 36
35 -#define PPC_OP(name) void glue(op_, name)(void) 37 +/* XXX: this is to be suppressed... */
  38 +#define PPC_OP(name) void OPPROTO glue(op_, name)(void)
36 39
37 #define REG 0 40 #define REG 0
38 #include "op_template.h" 41 #include "op_template.h"
@@ -134,31 +137,7 @@ @@ -134,31 +137,7 @@
134 /* set_Rc0 */ 137 /* set_Rc0 */
135 PPC_OP(set_Rc0) 138 PPC_OP(set_Rc0)
136 { 139 {
137 - uint32_t tmp;  
138 -  
139 - if (Ts0 < 0) {  
140 - tmp = 0x08;  
141 - } else if (Ts0 > 0) {  
142 - tmp = 0x04;  
143 - } else {  
144 - tmp = 0x02;  
145 - }  
146 - tmp |= xer_ov;  
147 - env->crf[0] = tmp;  
148 - RETURN();  
149 -}  
150 -  
151 -/* reset_Rc0 */  
152 -PPC_OP(reset_Rc0)  
153 -{  
154 - env->crf[0] = 0x02 | xer_ov;  
155 - RETURN();  
156 -}  
157 -  
158 -/* set_Rc0_1 */  
159 -PPC_OP(set_Rc0_1)  
160 -{  
161 - env->crf[0] = 0x04 | xer_ov; 140 + env->crf[0] = T0 | xer_ov;
162 RETURN(); 141 RETURN();
163 } 142 }
164 143
@@ -170,6 +149,12 @@ PPC_OP(set_Rc1) @@ -170,6 +149,12 @@ PPC_OP(set_Rc1)
170 } 149 }
171 150
172 /* Constants load */ 151 /* Constants load */
  152 +void OPPROTO op_reset_T0 (void)
  153 +{
  154 + T0 = 0;
  155 + RETURN();
  156 +}
  157 +
173 PPC_OP(set_T0) 158 PPC_OP(set_T0)
174 { 159 {
175 T0 = PARAM(1); 160 T0 = PARAM(1);
@@ -182,26 +167,30 @@ PPC_OP(set_T1) @@ -182,26 +167,30 @@ PPC_OP(set_T1)
182 RETURN(); 167 RETURN();
183 } 168 }
184 169
  170 +#if 0 // unused
185 PPC_OP(set_T2) 171 PPC_OP(set_T2)
186 { 172 {
187 T2 = PARAM(1); 173 T2 = PARAM(1);
188 RETURN(); 174 RETURN();
189 } 175 }
  176 +#endif
190 177
191 -/* Generate exceptions */  
192 -PPC_OP(raise_exception_err) 178 +void OPPROTO op_move_T1_T0 (void)
193 { 179 {
194 - do_raise_exception_err(PARAM(1), PARAM(2)); 180 + T1 = T0;
  181 + RETURN();
195 } 182 }
196 183
197 -PPC_OP(raise_exception) 184 +/* Generate exceptions */
  185 +PPC_OP(raise_exception_err)
198 { 186 {
199 - do_raise_exception(PARAM(1)); 187 + do_raise_exception_err(PARAM(1), PARAM(2));
200 } 188 }
201 189
202 PPC_OP(update_nip) 190 PPC_OP(update_nip)
203 { 191 {
204 env->nip = PARAM(1); 192 env->nip = PARAM(1);
  193 + RETURN();
205 } 194 }
206 195
207 PPC_OP(debug) 196 PPC_OP(debug)
@@ -209,46 +198,34 @@ PPC_OP(debug) @@ -209,46 +198,34 @@ PPC_OP(debug)
209 do_raise_exception(EXCP_DEBUG); 198 do_raise_exception(EXCP_DEBUG);
210 } 199 }
211 200
212 -/* Segment registers load and store with immediate index */  
213 -PPC_OP(load_srin)  
214 -{  
215 - T0 = regs->sr[T1 >> 28];  
216 - RETURN();  
217 -}  
218 201
219 -PPC_OP(store_srin) 202 +PPC_OP(exit_tb)
220 { 203 {
221 - do_store_sr(env, ((uint32_t)T1 >> 28), T0);  
222 - RETURN(); 204 + EXIT_TB();
223 } 205 }
224 206
225 -PPC_OP(load_sdr1) 207 +/* Load/store special registers */
  208 +PPC_OP(load_cr)
226 { 209 {
227 - T0 = regs->sdr1; 210 + do_load_cr();
228 RETURN(); 211 RETURN();
229 } 212 }
230 213
231 -PPC_OP(store_sdr1) 214 +PPC_OP(store_cr)
232 { 215 {
233 - do_store_sdr1(env, T0); 216 + do_store_cr(PARAM(1));
234 RETURN(); 217 RETURN();
235 } 218 }
236 219
237 -PPC_OP(exit_tb) 220 +void OPPROTO op_load_cro (void)
238 { 221 {
239 - EXIT_TB();  
240 -}  
241 -  
242 -/* Load/store special registers */  
243 -PPC_OP(load_cr)  
244 -{  
245 - T0 = do_load_cr(env); 222 + T0 = env->crf[PARAM1];
246 RETURN(); 223 RETURN();
247 } 224 }
248 225
249 -PPC_OP(store_cr) 226 +void OPPROTO op_store_cro (void)
250 { 227 {
251 - do_store_cr(env, T0, PARAM(1)); 228 + env->crf[PARAM1] = T0;
252 RETURN(); 229 RETURN();
253 } 230 }
254 231
@@ -272,15 +249,47 @@ PPC_OP(load_xer_bc) @@ -272,15 +249,47 @@ PPC_OP(load_xer_bc)
272 RETURN(); 249 RETURN();
273 } 250 }
274 251
  252 +void OPPROTO op_store_xer_bc (void)
  253 +{
  254 + xer_bc = T0;
  255 + RETURN();
  256 +}
  257 +
275 PPC_OP(load_xer) 258 PPC_OP(load_xer)
276 { 259 {
277 - T0 = do_load_xer(env); 260 + do_load_xer();
278 RETURN(); 261 RETURN();
279 } 262 }
280 263
281 PPC_OP(store_xer) 264 PPC_OP(store_xer)
282 { 265 {
283 - do_store_xer(env, T0); 266 + do_store_xer();
  267 + RETURN();
  268 +}
  269 +
  270 +#if !defined(CONFIG_USER_ONLY)
  271 +/* Segment registers load and store */
  272 +PPC_OP(load_sr)
  273 +{
  274 + T0 = regs->sr[T1];
  275 + RETURN();
  276 +}
  277 +
  278 +PPC_OP(store_sr)
  279 +{
  280 + do_store_sr(env, T1, T0);
  281 + RETURN();
  282 +}
  283 +
  284 +PPC_OP(load_sdr1)
  285 +{
  286 + T0 = regs->sdr1;
  287 + RETURN();
  288 +}
  289 +
  290 +PPC_OP(store_sdr1)
  291 +{
  292 + do_store_sdr1(env, T0);
284 RETURN(); 293 RETURN();
285 } 294 }
286 295
@@ -295,6 +304,7 @@ PPC_OP(store_msr) @@ -295,6 +304,7 @@ PPC_OP(store_msr)
295 do_store_msr(env, T0); 304 do_store_msr(env, T0);
296 RETURN(); 305 RETURN();
297 } 306 }
  307 +#endif
298 308
299 /* SPR */ 309 /* SPR */
300 PPC_OP(load_spr) 310 PPC_OP(load_spr)
@@ -345,6 +355,7 @@ PPC_OP(load_tbu) @@ -345,6 +355,7 @@ PPC_OP(load_tbu)
345 RETURN(); 355 RETURN();
346 } 356 }
347 357
  358 +#if !defined(CONFIG_USER_ONLY)
348 PPC_OP(store_tbl) 359 PPC_OP(store_tbl)
349 { 360 {
350 cpu_ppc_store_tbl(regs, T0); 361 cpu_ppc_store_tbl(regs, T0);
@@ -360,7 +371,8 @@ PPC_OP(store_tbu) @@ -360,7 +371,8 @@ PPC_OP(store_tbu)
360 PPC_OP(load_decr) 371 PPC_OP(load_decr)
361 { 372 {
362 T0 = cpu_ppc_load_decr(regs); 373 T0 = cpu_ppc_load_decr(regs);
363 - } 374 + RETURN();
  375 +}
364 376
365 PPC_OP(store_decr) 377 PPC_OP(store_decr)
366 { 378 {
@@ -371,15 +383,16 @@ PPC_OP(store_decr) @@ -371,15 +383,16 @@ PPC_OP(store_decr)
371 PPC_OP(load_ibat) 383 PPC_OP(load_ibat)
372 { 384 {
373 T0 = regs->IBAT[PARAM(1)][PARAM(2)]; 385 T0 = regs->IBAT[PARAM(1)][PARAM(2)];
  386 + RETURN();
374 } 387 }
375 388
376 -void op_store_ibatu (void) 389 +void OPPROTO op_store_ibatu (void)
377 { 390 {
378 do_store_ibatu(env, PARAM1, T0); 391 do_store_ibatu(env, PARAM1, T0);
379 RETURN(); 392 RETURN();
380 } 393 }
381 394
382 -void op_store_ibatl (void) 395 +void OPPROTO op_store_ibatl (void)
383 { 396 {
384 #if 1 397 #if 1
385 env->IBAT[1][PARAM1] = T0; 398 env->IBAT[1][PARAM1] = T0;
@@ -392,15 +405,16 @@ void op_store_ibatl (void) @@ -392,15 +405,16 @@ void op_store_ibatl (void)
392 PPC_OP(load_dbat) 405 PPC_OP(load_dbat)
393 { 406 {
394 T0 = regs->DBAT[PARAM(1)][PARAM(2)]; 407 T0 = regs->DBAT[PARAM(1)][PARAM(2)];
  408 + RETURN();
395 } 409 }
396 410
397 -void op_store_dbatu (void) 411 +void OPPROTO op_store_dbatu (void)
398 { 412 {
399 do_store_dbatu(env, PARAM1, T0); 413 do_store_dbatu(env, PARAM1, T0);
400 RETURN(); 414 RETURN();
401 } 415 }
402 416
403 -void op_store_dbatl (void) 417 +void OPPROTO op_store_dbatl (void)
404 { 418 {
405 #if 1 419 #if 1
406 env->DBAT[1][PARAM1] = T0; 420 env->DBAT[1][PARAM1] = T0;
@@ -409,17 +423,18 @@ void op_store_dbatl (void) @@ -409,17 +423,18 @@ void op_store_dbatl (void)
409 #endif 423 #endif
410 RETURN(); 424 RETURN();
411 } 425 }
  426 +#endif /* !defined(CONFIG_USER_ONLY) */
412 427
413 /* FPSCR */ 428 /* FPSCR */
414 PPC_OP(load_fpscr) 429 PPC_OP(load_fpscr)
415 { 430 {
416 - FT0 = do_load_fpscr(env); 431 + do_load_fpscr();
417 RETURN(); 432 RETURN();
418 } 433 }
419 434
420 PPC_OP(store_fpscr) 435 PPC_OP(store_fpscr)
421 { 436 {
422 - do_store_fpscr(env, FT0, PARAM1); 437 + do_store_fpscr(PARAM1);
423 RETURN(); 438 RETURN();
424 } 439 }
425 440
@@ -454,6 +469,7 @@ PPC_OP(setcrfbit) @@ -454,6 +469,7 @@ PPC_OP(setcrfbit)
454 PPC_OP(setlr) 469 PPC_OP(setlr)
455 { 470 {
456 regs->lr = PARAM1; 471 regs->lr = PARAM1;
  472 + RETURN();
457 } 473 }
458 474
459 PPC_OP(goto_tb0) 475 PPC_OP(goto_tb0)
@@ -469,6 +485,7 @@ PPC_OP(goto_tb1) @@ -469,6 +485,7 @@ PPC_OP(goto_tb1)
469 PPC_OP(b_T1) 485 PPC_OP(b_T1)
470 { 486 {
471 regs->nip = T1 & ~3; 487 regs->nip = T1 & ~3;
  488 + RETURN();
472 } 489 }
473 490
474 PPC_OP(jz_T0) 491 PPC_OP(jz_T0)
@@ -491,11 +508,13 @@ PPC_OP(btest_T1) @@ -491,11 +508,13 @@ PPC_OP(btest_T1)
491 PPC_OP(movl_T1_ctr) 508 PPC_OP(movl_T1_ctr)
492 { 509 {
493 T1 = regs->ctr; 510 T1 = regs->ctr;
  511 + RETURN();
494 } 512 }
495 513
496 PPC_OP(movl_T1_lr) 514 PPC_OP(movl_T1_lr)
497 { 515 {
498 T1 = regs->lr; 516 T1 = regs->lr;
  517 + RETURN();
499 } 518 }
500 519
501 /* tests with result in T0 */ 520 /* tests with result in T0 */
@@ -503,41 +522,49 @@ PPC_OP(movl_T1_lr) @@ -503,41 +522,49 @@ PPC_OP(movl_T1_lr)
503 PPC_OP(test_ctr) 522 PPC_OP(test_ctr)
504 { 523 {
505 T0 = regs->ctr; 524 T0 = regs->ctr;
  525 + RETURN();
506 } 526 }
507 527
508 PPC_OP(test_ctr_true) 528 PPC_OP(test_ctr_true)
509 { 529 {
510 T0 = (regs->ctr != 0 && (T0 & PARAM(1)) != 0); 530 T0 = (regs->ctr != 0 && (T0 & PARAM(1)) != 0);
  531 + RETURN();
511 } 532 }
512 533
513 PPC_OP(test_ctr_false) 534 PPC_OP(test_ctr_false)
514 { 535 {
515 T0 = (regs->ctr != 0 && (T0 & PARAM(1)) == 0); 536 T0 = (regs->ctr != 0 && (T0 & PARAM(1)) == 0);
  537 + RETURN();
516 } 538 }
517 539
518 PPC_OP(test_ctrz) 540 PPC_OP(test_ctrz)
519 { 541 {
520 T0 = (regs->ctr == 0); 542 T0 = (regs->ctr == 0);
  543 + RETURN();
521 } 544 }
522 545
523 PPC_OP(test_ctrz_true) 546 PPC_OP(test_ctrz_true)
524 { 547 {
525 T0 = (regs->ctr == 0 && (T0 & PARAM(1)) != 0); 548 T0 = (regs->ctr == 0 && (T0 & PARAM(1)) != 0);
  549 + RETURN();
526 } 550 }
527 551
528 PPC_OP(test_ctrz_false) 552 PPC_OP(test_ctrz_false)
529 { 553 {
530 T0 = (regs->ctr == 0 && (T0 & PARAM(1)) == 0); 554 T0 = (regs->ctr == 0 && (T0 & PARAM(1)) == 0);
  555 + RETURN();
531 } 556 }
532 557
533 PPC_OP(test_true) 558 PPC_OP(test_true)
534 { 559 {
535 T0 = (T0 & PARAM(1)); 560 T0 = (T0 & PARAM(1));
  561 + RETURN();
536 } 562 }
537 563
538 PPC_OP(test_false) 564 PPC_OP(test_false)
539 { 565 {
540 T0 = ((T0 & PARAM(1)) == 0); 566 T0 = ((T0 & PARAM(1)) == 0);
  567 + RETURN();
541 } 568 }
542 569
543 /* CTR maintenance */ 570 /* CTR maintenance */
@@ -555,8 +582,7 @@ PPC_OP(add) @@ -555,8 +582,7 @@ PPC_OP(add)
555 RETURN(); 582 RETURN();
556 } 583 }
557 584
558 -void do_addo (void);  
559 -void op_addo (void) 585 +void OPPROTO op_addo (void)
560 { 586 {
561 do_addo(); 587 do_addo();
562 RETURN(); 588 RETURN();
@@ -575,21 +601,19 @@ PPC_OP(addc) @@ -575,21 +601,19 @@ PPC_OP(addc)
575 RETURN(); 601 RETURN();
576 } 602 }
577 603
578 -void do_addco (void);  
579 -void op_addco (void) 604 +void OPPROTO op_addco (void)
580 { 605 {
581 do_addco(); 606 do_addco();
582 RETURN(); 607 RETURN();
583 } 608 }
584 609
585 /* add extended */ 610 /* add extended */
586 -void do_adde (void);  
587 -void op_adde (void) 611 +void OPPROTO op_adde (void)
588 { 612 {
589 do_adde(); 613 do_adde();
  614 + RETURN();
590 } 615 }
591 616
592 -void do_addeo (void);  
593 PPC_OP(addeo) 617 PPC_OP(addeo)
594 { 618 {
595 do_addeo(); 619 do_addeo();
@@ -626,8 +650,7 @@ PPC_OP(addme) @@ -626,8 +650,7 @@ PPC_OP(addme)
626 RETURN(); 650 RETURN();
627 } 651 }
628 652
629 -void do_addmeo (void);  
630 -void op_addmeo (void) 653 +void OPPROTO op_addmeo (void)
631 { 654 {
632 do_addmeo(); 655 do_addmeo();
633 RETURN(); 656 RETURN();
@@ -646,8 +669,7 @@ PPC_OP(addze) @@ -646,8 +669,7 @@ PPC_OP(addze)
646 RETURN(); 669 RETURN();
647 } 670 }
648 671
649 -void do_addzeo (void);  
650 -void op_addzeo (void) 672 +void OPPROTO op_addzeo (void)
651 { 673 {
652 do_addzeo(); 674 do_addzeo();
653 RETURN(); 675 RETURN();
@@ -664,8 +686,7 @@ PPC_OP(divw) @@ -664,8 +686,7 @@ PPC_OP(divw)
664 RETURN(); 686 RETURN();
665 } 687 }
666 688
667 -void do_divwo (void);  
668 -void op_divwo (void) 689 +void OPPROTO op_divwo (void)
669 { 690 {
670 do_divwo(); 691 do_divwo();
671 RETURN(); 692 RETURN();
@@ -682,8 +703,7 @@ PPC_OP(divwu) @@ -682,8 +703,7 @@ PPC_OP(divwu)
682 RETURN(); 703 RETURN();
683 } 704 }
684 705
685 -void do_divwuo (void);  
686 -void op_divwuo (void) 706 +void OPPROTO op_divwuo (void)
687 { 707 {
688 do_divwuo(); 708 do_divwuo();
689 RETURN(); 709 RETURN();
@@ -717,8 +737,7 @@ PPC_OP(mullw) @@ -717,8 +737,7 @@ PPC_OP(mullw)
717 RETURN(); 737 RETURN();
718 } 738 }
719 739
720 -void do_mullwo (void);  
721 -void op_mullwo (void) 740 +void OPPROTO op_mullwo (void)
722 { 741 {
723 do_mullwo(); 742 do_mullwo();
724 RETURN(); 743 RETURN();
@@ -733,8 +752,7 @@ PPC_OP(neg) @@ -733,8 +752,7 @@ PPC_OP(neg)
733 RETURN(); 752 RETURN();
734 } 753 }
735 754
736 -void do_nego (void);  
737 -void op_nego (void) 755 +void OPPROTO op_nego (void)
738 { 756 {
739 do_nego(); 757 do_nego();
740 RETURN(); 758 RETURN();
@@ -747,8 +765,7 @@ PPC_OP(subf) @@ -747,8 +765,7 @@ PPC_OP(subf)
747 RETURN(); 765 RETURN();
748 } 766 }
749 767
750 -void do_subfo (void);  
751 -void op_subfo (void) 768 +void OPPROTO op_subfo (void)
752 { 769 {
753 do_subfo(); 770 do_subfo();
754 RETURN(); 771 RETURN();
@@ -766,22 +783,19 @@ PPC_OP(subfc) @@ -766,22 +783,19 @@ PPC_OP(subfc)
766 RETURN(); 783 RETURN();
767 } 784 }
768 785
769 -void do_subfco (void);  
770 -void op_subfco (void) 786 +void OPPROTO op_subfco (void)
771 { 787 {
772 do_subfco(); 788 do_subfco();
773 RETURN(); 789 RETURN();
774 } 790 }
775 791
776 /* substract from extended */ 792 /* substract from extended */
777 -void do_subfe (void);  
778 -void op_subfe (void) 793 +void OPPROTO op_subfe (void)
779 { 794 {
780 do_subfe(); 795 do_subfe();
781 RETURN(); 796 RETURN();
782 } 797 }
783 798
784 -void do_subfeo (void);  
785 PPC_OP(subfeo) 799 PPC_OP(subfeo)
786 { 800 {
787 do_subfeo(); 801 do_subfeo();
@@ -810,8 +824,7 @@ PPC_OP(subfme) @@ -810,8 +824,7 @@ PPC_OP(subfme)
810 RETURN(); 824 RETURN();
811 } 825 }
812 826
813 -void do_subfmeo (void);  
814 -void op_subfmeo (void) 827 +void OPPROTO op_subfmeo (void)
815 { 828 {
816 do_subfmeo(); 829 do_subfmeo();
817 RETURN(); 830 RETURN();
@@ -830,8 +843,7 @@ PPC_OP(subfze) @@ -830,8 +843,7 @@ PPC_OP(subfze)
830 RETURN(); 843 RETURN();
831 } 844 }
832 845
833 -void do_subfzeo (void);  
834 -void op_subfzeo (void) 846 +void OPPROTO op_subfzeo (void)
835 { 847 {
836 do_subfzeo(); 848 do_subfzeo();
837 RETURN(); 849 RETURN();
@@ -906,18 +918,48 @@ PPC_OP(andc) @@ -906,18 +918,48 @@ PPC_OP(andc)
906 } 918 }
907 919
908 /* andi. */ 920 /* andi. */
909 -PPC_OP(andi_) 921 +void OPPROTO op_andi_T0 (void)
910 { 922 {
911 T0 &= PARAM(1); 923 T0 &= PARAM(1);
912 RETURN(); 924 RETURN();
913 } 925 }
914 926
  927 +void OPPROTO op_andi_T1 (void)
  928 +{
  929 + T1 &= PARAM1;
  930 + RETURN();
  931 +}
  932 +
915 /* count leading zero */ 933 /* count leading zero */
916 -PPC_OP(cntlzw) 934 +void OPPROTO op_cntlzw (void)
917 { 935 {
918 - T1 = T0;  
919 - for (T0 = 32; T1 > 0; T0--)  
920 - T1 = T1 >> 1; 936 + int cnt;
  937 +
  938 + cnt = 0;
  939 + if (!(T0 & 0xFFFF0000UL)) {
  940 + cnt += 16;
  941 + T0 <<= 16;
  942 + }
  943 + if (!(T0 & 0xFF000000UL)) {
  944 + cnt += 8;
  945 + T0 <<= 8;
  946 + }
  947 + if (!(T0 & 0xF0000000UL)) {
  948 + cnt += 4;
  949 + T0 <<= 4;
  950 + }
  951 + if (!(T0 & 0xC0000000UL)) {
  952 + cnt += 2;
  953 + T0 <<= 2;
  954 + }
  955 + if (!(T0 & 0x80000000UL)) {
  956 + cnt++;
  957 + T0 <<= 1;
  958 + }
  959 + if (!(T0 & 0x80000000UL)) {
  960 + cnt++;
  961 + }
  962 + T0 = cnt;
921 RETURN(); 963 RETURN();
922 } 964 }
923 965
@@ -992,48 +1034,15 @@ PPC_OP(xori) @@ -992,48 +1034,15 @@ PPC_OP(xori)
992 } 1034 }
993 1035
994 /*** Integer rotate ***/ 1036 /*** Integer rotate ***/
995 -/* rotate left word immediate then mask insert */  
996 -PPC_OP(rlwimi)  
997 -{  
998 - T0 = (rotl(T0, PARAM(1)) & PARAM(2)) | (T1 & PARAM(3));  
999 - RETURN();  
1000 -}  
1001 -  
1002 -/* rotate left immediate then and with mask insert */  
1003 -PPC_OP(rotlwi)  
1004 -{  
1005 - T0 = rotl(T0, PARAM(1));  
1006 - RETURN();  
1007 -}  
1008 -  
1009 -PPC_OP(slwi)  
1010 -{  
1011 - T0 = T0 << PARAM(1);  
1012 - RETURN();  
1013 -}  
1014 -  
1015 -PPC_OP(srwi) 1037 +void OPPROTO op_rotl32_T0_T1 (void)
1016 { 1038 {
1017 - T0 = T0 >> PARAM(1); 1039 + T0 = rotl32(T0, T1 & 0x1F);
1018 RETURN(); 1040 RETURN();
1019 } 1041 }
1020 1042
1021 -/* rotate left word then and with mask insert */  
1022 -PPC_OP(rlwinm) 1043 +void OPPROTO op_rotli32_T0 (void)
1023 { 1044 {
1024 - T0 = rotl(T0, PARAM(1)) & PARAM(2);  
1025 - RETURN();  
1026 -}  
1027 -  
1028 -PPC_OP(rotl)  
1029 -{  
1030 - T0 = rotl(T0, T1);  
1031 - RETURN();  
1032 -}  
1033 -  
1034 -PPC_OP(rlwnm)  
1035 -{  
1036 - T0 = rotl(T0, T1) & PARAM(1); 1045 + T0 = rotl32(T0, PARAM1);
1037 RETURN(); 1046 RETURN();
1038 } 1047 }
1039 1048
@@ -1050,7 +1059,7 @@ PPC_OP(slw) @@ -1050,7 +1059,7 @@ PPC_OP(slw)
1050 } 1059 }
1051 1060
1052 /* shift right algebraic word */ 1061 /* shift right algebraic word */
1053 -void op_sraw (void) 1062 +void OPPROTO op_sraw (void)
1054 { 1063 {
1055 do_sraw(); 1064 do_sraw();
1056 RETURN(); 1065 RETURN();
@@ -1080,25 +1089,55 @@ PPC_OP(srw) @@ -1080,25 +1089,55 @@ PPC_OP(srw)
1080 RETURN(); 1089 RETURN();
1081 } 1090 }
1082 1091
  1092 +void OPPROTO op_sl_T0_T1 (void)
  1093 +{
  1094 + T0 = T0 << T1;
  1095 + RETURN();
  1096 +}
  1097 +
  1098 +void OPPROTO op_sli_T0 (void)
  1099 +{
  1100 + T0 = T0 << PARAM1;
  1101 + RETURN();
  1102 +}
  1103 +
  1104 +void OPPROTO op_srl_T0_T1 (void)
  1105 +{
  1106 + T0 = T0 >> T1;
  1107 + RETURN();
  1108 +}
  1109 +
  1110 +void OPPROTO op_srli_T0 (void)
  1111 +{
  1112 + T0 = T0 >> PARAM1;
  1113 + RETURN();
  1114 +}
  1115 +
  1116 +void OPPROTO op_srli_T1 (void)
  1117 +{
  1118 + T1 = T1 >> PARAM1;
  1119 + RETURN();
  1120 +}
  1121 +
1083 /*** Floating-Point arithmetic ***/ 1122 /*** Floating-Point arithmetic ***/
1084 /* fadd - fadd. */ 1123 /* fadd - fadd. */
1085 PPC_OP(fadd) 1124 PPC_OP(fadd)
1086 { 1125 {
1087 - FT0 += FT1; 1126 + FT0 = float64_add(FT0, FT1, &env->fp_status);
1088 RETURN(); 1127 RETURN();
1089 } 1128 }
1090 1129
1091 /* fsub - fsub. */ 1130 /* fsub - fsub. */
1092 PPC_OP(fsub) 1131 PPC_OP(fsub)
1093 { 1132 {
1094 - FT0 -= FT1; 1133 + FT0 = float64_sub(FT0, FT1, &env->fp_status);
1095 RETURN(); 1134 RETURN();
1096 } 1135 }
1097 1136
1098 /* fmul - fmul. */ 1137 /* fmul - fmul. */
1099 PPC_OP(fmul) 1138 PPC_OP(fmul)
1100 { 1139 {
1101 - FT0 *= FT1; 1140 + FT0 = float64_mul(FT0, FT1, &env->fp_status);
1102 RETURN(); 1141 RETURN();
1103 } 1142 }
1104 1143
@@ -1141,14 +1180,16 @@ PPC_OP(fsel) @@ -1141,14 +1180,16 @@ PPC_OP(fsel)
1141 /* fmadd - fmadd. */ 1180 /* fmadd - fmadd. */
1142 PPC_OP(fmadd) 1181 PPC_OP(fmadd)
1143 { 1182 {
1144 - FT0 = (FT0 * FT1) + FT2; 1183 + FT0 = float64_mul(FT0, FT1, &env->fp_status);
  1184 + FT0 = float64_add(FT0, FT2, &env->fp_status);
1145 RETURN(); 1185 RETURN();
1146 } 1186 }
1147 1187
1148 /* fmsub - fmsub. */ 1188 /* fmsub - fmsub. */
1149 PPC_OP(fmsub) 1189 PPC_OP(fmsub)
1150 { 1190 {
1151 - FT0 = (FT0 * FT1) - FT2; 1191 + FT0 = float64_mul(FT0, FT1, &env->fp_status);
  1192 + FT0 = float64_sub(FT0, FT2, &env->fp_status);
1152 RETURN(); 1193 RETURN();
1153 } 1194 }
1154 1195
@@ -1170,7 +1211,7 @@ PPC_OP(fnmsub) @@ -1170,7 +1211,7 @@ PPC_OP(fnmsub)
1170 /* frsp - frsp. */ 1211 /* frsp - frsp. */
1171 PPC_OP(frsp) 1212 PPC_OP(frsp)
1172 { 1213 {
1173 - FT0 = (float)FT0; 1214 + FT0 = float64_to_float32(FT0, &env->fp_status);
1174 RETURN(); 1215 RETURN();
1175 } 1216 }
1176 1217
@@ -1188,7 +1229,6 @@ PPC_OP(fctiwz) @@ -1188,7 +1229,6 @@ PPC_OP(fctiwz)
1188 RETURN(); 1229 RETURN();
1189 } 1230 }
1190 1231
1191 -  
1192 /*** Floating-Point compare ***/ 1232 /*** Floating-Point compare ***/
1193 /* fcmpu */ 1233 /* fcmpu */
1194 PPC_OP(fcmpu) 1234 PPC_OP(fcmpu)
@@ -1229,12 +1269,14 @@ PPC_OP(fneg) @@ -1229,12 +1269,14 @@ PPC_OP(fneg)
1229 1269
1230 /* Load and store */ 1270 /* Load and store */
1231 #define MEMSUFFIX _raw 1271 #define MEMSUFFIX _raw
  1272 +#include "op_helper.h"
1232 #include "op_mem.h" 1273 #include "op_mem.h"
1233 #if !defined(CONFIG_USER_ONLY) 1274 #if !defined(CONFIG_USER_ONLY)
1234 #define MEMSUFFIX _user 1275 #define MEMSUFFIX _user
  1276 +#include "op_helper.h"
1235 #include "op_mem.h" 1277 #include "op_mem.h"
1236 -  
1237 #define MEMSUFFIX _kernel 1278 #define MEMSUFFIX _kernel
  1279 +#include "op_helper.h"
1238 #include "op_mem.h" 1280 #include "op_mem.h"
1239 #endif 1281 #endif
1240 1282
@@ -1247,24 +1289,18 @@ PPC_OP(check_reservation) @@ -1247,24 +1289,18 @@ PPC_OP(check_reservation)
1247 } 1289 }
1248 1290
1249 /* Return from interrupt */ 1291 /* Return from interrupt */
1250 -void do_rfi (void);  
1251 -void op_rfi (void) 1292 +#if !defined(CONFIG_USER_ONLY)
  1293 +void OPPROTO op_rfi (void)
1252 { 1294 {
1253 do_rfi(); 1295 do_rfi();
1254 RETURN(); 1296 RETURN();
1255 } 1297 }
  1298 +#endif
1256 1299
1257 /* Trap word */ 1300 /* Trap word */
1258 -void do_tw (uint32_t cmp, int flags);  
1259 -void op_tw (void)  
1260 -{  
1261 - do_tw(T1, PARAM(1));  
1262 - RETURN();  
1263 -}  
1264 -  
1265 -void op_twi (void) 1301 +void OPPROTO op_tw (void)
1266 { 1302 {
1267 - do_tw(PARAM(1), PARAM(2)); 1303 + do_tw(PARAM1);
1268 RETURN(); 1304 RETURN();
1269 } 1305 }
1270 1306
@@ -1275,6 +1311,7 @@ PPC_OP(icbi) @@ -1275,6 +1311,7 @@ PPC_OP(icbi)
1275 RETURN(); 1311 RETURN();
1276 } 1312 }
1277 1313
  1314 +#if !defined(CONFIG_USER_ONLY)
1278 /* tlbia */ 1315 /* tlbia */
1279 PPC_OP(tlbia) 1316 PPC_OP(tlbia)
1280 { 1317 {
@@ -1288,9 +1325,554 @@ PPC_OP(tlbie) @@ -1288,9 +1325,554 @@ PPC_OP(tlbie)
1288 do_tlbie(); 1325 do_tlbie();
1289 RETURN(); 1326 RETURN();
1290 } 1327 }
  1328 +#endif
1291 1329
1292 -void op_store_pir (void) 1330 +/* PowerPC 602/603/755 software TLB load instructions */
  1331 +#if !defined(CONFIG_USER_ONLY)
  1332 +void OPPROTO op_6xx_tlbld (void)
  1333 +{
  1334 + do_load_6xx_tlb(0);
  1335 + RETURN();
  1336 +}
  1337 +
  1338 +void OPPROTO op_6xx_tlbli (void)
  1339 +{
  1340 + do_load_6xx_tlb(1);
  1341 + RETURN();
  1342 +}
  1343 +#endif
  1344 +
  1345 +/* 601 specific */
  1346 +uint32_t cpu_ppc601_load_rtcl (CPUState *env);
  1347 +void OPPROTO op_load_601_rtcl (void)
  1348 +{
  1349 + T0 = cpu_ppc601_load_rtcl(env);
  1350 + RETURN();
  1351 +}
  1352 +
  1353 +uint32_t cpu_ppc601_load_rtcu (CPUState *env);
  1354 +void OPPROTO op_load_601_rtcu (void)
  1355 +{
  1356 + T0 = cpu_ppc601_load_rtcu(env);
  1357 + RETURN();
  1358 +}
  1359 +
  1360 +#if !defined(CONFIG_USER_ONLY)
  1361 +void cpu_ppc601_store_rtcl (CPUState *env, uint32_t value);
  1362 +void OPPROTO op_store_601_rtcl (void)
  1363 +{
  1364 + cpu_ppc601_store_rtcl(env, T0);
  1365 + RETURN();
  1366 +}
  1367 +
  1368 +void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value);
  1369 +void OPPROTO op_store_601_rtcu (void)
  1370 +{
  1371 + cpu_ppc601_store_rtcu(env, T0);
  1372 + RETURN();
  1373 +}
  1374 +
  1375 +void OPPROTO op_load_601_bat (void)
  1376 +{
  1377 + T0 = env->IBAT[PARAM1][PARAM2];
  1378 + RETURN();
  1379 +}
  1380 +#endif /* !defined(CONFIG_USER_ONLY) */
  1381 +
  1382 +/* 601 unified BATs store.
  1383 + * To avoid using specific MMU code for 601, we store BATs in
  1384 + * IBAT and DBAT simultaneously, then emulate unified BATs.
  1385 + */
  1386 +#if !defined(CONFIG_USER_ONLY)
  1387 +void OPPROTO op_store_601_batl (void)
  1388 +{
  1389 + int nr = PARAM1;
  1390 +
  1391 + env->IBAT[1][nr] = T0;
  1392 + env->DBAT[1][nr] = T0;
  1393 + RETURN();
  1394 +}
  1395 +
  1396 +void OPPROTO op_store_601_batu (void)
  1397 +{
  1398 + do_store_601_batu(PARAM1);
  1399 + RETURN();
  1400 +}
  1401 +#endif /* !defined(CONFIG_USER_ONLY) */
  1402 +
  1403 +/* PowerPC 601 specific instructions (POWER bridge) */
  1404 +/* XXX: those micro-ops need tests ! */
  1405 +void OPPROTO op_POWER_abs (void)
  1406 +{
  1407 + if (T0 == INT32_MIN)
  1408 + T0 = INT32_MAX;
  1409 + else if (T0 < 0)
  1410 + T0 = -T0;
  1411 + RETURN();
  1412 +}
  1413 +
  1414 +void OPPROTO op_POWER_abso (void)
  1415 +{
  1416 + do_POWER_abso();
  1417 + RETURN();
  1418 +}
  1419 +
  1420 +void OPPROTO op_POWER_clcs (void)
  1421 +{
  1422 + do_POWER_clcs();
  1423 + RETURN();
  1424 +}
  1425 +
  1426 +void OPPROTO op_POWER_div (void)
  1427 +{
  1428 + do_POWER_div();
  1429 + RETURN();
  1430 +}
  1431 +
  1432 +void OPPROTO op_POWER_divo (void)
  1433 +{
  1434 + do_POWER_divo();
  1435 + RETURN();
  1436 +}
  1437 +
  1438 +void OPPROTO op_POWER_divs (void)
  1439 +{
  1440 + do_POWER_divs();
  1441 + RETURN();
  1442 +}
  1443 +
  1444 +void OPPROTO op_POWER_divso (void)
  1445 +{
  1446 + do_POWER_divso();
  1447 + RETURN();
  1448 +}
  1449 +
  1450 +void OPPROTO op_POWER_doz (void)
  1451 +{
  1452 + if (Ts1 > Ts0)
  1453 + T0 = T1 - T0;
  1454 + else
  1455 + T0 = 0;
  1456 + RETURN();
  1457 +}
  1458 +
  1459 +void OPPROTO op_POWER_dozo (void)
  1460 +{
  1461 + do_POWER_dozo();
  1462 + RETURN();
  1463 +}
  1464 +
  1465 +void OPPROTO op_load_xer_cmp (void)
  1466 +{
  1467 + T2 = xer_cmp;
  1468 + RETURN();
  1469 +}
  1470 +
  1471 +void OPPROTO op_POWER_maskg (void)
  1472 +{
  1473 + do_POWER_maskg();
  1474 + RETURN();
  1475 +}
  1476 +
  1477 +void OPPROTO op_POWER_maskir (void)
  1478 +{
  1479 + T0 = (T0 & ~T2) | (T1 & T2);
  1480 + RETURN();
  1481 +}
  1482 +
  1483 +void OPPROTO op_POWER_mul (void)
  1484 +{
  1485 + uint64_t tmp;
  1486 +
  1487 + tmp = (uint64_t)T0 * (uint64_t)T1;
  1488 + env->spr[SPR_MQ] = tmp >> 32;
  1489 + T0 = tmp;
  1490 + RETURN();
  1491 +}
  1492 +
  1493 +void OPPROTO op_POWER_mulo (void)
  1494 +{
  1495 + do_POWER_mulo();
  1496 + RETURN();
  1497 +}
  1498 +
  1499 +void OPPROTO op_POWER_nabs (void)
  1500 +{
  1501 + if (T0 > 0)
  1502 + T0 = -T0;
  1503 + RETURN();
  1504 +}
  1505 +
  1506 +void OPPROTO op_POWER_nabso (void)
  1507 +{
  1508 + /* nabs never overflows */
  1509 + if (T0 > 0)
  1510 + T0 = -T0;
  1511 + xer_ov = 0;
  1512 + RETURN();
  1513 +}
  1514 +
  1515 +/* XXX: factorise POWER rotates... */
  1516 +void OPPROTO op_POWER_rlmi (void)
  1517 +{
  1518 + T0 = rotl32(T0, T2) & PARAM1;
  1519 + T0 |= T1 & PARAM2;
  1520 + RETURN();
  1521 +}
  1522 +
  1523 +void OPPROTO op_POWER_rrib (void)
  1524 +{
  1525 + T2 &= 0x1FUL;
  1526 + T0 = rotl32(T0 & INT32_MIN, T2);
  1527 + T0 |= T1 & ~rotl32(INT32_MIN, T2);
  1528 + RETURN();
  1529 +}
  1530 +
  1531 +void OPPROTO op_POWER_sle (void)
  1532 +{
  1533 + T1 &= 0x1FUL;
  1534 + env->spr[SPR_MQ] = rotl32(T0, T1);
  1535 + T0 = T0 << T1;
  1536 + RETURN();
  1537 +}
  1538 +
  1539 +void OPPROTO op_POWER_sleq (void)
  1540 +{
  1541 + uint32_t tmp = env->spr[SPR_MQ];
  1542 +
  1543 + T1 &= 0x1FUL;
  1544 + env->spr[SPR_MQ] = rotl32(T0, T1);
  1545 + T0 = T0 << T1;
  1546 + T0 |= tmp >> (32 - T1);
  1547 + RETURN();
  1548 +}
  1549 +
  1550 +void OPPROTO op_POWER_sllq (void)
  1551 +{
  1552 + uint32_t msk = -1;
  1553 +
  1554 + msk = msk << (T1 & 0x1FUL);
  1555 + if (T1 & 0x20UL)
  1556 + msk = ~msk;
  1557 + T1 &= 0x1FUL;
  1558 + T0 = (T0 << T1) & msk;
  1559 + T0 |= env->spr[SPR_MQ] & ~msk;
  1560 + RETURN();
  1561 +}
  1562 +
  1563 +void OPPROTO op_POWER_slq (void)
  1564 +{
  1565 + uint32_t msk = -1, tmp;
  1566 +
  1567 + msk = msk << (T1 & 0x1FUL);
  1568 + if (T1 & 0x20UL)
  1569 + msk = ~msk;
  1570 + T1 &= 0x1FUL;
  1571 + tmp = rotl32(T0, T1);
  1572 + T0 = tmp & msk;
  1573 + env->spr[SPR_MQ] = tmp;
  1574 + RETURN();
  1575 +}
  1576 +
  1577 +void OPPROTO op_POWER_sraq (void)
  1578 +{
  1579 + env->spr[SPR_MQ] = rotl32(T0, 32 - (T1 & 0x1FUL));
  1580 + if (T1 & 0x20UL)
  1581 + T0 = -1L;
  1582 + else
  1583 + T0 = Ts0 >> T1;
  1584 + RETURN();
  1585 +}
  1586 +
  1587 +void OPPROTO op_POWER_sre (void)
  1588 +{
  1589 + T1 &= 0x1FUL;
  1590 + env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
  1591 + T0 = Ts0 >> T1;
  1592 + RETURN();
  1593 +}
  1594 +
  1595 +void OPPROTO op_POWER_srea (void)
  1596 +{
  1597 + T1 &= 0x1FUL;
  1598 + env->spr[SPR_MQ] = T0 >> T1;
  1599 + T0 = Ts0 >> T1;
  1600 + RETURN();
  1601 +}
  1602 +
  1603 +void OPPROTO op_POWER_sreq (void)
  1604 +{
  1605 + uint32_t tmp;
  1606 + int32_t msk;
  1607 +
  1608 + T1 &= 0x1FUL;
  1609 + msk = INT32_MIN >> T1;
  1610 + tmp = env->spr[SPR_MQ];
  1611 + env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
  1612 + T0 = T0 >> T1;
  1613 + T0 |= tmp & msk;
  1614 + RETURN();
  1615 +}
  1616 +
  1617 +void OPPROTO op_POWER_srlq (void)
  1618 +{
  1619 + uint32_t tmp;
  1620 + int32_t msk;
  1621 +
  1622 + msk = INT32_MIN >> (T1 & 0x1FUL);
  1623 + if (T1 & 0x20UL)
  1624 + msk = ~msk;
  1625 + T1 &= 0x1FUL;
  1626 + tmp = env->spr[SPR_MQ];
  1627 + env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
  1628 + T0 = T0 >> T1;
  1629 + T0 &= msk;
  1630 + T0 |= tmp & ~msk;
  1631 + RETURN();
  1632 +}
  1633 +
  1634 +void OPPROTO op_POWER_srq (void)
  1635 +{
  1636 + T1 &= 0x1FUL;
  1637 + env->spr[SPR_MQ] = rotl32(T0, 32 - T1);
  1638 + T0 = T0 >> T1;
  1639 + RETURN();
  1640 +}
  1641 +
  1642 +/* POWER instructions not implemented in PowerPC 601 */
  1643 +#if !defined(CONFIG_USER_ONLY)
  1644 +void OPPROTO op_POWER_mfsri (void)
  1645 +{
  1646 + T1 = T0 >> 28;
  1647 + T0 = env->sr[T1];
  1648 + RETURN();
  1649 +}
  1650 +
  1651 +void OPPROTO op_POWER_rac (void)
  1652 +{
  1653 + do_POWER_rac();
  1654 + RETURN();
  1655 +}
  1656 +
  1657 +void OPPROTO op_POWER_rfsvc (void)
  1658 +{
  1659 + do_POWER_rfsvc();
  1660 + RETURN();
  1661 +}
  1662 +#endif
  1663 +
  1664 +/* PowerPC 602 specific instruction */
  1665 +#if !defined(CONFIG_USER_ONLY)
  1666 +void OPPROTO op_602_mfrom (void)
  1667 +{
  1668 + do_op_602_mfrom();
  1669 + RETURN();
  1670 +}
  1671 +#endif
  1672 +
  1673 +/* PowerPC 4xx specific micro-ops */
  1674 +void OPPROTO op_405_add_T0_T2 (void)
  1675 +{
  1676 + T0 = (int32_t)T0 + (int32_t)T2;
  1677 + RETURN();
  1678 +}
  1679 +
  1680 +void OPPROTO op_405_mulchw (void)
  1681 +{
  1682 + T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16));
  1683 + RETURN();
  1684 +}
  1685 +
  1686 +void OPPROTO op_405_mulchwu (void)
  1687 +{
  1688 + T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16));
  1689 + RETURN();
  1690 +}
  1691 +
  1692 +void OPPROTO op_405_mulhhw (void)
  1693 +{
  1694 + T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16));
  1695 + RETURN();
  1696 +}
  1697 +
  1698 +void OPPROTO op_405_mulhhwu (void)
  1699 +{
  1700 + T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16));
  1701 + RETURN();
  1702 +}
  1703 +
  1704 +void OPPROTO op_405_mullhw (void)
  1705 +{
  1706 + T0 = ((int16_t)T0) * ((int16_t)T1);
  1707 + RETURN();
  1708 +}
  1709 +
  1710 +void OPPROTO op_405_mullhwu (void)
  1711 +{
  1712 + T0 = ((uint16_t)T0) * ((uint16_t)T1);
  1713 + RETURN();
  1714 +}
  1715 +
  1716 +void OPPROTO op_405_check_ov (void)
  1717 +{
  1718 + do_405_check_ov();
  1719 + RETURN();
  1720 +}
  1721 +
  1722 +void OPPROTO op_405_check_sat (void)
  1723 +{
  1724 + do_405_check_sat();
  1725 + RETURN();
  1726 +}
  1727 +
  1728 +void OPPROTO op_405_check_ovu (void)
  1729 +{
  1730 + if (likely(T0 >= T2)) {
  1731 + xer_ov = 0;
  1732 + } else {
  1733 + xer_ov = 1;
  1734 + xer_so = 1;
  1735 + }
  1736 + RETURN();
  1737 +}
  1738 +
  1739 +void OPPROTO op_405_check_satu (void)
  1740 +{
  1741 + if (unlikely(T0 < T2)) {
  1742 + /* Saturate result */
  1743 + T0 = -1;
  1744 + }
  1745 + RETURN();
  1746 +}
  1747 +
  1748 +#if !defined(CONFIG_USER_ONLY)
  1749 +void OPPROTO op_4xx_load_dcr (void)
  1750 +{
  1751 + do_4xx_load_dcr(PARAM1);
  1752 + RETURN();
  1753 +}
  1754 +
  1755 +void OPPROTO op_4xx_store_dcr (void)
  1756 +{
  1757 + do_4xx_store_dcr(PARAM1);
  1758 + RETURN();
  1759 +}
  1760 +
  1761 +/* Return from critical interrupt :
  1762 + * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
  1763 + */
  1764 +void OPPROTO op_4xx_rfci (void)
  1765 +{
  1766 + do_4xx_rfci();
  1767 + RETURN();
  1768 +}
  1769 +
  1770 +void OPPROTO op_4xx_wrte (void)
  1771 +{
  1772 + msr_ee = T0 >> 16;
  1773 + RETURN();
  1774 +}
  1775 +
  1776 +void OPPROTO op_4xx_tlbre_lo (void)
  1777 +{
  1778 + do_4xx_tlbre_lo();
  1779 + RETURN();
  1780 +}
  1781 +
  1782 +void OPPROTO op_4xx_tlbre_hi (void)
  1783 +{
  1784 + do_4xx_tlbre_hi();
  1785 + RETURN();
  1786 +}
  1787 +
  1788 +void OPPROTO op_4xx_tlbsx (void)
  1789 +{
  1790 + do_4xx_tlbsx();
  1791 + RETURN();
  1792 +}
  1793 +
  1794 +void OPPROTO op_4xx_tlbsx_ (void)
  1795 +{
  1796 + do_4xx_tlbsx_();
  1797 + RETURN();
  1798 +}
  1799 +
  1800 +void OPPROTO op_4xx_tlbwe_lo (void)
  1801 +{
  1802 + do_4xx_tlbwe_lo();
  1803 + RETURN();
  1804 +}
  1805 +
  1806 +void OPPROTO op_4xx_tlbwe_hi (void)
  1807 +{
  1808 + do_4xx_tlbwe_hi();
  1809 + RETURN();
  1810 +}
  1811 +#endif
  1812 +
  1813 +/* SPR micro-ops */
  1814 +/* 440 specific */
  1815 +void OPPROTO op_440_dlmzb (void)
  1816 +{
  1817 + do_440_dlmzb();
  1818 + RETURN();
  1819 +}
  1820 +
  1821 +void OPPROTO op_440_dlmzb_update_Rc (void)
  1822 +{
  1823 + if (T0 == 8)
  1824 + T0 = 0x2;
  1825 + else if (T0 < 4)
  1826 + T0 = 0x4;
  1827 + else
  1828 + T0 = 0x8;
  1829 + RETURN();
  1830 +}
  1831 +
  1832 +#if !defined(CONFIG_USER_ONLY)
  1833 +void OPPROTO op_store_pir (void)
1293 { 1834 {
1294 env->spr[SPR_PIR] = T0 & 0x0000000FUL; 1835 env->spr[SPR_PIR] = T0 & 0x0000000FUL;
1295 RETURN(); 1836 RETURN();
1296 } 1837 }
  1838 +
  1839 +void OPPROTO op_load_403_pb (void)
  1840 +{
  1841 + do_load_403_pb(PARAM1);
  1842 + RETURN();
  1843 +}
  1844 +
  1845 +void OPPROTO op_store_403_pb (void)
  1846 +{
  1847 + do_store_403_pb(PARAM1);
  1848 + RETURN();
  1849 +}
  1850 +
  1851 +target_ulong load_40x_pit (CPUState *env);
  1852 +void OPPROTO op_load_40x_pit (void)
  1853 +{
  1854 + T0 = load_40x_pit(env);
  1855 + RETURN();
  1856 +}
  1857 +
  1858 +void store_40x_pit (CPUState *env, target_ulong val);
  1859 +void OPPROTO op_store_40x_pit (void)
  1860 +{
  1861 + store_40x_pit(env, T0);
  1862 + RETURN();
  1863 +}
  1864 +
  1865 +void store_booke_tcr (CPUState *env, target_ulong val);
  1866 +void OPPROTO op_store_booke_tcr (void)
  1867 +{
  1868 + store_booke_tcr(env, T0);
  1869 + RETURN();
  1870 +}
  1871 +
  1872 +void store_booke_tsr (CPUState *env, target_ulong val);
  1873 +void OPPROTO op_store_booke_tsr (void)
  1874 +{
  1875 + store_booke_tsr(env, T0);
  1876 + RETURN();
  1877 +}
  1878 +#endif /* !defined(CONFIG_USER_ONLY) */