Index: lib/csu/riscv/crt1.c =================================================================== --- lib/csu/riscv/crt1.c +++ 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 @@ " 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 Index: lib/csu/riscv/crti.S =================================================================== --- lib/csu/riscv/crti.S +++ 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 @@ sd ra, 0(sp) .section .fini,"ax",@progbits - .align 2 + .align 0 .globl _fini .type _fini,@function _fini: Index: lib/libc/riscv/gen/fabs.S =================================================================== --- lib/libc/riscv/gen/fabs.S +++ 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 Index: libexec/rtld-elf/riscv/reloc.c =================================================================== --- libexec/rtld-elf/riscv/reloc.c +++ 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 @@ __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); Index: share/mk/bsd.cpu.mk =================================================================== --- share/mk/bsd.cpu.mk +++ share/mk/bsd.cpu.mk @@ -364,8 +364,11 @@ .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 Index: share/mk/bsd.stand.mk =================================================================== --- share/mk/bsd.stand.mk +++ 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 Index: sys/boot/fdt/dts/riscv/lowrisc.dts =================================================================== --- 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"; - }; -}; Index: sys/boot/fdt/dts/riscv/qemu.dts =================================================================== --- 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"; - }; -}; Index: sys/boot/fdt/dts/riscv/rocket.dts =================================================================== --- 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"; - }; -}; Index: sys/boot/fdt/dts/riscv/spike.dts =================================================================== --- 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"; - }; -}; Index: sys/conf/files.riscv =================================================================== --- sys/conf/files.riscv +++ sys/conf/files.riscv @@ -46,7 +46,6 @@ 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 Index: sys/conf/kern.mk =================================================================== --- sys/conf/kern.mk +++ sys/conf/kern.mk @@ -121,7 +121,7 @@ .endif .if ${MACHINE_CPUARCH} == "riscv" -CFLAGS.gcc+= -mcmodel=medany +CFLAGS.gcc+= -mcmodel=medany -march=rv64imafdc -mabi=lp64 INLINE_LIMIT?= 8000 .endif Index: sys/conf/ldscript.riscv =================================================================== --- sys/conf/ldscript.riscv +++ sys/conf/ldscript.riscv @@ -6,7 +6,7 @@ SECTIONS { /* Read-only sections, merged into text segment: */ - . = kernbase; + . = kernbase + 0x200000; .text : AT(ADDR(.text) - kernbase) { *(.text) Index: sys/riscv/conf/GENERIC =================================================================== --- sys/riscv/conf/GENERIC +++ sys/riscv/conf/GENERIC @@ -75,11 +75,14 @@ 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 -# makeoptions MFS_IMAGE=/path/to/img -# options ROOTDEVNAME=\"ufs:/dev/md0\" +options MD_ROOT +options MD_ROOT_SIZE=32768 # 32MB ram disk +makeoptions MFS_IMAGE=/home/br/dev/freebsd-riscv/riscv.img +options ROOTDEVNAME=\"ufs:/dev/md0\" # Debugging support. Always need this: options KDB # Enable kernel debugger support. Index: sys/riscv/conf/LOWRISC =================================================================== --- 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 Index: sys/riscv/conf/LOWRISC.hints =================================================================== --- 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 Index: sys/riscv/conf/QEMU =================================================================== --- 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 Index: sys/riscv/conf/ROCKET =================================================================== --- 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 Index: sys/riscv/conf/SPIKE =================================================================== --- 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 Index: sys/riscv/include/machdep.h =================================================================== --- sys/riscv/include/machdep.h +++ sys/riscv/include/machdep.h @@ -40,6 +40,8 @@ struct riscv_bootparams { vm_offset_t kern_l1pt; /* Kernel L1 base */ 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[]; Index: sys/riscv/include/riscvreg.h =================================================================== --- sys/riscv/include/riscvreg.h +++ 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 Index: sys/riscv/include/sbi.h =================================================================== --- sys/riscv/include/sbi.h +++ 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; - -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); - -void sbi_console_putchar(unsigned char ch); -int sbi_console_getchar(void); - -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); - -uint64_t sbi_mask_interrupt(uint64_t which); -uint64_t sbi_unmask_interrupt(uint64_t which); +#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 + +static __inline uint64_t +sbi_call(uint64_t arg7, uint64_t arg0, uint64_t arg1, uint64_t arg2) +{ + + 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"); + + return (a0); +} + +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_ */ Index: sys/riscv/riscv/cpufunc_asm.S =================================================================== --- sys/riscv/riscv/cpufunc_asm.S +++ 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 @@ */ 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 @@ * 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 @@ * 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 @@ * 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 @@ */ ENTRY(riscv_idcache_wbinv_range) fence.i - sfence.vm + sfence.vma ret END(riscv_idcache_wbinv_range) Index: sys/riscv/riscv/exception.S =================================================================== --- sys/riscv/riscv/exception.S +++ 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 @@ .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 /* Index: sys/riscv/riscv/intr_machdep.c =================================================================== --- sys/riscv/riscv/intr_machdep.c +++ 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 @@ 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 @@ 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 Index: sys/riscv/riscv/locore.S =================================================================== --- sys/riscv/riscv/locore.S +++ 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 @@ -43,6 +43,8 @@ #include #include +#define PHYS_START 0x80000000 + .globl kernbase .set kernbase, KERNBASE @@ -53,148 +55,114 @@ .text .globl _start _start: - /* Setup supervisor trap vector */ - la t0, cpu_exception_handler - csrw stvec, t0 - - /* Ensure sscratch is zero */ - li t0, 0 - csrw sscratch, t0 + li t0, SSTATUS_SUM + csrs sstatus, t0 - /* Load physical memory information */ - li a0, 0 - la a1, memory_info - call sbi_query_memory - - /* Store base to s6 */ - la s6, memory_info - ld s6, 0(s6) /* s6 = physmem base */ + mv s10, a0 # hart id + mv s11, a1 # dtbp /* Direct secondary cores to mpentry */ - call sbi_hart_id - bnez a0, mpentry + bnez s10, mpentry /* * Page tables */ - /* Create an L1 page for early devmap */ + /* Add L1 entry for kernel */ la s1, pagetable_l1 - la s2, pagetable_l2_devmap /* Link to next level PN */ - li t0, KERNBASE - sub s2, s2, t0 - add s2, s2, s6 + la s2, pagetable_l2 /* Link to next level PN */ srli s2, s2, PAGE_SHIFT - li a5, (VM_MAX_KERNEL_ADDRESS - L2_SIZE) + li a5, KERNBASE srli a5, a5, L1_SHIFT /* >> L1_SHIFT */ andi a5, a5, 0x1ff /* & 0x1ff */ li t4, PTE_V slli t5, s2, PTE_PPN0_S /* (s2 << PTE_PPN0_S) */ or t6, t4, t5 - /* Store single level1 PTE entry to position */ + /* Store L1 PTE entry to position */ li a6, PTE_SIZE mulw a5, a5, a6 add t0, s1, a5 sd t6, (t0) - /* Create an L1 page for SBI */ - la s1, pagetable_l1 - la s2, pagetable_l2_sbi /* Link to next level PN */ - li t0, KERNBASE - sub s2, s2, t0 - add s2, s2, s6 - srli s2, s2, PAGE_SHIFT - li a5, 511 - li t4, PTE_V - slli t5, s2, PTE_PPN0_S /* (s2 << PTE_PPN0_S) */ - or t6, t4, t5 + /* Level 2 superpages (512 x 2MiB) */ + la s1, pagetable_l2 + li s6, PHYS_START + srli t4, s6, 21 /* Div physmem base by 2 MiB */ + li t2, 512 /* Build 512 entries */ + add t3, t4, t2 + li t5, 0 +2: + li t0, (PTE_V | PTE_RWX | PTE_D) + slli t2, t4, PTE_PPN1_S /* << PTE_PPN1_S */ + or t5, t0, t2 + sd t5, (s1) /* Store PTE entry to position */ + addi s1, s1, PTE_SIZE - /* Store SBI L1 PTE entry to position */ - li a6, PTE_SIZE - mulw a5, a5, a6 - add t0, s1, a5 - sd t6, (t0) + addi t4, t4, 1 + bltu t4, t3, 2b - /* Create an L2 page for SBI */ - la s1, pagetable_l2_sbi - la s2, pagetable_l3_sbi /* Link to next level PN */ - li t0, KERNBASE - sub s2, s2, t0 - add s2, s2, s6 + /* Create an L1 page for early devmap */ + la s1, pagetable_l1 + la s2, pagetable_l2_devmap /* Link to next level PN */ srli s2, s2, PAGE_SHIFT - li a5, 511 + + li a5, (VM_MAX_KERNEL_ADDRESS - L2_SIZE) + srli a5, a5, L1_SHIFT /* >> L1_SHIFT */ + andi a5, a5, 0x1ff /* & 0x1ff */ li t4, PTE_V slli t5, s2, PTE_PPN0_S /* (s2 << PTE_PPN0_S) */ or t6, t4, t5 - /* Store SBI L2 PTE entry to position */ + /* Store single level1 PTE entry to position */ li a6, PTE_SIZE mulw a5, a5, a6 add t0, s1, a5 sd t6, (t0) - /* Create an L3 page for SBI */ - la s1, pagetable_l3_sbi - li s2, 0x8000b000 + /* Create an L2 page superpage for DTB */ + la s1, pagetable_l2_devmap + mv s2, s11 srli s2, s2, PAGE_SHIFT - li a5, 511 - li t4, PTE_V | PTE_RX | PTE_W - slli t5, s2, PTE_PPN0_S /* (s2 << PTE_PPN0_S) */ - or t6, t4, t5 - - /* Store SBI L3 PTE entry to position */ - li a6, PTE_SIZE - mulw a5, a5, a6 - add t0, s1, a5 - sd t6, (t0) - /* END SBI page creation */ - /* 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 t0, (PTE_V | PTE_RWX | PTE_D) + slli t2, s2, PTE_PPN0_S /* << PTE_PPN0_S */ + or t0, t0, t2 - li a5, KERNBASE - srli a5, a5, L1_SHIFT /* >> L1_SHIFT */ - andi a5, a5, 0x1ff /* & 0x1ff */ - li t4, PTE_V - slli t5, s2, PTE_PPN0_S /* (s2 << PTE_PPN0_S) */ - or t6, t4, t5 - - /* Store L1 PTE entry to position */ + /* Store PTE entry to position */ li a6, PTE_SIZE + li a5, 510 mulw a5, a5, a6 - add t0, s1, a5 - sd t6, (t0) + add t1, s1, a5 + sd t0, (t1) - /* Level 2 superpages (512 x 2MiB) */ - la s1, pagetable_l2 - srli t4, s6, 21 /* Div physmem base by 2 MiB */ - li t2, 512 /* Build 512 entries */ - add t3, t4, t2 - li t5, 0 -2: - li t0, (PTE_V | PTE_RWX) - slli t2, t4, PTE_PPN1_S /* << PTE_PPN1_S */ - or t5, t0, t2 - sd t5, (s1) /* Store PTE entry to position */ - addi s1, s1, PTE_SIZE + /* Page tables END */ - addi t4, t4, 1 - bltu t4, t3, 2b + /* Setup supervisor trap vector */ + la t0, va + li t1, PHYS_START + sub t0, t0, t1 + 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,7 +178,7 @@ bltu a0, s1, 1b /* Fill riscv_bootparams */ - addi sp, sp, -16 + addi sp, sp, -24 la t0, pagetable_l1 sd t0, 0(sp) /* kern_l1pt */ @@ -218,6 +186,10 @@ la t0, initstack_end sd t0, 8(sp) /* kern_stack */ + li t0, (VM_MAX_KERNEL_ADDRESS - 2 * L2_SIZE) + sd t0, 16(sp) /* dtbp_virt */ + sd s11, 24(sp) /* dtbp_phys */ + mv a0, sp call _C_LABEL(initriscv) /* Off we go */ call _C_LABEL(mi_startup) @@ -258,14 +230,12 @@ .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) + /* 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 +254,39 @@ * 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 + li t1, PHYS_START + sub t0, t0, t1 + li t1, KERNBASE + add sp, t0, t1 + + /* Setup supervisor trap vector */ + la t0, mpva + li t1, PHYS_START + sub t0, t0, t1 + 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 +302,6 @@ 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 Index: sys/riscv/riscv/machdep.c =================================================================== --- sys/riscv/riscv/machdep.c +++ 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 @@ 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 @@ 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_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 @@ #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 @@ 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 @@ 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 @@ /* 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 @@ /* set page table base register for thread0 */ thread0.td_pcb->pcb_l1addr = \ - (rvbp->kern_l1pt - KERNBASE + memory_info.base); + (rvbp->kern_l1pt - KERNBASE + mem_regions[0].mr_start); msgbufinit(msgbufp, msgbufsize); mutex_init(); Index: sys/riscv/riscv/nexus.c =================================================================== --- sys/riscv/riscv/nexus.c +++ sys/riscv/riscv/nexus.c @@ -156,6 +156,8 @@ 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); Index: sys/riscv/riscv/pmap.c =================================================================== --- sys/riscv/riscv/pmap.c +++ sys/riscv/riscv/pmap.c @@ -596,8 +596,10 @@ 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 @@ /* TODO */ sched_pin(); - __asm __volatile("sfence.vm"); + __asm __volatile("sfence.vma %0" :: "r" (va) : "memory"); sched_unpin(); } @@ -782,7 +784,7 @@ /* TODO */ sched_pin(); - __asm __volatile("sfence.vm"); + __asm __volatile("sfence.vma"); sched_unpin(); } @@ -793,7 +795,7 @@ /* TODO */ sched_pin(); - __asm __volatile("sfence.vm"); + __asm __volatile("sfence.vma"); sched_unpin(); } @@ -3181,12 +3183,15 @@ 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(); Index: sys/riscv/riscv/riscv_console.c =================================================================== --- sys/riscv/riscv/riscv_console.c +++ 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 @@ #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 @@ 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 @@ 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 @@ static int riscv_cngetc(struct consdev *cp) { - uint8_t data; int ch; #if defined(KDB) @@ -245,26 +215,17 @@ 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); @@ -280,33 +241,11 @@ /* 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 @@ rcons_attach(device_t dev) { struct rcons_softc *sc; - int error; - 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"); + if (device_get_unit(dev) != 0) 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); - } + sc = device_get_softc(dev); + sc->dev = dev; csr_set(sie, SIE_SSIE); bus_generic_attach(sc->dev); - sbi_console_getchar(); - return (0); } @@ -356,4 +282,4 @@ 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); Index: sys/riscv/riscv/swtch.S =================================================================== --- sys/riscv/riscv/swtch.S +++ 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 @@ 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 @@ * 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) Index: sys/riscv/riscv/timer.c =================================================================== --- sys/riscv/riscv/timer.c +++ 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 @@ #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 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 struct riscv_timer_softc *riscv_timer_sc = NULL; -static timecounter_get_t riscv_tmr_get_timecount; +static timecounter_get_t riscv_timer_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 @@ } 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 @@ } 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 @@ } 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 @@ } static int -riscv_tmr_fdt_probe(device_t dev) +riscv_timer_probe(device_t dev) { - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (ofw_bus_is_compatible(dev, "riscv,timer")) { - device_set_desc(dev, "RISC-V Timer"); - return (BUS_PROBE_DEFAULT); - } + device_set_desc(dev, "RISC-V Timer"); - 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 @@ 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 @@ * 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 @@ } /* 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 @@ 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; } Index: sys/riscv/riscv/trap.c =================================================================== --- sys/riscv/riscv/trap.c +++ 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 @@ 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 @@ 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 @@ 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 @@ 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); } } Index: sys/riscv/riscv/vm_machdep.c =================================================================== --- sys/riscv/riscv/vm_machdep.c +++ 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 @@ 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 @@ 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;