From 92fd02fcc98084502fad0d251b50d6f9261da353 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 23 Dec 2013 14:11:32 -0600 Subject: Need to protect state on stack to do nested interrupt handling --- nuttx/arch/arm/src/lpc17xx/lpc17_vectors.S | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'nuttx/arch/arm/src/lpc17xx/lpc17_vectors.S') diff --git a/nuttx/arch/arm/src/lpc17xx/lpc17_vectors.S b/nuttx/arch/arm/src/lpc17xx/lpc17_vectors.S index 4be59a4d6..dc4a7a305 100644 --- a/nuttx/arch/arm/src/lpc17xx/lpc17_vectors.S +++ b/nuttx/arch/arm/src/lpc17xx/lpc17_vectors.S @@ -239,12 +239,12 @@ exception_common: * EXC_RETURN is 0xfffffffd (unprivileged thread) */ - adds r2, r14, #3 /* If R14=0xfffffffd, then r2 == 0 */ - ite ne /* Next two instructions are conditional */ - mrsne r1, msp /* R1=The main stack pointer */ - mrseq r1, psp /* R1=The process stack pointer */ -#else - mrs r1, msp /* R1=The main stack pointer */ + tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ + beq 1f /* Branch if context already on the MSP */ + mrs r1, psp /* R1=The process stack pointer (PSP) */ + mov sp, r1 /* Set the MSP to the PSP */ + +1: #endif /* r1 holds the value of the stack pointer AFTER the excption handling logic @@ -252,7 +252,7 @@ exception_common: * stack pointer BEFORE the interrupt modified it. */ - mov r2, r1 /* R2=Copy of the main/process stack pointer */ + mov r2, sp /* R2=Copy of the main/process stack pointer */ add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */ #ifdef CONFIG_ARMV7M_USEBASEPRI mrs r3, basepri /* R3=Current BASEPRI setting */ @@ -267,7 +267,7 @@ exception_common: * cannot be used in interrupt processing). */ - sub r1, #(4*SW_FPU_REGS) + sub sp, #(4*SW_FPU_REGS) #endif /* Save the remaining registers on the stack after the registers pushed @@ -276,9 +276,9 @@ exception_common: */ #ifdef CONFIG_NUTTX_KERNEL - stmdb r1!, {r2-r11,r14} /* Save the remaining registers plus the SP value */ + stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP value */ #else - stmdb r1!, {r2-r11} /* Save the remaining registers plus the SP value */ + stmdb sp!, {r2-r11} /* Save the remaining registers plus the SP value */ #endif #ifndef CONFIG_ARCH_HIPRI_INTERRUPT @@ -297,6 +297,14 @@ exception_common: msr basepri, r2 /* Set the BASEPRI */ #endif + /* There are two arguments to up_doirq: + * + * R0 = The IRQ number + * R1 = The top of the stack points to the saved state + */ + + mov r1, sp + #if CONFIG_ARCH_INTERRUPTSTACK > 3 /* If CONFIG_ARCH_INTERRUPTSTACK is defined, we will set the MSP to use * a special special interrupt stack pointer. The way that this is done @@ -314,7 +322,6 @@ exception_common: * kernel mode). */ - mov sp, r1 /* We are using the main stack pointer */ bl up_doirq /* R0=IRQ, R1=register save (msp) */ mov r1, sp /* Recover R1=main stack pointer */ #endif -- cgit v1.2.3