xref: /freebsd/sys/riscv/riscv/locore.S (revision b626c976)
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
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	/* 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
159a9063ba1SRuslan Bukin
160a9063ba1SRuslan Bukin	.align 2
161af19cc59SRuslan Bukinva:
162af19cc59SRuslan Bukin
163af19cc59SRuslan Bukin	/* Setup supervisor trap vector */
164af19cc59SRuslan Bukin	la	t0, cpu_exception_handler
165af19cc59SRuslan Bukin	csrw	stvec, t0
166af19cc59SRuslan Bukin
167af19cc59SRuslan Bukin	/* Ensure sscratch is zero */
168af19cc59SRuslan Bukin	li	t0, 0
169af19cc59SRuslan Bukin	csrw	sscratch, t0
17028029b68SRuslan Bukin
17128029b68SRuslan Bukin	/* Initialize stack pointer */
17228029b68SRuslan Bukin	la	s3, initstack_end
17328029b68SRuslan Bukin	mv	sp, s3
17428029b68SRuslan Bukin	addi	sp, sp, -PCB_SIZE
17528029b68SRuslan Bukin
17628029b68SRuslan Bukin	/* Clear BSS  */
17728029b68SRuslan Bukin	la	a0, _C_LABEL(__bss_start)
17828029b68SRuslan Bukin	la	s1, _C_LABEL(_end)
17928029b68SRuslan Bukin1:
18028029b68SRuslan Bukin	sd	zero, 0(a0)
18128029b68SRuslan Bukin	addi	a0, a0, 8
18228029b68SRuslan Bukin	bltu	a0, s1, 1b
18328029b68SRuslan Bukin
18428029b68SRuslan Bukin	/* Fill riscv_bootparams */
185af19cc59SRuslan Bukin	addi	sp, sp, -40
1865f8228b2SRuslan Bukin
18728029b68SRuslan Bukin	la	t0, pagetable_l1
18828029b68SRuslan Bukin	sd	t0, 0(sp) /* kern_l1pt */
189af19cc59SRuslan Bukin	sd	s9, 8(sp) /* kern_phys */
1905f8228b2SRuslan Bukin
19128029b68SRuslan Bukin	la	t0, initstack_end
192af19cc59SRuslan Bukin	sd	t0, 16(sp) /* kern_stack */
193af19cc59SRuslan Bukin
194af19cc59SRuslan Bukin	li	t0, (VM_MAX_KERNEL_ADDRESS - 2 * L2_SIZE)
195af19cc59SRuslan Bukin	sd	t0, 24(sp) /* dtbp_virt */
196af19cc59SRuslan Bukin	sd	s11, 32(sp) /* dtbp_phys */
19728029b68SRuslan Bukin
19828029b68SRuslan Bukin	mv	a0, sp
19928029b68SRuslan Bukin	call	_C_LABEL(initriscv)	/* Off we go */
20028029b68SRuslan Bukin	call	_C_LABEL(mi_startup)
20128029b68SRuslan Bukin
20228029b68SRuslan Bukin	.align  4
20328029b68SRuslan Bukininitstack:
20428029b68SRuslan Bukin	.space  (PAGE_SIZE * KSTACK_PAGES)
20528029b68SRuslan Bukininitstack_end:
20628029b68SRuslan Bukin
20728029b68SRuslan BukinENTRY(sigcode)
20828029b68SRuslan Bukin	mv	a0, sp
20928029b68SRuslan Bukin	addi	a0, a0, SF_UC
21028029b68SRuslan Bukin
21128029b68SRuslan Bukin1:
21228029b68SRuslan Bukin	li	t0, SYS_sigreturn
21328029b68SRuslan Bukin	ecall
21428029b68SRuslan Bukin
21528029b68SRuslan Bukin	/* sigreturn failed, exit */
21628029b68SRuslan Bukin	li	t0, SYS_exit
21728029b68SRuslan Bukin	ecall
21828029b68SRuslan Bukin
21928029b68SRuslan Bukin	j	1b
22028029b68SRuslan BukinEND(sigcode)
22128029b68SRuslan Bukin	/* This may be copied to the stack, keep it 16-byte aligned */
22228029b68SRuslan Bukin	.align	3
22328029b68SRuslan Bukinesigcode:
22428029b68SRuslan Bukin
22528029b68SRuslan Bukin	.data
22628029b68SRuslan Bukin	.align	3
22728029b68SRuslan Bukin	.global	szsigcode
22828029b68SRuslan Bukinszsigcode:
22928029b68SRuslan Bukin	.quad	esigcode - sigcode
23028029b68SRuslan Bukin
23128029b68SRuslan Bukin	.align	12
23228029b68SRuslan Bukinpagetable_l1:
23328029b68SRuslan Bukin	.space	PAGE_SIZE
23428029b68SRuslan Bukinpagetable_l2:
23528029b68SRuslan Bukin	.space	PAGE_SIZE
23602a37128SRuslan Bukinpagetable_l2_devmap:
23702a37128SRuslan Bukin	.space	PAGE_SIZE
2385f8228b2SRuslan Bukin
239af19cc59SRuslan Bukin        .align 3
240af19cc59SRuslan Bukinvirt_map:
241af19cc59SRuslan Bukin        .quad   virt_map
242af19cc59SRuslan Bukin
243af19cc59SRuslan Bukin	/* Not in use, but required for linking. */
244af19cc59SRuslan Bukin	.align 3
245af19cc59SRuslan Bukin	.globl __global_pointer$
246af19cc59SRuslan Bukin__global_pointer$:
247af19cc59SRuslan Bukin	.space	8
24828029b68SRuslan Bukin
24928029b68SRuslan Bukin	.globl init_pt_va
25028029b68SRuslan Bukininit_pt_va:
25128029b68SRuslan Bukin	.quad pagetable_l2	/* XXX: Keep page tables VA */
25228029b68SRuslan Bukin
25317696c12SRuslan Bukin#ifndef SMP
25417696c12SRuslan BukinENTRY(mpentry)
25517696c12SRuslan Bukin1:
25617696c12SRuslan Bukin	wfi
25717696c12SRuslan Bukin	j	1b
25817696c12SRuslan BukinEND(mpentry)
25917696c12SRuslan Bukin#else
26017696c12SRuslan Bukin/*
26117696c12SRuslan Bukin * mpentry(unsigned long)
26217696c12SRuslan Bukin *
26317696c12SRuslan Bukin * Called by a core when it is being brought online.
26417696c12SRuslan Bukin */
26517696c12SRuslan BukinENTRY(mpentry)
266*b626c976SRuslan Bukin	/*
267*b626c976SRuslan Bukin	 * Calculate the offset to __riscv_boot_ap
268*b626c976SRuslan Bukin	 * for the current core, cpuid is in a0.
269*b626c976SRuslan Bukin	 */
270*b626c976SRuslan Bukin	li	t1, 4
271*b626c976SRuslan Bukin	mulw	t1, t1, a0
272*b626c976SRuslan Bukin	/* Get the pointer */
273*b626c976SRuslan Bukin	la	t0, __riscv_boot_ap
274*b626c976SRuslan Bukin	add	t0, t0, t1
275*b626c976SRuslan Bukin
276*b626c976SRuslan Bukin1:
277*b626c976SRuslan Bukin	/* Wait the kernel to be ready */
278*b626c976SRuslan Bukin	lw	t1, 0(t0)
279*b626c976SRuslan Bukin	beqz	t1, 1b
280*b626c976SRuslan Bukin
281af19cc59SRuslan Bukin	/* Setup stack pointer */
282af19cc59SRuslan Bukin	la	t0, secondary_stacks
283af19cc59SRuslan Bukin	li	t1, (PAGE_SIZE * KSTACK_PAGES)
284af19cc59SRuslan Bukin	mulw	t1, t1, s10
285af19cc59SRuslan Bukin	add	t0, t0, t1
286af19cc59SRuslan Bukin	sub	t0, t0, s9
287af19cc59SRuslan Bukin	li	t1, KERNBASE
288af19cc59SRuslan Bukin	add	sp, t0, t1
289af19cc59SRuslan Bukin
290af19cc59SRuslan Bukin	/* Setup supervisor trap vector */
291af19cc59SRuslan Bukin	la	t0, mpva
292af19cc59SRuslan Bukin	sub	t0, t0, s9
293af19cc59SRuslan Bukin	li	t1, KERNBASE
294af19cc59SRuslan Bukin	add	t0, t0, t1
295af19cc59SRuslan Bukin	csrw	stvec, t0
296af19cc59SRuslan Bukin
297af19cc59SRuslan Bukin	/* Set page tables base register */
298af19cc59SRuslan Bukin	la	s2, pagetable_l1
299af19cc59SRuslan Bukin	srli	s2, s2, PAGE_SHIFT
300af19cc59SRuslan Bukin	li	t0, SATP_MODE_SV39
301af19cc59SRuslan Bukin	or	s2, s2, t0
302af19cc59SRuslan Bukin	sfence.vma
303af19cc59SRuslan Bukin	csrw	sptbr, s2
304a9063ba1SRuslan Bukin
305a9063ba1SRuslan Bukin	.align 2
306af19cc59SRuslan Bukinmpva:
307af19cc59SRuslan Bukin	/* Setup supervisor trap vector */
308af19cc59SRuslan Bukin	la	t0, cpu_exception_handler
309af19cc59SRuslan Bukin	csrw	stvec, t0
310af19cc59SRuslan Bukin
311af19cc59SRuslan Bukin	/* Ensure sscratch is zero */
312af19cc59SRuslan Bukin	li	t0, 0
313af19cc59SRuslan Bukin	csrw	sscratch, t0
31417696c12SRuslan Bukin
31517696c12SRuslan Bukin	call	init_secondary
31617696c12SRuslan BukinEND(mpentry)
31717696c12SRuslan Bukin#endif
318