diff options
author | Tom Rini <trini@konsulko.com> | 2015-08-05 14:12:37 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2015-08-05 14:12:37 -0400 |
commit | 1a2728ae4faf12874173de156b8a7e66cfbbeae5 (patch) | |
tree | 9aba8e6c915b341df8ec6077d8ecb28f1eb32b0b /common | |
parent | dcc7dbc73169bb4e39f27c1d95bbf031ccfc1744 (diff) | |
parent | 12c7510f17ff29190e52336910e43a50c0d620a6 (diff) | |
download | u-boot-imx-1a2728ae4faf12874173de156b8a7e66cfbbeae5.zip u-boot-imx-1a2728ae4faf12874173de156b8a7e66cfbbeae5.tar.gz u-boot-imx-1a2728ae4faf12874173de156b8a7e66cfbbeae5.tar.bz2 |
Merge git://git.denx.de/u-boot-x86
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile | 1 | ||||
-rw-r--r-- | common/board_f.c | 16 | ||||
-rw-r--r-- | common/board_info.c | 1 | ||||
-rw-r--r-- | common/cmd_efi.c | 257 | ||||
-rw-r--r-- | common/command.c | 2 |
5 files changed, 272 insertions, 5 deletions
diff --git a/common/Makefile b/common/Makefile index d6c1d48..6dc4c89 100644 --- a/common/Makefile +++ b/common/Makefile @@ -90,6 +90,7 @@ obj-$(CONFIG_CMD_DTT) += cmd_dtt.o obj-$(CONFIG_CMD_ECHO) += cmd_echo.o obj-$(CONFIG_ENV_IS_IN_EEPROM) += cmd_eeprom.o obj-$(CONFIG_CMD_EEPROM) += cmd_eeprom.o +obj-$(CONFIG_EFI_STUB) += cmd_efi.o obj-$(CONFIG_CMD_ELF) += cmd_elf.o obj-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o obj-$(CONFIG_CMD_EXT4) += cmd_ext4.o diff --git a/common/board_f.c b/common/board_f.c index 21be26f..c7cc67c 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -144,7 +144,7 @@ static int init_baud_rate(void) static int display_text_info(void) { -#ifndef CONFIG_SANDBOX +#if !defined(CONFIG_SANDBOX) && !defined(CONFIG_EFI_APP) ulong bss_start, bss_end, text_base; bss_start = (ulong)&__bss_start; @@ -267,7 +267,7 @@ static int setup_mon_len(void) { #if defined(__ARM__) || defined(__MICROBLAZE__) gd->mon_len = (ulong)&__bss_end - (ulong)_start; -#elif defined(CONFIG_SANDBOX) +#elif defined(CONFIG_SANDBOX) || defined(CONFIG_EFI_APP) gd->mon_len = (ulong)&_end - (ulong)_init; #elif defined(CONFIG_BLACKFIN) || defined(CONFIG_NIOS2) gd->mon_len = CONFIG_SYS_MONITOR_LEN; @@ -654,6 +654,8 @@ static int setup_dram_config(void) static int reloc_fdt(void) { + if (gd->flags & GD_FLG_SKIP_RELOC) + return 0; if (gd->new_fdt) { memcpy(gd->new_fdt, gd->fdt_blob, gd->fdt_size); gd->fdt_blob = gd->new_fdt; @@ -664,6 +666,11 @@ static int reloc_fdt(void) static int setup_reloc(void) { + if (gd->flags & GD_FLG_SKIP_RELOC) { + debug("Skipping relocation due to flag\n"); + return 0; + } + #ifdef CONFIG_SYS_TEXT_BASE gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE; #ifdef CONFIG_M68K @@ -689,6 +696,8 @@ static int setup_reloc(void) static int jump_to_copy(void) { + if (gd->flags & GD_FLG_SKIP_RELOC) + return 0; /* * x86 is special, but in a nice way. It uses a trampoline which * enables the dcache if possible. @@ -968,7 +977,8 @@ void board_init_f(ulong boot_flags) if (initcall_run_list(init_sequence_f)) hang(); -#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) +#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \ + !defined(CONFIG_EFI_APP) /* NOTREACHED - jump_to_copy() does not return */ hang(); #endif diff --git a/common/board_info.c b/common/board_info.c index 4e5a1f7..6afe98e 100644 --- a/common/board_info.c +++ b/common/board_info.c @@ -8,7 +8,6 @@ int __weak checkboard(void) { - printf("Board: Unknown\n"); return 0; } diff --git a/common/cmd_efi.c b/common/cmd_efi.c new file mode 100644 index 0000000..c76296e --- /dev/null +++ b/common/cmd_efi.c @@ -0,0 +1,257 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <efi.h> +#include <errno.h> +#include <malloc.h> + +static const char *const type_name[] = { + "reserved", + "loader_code", + "loader_data", + "bs_code", + "bs_data", + "rt_code", + "rt_data", + "conv", + "unusable", + "acpi_reclaim", + "acpi_nvs", + "io", + "io_port", + "pal_code", +}; + +static struct attr_info { + int shift; + const char *name; +} mem_attr[] = { + { EFI_MEMORY_UC_SHIFT, "uncached" }, + { EFI_MEMORY_WC_SHIFT, "write-coalescing" }, + { EFI_MEMORY_WT_SHIFT, "write-through" }, + { EFI_MEMORY_WB_SHIFT, "write-back" }, + { EFI_MEMORY_UCE_SHIFT, "uncached & exported" }, + { EFI_MEMORY_WP_SHIFT, "write-protect" }, + { EFI_MEMORY_RP_SHIFT, "read-protect" }, + { EFI_MEMORY_XP_SHIFT, "execute-protect" }, + { EFI_MEMORY_RUNTIME_SHIFT, "needs runtime mapping" } +}; + +/* Maximum different attribute values we can track */ +#define ATTR_SEEN_MAX 30 + +static inline bool is_boot_services(int type) +{ + return type == EFI_LOADER_CODE || type == EFI_LOADER_DATA || + type == EFI_BOOT_SERVICES_CODE || + type == EFI_BOOT_SERVICES_DATA; +} + +static int h_cmp_entry(const void *v1, const void *v2) +{ + const struct efi_mem_desc *desc1 = v1; + const struct efi_mem_desc *desc2 = v2; + int64_t diff = desc1->physical_start - desc2->physical_start; + + /* + * Manually calculate the difference to avoid sign loss in the 64-bit + * to 32-bit conversion + */ + return diff < 0 ? -1 : diff > 0 ? 1 : 0; +} + +void *efi_build_mem_table(struct efi_entry_memmap *map, int size, bool skip_bs) +{ + struct efi_mem_desc *desc, *end, *base, *dest, *prev; + int count; + u64 addr; + + base = malloc(size + sizeof(*desc)); + if (!base) { + debug("%s: Cannot allocate %#x bytes\n", __func__, size); + return NULL; + } + end = (struct efi_mem_desc *)((ulong)map + size); + count = ((ulong)end - (ulong)map->desc) / map->desc_size; + memcpy(base, map->desc, (ulong)end - (ulong)map->desc); + qsort(base, count, map->desc_size, h_cmp_entry); + prev = NULL; + addr = 0; + dest = base; + end = base + count; + for (desc = base; desc < end; desc = efi_get_next_mem_desc(map, desc)) { + bool merge = true; + int type = desc->type; + + if (skip_bs && is_boot_services(desc->type)) + type = EFI_CONVENTIONAL_MEMORY; + + memcpy(dest, desc, map->desc_size); + dest->type = type; + if (!skip_bs || !prev) + merge = false; + else if (desc->physical_start != addr) + merge = false; + else if (type != EFI_CONVENTIONAL_MEMORY) + merge = false; + else if (prev->type != EFI_CONVENTIONAL_MEMORY) + merge = false; + + if (merge) { + prev->num_pages += desc->num_pages; + } else { + prev = dest; + dest = efi_get_next_mem_desc(map, dest); + } + addr = desc->physical_start + (desc->num_pages << + EFI_PAGE_SHIFT); + } + + /* Mark the end */ + dest->type = EFI_TABLE_END; + + return base; +} + +static void efi_print_mem_table(struct efi_entry_memmap *map, + struct efi_mem_desc *desc, bool skip_bs) +{ + u64 attr_seen[ATTR_SEEN_MAX]; + int attr_seen_count; + int upto, i; + u64 addr; + + printf(" # %-14s %10s %10s %10s %s\n", "Type", "Physical", + "Virtual", "Size", "Attributes"); + + /* Keep track of all the different attributes we have seen */ + attr_seen_count = 0; + addr = 0; + for (upto = 0; desc->type != EFI_TABLE_END; + upto++, desc = efi_get_next_mem_desc(map, desc)) { + const char *name; + u64 size; + + if (skip_bs && is_boot_services(desc->type)) + continue; + if (desc->physical_start != addr) { + printf(" %-14s %010llx %10s %010llx\n", "<gap>", + addr, "", desc->physical_start - addr); + } + size = desc->num_pages << EFI_PAGE_SHIFT; + + name = desc->type < ARRAY_SIZE(type_name) ? + type_name[desc->type] : "<invalid>"; + printf("%2d %x:%-12s %010llx %010llx %010llx ", upto, + desc->type, name, desc->physical_start, + desc->virtual_start, size); + if (desc->attribute & EFI_MEMORY_RUNTIME) + putc('r'); + printf("%llx", desc->attribute & ~EFI_MEMORY_RUNTIME); + putc('\n'); + + for (i = 0; i < attr_seen_count; i++) { + if (attr_seen[i] == desc->attribute) + break; + } + if (i == attr_seen_count && i < ATTR_SEEN_MAX) + attr_seen[attr_seen_count++] = desc->attribute; + addr = desc->physical_start + size; + } + + printf("\nAttributes key:\n"); + for (i = 0; i < attr_seen_count; i++) { + u64 attr = attr_seen[i]; + bool first; + int j; + + printf("%c%llx: ", attr & EFI_MEMORY_RUNTIME ? 'r' : ' ', + attr & ~EFI_MEMORY_RUNTIME); + for (j = 0, first = true; j < ARRAY_SIZE(mem_attr); j++) { + if (attr & (1ULL << mem_attr[j].shift)) { + if (first) + first = false; + else + printf(", "); + printf("%s", mem_attr[j].name); + } + } + putc('\n'); + } + if (skip_bs) + printf("*Some areas are merged (use 'all' to see)\n"); +} + +static int do_efi_mem(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + struct efi_mem_desc *desc; + struct efi_entry_memmap *map; + int size, ret; + bool skip_bs; + + skip_bs = !argc || *argv[0] != 'a'; + ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size); + switch (ret) { + case -ENOENT: + printf("No EFI table available\n"); + goto done; + case -EPROTONOSUPPORT: + printf("Incorrect EFI table version\n"); + goto done; + } + printf("EFI table at %lx, memory map %p, size %x, version %x, descr. size %#x\n", + gd->arch.table, map, size, map->version, map->desc_size); + if (map->version != EFI_MEM_DESC_VERSION) { + printf("Incorrect memory map version\n"); + ret = -EPROTONOSUPPORT; + goto done; + } + + desc = efi_build_mem_table(map, size, skip_bs); + if (!desc) { + ret = -ENOMEM; + goto done; + } + + efi_print_mem_table(map, desc, skip_bs); + free(desc); +done: + if (ret) + printf("Error: %d\n", ret); + + return ret ? CMD_RET_FAILURE : 0; +} + +static cmd_tbl_t efi_commands[] = { + U_BOOT_CMD_MKENT(mem, 1, 1, do_efi_mem, "", ""), +}; + +static int do_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cmd_tbl_t *efi_cmd; + int ret; + + if (argc < 2) + return CMD_RET_USAGE; + efi_cmd = find_cmd_tbl(argv[1], efi_commands, ARRAY_SIZE(efi_commands)); + argc -= 2; + argv += 2; + if (!efi_cmd || argc > efi_cmd->maxargs) + return CMD_RET_USAGE; + + ret = efi_cmd->cmd(efi_cmd, flag, argc, argv); + + return cmd_process_error(efi_cmd, ret); +} + +U_BOOT_CMD( + efi, 3, 1, do_efi, + "EFI access", + "mem [all] Dump memory information [include boot services]" +); diff --git a/common/command.c b/common/command.c index 4719f49..381e6a2 100644 --- a/common/command.c +++ b/common/command.c @@ -492,7 +492,7 @@ static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) result = (cmdtp->cmd)(cmdtp, flag, argc, argv); if (result) - debug("Command failed, result=%d", result); + debug("Command failed, result=%d\n", result); return result; } |