1/*
2 * Copyright (c) 2013-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
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
29	check_vector_size SynchronousExceptionSP0
30
31vector_entry IrqSP0
32	mov	x0, #IRQ_SP_EL0
33	bl	plat_report_exception
34	no_ret	plat_panic_handler
35	check_vector_size IrqSP0
36
37vector_entry FiqSP0
38	mov	x0, #FIQ_SP_EL0
39	bl	plat_report_exception
40	no_ret	plat_panic_handler
41	check_vector_size FiqSP0
42
43vector_entry SErrorSP0
44	mov	x0, #SERROR_SP_EL0
45	bl	plat_report_exception
46	no_ret	plat_panic_handler
47	check_vector_size 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
57	check_vector_size SynchronousExceptionSPx
58
59vector_entry IrqSPx
60	mov	x0, #IRQ_SP_ELX
61	bl	plat_report_exception
62	no_ret	plat_panic_handler
63	check_vector_size IrqSPx
64
65vector_entry FiqSPx
66	mov	x0, #FIQ_SP_ELX
67	bl	plat_report_exception
68	no_ret	plat_panic_handler
69	check_vector_size FiqSPx
70
71vector_entry SErrorSPx
72	mov	x0, #SERROR_SP_ELX
73	bl	plat_report_exception
74	no_ret	plat_panic_handler
75	check_vector_size 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
94	check_vector_size SynchronousExceptionA64
95
96vector_entry IrqA64
97	mov	x0, #IRQ_AARCH64
98	bl	plat_report_exception
99	no_ret	plat_panic_handler
100	check_vector_size IrqA64
101
102vector_entry FiqA64
103	mov	x0, #FIQ_AARCH64
104	bl	plat_report_exception
105	no_ret	plat_panic_handler
106	check_vector_size FiqA64
107
108vector_entry SErrorA64
109	mov	x0, #SERROR_AARCH64
110	bl	plat_report_exception
111	no_ret	plat_panic_handler
112	check_vector_size 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
122	check_vector_size SynchronousExceptionA32
123
124vector_entry IrqA32
125	mov	x0, #IRQ_AARCH32
126	bl	plat_report_exception
127	no_ret	plat_panic_handler
128	check_vector_size IrqA32
129
130vector_entry FiqA32
131	mov	x0, #FIQ_AARCH32
132	bl	plat_report_exception
133	no_ret	plat_panic_handler
134	check_vector_size FiqA32
135
136vector_entry SErrorA32
137	mov	x0, #SERROR_AARCH32
138	bl	plat_report_exception
139	no_ret	plat_panic_handler
140	check_vector_size 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, #0
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
191#if SPIN_ON_BL1_EXIT
192	bl	print_debug_loop_message
193debug_loop:
194	b	debug_loop
195#endif
196
197	mov	x0, x20
198	bl	bl1_plat_prepare_exit
199
200	ldp	x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)]
201	ldp	x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)]
202	ldp	x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)]
203	ldp	x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)]
204	eret
205endfunc smc_handler64
206
207unexpected_sync_exception:
208	mov	x0, #SYNC_EXCEPTION_AARCH64
209	bl	plat_report_exception
210	no_ret	plat_panic_handler
211
212	/* -----------------------------------------------------
213	 * Save Secure/Normal world context and jump to
214	 * BL1 SMC handler.
215	 * -----------------------------------------------------
216	 */
217smc_handler:
218	/* -----------------------------------------------------
219	 * Save the GP registers x0-x29.
220	 * TODO: Revisit to store only SMCC specified registers.
221	 * -----------------------------------------------------
222	 */
223	bl	save_gp_registers
224
225	/* -----------------------------------------------------
226	 * Populate the parameters for the SMC handler. We
227	 * already have x0-x4 in place. x5 will point to a
228	 * cookie (not used now). x6 will point to the context
229	 * structure (SP_EL3) and x7 will contain flags we need
230	 * to pass to the handler.
231	 * -----------------------------------------------------
232	 */
233	mov	x5, xzr
234	mov	x6, sp
235
236	/* -----------------------------------------------------
237	 * Restore the saved C runtime stack value which will
238	 * become the new SP_EL0 i.e. EL3 runtime stack. It was
239	 * saved in the 'cpu_context' structure prior to the last
240	 * ERET from EL3.
241	 * -----------------------------------------------------
242	 */
243	ldr	x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
244
245	/* ---------------------------------------------
246	 * Switch back to SP_EL0 for the C runtime stack.
247	 * ---------------------------------------------
248	 */
249	msr	spsel, #0
250	mov	sp, x12
251
252	/* -----------------------------------------------------
253	 * Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there
254	 * is a world switch during SMC handling.
255	 * -----------------------------------------------------
256	 */
257	mrs	x16, spsr_el3
258	mrs	x17, elr_el3
259	mrs	x18, scr_el3
260	stp	x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
261	str	x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
262
263	/* Copy SCR_EL3.NS bit to the flag to indicate caller's security */
264	bfi	x7, x18, #0, #1
265
266	/* -----------------------------------------------------
267	 * Go to BL1 SMC handler.
268	 * -----------------------------------------------------
269	 */
270	bl	bl1_smc_handler
271
272	/* -----------------------------------------------------
273	 * Do the transition to next BL image.
274	 * -----------------------------------------------------
275	 */
276	b	el3_exit
277