For atomic instructions and LL/SC instruction pairs, the accessed address must be aligned to the access size. Otherwise, an EXCCODE_ALE exception is raised.
Add support for unaligned address accesses for these instructions. Signed-off-by: Bibo Mao <[email protected]> --- target/loongarch/tcg/tcg_cpu.c | 2 ++ target/loongarch/tcg/tcg_loongarch.h | 4 ++++ target/loongarch/tcg/tlb_helper.c | 16 ++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/target/loongarch/tcg/tcg_cpu.c b/target/loongarch/tcg/tcg_cpu.c index cbf0e12c81..0549506035 100644 --- a/target/loongarch/tcg/tcg_cpu.c +++ b/target/loongarch/tcg/tcg_cpu.c @@ -92,6 +92,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) case EXCCODE_PME: case EXCCODE_PNR: case EXCCODE_PPI: + case EXCCODE_ALE: cause = cs->exception_index; break; default: @@ -289,5 +290,6 @@ const TCGCPUOps loongarch_tcg_ops = { .cpu_exec_reset = cpu_reset, .do_interrupt = loongarch_cpu_do_interrupt, .do_transaction_failed = loongarch_cpu_do_transaction_failed, + .do_unaligned_access = loongarch_cpu_do_unaligned_access, #endif }; diff --git a/target/loongarch/tcg/tcg_loongarch.h b/target/loongarch/tcg/tcg_loongarch.h index 7fb627f2d6..9c8627972f 100644 --- a/target/loongarch/tcg/tcg_loongarch.h +++ b/target/loongarch/tcg/tcg_loongarch.h @@ -15,6 +15,10 @@ void loongarch_csr_translate_init(void); bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, bool probe, uintptr_t retaddr); +G_NORETURN void loongarch_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, + MMUAccessType access_type, + int mmu_idx, + uintptr_t retaddr); TLBRet loongarch_get_addr_from_tlb(CPULoongArchState *env, MMUContext *context, diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index a707de9876..5662b2c49a 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -706,6 +706,22 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, cpu_loop_exit_restore(cs, retaddr); } +G_NORETURN void loongarch_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, + MMUAccessType access_type, + int mmu_idx, + uintptr_t retaddr) +{ + CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); + + /* + * Unaligned accesses are currently triggered by atomic instructions + * that impose alignment requirements on memory operands. + */ + sys->CSR_BADV = vaddr; + do_raise_exception(env, EXCCODE_ALE, retaddr); +} + static inline uint64_t loongarch_sanitize_hw_pte(CPULoongArchState *env, uint64_t pte) { base-commit: 73294d096cc591e122fde9e63db4739de6d84f2b -- 2.54.0
