bl1_exceptions.S 8.76 KB
Newer Older
1
/*
2
 * Copyright (c) 2013-2016, 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
38
39
40
/* -----------------------------------------------------------------------------
 * Very simple stackless exception handlers used by BL1.
 * -----------------------------------------------------------------------------
 */
41
	.globl	bl1_exceptions
42

43
vector_base bl1_exceptions
44
45

	/* -----------------------------------------------------
46
	 * Current EL with SP0 : 0x0 - 0x200
47
48
	 * -----------------------------------------------------
	 */
49
vector_entry SynchronousExceptionSP0
50
51
	mov	x0, #SYNC_EXCEPTION_SP_EL0
	bl	plat_report_exception
52
	no_ret	plat_panic_handler
53
	check_vector_size SynchronousExceptionSP0
54

55
vector_entry IrqSP0
56
57
	mov	x0, #IRQ_SP_EL0
	bl	plat_report_exception
58
	no_ret	plat_panic_handler
59
	check_vector_size IrqSP0
60

61
vector_entry FiqSP0
62
63
	mov	x0, #FIQ_SP_EL0
	bl	plat_report_exception
64
	no_ret	plat_panic_handler
65
	check_vector_size FiqSP0
66

67
vector_entry SErrorSP0
68
69
	mov	x0, #SERROR_SP_EL0
	bl	plat_report_exception
70
	no_ret	plat_panic_handler
71
	check_vector_size SErrorSP0
72
73

	/* -----------------------------------------------------
74
	 * Current EL with SPx: 0x200 - 0x400
75
76
	 * -----------------------------------------------------
	 */
77
vector_entry SynchronousExceptionSPx
78
79
	mov	x0, #SYNC_EXCEPTION_SP_ELX
	bl	plat_report_exception
80
	no_ret	plat_panic_handler
81
	check_vector_size SynchronousExceptionSPx
82

83
vector_entry IrqSPx
84
85
	mov	x0, #IRQ_SP_ELX
	bl	plat_report_exception
86
	no_ret	plat_panic_handler
87
	check_vector_size IrqSPx
88

89
vector_entry FiqSPx
90
91
	mov	x0, #FIQ_SP_ELX
	bl	plat_report_exception
92
	no_ret	plat_panic_handler
93
	check_vector_size FiqSPx
94

95
vector_entry SErrorSPx
96
97
	mov	x0, #SERROR_SP_ELX
	bl	plat_report_exception
98
	no_ret	plat_panic_handler
99
	check_vector_size SErrorSPx
100
101

	/* -----------------------------------------------------
102
	 * Lower EL using AArch64 : 0x400 - 0x600
103
104
	 * -----------------------------------------------------
	 */
105
vector_entry SynchronousExceptionA64
106
107
108
	/* Enable the SError interrupt */
	msr	daifclr, #DAIF_ABT_BIT

109
110
	str	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]

111
	/* Expect only SMC exceptions */
112
113
114
	mrs	x30, esr_el3
	ubfx	x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
	cmp	x30, #EC_AARCH64_SMC
115
	b.ne	unexpected_sync_exception
116

117
	b	smc_handler64
118
	check_vector_size SynchronousExceptionA64
119

120
vector_entry IrqA64
121
122
	mov	x0, #IRQ_AARCH64
	bl	plat_report_exception
123
	no_ret	plat_panic_handler
124
	check_vector_size IrqA64
125

126
vector_entry FiqA64
127
128
	mov	x0, #FIQ_AARCH64
	bl	plat_report_exception
129
	no_ret	plat_panic_handler
130
	check_vector_size FiqA64
131

132
vector_entry SErrorA64
133
134
	mov	x0, #SERROR_AARCH64
	bl	plat_report_exception
135
	no_ret	plat_panic_handler
136
	check_vector_size SErrorA64
137
138

	/* -----------------------------------------------------
139
	 * Lower EL using AArch32 : 0x600 - 0x800
140
141
	 * -----------------------------------------------------
	 */
142
vector_entry SynchronousExceptionA32
143
144
	mov	x0, #SYNC_EXCEPTION_AARCH32
	bl	plat_report_exception
145
	no_ret	plat_panic_handler
146
	check_vector_size SynchronousExceptionA32
147

148
vector_entry IrqA32
149
150
	mov	x0, #IRQ_AARCH32
	bl	plat_report_exception
151
	no_ret	plat_panic_handler
152
	check_vector_size IrqA32
153

154
vector_entry FiqA32
155
156
	mov	x0, #FIQ_AARCH32
	bl	plat_report_exception
157
	no_ret	plat_panic_handler
158
	check_vector_size FiqA32
159

160
vector_entry SErrorA32
161
162
	mov	x0, #SERROR_AARCH32
	bl	plat_report_exception
163
	no_ret	plat_panic_handler
164
	check_vector_size SErrorA32
165
166
167


func smc_handler64
168

169
	/* ----------------------------------------------
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
	 * 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.
188
189
190
191
192
193
	 * ----------------------------------------------
	 */
	ldr	x30, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
	msr	spsel, #0
	mov	sp, x30

194
	/* ---------------------------------------------------------------------
195
	 * Pass EL3 control to next BL image.
196
	 * Here it expects X1 with the address of a entry_point_info_t
197
	 * structure describing the next BL image entrypoint.
198
199
200
201
202
	 * ---------------------------------------------------------------------
	 */
	mov	x20, x1

	mov	x0, x20
203
	bl	bl1_print_next_bl_ep_info
204
205
206
207
208
209
210
211
212
213
214

	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

215
216
217
218
219
220
#if SPIN_ON_BL1_EXIT
	bl	print_debug_loop_message
debug_loop:
	b	debug_loop
#endif

221
	mov	x0, x20
222
223
	bl	bl1_plat_prepare_exit

224
225
226
227
228
229
230
231
232
233
	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
234
	no_ret	plat_panic_handler
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
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

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