From owner-svn-src-all@freebsd.org Mon Jul 6 18:19:46 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 0C79036D659; Mon, 6 Jul 2020 18:19:46 +0000 (UTC) (envelope-from mhorne@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4B0v416mQfz4N0v; Mon, 6 Jul 2020 18:19:45 +0000 (UTC) (envelope-from mhorne@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id CABB9227D4; Mon, 6 Jul 2020 18:19:45 +0000 (UTC) (envelope-from mhorne@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 066IJjHX050165; Mon, 6 Jul 2020 18:19:45 GMT (envelope-from mhorne@FreeBSD.org) Received: (from mhorne@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 066IJhE0050151; Mon, 6 Jul 2020 18:19:43 GMT (envelope-from mhorne@FreeBSD.org) Message-Id: <202007061819.066IJhE0050151@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mhorne set sender to mhorne@FreeBSD.org using -f From: Mitchell Horne Date: Mon, 6 Jul 2020 18:19:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: 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 X-SVN-Group: head X-SVN-Commit-Author: mhorne X-SVN-Commit-Paths: 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 X-SVN-Commit-Revision: 362973 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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:19:46 -0000 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 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_ */