xref: /freebsd/sys/riscv/riscv/locore.S (revision 98f50c44)
128029b68SRuslan Bukin/*-
217696c12SRuslan Bukin * Copyright (c) 2015-2016 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
3728029b68SRuslan Bukin#include "assym.s"
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
4617696c12SRuslan Bukin#define	HTIF_RING_NENTRIES	(512)
4717696c12SRuslan Bukin#define	HTIF_RING_ENTRY_SZ	(24)
4817696c12SRuslan Bukin#define	HTIF_RING_SIZE		(HTIF_RING_ENTRY_SZ * HTIF_RING_NENTRIES)
4917696c12SRuslan Bukin#define	HW_STACK_SIZE		(96)
5017696c12SRuslan Bukin
5117696c12SRuslan Bukin/*
52*98f50c44SRuslan Bukin * Event queue:
5317696c12SRuslan Bukin *
5417696c12SRuslan Bukin * struct htif_ring {
5517696c12SRuslan Bukin *     uint64_t data;
5617696c12SRuslan Bukin *     uint64_t used;
5717696c12SRuslan Bukin *     uint64_t next;
5817696c12SRuslan Bukin * } htif_ring[HTIF_RING_NENTRIES];
5917696c12SRuslan Bukin * uint64_t htif_ring_cursor;
6017696c12SRuslan Bukin * uint64_t htif_ring_last;
6117696c12SRuslan Bukin */
6217696c12SRuslan Bukin
6317696c12SRuslan Bukin.macro build_ring
6417696c12SRuslan Bukin	la	t0, htif_ring
6517696c12SRuslan Bukin	li	t1, 0
6617696c12SRuslan Bukin	sd	t1, 0(t0)	/* zero data */
6717696c12SRuslan Bukin	sd	t1, 8(t0)	/* zero used */
6817696c12SRuslan Bukin	mv	t2, t0
6917696c12SRuslan Bukin	mv	t3, t0
706c1838e3SRuslan Bukin	li	t5, (HTIF_RING_SIZE)
7117696c12SRuslan Bukin	li	t6, 0
7217696c12SRuslan Bukin	add	t4, t0, t5
7317696c12SRuslan Bukin1:
746c1838e3SRuslan Bukin	addi	t3, t3, HTIF_RING_ENTRY_SZ	/* pointer to next */
7517696c12SRuslan Bukin	beq	t3, t4, 2f			/* finish */
7617696c12SRuslan Bukin	sd	t3, 16(t2)			/* store pointer */
776c1838e3SRuslan Bukin	addi	t2, t2, HTIF_RING_ENTRY_SZ	/* next entry */
7817696c12SRuslan Bukin	addi	t6, t6, 1			/* counter */
7917696c12SRuslan Bukin	j	1b
8017696c12SRuslan Bukin2:
816c1838e3SRuslan Bukin	addi	t3, t3, -HTIF_RING_ENTRY_SZ
8217696c12SRuslan Bukin	sd	t0, 16(t3)			/* last -> first */
8317696c12SRuslan Bukin
8417696c12SRuslan Bukin	li	t2, (HTIF_RING_SIZE)
8517696c12SRuslan Bukin	add	s0, t0, t2
8617696c12SRuslan Bukin	sd	t0, 0(s0)	/* cursor */
8717696c12SRuslan Bukin	sd	t0, 8(s0)	/* last */
8817696c12SRuslan Bukin	/* finish building ring */
8917696c12SRuslan Bukin.endm
9028029b68SRuslan Bukin
9128029b68SRuslan Bukin	.globl	kernbase
9228029b68SRuslan Bukin	.set	kernbase, KERNBASE
9328029b68SRuslan Bukin
9428029b68SRuslan Bukin	/* Trap entries */
9528029b68SRuslan Bukin	.text
9628029b68SRuslan Bukin
9728029b68SRuslan Bukinmentry:
98*98f50c44SRuslan Bukin	/* Vectors */
99*98f50c44SRuslan Bukin	j	_start		/* reset */
100*98f50c44SRuslan Bukin	j	bad_trap	/* NMI (non-maskable interrupt) */
101*98f50c44SRuslan Bukin	j	machine_trap
10228029b68SRuslan Bukin
10328029b68SRuslan Bukin	/* Reset vector */
10428029b68SRuslan Bukin	.text
10528029b68SRuslan Bukin	.globl _start
10628029b68SRuslan Bukin_start:
107*98f50c44SRuslan Bukin	/* Setup machine trap vector */
108*98f50c44SRuslan Bukin	la	t0, machine_trap
109*98f50c44SRuslan Bukin	csrw	mtvec, t0
110*98f50c44SRuslan Bukin
111*98f50c44SRuslan Bukin	/* Delegate interrupts to supervisor mode */
112*98f50c44SRuslan Bukin	li	t0, (MIP_SSIP | MIP_STIP | MIP_SEIP)
113*98f50c44SRuslan Bukin	csrw	mideleg, t0
114*98f50c44SRuslan Bukin
115*98f50c44SRuslan Bukin	/* Delegate exceptions to supervisor mode */
116*98f50c44SRuslan Bukin	li	t0,	(1 << EXCP_MISALIGNED_FETCH)	| \
117*98f50c44SRuslan Bukin			(1 << EXCP_FAULT_FETCH)		| \
118*98f50c44SRuslan Bukin			(1 << EXCP_ILLEGAL_INSTRUCTION)	| \
119*98f50c44SRuslan Bukin			(1 << EXCP_FAULT_LOAD)		| \
120*98f50c44SRuslan Bukin			(1 << EXCP_FAULT_STORE)		| \
121*98f50c44SRuslan Bukin			(1 << EXCP_BREAKPOINT)		| \
122*98f50c44SRuslan Bukin			(1 << EXCP_USER_ECALL)
123*98f50c44SRuslan Bukin	csrw	medeleg, t0
124*98f50c44SRuslan Bukin
125*98f50c44SRuslan Bukin	la	t0, cpu_exception_handler
126*98f50c44SRuslan Bukin	li	t1, KERNBASE
127*98f50c44SRuslan Bukin	add	t0, t0, t1
128*98f50c44SRuslan Bukin	csrw	stvec, t0
129*98f50c44SRuslan Bukin
13017696c12SRuslan Bukin	/* Direct secondary cores to mpentry */
13117696c12SRuslan Bukin	csrr	a0, mhartid
13217696c12SRuslan Bukin	bnez	a0, mpentry
13328029b68SRuslan Bukin
134*98f50c44SRuslan Bukin	li	t1, 0
135*98f50c44SRuslan Bukin	la	t0, tohost
136*98f50c44SRuslan Bukin	sd	t1, 0(t0)
137*98f50c44SRuslan Bukin	la	t0, fromhost
138*98f50c44SRuslan Bukin	sd	t1, 0(t0)
139*98f50c44SRuslan Bukin
14017696c12SRuslan Bukin	/* Build event queue for current core */
14117696c12SRuslan Bukin	build_ring
14228029b68SRuslan Bukin
14317696c12SRuslan Bukin	/* Setup machine-mode stack for CPU 0 */
14428029b68SRuslan Bukin	la	t0, hardstack_end
14528029b68SRuslan Bukin	csrw	mscratch, t0
14628029b68SRuslan Bukin
14728029b68SRuslan Bukin	li	t0, 0
14828029b68SRuslan Bukin	csrw	sscratch, t0
14928029b68SRuslan Bukin
15028029b68SRuslan Bukin	li	s10, PAGE_SIZE
15128029b68SRuslan Bukin	li	s9, (PAGE_SIZE * KSTACK_PAGES)
15228029b68SRuslan Bukin
15328029b68SRuslan Bukin	/* Page tables */
15428029b68SRuslan Bukin
15502a37128SRuslan Bukin	/* Create an L1 page for early devmap */
15602a37128SRuslan Bukin	la	s1, pagetable_l1
15702a37128SRuslan Bukin	la	s2, pagetable_l2_devmap	/* Link to next level PN */
15828029b68SRuslan Bukin	srli	s2, s2, PAGE_SHIFT
15928029b68SRuslan Bukin
16002a37128SRuslan Bukin	li	a5, (VM_MAX_KERNEL_ADDRESS - L2_SIZE)
16102a37128SRuslan Bukin	srli	a5, a5, L1_SHIFT	/* >> L1_SHIFT */
16202a37128SRuslan Bukin	andi	a5, a5, 0x1ff		/* & 0x1ff */
163*98f50c44SRuslan Bukin	li	t4, PTE_V
16428029b68SRuslan Bukin	slli	t5, s2, PTE_PPN0_S	/* (s2 << PTE_PPN0_S) */
16528029b68SRuslan Bukin	or	t6, t4, t5
16628029b68SRuslan Bukin
16702a37128SRuslan Bukin	/* Store single level1 PTE entry to position */
16828029b68SRuslan Bukin	li	a6, PTE_SIZE
16928029b68SRuslan Bukin	mulw	a5, a5, a6
17028029b68SRuslan Bukin	add	t0, s1, a5
17102a37128SRuslan Bukin	sd	t6, (t0)
17228029b68SRuslan Bukin
17302a37128SRuslan Bukin	/* Add single Level 1 entry for kernel */
17428029b68SRuslan Bukin	la	s1, pagetable_l1
17528029b68SRuslan Bukin	la	s2, pagetable_l2	/* Link to next level PN */
17628029b68SRuslan Bukin	srli	s2, s2, PAGE_SHIFT
17728029b68SRuslan Bukin
178*98f50c44SRuslan Bukin	li	a5, (KERNBASE + KERNENTRY)
17902a37128SRuslan Bukin	srli	a5, a5, L1_SHIFT	/* >> L1_SHIFT */
18028029b68SRuslan Bukin	andi	a5, a5, 0x1ff		/* & 0x1ff */
181*98f50c44SRuslan Bukin	li	t4, PTE_V
18228029b68SRuslan Bukin	slli	t5, s2, PTE_PPN0_S	/* (s2 << PTE_PPN0_S) */
18328029b68SRuslan Bukin	or	t6, t4, t5
18428029b68SRuslan Bukin
18528029b68SRuslan Bukin	/* Store single level1 PTE entry to position */
18628029b68SRuslan Bukin	li	a6, PTE_SIZE
18728029b68SRuslan Bukin	mulw	a5, a5, a6
18828029b68SRuslan Bukin	add	t0, s1, a5
18928029b68SRuslan Bukin	sd	t6, (t0)
19028029b68SRuslan Bukin
19128029b68SRuslan Bukin	/* Level 2 superpages (512 x 2MiB) */
19228029b68SRuslan Bukin	la	s1, pagetable_l2
193*98f50c44SRuslan Bukin	li	t4, KERNENTRY
194*98f50c44SRuslan Bukin	srli	t4, t4, 21		/* Div by 2 MiB */
195*98f50c44SRuslan Bukin	li	t2, 512			/* Build 512 entries */
196*98f50c44SRuslan Bukin	add	t3, t4, t2
19728029b68SRuslan Bukin	li	t5, 0
19828029b68SRuslan Bukin2:
199*98f50c44SRuslan Bukin	li	t0, (PTE_V | PTE_RWX)
20028029b68SRuslan Bukin	slli	t2, t4, PTE_PPN1_S	/* << PTE_PPN1_S */
20128029b68SRuslan Bukin	or	t5, t0, t2
20228029b68SRuslan Bukin	sd	t5, (s1)		/* Store PTE entry to position */
20328029b68SRuslan Bukin	addi	s1, s1, PTE_SIZE
20428029b68SRuslan Bukin
20528029b68SRuslan Bukin	addi	t4, t4, 1
20628029b68SRuslan Bukin	bltu	t4, t3, 2b
20728029b68SRuslan Bukin
20828029b68SRuslan Bukin	/* Set page tables base register */
20902a37128SRuslan Bukin	la	s1, pagetable_l1
210*98f50c44SRuslan Bukin	srli	s1, s1, PAGE_SHIFT
21128029b68SRuslan Bukin	csrw	sptbr, s1
21228029b68SRuslan Bukin
21328029b68SRuslan Bukin	/* Page tables END */
21428029b68SRuslan Bukin
21528029b68SRuslan Bukin	/* Enter supervisor mode */
21602a37128SRuslan Bukin	li	s0, ((MSTATUS_VM_SV39 << MSTATUS_VM_SHIFT) | \
217*98f50c44SRuslan Bukin		     (MSTATUS_PRV_S << MSTATUS_MPP_SHIFT));
21828029b68SRuslan Bukin	csrw	mstatus, s0
21928029b68SRuslan Bukin
22017696c12SRuslan Bukin	/*
22117696c12SRuslan Bukin	 * Enable machine-mode software interrupts
22217696c12SRuslan Bukin	 * so we can deliver IPI to this core.
22317696c12SRuslan Bukin	 */
22417696c12SRuslan Bukin	li	t0, MIE_MSIE
22517696c12SRuslan Bukin	csrs	mie, t0
22617696c12SRuslan Bukin
22728029b68SRuslan Bukin	/* Exit from machine mode */
22828029b68SRuslan Bukin	la	t0, .Lmmu_on
22917696c12SRuslan Bukin	li	s11, KERNBASE
23028029b68SRuslan Bukin	add	t0, t0, s11
23128029b68SRuslan Bukin	csrw	mepc, t0
232*98f50c44SRuslan Bukin	mret
23328029b68SRuslan Bukin
23428029b68SRuslan Bukin.Lmmu_on:
23528029b68SRuslan Bukin	/* Initialize stack pointer */
23628029b68SRuslan Bukin	la	s3, initstack_end
23728029b68SRuslan Bukin	mv	sp, s3
23828029b68SRuslan Bukin	addi	sp, sp, -PCB_SIZE
23928029b68SRuslan Bukin
24028029b68SRuslan Bukin	/* Clear BSS  */
24128029b68SRuslan Bukin	la	a0, _C_LABEL(__bss_start)
24228029b68SRuslan Bukin	la	s1, _C_LABEL(_end)
24328029b68SRuslan Bukin1:
24428029b68SRuslan Bukin	sd	zero, 0(a0)
24528029b68SRuslan Bukin	addi	a0, a0, 8
24628029b68SRuslan Bukin	bltu	a0, s1, 1b
24728029b68SRuslan Bukin
24828029b68SRuslan Bukin	/* Fill riscv_bootparams */
24928029b68SRuslan Bukin	addi	sp, sp, -16
25028029b68SRuslan Bukin	la	t0, pagetable_l1
25128029b68SRuslan Bukin	sd	t0, 0(sp) /* kern_l1pt */
25228029b68SRuslan Bukin	la	t0, initstack_end
25328029b68SRuslan Bukin	sd	t0, 8(sp) /* kern_stack */
25428029b68SRuslan Bukin
25528029b68SRuslan Bukin	mv	a0, sp
25628029b68SRuslan Bukin	call	_C_LABEL(initriscv)	/* Off we go */
25728029b68SRuslan Bukin	call	_C_LABEL(mi_startup)
25828029b68SRuslan Bukin
25928029b68SRuslan Bukin	.align  4
26028029b68SRuslan Bukininitstack:
26128029b68SRuslan Bukin	.space  (PAGE_SIZE * KSTACK_PAGES)
26228029b68SRuslan Bukininitstack_end:
26328029b68SRuslan Bukinhardstack:
26417696c12SRuslan Bukin	.space  (HW_STACK_SIZE * MAXCPU)
26528029b68SRuslan Bukinhardstack_end:
26628029b68SRuslan Bukin
26728029b68SRuslan Bukin	.globl htif_ring
26828029b68SRuslan Bukinhtif_ring:
269*98f50c44SRuslan Bukin	.space (HTIF_RING_SIZE + 16)
270*98f50c44SRuslan Bukinhtif_lock:
271*98f50c44SRuslan Bukin	.space (8)
272*98f50c44SRuslan Bukintohost:
273*98f50c44SRuslan Bukin	.space (8)
274*98f50c44SRuslan Bukinfromhost:
27528029b68SRuslan Bukin	.space (8)
27628029b68SRuslan Bukin
27728029b68SRuslan BukinENTRY(sigcode)
27828029b68SRuslan Bukin	mv	a0, sp
27928029b68SRuslan Bukin	addi	a0, a0, SF_UC
28028029b68SRuslan Bukin
28128029b68SRuslan Bukin1:
28228029b68SRuslan Bukin	li	t0, SYS_sigreturn
28328029b68SRuslan Bukin	ecall
28428029b68SRuslan Bukin
28528029b68SRuslan Bukin	/* sigreturn failed, exit */
28628029b68SRuslan Bukin	li	t0, SYS_exit
28728029b68SRuslan Bukin	ecall
28828029b68SRuslan Bukin
28928029b68SRuslan Bukin	j	1b
29028029b68SRuslan BukinEND(sigcode)
29128029b68SRuslan Bukin	/* This may be copied to the stack, keep it 16-byte aligned */
29228029b68SRuslan Bukin	.align	3
29328029b68SRuslan Bukinesigcode:
29428029b68SRuslan Bukin
29528029b68SRuslan Bukin	.data
29628029b68SRuslan Bukin	.align	3
29728029b68SRuslan Bukin	.global	szsigcode
29828029b68SRuslan Bukinszsigcode:
29928029b68SRuslan Bukin	.quad	esigcode - sigcode
30028029b68SRuslan Bukin
30128029b68SRuslan Bukin	.align	12
30228029b68SRuslan Bukinpagetable_l1:
30328029b68SRuslan Bukin	.space	PAGE_SIZE
30428029b68SRuslan Bukinpagetable_l2:
30528029b68SRuslan Bukin	.space	PAGE_SIZE
30602a37128SRuslan Bukinpagetable_l2_devmap:
30702a37128SRuslan Bukin	.space	PAGE_SIZE
30828029b68SRuslan Bukin
30928029b68SRuslan Bukin	.globl init_pt_va
31028029b68SRuslan Bukininit_pt_va:
31128029b68SRuslan Bukin	.quad pagetable_l2	/* XXX: Keep page tables VA */
31228029b68SRuslan Bukin
31317696c12SRuslan Bukin#ifndef SMP
31417696c12SRuslan BukinENTRY(mpentry)
31517696c12SRuslan Bukin1:
31617696c12SRuslan Bukin	wfi
31717696c12SRuslan Bukin	j	1b
31817696c12SRuslan BukinEND(mpentry)
31917696c12SRuslan Bukin#else
32017696c12SRuslan Bukin/*
32117696c12SRuslan Bukin * mpentry(unsigned long)
32217696c12SRuslan Bukin *
32317696c12SRuslan Bukin * Called by a core when it is being brought online.
32417696c12SRuslan Bukin * The data in x0 is passed straight to init_secondary.
32517696c12SRuslan Bukin */
32617696c12SRuslan BukinENTRY(mpentry)
32717696c12SRuslan Bukin	/*
32817696c12SRuslan Bukin	 * Calculate the offset to __riscv_boot_ap
32917696c12SRuslan Bukin	 * for current core, cpuid in a0.
33017696c12SRuslan Bukin	 */
33117696c12SRuslan Bukin	li	t1, 4
33217696c12SRuslan Bukin	mulw	t1, t1, a0
33317696c12SRuslan Bukin	/* Get pointer */
33417696c12SRuslan Bukin	la	t0, __riscv_boot_ap
33517696c12SRuslan Bukin	add	t0, t0, t1
33617696c12SRuslan Bukin
33717696c12SRuslan Bukin1:
33817696c12SRuslan Bukin	/* Wait the kernel to be ready */
33917696c12SRuslan Bukin	lw	t1, 0(t0)
34017696c12SRuslan Bukin	beqz	t1, 1b
34117696c12SRuslan Bukin
34217696c12SRuslan Bukin	/* Set page tables base register */
34302a37128SRuslan Bukin	la	t0, pagetable_l1
344*98f50c44SRuslan Bukin	srli	t0, t0, PAGE_SHIFT
34517696c12SRuslan Bukin	csrw	sptbr, t0
34617696c12SRuslan Bukin
34717696c12SRuslan Bukin	/* Configure mstatus */
34802a37128SRuslan Bukin	li	s0, ((MSTATUS_VM_SV39 << MSTATUS_VM_SHIFT) | \
349*98f50c44SRuslan Bukin		     (MSTATUS_PRV_S << MSTATUS_MPP_SHIFT));
35017696c12SRuslan Bukin	csrw	mstatus, s0
35117696c12SRuslan Bukin
35217696c12SRuslan Bukin	/* Setup stack for machine mode exceptions */
35317696c12SRuslan Bukin	la	t0, hardstack_end
35417696c12SRuslan Bukin	li	t1, HW_STACK_SIZE
35517696c12SRuslan Bukin	mulw	t1, t1, a0
35617696c12SRuslan Bukin	sub	t0, t0, t1
35717696c12SRuslan Bukin	csrw	mscratch, t0
35817696c12SRuslan Bukin
35917696c12SRuslan Bukin	li	t0, 0
36017696c12SRuslan Bukin	csrw	sscratch, t0
36117696c12SRuslan Bukin
36217696c12SRuslan Bukin	/*
36317696c12SRuslan Bukin	 * Enable machine-mode software interrupts
36417696c12SRuslan Bukin	 * so we can deliver IPI to this core.
36517696c12SRuslan Bukin	 */
36617696c12SRuslan Bukin	li	t0, MIE_MSIE
36717696c12SRuslan Bukin	csrs	mie, t0
36817696c12SRuslan Bukin
36917696c12SRuslan Bukin	/*
37017696c12SRuslan Bukin	 * Exit from machine mode and go to
37117696c12SRuslan Bukin	 * the virtual address space.
37217696c12SRuslan Bukin	 */
37317696c12SRuslan Bukin	la	t0, mp_virtdone
37417696c12SRuslan Bukin	li	s11, KERNBASE
37517696c12SRuslan Bukin	add	t0, t0, s11
37617696c12SRuslan Bukin	csrw	mepc, t0
377*98f50c44SRuslan Bukin	mret
37817696c12SRuslan Bukin
37917696c12SRuslan Bukinmp_virtdone:
38017696c12SRuslan Bukin	/* We are now in virtual address space */
38117696c12SRuslan Bukin
38217696c12SRuslan Bukin	/* Setup stack pointer */
38317696c12SRuslan Bukin	la	t0, secondary_stacks
38417696c12SRuslan Bukin	li	t1, (PAGE_SIZE * KSTACK_PAGES)
38517696c12SRuslan Bukin	mulw	t1, t1, a0
38617696c12SRuslan Bukin	add	sp, t0, t1
38717696c12SRuslan Bukin
38817696c12SRuslan Bukin	call	init_secondary
38917696c12SRuslan BukinEND(mpentry)
39017696c12SRuslan Bukin#endif
39117696c12SRuslan Bukin
39228029b68SRuslan Bukin#include "exception.S"
393