bl1_exceptions.S 8.51 KB
Newer Older
1
/*
2
 * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of ARM nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <arch.h>
32
#include <asm_macros.S>
33
#include <bl_common.h>
34
#include <bl1.h>
35
#include <context.h>
36

37
	.globl	bl1_exceptions
38

Achin Gupta's avatar
Achin Gupta committed
39
	.section	.vectors, "ax"; .align 11
40
41

	/* -----------------------------------------------------
42
	 * Very simple stackless exception handlers used by BL1.
43
44
45
	 * -----------------------------------------------------
	 */
	.align	7
46
bl1_exceptions:
47
	/* -----------------------------------------------------
48
	 * Current EL with SP0 : 0x0 - 0x200
49
50
51
52
53
54
	 * -----------------------------------------------------
	 */
SynchronousExceptionSP0:
	mov	x0, #SYNC_EXCEPTION_SP_EL0
	bl	plat_report_exception
	b	SynchronousExceptionSP0
55
	check_vector_size SynchronousExceptionSP0
56
57
58
59
60
61

	.align	7
IrqSP0:
	mov	x0, #IRQ_SP_EL0
	bl	plat_report_exception
	b	IrqSP0
62
	check_vector_size IrqSP0
63
64
65
66
67
68

	.align	7
FiqSP0:
	mov	x0, #FIQ_SP_EL0
	bl	plat_report_exception
	b	FiqSP0
69
	check_vector_size FiqSP0
70
71
72
73
74
75

	.align	7
SErrorSP0:
	mov	x0, #SERROR_SP_EL0
	bl	plat_report_exception
	b	SErrorSP0
76
	check_vector_size SErrorSP0
77
78

	/* -----------------------------------------------------
79
	 * Current EL with SPx: 0x200 - 0x400
80
81
82
83
84
85
86
	 * -----------------------------------------------------
	 */
	.align	7
SynchronousExceptionSPx:
	mov	x0, #SYNC_EXCEPTION_SP_ELX
	bl	plat_report_exception
	b	SynchronousExceptionSPx
87
	check_vector_size SynchronousExceptionSPx
88
89
90
91
92
93

	.align	7
IrqSPx:
	mov	x0, #IRQ_SP_ELX
	bl	plat_report_exception
	b	IrqSPx
94
	check_vector_size IrqSPx
95
96
97
98
99
100

	.align	7
FiqSPx:
	mov	x0, #FIQ_SP_ELX
	bl	plat_report_exception
	b	FiqSPx
101
	check_vector_size FiqSPx
102
103
104
105
106
107

	.align	7
SErrorSPx:
	mov	x0, #SERROR_SP_ELX
	bl	plat_report_exception
	b	SErrorSPx
108
	check_vector_size SErrorSPx
109
110

	/* -----------------------------------------------------
111
	 * Lower EL using AArch64 : 0x400 - 0x600
112
113
114
115
	 * -----------------------------------------------------
	 */
	.align	7
SynchronousExceptionA64:
116
117
118
	/* Enable the SError interrupt */
	msr	daifclr, #DAIF_ABT_BIT

119
120
	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]

121
	/* Expect only SMC exceptions */
122
123
124
	mrs	x30, esr_el3
	ubfx	x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
	cmp	x30, #EC_AARCH64_SMC
125
	b.ne	unexpected_sync_exception
126

127
	b	smc_handler64
128
	check_vector_size SynchronousExceptionA64
129
130
131
132
133
134

	.align	7
IrqA64:
	mov	x0, #IRQ_AARCH64
	bl	plat_report_exception
	b	IrqA64
135
	check_vector_size IrqA64
136
137
138
139
140
141

	.align	7
FiqA64:
	mov	x0, #FIQ_AARCH64
	bl	plat_report_exception
	b	FiqA64
142
	check_vector_size FiqA64
143
144
145
146
147
148

	.align	7
SErrorA64:
	mov	x0, #SERROR_AARCH64
	bl	plat_report_exception
	b   	SErrorA64
149
	check_vector_size SErrorA64
150
151

	/* -----------------------------------------------------
152
	 * Lower EL using AArch32 : 0x600 - 0x800
153
154
155
156
157
158
159
	 * -----------------------------------------------------
	 */
	.align	7
SynchronousExceptionA32:
	mov	x0, #SYNC_EXCEPTION_AARCH32
	bl	plat_report_exception
	b	SynchronousExceptionA32
160
	check_vector_size SynchronousExceptionA32
161
162
163
164
165
166

	.align	7
IrqA32:
	mov	x0, #IRQ_AARCH32
	bl	plat_report_exception
	b	IrqA32
167
	check_vector_size IrqA32
168
169
170
171
172
173

	.align	7
FiqA32:
	mov	x0, #FIQ_AARCH32
	bl	plat_report_exception
	b	FiqA32
174
	check_vector_size FiqA32
175
176
177
178
179
180

	.align	7
SErrorA32:
	mov	x0, #SERROR_AARCH32
	bl	plat_report_exception
	b	SErrorA32
181
	check_vector_size SErrorA32
182
183
184


func smc_handler64
185

186
	/* ----------------------------------------------
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
	 * Detect if this is a RUN_IMAGE or other SMC.
	 * ----------------------------------------------
	 */
	mov	x30, #BL1_SMC_RUN_IMAGE
	cmp	x30, x0
	b.ne	smc_handler

	/* ------------------------------------------------
	 * Make sure only Secure world reaches here.
	 * ------------------------------------------------
	 */
	mrs	x30, scr_el3
	tst	x30, #SCR_NS_BIT
	b.ne	unexpected_sync_exception

	/* ----------------------------------------------
	 * Handling RUN_IMAGE SMC. First switch back to
	 * SP_EL0 for the C runtime stack.
205
206
207
208
209
210
	 * ----------------------------------------------
	 */
	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
	msr	spsel, #0
	mov	sp, x30

211
	/* ---------------------------------------------------------------------
212
213
214
	 * Pass EL3 control to BL31.
	 * Here it expects X1 with the address of a entry_point_info_t
	 * structure describing the BL31 entrypoint.
215
216
217
218
219
	 * ---------------------------------------------------------------------
	 */
	mov	x20, x1

	mov	x0, x20
220
	bl	bl1_print_bl31_ep_info
221
222
223
224
225
226
227
228
229
230
231

	ldp	x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
	msr	elr_el3, x0
	msr	spsr_el3, x1
	ubfx	x0, x1, #MODE_EL_SHIFT, #2
	cmp	x0, #MODE_EL3
	b.ne	unexpected_sync_exception

	bl	disable_mmu_icache_el3
	tlbi	alle3

232
233
234
235
236
237
#if SPIN_ON_BL1_EXIT
	bl	print_debug_loop_message
debug_loop:
	b	debug_loop
#endif

238
	mov	x0, x20
239
240
	bl	bl1_plat_prepare_exit

241
242
243
244
245
246
247
248
249
250
251
252
	ldp	x6, x7, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x30)]
	ldp	x4, x5, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x20)]
	ldp	x2, x3, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x10)]
	ldp	x0, x1, [x20, #(ENTRY_POINT_INFO_ARGS_OFFSET + 0x0)]
	eret
endfunc smc_handler64

unexpected_sync_exception:
	mov	x0, #SYNC_EXCEPTION_AARCH64
	bl	plat_report_exception
	wfi
	b	unexpected_sync_exception
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318

	/* -----------------------------------------------------
	 * Save Secure/Normal world context and jump to
	 * BL1 SMC handler.
	 * -----------------------------------------------------
	 */
smc_handler:
	/* -----------------------------------------------------
	 * Save the GP registers x0-x29.
	 * TODO: Revisit to store only SMCC specified registers.
	 * -----------------------------------------------------
	 */
	bl	save_gp_registers

	/* -----------------------------------------------------
	 * Populate the parameters for the SMC handler. We
	 * already have x0-x4 in place. x5 will point to a
	 * cookie (not used now). x6 will point to the context
	 * structure (SP_EL3) and x7 will contain flags we need
	 * to pass to the handler.
	 * -----------------------------------------------------
	 */
	mov	x5, xzr
	mov	x6, sp

	/* -----------------------------------------------------
	 * Restore the saved C runtime stack value which will
	 * become the new SP_EL0 i.e. EL3 runtime stack. It was
	 * saved in the 'cpu_context' structure prior to the last
	 * ERET from EL3.
	 * -----------------------------------------------------
	 */
	ldr	x12, [x6, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]

	/* ---------------------------------------------
	 * Switch back to SP_EL0 for the C runtime stack.
	 * ---------------------------------------------
	 */
	msr	spsel, #0
	mov	sp, x12

	/* -----------------------------------------------------
	 * Save the SPSR_EL3, ELR_EL3, & SCR_EL3 in case there
	 * is a world switch during SMC handling.
	 * -----------------------------------------------------
	 */
	mrs	x16, spsr_el3
	mrs	x17, elr_el3
	mrs	x18, scr_el3
	stp	x16, x17, [x6, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
	str	x18, [x6, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]

	/* Copy SCR_EL3.NS bit to the flag to indicate caller's security */
	bfi	x7, x18, #0, #1

	/* -----------------------------------------------------
	 * Go to BL1 SMC handler.
	 * -----------------------------------------------------
	 */
	bl	bl1_smc_handler

	/* -----------------------------------------------------
	 * Do the transition to next BL image.
	 * -----------------------------------------------------
	 */
	b	el3_exit