mxr = get_field(env->vsstatus, MSTATUS_MXR);
}
- if (env->priv_ver >= PRIV_VERSION_1_10_0) {
- if (first_stage == true) {
- if (use_background) {
- base = (hwaddr)get_field(env->vsatp, SATP_PPN) << PGSHIFT;
- vm = get_field(env->vsatp, SATP_MODE);
- } else {
- base = (hwaddr)get_field(env->satp, SATP_PPN) << PGSHIFT;
- vm = get_field(env->satp, SATP_MODE);
- }
- widened = 0;
+ if (first_stage == true) {
+ if (use_background) {
+ base = (hwaddr)get_field(env->vsatp, SATP_PPN) << PGSHIFT;
+ vm = get_field(env->vsatp, SATP_MODE);
} else {
- base = (hwaddr)get_field(env->hgatp, HGATP_PPN) << PGSHIFT;
- vm = get_field(env->hgatp, HGATP_MODE);
- widened = 2;
- }
- sum = get_field(env->mstatus, MSTATUS_SUM);
- switch (vm) {
- case VM_1_10_SV32:
- levels = 2; ptidxbits = 10; ptesize = 4; break;
- case VM_1_10_SV39:
- levels = 3; ptidxbits = 9; ptesize = 8; break;
- case VM_1_10_SV48:
- levels = 4; ptidxbits = 9; ptesize = 8; break;
- case VM_1_10_SV57:
- levels = 5; ptidxbits = 9; ptesize = 8; break;
- case VM_1_10_MBARE:
- *physical = addr;
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- return TRANSLATE_SUCCESS;
- default:
- g_assert_not_reached();
+ base = (hwaddr)get_field(env->satp, SATP_PPN) << PGSHIFT;
+ vm = get_field(env->satp, SATP_MODE);
}
- } else {
widened = 0;
- base = (hwaddr)(env->sptbr) << PGSHIFT;
- sum = !get_field(env->mstatus, MSTATUS_PUM);
- vm = get_field(env->mstatus, MSTATUS_VM);
- switch (vm) {
- case VM_1_09_SV32:
- levels = 2; ptidxbits = 10; ptesize = 4; break;
- case VM_1_09_SV39:
- levels = 3; ptidxbits = 9; ptesize = 8; break;
- case VM_1_09_SV48:
- levels = 4; ptidxbits = 9; ptesize = 8; break;
- case VM_1_09_MBARE:
- *physical = addr;
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- return TRANSLATE_SUCCESS;
- default:
- g_assert_not_reached();
- }
+ } else {
+ base = (hwaddr)get_field(env->hgatp, HGATP_PPN) << PGSHIFT;
+ vm = get_field(env->hgatp, HGATP_MODE);
+ widened = 2;
+ }
+ sum = get_field(env->mstatus, MSTATUS_SUM);
+ switch (vm) {
+ case VM_1_10_SV32:
+ levels = 2; ptidxbits = 10; ptesize = 4; break;
+ case VM_1_10_SV39:
+ levels = 3; ptidxbits = 9; ptesize = 8; break;
+ case VM_1_10_SV48:
+ levels = 4; ptidxbits = 9; ptesize = 8; break;
+ case VM_1_10_SV57:
+ levels = 5; ptidxbits = 9; ptesize = 8; break;
+ case VM_1_10_MBARE:
+ *physical = addr;
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ return TRANSLATE_SUCCESS;
+ default:
+ g_assert_not_reached();
}
CPUState *cs = env_cpu(env);
hwaddr pte_addr;
if (two_stage && first_stage) {
+ int vbase_prot;
hwaddr vbase;
/* Do the second stage translation on the base PTE address. */
- get_physical_address(env, &vbase, prot, base, access_type,
+ get_physical_address(env, &vbase, &vbase_prot, base, MMU_DATA_LOAD,
mmu_idx, false, true);
pte_addr = vbase + idx * ptesize;
/* for superpage mappings, make a fake leaf PTE for the TLB's
benefit. */
target_ulong vpn = addr >> PGSHIFT;
- if (i == 0) {
- *physical = (ppn | (vpn & ((1L << (ptshift + widened)) - 1))) <<
- PGSHIFT;
- } else {
- *physical = (ppn | (vpn & ((1L << ptshift) - 1))) << PGSHIFT;
- }
+ *physical = (ppn | (vpn & ((1L << ptshift) - 1))) << PGSHIFT;
/* set permissions on the TLB entry */
if ((pte & PTE_R) || ((pte & PTE_X) && mxr)) {
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 {
#ifndef CONFIG_USER_ONLY
vaddr im_address;
hwaddr pa = 0;
- int prot;
+ int prot, prot2;
bool pmp_violation = false;
bool m_mode_two_stage = false;
bool hs_mode_two_stage = false;
/* Second stage lookup */
im_address = pa;
- ret = get_physical_address(env, &pa, &prot, im_address,
+ ret = get_physical_address(env, &pa, &prot2, im_address,
access_type, mmu_idx, false, true);
qemu_log_mask(CPU_LOG_MMU,
"%s 2nd-stage address=%" VADDR_PRIx " ret %d physical "
TARGET_FMT_plx " prot %d\n",
- __func__, im_address, ret, pa, prot);
+ __func__, im_address, ret, pa, prot2);
+
+ prot &= prot2;
if (riscv_feature(env, RISCV_FEATURE_PMP) &&
(ret == TRANSLATE_SUCCESS) &&
}
s = env->mstatus;
- s = set_field(s, MSTATUS_SPIE, env->priv_ver >= PRIV_VERSION_1_10_0 ?
- get_field(s, MSTATUS_SIE) : get_field(s, MSTATUS_UIE << env->priv));
+ s = set_field(s, MSTATUS_SPIE, get_field(s, MSTATUS_SIE));
s = set_field(s, MSTATUS_SPP, env->priv);
s = set_field(s, MSTATUS_SIE, 0);
env->mstatus = s;
}
s = env->mstatus;
- s = set_field(s, MSTATUS_MPIE, env->priv_ver >= PRIV_VERSION_1_10_0 ?
- get_field(s, MSTATUS_MIE) : get_field(s, MSTATUS_UIE << env->priv));
+ s = set_field(s, MSTATUS_MPIE, get_field(s, MSTATUS_MIE));
s = set_field(s, MSTATUS_MPP, env->priv);
s = set_field(s, MSTATUS_MIE, 0);
env->mstatus = s;