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 /*
57 * a0 = hart id
58 * a1 = dtbp
59 */
60
61 /* Pick a hart to run the boot process. */
62 lla t0, hart_lottery
63 li t1, 1
64 amoadd.w t0, t1, 0(t0)
65
66 /*
67 * We must jump to mpentry in the non-BSP case because the offset is
68 * too large to fit in a 12-bit branch immediate.
69 */
70 beqz t0, 1f
71 j mpentry
72
73 /*
74 * Page tables
75 */
76 1:
77 /* Get the kernel's load address */
78 jal get_physmem
79
80 /* Add L1 entry for kernel */
81 lla s1, pagetable_l1
82 lla s2, pagetable_l2 /* Link to next level PN */
83 srli s2, s2, PAGE_SHIFT
84
85 li a5, KERNBASE
86 srli a5, a5, L1_SHIFT /* >> L1_SHIFT */
87 andi a5, a5, 0x1ff /* & 0x1ff */
88 li t4, PTE_V
89 slli t5, s2, PTE_PPN0_S /* (s2 << PTE_PPN0_S) */
90 or t6, t4, t5
91
92 /* Store L1 PTE entry to position */
93 li a6, PTE_SIZE
94 mulw a5, a5, a6
95 add t0, s1, a5
96 sd t6, (t0)
97
98 /* Level 2 superpages (512 x 2MiB) */
99 lla s1, pagetable_l2
100 srli t4, s9, 21 /* Div physmem base by 2 MiB */
101 li t2, 512 /* Build 512 entries */
102 add t3, t4, t2
103 li t5, 0
104 2:
105 li t0, (PTE_KERN | PTE_X)
106 slli t2, t4, PTE_PPN1_S /* << PTE_PPN1_S */
107 or t5, t0, t2
108 sd t5, (s1) /* Store PTE entry to position */
109 addi s1, s1, PTE_SIZE
110
111 addi t4, t4, 1
112 bltu t4, t3, 2b
113
114 /* Create an L1 page for early devmap */
115 lla s1, pagetable_l1
116 lla s2, pagetable_l2_devmap /* Link to next level PN */
117 srli s2, s2, PAGE_SHIFT
118
119 li a5, (VM_MAX_KERNEL_ADDRESS - L2_SIZE)
120 srli a5, a5, L1_SHIFT /* >> L1_SHIFT */
121 andi a5, a5, 0x1ff /* & 0x1ff */
122 li t4, PTE_V
123 slli t5, s2, PTE_PPN0_S /* (s2 << PTE_PPN0_S) */
124 or t6, t4, t5
125
126 /* Store single level1 PTE entry to position */
127 li a6, PTE_SIZE
128 mulw a5, a5, a6
129 add t0, s1, a5
130 sd t6, (t0)
131
132 /* Create an L2 page superpage for DTB */
133 lla s1, pagetable_l2_devmap
134 mv s2, a1
135 srli s2, s2, PAGE_SHIFT
136
137 li t0, (PTE_KERN)
138 slli t2, s2, PTE_PPN0_S /* << PTE_PPN0_S */
139 or t0, t0, t2
140
141 /* Store PTE entry to position */
142 li a6, PTE_SIZE
143 li a5, 510
144 mulw a5, a5, a6
145 add t1, s1, a5
146 sd t0, (t1)
147
148 /* Page tables END */
149
150 /* Setup supervisor trap vector */
151 lla t0, va
152 sub t0, t0, s9
153 li t1, KERNBASE
154 add t0, t0, t1
155 csrw stvec, t0
156
157 /* Set page tables base register */
158 lla s2, pagetable_l1
159 srli s2, s2, PAGE_SHIFT
160 li t0, SATP_MODE_SV39
161 or s2, s2, t0
162 sfence.vma
163 csrw satp, s2
164
165 .align 2
166 va:
167
168 /* Setup supervisor trap vector */
169 la t0, cpu_exception_handler
170 csrw stvec, t0
171
172 /* Ensure sscratch is zero */
173 li t0, 0
174 csrw sscratch, t0
175
176 /* Set the global pointer */
177 .option push
178 .option norelax
179 la gp, __global_pointer$
180 .option pop
181
182 /* Initialize stack pointer */
183 la s3, initstack_end
184 mv sp, s3
185 addi sp, sp, -PCB_SIZE
186
187 /* Clear BSS */
188 la s0, _C_LABEL(__bss_start)
189 la s1, _C_LABEL(_end)
190 1:
191 sd zero, 0(s0)
192 addi s0, s0, 8
193 bltu s0, s1, 1b
194
195 #ifdef SMP
196 /* Store boot hart id. */
197 la t0, boot_hart
198 sw a0, 0(t0)
199 #endif
200
201 /* Fill riscv_bootparams */
202 addi sp, sp, -40
203
204 la t0, pagetable_l1
205 sd t0, 0(sp) /* kern_l1pt */
206 sd s9, 8(sp) /* kern_phys */
207
208 la t0, initstack
209 sd t0, 16(sp) /* kern_stack */
210
211 li t0, (VM_MAX_KERNEL_ADDRESS - 2 * L2_SIZE)
212 sd t0, 24(sp) /* dtbp_virt */
213 sd a1, 32(sp) /* dtbp_phys */
214
215 mv a0, sp
216 call _C_LABEL(initriscv) /* Off we go */
217 call _C_LABEL(mi_startup)
218
219 /*
220 * Get the physical address the kernel is loaded to. Returned in s9.
221 */
222 get_physmem:
223 lla t0, virt_map /* physical address of virt_map */
224 ld t1, 0(t0) /* virtual address of virt_map */
225 sub t1, t1, t0 /* calculate phys->virt delta */
226 li t2, KERNBASE
227 sub s9, t2, t1 /* s9 = physmem base */
228 ret
229
230 .align 4
231 initstack:
232 .space (PAGE_SIZE * KSTACK_PAGES)
233 initstack_end:
234
235 ENTRY(sigcode)
236 mv a0, sp
237 addi a0, a0, SF_UC
238
239 1:
240 li t0, SYS_sigreturn
241 ecall
242
243 /* sigreturn failed, exit */
244 li t0, SYS_exit
245 ecall
246
247 j 1b
248 END(sigcode)
249 /* This may be copied to the stack, keep it 16-byte aligned */
250 .align 3
251 esigcode:
252
253 .data
254 .align 3
255 .global szsigcode
256 szsigcode:
257 .quad esigcode - sigcode
258
259 .align 12
260 pagetable_l1:
261 .space PAGE_SIZE
262 pagetable_l2:
263 .space PAGE_SIZE
264 pagetable_l2_devmap:
265 .space PAGE_SIZE
266
267 .align 3
268 virt_map:
269 .quad virt_map
270 hart_lottery:
271 .space 4
272
273 .globl init_pt_va
274 init_pt_va:
275 .quad pagetable_l2 /* XXX: Keep page tables VA */
276
277 #ifndef SMP
278 ENTRY(mpentry)
279 1:
280 wfi
281 j 1b
282 END(mpentry)
283 #else
284 /*
285 * mpentry(unsigned long)
286 *
287 * Called by a core when it is being brought online.
288 */
289 ENTRY(mpentry)
290 /*
291 * Calculate the offset to __riscv_boot_ap
292 * for the current core, cpuid is in a0.
293 */
294 li t1, 4
295 mulw t1, t1, a0
296 /* Get the pointer */
297 lla t0, __riscv_boot_ap
298 add t0, t0, t1
299
300 1:
301 /* Wait the kernel to be ready */
302 lw t1, 0(t0)
303 beqz t1, 1b
304
305 /* Setup stack pointer */
306 lla t0, bootstack
307 ld sp, 0(t0)
308
309 /* Get the kernel's load address */
310 jal get_physmem
311
312 /* Setup supervisor trap vector */
313 lla t0, mpva
314 sub t0, t0, s9
315 li t1, KERNBASE
316 add t0, t0, t1
317 csrw stvec, t0
318
319 /* Set page tables base register */
320 lla s2, pagetable_l1
321 srli s2, s2, PAGE_SHIFT
322 li t0, SATP_MODE_SV39
323 or s2, s2, t0
324 sfence.vma
325 csrw satp, s2
326
327 .align 2
328 mpva:
329 /* Setup supervisor trap vector */
330 la t0, cpu_exception_handler
331 csrw stvec, t0
332
333 /* Ensure sscratch is zero */
334 li t0, 0
335 csrw sscratch, t0
336
337 /* Set the global pointer */
338 .option push
339 .option norelax
340 la gp, __global_pointer$
341 .option pop
342
343 call init_secondary
344 END(mpentry)
345 #endif
Cache object: c377e23a125f7d8849c022211fe9fc44
|