Loading target/riscv/cpu_helper.c +28 −9 Original line number Diff line number Diff line Loading @@ -277,10 +277,19 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv) * * Adapted from Spike's mmu_t::translate and mmu_t::walk * * @env: CPURISCVState * @physical: This will be set to the calculated physical address * @prot: The returned protection attributes * @addr: The virtual address to be translated * @access_type: The type of MMU access * @mmu_idx: Indicates current privilege level * @first_stage: Are we in first stage translation? * Second stage is used for hypervisor guest translation */ static int get_physical_address(CPURISCVState *env, hwaddr *physical, int *prot, target_ulong addr, int access_type, int mmu_idx) int access_type, int mmu_idx, bool first_stage) { /* NOTE: the env->pc value visible here will not be * correct, but the value visible to the exception handler Loading Loading @@ -485,13 +494,21 @@ restart: } static void raise_mmu_exception(CPURISCVState *env, target_ulong address, MMUAccessType access_type, bool pmp_violation) MMUAccessType access_type, bool pmp_violation, bool first_stage) { CPUState *cs = env_cpu(env); int page_fault_exceptions = int page_fault_exceptions; if (first_stage) { page_fault_exceptions = (env->priv_ver >= PRIV_VERSION_1_10_0) && get_field(env->satp, SATP_MODE) != VM_1_10_MBARE && !pmp_violation; } else { page_fault_exceptions = get_field(env->hgatp, HGATP_MODE) != VM_1_10_MBARE && !pmp_violation; } switch (access_type) { case MMU_INST_FETCH: cs->exception_index = page_fault_exceptions ? Loading @@ -518,7 +535,8 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) int prot; int mmu_idx = cpu_mmu_index(&cpu->env, false); if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0, mmu_idx)) { if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0, mmu_idx, true)) { return -1; } return phys_addr; Loading Loading @@ -583,7 +601,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n", __func__, address, access_type, mmu_idx); ret = get_physical_address(env, &pa, &prot, address, access_type, mmu_idx); ret = get_physical_address(env, &pa, &prot, address, access_type, mmu_idx, true); if (mode == PRV_M && access_type != MMU_INST_FETCH) { if (get_field(env->mstatus, MSTATUS_MPRV)) { Loading @@ -610,7 +629,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, } else if (probe) { return false; } else { raise_mmu_exception(env, address, access_type, pmp_violation); raise_mmu_exception(env, address, access_type, pmp_violation, true); riscv_raise_exception(env, cs->exception_index, retaddr); } #else Loading Loading
target/riscv/cpu_helper.c +28 −9 Original line number Diff line number Diff line Loading @@ -277,10 +277,19 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv) * * Adapted from Spike's mmu_t::translate and mmu_t::walk * * @env: CPURISCVState * @physical: This will be set to the calculated physical address * @prot: The returned protection attributes * @addr: The virtual address to be translated * @access_type: The type of MMU access * @mmu_idx: Indicates current privilege level * @first_stage: Are we in first stage translation? * Second stage is used for hypervisor guest translation */ static int get_physical_address(CPURISCVState *env, hwaddr *physical, int *prot, target_ulong addr, int access_type, int mmu_idx) int access_type, int mmu_idx, bool first_stage) { /* NOTE: the env->pc value visible here will not be * correct, but the value visible to the exception handler Loading Loading @@ -485,13 +494,21 @@ restart: } static void raise_mmu_exception(CPURISCVState *env, target_ulong address, MMUAccessType access_type, bool pmp_violation) MMUAccessType access_type, bool pmp_violation, bool first_stage) { CPUState *cs = env_cpu(env); int page_fault_exceptions = int page_fault_exceptions; if (first_stage) { page_fault_exceptions = (env->priv_ver >= PRIV_VERSION_1_10_0) && get_field(env->satp, SATP_MODE) != VM_1_10_MBARE && !pmp_violation; } else { page_fault_exceptions = get_field(env->hgatp, HGATP_MODE) != VM_1_10_MBARE && !pmp_violation; } switch (access_type) { case MMU_INST_FETCH: cs->exception_index = page_fault_exceptions ? Loading @@ -518,7 +535,8 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) int prot; int mmu_idx = cpu_mmu_index(&cpu->env, false); if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0, mmu_idx)) { if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0, mmu_idx, true)) { return -1; } return phys_addr; Loading Loading @@ -583,7 +601,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n", __func__, address, access_type, mmu_idx); ret = get_physical_address(env, &pa, &prot, address, access_type, mmu_idx); ret = get_physical_address(env, &pa, &prot, address, access_type, mmu_idx, true); if (mode == PRV_M && access_type != MMU_INST_FETCH) { if (get_field(env->mstatus, MSTATUS_MPRV)) { Loading @@ -610,7 +629,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, } else if (probe) { return false; } else { raise_mmu_exception(env, address, access_type, pmp_violation); raise_mmu_exception(env, address, access_type, pmp_violation, true); riscv_raise_exception(env, cs->exception_index, retaddr); } #else Loading