svn commit: r322361 - in head: lib/csu/riscv lib/libc/riscv/gen libexec/rtld-elf/riscv share/mk sys/boot/fdt/dts/riscv sys/conf sys/riscv/conf sys/riscv/include sys/riscv/riscv

Ruslan Bukin br at FreeBSD.org
Thu Aug 10 14:18:12 UTC 2017


Author: br
Date: Thu Aug 10 14:18:09 2017
New Revision: 322361
URL: https://svnweb.freebsd.org/changeset/base/322361

Log:
  Support for v1.10 (latest) of RISC-V privilege specification.
  
  New version is not compatible on supervisor mode with v1.9.1
  (previous version).
  
  Highlights:
      o BBL (Berkeley Boot Loader) provides no initial page tables
        anymore allowing us to choose VM, to build page tables manually
        and enable MMU in S-mode.
      o SBI interface changed.
      o GENERIC kernel.
        FDT is now chosen standard for RISC-V hardware description.
        DTB is now provided by Spike (golden model simulator). This
        allows us to introduce GENERIC kernel. However, description
        for console and timer devices is not provided in DTB, so move
        these devices temporary to nexus bus.
      o Supervisor can't access userspace by default. Solution is to
        set SUM (permit Supervisor User Memory access) bit in sstatus
        register.
      o Compressed extension is now turned on by default.
      o External GCC 7.1 compiler used.
      o _gp renamed to __global_pointer$
      o Compiler -march= string is now in use allowing us to choose
        required extensions (compressed, FPU, atomic, etc).
  
  Sponsored by:	DARPA, AFRL
  Differential Revision:	https://reviews.freebsd.org/D11800

Deleted:
  head/sys/boot/fdt/dts/riscv/
  head/sys/riscv/conf/LOWRISC
  head/sys/riscv/conf/LOWRISC.hints
  head/sys/riscv/conf/QEMU
  head/sys/riscv/conf/ROCKET
  head/sys/riscv/conf/SPIKE
  head/sys/riscv/riscv/sbi.S
Modified:
  head/lib/csu/riscv/crt1.c
  head/lib/csu/riscv/crti.S
  head/lib/libc/riscv/gen/fabs.S
  head/libexec/rtld-elf/riscv/reloc.c
  head/share/mk/bsd.cpu.mk
  head/share/mk/bsd.stand.mk
  head/sys/conf/Makefile.riscv
  head/sys/conf/files.riscv
  head/sys/conf/kern.mk
  head/sys/riscv/conf/GENERIC
  head/sys/riscv/include/machdep.h
  head/sys/riscv/include/riscvreg.h
  head/sys/riscv/include/sbi.h
  head/sys/riscv/riscv/cpufunc_asm.S
  head/sys/riscv/riscv/exception.S
  head/sys/riscv/riscv/intr_machdep.c
  head/sys/riscv/riscv/locore.S
  head/sys/riscv/riscv/machdep.c
  head/sys/riscv/riscv/nexus.c
  head/sys/riscv/riscv/pmap.c
  head/sys/riscv/riscv/riscv_console.c
  head/sys/riscv/riscv/swtch.S
  head/sys/riscv/riscv/timer.c
  head/sys/riscv/riscv/trap.c
  head/sys/riscv/riscv/vm_machdep.c

Modified: head/lib/csu/riscv/crt1.c
==============================================================================
--- head/lib/csu/riscv/crt1.c	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/lib/csu/riscv/crt1.c	Thu Aug 10 14:18:09 2017	(r322361)
@@ -1,7 +1,7 @@
 /* LINTLIBRARY */
 /*-
  * Copyright 1996-1998 John D. Polstra.
- * Copyright (c) 2015 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2017 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -64,7 +64,10 @@ __asm("	.text			\n"
 "	slli	t0, a0, 3	\n" /* mult by arg size */
 "	add	a2, a1, t0	\n" /* env is after argv */
 "	addi	a2, a2, 8	\n" /* argv is null terminated */
-"	lla	gp, _gp		\n" /* load global pointer */
+"	.option push		\n"
+"	.option norelax		\n"
+"	lla	gp, __global_pointer$\n"
+"	.option pop		\n"
 "	call	__start");
 
 void

Modified: head/lib/csu/riscv/crti.S
==============================================================================
--- head/lib/csu/riscv/crti.S	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/lib/csu/riscv/crti.S	Thu Aug 10 14:18:09 2017	(r322361)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2017 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -35,12 +35,13 @@
 #include <machine/asm.h>
 __FBSDID("$FreeBSD$");
 
-# this puts _gp into .dynsym, so symlook_obj can now find that (see reloc.c)
-	.weak	_gp
-_gp:
+# this puts __global_pointer$ into .dynsym, so symlook_obj can now find that
+# (see reloc.c)
+	.weak	__global_pointer$
+__global_pointer$:
 
 	.section .init,"ax", at progbits
-	.align	2
+	.align	0
 	.globl	_init
 	.type	_init, at function
 _init:
@@ -48,7 +49,7 @@ _init:
 	sd	ra, 0(sp)
 
 	.section .fini,"ax", at progbits
-	.align	2
+	.align	0
 	.globl	_fini
 	.type	_fini, at function
 _fini:

Modified: head/lib/libc/riscv/gen/fabs.S
==============================================================================
--- head/lib/libc/riscv/gen/fabs.S	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/lib/libc/riscv/gen/fabs.S	Thu Aug 10 14:18:09 2017	(r322361)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2017 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -35,7 +35,9 @@
 #include <machine/asm.h>
 __FBSDID("$FreeBSD$");
 
+#ifndef SOFTFLOAT
 ENTRY(fabs)
 	fabs.d	fa0, fa0
 	ret
 END(fabs)
+#endif

Modified: head/libexec/rtld-elf/riscv/reloc.c
==============================================================================
--- head/libexec/rtld-elf/riscv/reloc.c	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/libexec/rtld-elf/riscv/reloc.c	Thu Aug 10 14:18:09 2017	(r322361)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2017 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * This software was developed by SRI International and the University of
@@ -62,7 +62,7 @@ set_gp(Obj_Entry *obj)
 
 	__asm __volatile("mv    %0, gp" : "=r"(old));
 
-	symlook_init(&req, "_gp");
+	symlook_init(&req, "__global_pointer$");
 	req.ventry = NULL;
 	req.flags = SYMLOOK_EARLY;
 	res = symlook_obj(&req, obj);

Modified: head/share/mk/bsd.cpu.mk
==============================================================================
--- head/share/mk/bsd.cpu.mk	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/share/mk/bsd.cpu.mk	Thu Aug 10 14:18:09 2017	(r322361)
@@ -364,8 +364,11 @@ CFLAGS += -mcpu=8540 -Wa,-me500 -mspe=yes -mabi=spe -m
 
 .if ${MACHINE_CPUARCH} == "riscv"
 .if ${TARGET_ARCH:Mriscv*sf}
-CFLAGS += -mno-float
-ACFLAGS += -mno-float
+CFLAGS += -march=rv64imac -mabi=lp64
+ACFLAGS += -march=rv64imac -mabi=lp64
+.else
+CFLAGS += -march=rv64imafdc -mabi=lp64
+ACFLAGS += -march=rv64imafdc -mabi=lp64
 .endif
 .endif
 

Modified: head/share/mk/bsd.stand.mk
==============================================================================
--- head/share/mk/bsd.stand.mk	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/share/mk/bsd.stand.mk	Thu Aug 10 14:18:09 2017	(r322361)
@@ -7,7 +7,7 @@
 CFLAGS+= -ffreestanding -Wformat
 CFLAGS+= ${CFLAGS_NO_SIMD} -D_STANDALONE
 .if ${MACHINE_CPUARCH} == "riscv"
-CFLAGS+=	-mno-float
+CFLAGS+=	-march=rv64imac -mabi=lp64
 .elif ${MACHINE_CPUARCH} != "aarch64"
 CFLAGS+=	-msoft-float
 .endif

Modified: head/sys/conf/Makefile.riscv
==============================================================================
--- head/sys/conf/Makefile.riscv	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/sys/conf/Makefile.riscv	Thu Aug 10 14:18:09 2017	(r322361)
@@ -28,6 +28,11 @@ S=	../../..
 
 INCLUDES+= -I$S/contrib/libfdt
 
+SYSTEM_LD= @${LD} -N -m ${LD_EMULATION} -Bdynamic -T ${LDSCRIPT} ${_LDFLAGS} \
+	--no-warn-mismatch --warn-common --export-dynamic \
+	--dynamic-linker /red/herring \
+	-o ${.TARGET} -X ${SYSTEM_OBJS} vers.o
+
 .if !empty(DDB_ENABLED)
 CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
 .endif

Modified: head/sys/conf/files.riscv
==============================================================================
--- head/sys/conf/files.riscv	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/sys/conf/files.riscv	Thu Aug 10 14:18:09 2017	(r322361)
@@ -46,7 +46,6 @@ riscv/riscv/nexus.c		standard
 riscv/riscv/ofw_machdep.c	optional	fdt
 riscv/riscv/pmap.c		standard
 riscv/riscv/riscv_console.c	optional	rcons
-riscv/riscv/sbi.S		standard
 riscv/riscv/stack_machdep.c	optional	ddb | stack
 riscv/riscv/support.S		standard
 riscv/riscv/swtch.S		standard

Modified: head/sys/conf/kern.mk
==============================================================================
--- head/sys/conf/kern.mk	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/sys/conf/kern.mk	Thu Aug 10 14:18:09 2017	(r322361)
@@ -121,7 +121,7 @@ INLINE_LIMIT?=	8000
 .endif
 
 .if ${MACHINE_CPUARCH} == "riscv"
-CFLAGS.gcc+=	-mcmodel=medany
+CFLAGS.gcc+=	-mcmodel=medany -march=rv64imafdc -mabi=lp64
 INLINE_LIMIT?=	8000
 .endif
 

Modified: head/sys/riscv/conf/GENERIC
==============================================================================
--- head/sys/riscv/conf/GENERIC	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/sys/riscv/conf/GENERIC	Thu Aug 10 14:18:09 2017	(r322361)
@@ -75,6 +75,9 @@ options 	RACCT_DEFAULT_TO_DISABLED # Set kern.racct.en
 options 	RCTL			# Resource limits
 options 	SMP
 
+# RISC-V SBI console
+device		rcons
+
 # Uncomment for memory disk
 # options 	MD_ROOT
 # options 	MD_ROOT_SIZE=32768	# 32MB ram disk

Modified: head/sys/riscv/include/machdep.h
==============================================================================
--- head/sys/riscv/include/machdep.h	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/sys/riscv/include/machdep.h	Thu Aug 10 14:18:09 2017	(r322361)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2017 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -39,7 +39,10 @@
 
 struct riscv_bootparams {
 	vm_offset_t	kern_l1pt;	/* Kernel L1 base */
+	vm_offset_t	kern_phys;	/* Kernel base (physical) addr */
 	vm_offset_t	kern_stack;
+	vm_offset_t	dtbp_virt;	/* Device tree blob virtual addr */
+	vm_offset_t	dtbp_phys;	/* Device tree blob physical addr */
 };
 
 extern vm_paddr_t physmap[];

Modified: head/sys/riscv/include/riscvreg.h
==============================================================================
--- head/sys/riscv/include/riscvreg.h	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/sys/riscv/include/riscvreg.h	Thu Aug 10 14:18:09 2017	(r322361)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015-2016 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2017 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -51,6 +51,9 @@
 #define	EXCP_SUPERVISOR_ECALL		9
 #define	EXCP_HYPERVISOR_ECALL		10
 #define	EXCP_MACHINE_ECALL		11
+#define	EXCP_INST_PAGE_FAULT		12
+#define	EXCP_LOAD_PAGE_FAULT		13
+#define	EXCP_STORE_PAGE_FAULT		15
 #define	EXCP_INTR			(1ul << 63)
 
 #define	SSTATUS_UIE			(1 << 0)
@@ -68,7 +71,7 @@
 #define	SSTATUS_FS_MASK			(0x3 << SSTATUS_FS_SHIFT)
 #define	SSTATUS_XS_SHIFT		15
 #define	SSTATUS_XS_MASK			(0x3 << SSTATUS_XS_SHIFT)
-#define	SSTATUS_PUM			(1 << 18)
+#define	SSTATUS_SUM			(1 << 18)
 #define	SSTATUS32_SD			(1 << 63)
 #define	SSTATUS64_SD			(1 << 31)
 
@@ -140,6 +143,15 @@
 /* Note: sip register has no SIP_STIP bit in Spike simulator */
 #define	SIP_SSIP	(1 << 1)
 #define	SIP_STIP	(1 << 5)
+
+#define	SATP_PPN_S	0
+#define	SATP_PPN_M	(0xfffffffffff << SATP_PPN_S)
+#define	SATP_ASID_S	44
+#define	SATP_ASID_M	(0xffff << SATP_ASID_S)
+#define	SATP_MODE_S	60
+#define	SATP_MODE_M	(0xf << SATP_MODE_S)
+#define	SATP_MODE_SV39	(8ULL << SATP_MODE_S)
+#define	SATP_MODE_SV48	(9ULL << SATP_MODE_S)
 
 #if 0
 /* lowRISC TODO */

Modified: head/sys/riscv/include/sbi.h
==============================================================================
--- head/sys/riscv/include/sbi.h	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/sys/riscv/include/sbi.h	Thu Aug 10 14:18:09 2017	(r322361)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2016 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2016-2017 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -37,29 +37,97 @@
 #ifndef _MACHINE_SBI_H_
 #define	_MACHINE_SBI_H_
 
-typedef struct {
-	uint64_t base;
-	uint64_t size;
-	uint64_t node_id;
-} memory_block_info;
+#define	SBI_SET_TIMER			0
+#define	SBI_CONSOLE_PUTCHAR		1
+#define	SBI_CONSOLE_GETCHAR		2
+#define	SBI_CLEAR_IPI			3
+#define	SBI_SEND_IPI			4
+#define	SBI_REMOTE_FENCE_I		5
+#define	SBI_REMOTE_SFENCE_VMA		6
+#define	SBI_REMOTE_SFENCE_VMA_ASID	7
+#define	SBI_SHUTDOWN			8
 
-uint64_t sbi_query_memory(uint64_t id, memory_block_info *p);
-uint64_t sbi_hart_id(void);
-uint64_t sbi_num_harts(void);
-uint64_t sbi_timebase(void);
-void sbi_set_timer(uint64_t stime_value);
-void sbi_send_ipi(uint64_t hart_id);
-uint64_t sbi_clear_ipi(void);
-void sbi_shutdown(void);
+static __inline uint64_t
+sbi_call(uint64_t arg7, uint64_t arg0, uint64_t arg1, uint64_t arg2)
+{
 
-void sbi_console_putchar(unsigned char ch);
-int sbi_console_getchar(void);
+	register uintptr_t a0 __asm ("a0") = (uintptr_t)(arg0);
+	register uintptr_t a1 __asm ("a1") = (uintptr_t)(arg1);
+	register uintptr_t a2 __asm ("a2") = (uintptr_t)(arg2);
+	register uintptr_t a7 __asm ("a7") = (uintptr_t)(arg7);
+	__asm __volatile(			\
+		"ecall"				\
+		:"+r"(a0)			\
+		:"r"(a1), "r"(a2), "r"(a7)	\
+		:"memory");
 
-void sbi_remote_sfence_vm(uint64_t hart_mask_ptr, uint64_t asid);
-void sbi_remote_sfence_vm_range(uint64_t hart_mask_ptr, uint64_t asid, uint64_t start, uint64_t size);
-void sbi_remote_fence_i(uint64_t hart_mask_ptr);
+	return (a0);
+}
 
-uint64_t sbi_mask_interrupt(uint64_t which);
-uint64_t sbi_unmask_interrupt(uint64_t which);
+static __inline void
+sbi_console_putchar(int ch)
+{
+
+	sbi_call(SBI_CONSOLE_PUTCHAR, ch, 0, 0);
+}
+
+static __inline int
+sbi_console_getchar(void)
+{
+
+	return (sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0));
+}
+
+static __inline void
+sbi_set_timer(uint64_t val)
+{
+
+	sbi_call(SBI_SET_TIMER, val, 0, 0);
+}
+
+static __inline void
+sbi_shutdown(void)
+{
+
+	sbi_call(SBI_SHUTDOWN, 0, 0, 0);
+}
+
+static __inline void
+sbi_clear_ipi(void)
+{
+
+	sbi_call(SBI_CLEAR_IPI, 0, 0, 0);
+}
+
+static __inline void
+sbi_send_ipi(const unsigned long *hart_mask)
+{
+
+	sbi_call(SBI_SEND_IPI, (uint64_t)hart_mask, 0, 0);
+}
+
+static __inline void
+sbi_remote_fence_i(const unsigned long *hart_mask)
+{
+
+	sbi_call(SBI_REMOTE_FENCE_I, (uint64_t)hart_mask, 0, 0);
+}
+
+static __inline void
+sbi_remote_sfence_vma(const unsigned long *hart_mask,
+    unsigned long start, unsigned long size)
+{
+
+	sbi_call(SBI_REMOTE_SFENCE_VMA, (uint64_t)hart_mask, 0, 0);
+}
+
+static __inline void
+sbi_remote_sfence_vma_asid(const unsigned long *hart_mask,
+    unsigned long start, unsigned long size,
+    unsigned long asid)
+{
+
+	sbi_call(SBI_REMOTE_SFENCE_VMA_ASID, (uint64_t)hart_mask, 0, 0);
+}
 
 #endif /* !_MACHINE_SBI_H_ */

Modified: head/sys/riscv/riscv/cpufunc_asm.S
==============================================================================
--- head/sys/riscv/riscv/cpufunc_asm.S	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/sys/riscv/riscv/cpufunc_asm.S	Thu Aug 10 14:18:09 2017	(r322361)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015-2016 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2017 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -51,12 +51,12 @@ END(riscv_nullop)
  */
 
 ENTRY(riscv_tlb_flushID)
-	sfence.vm
+	sfence.vma
 	ret
 END(riscv_tlb_flushID)
 
 ENTRY(riscv_tlb_flushID_SE)
-	sfence.vm
+	sfence.vma
 	ret
 END(riscv_tlb_flushID_SE)
 
@@ -64,7 +64,7 @@ END(riscv_tlb_flushID_SE)
  * void riscv_dcache_wb_range(vm_offset_t, vm_size_t)
  */
 ENTRY(riscv_dcache_wb_range)
-	sfence.vm
+	sfence.vma
 	ret
 END(riscv_dcache_wb_range)
 
@@ -72,7 +72,7 @@ END(riscv_dcache_wb_range)
  * void riscv_dcache_wbinv_range(vm_offset_t, vm_size_t)
  */
 ENTRY(riscv_dcache_wbinv_range)
-	sfence.vm
+	sfence.vma
 	ret
 END(riscv_dcache_wbinv_range)
 
@@ -80,7 +80,7 @@ END(riscv_dcache_wbinv_range)
  * void riscv_dcache_inv_range(vm_offset_t, vm_size_t)
  */
 ENTRY(riscv_dcache_inv_range)
-	sfence.vm
+	sfence.vma
 	ret
 END(riscv_dcache_inv_range)
 
@@ -89,7 +89,7 @@ END(riscv_dcache_inv_range)
  */
 ENTRY(riscv_idcache_wbinv_range)
 	fence.i
-	sfence.vm
+	sfence.vma
 	ret
 END(riscv_idcache_wbinv_range)
 

Modified: head/sys/riscv/riscv/exception.S
==============================================================================
--- head/sys/riscv/riscv/exception.S	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/sys/riscv/riscv/exception.S	Thu Aug 10 14:18:09 2017	(r322361)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015-2016 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2017 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -116,8 +116,11 @@ __FBSDID("$FreeBSD$");
 .macro load_registers el
 	ld	t0, (TF_SSTATUS)(sp)
 .if \el == 0
-	/* Ensure user interrupts will be enabled on eret. */
-	li	t1, SSTATUS_SPIE
+	/*
+	 * Ensure user interrupts will be enabled on eret
+	 * and supervisor mode can access userspace on trap.
+	 */
+	li	t1, (SSTATUS_SPIE | SSTATUS_SUM)
 	or	t0, t0, t1
 .else
 	/*

Modified: head/sys/riscv/riscv/intr_machdep.c
==============================================================================
--- head/sys/riscv/riscv/intr_machdep.c	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/sys/riscv/riscv/intr_machdep.c	Thu Aug 10 14:18:09 2017	(r322361)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015-2016 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2017 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -265,12 +265,15 @@ riscv_unmask_ipi(void)
 static void
 ipi_send(struct pcpu *pc, int ipi)
 {
+	uintptr_t mask;
 
 	CTR3(KTR_SMP, "%s: cpu=%d, ipi=%x", __func__, pc->pc_cpuid, ipi);
 
 	atomic_set_32(&pc->pc_pending_ipis, ipi);
-	sbi_send_ipi(pc->pc_cpuid);
+	mask = (1 << (pc->pc_cpuid));
 
+	sbi_send_ipi(&mask);
+
 	CTR1(KTR_SMP, "%s: sent", __func__);
 }
 
@@ -302,16 +305,20 @@ void
 ipi_selected(cpuset_t cpus, u_int ipi)
 {
 	struct pcpu *pc;
+	uintptr_t mask;
 
 	CTR1(KTR_SMP, "ipi_selected: ipi: %x", ipi);
 
+	mask = 0;
 	STAILQ_FOREACH(pc, &cpuhead, pc_allcpu) {
 		if (CPU_ISSET(pc->pc_cpuid, &cpus)) {
 			CTR3(KTR_SMP, "%s: pc: %p, ipi: %x\n", __func__, pc,
 			    ipi);
-			ipi_send(pc, ipi);
+			atomic_set_32(&pc->pc_pending_ipis, ipi);
+			mask |= (1 << (pc->pc_cpuid));
 		}
 	}
+	sbi_send_ipi(&mask);
 }
 
 #endif

Modified: head/sys/riscv/riscv/locore.S
==============================================================================
--- head/sys/riscv/riscv/locore.S	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/sys/riscv/riscv/locore.S	Thu Aug 10 14:18:09 2017	(r322361)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2015-2016 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2017 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -53,149 +53,119 @@
 	.text
 	.globl _start
 _start:
-	/* Setup supervisor trap vector */
-	la	t0, cpu_exception_handler
-	csrw	stvec, t0
+	/* Get the physical address kernel loaded to */
+	la	t0, virt_map
+	ld	t1, 0(t0)
+	sub	t1, t1, t0
+	li	t2, KERNBASE
+	sub	s9, t2, t1	/* s9 = physmem base */
+	mv	s10, a0		/* s10 = hart id */
+	mv	s11, a1		/* s11 = dtbp */
 
-	/* Ensure sscratch is zero */
-	li	t0, 0
-	csrw	sscratch, t0
+	li	t0, SSTATUS_SUM
+	csrs	sstatus, t0
 
-	/* Load physical memory information */
-	li	a0, 0
-	la	a1, memory_info
-	call	sbi_query_memory
-
-	/* Store base to s6 */
-	la	s6, memory_info
-	ld	s6, 0(s6)	/* s6 = physmem base */
-
 	/* Direct secondary cores to mpentry */
-	call	sbi_hart_id
-	bnez	a0, mpentry
+	bnez	s10, mpentry
 
 	/*
 	 * Page tables
 	 */
 
-	/* Create an L1 page for early devmap */
+	/* Add L1 entry for kernel */
 	la	s1, pagetable_l1
-	la	s2, pagetable_l2_devmap	/* Link to next level PN */
-	li	t0, KERNBASE
-	sub	s2, s2, t0
-	add	s2, s2, s6
+	la	s2, pagetable_l2	/* Link to next level PN */
 	srli	s2, s2, PAGE_SHIFT
 
-	li	a5, (VM_MAX_KERNEL_ADDRESS - L2_SIZE)
+	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 single level1 PTE entry to position */
+	/* Store L1 PTE entry to position */
 	li	a6, PTE_SIZE
 	mulw	a5, a5, a6
 	add	t0, s1, a5
 	sd	t6, (t0)
 
-	/* Create an L1 page for SBI */
-	la	s1, pagetable_l1
-	la	s2, pagetable_l2_sbi	/* Link to next level PN */
-	li	t0, KERNBASE
-	sub	s2, s2, t0
-	add	s2, s2, s6
-	srli	s2, s2, PAGE_SHIFT
-	li	a5, 511
-	li	t4, PTE_V
-	slli	t5, s2, PTE_PPN0_S	/* (s2 << PTE_PPN0_S) */
-	or	t6, t4, t5
+	/* Level 2 superpages (512 x 2MiB) */
+	la	s1, pagetable_l2
+	srli	t4, s9, 21		/* Div physmem base by 2 MiB */
+	li	t2, 512			/* Build 512 entries */
+	add	t3, t4, t2
+	li	t5, 0
+2:
+	li	t0, (PTE_V | PTE_RWX | PTE_D)
+	slli	t2, t4, PTE_PPN1_S	/* << PTE_PPN1_S */
+	or	t5, t0, t2
+	sd	t5, (s1)		/* Store PTE entry to position */
+	addi	s1, s1, PTE_SIZE
 
-	/* Store SBI L1 PTE entry to position */
-	li	a6, PTE_SIZE
-	mulw	a5, a5, a6
-	add	t0, s1, a5
-	sd	t6, (t0)
+	addi	t4, t4, 1
+	bltu	t4, t3, 2b
 
-	/* Create an L2 page for SBI */
-	la	s1, pagetable_l2_sbi
-	la	s2, pagetable_l3_sbi	/* Link to next level PN */
-	li	t0, KERNBASE
-	sub	s2, s2, t0
-	add	s2, s2, s6
+	/* Create an L1 page for early devmap */
+	la	s1, pagetable_l1
+	la	s2, pagetable_l2_devmap	/* Link to next level PN */
 	srli	s2, s2, PAGE_SHIFT
-	li	a5, 511
+
+	li	a5, (VM_MAX_KERNEL_ADDRESS - L2_SIZE)
+	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 SBI L2 PTE entry to position */
+	/* Store single level1 PTE entry to position */
 	li	a6, PTE_SIZE
 	mulw	a5, a5, a6
 	add	t0, s1, a5
 	sd	t6, (t0)
 
-	/* Create an L3 page for SBI */
-	la	s1, pagetable_l3_sbi
-	li	s2, 0x8000b000
+	/* Create an L2 page superpage for DTB */
+	la	s1, pagetable_l2_devmap
+	mv	s2, s11
 	srli	s2, s2, PAGE_SHIFT
-	li	a5, 511
-	li	t4, PTE_V | PTE_RX | PTE_W
-	slli	t5, s2, PTE_PPN0_S	/* (s2 << PTE_PPN0_S) */
-	or	t6, t4, t5
 
-	/* Store SBI L3 PTE entry to position */
-	li	a6, PTE_SIZE
-	mulw	a5, a5, a6
-	add	t0, s1, a5
-	sd	t6, (t0)
-	/* END SBI page creation */
+	li	t0, (PTE_V | PTE_RWX | PTE_D)
+	slli	t2, s2, PTE_PPN0_S	/* << PTE_PPN0_S */
+	or	t0, t0, t2
 
-	/* Add L1 entry for kernel */
-	la	s1, pagetable_l1
-	la	s2, pagetable_l2	/* Link to next level PN */
-	li	t0, KERNBASE
-	sub	s2, s2, t0
-	add	s2, s2, s6
-	srli	s2, s2, PAGE_SHIFT
-
-	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 */
+	/* Store PTE entry to position */
 	li	a6, PTE_SIZE
+	li	a5, 510
 	mulw	a5, a5, a6
-	add	t0, s1, a5
-	sd	t6, (t0)
+	add	t1, s1, a5
+	sd	t0, (t1)
 
-	/* Level 2 superpages (512 x 2MiB) */
-	la	s1, pagetable_l2
-	srli	t4, s6, 21		/* Div physmem base by 2 MiB */
-	li	t2, 512			/* Build 512 entries */
-	add	t3, t4, t2
-	li	t5, 0
-2:
-	li	t0, (PTE_V | PTE_RWX)
-	slli	t2, t4, PTE_PPN1_S	/* << PTE_PPN1_S */
-	or	t5, t0, t2
-	sd	t5, (s1)		/* Store PTE entry to position */
-	addi	s1, s1, PTE_SIZE
+	/* Page tables END */
 
-	addi	t4, t4, 1
-	bltu	t4, t3, 2b
+	/* Setup supervisor trap vector */
+	la	t0, va
+	sub	t0, t0, s9
+	li	t1, KERNBASE
+	add	t0, t0, t1
+	csrw	stvec, t0
 
 	/* Set page tables base register */
 	la	s2, pagetable_l1
-	li	t0, KERNBASE
-	sub	s2, s2, t0
-	add	s2, s2, s6
 	srli	s2, s2, PAGE_SHIFT
+	li	t0, SATP_MODE_SV39
+	or	s2, s2, t0
+	sfence.vma
 	csrw	sptbr, s2
+va:
 
+	/* Setup supervisor trap vector */
+	la	t0, cpu_exception_handler
+	csrw	stvec, t0
+
+	/* Ensure sscratch is zero */
+	li	t0, 0
+	csrw	sscratch, t0
+
 	/* Initialize stack pointer */
 	la	s3, initstack_end
 	mv	sp, s3
@@ -210,14 +180,19 @@ _start:
 	bltu	a0, s1, 1b
 
 	/* Fill riscv_bootparams */
-	addi	sp, sp, -16
+	addi	sp, sp, -40
 
 	la	t0, pagetable_l1
 	sd	t0, 0(sp) /* kern_l1pt */
+	sd	s9, 8(sp) /* kern_phys */
 
 	la	t0, initstack_end
-	sd	t0, 8(sp) /* kern_stack */
+	sd	t0, 16(sp) /* kern_stack */
 
+	li	t0, (VM_MAX_KERNEL_ADDRESS - 2 * L2_SIZE)
+	sd	t0, 24(sp) /* dtbp_virt */
+	sd	s11, 32(sp) /* dtbp_phys */
+
 	mv	a0, sp
 	call	_C_LABEL(initriscv)	/* Off we go */
 	call	_C_LABEL(mi_startup)
@@ -258,15 +233,17 @@ pagetable_l2:
 	.space	PAGE_SIZE
 pagetable_l2_devmap:
 	.space	PAGE_SIZE
-pagetable_l2_sbi:
-	.space	PAGE_SIZE
-pagetable_l3_sbi:
-	.space	PAGE_SIZE
 
-	.globl memory_info
-memory_info:
-	.space	(24)
+        .align 3
+virt_map:
+        .quad   virt_map
 
+	/* Not in use, but required for linking. */
+	.align 3
+	.globl __global_pointer$
+__global_pointer$:
+	.space	8
+
 	.globl init_pt_va
 init_pt_va:
 	.quad pagetable_l2	/* XXX: Keep page tables VA */
@@ -284,6 +261,37 @@ END(mpentry)
  * Called by a core when it is being brought online.
  */
 ENTRY(mpentry)
+	/* Setup stack pointer */
+	la	t0, secondary_stacks
+	li	t1, (PAGE_SIZE * KSTACK_PAGES)
+	mulw	t1, t1, s10
+	add	t0, t0, t1
+	sub	t0, t0, s9
+	li	t1, KERNBASE
+	add	sp, t0, t1
+
+	/* Setup supervisor trap vector */
+	la	t0, mpva
+	sub	t0, t0, s9
+	li	t1, KERNBASE
+	add	t0, t0, t1
+	csrw	stvec, t0
+
+	/* Set page tables base register */
+	la	s2, pagetable_l1
+	srli	s2, s2, PAGE_SHIFT
+	li	t0, SATP_MODE_SV39
+	or	s2, s2, t0
+	sfence.vma
+	csrw	sptbr, s2
+mpva:
+	/* Setup supervisor trap vector */
+	la	t0, cpu_exception_handler
+	csrw	stvec, t0
+
+	/* Ensure sscratch is zero */
+	li	t0, 0
+	csrw	sscratch, t0
 	/*
 	 * Calculate the offset to __riscv_boot_ap
 	 * for current core, cpuid in a0.
@@ -298,20 +306,6 @@ ENTRY(mpentry)
 	/* Wait the kernel to be ready */
 	lw	t1, 0(t0)
 	beqz	t1, 1b
-
-	/* Set page tables base register */
-	la	s2, pagetable_l1
-	li	t0, KERNBASE
-	sub	s2, s2, t0
-	add	s2, s2, s6
-	srli	s2, s2, PAGE_SHIFT
-	csrw	sptbr, s2
-
-	/* Setup stack pointer */
-	la	t0, secondary_stacks
-	li	t1, (PAGE_SIZE * KSTACK_PAGES)
-	mulw	t1, t1, a0
-	add	sp, t0, t1
 
 	call	init_secondary
 END(mpentry)

Modified: head/sys/riscv/riscv/machdep.c
==============================================================================
--- head/sys/riscv/riscv/machdep.c	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/sys/riscv/riscv/machdep.c	Thu Aug 10 14:18:09 2017	(r322361)
@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 2014 Andrew Turner
- * Copyright (c) 2015-2016 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2017 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * Portions of this software were developed by SRI International and the
@@ -105,6 +105,8 @@ int cold = 1;
 long realmem = 0;
 long Maxmem = 0;
 
+#define	DTB_SIZE_MAX	(1024 * 1024)
+
 #define	PHYSMAP_SIZE	(2 * (VM_PHYSSEG_MAX - 1))
 vm_paddr_t physmap[PHYSMAP_SIZE];
 u_int physmap_idx;
@@ -117,7 +119,6 @@ int64_t idcache_line_size;	/* The minimum cache line s
 
 extern int *end;
 extern int *initstack_end;
-extern memory_block_info memory_info;
 
 struct pcpu *pcpup;
 
@@ -315,6 +316,9 @@ CTASSERT(sizeof(((struct trapframe *)0)->tf_s) ==
 CTASSERT(sizeof(((struct trapframe *)0)->tf_t) ==
     sizeof((struct reg *)0)->t);
 
+/* Support for FDT configurations only. */
+CTASSERT(FDT);
+
 int
 get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret)
 {
@@ -714,16 +718,13 @@ add_physmap_entry(uint64_t base, uint64_t length, vm_p
 
 #ifdef FDT
 static void
-try_load_dtb(caddr_t kmdp)
+try_load_dtb(caddr_t kmdp, vm_offset_t dtbp)
 {
-	vm_offset_t dtbp;
 
 #if defined(FDT_DTB_STATIC)
 	dtbp = (vm_offset_t)&fdt_static_dtb;
-#else
-	/* TODO */
-	dtbp = (vm_offset_t)NULL;
 #endif
+
 	if (dtbp == (vm_offset_t)NULL) {
 		printf("ERROR loading DTB\n");
 		return;
@@ -803,9 +804,14 @@ fake_preload_metadata(struct riscv_bootparams *rvbp __
 void
 initriscv(struct riscv_bootparams *rvbp)
 {
+	struct mem_region mem_regions[FDT_MEM_REGIONS];
+	vm_offset_t rstart, rend;
+	vm_offset_t s, e;
+	int mem_regions_sz;
 	vm_offset_t lastaddr;
 	vm_size_t kernlen;
 	caddr_t kmdp;
+	int i;
 
 	/* Set the module data location */
 	lastaddr = fake_preload_metadata(rvbp);
@@ -821,27 +827,35 @@ initriscv(struct riscv_bootparams *rvbp)
 	kern_envp = NULL;
 
 #ifdef FDT
-	try_load_dtb(kmdp);
+	try_load_dtb(kmdp, rvbp->dtbp_virt);
 #endif
 
 	/* Load the physical memory ranges */
 	physmap_idx = 0;
 
-#if 0
-	struct mem_region mem_regions[FDT_MEM_REGIONS];
-	int mem_regions_sz;
-	int i;
+#ifdef FDT
 	/* Grab physical memory regions information from device tree. */
 	if (fdt_get_mem_regions(mem_regions, &mem_regions_sz, NULL) != 0)
 		panic("Cannot get physical memory regions");
-	for (i = 0; i < mem_regions_sz; i++)
-		add_physmap_entry(mem_regions[i].mr_start,
-		    mem_regions[i].mr_size, physmap, &physmap_idx);
-#endif
 
-	add_physmap_entry(memory_info.base, memory_info.size,
-	    physmap, &physmap_idx);
+	s = rvbp->dtbp_phys;
+	e = s + DTB_SIZE_MAX;
 
+	for (i = 0; i < mem_regions_sz; i++) {
+		rstart = mem_regions[i].mr_start;
+		rend = (mem_regions[i].mr_start + mem_regions[i].mr_size);
+
+		if ((rstart < s) && (rend > e)) {
+			/* Exclude DTB region. */
+			add_physmap_entry(rstart, (s - rstart), physmap, &physmap_idx);
+			add_physmap_entry(e, (rend - e), physmap, &physmap_idx);
+		} else {
+			add_physmap_entry(mem_regions[i].mr_start,
+			    mem_regions[i].mr_size, physmap, &physmap_idx);
+		}
+	}
+#endif
+
 	/* Set the pcpu data, this is needed by pmap_bootstrap */
 	pcpup = &__pcpu[0];
 	pcpu_init(pcpup, 0, sizeof(struct pcpu));
@@ -858,7 +872,7 @@ initriscv(struct riscv_bootparams *rvbp)
 
 	/* Bootstrap enough of pmap to enter the kernel proper */
 	kernlen = (lastaddr - KERNBASE);
-	pmap_bootstrap(rvbp->kern_l1pt, memory_info.base, kernlen);
+	pmap_bootstrap(rvbp->kern_l1pt, mem_regions[0].mr_start, kernlen);
 
 	cninit();
 
@@ -866,7 +880,7 @@ initriscv(struct riscv_bootparams *rvbp)
 
 	/* set page table base register for thread0 */
 	thread0.td_pcb->pcb_l1addr = \
-	    (rvbp->kern_l1pt - KERNBASE + memory_info.base);
+	    (rvbp->kern_l1pt - KERNBASE + rvbp->kern_phys);
 
 	msgbufinit(msgbufp, msgbufsize);
 	mutex_init();

Modified: head/sys/riscv/riscv/nexus.c
==============================================================================
--- head/sys/riscv/riscv/nexus.c	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/sys/riscv/riscv/nexus.c	Thu Aug 10 14:18:09 2017	(r322361)
@@ -156,6 +156,8 @@ nexus_attach(device_t dev)
 	if (rman_init(&irq_rman) || rman_manage_region(&irq_rman, 0, ~0))
 		panic("nexus_attach irq_rman");
 
+	nexus_add_child(dev, 8, "timer", 0);
+	nexus_add_child(dev, 9, "rcons", 0);
 	nexus_add_child(dev, 10, "ofwbus", 0);
 
 	bus_generic_probe(dev);

Modified: head/sys/riscv/riscv/pmap.c
==============================================================================
--- head/sys/riscv/riscv/pmap.c	Thu Aug 10 13:51:04 2017	(r322360)
+++ head/sys/riscv/riscv/pmap.c	Thu Aug 10 14:18:09 2017	(r322361)
@@ -13,7 +13,7 @@
  * All rights reserved.
  * Copyright (c) 2014 The FreeBSD Foundation
  * All rights reserved.
- * Copyright (c) 2015-2016 Ruslan Bukin <br at bsdpad.com>
+ * Copyright (c) 2015-2017 Ruslan Bukin <br at bsdpad.com>
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
@@ -596,8 +596,10 @@ pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart,
 			min_pa = physmap[i];
 		if (physmap[i + 1] > max_pa)
 			max_pa = physmap[i + 1];
-		break;
 	}
+	printf("physmap_idx %lx\n", physmap_idx);
+	printf("min_pa %lx\n", min_pa);
+	printf("max_pa %lx\n", max_pa);
 
 	/* Create a direct map region early so we can use it for pa -> va */
 	pmap_bootstrap_dmap(l1pt, min_pa, max_pa);
@@ -771,7 +773,7 @@ pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
 	/* TODO */
 
 	sched_pin();
-	__asm __volatile("sfence.vm");
+	__asm __volatile("sfence.vma %0" :: "r" (va) : "memory");
 	sched_unpin();

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list