diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2023-04-12 13:43:16 +0200 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2023-05-02 13:05:45 -0700 |
commit | 2899062614ab68ffcd034909b5ea993d8403d6d6 (patch) | |
tree | 41395a79f587056926c79c0dd2919d66c6810776 /accel | |
parent | dc165fcd4effb9e005a4514ab7d666322648e971 (diff) |
accel/tcg: Add cpu_ld*_code_mmu
At least RISC-V has the need to be able to perform a read
using execute permissions, outside of translation.
Add helpers to facilitate this.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-Id: <20230325105429.1142530-9-richard.henderson@linaro.org>
Message-Id: <20230412114333.118895-9-richard.henderson@linaro.org>
Diffstat (limited to 'accel')
-rw-r--r-- | accel/tcg/cputlb.c | 48 | ||||
-rw-r--r-- | accel/tcg/user-exec.c | 58 |
2 files changed, 106 insertions, 0 deletions
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index efa0cb67c9..c8bd642d0e 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -2773,3 +2773,51 @@ uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr) MemOpIdx oi = make_memop_idx(MO_TEUQ, cpu_mmu_index(env, true)); return full_ldq_code(env, addr, oi, 0); } + +uint8_t cpu_ldb_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t retaddr) +{ + return full_ldub_code(env, addr, oi, retaddr); +} + +uint16_t cpu_ldw_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t retaddr) +{ + MemOp mop = get_memop(oi); + int idx = get_mmuidx(oi); + uint16_t ret; + + ret = full_lduw_code(env, addr, make_memop_idx(MO_TEUW, idx), retaddr); + if ((mop & MO_BSWAP) != MO_TE) { + ret = bswap16(ret); + } + return ret; +} + +uint32_t cpu_ldl_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t retaddr) +{ + MemOp mop = get_memop(oi); + int idx = get_mmuidx(oi); + uint32_t ret; + + ret = full_ldl_code(env, addr, make_memop_idx(MO_TEUL, idx), retaddr); + if ((mop & MO_BSWAP) != MO_TE) { + ret = bswap32(ret); + } + return ret; +} + +uint64_t cpu_ldq_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t retaddr) +{ + MemOp mop = get_memop(oi); + int idx = get_mmuidx(oi); + uint64_t ret; + + ret = full_ldq_code(env, addr, make_memop_idx(MO_TEUQ, idx), retaddr); + if ((mop & MO_BSWAP) != MO_TE) { + ret = bswap64(ret); + } + return ret; +} diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index a7e0c3e2f4..fc597a010d 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -1219,6 +1219,64 @@ uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr ptr) return ret; } +uint8_t cpu_ldb_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t ra) +{ + void *haddr; + uint8_t ret; + + haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_INST_FETCH); + ret = ldub_p(haddr); + clear_helper_retaddr(); + return ret; +} + +uint16_t cpu_ldw_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t ra) +{ + void *haddr; + uint16_t ret; + + haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_INST_FETCH); + ret = lduw_p(haddr); + clear_helper_retaddr(); + if (get_memop(oi) & MO_BSWAP) { + ret = bswap16(ret); + } + return ret; +} + +uint32_t cpu_ldl_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t ra) +{ + void *haddr; + uint32_t ret; + + haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_INST_FETCH); + ret = ldl_p(haddr); + clear_helper_retaddr(); + if (get_memop(oi) & MO_BSWAP) { + ret = bswap32(ret); + } + return ret; +} + +uint64_t cpu_ldq_code_mmu(CPUArchState *env, abi_ptr addr, + MemOpIdx oi, uintptr_t ra) +{ + void *haddr; + uint64_t ret; + + validate_memop(oi, MO_BEUQ); + haddr = cpu_mmu_lookup(env, addr, oi, ra, MMU_DATA_LOAD); + ret = ldq_p(haddr); + clear_helper_retaddr(); + if (get_memop(oi) & MO_BSWAP) { + ret = bswap64(ret); + } + return ret; +} + #include "ldst_common.c.inc" /* |