Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Jul 2020 18:19:43 +0000 (UTC)
From:      Mitchell Horne <mhorne@FreeBSD.org>
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
Message-ID:  <202007061819.066IJhE0050151@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <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@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_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202007061819.066IJhE0050151>