diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-05-13 16:19:05 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-05-13 16:19:05 +0000 |
commit | d85a6b5e74dbbf82ef5ed1518d9c588356a11251 (patch) | |
tree | dea1afe1fb2cb6db6e1f6aaf63c72fe52a1a62f5 /nuttx/arch/arm/src | |
parent | 27bee603a196dd9049de194777cc3be0d7514075 (diff) | |
download | px4-nuttx-d85a6b5e74dbbf82ef5ed1518d9c588356a11251.tar.gz px4-nuttx-d85a6b5e74dbbf82ef5ed1518d9c588356a11251.tar.bz2 px4-nuttx-d85a6b5e74dbbf82ef5ed1518d9c588356a11251.zip |
1st cut at lm3s6918 interrupt handling
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1776 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/arm/src')
-rw-r--r-- | nuttx/arch/arm/src/common/up_assert.c | 3 | ||||
-rw-r--r-- | nuttx/arch/arm/src/common/up_initialstate.c | 17 | ||||
-rw-r--r-- | nuttx/arch/arm/src/common/up_schedulesigaction.c | 40 | ||||
-rw-r--r-- | nuttx/arch/arm/src/common/up_sigdeliver.c | 14 | ||||
-rw-r--r-- | nuttx/arch/arm/src/lm3s/lm3s_vectors.S | 37 |
5 files changed, 79 insertions, 32 deletions
diff --git a/nuttx/arch/arm/src/common/up_assert.c b/nuttx/arch/arm/src/common/up_assert.c index 8460c6b71..88dd0bd49 100644 --- a/nuttx/arch/arm/src/common/up_assert.c +++ b/nuttx/arch/arm/src/common/up_assert.c @@ -134,7 +134,8 @@ static inline void up_registerdump(void) } #ifdef __thumb2__ - lldbg("xPSR: %08x\n", current_regs[REG_XPSR]); + lldbg("xPSR: %08x PRIMASK: %08x\n", + current_regs[REG_XPSR], current_regs[REG_PRIMASK]); #else lldbg("CPSR: %08x\n", current_regs[REG_CPSR]); #endif diff --git a/nuttx/arch/arm/src/common/up_initialstate.c b/nuttx/arch/arm/src/common/up_initialstate.c index 2dd1695ba..a945b4c51 100644 --- a/nuttx/arch/arm/src/common/up_initialstate.c +++ b/nuttx/arch/arm/src/common/up_initialstate.c @@ -81,11 +81,18 @@ void up_initial_state(_TCB *tcb) /* Initialize the initial exception register context structure */ memset(xcp, 0, sizeof(struct xcptcontext)); - xcp->regs[REG_SP] = (uint32)tcb->adj_stack_ptr; - xcp->regs[REG_PC] = (uint32)tcb->start; -#ifdef CONFIG_SUPPRESS_INTERRUPTS - xcp->regs[REG_CPSR] = SVC_MODE | PSR_I_BIT | PSR_F_BIT; + xcp->regs[REG_SP] = (uint32)tcb->adj_stack_ptr; + xcp->regs[REG_PC] = (uint32)tcb->start; + +#ifdef __thumb2__ +# ifdef CONFIG_SUPPRESS_INTERRUPTS + xcp->regs[REG_PRIMASK] = 1; +# endif #else - xcp->regs[REG_CPSR] = SVC_MODE | PSR_F_BIT; +# ifdef CONFIG_SUPPRESS_INTERRUPTS + xcp->regs[REG_CPSR] = SVC_MODE | PSR_I_BIT | PSR_F_BIT; +# else + xcp->regs[REG_CPSR] = SVC_MODE | PSR_F_BIT; +# endif #endif } diff --git a/nuttx/arch/arm/src/common/up_schedulesigaction.c b/nuttx/arch/arm/src/common/up_schedulesigaction.c index 36be3eb24..fb6798468 100644 --- a/nuttx/arch/arm/src/common/up_schedulesigaction.c +++ b/nuttx/arch/arm/src/common/up_schedulesigaction.c @@ -146,16 +146,26 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver) * the signals have been delivered. */ - tcb->xcp.sigdeliver = sigdeliver; - tcb->xcp.saved_pc = current_regs[REG_PC]; - tcb->xcp.saved_cpsr = current_regs[REG_CPSR]; + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = current_regs[REG_PC]; +#ifdef __thumb2__ + tcb->xcp.saved_primask = current_regs[REG_PRIMASK]; + tcb->xcp.saved_xpsr = current_regs[REG_XPSR]; +#else + tcb->xcp.saved_cpsr = current_regs[REG_CPSR]; +#endif /* Then set up to vector to the trampoline with interrupts * disabled */ - current_regs[REG_PC] = (uint32)up_sigdeliver; - current_regs[REG_CPSR] = SVC_MODE | PSR_I_BIT | PSR_F_BIT; + current_regs[REG_PC] = (uint32)up_sigdeliver; +#ifdef __thumb2__ + current_regs[REG_PRIMASK] = 1; + current_regs[REG_XPSR] = 0; +#else + current_regs[REG_CPSR] = SVC_MODE | PSR_I_BIT | PSR_F_BIT; +#endif /* And make sure that the saved context in the TCB * is the same as the interrupt return context. @@ -178,16 +188,26 @@ void up_schedule_sigaction(_TCB *tcb, sig_deliver_t sigdeliver) * the signals have been delivered. */ - tcb->xcp.sigdeliver = sigdeliver; - tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC]; - tcb->xcp.saved_cpsr = tcb->xcp.regs[REG_CPSR]; + tcb->xcp.sigdeliver = sigdeliver; + tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC]; +#ifdef __thumb2__ + tcb->xcp.saved_primask = tcb->xcp.regs[REG_PRIMASK]; + tcb->xcp.saved_xpsr = tcb->xcp.regs[REG_XPSR]; +#else + tcb->xcp.saved_cpsr = tcb->xcp.regs[REG_CPSR]; +#endif /* Then set up to vector to the trampoline with interrupts * disabled */ - tcb->xcp.regs[REG_PC] = (uint32)up_sigdeliver; - tcb->xcp.regs[REG_CPSR] = SVC_MODE | PSR_I_BIT | PSR_F_BIT; + tcb->xcp.regs[REG_PC] = (uint32)up_sigdeliver; +#ifdef __thumb2__ + tcb->xcp.regs[REG_PRIMASK] = 1; + tcb->xcp.regs[REG_XPSR] = 0; +#else + tcb->xcp.regs[REG_CPSR] = SVC_MODE | PSR_I_BIT | PSR_F_BIT; +#endif } irqrestore(flags); diff --git a/nuttx/arch/arm/src/common/up_sigdeliver.c b/nuttx/arch/arm/src/common/up_sigdeliver.c index 16227ae21..bf5661696 100644 --- a/nuttx/arch/arm/src/common/up_sigdeliver.c +++ b/nuttx/arch/arm/src/common/up_sigdeliver.c @@ -102,9 +102,13 @@ void up_sigdeliver(void) /* Save the real return state on the stack. */ up_copystate(regs, rtcb->xcp.regs); - regs[REG_PC] = rtcb->xcp.saved_pc; - regs[REG_CPSR] = rtcb->xcp.saved_cpsr; - + regs[REG_PC] = rtcb->xcp.saved_pc; +#ifdef __thumb2__ + regs[REG_PRIMASK] = rtcb->xcp.saved_primask; + regs[REG_XPSR] = rtcb->xcp.saved_xpsr; +#else + regs[REG_CPSR] = rtcb->xcp.saved_cpsr; +#endif /* Get a local copy of the sigdeliver function pointer. * we do this so that we can nullify the sigdeliver * function point in the TCB and accept more signal @@ -117,7 +121,11 @@ void up_sigdeliver(void) /* Then restore the task interrupt statat. */ +#ifdef __thumb2__ + irqrestore((uint16)regs[REG_PRIMASK]); +#else irqrestore(regs[REG_CPSR]); +#endif /* Deliver the signals */ diff --git a/nuttx/arch/arm/src/lm3s/lm3s_vectors.S b/nuttx/arch/arm/src/lm3s/lm3s_vectors.S index 3f196ae92..c17a387ae 100644 --- a/nuttx/arch/arm/src/lm3s/lm3s_vectors.S +++ b/nuttx/arch/arm/src/lm3s/lm3s_vectors.S @@ -38,6 +38,7 @@ ************************************************************************************/
#include <nuttx/config.h>
+#include <arch/irq.h>
/************************************************************************************
* Preprocessor Definitions
@@ -64,6 +65,10 @@ .globl dispach_irq
+ .syntax unified
+ .thumb
+ .file "lm3s_vectors.S"
+
/************************************************************************************
* Macros
************************************************************************************/
@@ -76,8 +81,8 @@ .macro HANDLER, label, irqno
\label:
- mov r0, \irqno
- br lm3s_irqcommon
+ mov r0, #\irqno
+ b lm3s_irqcommon
.endm
/************************************************************************************
@@ -86,7 +91,7 @@ .section .vectors, "ax"
.code 16
- .align 0
+ .align 2
.globl lm3s_vectors
.type lm3s_vectors, function
@@ -177,7 +182,6 @@ lm3s_vectors: ************************************************************************************/
.text
- .thumb_func
.type handlers, function
handlers:
HANDLER lm3s_reserved, LMSB_IRQ_RESERVED /* Unexpected/reserved vector */
@@ -194,8 +198,8 @@ handlers: #ifdef CONFIG_ARCH_CHIP_LM3S6918
HANDLER lm3s_gpioa, LM3S_IRQ_GPIOA /* Vector 16: GPIO Port A */
HANDLER lm3s_gpiob, LM3S_IRQ_GPIOB /* Vector 17: GPIO Port B */
- HANDLER lm3s_gpiod, LM3S_IRQ_GPIOC /* Vector 18: GPIO Port C */
- HANDLER lm3s_gpioe, LM3S_IRQ_GPIOD /* Vector 19: GPIO Port D */
+ HANDLER lm3s_gpioc, LM3S_IRQ_GPIOC /* Vector 18: GPIO Port C */
+ HANDLER lm3s_gpiod, LM3S_IRQ_GPIOD /* Vector 19: GPIO Port D */
HANDLER lm3s_gpioe, LM3S_IRQ_GPIOE /* Vector 20: GPIO Port E */
HANDLER lm3s_uart0, LM3S_IRQ_UART0 /* Vector 21: UART 0 */
HANDLER lm3s_uart1, LM3S_IRQ_UART1 /* Vector 22: UART 1 */
@@ -248,9 +252,10 @@ lm3s_irqcommon: /* Complete the context save */
mrs r1, psp /* R1=The process stack pointer */
- mov r3, r1 /* R3=Copy of the process stack pointer */
- add r3, #HW_XCPT_SIZE /* R3=PSP before the interrupt was taken */
- stmdb r1!, {r3-r11} /* Save the remaining registers plus the SP value */
+ mov r2, r1 /* R2=Copy of the process stack pointer */
+ add r2, #HW_XCPT_SIZE /* R2=PSP before the interrupt was taken */
+ mrs r3, primask /* R3=Current PRIMASK setting */
+ stmdb r1!, {r2-r11} /* Save the remaining registers plus the SP value */
/* Disable interrupts, select the stack to use for interrupt handling
* and call up_doirq to handle the interrupt
@@ -286,15 +291,21 @@ lm3s_irqcommon: */
add r1, r0, #(XCPTCONTEXT_SIZE-4) /* r2=offset HW save area */
- ldmia r1, {r4, r11} /* Eight registers in HW save area */
+ ldmia r1, {r4-r11} /* Eight registers in HW save area */
ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */
- stmdb r1!, {r4, r11} /* Eight registers in HW save area */
- mov psp, r1 /* New PSP */
+ stmdb r1!, {r4-r11} /* Eight registers in HW save area */
+ msr psp, r1 /* New PSP */
/* We simply need to "unwind" the same stack frame that we created */
1:
+ stmdb r0!, {r2-r11} /* Recover R4-R11 + 2 temp values */
+
+ /* Do we need to restore interrupts? */
+
+ tst r3, #1 /* PRIMASK it 1=1 means that interrupts are masked */
+ bne 2f
cpsie i /* Restore interrupts */
- stmdb r0!, {r3-r11} /* Recover R4-R11 (R3 does not have the correct value yet) * the remaining registers plus the SP value */
+2:
bx r14 /* And return */
.size handler, .-handlers
|