@@ -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)
@@ -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,
@@ -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,
@@ -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,
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(-)