From aac79251c7dfeb325f17dbded3076df278bfca89 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 23 Aug 2018 08:24:08 -0700 Subject: x86: efi: payload: Install E820 map from EFI memory map This implements payload-specific install_e820_map() to get E820 map from the EFI memory map descriptors. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- arch/x86/cpu/efi/payload.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) (limited to 'arch/x86/cpu/efi/payload.c') diff --git a/arch/x86/cpu/efi/payload.c b/arch/x86/cpu/efi/payload.c index 4649bfe86e..0e7c7c1ba4 100644 --- a/arch/x86/cpu/efi/payload.c +++ b/arch/x86/cpu/efi/payload.c @@ -8,6 +8,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -168,3 +169,84 @@ int last_stage_init(void) return 0; } + +unsigned int install_e820_map(unsigned int max_entries, + struct e820_entry *entries) +{ + struct efi_mem_desc *desc, *end; + struct efi_entry_memmap *map; + int size, ret; + efi_physical_addr_t last_end_addr = 0; + struct e820_entry *last_entry = NULL; + __u32 e820_type; + unsigned int num_entries = 0; + + 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); + for (desc = map->desc; desc < end; + desc = efi_get_next_mem_desc(map, desc)) { + if (desc->num_pages == 0) + continue; + + switch (desc->type) { + case EFI_LOADER_CODE: + case EFI_LOADER_DATA: + case EFI_BOOT_SERVICES_CODE: + case EFI_BOOT_SERVICES_DATA: + case EFI_CONVENTIONAL_MEMORY: + e820_type = E820_RAM; + break; + + case EFI_RESERVED_MEMORY_TYPE: + case EFI_RUNTIME_SERVICES_CODE: + case EFI_RUNTIME_SERVICES_DATA: + case EFI_MMAP_IO: + case EFI_MMAP_IO_PORT: + case EFI_PAL_CODE: + e820_type = E820_RESERVED; + break; + + case EFI_ACPI_RECLAIM_MEMORY: + e820_type = E820_ACPI; + break; + + case EFI_ACPI_MEMORY_NVS: + e820_type = E820_NVS; + break; + + case EFI_UNUSABLE_MEMORY: + e820_type = E820_UNUSABLE; + break; + + default: + printf("Invalid EFI memory descriptor type (0x%x)!\n", + desc->type); + continue; + } + + if (last_entry != NULL && last_entry->type == e820_type && + desc->physical_start == last_end_addr) { + last_entry->size += (desc->num_pages << EFI_PAGE_SHIFT); + last_end_addr += (desc->num_pages << EFI_PAGE_SHIFT); + } else { + if (num_entries >= E820MAX) + break; + + entries[num_entries].addr = desc->physical_start; + entries[num_entries].size = desc->num_pages; + entries[num_entries].size <<= EFI_PAGE_SHIFT; + entries[num_entries].type = e820_type; + last_entry = &entries[num_entries]; + last_end_addr = last_entry->addr + last_entry->size; + num_entries++; + } + } + + return num_entries; +} -- cgit From 1fdeacd32c6335acb7bd5f00c3f177013d971d3d Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 23 Aug 2018 08:24:10 -0700 Subject: x86: zimage: Support booting Linux kernel from an EFI payload At present Linux kernel loaded from U-Boot as an EFI payload does not boot. This fills in kernel's boot params structure with the required critical EFI information like system table address and memory map stuff so that kernel can obtain essential data like runtime services and ACPI table to boot. With this patch, now U-Boot as an EFI payload becomes much more practical: it is another option of kernel bootloader, ie, can be a replacement for grub. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- arch/x86/cpu/efi/payload.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'arch/x86/cpu/efi/payload.c') diff --git a/arch/x86/cpu/efi/payload.c b/arch/x86/cpu/efi/payload.c index 0e7c7c1ba4..c323c7b19a 100644 --- a/arch/x86/cpu/efi/payload.c +++ b/arch/x86/cpu/efi/payload.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -250,3 +251,39 @@ unsigned int install_e820_map(unsigned int max_entries, return num_entries; } + +void setup_efi_info(struct efi_info *efi_info) +{ + struct efi_entry_systable *table; + struct efi_entry_memmap *map; + char *signature; + int size, ret; + + memset(efi_info, 0, sizeof(struct efi_info)); + + ret = efi_info_get(EFIET_SYS_TABLE, (void **)&table, &size); + if (ret) { + printf("Cannot find EFI system table, ret=%d\n", ret); + return; + } + efi_info->efi_systab = (u32)(table->sys_table); + + ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size); + if (ret) { + printf("Cannot find EFI memory map tables, ret=%d\n", ret); + return; + } + efi_info->efi_memdesc_size = map->desc_size; + efi_info->efi_memdesc_version = map->version; + efi_info->efi_memmap = (u32)(map->desc); + efi_info->efi_memmap_size = size - sizeof(struct efi_entry_memmap); + +#ifdef CONFIG_EFI_STUB_64BIT + efi_info->efi_systab_hi = table->sys_table >> 32; + efi_info->efi_memmap_hi = (u64)(u32)(map->desc) >> 32; + signature = EFI64_LOADER_SIGNATURE; +#else + signature = EFI32_LOADER_SIGNATURE; +#endif + memcpy(&efi_info->efi_loader_signature, signature, 4); +} -- cgit