diff --git a/lib/csu/riscv/crt1.c b/lib/csu/riscv/crt1.c
index 0c3fbe656add..0905e84e7b58 100644
--- a/lib/csu/riscv/crt1.c
+++ b/lib/csu/riscv/crt1.c
@@ -1,7 +1,7 @@
/* LINTLIBRARY */
/*-
* Copyright 1996-1998 John D. Polstra.
- * Copyright (c) 2015 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* 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
diff --git a/lib/csu/riscv/crti.S b/lib/csu/riscv/crti.S
index df6027eee8b6..4aad1486c5c6 100644
--- a/lib/csu/riscv/crti.S
+++ b/lib/csu/riscv/crti.S
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -35,12 +35,13 @@
#include
__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",@progbits
- .align 2
+ .align 0
.globl _init
.type _init,@function
_init:
@@ -48,7 +49,7 @@ _init:
sd ra, 0(sp)
.section .fini,"ax",@progbits
- .align 2
+ .align 0
.globl _fini
.type _fini,@function
_fini:
diff --git a/lib/libc/riscv/gen/fabs.S b/lib/libc/riscv/gen/fabs.S
index 3fc791a452f4..7cd303336cf7 100644
--- a/lib/libc/riscv/gen/fabs.S
+++ b/lib/libc/riscv/gen/fabs.S
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -35,7 +35,9 @@
#include
__FBSDID("$FreeBSD$");
+#ifndef SOFTFLOAT
ENTRY(fabs)
fabs.d fa0, fa0
ret
END(fabs)
+#endif
diff --git a/libexec/rtld-elf/riscv/reloc.c b/libexec/rtld-elf/riscv/reloc.c
index a0fedf1c2416..303d1a4737b0 100644
--- a/libexec/rtld-elf/riscv/reloc.c
+++ b/libexec/rtld-elf/riscv/reloc.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* 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);
diff --git a/share/mk/bsd.cpu.mk b/share/mk/bsd.cpu.mk
index 0daca60a0a7e..80a19bc622e5 100644
--- a/share/mk/bsd.cpu.mk
+++ b/share/mk/bsd.cpu.mk
@@ -364,8 +364,11 @@ CFLAGS += -mcpu=8540 -Wa,-me500 -mspe=yes -mabi=spe -mfloat-gprs=double
.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
diff --git a/share/mk/bsd.stand.mk b/share/mk/bsd.stand.mk
index 838a3ca7c45f..bb20d98d1f96 100644
--- a/share/mk/bsd.stand.mk
+++ b/share/mk/bsd.stand.mk
@@ -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
diff --git a/sys/boot/fdt/dts/riscv/lowrisc.dts b/sys/boot/fdt/dts/riscv/lowrisc.dts
deleted file mode 100644
index ac47eb743a6f..000000000000
--- a/sys/boot/fdt/dts/riscv/lowrisc.dts
+++ /dev/null
@@ -1,108 +0,0 @@
-/*-
- * Copyright (c) 2016 Ruslan Bukin
- * All rights reserved.
- *
- * Portions of this software were developed by SRI International and the
- * University of Cambridge Computer Laboratory under DARPA/AFRL contract
- * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
- *
- * Portions of this software were developed by the University of Cambridge
- * Computer Laboratory as part of the CTSRD Project, with support from the
- * UK Higher Education Innovation Fund (HEIF).
- *
- * 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 AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-/dts-v1/;
-
-/ {
- model = "UC Berkeley Spike Simulator RV64I";
- compatible = "riscv,rv64i";
- #address-cells = <1>;
- #size-cells = <1>;
- #interrupt-cells = <1>;
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- compatible = "riscv,rv64i";
- reg = <0x40002000>;
- };
- };
-
- aliases {
- serial0 = &serial0;
- };
-
- memory {
- device_type = "memory";
- reg = <0x0 0x8000000>; /* 128MB at 0x0 */
- };
-
- soc {
- #address-cells = <1>;
- #size-cells = <1>;
- #interrupt-cells = <1>;
-
- compatible = "simple-bus";
- ranges;
-
- pic0: pic@0 {
- compatible = "riscv,pic";
- interrupt-controller;
- };
-
- serial0: serial@80001000 {
- compatible = "ns16550";
- reg = <0x80001000 0x1000>;
- reg-shift = <2>;
- interrupts = < 4 >;
- interrupt-parent = <&pic0>;
- current-speed = <115200>;
- clock-frequency = < 1000000 >;
- status = "okay";
- };
-
- spi0: spi@80010000 {
- compatible = "xlnx,xps-spi-3.2";
- reg = <0x80010000 0x1000>;
- };
-
- timer0: timer@0 {
- compatible = "riscv,timer";
- interrupts = < 1 >;
- interrupt-parent = < &pic0 >;
- clock-frequency = < 1000000 >;
- };
- };
-
- chosen {
- bootargs = "-v";
- stdin = "serial0";
- stdout = "serial0";
- };
-};
diff --git a/sys/boot/fdt/dts/riscv/qemu.dts b/sys/boot/fdt/dts/riscv/qemu.dts
deleted file mode 100644
index df6fe0086ae5..000000000000
--- a/sys/boot/fdt/dts/riscv/qemu.dts
+++ /dev/null
@@ -1,105 +0,0 @@
-/*-
- * Copyright (c) 2016 Ruslan Bukin
- * All rights reserved.
- *
- * Portions of this software were developed by SRI International and the
- * University of Cambridge Computer Laboratory under DARPA/AFRL contract
- * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
- *
- * Portions of this software were developed by the University of Cambridge
- * Computer Laboratory as part of the CTSRD Project, with support from the
- * UK Higher Education Innovation Fund (HEIF).
- *
- * 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 AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-/dts-v1/;
-
-/ {
- model = "QEMU RV64";
- compatible = "riscv,rv64";
- #address-cells = <1>;
- #size-cells = <1>;
- #interrupt-cells = <1>;
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- compatible = "riscv,rv64";
- reg = <0x0>;
- };
- };
-
- aliases {
- console0 = &console0;
- };
-
- memory {
- /*
- * This is not used currently.
- * We take information from sbi_query_memory.
- */
- device_type = "memory";
- reg = <0x80000000 0x40000000>; /* 1GB at 0x80000000 */
- };
-
- soc {
- #address-cells = <1>;
- #size-cells = <1>;
- #interrupt-cells = <1>;
-
- compatible = "simple-bus";
- ranges;
-
- pic0: pic@0 {
- compatible = "riscv,pic";
- interrupt-controller;
- };
-
- timer0: timer@0 {
- compatible = "riscv,timer";
- reg = < 0x40000000 0x0008 >, /* rtc */
- < 0x40000008 0x1000 >; /* timecmp */
- interrupts = < 5 >;
- interrupt-parent = < &pic0 >;
- clock-frequency = < 400000000 >;
- };
-
- console0: console@0 {
- compatible = "riscv,console";
- status = "okay";
- interrupts = < 1 >;
- interrupt-parent = < &pic0 >;
- };
- };
-
- chosen {
- bootargs = "-v";
- stdin = "console0";
- stdout = "console0";
- };
-};
diff --git a/sys/boot/fdt/dts/riscv/rocket.dts b/sys/boot/fdt/dts/riscv/rocket.dts
deleted file mode 100644
index 691f41209cf0..000000000000
--- a/sys/boot/fdt/dts/riscv/rocket.dts
+++ /dev/null
@@ -1,105 +0,0 @@
-/*-
- * Copyright (c) 2015-2016 Ruslan Bukin
- * All rights reserved.
- *
- * Portions of this software were developed by SRI International and the
- * University of Cambridge Computer Laboratory under DARPA/AFRL contract
- * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
- *
- * Portions of this software were developed by the University of Cambridge
- * Computer Laboratory as part of the CTSRD Project, with support from the
- * UK Higher Education Innovation Fund (HEIF).
- *
- * 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 AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-/dts-v1/;
-
-/ {
- model = "RocketChip RV64";
- compatible = "riscv,rv64";
- #address-cells = <1>;
- #size-cells = <1>;
- #interrupt-cells = <1>;
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- compatible = "riscv,rv64";
- reg = <0x0>;
- };
- };
-
- aliases {
- console0 = &console0;
- };
-
- memory {
- /*
- * This is not used currently.
- * We take information from sbi_query_memory.
- */
- device_type = "memory";
- reg = <0x80000000 0x10000000>; /* 256MB at 0x80000000 */
- };
-
- soc {
- #address-cells = <1>;
- #size-cells = <1>;
- #interrupt-cells = <1>;
-
- compatible = "simple-bus";
- ranges;
-
- pic0: pic@0 {
- compatible = "riscv,pic";
- interrupt-controller;
- };
-
- timer0: timer@0 {
- compatible = "riscv,timer";
- reg = < 0x4400bff8 0x0008 >, /* rtc */
- < 0x44004000 0x1000 >; /* timecmp */
- interrupts = < 5 >;
- interrupt-parent = < &pic0 >;
- clock-frequency = < 1000000 >;
- };
-
- console0: console@0 {
- compatible = "riscv,console";
- status = "okay";
- interrupts = < 1 >;
- interrupt-parent = < &pic0 >;
- };
- };
-
- chosen {
- bootargs = "-v";
- stdin = "console0";
- stdout = "console0";
- };
-};
diff --git a/sys/boot/fdt/dts/riscv/spike.dts b/sys/boot/fdt/dts/riscv/spike.dts
deleted file mode 100644
index 30ce7f5e13dc..000000000000
--- a/sys/boot/fdt/dts/riscv/spike.dts
+++ /dev/null
@@ -1,111 +0,0 @@
-/*-
- * Copyright (c) 2015-2016 Ruslan Bukin
- * All rights reserved.
- *
- * Portions of this software were developed by SRI International and the
- * University of Cambridge Computer Laboratory under DARPA/AFRL contract
- * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
- *
- * Portions of this software were developed by the University of Cambridge
- * Computer Laboratory as part of the CTSRD Project, with support from the
- * UK Higher Education Innovation Fund (HEIF).
- *
- * 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 AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-/dts-v1/;
-
-/ {
- model = "UC Berkeley Spike Simulator RV64";
- compatible = "riscv,rv64";
- #address-cells = <1>;
- #size-cells = <1>;
- #interrupt-cells = <1>;
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- compatible = "riscv,rv64";
- reg = <0x0>;
- };
-
- cpu@1 {
- device_type = "cpu";
- compatible = "riscv,rv64";
- reg = <0x0>;
- };
- };
-
- aliases {
- console0 = &console0;
- };
-
- memory {
- /*
- * This is not used currently.
- * We take information from sbi_query_memory.
- */
- device_type = "memory";
- reg = <0x80000000 0x40000000>; /* 1GB at 0x80000000 */
- };
-
- soc {
- #address-cells = <1>;
- #size-cells = <1>;
- #interrupt-cells = <1>;
-
- compatible = "simple-bus";
- ranges;
-
- pic0: pic@0 {
- compatible = "riscv,pic";
- interrupt-controller;
- };
-
- timer0: timer@0 {
- compatible = "riscv,timer";
- reg = < 0x40000000 0x0008 >, /* rtc */
- < 0x40000008 0x1000 >; /* timecmp */
- interrupts = < 5 >;
- interrupt-parent = < &pic0 >;
- clock-frequency = < 1000000 >;
- };
-
- console0: console@0 {
- compatible = "riscv,console";
- status = "okay";
- interrupts = < 1 >;
- interrupt-parent = < &pic0 >;
- };
- };
-
- chosen {
- bootargs = "-v";
- stdin = "console0";
- stdout = "console0";
- };
-};
diff --git a/sys/conf/Makefile.riscv b/sys/conf/Makefile.riscv
index 133ac964372e..1285acc886a2 100644
--- a/sys/conf/Makefile.riscv
+++ b/sys/conf/Makefile.riscv
@@ -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
diff --git a/sys/conf/files.riscv b/sys/conf/files.riscv
index 2a27bb1f18ad..aa035a6a7019 100644
--- a/sys/conf/files.riscv
+++ b/sys/conf/files.riscv
@@ -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
diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk
index 0f4c62a5c507..fa444e196000 100644
--- a/sys/conf/kern.mk
+++ b/sys/conf/kern.mk
@@ -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
diff --git a/sys/riscv/conf/GENERIC b/sys/riscv/conf/GENERIC
index a9c3c6fbdad0..23b487411598 100644
--- a/sys/riscv/conf/GENERIC
+++ b/sys/riscv/conf/GENERIC
@@ -75,6 +75,9 @@ options RACCT_DEFAULT_TO_DISABLED # Set kern.racct.enable=0 by default
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
diff --git a/sys/riscv/conf/LOWRISC b/sys/riscv/conf/LOWRISC
deleted file mode 100644
index f4a9c69baec7..000000000000
--- a/sys/riscv/conf/LOWRISC
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# Kernel configuration file for lowRISC.
-#
-# For more information on this file, please read the config(5) manual page,
-# and/or the handbook section on Kernel Configuration Files:
-#
-# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
-#
-# The handbook is also available locally in /usr/share/doc/handbook
-# if you've installed the doc distribution, otherwise always see the
-# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
-# latest information.
-#
-# An exhaustive list of options and more detailed explanations of the
-# device lines is also present in the ../../conf/NOTES and NOTES files.
-# If you are in doubt as to the purpose or necessity of a line, check first
-# in NOTES.
-#
-# $FreeBSD$
-
-include GENERIC
-ident LOWRISC
-
-hints "LOWRISC.hints"
-
-options ROOTDEVNAME=\"ufs:mmcsd0s2\"
-
-# MMC/SD
-device mmc
-device mmcsd
-# device mmc_spi
-
-# SPI
-device spibus
-device xilinx_spi
-
-# Serial (COM) ports
-device uart # Generic UART driver
-device uart_ns8250 # ns8250-type UART driver
-
-# RISCVTODO: This needs to be done via loader (when it's available).
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=lowrisc.dts
diff --git a/sys/riscv/conf/LOWRISC.hints b/sys/riscv/conf/LOWRISC.hints
deleted file mode 100644
index f8ed5ff7691a..000000000000
--- a/sys/riscv/conf/LOWRISC.hints
+++ /dev/null
@@ -1,5 +0,0 @@
-# $FreeBSD$
-
-# MMC device
-hint.mmc_spi.0.at="spibus0"
-hint.mmc_spi.0.cs=0
diff --git a/sys/riscv/conf/QEMU b/sys/riscv/conf/QEMU
deleted file mode 100644
index 7411aefc6b1d..000000000000
--- a/sys/riscv/conf/QEMU
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Kernel configuration file for QEMU emulator.
-#
-# For more information on this file, please read the config(5) manual page,
-# and/or the handbook section on Kernel Configuration Files:
-#
-# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
-#
-# The handbook is also available locally in /usr/share/doc/handbook
-# if you've installed the doc distribution, otherwise always see the
-# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
-# latest information.
-#
-# An exhaustive list of options and more detailed explanations of the
-# device lines is also present in the ../../conf/NOTES and NOTES files.
-# If you are in doubt as to the purpose or necessity of a line, check first
-# in NOTES.
-#
-# $FreeBSD$
-
-include GENERIC
-ident QEMU
-
-device rcons
-options ROOTDEVNAME=\"ufs:/dev/md0\"
-
-# RISCVTODO: This needs to be done via loader (when it's available).
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=qemu.dts
diff --git a/sys/riscv/conf/ROCKET b/sys/riscv/conf/ROCKET
deleted file mode 100644
index 1b2b1c08b8dd..000000000000
--- a/sys/riscv/conf/ROCKET
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Kernel configuration file for Rocket Core.
-#
-# For more information on this file, please read the config(5) manual page,
-# and/or the handbook section on Kernel Configuration Files:
-#
-# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
-#
-# The handbook is also available locally in /usr/share/doc/handbook
-# if you've installed the doc distribution, otherwise always see the
-# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
-# latest information.
-#
-# An exhaustive list of options and more detailed explanations of the
-# device lines is also present in the ../../conf/NOTES and NOTES files.
-# If you are in doubt as to the purpose or necessity of a line, check first
-# in NOTES.
-#
-# $FreeBSD$
-
-include GENERIC
-ident ROCKET
-
-device rcons
-options ROOTDEVNAME=\"ufs:/dev/md0\"
-
-# RISCVTODO: This needs to be done via loader (when it's available).
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=rocket.dts
diff --git a/sys/riscv/conf/SPIKE b/sys/riscv/conf/SPIKE
deleted file mode 100644
index cc36e6f97b00..000000000000
--- a/sys/riscv/conf/SPIKE
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Kernel configuration file for UCB Spike simulator.
-#
-# For more information on this file, please read the config(5) manual page,
-# and/or the handbook section on Kernel Configuration Files:
-#
-# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
-#
-# The handbook is also available locally in /usr/share/doc/handbook
-# if you've installed the doc distribution, otherwise always see the
-# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
-# latest information.
-#
-# An exhaustive list of options and more detailed explanations of the
-# device lines is also present in the ../../conf/NOTES and NOTES files.
-# If you are in doubt as to the purpose or necessity of a line, check first
-# in NOTES.
-#
-# $FreeBSD$
-
-include GENERIC
-ident SPIKE
-
-device rcons
-options ROOTDEVNAME=\"ufs:/dev/md0\"
-
-# RISCVTODO: This needs to be done via loader (when it's available).
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=spike.dts
diff --git a/sys/riscv/include/machdep.h b/sys/riscv/include/machdep.h
index 033f7d62af08..1cd34c22d64f 100644
--- a/sys/riscv/include/machdep.h
+++ b/sys/riscv/include/machdep.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* 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[];
diff --git a/sys/riscv/include/riscvreg.h b/sys/riscv/include/riscvreg.h
index 77f35bfa64b0..4558a4de4acc 100644
--- a/sys/riscv/include/riscvreg.h
+++ b/sys/riscv/include/riscvreg.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015-2016 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* 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)
@@ -141,6 +144,15 @@
#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 */
#define NCSRS 4096
diff --git a/sys/riscv/include/sbi.h b/sys/riscv/include/sbi.h
index 76690ab84b08..b2505aa7f6c6 100644
--- a/sys/riscv/include/sbi.h
+++ b/sys/riscv/include/sbi.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2016 Ruslan Bukin
+ * Copyright (c) 2016-2017 Ruslan Bukin
* 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_ */
diff --git a/sys/riscv/riscv/cpufunc_asm.S b/sys/riscv/riscv/cpufunc_asm.S
index 1d44c22f27fa..0328383a5ca4 100644
--- a/sys/riscv/riscv/cpufunc_asm.S
+++ b/sys/riscv/riscv/cpufunc_asm.S
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015-2016 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* 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)
diff --git a/sys/riscv/riscv/exception.S b/sys/riscv/riscv/exception.S
index d5efd732ca65..b103b4d24a31 100644
--- a/sys/riscv/riscv/exception.S
+++ b/sys/riscv/riscv/exception.S
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015-2016 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* 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
/*
diff --git a/sys/riscv/riscv/intr_machdep.c b/sys/riscv/riscv/intr_machdep.c
index b9da74fc73a2..caaefcfc5b3d 100644
--- a/sys/riscv/riscv/intr_machdep.c
+++ b/sys/riscv/riscv/intr_machdep.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015-2016 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -265,11 +265,14 @@ 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
diff --git a/sys/riscv/riscv/locore.S b/sys/riscv/riscv/locore.S
index 5edbf7887885..20649929d321 100644
--- a/sys/riscv/riscv/locore.S
+++ b/sys/riscv/riscv/locore.S
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015-2016 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -53,110 +53,28 @@
.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
-
- /* 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 */
+ li t0, SSTATUS_SUM
+ csrs sstatus, t0
/* Direct secondary cores to mpentry */
- call sbi_hart_id
- bnez a0, mpentry
+ bnez s10, mpentry
/*
* Page tables
*/
- /* Create an L1 page for early devmap */
- 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
- srli s2, s2, PAGE_SHIFT
-
- 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 single level1 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
-
- /* Store SBI L1 PTE entry to position */
- li a6, PTE_SIZE
- mulw a5, a5, a6
- add t0, s1, a5
- sd t6, (t0)
-
- /* 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
- 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
-
- /* Store SBI L2 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
- 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 */
-
/* 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
@@ -174,12 +92,12 @@ _start:
/* Level 2 superpages (512 x 2MiB) */
la s1, pagetable_l2
- srli t4, s6, 21 /* Div physmem base by 2 MiB */
+ 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)
+ 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 */
@@ -188,13 +106,65 @@ _start:
addi t4, t4, 1
bltu t4, t3, 2b
+ /* 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, (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 single level1 PTE entry to position */
+ li a6, PTE_SIZE
+ mulw a5, a5, a6
+ add t0, s1, a5
+ sd t6, (t0)
+
+ /* Create an L2 page superpage for DTB */
+ la s1, pagetable_l2_devmap
+ mv s2, s11
+ srli s2, s2, PAGE_SHIFT
+
+ li t0, (PTE_V | PTE_RWX | PTE_D)
+ slli t2, s2, PTE_PPN0_S /* << PTE_PPN0_S */
+ or t0, t0, t2
+
+ /* Store PTE entry to position */
+ li a6, PTE_SIZE
+ li a5, 510
+ mulw a5, a5, a6
+ add t1, s1, a5
+ sd t0, (t1)
+
+ /* Page tables END */
+
+ /* 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
@@ -210,13 +180,18 @@ _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 */
@@ -258,14 +233,16 @@ 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:
@@ -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.
@@ -299,20 +307,6 @@ ENTRY(mpentry)
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)
#endif
diff --git a/sys/riscv/riscv/machdep.c b/sys/riscv/riscv/machdep.c
index 14ddbc989329..f093e02b3f3e 100644
--- a/sys/riscv/riscv/machdep.c
+++ b/sys/riscv/riscv/machdep.c
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2014 Andrew Turner
- * Copyright (c) 2015-2016 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* 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 size */
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_paddr_t *physmap,
#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 __unused)
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,26 +827,34 @@ 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];
@@ -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();
diff --git a/sys/riscv/riscv/nexus.c b/sys/riscv/riscv/nexus.c
index 75e16b881f16..61c1c2f51be2 100644
--- a/sys/riscv/riscv/nexus.c
+++ b/sys/riscv/riscv/nexus.c
@@ -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);
diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c
index af8806d8eead..8011ced6b662 100644
--- a/sys/riscv/riscv/pmap.c
+++ b/sys/riscv/riscv/pmap.c
@@ -13,7 +13,7 @@
* All rights reserved.
* Copyright (c) 2014 The FreeBSD Foundation
* All rights reserved.
- * Copyright (c) 2015-2016 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* 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, vm_size_t kernlen)
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();
}
@@ -782,7 +784,7 @@ pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
/* TODO */
sched_pin();
- __asm __volatile("sfence.vm");
+ __asm __volatile("sfence.vma");
sched_unpin();
}
@@ -793,7 +795,7 @@ pmap_invalidate_all(pmap_t pmap)
/* TODO */
sched_pin();
- __asm __volatile("sfence.vm");
+ __asm __volatile("sfence.vma");
sched_unpin();
}
@@ -3181,12 +3183,15 @@ void
pmap_activate(struct thread *td)
{
pmap_t pmap;
+ uint64_t reg;
critical_enter();
pmap = vmspace_pmap(td->td_proc->p_vmspace);
td->td_pcb->pcb_l1addr = vtophys(pmap->pm_l1);
- __asm __volatile("csrw sptbr, %0" :: "r"(td->td_pcb->pcb_l1addr >> PAGE_SHIFT));
+ reg = SATP_MODE_SV39;
+ reg |= (td->td_pcb->pcb_l1addr >> PAGE_SHIFT);
+ __asm __volatile("csrw sptbr, %0" :: "r"(reg));
pmap_invalidate_all(pmap);
critical_exit();
diff --git a/sys/riscv/riscv/riscv_console.c b/sys/riscv/riscv/riscv_console.c
index d59ed59c18ae..df6aba155e11 100644
--- a/sys/riscv/riscv/riscv_console.c
+++ b/sys/riscv/riscv/riscv_console.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015-2016 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -68,11 +68,6 @@ __FBSDID("$FreeBSD$");
#include
#include
-static struct resource_spec rcons_spec[] = {
- { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE},
- { -1, 0 }
-};
-
/* bus softc */
struct rcons_softc {
struct resource *res[1];
@@ -110,17 +105,6 @@ static cn_ungrab_t riscv_cnungrab;
CONSOLE_DRIVER(riscv);
#define MAX_BURST_LEN 1
-#define QUEUE_SIZE 256
-
-struct queue_entry {
- uint64_t data;
- uint64_t used;
- struct queue_entry *next;
-};
-
-struct queue_entry cnqueue[QUEUE_SIZE];
-struct queue_entry *entry_last;
-struct queue_entry *entry_served;
static void
riscv_putc(int c)
@@ -195,21 +179,8 @@ riscv_cnprobe(struct consdev *cp)
static void
riscv_cninit(struct consdev *cp)
{
- int i;
strcpy(cp->cn_name, "rcons");
-
- for (i = 0; i < QUEUE_SIZE; i++) {
- if (i == (QUEUE_SIZE - 1))
- cnqueue[i].next = &cnqueue[0];
- else
- cnqueue[i].next = &cnqueue[i+1];
- cnqueue[i].data = 0;
- cnqueue[i].used = 0;
- }
-
- entry_last = &cnqueue[0];
- entry_served = &cnqueue[0];
}
static void
@@ -233,7 +204,6 @@ riscv_cnungrab(struct consdev *cp)
static int
riscv_cngetc(struct consdev *cp)
{
- uint8_t data;
int ch;
#if defined(KDB)
@@ -245,26 +215,17 @@ riscv_cngetc(struct consdev *cp)
if (kdb_active) {
ch = sbi_console_getchar();
while (ch) {
- entry_last->data = ch;
- entry_last->used = 1;
- entry_last = entry_last->next;
-
ch = sbi_console_getchar();
}
}
#endif
- if (entry_served->used == 1) {
- data = entry_served->data;
- entry_served->used = 0;
- entry_served = entry_served->next;
- ch = (data & 0xff);
- if (ch > 0 && ch < 0xff) {
+ ch = sbi_console_getchar();
+ if (ch > 0 && ch < 0xff) {
#if defined(KDB)
- kdb_alt_break(ch, &alt_break_state);
+ kdb_alt_break(ch, &alt_break_state);
#endif
- return (ch);
- }
+ return (ch);
}
return (-1);
@@ -279,34 +240,12 @@ riscv_cnputc(struct consdev *cp, int c)
/* Bus interface */
-static int
-rcons_intr(void *arg)
-{
- int c;
-
- c = sbi_console_getchar();
- if (c > 0 && c < 0xff) {
- entry_last->data = c;
- entry_last->used = 1;
- entry_last = entry_last->next;
- }
-
- csr_clear(sip, SIP_SSIP);
-
- return (FILTER_HANDLED);
-}
-
static int
rcons_probe(device_t dev)
{
- if (!ofw_bus_status_okay(dev))
- return (ENXIO);
-
- if (!ofw_bus_is_compatible(dev, "riscv,console"))
- return (ENXIO);
-
device_set_desc(dev, "RISC-V console");
+
return (BUS_PROBE_DEFAULT);
}
@@ -314,30 +253,17 @@ static int
rcons_attach(device_t dev)
{
struct rcons_softc *sc;
- int error;
+
+ if (device_get_unit(dev) != 0)
+ return (ENXIO);
sc = device_get_softc(dev);
sc->dev = dev;
- if (bus_alloc_resources(dev, rcons_spec, sc->res)) {
- device_printf(dev, "could not allocate resources\n");
- return (ENXIO);
- }
-
- /* Setup IRQs handler */
- error = bus_setup_intr(dev, sc->res[0], INTR_TYPE_CLK,
- rcons_intr, NULL, sc, &sc->ihl[0]);
- if (error) {
- device_printf(dev, "Unable to alloc int resource.\n");
- return (ENXIO);
- }
-
csr_set(sie, SIE_SSIE);
bus_generic_attach(sc->dev);
- sbi_console_getchar();
-
return (0);
}
@@ -356,4 +282,4 @@ static driver_t rcons_driver = {
static devclass_t rcons_devclass;
-DRIVER_MODULE(rcons, simplebus, rcons_driver, rcons_devclass, 0, 0);
+DRIVER_MODULE(rcons, nexus, rcons_driver, rcons_devclass, 0, 0);
diff --git a/sys/riscv/riscv/sbi.S b/sys/riscv/riscv/sbi.S
deleted file mode 100644
index b5b2916e0f4f..000000000000
--- a/sys/riscv/riscv/sbi.S
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * Copyright (c) 2016 Ruslan Bukin
- * All rights reserved.
- *
- * Portions of this software were developed by SRI International and the
- * University of Cambridge Computer Laboratory under DARPA/AFRL contract
- * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
- *
- * Portions of this software were developed by the University of Cambridge
- * Computer Laboratory as part of the CTSRD Project, with support from the
- * UK Higher Education Innovation Fund (HEIF).
- *
- * 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 AUTHOR 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 AUTHOR 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.
- */
-
-#include
-__FBSDID("$FreeBSD$");
-
-.globl sbi_hart_id; sbi_hart_id = -2048
-.globl sbi_num_harts; sbi_num_harts = -2032
-.globl sbi_query_memory; sbi_query_memory = -2016
-.globl sbi_console_putchar; sbi_console_putchar = -2000
-.globl sbi_console_getchar; sbi_console_getchar = -1984
-.globl sbi_send_ipi; sbi_send_ipi = -1952
-.globl sbi_clear_ipi; sbi_clear_ipi = -1936
-.globl sbi_timebase; sbi_timebase = -1920
-.globl sbi_shutdown; sbi_shutdown = -1904
-.globl sbi_set_timer; sbi_set_timer = -1888
-.globl sbi_mask_interrupt; sbi_mask_interrupt = -1872
-.globl sbi_unmask_interrupt; sbi_unmask_interrupt = -1856
-.globl sbi_remote_sfence_vm; sbi_remote_sfence_vm = -1840
-.globl sbi_remote_sfence_vm_range; sbi_remote_sfence_vm_range = -1824
-.globl sbi_remote_fence_i; sbi_remote_fence_i = -1808
diff --git a/sys/riscv/riscv/swtch.S b/sys/riscv/riscv/swtch.S
index 5cc1edd69a02..8753fddfb728 100644
--- a/sys/riscv/riscv/swtch.S
+++ b/sys/riscv/riscv/swtch.S
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015-2016 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -163,16 +163,18 @@ ENTRY(cpu_throw)
ld x13, TD_PCB(a1)
sd x13, PC_CURPCB(gp)
- sfence.vm
+ sfence.vma
/* Switch to the new pmap */
ld t0, PCB_L1ADDR(x13)
srli t0, t0, PAGE_SHIFT
+ li t1, SATP_MODE_SV39
+ or t0, t0, t1
csrw sptbr, t0
/* TODO: Invalidate the TLB */
- sfence.vm
+ sfence.vma
/* Load registers */
ld ra, (PCB_RA)(x13)
@@ -279,16 +281,18 @@ ENTRY(cpu_switch)
* to a user process.
*/
- sfence.vm
+ sfence.vma
/* Switch to the new pmap */
ld t0, PCB_L1ADDR(x13)
srli t0, t0, PAGE_SHIFT
+ li t1, SATP_MODE_SV39
+ or t0, t0, t1
csrw sptbr, t0
/* TODO: Invalidate the TLB */
- sfence.vm
+ sfence.vma
/* Release the old thread */
sd a2, TD_LOCK(a0)
diff --git a/sys/riscv/riscv/timer.c b/sys/riscv/riscv/timer.c
index 7876bbd5a8e9..0308ca50e6c8 100644
--- a/sys/riscv/riscv/timer.c
+++ b/sys/riscv/riscv/timer.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015-2016 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -61,66 +61,56 @@ __FBSDID("$FreeBSD$");
#include
#include
-#include
-#include
-#include
-#include
-
-#define DEFAULT_FREQ 1000000
+#define DEFAULT_FREQ 10000000
#define TIMER_COUNTS 0x00
#define TIMER_MTIMECMP(cpu) (cpu * 8)
-#define READ8(_sc, _reg) \
- bus_space_read_8(_sc->bst, _sc->bsh, _reg)
-#define WRITE8(_sc, _reg, _val) \
- bus_space_write_8(_sc->bst, _sc->bsh, _reg, _val)
-
-struct riscv_tmr_softc {
- struct resource *res[3];
- bus_space_tag_t bst;
- bus_space_handle_t bsh;
- bus_space_tag_t bst_timecmp;
- bus_space_handle_t bsh_timecmp;
+struct riscv_timer_softc {
void *ih;
uint32_t clkfreq;
struct eventtimer et;
+ int intr_rid;
+ struct resource *intr_res;
};
-static struct riscv_tmr_softc *riscv_tmr_sc = NULL;
+static struct riscv_timer_softc *riscv_timer_sc = NULL;
-static struct resource_spec timer_spec[] = {
- { SYS_RES_MEMORY, 0, RF_ACTIVE },
- { SYS_RES_MEMORY, 1, RF_ACTIVE },
- { SYS_RES_IRQ, 0, RF_ACTIVE },
- { -1, 0 }
-};
+static timecounter_get_t riscv_timer_get_timecount;
-static timecounter_get_t riscv_tmr_get_timecount;
-
-static struct timecounter riscv_tmr_timecount = {
+static struct timecounter riscv_timer_timecount = {
.tc_name = "RISC-V Timecounter",
- .tc_get_timecount = riscv_tmr_get_timecount,
+ .tc_get_timecount = riscv_timer_get_timecount,
.tc_poll_pps = NULL,
.tc_counter_mask = ~0u,
.tc_frequency = 0,
.tc_quality = 1000,
};
+static inline uint64_t
+get_cycles(void)
+{
+ uint64_t cycles;
+
+ __asm __volatile("rdtime %0" : "=r" (cycles));
+
+ return (cycles);
+}
+
static long
-get_counts(struct riscv_tmr_softc *sc)
+get_counts(struct riscv_timer_softc *sc)
{
uint64_t counts;
- counts = READ8(sc, TIMER_COUNTS);
+ counts = get_cycles();
return (counts);
}
static unsigned
-riscv_tmr_get_timecount(struct timecounter *tc)
+riscv_timer_get_timecount(struct timecounter *tc)
{
- struct riscv_tmr_softc *sc;
+ struct riscv_timer_softc *sc;
sc = tc->tc_priv;
@@ -128,22 +118,14 @@ riscv_tmr_get_timecount(struct timecounter *tc)
}
static int
-riscv_tmr_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
+riscv_timer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
{
- struct riscv_tmr_softc *sc;
uint64_t counts;
- int cpu;
-
- sc = (struct riscv_tmr_softc *)et->et_priv;
if (first != 0) {
counts = ((uint32_t)et->et_frequency * first) >> 32;
- counts += READ8(sc, TIMER_COUNTS);
- cpu = PCPU_GET(cpuid);
- bus_space_write_8(sc->bst_timecmp, sc->bsh_timecmp,
- TIMER_MTIMECMP(cpu), counts);
+ sbi_set_timer(get_cycles() + counts);
csr_set(sie, SIE_STIE);
- sbi_set_timer(counts);
return (0);
}
@@ -153,11 +135,8 @@ riscv_tmr_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
}
static int
-riscv_tmr_stop(struct eventtimer *et)
+riscv_timer_stop(struct eventtimer *et)
{
- struct riscv_tmr_softc *sc;
-
- sc = (struct riscv_tmr_softc *)et->et_priv;
/* TODO */
@@ -165,11 +144,11 @@ riscv_tmr_stop(struct eventtimer *et)
}
static int
-riscv_tmr_intr(void *arg)
+riscv_timer_intr(void *arg)
{
- struct riscv_tmr_softc *sc;
+ struct riscv_timer_softc *sc;
- sc = (struct riscv_tmr_softc *)arg;
+ sc = (struct riscv_timer_softc *)arg;
csr_clear(sip, SIP_STIP);
@@ -180,74 +159,55 @@ riscv_tmr_intr(void *arg)
}
static int
-riscv_tmr_fdt_probe(device_t dev)
+riscv_timer_probe(device_t dev)
{
- if (!ofw_bus_status_okay(dev))
- return (ENXIO);
+ device_set_desc(dev, "RISC-V Timer");
- if (ofw_bus_is_compatible(dev, "riscv,timer")) {
- device_set_desc(dev, "RISC-V Timer");
- return (BUS_PROBE_DEFAULT);
- }
-
- return (ENXIO);
+ return (BUS_PROBE_DEFAULT);
}
static int
-riscv_tmr_attach(device_t dev)
+riscv_timer_attach(device_t dev)
{
- struct riscv_tmr_softc *sc;
- phandle_t node;
- pcell_t clock;
+ struct riscv_timer_softc *sc;
int error;
sc = device_get_softc(dev);
- if (riscv_tmr_sc)
+ if (riscv_timer_sc)
return (ENXIO);
- /* Get the base clock frequency */
- node = ofw_bus_get_node(dev);
- if (node > 0) {
- error = OF_getprop(node, "clock-frequency", &clock,
- sizeof(clock));
- if (error > 0) {
- sc->clkfreq = fdt32_to_cpu(clock);
- }
- }
-
- if (sc->clkfreq == 0)
- sc->clkfreq = DEFAULT_FREQ;
+ if (device_get_unit(dev) != 0)
+ return ENXIO;
+ sc->clkfreq = DEFAULT_FREQ;
if (sc->clkfreq == 0) {
device_printf(dev, "No clock frequency specified\n");
return (ENXIO);
}
- if (bus_alloc_resources(dev, timer_spec, sc->res)) {
- device_printf(dev, "could not allocate resources\n");
+ riscv_timer_sc = sc;
+
+ sc->intr_rid = 0;
+ sc->intr_res = bus_alloc_resource(dev,
+ SYS_RES_IRQ, &sc->intr_rid, IRQ_TIMER_SUPERVISOR,
+ IRQ_TIMER_SUPERVISOR, 1, RF_ACTIVE);
+ if (sc->intr_res == NULL) {
+ device_printf(dev, "failed to allocate irq\n");
return (ENXIO);
}
- /* Memory interface */
- sc->bst = rman_get_bustag(sc->res[0]);
- sc->bsh = rman_get_bushandle(sc->res[0]);
- sc->bst_timecmp = rman_get_bustag(sc->res[1]);
- sc->bsh_timecmp = rman_get_bushandle(sc->res[1]);
-
- riscv_tmr_sc = sc;
-
/* Setup IRQs handler */
- error = bus_setup_intr(dev, sc->res[2], INTR_TYPE_CLK,
- riscv_tmr_intr, NULL, sc, &sc->ih);
+ error = bus_setup_intr(dev, sc->intr_res, INTR_TYPE_CLK,
+ riscv_timer_intr, NULL, sc, &sc->ih);
if (error) {
device_printf(dev, "Unable to alloc int resource.\n");
return (ENXIO);
}
- riscv_tmr_timecount.tc_frequency = sc->clkfreq;
- riscv_tmr_timecount.tc_priv = sc;
- tc_init(&riscv_tmr_timecount);
+ riscv_timer_timecount.tc_frequency = sc->clkfreq;
+ riscv_timer_timecount.tc_priv = sc;
+ tc_init(&riscv_timer_timecount);
sc->et.et_name = "RISC-V Eventtimer";
sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERCPU;
@@ -256,31 +216,29 @@ riscv_tmr_attach(device_t dev)
sc->et.et_frequency = sc->clkfreq;
sc->et.et_min_period = (0x00000002LLU << 32) / sc->et.et_frequency;
sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
- sc->et.et_start = riscv_tmr_start;
- sc->et.et_stop = riscv_tmr_stop;
+ sc->et.et_start = riscv_timer_start;
+ sc->et.et_stop = riscv_timer_stop;
sc->et.et_priv = sc;
et_register(&sc->et);
return (0);
}
-static device_method_t riscv_tmr_fdt_methods[] = {
- DEVMETHOD(device_probe, riscv_tmr_fdt_probe),
- DEVMETHOD(device_attach, riscv_tmr_attach),
+static device_method_t riscv_timer_methods[] = {
+ DEVMETHOD(device_probe, riscv_timer_probe),
+ DEVMETHOD(device_attach, riscv_timer_attach),
{ 0, 0 }
};
-static driver_t riscv_tmr_fdt_driver = {
+static driver_t riscv_timer_driver = {
"timer",
- riscv_tmr_fdt_methods,
- sizeof(struct riscv_tmr_softc),
+ riscv_timer_methods,
+ sizeof(struct riscv_timer_softc),
};
-static devclass_t riscv_tmr_fdt_devclass;
+static devclass_t riscv_timer_devclass;
-EARLY_DRIVER_MODULE(timer, simplebus, riscv_tmr_fdt_driver, riscv_tmr_fdt_devclass,
- 0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
-EARLY_DRIVER_MODULE(timer, ofwbus, riscv_tmr_fdt_driver, riscv_tmr_fdt_devclass,
+EARLY_DRIVER_MODULE(timer, nexus, riscv_timer_driver, riscv_timer_devclass,
0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
void
@@ -293,7 +251,7 @@ DELAY(int usec)
* Check the timers are setup, if not just
* use a for loop for the meantime
*/
- if (riscv_tmr_sc == NULL) {
+ if (riscv_timer_sc == NULL) {
for (; usec > 0; usec--)
for (counts = 200; counts > 0; counts--)
/*
@@ -305,7 +263,7 @@ DELAY(int usec)
}
/* Get the number of times to count */
- counts_per_usec = ((riscv_tmr_timecount.tc_frequency / 1000000) + 1);
+ counts_per_usec = ((riscv_timer_timecount.tc_frequency / 1000000) + 1);
/*
* Clamp the timeout at a maximum value (about 32 seconds with
@@ -318,10 +276,10 @@ DELAY(int usec)
else
counts = usec * counts_per_usec;
- first = get_counts(riscv_tmr_sc);
+ first = get_counts(riscv_timer_sc);
while (counts > 0) {
- last = get_counts(riscv_tmr_sc);
+ last = get_counts(riscv_timer_sc);
counts -= (int64_t)(last - first);
first = last;
}
diff --git a/sys/riscv/riscv/trap.c b/sys/riscv/riscv/trap.c
index 5af0c014e3dc..002e10e82fe0 100644
--- a/sys/riscv/riscv/trap.c
+++ b/sys/riscv/riscv/trap.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015-2016 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -212,7 +212,8 @@ data_abort(struct trapframe *frame, int lower)
va = trunc_page(sbadaddr);
- if (frame->tf_scause == EXCP_FAULT_STORE) {
+ if ((frame->tf_scause == EXCP_FAULT_STORE) ||
+ (frame->tf_scause == EXCP_STORE_PAGE_FAULT)) {
ftype = (VM_PROT_READ | VM_PROT_WRITE);
} else {
ftype = (VM_PROT_READ);
@@ -296,6 +297,8 @@ do_trap_supervisor(struct trapframe *frame)
case EXCP_FAULT_LOAD:
case EXCP_FAULT_STORE:
case EXCP_FAULT_FETCH:
+ case EXCP_STORE_PAGE_FAULT:
+ case EXCP_LOAD_PAGE_FAULT:
data_abort(frame, 0);
break;
case EXCP_BREAKPOINT:
@@ -354,6 +357,9 @@ do_trap_user(struct trapframe *frame)
case EXCP_FAULT_LOAD:
case EXCP_FAULT_STORE:
case EXCP_FAULT_FETCH:
+ case EXCP_STORE_PAGE_FAULT:
+ case EXCP_LOAD_PAGE_FAULT:
+ case EXCP_INST_PAGE_FAULT:
data_abort(frame, 1);
break;
case EXCP_USER_ECALL:
@@ -381,7 +387,7 @@ do_trap_user(struct trapframe *frame)
break;
default:
dump_regs(frame);
- panic("Unknown userland exception %x badaddr %lx\n",
+ panic("Unknown userland exception %x, badaddr %lx\n",
exception, frame->tf_sbadaddr);
}
}
diff --git a/sys/riscv/riscv/vm_machdep.c b/sys/riscv/riscv/vm_machdep.c
index c5c62fe24db2..73bb5aae7b6c 100644
--- a/sys/riscv/riscv/vm_machdep.c
+++ b/sys/riscv/riscv/vm_machdep.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015-2016 Ruslan Bukin
+ * Copyright (c) 2015-2017 Ruslan Bukin
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
@@ -88,6 +88,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
tf->tf_a[0] = 0;
tf->tf_a[1] = 0;
tf->tf_sstatus |= (SSTATUS_SPIE); /* Enable interrupts. */
+ tf->tf_sstatus |= (SSTATUS_SUM); /* Supervisor can access userspace. */
tf->tf_sstatus &= ~(SSTATUS_SPP); /* User mode. */
td2->td_frame = tf;
@@ -179,7 +180,9 @@ void
cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg,
stack_t *stack)
{
- struct trapframe *tf = td->td_frame;
+ struct trapframe *tf;
+
+ tf = td->td_frame;
tf->tf_sp = STACKALIGN((uintptr_t)stack->ss_sp + stack->ss_size);
tf->tf_sepc = (register_t)entry;