Commit 0411a9725829d626bb0b2f11a461463c96061682

Authored by j_mayer
1 parent 7ac256b8

Gprof prooved the PowerPC emulation spent too much time in MSR load and store

routines. Coming back to a raw MSR storage model then speed-up the emulation.
Improve fast MSR updates (wrtee wrteei and mtriee cases).
Share rfi family instructions helpers code to avoid bug in duplicated code.
Allow entering halt mode as the result of a rfi instruction.
Add a new helper_regs.h file to avoid duplication of special registers
 manipulation routines (currently XER and MSR).


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3436 c046a42c-6fe2-441c-8c8c-71466251a162
gdbstub.c
... ... @@ -300,7 +300,7 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
300 300 }
301 301 /* nip, msr, ccr, lnk, ctr, xer, mq */
302 302 registers[96] = tswapl(env->nip);
303   - registers[97] = tswapl(do_load_msr(env));
  303 + registers[97] = tswapl(env->msr);
304 304 tmp = 0;
305 305 for (i = 0; i < 8; i++)
306 306 tmp |= env->crf[i] << (32 - ((i + 1) * 4));
... ... @@ -329,7 +329,7 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
329 329 }
330 330 /* nip, msr, ccr, lnk, ctr, xer, mq */
331 331 env->nip = tswapl(registers[96]);
332   - do_store_msr(env, tswapl(registers[97]));
  332 + ppc_store_msr(env, tswapl(registers[97]));
333 333 registers[98] = tswapl(registers[98]);
334 334 for (i = 0; i < 8; i++)
335 335 env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
... ...
linux-user/main.c
... ... @@ -2168,14 +2168,13 @@ int main(int argc, char **argv)
2168 2168 }
2169 2169 cpu_ppc_register(env, def);
2170 2170 cpu_ppc_reset(env);
2171   - for (i = 0; i < 32; i++) {
2172   - if (i != 12 && i != 6 && i != 13)
2173   - env->msr[i] = (regs->msr >> i) & 1;
2174   - }
2175   -#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
2176   - msr_sf = 1;
  2171 + env->msr = regs->msr & ~((1 << 6) | (1 << 12) | (1 << 13));
  2172 +#if defined(TARGET_PPC64)
  2173 +#if defined(TARGET_ABI32)
  2174 + env->msr &= ~((target_ulong)1 << MSR_SF);
2177 2175 #else
2178   - msr_sf = 0;
  2176 + env->msr |= (target_ulong)1 << MSR_SF;
  2177 +#endif
2179 2178 #endif
2180 2179 env->nip = regs->nip;
2181 2180 for(i = 0; i < 32; i++) {
... ...
monitor.c
... ... @@ -1415,7 +1415,7 @@ static target_long monitor_get_msr (struct MonitorDef *md, int val)
1415 1415 CPUState *env = mon_get_cpu();
1416 1416 if (!env)
1417 1417 return 0;
1418   - return do_load_msr(env);
  1418 + return env->msr;
1419 1419 }
1420 1420  
1421 1421 static target_long monitor_get_xer (struct MonitorDef *md, int val)
... ...
target-ppc/cpu.h
... ... @@ -368,7 +368,7 @@ union ppc_tlb_t {
368 368 #define MSR_DE 9 /* Debug interrupts enable on embedded PowerPC x */
369 369 #define MSR_FE1 8 /* Floating point exception mode 1 hflags */
370 370 #define MSR_AL 7 /* AL bit on POWER */
371   -#define MSR_EP 3 /* Exception prefix on 601 */
  371 +#define MSR_EP 6 /* Exception prefix on 601 */
372 372 #define MSR_IR 5 /* Instruction relocate */
373 373 #define MSR_DR 4 /* Data relocate */
374 374 #define MSR_PE 3 /* Protection enable on 403 */
... ... @@ -376,41 +376,42 @@ union ppc_tlb_t {
376 376 #define MSR_PMM 2 /* Performance monitor mark on POWER x */
377 377 #define MSR_RI 1 /* Recoverable interrupt 1 */
378 378 #define MSR_LE 0 /* Little-endian mode 1 hflags */
379   -#define msr_sf env->msr[MSR_SF]
380   -#define msr_isf env->msr[MSR_ISF]
381   -#define msr_hv env->msr[MSR_HV]
382   -#define msr_cm env->msr[MSR_CM]
383   -#define msr_icm env->msr[MSR_ICM]
384   -#define msr_ucle env->msr[MSR_UCLE]
385   -#define msr_vr env->msr[MSR_VR]
386   -#define msr_spe env->msr[MSR_SPE]
387   -#define msr_ap env->msr[MSR_AP]
388   -#define msr_sa env->msr[MSR_SA]
389   -#define msr_key env->msr[MSR_KEY]
390   -#define msr_pow env->msr[MSR_POW]
391   -#define msr_tgpr env->msr[MSR_TGPR]
392   -#define msr_ce env->msr[MSR_CE]
393   -#define msr_ile env->msr[MSR_ILE]
394   -#define msr_ee env->msr[MSR_EE]
395   -#define msr_pr env->msr[MSR_PR]
396   -#define msr_fp env->msr[MSR_FP]
397   -#define msr_me env->msr[MSR_ME]
398   -#define msr_fe0 env->msr[MSR_FE0]
399   -#define msr_se env->msr[MSR_SE]
400   -#define msr_dwe env->msr[MSR_DWE]
401   -#define msr_uble env->msr[MSR_UBLE]
402   -#define msr_be env->msr[MSR_BE]
403   -#define msr_de env->msr[MSR_DE]
404   -#define msr_fe1 env->msr[MSR_FE1]
405   -#define msr_al env->msr[MSR_AL]
406   -#define msr_ir env->msr[MSR_IR]
407   -#define msr_dr env->msr[MSR_DR]
408   -#define msr_pe env->msr[MSR_PE]
409   -#define msr_ep env->msr[MSR_EP]
410   -#define msr_px env->msr[MSR_PX]
411   -#define msr_pmm env->msr[MSR_PMM]
412   -#define msr_ri env->msr[MSR_RI]
413   -#define msr_le env->msr[MSR_LE]
  379 +
  380 +#define msr_sf ((env->msr >> MSR_SF) & 1)
  381 +#define msr_isf ((env->msr >> MSR_ISF) & 1)
  382 +#define msr_hv ((env->msr >> MSR_HV) & 1)
  383 +#define msr_cm ((env->msr >> MSR_CM) & 1)
  384 +#define msr_icm ((env->msr >> MSR_ICM) & 1)
  385 +#define msr_ucle ((env->msr >> MSR_UCLE) & 1)
  386 +#define msr_vr ((env->msr >> MSR_VR) & 1)
  387 +#define msr_spe ((env->msr >> MSR_SE) & 1)
  388 +#define msr_ap ((env->msr >> MSR_AP) & 1)
  389 +#define msr_sa ((env->msr >> MSR_SA) & 1)
  390 +#define msr_key ((env->msr >> MSR_KEY) & 1)
  391 +#define msr_pow ((env->msr >> MSR_POW) & 1)
  392 +#define msr_tgpr ((env->msr >> MSR_TGPR) & 1)
  393 +#define msr_ce ((env->msr >> MSR_CE) & 1)
  394 +#define msr_ile ((env->msr >> MSR_ILE) & 1)
  395 +#define msr_ee ((env->msr >> MSR_EE) & 1)
  396 +#define msr_pr ((env->msr >> MSR_PR) & 1)
  397 +#define msr_fp ((env->msr >> MSR_FP) & 1)
  398 +#define msr_me ((env->msr >> MSR_ME) & 1)
  399 +#define msr_fe0 ((env->msr >> MSR_FE0) & 1)
  400 +#define msr_se ((env->msr >> MSR_SE) & 1)
  401 +#define msr_dwe ((env->msr >> MSR_DWE) & 1)
  402 +#define msr_uble ((env->msr >> MSR_UBLE) & 1)
  403 +#define msr_be ((env->msr >> MSR_BE) & 1)
  404 +#define msr_de ((env->msr >> MSR_DE) & 1)
  405 +#define msr_fe1 ((env->msr >> MSR_FE1) & 1)
  406 +#define msr_al ((env->msr >> MSR_AL) & 1)
  407 +#define msr_ep ((env->msr >> MSR_EP) & 1)
  408 +#define msr_ir ((env->msr >> MSR_IR) & 1)
  409 +#define msr_dr ((env->msr >> MSR_DR) & 1)
  410 +#define msr_pe ((env->msr >> MSR_PE) & 1)
  411 +#define msr_px ((env->msr >> MSR_PX) & 1)
  412 +#define msr_pmm ((env->msr >> MSR_PMM) & 1)
  413 +#define msr_ri ((env->msr >> MSR_RI) & 1)
  414 +#define msr_le ((env->msr >> MSR_LE) & 1)
414 415  
415 416 enum {
416 417 POWERPC_FLAG_NONE = 0x00000000,
... ... @@ -468,7 +469,7 @@ struct CPUPPCState {
468 469  
469 470 /* Those ones are used in supervisor mode only */
470 471 /* machine state register */
471   - uint8_t msr[64];
  472 + target_ulong msr;
472 473 /* temporary general purpose registers */
473 474 ppc_gpr_t tgpr[4]; /* Used to speed-up TLB assist handlers */
474 475  
... ... @@ -639,13 +640,8 @@ void do_store_sr (CPUPPCState *env, int srnum, target_ulong value);
639 640 #endif /* !defined(CONFIG_USER_ONLY) */
640 641 target_ulong ppc_load_xer (CPUPPCState *env);
641 642 void ppc_store_xer (CPUPPCState *env, target_ulong value);
642   -target_ulong do_load_msr (CPUPPCState *env);
643   -int do_store_msr (CPUPPCState *env, target_ulong value);
644   -#if defined(TARGET_PPC64)
645   -int ppc_store_msr_32 (CPUPPCState *env, uint32_t value);
646   -#endif
  643 +void ppc_store_msr (CPUPPCState *env, target_ulong value);
647 644  
648   -void do_compute_hflags (CPUPPCState *env);
649 645 void cpu_ppc_reset (void *opaque);
650 646 CPUPPCState *cpu_ppc_init (void);
651 647 void cpu_ppc_close(CPUPPCState *env);
... ...
target-ppc/exec.h
... ... @@ -118,7 +118,7 @@ static always_inline int cpu_halted (CPUState *env)
118 118 {
119 119 if (!env->halted)
120 120 return 0;
121   - if (env->msr[MSR_EE] && (env->interrupt_request & CPU_INTERRUPT_HARD)) {
  121 + if (msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD)) {
122 122 env->halted = 0;
123 123 return 0;
124 124 }
... ...
target-ppc/helper.c
... ... @@ -27,10 +27,12 @@
27 27  
28 28 #include "cpu.h"
29 29 #include "exec-all.h"
  30 +#include "helper_regs.h"
30 31  
31 32 //#define DEBUG_MMU
32 33 //#define DEBUG_BATS
33 34 //#define DEBUG_SOFTWARE_TLB
  35 +//#define DUMP_PAGE_TABLES
34 36 //#define DEBUG_EXCEPTIONS
35 37 //#define FLUSH_ALL_TLBS
36 38  
... ... @@ -447,7 +449,7 @@ static int get_bat (CPUState *env, mmu_ctx_t *ctx,
447 449 {
448 450 target_ulong *BATlt, *BATut, *BATu, *BATl;
449 451 target_ulong base, BEPIl, BEPIu, bl;
450   - int i, pp;
  452 + int i, pp, pr;
451 453 int ret = -1;
452 454  
453 455 #if defined (DEBUG_BATS)
... ... @@ -456,6 +458,7 @@ static int get_bat (CPUState *env, mmu_ctx_t *ctx,
456 458 type == ACCESS_CODE ? 'I' : 'D', virtual);
457 459 }
458 460 #endif
  461 + pr = msr_pr;
459 462 switch (type) {
460 463 case ACCESS_CODE:
461 464 BATlt = env->IBAT[1];
... ... @@ -490,8 +493,8 @@ static int get_bat (CPUState *env, mmu_ctx_t *ctx,
490 493 if ((virtual & 0xF0000000) == BEPIu &&
491 494 ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
492 495 /* BAT matches */
493   - if ((msr_pr == 0 && (*BATu & 0x00000002)) ||
494   - (msr_pr == 1 && (*BATu & 0x00000001))) {
  496 + if (((pr == 0) && (*BATu & 0x00000002)) ||
  497 + ((pr != 0) && (*BATu & 0x00000001))) {
495 498 /* Get physical address */
496 499 ctx->raddr = (*BATl & 0xF0000000) |
497 500 ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
... ... @@ -851,9 +854,10 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx,
851 854 #if defined(TARGET_PPC64)
852 855 int attr;
853 856 #endif
854   - int ds, vsid_sh, sdr_sh;
  857 + int ds, vsid_sh, sdr_sh, pr;
855 858 int ret, ret2;
856 859  
  860 + pr = msr_pr;
857 861 #if defined(TARGET_PPC64)
858 862 if (env->mmu_model == POWERPC_MMU_64B) {
859 863 #if defined (DEBUG_MMU)
... ... @@ -864,8 +868,8 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx,
864 868 ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr);
865 869 if (ret < 0)
866 870 return ret;
867   - ctx->key = ((attr & 0x40) && msr_pr == 1) ||
868   - ((attr & 0x80) && msr_pr == 0) ? 1 : 0;
  871 + ctx->key = ((attr & 0x40) && (pr != 0)) ||
  872 + ((attr & 0x80) && (pr == 0)) ? 1 : 0;
869 873 ds = 0;
870 874 ctx->nx = attr & 0x20 ? 1 : 0;
871 875 vsid_mask = 0x00003FFFFFFFFF80ULL;
... ... @@ -877,8 +881,8 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx,
877 881 {
878 882 sr = env->sr[eaddr >> 28];
879 883 page_mask = 0x0FFFFFFF;
880   - ctx->key = (((sr & 0x20000000) && msr_pr == 1) ||
881   - ((sr & 0x40000000) && msr_pr == 0)) ? 1 : 0;
  884 + ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
  885 + ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
882 886 ds = sr & 0x80000000 ? 1 : 0;
883 887 ctx->nx = sr & 0x10000000 ? 1 : 0;
884 888 vsid = sr & 0x00FFFFFF;
... ... @@ -892,7 +896,8 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx,
892 896 " nip=0x" ADDRX " lr=0x" ADDRX
893 897 " ir=%d dr=%d pr=%d %d t=%d\n",
894 898 eaddr, (int)(eaddr >> 28), sr, env->nip,
895   - env->lr, msr_ir, msr_dr, msr_pr, rw, type);
  899 + env->lr, (int)msr_ir, (int)msr_dr, pr != 0 ? 1 : 0,
  900 + rw, type);
896 901 }
897 902 #endif
898 903 }
... ... @@ -981,7 +986,7 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx,
981 986 ret = ret2;
982 987 }
983 988 }
984   -#if defined (DEBUG_MMU)
  989 +#if defined (DUMP_PAGE_TABLES)
985 990 if (loglevel != 0) {
986 991 target_phys_addr_t curaddr;
987 992 uint32_t a0, a1, a2, a3;
... ... @@ -1157,10 +1162,11 @@ int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1157 1162 {
1158 1163 ppcemb_tlb_t *tlb;
1159 1164 target_phys_addr_t raddr;
1160   - int i, ret, zsel, zpr;
  1165 + int i, ret, zsel, zpr, pr;
1161 1166  
1162 1167 ret = -1;
1163 1168 raddr = -1;
  1169 + pr = msr_pr;
1164 1170 for (i = 0; i < env->nb_tlb; i++) {
1165 1171 tlb = &env->tlb[i].tlbe;
1166 1172 if (ppcemb_tlb_check(env, tlb, &raddr, address,
... ... @@ -1177,7 +1183,7 @@ int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1177 1183 /* Check execute enable bit */
1178 1184 switch (zpr) {
1179 1185 case 0x2:
1180   - if (msr_pr)
  1186 + if (pr != 0)
1181 1187 goto check_perms;
1182 1188 /* No break here */
1183 1189 case 0x3:
... ... @@ -1186,7 +1192,7 @@ int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1186 1192 ret = 0;
1187 1193 break;
1188 1194 case 0x0:
1189   - if (msr_pr) {
  1195 + if (pr != 0) {
1190 1196 ctx->prot = 0;
1191 1197 ret = -2;
1192 1198 break;
... ... @@ -1248,7 +1254,7 @@ int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
1248 1254 if (ppcemb_tlb_check(env, tlb, &raddr, address,
1249 1255 env->spr[SPR_BOOKE_PID], 1, i) < 0)
1250 1256 continue;
1251   - if (msr_pr)
  1257 + if (msr_pr != 0)
1252 1258 prot = tlb->prot & 0xF;
1253 1259 else
1254 1260 prot = (tlb->prot >> 4) & 0xF;
... ... @@ -1343,6 +1349,7 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
1343 1349 int rw, int access_type, int check_BATs)
1344 1350 {
1345 1351 int ret;
  1352 +
1346 1353 #if 0
1347 1354 if (loglevel != 0) {
1348 1355 fprintf(logfile, "%s\n", __func__);
... ... @@ -1949,180 +1956,18 @@ void do_store_sr (CPUPPCState *env, int srnum, target_ulong value)
1949 1956  
1950 1957 target_ulong ppc_load_xer (CPUPPCState *env)
1951 1958 {
1952   - return (xer_so << XER_SO) |
1953   - (xer_ov << XER_OV) |
1954   - (xer_ca << XER_CA) |
1955   - (xer_bc << XER_BC) |
1956   - (xer_cmp << XER_CMP);
  1959 + return hreg_load_xer(env);
1957 1960 }
1958 1961  
1959 1962 void ppc_store_xer (CPUPPCState *env, target_ulong value)
1960 1963 {
1961   - xer_so = (value >> XER_SO) & 0x01;
1962   - xer_ov = (value >> XER_OV) & 0x01;
1963   - xer_ca = (value >> XER_CA) & 0x01;
1964   - xer_cmp = (value >> XER_CMP) & 0xFF;
1965   - xer_bc = (value >> XER_BC) & 0x7F;
1966   -}
1967   -
1968   -/* Swap temporary saved registers with GPRs */
1969   -static always_inline void swap_gpr_tgpr (CPUPPCState *env)
1970   -{
1971   - ppc_gpr_t tmp;
1972   -
1973   - tmp = env->gpr[0];
1974   - env->gpr[0] = env->tgpr[0];
1975   - env->tgpr[0] = tmp;
1976   - tmp = env->gpr[1];
1977   - env->gpr[1] = env->tgpr[1];
1978   - env->tgpr[1] = tmp;
1979   - tmp = env->gpr[2];
1980   - env->gpr[2] = env->tgpr[2];
1981   - env->tgpr[2] = tmp;
1982   - tmp = env->gpr[3];
1983   - env->gpr[3] = env->tgpr[3];
1984   - env->tgpr[3] = tmp;
  1964 + hreg_store_xer(env, value);
1985 1965 }
1986 1966  
1987 1967 /* GDBstub can read and write MSR... */
1988   -target_ulong do_load_msr (CPUPPCState *env)
1989   -{
1990   - return
1991   -#if defined (TARGET_PPC64)
1992   - ((target_ulong)msr_sf << MSR_SF) |
1993   - ((target_ulong)msr_isf << MSR_ISF) |
1994   - ((target_ulong)msr_hv << MSR_HV) |
1995   -#endif
1996   - ((target_ulong)msr_ucle << MSR_UCLE) |
1997   - ((target_ulong)msr_vr << MSR_VR) | /* VR / SPE */
1998   - ((target_ulong)msr_ap << MSR_AP) |
1999   - ((target_ulong)msr_sa << MSR_SA) |
2000   - ((target_ulong)msr_key << MSR_KEY) |
2001   - ((target_ulong)msr_pow << MSR_POW) |
2002   - ((target_ulong)msr_tgpr << MSR_TGPR) | /* TGPR / CE */
2003   - ((target_ulong)msr_ile << MSR_ILE) |
2004   - ((target_ulong)msr_ee << MSR_EE) |
2005   - ((target_ulong)msr_pr << MSR_PR) |
2006   - ((target_ulong)msr_fp << MSR_FP) |
2007   - ((target_ulong)msr_me << MSR_ME) |
2008   - ((target_ulong)msr_fe0 << MSR_FE0) |
2009   - ((target_ulong)msr_se << MSR_SE) | /* SE / DWE / UBLE */
2010   - ((target_ulong)msr_be << MSR_BE) | /* BE / DE */
2011   - ((target_ulong)msr_fe1 << MSR_FE1) |
2012   - ((target_ulong)msr_al << MSR_AL) |
2013   - ((target_ulong)msr_ep << MSR_EP) |
2014   - ((target_ulong)msr_ir << MSR_IR) |
2015   - ((target_ulong)msr_dr << MSR_DR) |
2016   - ((target_ulong)msr_pe << MSR_PE) |
2017   - ((target_ulong)msr_px << MSR_PX) | /* PX / PMM */
2018   - ((target_ulong)msr_ri << MSR_RI) |
2019   - ((target_ulong)msr_le << MSR_LE);
2020   -}
2021   -
2022   -int do_store_msr (CPUPPCState *env, target_ulong value)
2023   -{
2024   - int enter_pm;
2025   -
2026   - value &= env->msr_mask;
2027   - if (((value >> MSR_IR) & 1) != msr_ir ||
2028   - ((value >> MSR_DR) & 1) != msr_dr) {
2029   - /* Flush all tlb when changing translation mode */
2030   - tlb_flush(env, 1);
2031   - env->interrupt_request |= CPU_INTERRUPT_EXITTB;
2032   - }
2033   -#if !defined (CONFIG_USER_ONLY)
2034   - if (unlikely((env->flags & POWERPC_FLAG_TGPR) &&
2035   - ((value >> MSR_TGPR) & 1) != msr_tgpr)) {
2036   - /* Swap temporary saved registers with GPRs */
2037   - swap_gpr_tgpr(env);
2038   - }
2039   - if (unlikely((value >> MSR_EP) & 1) != msr_ep) {
2040   - /* Change the exception prefix on PowerPC 601 */
2041   - env->excp_prefix = ((value >> MSR_EP) & 1) * 0xFFF00000;
2042   - }
2043   -#endif
2044   -#if defined (TARGET_PPC64)
2045   - msr_sf = (value >> MSR_SF) & 1;
2046   - msr_isf = (value >> MSR_ISF) & 1;
2047   - msr_hv = (value >> MSR_HV) & 1;
2048   -#endif
2049   - msr_ucle = (value >> MSR_UCLE) & 1;
2050   - msr_vr = (value >> MSR_VR) & 1; /* VR / SPE */
2051   - msr_ap = (value >> MSR_AP) & 1;
2052   - msr_sa = (value >> MSR_SA) & 1;
2053   - msr_key = (value >> MSR_KEY) & 1;
2054   - msr_pow = (value >> MSR_POW) & 1;
2055   - msr_tgpr = (value >> MSR_TGPR) & 1; /* TGPR / CE */
2056   - msr_ile = (value >> MSR_ILE) & 1;
2057   - msr_ee = (value >> MSR_EE) & 1;
2058   - msr_pr = (value >> MSR_PR) & 1;
2059   - msr_fp = (value >> MSR_FP) & 1;
2060   - msr_me = (value >> MSR_ME) & 1;
2061   - msr_fe0 = (value >> MSR_FE0) & 1;
2062   - msr_se = (value >> MSR_SE) & 1; /* SE / DWE / UBLE */
2063   - msr_be = (value >> MSR_BE) & 1; /* BE / DE */
2064   - msr_fe1 = (value >> MSR_FE1) & 1;
2065   - msr_al = (value >> MSR_AL) & 1;
2066   - msr_ep = (value >> MSR_EP) & 1;
2067   - msr_ir = (value >> MSR_IR) & 1;
2068   - msr_dr = (value >> MSR_DR) & 1;
2069   - msr_pe = (value >> MSR_PE) & 1;
2070   - msr_px = (value >> MSR_PX) & 1; /* PX / PMM */
2071   - msr_ri = (value >> MSR_RI) & 1;
2072   - msr_le = (value >> MSR_LE) & 1;
2073   - do_compute_hflags(env);
2074   -
2075   - enter_pm = 0;
2076   - switch (env->excp_model) {
2077   - case POWERPC_EXCP_603:
2078   - case POWERPC_EXCP_603E:
2079   - case POWERPC_EXCP_G2:
2080   - /* Don't handle SLEEP mode: we should disable all clocks...
2081   - * No dynamic power-management.
2082   - */
2083   - if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00C00000) != 0)
2084   - enter_pm = 1;
2085   - break;
2086   - case POWERPC_EXCP_604:
2087   - if (msr_pow == 1)
2088   - enter_pm = 1;
2089   - break;
2090   - case POWERPC_EXCP_7x0:
2091   - if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00E00000) != 0)
2092   - enter_pm = 1;
2093   - break;
2094   - default:
2095   - break;
2096   - }
2097   -
2098   - return enter_pm;
2099   -}
2100   -
2101   -#if defined(TARGET_PPC64)
2102   -int ppc_store_msr_32 (CPUPPCState *env, uint32_t value)
2103   -{
2104   - return do_store_msr(env, (do_load_msr(env) & ~0xFFFFFFFFULL) |
2105   - (value & 0xFFFFFFFF));
2106   -}
2107   -#endif
2108   -
2109   -void do_compute_hflags (CPUPPCState *env)
  1968 +void ppc_store_msr (CPUPPCState *env, target_ulong value)
2110 1969 {
2111   - /* Compute current hflags */
2112   - env->hflags = (msr_vr << MSR_VR) |
2113   - (msr_ap << MSR_AP) | (msr_sa << MSR_SA) | (msr_pr << MSR_PR) |
2114   - (msr_fp << MSR_FP) | (msr_fe0 << MSR_FE0) | (msr_se << MSR_SE) |
2115   - (msr_be << MSR_BE) | (msr_fe1 << MSR_FE1) | (msr_le << MSR_LE);
2116   -#if defined (TARGET_PPC64)
2117   - env->hflags |= msr_cm << MSR_CM;
2118   - env->hflags |= (uint64_t)msr_sf << MSR_SF;
2119   - env->hflags |= (uint64_t)msr_hv << MSR_HV;
2120   - /* Precompute MMU index */
2121   - if (msr_pr == 0 && msr_hv == 1)
2122   - env->mmu_idx = 2;
2123   - else
2124   -#endif
2125   - env->mmu_idx = 1 - msr_pr;
  1970 + hreg_store_msr(env, value);
2126 1971 }
2127 1972  
2128 1973 /*****************************************************************************/
... ... @@ -2154,14 +1999,15 @@ static void dump_syscall (CPUState *env)
2154 1999 static always_inline void powerpc_excp (CPUState *env,
2155 2000 int excp_model, int excp)
2156 2001 {
2157   - target_ulong msr, vector;
  2002 + target_ulong msr, new_msr, vector;
2158 2003 int srr0, srr1, asrr0, asrr1;
2159 2004  
2160 2005 if (loglevel & CPU_LOG_INT) {
2161 2006 fprintf(logfile, "Raise exception at 0x" ADDRX " => 0x%08x (%02x)\n",
2162 2007 env->nip, excp, env->error_code);
2163 2008 }
2164   - msr = do_load_msr(env);
  2009 + msr = env->msr;
  2010 + new_msr = msr;
2165 2011 srr0 = SPR_SRR0;
2166 2012 srr1 = SPR_SRR1;
2167 2013 asrr0 = -1;
... ... @@ -2172,7 +2018,7 @@ static always_inline void powerpc_excp (CPUState *env,
2172 2018 /* Should never happen */
2173 2019 return;
2174 2020 case POWERPC_EXCP_CRITICAL: /* Critical input */
2175   - msr_ri = 0; /* XXX: check this */
  2021 + new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2176 2022 switch (excp_model) {
2177 2023 case POWERPC_EXCP_40x:
2178 2024 srr0 = SPR_40x_SRR2;
... ... @@ -2203,10 +2049,10 @@ static always_inline void powerpc_excp (CPUState *env,
2203 2049 env->halted = 1;
2204 2050 env->interrupt_request |= CPU_INTERRUPT_EXITTB;
2205 2051 }
2206   - msr_ri = 0;
2207   - msr_me = 0;
  2052 + new_msr &= ~((target_ulong)1 << MSR_RI);
  2053 + new_msr &= ~((target_ulong)1 << MSR_ME);
2208 2054 #if defined(TARGET_PPC64H)
2209   - msr_hv = 1;
  2055 + new_msr |= (target_ulong)1 << MSR_HV;
2210 2056 #endif
2211 2057 /* XXX: should also have something loaded in DAR / DSISR */
2212 2058 switch (excp_model) {
... ... @@ -2231,10 +2077,10 @@ static always_inline void powerpc_excp (CPUState *env,
2231 2077 "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
2232 2078 }
2233 2079 #endif
2234   - msr_ri = 0;
  2080 + new_msr &= ~((target_ulong)1 << MSR_RI);
2235 2081 #if defined(TARGET_PPC64H)
2236 2082 if (lpes1 == 0)
2237   - msr_hv = 1;
  2083 + new_msr |= (target_ulong)1 << MSR_HV;
2238 2084 #endif
2239 2085 goto store_next;
2240 2086 case POWERPC_EXCP_ISI: /* Instruction storage exception */
... ... @@ -2244,25 +2090,25 @@ static always_inline void powerpc_excp (CPUState *env,
2244 2090 "\n", msr, env->nip);
2245 2091 }
2246 2092 #endif
2247   - msr_ri = 0;
  2093 + new_msr &= ~((target_ulong)1 << MSR_RI);
2248 2094 #if defined(TARGET_PPC64H)
2249 2095 if (lpes1 == 0)
2250   - msr_hv = 1;
  2096 + new_msr |= (target_ulong)1 << MSR_HV;
2251 2097 #endif
2252 2098 msr |= env->error_code;
2253 2099 goto store_next;
2254 2100 case POWERPC_EXCP_EXTERNAL: /* External input */
2255   - msr_ri = 0;
  2101 + new_msr &= ~((target_ulong)1 << MSR_RI);
2256 2102 #if defined(TARGET_PPC64H)
2257 2103 if (lpes0 == 1)
2258   - msr_hv = 1;
  2104 + new_msr |= (target_ulong)1 << MSR_HV;
2259 2105 #endif
2260 2106 goto store_next;
2261 2107 case POWERPC_EXCP_ALIGN: /* Alignment exception */
2262   - msr_ri = 0;
  2108 + new_msr &= ~((target_ulong)1 << MSR_RI);
2263 2109 #if defined(TARGET_PPC64H)
2264 2110 if (lpes1 == 0)
2265   - msr_hv = 1;
  2111 + new_msr |= (target_ulong)1 << MSR_HV;
2266 2112 #endif
2267 2113 /* XXX: this is false */
2268 2114 /* Get rS/rD and rA from faulting opcode */
... ... @@ -2279,10 +2125,10 @@ static always_inline void powerpc_excp (CPUState *env,
2279 2125 #endif
2280 2126 return;
2281 2127 }
2282   - msr_ri = 0;
  2128 + new_msr &= ~((target_ulong)1 << MSR_RI);
2283 2129 #if defined(TARGET_PPC64H)
2284 2130 if (lpes1 == 0)
2285   - msr_hv = 1;
  2131 + new_msr |= (target_ulong)1 << MSR_HV;
2286 2132 #endif
2287 2133 msr |= 0x00100000;
2288 2134 /* Set FX */
... ... @@ -2303,26 +2149,26 @@ static always_inline void powerpc_excp (CPUState *env,
2303 2149 env->nip);
2304 2150 }
2305 2151 #endif
2306   - msr_ri = 0;
  2152 + new_msr &= ~((target_ulong)1 << MSR_RI);
2307 2153 #if defined(TARGET_PPC64H)
2308 2154 if (lpes1 == 0)
2309   - msr_hv = 1;
  2155 + new_msr |= (target_ulong)1 << MSR_HV;
2310 2156 #endif
2311 2157 msr |= 0x00080000;
2312 2158 break;
2313 2159 case POWERPC_EXCP_PRIV:
2314   - msr_ri = 0;
  2160 + new_msr &= ~((target_ulong)1 << MSR_RI);
2315 2161 #if defined(TARGET_PPC64H)
2316 2162 if (lpes1 == 0)
2317   - msr_hv = 1;
  2163 + new_msr |= (target_ulong)1 << MSR_HV;
2318 2164 #endif
2319 2165 msr |= 0x00040000;
2320 2166 break;
2321 2167 case POWERPC_EXCP_TRAP:
2322   - msr_ri = 0;
  2168 + new_msr &= ~((target_ulong)1 << MSR_RI);
2323 2169 #if defined(TARGET_PPC64H)
2324 2170 if (lpes1 == 0)
2325   - msr_hv = 1;
  2171 + new_msr |= (target_ulong)1 << MSR_HV;
2326 2172 #endif
2327 2173 msr |= 0x00020000;
2328 2174 break;
... ... @@ -2334,10 +2180,10 @@ static always_inline void powerpc_excp (CPUState *env,
2334 2180 }
2335 2181 goto store_next;
2336 2182 case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
2337   - msr_ri = 0;
  2183 + new_msr &= ~((target_ulong)1 << MSR_RI);
2338 2184 #if defined(TARGET_PPC64H)
2339 2185 if (lpes1 == 0)
2340   - msr_hv = 1;
  2186 + new_msr |= (target_ulong)1 << MSR_HV;
2341 2187 #endif
2342 2188 goto store_current;
2343 2189 case POWERPC_EXCP_SYSCALL: /* System call exception */
... ... @@ -2352,20 +2198,20 @@ static always_inline void powerpc_excp (CPUState *env,
2352 2198 if (loglevel & CPU_LOG_INT) {
2353 2199 dump_syscall(env);
2354 2200 }
2355   - msr_ri = 0;
  2201 + new_msr &= ~((target_ulong)1 << MSR_RI);
2356 2202 #if defined(TARGET_PPC64H)
2357 2203 if (lev == 1 || (lpes0 == 0 && lpes1 == 0))
2358   - msr_hv = 1;
  2204 + new_msr |= (target_ulong)1 << MSR_HV;
2359 2205 #endif
2360 2206 goto store_next;
2361 2207 case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
2362   - msr_ri = 0;
  2208 + new_msr &= ~((target_ulong)1 << MSR_RI);
2363 2209 goto store_current;
2364 2210 case POWERPC_EXCP_DECR: /* Decrementer exception */
2365   - msr_ri = 0;
  2211 + new_msr &= ~((target_ulong)1 << MSR_RI);
2366 2212 #if defined(TARGET_PPC64H)
2367 2213 if (lpes1 == 0)
2368   - msr_hv = 1;
  2214 + new_msr |= (target_ulong)1 << MSR_HV;
2369 2215 #endif
2370 2216 goto store_next;
2371 2217 case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
... ... @@ -2374,7 +2220,7 @@ static always_inline void powerpc_excp (CPUState *env,
2374 2220 if (loglevel != 0)
2375 2221 fprintf(logfile, "FIT exception\n");
2376 2222 #endif
2377   - msr_ri = 0; /* XXX: check this */
  2223 + new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2378 2224 goto store_next;
2379 2225 case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
2380 2226 #if defined (DEBUG_EXCEPTIONS)
... ... @@ -2389,13 +2235,13 @@ static always_inline void powerpc_excp (CPUState *env,
2389 2235 default:
2390 2236 break;
2391 2237 }
2392   - msr_ri = 0; /* XXX: check this */
  2238 + new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2393 2239 goto store_next;
2394 2240 case POWERPC_EXCP_DTLB: /* Data TLB error */
2395   - msr_ri = 0; /* XXX: check this */
  2241 + new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2396 2242 goto store_next;
2397 2243 case POWERPC_EXCP_ITLB: /* Instruction TLB error */
2398   - msr_ri = 0; /* XXX: check this */
  2244 + new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2399 2245 goto store_next;
2400 2246 case POWERPC_EXCP_DEBUG: /* Debug interrupt */
2401 2247 switch (excp_model) {
... ... @@ -2413,7 +2259,7 @@ static always_inline void powerpc_excp (CPUState *env,
2413 2259 goto store_next;
2414 2260 #if defined(TARGET_PPCEMB)
2415 2261 case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable */
2416   - msr_ri = 0; /* XXX: check this */
  2262 + new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2417 2263 goto store_current;
2418 2264 case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */
2419 2265 /* XXX: TODO */
... ... @@ -2426,7 +2272,7 @@ static always_inline void powerpc_excp (CPUState *env,
2426 2272 "is not implemented yet !\n");
2427 2273 goto store_next;
2428 2274 case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */
2429   - msr_ri = 0;
  2275 + new_msr &= ~((target_ulong)1 << MSR_RI);
2430 2276 /* XXX: TODO */
2431 2277 cpu_abort(env,
2432 2278 "Performance counter exception is not implemented yet !\n");
... ... @@ -2451,24 +2297,24 @@ static always_inline void powerpc_excp (CPUState *env,
2451 2297 goto store_next;
2452 2298 #endif /* defined(TARGET_PPCEMB) */
2453 2299 case POWERPC_EXCP_RESET: /* System reset exception */
2454   - msr_ri = 0;
  2300 + new_msr &= ~((target_ulong)1 << MSR_RI);
2455 2301 #if defined(TARGET_PPC64H)
2456   - msr_hv = 1;
  2302 + new_msr |= (target_ulong)1 << MSR_HV;
2457 2303 #endif
2458 2304 goto store_next;
2459 2305 #if defined(TARGET_PPC64)
2460 2306 case POWERPC_EXCP_DSEG: /* Data segment exception */
2461   - msr_ri = 0;
  2307 + new_msr &= ~((target_ulong)1 << MSR_RI);
2462 2308 #if defined(TARGET_PPC64H)
2463 2309 if (lpes1 == 0)
2464   - msr_hv = 1;
  2310 + new_msr |= (target_ulong)1 << MSR_HV;
2465 2311 #endif
2466 2312 goto store_next;
2467 2313 case POWERPC_EXCP_ISEG: /* Instruction segment exception */
2468   - msr_ri = 0;
  2314 + new_msr &= ~((target_ulong)1 << MSR_RI);
2469 2315 #if defined(TARGET_PPC64H)
2470 2316 if (lpes1 == 0)
2471   - msr_hv = 1;
  2317 + new_msr |= (target_ulong)1 << MSR_HV;
2472 2318 #endif
2473 2319 goto store_next;
2474 2320 #endif /* defined(TARGET_PPC64) */
... ... @@ -2476,46 +2322,43 @@ static always_inline void powerpc_excp (CPUState *env,
2476 2322 case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
2477 2323 srr0 = SPR_HSRR0;
2478 2324 srr1 = SPR_HSSR1;
2479   - msr_hv = 1;
  2325 + new_msr |= (target_ulong)1 << MSR_HV;
2480 2326 goto store_next;
2481 2327 #endif
2482 2328 case POWERPC_EXCP_TRACE: /* Trace exception */
2483   - msr_ri = 0;
  2329 + new_msr &= ~((target_ulong)1 << MSR_RI);
2484 2330 #if defined(TARGET_PPC64H)
2485 2331 if (lpes1 == 0)
2486   - msr_hv = 1;
  2332 + new_msr |= (target_ulong)1 << MSR_HV;
2487 2333 #endif
2488 2334 goto store_next;
2489 2335 #if defined(TARGET_PPC64H)
2490 2336 case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
2491 2337 srr0 = SPR_HSRR0;
2492 2338 srr1 = SPR_HSSR1;
2493   - msr_hv = 1;
  2339 + new_msr |= (target_ulong)1 << MSR_HV;
2494 2340 goto store_next;
2495 2341 case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */
2496 2342 srr0 = SPR_HSRR0;
2497 2343 srr1 = SPR_HSSR1;
2498   - msr_hv = 1;
2499   - /* XXX: TODO */
2500   - cpu_abort(env, "Hypervisor instruction storage exception "
2501   - "is not implemented yet !\n");
  2344 + new_msr |= (target_ulong)1 << MSR_HV;
2502 2345 goto store_next;
2503 2346 case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
2504 2347 srr0 = SPR_HSRR0;
2505 2348 srr1 = SPR_HSSR1;
2506   - msr_hv = 1;
  2349 + new_msr |= (target_ulong)1 << MSR_HV;
2507 2350 goto store_next;
2508 2351 case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */
2509 2352 srr0 = SPR_HSRR0;
2510 2353 srr1 = SPR_HSSR1;
2511   - msr_hv = 1;
  2354 + new_msr |= (target_ulong)1 << MSR_HV;
2512 2355 goto store_next;
2513 2356 #endif /* defined(TARGET_PPC64H) */
2514 2357 case POWERPC_EXCP_VPU: /* Vector unavailable exception */
2515   - msr_ri = 0;
  2358 + new_msr &= ~((target_ulong)1 << MSR_RI);
2516 2359 #if defined(TARGET_PPC64H)
2517 2360 if (lpes1 == 0)
2518   - msr_hv = 1;
  2361 + new_msr |= (target_ulong)1 << MSR_HV;
2519 2362 #endif
2520 2363 goto store_current;
2521 2364 case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */
... ... @@ -2523,7 +2366,7 @@ static always_inline void powerpc_excp (CPUState *env,
2523 2366 if (loglevel != 0)
2524 2367 fprintf(logfile, "PIT exception\n");
2525 2368 #endif
2526   - msr_ri = 0; /* XXX: check this */
  2369 + new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2527 2370 goto store_next;
2528 2371 case POWERPC_EXCP_IO: /* IO error exception */
2529 2372 /* XXX: TODO */
... ... @@ -2539,10 +2382,10 @@ static always_inline void powerpc_excp (CPUState *env,
2539 2382 "is not implemented yet !\n");
2540 2383 goto store_next;
2541 2384 case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
2542   - msr_ri = 0; /* XXX: check this */
  2385 + new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2543 2386 #if defined(TARGET_PPC64H) /* XXX: check this */
2544 2387 if (lpes1 == 0)
2545   - msr_hv = 1;
  2388 + new_msr |= (target_ulong)1 << MSR_HV;
2546 2389 #endif
2547 2390 switch (excp_model) {
2548 2391 case POWERPC_EXCP_602:
... ... @@ -2560,10 +2403,10 @@ static always_inline void powerpc_excp (CPUState *env,
2560 2403 }
2561 2404 break;
2562 2405 case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
2563   - msr_ri = 0; /* XXX: check this */
  2406 + new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2564 2407 #if defined(TARGET_PPC64H) /* XXX: check this */
2565 2408 if (lpes1 == 0)
2566   - msr_hv = 1;
  2409 + new_msr |= (target_ulong)1 << MSR_HV;
2567 2410 #endif
2568 2411 switch (excp_model) {
2569 2412 case POWERPC_EXCP_602:
... ... @@ -2581,10 +2424,10 @@ static always_inline void powerpc_excp (CPUState *env,
2581 2424 }
2582 2425 break;
2583 2426 case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
2584   - msr_ri = 0; /* XXX: check this */
  2427 + new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
2585 2428 #if defined(TARGET_PPC64H) /* XXX: check this */
2586 2429 if (lpes1 == 0)
2587   - msr_hv = 1;
  2430 + new_msr |= (target_ulong)1 << MSR_HV;
2588 2431 #endif
2589 2432 switch (excp_model) {
2590 2433 case POWERPC_EXCP_602:
... ... @@ -2593,8 +2436,10 @@ static always_inline void powerpc_excp (CPUState *env,
2593 2436 case POWERPC_EXCP_G2:
2594 2437 tlb_miss_tgpr:
2595 2438 /* Swap temporary saved registers with GPRs */
2596   - swap_gpr_tgpr(env);
2597   - msr_tgpr = 1;
  2439 + if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
  2440 + new_msr |= (target_ulong)1 << MSR_TGPR;
  2441 + hreg_swap_gpr_tgpr(env);
  2442 + }
2598 2443 goto tlb_miss;
2599 2444 case POWERPC_EXCP_7x5:
2600 2445 tlb_miss:
... ... @@ -2639,8 +2484,8 @@ static always_inline void powerpc_excp (CPUState *env,
2639 2484 if (excp == POWERPC_EXCP_IFTLB) {
2640 2485 es = "I";
2641 2486 en = 'I';
2642   - miss = &env->spr[SPR_IMISS];
2643   - cmp = &env->spr[SPR_ICMP];
  2487 + miss = &env->spr[SPR_TLBMISS];
  2488 + cmp = &env->spr[SPR_PTEHI];
2644 2489 } else {
2645 2490 if (excp == POWERPC_EXCP_DLTLB)
2646 2491 es = "DL";
... ... @@ -2681,10 +2526,10 @@ static always_inline void powerpc_excp (CPUState *env,
2681 2526 "is not implemented yet !\n");
2682 2527 goto store_next;
2683 2528 case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */
2684   - msr_ri = 0;
  2529 + new_msr &= ~((target_ulong)1 << MSR_RI);
2685 2530 #if defined(TARGET_PPC64H)
2686 2531 if (lpes1 == 0)
2687   - msr_hv = 1;
  2532 + new_msr |= (target_ulong)1 << MSR_HV;
2688 2533 #endif
2689 2534 /* XXX: TODO */
2690 2535 cpu_abort(env,
... ... @@ -2725,23 +2570,26 @@ static always_inline void powerpc_excp (CPUState *env,
2725 2570 if (asrr1 != -1)
2726 2571 env->spr[asrr1] = env->spr[srr1];
2727 2572 /* If we disactivated any translation, flush TLBs */
2728   - if (msr_ir || msr_dr)
  2573 + if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR)))
2729 2574 tlb_flush(env, 1);
2730 2575 /* reload MSR with correct bits */
2731   - msr_ee = 0;
2732   - msr_pr = 0;
2733   - msr_fp = 0;
2734   - msr_fe0 = 0;
2735   - msr_se = 0;
2736   - msr_be = 0;
2737   - msr_fe1 = 0;
2738   - msr_ir = 0;
2739   - msr_dr = 0;
  2576 + new_msr &= ~((target_ulong)1 << MSR_EE);
  2577 + new_msr &= ~((target_ulong)1 << MSR_PR);
  2578 + new_msr &= ~((target_ulong)1 << MSR_FP);
  2579 + new_msr &= ~((target_ulong)1 << MSR_FE0);
  2580 + new_msr &= ~((target_ulong)1 << MSR_SE);
  2581 + new_msr &= ~((target_ulong)1 << MSR_BE);
  2582 + new_msr &= ~((target_ulong)1 << MSR_FE1);
  2583 + new_msr &= ~((target_ulong)1 << MSR_IR);
  2584 + new_msr &= ~((target_ulong)1 << MSR_DR);
2740 2585 #if 0 /* Fix this: not on all targets */
2741   - msr_pmm = 0;
  2586 + new_msr &= ~((target_ulong)1 << MSR_PMM);
2742 2587 #endif
2743   - msr_le = msr_ile;
2744   - do_compute_hflags(env);
  2588 + new_msr &= ~((target_ulong)1 << MSR_LE);
  2589 + if (msr_ile)
  2590 + new_msr |= (target_ulong)1 << MSR_LE;
  2591 + else
  2592 + new_msr &= ~((target_ulong)1 << MSR_LE);
2745 2593 /* Jump to handler */
2746 2594 vector = env->excp_vectors[excp];
2747 2595 if (vector == (target_ulong)-1) {
... ... @@ -2751,15 +2599,26 @@ static always_inline void powerpc_excp (CPUState *env,
2751 2599 vector |= env->excp_prefix;
2752 2600 #if defined(TARGET_PPC64)
2753 2601 if (excp_model == POWERPC_EXCP_BOOKE) {
2754   - msr_cm = msr_icm;
2755   - if (!msr_cm)
  2602 + if (!msr_icm) {
  2603 + new_msr &= ~((target_ulong)1 << MSR_CM);
2756 2604 vector = (uint32_t)vector;
  2605 + } else {
  2606 + new_msr |= (target_ulong)1 << MSR_CM;
  2607 + }
2757 2608 } else {
2758   - msr_sf = msr_isf;
2759   - if (!msr_sf)
  2609 + if (!msr_isf) {
  2610 + new_msr &= ~((target_ulong)1 << MSR_SF);
2760 2611 vector = (uint32_t)vector;
  2612 + } else {
  2613 + new_msr |= (target_ulong)1 << MSR_SF;
  2614 + }
2761 2615 }
2762 2616 #endif
  2617 + /* XXX: we don't use hreg_store_msr here as already have treated
  2618 + * any special case that could occur. Just store MSR and update hflags
  2619 + */
  2620 + env->msr = new_msr;
  2621 + hreg_compute_hflags(env);
2763 2622 env->nip = vector;
2764 2623 /* Reset exception state */
2765 2624 env->exception_index = POWERPC_EXCP_NONE;
... ... @@ -2773,11 +2632,11 @@ void do_interrupt (CPUState *env)
2773 2632  
2774 2633 void ppc_hw_interrupt (CPUPPCState *env)
2775 2634 {
2776   -#if 1
  2635 +#if 0
2777 2636 if (loglevel & CPU_LOG_INT) {
2778 2637 fprintf(logfile, "%s: %p pending %08x req %08x me %d ee %d\n",
2779 2638 __func__, env, env->pending_interrupts,
2780   - env->interrupt_request, msr_me, msr_ee);
  2639 + env->interrupt_request, (int)msr_me, (int)msr_ee);
2781 2640 }
2782 2641 #endif
2783 2642 /* External reset */
... ... @@ -2801,7 +2660,7 @@ void ppc_hw_interrupt (CPUPPCState *env)
2801 2660 }
2802 2661 #endif
2803 2662 #if defined(TARGET_PPC64H)
2804   - if ((msr_ee != 0 || msr_hv == 0 || msr_pr == 1) & hdice != 0) {
  2663 + if ((msr_ee != 0 || msr_hv == 0 || msr_pr != 0) & hdice != 0) {
2805 2664 /* Hypervisor decrementer exception */
2806 2665 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
2807 2666 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
... ... @@ -2933,34 +2792,31 @@ void cpu_dump_rfi (target_ulong RA, target_ulong msr)
2933 2792 void cpu_ppc_reset (void *opaque)
2934 2793 {
2935 2794 CPUPPCState *env;
2936   - int i;
  2795 + target_ulong msr;
2937 2796  
2938 2797 env = opaque;
2939   - /* XXX: some of those flags initialisation values could depend
2940   - * on the actual PowerPC implementation
2941   - */
2942   - for (i = 0; i < 63; i++)
2943   - env->msr[i] = 0;
  2798 + msr = (target_ulong)0;
2944 2799 #if defined(TARGET_PPC64)
2945   - msr_hv = 0; /* Should be 1... */
  2800 + msr |= (target_ulong)0 << MSR_HV; /* Should be 1... */
2946 2801 #endif
2947   - msr_ap = 0; /* TO BE CHECKED */
2948   - msr_sa = 0; /* TO BE CHECKED */
2949   - msr_ep = 1;
  2802 + msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
  2803 + msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
  2804 + msr |= (target_ulong)1 << MSR_EP;
2950 2805 #if defined (DO_SINGLE_STEP) && 0
2951 2806 /* Single step trace mode */
2952   - msr_se = 1;
2953   - msr_be = 1;
  2807 + msr |= (target_ulong)1 << MSR_SE;
  2808 + msr |= (target_ulong)1 << MSR_BE;
2954 2809 #endif
2955 2810 #if defined(CONFIG_USER_ONLY)
2956   - msr_fp = 1; /* Allow floating point exceptions */
2957   - msr_pr = 1;
  2811 + msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
  2812 + msr |= (target_ulong)1 << MSR_PR;
2958 2813 #else
2959 2814 env->nip = env->hreset_vector | env->excp_prefix;
2960 2815 if (env->mmu_model != POWERPC_MMU_REAL_4xx)
2961 2816 ppc_tlb_invalidate_all(env);
2962 2817 #endif
2963   - do_compute_hflags(env);
  2818 + env->msr = msr;
  2819 + hreg_compute_hflags(env);
2964 2820 env->reserve = -1;
2965 2821 /* Be sure no exception or interrupt is pending */
2966 2822 env->pending_interrupts = 0;
... ...
target-ppc/helper_regs.h 0 โ†’ 100644
  1 +/*
  2 + * PowerPC emulation special registers manipulation helpers for qemu.
  3 + *
  4 + * Copyright (c) 2003-2007 Jocelyn Mayer
  5 + *
  6 + * This library is free software; you can redistribute it and/or
  7 + * modify it under the terms of the GNU Lesser General Public
  8 + * License as published by the Free Software Foundation; either
  9 + * version 2 of the License, or (at your option) any later version.
  10 + *
  11 + * This library is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 + * Lesser General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU Lesser General Public
  17 + * License along with this library; if not, write to the Free Software
  18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 + */
  20 +
  21 +#if !defined(__HELPER_REGS_H__)
  22 +#define __HELPER_REGS_H__
  23 +
  24 +static always_inline target_ulong hreg_load_xer (CPUPPCState *env)
  25 +{
  26 + return (xer_so << XER_SO) |
  27 + (xer_ov << XER_OV) |
  28 + (xer_ca << XER_CA) |
  29 + (xer_bc << XER_BC) |
  30 + (xer_cmp << XER_CMP);
  31 +}
  32 +
  33 +static always_inline void hreg_store_xer (CPUPPCState *env, target_ulong value)
  34 +{
  35 + xer_so = (value >> XER_SO) & 0x01;
  36 + xer_ov = (value >> XER_OV) & 0x01;
  37 + xer_ca = (value >> XER_CA) & 0x01;
  38 + xer_cmp = (value >> XER_CMP) & 0xFF;
  39 + xer_bc = (value >> XER_BC) & 0x7F;
  40 +}
  41 +
  42 +/* Swap temporary saved registers with GPRs */
  43 +static always_inline void hreg_swap_gpr_tgpr (CPUPPCState *env)
  44 +{
  45 + ppc_gpr_t tmp;
  46 +
  47 + tmp = env->gpr[0];
  48 + env->gpr[0] = env->tgpr[0];
  49 + env->tgpr[0] = tmp;
  50 + tmp = env->gpr[1];
  51 + env->gpr[1] = env->tgpr[1];
  52 + env->tgpr[1] = tmp;
  53 + tmp = env->gpr[2];
  54 + env->gpr[2] = env->tgpr[2];
  55 + env->tgpr[2] = tmp;
  56 + tmp = env->gpr[3];
  57 + env->gpr[3] = env->tgpr[3];
  58 + env->tgpr[3] = tmp;
  59 +}
  60 +
  61 +static always_inline void hreg_compute_hflags (CPUPPCState *env)
  62 +{
  63 + target_ulong hflags_mask;
  64 +
  65 + /* We 'forget' FE0 & FE1: we'll never generate imprecise exceptions */
  66 + hflags_mask = (1 << MSR_VR) | (1 << MSR_AP) | (1 << MSR_SA) |
  67 + (1 << MSR_PR) | (1 << MSR_FP) | (1 << MSR_SE) | (1 << MSR_BE) |
  68 + (1 << MSR_LE);
  69 +#if defined (TARGET_PPC64)
  70 + hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF);
  71 +#if defined (TARGET_PPC64H)
  72 + hflags_mask |= 1ULL << MSR_HV;
  73 + /* Precompute MMU index */
  74 + if (msr_pr == 0 && msr_hv != 0)
  75 + env->mmu_idx = 2;
  76 + else
  77 +#endif
  78 +#endif
  79 + env->mmu_idx = 1 - msr_pr;
  80 + env->hflags = env->msr & hflags_mask;
  81 +}
  82 +
  83 +static always_inline int hreg_store_msr (CPUPPCState *env, target_ulong value)
  84 +{
  85 + int enter_pm, excp;
  86 +
  87 + excp = 0;
  88 + value &= env->msr_mask;
  89 +#if !defined (CONFIG_USER_ONLY)
  90 + if (((value >> MSR_IR) & 1) != msr_ir ||
  91 + ((value >> MSR_DR) & 1) != msr_dr) {
  92 + /* Flush all tlb when changing translation mode */
  93 + tlb_flush(env, 1);
  94 + excp = POWERPC_EXCP_NONE;
  95 + env->interrupt_request |= CPU_INTERRUPT_EXITTB;
  96 + }
  97 + if (unlikely((env->flags & POWERPC_FLAG_TGPR) &&
  98 + ((value ^ env->msr) & (1 << MSR_TGPR)))) {
  99 + /* Swap temporary saved registers with GPRs */
  100 + hreg_swap_gpr_tgpr(env);
  101 + }
  102 + if (unlikely((value >> MSR_EP) & 1) != msr_ep) {
  103 + /* Change the exception prefix on PowerPC 601 */
  104 + env->excp_prefix = ((value >> MSR_EP) & 1) * 0xFFF00000;
  105 + }
  106 +#endif
  107 + env->msr = value;
  108 + hreg_compute_hflags(env);
  109 + enter_pm = 0;
  110 +#if !defined (CONFIG_USER_ONLY)
  111 + if (unlikely(msr_pow == 1)) {
  112 + switch (env->excp_model) {
  113 + case POWERPC_EXCP_603:
  114 + case POWERPC_EXCP_603E:
  115 + case POWERPC_EXCP_G2:
  116 + /* Don't handle SLEEP mode: we should disable all clocks...
  117 + * No dynamic power-management.
  118 + */
  119 + if ((env->spr[SPR_HID0] & 0x00C00000) != 0)
  120 + enter_pm = 1;
  121 + break;
  122 + case POWERPC_EXCP_604:
  123 + enter_pm = 1;
  124 + break;
  125 + case POWERPC_EXCP_7x0:
  126 + if ((env->spr[SPR_HID0] & 0x00E00000) != 0)
  127 + enter_pm = 1;
  128 + break;
  129 + default:
  130 + break;
  131 + }
  132 + if (enter_pm) {
  133 + env->halted = 1;
  134 + excp = EXCP_HALTED;
  135 + }
  136 + }
  137 +#endif
  138 +
  139 + return excp;
  140 +}
  141 +
  142 +#endif /* !defined(__HELPER_REGS_H__) */
... ...
target-ppc/op.c
... ... @@ -22,6 +22,7 @@
22 22  
23 23 #include "config.h"
24 24 #include "exec.h"
  25 +#include "helper_regs.h"
25 26 #include "op_helper.h"
26 27  
27 28 #define REG 0
... ... @@ -284,13 +285,13 @@ void OPPROTO op_store_xer_bc (void)
284 285  
285 286 void OPPROTO op_load_xer (void)
286 287 {
287   - do_load_xer();
  288 + T0 = hreg_load_xer(env);
288 289 RETURN();
289 290 }
290 291  
291 292 void OPPROTO op_store_xer (void)
292 293 {
293   - do_store_xer();
  294 + hreg_store_xer(env, T0);
294 295 RETURN();
295 296 }
296 297  
... ... @@ -358,37 +359,36 @@ void OPPROTO op_store_asr (void)
358 359  
359 360 void OPPROTO op_load_msr (void)
360 361 {
361   - T0 = do_load_msr(env);
  362 + T0 = env->msr;
362 363 RETURN();
363 364 }
364 365  
365 366 void OPPROTO op_store_msr (void)
366 367 {
367   - if (do_store_msr(env, T0)) {
368   - env->halted = 1;
369   - do_raise_exception(EXCP_HLT);
370   - }
  368 + do_store_msr();
371 369 RETURN();
372 370 }
373 371  
374   -void OPPROTO op_update_riee (void)
  372 +#if defined (TARGET_PPC64)
  373 +void OPPROTO op_store_msr_32 (void)
375 374 {
376   - msr_ri = (T0 >> MSR_RI) & 1;
377   - msr_ee = (T0 >> MSR_EE) & 1;
  375 + T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF);
  376 + do_store_msr();
378 377 RETURN();
379 378 }
  379 +#endif
380 380  
381   -#if defined (TARGET_PPC64)
382   -void OPPROTO op_store_msr_32 (void)
  381 +void OPPROTO op_update_riee (void)
383 382 {
384   - if (ppc_store_msr_32(env, T0)) {
385   - env->halted = 1;
386   - do_raise_exception(EXCP_HLT);
387   - }
  383 + /* We don't call do_store_msr here as we won't trigger
  384 + * any special case nor change hflags
  385 + */
  386 + T0 &= (1 << MSR_RI) | (1 << MSR_EE);
  387 + env->msr &= ~(1 << MSR_RI) | (1 << MSR_EE);
  388 + env->msr |= T0;
388 389 RETURN();
389 390 }
390 391 #endif
391   -#endif
392 392  
393 393 /* SPR */
394 394 void OPPROTO op_load_spr (void)
... ... @@ -2517,7 +2517,12 @@ void OPPROTO op_rfmci (void)
2517 2517  
2518 2518 void OPPROTO op_wrte (void)
2519 2519 {
2520   - msr_ee = T0 >> 16;
  2520 + /* We don't call do_store_msr here as we won't trigger
  2521 + * any special case nor change hflags
  2522 + */
  2523 + T0 &= 1 << MSR_EE;
  2524 + env->msr &= ~(1 << MSR_EE);
  2525 + env->msr |= T0;
2521 2526 RETURN();
2522 2527 }
2523 2528  
... ...
target-ppc/op_helper.c
... ... @@ -19,6 +19,7 @@
19 19 */
20 20 #include "exec.h"
21 21  
  22 +#include "helper_regs.h"
22 23 #include "op_helper.h"
23 24  
24 25 #define MEMSUFFIX _raw
... ... @@ -98,24 +99,6 @@ void do_store_cr (uint32_t mask)
98 99 }
99 100 }
100 101  
101   -void do_load_xer (void)
102   -{
103   - T0 = (xer_so << XER_SO) |
104   - (xer_ov << XER_OV) |
105   - (xer_ca << XER_CA) |
106   - (xer_bc << XER_BC) |
107   - (xer_cmp << XER_CMP);
108   -}
109   -
110   -void do_store_xer (void)
111   -{
112   - xer_so = (T0 >> XER_SO) & 0x01;
113   - xer_ov = (T0 >> XER_OV) & 0x01;
114   - xer_ca = (T0 >> XER_CA) & 0x01;
115   - xer_cmp = (T0 >> XER_CMP) & 0xFF;
116   - xer_bc = (T0 >> XER_BC) & 0x7F;
117   -}
118   -
119 102 #if defined(TARGET_PPC64)
120 103 void do_store_pri (int prio)
121 104 {
... ... @@ -970,56 +953,63 @@ void do_fcmpo (void)
970 953  
971 954 #if !defined (CONFIG_USER_ONLY)
972 955 void cpu_dump_rfi (target_ulong RA, target_ulong msr);
973   -void do_rfi (void)
  956 +
  957 +void do_store_msr (void)
  958 +{
  959 + T0 = hreg_store_msr(env, T0);
  960 + if (T0 != 0) {
  961 + env->interrupt_request |= CPU_INTERRUPT_EXITTB;
  962 + do_raise_exception(T0);
  963 + }
  964 +}
  965 +
  966 +static always_inline void __do_rfi (target_ulong nip, target_ulong msr,
  967 + target_ulong msrm, int keep_msrh)
974 968 {
975 969 #if defined(TARGET_PPC64)
976   - if (env->spr[SPR_SRR1] & (1ULL << MSR_SF)) {
977   - env->nip = (uint64_t)(env->spr[SPR_SRR0] & ~0x00000003);
978   - do_store_msr(env, (uint64_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL));
  970 + if (msr & (1ULL << MSR_SF)) {
  971 + nip = (uint64_t)nip;
  972 + msr &= (uint64_t)msrm;
979 973 } else {
980   - env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003);
981   - ppc_store_msr_32(env, (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL));
  974 + nip = (uint32_t)nip;
  975 + msr = (uint32_t)(msr & msrm);
  976 + if (keep_msrh)
  977 + msr |= env->msr & ~((uint64_t)0xFFFFFFFF);
982 978 }
983 979 #else
984   - env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003);
985   - do_store_msr(env, (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL));
  980 + nip = (uint32_t)nip;
  981 + msr &= (uint32_t)msrm;
986 982 #endif
  983 + /* XXX: beware: this is false if VLE is supported */
  984 + env->nip = nip & ~((target_ulong)0x00000003);
  985 + hreg_store_msr(env, msr);
987 986 #if defined (DEBUG_OP)
988   - cpu_dump_rfi(env->nip, do_load_msr(env));
  987 + cpu_dump_rfi(env->nip, env->msr);
989 988 #endif
  989 + /* No need to raise an exception here,
  990 + * as rfi is always the last insn of a TB
  991 + */
990 992 env->interrupt_request |= CPU_INTERRUPT_EXITTB;
991 993 }
992 994  
  995 +void do_rfi (void)
  996 +{
  997 + __do_rfi(env->spr[SPR_SRR0], env->spr[SPR_SRR1],
  998 + ~((target_ulong)0xFFFF0000), 1);
  999 +}
  1000 +
993 1001 #if defined(TARGET_PPC64)
994 1002 void do_rfid (void)
995 1003 {
996   - if (env->spr[SPR_SRR1] & (1ULL << MSR_SF)) {
997   - env->nip = (uint64_t)(env->spr[SPR_SRR0] & ~0x00000003);
998   - do_store_msr(env, (uint64_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL));
999   - } else {
1000   - env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003);
1001   - do_store_msr(env, (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL));
1002   - }
1003   -#if defined (DEBUG_OP)
1004   - cpu_dump_rfi(env->nip, do_load_msr(env));
1005   -#endif
1006   - env->interrupt_request |= CPU_INTERRUPT_EXITTB;
  1004 + __do_rfi(env->spr[SPR_SRR0], env->spr[SPR_SRR1],
  1005 + ~((target_ulong)0xFFFF0000), 0);
1007 1006 }
1008 1007 #endif
1009 1008 #if defined(TARGET_PPC64H)
1010 1009 void do_hrfid (void)
1011 1010 {
1012   - if (env->spr[SPR_HSRR1] & (1ULL << MSR_SF)) {
1013   - env->nip = (uint64_t)(env->spr[SPR_HSRR0] & ~0x00000003);
1014   - do_store_msr(env, (uint64_t)(env->spr[SPR_HSRR1] & ~0xFFFF0000UL));
1015   - } else {
1016   - env->nip = (uint32_t)(env->spr[SPR_HSRR0] & ~0x00000003);
1017   - do_store_msr(env, (uint32_t)(env->spr[SPR_HSRR1] & ~0xFFFF0000UL));
1018   - }
1019   -#if defined (DEBUG_OP)
1020   - cpu_dump_rfi(env->nip, do_load_msr(env));
1021   -#endif
1022   - env->interrupt_request |= CPU_INTERRUPT_EXITTB;
  1011 + __do_rfi(env->spr[SPR_HSRR0], env->spr[SPR_HSRR1],
  1012 + ~((target_ulong)0xFFFF0000), 0);
1023 1013 }
1024 1014 #endif
1025 1015 #endif
... ... @@ -1214,13 +1204,7 @@ void do_POWER_rac (void)
1214 1204  
1215 1205 void do_POWER_rfsvc (void)
1216 1206 {
1217   - env->nip = env->lr & ~0x00000003UL;
1218   - T0 = env->ctr & 0x0000FFFFUL;
1219   - do_store_msr(env, T0);
1220   -#if defined (DEBUG_OP)
1221   - cpu_dump_rfi(env->nip, do_load_msr(env));
1222   -#endif
1223   - env->interrupt_request |= CPU_INTERRUPT_EXITTB;
  1207 + __do_rfi(env->lr, env->ctr, 0x0000FFFF, 0);
1224 1208 }
1225 1209  
1226 1210 /* PowerPC 601 BAT management helper */
... ... @@ -1332,63 +1316,26 @@ void do_store_dcr (void)
1332 1316 #if !defined(CONFIG_USER_ONLY)
1333 1317 void do_40x_rfci (void)
1334 1318 {
1335   - env->nip = env->spr[SPR_40x_SRR2];
1336   - do_store_msr(env, env->spr[SPR_40x_SRR3] & ~0xFFFF0000);
1337   -#if defined (DEBUG_OP)
1338   - cpu_dump_rfi(env->nip, do_load_msr(env));
1339   -#endif
1340   - env->interrupt_request = CPU_INTERRUPT_EXITTB;
  1319 + __do_rfi(env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3],
  1320 + ~((target_ulong)0xFFFF0000), 0);
1341 1321 }
1342 1322  
1343 1323 void do_rfci (void)
1344 1324 {
1345   -#if defined(TARGET_PPC64)
1346   - if (env->spr[SPR_BOOKE_CSRR1] & (1 << MSR_CM)) {
1347   - env->nip = (uint64_t)env->spr[SPR_BOOKE_CSRR0];
1348   - } else
1349   -#endif
1350   - {
1351   - env->nip = (uint32_t)env->spr[SPR_BOOKE_CSRR0];
1352   - }
1353   - do_store_msr(env, (uint32_t)env->spr[SPR_BOOKE_CSRR1] & ~0x3FFF0000);
1354   -#if defined (DEBUG_OP)
1355   - cpu_dump_rfi(env->nip, do_load_msr(env));
1356   -#endif
1357   - env->interrupt_request = CPU_INTERRUPT_EXITTB;
  1325 + __do_rfi(env->spr[SPR_BOOKE_CSRR0], SPR_BOOKE_CSRR1,
  1326 + ~((target_ulong)0x3FFF0000), 0);
1358 1327 }
1359 1328  
1360 1329 void do_rfdi (void)
1361 1330 {
1362   -#if defined(TARGET_PPC64)
1363   - if (env->spr[SPR_BOOKE_DSRR1] & (1 << MSR_CM)) {
1364   - env->nip = (uint64_t)env->spr[SPR_BOOKE_DSRR0];
1365   - } else
1366   -#endif
1367   - {
1368   - env->nip = (uint32_t)env->spr[SPR_BOOKE_DSRR0];
1369   - }
1370   - do_store_msr(env, (uint32_t)env->spr[SPR_BOOKE_DSRR1] & ~0x3FFF0000);
1371   -#if defined (DEBUG_OP)
1372   - cpu_dump_rfi(env->nip, do_load_msr(env));
1373   -#endif
1374   - env->interrupt_request = CPU_INTERRUPT_EXITTB;
  1331 + __do_rfi(env->spr[SPR_BOOKE_DSRR0], SPR_BOOKE_DSRR1,
  1332 + ~((target_ulong)0x3FFF0000), 0);
1375 1333 }
1376 1334  
1377 1335 void do_rfmci (void)
1378 1336 {
1379   -#if defined(TARGET_PPC64)
1380   - if (env->spr[SPR_BOOKE_MCSRR1] & (1 << MSR_CM)) {
1381   - env->nip = (uint64_t)env->spr[SPR_BOOKE_MCSRR0];
1382   - } else
1383   -#endif
1384   - {
1385   - env->nip = (uint32_t)env->spr[SPR_BOOKE_MCSRR0];
1386   - }
1387   - do_store_msr(env, (uint32_t)env->spr[SPR_BOOKE_MCSRR1] & ~0x3FFF0000);
1388   -#if defined (DEBUG_OP)
1389   - cpu_dump_rfi(env->nip, do_load_msr(env));
1390   -#endif
1391   - env->interrupt_request = CPU_INTERRUPT_EXITTB;
  1337 + __do_rfi(env->spr[SPR_BOOKE_MCSRR0], SPR_BOOKE_MCSRR1,
  1338 + ~((target_ulong)0x3FFF0000), 0);
1392 1339 }
1393 1340  
1394 1341 void do_load_403_pb (int num)
... ...
target-ppc/op_helper.h
... ... @@ -57,8 +57,6 @@ void do_print_mem_EA (target_ulong EA);
57 57 /* Registers load and stores */
58 58 void do_load_cr (void);
59 59 void do_store_cr (uint32_t mask);
60   -void do_load_xer (void);
61   -void do_store_xer (void);
62 60 #if defined(TARGET_PPC64)
63 61 void do_store_pri (int prio);
64 62 #endif
... ... @@ -129,6 +127,7 @@ void do_tw (int flags);
129 127 void do_td (int flags);
130 128 #endif
131 129 #if !defined(CONFIG_USER_ONLY)
  130 +void do_store_msr (void);
132 131 void do_rfi (void);
133 132 #if defined(TARGET_PPC64)
134 133 void do_rfid (void);
... ...
target-ppc/translate.c
... ... @@ -6538,18 +6538,10 @@ GEN_SPE(efdtsteq, speundef, 0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
6538 6538 GEN_OPCODE_MARK(end);
6539 6539  
6540 6540 #include "translate_init.c"
  6541 +#include "helper_regs.h"
6541 6542  
6542 6543 /*****************************************************************************/
6543 6544 /* Misc PowerPC helpers */
6544   -static always_inline uint32_t load_xer (CPUState *env)
6545   -{
6546   - return (xer_so << XER_SO) |
6547   - (xer_ov << XER_OV) |
6548   - (xer_ca << XER_CA) |
6549   - (xer_bc << XER_BC) |
6550   - (xer_cmp << XER_CMP);
6551   -}
6552   -
6553 6545 void cpu_dump_state (CPUState *env, FILE *f,
6554 6546 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6555 6547 int flags)
... ... @@ -6566,8 +6558,8 @@ void cpu_dump_state (CPUState *env, FILE *f,
6566 6558  
6567 6559 int i;
6568 6560  
6569   - cpu_fprintf(f, "NIP " ADDRX " LR " ADDRX " CTR " ADDRX "\n",
6570   - env->nip, env->lr, env->ctr);
  6561 + cpu_fprintf(f, "NIP " ADDRX " LR " ADDRX " CTR " ADDRX " idx %d\n",
  6562 + env->nip, env->lr, env->ctr, env->mmu_idx);
6571 6563 cpu_fprintf(f, "MSR " REGX FILL " XER %08x "
6572 6564 #if !defined(NO_TIMER_DUMP)
6573 6565 "TB %08x %08x "
... ... @@ -6576,7 +6568,7 @@ void cpu_dump_state (CPUState *env, FILE *f,
6576 6568 #endif
6577 6569 #endif
6578 6570 "\n",
6579   - do_load_msr(env), load_xer(env)
  6571 + env->msr, hreg_load_xer(env)
6580 6572 #if !defined(NO_TIMER_DUMP)
6581 6573 , cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
6582 6574 #if !defined(CONFIG_USER_ONLY)
... ... @@ -6753,7 +6745,7 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
6753 6745 if (loglevel & CPU_LOG_TB_IN_ASM) {
6754 6746 fprintf(logfile, "----------------\n");
6755 6747 fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
6756   - ctx.nip, 1 - msr_pr, msr_ir);
  6748 + ctx.nip, supervisor, (int)msr_ir);
6757 6749 }
6758 6750 #endif
6759 6751 ctx.opcode = ldl_code(ctx.nip);
... ... @@ -6787,12 +6779,12 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
6787 6779 fprintf(logfile, "invalid/unsupported opcode: "
6788 6780 "%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
6789 6781 opc1(ctx.opcode), opc2(ctx.opcode),
6790   - opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
  6782 + opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6791 6783 } else {
6792 6784 printf("invalid/unsupported opcode: "
6793 6785 "%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
6794 6786 opc1(ctx.opcode), opc2(ctx.opcode),
6795   - opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
  6787 + opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6796 6788 }
6797 6789 } else {
6798 6790 if (unlikely((ctx.opcode & handler->inval) != 0)) {
... ...