128029b68SRuslan Bukin/*- 2157654d0SRuslan Bukin * Copyright (c) 2015-2018 Ruslan Bukin <br@bsdpad.com> 328029b68SRuslan Bukin * All rights reserved. 428029b68SRuslan Bukin * 528029b68SRuslan Bukin * Portions of this software were developed by SRI International and the 628029b68SRuslan Bukin * University of Cambridge Computer Laboratory under DARPA/AFRL contract 728029b68SRuslan Bukin * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. 828029b68SRuslan Bukin * 928029b68SRuslan Bukin * Portions of this software were developed by the University of Cambridge 1028029b68SRuslan Bukin * Computer Laboratory as part of the CTSRD Project, with support from the 1128029b68SRuslan Bukin * UK Higher Education Innovation Fund (HEIF). 1228029b68SRuslan Bukin * 1328029b68SRuslan Bukin * Redistribution and use in source and binary forms, with or without 1428029b68SRuslan Bukin * modification, are permitted provided that the following conditions 1528029b68SRuslan Bukin * are met: 1628029b68SRuslan Bukin * 1. Redistributions of source code must retain the above copyright 1728029b68SRuslan Bukin * notice, this list of conditions and the following disclaimer. 1828029b68SRuslan Bukin * 2. Redistributions in binary form must reproduce the above copyright 1928029b68SRuslan Bukin * notice, this list of conditions and the following disclaimer in the 2028029b68SRuslan Bukin * documentation and/or other materials provided with the distribution. 2128029b68SRuslan Bukin * 2228029b68SRuslan Bukin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2328029b68SRuslan Bukin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2428029b68SRuslan Bukin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2528029b68SRuslan Bukin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2628029b68SRuslan Bukin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2728029b68SRuslan Bukin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2828029b68SRuslan Bukin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2928029b68SRuslan Bukin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3028029b68SRuslan Bukin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3128029b68SRuslan Bukin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3228029b68SRuslan Bukin * SUCH DAMAGE. 3328029b68SRuslan Bukin * 3428029b68SRuslan Bukin * $FreeBSD$ 3528029b68SRuslan Bukin */ 3628029b68SRuslan Bukin 37fc2a8776SEd Maste#include "assym.inc" 3828029b68SRuslan Bukin 3928029b68SRuslan Bukin#include <sys/syscall.h> 4028029b68SRuslan Bukin#include <machine/asm.h> 4128029b68SRuslan Bukin#include <machine/param.h> 4228029b68SRuslan Bukin#include <machine/trap.h> 4328029b68SRuslan Bukin#include <machine/riscvreg.h> 4428029b68SRuslan Bukin#include <machine/pte.h> 4528029b68SRuslan Bukin 4628029b68SRuslan Bukin .globl kernbase 4728029b68SRuslan Bukin .set kernbase, KERNBASE 4828029b68SRuslan Bukin 4928029b68SRuslan Bukin .text 50f7d2df2aSMitchell Horne/* 51f7d2df2aSMitchell Horne * Alternate entry point. Used when booting via SBI firmware. It must be placed 52f7d2df2aSMitchell Horne * at the beginning of the .text section. Arguments are as follows: 53f7d2df2aSMitchell Horne * - a0 = hart ID 54f7d2df2aSMitchell Horne * - a1 = dtbp 55f7d2df2aSMitchell Horne * 56f7d2df2aSMitchell Horne * Multiple CPUs might enter from this point, so we perform a hart lottery and 57f7d2df2aSMitchell Horne * send the losers to mpentry. 58f7d2df2aSMitchell Horne */ 59f7d2df2aSMitchell Horne .globl _alt_start 60f7d2df2aSMitchell Horne_alt_start: 617fdf7f91SMitchell Horne /* Set the global pointer */ 627fdf7f91SMitchell Horne.option push 637fdf7f91SMitchell Horne.option norelax 647fdf7f91SMitchell Horne lla gp, __global_pointer$ 657fdf7f91SMitchell Horne.option pop 667fdf7f91SMitchell Horne 67b803d0b7SRuslan Bukin /* Pick a hart to run the boot process. */ 68f39b4f88SJohn Baldwin lla t0, hart_lottery 69b803d0b7SRuslan Bukin li t1, 1 70b803d0b7SRuslan Bukin amoadd.w t0, t1, 0(t0) 71c7ac71f2SMitchell Horne 72c7ac71f2SMitchell Horne /* 73c7ac71f2SMitchell Horne * We must jump to mpentry in the non-BSP case because the offset is 74c7ac71f2SMitchell Horne * too large to fit in a 12-bit branch immediate. 75c7ac71f2SMitchell Horne */ 76c7ac71f2SMitchell Horne beqz t0, 1f 77c7ac71f2SMitchell Horne j mpentry 78f7d2df2aSMitchell Horne1: 79f7d2df2aSMitchell Horne /* Store the boot hart */ 80f7d2df2aSMitchell Horne lla t0, boot_hart 81f7d2df2aSMitchell Horne sw a0, 0(t0) 82f7d2df2aSMitchell Horne 83f7d2df2aSMitchell Horne /* Load zero as modulep */ 84f7d2df2aSMitchell Horne mv a0, zero 85f7d2df2aSMitchell Horne j pagetables 865f8228b2SRuslan Bukin 875f8228b2SRuslan Bukin/* 88f7d2df2aSMitchell Horne * Main entry point. This routine is marked as the ELF entry, and is where 89f7d2df2aSMitchell Horne * loader(8) will enter the kernel. Arguments are as follows: 90f7d2df2aSMitchell Horne * - a0 = modulep 91f7d2df2aSMitchell Horne * - a1 = ??? 92f7d2df2aSMitchell Horne * 93f7d2df2aSMitchell Horne * It is expected that only a single CPU will enter here. 945f8228b2SRuslan Bukin */ 95f7d2df2aSMitchell Horne .globl _start 96f7d2df2aSMitchell Horne_start: 97f7d2df2aSMitchell Horne /* Set the global pointer */ 98f7d2df2aSMitchell Horne.option push 99f7d2df2aSMitchell Horne.option norelax 100f7d2df2aSMitchell Horne lla gp, __global_pointer$ 101f7d2df2aSMitchell Horne.option pop 102f7d2df2aSMitchell Horne 103f7d2df2aSMitchell Horne /* 104f7d2df2aSMitchell Horne * Zero a1 to indicate that we have no DTB pointer. It is already 105f7d2df2aSMitchell Horne * included in the loader(8) metadata. 106f7d2df2aSMitchell Horne */ 107f7d2df2aSMitchell Horne mv a1, zero 108f7d2df2aSMitchell Horne 109f7d2df2aSMitchell Horne /* 110f7d2df2aSMitchell Horne * Page tables setup 111f7d2df2aSMitchell Horne * a0 - modulep or zero 112f7d2df2aSMitchell Horne * a1 - zero or dtbp 113f7d2df2aSMitchell Horne */ 114f7d2df2aSMitchell Hornepagetables: 115df62bf00SMitchell Horne /* Get the kernel's load address */ 116df62bf00SMitchell Horne jal get_physmem 117df62bf00SMitchell Horne 1185f8228b2SRuslan Bukin /* Add L1 entry for kernel */ 119f39b4f88SJohn Baldwin lla s1, pagetable_l1 120f39b4f88SJohn Baldwin lla s2, pagetable_l2 /* Link to next level PN */ 12128029b68SRuslan Bukin srli s2, s2, PAGE_SHIFT 12228029b68SRuslan Bukin 1235f8228b2SRuslan Bukin li a5, KERNBASE 12402a37128SRuslan Bukin srli a5, a5, L1_SHIFT /* >> L1_SHIFT */ 12528029b68SRuslan Bukin andi a5, a5, 0x1ff /* & 0x1ff */ 12698f50c44SRuslan Bukin li t4, PTE_V 12728029b68SRuslan Bukin slli t5, s2, PTE_PPN0_S /* (s2 << PTE_PPN0_S) */ 12828029b68SRuslan Bukin or t6, t4, t5 12928029b68SRuslan Bukin 1305f8228b2SRuslan Bukin /* Store L1 PTE entry to position */ 13128029b68SRuslan Bukin li a6, PTE_SIZE 13228029b68SRuslan Bukin mulw a5, a5, a6 13328029b68SRuslan Bukin add t0, s1, a5 13428029b68SRuslan Bukin sd t6, (t0) 13528029b68SRuslan Bukin 13628029b68SRuslan Bukin /* Level 2 superpages (512 x 2MiB) */ 137f39b4f88SJohn Baldwin lla s1, pagetable_l2 138af19cc59SRuslan Bukin srli t4, s9, 21 /* Div physmem base by 2 MiB */ 13998f50c44SRuslan Bukin li t2, 512 /* Build 512 entries */ 14098f50c44SRuslan Bukin add t3, t4, t2 14128029b68SRuslan Bukin li t5, 0 142d198cb6dSJohn Baldwin li t0, (PTE_KERN | PTE_X) 143*6f11e59dSKristof Provost1: 14428029b68SRuslan Bukin slli t2, t4, PTE_PPN1_S /* << PTE_PPN1_S */ 14528029b68SRuslan Bukin or t5, t0, t2 14628029b68SRuslan Bukin sd t5, (s1) /* Store PTE entry to position */ 14728029b68SRuslan Bukin addi s1, s1, PTE_SIZE 14828029b68SRuslan Bukin 14928029b68SRuslan Bukin addi t4, t4, 1 150f7d2df2aSMitchell Horne bltu t4, t3, 1b 15128029b68SRuslan Bukin 152af19cc59SRuslan Bukin /* Create an L1 page for early devmap */ 153f39b4f88SJohn Baldwin lla s1, pagetable_l1 154f39b4f88SJohn Baldwin lla s2, pagetable_l2_devmap /* Link to next level PN */ 155af19cc59SRuslan Bukin srli s2, s2, PAGE_SHIFT 156af19cc59SRuslan Bukin 157af19cc59SRuslan Bukin li a5, (VM_MAX_KERNEL_ADDRESS - L2_SIZE) 158af19cc59SRuslan Bukin srli a5, a5, L1_SHIFT /* >> L1_SHIFT */ 159af19cc59SRuslan Bukin andi a5, a5, 0x1ff /* & 0x1ff */ 160af19cc59SRuslan Bukin li t4, PTE_V 161af19cc59SRuslan Bukin slli t5, s2, PTE_PPN0_S /* (s2 << PTE_PPN0_S) */ 162af19cc59SRuslan Bukin or t6, t4, t5 163af19cc59SRuslan Bukin 164af19cc59SRuslan Bukin /* Store single level1 PTE entry to position */ 165af19cc59SRuslan Bukin li a6, PTE_SIZE 166af19cc59SRuslan Bukin mulw a5, a5, a6 167af19cc59SRuslan Bukin add t0, s1, a5 168af19cc59SRuslan Bukin sd t6, (t0) 169af19cc59SRuslan Bukin 170f7d2df2aSMitchell Horne /* Check if we have a DTB that needs to be mapped */ 171f7d2df2aSMitchell Horne beqz a1, 2f 172f7d2df2aSMitchell Horne 173af19cc59SRuslan Bukin /* Create an L2 page superpage for DTB */ 174f39b4f88SJohn Baldwin lla s1, pagetable_l2_devmap 175b803d0b7SRuslan Bukin mv s2, a1 176af19cc59SRuslan Bukin srli s2, s2, PAGE_SHIFT 177c714d797SAlex Richardson /* Mask off any bits that aren't aligned */ 178c714d797SAlex Richardson andi s2, s2, ~((1 << (PTE_PPN1_S - PTE_PPN0_S)) - 1) 179af19cc59SRuslan Bukin 180b977d819SRuslan Bukin li t0, (PTE_KERN) 181af19cc59SRuslan Bukin slli t2, s2, PTE_PPN0_S /* << PTE_PPN0_S */ 182af19cc59SRuslan Bukin or t0, t0, t2 183af19cc59SRuslan Bukin 184af19cc59SRuslan Bukin /* Store PTE entry to position */ 185af19cc59SRuslan Bukin li a6, PTE_SIZE 186af19cc59SRuslan Bukin li a5, 510 187af19cc59SRuslan Bukin mulw a5, a5, a6 188af19cc59SRuslan Bukin add t1, s1, a5 189af19cc59SRuslan Bukin sd t0, (t1) 190af19cc59SRuslan Bukin 191af19cc59SRuslan Bukin /* Page tables END */ 192af19cc59SRuslan Bukin 193af19cc59SRuslan Bukin /* Setup supervisor trap vector */ 194f7d2df2aSMitchell Horne2: 195f39b4f88SJohn Baldwin lla t0, va 196af19cc59SRuslan Bukin sub t0, t0, s9 197af19cc59SRuslan Bukin li t1, KERNBASE 198af19cc59SRuslan Bukin add t0, t0, t1 199af19cc59SRuslan Bukin csrw stvec, t0 200af19cc59SRuslan Bukin 20128029b68SRuslan Bukin /* Set page tables base register */ 202f39b4f88SJohn Baldwin lla s2, pagetable_l1 2035f8228b2SRuslan Bukin srli s2, s2, PAGE_SHIFT 204af19cc59SRuslan Bukin li t0, SATP_MODE_SV39 205af19cc59SRuslan Bukin or s2, s2, t0 206af19cc59SRuslan Bukin sfence.vma 2071f5e341bSMark Johnston csrw satp, s2 208a9063ba1SRuslan Bukin 209a9063ba1SRuslan Bukin .align 2 210af19cc59SRuslan Bukinva: 2117fdf7f91SMitchell Horne /* Set the global pointer again, this time with the virtual address. */ 2127fdf7f91SMitchell Horne.option push 2137fdf7f91SMitchell Horne.option norelax 2147fdf7f91SMitchell Horne lla gp, __global_pointer$ 2157fdf7f91SMitchell Horne.option pop 216af19cc59SRuslan Bukin 217af19cc59SRuslan Bukin /* Setup supervisor trap vector */ 218af19cc59SRuslan Bukin la t0, cpu_exception_handler 219af19cc59SRuslan Bukin csrw stvec, t0 220af19cc59SRuslan Bukin 221af19cc59SRuslan Bukin /* Ensure sscratch is zero */ 222af19cc59SRuslan Bukin li t0, 0 223af19cc59SRuslan Bukin csrw sscratch, t0 22428029b68SRuslan Bukin 22528029b68SRuslan Bukin /* Initialize stack pointer */ 22628029b68SRuslan Bukin la s3, initstack_end 22728029b68SRuslan Bukin mv sp, s3 228d8f2b755SRuslan Bukin 229d8f2b755SRuslan Bukin /* Allocate space for thread0 PCB and riscv_bootparams */ 230f60da2efSRuslan Bukin addi sp, sp, -(PCB_SIZE + RISCV_BOOTPARAMS_SIZE) & ~STACKALIGNBYTES 23128029b68SRuslan Bukin 23228029b68SRuslan Bukin /* Clear BSS */ 233b803d0b7SRuslan Bukin la s0, _C_LABEL(__bss_start) 23428029b68SRuslan Bukin la s1, _C_LABEL(_end) 23528029b68SRuslan Bukin1: 236b803d0b7SRuslan Bukin sd zero, 0(s0) 237b803d0b7SRuslan Bukin addi s0, s0, 8 238b803d0b7SRuslan Bukin bltu s0, s1, 1b 239b803d0b7SRuslan Bukin 24028029b68SRuslan Bukin /* Fill riscv_bootparams */ 24128029b68SRuslan Bukin la t0, pagetable_l1 242c5ccc92cSRuslan Bukin sd t0, RISCV_BOOTPARAMS_KERN_L1PT(sp) 243c5ccc92cSRuslan Bukin sd s9, RISCV_BOOTPARAMS_KERN_PHYS(sp) 2445f8228b2SRuslan Bukin 2450ef3ca7aSMark Johnston la t0, initstack 246c5ccc92cSRuslan Bukin sd t0, RISCV_BOOTPARAMS_KERN_STACK(sp) 247af19cc59SRuslan Bukin 24824891abdSMitchell Horne li t0, (VM_EARLY_DTB_ADDRESS) 249c714d797SAlex Richardson /* Add offset of DTB within superpage */ 250c714d797SAlex Richardson li t1, (L2_OFFSET) 251c714d797SAlex Richardson and t1, a1, t1 252c714d797SAlex Richardson add t0, t0, t1 253c5ccc92cSRuslan Bukin sd t0, RISCV_BOOTPARAMS_DTBP_VIRT(sp) 254c98013c0SAlex Richardson sd a1, RISCV_BOOTPARAMS_DTBP_PHYS(sp) 25528029b68SRuslan Bukin 256f7d2df2aSMitchell Horne sd a0, RISCV_BOOTPARAMS_MODULEP(sp) 257f7d2df2aSMitchell Horne 25828029b68SRuslan Bukin mv a0, sp 25928029b68SRuslan Bukin call _C_LABEL(initriscv) /* Off we go */ 26028029b68SRuslan Bukin call _C_LABEL(mi_startup) 26128029b68SRuslan Bukin 262df62bf00SMitchell Horne/* 263df62bf00SMitchell Horne * Get the physical address the kernel is loaded to. Returned in s9. 264df62bf00SMitchell Horne */ 265df62bf00SMitchell Horneget_physmem: 266df62bf00SMitchell Horne lla t0, virt_map /* physical address of virt_map */ 267df62bf00SMitchell Horne ld t1, 0(t0) /* virtual address of virt_map */ 268df62bf00SMitchell Horne sub t1, t1, t0 /* calculate phys->virt delta */ 269df62bf00SMitchell Horne li t2, KERNBASE 270df62bf00SMitchell Horne sub s9, t2, t1 /* s9 = physmem base */ 271df62bf00SMitchell Horne ret 272df62bf00SMitchell Horne 27328029b68SRuslan Bukin .align 4 27428029b68SRuslan Bukininitstack: 27528029b68SRuslan Bukin .space (PAGE_SIZE * KSTACK_PAGES) 27628029b68SRuslan Bukininitstack_end: 27728029b68SRuslan Bukin 27828029b68SRuslan BukinENTRY(sigcode) 27928029b68SRuslan Bukin mv a0, sp 28028029b68SRuslan Bukin addi a0, a0, SF_UC 28128029b68SRuslan Bukin 28228029b68SRuslan Bukin1: 28328029b68SRuslan Bukin li t0, SYS_sigreturn 28428029b68SRuslan Bukin ecall 28528029b68SRuslan Bukin 28628029b68SRuslan Bukin /* sigreturn failed, exit */ 28728029b68SRuslan Bukin li t0, SYS_exit 28828029b68SRuslan Bukin ecall 28928029b68SRuslan Bukin 29028029b68SRuslan Bukin j 1b 29128029b68SRuslan BukinEND(sigcode) 29228029b68SRuslan Bukin /* This may be copied to the stack, keep it 16-byte aligned */ 29328029b68SRuslan Bukin .align 3 29428029b68SRuslan Bukinesigcode: 29528029b68SRuslan Bukin 29628029b68SRuslan Bukin .data 29728029b68SRuslan Bukin .align 3 29828029b68SRuslan Bukin .global szsigcode 29928029b68SRuslan Bukinszsigcode: 30028029b68SRuslan Bukin .quad esigcode - sigcode 30128029b68SRuslan Bukin 30228029b68SRuslan Bukin .align 12 30328029b68SRuslan Bukinpagetable_l1: 30428029b68SRuslan Bukin .space PAGE_SIZE 30528029b68SRuslan Bukinpagetable_l2: 30628029b68SRuslan Bukin .space PAGE_SIZE 30702a37128SRuslan Bukinpagetable_l2_devmap: 30802a37128SRuslan Bukin .space PAGE_SIZE 3095f8228b2SRuslan Bukin 310af19cc59SRuslan Bukin .align 3 311af19cc59SRuslan Bukinvirt_map: 312af19cc59SRuslan Bukin .quad virt_map 313b803d0b7SRuslan Bukinhart_lottery: 314b803d0b7SRuslan Bukin .space 4 315af19cc59SRuslan Bukin 31628029b68SRuslan Bukin .globl init_pt_va 31728029b68SRuslan Bukininit_pt_va: 31828029b68SRuslan Bukin .quad pagetable_l2 /* XXX: Keep page tables VA */ 31928029b68SRuslan Bukin 32017696c12SRuslan Bukin#ifndef SMP 32117696c12SRuslan BukinENTRY(mpentry) 32217696c12SRuslan Bukin1: 32317696c12SRuslan Bukin wfi 32417696c12SRuslan Bukin j 1b 32517696c12SRuslan BukinEND(mpentry) 32617696c12SRuslan Bukin#else 32717696c12SRuslan Bukin/* 32817696c12SRuslan Bukin * mpentry(unsigned long) 32917696c12SRuslan Bukin * 33017696c12SRuslan Bukin * Called by a core when it is being brought online. 33117696c12SRuslan Bukin */ 33217696c12SRuslan BukinENTRY(mpentry) 333b626c976SRuslan Bukin /* 334b626c976SRuslan Bukin * Calculate the offset to __riscv_boot_ap 335b626c976SRuslan Bukin * for the current core, cpuid is in a0. 336b626c976SRuslan Bukin */ 337b626c976SRuslan Bukin li t1, 4 338b626c976SRuslan Bukin mulw t1, t1, a0 339b626c976SRuslan Bukin /* Get the pointer */ 340e12bf34cSMitchell Horne lla t0, __riscv_boot_ap 341b626c976SRuslan Bukin add t0, t0, t1 342b626c976SRuslan Bukin 343b626c976SRuslan Bukin1: 344b626c976SRuslan Bukin /* Wait the kernel to be ready */ 345b626c976SRuslan Bukin lw t1, 0(t0) 346b626c976SRuslan Bukin beqz t1, 1b 347b626c976SRuslan Bukin 348af19cc59SRuslan Bukin /* Setup stack pointer */ 3498db2e8fdSMark Johnston lla t0, bootstack 3508db2e8fdSMark Johnston ld sp, 0(t0) 351af19cc59SRuslan Bukin 352df62bf00SMitchell Horne /* Get the kernel's load address */ 353df62bf00SMitchell Horne jal get_physmem 354df62bf00SMitchell Horne 355af19cc59SRuslan Bukin /* Setup supervisor trap vector */ 356e12bf34cSMitchell Horne lla t0, mpva 357af19cc59SRuslan Bukin sub t0, t0, s9 358af19cc59SRuslan Bukin li t1, KERNBASE 359af19cc59SRuslan Bukin add t0, t0, t1 360af19cc59SRuslan Bukin csrw stvec, t0 361af19cc59SRuslan Bukin 362af19cc59SRuslan Bukin /* Set page tables base register */ 363e12bf34cSMitchell Horne lla s2, pagetable_l1 364af19cc59SRuslan Bukin srli s2, s2, PAGE_SHIFT 365af19cc59SRuslan Bukin li t0, SATP_MODE_SV39 366af19cc59SRuslan Bukin or s2, s2, t0 367af19cc59SRuslan Bukin sfence.vma 3681f5e341bSMark Johnston csrw satp, s2 369a9063ba1SRuslan Bukin 370a9063ba1SRuslan Bukin .align 2 371af19cc59SRuslan Bukinmpva: 3727fdf7f91SMitchell Horne /* Set the global pointer again, this time with the virtual address. */ 3737fdf7f91SMitchell Horne.option push 3747fdf7f91SMitchell Horne.option norelax 3757fdf7f91SMitchell Horne lla gp, __global_pointer$ 3767fdf7f91SMitchell Horne.option pop 3777fdf7f91SMitchell Horne 378af19cc59SRuslan Bukin /* Setup supervisor trap vector */ 379af19cc59SRuslan Bukin la t0, cpu_exception_handler 380af19cc59SRuslan Bukin csrw stvec, t0 381af19cc59SRuslan Bukin 382af19cc59SRuslan Bukin /* Ensure sscratch is zero */ 383af19cc59SRuslan Bukin li t0, 0 384af19cc59SRuslan Bukin csrw sscratch, t0 38517696c12SRuslan Bukin 38617696c12SRuslan Bukin call init_secondary 38717696c12SRuslan BukinEND(mpentry) 38817696c12SRuslan Bukin#endif 389