aboutsummaryrefslogtreecommitdiff
path: root/sys/riscv
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-08-16 20:19:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-08-16 20:19:05 +0000
commit27067774dce3388702a4cf744d7096c6fb71b688 (patch)
tree56300949abd050b3cd2e23d29210d2a567bc8aec /sys/riscv
parent44be0a8ea517cbe7a9140bca20e1e93228ac0a04 (diff)
parent915a263ea24ab051bb57674a4d6f5ffe4ef0d5b5 (diff)
Merge ^/head r303250 through r304235.
Notes
Notes: svn path=/projects/clang390-import/; revision=304236
Diffstat (limited to 'sys/riscv')
-rw-r--r--sys/riscv/conf/GENERIC5
-rw-r--r--sys/riscv/conf/QEMU4
-rw-r--r--sys/riscv/conf/ROCKET4
-rw-r--r--sys/riscv/conf/SPIKE4
-rw-r--r--sys/riscv/htif/htif.c283
-rw-r--r--sys/riscv/htif/htif_block.c297
-rw-r--r--sys/riscv/include/cpu.h11
-rw-r--r--sys/riscv/include/cpufunc.h26
-rw-r--r--sys/riscv/include/db_machdep.h2
-rw-r--r--sys/riscv/include/intr.h18
-rw-r--r--sys/riscv/include/pcpu.h3
-rw-r--r--sys/riscv/include/pte.h37
-rw-r--r--sys/riscv/include/riscvreg.h139
-rw-r--r--sys/riscv/include/sbi.h (renamed from sys/riscv/htif/htif.h)76
-rw-r--r--sys/riscv/include/vmparam.h23
-rw-r--r--sys/riscv/riscv/exception.S412
-rw-r--r--sys/riscv/riscv/identcpu.c40
-rw-r--r--sys/riscv/riscv/intr_machdep.c36
-rw-r--r--sys/riscv/riscv/locore.S278
-rw-r--r--sys/riscv/riscv/machdep.c27
-rw-r--r--sys/riscv/riscv/mp_machdep.c12
-rw-r--r--sys/riscv/riscv/pmap.c149
-rw-r--r--sys/riscv/riscv/riscv_console.c (renamed from sys/riscv/htif/htif_console.c)221
-rw-r--r--sys/riscv/riscv/sbi.S52
-rw-r--r--sys/riscv/riscv/swtch.S7
-rw-r--r--sys/riscv/riscv/timer.c64
-rw-r--r--sys/riscv/riscv/trap.c38
-rw-r--r--sys/riscv/riscv/vm_machdep.c16
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);
}
/*