From owner-svn-src-stable@freebsd.org Fri May 8 05:30:13 2020 Return-Path: Delivered-To: svn-src-stable@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 10B6F2C1593; Fri, 8 May 2020 05:30:13 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49JJnJ73pgz4FRJ; Fri, 8 May 2020 05:30:12 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id CF2632534F; Fri, 8 May 2020 05:30:12 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0485UCMe008417; Fri, 8 May 2020 05:30:12 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0485UBdx008409; Fri, 8 May 2020 05:30:11 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <202005080530.0485UBdx008409@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Fri, 8 May 2020 05:30:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r360808 - in stable/12/sys: conf riscv/include riscv/riscv X-SVN-Group: stable-12 X-SVN-Commit-Author: jhb X-SVN-Commit-Paths: in stable/12/sys: conf riscv/include riscv/riscv X-SVN-Commit-Revision: 360808 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 May 2020 05:30:13 -0000 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 * All rights reserved. + * Copyright (c) 2019 Mitchell Horne * * 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 #include +/* 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