summary refs log tree commit diff stats
path: root/target-ppc
diff options
context:
space:
mode:
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/arch_dump.c6
-rw-r--r--target-ppc/cpu-qom.h8
-rw-r--r--target-ppc/cpu.h17
-rw-r--r--target-ppc/excp_helper.c73
-rw-r--r--target-ppc/fpu_helper.c26
-rw-r--r--target-ppc/helper_regs.h2
-rw-r--r--target-ppc/int_helper.c4
-rw-r--r--target-ppc/kvm.c8
-rw-r--r--target-ppc/machine.c4
-rw-r--r--target-ppc/misc_helper.c4
-rw-r--r--target-ppc/mmu-hash32.c35
-rw-r--r--target-ppc/mmu-hash32.h14
-rw-r--r--target-ppc/mmu-hash64.c30
-rw-r--r--target-ppc/mmu-hash64.h8
-rw-r--r--target-ppc/mmu_helper.c208
-rw-r--r--target-ppc/translate.c4
-rw-r--r--target-ppc/translate_init.c66
-rw-r--r--target-ppc/user_only_helper.c8
18 files changed, 296 insertions, 229 deletions
diff --git a/target-ppc/arch_dump.c b/target-ppc/arch_dump.c
index 17fd4c6fb1..9dccf1ae1f 100644
--- a/target-ppc/arch_dump.c
+++ b/target-ppc/arch_dump.c
@@ -164,7 +164,7 @@ static void ppc64_write_elf64_speregset(Note *note, PowerPCCPU *cpu)
     speregset->spe_fscr = cpu_to_be32(cpu->env.spe_fscr);
 }
 
-struct NoteFuncDescStruct {
+static const struct NoteFuncDescStruct {
     int contents_size;
     void (*note_contents_func)(Note *note, PowerPCCPU *cpu);
 } note_func[] = {
@@ -196,7 +196,7 @@ ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
     int name_size = 8; /* "CORE" or "QEMU" rounded */
     size_t elf_note_size = 0;
     int note_head_size;
-    NoteFuncDesc *nf;
+    const NoteFuncDesc *nf;
 
     if (class != ELFCLASS64) {
         return -1;
@@ -221,7 +221,7 @@ static int ppc64_write_all_elf64_notes(const char *note_name,
     Note note;
     int ret = -1;
     int note_size;
-    NoteFuncDesc *nf;
+    const NoteFuncDesc *nf;
 
     for (nf = note_func; nf->note_contents_func; nf++) {
         note.hdr.n_namesz = cpu_to_be32(sizeof(note.name));
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index b17c024543..47dc8e6fdf 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -38,6 +38,8 @@
 #define POWERPC_CPU_GET_CLASS(obj) \
     OBJECT_GET_CLASS(PowerPCCPUClass, (obj), TYPE_POWERPC_CPU)
 
+typedef struct PowerPCCPU PowerPCCPU;
+
 /**
  * PowerPCCPUClass:
  * @parent_realize: The parent class' realize handler.
@@ -71,7 +73,7 @@ typedef struct PowerPCCPUClass {
     void (*init_proc)(CPUPPCState *env);
     int  (*check_pow)(CPUPPCState *env);
 #if defined(CONFIG_SOFTMMU)
-    int (*handle_mmu_fault)(CPUPPCState *env, target_ulong eaddr, int rwx,
+    int (*handle_mmu_fault)(PowerPCCPU *cpu, target_ulong eaddr, int rwx,
                             int mmu_idx);
 #endif
 } PowerPCCPUClass;
@@ -83,14 +85,14 @@ typedef struct PowerPCCPUClass {
  *
  * A PowerPC CPU.
  */
-typedef struct PowerPCCPU {
+struct PowerPCCPU {
     /*< private >*/
     CPUState parent_obj;
     /*< public >*/
 
     CPUPPCState env;
     int cpu_dt_id;
-} PowerPCCPU;
+};
 
 static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
 {
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index afab267485..2719c08323 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -334,6 +334,7 @@ struct ppc_spr_t {
     void (*hea_write)(void *opaque, int spr_num, int gpr_num);
 #endif
     const char *name;
+    target_ulong default_value;
 #ifdef CONFIG_KVM
     /* We (ab)use the fact that all the SPRs will have ids for the
      * ONE_REG interface will have KVM_REG_PPC to use 0 as meaning,
@@ -1111,8 +1112,8 @@ int cpu_ppc_signal_handler (int host_signum, void *pinfo,
                             void *puc);
 void ppc_hw_interrupt (CPUPPCState *env);
 #if defined(CONFIG_USER_ONLY)
-int cpu_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
-                         int mmu_idx);
+int ppc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
+                             int mmu_idx);
 #endif
 
 #if !defined(CONFIG_USER_ONLY)
@@ -1900,6 +1901,8 @@ enum {
     PPC2_LSQ_ISA207    = 0x0000000000002000ULL,
     /* ISA 2.07 Altivec                                                      */
     PPC2_ALTIVEC_207   = 0x0000000000004000ULL,
+    /* PowerISA 2.07 Book3s specification                                    */
+    PPC2_ISA207S       = 0x0000000000008000ULL,
 
 #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
                         PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
@@ -2100,7 +2103,7 @@ static inline int booke206_tlbm_to_tlbn(CPUPPCState *env, ppcmas_tlb_t *tlbm)
         }
     }
 
-    cpu_abort(env, "Unknown TLBe: %d\n", id);
+    cpu_abort(CPU(ppc_env_get_cpu(env)), "Unknown TLBe: %d\n", id);
     return 0;
 }
 
@@ -2171,14 +2174,6 @@ static inline bool msr_is_64bit(CPUPPCState *env, target_ulong msr)
 
 extern void (*cpu_ppc_hypercall)(PowerPCCPU *);
 
-static inline bool cpu_has_work(CPUState *cpu)
-{
-    PowerPCCPU *ppc_cpu = POWERPC_CPU(cpu);
-    CPUPPCState *env = &ppc_cpu->env;
-
-    return msr_ee && (cpu->interrupt_request & CPU_INTERRUPT_HARD);
-}
-
 #include "exec/exec-all.h"
 
 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index d541929743..19bc6b66ba 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -43,13 +43,15 @@ void ppc_cpu_do_interrupt(CPUState *cs)
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     CPUPPCState *env = &cpu->env;
 
-    env->exception_index = POWERPC_EXCP_NONE;
+    cs->exception_index = POWERPC_EXCP_NONE;
     env->error_code = 0;
 }
 
 void ppc_hw_interrupt(CPUPPCState *env)
 {
-    env->exception_index = POWERPC_EXCP_NONE;
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
+
+    cs->exception_index = POWERPC_EXCP_NONE;
     env->error_code = 0;
 }
 #else /* defined(CONFIG_USER_ONLY) */
@@ -68,8 +70,8 @@ static inline void dump_syscall(CPUPPCState *env)
  */
 static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
 {
+    CPUState *cs = CPU(cpu);
     CPUPPCState *env = &cpu->env;
-    CPUState *cs;
     target_ulong msr, new_msr, vector;
     int srr0, srr1, asrr0, asrr1;
     int lpes0, lpes1, lev;
@@ -135,7 +137,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
                 fprintf(stderr, "Machine check while not allowed. "
                         "Entering checkstop state\n");
             }
-            cs = CPU(cpu);
             cs->halted = 1;
             cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
         }
@@ -204,7 +205,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         case POWERPC_EXCP_FP:
             if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
                 LOG_EXCP("Ignore floating point exception\n");
-                env->exception_index = POWERPC_EXCP_NONE;
+                cs->exception_index = POWERPC_EXCP_NONE;
                 env->error_code = 0;
                 return;
             }
@@ -241,7 +242,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             break;
         default:
             /* Should never occur */
-            cpu_abort(env, "Invalid program exception %d. Aborting\n",
+            cpu_abort(cs, "Invalid program exception %d. Aborting\n",
                       env->error_code);
             break;
         }
@@ -301,26 +302,26 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             break;
         }
         /* XXX: TODO */
-        cpu_abort(env, "Debug exception is not implemented yet !\n");
+        cpu_abort(cs, "Debug exception is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_SPEU:      /* SPE/embedded floating-point unavailable  */
         env->spr[SPR_BOOKE_ESR] = ESR_SPV;
         goto store_current;
     case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */
         /* XXX: TODO */
-        cpu_abort(env, "Embedded floating point data exception "
+        cpu_abort(cs, "Embedded floating point data exception "
                   "is not implemented yet !\n");
         env->spr[SPR_BOOKE_ESR] = ESR_SPV;
         goto store_next;
     case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */
         /* XXX: TODO */
-        cpu_abort(env, "Embedded floating point round exception "
+        cpu_abort(cs, "Embedded floating point round exception "
                   "is not implemented yet !\n");
         env->spr[SPR_BOOKE_ESR] = ESR_SPV;
         goto store_next;
     case POWERPC_EXCP_EPERFM:    /* Embedded performance monitor interrupt   */
         /* XXX: TODO */
-        cpu_abort(env,
+        cpu_abort(cs,
                   "Performance counter exception is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */
@@ -402,15 +403,15 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         goto store_next;
     case POWERPC_EXCP_IO:        /* IO error exception                       */
         /* XXX: TODO */
-        cpu_abort(env, "601 IO error exception is not implemented yet !\n");
+        cpu_abort(cs, "601 IO error exception is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_RUNM:      /* Run mode exception                       */
         /* XXX: TODO */
-        cpu_abort(env, "601 run mode exception is not implemented yet !\n");
+        cpu_abort(cs, "601 run mode exception is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_EMUL:      /* Emulation trap exception                 */
         /* XXX: TODO */
-        cpu_abort(env, "602 emulation trap exception "
+        cpu_abort(cs, "602 emulation trap exception "
                   "is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */
@@ -428,7 +429,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         case POWERPC_EXCP_74xx:
             goto tlb_miss_74xx;
         default:
-            cpu_abort(env, "Invalid instruction TLB miss exception\n");
+            cpu_abort(cs, "Invalid instruction TLB miss exception\n");
             break;
         }
         break;
@@ -447,7 +448,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         case POWERPC_EXCP_74xx:
             goto tlb_miss_74xx;
         default:
-            cpu_abort(env, "Invalid data load TLB miss exception\n");
+            cpu_abort(cs, "Invalid data load TLB miss exception\n");
             break;
         }
         break;
@@ -533,30 +534,30 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             msr |= env->error_code; /* key bit */
             break;
         default:
-            cpu_abort(env, "Invalid data store TLB miss exception\n");
+            cpu_abort(cs, "Invalid data store TLB miss exception\n");
             break;
         }
         goto store_next;
     case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */
         /* XXX: TODO */
-        cpu_abort(env, "Floating point assist exception "
+        cpu_abort(cs, "Floating point assist exception "
                   "is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_DABR:      /* Data address breakpoint                  */
         /* XXX: TODO */
-        cpu_abort(env, "DABR exception is not implemented yet !\n");
+        cpu_abort(cs, "DABR exception is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */
         /* XXX: TODO */
-        cpu_abort(env, "IABR exception is not implemented yet !\n");
+        cpu_abort(cs, "IABR exception is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_SMI:       /* System management interrupt              */
         /* XXX: TODO */
-        cpu_abort(env, "SMI exception is not implemented yet !\n");
+        cpu_abort(cs, "SMI exception is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */
         /* XXX: TODO */
-        cpu_abort(env, "Thermal management exception "
+        cpu_abort(cs, "Thermal management exception "
                   "is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */
@@ -564,36 +565,36 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
             new_msr |= (target_ulong)MSR_HVB;
         }
         /* XXX: TODO */
-        cpu_abort(env,
+        cpu_abort(cs,
                   "Performance counter exception is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */
         /* XXX: TODO */
-        cpu_abort(env, "VPU assist exception is not implemented yet !\n");
+        cpu_abort(cs, "VPU assist exception is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_SOFTP:     /* Soft patch exception                     */
         /* XXX: TODO */
-        cpu_abort(env,
+        cpu_abort(cs,
                   "970 soft-patch exception is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */
         /* XXX: TODO */
-        cpu_abort(env,
+        cpu_abort(cs,
                   "970 maintenance exception is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_MEXTBR:    /* Maskable external breakpoint             */
         /* XXX: TODO */
-        cpu_abort(env, "Maskable external exception "
+        cpu_abort(cs, "Maskable external exception "
                   "is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_NMEXTBR:   /* Non maskable external breakpoint         */
         /* XXX: TODO */
-        cpu_abort(env, "Non maskable external exception "
+        cpu_abort(cs, "Non maskable external exception "
                   "is not implemented yet !\n");
         goto store_next;
     default:
     excp_invalid:
-        cpu_abort(env, "Invalid PowerPC exception %d. Aborting\n", excp);
+        cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
         break;
     store_current:
         /* save current instruction location */
@@ -615,7 +616,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     }
     /* If we disactivated any translation, flush TLBs */
     if (msr & ((1 << MSR_IR) | (1 << MSR_DR))) {
-        tlb_flush(env, 1);
+        tlb_flush(cs, 1);
     }
 
 #ifdef TARGET_PPC64
@@ -635,7 +636,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     /* Jump to handler */
     vector = env->excp_vectors[excp];
     if (vector == (target_ulong)-1ULL) {
-        cpu_abort(env, "Raised an exception without defined vector %d\n",
+        cpu_abort(cs, "Raised an exception without defined vector %d\n",
                   excp);
     }
     vector |= env->excp_prefix;
@@ -662,7 +663,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
     hreg_compute_hflags(env);
     env->nip = vector;
     /* Reset exception state */
-    env->exception_index = POWERPC_EXCP_NONE;
+    cs->exception_index = POWERPC_EXCP_NONE;
     env->error_code = 0;
 
     if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
@@ -670,7 +671,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         /* XXX: The BookE changes address space when switching modes,
                 we should probably implement that as different MMU indexes,
                 but for the moment we do it the slow way and flush all.  */
-        tlb_flush(env, 1);
+        tlb_flush(cs, 1);
     }
 }
 
@@ -679,7 +680,7 @@ void ppc_cpu_do_interrupt(CPUState *cs)
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     CPUPPCState *env = &cpu->env;
 
-    powerpc_excp(cpu, env->excp_model, env->exception_index);
+    powerpc_excp(cpu, env->excp_model, cs->exception_index);
 }
 
 void ppc_hw_interrupt(CPUPPCState *env)
@@ -815,12 +816,14 @@ static void cpu_dump_rfi(target_ulong RA, target_ulong msr)
 void helper_raise_exception_err(CPUPPCState *env, uint32_t exception,
                                 uint32_t error_code)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
+
 #if 0
     printf("Raise exception %3x code : %d\n", exception, error_code);
 #endif
-    env->exception_index = exception;
+    cs->exception_index = exception;
     env->error_code = error_code;
-    cpu_loop_exit(env);
+    cpu_loop_exit(cs);
 }
 
 void helper_raise_exception(CPUPPCState *env, uint32_t exception)
diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index e7f329566d..fd91239d37 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -119,6 +119,7 @@ uint32_t helper_compute_fprf(CPUPPCState *env, uint64_t arg, uint32_t set_fprf)
 static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op,
                                              int set_fpcc)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     uint64_t ret = 0;
     int ve;
 
@@ -155,7 +156,7 @@ static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op,
         }
         /* We must update the target FPR before raising the exception */
         if (ve != 0) {
-            env->exception_index = POWERPC_EXCP_PROGRAM;
+            cs->exception_index = POWERPC_EXCP_PROGRAM;
             env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_VXVC;
             /* Update the floating-point enabled exception summary */
             env->fpscr |= 1 << FPSCR_FEX;
@@ -224,6 +225,8 @@ static inline void float_zero_divide_excp(CPUPPCState *env)
 
 static inline void float_overflow_excp(CPUPPCState *env)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
+
     env->fpscr |= 1 << FPSCR_OX;
     /* Update the floating-point exception summary */
     env->fpscr |= 1 << FPSCR_FX;
@@ -232,7 +235,7 @@ static inline void float_overflow_excp(CPUPPCState *env)
         /* Update the floating-point enabled exception summary */
         env->fpscr |= 1 << FPSCR_FEX;
         /* We must update the target FPR before raising the exception */
-        env->exception_index = POWERPC_EXCP_PROGRAM;
+        cs->exception_index = POWERPC_EXCP_PROGRAM;
         env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_OX;
     } else {
         env->fpscr |= 1 << FPSCR_XX;
@@ -242,6 +245,8 @@ static inline void float_overflow_excp(CPUPPCState *env)
 
 static inline void float_underflow_excp(CPUPPCState *env)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
+
     env->fpscr |= 1 << FPSCR_UX;
     /* Update the floating-point exception summary */
     env->fpscr |= 1 << FPSCR_FX;
@@ -250,13 +255,15 @@ static inline void float_underflow_excp(CPUPPCState *env)
         /* Update the floating-point enabled exception summary */
         env->fpscr |= 1 << FPSCR_FEX;
         /* We must update the target FPR before raising the exception */
-        env->exception_index = POWERPC_EXCP_PROGRAM;
+        cs->exception_index = POWERPC_EXCP_PROGRAM;
         env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_UX;
     }
 }
 
 static inline void float_inexact_excp(CPUPPCState *env)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
+
     env->fpscr |= 1 << FPSCR_XX;
     /* Update the floating-point exception summary */
     env->fpscr |= 1 << FPSCR_FX;
@@ -264,7 +271,7 @@ static inline void float_inexact_excp(CPUPPCState *env)
         /* Update the floating-point enabled exception summary */
         env->fpscr |= 1 << FPSCR_FEX;
         /* We must update the target FPR before raising the exception */
-        env->exception_index = POWERPC_EXCP_PROGRAM;
+        cs->exception_index = POWERPC_EXCP_PROGRAM;
         env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_XX;
     }
 }
@@ -316,6 +323,7 @@ void helper_fpscr_clrbit(CPUPPCState *env, uint32_t bit)
 
 void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     int prev;
 
     prev = (env->fpscr >> bit) & 1;
@@ -439,7 +447,7 @@ void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit)
             /* Update the floating-point enabled exception summary */
             env->fpscr |= 1 << FPSCR_FEX;
             /* We have to update Rc1 before raising the exception */
-            env->exception_index = POWERPC_EXCP_PROGRAM;
+            cs->exception_index = POWERPC_EXCP_PROGRAM;
             break;
         }
     }
@@ -447,6 +455,7 @@ void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit)
 
 void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     target_ulong prev, new;
     int i;
 
@@ -468,7 +477,7 @@ void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
     }
     if ((fpscr_ex & fpscr_eex) != 0) {
         env->fpscr |= 1 << FPSCR_FEX;
-        env->exception_index = POWERPC_EXCP_PROGRAM;
+        cs->exception_index = POWERPC_EXCP_PROGRAM;
         /* XXX: we should compute it properly */
         env->error_code = POWERPC_EXCP_FP;
     } else {
@@ -484,6 +493,7 @@ void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
 
 void helper_float_check_status(CPUPPCState *env)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     int status = get_float_exception_flags(&env->fp_status);
 
     if (status & float_flag_divbyzero) {
@@ -496,11 +506,11 @@ void helper_float_check_status(CPUPPCState *env)
         float_inexact_excp(env);
     }
 
-    if (env->exception_index == POWERPC_EXCP_PROGRAM &&
+    if (cs->exception_index == POWERPC_EXCP_PROGRAM &&
         (env->error_code & POWERPC_EXCP_FP)) {
         /* Differred floating-point exception after target FPR update */
         if (msr_fe0 != 0 || msr_fe1 != 0) {
-            helper_raise_exception_err(env, env->exception_index,
+            helper_raise_exception_err(env, cs->exception_index,
                                        env->error_code);
         }
     }
diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h
index c02e8da4e4..f7ec9c2b81 100644
--- a/target-ppc/helper_regs.h
+++ b/target-ppc/helper_regs.h
@@ -83,7 +83,7 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
     if (((value >> MSR_IR) & 1) != msr_ir ||
         ((value >> MSR_DR) & 1) != msr_dr) {
         /* Flush all tlb when changing translation mode */
-        tlb_flush(env, 1);
+        tlb_flush(cs, 1);
         excp = POWERPC_EXCP_NONE;
         cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
     }
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 63dde94b04..18b54f060a 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1075,7 +1075,7 @@ void helper_vbpermq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
 #undef VBPERMQ_INDEX
 #undef VBPERMQ_DW
 
-uint64_t VGBBD_MASKS[256] = {
+static const uint64_t VGBBD_MASKS[256] = {
     0x0000000000000000ull, /* 00 */
     0x0000000000000080ull, /* 01 */
     0x0000000000008000ull, /* 02 */
@@ -2216,7 +2216,7 @@ static int bcd_cmp_mag(ppc_avr_t *a, ppc_avr_t *b)
         uint8_t dig_a = bcd_get_digit(a, i, &invalid);
         uint8_t dig_b = bcd_get_digit(b, i, &invalid);
         if (unlikely(invalid)) {
-            return 0; /* doesnt matter */
+            return 0; /* doesn't matter */
         } else if (dig_a > dig_b) {
             return 1;
         } else if (dig_a < dig_b) {
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 32e7a8c0a7..9974b10ccb 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1178,7 +1178,7 @@ static int kvmppc_handle_halt(PowerPCCPU *cpu)
 
     if (!(cs->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) {
         cs->halted = 1;
-        env->exception_index = EXCP_HLT;
+        cs->exception_index = EXCP_HLT;
     }
 
     return 0;
@@ -1504,7 +1504,6 @@ int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len)
 
 void kvmppc_set_papr(PowerPCCPU *cpu)
 {
-    CPUPPCState *env = &cpu->env;
     CPUState *cs = CPU(cpu);
     struct kvm_enable_cap cap = {};
     int ret;
@@ -1513,7 +1512,7 @@ void kvmppc_set_papr(PowerPCCPU *cpu)
     ret = kvm_vcpu_ioctl(cs, KVM_ENABLE_CAP, &cap);
 
     if (ret) {
-        cpu_abort(env, "This KVM version does not support PAPR\n");
+        cpu_abort(cs, "This KVM version does not support PAPR\n");
     }
 
     /* Update the capability flag so we sync the right information
@@ -1523,7 +1522,6 @@ void kvmppc_set_papr(PowerPCCPU *cpu)
 
 void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy)
 {
-    CPUPPCState *env = &cpu->env;
     CPUState *cs = CPU(cpu);
     struct kvm_enable_cap cap = {};
     int ret;
@@ -1533,7 +1531,7 @@ void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy)
     ret = kvm_vcpu_ioctl(cs, KVM_ENABLE_CAP, &cap);
 
     if (ret && mpic_proxy) {
-        cpu_abort(env, "This KVM version does not support EPR\n");
+        cpu_abort(cs, "This KVM version does not support EPR\n");
     }
 }
 
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index 2d46ceccca..063b379d90 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -114,7 +114,7 @@ static void put_avr(QEMUFile *f, void *pv, size_t size)
     qemu_put_be64(f, v->u64[1]);
 }
 
-const VMStateInfo vmstate_info_avr = {
+static const VMStateInfo vmstate_info_avr = {
     .name = "avr",
     .get  = get_avr,
     .put  = put_avr,
@@ -288,7 +288,7 @@ static void put_slbe(QEMUFile *f, void *pv, size_t size)
     qemu_put_be64(f, v->vsid);
 }
 
-const VMStateInfo vmstate_info_slbe = {
+static const VMStateInfo vmstate_info_slbe = {
     .name = "slbe",
     .get  = get_slbe,
     .put  = put_slbe,
diff --git a/target-ppc/misc_helper.c b/target-ppc/misc_helper.c
index dc2ebfc452..2eb2fa6e20 100644
--- a/target-ppc/misc_helper.c
+++ b/target-ppc/misc_helper.c
@@ -62,10 +62,12 @@ void helper_store_hid0_601(CPUPPCState *env, target_ulong val)
 
 void helper_store_403_pbr(CPUPPCState *env, uint32_t num, target_ulong value)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
+
     if (likely(env->pb[num] != value)) {
         env->pb[num] = value;
         /* Should be optimized */
-        tlb_flush(env, 1);
+        tlb_flush(CPU(cpu), 1);
     }
 }
 
diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c
index 6a77dc4f97..1cc19162b7 100644
--- a/target-ppc/mmu-hash32.c
+++ b/target-ppc/mmu-hash32.c
@@ -222,6 +222,7 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
                                    target_ulong eaddr, int rwx,
                                    hwaddr *raddr, int *prot)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     int key = !!(msr_pr ? (sr & SR32_KP) : (sr & SR32_KS));
 
     LOG_MMU("direct store...\n");
@@ -238,7 +239,7 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
 
     if (rwx == 2) {
         /* No code fetch is allowed in direct-store areas */
-        env->exception_index = POWERPC_EXCP_ISI;
+        cs->exception_index = POWERPC_EXCP_ISI;
         env->error_code = 0x10000000;
         return 1;
     }
@@ -249,7 +250,7 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
         break;
     case ACCESS_FLOAT:
         /* Floating point load/store */
-        env->exception_index = POWERPC_EXCP_ALIGN;
+        cs->exception_index = POWERPC_EXCP_ALIGN;
         env->error_code = POWERPC_EXCP_ALIGN_FP;
         env->spr[SPR_DAR] = eaddr;
         return 1;
@@ -272,7 +273,7 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
         return 0;
     case ACCESS_EXT:
         /* eciwx or ecowx */
-        env->exception_index = POWERPC_EXCP_DSI;
+        cs->exception_index = POWERPC_EXCP_DSI;
         env->error_code = 0;
         env->spr[SPR_DAR] = eaddr;
         if (rwx == 1) {
@@ -290,7 +291,7 @@ static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
         *raddr = eaddr;
         return 0;
     } else {
-        env->exception_index = POWERPC_EXCP_DSI;
+        cs->exception_index = POWERPC_EXCP_DSI;
         env->error_code = 0;
         env->spr[SPR_DAR] = eaddr;
         if (rwx == 1) {
@@ -380,9 +381,11 @@ static hwaddr ppc_hash32_pte_raddr(target_ulong sr, ppc_hash_pte32_t pte,
     return (rpn & ~mask) | (eaddr & mask);
 }
 
-int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
+int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, target_ulong eaddr, int rwx,
                                 int mmu_idx)
 {
+    CPUState *cs = CPU(cpu);
+    CPUPPCState *env = &cpu->env;
     target_ulong sr;
     hwaddr pte_offset;
     ppc_hash_pte32_t pte;
@@ -397,7 +400,7 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
     if (((rwx == 2) && (msr_ir == 0)) || ((rwx != 2) && (msr_dr == 0))) {
         /* Translation is off */
         raddr = eaddr;
-        tlb_set_page(env, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
+        tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
                      PAGE_READ | PAGE_WRITE | PAGE_EXEC, mmu_idx,
                      TARGET_PAGE_SIZE);
         return 0;
@@ -409,10 +412,10 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
         if (raddr != -1) {
             if (need_prot[rwx] & ~prot) {
                 if (rwx == 2) {
-                    env->exception_index = POWERPC_EXCP_ISI;
+                    cs->exception_index = POWERPC_EXCP_ISI;
                     env->error_code = 0x08000000;
                 } else {
-                    env->exception_index = POWERPC_EXCP_DSI;
+                    cs->exception_index = POWERPC_EXCP_DSI;
                     env->error_code = 0;
                     env->spr[SPR_DAR] = eaddr;
                     if (rwx == 1) {
@@ -424,7 +427,7 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
                 return 1;
             }
 
-            tlb_set_page(env, eaddr & TARGET_PAGE_MASK,
+            tlb_set_page(cs, eaddr & TARGET_PAGE_MASK,
                          raddr & TARGET_PAGE_MASK, prot, mmu_idx,
                          TARGET_PAGE_SIZE);
             return 0;
@@ -438,7 +441,7 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
     if (sr & SR32_T) {
         if (ppc_hash32_direct_store(env, sr, eaddr, rwx,
                                     &raddr, &prot) == 0) {
-            tlb_set_page(env, eaddr & TARGET_PAGE_MASK,
+            tlb_set_page(cs, eaddr & TARGET_PAGE_MASK,
                          raddr & TARGET_PAGE_MASK, prot, mmu_idx,
                          TARGET_PAGE_SIZE);
             return 0;
@@ -449,7 +452,7 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
 
     /* 5. Check for segment level no-execute violation */
     if ((rwx == 2) && (sr & SR32_NX)) {
-        env->exception_index = POWERPC_EXCP_ISI;
+        cs->exception_index = POWERPC_EXCP_ISI;
         env->error_code = 0x10000000;
         return 1;
     }
@@ -458,10 +461,10 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
     pte_offset = ppc_hash32_htab_lookup(env, sr, eaddr, &pte);
     if (pte_offset == -1) {
         if (rwx == 2) {
-            env->exception_index = POWERPC_EXCP_ISI;
+            cs->exception_index = POWERPC_EXCP_ISI;
             env->error_code = 0x40000000;
         } else {
-            env->exception_index = POWERPC_EXCP_DSI;
+            cs->exception_index = POWERPC_EXCP_DSI;
             env->error_code = 0;
             env->spr[SPR_DAR] = eaddr;
             if (rwx == 1) {
@@ -483,10 +486,10 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
         /* Access right violation */
         LOG_MMU("PTE access rejected\n");
         if (rwx == 2) {
-            env->exception_index = POWERPC_EXCP_ISI;
+            cs->exception_index = POWERPC_EXCP_ISI;
             env->error_code = 0x08000000;
         } else {
-            env->exception_index = POWERPC_EXCP_DSI;
+            cs->exception_index = POWERPC_EXCP_DSI;
             env->error_code = 0;
             env->spr[SPR_DAR] = eaddr;
             if (rwx == 1) {
@@ -519,7 +522,7 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
 
     raddr = ppc_hash32_pte_raddr(sr, pte, eaddr);
 
-    tlb_set_page(env, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
+    tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
                  prot, mmu_idx, TARGET_PAGE_SIZE);
 
     return 0;
diff --git a/target-ppc/mmu-hash32.h b/target-ppc/mmu-hash32.h
index 4671141a32..d515d4ff73 100644
--- a/target-ppc/mmu-hash32.h
+++ b/target-ppc/mmu-hash32.h
@@ -5,7 +5,7 @@
 
 hwaddr get_pteg_offset32(CPUPPCState *env, hwaddr hash);
 hwaddr ppc_hash32_get_phys_page_debug(CPUPPCState *env, target_ulong addr);
-int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
+int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, target_ulong address, int rw,
                                 int mmu_idx);
 
 /*
@@ -68,7 +68,8 @@ int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
 static inline target_ulong ppc_hash32_load_hpte0(CPUPPCState *env,
                                                  hwaddr pte_offset)
 {
-    CPUState *cs = ENV_GET_CPU(env);
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
+
     assert(!env->external_htab); /* Not supported on 32-bit for now */
     return ldl_phys(cs->as, env->htab_base + pte_offset);
 }
@@ -76,7 +77,8 @@ static inline target_ulong ppc_hash32_load_hpte0(CPUPPCState *env,
 static inline target_ulong ppc_hash32_load_hpte1(CPUPPCState *env,
                                                  hwaddr pte_offset)
 {
-    CPUState *cs = ENV_GET_CPU(env);
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
+
     assert(!env->external_htab); /* Not supported on 32-bit for now */
     return ldl_phys(cs->as, env->htab_base + pte_offset + HASH_PTE_SIZE_32/2);
 }
@@ -84,7 +86,8 @@ static inline target_ulong ppc_hash32_load_hpte1(CPUPPCState *env,
 static inline void ppc_hash32_store_hpte0(CPUPPCState *env,
                                           hwaddr pte_offset, target_ulong pte0)
 {
-    CPUState *cs = ENV_GET_CPU(env);
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
+
     assert(!env->external_htab); /* Not supported on 32-bit for now */
     stl_phys(cs->as, env->htab_base + pte_offset, pte0);
 }
@@ -92,7 +95,8 @@ static inline void ppc_hash32_store_hpte0(CPUPPCState *env,
 static inline void ppc_hash32_store_hpte1(CPUPPCState *env,
                                           hwaddr pte_offset, target_ulong pte1)
 {
-    CPUState *cs = ENV_GET_CPU(env);
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
+
     assert(!env->external_htab); /* Not supported on 32-bit for now */
     stl_phys(cs->as, env->htab_base + pte_offset + HASH_PTE_SIZE_32/2, pte1);
 }
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index f2af4fbaa7..1fefe5881e 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -99,6 +99,7 @@ void dump_slb(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
 
 void helper_slbia(CPUPPCState *env)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
     int n, do_invalidate;
 
     do_invalidate = 0;
@@ -116,12 +117,13 @@ void helper_slbia(CPUPPCState *env)
         }
     }
     if (do_invalidate) {
-        tlb_flush(env, 1);
+        tlb_flush(CPU(cpu), 1);
     }
 }
 
 void helper_slbie(CPUPPCState *env, target_ulong addr)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
     ppc_slb_t *slb;
 
     slb = slb_lookup(env, addr);
@@ -136,7 +138,7 @@ void helper_slbie(CPUPPCState *env, target_ulong addr)
          *      and we still don't have a tlb_flush_mask(env, n, mask)
          *      in QEMU, we just invalidate all TLBs
          */
-        tlb_flush(env, 1);
+        tlb_flush(CPU(cpu), 1);
     }
 }
 
@@ -454,9 +456,11 @@ static hwaddr ppc_hash64_pte_raddr(ppc_slb_t *slb, ppc_hash_pte64_t pte,
     return (rpn & ~mask) | (eaddr & mask);
 }
 
-int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
+int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, target_ulong eaddr,
                                 int rwx, int mmu_idx)
 {
+    CPUState *cs = CPU(cpu);
+    CPUPPCState *env = &cpu->env;
     ppc_slb_t *slb;
     hwaddr pte_offset;
     ppc_hash_pte64_t pte;
@@ -472,7 +476,7 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
         /* Translation is off */
         /* In real mode the top 4 effective address bits are ignored */
         raddr = eaddr & 0x0FFFFFFFFFFFFFFFULL;
-        tlb_set_page(env, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
+        tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
                      PAGE_READ | PAGE_WRITE | PAGE_EXEC, mmu_idx,
                      TARGET_PAGE_SIZE);
         return 0;
@@ -483,10 +487,10 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
 
     if (!slb) {
         if (rwx == 2) {
-            env->exception_index = POWERPC_EXCP_ISEG;
+            cs->exception_index = POWERPC_EXCP_ISEG;
             env->error_code = 0;
         } else {
-            env->exception_index = POWERPC_EXCP_DSEG;
+            cs->exception_index = POWERPC_EXCP_DSEG;
             env->error_code = 0;
             env->spr[SPR_DAR] = eaddr;
         }
@@ -495,7 +499,7 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
 
     /* 3. Check for segment level no-execute violation */
     if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) {
-        env->exception_index = POWERPC_EXCP_ISI;
+        cs->exception_index = POWERPC_EXCP_ISI;
         env->error_code = 0x10000000;
         return 1;
     }
@@ -504,10 +508,10 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
     pte_offset = ppc_hash64_htab_lookup(env, slb, eaddr, &pte);
     if (pte_offset == -1) {
         if (rwx == 2) {
-            env->exception_index = POWERPC_EXCP_ISI;
+            cs->exception_index = POWERPC_EXCP_ISI;
             env->error_code = 0x40000000;
         } else {
-            env->exception_index = POWERPC_EXCP_DSI;
+            cs->exception_index = POWERPC_EXCP_DSI;
             env->error_code = 0;
             env->spr[SPR_DAR] = eaddr;
             if (rwx == 1) {
@@ -530,12 +534,12 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
         /* Access right violation */
         LOG_MMU("PTE access rejected\n");
         if (rwx == 2) {
-            env->exception_index = POWERPC_EXCP_ISI;
+            cs->exception_index = POWERPC_EXCP_ISI;
             env->error_code = 0x08000000;
         } else {
             target_ulong dsisr = 0;
 
-            env->exception_index = POWERPC_EXCP_DSI;
+            cs->exception_index = POWERPC_EXCP_DSI;
             env->error_code = 0;
             env->spr[SPR_DAR] = eaddr;
             if (need_prot[rwx] & ~pp_prot) {
@@ -574,7 +578,7 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
 
     raddr = ppc_hash64_pte_raddr(slb, pte, eaddr);
 
-    tlb_set_page(env, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
+    tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
                  prot, mmu_idx, TARGET_PAGE_SIZE);
 
     return 0;
@@ -608,7 +612,7 @@ void ppc_hash64_store_hpte(CPUPPCState *env,
                            target_ulong pte_index,
                            target_ulong pte0, target_ulong pte1)
 {
-    CPUState *cs = ENV_GET_CPU(env);
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
 
     if (kvmppc_kern_htab) {
         return kvmppc_hash64_write_pte(env, pte_index, pte0, pte1);
diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
index 1746b3e2d3..49e385db90 100644
--- a/target-ppc/mmu-hash64.h
+++ b/target-ppc/mmu-hash64.h
@@ -7,7 +7,7 @@
 void dump_slb(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
 int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs);
 hwaddr ppc_hash64_get_phys_page_debug(CPUPPCState *env, target_ulong addr);
-int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
+int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, target_ulong address, int rw,
                                 int mmu_idx);
 void ppc_hash64_store_hpte(CPUPPCState *env, target_ulong index,
                            target_ulong pte0, target_ulong pte1);
@@ -85,8 +85,9 @@ void ppc_hash64_stop_access(uint64_t token);
 static inline target_ulong ppc_hash64_load_hpte0(CPUPPCState *env,
                                                  uint64_t token, int index)
 {
-    CPUState *cs = ENV_GET_CPU(env);
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     uint64_t addr;
+
     addr = token + (index * HASH_PTE_SIZE_64);
     if (env->external_htab) {
         return  ldq_p((const void *)(uintptr_t)addr);
@@ -98,8 +99,9 @@ static inline target_ulong ppc_hash64_load_hpte0(CPUPPCState *env,
 static inline target_ulong ppc_hash64_load_hpte1(CPUPPCState *env,
                                                  uint64_t token, int index)
 {
-    CPUState *cs = ENV_GET_CPU(env);
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     uint64_t addr;
+
     addr = token + (index * HASH_PTE_SIZE_64) + HASH_PTE_SIZE_64/2;
     if (env->external_htab) {
         return  ldq_p((const void *)(uintptr_t)addr);
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 8e2f8e736a..1771863dff 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -231,6 +231,7 @@ static inline int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
 
 static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
     ppc6xx_tlb_t *tlb;
     int nr, max;
 
@@ -244,7 +245,7 @@ static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env)
         tlb = &env->tlb.tlb6[nr];
         pte_invalidate(&tlb->pte0);
     }
-    tlb_flush(env, 1);
+    tlb_flush(CPU(cpu), 1);
 }
 
 static inline void ppc6xx_tlb_invalidate_virt2(CPUPPCState *env,
@@ -252,6 +253,7 @@ static inline void ppc6xx_tlb_invalidate_virt2(CPUPPCState *env,
                                                int is_code, int match_epn)
 {
 #if !defined(FLUSH_ALL_TLBS)
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     ppc6xx_tlb_t *tlb;
     int way, nr;
 
@@ -263,7 +265,7 @@ static inline void ppc6xx_tlb_invalidate_virt2(CPUPPCState *env,
             LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx "\n", nr,
                       env->nb_tlb, eaddr);
             pte_invalidate(&tlb->pte0);
-            tlb_flush_page(env, tlb->EPN);
+            tlb_flush_page(cs, tlb->EPN);
         }
     }
 #else
@@ -643,6 +645,7 @@ static int ppcemb_tlb_search(CPUPPCState *env, target_ulong address,
 /* Helpers specific to PowerPC 40x implementations */
 static inline void ppc4xx_tlb_invalidate_all(CPUPPCState *env)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
     ppcemb_tlb_t *tlb;
     int i;
 
@@ -650,13 +653,14 @@ static inline void ppc4xx_tlb_invalidate_all(CPUPPCState *env)
         tlb = &env->tlb.tlbe[i];
         tlb->prot &= ~PAGE_VALID;
     }
-    tlb_flush(env, 1);
+    tlb_flush(CPU(cpu), 1);
 }
 
 static inline void ppc4xx_tlb_invalidate_virt(CPUPPCState *env,
                                               target_ulong eaddr, uint32_t pid)
 {
 #if !defined(FLUSH_ALL_TLBS)
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     ppcemb_tlb_t *tlb;
     hwaddr raddr;
     target_ulong page, end;
@@ -667,7 +671,7 @@ static inline void ppc4xx_tlb_invalidate_virt(CPUPPCState *env,
         if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {
             end = tlb->EPN + tlb->size;
             for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) {
-                tlb_flush_page(env, page);
+                tlb_flush_page(cs, page);
             }
             tlb->prot &= ~PAGE_VALID;
             break;
@@ -746,9 +750,11 @@ static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
 
 void store_40x_sler(CPUPPCState *env, uint32_t val)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
+
     /* XXX: TO BE FIXED */
     if (val != 0x00000000) {
-        cpu_abort(env, "Little-endian regions are not supported by now\n");
+        cpu_abort(CPU(cpu), "Little-endian regions are not supported by now\n");
     }
     env->spr[SPR_405_SLER] = val;
 }
@@ -858,6 +864,7 @@ static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
 static void booke206_flush_tlb(CPUPPCState *env, int flags,
                                const int check_iprot)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
     int tlb_size;
     int i, j;
     ppcmas_tlb_t *tlb = env->tlb.tlbm;
@@ -874,7 +881,7 @@ static void booke206_flush_tlb(CPUPPCState *env, int flags,
         tlb += booke206_tlb_size(env, i);
     }
 
-    tlb_flush(env, 1);
+    tlb_flush(CPU(cpu), 1);
 }
 
 static hwaddr booke206_tlb_to_page_size(CPUPPCState *env,
@@ -1344,6 +1351,7 @@ static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx,
 static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
                                 target_ulong eaddr, int rw, int access_type)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
     int ret = -1;
     bool real_mode = (access_type == ACCESS_CODE && msr_ir == 0)
         || (access_type != ACCESS_CODE && msr_dr == 0);
@@ -1388,17 +1396,17 @@ static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
         break;
     case POWERPC_MMU_MPC8xx:
         /* XXX: TODO */
-        cpu_abort(env, "MPC8xx MMU model is not implemented\n");
+        cpu_abort(CPU(cpu), "MPC8xx MMU model is not implemented\n");
         break;
     case POWERPC_MMU_REAL:
         if (real_mode) {
             ret = check_physical(env, ctx, eaddr, rw);
         } else {
-            cpu_abort(env, "PowerPC in real mode do not do any translation\n");
+            cpu_abort(CPU(cpu), "PowerPC in real mode do not do any translation\n");
         }
         return -1;
     default:
-        cpu_abort(env, "Unknown or invalid MMU model\n");
+        cpu_abort(CPU(cpu), "Unknown or invalid MMU model\n");
         return -1;
     }
 #if 0
@@ -1491,6 +1499,7 @@ static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
 static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                                     int rw, int mmu_idx)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     mmu_ctx_t ctx;
     int access_type;
     int ret = 0;
@@ -1505,29 +1514,29 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
     }
     ret = get_physical_address(env, &ctx, address, rw, access_type);
     if (ret == 0) {
-        tlb_set_page(env, address & TARGET_PAGE_MASK,
+        tlb_set_page(cs, address & TARGET_PAGE_MASK,
                      ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
                      mmu_idx, TARGET_PAGE_SIZE);
         ret = 0;
     } else if (ret < 0) {
-        LOG_MMU_STATE(CPU(ppc_env_get_cpu(env)));
+        LOG_MMU_STATE(cs);
         if (access_type == ACCESS_CODE) {
             switch (ret) {
             case -1:
                 /* No matches in page tables or TLB */
                 switch (env->mmu_model) {
                 case POWERPC_MMU_SOFT_6xx:
-                    env->exception_index = POWERPC_EXCP_IFTLB;
+                    cs->exception_index = POWERPC_EXCP_IFTLB;
                     env->error_code = 1 << 18;
                     env->spr[SPR_IMISS] = address;
                     env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
                     goto tlb_miss;
                 case POWERPC_MMU_SOFT_74xx:
-                    env->exception_index = POWERPC_EXCP_IFTLB;
+                    cs->exception_index = POWERPC_EXCP_IFTLB;
                     goto tlb_miss_74xx;
                 case POWERPC_MMU_SOFT_4xx:
                 case POWERPC_MMU_SOFT_4xx_Z:
-                    env->exception_index = POWERPC_EXCP_ITLB;
+                    cs->exception_index = POWERPC_EXCP_ITLB;
                     env->error_code = 0;
                     env->spr[SPR_40x_DEAR] = address;
                     env->spr[SPR_40x_ESR] = 0x00000000;
@@ -1536,26 +1545,26 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                     booke206_update_mas_tlb_miss(env, address, rw);
                     /* fall through */
                 case POWERPC_MMU_BOOKE:
-                    env->exception_index = POWERPC_EXCP_ITLB;
+                    cs->exception_index = POWERPC_EXCP_ITLB;
                     env->error_code = 0;
                     env->spr[SPR_BOOKE_DEAR] = address;
                     return -1;
                 case POWERPC_MMU_MPC8xx:
                     /* XXX: TODO */
-                    cpu_abort(env, "MPC8xx MMU model is not implemented\n");
+                    cpu_abort(cs, "MPC8xx MMU model is not implemented\n");
                     break;
                 case POWERPC_MMU_REAL:
-                    cpu_abort(env, "PowerPC in real mode should never raise "
+                    cpu_abort(cs, "PowerPC in real mode should never raise "
                               "any MMU exceptions\n");
                     return -1;
                 default:
-                    cpu_abort(env, "Unknown or invalid MMU model\n");
+                    cpu_abort(cs, "Unknown or invalid MMU model\n");
                     return -1;
                 }
                 break;
             case -2:
                 /* Access rights violation */
-                env->exception_index = POWERPC_EXCP_ISI;
+                cs->exception_index = POWERPC_EXCP_ISI;
                 env->error_code = 0x08000000;
                 break;
             case -3:
@@ -1564,13 +1573,13 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                     (env->mmu_model == POWERPC_MMU_BOOKE206)) {
                     env->spr[SPR_BOOKE_ESR] = 0x00000000;
                 }
-                env->exception_index = POWERPC_EXCP_ISI;
+                cs->exception_index = POWERPC_EXCP_ISI;
                 env->error_code = 0x10000000;
                 break;
             case -4:
                 /* Direct store exception */
                 /* No code fetch is allowed in direct-store areas */
-                env->exception_index = POWERPC_EXCP_ISI;
+                cs->exception_index = POWERPC_EXCP_ISI;
                 env->error_code = 0x10000000;
                 break;
             }
@@ -1581,10 +1590,10 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                 switch (env->mmu_model) {
                 case POWERPC_MMU_SOFT_6xx:
                     if (rw == 1) {
-                        env->exception_index = POWERPC_EXCP_DSTLB;
+                        cs->exception_index = POWERPC_EXCP_DSTLB;
                         env->error_code = 1 << 16;
                     } else {
-                        env->exception_index = POWERPC_EXCP_DLTLB;
+                        cs->exception_index = POWERPC_EXCP_DLTLB;
                         env->error_code = 0;
                     }
                     env->spr[SPR_DMISS] = address;
@@ -1598,9 +1607,9 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                     break;
                 case POWERPC_MMU_SOFT_74xx:
                     if (rw == 1) {
-                        env->exception_index = POWERPC_EXCP_DSTLB;
+                        cs->exception_index = POWERPC_EXCP_DSTLB;
                     } else {
-                        env->exception_index = POWERPC_EXCP_DLTLB;
+                        cs->exception_index = POWERPC_EXCP_DLTLB;
                     }
                 tlb_miss_74xx:
                     /* Implement LRU algorithm */
@@ -1611,7 +1620,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                     break;
                 case POWERPC_MMU_SOFT_4xx:
                 case POWERPC_MMU_SOFT_4xx_Z:
-                    env->exception_index = POWERPC_EXCP_DTLB;
+                    cs->exception_index = POWERPC_EXCP_DTLB;
                     env->error_code = 0;
                     env->spr[SPR_40x_DEAR] = address;
                     if (rw) {
@@ -1622,29 +1631,29 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                     break;
                 case POWERPC_MMU_MPC8xx:
                     /* XXX: TODO */
-                    cpu_abort(env, "MPC8xx MMU model is not implemented\n");
+                    cpu_abort(cs, "MPC8xx MMU model is not implemented\n");
                     break;
                 case POWERPC_MMU_BOOKE206:
                     booke206_update_mas_tlb_miss(env, address, rw);
                     /* fall through */
                 case POWERPC_MMU_BOOKE:
-                    env->exception_index = POWERPC_EXCP_DTLB;
+                    cs->exception_index = POWERPC_EXCP_DTLB;
                     env->error_code = 0;
                     env->spr[SPR_BOOKE_DEAR] = address;
                     env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0;
                     return -1;
                 case POWERPC_MMU_REAL:
-                    cpu_abort(env, "PowerPC in real mode should never raise "
+                    cpu_abort(cs, "PowerPC in real mode should never raise "
                               "any MMU exceptions\n");
                     return -1;
                 default:
-                    cpu_abort(env, "Unknown or invalid MMU model\n");
+                    cpu_abort(cs, "Unknown or invalid MMU model\n");
                     return -1;
                 }
                 break;
             case -2:
                 /* Access rights violation */
-                env->exception_index = POWERPC_EXCP_DSI;
+                cs->exception_index = POWERPC_EXCP_DSI;
                 env->error_code = 0;
                 if (env->mmu_model == POWERPC_MMU_SOFT_4xx
                     || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) {
@@ -1670,13 +1679,13 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                 switch (access_type) {
                 case ACCESS_FLOAT:
                     /* Floating point load/store */
-                    env->exception_index = POWERPC_EXCP_ALIGN;
+                    cs->exception_index = POWERPC_EXCP_ALIGN;
                     env->error_code = POWERPC_EXCP_ALIGN_FP;
                     env->spr[SPR_DAR] = address;
                     break;
                 case ACCESS_RES:
                     /* lwarx, ldarx or stwcx. */
-                    env->exception_index = POWERPC_EXCP_DSI;
+                    cs->exception_index = POWERPC_EXCP_DSI;
                     env->error_code = 0;
                     env->spr[SPR_DAR] = address;
                     if (rw == 1) {
@@ -1687,7 +1696,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                     break;
                 case ACCESS_EXT:
                     /* eciwx or ecowx */
-                    env->exception_index = POWERPC_EXCP_DSI;
+                    cs->exception_index = POWERPC_EXCP_DSI;
                     env->error_code = 0;
                     env->spr[SPR_DAR] = address;
                     if (rw == 1) {
@@ -1698,7 +1707,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                     break;
                 default:
                     printf("DSI: invalid exception (%d)\n", ret);
-                    env->exception_index = POWERPC_EXCP_PROGRAM;
+                    cs->exception_index = POWERPC_EXCP_PROGRAM;
                     env->error_code =
                         POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
                     env->spr[SPR_DAR] = address;
@@ -1709,7 +1718,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
         }
 #if 0
         printf("%s: set exception to %d %02x\n", __func__,
-               env->exception, env->error_code);
+               cs->exception, env->error_code);
 #endif
         ret = 1;
     }
@@ -1723,6 +1732,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
 static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu,
                                      target_ulong mask)
 {
+    CPUState *cs = CPU(ppc_env_get_cpu(env));
     target_ulong base, end, page;
 
     base = BATu & ~0x0001FFFF;
@@ -1730,7 +1740,7 @@ static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu,
     LOG_BATS("Flush BAT from " TARGET_FMT_lx " to " TARGET_FMT_lx " ("
              TARGET_FMT_lx ")\n", base, end, mask);
     for (page = base; page != end; page += TARGET_PAGE_SIZE) {
-        tlb_flush_page(env, page);
+        tlb_flush_page(cs, page);
     }
     LOG_BATS("Flush done\n");
 }
@@ -1892,6 +1902,8 @@ void helper_store_601_batl(CPUPPCState *env, uint32_t nr, target_ulong value)
 /* TLB management */
 void ppc_tlb_invalidate_all(CPUPPCState *env)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
+
     switch (env->mmu_model) {
     case POWERPC_MMU_SOFT_6xx:
     case POWERPC_MMU_SOFT_74xx:
@@ -1902,14 +1914,14 @@ void ppc_tlb_invalidate_all(CPUPPCState *env)
         ppc4xx_tlb_invalidate_all(env);
         break;
     case POWERPC_MMU_REAL:
-        cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
+        cpu_abort(CPU(cpu), "No TLB for PowerPC 4xx in real mode\n");
         break;
     case POWERPC_MMU_MPC8xx:
         /* XXX: TODO */
-        cpu_abort(env, "MPC8xx MMU model is not implemented\n");
+        cpu_abort(CPU(cpu), "MPC8xx MMU model is not implemented\n");
         break;
     case POWERPC_MMU_BOOKE:
-        tlb_flush(env, 1);
+        tlb_flush(CPU(cpu), 1);
         break;
     case POWERPC_MMU_BOOKE206:
         booke206_flush_tlb(env, -1, 0);
@@ -1922,11 +1934,11 @@ void ppc_tlb_invalidate_all(CPUPPCState *env)
     case POWERPC_MMU_2_06a:
     case POWERPC_MMU_2_06d:
 #endif /* defined(TARGET_PPC64) */
-        tlb_flush(env, 1);
+        tlb_flush(CPU(cpu), 1);
         break;
     default:
         /* XXX: TODO */
-        cpu_abort(env, "Unknown MMU model\n");
+        cpu_abort(CPU(cpu), "Unknown MMU model\n");
         break;
     }
 }
@@ -1934,6 +1946,9 @@ void ppc_tlb_invalidate_all(CPUPPCState *env)
 void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
 {
 #if !defined(FLUSH_ALL_TLBS)
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
+    CPUState *cs;
+
     addr &= TARGET_PAGE_MASK;
     switch (env->mmu_model) {
     case POWERPC_MMU_SOFT_6xx:
@@ -1948,43 +1963,44 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
         ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]);
         break;
     case POWERPC_MMU_REAL:
-        cpu_abort(env, "No TLB for PowerPC 4xx in real mode\n");
+        cpu_abort(CPU(cpu), "No TLB for PowerPC 4xx in real mode\n");
         break;
     case POWERPC_MMU_MPC8xx:
         /* XXX: TODO */
-        cpu_abort(env, "MPC8xx MMU model is not implemented\n");
+        cpu_abort(CPU(cpu), "MPC8xx MMU model is not implemented\n");
         break;
     case POWERPC_MMU_BOOKE:
         /* XXX: TODO */
-        cpu_abort(env, "BookE MMU model is not implemented\n");
+        cpu_abort(CPU(cpu), "BookE MMU model is not implemented\n");
         break;
     case POWERPC_MMU_BOOKE206:
         /* XXX: TODO */
-        cpu_abort(env, "BookE 2.06 MMU model is not implemented\n");
+        cpu_abort(CPU(cpu), "BookE 2.06 MMU model is not implemented\n");
         break;
     case POWERPC_MMU_32B:
     case POWERPC_MMU_601:
         /* tlbie invalidate TLBs for all segments */
         addr &= ~((target_ulong)-1ULL << 28);
+        cs = CPU(cpu);
         /* XXX: this case should be optimized,
          * giving a mask to tlb_flush_page
          */
-        tlb_flush_page(env, addr | (0x0 << 28));
-        tlb_flush_page(env, addr | (0x1 << 28));
-        tlb_flush_page(env, addr | (0x2 << 28));
-        tlb_flush_page(env, addr | (0x3 << 28));
-        tlb_flush_page(env, addr | (0x4 << 28));
-        tlb_flush_page(env, addr | (0x5 << 28));
-        tlb_flush_page(env, addr | (0x6 << 28));
-        tlb_flush_page(env, addr | (0x7 << 28));
-        tlb_flush_page(env, addr | (0x8 << 28));
-        tlb_flush_page(env, addr | (0x9 << 28));
-        tlb_flush_page(env, addr | (0xA << 28));
-        tlb_flush_page(env, addr | (0xB << 28));
-        tlb_flush_page(env, addr | (0xC << 28));
-        tlb_flush_page(env, addr | (0xD << 28));
-        tlb_flush_page(env, addr | (0xE << 28));
-        tlb_flush_page(env, addr | (0xF << 28));
+        tlb_flush_page(cs, addr | (0x0 << 28));
+        tlb_flush_page(cs, addr | (0x1 << 28));
+        tlb_flush_page(cs, addr | (0x2 << 28));
+        tlb_flush_page(cs, addr | (0x3 << 28));
+        tlb_flush_page(cs, addr | (0x4 << 28));
+        tlb_flush_page(cs, addr | (0x5 << 28));
+        tlb_flush_page(cs, addr | (0x6 << 28));
+        tlb_flush_page(cs, addr | (0x7 << 28));
+        tlb_flush_page(cs, addr | (0x8 << 28));
+        tlb_flush_page(cs, addr | (0x9 << 28));
+        tlb_flush_page(cs, addr | (0xA << 28));
+        tlb_flush_page(cs, addr | (0xB << 28));
+        tlb_flush_page(cs, addr | (0xC << 28));
+        tlb_flush_page(cs, addr | (0xD << 28));
+        tlb_flush_page(cs, addr | (0xE << 28));
+        tlb_flush_page(cs, addr | (0xF << 28));
         break;
 #if defined(TARGET_PPC64)
     case POWERPC_MMU_64B:
@@ -1996,12 +2012,12 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
          *      and we still don't have a tlb_flush_mask(env, n, mask) in QEMU,
          *      we just invalidate all TLBs
          */
-        tlb_flush(env, 1);
+        tlb_flush(CPU(cpu), 1);
         break;
 #endif /* defined(TARGET_PPC64) */
     default:
         /* XXX: TODO */
-        cpu_abort(env, "Unknown MMU model\n");
+        cpu_abort(CPU(cpu), "Unknown MMU model\n");
         break;
     }
 #else
@@ -2013,6 +2029,8 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
 /* Special registers manipulation */
 void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
+
     LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value);
     assert(!env->external_htab);
     if (env->spr[SPR_SDR1] != value) {
@@ -2035,7 +2053,7 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
             env->htab_mask = ((value & SDR_32_HTABMASK) << 16) | 0xFFFF;
             env->htab_base = value & SDR_32_HTABORG;
         }
-        tlb_flush(env, 1);
+        tlb_flush(CPU(cpu), 1);
     }
 }
 
@@ -2053,6 +2071,8 @@ target_ulong helper_load_sr(CPUPPCState *env, target_ulong sr_num)
 
 void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
+
     LOG_MMU("%s: reg=%d " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__,
             (int)srnum, value, env->sr[srnum]);
 #if defined(TARGET_PPC64)
@@ -2085,11 +2105,11 @@ void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value)
             page = (16 << 20) * srnum;
             end = page + (16 << 20);
             for (; page != end; page += TARGET_PAGE_SIZE) {
-                tlb_flush_page(env, page);
+                tlb_flush_page(CPU(cpu), page);
             }
         }
 #else
-        tlb_flush(env, 1);
+        tlb_flush(CPU(cpu), 1);
 #endif
     }
 }
@@ -2316,6 +2336,8 @@ target_ulong helper_4xx_tlbre_lo(CPUPPCState *env, target_ulong entry)
 void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry,
                          target_ulong val)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
     ppcemb_tlb_t *tlb;
     target_ulong page, end;
 
@@ -2329,7 +2351,7 @@ void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry,
         LOG_SWTLB("%s: invalidate old TLB %d start " TARGET_FMT_lx " end "
                   TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end);
         for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) {
-            tlb_flush_page(env, page);
+            tlb_flush_page(cs, page);
         }
     }
     tlb->size = booke_tlb_to_page_size((val >> PPC4XX_TLBHI_SIZE_SHIFT)
@@ -2339,7 +2361,7 @@ void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry,
      * of the ppc or ppc64 one
      */
     if ((val & PPC4XX_TLBHI_V) && tlb->size < TARGET_PAGE_SIZE) {
-        cpu_abort(env, "TLB size " TARGET_FMT_lu " < %u "
+        cpu_abort(cs, "TLB size " TARGET_FMT_lu " < %u "
                   "are not supported (%d)\n",
                   tlb->size, TARGET_PAGE_SIZE, (int)((val >> 7) & 0x7));
     }
@@ -2348,7 +2370,7 @@ void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry,
         tlb->prot |= PAGE_VALID;
         if (val & PPC4XX_TLBHI_E) {
             /* XXX: TO BE FIXED */
-            cpu_abort(env,
+            cpu_abort(cs,
                       "Little-endian TLB entries are not supported by now\n");
         }
     } else {
@@ -2368,7 +2390,7 @@ void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry,
         LOG_SWTLB("%s: invalidate TLB %d start " TARGET_FMT_lx " end "
                   TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end);
         for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) {
-            tlb_flush_page(env, page);
+            tlb_flush_page(cs, page);
         }
     }
 }
@@ -2409,6 +2431,7 @@ target_ulong helper_4xx_tlbsx(CPUPPCState *env, target_ulong address)
 void helper_440_tlbwe(CPUPPCState *env, uint32_t word, target_ulong entry,
                       target_ulong value)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
     ppcemb_tlb_t *tlb;
     target_ulong EPN, RPN, size;
     int do_flush_tlbs;
@@ -2444,13 +2467,13 @@ void helper_440_tlbwe(CPUPPCState *env, uint32_t word, target_ulong entry,
         }
         tlb->PID = env->spr[SPR_440_MMUCR] & 0x000000FF;
         if (do_flush_tlbs) {
-            tlb_flush(env, 1);
+            tlb_flush(CPU(cpu), 1);
         }
         break;
     case 1:
         RPN = value & 0xFFFFFC0F;
         if ((tlb->prot & PAGE_VALID) && tlb->RPN != RPN) {
-            tlb_flush(env, 1);
+            tlb_flush(CPU(cpu), 1);
         }
         tlb->RPN = RPN;
         break;
@@ -2544,6 +2567,7 @@ target_ulong helper_440_tlbsx(CPUPPCState *env, target_ulong address)
 
 static ppcmas_tlb_t *booke206_cur_tlb(CPUPPCState *env)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
     uint32_t tlbncfg = 0;
     int esel = (env->spr[SPR_BOOKE_MAS0] & MAS0_ESEL_MASK) >> MAS0_ESEL_SHIFT;
     int ea = (env->spr[SPR_BOOKE_MAS2] & MAS2_EPN_MASK);
@@ -2553,7 +2577,7 @@ static ppcmas_tlb_t *booke206_cur_tlb(CPUPPCState *env)
     tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlb];
 
     if ((tlbncfg & TLBnCFG_HES) && (env->spr[SPR_BOOKE_MAS0] & MAS0_HES)) {
-        cpu_abort(env, "we don't support HES yet\n");
+        cpu_abort(CPU(cpu), "we don't support HES yet\n");
     }
 
     return booke206_get_tlbm(env, tlb, ea, esel);
@@ -2561,13 +2585,16 @@ static ppcmas_tlb_t *booke206_cur_tlb(CPUPPCState *env)
 
 void helper_booke_setpid(CPUPPCState *env, uint32_t pidn, target_ulong pid)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
+
     env->spr[pidn] = pid;
     /* changing PIDs mean we're in a different address space now */
-    tlb_flush(env, 1);
+    tlb_flush(CPU(cpu), 1);
 }
 
 void helper_booke206_tlbwe(CPUPPCState *env)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
     uint32_t tlbncfg, tlbn;
     ppcmas_tlb_t *tlb;
     uint32_t size_tlb, size_ps;
@@ -2621,7 +2648,7 @@ void helper_booke206_tlbwe(CPUPPCState *env)
     }
 
     if (msr_gs) {
-        cpu_abort(env, "missing HV implementation\n");
+        cpu_abort(CPU(cpu), "missing HV implementation\n");
     }
     tlb->mas7_3 = ((uint64_t)env->spr[SPR_BOOKE_MAS7] << 32) |
         env->spr[SPR_BOOKE_MAS3];
@@ -2655,9 +2682,9 @@ void helper_booke206_tlbwe(CPUPPCState *env)
     }
 
     if (booke206_tlb_to_page_size(env, tlb) == TARGET_PAGE_SIZE) {
-        tlb_flush_page(env, tlb->mas2 & MAS2_EPN_MASK);
+        tlb_flush_page(CPU(cpu), tlb->mas2 & MAS2_EPN_MASK);
     } else {
-        tlb_flush(env, 1);
+        tlb_flush(CPU(cpu), 1);
     }
 }
 
@@ -2764,6 +2791,8 @@ static inline void booke206_invalidate_ea_tlb(CPUPPCState *env, int tlbn,
 
 void helper_booke206_tlbivax(CPUPPCState *env, target_ulong address)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
+
     if (address & 0x4) {
         /* flush all entries */
         if (address & 0x8) {
@@ -2779,11 +2808,11 @@ void helper_booke206_tlbivax(CPUPPCState *env, target_ulong address)
     if (address & 0x8) {
         /* flush TLB1 entries */
         booke206_invalidate_ea_tlb(env, 1, address);
-        tlb_flush(env, 1);
+        tlb_flush(CPU(cpu), 1);
     } else {
         /* flush TLB0 entries */
         booke206_invalidate_ea_tlb(env, 0, address);
-        tlb_flush_page(env, address & MAS2_EPN_MASK);
+        tlb_flush_page(CPU(cpu), address & MAS2_EPN_MASK);
     }
 }
 
@@ -2795,6 +2824,7 @@ void helper_booke206_tlbilx0(CPUPPCState *env, target_ulong address)
 
 void helper_booke206_tlbilx1(CPUPPCState *env, target_ulong address)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
     int i, j;
     int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID);
     ppcmas_tlb_t *tlb = env->tlb.tlbm;
@@ -2811,11 +2841,12 @@ void helper_booke206_tlbilx1(CPUPPCState *env, target_ulong address)
         }
         tlb += booke206_tlb_size(env, i);
     }
-    tlb_flush(env, 1);
+    tlb_flush(CPU(cpu), 1);
 }
 
 void helper_booke206_tlbilx3(CPUPPCState *env, target_ulong address)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
     int i, j;
     ppcmas_tlb_t *tlb;
     int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID);
@@ -2851,7 +2882,7 @@ void helper_booke206_tlbilx3(CPUPPCState *env, target_ulong address)
             tlb->mas1 &= ~MAS1_VALID;
         }
     }
-    tlb_flush(env, 1);
+    tlb_flush(CPU(cpu), 1);
 }
 
 void helper_booke206_tlbflush(CPUPPCState *env, uint32_t type)
@@ -2892,23 +2923,24 @@ void helper_booke206_tlbflush(CPUPPCState *env, uint32_t type)
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
-void tlb_fill(CPUPPCState *env, target_ulong addr, int is_write, int mmu_idx,
+void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
-    CPUState *cpu = CPU(ppc_env_get_cpu(env));
-    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
+    CPUPPCState *env = &cpu->env;
     int ret;
 
     if (pcc->handle_mmu_fault) {
-        ret = pcc->handle_mmu_fault(env, addr, is_write, mmu_idx);
+        ret = pcc->handle_mmu_fault(cpu, addr, is_write, mmu_idx);
     } else {
         ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx);
     }
     if (unlikely(ret != 0)) {
         if (likely(retaddr)) {
             /* now we have a real cpu fault */
-            cpu_restore_state(env, retaddr);
+            cpu_restore_state(cs, retaddr);
         }
-        helper_raise_exception_err(env, env->exception_index, env->error_code);
+        helper_raise_exception_err(env, cs->exception_index, env->error_code);
     }
 }
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 91c33dcd1d..e3fcb03c26 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -11377,8 +11377,8 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
     /* Set env in case of segfault during code fetch */
     while (ctx.exception == POWERPC_EXCP_NONE
             && tcg_ctx.gen_opc_ptr < gen_opc_end) {
-        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
-            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+        if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
+            QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
                 if (bp->pc == ctx.nip) {
                     gen_debug_exception(ctxp);
                     break;
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 3eafbb0d1a..7f53c33eaf 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -631,7 +631,7 @@ static inline void _spr_register(CPUPPCState *env, int num,
 #if defined(CONFIG_KVM)
     spr->one_reg_id = one_reg_id,
 #endif
-    env->spr[num] = initial_value;
+    env->spr[num] = spr->default_value = initial_value;
 }
 
 /* Generic PowerPC SPRs */
@@ -4432,6 +4432,7 @@ enum fsl_e500_version {
 
 static void init_proc_e500 (CPUPPCState *env, int version)
 {
+    PowerPCCPU *cpu = ppc_env_get_cpu(env);
     uint32_t tlbncfg[2];
     uint64_t ivor_mask;
     uint64_t ivpr_mask = 0xFFFF0000ULL;
@@ -4490,7 +4491,7 @@ static void init_proc_e500 (CPUPPCState *env, int version)
         tlbncfg[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64);
         break;
     default:
-        cpu_abort(env, "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]);
+        cpu_abort(CPU(cpu), "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]);
     }
 #endif
     /* Cache sizes */
@@ -4507,7 +4508,7 @@ static void init_proc_e500 (CPUPPCState *env, int version)
         l1cfg0 |= 0x1000000; /* 64 byte cache block size */
         break;
     default:
-        cpu_abort(env, "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]);
+        cpu_abort(CPU(cpu), "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]);
     }
     gen_spr_BookE206(env, 0x000000DF, tlbncfg);
     /* XXX : not implemented */
@@ -7172,7 +7173,8 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
                         PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
                         PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
-                        PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207;
+                        PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
+                        PPC2_ISA205 | PPC2_ISA207S;
     pcc->msr_mask = 0x800000000284FF36ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
@@ -7433,7 +7435,7 @@ static int create_new_table (opc_handler_t **table, unsigned char idx)
 {
     opc_handler_t **tmp;
 
-    tmp = g_malloc(0x20 * sizeof(opc_handler_t));
+    tmp = g_new(opc_handler_t *, 0x20);
     fill_new_table(tmp, 0x20);
     table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
 
@@ -7847,6 +7849,12 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
                    max_smt, kvm_enabled() ? "KVM" : "TCG");
         return;
     }
+    if (!is_power_of_2(smp_threads)) {
+        error_setg(errp, "Cannot support %d threads on PPC with %s, "
+                   "threads count must be a power of 2.",
+                   smp_threads, kvm_enabled() ? "KVM" : "TCG");
+        return;
+    }
 
     cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
         + (cs->cpu_index % smp_threads);
@@ -8220,26 +8228,7 @@ static ObjectClass *ppc_cpu_class_by_name(const char *name)
 
 PowerPCCPU *cpu_ppc_init(const char *cpu_model)
 {
-    PowerPCCPU *cpu;
-    ObjectClass *oc;
-    Error *err = NULL;
-
-    oc = ppc_cpu_class_by_name(cpu_model);
-    if (oc == NULL) {
-        return NULL;
-    }
-
-    cpu = POWERPC_CPU(object_new(object_class_get_name(oc)));
-
-    object_property_set_bool(OBJECT(cpu), true, "realized", &err);
-    if (err != NULL) {
-        error_report("%s", error_get_pretty(err));
-        error_free(err);
-        object_unref(OBJECT(cpu));
-        return NULL;
-    }
-
-    return cpu;
+    return POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU, cpu_model));
 }
 
 /* Sort by PVR, ordering special case "host" last. */
@@ -8384,6 +8373,14 @@ static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
     cpu->env.nip = value;
 }
 
+static bool ppc_cpu_has_work(CPUState *cs)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
+}
+
 /* CPUClass::reset() */
 static void ppc_cpu_reset(CPUState *s)
 {
@@ -8391,6 +8388,7 @@ static void ppc_cpu_reset(CPUState *s)
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
     CPUPPCState *env = &cpu->env;
     target_ulong msr;
+    int i;
 
     pcc->parent_reset(s);
 
@@ -8433,7 +8431,7 @@ static void ppc_cpu_reset(CPUState *s)
     env->reserve_addr = (target_ulong)-1ULL;
     /* Be sure no exception or interrupt is pending */
     env->pending_interrupts = 0;
-    env->exception_index = POWERPC_EXCP_NONE;
+    s->exception_index = POWERPC_EXCP_NONE;
     env->error_code = 0;
 
 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
@@ -8444,8 +8442,17 @@ static void ppc_cpu_reset(CPUState *s)
     env->dtl_size = 0;
 #endif /* TARGET_PPC64 */
 
+    for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
+        ppc_spr_t *spr = &env->spr_cb[i];
+
+        if (!spr->name) {
+            continue;
+        }
+        env->spr[i] = spr->default_value;
+    }
+
     /* Flush all TLBs */
-    tlb_flush(env, 1);
+    tlb_flush(s, 1);
 }
 
 static void ppc_cpu_initfn(Object *obj)
@@ -8511,13 +8518,16 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     cc->reset = ppc_cpu_reset;
 
     cc->class_by_name = ppc_cpu_class_by_name;
+    cc->has_work = ppc_cpu_has_work;
     cc->do_interrupt = ppc_cpu_do_interrupt;
     cc->dump_state = ppc_cpu_dump_state;
     cc->dump_statistics = ppc_cpu_dump_statistics;
     cc->set_pc = ppc_cpu_set_pc;
     cc->gdb_read_register = ppc_cpu_gdb_read_register;
     cc->gdb_write_register = ppc_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_USER_ONLY
+    cc->handle_mmu_fault = ppc_cpu_handle_mmu_fault;
+#else
     cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
     cc->vmsd = &vmstate_ppc_cpu;
 #if defined(TARGET_PPC64)
diff --git a/target-ppc/user_only_helper.c b/target-ppc/user_only_helper.c
index 56e686efd1..829f66f504 100644
--- a/target-ppc/user_only_helper.c
+++ b/target-ppc/user_only_helper.c
@@ -20,9 +20,11 @@
 
 #include "cpu.h"
 
-int cpu_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
-                         int mmu_idx)
+int ppc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
+                             int mmu_idx)
 {
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
     int exception, error_code;
 
     if (rw == 2) {
@@ -37,7 +39,7 @@ int cpu_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
         env->spr[SPR_DAR] = address;
         env->spr[SPR_DSISR] = error_code;
     }
-    env->exception_index = exception;
+    cs->exception_index = exception;
     env->error_code = error_code;
 
     return 1;