Hi Simon, On Wed, Jul 22, 2015 at 11:49 PM, Simon Glass <s...@chromium.org> wrote: > When U-Boot is running from EFI some of the x86 init is replaced with > EFI-specific init. For example, since DRAM has already been set up, we only > need to find it, not init it. Add these functions so that boards can easily > allow booting from EFI if required. > > Signed-off-by: Simon Glass <s...@chromium.org> > --- > > arch/x86/lib/Makefile | 1 + > arch/x86/lib/efi/Makefile | 9 +++ > arch/x86/lib/efi/car.S | 12 ++++ > arch/x86/lib/efi/efi.c | 151 > ++++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 173 insertions(+) > create mode 100644 arch/x86/lib/efi/Makefile > create mode 100644 arch/x86/lib/efi/car.S > create mode 100644 arch/x86/lib/efi/efi.c > > diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile > index fb4a73c..3db373c 100644 > --- a/arch/x86/lib/Makefile > +++ b/arch/x86/lib/Makefile > @@ -31,6 +31,7 @@ obj-y += bios_interrupts.o > obj-$(CONFIG_CMD_BOOTM) += bootm.o > obj-y += cmd_boot.o > obj-$(CONFIG_HAVE_FSP) += cmd_hob.o > +obj-$(CONFIG_EFI_STUB) += efi/ > obj-y += gcc.o > obj-y += init_helpers.o > obj-y += interrupts.o > diff --git a/arch/x86/lib/efi/Makefile b/arch/x86/lib/efi/Makefile > new file mode 100644 > index 0000000..a308a0e > --- /dev/null > +++ b/arch/x86/lib/efi/Makefile > @@ -0,0 +1,9 @@ > +# > +# (C) Copyright 2002-2006 > +# Wolfgang Denk, DENX Software Engineering, w...@denx.de. > +# > +# SPDX-License-Identifier: GPL-2.0+ > +# > + > +obj-y += car.o > +obj-y += efi.o > diff --git a/arch/x86/lib/efi/car.S b/arch/x86/lib/efi/car.S > new file mode 100644 > index 0000000..6dda058 > --- /dev/null > +++ b/arch/x86/lib/efi/car.S > @@ -0,0 +1,12 @@ > +/* > + * Copyright (c) 2015 Google, Inc > + * Written by Simon Glass <s...@chromium.org> > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +.section .text > +
This is not needed. > +.globl car_init > +car_init: > + jmp car_init_ret > diff --git a/arch/x86/lib/efi/efi.c b/arch/x86/lib/efi/efi.c > new file mode 100644 > index 0000000..ede5d56 > --- /dev/null > +++ b/arch/x86/lib/efi/efi.c > @@ -0,0 +1,151 @@ > +/* > + * Copyright (c) 2015 Google, Inc > + * Written by Simon Glass <s...@chromium.org> > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include <common.h> > +#include <debug_uart.h> > +#include <efi.h> > +#include <errno.h> > +#include <linux/err.h> > +#include <linux/types.h> > + > +DECLARE_GLOBAL_DATA_PTR; > + > +/* > + * This function looks for the highest region of memory lower than 4GB which > + * has enough space for U-Boot where U-Boot is aligned on a page boundary. > + * It overrides the default implementation found elsewhere which simply > + * picks the end of ram, wherever that may be. The location of the stack, > + * the relocation address, and how far U-Boot is moved by relocation are > + * set in the global data structure. > + */ > +ulong board_get_usable_ram_top(ulong total_size) > +{ > + struct efi_mem_desc *desc, *end; > + struct efi_entry_memmap *map; > + int ret, size; > + uintptr_t dest_addr = 0; > + struct efi_mem_desc *largest = NULL; > + > + /* > + * Find largest area of memory below 4GB. We could > + * call efi_build_mem_table() for a more accurate picture since it > + * merges areas together where possible. But that function uses more > + * pre-relocation memory, and it's not critical that we find the > + * absolute largest region. > + */ > + ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size); > + if (ret) { > + /* We should have stopped in dram_init(), something is wrong > */ > + debug("%s: Missing memory map\n", __func__); > + goto err; > + } > + > + end = (struct efi_mem_desc *)((ulong)map + size); > + desc = map->desc; > + for (; desc < end; desc = efi_get_next_mem_desc(map, desc)) { > + if (desc->type != EFI_CONVENTIONAL_MEMORY || > + desc->physical_start >= 1ULL << 32) > + continue; > + if (!largest || desc->num_pages > largest->num_pages) > + largest = desc; > + } > + > + /* If no suitable area was found, return an error. */ > + assert(largest); > + if (!largest || (largest->num_pages << EFI_PAGE_SHIFT) < (2 << 20)) > + goto err; > + > + dest_addr = largest->physical_start + (largest->num_pages << > + EFI_PAGE_SHIFT); > + > + return (ulong)dest_addr; > +err: > + panic("No available memory found for relocation"); > + return 0; > +} > + > +int dram_init(void) > +{ > + struct efi_mem_desc *desc, *end; > + struct efi_entry_memmap *map; > + int size, ret; > + > + ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size); > + if (ret) { > + printf("Cannot find EFI memory map tables, ret=%d\n", ret); > + > + return -ENODEV; > + } > + > + end = (struct efi_mem_desc *)((ulong)map + size); > + gd->ram_size = 0; > + desc = map->desc; > + for (; desc < end; desc = efi_get_next_mem_desc(map, desc)) { > + if (desc->type < EFI_MMAP_IO) > + gd->ram_size += desc->num_pages << EFI_PAGE_SHIFT; > + } > + > + return 0; > +} > + > +void dram_init_banksize(void) > +{ > + struct efi_mem_desc *desc, *end; > + struct efi_entry_memmap *map; > + int ret, size; > + int num_banks; > + > + ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size); > + if (ret) { > + /* We should have stopped in dram_init(), something is wrong > */ > + debug("%s: Missing memory map\n", __func__); > + return; > + } > + end = (struct efi_mem_desc *)((ulong)map + size); > + desc = map->desc; > + for (num_banks = 0; > + desc < end && num_banks < CONFIG_NR_DRAM_BANKS; > + desc = efi_get_next_mem_desc(map, desc)) { > + /* > + * We only use conventional memory below 4GB, and ignore > + * anything less than 1MB. > + */ > + if (desc->type != EFI_CONVENTIONAL_MEMORY || > + desc->physical_start >= 1ULL << 32 || > + (desc->num_pages << EFI_PAGE_SHIFT) < 1 << 20) > + continue; > + gd->bd->bi_dram[num_banks].start = desc->physical_start; > + gd->bd->bi_dram[num_banks].size = desc->num_pages << > + EFI_PAGE_SHIFT; > + num_banks++; > + } > +} > + > +int print_cpuinfo(void) > +{ > + return default_print_cpuinfo(); > +} > + > +/* Find any available tables and copy them to a safe place */ > +int reserve_arch(void) > +{ > + struct efi_info_hdr *hdr; > + > + debug("table=%lx\n", gd->arch.table); > + if (!gd->arch.table) > + return 0; > + > + hdr = (struct efi_info_hdr *)gd->arch.table; > + > + gd->start_addr_sp -= hdr->total_size; > + memcpy((void *)gd->start_addr_sp, hdr, hdr->total_size); > + debug("Stashing EFI table at %lx to %lx, size %x\n", > + gd->arch.table, gd->start_addr_sp, hdr->total_size); > + gd->arch.table = gd->start_addr_sp; > + > + return 0; > +} > -- Regards, Bin _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot