]> git.proxmox.com Git - qemu.git/blobdiff - target-ppc/helper.c
Large page TLB flush
[qemu.git] / target-ppc / helper.c
index 084d36f78b7c6b099f30dce0de3df7091f5b0fe7..c28223bd29bfec2da8faa99caaa83fbbf9ec27cd 100644 (file)
@@ -97,11 +97,6 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
     return 1;
 }
 
-target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
-{
-    return addr;
-}
-
 #else
 /* Common routines used by software and hardware TLBs emulation */
 static inline int pte_is_valid(target_ulong pte0)
@@ -736,14 +731,13 @@ static inline int slb_lookup(CPUPPCState *env, target_ulong eaddr,
                     PRIx32 "\n", __func__, n, slb->tmp64, slb->tmp);
         if (slb_is_valid(slb)) {
             /* SLB entry is valid */
+            mask = 0xFFFFFFFFF0000000ULL;
             if (slb->tmp & 0x8) {
-                /* 1 TB Segment */
-                mask = 0xFFFF000000000000ULL;
+                /* 16 MB PTEs */
                 if (target_page_bits)
-                    *target_page_bits = 24; // XXX 16M pages?
+                    *target_page_bits = 24;
             } else {
-                /* 256MB Segment */
-                mask = 0xFFFFFFFFF0000000ULL;
+                /* 4 KB PTEs */
                 if (target_page_bits)
                     *target_page_bits = TARGET_PAGE_BITS;
             }
@@ -1155,7 +1149,7 @@ static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
                              env->spr[SPR_40x_PID], 0, i) < 0)
             continue;
         zsel = (tlb->attr >> 4) & 0xF;
-        zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3;
+        zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3;
         LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
                     __func__, i, zsel, zpr, rw, tlb->attr);
         /* Check execute enable bit */
@@ -1171,6 +1165,8 @@ static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
             break;
         case 0x0:
             if (pr != 0) {
+                /* Raise Zone protection fault.  */
+                env->spr[SPR_40x_ESR] = 1 << 22;
                 ctx->prot = 0;
                 ret = -2;
                 break;
@@ -1183,6 +1179,8 @@ static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
             ctx->prot = tlb->prot;
             ctx->prot |= PAGE_EXEC;
             ret = check_prot(ctx->prot, rw, access_type);
+            if (ret == -2)
+                env->spr[SPR_40x_ESR] = 0;
             break;
         }
         if (ret >= 0) {
@@ -1412,9 +1410,10 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
     }
     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,
-                                mmu_idx, is_softmmu);
+        tlb_set_page(env, 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(env);
         if (access_type == ACCESS_CODE) {
@@ -1580,11 +1579,20 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                 /* Access rights violation */
                 env->exception_index = POWERPC_EXCP_DSI;
                 env->error_code = 0;
-                env->spr[SPR_DAR] = address;
-                if (rw == 1)
-                    env->spr[SPR_DSISR] = 0x0A000000;
-                else
-                    env->spr[SPR_DSISR] = 0x08000000;
+                if (env->mmu_model == POWERPC_MMU_SOFT_4xx
+                    || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) {
+                    env->spr[SPR_40x_DEAR] = address;
+                    if (rw) {
+                        env->spr[SPR_40x_ESR] |= 0x00800000;
+                    }
+                } else {
+                    env->spr[SPR_DAR] = address;
+                    if (rw == 1) {
+                        env->spr[SPR_DSISR] = 0x0A000000;
+                    } else {
+                        env->spr[SPR_DSISR] = 0x08000000;
+                    }
+                }
                 break;
             case -4:
                 /* Direct store exception */
@@ -2748,9 +2756,8 @@ void cpu_dump_rfi (target_ulong RA, target_ulong msr)
              TARGET_FMT_lx "\n", RA, msr);
 }
 
-void cpu_ppc_reset (void *opaque)
+void cpu_reset(CPUPPCState *env)
 {
-    CPUPPCState *env = opaque;
     target_ulong msr;
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
@@ -2811,9 +2818,6 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model)
     ppc_translate_init();
     env->cpu_model_str = cpu_model;
     cpu_ppc_register_internal(env, def);
-#if defined(CONFIG_USER_ONLY)
-    cpu_ppc_reset(env);
-#endif
 
     qemu_init_vcpu(env);