summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJun Nie <jun.nie@linaro.org>2018-08-21 15:29:34 +0800
committerJun Nie <jun.nie@linaro.org>2018-08-24 00:22:51 +0800
commit419b79b7423277fadb1bc17d963648a2b4a6c732 (patch)
treef0d211bc2461a465d87912b8d616426fa6a35273
parentd9f545d481a2572e021ba3b1166418a1571e4d11 (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.S6
-rw-r--r--include/lib/aarch32/arch.h7
-rw-r--r--plat/common/aarch32/platform_mp_stack.S21
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