]> xenbits.xensource.com Git - qemu-xen-3.3-testing.git/commitdiff
PowerPC MMU and exception fixes:
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 3 Nov 2007 13:37:12 +0000 (13:37 +0000)
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 3 Nov 2007 13:37:12 +0000 (13:37 +0000)
* PowerPC 601 (and probably POWER/POWER2) uses a different BAT format than
  later PowerPC implementation.
* Bugfix in BATs check: must not stop after 4 BATs when more are provided.
* Enable POWER 'rac' instruction.
* Fix exception prefix for all supported PowerPC implementations.
* Fix exceptions, MMU model and bus model for PowerPC 601 & 620.
* Enable PowerPC 620 as it could mostly boot a PreP target.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3518 c046a42c-6fe2-441c-8c8c-71466251a162

target-ppc/cpu.h
target-ppc/exec.h
target-ppc/helper.c
target-ppc/op_helper.c
target-ppc/translate_init.c

index 196f98cae5a2f72adce0b3a87b67e850a790b69e..4beeab25f11966e6599bde079cd1c6905f0f0889 100644 (file)
@@ -102,6 +102,8 @@ enum {
     POWERPC_MMU_BOOKE,
     /* BookE FSL MMU model                                     */
     POWERPC_MMU_BOOKE_FSL,
+    /* PowerPC 601 MMU model (specific BATs format)            */
+    POWERPC_MMU_601,
 #if defined(TARGET_PPC64)
     /* 64 bits PowerPC MMU                                     */
     POWERPC_MMU_64B,
index 5abcee052250bb362828bbb09f3fd5d7dff2883e..f561357044701b1baf4f51d663a790bb664e7efa 100644 (file)
@@ -98,7 +98,7 @@ void do_raise_exception_err (uint32_t exception, int error_code);
 void do_raise_exception (uint32_t exception);
 
 int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong vaddr,
-                          int rw, int access_type, int check_BATs);
+                          int rw, int access_type);
 
 void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
                        target_ulong pte0, target_ulong pte1);
index f68656d5d2206b7225b3a24c7fca38698176f559..9d6f490b5357e5b4621e60e5732d37b91c44c6e4 100644 (file)
@@ -448,12 +448,65 @@ static always_inline int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx,
 }
 
 /* Perform BAT hit & translation */
+static always_inline void bat_size_prot (CPUState *env, target_ulong *blp,
+                                         int *validp, int *protp,
+                                         target_ulong *BATu, target_ulong *BATl)
+{
+    target_ulong bl;
+    int pp, valid, prot;
+
+    bl = (*BATu & 0x00001FFC) << 15;
+    valid = 0;
+    prot = 0;
+    if (((msr_pr == 0) && (*BATu & 0x00000002)) ||
+        ((msr_pr != 0) && (*BATu & 0x00000001))) {
+        valid = 1;
+        pp = *BATl & 0x00000003;
+        if (pp != 0) {
+            prot = PAGE_READ | PAGE_EXEC;
+            if (pp == 0x2)
+                prot |= PAGE_WRITE;
+        }
+    }
+    *blp = bl;
+    *validp = valid;
+    *protp = prot;
+}
+
+static always_inline void bat_601_size_prot (CPUState *env,target_ulong *blp,
+                                             int *validp, int *protp,
+                                             target_ulong *BATu,
+                                             target_ulong *BATl)
+{
+    target_ulong bl;
+    int key, pp, valid, prot;
+
+    bl = (*BATl & 0x0000003F) << 17;
+    if (loglevel != 0) {
+        fprintf(logfile, "b %02x ==> bl %08x msk %08x\n",
+                *BATl & 0x0000003F, bl, ~bl);
+    }
+    prot = 0;
+    valid = (*BATl >> 6) & 1;
+    if (valid) {
+        pp = *BATu & 0x00000003;
+        if (msr_pr == 0)
+            key = (*BATu >> 3) & 1;
+        else
+            key = (*BATu >> 2) & 1;
+        prot = pp_check(key, pp, 0);
+    }
+    *blp = bl;
+    *validp = valid;
+    *protp = prot;
+}
+
 static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
                                   target_ulong virtual, int rw, int type)
 {
     target_ulong *BATlt, *BATut, *BATu, *BATl;
     target_ulong base, BEPIl, BEPIu, bl;
-    int i, pp, pr;
+    int i, valid, prot;
     int ret = -1;
 
 #if defined (DEBUG_BATS)
@@ -462,7 +515,6 @@ static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
                 type == ACCESS_CODE ? 'I' : 'D', virtual);
     }
 #endif
-    pr = msr_pr;
     switch (type) {
     case ACCESS_CODE:
         BATlt = env->IBAT[1];
@@ -480,12 +532,16 @@ static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
     }
 #endif
     base = virtual & 0xFFFC0000;
-    for (i = 0; i < 4; i++) {
+    for (i = 0; i < env->nb_BATs; i++) {
         BATu = &BATut[i];
         BATl = &BATlt[i];
         BEPIu = *BATu & 0xF0000000;
         BEPIl = *BATu & 0x0FFE0000;
-        bl = (*BATu & 0x00001FFC) << 15;
+        if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
+            bat_601_size_prot(env, &bl, &valid, &prot, BATu, BATl);
+        } else {
+            bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
+        }
 #if defined (DEBUG_BATS)
         if (loglevel != 0) {
             fprintf(logfile, "%s: %cBAT%d v 0x" ADDRX " BATu 0x" ADDRX
@@ -497,20 +553,13 @@ static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
         if ((virtual & 0xF0000000) == BEPIu &&
             ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
             /* BAT matches */
-            if (((pr == 0) && (*BATu & 0x00000002)) ||
-                ((pr != 0) && (*BATu & 0x00000001))) {
+            if (valid != 0) {
                 /* Get physical address */
                 ctx->raddr = (*BATl & 0xF0000000) |
                     ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
                     (virtual & 0x0001F000);
                 /* Compute access rights */
-                pp = *BATl & 0x00000003;
-                ctx->prot = 0;
-                if (pp != 0) {
-                    ctx->prot = PAGE_READ | PAGE_EXEC;
-                    if (pp == 0x2)
-                        ctx->prot |= PAGE_WRITE;
-                }
+                ctx->prot = prot;
                 ret = check_prot(ctx->prot, rw, type);
 #if defined (DEBUG_BATS)
                 if (ret == 0 && loglevel != 0) {
@@ -1302,6 +1351,7 @@ static always_inline int check_physical (CPUState *env, mmu_ctx_t *ctx,
     ret = 0;
     switch (env->mmu_model) {
     case POWERPC_MMU_32B:
+    case POWERPC_MMU_601:
     case POWERPC_MMU_SOFT_6xx:
     case POWERPC_MMU_SOFT_74xx:
     case POWERPC_MMU_SOFT_4xx:
@@ -1353,7 +1403,7 @@ static always_inline int check_physical (CPUState *env, mmu_ctx_t *ctx,
 }
 
 int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
-                          int rw, int access_type, int check_BATs)
+                          int rw, int access_type)
 {
     int ret;
 
@@ -1370,15 +1420,15 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
         ret = -1;
         switch (env->mmu_model) {
         case POWERPC_MMU_32B:
+        case POWERPC_MMU_601:
         case POWERPC_MMU_SOFT_6xx:
         case POWERPC_MMU_SOFT_74xx:
-            /* Try to find a BAT */
-            if (check_BATs)
-                ret = get_bat(env, ctx, eaddr, rw, access_type);
-            /* No break here */
 #if defined(TARGET_PPC64)
         case POWERPC_MMU_64B:
 #endif
+            /* Try to find a BAT */
+            if (env->nb_BATs != 0)
+                ret = get_bat(env, ctx, eaddr, rw, access_type);
             if (ret < 0) {
                 /* We didn't match any BAT entry or don't have BATs */
                 ret = get_segment(env, ctx, eaddr, rw, access_type);
@@ -1419,7 +1469,7 @@ target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
 {
     mmu_ctx_t ctx;
 
-    if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT, 1) != 0))
+    if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0))
         return -1;
 
     return ctx.raddr & TARGET_PAGE_MASK;
@@ -1444,7 +1494,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
         access_type = ACCESS_INT;
         //        access_type = env->access_type;
     }
-    ret = get_physical_address(env, &ctx, address, rw, access_type, 1);
+    ret = get_physical_address(env, &ctx, address, rw, access_type);
     if (ret == 0) {
         ret = tlb_set_page_exec(env, address & TARGET_PAGE_MASK,
                                 ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
@@ -1476,6 +1526,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                     env->spr[SPR_40x_ESR] = 0x00000000;
                     break;
                 case POWERPC_MMU_32B:
+                case POWERPC_MMU_601:
 #if defined(TARGET_PPC64)
                 case POWERPC_MMU_64B:
 #endif
@@ -1567,6 +1618,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                         env->spr[SPR_40x_ESR] = 0x00000000;
                     break;
                 case POWERPC_MMU_32B:
+                case POWERPC_MMU_601:
 #if defined(TARGET_PPC64)
                 case POWERPC_MMU_64B:
 #endif
@@ -1809,6 +1861,7 @@ void ppc_tlb_invalidate_all (CPUPPCState *env)
         cpu_abort(env, "MMU model not implemented\n");
         break;
     case POWERPC_MMU_32B:
+    case POWERPC_MMU_601:
 #if defined(TARGET_PPC64)
     case POWERPC_MMU_64B:
 #endif /* defined(TARGET_PPC64) */
@@ -1848,6 +1901,7 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
         cpu_abort(env, "MMU model not implemented\n");
         break;
     case POWERPC_MMU_32B:
+    case POWERPC_MMU_601:
         /* tlbie invalidate TLBs for all segments */
         addr &= ~((target_ulong)-1 << 28);
         /* XXX: this case should be optimized,
index e534fab9f8b7ec098c427b604254118d2272f302..f5d26aeaa3e5bf8026c96a0ab3a91f2ddae09023 100644 (file)
@@ -1682,15 +1682,18 @@ void do_POWER_mulo (void)
 #if !defined (CONFIG_USER_ONLY)
 void do_POWER_rac (void)
 {
-#if 0
     mmu_ctx_t ctx;
+    int nb_BATs;
 
     /* We don't have to generate many instances of this instruction,
      * as rac is supervisor only.
      */
-    if (get_physical_address(env, &ctx, T0, 0, ACCESS_INT, 1) == 0)
+    /* XXX: FIX THIS: Pretend we have no BAT */
+    nb_BATs = env->nb_BATs;
+    env->nb_BATs = 0;
+    if (get_physical_address(env, &ctx, T0, 0, ACCESS_INT) == 0)
         T0 = ctx.raddr;
-#endif
+    env->nb_BATs = nb_BATs;
 }
 
 void do_POWER_rfsvc (void)
index 5698622ba3b1438b0527eb105f78fdb7735538d4..dcf1e1fd04f7ebe2f56f7c80742dca83960ade1e 100644 (file)
@@ -2246,9 +2246,9 @@ static void init_excp_4xx_real (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_FIT]      = 0x00001010;
     env->excp_vectors[POWERPC_EXCP_WDT]      = 0x00001020;
     env->excp_vectors[POWERPC_EXCP_DEBUG]    = 0x00002000;
-    env->excp_prefix = 0x00000000;
-    env->ivor_mask = 0x0000FFF0;
-    env->ivpr_mask = 0xFFFF0000;
+    env->excp_prefix = 0x00000000UL;
+    env->ivor_mask = 0x0000FFF0UL;
+    env->ivpr_mask = 0xFFFF0000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2271,9 +2271,9 @@ static void init_excp_4xx_softmmu (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_DTLB]     = 0x00001100;
     env->excp_vectors[POWERPC_EXCP_ITLB]     = 0x00001200;
     env->excp_vectors[POWERPC_EXCP_DEBUG]    = 0x00002000;
-    env->excp_prefix = 0x00000000;
-    env->ivor_mask = 0x0000FFF0;
-    env->ivpr_mask = 0xFFFF0000;
+    env->excp_prefix = 0x00000000UL;
+    env->ivor_mask = 0x0000FFF0UL;
+    env->ivpr_mask = 0xFFFF0000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2298,9 +2298,9 @@ static void init_excp_BookE (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_DTLB]     = 0x00000000;
     env->excp_vectors[POWERPC_EXCP_ITLB]     = 0x00000000;
     env->excp_vectors[POWERPC_EXCP_DEBUG]    = 0x00000000;
-    env->excp_prefix = 0x00000000;
-    env->ivor_mask = 0x0000FFE0;
-    env->ivpr_mask = 0xFFFF0000;
+    env->excp_prefix = 0x00000000UL;
+    env->ivor_mask = 0x0000FFE0UL;
+    env->ivpr_mask = 0xFFFF0000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2321,7 +2321,7 @@ static void init_excp_601 (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_IO]       = 0x00000A00;
     env->excp_vectors[POWERPC_EXCP_SYSCALL]  = 0x00000C00;
     env->excp_vectors[POWERPC_EXCP_RUNM]     = 0x00002000;
-    env->excp_prefix = 0xFFF00000;
+    env->excp_prefix = 0xFFF00000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0x00000100UL;
 #endif
@@ -2349,7 +2349,7 @@ static void init_excp_602 (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
     env->excp_vectors[POWERPC_EXCP_WDT]      = 0x00001500;
     env->excp_vectors[POWERPC_EXCP_EMUL]     = 0x00001600;
-    env->excp_prefix = 0xFFF00000;
+    env->excp_prefix = 0xFFF00000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2374,6 +2374,7 @@ static void init_excp_603 (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_DSTLB]    = 0x00001200;
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2399,6 +2400,7 @@ static void init_excp_G2 (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_DSTLB]    = 0x00001200;
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2421,6 +2423,7 @@ static void init_excp_604 (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_PERFM]    = 0x00000F00;
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2433,7 +2436,9 @@ static void init_excp_620 (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;
     env->excp_vectors[POWERPC_EXCP_MCHECK]   = 0x00000200;
     env->excp_vectors[POWERPC_EXCP_DSI]      = 0x00000300;
+    env->excp_vectors[POWERPC_EXCP_DSEG]     = 0x00000380;
     env->excp_vectors[POWERPC_EXCP_ISI]      = 0x00000400;
+    env->excp_vectors[POWERPC_EXCP_ISEG]     = 0x00000480;
     env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
     env->excp_vectors[POWERPC_EXCP_ALIGN]    = 0x00000600;
     env->excp_vectors[POWERPC_EXCP_PROGRAM]  = 0x00000700;
@@ -2445,8 +2450,9 @@ static void init_excp_620 (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_PERFM]    = 0x00000F00;
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
+    env->excp_prefix = 0xFFF00000UL;
     /* Hardware reset vector */
-    env->hreset_vector = 0x0000000000000100ULL; /* ? */
+    env->hreset_vector = 0x0000000000000100ULL;
 #endif
 }
 #endif /* defined(TARGET_PPC64) */
@@ -2468,6 +2474,7 @@ static void init_excp_7x0 (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_PERFM]    = 0x00000F00;
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_THERM]    = 0x00001700;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2491,6 +2498,7 @@ static void init_excp_750FX (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
     env->excp_vectors[POWERPC_EXCP_THERM]    = 0x00001700;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2517,6 +2525,7 @@ static void init_excp_7x5 (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_PERFM]    = 0x00000F00;
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2542,6 +2551,7 @@ static void init_excp_7400 (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
     env->excp_vectors[POWERPC_EXCP_VPUA]     = 0x00001600;
     env->excp_vectors[POWERPC_EXCP_THERM]    = 0x00001700;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2569,6 +2579,7 @@ static void init_excp_7450 (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_IABR]     = 0x00001300;
     env->excp_vectors[POWERPC_EXCP_SMI]      = 0x00001400;
     env->excp_vectors[POWERPC_EXCP_VPUA]     = 0x00001600;
+    env->excp_prefix = 0x00000000UL;
     /* Hardware reset vector */
     env->hreset_vector = 0xFFFFFFFCUL;
 #endif
@@ -2600,6 +2611,7 @@ static void init_excp_970 (CPUPPCState *env)
     env->excp_vectors[POWERPC_EXCP_MAINT]    = 0x00001600;
     env->excp_vectors[POWERPC_EXCP_VPUA]     = 0x00001700;
     env->excp_vectors[POWERPC_EXCP_THERM]    = 0x00001800;
+    env->excp_prefix   = 0x00000000FFF00000ULL;
     /* Hardware reset vector */
     env->hreset_vector = 0x0000000000000100ULL;
 #endif
@@ -3232,7 +3244,7 @@ static void init_proc_e500 (CPUPPCState *env)
 #define POWERPC_INSNS_601    (POWERPC_INSNS_6xx | PPC_CACHE_DCBZ |            \
                               PPC_SEGMENT | PPC_EXTERN | PPC_POWER_BR)
 #define POWERPC_MSRM_601     (0x000000000000FD70ULL)
-#define POWERPC_MMU_601      (POWERPC_MMU_32B)
+//#define POWERPC_MMU_601      (POWERPC_MMU_601)
 //#define POWERPC_EXCP_601     (POWERPC_EXCP_601)
 #define POWERPC_INPUT_601    (PPC_FLAGS_INPUT_6xx)
 #define POWERPC_BFDM_601     (bfd_mach_ppc_601)
@@ -3248,7 +3260,7 @@ static void init_proc_601 (CPUPPCState *env)
     spr_register(env, SPR_HID0, "HID0",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
-                 0x00000000);
+                 0x80010080);
     /* XXX : not implemented */
     spr_register(env, SPR_HID1, "HID1",
                  SPR_NOACCESS, SPR_NOACCESS,
@@ -3278,7 +3290,8 @@ static void init_proc_601 (CPUPPCState *env)
     init_excp_601(env);
     env->dcache_line_size = 64;
     env->icache_line_size = 64;
-    /* XXX: TODO: allocate internal IRQ controller */
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
 }
 
 /* PowerPC 602                                                               */
@@ -4182,9 +4195,6 @@ static void init_proc_970 (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0xFFF00000); /* XXX: This is a hack */
-#if !defined(CONFIG_USER_ONLY)
-    env->excp_prefix = 0xFFF00000;
-#endif
 #if !defined(CONFIG_USER_ONLY)
     env->slb_nr = 32;
 #endif
@@ -4259,9 +4269,6 @@ static void init_proc_970FX (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0xFFF00000); /* XXX: This is a hack */
-#if !defined(CONFIG_USER_ONLY)
-    env->excp_prefix = 0xFFF00000;
-#endif
 #if !defined(CONFIG_USER_ONLY)
     env->slb_nr = 32;
 #endif
@@ -4336,9 +4343,6 @@ static void init_proc_970GX (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0xFFF00000); /* XXX: This is a hack */
-#if !defined(CONFIG_USER_ONLY)
-    env->excp_prefix = 0xFFF00000;
-#endif
 #if !defined(CONFIG_USER_ONLY)
     env->slb_nr = 32;
 #endif
@@ -4413,9 +4417,6 @@ static void init_proc_970MP (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0xFFF00000); /* XXX: This is a hack */
-#if !defined(CONFIG_USER_ONLY)
-    env->excp_prefix = 0xFFF00000;
-#endif
 #if !defined(CONFIG_USER_ONLY)
     env->slb_nr = 32;
 #endif
@@ -4432,7 +4433,7 @@ static void init_proc_970MP (CPUPPCState *env)
 #define POWERPC_MSRM_620     (0x800000000005FF73ULL)
 #define POWERPC_MMU_620      (POWERPC_MMU_64B)
 #define POWERPC_EXCP_620     (POWERPC_EXCP_970)
-#define POWERPC_INPUT_620    (PPC_FLAGS_INPUT_970)
+#define POWERPC_INPUT_620    (PPC_FLAGS_INPUT_6xx)
 #define POWERPC_BFDM_620     (bfd_mach_ppc64)
 #define POWERPC_FLAG_620     (POWERPC_FLAG_SE | POWERPC_FLAG_BE)
 #define check_pow_620        check_pow_nocheck /* Check this */
@@ -4456,7 +4457,8 @@ static void init_proc_620 (CPUPPCState *env)
     init_excp_620(env);
     env->dcache_line_size = 64;
     env->icache_line_size = 64;
-    /* XXX: TODO: initialize internal interrupt controller */
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
 }
 #endif /* defined (TARGET_PPC64) */
 
@@ -5771,10 +5773,8 @@ static ppc_def_t ppc_defs[] = {
     POWERPC_DEF("7457v1.2",    CPU_POWERPC_74x7_v12,    0xFFFFFFFF, 7455),
     /* 64 bits PowerPC                                                       */
 #if defined (TARGET_PPC64)
-#if defined (TODO)
     /* PowerPC 620                                                           */
     POWERPC_DEF("620",         CPU_POWERPC_620,         0xFFFFFFFF, 620),
-#endif
 #if defined (TODO)
     /* PowerPC 630 (POWER3)                                                  */
     POWERPC_DEF("630",         CPU_POWERPC_630,         0xFFFFFFFF, 630),