Hi Simon, On Wed, Jul 22, 2015 at 11:49 PM, Simon Glass <s...@chromium.org> wrote: > Most EFI implementations use 64-bit. Add a way to build U-Boot as a 64-bit > EFI payload. The payload unpacks a (32-bit) U-Boot and starts it. This can > be enabled for x86 boards at present. > > Signed-off-by: Simon Glass <s...@chromium.org> > --- > > Makefile | 2 +- > arch/x86/config.mk | 11 +++++++++ > arch/x86/include/asm/types.h | 5 +++- > lib/efi/efi_stub.c | 58 > ++++++++++++++++++++++++++++++++++++++++---- > 4 files changed, 69 insertions(+), 7 deletions(-) > > diff --git a/Makefile b/Makefile > index 9f863e1..6e3edb4 100644 > --- a/Makefile > +++ b/Makefile > @@ -1109,7 +1109,7 @@ u-boot-payload.lds: $(LDSCRIPT_EFI) FORCE > u-boot-payload: u-boot-dtb.bin.o u-boot-payload.lds \ > FORCE > $(LD) $(LDFLAGS_EFI) -o $@ \ > - -T u-boot-payload.lds \ > + -T u-boot-payload.lds arch/x86/cpu/call32.o \ > lib/efi/efi.o lib/efi/efi_stub.o u-boot-dtb.bin.o \ > $(addprefix arch/$(ARCH)/lib/,$(EFISTUB)) > > diff --git a/arch/x86/config.mk b/arch/x86/config.mk > index bb0b254..5107b43 100644 > --- a/arch/x86/config.mk > +++ b/arch/x86/config.mk > @@ -15,7 +15,10 @@ PF_CPPFLAGS_X86 := $(call cc-option, > -fno-toplevel-reorder, \ > > PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_X86) > PLATFORM_CPPFLAGS += -fno-dwarf2-cfi-asm > + > +ifeq ($(CONFIG_X86_64),)
Again I don't see CONFIG_X86_64 is introduced anywhere so far. > PLATFORM_CPPFLAGS += -march=i386 -m32 > +endif > > PLATFORM_RELFLAGS += -ffunction-sections -fvisibility=hidden > > @@ -33,11 +36,19 @@ OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j > .dynamic -j .dynsym \ > CFLAGS_NON_EFI := -mregparm=3 > CFLAGS_EFI := -fpic -fshort-wchar $(call cc-option, -mno-red-zone) > > +ifeq ($(CONFIG_X86_64)$(CONFIG_EFI_STUB_64BIT),) > EFIARCH=ia32 > +else > +EFIARCH=x86_64 > +endif > > LDSCRIPT_EFI := $(srctree)/$(CPUDIR)/efi/elf_$(EFIARCH)_efi.lds > +EFISTUB := crt0-efi-$(EFIARCH).o reloc_$(EFIARCH).o > OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH) > > +CPPFLAGS_REMOVE_crt0-efi-$(EFIARCH).o += $(CFLAGS_NON_EFI) > +CPPFLAGS_crt0-efi-$(EFIARCH).o += $(CFLAGS_EFI) > + > ifeq ($(CONFIG_ARCH_EFI),y) > > PLATFORM_CPPFLAGS += $(CFLAGS_EFI) > diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h > index e272c90..766617f 100644 > --- a/arch/x86/include/asm/types.h > +++ b/arch/x86/include/asm/types.h > @@ -44,8 +44,11 @@ typedef __INT64_TYPE__ s64; > typedef __UINT64_TYPE__ u64; > #endif > > +#ifdef CONFIG_EFI_STUB_64BIT > +#define BITS_PER_LONG 64 > +#else > #define BITS_PER_LONG 32 > - > +#endif > /* Dma addresses are 32-bits wide. */ > > typedef u32 dma_addr_t; > diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c > index e3b7cdb..36f14ff 100644 > --- a/lib/efi/efi_stub.c > +++ b/lib/efi/efi_stub.c > @@ -6,8 +6,8 @@ > * EFI information obtained here: > * http://wiki.phoenix.com/wiki/index.php/EFI_BOOT_SERVICES > * > - * Loads a payload (U-Boot) within the EFI environment. This is built as a > - * 32-bit EFI application. > + * Loads a payload (U-Boot) within the EFI environment. This is built as an > + * EFI application. It can be built either in 32-bit or 64-bit mode. > */ > > #include <common.h> > @@ -116,12 +116,12 @@ void *memset(void *inptr, int ch, size_t size) > > static void jump_to_uboot(ulong cs32, ulong addr, ulong info) > { > +#ifdef CONFIG_EFI_STUB_32BIT > typedef void (*func_t)(int bist, int unused, ulong info); > > -#ifdef CONFIG_EFI_STUB_32BIT > ((func_t)addr)(bist, 0, info); > #else > - /* TODO: Implement this */ > + cpu_call32(cs32, CONFIG_SYS_TEXT_BASE, info); > #endif > } > > @@ -151,7 +151,55 @@ static int get_codeseg32(void) > { > int cs32 = 0; > > - /* TODO(sjg): Implement this for 64-bit mode */ > +#ifdef CONFIG_EFI_STUB_64BIT > + struct desctab_info gdt; > + uint64_t *ptr; > + int i; > + > + get_gdt(&gdt); > + for (ptr = (uint64_t *)(unsigned long)gdt.addr, i = 0; i < gdt.limit; > + i += 8, ptr++) { > + uint64_t desc = *ptr; > + > + if ((desc & GDT_PRESENT) && (desc && GDT_NOTSYS) && > + !(desc & GDT_LONG) && (desc & GDT_4GB) && > + (desc & GDT_32BIT) && (desc & GDT_CODE)) { I think only checking GDT_4KB is not enough. We should check segment limit to make sure CONFIG_SYS_TEXT_BASE is within the range. > + cs32 = i; > + break; > + } > + } > + > +#ifdef DEBUG > + puts("\ngdt: "); > + printhex8(gdt.limit); > + puts(", addr: "); > + printhex8(gdt.addr >> 32); > + printhex8(gdt.addr); > + for (i = 0; i < gdt.limit; i += 8) { > + uint32_t *ptr = (uint32_t *)((unsigned long)gdt.addr + i); > + > + puts("\n"); > + printhex2(i); > + puts(": "); > + printhex8(ptr[1]); > + puts(" "); > + printhex8(ptr[0]); > + } > + puts("\n "); > + puts("32-bit code segment: "); > + printhex2(cs32); > + puts("\n "); > + > + puts("page_table: "); > + printhex8(read_cr3()); > + puts("\n "); > +#endif > + if (!cs32) { > + puts("Can't find 32-bit code segment\n"); > + return -ENOENT; > + } > +#endif > + > return cs32; > } > Regards, Bin _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot