Index: head/sys/conf/files.riscv =================================================================== --- head/sys/conf/files.riscv +++ head/sys/conf/files.riscv @@ -55,6 +55,7 @@ riscv/riscv/plic.c standard riscv/riscv/pmap.c standard riscv/riscv/riscv_console.c optional rcons +riscv/riscv/sbi.c standard riscv/riscv/soc.c standard riscv/riscv/stack_machdep.c optional ddb | stack riscv/riscv/support.S standard Index: head/sys/riscv/riscv/identcpu.c =================================================================== --- head/sys/riscv/riscv/identcpu.c +++ head/sys/riscv/riscv/identcpu.c @@ -60,6 +60,11 @@ SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "Machine class"); +/* Hardware implementation info. These values may be empty. */ +register_t mvendorid; /* The CPU's JEDEC vendor ID */ +register_t marchid; /* The architecture ID */ +register_t mimpid; /* The implementation ID */ + struct cpu_desc { u_int cpu_impl; u_int cpu_part_num; Index: head/sys/riscv/riscv/machdep.c =================================================================== --- head/sys/riscv/riscv/machdep.c +++ head/sys/riscv/riscv/machdep.c @@ -850,6 +850,9 @@ PCPU_SET(curthread, &thread0); + /* Initialize SBI interface. */ + sbi_init(); + /* Set the module data location */ lastaddr = fake_preload_metadata(rvbp); Index: head/sys/riscv/riscv/sbi.c =================================================================== --- head/sys/riscv/riscv/sbi.c +++ head/sys/riscv/riscv/sbi.c @@ -0,0 +1,127 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2019 Mitchell Horne + * + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include + +u_long sbi_spec_version; +u_long sbi_impl_id; +u_long sbi_impl_version; + +static struct sbi_ret +sbi_get_spec_version(void) +{ + return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_SPEC_VERSION)); +} + +static struct sbi_ret +sbi_get_impl_id(void) +{ + return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_IMPL_ID)); +} + +static struct sbi_ret +sbi_get_impl_version(void) +{ + return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_IMPL_VERSION)); +} + +static struct sbi_ret +sbi_get_mvendorid(void) +{ + return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_MVENDORID)); +} + + +static struct sbi_ret +sbi_get_marchid(void) +{ + return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_MARCHID)); +} + +static struct sbi_ret +sbi_get_mimpid(void) +{ + return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_MIMPID)); +} + +void +sbi_init(void) +{ + struct sbi_ret sret; + + /* + * Get the spec version. For legacy SBI implementations this will + * return an error, otherwise it is guaranteed to succeed. + */ + sret = sbi_get_spec_version(); + if (sret.error != 0) { + /* We are running a legacy SBI implementation. */ + sbi_spec_version = 0; + return; + } + + /* Set the SBI implementation info. */ + sbi_spec_version = sret.value; + sbi_impl_id = sbi_get_impl_id().value; + sbi_impl_version = sbi_get_impl_version().value; + + /* Set the hardware implementation info. */ + mvendorid = sbi_get_mvendorid().value; + marchid = sbi_get_marchid().value; + mimpid = sbi_get_mimpid().value; + + /* + * Probe for legacy extensions. Currently we rely on all of them + * to be implemented, but this is not guaranteed by the spec. + */ + KASSERT(sbi_probe_extension(SBI_SET_TIMER) != 0, + ("SBI doesn't implement sbi_set_timer()")); + KASSERT(sbi_probe_extension(SBI_CONSOLE_PUTCHAR) != 0, + ("SBI doesn't implement sbi_console_putchar()")); + KASSERT(sbi_probe_extension(SBI_CONSOLE_GETCHAR) != 0, + ("SBI doesn't implement sbi_console_getchar()")); + KASSERT(sbi_probe_extension(SBI_CLEAR_IPI) != 0, + ("SBI doesn't implement sbi_clear_ipi()")); + KASSERT(sbi_probe_extension(SBI_SEND_IPI) != 0, + ("SBI doesn't implement sbi_send_ipi()")); + KASSERT(sbi_probe_extension(SBI_REMOTE_FENCE_I) != 0, + ("SBI doesn't implement sbi_remote_fence_i()")); + KASSERT(sbi_probe_extension(SBI_REMOTE_SFENCE_VMA) != 0, + ("SBI doesn't implement sbi_remote_sfence_vma()")); + KASSERT(sbi_probe_extension(SBI_REMOTE_SFENCE_VMA_ASID) != 0, + ("SBI doesn't implement sbi_remote_sfence_vma_asid()")); + KASSERT(sbi_probe_extension(SBI_SHUTDOWN) != 0, + ("SBI doesn't implement sbi_shutdown()")); +}