mirror of https://gitee.com/openkylin/qemu.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
|
||||
cc->do_interrupt = arm_cpu_do_interrupt;
|
||||
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->asidx_from_attrs = arm_asidx_from_attrs;
|
||||
cc->vmsd = &vmstate_arm_cpu;
|
||||
|
|
|
@ -472,6 +472,16 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
|
|||
MMUAccessType access_type,
|
||||
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 */
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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) */
|
||||
|
||||
uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
|
||||
|
|
Loading…
Reference in New Issue