ARMv7-A: Need 8-byte stack alignment when callign C code from interrupt handlers. This change needs to be ported to other ARM architectures as well

This commit is contained in:
Gregory Nutt 2013-07-23 14:47:16 -06:00
parent 14df812735
commit 812bf02972
3 changed files with 75 additions and 30 deletions

View File

@ -5165,4 +5165,7 @@
definitions for the SAMA5D3 (2013-7-23).
* arch/arm/src/sama5/chip/: New header files for SAMA5 AXI Matrix
SFR, and BSC blocks (2013-7-23).
* arch/arm/src/armv7-a/arm_vectors.S: Force 8-byte stack alignment
in interrupt handlers before calling C code. Other ARM
architectures need to do this as well (2013-7-23).

29
TODO
View File

@ -1,4 +1,4 @@
NuttX TODO List (Last updated June 23, 2013)
NuttX TODO List (Last updated July 23, 2013)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This file summarizes known NuttX bugs, limitations, inconsistencies with
@ -24,7 +24,7 @@ nuttx/
(1) Documentation (Documentation/)
(6) Build system / Toolchains
(5) Linux/Cywgin simulation (arch/sim)
(4) ARM (arch/arm/)
(5) ARM (arch/arm/)
(1) ARM/C5471 (arch/arm/src/c5471/)
(3) ARM/DM320 (arch/arm/src/dm320/)
(2) ARM/i.MX (arch/arm/src/imx/)
@ -1455,6 +1455,31 @@ o ARM (arch/arm/)
If your design needs continous interrupts like this, please try
the above change and, please, submit a patch with the working fix.
Title: STACK ALIGNMENT IN INTERRUPT HANDLERS
Description: The EABI standard requires that the stack always have a 32-byte
alignment. There is no guaratee at present that the stack will be
so aligned in an interrupt handler. Therefore, I would expect some
issues if, for example, floating point or perhaps long long operations
were performed in an interrupt handler.
This issue exists for ARM7, ARM9, Cortex-M0, Cortex-M3, and
Cortex-M4 but has been addressed for the Cortex-A5. The fix
is really simple can cannot be incorporated without some
substantial testing. For ARM, the fix is the following logic
arround each call into C code from assembly:
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignement */
bl cfunction /* Call the C function */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
This same issue applies to the interrupt stack which is, I think
improperly aligned in almost all cases (except Cortex-A5).
Status: Open
Priority: Low for me because I never do floating point operations in
interrupt handlers.
o ARM/C5471 (arch/arm/src/c5471/)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -134,10 +134,15 @@ arm_vectorirq:
#if CONFIG_ARCH_INTERRUPTSTACK > 3
ldr sp, .Lirqstackbase /* SP = interrupt stack base */
str r0, [sp] /* Save the user stack pointer */
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignement */
bl up_decodeirq /* Call the handler */
ldr sp, [sp] /* Restore the user stack pointer */
ldr sp, [r4] /* Restore the user stack pointer */
#else
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignement */
bl up_decodeirq /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
#endif
/* Restore the CPSR, SVC modr registers and return */
@ -192,7 +197,10 @@ arm_vectorswi:
mov fp, #0 /* Init frame pointer */
mov r0, sp /* Get r0=xcp */
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignement */
bl up_syscall /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
/* Restore the CPSR, SVC modr registers and return */
@ -262,7 +270,10 @@ arm_vectordata:
mov r0, sp /* Get r0=xcp */
mrc CP15_DFAR(r1) /* Get R1=DFAR */
mrc CP15_DFSR(r2) /* Get r2=DFSR */
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignement */
bl arm_dataabort /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
/* Restore the CPSR, SVC modr registers and return */
@ -335,7 +346,10 @@ arm_vectorprefetch:
mov r0, sp /* Get r0=xcp */
mrc CP15_IFAR(r1) /* Get R1=IFAR */
mrc CP15_IFSR(r2) /* Get r2=IFSR */
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignement */
bl arm_prefetchabort /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
/* Restore the CPSR, SVC modr registers and return */
@ -403,7 +417,10 @@ arm_vectorundefinsn:
mov fp, #0 /* Init frame pointer */
mov r0, sp /* Get r0=xcp */
mov r4, sp /* Save the SP in a preserved register */
bic sp, sp, #7 /* Force 8-byte alignement */
bl arm_undefinedinsn /* Call the handler */
mov sp, r4 /* Restore the possibly unaligned stack pointer */
/* Restore the CPSR, SVC modr registers and return */