This is an automated email from the ASF dual-hosted git repository.

jiuzhudong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new f766dc6c08d arch/arm: Add arm memmanage fault skip operation
f766dc6c08d is described below

commit f766dc6c08d9f41f20d4b43c3c1278d557c1a1f2
Author: pangzhen1 <[email protected]>
AuthorDate: Wed Jan 22 13:41:03 2025 +0800

    arch/arm: Add arm memmanage fault skip operation
    
    In some scenarios (e.g. testing, debugging, etc.) where we want to trigger 
a memmanage fault without panic the system, we can use this Memory Management 
Fault skip operation.
    
    Signed-off-by: pangzhen1 <[email protected]>
---
 arch/arm/src/armv7-m/arm_memfault.c | 34 ++++++++++++++++++++++++++++++++++
 arch/arm/src/armv8-m/arm_memfault.c | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+)

diff --git a/arch/arm/src/armv7-m/arm_memfault.c 
b/arch/arm/src/armv7-m/arm_memfault.c
index d2fff74a7c0..0f540c0bdda 100644
--- a/arch/arm/src/armv7-m/arm_memfault.c
+++ b/arch/arm/src/armv7-m/arm_memfault.c
@@ -100,6 +100,40 @@ int arm_memfault(int irq, void *context, void *arg)
       mfalert("\tFloating-point lazy state preservation error\n");
     }
 
+  /* In some scenarios (e.g. testing, debugging, etc.) where we want to
+   * ignore the memory management fault and proceed, we can set the parameter
+   * arg to 0xffffffff to skip the Memory Management Fault exception
+   */
+
+  if (arg == (void *)0xffffffff)
+    {
+      uint32_t *regs = context;
+      uint16_t insn;
+      mfalert("Skip the memory management fault and proceed\n");
+
+      /* regs[REG_PC] advance by 2/4 bytes depends on whether the encoded
+       * faulty instructions are 16-bit/32-bit thumb instructions
+       */
+
+      insn = (*(volatile uint16_t *)(regs[REG_PC]) >> 11) & 0x1f;
+
+      if (insn == 0x1d || insn == 0x1e || insn == 0x1f)
+        {
+          regs[REG_PC] += 4;
+        }
+      else
+        {
+          regs[REG_PC] += 2;
+        }
+
+      /* Clear the MMFSR and MMFAR register */
+
+      putreg32(0xff, NVIC_CFAULTS);
+      putreg32(0, NVIC_MEMMANAGE_ADDR);
+
+      return OK;
+    }
+
   up_irq_save();
   PANIC_WITH_REGS("panic", context);
   return OK; /* Won't get here */
diff --git a/arch/arm/src/armv8-m/arm_memfault.c 
b/arch/arm/src/armv8-m/arm_memfault.c
index 7ac7c124ab2..16183f351e3 100644
--- a/arch/arm/src/armv8-m/arm_memfault.c
+++ b/arch/arm/src/armv8-m/arm_memfault.c
@@ -100,6 +100,40 @@ int arm_memfault(int irq, void *context, void *arg)
       mfalert("\tFloating-point lazy state preservation error\n");
     }
 
+  /* In some scenarios (e.g. testing, debugging, etc.) where we want to
+   * ignore the memory management fault and proceed, we can set the parameter
+   * arg to 0xffffffff to skip the Memory Management Fault exception
+   */
+
+  if (arg == (void *)0xffffffff)
+    {
+      uint32_t *regs = context;
+      uint16_t insn;
+      mfalert("Skip the memory management fault and proceed\n");
+
+      /* regs[REG_PC] advance by 2/4 bytes depends on whether the encoded
+       * faulty instructions are 16-bit/32-bit thumb instructions
+       */
+
+      insn = (*(volatile uint16_t *)(regs[REG_PC]) >> 11) & 0x1f;
+
+      if (insn == 0x1d || insn == 0x1e || insn == 0x1f)
+        {
+          regs[REG_PC] += 4;
+        }
+      else
+        {
+          regs[REG_PC] += 2;
+        }
+
+      /* Clear the MMFSR and MMFAR register */
+
+      putreg32(0xff, NVIC_CFAULTS);
+      putreg32(0, NVIC_MEMMANAGE_ADDR);
+
+      return OK;
+    }
+
   up_irq_save();
   PANIC_WITH_REGS("panic", context);
   return OK; /* Won't get here */

Reply via email to