xref: /freebsd/sys/riscv/riscv/locore.S (revision 6f11e59d)
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