From owner-svn-src-all@freebsd.org Mon Jul 6 18:26:51 2020 Return-Path: Delivered-To: svn-src-all@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 3545036DA56; Mon, 6 Jul 2020 18:26:51 +0000 (UTC) (envelope-from mhorne@freebsd.org) Received: from smtp.freebsd.org (smtp.freebsd.org [96.47.72.83]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "smtp.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4B0vDC0xL6z4NPk; Mon, 6 Jul 2020 18:26:51 +0000 (UTC) (envelope-from mhorne@freebsd.org) Received: from mail-yb1-f175.google.com (mail-yb1-f175.google.com [209.85.219.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "GTS CA 1O1" (verified OK)) (Authenticated sender: mhorne) by smtp.freebsd.org (Postfix) with ESMTPSA id EEC95249DE; Mon, 6 Jul 2020 18:26:50 +0000 (UTC) (envelope-from mhorne@freebsd.org) Received: by mail-yb1-f175.google.com with SMTP id y13so19391785ybj.10; Mon, 06 Jul 2020 11:26:50 -0700 (PDT) X-Gm-Message-State: AOAM533AFWROifMzdY6h7r08LOq1PFetA0rKRcjv6xLcJZr2/yr+PPvl /iWSHib5HcD/0NTKYhkEFjfMVOVnu/xPPeanS74= X-Google-Smtp-Source: ABdhPJwmK0YJ7k4uG78Gg+5WlMg8Rj+dZP+k6UldZyWZcj7gf6+23RbzHmR9G39RCRQqUvUfRpb7QgX0t/gKSLaXuUI= X-Received: by 2002:a25:3851:: with SMTP id f78mr81569403yba.212.1594060009740; Mon, 06 Jul 2020 11:26:49 -0700 (PDT) MIME-Version: 1.0 References: <202007061819.066IJhE0050151@repo.freebsd.org> In-Reply-To: <202007061819.066IJhE0050151@repo.freebsd.org> From: Mitchell Horne Date: Mon, 6 Jul 2020 15:26:38 -0300 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: 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 To: Mitchell Horne Cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Content-Type: text/plain; charset="UTF-8" X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Jul 2020 18:26:51 -0000 On Mon, Jul 6, 2020 at 3:19 PM Mitchell Horne 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 > #include > > -#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 > +#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 > + * > + * 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 > + > +/* > + * 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_ */