All ARMV7-M: Force 8-byte stack alignment when calling from assembly to C to interrupt handling

This commit is contained in:
Gregory Nutt 2015-09-15 07:37:09 -06:00
parent f7ca98c5ae
commit 39859a9645
7 changed files with 109 additions and 76 deletions

View File

@ -1,7 +1,7 @@
/************************************************************************************
* arch/arm/src/armv7-m/up_exception.S
*
* Copyright (C) 2009-2013 Gregory Nutt. All rights reserved.
* Copyright (C) 2009-2013, 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Michael Smith. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
@ -183,16 +183,17 @@ exception_common:
mov r1, sp
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Also save the top of the stack in a preserved register */
mov r4, sp
#if CONFIG_ARCH_INTERRUPTSTACK > 7
/* 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
* here prohibits nested interrupts without some additional logic!
*/
ldr sp, =g_intstackbase
push {r1} /* Save the MSP on the interrupt stack */
bl up_doirq /* R0=IRQ, R1=register save area on stack */
pop {r1} /* Recover R1=main stack pointer */
#else
/* Otherwise, we will re-use the interrupted thread's stack. That may
@ -200,10 +201,14 @@ exception_common:
* kernel mode).
*/
bl up_doirq /* R0=IRQ, R1=register save area on stack */
mrs r1, msp /* Get R1=main stack pointer */
bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */
mov sp, r2 /* Instantiate the aligned stack */
#endif
bl up_doirq /* R0=IRQ, R1=register save (msp) */
mov r1, r4 /* Recover R1=main stack pointer */
/* On return from up_doirq, R0 will hold a pointer to register context
* array to use for the interrupt return. If that return value is the same
* as current stack pointer, then things are relatively easy.
@ -312,13 +317,13 @@ exception_common:
*
************************************************************************************/
#if CONFIG_ARCH_INTERRUPTSTACK > 3
#if CONFIG_ARCH_INTERRUPTSTACK > 7
.bss
.global g_intstackalloc
.global g_intstackbase
.align 4
.align 8
g_intstackalloc:
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~7)
g_intstackbase:
.size g_intstackalloc, .-g_intstackalloc
#endif

View File

@ -191,16 +191,17 @@ exception_common:
mov r1, sp
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Also save the top of the stack in a preserved register */
mov r4, sp
#if CONFIG_ARCH_INTERRUPTSTACK > 7
/* 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
* here prohibits nested interrupts without some additional logic!
*/
ldr sp, =g_intstackbase
push {r1} /* Save the MSP on the interrupt stack */
bl up_doirq /* R0=IRQ, R1=register save area on stack */
pop {r1} /* Recover R1=main stack pointer */
#else
/* Otherwise, we will re-use the interrupted thread's stack. That may
@ -208,10 +209,14 @@ exception_common:
* kernel mode).
*/
bl up_doirq /* R0=IRQ, R1=register save (msp) */
mov r1, sp /* Recover R1=main stack pointer */
bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */
mov sp, r2 /* Instantiate the aligned stack */
#endif
bl up_doirq /* R0=IRQ, R1=register save (msp) */
mov r1, r4 /* Recover R1=main stack pointer */
/* On return from up_doirq, R0 will hold a pointer to register context
* array to use for the interrupt return. If that return value is the same
* as current stack pointer, then things are relatively easy.
@ -344,13 +349,13 @@ exception_common:
*
************************************************************************************************/
#if CONFIG_ARCH_INTERRUPTSTACK > 3
#if CONFIG_ARCH_INTERRUPTSTACK > 7
.bss
.global g_intstackalloc
.global g_intstackbase
.align 4
.align 8
g_intstackalloc:
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~7)
g_intstackbase:
.size g_intstackalloc, .-g_intstackalloc
#endif

View File

@ -2,7 +2,7 @@
* arch/arm/src/kinetis/kinetis_vectors.S
* arch/arm/src/chip/kinetis_vectors.S
*
* Copyright (C) 2011, 2013-2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2011, 2013-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -812,7 +812,7 @@ exception_common:
1:
#endif
/* r1 holds the value of the stack pointer AFTER the excption handling logic
/* r1 holds the value of the stack pointer AFTER the exception handling logic
* pushed the various registers onto the stack. Get r2 = the value of the
* stack pointer BEFORE the interrupt modified it.
*/
@ -870,16 +870,17 @@ exception_common:
mov r1, sp
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Also save the top of the stack in a preserved register */
mov r4, sp
#if CONFIG_ARCH_INTERRUPTSTACK > 7
/* 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
* here prohibits nested interrupts without some additional logic!
*/
ldr sp, =g_intstackbase
push {r1} /* Save the MSP on the interrupt stack */
bl up_doirq /* R0=IRQ, R1=register save area on stack */
pop {r1} /* Recover R1=main stack pointer */
#else
/* Otherwise, we will re-use the interrupted thread's stack. That may
@ -887,10 +888,14 @@ exception_common:
* kernel mode).
*/
bl up_doirq /* R0=IRQ, R1=register save (msp) */
mov r1, sp /* Recover R1=main stack pointer */
bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */
mov sp, r2 /* Instantiate the aligned stack */
#endif
bl up_doirq /* R0=IRQ, R1=register save (msp) */
mov r1, r4 /* Recover R1=main stack pointer */
/* On return from up_doirq, R0 will hold a pointer to register context
* array to use for the interrupt return. If that return value is the same
* as current stack pointer, then things are relatively easy.
@ -1023,13 +1028,13 @@ exception_common:
*
************************************************************************************************/
#if CONFIG_ARCH_INTERRUPTSTACK > 3
#if CONFIG_ARCH_INTERRUPTSTACK > 7
.bss
.global g_intstackalloc
.global g_intstackbase
.align 4
.align 8
g_intstackalloc:
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~7)
g_intstackbase:
.size g_intstackalloc, .-g_intstackalloc
#endif

View File

@ -1,8 +1,7 @@
/************************************************************************************************
* arch/arm/src/lpc17xx/lpc17_vectors.S
* arch/arm/src/chip/lpc17_vectors.S
*
* Copyright (C) 2010-2011, 2013-2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2010-2011, 2013-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -247,7 +246,7 @@ exception_common:
1:
#endif
/* r1 holds the value of the stack pointer AFTER the excption handling logic
/* r1 holds the value of the stack pointer AFTER the exception handling logic
* pushed the various registers onto the stack. Get r2 = the value of the
* stack pointer BEFORE the interrupt modified it.
*/
@ -305,16 +304,17 @@ exception_common:
mov r1, sp
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Also save the top of the stack in a preserved register */
mov r4, sp
#if CONFIG_ARCH_INTERRUPTSTACK > 7
/* 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
* here prohibits nested interrupts without some additional logic!
*/
ldr sp, =g_intstackbase
push {r1} /* Save the MSP on the interrupt stack */
bl up_doirq /* R0=IRQ, R1=register save area on stack */
pop {r1} /* Recover R1=main stack pointer */
#else
/* Otherwise, we will re-use the interrupted thread's stack. That may
@ -322,10 +322,14 @@ exception_common:
* kernel mode).
*/
bl up_doirq /* R0=IRQ, R1=register save (msp) */
mov r1, sp /* Recover R1=main stack pointer */
bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */
mov sp, r2 /* Instantiate the aligned stack */
#endif
bl up_doirq /* R0=IRQ, R1=register save (msp) */
mov r1, r4 /* Recover R1=main stack pointer */
/* On return from up_doirq, R0 will hold a pointer to register context
* array to use for the interrupt return. If that return value is the same
* as current stack pointer, then things are relatively easy.
@ -458,13 +462,13 @@ exception_common:
*
************************************************************************************************/
#if CONFIG_ARCH_INTERRUPTSTACK > 3
#if CONFIG_ARCH_INTERRUPTSTACK > 7
.bss
.global g_intstackalloc
.global g_intstackbase
.align 4
.align 8
g_intstackalloc:
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~7)
g_intstackbase:
.size g_intstackalloc, .-g_intstackalloc
#endif

View File

@ -1,7 +1,7 @@
/************************************************************************************************
* arch/arm/src/sam34/sam_vectors.S
*
* Copyright (C) 2009-2010, 2013-2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2009-2010, 2013-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -260,7 +260,7 @@ exception_common:
1:
#endif
/* r1 holds the value of the stack pointer AFTER the excption handling logic
/* r1 holds the value of the stack pointer AFTER the exception handling logic
* pushed the various registers onto the stack. Get r2 = the value of the
* stack pointer BEFORE the interrupt modified it.
*/
@ -318,16 +318,17 @@ exception_common:
mov r1, sp
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Also save the top of the stack in a preserved register */
mov r4, sp
#if CONFIG_ARCH_INTERRUPTSTACK > 7
/* 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
* here prohibits nested interrupts without some additional logic!
*/
ldr sp, =g_intstackbase
push {r1} /* Save the MSP on the interrupt stack */
bl up_doirq /* R0=IRQ, R1=register save area on stack */
pop {r1} /* Recover R1=main stack pointer */
#else
/* Otherwise, we will re-use the interrupted thread's stack. That may
@ -335,10 +336,14 @@ exception_common:
* kernel mode).
*/
bl up_doirq /* R0=IRQ, R1=register save (msp) */
mov r1, sp /* Recover R1=main stack pointer */
bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */
mov sp, r2 /* Instantiate the aligned stack */
#endif
bl up_doirq /* R0=IRQ, R1=register save (msp) */
mov r1, r4 /* Recover R1=main stack pointer */
/* On return from up_doirq, R0 will hold a pointer to register context
* array to use for the interrupt return. If that return value is the same
* as current stack pointer, then things are relatively easy.
@ -471,13 +476,13 @@ exception_common:
*
************************************************************************************************/
#if CONFIG_ARCH_INTERRUPTSTACK > 3
#if CONFIG_ARCH_INTERRUPTSTACK > 7
.bss
.global g_intstackalloc
.global g_intstackbase
.align 4
.align 8
g_intstackalloc:
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~7)
g_intstackbase:
.size g_intstackalloc, .-g_intstackalloc
#endif

View File

@ -1,8 +1,7 @@
/************************************************************************************
* arch/arm/src/stm32/stm32_vectors.S
* arch/arm/src/chip/stm32_vectors.S
*
* Copyright (C) 2009-2013 Gregory Nutt. All rights reserved.
* Copyright (C) 2009-2013, 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -280,7 +279,7 @@ exception_common:
1:
#endif
/* r1 holds the value of the stack pointer AFTER the excption handling logic
/* r1 holds the value of the stack pointer AFTER the exception handling logic
* pushed the various registers onto the stack. Get r2 = the value of the
* stack pointer BEFORE the interrupt modified it.
*/
@ -338,16 +337,17 @@ exception_common:
mov r1, sp
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Also save the top of the stack in a preserved register */
mov r4, sp
#if CONFIG_ARCH_INTERRUPTSTACK > 7
/* 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
* here prohibits nested interrupts without some additional logic!
*/
ldr sp, =g_intstackbase
push {r1} /* Save the MSP on the interrupt stack */
bl up_doirq /* R0=IRQ, R1=register save area on stack */
pop {r1} /* Recover R1=main stack pointer */
#else
/* Otherwise, we will re-use the interrupted thread's stack. That may
@ -355,10 +355,14 @@ exception_common:
* kernel mode).
*/
bl up_doirq /* R0=IRQ, R1=register save (msp) */
mov r1, sp /* Recover R1=main stack pointer */
bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */
mov sp, r2 /* Instantiate the aligned stack */
#endif
bl up_doirq /* R0=IRQ, R1=register save (msp) */
mov r1, r4 /* Recover R1=main stack pointer */
/* On return from up_doirq, R0 will hold a pointer to register context
* array to use for the interrupt return. If that return value is the same
* as current stack pointer, then things are relatively easy.
@ -491,13 +495,13 @@ exception_common:
*
************************************************************************************/
#if CONFIG_ARCH_INTERRUPTSTACK > 3
#if CONFIG_ARCH_INTERRUPTSTACK > 7
.bss
.global g_intstackalloc
.global g_intstackbase
.align 4
.align 8
g_intstackalloc:
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~7)
g_intstackbase:
.size g_intstackalloc, .-g_intstackalloc
#endif

View File

@ -1,7 +1,7 @@
/************************************************************************************
* arch/arm/src/tiva/tiva_vectors.S
*
* Copyright (C) 2009-2010, 2013-2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2009-2010, 2013-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -237,7 +237,7 @@ exception_common:
1:
#endif
/* r1 holds the value of the stack pointer AFTER the excption handling logic
/* r1 holds the value of the stack pointer AFTER the exception handling logic
* pushed the various registers onto the stack. Get r2 = the value of the
* stack pointer BEFORE the interrupt modified it.
*/
@ -295,16 +295,17 @@ exception_common:
mov r1, sp
#if CONFIG_ARCH_INTERRUPTSTACK > 3
/* Also save the top of the stack in a preserved register */
mov r4, sp
#if CONFIG_ARCH_INTERRUPTSTACK > 7
/* 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
* here prohibits nested interrupts without some additional logic!
*/
ldr sp, =g_intstackbase
push {r1} /* Save the MSP on the interrupt stack */
bl up_doirq /* R0=IRQ, R1=register save area on stack */
pop {r1} /* Recover R1=main stack pointer */
#else
/* Otherwise, we will re-use the interrupted thread's stack. That may
@ -312,10 +313,14 @@ exception_common:
* kernel mode).
*/
bl up_doirq /* R0=IRQ, R1=register save (msp) */
mov r1, sp /* Recover R1=main stack pointer */
bic r2, r4, #7 /* Get the stack pointer with 8-byte alignment */
mov sp, r2 /* Instantiate the aligned stack */
#endif
bl up_doirq /* R0=IRQ, R1=register save (msp) */
mov r1, r4 /* Recover R1=main stack pointer */
/* On return from up_doirq, R0 will hold a pointer to register context
* array to use for the interrupt return. If that return value is the same
* as current stack pointer, then things are relatively easy.
@ -448,13 +453,13 @@ exception_common:
*
************************************************************************************/
#if CONFIG_ARCH_INTERRUPTSTACK > 3
#if CONFIG_ARCH_INTERRUPTSTACK > 7
.bss
.global g_intstackalloc
.global g_intstackbase
.align 4
.align 8
g_intstackalloc:
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~7)
g_intstackbase:
.size g_intstackalloc, .-g_intstackalloc
#endif