Hi Simon, On Fri, Jul 31, 2015 at 11:31 PM, Simon Glass <[email protected]> wrote: > From: Ben Stoltz <[email protected]> > > Add the required x86 glue code. This includes the initial start-up, > relocation and jumping to efi_main(). We also need to avoid fiddling with > interrupts. > > Signed-off-by: Ben Stoltz <[email protected]> > Signed-off-by: Simon Glass <[email protected]> > --- > > Changes in v2: > - Add ALIGN() before .dynamic in the linker script > - Add a blank line before return in the _relocate() function > - Add a comment as to why .hash has to be first in the linker script > - Add a comment as to why interrupt_init() must be skipped for EFI > - Drop unused DECLARE_GLOBAL_DATA_INIT > - Drop unused board_eth_init() > - Drop use of CONFIG_X86_64 since we don't support a 64-bit EFI application > yet > - Fix spacing around operators > - Move 64-bit crt0 to a later patch > - Move crt0 and reloc files into arch/x86/lib/efi/ > - Remove KEEP in the EFI linker script since garbage collection is not enabled > - Rename CONFIG_ARCH_EFI to CONFIG_EFI_APP > - Rename ImageBase to image_base > - Use SPDX for the EFI start and relocation code > - Use u-boot-app.efi instead of u-boot.efi > > Makefile | 6 +-- > arch/x86/Kconfig | 3 ++ > arch/x86/Makefile | 2 + > arch/x86/cpu/Makefile | 1 + > arch/x86/cpu/efi/Makefile | 8 +++ > arch/x86/cpu/efi/efi.c | 42 ++++++++++++++++ > arch/x86/cpu/efi/elf_ia32_efi.lds | 94 > ++++++++++++++++++++++++++++++++++++ > arch/x86/cpu/efi/sdram.c | 29 +++++++++++ > arch/x86/cpu/interrupts.c | 6 +++ > arch/x86/include/asm/arch-efi/gpio.h | 10 ++++ > arch/x86/lib/efi/crt0-efi-ia32.S | 52 ++++++++++++++++++++ > arch/x86/lib/efi/reloc_ia32.c | 72 +++++++++++++++++++++++++++ > 12 files changed, 322 insertions(+), 3 deletions(-) > create mode 100644 arch/x86/cpu/efi/Makefile > create mode 100644 arch/x86/cpu/efi/efi.c > create mode 100644 arch/x86/cpu/efi/elf_ia32_efi.lds > create mode 100644 arch/x86/cpu/efi/sdram.c > create mode 100644 arch/x86/include/asm/arch-efi/gpio.h > create mode 100644 arch/x86/lib/efi/crt0-efi-ia32.S > create mode 100644 arch/x86/lib/efi/reloc_ia32.c > > diff --git a/Makefile b/Makefile > index 3fb006b..6da9224 100644 > --- a/Makefile > +++ b/Makefile > @@ -750,7 +750,7 @@ ifneq ($(CONFIG_SPL_TARGET),) > ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%) > endif > ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf > -ALL-$(CONFIG_EFI_APP) += u-boot.efi > +ALL-$(CONFIG_EFI_APP) += u-boot-app.efi >
Can we move this change to http://patchwork.ozlabs.org/patch/502642/? > ifneq ($(BUILD_ROM),) > ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom > @@ -1079,8 +1079,8 @@ u-boot-dtb-tegra.bin: u-boot-nodtb-tegra.bin dts/dt.dtb > FORCE > endif > endif > > -OBJCOPYFLAGS_u-boot.efi := $(OBJCOPYFLAGS_EFI) > -u-boot.efi: u-boot FORCE > +OBJCOPYFLAGS_u-boot-app.efi := $(OBJCOPYFLAGS_EFI) > +u-boot-app.efi: u-boot FORCE > $(call if_changed,zobjcopy) > Ditto. > u-boot-img.bin: spl/u-boot-spl.bin u-boot.img FORCE > diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig > index e8968a7..7e6e89c 100644 > --- a/arch/x86/Kconfig > +++ b/arch/x86/Kconfig > @@ -11,6 +11,9 @@ choice > config VENDOR_COREBOOT > bool "coreboot" > > +config VENDOR_EFI > + bool "efi" > + > config VENDOR_EMULATION > bool "emulation" > > diff --git a/arch/x86/Makefile b/arch/x86/Makefile > index 36a6018..d104a49 100644 > --- a/arch/x86/Makefile > +++ b/arch/x86/Makefile > @@ -2,7 +2,9 @@ > # SPDX-License-Identifier: GPL-2.0+ > # > > +ifeq ($(CONFIG_EFI_APP),) > head-y := arch/x86/cpu/start.o > +endif > ifeq ($(CONFIG_SPL_BUILD),y) > head-y += arch/x86/cpu/start16.o > head-y += arch/x86/cpu/resetvec.o > diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile > index 8a8e63e..5e058c0 100644 > --- a/arch/x86/cpu/Makefile > +++ b/arch/x86/cpu/Makefile > @@ -14,6 +14,7 @@ obj-y += interrupts.o cpu.o cpu_x86.o call64.o > > obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/ > obj-$(CONFIG_SYS_COREBOOT) += coreboot/ > +obj-$(CONFIG_EFI_APP) += efi/ > obj-$(CONFIG_QEMU) += qemu/ > obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/ > obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/ > diff --git a/arch/x86/cpu/efi/Makefile b/arch/x86/cpu/efi/Makefile > new file mode 100644 > index 0000000..e091637 > --- /dev/null > +++ b/arch/x86/cpu/efi/Makefile > @@ -0,0 +1,8 @@ > +# > +# Copyright (c) 2015 Google, Inc > +# > +# SPDX-License-Identifier: GPL-2.0+ > +# > + > +obj-y += efi.o > +obj-y += sdram.o > diff --git a/arch/x86/cpu/efi/efi.c b/arch/x86/cpu/efi/efi.c > new file mode 100644 > index 0000000..75ba0d4 > --- /dev/null > +++ b/arch/x86/cpu/efi/efi.c > @@ -0,0 +1,42 @@ > +/* > + * Copyright (c) 2015 Google, Inc > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include <common.h> > +#include <fdtdec.h> > +#include <netdev.h> > + > +int arch_cpu_init(void) > +{ > +#ifdef CONFIG_SYS_X86_TSC_TIMER > + timer_set_base(rdtsc()); > +#endif > + > + return 0; > +} > + > +int board_early_init_f(void) > +{ > + return 0; > +} > + > +int print_cpuinfo(void) > +{ > + return default_print_cpuinfo(); > +} > + > +void board_final_cleanup(void) > +{ > +} > + > +int misc_init_r(void) > +{ > + return 0; > +} > + > +int arch_misc_init(void) > +{ > + return 0; > +} > diff --git a/arch/x86/cpu/efi/elf_ia32_efi.lds > b/arch/x86/cpu/efi/elf_ia32_efi.lds > new file mode 100644 > index 0000000..a83ddd0 > --- /dev/null > +++ b/arch/x86/cpu/efi/elf_ia32_efi.lds > @@ -0,0 +1,94 @@ > +/* > + * U-Boot EFI linker script > + * > + * SPDX-License-Identifier: bsd-2-clause Should be "BSD-2-Clause" (per http://spdx.org/licenses/) > + * > + * Modified from usr/lib32/elf_ia32_efi.lds in gnu-efi > + */ > + > +#include <config.h> > + > +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") > +OUTPUT_ARCH(i386) > +ENTRY(_start) > +SECTIONS > +{ > + image_base = .; > + .hash : { *(.hash) } /* this MUST come first, EFI expects it */ > + . = ALIGN(4096); > + .text : > + { > + *(.text) > + *(.text.*) > + *(.gnu.linkonce.t.*) > + } > + . = ALIGN(4096); > + .sdata : > + { > + *(.got.plt) > + *(.got) > + *(.srodata) > + *(.sdata) > + *(.sbss) > + *(.scommon) > + } > + . = ALIGN(4096); > + .data : > + { > + *(.rodata*) > + *(.data) > + *(.data1) > + *(.data.*) > + *(.sdata) > + *(.got.plt) > + *(.got) > + /* > + * the EFI loader doesn't seem to like a .bss section, so we > + * stick it all into .data: > + */ > + *(.sbss) > + *(.scommon) > + *(.dynbss) > + *(.bss) > + *(COMMON) > + > + /* U-Boot lists and device tree */ > + . = ALIGN(8); > + *(SORT(.u_boot_list*)); > + . = ALIGN(8); > + *(.dtb*); > + } > + > + . = ALIGN(4096); > + .dynamic : { *(.dynamic) } > + . = ALIGN(4096); > + .rel : > + { > + *(.rel.data) > + *(.rel.data.*) > + *(.rel.got) > + *(.rel.stab) > + *(.data.rel.ro.local) > + *(.data.rel.local) > + *(.data.rel.ro) > + *(.data.rel*) > + *(.rel.u_boot_list*) > + } > + . = ALIGN(4096); > + .reloc : /* This is the PECOFF .reloc section! */ > + { > + *(.reloc) > + } > + . = ALIGN(4096); > + .dynsym : { *(.dynsym) } > + . = ALIGN(4096); > + .dynstr : { *(.dynstr) } > + . = ALIGN(4096); > + /DISCARD/ : > + { > + *(.rel.reloc) > + *(.eh_frame) > + *(.note.GNU-stack) > + } > + .comment 0 : { *(.comment) } > +} > diff --git a/arch/x86/cpu/efi/sdram.c b/arch/x86/cpu/efi/sdram.c > new file mode 100644 > index 0000000..5159944 > --- /dev/null > +++ b/arch/x86/cpu/efi/sdram.c > @@ -0,0 +1,29 @@ > +/* > + * Copyright (c) 2015 Google, Inc > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include <common.h> > +#include <efi.h> > +#include <asm/u-boot-x86.h> > + > +DECLARE_GLOBAL_DATA_PTR; > + > +ulong board_get_usable_ram_top(ulong total_size) > +{ > + return (ulong)efi_get_ram_base() + gd->ram_size; > +} > + > +int dram_init(void) > +{ > + /* gd->ram_size is set as part of EFI init */ > + > + return 0; > +} > + > +void dram_init_banksize(void) > +{ > + gd->bd->bi_dram[0].start = efi_get_ram_base(); > + gd->bd->bi_dram[0].size = CONFIG_EFI_RAM_SIZE; > +} > diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c > index 3a9c2d4..a112938 100644 > --- a/arch/x86/cpu/interrupts.c > +++ b/arch/x86/cpu/interrupts.c > @@ -242,6 +242,11 @@ int disable_interrupts(void) > > int interrupt_init(void) > { > + /* > + * When running as an EFI application we are not in control of > + * interrupts and should leave them alone. > + */ > +#ifndef CONFIG_EFI_APP > /* Just in case... */ > disable_interrupts(); > > @@ -255,6 +260,7 @@ int interrupt_init(void) > > /* It is now safe to enable interrupts */ > enable_interrupts(); > +#endif > > return 0; > } > diff --git a/arch/x86/include/asm/arch-efi/gpio.h > b/arch/x86/include/asm/arch-efi/gpio.h > new file mode 100644 > index 0000000..f044f07 > --- /dev/null > +++ b/arch/x86/include/asm/arch-efi/gpio.h > @@ -0,0 +1,10 @@ > +/* > + * Copyright (c) 2015 Google, Inc. > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#ifndef _X86_ARCH_GPIO_H_ > +#define _X86_ARCH_GPIO_H_ > + > +#endif /* _X86_ARCH_GPIO_H_ */ > diff --git a/arch/x86/lib/efi/crt0-efi-ia32.S > b/arch/x86/lib/efi/crt0-efi-ia32.S > new file mode 100644 > index 0000000..30e5eb0 > --- /dev/null > +++ b/arch/x86/lib/efi/crt0-efi-ia32.S > @@ -0,0 +1,52 @@ > +/* > + * crt0-efi-ia32.S - x86 EFI startup code. > + * > + * Copyright (C) 1999 Hewlett-Packard Co. > + * Contributed by David Mosberger <[email protected]>. > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > + .text > + .align 4 > + > + .globl _start > +_start: > + pushl %ebp > + movl %esp,%ebp > + > + pushl 12(%ebp) # copy "image" argument > + pushl 8(%ebp) # copy "systab" argument > + > + call 0f > +0: popl %eax > + movl %eax,%ebx > + > + addl $image_base-0b,%eax # %eax = ldbase > + addl $_DYNAMIC-0b,%ebx # %ebx = _DYNAMIC > + > + pushl %ebx # pass _DYNAMIC as second argument > + pushl %eax # pass ldbase as first argument > + call _relocate > + popl %ebx > + popl %ebx > + testl %eax,%eax > + jne .exit > + call efi_main # call app with "image" and "systab" argument > + > +.exit: leave > + ret > + > + /* > + * hand-craft a dummy .reloc section so EFI knows it's a relocatable > + * executable: > + */ > + .data > +dummy: .long 0 > + > +#define IMAGE_REL_ABSOLUTE 0 > + .section .reloc > + .long dummy /* Page RVA */ > + .long 10 /* Block Size (2*4+2) > */ > + .word (IMAGE_REL_ABSOLUTE << 12) + 0 /* reloc for dummy */ > diff --git a/arch/x86/lib/efi/reloc_ia32.c b/arch/x86/lib/efi/reloc_ia32.c > new file mode 100644 > index 0000000..4d68255 > --- /dev/null > +++ b/arch/x86/lib/efi/reloc_ia32.c > @@ -0,0 +1,72 @@ > +/* > + * reloc_ia32.c - position independent x86 ELF shared object relocator > + * Copyright (C) 1999 Hewlett-Packard Co. > + * Contributed by David Mosberger <[email protected]>. > + * > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#include <common.h> > +#include <efi.h> > +#include <elf.h> > +#include <asm/elf.h> > + > +efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image, > + struct efi_system_table *systab) > +{ > + long relsz = 0, relent = 0; > + Elf32_Rel *rel = 0; > + unsigned long *addr; > + int i; > + > + for (i = 0; dyn[i].d_tag != DT_NULL; ++i) { > + switch (dyn[i].d_tag) { > + case DT_REL: > + rel = (Elf32_Rel *)((unsigned long)dyn[i].d_un.d_ptr + > + ldbase); > + break; > + > + case DT_RELSZ: > + relsz = dyn[i].d_un.d_val; > + break; > + > + case DT_RELENT: > + relent = dyn[i].d_un.d_val; > + break; > + > + case DT_RELA: > + break; > + > + default: > + break; > + } > + } > + > + if (!rel && relent == 0) > + return EFI_SUCCESS; > + > + if (!rel || relent == 0) > + return EFI_LOAD_ERROR; > + > + while (relsz > 0) { > + /* apply the relocs */ > + switch (ELF32_R_TYPE(rel->r_info)) { > + case R_386_NONE: > + break; > + > + case R_386_RELATIVE: > + addr = (unsigned long *)(ldbase + rel->r_offset); > + *addr += ldbase; > + break; > + > + default: > + break; > + } > + rel = (Elf32_Rel *)((char *)rel + relent); > + relsz -= relent; > + } > + > + return EFI_SUCCESS; > +} > -- Regards, Bin _______________________________________________ U-Boot mailing list [email protected] http://lists.denx.de/mailman/listinfo/u-boot

