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
  *

Reply via email to