From af19cc59ca5e72b70169feeaf5fca52b339edcf4 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Thu, 10 Aug 2017 14:18:09 +0000 Subject: [PATCH] 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 --- lib/csu/riscv/crt1.c | 7 +- lib/csu/riscv/crti.S | 13 +- lib/libc/riscv/gen/fabs.S | 4 +- libexec/rtld-elf/riscv/reloc.c | 4 +- share/mk/bsd.cpu.mk | 7 +- share/mk/bsd.stand.mk | 2 +- sys/boot/fdt/dts/riscv/lowrisc.dts | 108 ------------- sys/boot/fdt/dts/riscv/qemu.dts | 105 ------------- sys/boot/fdt/dts/riscv/rocket.dts | 105 ------------- sys/boot/fdt/dts/riscv/spike.dts | 111 -------------- sys/conf/Makefile.riscv | 5 + sys/conf/files.riscv | 1 - sys/conf/kern.mk | 2 +- sys/riscv/conf/GENERIC | 3 + sys/riscv/conf/LOWRISC | 43 ------ sys/riscv/conf/LOWRISC.hints | 5 - sys/riscv/conf/QEMU | 29 ---- sys/riscv/conf/ROCKET | 29 ---- sys/riscv/conf/SPIKE | 29 ---- sys/riscv/include/machdep.h | 5 +- sys/riscv/include/riscvreg.h | 16 +- sys/riscv/include/sbi.h | 110 ++++++++++--- sys/riscv/riscv/cpufunc_asm.S | 14 +- sys/riscv/riscv/exception.S | 9 +- sys/riscv/riscv/intr_machdep.c | 13 +- sys/riscv/riscv/locore.S | 238 ++++++++++++++--------------- sys/riscv/riscv/machdep.c | 54 ++++--- sys/riscv/riscv/nexus.c | 2 + sys/riscv/riscv/pmap.c | 17 ++- sys/riscv/riscv/riscv_console.c | 94 ++---------- sys/riscv/riscv/sbi.S | 52 ------- sys/riscv/riscv/swtch.S | 14 +- sys/riscv/riscv/timer.c | 172 ++++++++------------- sys/riscv/riscv/trap.c | 12 +- sys/riscv/riscv/vm_machdep.c | 7 +- 35 files changed, 423 insertions(+), 1018 deletions(-) delete mode 100644 sys/boot/fdt/dts/riscv/lowrisc.dts delete mode 100644 sys/boot/fdt/dts/riscv/qemu.dts delete mode 100644 sys/boot/fdt/dts/riscv/rocket.dts delete mode 100644 sys/boot/fdt/dts/riscv/spike.dts delete mode 100644 sys/riscv/conf/LOWRISC delete mode 100644 sys/riscv/conf/LOWRISC.hints delete mode 100644 sys/riscv/conf/QEMU delete mode 100644 sys/riscv/conf/ROCKET delete mode 100644 sys/riscv/conf/SPIKE delete mode 100644 sys/riscv/riscv/sbi.S 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;