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