1f5478dedSAntonio Nino Diaz/* 2c3e8b0beSAlexei Fedorov * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. 3f5478dedSAntonio Nino Diaz * 4f5478dedSAntonio Nino Diaz * SPDX-License-Identifier: BSD-3-Clause 5f5478dedSAntonio Nino Diaz */ 6f5478dedSAntonio Nino Diaz#ifndef SMCCC_MACROS_S 7f5478dedSAntonio Nino Diaz#define SMCCC_MACROS_S 8f5478dedSAntonio Nino Diaz 9f5478dedSAntonio Nino Diaz#include <arch.h> 10f5478dedSAntonio Nino Diaz 11f5478dedSAntonio Nino Diaz/* 12f5478dedSAntonio Nino Diaz * Macro to save the General purpose registers (r0 - r12), the banked 13f5478dedSAntonio Nino Diaz * spsr, lr, sp registers and the `scr` register to the SMC context on entry 14f5478dedSAntonio Nino Diaz * due a SMC call. The `lr` of the current mode (monitor) is expected to be 15f5478dedSAntonio Nino Diaz * already saved. The `sp` must point to the `smc_ctx_t` to save to. 16f5478dedSAntonio Nino Diaz * Additionally, also save the 'pmcr' register as this is updated whilst 17f5478dedSAntonio Nino Diaz * executing in the secure world. 18f5478dedSAntonio Nino Diaz */ 19f5478dedSAntonio Nino Diaz .macro smccc_save_gp_mode_regs 20f5478dedSAntonio Nino Diaz /* Save r0 - r12 in the SMC context */ 21f5478dedSAntonio Nino Diaz stm sp, {r0-r12} 22f5478dedSAntonio Nino Diaz mov r0, sp 23f5478dedSAntonio Nino Diaz add r0, r0, #SMC_CTX_SP_USR 24f5478dedSAntonio Nino Diaz 25f5478dedSAntonio Nino Diaz#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION) 26f5478dedSAntonio Nino Diaz /* Must be in secure state to restore Monitor mode */ 27f5478dedSAntonio Nino Diaz ldcopr r4, SCR 28f5478dedSAntonio Nino Diaz bic r2, r4, #SCR_NS_BIT 29f5478dedSAntonio Nino Diaz stcopr r2, SCR 30f5478dedSAntonio Nino Diaz isb 31f5478dedSAntonio Nino Diaz 32f5478dedSAntonio Nino Diaz cps #MODE32_sys 33f5478dedSAntonio Nino Diaz stm r0!, {sp, lr} 34f5478dedSAntonio Nino Diaz 35f5478dedSAntonio Nino Diaz cps #MODE32_irq 36f5478dedSAntonio Nino Diaz mrs r2, spsr 37f5478dedSAntonio Nino Diaz stm r0!, {r2, sp, lr} 38f5478dedSAntonio Nino Diaz 39f5478dedSAntonio Nino Diaz cps #MODE32_fiq 40f5478dedSAntonio Nino Diaz mrs r2, spsr 41f5478dedSAntonio Nino Diaz stm r0!, {r2, sp, lr} 42f5478dedSAntonio Nino Diaz 43f5478dedSAntonio Nino Diaz cps #MODE32_svc 44f5478dedSAntonio Nino Diaz mrs r2, spsr 45f5478dedSAntonio Nino Diaz stm r0!, {r2, sp, lr} 46f5478dedSAntonio Nino Diaz 47f5478dedSAntonio Nino Diaz cps #MODE32_abt 48f5478dedSAntonio Nino Diaz mrs r2, spsr 49f5478dedSAntonio Nino Diaz stm r0!, {r2, sp, lr} 50f5478dedSAntonio Nino Diaz 51f5478dedSAntonio Nino Diaz cps #MODE32_und 52f5478dedSAntonio Nino Diaz mrs r2, spsr 53f5478dedSAntonio Nino Diaz stm r0!, {r2, sp, lr} 54f5478dedSAntonio Nino Diaz 55f5478dedSAntonio Nino Diaz /* lr_mon is already saved by caller */ 56f5478dedSAntonio Nino Diaz cps #MODE32_mon 57f5478dedSAntonio Nino Diaz mrs r2, spsr 58f5478dedSAntonio Nino Diaz stm r0!, {r2} 59f5478dedSAntonio Nino Diaz 60f5478dedSAntonio Nino Diaz stcopr r4, SCR 61f5478dedSAntonio Nino Diaz#else 62f5478dedSAntonio Nino Diaz /* Save the banked registers including the current SPSR and LR */ 63f5478dedSAntonio Nino Diaz mrs r4, sp_usr 64f5478dedSAntonio Nino Diaz mrs r5, lr_usr 65f5478dedSAntonio Nino Diaz mrs r6, spsr_irq 66f5478dedSAntonio Nino Diaz mrs r7, sp_irq 67f5478dedSAntonio Nino Diaz mrs r8, lr_irq 68f5478dedSAntonio Nino Diaz mrs r9, spsr_fiq 69f5478dedSAntonio Nino Diaz mrs r10, sp_fiq 70f5478dedSAntonio Nino Diaz mrs r11, lr_fiq 71f5478dedSAntonio Nino Diaz mrs r12, spsr_svc 72f5478dedSAntonio Nino Diaz stm r0!, {r4-r12} 73f5478dedSAntonio Nino Diaz 74f5478dedSAntonio Nino Diaz mrs r4, sp_svc 75f5478dedSAntonio Nino Diaz mrs r5, lr_svc 76f5478dedSAntonio Nino Diaz mrs r6, spsr_abt 77f5478dedSAntonio Nino Diaz mrs r7, sp_abt 78f5478dedSAntonio Nino Diaz mrs r8, lr_abt 79f5478dedSAntonio Nino Diaz mrs r9, spsr_und 80f5478dedSAntonio Nino Diaz mrs r10, sp_und 81f5478dedSAntonio Nino Diaz mrs r11, lr_und 82f5478dedSAntonio Nino Diaz mrs r12, spsr 83f5478dedSAntonio Nino Diaz stm r0!, {r4-r12} 84f5478dedSAntonio Nino Diaz /* lr_mon is already saved by caller */ 85f5478dedSAntonio Nino Diaz 86f5478dedSAntonio Nino Diaz ldcopr r4, SCR 87c3e8b0beSAlexei Fedorov 88c3e8b0beSAlexei Fedorov#if ARM_ARCH_MAJOR > 7 89c3e8b0beSAlexei Fedorov /* 90c3e8b0beSAlexei Fedorov * Check if earlier initialization of SDCR.SCCD to 1 91c3e8b0beSAlexei Fedorov * failed, meaning that ARMv8-PMU is not implemented, 92c3e8b0beSAlexei Fedorov * cycle counting is not disabled and PMCR should be 93c3e8b0beSAlexei Fedorov * saved in Non-secure context. 94c3e8b0beSAlexei Fedorov */ 95c3e8b0beSAlexei Fedorov ldcopr r5, SDCR 96c3e8b0beSAlexei Fedorov tst r5, #SDCR_SCCD_BIT 97c3e8b0beSAlexei Fedorov bne 1f 98f5478dedSAntonio Nino Diaz#endif 99c3e8b0beSAlexei Fedorov /* Secure Cycle Counter is not disabled */ 100c3e8b0beSAlexei Fedorov#endif 101c3e8b0beSAlexei Fedorov ldcopr r5, PMCR 102c3e8b0beSAlexei Fedorov 103c3e8b0beSAlexei Fedorov /* Check caller's security state */ 104c3e8b0beSAlexei Fedorov tst r4, #SCR_NS_BIT 105c3e8b0beSAlexei Fedorov beq 2f 106c3e8b0beSAlexei Fedorov 107c3e8b0beSAlexei Fedorov /* Save PMCR if called from Non-secure state */ 108c3e8b0beSAlexei Fedorov str r5, [sp, #SMC_CTX_PMCR] 109c3e8b0beSAlexei Fedorov 110c3e8b0beSAlexei Fedorov /* Disable cycle counter when event counting is prohibited */ 111c3e8b0beSAlexei Fedorov2: orr r5, r5, #PMCR_DP_BIT 112c3e8b0beSAlexei Fedorov stcopr r5, PMCR 113c3e8b0beSAlexei Fedorov isb 114c3e8b0beSAlexei Fedorov1: str r4, [sp, #SMC_CTX_SCR] 115f5478dedSAntonio Nino Diaz .endm 116f5478dedSAntonio Nino Diaz 117f5478dedSAntonio Nino Diaz/* 118f5478dedSAntonio Nino Diaz * Macro to restore the `smc_ctx_t`, which includes the General purpose 119f5478dedSAntonio Nino Diaz * registers and banked mode registers, and exit from the monitor mode. 120f5478dedSAntonio Nino Diaz * r0 must point to the `smc_ctx_t` to restore from. 121f5478dedSAntonio Nino Diaz */ 122f5478dedSAntonio Nino Diaz .macro monitor_exit 123f5478dedSAntonio Nino Diaz /* 124f5478dedSAntonio Nino Diaz * Save the current sp and restore the smc context 125f5478dedSAntonio Nino Diaz * pointer to sp which will be used for handling the 126f5478dedSAntonio Nino Diaz * next SMC. 127f5478dedSAntonio Nino Diaz */ 128f5478dedSAntonio Nino Diaz str sp, [r0, #SMC_CTX_SP_MON] 129f5478dedSAntonio Nino Diaz mov sp, r0 130f5478dedSAntonio Nino Diaz 131f5478dedSAntonio Nino Diaz /* 132f5478dedSAntonio Nino Diaz * Restore SCR first so that we access the right banked register 133f5478dedSAntonio Nino Diaz * when the other mode registers are restored. 134f5478dedSAntonio Nino Diaz */ 135f5478dedSAntonio Nino Diaz ldr r1, [r0, #SMC_CTX_SCR] 136f5478dedSAntonio Nino Diaz stcopr r1, SCR 137f5478dedSAntonio Nino Diaz isb 138f5478dedSAntonio Nino Diaz 139f5478dedSAntonio Nino Diaz /* 140c3e8b0beSAlexei Fedorov * Restore PMCR when returning to Non-secure state 141c3e8b0beSAlexei Fedorov */ 142c3e8b0beSAlexei Fedorov tst r1, #SCR_NS_BIT 143c3e8b0beSAlexei Fedorov beq 2f 144c3e8b0beSAlexei Fedorov 145c3e8b0beSAlexei Fedorov /* 146c3e8b0beSAlexei Fedorov * Back to Non-secure state 147c3e8b0beSAlexei Fedorov */ 148c3e8b0beSAlexei Fedorov#if ARM_ARCH_MAJOR > 7 149c3e8b0beSAlexei Fedorov /* 150c3e8b0beSAlexei Fedorov * Check if earlier initialization SDCR.SCCD to 1 151c3e8b0beSAlexei Fedorov * failed, meaning that ARMv8-PMU is not implemented and 152c3e8b0beSAlexei Fedorov * PMCR should be restored from Non-secure context. 153c3e8b0beSAlexei Fedorov */ 154c3e8b0beSAlexei Fedorov ldcopr r1, SDCR 155c3e8b0beSAlexei Fedorov tst r1, #SDCR_SCCD_BIT 156c3e8b0beSAlexei Fedorov bne 2f 157c3e8b0beSAlexei Fedorov#endif 158c3e8b0beSAlexei Fedorov /* 159f5478dedSAntonio Nino Diaz * Restore the PMCR register. 160f5478dedSAntonio Nino Diaz */ 161f5478dedSAntonio Nino Diaz ldr r1, [r0, #SMC_CTX_PMCR] 162f5478dedSAntonio Nino Diaz stcopr r1, PMCR 163c3e8b0beSAlexei Fedorov2: 164f5478dedSAntonio Nino Diaz /* Restore the banked registers including the current SPSR */ 165f5478dedSAntonio Nino Diaz add r1, r0, #SMC_CTX_SP_USR 166f5478dedSAntonio Nino Diaz 167f5478dedSAntonio Nino Diaz#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION) 168f5478dedSAntonio Nino Diaz /* Must be in secure state to restore Monitor mode */ 169f5478dedSAntonio Nino Diaz ldcopr r4, SCR 170f5478dedSAntonio Nino Diaz bic r2, r4, #SCR_NS_BIT 171f5478dedSAntonio Nino Diaz stcopr r2, SCR 172f5478dedSAntonio Nino Diaz isb 173f5478dedSAntonio Nino Diaz 174f5478dedSAntonio Nino Diaz cps #MODE32_sys 175f5478dedSAntonio Nino Diaz ldm r1!, {sp, lr} 176f5478dedSAntonio Nino Diaz 177f5478dedSAntonio Nino Diaz cps #MODE32_irq 178f5478dedSAntonio Nino Diaz ldm r1!, {r2, sp, lr} 179f5478dedSAntonio Nino Diaz msr spsr_fsxc, r2 180f5478dedSAntonio Nino Diaz 181f5478dedSAntonio Nino Diaz cps #MODE32_fiq 182f5478dedSAntonio Nino Diaz ldm r1!, {r2, sp, lr} 183f5478dedSAntonio Nino Diaz msr spsr_fsxc, r2 184f5478dedSAntonio Nino Diaz 185f5478dedSAntonio Nino Diaz cps #MODE32_svc 186f5478dedSAntonio Nino Diaz ldm r1!, {r2, sp, lr} 187f5478dedSAntonio Nino Diaz msr spsr_fsxc, r2 188f5478dedSAntonio Nino Diaz 189f5478dedSAntonio Nino Diaz cps #MODE32_abt 190f5478dedSAntonio Nino Diaz ldm r1!, {r2, sp, lr} 191f5478dedSAntonio Nino Diaz msr spsr_fsxc, r2 192f5478dedSAntonio Nino Diaz 193f5478dedSAntonio Nino Diaz cps #MODE32_und 194f5478dedSAntonio Nino Diaz ldm r1!, {r2, sp, lr} 195f5478dedSAntonio Nino Diaz msr spsr_fsxc, r2 196f5478dedSAntonio Nino Diaz 197f5478dedSAntonio Nino Diaz cps #MODE32_mon 198f5478dedSAntonio Nino Diaz ldm r1!, {r2} 199f5478dedSAntonio Nino Diaz msr spsr_fsxc, r2 200f5478dedSAntonio Nino Diaz 201f5478dedSAntonio Nino Diaz stcopr r4, SCR 202f5478dedSAntonio Nino Diaz isb 203f5478dedSAntonio Nino Diaz#else 204f5478dedSAntonio Nino Diaz ldm r1!, {r4-r12} 205f5478dedSAntonio Nino Diaz msr sp_usr, r4 206f5478dedSAntonio Nino Diaz msr lr_usr, r5 207f5478dedSAntonio Nino Diaz msr spsr_irq, r6 208f5478dedSAntonio Nino Diaz msr sp_irq, r7 209f5478dedSAntonio Nino Diaz msr lr_irq, r8 210f5478dedSAntonio Nino Diaz msr spsr_fiq, r9 211f5478dedSAntonio Nino Diaz msr sp_fiq, r10 212f5478dedSAntonio Nino Diaz msr lr_fiq, r11 213f5478dedSAntonio Nino Diaz msr spsr_svc, r12 214f5478dedSAntonio Nino Diaz 215f5478dedSAntonio Nino Diaz ldm r1!, {r4-r12} 216f5478dedSAntonio Nino Diaz msr sp_svc, r4 217f5478dedSAntonio Nino Diaz msr lr_svc, r5 218f5478dedSAntonio Nino Diaz msr spsr_abt, r6 219f5478dedSAntonio Nino Diaz msr sp_abt, r7 220f5478dedSAntonio Nino Diaz msr lr_abt, r8 221f5478dedSAntonio Nino Diaz msr spsr_und, r9 222f5478dedSAntonio Nino Diaz msr sp_und, r10 223f5478dedSAntonio Nino Diaz msr lr_und, r11 224f5478dedSAntonio Nino Diaz /* 225f5478dedSAntonio Nino Diaz * Use the `_fsxc` suffix explicitly to instruct the assembler 226f5478dedSAntonio Nino Diaz * to update all the 32 bits of SPSR. Else, by default, the 227f5478dedSAntonio Nino Diaz * assembler assumes `_fc` suffix which only modifies 228f5478dedSAntonio Nino Diaz * f->[31:24] and c->[7:0] bits of SPSR. 229f5478dedSAntonio Nino Diaz */ 230f5478dedSAntonio Nino Diaz msr spsr_fsxc, r12 231f5478dedSAntonio Nino Diaz#endif 232f5478dedSAntonio Nino Diaz 233f5478dedSAntonio Nino Diaz /* Restore the LR */ 234f5478dedSAntonio Nino Diaz ldr lr, [r0, #SMC_CTX_LR_MON] 235f5478dedSAntonio Nino Diaz 236f5478dedSAntonio Nino Diaz /* Restore the rest of the general purpose registers */ 237f5478dedSAntonio Nino Diaz ldm r0, {r0-r12} 238*6bc24382SMadhukar Pappireddy exception_return 239f5478dedSAntonio Nino Diaz .endm 240f5478dedSAntonio Nino Diaz 241f5478dedSAntonio Nino Diaz#endif /* SMCCC_MACROS_S */ 242