?? helper.c
字號:
break; case 0x0: if (pr != 0) { ctx->prot = 0; ret = -2; break; } /* No break here */ case 0x1: check_perms: /* Check from TLB entry */ /* XXX: there is a problem here or in the TLB fill code... */ ctx->prot = tlb->prot; ctx->prot |= PAGE_EXEC; ret = check_prot(ctx->prot, rw, access_type); break; } if (ret >= 0) { ctx->raddr = raddr;#if defined (DEBUG_SOFTWARE_TLB) if (loglevel != 0) { fprintf(logfile, "%s: access granted " ADDRX " => " PADDRX " %d %d\n", __func__, address, ctx->raddr, ctx->prot, ret); }#endif return 0; } }#if defined (DEBUG_SOFTWARE_TLB) if (loglevel != 0) { fprintf(logfile, "%s: access refused " ADDRX " => " PADDRX " %d %d\n", __func__, address, raddr, ctx->prot, ret); }#endif return ret;}void store_40x_sler (CPUPPCState *env, uint32_t val){ /* XXX: TO BE FIXED */ if (val != 0x00000000) { cpu_abort(env, "Little-endian regions are not supported by now\n"); } env->spr[SPR_405_SLER] = val;}int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong address, int rw, int access_type){ ppcemb_tlb_t *tlb; target_phys_addr_t raddr; int i, prot, ret; ret = -1; raddr = (target_phys_addr_t)-1ULL; for (i = 0; i < env->nb_tlb; i++) { tlb = &env->tlb[i].tlbe; if (ppcemb_tlb_check(env, tlb, &raddr, address, env->spr[SPR_BOOKE_PID], 1, i) < 0) continue; if (msr_pr != 0) prot = tlb->prot & 0xF; else prot = (tlb->prot >> 4) & 0xF; /* Check the address space */ if (access_type == ACCESS_CODE) { if (msr_ir != (tlb->attr & 1)) continue; ctx->prot = prot; if (prot & PAGE_EXEC) { ret = 0; break; } ret = -3; } else { if (msr_dr != (tlb->attr & 1)) continue; ctx->prot = prot; if ((!rw && prot & PAGE_READ) || (rw && (prot & PAGE_WRITE))) { ret = 0; break; } ret = -2; } } if (ret >= 0) ctx->raddr = raddr; return ret;}static always_inline int check_physical (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw){ int in_plb, ret; ctx->raddr = eaddr; ctx->prot = PAGE_READ | PAGE_EXEC; 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: case POWERPC_MMU_REAL: case POWERPC_MMU_BOOKE: ctx->prot |= PAGE_WRITE; break;#if defined(TARGET_PPC64) case POWERPC_MMU_620: case POWERPC_MMU_64B: /* Real address are 60 bits long */ ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL; ctx->prot |= PAGE_WRITE; break;#endif case POWERPC_MMU_SOFT_4xx_Z: if (unlikely(msr_pe != 0)) { /* 403 family add some particular protections, * using PBL/PBU registers for accesses with no translation. */ in_plb = /* Check PLB validity */ (env->pb[0] < env->pb[1] && /* and address in plb area */ eaddr >= env->pb[0] && eaddr < env->pb[1]) || (env->pb[2] < env->pb[3] && eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0; if (in_plb ^ msr_px) { /* Access in protected area */ if (rw == 1) { /* Access is not allowed */ ret = -2; } } else { /* Read-write access is allowed */ ctx->prot |= PAGE_WRITE; } } break; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ cpu_abort(env, "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_BOOKE_FSL: /* XXX: TODO */ cpu_abort(env, "BookE FSL MMU model not implemented\n"); break; default: cpu_abort(env, "Unknown or invalid MMU model\n"); return -1; } return ret;}int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw, int access_type){ int ret;#if 0 if (loglevel != 0) { fprintf(logfile, "%s\n", __func__); }#endif if ((access_type == ACCESS_CODE && msr_ir == 0) || (access_type != ACCESS_CODE && msr_dr == 0)) { /* No address translation */ ret = check_physical(env, ctx, eaddr, rw); } else { ret = -1; switch (env->mmu_model) { case POWERPC_MMU_32B: case POWERPC_MMU_601: case POWERPC_MMU_SOFT_6xx: case POWERPC_MMU_SOFT_74xx:#if defined(TARGET_PPC64) case POWERPC_MMU_620: 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); } break; case POWERPC_MMU_SOFT_4xx: case POWERPC_MMU_SOFT_4xx_Z: ret = mmu40x_get_physical_address(env, ctx, eaddr, rw, access_type); break; case POWERPC_MMU_BOOKE: ret = mmubooke_get_physical_address(env, ctx, eaddr, rw, access_type); break; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ cpu_abort(env, "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_BOOKE_FSL: /* XXX: TODO */ cpu_abort(env, "BookE FSL MMU model not implemented\n"); return -1; case POWERPC_MMU_REAL: cpu_abort(env, "PowerPC in real mode do not do any translation\n"); return -1; default: cpu_abort(env, "Unknown or invalid MMU model\n"); return -1; } }#if 0 if (loglevel != 0) { fprintf(logfile, "%s address " ADDRX " => %d " PADDRX "\n", __func__, eaddr, ret, ctx->raddr); }#endif return ret;}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) != 0)) return -1; return ctx.raddr & TARGET_PAGE_MASK;}/* Perform address translation */int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, int mmu_idx, int is_softmmu){ mmu_ctx_t ctx; int access_type; int ret = 0; if (rw == 2) { /* code access */ rw = 0; access_type = ACCESS_CODE; } else { /* data access */ /* XXX: put correct access by using cpu_restore_state() correctly */ access_type = ACCESS_INT; // access_type = env->access_type; } 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); } else if (ret < 0) {#if defined (DEBUG_MMU) if (loglevel != 0) cpu_dump_state(env, logfile, fprintf, 0);#endif if (access_type == ACCESS_CODE) { switch (ret) { case -1: /* No matches in page tables or TLB */ switch (env->mmu_model) { case POWERPC_MMU_SOFT_6xx: env->exception_index = POWERPC_EXCP_IFTLB; env->error_code = 1 << 18; env->spr[SPR_IMISS] = address; env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem; goto tlb_miss; case POWERPC_MMU_SOFT_74xx: env->exception_index = POWERPC_EXCP_IFTLB; goto tlb_miss_74xx; case POWERPC_MMU_SOFT_4xx: case POWERPC_MMU_SOFT_4xx_Z: env->exception_index = POWERPC_EXCP_ITLB; env->error_code = 0; env->spr[SPR_40x_DEAR] = address; env->spr[SPR_40x_ESR] = 0x00000000; break; case POWERPC_MMU_32B: case POWERPC_MMU_601:#if defined(TARGET_PPC64) case POWERPC_MMU_620: case POWERPC_MMU_64B:#endif env->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x40000000; break; case POWERPC_MMU_BOOKE: /* XXX: TODO */ cpu_abort(env, "BookE MMU model is not implemented\n"); return -1; case POWERPC_MMU_BOOKE_FSL: /* XXX: TODO */ cpu_abort(env, "BookE FSL MMU model is not implemented\n"); return -1; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ cpu_abort(env, "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_REAL: cpu_abort(env, "PowerPC in real mode should never raise " "any MMU exceptions\n"); return -1; default: cpu_abort(env, "Unknown or invalid MMU model\n"); return -1; } break; case -2: /* Access rights violation */ env->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x08000000; break; case -3: /* No execute protection violation */ env->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x10000000; break; case -4: /* Direct store exception */ /* No code fetch is allowed in direct-store areas */ env->exception_index = POWERPC_EXCP_ISI; env->error_code = 0x10000000; break;#if defined(TARGET_PPC64) case -5: /* No match in segment table */ if (env->mmu_model == POWERPC_MMU_620) { env->exception_index = POWERPC_EXCP_ISI; /* XXX: this might be incorrect */ env->error_code = 0x40000000; } else { env->exception_index = POWERPC_EXCP_ISEG; env->error_code = 0; } break;#endif } } else { switch (ret) { case -1: /* No matches in page tables or TLB */ switch (env->mmu_model) { case POWERPC_MMU_SOFT_6xx: if (rw == 1) { env->exception_index = POWERPC_EXCP_DSTLB; env->error_code = 1 << 16; } else { env->exception_index = POWERPC_EXCP_DLTLB; env->error_code = 0; } env->spr[SPR_DMISS] = address; env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem; tlb_miss: env->error_code |= ctx.key << 19; env->spr[SPR_HASH1] = ctx.pg_addr[0]; env->spr[SPR_HASH2] = ctx.pg_addr[1]; break; case POWERPC_MMU_SOFT_74xx: if (rw == 1) { env->exception_index = POWERPC_EXCP_DSTLB; } else { env->exception_index = POWERPC_EXCP_DLTLB; } tlb_miss_74xx: /* Implement LRU algorithm */ env->error_code = ctx.key << 19; env->spr[SPR_TLBMISS] = (address & ~((target_ulong)0x3)) | ((env->last_way + 1) & (env->nb_ways - 1)); env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem; break; case POWERPC_MMU_SOFT_4xx: case POWERPC_MMU_SOFT_4xx_Z: env->exception_index = POWERPC_EXCP_DTLB; env->error_code = 0; env->spr[SPR_40x_DEAR] = address; if (rw) env->spr[SPR_40x_ESR] = 0x00800000; else env->spr[SPR_40x_ESR] = 0x00000000; break; case POWERPC_MMU_32B: case POWERPC_MMU_601:#if defined(TARGET_PPC64) case POWERPC_MMU_620: case POWERPC_MMU_64B:#endif env->exception_index = POWERPC_EXCP_DSI; env->error_code = 0; env->spr[SPR_DAR] = address; if (rw == 1) env->spr[SPR_DSISR] = 0x42000000; else env->spr[SPR_DSISR] = 0x40000000; break; case POWERPC_MMU_MPC8xx: /* XXX: TODO */ cpu_abort(env, "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_BOOKE: /* XXX: TODO */ cpu_abort(env, "BookE MMU model is not implemented\n");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -