[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH V4 15/15] Add ARM EFI boot support



On Fri, 12 Sep 2014, Roy Franz wrote:
> On Fri, Sep 12, 2014 at 10:41 AM, Stefano Stabellini
> <stefano.stabellini@xxxxxxxxxxxxx> 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 
> >> <stefano.stabellini@xxxxxxxxxxxxx> 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 <roy.franz@xxxxxxxxxx>
> >>       > ---
> >>       >  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 <asm/page.h>
> >>       >  #include <asm/asm_defns.h>
> >>       >  #include <asm/early_printk.h>
> >>       > +#include <efi/efierr.h>
> >>       > +#include <asm/arm64/efibind.h>
> >>       >
> >>       >  #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?

Sorry my comment was wrong, not had my coffee yet!
I meant right before:

msr   sctlr_el2, x0

to make sure that ordering and arguments are correct. And yes, we do the
same when enabling dcache see:

        mrs   x0, SCTLR_EL2
        orr   x0, x0, #SCTLR_M       /* Enable MMU */
        orr   x0, x0, #SCTLR_C       /* Enable D-cache */
        dsb   sy                     /* Flush PTE writes and finish reads */
        msr   SCTLR_EL2, x0          /* now paging is enabled */
        isb                          /* Now, flush the icache */


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.