-/* $OpenBSD: locore.S,v 1.12 2021/06/29 21:27:53 kettenis Exp $ */
+/* $OpenBSD: locore.S,v 1.13 2021/07/02 10:42:22 kettenis Exp $ */
/*-
* Copyright (c) 2015-2018 Ruslan Bukin <br@bsdpad.com>
* SUCH DAMAGE.
*/
-#include <assym.h>
+#include "assym.h"
+
#include <sys/syscall.h>
#include <machine/asm.h>
#include <machine/param.h>
#include <machine/vmparam.h>
-#include <machine/trap.h>
#include <machine/riscvreg.h>
#include <machine/pte.h>
+#define VM_EARLY_DTB_ADDRESS (VM_MAX_KERNEL_ADDRESS - (2 * L2_SIZE))
.globl kernbase
.set kernbase, KERNBASE
- /* Reset vector */
.text
+/*
+ * Main entry point. Arguments are as follows:
+ * - a0 = esym
+ * - a2 = dtbp
+ *
+ * It is expected that only a single CPU will enter here.
+ */
.globl _start_kern_bootstrap
_start_kern_bootstrap:
lla gp, __global_pointer$
.option pop
- /* Get the physical address kernel loaded to */
- lla t0, virt_map //virt_map is a phy addr where its own va is stored.
- ld t1, 0(t0)
- sub t1, t1, t0 //t1 = t1 - t0 = va - pa, va<-->pa offset
- li t2, KERNBASE //KERNBASE is virtual addr
- sub s9, t2, t1 //s9 = physmem base of kernel
-
/*
- * EFIBOOT passes:
- * a0 = esym
- * a1 = 0
- * a2 = dtb
+ * Page tables setup
*/
- la t0, esym
- add a3, a0, t1
- sd a3, 0(t0)
- mv a1, a2
+ /* Get the kernel's load address */
+ jal get_physmem
- /*
- * Page tables
- */
+ /* Add L1 entry for kernel */
+ lla s1, pagetable_l1
+ lla s2, pagetable_l2 /* Link to next level PN */
+ srli s2, s2, PAGE_SHIFT
- /* step0) Identity map kernel @ 0x80000000 */
- /* Build PTE for 1 GiB identity-mapped gigapage */
- lla s1, pagetable_l1 //phy addr
- mv s2, s9 //phy addr
- li t0, 0xffffffffc0000000
- and s2, s2, t0
- srli s2, s2, PAGE_SHIFT //12, 4K page
- slli t5, s2, PTE_PPN0_S //10bit Phys Mem Attribute
- li t4, (PTE_KERN | PTE_X) //flag bit
- or t6, t4, t5 //t6 now is PTE for a 1 GiB gigapage
-
- /* Calculate VPN[2] for 1 GiB identity-mapped gigapage */
- mv a5, s9 //va -- identity mapped
- srli a5, a5, L1_SHIFT //30, remaining va[63:30]
- andi a5, a5, 0x1ff //only use va[38:30] as VPN[2], =0x002
-
- /* Store L1 PTE entry */
+ li a5, KERNBASE
+ srli a5, a5, L1_SHIFT /* >> L1_SHIFT */
+ andi a5, a5, 0x1ff /* & 0x1ff */
+ li t4, PTE_V
+ slli t5, s2, PTE_PPN0_S /* (s2 << PTE_PPN0_S) */
+ or t6, t4, t5
+
+ /* Store L1 PTE entry to position */
li a6, PTE_SIZE
mulw a5, a5, a6
add t0, s1, a5
- mv s8, t0 // Store address in L1 Page Table to unmap later
sd t6, (t0)
- /* step1) Add L1 entry for kernel */
-
- //calc PTE based on pa
- lla s1, pagetable_l1 //phy addr
- lla s2, pagetable_l2
- srli s2, s2, PAGE_SHIFT //12, 4K page
- slli t5, s2, PTE_PPN0_S //10bit Phys Mem Attribute
- li t4, PTE_V //PTE valid
- or t6, t4, t5 //t6 now is the PTE for a level 2 page table
-
- //calc VPN[2] based on va
- li a5, KERNBASE //va
- srli a5, a5, L1_SHIFT //30
- andi a5, a5, 0x1ff //va[38:30] as VPN[2],==0x100
-
- /* Store L1 PTE entry */
- li a6, PTE_SIZE //8 Bytes
- mulw a5, a5, a6 //distance in unit of bytes
- add t0, s1, a5 //s1 is L1 table base pa
- sd t6, (t0) //PTE of a l2 page table is populated to l1 page table
-
-
- /* step2) Level 2 superpages (512 x 2MiB) */ //mega pages: two-level page table
+ /* Level 2 superpages (512 x 2MiB) */
lla s1, pagetable_l2
- //calc PTE
srli t4, s9, L2_SHIFT /* Div physmem base by 2 MiB */
- li t2, 512 /* Build totally 512 entries */
+ li t2, 512 /* Build 512 entries */
add t3, t4, t2
- li t5, 0
-2:
li t0, (PTE_KERN | PTE_X)
- slli t2, t4, PTE_PPN1_S //19
- or t5, t0, t2 //PTE contructed
+1:
+ slli t2, t4, PTE_PPN1_S /* << PTE_PPN1_S */
+ or t5, t0, t2
sd t5, (s1) /* Store PTE entry to position */
-
- //iterating
addi s1, s1, PTE_SIZE
- addi t4, t4, 1
- bltu t4, t3, 2b //512 entries
+ addi t4, t4, 1
+ bltu t4, t3, 1b
- /* step3) Create an L1 entry for early devmap */
- lla s1, pagetable_l1 //pa
+ /* Create an L1 page for early devmap */
+ lla s1, pagetable_l1
+ lla s2, pagetable_l2_devmap /* Link to next level PN */
+ srli s2, s2, PAGE_SHIFT
- //calculate PTE based on pa: (PPN) + privilege/permission + ...
- lla s2, pagetable_l2_devmap /* Link to next level PN */ //pa
- srli s2, s2, PAGE_SHIFT //12, --> PPN
- slli t5, s2, PTE_PPN0_S //10, PMA
+ li a5, (VM_MAX_KERNEL_ADDRESS - L2_SIZE)
+ srli a5, a5, L1_SHIFT /* >> L1_SHIFT */
+ andi a5, a5, 0x1ff /* & 0x1ff */
li t4, PTE_V
- or t6, t4, t5 //PTE contructed
-
- //calculate VPN[2] index based on va
- li a5, (VM_MAX_KERNEL_ADDRESS - L2_SIZE)//devmap is at kernel mem top, va
- srli a5, a5, L1_SHIFT //30
- andi a5, a5, 0x1ff //index using va[38:30]
+ slli t5, s2, PTE_PPN0_S /* (s2 << PTE_PPN0_S) */
+ or t6, t4, t5
/* Store single level1 PTE entry to position */
li a6, PTE_SIZE
- mulw a5, a5, a6 //offset in Bytes
- add t0, s1, a5 //find the physical add to write
+ mulw a5, a5, a6
+ add t0, s1, a5
sd t6, (t0)
-
- /* step4) Create ONE L2 superpage 2MB for DTB */
+ /* Create an L2 page superpage for DTB */
lla s1, pagetable_l2_devmap
+ mv s2, a1
+ srli s2, s2, PAGE_SHIFT
+ /* Mask off any bits that aren't aligned */
+ andi s2, s2, ~((1 << (PTE_PPN1_S - PTE_PPN0_S)) - 1)
- //calc PTE based on pa
- mv s2, a1 //dtb
- li t0, 0xffffffffffe00000
- and s2, s2, t0
- srli s2, s2, PAGE_SHIFT //12
- slli t2, s2, PTE_PPN0_S //10
li t0, (PTE_KERN)
- or t0, t0, t2 //PTE contructed
+ slli t2, s2, PTE_PPN0_S /* << PTE_PPN0_S */
+ or t0, t0, t2
/* Store PTE entry to position */
li a6, PTE_SIZE
/* Page tables END */
-
- /* Calculate virtual address of the first instruction after enable paging */
- lla s3, va //va is a physical addr!
- sub s3, s3, s9 //offset comparing to phymem base
- li t0, KERNBASE //virt addr
- add s3, s3, t0
+ /* Setup supervisor trap vector */
+ lla t0, va
+ sub t0, t0, s9
+ li t1, KERNBASE
+ add t0, t0, t1
+ csrw stvec, t0
/* Set page tables base register */
- lla s2, pagetable_l1 //pa
- srli s2, s2, PAGE_SHIFT //12, --> PPN
- li t0, SATP_MODE_SV39 //satp[63:60] = 1000b, enable paging!
+ lla s2, pagetable_l1
+ srli s2, s2, PAGE_SHIFT
+ li t0, SATP_MODE_SV39
or s2, s2, t0
- sfence.vma //Supervisor Fence for Virtual Memory, to flush TLB
+ sfence.vma
csrw satp, s2
- jr s3
.align 2
va:
lla gp, __global_pointer$
.option pop
- /* Unmap the identity mapped kernel gigapage */
- sd x0, (s8) // s8 is addr of pte for identity mapped kernel
- sfence.vma // Flush the TLB. Goodbye identity mapped kernel!
-
/* Setup supervisor trap vector */
la t0, cpu_exception_handler
csrw stvec, t0
csrw sscratch, t0
/* Initialize stack pointer */
- la s3, initstack_end
- mv sp, s3
+ la sp, initstack_end
- /* Allocate space for thread0 PCB and riscv_bootparams */
- addi sp, sp, -(PCB_SIZEOF + RISCV_BOOTPARAMS_SIZEOF) & ~STACKALIGNBYTES
+ /* Clear frame pointer */
+ mv s0, zero
+
+ /* Allocate space for riscv_bootparams */
+ addi sp, sp, -RISCV_BOOTPARAMS_SIZEOF
+ andi sp, sp, ~STACKALIGNBYTES
/* Clear BSS */
- la s0, _C_LABEL(__bss_start)
- la s1, _C_LABEL(_end)
+ la t0, _C_LABEL(__bss_start)
+ la t1, _C_LABEL(_end)
1:
- sd zero, 0(s0)
- addi s0, s0, 8
- bltu s0, s1, 1b
+ sd zero, 0(t0)
+ addi t0, t0, 8
+ bltu t0, t1, 1b
/* Fill riscv_bootparams */
- addi sp, sp, -RISCV_BOOTPARAMS_SIZEOF
-
la t0, pagetable_l1
- sd t0, KERN_L1PT(sp)
-
- li t0, KERNBASE
- sub t0, s9, t0 //offset: PA - VA, used in pmap_*
- sd t0, KERN_DELTA(sp)
+ sd t0, RISCV_BOOTPARAMS_KERN_L1PT(sp)
+ sd s9, RISCV_BOOTPARAMS_KERN_PHYS(sp)
la t0, initstack
- sd t0, KERN_STACK(sp)
+ sd t0, RISCV_BOOTPARAMS_KERN_STACK(sp)
- li t0, (VM_MAX_KERNEL_ADDRESS - 2 * L2_SIZE) // XXX Why 2?
- li t1, 0x1fffff
+ li t0, (VM_EARLY_DTB_ADDRESS)
+ /* Add offset of DTB within superpage */
+ li t1, (L2_OFFSET)
and t1, a1, t1
add t0, t0, t1
- sd t0, DTBP_VIRT(sp)
- sd a1, DTBP_PHYS(sp)
+ sd t0, RISCV_BOOTPARAMS_DTBP_VIRT(sp)
+ sd a1, RISCV_BOOTPARAMS_DTBP_PHYS(sp)
+
+ /* Set esym to virtual addres of symbol table end */
+ lla t0, esym
+ sub t1, a0, s9
+ li t2, KERNBASE
+ add t1, t1, t2
+ sd t1, 0(t0)
- mv a0, sp //stack setup, can call C now!
- call _C_LABEL(initriscv) // Off we go, defined in machdep.c
- call _C_LABEL(main) //defined in openbsd/kern/init_main.c
+ mv a0, sp
+ call _C_LABEL(initriscv) /* Off we go */
+ call _C_LABEL(main)
/*
* Get the physical address the kernel is loaded to. Returned in s9.
.text
ENTRY(sigcode)
mv a0, sp
- addi a0, a0, SF_SC //actual saved context
+ addi a0, a0, SF_SC
li t0, SYS_sigreturn
ecall
+
.globl _C_LABEL(sigcoderet)
_C_LABEL(sigcoderet):
/* sigreturn failed, exit */
.globl _C_LABEL(esigcode)
_C_LABEL(esigcode):
-
.data
.global _C_LABEL(esym)
-_C_LABEL(esym): .quad _C_LABEL(end)
-
+_C_LABEL(esym):
+ .quad _C_LABEL(end)
.align 12
pagetable_l1:
.space PAGE_SIZE
- .globl pagetable_l2
pagetable_l2:
.space PAGE_SIZE
pagetable_l2_devmap:
virt_map:
.quad virt_map
- .globl init_pt_va
-init_pt_va:
- .quad pagetable_l2 /* XXX: Keep page tables VA */
-
#ifdef MULTIPROCESSOR
.text
-/* $OpenBSD: machdep.c,v 1.23 2021/06/30 22:20:56 kettenis Exp $ */
+/* $OpenBSD: machdep.c,v 1.24 2021/07/02 10:42:22 kettenis Exp $ */
/*
* Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
void
initriscv(struct riscv_bootparams *rbp)
{
- long kernbase = (long)_start & ~PAGE_MASK;
- long kvo = rbp->kern_delta;
paddr_t memstart, memend;
+ paddr_t ramstart, ramend;
+ paddr_t start, end;
vaddr_t vstart;
void *config = (void *)rbp->dtbp_virt;
void *fdt = NULL;
paddr_t fdt_start = (paddr_t)rbp->dtbp_phys;
size_t fdt_size;
+ struct fdt_reg reg;
+ void *node;
EFI_PHYSICAL_ADDRESS system_table = 0;
int (*map_func_save)(bus_space_tag_t, bus_addr_t, bus_size_t, int,
bus_space_handle_t *);
- paddr_t ramstart, ramend;
- paddr_t start, end;
int i;
/* Set the per-CPU pointer. */
__asm volatile("mv tp, %0" :: "r"(&cpu_info_primary));
- // NOTE that 1GB of ram is mapped in by default in
- // the bootstrap memory config, so nothing is necessary
- // until pmap_bootstrap_finalize is called??
-
- //NOTE: FDT is already mapped (rbp->dtbp_virt => rbp->dtbp_phys)
- // Initialize the Flattened Device Tree
if (!fdt_init(config) || fdt_get_size(config) == 0)
panic("initriscv: no FDT");
fdt_size = fdt_get_size(config);
- struct fdt_reg reg;
- void *node;
-
node = fdt_find_node("/cpus");
if (node != NULL) {
char *prop;
}
/* The bootloader has loaded us into a 64MB block. */
- memstart = KERNBASE + kvo;
+ memstart = rbp->kern_phys;
memend = memstart + 64 * 1024 * 1024;
- /* XXX */
- kernbase = KERNBASE;
-
/* Bootstrap enough of pmap to enter the kernel proper. */
- vstart = pmap_bootstrap(kvo, rbp->kern_l1pt,
- kernbase, esym, memstart, memend, ramstart, ramend);
+ vstart = pmap_bootstrap(rbp->kern_phys - KERNBASE, rbp->kern_l1pt,
+ KERNBASE, esym, memstart, memend, ramstart, ramend);
proc0paddr = (struct user *)rbp->kern_stack;