void arm_cpu_record_sigbus(CPUState *cpu, vaddr addr,
MMUAccessType access_type, uintptr_t ra);
#else
-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, CPUTLBEntryFull *out, vaddr addr,
+ MMUAccessType access_type, int mmu_idx,
+ MemOp memop, int size, bool probe, uintptr_t ra);
#endif
static inline int arm_to_core_mmu_idx(ARMMMUIdx mmu_idx)
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)
+bool arm_cpu_tlb_fill_align(CPUState *cs, CPUTLBEntryFull *out, vaddr address,
+ MMUAccessType access_type, int mmu_idx,
+ MemOp memop, int size, bool probe, uintptr_t ra)
{
ARMCPU *cpu = ARM_CPU(cs);
GetPhysAddrResult res = {};
ARMMMUFaultInfo local_fi, *fi;
- int ret;
/*
* Allow S1_ptw_translate to see any fault generated here.
}
/*
- * Walk the page table and (if the mapping exists) add the page
- * to the TLB. On success, return true. Otherwise, if probing,
- * return false. Otherwise populate fsr with ARM DFSR/IFSR fault
- * register format, and signal the fault.
+ * Per R_XCHFJ, alignment fault not due to memory type has
+ * highest precedence. Otherwise, walk the page table and
+ * and collect the page description.
*/
- ret = get_phys_addr(&cpu->env, address, access_type, 0,
- core_to_arm_mmu_idx(&cpu->env, mmu_idx),
- &res, fi);
- if (likely(!ret)) {
- /*
- * Map a single [sub]page. Regions smaller than our declared
- * target page size are handled specially, so for those we
- * pass in the exact addresses.
- */
- if (res.f.lg_page_size >= TARGET_PAGE_BITS) {
- res.f.phys_addr &= TARGET_PAGE_MASK;
- address &= TARGET_PAGE_MASK;
- }
-
+ if (address & ((1 << memop_alignment_bits(memop)) - 1)) {
+ fi->type = ARMFault_Alignment;
+ } else if (!get_phys_addr(&cpu->env, address, access_type, memop,
+ core_to_arm_mmu_idx(&cpu->env, mmu_idx),
+ &res, fi)) {
res.f.extra.arm.pte_attrs = res.cacheattrs.attrs;
res.f.extra.arm.shareability = res.cacheattrs.shareability;
-
- tlb_set_page_full(cs, mmu_idx, address, &res.f);
+ *out = res.f;
return true;
- } else if (probe) {
+ }
+ if (probe) {
return false;
- } else {
- /* now we have a real cpu fault */
- cpu_restore_state(cs, retaddr);
- arm_deliver_fault(cpu, address, access_type, mmu_idx, fi);
}
+
+ /* Now we have a real cpu fault. */
+ cpu_restore_state(cs, ra);
+ arm_deliver_fault(cpu, address, access_type, mmu_idx, fi);
}
#else
void arm_cpu_record_sigsegv(CPUState *cs, vaddr addr,