mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-08-18 10:27:06 +02:00
The current SMC context data structure `smc_ctx_t` and related helpers are optimized for case when SMC call does not result in world switch. This was the case for SP_MIN and BL1 cold boot flow. But the firmware update usecase requires world switch as a result of SMC and the current SMC context helpers were not helping very much in this regard. Therefore this patch does the following changes to improve this: 1. Add monitor stack pointer, `spmon` to `smc_ctx_t` The C Runtime stack pointer in monitor mode, `sp_mon` is added to the SMC context, and the `smc_ctx_t` pointer is cached in `sp_mon` prior to exit from Monitor mode. This makes is easier to retrieve the context when the next SMC call happens. As a result of this change, the SMC context helpers no longer depend on the stack to save and restore the register. This aligns it with the context save and restore mechanism in AArch64. 2. Add SCR in `smc_ctx_t` Adding the SCR register to `smc_ctx_t` makes it easier to manage this register state when switching between non secure and secure world as a result of an SMC call. Change-Id: I5e12a7056107c1701b457b8f7363fdbf892230bf Signed-off-by: Soby Mathew <soby.mathew@arm.com> Signed-off-by: dp-arm <dimitris.papastamos@arm.com>
112 lines
2.5 KiB
ArmAsm
112 lines
2.5 KiB
ArmAsm
/*
|
|
* Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
#ifndef __SMCC_MACROS_S__
|
|
#define __SMCC_MACROS_S__
|
|
|
|
#include <arch.h>
|
|
|
|
/*
|
|
* Macro to save the General purpose registers (r0 - r12), the banked
|
|
* spsr, lr, sp registers and the `scr` register to the SMC context on entry
|
|
* due a SMC call. The `lr` of the current mode (monitor) is expected to be
|
|
* already saved. The `sp` must point to the `smc_ctx_t` to save to.
|
|
*/
|
|
.macro smcc_save_gp_mode_regs
|
|
/* Save r0 - r12 in the SMC context */
|
|
stm sp, {r0-r12}
|
|
mov r0, sp
|
|
add r0, r0, #SMC_CTX_SP_USR
|
|
|
|
/* Save the banked registers including the current SPSR and LR */
|
|
mrs r4, sp_usr
|
|
mrs r5, lr_usr
|
|
mrs r6, spsr_irq
|
|
mrs r7, sp_irq
|
|
mrs r8, lr_irq
|
|
mrs r9, spsr_fiq
|
|
mrs r10, sp_fiq
|
|
mrs r11, lr_fiq
|
|
mrs r12, spsr_svc
|
|
stm r0!, {r4-r12}
|
|
|
|
mrs r4, sp_svc
|
|
mrs r5, lr_svc
|
|
mrs r6, spsr_abt
|
|
mrs r7, sp_abt
|
|
mrs r8, lr_abt
|
|
mrs r9, spsr_und
|
|
mrs r10, sp_und
|
|
mrs r11, lr_und
|
|
mrs r12, spsr
|
|
stm r0!, {r4-r12}
|
|
|
|
/* lr_mon is already saved by caller */
|
|
ldcopr r4, SCR
|
|
str r4, [sp, #SMC_CTX_SCR]
|
|
.endm
|
|
|
|
/*
|
|
* Macro to restore the `smc_ctx_t`, which includes the General purpose
|
|
* registers and banked mode registers, and exit from the monitor mode.
|
|
* r0 must point to the `smc_ctx_t` to restore from.
|
|
*/
|
|
.macro monitor_exit
|
|
/*
|
|
* Save the current sp and restore the smc context
|
|
* pointer to sp which will be used for handling the
|
|
* next SMC.
|
|
*/
|
|
str sp, [r0, #SMC_CTX_SP_MON]
|
|
mov sp, r0
|
|
|
|
/*
|
|
* Restore SCR first so that we access the right banked register
|
|
* when the other mode registers are restored.
|
|
*/
|
|
ldr r1, [r0, #SMC_CTX_SCR]
|
|
stcopr r1, SCR
|
|
isb
|
|
|
|
/* Restore the banked registers including the current SPSR */
|
|
add r1, r0, #SMC_CTX_SP_USR
|
|
ldm r1!, {r4-r12}
|
|
msr sp_usr, r4
|
|
msr lr_usr, r5
|
|
msr spsr_irq, r6
|
|
msr sp_irq, r7
|
|
msr lr_irq, r8
|
|
msr spsr_fiq, r9
|
|
msr sp_fiq, r10
|
|
msr lr_fiq, r11
|
|
msr spsr_svc, r12
|
|
|
|
ldm r1!, {r4-r12}
|
|
msr sp_svc, r4
|
|
msr lr_svc, r5
|
|
msr spsr_abt, r6
|
|
msr sp_abt, r7
|
|
msr lr_abt, r8
|
|
msr spsr_und, r9
|
|
msr sp_und, r10
|
|
msr lr_und, r11
|
|
/*
|
|
* Use the `_fsxc` suffix explicitly to instruct the assembler
|
|
* to update all the 32 bits of SPSR. Else, by default, the
|
|
* assembler assumes `_fc` suffix which only modifies
|
|
* f->[31:24] and c->[7:0] bits of SPSR.
|
|
*/
|
|
msr spsr_fsxc, r12
|
|
|
|
/* Restore the LR */
|
|
ldr lr, [r0, #SMC_CTX_LR_MON]
|
|
|
|
/* Restore the rest of the general purpose registers */
|
|
ldm r0, {r0-r12}
|
|
eret
|
|
.endm
|
|
|
|
#endif /* __SMCC_MACROS_S__ */
|