RISC-V: add support for SBI spec v0.2
The Supervisor Binary Interface (SBI) specification v0.2 is a backwards incompatible update to the SBI call interface for kernels running in supervisor mode. The goal of this update was to make it easier for new and optional functionality to be added to the SBI. SBI functions are now called by passing an "extension ID" and a "function ID" which are passed in a7 and a6 respectively. SBI calls will also return an error and value in the following struct: struct sbi_ret { long error; long value; } This version introduces several new functions under the "base" extension. It is expected that all SBI implementations >= 0.2 will support this base set of functions, as they implement some essential services such as obtaining the SBI version, CPU implementation info, and extension probing. Existing SBI functions have been designated as "legacy". For the time being they will remain implemented, but it is expected that in the future their functionality will be duplicated or replaced by new SBI extensions. Each legacy function has been assigned its own extension ID, and for now we simply probe and assert for their existence. Compatibility with legacy SBI implementations (such as BBL) is maintained by checking the output of sbi_get_spec_version(). This function is guaranteed to succeed by the new spec, but will return an error in legacy implementations. We use this as an indicator of whether or not we can rely on the new SBI base extensions. For further info on the Supervisor Binary Interface, see: https://github.com/riscv/riscv-sbi-doc/blob/master/riscv-sbi.adoc Reviewed by: kp, jhb MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D22326
This commit is contained in:
parent
331baa6f1b
commit
ff33210c04
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=354720
@ -55,6 +55,7 @@ riscv/riscv/ofw_machdep.c optional fdt
|
||||
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
|
||||
|
@ -60,6 +60,11 @@ char machine[] = "riscv";
|
||||
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;
|
||||
|
@ -850,6 +850,9 @@ initriscv(struct riscv_bootparams *rvbp)
|
||||
|
||||
PCPU_SET(curthread, &thread0);
|
||||
|
||||
/* Initialize SBI interface. */
|
||||
sbi_init();
|
||||
|
||||
/* Set the module data location */
|
||||
lastaddr = fake_preload_metadata(rvbp);
|
||||
|
||||
|
127
sys/riscv/riscv/sbi.c
Normal file
127
sys/riscv/riscv/sbi.c
Normal file
@ -0,0 +1,127 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2019 Mitchell Horne <mhorne@FreeBSD.org>
|
||||
*
|
||||
* 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/types.h>
|
||||
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/sbi.h>
|
||||
|
||||
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()"));
|
||||
}
|
Loading…
Reference in New Issue
Block a user