xref: /kvm-unit-tests/arm/cstart64.S (revision 62bdc67f9e596634b2b6927cc57c82173cb224a4)
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 */
839ac3f84SAndrew Jones#define __ASSEMBLY__
9*62bdc67fSAndrew Jones#include <auxinfo.h>
1039ac3f84SAndrew Jones#include <asm/asm-offsets.h>
117ee966e9SAndrew Jones#include <asm/ptrace.h>
12db328a24SAndrew Jones#include <asm/processor.h>
13db328a24SAndrew Jones#include <asm/page.h>
14db328a24SAndrew Jones#include <asm/pgtable-hwdef.h>
1539ac3f84SAndrew Jones
1639ac3f84SAndrew Jones.section .init
1739ac3f84SAndrew Jones
1839ac3f84SAndrew Jones.globl start
1939ac3f84SAndrew Jonesstart:
2039ac3f84SAndrew Jones	/*
2139ac3f84SAndrew Jones	 * bootloader params are in x0-x3
2239ac3f84SAndrew Jones	 * The physical address of the dtb is in x0, x1-x3 are reserved
2339ac3f84SAndrew Jones	 * See the kernel doc Documentation/arm64/booting.txt
2439ac3f84SAndrew Jones	 */
251693644dSAndrew Jones	mov	x4, #1
261693644dSAndrew Jones	msr	spsel, x4
271693644dSAndrew Jones	isb
2863ab2d70SPaolo Bonzini	adrp    x4, stackptr
2963ab2d70SPaolo Bonzini	add     sp, x4, :lo12:stackptr
3039ac3f84SAndrew Jones	stp	x0, x1, [sp, #-16]!
3139ac3f84SAndrew Jones
3239ac3f84SAndrew Jones	/* Enable FP/ASIMD */
3339ac3f84SAndrew Jones	mov	x0, #(3 << 20)
3439ac3f84SAndrew Jones	msr	cpacr_el1, x0
3539ac3f84SAndrew Jones
3639ac3f84SAndrew Jones	/* set up exception handling */
377ee966e9SAndrew Jones	bl	exceptions_init
3839ac3f84SAndrew Jones
3939ac3f84SAndrew Jones	/* complete setup */
4039ac3f84SAndrew Jones	ldp	x0, x1, [sp], #16
4139ac3f84SAndrew Jones	bl	setup
42*62bdc67fSAndrew Jones	bl	get_mmu_off
43*62bdc67fSAndrew Jones	cbnz	x0, 1f
44*62bdc67fSAndrew Jones	bl	setup_vm
4539ac3f84SAndrew Jones
46*62bdc67fSAndrew Jones1:
4739ac3f84SAndrew Jones	/* run the test */
4863ab2d70SPaolo Bonzini	adrp	x0, __argc
4963ab2d70SPaolo Bonzini	ldr	x0, [x0, :lo12:__argc]
5063ab2d70SPaolo Bonzini	adrp	x1, __argv
5163ab2d70SPaolo Bonzini	add	x1, x1, :lo12:__argv
5263ab2d70SPaolo Bonzini	adrp	x2, __environ
5363ab2d70SPaolo Bonzini	add	x2, x2, :lo12:__environ
5439ac3f84SAndrew Jones	bl	main
5539ac3f84SAndrew Jones	bl	exit
5639ac3f84SAndrew Jones	b	halt
5739ac3f84SAndrew Jones
587ee966e9SAndrew Jonesexceptions_init:
5963ab2d70SPaolo Bonzini	adrp	x0, vector_table
6063ab2d70SPaolo Bonzini	add	x0, x0, :lo12:vector_table
617ee966e9SAndrew Jones	msr	vbar_el1, x0
627ee966e9SAndrew Jones	isb
637ee966e9SAndrew Jones	ret
647ee966e9SAndrew Jones
6539ac3f84SAndrew Jones.text
6639ac3f84SAndrew Jones
67*62bdc67fSAndrew Jones.globl get_mmu_off
68*62bdc67fSAndrew Jonesget_mmu_off:
69*62bdc67fSAndrew Jones	adrp	x0, auxinfo
70*62bdc67fSAndrew Jones	ldr	x0, [x0, :lo12:auxinfo + 8]
71*62bdc67fSAndrew Jones	and	x0, x0, #AUXINFO_MMU_OFF
72*62bdc67fSAndrew Jones	ret
73*62bdc67fSAndrew Jones
7468ea0e0bSAndrew Jones.globl secondary_entry
7568ea0e0bSAndrew Jonessecondary_entry:
7668ea0e0bSAndrew Jones	/* Enable FP/ASIMD */
7768ea0e0bSAndrew Jones	mov	x0, #(3 << 20)
7868ea0e0bSAndrew Jones	msr	cpacr_el1, x0
7968ea0e0bSAndrew Jones
8068ea0e0bSAndrew Jones	/* set up exception handling */
8168ea0e0bSAndrew Jones	bl	exceptions_init
8268ea0e0bSAndrew Jones
83*62bdc67fSAndrew Jones	/* enable the MMU unless requested off */
84*62bdc67fSAndrew Jones	bl	get_mmu_off
85*62bdc67fSAndrew Jones	cbnz	x0, 1f
8663ab2d70SPaolo Bonzini	adrp	x0, mmu_idmap
8763ab2d70SPaolo Bonzini	ldr	x0, [x0, :lo12:mmu_idmap]
8868ea0e0bSAndrew Jones	bl	asm_mmu_enable
8968ea0e0bSAndrew Jones
90*62bdc67fSAndrew Jones1:
9168ea0e0bSAndrew Jones	/* set the stack */
9263ab2d70SPaolo Bonzini	adrp	x0, secondary_data
9363ab2d70SPaolo Bonzini	ldr	x0, [x0, :lo12:secondary_data]
9468ea0e0bSAndrew Jones	mov	sp, x0
9568ea0e0bSAndrew Jones
9668ea0e0bSAndrew Jones	/* finish init in C code */
9768ea0e0bSAndrew Jones	bl	secondary_cinit
9868ea0e0bSAndrew Jones
9968ea0e0bSAndrew Jones	/* x0 is now the entry function, run it */
100543ce33cSAndrew Jones	blr	x0
1019246de4cSAndrew Jones	b	do_idle
10268ea0e0bSAndrew Jones
10339ac3f84SAndrew Jones.globl halt
10439ac3f84SAndrew Joneshalt:
10539ac3f84SAndrew Jones1:	wfi
10639ac3f84SAndrew Jones	b	1b
1077ee966e9SAndrew Jones
1087ee966e9SAndrew Jones/*
109db328a24SAndrew Jones * asm_mmu_enable
110db328a24SAndrew Jones *   Inputs:
111db328a24SAndrew Jones *     x0 is the base address of the translation table
112db328a24SAndrew Jones *   Outputs: none
113db328a24SAndrew Jones *
114db328a24SAndrew Jones * Adapted from
115db328a24SAndrew Jones *   arch/arm64/kernel/head.S
116db328a24SAndrew Jones *   arch/arm64/mm/proc.S
117db328a24SAndrew Jones */
118db328a24SAndrew Jones
119db328a24SAndrew Jones/*
120db328a24SAndrew Jones * Memory region attributes for LPAE:
121db328a24SAndrew Jones *
122db328a24SAndrew Jones *   n = AttrIndx[2:0]
123db328a24SAndrew Jones *                      n       MAIR
124db328a24SAndrew Jones *   DEVICE_nGnRnE      000     00000000
125db328a24SAndrew Jones *   DEVICE_nGnRE       001     00000100
126db328a24SAndrew Jones *   DEVICE_GRE         010     00001100
127db328a24SAndrew Jones *   NORMAL_NC          011     01000100
128db328a24SAndrew Jones *   NORMAL             100     11111111
129db328a24SAndrew Jones */
130db328a24SAndrew Jones#define MAIR(attr, mt) ((attr) << ((mt) * 8))
131db328a24SAndrew Jones
132db328a24SAndrew Jones.globl asm_mmu_enable
133db328a24SAndrew Jonesasm_mmu_enable:
134db328a24SAndrew Jones	ic	iallu			// I+BTB cache invalidate
135db328a24SAndrew Jones	tlbi	vmalle1is		// invalidate I + D TLBs
136db328a24SAndrew Jones	dsb	ish
137db328a24SAndrew Jones
138db328a24SAndrew Jones	/* TCR */
139db328a24SAndrew Jones	ldr	x1, =TCR_TxSZ(VA_BITS) |		\
140db328a24SAndrew Jones		     TCR_TG0_64K | TCR_TG1_64K |	\
141db328a24SAndrew Jones		     TCR_IRGN_WBWA | TCR_ORGN_WBWA |	\
142db328a24SAndrew Jones		     TCR_SHARED
143d140ad48SAndrew Jones	mrs	x2, id_aa64mmfr0_el1
144db328a24SAndrew Jones	bfi	x1, x2, #32, #3
145db328a24SAndrew Jones	msr	tcr_el1, x1
146db328a24SAndrew Jones
147db328a24SAndrew Jones	/* MAIR */
148db328a24SAndrew Jones	ldr	x1, =MAIR(0x00, MT_DEVICE_nGnRnE) |	\
149db328a24SAndrew Jones		     MAIR(0x04, MT_DEVICE_nGnRE) |	\
150db328a24SAndrew Jones		     MAIR(0x0c, MT_DEVICE_GRE) |	\
151db328a24SAndrew Jones		     MAIR(0x44, MT_NORMAL_NC) |		\
152db328a24SAndrew Jones		     MAIR(0xff, MT_NORMAL)
153db328a24SAndrew Jones	msr	mair_el1, x1
154db328a24SAndrew Jones
155db328a24SAndrew Jones	/* TTBR0 */
156db328a24SAndrew Jones	msr	ttbr0_el1, x0
157db328a24SAndrew Jones	isb
158db328a24SAndrew Jones
159db328a24SAndrew Jones	/* SCTLR */
160db328a24SAndrew Jones	mrs	x1, sctlr_el1
161db328a24SAndrew Jones	orr	x1, x1, SCTLR_EL1_C
162db328a24SAndrew Jones	orr	x1, x1, SCTLR_EL1_I
163db328a24SAndrew Jones	orr	x1, x1, SCTLR_EL1_M
164db328a24SAndrew Jones	msr	sctlr_el1, x1
165db328a24SAndrew Jones	isb
166db328a24SAndrew Jones
167db328a24SAndrew Jones	ret
168db328a24SAndrew Jones
169e27b176bSAndrew Jones.globl asm_mmu_disable
170e27b176bSAndrew Jonesasm_mmu_disable:
171e27b176bSAndrew Jones	mrs	x0, sctlr_el1
172e27b176bSAndrew Jones	bic	x0, x0, SCTLR_EL1_M
173e27b176bSAndrew Jones	msr	sctlr_el1, x0
174e27b176bSAndrew Jones	isb
175e27b176bSAndrew Jones	ret
176e27b176bSAndrew Jones
177db328a24SAndrew Jones/*
1787ee966e9SAndrew Jones * Vectors
1797ee966e9SAndrew Jones * Adapted from arch/arm64/kernel/entry.S
1807ee966e9SAndrew Jones */
1817ee966e9SAndrew Jones.macro vector_stub, name, vec
1827ee966e9SAndrew Jones\name:
1837ee966e9SAndrew Jones	stp	 x0,  x1, [sp, #-S_FRAME_SIZE]!
1847ee966e9SAndrew Jones	stp	 x2,  x3, [sp,  #16]
1857ee966e9SAndrew Jones	stp	 x4,  x5, [sp,  #32]
1867ee966e9SAndrew Jones	stp	 x6,  x7, [sp,  #48]
1877ee966e9SAndrew Jones	stp	 x8,  x9, [sp,  #64]
1887ee966e9SAndrew Jones	stp	x10, x11, [sp,  #80]
1897ee966e9SAndrew Jones	stp	x12, x13, [sp,  #96]
1907ee966e9SAndrew Jones	stp	x14, x15, [sp, #112]
1917ee966e9SAndrew Jones	stp	x16, x17, [sp, #128]
1927ee966e9SAndrew Jones	stp	x18, x19, [sp, #144]
1937ee966e9SAndrew Jones	stp	x20, x21, [sp, #160]
1947ee966e9SAndrew Jones	stp	x22, x23, [sp, #176]
1957ee966e9SAndrew Jones	stp	x24, x25, [sp, #192]
1967ee966e9SAndrew Jones	stp	x26, x27, [sp, #208]
1977ee966e9SAndrew Jones	stp	x28, x29, [sp, #224]
1987ee966e9SAndrew Jones
1997ee966e9SAndrew Jones	str	x30, [sp, #S_LR]
2007ee966e9SAndrew Jones
2017ee966e9SAndrew Jones	.if \vec >= 8
2027ee966e9SAndrew Jones	mrs	x1, sp_el0
2037ee966e9SAndrew Jones	.else
2047ee966e9SAndrew Jones	add	x1, sp, #S_FRAME_SIZE
2057ee966e9SAndrew Jones	.endif
2067ee966e9SAndrew Jones	str	x1, [sp, #S_SP]
2077ee966e9SAndrew Jones
2087ee966e9SAndrew Jones	mrs	x1, elr_el1
2097ee966e9SAndrew Jones	mrs	x2, spsr_el1
2107ee966e9SAndrew Jones	stp	x1, x2, [sp, #S_PC]
2117ee966e9SAndrew Jones
212f6d10793SAndrew Jones	mov	x0, \vec
2137ee966e9SAndrew Jones	mov	x1, sp
2147ee966e9SAndrew Jones	mrs	x2, esr_el1
2157ee966e9SAndrew Jones	bl	do_handle_exception
2167ee966e9SAndrew Jones
2177ee966e9SAndrew Jones	ldp	x1, x2, [sp, #S_PC]
2187ee966e9SAndrew Jones	msr	spsr_el1, x2
2197ee966e9SAndrew Jones	msr	elr_el1, x1
2207ee966e9SAndrew Jones
2217ee966e9SAndrew Jones	.if \vec >= 8
2227ee966e9SAndrew Jones	ldr	x1, [sp, #S_SP]
2237ee966e9SAndrew Jones	msr	sp_el0, x1
2247ee966e9SAndrew Jones	.endif
2257ee966e9SAndrew Jones
2267ee966e9SAndrew Jones	ldr	x30, [sp, #S_LR]
2277ee966e9SAndrew Jones
2287ee966e9SAndrew Jones	ldp	x28, x29, [sp, #224]
2297ee966e9SAndrew Jones	ldp	x26, x27, [sp, #208]
2307ee966e9SAndrew Jones	ldp	x24, x25, [sp, #192]
2317ee966e9SAndrew Jones	ldp	x22, x23, [sp, #176]
2327ee966e9SAndrew Jones	ldp	x20, x21, [sp, #160]
2337ee966e9SAndrew Jones	ldp	x18, x19, [sp, #144]
2347ee966e9SAndrew Jones	ldp	x16, x17, [sp, #128]
2357ee966e9SAndrew Jones	ldp	x14, x15, [sp, #112]
2367ee966e9SAndrew Jones	ldp	x12, x13, [sp,  #96]
2377ee966e9SAndrew Jones	ldp	x10, x11, [sp,  #80]
2387ee966e9SAndrew Jones	ldp	 x8,  x9, [sp,  #64]
2397ee966e9SAndrew Jones	ldp	 x6,  x7, [sp,  #48]
2407ee966e9SAndrew Jones	ldp	 x4,  x5, [sp,  #32]
2417ee966e9SAndrew Jones	ldp	 x2,  x3, [sp,  #16]
2427ee966e9SAndrew Jones	ldp	 x0,  x1, [sp], #S_FRAME_SIZE
2437ee966e9SAndrew Jones
2447ee966e9SAndrew Jones	eret
2457ee966e9SAndrew Jones.endm
2467ee966e9SAndrew Jones
2477ee966e9SAndrew Jonesvector_stub	el1t_sync,     0
2487ee966e9SAndrew Jonesvector_stub	el1t_irq,      1
2497ee966e9SAndrew Jonesvector_stub	el1t_fiq,      2
2507ee966e9SAndrew Jonesvector_stub	el1t_error,    3
2517ee966e9SAndrew Jones
2527ee966e9SAndrew Jonesvector_stub	el1h_sync,     4
2537ee966e9SAndrew Jonesvector_stub	el1h_irq,      5
2547ee966e9SAndrew Jonesvector_stub	el1h_fiq,      6
2557ee966e9SAndrew Jonesvector_stub	el1h_error,    7
2567ee966e9SAndrew Jones
2577ee966e9SAndrew Jonesvector_stub	el0_sync_64,   8
2587ee966e9SAndrew Jonesvector_stub	el0_irq_64,    9
2597ee966e9SAndrew Jonesvector_stub	el0_fiq_64,   10
2607ee966e9SAndrew Jonesvector_stub	el0_error_64, 11
2617ee966e9SAndrew Jones
2627ee966e9SAndrew Jonesvector_stub	el0_sync_32,  12
2637ee966e9SAndrew Jonesvector_stub	el0_irq_32,   13
2647ee966e9SAndrew Jonesvector_stub	el0_fiq_32,   14
2657ee966e9SAndrew Jonesvector_stub	el0_error_32, 15
2667ee966e9SAndrew Jones
2677ee966e9SAndrew Jones.section .text.ex
2687ee966e9SAndrew Jones
2697ee966e9SAndrew Jones.macro ventry, label
2707ee966e9SAndrew Jones.align 7
2717ee966e9SAndrew Jones	b	\label
2727ee966e9SAndrew Jones.endm
2737ee966e9SAndrew Jones
2747ee966e9SAndrew Jones.align 11
2757ee966e9SAndrew Jonesvector_table:
2767ee966e9SAndrew Jones	ventry	el1t_sync			// Synchronous EL1t
2777ee966e9SAndrew Jones	ventry	el1t_irq			// IRQ EL1t
2787ee966e9SAndrew Jones	ventry	el1t_fiq			// FIQ EL1t
2797ee966e9SAndrew Jones	ventry	el1t_error			// Error EL1t
2807ee966e9SAndrew Jones
2817ee966e9SAndrew Jones	ventry	el1h_sync			// Synchronous EL1h
2827ee966e9SAndrew Jones	ventry	el1h_irq			// IRQ EL1h
2837ee966e9SAndrew Jones	ventry	el1h_fiq			// FIQ EL1h
2847ee966e9SAndrew Jones	ventry	el1h_error			// Error EL1h
2857ee966e9SAndrew Jones
2867ee966e9SAndrew Jones	ventry	el0_sync_64			// Synchronous 64-bit EL0
2877ee966e9SAndrew Jones	ventry	el0_irq_64			// IRQ 64-bit EL0
2887ee966e9SAndrew Jones	ventry	el0_fiq_64			// FIQ 64-bit EL0
2897ee966e9SAndrew Jones	ventry	el0_error_64			// Error 64-bit EL0
2907ee966e9SAndrew Jones
2917ee966e9SAndrew Jones	ventry	el0_sync_32			// Synchronous 32-bit EL0
2927ee966e9SAndrew Jones	ventry	el0_irq_32			// IRQ 32-bit EL0
2937ee966e9SAndrew Jones	ventry	el0_fiq_32			// FIQ 32-bit EL0
2947ee966e9SAndrew Jones	ventry	el0_error_32			// Error 32-bit EL0
295