From 8f6be9a9b5ff34570e45cd54f5aa362c4a67505a Mon Sep 17 00:00:00 2001 From: wangmingrong1 Date: Mon, 26 May 2025 15:10:46 +0800 Subject: [PATCH] arm: Enhance armv7a's dataaboart to adapt to debug mode Signed-off-by: wangmingrong1 --- arch/arm/src/armv7-a/arm_dataabort.c | 62 ++++++++++++++++++---------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/arch/arm/src/armv7-a/arm_dataabort.c b/arch/arm/src/armv7-a/arm_dataabort.c index f5642b0c49..3bf5daa09d 100644 --- a/arch/arm/src/armv7-a/arm_dataabort.c +++ b/arch/arm/src/armv7-a/arm_dataabort.c @@ -32,6 +32,7 @@ #include +#include "mmu.h" #include "sched/sched.h" #include "arm_internal.h" @@ -92,7 +93,11 @@ uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) */ pginfo("DFSR: %08x DFAR: %08x\n", dfsr, dfar); - if ((dfsr & FSR_MASK) != FSR_PAGE) + if (FSR_FAULT(dfsr) == FSR_FAULT_DEBUG) + { + arm_dbgmonitor(0, (void *)dfar, regs); + } + else if((dfsr & FSR_MASK) != FSR_PAGE) { goto segfault; } @@ -102,33 +107,36 @@ uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) * (It has not yet been saved in the register context save area). */ - pginfo("VBASE: %08x VEND: %08x\n", PG_PAGED_VBASE, PG_PAGED_VEND); - if (dfar < PG_PAGED_VBASE || dfar >= PG_PAGED_VEND) + else if (dfar < PG_PAGED_VBASE || dfar >= PG_PAGED_VEND) { goto segfault; } + else + { + pginfo("VBASE: %08x VEND: %08x\n", PG_PAGED_VBASE, PG_PAGED_VEND); - /* Save the offending data address as the fault address in the TCB of - * the currently task. This fault address is also used by the prefetch - * abort handling; this will allow common paging logic for both - * prefetch and data aborts. - */ + /* Save the offending data address as the fault address in the TCB of + * the currently task. This fault address is also used by the prefetch + * abort handling; this will allow common paging logic for both + * prefetch and data aborts. + */ - tcb->xcp.dfar = regs[REG_R15]; + tcb->xcp.dfar = regs[REG_R15]; - /* Call pg_miss() to schedule the page fill. A consequences of this - * call are: - * - * (1) The currently executing task will be blocked and saved on - * on the g_waitingforfill task list. - * (2) An interrupt-level context switch will occur so that when - * this function returns, it will return to a different task, - * most likely the page fill worker thread. - * (3) The page fill worker task has been signalled and should - * execute immediately when we return from this exception. - */ + /* Call pg_miss() to schedule the page fill. A consequences of this + * call are: + * + * (1) The currently executing task will be blocked and saved on + * on the g_waitingforfill task list. + * (2) An interrupt-level context switch will occur so that when + * this function returns, it will return to a different task, + * most likely the page fill worker thread. + * (3) The page fill worker task has been signalled and should + * execute immediately when we return from this exception. + */ - pg_miss(); + pg_miss(); + } /* Restore the previous value of saveregs. */ @@ -156,7 +164,17 @@ uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) _alert("Data abort. PC: %08" PRIx32 " DFAR: %08" PRIx32 " DFSR: %08" PRIx32 "\n", regs[REG_PC], dfar, dfsr); - PANIC_WITH_REGS("panic", regs); + + if (FSR_FAULT(dfsr) == FSR_FAULT_DEBUG) + { + arm_dbgmonitor(0, (void *)dfar, regs); + } + else + { + PANIC_WITH_REGS("panic", regs); + } + + up_set_interrupt_context(false); return regs; /* To keep the compiler happy */ }