Fill in the tlb_fill_align hook. So far this is the same
as tlb_fill_align_first, except that we can pass memop to
get_phys_addr as well.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/internals.h | 3 +++
target/arm/cpu.c | 2 +-
target/arm/tcg/cpu-v7m.c | 2 +-
target/arm/tcg/tlb_helper.c | 27 +++++++++++++++++++++++----
4 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index a6088d551c..6916d43009 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -819,6 +819,9 @@ void arm_cpu_record_sigbus(CPUState *cpu, vaddr addr,
bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
+bool arm_cpu_tlb_fill_align(CPUState *cs, vaddr address, MemOp memop,
+ int size, MMUAccessType access_type,
+ int mmu_idx, bool probe, uintptr_t retaddr);
#endif
static inline int arm_to_core_mmu_idx(ARMMMUIdx mmu_idx)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 08731ed4e0..293eb5949e 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2663,7 +2663,7 @@ static const TCGCPUOps arm_tcg_ops = {
.record_sigsegv = arm_cpu_record_sigsegv,
.record_sigbus = arm_cpu_record_sigbus,
#else
- .tlb_fill_align = tlb_fill_align_first,
+ .tlb_fill_align = arm_cpu_tlb_fill_align,
.tlb_fill = arm_cpu_tlb_fill,
.cpu_exec_interrupt = arm_cpu_exec_interrupt,
.cpu_exec_halt = arm_cpu_exec_halt,
diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
index 8874fe0e11..a071979636 100644
--- a/target/arm/tcg/cpu-v7m.c
+++ b/target/arm/tcg/cpu-v7m.c
@@ -242,7 +242,7 @@ static const TCGCPUOps arm_v7m_tcg_ops = {
.record_sigsegv = arm_cpu_record_sigsegv,
.record_sigbus = arm_cpu_record_sigbus,
#else
- .tlb_fill_align = tlb_fill_align_first,
+ .tlb_fill_align = arm_cpu_tlb_fill_align,
.tlb_fill = arm_cpu_tlb_fill,
.cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt,
.cpu_exec_halt = arm_cpu_exec_halt,
diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
index 1d8b7bcaa2..e83ece9462 100644
--- a/target/arm/tcg/tlb_helper.c
+++ b/target/arm/tcg/tlb_helper.c
@@ -318,9 +318,9 @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
arm_deliver_fault(cpu, addr, access_type, mmu_idx, &fi);
}
-bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
+static bool tlb_fill_internal(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, MemOp memop,
+ int mmu_idx, bool probe, uintptr_t retaddr)
{
ARMCPU *cpu = ARM_CPU(cs);
GetPhysAddrResult res = {};
@@ -344,7 +344,7 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
* return false. Otherwise populate fsr with ARM DFSR/IFSR fault
* register format, and signal the fault.
*/
- ret = get_phys_addr(&cpu->env, address, access_type, 0,
+ ret = get_phys_addr(&cpu->env, address, access_type, memop,
core_to_arm_mmu_idx(&cpu->env, mmu_idx),
&res, fi);
if (likely(!ret)) {
@@ -371,6 +371,25 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
arm_deliver_fault(cpu, address, access_type, mmu_idx, fi);
}
}
+
+bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr)
+{
+ return tlb_fill_internal(cs, address, size, access_type, 0,
+ mmu_idx, probe, retaddr);
+}
+
+bool arm_cpu_tlb_fill_align(CPUState *cs, vaddr address, MemOp memop,
+ int size, MMUAccessType access_type,
+ int mmu_idx, bool probe, uintptr_t retaddr)
+{
+ if (unlikely(address & ((1 << memop_alignment_bits(memop)) - 1))) {
+ arm_cpu_do_unaligned_access(cs, address, access_type, mmu_idx, retaddr);
+ }
+ return tlb_fill_internal(cs, address, size, access_type, memop,
+ mmu_idx, probe, retaddr);
+}
#else
void arm_cpu_record_sigsegv(CPUState *cs, vaddr addr,
MMUAccessType access_type,
--
2.43.0