xref: /freebsd/sys/riscv/riscv/locore.S (revision 95ee2897)
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
35fc2a8776SEd Maste#include "assym.inc"
3628029b68SRuslan Bukin
3728029b68SRuslan Bukin#include <sys/syscall.h>
3828029b68SRuslan Bukin#include <machine/asm.h>
3928029b68SRuslan Bukin#include <machine/param.h>
4028029b68SRuslan Bukin#include <machine/trap.h>
4128029b68SRuslan Bukin#include <machine/riscvreg.h>
4228029b68SRuslan Bukin#include <machine/pte.h>
4328029b68SRuslan Bukin
4428029b68SRuslan Bukin	.globl	kernbase
4528029b68SRuslan Bukin	.set	kernbase, KERNBASE
4628029b68SRuslan Bukin
4728029b68SRuslan Bukin	.text
48f7d2df2aSMitchell Horne/*
49f7d2df2aSMitchell Horne * Alternate entry point. Used when booting via SBI firmware. It must be placed
50f7d2df2aSMitchell Horne * at the beginning of the .text section. Arguments are as follows:
51f7d2df2aSMitchell Horne *  - a0 = hart ID
52f7d2df2aSMitchell Horne *  - a1 = dtbp
53f7d2df2aSMitchell Horne *
54f7d2df2aSMitchell Horne * Multiple CPUs might enter from this point, so we perform a hart lottery and
55f7d2df2aSMitchell Horne * send the losers to mpentry.
56f7d2df2aSMitchell Horne */
57f7d2df2aSMitchell Horne	.globl _alt_start
58f7d2df2aSMitchell Horne_alt_start:
597fdf7f91SMitchell Horne	/* Set the global pointer */
607fdf7f91SMitchell Horne.option push
617fdf7f91SMitchell Horne.option norelax
627fdf7f91SMitchell Horne	lla	gp, __global_pointer$
637fdf7f91SMitchell Horne.option pop
647fdf7f91SMitchell Horne
65b803d0b7SRuslan Bukin	/* Pick a hart to run the boot process. */
66f39b4f88SJohn Baldwin	lla	t0, hart_lottery
67b803d0b7SRuslan Bukin	li	t1, 1
68b803d0b7SRuslan Bukin	amoadd.w t0, t1, 0(t0)
69c7ac71f2SMitchell Horne
70c7ac71f2SMitchell Horne	/*
71c7ac71f2SMitchell Horne	 * We must jump to mpentry in the non-BSP case because the offset is
72c7ac71f2SMitchell Horne	 * too large to fit in a 12-bit branch immediate.
73c7ac71f2SMitchell Horne	 */
74c7ac71f2SMitchell Horne	beqz	t0, 1f
75c7ac71f2SMitchell Horne	j	mpentry
76f7d2df2aSMitchell Horne1:
77f7d2df2aSMitchell Horne	/* Store the boot hart */
78f7d2df2aSMitchell Horne	lla	t0, boot_hart
79f7d2df2aSMitchell Horne	sw	a0, 0(t0)
80f7d2df2aSMitchell Horne
81f7d2df2aSMitchell Horne	/* Load zero as modulep */
82f7d2df2aSMitchell Horne	mv	a0, zero
83f7d2df2aSMitchell Horne	j	pagetables
845f8228b2SRuslan Bukin
855f8228b2SRuslan Bukin/*
86f7d2df2aSMitchell Horne * Main entry point. This routine is marked as the ELF entry, and is where
87f7d2df2aSMitchell Horne * loader(8) will enter the kernel. Arguments are as follows:
88f7d2df2aSMitchell Horne *  - a0 = modulep
89f7d2df2aSMitchell Horne *  - a1 = ???
90f7d2df2aSMitchell Horne *
91f7d2df2aSMitchell Horne * It is expected that only a single CPU will enter here.
925f8228b2SRuslan Bukin */
93f7d2df2aSMitchell Horne	.globl _start
94f7d2df2aSMitchell Horne_start:
95f7d2df2aSMitchell Horne	/* Set the global pointer */
96f7d2df2aSMitchell Horne.option push
97f7d2df2aSMitchell Horne.option norelax
98f7d2df2aSMitchell Horne	lla	gp, __global_pointer$
99f7d2df2aSMitchell Horne.option pop
100f7d2df2aSMitchell Horne
101f7d2df2aSMitchell Horne	/*
102f7d2df2aSMitchell Horne	 * Zero a1 to indicate that we have no DTB pointer. It is already
103f7d2df2aSMitchell Horne	 * included in the loader(8) metadata.
104f7d2df2aSMitchell Horne	 */
105f7d2df2aSMitchell Horne	mv	a1, zero
106f7d2df2aSMitchell Horne
107f7d2df2aSMitchell Horne	/*
10843379792SMark Johnston	 * Set up page tables: map a 1GB region starting at KERNBASE using 2MB
10943379792SMark Johnston	 * superpages, starting from the first 2MB physical page into which the
11043379792SMark Johnston	 * kernel was loaded.  Also reserve an L2 page for the early device map
11143379792SMark Johnston	 * and map the DTB, if any, using the second-last entry of that L2
11243379792SMark Johnston	 * page.  This is hopefully enough to get us to pmap_bootstrap().
11343379792SMark Johnston	 *
11443379792SMark Johnston	 * Implementations are required to provide SV39 mode, so we use that
11543379792SMark Johnston	 * initially and will optionally enable SV48 mode during kernel pmap
11643379792SMark Johnston	 * initialization.
11743379792SMark Johnston	 *
118f7d2df2aSMitchell Horne	 *  a0 - modulep or zero
119f7d2df2aSMitchell Horne	 *  a1 - zero or dtbp
120f7d2df2aSMitchell Horne	 */
121f7d2df2aSMitchell Hornepagetables:
122df62bf00SMitchell Horne	/* Get the kernel's load address */
123df62bf00SMitchell Horne	jal	get_physmem
124df62bf00SMitchell Horne
1255f8228b2SRuslan Bukin	/* Add L1 entry for kernel */
126f39b4f88SJohn Baldwin	lla	s1, pagetable_l1
127f39b4f88SJohn Baldwin	lla	s2, pagetable_l2	/* Link to next level PN */
12828029b68SRuslan Bukin	srli	s2, s2, PAGE_SHIFT
12928029b68SRuslan Bukin
1305f8228b2SRuslan Bukin	li	a5, KERNBASE
13102a37128SRuslan Bukin	srli	a5, a5, L1_SHIFT	/* >> L1_SHIFT */
13243379792SMark Johnston	andi	a5, a5, Ln_ADDR_MASK	/* & Ln_ADDR_MASK */
13398f50c44SRuslan Bukin	li	t4, PTE_V
13428029b68SRuslan Bukin	slli	t5, s2, PTE_PPN0_S	/* (s2 << PTE_PPN0_S) */
13528029b68SRuslan Bukin	or	t6, t4, t5
13628029b68SRuslan Bukin
1375f8228b2SRuslan Bukin	/* Store L1 PTE entry to position */
13828029b68SRuslan Bukin	li	a6, PTE_SIZE
13928029b68SRuslan Bukin	mulw	a5, a5, a6
14028029b68SRuslan Bukin	add	t0, s1, a5
14128029b68SRuslan Bukin	sd	t6, (t0)
14228029b68SRuslan Bukin
14328029b68SRuslan Bukin	/* Level 2 superpages (512 x 2MiB) */
144f39b4f88SJohn Baldwin	lla	s1, pagetable_l2
145eb81dfb3SKristof Provost	srli	t4, s9, L2_SHIFT	/* Div physmem base by 2 MiB */
14698f50c44SRuslan Bukin	li	t2, 512			/* Build 512 entries */
14798f50c44SRuslan Bukin	add	t3, t4, t2
148d198cb6dSJohn Baldwin	li	t0, (PTE_KERN | PTE_X)
1496f11e59dSKristof Provost1:
15028029b68SRuslan Bukin	slli	t2, t4, PTE_PPN1_S	/* << PTE_PPN1_S */
15128029b68SRuslan Bukin	or	t5, t0, t2
15228029b68SRuslan Bukin	sd	t5, (s1)		/* Store PTE entry to position */
15328029b68SRuslan Bukin	addi	s1, s1, PTE_SIZE
15428029b68SRuslan Bukin
15528029b68SRuslan Bukin	addi	t4, t4, 1
156f7d2df2aSMitchell Horne	bltu	t4, t3, 1b
15728029b68SRuslan Bukin
15843379792SMark Johnston	/* Create an L1 table entry for early devmap */
159f39b4f88SJohn Baldwin	lla	s1, pagetable_l1
160f39b4f88SJohn Baldwin	lla	s2, pagetable_l2_devmap	/* Link to next level PN */
161af19cc59SRuslan Bukin	srli	s2, s2, PAGE_SHIFT
162af19cc59SRuslan Bukin
163ef0a711fSAlfredo Mazzinghi	li	a5, (VM_MAX_KERNEL_ADDRESS - PMAP_MAPDEV_EARLY_SIZE)
164af19cc59SRuslan Bukin	srli	a5, a5, L1_SHIFT	/* >> L1_SHIFT */
16543379792SMark Johnston	andi	a5, a5, Ln_ADDR_MASK	/* & Ln_ADDR_MASK */
166af19cc59SRuslan Bukin	li	t4, PTE_V
167af19cc59SRuslan Bukin	slli	t5, s2, PTE_PPN0_S	/* (s2 << PTE_PPN0_S) */
168af19cc59SRuslan Bukin	or	t6, t4, t5
169af19cc59SRuslan Bukin
17043379792SMark Johnston	/* Store the L1 table entry */
171af19cc59SRuslan Bukin	li	a6, PTE_SIZE
172af19cc59SRuslan Bukin	mulw	a5, a5, a6
173af19cc59SRuslan Bukin	add	t0, s1, a5
174af19cc59SRuslan Bukin	sd	t6, (t0)
175af19cc59SRuslan Bukin
176f7d2df2aSMitchell Horne	/* Check if we have a DTB that needs to be mapped */
177f7d2df2aSMitchell Horne	beqz	a1, 2f
178f7d2df2aSMitchell Horne
17943379792SMark Johnston	/* Create an L2 mapping for the DTB */
180f39b4f88SJohn Baldwin	lla	s1, pagetable_l2_devmap
181b803d0b7SRuslan Bukin	mv	s2, a1
182af19cc59SRuslan Bukin	srli	s2, s2, PAGE_SHIFT
183c714d797SAlex Richardson	/* Mask off any bits that aren't aligned */
184c714d797SAlex Richardson	andi	s2, s2, ~((1 << (PTE_PPN1_S - PTE_PPN0_S)) - 1)
185af19cc59SRuslan Bukin
186b977d819SRuslan Bukin	li	t0, (PTE_KERN)
187af19cc59SRuslan Bukin	slli	t2, s2, PTE_PPN0_S	/* << PTE_PPN0_S */
188af19cc59SRuslan Bukin	or	t0, t0, t2
189af19cc59SRuslan Bukin
19043379792SMark Johnston	/* Store the L2 table entry for the DTB */
191af19cc59SRuslan Bukin	li	a6, PTE_SIZE
192ef0a711fSAlfredo Mazzinghi	li	a5, VM_EARLY_DTB_ADDRESS
193ef0a711fSAlfredo Mazzinghi	srli	a5, a5, L2_SHIFT    /* >> L2_SHIFT */
194ef0a711fSAlfredo Mazzinghi	andi	a5, a5, Ln_ADDR_MASK    /* & Ln_ADDR_MASK */
195af19cc59SRuslan Bukin	mulw	a5, a5, a6
196af19cc59SRuslan Bukin	add	t1, s1, a5
197af19cc59SRuslan Bukin	sd	t0, (t1)
198af19cc59SRuslan Bukin
199af19cc59SRuslan Bukin	/* Page tables END */
200af19cc59SRuslan Bukin
201af19cc59SRuslan Bukin	/* Setup supervisor trap vector */
202f7d2df2aSMitchell Horne2:
203f39b4f88SJohn Baldwin	lla	t0, va
204af19cc59SRuslan Bukin	sub	t0, t0, s9
205af19cc59SRuslan Bukin	li	t1, KERNBASE
206af19cc59SRuslan Bukin	add	t0, t0, t1
207af19cc59SRuslan Bukin	csrw	stvec, t0
208af19cc59SRuslan Bukin
20928029b68SRuslan Bukin	/* Set page tables base register */
210f39b4f88SJohn Baldwin	lla	s2, pagetable_l1
2115f8228b2SRuslan Bukin	srli	s2, s2, PAGE_SHIFT
212af19cc59SRuslan Bukin	li	t0, SATP_MODE_SV39
213af19cc59SRuslan Bukin	or	s2, s2, t0
214af19cc59SRuslan Bukin	sfence.vma
2151f5e341bSMark Johnston	csrw	satp, s2
216a9063ba1SRuslan Bukin
217a9063ba1SRuslan Bukin	.align 2
218af19cc59SRuslan Bukinva:
2197fdf7f91SMitchell Horne	/* Set the global pointer again, this time with the virtual address. */
2207fdf7f91SMitchell Horne.option push
2217fdf7f91SMitchell Horne.option norelax
2227fdf7f91SMitchell Horne	lla	gp, __global_pointer$
2237fdf7f91SMitchell Horne.option pop
224af19cc59SRuslan Bukin
225af19cc59SRuslan Bukin	/* Setup supervisor trap vector */
226af19cc59SRuslan Bukin	la	t0, cpu_exception_handler
227af19cc59SRuslan Bukin	csrw	stvec, t0
228af19cc59SRuslan Bukin
229af19cc59SRuslan Bukin	/* Ensure sscratch is zero */
230af19cc59SRuslan Bukin	li	t0, 0
231af19cc59SRuslan Bukin	csrw	sscratch, t0
23228029b68SRuslan Bukin
23328029b68SRuslan Bukin	/* Initialize stack pointer */
23499c9fdd0SMitchell Horne	la	sp, initstack_end
23599c9fdd0SMitchell Horne
23699c9fdd0SMitchell Horne	/* Clear frame pointer */
23799c9fdd0SMitchell Horne	mv	s0, zero
238d8f2b755SRuslan Bukin
239d8f2b755SRuslan Bukin	/* Allocate space for thread0 PCB and riscv_bootparams */
240f60da2efSRuslan Bukin	addi	sp, sp, -(PCB_SIZE + RISCV_BOOTPARAMS_SIZE) & ~STACKALIGNBYTES
24128029b68SRuslan Bukin
24228029b68SRuslan Bukin	/* Clear BSS */
24399c9fdd0SMitchell Horne	la	t0, _C_LABEL(__bss_start)
24499c9fdd0SMitchell Horne	la	t1, _C_LABEL(_end)
24528029b68SRuslan Bukin1:
24699c9fdd0SMitchell Horne	sd	zero, 0(t0)
24799c9fdd0SMitchell Horne	addi	t0, t0, 8
24899c9fdd0SMitchell Horne	bltu	t0, t1, 1b
249b803d0b7SRuslan Bukin
25028029b68SRuslan Bukin	/* Fill riscv_bootparams */
25128029b68SRuslan Bukin	la	t0, pagetable_l1
252c5ccc92cSRuslan Bukin	sd	t0, RISCV_BOOTPARAMS_KERN_L1PT(sp)
253c5ccc92cSRuslan Bukin	sd	s9, RISCV_BOOTPARAMS_KERN_PHYS(sp)
2545f8228b2SRuslan Bukin
2550ef3ca7aSMark Johnston	la	t0, initstack
256c5ccc92cSRuslan Bukin	sd	t0, RISCV_BOOTPARAMS_KERN_STACK(sp)
257af19cc59SRuslan Bukin
25824891abdSMitchell Horne	li	t0, (VM_EARLY_DTB_ADDRESS)
259c714d797SAlex Richardson	/* Add offset of DTB within superpage */
260c714d797SAlex Richardson	li	t1, (L2_OFFSET)
261c714d797SAlex Richardson	and	t1, a1, t1
262c714d797SAlex Richardson	add	t0, t0, t1
263c5ccc92cSRuslan Bukin	sd	t0, RISCV_BOOTPARAMS_DTBP_VIRT(sp)
264c98013c0SAlex Richardson	sd	a1, RISCV_BOOTPARAMS_DTBP_PHYS(sp)
26528029b68SRuslan Bukin
266f7d2df2aSMitchell Horne	sd	a0, RISCV_BOOTPARAMS_MODULEP(sp)
267f7d2df2aSMitchell Horne
26828029b68SRuslan Bukin	mv	a0, sp
26928029b68SRuslan Bukin	call	_C_LABEL(initriscv)	/* Off we go */
27028029b68SRuslan Bukin	call	_C_LABEL(mi_startup)
27128029b68SRuslan Bukin
27299c9fdd0SMitchell Horne	/* We should never reach here, but if so just hang. */
27399c9fdd0SMitchell Horne2:
27499c9fdd0SMitchell Horne	wfi
27599c9fdd0SMitchell Horne	j	2b
27699c9fdd0SMitchell Horne
277df62bf00SMitchell Horne/*
278df62bf00SMitchell Horne * Get the physical address the kernel is loaded to. Returned in s9.
279df62bf00SMitchell Horne */
280df62bf00SMitchell Horneget_physmem:
281df62bf00SMitchell Horne	lla	t0, virt_map	/* physical address of virt_map */
282df62bf00SMitchell Horne	ld	t1, 0(t0)	/* virtual address of virt_map */
283df62bf00SMitchell Horne	sub	t1, t1, t0	/* calculate phys->virt delta */
284df62bf00SMitchell Horne	li	t2, KERNBASE
285df62bf00SMitchell Horne	sub	s9, t2, t1	/* s9 = physmem base */
286df62bf00SMitchell Horne	ret
287df62bf00SMitchell Horne
28828029b68SRuslan Bukin	.align  4
28928029b68SRuslan Bukininitstack:
29028029b68SRuslan Bukin	.space  (PAGE_SIZE * KSTACK_PAGES)
29128029b68SRuslan Bukininitstack_end:
29228029b68SRuslan Bukin
29328029b68SRuslan BukinENTRY(sigcode)
29428029b68SRuslan Bukin	mv	a0, sp
29528029b68SRuslan Bukin	addi	a0, a0, SF_UC
29628029b68SRuslan Bukin
29728029b68SRuslan Bukin1:
29828029b68SRuslan Bukin	li	t0, SYS_sigreturn
29928029b68SRuslan Bukin	ecall
30028029b68SRuslan Bukin
30128029b68SRuslan Bukin	/* sigreturn failed, exit */
30228029b68SRuslan Bukin	li	t0, SYS_exit
30328029b68SRuslan Bukin	ecall
30428029b68SRuslan Bukin
30528029b68SRuslan Bukin	j	1b
30628029b68SRuslan BukinEND(sigcode)
30728029b68SRuslan Bukin	/* This may be copied to the stack, keep it 16-byte aligned */
30828029b68SRuslan Bukin	.align	3
30928029b68SRuslan Bukinesigcode:
31028029b68SRuslan Bukin
31128029b68SRuslan Bukin	.data
31228029b68SRuslan Bukin	.align	3
31328029b68SRuslan Bukin	.global	szsigcode
31428029b68SRuslan Bukinszsigcode:
31528029b68SRuslan Bukin	.quad	esigcode - sigcode
31628029b68SRuslan Bukin
31728029b68SRuslan Bukin	.align	12
31828029b68SRuslan Bukinpagetable_l1:
31928029b68SRuslan Bukin	.space	PAGE_SIZE
32028029b68SRuslan Bukinpagetable_l2:
32128029b68SRuslan Bukin	.space	PAGE_SIZE
32202a37128SRuslan Bukinpagetable_l2_devmap:
32302a37128SRuslan Bukin	.space	PAGE_SIZE
3245f8228b2SRuslan Bukin
325af19cc59SRuslan Bukin	.align 3
326af19cc59SRuslan Bukinvirt_map:
327af19cc59SRuslan Bukin	.quad   virt_map
328b803d0b7SRuslan Bukinhart_lottery:
329b803d0b7SRuslan Bukin	.space	4
330af19cc59SRuslan Bukin
33128029b68SRuslan Bukin	.globl init_pt_va
33228029b68SRuslan Bukininit_pt_va:
33328029b68SRuslan Bukin	.quad pagetable_l2	/* XXX: Keep page tables VA */
33428029b68SRuslan Bukin
33517696c12SRuslan Bukin#ifndef SMP
33617696c12SRuslan BukinENTRY(mpentry)
33717696c12SRuslan Bukin1:
33817696c12SRuslan Bukin	wfi
33917696c12SRuslan Bukin	j	1b
34017696c12SRuslan BukinEND(mpentry)
34117696c12SRuslan Bukin#else
34217696c12SRuslan Bukin/*
34317696c12SRuslan Bukin * mpentry(unsigned long)
34417696c12SRuslan Bukin *
34517696c12SRuslan Bukin * Called by a core when it is being brought online.
34617696c12SRuslan Bukin */
34717696c12SRuslan BukinENTRY(mpentry)
348b626c976SRuslan Bukin	/*
349b626c976SRuslan Bukin	 * Calculate the offset to __riscv_boot_ap
350b626c976SRuslan Bukin	 * for the current core, cpuid is in a0.
351b626c976SRuslan Bukin	 */
352b626c976SRuslan Bukin	li	t1, 4
353b626c976SRuslan Bukin	mulw	t1, t1, a0
354b626c976SRuslan Bukin	/* Get the pointer */
355e12bf34cSMitchell Horne	lla	t0, __riscv_boot_ap
356b626c976SRuslan Bukin	add	t0, t0, t1
357b626c976SRuslan Bukin
358b626c976SRuslan Bukin1:
359b626c976SRuslan Bukin	/* Wait the kernel to be ready */
360b626c976SRuslan Bukin	lw	t1, 0(t0)
361b626c976SRuslan Bukin	beqz	t1, 1b
362b626c976SRuslan Bukin
363af19cc59SRuslan Bukin	/* Setup stack pointer */
3648db2e8fdSMark Johnston	lla	t0, bootstack
3658db2e8fdSMark Johnston	ld	sp, 0(t0)
366af19cc59SRuslan Bukin
367df62bf00SMitchell Horne	/* Get the kernel's load address */
368df62bf00SMitchell Horne	jal	get_physmem
369df62bf00SMitchell Horne
370af19cc59SRuslan Bukin	/* Setup supervisor trap vector */
371e12bf34cSMitchell Horne	lla	t0, mpva
372af19cc59SRuslan Bukin	sub	t0, t0, s9
373af19cc59SRuslan Bukin	li	t1, KERNBASE
374af19cc59SRuslan Bukin	add	t0, t0, t1
375af19cc59SRuslan Bukin	csrw	stvec, t0
376af19cc59SRuslan Bukin
377af19cc59SRuslan Bukin	/* Set page tables base register */
378e12bf34cSMitchell Horne	lla	s2, pagetable_l1
379af19cc59SRuslan Bukin	srli	s2, s2, PAGE_SHIFT
380af19cc59SRuslan Bukin	li	t0, SATP_MODE_SV39
381af19cc59SRuslan Bukin	or	s2, s2, t0
382af19cc59SRuslan Bukin	sfence.vma
3831f5e341bSMark Johnston	csrw	satp, s2
384a9063ba1SRuslan Bukin
385a9063ba1SRuslan Bukin	.align 2
386af19cc59SRuslan Bukinmpva:
3877fdf7f91SMitchell Horne	/* Set the global pointer again, this time with the virtual address. */
3887fdf7f91SMitchell Horne.option push
3897fdf7f91SMitchell Horne.option norelax
3907fdf7f91SMitchell Horne	lla	gp, __global_pointer$
3917fdf7f91SMitchell Horne.option pop
3927fdf7f91SMitchell Horne
393af19cc59SRuslan Bukin	/* Setup supervisor trap vector */
394af19cc59SRuslan Bukin	la	t0, cpu_exception_handler
395af19cc59SRuslan Bukin	csrw	stvec, t0
396af19cc59SRuslan Bukin
397af19cc59SRuslan Bukin	/* Ensure sscratch is zero */
398af19cc59SRuslan Bukin	li	t0, 0
399af19cc59SRuslan Bukin	csrw	sscratch, t0
40017696c12SRuslan Bukin
40117696c12SRuslan Bukin	call	init_secondary
40217696c12SRuslan BukinEND(mpentry)
40317696c12SRuslan Bukin#endif
404