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