svn commit: r360808 - in stable/12/sys: conf riscv/include riscv/riscv
John Baldwin
jhb at FreeBSD.org
Fri May 8 05:30:13 UTC 2020
Author: jhb
Date: Fri May 8 05:30:10 2020
New Revision: 360808
URL: https://svnweb.freebsd.org/changeset/base/360808
Log:
MFC 354719,354720,354721,354722,357480: OpenSBI support.
354719:
RISC-V: pass arg6 in sbi_call
Allow for an additional argument to sbi_call which will be passed in a6.
This is required for SBI spec 0.2 support, as a6 will indicate the SBI
function ID.
While here, introduce some macros to clean up the calls.
354720:
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
354721:
Add missing files from r354720
354722:
RISC-V: Print SBI info at startup
SBI version 0.2 introduces functions for obtaining the details of the
SBI implementation, such as version and implemntation ID. Print this
info at startup when it is available.
357480:
Set the LMA of the riscv kernel to the OpenSBI jump target by default
This allows us to boot FreeBSD RISCV on QEMU using the -kernel command line
options. When using that option, QEMU maps the kernel ELF file to the
addresses specified in the LMAs in the program headers.
Since version 4.2 QEMU ships with OpenSBI fw_jump by default so this allows
booting FreeBSD using the following command line:
qemu-system-riscv64 -bios default -kernel /.../boot/kernel/kernel -nographic -M virt
Without this change the -kernel option cannot be used since the LMAs start
at address zero and QEMU already maps a ROM to these low physical addresses.
For targets that require a different kernel LMA the make variable
KERNEL_LMA can be overwritten in the config file. For example, adding
`makeoptions KERNEL_LMA=0xc0200000` will create an ELF file that will be
loaded at 0xc0200000.
Before:
There are 4 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x001000 0xffffffc000000000 0x0000000000000000 0x75e598 0x8be318 RWE 0x1000
DYNAMIC 0x71fb20 0xffffffc00071eb20 0x000000000071eb20 0x000100 0x000100 RW 0x8
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x0
NOTE 0x693400 0xffffffc000692400 0x0000000000692400 0x000024 0x000024 R 0x4
After:
There are 4 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x001000 0xffffffc000000000 0x0000000080200000 0x734198 0x893e18 RWE 0x1000
DYNAMIC 0x6f7810 0xffffffc0006f6810 0x00000000808f6810 0x000100 0x000100 RW 0x8
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x0
NOTE 0x66ca70 0xffffffc00066ba70 0x000000008086ba70 0x000024 0x000024 R 0x4
Added:
stable/12/sys/riscv/riscv/sbi.c
- copied, changed from r354720, head/sys/riscv/riscv/sbi.c
Modified:
stable/12/sys/conf/Makefile.riscv
stable/12/sys/conf/files.riscv
stable/12/sys/conf/ldscript.riscv
stable/12/sys/riscv/include/md_var.h
stable/12/sys/riscv/include/sbi.h
stable/12/sys/riscv/riscv/identcpu.c
stable/12/sys/riscv/riscv/machdep.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/conf/Makefile.riscv
==============================================================================
--- stable/12/sys/conf/Makefile.riscv Fri May 8 02:42:15 2020 (r360807)
+++ stable/12/sys/conf/Makefile.riscv Fri May 8 05:30:10 2020 (r360808)
@@ -28,8 +28,17 @@ S= ../../..
INCLUDES+= -I$S/contrib/libfdt
+# Set the ELF LMA to the address that OpenSBI's fw_jump jumps to. This allows
+# us to load the kernel with the -kernel flag in QEMU without having to embed
+# it inside BBL or OpenSBI's fw_payload first.
+# Note: For rv32 the start address is different (0x80400000).
+# We set this value using --defsym rather than hardcoding it in ldscript.riscv
+# so that different kernel configs can override the load address.
+KERNEL_LMA?= 0x80200000
+
SYSTEM_LD= @${LD} -N -m ${LD_EMULATION} -Bdynamic -T ${LDSCRIPT} ${_LDFLAGS} \
--no-warn-mismatch --warn-common --export-dynamic \
+ --defsym='kernel_lma=${KERNEL_LMA}' \
--dynamic-linker /red/herring \
-o ${.TARGET} -X ${SYSTEM_OBJS} vers.o
Modified: stable/12/sys/conf/files.riscv
==============================================================================
--- stable/12/sys/conf/files.riscv Fri May 8 02:42:15 2020 (r360807)
+++ stable/12/sys/conf/files.riscv Fri May 8 05:30:10 2020 (r360808)
@@ -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
Modified: stable/12/sys/conf/ldscript.riscv
==============================================================================
--- stable/12/sys/conf/ldscript.riscv Fri May 8 02:42:15 2020 (r360807)
+++ stable/12/sys/conf/ldscript.riscv Fri May 8 05:30:10 2020 (r360808)
@@ -7,7 +7,8 @@ SECTIONS
{
/* Read-only sections, merged into text segment: */
. = kernbase;
- .text : AT(ADDR(.text) - kernbase)
+ /* The load address kernel_lma is set using --defsym= on the command line. */
+ .text : AT(kernel_lma)
{
*(.text)
*(.stub)
Modified: stable/12/sys/riscv/include/md_var.h
==============================================================================
--- stable/12/sys/riscv/include/md_var.h Fri May 8 02:42:15 2020 (r360807)
+++ stable/12/sys/riscv/include/md_var.h Fri May 8 05:30:10 2020 (r360808)
@@ -39,6 +39,9 @@ extern int szsigcode;
extern uint64_t *vm_page_dump;
extern int vm_page_dump_size;
extern u_long elf_hwcap;
+extern register_t mvendorid;
+extern register_t marchid;
+extern register_t mimpid;
struct dumperinfo;
Modified: stable/12/sys/riscv/include/sbi.h
==============================================================================
--- stable/12/sys/riscv/include/sbi.h Fri May 8 02:42:15 2020 (r360807)
+++ stable/12/sys/riscv/include/sbi.h Fri May 8 05:30:10 2020 (r360808)
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 2016-2017 Ruslan Bukin <br at bsdpad.com>
* All rights reserved.
+ * Copyright (c) 2019 Mitchell Horne <mhorne at FreeBSD.org>
*
* Portions of this software were developed by SRI International and the
* University of Cambridge Computer Laboratory under DARPA/AFRL contract
@@ -37,6 +38,35 @@
#ifndef _MACHINE_SBI_H_
#define _MACHINE_SBI_H_
+/* SBI Specification Version */
+#define SBI_SPEC_VERS_MAJOR_OFFSET 24
+#define SBI_SPEC_VERS_MAJOR_MASK (0x7F << SBI_SPEC_VERS_MAJOR_OFFSET)
+#define SBI_SPEC_VERS_MINOR_OFFSET 0
+#define SBI_SPEC_VERS_MINOR_MASK (0xFFFFFF << SBI_SPEC_VERS_MINOR_OFFSET)
+
+/* SBI Implementation IDs */
+#define SBI_IMPL_ID_BBL 0
+#define SBI_IMPL_ID_OPENSBI 1
+
+/* SBI Error Codes */
+#define SBI_SUCCESS 0
+#define SBI_ERR_FAILURE -1
+#define SBI_ERR_NOT_SUPPORTED -2
+#define SBI_ERR_INVALID_PARAM -3
+#define SBI_ERR_DENIED -4
+#define SBI_ERR_INVALID_ADDRESS -5
+
+/* SBI Base Extension */
+#define SBI_EXT_ID_BASE 0x10
+#define SBI_BASE_GET_SPEC_VERSION 0
+#define SBI_BASE_GET_IMPL_ID 1
+#define SBI_BASE_GET_IMPL_VERSION 2
+#define SBI_BASE_PROBE_EXTENSION 3
+#define SBI_BASE_GET_MVENDORID 4
+#define SBI_BASE_GET_MARCHID 5
+#define SBI_BASE_GET_MIMPID 6
+
+/* Legacy Extensions */
#define SBI_SET_TIMER 0
#define SBI_CONSOLE_PUTCHAR 1
#define SBI_CONSOLE_GETCHAR 2
@@ -47,77 +77,109 @@
#define SBI_REMOTE_SFENCE_VMA_ASID 7
#define SBI_SHUTDOWN 8
+#define SBI_CALL0(e, f) SBI_CALL4(e, f, 0, 0, 0, 0)
+#define SBI_CALL1(e, f, p1) SBI_CALL4(e, f, p1, 0, 0, 0)
+#define SBI_CALL2(e, f, p1, p2) SBI_CALL4(e, f, p1, p2, 0, 0)
+#define SBI_CALL3(e, f, p1, p2, p3) SBI_CALL4(e, f, p1, p2, p3, 0)
+#define SBI_CALL4(e, f, p1, p2, p3, p4) sbi_call(e, f, p1, p2, p3, p4)
+
/*
* Documentation available at
- * https://github.com/riscv/riscv-sbi-doc/blob/master/riscv-sbi.md
+ * https://github.com/riscv/riscv-sbi-doc/blob/master/riscv-sbi.adoc
*/
-static __inline uint64_t
-sbi_call(uint64_t arg7, uint64_t arg0, uint64_t arg1, uint64_t arg2,
- uint64_t arg3)
+struct sbi_ret {
+ long error;
+ long value;
+};
+
+static __inline struct sbi_ret
+sbi_call(uint64_t arg7, uint64_t arg6, uint64_t arg0, uint64_t arg1,
+ uint64_t arg2, uint64_t arg3)
{
+ struct sbi_ret ret;
+
register uintptr_t a0 __asm ("a0") = (uintptr_t)(arg0);
register uintptr_t a1 __asm ("a1") = (uintptr_t)(arg1);
register uintptr_t a2 __asm ("a2") = (uintptr_t)(arg2);
register uintptr_t a3 __asm ("a3") = (uintptr_t)(arg3);
+ register uintptr_t a6 __asm ("a6") = (uintptr_t)(arg6);
register uintptr_t a7 __asm ("a7") = (uintptr_t)(arg7);
__asm __volatile( \
"ecall" \
- :"+r"(a0) \
- :"r"(a1), "r"(a2), "r" (a3), "r"(a7) \
+ :"+r"(a0), "+r"(a1) \
+ :"r"(a2), "r"(a3), "r"(a6), "r"(a7) \
:"memory");
- return (a0);
+ ret.error = a0;
+ ret.value = a1;
+ 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;
+
+static __inline long
+sbi_probe_extension(long id)
+{
+ return (SBI_CALL1(SBI_EXT_ID_BASE, SBI_BASE_PROBE_EXTENSION, id).value);
+}
+
+/* Legacy extension functions. */
static __inline void
sbi_console_putchar(int ch)
{
- sbi_call(SBI_CONSOLE_PUTCHAR, ch, 0, 0, 0);
+ (void)SBI_CALL1(SBI_CONSOLE_PUTCHAR, 0, ch);
}
static __inline int
sbi_console_getchar(void)
{
- return (sbi_call(SBI_CONSOLE_GETCHAR, 0, 0, 0, 0));
+ /*
+ * XXX: The "error" is returned here because legacy SBI functions
+ * continue to return their value in a0.
+ */
+ return (SBI_CALL0(SBI_CONSOLE_GETCHAR, 0).error);
}
static __inline void
sbi_set_timer(uint64_t val)
{
- sbi_call(SBI_SET_TIMER, val, 0, 0, 0);
+ (void)SBI_CALL1(SBI_SET_TIMER, 0, val);
}
static __inline void
sbi_shutdown(void)
{
- sbi_call(SBI_SHUTDOWN, 0, 0, 0, 0);
+ (void)SBI_CALL0(SBI_SHUTDOWN, 0);
}
static __inline void
sbi_clear_ipi(void)
{
- sbi_call(SBI_CLEAR_IPI, 0, 0, 0, 0);
+ (void)SBI_CALL0(SBI_CLEAR_IPI, 0);
}
static __inline void
sbi_send_ipi(const unsigned long *hart_mask)
{
- sbi_call(SBI_SEND_IPI, (uint64_t)hart_mask, 0, 0, 0);
+ (void)SBI_CALL1(SBI_SEND_IPI, 0, (uint64_t)hart_mask);
}
static __inline void
sbi_remote_fence_i(const unsigned long *hart_mask)
{
- sbi_call(SBI_REMOTE_FENCE_I, (uint64_t)hart_mask, 0, 0, 0);
+ (void)SBI_CALL1(SBI_REMOTE_FENCE_I, 0, (uint64_t)hart_mask);
}
static __inline void
@@ -125,7 +187,8 @@ sbi_remote_sfence_vma(const unsigned long *hart_mask,
unsigned long start, unsigned long size)
{
- sbi_call(SBI_REMOTE_SFENCE_VMA, (uint64_t)hart_mask, start, size, 0);
+ (void)SBI_CALL3(SBI_REMOTE_SFENCE_VMA, 0, (uint64_t)hart_mask, start,
+ size);
}
static __inline void
@@ -134,8 +197,11 @@ sbi_remote_sfence_vma_asid(const unsigned long *hart_m
unsigned long asid)
{
- sbi_call(SBI_REMOTE_SFENCE_VMA_ASID, (uint64_t)hart_mask, start, size,
- asid);
+ (void)SBI_CALL4(SBI_REMOTE_SFENCE_VMA_ASID, 0, (uint64_t)hart_mask,
+ start, size, asid);
}
+
+void sbi_print_version(void);
+void sbi_init(void);
#endif /* !_MACHINE_SBI_H_ */
Modified: stable/12/sys/riscv/riscv/identcpu.c
==============================================================================
--- stable/12/sys/riscv/riscv/identcpu.c Fri May 8 02:42:15 2020 (r360807)
+++ stable/12/sys/riscv/riscv/identcpu.c Fri May 8 05:30:10 2020 (r360808)
@@ -59,6 +59,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;
Modified: stable/12/sys/riscv/riscv/machdep.c
==============================================================================
--- stable/12/sys/riscv/riscv/machdep.c Fri May 8 02:42:15 2020 (r360807)
+++ stable/12/sys/riscv/riscv/machdep.c Fri May 8 05:30:10 2020 (r360808)
@@ -128,6 +128,7 @@ static void
cpu_startup(void *dummy)
{
+ sbi_print_version();
identify_cpu();
printf("real memory = %ju (%ju MB)\n", ptoa((uintmax_t)realmem),
@@ -847,6 +848,9 @@ initriscv(struct riscv_bootparams *rvbp)
__asm __volatile("mv tp, %0" :: "r"(pcpup));
PCPU_SET(curthread, &thread0);
+
+ /* Initialize SBI interface. */
+ sbi_init();
/* Set the module data location */
lastaddr = fake_preload_metadata(rvbp);
Copied and modified: stable/12/sys/riscv/riscv/sbi.c (from r354720, head/sys/riscv/riscv/sbi.c)
==============================================================================
--- head/sys/riscv/riscv/sbi.c Fri Nov 15 03:34:27 2019 (r354720, copy source)
+++ stable/12/sys/riscv/riscv/sbi.c Fri May 8 05:30:10 2020 (r360808)
@@ -35,6 +35,10 @@ __FBSDID("$FreeBSD$");
#include <machine/md_var.h>
#include <machine/sbi.h>
+/* SBI Implementation-Specific Definitions */
+#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;
@@ -74,6 +78,39 @@ static struct sbi_ret
sbi_get_mimpid(void)
{
return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_MIMPID));
+}
+
+void
+sbi_print_version(void)
+{
+ u_int major;
+ u_int minor;
+
+ /* For legacy SBI implementations. */
+ if (sbi_spec_version == 0) {
+ printf("SBI: Unknown (Legacy) Implementation\n");
+ printf("SBI Specification Version: 0.1\n");
+ return;
+ }
+
+ switch (sbi_impl_id) {
+ case (SBI_IMPL_ID_BBL):
+ printf("SBI: Berkely Boot Loader %u\n", sbi_impl_version);
+ break;
+ case (SBI_IMPL_ID_OPENSBI):
+ major = sbi_impl_version >> OPENSBI_VERSION_MAJOR_OFFSET;
+ minor = sbi_impl_version & OPENSBI_VERSION_MINOR_MASK;
+ printf("SBI: OpenSBI v%u.%u\n", major, minor);
+ break;
+ default:
+ printf("SBI: Unrecognized Implementation: %u\n", sbi_impl_id);
+ break;
+ }
+
+ major = (sbi_spec_version & SBI_SPEC_VERS_MAJOR_MASK) >>
+ SBI_SPEC_VERS_MAJOR_OFFSET;
+ minor = (sbi_spec_version & SBI_SPEC_VERS_MINOR_MASK);
+ printf("SBI Specification Version: %u.%u\n", major, minor);
}
void
More information about the svn-src-all
mailing list