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