]> Git Repo - qemu.git/blobdiff - target-ppc/helper.c
pci: Unregister BARs before device exit
[qemu.git] / target-ppc / helper.c
index 137a494201ba4ffa2dcfc0901f5fa09813c2fe60..e97e49640d073244713cb5c4c1dd7417cb3d7057 100644 (file)
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
 
 #include "cpu.h"
 #include "helper_regs.h"
-#include "qemu-common.h"
 #include "kvm.h"
 #include "kvm_ppc.h"
 #include "cpus.h"
 /*****************************************************************************/
 /* PowerPC Hypercall emulation */
 
-void (*cpu_ppc_hypercall)(CPUState *);
+void (*cpu_ppc_hypercall)(CPUPPCState *);
 
 /*****************************************************************************/
 /* PowerPC MMU emulation */
 
 #if defined(CONFIG_USER_ONLY)
-int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
+int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw,
                               int mmu_idx)
 {
     int exception, error_code;
@@ -297,7 +291,7 @@ static inline int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
 }
 
 /* Software driven TLB helpers */
-static inline int ppc6xx_tlb_getnum(CPUState *env, target_ulong eaddr, int way,
+static inline int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr, int way,
                                     int is_code)
 {
     int nr;
@@ -313,7 +307,7 @@ static inline int ppc6xx_tlb_getnum(CPUState *env, target_ulong eaddr, int way,
     return nr;
 }
 
-static inline void ppc6xx_tlb_invalidate_all(CPUState *env)
+static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env)
 {
     ppc6xx_tlb_t *tlb;
     int nr, max;
@@ -330,7 +324,7 @@ static inline void ppc6xx_tlb_invalidate_all(CPUState *env)
     tlb_flush(env, 1);
 }
 
-static inline void __ppc6xx_tlb_invalidate_virt(CPUState *env,
+static inline void __ppc6xx_tlb_invalidate_virt(CPUPPCState *env,
                                                 target_ulong eaddr,
                                                 int is_code, int match_epn)
 {
@@ -355,13 +349,13 @@ static inline void __ppc6xx_tlb_invalidate_virt(CPUState *env,
 #endif
 }
 
-static inline void ppc6xx_tlb_invalidate_virt(CPUState *env,
+static inline void ppc6xx_tlb_invalidate_virt(CPUPPCState *env,
                                               target_ulong eaddr, int is_code)
 {
     __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
 }
 
-void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
+void ppc6xx_tlb_store (CPUPPCState *env, target_ulong EPN, int way, int is_code,
                        target_ulong pte0, target_ulong pte1)
 {
     ppc6xx_tlb_t *tlb;
@@ -371,7 +365,7 @@ void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
     tlb = &env->tlb.tlb6[nr];
     LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx
               " PTE1 " TARGET_FMT_lx "\n", nr, env->nb_tlb, EPN, pte0, pte1);
-    /* Invalidate any pending reference in Qemu for this virtual address */
+    /* Invalidate any pending reference in QEMU for this virtual address */
     __ppc6xx_tlb_invalidate_virt(env, EPN, is_code, 1);
     tlb->pte0 = pte0;
     tlb->pte1 = pte1;
@@ -380,7 +374,7 @@ void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
     env->last_way = way;
 }
 
-static inline int ppc6xx_tlb_check(CPUState *env, mmu_ctx_t *ctx,
+static inline int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx,
                                    target_ulong eaddr, int rw, int access_type)
 {
     ppc6xx_tlb_t *tlb;
@@ -442,7 +436,7 @@ static inline int ppc6xx_tlb_check(CPUState *env, mmu_ctx_t *ctx,
 }
 
 /* Perform BAT hit & translation */
-static inline void bat_size_prot(CPUState *env, target_ulong *blp, int *validp,
+static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp, int *validp,
                                  int *protp, target_ulong *BATu,
                                  target_ulong *BATl)
 {
@@ -467,7 +461,7 @@ static inline void bat_size_prot(CPUState *env, target_ulong *blp, int *validp,
     *protp = prot;
 }
 
-static inline void bat_601_size_prot(CPUState *env, target_ulong *blp,
+static inline void bat_601_size_prot(CPUPPCState *env, target_ulong *blp,
                                      int *validp, int *protp,
                                      target_ulong *BATu, target_ulong *BATl)
 {
@@ -492,7 +486,7 @@ static inline void bat_601_size_prot(CPUState *env, target_ulong *blp,
     *protp = prot;
 }
 
-static inline int get_bat(CPUState *env, mmu_ctx_t *ctx, target_ulong virtual,
+static inline int get_bat(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong virtual,
                           int rw, int type)
 {
     target_ulong *BATlt, *BATut, *BATu, *BATl;
@@ -567,7 +561,7 @@ static inline int get_bat(CPUState *env, mmu_ctx_t *ctx, target_ulong virtual,
     return ret;
 }
 
-static inline target_phys_addr_t get_pteg_offset(CPUState *env,
+static inline target_phys_addr_t get_pteg_offset(CPUPPCState *env,
                                                  target_phys_addr_t hash,
                                                  int pte_size)
 {
@@ -575,7 +569,7 @@ static inline target_phys_addr_t get_pteg_offset(CPUState *env,
 }
 
 /* PTE table lookup */
-static inline int _find_pte(CPUState *env, mmu_ctx_t *ctx, int is_64b, int h,
+static inline int _find_pte(CPUPPCState *env, mmu_ctx_t *ctx, int is_64b, int h,
                             int rw, int type, int target_page_bits)
 {
     target_phys_addr_t pteg_off;
@@ -597,12 +591,6 @@ static inline int _find_pte(CPUState *env, mmu_ctx_t *ctx, int is_64b, int h,
                 pte1 = ldq_phys(env->htab_base + pteg_off + (i * 16) + 8);
             }
 
-            /* We have a TLB that saves 4K pages, so let's
-             * split a huge page to 4k chunks */
-            if (target_page_bits != TARGET_PAGE_BITS)
-                pte1 |= (ctx->eaddr & (( 1 << target_page_bits ) - 1))
-                        & TARGET_PAGE_MASK;
-
             r = pte64_check(ctx, pte0, pte1, h, rw, type);
             LOG_MMU("Load pte from " TARGET_FMT_lx " => " TARGET_FMT_lx " "
                     TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
@@ -678,10 +666,16 @@ static inline int _find_pte(CPUState *env, mmu_ctx_t *ctx, int is_64b, int h,
         }
     }
 
+    /* We have a TLB that saves 4K pages, so let's
+     * split a huge page to 4k chunks */
+    if (target_page_bits != TARGET_PAGE_BITS) {
+        ctx->raddr |= (ctx->eaddr & ((1 << target_page_bits) - 1))
+                      & TARGET_PAGE_MASK;
+    }
     return ret;
 }
 
-static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
+static inline int find_pte(CPUPPCState *env, mmu_ctx_t *ctx, int h, int rw,
                            int type, int target_page_bits)
 {
 #if defined(TARGET_PPC64)
@@ -735,7 +729,7 @@ void ppc_slb_invalidate_all (CPUPPCState *env)
             slb->esid &= ~SLB_ESID_V;
             /* XXX: given the fact that segment size is 256 MB or 1TB,
              *      and we still don't have a tlb_flush_mask(env, n, mask)
-             *      in Qemu, we just invalidate all TLBs
+             *      in QEMU, we just invalidate all TLBs
              */
             do_invalidate = 1;
         }
@@ -758,7 +752,7 @@ void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
 
         /* XXX: given the fact that segment size is 256 MB or 1TB,
          *      and we still don't have a tlb_flush_mask(env, n, mask)
-         *      in Qemu, we just invalidate all TLBs
+         *      in QEMU, we just invalidate all TLBs
          */
         tlb_flush(env, 1);
     }
@@ -818,7 +812,7 @@ int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt)
 #endif /* defined(TARGET_PPC64) */
 
 /* Perform segment based translation */
-static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
+static inline int get_segment(CPUPPCState *env, mmu_ctx_t *ctx,
                               target_ulong eaddr, int rw, int type)
 {
     target_phys_addr_t hash;
@@ -1008,7 +1002,7 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
 }
 
 /* Generic TLB check function for embedded PowerPC implementations */
-int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb,
+int ppcemb_tlb_check(CPUPPCState *env, ppcemb_tlb_t *tlb,
                      target_phys_addr_t *raddrp,
                      target_ulong address, uint32_t pid, int ext,
                      int i)
@@ -1061,7 +1055,7 @@ int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid)
 }
 
 /* Helpers specific to PowerPC 40x implementations */
-static inline void ppc4xx_tlb_invalidate_all(CPUState *env)
+static inline void ppc4xx_tlb_invalidate_all(CPUPPCState *env)
 {
     ppcemb_tlb_t *tlb;
     int i;
@@ -1073,7 +1067,7 @@ static inline void ppc4xx_tlb_invalidate_all(CPUState *env)
     tlb_flush(env, 1);
 }
 
-static inline void ppc4xx_tlb_invalidate_virt(CPUState *env,
+static inline void ppc4xx_tlb_invalidate_virt(CPUPPCState *env,
                                               target_ulong eaddr, uint32_t pid)
 {
 #if !defined(FLUSH_ALL_TLBS)
@@ -1097,7 +1091,7 @@ static inline void ppc4xx_tlb_invalidate_virt(CPUState *env,
 #endif
 }
 
-static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
+static int mmu40x_get_physical_address (CPUPPCState *env, mmu_ctx_t *ctx,
                                  target_ulong address, int rw, int access_type)
 {
     ppcemb_tlb_t *tlb;
@@ -1168,7 +1162,7 @@ void store_40x_sler (CPUPPCState *env, uint32_t val)
     env->spr[SPR_405_SLER] = val;
 }
 
-static inline int mmubooke_check_tlb (CPUState *env, ppcemb_tlb_t *tlb,
+static inline int mmubooke_check_tlb (CPUPPCState *env, ppcemb_tlb_t *tlb,
                                       target_phys_addr_t *raddr, int *prot,
                                       target_ulong address, int rw,
                                       int access_type, int i)
@@ -1238,7 +1232,7 @@ found_tlb:
     return ret;
 }
 
-static int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
+static int mmubooke_get_physical_address (CPUPPCState *env, mmu_ctx_t *ctx,
                                           target_ulong address, int rw,
                                           int access_type)
 {
@@ -1270,7 +1264,7 @@ static int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
     return ret;
 }
 
-void booke206_flush_tlb(CPUState *env, int flags, const int check_iprot)
+void booke206_flush_tlb(CPUPPCState *env, int flags, const int check_iprot)
 {
     int tlb_size;
     int i, j;
@@ -1291,26 +1285,17 @@ void booke206_flush_tlb(CPUState *env, int flags, const int check_iprot)
     tlb_flush(env, 1);
 }
 
-target_phys_addr_t booke206_tlb_to_page_size(CPUState *env, ppcmas_tlb_t *tlb)
+target_phys_addr_t booke206_tlb_to_page_size(CPUPPCState *env, ppcmas_tlb_t *tlb)
 {
-    uint32_t tlbncfg;
-    int tlbn = booke206_tlbm_to_tlbn(env, tlb);
     int tlbm_size;
 
-    tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn];
-
-    if (tlbncfg & TLBnCFG_AVAIL) {
-        tlbm_size = (tlb->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
-    } else {
-        tlbm_size = (tlbncfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT;
-        tlbm_size <<= 1;
-    }
+    tlbm_size = (tlb->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
 
     return 1024ULL << tlbm_size;
 }
 
 /* TLB check function for MAS based SoftTLBs */
-int ppcmas_tlb_check(CPUState *env, ppcmas_tlb_t *tlb,
+int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb,
                      target_phys_addr_t *raddrp,
                      target_ulong address, uint32_t pid)
 {
@@ -1338,12 +1323,15 @@ int ppcmas_tlb_check(CPUState *env, ppcmas_tlb_t *tlb,
     if ((address & mask) != (tlb->mas2 & MAS2_EPN_MASK)) {
         return -1;
     }
-    *raddrp = (tlb->mas7_3 & mask) | (address & ~mask);
+
+    if (raddrp) {
+        *raddrp = (tlb->mas7_3 & mask) | (address & ~mask);
+    }
 
     return 0;
 }
 
-static int mmubooke206_check_tlb(CPUState *env, ppcmas_tlb_t *tlb,
+static int mmubooke206_check_tlb(CPUPPCState *env, ppcmas_tlb_t *tlb,
                                  target_phys_addr_t *raddr, int *prot,
                                  target_ulong address, int rw,
                                  int access_type)
@@ -1429,7 +1417,7 @@ found_tlb:
     return ret;
 }
 
-static int mmubooke206_get_physical_address(CPUState *env, mmu_ctx_t *ctx,
+static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
                                             target_ulong address, int rw,
                                             int access_type)
 {
@@ -1445,6 +1433,9 @@ static int mmubooke206_get_physical_address(CPUState *env, mmu_ctx_t *ctx,
 
         for (j = 0; j < ways; j++) {
             tlb = booke206_get_tlbm(env, i, address, j);
+            if (!tlb) {
+                continue;
+            }
             ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address,
                                         rw, access_type);
             if (ret != -1) {
@@ -1475,8 +1466,55 @@ static const char *book3e_tsize_to_str[32] = {
     "1T", "2T"
 };
 
+static void mmubooke_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
+                                 CPUPPCState *env)
+{
+    ppcemb_tlb_t *entry;
+    int i;
+
+    if (kvm_enabled() && !env->kvm_sw_tlb) {
+        cpu_fprintf(f, "Cannot access KVM TLB\n");
+        return;
+    }
+
+    cpu_fprintf(f, "\nTLB:\n");
+    cpu_fprintf(f, "Effective          Physical           Size PID   Prot     "
+                "Attr\n");
+
+    entry = &env->tlb.tlbe[0];
+    for (i = 0; i < env->nb_tlb; i++, entry++) {
+        target_phys_addr_t ea, pa;
+        target_ulong mask;
+        uint64_t size = (uint64_t)entry->size;
+        char size_buf[20];
+
+        /* Check valid flag */
+        if (!(entry->prot & PAGE_VALID)) {
+            continue;
+        }
+
+        mask = ~(entry->size - 1);
+        ea = entry->EPN & mask;
+        pa = entry->RPN & mask;
+#if (TARGET_PHYS_ADDR_BITS >= 36)
+        /* Extend the physical address to 36 bits */
+        pa |= (target_phys_addr_t)(entry->RPN & 0xF) << 32;
+#endif
+        size /= 1024;
+        if (size >= 1024) {
+            snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "M", size / 1024);
+        } else {
+            snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "k", size);
+        }
+        cpu_fprintf(f, "0x%016" PRIx64 " 0x%016" PRIx64 " %s %-5u %08x %08x\n",
+                    (uint64_t)ea, (uint64_t)pa, size_buf, (uint32_t)entry->PID,
+                    entry->prot, entry->attr);
+    }
+
+}
+
 static void mmubooke206_dump_one_tlb(FILE *f, fprintf_function cpu_fprintf,
-                                     CPUState *env, int tlbn, int offset,
+                                     CPUPPCState *env, int tlbn, int offset,
                                      int tlbsize)
 {
     ppcmas_tlb_t *entry;
@@ -1523,7 +1561,7 @@ static void mmubooke206_dump_one_tlb(FILE *f, fprintf_function cpu_fprintf,
 }
 
 static void mmubooke206_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
-                                 CPUState *env)
+                                 CPUPPCState *env)
 {
     int offset = 0;
     int i;
@@ -1545,18 +1583,49 @@ static void mmubooke206_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
     }
 }
 
-void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env)
+#if defined(TARGET_PPC64)
+static void mmubooks_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
+                              CPUPPCState *env)
+{
+    int i;
+    uint64_t slbe, slbv;
+
+    cpu_synchronize_state(env);
+
+    cpu_fprintf(f, "SLB\tESID\t\t\tVSID\n");
+    for (i = 0; i < env->slb_nr; i++) {
+        slbe = env->slb[i].esid;
+        slbv = env->slb[i].vsid;
+        if (slbe == 0 && slbv == 0) {
+            continue;
+        }
+        cpu_fprintf(f, "%d\t0x%016" PRIx64 "\t0x%016" PRIx64 "\n",
+                    i, slbe, slbv);
+    }
+}
+#endif
+
+void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
 {
     switch (env->mmu_model) {
+    case POWERPC_MMU_BOOKE:
+        mmubooke_dump_mmu(f, cpu_fprintf, env);
+        break;
     case POWERPC_MMU_BOOKE206:
         mmubooke206_dump_mmu(f, cpu_fprintf, env);
         break;
+#if defined(TARGET_PPC64)
+    case POWERPC_MMU_64B:
+    case POWERPC_MMU_2_06:
+        mmubooks_dump_mmu(f, cpu_fprintf, env);
+        break;
+#endif
     default:
         cpu_fprintf(f, "%s: unimplemented\n", __func__);
     }
 }
 
-static inline int check_physical(CPUState *env, mmu_ctx_t *ctx,
+static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx,
                                  target_ulong eaddr, int rw)
 {
     int in_plb, ret;
@@ -1622,7 +1691,7 @@ static inline int check_physical(CPUState *env, mmu_ctx_t *ctx,
     return ret;
 }
 
-int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
+int get_physical_address (CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr,
                           int rw, int access_type)
 {
     int ret;
@@ -1697,7 +1766,7 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
     return ret;
 }
 
-target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
+target_phys_addr_t cpu_get_phys_page_debug (CPUPPCState *env, target_ulong addr)
 {
     mmu_ctx_t ctx;
 
@@ -1707,7 +1776,7 @@ target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
     return ctx.raddr & TARGET_PAGE_MASK;
 }
 
-static void booke206_update_mas_tlb_miss(CPUState *env, target_ulong address,
+static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
                                      int rw)
 {
     env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
@@ -1748,7 +1817,7 @@ static void booke206_update_mas_tlb_miss(CPUState *env, target_ulong address,
 }
 
 /* Perform address translation */
-int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
+int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw,
                               int mmu_idx)
 {
     mmu_ctx_t ctx;
@@ -2300,7 +2369,7 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
     case POWERPC_MMU_2_06:
         /* tlbie invalidate TLBs for all segments */
         /* XXX: given the fact that there are too many segments to invalidate,
-         *      and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
+         *      and we still don't have a tlb_flush_mask(env, n, mask) in QEMU,
          *      we just invalidate all TLBs
          */
         tlb_flush(env, 1);
@@ -2415,19 +2484,19 @@ void ppc_store_msr (CPUPPCState *env, target_ulong value)
 /*****************************************************************************/
 /* Exception processing */
 #if defined (CONFIG_USER_ONLY)
-void do_interrupt (CPUState *env)
+void do_interrupt (CPUPPCState *env)
 {
     env->exception_index = POWERPC_EXCP_NONE;
     env->error_code = 0;
 }
 
-void ppc_hw_interrupt (CPUState *env)
+void ppc_hw_interrupt (CPUPPCState *env)
 {
     env->exception_index = POWERPC_EXCP_NONE;
     env->error_code = 0;
 }
 #else /* defined (CONFIG_USER_ONLY) */
-static inline void dump_syscall(CPUState *env)
+static inline void dump_syscall(CPUPPCState *env)
 {
     qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 " r3=%016" PRIx64
                   " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
@@ -2440,7 +2509,7 @@ static inline void dump_syscall(CPUState *env)
 /* Note that this function should be greatly optimized
  * when called with a constant excp, from ppc_hw_interrupt
  */
-static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
+static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
 {
     target_ulong msr, new_msr, vector;
     int srr0, srr1, asrr0, asrr1;
@@ -2670,22 +2739,10 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
                   "Performance counter exception is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */
-        /* XXX: TODO */
-        cpu_abort(env,
-                  "Embedded doorbell interrupt is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_DOORCI:    /* Embedded doorbell critical interrupt     */
-        switch (excp_model) {
-        case POWERPC_EXCP_BOOKE:
-            srr0 = SPR_BOOKE_CSRR0;
-            srr1 = SPR_BOOKE_CSRR1;
-            break;
-        default:
-            break;
-        }
-        /* XXX: TODO */
-        cpu_abort(env, "Embedded doorbell critical interrupt "
-                  "is not implemented yet !\n");
+        srr0 = SPR_BOOKE_CSRR0;
+        srr1 = SPR_BOOKE_CSRR1;
         goto store_next;
     case POWERPC_EXCP_RESET:     /* System reset exception                   */
         if (msr_pow) {
@@ -2953,7 +3010,7 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
     if (asrr1 != -1)
         env->spr[asrr1] = env->spr[srr1];
     /* If we disactivated any translation, flush TLBs */
-    if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR)))
+    if (msr & ((1 << MSR_IR) | (1 << MSR_DR)))
         tlb_flush(env, 1);
 
     if (msr_ile) {
@@ -3001,7 +3058,7 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
     }
 }
 
-void do_interrupt (CPUState *env)
+void do_interrupt (CPUPPCState *env)
 {
     powerpc_excp(env, env->excp_model, env->exception_index);
 }
@@ -3129,56 +3186,14 @@ void cpu_dump_rfi (target_ulong RA, target_ulong msr)
              TARGET_FMT_lx "\n", RA, msr);
 }
 
-void cpu_reset(CPUPPCState *env)
+void cpu_state_reset(CPUPPCState *env)
 {
-    target_ulong msr;
-
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
-        log_cpu_state(env, 0);
-    }
-
-    msr = (target_ulong)0;
-    if (0) {
-        /* XXX: find a suitable condition to enable the hypervisor mode */
-        msr |= (target_ulong)MSR_HVB;
-    }
-    msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
-    msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
-    msr |= (target_ulong)1 << MSR_EP;
-#if defined (DO_SINGLE_STEP) && 0
-    /* Single step trace mode */
-    msr |= (target_ulong)1 << MSR_SE;
-    msr |= (target_ulong)1 << MSR_BE;
-#endif
-#if defined(CONFIG_USER_ONLY)
-    msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
-    msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
-    msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
-    msr |= (target_ulong)1 << MSR_PR;
-#else
-    env->excp_prefix = env->hreset_excp_prefix;
-    env->nip = env->hreset_vector | env->excp_prefix;
-    if (env->mmu_model != POWERPC_MMU_REAL)
-        ppc_tlb_invalidate_all(env);
-#endif
-    env->msr = msr & env->msr_mask;
-#if defined(TARGET_PPC64)
-    if (env->mmu_model & POWERPC_MMU_64)
-        env->msr |= (1ULL << MSR_SF);
-#endif
-    hreg_compute_hflags(env);
-    env->reserve_addr = (target_ulong)-1ULL;
-    /* Be sure no exception or interrupt is pending */
-    env->pending_interrupts = 0;
-    env->exception_index = POWERPC_EXCP_NONE;
-    env->error_code = 0;
-    /* Flush all TLBs */
-    tlb_flush(env, 1);
+    cpu_reset(ENV_GET_CPU(env));
 }
 
 CPUPPCState *cpu_ppc_init (const char *cpu_model)
 {
+    PowerPCCPU *cpu;
     CPUPPCState *env;
     const ppc_def_t *def;
 
@@ -3186,20 +3201,13 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model)
     if (!def)
         return NULL;
 
-    env = g_malloc0(sizeof(CPUPPCState));
-    cpu_exec_init(env);
+    cpu = POWERPC_CPU(object_new(TYPE_POWERPC_CPU));
+    env = &cpu->env;
+
     if (tcg_enabled()) {
         ppc_translate_init();
     }
-    /* Adjust cpu index for SMT */
-#if !defined(CONFIG_USER_ONLY)
-    if (kvm_enabled()) {
-        int smt = kvmppc_smt_threads();
 
-        env->cpu_index = (env->cpu_index / smp_threads)*smt
-            + (env->cpu_index % smp_threads);
-    }
-#endif /* !CONFIG_USER_ONLY */
     env->cpu_model_str = cpu_model;
     cpu_ppc_register_internal(env, def);
 
@@ -3207,9 +3215,3 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model)
 
     return env;
 }
-
-void cpu_ppc_close (CPUPPCState *env)
-{
-    /* Should also remove all opcode tables... */
-    g_free(env);
-}
This page took 0.045977 seconds and 4 git commands to generate.