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