/* init CPUs */
     env = cpu_init();
+    qemu_register_reset(&cpu_ppc_reset, env);
     register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
 
     /* Default CPU is a generic 74x/75x */
 
 
     sysctrl = qemu_mallocz(sizeof(sysctrl_t));
     if (sysctrl == NULL)
-       return;
+        return;
 
     linux_boot = (kernel_filename != NULL);
-    
+
     /* init CPUs */
 
     env = cpu_init();
+    qemu_register_reset(&cpu_ppc_reset, env);
     register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
 
     /* Default CPU is a 604 */
 
 void ppc_store_msr_32 (CPUPPCState *env, uint32_t value);
 
 void do_compute_hflags (CPUPPCState *env);
+void cpu_ppc_reset (void *opaque);
+CPUPPCState *cpu_ppc_init (void);
+void cpu_ppc_close(CPUPPCState *env);
 
 int ppc_find_by_name (const unsigned char *name, ppc_def_t **def);
 int ppc_find_by_pvr (uint32_t apvr, ppc_def_t **def);
 void store_40x_pit (CPUPPCState *env, target_ulong val);
 void store_booke_tcr (CPUPPCState *env, target_ulong val);
 void store_booke_tsr (CPUPPCState *env, target_ulong val);
+void ppc_tlb_invalidate_all (CPUPPCState *env);
 #endif
 #endif
 
 
     return ret;
 }
 
+void ppc4xx_tlb_invalidate_all (CPUState *env)
+{
+    ppcemb_tlb_t *tlb;
+    int i;
+
+    for (i = 0; i < env->nb_tlb; i++) {
+        tlb = &env->tlb[i].tlbe;
+        if (tlb->prot & PAGE_VALID) {
+#if 0 // XXX: TLB have variable sizes then we flush all Qemu TLB.
+            end = tlb->EPN + tlb->size;
+            for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
+                tlb_flush_page(env, page);
+#endif
+            tlb->prot &= ~PAGE_VALID;
+        }
+    }
+    tlb_flush(env, 1);
+}
+
 int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
                                  target_ulong address, int rw, int access_type)
 {
     env->DBAT[1][nr] = value;
 }
 
+
+/*****************************************************************************/
+/* TLB management */
+void ppc_tlb_invalidate_all (CPUPPCState *env)
+{
+    if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
+        ppc6xx_tlb_invalidate_all(env);
+    } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
+        ppc4xx_tlb_invalidate_all(env);
+    } else {
+        tlb_flush(env, 1);
+    }
+}
+
 /*****************************************************************************/
 /* Special registers manipulation */
 #if defined(TARGET_PPC64)
     fprintf(f, "Memory access at address " TARGET_FMT_lx "\n", EA);
 }
 
+void cpu_ppc_reset (void *opaque)
+{
+    CPUPPCState *env;
+
+    env = opaque;
+#if defined (DO_SINGLE_STEP) && 0
+    /* Single step trace mode */
+    msr_se = 1;
+    msr_be = 1;
+#endif
+    msr_fp = 1; /* Allow floating point exceptions */
+    msr_me = 1; /* Allow machine check exceptions  */
+#if defined(TARGET_PPC64)
+    msr_sf = 0; /* Boot in 32 bits mode */
+    msr_cm = 0;
+#endif
+#if defined(CONFIG_USER_ONLY)
+    msr_pr = 1;
+    tlb_flush(env, 1);
+#else
+    env->nip = 0xFFFFFFFC;
+    ppc_tlb_invalidate_all(env);
+#endif
+    do_compute_hflags(env);
+    env->reserve = -1;
+}
+
+CPUPPCState *cpu_ppc_init (void)
+{
+    CPUPPCState *env;
+
+    env = qemu_mallocz(sizeof(CPUPPCState));
+    if (!env)
+        return NULL;
+    cpu_exec_init(env);
+    cpu_ppc_reset(env);
+
+    return env;
+}
+
+void cpu_ppc_close (CPUPPCState *env)
+{
+    /* Should also remove all opcode tables... */
+    free(env);
+}
 
 /* TLB invalidation helpers */
 void do_tlbia (void)
 {
-    if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
-        ppc6xx_tlb_invalidate_all(env);
-    } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
-        /* XXX: TODO */
-#if 0
-        ppcbooke_tlb_invalidate_all(env);
-#endif
-    } else {
-        tlb_flush(env, 1);
-    }
+    ppc_tlb_invalidate_all(env);
 }
 
 void do_tlbie (void)
 }
 
 /* Helpers for 4xx TLB management */
-void do_4xx_tlbia (void)
-{
-    ppcemb_tlb_t *tlb;
-    int i;
-
-    for (i = 0; i < 64; i++) {
-        tlb = &env->tlb[i].tlbe;
-        if (tlb->prot & PAGE_VALID) {
-#if 0
-            end = tlb->EPN + tlb->size;
-            for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
-                tlb_flush_page(env, page);
-#endif
-            tlb->prot &= ~PAGE_VALID;
-        }
-    }
-    tlb_flush(env, 1);
-}
-
 void do_4xx_tlbre_lo (void)
 {
     ppcemb_tlb_t *tlb;
 
     return 0;
 }
 
-void do_compute_hflags (CPUPPCState *env);
-CPUPPCState *cpu_ppc_init (void)
-{
-    CPUPPCState *env;
-
-    env = qemu_mallocz(sizeof(CPUPPCState));
-    if (!env)
-        return NULL;
-    cpu_exec_init(env);
-    tlb_flush(env, 1);
-#if defined (DO_SINGLE_STEP) && 0
-    /* Single step trace mode */
-    msr_se = 1;
-    msr_be = 1;
-#endif
-    msr_fp = 1; /* Allow floating point exceptions */
-    msr_me = 1; /* Allow machine check exceptions  */
-#if defined(CONFIG_USER_ONLY)
-    msr_pr = 1;
-#else
-    env->nip = 0xFFFFFFFC;
-#endif
-    do_compute_hflags(env);
-    env->reserve = -1;
-    return env;
-}
-
-void cpu_ppc_close(CPUPPCState *env)
-{
-    /* Should also remove all opcode tables... */
-    free(env);
-}
-
 /*****************************************************************************/
 /* PowerPC CPU definitions */
 static ppc_def_t ppc_defs[] =