xref: /arm-trusted-firmware/bl1/aarch32/bl1_exceptions.S (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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