summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-03-19 16:11:23 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-03-19 16:11:23 +0000
commita48a83271d371fd33201e3bba10967531ad32419 (patch)
treec58b80885bb66dbe6eda976a83caea2eae93e7fe /nuttx
parentc79e92ceffd9665632b58a6fb884178a4f4c71a2 (diff)
downloadpx4-nuttx-a48a83271d371fd33201e3bba10967531ad32419.tar.gz
px4-nuttx-a48a83271d371fd33201e3bba10967531ad32419.tar.bz2
px4-nuttx-a48a83271d371fd33201e3bba10967531ad32419.zip
If the PRIMASK is used to disable interrupts, then additional logic is required to handle hard faults in the kernel build
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5761 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_assert.c40
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_hardfault.c40
-rw-r--r--nuttx/arch/arm/src/armv7-m/up_memfault.c24
3 files changed, 83 insertions, 21 deletions
diff --git a/nuttx/arch/arm/src/armv7-m/up_assert.c b/nuttx/arch/arm/src/armv7-m/up_assert.c
index a4a58639c..b0df6d729 100644
--- a/nuttx/arch/arm/src/armv7-m/up_assert.c
+++ b/nuttx/arch/arm/src/armv7-m/up_assert.c
@@ -147,12 +147,19 @@ static inline void up_registerdump(void)
current_regs[REG_R10], current_regs[REG_R11],
current_regs[REG_R12], current_regs[REG_R13],
current_regs[REG_R14], current_regs[REG_R15]);
+
#ifdef CONFIG_ARMV7M_USEBASEPRI
- lldbg("xPSR: %08x BASEPRI: %08x\n",
- current_regs[REG_XPSR], current_regs[REG_BASEPRI]);
+ lldbg("xPSR: %08x BASEPRI: %08x CONTROL: %08x\n",
+ current_regs[REG_XPSR], current_regs[REG_BASEPRI],
+ getcontrol());
#else
- lldbg("xPSR: %08x PRIMASK: %08x\n",
- current_regs[REG_XPSR], current_regs[REG_PRIMASK]);
+ lldbg("xPSR: %08x PRIMASK: %08x CONTROL: %08x\n",
+ current_regs[REG_XPSR], current_regs[REG_PRIMASK],
+ getcontrol());
+#endif
+
+#ifdef REG_EXC_RETURN
+ lldbg("EXC_RETURN: %08x\n", current_regs[REG_EXC_RETURN]);
#endif
}
}
@@ -189,9 +196,9 @@ static void up_dumpstate(void)
ustacksize = (uint32_t)rtcb->adj_stack_size;
}
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Get the limits on the interrupt stack memory */
-#if CONFIG_ARCH_INTERRUPTSTACK > 3
istackbase = (uint32_t)&g_intstackbase;
istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4;
@@ -236,7 +243,11 @@ static void up_dumpstate(void)
{
up_stackdump(sp, ustackbase);
}
+
#else
+
+ /* Show user stack info */
+
lldbg("sp: %08x\n", sp);
lldbg("stack base: %08x\n", ustackbase);
lldbg("stack size: %08x\n", ustacksize);
@@ -247,12 +258,13 @@ static void up_dumpstate(void)
if (sp > ustackbase || sp <= ustackbase - ustacksize)
{
- lldbg("ERROR: Stack pointer is not within allocated stack\n");
+ lldbg("ERROR: Stack pointer is not within the allocated stack\n");
}
else
{
up_stackdump(sp, ustackbase);
}
+
#endif
/* Then dump the registers (if available) */
@@ -274,16 +286,16 @@ static void _up_assert(int errorcode)
if (current_regs || ((struct tcb_s*)g_readytorun.head)->pid == 0)
{
- (void)irqsave();
- for(;;)
- {
+ (void)irqsave();
+ for(;;)
+ {
#ifdef CONFIG_ARCH_LEDS
- up_ledon(LED_PANIC);
- up_mdelay(250);
- up_ledoff(LED_PANIC);
- up_mdelay(250);
+ up_ledon(LED_PANIC);
+ up_mdelay(250);
+ up_ledoff(LED_PANIC);
+ up_mdelay(250);
#endif
- }
+ }
}
else
{
diff --git a/nuttx/arch/arm/src/armv7-m/up_hardfault.c b/nuttx/arch/arm/src/armv7-m/up_hardfault.c
index fa750b525..e43b18cb3 100644
--- a/nuttx/arch/arm/src/armv7-m/up_hardfault.c
+++ b/nuttx/arch/arm/src/armv7-m/up_hardfault.c
@@ -44,6 +44,7 @@
#include <assert.h>
#include <debug.h>
+#include <nuttx/userspace.h>
#include <arch/irq.h>
#include "up_arch.h"
@@ -102,7 +103,27 @@ int up_hardfault(int irq, FAR void *context)
#ifndef CONFIG_ARMV7M_USEBASEPRI
uint16_t *pc = (uint16_t*)regs[REG_PC] - 1;
- if ((void*)pc >= (void*)&_stext && (void*)pc < (void*)&_etext)
+
+ /* Check if the pc lies in known FLASH memory.
+ * REVISIT: What if the PC lies in "unknown" external memory? Best
+ * use the BASEPRI register if you have external memory.
+ */
+
+#ifdef CONFIG_NUTTX_KERNEL
+ /* In the kernel build, SVCalls are expected in either the base, kernel
+ * FLASH region or in the user FLASH region.
+ */
+
+ if (((uintptr_t)pc >= (uintptr_t)&_stext &&
+ (uintptr_t)pc < (uintptr_t)&_etext) ||
+ ((uintptr_t)pc >= (uintptr_t)USERSPACE->us_textstart &&
+ (uintptr_t)pc < (uintptr_t)USERSPACE->us_textend))
+#else
+ /* SVCalls are expected only from the base, kernel FLASH region */
+
+ if ((uintptr_t)pc >= (uintptr_t)&_stext &&
+ (uintptr_t)pc < (uintptr_t)&_etext)
+#endif
{
/* Fetch the instruction that caused the Hard fault */
@@ -125,8 +146,8 @@ int up_hardfault(int irq, FAR void *context)
hfdbg("\nHard Fault:\n");
hfdbg(" IRQ: %d regs: %p\n", irq, regs);
- hfdbg(" BASEPRI: %08x PRIMASK: %08x IPSR: %08x\n",
- getbasepri(), getprimask(), getipsr());
+ hfdbg(" BASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
+ getbasepri(), getprimask(), getipsr(), getcontrol());
hfdbg(" CFAULTS: %08x HFAULTS: %08x DFAULTS: %08x BFAULTADDR: %08x AFAULTS: %08x\n",
getreg32(NVIC_CFAULTS), getreg32(NVIC_HFAULTS),
getreg32(NVIC_DFAULTS), getreg32(NVIC_BFAULT_ADDR),
@@ -137,12 +158,25 @@ int up_hardfault(int irq, FAR void *context)
hfdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
+
#ifdef CONFIG_ARMV7M_USEBASEPRI
+# ifdef REG_EXC_RETURN
+ hfdbg(" xPSR: %08x BASEPRI: %08x EXC_RETURN: %08x (saved)\n",
+ current_regs[REG_XPSR], current_regs[REG_BASEPRI],
+ current_regs[REG_EXC_RETURN]);
+# else
hfdbg(" xPSR: %08x BASEPRI: %08x (saved)\n",
current_regs[REG_XPSR], current_regs[REG_BASEPRI]);
+# endif
#else
+# ifdef REG_EXC_RETURN
+ hfdbg(" xPSR: %08x PRIMASK: %08x EXC_RETURN: %08x (saved)\n",
+ current_regs[REG_XPSR], current_regs[REG_PRIMASK],
+ current_regs[REG_EXC_RETURN]);
+# else
hfdbg(" xPSR: %08x PRIMASK: %08x (saved)\n",
current_regs[REG_XPSR], current_regs[REG_PRIMASK]);
+# endif
#endif
(void)irqsave();
diff --git a/nuttx/arch/arm/src/armv7-m/up_memfault.c b/nuttx/arch/arm/src/armv7-m/up_memfault.c
index a90f7cc74..c9f1b57b1 100644
--- a/nuttx/arch/arm/src/armv7-m/up_memfault.c
+++ b/nuttx/arch/arm/src/armv7-m/up_memfault.c
@@ -97,17 +97,33 @@ int up_memfault(int irq, FAR void *context)
mfdbg(" IRQ: %d context: %p\n", irq, regs);
lldbg(" CFAULTS: %08x MMFAR: %08x\n",
getreg32(NVIC_CFAULTS), getreg32(NVIC_MEMMANAGE_ADDR));
+ mfdbg(" BASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
+ getbasepri(), getprimask(), getipsr(), getcontrol());
mfdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3],
regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]);
mfdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
-#ifdef REG_EXC_RETURN
- mfdbg(" PSR: %08x EXC_RETURN: %08x\n",
- regs[REG_XPSR], regs[REG_EXC_RETURN]);
+
+#ifdef CONFIG_ARMV7M_USEBASEPRI
+# ifdef REG_EXC_RETURN
+ mfdbg(" xPSR: %08x BASEPRI: %08x EXC_RETURN: %08x (saved)\n",
+ current_regs[REG_XPSR], current_regs[REG_BASEPRI],
+ current_regs[REG_EXC_RETURN]);
+# else
+ mfdbg(" xPSR: %08x BASEPRI: %08x (saved)\n",
+ current_regs[REG_XPSR], current_regs[REG_BASEPRI]);
+# endif
#else
- mfdbg(" PSR: %08x\n", regs[REG_XPSR]);
+# ifdef REG_EXC_RETURN
+ mfdbg(" xPSR: %08x PRIMASK: %08x EXC_RETURN: %08x (saved)\n",
+ current_regs[REG_XPSR], current_regs[REG_PRIMASK],
+ current_regs[REG_EXC_RETURN]);
+# else
+ mfdbg(" xPSR: %08x PRIMASK: %08x (saved)\n",
+ current_regs[REG_XPSR], current_regs[REG_PRIMASK]);
+# endif
#endif
PANIC(OSERR_UNEXPECTEDISR);