xref: /kvm-unit-tests/arm/cstart64.S (revision abdc5d02a7796a55802509ac9bb704c721f2a5f6)
139ac3f84SAndrew Jones/*
239ac3f84SAndrew Jones * Boot entry point and assembler functions for aarch64 tests.
339ac3f84SAndrew Jones *
449f758b8SAndrew Jones * Copyright (C) 2017, Red Hat Inc, Andrew Jones <drjones@redhat.com>
539ac3f84SAndrew Jones *
649f758b8SAndrew Jones * This work is licensed under the terms of the GNU GPL, version 2.
739ac3f84SAndrew Jones */
862bdc67fSAndrew Jones#include <auxinfo.h>
939ac3f84SAndrew Jones#include <asm/asm-offsets.h>
10b5f659beSAlexandru Elisei#include <asm/assembler.h>
117ee966e9SAndrew Jones#include <asm/ptrace.h>
12db328a24SAndrew Jones#include <asm/page.h>
13db328a24SAndrew Jones#include <asm/pgtable-hwdef.h>
14d47d370cSSubhasish Ghosh#include <asm/processor.h>
15993c37beSAndrew Jones#include <asm/thread_info.h>
161dd3501aSAlexandru Elisei#include <asm/sysreg.h>
17993c37beSAndrew Jones
18d231b539SNikos Nikoleris#ifdef CONFIG_EFI
19d231b539SNikos Nikoleris#include "efi/crt0-efi-aarch64.S"
20d231b539SNikos Nikoleris#else
21d231b539SNikos Nikoleris
22993c37beSAndrew Jones.macro zero_range, tmp1, tmp2
23993c37beSAndrew Jones9998:	cmp	\tmp1, \tmp2
24993c37beSAndrew Jones	b.eq	9997f
25993c37beSAndrew Jones	stp	xzr, xzr, [\tmp1], #16
26993c37beSAndrew Jones	b	9998b
27993c37beSAndrew Jones9997:
28993c37beSAndrew Jones.endm
2939ac3f84SAndrew Jones
3039ac3f84SAndrew Jones.section .init
3139ac3f84SAndrew Jones
32f6416021SAndrew Jones/*
33f6416021SAndrew Jones * Bootloader params are in x0-x3. See kernel doc
34f6416021SAndrew Jones * Documentation/arm64/booting.txt
35f6416021SAndrew Jones */
3639ac3f84SAndrew Jones.globl start
3739ac3f84SAndrew Jonesstart:
38f6416021SAndrew Jones	/* get our base address */
39f6416021SAndrew Jones	adrp	x4, start
40f6416021SAndrew Jones	add     x4, x4, :lo12:start
41f6416021SAndrew Jones
4239ac3f84SAndrew Jones	/*
43f6416021SAndrew Jones	 * Update all R_AARCH64_RELATIVE relocations using the table
44f6416021SAndrew Jones	 * of Elf64_Rela entries between reloc_start/end. The build
45f6416021SAndrew Jones	 * will not emit other relocation types.
46f6416021SAndrew Jones	 *
47f6416021SAndrew Jones	 * struct Elf64_Rela {
48f6416021SAndrew Jones	 * 	uint64_t r_offset;
49f6416021SAndrew Jones	 * 	uint64_t r_info;
50f6416021SAndrew Jones	 * 	int64_t  r_addend;
51f6416021SAndrew Jones	 * }
5239ac3f84SAndrew Jones	 */
53f6416021SAndrew Jones	adrp	x5, reloc_start
54f6416021SAndrew Jones	add     x5, x5, :lo12:reloc_start
55f6416021SAndrew Jones	adrp	x6, reloc_end
56f6416021SAndrew Jones	add     x6, x6, :lo12:reloc_end
57f6416021SAndrew Jones1:
58f6416021SAndrew Jones	cmp	x5, x6
59f6416021SAndrew Jones	b.hs	1f
60f6416021SAndrew Jones	ldr	x7, [x5]			// r_offset
61f6416021SAndrew Jones	ldr	x8, [x5, #16]			// r_addend
62f6416021SAndrew Jones	add	x8, x8, x4			// val = base + r_addend
63f6416021SAndrew Jones	str	x8, [x4, x7]			// base[r_offset] = val
64f6416021SAndrew Jones	add	x5, x5, #24
65f6416021SAndrew Jones	b	1b
66f6416021SAndrew Jones
67f6416021SAndrew Jones1:
68993c37beSAndrew Jones	/* zero BSS */
69993c37beSAndrew Jones	adrp	x4, bss
70993c37beSAndrew Jones	add	x4, x4, :lo12:bss
71993c37beSAndrew Jones	adrp    x5, ebss
72993c37beSAndrew Jones	add     x5, x5, :lo12:ebss
73993c37beSAndrew Jones	zero_range x4, x5
74993c37beSAndrew Jones
75993c37beSAndrew Jones	/* zero and set up stack */
76993c37beSAndrew Jones	adrp    x5, stacktop
77993c37beSAndrew Jones	add     x5, x5, :lo12:stacktop
78993c37beSAndrew Jones	sub	x4, x5, #THREAD_SIZE
79993c37beSAndrew Jones	zero_range x4, x5
8010b65ce7SAlexandru Elisei
8110b65ce7SAlexandru Elisei	/* set SCTLR_EL1 to a known value */
8210b65ce7SAlexandru Elisei	ldr	x4, =INIT_SCTLR_EL1_MMU_OFF
8310b65ce7SAlexandru Elisei	msr	sctlr_el1, x4
8410b65ce7SAlexandru Elisei	isb
8510b65ce7SAlexandru Elisei
861693644dSAndrew Jones	mov	x4, #1
871693644dSAndrew Jones	msr	spsel, x4
8863ab2d70SPaolo Bonzini	adrp    x4, stackptr
8963ab2d70SPaolo Bonzini	add     sp, x4, :lo12:stackptr
9039ac3f84SAndrew Jones
91231796c5SJoey Gouly	/* enable FP/ASIMD and SVE */
92231796c5SJoey Gouly	mov	x4, (3 << 20)
93231796c5SJoey Gouly	orr	x4, x4, (3 << 16)
94f6416021SAndrew Jones	msr	cpacr_el1, x4
9539ac3f84SAndrew Jones
9639ac3f84SAndrew Jones	/* set up exception handling */
977ee966e9SAndrew Jones	bl	exceptions_init
9839ac3f84SAndrew Jones
9939ac3f84SAndrew Jones	/* complete setup */
1005a2a7371SAndrew Jones	adrp	x1, stacktop
1015a2a7371SAndrew Jones	add	x1, x1, :lo12:stacktop		// x1 is the base of free memory
102f6416021SAndrew Jones	bl	setup				// x0 is the addr of the dtb
10339ac3f84SAndrew Jones
10439ac3f84SAndrew Jones	/* run the test */
10563ab2d70SPaolo Bonzini	adrp	x0, __argc
106364bb39dSAndrew Jones	ldr	w0, [x0, :lo12:__argc]
10763ab2d70SPaolo Bonzini	adrp	x1, __argv
10863ab2d70SPaolo Bonzini	add	x1, x1, :lo12:__argv
10963ab2d70SPaolo Bonzini	adrp	x2, __environ
11063ab2d70SPaolo Bonzini	add	x2, x2, :lo12:__environ
11139ac3f84SAndrew Jones	bl	main
11239ac3f84SAndrew Jones	bl	exit
11339ac3f84SAndrew Jones	b	halt
11439ac3f84SAndrew Jones
115d231b539SNikos Nikoleris#endif
116d231b539SNikos Nikoleris
11739ac3f84SAndrew Jones.text
11839ac3f84SAndrew Jones
119bd5bd157SAndrew Jones/*
120cddb18bcSAlexandru Elisei * arm_smccc_hvc / arm_smccc_smc
121bd5bd157SAndrew Jones *
122bd5bd157SAndrew Jones * Inputs:
123bd5bd157SAndrew Jones *   w0 -- function_id
124bd5bd157SAndrew Jones *   x1 -- arg0
125bd5bd157SAndrew Jones *   x2 -- arg1
126bd5bd157SAndrew Jones *   x3 -- arg2
127cddb18bcSAlexandru Elisei *   x4 -- arg3
128cddb18bcSAlexandru Elisei *   x5 -- arg4
129cddb18bcSAlexandru Elisei *   x6 -- arg5
130cddb18bcSAlexandru Elisei *   x7 -- arg6
131cddb18bcSAlexandru Elisei *   sp -- { arg7, arg8, arg9, arg10, result }
132bd5bd157SAndrew Jones *
133bd5bd157SAndrew Jones * Outputs:
134bd5bd157SAndrew Jones *   x0 -- return code
135cddb18bcSAlexandru Elisei *
136cddb18bcSAlexandru Elisei * If result pointer is not NULL:
137cddb18bcSAlexandru Elisei *   result.r0 -- return code
138cddb18bcSAlexandru Elisei *   result.r1 -- x1
139cddb18bcSAlexandru Elisei *   result.r2 -- x2
140cddb18bcSAlexandru Elisei *   result.r3 -- x3
141cddb18bcSAlexandru Elisei *   result.r4 -- x4
142cddb18bcSAlexandru Elisei *   result.r5 -- x5
143cddb18bcSAlexandru Elisei *   result.r6 -- x6
144cddb18bcSAlexandru Elisei *   result.r7 -- x7
145cddb18bcSAlexandru Elisei *   result.r8 -- x8
146cddb18bcSAlexandru Elisei *   result.r9 -- x9
147bd5bd157SAndrew Jones */
148cddb18bcSAlexandru Elisei.macro do_smccc_call instr
149cddb18bcSAlexandru Elisei	/* Save x8-x11 on stack */
150cddb18bcSAlexandru Elisei	stp	x9, x8,	  [sp, #-16]!
151cddb18bcSAlexandru Elisei	stp	x11, x10, [sp, #-16]!
152cddb18bcSAlexandru Elisei	/* Load arg7 - arg10 from the stack */
153cddb18bcSAlexandru Elisei	ldp	x8, x9,   [sp, #32]
154cddb18bcSAlexandru Elisei	ldp	x10, x11, [sp, #48]
155cddb18bcSAlexandru Elisei	\instr	#0
156cddb18bcSAlexandru Elisei	/* Get the result address */
157cddb18bcSAlexandru Elisei	ldr	x10, [sp, #64]
158cddb18bcSAlexandru Elisei	cmp	x10, xzr
159cddb18bcSAlexandru Elisei	b.eq	1f
160cddb18bcSAlexandru Elisei	stp	x0, x1, [x10, #0]
161cddb18bcSAlexandru Elisei	stp	x2, x3, [x10, #16]
162cddb18bcSAlexandru Elisei	stp	x4, x5, [x10, #32]
163cddb18bcSAlexandru Elisei	stp	x6, x7, [x10, #48]
164cddb18bcSAlexandru Elisei	stp	x8, x9, [x10, #64]
165cddb18bcSAlexandru Elisei1:
166cddb18bcSAlexandru Elisei	/* Restore x8-x11 from stack */
167cddb18bcSAlexandru Elisei	ldp	x11, x10, [sp], #16
168cddb18bcSAlexandru Elisei	ldp	x9, x8,   [sp], #16
169bd5bd157SAndrew Jones	ret
170cddb18bcSAlexandru Elisei.endm
171bd5bd157SAndrew Jones
172cddb18bcSAlexandru Elisei.globl arm_smccc_hvc
173cddb18bcSAlexandru Eliseiarm_smccc_hvc:
174cddb18bcSAlexandru Elisei	do_smccc_call hvc
175cddb18bcSAlexandru Elisei
176cddb18bcSAlexandru Elisei.globl arm_smccc_smc
177cddb18bcSAlexandru Eliseiarm_smccc_smc:
178cddb18bcSAlexandru Elisei	do_smccc_call smc
179bd5bd157SAndrew Jones
18062bdc67fSAndrew Jonesget_mmu_off:
18162bdc67fSAndrew Jones	adrp	x0, auxinfo
18262bdc67fSAndrew Jones	ldr	x0, [x0, :lo12:auxinfo + 8]
18362bdc67fSAndrew Jones	and	x0, x0, #AUXINFO_MMU_OFF
18462bdc67fSAndrew Jones	ret
18562bdc67fSAndrew Jones
18668ea0e0bSAndrew Jones.globl secondary_entry
18768ea0e0bSAndrew Jonessecondary_entry:
188231796c5SJoey Gouly	/* enable FP/ASIMD and SVE */
18968ea0e0bSAndrew Jones	mov	x0, #(3 << 20)
190231796c5SJoey Gouly	orr	x0, x0, #(3 << 16)
19168ea0e0bSAndrew Jones	msr	cpacr_el1, x0
19268ea0e0bSAndrew Jones
19368ea0e0bSAndrew Jones	/* set up exception handling */
19468ea0e0bSAndrew Jones	bl	exceptions_init
19568ea0e0bSAndrew Jones
19662bdc67fSAndrew Jones	/* enable the MMU unless requested off */
19762bdc67fSAndrew Jones	bl	get_mmu_off
19862bdc67fSAndrew Jones	cbnz	x0, 1f
19963ab2d70SPaolo Bonzini	adrp	x0, mmu_idmap
20063ab2d70SPaolo Bonzini	ldr	x0, [x0, :lo12:mmu_idmap]
20168ea0e0bSAndrew Jones	bl	asm_mmu_enable
20268ea0e0bSAndrew Jones
20362bdc67fSAndrew Jones1:
20468ea0e0bSAndrew Jones	/* set the stack */
20563ab2d70SPaolo Bonzini	adrp	x0, secondary_data
20663ab2d70SPaolo Bonzini	ldr	x0, [x0, :lo12:secondary_data]
20768ea0e0bSAndrew Jones	mov	sp, x0
20868ea0e0bSAndrew Jones
20968ea0e0bSAndrew Jones	/* finish init in C code */
21068ea0e0bSAndrew Jones	bl	secondary_cinit
21168ea0e0bSAndrew Jones
21268ea0e0bSAndrew Jones	/* x0 is now the entry function, run it */
213543ce33cSAndrew Jones	blr	x0
2149246de4cSAndrew Jones	b	do_idle
21568ea0e0bSAndrew Jones
21639ac3f84SAndrew Jones.globl halt
21739ac3f84SAndrew Joneshalt:
21839ac3f84SAndrew Jones1:	wfi
21939ac3f84SAndrew Jones	b	1b
2207ee966e9SAndrew Jones
2217ee966e9SAndrew Jones/*
222db328a24SAndrew Jones * asm_mmu_enable
223db328a24SAndrew Jones *   Inputs:
224db328a24SAndrew Jones *     x0 is the base address of the translation table
225db328a24SAndrew Jones *   Outputs: none
226db328a24SAndrew Jones *
227db328a24SAndrew Jones * Adapted from
228db328a24SAndrew Jones *   arch/arm64/kernel/head.S
229db328a24SAndrew Jones *   arch/arm64/mm/proc.S
230db328a24SAndrew Jones */
231db328a24SAndrew Jones
232db328a24SAndrew Jones/*
233db328a24SAndrew Jones * Memory region attributes for LPAE:
234db328a24SAndrew Jones *
235db328a24SAndrew Jones *   n = AttrIndx[2:0]
236db328a24SAndrew Jones *                      n       MAIR
237db328a24SAndrew Jones *   DEVICE_nGnRnE      000     00000000
238db328a24SAndrew Jones *   DEVICE_nGnRE       001     00000100
239db328a24SAndrew Jones *   DEVICE_GRE         010     00001100
240db328a24SAndrew Jones *   NORMAL_NC          011     01000100
241db328a24SAndrew Jones *   NORMAL             100     11111111
242cc70e4b6SNikos Nikoleris *   NORMAL_WT          101     10111011
243cc70e4b6SNikos Nikoleris *   DEVICE_nGRE        110     00001000
244*1b59c632SVladimir Murzin *   NORMAL_TAGGED      111     11110000
245db328a24SAndrew Jones */
246db328a24SAndrew Jones#define MAIR(attr, mt) ((attr) << ((mt) * 8))
247db328a24SAndrew Jones
248a2d06852SNikos Nikoleris#if PAGE_SIZE == SZ_64K
249a2d06852SNikos Nikoleris#define TCR_TG_FLAGS	TCR_TG0_64K | TCR_TG1_64K
250a2d06852SNikos Nikoleris#elif PAGE_SIZE == SZ_16K
251a2d06852SNikos Nikoleris#define TCR_TG_FLAGS	TCR_TG0_16K | TCR_TG1_16K
252a2d06852SNikos Nikoleris#elif PAGE_SIZE == SZ_4K
253a2d06852SNikos Nikoleris#define TCR_TG_FLAGS	TCR_TG0_4K | TCR_TG1_4K
254a2d06852SNikos Nikoleris#endif
255a2d06852SNikos Nikoleris
256db328a24SAndrew Jones.globl asm_mmu_enable
257db328a24SAndrew Jonesasm_mmu_enable:
25842d51704SAlexandru Elisei	tlbi	vmalle1			// invalidate I + D TLBs
25942d51704SAlexandru Elisei	dsb	nsh
260db328a24SAndrew Jones
261db328a24SAndrew Jones	/* TCR */
262db328a24SAndrew Jones	ldr	x1, =TCR_TxSZ(VA_BITS) |		\
263a2d06852SNikos Nikoleris		     TCR_TG_FLAGS  |			\
264db328a24SAndrew Jones		     TCR_IRGN_WBWA | TCR_ORGN_WBWA |	\
2658425ac5cSAlexandru Elisei		     TCR_SHARED |			\
2668425ac5cSAlexandru Elisei		     TCR_EPD1
267d140ad48SAndrew Jones	mrs	x2, id_aa64mmfr0_el1
268db328a24SAndrew Jones	bfi	x1, x2, #32, #3
269db328a24SAndrew Jones	msr	tcr_el1, x1
270db328a24SAndrew Jones
271db328a24SAndrew Jones	/* MAIR */
272db328a24SAndrew Jones	ldr	x1, =MAIR(0x00, MT_DEVICE_nGnRnE) |	\
273db328a24SAndrew Jones		     MAIR(0x04, MT_DEVICE_nGnRE) |	\
274db328a24SAndrew Jones		     MAIR(0x0c, MT_DEVICE_GRE) |	\
275db328a24SAndrew Jones		     MAIR(0x44, MT_NORMAL_NC) |		\
276cc70e4b6SNikos Nikoleris		     MAIR(0xff, MT_NORMAL) |	        \
277cc70e4b6SNikos Nikoleris		     MAIR(0xbb, MT_NORMAL_WT) |         \
278*1b59c632SVladimir Murzin		     MAIR(0x08, MT_DEVICE_nGRE) |       \
279*1b59c632SVladimir Murzin		     MAIR(0xf0, MT_NORMAL_TAGGED)
280db328a24SAndrew Jones	msr	mair_el1, x1
281db328a24SAndrew Jones
282db328a24SAndrew Jones	/* TTBR0 */
283db328a24SAndrew Jones	msr	ttbr0_el1, x0
284db328a24SAndrew Jones	isb
285db328a24SAndrew Jones
286db328a24SAndrew Jones	/* SCTLR */
287db328a24SAndrew Jones	mrs	x1, sctlr_el1
288db328a24SAndrew Jones	orr	x1, x1, SCTLR_EL1_C
289db328a24SAndrew Jones	orr	x1, x1, SCTLR_EL1_I
290db328a24SAndrew Jones	orr	x1, x1, SCTLR_EL1_M
291db328a24SAndrew Jones	msr	sctlr_el1, x1
292db328a24SAndrew Jones	isb
293db328a24SAndrew Jones
294db328a24SAndrew Jones	ret
295db328a24SAndrew Jones
296e27b176bSAndrew Jones.globl asm_mmu_disable
297e27b176bSAndrew Jonesasm_mmu_disable:
298e27b176bSAndrew Jones	mrs	x0, sctlr_el1
299e27b176bSAndrew Jones	bic	x0, x0, SCTLR_EL1_M
300e27b176bSAndrew Jones	msr	sctlr_el1, x0
301e27b176bSAndrew Jones	isb
302410b3bf0SAlexandru Elisei
303410b3bf0SAlexandru Elisei	/* Clean + invalidate the entire memory */
304410b3bf0SAlexandru Elisei	adrp	x0, __phys_offset
305410b3bf0SAlexandru Elisei	ldr	x0, [x0, :lo12:__phys_offset]
306410b3bf0SAlexandru Elisei	adrp	x1, __phys_end
307410b3bf0SAlexandru Elisei	ldr	x1, [x1, :lo12:__phys_end]
308b5f659beSAlexandru Elisei	sub	x1, x1, x0
309410b3bf0SAlexandru Elisei	dcache_by_line_op civac, sy, x0, x1, x2, x3
310410b3bf0SAlexandru Elisei
311e27b176bSAndrew Jones	ret
312e27b176bSAndrew Jones
313db328a24SAndrew Jones/*
3147ee966e9SAndrew Jones * Vectors
3152da0f98cSAndrew Jones */
3162da0f98cSAndrew Jones
31723e17626SNikos Nikoleris.globl exceptions_init
3182da0f98cSAndrew Jonesexceptions_init:
3192da0f98cSAndrew Jones	adrp	x4, vector_table
3202da0f98cSAndrew Jones	add	x4, x4, :lo12:vector_table
3212da0f98cSAndrew Jones	msr	vbar_el1, x4
3222da0f98cSAndrew Jones	isb
3232da0f98cSAndrew Jones	ret
3242da0f98cSAndrew Jones
3252da0f98cSAndrew Jones/*
3262da0f98cSAndrew Jones * Vector stubs
3277ee966e9SAndrew Jones * Adapted from arch/arm64/kernel/entry.S
328332b6216SNikos Nikoleris * Declare as weak to allow external tests to redefine and override a
329332b6216SNikos Nikoleris * vector_stub.
3307ee966e9SAndrew Jones */
3317ee966e9SAndrew Jones.macro vector_stub, name, vec
332332b6216SNikos Nikoleris.weak \name
3337ee966e9SAndrew Jones\name:
3347ee966e9SAndrew Jones	stp	 x0,  x1, [sp, #-S_FRAME_SIZE]!
3357ee966e9SAndrew Jones	stp	 x2,  x3, [sp,  #16]
3367ee966e9SAndrew Jones	stp	 x4,  x5, [sp,  #32]
3377ee966e9SAndrew Jones	stp	 x6,  x7, [sp,  #48]
3387ee966e9SAndrew Jones	stp	 x8,  x9, [sp,  #64]
3397ee966e9SAndrew Jones	stp	x10, x11, [sp,  #80]
3407ee966e9SAndrew Jones	stp	x12, x13, [sp,  #96]
3417ee966e9SAndrew Jones	stp	x14, x15, [sp, #112]
3427ee966e9SAndrew Jones	stp	x16, x17, [sp, #128]
3437ee966e9SAndrew Jones	stp	x18, x19, [sp, #144]
3447ee966e9SAndrew Jones	stp	x20, x21, [sp, #160]
3457ee966e9SAndrew Jones	stp	x22, x23, [sp, #176]
3467ee966e9SAndrew Jones	stp	x24, x25, [sp, #192]
3477ee966e9SAndrew Jones	stp	x26, x27, [sp, #208]
3487ee966e9SAndrew Jones	stp	x28, x29, [sp, #224]
3497ee966e9SAndrew Jones
3507ee966e9SAndrew Jones	str	x30, [sp, #S_LR]
3517ee966e9SAndrew Jones
3527ee966e9SAndrew Jones	.if \vec >= 8
3537ee966e9SAndrew Jones	mrs	x1, sp_el0
3547ee966e9SAndrew Jones	.else
3557ee966e9SAndrew Jones	add	x1, sp, #S_FRAME_SIZE
3567ee966e9SAndrew Jones	.endif
3577ee966e9SAndrew Jones	str	x1, [sp, #S_SP]
3587ee966e9SAndrew Jones
3597ee966e9SAndrew Jones	mrs	x1, elr_el1
3607ee966e9SAndrew Jones	mrs	x2, spsr_el1
3617ee966e9SAndrew Jones	stp	x1, x2, [sp, #S_PC]
3627ee966e9SAndrew Jones
363ecb5e711SNadav Amit	/*
364ecb5e711SNadav Amit	 * Save a frame pointer using the link to allow unwinding of
365ecb5e711SNadav Amit	 * exceptions.
366ecb5e711SNadav Amit	 */
367ecb5e711SNadav Amit	stp	x29, x1, [sp, #S_FP]
368ecb5e711SNadav Amit	add 	x29, sp, #S_FP
369ecb5e711SNadav Amit
370f6d10793SAndrew Jones	mov	x0, \vec
3717ee966e9SAndrew Jones	mov	x1, sp
3727ee966e9SAndrew Jones	mrs	x2, esr_el1
3737ee966e9SAndrew Jones	bl	do_handle_exception
3747ee966e9SAndrew Jones
3757ee966e9SAndrew Jones	ldp	x1, x2, [sp, #S_PC]
3767ee966e9SAndrew Jones	msr	spsr_el1, x2
3777ee966e9SAndrew Jones	msr	elr_el1, x1
3787ee966e9SAndrew Jones
3797ee966e9SAndrew Jones	.if \vec >= 8
3807ee966e9SAndrew Jones	ldr	x1, [sp, #S_SP]
3817ee966e9SAndrew Jones	msr	sp_el0, x1
3827ee966e9SAndrew Jones	.endif
3837ee966e9SAndrew Jones
3847ee966e9SAndrew Jones	ldr	x30, [sp, #S_LR]
3857ee966e9SAndrew Jones
3867ee966e9SAndrew Jones	ldp	x28, x29, [sp, #224]
3877ee966e9SAndrew Jones	ldp	x26, x27, [sp, #208]
3887ee966e9SAndrew Jones	ldp	x24, x25, [sp, #192]
3897ee966e9SAndrew Jones	ldp	x22, x23, [sp, #176]
3907ee966e9SAndrew Jones	ldp	x20, x21, [sp, #160]
3917ee966e9SAndrew Jones	ldp	x18, x19, [sp, #144]
3927ee966e9SAndrew Jones	ldp	x16, x17, [sp, #128]
3937ee966e9SAndrew Jones	ldp	x14, x15, [sp, #112]
3947ee966e9SAndrew Jones	ldp	x12, x13, [sp,  #96]
3957ee966e9SAndrew Jones	ldp	x10, x11, [sp,  #80]
3967ee966e9SAndrew Jones	ldp	 x8,  x9, [sp,  #64]
3977ee966e9SAndrew Jones	ldp	 x6,  x7, [sp,  #48]
3987ee966e9SAndrew Jones	ldp	 x4,  x5, [sp,  #32]
3997ee966e9SAndrew Jones	ldp	 x2,  x3, [sp,  #16]
4007ee966e9SAndrew Jones	ldp	 x0,  x1, [sp], #S_FRAME_SIZE
4017ee966e9SAndrew Jones
4027ee966e9SAndrew Jones	eret
4037ee966e9SAndrew Jones.endm
4047ee966e9SAndrew Jones
405ecb5e711SNadav Amit.globl vector_stub_start
406ecb5e711SNadav Amitvector_stub_start:
407ecb5e711SNadav Amit
4087ee966e9SAndrew Jonesvector_stub	el1t_sync,     0
4097ee966e9SAndrew Jonesvector_stub	el1t_irq,      1
4107ee966e9SAndrew Jonesvector_stub	el1t_fiq,      2
4117ee966e9SAndrew Jonesvector_stub	el1t_error,    3
4127ee966e9SAndrew Jones
4137ee966e9SAndrew Jonesvector_stub	el1h_sync,     4
4147ee966e9SAndrew Jonesvector_stub	el1h_irq,      5
4157ee966e9SAndrew Jonesvector_stub	el1h_fiq,      6
4167ee966e9SAndrew Jonesvector_stub	el1h_error,    7
4177ee966e9SAndrew Jones
4187ee966e9SAndrew Jonesvector_stub	el0_sync_64,   8
4197ee966e9SAndrew Jonesvector_stub	el0_irq_64,    9
4207ee966e9SAndrew Jonesvector_stub	el0_fiq_64,   10
4217ee966e9SAndrew Jonesvector_stub	el0_error_64, 11
4227ee966e9SAndrew Jones
4237ee966e9SAndrew Jonesvector_stub	el0_sync_32,  12
4247ee966e9SAndrew Jonesvector_stub	el0_irq_32,   13
4257ee966e9SAndrew Jonesvector_stub	el0_fiq_32,   14
4267ee966e9SAndrew Jonesvector_stub	el0_error_32, 15
4277ee966e9SAndrew Jones
428ecb5e711SNadav Amit.globl vector_stub_end
429ecb5e711SNadav Amitvector_stub_end:
430ecb5e711SNadav Amit
4317ee966e9SAndrew Jones.section .text.ex
4327ee966e9SAndrew Jones
4337ee966e9SAndrew Jones.macro ventry, label
4347ee966e9SAndrew Jones.align 7
4357ee966e9SAndrew Jones	b	\label
4367ee966e9SAndrew Jones.endm
4377ee966e9SAndrew Jones
438332b6216SNikos Nikoleris
439332b6216SNikos Nikoleris/*
440332b6216SNikos Nikoleris * Declare as weak to allow external tests to redefine and override the
441332b6216SNikos Nikoleris * default vector table.
442332b6216SNikos Nikoleris */
4437ee966e9SAndrew Jones.align 11
444332b6216SNikos Nikoleris.weak vector_table
4457ee966e9SAndrew Jonesvector_table:
4467ee966e9SAndrew Jones	ventry	el1t_sync			// Synchronous EL1t
4477ee966e9SAndrew Jones	ventry	el1t_irq			// IRQ EL1t
4487ee966e9SAndrew Jones	ventry	el1t_fiq			// FIQ EL1t
4497ee966e9SAndrew Jones	ventry	el1t_error			// Error EL1t
4507ee966e9SAndrew Jones
4517ee966e9SAndrew Jones	ventry	el1h_sync			// Synchronous EL1h
4527ee966e9SAndrew Jones	ventry	el1h_irq			// IRQ EL1h
4537ee966e9SAndrew Jones	ventry	el1h_fiq			// FIQ EL1h
4547ee966e9SAndrew Jones	ventry	el1h_error			// Error EL1h
4557ee966e9SAndrew Jones
4567ee966e9SAndrew Jones	ventry	el0_sync_64			// Synchronous 64-bit EL0
4577ee966e9SAndrew Jones	ventry	el0_irq_64			// IRQ 64-bit EL0
4587ee966e9SAndrew Jones	ventry	el0_fiq_64			// FIQ 64-bit EL0
4597ee966e9SAndrew Jones	ventry	el0_error_64			// Error 64-bit EL0
4607ee966e9SAndrew Jones
4617ee966e9SAndrew Jones	ventry	el0_sync_32			// Synchronous 32-bit EL0
4627ee966e9SAndrew Jones	ventry	el0_irq_32			// IRQ 32-bit EL0
4637ee966e9SAndrew Jones	ventry	el0_fiq_32			// FIQ 32-bit EL0
4647ee966e9SAndrew Jones	ventry	el0_error_32			// Error 32-bit EL0
465