summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-10-06 16:20:53 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-10-06 16:20:53 +0000
commita305dd56e4fcf5d74b3bfb5e4d91f1e48e6e1298 (patch)
tree38238ad32d0cec73a53f458a03c172a8734a8757 /nuttx/arch/arm
parent38dc3d5a7c2dfaf6a6d867e7c41ab455d2e8bc6f (diff)
downloadpx4-nuttx-a305dd56e4fcf5d74b3bfb5e4d91f1e48e6e1298.tar.gz
px4-nuttx-a305dd56e4fcf5d74b3bfb5e4d91f1e48e6e1298.tar.bz2
px4-nuttx-a305dd56e4fcf5d74b3bfb5e4d91f1e48e6e1298.zip
Add option for ARM interrupt stack
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@981 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/arm')
-rw-r--r--nuttx/arch/arm/src/c5471/c5471_vectors.S35
-rw-r--r--nuttx/arch/arm/src/common/up_assert.c151
-rw-r--r--nuttx/arch/arm/src/common/up_internal.h12
-rw-r--r--nuttx/arch/arm/src/common/up_vectors.S36
4 files changed, 196 insertions, 38 deletions
diff --git a/nuttx/arch/arm/src/c5471/c5471_vectors.S b/nuttx/arch/arm/src/c5471/c5471_vectors.S
index 1329017bc..f84647707 100644
--- a/nuttx/arch/arm/src/c5471/c5471_vectors.S
+++ b/nuttx/arch/arm/src/c5471/c5471_vectors.S
@@ -156,7 +156,15 @@ up_vectorirq:
mov fp, #0 /* Init frame pointer */
mov r1, sp /* Get r1=xcp */
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ ldr sp, .Lirqstackbase /* SP = interrupt stack base */
+ str r1, [sp] /* Save the user stack pointer */
+ bl up_doirq /* Call the handler */
+ ldr sp, [sp] /* Restore the user stack pointer */
+#else
bl up_doirq /* Call the handler */
+#endif
/* Restore the CPSR, SVC modr registers and return */
.Lnoirqset:
@@ -166,7 +174,10 @@ up_vectorirq:
.Lirqtmp:
.word g_irqtmp
-
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+.Lirqstackbase:
+ .word up_stackbase
+#endif
.align 5
/************************************************************************************
@@ -446,4 +457,26 @@ up_vectorfiq:
.type up_vectoraddrexcptn, %function
up_vectoraddrexcptn:
b up_vectoraddrexcptn
+
+/************************************************************************************
+ * Name: up_interruptstack/g_userstack
+ *
+ * Description:
+ * Shouldn't happen
+ *
+ ************************************************************************************/
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ .bss
+ .align 4
+ .globl g_userstack
+ .type g_userstack, object
+up_interruptstack:
+ .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4)
+g_userstack:
+up_stackbase:
+ .skip 4
+ .size g_userstack, 4
+ .size up_interruptstack, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
+#endif
.end
diff --git a/nuttx/arch/arm/src/common/up_assert.c b/nuttx/arch/arm/src/common/up_assert.c
index 895b1f0f5..1790225c2 100644
--- a/nuttx/arch/arm/src/common/up_assert.c
+++ b/nuttx/arch/arm/src/common/up_assert.c
@@ -94,62 +94,143 @@ static inline uint32 up_getsp(void)
****************************************************************************/
#ifdef CONFIG_ARCH_STACKDUMP
-static void up_stackdump(void)
+static void up_stackdump(uint32 sp, uint32 stack_base)
+{
+ uint32 stack ;
+
+ for (stack = sp & ~0x1f; stack < stack_base; stack += 32)
+ {
+ uint32 *ptr = (uint32*)stack;
+ lldbg("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ stack, ptr[0], ptr[1], ptr[2], ptr[3],
+ ptr[4], ptr[5], ptr[6], ptr[7]);
+ }
+}
+#else
+# define up_stackdump()
+#endif
+
+/****************************************************************************
+ * Name: up_registerdump
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_STACKDUMP
+static inline void up_registerdump(void)
+{
+ /* Are user registers available from interrupt processing? */
+
+ if (current_regs)
+ {
+ int regs;
+
+ /* Yes.. dump the interrupt registers */
+
+ for (regs = REG_R0; regs <= REG_R15; regs += 8)
+ {
+ uint32 *ptr = (uint32*)&current_regs[regs];
+ lldbg("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ regs, ptr[0], ptr[1], ptr[2], ptr[3],
+ ptr[4], ptr[5], ptr[6], ptr[7]);
+ }
+ lldbg("CPSR: %08x\n", current_regs[REG_CPSR]);
+ }
+}
+#else
+# define up_registerdump()
+#endif
+
+/****************************************************************************
+ * Name: up_dumpstate
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_STACKDUMP
+static void up_dumpstate(void)
{
_TCB *rtcb = (_TCB*)g_readytorun.head;
uint32 sp = up_getsp();
- uint32 stack_base;
- uint32 stack_size;
+ uint32 ustackbase;
+ uint32 ustacksize;
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ uint32 istackbase;
+ uint32 istacksize;
+#endif
+
+ /* Get the limits on the user stack memory */
if (rtcb->pid == 0)
{
- stack_base = g_heapbase - 4;
- stack_size = CONFIG_PROC_STACK_SIZE;
+ ustackbase = g_heapbase - 4;
+ ustacksize = CONFIG_PROC_STACK_SIZE;
}
else
{
- stack_base = (uint32)rtcb->adj_stack_ptr;
- stack_size = (uint32)rtcb->adj_stack_size;
+ ustackbase = (uint32)rtcb->adj_stack_ptr;
+ ustacksize = (uint32)rtcb->adj_stack_size;
+ }
+
+ /* Get the limits on the interrupt stack memory */
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ istackbase = (uint32)&g_userstack;
+ istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4;
+
+ /* Show interrupt stack info */
+
+ lldbg("sp: %08x\n", sp);
+ lldbg("IRQ stack:\n");
+ lldbg(" base: %08x\n", istackbase);
+ lldbg(" size: %08x\n", istacksize);
+
+ /* Does the current stack pointer lie within the interrupt
+ * stack?
+ */
+
+ if (sp <= istackbase && sp < istackbase - istacksize)
+ {
+ /* Yes.. dump the interrupt stack */
+
+ up_stackdump(sp, istackbase);
+
+ /* Extract the user stack pointer which should lie
+ * at the base of the interrupt stack.
+ */
+
+ sp = g_userstack;
+ lldbg("sp: %08x\n", sp);
}
- lldbg("stack_base: %08x\n", stack_base);
- lldbg("stack_size: %08x\n", stack_size);
+ /* Show user stack info */
+
+ lldbg("User stack:\n");
+ lldbg(" base: %08x\n", ustackbase);
+ lldbg(" size: %08x\n", ustacksize);
+#else
lldbg("sp: %08x\n", sp);
+ lldbg("stack base: %08x\n", ustackbase);
+ lldbg("stack size: %08x\n", ustacksize);
+#endif
+
+ /* Dump the user stack if the stack pointer lies within the allocated user
+ * stack memory.
+ */
- if (sp >= stack_base || sp < stack_base - stack_size)
+ if (sp >= ustackbase || sp < ustackbase - ustacksize)
{
+#if !defined(CONFIG_ARCH_INTERRUPTSTACK) || CONFIG_ARCH_INTERRUPTSTACK < 4
lldbg("ERROR: Stack pointer is not within allocated stack\n");
- return;
+#endif
}
else
{
- uint32 stack = sp & ~0x1f;
-
- for (stack = sp & ~0x1f; stack < stack_base; stack += 32)
- {
- uint32 *ptr = (uint32*)stack;
- lldbg("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
- stack, ptr[0], ptr[1], ptr[2], ptr[3],
- ptr[4], ptr[5], ptr[6], ptr[7]);
- }
+ up_stackdump(sp, ustackbase);
}
- if (current_regs)
- {
- int regs;
+ /* Then dump the registers (if available) */
- for (regs = REG_R0; regs <= REG_R15; regs += 8)
- {
- uint32 *ptr = (uint32*)&current_regs[regs];
- lldbg("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n",
- regs, ptr[0], ptr[1], ptr[2], ptr[3],
- ptr[4], ptr[5], ptr[6], ptr[7]);
- }
- lldbg("CPSR: %08x\n", current_regs[REG_CPSR]);
- }
+ up_registerdump();
}
#else
-# define up_stackdump()
+# define up_dumpstate()
#endif
/****************************************************************************
@@ -201,7 +282,7 @@ void up_assert(const ubyte *filename, int lineno)
lldbg("Assertion failed at file:%s line: %d\n",
filename, lineno);
#endif
- up_stackdump();
+ up_dumpstate();
_up_assert(EXIT_FAILURE);
}
@@ -223,6 +304,6 @@ void up_assert_code(const ubyte *filename, int lineno, int errorcode)
lldbg("Assertion failed at file:%s line: %d error code: %d\n",
filename, lineno, errorcode);
#endif
- up_stackdump();
+ up_dumpstate();
_up_assert(errorcode);
}
diff --git a/nuttx/arch/arm/src/common/up_internal.h b/nuttx/arch/arm/src/common/up_internal.h
index 76313b31d..862ceb82c 100644
--- a/nuttx/arch/arm/src/common/up_internal.h
+++ b/nuttx/arch/arm/src/common/up_internal.h
@@ -65,6 +65,12 @@
# define CONFIG_USE_EARLYSERIALINIT 1
#endif
+/* Check if an interrupt stack size is configured */
+
+#ifndef CONFIG_ARCH_INTERRUPTSTACK
+# define CONFIG_ARCH_INTERRUPTSTACK 0
+#endif
+
/****************************************************************************
* Public Types
****************************************************************************/
@@ -92,6 +98,12 @@ extern uint32 *current_regs;
*/
extern uint32 g_heapbase;
+
+/* Address of the saved user stack pointer */
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+extern uint32 g_userstack;
+#endif
#endif
/****************************************************************************
diff --git a/nuttx/arch/arm/src/common/up_vectors.S b/nuttx/arch/arm/src/common/up_vectors.S
index 6d4c79e7d..e97683a16 100644
--- a/nuttx/arch/arm/src/common/up_vectors.S
+++ b/nuttx/arch/arm/src/common/up_vectors.S
@@ -128,7 +128,15 @@ up_vectorirq:
mov fp, #0 /* Init frame pointer */
mov r0, sp /* Get r0=xcp */
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ ldr sp, .Lirqstackbase /* SP = interrupt stack base */
+ str r0, [sp] /* Save the user stack pointer */
+ bl up_decodeirq /* Call the handler */
+ ldr sp, [sp] /* Restore the user stack pointer */
+#else
bl up_decodeirq /* Call the handler */
+#endif
/* Restore the CPSR, SVC modr registers and return */
.Lnoirqset:
@@ -138,8 +146,11 @@ up_vectorirq:
.Lirqtmp:
.word g_irqtmp
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+.Lirqstackbase:
+ .word up_stackbase
+#endif
.size up_vectorirq, . - up_vectorirq
-
.align 5
/************************************************************************************
@@ -404,4 +415,25 @@ up_vectorfiq:
subs pc, lr, #4
.size up_vectofiq, . - up_vectorfiq
- .align 5
+/************************************************************************************
+ * Name: up_interruptstack/g_userstack
+ *
+ * Description:
+ * Shouldn't happen
+ *
+ ************************************************************************************/
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 3
+ .bss
+ .align 4
+ .globl g_userstack
+ .type g_userstack, object
+up_interruptstack:
+ .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4)
+g_userstack:
+up_stackbase:
+ .skip 4
+ .size g_userstack, 4
+ .size up_interruptstack, (CONFIG_ARCH_INTERRUPTSTACK & ~3)
+#endif
+ .end