diff options
author | TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com> | 2024-09-19 13:50:44 +0800 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2024-10-30 11:22:07 +1000 |
commit | 870589dcddcc542d88c5f0cdd9b2b43becc8a070 (patch) | |
tree | 331df51c433855266b06d8c29497a82987620df0 /target | |
parent | 929e4277c128772bad41cc795995f754cb9991af (diff) |
target/riscv: Detect sxl to set bit width for RV32 in RV64
Ensure correct bit width based on sxl when running RV32 on RV64 QEMU.
This is required as MMU address translations run in S-mode.
Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20240919055048.562-5-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target')
-rw-r--r-- | target/riscv/cpu_helper.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index a935377b4a..621bf4c1b8 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -890,12 +890,14 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical, CPUState *cs = env_cpu(env); int va_bits = PGSHIFT + levels * ptidxbits + widened; + int sxlen = 16 << riscv_cpu_sxl(env); + int sxlen_bytes = sxlen / 8; if (first_stage == true) { target_ulong mask, masked_msbs; - if (TARGET_LONG_BITS > (va_bits - 1)) { - mask = (1L << (TARGET_LONG_BITS - (va_bits - 1))) - 1; + if (sxlen > (va_bits - 1)) { + mask = (1L << (sxlen - (va_bits - 1))) - 1; } else { mask = 0; } @@ -964,7 +966,7 @@ restart: int pmp_prot; int pmp_ret = get_physical_address_pmp(env, &pmp_prot, pte_addr, - sizeof(target_ulong), + sxlen_bytes, MMU_DATA_LOAD, PRV_S); if (pmp_ret != TRANSLATE_SUCCESS) { return TRANSLATE_PMP_FAIL; @@ -1116,7 +1118,7 @@ restart: * it is no longer valid and we must re-walk the page table. */ MemoryRegion *mr; - hwaddr l = sizeof(target_ulong), addr1; + hwaddr l = sxlen_bytes, addr1; mr = address_space_translate(cs->as, pte_addr, &addr1, &l, false, MEMTXATTRS_UNSPECIFIED); if (memory_region_is_ram(mr)) { @@ -1128,7 +1130,12 @@ restart: */ *pte_pa = pte = updated_pte; #else - target_ulong old_pte = qatomic_cmpxchg(pte_pa, pte, updated_pte); + target_ulong old_pte; + if (riscv_cpu_sxl(env) == MXL_RV32) { + old_pte = qatomic_cmpxchg((uint32_t *)pte_pa, pte, updated_pte); + } else { + old_pte = qatomic_cmpxchg(pte_pa, pte, updated_pte); + } if (old_pte != pte) { goto restart; } |