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