diff options
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/Kconfig | 11 | ||||
-rw-r--r-- | cmd/bootflow.c | 9 | ||||
-rw-r--r-- | cmd/bootmenu.c | 16 | ||||
-rw-r--r-- | cmd/cedit.c | 28 | ||||
-rw-r--r-- | cmd/eficonfig.c | 2 | ||||
-rw-r--r-- | cmd/efidebug.c | 25 | ||||
-rw-r--r-- | cmd/sb.c | 42 | ||||
-rw-r--r-- | cmd/x86/Makefile | 1 | ||||
-rw-r--r-- | cmd/x86/cbcmos.c | 139 | ||||
-rw-r--r-- | cmd/x86/cbsysinfo.c | 73 |
10 files changed, 316 insertions, 30 deletions
diff --git a/cmd/Kconfig b/cmd/Kconfig index 4fba9fe6703..636833646f6 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2871,6 +2871,17 @@ config CMD_CBSYSINFO memory by coreboot before jumping to U-Boot. It can be useful for debugging the beaaviour of coreboot or U-Boot. +config CMD_CBCMOS + bool "cbcmos" + depends on X86 + default y if SYS_COREBOOT + help + This provides information options to check the CMOS RAM checksum, + if present, as well as to update it. + + It is useful when coreboot CMOS-RAM settings must be examined or + updated. + config CMD_CYCLIC bool "cyclic - Show information about cyclic functions" depends on CYCLIC diff --git a/cmd/bootflow.c b/cmd/bootflow.c index 1588f277a4a..f67948d7368 100644 --- a/cmd/bootflow.c +++ b/cmd/bootflow.c @@ -393,7 +393,11 @@ static int do_bootflow_info(struct cmd_tbl *cmdtp, int flag, int argc, printf("Partition: %d\n", bflow->part); printf("Subdir: %s\n", bflow->subdir ? bflow->subdir : "(none)"); printf("Filename: %s\n", bflow->fname); - printf("Buffer: %lx\n", (ulong)map_to_sysmem(bflow->buf)); + printf("Buffer: "); + if (bflow->buf) + printf("%lx\n", (ulong)map_to_sysmem(bflow->buf)); + else + printf("(not loaded)\n"); printf("Size: %x (%d bytes)\n", bflow->size, bflow->size); printf("OS: %s\n", bflow->os_name ? bflow->os_name : "(none)"); printf("Cmdline: "); @@ -403,7 +407,8 @@ static int do_bootflow_info(struct cmd_tbl *cmdtp, int flag, int argc, puts("(none)"); putc('\n'); if (bflow->x86_setup) - printf("X86 setup: %p\n", bflow->x86_setup); + printf("X86 setup: %lx\n", + (ulong)map_to_sysmem(bflow->x86_setup)); printf("Logo: %s\n", bflow->logo ? simple_xtoa((ulong)map_to_sysmem(bflow->logo)) : "(none)"); if (bflow->logo) { diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 977a04b7d76..ffa63a4628d 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -103,11 +103,13 @@ static char *bootmenu_choice_entry(void *data) switch (key) { case BKEY_UP: + menu->last_active = menu->active; if (menu->active > 0) --menu->active; /* no menu key selected, regenerate menu */ return NULL; case BKEY_DOWN: + menu->last_active = menu->active; if (menu->active < menu->count - 1) ++menu->active; /* no menu key selected, regenerate menu */ @@ -133,6 +135,17 @@ static char *bootmenu_choice_entry(void *data) return NULL; } +static bool bootmenu_need_reprint(void *data) +{ + struct bootmenu_data *menu = data; + bool need_reprint; + + need_reprint = menu->last_active != menu->active; + menu->last_active = menu->active; + + return need_reprint; +} + static void bootmenu_destroy(struct bootmenu_data *menu) { struct bootmenu_entry *iter = menu->first; @@ -332,6 +345,7 @@ static struct bootmenu_data *bootmenu_create(int delay) menu->delay = delay; menu->active = 0; + menu->last_active = -1; menu->first = NULL; default_str = env_get("bootmenu_default"); @@ -506,7 +520,7 @@ static enum bootmenu_ret bootmenu_show(int delay) menu = menu_create(NULL, bootmenu->delay, 1, menu_display_statusline, bootmenu_print_entry, bootmenu_choice_entry, - bootmenu); + bootmenu_need_reprint, bootmenu); if (!menu) { bootmenu_destroy(bootmenu); return BOOTMENU_RET_FAIL; diff --git a/cmd/cedit.c b/cmd/cedit.c index fec67a8e334..f696356419e 100644 --- a/cmd/cedit.c +++ b/cmd/cedit.c @@ -67,6 +67,28 @@ static int do_cedit_load(struct cmd_tbl *cmdtp, int flag, int argc, return 0; } +#ifdef CONFIG_COREBOOT_SYSINFO +static int do_cedit_cb_load(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct expo *exp; + int ret; + + if (argc > 1) + return CMD_RET_USAGE; + + ret = cb_expo_build(&exp); + if (ret) { + printf("Failed to build expo: %dE\n", ret); + return CMD_RET_FAILURE; + } + + cur_exp = exp; + + return 0; +} +#endif /* CONFIG_COREBOOT_SYSINFO */ + static int do_cedit_write_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { @@ -271,6 +293,9 @@ static int do_cedit_run(struct cmd_tbl *cmdtp, int flag, int argc, U_BOOT_LONGHELP(cedit, "load <interface> <dev[:part]> <filename> - load config editor\n" +#ifdef CONFIG_COREBOOT_SYSINFO + "cb_load - load coreboot CMOS editor\n" +#endif "cedit read_fdt <i/f> <dev[:part]> <filename> - read settings\n" "cedit write_fdt <i/f> <dev[:part]> <filename> - write settings\n" "cedit read_env [-v] - read settings from env vars\n" @@ -281,6 +306,9 @@ U_BOOT_LONGHELP(cedit, U_BOOT_CMD_WITH_SUBCMDS(cedit, "Configuration editor", cedit_help_text, U_BOOT_SUBCMD_MKENT(load, 5, 1, do_cedit_load), +#ifdef CONFIG_COREBOOT_SYSINFO + U_BOOT_SUBCMD_MKENT(cb_load, 5, 1, do_cedit_cb_load), +#endif U_BOOT_SUBCMD_MKENT(read_fdt, 5, 1, do_cedit_read_fdt), U_BOOT_SUBCMD_MKENT(write_fdt, 5, 1, do_cedit_write_fdt), U_BOOT_SUBCMD_MKENT(read_env, 2, 1, do_cedit_read_env), diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index 029180250f0..e08b6ba4a5d 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -443,7 +443,7 @@ efi_status_t eficonfig_process_common(struct efimenu *efi_menu, efi_menu->menu_desc = menu_desc; menu = menu_create(NULL, 0, 1, display_statusline, item_data_print, - item_choice, efi_menu); + item_choice, NULL, efi_menu); if (!menu) return EFI_INVALID_PARAMETER; diff --git a/cmd/efidebug.c b/cmd/efidebug.c index e040fe75fa1..02f1e080e88 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -511,6 +511,27 @@ static int do_efi_show_images(struct cmd_tbl *cmdtp, int flag, return CMD_RET_SUCCESS; } +/** + * do_efi_show_defaults() - show UEFI default filename and PXE architecture + * + * @cmdtp: Command table + * @flag: Command flag + * @argc: Number of arguments + * @argv: Argument array + * Return: CMD_RET_SUCCESS on success, CMD_RET_RET_FAILURE on failure + * + * Implement efidebug "defaults" sub-command. + * Shows the default EFI filename and PXE architecture + */ +static int do_efi_show_defaults(struct cmd_tbl *cmdtp, int flag, + int argc, char *const argv[]) +{ + printf("Default boot path: EFI\\BOOT\\%s\n", efi_get_basename()); + printf("PXE arch: 0x%02x\n", efi_get_pxe_arch()); + + return CMD_RET_SUCCESS; +} + static const char * const efi_mem_type_string[] = { [EFI_RESERVED_MEMORY_TYPE] = "RESERVED", [EFI_LOADER_CODE] = "LOADER CODE", @@ -1561,6 +1582,8 @@ static struct cmd_tbl cmd_efidebug_sub[] = { "", ""), U_BOOT_CMD_MKENT(dh, CONFIG_SYS_MAXARGS, 1, do_efi_show_handles, "", ""), + U_BOOT_CMD_MKENT(defaults, CONFIG_SYS_MAXARGS, 1, do_efi_show_defaults, + "", ""), U_BOOT_CMD_MKENT(images, CONFIG_SYS_MAXARGS, 1, do_efi_show_images, "", ""), U_BOOT_CMD_MKENT(memmap, CONFIG_SYS_MAXARGS, 1, do_efi_show_memmap, @@ -1653,6 +1676,8 @@ U_BOOT_LONGHELP(efidebug, " - show UEFI drivers\n" "efidebug dh\n" " - show UEFI handles\n" + "efidebug defaults\n" + " - show default EFI filename and PXE architecture\n" "efidebug images\n" " - show loaded images\n" "efidebug memmap\n" @@ -7,6 +7,7 @@ #include <command.h> #include <dm.h> #include <spl.h> +#include <asm/cpu.h> #include <asm/global_data.h> #include <asm/state.h> @@ -29,6 +30,14 @@ static int do_sb_handoff(struct cmd_tbl *cmdtp, int flag, int argc, #endif } +static int do_sb_map(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + sandbox_map_list(); + + return 0; +} + static int do_sb_state(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { @@ -40,29 +49,12 @@ static int do_sb_state(struct cmd_tbl *cmdtp, int flag, int argc, return 0; } -static struct cmd_tbl cmd_sb_sub[] = { - U_BOOT_CMD_MKENT(handoff, 1, 0, do_sb_handoff, "", ""), - U_BOOT_CMD_MKENT(state, 1, 0, do_sb_state, "", ""), -}; - -static int do_sb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - struct cmd_tbl *c; - - /* Skip past 'sb' */ - argc--; - argv++; - - c = find_cmd_tbl(argv[0], cmd_sb_sub, ARRAY_SIZE(cmd_sb_sub)); - if (c) - return c->cmd(cmdtp, flag, argc, argv); - else - return CMD_RET_USAGE; -} - -U_BOOT_CMD( - sb, 8, 1, do_sb, - "Sandbox status commands", +U_BOOT_LONGHELP(sb, "handoff - Show handoff data received from SPL\n" - "sb state - Show sandbox state" -); + "sb map - Show mapped memory\n" + "sb state - Show sandbox state"); + +U_BOOT_CMD_WITH_SUBCMDS(sb, "Sandbox status commands", sb_help_text, + U_BOOT_SUBCMD_MKENT(handoff, 1, 1, do_sb_handoff), + U_BOOT_SUBCMD_MKENT(map, 1, 1, do_sb_map), + U_BOOT_SUBCMD_MKENT(state, 1, 1, do_sb_state)); diff --git a/cmd/x86/Makefile b/cmd/x86/Makefile index 925215235d3..5f3f5be2882 100644 --- a/cmd/x86/Makefile +++ b/cmd/x86/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_CMD_CBSYSINFO) += cbsysinfo.o obj-y += cpuid.o msr.o mtrr.o +obj-$(CONFIG_CMD_CBCMOS) += cbcmos.o obj-$(CONFIG_CMD_EXCEPTION) += exception.o obj-$(CONFIG_USE_HOB) += hob.o obj-$(CONFIG_HAVE_FSP) += fsp.o diff --git a/cmd/x86/cbcmos.c b/cmd/x86/cbcmos.c new file mode 100644 index 00000000000..fe5582fbf51 --- /dev/null +++ b/cmd/x86/cbcmos.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Support for booting from coreboot + * + * Copyright 2021 Google LLC + */ + +#define LOG_CATEGORY UCLASS_RTC + +#include <command.h> +#include <dm.h> +#include <rtc.h> +#include <asm/cb_sysinfo.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +const struct sysinfo_t *get_table(void) +{ + if (!gd->arch.coreboot_table) { + printf("No coreboot sysinfo table found\n"); + return NULL; + } + + return &lib_sysinfo; +} + +static int calc_sum(struct udevice *dev, uint start_bit, uint bit_count) +{ + uint start_byte = start_bit / 8; + uint byte_count = bit_count / 8; + int ret, i; + uint sum; + + log_debug("Calc sum from %x: %x bytes\n", start_byte, byte_count); + sum = 0; + for (i = 0; i < bit_count / 8; i++) { + ret = rtc_read8(dev, start_bit / 8 + i); + if (ret < 0) + return ret; + sum += ret; + } + + return (sum & 0xff) << 8 | (sum & 0xff00) >> 8; +} + +/** + * prep_cbcmos() - Prepare for a CMOS-RAM command + * + * @tab: coreboot table + * @devnum: RTC device name to use, or NULL for the first one + * @dep: Returns RTC device on success + * Return: calculated checksum for CMOS RAM or -ve on error + */ +static int prep_cbcmos(const struct sysinfo_t *tab, const char *devname, + struct udevice **devp) +{ + struct udevice *dev; + int ret; + + if (!tab) + return CMD_RET_FAILURE; + if (devname) + ret = uclass_get_device_by_name(UCLASS_RTC, devname, &dev); + else + ret = uclass_first_device_err(UCLASS_RTC, &dev); + if (ret) { + printf("Failed to get RTC device: %dE\n", ret); + return ret; + } + + ret = calc_sum(dev, tab->cmos_range_start, + tab->cmos_range_end + 1 - tab->cmos_range_start); + if (ret < 0) { + printf("Failed to read RTC device: %dE\n", ret); + return ret; + } + *devp = dev; + + return ret; +} + +static int do_cbcmos_check(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + const struct sysinfo_t *tab = get_table(); + struct udevice *dev; + u16 cur, sum; + int ret; + + ret = prep_cbcmos(tab, argv[1], &dev); + if (ret < 0) + return CMD_RET_FAILURE; + sum = ret; + + ret = rtc_read16(dev, tab->cmos_checksum_location / 8, &cur); + if (ret < 0) { + printf("Failed to read RTC device: %dE\n", ret); + return CMD_RET_FAILURE; + } + if (sum != cur) { + printf("Checksum %04x error: calculated %04x\n", cur, sum); + return CMD_RET_FAILURE; + } + + return 0; +} + +static int do_cbcmos_update(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + const struct sysinfo_t *tab = get_table(); + struct udevice *dev; + u16 sum; + int ret; + + ret = prep_cbcmos(tab, argv[1], &dev); + if (ret < 0) + return CMD_RET_FAILURE; + sum = ret; + + ret = rtc_write16(dev, tab->cmos_checksum_location / 8, sum); + if (ret < 0) { + printf("Failed to read RTC device: %dE\n", ret); + return CMD_RET_FAILURE; + } + printf("Checksum %04x written\n", sum); + + return 0; +} + +U_BOOT_LONGHELP(cbcmos, + "check - check CMOS RAM\n" + "cbcmos update - Update CMOS-RAM checksum"; +); + +U_BOOT_CMD_WITH_SUBCMDS(cbcmos, "coreboot CMOS RAM", cbcmos_help_text, + U_BOOT_SUBCMD_MKENT(check, 2, 1, do_cbcmos_check), + U_BOOT_SUBCMD_MKENT(update, 2, 1, do_cbcmos_update)); diff --git a/cmd/x86/cbsysinfo.c b/cmd/x86/cbsysinfo.c index 7ca2e13ae2f..ea4d89616f6 100644 --- a/cmd/x86/cbsysinfo.c +++ b/cmd/x86/cbsysinfo.c @@ -184,6 +184,77 @@ static const char *timestamp_name(uint32_t id) return "<unknown>"; } +static void show_option_vals(const struct cb_cmos_option_table *tab, + uint id) +{ + const void *ptr, *end; + bool found = false; + + end = (void *)tab + tab->size; + for (ptr = (void *)tab + tab->header_length; ptr < end;) { + const struct cb_record *rec = ptr; + + switch (rec->tag) { + case CB_TAG_OPTION_ENUM: { + const struct cb_cmos_enums *enums = ptr; + + if (enums->config_id == id) { + if (!found) + printf(" "); + printf(" %d:%s", enums->value, enums->text); + found = true; + } + break; + } + break; + case CB_TAG_OPTION_DEFAULTS: + case CB_TAG_OPTION_CHECKSUM: + case CB_TAG_OPTION: + break; + default: + printf("tag %x\n", rec->tag); + break; + } + ptr += rec->size; + } +} + +static void show_option_table(const struct cb_cmos_option_table *tab) +{ + const void *ptr, *end; + + print_ptr("option_table", tab); + if (!tab->size) + return; + + printf(" Bit Len Cfg ID Name\n"); + end = (void *)tab + tab->size; + for (ptr = (void *)tab + tab->header_length; ptr < end;) { + const struct cb_record *rec = ptr; + + switch (rec->tag) { + case CB_TAG_OPTION: { + const struct cb_cmos_entries *entry = ptr; + + printf("%4x %4x %3c %3x %-20s", entry->bit, + entry->length, entry->config, entry->config_id, + entry->name); + show_option_vals(tab, entry->config_id); + printf("\n"); + break; + } + case CB_TAG_OPTION_ENUM: + case CB_TAG_OPTION_DEFAULTS: + case CB_TAG_OPTION_CHECKSUM: + break; + default: + printf("tag %x\n", rec->tag); + break; + } + ptr += rec->size; + } +} + static void show_table(struct sysinfo_t *info, bool verbose) { struct cb_serial *ser = info->serial; @@ -218,7 +289,7 @@ static void show_table(struct sysinfo_t *info, bool verbose) printf("%12d: %02x:%-8s %016llx %016llx\n", i, mr->type, get_mem_name(mr->type), mr->base, mr->size); } - print_ptr("option_table", info->option_table); + show_option_table(info->option_table); print_hex("CMOS start", info->cmos_range_start); if (info->cmos_range_start) { |