mirror of https://github.com/xemu-project/xemu.git
target/arm: Implement new do_transaction_failed hook
Implement the new do_transaction_failed hook for ARM, which should cause the CPU to take a prefetch abort or data abort. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Message-id: 1504626814-23124-4-git-send-email-peter.maydell@linaro.org
This commit is contained in:
parent
4672cbd7be
commit
c79c0a314c
|
@ -1707,6 +1707,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
#else
|
#else
|
||||||
cc->do_interrupt = arm_cpu_do_interrupt;
|
cc->do_interrupt = arm_cpu_do_interrupt;
|
||||||
cc->do_unaligned_access = arm_cpu_do_unaligned_access;
|
cc->do_unaligned_access = arm_cpu_do_unaligned_access;
|
||||||
|
cc->do_transaction_failed = arm_cpu_do_transaction_failed;
|
||||||
cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug;
|
cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug;
|
||||||
cc->asidx_from_attrs = arm_asidx_from_attrs;
|
cc->asidx_from_attrs = arm_asidx_from_attrs;
|
||||||
cc->vmsd = &vmstate_arm_cpu;
|
cc->vmsd = &vmstate_arm_cpu;
|
||||||
|
|
|
@ -472,6 +472,16 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
|
||||||
MMUAccessType access_type,
|
MMUAccessType access_type,
|
||||||
int mmu_idx, uintptr_t retaddr);
|
int mmu_idx, uintptr_t retaddr);
|
||||||
|
|
||||||
|
/* arm_cpu_do_transaction_failed: handle a memory system error response
|
||||||
|
* (eg "no device/memory present at address") by raising an external abort
|
||||||
|
* exception
|
||||||
|
*/
|
||||||
|
void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
|
||||||
|
vaddr addr, unsigned size,
|
||||||
|
MMUAccessType access_type,
|
||||||
|
int mmu_idx, MemTxAttrs attrs,
|
||||||
|
MemTxResult response, uintptr_t retaddr);
|
||||||
|
|
||||||
/* Call the EL change hook if one has been registered */
|
/* Call the EL change hook if one has been registered */
|
||||||
static inline void arm_call_el_change_hook(ARMCPU *cpu)
|
static inline void arm_call_el_change_hook(ARMCPU *cpu)
|
||||||
{
|
{
|
||||||
|
|
|
@ -229,6 +229,49 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
|
||||||
deliver_fault(cpu, vaddr, access_type, fsr, fsc, &fi);
|
deliver_fault(cpu, vaddr, access_type, fsr, fsc, &fi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* arm_cpu_do_transaction_failed: handle a memory system error response
|
||||||
|
* (eg "no device/memory present at address") by raising an external abort
|
||||||
|
* exception
|
||||||
|
*/
|
||||||
|
void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
|
||||||
|
vaddr addr, unsigned size,
|
||||||
|
MMUAccessType access_type,
|
||||||
|
int mmu_idx, MemTxAttrs attrs,
|
||||||
|
MemTxResult response, uintptr_t retaddr)
|
||||||
|
{
|
||||||
|
ARMCPU *cpu = ARM_CPU(cs);
|
||||||
|
CPUARMState *env = &cpu->env;
|
||||||
|
uint32_t fsr, fsc;
|
||||||
|
ARMMMUFaultInfo fi = {};
|
||||||
|
ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
|
||||||
|
|
||||||
|
if (retaddr) {
|
||||||
|
/* now we have a real cpu fault */
|
||||||
|
cpu_restore_state(cs, retaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The EA bit in syndromes and fault status registers is an
|
||||||
|
* IMPDEF classification of external aborts. ARM implementations
|
||||||
|
* usually use this to indicate AXI bus Decode error (0) or
|
||||||
|
* Slave error (1); in QEMU we follow that.
|
||||||
|
*/
|
||||||
|
fi.ea = (response != MEMTX_DECODE_ERROR);
|
||||||
|
|
||||||
|
/* The fault status register format depends on whether we're using
|
||||||
|
* the LPAE long descriptor format, or the short descriptor format.
|
||||||
|
*/
|
||||||
|
if (arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
|
||||||
|
/* long descriptor form, STATUS 0b010000: synchronous ext abort */
|
||||||
|
fsr = (fi.ea << 12) | (1 << 9) | 0x10;
|
||||||
|
} else {
|
||||||
|
/* short descriptor form, FSR 0b01000 : synchronous ext abort */
|
||||||
|
fsr = (fi.ea << 12) | 0x8;
|
||||||
|
}
|
||||||
|
fsc = 0x10;
|
||||||
|
|
||||||
|
deliver_fault(cpu, addr, access_type, fsr, fsc, &fi);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !defined(CONFIG_USER_ONLY) */
|
#endif /* !defined(CONFIG_USER_ONLY) */
|
||||||
|
|
||||||
uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
|
uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
|
||||||
|
|
Loading…
Reference in New Issue