xref: /kvm-unit-tests/riscv/cstart.S (revision 22f287f4024419702c8024174139d1b46d12f2be)
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Boot entry point and assembler functions for riscv.
4 *
5 * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
6 */
7#include <asm/csr.h>
8
9.macro zero_range, tmp1, tmp2
109998:	beq	\tmp1, \tmp2, 9997f
11	sd	zero, 0(\tmp1)
12	addi	\tmp1, \tmp1, 8
13	j	9998b
149997:
15.endm
16
17	.section .init
18
19/*
20 * The hartid of the current core is in a0
21 * The address of the devicetree is in a1
22 *
23 * See Linux kernel doc Documentation/riscv/boot.rst
24 */
25.global start
26start:
27	/*
28	 * Stash the hartid in scratch and shift the dtb
29	 * address into a0
30	 */
31	csrw	CSR_SSCRATCH, a0
32	mv	a0, a1
33
34	/*
35	 * Update all R_RISCV_RELATIVE relocations using the table
36	 * of Elf64_Rela entries between reloc_start/end. The build
37	 * will not emit other relocation types.
38	 *
39	 * struct Elf64_Rela {
40	 * 	uint64_t r_offset;
41	 * 	uint64_t r_info;
42	 * 	int64_t  r_addend;
43	 * }
44	 */
45	la	a1, reloc_start
46	la	a2, reloc_end
47	la	a3, start			// base
481:
49	bge	a1, a2, 1f
50	ld	a4, 0(a1)			// r_offset
51	ld	a5, 16(a1)			// r_addend
52	add	a4, a3, a4			// addr = base + r_offset
53	add	a5, a3, a5			// val = base + r_addend
54	sd	a5, 0(a4)			// *addr = val
55	addi	a1, a1, 24
56	j	1b
57
581:
59	/* zero BSS */
60	la	a1, bss
61	la	a2, ebss
62	zero_range a1, a2
63
64	/* zero and set up stack */
65	la	sp, stacktop
66	li	a1, -8192
67	add	a1, sp, a1
68	zero_range a1, sp
69
70	/* set up exception handling */
71	//TODO
72
73	/* complete setup */
74	la	a1, stacktop			// a1 is the base of free memory
75	call	setup				// a0 is the addr of the dtb
76
77	/* run the test */
78	la	a0, __argc
79	ld	a0, 0(a0)
80	la	a1, __argv
81	la	a2, __environ
82	call	main
83	call	exit
84	j	halt
85
86	.text
87
88.balign 4
89.global halt
90halt:
911:	wfi
92	j	1b
93