1/* 2 * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <arch.h> 8#include <asm_macros.S> 9#include <bl1/bl1.h> 10#include <common/bl_common.h> 11#include <context.h> 12#include <lib/xlat_tables/xlat_tables.h> 13#include <smccc_helpers.h> 14#include <smccc_macros.S> 15 16 .globl bl1_aarch32_smc_handler 17 18 19func bl1_aarch32_smc_handler 20 /* On SMC entry, `sp` points to `smc_ctx_t`. Save `lr`. */ 21 str lr, [sp, #SMC_CTX_LR_MON] 22 23 /* ------------------------------------------------ 24 * SMC in BL1 is handled assuming that the MMU is 25 * turned off by BL2. 26 * ------------------------------------------------ 27 */ 28 29 /* ---------------------------------------------- 30 * Detect if this is a RUN_IMAGE or other SMC. 31 * ---------------------------------------------- 32 */ 33 mov lr, #BL1_SMC_RUN_IMAGE 34 cmp lr, r0 35 bne smc_handler 36 37 /* ------------------------------------------------ 38 * Make sure only Secure world reaches here. 39 * ------------------------------------------------ 40 */ 41 ldcopr r8, SCR 42 tst r8, #SCR_NS_BIT 43 blne report_exception 44 45 /* --------------------------------------------------------------------- 46 * Pass control to next secure image. 47 * Here it expects r1 to contain the address of a entry_point_info_t 48 * structure describing the BL entrypoint. 49 * --------------------------------------------------------------------- 50 */ 51 mov r8, r1 52 mov r0, r1 53 bl bl1_print_next_bl_ep_info 54 55#if SPIN_ON_BL1_EXIT 56 bl print_debug_loop_message 57debug_loop: 58 b debug_loop 59#endif 60 61 mov r0, r8 62 bl bl1_plat_prepare_exit 63 64 stcopr r0, TLBIALL 65 dsb sy 66 isb 67 68 /* 69 * Extract PC and SPSR based on struct `entry_point_info_t` 70 * and load it in LR and SPSR registers respectively. 71 */ 72 ldr lr, [r8, #ENTRY_POINT_INFO_PC_OFFSET] 73 ldr r1, [r8, #(ENTRY_POINT_INFO_PC_OFFSET + 4)] 74 msr spsr_xc, r1 75 76 /* Some BL32 stages expect lr_svc to provide the BL33 entry address */ 77 cps #MODE32_svc 78 ldr lr, [r8, #ENTRY_POINT_INFO_LR_SVC_OFFSET] 79 cps #MODE32_mon 80 81 add r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET 82 ldm r8, {r0, r1, r2, r3} 83 exception_return 84endfunc bl1_aarch32_smc_handler 85 86 /* ----------------------------------------------------- 87 * Save Secure/Normal world context and jump to 88 * BL1 SMC handler. 89 * ----------------------------------------------------- 90 */ 91func smc_handler 92 /* ----------------------------------------------------- 93 * Save the GP registers. 94 * ----------------------------------------------------- 95 */ 96 smccc_save_gp_mode_regs 97 98 /* 99 * `sp` still points to `smc_ctx_t`. Save it to a register 100 * and restore the C runtime stack pointer to `sp`. 101 */ 102 mov r6, sp 103 ldr sp, [r6, #SMC_CTX_SP_MON] 104 105 ldr r0, [r6, #SMC_CTX_SCR] 106 and r7, r0, #SCR_NS_BIT /* flags */ 107 108 /* Switch to Secure Mode */ 109 bic r0, #SCR_NS_BIT 110 stcopr r0, SCR 111 isb 112 113 /* If caller is from Secure world then turn on the MMU */ 114 tst r7, #SCR_NS_BIT 115 bne skip_mmu_on 116 117 /* Turn on the MMU */ 118 mov r0, #DISABLE_DCACHE 119 bl enable_mmu_svc_mon 120 121 /* 122 * Invalidate `smc_ctx_t` in data cache to prevent dirty data being 123 * used. 124 */ 125 mov r0, r6 126 mov r1, #SMC_CTX_SIZE 127 bl inv_dcache_range 128 129 /* Enable the data cache. */ 130 ldcopr r9, SCTLR 131 orr r9, r9, #SCTLR_C_BIT 132 stcopr r9, SCTLR 133 isb 134 135skip_mmu_on: 136 /* Prepare arguments for BL1 SMC wrapper. */ 137 ldr r0, [r6, #SMC_CTX_GPREG_R0] /* smc_fid */ 138 mov r1, #0 /* cookie */ 139 mov r2, r6 /* handle */ 140 mov r3, r7 /* flags */ 141 bl bl1_smc_wrapper 142 143 /* Get the smc_context for next BL image */ 144 bl smc_get_next_ctx 145 mov r4, r0 146 147 /* Only turn-off MMU if going to secure world */ 148 ldr r5, [r4, #SMC_CTX_SCR] 149 tst r5, #SCR_NS_BIT 150 bne skip_mmu_off 151 152 /* Disable the MMU */ 153 bl disable_mmu_icache_secure 154 stcopr r0, TLBIALL 155 dsb sy 156 isb 157 158skip_mmu_off: 159 /* ----------------------------------------------------- 160 * Do the transition to next BL image. 161 * ----------------------------------------------------- 162 */ 163 mov r0, r4 164 monitor_exit 165endfunc smc_handler 166