o Remove operation in machine mode.
Machine privilege level was specially designed to use in vendor's firmware or bootloader. We have implemented operation in machine mode in FreeBSD as part of understanding RISC-V ISA, but it is time to remove it. We now use BBL (Berkeley Boot Loader) -- standard RISC-V firmware, which provides operation in machine mode for us. We now use standard SBI calls to machine mode, instead of handmade 'syscalls'. o Remove HTIF bus. HTIF bus is now legacy and no longer exists in RISC-V specification. HTIF code still exists in Spike simulator, but BBL do not provide raw interface to it. Memory disk is only choice for now to have multiuser booted in Spike, until Spike has implemented more devices (e.g. Virtio, etc). Sponsored by: DARPA, AFRL Sponsored by: HEIF5
This commit is contained in:
parent
4cf6e978b4
commit
5f8228b2f3
@ -72,15 +72,11 @@
|
||||
clock-frequency = < 400000000 >;
|
||||
};
|
||||
|
||||
htif0: htif@0 {
|
||||
compatible = "riscv,htif";
|
||||
interrupts = < 0 >;
|
||||
console0: console@0 {
|
||||
compatible = "riscv,console";
|
||||
status = "okay";
|
||||
interrupts = < 1 >;
|
||||
interrupt-parent = < &pic0 >;
|
||||
|
||||
console0: console@0 {
|
||||
compatible = "htif,console";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -83,15 +83,11 @@
|
||||
clock-frequency = < 1000000 >;
|
||||
};
|
||||
|
||||
htif0: htif@0 {
|
||||
compatible = "riscv,htif";
|
||||
interrupts = < 0 >;
|
||||
console0: console@0 {
|
||||
compatible = "riscv,console";
|
||||
status = "okay";
|
||||
interrupts = < 1 >;
|
||||
interrupt-parent = < &pic0 >;
|
||||
|
||||
console0: console@0 {
|
||||
compatible = "htif,console";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -65,6 +65,10 @@
|
||||
};
|
||||
|
||||
memory {
|
||||
/*
|
||||
* This is not used currently.
|
||||
* We take information from sbi_query_memory.
|
||||
*/
|
||||
device_type = "memory";
|
||||
reg = <0x80000000 0x40000000>; /* 1GB at 0x80000000 */
|
||||
};
|
||||
@ -90,15 +94,11 @@
|
||||
clock-frequency = < 1000000 >;
|
||||
};
|
||||
|
||||
htif0: htif@0 {
|
||||
compatible = "riscv,htif";
|
||||
console0: console@0 {
|
||||
compatible = "riscv,console";
|
||||
status = "okay";
|
||||
interrupts = < 1 >;
|
||||
interrupt-parent = < &pic0 >;
|
||||
|
||||
console0: console@0 {
|
||||
compatible = "htif,console";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -19,9 +19,6 @@ libkern/flsl.c standard
|
||||
libkern/flsll.c standard
|
||||
libkern/memmove.c standard
|
||||
libkern/memset.c standard
|
||||
riscv/htif/htif.c optional htif
|
||||
riscv/htif/htif_block.c optional htif
|
||||
riscv/htif/htif_console.c optional htif
|
||||
riscv/riscv/autoconf.c standard
|
||||
riscv/riscv/bcopy.c standard
|
||||
riscv/riscv/bus_machdep.c standard
|
||||
@ -36,6 +33,7 @@ riscv/riscv/db_interface.c optional ddb
|
||||
riscv/riscv/db_trace.c optional ddb
|
||||
riscv/riscv/dump_machdep.c standard
|
||||
riscv/riscv/elf_machdep.c standard
|
||||
riscv/riscv/exception.S standard
|
||||
riscv/riscv/intr_machdep.c standard
|
||||
riscv/riscv/in_cksum.c optional inet | inet6
|
||||
riscv/riscv/identcpu.c standard
|
||||
@ -47,6 +45,8 @@ riscv/riscv/mem.c standard
|
||||
riscv/riscv/nexus.c standard
|
||||
riscv/riscv/ofw_machdep.c optional fdt
|
||||
riscv/riscv/pmap.c standard
|
||||
riscv/riscv/riscv_console.c optional rcons
|
||||
riscv/riscv/sbi.S standard
|
||||
riscv/riscv/stack_machdep.c optional ddb | stack
|
||||
riscv/riscv/support.S standard
|
||||
riscv/riscv/swtch.S standard
|
||||
|
@ -6,7 +6,7 @@ SEARCH_DIR(/usr/lib);
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
. = kernbase + 0x80000000 /* KERNENTRY */;
|
||||
. = kernbase;
|
||||
.text : AT(ADDR(.text) - kernbase)
|
||||
{
|
||||
*(.text)
|
||||
|
@ -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\"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,278 +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);
|
||||
|
||||
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);
|
@ -1,299 +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 resp;
|
||||
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;
|
||||
resp = htif_command(cmd);
|
||||
htif_blk_intr(sc, resp);
|
||||
|
||||
/* 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);
|
@ -81,21 +81,6 @@ intr_enable(void)
|
||||
);
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -37,19 +37,6 @@
|
||||
#ifndef _MACHINE_RISCVREG_H_
|
||||
#define _MACHINE_RISCVREG_H_
|
||||
|
||||
/* Machine mode requests */
|
||||
#define ECALL_MTIMECMP 0x01
|
||||
#define ECALL_HTIF_GET_ENTRY 0x02
|
||||
#define ECALL_MCPUID_GET 0x03
|
||||
#define ECALL_MIMPID_GET 0x04
|
||||
#define ECALL_SEND_IPI 0x05
|
||||
#define ECALL_CLEAR_IPI 0x06
|
||||
#define ECALL_MIE_SET 0x07
|
||||
#define ECALL_IO_IRQ_MASK 0x08
|
||||
#define ECALL_HTIF_CMD 0x09
|
||||
#define ECALL_HTIF_CMD_REQ 0x0a
|
||||
#define ECALL_HTIF_CMD_RESP 0x0b
|
||||
|
||||
#define EXCP_SHIFT 0
|
||||
#define EXCP_MASK (0xf << EXCP_SHIFT)
|
||||
#define EXCP_MISALIGNED_FETCH 0
|
||||
@ -65,9 +52,6 @@
|
||||
#define EXCP_HYPERVISOR_ECALL 10
|
||||
#define EXCP_MACHINE_ECALL 11
|
||||
#define EXCP_INTR (1ul << 63)
|
||||
#define EXCP_INTR_SOFTWARE 0
|
||||
#define EXCP_INTR_TIMER 1
|
||||
#define EXCP_INTR_HTIF 2
|
||||
|
||||
#define SSTATUS_UIE (1 << 0)
|
||||
#define SSTATUS_SIE (1 << 1)
|
||||
|
@ -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_ */
|
@ -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 (0x80000000)
|
||||
#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 */
|
||||
|
||||
|
@ -235,388 +235,3 @@ ENTRY(cpu_exception_handler_user)
|
||||
csrrw sp, sscratch, sp
|
||||
sret
|
||||
END(cpu_exception_handler_user)
|
||||
|
||||
/*
|
||||
* Trap handlers
|
||||
*/
|
||||
.text
|
||||
bad_trap:
|
||||
j bad_trap
|
||||
|
||||
machine_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)
|
||||
|
||||
csrr t3, mstatus /* Required for debug */
|
||||
csrr t0, mcause
|
||||
bltz t0, machine_interrupt
|
||||
|
||||
li t1, EXCP_SUPERVISOR_ECALL
|
||||
beq t0, t1, supervisor_call
|
||||
4:
|
||||
/* NOT REACHED */
|
||||
j 4b
|
||||
|
||||
machine_interrupt:
|
||||
/* Type of interrupt ? */
|
||||
csrr t0, mcause
|
||||
andi t0, t0, EXCP_MASK
|
||||
#if 0
|
||||
/* lowRISC TODO */
|
||||
li t1, 4
|
||||
beq t1, t0, io_interrupt /* lowRISC only */
|
||||
#endif
|
||||
li t1, 1
|
||||
beq t1, t0, supervisor_software_interrupt
|
||||
li t1, 3
|
||||
beq t1, t0, machine_software_interrupt
|
||||
li t1, 5
|
||||
beq t1, t0, supervisor_timer_interrupt
|
||||
li t1, 7
|
||||
beq t1, t0, machine_timer_interrupt
|
||||
|
||||
/* NOT REACHED */
|
||||
1:
|
||||
j 1b
|
||||
|
||||
#if 0
|
||||
/* lowRISC TODO */
|
||||
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
|
||||
#endif
|
||||
|
||||
supervisor_software_interrupt:
|
||||
1:
|
||||
/* Nothing here as we are using mideleg feature */
|
||||
j 1b
|
||||
|
||||
machine_software_interrupt:
|
||||
/* Clear IPI */
|
||||
li t0, 0x40001000
|
||||
csrr t2, mhartid
|
||||
li t3, 0x1000
|
||||
mul t2, t2, t3
|
||||
add t0, t0, t2
|
||||
li t2, 0
|
||||
sd t2, 0(t0)
|
||||
|
||||
/* Clear machine software pending bit */
|
||||
li t0, MIP_MSIP
|
||||
csrc mip, t0
|
||||
|
||||
/* Post supervisor software interrupt */
|
||||
li t0, MIP_SSIP
|
||||
csrs mip, t0
|
||||
|
||||
j exit
|
||||
|
||||
supervisor_timer_interrupt:
|
||||
1:
|
||||
/* Nothing here as we are using mideleg feature */
|
||||
j 1b
|
||||
|
||||
machine_timer_interrupt:
|
||||
/* Disable machine timer interrupts */
|
||||
li t0, MIE_MTIE
|
||||
csrc mie, t0
|
||||
|
||||
/* Clear machine timer interrupt pending */
|
||||
li t0, MIP_MTIP
|
||||
csrc mip, t0
|
||||
|
||||
/* Post supervisor timer interrupt */
|
||||
li t0, MIP_STIP
|
||||
csrs mip, t0
|
||||
|
||||
/*
|
||||
* Check for HTIF interrupts.
|
||||
* The only interrupt expected here is key press.
|
||||
*/
|
||||
la t0, htif_lock
|
||||
li t2, 1
|
||||
amoswap.d t3, t2, 0(t0)
|
||||
bnez t3, 5f /* Another operation in progress, give up */
|
||||
|
||||
/* We have lock */
|
||||
la t1, fromhost
|
||||
ld t5, 0(t1)
|
||||
beqz t5, 4f
|
||||
|
||||
/* Console GET intr ? */
|
||||
mv t1, t5
|
||||
li t0, 0x100
|
||||
srli t1, t1, 48
|
||||
beq t1, t0, 2f
|
||||
1:
|
||||
/* There is no interrupts except keypress */
|
||||
j 1b
|
||||
|
||||
2:
|
||||
/* Save entry */
|
||||
la t0, htif_ring
|
||||
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
|
||||
|
||||
3:
|
||||
la t1, fromhost
|
||||
li t5, 0
|
||||
sd t5, 0(t1)
|
||||
|
||||
4:
|
||||
/* Release lock */
|
||||
la t0, htif_lock
|
||||
li t2, 0
|
||||
amoswap.d t3, t2, 0(t0)
|
||||
|
||||
5:
|
||||
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_CMD_REQ
|
||||
beq t5, t4, htif_cmd_req
|
||||
li t4, ECALL_HTIF_CMD_RESP
|
||||
beq t5, t4, htif_cmd_resp
|
||||
li t4, ECALL_HTIF_GET_ENTRY
|
||||
beq t5, t4, htif_get_entry
|
||||
li t4, ECALL_MTIMECMP
|
||||
beq t5, t4, set_mtimecmp
|
||||
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_MIE_SET
|
||||
beq t5, t4, mie_set
|
||||
#if 0
|
||||
/* lowRISC TODO */
|
||||
li t4, ECALL_IO_IRQ_MASK
|
||||
beq t5, t4, io_irq_mask
|
||||
#endif
|
||||
j exit_next_instr
|
||||
|
||||
#if 0
|
||||
/* lowRISC TODO */
|
||||
io_irq_mask:
|
||||
csrw CSR_IO_IRQ, t6
|
||||
j exit_next_instr
|
||||
#endif
|
||||
|
||||
mie_set:
|
||||
csrs mie, t6
|
||||
j exit_next_instr
|
||||
|
||||
mcpuid_get:
|
||||
csrr t6, misa
|
||||
j exit_next_instr
|
||||
|
||||
mimpid_get:
|
||||
csrr t6, mimpid
|
||||
j exit_next_instr
|
||||
|
||||
send_ipi:
|
||||
/* CPU ipi MMIO register in t6 */
|
||||
mv t0, t6
|
||||
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
|
||||
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
|
||||
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_resp:
|
||||
la t0, htif_lock
|
||||
li t2, 1
|
||||
1:
|
||||
amoswap.d t3, t2, 0(t0)
|
||||
bnez t3, 1b
|
||||
|
||||
/* We have lock. Read for data */
|
||||
la t4, fromhost
|
||||
ld t6, 0(t4)
|
||||
beqz t6, 2f
|
||||
|
||||
/* Clear event */
|
||||
li t5, 0
|
||||
sd t5, 0(t4)
|
||||
|
||||
2:
|
||||
/* Release lock */
|
||||
la t0, htif_lock
|
||||
li t2, 0
|
||||
amoswap.d t3, t2, 0(t0)
|
||||
|
||||
j exit_next_instr
|
||||
|
||||
htif_cmd_req:
|
||||
la t0, htif_lock
|
||||
li t2, 1
|
||||
1:
|
||||
amoswap.d t3, t2, 0(t0)
|
||||
bnez t3, 1b
|
||||
|
||||
/* We have lock. Store new request */
|
||||
la t4, tohost
|
||||
sd t6, 0(t4)
|
||||
|
||||
/* Release lock */
|
||||
la t0, htif_lock
|
||||
li t2, 0
|
||||
amoswap.d t3, t2, 0(t0)
|
||||
|
||||
j exit_next_instr
|
||||
|
||||
htif_cmd:
|
||||
la t0, htif_lock
|
||||
li t2, 1
|
||||
1:
|
||||
amoswap.d t3, t2, 0(t0)
|
||||
bnez t3, 1b
|
||||
|
||||
mv t3, t6
|
||||
|
||||
/* We have lock. Store new request */
|
||||
la t4, tohost
|
||||
sd t6, 0(t4)
|
||||
2:
|
||||
/* Poll for result */
|
||||
la t4, fromhost
|
||||
ld t6, 0(t4)
|
||||
beqz t6, 2b
|
||||
|
||||
/* Check for unexpected event */
|
||||
srli t0, t6, 48
|
||||
srli t2, t3, 48
|
||||
beq t2, t0, 3f
|
||||
|
||||
/*
|
||||
* We have something unexpected (e.g. keyboard keypress)
|
||||
* Save entry.
|
||||
*/
|
||||
la t0, htif_ring
|
||||
li t4, (HTIF_RING_SIZE)
|
||||
add t0, t0, t4 /* t0 == htif_ring_cursor */
|
||||
|
||||
ld t2, 0(t0) /* load ptr to cursor */
|
||||
sd t6, 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
|
||||
|
||||
/* Clear and look for response again */
|
||||
la t2, fromhost
|
||||
li t5, 0
|
||||
sd t5, 0(t2)
|
||||
j 2b
|
||||
|
||||
3:
|
||||
la t2, fromhost
|
||||
li t5, 0
|
||||
sd t5, 0(t2)
|
||||
|
||||
/* Release lock */
|
||||
la t0, htif_lock
|
||||
li t2, 0
|
||||
amoswap.d t3, t2, 0(t0)
|
||||
|
||||
j exit_next_instr
|
||||
|
||||
set_mtimecmp:
|
||||
/* Enable interrupts */
|
||||
li t0, (MIE_MTIE | MIE_STIE)
|
||||
csrs mie, 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
|
||||
mret
|
||||
|
||||
exit_mrts:
|
||||
j exit_mrts
|
||||
|
@ -57,7 +57,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/intr.h>
|
||||
|
||||
ASSYM(KERNBASE, KERNBASE);
|
||||
ASSYM(KERNENTRY, KERNENTRY);
|
||||
ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS);
|
||||
ASSYM(VM_MAX_KERNEL_ADDRESS, VM_MAX_KERNEL_ADDRESS);
|
||||
ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
|
||||
|
@ -101,8 +101,9 @@ identify_cpu(void)
|
||||
|
||||
cpu_partsp = NULL;
|
||||
|
||||
mimpid = machine_command(ECALL_MIMPID_GET, 0);
|
||||
misa = machine_command(ECALL_MCPUID_GET, 0);
|
||||
/* TODO: can we get mimpid and misa somewhere ? */
|
||||
mimpid = 0;
|
||||
misa = 0;
|
||||
|
||||
cpu = PCPU_GET(cpuid);
|
||||
|
||||
|
@ -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>
|
||||
@ -267,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__);
|
||||
}
|
||||
|
@ -43,118 +43,47 @@
|
||||
#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:
|
||||
*
|
||||
* 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
|
||||
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:
|
||||
/* Vectors */
|
||||
j _start /* reset */
|
||||
j bad_trap /* NMI (non-maskable interrupt) */
|
||||
j machine_trap
|
||||
|
||||
/* Reset vector */
|
||||
.text
|
||||
.globl _start
|
||||
_start:
|
||||
/* Setup machine trap vector */
|
||||
la t0, machine_trap
|
||||
csrw mtvec, t0
|
||||
|
||||
/* Delegate interrupts to supervisor mode */
|
||||
li t0, (MIP_SSIP | MIP_STIP | MIP_SEIP)
|
||||
csrw mideleg, t0
|
||||
|
||||
/* Delegate exceptions to supervisor mode */
|
||||
li t0, (1 << EXCP_MISALIGNED_FETCH) | \
|
||||
(1 << EXCP_FAULT_FETCH) | \
|
||||
(1 << EXCP_ILLEGAL_INSTRUCTION) | \
|
||||
(1 << EXCP_FAULT_LOAD) | \
|
||||
(1 << EXCP_FAULT_STORE) | \
|
||||
(1 << EXCP_BREAKPOINT) | \
|
||||
(1 << EXCP_USER_ECALL)
|
||||
csrw medeleg, t0
|
||||
|
||||
/* Setup supervisor trap vector */
|
||||
la t0, cpu_exception_handler
|
||||
li t1, KERNBASE
|
||||
add t0, t0, t1
|
||||
csrw stvec, t0
|
||||
|
||||
/* Direct secondary cores to mpentry */
|
||||
csrr a0, mhartid
|
||||
bnez a0, mpentry
|
||||
|
||||
li t1, 0
|
||||
la t0, tohost
|
||||
sd t1, 0(t0)
|
||||
la t0, fromhost
|
||||
sd t1, 0(t0)
|
||||
|
||||
/* Build event queue for current core */
|
||||
build_ring
|
||||
|
||||
/* Setup machine-mode stack for CPU 0 */
|
||||
la t0, hardstack_end
|
||||
csrw mscratch, 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
|
||||
|
||||
/* Page tables */
|
||||
/* 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
|
||||
*/
|
||||
|
||||
/* 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)
|
||||
@ -170,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 + KERNENTRY)
|
||||
li a5, KERNBASE
|
||||
srli a5, a5, L1_SHIFT /* >> L1_SHIFT */
|
||||
andi a5, a5, 0x1ff /* & 0x1ff */
|
||||
li t4, PTE_V
|
||||
slli t5, s2, PTE_PPN0_S /* (s2 << PTE_PPN0_S) */
|
||||
or t6, t4, t5
|
||||
|
||||
/* Store single level1 PTE entry to position */
|
||||
/* Store L1 PTE entry to position */
|
||||
li a6, PTE_SIZE
|
||||
mulw a5, a5, a6
|
||||
add t0, s1, a5
|
||||
@ -190,8 +174,7 @@ _start:
|
||||
|
||||
/* Level 2 superpages (512 x 2MiB) */
|
||||
la s1, pagetable_l2
|
||||
li t4, KERNENTRY
|
||||
srli t4, t4, 21 /* Div by 2 MiB */
|
||||
srli t4, s6, 21 /* Div physmem base by 2 MiB */
|
||||
li t2, 512 /* Build 512 entries */
|
||||
add t3, t4, t2
|
||||
li t5, 0
|
||||
@ -206,32 +189,13 @@ _start:
|
||||
bltu t4, t3, 2b
|
||||
|
||||
/* Set page tables base register */
|
||||
la s1, pagetable_l1
|
||||
srli s1, s1, PAGE_SHIFT
|
||||
csrw sptbr, s1
|
||||
la s2, pagetable_l1
|
||||
li t0, KERNBASE
|
||||
sub s2, s2, t0
|
||||
add s2, s2, s6
|
||||
srli s2, s2, PAGE_SHIFT
|
||||
csrw sptbr, s2
|
||||
|
||||
/* Page tables END */
|
||||
|
||||
/* Enter supervisor mode */
|
||||
li s0, ((MSTATUS_VM_SV39 << MSTATUS_VM_SHIFT) | \
|
||||
(MSTATUS_PRV_S << MSTATUS_MPP_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
|
||||
mret
|
||||
|
||||
.Lmmu_on:
|
||||
/* Initialize stack pointer */
|
||||
la s3, initstack_end
|
||||
mv sp, s3
|
||||
@ -247,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 */
|
||||
|
||||
@ -260,19 +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)
|
||||
htif_lock:
|
||||
.space (8)
|
||||
tohost:
|
||||
.space (8)
|
||||
fromhost:
|
||||
.space (8)
|
||||
|
||||
ENTRY(sigcode)
|
||||
mv a0, sp
|
||||
@ -305,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:
|
||||
@ -321,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)
|
||||
/*
|
||||
@ -340,44 +300,12 @@ ENTRY(mpentry)
|
||||
beqz t1, 1b
|
||||
|
||||
/* Set page tables base register */
|
||||
la t0, pagetable_l1
|
||||
srli t0, t0, PAGE_SHIFT
|
||||
csrw sptbr, t0
|
||||
|
||||
/* Configure mstatus */
|
||||
li s0, ((MSTATUS_VM_SV39 << MSTATUS_VM_SHIFT) | \
|
||||
(MSTATUS_PRV_S << MSTATUS_MPP_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
|
||||
mret
|
||||
|
||||
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
|
||||
@ -388,5 +316,3 @@ mp_virtdone:
|
||||
call init_secondary
|
||||
END(mpentry)
|
||||
#endif
|
||||
|
||||
#include "exception.S"
|
||||
|
@ -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;
|
||||
|
||||
@ -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);
|
||||
@ -755,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];
|
||||
@ -778,14 +785,15 @@ initriscv(struct riscv_bootparams *rvbp)
|
||||
|
||||
/* 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();
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
@ -458,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);
|
||||
@ -466,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;
|
||||
@ -475,19 +487,12 @@ pmap_bootstrap_dmap(vm_offset_t l1pt, vm_paddr_t kernstart)
|
||||
pt_entry_t entry;
|
||||
pn_t pn;
|
||||
|
||||
/*
|
||||
* Initialize DMAP starting from zero physical address.
|
||||
* TODO: remove this once machine-mode code splitted out.
|
||||
*/
|
||||
kernstart = 0;
|
||||
printf("%s: l1pt 0x%016lx kernstart 0x%016lx\n", __func__, l1pt, kernstart);
|
||||
|
||||
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"));
|
||||
|
||||
@ -498,6 +503,10 @@ pmap_bootstrap_dmap(vm_offset_t l1pt, vm_paddr_t kernstart)
|
||||
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();
|
||||
}
|
||||
@ -552,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;
|
||||
@ -574,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,
|
||||
@ -585,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;
|
||||
|
@ -47,16 +47,41 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/tty.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/trap.h>
|
||||
|
||||
#include "htif.h"
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <dev/ofw/openfirm.h>
|
||||
|
||||
#include <ddb/ddb.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 <machine/sbi.h>
|
||||
|
||||
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;
|
||||
|
||||
static struct ttydevsw riscv_ttydevsw = {
|
||||
@ -86,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,13 +125,8 @@ struct queue_entry *entry_served;
|
||||
static void
|
||||
riscv_putc(int c)
|
||||
{
|
||||
uint64_t cmd;
|
||||
|
||||
cmd = (HTIF_CMD_WRITE << HTIF_CMD_SHIFT);
|
||||
cmd |= (CONSOLE_DEFAULT_ID << HTIF_DEV_ID_SHIFT);
|
||||
cmd |= c;
|
||||
|
||||
machine_command(ECALL_HTIF_CMD, cmd);
|
||||
sbi_console_putchar(c);
|
||||
}
|
||||
|
||||
#ifdef EARLY_PRINTF
|
||||
@ -215,39 +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
|
||||
uint64_t cmd;
|
||||
uint8_t data;
|
||||
int ch;
|
||||
|
||||
cmd = (HTIF_CMD_READ << HTIF_CMD_SHIFT);
|
||||
cmd |= (CONSOLE_DEFAULT_ID << HTIF_DEV_ID_SHIFT);
|
||||
|
||||
machine_command(ECALL_HTIF_CMD_REQ, cmd);
|
||||
|
||||
#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) {
|
||||
ch = sbi_console_getchar();
|
||||
while (ch) {
|
||||
entry_last->data = ch;
|
||||
entry_last->used = 1;
|
||||
entry_last = entry_last->next;
|
||||
|
||||
entry = machine_command(ECALL_HTIF_CMD_RESP, 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_CMD_RESP, 0);
|
||||
ch = sbi_console_getchar();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -275,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;
|
||||
int c;
|
||||
|
||||
sc = arg;
|
||||
|
||||
devcmd = HTIF_DEV_CMD(entry);
|
||||
data = HTIF_DEV_DATA(entry);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
htif_setup_intr(sc->index, htif_console_intr, sc);
|
||||
/* Setup IRQs handler */
|
||||
error = bus_setup_intr(dev, sc->res[0], INTR_TYPE_CLK,
|
||||
rcons_intr, NULL, sc, &sc->ihl[0]);
|
||||
if (error) {
|
||||
device_printf(dev, "Unable to alloc int resource.\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
csr_set(sie, SIE_SSIE);
|
||||
|
||||
bus_generic_attach(sc->dev);
|
||||
|
||||
sbi_console_getchar();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
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);
|
52
sys/riscv/riscv/sbi.S
Normal file
52
sys/riscv/riscv/sbi.S
Normal file
@ -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
|
@ -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>
|
||||
@ -135,7 +136,7 @@ riscv_tmr_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
cpu = PCPU_GET(cpuid);
|
||||
WRITE8(sc, TIMER_MTIMECMP(cpu), counts);
|
||||
csr_set(sie, SIE_STIE);
|
||||
machine_command(ECALL_MTIMECMP, counts);
|
||||
sbi_set_timer(counts);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -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.
|
||||
@ -106,9 +107,9 @@ void
|
||||
cpu_reset(void)
|
||||
{
|
||||
|
||||
printf("cpu_reset");
|
||||
while(1)
|
||||
__asm volatile("wfi" ::: "memory");
|
||||
sbi_shutdown();
|
||||
|
||||
while(1);
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user