diff options
author | Benjamin Walsh <benjamin.walsh@windriver.com> | 2016-10-01 18:49:36 -0400 |
---|---|---|
committer | Maureen Helm <maureen.helm@nxp.com> | 2016-10-07 22:51:11 +0000 |
commit | fc59e5b584d72687d4684563cf09c531f234c1f6 (patch) | |
tree | 0adc151f4bb1c550511382f6ce05fc9d9d0c38ef /arch | |
parent | 33118f9212277303f76d21b2e2842f79bdce9e7d (diff) |
unified/arm: fix saving of registers in __pendsv()
The unified kernel calls a function (_get_next_ready_thread) to fetch
the next thread to run: it thus must save caller-saved registers that
are expected to hold a value before calling such function.
The callee-saved registers are available after saving them in the
outgoing thread's stack, so use some of those instead to reduce the
number of registers to save before calling _get_next_ready_thread. Also,
save caller-saved registers in callee-saved registers instead of on the
stack to reduce memory accesses.
This issue did not show up previously, probably because
_get_next_ready_thread did not use the regsiters that had to be saved,
but an upcoming optimization to that function stomps on them.
Change-Id: I27dcededace846e623c3870d907f0d4c464173bf
Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/core/swap.S | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/arch/arm/core/swap.S b/arch/arm/core/swap.S index 8762dce3f..9f061e81d 100644 --- a/arch/arm/core/swap.S +++ b/arch/arm/core/swap.S @@ -92,8 +92,8 @@ SECTION_FUNC(TEXT, __pendsv) * to pend PendSV have been taken with the current kernel * state and this is what we're handling currently. */ - ldr ip, =_SCS_ICSR - ldr r3, =_SCS_ICSR_UNPENDSV + ldr v4, =_SCS_ICSR + ldr v3, =_SCS_ICSR_UNPENDSV /* protect the kernel state while we play with the thread lists */ movs.n r0, #_EXC_IRQ_DEFAULT_PRIO @@ -102,9 +102,11 @@ SECTION_FUNC(TEXT, __pendsv) /* find out incoming thread (fiber or task) */ #ifdef CONFIG_KERNEL_V2 - push {lr} + mov.n v2, lr + movs.n v1, r1 blx _get_next_ready_thread - pop {lr} + movs.n r1, v1 + mov.n lr, v2 movs.n r2, r0 #else /* is there a fiber ready ? */ @@ -137,8 +139,8 @@ SECTION_FUNC(TEXT, __pendsv) * has been handled. */ - /* _SCS_ICSR is still in ip and _SCS_ICSR_UNPENDSV in r3 */ - str r3, [ip, #0] + /* _SCS_ICSR is still in v4 and _SCS_ICSR_UNPENDSV in v3 */ + str v3, [v4, #0] /* restore BASEPRI for the incoming thread */ ldr r0, [r2, #__tTCS_basepri_OFFSET] |