1/* 2 * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6#ifndef __SMCC_MACROS_S__ 7#define __SMCC_MACROS_S__ 8 9#include <arch.h> 10 11/* 12 * Macro to save the General purpose registers (r0 - r12), the banked 13 * spsr, lr, sp registers and the `scr` register to the SMC context on entry 14 * due a SMC call. The `lr` of the current mode (monitor) is expected to be 15 * already saved. The `sp` must point to the `smc_ctx_t` to save to. 16 * Additionally, also save the 'pmcr' register as this is updated whilst 17 * executing in the secure world. 18 */ 19 .macro smcc_save_gp_mode_regs 20 /* Save r0 - r12 in the SMC context */ 21 stm sp, {r0-r12} 22 mov r0, sp 23 add r0, r0, #SMC_CTX_SP_USR 24 25 /* Save the banked registers including the current SPSR and LR */ 26 mrs r4, sp_usr 27 mrs r5, lr_usr 28 mrs r6, spsr_irq 29 mrs r7, sp_irq 30 mrs r8, lr_irq 31 mrs r9, spsr_fiq 32 mrs r10, sp_fiq 33 mrs r11, lr_fiq 34 mrs r12, spsr_svc 35 stm r0!, {r4-r12} 36 37 mrs r4, sp_svc 38 mrs r5, lr_svc 39 mrs r6, spsr_abt 40 mrs r7, sp_abt 41 mrs r8, lr_abt 42 mrs r9, spsr_und 43 mrs r10, sp_und 44 mrs r11, lr_und 45 mrs r12, spsr 46 stm r0!, {r4-r12} 47 48 /* lr_mon is already saved by caller */ 49 ldcopr r4, SCR 50 str r4, [sp, #SMC_CTX_SCR] 51 ldcopr r4, PMCR 52 str r4, [sp, #SMC_CTX_PMCR] 53 .endm 54 55/* 56 * Macro to restore the `smc_ctx_t`, which includes the General purpose 57 * registers and banked mode registers, and exit from the monitor mode. 58 * r0 must point to the `smc_ctx_t` to restore from. 59 */ 60 .macro monitor_exit 61 /* 62 * Save the current sp and restore the smc context 63 * pointer to sp which will be used for handling the 64 * next SMC. 65 */ 66 str sp, [r0, #SMC_CTX_SP_MON] 67 mov sp, r0 68 69 /* 70 * Restore SCR first so that we access the right banked register 71 * when the other mode registers are restored. 72 */ 73 ldr r1, [r0, #SMC_CTX_SCR] 74 stcopr r1, SCR 75 isb 76 77 /* 78 * Restore the PMCR register. 79 */ 80 ldr r1, [r0, #SMC_CTX_PMCR] 81 stcopr r1, PMCR 82 83 /* Restore the banked registers including the current SPSR */ 84 add r1, r0, #SMC_CTX_SP_USR 85 ldm r1!, {r4-r12} 86 msr sp_usr, r4 87 msr lr_usr, r5 88 msr spsr_irq, r6 89 msr sp_irq, r7 90 msr lr_irq, r8 91 msr spsr_fiq, r9 92 msr sp_fiq, r10 93 msr lr_fiq, r11 94 msr spsr_svc, r12 95 96 ldm r1!, {r4-r12} 97 msr sp_svc, r4 98 msr lr_svc, r5 99 msr spsr_abt, r6 100 msr sp_abt, r7 101 msr lr_abt, r8 102 msr spsr_und, r9 103 msr sp_und, r10 104 msr lr_und, r11 105 /* 106 * Use the `_fsxc` suffix explicitly to instruct the assembler 107 * to update all the 32 bits of SPSR. Else, by default, the 108 * assembler assumes `_fc` suffix which only modifies 109 * f->[31:24] and c->[7:0] bits of SPSR. 110 */ 111 msr spsr_fsxc, r12 112 113 /* Restore the LR */ 114 ldr lr, [r0, #SMC_CTX_LR_MON] 115 116 /* Restore the rest of the general purpose registers */ 117 ldm r0, {r0-r12} 118 eret 119 .endm 120 121#endif /* __SMCC_MACROS_S__ */ 122