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