#define ELF_MACHINE     EM_PPC
 #endif
 
-/* XXX: this should be tunable: PowerPC 601 & 64 bits PowerPC
- *                              have different cache line sizes
- */
-#define ICACHE_LINE_SIZE 32
-#define DCACHE_LINE_SIZE 32
-
 /*****************************************************************************/
 /* MMU model                                                                 */
 enum {
     /* 403 dedicated access protection registers */
     target_ulong pb[4];
 
+    int dcache_line_size;
+    int icache_line_size;
+
     /* Those resources are used during exception processing */
     /* CPU model definition */
     target_ulong msr_mask;
     target_ulong excp_prefix;
     target_ulong ivor_mask;
     target_ulong ivpr_mask;
+    target_ulong hreset_vector;
 #endif
 
     /* Those resources are used only during code translation */
 #define SPR_601_HID5     (0x3F5)
 #define SPR_40x_DAC1     (0x3F6)
 #define SPR_MSSCR0       (0x3F6)
+#define SPR_970_HID5     (0x3F6)
 #define SPR_MSSSR0       (0x3F7)
 #define SPR_DABRX        (0x3F7)
 #define SPR_40x_DAC2     (0x3F7)
 
     switch (T0) {
     case 0x0CUL:
         /* Instruction cache line size */
-        T0 = ICACHE_LINE_SIZE;
+        T0 = env->icache_line_size;
         break;
     case 0x0DUL:
         /* Data cache line size */
-        T0 = DCACHE_LINE_SIZE;
+        T0 = env->dcache_line_size;
         break;
     case 0x0EUL:
         /* Minimum cache line size */
-        T0 = ICACHE_LINE_SIZE < DCACHE_LINE_SIZE ?
-            ICACHE_LINE_SIZE : DCACHE_LINE_SIZE;
+        T0 = env->icache_line_size < env->dcache_line_size ?
+            env->icache_line_size : env->dcache_line_size;
         break;
     case 0x0FUL:
         /* Maximum cache line size */
-        T0 = ICACHE_LINE_SIZE > DCACHE_LINE_SIZE ?
-            ICACHE_LINE_SIZE : DCACHE_LINE_SIZE;
+        T0 = env->icache_line_size > env->dcache_line_size ?
+            env->icache_line_size : env->dcache_line_size;
         break;
     default:
         /* Undefined */
 
 void glue(do_stmw, MEMSUFFIX) (int src);
 void glue(do_stmw_le, MEMSUFFIX) (int src);
 void glue(do_icbi, MEMSUFFIX) (void);
+void glue(do_dcbz, MEMSUFFIX) (void);
 void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb);
 void glue(do_POWER2_lfq, MEMSUFFIX) (void);
 void glue(do_POWER2_lfq_le, MEMSUFFIX) (void);
 void glue(do_stmw_64, MEMSUFFIX) (int src);
 void glue(do_stmw_le_64, MEMSUFFIX) (int src);
 void glue(do_icbi_64, MEMSUFFIX) (void);
+void glue(do_dcbz_64, MEMSUFFIX) (void);
 #endif
 
 #else
 
      * do the load "by hand".
      */
     tmp = glue(ldl, MEMSUFFIX)((uint32_t)T0);
-    T0 &= ~(ICACHE_LINE_SIZE - 1);
-    tb_invalidate_page_range((uint32_t)T0, (uint32_t)(T0 + ICACHE_LINE_SIZE));
+    T0 &= ~(env->icache_line_size - 1);
+    tb_invalidate_page_range((uint32_t)T0,
+                             (uint32_t)(T0 + env->icache_line_size));
 }
 
 #if defined(TARGET_PPC64)
      * do the load "by hand".
      */
     tmp = glue(ldq, MEMSUFFIX)((uint64_t)T0);
-    T0 &= ~(ICACHE_LINE_SIZE - 1);
-    tb_invalidate_page_range((uint64_t)T0, (uint64_t)(T0 + ICACHE_LINE_SIZE));
+    T0 &= ~(env->icache_line_size - 1);
+    tb_invalidate_page_range((uint64_t)T0,
+                             (uint64_t)(T0 + env->icache_line_size));
+}
+#endif
+
+void glue(do_dcbz, MEMSUFFIX) (void)
+{
+    int dcache_line_size = env->dcache_line_size;
+
+    /* XXX: should be 970 specific (?) */
+    if (((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1)
+        dcache_line_size = 32;
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x00), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x04), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x08), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x0C), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x10), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x14), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x18), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x1C), 0);
+    if (dcache_line_size >= 64) {
+        glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x20UL), 0);
+        glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x24UL), 0);
+        glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x28UL), 0);
+        glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x2CUL), 0);
+        glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x30UL), 0);
+        glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x34UL), 0);
+        glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x38UL), 0);
+        glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x3CUL), 0);
+        if (dcache_line_size >= 128) {
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x40UL), 0);
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x44UL), 0);
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x48UL), 0);
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x4CUL), 0);
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x50UL), 0);
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x54UL), 0);
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x58UL), 0);
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x5CUL), 0);
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x60UL), 0);
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x64UL), 0);
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x68UL), 0);
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x6CUL), 0);
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x70UL), 0);
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x74UL), 0);
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x78UL), 0);
+            glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x7CUL), 0);
+        }
+    }
+}
+
+#if defined(TARGET_PPC64)
+void glue(do_dcbz_64, MEMSUFFIX) (void)
+{
+    int dcache_line_size = env->dcache_line_size;
+
+    /* XXX: should be 970 specific (?) */
+    if (((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1)
+        dcache_line_size = 32;
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x00), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x04), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x08), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x0C), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x10), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x14), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x18), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x1C), 0);
+    if (dcache_line_size >= 64) {
+        glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x20UL), 0);
+        glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x24UL), 0);
+        glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x28UL), 0);
+        glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x2CUL), 0);
+        glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x30UL), 0);
+        glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x34UL), 0);
+        glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x38UL), 0);
+        glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x3CUL), 0);
+        if (dcache_line_size >= 128) {
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x40UL), 0);
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x44UL), 0);
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x48UL), 0);
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x4CUL), 0);
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x50UL), 0);
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x54UL), 0);
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x58UL), 0);
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x5CUL), 0);
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x60UL), 0);
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x64UL), 0);
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x68UL), 0);
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x6CUL), 0);
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x70UL), 0);
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x74UL), 0);
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x78UL), 0);
+            glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x7CUL), 0);
+        }
+    }
 }
 #endif
 
 
 }
 #endif
 
-void OPPROTO glue(op_dcbz, MEMSUFFIX) (void)
+void OPPROTO glue(op_dcbz_l32, MEMSUFFIX) (void)
+{
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x00), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x04), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x08), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x0C), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x10), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x14), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x18), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x1C), 0);
+    RETURN();
+}
+
+void OPPROTO glue(op_dcbz_l64, MEMSUFFIX) (void)
 {
     glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x00), 0);
     glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x04), 0);
     glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x14), 0);
     glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x18), 0);
     glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x1C), 0);
-#if DCACHE_LINE_SIZE == 64
-    /* XXX: cache line size should be 64 for POWER & PowerPC 601 */
     glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x20UL), 0);
     glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x24UL), 0);
     glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x28UL), 0);
     glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x34UL), 0);
     glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x38UL), 0);
     glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x3CUL), 0);
-#endif
+    RETURN();
+}
+
+void OPPROTO glue(op_dcbz_l128, MEMSUFFIX) (void)
+{
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x00), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x04), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x08), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x0C), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x10), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x14), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x18), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x1C), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x20UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x24UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x28UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x2CUL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x30UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x34UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x38UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x3CUL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x40UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x44UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x48UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x4CUL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x50UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x54UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x58UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x5CUL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x60UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x64UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x68UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x6CUL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x70UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x74UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x78UL), 0);
+    glue(stl, MEMSUFFIX)((uint32_t)(T0 + 0x7CUL), 0);
+    RETURN();
+}
+
+void OPPROTO glue(op_dcbz, MEMSUFFIX) (void)
+{
+    glue(do_dcbz, MEMSUFFIX)();
     RETURN();
 }
 
 #if defined(TARGET_PPC64)
-void OPPROTO glue(op_dcbz_64, MEMSUFFIX) (void)
+void OPPROTO glue(op_dcbz_l32_64, MEMSUFFIX) (void)
+{
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x00), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x04), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x08), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x0C), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x10), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x14), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x18), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x1C), 0);
+    RETURN();
+}
+
+void OPPROTO glue(op_dcbz_l64_64, MEMSUFFIX) (void)
 {
     glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x00), 0);
     glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x04), 0);
     glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x14), 0);
     glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x18), 0);
     glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x1C), 0);
-#if DCACHE_LINE_SIZE == 64
-    /* XXX: cache line size should be 64 for POWER & PowerPC 601 */
     glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x20UL), 0);
     glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x24UL), 0);
     glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x28UL), 0);
     glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x34UL), 0);
     glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x38UL), 0);
     glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x3CUL), 0);
-#endif
+    RETURN();
+}
+
+void OPPROTO glue(op_dcbz_l128_64, MEMSUFFIX) (void)
+{
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x00), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x04), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x08), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x0C), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x10), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x14), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x18), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x1C), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x20UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x24UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x28UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x2CUL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x30UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x34UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x38UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x3CUL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x40UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x44UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x48UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x4CUL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x50UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x54UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x58UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x5CUL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x60UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x64UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x68UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x6CUL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x70UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x74UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x78UL), 0);
+    glue(stl, MEMSUFFIX)((uint64_t)(T0 + 0x7CUL), 0);
+    RETURN();
+}
+
+void OPPROTO glue(op_dcbz_64, MEMSUFFIX) (void)
+{
+    glue(do_dcbz_64, MEMSUFFIX)();
     RETURN();
 }
 #endif
 
 #endif
     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
     int singlestep_enabled;
+    int dcache_line_size;
 } DisasContext;
 
 struct opc_handler_t {
     PPC_WAIT          = 0x0000100000000000ULL,
     /* New 64 bits extensions (PowerPC 2.0x)            */
     PPC_64BX          = 0x0000200000000000ULL,
+    /* dcbz instruction with fixed cache line size      */
+    PPC_CACHE_DCBZ    = 0x0000400000000000ULL,
+    /* dcbz instruction with tunable cache line size    */
+    PPC_CACHE_DCBZT   = 0x0000800000000000ULL,
 };
 
 /*****************************************************************************/
 }
 
 /* dcbz */
-#define op_dcbz() (*gen_op_dcbz[ctx->mem_idx])()
+#define op_dcbz(n) (*gen_op_dcbz[n][ctx->mem_idx])()
 #if defined(CONFIG_USER_ONLY)
 /* User-mode only */
-static GenOpFunc *gen_op_dcbz[] = {
-    &gen_op_dcbz_raw,
-    &gen_op_dcbz_raw,
+static GenOpFunc *gen_op_dcbz[4][4] = {
+    {
+        &gen_op_dcbz_l32_raw,
+        &gen_op_dcbz_l32_raw,
 #if defined(TARGET_PPC64)
-    &gen_op_dcbz_64_raw,
-    &gen_op_dcbz_64_raw,
+        &gen_op_dcbz_l32_64_raw,
+        &gen_op_dcbz_l32_64_raw,
 #endif
+    },
+    {
+        &gen_op_dcbz_l64_raw,
+        &gen_op_dcbz_l64_raw,
+#if defined(TARGET_PPC64)
+        &gen_op_dcbz_l64_64_raw,
+        &gen_op_dcbz_l64_64_raw,
+#endif
+    },
+    {
+        &gen_op_dcbz_l128_raw,
+        &gen_op_dcbz_l128_raw,
+#if defined(TARGET_PPC64)
+        &gen_op_dcbz_l128_64_raw,
+        &gen_op_dcbz_l128_64_raw,
+#endif
+    },
+    {
+        &gen_op_dcbz_raw,
+        &gen_op_dcbz_raw,
+#if defined(TARGET_PPC64)
+        &gen_op_dcbz_64_raw,
+        &gen_op_dcbz_64_raw,
+#endif
+    },
 };
 #else
 #if defined(TARGET_PPC64)
 /* Full system - 64 bits mode */
-static GenOpFunc *gen_op_dcbz[] = {
-    &gen_op_dcbz_user,
-    &gen_op_dcbz_user,
-    &gen_op_dcbz_64_user,
-    &gen_op_dcbz_64_user,
-    &gen_op_dcbz_kernel,
-    &gen_op_dcbz_kernel,
-    &gen_op_dcbz_64_kernel,
-    &gen_op_dcbz_64_kernel,
+static GenOpFunc *gen_op_dcbz[4][12] = {
+    {
+        &gen_op_dcbz_l32_user,
+        &gen_op_dcbz_l32_user,
+        &gen_op_dcbz_l32_64_user,
+        &gen_op_dcbz_l32_64_user,
+        &gen_op_dcbz_l32_kernel,
+        &gen_op_dcbz_l32_kernel,
+        &gen_op_dcbz_l32_64_kernel,
+        &gen_op_dcbz_l32_64_kernel,
+#if defined(TARGET_PPC64H)
+        &gen_op_dcbz_l32_hypv,
+        &gen_op_dcbz_l32_hypv,
+        &gen_op_dcbz_l32_64_hypv,
+        &gen_op_dcbz_l32_64_hypv,
+#endif
+    },
+    {
+        &gen_op_dcbz_l64_user,
+        &gen_op_dcbz_l64_user,
+        &gen_op_dcbz_l64_64_user,
+        &gen_op_dcbz_l64_64_user,
+        &gen_op_dcbz_l64_kernel,
+        &gen_op_dcbz_l64_kernel,
+        &gen_op_dcbz_l64_64_kernel,
+        &gen_op_dcbz_l64_64_kernel,
 #if defined(TARGET_PPC64H)
-    &gen_op_dcbz_hypv,
-    &gen_op_dcbz_hypv,
-    &gen_op_dcbz_64_hypv,
-    &gen_op_dcbz_64_hypv,
+        &gen_op_dcbz_l64_hypv,
+        &gen_op_dcbz_l64_hypv,
+        &gen_op_dcbz_l64_64_hypv,
+        &gen_op_dcbz_l64_64_hypv,
+#endif
+    },
+    {
+        &gen_op_dcbz_l128_user,
+        &gen_op_dcbz_l128_user,
+        &gen_op_dcbz_l128_64_user,
+        &gen_op_dcbz_l128_64_user,
+        &gen_op_dcbz_l128_kernel,
+        &gen_op_dcbz_l128_kernel,
+        &gen_op_dcbz_l128_64_kernel,
+        &gen_op_dcbz_l128_64_kernel,
+#if defined(TARGET_PPC64H)
+        &gen_op_dcbz_l128_hypv,
+        &gen_op_dcbz_l128_hypv,
+        &gen_op_dcbz_l128_64_hypv,
+        &gen_op_dcbz_l128_64_hypv,
+#endif
+    },
+    {
+        &gen_op_dcbz_user,
+        &gen_op_dcbz_user,
+        &gen_op_dcbz_64_user,
+        &gen_op_dcbz_64_user,
+        &gen_op_dcbz_kernel,
+        &gen_op_dcbz_kernel,
+        &gen_op_dcbz_64_kernel,
+        &gen_op_dcbz_64_kernel,
+#if defined(TARGET_PPC64H)
+        &gen_op_dcbz_hypv,
+        &gen_op_dcbz_hypv,
+        &gen_op_dcbz_64_hypv,
+        &gen_op_dcbz_64_hypv,
 #endif
+    },
 };
 #else
 /* Full system - 32 bits mode */
-static GenOpFunc *gen_op_dcbz[] = {
-    &gen_op_dcbz_user,
-    &gen_op_dcbz_user,
-    &gen_op_dcbz_kernel,
-    &gen_op_dcbz_kernel,
+static GenOpFunc *gen_op_dcbz[4][4] = {
+    {
+        &gen_op_dcbz_l32_user,
+        &gen_op_dcbz_l32_user,
+        &gen_op_dcbz_l32_kernel,
+        &gen_op_dcbz_l32_kernel,
+    },
+    {
+        &gen_op_dcbz_l64_user,
+        &gen_op_dcbz_l64_user,
+        &gen_op_dcbz_l64_kernel,
+        &gen_op_dcbz_l64_kernel,
+    },
+    {
+        &gen_op_dcbz_l128_user,
+        &gen_op_dcbz_l128_user,
+        &gen_op_dcbz_l128_kernel,
+        &gen_op_dcbz_l128_kernel,
+    },
+    {
+        &gen_op_dcbz_user,
+        &gen_op_dcbz_user,
+        &gen_op_dcbz_kernel,
+        &gen_op_dcbz_kernel,
+    },
 };
 #endif
 #endif
 
-GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE)
+static inline void handler_dcbz (DisasContext *ctx, int dcache_line_size)
+{
+    int n;
+
+    switch (dcache_line_size) {
+    case 32:
+        n = 0;
+        break;
+    case 64:
+        n = 1;
+        break;
+    case 128:
+        n = 2;
+        break;
+    default:
+        n = 3;
+        break;
+    }
+    op_dcbz(n);
+}
+
+GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
 {
     gen_addr_reg_index(ctx);
-    op_dcbz();
+    handler_dcbz(ctx, ctx->dcache_line_size);
+    gen_op_check_reservation();
+}
+
+GEN_HANDLER(dcbz_970, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
+{
+    gen_addr_reg_index(ctx);
+    if (ctx->opcode & 0x00200000)
+        handler_dcbz(ctx, ctx->dcache_line_size);
+    else
+        handler_dcbz(ctx, -1);
     gen_op_check_reservation();
 }
 
 #else
     ctx.mem_idx = (supervisor << 1) | msr_le;
 #endif
+    ctx.dcache_line_size = env->dcache_line_size;
     ctx.fpu_enabled = msr_fp;
 #if defined(TARGET_PPCEMB)
     ctx.spe_enabled = msr_spe;
 
 /* PowerPC implementations definitions                                       */
 
 /* PowerPC 40x instruction set                                               */
-#define POWERPC_INSNS_EMB    (PPC_INSNS_BASE | PPC_EMB_COMMON)
+#define POWERPC_INSNS_EMB    (PPC_INSNS_BASE | PPC_CACHE_DCBZ | PPC_EMB_COMMON)
 
 /* PowerPC 401                                                               */
 #define POWERPC_INSNS_401    (POWERPC_INSNS_EMB |                             \
     gen_spr_401_403(env);
     gen_spr_401(env);
     init_excp_4xx_real(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc40x_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 401x2                                                             */
     env->nb_ways = 1;
     env->id_tlbs = 0;
     init_excp_4xx_softmmu(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc40x_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 401x3                                                             */
     gen_spr_401x2(env);
     gen_spr_compress(env);
     init_excp_4xx_softmmu(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc40x_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* IOP480                                                                    */
     env->nb_ways = 1;
     env->id_tlbs = 0;
     init_excp_4xx_softmmu(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc40x_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 403                                                               */
     gen_spr_403(env);
     gen_spr_403_real(env);
     init_excp_4xx_real(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc40x_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 403 GCX                                                           */
     env->nb_ways = 1;
     env->id_tlbs = 0;
     init_excp_4xx_softmmu(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc40x_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 405                                                               */
     env->nb_ways = 1;
     env->id_tlbs = 0;
     init_excp_4xx_softmmu(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc40x_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 440 EP                                                            */
     env->nb_ways = 1;
     env->id_tlbs = 0;
     init_excp_BookE(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* XXX: TODO: allocate internal IRQ controller */
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 440 GP                                                            */
     env->nb_ways = 1;
     env->id_tlbs = 0;
     init_excp_BookE(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* XXX: TODO: allocate internal IRQ controller */
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 440x4                                                             */
     env->nb_ways = 1;
     env->id_tlbs = 0;
     init_excp_BookE(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* XXX: TODO: allocate internal IRQ controller */
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 440x5                                                             */
     env->nb_ways = 1;
     env->id_tlbs = 0;
     init_excp_BookE(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* XXX: TODO: allocate internal IRQ controller */
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 460 (guessed)                                                     */
     env->nb_ways = 1;
     env->id_tlbs = 0;
     init_excp_BookE(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* XXX: TODO: allocate internal IRQ controller */
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 460F (guessed)                                                    */
     env->nb_ways = 1;
     env->id_tlbs = 0;
     init_excp_BookE(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* XXX: TODO: allocate internal IRQ controller */
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* Generic BookE PowerPC                                                     */
 static void init_proc_BookE (CPUPPCState *env)
 {
     init_excp_BookE(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* e200 core                                                                 */
     env->nb_ways = 1;
     env->id_tlbs = 0;
     init_excp_BookE(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* XXX: TODO: allocate internal IRQ controller */
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* e600 core                                                                 */
 #define POWERPC_INSNS_WORKS  (POWERPC_INSNS_6xx | PPC_FLOAT_FSQRT |           \
                               PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE |            \
                               PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX |             \
-                              PPC_MEM_TLBSYNC | PPC_MFTB)
+                              PPC_MEM_TLBSYNC | PPC_CACHE_DCBZ | PPC_MFTB)
 
 /* POWER : same as 601, without mfmsr, mfsr                                  */
 #if defined(TODO)
 #endif /* TODO */
 
 /* PowerPC 601                                                               */
-#define POWERPC_INSNS_601    (POWERPC_INSNS_6xx | PPC_EXTERN | PPC_POWER_BR)
+#define POWERPC_INSNS_601    (POWERPC_INSNS_6xx | PPC_CACHE_DCBZ |            \
+                              PPC_EXTERN | PPC_POWER_BR)
 #define POWERPC_MSRM_601     (0x000000000000FE70ULL)
 //#define POWERPC_MMU_601      (POWERPC_MMU_601)
 //#define POWERPC_EXCP_601     (POWERPC_EXCP_601)
     env->id_tlbs = 0;
     env->id_tlbs = 0;
     init_excp_601(env);
+    env->dcache_line_size = 64;
+    env->icache_line_size = 64;
     /* XXX: TODO: allocate internal IRQ controller */
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 602                                                               */
 #define POWERPC_INSNS_602    (POWERPC_INSNS_6xx | PPC_MFTB |                  \
                               PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE |            \
                               PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX |             \
-                              PPC_6xx_TLB | PPC_MEM_TLBSYNC | PPC_602_SPEC)
+                              PPC_6xx_TLB | PPC_MEM_TLBSYNC | PPC_CACHE_DCBZ |\
+                              PPC_602_SPEC)
 #define POWERPC_MSRM_602     (0x000000000033FF73ULL)
 #define POWERPC_MMU_602      (POWERPC_MMU_SOFT_6xx)
 //#define POWERPC_EXCP_602     (POWERPC_EXCP_602)
     gen_low_BATs(env);
     gen_6xx_7xx_soft_tlb(env, 64, 2);
     init_excp_602(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc6xx_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 603                                                               */
     gen_low_BATs(env);
     gen_6xx_7xx_soft_tlb(env, 64, 2);
     init_excp_603(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc6xx_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 603e                                                              */
     gen_low_BATs(env);
     gen_6xx_7xx_soft_tlb(env, 64, 2);
     init_excp_603(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc6xx_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC G2                                                                */
     gen_high_BATs(env);
     gen_6xx_7xx_soft_tlb(env, 64, 2);
     init_excp_G2(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc6xx_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC G2LE                                                              */
     gen_high_BATs(env);
     gen_6xx_7xx_soft_tlb(env, 64, 2);
     init_excp_G2(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc6xx_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 604                                                               */
     /* Memory management */
     gen_low_BATs(env);
     init_excp_604(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc6xx_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 740/750 (aka G3)                                                  */
     /* Memory management */
     gen_low_BATs(env);
     init_excp_7x0(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc6xx_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 750FX/GX                                                          */
     /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
     gen_high_BATs(env);
     init_excp_750FX(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc6xx_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 745/755                                                           */
     gen_low_BATs(env);
     gen_high_BATs(env);
     gen_6xx_7xx_soft_tlb(env, 64, 2);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc6xx_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 7400 (aka G4)                                                     */
     /* Memory management */
     gen_low_BATs(env);
     init_excp_7400(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc6xx_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 7410 (aka G4)                                                     */
     /* Memory management */
     gen_low_BATs(env);
     init_excp_7400(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc6xx_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 7440 (aka G4)                                                     */
     /* Memory management */
     gen_low_BATs(env);
     gen_74xx_soft_tlb(env, 128, 2);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc6xx_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 7450 (aka G4)                                                     */
     gen_low_BATs(env);
     gen_74xx_soft_tlb(env, 128, 2);
     init_excp_7450(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc6xx_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 7445 (aka G4)                                                     */
     gen_high_BATs(env);
     gen_74xx_soft_tlb(env, 128, 2);
     init_excp_7450(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc6xx_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 /* PowerPC 7455 (aka G4)                                                     */
     gen_high_BATs(env);
     gen_74xx_soft_tlb(env, 128, 2);
     init_excp_7450(env);
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
     /* Allocate hardware IRQ controller */
     ppc6xx_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0xFFFFFFFCUL;
+#endif
 }
 
 #if defined (TARGET_PPC64)
+#define POWERPC_INSNS_WORK64  (POWERPC_INSNS_6xx | PPC_FLOAT_FSQRT |          \
+                              PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE |            \
+                              PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX |             \
+                              PPC_MEM_TLBSYNC | PPC_CACHE_DCBZT | PPC_MFTB)
 /* PowerPC 970                                                               */
-#define POWERPC_INSNS_970    (POWERPC_INSNS_WORKS | PPC_FLOAT_FSQRT |         \
+#define POWERPC_INSNS_970    (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT |        \
                               PPC_64B | PPC_ALTIVEC |                         \
                               PPC_64_BRIDGE | PPC_SLBI)
 #define POWERPC_MSRM_970     (0x900000000204FF36ULL)
     spr_register(env, SPR_HID0, "HID0",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_clear,
-                 0x00000000);
+                 0x60000000);
     /* XXX : not implemented */
     spr_register(env, SPR_HID1, "HID1",
                  SPR_NOACCESS, SPR_NOACCESS,
     env->slb_nr = 32;
 #endif
     init_excp_970(env);
+    env->dcache_line_size = 128;
+    env->icache_line_size = 128;
     /* Allocate hardware IRQ controller */
     ppc970_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0x0000000000000100ULL;
+#endif
 }
 
 /* PowerPC 970FX (aka G5)                                                    */
-#define POWERPC_INSNS_970FX  (POWERPC_INSNS_WORKS | PPC_FLOAT_FSQRT |         \
+#define POWERPC_INSNS_970FX  (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT |        \
                               PPC_64B | PPC_ALTIVEC |                         \
                               PPC_64_BRIDGE | PPC_SLBI)
 #define POWERPC_MSRM_970FX   (0x800000000204FF36ULL)
     spr_register(env, SPR_HID0, "HID0",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_clear,
-                 0x00000000);
+                 0x60000000);
     /* XXX : not implemented */
     spr_register(env, SPR_HID1, "HID1",
                  SPR_NOACCESS, SPR_NOACCESS,
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
+    /* XXX : not implemented */
+    spr_register(env, SPR_970_HID5, "HID5",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
     /* Memory management */
     /* XXX: not correct */
     gen_low_BATs(env);
     env->slb_nr = 32;
 #endif
     init_excp_970(env);
+    env->dcache_line_size = 128;
+    env->icache_line_size = 128;
     /* Allocate hardware IRQ controller */
     ppc970_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0x0000000000000100ULL;
+#endif
 }
 
 /* PowerPC 970 GX                                                            */
-#define POWERPC_INSNS_970GX  (POWERPC_INSNS_WORKS | PPC_FLOAT_FSQRT |         \
+#define POWERPC_INSNS_970GX  (POWERPC_INSNS_WORK64 | PPC_FLOAT_FSQRT |        \
                               PPC_64B | PPC_ALTIVEC |                         \
                               PPC_64_BRIDGE | PPC_SLBI)
 #define POWERPC_MSRM_970GX   (0x800000000204FF36ULL)
     spr_register(env, SPR_HID0, "HID0",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_clear,
-                 0x00000000);
+                 0x60000000);
     /* XXX : not implemented */
     spr_register(env, SPR_HID1, "HID1",
                  SPR_NOACCESS, SPR_NOACCESS,
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
+    /* XXX : not implemented */
+    spr_register(env, SPR_970_HID5, "HID5",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
     /* Memory management */
     /* XXX: not correct */
     gen_low_BATs(env);
     env->slb_nr = 32;
 #endif
     init_excp_970(env);
+    env->dcache_line_size = 128;
+    env->icache_line_size = 128;
     /* Allocate hardware IRQ controller */
     ppc970_irq_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0x0000000000000100ULL;
+#endif
 }
 
 /* PowerPC 620                                                               */
     gen_low_BATs(env);
     gen_high_BATs(env);
     init_excp_620(env);
+    env->dcache_line_size = 64;
+    env->icache_line_size = 64;
     /* XXX: TODO: initialize internal interrupt controller */
+#if !defined(CONFIG_USER_ONLY)
+    /* Hardware reset vector */
+    env->hreset_vector = 0x0000000000000100ULL; /* ? */
+#endif
 }
 #endif /* defined (TARGET_PPC64) */