diff options
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/Kconfig | 102 | ||||
-rw-r--r-- | cmd/Makefile | 3 | ||||
-rw-r--r-- | cmd/acpi.c | 87 | ||||
-rw-r--r-- | cmd/arm/exception.c | 1 | ||||
-rw-r--r-- | cmd/armflash.c | 12 | ||||
-rw-r--r-- | cmd/avb.c | 173 | ||||
-rw-r--r-- | cmd/bootefi.c | 664 | ||||
-rw-r--r-- | cmd/bootflow.c | 31 | ||||
-rw-r--r-- | cmd/booti.c | 55 | ||||
-rw-r--r-- | cmd/bootm.c | 43 | ||||
-rw-r--r-- | cmd/bootmenu.c | 10 | ||||
-rw-r--r-- | cmd/bootz.c | 35 | ||||
-rw-r--r-- | cmd/cli.c | 133 | ||||
-rw-r--r-- | cmd/clk.c | 13 | ||||
-rw-r--r-- | cmd/efi_common.c | 4 | ||||
-rw-r--r-- | cmd/eficonfig.c | 7 | ||||
-rw-r--r-- | cmd/efidebug.c | 21 | ||||
-rw-r--r-- | cmd/elf.c | 39 | ||||
-rw-r--r-- | cmd/hash.c | 19 | ||||
-rw-r--r-- | cmd/load.c | 4 | ||||
-rw-r--r-- | cmd/md5sum.c | 150 | ||||
-rw-r--r-- | cmd/mem.c | 40 | ||||
-rw-r--r-- | cmd/mtd.c | 4 | ||||
-rw-r--r-- | cmd/part.c | 2 | ||||
-rw-r--r-- | cmd/pmic.c | 4 | ||||
-rw-r--r-- | cmd/reiser.c | 171 | ||||
-rw-r--r-- | cmd/riscv/exception.c | 1 | ||||
-rw-r--r-- | cmd/riscv/sbi.c | 4 | ||||
-rw-r--r-- | cmd/rng.c | 30 | ||||
-rw-r--r-- | cmd/sandbox/exception.c | 1 | ||||
-rw-r--r-- | cmd/setexpr.c | 9 | ||||
-rw-r--r-- | cmd/smbios.c | 216 | ||||
-rw-r--r-- | cmd/sysboot.c | 4 | ||||
-rw-r--r-- | cmd/usb_mass_storage.c | 4 | ||||
-rw-r--r-- | cmd/x86/Makefile | 1 | ||||
-rw-r--r-- | cmd/x86/exception.c | 1 | ||||
-rw-r--r-- | cmd/x86/zboot.c | 182 | ||||
-rw-r--r-- | cmd/ximg.c | 7 |
38 files changed, 1118 insertions, 1169 deletions
diff --git a/cmd/Kconfig b/cmd/Kconfig index 311b0c2..3830519 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -22,6 +22,31 @@ config HUSH_PARSER If disabled, you get the old, much simpler behaviour with a somewhat smaller memory footprint. +menu "Hush flavor to use" +depends on HUSH_PARSER + +config HUSH_OLD_PARSER + bool "Use hush old parser" + default y + help + This option enables the old flavor of hush based on hush Busybox from + 2005. + + It is actually the default U-Boot shell when decided to use hush as shell. + +config HUSH_MODERN_PARSER + bool "Use hush modern parser" + help + This option enables the new flavor of hush based on hush upstream + Busybox. + + This parser is experimental and not well tested. + +config HUSH_SELECTABLE + bool + default y if HUSH_OLD_PARSER && HUSH_MODERN_PARSER +endmenu + config CMDLINE_EDITING bool "Enable command line editing" default y @@ -69,7 +94,7 @@ config SYS_PROMPT_HUSH_PS2 config SYS_MAXARGS int "Maximum number arguments accepted by commands" - default 16 + default 64 config SYS_XTRACE bool "Command execution tracer" @@ -164,9 +189,21 @@ config CMD_HISTORY Show the command-line history, i.e. a list of commands that are in the history buffer. +config CMD_HISTORY_USE_CALLOC + bool "dynamically allocate memory" + default y + depends on CMD_HISTORY + help + Saying Y to this will use calloc to get the space for history + storing. Otherwise the history buffer will be an uninitialized + static array directly, without the memory allocation, and it is + writable after relocation to RAM. If u-boot is running from ROM + all the time or unsure, say Y to this. + config CMD_LICENSE bool "license" select BUILD_BIN2C + depends on GZIP help Print GPL license text @@ -206,6 +243,12 @@ config CMD_SBI help Display information about the SBI implementation. +config CMD_SMBIOS + bool "smbios" + depends on SMBIOS + help + Display the SMBIOS information. + endmenu menu "Boot commands" @@ -274,7 +317,7 @@ config CMD_BOOTMETH config BOOTM_EFI bool "Support booting UEFI FIT images" - depends on CMD_BOOTEFI && CMD_BOOTM && FIT + depends on EFI_BINARY_EXEC && CMD_BOOTM && FIT default y help Support booting UEFI FIT images via the bootm command. @@ -314,9 +357,19 @@ config CMD_BOOTEFI help Boot an EFI image from memory. +if CMD_BOOTEFI +config CMD_BOOTEFI_BINARY + bool "Allow booting an EFI binary directly" + depends on EFI_BINARY_EXEC + default y + help + Select this option to enable direct execution of binary at 'bootefi'. + This subcommand will allow you to load the UEFI binary using + other U-Boot commands or external methods and then run it. + config CMD_BOOTEFI_BOOTMGR bool "UEFI Boot Manager command" - depends on BOOTEFI_BOOTMGR && CMD_BOOTEFI + depends on EFI_BOOTMGR default y help Select this option to enable the 'bootmgr' subcommand of 'bootefi'. @@ -325,7 +378,6 @@ config CMD_BOOTEFI_BOOTMGR config CMD_BOOTEFI_HELLO_COMPILE bool "Compile a standard EFI hello world binary for testing" - depends on CMD_BOOTEFI && !CPU_V7M default y help This compiles a standard EFI hello world application with U-Boot so @@ -338,7 +390,7 @@ config CMD_BOOTEFI_HELLO_COMPILE config CMD_BOOTEFI_HELLO bool "Allow booting a standard EFI hello world for testing" - depends on CMD_BOOTEFI_HELLO_COMPILE + depends on CMD_BOOTEFI_BINARY && CMD_BOOTEFI_HELLO_COMPILE default y if CMD_BOOTEFI_SELFTEST help This adds a standard EFI hello world application to U-Boot so that @@ -347,6 +399,7 @@ config CMD_BOOTEFI_HELLO up EFI support on a new architecture. source lib/efi_selftest/Kconfig +endif config CMD_BOOTMENU bool "bootmenu" @@ -389,6 +442,17 @@ config CMD_ELF help Boot an ELF/vxWorks image from the memory. +config CMD_ELF_FDT_SETUP + bool "Flattened Device Tree setup in bootelf cmd" + default n + depends on CMD_ELF + select LIB_LIBFDT + select LMB + help + Do FDT setup in bootelf command optionally by param -d, which + allows to bring additional system info (e.g. /memory node) to + the Operating System or application. + config CMD_FDT bool "Flattened Device Tree utility commands" default y @@ -437,6 +501,16 @@ config CMD_XIMG help Extract a part of a multi-image. +config SYS_XIMG_LEN + hex "imxtract max gunzip size" + default 0x800000 + depends on CMD_XIMG && GZIP + help + This provides the size of the commad-line argument area + used by imxtract for extracting pieces of FIT image. + It should be large enough to fit uncompressed size of + FIT piece we are extracting. + config CMD_SPL bool "spl export - Export boot information for Falcon boot" depends on SPL @@ -490,6 +564,8 @@ config THOR_RESET_OFF config CMD_ZBOOT bool "zboot - x86 boot command" + depends on ZBOOT + default y help With x86 machines it is common to boot a bzImage file which contains both a kernel and a setup.bin file. The latter includes @@ -640,6 +716,7 @@ config CRC32_VERIFY config CMD_EEPROM bool "eeprom - EEPROM subsystem" + depends on DM_I2C || SYS_I2C_LEGACY help (deprecated, needs conversion to driver model) Provides commands to read and write EEPROM (Electrically Erasable @@ -725,6 +802,7 @@ config LOOPW config CMD_MD5SUM bool "md5sum" select MD5 + select HASH help Compute MD5 checksum. @@ -991,7 +1069,7 @@ config CMD_FASTBOOT config CMD_FLASH bool "flinfo, erase, protect" default y - depends on MTD || FLASH_CFI_DRIVER || MTD_NOR_FLASH + depends on FLASH_CFI_DRIVER || MTD_NOR_FLASH help NOR flash support. flinfo - print FLASH memory information @@ -2064,7 +2142,7 @@ config CMD_EFIDEBUG config CMD_EFICONFIG bool "eficonfig - provide menu-driven uefi variables maintenance interface" default y if !HAS_BOARD_SIZE_LIMIT - depends on BOOTEFI_BOOTMGR + depends on EFI_BOOTMGR select MENU help Enable the 'eficonfig' command which provides the menu-driven UEFI @@ -2608,6 +2686,7 @@ config JFFS2_PART_SIZE config CMD_MTDPARTS bool "MTD partition support" depends on MTD + select MTD_PARTITIONS help MTD partitioning tool support. It is strongly encouraged to avoid using this command @@ -2649,15 +2728,6 @@ config MTDPARTS_DEFAULT Defines a default MTD partitioning scheme in the Linux MTD command line partitions format -config CMD_REISER - bool "reiser - Access to reiserfs filesystems" - help - This provides two commands which operate on a resierfs filesystem, - commonly used some years ago: - - reiserls - list files - reiserload - load a file - config CMD_YAFFS2 bool "yaffs2 - Access of YAFFS2 filesystem" depends on YAFFS2 diff --git a/cmd/Makefile b/cmd/Makefile index 5ed0e40..87133cc 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -168,6 +168,7 @@ obj-$(CONFIG_CMD_SETEXPR) += setexpr.o obj-$(CONFIG_CMD_SETEXPR_FMT) += printf.o obj-$(CONFIG_CMD_SPI) += spi.o obj-$(CONFIG_CMD_STRINGS) += strings.o +obj-$(CONFIG_CMD_SMBIOS) += smbios.o obj-$(CONFIG_CMD_SMC) += smccc.o obj-$(CONFIG_CMD_SYSBOOT) += sysboot.o obj-$(CONFIG_CMD_STACKPROTECTOR_TEST) += stackprot_test.o @@ -229,6 +230,8 @@ obj-$(CONFIG_CMD_AVB) += avb.o # Foundries.IO SCP03 obj-$(CONFIG_CMD_SCP03) += scp03.o +obj-$(CONFIG_HUSH_SELECTABLE) += cli.o + obj-$(CONFIG_ARM) += arm/ obj-$(CONFIG_RISCV) += riscv/ obj-$(CONFIG_SANDBOX) += sandbox/ @@ -6,6 +6,7 @@ #include <common.h> #include <command.h> #include <display_options.h> +#include <log.h> #include <mapmem.h> #include <acpi/acpi_table.h> #include <asm/acpi_table.h> @@ -17,7 +18,8 @@ DECLARE_GLOBAL_DATA_PTR; /** * dump_hdr() - Dump an ACPI header * - * If the header is for FACS then it shows the revision information as well + * Except for the Firmware ACPI Control Structure (FACS) + * additionally show the revision information. * * @hdr: ACPI header to dump */ @@ -25,12 +27,12 @@ static void dump_hdr(struct acpi_table_header *hdr) { bool has_hdr = memcmp(hdr->signature, "FACS", ACPI_NAME_LEN); - printf("%.*s %08lx %5x", ACPI_NAME_LEN, hdr->signature, + printf("%.*s %16lx %5x", ACPI_NAME_LEN, hdr->signature, (ulong)map_to_sysmem(hdr), hdr->length); if (has_hdr) { printf(" v%02d %.6s %.8s %x %.4s %x\n", hdr->revision, hdr->oem_id, hdr->oem_table_id, hdr->oem_revision, - hdr->aslc_id, hdr->aslc_revision); + hdr->creator_id, hdr->creator_revision); } else { printf("\n"); } @@ -43,8 +45,8 @@ static int dump_table_name(const char *sig) hdr = acpi_find_table(sig); if (!hdr) return -ENOENT; - printf("%.*s @ %08lx\n", ACPI_NAME_LEN, hdr->signature, - (ulong)map_to_sysmem(hdr)); + printf("%.*s @ %16lx\n", ACPI_NAME_LEN, hdr->signature, + (ulong)nomap_to_sysmem(hdr)); print_buffer(0, hdr, 1, hdr->length, 0); return 0; @@ -52,53 +54,63 @@ static int dump_table_name(const char *sig) static void list_fadt(struct acpi_fadt *fadt) { - if (fadt->dsdt) - dump_hdr(map_sysmem(fadt->dsdt, 0)); - if (fadt->firmware_ctrl) - dump_hdr(map_sysmem(fadt->firmware_ctrl, 0)); + if (fadt->header.revision >= 3 && fadt->x_dsdt) + dump_hdr(nomap_sysmem(fadt->x_dsdt, 0)); + else if (fadt->dsdt) + dump_hdr(nomap_sysmem(fadt->dsdt, 0)); + if (!IS_ENABLED(CONFIG_X86) && + !(fadt->flags & ACPI_FADT_HW_REDUCED_ACPI)) + log_err("FADT not ACPI-hardware-reduced-compliant\n"); + if (fadt->header.revision >= 3 && fadt->x_firmware_ctrl) + dump_hdr(nomap_sysmem(fadt->x_firmware_ctrl, 0)); + else if (fadt->firmware_ctrl) + dump_hdr(nomap_sysmem(fadt->firmware_ctrl, 0)); } -static int list_rsdt(struct acpi_rsdt *rsdt, struct acpi_xsdt *xsdt) +static void list_rsdt(struct acpi_rsdp *rsdp) { int len, i, count; + struct acpi_rsdt *rsdt; + struct acpi_xsdt *xsdt; - dump_hdr(&rsdt->header); - if (xsdt) + if (rsdp->rsdt_address) { + rsdt = nomap_sysmem(rsdp->rsdt_address, 0); + dump_hdr(&rsdt->header); + } + if (rsdp->xsdt_address) { + xsdt = nomap_sysmem(rsdp->xsdt_address, 0); dump_hdr(&xsdt->header); - len = rsdt->header.length - sizeof(rsdt->header); - count = len / sizeof(u32); + len = xsdt->header.length - sizeof(xsdt->header); + count = len / sizeof(u64); + } else if (rsdp->rsdt_address) { + len = rsdt->header.length - sizeof(rsdt->header); + count = len / sizeof(u32); + } else { + return; + } + for (i = 0; i < count; i++) { struct acpi_table_header *hdr; + u64 entry; - if (!rsdt->entry[i]) + if (rsdp->xsdt_address) + entry = xsdt->entry[i]; + else + entry = rsdt->entry[i]; + if (!entry) break; - hdr = map_sysmem(rsdt->entry[i], 0); + hdr = nomap_sysmem(entry, 0); dump_hdr(hdr); if (!memcmp(hdr->signature, "FACP", ACPI_NAME_LEN)) list_fadt((struct acpi_fadt *)hdr); - if (xsdt) { - if (xsdt->entry[i] != rsdt->entry[i]) { - printf(" (xsdt mismatch %llx)\n", - xsdt->entry[i]); - } - } } - - return 0; } -static int list_rsdp(struct acpi_rsdp *rsdp) +static void list_rsdp(struct acpi_rsdp *rsdp) { - struct acpi_rsdt *rsdt; - struct acpi_xsdt *xsdt; - - printf("RSDP %08lx %5x v%02d %.6s\n", (ulong)map_to_sysmem(rsdp), + printf("RSDP %16lx %5x v%02d %.6s\n", (ulong)map_to_sysmem(rsdp), rsdp->length, rsdp->revision, rsdp->oem_id); - rsdt = map_sysmem(rsdp->rsdt_address, 0); - xsdt = map_sysmem(rsdp->xsdt_address, 0); - list_rsdt(rsdt, xsdt); - - return 0; + list_rsdt(rsdp); } static int do_acpi_list(struct cmd_tbl *cmdtp, int flag, int argc, @@ -111,8 +123,8 @@ static int do_acpi_list(struct cmd_tbl *cmdtp, int flag, int argc, printf("No ACPI tables present\n"); return 0; } - printf("Name Base Size Detail\n"); - printf("---- -------- ----- ------\n"); + printf("Name Base Size Detail\n" + "---- ---------------- ----- ----------------------------\n"); list_rsdp(rsdp); return 0; @@ -156,6 +168,9 @@ static int do_acpi_dump(struct cmd_tbl *cmdtp, int flag, int argc, char sig[ACPI_NAME_LEN]; int ret; + if (argc < 2) + return CMD_RET_USAGE; + name = argv[1]; if (strlen(name) != ACPI_NAME_LEN) { printf("Table name '%s' must be four characters\n", name); diff --git a/cmd/arm/exception.c b/cmd/arm/exception.c index 522f6df..98a9795 100644 --- a/cmd/arm/exception.c +++ b/cmd/arm/exception.c @@ -5,7 +5,6 @@ * Copyright (c) 2018, Heinrich Schuchardt <xypron.glpk@gmx.de> */ -#include <common.h> #include <command.h> static int do_unaligned(struct cmd_tbl *cmdtp, int flag, int argc, diff --git a/cmd/armflash.c b/cmd/armflash.c index d1466f7..fdaea5a 100644 --- a/cmd/armflash.c +++ b/cmd/armflash.c @@ -180,6 +180,7 @@ static int load_image(const char * const name, const ulong address) { struct afs_image *afi = NULL; int i; + loff_t len_read = 0; parse_flash(); for (i = 0; i < num_afs_images; i++) { @@ -197,6 +198,7 @@ static int load_image(const char * const name, const ulong address) for (i = 0; i < afi->region_count; i++) { ulong from, to; + u32 size; from = afi->flash_mem_start + afi->regions[i].offset; if (address) { @@ -208,14 +210,20 @@ static int load_image(const char * const name, const ulong address) return CMD_RET_FAILURE; } - memcpy((void *)to, (void *)from, afi->regions[i].size); + size = afi->regions[i].size; + memcpy((void *)to, (void *)from, size); printf("loaded region %d from %08lX to %08lX, %08X bytes\n", i, from, to, - afi->regions[i].size); + size); + + len_read += size; } + + env_set_hex("filesize", len_read); + return CMD_RET_SUCCESS; } @@ -1,8 +1,6 @@ - +// SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2018, Linaro Limited - * - * SPDX-License-Identifier: GPL-2.0+ */ #include <avb_verify.h> @@ -13,6 +11,7 @@ #include <mmc.h> #define AVB_BOOTARGS "avb_bootargs" + static struct AvbOps *avb_ops; int do_avb_init(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) @@ -30,8 +29,10 @@ int do_avb_init(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) avb_ops = avb_ops_alloc(mmc_dev); if (avb_ops) return CMD_RET_SUCCESS; + else + printf("Can't allocate AvbOps"); - printf("Failed to initialize avb2\n"); + printf("Failed to initialize AVB\n"); return CMD_RET_FAILURE; } @@ -43,10 +44,11 @@ int do_avb_read_part(struct cmd_tbl *cmdtp, int flag, int argc, s64 offset; size_t bytes, bytes_read = 0; void *buffer; + int ret; if (!avb_ops) { - printf("AVB 2.0 is not initialized, please run 'avb init'\n"); - return CMD_RET_USAGE; + printf("AVB is not initialized, please run 'avb init <id>'\n"); + return CMD_RET_FAILURE; } if (argc != 5) @@ -57,14 +59,15 @@ int do_avb_read_part(struct cmd_tbl *cmdtp, int flag, int argc, bytes = hextoul(argv[3], NULL); buffer = (void *)hextoul(argv[4], NULL); - if (avb_ops->read_from_partition(avb_ops, part, offset, bytes, - buffer, &bytes_read) == - AVB_IO_RESULT_OK) { + ret = avb_ops->read_from_partition(avb_ops, part, offset, + bytes, buffer, &bytes_read); + if (ret == AVB_IO_RESULT_OK) { printf("Read %zu bytes\n", bytes_read); return CMD_RET_SUCCESS; } - printf("Failed to read from partition\n"); + printf("Failed to read from partition '%s', err = %d\n", + part, ret); return CMD_RET_FAILURE; } @@ -76,10 +79,11 @@ int do_avb_read_part_hex(struct cmd_tbl *cmdtp, int flag, int argc, s64 offset; size_t bytes, bytes_read = 0; char *buffer; + int ret; if (!avb_ops) { - printf("AVB 2.0 is not initialized, please run 'avb init'\n"); - return CMD_RET_USAGE; + printf("AVB is not initialized, please run 'avb init <id>'\n"); + return CMD_RET_FAILURE; } if (argc != 4) @@ -96,8 +100,9 @@ int do_avb_read_part_hex(struct cmd_tbl *cmdtp, int flag, int argc, } memset(buffer, 0, bytes); - if (avb_ops->read_from_partition(avb_ops, part, offset, bytes, buffer, - &bytes_read) == AVB_IO_RESULT_OK) { + ret = avb_ops->read_from_partition(avb_ops, part, offset, + bytes, buffer, &bytes_read); + if (ret == AVB_IO_RESULT_OK) { printf("Requested %zu, read %zu bytes\n", bytes, bytes_read); printf("Data: "); for (int i = 0; i < bytes_read; i++) @@ -109,7 +114,8 @@ int do_avb_read_part_hex(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_SUCCESS; } - printf("Failed to read from partition\n"); + printf("Failed to read from partition '%s', err = %d\n", + part, ret); free(buffer); return CMD_RET_FAILURE; @@ -122,9 +128,10 @@ int do_avb_write_part(struct cmd_tbl *cmdtp, int flag, int argc, s64 offset; size_t bytes; void *buffer; + int ret; if (!avb_ops) { - printf("AVB 2.0 is not initialized, run 'avb init' first\n"); + printf("AVB is not initialized, please run 'avb init <id>'\n"); return CMD_RET_FAILURE; } @@ -136,13 +143,15 @@ int do_avb_write_part(struct cmd_tbl *cmdtp, int flag, int argc, bytes = hextoul(argv[3], NULL); buffer = (void *)hextoul(argv[4], NULL); - if (avb_ops->write_to_partition(avb_ops, part, offset, bytes, buffer) == - AVB_IO_RESULT_OK) { + ret = avb_ops->write_to_partition(avb_ops, part, offset, + bytes, buffer); + if (ret == AVB_IO_RESULT_OK) { printf("Wrote %zu bytes\n", bytes); return CMD_RET_SUCCESS; } - printf("Failed to write in partition\n"); + printf("Failed to write in partition '%s', err = %d\n", + part, ret); return CMD_RET_FAILURE; } @@ -152,9 +161,10 @@ int do_avb_read_rb(struct cmd_tbl *cmdtp, int flag, int argc, { size_t index; u64 rb_idx; + int ret; if (!avb_ops) { - printf("AVB 2.0 is not initialized, run 'avb init' first\n"); + printf("AVB is not initialized, please run 'avb init <id>'\n"); return CMD_RET_FAILURE; } @@ -163,13 +173,14 @@ int do_avb_read_rb(struct cmd_tbl *cmdtp, int flag, int argc, index = (size_t)hextoul(argv[1], NULL); - if (avb_ops->read_rollback_index(avb_ops, index, &rb_idx) == - AVB_IO_RESULT_OK) { + ret = avb_ops->read_rollback_index(avb_ops, index, &rb_idx); + if (ret == AVB_IO_RESULT_OK) { printf("Rollback index: %llx\n", rb_idx); return CMD_RET_SUCCESS; } - printf("Failed to read rollback index\n"); + printf("Failed to read rollback index id = %zu, err = %d\n", + index, ret); return CMD_RET_FAILURE; } @@ -179,9 +190,10 @@ int do_avb_write_rb(struct cmd_tbl *cmdtp, int flag, int argc, { size_t index; u64 rb_idx; + int ret; if (!avb_ops) { - printf("AVB 2.0 is not initialized, run 'avb init' first\n"); + printf("AVB is not initialized, please run 'avb init <id>'\n"); return CMD_RET_FAILURE; } @@ -191,11 +203,12 @@ int do_avb_write_rb(struct cmd_tbl *cmdtp, int flag, int argc, index = (size_t)hextoul(argv[1], NULL); rb_idx = hextoul(argv[2], NULL); - if (avb_ops->write_rollback_index(avb_ops, index, rb_idx) == - AVB_IO_RESULT_OK) + ret = avb_ops->write_rollback_index(avb_ops, index, rb_idx); + if (ret == AVB_IO_RESULT_OK) return CMD_RET_SUCCESS; - printf("Failed to write rollback index\n"); + printf("Failed to write rollback index id = %zu, err = %d\n", + index, ret); return CMD_RET_FAILURE; } @@ -205,9 +218,10 @@ int do_avb_get_uuid(struct cmd_tbl *cmdtp, int flag, { const char *part; char buffer[UUID_STR_LEN + 1]; + int ret; if (!avb_ops) { - printf("AVB 2.0 is not initialized, run 'avb init' first\n"); + printf("AVB is not initialized, please run 'avb init <id>'\n"); return CMD_RET_FAILURE; } @@ -216,14 +230,16 @@ int do_avb_get_uuid(struct cmd_tbl *cmdtp, int flag, part = argv[1]; - if (avb_ops->get_unique_guid_for_partition(avb_ops, part, buffer, - UUID_STR_LEN + 1) == - AVB_IO_RESULT_OK) { + ret = avb_ops->get_unique_guid_for_partition(avb_ops, part, + buffer, + UUID_STR_LEN + 1); + if (ret == AVB_IO_RESULT_OK) { printf("'%s' UUID: %s\n", part, buffer); return CMD_RET_SUCCESS; } - printf("Failed to read UUID\n"); + printf("Failed to read partition '%s' UUID, err = %d\n", + part, ret); return CMD_RET_FAILURE; } @@ -234,15 +250,17 @@ int do_avb_verify_part(struct cmd_tbl *cmdtp, int flag, const char * const requested_partitions[] = {"boot", NULL}; AvbSlotVerifyResult slot_result; AvbSlotVerifyData *out_data; + enum avb_boot_state boot_state; char *cmdline; char *extra_args; char *slot_suffix = ""; + int ret; bool unlocked = false; int res = CMD_RET_FAILURE; if (!avb_ops) { - printf("AVB 2.0 is not initialized, run 'avb init' first\n"); + printf("AVB is not initialized, please run 'avb init <id>'\n"); return CMD_RET_FAILURE; } @@ -255,9 +273,10 @@ int do_avb_verify_part(struct cmd_tbl *cmdtp, int flag, printf("## Android Verified Boot 2.0 version %s\n", avb_version_string()); - if (avb_ops->read_is_device_unlocked(avb_ops, &unlocked) != - AVB_IO_RESULT_OK) { - printf("Can't determine device lock state.\n"); + ret = avb_ops->read_is_device_unlocked(avb_ops, &unlocked); + if (ret != AVB_IO_RESULT_OK) { + printf("Can't determine device lock state, err = %d\n", + ret); return CMD_RET_FAILURE; } @@ -269,18 +288,23 @@ int do_avb_verify_part(struct cmd_tbl *cmdtp, int flag, AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, &out_data); - switch (slot_result) { - case AVB_SLOT_VERIFY_RESULT_OK: - /* Until we don't have support of changing unlock states, we - * assume that we are by default in locked state. - * So in this case we can boot only when verification is - * successful; we also supply in cmdline GREEN boot state - */ + /* + * LOCKED devices with custom root of trust setup is not supported (YELLOW) + */ + if (slot_result == AVB_SLOT_VERIFY_RESULT_OK) { printf("Verification passed successfully\n"); - /* export additional bootargs to AVB_BOOTARGS env var */ + /* + * ORANGE state indicates that device may be freely modified. + * Device integrity is left to the user to verify out-of-band. + */ + if (unlocked) + boot_state = AVB_ORANGE; + else + boot_state = AVB_GREEN; - extra_args = avb_set_state(avb_ops, AVB_GREEN); + /* export boot state to AVB_BOOTARGS env var */ + extra_args = avb_set_state(avb_ops, boot_state); if (extra_args) cmdline = append_cmd_line(out_data->cmdline, extra_args); @@ -290,30 +314,8 @@ int do_avb_verify_part(struct cmd_tbl *cmdtp, int flag, env_set(AVB_BOOTARGS, cmdline); res = CMD_RET_SUCCESS; - break; - case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION: - printf("Verification failed\n"); - break; - case AVB_SLOT_VERIFY_RESULT_ERROR_IO: - printf("I/O error occurred during verification\n"); - break; - case AVB_SLOT_VERIFY_RESULT_ERROR_OOM: - printf("OOM error occurred during verification\n"); - break; - case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA: - printf("Corrupted dm-verity metadata detected\n"); - break; - case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION: - printf("Unsupported version avbtool was used\n"); - break; - case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX: - printf("Checking rollback index failed\n"); - break; - case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED: - printf("Public key was rejected\n"); - break; - default: - printf("Unknown error occurred\n"); + } else { + printf("Verification failed, reason: %s\n", str_avb_slot_error(slot_result)); } if (out_data) @@ -326,9 +328,10 @@ int do_avb_is_unlocked(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { bool unlock; + int ret; if (!avb_ops) { - printf("AVB not initialized, run 'avb init' first\n"); + printf("AVB is not initialized, please run 'avb init <id>'\n"); return CMD_RET_FAILURE; } @@ -337,13 +340,14 @@ int do_avb_is_unlocked(struct cmd_tbl *cmdtp, int flag, return CMD_RET_USAGE; } - if (avb_ops->read_is_device_unlocked(avb_ops, &unlock) == - AVB_IO_RESULT_OK) { + ret = avb_ops->read_is_device_unlocked(avb_ops, &unlock); + if (ret == AVB_IO_RESULT_OK) { printf("Unlocked = %d\n", unlock); return CMD_RET_SUCCESS; } - printf("Can't determine device lock state.\n"); + printf("Can't determine device lock state, err = %d\n", + ret); return CMD_RET_FAILURE; } @@ -356,9 +360,10 @@ int do_avb_read_pvalue(struct cmd_tbl *cmdtp, int flag, int argc, size_t bytes_read; void *buffer; char *endp; + int ret; if (!avb_ops) { - printf("AVB 2.0 is not initialized, run 'avb init' first\n"); + printf("AVB is not initialized, please run 'avb init <id>'\n"); return CMD_RET_FAILURE; } @@ -374,15 +379,16 @@ int do_avb_read_pvalue(struct cmd_tbl *cmdtp, int flag, int argc, if (!buffer) return CMD_RET_FAILURE; - if (avb_ops->read_persistent_value(avb_ops, name, bytes, buffer, - &bytes_read) == AVB_IO_RESULT_OK) { + ret = avb_ops->read_persistent_value(avb_ops, name, bytes, + buffer, &bytes_read); + if (ret == AVB_IO_RESULT_OK) { printf("Read %zu bytes, value = %s\n", bytes_read, (char *)buffer); free(buffer); return CMD_RET_SUCCESS; } - printf("Failed to read persistent value\n"); + printf("Failed to read persistent value, err = %d\n", ret); free(buffer); @@ -394,9 +400,10 @@ int do_avb_write_pvalue(struct cmd_tbl *cmdtp, int flag, int argc, { const char *name; const char *value; + int ret; if (!avb_ops) { - printf("AVB 2.0 is not initialized, run 'avb init' first\n"); + printf("AVB is not initialized, please run 'avb init <id>'\n"); return CMD_RET_FAILURE; } @@ -406,14 +413,16 @@ int do_avb_write_pvalue(struct cmd_tbl *cmdtp, int flag, int argc, name = argv[1]; value = argv[2]; - if (avb_ops->write_persistent_value(avb_ops, name, strlen(value) + 1, - (const uint8_t *)value) == - AVB_IO_RESULT_OK) { + ret = avb_ops->write_persistent_value(avb_ops, name, + strlen(value) + 1, + (const uint8_t *)value); + if (ret == AVB_IO_RESULT_OK) { printf("Wrote %zu bytes\n", strlen(value) + 1); return CMD_RET_SUCCESS; } - printf("Failed to write persistent value\n"); + printf("Failed to write persistent value `%s` = `%s`, err = %d\n", + name, value, ret); return CMD_RET_FAILURE; } diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 4d74969..578dbb1 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -7,555 +7,23 @@ #define LOG_CATEGORY LOGC_EFI -#include <common.h> -#include <bootm.h> -#include <charset.h> #include <command.h> -#include <dm.h> +#include <efi.h> #include <efi_loader.h> -#include <efi_selftest.h> -#include <env.h> -#include <errno.h> -#include <image.h> +#include <exports.h> #include <log.h> #include <malloc.h> -#include <asm/global_data.h> -#include <linux/libfdt.h> -#include <linux/libfdt_env.h> #include <mapmem.h> -#include <memalign.h> +#include <vsprintf.h> #include <asm-generic/sections.h> -#include <linux/linkage.h> +#include <asm/global_data.h> +#include <linux/string.h> DECLARE_GLOBAL_DATA_PTR; -static struct efi_device_path *bootefi_image_path; -static struct efi_device_path *bootefi_device_path; -static void *image_addr; -static size_t image_size; - -/** - * efi_get_image_parameters() - return image parameters - * - * @img_addr: address of loaded image in memory - * @img_size: size of loaded image - */ -void efi_get_image_parameters(void **img_addr, size_t *img_size) -{ - *img_addr = image_addr; - *img_size = image_size; -} - -/** - * efi_clear_bootdev() - clear boot device - */ -static void efi_clear_bootdev(void) -{ - efi_free_pool(bootefi_device_path); - efi_free_pool(bootefi_image_path); - bootefi_device_path = NULL; - bootefi_image_path = NULL; - image_addr = NULL; - image_size = 0; -} - -/** - * efi_set_bootdev() - set boot device - * - * This function is called when a file is loaded, e.g. via the 'load' command. - * We use the path to this file to inform the UEFI binary about the boot device. - * - * @dev: device, e.g. "MMC" - * @devnr: number of the device, e.g. "1:2" - * @path: path to file loaded - * @buffer: buffer with file loaded - * @buffer_size: size of file loaded - */ -void efi_set_bootdev(const char *dev, const char *devnr, const char *path, - void *buffer, size_t buffer_size) -{ - struct efi_device_path *device, *image; - efi_status_t ret; - - log_debug("dev=%s, devnr=%s, path=%s, buffer=%p, size=%zx\n", dev, - devnr, path, buffer, buffer_size); - - /* Forget overwritten image */ - if (buffer + buffer_size >= image_addr && - image_addr + image_size >= buffer) - efi_clear_bootdev(); - - /* Remember only PE-COFF and FIT images */ - if (efi_check_pe(buffer, buffer_size, NULL) != EFI_SUCCESS) { - if (IS_ENABLED(CONFIG_FIT) && - !fit_check_format(buffer, IMAGE_SIZE_INVAL)) { - /* - * FIT images of type EFI_OS are started via command - * bootm. We should not use their boot device with the - * bootefi command. - */ - buffer = 0; - buffer_size = 0; - } else { - log_debug("- not remembering image\n"); - return; - } - } - - /* efi_set_bootdev() is typically called repeatedly, recover memory */ - efi_clear_bootdev(); - - image_addr = buffer; - image_size = buffer_size; - - ret = efi_dp_from_name(dev, devnr, path, &device, &image); - if (ret == EFI_SUCCESS) { - bootefi_device_path = device; - if (image) { - /* FIXME: image should not contain device */ - struct efi_device_path *image_tmp = image; - - efi_dp_split_file_path(image, &device, &image); - efi_free_pool(image_tmp); - } - bootefi_image_path = image; - log_debug("- boot device %pD\n", device); - if (image) - log_debug("- image %pD\n", image); - } else { - log_debug("- efi_dp_from_name() failed, err=%lx\n", ret); - efi_clear_bootdev(); - } -} - -/** - * efi_env_set_load_options() - set load options from environment variable - * - * @handle: the image handle - * @env_var: name of the environment variable - * @load_options: pointer to load options (output) - * Return: status code - */ -static efi_status_t efi_env_set_load_options(efi_handle_t handle, - const char *env_var, - u16 **load_options) -{ - const char *env = env_get(env_var); - size_t size; - u16 *pos; - efi_status_t ret; - - *load_options = NULL; - if (!env) - return EFI_SUCCESS; - size = sizeof(u16) * (utf8_utf16_strlen(env) + 1); - pos = calloc(size, 1); - if (!pos) - return EFI_OUT_OF_RESOURCES; - *load_options = pos; - utf8_utf16_strcpy(&pos, env); - ret = efi_set_load_options(handle, size, *load_options); - if (ret != EFI_SUCCESS) { - free(*load_options); - *load_options = NULL; - } - return ret; -} - -#if !CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) - -/** - * copy_fdt() - Copy the device tree to a new location available to EFI - * - * The FDT is copied to a suitable location within the EFI memory map. - * Additional 12 KiB are added to the space in case the device tree needs to be - * expanded later with fdt_open_into(). - * - * @fdtp: On entry a pointer to the flattened device tree. - * On exit a pointer to the copy of the flattened device tree. - * FDT start - * Return: status code - */ -static efi_status_t copy_fdt(void **fdtp) -{ - unsigned long fdt_ram_start = -1L, fdt_pages; - efi_status_t ret = 0; - void *fdt, *new_fdt; - u64 new_fdt_addr; - uint fdt_size; - int i; - - for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { - u64 ram_start = gd->bd->bi_dram[i].start; - u64 ram_size = gd->bd->bi_dram[i].size; - - if (!ram_size) - continue; - - if (ram_start < fdt_ram_start) - fdt_ram_start = ram_start; - } - - /* - * Give us at least 12 KiB of breathing room in case the device tree - * needs to be expanded later. - */ - fdt = *fdtp; - fdt_pages = efi_size_in_pages(fdt_totalsize(fdt) + 0x3000); - fdt_size = fdt_pages << EFI_PAGE_SHIFT; - - ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, - EFI_ACPI_RECLAIM_MEMORY, fdt_pages, - &new_fdt_addr); - if (ret != EFI_SUCCESS) { - log_err("ERROR: Failed to reserve space for FDT\n"); - goto done; - } - new_fdt = (void *)(uintptr_t)new_fdt_addr; - memcpy(new_fdt, fdt, fdt_totalsize(fdt)); - fdt_set_totalsize(new_fdt, fdt_size); +static struct efi_device_path *test_image_path; +static struct efi_device_path *test_device_path; - *fdtp = (void *)(uintptr_t)new_fdt_addr; -done: - return ret; -} - -/** - * get_config_table() - get configuration table - * - * @guid: GUID of the configuration table - * Return: pointer to configuration table or NULL - */ -static void *get_config_table(const efi_guid_t *guid) -{ - size_t i; - - for (i = 0; i < systab.nr_tables; i++) { - if (!guidcmp(guid, &systab.tables[i].guid)) - return systab.tables[i].table; - } - return NULL; -} - -#endif /* !CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) */ - -/** - * efi_install_fdt() - install device tree - * - * If fdt is not EFI_FDT_USE_INTERNAL, the device tree located at that memory - * address will will be installed as configuration table, otherwise the device - * tree located at the address indicated by environment variable fdt_addr or as - * fallback fdtcontroladdr will be used. - * - * On architectures using ACPI tables device trees shall not be installed as - * configuration table. - * - * @fdt: address of device tree or EFI_FDT_USE_INTERNAL to use the - * the hardware device tree as indicated by environment variable - * fdt_addr or as fallback the internal device tree as indicated by - * the environment variable fdtcontroladdr - * Return: status code - */ -efi_status_t efi_install_fdt(void *fdt) -{ - /* - * The EBBR spec requires that we have either an FDT or an ACPI table - * but not both. - */ -#if CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE) - if (fdt) { - log_warning("WARNING: Can't have ACPI table and device tree - ignoring DT.\n"); - return EFI_SUCCESS; - } -#else - struct bootm_headers img = { 0 }; - efi_status_t ret; - - if (fdt == EFI_FDT_USE_INTERNAL) { - const char *fdt_opt; - uintptr_t fdt_addr; - - /* Look for device tree that is already installed */ - if (get_config_table(&efi_guid_fdt)) - return EFI_SUCCESS; - /* Check if there is a hardware device tree */ - fdt_opt = env_get("fdt_addr"); - /* Use our own device tree as fallback */ - if (!fdt_opt) { - fdt_opt = env_get("fdtcontroladdr"); - if (!fdt_opt) { - log_err("ERROR: need device tree\n"); - return EFI_NOT_FOUND; - } - } - fdt_addr = hextoul(fdt_opt, NULL); - if (!fdt_addr) { - log_err("ERROR: invalid $fdt_addr or $fdtcontroladdr\n"); - return EFI_LOAD_ERROR; - } - fdt = map_sysmem(fdt_addr, 0); - } - - /* Install device tree */ - if (fdt_check_header(fdt)) { - log_err("ERROR: invalid device tree\n"); - return EFI_LOAD_ERROR; - } - - /* Prepare device tree for payload */ - ret = copy_fdt(&fdt); - if (ret) { - log_err("ERROR: out of memory\n"); - return EFI_OUT_OF_RESOURCES; - } - - if (image_setup_libfdt(&img, fdt, 0, NULL)) { - log_err("ERROR: failed to process device tree\n"); - return EFI_LOAD_ERROR; - } - - /* Create memory reservations as indicated by the device tree */ - efi_carve_out_dt_rsv(fdt); - - efi_try_purge_kaslr_seed(fdt); - - if (CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL_MEASURE_DTB)) { - ret = efi_tcg2_measure_dtb(fdt); - if (ret == EFI_SECURITY_VIOLATION) { - log_err("ERROR: failed to measure DTB\n"); - return ret; - } - } - - /* Install device tree as UEFI table */ - ret = efi_install_configuration_table(&efi_guid_fdt, fdt); - if (ret != EFI_SUCCESS) { - log_err("ERROR: failed to install device tree\n"); - return ret; - } -#endif /* GENERATE_ACPI_TABLE */ - - return EFI_SUCCESS; -} - -/** - * do_bootefi_exec() - execute EFI binary - * - * The image indicated by @handle is started. When it returns the allocated - * memory for the @load_options is freed. - * - * @handle: handle of loaded image - * @load_options: load options - * Return: status code - * - * Load the EFI binary into a newly assigned memory unwinding the relocation - * information, install the loaded image protocol, and call the binary. - */ -static efi_status_t do_bootefi_exec(efi_handle_t handle, void *load_options) -{ - efi_status_t ret; - efi_uintn_t exit_data_size = 0; - u16 *exit_data = NULL; - struct efi_event *evt; - - /* On ARM switch from EL3 or secure mode to EL2 or non-secure mode */ - switch_to_non_secure_mode(); - - /* - * The UEFI standard requires that the watchdog timer is set to five - * minutes when invoking an EFI boot option. - * - * Unified Extensible Firmware Interface (UEFI), version 2.7 Errata A - * 7.5. Miscellaneous Boot Services - EFI_BOOT_SERVICES.SetWatchdogTimer - */ - ret = efi_set_watchdog(300); - if (ret != EFI_SUCCESS) { - log_err("ERROR: Failed to set watchdog timer\n"); - goto out; - } - - /* Call our payload! */ - ret = EFI_CALL(efi_start_image(handle, &exit_data_size, &exit_data)); - if (ret != EFI_SUCCESS) { - log_err("## Application failed, r = %lu\n", - ret & ~EFI_ERROR_MASK); - if (exit_data) { - log_err("## %ls\n", exit_data); - efi_free_pool(exit_data); - } - } - - efi_restore_gd(); - -out: - free(load_options); - - if (IS_ENABLED(CONFIG_EFI_LOAD_FILE2_INITRD)) { - if (efi_initrd_deregister() != EFI_SUCCESS) - log_err("Failed to remove loadfile2 for initrd\n"); - } - - /* Notify EFI_EVENT_GROUP_RETURN_TO_EFIBOOTMGR event group. */ - list_for_each_entry(evt, &efi_events, link) { - if (evt->group && - !guidcmp(evt->group, - &efi_guid_event_group_return_to_efibootmgr)) { - efi_signal_event(evt); - EFI_CALL(systab.boottime->close_event(evt)); - break; - } - } - - /* Control is returned to U-Boot, disable EFI watchdog */ - efi_set_watchdog(0); - - return ret; -} - -/** - * do_efibootmgr() - execute EFI boot manager - * - * Return: status code - */ -static int do_efibootmgr(void) -{ - efi_handle_t handle; - efi_status_t ret; - void *load_options; - - ret = efi_bootmgr_load(&handle, &load_options); - if (ret != EFI_SUCCESS) { - log_notice("EFI boot manager: Cannot load any image\n"); - return CMD_RET_FAILURE; - } - - ret = do_bootefi_exec(handle, load_options); - - if (ret != EFI_SUCCESS) - return CMD_RET_FAILURE; - - return CMD_RET_SUCCESS; -} - -/** - * do_bootefi_image() - execute EFI binary - * - * Set up memory image for the binary to be loaded, prepare device path, and - * then call do_bootefi_exec() to execute it. - * - * @image_opt: string with image start address - * @size_opt: string with image size or NULL - * Return: status code - */ -static int do_bootefi_image(const char *image_opt, const char *size_opt) -{ - void *image_buf; - unsigned long addr, size; - efi_status_t ret; - -#ifdef CONFIG_CMD_BOOTEFI_HELLO - if (!strcmp(image_opt, "hello")) { - image_buf = __efi_helloworld_begin; - size = __efi_helloworld_end - __efi_helloworld_begin; - efi_clear_bootdev(); - } else -#endif - { - addr = strtoul(image_opt, NULL, 16); - /* Check that a numeric value was passed */ - if (!addr) - return CMD_RET_USAGE; - image_buf = map_sysmem(addr, 0); - - if (size_opt) { - size = strtoul(size_opt, NULL, 16); - if (!size) - return CMD_RET_USAGE; - efi_clear_bootdev(); - } else { - if (image_buf != image_addr) { - log_err("No UEFI binary known at %s\n", - image_opt); - return CMD_RET_FAILURE; - } - size = image_size; - } - } - ret = efi_run_image(image_buf, size); - - if (ret != EFI_SUCCESS) - return CMD_RET_FAILURE; - - return CMD_RET_SUCCESS; -} - -/** - * efi_run_image() - run loaded UEFI image - * - * @source_buffer: memory address of the UEFI image - * @source_size: size of the UEFI image - * Return: status code - */ -efi_status_t efi_run_image(void *source_buffer, efi_uintn_t source_size) -{ - efi_handle_t mem_handle = NULL, handle; - struct efi_device_path *file_path = NULL; - struct efi_device_path *msg_path; - efi_status_t ret, ret2; - u16 *load_options; - - if (!bootefi_device_path || !bootefi_image_path) { - log_debug("Not loaded from disk\n"); - /* - * Special case for efi payload not loaded from disk, - * such as 'bootefi hello' or for example payload - * loaded directly into memory via JTAG, etc: - */ - file_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE, - (uintptr_t)source_buffer, - source_size); - /* - * Make sure that device for device_path exist - * in load_image(). Otherwise, shell and grub will fail. - */ - ret = efi_install_multiple_protocol_interfaces(&mem_handle, - &efi_guid_device_path, - file_path, NULL); - if (ret != EFI_SUCCESS) - goto out; - msg_path = file_path; - } else { - file_path = efi_dp_append(bootefi_device_path, - bootefi_image_path); - msg_path = bootefi_image_path; - log_debug("Loaded from disk\n"); - } - - log_info("Booting %pD\n", msg_path); - - ret = EFI_CALL(efi_load_image(false, efi_root, file_path, source_buffer, - source_size, &handle)); - if (ret != EFI_SUCCESS) { - log_err("Loading image failed\n"); - goto out; - } - - /* Transfer environment variable as load options */ - ret = efi_env_set_load_options(handle, "bootargs", &load_options); - if (ret != EFI_SUCCESS) - goto out; - - ret = do_bootefi_exec(handle, load_options); - -out: - ret2 = efi_uninstall_multiple_protocol_interfaces(mem_handle, - &efi_guid_device_path, - file_path, NULL); - efi_free_pool(file_path); - return (ret != EFI_SUCCESS) ? ret : ret2; -} - -#ifdef CONFIG_CMD_BOOTEFI_SELFTEST static efi_status_t bootefi_run_prepare(const char *load_options_path, struct efi_device_path *device_path, struct efi_device_path *image_path, @@ -597,23 +65,26 @@ static efi_status_t bootefi_test_prepare efi_status_t ret; /* Construct a dummy device path */ - bootefi_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE, 0, 0); - if (!bootefi_device_path) + test_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE, 0, 0); + if (!test_device_path) return EFI_OUT_OF_RESOURCES; - bootefi_image_path = efi_dp_from_file(NULL, path); - if (!bootefi_image_path) { + test_image_path = efi_dp_from_file(NULL, path); + if (!test_image_path) { ret = EFI_OUT_OF_RESOURCES; goto failure; } - ret = bootefi_run_prepare(load_options_path, bootefi_device_path, - bootefi_image_path, image_objp, + ret = bootefi_run_prepare(load_options_path, test_device_path, + test_image_path, image_objp, loaded_image_infop); if (ret == EFI_SUCCESS) return ret; failure: + efi_free_pool(test_device_path); + efi_free_pool(test_image_path); + /* TODO: not sure calling clear function is necessary */ efi_clear_bootdev(); return ret; } @@ -638,6 +109,8 @@ static int do_efi_selftest(void) ret = EFI_CALL(efi_selftest(&image_obj->header, &systab)); efi_restore_gd(); free(loaded_image_info->load_options); + efi_free_pool(test_device_path); + efi_free_pool(test_image_path); if (ret != EFI_SUCCESS) efi_delete_handle(&image_obj->header); else @@ -645,7 +118,6 @@ static int do_efi_selftest(void) return ret != EFI_SUCCESS; } -#endif /* CONFIG_CMD_BOOTEFI_SELFTEST */ /** * do_bootefi() - execute `bootefi` command @@ -660,20 +132,15 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { efi_status_t ret; - char *img_addr, *img_size, *str_copy, *pos; - void *fdt; + char *p; + void *fdt, *image_buf; + unsigned long addr, size; + void *image_addr; + size_t image_size; if (argc < 2) return CMD_RET_USAGE; - /* Initialize EFI drivers */ - ret = efi_init_obj_list(); - if (ret != EFI_SUCCESS) { - log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n", - ret & ~EFI_ERROR_MASK); - return CMD_RET_FAILURE; - } - if (argc > 2) { uintptr_t fdt_addr; @@ -682,32 +149,75 @@ static int do_bootefi(struct cmd_tbl *cmdtp, int flag, int argc, } else { fdt = EFI_FDT_USE_INTERNAL; } - ret = efi_install_fdt(fdt); - if (ret == EFI_INVALID_PARAMETER) - return CMD_RET_USAGE; - else if (ret != EFI_SUCCESS) - return CMD_RET_FAILURE; - if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { - if (!strcmp(argv[1], "bootmgr")) - return do_efibootmgr(); + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR) && + !strcmp(argv[1], "bootmgr")) { + ret = efi_bootmgr_run(fdt); + + if (ret != EFI_SUCCESS) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; } -#ifdef CONFIG_CMD_BOOTEFI_SELFTEST - if (!strcmp(argv[1], "selftest")) + + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_SELFTEST) && + !strcmp(argv[1], "selftest")) { + /* Initialize EFI drivers */ + ret = efi_init_obj_list(); + if (ret != EFI_SUCCESS) { + log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n", + ret & ~EFI_ERROR_MASK); + return CMD_RET_FAILURE; + } + + ret = efi_install_fdt(fdt); + if (ret != EFI_SUCCESS) + return CMD_RET_FAILURE; + return do_efi_selftest(); -#endif - str_copy = strdup(argv[1]); - if (!str_copy) { - log_err("Out of memory\n"); - return CMD_RET_FAILURE; } - pos = str_copy; - img_addr = strsep(&pos, ":"); - img_size = strsep(&pos, ":"); - ret = do_bootefi_image(img_addr, img_size); - free(str_copy); - return ret; + if (!IS_ENABLED(CONFIG_CMD_BOOTEFI_BINARY)) + return CMD_RET_SUCCESS; + + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_HELLO) && + !strcmp(argv[1], "hello")) { + image_buf = __efi_helloworld_begin; + size = __efi_helloworld_end - __efi_helloworld_begin; + /* TODO: not sure calling clear function is necessary */ + efi_clear_bootdev(); + } else { + addr = strtoul(argv[1], NULL, 16); + /* Check that a numeric value was passed */ + if (!addr) + return CMD_RET_USAGE; + image_buf = map_sysmem(addr, 0); + + p = strchr(argv[1], ':'); + if (p) { + size = strtoul(++p, NULL, 16); + if (!size) + return CMD_RET_USAGE; + efi_clear_bootdev(); + } else { + /* Image should be already loaded */ + efi_get_image_parameters(&image_addr, &image_size); + + if (image_buf != image_addr) { + log_err("No UEFI binary known at %s\n", + argv[1]); + return CMD_RET_FAILURE; + } + size = image_size; + } + } + + ret = efi_binary_run(image_buf, size, fdt); + + if (ret != EFI_SUCCESS) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; } U_BOOT_LONGHELP(bootefi, diff --git a/cmd/bootflow.c b/cmd/bootflow.c index 3aeb40d..be5d7d8 100644 --- a/cmd/bootflow.c +++ b/cmd/bootflow.c @@ -135,7 +135,7 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc, struct udevice *dev = NULL; struct bootflow bflow; bool all = false, boot = false, errors = false, no_global = false; - bool list = false, no_hunter = false; + bool list = false, no_hunter = false, menu = false, text_mode = false; int num_valid = 0; const char *label = NULL; bool has_args; @@ -155,6 +155,8 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc, no_global = strchr(argv[1], 'G'); list = strchr(argv[1], 'l'); no_hunter = strchr(argv[1], 'H'); + menu = strchr(argv[1], 'm'); + text_mode = strchr(argv[1], 't'); argc--; argv++; } @@ -213,15 +215,32 @@ static int do_bootflow_scan(struct cmd_tbl *cmdtp, int flag, int argc, } if (list) show_bootflow(i, &bflow, errors); - if (boot && !bflow.err) + if (!menu && boot && !bflow.err) bootflow_run_boot(&iter, &bflow); } bootflow_iter_uninit(&iter); if (list) show_footer(i, num_valid); - if (IS_ENABLED(CONFIG_CMD_BOOTFLOW_FULL) && !num_valid && !list) - printf("No bootflows found; try again with -l\n"); + if (IS_ENABLED(CONFIG_CMD_BOOTFLOW_FULL) && IS_ENABLED(CONFIG_EXPO)) { + if (!num_valid && !list) { + printf("No bootflows found; try again with -l\n"); + } else if (menu) { + struct bootflow *sel_bflow; + + ret = bootflow_handle_menu(std, text_mode, &sel_bflow); + if (!ret && boot) { + ret = console_clear(); + if (ret) { + log_err("Failed to clear console: %dE\n", + ret); + return ret; + } + + bootflow_run_boot(NULL, sel_bflow); + } + } + } return 0; } @@ -524,9 +543,7 @@ static int do_bootflow_cmdline(struct cmd_tbl *cmdtp, int flag, int argc, op = argv[1]; arg = argv[2]; if (*op == 's') { - if (argc < 4) - return CMD_RET_USAGE; - val = argv[3]; + val = argv[3] ?: (const char *)BOOTFLOWCL_EMPTY; } switch (*op) { diff --git a/cmd/booti.c b/cmd/booti.c index 41d40c9..898df0f 100644 --- a/cmd/booti.c +++ b/cmd/booti.c @@ -20,9 +20,9 @@ DECLARE_GLOBAL_DATA_PTR; /* * Image booting support */ -static int booti_start(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], struct bootm_headers *images) +static int booti_start(struct bootm_info *bmi) { + struct bootm_headers *images = bmi->images; int ret; ulong ld; ulong relocated_addr; @@ -34,16 +34,15 @@ static int booti_start(struct cmd_tbl *cmdtp, int flag, int argc, unsigned long decomp_len; int ctype; - ret = do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START, - images, 1); + ret = bootm_run_states(bmi, BOOTM_STATE_START); /* Setup Linux kernel Image entry point */ - if (!argc) { + if (!bmi->addr_img) { ld = image_load_addr; debug("* kernel: default image load address = 0x%08lx\n", image_load_addr); } else { - ld = hextoul(argv[0], NULL); + ld = hextoul(bmi->addr_img, NULL); debug("* kernel: cmdline image address = 0x%08lx\n", ld); } @@ -95,9 +94,8 @@ static int booti_start(struct cmd_tbl *cmdtp, int flag, int argc, * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not * have a header that provide this informaiton. */ - if (bootm_find_images(image_load_addr, cmd_arg1(argc, argv), - cmd_arg2(argc, argv), relocated_addr, - image_size)) + if (bootm_find_images(image_load_addr, bmi->conf_ramdisk, bmi->conf_fdt, + relocated_addr, image_size)) return 1; return 0; @@ -105,12 +103,25 @@ static int booti_start(struct cmd_tbl *cmdtp, int flag, int argc, int do_booti(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + struct bootm_info bmi; + int states; int ret; /* Consume 'booti' */ argc--; argv++; - if (booti_start(cmdtp, flag, argc, argv, &images)) + bootm_init(&bmi); + if (argc) + bmi.addr_img = argv[0]; + if (argc > 1) + bmi.conf_ramdisk = argv[1]; + if (argc > 2) + bmi.conf_fdt = argv[2]; + bmi.boot_progress = true; + bmi.cmd_name = "booti"; + /* do not set up argc and argv[] since nothing uses them */ + + if (booti_start(&bmi)) return 1; /* @@ -120,19 +131,17 @@ int do_booti(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) bootm_disable_interrupts(); images.os.os = IH_OS_LINUX; -#ifdef CONFIG_RISCV_SMODE - images.os.arch = IH_ARCH_RISCV; -#elif CONFIG_ARM64 - images.os.arch = IH_ARCH_ARM64; -#endif - ret = do_bootm_states(cmdtp, flag, argc, argv, -#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH - BOOTM_STATE_RAMDISK | -#endif - BOOTM_STATE_MEASURE | - BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO | - BOOTM_STATE_OS_GO, - &images, 1); + if (IS_ENABLED(CONFIG_RISCV_SMODE)) + images.os.arch = IH_ARCH_RISCV; + else if (IS_ENABLED(CONFIG_ARM64)) + images.os.arch = IH_ARCH_ARM64; + + states = BOOTM_STATE_MEASURE | BOOTM_STATE_OS_PREP | + BOOTM_STATE_OS_FAKE_GO | BOOTM_STATE_OS_GO; + if (IS_ENABLED(CONFIG_SYS_BOOT_RAMDISK_HIGH)) + states |= BOOTM_STATE_RAMDISK; + + ret = bootm_run_states(&bmi, states); return ret; } diff --git a/cmd/bootm.c b/cmd/bootm.c index 6ded091..9737a2d 100644 --- a/cmd/bootm.c +++ b/cmd/bootm.c @@ -76,6 +76,7 @@ static ulong bootm_get_addr(int argc, char *const argv[]) static int do_bootm_subcommand(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + struct bootm_info bmi; int ret = 0; long state; struct cmd_tbl *c; @@ -103,7 +104,21 @@ static int do_bootm_subcommand(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_USAGE; } - ret = do_bootm_states(cmdtp, flag, argc, argv, state, &images, 0); + bootm_init(&bmi); + if (argc) + bmi.addr_img = argv[0]; + if (argc > 1) + bmi.conf_ramdisk = argv[1]; + if (argc > 2) + bmi.conf_fdt = argv[2]; + bmi.cmd_name = "bootm"; + bmi.boot_progress = false; + + /* set up argc and argv[] since some OSes use them */ + bmi.argc = argc; + bmi.argv = argv; + + ret = bootm_run_states(&bmi, state); #if defined(CONFIG_CMD_BOOTM_PRE_LOAD) if (!ret && (state & BOOTM_STATE_PRE_LOAD)) @@ -120,7 +135,7 @@ static int do_bootm_subcommand(struct cmd_tbl *cmdtp, int flag, int argc, int do_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - int states; + struct bootm_info bmi; int ret; /* determine if we have a sub command */ @@ -141,17 +156,19 @@ int do_bootm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) return do_bootm_subcommand(cmdtp, flag, argc, argv); } - states = BOOTM_STATE_START | BOOTM_STATE_FINDOS | BOOTM_STATE_PRE_LOAD | - BOOTM_STATE_FINDOTHER | BOOTM_STATE_LOADOS | - BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO | - BOOTM_STATE_OS_GO; - if (IS_ENABLED(CONFIG_SYS_BOOT_RAMDISK_HIGH)) - states |= BOOTM_STATE_RAMDISK; - if (IS_ENABLED(CONFIG_MEASURED_BOOT)) - states |= BOOTM_STATE_MEASURE; - if (IS_ENABLED(CONFIG_PPC) || IS_ENABLED(CONFIG_MIPS)) - states |= BOOTM_STATE_OS_CMDLINE; - ret = do_bootm_states(cmdtp, flag, argc, argv, states, &images, 1); + bootm_init(&bmi); + if (argc) + bmi.addr_img = argv[0]; + if (argc > 1) + bmi.conf_ramdisk = argv[1]; + if (argc > 2) + bmi.conf_fdt = argv[2]; + + /* set up argc and argv[] since some OSes use them */ + bmi.argc = argc; + bmi.argv = argv; + + ret = bootm_run(&bmi); return ret ? CMD_RET_FAILURE : 0; } diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 987b168..78184fc 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -119,7 +119,7 @@ static char *bootmenu_choice_entry(void *data) iter = iter->next; return iter->key; case BKEY_QUIT: - /* Quit by choosing the last entry - U-Boot console */ + /* Quit by choosing the last entry */ iter = menu->first; while (iter->next) iter = iter->next; @@ -361,15 +361,15 @@ static struct bootmenu_data *bootmenu_create(int delay) } #endif - /* Add U-Boot console entry at the end */ + /* Add Exit entry at the end */ if (i <= MAX_COUNT - 1) { entry = malloc(sizeof(struct bootmenu_entry)); if (!entry) goto cleanup; - /* Add Quit entry if entering U-Boot console is disabled */ + /* Add Quit entry if exiting bootmenu is disabled */ if (!IS_ENABLED(CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE)) - entry->title = strdup("U-Boot console"); + entry->title = strdup("Exit"); else entry->title = strdup("Quit"); @@ -532,7 +532,7 @@ static enum bootmenu_ret bootmenu_show(int delay) title = strdup(iter->title); command = strdup(iter->command); - /* last entry is U-Boot console or Quit */ + /* last entry exits bootmenu */ if (iter->num == iter->menu->count - 1) { ret = BOOTMENU_RET_QUIT; goto cleanup; diff --git a/cmd/bootz.c b/cmd/bootz.c index a652879..b6bb4aa 100644 --- a/cmd/bootz.c +++ b/cmd/bootz.c @@ -27,11 +27,20 @@ int __weak bootz_setup(ulong image, ulong *start, ulong *end) static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[], struct bootm_headers *images) { - int ret; ulong zi_start, zi_end; + struct bootm_info bmi; + int ret; + + bootm_init(&bmi); + if (argc) + bmi.addr_img = argv[0]; + if (argc > 1) + bmi.conf_ramdisk = argv[1]; + if (argc > 2) + bmi.conf_fdt = argv[2]; + /* do not set up argc and argv[] since nothing uses them */ - ret = do_bootm_states(cmdtp, flag, argc, argv, BOOTM_STATE_START, - images, 1); + ret = bootm_run_states(&bmi, BOOTM_STATE_START); /* Setup Linux kernel zImage entry point */ if (!argc) { @@ -64,6 +73,7 @@ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc, int do_bootz(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + struct bootm_info bmi; int ret; /* Consume 'bootz' */ @@ -79,14 +89,17 @@ int do_bootz(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) bootm_disable_interrupts(); images.os.os = IH_OS_LINUX; - ret = do_bootm_states(cmdtp, flag, argc, argv, -#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH - BOOTM_STATE_RAMDISK | -#endif - BOOTM_STATE_MEASURE | - BOOTM_STATE_OS_PREP | BOOTM_STATE_OS_FAKE_GO | - BOOTM_STATE_OS_GO, - &images, 1); + + bootm_init(&bmi); + if (argc) + bmi.addr_img = argv[0]; + if (argc > 1) + bmi.conf_ramdisk = argv[1]; + if (argc > 2) + bmi.conf_fdt = argv[2]; + bmi.cmd_name = "bootz"; + + ret = bootz_run(&bmi); return ret; } diff --git a/cmd/cli.c b/cmd/cli.c new file mode 100644 index 0000000..be3bf7d --- /dev/null +++ b/cmd/cli.c @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include <cli.h> +#include <command.h> +#include <string.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const char *gd_flags_to_parser_name(void) +{ + if (gd->flags & GD_FLG_HUSH_OLD_PARSER) + return "old"; + if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) + return "modern"; + return NULL; +} + +static int do_cli_get(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + const char *current = gd_flags_to_parser_name(); + + if (!current) { + printf("current cli value is not valid, this should not happen!\n"); + return CMD_RET_FAILURE; + } + + printf("%s\n", current); + + return CMD_RET_SUCCESS; +} + +static int parser_string_to_gd_flags(const char *parser) +{ + if (!strcmp(parser, "old")) + return GD_FLG_HUSH_OLD_PARSER; + if (!strcmp(parser, "modern")) + return GD_FLG_HUSH_MODERN_PARSER; + return -1; +} + +static int gd_flags_to_parser_config(int flag) +{ + if (gd->flags & GD_FLG_HUSH_OLD_PARSER) + return CONFIG_VAL(HUSH_OLD_PARSER); + if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) + return CONFIG_VAL(HUSH_MODERN_PARSER); + return -1; +} + +static void reset_parser_gd_flags(void) +{ + gd->flags &= ~GD_FLG_HUSH_OLD_PARSER; + gd->flags &= ~GD_FLG_HUSH_MODERN_PARSER; +} + +static int do_cli_set(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + char *parser_name; + int parser_config; + int parser_flag; + + if (argc < 2) + return CMD_RET_USAGE; + + parser_name = argv[1]; + + parser_flag = parser_string_to_gd_flags(parser_name); + if (parser_flag == -1) { + printf("Bad value for parser name: %s\n", parser_name); + return CMD_RET_USAGE; + } + + parser_config = gd_flags_to_parser_config(parser_flag); + switch (parser_config) { + case -1: + printf("Bad value for parser flags: %d\n", parser_flag); + return CMD_RET_FAILURE; + case 0: + printf("Want to set current parser to %s, but its code was not compiled!\n", + parser_name); + return CMD_RET_FAILURE; + } + + reset_parser_gd_flags(); + gd->flags |= parser_flag; + + cli_init(); + cli_loop(); + + /* cli_loop() should never return. */ + return CMD_RET_FAILURE; +} + +static struct cmd_tbl parser_sub[] = { + U_BOOT_CMD_MKENT(get, 1, 1, do_cli_get, "", ""), + U_BOOT_CMD_MKENT(set, 2, 1, do_cli_set, "", ""), +}; + +static int do_cli(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct cmd_tbl *cp; + + if (argc < 2) + return CMD_RET_USAGE; + + /* drop initial "parser" arg */ + argc--; + argv++; + + cp = find_cmd_tbl(argv[0], parser_sub, ARRAY_SIZE(parser_sub)); + if (cp) + return cp->cmd(cmdtp, flag, argc, argv); + + return CMD_RET_USAGE; +} + +#if CONFIG_IS_ENABLED(SYS_LONGHELP) +static char cli_help_text[] = + "get - print current cli\n" + "set - set the current cli, possible value are: old, modern" + ; +#endif + +U_BOOT_CMD(cli, 3, 1, do_cli, + "cli", +#if CONFIG_IS_ENABLED(SYS_LONGHELP) + cli_help_text +#endif +); @@ -59,9 +59,10 @@ static void show_clks(struct udevice *dev, int depth, int last_flag) } } -int __weak soc_clk_dump(void) +static int soc_clk_dump(void) { struct udevice *dev; + const struct clk_ops *ops; printf(" Rate Usecnt Name\n"); printf("------------------------------------------\n"); @@ -69,10 +70,18 @@ int __weak soc_clk_dump(void) uclass_foreach_dev_probe(UCLASS_CLK, dev) show_clks(dev, -1, 0); + uclass_foreach_dev_probe(UCLASS_CLK, dev) { + ops = dev_get_driver_ops(dev); + if (ops && ops->dump) { + printf("\n%s %s:\n", dev->driver->name, dev->name); + ops->dump(dev); + } + } + return 0; } #else -int __weak soc_clk_dump(void) +static int soc_clk_dump(void) { puts("Not implemented\n"); return 1; diff --git a/cmd/efi_common.c b/cmd/efi_common.c index f405609..1aa2351 100644 --- a/cmd/efi_common.c +++ b/cmd/efi_common.c @@ -17,10 +17,8 @@ void efi_show_tables(struct efi_system_table *systab) for (i = 0; i < systab->nr_tables; i++) { struct efi_configuration_table *tab = &systab->tables[i]; - char guid_str[37]; - uuid_bin_to_str(tab->guid.b, guid_str, 1); - printf("%p %pUl %s\n", tab->table, guid_str, + printf("%p %pUl %s\n", tab->table, tab->guid.b, uuid_guid_get_str(tab->guid.b) ?: "(unknown)"); } } diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index 34a59cb..8234e60 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -531,7 +531,7 @@ struct efi_device_path *eficonfig_create_device_path(struct efi_device_path *dp_ dp = efi_dp_shorten(dp_volume); if (!dp) dp = dp_volume; - dp = efi_dp_append(dp, &fp->dp); + dp = efi_dp_concat(dp, &fp->dp, false); free(buf); return dp; @@ -1484,7 +1484,8 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo ret = EFI_OUT_OF_RESOURCES; goto out; } - initrd_dp = efi_dp_append((const struct efi_device_path *)&id_dp, dp); + initrd_dp = efi_dp_concat((const struct efi_device_path *)&id_dp, + dp, false); efi_free_pool(dp); } @@ -1495,7 +1496,7 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo } final_dp_size = efi_dp_size(dp) + sizeof(END); if (initrd_dp) { - final_dp = efi_dp_concat(dp, initrd_dp); + final_dp = efi_dp_concat(dp, initrd_dp, true); final_dp_size += efi_dp_size(initrd_dp) + sizeof(END); } else { final_dp = efi_dp_dup(dp); diff --git a/cmd/efidebug.c b/cmd/efidebug.c index 78ef16f..a587860 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -173,15 +173,12 @@ EFI_ESRT_UPDATE_STATUS_NUM > (idx) ? efi_update_status_str[(idx)] : "error"\ static int do_efi_capsule_esrt(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) { - struct efi_system_resource_table *esrt = NULL; + struct efi_system_resource_table *esrt; if (argc != 1) return CMD_RET_USAGE; - for (int idx = 0; idx < systab.nr_tables; idx++) - if (!guidcmp(&efi_esrt_guid, &systab.tables[idx].guid)) - esrt = (struct efi_system_resource_table *)systab.tables[idx].table; - + esrt = efi_get_configuration_table(&efi_esrt_guid); if (!esrt) { log_info("ESRT: table not present\n"); return CMD_RET_SUCCESS; @@ -699,8 +696,8 @@ struct efi_device_path *create_initrd_dp(const char *dev, const char *part, if (!short_fp) short_fp = tmp_fp; - initrd_dp = efi_dp_append((const struct efi_device_path *)&id_dp, - short_fp); + initrd_dp = efi_dp_concat((const struct efi_device_path *)&id_dp, + short_fp, false); out: efi_free_pool(tmp_dp); @@ -754,6 +751,10 @@ static int efi_boot_add_uri(int argc, char *const argv[], u16 *var_name16, uridp_len = sizeof(struct efi_device_path) + strlen(argv[3]) + 1; uridp = efi_alloc(uridp_len + sizeof(END)); + if (!uridp) { + log_err("Out of memory\n"); + return CMD_RET_FAILURE; + } uridp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; uridp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_URI; uridp->dp.length = uridp_len; @@ -916,7 +917,7 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag, goto out; } - final_fp = efi_dp_concat(file_path, initrd_dp); + final_fp = efi_dp_concat(file_path, initrd_dp, true); if (!final_fp) { printf("Cannot create final device path\n"); r = CMD_RET_FAILURE; @@ -1410,7 +1411,7 @@ static __maybe_unused int do_efi_test_bootmgr(struct cmd_tbl *cmdtp, int flag, } static struct cmd_tbl cmd_efidebug_test_sub[] = { -#ifdef CONFIG_CMD_BOOTEFI_BOOTMGR +#ifdef CONFIG_EFI_BOOTMGR U_BOOT_CMD_MKENT(bootmgr, CONFIG_SYS_MAXARGS, 1, do_efi_test_bootmgr, "", ""), #endif @@ -1604,7 +1605,7 @@ U_BOOT_LONGHELP(efidebug, " - show UEFI memory map\n" "efidebug tables\n" " - show UEFI configuration tables\n" -#ifdef CONFIG_CMD_BOOTEFI_BOOTMGR +#ifdef CONFIG_EFI_BOOTMGR "efidebug test bootmgr\n" " - run simple bootmgr for test\n" #endif @@ -38,6 +38,10 @@ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]), /* Interpreter command to boot an arbitrary ELF image from memory */ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { +#if CONFIG_IS_ENABLED(CMD_ELF_FDT_SETUP) + struct bootm_headers img = {0}; + unsigned long fdt_addr = 0; /* Address of the FDT */ +#endif unsigned long addr; /* Address of the ELF image */ unsigned long rc; /* Return value from user code */ char *sload = NULL; @@ -46,13 +50,25 @@ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) /* Consume 'bootelf' */ argc--; argv++; - /* Check for flag. */ + /* Check for [-p|-s] flag. */ if (argc >= 1 && (argv[0][0] == '-' && \ (argv[0][1] == 'p' || argv[0][1] == 's'))) { sload = argv[0]; /* Consume flag. */ argc--; argv++; } + +#if CONFIG_IS_ENABLED(CMD_ELF_FDT_SETUP) + /* Check for [-d fdt_addr_r] option. */ + if ((argc >= 2) && (argv[0][0] == '-') && (argv[0][1] == 'd')) { + if (strict_strtoul(argv[1], 16, &fdt_addr) != 0) + return CMD_RET_USAGE; + /* Consume option. */ + argc -= 2; + argv += 2; + } +#endif + /* Check for address. */ if (argc >= 1 && strict_strtoul(argv[0], 16, &addr) != -EINVAL) { /* Consume address */ @@ -68,6 +84,16 @@ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) else addr = load_elf_image_shdr(addr); +#if CONFIG_IS_ENABLED(CMD_ELF_FDT_SETUP) + if (fdt_addr) { + printf("## Setting up FDT at 0x%08lx ...\n", fdt_addr); + flush(); + + if (image_setup_libfdt(&img, (void *)fdt_addr, NULL)) + return 1; + } +#endif + if (!env_get_autostart()) return rcode; @@ -298,9 +324,16 @@ int do_bootvx(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) U_BOOT_CMD( bootelf, CONFIG_SYS_MAXARGS, 0, do_bootelf, "Boot from an ELF image in memory", - "[-p|-s] [address]\n" + "[-p|-s] " +#if CONFIG_IS_ENABLED(CMD_ELF_FDT_SETUP) + "[-d fdt_addr_r] " +#endif + "[address]\n" "\t- load ELF image at [address] via program headers (-p)\n" - "\t or via section headers (-s)" + "\t or via section headers (-s)\n" +#if CONFIG_IS_ENABLED(CMD_ELF_FDT_SETUP) + "\t- setup FDT image at [fdt_addr_r] (-d)" +#endif ); U_BOOT_CMD( @@ -14,15 +14,22 @@ #include <hash.h> #include <linux/ctype.h> +#if IS_ENABLED(CONFIG_HASH_VERIFY) +#define HARGS 6 +#else +#define HARGS 5 +#endif + static int do_hash(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { char *s; int flags = HASH_FLAG_ENV; -#ifdef CONFIG_HASH_VERIFY - if (argc < 4) + if (argc < (HARGS - 1)) return CMD_RET_USAGE; + +#if IS_ENABLED(CONFIG_HASH_VERIFY) if (!strcmp(argv[1], "-v")) { flags |= HASH_FLAG_VERIFY; argc--; @@ -37,18 +44,12 @@ static int do_hash(struct cmd_tbl *cmdtp, int flag, int argc, return hash_command(*argv, flags, cmdtp, flag, argc - 1, argv + 1); } -#ifdef CONFIG_HASH_VERIFY -#define HARGS 6 -#else -#define HARGS 5 -#endif - U_BOOT_CMD( hash, HARGS, 1, do_hash, "compute hash message digest", "algorithm address count [[*]hash_dest]\n" " - compute message digest [save to env var / *address]" -#ifdef CONFIG_HASH_VERIFY +#if IS_ENABLED(CONFIG_HASH_VERIFY) "\nhash -v algorithm address count [*]hash\n" " - verify message digest of memory area to immediate value, \n" " env var or *address" @@ -230,7 +230,7 @@ static ulong load_serial(long offset) static int read_record(char *buf, ulong len) { char *p; - char c; + int c; --len; /* always leave room for terminating '\0' byte */ @@ -827,7 +827,7 @@ static void handle_send_packet(int n) /* k_recv receives a OS Open image file over kermit line */ static int k_recv(void) { - char new_char; + int new_char; char k_state, k_state_saved; int sum; int done; diff --git a/cmd/md5sum.c b/cmd/md5sum.c index 0f0e1d3..ded3f9e 100644 --- a/cmd/md5sum.c +++ b/cmd/md5sum.c @@ -7,166 +7,36 @@ * Wolfgang Denk, DENX Software Engineering, wd@denx.de. */ -#include <common.h> #include <command.h> #include <env.h> #include <image.h> +#include <hash.h> #include <mapmem.h> #include <u-boot/md5.h> #include <asm/io.h> -/* - * Store the resulting sum to an address or variable - */ -static void store_result(const u8 *sum, const char *dest) -{ - unsigned int i; - - if (*dest == '*') { - u8 *ptr; - - ptr = (u8 *)hextoul(dest + 1, NULL); - for (i = 0; i < 16; i++) - *ptr++ = sum[i]; - } else { - char str_output[33]; - char *str_ptr = str_output; - - for (i = 0; i < 16; i++) { - sprintf(str_ptr, "%02x", sum[i]); - str_ptr += 2; - } - env_set(dest, str_output); - } -} - -#ifdef CONFIG_MD5SUM_VERIFY -static int parse_verify_sum(char *verify_str, u8 *vsum) -{ - if (*verify_str == '*') { - u8 *ptr; - - ptr = (u8 *)hextoul(verify_str + 1, NULL); - memcpy(vsum, ptr, 16); - } else { - unsigned int i; - char *vsum_str; - - if (strlen(verify_str) == 32) - vsum_str = verify_str; - else { - vsum_str = env_get(verify_str); - if (vsum_str == NULL || strlen(vsum_str) != 32) - return 1; - } - - for (i = 0; i < 16; i++) { - char *nullp = vsum_str + (i + 1) * 2; - char end = *nullp; - - *nullp = '\0'; - *(u8 *)(vsum + i) = - hextoul(vsum_str + (i * 2), NULL); - *nullp = end; - } - } - return 0; -} - -int do_md5sum(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +static int do_md5sum(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) { - ulong addr, len; - unsigned int i; - u8 output[16]; - u8 vsum[16]; - int verify = 0; + int flags = HASH_FLAG_ENV; int ac; - char * const *av; - void *buf; + char *const *av; if (argc < 3) return CMD_RET_USAGE; av = argv + 1; ac = argc - 1; - if (strcmp(*av, "-v") == 0) { - verify = 1; + if (IS_ENABLED(CONFIG_MD5SUM_VERIFY) && strcmp(*av, "-v") == 0) { + flags |= HASH_FLAG_VERIFY; av++; ac--; - if (ac < 3) - return CMD_RET_USAGE; } - addr = hextoul(*av++, NULL); - len = hextoul(*av++, NULL); - - buf = map_sysmem(addr, len); - md5_wd(buf, len, output, CHUNKSZ_MD5); - unmap_sysmem(buf); - - if (!verify) { - printf("md5 for %08lx ... %08lx ==> ", addr, addr + len - 1); - for (i = 0; i < 16; i++) - printf("%02x", output[i]); - printf("\n"); - - if (ac > 2) - store_result(output, *av); - } else { - char *verify_str = *av++; - - if (parse_verify_sum(verify_str, vsum)) { - printf("ERROR: %s does not contain a valid md5 sum\n", - verify_str); - return 1; - } - if (memcmp(output, vsum, 16) != 0) { - printf("md5 for %08lx ... %08lx ==> ", addr, - addr + len - 1); - for (i = 0; i < 16; i++) - printf("%02x", output[i]); - printf(" != "); - for (i = 0; i < 16; i++) - printf("%02x", vsum[i]); - printf(" ** ERROR **\n"); - return 1; - } - } - - return 0; -} -#else -static int do_md5sum(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) -{ - unsigned long addr, len; - unsigned int i; - u8 output[16]; - void *buf; - - if (argc < 3) - return CMD_RET_USAGE; - - addr = hextoul(argv[1], NULL); - len = hextoul(argv[2], NULL); - - buf = map_sysmem(addr, len); - md5_wd(buf, len, output, CHUNKSZ_MD5); - unmap_sysmem(buf); - - printf("md5 for %08lx ... %08lx ==> ", addr, addr + len - 1); - for (i = 0; i < 16; i++) - printf("%02x", output[i]); - printf("\n"); - - if (argc > 3) - store_result(output, argv[3]); - - return 0; + return hash_command("md5", flags, cmdtp, flag, ac, av); } -#endif -#ifdef CONFIG_MD5SUM_VERIFY +#if IS_ENABLED(CONFIG_MD5SUM_VERIFY) U_BOOT_CMD( md5sum, 5, 1, do_md5sum, "compute MD5 message digest", @@ -182,4 +52,4 @@ U_BOOT_CMD( "address count [[*]sum]\n" " - compute MD5 message digest [save to sum]" ); -#endif +#endif /* IS_ENABLED(CONFIG_MD5SUM_VERIFY) */ @@ -35,11 +35,9 @@ DECLARE_GLOBAL_DATA_PTR; /* Create a compile-time value */ -#ifdef MEM_SUPPORT_64BIT_DATA -#define SUPPORT_64BIT_DATA 1 +#if MEM_SUPPORT_64BIT_DATA #define HELP_Q ", .q" #else -#define SUPPORT_64BIT_DATA 0 #define HELP_Q "" #endif @@ -131,7 +129,7 @@ static int do_mem_nm(struct cmd_tbl *cmdtp, int flag, int argc, static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - ulong writeval; /* 64-bit if SUPPORT_64BIT_DATA */ + ulong writeval; /* 64-bit if MEM_SUPPORT_64BIT_DATA */ ulong addr, count; int size; void *buf, *start; @@ -152,7 +150,7 @@ static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc, /* Get the value to write. */ - if (SUPPORT_64BIT_DATA) + if (MEM_SUPPORT_64BIT_DATA) writeval = simple_strtoull(argv[2], NULL, 16); else writeval = hextoul(argv[2], NULL); @@ -170,7 +168,7 @@ static int do_mem_mw(struct cmd_tbl *cmdtp, int flag, int argc, while (count-- > 0) { if (size == 4) *((u32 *)buf) = (u32)writeval; - else if (SUPPORT_64BIT_DATA && size == 8) + else if (MEM_SUPPORT_64BIT_DATA && size == 8) *((ulong *)buf) = writeval; else if (size == 2) *((u16 *)buf) = (u16)writeval; @@ -248,7 +246,7 @@ static int do_mem_cmp(struct cmd_tbl *cmdtp, int flag, int argc, int rcode = 0; const char *type; const void *buf1, *buf2, *base; - ulong word1, word2; /* 64-bit if SUPPORT_64BIT_DATA */ + ulong word1, word2; /* 64-bit if MEM_SUPPORT_64BIT_DATA */ if (argc != 4) return CMD_RET_USAGE; @@ -276,7 +274,7 @@ static int do_mem_cmp(struct cmd_tbl *cmdtp, int flag, int argc, if (size == 4) { word1 = *(u32 *)buf1; word2 = *(u32 *)buf2; - } else if (SUPPORT_64BIT_DATA && size == 8) { + } else if (MEM_SUPPORT_64BIT_DATA && size == 8) { word1 = *(ulong *)buf1; word2 = *(ulong *)buf2; } else if (size == 2) { @@ -361,7 +359,7 @@ static int do_mem_cp(struct cmd_tbl *cmdtp, int flag, int argc, } #endif - memcpy(dst, src, count * size); + memmove(dst, src, count * size); unmap_sysmem(src); unmap_sysmem(dst); @@ -528,7 +526,7 @@ static int do_mem_loop(struct cmd_tbl *cmdtp, int flag, int argc, { ulong addr, length, i, bytes; int size; - volatile ulong *llp; /* 64-bit if SUPPORT_64BIT_DATA */ + volatile ulong *llp; /* 64-bit if MEM_SUPPORT_64BIT_DATA */ volatile u32 *longp; volatile u16 *shortp; volatile u8 *cp; @@ -559,7 +557,7 @@ static int do_mem_loop(struct cmd_tbl *cmdtp, int flag, int argc, * If we have only one object, just run infinite loops. */ if (length == 1) { - if (SUPPORT_64BIT_DATA && size == 8) { + if (MEM_SUPPORT_64BIT_DATA && size == 8) { llp = (ulong *)buf; for (;;) i = *llp; @@ -579,7 +577,7 @@ static int do_mem_loop(struct cmd_tbl *cmdtp, int flag, int argc, i = *cp; } - if (SUPPORT_64BIT_DATA && size == 8) { + if (MEM_SUPPORT_64BIT_DATA && size == 8) { for (;;) { llp = (ulong *)buf; i = length; @@ -620,8 +618,8 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc, { ulong addr, length, i, bytes; int size; - volatile ulong *llp; /* 64-bit if SUPPORT_64BIT_DATA */ - ulong data; /* 64-bit if SUPPORT_64BIT_DATA */ + volatile ulong *llp; /* 64-bit if MEM_SUPPORT_64BIT_DATA */ + ulong data; /* 64-bit if MEM_SUPPORT_64BIT_DATA */ volatile u32 *longp; volatile u16 *shortp; volatile u8 *cp; @@ -646,7 +644,7 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc, length = hextoul(argv[2], NULL); /* data to write */ - if (SUPPORT_64BIT_DATA) + if (MEM_SUPPORT_64BIT_DATA) data = simple_strtoull(argv[3], NULL, 16); else data = hextoul(argv[3], NULL); @@ -658,7 +656,7 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc, * If we have only one object, just run infinite loops. */ if (length == 1) { - if (SUPPORT_64BIT_DATA && size == 8) { + if (MEM_SUPPORT_64BIT_DATA && size == 8) { llp = (ulong *)buf; for (;;) *llp = data; @@ -678,7 +676,7 @@ static int do_mem_loopw(struct cmd_tbl *cmdtp, int flag, int argc, *cp = data; } - if (SUPPORT_64BIT_DATA && size == 8) { + if (MEM_SUPPORT_64BIT_DATA && size == 8) { for (;;) { llp = (ulong *)buf; i = length; @@ -1151,7 +1149,7 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, char *const argv[]) { ulong addr; - ulong i; /* 64-bit if SUPPORT_64BIT_DATA */ + ulong i; /* 64-bit if MEM_SUPPORT_64BIT_DATA */ int nbytes, size; void *ptr = NULL; @@ -1186,7 +1184,7 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, printf("%08lx:", addr); if (size == 4) printf(" %08x", *((u32 *)ptr)); - else if (SUPPORT_64BIT_DATA && size == 8) + else if (MEM_SUPPORT_64BIT_DATA && size == 8) printf(" %0lx", *((ulong *)ptr)); else if (size == 2) printf(" %04x", *((u16 *)ptr)); @@ -1211,7 +1209,7 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, #endif else { char *endp; - if (SUPPORT_64BIT_DATA) + if (MEM_SUPPORT_64BIT_DATA) i = simple_strtoull(console_buffer, &endp, 16); else i = hextoul(console_buffer, &endp); @@ -1222,7 +1220,7 @@ mod_mem(struct cmd_tbl *cmdtp, int incrflag, int flag, int argc, bootretry_reset_cmd_timeout(); if (size == 4) *((u32 *)ptr) = i; - else if (SUPPORT_64BIT_DATA && size == 8) + else if (MEM_SUPPORT_64BIT_DATA && size == 8) *((ulong *)ptr) = i; else if (size == 2) *((u16 *)ptr) = i; @@ -77,7 +77,7 @@ static void mtd_dump_device_buf(struct mtd_info *mtd, u64 start_off, if (has_pages) { for (page = 0; page < npages; page++) { - u64 data_off = page * mtd->writesize; + u64 data_off = (u64)page * mtd->writesize; printf("\nDump %d data bytes from 0x%08llx:\n", mtd->writesize, start_off + data_off); @@ -85,7 +85,7 @@ static void mtd_dump_device_buf(struct mtd_info *mtd, u64 start_off, mtd->writesize, start_off + data_off); if (woob) { - u64 oob_off = page * mtd->oobsize; + u64 oob_off = (u64)page * mtd->oobsize; printf("Dump %d OOB bytes from page at 0x%08llx:\n", mtd->oobsize, start_off + data_off); @@ -308,9 +308,9 @@ U_BOOT_CMD( #ifdef CONFIG_PARTITION_TYPE_GUID "part type <interface> <dev>:<part>\n" " - print partition type\n" -#endif "part type <interface> <dev>:<part> <varname>\n" " - set environment variable to partition type\n" +#endif "part set <interface> <dev> type\n" " - set partition type for a device\n" "part types\n" @@ -225,6 +225,6 @@ U_BOOT_CMD(pmic, CONFIG_SYS_MAXARGS, 1, do_pmic, "list - list pmic devices\n" "pmic dev [name] - show or [set] operating PMIC device\n" "pmic dump - dump registers\n" - "pmic read address - read byte of register at address\n" - "pmic write address - write byte to register at address\n" + "pmic read <reg> - read byte of 'reg' register\n" + "pmic write <reg> <byte> - write 'byte' byte to 'reg' register\n" ); diff --git a/cmd/reiser.c b/cmd/reiser.c deleted file mode 100644 index 707167f..0000000 --- a/cmd/reiser.c +++ /dev/null @@ -1,171 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * (C) Copyright 2003 - 2004 - * Sysgo Real-Time Solutions, AG <www.elinos.com> - * Pavel Bartusek <pba@sysgo.com> - */ - -/* - * Reiserfs support - */ -#include <common.h> -#include <config.h> -#include <command.h> -#include <env.h> -#include <image.h> -#include <linux/ctype.h> -#include <asm/byteorder.h> -#include <reiserfs.h> -#include <part.h> - -#if !CONFIG_IS_ENABLED(DOS_PARTITION) -#error DOS partition support must be selected -#endif - -/* #define REISER_DEBUG */ - -#ifdef REISER_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -int do_reiserls(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - char *filename = "/"; - int dev, part; - struct blk_desc *dev_desc = NULL; - struct disk_partition info; - - if (argc < 3) - return CMD_RET_USAGE; - - part = blk_get_device_part_str(argv[1], argv[2], &dev_desc, &info, 1); - if (part < 0) - return 1; - - if (argc == 4) { - filename = argv[3]; - } - - dev = dev_desc->devnum; - PRINTF("Using device %s %d:%d, directory: %s\n", argv[1], dev, part, filename); - - reiserfs_set_blk_dev(dev_desc, &info); - - if (!reiserfs_mount(info.size)) { - printf ("** Bad Reiserfs partition or disk - %s %d:%d **\n", argv[1], dev, part); - return 1; - } - - if (reiserfs_ls (filename)) { - printf ("** Error reiserfs_ls() **\n"); - return 1; - }; - - return 0; -} - -U_BOOT_CMD( - reiserls, 4, 1, do_reiserls, - "list files in a directory (default /)", - "<interface> <dev[:part]> [directory]\n" - " - list files from 'dev' on 'interface' in a 'directory'" -); - -/****************************************************************************** - * Reiserfs boot command intepreter. Derived from diskboot - */ -int do_reiserload(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) -{ - char *filename = NULL; - int dev, part; - ulong addr = 0, filelen; - struct disk_partition info; - struct blk_desc *dev_desc = NULL; - unsigned long count; - char *addr_str; - - switch (argc) { - case 3: - addr_str = env_get("loadaddr"); - if (addr_str != NULL) { - addr = hextoul(addr_str, NULL); - } else { - addr = CONFIG_SYS_LOAD_ADDR; - } - filename = env_get("bootfile"); - count = 0; - break; - case 4: - addr = hextoul(argv[3], NULL); - filename = env_get("bootfile"); - count = 0; - break; - case 5: - addr = hextoul(argv[3], NULL); - filename = argv[4]; - count = 0; - break; - case 6: - addr = hextoul(argv[3], NULL); - filename = argv[4]; - count = hextoul(argv[5], NULL); - break; - - default: - return CMD_RET_USAGE; - } - - if (!filename) { - puts ("\n** No boot file defined **\n"); - return 1; - } - - part = blk_get_device_part_str(argv[1], argv[2], &dev_desc, &info, 1); - if (part < 0) - return 1; - - dev = dev_desc->devnum; - - printf("Loading file \"%s\" from %s device %d%c%c\n", - filename, argv[1], dev, - part ? ':' : ' ', part ? part + '0' : ' '); - - reiserfs_set_blk_dev(dev_desc, &info); - - if (!reiserfs_mount(info.size)) { - printf ("** Bad Reiserfs partition or disk - %s %d:%d **\n", argv[1], dev, part); - return 1; - } - - filelen = reiserfs_open(filename); - if (filelen < 0) { - printf("** File not found %s **\n", filename); - return 1; - } - if ((count < filelen) && (count != 0)) { - filelen = count; - } - - if (reiserfs_read((char *)addr, filelen) != filelen) { - printf("\n** Unable to read \"%s\" from %s %d:%d **\n", filename, argv[1], dev, part); - return 1; - } - - /* Loading ok, update default load address */ - image_load_addr = addr; - - printf ("\n%ld bytes read\n", filelen); - env_set_hex("filesize", filelen); - - return filelen; -} - -U_BOOT_CMD( - reiserload, 6, 0, do_reiserload, - "load binary file from a Reiser filesystem", - "<interface> <dev[:part]> [addr] [filename] [bytes]\n" - " - load binary file 'filename' from 'dev' on 'interface'\n" - " to address 'addr' from dos filesystem" -); diff --git a/cmd/riscv/exception.c b/cmd/riscv/exception.c index f38f454..14ad6c4 100644 --- a/cmd/riscv/exception.c +++ b/cmd/riscv/exception.c @@ -5,7 +5,6 @@ * Copyright (c) 2018, Heinrich Schuchardt <xypron.glpk@gmx.de> */ -#include <common.h> #include <command.h> static int do_compressed(struct cmd_tbl *cmdtp, int flag, int argc, diff --git a/cmd/riscv/sbi.c b/cmd/riscv/sbi.c index 940d9bc..bd9d9c4 100644 --- a/cmd/riscv/sbi.c +++ b/cmd/riscv/sbi.c @@ -53,6 +53,7 @@ static struct sbi_ext extensions[] = { { SBI_EXT_CPPC, "Collaborative Processor Performance Control Extension" }, { SBI_EXT_NACL, "Nested Acceleration Extension" }, { SBI_EXT_STA, "Steal-time Accounting Extension" }, + { SBI_EXT_DBTR, "Debug Trigger Extension" }, }; static int do_sbi(struct cmd_tbl *cmdtp, int flag, int argc, @@ -80,6 +81,7 @@ static int do_sbi(struct cmd_tbl *cmdtp, int flag, int argc, break; switch (impl_id) { case 1: /* OpenSBI */ + case 8: /* PolarFire Hart Software Services */ printf("%ld.%ld", vers >> 16, vers & 0xffff); break; @@ -98,7 +100,7 @@ static int do_sbi(struct cmd_tbl *cmdtp, int flag, int argc, } } if (i == ARRAY_SIZE(implementations)) - printf("Unknown implementation ID %ld", ret); + printf("\nUnknown implementation ID 0x%x", impl_id); } printf("\nMachine:\n"); ret = sbi_get_mvendorid(&mvendorid); @@ -17,7 +17,23 @@ static int do_rng(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) u8 buf[64]; int devnum; struct udevice *dev; - int ret = CMD_RET_SUCCESS; + int ret = CMD_RET_SUCCESS, err; + + if (argc == 2 && !strcmp(argv[1], "list")) { + int idx = 0; + + uclass_foreach_dev_probe(UCLASS_RNG, dev) { + idx++; + printf("RNG #%d - %s\n", dev->seq_, dev->name); + } + + if (!idx) { + log_err("No RNG device\n"); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; + } switch (argc) { case 1: @@ -46,8 +62,9 @@ static int do_rng(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) n = min(n, sizeof(buf)); - if (dm_rng_read(dev, buf, n)) { - printf("Reading RNG failed\n"); + err = dm_rng_read(dev, buf, n); + if (err) { + puts(err == -EINTR ? "Abort\n" : "Reading RNG failed\n"); ret = CMD_RET_FAILURE; } else { print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, n); @@ -56,12 +73,9 @@ static int do_rng(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) return ret; } -U_BOOT_LONGHELP(rng, - "[dev [n]]\n" - " - print n random bytes(max 64) read from dev\n"); - U_BOOT_CMD( rng, 3, 0, do_rng, "print bytes from the hardware random number generator", - rng_help_text + "list - list all the probed rng devices\n" + "rng [dev] [n] - print n random bytes(max 64) read from dev\n" ); diff --git a/cmd/sandbox/exception.c b/cmd/sandbox/exception.c index c082401..cfa153d 100644 --- a/cmd/sandbox/exception.c +++ b/cmd/sandbox/exception.c @@ -5,7 +5,6 @@ * Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de> */ -#include <common.h> #include <command.h> static int do_sigsegv(struct cmd_tbl *cmdtp, int flag, int argc, diff --git a/cmd/setexpr.c b/cmd/setexpr.c index 233471f..ab76824 100644 --- a/cmd/setexpr.c +++ b/cmd/setexpr.c @@ -216,14 +216,12 @@ int setexpr_regex_sub(char *data, uint data_size, char *nbuf, uint nbuf_size, if (res == 0) { if (loop == 0) { debug("%s: No match\n", data); - return 1; } else { - break; + debug("## MATCH ## %s\n", data); } + break; } - debug("## MATCH ## %s\n", data); - if (!s) return 1; @@ -540,7 +538,8 @@ U_BOOT_CMD( " - For each substring matching the regular expression <r> in the\n" " string <t>, substitute the string <s>. The result is\n" " assigned to <name>. If <t> is not supplied, use the old\n" - " value of <name>\n" + " value of <name>. If no substring matching <r> is found in <t>,\n" + " assign <t> to <name>.\n" "setexpr name sub r s [t]\n" " - Just like gsub(), but replace only the first matching substring" #endif diff --git a/cmd/smbios.c b/cmd/smbios.c new file mode 100644 index 0000000..d3bd8b1 --- /dev/null +++ b/cmd/smbios.c @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * The 'smbios' command displays information from the SMBIOS table. + * + * Copyright (c) 2023, Heinrich Schuchardt <heinrich.schuchardt@canonical.com> + */ + +#include <command.h> +#include <hexdump.h> +#include <mapmem.h> +#include <smbios.h> +#include <tables_csum.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const char * const wakeup_type_strings[] = { + "Reserved", /* 0x00 */ + "Other", /* 0x01 */ + "Unknown", /* 0x02 */ + "APM Timer", /* 0x03 */ + "Modem Ring", /* 0x04 */ + "Lan Remote", /* 0x05 */ + "Power Switch", /* 0x06 */ + "PCI PME#", /* 0x07 */ + "AC Power Restored", /* 0x08 */ +}; + +/** + * smbios_get_string() - get SMBIOS string from table + * + * @table: SMBIOS table + * @index: index of the string + * Return: address of string, may point to empty string + */ +static const char *smbios_get_string(void *table, int index) +{ + const char *str = (char *)table + + ((struct smbios_header *)table)->length; + static const char fallback[] = "Not Specified"; + + if (!index) + return fallback; + + if (!*str) + ++str; + for (--index; *str && index; --index) + str += strlen(str) + 1; + + return str; +} + +static struct smbios_header *next_table(struct smbios_header *table) +{ + const char *str; + + if (table->type == SMBIOS_END_OF_TABLE) + return NULL; + + str = smbios_get_string(table, -1); + return (struct smbios_header *)(++str); +} + +static void smbios_print_generic(struct smbios_header *table) +{ + char *str = (char *)table + table->length; + + if (CONFIG_IS_ENABLED(HEXDUMP)) { + printf("Header and Data:\n"); + print_hex_dump("\t", DUMP_PREFIX_OFFSET, 16, 1, + table, table->length, false); + } + if (*str) { + printf("Strings:\n"); + for (int index = 1; *str; ++index) { + printf("\tString %u: %s\n", index, str); + str += strlen(str) + 1; + } + } +} + +void smbios_print_str(const char *label, void *table, u8 index) +{ + printf("\t%s: %s\n", label, smbios_get_string(table, index)); +} + +const char *smbios_wakeup_type_str(u8 wakeup_type) +{ + if (wakeup_type >= ARRAY_SIZE(wakeup_type_strings)) + /* Values over 0x08 are reserved. */ + wakeup_type = 0; + return wakeup_type_strings[wakeup_type]; +} + +static void smbios_print_type1(struct smbios_type1 *table) +{ + printf("System Information\n"); + smbios_print_str("Manufacturer", table, table->manufacturer); + smbios_print_str("Product Name", table, table->product_name); + smbios_print_str("Version", table, table->version); + smbios_print_str("Serial Number", table, table->serial_number); + if (table->length >= 0x19) { + printf("\tUUID: %pUl\n", table->uuid); + printf("\tWake-up Type: %s\n", + smbios_wakeup_type_str(table->wakeup_type)); + } + if (table->length >= 0x1b) { + smbios_print_str("SKU Number", table, table->sku_number); + smbios_print_str("Family", table, table->family); + } +} + +static void smbios_print_type2(struct smbios_type2 *table) +{ + u16 *handle; + + printf("Base Board Information\n"); + smbios_print_str("Manufacturer", table, table->manufacturer); + smbios_print_str("Product Name", table, table->product_name); + smbios_print_str("Version", table, table->version); + smbios_print_str("Serial Number", table, table->serial_number); + smbios_print_str("Asset Tag", table, table->asset_tag_number); + printf("\tFeature Flags: 0x%04x\n", table->feature_flags); + smbios_print_str("Chassis Location", table, table->chassis_location); + printf("\tChassis Handle: 0x%04x\n", table->chassis_handle); + smbios_print_str("Board Type", table, table->board_type); + printf("\tContained Object Handles: "); + handle = (void *)table->eos; + for (int i = 0; i < table->number_contained_objects; ++i) + printf("0x%04x ", handle[i]); + printf("\n"); +} + +static void smbios_print_type127(struct smbios_type127 *table) +{ + printf("End Of Table\n"); +} + +static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + ulong addr; + void *entry; + u32 size; + char version[12]; + struct smbios_header *table; + static const char smbios_sig[] = "_SM_"; + static const char smbios3_sig[] = "_SM3_"; + size_t count = 0; + u32 table_maximum_size; + + addr = gd_smbios_start(); + if (!addr) { + log_warning("SMBIOS not available\n"); + return CMD_RET_FAILURE; + } + entry = map_sysmem(addr, 0); + if (!memcmp(entry, smbios3_sig, sizeof(smbios3_sig) - 1)) { + struct smbios3_entry *entry3 = entry; + + table = (void *)(uintptr_t)entry3->struct_table_address; + snprintf(version, sizeof(version), "%d.%d.%d", + entry3->major_ver, entry3->minor_ver, entry3->doc_rev); + table = (void *)(uintptr_t)entry3->struct_table_address; + size = entry3->length; + table_maximum_size = entry3->table_maximum_size; + } else if (!memcmp(entry, smbios_sig, sizeof(smbios_sig) - 1)) { + struct smbios_entry *entry2 = entry; + + snprintf(version, sizeof(version), "%d.%d", + entry2->major_ver, entry2->minor_ver); + table = (void *)(uintptr_t)entry2->struct_table_address; + size = entry2->length; + table_maximum_size = entry2->struct_table_length; + } else { + log_err("Unknown SMBIOS anchor format\n"); + return CMD_RET_FAILURE; + } + if (table_compute_checksum(entry, size)) { + log_err("Invalid anchor checksum\n"); + return CMD_RET_FAILURE; + } + printf("SMBIOS %s present.\n", version); + + for (struct smbios_header *pos = table; pos; pos = next_table(pos)) + ++count; + printf("%zd structures occupying %d bytes\n", count, table_maximum_size); + printf("Table at 0x%llx\n", (unsigned long long)map_to_sysmem(table)); + + for (struct smbios_header *pos = table; pos; pos = next_table(pos)) { + printf("\nHandle 0x%04x, DMI type %d, %d bytes at 0x%llx\n", + pos->handle, pos->type, pos->length, + (unsigned long long)map_to_sysmem(pos)); + switch (pos->type) { + case 1: + smbios_print_type1((struct smbios_type1 *)pos); + break; + case 2: + smbios_print_type2((struct smbios_type2 *)pos); + break; + case 127: + smbios_print_type127((struct smbios_type127 *)pos); + break; + default: + smbios_print_generic(pos); + break; + } + } + + return CMD_RET_SUCCESS; +} + +U_BOOT_LONGHELP(smbios, "- display SMBIOS information"); + +U_BOOT_CMD(smbios, 1, 0, do_smbios, "display SMBIOS information", + smbios_help_text); diff --git a/cmd/sysboot.c b/cmd/sysboot.c index 63a7806..d14c570 100644 --- a/cmd/sysboot.c +++ b/cmd/sysboot.c @@ -77,6 +77,10 @@ static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc, if (argc < 6) { filename = env_get("bootfile"); + if (!filename) { + printf("Specify a filename or set the ${bootfile} environment variable\n"); + return 1; + } } else { filename = argv[5]; env_set("bootfile", filename); diff --git a/cmd/usb_mass_storage.c b/cmd/usb_mass_storage.c index a8ddeb4..751701f 100644 --- a/cmd/usb_mass_storage.c +++ b/cmd/usb_mass_storage.c @@ -88,10 +88,6 @@ static int ums_init(const char *devtype, const char *devnums_part_str) if (!strchr(devnum_part_str, ':')) partnum = 0; - /* f_mass_storage.c assumes SECTOR_SIZE sectors */ - if (block_dev->blksz != SECTOR_SIZE) - goto cleanup; - ums_new = realloc(ums, (ums_count + 1) * sizeof(*ums)); if (!ums_new) goto cleanup; diff --git a/cmd/x86/Makefile b/cmd/x86/Makefile index 5f82204..b1f39d3 100644 --- a/cmd/x86/Makefile +++ b/cmd/x86/Makefile @@ -5,3 +5,4 @@ obj-y += mtrr.o obj-$(CONFIG_CMD_EXCEPTION) += exception.o obj-$(CONFIG_USE_HOB) += hob.o obj-$(CONFIG_HAVE_FSP) += fsp.o +obj-$(CONFIG_CMD_ZBOOT) += zboot.o diff --git a/cmd/x86/exception.c b/cmd/x86/exception.c index 82faaa9..14b6bd6 100644 --- a/cmd/x86/exception.c +++ b/cmd/x86/exception.c @@ -5,7 +5,6 @@ * Copyright (c) 2018, Heinrich Schuchardt <xypron.glpk@gmx.de> */ -#include <common.h> #include <command.h> static int do_undefined(struct cmd_tbl *cmdtp, int flag, int argc, diff --git a/cmd/x86/zboot.c b/cmd/x86/zboot.c new file mode 100644 index 0000000..addf28c --- /dev/null +++ b/cmd/x86/zboot.c @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se> + */ + +#include <command.h> +#include <mapmem.h> +#include <vsprintf.h> +#include <asm/zimage.h> + +static int do_zboot_start(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + ulong bzimage_addr = 0, bzimage_size, initrd_addr, initrd_size; + ulong base_addr; + const char *s, *cmdline; + + /* argv[1] holds the address of the bzImage */ + s = cmd_arg1(argc, argv) ? : env_get("fileaddr"); + if (s) + bzimage_addr = hextoul(s, NULL); + bzimage_size = argc > 2 ? hextoul(argv[2], NULL) : 0; + initrd_addr = argc > 3 ? hextoul(argv[3], NULL) : 0; + initrd_size = argc > 4 ? hextoul(argv[4], NULL) : 0; + base_addr = argc > 5 ? hextoul(argv[5], NULL) : 0; + cmdline = argc > 6 ? env_get(argv[6]) : NULL; + + zboot_start(bzimage_addr, bzimage_size, initrd_addr, initrd_size, + base_addr, cmdline); + + return 0; +} + +static int do_zboot_load(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + + ret = zboot_load(); + if (ret) + return ret; + + return 0; +} + +static int do_zboot_setup(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + if (!state.base_ptr) { + printf("base is not set: use 'zboot load' first\n"); + return CMD_RET_FAILURE; + } + if (zboot_setup()) { + puts("Setting up boot parameters failed ...\n"); + return CMD_RET_FAILURE; + } + + if (zboot_setup()) + return CMD_RET_FAILURE; + + return 0; +} + +static int do_zboot_info(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + zboot_info(); + + return 0; +} + +static int do_zboot_go(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + int ret; + + ret = zboot_go(); + if (ret) { + printf("Kernel returned! (err=%d)\n", ret); + return CMD_RET_FAILURE; + } + + return 0; +} + +static int do_zboot_dump(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct boot_params *base_ptr = state.base_ptr; + + if (argc > 1) + base_ptr = (void *)hextoul(argv[1], NULL); + if (!base_ptr) { + printf("No zboot setup_base\n"); + return CMD_RET_FAILURE; + } + zimage_dump(base_ptr, true); + + return 0; +} + +/* Note: This defines the complete_zboot() function */ +U_BOOT_SUBCMDS(zboot, + U_BOOT_CMD_MKENT(start, 8, 1, do_zboot_start, "", ""), + U_BOOT_CMD_MKENT(load, 1, 1, do_zboot_load, "", ""), + U_BOOT_CMD_MKENT(setup, 1, 1, do_zboot_setup, "", ""), + U_BOOT_CMD_MKENT(info, 1, 1, do_zboot_info, "", ""), + U_BOOT_CMD_MKENT(go, 1, 1, do_zboot_go, "", ""), + U_BOOT_CMD_MKENT(dump, 2, 1, do_zboot_dump, "", ""), +) + +int do_zboot_states(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[], int state_mask) +{ + int ret; + + if (flag & ZBOOT_STATE_START) + ret = do_zboot_start(cmdtp, flag, argc, argv); + if (!ret && (flag & ZBOOT_STATE_LOAD)) + ret = do_zboot_load(cmdtp, flag, argc, argv); + if (!ret && (flag & ZBOOT_STATE_SETUP)) + ret = do_zboot_setup(cmdtp, flag, argc, argv); + if (!ret && (flag & ZBOOT_STATE_INFO)) + ret = do_zboot_info(cmdtp, flag, argc, argv); + if (!ret && (flag & ZBOOT_STATE_GO)) + ret = do_zboot_go(cmdtp, flag, argc, argv); + if (ret) + return ret; + + return 0; +} + +int do_zboot_parent(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[], int *repeatable) +{ + /* determine if we have a sub command */ + if (argc > 1) { + char *endp; + + hextoul(argv[1], &endp); + /* + * endp pointing to nul means that argv[1] was just a valid + * number, so pass it along to the normal processing + */ + if (*endp) + return do_zboot(cmdtp, flag, argc, argv, repeatable); + } + + do_zboot_states(cmdtp, flag, argc, argv, ZBOOT_STATE_START | + ZBOOT_STATE_LOAD | ZBOOT_STATE_SETUP | + ZBOOT_STATE_INFO | ZBOOT_STATE_GO); + + return CMD_RET_FAILURE; +} + +U_BOOT_CMDREP_COMPLETE( + zboot, 8, do_zboot_parent, "Boot bzImage", + "[addr] [size] [initrd addr] [initrd size] [setup] [cmdline]\n" + " addr - The optional starting address of the bzimage.\n" + " If not set it defaults to the environment\n" + " variable \"fileaddr\".\n" + " size - The optional size of the bzimage. Defaults to\n" + " zero.\n" + " initrd addr - The address of the initrd image to use, if any.\n" + " initrd size - The size of the initrd image to use, if any.\n" + " setup - The address of the kernel setup region, if this\n" + " is not at addr\n" + " cmdline - Environment variable containing the kernel\n" + " command line, to override U-Boot's normal\n" + " cmdline generation\n" + "\n" + "Sub-commands to do part of the zboot sequence:\n" + "\tstart [addr [arg ...]] - specify arguments\n" + "\tload - load OS image\n" + "\tsetup - set up table\n" + "\tinfo - show summary info\n" + "\tgo - start OS\n" + "\tdump [addr] - dump info (optional address of boot params)", + complete_zboot +); @@ -27,11 +27,6 @@ #include <asm/cache.h> #include <asm/io.h> -#ifndef CFG_SYS_XIMG_LEN -/* use 8MByte as default max gunzip size */ -#define CFG_SYS_XIMG_LEN 0x800000 -#endif - static int do_imgextract(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { @@ -52,7 +47,7 @@ do_imgextract(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) size_t fit_len; #endif #ifdef CONFIG_GZIP - uint unc_len = CFG_SYS_XIMG_LEN; + uint unc_len = CONFIG_SYS_XIMG_LEN; #endif uint8_t comp; |