1/*
2 * Copyright (c) 2013-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
13/* -----------------------------------------------------------------------------
14 * Very simple stackless exception handlers used by BL1.
15 * -----------------------------------------------------------------------------
16 */
17	.globl	bl1_exceptions
18
19vector_base bl1_exceptions
20
21	/* -----------------------------------------------------
22	 * Current EL with SP0 : 0x0 - 0x200
23	 * -----------------------------------------------------
24	 */
25vector_entry SynchronousExceptionSP0
26	mov	x0, #SYNC_EXCEPTION_SP_EL0
27	bl	plat_report_exception
28	no_ret	plat_panic_handler
29end_vector_entry SynchronousExceptionSP0
30
31vector_entry IrqSP0
32	mov	x0, #IRQ_SP_EL0
33	bl	plat_report_exception
34	no_ret	plat_panic_handler
35end_vector_entry IrqSP0
36
37vector_entry FiqSP0
38	mov	x0, #FIQ_SP_EL0
39	bl	plat_report_exception
40	no_ret	plat_panic_handler
41end_vector_entry FiqSP0
42
43vector_entry SErrorSP0
44	mov	x0, #SERROR_SP_EL0
45	bl	plat_report_exception
46	no_ret	plat_panic_handler
47end_vector_entry SErrorSP0
48
49	/* -----------------------------------------------------
50	 * Current EL with SPx: 0x200 - 0x400
51	 * -----------------------------------------------------
52	 */
53vector_entry SynchronousExceptionSPx
54	mov	x0, #SYNC_EXCEPTION_SP_ELX
55	bl	plat_report_exception
56	no_ret	plat_panic_handler
57end_vector_entry SynchronousExceptionSPx
58
59vector_entry IrqSPx
60	mov	x0, #IRQ_SP_ELX
61	bl	plat_report_exception
62	no_ret	plat_panic_handler
63end_vector_entry IrqSPx
64
65vector_entry FiqSPx
66	mov	x0, #FIQ_SP_ELX
67	bl	plat_report_exception
68	no_ret	plat_panic_handler
69end_vector_entry FiqSPx
70
71vector_entry SErrorSPx
72	mov	x0, #SERROR_SP_ELX
73	bl	plat_report_exception
74	no_ret	plat_panic_handler
75end_vector_entry SErrorSPx
76
77	/* -----------------------------------------------------
78	 * Lower EL using AArch64 : 0x400 - 0x600
79	 * -----------------------------------------------------
80	 */
81vector_entry SynchronousExceptionA64
82	/* Enable the SError interrupt */
83	msr	daifclr, #DAIF_ABT_BIT
84
85	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
86
87	/* Expect only SMC exceptions */
88	mrs	x30, esr_el3
89	ubfx	x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
90	cmp	x30, #EC_AARCH64_SMC
91	b.ne	unexpected_sync_exception
92
93	b	smc_handler64
94end_vector_entry SynchronousExceptionA64
95
96vector_entry IrqA64
97	mov	x0, #IRQ_AARCH64
98	bl	plat_report_exception
99	no_ret	plat_panic_handler
100end_vector_entry IrqA64
101
102vector_entry FiqA64
103	mov	x0, #FIQ_AARCH64
104	bl	plat_report_exception
105	no_ret	plat_panic_handler
106end_vector_entry FiqA64
107
108vector_entry SErrorA64
109	mov	x0, #SERROR_AARCH64
110	bl	plat_report_exception
111	no_ret	plat_panic_handler
112end_vector_entry SErrorA64
113
114	/* -----------------------------------------------------
115	 * Lower EL using AArch32 : 0x600 - 0x800
116	 * -----------------------------------------------------
117	 */
118vector_entry SynchronousExceptionA32
119	mov	x0, #SYNC_EXCEPTION_AARCH32
120	bl	plat_report_exception
121	no_ret	plat_panic_handler
122end_vector_entry SynchronousExceptionA32
123
124vector_entry IrqA32
125	mov	x0, #IRQ_AARCH32
126	bl	plat_report_exception
127	no_ret	plat_panic_handler
128end_vector_entry IrqA32
129
130vector_entry FiqA32
131	mov	x0, #FIQ_AARCH32
132	bl	plat_report_exception
133	no_ret	plat_panic_handler
134end_vector_entry FiqA32
135
136vector_entry SErrorA32
137	mov	x0, #SERROR_AARCH32
138	bl	plat_report_exception
139	no_ret	plat_panic_handler
140end_vector_entry SErrorA32
141
142
143func smc_handler64
144
145	/* ----------------------------------------------
146	 * Detect if this is a RUN_IMAGE or other SMC.
147	 * ----------------------------------------------
148	 */
149	mov	x30, #BL1_SMC_RUN_IMAGE
150	cmp	x30, x0
151	b.ne	smc_handler
152
153	/* ------------------------------------------------
154	 * Make sure only Secure world reaches here.
155	 * ------------------------------------------------
156	 */
157	mrs	x30, scr_el3
158	tst	x30, #SCR_NS_BIT
159	b.ne	unexpected_sync_exception
160
161	/* ----------------------------------------------
162	 * Handling RUN_IMAGE SMC. First switch back to
163	 * SP_EL0 for the C runtime stack.
164	 * ----------------------------------------------
165	 */
166	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
167	msr	spsel, #MODE_SP_EL0
168	mov	sp, x30
169
170	/* ---------------------------------------------------------------------
171	 * Pass EL3 control to next BL image.
172	 * Here it expects X1 with the address of a entry_point_info_t
173	 * structure describing the next BL image entrypoint.
174	 * ---------------------------------------------------------------------
175	 */
176	mov	x20, x1
177
178	mov	x0, x20
179	bl	bl1_print_next_bl_ep_info
180
181	ldp	x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
182	msr	elr_el3, x0
183	msr	spsr_el3, x1
184	ubfx	x0, x1, #MODE_EL_SHIFT, #2
185	cmp	x0, #MODE_EL3
186	b.ne	unexpected_sync_exception
187
188	bl	disable_mmu_icache_el3
189	tlbi	alle3
190	dsb	ish /* ERET implies ISB, so it is not needed here */
191
192#if SPIN_ON_BL1_EXIT
193	bl	print_debug_loop_message
194debug_loop:
195	b	debug_loop
196#endif
197
198	mov	x0, x20
199	bl	bl1_plat_prepare_exit
200
201	ldp	x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)]
202	ldp	x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)]
203	ldp	x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)]
204	ldp	x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)]
205	exception_return
206endfunc smc_handler64
207
208unexpected_sync_exception:
209	mov	x0, #SYNC_EXCEPTION_AARCH64
210	bl	plat_report_exception
211	no_ret	plat_panic_handler
212
213	/* -----------------------------------------------------
214	 * Save Secure/Normal world context and jump to
215	 * BL1 SMC handler.
216	 * -----------------------------------------------------
217	 */
218smc_handler:
219	/* -----------------------------------------------------
220	 * Save x0-x29 and ARMv8.3-PAuth (if enabled) registers.
221	 * Save PMCR_EL0 and disable Cycle Counter.
222	 * TODO: Revisit to store only SMCCC specified registers.
223	 * -----------------------------------------------------
224	 */
225	bl	prepare_el3_entry
226
227#if ENABLE_PAUTH
228	/* -----------------------------------------------------
229	 * Load and program stored APIAKey firmware key.
230	 * Re-enable pointer authentication in EL3, as it was
231	 * disabled before jumping to the next boot image.
232	 * -----------------------------------------------------
233	 */
234	bl	pauth_load_bl1_apiakey_enable
235#endif
236	/* -----------------------------------------------------
237	 * Populate the parameters for the SMC handler. We
238	 * already have x0-x4 in place. x5 will point to a
239	 * cookie (not used now). x6 will point to the context
240	 * structure (SP_EL3) and x7 will contain flags we need
241	 * to pass to the handler.
242	 * -----------------------------------------------------
243	 */
244	mov	x5, xzr
245	mov	x6, sp
246
247	/* -----------------------------------------------------
248	 * Restore the saved C runtime stack value which will
249	 * become the new SP_EL0 i.e. EL3 runtime stack. It was
250	 * saved in the 'cpu_context' structure prior to the last
251	 * ERET from EL3.
252	 * -----------------------------------------------------
253	 */
254	ldr	x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
255
256	/* ---------------------------------------------
257	 * Switch back to SP_EL0 for the C runtime stack.
258	 * ---------------------------------------------
259	 */
260	msr	spsel, #MODE_SP_EL0
261	mov	sp, x12
262
263	/* -----------------------------------------------------
264	 * Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there
265	 * is a world switch during SMC handling.
266	 * -----------------------------------------------------
267	 */
268	mrs	x16, spsr_el3
269	mrs	x17, elr_el3
270	mrs	x18, scr_el3
271	stp	x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
272	str	x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
273
274	/* Copy SCR_EL3.NS bit to the flag to indicate caller's security */
275	bfi	x7, x18, #0, #1
276
277	/* -----------------------------------------------------
278	 * Go to BL1 SMC handler.
279	 * -----------------------------------------------------
280	 */
281	bl	bl1_smc_handler
282
283	/* -----------------------------------------------------
284	 * Do the transition to next BL image.
285	 * -----------------------------------------------------
286	 */
287	b	el3_exit
288