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: Fri, 12 Sep 2014 10:50:21 -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: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 On Fri, Sep 12, 2014 at 10:41 AM, Stefano Stabellini wrote: > Please use plain text in emails, no html. > > On Thu, 11 Sep 2014, Roy Franz wrote: >> On Thu, Sep 11, 2014 at 5:49 PM, Stefano Stabellini 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 > > I think this would be to make sure __flush_dcache_all reads the correct > arguments. We do the same when enabling dcache. So where exactly are you suggesting the dsb? Before the call to __flush_dcache_all? Roy sorry about the html... gmail switches it back to html sometines...