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 759 void cpu_dump_state(CPUState *env, FILE *f,
760 760 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
761 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 766 void cpu_abort(CPUState *env, const char *fmt, ...);
764 767 extern CPUState *first_cpu;
... ...
gdbstub.c
... ... @@ -307,7 +307,7 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
307 307 registers[98] = tswapl(tmp);
308 308 registers[99] = tswapl(env->lr);
309 309 registers[100] = tswapl(env->ctr);
310   - registers[101] = tswapl(do_load_xer(env));
  310 + registers[101] = tswapl(ppc_load_xer(env));
311 311 registers[102] = 0;
312 312  
313 313 return 103 * 4;
... ... @@ -335,7 +335,7 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
335 335 env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
336 336 env->lr = tswapl(registers[99]);
337 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 340 #elif defined (TARGET_SPARC)
341 341 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
... ...
hw/ppc.c
1 1 /*
2 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 6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 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 41 {
42 42 /* TB time in tb periods */
43 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 47 uint32_t cpu_ppc_load_tbl (CPUState *env)
... ... @@ -52,14 +52,14 @@ uint32_t cpu_ppc_load_tbl (CPUState *env)
52 52 tb = cpu_ppc_get_tb(tb_env);
53 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 64 #endif
65 65  
... ... @@ -75,6 +75,7 @@ uint32_t cpu_ppc_load_tbu (CPUState *env)
75 75 #ifdef DEBUG_TB
76 76 printf("%s: tb=0x%016lx\n", __func__, tb);
77 77 #endif
  78 +
78 79 return tb >> 32;
79 80 }
80 81  
... ... @@ -117,6 +118,7 @@ uint32_t cpu_ppc_load_decr (CPUState *env)
117 118 #if defined(DEBUG_TB)
118 119 printf("%s: 0x%08x\n", __func__, decr);
119 120 #endif
  121 +
120 122 return decr;
121 123 }
122 124  
... ... @@ -146,7 +148,7 @@ static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
146 148 if (is_excp)
147 149 next += tb_env->decr_next - now;
148 150 if (next == now)
149   - next++;
  151 + next++;
150 152 tb_env->decr_next = next;
151 153 /* Adjust timer */
152 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 156 * raise an exception.
155 157 */
156 158 if ((value & 0x80000000) && !(decr & 0x80000000))
157   - cpu_ppc_decr_excp(env);
  159 + cpu_ppc_decr_excp(env);
158 160 }
159 161  
160 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 179 return NULL;
178 180 env->tb_env = tb_env;
179 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 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 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 240 #if 0
195 241 /*****************************************************************************/
196 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 310 tmp |= m48t59_read(nvram, addr + 1) << 16;
265 311 tmp |= m48t59_read(nvram, addr + 2) << 8;
266 312 tmp |= m48t59_read(nvram, addr + 3);
  313 +
267 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 363 odd = count & 1;
317 364 count &= ~1;
318 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 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 372 return crc;
... ...
linux-user/main.c
... ... @@ -670,18 +670,23 @@ void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
670 670 {
671 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 690 void cpu_loop(CPUPPCState *env)
686 691 {
687 692 target_siginfo_t info;
... ...
monitor.c
... ... @@ -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 345 static void do_quit(void)
335 346 {
336 347 exit(0);
... ... @@ -1303,6 +1314,10 @@ static term_cmd_t info_cmds[] = {
1303 1314 "", "show which guest mouse is receiving events" },
1304 1315 { "vnc", "", do_info_vnc,
1305 1316 "", "show the vnc server status"},
  1317 +#if defined(TARGET_PPC)
  1318 + { "cpustats", "", do_info_cpu_stats,
  1319 + "", "show CPU statistics", },
  1320 +#endif
1306 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 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 6 * This library is free software; you can redistribute it and/or
7 7 * modify it under the terms of the GNU Lesser General Public
... ... @@ -21,8 +21,22 @@
21 21 #define __CPU_PPC_H__
22 22  
23 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 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 41 #include "cpu-defs.h"
28 42  
... ... @@ -32,7 +46,11 @@
32 46  
33 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 55 /* XXX: this should be tunable: PowerPC 601 & 64 bits PowerPC
38 56 * have different cache line sizes
... ... @@ -42,6 +60,7 @@
42 60  
43 61 /* XXX: put this in a common place */
44 62 #define likely(x) __builtin_expect(!!(x), 1)
  63 +#define unlikely(x) __builtin_expect(!!(x), 0)
45 64  
46 65 /*****************************************************************************/
47 66 /* PVR definitions for most known PowerPC */
... ... @@ -54,72 +73,155 @@ enum {
54 73 CPU_PPC_401E2 = 0x00250000,
55 74 CPU_PPC_401F2 = 0x00260000,
56 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 79 /* PowerPC 403 cores */
59   - CPU_PPC_403GA = 0x00200000,
  80 + CPU_PPC_403GA = 0x00200011,
60 81 CPU_PPC_403GB = 0x00200100,
61 82 CPU_PPC_403GC = 0x00200200,
62 83 CPU_PPC_403GCX = 0x00201400,
  84 +#define CPU_PPC_403 CPU_PPC_403GCX
63 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 90 CPU_PPC_405D2 = 0x20010000,
68 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 101 #if 0
72   - CPU_PPC_STB02 = xxx,
  102 + CPU_PPC_STB01010 = xxx,
  103 +#endif
  104 +#if 0
  105 + CPU_PPC_STB0210 = xxx,
73 106 #endif
74 107 CPU_PPC_STB03 = 0x40310000,
75 108 #if 0
76   - CPU_PPC_STB04 = xxx,
  109 + CPU_PPC_STB043 = xxx,
77 110 #endif
78   - CPU_PPC_STB25 = 0x51510000,
  111 +#if 0
  112 + CPU_PPC_STB045 = xxx,
  113 +#endif
  114 + CPU_PPC_STB25 = 0x51510950,
79 115 #if 0
80 116 CPU_PPC_STB130 = xxx,
81 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 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 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 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 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 171 /* PowerPC 74x/75x cores (aka G3) */
104 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 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 185 CPU_PPC_750CXE24 = 0x00082214,
109 186 CPU_PPC_750CXE24b = 0x00083214,
110 187 CPU_PPC_750CXE31 = 0x00083211,
111 188 CPU_PPC_750CXE31b = 0x00083311,
112 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 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 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 225 CPU_PPC_7457A = 0x80030000,
124 226 /* 64 bits PowerPC */
125 227 CPU_PPC_620 = 0x00140000,
... ... @@ -130,7 +232,21 @@ enum {
130 232 CPU_PPC_POWER5 = 0x003A0000,
131 233 CPU_PPC_POWER5P = 0x003B0000,
132 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 250 CPU_PPC_RS64 = 0x00330000,
135 251 CPU_PPC_RS64II = 0x00340000,
136 252 CPU_PPC_RS64III = 0x00360000,
... ... @@ -147,12 +263,28 @@ enum {
147 263 #endif
148 264 };
149 265  
150   -/* System version register (used on MPC 8xx) */
  266 +/* System version register (used on MPC 8xxx) */
151 267 enum {
152 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 329 /* Time base support */
198 330 PPC_TB = 0x00002000,
199 331 /* Embedded PowerPC dedicated instructions */
200   - PPC_4xx_COMMON = 0x00004000,
  332 + PPC_EMB_COMMON = 0x00004000,
201 333 /* PowerPC 40x exception model */
202 334 PPC_40x_EXCP = 0x00008000,
203 335 /* PowerPC 40x specific instructions */
... ... @@ -225,12 +357,20 @@ enum {
225 357 PPC_64H = 0x02000000,
226 358 /* 64 bits PowerPC "bridge" features */
227 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 370 /* CPU run-time flags (MMU and exception model) */
231 371 enum {
232 372 /* MMU model */
233   -#define PPC_FLAGS_MMU_MASK (0x0000000F)
  373 + PPC_FLAGS_MMU_MASK = 0x0000000F,
234 374 /* Standard 32 bits PowerPC MMU */
235 375 PPC_FLAGS_MMU_32B = 0x00000000,
236 376 /* Standard 64 bits PowerPC MMU */
... ... @@ -243,8 +383,10 @@ enum {
243 383 PPC_FLAGS_MMU_SOFT_4xx = 0x00000004,
244 384 /* PowerPC 403 MMU */
245 385 PPC_FLAGS_MMU_403 = 0x00000005,
  386 + /* Freescale e500 MMU model */
  387 + PPC_FLAGS_MMU_e500 = 0x00000006,
246 388 /* Exception model */
247   -#define PPC_FLAGS_EXCP_MASK (0x000000F0)
  389 + PPC_FLAGS_EXCP_MASK = 0x000000F0,
248 390 /* Standard PowerPC exception model */
249 391 PPC_FLAGS_EXCP_STD = 0x00000000,
250 392 /* PowerPC 40x exception model */
... ... @@ -277,32 +419,42 @@ enum {
277 419 #define PPC_FLAGS_TODO (0x00000000)
278 420  
279 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 423 /* PowerPC 401 */
282 424 #define PPC_INSNS_401 (PPC_INSNS_TODO)
283 425 #define PPC_FLAGS_401 (PPC_FLAGS_TODO)
284 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 430 #define PPC_FLAGS_403 (PPC_FLAGS_MMU_403 | PPC_FLAGS_EXCP_40x)
288 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 435 PPC_405_MAC)
292 436 #define PPC_FLAGS_405 (PPC_FLAGS_MMU_SOFT_4xx | PPC_FLAGS_EXCP_40x)
293 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 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 449 /* Non-embedded PowerPC */
298 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 452 /* PowerPC 601 */
301 453 #define PPC_INSNS_601 (PPC_INSNS_COMMON | PPC_EXTERN | PPC_POWER_BR)
302 454 #define PPC_FLAGS_601 (PPC_FLAGS_MMU_601 | PPC_FLAGS_EXCP_601)
303 455 /* PowerPC 602 */
304 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 458 #define PPC_FLAGS_602 (PPC_FLAGS_MMU_SOFT_6xx | PPC_FLAGS_EXCP_602)
307 459 /* PowerPC 603 */
308 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 500 typedef struct ppc_spr_t ppc_spr_t;
349 501 typedef struct ppc_dcr_t ppc_dcr_t;
350 502 typedef struct ppc_avr_t ppc_avr_t;
  503 +typedef struct ppc_tlb_t ppc_tlb_t;
  504 +
351 505  
352 506 /* SPR access micro-ops generations callbacks */
353 507 struct ppc_spr_t {
354 508 void (*uea_read)(void *opaque, int spr_num);
355 509 void (*uea_write)(void *opaque, int spr_num);
  510 +#if !defined(CONFIG_USER_ONLY)
356 511 void (*oea_read)(void *opaque, int spr_num);
357 512 void (*oea_write)(void *opaque, int spr_num);
  513 +#endif
358 514 const unsigned char *name;
359 515 };
360 516  
... ... @@ -364,46 +520,42 @@ struct ppc_avr_t {
364 520 };
365 521  
366 522 /* Software TLB cache */
367   -typedef struct ppc_tlb_t ppc_tlb_t;
368 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 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 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 541 #define MSR_KEY 19 /* key bit on 603e */
391 542 #define MSR_POW 18 /* Power management */
392 543 #define MSR_WE 18 /* Wait state enable on embedded PowerPC */
393 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 546 #define MSR_CE 17 /* Critical interrupt enable on embedded PowerPC */
396 547 #define MSR_ILE 16 /* Interrupt little-endian mode */
397 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 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 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 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 559 #define MSR_AL 7 /* AL bit on POWER */
408 560 #define MSR_IP 6 /* Interrupt prefix */
409 561 #define MSR_IR 5 /* Instruction relocate */
... ... @@ -415,42 +567,45 @@ struct ppc_tlb_t {
415 567 #define MSR_PX 2 /* Protection exclusive on 403 */
416 568 #define MSR_PMM 2 /* Performance monitor mark on POWER */
417 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 571 #define msr_sf env->msr[MSR_SF]
420 572 #define msr_isf env->msr[MSR_ISF]
421 573 #define msr_hv env->msr[MSR_HV]
  574 +#define msr_ucle env->msr[MSR_UCLE]
422 575 #define msr_vr env->msr[MSR_VR]
  576 +#define msr_spe env->msr[MSR_SPE]
423 577 #define msr_ap env->msr[MSR_AP]
424 578 #define msr_sa env->msr[MSR_SA]
425 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 581 #define msr_we env->msr[MSR_WE]
428 582 #define msr_tgpr env->msr[MSR_TGPR]
429 583 #define msr_tlb env->msr[MSR_TLB]
430 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 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 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 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 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 602 #define msr_ds env->msr[MSR_DS]
448 603 #define msr_pe env->msr[MSR_PE]
449 604 #define msr_ep env->msr[MSR_EP]
450 605 #define msr_px env->msr[MSR_PX]
451 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 611 /* The whole PowerPC CPU context */
... ... @@ -465,7 +620,7 @@ struct CPUPPCState {
465 620 target_ulong t0, t1, t2;
466 621 #endif
467 622 /* general purpose registers */
468   - target_ulong gpr[32];
  623 + ppc_gpr_t gpr[32];
469 624 /* LR */
470 625 target_ulong lr;
471 626 /* CTR */
... ... @@ -482,10 +637,10 @@ struct CPUPPCState {
482 637 /* machine state register */
483 638 uint8_t msr[64];
484 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 642 /* Floating point execution context */
488   - /* temporary float registers */
  643 + /* temporary float registers */
489 644 float64 ft0;
490 645 float64 ft1;
491 646 float64 ft2;
... ... @@ -529,9 +684,12 @@ struct CPUPPCState {
529 684 ppc_dcr_t *dcr_env;
530 685  
531 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 693 /* Callbacks for specific checks on some implementations */
536 694 int (*tlb_check_more)(CPUPPCState *env, struct ppc_tlb_t *tlb, int *prot,
537 695 target_ulong vaddr, int rw, int acc_type,
... ... @@ -568,6 +726,16 @@ struct CPUPPCState {
568 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 740 CPUPPCState *cpu_ppc_init(void);
573 741 int cpu_ppc_exec(CPUPPCState *s);
... ... @@ -583,6 +751,7 @@ void cpu_loop_exit(void);
583 751  
584 752 void dump_stack (CPUPPCState *env);
585 753  
  754 +#if !defined(CONFIG_USER_ONLY)
586 755 target_ulong do_load_ibatu (CPUPPCState *env, int nr);
587 756 target_ulong do_load_ibatl (CPUPPCState *env, int nr);
588 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 760 target_ulong do_load_dbatl (CPUPPCState *env, int nr);
592 761 void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value);
593 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 763 target_ulong do_load_sdr1 (CPUPPCState *env);
598 764 void do_store_sdr1 (CPUPPCState *env, target_ulong value);
599 765 target_ulong do_load_asr (CPUPPCState *env);
600 766 void do_store_asr (CPUPPCState *env, target_ulong value);
601 767 target_ulong do_load_sr (CPUPPCState *env, int srnum);
602 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 772 target_ulong do_load_msr (CPUPPCState *env);
608 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 775 void do_compute_hflags (CPUPPCState *env);
613 776  
... ... @@ -645,261 +808,294 @@ void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value);
645 808 #define xer_bc env->xer[0]
646 809  
647 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 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 1099 /* Memory access type :
904 1100 * may be needed for precise access rights control and precise exceptions.
905 1101 */
... ... @@ -977,7 +1173,7 @@ enum {
977 1173 #define EXCP_PPC_MAX 0x4000
978 1174 /* Qemu exceptions: special cases we want to stop translation */
979 1175 #define EXCP_MTMSR 0x11000 /* mtmsr instruction: */
980   - /* may change privilege level */
  1176 + /* may change privilege level */
981 1177 #define EXCP_BRANCH 0x11001 /* branch instruction */
982 1178 #define EXCP_SYSCALL_USER 0x12000 /* System call in user mode only */
983 1179 #define EXCP_INTERRUPT_CRITICAL 0x13000 /* critical IRQ */
... ...
target-ppc/exec.h
1 1 /*
2 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 6 * This library is free software; you can redistribute it and/or
7 7 * modify it under the terms of the GNU Lesser General Public
... ... @@ -24,15 +24,34 @@
24 24  
25 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 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 52 #define PARAM(n) ((uint32_t)PARAM##n)
35 53 #define SPARAM(n) ((int32_t)PARAM##n)
  54 +
36 55 #define FT0 (env->ft0)
37 56 #define FT1 (env->ft1)
38 57 #define FT2 (env->ft2)
... ... @@ -43,14 +62,28 @@ register uint32_t T2 asm(AREG3);
43 62 # define RETURN() __asm__ __volatile__("" : : : "memory");
44 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 87 #if !defined(CONFIG_USER_ONLY)
55 88 #include "softmmu_exec.h"
56 89 #endif /* !defined(CONFIG_USER_ONLY) */
... ... @@ -58,23 +91,14 @@ static inline uint32_t rotl (uint32_t i, int n)
58 91 void do_raise_exception_err (uint32_t exception, int error_code);
59 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 103 static inline void env_to_regs(void)
80 104 {
... ... @@ -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 112 int is_user, int is_softmmu);
89 113  
90 114 #endif /* !defined (__PPC_H__) */
... ...
target-ppc/helper.c
1 1 /*
2 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 6 * This library is free software; you can redistribute it and/or
7 7 * modify it under the terms of the GNU Lesser General Public
... ... @@ -30,6 +30,7 @@
30 30  
31 31 //#define DEBUG_MMU
32 32 //#define DEBUG_BATS
  33 +//#define DEBUG_SOFTWARE_TLB
33 34 //#define DEBUG_EXCEPTIONS
34 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 56 }
56 57 env->exception_index = exception;
57 58 env->error_code = error_code;
  59 +
58 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 65 return addr;
63 66 }
64 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 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 353 int i;
72 354 int ret = -1;
73 355  
74 356 #if defined (DEBUG_BATS)
75 357 if (loglevel > 0) {
76 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 361 #endif
80 362 switch (type) {
... ... @@ -90,7 +372,7 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot,
90 372 #if defined (DEBUG_BATS)
91 373 if (loglevel > 0) {
92 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 377 #endif
96 378 base = virtual & 0xFFFC0000;
... ... @@ -113,18 +395,18 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot,
113 395 if ((msr_pr == 0 && (*BATu & 0x00000002)) ||
114 396 (msr_pr == 1 && (*BATu & 0x00000001))) {
115 397 /* Get physical address */
116   - *real = (*BATl & 0xF0000000) |
  398 + ctx->raddr = (*BATl & 0xF0000000) |
117 399 ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
118 400 (virtual & 0x0001F000);
119 401 if (*BATl & 0x00000001)
120   - *prot = PAGE_READ;
  402 + ctx->prot = PAGE_READ;
121 403 if (*BATl & 0x00000002)
122   - *prot = PAGE_WRITE | PAGE_READ;
  404 + ctx->prot = PAGE_WRITE | PAGE_READ;
123 405 #if defined (DEBUG_BATS)
124 406 if (loglevel > 0) {
125 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 411 #endif
130 412 ret = 0;
... ... @@ -153,189 +435,154 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot,
153 435 }
154 436  
155 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 446 for (i = 0; i < 8; i++) {
164 447 pte0 = ldl_phys(base + (i * 8));
165 448 pte1 = ldl_phys(base + (i * 8) + 4);
166 449 #if defined (DEBUG_MMU)
167 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 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 480 if (good != -1) {
231   - *RPN = keep & 0xFFFFF000;
  481 + done:
232 482 #if defined (DEBUG_MMU)
233 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 487 #endif
238 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 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 501 return (sdr1 & 0xFFFF0000) | (hash & mask);
265 502 }
266 503  
267 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 510 int ret = -1, ret2;
276 511  
277   - sr = env->sr[virtual >> 28];
  512 + sr = env->sr[eaddr >> 28];
278 513 #if defined (DEBUG_MMU)
279 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 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 523 if ((sr & 0x80000000) == 0) {
289 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 528 #endif
294 529 /* Check if instruction fetch is allowed, if needed */
295 530 if (type != ACCESS_CODE || (sr & 0x10000000) == 0) {
296 531 /* Page address translation */
  532 + pgidx = (eaddr >> TARGET_PAGE_BITS) & 0xFFFF;
297 533 vsid = sr & 0x00FFFFFF;
298   - pgidx = (virtual >> 12) & 0xFFFF;
299   - sdr = env->sdr1;
300 534 hash = ((vsid ^ pgidx) & 0x0007FFFF) << 6;
  535 + /* Primary table address */
  536 + sdr = env->sdr1;
301 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 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 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 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 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 575 } else {
329 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 579 #endif
333   - ret = -3;
  580 + ret = -3;
334 581 }
335 582 } else {
336 583 #if defined (DEBUG_MMU)
337 584 if (loglevel > 0)
338   - fprintf(logfile, "direct store...\n");
  585 + fprintf(logfile, "direct store...\n");
339 586 #endif
340 587 /* Direct-store segment : absolutely *BUGGY* for now */
341 588 switch (type) {
... ... @@ -356,7 +603,7 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot,
356 603 /* Should make the instruction do no-op.
357 604 * As it already do no-op, it's quite easy :-)
358 605 */
359   - *real = virtual;
  606 + ctx->raddr = eaddr;
360 607 return 0;
361 608 case ACCESS_EXT:
362 609 /* eciwx or ecowx */
... ... @@ -370,8 +617,8 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot,
370 617 "address translation\n");
371 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 622 ret = 2;
376 623 } else {
377 624 ret = -2;
... ... @@ -381,8 +628,44 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot,
381 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 670 int ret;
388 671 #if 0
... ... @@ -393,46 +676,46 @@ static int get_physical_address (CPUState *env, uint32_t *physical, int *prot,
393 676 if ((access_type == ACCESS_CODE && msr_ir == 0) ||
394 677 (access_type != ACCESS_CODE && msr_dr == 0)) {
395 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 680 } else {
400 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 685 if (ret < 0) {
403 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 690 #if 0
408 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 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 705 return -1;
423   - return phys_addr;
  706 +
  707 + return ctx.raddr & TARGET_PAGE_MASK;
424 708 }
425 709  
426 710 /* Perform address translation */
427 711 int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
428 712 int is_user, int is_softmmu)
429 713 {
430   - uint32_t physical;
431   - int prot;
  714 + mmu_ctx_t ctx;
432 715 int exception = 0, error_code = 0;
433 716 int access_type;
434 717 int ret = 0;
435   -
  718 +
436 719 if (rw == 2) {
437 720 /* code access */
438 721 rw = 0;
... ... @@ -444,35 +727,39 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
444 727 access_type = ACCESS_INT;
445 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 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 735 } else if (ret < 0) {
458   - do_fault:
459 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 739 #endif
463 740 if (access_type == ACCESS_CODE) {
464 741 exception = EXCP_ISI;
465 742 switch (ret) {
466 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 756 break;
470 757 case -2:
471 758 /* Access rights violation */
472 759 error_code = 0x08000000;
473 760 break;
474 761 case -3:
475   - /* No execute protection violation */
  762 + /* No execute protection violation */
476 763 error_code = 0x10000000;
477 764 break;
478 765 case -4:
... ... @@ -490,8 +777,28 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
490 777 exception = EXCP_DSI;
491 778 switch (ret) {
492 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 802 break;
496 803 case -2:
497 804 /* Access rights violation */
... ... @@ -514,7 +821,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
514 821 error_code = 0x04100000;
515 822 break;
516 823 default:
517   - printf("DSI: invalid exception (%d)\n", ret);
  824 + printf("DSI: invalid exception (%d)\n", ret);
518 825 exception = EXCP_PROGRAM;
519 826 error_code = EXCP_INVAL | EXCP_INVAL_INVAL;
520 827 break;
... ... @@ -528,10 +835,11 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
528 835 }
529 836 if (exception == EXCP_DSI && rw == 1)
530 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 840 env->spr[SPR_DSISR] = error_code;
534 841 }
  842 + out:
535 843 #if 0
536 844 printf("%s: set exception to %d %02x\n",
537 845 __func__, exception, error_code);
... ... @@ -540,9 +848,9 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
540 848 env->error_code = error_code;
541 849 ret = 1;
542 850 }
  851 +
543 852 return ret;
544 853 }
545   -#endif
546 854  
547 855 /*****************************************************************************/
548 856 /* BATs management */
... ... @@ -551,11 +859,14 @@ static inline void do_invalidate_BAT (CPUPPCState *env,
551 859 target_ulong BATu, target_ulong mask)
552 860 {
553 861 target_ulong base, end, page;
  862 +
554 863 base = BATu & ~0x0001FFFF;
555 864 end = base + mask + 0x00020000;
556 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 870 #endif
560 871 for (page = base; page != end; page += TARGET_PAGE_SIZE)
561 872 tlb_flush_page(env, page);
... ... @@ -608,8 +919,7 @@ void do_store_ibatu (CPUPPCState *env, int nr, target_ulong value)
608 919 (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
609 920 #if !defined(FLUSH_ALL_TLBS)
610 921 do_invalidate_BAT(env, env->IBAT[0][nr], mask);
611   -#endif
612   -#if defined(FLUSH_ALL_TLBS)
  922 +#else
613 923 tlb_flush(env, 1);
614 924 #endif
615 925 }
... ... @@ -663,24 +973,8 @@ void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
663 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 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 978 target_ulong do_load_sdr1 (CPUPPCState *env)
685 979 {
686 980 return env->sdr1;
... ... @@ -695,7 +989,7 @@ void do_store_sdr1 (CPUPPCState *env, target_ulong value)
695 989 #endif
696 990 if (env->sdr1 != value) {
697 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 1018 tlb_flush_page(env, page);
725 1019 }
726 1020 #else
727   - invalidate_all_tlbs(env);
  1021 + tlb_flush(env, 1);
728 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 1029 return (xer_so << XER_SO) |
757 1030 (xer_ov << XER_OV) |
... ... @@ -760,7 +1033,7 @@ uint32_t do_load_xer (CPUPPCState *env)
760 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 1038 xer_so = (value >> XER_SO) & 0x01;
766 1039 xer_ov = (value >> XER_OV) & 0x01;
... ... @@ -769,40 +1042,58 @@ void do_store_xer (CPUPPCState *env, uint32_t value)
769 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 1099 void do_store_msr (CPUPPCState *env, target_ulong value)
... ... @@ -812,10 +1103,7 @@ void do_store_msr (CPUPPCState *env, target_ulong value)
812 1103 value &= env->msr_mask;
813 1104 if (((value >> MSR_IR) & 1) != msr_ir ||
814 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 1107 tlb_flush(env, 1);
820 1108 env->interrupt_request |= CPU_INTERRUPT_EXITTB;
821 1109 }
... ... @@ -824,35 +1112,52 @@ void do_store_msr (CPUPPCState *env, target_ulong value)
824 1112 fprintf(logfile, "%s: T0 %08lx\n", __func__, value);
825 1113 }
826 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 1155 do_compute_hflags(env);
851 1156  
852 1157 enter_pm = 0;
853 1158 switch (PPC_EXCP(env)) {
854 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 1161 enter_pm = 1;
857 1162 break;
858 1163 default:
... ... @@ -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 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 1190 {
945 1191 env->exception_index = -1;
946 1192 }
947   -#else
  1193 +#else /* defined (CONFIG_USER_ONLY) */
948 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 1198 env->gpr[0], env->gpr[3], env->gpr[4],
952 1199 env->gpr[5], env->gpr[6], env->nip);
953 1200 }
954 1201  
955 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 1205 int excp;
959 1206  
960 1207 excp = env->exception_index;
... ... @@ -967,7 +1214,7 @@ void do_interrupt (CPUState *env)
967 1214 if (loglevel != 0) {
968 1215 fprintf(logfile, "Raise exception at 0x%08lx => 0x%08x (%02x)\n",
969 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 1220 #endif
... ... @@ -978,7 +1225,7 @@ void do_interrupt (CPUState *env)
978 1225 msr_pow = 0;
979 1226 /* Generate informations in save/restore registers */
980 1227 switch (excp) {
981   - /* Generic PowerPC exceptions */
  1228 + /* Generic PowerPC exceptions */
982 1229 case EXCP_RESET: /* 0x0100 */
983 1230 if (PPC_EXCP(env) != PPC_FLAGS_EXCP_40x) {
984 1231 if (msr_ip)
... ... @@ -993,7 +1240,7 @@ void do_interrupt (CPUState *env)
993 1240 if (msr_me == 0) {
994 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 1244 srr_0 = &env->spr[SPR_40x_SRR2];
998 1245 srr_1 = &env->spr[SPR_40x_SRR3];
999 1246 }
... ... @@ -1004,26 +1251,26 @@ void do_interrupt (CPUState *env)
1004 1251 /* data location address has been stored
1005 1252 * when the fault has been detected
1006 1253 */
1007   - msr &= ~0xFFFF0000;
  1254 + msr &= ~0xFFFF0000;
1008 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 1263 #endif
1017 1264 goto store_next;
1018 1265 case EXCP_ISI: /* 0x0400 */
1019 1266 /* Store exception cause */
1020   - msr &= ~0xFFFF0000;
  1267 + msr &= ~0xFFFF0000;
1021 1268 msr |= env->error_code;
1022 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 1274 #endif
1028 1275 goto store_next;
1029 1276 case EXCP_EXTERNAL: /* 0x0500 */
... ... @@ -1039,7 +1286,7 @@ void do_interrupt (CPUState *env)
1039 1286 }
1040 1287 goto store_next;
1041 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 1290 /* Store exception cause */
1044 1291 /* Get rS/rD and rA from faulting opcode */
1045 1292 env->spr[SPR_DSISR] |=
... ... @@ -1063,7 +1310,7 @@ void do_interrupt (CPUState *env)
1063 1310 printf("Ignore floating point exception\n");
1064 1311 #endif
1065 1312 return;
1066   - }
  1313 + }
1067 1314 msr |= 0x00100000;
1068 1315 /* Set FX */
1069 1316 env->fpscr[7] |= 0x8;
... ... @@ -1071,21 +1318,21 @@ void do_interrupt (CPUState *env)
1071 1318 if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) &
1072 1319 ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3)))
1073 1320 env->fpscr[7] |= 0x4;
1074   - break;
  1321 + break;
1075 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 1324 msr |= 0x00080000;
1078   - break;
  1325 + break;
1079 1326 case EXCP_PRIV:
1080 1327 msr |= 0x00040000;
1081   - break;
  1328 + break;
1082 1329 case EXCP_TRAP:
1083 1330 msr |= 0x00020000;
1084 1331 break;
1085 1332 default:
1086 1333 /* Should never occur */
1087   - break;
1088   - }
  1334 + break;
  1335 + }
1089 1336 msr |= 0x00010000;
1090 1337 goto store_current;
1091 1338 case EXCP_NO_FP: /* 0x0800 */
... ... @@ -1125,7 +1372,7 @@ void do_interrupt (CPUState *env)
1125 1372 cpu_abort(env, "Floating point assist exception "
1126 1373 "is not implemented yet !\n");
1127 1374 goto store_next;
1128   - /* 64 bits PowerPC exceptions */
  1375 + /* 64 bits PowerPC exceptions */
1129 1376 case EXCP_DSEG: /* 0x0380 */
1130 1377 /* XXX: TODO */
1131 1378 cpu_abort(env, "Data segment exception is not implemented yet !\n");
... ... @@ -1141,14 +1388,16 @@ void do_interrupt (CPUState *env)
1141 1388 /* Requeue it */
1142 1389 env->interrupt_request |= CPU_INTERRUPT_TIMER;
1143 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 1396 goto store_next;
1149 1397 /* Implementation specific exceptions */
1150 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 1401 /* Critical interrupt on G2 */
1153 1402 /* XXX: TODO */
1154 1403 cpu_abort(env, "G2 critical interrupt is not implemented yet !\n");
... ... @@ -1186,9 +1435,10 @@ void do_interrupt (CPUState *env)
1186 1435 case PPC_FLAGS_EXCP_602:
1187 1436 case PPC_FLAGS_EXCP_603:
1188 1437 /* ITLBMISS on 602/603 */
1189   - msr &= ~0xF00F0000;
1190   - msr_tgpr = 1;
1191 1438 goto store_gprs;
  1439 + case PPC_FLAGS_EXCP_7x5:
  1440 + /* ITLBMISS on 745/755 */
  1441 + goto tlb_miss;
1192 1442 default:
1193 1443 cpu_abort(env, "Invalid exception 0x1000 !\n");
1194 1444 break;
... ... @@ -1198,8 +1448,8 @@ void do_interrupt (CPUState *env)
1198 1448 switch (PPC_EXCP(env)) {
1199 1449 case PPC_FLAGS_EXCP_40x:
1200 1450 /* FIT on 4xx */
1201   - cpu_abort(env, "40x FIT exception is not implemented yet !\n");
1202 1451 /* XXX: TODO */
  1452 + cpu_abort(env, "40x FIT exception is not implemented yet !\n");
1203 1453 goto store_next;
1204 1454 default:
1205 1455 cpu_abort(env, "Invalid exception 0x1010 !\n");
... ... @@ -1230,9 +1480,10 @@ void do_interrupt (CPUState *env)
1230 1480 case PPC_FLAGS_EXCP_602:
1231 1481 case PPC_FLAGS_EXCP_603:
1232 1482 /* DLTLBMISS on 602/603 */
1233   - msr &= ~0xF00F0000;
1234   - msr_tgpr = 1;
1235 1483 goto store_gprs;
  1484 + case PPC_FLAGS_EXCP_7x5:
  1485 + /* DLTLBMISS on 745/755 */
  1486 + goto tlb_miss;
1236 1487 default:
1237 1488 cpu_abort(env, "Invalid exception 0x1100 !\n");
1238 1489 break;
... ... @@ -1249,37 +1500,44 @@ void do_interrupt (CPUState *env)
1249 1500 case PPC_FLAGS_EXCP_602:
1250 1501 case PPC_FLAGS_EXCP_603:
1251 1502 /* DSTLBMISS on 602/603 */
1252   - msr &= ~0xF00F0000;
1253   - msr_tgpr = 1;
1254 1503 store_gprs:
  1504 + /* Swap temporary saved registers with GPRs */
  1505 + swap_gpr_tgpr(env);
  1506 + msr_tgpr = 1;
1255 1507 #if defined (DEBUG_SOFTWARE_TLB)
1256 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 1529 env->error_code);
1264 1530 }
1265 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 1537 msr |= env->crf[0] << 28;
1280 1538 msr |= env->error_code; /* key, D/I, S/L bits */
1281 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 1541 goto store_next;
1284 1542 default:
1285 1543 cpu_abort(env, "Invalid exception 0x1200 !\n");
... ... @@ -1324,6 +1582,7 @@ void do_interrupt (CPUState *env)
1324 1582 switch (PPC_EXCP(env)) {
1325 1583 case PPC_FLAGS_EXCP_602:
1326 1584 /* Watchdog on 602 */
  1585 + /* XXX: TODO */
1327 1586 cpu_abort(env,
1328 1587 "602 watchdog exception is not implemented yet !\n");
1329 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 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 6 * This library is free software; you can redistribute it and/or
7 7 * modify it under the terms of the GNU Lesser General Public
... ... @@ -22,7 +22,9 @@
22 22  
23 23 #include "config.h"
24 24 #include "exec.h"
  25 +#include "op_helper.h"
25 26  
  27 +/* XXX: this is to be suppressed */
26 28 #define regs (env)
27 29 #define Ts0 (int32_t)T0
28 30 #define Ts1 (int32_t)T1
... ... @@ -32,7 +34,8 @@
32 34 #define FT1 (env->ft1)
33 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 40 #define REG 0
38 41 #include "op_template.h"
... ... @@ -134,31 +137,7 @@
134 137 /* set_Rc0 */
135 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 141 RETURN();
163 142 }
164 143  
... ... @@ -170,6 +149,12 @@ PPC_OP(set_Rc1)
170 149 }
171 150  
172 151 /* Constants load */
  152 +void OPPROTO op_reset_T0 (void)
  153 +{
  154 + T0 = 0;
  155 + RETURN();
  156 +}
  157 +
173 158 PPC_OP(set_T0)
174 159 {
175 160 T0 = PARAM(1);
... ... @@ -182,26 +167,30 @@ PPC_OP(set_T1)
182 167 RETURN();
183 168 }
184 169  
  170 +#if 0 // unused
185 171 PPC_OP(set_T2)
186 172 {
187 173 T2 = PARAM(1);
188 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 190 PPC_OP(update_nip)
203 191 {
204 192 env->nip = PARAM(1);
  193 + RETURN();
205 194 }
206 195  
207 196 PPC_OP(debug)
... ... @@ -209,46 +198,34 @@ PPC_OP(debug)
209 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 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 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 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 229 RETURN();
253 230 }
254 231  
... ... @@ -272,15 +249,47 @@ PPC_OP(load_xer_bc)
272 249 RETURN();
273 250 }
274 251  
  252 +void OPPROTO op_store_xer_bc (void)
  253 +{
  254 + xer_bc = T0;
  255 + RETURN();
  256 +}
  257 +
275 258 PPC_OP(load_xer)
276 259 {
277   - T0 = do_load_xer(env);
  260 + do_load_xer();
278 261 RETURN();
279 262 }
280 263  
281 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 293 RETURN();
285 294 }
286 295  
... ... @@ -295,6 +304,7 @@ PPC_OP(store_msr)
295 304 do_store_msr(env, T0);
296 305 RETURN();
297 306 }
  307 +#endif
298 308  
299 309 /* SPR */
300 310 PPC_OP(load_spr)
... ... @@ -345,6 +355,7 @@ PPC_OP(load_tbu)
345 355 RETURN();
346 356 }
347 357  
  358 +#if !defined(CONFIG_USER_ONLY)
348 359 PPC_OP(store_tbl)
349 360 {
350 361 cpu_ppc_store_tbl(regs, T0);
... ... @@ -360,7 +371,8 @@ PPC_OP(store_tbu)
360 371 PPC_OP(load_decr)
361 372 {
362 373 T0 = cpu_ppc_load_decr(regs);
363   - }
  374 + RETURN();
  375 +}
364 376  
365 377 PPC_OP(store_decr)
366 378 {
... ... @@ -371,15 +383,16 @@ PPC_OP(store_decr)
371 383 PPC_OP(load_ibat)
372 384 {
373 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 391 do_store_ibatu(env, PARAM1, T0);
379 392 RETURN();
380 393 }
381 394  
382   -void op_store_ibatl (void)
  395 +void OPPROTO op_store_ibatl (void)
383 396 {
384 397 #if 1
385 398 env->IBAT[1][PARAM1] = T0;
... ... @@ -392,15 +405,16 @@ void op_store_ibatl (void)
392 405 PPC_OP(load_dbat)
393 406 {
394 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 413 do_store_dbatu(env, PARAM1, T0);
400 414 RETURN();
401 415 }
402 416  
403   -void op_store_dbatl (void)
  417 +void OPPROTO op_store_dbatl (void)
404 418 {
405 419 #if 1
406 420 env->DBAT[1][PARAM1] = T0;
... ... @@ -409,17 +423,18 @@ void op_store_dbatl (void)
409 423 #endif
410 424 RETURN();
411 425 }
  426 +#endif /* !defined(CONFIG_USER_ONLY) */
412 427  
413 428 /* FPSCR */
414 429 PPC_OP(load_fpscr)
415 430 {
416   - FT0 = do_load_fpscr(env);
  431 + do_load_fpscr();
417 432 RETURN();
418 433 }
419 434  
420 435 PPC_OP(store_fpscr)
421 436 {
422   - do_store_fpscr(env, FT0, PARAM1);
  437 + do_store_fpscr(PARAM1);
423 438 RETURN();
424 439 }
425 440  
... ... @@ -454,6 +469,7 @@ PPC_OP(setcrfbit)
454 469 PPC_OP(setlr)
455 470 {
456 471 regs->lr = PARAM1;
  472 + RETURN();
457 473 }
458 474  
459 475 PPC_OP(goto_tb0)
... ... @@ -469,6 +485,7 @@ PPC_OP(goto_tb1)
469 485 PPC_OP(b_T1)
470 486 {
471 487 regs->nip = T1 & ~3;
  488 + RETURN();
472 489 }
473 490  
474 491 PPC_OP(jz_T0)
... ... @@ -491,11 +508,13 @@ PPC_OP(btest_T1)
491 508 PPC_OP(movl_T1_ctr)
492 509 {
493 510 T1 = regs->ctr;
  511 + RETURN();
494 512 }
495 513  
496 514 PPC_OP(movl_T1_lr)
497 515 {
498 516 T1 = regs->lr;
  517 + RETURN();
499 518 }
500 519  
501 520 /* tests with result in T0 */
... ... @@ -503,41 +522,49 @@ PPC_OP(movl_T1_lr)
503 522 PPC_OP(test_ctr)
504 523 {
505 524 T0 = regs->ctr;
  525 + RETURN();
506 526 }
507 527  
508 528 PPC_OP(test_ctr_true)
509 529 {
510 530 T0 = (regs->ctr != 0 && (T0 & PARAM(1)) != 0);
  531 + RETURN();
511 532 }
512 533  
513 534 PPC_OP(test_ctr_false)
514 535 {
515 536 T0 = (regs->ctr != 0 && (T0 & PARAM(1)) == 0);
  537 + RETURN();
516 538 }
517 539  
518 540 PPC_OP(test_ctrz)
519 541 {
520 542 T0 = (regs->ctr == 0);
  543 + RETURN();
521 544 }
522 545  
523 546 PPC_OP(test_ctrz_true)
524 547 {
525 548 T0 = (regs->ctr == 0 && (T0 & PARAM(1)) != 0);
  549 + RETURN();
526 550 }
527 551  
528 552 PPC_OP(test_ctrz_false)
529 553 {
530 554 T0 = (regs->ctr == 0 && (T0 & PARAM(1)) == 0);
  555 + RETURN();
531 556 }
532 557  
533 558 PPC_OP(test_true)
534 559 {
535 560 T0 = (T0 & PARAM(1));
  561 + RETURN();
536 562 }
537 563  
538 564 PPC_OP(test_false)
539 565 {
540 566 T0 = ((T0 & PARAM(1)) == 0);
  567 + RETURN();
541 568 }
542 569  
543 570 /* CTR maintenance */
... ... @@ -555,8 +582,7 @@ PPC_OP(add)
555 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 587 do_addo();
562 588 RETURN();
... ... @@ -575,21 +601,19 @@ PPC_OP(addc)
575 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 606 do_addco();
582 607 RETURN();
583 608 }
584 609  
585 610 /* add extended */
586   -void do_adde (void);
587   -void op_adde (void)
  611 +void OPPROTO op_adde (void)
588 612 {
589 613 do_adde();
  614 + RETURN();
590 615 }
591 616  
592   -void do_addeo (void);
593 617 PPC_OP(addeo)
594 618 {
595 619 do_addeo();
... ... @@ -626,8 +650,7 @@ PPC_OP(addme)
626 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 655 do_addmeo();
633 656 RETURN();
... ... @@ -646,8 +669,7 @@ PPC_OP(addze)
646 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 674 do_addzeo();
653 675 RETURN();
... ... @@ -664,8 +686,7 @@ PPC_OP(divw)
664 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 691 do_divwo();
671 692 RETURN();
... ... @@ -682,8 +703,7 @@ PPC_OP(divwu)
682 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 708 do_divwuo();
689 709 RETURN();
... ... @@ -717,8 +737,7 @@ PPC_OP(mullw)
717 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 742 do_mullwo();
724 743 RETURN();
... ... @@ -733,8 +752,7 @@ PPC_OP(neg)
733 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 757 do_nego();
740 758 RETURN();
... ... @@ -747,8 +765,7 @@ PPC_OP(subf)
747 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 770 do_subfo();
754 771 RETURN();
... ... @@ -766,22 +783,19 @@ PPC_OP(subfc)
766 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 788 do_subfco();
773 789 RETURN();
774 790 }
775 791  
776 792 /* substract from extended */
777   -void do_subfe (void);
778   -void op_subfe (void)
  793 +void OPPROTO op_subfe (void)
779 794 {
780 795 do_subfe();
781 796 RETURN();
782 797 }
783 798  
784   -void do_subfeo (void);
785 799 PPC_OP(subfeo)
786 800 {
787 801 do_subfeo();
... ... @@ -810,8 +824,7 @@ PPC_OP(subfme)
810 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 829 do_subfmeo();
817 830 RETURN();
... ... @@ -830,8 +843,7 @@ PPC_OP(subfze)
830 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 848 do_subfzeo();
837 849 RETURN();
... ... @@ -906,18 +918,48 @@ PPC_OP(andc)
906 918 }
907 919  
908 920 /* andi. */
909   -PPC_OP(andi_)
  921 +void OPPROTO op_andi_T0 (void)
910 922 {
911 923 T0 &= PARAM(1);
912 924 RETURN();
913 925 }
914 926  
  927 +void OPPROTO op_andi_T1 (void)
  928 +{
  929 + T1 &= PARAM1;
  930 + RETURN();
  931 +}
  932 +
915 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 963 RETURN();
922 964 }
923 965  
... ... @@ -992,48 +1034,15 @@ PPC_OP(xori)
992 1034 }
993 1035  
994 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 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 1046 RETURN();
1038 1047 }
1039 1048  
... ... @@ -1050,7 +1059,7 @@ PPC_OP(slw)
1050 1059 }
1051 1060  
1052 1061 /* shift right algebraic word */
1053   -void op_sraw (void)
  1062 +void OPPROTO op_sraw (void)
1054 1063 {
1055 1064 do_sraw();
1056 1065 RETURN();
... ... @@ -1080,25 +1089,55 @@ PPC_OP(srw)
1080 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 1122 /*** Floating-Point arithmetic ***/
1084 1123 /* fadd - fadd. */
1085 1124 PPC_OP(fadd)
1086 1125 {
1087   - FT0 += FT1;
  1126 + FT0 = float64_add(FT0, FT1, &env->fp_status);
1088 1127 RETURN();
1089 1128 }
1090 1129  
1091 1130 /* fsub - fsub. */
1092 1131 PPC_OP(fsub)
1093 1132 {
1094   - FT0 -= FT1;
  1133 + FT0 = float64_sub(FT0, FT1, &env->fp_status);
1095 1134 RETURN();
1096 1135 }
1097 1136  
1098 1137 /* fmul - fmul. */
1099 1138 PPC_OP(fmul)
1100 1139 {
1101   - FT0 *= FT1;
  1140 + FT0 = float64_mul(FT0, FT1, &env->fp_status);
1102 1141 RETURN();
1103 1142 }
1104 1143  
... ... @@ -1141,14 +1180,16 @@ PPC_OP(fsel)
1141 1180 /* fmadd - fmadd. */
1142 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 1185 RETURN();
1146 1186 }
1147 1187  
1148 1188 /* fmsub - fmsub. */
1149 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 1193 RETURN();
1153 1194 }
1154 1195  
... ... @@ -1170,7 +1211,7 @@ PPC_OP(fnmsub)
1170 1211 /* frsp - frsp. */
1171 1212 PPC_OP(frsp)
1172 1213 {
1173   - FT0 = (float)FT0;
  1214 + FT0 = float64_to_float32(FT0, &env->fp_status);
1174 1215 RETURN();
1175 1216 }
1176 1217  
... ... @@ -1188,7 +1229,6 @@ PPC_OP(fctiwz)
1188 1229 RETURN();
1189 1230 }
1190 1231  
1191   -
1192 1232 /*** Floating-Point compare ***/
1193 1233 /* fcmpu */
1194 1234 PPC_OP(fcmpu)
... ... @@ -1229,12 +1269,14 @@ PPC_OP(fneg)
1229 1269  
1230 1270 /* Load and store */
1231 1271 #define MEMSUFFIX _raw
  1272 +#include "op_helper.h"
1232 1273 #include "op_mem.h"
1233 1274 #if !defined(CONFIG_USER_ONLY)
1234 1275 #define MEMSUFFIX _user
  1276 +#include "op_helper.h"
1235 1277 #include "op_mem.h"
1236   -
1237 1278 #define MEMSUFFIX _kernel
  1279 +#include "op_helper.h"
1238 1280 #include "op_mem.h"
1239 1281 #endif
1240 1282  
... ... @@ -1247,24 +1289,18 @@ PPC_OP(check_reservation)
1247 1289 }
1248 1290  
1249 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 1295 do_rfi();
1254 1296 RETURN();
1255 1297 }
  1298 +#endif
1256 1299  
1257 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 1304 RETURN();
1269 1305 }
1270 1306  
... ... @@ -1275,6 +1311,7 @@ PPC_OP(icbi)
1275 1311 RETURN();
1276 1312 }
1277 1313  
  1314 +#if !defined(CONFIG_USER_ONLY)
1278 1315 /* tlbia */
1279 1316 PPC_OP(tlbia)
1280 1317 {
... ... @@ -1288,9 +1325,554 @@ PPC_OP(tlbie)
1288 1325 do_tlbie();
1289 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 1835 env->spr[SPR_PIR] = T0 & 0x0000000FUL;
1295 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) */
... ...