diff options
author | Jun Nie <jun.nie@linaro.org> | 2018-08-21 15:29:34 +0800 |
---|---|---|
committer | Jun Nie <jun.nie@linaro.org> | 2018-08-24 00:22:51 +0800 |
commit | 419b79b7423277fadb1bc17d963648a2b4a6c732 (patch) | |
tree | f0d211bc2461a465d87912b8d616426fa6a35273 | |
parent | d9f545d481a2572e021ba3b1166418a1571e4d11 (diff) |
Aarch32: Add IRQ stack for ARMv7
Add stack for IRQ mode for ARMv7. Otherwise, stack operation in
IRQ mode result data abort due to data access to random address.
Signed-off-by: Jun Nie <jun.nie@linaro.org>
-rw-r--r-- | framework/tftf.ld.S | 6 | ||||
-rw-r--r-- | include/lib/aarch32/arch.h | 7 | ||||
-rw-r--r-- | plat/common/aarch32/platform_mp_stack.S | 21 |
3 files changed, 34 insertions, 0 deletions
diff --git a/framework/tftf.ld.S b/framework/tftf.ld.S index cf97e83..73f4e2f 100644 --- a/framework/tftf.ld.S +++ b/framework/tftf.ld.S @@ -72,6 +72,12 @@ SECTIONS __STACKS_END__ = .; } >RAM + stacks (NOLOAD) : { + __IRQ_STACKS_START__ = .; + *(irq_stacks) + __IRQ_STACKS_END__ = .; + } >RAM + /* * The .bss section gets initialised to 0 at runtime. * Its base address must be 16-byte aligned. diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h index e8bde12..dc28195 100644 --- a/include/lib/aarch32/arch.h +++ b/include/lib/aarch32/arch.h @@ -353,6 +353,13 @@ ((endian) & SPSR_E_MASK) << SPSR_E_SHIFT | \ ((aif) & SPSR_AIF_MASK) << SPSR_AIF_SHIFT) +#define SPSR_ARMV7(mode, aif) \ + (MODE_RW_32 << MODE_RW_SHIFT | \ + ((mode) & MODE32_MASK) << MODE32_SHIFT | \ + ((aif) & SPSR_AIF_MASK) << SPSR_AIF_SHIFT) + +#define SPSR_ARMV7_IRQ SPSR_ARMV7(MODE32_irq, SPSR_FIQ_BIT | SPSR_IRQ_BIT) + /******************************************************************************* * Definitions of register offsets and fields in the CNTBaseN Frame of the * system level implementation of the Generic Timer. diff --git a/plat/common/aarch32/platform_mp_stack.S b/plat/common/aarch32/platform_mp_stack.S index 94ef15d..d0f9e6f 100644 --- a/plat/common/aarch32/platform_mp_stack.S +++ b/plat/common/aarch32/platform_mp_stack.S @@ -38,6 +38,7 @@ .weak platform_set_stack .weak platform_get_stack .weak platform_set_coherent_stack + .weak irq_set_stack /* ----------------------------------------------------- * void platform_set_coherent_stack (unsigned long mpidr) @@ -79,6 +80,14 @@ func platform_set_stack mov r9, lr get_mp_stack platform_normal_stacks, PLATFORM_STACK_SIZE mov sp, r0 + +#if ARM_ARCH_MAJOR != 8 + mrs r2, cpsr + msr cpsr, #SPSR_ARMV7_IRQ + get_mp_stack irq_stacks, IRQ_STACK_SIZE + mov sp, r0 + msr cpsr, r2 +#endif bx r9 endfunc platform_set_stack @@ -92,6 +101,18 @@ endfunc platform_set_stack declare_stack platform_normal_stacks, tftf_normal_stacks, \ PLATFORM_STACK_SIZE, PLATFORM_CORE_COUNT +#if ARM_ARCH_MAJOR != 8 + /* ----------------------------------------------------- + * Per-cpu stacks in normal memory. + * Used for C code during runtime execution (when coherent + * stacks are not required). + * Each cpu gets a stack of IRQ_STACK_SIZE bytes. + * ----------------------------------------------------- + */ +declare_stack irq_stacks, tftf_normal_stacks, \ + IRQ_STACK_SIZE, PLATFORM_CORE_COUNT +#endif + /* ----------------------------------------------------- * Per-cpu stacks in device memory. * Used for C code just before power down or right after |