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 */ 831: 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 1082: 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 170va: 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) 1941: 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_end 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 224initstack: 225 .space (PAGE_SIZE * KSTACK_PAGES) 226initstack_end: 227 228ENTRY(sigcode) 229 mv a0, sp 230 addi a0, a0, SF_UC 231 2321: 233 li t0, SYS_sigreturn 234 ecall 235 236 /* sigreturn failed, exit */ 237 li t0, SYS_exit 238 ecall 239 240 j 1b 241END(sigcode) 242 /* This may be copied to the stack, keep it 16-byte aligned */ 243 .align 3 244esigcode: 245 246 .data 247 .align 3 248 .global szsigcode 249szsigcode: 250 .quad esigcode - sigcode 251 252 .align 12 253pagetable_l1: 254 .space PAGE_SIZE 255pagetable_l2: 256 .space PAGE_SIZE 257pagetable_l2_devmap: 258 .space PAGE_SIZE 259 260 .align 3 261virt_map: 262 .quad virt_map 263hart_lottery: 264 .space 4 265 266 .globl init_pt_va 267init_pt_va: 268 .quad pagetable_l2 /* XXX: Keep page tables VA */ 269 270#ifndef SMP 271ENTRY(mpentry) 2721: 273 wfi 274 j 1b 275END(mpentry) 276#else 277/* 278 * mpentry(unsigned long) 279 * 280 * Called by a core when it is being brought online. 281 */ 282ENTRY(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 2931: 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 324mpva: 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 340END(mpentry) 341#endif 342