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