1/* 2 * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6#ifndef SMCCC_MACROS_S 7#define SMCCC_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 smccc_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#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION) 26 /* Must be in secure state to restore Monitor mode */ 27 ldcopr r4, SCR 28 bic r2, r4, #SCR_NS_BIT 29 stcopr r2, SCR 30 isb 31 32 cps #MODE32_sys 33 stm r0!, {sp, lr} 34 35 cps #MODE32_irq 36 mrs r2, spsr 37 stm r0!, {r2, sp, lr} 38 39 cps #MODE32_fiq 40 mrs r2, spsr 41 stm r0!, {r2, sp, lr} 42 43 cps #MODE32_svc 44 mrs r2, spsr 45 stm r0!, {r2, sp, lr} 46 47 cps #MODE32_abt 48 mrs r2, spsr 49 stm r0!, {r2, sp, lr} 50 51 cps #MODE32_und 52 mrs r2, spsr 53 stm r0!, {r2, sp, lr} 54 55 /* lr_mon is already saved by caller */ 56 cps #MODE32_mon 57 mrs r2, spsr 58 stm r0!, {r2} 59 60 stcopr r4, SCR 61 isb 62#else 63 /* Save the banked registers including the current SPSR and LR */ 64 mrs r4, sp_usr 65 mrs r5, lr_usr 66 mrs r6, spsr_irq 67 mrs r7, sp_irq 68 mrs r8, lr_irq 69 mrs r9, spsr_fiq 70 mrs r10, sp_fiq 71 mrs r11, lr_fiq 72 mrs r12, spsr_svc 73 stm r0!, {r4-r12} 74 75 mrs r4, sp_svc 76 mrs r5, lr_svc 77 mrs r6, spsr_abt 78 mrs r7, sp_abt 79 mrs r8, lr_abt 80 mrs r9, spsr_und 81 mrs r10, sp_und 82 mrs r11, lr_und 83 mrs r12, spsr 84 stm r0!, {r4-r12} 85 /* lr_mon is already saved by caller */ 86 87 ldcopr r4, SCR 88#endif 89 str r4, [sp, #SMC_CTX_SCR] 90 ldcopr r4, PMCR 91 str r4, [sp, #SMC_CTX_PMCR] 92 .endm 93 94/* 95 * Macro to restore the `smc_ctx_t`, which includes the General purpose 96 * registers and banked mode registers, and exit from the monitor mode. 97 * r0 must point to the `smc_ctx_t` to restore from. 98 */ 99 .macro monitor_exit 100 /* 101 * Save the current sp and restore the smc context 102 * pointer to sp which will be used for handling the 103 * next SMC. 104 */ 105 str sp, [r0, #SMC_CTX_SP_MON] 106 mov sp, r0 107 108 /* 109 * Restore SCR first so that we access the right banked register 110 * when the other mode registers are restored. 111 */ 112 ldr r1, [r0, #SMC_CTX_SCR] 113 stcopr r1, SCR 114 isb 115 116 /* 117 * Restore the PMCR register. 118 */ 119 ldr r1, [r0, #SMC_CTX_PMCR] 120 stcopr r1, PMCR 121 122 /* Restore the banked registers including the current SPSR */ 123 add r1, r0, #SMC_CTX_SP_USR 124 125#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION) 126 /* Must be in secure state to restore Monitor mode */ 127 ldcopr r4, SCR 128 bic r2, r4, #SCR_NS_BIT 129 stcopr r2, SCR 130 isb 131 132 cps #MODE32_sys 133 ldm r1!, {sp, lr} 134 135 cps #MODE32_irq 136 ldm r1!, {r2, sp, lr} 137 msr spsr_fsxc, r2 138 139 cps #MODE32_fiq 140 ldm r1!, {r2, sp, lr} 141 msr spsr_fsxc, r2 142 143 cps #MODE32_svc 144 ldm r1!, {r2, sp, lr} 145 msr spsr_fsxc, r2 146 147 cps #MODE32_abt 148 ldm r1!, {r2, sp, lr} 149 msr spsr_fsxc, r2 150 151 cps #MODE32_und 152 ldm r1!, {r2, sp, lr} 153 msr spsr_fsxc, r2 154 155 cps #MODE32_mon 156 ldm r1!, {r2} 157 msr spsr_fsxc, r2 158 159 stcopr r4, SCR 160 isb 161#else 162 ldm r1!, {r4-r12} 163 msr sp_usr, r4 164 msr lr_usr, r5 165 msr spsr_irq, r6 166 msr sp_irq, r7 167 msr lr_irq, r8 168 msr spsr_fiq, r9 169 msr sp_fiq, r10 170 msr lr_fiq, r11 171 msr spsr_svc, r12 172 173 ldm r1!, {r4-r12} 174 msr sp_svc, r4 175 msr lr_svc, r5 176 msr spsr_abt, r6 177 msr sp_abt, r7 178 msr lr_abt, r8 179 msr spsr_und, r9 180 msr sp_und, r10 181 msr lr_und, r11 182 /* 183 * Use the `_fsxc` suffix explicitly to instruct the assembler 184 * to update all the 32 bits of SPSR. Else, by default, the 185 * assembler assumes `_fc` suffix which only modifies 186 * f->[31:24] and c->[7:0] bits of SPSR. 187 */ 188 msr spsr_fsxc, r12 189#endif 190 191 /* Restore the LR */ 192 ldr lr, [r0, #SMC_CTX_LR_MON] 193 194 /* Restore the rest of the general purpose registers */ 195 ldm r0, {r0-r12} 196 eret 197 .endm 198 199#endif /* SMCCC_MACROS_S */ 200