diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-12-23 14:11:32 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-12-23 14:11:32 -0600 |
commit | 92fd02fcc98084502fad0d251b50d6f9261da353 (patch) | |
tree | d00ad3c287176d5cc5e5d6a20284de9c9e9f4ab2 /nuttx/arch | |
parent | 510b3dc3b44605010d2a1434f8cbe5e6f5e45a2b (diff) | |
download | nuttx-92fd02fcc98084502fad0d251b50d6f9261da353.tar.gz nuttx-92fd02fcc98084502fad0d251b50d6f9261da353.tar.bz2 nuttx-92fd02fcc98084502fad0d251b50d6f9261da353.zip |
Need to protect state on stack to do nested interrupt handling
Diffstat (limited to 'nuttx/arch')
-rw-r--r-- | nuttx/arch/arm/src/armv7-m/up_exception.S | 40 | ||||
-rw-r--r-- | nuttx/arch/arm/src/kinetis/kinetis_vectors.S | 29 | ||||
-rw-r--r-- | nuttx/arch/arm/src/lm/lm_vectors.S | 29 | ||||
-rw-r--r-- | nuttx/arch/arm/src/lpc17xx/lpc17_vectors.S | 29 | ||||
-rw-r--r-- | nuttx/arch/arm/src/sam34/sam_vectors.S | 29 | ||||
-rw-r--r-- | nuttx/arch/arm/src/stm32/stm32_vectors.S | 29 |
6 files changed, 114 insertions, 71 deletions
diff --git a/nuttx/arch/arm/src/armv7-m/up_exception.S b/nuttx/arch/arm/src/armv7-m/up_exception.S index 3eb8f97e3..517525415 100644 --- a/nuttx/arch/arm/src/armv7-m/up_exception.S +++ b/nuttx/arch/arm/src/armv7-m/up_exception.S @@ -126,11 +126,12 @@ exception_common: /* The EXC_RETURN value tells us whether the context is on the MSP or PSP */ tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ - ite eq /* next two instructions conditional */ - mrseq r1, msp /* R1=The main stack pointer */ - mrsne r1, psp /* R1=The process stack pointer */ + 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 */ - mov r2, r1 /* R2=Copy of the main/process stack pointer */ +1: + mov r2, sp /* R2=Copy of the main/process stack pointer */ add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */ /* (ignoring the xPSR[9] alignment bit) */ #ifdef CONFIG_ARMV7M_USEBASEPRI @@ -152,11 +153,11 @@ exception_common: * where to put the registers. */ - vstmdb r1!, {s16-s31} /* Save the non-volatile FP context */ + vstmdb sp!, {s16-s31} /* Save the non-volatile FP context */ #endif - stmdb r1!, {r2-r11,r14} /* Save the remaining registers plus the SP/PRIMASK values */ + stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP/PRIMASK values */ #ifndef CONFIG_ARCH_HIPRI_INTERRUPT /* Disable interrupts, select the stack to use for interrupt handling @@ -174,6 +175,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 @@ -191,9 +200,8 @@ exception_common: * kernel mode). */ - msr msp, r1 /* We are using the main stack pointer */ bl up_doirq /* R0=IRQ, R1=register save area on stack */ - mrs r1, msp /* Recover R1=main stack pointer */ + mrs r1, msp /* Get R1=main stack pointer */ #endif /* On return from up_doirq, R0 will hold a pointer to register context @@ -202,7 +210,7 @@ exception_common: */ cmp r0, r1 /* Context switch? */ - beq 1f /* Branch if no context switch */ + beq 2f /* Branch if no context switch */ /* We are returning with a pending context switch. This case is different * because in this case, the register save structure does not lie on the @@ -235,9 +243,9 @@ exception_common: vldmia r0, {s16-s31} /* Recover S16-S31 */ #endif - b 2f /* Re-join common logic */ + b 3f /* Re-join common logic */ -1: +2: /* We are returning with no context switch. We simply need to "unwind" * the same stack frame that we created at entry. */ @@ -247,7 +255,7 @@ exception_common: vldmia r1!, {s16-s31} /* Recover S16-S31 */ #endif -2: +3: /* The EXC_RETURN value tells us whether we are returning on the MSP or PSP */ @@ -259,15 +267,15 @@ exception_common: mrs r2, control /* R2=Contents of the control register */ tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ - beq 3f /* Branch if privileged */ + beq 4f /* Branch if privileged */ orr r2, r2, #1 /* Unprivileged mode */ msr psp, r1 /* R1=The process stack pointer */ - b 4f -3: + b 5f +4: bic r2, r2, #1 /* Privileged mode */ msr msp, r1 /* R1=The main stack pointer */ -4: +5: msr control, r2 /* Save the updated control register */ #else tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */ diff --git a/nuttx/arch/arm/src/kinetis/kinetis_vectors.S b/nuttx/arch/arm/src/kinetis/kinetis_vectors.S index 619f133a2..be597cfa9 100644 --- a/nuttx/arch/arm/src/kinetis/kinetis_vectors.S +++ b/nuttx/arch/arm/src/kinetis/kinetis_vectors.S @@ -627,12 +627,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 @@ -640,7 +640,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 */ @@ -655,7 +655,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 @@ -664,9 +664,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 @@ -685,6 +685,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 @@ -702,7 +710,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 diff --git a/nuttx/arch/arm/src/lm/lm_vectors.S b/nuttx/arch/arm/src/lm/lm_vectors.S index 796ad5554..bdd65a543 100644 --- a/nuttx/arch/arm/src/lm/lm_vectors.S +++ b/nuttx/arch/arm/src/lm/lm_vectors.S @@ -230,12 +230,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 @@ -243,7 +243,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 */ @@ -258,7 +258,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 @@ -267,9 +267,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 @@ -288,6 +288,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 @@ -305,7 +313,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 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 diff --git a/nuttx/arch/arm/src/sam34/sam_vectors.S b/nuttx/arch/arm/src/sam34/sam_vectors.S index 4631ad13e..6ef3e2b80 100644 --- a/nuttx/arch/arm/src/sam34/sam_vectors.S +++ b/nuttx/arch/arm/src/sam34/sam_vectors.S @@ -244,12 +244,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 @@ -257,7 +257,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 */ @@ -272,7 +272,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 @@ -281,9 +281,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 @@ -302,6 +302,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 @@ -319,7 +327,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 diff --git a/nuttx/arch/arm/src/stm32/stm32_vectors.S b/nuttx/arch/arm/src/stm32/stm32_vectors.S index 00f4ebf59..da9eea46c 100644 --- a/nuttx/arch/arm/src/stm32/stm32_vectors.S +++ b/nuttx/arch/arm/src/stm32/stm32_vectors.S @@ -254,12 +254,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 @@ -267,7 +267,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 */ @@ -282,7 +282,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 @@ -291,9 +291,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 @@ -312,6 +312,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 @@ -329,7 +337,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 |