xref: /freebsd/sys/riscv/riscv/locore.S (revision 0957b409)
1/*-
2 * Copyright (c) 2015-2018 Ruslan Bukin <br@bsdpad.com>
3 * All rights reserved.
4 *
5 * Portions of this software were developed by SRI International and the
6 * University of Cambridge Computer Laboratory under DARPA/AFRL contract
7 * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
8 *
9 * Portions of this software were developed by the University of Cambridge
10 * Computer Laboratory as part of the CTSRD Project, with support from the
11 * UK Higher Education Innovation Fund (HEIF).
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * $FreeBSD$
35 */
36
37#include "assym.inc"
38
39#include <sys/syscall.h>
40#include <machine/asm.h>
41#include <machine/param.h>
42#include <machine/trap.h>
43#include <machine/riscvreg.h>
44#include <machine/pte.h>
45
46	.globl	kernbase
47	.set	kernbase, KERNBASE
48
49	/* Trap entries */
50	.text
51
52	/* Reset vector */
53	.text
54	.globl _start
55_start:
56	/* Get the physical address kernel loaded to */
57	la	t0, virt_map
58	ld	t1, 0(t0)
59	sub	t1, t1, t0
60	li	t2, KERNBASE
61	sub	s9, t2, t1	/* s9 = physmem base */
62	mv	s10, a0		/* s10 = hart id */
63	mv	s11, a1		/* s11 = dtbp */
64
65	/* Direct secondary cores to mpentry */
66	bnez	s10, mpentry
67
68	/*
69	 * Page tables
70	 */
71
72	/* Add L1 entry for kernel */
73	la	s1, pagetable_l1
74	la	s2, pagetable_l2	/* Link to next level PN */
75	srli	s2, s2, PAGE_SHIFT
76
77	li	a5, KERNBASE
78	srli	a5, a5, L1_SHIFT	/* >> L1_SHIFT */
79	andi	a5, a5, 0x1ff		/* & 0x1ff */
80	li	t4, PTE_V
81	slli	t5, s2, PTE_PPN0_S	/* (s2 << PTE_PPN0_S) */
82	or	t6, t4, t5
83
84	/* Store L1 PTE entry to position */
85	li	a6, PTE_SIZE
86	mulw	a5, a5, a6
87	add	t0, s1, a5
88	sd	t6, (t0)
89
90	/* Level 2 superpages (512 x 2MiB) */
91	la	s1, pagetable_l2
92	srli	t4, s9, 21		/* Div physmem base by 2 MiB */
93	li	t2, 512			/* Build 512 entries */
94	add	t3, t4, t2
95	li	t5, 0
962:
97	li	t0, (PTE_KERN | PTE_X)
98	slli	t2, t4, PTE_PPN1_S	/* << PTE_PPN1_S */
99	or	t5, t0, t2
100	sd	t5, (s1)		/* Store PTE entry to position */
101	addi	s1, s1, PTE_SIZE
102
103	addi	t4, t4, 1
104	bltu	t4, t3, 2b
105
106	/* Create an L1 page for early devmap */
107	la	s1, pagetable_l1
108	la	s2, pagetable_l2_devmap	/* Link to next level PN */
109	srli	s2, s2, PAGE_SHIFT
110
111	li	a5, (VM_MAX_KERNEL_ADDRESS - L2_SIZE)
112	srli	a5, a5, L1_SHIFT	/* >> L1_SHIFT */
113	andi	a5, a5, 0x1ff		/* & 0x1ff */
114	li	t4, PTE_V
115	slli	t5, s2, PTE_PPN0_S	/* (s2 << PTE_PPN0_S) */
116	or	t6, t4, t5
117
118	/* Store single level1 PTE entry to position */
119	li	a6, PTE_SIZE
120	mulw	a5, a5, a6
121	add	t0, s1, a5
122	sd	t6, (t0)
123
124	/* Create an L2 page superpage for DTB */
125	la	s1, pagetable_l2_devmap
126	mv	s2, s11
127	srli	s2, s2, PAGE_SHIFT
128
129	li	t0, (PTE_KERN)
130	slli	t2, s2, PTE_PPN0_S	/* << PTE_PPN0_S */
131	or	t0, t0, t2
132
133	/* Store PTE entry to position */
134	li	a6, PTE_SIZE
135	li	a5, 510
136	mulw	a5, a5, a6
137	add	t1, s1, a5
138	sd	t0, (t1)
139
140	/* Page tables END */
141
142	/* Setup supervisor trap vector */
143	la	t0, va
144	sub	t0, t0, s9
145	li	t1, KERNBASE
146	add	t0, t0, t1
147	csrw	stvec, t0
148
149	/* Set page tables base register */
150	la	s2, pagetable_l1
151	srli	s2, s2, PAGE_SHIFT
152	li	t0, SATP_MODE_SV39
153	or	s2, s2, t0
154	sfence.vma
155	csrw	satp, s2
156
157	.align 2
158va:
159
160	/* Setup supervisor trap vector */
161	la	t0, cpu_exception_handler
162	csrw	stvec, t0
163
164	/* Ensure sscratch is zero */
165	li	t0, 0
166	csrw	sscratch, t0
167
168	/* Initialize stack pointer */
169	la	s3, initstack_end
170	mv	sp, s3
171	addi	sp, sp, -PCB_SIZE
172
173	/* Clear BSS  */
174	la	a0, _C_LABEL(__bss_start)
175	la	s1, _C_LABEL(_end)
1761:
177	sd	zero, 0(a0)
178	addi	a0, a0, 8
179	bltu	a0, s1, 1b
180
181	/* Fill riscv_bootparams */
182	addi	sp, sp, -40
183
184	la	t0, pagetable_l1
185	sd	t0, 0(sp) /* kern_l1pt */
186	sd	s9, 8(sp) /* kern_phys */
187
188	la	t0, initstack_end
189	sd	t0, 16(sp) /* kern_stack */
190
191	li	t0, (VM_MAX_KERNEL_ADDRESS - 2 * L2_SIZE)
192	sd	t0, 24(sp) /* dtbp_virt */
193	sd	s11, 32(sp) /* dtbp_phys */
194
195	mv	a0, sp
196	call	_C_LABEL(initriscv)	/* Off we go */
197	call	_C_LABEL(mi_startup)
198
199	.align  4
200initstack:
201	.space  (PAGE_SIZE * KSTACK_PAGES)
202initstack_end:
203
204ENTRY(sigcode)
205	mv	a0, sp
206	addi	a0, a0, SF_UC
207
2081:
209	li	t0, SYS_sigreturn
210	ecall
211
212	/* sigreturn failed, exit */
213	li	t0, SYS_exit
214	ecall
215
216	j	1b
217END(sigcode)
218	/* This may be copied to the stack, keep it 16-byte aligned */
219	.align	3
220esigcode:
221
222	.data
223	.align	3
224	.global	szsigcode
225szsigcode:
226	.quad	esigcode - sigcode
227
228	.align	12
229pagetable_l1:
230	.space	PAGE_SIZE
231pagetable_l2:
232	.space	PAGE_SIZE
233pagetable_l2_devmap:
234	.space	PAGE_SIZE
235
236        .align 3
237virt_map:
238        .quad   virt_map
239
240	/* Not in use, but required for linking. */
241	.align 3
242	.globl __global_pointer$
243__global_pointer$:
244	.space	8
245
246	.globl init_pt_va
247init_pt_va:
248	.quad pagetable_l2	/* XXX: Keep page tables VA */
249
250#ifndef SMP
251ENTRY(mpentry)
2521:
253	wfi
254	j	1b
255END(mpentry)
256#else
257/*
258 * mpentry(unsigned long)
259 *
260 * Called by a core when it is being brought online.
261 */
262ENTRY(mpentry)
263	/*
264	 * Calculate the offset to __riscv_boot_ap
265	 * for the current core, cpuid is in a0.
266	 */
267	li	t1, 4
268	mulw	t1, t1, a0
269	/* Get the pointer */
270	la	t0, __riscv_boot_ap
271	add	t0, t0, t1
272
2731:
274	/* Wait the kernel to be ready */
275	lw	t1, 0(t0)
276	beqz	t1, 1b
277
278	/* Setup stack pointer */
279	la	t0, secondary_stacks
280	li	t1, (PAGE_SIZE * KSTACK_PAGES)
281	mulw	t1, t1, s10
282	add	t0, t0, t1
283	sub	t0, t0, s9
284	li	t1, KERNBASE
285	add	sp, t0, t1
286
287	/* Setup supervisor trap vector */
288	la	t0, mpva
289	sub	t0, t0, s9
290	li	t1, KERNBASE
291	add	t0, t0, t1
292	csrw	stvec, t0
293
294	/* Set page tables base register */
295	la	s2, pagetable_l1
296	srli	s2, s2, PAGE_SHIFT
297	li	t0, SATP_MODE_SV39
298	or	s2, s2, t0
299	sfence.vma
300	csrw	satp, s2
301
302	.align 2
303mpva:
304	/* Setup supervisor trap vector */
305	la	t0, cpu_exception_handler
306	csrw	stvec, t0
307
308	/* Ensure sscratch is zero */
309	li	t0, 0
310	csrw	sscratch, t0
311
312	call	init_secondary
313END(mpentry)
314#endif
315