xref: /freebsd/sys/riscv/riscv/locore.S (revision fc2a8776)
128029b68SRuslan Bukin/*-
2af19cc59SRuslan Bukin * Copyright (c) 2015-2017 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
37*fc2a8776SEd 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	/* Trap entries */
5028029b68SRuslan Bukin	.text
5128029b68SRuslan Bukin
5228029b68SRuslan Bukin	/* Reset vector */
5328029b68SRuslan Bukin	.text
5428029b68SRuslan Bukin	.globl _start
5528029b68SRuslan Bukin_start:
56af19cc59SRuslan Bukin	/* Get the physical address kernel loaded to */
57af19cc59SRuslan Bukin	la	t0, virt_map
58af19cc59SRuslan Bukin	ld	t1, 0(t0)
59af19cc59SRuslan Bukin	sub	t1, t1, t0
60af19cc59SRuslan Bukin	li	t2, KERNBASE
61af19cc59SRuslan Bukin	sub	s9, t2, t1	/* s9 = physmem base */
62af19cc59SRuslan Bukin	mv	s10, a0		/* s10 = hart id */
63af19cc59SRuslan Bukin	mv	s11, a1		/* s11 = dtbp */
6498f50c44SRuslan Bukin
65af19cc59SRuslan Bukin	li	t0, SSTATUS_SUM
66af19cc59SRuslan Bukin	csrs	sstatus, t0
675f8228b2SRuslan Bukin
685f8228b2SRuslan Bukin	/* Direct secondary cores to mpentry */
69af19cc59SRuslan Bukin	bnez	s10, mpentry
705f8228b2SRuslan Bukin
715f8228b2SRuslan Bukin	/*
725f8228b2SRuslan Bukin	 * Page tables
735f8228b2SRuslan Bukin	 */
7428029b68SRuslan Bukin
755f8228b2SRuslan Bukin	/* Add L1 entry for kernel */
7628029b68SRuslan Bukin	la	s1, pagetable_l1
7728029b68SRuslan Bukin	la	s2, pagetable_l2	/* Link to next level PN */
7828029b68SRuslan Bukin	srli	s2, s2, PAGE_SHIFT
7928029b68SRuslan Bukin
805f8228b2SRuslan Bukin	li	a5, KERNBASE
8102a37128SRuslan Bukin	srli	a5, a5, L1_SHIFT	/* >> L1_SHIFT */
8228029b68SRuslan Bukin	andi	a5, a5, 0x1ff		/* & 0x1ff */
8398f50c44SRuslan Bukin	li	t4, PTE_V
8428029b68SRuslan Bukin	slli	t5, s2, PTE_PPN0_S	/* (s2 << PTE_PPN0_S) */
8528029b68SRuslan Bukin	or	t6, t4, t5
8628029b68SRuslan Bukin
875f8228b2SRuslan Bukin	/* Store L1 PTE entry to position */
8828029b68SRuslan Bukin	li	a6, PTE_SIZE
8928029b68SRuslan Bukin	mulw	a5, a5, a6
9028029b68SRuslan Bukin	add	t0, s1, a5
9128029b68SRuslan Bukin	sd	t6, (t0)
9228029b68SRuslan Bukin
9328029b68SRuslan Bukin	/* Level 2 superpages (512 x 2MiB) */
9428029b68SRuslan Bukin	la	s1, pagetable_l2
95af19cc59SRuslan Bukin	srli	t4, s9, 21		/* Div physmem base by 2 MiB */
9698f50c44SRuslan Bukin	li	t2, 512			/* Build 512 entries */
9798f50c44SRuslan Bukin	add	t3, t4, t2
9828029b68SRuslan Bukin	li	t5, 0
9928029b68SRuslan Bukin2:
100af19cc59SRuslan Bukin	li	t0, (PTE_V | PTE_RWX | PTE_D)
10128029b68SRuslan Bukin	slli	t2, t4, PTE_PPN1_S	/* << PTE_PPN1_S */
10228029b68SRuslan Bukin	or	t5, t0, t2
10328029b68SRuslan Bukin	sd	t5, (s1)		/* Store PTE entry to position */
10428029b68SRuslan Bukin	addi	s1, s1, PTE_SIZE
10528029b68SRuslan Bukin
10628029b68SRuslan Bukin	addi	t4, t4, 1
10728029b68SRuslan Bukin	bltu	t4, t3, 2b
10828029b68SRuslan Bukin
109af19cc59SRuslan Bukin	/* Create an L1 page for early devmap */
110af19cc59SRuslan Bukin	la	s1, pagetable_l1
111af19cc59SRuslan Bukin	la	s2, pagetable_l2_devmap	/* Link to next level PN */
112af19cc59SRuslan Bukin	srli	s2, s2, PAGE_SHIFT
113af19cc59SRuslan Bukin
114af19cc59SRuslan Bukin	li	a5, (VM_MAX_KERNEL_ADDRESS - L2_SIZE)
115af19cc59SRuslan Bukin	srli	a5, a5, L1_SHIFT	/* >> L1_SHIFT */
116af19cc59SRuslan Bukin	andi	a5, a5, 0x1ff		/* & 0x1ff */
117af19cc59SRuslan Bukin	li	t4, PTE_V
118af19cc59SRuslan Bukin	slli	t5, s2, PTE_PPN0_S	/* (s2 << PTE_PPN0_S) */
119af19cc59SRuslan Bukin	or	t6, t4, t5
120af19cc59SRuslan Bukin
121af19cc59SRuslan Bukin	/* Store single level1 PTE entry to position */
122af19cc59SRuslan Bukin	li	a6, PTE_SIZE
123af19cc59SRuslan Bukin	mulw	a5, a5, a6
124af19cc59SRuslan Bukin	add	t0, s1, a5
125af19cc59SRuslan Bukin	sd	t6, (t0)
126af19cc59SRuslan Bukin
127af19cc59SRuslan Bukin	/* Create an L2 page superpage for DTB */
128af19cc59SRuslan Bukin	la	s1, pagetable_l2_devmap
129af19cc59SRuslan Bukin	mv	s2, s11
130af19cc59SRuslan Bukin	srli	s2, s2, PAGE_SHIFT
131af19cc59SRuslan Bukin
132af19cc59SRuslan Bukin	li	t0, (PTE_V | PTE_RWX | PTE_D)
133af19cc59SRuslan Bukin	slli	t2, s2, PTE_PPN0_S	/* << PTE_PPN0_S */
134af19cc59SRuslan Bukin	or	t0, t0, t2
135af19cc59SRuslan Bukin
136af19cc59SRuslan Bukin	/* Store PTE entry to position */
137af19cc59SRuslan Bukin	li	a6, PTE_SIZE
138af19cc59SRuslan Bukin	li	a5, 510
139af19cc59SRuslan Bukin	mulw	a5, a5, a6
140af19cc59SRuslan Bukin	add	t1, s1, a5
141af19cc59SRuslan Bukin	sd	t0, (t1)
142af19cc59SRuslan Bukin
143af19cc59SRuslan Bukin	/* Page tables END */
144af19cc59SRuslan Bukin
145af19cc59SRuslan Bukin	/* Setup supervisor trap vector */
146af19cc59SRuslan Bukin	la	t0, va
147af19cc59SRuslan Bukin	sub	t0, t0, s9
148af19cc59SRuslan Bukin	li	t1, KERNBASE
149af19cc59SRuslan Bukin	add	t0, t0, t1
150af19cc59SRuslan Bukin	csrw	stvec, t0
151af19cc59SRuslan Bukin
15228029b68SRuslan Bukin	/* Set page tables base register */
1535f8228b2SRuslan Bukin	la	s2, pagetable_l1
1545f8228b2SRuslan Bukin	srli	s2, s2, PAGE_SHIFT
155af19cc59SRuslan Bukin	li	t0, SATP_MODE_SV39
156af19cc59SRuslan Bukin	or	s2, s2, t0
157af19cc59SRuslan Bukin	sfence.vma
1585f8228b2SRuslan Bukin	csrw	sptbr, s2
159af19cc59SRuslan Bukinva:
160af19cc59SRuslan Bukin
161af19cc59SRuslan Bukin	/* Setup supervisor trap vector */
162af19cc59SRuslan Bukin	la	t0, cpu_exception_handler
163af19cc59SRuslan Bukin	csrw	stvec, t0
164af19cc59SRuslan Bukin
165af19cc59SRuslan Bukin	/* Ensure sscratch is zero */
166af19cc59SRuslan Bukin	li	t0, 0
167af19cc59SRuslan Bukin	csrw	sscratch, t0
16828029b68SRuslan Bukin
16928029b68SRuslan Bukin	/* Initialize stack pointer */
17028029b68SRuslan Bukin	la	s3, initstack_end
17128029b68SRuslan Bukin	mv	sp, s3
17228029b68SRuslan Bukin	addi	sp, sp, -PCB_SIZE
17328029b68SRuslan Bukin
17428029b68SRuslan Bukin	/* Clear BSS  */
17528029b68SRuslan Bukin	la	a0, _C_LABEL(__bss_start)
17628029b68SRuslan Bukin	la	s1, _C_LABEL(_end)
17728029b68SRuslan Bukin1:
17828029b68SRuslan Bukin	sd	zero, 0(a0)
17928029b68SRuslan Bukin	addi	a0, a0, 8
18028029b68SRuslan Bukin	bltu	a0, s1, 1b
18128029b68SRuslan Bukin
18228029b68SRuslan Bukin	/* Fill riscv_bootparams */
183af19cc59SRuslan Bukin	addi	sp, sp, -40
1845f8228b2SRuslan Bukin
18528029b68SRuslan Bukin	la	t0, pagetable_l1
18628029b68SRuslan Bukin	sd	t0, 0(sp) /* kern_l1pt */
187af19cc59SRuslan Bukin	sd	s9, 8(sp) /* kern_phys */
1885f8228b2SRuslan Bukin
18928029b68SRuslan Bukin	la	t0, initstack_end
190af19cc59SRuslan Bukin	sd	t0, 16(sp) /* kern_stack */
191af19cc59SRuslan Bukin
192af19cc59SRuslan Bukin	li	t0, (VM_MAX_KERNEL_ADDRESS - 2 * L2_SIZE)
193af19cc59SRuslan Bukin	sd	t0, 24(sp) /* dtbp_virt */
194af19cc59SRuslan Bukin	sd	s11, 32(sp) /* dtbp_phys */
19528029b68SRuslan Bukin
19628029b68SRuslan Bukin	mv	a0, sp
19728029b68SRuslan Bukin	call	_C_LABEL(initriscv)	/* Off we go */
19828029b68SRuslan Bukin	call	_C_LABEL(mi_startup)
19928029b68SRuslan Bukin
20028029b68SRuslan Bukin	.align  4
20128029b68SRuslan Bukininitstack:
20228029b68SRuslan Bukin	.space  (PAGE_SIZE * KSTACK_PAGES)
20328029b68SRuslan Bukininitstack_end:
20428029b68SRuslan Bukin
20528029b68SRuslan BukinENTRY(sigcode)
20628029b68SRuslan Bukin	mv	a0, sp
20728029b68SRuslan Bukin	addi	a0, a0, SF_UC
20828029b68SRuslan Bukin
20928029b68SRuslan Bukin1:
21028029b68SRuslan Bukin	li	t0, SYS_sigreturn
21128029b68SRuslan Bukin	ecall
21228029b68SRuslan Bukin
21328029b68SRuslan Bukin	/* sigreturn failed, exit */
21428029b68SRuslan Bukin	li	t0, SYS_exit
21528029b68SRuslan Bukin	ecall
21628029b68SRuslan Bukin
21728029b68SRuslan Bukin	j	1b
21828029b68SRuslan BukinEND(sigcode)
21928029b68SRuslan Bukin	/* This may be copied to the stack, keep it 16-byte aligned */
22028029b68SRuslan Bukin	.align	3
22128029b68SRuslan Bukinesigcode:
22228029b68SRuslan Bukin
22328029b68SRuslan Bukin	.data
22428029b68SRuslan Bukin	.align	3
22528029b68SRuslan Bukin	.global	szsigcode
22628029b68SRuslan Bukinszsigcode:
22728029b68SRuslan Bukin	.quad	esigcode - sigcode
22828029b68SRuslan Bukin
22928029b68SRuslan Bukin	.align	12
23028029b68SRuslan Bukinpagetable_l1:
23128029b68SRuslan Bukin	.space	PAGE_SIZE
23228029b68SRuslan Bukinpagetable_l2:
23328029b68SRuslan Bukin	.space	PAGE_SIZE
23402a37128SRuslan Bukinpagetable_l2_devmap:
23502a37128SRuslan Bukin	.space	PAGE_SIZE
2365f8228b2SRuslan Bukin
237af19cc59SRuslan Bukin        .align 3
238af19cc59SRuslan Bukinvirt_map:
239af19cc59SRuslan Bukin        .quad   virt_map
240af19cc59SRuslan Bukin
241af19cc59SRuslan Bukin	/* Not in use, but required for linking. */
242af19cc59SRuslan Bukin	.align 3
243af19cc59SRuslan Bukin	.globl __global_pointer$
244af19cc59SRuslan Bukin__global_pointer$:
245af19cc59SRuslan Bukin	.space	8
24628029b68SRuslan Bukin
24728029b68SRuslan Bukin	.globl init_pt_va
24828029b68SRuslan Bukininit_pt_va:
24928029b68SRuslan Bukin	.quad pagetable_l2	/* XXX: Keep page tables VA */
25028029b68SRuslan Bukin
25117696c12SRuslan Bukin#ifndef SMP
25217696c12SRuslan BukinENTRY(mpentry)
25317696c12SRuslan Bukin1:
25417696c12SRuslan Bukin	wfi
25517696c12SRuslan Bukin	j	1b
25617696c12SRuslan BukinEND(mpentry)
25717696c12SRuslan Bukin#else
25817696c12SRuslan Bukin/*
25917696c12SRuslan Bukin * mpentry(unsigned long)
26017696c12SRuslan Bukin *
26117696c12SRuslan Bukin * Called by a core when it is being brought online.
26217696c12SRuslan Bukin */
26317696c12SRuslan BukinENTRY(mpentry)
264af19cc59SRuslan Bukin	/* Setup stack pointer */
265af19cc59SRuslan Bukin	la	t0, secondary_stacks
266af19cc59SRuslan Bukin	li	t1, (PAGE_SIZE * KSTACK_PAGES)
267af19cc59SRuslan Bukin	mulw	t1, t1, s10
268af19cc59SRuslan Bukin	add	t0, t0, t1
269af19cc59SRuslan Bukin	sub	t0, t0, s9
270af19cc59SRuslan Bukin	li	t1, KERNBASE
271af19cc59SRuslan Bukin	add	sp, t0, t1
272af19cc59SRuslan Bukin
273af19cc59SRuslan Bukin	/* Setup supervisor trap vector */
274af19cc59SRuslan Bukin	la	t0, mpva
275af19cc59SRuslan Bukin	sub	t0, t0, s9
276af19cc59SRuslan Bukin	li	t1, KERNBASE
277af19cc59SRuslan Bukin	add	t0, t0, t1
278af19cc59SRuslan Bukin	csrw	stvec, t0
279af19cc59SRuslan Bukin
280af19cc59SRuslan Bukin	/* Set page tables base register */
281af19cc59SRuslan Bukin	la	s2, pagetable_l1
282af19cc59SRuslan Bukin	srli	s2, s2, PAGE_SHIFT
283af19cc59SRuslan Bukin	li	t0, SATP_MODE_SV39
284af19cc59SRuslan Bukin	or	s2, s2, t0
285af19cc59SRuslan Bukin	sfence.vma
286af19cc59SRuslan Bukin	csrw	sptbr, s2
287af19cc59SRuslan Bukinmpva:
288af19cc59SRuslan Bukin	/* Setup supervisor trap vector */
289af19cc59SRuslan Bukin	la	t0, cpu_exception_handler
290af19cc59SRuslan Bukin	csrw	stvec, t0
291af19cc59SRuslan Bukin
292af19cc59SRuslan Bukin	/* Ensure sscratch is zero */
293af19cc59SRuslan Bukin	li	t0, 0
294af19cc59SRuslan Bukin	csrw	sscratch, t0
29517696c12SRuslan Bukin	/*
29617696c12SRuslan Bukin	 * Calculate the offset to __riscv_boot_ap
29717696c12SRuslan Bukin	 * for current core, cpuid in a0.
29817696c12SRuslan Bukin	 */
29917696c12SRuslan Bukin	li	t1, 4
30017696c12SRuslan Bukin	mulw	t1, t1, a0
30117696c12SRuslan Bukin	/* Get pointer */
30217696c12SRuslan Bukin	la	t0, __riscv_boot_ap
30317696c12SRuslan Bukin	add	t0, t0, t1
30417696c12SRuslan Bukin
30517696c12SRuslan Bukin1:
30617696c12SRuslan Bukin	/* Wait the kernel to be ready */
30717696c12SRuslan Bukin	lw	t1, 0(t0)
30817696c12SRuslan Bukin	beqz	t1, 1b
30917696c12SRuslan Bukin
31017696c12SRuslan Bukin	call	init_secondary
31117696c12SRuslan BukinEND(mpentry)
31217696c12SRuslan Bukin#endif
313