[RFC PATCH 17/18] target/riscv: Pass first/last to get_physical_address_pmp
Richard Henderson <[email protected]>
| Newsgroups | org.nongnu.qemu-arm,org.nongnu.qemu-devel,org.nongnu.qemu-riscv |
|---|---|
| Message-ID | <[email protected]> |
Signed-off-by: Richard Henderson <[email protected]> --- target/riscv/tcg/cpu_helper.c | 48 +++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/target/riscv/tcg/cpu_helper.c b/target/riscv/tcg/cpu_helper.c index 3318e82ea7..fb1250a4b8 100644 --- a/target/riscv/tcg/cpu_helper.c +++ b/target/riscv/tcg/cpu_helper.c @@ -899,12 +899,13 @@ void riscv_cpu_set_mode(CPURISCVState *env, privilege_mode_t newpriv, * * @env: CPURISCVState * @prot: The returned protection attributes - * @addr: The physical address to be checked permission + * @first, @last: The physical address range to be permission checked * @access_type: The type of MMU access * @mode: Indicates current privilege level. */ -static int get_physical_address_pmp(CPURISCVState *env, int *prot, hwaddr addr, - int size, MMUAccessType access_type, +static int get_physical_address_pmp(CPURISCVState *env, int *prot, + hwaddr first, hwaddr last, + MMUAccessType access_type, privilege_mode_t mode) { pmp_priv_t pmp_priv; @@ -915,8 +916,8 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot, hwaddr addr, return TRANSLATE_SUCCESS; } - pmp_has_privs = pmp_hart_has_privs(env, addr, size, 1 << access_type, - &pmp_priv, mode); + pmp_has_privs = pmp_hart_has_privs(env, first, last - first + 1, + 1 << access_type, &pmp_priv, mode); if (!pmp_has_privs) { *prot = 0; return TRANSLATE_PMP_FAIL; @@ -1142,6 +1143,8 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical, base = base_root; for (i = 0; i < levels; i++, ptshift -= ptidxbits) { target_ulong idx; + int pmp_prot, pmp_ret; + if (i == 0) { idx = (addr >> (PGSHIFT + ptshift)) & ((1 << (ptidxbits + widened)) - 1); @@ -1174,10 +1177,9 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical, pte_addr = base + idx * ptesize; } - int pmp_prot; - int pmp_ret = get_physical_address_pmp(env, &pmp_prot, pte_addr, - sxlen_bytes, - MMU_DATA_LOAD, PRV_S); + pmp_ret = get_physical_address_pmp(env, &pmp_prot, pte_addr, + pte_addr + sxlen_bytes - 1, + MMU_DATA_LOAD, PRV_S); if (pmp_ret != TRANSLATE_SUCCESS) { return TRANSLATE_PMP_FAIL; } @@ -1425,7 +1427,8 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical, } pmp_ret = get_physical_address_pmp(env, &pmp_prot, pte_addr, - sxlen_bytes, MMU_DATA_STORE, PRV_S); + pte_addr + sxlen_bytes - 1, + MMU_DATA_STORE, PRV_S); if (pmp_ret != TRANSLATE_SUCCESS) { return TRANSLATE_PMP_FAIL; } @@ -1655,8 +1658,6 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, vaddr first, vaddr last, { RISCVCPU *cpu = RISCV_CPU(cs); CPURISCVState *env = &cpu->env; - int size = last - address + 1; - vaddr im_address; hwaddr pa = 0; int prot, prot2, prot_pmp; bool pmp_pma_violation = false; @@ -1676,7 +1677,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, vaddr first, vaddr last, pmu_tlb_fill_incr_ctr(cpu, access_type); if (two_stage_lookup) { /* Two stage lookup */ - ret = get_physical_address(env, &pa, &prot, address, + ret = get_physical_address(env, &pa, &prot, first, &env->guest_phys_fault_addr, access_type, mmu_idx, true, true, false, probe); /* @@ -1692,11 +1693,11 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, vaddr first, vaddr last, qemu_log_mask(CPU_LOG_MMU, "%s 1st-stage address=%" VADDR_PRIx " ret %d physical " HWADDR_FMT_plx " prot %d\n", - __func__, address, ret, pa, prot); + __func__, first, ret, pa, prot); if (ret == TRANSLATE_SUCCESS) { /* Second stage lookup */ - im_address = pa; + vaddr im_address = pa; ret = get_physical_address(env, &pa, &prot2, im_address, NULL, access_type, MMUIdx_U, false, true, @@ -1711,8 +1712,9 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, vaddr first, vaddr last, prot &= prot2; if (ret == TRANSLATE_SUCCESS) { - ret = get_physical_address_pmp(env, &prot_pmp, pa, - size, access_type, mode); + ret = get_physical_address_pmp(env, &prot_pmp, + pa, pa + (last - first), + access_type, mode); tlb_size = pmp_get_tlb_size(env, pa); qemu_log_mask(CPU_LOG_MMU, @@ -1736,18 +1738,19 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, vaddr first, vaddr last, } } else { /* Single stage lookup */ - ret = get_physical_address(env, &pa, &prot, address, NULL, + ret = get_physical_address(env, &pa, &prot, first, NULL, access_type, mmu_idx, true, false, false, probe); qemu_log_mask(CPU_LOG_MMU, "%s address=%" VADDR_PRIx " ret %d physical " HWADDR_FMT_plx " prot %d\n", - __func__, address, ret, pa, prot); + __func__, first, ret, pa, prot); if (ret == TRANSLATE_SUCCESS) { - ret = get_physical_address_pmp(env, &prot_pmp, pa, - size, access_type, mode); + ret = get_physical_address_pmp(env, &prot_pmp, + pa, pa + (last - first), + access_type, mode); tlb_size = pmp_get_tlb_size(env, pa); qemu_log_mask(CPU_LOG_MMU, @@ -1764,7 +1767,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, vaddr first, vaddr last, } if (ret == TRANSLATE_SUCCESS) { - tlb_set_page(cs, address & ~(tlb_size - 1), pa & ~(tlb_size - 1), + tlb_set_page(cs, address & ~(tlb_size - 1), + (pa + (address - first)) & ~(tlb_size - 1), prot, mmu_idx, tlb_size); return true; } else if (probe) { -- 2.43.0