summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-02-07 11:42:26 -0500
committerTom Rini <trini@konsulko.com>2023-02-07 11:42:26 -0500
commitb69026c91f2e98b247120e217a986f5056724baf (patch)
treef1533069fcdbcf265deb0ea6b3b940e81902d9b3 /cmd
parentf8f47e6ff214a3ba7a61025bcc4dc058f507c279 (diff)
parent41a29f284cef48a86c86d038c0cd8cc1c851417e (diff)
Merge branch '2023-02-07-assorted-updates'
- Default to dynamic LMB allocation, and fix an issue with the EFI one, assorted TI platform updates, socrates platform updates, switch qemu-arm to using bootstd, imagetool fixes, macOS host build fixes, keymile platform upates, spl FPGA load fix, MMC env bugfix, add seama command, usb bootdev test bugfix.
Diffstat (limited to 'cmd')
-rw-r--r--cmd/Kconfig6
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/bootflow.c21
-rw-r--r--cmd/qfw.c89
-rw-r--r--cmd/seama.c158
5 files changed, 189 insertions, 86 deletions
diff --git a/cmd/Kconfig b/cmd/Kconfig
index dc0446e02e8..b50e14f70a0 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -337,6 +337,12 @@ config BOOTM_RTEMS
help
Support booting RTEMS images via the bootm command.
+config CMD_SEAMA
+ bool "Support read SEAMA NAND images"
+ depends on MTD_RAW_NAND
+ help
+ Support reading NAND Seattle Image (SEAMA) images.
+
config CMD_VBE
bool "vbe - Verified Boot for Embedded"
depends on BOOTMETH_VBE
diff --git a/cmd/Makefile b/cmd/Makefile
index 7b6ff731865..b03d68d5f9b 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -156,6 +156,7 @@ obj-$(CONFIG_SANDBOX) += sb.o
obj-$(CONFIG_CMD_SF) += sf.o
obj-$(CONFIG_CMD_SCSI) += scsi.o disk.o
obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o
+obj-$(CONFIG_CMD_SEAMA) += seama.o
obj-$(CONFIG_CMD_SETEXPR) += setexpr.o
obj-$(CONFIG_CMD_SETEXPR_FMT) += printf.o
obj-$(CONFIG_CMD_SPI) += spi.o
diff --git a/cmd/bootflow.c b/cmd/bootflow.c
index 692bc6d117f..3548bbb6830 100644
--- a/cmd/bootflow.c
+++ b/cmd/bootflow.c
@@ -394,15 +394,20 @@ static int do_bootflow_menu(struct cmd_tbl *cmdtp, int flag, int argc,
if (ret)
return CMD_RET_FAILURE;
- ret = bootflow_menu_run(std, text_mode, &bflow);
- if (ret) {
- if (ret == -EAGAIN)
- printf("Nothing chosen\n");
- else
- printf("Menu failed (err=%d)\n", ret);
-
- return CMD_RET_FAILURE;
+ if (IS_ENABLED(CONFIG_EXPO)) {
+ ret = bootflow_menu_run(std, text_mode, &bflow);
+ if (ret) {
+ if (ret == -EAGAIN)
+ printf("Nothing chosen\n");
+ else
+ printf("Menu failed (err=%d)\n", ret);
+ }
+ } else {
+ printf("Menu not supported\n");
+ ret = -ENOSYS;
}
+ if (ret)
+ return CMD_RET_FAILURE;
printf("Selected: %s\n", bflow->os_name ? bflow->os_name : bflow->name);
std->cur_bootflow = bflow;
diff --git a/cmd/qfw.c b/cmd/qfw.c
index 0c49c6074e1..ae3c6a7a84e 100644
--- a/cmd/qfw.c
+++ b/cmd/qfw.c
@@ -12,73 +12,6 @@
static struct udevice *qfw_dev;
-/*
- * This function prepares kernel for zboot. It loads kernel data
- * to 'load_addr', initrd to 'initrd_addr' and kernel command
- * line using qemu fw_cfg interface.
- */
-static int qemu_fwcfg_cmd_setup_kernel(void *load_addr, void *initrd_addr)
-{
- char *data_addr;
- uint32_t setup_size, kernel_size, cmdline_size, initrd_size;
-
- qfw_read_entry(qfw_dev, FW_CFG_SETUP_SIZE, 4, &setup_size);
- qfw_read_entry(qfw_dev, FW_CFG_KERNEL_SIZE, 4, &kernel_size);
-
- if (kernel_size == 0) {
- printf("fatal: no kernel available\n");
- return CMD_RET_FAILURE;
- }
-
- data_addr = load_addr;
- if (setup_size != 0) {
- qfw_read_entry(qfw_dev, FW_CFG_SETUP_DATA,
- le32_to_cpu(setup_size), data_addr);
- data_addr += le32_to_cpu(setup_size);
- }
-
- qfw_read_entry(qfw_dev, FW_CFG_KERNEL_DATA,
- le32_to_cpu(kernel_size), data_addr);
- data_addr += le32_to_cpu(kernel_size);
- env_set_hex("filesize", le32_to_cpu(kernel_size));
-
- data_addr = initrd_addr;
- qfw_read_entry(qfw_dev, FW_CFG_INITRD_SIZE, 4, &initrd_size);
- if (initrd_size == 0) {
- printf("warning: no initrd available\n");
- } else {
- qfw_read_entry(qfw_dev, FW_CFG_INITRD_DATA,
- le32_to_cpu(initrd_size), data_addr);
- data_addr += le32_to_cpu(initrd_size);
- env_set_hex("filesize", le32_to_cpu(initrd_size));
- }
-
- qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_SIZE, 4, &cmdline_size);
- if (cmdline_size) {
- qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_DATA,
- le32_to_cpu(cmdline_size), data_addr);
- /*
- * if kernel cmdline only contains '\0', (e.g. no -append
- * when invoking qemu), do not update bootargs
- */
- if (*data_addr != '\0') {
- if (env_set("bootargs", data_addr) < 0)
- printf("warning: unable to change bootargs\n");
- }
- }
-
- printf("loading kernel to address %p size %x", load_addr,
- le32_to_cpu(kernel_size));
- if (initrd_size)
- printf(" initrd %p size %x\n",
- initrd_addr,
- le32_to_cpu(initrd_size));
- else
- printf("\n");
-
- return 0;
-}
-
static int qemu_fwcfg_cmd_list_firmware(void)
{
int ret;
@@ -119,28 +52,28 @@ static int qemu_fwcfg_do_load(struct cmd_tbl *cmdtp, int flag,
int argc, char *const argv[])
{
char *env;
- void *load_addr;
- void *initrd_addr;
+ ulong load_addr;
+ ulong initrd_addr;
env = env_get("loadaddr");
load_addr = env ?
- (void *)hextoul(env, NULL) :
- (void *)CONFIG_SYS_LOAD_ADDR;
+ hextoul(env, NULL) :
+ CONFIG_SYS_LOAD_ADDR;
env = env_get("ramdiskaddr");
initrd_addr = env ?
- (void *)hextoul(env, NULL) :
+ hextoul(env, NULL) :
#ifdef CFG_RAMDISK_ADDR
- (void *)CFG_RAMDISK_ADDR;
+ CFG_RAMDISK_ADDR;
#else
- NULL;
+ 0;
#endif
if (argc == 2) {
- load_addr = (void *)hextoul(argv[0], NULL);
- initrd_addr = (void *)hextoul(argv[1], NULL);
+ load_addr = hextoul(argv[0], NULL);
+ initrd_addr = hextoul(argv[1], NULL);
} else if (argc == 1) {
- load_addr = (void *)hextoul(argv[0], NULL);
+ load_addr = hextoul(argv[0], NULL);
}
if (!load_addr || !initrd_addr) {
@@ -148,7 +81,7 @@ static int qemu_fwcfg_do_load(struct cmd_tbl *cmdtp, int flag,
return CMD_RET_FAILURE;
}
- return qemu_fwcfg_cmd_setup_kernel(load_addr, initrd_addr);
+ return qemu_fwcfg_setup_kernel(qfw_dev, load_addr, initrd_addr);
}
static struct cmd_tbl fwcfg_commands[] = {
diff --git a/cmd/seama.c b/cmd/seama.c
new file mode 100644
index 00000000000..3aafb43c48a
--- /dev/null
+++ b/cmd/seama.c
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2023 Linus Walleij <linus.walleij@linaro.org>
+ * Support for the "SEAttle iMAge" SEAMA NAND image format
+ */
+
+#include <common.h>
+#include <command.h>
+#include <nand.h>
+
+/*
+ * All SEAMA data is stored in the flash in "network endianness"
+ * i.e. big endian, which means that it needs to be byte-swapped
+ * on all little endian platforms.
+ *
+ * structure for a SEAMA entity in NAND flash:
+ *
+ * 32 bit SEAMA magic 0x5EA3A417
+ * 16 bit reserved
+ * 16 bit metadata size (following the header)
+ * 32 bit image size
+ * 16 bytes MD5 digest of the image
+ * meta data
+ * ... image data ...
+ *
+ * Then if a new SEAMA magic follows, that is the next image.
+ */
+
+#define SEAMA_MAGIC 0x5EA3A417
+#define SEAMA_HDR_NO_META_SZ 28
+#define SEAMA_MAX_META_SZ (1024 - SEAMA_HDR_NO_META_SZ)
+
+struct seama_header {
+ u32 magic;
+ u32 meta_size;
+ u32 image_size;
+ u8 md5[16];
+ u8 metadata[SEAMA_MAX_META_SZ];
+};
+
+static struct seama_header shdr;
+
+static int env_set_val(const char *varname, ulong val)
+{
+ int ret;
+
+ ret = env_set_hex(varname, val);
+ if (ret)
+ printf("Failed to %s env var\n", varname);
+
+ return ret;
+}
+
+static int do_seama_load_image(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct mtd_info *mtd;
+ uintptr_t load_addr;
+ unsigned long image_index;
+ u32 len;
+ size_t readsz;
+ int ret;
+ u32 *start;
+ u32 *offset;
+ u32 *end;
+ u32 tmp;
+
+ if (argc < 2 || argc > 3)
+ return CMD_RET_USAGE;
+
+ load_addr = hextoul(argv[1], NULL);
+ if (!load_addr) {
+ printf("Invalid load address\n");
+ return CMD_RET_USAGE;
+ }
+
+ /* Can be 0 for first image */
+ image_index = hextoul(argv[2], NULL);
+
+ /* We only support one NAND, the first one */
+ nand_curr_device = 0;
+ mtd = get_nand_dev_by_index(0);
+ if (!mtd) {
+ printf("NAND Device 0 not available\n");
+ return CMD_RET_FAILURE;
+ }
+
+#ifdef CONFIG_SYS_NAND_SELECT_DEVICE
+ board_nand_select_device(mtd_to_nand(mtd), 0);
+#endif
+
+ printf("Loading SEAMA image %lu from %s\n", image_index, mtd->name);
+
+ readsz = sizeof(shdr);
+ offset = 0;
+ ret = nand_read_skip_bad(mtd, 0, &readsz, NULL, mtd->size,
+ (u_char *)&shdr);
+ if (ret) {
+ printf("Read error reading SEAMA header\n");
+ return CMD_RET_FAILURE;
+ }
+
+ if (shdr.magic != SEAMA_MAGIC) {
+ printf("Invalid SEAMA image magic: 0x%08x\n", shdr.magic);
+ return CMD_RET_FAILURE;
+ }
+
+ /* Only the lower 16 bits are valid */
+ shdr.meta_size &= 0xFFFF;
+
+ if (env_set_val("seama_image_size", 0))
+ return CMD_RET_FAILURE;
+
+ printf("SEMA IMAGE:\n");
+ printf(" metadata size %d\n", shdr.meta_size);
+ printf(" image size %d\n", shdr.image_size);
+ printf(" checksum %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+ shdr.md5[0], shdr.md5[1], shdr.md5[2], shdr.md5[3],
+ shdr.md5[4], shdr.md5[5], shdr.md5[6], shdr.md5[7],
+ shdr.md5[8], shdr.md5[9], shdr.md5[10], shdr.md5[11],
+ shdr.md5[12], shdr.md5[13], shdr.md5[14], shdr.md5[15]);
+
+ /* TODO: handle metadata if needed */
+
+ len = shdr.image_size;
+ if (env_set_val("seama_image_size", len))
+ return CMD_RET_FAILURE;
+
+ /* We need to include the header (read full pages) */
+ readsz = shdr.image_size + SEAMA_HDR_NO_META_SZ + shdr.meta_size;
+ ret = nand_read_skip_bad(mtd, 0, &readsz, NULL, mtd->size,
+ (u_char *)load_addr);
+ if (ret) {
+ printf("Read error reading SEAMA main image\n");
+ return CMD_RET_FAILURE;
+ }
+
+ /* We use a temporary variable tmp to avoid to hairy casts */
+ start = (u32 *)load_addr;
+ tmp = (u32)start;
+ tmp += SEAMA_HDR_NO_META_SZ + shdr.meta_size;
+ offset = (u32 *)tmp;
+ tmp += shdr.image_size;
+ end = (u32 *)tmp;
+
+ printf("Decoding SEAMA image 0x%08x..0x%08x to 0x%08x\n",
+ (u32)offset, (u32)end, (u32)start);
+ for (; start < end; start++, offset++)
+ *start = be32_to_cpu(*offset);
+
+ return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD
+ (seama, 3, 1, do_seama_load_image,
+ "Load the SEAMA image and sets envs",
+ "seama <addr> <imageindex>\n"
+);