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