svn commit: r362973 - in head: share/mk stand stand/common stand/efi/include/riscv stand/efi/libefi stand/efi/loader stand/efi/loader/arch/riscv sys/riscv/include

Mitchell Horne mhorne at freebsd.org
Mon Jul 6 18:26:51 UTC 2020


On Mon, Jul 6, 2020 at 3:19 PM Mitchell Horne <mhorne at freebsd.org> wrote:
>
> Author: mhorne
> Date: Mon Jul  6 18:19:42 2020
> New Revision: 362973
> URL: https://svnweb.freebsd.org/changeset/base/362973
>
> Log:
>   RISC-V boot1.efi and loader.efi support
>
>   This implementation doesn't have any major deviations from the other EFI
>   ports. I've copied the boilerplate from arm and arm64.
>
>   I've tested this with the following boot flows:
>   OpenSBI (M-mode) -> u-boot (S-mode) -> loader.efi -> FreeBSD
>   OpenSBI (M-mode) -> u-boot (S-mode) -> boot1.efi -> loader.efi -> FreeBSD
>
>   Due to the way that u-boot handles secondary CPUs, OpenSBI >= v0.7 is required,
>   as the HSM extension is needed to bring them up explicitly. Because of this,
>   using BBL as the SBI implementation will not be possible. Additionally, there
>   are a few recent u-boot changes that are required as well, all of which will be
>   present in the upcoming v2020.07 release.
>
>   Looks good:   emaste
>   Differential Revision:        https://reviews.freebsd.org/D25135
>
> Added:
>   head/stand/efi/include/riscv/
>   head/stand/efi/include/riscv/efibind.h
>      - copied unchanged from r362787, head/stand/efi/include/arm64/efibind.h
>   head/stand/efi/loader/arch/riscv/
>   head/stand/efi/loader/arch/riscv/Makefile.inc   (contents, props changed)
>   head/stand/efi/loader/arch/riscv/exec.c
>      - copied, changed from r362787, head/stand/efi/loader/arch/arm/exec.c
>   head/stand/efi/loader/arch/riscv/ldscript.riscv   (contents, props changed)
>   head/stand/efi/loader/arch/riscv/start.S   (contents, props changed)
> Modified:
>   head/share/mk/src.opts.mk
>   head/stand/common/self_reloc.c
>   head/stand/defs.mk
>   head/stand/efi/libefi/Makefile
>   head/stand/efi/loader/copy.c
>   head/stand/efi/loader/main.c
>   head/stand/loader.mk
>   head/sys/riscv/include/metadata.h
>
> Modified: head/share/mk/src.opts.mk
> ==============================================================================
> --- head/share/mk/src.opts.mk   Mon Jul  6 17:47:29 2020        (r362972)
> +++ head/share/mk/src.opts.mk   Mon Jul  6 18:19:42 2020        (r362973)
> @@ -318,8 +318,8 @@ BROKEN_OPTIONS+=LIBSOFT
>  # marked no longer broken with the switch to LLVM.
>  BROKEN_OPTIONS+=GOOGLETEST SSP
>  .endif
> -# EFI doesn't exist on mips, powerpc, or riscv.
> -.if ${__T:Mmips*} || ${__T:Mpowerpc*} || ${__T:Mriscv*}
> +# EFI doesn't exist on mips or powerpc.
> +.if ${__T:Mmips*} || ${__T:Mpowerpc*}
>  BROKEN_OPTIONS+=EFI
>  .endif
>  # OFW is only for powerpc, exclude others
>

I meant to commit this hunk separately, but included it by mistake.
The log would have been:

Enable MK_EFI by default on RISC-V

We can now build the EFI libraries, utilities, and bootloader. This is
enough for EFI boot-time services and for us to un-break this option.

Reviewed by: br
Differential Revision: https://reviews.freebsd.org/D25137

> Modified: head/stand/common/self_reloc.c
> ==============================================================================
> --- head/stand/common/self_reloc.c      Mon Jul  6 17:47:29 2020        (r362972)
> +++ head/stand/common/self_reloc.c      Mon Jul  6 18:19:42 2020        (r362973)
> @@ -31,7 +31,7 @@ __FBSDID("$FreeBSD$");
>  #include <elf.h>
>  #include <bootstrap.h>
>
> -#if defined(__aarch64__) || defined(__amd64__)
> +#if defined(__aarch64__) || defined(__amd64__) || defined(__riscv)
>  #define        ElfW_Rel        Elf64_Rela
>  #define        ElfW_Dyn        Elf64_Dyn
>  #define        ELFW_R_TYPE     ELF64_R_TYPE
> @@ -55,6 +55,9 @@ __FBSDID("$FreeBSD$");
>  #elif defined(__i386__)
>  #define        RELOC_TYPE_NONE         R_386_NONE
>  #define        RELOC_TYPE_RELATIVE     R_386_RELATIVE
> +#elif defined(__riscv)
> +#define        RELOC_TYPE_NONE         R_RISCV_NONE
> +#define        RELOC_TYPE_RELATIVE     R_RISCV_RELATIVE
>  #endif
>
>  void self_reloc(Elf_Addr baseaddr, ElfW_Dyn *dynamic);
>
> Modified: head/stand/defs.mk
> ==============================================================================
> --- head/stand/defs.mk  Mon Jul  6 17:47:29 2020        (r362972)
> +++ head/stand/defs.mk  Mon Jul  6 18:19:42 2020        (r362973)
> @@ -115,13 +115,14 @@ AFLAGS+=  --32
>  SSP_CFLAGS=
>
>  # Add in the no float / no SIMD stuff and announce we're freestanding
> -# aarch64 and riscv don't have -msoft-float, but all others do. riscv
> -# currently has no /boot/loader, but may soon.
> +# aarch64 and riscv don't have -msoft-float, but all others do.
>  CFLAGS+=       -ffreestanding ${CFLAGS_NO_SIMD}
>  .if ${MACHINE_CPUARCH} == "aarch64"
>  CFLAGS+=       -mgeneral-regs-only -ffixed-x18 -fPIC
>  .elif ${MACHINE_CPUARCH} == "riscv"
> -CFLAGS+=       -march=rv64imac -mabi=lp64
> +CFLAGS+=       -march=rv64imac -mabi=lp64 -fPIC
> +CFLAGS.clang+= -mcmodel=medium
> +CFLAGS.gcc+=   -mcmodel=medany
>  .else
>  CFLAGS+=       -msoft-float
>  .endif
> @@ -146,6 +147,12 @@ CFLAGS+=   -fPIC -mno-red-zone
>  CFLAGS.clang+= -mno-movt
>  CFLAGS.clang+=  -mfpu=none
>  CFLAGS+=       -fPIC
> +.endif
> +
> +# Some RISC-V linkers have support for relaxations, while some (lld) do not
> +# yet. If this is the case we inhibit the compiler from emitting relaxations.
> +.if ${LINKER_FEATURES:Mriscv-relaxations} == ""
> +CFLAGS+=       -mno-relax
>  .endif
>
>  # The boot loader build uses dd status=none, where possible, for reproducible
>
> Copied: head/stand/efi/include/riscv/efibind.h (from r362787, head/stand/efi/include/arm64/efibind.h)
> ==============================================================================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/stand/efi/include/riscv/efibind.h      Mon Jul  6 18:19:42 2020        (r362973, copy of r362787, head/stand/efi/include/arm64/efibind.h)
> @@ -0,0 +1,217 @@
> +/* $FreeBSD$ */
> +/*++
> +
> +Copyright (c)  1999 - 2003 Intel Corporation. All rights reserved
> +This software and associated documentation (if any) is furnished
> +under a license and may only be used or copied in accordance
> +with the terms of the license. Except as permitted by such
> +license, no part of this software or documentation may be
> +reproduced, stored in a retrieval system, or transmitted in any
> +form or by any means without the express written consent of
> +Intel Corporation.
> +
> +Module Name:
> +
> +    efefind.h
> +
> +Abstract:
> +
> +    EFI to compile bindings
> +
> +
> +
> +
> +Revision History
> +
> +--*/
> +
> +#pragma pack()
> +
> +
> +#ifdef __FreeBSD__
> +#include <sys/stdint.h>
> +#else
> +//
> +// Basic int types of various widths
> +//
> +
> +#if (__STDC_VERSION__ < 199901L )
> +
> +    // No ANSI C 1999/2000 stdint.h integer width declarations
> +
> +    #ifdef _MSC_EXTENSIONS
> +
> +        // Use Microsoft C compiler integer width declarations
> +
> +        typedef unsigned __int64    uint64_t;
> +        typedef __int64             int64_t;
> +        typedef unsigned __int32    uint32_t;
> +        typedef __int32             int32_t;
> +        typedef unsigned __int16    uint16_t;
> +        typedef __int16             int16_t;
> +        typedef unsigned __int8     uint8_t;
> +        typedef __int8              int8_t;
> +    #else
> +        #ifdef UNIX_LP64
> +
> +            // Use LP64 programming model from C_FLAGS for integer width declarations
> +
> +            typedef unsigned long       uint64_t;
> +            typedef long                int64_t;
> +            typedef unsigned int        uint32_t;
> +            typedef int                 int32_t;
> +            typedef unsigned short      uint16_t;
> +            typedef short               int16_t;
> +            typedef unsigned char       uint8_t;
> +            typedef char                int8_t;
> +        #else
> +
> +            // Assume P64 programming model from C_FLAGS for integer width declarations
> +
> +            typedef unsigned long long  uint64_t;
> +            typedef long long           int64_t;
> +            typedef unsigned int        uint32_t;
> +            typedef int                 int32_t;
> +            typedef unsigned short      uint16_t;
> +            typedef short               int16_t;
> +            typedef unsigned char       uint8_t;
> +            typedef char                int8_t;
> +        #endif
> +    #endif
> +#endif
> +#endif /* __FreeBSD__ */
> +
> +//
> +// Basic EFI types of various widths
> +//
> +
> +
> +typedef uint64_t   UINT64;
> +typedef int64_t    INT64;
> +typedef uint32_t   UINT32;
> +typedef int32_t    INT32;
> +typedef uint16_t   UINT16;
> +typedef int16_t    INT16;
> +typedef uint8_t    UINT8;
> +typedef int8_t     INT8;
> +
> +
> +#undef VOID
> +#define VOID    void
> +
> +
> +typedef int64_t    INTN;
> +typedef uint64_t   UINTN;
> +
> +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +// BugBug: Code to debug
> +//
> +#define BIT63   0x8000000000000000
> +
> +#define PLATFORM_IOBASE_ADDRESS   (0xffffc000000 | BIT63)
> +#define PORT_TO_MEMD(_Port) (PLATFORM_IOBASE_ADDRESS | ( ( ( (_Port) & 0xfffc) << 10 ) | ( (_Port) & 0x0fff) ) )
> +
> +//
> +// Macro's with casts make this much easier to use and read.
> +//
> +#define PORT_TO_MEM8D(_Port)  (*(UINT8  *)(PORT_TO_MEMD(_Port)))
> +#define POST_CODE(_Data)  (PORT_TO_MEM8D(0x80) = (_Data))
> +//
> +// BugBug: End Debug Code!!!
> +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +
> +#define EFIERR(a)           (0x8000000000000000 | a)
> +#define EFI_ERROR_MASK      0x8000000000000000
> +#define EFIERR_OEM(a)       (0xc000000000000000 | a)
> +
> +#define BAD_POINTER         0xFBFBFBFBFBFBFBFB
> +#define MAX_ADDRESS         0xFFFFFFFFFFFFFFFF
> +
> +#define BREAKPOINT()  __break(0)
> +
> +//
> +// Pointers must be aligned to these address to function
> +//  you will get an alignment fault if this value is less than 8
> +//
> +#define MIN_ALIGNMENT_SIZE  8
> +
> +#define ALIGN_VARIABLE(Value , Adjustment) \
> +            (UINTN) Adjustment = 0; \
> +            if((UINTN)Value % MIN_ALIGNMENT_SIZE) \
> +                (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \
> +            Value = (UINTN)Value + (UINTN)Adjustment
> +
> +//
> +// Define macros to create data structure signatures.
> +//
> +
> +#define EFI_SIGNATURE_16(A,B)             ((A) | (B<<8))
> +#define EFI_SIGNATURE_32(A,B,C,D)         (EFI_SIGNATURE_16(A,B)     | (EFI_SIGNATURE_16(C,D)     << 16))
> +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32))
> +
> +//
> +// EFIAPI - prototype calling convention for EFI function pointers
> +// BOOTSERVICE - prototype for implementation of a boot service interface
> +// RUNTIMESERVICE - prototype for implementation of a runtime service interface
> +// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service
> +// RUNTIME_CODE - pragma macro for declaring runtime code
> +//
> +
> +#ifndef EFIAPI                  // Forces EFI calling conventions reguardless of compiler options
> +    #ifdef _MSC_EXTENSIONS
> +        #define EFIAPI __cdecl  // Force C calling convention for Microsoft C compiler
> +    #else
> +        #define EFIAPI          // Substitute expresion to force C calling convention
> +    #endif
> +#endif
> +
> +#define BOOTSERVICE
> +#define RUNTIMESERVICE
> +#define RUNTIMEFUNCTION
> +
> +#define RUNTIME_CODE(a)         alloc_text("rtcode", a)
> +#define BEGIN_RUNTIME_DATA()    data_seg("rtdata")
> +#define END_RUNTIME_DATA()      data_seg()
> +
> +#define VOLATILE    volatile
> +
> +//
> +// BugBug: Need to find out if this is portable across compilers.
> +//
> +void __mfa (void);
> +#define MEMORY_FENCE()    __mfa()
> +
> +#ifdef EFI_NO_INTERFACE_DECL
> +  #define EFI_FORWARD_DECLARATION(x)
> +  #define EFI_INTERFACE_DECL(x)
> +#else
> +  #define EFI_FORWARD_DECLARATION(x) typedef struct _##x x
> +  #define EFI_INTERFACE_DECL(x) typedef struct x
> +#endif
> +
> +//
> +// When build similar to FW, then link everything together as
> +// one big module.
> +//
> +
> +#define EFI_DRIVER_ENTRY_POINT(InitFunction)
> +
> +#define LOAD_INTERNAL_DRIVER(_if, type, name, entry)    \
> +            (_if)->LoadInternal(type, name, entry)
> +//        entry(NULL, ST)
> +
> +#ifdef __FreeBSD__
> +#define INTERFACE_DECL(x) struct x
> +#else
> +//
> +// Some compilers don't support the forward reference construct:
> +//  typedef struct XXXXX
> +//
> +// The following macro provide a workaround for such cases.
> +//
> +#ifdef NO_INTERFACE_DECL
> +#define INTERFACE_DECL(x)
> +#else
> +#define INTERFACE_DECL(x) typedef struct x
> +#endif
> +#endif
>
> Modified: head/stand/efi/libefi/Makefile
> ==============================================================================
> --- head/stand/efi/libefi/Makefile      Mon Jul  6 17:47:29 2020        (r362972)
> +++ head/stand/efi/libefi/Makefile      Mon Jul  6 18:19:42 2020        (r362973)
> @@ -27,7 +27,8 @@ SRCS+=  teken.c
>
>  .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
>  SRCS+= time.c
> -.elif ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm"
> +.elif ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm" || \
> +    ${MACHINE_CPUARCH} == "riscv"
>  SRCS+= time_event.c
>  .endif
>
>
> Added: head/stand/efi/loader/arch/riscv/Makefile.inc
> ==============================================================================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/stand/efi/loader/arch/riscv/Makefile.inc       Mon Jul  6 18:19:42 2020        (r362973)
> @@ -0,0 +1,7 @@
> +# $FreeBSD$
> +
> +HAVE_FDT=yes
> +
> +SRCS+= exec.c \
> +       efiserialio.c \
> +       start.S
>
> Copied and modified: head/stand/efi/loader/arch/riscv/exec.c (from r362787, head/stand/efi/loader/arch/arm/exec.c)
> ==============================================================================
> --- head/stand/efi/loader/arch/arm/exec.c       Mon Jun 29 18:06:00 2020        (r362787, copy source)
> +++ head/stand/efi/loader/arch/riscv/exec.c     Mon Jul  6 18:19:42 2020        (r362973)
> @@ -43,25 +43,11 @@ __FBSDID("$FreeBSD$");
>  #include "bootstrap.h"
>  #include "loader_efi.h"
>
> -extern vm_offset_t md_load(char *, vm_offset_t *);
>  extern int bi_load(char *, vm_offset_t *, vm_offset_t *);
>
>  static int
> -__elfN(arm_load)(char *filename, uint64_t dest,
> -    struct preloaded_file **result)
> +__elfN(exec)(struct preloaded_file *fp)
>  {
> -       int r;
> -
> -       r = __elfN(loadfile)(filename, dest, result);
> -       if (r != 0)
> -               return (r);
> -
> -       return (0);
> -}
> -
> -static int
> -__elfN(arm_exec)(struct preloaded_file *fp)
> -{
>         struct file_metadata *fmp;
>         vm_offset_t modulep, kernend;
>         Elf_Ehdr *e;
> @@ -85,22 +71,22 @@ __elfN(arm_exec)(struct preloaded_file *fp)
>                 return (error);
>         }
>
> -       /* At this point we've called ExitBootServices, so we can't call
> -        * printf or any other function that uses Boot Services */
> -
> +       /*
> +        * At this point we've called ExitBootServices, so we can't call
> +        * printf or any other function that uses Boot Services
> +        */
>         dev_cleanup();
>
>         (*entry)((void *)modulep);
>         panic("exec returned");
>  }
>
> -static struct file_format arm_elf = {
> -       __elfN(arm_load),
> -       __elfN(arm_exec)
> +static struct file_format riscv_elf = {
> +       __elfN(loadfile),
> +       __elfN(exec)
>  };
>
>  struct file_format *file_formats[] = {
> -       &arm_elf,
> +       &riscv_elf,
>         NULL
>  };
> -
>
> Added: head/stand/efi/loader/arch/riscv/ldscript.riscv
> ==============================================================================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/stand/efi/loader/arch/riscv/ldscript.riscv     Mon Jul  6 18:19:42 2020        (r362973)
> @@ -0,0 +1,87 @@
> +/* $FreeBSD$ */
> +OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv")
> +OUTPUT_ARCH(riscv64)
> +ENTRY(_start)
> +SECTIONS
> +{
> +  /* Read-only sections, merged into text segment: */
> +  . = 0;
> +  ImageBase = .;
> +  .text                : {
> +    *(.peheader)
> +    *(.text .stub .text.* .gnu.linkonce.t.*)
> +    /* .gnu.warning sections are handled specially by elf32.em. */
> +    *(.gnu.warning)
> +    *(.plt)
> +  } =0x9090
> +  . = ALIGN(16);
> +  .data                : {
> +    *(.rodata .rodata.* .gnu.linkonce.r.*)
> +    *(.rodata1)
> +    *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
> +    *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
> +    *(.opd)
> +    *(.data .data.* .gnu.linkonce.d.*)
> +    *(.data1)
> +    *(.plabel)
> +
> +    . = ALIGN(16);
> +    __bss_start = .;
> +    *(.sbss .sbss.* .gnu.linkonce.sb.*)
> +    *(.scommon)
> +    *(.dynbss)
> +    *(.bss *.bss.*)
> +    *(COMMON)
> +    . = ALIGN(16);
> +    __bss_end = .;
> +  }
> +  . = ALIGN(16);
> +  set_Xcommand_set     : {
> +    __start_set_Xcommand_set = .;
> +    *(set_Xcommand_set)
> +    __stop_set_Xcommand_set = .;
> +  }
> +  set_Xficl_compile_set        : {
> +    __start_set_Xficl_compile_set = .;
> +    *(set_Xficl_compile_set)
> +    __stop_set_Xficl_compile_set = .;
> +  }
> +  . = ALIGN(16);
> +  .sdata       : {
> +    /*
> +     * u-boot expects the gp register to be untouched by the EFI payload, so we
> +     * can't enable this yet.
> +     */
> +    /* __global_pointer$ = . + 0x800; */
> +    *(.got.plt .got)
> +    *(.sdata .sdata.* .gnu.linkonce.s.*)
> +    *(dynsbss)
> +    *(.scommon)
> +  }
> +  . = ALIGN(16);
> +  .dynamic     : { *(.dynamic) }
> +  . = ALIGN(16);
> +  .rela.dyn    : {
> +    *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
> +    *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
> +    *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
> +    *(.rela.got)
> +    *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
> +    *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
> +    *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
> +    *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
> +    *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
> +    *(.rela.plt)
> +    *(.relset_*)
> +    *(.rela.dyn .rela.dyn.*)
> +  }
> +  . = ALIGN(16);
> +  .reloc       : { *(.reloc) }
> +  . = ALIGN(16);
> +  .dynsym      : { *(.dynsym) }
> +  _edata = .;
> +
> +  /* Unused sections */
> +  .dynstr      : { *(.dynstr) }
> +  .hash                : { *(.hash) }
> +}
>
> Added: head/stand/efi/loader/arch/riscv/start.S
> ==============================================================================
> --- /dev/null   00:00:00 1970   (empty, because file is newly added)
> +++ head/stand/efi/loader/arch/riscv/start.S    Mon Jul  6 18:19:42 2020        (r362973)
> @@ -0,0 +1,168 @@
> +/*-
> + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
> + *
> + * Copyright (c) 2020 Mitchell Horne <mhorne at 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.
> + *
> + * $FreeBSD$
> + */
> +
> +#include <machine/asm.h>
> +
> +/*
> + * We need to be a PE32+ file for EFI. On some architectures we can use
> + * objcopy to create the correct file, however on RISC-V we need to do
> + * it ourselves.
> + */
> +
> +#define        IMAGE_FILE_MACHINE_RISCV64      0x5064
> +
> +#define        IMAGE_SCN_CNT_CODE              0x00000020
> +#define        IMAGE_SCN_CNT_INITIALIZED_DATA  0x00000040
> +#define        IMAGE_SCN_MEM_DISCARDABLE       0x02000000
> +#define        IMAGE_SCN_MEM_EXECUTE           0x20000000
> +#define        IMAGE_SCN_MEM_READ              0x40000000
> +
> +       .section .peheader,"a"
> +efi_start:
> +       /* The MS-DOS Stub, only used to get the offset of the COFF header */
> +       .ascii  "MZ"
> +       .short  0
> +       .space  0x38
> +       .long   pe_sig - efi_start
> +
> +       /* The PE32 Signature. Needs to be 8-byte aligned */
> +       .align  3
> +pe_sig:
> +       .ascii  "PE"
> +       .short  0
> +coff_head:
> +       .short  IMAGE_FILE_MACHINE_RISCV64      /* RISC-V 64 file */
> +       .short  2                               /* 2 Sections */
> +       .long   0                               /* Timestamp */
> +       .long   0                               /* No symbol table */
> +       .long   0                               /* No symbols */
> +       .short  section_table - optional_header /* Optional header size */
> +       .short  0       /* Characteristics TODO: Fill in */
> +
> +optional_header:
> +       .short  0x020b                          /* PE32+ (64-bit addressing) */
> +       .byte   0                               /* Major linker version */
> +       .byte   0                               /* Minor linker version */
> +       .long   _edata - _end_header            /* Code size */
> +       .long   0                               /* No initialized data */
> +       .long   0                               /* No uninitialized data */
> +       .long   _start - efi_start              /* Entry point */
> +       .long   _end_header - efi_start         /* Start of code */
> +
> +optional_windows_header:
> +       .quad   0                               /* Image base */
> +       .long   32                              /* Section Alignment */
> +       .long   8                               /* File alignment */
> +       .short  0                               /* Major OS version */
> +       .short  0                               /* Minor OS version */
> +       .short  0                               /* Major image version */
> +       .short  0                               /* Minor image version */
> +       .short  0                               /* Major subsystem version */
> +       .short  0                               /* Minor subsystem version */
> +       .long   0                               /* Win32 version */
> +       .long   _edata - efi_start              /* Image size */
> +       .long   _end_header - efi_start         /* Header size */
> +       .long   0                               /* Checksum */
> +       .short  0xa                             /* Subsystem (EFI app) */
> +       .short  0                               /* DLL Characteristics */
> +       .quad   0                               /* Stack reserve */
> +       .quad   0                               /* Stack commit */
> +       .quad   0                               /* Heap reserve */
> +       .quad   0                               /* Heap commit */
> +       .long   0                               /* Loader flags */
> +       .long   6                               /* Number of RVAs */
> +
> +       /* RVAs: */
> +       .quad   0
> +       .quad   0
> +       .quad   0
> +       .quad   0
> +       .quad   0
> +       .quad   0
> +
> +section_table:
> +       /* We need a .reloc section for EFI */
> +       .ascii  ".reloc"
> +       .byte   0
> +       .byte   0                               /* Pad to 8 bytes */
> +       .long   0                               /* Virtual size */
> +       .long   0                               /* Virtual address */
> +       .long   0                               /* Size of raw data */
> +       .long   0                               /* Pointer to raw data */
> +       .long   0                               /* Pointer to relocations */
> +       .long   0                               /* Pointer to line numbers */
> +       .short  0                               /* Number of relocations */
> +       .short  0                               /* Number of line numbers */
> +       .long   (IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | \
> +                IMAGE_SCN_MEM_DISCARDABLE)     /* Characteristics */
> +
> +       /* The contents of the loader */
> +       .ascii  ".text"
> +       .byte   0
> +       .byte   0
> +       .byte   0                               /* Pad to 8 bytes */
> +       .long   _edata - _end_header            /* Virtual size */
> +       .long   _end_header - efi_start         /* Virtual address */
> +       .long   _edata - _end_header            /* Size of raw data */
> +       .long   _end_header - efi_start         /* Pointer to raw data */
> +       .long   0                               /* Pointer to relocations */
> +       .long   0                               /* Pointer to line numbers */
> +       .short  0                               /* Number of relocations */
> +       .short  0                               /* Number of line numbers */
> +       .long   (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | \
> +                IMAGE_SCN_MEM_READ)            /* Characteristics */
> +_end_header:
> +
> +       .text
> +       .globl  _start
> +_start:
> +       /* Save the boot params to the stack */
> +       addi    sp, sp, -16
> +       sd      a0, 0(sp)
> +       sd      a1, 8(sp)
> +
> +       /* Zero the BSS */
> +       lla     t0, __bss_start
> +       lla     t1, __bss_end
> +
> +1:     sd      zero, 0(t0)
> +       addi    t0, t0, 8
> +       bltu    t0, t1, 1b
> +
> +       lla     a0, ImageBase
> +       lla     a1, _DYNAMIC
> +       call    _C_LABEL(self_reloc)
> +
> +       ld      a1, 8(sp)
> +       ld      a0, 0(sp)
> +       tail    _C_LABEL(efi_main)
> +
> +       /* NOTREACHED */
> +2:     wfi
> +       j       2b
>
> Modified: head/stand/efi/loader/copy.c
> ==============================================================================
> --- head/stand/efi/loader/copy.c        Mon Jul  6 17:47:29 2020        (r362972)
> +++ head/stand/efi/loader/copy.c        Mon Jul  6 18:19:42 2020        (r362973)
> @@ -227,7 +227,7 @@ efi_copy_init(void)
>         staging_base = staging;
>         staging_end = staging + nr_pages * EFI_PAGE_SIZE;
>
> -#if defined(__aarch64__) || defined(__arm__)
> +#if defined(__aarch64__) || defined(__arm__) || defined(__riscv)
>         /*
>          * Round the kernel load address to a 2MiB value. This is needed
>          * because the kernel builds a page table based on where it has
> @@ -277,7 +277,7 @@ before_staging:
>                 return (false);
>         }
>         addr = staging - nr_pages * EFI_PAGE_SIZE;
> -#if defined(__aarch64__) || defined(__arm__)
> +#if defined(__aarch64__) || defined(__arm__) || defined(__riscv)
>         /* See efi_copy_init for why this is needed */
>         addr = rounddown2(addr, 2 * 1024 * 1024);
>  #endif
> @@ -343,6 +343,11 @@ efi_copyout(const vm_offset_t src, void *dest, const s
>  ssize_t
>  efi_readin(readin_handle_t fd, vm_offset_t dest, const size_t len)
>  {
> +
> +       if (!stage_offset_set) {
> +               stage_offset = (vm_offset_t)staging - dest;
> +               stage_offset_set = 1;
> +       }
>
>         if (!efi_check_space(dest + stage_offset + len)) {
>                 errno = ENOMEM;
>
> Modified: head/stand/efi/loader/main.c
> ==============================================================================
> --- head/stand/efi/loader/main.c        Mon Jul  6 17:47:29 2020        (r362972)
> +++ head/stand/efi/loader/main.c        Mon Jul  6 18:19:42 2020        (r362973)
> @@ -912,7 +912,7 @@ main(int argc, CHAR16 *argv[])
>          */
>         setenv("console", "efi", 1);
>         uhowto = parse_uefi_con_out();
> -#if defined(__aarch64__) || defined(__arm__)
> +#if defined(__aarch64__) || defined(__arm__) || defined(__riscv)
>         if ((uhowto & RB_SERIAL) != 0)
>                 setenv("console", "comconsole", 1);
>  #endif
>
> Modified: head/stand/loader.mk
> ==============================================================================
> --- head/stand/loader.mk        Mon Jul  6 17:47:29 2020        (r362972)
> +++ head/stand/loader.mk        Mon Jul  6 18:19:42 2020        (r362973)
> @@ -25,6 +25,9 @@ SRCS+=        metadata.c
>  .elif ${MACHINE} == "mips"
>  SRCS+= load_elf32.c reloc_elf32.c
>  SRCS+= metadata.c
> +.elif ${MACHINE_CPUARCH} == "riscv"
> +SRCS+= load_elf64.c reloc_elf64.c
> +SRCS+= metadata.c
>  .endif
>
>  .if ${LOADER_DISK_SUPPORT:Uyes} == "yes"
>
> Modified: head/sys/riscv/include/metadata.h
> ==============================================================================
> --- head/sys/riscv/include/metadata.h   Mon Jul  6 17:47:29 2020        (r362972)
> +++ head/sys/riscv/include/metadata.h   Mon Jul  6 18:19:42 2020        (r362973)
> @@ -30,6 +30,28 @@
>  #ifndef _MACHINE_METADATA_H_
>  #define        _MACHINE_METADATA_H_
>
> -#define        MODINFOMD_DTBP  0x1001
> +#define        MODINFOMD_DTBP          0x1001
> +#define        MODINFOMD_EFI_MAP       0x1002
> +
> +struct efi_map_header {
> +       size_t          memory_size;
> +       size_t          descriptor_size;
> +       uint32_t        descriptor_version;
> +};
> +
> +/*
> + * Placeholder for now
> + */
> +struct efi_fb {
> +       uint64_t        fb_addr;
> +       uint64_t        fb_size;
> +       uint32_t        fb_height;
> +       uint32_t        fb_width;
> +       uint32_t        fb_stride;
> +       uint32_t        fb_mask_red;
> +       uint32_t        fb_mask_green;
> +       uint32_t        fb_mask_blue;
> +       uint32_t        fb_mask_reserved;
> +};
>
>  #endif /* !_MACHINE_METADATA_H_ */


More information about the svn-src-head mailing list