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