Home | History | Annotate | Download | only in aarch32
      1 /*
      2  * Copyright (c) 2016, 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.h>
     10 #include <bl_common.h>
     11 #include <context.h>
     12 #include <smcc_helpers.h>
     13 #include <smcc_macros.S>
     14 #include <xlat_tables.h>
     15 
     16 	.globl	bl1_aarch32_smc_handler
     17 
     18 
     19 func 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
     57 debug_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, r1
     75 
     76 	add	r8, r8, #ENTRY_POINT_INFO_ARGS_OFFSET
     77 	ldm	r8, {r0, r1, r2, r3}
     78 	eret
     79 endfunc bl1_aarch32_smc_handler
     80 
     81 	/* -----------------------------------------------------
     82 	 * Save Secure/Normal world context and jump to
     83 	 * BL1 SMC handler.
     84 	 * -----------------------------------------------------
     85 	 */
     86 func smc_handler
     87 	/* -----------------------------------------------------
     88 	 * Save the GP registers.
     89 	 * -----------------------------------------------------
     90 	 */
     91 	smcc_save_gp_mode_regs
     92 
     93 	/*
     94 	 * `sp` still points to `smc_ctx_t`. Save it to a register
     95 	 * and restore the C runtime stack pointer to `sp`.
     96 	 */
     97 	mov	r6, sp
     98 	ldr	sp, [r6, #SMC_CTX_SP_MON]
     99 
    100 	ldr	r0, [r6, #SMC_CTX_SCR]
    101 	and	r7, r0, #SCR_NS_BIT		/* flags */
    102 
    103 	/* Switch to Secure Mode */
    104 	bic	r0, #SCR_NS_BIT
    105 	stcopr	r0, SCR
    106 	isb
    107 
    108 	/* If caller is from Secure world then turn on the MMU */
    109 	tst	r7, #SCR_NS_BIT
    110 	bne	skip_mmu_on
    111 
    112 	/* Turn on the MMU */
    113 	mov	r0, #DISABLE_DCACHE
    114 	bl	enable_mmu_secure
    115 
    116 	/* Enable the data cache. */
    117 	ldcopr	r9, SCTLR
    118 	orr	r9, r9, #SCTLR_C_BIT
    119 	stcopr	r9, SCTLR
    120 	isb
    121 
    122 skip_mmu_on:
    123 	/* Prepare arguments for BL1 SMC wrapper. */
    124 	ldr	r0, [r6, #SMC_CTX_GPREG_R0]	/* smc_fid */
    125 	mov	r1, #0				/* cookie */
    126 	mov	r2, r6				/* handle */
    127 	mov	r3, r7				/* flags */
    128 	bl	bl1_smc_wrapper
    129 
    130 	/* Get the smc_context for next BL image */
    131 	bl	smc_get_next_ctx
    132 	mov	r4, r0
    133 
    134 	/* Only turn-off MMU if going to secure world */
    135 	ldr	r5, [r4, #SMC_CTX_SCR]
    136 	tst	r5, #SCR_NS_BIT
    137 	bne	skip_mmu_off
    138 
    139 	/* Disable the MMU */
    140 	bl	disable_mmu_icache_secure
    141 	stcopr	r0, TLBIALL
    142 	dsb	sy
    143 	isb
    144 
    145 skip_mmu_off:
    146 	/* -----------------------------------------------------
    147 	 * Do the transition to next BL image.
    148 	 * -----------------------------------------------------
    149 	 */
    150 	mov	r0, r4
    151 	monitor_exit
    152 endfunc smc_handler
    153