Module Name:    src
Committed By:   skrll
Date:           Tue Sep 20 07:18:24 UTC 2022

Modified Files:
        src/sys/arch/riscv/include: locore.h pmap.h vmparam.h
        src/sys/arch/riscv/riscv: genassym.cf locore.S pmap_machdep.c
            riscv_machdep.c
Added Files:
        src/sys/arch/riscv/include: machdep.h

Log Message:
Checkpoint WIP.

QEMU RV64 virt can boot into virtual mode

OpenSBI v1.0
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|____/_____|
        | |
        |_|

Platform Name             : riscv-virtio,qemu
Platform Features         : medeleg
Platform HART Count       : 1
Platform IPI Device       : aclint-mswi
Platform Timer Device     : aclint-mtimer @ 10000000Hz
Platform Console Device   : uart8250
Platform HSM Device       : ---
Platform Reboot Device    : sifive_test
Platform Shutdown Device  : sifive_test
Firmware Base             : 0x80000000
Firmware Size             : 252 KB
Runtime SBI Version       : 0.3

Domain0 Name              : root
Domain0 Boot HART         : 0
Domain0 HARTs             : 0*
Domain0 Region00          : 0x0000000002000000-0x000000000200ffff (I)
Domain0 Region01          : 0x0000000080000000-0x000000008003ffff ()
Domain0 Region02          : 0x0000000000000000-0xffffffffffffffff (R,W,X)
Domain0 Next Address      : 0x0000000080200000
Domain0 Next Arg1         : 0x00000000bfe00000
Domain0 Next Mode         : S-mode
Domain0 SysReset          : yes

Boot HART ID              : 0
Boot HART Domain          : root
Boot HART ISA             : rv64imafdcsuh
Boot HART Features        : scounteren,mcounteren,mcountinhibit,time
Boot HART PMP Count       : 16
Boot HART PMP Granularity : 4
Boot HART PMP Address Bits: 54
Boot HART MHPM Count      : 16
Boot HART MIDELEG         : 0x0000000000001666
Boot HART MEDELEG         : 0x0000000000f0b509

------------
NetBSD start

sp:      0x0000_0000_80a0_2000
pc:      0x0000_0000_8020_0090
hart:    0x0000_0000_0000_0000
dtb:     0x0000_0000_bfe0_0000
l1:      0x0000_0000_80a0_2000
l2:      0x0000_0000_80a0_3000
uspace:  0x0000_0000_80a0_0000
bootstk: 0x0000_0000_80a0_2000
vtopdiff:0xffff_ffbf_7fe0_0000

bss:     0x0000_0000_808a_8bdc - 0x0000_0000_80a0_4000

0x0000_0000_80a0_3800: 0x0000_0000_2028_0821

kern 0x0000_0000_80a0_2000: 0x0000_0000_2008_002f
kern 0x0000_0000_80a0_2008: 0x0000_0000_2010_002f
kern 0x0000_0000_80a0_2010: 0x0000_0000_2018_002f
kern 0x0000_0000_80a0_2018: 0x0000_0000_2020_002f
kern 0x0000_0000_80a0_2020: 0x0000_0000_2028_002f
kern 0x0000_0000_80a0_2028: 0x0000_0000_2030_002f
kern 0x0000_0000_80a0_2030: 0x0000_0000_2038_002f
kern 0x0000_0000_80a0_2038: 0x0000_0000_2040_002f
kern 0x0000_0000_80a0_2040: 0x0000_0000_2048_002f
kern 0x0000_0000_80a0_2048: 0x0000_0000_2050_002f
kern 0x0000_0000_80a0_2050: 0x0000_0000_2058_002f
kern 0x0000_0000_80a0_2058: 0x0000_0000_2060_002f
kern 0x0000_0000_80a0_2060: 0x0000_0000_2068_002f
kern 0x0000_0000_80a0_2068: 0x0000_0000_2070_002f
kern 0x0000_0000_80a0_2070: 0x0000_0000_2078_002f
kern 0x0000_0000_80a0_2078: 0x0000_0000_2080_002f
dtb  0x0000_0000_80a0_2080: 0x0000_0000_2ff8_0027
PM
[   1.0000000] FDT<0xffffffc002000000>
[   1.0000000] consinit ok
[   1.0000000] NetBSD/riscv (fdt) booting ...
[   1.0000000] FDT /memory @ 0x80000000 size 0x40000000
[   1.0000000] init_riscv: memory start 80000000 end c0000000 (len 40000000)
[   1.0000000] bootargs: root=ld4a -v -x
[   1.0000000] bootflag 'r' not recognised
[   1.0000000] bootflag 'o' not recognised
[   1.0000000] bootflag 'o' not recognised
[   1.0000000] bootflag 't' not recognised
[   1.0000000] bootflag '=' not recognised
[   1.0000000] bootflag 'l' not recognised
[   1.0000000] bootflag ' ' not recognised
[   1.0000000] bootflag ' ' not recognised
[   1.0000000] ------------------------------------------
[   1.0000000]            kern_vtopdiff = 0xffffffbf7fe00000
[   1.0000000]             memory_start = 0x        80000000
[   1.0000000]               memory_end = 0x        c0000000
[   1.0000000]              memory_size = 0x        40000000
[   1.0000000]           kernstart_phys = 0x        80200000
[   1.0000000]             kernend_phys = 0x        80a00000
[   1.0000000]    VM_MIN_KERNEL_ADDRESS = 0xffffffc000000000
[   1.0000000]           kernstart_mega = 0xffffffc000000000
[   1.0000000]                kernstart = 0xffffffc000000000
[   1.0000000]                  kernend = 0xffffffc000800000
[   1.0000000]             kernend_mega = 0xffffffc000800000
[   1.0000000]    VM_MAX_KERNEL_ADDRESS = 0xffffffd000000000
[   1.0000000] ------------------------------------------
[   1.0000000] panic: kernel diagnostic assertion "msgbufaddr != 0" failed: 
file "/home/nick/netbsd/nbcvs/src/sys/arch/riscv/riscv/riscv_machdep.c", line 
564


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/riscv/include/locore.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/riscv/include/machdep.h
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/riscv/include/pmap.h \
    src/sys/arch/riscv/include/vmparam.h
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/riscv/riscv/genassym.cf
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/riscv/riscv/locore.S
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/riscv/riscv/pmap_machdep.c
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/riscv/riscv/riscv_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/riscv/include/locore.h
diff -u src/sys/arch/riscv/include/locore.h:1.10 src/sys/arch/riscv/include/locore.h:1.11
--- src/sys/arch/riscv/include/locore.h:1.10	Tue Oct  5 11:01:49 2021
+++ src/sys/arch/riscv/include/locore.h	Tue Sep 20 07:18:23 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.h,v 1.10 2021/10/05 11:01:49 jmcneill Exp $ */
+/* $NetBSD: locore.h,v 1.11 2022/09/20 07:18:23 skrll Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -216,7 +216,6 @@ void	cpu_lwp_trampoline(void);
 
 void *	cpu_sendsig_getframe(struct lwp *, int, bool *);
 
-void	init_riscv(vaddr_t, vaddr_t);
 #endif
 
 #endif /* _RISCV_LOCORE_H_ */

Index: src/sys/arch/riscv/include/pmap.h
diff -u src/sys/arch/riscv/include/pmap.h:1.9 src/sys/arch/riscv/include/pmap.h:1.10
--- src/sys/arch/riscv/include/pmap.h:1.9	Sat May  1 07:41:24 2021
+++ src/sys/arch/riscv/include/pmap.h	Tue Sep 20 07:18:23 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.h,v 1.9 2021/05/01 07:41:24 skrll Exp $ */
+/* $NetBSD: pmap.h,v 1.10 2022/09/20 07:18:23 skrll Exp $ */
 
 /*
  * Copyright (c) 2014, 2019, 2021 The NetBSD Foundation, Inc.
@@ -117,12 +117,10 @@ pmap_procwr(struct proc *p, vaddr_t va, 
 
 #define __HAVE_PMAP_MD
 struct pmap_md {
-	paddr_t md_ptbr;
+	paddr_t md_ppn;
 	pd_entry_t *md_pdetab;
 };
 
-void	pmap_bootstrap(void);
-
 struct vm_page *
 	pmap_md_alloc_poolpage(int flags);
 vaddr_t	pmap_md_map_poolpage(paddr_t, vsize_t);
@@ -132,13 +130,14 @@ bool	pmap_md_io_vaddr_p(vaddr_t);
 paddr_t	pmap_md_direct_mapped_vaddr_to_paddr(vaddr_t);
 vaddr_t	pmap_md_direct_map_paddr(paddr_t);
 void	pmap_md_init(void);
-bool	pmap_md_tlb_check_entry(void *, vaddr_t, tlb_asid_t, pt_entry_t);
 
 void	pmap_md_xtab_activate(struct pmap *, struct lwp *);
 void	pmap_md_xtab_deactivate(struct pmap *);
 void	pmap_md_pdetab_init(struct pmap *);
 bool	pmap_md_ok_to_steal_p(const uvm_physseg_t, size_t);
 
+void	pmap_bootstrap(vaddr_t kstart, vaddr_t kend);
+
 extern vaddr_t pmap_direct_base;
 extern vaddr_t pmap_direct_end;
 #define PMAP_DIRECT_MAP(pa)	(pmap_direct_base + (pa))
@@ -148,6 +147,14 @@ extern vaddr_t pmap_direct_end;
 #define MEGAPAGE_ROUND(x)	MEGAPAGE_TRUNC((x) + SEGOFSET)
 
 #ifdef __PMAP_PRIVATE
+
+static inline bool
+pmap_md_tlb_check_entry(void *ctx, vaddr_t va, tlb_asid_t asid, pt_entry_t pte)
+{
+        // TLB not walked and so not called.
+        return false;
+}
+
 static inline void
 pmap_md_page_syncicache(struct vm_page_md *mdpg, const kcpuset_t *kc)
 {
Index: src/sys/arch/riscv/include/vmparam.h
diff -u src/sys/arch/riscv/include/vmparam.h:1.9 src/sys/arch/riscv/include/vmparam.h:1.10
--- src/sys/arch/riscv/include/vmparam.h:1.9	Sat May  1 07:41:24 2021
+++ src/sys/arch/riscv/include/vmparam.h	Tue Sep 20 07:18:23 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: vmparam.h,v 1.9 2021/05/01 07:41:24 skrll Exp $	*/
+/*	$NetBSD: vmparam.h,v 1.10 2022/09/20 07:18:23 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2014, 2020 The NetBSD Foundation, Inc.
@@ -126,8 +126,15 @@
 #define VM_MAX_KERNEL_ADDRESS	((vaddr_t)-0x40000000)	/* 0xffffffffc0000000 */
 
 #endif
-#define VM_KERNEL_VM_BASE	VM_MIN_KERNEL_ADDRESS
-#define VM_KERNEL_VM_SIZE	0x2000000	 /* 32 MiB (8 / 16 megapages) */
+#define VM_KERNEL_BASE		VM_MIN_KERNEL_ADDRESS
+#define VM_KERNEL_SIZE		0x2000000	/* 32 MiB (8 / 16 megapages) */
+#define VM_KERNEL_DTB_BASE	(VM_KERNEL_BASE + VM_KERNEL_SIZE)
+#define VM_KERNEL_DTB_SIZE	0x2000000	/* 32 MiB (8 / 16 megapages) */
+
+#define VM_KERNEL_RESERVED	(VM_KERNEL_SIZE + VM_KERNEL_DTB_SIZE)
+
+#define VM_KERNEL_VM_BASE	(VM_MIN_KERNEL_ADDRESS + VM_KERNEL_RESERVED)
+#define VM_KERNEL_VM_SIZE	(VM_MAX_KERNEL_ADDRESS - VM_KERNEL_VM_BASE)
 
 #define VM_MAX_ADDRESS		VM_MAXUSER_ADDRESS
 #define VM_MAXUSER_ADDRESS32	((vaddr_t)(1UL << 31))/* 0x0000000080000000 */

Index: src/sys/arch/riscv/riscv/genassym.cf
diff -u src/sys/arch/riscv/riscv/genassym.cf:1.11 src/sys/arch/riscv/riscv/genassym.cf:1.12
--- src/sys/arch/riscv/riscv/genassym.cf:1.11	Sun Sep 11 15:31:12 2022
+++ src/sys/arch/riscv/riscv/genassym.cf	Tue Sep 20 07:18:23 2022
@@ -1,4 +1,4 @@
-#	$NetBSD: genassym.cf,v 1.11 2022/09/11 15:31:12 skrll Exp $
+#	$NetBSD: genassym.cf,v 1.12 2022/09/20 07:18:23 skrll Exp $
 
 #-
 # Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -49,18 +49,13 @@ include <uvm/uvm_extern.h>
 include <riscv/locore.h>
 include <riscv/sysreg.h>
 
-#define	SR_IM		SR_IM
-#define	SR_IM_LSHIFT	__SIZEOF_LONG__ * 8 - (ilog2(SR_IM) + 1)
-#define	SR_IM_RSHIFT	ilog2(__LOWEST_SET_BIT(SR_IM))
-#define	SR_VM		SR_VM
-#define	SR_U64		SR_U64
-#define	SR_S64		SR_S64
-#define	SR_EF		SR_EF
-#define	SR_PEI		SR_PEI
-#define	SR_EI		SR_EI
-#define	SR_PS		SR_PS
-#define	SR_S		SR_S
+
+define	SR_SPP		SR_SPP
 define	SR_SIE		SR_SIE
+define	SR_FS		SR_FS
+# define	SR_PS		SR_PS
+# define	SR_S		SR_S
+define	SR_SUM		SR_SUM
 
 define	CAUSE_SYSCALL	CAUSE_SYSCALL
 
@@ -161,6 +156,7 @@ define	FB_SR		offsetof(struct faultbuf, 
 define	PAGE_SIZE	PAGE_SIZE
 define	PAGE_MASK	PAGE_MASK
 define	PAGE_SHIFT	PAGE_SHIFT
+define	UPAGES		UPAGES
 define	USRSTACK	USRSTACK
 
 ifdef	__HAVE_FAST_SOFTINTS
@@ -186,6 +182,8 @@ define	RW_READER	RW_READER
 
 define	VM_MIN_KERNEL_ADDRESS	VM_MIN_KERNEL_ADDRESS
 define	VM_MAX_KERNEL_ADDRESS	VM_MAX_KERNEL_ADDRESS
+define	VM_KERNEL_BASE		VM_KERNEL_BASE
+define	VM_KERNEL_SIZE		VM_KERNEL_SIZE
 
 define	USPACE		USPACE
 ifdef XSEGSHIFT
@@ -196,6 +194,7 @@ define	PGSHIFT		PGSHIFT
 define	NPDEPG		NPDEPG
 define	NBSEG		NBSEG
 
+# Constants from pte.h
 define	PTE_D		PTE_D
 define	PTE_A		PTE_A
 define	PTE_G		PTE_G
@@ -205,8 +204,29 @@ define	PTE_W		PTE_W
 define	PTE_R		PTE_R
 define	PTE_V		PTE_V
 
+define	PTE_KERN	PTE_KERN
+
+define	L0_SHIFT	L0_SHIFT
+define	L1_SHIFT	L1_SHIFT
+define	L1_SIZE		L1_SIZE
+define	L1_OFFSET	L1_OFFSET
+define	L2_SHIFT	L2_SHIFT
+define	L2_SIZE		L2_SIZE
+define	L2_OFFSET	L2_OFFSET
+#define	L3_SHIFT	L3_SHIFT
+#define	L3_SIZE		L3_SIZE
+#define	L3_OFFSET	L3_OFFSET
+define	Ln_ENTRIES	Ln_ENTRIES
+define	Ln_ADDR_MASK	Ln_ADDR_MASK
+#define	PTE_PPN0_S	PTE_PPN0_S
+#define	PTE_PPN1_S	PTE_PPN1_S
+#define	PTE_PPN2_S	PTE_PPN2_S
+#define	PTE_PPN3_S	PTE_PPN3_S
+#define	PTE_SIZE	PTE_SIZE
+define	PTE_PPN_SHIFT	PTE_PPN_SHIFT
+
 define	PM_MD_PDETAB	offsetof(struct pmap, pm_md.md_pdetab)
-define	PM_MD_PTBR	offsetof(struct pmap, pm_md.md_ptbr)
+define	PM_MD_PPN	offsetof(struct pmap, pm_md.md_ppn)
 
 # for bus_space_asm
 define	BS_STRIDE		offsetof(struct bus_space, bs_stride)

Index: src/sys/arch/riscv/riscv/locore.S
diff -u src/sys/arch/riscv/riscv/locore.S:1.24 src/sys/arch/riscv/riscv/locore.S:1.25
--- src/sys/arch/riscv/riscv/locore.S:1.24	Sun Apr 10 09:50:45 2022
+++ src/sys/arch/riscv/riscv/locore.S	Tue Sep 20 07:18:23 2022
@@ -1,11 +1,11 @@
-/* $NetBSD: locore.S,v 1.24 2022/04/10 09:50:45 andvar Exp $ */
+/* $NetBSD: locore.S,v 1.25 2022/09/20 07:18:23 skrll Exp $ */
 
 /*-
- * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * Copyright (c) 2014, 2022 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
- * by Matt Thomas of 3am Software Foundry.
+ * by Matt Thomas of 3am Software Foundry, and by Nick Hudson.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,125 +29,524 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "opt_console.h"
+#include "opt_riscv_debug.h"
+
 #include <machine/asm.h>
 #include "assym.h"
 
 	.globl	_C_LABEL(exception_userexit)
 	.globl	_C_LABEL(cpu_Debugger_insn)
 
+#if defined(VERBOSE_INIT_RISCV)
+
+#define VPRINTS(string)		\
+	call	locore_prints	; \
+	.asciz string		; \
+	.align 3		; \
+
+#define VPRINTX(regno)		\
+	mv	a0, regno	; \
+	call	locore_printx
+
+#define VPRINTXNL(regno)	\
+	mv	a0, regno	; \
+	call	locore_printxnl
+
+/* Need to turn relaxation off for VPRINTS */
+	.option norelax
+
+#else
+#define VPRINTS(string)		/* nothing */
+#define VPRINTX(regno)		/* nothing */
+#define VPRINTXNL(regno)	/* nothing */
+#endif
+
+#if VM_MIN_KERNEL_ADDRESS != VM_KERNEL_BASE
+#error VM_MIN_KERNEL_ADDRESS assumed to match VM_KERNEL_BASE
+#endif
+
+/*
+ * Entry point where.
+ *    a0 is hartid
+ *    a1 is pointer to dtb (PA)
+ */
 ENTRY_NP(start)
-	// We get loaded and starting running at or near 0, not where we
-	// should be. We need to construct an initial PDETAB
+	csrw	sie, zero		// disable interrupts
+	csrw	sip, zero		// clear any pending
 
-	li	s11, VM_MAX_KERNEL_ADDRESS
-	li	s10, PAGE_SIZE
-	li	s9, USPACE
+	li	s0, SR_FS
+	csrc	sstatus, s0		// disable FP
 
 	/*
-	 * XXX XXX XXX: This is completely broken and wrong, we should map only
-	 * the kernel sections, and the direct map should be mapped later in C.
+	 * atomically swap a non-zero value into hart_boot.  If we see zero
+	 * we won in race to become BP.
 	 */
-#if 0
-#if 0
-	// The kernel doesn't use gp/_gp since we'd have to reload it on
-	// each exception.
-	PTR_LA	gp, _C_LABEL(_gp)
-#endif
+	li	s1, 1
+	la	s0, hart_boot
+
+	amoswap.w s0, s1, (s0)
+	bnez	s0, mpentry
+	/*
+	 * The BP only executes from here on.
+	 */
+	mv	s0, a0			// copy hartid
+	mv	s1, a1			// copy dtb PA
+
+	/* set the stack pointer for boot */
+	PTR_LA	s8, _C_LABEL(bootstk)
+	mv	sp, s8
+
+	VPRINTS("\n------------\nNetBSD start\n\n")
+	VPRINTS("sp:      ")
+	VPRINTXNL(sp)
+
+	VPRINTS("pc:      ")
+	auipc	a0, 0
+	VPRINTXNL(a0)
+
+	VPRINTS("hart:    ")
+	VPRINTXNL(s0)
+
+	VPRINTS("dtb:     ")
+	VPRINTXNL(s1)
+
+	/*
+	 * Calculate the difference between the VA and PA for start and
+	 * keep in s8.  Store this in kern_vtopdiff once the MMU is on.
+	 */
+	PTR_LA	s11, start
+	PTR_L	s8, .Lstart
+
+	sub	s8, s8, s11
+
+	/*
+	 * Our load address is not fixed, but our VA is.  We need to construct
+	 * an initial PDETAB.
+	 */
+
+	li	s10, PAGE_SIZE
+	li	s9, USPACE
+
+	PTR_LA	s5, _C_LABEL(lwp0uspace)
+	PTR_LA	s6, _C_LABEL(bootstk)
+
+	// The space for the inital page table is included in the kernel
+	// .bss size calculation so we know the space exists.
 
-	PTR_LA	a0, _C_LABEL(__bss_start)
-	PTR_LA	s1, _C_LABEL(_end)
 	li	a1, 0
+	PTR_LA	s2, _C_LABEL(l1_pte)
+	mv	s4, s2			// last page table
+#ifdef _LP64
+	PTR_LA	s3, _C_LABEL(l2_pte)	// s3 = second PDE page (RV64 only)
+	mv	s4, s3			// last page table
+#ifdef notyet
+	PTR_LA	s4, _C_LABEL(l3_pte)
+#endif
+#endif
+	PTR_LA	s7, _C_LABEL(mmutables_end)
+
 
-	add	s1, s1, s10		// PAGE_SIZE
-	addi	s1, s1, -1		//   -1 == PAGE_MASK
-	neg	a1, s10			// -PAGE_SIZE
-	and	s1, s1, a1		// s1 is page aligned end of kernel
-					// s1 = uarea
-	add	s2, s1, s9		// s2 = first PDE page
+	// s2	L1 PDE (SV32:4MiB megapages, SV{39,48}: 2MiB megapages)
+	// s3	L2 PDE (_LP64 SV39 only)
+	// s4	L3 PDE (_LP64 SV48 only)
+	// s5	lwp0uspace
+	// s6	bootstk
+	// s7   end of memory to clear
+
+	VPRINTS("l1:      ")
+	VPRINTXNL(s2)
 #ifdef _LP64
-	add	s3, s2, s10		// s3 = second PDE page (RV64 only)
-#else
-	mv	s3, s2
+	VPRINTS("l2:      ")
+	VPRINTXNL(s3)
+#ifdef notyet
+	VPRINTS("l3:      ")
+	VPRINTXNL(s4)
 #endif
-	add	s4, s3, s10		// s4 = first kernel PTE page
-	add	s5, s1, s9		// s5 = kernel_end
-	sub	a2, s5, a0
-	call	memset			// zero through kernel_end
-
-	// As a temporary hack, word 0 contains the amount of memory in MB
-	INT_L	a7, (zero)		// load memory size
-	slli	a7, a7, (20-PGSHIFT)	// convert MB to pages
-	PTR_LA	t0, physmem
-	INT_S	a7, (t0)		// store it in physmem
+#endif
+
+	VPRINTS("uspace:  ")
+	VPRINTXNL(s5)
+	VPRINTS("bootstk: ")
+	VPRINTXNL(s6)
+
+	VPRINTS("vtopdiff:")
+	VPRINTXNL(s8)
+
+	VPRINTS("\n\r")
+
+	VPRINTS("bss:     ")
+	PTR_LA	a0, _C_LABEL(__bss_start)
+	VPRINTX(a0)
+	VPRINTS(" - ")
+	VPRINTXNL(s7)
+
+	VPRINTS("\n\r")
+
+	// a0	start of memory to clear
+	// a1	end of memory to clear
+	PTR_LA	a0, _C_LABEL(__bss_start)
+	mv	a1, s7
+
+	call	clear_bss		// zero through kernel_end (inc. stack)
+
+	li	s7, PTE_KERN		// for megapages
+
+	// We allocated the kernel first PDE page so let's insert in the
+	// page table.
+
+	// Need to setup tables so that for
+	// sv32 : s2
+	// sv39 : s3 -> s2
+	// sv48 : s4 -> s3 -> s2
 
-	li	t4, PTE_V | PTE_SX | PTE_SW | PTE_SR | PTE_G
 #ifdef _LP64
-	REG_S	t4, 0(s2)		// keep a mapping for the first 8GB.
-	or	t0, s3, t4		// point to next page
-	or	t0, t0, PTE_T		// tranverse it.
-	REG_S	t0, -SZREG(s3)		// store in highest first level PDE
-#endif
-
-#if (VM_MIN_KERNEL_ADDRESS >> XSEGSHIFT) != (VM_MAX_KERNEL_ADDRESS >> XSEGSHIFT)
-#error VM_MIN_KERNEL_ADDRESS not in same first level PDE as VM_MAX_KERNEL_ADDRESS
-#endif
-	// We allocated the kernel first PTE page so let's insert in the
-	// page table.  For now, we assume it's in the same PDE page as the
-	// direct-mapped memory.
-	or	t0, s4, t4
-	or	t0, t0, PTE_T
-#if ((VM_MIN_KERNEL_ADDRESS >> SEGSHIFT) & (NPDEPG-1)) * SZREG
-	li	t1, ((VM_MIN_KERNEL_ADDRESS >> SEGSHIFT) & (NPDEPG-1)) * SZREG
+	srli	t0, s2, (PGSHIFT - PTE_PPN_SHIFT)
+	or	t0, t0, s7		// Assumes s2[11:0] == 0
+#if ((VM_MIN_KERNEL_ADDRESS >> XSEGSHIFT) & (NPDEPG - 1)) * SZREG
+	li	t1, ((VM_MIN_KERNEL_ADDRESS >> XSEGSHIFT) & (NPDEPG - 1)) * SZREG
+#ifdef notyet
+	add	t1, t1, s4
+#else
 	add	t1, t1, s3
+#endif
 	REG_S	t0, 0(t1)
+
+	VPRINTX(t1)
+#else
+#ifdef notyet
+	REG_S	t0, 0(s4)
 #else
 	REG_S	t0, 0(s3)
 #endif
 
-	li	t0, ((VM_MAX_KERNEL_ADDRESS >> SEGSHIFT) & (NPDEPG-1)) * SZREG
-	add	s3, s3, t0
-	srli	a7, a7, (SEGSHIFT-PGSHIFT) // pages to segments
-	li	t3, NBSEG		// load for ease
+	VPRINTX(s3)
+#endif
+#endif
+
+	VPRINTS(": ")
+	VPRINTXNL(t0)
+	VPRINTS("\n\r")
+
+#if PGSHIFT < PTE_PPN_SHIFT
+#error Code assumes PGSHIFT is greater than PTE_PPN_SHIFT
+#endif
+
+	li	s5, (VM_KERNEL_SIZE >> SEGSHIFT)		// # of megapages
+	li	s6, (NBSEG >> (PGSHIFT - PTE_PPN_SHIFT))	// load for ease
+	li	s7, PTE_KERN | PTE_R | PTE_W | PTE_X
 
 	//
-	// Fill in the PDEs to direct map memory.
+	// Fill in the PDEs for kernel.
 	//
-.Lfill:	REG_S	t4, 0(s3)		// store PDE
-	add	t4, t4, t3		// advance PA in PDE to next segment
-	add	s3, s3, SZREG		// advance to next PDE slot
-	addi	a7, a7, -1		// count down segment
-	bgtz	a6, .Lfill		// loop if more
+	PTR_LA	s0, start
+	srli	s0, s0, (PGSHIFT - PTE_PPN_SHIFT)
+	or	s0, s0, s7
+.Lfill:
+	VPRINTS("kern ")
+	VPRINTX(s2)
+	VPRINTS(": ")
+	VPRINTXNL(s0)
+
+	REG_S	s0, 0(s2)		// store PDE
+	add	s0, s0, s6		// advance PA in PDE to next segment
+	add	s2, s2, SZREG		// advance to next PDE slot
+	addi	s5, s5, -1		// count down segment
+	bnez	s5, .Lfill		// loop if more
+
+	li	s7, PTE_KERN | PTE_R | PTE_W
+
+	// DTB physical address
+	mv	s0, s1
+	srli	s0, s0, SEGSHIFT	// round down to NBSEG, and shift in
+	slli	s0, s0, (SEGSHIFT - PGSHIFT + PTE_PPN_SHIFT)	// ... to PPN
+	or	s0, s0, s7
+
+	VPRINTS("dtb  ")
+	VPRINTX(s2)
+	VPRINTS(": ")
+	VPRINTXNL(s0)
+
+	REG_S	s0, 0(s2)
+	add	s2, s2, SZREG		// advance to next PDE slot
+
+#ifdef CONSADDR
+	ld	s0, .Lconsaddr
+	srli	s0, s0, SEGSHIFT	// round down to NBSEG, and shift in
+	slli	s0, s0, (SEGSHIFT - PGSHIFT + PTE_PPN_SHIFT)	// ... to PPN
+	or	s0, s0, s7
+
+	VPRINTS("cons ")
+	VPRINTX(s2)
+	VPRINTS(": ")
+	VPRINTXNL(s0)
+
+	REG_S	s0, 0(s2)
+	add	s2, s2, SZREG		// advance to next PDE slot
 #endif
 
-	// We should have a VM so let's start using our real addresses
+	li	a0, 'P'
+	call	_C_LABEL(uartputc)
+
+	/* Set supervisor trap vector base register */
 	PTR_LA	t0, .Lmmu_on
+	add	t0, t0, s8
+	csrw	stvec, t0
+
+	/* Set supervisor address translation and protection register */
+	srli	t1, s4, PGSHIFT
+#ifdef _LP64
+	li	t0, SATP_MODE_SV39
+#else
+	li	t0, SATP_MODE_SV32
+#endif
+	or	t0, t0, t1
+	sfence.vma
+	csrw	satp, t0
 
+	.align 2
 .Lmmu_on:
 	// MMU is on!
 	csrw	sscratch, zero		// zero in sscratch to mark kernel
 
+	li	a0, 'M'
+	call	_C_LABEL(uartputc)	// uartputs doesn't use stack
+	li	a0, '\n'
+	call	_C_LABEL(uartputc)	// uartputs doesn't use stack
+	li	a0, '\r'
+	call	_C_LABEL(uartputc)	// uartputs doesn't use stack
+
 	PTR_LA	tp, _C_LABEL(lwp0)	// put curlwp in tp
 
+	.global vstart
+vstart:
+
+	/* Set supervisor trap vector base register */
 	PTR_LA	a0, _C_LABEL(cpu_exception_handler)
 	csrw	stvec, a0
 
-	PTR_S	s1, L_PCB(tp)		// set uarea of lwp (already zeroed)
+	PTR_LA	s2, bootstk		// top of lwp0uspace
+	PTR_S	s2, L_PCB(tp)		// set uarea of lwp (already zeroed)
 	addi	sp, s2, -TF_LEN		// switch to new stack
 	PTR_S	sp, L_MD_UTF(tp)	// store pointer to empty trapframe
 
 	PTR_LA	t1, _C_LABEL(kernel_pmap_store)
-	add	t2, s2, s11 		// PA -> VA
+	add	t2, s4, s8 		// PA -> VA
+	srli	t3, s4, PGSHIFT
 	PTR_S	t2, PM_MD_PDETAB(t1)	// VA of kernel PDETAB
-	PTR_S	s2, PM_MD_PTBR(t1)	// PA of kernel PDETAB
+	PTR_S	t3, PM_MD_PPN(t1)	// PPN of kernel PDETAB
+
+	/*
+	 * Store kern_vtopdiff (the difference between the physical
+	 * and virtual address of the "start" symbol).
+	 */
+	PTR_LA	s11, _C_LABEL(kern_vtopdiff)
+	PTR_S	s8, 0(s11)	/* kern_vtopdiff = start(virt) - start(phys) */
+
+#if notyet
+	mv	a0, s1			// dtb
+	call	_C_LABEL(init_mmu)
+#endif
+
+	li	t0, VM_MIN_KERNEL_ADDRESS + VM_KERNEL_SIZE
+	li	t1, NBSEG - 1
+	and	t1, s1, t1
+	or	t0, t0, t1
+
+	/* Set the global pointer */
+	.option push
+	.option norelax
+	lla	gp, __global_pointer$
+	.option pop
 
 	// Now we should ready to start initializing the kernel.
-	PTR_LA	a0, _C_LABEL(start)	// kernel_start
-	add	a1, s5, s11		// kernel_end
+	mv	a0, s0			// hartid
+	mv	a1, t0			// vdtb
+	//mv	a1, s1			// dtb (physical)
 	call	_C_LABEL(init_riscv)	// do MD startup
 	tail	_C_LABEL(main)		// and transfer to main
-	// not reached
+	/* No return from main */
 END(start)
 
+
+ENTRY(mpentry)
+1:
+	wfi
+	j	1b
+END(mpentry)
+
+
+	.align 3
+.Lstart:
+#ifdef _LP64
+	.quad	start
+#else
+	.word	start
+#endif
+
+
+#ifdef CONSADDR
+	.align 3
+.Lconsaddr:
+#ifdef _LP64
+	.quad	CONSADDR
+#else
+	.word	CONSADDR
+#endif
+#endif
+
+
+ENTRY_NP(uartputc)
+#ifdef EARLYCONS
+	tail	___CONCAT(EARLYCONS, _platform_early_putchar)
+#else
+#define SBI_LEGACY_CONSOLE_PUTCHAR        1
+	li	a7, SBI_LEGACY_CONSOLE_PUTCHAR
+	ecall
+	ret
+#endif
+END(uartputc)
+
+
+ENTRY_NP(clear_bss)
+	bgeu	a0, a1, 1f
+2:
+	sb	zero, 0(a0)
+	addi	a0, a0, 1
+	bne	a1, a0, 2b
+1:
+	ret
+END(clear_bss)
+
+
+#if defined(VERBOSE_INIT_RISCV)
+ENTRY_NP(locore_prints)
+	addi	sp, sp, -(SZREG * 2)
+	REG_S	s0, (0 * SZREG)(sp)
+	mv	s0, ra
+1:
+	lbu	a0, 0(s0)
+	beqz	a0, 2f
+
+	call	uartputc
+
+	addi	s0, s0, 1
+	j	1b
+2:
+	addi	s0, s0, 8	// s0 points to the null terminator
+	andi	ra, s0, -8
+
+	REG_L	s0, (0 * SZREG)(sp)
+	addi	sp, sp, (SZREG * 2)
+	ret
+
+END(locore_prints)
+
+
+ENTRY_NP(locore_printx)
+	addi	sp, sp, -(SZREG * 4)
+	REG_S	s0, (0 * SZREG)(sp)
+	REG_S	s1, (1 * SZREG)(sp)
+	REG_S	s2, (2 * SZREG)(sp)
+	REG_S	ra, (3 * SZREG)(sp)
+
+	mv	s1, a0		// our print value
+	li	s2, 10
+
+	li	a0, '0'
+	call	uartputc
+	li	a0, 'x'
+	call	uartputc
+
+	// Word size in bits
+	li	s0, (SZREG * 8)
+1:
+	addi	s0, s0, -4	// nibble shift
+
+	srl	a0, s1, s0	// extract ...
+	andi	a0, a0, 0xf
+
+	bltu	a0, s2, 2f
+	addi	a0, a0, ('a' - '0' - 10)
+2:	addi	a0, a0, '0'
+
+	call	uartputc
+
+	beqz	s0, 3f
+
+	and	a0, s0, (16 - 1)
+	bnez	a0, 1b
+
+	li	a0, '_'
+	call	uartputc
+
+	j	1b
+
+3:
+	REG_L	s0, (0 * SZREG)(sp)
+	REG_L	s1, (1 * SZREG)(sp)
+	REG_L	s2, (2 * SZREG)(sp)
+	REG_L	ra, (3 * SZREG)(sp)
+	addi	sp, sp, (SZREG * 4)
+	ret
+END(locore_printx)
+
+
+ENTRY_NP(locore_printxnl)
+	addi	sp, sp, -(SZREG * 2)
+	REG_S	ra, (1 * SZREG)(sp)
+
+	call	locore_printx
+	li	a0, '\n'
+	call	uartputc
+
+	li	a0, '\r'
+	call	uartputc
+
+	REG_L	ra, (1 * SZREG)(sp)
+	addi	sp, sp, (SZREG * 2)
+
+	ret
+END(locore_printxnl)
+#endif	/* VERBOSE_INIT_RISCV */
+
+
+	.data
+	.align	2
+hart_boot:
+	.word	0
+
+	.section "_init_memory", "aw", %nobits
+	.align PGSHIFT
+	.global _C_LABEL(lwp0uspace)
+_C_LABEL(lwp0uspace):
+	.space	UPAGES * PAGE_SIZE
+bootstk:
+
+	/*
+	 * Allocate some memory after the kernel image for stacks and
+	 * bootstrap L1PT
+	 */
+	.align PGSHIFT
+
+	.section "_init_memory", "aw", %nobits
+	.align PGSHIFT
+mmutables_start:
+	.global _C_LABEL(l1_pte)
+l1_pte:
+	.space PAGE_SIZE
+#ifdef _LP64
+	.global _C_LABEL(l2_pte)
+l2_pte:
+	.space PAGE_SIZE
+#ifdef notyet
+l3_pte:
+	.space PAGE_SIZE
+#endif
+#endif
+mmutables_end:
+
+
 //
 // struct lwp *cpu_switchto(struct lwp *oldl, struct lwp *newl, bool returning);
 //

Index: src/sys/arch/riscv/riscv/pmap_machdep.c
diff -u src/sys/arch/riscv/riscv/pmap_machdep.c:1.10 src/sys/arch/riscv/riscv/pmap_machdep.c:1.11
--- src/sys/arch/riscv/riscv/pmap_machdep.c:1.10	Sat Oct 30 07:18:46 2021
+++ src/sys/arch/riscv/riscv/pmap_machdep.c	Tue Sep 20 07:18:23 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap_machdep.c,v 1.10 2021/10/30 07:18:46 skrll Exp $ */
+/* $NetBSD: pmap_machdep.c,v 1.11 2022/09/20 07:18:23 skrll Exp $ */
 
 /*
  * Copyright (c) 2014, 2019, 2021 The NetBSD Foundation, Inc.
@@ -30,17 +30,26 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "opt_riscv_debug.h"
+
 #define __PMAP_PRIVATE
 
 #include <sys/cdefs.h>
-
-__RCSID("$NetBSD: pmap_machdep.c,v 1.10 2021/10/30 07:18:46 skrll Exp $");
+__RCSID("$NetBSD: pmap_machdep.c,v 1.11 2022/09/20 07:18:23 skrll Exp $");
 
 #include <sys/param.h>
+#include <sys/buf.h>
 
 #include <uvm/uvm.h>
 
-#include <riscv/locore.h>
+#include <riscv/machdep.h>
+#include <riscv/sysreg.h>
+
+#ifdef VERBOSE_INIT_RISCV
+#define VPRINTF(...)	printf(__VA_ARGS__)
+#else
+#define VPRINTF(...)	__nothing
+#endif
 
 int riscv_poolpage_vmfreelist = VM_FREELIST_DEFAULT;
 
@@ -48,13 +57,6 @@ vaddr_t pmap_direct_base __read_mostly;
 vaddr_t pmap_direct_end __read_mostly;
 
 void
-pmap_bootstrap(void)
-{
-
-	pmap_bootstrap_common();
-}
-
-void
 pmap_zero_page(paddr_t pa)
 {
 #ifdef _LP64
@@ -124,7 +126,8 @@ pmap_md_direct_mapped_vaddr_to_paddr(vad
 #ifdef PMAP_DIRECT_MAP
 	return PMAP_DIRECT_UNMAP(va);
 #else
-#error "no direct map"
+	KASSERT(false);
+	return 0;
 #endif
 #else
 	KASSERT(false);
@@ -150,29 +153,122 @@ pmap_md_ok_to_steal_p(const uvm_physseg_
 	return true;
 }
 
-bool
-pmap_md_tlb_check_entry(void *ctx, vaddr_t va, tlb_asid_t asid, pt_entry_t pte)
-{
-	return false;
-}
 
 void
 pmap_md_xtab_activate(struct pmap *pmap, struct lwp *l)
 {
-	__asm("csrw\tsptbr, %0" :: "r"(pmap->pm_md.md_ptbr));
+        struct pmap_asid_info * const pai = PMAP_PAI(pmap, cpu_tlb_info(ci));
+
+	 uint64_t satp =
+#ifdef _LP64
+	    __SHIFTIN(SATP_MODE_SV39, SATP_MODE) |
+#else
+	    __SHIFTIN(SATP_MODE_SV32, SATP_MODE) |
+#endif
+	    __SHIFTIN(pai->pai_asid, SATP_ASID) |
+	    __SHIFTIN(pmap->pm_md.md_ppn, SATP_PPN);
+
+	riscvreg_satp_write(satp);
 }
 
 void
 pmap_md_xtab_deactivate(struct pmap *pmap)
 {
+
+	riscvreg_satp_write(0);
 }
 
 void
 pmap_md_pdetab_init(struct pmap *pmap)
 {
+	KASSERT(pmap != NULL);
+
+	const vaddr_t pdetabva = (vaddr_t)pmap->pm_md.md_pdetab;
+	const paddr_t pdetabpa = pmap_md_direct_mapped_vaddr_to_paddr(pdetabva);
 	pmap->pm_md.md_pdetab[NPDEPG-1] = pmap_kernel()->pm_md.md_pdetab[NPDEPG-1];
-	pmap->pm_md.md_ptbr =
-	    pmap_md_direct_mapped_vaddr_to_paddr((vaddr_t)pmap->pm_md.md_pdetab);
+	pmap->pm_md.md_ppn = pdetabpa >> PAGE_SHIFT;
+}
+
+void
+pmap_bootstrap(vaddr_t vstart, vaddr_t vend)
+{
+	extern pd_entry_t l1_pte[512];
+	pmap_t pm = pmap_kernel();
+
+	pmap_bootstrap_common();
+
+	/* Use the tables we already built in init_mmu() */
+	pm->pm_md.md_pdetab = l1_pte;
+
+	/* Get the PPN for l1_pte */
+	pm->pm_md.md_ppn = atop(KERN_VTOPHYS((vaddr_t)l1_pte));
+
+	/* Setup basic info like pagesize=PAGE_SIZE */
+	uvm_md_init();
+
+	/* init the lock */
+	pmap_tlb_info_init(&pmap_tlb0_info);
+
+#ifdef MULTIPROCESSOR
+	VPRINTF("kcpusets ");
+
+	kcpuset_create(&pm->pm_onproc, true);
+	kcpuset_create(&pm->pm_active, true);
+	KASSERT(pm->pm_onproc != NULL);
+	KASSERT(pm->pm_active != NULL);
+	kcpuset_set(pm->pm_onproc, cpu_number());
+	kcpuset_set(pm->pm_active, cpu_number());
+#endif
+
+	VPRINTF("nkmempages ");
+	/*
+	 * Compute the number of pages kmem_arena will have.  This will also
+	 * be called by uvm_km_bootstrap later, but that doesn't matter
+	 */
+	kmeminit_nkmempages();
+
+	/* Get size of buffer cache and set an upper limit */
+	buf_setvalimit((VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) / 8);
+	vsize_t bufsz = buf_memcalc();
+	buf_setvalimit(bufsz);
+
+	vsize_t kvmsize = (VM_PHYS_SIZE + (ubc_nwins << ubc_winshift) +
+	    bufsz + 16 * NCARGS + pager_map_size) +
+	    /*(maxproc * UPAGES) + */nkmempages * NBPG;
+
+#ifdef SYSVSHM
+	kvmsize += shminfo.shmall;
+#endif
+
+	/* Calculate VA address space and roundup to NBSEG tables */
+	kvmsize = roundup(kvmsize, NBSEG);
+
+	/*
+	 * Initialize `FYI' variables.	Note we're relying on
+	 * the fact that BSEARCH sorts the vm_physmem[] array
+	 * for us.  Must do this before uvm_pageboot_alloc()
+	 * can be called.
+	 */
+	pmap_limits.avail_start = ptoa(uvm_physseg_get_start(uvm_physseg_get_first()));
+	pmap_limits.avail_end = ptoa(uvm_physseg_get_end(uvm_physseg_get_last()));
+
+	/*
+	 * Update the naive settings in pmap_limits to the actual KVA range.
+	 */
+	pmap_limits.virtual_start = vstart;
+	pmap_limits.virtual_end = vend;
+
+	VPRINTF("\nlimits: %" PRIxVADDR " - %" PRIxVADDR "\n", vstart, vend);
+
+	/*
+	 * Initialize the pools.
+	 */
+	pool_init(&pmap_pmap_pool, PMAP_SIZE, 0, 0, 0, "pmappl",
+	    &pool_allocator_nointr, IPL_NONE);
+	pool_init(&pmap_pv_pool, sizeof(struct pv_entry), 0, 0, 0, "pvpl",
+	    &pmap_pv_page_allocator, IPL_NONE);
+
+	pmap_pvlist_lock_init(/*riscv_dcache_align*/ 64);
 }
 
 /* -------------------------------------------------------------------------- */
@@ -196,18 +292,37 @@ void    tlb_invalidate_globals(void);
 void
 tlb_invalidate_asids(tlb_asid_t lo, tlb_asid_t hi)
 {
-	__asm __volatile("sfence.vm" ::: "memory");
+	for (; lo <= hi; lo++) {
+		__asm __volatile("sfence.vma zero, %[asid]"
+		    : /* output operands */
+		    : [asid] "r" (lo)
+		    : "memory");
+	}
 }
 void
 tlb_invalidate_addr(vaddr_t va, tlb_asid_t asid)
 {
-	__asm __volatile("sfence.vm" ::: "memory");
+	if (asid == KERNEL_PID) {
+		__asm __volatile("sfence.vma %[va]"
+		    : /* output operands */
+		    : [va] "r" (va)
+		    : "memory");
+	} else {
+		__asm __volatile("sfence.vma %[va], %[asid]"
+		    : /* output operands */
+		    : [va] "r" (va), [asid] "r" (asid)
+		    : "memory");
+	}
 }
 
 bool
 tlb_update_addr(vaddr_t va, tlb_asid_t asid, pt_entry_t pte, bool insert_p)
 {
-	__asm __volatile("sfence.vm" ::: "memory");
+	KASSERT(asid != KERNEL_PID);
+	__asm __volatile("sfence.vma %[va], %[asid]"
+	    : /* output operands */
+	    : [va] "r" (va), [asid] "r" (asid)
+	    : "memory");
 	return false;
 }
 
@@ -216,13 +331,19 @@ tlb_record_asids(u_long *ptr, tlb_asid_t
 {
 	memset(ptr, 0xff, PMAP_TLB_NUM_PIDS / NBBY);
 	ptr[0] = -2UL;
+
 	return PMAP_TLB_NUM_PIDS - 1;
 }
 
+void
+tlb_walk(void *ctx, bool (*func)(void *, vaddr_t, tlb_asid_t, pt_entry_t))
+{
+	/* no way to view the TLB */
+}
+
 #if 0
 void    tlb_enter_addr(size_t, const struct tlbmask *);
 void    tlb_read_entry(size_t, struct tlbmask *);
 void    tlb_write_entry(size_t, const struct tlbmask *);
-void    tlb_walk(void *, bool (*)(void *, vaddr_t, tlb_asid_t, pt_entry_t));
 void    tlb_dump(void (*)(const char *, ...));
 #endif

Index: src/sys/arch/riscv/riscv/riscv_machdep.c
diff -u src/sys/arch/riscv/riscv/riscv_machdep.c:1.17 src/sys/arch/riscv/riscv/riscv_machdep.c:1.18
--- src/sys/arch/riscv/riscv/riscv_machdep.c:1.17	Tue Sep 20 06:53:36 2022
+++ src/sys/arch/riscv/riscv/riscv_machdep.c	Tue Sep 20 07:18:24 2022
@@ -1,11 +1,11 @@
-/*	$NetBSD: riscv_machdep.c,v 1.17 2022/09/20 06:53:36 skrll Exp $	*/
+/*	$NetBSD: riscv_machdep.c,v 1.18 2022/09/20 07:18:24 skrll Exp $	*/
 
 /*-
- * Copyright (c) 2014, 2019 The NetBSD Foundation, Inc.
+ * Copyright (c) 2014, 2019, 2022 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
- * by Matt Thomas of 3am Software Foundry.
+ * by Matt Thomas of 3am Software Foundry, and by Nick Hudson.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,32 +29,73 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <sys/cdefs.h>
-
 #include "opt_modular.h"
-__RCSID("$NetBSD: riscv_machdep.c,v 1.17 2022/09/20 06:53:36 skrll Exp $");
+#include "opt_riscv_debug.h"
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: riscv_machdep.c,v 1.18 2022/09/20 07:18:24 skrll Exp $");
 
 #include <sys/param.h>
 
+#include <sys/boot_flag.h>
 #include <sys/cpu.h>
 #include <sys/exec.h>
 #include <sys/kmem.h>
 #include <sys/ktrace.h>
 #include <sys/lwp.h>
 #include <sys/module.h>
+#include <sys/msgbuf.h>
 #include <sys/proc.h>
 #include <sys/reboot.h>
 #include <sys/syscall.h>
 #include <sys/systm.h>
 
+#include <dev/cons.h>
 #include <uvm/uvm_extern.h>
 
 #include <riscv/locore.h>
+#include <riscv/machdep.h>
+#include <riscv/pte.h>
 
 int cpu_printfataltraps;
 char machine[] = MACHINE;
 char machine_arch[] = MACHINE_ARCH;
 
+#include <libfdt.h>
+#include <dev/fdt/fdtvar.h>
+#include <dev/fdt/fdt_memory.h>
+
+#ifdef VERBOSE_INIT_RISCV
+#define VPRINTF(...)	printf(__VA_ARGS__)
+#else
+#define VPRINTF(...)	__nothing
+#endif
+
+#ifndef FDT_MAX_BOOT_STRING
+#define FDT_MAX_BOOT_STRING 1024
+#endif
+
+char bootargs[FDT_MAX_BOOT_STRING] = "";
+char *boot_args = NULL;
+
+static void
+earlyconsputc(dev_t dev, int c)
+{
+	uartputc(c);
+}
+
+static int
+earlyconsgetc(dev_t dev)
+{
+	return 0;
+}
+
+static struct consdev earlycons = {
+	.cn_putc = earlyconsputc,
+	.cn_getc = earlyconsgetc,
+	.cn_pollc = nullcnpollc,
+};
+
 struct vm_map *phys_map;
 
 struct trapframe cpu_ddb_regs;
@@ -70,6 +111,12 @@ const pcu_ops_t * const pcu_ops_md_defs[
 #endif
 };
 
+/*
+ * Used by PHYSTOV and VTOPHYS -- Will be set be BSS is zeroed so
+ * keep it in data
+ */
+unsigned long kern_vtopdiff __attribute__((__section__(".data")));
+
 void
 delay(unsigned long us)
 {
@@ -338,10 +385,191 @@ cpu_startup(void)
 	printf("avail memory = %s\n", pbuf);
 }
 
+static void
+riscv_init_lwp0_uarea(void)
+{
+	extern char lwp0uspace[];
+
+	uvm_lwp_setuarea(&lwp0, (vaddr_t)lwp0uspace);
+	memset(&lwp0.l_md, 0, sizeof(lwp0.l_md));
+	memset(lwp_getpcb(&lwp0), 0, sizeof(struct pcb));
+
+	struct trapframe *tf = (struct trapframe *)(lwp0uspace + USPACE) - 1;
+	memset(tf, 0, sizeof(struct trapframe));
+
+	lwp0.l_md.md_utf = lwp0.l_md.md_ktf = tf;
+}
+
+
+static void
+riscv_print_memory(const struct fdt_memory *m, void *arg)
+{
+
+	VPRINTF("FDT /memory @ 0x%" PRIx64 " size 0x%" PRIx64 "\n",
+	    m->start, m->end - m->start);
+}
+
+
+static void
+parse_bi_bootargs(char *args)
+{
+	int howto;
+
+	for (char *cp = args; *cp; cp++) {
+		/* Ignore superfluous '-', if there is one */
+		if (*cp == '-')
+			continue;
+
+		howto = 0;
+		BOOT_FLAG(*cp, howto);
+		if (!howto)
+			printf("bootflag '%c' not recognised\n", *cp);
+		else
+			boothowto |= howto;
+	}
+}
+
+
 void
-init_riscv(vaddr_t kernstart, vaddr_t kernend)
+init_riscv(register_t hartid, vaddr_t vdtb)
 {
 
-	/* Early VM bootstrap. */
-	pmap_bootstrap();
+	/* set temporally to work printf()/panic() even before consinit() */
+	cn_tab = &earlycons;
+
+	/* Load FDT */
+	void *fdt_data = (void *)vdtb;
+	int error = fdt_check_header(fdt_data);
+	if (error != 0)
+	    panic("fdt_check_header failed: %s", fdt_strerror(error));
+
+	fdtbus_init(fdt_data);
+
+#if 0
+	/* Lookup platform specific backend */
+	plat = riscv_fdt_platform();
+	if (plat == NULL)
+		panic("Kernel does not support this device");
+
+#endif
+	/* Early console may be available, announce ourselves. */
+	VPRINTF("FDT<%p>\n", fdt_data);
+
+	const int chosen = OF_finddevice("/chosen");
+	if (chosen >= 0)
+		OF_getprop(chosen, "bootargs", bootargs, sizeof(bootargs));
+	boot_args = bootargs;
+
+#if 0
+	/*
+	 * If stdout-path is specified on the command line, override the
+	 * value in /chosen/stdout-path before initializing console.
+	 */
+	VPRINTF("stdout\n");
+	fdt_update_stdout_path();
+#endif
+
+	/*
+	 * Done making changes to the FDT.
+	 */
+	fdt_pack(fdt_data);
+
+	VPRINTF("consinit ");
+	consinit();
+	VPRINTF("ok\n");
+
+	/* Talk to the user */
+	printf("NetBSD/riscv (fdt) booting ...\n");
+
+#ifdef BOOT_ARGS
+	char mi_bootargs[] = BOOT_ARGS;
+	parse_bi_bootargs(mi_bootargs);
+#endif
+
+	/* SPAM me while testing */
+	boothowto |= AB_DEBUG;
+
+	uint64_t memory_start, memory_end;
+	fdt_memory_get(&memory_start, &memory_end);
+
+	fdt_memory_foreach(riscv_print_memory, NULL);
+
+	/* Cannot map memory above largest page number */
+	const uint64_t maxppn = __SHIFTOUT_MASK(PTE_PPN) - 1;
+	const uint64_t memory_limit = ptoa(maxppn);
+
+	if (memory_end > memory_limit) {
+		fdt_memory_remove_range(memory_limit, memory_end);
+		memory_end = memory_limit;
+	}
+
+	uint64_t memory_size __unused = memory_end - memory_start;
+
+	VPRINTF("%s: memory start %" PRIx64 " end %" PRIx64 " (len %"
+	    PRIx64 ")\n", __func__, memory_start, memory_end, memory_size);
+
+	/* Perform PT build and VM init */
+	//cpu_kernel_vm_init();
+
+	VPRINTF("bootargs: %s\n", bootargs);
+
+	parse_bi_bootargs(boot_args);
+
+
+	// initarm_common
+	extern char __kernel_text[];
+	extern char _end[];
+
+	vaddr_t kernstart = trunc_page((vaddr_t)__kernel_text);
+	vaddr_t kernend = round_page((vaddr_t)_end);
+	paddr_t kernstart_phys __unused = KERN_VTOPHYS(kernstart);
+	paddr_t kernend_phys __unused = KERN_VTOPHYS(kernend);
+
+	vaddr_t kernelvmstart;
+
+	vaddr_t kernstart_mega __unused = MEGAPAGE_TRUNC(kernstart);
+	vaddr_t kernend_mega = MEGAPAGE_ROUND(kernend);
+
+	kernelvmstart = kernend_mega;
+
+#define DPRINTF(v)	VPRINTF("%24s = 0x%16lx\n", #v, (unsigned long)v);
+
+	VPRINTF("------------------------------------------\n");
+	DPRINTF(kern_vtopdiff);
+	DPRINTF(memory_start);
+	DPRINTF(memory_end);
+	DPRINTF(memory_size);
+	DPRINTF(kernstart_phys);
+	DPRINTF(kernend_phys)
+	DPRINTF(VM_MIN_KERNEL_ADDRESS);
+	DPRINTF(kernstart_mega);
+	DPRINTF(kernstart);
+	DPRINTF(kernend);
+	DPRINTF(kernend_mega);
+	DPRINTF(VM_MAX_KERNEL_ADDRESS);
+	VPRINTF("------------------------------------------\n");
+
+#undef DPRINTF
+
+	KASSERT(kernelvmstart < VM_KERNEL_VM_BASE);
+
+	kernelvmstart = VM_KERNEL_VM_BASE;
+
+	/*
+	 * msgbuf is allocated from the bottom of any one of memory blocks
+	 * to avoid corruption due to bootloader or changing kernel layout.
+	 */
+	paddr_t msgbufaddr = 0;
+
+	KASSERT(msgbufaddr != 0);	/* no space for msgbuf */
+#ifdef _LP64
+	initmsgbuf((void *)RISCV_PA_TO_KVA(msgbufaddr), MSGBUFSIZE);
+#endif
+
+	uvm_md_init();
+
+	pmap_bootstrap(kernelvmstart, VM_MAX_KERNEL_ADDRESS);
+
+	/* Finish setting up lwp0 on our end before we call main() */
+	riscv_init_lwp0_uarea();
 }

Added files:

Index: src/sys/arch/riscv/include/machdep.h
diff -u /dev/null src/sys/arch/riscv/include/machdep.h:1.1
--- /dev/null	Tue Sep 20 07:18:24 2022
+++ src/sys/arch/riscv/include/machdep.h	Tue Sep 20 07:18:23 2022
@@ -0,0 +1,68 @@
+/*	$NetBSD: machdep.h,v 1.1 2022/09/20 07:18:23 skrll Exp $	*/
+
+/*-
+ * Copyright (c) 2022 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nick Hudson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RISCV_MACHDEP_H_
+#define _RISCV_MACHDEP_H_
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: machdep.h,v 1.1 2022/09/20 07:18:23 skrll Exp $");
+
+#include <sys/proc.h>
+#include <sys/lwp.h>
+#include <sys/siginfo.h>
+
+static inline paddr_t
+riscv_kern_vtophys(vaddr_t va)
+{
+	extern unsigned long kern_vtopdiff;
+
+	return va - kern_vtopdiff;
+}
+
+static inline vaddr_t
+riscv_kern_phystov(paddr_t pa)
+{
+	extern unsigned long kern_vtopdiff;
+
+	return pa + kern_vtopdiff;
+}
+
+#define KERN_VTOPHYS(va)	riscv_kern_vtophys((vaddr_t)va)
+#define KERN_PHYSTOV(pa)	riscv_kern_phystov((paddr_t)pa)
+
+
+void	uartputc(int);
+
+paddr_t	init_mmu(paddr_t);
+void	init_riscv(register_t, vaddr_t);
+
+
+#endif	/* _RISCV_MACHDEP_H_ */

Reply via email to