1 /*-
2 * Copyright (c) 2015-2016 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.s"
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 #define HTIF_RING_NENTRIES (512)
47 #define HTIF_RING_ENTRY_SZ (24)
48 #define HTIF_RING_SIZE (HTIF_RING_ENTRY_SZ * HTIF_RING_NENTRIES)
49 #define HW_STACK_SIZE (96)
50
51 /*
52 * Event queue for each CPU core:
53 *
54 * struct htif_ring {
55 * uint64_t data;
56 * uint64_t used;
57 * uint64_t next;
58 * } htif_ring[HTIF_RING_NENTRIES];
59 * uint64_t htif_ring_cursor;
60 * uint64_t htif_ring_last;
61 */
62
63 .macro build_ring
64 la t0, htif_ring
65 #ifdef SMP
66 csrr a0, mhartid
67 li s0, (HTIF_RING_SIZE + 16)
68 mulw s0, a0, s0
69 add t0, t0, s0
70 #endif
71 li t1, 0
72 sd t1, 0(t0) /* zero data */
73 sd t1, 8(t0) /* zero used */
74 mv t2, t0
75 mv t3, t0
76 li t5, (HTIF_RING_SIZE)
77 li t6, 0
78 add t4, t0, t5
79 1:
80 addi t3, t3, HTIF_RING_ENTRY_SZ /* pointer to next */
81 beq t3, t4, 2f /* finish */
82 sd t3, 16(t2) /* store pointer */
83 addi t2, t2, HTIF_RING_ENTRY_SZ /* next entry */
84 addi t6, t6, 1 /* counter */
85 j 1b
86 2:
87 addi t3, t3, -HTIF_RING_ENTRY_SZ
88 sd t0, 16(t3) /* last -> first */
89
90 li t2, (HTIF_RING_SIZE)
91 add s0, t0, t2
92 sd t0, 0(s0) /* cursor */
93 sd t0, 8(s0) /* last */
94 /* finish building ring */
95 .endm
96
97 .globl kernbase
98 .set kernbase, KERNBASE
99
100 /* Trap entries */
101 .text
102
103 mentry:
104 /* User mode entry point (mtvec + 0x000) */
105 .align 6
106 j user_trap
107
108 /* Supervisor mode entry point (mtvec + 0x040) */
109 .align 6
110 j supervisor_trap
111
112 /* Hypervisor mode entry point (mtvec + 0x080) */
113 .align 6
114 j bad_trap
115
116 /* Machine mode entry point (mtvec + 0x0C0) */
117 .align 6
118 j bad_trap
119
120 /* Reset vector */
121 .text
122 .align 8
123 .globl _start
124 _start:
125 /* Direct secondary cores to mpentry */
126 csrr a0, mhartid
127 bnez a0, mpentry
128
129 /* Build event queue for current core */
130 build_ring
131
132 /* Setup machine-mode stack for CPU 0 */
133 la t0, hardstack_end
134 csrw mscratch, t0
135
136 li t0, 0
137 csrw sscratch, t0
138
139 li s10, PAGE_SIZE
140 li s9, (PAGE_SIZE * KSTACK_PAGES)
141
142 /* Page tables */
143
144 /* Create an L1 page for early devmap */
145 la s1, pagetable_l1
146 la s2, pagetable_l2_devmap /* Link to next level PN */
147 srli s2, s2, PAGE_SHIFT
148
149 li a5, (VM_MAX_KERNEL_ADDRESS - L2_SIZE)
150 srli a5, a5, L1_SHIFT /* >> L1_SHIFT */
151 andi a5, a5, 0x1ff /* & 0x1ff */
152 li t4, (PTE_VALID | (PTE_TYPE_PTR << PTE_TYPE_S))
153 slli t5, s2, PTE_PPN0_S /* (s2 << PTE_PPN0_S) */
154 or t6, t4, t5
155
156 /* Store single level1 PTE entry to position */
157 li a6, PTE_SIZE
158 mulw a5, a5, a6
159 add t0, s1, a5
160 sd t6, (t0)
161
162 /* Add single Level 1 entry for kernel */
163 la s1, pagetable_l1
164 la s2, pagetable_l2 /* Link to next level PN */
165 srli s2, s2, PAGE_SHIFT
166
167 li a5, KERNBASE
168 srli a5, a5, L1_SHIFT /* >> L1_SHIFT */
169 andi a5, a5, 0x1ff /* & 0x1ff */
170 li t4, (PTE_VALID | (PTE_TYPE_PTR << PTE_TYPE_S))
171 slli t5, s2, PTE_PPN0_S /* (s2 << PTE_PPN0_S) */
172 or t6, t4, t5
173
174 /* Store single level1 PTE entry to position */
175 li a6, PTE_SIZE
176 mulw a5, a5, a6
177 add t0, s1, a5
178 sd t6, (t0)
179
180 /* Level 2 superpages (512 x 2MiB) */
181 la s1, pagetable_l2
182 li t3, 512 /* Build 512 entries */
183 li t4, 0 /* Counter */
184 li t5, 0
185 2:
186 li t0, (PTE_VALID | (PTE_TYPE_SRWX << PTE_TYPE_S))
187 slli t2, t4, PTE_PPN1_S /* << PTE_PPN1_S */
188 or t5, t0, t2
189 sd t5, (s1) /* Store PTE entry to position */
190 addi s1, s1, PTE_SIZE
191
192 addi t4, t4, 1
193 bltu t4, t3, 2b
194
195 /* Set page tables base register */
196 la s1, pagetable_l1
197 csrw sptbr, s1
198
199 /* Page tables END */
200
201 /* Enter supervisor mode */
202 li s0, ((MSTATUS_VM_SV39 << MSTATUS_VM_SHIFT) | \
203 (MSTATUS_PRV_M << MSTATUS_PRV_SHIFT) | \
204 (MSTATUS_PRV_S << MSTATUS_PRV1_SHIFT) | \
205 (MSTATUS_PRV_U << MSTATUS_PRV2_SHIFT));
206 csrw mstatus, s0
207
208 /*
209 * Enable machine-mode software interrupts
210 * so we can deliver IPI to this core.
211 */
212 li t0, MIE_MSIE
213 csrs mie, t0
214
215 /* Exit from machine mode */
216 la t0, .Lmmu_on
217 li s11, KERNBASE
218 add t0, t0, s11
219 csrw mepc, t0
220 eret
221
222 .Lmmu_on:
223 /* Initialize stack pointer */
224 la s3, initstack_end
225 mv sp, s3
226 addi sp, sp, -PCB_SIZE
227
228 /* Clear BSS */
229 la a0, _C_LABEL(__bss_start)
230 la s1, _C_LABEL(_end)
231 1:
232 sd zero, 0(a0)
233 addi a0, a0, 8
234 bltu a0, s1, 1b
235
236 /* Fill riscv_bootparams */
237 addi sp, sp, -16
238 la t0, pagetable_l1
239 sd t0, 0(sp) /* kern_l1pt */
240 la t0, initstack_end
241 sd t0, 8(sp) /* kern_stack */
242
243 mv a0, sp
244 call _C_LABEL(initriscv) /* Off we go */
245 call _C_LABEL(mi_startup)
246
247 .align 4
248 initstack:
249 .space (PAGE_SIZE * KSTACK_PAGES)
250 initstack_end:
251 hardstack:
252 .space (HW_STACK_SIZE * MAXCPU)
253 hardstack_end:
254
255 .globl htif_ring
256 htif_ring:
257 .space ((HTIF_RING_SIZE + 16) * MAXCPU)
258
259 .globl console_intr
260 console_intr:
261 .space (8)
262
263 ENTRY(sigcode)
264 mv a0, sp
265 addi a0, a0, SF_UC
266
267 1:
268 li t0, SYS_sigreturn
269 ecall
270
271 /* sigreturn failed, exit */
272 li t0, SYS_exit
273 ecall
274
275 j 1b
276 END(sigcode)
277 /* This may be copied to the stack, keep it 16-byte aligned */
278 .align 3
279 esigcode:
280
281 .data
282 .align 3
283 .global szsigcode
284 szsigcode:
285 .quad esigcode - sigcode
286
287 .align 12
288 pagetable_l1:
289 .space PAGE_SIZE
290 pagetable_l2:
291 .space PAGE_SIZE
292 pagetable_l2_devmap:
293 .space PAGE_SIZE
294
295 .globl init_pt_va
296 init_pt_va:
297 .quad pagetable_l2 /* XXX: Keep page tables VA */
298
299 #ifndef SMP
300 ENTRY(mpentry)
301 1:
302 wfi
303 j 1b
304 END(mpentry)
305 #else
306 /*
307 * mpentry(unsigned long)
308 *
309 * Called by a core when it is being brought online.
310 * The data in x0 is passed straight to init_secondary.
311 */
312 ENTRY(mpentry)
313 /*
314 * Calculate the offset to __riscv_boot_ap
315 * for current core, cpuid in a0.
316 */
317 li t1, 4
318 mulw t1, t1, a0
319 /* Get pointer */
320 la t0, __riscv_boot_ap
321 add t0, t0, t1
322
323 1:
324 /* Wait the kernel to be ready */
325 lw t1, 0(t0)
326 beqz t1, 1b
327
328 /* Build event queue ring for this core */
329 build_ring
330
331 /* Set page tables base register */
332 la t0, pagetable_l1
333 csrw sptbr, t0
334
335 /* Configure mstatus */
336 li s0, ((MSTATUS_VM_SV39 << MSTATUS_VM_SHIFT) | \
337 (MSTATUS_PRV_M << MSTATUS_PRV_SHIFT) | \
338 (MSTATUS_PRV_S << MSTATUS_PRV1_SHIFT) | \
339 (MSTATUS_PRV_U << MSTATUS_PRV2_SHIFT));
340 csrw mstatus, s0
341
342 /* Setup stack for machine mode exceptions */
343 la t0, hardstack_end
344 li t1, HW_STACK_SIZE
345 mulw t1, t1, a0
346 sub t0, t0, t1
347 csrw mscratch, t0
348
349 li t0, 0
350 csrw sscratch, t0
351
352 /*
353 * Enable machine-mode software interrupts
354 * so we can deliver IPI to this core.
355 */
356 li t0, MIE_MSIE
357 csrs mie, t0
358
359 /*
360 * Exit from machine mode and go to
361 * the virtual address space.
362 */
363 la t0, mp_virtdone
364 li s11, KERNBASE
365 add t0, t0, s11
366 csrw mepc, t0
367 eret
368
369 mp_virtdone:
370 /* We are now in virtual address space */
371
372 /* Setup stack pointer */
373 la t0, secondary_stacks
374 li t1, (PAGE_SIZE * KSTACK_PAGES)
375 mulw t1, t1, a0
376 add sp, t0, t1
377
378 call init_secondary
379 END(mpentry)
380 #endif
381
382 #include "exception.S"
Cache object: f74b1f30df4ff453ab23c936380932a3
|