This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 6cc98495618d5ec4dc2de4e568f46c2729625ca6 Author: wangmingrong1 <[email protected]> AuthorDate: Mon May 26 14:47:21 2025 +0800 arm: Enhance armv7a's prefetchaboart to adapt to debug mode ifar is 0 on qemu platform, the reason is unknown, so here use regs[REG_PC] Signed-off-by: wangmingrong1 <[email protected]> --- arch/arm/src/armv7-a/arm_prefetchabort.c | 29 ++++++++++++++++++++++------- arch/arm/src/armv7-a/mmu.h | 25 +++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/arch/arm/src/armv7-a/arm_prefetchabort.c b/arch/arm/src/armv7-a/arm_prefetchabort.c index 93446d42a5..8a87387570 100644 --- a/arch/arm/src/armv7-a/arm_prefetchabort.c +++ b/arch/arm/src/armv7-a/arm_prefetchabort.c @@ -35,6 +35,7 @@ # include <nuttx/page.h> #endif +#include "mmu.h" #include "sched/sched.h" #include "arm_internal.h" @@ -77,7 +78,11 @@ uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) pginfo("VADDR: %08x VBASE: %08x VEND: %08x\n", regs[REG_PC], PG_PAGED_VBASE, PG_PAGED_VEND); - if (regs[REG_R15] >= PG_PAGED_VBASE && regs[REG_R15] < PG_PAGED_VEND) + if (FSR_FAULT(ifsr) == FSR_FAULT_DEBUG) + { + arm_dbgmonitor(0, (void *)regs[REG_PC], regs); + } + else if (regs[REG_R15] >= PG_PAGED_VBASE && regs[REG_R15] < PG_PAGED_VEND) { /* Save the offending PC as the fault address in the TCB of the * currently executing task. This value is, of course, already known @@ -101,11 +106,6 @@ uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) */ pg_miss(); - - /* Restore the previous value of saveregs. */ - - up_set_interrupt_context(savestate); - tcb->xcp.regs = saveregs; } else { @@ -114,6 +114,11 @@ uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) PANIC_WITH_REGS("panic", regs); } + /* Restore the previous value of saveregs. */ + + up_set_interrupt_context(savestate); + tcb->xcp.regs = saveregs; + return regs; } @@ -130,7 +135,17 @@ uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) _alert("Prefetch abort. PC: %08" PRIx32 " IFAR: %08" PRIx32 " IFSR: %08" PRIx32 "\n", regs[REG_PC], ifar, ifsr); - PANIC_WITH_REGS("panic", regs); + + if (FSR_FAULT(ifsr) == FSR_FAULT_DEBUG) + { + arm_dbgmonitor(0, (void *)regs[REG_PC], regs); + } + else + { + PANIC_WITH_REGS("panic", regs); + } + + up_set_interrupt_context(false); return regs; /* To keep the compiler happy */ } diff --git a/arch/arm/src/armv7-a/mmu.h b/arch/arm/src/armv7-a/mmu.h index 47e3145d74..c72c8baa8a 100644 --- a/arch/arm/src/armv7-a/mmu.h +++ b/arch/arm/src/armv7-a/mmu.h @@ -164,6 +164,31 @@ #define IFSR_EXT (1 << 12) /* Bit 12: External Abort Qualifier */ /* Bits 13-31: Reserved */ +#define FSR_FAULT(fsr) (((fsr) & 0x0f) | (((fsr) & 0x400) >> 6)) +#define FSR_FAULT_ALIGNMENT 0x01 /* Alignment fault (DFSR only) */ +#define FSR_FAULT_DEBUG 0x02 /* Debug event */ +#define FSR_FAULT_TRANSLATION_L1 0x05 /* Translation fault, first level */ +#define FSR_FAULT_TRANSLATION_L2 0x07 /* Translation fault, second level */ +#define FSR_FAULT_ACCESS_FLAG_L1 0x06 /* Access flag fault, first level */ +#define FSR_FAULT_ACCESS_FLAG_L2 0x08 /* Access flag fault, second level */ +#define FSR_FAULT_DOMAIN_L1 0x09 /* Domain fault, first level */ +#define FSR_FAULT_DOMAIN_L2 0x0b /* Domain fault, second level */ +#define FSR_FAULT_PERMISSION_L1 0x0d /* Permission fault, first level */ +#define FSR_FAULT_PERMISSION_L2 0x0f /* Permission fault, second level */ +#define FSR_FAULT_SYNC_EXTERNAL_ABORT 0x08 /* Synchronous external abort */ +#define FSR_FAULT_SYNC_EXTERNAL_L1 0x0c /* External abort on translation table walk, first level */ +#define FSR_FAULT_SYNC_EXTERNAL_L2 0x0e /* External abort on translation table walk, second level */ +#define FSR_FAULT_SYNC_PARITY_L1 0x1c /* Synchronous parity error on translation table walk, first level */ +#define FSR_FAULT_SYNC_PARITY_L2 0x1e /* Synchronous parity error on translation table walk, second level */ +#define FSR_FAULT_PARITY 0x19 /* Parity error on memory access */ +#define FSR_FAULT_TLB_CONFLICT 0x10 /* TLB conflict abort */ +#define FSR_FAULT_ICACHE_MAINT 0x04 /* Fault on instruction cache maintenance */ +#define FSR_FAULT_LOCKDOWN 0x14 /* Implementation defined: lockdown */ +#define FSR_FAULT_COPROC_ABORT 0x1a /* Implementation defined: coprocessor abort */ +#define FSR_FAULT_PARITY_MEM_SYNC 0x11 /* Synchronous parity error on memory access */ +#define FSR_FAULT_EXTERNAL_ASYNC 0x16 /* Asynchronous external abort (DFSR only) */ +#define FSR_FAULT_PARITY_MEM_ASYNC 0x18 /* Asynchronous parity error on memory access (DFSR only) */ + /* Data Fault Address Register(DFAR). Holds the MVA of the faulting address * when a synchronous fault occurs *
