Reviewed-by: Xianglai Li <[email protected]>
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