bl1_exceptions.S 7.42 KB
Newer Older
1
/*
2
 * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
3
 *
dp-arm's avatar
dp-arm committed
4
 * SPDX-License-Identifier: BSD-3-Clause
5
6
7
 */

#include <arch.h>
8
#include <asm_macros.S>
9
#include <bl1.h>
Isla Mitchell's avatar
Isla Mitchell committed
10
#include <bl_common.h>
11
#include <context.h>
12

13
14
15
16
/* -----------------------------------------------------------------------------
 * Very simple stackless exception handlers used by BL1.
 * -----------------------------------------------------------------------------
 */
17
	.globl	bl1_exceptions
18

19
vector_base bl1_exceptions
20
21

	/* -----------------------------------------------------
22
	 * Current EL with SP0 : 0x0 - 0x200
23
24
	 * -----------------------------------------------------
	 */
25
vector_entry SynchronousExceptionSP0
26
27
	mov	x0, #SYNC_EXCEPTION_SP_EL0
	bl	plat_report_exception
28
	no_ret	plat_panic_handler
29
	check_vector_size SynchronousExceptionSP0
30

31
vector_entry IrqSP0
32
33
	mov	x0, #IRQ_SP_EL0
	bl	plat_report_exception
34
	no_ret	plat_panic_handler
35
	check_vector_size IrqSP0
36

37
vector_entry FiqSP0
38
39
	mov	x0, #FIQ_SP_EL0
	bl	plat_report_exception
40
	no_ret	plat_panic_handler
41
	check_vector_size FiqSP0
42

43
vector_entry SErrorSP0
44
45
	mov	x0, #SERROR_SP_EL0
	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
	 * -----------------------------------------------------
	 */
53
vector_entry SynchronousExceptionSPx
54
55
	mov	x0, #SYNC_EXCEPTION_SP_ELX
	bl	plat_report_exception
56
	no_ret	plat_panic_handler
57
	check_vector_size SynchronousExceptionSPx
58

59
vector_entry IrqSPx
60
61
	mov	x0, #IRQ_SP_ELX
	bl	plat_report_exception
62
	no_ret	plat_panic_handler
63
	check_vector_size IrqSPx
64

65
vector_entry FiqSPx
66
67
	mov	x0, #FIQ_SP_ELX
	bl	plat_report_exception
68
	no_ret	plat_panic_handler
69
	check_vector_size FiqSPx
70

71
vector_entry SErrorSPx
72
73
	mov	x0, #SERROR_SP_ELX
	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
	 * -----------------------------------------------------
	 */
81
vector_entry SynchronousExceptionA64
82
83
84
	/* Enable the SError interrupt */
	msr	daifclr, #DAIF_ABT_BIT

85
86
	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]

87
	/* Expect only SMC exceptions */
88
89
90
	mrs	x30, esr_el3
	ubfx	x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
	cmp	x30, #EC_AARCH64_SMC
91
	b.ne	unexpected_sync_exception
92

93
	b	smc_handler64
94
	check_vector_size SynchronousExceptionA64
95

96
vector_entry IrqA64
97
98
	mov	x0, #IRQ_AARCH64
	bl	plat_report_exception
99
	no_ret	plat_panic_handler
100
	check_vector_size IrqA64
101

102
vector_entry FiqA64
103
104
	mov	x0, #FIQ_AARCH64
	bl	plat_report_exception
105
	no_ret	plat_panic_handler
106
	check_vector_size FiqA64
107

108
vector_entry SErrorA64
109
110
	mov	x0, #SERROR_AARCH64
	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
	 * -----------------------------------------------------
	 */
118
vector_entry SynchronousExceptionA32
119
120
	mov	x0, #SYNC_EXCEPTION_AARCH32
	bl	plat_report_exception
121
	no_ret	plat_panic_handler
122
	check_vector_size SynchronousExceptionA32
123

124
vector_entry IrqA32
125
126
	mov	x0, #IRQ_AARCH32
	bl	plat_report_exception
127
	no_ret	plat_panic_handler
128
	check_vector_size IrqA32
129

130
vector_entry FiqA32
131
132
	mov	x0, #FIQ_AARCH32
	bl	plat_report_exception
133
	no_ret	plat_panic_handler
134
	check_vector_size FiqA32
135

136
vector_entry SErrorA32
137
138
	mov	x0, #SERROR_AARCH32
	bl	plat_report_exception
139
	no_ret	plat_panic_handler
140
	check_vector_size SErrorA32
141
142
143


func smc_handler64
144

145
	/* ----------------------------------------------
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
	 * 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.
164
165
166
167
168
169
	 * ----------------------------------------------
	 */
	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
	msr	spsel, #0
	mov	sp, x30

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
177
178
	 * ---------------------------------------------------------------------
	 */
	mov	x20, x1

	mov	x0, x20
179
	bl	bl1_print_next_bl_ep_info
180
181
182
183
184
185
186
187
188
189

	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
190
	dsb	ish /* ERET implies ISB, so it is not needed here */
191

192
193
194
195
196
197
#if SPIN_ON_BL1_EXIT
	bl	print_debug_loop_message
debug_loop:
	b	debug_loop
#endif

198
	mov	x0, x20
199
200
	bl	bl1_plat_prepare_exit

201
202
203
204
205
206
207
208
209
210
	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
211
	no_ret	plat_panic_handler
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
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

	/* -----------------------------------------------------
	 * 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