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 992: 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 159va: 160 161 /* Setup supervisor trap vector */ 162 la t0, cpu_exception_handler 163 csrw stvec, t0 164 165 /* Ensure sscratch is zero */ 166 li t0, 0 167 csrw sscratch, t0 168 169 /* Initialize stack pointer */ 170 la s3, initstack_end 171 mv sp, s3 172 addi sp, sp, -PCB_SIZE 173 174 /* Clear BSS */ 175 la a0, _C_LABEL(__bss_start) 176 la s1, _C_LABEL(_end) 1771: 178 sd zero, 0(a0) 179 addi a0, a0, 8 180 bltu a0, s1, 1b 181 182 /* Fill riscv_bootparams */ 183 addi sp, sp, -40 184 185 la t0, pagetable_l1 186 sd t0, 0(sp) /* kern_l1pt */ 187 sd s9, 8(sp) /* kern_phys */ 188 189 la t0, initstack_end 190 sd t0, 16(sp) /* kern_stack */ 191 192 li t0, (VM_MAX_KERNEL_ADDRESS - 2 * L2_SIZE) 193 sd t0, 24(sp) /* dtbp_virt */ 194 sd s11, 32(sp) /* dtbp_phys */ 195 196 mv a0, sp 197 call _C_LABEL(initriscv) /* Off we go */ 198 call _C_LABEL(mi_startup) 199 200 .align 4 201initstack: 202 .space (PAGE_SIZE * KSTACK_PAGES) 203initstack_end: 204 205ENTRY(sigcode) 206 mv a0, sp 207 addi a0, a0, SF_UC 208 2091: 210 li t0, SYS_sigreturn 211 ecall 212 213 /* sigreturn failed, exit */ 214 li t0, SYS_exit 215 ecall 216 217 j 1b 218END(sigcode) 219 /* This may be copied to the stack, keep it 16-byte aligned */ 220 .align 3 221esigcode: 222 223 .data 224 .align 3 225 .global szsigcode 226szsigcode: 227 .quad esigcode - sigcode 228 229 .align 12 230pagetable_l1: 231 .space PAGE_SIZE 232pagetable_l2: 233 .space PAGE_SIZE 234pagetable_l2_devmap: 235 .space PAGE_SIZE 236 237 .align 3 238virt_map: 239 .quad virt_map 240 241 /* Not in use, but required for linking. */ 242 .align 3 243 .globl __global_pointer$ 244__global_pointer$: 245 .space 8 246 247 .globl init_pt_va 248init_pt_va: 249 .quad pagetable_l2 /* XXX: Keep page tables VA */ 250 251#ifndef SMP 252ENTRY(mpentry) 2531: 254 wfi 255 j 1b 256END(mpentry) 257#else 258/* 259 * mpentry(unsigned long) 260 * 261 * Called by a core when it is being brought online. 262 */ 263ENTRY(mpentry) 264 /* Setup stack pointer */ 265 la t0, secondary_stacks 266 li t1, (PAGE_SIZE * KSTACK_PAGES) 267 mulw t1, t1, s10 268 add t0, t0, t1 269 sub t0, t0, s9 270 li t1, KERNBASE 271 add sp, t0, t1 272 273 /* Setup supervisor trap vector */ 274 la t0, mpva 275 sub t0, t0, s9 276 li t1, KERNBASE 277 add t0, t0, t1 278 csrw stvec, t0 279 280 /* Set page tables base register */ 281 la s2, pagetable_l1 282 srli s2, s2, PAGE_SHIFT 283 li t0, SATP_MODE_SV39 284 or s2, s2, t0 285 sfence.vma 286 csrw sptbr, s2 287mpva: 288 /* Setup supervisor trap vector */ 289 la t0, cpu_exception_handler 290 csrw stvec, t0 291 292 /* Ensure sscratch is zero */ 293 li t0, 0 294 csrw sscratch, t0 295 /* 296 * Calculate the offset to __riscv_boot_ap 297 * for current core, cpuid in a0. 298 */ 299 li t1, 4 300 mulw t1, t1, a0 301 /* Get pointer */ 302 la t0, __riscv_boot_ap 303 add t0, t0, t1 304 3051: 306 /* Wait the kernel to be ready */ 307 lw t1, 0(t0) 308 beqz t1, 1b 309 310 call init_secondary 311END(mpentry) 312#endif 313