From mboxrd@z Thu Jan 1 00:00:00 1970 From: Roy Franz Subject: Re: [PATCH V4 15/15] Add ARM EFI boot support Date: Thu, 11 Sep 2014 20:21:00 -0700 Message-ID: References: <1410310325-4509-1-git-send-email-roy.franz@linaro.org> <1410310325-4509-16-git-send-email-roy.franz@linaro.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============5132891646511509130==" Return-path: In-Reply-To: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Stefano Stabellini Cc: keir , Ian Campbell , tim , xen-devel , Stefano Stabellini , Jan Beulich , Fu Wei List-Id: xen-devel@lists.xenproject.org --===============5132891646511509130== Content-Type: multipart/alternative; boundary=001a11c3584a3e8ed20502d5c699 --001a11c3584a3e8ed20502d5c699 Content-Type: text/plain; charset=UTF-8 On Thu, Sep 11, 2014 at 5:49 PM, Stefano Stabellini < stefano.stabellini@eu.citrix.com> wrote: > On Tue, 9 Sep 2014, Roy Franz wrote: > > This patch adds EFI boot support for ARM based on the previous > refactoring of > > the x86 EFI boot code. All ARM specific code is in the ARM efi-boot.h > header > > file, with the main EFI entry point common/efi/boot.c. The PE/COFF > header is > > open-coded in head.S, which allows us to have a single binary be both an > EFI > > executable and a normal arm64 IMAGE file. There is currently no PE/COFF > > toolchain support for arm64, so it is not possible to create the PE/COFF > header > > in the same manner as on x86. This also simplifies the build as > compared to > > x86, as we always build the same executable, whereas x86 builds 2. An > ARM > > version of efi-bind.h is added, which is based on the x86_64 version > with the > > x86 specific portions removed. The Makefile in common/efi is different > for x86 > > and ARM, as for ARM we always build in EFI support. > > > > Signed-off-by: Roy Franz > > --- > > config/arm64.mk | 1 + > > xen/arch/arm/arm64/head.S | 150 ++++++++- > > xen/arch/arm/xen.lds.S | 1 + > > xen/common/Makefile | 1 + > > xen/common/efi/Makefile | 3 + > > xen/include/asm-arm/arm64/efibind.h | 216 +++++++++++++ > > xen/include/asm-arm/efi-boot.h | 630 > ++++++++++++++++++++++++++++++++++++ > > xen/include/asm-arm/efi.h | 29 ++ > > xen/include/asm-arm/efibind.h | 2 + > > xen/include/asm-arm/setup.h | 2 +- > > 10 files changed, 1031 insertions(+), 4 deletions(-) > > create mode 100644 xen/common/efi/Makefile > > create mode 100644 xen/include/asm-arm/arm64/efibind.h > > create mode 100644 xen/include/asm-arm/efi-boot.h > > create mode 100644 xen/include/asm-arm/efi.h > > create mode 100644 xen/include/asm-arm/efibind.h > > > > diff --git a/config/arm64.mk b/config/arm64.mk > > index 15b57a4..e6aab0e 100644 > > --- a/config/arm64.mk > > +++ b/config/arm64.mk > > @@ -1,6 +1,7 @@ > > CONFIG_ARM := y > > CONFIG_ARM_64 := y > > CONFIG_ARM_$(XEN_OS) := y > > +CONFIG_EFI := y > > > > CONFIG_XEN_INSTALL_SUFFIX := > > > > diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S > > index 43b5e72..158c102 100644 > > --- a/xen/arch/arm/arm64/head.S > > +++ b/xen/arch/arm/arm64/head.S > > @@ -24,6 +24,8 @@ > > #include > > #include > > #include > > +#include > > +#include > > > > #define PT_PT 0xf7f /* nG=1 AF=1 SH=11 AP=01 NS=1 ATTR=111 T=1 P=1 > */ > > #define PT_MEM 0xf7d /* nG=1 AF=1 SH=11 AP=01 NS=1 ATTR=111 T=0 P=1 > */ > > @@ -104,8 +106,14 @@ GLOBAL(start) > > /* > > * DO NOT MODIFY. Image header expected by Linux boot-loaders. > > */ > > - b real_start /* branch to kernel start, magic */ > > - .long 0 /* reserved */ > > +efi_head: > > + /* > > + * This add instruction has no meaningful effect except that > > + * its opcode forms the magic "MZ" signature of a PE/COFF file > > + * that is required for UEFI applications. > > + */ > > + add x13, x18, #0x16 > > + b real_start /* branch to kernel start */ > > .quad 0 /* Image load offset from start of > RAM */ > > .quad 0 /* reserved */ > > .quad 0 /* reserved */ > > @@ -116,8 +124,113 @@ GLOBAL(start) > > .byte 0x52 > > .byte 0x4d > > .byte 0x64 > > - .word 0 /* reserved */ > > + .long pe_header - efi_head /* Offset to the PE header. > */ > > + > > + /* > > + * Add the PE/COFF header to the file. The address of this > header > > + * is at offset 0x3c in the file, and is part of Linux "Image" > > + * header. The arm64 Linux Image format is designed to support > > + * being both an 'Image' format binary and a PE/COFF binary. > > + * The PE/COFF format is defined by Microsoft, and is available > > + * from: http://msdn.microsoft.com/en-us/gg463119.aspx > > + * Version 8.3 adds support for arm64 and UEFI usage. > > + */ > > + > > + .align 3 > > +pe_header: > > + .ascii "PE" > > + .short 0 > > +coff_header: > > + .short 0xaa64 /* AArch64 */ > > + .short 2 /* nr_sections */ > > + .long 0 /* TimeDateStamp */ > > + .long 0 /* PointerToSymbolTable > */ > > + .long 1 /* NumberOfSymbols */ > > + .short section_table - optional_header /* SizeOfOptionalHeader > */ > > + .short 0x206 /* Characteristics. */ > > + /* > IMAGE_FILE_DEBUG_STRIPPED | */ > > + /* > IMAGE_FILE_EXECUTABLE_IMAGE | */ > > + /* > IMAGE_FILE_LINE_NUMS_STRIPPED */ > > +optional_header: > > + .short 0x20b /* PE32+ format */ > > + .byte 0x02 /* MajorLinkerVersion */ > > + .byte 0x14 /* MinorLinkerVersion */ > > + .long _end - real_start /* SizeOfCode */ > > + .long 0 /* > SizeOfInitializedData */ > > + .long 0 /* > SizeOfUninitializedData */ > > + .long efi_start - efi_head /* AddressOfEntryPoint > */ > > + .long real_start - efi_head /* BaseOfCode */ > > + > > +extra_header_fields: > > + .quad 0 /* ImageBase */ > > + .long 0x1000 /* SectionAlignment (4 > KByte) */ > > + .long 0x8 /* FileAlignment */ > > + .short 0 /* > MajorOperatingSystemVersion */ > > + .short 0 /* > MinorOperatingSystemVersion */ > > + .short 0 /* MajorImageVersion */ > > + .short 0 /* MinorImageVersion */ > > + .short 0 /* > MajorSubsystemVersion */ > > + .short 0 /* > MinorSubsystemVersion */ > > + .long 0 /* Win32VersionValue */ > > + > > + .long _end - efi_head /* SizeOfImage */ > > + > > + /* Everything before the kernel image is considered part of the > header */ > > + .long real_start - efi_head /* SizeOfHeaders */ > > + .long 0 /* CheckSum */ > > + .short 0xa /* Subsystem (EFI > application) */ > > + .short 0 /* DllCharacteristics */ > > + .quad 0 /* SizeOfStackReserve */ > > + .quad 0 /* SizeOfStackCommit */ > > + .quad 0 /* SizeOfHeapReserve */ > > + .quad 0 /* SizeOfHeapCommit */ > > + .long 0 /* LoaderFlags */ > > + .long 0x6 /* NumberOfRvaAndSizes > */ > > + > > + .quad 0 /* ExportTable */ > > + .quad 0 /* ImportTable */ > > + .quad 0 /* ResourceTable */ > > + .quad 0 /* ExceptionTable */ > > + .quad 0 /* CertificationTable */ > > + .quad 0 /* BaseRelocationTable > */ > > + > > + /* Section table */ > > +section_table: > > > > + /* > > + * The EFI application loader requires a relocation section > > + * because EFI applications must be relocatable. This is a > > + * dummy section as far as we are concerned. > > + */ > > + .ascii ".reloc" > > + .byte 0 > > + .byte 0 /* end of 0 padding of > section name */ > > + .long 0 > > + .long 0 > > + .long 0 /* SizeOfRawData */ > > + .long 0 /* PointerToRawData */ > > + .long 0 /* PointerToRelocations > */ > > + .long 0 /* PointerToLineNumbers > */ > > + .short 0 /* NumberOfRelocations > */ > > + .short 0 /* NumberOfLineNumbers > */ > > + .long 0x42100040 /* Characteristics > (section flags) */ > > + > > + > > + .ascii ".text" > > + .byte 0 > > + .byte 0 > > + .byte 0 /* end of 0 padding of > section name */ > > + .long _end - real_start /* VirtualSize */ > > + .long real_start - efi_head /* VirtualAddress */ > > + .long __init_end_efi - real_start /* SizeOfRawData */ > > + .long real_start - efi_head /* PointerToRawData */ > > + > > + .long 0 /* PointerToRelocations (0 for > executables) */ > > + .long 0 /* PointerToLineNumbers (0 for > executables) */ > > + .short 0 /* NumberOfRelocations (0 for > executables) */ > > + .short 0 /* NumberOfLineNumbers (0 for > executables) */ > > + .long 0xe0500020 /* Characteristics (section flags) */ > > + .align 5 > > real_start: > > msr DAIFSet, 0xf /* Disable all interrupts */ > > > > @@ -617,6 +730,37 @@ putn: ret > > ENTRY(lookup_processor_type) > > mov x0, #0 > > ret > > +/* > > + * Function to transition from EFI loader in C, to Xen entry point. > > + * void noreturn efi_xen_start(void *fdt_ptr); > > + */ > > +ENTRY(efi_xen_start) > > + /* > > + * Turn off cache and MMU as Xen expects. EFI enables them, but > also > > + * mandates a 1:1 (unity) VA->PA mapping, so we can turn off the > > + * MMU while executing EFI code before entering Xen. > > + * The EFI loader calls this to start Xen. > > + * Preserve x0 (fdf pointer) across call to __flush_dcache_all, > > + * restore for entry into Xen. > > + */ > > + mov x20, x0 > > + bl __flush_dcache_all > > + ic ialluis > > + > > + /* Turn off Dcache and MMU */ > > + mrs x0, sctlr_el2 > > + bic x0, x0, #1 << 0 /* clear SCTLR.M */ > > + bic x0, x0, #1 << 2 /* clear SCTLR.C */ > > dsb? > The dsb is done at the end of __flush_dcache_all > > > + msr sctlr_el2, x0 > > + isb > > + > > + /* Jump to Xen entry point */ > > + mov x0, x20 > > + mov x1, xzr > > + mov x2, xzr > > + mov x3, xzr > > + b real_start > > +ENDPROC(efi_xen_start) > > > > /* > > * Local variables: > > diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S > > index 079e085..d8b0cfe 100644 > > --- a/xen/arch/arm/xen.lds.S > > +++ b/xen/arch/arm/xen.lds.S > > @@ -135,6 +135,7 @@ SECTIONS > > *(.xsm_initcall.init) > > __xsm_initcall_end = .; > > } :text > > + __init_end_efi = .; > > . = ALIGN(STACK_SIZE); > > __init_end = .; > > > > diff --git a/xen/common/Makefile b/xen/common/Makefile > > index 3683ae3..e78cb29 100644 > > --- a/xen/common/Makefile > > +++ b/xen/common/Makefile > > @@ -67,4 +67,5 @@ subdir-$(x86_64) += hvm > > subdir-$(coverage) += gcov > > > > subdir-y += libelf > > +subdir-$(CONFIG_EFI) += efi > > subdir-$(HAS_DEVICE_TREE) += libfdt > > diff --git a/xen/common/efi/Makefile b/xen/common/efi/Makefile > > new file mode 100644 > > index 0000000..195b2f3 > > --- /dev/null > > +++ b/xen/common/efi/Makefile > > @@ -0,0 +1,3 @@ > > +CFLAGS += -fshort-wchar > > + > > +obj-y += boot.init.o > > diff --git a/xen/include/asm-arm/arm64/efibind.h > b/xen/include/asm-arm/arm64/efibind.h > > new file mode 100644 > > index 0000000..2b0bf40 > > --- /dev/null > > +++ b/xen/include/asm-arm/arm64/efibind.h > > @@ -0,0 +1,216 @@ > > +/*++ > > + > > +Copyright (c) 1998 Intel Corporation > > + > > +Module Name: > > + > > + efefind.h > > + > > +Abstract: > > + > > + EFI to compile bindings > > + > > + > > + > > + > > +Revision History > > + > > +--*/ > > + > > +#ifndef __GNUC__ > > +#pragma pack() > > +#endif > > + > > +#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 EFI_STUB_ERROR MAX_ADDRESS > > + > > +#ifndef __ASSEMBLY__ > > +// > > +// Basic int types of various widths > > +// > > + > > +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L ) > > + > > + // No ANSI C 1999/2000 stdint.h integer width declarations > > + > > + #if defined(__GNUC__) > > + typedef unsigned long long uint64_t __attribute__((aligned > (8))); > > + typedef long long int64_t __attribute__((aligned > (8))); > > + 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; > > + #elif defined(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 __attribute__((aligned > (8))); > > + typedef long long int64_t __attribute__((aligned (8))); > > + 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 > > + > > +// > > +// Basic EFI types of various widths > > +// > > + > > +#ifndef __WCHAR_TYPE__ > > +# define __WCHAR_TYPE__ short > > +#endif > > + > > +typedef uint64_t UINT64; > > +typedef int64_t INT64; > > + > > +#ifndef _BASETSD_H_ > > + typedef uint32_t UINT32; > > + typedef int32_t INT32; > > +#endif > > + > > +typedef uint16_t UINT16; > > +typedef int16_t INT16; > > +typedef uint8_t UINT8; > > +typedef int8_t INT8; > > +typedef __WCHAR_TYPE__ WCHAR; > > + > > +#undef VOID > > +#define VOID void > > + > > + > > +typedef int64_t INTN; > > +typedef uint64_t UINTN; > > + > > +#define POST_CODE(_Data) > > + > > + > > +#define BREAKPOINT() while (TRUE); // Make it hang on > Bios[Dbg]32 > > + > > +// > > +// Pointers must be aligned to these address to function > > +// > > + > > +#define MIN_ALIGNMENT_SIZE 4 > > + > > +#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 build data structure signatures from characters. > > +// > > + > > +#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)) > > + > > +#define EXPORTAPI > > + > > + > > +// > > +// 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 > > + #define EFIAPI // Substitute expresion to force C > calling convention > > +#endif > > + > > +#define BOOTSERVICE > > +//#define RUNTIMESERVICE(proto,a) alloc_text("rtcode",a); proto a > > +//#define RUNTIMEFUNCTION(proto,a) alloc_text("rtcode",a); proto a > > +#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 > > + > > +#define MEMORY_FENCE() > > + > > + > > +// > > +// When build similiar to FW, then link everything together as > > +// one big module. > > +// > > + > > +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ > > + UINTN \ > > + InitializeDriver ( \ > > + VOID *ImageHandle, \ > > + VOID *SystemTable \ > > + ) \ > > + { \ > > + return InitFunction(ImageHandle, \ > > + SystemTable); \ > > + } \ > > + \ > > + EFI_STATUS efi_main( \ > > + EFI_HANDLE image, \ > > + EFI_SYSTEM_TABLE *systab \ > > + ) __attribute__((weak, \ > > + alias ("InitializeDriver"))); > > + > > +#define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ > > + (_if)->LoadInternal(type, name, entry) > > + > > + > > +// > > +// 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 > > +#ifdef __GNUC__ > > +#define INTERFACE_DECL(x) struct x > > +#else > > +#define INTERFACE_DECL(x) typedef struct x > > +#endif > > +#endif > > + > > +#endif > > + > > +/* > > + * Local variables: > > + * mode: C > > + * c-file-style: "BSD" > > + * c-basic-offset: 4 > > + * tab-width: 4 > > + * indent-tabs-mode: nil > > + * End: > > + */ > > diff --git a/xen/include/asm-arm/efi-boot.h > b/xen/include/asm-arm/efi-boot.h > > new file mode 100644 > > index 0000000..2db0966 > > --- /dev/null > > +++ b/xen/include/asm-arm/efi-boot.h > > @@ -0,0 +1,630 @@ > > +/* > > + * Architecture specific implementation for EFI boot code. This file > > + * is intended to be included by XXX _only_, and therefore can define > > + * arch specific global variables. > > + */ > > +#include > > +#include > > + > > +static void noreturn blexit(const CHAR16 *str); > > +static void PrintErrMesg(const CHAR16 *mesg, EFI_STATUS ErrCode); > > +void noreturn efi_xen_start(void *fdt_ptr); > > + > > +#define DEVICE_TREE_GUID \ > > +{0xb1b621d5, 0xf19c, 0x41a5, {0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, > 0xe0}} > > + > > +static struct file __initdata dtbfile; > > +static void __initdata *fdt; > > +static void __initdata *memmap; > > + > > +static int __init setup_chosen_node(void *fdt, int *addr_cells, int > *size_cells) > > +{ > > + int node; > > + const struct fdt_property *prop; > > + int len; > > + uint32_t val; > > + > > + if ( !fdt || !addr_cells || !size_cells ) > > + return -1; > > + > > + /* locate chosen node, which is where we add Xen module info. */ > > + node = fdt_subnode_offset(fdt, 0, "chosen"); > > + if ( node < 0 ) > > + { > > + node = fdt_add_subnode(fdt, 0, "chosen"); > > + if ( node < 0 ) > > + return node; > > + } > > + > > + /* Get or set #address-cells and #size-cells */ > > + prop = fdt_get_property(fdt, node, "#address-cells", &len); > > + if ( !prop ) > > + { > > + val = cpu_to_fdt32(2); > > + if ( fdt_setprop(fdt, node, "#address-cells", &val, > sizeof(val)) ) > > + return -1; > > + *addr_cells = 2; > > + } > > + else > > + *addr_cells = fdt32_to_cpu(*((uint32_t *)prop->data)); > > + > > + prop = fdt_get_property(fdt, node, "#size-cells", &len); > > + if ( !prop ) > > + { > > + val = cpu_to_fdt32(2); > > + if ( fdt_setprop(fdt, node, "#size-cells", &val, sizeof(val)) ) > > + return -1; > > + *size_cells = 2; > > + } > > + else > > + *size_cells = fdt32_to_cpu(*((uint32_t *)prop->data)); > > + > > + /* > > + * Make sure ranges is empty if it exists, otherwise create empty > ranges > > + * property. > > + */ > > + prop = fdt_get_property(fdt, node, "ranges", &len); > > + if ( !prop ) > > + { > > + val = cpu_to_fdt32(0); > > + if ( fdt_setprop(fdt, node, "ranges", &val, 0) ) > > + return -1; > > + } > > + else if ( fdt32_to_cpu(prop->len) ) > > + return -1; /* Non-empty ranges property */ > > + return node; > > +} > > + > > +/* > > + * Set a single 'reg' property taking into account the > > + * configured addr and size cell sizes. > > + */ > > +static int __init fdt_set_reg(void *fdt, int node, int addr_cells, > > + int size_cells, uint64_t addr, uint64_t > len) > > +{ > > + uint8_t data[16]; /* at most 2 64 bit words */ > > + void *p = data; > > + > > + /* Make sure that the values provided can be represented in > > + * the reg property. > > + */ > > + if ( addr_cells == 1 && (addr >> 32) ) > > + return -1; > > + if ( size_cells == 1 && (len >> 32) ) > > + return -1; > > + > > + if ( addr_cells == 1 ) > > + { > > + *(uint32_t *)p = cpu_to_fdt32(addr); > > + p += sizeof(uint32_t); > > + } > > + else if ( addr_cells == 2 ) > > + { > > + *(uint64_t *)p = cpu_to_fdt64(addr); > > + p += sizeof(uint64_t); > > + } > > + else > > + return -1; > > + > > + if ( size_cells == 1 ) > > + { > > + *(uint32_t *)p = cpu_to_fdt32(len); > > + p += sizeof(uint32_t); > > + } > > + else if ( size_cells == 2 ) > > + { > > + *(uint64_t *)p = cpu_to_fdt64(len); > > + p += sizeof(uint64_t); > > + } > > + else > > + return -1; > > + > > + return(fdt_setprop(fdt, node, "reg", data, p - (void *)data)); > > +} > > + > > +static void __init *lookup_fdt_config_table(EFI_SYSTEM_TABLE *sys_table) > > +{ > > + const EFI_GUID fdt_guid = DEVICE_TREE_GUID; > > + EFI_CONFIGURATION_TABLE *tables; > > + void *fdt = NULL; > > + int i; > > + > > + tables = sys_table->ConfigurationTable; > > + for ( i = 0; i < sys_table->NumberOfTableEntries; i++ ) > > + { > > + if ( match_guid(&tables[i].VendorGuid, &fdt_guid) ) > > + { > > + fdt = tables[i].VendorTable; > > + break; > > + } > > + } > > + return fdt; > > +} > > + > > +static EFI_STATUS __init efi_get_memory_map(void **map, > > + UINTN *mmap_size, > > + UINTN *desc_size, > > + UINT32 *desc_ver, > > + UINTN *key_ptr) > > +{ > > + EFI_MEMORY_DESCRIPTOR *m = NULL; > > + EFI_STATUS status; > > + unsigned long key; > > + u32 desc_version; > > + > > + *map = NULL; > > + *mmap_size = EFI_PAGE_SIZE; > > +again: > > + *mmap_size += EFI_PAGE_SIZE; /* Page size is allocation > granularity */ > > + status = efi_bs->AllocatePool(EfiLoaderData, *mmap_size, (void > **)&m); > > + if ( status != EFI_SUCCESS ) > > + return status; > > + > > + *desc_size = 0; > > + key = 0; > > + status = efi_bs->GetMemoryMap(mmap_size, m, &key, desc_size, > &desc_version); > > + if ( status == EFI_BUFFER_TOO_SMALL ) > > + { > > + efi_bs->FreePool(m); > > + goto again; > > + } > > + > > + if ( status != EFI_SUCCESS ) > > + { > > + efi_bs->FreePool(m); > > + return status; > > + } > > + > > + if ( key_ptr && status == EFI_SUCCESS ) > > + *key_ptr = key; > > + if ( desc_ver && status == EFI_SUCCESS ) > > + *desc_ver = desc_version; > > + > > + *map = m; > > + return status; > > +} > > + > > +static EFI_STATUS __init > efi_process_memory_map_bootinfo(EFI_MEMORY_DESCRIPTOR *map, > > + UINTN mmap_size, > > + UINTN desc_size) > > +{ > > + int Index; > > + int i = 0; > > + > > + EFI_MEMORY_DESCRIPTOR *desc_ptr = map; > > + > > + for ( Index = 0; Index < (mmap_size / desc_size); Index++ ) > > + { > > + if ( desc_ptr->Type == EfiConventionalMemory > > + || desc_ptr->Type == EfiBootServicesCode > > + || desc_ptr->Type == EfiBootServicesData ) > > + { > > + bootinfo.mem.bank[i].start = desc_ptr->PhysicalStart; > > + bootinfo.mem.bank[i].size = desc_ptr->NumberOfPages * > EFI_PAGE_SIZE; > > + if ( ++i >= NR_MEM_BANKS ) > > + { > > + PrintStr(L"Warning: All "); > > + DisplayUint(NR_MEM_BANKS, -1); > > + PrintStr(L" bootinfo mem banks exhausted.\r\n"); > > + break; > > + } > > + } > > + desc_ptr = NextMemoryDescriptor(desc_ptr, desc_size); > > + } > > + > > + bootinfo.mem.nr_banks = i; > > + return EFI_SUCCESS; > > + > > +} > > + > > +/* > > + * Add the FDT nodes for the standard EFI information, which consist > > + * of the System table address, the address of the final EFI memory map, > > + * and memory map information. > > + */ > > +EFI_STATUS __init fdt_add_uefi_nodes(EFI_SYSTEM_TABLE *sys_table, > > + void *fdt, > > + EFI_MEMORY_DESCRIPTOR > *memory_map, > > + UINTN map_size, > > + UINTN desc_size, > > + UINT32 desc_ver) > > +{ > > + int node; > > + int status; > > + u32 fdt_val32; > > + u64 fdt_val64; > > + int prev; > > + /* > > + * Delete any memory nodes present. The EFI memory map is the only > > + * memory description provided to Xen. > > + */ > > + prev = 0; > > + for (;;) > > + { > > + const char *type; > > + int len; > > + > > + node = fdt_next_node(fdt, prev, NULL); > > + if ( node < 0 ) > > + break; > > + > > + type = fdt_getprop(fdt, node, "device_type", &len); > > + if ( type && strncmp(type, "memory", len) == 0 ) > > + { > > + fdt_del_node(fdt, node); > > + continue; > > + } > > + > > + prev = node; > > + } > > + > > + /* Add FDT entries for EFI runtime services in chosen node. */ > > + node = fdt_subnode_offset(fdt, 0, "chosen"); > > + if ( node < 0 ) > > + { > > + node = fdt_add_subnode(fdt, 0, "chosen"); > > + if ( node < 0 ) > > + { > > + status = node; /* node is error code when negative */ > > + goto fdt_set_fail; > > + } > > + } > > setup_chosen_node? > Yes, this should be done here as well. I will add that for the case of creating a new FDT. > > > > + fdt_val64 = cpu_to_fdt64((u64)(uintptr_t)sys_table); > > + status = fdt_setprop(fdt, node, "linux,uefi-system-table", > > + &fdt_val64, sizeof(fdt_val64)); > > + if ( status ) > > + goto fdt_set_fail; > > + > > + fdt_val64 = cpu_to_fdt64((u64)(uintptr_t)memory_map); > > + status = fdt_setprop(fdt, node, "linux,uefi-mmap-start", > > + &fdt_val64, sizeof(fdt_val64)); > > + if ( status ) > > + goto fdt_set_fail; > > + > > + fdt_val32 = cpu_to_fdt32(map_size); > > + status = fdt_setprop(fdt, node, "linux,uefi-mmap-size", > > + &fdt_val32, sizeof(fdt_val32)); > > + if ( status ) > > + goto fdt_set_fail; > > + > > + fdt_val32 = cpu_to_fdt32(desc_size); > > + status = fdt_setprop(fdt, node, "linux,uefi-mmap-desc-size", > > + &fdt_val32, sizeof(fdt_val32)); > > + if ( status ) > > + goto fdt_set_fail; > > + > > + fdt_val32 = cpu_to_fdt32(desc_ver); > > + status = fdt_setprop(fdt, node, "linux,uefi-mmap-desc-ver", > > + &fdt_val32, sizeof(fdt_val32)); > > + if ( status ) > > + goto fdt_set_fail; > > + > > + return EFI_SUCCESS; > > + > > +fdt_set_fail: > > + if ( status == -FDT_ERR_NOSPACE ) > > + return EFI_BUFFER_TOO_SMALL; > > + > > + return EFI_LOAD_ERROR; > > +} > > + > > +/* > > + * Allocates new memory for a larger FDT, and frees existing memory if > > + * struct file size is non-zero. Updates file struct with new memory > > + * address/size for later freeing. If fdtfile.ptr is NULL, an empty FDT > > + * is created. > > + */ > > +static void __init *fdt_increase_size(struct file *fdtfile, int > add_size) > > +{ > > + EFI_STATUS status; > > + EFI_PHYSICAL_ADDRESS fdt_addr; > > + int fdt_size; > > + int pages; > > + void *new_fdt; > > + > > + if ( fdtfile->ptr ) > > + fdt_size = fdt_totalsize(fdtfile->ptr); > > + else > > + fdt_size = 0; > > + > > + pages = PFN_UP(fdt_size) + PFN_UP(add_size); > > Shouldn't this be PFN_UP(fdt_size+add_size)? > Yup, I will fix this. > > > > + status = efi_bs->AllocatePages(AllocateAnyPages, EfiLoaderData, > > + pages, &fdt_addr); > > + > > + if ( status != EFI_SUCCESS ) > > + return NULL; > > + > > + new_fdt = (void *)fdt_addr; > > + > > + if ( fdt_size ) > > + { > > + if ( fdt_open_into(dtbfile.ptr, new_fdt, pages * EFI_PAGE_SIZE) > ) > > + return NULL; > > + } > > + else > > + { > > + /* > > + * Create an empty FDT if not provided one, which is the > expected case > > + * when booted from the UEFI shell on an ACPI only system. We > will use > > + * the FDT to pass the EFI information to Xen, as well as nodes > for > > + * any modules the stub loads. The ACPI tables are part of the > UEFI > > + * system table that is passed in the FDT. > > + */ > > + if ( fdt_create_empty_tree(new_fdt, pages * EFI_PAGE_SIZE) ) > > + return NULL; > > + } > > + > > + /* > > + * Now that we have the new FDT allocated and copied, free the > > + * original and update the struct file so that the error handling > > + * code will free it. If the original FDT came from a configuration > > + * table, we don't own that memory and can't free it. > > + */ > > + if ( dtbfile.size ) > > + efi_bs->FreePages(dtbfile.addr, PFN_UP(dtbfile.size)); > > + > > + /* Update 'file' info for new memory so we clean it up on error > exits */ > > + dtbfile.addr = fdt_addr; > > + dtbfile.size = pages * EFI_PAGE_SIZE; > > + return new_fdt; > > +} > > + > > +static void __init efi_arch_pci(void) > > +{ > > +} > > + > > +static void __init efi_arch_relocate_image(unsigned long delta) > > +{ > > +} > > + > > +static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE > *SystemTable, > > + void *map, > > + UINTN map_size, > > + UINTN desc_size, > > + UINT32 desc_ver) > > +{ > > + EFI_STATUS status; > > + > > + status = efi_process_memory_map_bootinfo(map, map_size, desc_size); > > + if ( EFI_ERROR(status) ) > > + blexit(L"ERROR processing EFI memory map\r\n"); > > + > > + status = fdt_add_uefi_nodes(SystemTable, fdt, map, map_size, > desc_size, > > + desc_ver); > > + if ( EFI_ERROR(status) ) > > + PrintErrMesg(L"ERROR updating FDT\r\n", status); > > +} > > + > > +static void __init efi_arch_pre_exit_boot(void) > > +{ > > +} > > + > > +static void __init efi_arch_post_exit_boot(void) > > +{ > > + efi_xen_start(fdt); > > +} > > + > > +static void __init efi_arch_cfg_file(EFI_FILE_HANDLE dir_handle, char > *section) > > +{ > > + union string name; > > + name.s = get_value(&cfg, section, "dtb"); > > + if ( name.s ) > > + { > > + if ( !read_file(dir_handle, &dtbfile, name.s)) > > + blexit(NULL); > > + } > > + fdt = fdt_increase_size(&dtbfile, cfg.size + EFI_PAGE_SIZE); > > + if ( !fdt ) > > + blexit(L"Unable to create new FDT\r\n"); > > +} > > + > > +static void __init efi_arch_get_memory_map(UINTN *map_size, > > + void **map, > > + UINTN *map_key, UINTN > *desc_size, > > + UINT32 *desc_ver) > > +{ > > + EFI_STATUS status; > > + > > + status = efi_get_memory_map(map, map_size, desc_size, desc_ver, > map_key); > > + if ( EFI_ERROR(status) ) > > + blexit(L"ERROR getting EFI memory map.\r\n"); > > + memmap = *map; > > +} > > + > > +static void __init efi_arch_edd(void) > > +{ > > +} > > + > > +static void __init efi_arch_video(bool_t base_video, > > + UINTN cols, UINTN rows, UINTN depth, > > + EFI_GRAPHICS_OUTPUT_PROTOCOL *gop) > > +{ > > +} > > + > > +static void __init efi_arch_memory(void) > > +{ > > +} > > + > > +static void __init efi_arch_handle_cmdline(CHAR16 *image_name, > > + CHAR16 *cmdline_options, > > + char *cfgfile_options) > > +{ > > + union string name; > > + char *buf; > > + EFI_STATUS status; > > + int prop_len; > > + int chosen; > > + > > + /* locate chosen node, which is where we add Xen module info. */ > > + chosen = fdt_subnode_offset(fdt, 0, "chosen"); > > + if ( chosen < 0 ) > > + blexit(L"ERROR unable to find chosen node\r\n"); > > + > > + status = efi_bs->AllocatePool(EfiBootServicesData, EFI_PAGE_SIZE, > (void **)&buf); > > + if ( EFI_ERROR(status) ) > > + PrintErrMesg(L"ERROR allocating memory.\r\n", status); > > + > > + if ( image_name ) > > + { > > + name.w = image_name; > > + w2s(&name); > > + } > > + else > > + name.s = "xen"; > > + > > + prop_len = 0; > > + prop_len += snprintf(buf + prop_len, > > + EFI_PAGE_SIZE - prop_len, "%s", name.s); > > + if ( prop_len >= EFI_PAGE_SIZE ) > > + blexit(L"FDT string overflow"); > > + > > + if ( cfgfile_options ) > > + { > > + prop_len += snprintf(buf + prop_len, > > + EFI_PAGE_SIZE - prop_len, " %s", > cfgfile_options); > > + if ( prop_len >= EFI_PAGE_SIZE ) > > + blexit(L"FDT string overflow"); > > + } > > + > > + if ( cmdline_options ) > > + { > > + name.w = cmdline_options; > > + w2s(&name); > > + } > > + else > > + name.s = NULL; > > + > > + if ( name.s ) > > + { > > + prop_len += snprintf(buf + prop_len, > > + EFI_PAGE_SIZE - prop_len, " %s", name.s); > > + if ( prop_len >= EFI_PAGE_SIZE ) > > + blexit(L"FDT string overflow"); > > + } > > + > > + if ( fdt_setprop_string(fdt, chosen, "xen,xen-bootargs", buf) < 0 ) > > + blexit(L"unable to set xen,xen-bootargs property."); > > + > > + efi_bs->FreePool(buf); > > +} > > + > > +static void __init efi_arch_handle_module(struct file *file, char *name, > > + char *options) > > +{ > > + int node; > > + int chosen; > > + int addr_len, size_len; > > + > > + if ( file == &dtbfile ) > > + return; > > + chosen = setup_chosen_node(fdt, &addr_len, &size_len); > > + if ( chosen < 0 ) > > + blexit(L"Unable to setup chosen node\r\n"); > > + > > + if ( file == &ramdisk ) > > + { > > + char ramdisk_compat[] = "multiboot,ramdisk\0multiboot,module"; > > + node = fdt_add_subnode(fdt, chosen, "ramdisk"); > > + if ( node < 0 ) > > + blexit(L"Error adding ramdisk FDT node."); > > + if ( fdt_setprop(fdt, node, "compatible", ramdisk_compat, > > + sizeof(ramdisk_compat)) < 0 ) > > + blexit(L"unable to set compatible property."); > > + if ( fdt_set_reg(fdt, node, addr_len, size_len, ramdisk.addr, > > + ramdisk.size) < 0 ) > > + blexit(L"unable to set reg property."); > > + } > > + else if ( file == &xsm ) > > + { > > + char xsm_compat[] = "xen,xsm-policy\0multiboot,module"; > > + node = fdt_add_subnode(fdt, chosen, "xsm"); > > + if ( node < 0 ) > > + blexit(L"Error adding xsm FDT node."); > > + if ( fdt_setprop(fdt, node, "compatible", xsm_compat, > > + sizeof(xsm_compat)) < 0 ) > > + blexit(L"unable to set compatible property."); > > + if ( fdt_set_reg(fdt, node, addr_len, size_len, xsm.addr, > > + xsm.size) < 0 ) > > + blexit(L"unable to set reg property."); > > + } > > + else if ( file == &kernel ) > > + { > > + char kernel_compat[] = "multiboot,kernel\0multiboot,module"; > > + node = fdt_add_subnode(fdt, chosen, "kernel"); > > + if ( node < 0 ) > > + blexit(L"Error adding dom0 FDT node."); > > + if ( fdt_setprop(fdt, node, "compatible", kernel_compat, > > + sizeof(kernel_compat)) < 0 ) > > + blexit(L"unable to set compatible property."); > > + if ( options && fdt_setprop_string(fdt, node, "bootargs", > options) < 0 ) > > + blexit(L"unable to set bootargs property."); > > + if ( fdt_set_reg(fdt, node, addr_len, size_len, kernel.addr, > > + kernel.size) < 0 ) > > + blexit(L"unable to set reg property."); > > + } > > + else > > + blexit(L"Unknown module type\r\n"); > > +} > > + > > +static void __init efi_arch_cpu(void) > > +{ > > +} > > + > > +static void __init efi_arch_smbios(void) > > +{ > > +} > > + > > +static void __init efi_arch_blexit(void) > > +{ > > + if ( dtbfile.addr && dtbfile.size ) > > + efi_bs->FreePages(dtbfile.addr, PFN_UP(dtbfile.size)); > > + if ( memmap ) > > + efi_bs->FreePool(memmap); > > +} > > + > > +static void __init efi_arch_load_addr_check(EFI_LOADED_IMAGE > *loaded_image) > > +{ > > + if ( (unsigned long)loaded_image->ImageBase & ((1 << 12) - 1) ) > > + blexit(L"Xen must be loaded at a 4 KByte boundary."); > > +} > > + > > +static void __init efi_arch_runtime_setup(EFI_SYSTEM_TABLE *SystemTable) > > +{ > > +} > > + > > +static __init bool_t efi_arch_use_config_file(EFI_SYSTEM_TABLE > *SystemTable) > > +{ > > + /* > > + * For arm, we may get a device tree from GRUB (or other bootloader) > > + * that contains modules that have already been loaded into > memory. In > > + * this case, we do not use a configuration file, and rely on the > > + * bootloader to have loaded all required modules and appropriate > > + * options. > > + */ > > + > > + fdt = lookup_fdt_config_table(SystemTable); > > + dtbfile.ptr = fdt; > > + dtbfile.size = 0; /* Config table memory can't be freed, so set > size to 0 */ > > + if ( !fdt || fdt_node_offset_by_compatible(fdt, 0, > "multiboot,module") < 0 ) > > + { > > + /* > > + * We either have no FDT, or one without modules, so we must > have a > > + * Xen EFI configuration file to specify modules. (dom0 > required) > > + */ > > + return 1; > > + } > > + PrintStr(L"Using modules provided by bootloader in FDT\r\n"); > > + /* We have modules already defined in fdt, just add space. */ > > + fdt = fdt_increase_size(&dtbfile, EFI_PAGE_SIZE); > > + return 0; > > +} > > + > > +/* > > + * Local variables: > > + * mode: C > > + * c-file-style: "BSD" > > + * c-basic-offset: 4 > > + * indent-tabs-mode: nil > > + * End: > > + */ > > diff --git a/xen/include/asm-arm/efi.h b/xen/include/asm-arm/efi.h > > new file mode 100644 > > index 0000000..aae4716 > > --- /dev/null > > +++ b/xen/include/asm-arm/efi.h > > @@ -0,0 +1,29 @@ > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +extern unsigned int efi_num_ct; > > +extern EFI_CONFIGURATION_TABLE *efi_ct; > > + > > +extern unsigned int efi_version, efi_fw_revision; > > +extern const CHAR16 *efi_fw_vendor; > > + > > +extern EFI_RUNTIME_SERVICES *efi_rs; > > + > > +extern UINTN efi_memmap_size, efi_mdesc_size; > > +extern void *efi_memmap; > > + > > +extern const struct efi_pci_rom *efi_pci_roms; > > + > > +extern UINT64 efi_boot_max_var_store_size, > efi_boot_remain_var_store_size, > > + efi_boot_max_var_size; > > + > > +unsigned long efi_rs_enter(void); > > +void efi_rs_leave(unsigned long); > > diff --git a/xen/include/asm-arm/efibind.h > b/xen/include/asm-arm/efibind.h > > new file mode 100644 > > index 0000000..09dca7a > > --- /dev/null > > +++ b/xen/include/asm-arm/efibind.h > > @@ -0,0 +1,2 @@ > > +#include > > +#include > > diff --git a/xen/include/asm-arm/setup.h b/xen/include/asm-arm/setup.h > > index 36e5704..40814e6 100644 > > --- a/xen/include/asm-arm/setup.h > > +++ b/xen/include/asm-arm/setup.h > > @@ -3,7 +3,7 @@ > > > > #include > > > > -#define NR_MEM_BANKS 8 > > +#define NR_MEM_BANKS 32 > > Why? > At the very least you should write it in the commit message. > > In the EFI case, we have the EFI memory map which lists all memory by region and usage (ie available, boot_services, runtime, etc.) not the physical memory banks that are provided by FDT. I am putting the available memory from the EFI memory map into the memory bank list, so this requires more entries. This is somewhat problematic as it is possible for the EFI memory map to be very fragmented, which could lead to a great many regions. Roy > > #define MAX_MODULES 5 /* Current maximum useful modules */ > > > > -- > > 2.1.0.rc1 > > > --001a11c3584a3e8ed20502d5c699 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
On T= hu, Sep 11, 2014 at 5:49 PM, Stefano Stabellini <stefano.st= abellini@eu.citrix.com> wrote:
On Tue, 9 Sep 2014, Roy Franz wrote:
> This patch adds EFI boot support for ARM based on the previous refacto= ring of
> the x86 EFI boot code.=C2=A0 All ARM specific code is in the ARM efi-b= oot.h header
> file, with the main EFI entry point common/efi/boot.c.=C2=A0 The PE/CO= FF header is
> open-coded in head.S, which allows us to have a single binary be both = an EFI
> executable and a normal arm64 IMAGE file. There is currently no PE/COF= F
> toolchain support for arm64, so it is not possible to create the PE/CO= FF header
> in the same manner as on x86.=C2=A0 This also simplifies the build as = compared to
> x86, as we always build the same executable, whereas x86 builds 2.=C2= =A0 An ARM
> version of efi-bind.h is added, which is based on the x86_64 version w= ith the
> x86 specific portions removed.=C2=A0 The Makefile in common/efi is dif= ferent for x86
> and ARM, as for ARM we always build in EFI support.
>
> Signed-off-by: Roy Franz <r= oy.franz@linaro.org>
> ---
>=C2=A0 config/arm64.mk=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0|=C2=A0 =C2=A01 +
>=C2=A0 xen/arch/arm/arm64/head.S=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0| 150 ++++++++-
>=C2=A0 xen/arch/arm/xen.lds.S=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 |=C2=A0 =C2=A01 +
>=C2=A0 xen/common/Makefile=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0|=C2=A0 =C2=A01 +
>=C2=A0 xen/common/efi/Makefile=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0|=C2=A0 =C2=A03 +
>=C2=A0 xen/include/asm-arm/arm64/efibind.h | 216 +++++++++++++
>=C2=A0 xen/include/asm-arm/efi-boot.h=C2=A0 =C2=A0 =C2=A0 | 630 +++++++= +++++++++++++++++++++++++++++
>=C2=A0 xen/include/asm-arm/efi.h=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0|=C2=A0 29 ++
>=C2=A0 xen/include/asm-arm/efibind.h=C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 = =C2=A02 +
>=C2=A0 xen/include/asm-arm/setup.h=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|= =C2=A0 =C2=A02 +-
>=C2=A0 10 files changed, 1031 insertions(+), 4 deletions(-)
>=C2=A0 create mode 100644 xen/common/efi/Makefile
>=C2=A0 create mode 100644 xen/include/asm-arm/arm64/efibind.h
>=C2=A0 create mode 100644 xen/include/asm-arm/efi-boot.h
>=C2=A0 create mode 100644 xen/include/asm-arm/efi.h
>=C2=A0 create mode 100644 xen/include/asm-arm/efibind.h
>
> diff --git a/config/
arm6= 4.mk b/config/arm64.mk
> index 15b57a4..e6aab0e 100644
> --- a/config/
arm64.mk
> +++ b/config/
arm64.mk
> @@ -1,6 +1,7 @@
>=C2=A0 CONFIG_ARM :=3D y
>=C2=A0 CONFIG_ARM_64 :=3D y
>=C2=A0 CONFIG_ARM_$(XEN_OS) :=3D y
> +CONFIG_EFI :=3D y
>
>=C2=A0 CONFIG_XEN_INSTALL_SUFFIX :=3D
>
> diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
> index 43b5e72..158c102 100644
> --- a/xen/arch/arm/arm64/head.S
> +++ b/xen/arch/arm/arm64/head.S
> @@ -24,6 +24,8 @@
>=C2=A0 #include <asm/page.h>
>=C2=A0 #include <asm/asm_defns.h>
>=C2=A0 #include <asm/early_printk.h>
> +#include <efi/efierr.h>
> +#include <asm/arm64/efibind.h>
>
>=C2=A0 #define PT_PT=C2=A0 =C2=A0 =C2=A00xf7f /* nG=3D1 AF=3D1 SH=3D11 = AP=3D01 NS=3D1 ATTR=3D111 T=3D1 P=3D1 */
>=C2=A0 #define PT_MEM=C2=A0 =C2=A0 0xf7d /* nG=3D1 AF=3D1 SH=3D11 AP=3D= 01 NS=3D1 ATTR=3D111 T=3D0 P=3D1 */
> @@ -104,8 +106,14 @@ GLOBAL(start)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /*
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* DO NOT MODIFY. Image header = expected by Linux boot-loaders.
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*/
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 b=C2=A0 =C2=A0 =C2=A0 =C2=A0real_start=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* branch to kernel start, magic */ > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* reserved */
> +efi_head:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 /*
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* This add instruction has no meani= ngful effect except that
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* its opcode forms the magic "= MZ" signature of a PE/COFF file
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* that is required for UEFI applica= tions.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*/
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 add=C2=A0 =C2=A0 =C2=A0x13, x18, #0x16 > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 b=C2=A0 =C2=A0 =C2=A0 =C2=A0real_start=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* branch to kernel start */
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .quad=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* Image load offset f= rom start of RAM */
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .quad=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* reserved */
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .quad=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* reserved */
> @@ -116,8 +124,113 @@ GLOBAL(start)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .byte=C2=A0 =C2=A00x52
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .byte=C2=A0 =C2=A00x4d
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 .byte=C2=A0 =C2=A00x64
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 .word=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* reserved */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A0pe_header - efi_head=C2= =A0 =C2=A0 =C2=A0 =C2=A0 /* Offset to the PE header. */
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 /*
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* Add the PE/COFF header to the fil= e.=C2=A0 The address of this header
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* is at offset 0x3c in the file, an= d is part of Linux "Image"
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* header.=C2=A0 The arm64 Linux Ima= ge format is designed to support
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* being both an 'Image' for= mat binary and a PE/COFF binary.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* The PE/COFF format is defined by = Microsoft, and is available
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* from:
http://msdn.microsoft.com/= en-us/gg463119.aspx
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* Version 8.3 adds support for arm6= 4 and UEFI usage.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*/
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .align=C2=A0 3
> +pe_header:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .ascii=C2=A0 "PE"
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0
> +coff_header:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0xaa64=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* AA= rch64 */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 2=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0/* nr_sections */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* TimeDateStamp */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* PointerToSymbolTable */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A01=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* NumberOfSymbols */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 section_table - optional_hea= der /* SizeOfOptionalHeader */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0x206=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* Characteristics. */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 /* IMAGE_FILE_DEBUG_STRIPPED | */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 /* IMAGE_FILE_EXECUTABLE_IMAGE | */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 /* IMAGE_FILE_LINE_NUMS_STRIPPED */
> +optional_header:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0x20b=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* PE32+ format */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .byte=C2=A0 =C2=A00x02=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 /* MajorLinkerVersion */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .byte=C2=A0 =C2=A00x14=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 /* MinorLinkerVersion */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A0_end - real_start=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* SizeOfCode */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* SizeOfInitializedData */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* SizeOfUninitializedData */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A0efi_start - efi_head=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* AddressOfEntryPoint */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A0real_start - efi_head= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* BaseOfCode */
> +
> +extra_header_fields:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .quad=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* ImageBase */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00x1000=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /= * SectionAlignment (4 KByte) */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00x8=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0/* FileAlignment */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0/* MajorOperatingSystemVersion */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0/* MinorOperatingSystemVersion */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0/* MajorImageVersion */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0/* MinorImageVersion */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0/* MajorSubsystemVersion */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0/* MinorSubsystemVersion */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* Win32VersionValue */
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A0_end - efi_head=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* SizeOfImage */ > +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* Everything before the kernel image is = considered part of the header */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A0real_start - efi_head= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* SizeOfHeaders */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* CheckSum */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0xa=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0/* Subsystem (EFI application) */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0/* DllCharacteristics */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .quad=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* SizeOfStackReserve */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .quad=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* SizeOfStackCommit */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .quad=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* SizeOfHeapReserve */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .quad=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* SizeOfHeapCommit */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* LoaderFlags */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00x6=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0/* NumberOfRvaAndSizes */
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .quad=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* ExportTable */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .quad=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* ImportTable */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .quad=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* ResourceTable */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .quad=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* ExceptionTable */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .quad=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* CertificationTable */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .quad=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* BaseRelocationTable */
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* Section table */
> +section_table:
>
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 /*
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* The EFI application loader requir= es a relocation section
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* because EFI applications must be = relocatable.=C2=A0 This is a
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* dummy section as far as we are co= ncerned.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*/
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .ascii=C2=A0 ".reloc"
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .byte=C2=A0 =C2=A00
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .byte=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* end of 0 padding of section name */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* SizeOfRawData */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* PointerToRawData */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* PointerToRelocations */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* PointerToLineNumbers */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0/* NumberOfRelocations */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0/* NumberOfLineNumbers */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00x42100040=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* Characte= ristics (section flags) */
> +
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .ascii=C2=A0 ".text"
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .byte=C2=A0 =C2=A00
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .byte=C2=A0 =C2=A00
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .byte=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0/* end of 0 padding of section name */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A0_end - real_start=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* VirtualSize */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A0real_start - efi_head= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* VirtualAddress */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A0__init_end_efi - real_s= tart=C2=A0 =C2=A0 =C2=A0/* SizeOfRawData */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A0real_start - efi_head= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* PointerToRawData */
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* PointerToRelocations (0 for executabl= es) */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* PointerToLineNumbers (0 for executabl= es) */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* NumberOfRelocations=C2=A0 (0 for executable= s) */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .short=C2=A0 0=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* NumberOfLineNumbers=C2=A0 (0 for executable= s) */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .long=C2=A0 =C2=A00xe0500020=C2=A0 =C2=A0= =C2=A0 =C2=A0/* Characteristics (section flags) */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 .align=C2=A0 5
>=C2=A0 real_start:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 msr=C2=A0 =C2=A0DAIFSet, 0xf=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Disable all interrupts */
>
> @@ -617,6 +730,37 @@ putn:=C2=A0 =C2=A0ret
>=C2=A0 ENTRY(lookup_processor_type)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 mov=C2=A0 x0, #0
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret
> +/*
> + *=C2=A0 Function to transition from EFI loader in C, to Xen entry po= int.
> + *=C2=A0 void noreturn efi_xen_start(void *fdt_ptr);
> + */
> +ENTRY(efi_xen_start)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 /*
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* Turn off cache and MMU as Xen exp= ects. EFI enables them, but also
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* mandates a 1:1 (unity) VA->PA = mapping, so we can turn off the
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* MMU while executing EFI code befo= re entering Xen.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* The EFI loader calls this to star= t Xen.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* Preserve x0 (fdf pointer) across = call to __flush_dcache_all,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* restore for entry into Xen.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*/
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 mov=C2=A0 =C2=A0x20, x0
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 bl=C2=A0 =C2=A0 __flush_dcache_all
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ic=C2=A0 =C2=A0 ialluis
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* Turn off Dcache and MMU */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 mrs=C2=A0 =C2=A0x0, sctlr_el2
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 bic=C2=A0 =C2=A0x0, x0, #1 << 0=C2= =A0 =C2=A0 =C2=A0 =C2=A0 /* clear SCTLR.M */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 bic=C2=A0 =C2=A0x0, x0, #1 << 2=C2= =A0 =C2=A0 =C2=A0 =C2=A0 /* clear SCTLR.C */

dsb?

The dsb is done at the= end of =C2=A0__flush_dcache_all



> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 msr=C2=A0 =C2=A0sctlr_el2, x0
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 isb
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* Jump to Xen entry point */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 mov=C2=A0 =C2=A0x0, x20
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 mov=C2=A0 =C2=A0x1, xzr
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 mov=C2=A0 =C2=A0x2, xzr
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 mov=C2=A0 =C2=A0x3, xzr
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 b=C2=A0 =C2=A0 =C2=A0real_start
> +ENDPROC(efi_xen_start)
>
>=C2=A0 /*
>=C2=A0 =C2=A0* Local variables:
> diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S
> index 079e085..d8b0cfe 100644
> --- a/xen/arch/arm/xen.lds.S
> +++ b/xen/arch/arm/xen.lds.S
> @@ -135,6 +135,7 @@ SECTIONS
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*(.xsm_initcall.init)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0__xsm_initcall_end =3D .;
>=C2=A0 =C2=A0 } :text
> +=C2=A0 __init_end_efi =3D .;
>=C2=A0 =C2=A0 . =3D ALIGN(STACK_SIZE);
>=C2=A0 =C2=A0 __init_end =3D .;
>
> diff --git a/xen/common/Makefile b/xen/common/Makefile
> index 3683ae3..e78cb29 100644
> --- a/xen/common/Makefile
> +++ b/xen/common/Makefile
> @@ -67,4 +67,5 @@ subdir-$(x86_64) +=3D hvm
>=C2=A0 subdir-$(coverage) +=3D gcov
>
>=C2=A0 subdir-y +=3D libelf
> +subdir-$(CONFIG_EFI) +=3D efi
>=C2=A0 subdir-$(HAS_DEVICE_TREE) +=3D libfdt
> diff --git a/xen/common/efi/Makefile b/xen/common/efi/Makefile
> new file mode 100644
> index 0000000..195b2f3
> --- /dev/null
> +++ b/xen/common/efi/Makefile
> @@ -0,0 +1,3 @@
> +CFLAGS +=3D -fshort-wchar
> +
> +obj-y +=3D boot.init.o
> diff --git a/xen/include/asm-arm/arm64/efibind.h b/xen/include/asm-arm= /arm64/efibind.h
> new file mode 100644
> index 0000000..2b0bf40
> --- /dev/null
> +++ b/xen/include/asm-arm/arm64/efibind.h
> @@ -0,0 +1,216 @@
> +/*++
> +
> +Copyright (c) 1998=C2=A0 Intel Corporation
> +
> +Module Name:
> +
> +=C2=A0 =C2=A0 efefind.h
> +
> +Abstract:
> +
> +=C2=A0 =C2=A0 EFI to compile bindings
> +
> +
> +
> +
> +Revision History
> +
> +--*/
> +
> +#ifndef __GNUC__
> +#pragma pack()
> +#endif
> +
> +#define EFIERR(a)=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(0x80000000= 00000000 | a)
> +#define EFI_ERROR_MASK=C2=A0 =C2=A0 =C2=A0 0x8000000000000000
> +#define EFIERR_OEM(a)=C2=A0 =C2=A0 =C2=A0 =C2=A0(0xc000000000000000 |= a)
> +
> +#define BAD_POINTER=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00xFBFBFBFBFBFBFB= FB
> +#define MAX_ADDRESS=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00xFFFFFFFFFFFFFF= FF
> +
> +#define EFI_STUB_ERROR=C2=A0 =C2=A0 =C2=A0 MAX_ADDRESS
> +
> +#ifndef __ASSEMBLY__
> +//
> +// Basic int types of various widths
> +//
> +
> +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L ) > +
> +=C2=A0 =C2=A0 // No ANSI C 1999/2000 stdint.h integer width declarati= ons
> +
> +=C2=A0 =C2=A0 #if defined(__GNUC__)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 typedef unsigned long long=C2=A0 uint64_t= __attribute__((aligned (8)));
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 typedef long long=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0int64_t __attribute__((aligned (8)));
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 typedef unsigned int=C2=A0 =C2=A0 =C2=A0 = =C2=A0 uint32_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 typedef int=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0int32_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 typedef unsigned short=C2=A0 =C2=A0 =C2= =A0 uint16_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 typedef short=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0int16_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 typedef unsigned char=C2=A0 =C2=A0 =C2=A0= =C2=A0uint8_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 typedef char=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 int8_t;
> +=C2=A0 =C2=A0 #elif defined(UNIX_LP64)
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 /*=C2=A0 Use LP64 programming model from = C_FLAGS for integer width declarations */
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef unsigned long=C2=A0 =C2=A0 =C2=A0 = =C2=A0uint64_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef long=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 int64_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef unsigned int=C2=A0 =C2=A0 =C2=A0 = =C2=A0 uint32_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef int=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0int32_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef unsigned short=C2=A0 =C2=A0 =C2=A0= uint16_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef short=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0int16_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef unsigned char=C2=A0 =C2=A0 =C2=A0 = =C2=A0uint8_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef char=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 int8_t;
> +=C2=A0 =C2=A0 #else
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0/*=C2=A0 Assume P64 programming model from= C_FLAGS for integer width declarations */
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef unsigned long long=C2=A0 uint64_t = __attribute__((aligned (8)));
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef long long=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0int64_t __attribute__((aligned (8)));
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef unsigned int=C2=A0 =C2=A0 =C2=A0 = =C2=A0 uint32_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef int=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0int32_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef unsigned short=C2=A0 =C2=A0 =C2=A0= uint16_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef short=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0int16_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef unsigned char=C2=A0 =C2=A0 =C2=A0 = =C2=A0uint8_t;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0typedef char=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 int8_t;
> +=C2=A0 =C2=A0 #endif
> +#endif
> +
> +//
> +// Basic EFI types of various widths
> +//
> +
> +#ifndef __WCHAR_TYPE__
> +# define __WCHAR_TYPE__ short
> +#endif
> +
> +typedef uint64_t=C2=A0 =C2=A0UINT64;
> +typedef int64_t=C2=A0 =C2=A0 INT64;
> +
> +#ifndef _BASETSD_H_
> +=C2=A0 =C2=A0 typedef uint32_t=C2=A0 =C2=A0UINT32;
> +=C2=A0 =C2=A0 typedef int32_t=C2=A0 =C2=A0 INT32;
> +#endif
> +
> +typedef uint16_t=C2=A0 =C2=A0UINT16;
> +typedef int16_t=C2=A0 =C2=A0 INT16;
> +typedef uint8_t=C2=A0 =C2=A0 UINT8;
> +typedef int8_t=C2=A0 =C2=A0 =C2=A0INT8;
> +typedef __WCHAR_TYPE__ WCHAR;
> +
> +#undef VOID
> +#define VOID=C2=A0 =C2=A0 void
> +
> +
> +typedef int64_t=C2=A0 =C2=A0 INTN;
> +typedef uint64_t=C2=A0 =C2=A0UINTN;
> +
> +#define POST_CODE(_Data)
> +
> +
> +#define BREAKPOINT()=C2=A0 =C2=A0 =C2=A0 =C2=A0 while (TRUE);=C2=A0 = =C2=A0 // Make it hang on Bios[Dbg]32
> +
> +//
> +// Pointers must be aligned to these address to function
> +//
> +
> +#define MIN_ALIGNMENT_SIZE=C2=A0 4
> +
> +#define ALIGN_VARIABLE(Value ,Adjustment) \
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (UINTN)Adjustment =3D 0; \<= br> > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if((UINTN)Value % MIN_ALIGN= MENT_SIZE) \
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (UINTN)Adjust= ment =3D MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Value =3D (UINTN)Value + (U= INTN)Adjustment
> +
> +
> +//
> +// Define macros to build data structure signatures from characters.<= br> > +//
> +
> +#define EFI_SIGNATURE_16(A,B)=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0((A) | (B<<8))
> +#define EFI_SIGNATURE_32(A,B,C,D)=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(E= FI_SIGNATURE_16(A,B)=C2=A0 =C2=A0 =C2=A0| (EFI_SIGNATURE_16(C,D)=C2=A0 =C2= =A0 =C2=A0<< 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))
> +
> +#define EXPORTAPI
> +
> +
> +//
> +// EFIAPI - prototype calling convention for EFI function pointers > +// BOOTSERVICE - prototype for implementation of a boot service inter= face
> +// RUNTIMESERVICE - prototype for implementation of a runtime service= interface
> +// RUNTIMEFUNCTION - prototype for implementation of a runtime functi= on that is not a service
> +// RUNTIME_CODE - pragma macro for declaring runtime code
> +//
> +
> +#ifndef EFIAPI=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 // Forces EFI calling conventions reguardless of compiler options > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 #define EFIAPI=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 // Substitute expresion to force C calling convention
> +#endif
> +
> +#define BOOTSERVICE
> +//#define RUNTIMESERVICE(proto,a)=C2=A0 =C2=A0 alloc_text("rtcod= e",a); proto a
> +//#define RUNTIMEFUNCTION(proto,a)=C2=A0 =C2=A0alloc_text("rtcod= e",a); proto a
> +#define RUNTIMESERVICE
> +#define RUNTIMEFUNCTION
> +
> +
> +#define RUNTIME_CODE(a)=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0alloc_text(&= quot;rtcode", a)
> +#define BEGIN_RUNTIME_DATA()=C2=A0 =C2=A0 data_seg("rtdata"= )
> +#define END_RUNTIME_DATA()=C2=A0 =C2=A0 =C2=A0 data_seg("")=
> +
> +#define VOLATILE=C2=A0 =C2=A0 volatile
> +
> +#define MEMORY_FENCE()
> +
> +
> +//
> +// When build similiar to FW, then link everything together as
> +// one big module.
> +//
> +
> +#define EFI_DRIVER_ENTRY_POINT(InitFunction)=C2=A0 =C2=A0 \
> +=C2=A0 =C2=A0 UINTN=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0\
> +=C2=A0 =C2=A0 InitializeDriver (=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 \
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 VOID=C2=A0 =C2=A0 *ImageHandle,=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0\
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 VOID=C2=A0 =C2=A0 *SystemTable=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 \
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 )=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0\
> +=C2=A0 =C2=A0 {=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0\
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return InitFunction(ImageHandle,=C2=A0 = =C2=A0 =C2=A0 =C2=A0 \
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 SystemTable);= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0\
> +=C2=A0 =C2=A0 }=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0\
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 \
> +=C2=A0 =C2=A0 EFI_STATUS efi_main(=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 \
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 EFI_HANDLE image,=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0\
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 EFI_SYSTEM_TABLE *systab=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 \
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ) __attribute__((weak,=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 \
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 alias ("= InitializeDriver")));
> +
> +#define LOAD_INTERNAL_DRIVER(_if, type, name, entry)=C2=A0 =C2=A0 \ > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 (_if)->LoadInternal(type, name, entry)=
> +
> +
> +//
> +// Some compilers don't support the forward reference construct:<= br> > +//=C2=A0 typedef struct XXXXX
> +//
> +// The following macro provide a workaround for such cases.
> +//
> +#ifdef NO_INTERFACE_DECL
> +#define INTERFACE_DECL(x)
> +#else
> +#ifdef __GNUC__
> +#define INTERFACE_DECL(x) struct x
> +#else
> +#define INTERFACE_DECL(x) typedef struct x
> +#endif
> +#endif
> +
> +#endif
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * tab-width: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/include/asm-arm/efi-boot.h b/xen/include/asm-arm/efi-= boot.h
> new file mode 100644
> index 0000000..2db0966
> --- /dev/null
> +++ b/xen/include/asm-arm/efi-boot.h
> @@ -0,0 +1,630 @@
> +/*
> + * Architecture specific implementation for EFI boot code.=C2=A0 This= file
> + * is intended to be included by XXX _only_, and therefore can define=
> + * arch specific global variables.
> + */
> +#include <xen/libfdt/libfdt.h>
> +#include <asm/setup.h>
> +
> +static void noreturn blexit(const CHAR16 *str);
> +static void PrintErrMesg(const CHAR16 *mesg, EFI_STATUS ErrCode);
> +void noreturn efi_xen_start(void *fdt_ptr);
> +
> +#define DEVICE_TREE_GUID \
> +{0xb1b621d5, 0xf19c, 0x41a5, {0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xa= a, 0xe0}}
> +
> +static struct file __initdata dtbfile;
> +static void __initdata *fdt;
> +static void __initdata *memmap;
> +
> +static int __init setup_chosen_node(void *fdt, int *addr_cells, int *= size_cells)
> +{
> +=C2=A0 =C2=A0 int node;
> +=C2=A0 =C2=A0 const struct fdt_property *prop;
> +=C2=A0 =C2=A0 int len;
> +=C2=A0 =C2=A0 uint32_t val;
> +
> +=C2=A0 =C2=A0 if ( !fdt || !addr_cells || !size_cells )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
> +
> +=C2=A0 =C2=A0 /* locate chosen node, which is where we add Xen module= info. */
> +=C2=A0 =C2=A0 node =3D fdt_subnode_offset(fdt, 0, "chosen")= ;
> +=C2=A0 =C2=A0 if ( node < 0 )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 node =3D fdt_add_subnode(fdt, 0, "ch= osen");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( node < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return node;
> +=C2=A0 =C2=A0 }
> +
> +=C2=A0 =C2=A0 /* Get or set #address-cells and #size-cells */
> +=C2=A0 =C2=A0 prop =3D fdt_get_property(fdt, node, "#address-cel= ls", &len);
> +=C2=A0 =C2=A0 if ( !prop )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 val =3D cpu_to_fdt32(2);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( fdt_setprop(fdt, node, "#addres= s-cells", &val, sizeof(val)) )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 *addr_cells =3D 2;
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 else
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 *addr_cells =3D fdt32_to_cpu(*((uint32_t = *)prop->data));
> +
> +=C2=A0 =C2=A0 prop =3D fdt_get_property(fdt, node, "#size-cells&= quot;, &len);
> +=C2=A0 =C2=A0 if ( !prop )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 val =3D cpu_to_fdt32(2);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( fdt_setprop(fdt, node, "#size-c= ells", &val, sizeof(val)) )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 *size_cells =3D 2;
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 else
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 *size_cells =3D fdt32_to_cpu(*((uint32_t = *)prop->data));
> +
> +=C2=A0 =C2=A0 /*
> +=C2=A0 =C2=A0 =C2=A0* Make sure ranges is empty if it exists, otherwi= se create empty ranges
> +=C2=A0 =C2=A0 =C2=A0* property.
> +=C2=A0 =C2=A0 =C2=A0*/
> +=C2=A0 =C2=A0 prop =3D fdt_get_property(fdt, node, "ranges"= , &len);
> +=C2=A0 =C2=A0 if ( !prop )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 val =3D cpu_to_fdt32(0);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( fdt_setprop(fdt, node, "ranges&= quot;, &val, 0) )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 else if ( fdt32_to_cpu(prop->len) )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;=C2=A0 /* Non-emp= ty ranges property */
> +=C2=A0 =C2=A0 return node;
> +}
> +
> +/*
> + * Set a single 'reg' property taking into account the
> + * configured addr and size cell sizes.
> + */
> +static int __init fdt_set_reg(void *fdt, int node, int addr_cells, > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 int size_cells, uint64_t addr, uint64_t= len)
> +{
> +=C2=A0 =C2=A0 uint8_t data[16]; /* at most 2 64 bit words */
> +=C2=A0 =C2=A0 void *p =3D data;
> +
> +=C2=A0 =C2=A0 /* Make sure that the values provided can be represente= d in
> +=C2=A0 =C2=A0 =C2=A0* the reg property.
> +=C2=A0 =C2=A0 =C2=A0*/
> +=C2=A0 =C2=A0 if ( addr_cells =3D=3D 1 && (addr >> 32) = )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
> +=C2=A0 =C2=A0 if ( size_cells =3D=3D 1 && (len >> 32) )=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
> +
> +=C2=A0 =C2=A0 if ( addr_cells =3D=3D 1 )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 *(uint32_t *)p =3D cpu_to_fdt32(addr); > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 p +=3D sizeof(uint32_t);
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 else if ( addr_cells =3D=3D 2 )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 *(uint64_t *)p =3D cpu_to_fdt64(addr); > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 p +=3D sizeof(uint64_t);
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 else
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
> +
> +=C2=A0 =C2=A0 if ( size_cells =3D=3D 1 )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 *(uint32_t *)p =3D cpu_to_fdt32(len);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 p +=3D sizeof(uint32_t);
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 else if ( size_cells =3D=3D 2 )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 *(uint64_t *)p =3D cpu_to_fdt64(len);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 p +=3D sizeof(uint64_t);
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 else
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
> +
> +=C2=A0 =C2=A0 return(fdt_setprop(fdt, node, "reg", data, p = - (void *)data));
> +}
> +
> +static void __init *lookup_fdt_config_table(EFI_SYSTEM_TABLE *sys_tab= le)
> +{
> +=C2=A0 =C2=A0 const EFI_GUID fdt_guid =3D DEVICE_TREE_GUID;
> +=C2=A0 =C2=A0 EFI_CONFIGURATION_TABLE *tables;
> +=C2=A0 =C2=A0 void *fdt =3D NULL;
> +=C2=A0 =C2=A0 int i;
> +
> +=C2=A0 =C2=A0 tables =3D sys_table->ConfigurationTable;
> +=C2=A0 =C2=A0 for ( i =3D 0; i < sys_table->NumberOfTableEntrie= s; i++ )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( match_guid(&tables[i].VendorGuid= , &fdt_guid) )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fdt =3D tables[i].VendorTab= le;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 return fdt;
> +}
> +
> +static EFI_STATUS __init efi_get_memory_map(void **map,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 UINTN *mmap_size,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 UINTN *desc_size,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 UINT32 *desc_ver,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 UINTN *key_ptr)
> +{
> +=C2=A0 =C2=A0 EFI_MEMORY_DESCRIPTOR *m =3D NULL;
> +=C2=A0 =C2=A0 EFI_STATUS status;
> +=C2=A0 =C2=A0 unsigned long key;
> +=C2=A0 =C2=A0 u32 desc_version;
> +
> +=C2=A0 =C2=A0 *map =3D NULL;
> +=C2=A0 =C2=A0 *mmap_size =3D EFI_PAGE_SIZE;
> +again:
> +=C2=A0 =C2=A0 *mmap_size +=3D EFI_PAGE_SIZE;=C2=A0 /* Page size is al= location granularity */
> +=C2=A0 =C2=A0 status =3D efi_bs->AllocatePool(EfiLoaderData, *mmap= _size, (void **)&m);
> +=C2=A0 =C2=A0 if ( status !=3D EFI_SUCCESS )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return status;
> +
> +=C2=A0 =C2=A0 *desc_size =3D 0;
> +=C2=A0 =C2=A0 key =3D 0;
> +=C2=A0 =C2=A0 status =3D efi_bs->GetMemoryMap(mmap_size, m, &k= ey, desc_size, &desc_version);
> +=C2=A0 =C2=A0 if ( status =3D=3D EFI_BUFFER_TOO_SMALL )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 efi_bs->FreePool(m);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 goto again;
> +=C2=A0 =C2=A0 }
> +
> +=C2=A0 =C2=A0 if ( status !=3D EFI_SUCCESS )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 efi_bs->FreePool(m);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return status;
> +=C2=A0 =C2=A0 }
> +
> +=C2=A0 =C2=A0 if ( key_ptr && status =3D=3D EFI_SUCCESS )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 *key_ptr =3D key;
> +=C2=A0 =C2=A0 if ( desc_ver && status =3D=3D EFI_SUCCESS ) > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 *desc_ver =3D desc_version;
> +
> +=C2=A0 =C2=A0 *map =3D m;
> +=C2=A0 =C2=A0 return status;
> +}
> +
> +static EFI_STATUS __init efi_process_memory_map_bootinfo(EFI_MEMORY_D= ESCRIPTOR *map,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 UINTN mmap_size,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 UINTN desc_size)
> +{
> +=C2=A0 =C2=A0 int Index;
> +=C2=A0 =C2=A0 int i =3D 0;
> +
> +=C2=A0 =C2=A0 EFI_MEMORY_DESCRIPTOR *desc_ptr =3D map;
> +
> +=C2=A0 =C2=A0 for ( Index =3D 0; Index < (mmap_size / desc_size); = Index++ )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( desc_ptr->Type =3D=3D EfiConventi= onalMemory
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| desc_ptr->Type = =3D=3D EfiBootServicesCode
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| desc_ptr->Type = =3D=3D EfiBootServicesData )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 bootinfo.mem.bank[i].start = =3D desc_ptr->PhysicalStart;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 bootinfo.mem.bank[i].size = =3D desc_ptr->NumberOfPages * EFI_PAGE_SIZE;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( ++i >=3D NR_MEM_BAN= KS )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 PrintStr(L&qu= ot;Warning: All ");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 DisplayUint(N= R_MEM_BANKS, -1);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 PrintStr(L&qu= ot; bootinfo mem banks exhausted.\r\n");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 desc_ptr =3D NextMemoryDescriptor(desc_pt= r, desc_size);
> +=C2=A0 =C2=A0 }
> +
> +=C2=A0 =C2=A0 bootinfo.mem.nr_banks =3D i;
> +=C2=A0 =C2=A0 return EFI_SUCCESS;
> +
> +}
> +
> +/*
> + * Add the FDT nodes for the standard EFI information, which consist<= br> > + * of the System table address, the address of the final EFI memory m= ap,
> + * and memory map information.
> + */
> +EFI_STATUS __init fdt_add_uefi_nodes(EFI_SYSTEM_TABLE *sys_table,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 void *fdt,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 EFI_MEMORY_DESCRIPTOR *memory_map,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 UINTN map_size,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 UINTN desc_size,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 UINT32 desc_ver)
> +{
> +=C2=A0 =C2=A0 int node;
> +=C2=A0 =C2=A0 int status;
> +=C2=A0 =C2=A0 u32 fdt_val32;
> +=C2=A0 =C2=A0 u64 fdt_val64;
> +=C2=A0 =C2=A0 int prev;
> +=C2=A0 =C2=A0 /*
> +=C2=A0 =C2=A0 =C2=A0* Delete any memory nodes present.=C2=A0 The EFI = memory map is the only
> +=C2=A0 =C2=A0 =C2=A0* memory description provided to Xen.
> +=C2=A0 =C2=A0 =C2=A0*/
> +=C2=A0 =C2=A0 prev =3D 0;
> +=C2=A0 =C2=A0 for (;;)
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 const char *type;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 int len;
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 node =3D fdt_next_node(fdt, prev, NULL);<= br> > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( node < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 type =3D fdt_getprop(fdt, node, "dev= ice_type", &len);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( type && strncmp(type, "= memory", len) =3D=3D 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fdt_del_node(fdt, node); > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 continue;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 prev =3D node;
> +=C2=A0 =C2=A0 }
> +
> +=C2=A0 =C2=A0 /* Add FDT entries for EFI runtime services in chosen n= ode. */
> +=C2=A0 =C2=A0 node =3D fdt_subnode_offset(fdt, 0, "chosen")= ;
> +=C2=A0 =C2=A0 if ( node < 0 )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 node =3D fdt_add_subnode(fdt, 0, "ch= osen");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( node < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 status =3D node; /* node is= error code when negative */
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 goto fdt_set_fail;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 }

setup_chosen_node?

Yes, thi= s should be done here as well. =C2=A0I will add that for the case of creati= ng
a new FDT.=C2=A0


> +=C2=A0 =C2=A0 fdt_val64 =3D cpu_to_fdt64((u64)(uintptr_t)sys_table);<= br> > +=C2=A0 =C2=A0 status =3D fdt_setprop(fdt, node, "linux,uefi-syst= em-table",
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0&fdt_val64, sizeof(fdt_val64));
> +=C2=A0 =C2=A0 if ( status )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 goto fdt_set_fail;
> +
> +=C2=A0 =C2=A0 fdt_val64 =3D cpu_to_fdt64((u64)(uintptr_t)memory_map);=
> +=C2=A0 =C2=A0 status =3D fdt_setprop(fdt, node, "linux,uefi-mmap= -start",
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0&fdt_val64,=C2=A0 sizeof(fdt_val64));
> +=C2=A0 =C2=A0 if ( status )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 goto fdt_set_fail;
> +
> +=C2=A0 =C2=A0 fdt_val32 =3D cpu_to_fdt32(map_size);
> +=C2=A0 =C2=A0 status =3D fdt_setprop(fdt, node, "linux,uefi-mmap= -size",
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0&fdt_val32,=C2=A0 sizeof(fdt_val32));
> +=C2=A0 =C2=A0 if ( status )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 goto fdt_set_fail;
> +
> +=C2=A0 =C2=A0 fdt_val32 =3D cpu_to_fdt32(desc_size);
> +=C2=A0 =C2=A0 status =3D fdt_setprop(fdt, node, "linux,uefi-mmap= -desc-size",
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0&fdt_val32, sizeof(fdt_val32));
> +=C2=A0 =C2=A0 if ( status )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 goto fdt_set_fail;
> +
> +=C2=A0 =C2=A0 fdt_val32 =3D cpu_to_fdt32(desc_ver);
> +=C2=A0 =C2=A0 status =3D fdt_setprop(fdt, node, "linux,uefi-mmap= -desc-ver",
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0&fdt_val32, sizeof(fdt_val32));
> +=C2=A0 =C2=A0 if ( status )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 goto fdt_set_fail;
> +
> +=C2=A0 =C2=A0 return EFI_SUCCESS;
> +
> +fdt_set_fail:
> +=C2=A0 =C2=A0 if ( status =3D=3D -FDT_ERR_NOSPACE )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return EFI_BUFFER_TOO_SMALL;
> +
> +=C2=A0 =C2=A0 return EFI_LOAD_ERROR;
> +}
> +
> +/*
> + * Allocates new memory for a larger FDT, and frees existing memory i= f
> + * struct file size is non-zero.=C2=A0 Updates file struct with new m= emory
> + * address/size for later freeing.=C2=A0 If fdtfile.ptr is NULL, an e= mpty FDT
> + * is created.
> + */
> +static void __init *fdt_increase_size(struct file *fdtfile, int add_s= ize)
> +{
> +=C2=A0 =C2=A0 EFI_STATUS status;
> +=C2=A0 =C2=A0 EFI_PHYSICAL_ADDRESS fdt_addr;
> +=C2=A0 =C2=A0 int fdt_size;
> +=C2=A0 =C2=A0 int pages;
> +=C2=A0 =C2=A0 void *new_fdt;
> +
> +=C2=A0 =C2=A0 if ( fdtfile->ptr )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 fdt_size =3D fdt_totalsize(fdtfile->pt= r);
> +=C2=A0 =C2=A0 else
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 fdt_size =3D 0;
> +
> +=C2=A0 =C2=A0 pages =3D PFN_UP(fdt_size) + PFN_UP(add_size);

Shouldn't this be PFN_UP(fdt_size+add_size)?
Yup, I will fix this.=C2=A0


> +=C2=A0 =C2=A0 status =3D efi_bs->AllocatePages(AllocateAnyPages, E= fiLoaderData,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pages, &fdt_add= r);
> +
> +=C2=A0 =C2=A0 if ( status !=3D EFI_SUCCESS )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return NULL;
> +
> +=C2=A0 =C2=A0 new_fdt =3D (void *)fdt_addr;
> +
> +=C2=A0 =C2=A0 if ( fdt_size )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( fdt_open_into(dtbfile.ptr, new_fdt, = pages * EFI_PAGE_SIZE) )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return NULL;
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 else
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 /*
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* Create an empty FDT if not provid= ed one, which is the expected case
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* when booted from the UEFI shell o= n an ACPI only system.=C2=A0 We will use
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* the FDT to pass the EFI informati= on to Xen, as well as nodes for
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* any modules the stub loads.=C2=A0= The ACPI tables are part of the UEFI
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* system table that is passed in th= e FDT.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*/
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( fdt_create_empty_tree(new_fdt, pages= * EFI_PAGE_SIZE) )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return NULL;
> +=C2=A0 =C2=A0 }
> +
> +=C2=A0 =C2=A0 /*
> +=C2=A0 =C2=A0 =C2=A0* Now that we have the new FDT allocated and copi= ed, free the
> +=C2=A0 =C2=A0 =C2=A0* original and update the struct file so that the= error handling
> +=C2=A0 =C2=A0 =C2=A0* code will free it.=C2=A0 If the original FDT ca= me from a configuration
> +=C2=A0 =C2=A0 =C2=A0* table, we don't own that memory and can'= ;t free it.
> +=C2=A0 =C2=A0 =C2=A0*/
> +=C2=A0 =C2=A0 if ( dtbfile.size )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 efi_bs->FreePages(dtbfile.addr, PFN_UP= (dtbfile.size));
> +
> +=C2=A0 =C2=A0 /* Update 'file' info for new memory so we clea= n it up on error exits */
> +=C2=A0 =C2=A0 dtbfile.addr =3D fdt_addr;
> +=C2=A0 =C2=A0 dtbfile.size =3D pages * EFI_PAGE_SIZE;
> +=C2=A0 =C2=A0 return new_fdt;
> +}
> +
> +static void __init efi_arch_pci(void)
> +{
> +}
> +
> +static void __init efi_arch_relocate_image(unsigned long delta)
> +{
> +}
> +
> +static void __init efi_arch_process_memory_map(EFI_SYSTEM_TABLE *Syst= emTable,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0void *map,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0UINTN map_size,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0UINTN desc_size,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0UINT32 desc_ver)
> +{
> +=C2=A0 =C2=A0 EFI_STATUS status;
> +
> +=C2=A0 =C2=A0 status =3D efi_process_memory_map_bootinfo(map, map_siz= e, desc_size);
> +=C2=A0 =C2=A0 if ( EFI_ERROR(status) )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"ERROR processing EFI memory= map\r\n");
> +
> +=C2=A0 =C2=A0 status =3D fdt_add_uefi_nodes(SystemTable, fdt, map, ma= p_size, desc_size,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 desc_ver);
> +=C2=A0 =C2=A0 if ( EFI_ERROR(status) )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 PrintErrMesg(L"ERROR updating FDT\r\= n", status);
> +}
> +
> +static void __init efi_arch_pre_exit_boot(void)
> +{
> +}
> +
> +static void __init efi_arch_post_exit_boot(void)
> +{
> +=C2=A0 =C2=A0 efi_xen_start(fdt);
> +}
> +
> +static void __init efi_arch_cfg_file(EFI_FILE_HANDLE dir_handle, char= *section)
> +{
> +=C2=A0 =C2=A0 union string name;
> +=C2=A0 =C2=A0 name.s =3D get_value(&cfg, section, "dtb"= );
> +=C2=A0 =C2=A0 if ( name.s )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( !read_file(dir_handle, &dtbfile,= name.s))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(NULL);
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 fdt =3D fdt_increase_size(&dtbfile, cfg.size + EFI_= PAGE_SIZE);
> +=C2=A0 =C2=A0 if ( !fdt )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"Unable to create new FDT\r\= n");
> +}
> +
> +static void __init efi_arch_get_memory_map(UINTN *map_size,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0void **map,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0UINTN *map_key, UINTN *desc_size,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0UINT32 *desc_ver)
> +{
> +=C2=A0 =C2=A0 EFI_STATUS status;
> +
> +=C2=A0 =C2=A0 status =3D efi_get_memory_map(map, map_size, desc_size,= desc_ver, map_key);
> +=C2=A0 =C2=A0 if ( EFI_ERROR(status) )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"ERROR getting EFI memory ma= p.\r\n");
> +=C2=A0 =C2=A0 memmap =3D *map;
> +}
> +
> +static void __init efi_arch_edd(void)
> +{
> +}
> +
> +static void __init efi_arch_video(bool_t base_video,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 UINTN cols, UINTN rows, U= INTN depth,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 EFI_GRAPHICS_OUTPUT_PROTO= COL *gop)
> +{
> +}
> +
> +static void __init efi_arch_memory(void)
> +{
> +}
> +
> +static void __init efi_arch_handle_cmdline(CHAR16 *image_name,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0CHAR16 *cmdline_options,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0char *cfgfile_options)
> +{
> +=C2=A0 =C2=A0 union string name;
> +=C2=A0 =C2=A0 char *buf;
> +=C2=A0 =C2=A0 EFI_STATUS status;
> +=C2=A0 =C2=A0 int prop_len;
> +=C2=A0 =C2=A0 int chosen;
> +
> +=C2=A0 =C2=A0 /* locate chosen node, which is where we add Xen module= info. */
> +=C2=A0 =C2=A0 chosen =3D fdt_subnode_offset(fdt, 0, "chosen"= ;);
> +=C2=A0 =C2=A0 if ( chosen < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"ERROR unable to find chosen= node\r\n");
> +
> +=C2=A0 =C2=A0 status =3D efi_bs->AllocatePool(EfiBootServicesData,= EFI_PAGE_SIZE, (void **)&buf);
> +=C2=A0 =C2=A0 if ( EFI_ERROR(status) )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 PrintErrMesg(L"ERROR allocating memo= ry.\r\n", status);
> +
> +=C2=A0 =C2=A0 if ( image_name )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 name.w =3D image_name;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 w2s(&name);
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 else
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 name.s =3D "xen";
> +
> +=C2=A0 =C2=A0 prop_len =3D 0;
> +=C2=A0 =C2=A0 prop_len +=3D snprintf(buf + prop_len,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0EFI_PAGE_SIZE - prop_len, "%s", name.= s);
> +=C2=A0 =C2=A0 if ( prop_len >=3D EFI_PAGE_SIZE )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"FDT string overflow");=
> +
> +=C2=A0 =C2=A0 if ( cfgfile_options )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 prop_len +=3D snprintf(buf + prop_len, > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0EFI_PAGE_SIZE - prop_len, " = %s", cfgfile_options);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( prop_len >=3D EFI_PAGE_SIZE )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"FDT string ov= erflow");
> +=C2=A0 =C2=A0 }
> +
> +=C2=A0 =C2=A0 if ( cmdline_options )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 name.w =3D cmdline_options;
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 w2s(&name);
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 else
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 name.s =3D NULL;
> +
> +=C2=A0 =C2=A0 if ( name.s )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 prop_len +=3D snprintf(buf + prop_len, > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0EFI_PAGE_SIZE - prop_len, " = %s", name.s);
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( prop_len >=3D EFI_PAGE_SIZE )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"FDT string ov= erflow");
> +=C2=A0 =C2=A0 }
> +
> +=C2=A0 =C2=A0 if ( fdt_setprop_string(fdt, chosen, "xen,xen-boot= args", buf) < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"unable to set xen,xen-boota= rgs property.");
> +
> +=C2=A0 =C2=A0 efi_bs->FreePool(buf);
> +}
> +
> +static void __init efi_arch_handle_module(struct file *file, char *na= me,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 char *options)
> +{
> +=C2=A0 =C2=A0 int node;
> +=C2=A0 =C2=A0 int chosen;
> +=C2=A0 =C2=A0 int addr_len, size_len;
> +
> +=C2=A0 =C2=A0 if ( file =3D=3D &dtbfile )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return;
> +=C2=A0 =C2=A0 chosen =3D setup_chosen_node(fdt, &addr_len, &s= ize_len);
> +=C2=A0 =C2=A0 if ( chosen < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"Unable to setup chosen node= \r\n");
> +
> +=C2=A0 =C2=A0 if ( file =3D=3D &ramdisk )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 char ramdisk_compat[] =3D "multiboot= ,ramdisk\0multiboot,module";
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 node =3D fdt_add_subnode(fdt, chosen, &qu= ot;ramdisk");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( node < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"Error adding = ramdisk FDT node.");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( fdt_setprop(fdt, node, "compati= ble", ramdisk_compat,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0sizeof(ramdisk_compat)) < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"unable to set= compatible property.");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( fdt_set_reg(fdt, node, addr_len, siz= e_len, ramdisk.addr,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= ramdisk.size) < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"unable to set= reg property.");
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 else if ( file =3D=3D &xsm )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 char xsm_compat[] =3D "xen,xsm-polic= y\0multiboot,module";
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 node =3D fdt_add_subnode(fdt, chosen, &qu= ot;xsm");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( node < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"Error adding = xsm FDT node.");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( fdt_setprop(fdt, node, "compati= ble", xsm_compat,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0sizeof(xsm_compat)) < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"unable to set= compatible property.");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( fdt_set_reg(fdt, node, addr_len, siz= e_len, xsm.addr,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= xsm.size) < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"unable to set= reg property.");
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 else if ( file =3D=3D &kernel )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 char kernel_compat[] =3D "multiboot,= kernel\0multiboot,module";
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 node =3D fdt_add_subnode(fdt, chosen, &qu= ot;kernel");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( node < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"Error adding = dom0 FDT node.");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( fdt_setprop(fdt, node, "compati= ble", kernel_compat,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0sizeof(kernel_compat)) < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"unable to set= compatible property.");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( options && fdt_setprop_strin= g(fdt, node, "bootargs", options) < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"unable to set= bootargs property.");
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if ( fdt_set_reg(fdt, node, addr_len, siz= e_len, kernel.addr,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0kernel.size) < 0 )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"unable to set= reg property.");
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 else
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"Unknown module type\r\n&quo= t;);
> +}
> +
> +static void __init efi_arch_cpu(void)
> +{
> +}
> +
> +static void __init efi_arch_smbios(void)
> +{
> +}
> +
> +static void __init efi_arch_blexit(void)
> +{
> +=C2=A0 =C2=A0 if ( dtbfile.addr && dtbfile.size )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 efi_bs->FreePages(dtbfile.addr, PFN_UP= (dtbfile.size));
> +=C2=A0 =C2=A0 if ( memmap )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 efi_bs->FreePool(memmap);
> +}
> +
> +static void __init efi_arch_load_addr_check(EFI_LOADED_IMAGE *loaded_= image)
> +{
> +=C2=A0 =C2=A0 if ( (unsigned long)loaded_image->ImageBase & ((= 1 << 12) - 1) )
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 blexit(L"Xen must be loaded at a 4 K= Byte boundary.");
> +}
> +
> +static void __init efi_arch_runtime_setup(EFI_SYSTEM_TABLE *SystemTab= le)
> +{
> +}
> +
> +static __init bool_t efi_arch_use_config_file(EFI_SYSTEM_TABLE *Syste= mTable)
> +{
> +=C2=A0 =C2=A0 /*
> +=C2=A0 =C2=A0 =C2=A0* For arm, we may get a device tree from GRUB (or= other bootloader)
> +=C2=A0 =C2=A0 =C2=A0* that contains modules that have already been lo= aded into memory.=C2=A0 In
> +=C2=A0 =C2=A0 =C2=A0* this case, we do not use a configuration file, = and rely on the
> +=C2=A0 =C2=A0 =C2=A0* bootloader to have loaded all required modules = and appropriate
> +=C2=A0 =C2=A0 =C2=A0* options.
> +=C2=A0 =C2=A0 =C2=A0*/
> +
> +=C2=A0 =C2=A0 fdt =3D lookup_fdt_config_table(SystemTable);
> +=C2=A0 =C2=A0 dtbfile.ptr =3D fdt;
> +=C2=A0 =C2=A0 dtbfile.size =3D 0;=C2=A0 /* Config table memory can= 9;t be freed, so set size to 0 */
> +=C2=A0 =C2=A0 if ( !fdt || fdt_node_offset_by_compatible(fdt, 0, &quo= t;multiboot,module") < 0 )
> +=C2=A0 =C2=A0 {
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 /*
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* We either have no FDT, or one wit= hout modules, so we must have a
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* Xen EFI configuration file to spe= cify modules.=C2=A0 (dom0 required)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0*/
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 return 1;
> +=C2=A0 =C2=A0 }
> +=C2=A0 =C2=A0 PrintStr(L"Using modules provided by bootloader in= FDT\r\n");
> +=C2=A0 =C2=A0 /* We have modules already defined in fdt, just add spa= ce. */
> +=C2=A0 =C2=A0 fdt =3D fdt_increase_size(&dtbfile, EFI_PAGE_SIZE);=
> +=C2=A0 =C2=A0 return 0;
> +}
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/include/asm-arm/efi.h b/xen/include/asm-arm/efi.h
> new file mode 100644
> index 0000000..aae4716
> --- /dev/null
> +++ b/xen/include/asm-arm/efi.h
> @@ -0,0 +1,29 @@
> +#include <asm/efibind.h>
> +#include <efi/efidef.h>
> +#include <efi/efierr.h>
> +#include <efi/eficon.h>
> +#include <efi/efidevp.h>
> +#include <efi/eficapsule.h>
> +#include <efi/efiapi.h>
> +#include <xen/efi.h>
> +#include <xen/spinlock.h>
> +#include <asm/page.h>
> +
> +extern unsigned int efi_num_ct;
> +extern EFI_CONFIGURATION_TABLE *efi_ct;
> +
> +extern unsigned int efi_version, efi_fw_revision;
> +extern const CHAR16 *efi_fw_vendor;
> +
> +extern EFI_RUNTIME_SERVICES *efi_rs;
> +
> +extern UINTN efi_memmap_size, efi_mdesc_size;
> +extern void *efi_memmap;
> +
> +extern const struct efi_pci_rom *efi_pci_roms;
> +
> +extern UINT64 efi_boot_max_var_store_size, efi_boot_remain_var_store_= size,
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 efi_boot_max_var_siz= e;
> +
> +unsigned long efi_rs_enter(void);
> +void efi_rs_leave(unsigned long);
> diff --git a/xen/include/asm-arm/efibind.h b/xen/include/asm-arm/efibi= nd.h
> new file mode 100644
> index 0000000..09dca7a
> --- /dev/null
> +++ b/xen/include/asm-arm/efibind.h
> @@ -0,0 +1,2 @@
> +#include <xen/types.h>
> +#include <asm/arm64/efibind.h>
> diff --git a/xen/include/asm-arm/setup.h b/xen/include/asm-arm/setup.h=
> index 36e5704..40814e6 100644
> --- a/xen/include/asm-arm/setup.h
> +++ b/xen/include/asm-arm/setup.h
> @@ -3,7 +3,7 @@
>
>=C2=A0 #include <public/version.h>
>
> -#define NR_MEM_BANKS 8
> +#define NR_MEM_BANKS 32

Why?
At the very least you should write it in the commit message.

In the = EFI case, we have the EFI memory map which lists all memory by region and u= sage =C2=A0(ie available, boot_services, runtime, etc.)
not the p= hysical memory banks that are provided by FDT. =C2=A0I am putting the avail= able memory from the EFI memory map into the memory bank
list, so= this requires more entries. =C2=A0This is somewhat problematic as it is po= ssible for the EFI memory map to be very fragmented, which could lead
=
to a great many regions.

Roy



>=C2=A0 #define MAX_MODULES 5 /* Current maximum useful modules */
>
> --
> 2.1.0.rc1
>

--001a11c3584a3e8ed20502d5c699-- --===============5132891646511509130== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel --===============5132891646511509130==--