/* * 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 /* * Macro to save the General purpose registers including the banked * registers to the SMC context on entry due a SMC call. On return, r0 * contains the pointer to the `smc_context_t`. */ .macro smcc_save_gp_mode_regs push {r0-r4, lr} ldcopr r0, SCR and r0, r0, #SCR_NS_BIT bl smc_get_ctx /* Save r5 - r12 in the SMC context */ add r1, r0, #SMC_CTX_GPREG_R5 stm r1!, {r5-r12} /* * Pop r0 - r4, lr to r4 - r8, lr from stack and then save * it to SMC context. */ pop {r4-r8, lr} stm r0, {r4-r8} /* 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 r1!, {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 r1!, {r4-r12, lr} .endm /* * Macro to restore the General purpose registers including the banked * registers from the SMC context prior to exit from the SMC call. * r0 must point to the `smc_context_t` to restore from. */ .macro smcc_restore_gp_mode_regs /* Restore the banked registers including the current SPSR and LR */ 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, lr} 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 rest of the general purpose registers */ ldm r0, {r0-r12} .endm #endif /* __SMCC_MACROS_S__ */