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