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 <b...@bsdpad.com>
  * All rights reserved.
+ * Copyright (c) 2019 Mitchell Horne <mho...@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
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to