Add support for arm64 to loader.efi and boot1.efi
Reviewed by: emaste Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
30dd368aa7
commit
0cafabf97f
1
sys/arm64/include/psl.h
Normal file
1
sys/arm64/include/psl.h
Normal file
@ -0,0 +1 @@
|
||||
/* $FreeBSD$ */
|
7
sys/boot/Makefile.arm64
Normal file
7
sys/boot/Makefile.arm64
Normal file
@ -0,0 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.if ${MK_FDT} != "no"
|
||||
SUBDIR+= fdt
|
||||
.endif
|
||||
|
||||
SUBDIR+= efi
|
3
sys/boot/arm64/Makefile
Normal file
3
sys/boot/arm64/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.include <bsd.subdir.mk>
|
95
sys/boot/arm64/libarm64/cache.c
Normal file
95
sys/boot/arm64/libarm64/cache.c
Normal file
@ -0,0 +1,95 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Semihalf under
|
||||
* the sponsorship of the FreeBSD Foundation.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <machine/armreg.h>
|
||||
|
||||
#include <stand.h>
|
||||
#include <efi.h>
|
||||
|
||||
#include "cache.h"
|
||||
|
||||
static unsigned int
|
||||
get_dcache_line_size(void)
|
||||
{
|
||||
uint64_t ctr;
|
||||
unsigned int dcl_size;
|
||||
|
||||
/* Accessible from all security levels */
|
||||
ctr = READ_SPECIALREG(ctr_el0);
|
||||
|
||||
/*
|
||||
* Relevant field [19:16] is LOG2
|
||||
* of the number of words in DCache line
|
||||
*/
|
||||
dcl_size = CTR_DLINE_SIZE(ctr);
|
||||
|
||||
/* Size of word shifted by cache line size */
|
||||
return (sizeof(int) << dcl_size);
|
||||
}
|
||||
|
||||
void
|
||||
cpu_flush_dcache(const void *ptr, size_t len)
|
||||
{
|
||||
|
||||
uint64_t cl_size;
|
||||
vm_offset_t addr, end;
|
||||
|
||||
cl_size = get_dcache_line_size();
|
||||
|
||||
/* Calculate end address to clean */
|
||||
end = (vm_offset_t)(ptr + len);
|
||||
/* Align start address to cache line */
|
||||
addr = (vm_offset_t)ptr;
|
||||
addr = rounddown2(addr, cl_size);
|
||||
|
||||
for (; addr < end; addr += cl_size)
|
||||
__asm __volatile("dc civac, %0" : : "r" (addr) : "memory");
|
||||
/* Full system DSB */
|
||||
__asm __volatile("dsb sy" : : : "memory");
|
||||
}
|
||||
|
||||
void
|
||||
cpu_inval_icache(const void *ptr, size_t len)
|
||||
{
|
||||
|
||||
/* NULL ptr or 0 len means all */
|
||||
if (ptr == NULL || len == 0) {
|
||||
__asm __volatile(
|
||||
"ic ialluis \n"
|
||||
"dsb ish \n"
|
||||
: : : "memory");
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: Other cache ranges if necessary */
|
||||
}
|
38
sys/boot/arm64/libarm64/cache.h
Normal file
38
sys/boot/arm64/libarm64/cache.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Semihalf under
|
||||
* the sponsorship of the FreeBSD Foundation.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#ifndef _CACHE_H_
|
||||
#define _CACHE_H_
|
||||
|
||||
/* cache.c */
|
||||
void cpu_flush_dcache(const void *, size_t);
|
||||
void cpu_inval_icache(const void *, size_t);
|
||||
|
||||
#endif /* _CACHE_H_ */
|
@ -9,6 +9,8 @@ SRCS+= load_elf32.c load_elf32_obj.c reloc_elf32.c
|
||||
SRCS+= load_elf64.c load_elf64_obj.c reloc_elf64.c
|
||||
.elif ${MACHINE} == "pc98"
|
||||
SRCS+= load_elf32.c load_elf32_obj.c reloc_elf32.c
|
||||
.elif ${MACHINE_CPUARCH} == "aarch64"
|
||||
SRCS+= load_elf64.c reloc_elf64.c
|
||||
.elif ${MACHINE_CPUARCH} == "arm"
|
||||
SRCS+= load_elf32.c reloc_elf32.c
|
||||
.elif ${MACHINE_CPUARCH} == "powerpc"
|
||||
|
@ -10,7 +10,9 @@ SUBDIR+= fdt
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "arm"
|
||||
.if ${MACHINE_CPUARCH} == "aarch64" || \
|
||||
${MACHINE_CPUARCH} == "amd64" || \
|
||||
${MACHINE_CPUARCH} == "arm"
|
||||
SUBDIR+= loader boot1
|
||||
.endif
|
||||
|
||||
|
26
sys/boot/efi/boot1/fat-arm64.tmpl.bz2.uu
Normal file
26
sys/boot/efi/boot1/fat-arm64.tmpl.bz2.uu
Normal file
@ -0,0 +1,26 @@
|
||||
FAT template boot filesystem created by generate-fat.sh
|
||||
DO NOT EDIT
|
||||
$FreeBSD$
|
||||
begin 644 fat-arm64.tmpl.bz2
|
||||
M0EIH.3%!62936:2BH:(`&T#_____ZZKJ[_^N_ZO_J_Z[OJ_NJ^JK^KZNKNNJ
|
||||
MZNKNZOJ^P`+\```"``:`9,@T&F3$,@!B`,AIHP$#0-`T``,09--&31IH9#)D
|
||||
M,(#$T&)B!A``-`,F0:#3)B&0`Q`&0TT8"!H&@:``&(,FFC)HTT,ADR&$!B:#
|
||||
M$Q`P@`&@&3(-!IDQ#(`8@#(::,!`T#0-``#$&331DT::&0R9#"`Q-!B8@8"J
|
||||
M*0GY$I&GH"-&AZ@T```T`:`!HT```&@&@-,C0`-`#U,(-`&)ZF(PGIJ>IO;U
|
||||
M^=&QL3`-\E@Q+$(RTHB$7I"(B(-W:73$0@A#;S##$3$`A#FL\LAF,;&8;[CE
|
||||
M&D=@ON\:9IWHO):QK7LL=LFN;1M6Y:%F>-1G^&O-A*(@0AQ,\#H*KRCJF>9Q
|
||||
MFF_,RWU4X-,R6K5EJU:M6L"JMB5555555JVJU*U-JU:M6MUB*I555555;XHJ
|
||||
ME555555YM='L;(N7+ERY<N4****************.2B55555555%%%%%%%%"B
|
||||
MBBBBBC#S/DW+ERY<N7+E&NE55555550HHHHHHHS_(SQEG'X7.OTSKFY=#*]*
|
||||
M9?C*,7MM&JO=0EIDQW:7C-0U;WGRM>_!^S^F[=KA#3YJ.S-)`!>O]K)`#-ZO
|
||||
MU=9T,X(@!H',-+,1Q'-6'#ZNQORGURS=]_O%.6SF5G,PC`G#X_@7W$RC>2Q)
|
||||
M9MW3P&G:AJFA?`^AKWXOV?R_QDL9F^`=5H>$UWWT9K&Q/HS.!KXB)U)9$6,)
|
||||
M*/!EJ7>+W2L65_C\&LP69G$?'M$18.(LL.G:AZ;%>TUKYF.V+9/W9AMF[<VT
|
||||
MS/X;%DL?1SW5Y]4L]R=+RLNCTMB[6_5C8C2+?DPWF/F.G]WN[5+:G4UOWC%E
|
||||
M*3V7BO??&^=COL?:V3]&T9#<-XWKX3\,BQ#[KW01%D(X'O<#8?*B.`D]1J&O
|
||||
M>&^]HFB?J_AM6V;ANF2RG7,61I)?])L35<Y8C.RWDHV3\GZOW;-TC:MLW#<O
|
||||
MG;QDO2<6_S5;,T$1["/3W^^]&4;3*_F\:?7"90R&E;=N']O@;ENF[?ZR6Q93
|
||||
M_F6SAO9,N65+9R:#69>2^EX5C12BSAX@$(3`!EWEZ6P2R$9#_Q=R13A0D*2B
|
||||
"H:(`
|
||||
`
|
||||
end
|
@ -18,7 +18,7 @@ BOOT1_SIZE=128k
|
||||
#
|
||||
# Known filenames
|
||||
# amd64: BOOTx64.efi
|
||||
# aarch64: BOOTaa64.efi
|
||||
# arm64: BOOTaa64.efi
|
||||
# arm: BOOTarm.efi
|
||||
# i386: BOOTia32.efi
|
||||
#
|
||||
|
219
sys/boot/efi/include/arm64/efibind.h
Normal file
219
sys/boot/efi/include/arm64/efibind.h
Normal file
@ -0,0 +1,219 @@
|
||||
/* $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
|
||||
|
||||
#if _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
|
||||
|
||||
#pragma intrinsic (__break)
|
||||
#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
|
||||
#if _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 accross compliers.
|
||||
//
|
||||
void __mfa (void);
|
||||
#pragma intrinsic (__mfa)
|
||||
#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 similiar 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
|
@ -42,7 +42,7 @@ CFLAGS+= -DNO_PCI -DEFI
|
||||
BOOT_FORTH= yes
|
||||
CFLAGS+= -DBOOT_FORTH
|
||||
CFLAGS+= -I${.CURDIR}/../../ficl
|
||||
CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE}
|
||||
CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE_CPUARCH}
|
||||
LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
|
||||
.endif
|
||||
|
||||
|
9
sys/boot/efi/loader/arch/arm64/Makefile.inc
Normal file
9
sys/boot/efi/loader/arch/arm64/Makefile.inc
Normal file
@ -0,0 +1,9 @@
|
||||
# $FreeBSD$
|
||||
|
||||
LOADER_FDT_SUPPORT=yes
|
||||
SRCS+= exec.c \
|
||||
start.S
|
||||
|
||||
.PATH: ${.CURDIR}/../../arm64/libarm64
|
||||
CFLAGS+=-I${.CURDIR}/../../arm64/libarm64
|
||||
SRCS+= cache.c
|
109
sys/boot/efi/loader/arch/arm64/exec.c
Normal file
109
sys/boot/efi/loader/arch/arm64/exec.c
Normal file
@ -0,0 +1,109 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 ``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 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stand.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/linker.h>
|
||||
#include <machine/elf.h>
|
||||
|
||||
#include <bootstrap.h>
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
#include "loader_efi.h"
|
||||
#include "cache.h"
|
||||
|
||||
static int elf64_exec(struct preloaded_file *amp);
|
||||
static int elf64_obj_exec(struct preloaded_file *amp);
|
||||
|
||||
int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp);
|
||||
|
||||
static struct file_format arm64_elf = {
|
||||
elf64_loadfile,
|
||||
elf64_exec
|
||||
};
|
||||
|
||||
struct file_format *file_formats[] = {
|
||||
&arm64_elf,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int
|
||||
elf64_exec(struct preloaded_file *fp)
|
||||
{
|
||||
vm_offset_t modulep, kernendp;
|
||||
vm_offset_t clean_addr;
|
||||
size_t clean_size;
|
||||
struct file_metadata *md;
|
||||
EFI_STATUS status;
|
||||
EFI_PHYSICAL_ADDRESS addr;
|
||||
Elf_Ehdr *ehdr;
|
||||
int err;
|
||||
void (*entry)(vm_offset_t);
|
||||
|
||||
if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
|
||||
return(EFTYPE);
|
||||
|
||||
ehdr = (Elf_Ehdr *)&(md->md_data);
|
||||
entry = efi_translate(ehdr->e_entry);
|
||||
|
||||
err = bi_load(fp->f_args, &modulep, &kernendp);
|
||||
if (err != 0)
|
||||
return (err);
|
||||
|
||||
status = BS->ExitBootServices(IH, efi_mapkey);
|
||||
if (EFI_ERROR(status)) {
|
||||
printf("%s: ExitBootServices() returned 0x%lx\n", __func__,
|
||||
(long)status);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/* Clean D-cache under kernel area and invalidate whole I-cache */
|
||||
clean_addr = efi_translate(fp->f_addr);
|
||||
clean_size = efi_translate(kernendp) - clean_addr;
|
||||
|
||||
cpu_flush_dcache((void *)clean_addr, clean_size);
|
||||
cpu_inval_icache(NULL, 0);
|
||||
|
||||
(*entry)(modulep);
|
||||
panic("exec returned");
|
||||
}
|
||||
|
||||
static int
|
||||
elf64_obj_exec(struct preloaded_file *fp)
|
||||
{
|
||||
|
||||
printf("%s called for preloaded file %p (=%s):\n", __func__, fp,
|
||||
fp->f_name);
|
||||
return (ENOSYS);
|
||||
}
|
||||
|
80
sys/boot/efi/loader/arch/arm64/ldscript.arm64
Normal file
80
sys/boot/efi/loader/arch/arm64/ldscript.arm64
Normal file
@ -0,0 +1,80 @@
|
||||
/* $FreeBSD$ */
|
||||
/*
|
||||
OUTPUT_FORMAT("elf64-aarch64-freebsd", "elf64-aarch64-freebsd", "elf64-aarch64-freebsd")
|
||||
*/
|
||||
OUTPUT_ARCH(aarch64)
|
||||
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)
|
||||
} =0x00300000010070000002000001000400
|
||||
. = 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 = .;
|
||||
}
|
||||
. = ALIGN(16);
|
||||
__gp = .;
|
||||
.sdata : {
|
||||
*(.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) }
|
||||
}
|
165
sys/boot/efi/loader/arch/arm64/start.S
Normal file
165
sys/boot/efi/loader/arch/arm64/start.S
Normal file
@ -0,0 +1,165 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 Andrew Turner
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
/*
|
||||
* We need to be a PE32+ file for EFI. On some architectures we can use
|
||||
* objcopy to create the correct file, however on arm64 we need to do
|
||||
* it ourselves.
|
||||
*/
|
||||
|
||||
#define IMAGE_FILE_MACHINE_ARM64 0xaa64
|
||||
|
||||
#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
|
||||
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_ARM64 /* AArch64 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 */
|
||||
stp x0, x1, [sp, #-16]!
|
||||
|
||||
adr x0, __bss_start
|
||||
adr x1, __bss_end
|
||||
|
||||
b 2f
|
||||
|
||||
1:
|
||||
stp xzr, xzr, [x0], #16
|
||||
2:
|
||||
cmp x0, x1
|
||||
b.lo 1b
|
||||
|
||||
adr x0, ImageBase
|
||||
adr x1, _DYNAMIC
|
||||
|
||||
bl _reloc
|
||||
|
||||
ldp x0, x1, [sp], #16
|
||||
|
||||
bl efi_main
|
||||
|
||||
1: b 1b
|
@ -61,8 +61,14 @@ efi_copy_init(void)
|
||||
}
|
||||
staging_end = staging + STAGE_PAGES * 4096;
|
||||
|
||||
#ifdef __arm__
|
||||
/* Round the kernel load address to a 2MiB value */
|
||||
#if defined(__aarch64__) || defined(__arm__)
|
||||
/*
|
||||
* Round the kernel load address to a 2MiB value. This is needed
|
||||
* because the kernel builds a page table based on where it has
|
||||
* been loaded in physical address space. As the kernel will use
|
||||
* either a 1MiB or 2MiB page for this we need to make sure it
|
||||
* is correctly aligned for both cases.
|
||||
*/
|
||||
staging = roundup2(staging, 2 * 1024 * 1024);
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user