From aac79251c7dfeb325f17dbded3076df278bfca89 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 23 Aug 2018 08:24:08 -0700 Subject: [PATCH 1/5] 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(+) 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; +} From cbe503fbc11f36086482bfd7066c2e36b82f1544 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 23 Aug 2018 08:24:09 -0700 Subject: [PATCH 2/5] efi: stub: Pass EFI system table address to U-Boot payload This updates the EFI stub codes to pass UEFI BIOS's system table address to U-Boot payload so that U-Boot can utilize it. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- include/efi.h | 10 ++++++++++ lib/efi/efi_stub.c | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/include/efi.h b/include/efi.h index 7e7c1cafc2..63017c86f2 100644 --- a/include/efi.h +++ b/include/efi.h @@ -248,6 +248,7 @@ enum efi_entry_t { EFIET_END, /* Signals this is the last (empty) entry */ EFIET_MEMORY_MAP, EFIET_GOP_MODE, + EFIET_SYS_TABLE, /* Number of entries */ EFIET_MEMORY_COUNT, @@ -338,6 +339,15 @@ struct efi_entry_gopmode { } info[]; }; +/** + * struct efi_entry_systable - system table passed to U-Boot + * + * @sys_table: EFI system table address + */ +struct efi_entry_systable { + efi_physical_addr_t sys_table; +}; + static inline struct efi_mem_desc *efi_get_next_mem_desc( struct efi_entry_memmap *map, struct efi_mem_desc *desc) { diff --git a/lib/efi/efi_stub.c b/lib/efi/efi_stub.c index 1b495ec81b..12e3d637dd 100644 --- a/lib/efi/efi_stub.c +++ b/lib/efi/efi_stub.c @@ -277,6 +277,7 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, struct efi_entry_memmap map; struct efi_gop *gop; struct efi_entry_gopmode mode; + struct efi_entry_systable table; efi_guid_t efi_gop_guid = EFI_GOP_GUID; efi_uintn_t key, desc_size, size; efi_status_t ret; @@ -335,6 +336,9 @@ efi_status_t EFIAPI efi_main(efi_handle_t image, return ret; } + table.sys_table = (ulong)sys_table; + add_entry_addr(priv, EFIET_SYS_TABLE, &table, sizeof(table), NULL, 0); + ret = boot->exit_boot_services(image, key); if (ret) { /* From 1fdeacd32c6335acb7bd5f00c3f177013d971d3d Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 23 Aug 2018 08:24:10 -0700 Subject: [PATCH 3/5] 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 +++++++++++++++++++++++++++++++++++ arch/x86/include/asm/zimage.h | 1 + arch/x86/lib/zimage.c | 4 ++++ include/efi.h | 3 +++ 4 files changed, 45 insertions(+) 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); +} diff --git a/arch/x86/include/asm/zimage.h b/arch/x86/include/asm/zimage.h index 03bed54d0b..80e128ccf3 100644 --- a/arch/x86/include/asm/zimage.h +++ b/arch/x86/include/asm/zimage.h @@ -35,5 +35,6 @@ struct boot_params *load_zimage(char *image, unsigned long kernel_size, int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, unsigned long initrd_addr, unsigned long initrd_size); void setup_video(struct screen_info *screen_info); +void setup_efi_info(struct efi_info *efi_info); #endif diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c index 04ed972482..0442fda760 100644 --- a/arch/x86/lib/zimage.c +++ b/arch/x86/lib/zimage.c @@ -295,6 +295,10 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, setup_device_tree(hdr, (const void *)env_get_hex("fdtaddr", 0)); setup_video(&setup_base->screen_info); +#ifdef CONFIG_EFI_STUB + setup_efi_info(&setup_base->efi_info); +#endif + return 0; } diff --git a/include/efi.h b/include/efi.h index 63017c86f2..e1854ecd23 100644 --- a/include/efi.h +++ b/include/efi.h @@ -41,6 +41,9 @@ #define efi_va_end va_end #endif /* __x86_64__ */ +#define EFI32_LOADER_SIGNATURE "EL32" +#define EFI64_LOADER_SIGNATURE "EL64" + struct efi_device_path; typedef struct { From a0913cdf7b7ef1a9f622294cf7a9e97ea9eb72f2 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 23 Aug 2018 08:24:11 -0700 Subject: [PATCH 4/5] x86: efi: payload: Turn on acpi in the kernel command line Now that we have full Linux kernel boot support on EFI payload, avoid pass "acpi=off" to the kernel command line. Signed-off-by: Bin Meng Reviewed-by: Simon Glass --- include/configs/x86-common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index cc621cb942..f0b027e69c 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -107,7 +107,7 @@ #define CONFIG_BOOTFILE "bzImage" #define CONFIG_LOADADDR 0x1000000 #define CONFIG_RAMDISK_ADDR 0x4000000 -#ifdef CONFIG_GENERATE_ACPI_TABLE +#if defined(CONFIG_GENERATE_ACPI_TABLE) || defined(CONFIG_EFI_STUB) #define CONFIG_OTHBOOTARGS "othbootargs=\0" #else #define CONFIG_OTHBOOTARGS "othbootargs=acpi=off\0" From e69cc6bc42c37598e2fdda421360be6cbc0470fd Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 23 Aug 2018 21:28:58 -0700 Subject: [PATCH 5/5] x86: zimage: Remove acpi_rsdp_addr propagation to kernel boot parameters As of today, the proposal of adding "acpi_rsdp_addr" to the kernel boot protocol does not make its way to the kernel mainline. This creates some confusion if we leave it in the U-Boot code base. Remove it for now until we have a clear picture with kernel upstream. Note this eventually does a partial revert to commit 3469bf427454 ("x86: zImage: Propagate acpi_rsdp_addr to kernel via boot parameters") Signed-off-by: Bin Meng Acked-by: Andy Shevchenko Reviewed-by: Simon Glass --- arch/x86/include/asm/bootparam.h | 1 - arch/x86/lib/zimage.c | 5 ----- 2 files changed, 6 deletions(-) diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h index 0386cbeca5..dfbd4b4bba 100644 --- a/arch/x86/include/asm/bootparam.h +++ b/arch/x86/include/asm/bootparam.h @@ -69,7 +69,6 @@ struct setup_header { __u64 pref_address; __u32 init_size; __u32 handover_offset; - __u64 acpi_rsdp_addr; } __attribute__((packed)); struct sys_desc_table { diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c index 0442fda760..230b38e938 100644 --- a/arch/x86/lib/zimage.c +++ b/arch/x86/lib/zimage.c @@ -287,11 +287,6 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot, hdr->hardware_subarch = X86_SUBARCH_INTEL_MID; #endif -#ifdef CONFIG_GENERATE_ACPI_TABLE - if (bootproto >= 0x020e) - hdr->acpi_rsdp_addr = acpi_get_rsdp_addr(); -#endif - setup_device_tree(hdr, (const void *)env_get_hex("fdtaddr", 0)); setup_video(&setup_base->screen_info);