mirror of
https://github.com/apache/nuttx.git
synced 2026-09-27 18:58:27 +08:00
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
This commit is contained in:
@@ -147,12 +147,19 @@ static inline void up_registerdump(void)
|
|||||||
current_regs[REG_R10], current_regs[REG_R11],
|
current_regs[REG_R10], current_regs[REG_R11],
|
||||||
current_regs[REG_R12], current_regs[REG_R13],
|
current_regs[REG_R12], current_regs[REG_R13],
|
||||||
current_regs[REG_R14], current_regs[REG_R15]);
|
current_regs[REG_R14], current_regs[REG_R15]);
|
||||||
|
|
||||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||||
lldbg("xPSR: %08x BASEPRI: %08x\n",
|
lldbg("xPSR: %08x BASEPRI: %08x CONTROL: %08x\n",
|
||||||
current_regs[REG_XPSR], current_regs[REG_BASEPRI]);
|
current_regs[REG_XPSR], current_regs[REG_BASEPRI],
|
||||||
|
getcontrol());
|
||||||
#else
|
#else
|
||||||
lldbg("xPSR: %08x PRIMASK: %08x\n",
|
lldbg("xPSR: %08x PRIMASK: %08x CONTROL: %08x\n",
|
||||||
current_regs[REG_XPSR], current_regs[REG_PRIMASK]);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,9 +196,9 @@ static void up_dumpstate(void)
|
|||||||
ustacksize = (uint32_t)rtcb->adj_stack_size;
|
ustacksize = (uint32_t)rtcb->adj_stack_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||||
/* Get the limits on the interrupt stack memory */
|
/* Get the limits on the interrupt stack memory */
|
||||||
|
|
||||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
|
||||||
istackbase = (uint32_t)&g_intstackbase;
|
istackbase = (uint32_t)&g_intstackbase;
|
||||||
istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4;
|
istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4;
|
||||||
|
|
||||||
@@ -236,7 +243,11 @@ static void up_dumpstate(void)
|
|||||||
{
|
{
|
||||||
up_stackdump(sp, ustackbase);
|
up_stackdump(sp, ustackbase);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
/* Show user stack info */
|
||||||
|
|
||||||
lldbg("sp: %08x\n", sp);
|
lldbg("sp: %08x\n", sp);
|
||||||
lldbg("stack base: %08x\n", ustackbase);
|
lldbg("stack base: %08x\n", ustackbase);
|
||||||
lldbg("stack size: %08x\n", ustacksize);
|
lldbg("stack size: %08x\n", ustacksize);
|
||||||
@@ -247,12 +258,13 @@ static void up_dumpstate(void)
|
|||||||
|
|
||||||
if (sp > ustackbase || sp <= ustackbase - ustacksize)
|
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
|
else
|
||||||
{
|
{
|
||||||
up_stackdump(sp, ustackbase);
|
up_stackdump(sp, ustackbase);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Then dump the registers (if available) */
|
/* 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)
|
if (current_regs || ((struct tcb_s*)g_readytorun.head)->pid == 0)
|
||||||
{
|
{
|
||||||
(void)irqsave();
|
(void)irqsave();
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_ARCH_LEDS
|
#ifdef CONFIG_ARCH_LEDS
|
||||||
up_ledon(LED_PANIC);
|
up_ledon(LED_PANIC);
|
||||||
up_mdelay(250);
|
up_mdelay(250);
|
||||||
up_ledoff(LED_PANIC);
|
up_ledoff(LED_PANIC);
|
||||||
up_mdelay(250);
|
up_mdelay(250);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/userspace.h>
|
||||||
#include <arch/irq.h>
|
#include <arch/irq.h>
|
||||||
|
|
||||||
#include "up_arch.h"
|
#include "up_arch.h"
|
||||||
@@ -102,7 +103,27 @@ int up_hardfault(int irq, FAR void *context)
|
|||||||
|
|
||||||
#ifndef CONFIG_ARMV7M_USEBASEPRI
|
#ifndef CONFIG_ARMV7M_USEBASEPRI
|
||||||
uint16_t *pc = (uint16_t*)regs[REG_PC] - 1;
|
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 */
|
/* 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("\nHard Fault:\n");
|
||||||
hfdbg(" IRQ: %d regs: %p\n", irq, regs);
|
hfdbg(" IRQ: %d regs: %p\n", irq, regs);
|
||||||
hfdbg(" BASEPRI: %08x PRIMASK: %08x IPSR: %08x\n",
|
hfdbg(" BASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n",
|
||||||
getbasepri(), getprimask(), getipsr());
|
getbasepri(), getprimask(), getipsr(), getcontrol());
|
||||||
hfdbg(" CFAULTS: %08x HFAULTS: %08x DFAULTS: %08x BFAULTADDR: %08x AFAULTS: %08x\n",
|
hfdbg(" CFAULTS: %08x HFAULTS: %08x DFAULTS: %08x BFAULTADDR: %08x AFAULTS: %08x\n",
|
||||||
getreg32(NVIC_CFAULTS), getreg32(NVIC_HFAULTS),
|
getreg32(NVIC_CFAULTS), getreg32(NVIC_HFAULTS),
|
||||||
getreg32(NVIC_DFAULTS), getreg32(NVIC_BFAULT_ADDR),
|
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",
|
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_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
|
||||||
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
|
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
|
||||||
|
|
||||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
#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",
|
hfdbg(" xPSR: %08x BASEPRI: %08x (saved)\n",
|
||||||
current_regs[REG_XPSR], current_regs[REG_BASEPRI]);
|
current_regs[REG_XPSR], current_regs[REG_BASEPRI]);
|
||||||
|
# endif
|
||||||
#else
|
#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",
|
hfdbg(" xPSR: %08x PRIMASK: %08x (saved)\n",
|
||||||
current_regs[REG_XPSR], current_regs[REG_PRIMASK]);
|
current_regs[REG_XPSR], current_regs[REG_PRIMASK]);
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
(void)irqsave();
|
(void)irqsave();
|
||||||
|
|||||||
@@ -97,17 +97,33 @@ int up_memfault(int irq, FAR void *context)
|
|||||||
mfdbg(" IRQ: %d context: %p\n", irq, regs);
|
mfdbg(" IRQ: %d context: %p\n", irq, regs);
|
||||||
lldbg(" CFAULTS: %08x MMFAR: %08x\n",
|
lldbg(" CFAULTS: %08x MMFAR: %08x\n",
|
||||||
getreg32(NVIC_CFAULTS), getreg32(NVIC_MEMMANAGE_ADDR));
|
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",
|
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_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3],
|
||||||
regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]);
|
regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]);
|
||||||
mfdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n",
|
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_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11],
|
||||||
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
|
regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]);
|
||||||
#ifdef REG_EXC_RETURN
|
|
||||||
mfdbg(" PSR: %08x EXC_RETURN: %08x\n",
|
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||||
regs[REG_XPSR], regs[REG_EXC_RETURN]);
|
# 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
|
#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
|
#endif
|
||||||
|
|
||||||
PANIC(OSERR_UNEXPECTEDISR);
|
PANIC(OSERR_UNEXPECTEDISR);
|
||||||
|
|||||||
Reference in New Issue
Block a user