xref: /kvm-unit-tests/arm/cstart64.S (revision d140ad48e20a9829aee0ff89c1d44696b32464c1)
139ac3f84SAndrew Jones/*
239ac3f84SAndrew Jones * Boot entry point and assembler functions for aarch64 tests.
339ac3f84SAndrew Jones *
439ac3f84SAndrew Jones * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
539ac3f84SAndrew Jones *
639ac3f84SAndrew Jones * This work is licensed under the terms of the GNU LGPL, version 2.
739ac3f84SAndrew Jones */
839ac3f84SAndrew Jones#define __ASSEMBLY__
939ac3f84SAndrew Jones#include <asm/asm-offsets.h>
107ee966e9SAndrew Jones#include <asm/ptrace.h>
11db328a24SAndrew Jones#include <asm/processor.h>
12db328a24SAndrew Jones#include <asm/page.h>
13db328a24SAndrew Jones#include <asm/pgtable-hwdef.h>
1439ac3f84SAndrew Jones
1539ac3f84SAndrew Jones.section .init
1639ac3f84SAndrew Jones
1739ac3f84SAndrew Jones.globl start
1839ac3f84SAndrew Jonesstart:
1939ac3f84SAndrew Jones	/*
2039ac3f84SAndrew Jones	 * bootloader params are in x0-x3
2139ac3f84SAndrew Jones	 * The physical address of the dtb is in x0, x1-x3 are reserved
2239ac3f84SAndrew Jones	 * See the kernel doc Documentation/arm64/booting.txt
2339ac3f84SAndrew Jones	 */
2439ac3f84SAndrew Jones	adr     x4, stacktop
2539ac3f84SAndrew Jones	mov	sp, x4
2639ac3f84SAndrew Jones	stp	x0, x1, [sp, #-16]!
2739ac3f84SAndrew Jones
2839ac3f84SAndrew Jones	/* Enable FP/ASIMD */
2939ac3f84SAndrew Jones	mov	x0, #(3 << 20)
3039ac3f84SAndrew Jones	msr	cpacr_el1, x0
3139ac3f84SAndrew Jones
3239ac3f84SAndrew Jones	/* set up exception handling */
337ee966e9SAndrew Jones	bl	exceptions_init
3439ac3f84SAndrew Jones
3539ac3f84SAndrew Jones	/* complete setup */
3639ac3f84SAndrew Jones	ldp	x0, x1, [sp], #16
3739ac3f84SAndrew Jones	bl	setup
3839ac3f84SAndrew Jones
3939ac3f84SAndrew Jones	/* run the test */
4039ac3f84SAndrew Jones	adr	x0, __argc
4139ac3f84SAndrew Jones	ldr	x0, [x0]
4239ac3f84SAndrew Jones	adr	x1, __argv
4339ac3f84SAndrew Jones	bl	main
4439ac3f84SAndrew Jones	bl	exit
4539ac3f84SAndrew Jones	b	halt
4639ac3f84SAndrew Jones
477ee966e9SAndrew Jonesexceptions_init:
487ee966e9SAndrew Jones	adr	x0, vector_table
497ee966e9SAndrew Jones	msr	vbar_el1, x0
507ee966e9SAndrew Jones	isb
517ee966e9SAndrew Jones	ret
527ee966e9SAndrew Jones
5339ac3f84SAndrew Jones.text
5439ac3f84SAndrew Jones
5539ac3f84SAndrew Jones.globl halt
5639ac3f84SAndrew Joneshalt:
5739ac3f84SAndrew Jones1:	wfi
5839ac3f84SAndrew Jones	b	1b
597ee966e9SAndrew Jones
607ee966e9SAndrew Jones/*
61db328a24SAndrew Jones * asm_mmu_enable
62db328a24SAndrew Jones *   Inputs:
63db328a24SAndrew Jones *     x0 is the base address of the translation table
64db328a24SAndrew Jones *   Outputs: none
65db328a24SAndrew Jones *
66db328a24SAndrew Jones * Adapted from
67db328a24SAndrew Jones *   arch/arm64/kernel/head.S
68db328a24SAndrew Jones *   arch/arm64/mm/proc.S
69db328a24SAndrew Jones */
70db328a24SAndrew Jones
71db328a24SAndrew Jones/*
72db328a24SAndrew Jones * Memory region attributes for LPAE:
73db328a24SAndrew Jones *
74db328a24SAndrew Jones *   n = AttrIndx[2:0]
75db328a24SAndrew Jones *                      n       MAIR
76db328a24SAndrew Jones *   DEVICE_nGnRnE      000     00000000
77db328a24SAndrew Jones *   DEVICE_nGnRE       001     00000100
78db328a24SAndrew Jones *   DEVICE_GRE         010     00001100
79db328a24SAndrew Jones *   NORMAL_NC          011     01000100
80db328a24SAndrew Jones *   NORMAL             100     11111111
81db328a24SAndrew Jones */
82db328a24SAndrew Jones#define MAIR(attr, mt) ((attr) << ((mt) * 8))
83db328a24SAndrew Jones
84db328a24SAndrew Jones.globl asm_mmu_enable
85db328a24SAndrew Jonesasm_mmu_enable:
86db328a24SAndrew Jones	ic	iallu			// I+BTB cache invalidate
87db328a24SAndrew Jones	tlbi	vmalle1is		// invalidate I + D TLBs
88db328a24SAndrew Jones	dsb	ish
89db328a24SAndrew Jones
90db328a24SAndrew Jones	/* TCR */
91db328a24SAndrew Jones	ldr	x1, =TCR_TxSZ(VA_BITS) |		\
92db328a24SAndrew Jones		     TCR_TG0_64K | TCR_TG1_64K |	\
93db328a24SAndrew Jones		     TCR_IRGN_WBWA | TCR_ORGN_WBWA |	\
94db328a24SAndrew Jones		     TCR_SHARED
95*d140ad48SAndrew Jones	mrs	x2, id_aa64mmfr0_el1
96db328a24SAndrew Jones	bfi	x1, x2, #32, #3
97db328a24SAndrew Jones	msr	tcr_el1, x1
98db328a24SAndrew Jones
99db328a24SAndrew Jones	/* MAIR */
100db328a24SAndrew Jones	ldr	x1, =MAIR(0x00, MT_DEVICE_nGnRnE) |	\
101db328a24SAndrew Jones		     MAIR(0x04, MT_DEVICE_nGnRE) |	\
102db328a24SAndrew Jones		     MAIR(0x0c, MT_DEVICE_GRE) |	\
103db328a24SAndrew Jones		     MAIR(0x44, MT_NORMAL_NC) |		\
104db328a24SAndrew Jones		     MAIR(0xff, MT_NORMAL)
105db328a24SAndrew Jones	msr	mair_el1, x1
106db328a24SAndrew Jones
107db328a24SAndrew Jones	/* TTBR0 */
108db328a24SAndrew Jones	msr	ttbr0_el1, x0
109db328a24SAndrew Jones	isb
110db328a24SAndrew Jones
111db328a24SAndrew Jones	/* SCTLR */
112db328a24SAndrew Jones	mrs	x1, sctlr_el1
113db328a24SAndrew Jones	orr	x1, x1, SCTLR_EL1_C
114db328a24SAndrew Jones	orr	x1, x1, SCTLR_EL1_I
115db328a24SAndrew Jones	orr	x1, x1, SCTLR_EL1_M
116db328a24SAndrew Jones	msr	sctlr_el1, x1
117db328a24SAndrew Jones	isb
118db328a24SAndrew Jones
119db328a24SAndrew Jones	ret
120db328a24SAndrew Jones
121db328a24SAndrew Jones/*
1227ee966e9SAndrew Jones * Vectors
1237ee966e9SAndrew Jones * Adapted from arch/arm64/kernel/entry.S
1247ee966e9SAndrew Jones */
1257ee966e9SAndrew Jones.macro vector_stub, name, vec
1267ee966e9SAndrew Jones\name:
1277ee966e9SAndrew Jones	stp	 x0,  x1, [sp, #-S_FRAME_SIZE]!
1287ee966e9SAndrew Jones	stp	 x2,  x3, [sp,  #16]
1297ee966e9SAndrew Jones	stp	 x4,  x5, [sp,  #32]
1307ee966e9SAndrew Jones	stp	 x6,  x7, [sp,  #48]
1317ee966e9SAndrew Jones	stp	 x8,  x9, [sp,  #64]
1327ee966e9SAndrew Jones	stp	x10, x11, [sp,  #80]
1337ee966e9SAndrew Jones	stp	x12, x13, [sp,  #96]
1347ee966e9SAndrew Jones	stp	x14, x15, [sp, #112]
1357ee966e9SAndrew Jones	stp	x16, x17, [sp, #128]
1367ee966e9SAndrew Jones	stp	x18, x19, [sp, #144]
1377ee966e9SAndrew Jones	stp	x20, x21, [sp, #160]
1387ee966e9SAndrew Jones	stp	x22, x23, [sp, #176]
1397ee966e9SAndrew Jones	stp	x24, x25, [sp, #192]
1407ee966e9SAndrew Jones	stp	x26, x27, [sp, #208]
1417ee966e9SAndrew Jones	stp	x28, x29, [sp, #224]
1427ee966e9SAndrew Jones
1437ee966e9SAndrew Jones	str	x30, [sp, #S_LR]
1447ee966e9SAndrew Jones
1457ee966e9SAndrew Jones	.if \vec >= 8
1467ee966e9SAndrew Jones	mrs	x1, sp_el0
1477ee966e9SAndrew Jones	.else
1487ee966e9SAndrew Jones	add	x1, sp, #S_FRAME_SIZE
1497ee966e9SAndrew Jones	.endif
1507ee966e9SAndrew Jones	str	x1, [sp, #S_SP]
1517ee966e9SAndrew Jones
1527ee966e9SAndrew Jones	mrs	x1, elr_el1
1537ee966e9SAndrew Jones	mrs	x2, spsr_el1
1547ee966e9SAndrew Jones	stp	x1, x2, [sp, #S_PC]
1557ee966e9SAndrew Jones
1567ee966e9SAndrew Jones	and	x2, x2, #PSR_MODE_MASK
1577ee966e9SAndrew Jones	cmp	x2, #PSR_MODE_EL0t
1587ee966e9SAndrew Jones	b.ne	1f
1597ee966e9SAndrew Jones	adr	x2, user_mode
1607ee966e9SAndrew Jones	str	xzr, [x2]		/* we're in kernel mode now */
1617ee966e9SAndrew Jones
1627ee966e9SAndrew Jones1:	mov	x0, \vec
1637ee966e9SAndrew Jones	mov	x1, sp
1647ee966e9SAndrew Jones	mrs	x2, esr_el1
1657ee966e9SAndrew Jones	bl	do_handle_exception
1667ee966e9SAndrew Jones
1677ee966e9SAndrew Jones	ldp	x1, x2, [sp, #S_PC]
1687ee966e9SAndrew Jones	msr	spsr_el1, x2
1697ee966e9SAndrew Jones	msr	elr_el1, x1
1707ee966e9SAndrew Jones
1717ee966e9SAndrew Jones	and	x2, x2, #PSR_MODE_MASK
1727ee966e9SAndrew Jones	cmp	x2, #PSR_MODE_EL0t
1737ee966e9SAndrew Jones	b.ne	1f
1747ee966e9SAndrew Jones	adr	x2, user_mode
1757ee966e9SAndrew Jones	mov	x1, #1
1767ee966e9SAndrew Jones	str	x1, [x2]		/* we're going back to user mode */
1777ee966e9SAndrew Jones
1787ee966e9SAndrew Jones1:
1797ee966e9SAndrew Jones	.if \vec >= 8
1807ee966e9SAndrew Jones	ldr	x1, [sp, #S_SP]
1817ee966e9SAndrew Jones	msr	sp_el0, x1
1827ee966e9SAndrew Jones	.endif
1837ee966e9SAndrew Jones
1847ee966e9SAndrew Jones	ldr	x30, [sp, #S_LR]
1857ee966e9SAndrew Jones
1867ee966e9SAndrew Jones	ldp	x28, x29, [sp, #224]
1877ee966e9SAndrew Jones	ldp	x26, x27, [sp, #208]
1887ee966e9SAndrew Jones	ldp	x24, x25, [sp, #192]
1897ee966e9SAndrew Jones	ldp	x22, x23, [sp, #176]
1907ee966e9SAndrew Jones	ldp	x20, x21, [sp, #160]
1917ee966e9SAndrew Jones	ldp	x18, x19, [sp, #144]
1927ee966e9SAndrew Jones	ldp	x16, x17, [sp, #128]
1937ee966e9SAndrew Jones	ldp	x14, x15, [sp, #112]
1947ee966e9SAndrew Jones	ldp	x12, x13, [sp,  #96]
1957ee966e9SAndrew Jones	ldp	x10, x11, [sp,  #80]
1967ee966e9SAndrew Jones	ldp	 x8,  x9, [sp,  #64]
1977ee966e9SAndrew Jones	ldp	 x6,  x7, [sp,  #48]
1987ee966e9SAndrew Jones	ldp	 x4,  x5, [sp,  #32]
1997ee966e9SAndrew Jones	ldp	 x2,  x3, [sp,  #16]
2007ee966e9SAndrew Jones	ldp	 x0,  x1, [sp], #S_FRAME_SIZE
2017ee966e9SAndrew Jones
2027ee966e9SAndrew Jones	eret
2037ee966e9SAndrew Jones.endm
2047ee966e9SAndrew Jones
2057ee966e9SAndrew Jonesvector_stub	el1t_sync,     0
2067ee966e9SAndrew Jonesvector_stub	el1t_irq,      1
2077ee966e9SAndrew Jonesvector_stub	el1t_fiq,      2
2087ee966e9SAndrew Jonesvector_stub	el1t_error,    3
2097ee966e9SAndrew Jones
2107ee966e9SAndrew Jonesvector_stub	el1h_sync,     4
2117ee966e9SAndrew Jonesvector_stub	el1h_irq,      5
2127ee966e9SAndrew Jonesvector_stub	el1h_fiq,      6
2137ee966e9SAndrew Jonesvector_stub	el1h_error,    7
2147ee966e9SAndrew Jones
2157ee966e9SAndrew Jonesvector_stub	el0_sync_64,   8
2167ee966e9SAndrew Jonesvector_stub	el0_irq_64,    9
2177ee966e9SAndrew Jonesvector_stub	el0_fiq_64,   10
2187ee966e9SAndrew Jonesvector_stub	el0_error_64, 11
2197ee966e9SAndrew Jones
2207ee966e9SAndrew Jonesvector_stub	el0_sync_32,  12
2217ee966e9SAndrew Jonesvector_stub	el0_irq_32,   13
2227ee966e9SAndrew Jonesvector_stub	el0_fiq_32,   14
2237ee966e9SAndrew Jonesvector_stub	el0_error_32, 15
2247ee966e9SAndrew Jones
2257ee966e9SAndrew Jones.section .text.ex
2267ee966e9SAndrew Jones
2277ee966e9SAndrew Jones.macro ventry, label
2287ee966e9SAndrew Jones.align 7
2297ee966e9SAndrew Jones	b	\label
2307ee966e9SAndrew Jones.endm
2317ee966e9SAndrew Jones
2327ee966e9SAndrew Jones.align 11
2337ee966e9SAndrew Jonesvector_table:
2347ee966e9SAndrew Jones	ventry	el1t_sync			// Synchronous EL1t
2357ee966e9SAndrew Jones	ventry	el1t_irq			// IRQ EL1t
2367ee966e9SAndrew Jones	ventry	el1t_fiq			// FIQ EL1t
2377ee966e9SAndrew Jones	ventry	el1t_error			// Error EL1t
2387ee966e9SAndrew Jones
2397ee966e9SAndrew Jones	ventry	el1h_sync			// Synchronous EL1h
2407ee966e9SAndrew Jones	ventry	el1h_irq			// IRQ EL1h
2417ee966e9SAndrew Jones	ventry	el1h_fiq			// FIQ EL1h
2427ee966e9SAndrew Jones	ventry	el1h_error			// Error EL1h
2437ee966e9SAndrew Jones
2447ee966e9SAndrew Jones	ventry	el0_sync_64			// Synchronous 64-bit EL0
2457ee966e9SAndrew Jones	ventry	el0_irq_64			// IRQ 64-bit EL0
2467ee966e9SAndrew Jones	ventry	el0_fiq_64			// FIQ 64-bit EL0
2477ee966e9SAndrew Jones	ventry	el0_error_64			// Error 64-bit EL0
2487ee966e9SAndrew Jones
2497ee966e9SAndrew Jones	ventry	el0_sync_32			// Synchronous 32-bit EL0
2507ee966e9SAndrew Jones	ventry	el0_irq_32			// IRQ 32-bit EL0
2517ee966e9SAndrew Jones	ventry	el0_fiq_32			// FIQ 32-bit EL0
2527ee966e9SAndrew Jones	ventry	el0_error_32			// Error 32-bit EL0
253