diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-08-16 20:19:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-08-16 20:19:05 +0000 |
commit | 27067774dce3388702a4cf744d7096c6fb71b688 (patch) | |
tree | 56300949abd050b3cd2e23d29210d2a567bc8aec /sys/riscv | |
parent | 44be0a8ea517cbe7a9140bca20e1e93228ac0a04 (diff) | |
parent | 915a263ea24ab051bb57674a4d6f5ffe4ef0d5b5 (diff) |
Merge ^/head r303250 through r304235.
Notes
Notes:
svn path=/projects/clang390-import/; revision=304236
Diffstat (limited to 'sys/riscv')
28 files changed, 660 insertions, 1624 deletions
diff --git a/sys/riscv/conf/GENERIC b/sys/riscv/conf/GENERIC index 13f595a43fbb..6c53da2a051c 100644 --- a/sys/riscv/conf/GENERIC +++ b/sys/riscv/conf/GENERIC @@ -26,6 +26,7 @@ makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols # FIXME: linker error. "--relax and -r may not be used together" makeoptions WITHOUT_MODULES="usb otusfw mwlfw ispfw mwlfw ralfw rtwnfw urtwnfw" +# makeoptions NO_MODULES options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption @@ -40,7 +41,6 @@ options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories options UFS_GJOURNAL # Enable gjournal-based UFS journaling options QUOTA # Enable disk quotas for UFS -options MD_ROOT # MD is a potential root device options NFSCL # Network Filesystem Client options NFSD # Network Filesystem Server options NFSLOCKD # Network Lock Manager @@ -76,7 +76,7 @@ options SMP # Uncomment for memory disk # options MD_ROOT -# options MD_ROOT_SIZE=8192 # 8MB ram disk +# options MD_ROOT_SIZE=32768 # 32MB ram disk # makeoptions MFS_IMAGE=/path/to/img # options ROOTDEVNAME=\"ufs:/dev/md0\" @@ -93,6 +93,7 @@ options INVARIANT_SUPPORT # Extra sanity checks of internal structures, require # options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones # options EARLY_PRINTF +# options VERBOSE_SYSINIT # Pseudo devices. device loop # Network loopback diff --git a/sys/riscv/conf/QEMU b/sys/riscv/conf/QEMU index 26c65430844f..7411aefc6b1d 100644 --- a/sys/riscv/conf/QEMU +++ b/sys/riscv/conf/QEMU @@ -21,8 +21,8 @@ include GENERIC ident QEMU -device htif -options ROOTDEVNAME=\"ufs:/dev/htif_blk0\" +device rcons +options ROOTDEVNAME=\"ufs:/dev/md0\" # RISCVTODO: This needs to be done via loader (when it's available). options FDT_DTB_STATIC diff --git a/sys/riscv/conf/ROCKET b/sys/riscv/conf/ROCKET index 9a9e3efe46e3..1b2b1c08b8dd 100644 --- a/sys/riscv/conf/ROCKET +++ b/sys/riscv/conf/ROCKET @@ -21,8 +21,8 @@ include GENERIC ident ROCKET -device htif -options ROOTDEVNAME=\"ufs:/dev/htif_blk0\" +device rcons +options ROOTDEVNAME=\"ufs:/dev/md0\" # RISCVTODO: This needs to be done via loader (when it's available). options FDT_DTB_STATIC diff --git a/sys/riscv/conf/SPIKE b/sys/riscv/conf/SPIKE index 6c4a7434bb4c..cc36e6f97b00 100644 --- a/sys/riscv/conf/SPIKE +++ b/sys/riscv/conf/SPIKE @@ -21,8 +21,8 @@ include GENERIC ident SPIKE -device htif -options ROOTDEVNAME=\"ufs:/dev/htif_blk0\" +device rcons +options ROOTDEVNAME=\"ufs:/dev/md0\" # RISCVTODO: This needs to be done via loader (when it's available). options FDT_DTB_STATIC diff --git a/sys/riscv/htif/htif.c b/sys/riscv/htif/htif.c deleted file mode 100644 index b07b78998591..000000000000 --- a/sys/riscv/htif/htif.c +++ /dev/null @@ -1,283 +0,0 @@ -/*- - * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com> - * 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 <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/bus.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/rman.h> -#include <sys/pcpu.h> -#include <sys/proc.h> - -#include <vm/vm.h> -#include <vm/pmap.h> - -#include <dev/fdt/fdt_common.h> -#include <dev/ofw/openfirm.h> -#include <dev/ofw/ofw_bus.h> -#include <dev/ofw/ofw_bus_subr.h> - -#include <machine/bus.h> -#include <machine/cpu.h> -#include <machine/intr.h> -#include <machine/asm.h> -#include <machine/trap.h> -#include <machine/vmparam.h> - -#include "htif.h" - -static struct resource_spec htif_spec[] = { - { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE}, - { -1, 0 } -}; - -struct intr_entry { - void (*func) (void *, uint64_t); - void *arg; -}; - -struct intr_entry intrs[HTIF_NDEV]; - -uint64_t -htif_command(uint64_t arg) -{ - - return (machine_command(ECALL_HTIF_CMD, arg)); -} - -int -htif_setup_intr(int id, void *func, void *arg) -{ - - if (id >= HTIF_NDEV) - return (-1); - - intrs[id].func = func; - intrs[id].arg = arg; - - return (0); -} - -static void -htif_handle_entry(struct htif_softc *sc) -{ - uint64_t entry; - uint8_t devcmd; - uint8_t devid; - - entry = machine_command(ECALL_HTIF_GET_ENTRY, 0); - while (entry) { - devid = HTIF_DEV_ID(entry); - devcmd = HTIF_DEV_CMD(entry); - - if (devcmd == HTIF_CMD_IDENTIFY) { - /* Enumeration interrupt */ - if (devid == sc->identify_id) - sc->identify_done = 1; - } else { - /* Device interrupt */ - if (intrs[devid].func != NULL) - intrs[devid].func(intrs[devid].arg, entry); - } - - entry = machine_command(ECALL_HTIF_GET_ENTRY, 0); - } -} - -static int -htif_intr(void *arg) -{ - struct htif_softc *sc; - - sc = arg; - - csr_clear(sip, SIP_SSIP); - - htif_handle_entry(sc); - - return (FILTER_HANDLED); -} - -static int -htif_add_device(struct htif_softc *sc, int i, char *id, char *name) -{ - struct htif_dev_ivars *di; - - di = malloc(sizeof(struct htif_dev_ivars), M_DEVBUF, M_WAITOK | M_ZERO); - di->sc = sc; - di->index = i; - di->id = malloc(HTIF_ID_LEN, M_DEVBUF, M_WAITOK | M_ZERO); - memcpy(di->id, id, HTIF_ID_LEN); - - di->dev = device_add_child(sc->dev, name, -1); - device_set_ivars(di->dev, di); - - return (0); -} - -static int -htif_enumerate(struct htif_softc *sc) -{ - char id[HTIF_ID_LEN] __aligned(HTIF_ALIGN); - uint64_t paddr; - uint64_t data; - uint64_t cmd; - int len; - int i; - - device_printf(sc->dev, "Enumerating devices\n"); - - for (i = 0; i < HTIF_NDEV; i++) { - paddr = pmap_kextract((vm_offset_t)&id); - data = (paddr << IDENTIFY_PADDR_SHIFT); - data |= IDENTIFY_IDENT; - - sc->identify_id = i; - sc->identify_done = 0; - - cmd = i; - cmd <<= HTIF_DEV_ID_SHIFT; - cmd |= (HTIF_CMD_IDENTIFY << HTIF_CMD_SHIFT); - cmd |= data; - - htif_command(cmd); - - /* Do poll as interrupts are disabled yet */ - while (sc->identify_done == 0) { - htif_handle_entry(sc); - } - - len = strnlen(id, sizeof(id)); - if (len <= 0) - break; - - if (bootverbose) - printf(" %d %s\n", i, id); - - if (strncmp(id, "disk", 4) == 0) - htif_add_device(sc, i, id, "htif_blk"); - else if (strncmp(id, "bcd", 3) == 0) - htif_add_device(sc, i, id, "htif_console"); - else if (strncmp(id, "syscall_proxy", 13) == 0) - htif_add_device(sc, i, id, "htif_syscall_proxy"); - } - - return (bus_generic_attach(sc->dev)); -} - -int -htif_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) -{ - struct htif_dev_ivars *ivars; - - ivars = device_get_ivars(child); - - switch (which) { - case HTIF_IVAR_INDEX: - *result = ivars->index; - break; - case HTIF_IVAR_ID: - *result = (uintptr_t)ivars->id; - default: - return (EINVAL); - } - - return (0); -} - -static int -htif_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "riscv,htif")) - return (ENXIO); - - device_set_desc(dev, "HTIF bus device"); - return (BUS_PROBE_DEFAULT); -} - -static int -htif_attach(device_t dev) -{ - struct htif_softc *sc; - int error; - - sc = device_get_softc(dev); - sc->dev = dev; - - if (bus_alloc_resources(dev, htif_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, - htif_intr, NULL, sc, &sc->ihl[0]); - if (error) { - device_printf(dev, "Unable to alloc int resource.\n"); - return (ENXIO); - } - - csr_set(sie, SIE_SSIE); - - return (htif_enumerate(sc)); -} - -static device_method_t htif_methods[] = { - DEVMETHOD(device_probe, htif_probe), - DEVMETHOD(device_attach, htif_attach), - - /* Bus interface */ - DEVMETHOD(bus_read_ivar, htif_read_ivar), - - DEVMETHOD_END -}; - -static driver_t htif_driver = { - "htif", - htif_methods, - sizeof(struct htif_softc) -}; - -static devclass_t htif_devclass; - -DRIVER_MODULE(htif, simplebus, htif_driver, - htif_devclass, 0, 0); diff --git a/sys/riscv/htif/htif_block.c b/sys/riscv/htif/htif_block.c deleted file mode 100644 index a31de1c75a11..000000000000 --- a/sys/riscv/htif/htif_block.c +++ /dev/null @@ -1,297 +0,0 @@ -/*- - * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com> - * 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 <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/kthread.h> -#include <sys/selinfo.h> -#include <sys/module.h> -#include <sys/lock.h> -#include <sys/mutex.h> -#include <sys/malloc.h> -#include <sys/sysctl.h> -#include <sys/uio.h> - -#include <sys/bio.h> -#include <sys/bus.h> -#include <sys/conf.h> -#include <sys/disk.h> -#include <geom/geom_disk.h> - -#include <vm/vm.h> -#include <vm/pmap.h> - -#include <machine/md_var.h> -#include <machine/bus.h> -#include <machine/trap.h> -#include <sys/rman.h> - -#include "htif.h" - -#define SECTOR_SIZE_SHIFT (9) -#define SECTOR_SIZE (1 << SECTOR_SIZE_SHIFT) - -#define HTIF_BLK_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) -#define HTIF_BLK_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) -#define HTIF_BLK_LOCK_INIT(_sc) \ - mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \ - "htif_blk", MTX_DEF) -#define HTIF_BLK_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); -#define HTIF_BLK_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); -#define HTIF_BLK_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); - -static void htif_blk_task(void *arg); - -static disk_open_t htif_blk_open; -static disk_close_t htif_blk_close; -static disk_strategy_t htif_blk_strategy; - -struct htif_blk_softc { - device_t dev; - struct disk *disk; - struct mtx htif_io_mtx; - struct mtx sc_mtx; - struct proc *p; - struct bio_queue_head bio_queue; - int running; - int intr_chan; - int cmd_done; - int index; - uint16_t curtag; -}; - -struct htif_blk_request { - uint64_t addr; - uint64_t offset; /* offset in bytes */ - uint64_t size; /* length in bytes */ - uint64_t tag; -}; - -static void -htif_blk_intr(void *arg, uint64_t entry) -{ - struct htif_blk_softc *sc; - uint64_t devcmd; - uint64_t data; - - sc = arg; - - devcmd = HTIF_DEV_CMD(entry); - data = HTIF_DEV_DATA(entry); - - if (sc->curtag == data) { - wmb(); - sc->cmd_done = 1; - wakeup(&sc->intr_chan); - } else { - device_printf(sc->dev, "Unexpected tag %d (should be %d)\n", - data, sc->curtag); - } -} - -static int -htif_blk_probe(device_t dev) -{ - - return (0); -} - -static int -htif_blk_attach(device_t dev) -{ - struct htif_blk_softc *sc; - char prefix[] = " size="; - char *str; - long size; - - sc = device_get_softc(dev); - sc->dev = dev; - - mtx_init(&sc->htif_io_mtx, device_get_nameunit(dev), "htif_blk", MTX_DEF); - HTIF_BLK_LOCK_INIT(sc); - - str = strstr(htif_get_id(dev), prefix); - - size = strtol((str + 6), NULL, 10); - if (size == 0) { - return (ENXIO); - } - - sc->index = htif_get_index(dev); - if (sc->index < 0) - return (EINVAL); - htif_setup_intr(sc->index, htif_blk_intr, sc); - - sc->disk = disk_alloc(); - sc->disk->d_drv1 = sc; - - sc->disk->d_maxsize = 4096; /* Max transfer */ - sc->disk->d_name = "htif_blk"; - sc->disk->d_open = htif_blk_open; - sc->disk->d_close = htif_blk_close; - sc->disk->d_strategy = htif_blk_strategy; - sc->disk->d_unit = 0; - sc->disk->d_sectorsize = SECTOR_SIZE; - sc->disk->d_mediasize = size; - disk_create(sc->disk, DISK_VERSION); - - bioq_init(&sc->bio_queue); - - sc->running = 1; - - kproc_create(&htif_blk_task, sc, &sc->p, 0, 0, "%s: transfer", - device_get_nameunit(dev)); - - return (0); -} - -static int -htif_blk_open(struct disk *dp) -{ - - return (0); -} - -static int -htif_blk_close(struct disk *dp) -{ - - return (0); -} - -static void -htif_blk_task(void *arg) -{ - struct htif_blk_request req __aligned(HTIF_ALIGN); - struct htif_blk_softc *sc; - uint64_t req_paddr; - struct bio *bp; - uint64_t paddr; - uint64_t cmd; - int i; - - sc = (struct htif_blk_softc *)arg; - - while (1) { - HTIF_BLK_LOCK(sc); - do { - bp = bioq_takefirst(&sc->bio_queue); - if (bp == NULL) - msleep(sc, &sc->sc_mtx, PRIBIO, "jobqueue", 0); - } while (bp == NULL); - HTIF_BLK_UNLOCK(sc); - - if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) { - HTIF_BLK_LOCK(sc); - - rmb(); - req.offset = (bp->bio_pblkno * sc->disk->d_sectorsize); - req.size = bp->bio_bcount; - paddr = vtophys(bp->bio_data); - KASSERT(paddr != 0, ("paddr is 0")); - req.addr = paddr; - sc->curtag++; - req.tag = sc->curtag; - - cmd = sc->index; - cmd <<= HTIF_DEV_ID_SHIFT; - if (bp->bio_cmd == BIO_READ) - cmd |= (HTIF_CMD_READ << HTIF_CMD_SHIFT); - else - cmd |= (HTIF_CMD_WRITE << HTIF_CMD_SHIFT); - req_paddr = vtophys(&req); - KASSERT(req_paddr != 0, ("req_paddr is 0")); - cmd |= req_paddr; - - sc->cmd_done = 0; - htif_command(cmd); - - /* Wait for interrupt */ - i = 0; - while (sc->cmd_done == 0) { - msleep(&sc->intr_chan, &sc->sc_mtx, PRIBIO, "intr", hz/2); - - if (i++ > 2) { - /* TODO: try to re-issue operation on timeout ? */ - bp->bio_error = EIO; - bp->bio_flags |= BIO_ERROR; - disk_err(bp, "hard error", -1, 1); - break; - } - } - HTIF_BLK_UNLOCK(sc); - - biodone(bp); - } else { - printf("unknown op %d\n", bp->bio_cmd); - } - } -} - -static void -htif_blk_strategy(struct bio *bp) -{ - struct htif_blk_softc *sc; - - sc = bp->bio_disk->d_drv1; - - HTIF_BLK_LOCK(sc); - if (sc->running > 0) { - bioq_disksort(&sc->bio_queue, bp); - HTIF_BLK_UNLOCK(sc); - wakeup(sc); - } else { - HTIF_BLK_UNLOCK(sc); - biofinish(bp, NULL, ENXIO); - } -} - -static device_method_t htif_blk_methods[] = { - DEVMETHOD(device_probe, htif_blk_probe), - DEVMETHOD(device_attach, htif_blk_attach), -}; - -static driver_t htif_blk_driver = { - "htif_blk", - htif_blk_methods, - sizeof(struct htif_blk_softc) -}; - -static devclass_t htif_blk_devclass; - -DRIVER_MODULE(htif_blk, htif, htif_blk_driver, htif_blk_devclass, 0, 0); diff --git a/sys/riscv/include/cpu.h b/sys/riscv/include/cpu.h index c0a55a78a275..9b488ac9ecb6 100644 --- a/sys/riscv/include/cpu.h +++ b/sys/riscv/include/cpu.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com> + * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com> * All rights reserved. * * Portions of this software were developed by SRI International and the @@ -67,11 +67,10 @@ #define CPU_PART_SHIFT 62 #define CPU_PART_MASK (0x3ul << CPU_PART_SHIFT) -#define CPU_PART(mcpuid) ((mcpuid & CPU_PART_MASK) >> CPU_PART_SHIFT) -#define CPU_PART_RV32I 0x0 -#define CPU_PART_RV32E 0x1 -#define CPU_PART_RV64I 0x2 -#define CPU_PART_RV128I 0x3 +#define CPU_PART(misa) ((misa & CPU_PART_MASK) >> CPU_PART_SHIFT) +#define CPU_PART_RV32 0x1 +#define CPU_PART_RV64 0x2 +#define CPU_PART_RV128 0x3 extern char btext[]; extern char etext[]; diff --git a/sys/riscv/include/cpufunc.h b/sys/riscv/include/cpufunc.h index 4ee68dcfccbd..6cac649b4e95 100644 --- a/sys/riscv/include/cpufunc.h +++ b/sys/riscv/include/cpufunc.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com> + * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com> * All rights reserved. * * Portions of this software were developed by SRI International and the @@ -54,11 +54,11 @@ intr_disable(void) uint64_t ret; __asm __volatile( - "csrrci %0, sstatus, 1" - : "=&r" (ret) + "csrrci %0, sstatus, %1" + : "=&r" (ret) : "i" (SSTATUS_SIE) ); - return (ret & SSTATUS_IE); + return (ret & (SSTATUS_SIE)); } static __inline void @@ -76,25 +76,11 @@ intr_enable(void) { __asm __volatile( - "csrsi sstatus, 1" + "csrsi sstatus, %0" + :: "i" (SSTATUS_SIE) ); } -static __inline register_t -machine_command(uint64_t cmd, uint64_t arg) -{ - uint64_t res; - - __asm __volatile( - "mv t5, %2\n" - "mv t6, %1\n" - "ecall\n" - "mv %0, t6" : "=&r"(res) : "r"(arg), "r"(cmd) - ); - - return (res); -} - #define cpu_nullop() riscv_nullop() #define cpufunc_nullop() riscv_nullop() #define cpu_setttb(a) riscv_setttb(a) diff --git a/sys/riscv/include/db_machdep.h b/sys/riscv/include/db_machdep.h index 7dfd90299d42..21550e4d574a 100644 --- a/sys/riscv/include/db_machdep.h +++ b/sys/riscv/include/db_machdep.h @@ -41,7 +41,7 @@ #include <machine/frame.h> #include <machine/trap.h> -#define T_BREAKPOINT (EXCP_INSTR_BREAKPOINT) +#define T_BREAKPOINT (EXCP_BREAKPOINT) #define T_WATCHPOINT (0) typedef vm_offset_t db_addr_t; diff --git a/sys/riscv/include/intr.h b/sys/riscv/include/intr.h index bc8c138ad01f..85c107bf507c 100644 --- a/sys/riscv/include/intr.h +++ b/sys/riscv/include/intr.h @@ -57,11 +57,23 @@ void riscv_unmask_ipi(void); #endif enum { - IRQ_SOFTWARE, - IRQ_TIMER, - IRQ_HTIF, + IRQ_SOFTWARE_USER, + IRQ_SOFTWARE_SUPERVISOR, + IRQ_SOFTWARE_HYPERVISOR, + IRQ_SOFTWARE_MACHINE, + IRQ_TIMER_USER, + IRQ_TIMER_SUPERVISOR, + IRQ_TIMER_HYPERVISOR, + IRQ_TIMER_MACHINE, + IRQ_EXTERNAL_USER, + IRQ_EXTERNAL_SUPERVISOR, + IRQ_EXTERNAL_HYPERVISOR, + IRQ_EXTERNAL_MACHINE, +#if 0 + /* lowRISC TODO */ IRQ_COP, /* lowRISC only */ IRQ_UART, /* lowRISC only */ +#endif NIRQS }; diff --git a/sys/riscv/include/pcpu.h b/sys/riscv/include/pcpu.h index d72b11c012e1..ea5336029d68 100644 --- a/sys/riscv/include/pcpu.h +++ b/sys/riscv/include/pcpu.h @@ -46,8 +46,7 @@ #define PCPU_MD_FIELDS \ uint32_t pc_pending_ipis; /* IPIs pending to this CPU */ \ - uint64_t pc_reg; /* CPU MMIO base (PA) */ \ - char __pad[117] + char __pad[125] #ifdef _KERNEL diff --git a/sys/riscv/include/pte.h b/sys/riscv/include/pte.h index d15cb84379fa..1658b90dca67 100644 --- a/sys/riscv/include/pte.h +++ b/sys/riscv/include/pte.h @@ -1,6 +1,6 @@ /*- * Copyright (c) 2014 Andrew Turner - * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com> + * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com> * All rights reserved. * * Portions of this software were developed by SRI International and the @@ -66,29 +66,18 @@ typedef uint64_t pn_t; /* page number */ #define Ln_ADDR_MASK (Ln_ENTRIES - 1) /* Bits 9:7 are reserved for software */ -#define PTE_SW_MANAGED (1 << 8) -#define PTE_SW_WIRED (1 << 7) -#define PTE_DIRTY (1 << 6) /* Virtual page is written */ -#define PTE_REF (1 << 5) /* Virtual page is referenced */ -#define PTE_VALID (1 << 0) /* Virtual page is valid */ -#define PTE_TYPE_S 1 -#define PTE_TYPE_M (0xf << PTE_TYPE_S) -#define PTE_TYPE_PTR 0 -#define PTE_TYPE_PTR_G 1 -#define PTE_TYPE_SROURX 2 /* Supervisor read-only, user read-execute page. */ -#define PTE_TYPE_SRWURWX 3 /* Supervisor read-write, user read-write-execute page. */ -#define PTE_TYPE_SURO 4 /* Supervisor and user read-only page. */ -#define PTE_TYPE_SURW 5 /* Supervisor and user read-write page. */ -#define PTE_TYPE_SURX 6 /* Supervisor and user read-execute page. */ -#define PTE_TYPE_SURWX 7 /* Supervisor and User Read Write Execute */ -#define PTE_TYPE_SRO 8 /* Supervisor read-only page. */ -#define PTE_TYPE_SRW 9 /* Supervisor read-write page. */ -#define PTE_TYPE_SRX 10 /* Supervisor read-execute page. */ -#define PTE_TYPE_SRWX 11 /* Supervisor read-write-execute page. */ -#define PTE_TYPE_SRO_G 12 /* Supervisor read-only page--global mapping. */ -#define PTE_TYPE_SRW_G 13 /* Supervisor read-write page--global mapping. */ -#define PTE_TYPE_SRX_G 14 /* Supervisor read-execute page--global mapping. */ -#define PTE_TYPE_SRWX_G 15 /* Supervisor Read Write Execute Global */ +#define PTE_SW_MANAGED (1 << 9) +#define PTE_SW_WIRED (1 << 8) +#define PTE_D (1 << 7) /* Dirty */ +#define PTE_A (1 << 6) /* Accessed */ +#define PTE_G (1 << 5) /* Global */ +#define PTE_U (1 << 4) /* User */ +#define PTE_X (1 << 3) /* Execute */ +#define PTE_W (1 << 2) /* Write */ +#define PTE_R (1 << 1) /* Read */ +#define PTE_V (1 << 0) /* Valid */ +#define PTE_RWX (PTE_R | PTE_W | PTE_X) +#define PTE_RX (PTE_R | PTE_X) #define PTE_PPN0_S 10 #define PTE_PPN1_S 19 diff --git a/sys/riscv/include/riscvreg.h b/sys/riscv/include/riscvreg.h index b18df1798446..2e3a4a2e9f5d 100644 --- a/sys/riscv/include/riscvreg.h +++ b/sys/riscv/include/riscvreg.h @@ -37,90 +37,113 @@ #ifndef _MACHINE_RISCVREG_H_ #define _MACHINE_RISCVREG_H_ -/* Machine mode requests */ -#define ECALL_MTIMECMP 0x01 -#define ECALL_CLEAR_PENDING 0x02 -#define ECALL_HTIF_CMD 0x03 -#define ECALL_HTIF_GET_ENTRY 0x04 -#define ECALL_MCPUID_GET 0x05 -#define ECALL_MIMPID_GET 0x06 -#define ECALL_SEND_IPI 0x07 -#define ECALL_CLEAR_IPI 0x08 -#define ECALL_HTIF_LOWPUTC 0x09 -#define ECALL_MIE_SET 0x0a -#define ECALL_IO_IRQ_MASK 0x0b - #define EXCP_SHIFT 0 #define EXCP_MASK (0xf << EXCP_SHIFT) -#define EXCP_INSTR_ADDR_MISALIGNED 0 -#define EXCP_INSTR_ACCESS_FAULT 1 -#define EXCP_INSTR_ILLEGAL 2 -#define EXCP_INSTR_BREAKPOINT 3 -#define EXCP_LOAD_ADDR_MISALIGNED 4 -#define EXCP_LOAD_ACCESS_FAULT 5 -#define EXCP_STORE_ADDR_MISALIGNED 6 -#define EXCP_STORE_ACCESS_FAULT 7 -#define EXCP_UMODE_ENV_CALL 8 -#define EXCP_SMODE_ENV_CALL 9 -#define EXCP_HMODE_ENV_CALL 10 -#define EXCP_MMODE_ENV_CALL 11 -#define EXCP_INTR (1 << 31) -#define EXCP_INTR_SOFTWARE 0 -#define EXCP_INTR_TIMER 1 -#define EXCP_INTR_HTIF 2 - -#define SSTATUS_IE (1 << 0) -#define SSTATUS_PIE (1 << 3) -#define SSTATUS_PS (1 << 4) - -#define MSTATUS_MPRV (1 << 16) -#define MSTATUS_PRV_SHIFT 1 -#define MSTATUS_PRV1_SHIFT 4 -#define MSTATUS_PRV2_SHIFT 7 -#define MSTATUS_PRV_MASK (0x3 << MSTATUS_PRV_SHIFT) -#define MSTATUS_PRV_U 0 /* user */ -#define MSTATUS_PRV_S 1 /* supervisor */ -#define MSTATUS_PRV_H 2 /* hypervisor */ -#define MSTATUS_PRV_M 3 /* machine */ - -#define MSTATUS_VM_SHIFT 17 -#define MSTATUS_VM_MASK 0x1f -#define MSTATUS_VM_MBARE 0 -#define MSTATUS_VM_MBB 1 -#define MSTATUS_VM_MBBID 2 -#define MSTATUS_VM_SV32 8 -#define MSTATUS_VM_SV39 9 -#define MSTATUS_VM_SV48 10 - +#define EXCP_MISALIGNED_FETCH 0 +#define EXCP_FAULT_FETCH 1 +#define EXCP_ILLEGAL_INSTRUCTION 2 +#define EXCP_BREAKPOINT 3 +#define EXCP_MISALIGNED_LOAD 4 +#define EXCP_FAULT_LOAD 5 +#define EXCP_MISALIGNED_STORE 6 +#define EXCP_FAULT_STORE 7 +#define EXCP_USER_ECALL 8 +#define EXCP_SUPERVISOR_ECALL 9 +#define EXCP_HYPERVISOR_ECALL 10 +#define EXCP_MACHINE_ECALL 11 +#define EXCP_INTR (1ul << 63) + +#define SSTATUS_UIE (1 << 0) +#define SSTATUS_SIE (1 << 1) +#define SSTATUS_UPIE (1 << 4) +#define SSTATUS_SPIE (1 << 5) +#define SSTATUS_SPIE_SHIFT 5 +#define SSTATUS_SPP (1 << 8) +#define SSTATUS_SPP_SHIFT 8 +#define SSTATUS_FS_MASK 0x3 +#define SSTATUS_FS_SHIFT 13 +#define SSTATUS_XS_MASK 0x3 +#define SSTATUS_XS_SHIFT 15 +#define SSTATUS_PUM (1 << 18) +#define SSTATUS32_SD (1 << 63) +#define SSTATUS64_SD (1 << 31) + +#define MSTATUS_UIE (1 << 0) +#define MSTATUS_SIE (1 << 1) +#define MSTATUS_HIE (1 << 2) +#define MSTATUS_MIE (1 << 3) +#define MSTATUS_UPIE (1 << 4) +#define MSTATUS_SPIE (1 << 5) +#define MSTATUS_SPIE_SHIFT 5 +#define MSTATUS_HPIE (1 << 6) +#define MSTATUS_MPIE (1 << 7) +#define MSTATUS_MPIE_SHIFT 7 +#define MSTATUS_SPP (1 << 8) +#define MSTATUS_SPP_SHIFT 8 +#define MSTATUS_HPP_MASK 0x3 +#define MSTATUS_HPP_SHIFT 9 +#define MSTATUS_MPP_MASK 0x3 +#define MSTATUS_MPP_SHIFT 11 +#define MSTATUS_FS_MASK 0x3 +#define MSTATUS_FS_SHIFT 13 +#define MSTATUS_XS_MASK 0x3 +#define MSTATUS_XS_SHIFT 15 +#define MSTATUS_MPRV (1 << 17) +#define MSTATUS_PUM (1 << 18) +#define MSTATUS_VM_MASK 0x1f +#define MSTATUS_VM_SHIFT 24 +#define MSTATUS_VM_MBARE 0 +#define MSTATUS_VM_MBB 1 +#define MSTATUS_VM_MBBID 2 +#define MSTATUS_VM_SV32 8 +#define MSTATUS_VM_SV39 9 +#define MSTATUS_VM_SV48 10 +#define MSTATUS_VM_SV57 11 +#define MSTATUS_VM_SV64 12 +#define MSTATUS32_SD (1 << 63) +#define MSTATUS64_SD (1 << 31) + +#define MSTATUS_PRV_U 0 /* user */ +#define MSTATUS_PRV_S 1 /* supervisor */ +#define MSTATUS_PRV_H 2 /* hypervisor */ +#define MSTATUS_PRV_M 3 /* machine */ + +#define MIE_USIE (1 << 0) #define MIE_SSIE (1 << 1) #define MIE_HSIE (1 << 2) #define MIE_MSIE (1 << 3) +#define MIE_UTIE (1 << 4) #define MIE_STIE (1 << 5) #define MIE_HTIE (1 << 6) #define MIE_MTIE (1 << 7) +#define MIP_USIP (1 << 0) #define MIP_SSIP (1 << 1) #define MIP_HSIP (1 << 2) #define MIP_MSIP (1 << 3) +#define MIP_UTIP (1 << 4) #define MIP_STIP (1 << 5) #define MIP_HTIP (1 << 6) #define MIP_MTIP (1 << 7) -#define SR_IE (1 << 0) -#define SR_IE1 (1 << 3) -#define SR_IE2 (1 << 6) -#define SR_IE3 (1 << 9) - +#define SIE_USIE (1 << 0) #define SIE_SSIE (1 << 1) +#define SIE_UTIE (1 << 4) #define SIE_STIE (1 << 5) +#define MIP_SEIP (1 << 9) + /* Note: sip register has no SIP_STIP bit in Spike simulator */ #define SIP_SSIP (1 << 1) #define SIP_STIP (1 << 5) +#if 0 +/* lowRISC TODO */ #define NCSRS 4096 #define CSR_IPI 0x783 #define CSR_IO_IRQ 0x7c0 /* lowRISC only? */ +#endif + #define XLEN 8 #define INSN_SIZE 4 diff --git a/sys/riscv/htif/htif.h b/sys/riscv/include/sbi.h index a1183d97c08e..76690ab84b08 100644 --- a/sys/riscv/htif/htif.h +++ b/sys/riscv/include/sbi.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com> + * Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com> * All rights reserved. * * Portions of this software were developed by SRI International and the @@ -34,60 +34,32 @@ * $FreeBSD$ */ -#define HTIF_DEV_ID_SHIFT (56) -#define HTIF_DEV_ID_MASK (0xfful << HTIF_DEV_ID_SHIFT) -#define HTIF_CMD_SHIFT (48) -#define HTIF_CMD_MASK (0xfful << HTIF_CMD_SHIFT) -#define HTIF_DATA_SHIFT (0) -#define HTIF_DATA_MASK (0xffffffff << HTIF_DATA_SHIFT) +#ifndef _MACHINE_SBI_H_ +#define _MACHINE_SBI_H_ -#define HTIF_CMD_READ (0x00ul) -#define HTIF_CMD_WRITE (0x01ul) -#define HTIF_CMD_READ_CONTROL_REG (0x02ul) -#define HTIF_CMD_WRITE_CONTROL_REG (0x03ul) -#define HTIF_CMD_IDENTIFY (0xfful) -#define IDENTIFY_PADDR_SHIFT 8 -#define IDENTIFY_IDENT 0xff +typedef struct { + uint64_t base; + uint64_t size; + uint64_t node_id; +} memory_block_info; -#define HTIF_NDEV (256) -#define HTIF_ID_LEN (64) -#define HTIF_ALIGN (64) +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); -#define HTIF_DEV_CMD(entry) ((entry & HTIF_CMD_MASK) >> HTIF_CMD_SHIFT) -#define HTIF_DEV_ID(entry) ((entry & HTIF_DEV_ID_MASK) >> HTIF_DEV_ID_SHIFT) -#define HTIF_DEV_DATA(entry) ((entry & HTIF_DATA_MASK) >> HTIF_DATA_SHIFT) +void sbi_console_putchar(unsigned char ch); +int sbi_console_getchar(void); -/* bus softc */ -struct htif_softc { - struct resource *res[1]; - void *ihl[1]; - device_t dev; - uint64_t identify_id; - uint64_t identify_done; -}; +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); -/* device private data */ -struct htif_dev_ivars { - char *id; - int index; - device_t dev; - struct htif_softc *sc; -}; +uint64_t sbi_mask_interrupt(uint64_t which); +uint64_t sbi_unmask_interrupt(uint64_t which); -uint64_t htif_command(uint64_t); -int htif_setup_intr(int id, void *func, void *arg); -int htif_read_ivar(device_t dev, device_t child, int which, uintptr_t *result); - -enum htif_device_ivars { - HTIF_IVAR_INDEX, - HTIF_IVAR_ID, -}; - -/* - * Simplified accessors for HTIF devices - */ -#define HTIF_ACCESSOR(var, ivar, type) \ - __BUS_ACCESSOR(htif, var, HTIF, ivar, type) - -HTIF_ACCESSOR(index, INDEX, int); -HTIF_ACCESSOR(id, ID, char *); +#endif /* !_MACHINE_SBI_H_ */ diff --git a/sys/riscv/include/vmparam.h b/sys/riscv/include/vmparam.h index a2166c80e1df..7ecd884f9da0 100644 --- a/sys/riscv/include/vmparam.h +++ b/sys/riscv/include/vmparam.h @@ -156,26 +156,26 @@ #define VM_MIN_KERNEL_ADDRESS (0xffffffc000000000UL) #define VM_MAX_KERNEL_ADDRESS (0xffffffc800000000UL) -/* Direct Map for 128 GiB of PA: 0x0 - 0x1fffffffff */ +/* 128 GiB maximum for the direct map region */ #define DMAP_MIN_ADDRESS (0xffffffd000000000UL) -#define DMAP_MAX_ADDRESS (0xffffffefffffffffUL) +#define DMAP_MAX_ADDRESS (0xfffffff000000000UL) -#define DMAP_MIN_PHYSADDR (0x0000000000000000UL) -#define DMAP_MAX_PHYSADDR (DMAP_MAX_ADDRESS - DMAP_MIN_ADDRESS) +#define DMAP_MIN_PHYSADDR (dmap_phys_base) +#define DMAP_MAX_PHYSADDR (dmap_phys_max) /* True if pa is in the dmap range */ #define PHYS_IN_DMAP(pa) ((pa) >= DMAP_MIN_PHYSADDR && \ - (pa) <= DMAP_MAX_PHYSADDR) + (pa) < DMAP_MAX_PHYSADDR) /* True if va is in the dmap range */ #define VIRT_IN_DMAP(va) ((va) >= DMAP_MIN_ADDRESS && \ - (va) <= DMAP_MAX_ADDRESS) + (va) < (dmap_max_addr)) #define PHYS_TO_DMAP(pa) \ ({ \ KASSERT(PHYS_IN_DMAP(pa), \ ("%s: PA out of range, PA: 0x%lx", __func__, \ (vm_paddr_t)(pa))); \ - (pa) | DMAP_MIN_ADDRESS; \ + ((pa) - dmap_phys_base) + DMAP_MIN_ADDRESS; \ }) #define DMAP_TO_PHYS(va) \ @@ -183,7 +183,7 @@ KASSERT(VIRT_IN_DMAP(va), \ ("%s: VA out of range, VA: 0x%lx", __func__, \ (vm_offset_t)(va))); \ - (va) & ~DMAP_MIN_ADDRESS; \ + ((va) - DMAP_MIN_ADDRESS) + dmap_phys_base; \ }) #define VM_MIN_USER_ADDRESS (0x0000000000000000UL) @@ -196,7 +196,7 @@ #define SHAREDPAGE (VM_MAXUSER_ADDRESS - PAGE_SIZE) #define USRSTACK SHAREDPAGE -#define KERNENTRY (0x200) +#define KERNENTRY (0) /* * How many physical pages per kmem arena virtual page. @@ -233,9 +233,14 @@ * #define UMA_MD_SMALL_ALLOC */ +#ifndef LOCORE +extern vm_paddr_t dmap_phys_base; +extern vm_paddr_t dmap_phys_max; +extern vm_offset_t dmap_max_addr; extern u_int tsb_kernel_ldd_phys; extern vm_offset_t vm_max_kernel_address; extern vm_offset_t init_pt_va; +#endif #define ZERO_REGION_SIZE (64 * 1024) /* 64KB */ diff --git a/sys/riscv/riscv/exception.S b/sys/riscv/riscv/exception.S index c00094c3e911..d5efd732ca65 100644 --- a/sys/riscv/riscv/exception.S +++ b/sys/riscv/riscv/exception.S @@ -117,14 +117,15 @@ __FBSDID("$FreeBSD$"); ld t0, (TF_SSTATUS)(sp) .if \el == 0 /* Ensure user interrupts will be enabled on eret. */ - ori t0, t0, SSTATUS_PIE + li t1, SSTATUS_SPIE + or t0, t0, t1 .else /* * Disable interrupts for supervisor mode exceptions. * For user mode exceptions we have already done this * in do_ast. */ - li t1, ~SSTATUS_IE + li t1, ~SSTATUS_SIE and t0, t0, t1 .endif csrw sstatus, t0 @@ -182,7 +183,7 @@ __FBSDID("$FreeBSD$"); /* Disable interrupts */ csrr a4, sstatus 1: - csrci sstatus, SSTATUS_IE + csrci sstatus, (SSTATUS_SIE) ld a1, PC_CURTHREAD(gp) lw a2, TD_FLAGS(a1) @@ -192,7 +193,7 @@ __FBSDID("$FreeBSD$"); beqz a2, 2f /* Restore interrupts */ - andi a4, a4, SSTATUS_IE + andi a4, a4, (SSTATUS_SIE) csrs sstatus, a4 /* Handle the ast */ @@ -204,12 +205,24 @@ __FBSDID("$FreeBSD$"); 2: .endm +ENTRY(cpu_exception_handler) + csrrw sp, sscratch, sp + beqz sp, 1f + /* User mode detected */ + csrrw sp, sscratch, sp + j cpu_exception_handler_user +1: + /* Supervisor mode detected */ + csrrw sp, sscratch, sp + j cpu_exception_handler_supervisor +END(cpu_exception_handler) + ENTRY(cpu_exception_handler_supervisor) save_registers 1 mv a0, sp call _C_LABEL(do_trap_supervisor) load_registers 1 - eret + sret END(cpu_exception_handler_supervisor) ENTRY(cpu_exception_handler_user) @@ -220,392 +233,5 @@ ENTRY(cpu_exception_handler_user) do_ast load_registers 0 csrrw sp, sscratch, sp - eret + sret END(cpu_exception_handler_user) - -/* - * Trap handlers - */ - .text -bad_trap: - j bad_trap - -user_trap: - /* Save state */ - csrrw sp, mscratch, sp - addi sp, sp, -64 - sd t0, (8 * 0)(sp) - sd t1, (8 * 1)(sp) - sd t2, (8 * 2)(sp) - sd t3, (8 * 3)(sp) - sd t4, (8 * 4)(sp) - sd t5, (8 * 5)(sp) - sd a0, (8 * 7)(sp) - - la t2, _C_LABEL(cpu_exception_handler_user) - - csrr t0, mcause - bltz t0, machine_interrupt - j exit_mrts - -supervisor_trap: - /* Save state */ - csrrw sp, mscratch, sp - addi sp, sp, -64 - sd t0, (8 * 0)(sp) - sd t1, (8 * 1)(sp) - sd t2, (8 * 2)(sp) - sd t3, (8 * 3)(sp) - sd t4, (8 * 4)(sp) - sd t5, (8 * 5)(sp) - sd a0, (8 * 7)(sp) - - la t2, _C_LABEL(cpu_exception_handler_supervisor) - - csrr t0, mcause - bltz t0, machine_interrupt - - li t1, EXCP_SMODE_ENV_CALL - beq t0, t1, supervisor_call - j exit_mrts - -machine_interrupt: - /* Type of interrupt ? */ - csrr t0, mcause - andi t0, t0, EXCP_MASK - li t1, 0 - beq t1, t0, software_interrupt - li t1, 1 - beq t1, t0, timer_interrupt - li t1, 2 - beq t1, t0, htif_interrupt - li t1, 4 - beq t1, t0, io_interrupt /* lowRISC only */ - - /* not reached */ -1: - j 1b - -io_interrupt: - /* Disable IO interrupts so we can go to supervisor mode */ - csrwi CSR_IO_IRQ, 0 - - /* Handle the trap in supervisor mode */ - j exit_mrts - -software_interrupt: - li t0, MIP_MSIP - csrc mip, t0 - li t0, MIP_SSIP - csrs mip, t0 - - /* If PRV1 is PRV_U (user) then serve the trap */ - csrr t0, mstatus - li t1, (MSTATUS_PRV_M << MSTATUS_PRV1_SHIFT) - and t0, t0, t1 - beqz t0, 1f - - /* - * If PRV1 is supervisor and interrupts were enabled, - * then serve the trap. - */ - csrr t0, mstatus - li t1, (SR_IE1 | (MSTATUS_PRV_M << MSTATUS_PRV1_SHIFT)) - and t0, t0, t1 - li t1, (SR_IE1 | (MSTATUS_PRV_S << MSTATUS_PRV1_SHIFT)) - beq t0, t1, 1f - - j exit - -1: - /* Handle the trap in supervisor mode */ - j exit_mrts - -timer_interrupt: - /* Disable machine timer interrupts */ - li t0, MIE_MTIE - csrc mie, t0 - - /* Clear machine pending */ - li t0, MIP_MTIP - csrc mip, t0 - - /* Post supervisor timer interrupt */ - li t0, MIP_STIP - csrs mip, t0 - - /* If PRV1 is PRV_U (user) then serve the trap */ - csrr t0, mstatus - li t1, (MSTATUS_PRV_M << MSTATUS_PRV1_SHIFT) - and t0, t0, t1 - beqz t0, 1f - - /* - * If PRV1 is supervisor and interrupts were enabled, - * then serve the trap. - */ - csrr t0, mstatus - li t1, (SR_IE1 | (MSTATUS_PRV_M << MSTATUS_PRV1_SHIFT)) - and t0, t0, t1 - li t1, (SR_IE1 | (MSTATUS_PRV_S << MSTATUS_PRV1_SHIFT)) - beq t0, t1, 1f - - j exit - -1: - /* Serve a trap in supervisor mode */ - j exit_mrts - -htif_interrupt: -1: - li t5, 0 - csrrw t5, mfromhost, t5 - beqz t5, 3f - - /* Console PUT intr ? */ - mv t1, t5 - li t0, 0x101 - srli t1, t1, 48 - bne t1, t0, 2f - /* Yes */ - la t0, console_intr - li t1, 1 - sd t1, 0(t0) - - /* Check if there is any other pending event */ - j 1b - -2: - /* Save entry */ - la t0, htif_ring - csrr t1, mhartid - li t4, (HTIF_RING_SIZE + 16) - mulw t4, t4, t1 - add t0, t0, t4 - li t4, (HTIF_RING_SIZE) - add t0, t0, t4 /* t0 == htif_ring_cursor */ - - ld t1, 0(t0) /* load ptr to cursor */ - sd t5, 0(t1) /* put entry */ - li t4, 1 - sd t4, 8(t1) /* mark used */ - ld t4, 16(t1) /* take next */ - /* Update cursor */ - sd t4, 0(t0) - - /* Post supervisor software interrupt */ - li t0, MIP_SSIP - csrs mip, t0 - - /* Check if there is any other pending event */ - j 1b - -3: - j exit - -supervisor_call: - csrr t1, mepc - addi t1, t1, 4 /* Next instruction in t1 */ - li t4, ECALL_HTIF_CMD - beq t5, t4, htif_cmd - li t4, ECALL_HTIF_GET_ENTRY - beq t5, t4, htif_get_entry - li t4, ECALL_MTIMECMP - beq t5, t4, set_mtimecmp - li t4, ECALL_CLEAR_PENDING - beq t5, t4, clear_pending - li t4, ECALL_MCPUID_GET - beq t5, t4, mcpuid_get - li t4, ECALL_MIMPID_GET - beq t5, t4, mimpid_get - li t4, ECALL_SEND_IPI - beq t5, t4, send_ipi - li t4, ECALL_CLEAR_IPI - beq t5, t4, clear_ipi - li t4, ECALL_HTIF_LOWPUTC - beq t5, t4, htif_lowputc - li t4, ECALL_MIE_SET - beq t5, t4, mie_set - li t4, ECALL_IO_IRQ_MASK - beq t5, t4, io_irq_mask - j exit_next_instr - -io_irq_mask: - csrw CSR_IO_IRQ, t6 - j exit_next_instr - -mie_set: - csrs mie, t6 - j exit_next_instr - -mcpuid_get: - csrr t6, mcpuid - j exit_next_instr - -mimpid_get: - csrr t6, mimpid - j exit_next_instr - -send_ipi: - /* CPU mmio base in t6 */ - mv t0, t6 - li t2, (CSR_IPI * XLEN) - add t0, t0, t2 /* t0 = CSR_IPI */ - li t2, 1 - sd t2, 0(t0) - j exit_next_instr - -clear_ipi: - /* Do only clear if there are no new entries in HTIF ring */ - la t0, htif_ring - csrr t2, mhartid - li t4, (HTIF_RING_SIZE + 16) - mulw t4, t4, t2 - add t0, t0, t4 - li t4, (HTIF_RING_SIZE) - add t0, t0, t4 /* t0 == ptr to htif_ring_cursor */ - ld t2, 8(t0) /* load htif_ring_last */ - ld t2, 8(t2) /* load used */ - bnez t2, 1f - - /* Clear supervisor software interrupt pending bit */ - li t0, MIP_SSIP - csrc mip, t0 - -1: - j exit_next_instr - -htif_get_entry: - /* Get a htif_ring for current core */ - la t0, htif_ring - csrr t2, mhartid - li t4, (HTIF_RING_SIZE + 16) - mulw t4, t4, t2 - add t0, t0, t4 - li t4, (HTIF_RING_SIZE + 8) - add t0, t0, t4 /* t0 == htif_ring_last */ - - /* Check for new entries */ - li t6, 0 /* preset return value */ - ld t2, 0(t0) /* load ptr to last */ - ld t4, 8(t2) /* get used */ - beqz t4, 1f /* No new entries. Exit */ - - /* Get one */ - ld t6, 0(t2) /* get entry */ - li t4, 0 - sd t4, 8(t2) /* mark free */ - sd t4, 0(t2) /* free entry, just in case */ - ld t4, 16(t2) /* take next */ - sd t4, 0(t0) /* update ptr to last */ -1: - /* Exit. Result is stored in t6 */ - j exit_next_instr - -htif_cmd: -1: - mv t0, t6 - csrrw t0, mtohost, t0 - bnez t0, 1b - j exit_next_instr - -htif_lowputc: -1: - mv t0, t6 - csrrw t0, mtohost, t0 - bnez t0, 1b - -2: - li t4, 0 - csrrw t5, mfromhost, t4 - beqz t5, 2b - - /* Console PUT intr ? */ - mv t2, t5 - srli t2, t2, 48 - li t3, 0x0101 - beq t2, t3, 3f - - /* Not a console PUT, so save entry */ - la t0, htif_ring - csrr t2, mhartid - li t4, (HTIF_RING_SIZE + 16) - mulw t4, t4, t2 - add t0, t0, t4 - li t4, (HTIF_RING_SIZE) - add t0, t0, t4 /* t0 == htif_ring_cursor */ - - ld t2, 0(t0) /* load ptr to cursor */ - sd t5, 0(t2) /* put entry */ - li t4, 1 - sd t4, 8(t2) /* mark used */ - ld t4, 16(t2) /* take next */ - /* Update cursor */ - sd t4, 0(t0) - - /* Post supervisor software interrupt */ - li t0, MIP_SSIP - csrs mip, t0 - - /* Wait for console intr again */ - j 2b - -3: - j exit_next_instr - -set_mtimecmp: - csrr t2, stime - add t6, t6, t2 - csrw mtimecmp, t6 - - /* Enable interrupts */ - li t0, (MIE_MTIE | MIE_STIE) - csrs mie, t0 - j exit_next_instr - -clear_pending: - li t0, MIP_STIP - csrc mip, t0 - j exit_next_instr - -/* - * Trap exit functions - */ -exit_next_instr: - /* Next instruction is in t1 */ - csrw mepc, t1 -exit: - /* Restore state */ - ld t0, (8 * 0)(sp) - ld t1, (8 * 1)(sp) - ld t2, (8 * 2)(sp) - ld t3, (8 * 3)(sp) - ld t4, (8 * 4)(sp) - ld t5, (8 * 5)(sp) - ld a0, (8 * 7)(sp) - addi sp, sp, 64 - csrrw sp, mscratch, sp - eret - -/* - * Redirect to supervisor - */ -exit_mrts: - /* Setup exception handler */ - li t1, KERNBASE - add t2, t2, t1 - csrw stvec, t2 - - /* Restore state */ - ld t0, (8 * 0)(sp) - ld t1, (8 * 1)(sp) - ld t2, (8 * 2)(sp) - ld t3, (8 * 3)(sp) - ld t4, (8 * 4)(sp) - ld t5, (8 * 5)(sp) - ld a0, (8 * 7)(sp) - addi sp, sp, 64 - csrrw sp, mscratch, sp - - /* Redirect to supervisor */ - mrts diff --git a/sys/riscv/riscv/identcpu.c b/sys/riscv/riscv/identcpu.c index dd1f2ba13382..94ad889e0ed9 100644 --- a/sys/riscv/riscv/identcpu.c +++ b/sys/riscv/riscv/identcpu.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com> + * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com> * All rights reserved. * * Portions of this software were developed by SRI International and the @@ -67,28 +67,16 @@ struct cpu_parts { struct cpu_implementers { u_int impl_id; const char *impl_name; - /* - * Part number is implementation defined - * so each vendor will have its own set of values and names. - */ - const struct cpu_parts *cpu_parts; }; -#define CPU_IMPLEMENTER_NONE { 0, "Unknown Implementer", cpu_parts_none } +#define CPU_IMPLEMENTER_NONE { 0, "Unknown Implementer" } /* - * Per-implementer table of (PartNum, CPU Name) pairs. + * CPU base */ -/* UC Berkeley */ -static const struct cpu_parts cpu_parts_ucb[] = { - { CPU_PART_RV32I, "RV32I" }, - { CPU_PART_RV32E, "RV32E" }, - { CPU_PART_RV64I, "RV64I" }, - { CPU_PART_RV128I, "RV128I" }, - CPU_PART_NONE, -}; - -/* Unknown */ -static const struct cpu_parts cpu_parts_none[] = { +static const struct cpu_parts cpu_parts_std[] = { + { CPU_PART_RV32, "RV32" }, + { CPU_PART_RV64, "RV64" }, + { CPU_PART_RV128, "RV128" }, CPU_PART_NONE, }; @@ -96,7 +84,7 @@ static const struct cpu_parts cpu_parts_none[] = { * Implementers table. */ const struct cpu_implementers cpu_implementers[] = { - { CPU_IMPL_UCB_ROCKET, "UC Berkeley Rocket", cpu_parts_ucb }, + { CPU_IMPL_UCB_ROCKET, "UC Berkeley Rocket" }, CPU_IMPLEMENTER_NONE, }; @@ -107,16 +95,16 @@ identify_cpu(void) uint32_t part_id; uint32_t impl_id; uint64_t mimpid; - uint64_t mcpuid; + uint64_t misa; u_int cpu; size_t i; cpu_partsp = NULL; - mimpid = machine_command(ECALL_MIMPID_GET, 0); - mcpuid = machine_command(ECALL_MCPUID_GET, 0); + /* TODO: can we get mimpid and misa somewhere ? */ + mimpid = 0; + misa = 0; - /* SMPTODO: use mhartid ? */ cpu = PCPU_GET(cpuid); impl_id = CPU_IMPL(mimpid); @@ -125,12 +113,12 @@ identify_cpu(void) cpu_implementers[i].impl_id == 0) { cpu_desc[cpu].cpu_impl = impl_id; cpu_desc[cpu].cpu_impl_name = cpu_implementers[i].impl_name; - cpu_partsp = cpu_implementers[i].cpu_parts; + cpu_partsp = cpu_parts_std; break; } } - part_id = CPU_PART(mcpuid); + part_id = CPU_PART(misa); for (i = 0; &cpu_partsp[i] != NULL; i++) { if (part_id == cpu_partsp[i].part_id || cpu_partsp[i].part_id == -1) { diff --git a/sys/riscv/riscv/intr_machdep.c b/sys/riscv/riscv/intr_machdep.c index ad30bf2f991f..879cea710e7e 100644 --- a/sys/riscv/riscv/intr_machdep.c +++ b/sys/riscv/riscv/intr_machdep.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include <machine/cpufunc.h> #include <machine/frame.h> #include <machine/intr.h> +#include <machine/sbi.h> #ifdef SMP #include <machine/smp.h> @@ -95,15 +96,20 @@ riscv_mask_irq(void *source) irq = (uintptr_t)source; switch (irq) { - case IRQ_TIMER: + case IRQ_TIMER_SUPERVISOR: csr_clear(sie, SIE_STIE); break; - case IRQ_SOFTWARE: + case IRQ_SOFTWARE_USER: + csr_clear(sie, SIE_USIE); + case IRQ_SOFTWARE_SUPERVISOR: csr_clear(sie, SIE_SSIE); break; +#if 0 + /* lowRISC TODO */ case IRQ_UART: machine_command(ECALL_IO_IRQ_MASK, 0); break; +#endif default: panic("Unknown irq %d\n", irq); } @@ -117,15 +123,21 @@ riscv_unmask_irq(void *source) irq = (uintptr_t)source; switch (irq) { - case IRQ_TIMER: + case IRQ_TIMER_SUPERVISOR: csr_set(sie, SIE_STIE); break; - case IRQ_SOFTWARE: + case IRQ_SOFTWARE_USER: + csr_set(sie, SIE_USIE); + break; + case IRQ_SOFTWARE_SUPERVISOR: csr_set(sie, SIE_SSIE); break; +#if 0 + /* lowRISC TODO */ case IRQ_UART: machine_command(ECALL_IO_IRQ_MASK, 1); break; +#endif default: panic("Unknown irq %d\n", irq); } @@ -209,18 +221,18 @@ riscv_cpu_intr(struct trapframe *frame) active_irq = (frame->tf_scause & EXCP_MASK); switch (active_irq) { +#if 0 + /* lowRISC TODO */ case IRQ_UART: - case IRQ_SOFTWARE: - case IRQ_TIMER: +#endif + case IRQ_SOFTWARE_USER: + case IRQ_SOFTWARE_SUPERVISOR: + case IRQ_TIMER_SUPERVISOR: event = intr_events[active_irq]; /* Update counters */ atomic_add_long(riscv_intr_counters[active_irq], 1); PCPU_INC(cnt.v_intr); break; - case IRQ_HTIF: - /* HTIF interrupts are only handled in machine mode */ - panic("%s: HTIF interrupt", __func__); - break; default: event = NULL; } @@ -237,7 +249,7 @@ void riscv_setup_ipihandler(driver_filter_t *filt) { - riscv_setup_intr("ipi", filt, NULL, NULL, IRQ_SOFTWARE, + riscv_setup_intr("ipi", filt, NULL, NULL, IRQ_SOFTWARE_SUPERVISOR, INTR_TYPE_MISC, NULL); } @@ -256,7 +268,7 @@ ipi_send(struct pcpu *pc, int ipi) CTR3(KTR_SMP, "%s: cpu=%d, ipi=%x", __func__, pc->pc_cpuid, ipi); atomic_set_32(&pc->pc_pending_ipis, ipi); - machine_command(ECALL_SEND_IPI, pc->pc_reg); + sbi_send_ipi(pc->pc_cpuid); CTR1(KTR_SMP, "%s: sent", __func__); } diff --git a/sys/riscv/riscv/locore.S b/sys/riscv/riscv/locore.S index 9df5c2da258c..2b36e2e8aeb8 100644 --- a/sys/riscv/riscv/locore.S +++ b/sys/riscv/riscv/locore.S @@ -43,113 +43,53 @@ #include <machine/riscvreg.h> #include <machine/pte.h> -#define HTIF_RING_NENTRIES (512) -#define HTIF_RING_ENTRY_SZ (24) -#define HTIF_RING_SIZE (HTIF_RING_ENTRY_SZ * HTIF_RING_NENTRIES) -#define HW_STACK_SIZE (96) - -/* - * Event queue for each CPU core: - * - * struct htif_ring { - * uint64_t data; - * uint64_t used; - * uint64_t next; - * } htif_ring[HTIF_RING_NENTRIES]; - * uint64_t htif_ring_cursor; - * uint64_t htif_ring_last; - */ - -.macro build_ring - la t0, htif_ring -#ifdef SMP - csrr a0, mhartid - li s0, (HTIF_RING_SIZE + 16) - mulw s0, a0, s0 - add t0, t0, s0 -#endif - li t1, 0 - sd t1, 0(t0) /* zero data */ - sd t1, 8(t0) /* zero used */ - mv t2, t0 - mv t3, t0 - li t5, (HTIF_RING_SIZE) - li t6, 0 - add t4, t0, t5 -1: - addi t3, t3, HTIF_RING_ENTRY_SZ /* pointer to next */ - beq t3, t4, 2f /* finish */ - sd t3, 16(t2) /* store pointer */ - addi t2, t2, HTIF_RING_ENTRY_SZ /* next entry */ - addi t6, t6, 1 /* counter */ - j 1b -2: - addi t3, t3, -HTIF_RING_ENTRY_SZ - sd t0, 16(t3) /* last -> first */ - - li t2, (HTIF_RING_SIZE) - add s0, t0, t2 - sd t0, 0(s0) /* cursor */ - sd t0, 8(s0) /* last */ - /* finish building ring */ -.endm - .globl kernbase .set kernbase, KERNBASE /* Trap entries */ .text -mentry: - /* User mode entry point (mtvec + 0x000) */ - .align 6 - j user_trap - - /* Supervisor mode entry point (mtvec + 0x040) */ - .align 6 - j supervisor_trap - - /* Hypervisor mode entry point (mtvec + 0x080) */ - .align 6 - j bad_trap - - /* Machine mode entry point (mtvec + 0x0C0) */ - .align 6 - j bad_trap - /* Reset vector */ .text - .align 8 .globl _start _start: - /* Direct secondary cores to mpentry */ - csrr a0, mhartid - bnez a0, mpentry - - /* Build event queue for current core */ - build_ring - - /* Setup machine-mode stack for CPU 0 */ - la t0, hardstack_end - csrw mscratch, t0 + /* Setup supervisor trap vector */ + la t0, cpu_exception_handler + csrw stvec, t0 + /* Ensure sscratch is zero */ li t0, 0 csrw sscratch, t0 - li s10, PAGE_SIZE - li s9, (PAGE_SIZE * KSTACK_PAGES) + /* Load physical memory information */ + li a0, 0 + la a1, memory_info + call sbi_query_memory + + /* Store base to s6 */ + la s6, memory_info + ld s6, 0(s6) /* s6 = physmem base */ + + /* Direct secondary cores to mpentry */ + call sbi_hart_id + bnez a0, mpentry - /* Page tables */ + /* + * 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_VALID | (PTE_TYPE_PTR << PTE_TYPE_S)) + li t4, PTE_V slli t5, s2, PTE_PPN0_S /* (s2 << PTE_PPN0_S) */ or t6, t4, t5 @@ -159,19 +99,74 @@ _start: add t0, s1, a5 sd t6, (t0) - /* Add single Level 1 entry for kernel */ + /* 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, 0x80009000 + 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 srli a5, a5, L1_SHIFT /* >> L1_SHIFT */ andi a5, a5, 0x1ff /* & 0x1ff */ - li t4, (PTE_VALID | (PTE_TYPE_PTR << PTE_TYPE_S)) + 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 @@ -179,11 +174,12 @@ _start: /* Level 2 superpages (512 x 2MiB) */ la s1, pagetable_l2 - li t3, 512 /* Build 512 entries */ - li t4, 0 /* Counter */ + 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_VALID | (PTE_TYPE_SRWX << PTE_TYPE_S)) + 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 */ @@ -193,33 +189,13 @@ _start: bltu t4, t3, 2b /* Set page tables base register */ - la s1, pagetable_l1 - csrw sptbr, s1 - - /* Page tables END */ - - /* Enter supervisor mode */ - li s0, ((MSTATUS_VM_SV39 << MSTATUS_VM_SHIFT) | \ - (MSTATUS_PRV_M << MSTATUS_PRV_SHIFT) | \ - (MSTATUS_PRV_S << MSTATUS_PRV1_SHIFT) | \ - (MSTATUS_PRV_U << MSTATUS_PRV2_SHIFT)); - csrw mstatus, s0 - - /* - * Enable machine-mode software interrupts - * so we can deliver IPI to this core. - */ - li t0, MIE_MSIE - csrs mie, t0 - - /* Exit from machine mode */ - la t0, .Lmmu_on - li s11, KERNBASE - add t0, t0, s11 - csrw mepc, t0 - eret + la s2, pagetable_l1 + li t0, KERNBASE + sub s2, s2, t0 + add s2, s2, s6 + srli s2, s2, PAGE_SHIFT + csrw sptbr, s2 -.Lmmu_on: /* Initialize stack pointer */ la s3, initstack_end mv sp, s3 @@ -235,8 +211,10 @@ _start: /* Fill riscv_bootparams */ addi sp, sp, -16 + la t0, pagetable_l1 sd t0, 0(sp) /* kern_l1pt */ + la t0, initstack_end sd t0, 8(sp) /* kern_stack */ @@ -248,17 +226,6 @@ _start: initstack: .space (PAGE_SIZE * KSTACK_PAGES) initstack_end: -hardstack: - .space (HW_STACK_SIZE * MAXCPU) -hardstack_end: - - .globl htif_ring -htif_ring: - .space ((HTIF_RING_SIZE + 16) * MAXCPU) - - .globl console_intr -console_intr: - .space (8) ENTRY(sigcode) mv a0, sp @@ -291,6 +258,14 @@ 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) .globl init_pt_va init_pt_va: @@ -307,7 +282,6 @@ END(mpentry) * mpentry(unsigned long) * * Called by a core when it is being brought online. - * The data in x0 is passed straight to init_secondary. */ ENTRY(mpentry) /* @@ -325,49 +299,13 @@ ENTRY(mpentry) lw t1, 0(t0) beqz t1, 1b - /* Build event queue ring for this core */ - build_ring - /* Set page tables base register */ - la t0, pagetable_l1 - csrw sptbr, t0 - - /* Configure mstatus */ - li s0, ((MSTATUS_VM_SV39 << MSTATUS_VM_SHIFT) | \ - (MSTATUS_PRV_M << MSTATUS_PRV_SHIFT) | \ - (MSTATUS_PRV_S << MSTATUS_PRV1_SHIFT) | \ - (MSTATUS_PRV_U << MSTATUS_PRV2_SHIFT)); - csrw mstatus, s0 - - /* Setup stack for machine mode exceptions */ - la t0, hardstack_end - li t1, HW_STACK_SIZE - mulw t1, t1, a0 - sub t0, t0, t1 - csrw mscratch, t0 - - li t0, 0 - csrw sscratch, t0 - - /* - * Enable machine-mode software interrupts - * so we can deliver IPI to this core. - */ - li t0, MIE_MSIE - csrs mie, t0 - - /* - * Exit from machine mode and go to - * the virtual address space. - */ - la t0, mp_virtdone - li s11, KERNBASE - add t0, t0, s11 - csrw mepc, t0 - eret - -mp_virtdone: - /* We are now in virtual address space */ + 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 @@ -378,5 +316,3 @@ mp_virtdone: call init_secondary END(mpentry) #endif - -#include "exception.S" diff --git a/sys/riscv/riscv/machdep.c b/sys/riscv/riscv/machdep.c index fafa2f439788..7bc4402597de 100644 --- a/sys/riscv/riscv/machdep.c +++ b/sys/riscv/riscv/machdep.c @@ -80,6 +80,7 @@ __FBSDID("$FreeBSD$"); #include <machine/trap.h> #include <machine/vmparam.h> #include <machine/intr.h> +#include <machine/sbi.h> #include <machine/asm.h> @@ -116,6 +117,7 @@ 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; @@ -440,10 +442,10 @@ sys_sigreturn(struct thread *td, struct sigreturn_args *uap) /* * Make sure the processor mode has not been tampered with and * interrupts have not been disabled. + * Supervisor interrupts in user mode are always enabled. */ sstatus = uc.uc_mcontext.mc_gpregs.gp_sstatus; - if ((sstatus & SSTATUS_PS) != 0 || - (sstatus & SSTATUS_PIE) == 0) + if ((sstatus & SSTATUS_SPP) != 0) return (EINVAL); error = set_mcontext(td, &uc.uc_mcontext); @@ -728,12 +730,9 @@ 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 lastaddr; - int mem_regions_sz; vm_size_t kernlen; caddr_t kmdp; - int i; /* Set the module data location */ lastaddr = fake_preload_metadata(rvbp); @@ -743,7 +742,8 @@ initriscv(struct riscv_bootparams *rvbp) if (kmdp == NULL) kmdp = preload_search_by_type("elf64 kernel"); - boothowto = 0; + boothowto = RB_VERBOSE | RB_SINGLE; + boothowto = RB_VERBOSE; kern_envp = NULL; @@ -754,12 +754,20 @@ initriscv(struct riscv_bootparams *rvbp) /* Load the physical memory ranges */ physmap_idx = 0; +#if 0 + struct mem_region mem_regions[FDT_MEM_REGIONS]; + int mem_regions_sz; + int i; /* 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); /* Set the pcpu data, this is needed by pmap_bootstrap */ pcpup = &__pcpu[0]; @@ -775,16 +783,17 @@ initriscv(struct riscv_bootparams *rvbp) cache_setup(); - /* Bootstrap enough of pmap to enter the kernel proper */ + /* Bootstrap enough of pmap to enter the kernel proper */ kernlen = (lastaddr - KERNBASE); - pmap_bootstrap(rvbp->kern_l1pt, KERNENTRY, kernlen); + pmap_bootstrap(rvbp->kern_l1pt, memory_info.base, kernlen); cninit(); init_proc0(rvbp->kern_stack); /* set page table base register for thread0 */ - thread0.td_pcb->pcb_l1addr = (rvbp->kern_l1pt - KERNBASE); + thread0.td_pcb->pcb_l1addr = \ + (rvbp->kern_l1pt - KERNBASE + memory_info.base); msgbufinit(msgbufp, msgbufsize); mutex_init(); diff --git a/sys/riscv/riscv/mp_machdep.c b/sys/riscv/riscv/mp_machdep.c index 9152e700e36d..33353ac2a3c8 100644 --- a/sys/riscv/riscv/mp_machdep.c +++ b/sys/riscv/riscv/mp_machdep.c @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include <machine/intr.h> #include <machine/smp.h> +#include <machine/sbi.h> #ifdef VFP #include <machine/vfp.h> #endif @@ -273,14 +274,7 @@ ipi_handler(void *arg) u_int cpu, ipi; int bit; - /* - * We have shared interrupt line for both IPI and HTIF, - * so we don't really need to clear pending bit here - * as it will be cleared later in htif_intr. - * But lets assume HTIF is optional part, so do clear - * pending bit if there is no new entires in htif_ring. - */ - machine_command(ECALL_CLEAR_IPI, 0); + sbi_clear_ipi(); cpu = PCPU_GET(cpuid); @@ -382,12 +376,10 @@ cpu_init_fdt(u_int id, phandle_t node, u_int addr_size, pcell_t *reg) /* We are already running on cpu 0 */ if (id == 0) { - pcpup->pc_reg = target_cpu; return (1); } pcpu_init(pcpup, id, sizeof(struct pcpu)); - pcpup->pc_reg = target_cpu; dpcpu[id - 1] = (void *)kmem_malloc(kernel_arena, DPCPU_SIZE, M_WAITOK | M_ZERO); diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c index a6c899b0776e..f09fc857a897 100644 --- a/sys/riscv/riscv/pmap.c +++ b/sys/riscv/riscv/pmap.c @@ -220,6 +220,14 @@ vm_offset_t kernel_vm_end = 0; struct msgbuf *msgbufp = NULL; +vm_paddr_t dmap_phys_base; /* The start of the dmap region */ +vm_paddr_t dmap_phys_max; /* The limit of the dmap region */ +vm_offset_t dmap_max_addr; /* The virtual address limit of the dmap */ + +/* This code assumes all L1 DMAP entries will be used */ +CTASSERT((DMAP_MIN_ADDRESS & ~L1_OFFSET) == DMAP_MIN_ADDRESS); +CTASSERT((DMAP_MAX_ADDRESS & ~L1_OFFSET) == DMAP_MAX_ADDRESS); + static struct rwlock_padalign pvh_global_lock; /* @@ -311,9 +319,9 @@ pmap_l2(pmap_t pmap, vm_offset_t va) l1 = pmap_l1(pmap, va); if (l1 == NULL) return (NULL); - if ((pmap_load(l1) & PTE_VALID) == 0) + if ((pmap_load(l1) & PTE_V) == 0) return (NULL); - if ((pmap_load(l1) & PTE_TYPE_M) != (PTE_TYPE_PTR << PTE_TYPE_S)) + if ((pmap_load(l1) & PTE_RX) != 0) return (NULL); return (pmap_l1_to_l2(l1, va)); @@ -339,9 +347,9 @@ pmap_l3(pmap_t pmap, vm_offset_t va) l2 = pmap_l2(pmap, va); if (l2 == NULL) return (NULL); - if ((pmap_load(l2) & PTE_VALID) == 0) + if ((pmap_load(l2) & PTE_V) == 0) return (NULL); - if ((pmap_load(l2) & PTE_TYPE_M) != (PTE_TYPE_PTR << PTE_TYPE_S)) + if ((pmap_load(l2) & PTE_RX) != 0) return (NULL); return (pmap_l2_to_l3(l2, va)); @@ -352,10 +360,7 @@ static __inline int pmap_is_write(pt_entry_t entry) { - if (entry & (1 << PTE_TYPE_S)) - return (1); - - return (0); + return (entry & PTE_W); } static __inline int @@ -370,7 +375,7 @@ static __inline int pmap_l3_valid(pt_entry_t l3) { - return (l3 & PTE_VALID); + return (l3 & PTE_V); } static __inline int @@ -389,7 +394,7 @@ static inline int pmap_page_dirty(pt_entry_t pte) { - return (pte & PTE_DIRTY); + return (pte & PTE_D); } static __inline void @@ -442,7 +447,7 @@ pmap_early_page_idx(vm_offset_t l1pt, vm_offset_t va, u_int *l1_slot, *l1_slot = (va >> L1_SHIFT) & Ln_ADDR_MASK; /* Check locore has used a table L1 map */ - KASSERT((l1[*l1_slot] & PTE_TYPE_M) == (PTE_TYPE_PTR << PTE_TYPE_S), + KASSERT((l1[*l1_slot] & PTE_RX) == 0, ("Invalid bootstrap L1 table")); /* Find the address of the L2 table */ @@ -461,6 +466,10 @@ pmap_early_vtophys(vm_offset_t l1pt, vm_offset_t va) l2 = pmap_early_page_idx(l1pt, va, &l1_slot, &l2_slot); + /* Check locore has used L2 superpages */ + KASSERT((l2[l2_slot] & PTE_RX) != 0, + ("Invalid bootstrap L2 table")); + /* L2 is superpages */ ret = (l2[l2_slot] >> PTE_PPN1_S) << L2_SHIFT; ret += (va & L2_OFFSET); @@ -469,7 +478,7 @@ pmap_early_vtophys(vm_offset_t l1pt, vm_offset_t va) } static void -pmap_bootstrap_dmap(vm_offset_t l1pt, vm_paddr_t kernstart) +pmap_bootstrap_dmap(vm_offset_t kern_l1, vm_paddr_t min_pa, vm_paddr_t max_pa) { vm_offset_t va; vm_paddr_t pa; @@ -478,22 +487,26 @@ pmap_bootstrap_dmap(vm_offset_t l1pt, vm_paddr_t kernstart) pt_entry_t entry; pn_t pn; - pa = kernstart & ~L1_OFFSET; + pa = dmap_phys_base = min_pa & ~L1_OFFSET; va = DMAP_MIN_ADDRESS; - l1 = (pd_entry_t *)l1pt; + l1 = (pd_entry_t *)kern_l1; l1_slot = pmap_l1_index(DMAP_MIN_ADDRESS); - for (; va < DMAP_MAX_ADDRESS; + for (; va < DMAP_MAX_ADDRESS && pa < max_pa; pa += L1_SIZE, va += L1_SIZE, l1_slot++) { KASSERT(l1_slot < Ln_ENTRIES, ("Invalid L1 index")); /* superpages */ pn = (pa / PAGE_SIZE); - entry = (PTE_VALID | (PTE_TYPE_SRWX << PTE_TYPE_S)); + entry = (PTE_V | PTE_RWX); entry |= (pn << PTE_PPN0_S); pmap_load_store(&l1[l1_slot], entry); } + /* Set the upper limit of the DMAP region */ + dmap_phys_max = pa; + dmap_max_addr = va; + cpu_dcache_wb_range((vm_offset_t)l1, PAGE_SIZE); cpu_tlb_flushID(); } @@ -521,19 +534,20 @@ pmap_bootstrap_l3(vm_offset_t l1pt, vm_offset_t va, vm_offset_t l3_start) pa = pmap_early_vtophys(l1pt, l3pt); pn = (pa / PAGE_SIZE); - entry = (PTE_VALID | (PTE_TYPE_PTR << PTE_TYPE_S)); + entry = (PTE_V); entry |= (pn << PTE_PPN0_S); pmap_load_store(&l2[l2_slot], entry); l3pt += PAGE_SIZE; } + /* Clean the L2 page table */ memset((void *)l3_start, 0, l3pt - l3_start); cpu_dcache_wb_range(l3_start, l3pt - l3_start); cpu_dcache_wb_range((vm_offset_t)l2, PAGE_SIZE); - return l3pt; + return (l3pt); } /* @@ -547,7 +561,7 @@ pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart, vm_size_t kernlen) pt_entry_t *l2; vm_offset_t va, freemempos; vm_offset_t dpcpu, msgbufpv; - vm_paddr_t pa, min_pa; + vm_paddr_t pa, min_pa, max_pa; int i; kern_delta = KERNBASE - kernstart; @@ -569,7 +583,7 @@ pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart, vm_size_t kernlen) LIST_INIT(&allpmaps); /* Assume the address we were loaded to is a valid physical address */ - min_pa = KERNBASE - kern_delta; + min_pa = max_pa = KERNBASE - kern_delta; /* * Find the minimum physical address. physmap is sorted, @@ -580,11 +594,13 @@ pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart, vm_size_t kernlen) continue; if (physmap[i] <= min_pa) min_pa = physmap[i]; + if (physmap[i + 1] > max_pa) + max_pa = physmap[i + 1]; break; } /* Create a direct map region early so we can use it for pa -> va */ - pmap_bootstrap_dmap(l1pt, min_pa); + pmap_bootstrap_dmap(l1pt, min_pa, max_pa); va = KERNBASE; pa = KERNBASE - kern_delta; @@ -598,6 +614,10 @@ pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart, vm_size_t kernlen) if (physmap[map_slot] == physmap[map_slot + 1]) continue; + if (physmap[map_slot] <= pa && + physmap[map_slot + 1] > pa) + break; + phys_avail[avail_slot] = physmap[map_slot]; phys_avail[avail_slot + 1] = physmap[map_slot + 1]; physmem += (phys_avail[avail_slot + 1] - @@ -627,11 +647,11 @@ pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart, vm_size_t kernlen) /* Find how many pages we have mapped */ for (; l2_slot < Ln_ENTRIES; l2_slot++) { - if ((l2[l2_slot] & PTE_VALID) == 0) + if ((l2[l2_slot] & PTE_V) == 0) break; /* Check locore used L2 superpages */ - KASSERT((l2[l2_slot] & PTE_TYPE_M) != (PTE_TYPE_PTR << PTE_TYPE_S), + KASSERT((l2[l2_slot] & PTE_RX) != 0, ("Invalid bootstrap L2 table")); va += L2_SIZE; @@ -672,12 +692,14 @@ pmap_bootstrap(vm_offset_t l1pt, vm_paddr_t kernstart, vm_size_t kernlen) map_slot = used_map_slot; for (; avail_slot < (PHYS_AVAIL_SIZE - 2) && map_slot < (physmap_idx * 2); map_slot += 2) { - if (physmap[map_slot] == physmap[map_slot + 1]) + if (physmap[map_slot] == physmap[map_slot + 1]) { continue; + } /* Have we used the current range? */ - if (physmap[map_slot + 1] <= pa) + if (physmap[map_slot + 1] <= pa) { continue; + } /* Do we need to split the entry? */ if (physmap[map_slot] < pa) { @@ -797,7 +819,7 @@ pmap_extract(pmap_t pmap, vm_offset_t va) l2p = pmap_l2(pmap, va); if (l2p != NULL) { l2 = pmap_load(l2p); - if ((l2 & PTE_TYPE_M) == (PTE_TYPE_PTR << PTE_TYPE_S)) { + if ((l2 & PTE_RX) == 0) { l3p = pmap_l2_to_l3(l2p, va); if (l3p != NULL) { l3 = pmap_load(l3p); @@ -861,7 +883,7 @@ pmap_kextract(vm_offset_t va) l2 = pmap_l2(kernel_pmap, va); if (l2 == NULL) panic("pmap_kextract: No l2"); - if ((pmap_load(l2) & PTE_TYPE_M) != (PTE_TYPE_PTR << PTE_TYPE_S)) { + if ((pmap_load(l2) & PTE_RX) != 0) { /* superpages */ pa = (pmap_load(l2) >> PTE_PPN1_S) << L2_SHIFT; pa |= (va & L2_OFFSET); @@ -902,7 +924,7 @@ pmap_kenter_device(vm_offset_t sva, vm_size_t size, vm_paddr_t pa) KASSERT(l3 != NULL, ("Invalid page table, va: 0x%lx", va)); pn = (pa / PAGE_SIZE); - entry = (PTE_VALID | (PTE_TYPE_SRWX << PTE_TYPE_S)); + entry = (PTE_V | PTE_RWX); entry |= (pn << PTE_PPN0_S); pmap_load_store(l3, entry); @@ -1004,7 +1026,7 @@ pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count) pn = (pa / PAGE_SIZE); l3 = pmap_l3(kernel_pmap, va); - entry = (PTE_VALID | (PTE_TYPE_SRWX << PTE_TYPE_S)); + entry = (PTE_V | PTE_RWX); entry |= (pn << PTE_PPN0_S); pmap_load_store(l3, entry); @@ -1261,7 +1283,7 @@ _pmap_alloc_l3(pmap_t pmap, vm_pindex_t ptepindex, struct rwlock **lockp) l1 = &pmap->pm_l1[l1index]; pn = (VM_PAGE_TO_PHYS(m) / PAGE_SIZE); - entry = (PTE_VALID | (PTE_TYPE_PTR << PTE_TYPE_S)); + entry = (PTE_V); entry |= (pn << PTE_PPN0_S); pmap_load_store(l1, entry); pmap_distribute_l1(pmap, l1index, entry); @@ -1294,7 +1316,7 @@ _pmap_alloc_l3(pmap_t pmap, vm_pindex_t ptepindex, struct rwlock **lockp) l2 = &l2[ptepindex & Ln_ADDR_MASK]; pn = (VM_PAGE_TO_PHYS(m) / PAGE_SIZE); - entry = (PTE_VALID | (PTE_TYPE_PTR << PTE_TYPE_S)); + entry = (PTE_V); entry |= (pn << PTE_PPN0_S); pmap_load_store(l2, entry); @@ -1428,7 +1450,7 @@ pmap_growkernel(vm_offset_t addr) paddr = VM_PAGE_TO_PHYS(nkpg); pn = (paddr / PAGE_SIZE); - entry = (PTE_VALID | (PTE_TYPE_PTR << PTE_TYPE_S)); + entry = (PTE_V); entry |= (pn << PTE_PPN0_S); pmap_load_store(l1, entry); pmap_distribute_l1(kernel_pmap, @@ -1438,7 +1460,7 @@ pmap_growkernel(vm_offset_t addr) continue; /* try again */ } l2 = pmap_l1_to_l2(l1, kernel_vm_end); - if ((pmap_load(l2) & PTE_REF) != 0) { + if ((pmap_load(l2) & PTE_A) != 0) { kernel_vm_end = (kernel_vm_end + L2_SIZE) & ~L2_OFFSET; if (kernel_vm_end - 1 >= kernel_map->max_offset) { kernel_vm_end = kernel_map->max_offset; @@ -1452,12 +1474,13 @@ pmap_growkernel(vm_offset_t addr) VM_ALLOC_ZERO); if (nkpg == NULL) panic("pmap_growkernel: no memory to grow kernel"); - if ((nkpg->flags & PG_ZERO) == 0) + if ((nkpg->flags & PG_ZERO) == 0) { pmap_zero_page(nkpg); + } paddr = VM_PAGE_TO_PHYS(nkpg); pn = (paddr / PAGE_SIZE); - entry = (PTE_VALID | (PTE_TYPE_PTR << PTE_TYPE_S)); + entry = (PTE_V); entry |= (pn << PTE_PPN0_S); pmap_load_store(l2, entry); @@ -1754,7 +1777,7 @@ pmap_remove_l3(pmap_t pmap, pt_entry_t *l3, vm_offset_t va, m = PHYS_TO_VM_PAGE(phys); if (pmap_page_dirty(old_l3)) vm_page_dirty(m); - if (old_l3 & PTE_REF) + if (old_l3 & PTE_A) vm_page_aflag_set(m, PGA_REFERENCED); CHANGE_PV_LIST_LOCK_TO_VM_PAGE(lockp, m); pmap_pvh_free(&m->md, pmap, va); @@ -1822,7 +1845,7 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) */ if (l3_pte == 0) continue; - if ((pmap_load(l2) & PTE_TYPE_M) != (PTE_TYPE_PTR << PTE_TYPE_S)) + if ((pmap_load(l2) & PTE_RX) != 0) continue; /* @@ -1899,7 +1922,7 @@ pmap_remove_all(vm_page_t m) KASSERT(l2 != NULL, ("pmap_remove_all: no l2 table found")); tl2 = pmap_load(l2); - KASSERT((tl2 & PTE_TYPE_M) == (PTE_TYPE_PTR << PTE_TYPE_S), + KASSERT((tl2 & PTE_RX) == 0, ("pmap_remove_all: found a table when expecting " "a block in %p's pv list", m)); @@ -1912,7 +1935,7 @@ pmap_remove_all(vm_page_t m) pmap_invalidate_page(pmap, pv->pv_va); if (tl3 & PTE_SW_WIRED) pmap->pm_stats.wired_count--; - if ((tl3 & PTE_REF) != 0) + if ((tl3 & PTE_A) != 0) vm_page_aflag_set(m, PGA_REFERENCED); /* @@ -1969,7 +1992,7 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) l2 = pmap_l1_to_l2(l1, sva); if (l2 == NULL) continue; - if ((pmap_load(l2) & PTE_TYPE_M) != (PTE_TYPE_PTR << PTE_TYPE_S)) + if ((pmap_load(l2) & PTE_RX) != 0) continue; if (va_next > eva) @@ -1981,7 +2004,7 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) l3 = pmap_load(l3p); if (pmap_l3_valid(l3)) { entry = pmap_load(l3p); - entry &= ~(1 << PTE_TYPE_S); + entry &= ~(PTE_W); pmap_load_store(l3p, entry); PTE_SYNC(l3p); /* XXX: Use pmap_invalidate_range */ @@ -2030,19 +2053,11 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, pa = VM_PAGE_TO_PHYS(m); pn = (pa / PAGE_SIZE); - new_l3 = PTE_VALID; - - if ((prot & VM_PROT_WRITE) == 0) { /* Read-only */ - if ((va >> 63) == 0) /* USER */ - new_l3 |= (PTE_TYPE_SURX << PTE_TYPE_S); - else /* KERNEL */ - new_l3 |= (PTE_TYPE_SRX << PTE_TYPE_S); - } else { - if ((va >> 63) == 0) /* USER */ - new_l3 |= (PTE_TYPE_SURWX << PTE_TYPE_S); - else /* KERNEL */ - new_l3 |= (PTE_TYPE_SRWX << PTE_TYPE_S); - } + new_l3 = PTE_V | PTE_R | PTE_X; + if (prot & VM_PROT_WRITE) + new_l3 |= PTE_W; + if ((va >> 63) == 0) + new_l3 |= PTE_U; new_l3 |= (pn << PTE_PPN0_S); if ((flags & PMAP_ENTER_WIRED) != 0) @@ -2086,7 +2101,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, l2_pn = (l2_pa / PAGE_SIZE); l1 = pmap_l1(pmap, va); - entry = (PTE_VALID | (PTE_TYPE_PTR << PTE_TYPE_S)); + entry = (PTE_V); entry |= (l2_pn << PTE_PPN0_S); pmap_load_store(l1, entry); pmap_distribute_l1(pmap, pmap_l1_index(va), entry); @@ -2107,7 +2122,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, l3_pa = VM_PAGE_TO_PHYS(l3_m); l3_pn = (l3_pa / PAGE_SIZE); - entry = (PTE_VALID | (PTE_TYPE_PTR << PTE_TYPE_S)); + entry = (PTE_V); entry |= (l3_pn << PTE_PPN0_S); pmap_load_store(l2, entry); PTE_SYNC(l2); @@ -2201,7 +2216,7 @@ validate: om = PHYS_TO_VM_PAGE(opa); if (pmap_page_dirty(orig_l3)) vm_page_dirty(om); - if ((orig_l3 & PTE_REF) != 0) + if ((orig_l3 & PTE_A) != 0) vm_page_aflag_set(om, PGA_REFERENCED); CHANGE_PV_LIST_LOCK_TO_PHYS(&lock, opa); pmap_pvh_free(&om->md, pmap, va); @@ -2388,7 +2403,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, pn = (pa / PAGE_SIZE); /* RISCVTODO: check permissions */ - entry = (PTE_VALID | (PTE_TYPE_SRWX << PTE_TYPE_S)); + entry = (PTE_V | PTE_RWX); entry |= (pn << PTE_PPN0_S); /* @@ -2831,12 +2846,12 @@ restart: mask = 0; value = 0; if (modified) { - mask |= PTE_DIRTY; - value |= PTE_DIRTY; + mask |= PTE_D; + value |= PTE_D; } if (accessed) { - mask |= PTE_REF; - value |= PTE_REF; + mask |= PTE_A; + value |= PTE_A; } #if 0 @@ -2968,11 +2983,11 @@ retry: oldl3 = pmap_load(l3); if (pmap_is_write(oldl3)) { - newl3 = oldl3 & ~(1 << PTE_TYPE_S); + newl3 = oldl3 & ~(PTE_W); if (!atomic_cmpset_long(l3, oldl3, newl3)) goto retry; /* TODO: use pmap_page_dirty(oldl3) ? */ - if ((oldl3 & PTE_REF) != 0) + if ((oldl3 & PTE_A) != 0) vm_page_dirty(m); pmap_invalidate_page(pmap, pv->pv_va); } @@ -3045,11 +3060,11 @@ retry: } l2 = pmap_l2(pmap, pv->pv_va); - KASSERT((pmap_load(l2) & PTE_TYPE_M) == (PTE_TYPE_PTR << PTE_TYPE_S), + KASSERT((pmap_load(l2) & PTE_RX) == 0, ("pmap_ts_referenced: found an invalid l2 table")); l3 = pmap_l2_to_l3(l2, pv->pv_va); - if ((pmap_load(l3) & PTE_REF) != 0) { + if ((pmap_load(l3) & PTE_A) != 0) { if (safe_to_clear_referenced(pmap, pmap_load(l3))) { /* * TODO: We don't handle the access flag @@ -3178,7 +3193,7 @@ pmap_activate(struct thread *td) 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)); + __asm __volatile("csrw sptbr, %0" :: "r"(td->td_pcb->pcb_l1addr >> PAGE_SHIFT)); pmap_invalidate_all(pmap); critical_exit(); diff --git a/sys/riscv/htif/htif_console.c b/sys/riscv/riscv/riscv_console.c index 200ad9e94244..d59ed59c18ae 100644 --- a/sys/riscv/htif/htif_console.c +++ b/sys/riscv/riscv/riscv_console.c @@ -47,17 +47,40 @@ __FBSDID("$FreeBSD$"); #include <sys/tty.h> #include <sys/bus.h> #include <sys/module.h> +#include <sys/rman.h> -#include <machine/bus.h> -#include <machine/trap.h> +#include <dev/ofw/openfirm.h> +#include <ddb/ddb.h> -#include "htif.h" +#include <vm/vm.h> +#include <vm/pmap.h> +#include <dev/fdt/fdt_common.h> #include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> -#include <ddb/ddb.h> +#include <machine/bus.h> +#include <machine/cpu.h> +#include <machine/intr.h> +#include <machine/asm.h> +#include <machine/trap.h> +#include <machine/vmparam.h> +#include <machine/sbi.h> -extern uint64_t console_intr; +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]; + void *ihl[1]; + device_t dev; +}; + +/* CN Console interface */ static tsw_outwakeup_t riscvtty_outwakeup; @@ -88,8 +111,6 @@ CONSOLE_DRIVER(riscv); #define MAX_BURST_LEN 1 #define QUEUE_SIZE 256 -#define CONSOLE_DEFAULT_ID 1ul -#define SPIN_IN_MACHINE_MODE 1 struct queue_entry { uint64_t data; @@ -102,65 +123,10 @@ struct queue_entry *entry_last; struct queue_entry *entry_served; static void -htif_putc(int c) -{ - uint64_t cmd; - - cmd = (HTIF_CMD_WRITE << HTIF_CMD_SHIFT); - cmd |= (CONSOLE_DEFAULT_ID << HTIF_DEV_ID_SHIFT); - cmd |= c; - -#ifdef SPIN_IN_MACHINE_MODE - machine_command(ECALL_HTIF_LOWPUTC, cmd); -#else - htif_command(cmd); -#endif - -} - -static uint8_t -htif_getc(void) -{ - uint64_t cmd; - uint8_t res; - - cmd = (HTIF_CMD_READ << HTIF_CMD_SHIFT); - cmd |= (CONSOLE_DEFAULT_ID << HTIF_DEV_ID_SHIFT); - - res = htif_command(cmd); - - return (res); -} - -static void riscv_putc(int c) { - uint64_t counter; - uint64_t *cc; - uint64_t val; - - val = 0; - counter = 0; - - cc = (uint64_t*)&console_intr; - *cc = 0; - - htif_putc(c); - -#ifndef SPIN_IN_MACHINE_MODE - /* Wait for an interrupt */ - __asm __volatile( - "li %0, 1\n" /* counter = 1 */ - "slli %0, %0, 12\n" /* counter <<= 12 */ - "1:" - "addi %0, %0, -1\n" /* counter -= 1 */ - "beqz %0, 2f\n" /* counter == 0 ? finish */ - "ld %1, 0(%2)\n" /* val = *cc */ - "beqz %1, 1b\n" /* val == 0 ? repeat */ - "2:" - : "=&r"(counter), "=&r"(val) : "r"(cc) - ); -#endif + + sbi_console_putchar(c); } #ifdef EARLY_PRINTF @@ -267,34 +233,23 @@ riscv_cnungrab(struct consdev *cp) static int riscv_cngetc(struct consdev *cp) { -#if defined(KDB) - uint64_t devcmd; - uint64_t entry; - uint64_t devid; -#endif uint8_t data; int ch; - htif_getc(); - #if defined(KDB) + /* + * RISCVTODO: BBL polls for console data on timer interrupt, + * but interrupts are turned off in KDB. + * So we currently do not have console in KDB. + */ if (kdb_active) { - entry = machine_command(ECALL_HTIF_GET_ENTRY, 0); - while (entry) { - devid = HTIF_DEV_ID(entry); - devcmd = HTIF_DEV_CMD(entry); - data = HTIF_DEV_DATA(entry); - - if (devid == CONSOLE_DEFAULT_ID && devcmd == 0) { - entry_last->data = data; - entry_last->used = 1; - entry_last = entry_last->next; - } else { - printf("Lost interrupt: devid %d\n", - devid); - } - - entry = machine_command(ECALL_HTIF_GET_ENTRY, 0); + ch = sbi_console_getchar(); + while (ch) { + entry_last->data = ch; + entry_last->used = 1; + entry_last = entry_last->next; + + ch = sbi_console_getchar(); } } #endif @@ -322,75 +277,83 @@ riscv_cnputc(struct consdev *cp, int c) riscv_putc(c); } -/* - * Bus interface. - */ +/* Bus interface */ -struct htif_console_softc { - device_t dev; - int running; - int intr_chan; - int cmd_done; - int curtag; - int index; -}; - -static void -htif_console_intr(void *arg, uint64_t entry) +static int +rcons_intr(void *arg) { - struct htif_console_softc *sc; - uint8_t devcmd; - uint64_t data; - - sc = arg; - - devcmd = HTIF_DEV_CMD(entry); - data = HTIF_DEV_DATA(entry); + int c; - if (devcmd == 0) { - entry_last->data = data; + 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 -htif_console_probe(device_t dev) +rcons_probe(device_t dev) { - return (0); + 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); } static int -htif_console_attach(device_t dev) +rcons_attach(device_t dev) { - struct htif_console_softc *sc; + struct rcons_softc *sc; + int error; sc = device_get_softc(dev); sc->dev = dev; - sc->index = htif_get_index(dev); - if (sc->index < 0) - return (EINVAL); + 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); + } - htif_setup_intr(sc->index, htif_console_intr, sc); + csr_set(sie, SIE_SSIE); + + bus_generic_attach(sc->dev); + + sbi_console_getchar(); return (0); } -static device_method_t htif_console_methods[] = { - DEVMETHOD(device_probe, htif_console_probe), - DEVMETHOD(device_attach, htif_console_attach), +static device_method_t rcons_methods[] = { + DEVMETHOD(device_probe, rcons_probe), + DEVMETHOD(device_attach, rcons_attach), + DEVMETHOD_END }; -static driver_t htif_console_driver = { - "htif_console", - htif_console_methods, - sizeof(struct htif_console_softc) +static driver_t rcons_driver = { + "rcons", + rcons_methods, + sizeof(struct rcons_softc) }; -static devclass_t htif_console_devclass; +static devclass_t rcons_devclass; -DRIVER_MODULE(htif_console, htif, htif_console_driver, - htif_console_devclass, 0, 0); +DRIVER_MODULE(rcons, simplebus, rcons_driver, rcons_devclass, 0, 0); diff --git a/sys/riscv/riscv/sbi.S b/sys/riscv/riscv/sbi.S new file mode 100644 index 000000000000..b5b2916e0f4f --- /dev/null +++ b/sys/riscv/riscv/sbi.S @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com> + * 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 <machine/asm.h> +__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 90461d8d0e7a..b5cced30d8f7 100644 --- a/sys/riscv/riscv/swtch.S +++ b/sys/riscv/riscv/swtch.S @@ -56,6 +56,7 @@ ENTRY(cpu_throw) /* Switch to the new pmap */ ld t0, PCB_L1ADDR(x13) + srli t0, t0, PAGE_SHIFT csrw sptbr, t0 /* TODO: Invalidate the TLB */ @@ -79,6 +80,7 @@ ENTRY(cpu_throw) ld s9, (PCB_S + 9 * 8)(x13) ld s10, (PCB_S + 10 * 8)(x13) ld s11, (PCB_S + 11 * 8)(x13) + ret .Lcpu_throw_panic_str: @@ -135,6 +137,7 @@ ENTRY(cpu_switch) /* Switch to the new pmap */ ld t0, PCB_L1ADDR(x13) + srli t0, t0, PAGE_SHIFT csrw sptbr, t0 /* TODO: Invalidate the TLB */ @@ -187,7 +190,7 @@ ENTRY(fork_trampoline) /* Restore sstatus */ ld t0, (TF_SSTATUS)(sp) /* Ensure interrupts disabled */ - li t1, ~SSTATUS_IE + li t1, ~SSTATUS_SIE and t0, t0, t1 csrw sstatus, t0 @@ -244,7 +247,7 @@ ENTRY(fork_trampoline) /* Load user stack */ ld sp, (TF_SP - TF_SIZE)(sp) - eret + sret END(fork_trampoline) ENTRY(savectx) diff --git a/sys/riscv/riscv/timer.c b/sys/riscv/riscv/timer.c index fbef1a142d44..0462e62b1aac 100644 --- a/sys/riscv/riscv/timer.c +++ b/sys/riscv/riscv/timer.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com> + * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com> * All rights reserved. * * Portions of this software were developed by SRI International and the @@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$"); #include <machine/intr.h> #include <machine/asm.h> #include <machine/trap.h> +#include <machine/sbi.h> #include <dev/fdt/fdt_common.h> #include <dev/ofw/openfirm.h> @@ -67,9 +68,19 @@ __FBSDID("$FreeBSD$"); #define DEFAULT_FREQ 1000000 +#define TIMER_COUNTS 0x00 +#define TIMER_MTIMECMP(cpu) (0x08 + (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[1]; - void *ihl[1]; + struct resource *res[2]; + bus_space_tag_t bst; + bus_space_handle_t bsh; + void *ih; uint32_t clkfreq; struct eventtimer et; }; @@ -77,6 +88,7 @@ struct riscv_tmr_softc { static struct riscv_tmr_softc *riscv_tmr_sc = NULL; static struct resource_spec timer_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, { SYS_RES_IRQ, 0, RF_ACTIVE }, { -1, 0 } }; @@ -93,30 +105,39 @@ static struct timecounter riscv_tmr_timecount = { }; static long -get_counts(void) +get_counts(struct riscv_tmr_softc *sc) { - return (csr_read(stime)); + return (READ8(sc, TIMER_COUNTS)); } static unsigned riscv_tmr_get_timecount(struct timecounter *tc) { + struct riscv_tmr_softc *sc; + + sc = tc->tc_priv; - return (get_counts()); + return (get_counts(sc)); } static int riscv_tmr_start(struct eventtimer *et, sbintime_t first, sbintime_t period) { struct riscv_tmr_softc *sc; - int counts; + uint64_t counts; + int cpu; sc = (struct riscv_tmr_softc *)et->et_priv; if (first != 0) { counts = ((uint32_t)et->et_frequency * first) >> 32; - machine_command(ECALL_MTIMECMP, counts); + counts += READ8(sc, TIMER_COUNTS); + cpu = PCPU_GET(cpuid); + WRITE8(sc, TIMER_MTIMECMP(cpu), counts); + csr_set(sie, SIE_STIE); + sbi_set_timer(counts); + return (0); } @@ -143,13 +164,7 @@ riscv_tmr_intr(void *arg) sc = (struct riscv_tmr_softc *)arg; - /* - * Clear interrupt pending bit. - * Note: SIP_STIP bit is not implemented in sip register - * in Spike simulator, so use machine command to clear - * interrupt pending bit in mip. - */ - machine_command(ECALL_CLEAR_PENDING, 0); + csr_clear(sip, SIP_STIP); if (sc->et.et_active) sc->et.et_event_cb(&sc->et, sc->et.et_arg); @@ -207,17 +222,22 @@ riscv_tmr_attach(device_t dev) return (ENXIO); } + /* Memory interface */ + sc->bst = rman_get_bustag(sc->res[0]); + sc->bsh = rman_get_bushandle(sc->res[0]); + riscv_tmr_sc = sc; /* Setup IRQs handler */ - error = bus_setup_intr(dev, sc->res[0], INTR_TYPE_CLK, - riscv_tmr_intr, NULL, sc, &sc->ihl[0]); + error = bus_setup_intr(dev, sc->res[1], INTR_TYPE_CLK, + riscv_tmr_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); sc->et.et_name = "RISC-V Eventtimer"; @@ -257,8 +277,8 @@ EARLY_DRIVER_MODULE(timer, ofwbus, riscv_tmr_fdt_driver, riscv_tmr_fdt_devclass, void DELAY(int usec) { - int32_t counts, counts_per_usec; - uint32_t first, last; + int64_t counts, counts_per_usec; + uint64_t first, last; /* * Check the timers are setup, if not just @@ -289,11 +309,11 @@ DELAY(int usec) else counts = usec * counts_per_usec; - first = get_counts(); + first = get_counts(riscv_tmr_sc); while (counts > 0) { - last = get_counts(); - counts -= (int32_t)(last - first); + last = get_counts(riscv_tmr_sc); + counts -= (int64_t)(last - first); first = last; } } diff --git a/sys/riscv/riscv/trap.c b/sys/riscv/riscv/trap.c index 22d27f41e592..97d9a2c1efdd 100644 --- a/sys/riscv/riscv/trap.c +++ b/sys/riscv/riscv/trap.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com> + * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com> * All rights reserved. * * Portions of this software were developed by SRI International and the @@ -211,7 +211,7 @@ data_abort(struct trapframe *frame, int lower) va = trunc_page(sbadaddr); - if (frame->tf_scause == EXCP_STORE_ACCESS_FAULT) { + if (frame->tf_scause == EXCP_FAULT_STORE) { ftype = (VM_PROT_READ | VM_PROT_WRITE); } else { ftype = (VM_PROT_READ); @@ -269,6 +269,12 @@ void do_trap_supervisor(struct trapframe *frame) { uint64_t exception; + uint64_t sstatus; + + /* Ensure we came from supervisor mode, interrupts disabled */ + __asm __volatile("csrr %0, sstatus" : "=&r" (sstatus)); + KASSERT((sstatus & (SSTATUS_SPP | SSTATUS_SIE)) == SSTATUS_SPP, + ("We must came from S mode with interrupts disabled")); exception = (frame->tf_scause & EXCP_MASK); if (frame->tf_scause & EXCP_INTR) { @@ -286,12 +292,12 @@ do_trap_supervisor(struct trapframe *frame) curthread, frame->tf_sepc, frame); switch(exception) { - case EXCP_LOAD_ACCESS_FAULT: - case EXCP_STORE_ACCESS_FAULT: - case EXCP_INSTR_ACCESS_FAULT: + case EXCP_FAULT_LOAD: + case EXCP_FAULT_STORE: + case EXCP_FAULT_FETCH: data_abort(frame, 0); break; - case EXCP_INSTR_BREAKPOINT: + case EXCP_BREAKPOINT: #ifdef KDTRACE_HOOKS if (dtrace_invop_jump_addr != 0) { dtrace_invop_jump_addr(frame); @@ -305,7 +311,7 @@ do_trap_supervisor(struct trapframe *frame) panic("No debugger in kernel.\n"); #endif break; - case EXCP_INSTR_ILLEGAL: + case EXCP_ILLEGAL_INSTRUCTION: dump_regs(frame); panic("Illegal instruction at 0x%016lx\n", frame->tf_sepc); break; @@ -321,10 +327,16 @@ do_trap_user(struct trapframe *frame) { uint64_t exception; struct thread *td; + uint64_t sstatus; td = curthread; td->td_frame = frame; + /* Ensure we came from usermode, interrupts disabled */ + __asm __volatile("csrr %0, sstatus" : "=&r" (sstatus)); + KASSERT((sstatus & (SSTATUS_SPP | SSTATUS_SIE)) == 0, + ("We must came from U mode with interrupts disabled")); + exception = (frame->tf_scause & EXCP_MASK); if (frame->tf_scause & EXCP_INTR) { /* Interrupt */ @@ -336,20 +348,20 @@ do_trap_user(struct trapframe *frame) curthread, frame->tf_sepc, frame); switch(exception) { - case EXCP_LOAD_ACCESS_FAULT: - case EXCP_STORE_ACCESS_FAULT: - case EXCP_INSTR_ACCESS_FAULT: + case EXCP_FAULT_LOAD: + case EXCP_FAULT_STORE: + case EXCP_FAULT_FETCH: data_abort(frame, 1); break; - case EXCP_UMODE_ENV_CALL: + case EXCP_USER_ECALL: frame->tf_sepc += 4; /* Next instruction */ svc_handler(frame); break; - case EXCP_INSTR_ILLEGAL: + case EXCP_ILLEGAL_INSTRUCTION: call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)frame->tf_sepc); userret(td, frame); break; - case EXCP_INSTR_BREAKPOINT: + case EXCP_BREAKPOINT: call_trapsignal(td, SIGTRAP, TRAP_BRKPT, (void *)frame->tf_sepc); userret(td, frame); break; diff --git a/sys/riscv/riscv/vm_machdep.c b/sys/riscv/riscv/vm_machdep.c index 833482c73f65..d2d4c6e3d3ec 100644 --- a/sys/riscv/riscv/vm_machdep.c +++ b/sys/riscv/riscv/vm_machdep.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com> + * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com> * All rights reserved. * * Portions of this software were developed by SRI International and the @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include <machine/cpu.h> #include <machine/pcb.h> #include <machine/frame.h> +#include <machine/sbi.h> /* * Finish a fork operation, with process p2 nearly set up. @@ -86,7 +87,8 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) /* Arguments for child */ tf->tf_a[0] = 0; tf->tf_a[1] = 0; - tf->tf_sstatus = SSTATUS_PIE; + tf->tf_sstatus = (SSTATUS_SPIE); + tf->tf_sstatus |= (MSTATUS_PRV_U << MSTATUS_SPP_SHIFT); td2->td_frame = tf; @@ -98,16 +100,16 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) /* Setup to release spin count in fork_exit(). */ td2->td_md.md_spinlock_count = 1; - td2->td_md.md_saved_sstatus_ie = 1; + td2->td_md.md_saved_sstatus_ie = (SSTATUS_SIE); } void cpu_reset(void) { - printf("cpu_reset"); - while(1) - __asm volatile("wfi" ::: "memory"); + sbi_shutdown(); + + while(1); } void @@ -166,7 +168,7 @@ cpu_copy_thread(struct thread *td, struct thread *td0) /* Setup to release spin count in fork_exit(). */ td->td_md.md_spinlock_count = 1; - td->td_md.md_saved_sstatus_ie = 1; + td->td_md.md_saved_sstatus_ie = (SSTATUS_SIE); } /* |