diff --git a/sys/riscv/include/sbi.h b/sys/riscv/include/sbi.h --- a/sys/riscv/include/sbi.h +++ b/sys/riscv/include/sbi.h @@ -159,11 +159,7 @@ return (ret); } -/* Base extension functions and variables. */ -extern u_long sbi_spec_version; -extern u_long sbi_impl_id; -extern u_long sbi_impl_version; - +/* Base extension functions. */ static __inline long sbi_probe_extension(long id) { diff --git a/sys/riscv/riscv/sbi.c b/sys/riscv/riscv/sbi.c --- a/sys/riscv/riscv/sbi.c +++ b/sys/riscv/riscv/sbi.c @@ -2,6 +2,7 @@ * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2019 Mitchell Horne + * Copyright (c) 2021 Jessica Clarke * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,9 +40,15 @@ #define OPENSBI_VERSION_MAJOR_OFFSET 16 #define OPENSBI_VERSION_MINOR_MASK 0xFFFF -u_long sbi_spec_version; -u_long sbi_impl_id; -u_long sbi_impl_version; +struct sbi_softc { + device_t dev; +}; + +static struct sbi_softc *sbi_softc = NULL; + +static u_long sbi_spec_version; +static u_long sbi_impl_id; +static u_long sbi_impl_version; static bool has_time_extension = false; static bool has_ipi_extension = false; @@ -315,10 +322,53 @@ } static void -sbi_late_init(void *dummy __unused) +sbi_identify(driver_t *driver, device_t parent) +{ + device_t dev; + + if (device_find_child(parent, "sbi", -1) != NULL) + return; + + dev = BUS_ADD_CHILD(parent, 0, "sbi", -1); + if (dev == NULL) + device_printf(parent, "Can't add sbi child\n"); +} + +static void +sbi_probe(device_t dev) +{ + device_set_desc(dev, "RISC-V Supervisor Binary Interface"); + + return (BUS_PROBE_NOWILDCARD); +} + +static void +sbi_attach(device_t dev) { + struct sbi_softc *sc; + + if (sbi_softc != NULL) + return (ENXIO); + + sc = device_get_softc(dev); + sc->dev = dev; + sbi_softc = sc; + EVENTHANDLER_REGISTER(shutdown_final, sbi_shutdown_final, NULL, SHUTDOWN_PRI_LAST); + + return (0); } -SYSINIT(sbi, SI_SUB_KLD, SI_ORDER_ANY, sbi_late_init, NULL); +static device_method_t sbi_methods[] = { + /* Device interface */ + DEVMETHOD(device_identify, sbi_identify), + DEVMETHOD(device_probe, sbi_probe), + DEVMETHOD(device_attach, sbi_attach), + + DEVMETHOD_END +}; + +DEFINE_CLASS_0(sbi, sbi_driver, sbi_methods, sizeof(struct sbi_softc)); +EARLY_DRIVER_MODULE(sbi, nexus, sbi_driver, 0, 0, + BUS_PASS_CPU + BUS_PASS_ORDER_FIRST);