summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2025-11-03 10:12:05 -0600
committerTom Rini <[email protected]>2025-11-03 10:12:05 -0600
commit9ccda31f54881d3321263a81599454a1d6efb65e (patch)
tree71c250bf67f39df36d05ef55512692132b99fa40
parentc2637036b8f0c90a2cfc59900f7da31eae646b03 (diff)
parente9dc6c12958fc5d909848fc3999e6be5df1cd3ae (diff)
Merge patch series "Convert extension support to UCLASS and adds its support to boot flows"
Kory Maincent (TI.com) <[email protected]> says: This series converts the extension board framework to use UCLASS as requested by Simon Glass, then adds extension support to pxe_utils and bootmeth_efi (not tested) to enable extension boards devicetree load in the standard boot process. I can't test the imx8 extension scan enabled by the imx8mm-cl-iot-gate_defconfig as I don't have this board. I also can't test the efi bootmeth change as I don't have such board. Link: https://lore.kernel.org/r/20251030-feature_sysboot_extension_board-v5-0-cfb77672fc68@bootlin.com
-rw-r--r--MAINTAINERS9
-rw-r--r--board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c70
-rw-r--r--board/sandbox/sandbox.c29
-rw-r--r--board/sunxi/Makefile2
-rw-r--r--board/sunxi/chip.c36
-rw-r--r--board/ti/common/Kconfig2
-rw-r--r--board/ti/common/Makefile2
-rw-r--r--board/ti/common/cape_detect.c56
-rw-r--r--boot/Kconfig4
-rw-r--r--boot/Makefile1
-rw-r--r--boot/bootmeth_efi.c79
-rw-r--r--boot/extension-uclass.c93
-rw-r--r--boot/pxe_utils.c92
-rw-r--r--cmd/Kconfig3
-rw-r--r--cmd/extension_board.c183
-rw-r--r--doc/usage/cmd/extension.rst29
-rw-r--r--doc/usage/pxe.rst4
-rw-r--r--include/dm/uclass-id.h1
-rw-r--r--include/extension_board.h86
-rw-r--r--test/boot/bootdev.c32
-rw-r--r--test/boot/bootflow.c6
-rw-r--r--test/boot/bootstd_common.h4
22 files changed, 565 insertions, 258 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 5f9163f9c09..8c7d0e0ab2f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1185,6 +1185,15 @@ F: scripts/event_dump.py
F: test/common/event.c
F: test/py/tests/test_event_dump.py
+EXTENSION
+M: Kory Maincent <[email protected]>
+S: Maintained
+F: board/sunxi/chip.c
+F: board/ti/common/cape_detect.c
+F: boot/extension-uclass.c
+F: cmd/extension_board.c
+F: include/extension_board.h
+
FASTBOOT
M: Mattijs Korpershoek <[email protected]>
S: Maintained
diff --git a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c
index bda7aac5be4..260d8757129 100644
--- a/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c
+++ b/board/compulab/imx8mm-cl-iot-gate/imx8mm-cl-iot-gate.c
@@ -249,6 +249,8 @@ int board_mmc_get_env_dev(int devno)
#define IOT_GATE_IMX8_EXT_I2C_ADDR_GPIO 0x22 /* I2C address of the GPIO
extender */
+#if !IS_ENABLED(CONFIG_XPL_BUILD)
+
static int iot_gate_imx8_ext_id = IOT_GATE_EXT_EMPTY; /* Extension board ID */
static int iot_gate_imx8_ext_ied_id [3] = {
IOT_GATE_IMX8_CARD_ID_EMPTY,
@@ -434,9 +436,10 @@ static int iot_gate_imx8_update_ext_ied(void)
return 0;
}
-int extension_board_scan(struct list_head *extension_list)
+static int iot_gate_imx8_extension_board_scan(struct udevice *dev,
+ struct alist *extension_list)
{
- struct extension *extension = NULL;
+ struct extension extension = {0};
int i;
int ret = 0;
@@ -446,25 +449,21 @@ int extension_board_scan(struct list_head *extension_list)
case IOT_GATE_EXT_EMPTY:
break;
case IOT_GATE_EXT_CAN:
- extension = calloc(1, sizeof(struct extension));
- snprintf(extension->name, sizeof(extension->name),
+ snprintf(extension.name, sizeof(extension.name),
"IOT_GATE_EXT_CAN");
break;
case IOT_GATE_EXT_IED:
- extension = calloc(1, sizeof(struct extension));
- snprintf(extension->name, sizeof(extension->name),
+ snprintf(extension.name, sizeof(extension.name),
"IOT_GATE_EXT_IED");
- snprintf(extension->overlay, sizeof(extension->overlay),
+ snprintf(extension.overlay, sizeof(extension.overlay),
"imx8mm-cl-iot-gate-ied.dtbo");
break;
case IOT_GATE_EXT_POE:
- extension = calloc(1, sizeof(struct extension));
- snprintf(extension->name, sizeof(extension->name),
+ snprintf(extension.name, sizeof(extension.name),
"IOT_GATE_EXT_POE");
break;
case IOT_GATE_EXT_POEV2:
- extension = calloc(1, sizeof(struct extension));
- snprintf(extension->name, sizeof(extension->name),
+ snprintf(extension.name, sizeof(extension.name),
"IOT_GATE_EXT_POEV2");
break;
default:
@@ -472,10 +471,11 @@ int extension_board_scan(struct list_head *extension_list)
break;
}
- if (extension) {
- snprintf(extension->owner, sizeof(extension->owner),
+ if (extension.name[0]) {
+ snprintf(extension.owner, sizeof(extension.owner),
"Compulab");
- list_add_tail(&extension->list, extension_list);
+ if (!alist_add(extension_list, extension))
+ return -ENOMEM;
ret = 1;
} else
return ret;
@@ -484,44 +484,38 @@ int extension_board_scan(struct list_head *extension_list)
iot_gate_imx8_update_ext_ied();
for (i=0; i<ARRAY_SIZE(iot_gate_imx8_ext_ied_id); i++) {
- extension = NULL;
+ memset(&extension, 0, sizeof(extension));
switch (iot_gate_imx8_ext_ied_id[i]) {
case IOT_GATE_IMX8_CARD_ID_EMPTY:
break;
case IOT_GATE_IMX8_CARD_ID_RS_485:
- extension = calloc(1, sizeof(struct extension));
- snprintf(extension->name, sizeof(extension->name),
+ snprintf(extension.name, sizeof(extension.name),
"IOT_GATE_IMX8_CARD_ID_RS_485");
break;
case IOT_GATE_IMX8_CARD_ID_RS_232:
- extension = calloc(1, sizeof(struct extension));
- snprintf(extension->name, sizeof(extension->name),
+ snprintf(extension.name, sizeof(extension.name),
"IOT_GATE_IMX8_CARD_ID_RS_232");
break;
case IOT_GATE_IMX8_CARD_ID_CAN:
- extension = calloc(1, sizeof(struct extension));
- snprintf(extension->name, sizeof(extension->name),
+ snprintf(extension.name, sizeof(extension.name),
"IOT_GATE_IMX8_CARD_ID_CAN");
- snprintf(extension->overlay, sizeof(extension->overlay),
+ snprintf(extension.overlay, sizeof(extension.overlay),
"imx8mm-cl-iot-gate-ied-can%d.dtbo", i);
break;
case IOT_GATE_IMX8_CARD_ID_TPM:
- extension = calloc(1, sizeof(struct extension));
- snprintf(extension->name, sizeof(extension->name),
+ snprintf(extension.name, sizeof(extension.name),
"IOT_GATE_IMX8_CARD_ID_TPM");
- snprintf(extension->overlay, sizeof(extension->overlay),
+ snprintf(extension.overlay, sizeof(extension.overlay),
"imx8mm-cl-iot-gate-ied-tpm%d.dtbo", i);
break;
case IOT_GATE_IMX8_CARD_ID_CL420:
- extension = calloc(1, sizeof(struct extension));
- snprintf(extension->name, sizeof(extension->name),
+ snprintf(extension.name, sizeof(extension.name),
"IOT_GATE_IMX8_CARD_ID_CL420");
- snprintf(extension->overlay, sizeof(extension->overlay),
+ snprintf(extension.overlay, sizeof(extension.overlay),
"imx8mm-cl-iot-gate-ied-can%d.dtbo", i);
break;
case IOT_GATE_IMX8_CARD_ID_DI4O4:
- extension = calloc(1, sizeof(struct extension));
- snprintf(extension->name, sizeof(extension->name),
+ snprintf(extension.name, sizeof(extension.name),
"IOT_GATE_IMX8_CARD_ID_DI4O4");
break;
default:
@@ -529,12 +523,13 @@ int extension_board_scan(struct list_head *extension_list)
__func__, i, iot_gate_imx8_ext_ied_id[i]);
break;
}
- if (extension) {
- snprintf(extension->owner, sizeof(extension->owner),
+ if (extension.name[0]) {
+ snprintf(extension.owner, sizeof(extension.owner),
"Compulab");
- snprintf(extension->other, sizeof(extension->other),
+ snprintf(extension.other, sizeof(extension.other),
"On slot %d", i);
- list_add_tail(&extension->list, extension_list);
+ if (!alist_add(extension_list, extension))
+ return -ENOMEM;
ret = ret + 1;
}
}
@@ -542,6 +537,13 @@ int extension_board_scan(struct list_head *extension_list)
return ret;
}
+U_BOOT_EXTENSION(iot_gate_imx8_extension, iot_gate_imx8_extension_board_scan);
+
+U_BOOT_DRVINFO(iot_gate_imx8_extension) = {
+ .name = "iot_gate_imx8_extension",
+};
+#endif
+
static int setup_mac_address(void)
{
unsigned char enetaddr[6];
diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c
index 0dc23a27dfc..d0bb3e3bb48 100644
--- a/board/sandbox/sandbox.c
+++ b/board/sandbox/sandbox.c
@@ -110,24 +110,33 @@ int ft_board_setup(void *fdt, struct bd_info *bd)
return fdt_add_mem_rsv(fdt, 0x00d02000, 0x4000);
}
-#ifdef CONFIG_CMD_EXTENSION
-int extension_board_scan(struct list_head *extension_list)
+#if CONFIG_IS_ENABLED(SUPPORT_EXTENSION_SCAN) && \
+ !CONFIG_IS_ENABLED(XPL_BUILD)
+static int sandbox_extension_board_scan(struct udevice *dev,
+ struct alist *extension_list)
{
- struct extension *extension;
int i;
for (i = 0; i < 2; i++) {
- extension = calloc(1, sizeof(struct extension));
- snprintf(extension->overlay, sizeof(extension->overlay), "overlay%d.dtbo", i);
- snprintf(extension->name, sizeof(extension->name), "extension board %d", i);
- snprintf(extension->owner, sizeof(extension->owner), "sandbox");
- snprintf(extension->version, sizeof(extension->version), "1.1");
- snprintf(extension->other, sizeof(extension->other), "Fictional extension board");
- list_add_tail(&extension->list, extension_list);
+ struct extension extension = {0};
+
+ snprintf(extension.overlay, sizeof(extension.overlay), "overlay%d.dtbo", i);
+ snprintf(extension.name, sizeof(extension.name), "extension board %d", i);
+ snprintf(extension.owner, sizeof(extension.owner), "sandbox");
+ snprintf(extension.version, sizeof(extension.version), "1.1");
+ snprintf(extension.other, sizeof(extension.other), "Fictional extension board");
+ if (!alist_add(extension_list, extension))
+ return -ENOMEM;
}
return i;
}
+
+U_BOOT_EXTENSION(sandbox_extension, sandbox_extension_board_scan);
+
+U_BOOT_DRVINFO(sandbox_extension) = {
+ .name = "sandbox_extension",
+};
#endif
#ifdef CONFIG_BOARD_LATE_INIT
diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index d96b7897b6c..ee82493117a 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -11,4 +11,4 @@ obj-$(CONFIG_SUN7I_GMAC) += gmac.o
obj-$(CONFIG_MACH_SUN4I) += dram_sun4i_auto.o
obj-$(CONFIG_MACH_SUN5I) += dram_sun5i_auto.o
obj-$(CONFIG_MACH_SUN7I) += dram_sun5i_auto.o
-obj-$(CONFIG_CHIP_DIP_SCAN) += chip.o
+obj-$(CONFIG_$(PHASE_)CHIP_DIP_SCAN) += chip.o
diff --git a/board/sunxi/chip.c b/board/sunxi/chip.c
index 270af2506d2..b60a739df41 100644
--- a/board/sunxi/chip.c
+++ b/board/sunxi/chip.c
@@ -40,16 +40,12 @@ struct dip_w1_header {
u8 data[16]; /* user data, per-dip specific */
} __packed;
-int extension_board_scan(struct list_head *extension_list)
+static int sunxi_extension_board_scan(struct udevice *udev,
+ struct alist *extension_list)
{
- struct extension *dip;
- struct dip_w1_header w1_header;
struct udevice *bus, *dev;
- u32 vid;
- u16 pid;
- int ret;
-
int num_dip = 0;
+ int ret;
sunxi_gpio_set_pull(SUNXI_GPD(2), SUNXI_GPIO_PULL_UP);
@@ -60,6 +56,11 @@ int extension_board_scan(struct list_head *extension_list)
}
for_each_w1_device(bus, &dev) {
+ struct extension dip = {0};
+ struct dip_w1_header w1_header;
+ u32 vid;
+ u16 pid;
+
if (w1_get_device_family(dev) != W1_FAMILY_DS2431)
continue;
@@ -82,18 +83,19 @@ int extension_board_scan(struct list_head *extension_list)
w1_header.product_name, pid,
w1_header.vendor_name, vid);
- dip = calloc(1, sizeof(struct extension));
- if (!dip) {
- printf("Error in memory allocation\n");
- return num_dip;
- }
-
- snprintf(dip->overlay, sizeof(dip->overlay), "dip-%x-%x.dtbo",
+ snprintf(dip.overlay, sizeof(dip.overlay), "dip-%x-%x.dtbo",
vid, pid);
- strncpy(dip->name, w1_header.product_name, 32);
- strncpy(dip->owner, w1_header.vendor_name, 32);
- list_add_tail(&dip->list, extension_list);
+ strlcpy(dip.name, w1_header.product_name, sizeof(dip.name));
+ strlcpy(dip.owner, w1_header.vendor_name, sizeof(dip.owner));
+ if (!alist_add(extension_list, dip))
+ return -ENOMEM;
num_dip++;
}
return num_dip;
}
+
+U_BOOT_EXTENSION(dip, sunxi_extension_board_scan);
+
+U_BOOT_DRVINFO(dip) = {
+ .name = "dip",
+};
diff --git a/board/ti/common/Kconfig b/board/ti/common/Kconfig
index f481812247c..9512c5c23f1 100644
--- a/board/ti/common/Kconfig
+++ b/board/ti/common/Kconfig
@@ -20,7 +20,7 @@ config CAPE_EEPROM_BUS_NUM
int "Cape EEPROM's I2C bus address"
range 0 8
default 2
- depends on CMD_EXTENSION
+ depends on SUPPORT_EXTENSION_SCAN
config TI_COMMON_CMD_OPTIONS
bool "Enable cmd options on TI platforms"
diff --git a/board/ti/common/Makefile b/board/ti/common/Makefile
index caf6b9fa8c1..f58935b4103 100644
--- a/board/ti/common/Makefile
+++ b/board/ti/common/Makefile
@@ -2,6 +2,6 @@
# Copyright (C) 2015-2016 Texas Instruments Incorporated - https://www.ti.com/
obj-${CONFIG_TI_I2C_BOARD_DETECT} += board_detect.o
-obj-${CONFIG_CMD_EXTENSION} += cape_detect.o
+obj-${CONFIG_$(PHASE_)SUPPORT_EXTENSION_SCAN} += cape_detect.o
obj-${CONFIG_OF_LIBFDT} += fdt_ops.o
obj-${CONFIG_ARCH_K3} += k3-ddr.o
diff --git a/board/ti/common/cape_detect.c b/board/ti/common/cape_detect.c
index da805befabc..0bd4a38c187 100644
--- a/board/ti/common/cape_detect.c
+++ b/board/ti/common/cape_detect.c
@@ -22,21 +22,21 @@ static void sanitize_field(char *text, size_t size)
}
}
-int extension_board_scan(struct list_head *extension_list)
+static int ti_extension_board_scan(struct udevice *dev,
+ struct alist *extension_list)
{
- struct extension *cape;
- struct am335x_cape_eeprom_id eeprom_header;
-
- int num_capes = 0;
- int ret, i;
- struct udevice *dev;
unsigned char addr;
-
- char process_cape_part_number[17] = {'0'};
- char process_cape_version[5] = {'0'};
- uint8_t cursor = 0;
+ int num_capes = 0;
for (addr = CAPE_EEPROM_FIRST_ADDR; addr <= CAPE_EEPROM_LAST_ADDR; addr++) {
+ struct am335x_cape_eeprom_id eeprom_header;
+ char process_cape_part_number[17] = {'0'};
+ char process_cape_version[5] = {'0'};
+ struct extension cape = {0};
+ struct udevice *dev;
+ u8 cursor = 0;
+ int ret, i;
+
ret = i2c_get_chip_for_busnum(CONFIG_CAPE_EEPROM_BUS_NUM, addr, 1, &dev);
if (ret)
continue;
@@ -59,8 +59,8 @@ int extension_board_scan(struct list_head *extension_list)
sanitize_field(eeprom_header.part_number, sizeof(eeprom_header.part_number));
/* Process cape part_number */
- memset(process_cape_part_number, 0, sizeof(process_cape_part_number));
- strncpy(process_cape_part_number, eeprom_header.part_number, 16);
+ strlcpy(process_cape_part_number, eeprom_header.part_number,
+ sizeof(process_cape_part_number));
/* Some capes end with '.' */
for (i = 15; i >= 0; i--) {
if (process_cape_part_number[i] == '.')
@@ -70,8 +70,8 @@ int extension_board_scan(struct list_head *extension_list)
}
/* Process cape version */
- memset(process_cape_version, 0, sizeof(process_cape_version));
- strncpy(process_cape_version, eeprom_header.version, 4);
+ strlcpy(process_cape_version, eeprom_header.version,
+ sizeof(process_cape_version));
for (i = 0; i < 4; i++) {
if (process_cape_version[i] == 0)
process_cape_version[i] = '0';
@@ -79,19 +79,23 @@ int extension_board_scan(struct list_head *extension_list)
printf("BeagleBone Cape: %s (0x%x)\n", eeprom_header.board_name, addr);
- cape = calloc(1, sizeof(struct extension));
- if (!cape) {
- printf("Error in memory allocation\n");
- return num_capes;
- }
-
- snprintf(cape->overlay, sizeof(cape->overlay), "%s-%s.dtbo",
+ snprintf(cape.overlay, sizeof(cape.overlay), "%s-%s.dtbo",
process_cape_part_number, process_cape_version);
- strncpy(cape->name, eeprom_header.board_name, 32);
- strncpy(cape->version, process_cape_version, 4);
- strncpy(cape->owner, eeprom_header.manufacturer, 16);
- list_add_tail(&cape->list, extension_list);
+ strlcpy(cape.name, eeprom_header.board_name,
+ sizeof(eeprom_header.board_name));
+ strlcpy(cape.version, process_cape_version,
+ sizeof(process_cape_version));
+ strlcpy(cape.owner, eeprom_header.manufacturer,
+ sizeof(eeprom_header.manufacturer) + 1);
+ if (!alist_add(extension_list, cape))
+ return -ENOMEM;
num_capes++;
}
return num_capes;
}
+
+U_BOOT_EXTENSION(cape, ti_extension_board_scan);
+
+U_BOOT_DRVINFO(cape) = {
+ .name = "cape",
+};
diff --git a/boot/Kconfig b/boot/Kconfig
index 9adb051400f..921f096da56 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -1909,6 +1909,10 @@ endmenu
endif # OF_LIBFDT
+config SUPPORT_EXTENSION_SCAN
+ select OF_LIBFDT_OVERLAY
+ bool
+
config USE_BOOTARGS
bool "Enable boot arguments"
help
diff --git a/boot/Makefile b/boot/Makefile
index 3da6f7a0914..7fb56e7ef37 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_BOOT_RETRY) += bootretry.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o bootm_os.o
obj-$(CONFIG_CMD_BOOTZ) += bootm.o bootm_os.o
obj-$(CONFIG_CMD_BOOTI) += bootm.o bootm_os.o
+obj-$(CONFIG_SUPPORT_EXTENSION_SCAN) += extension-uclass.o
obj-$(CONFIG_PXE_UTILS) += pxe_utils.o
diff --git a/boot/bootmeth_efi.c b/boot/bootmeth_efi.c
index 0af23df3a4a..f592fec07f6 100644
--- a/boot/bootmeth_efi.c
+++ b/boot/bootmeth_efi.c
@@ -16,6 +16,7 @@
#include <efi.h>
#include <efi_loader.h>
#include <env.h>
+#include <extension_board.h>
#include <fs.h>
#include <malloc.h>
#include <mapmem.h>
@@ -99,8 +100,11 @@ static int distro_efi_check(struct udevice *dev, struct bootflow_iter *iter)
static int distro_efi_try_bootflow_files(struct udevice *dev,
struct bootflow *bflow)
{
+ ulong fdt_addr, size, overlay_addr;
+ const struct extension *extension;
+ struct fdt_header *working_fdt;
struct blk_desc *desc = NULL;
- ulong fdt_addr, size;
+ struct alist *extension_list;
char fname[256];
int ret, seq;
@@ -148,23 +152,66 @@ static int distro_efi_try_bootflow_files(struct udevice *dev,
return log_msg_ret("fil", -ENOMEM);
}
- if (!ret) {
- bflow->fdt_size = size;
- bflow->fdt_addr = fdt_addr;
-
- /*
- * TODO: Apply extension overlay
- *
- * Here we need to load and apply the extension overlay. This is
- * not implemented. See do_extension_apply(). The extension
- * stuff needs an implementation in boot/extension.c so it is
- * separate from the command code. Really the extension stuff
- * should use the device tree and a uclass / driver interface
- * rather than implementing its own list
- */
- } else {
+ if (ret) {
log_debug("No device tree available\n");
bflow->flags |= BOOTFLOWF_USE_BUILTIN_FDT;
+ return 0;
+ }
+
+ bflow->fdt_size = size;
+ bflow->fdt_addr = fdt_addr;
+
+ if (!CONFIG_IS_ENABLED(SUPPORT_EXTENSION_SCAN))
+ return 0;
+
+ ret = extension_scan();
+ if (ret < 0)
+ return 0;
+
+ extension_list = extension_get_list();
+ if (!extension_list)
+ return 0;
+
+ working_fdt = map_sysmem(fdt_addr, 0);
+ if (fdt_check_header(working_fdt))
+ return 0;
+
+ overlay_addr = env_get_hex("extension_overlay_addr", 0);
+ if (!overlay_addr) {
+ log_debug("Environment extension_overlay_addr is missing\n");
+ return 0;
+ }
+
+ alist_for_each(extension, extension_list) {
+ char *overlay_file;
+ int len;
+
+ len = sizeof(EFI_DIRNAME) + strlen(extension->overlay);
+ overlay_file = calloc(1, len);
+ if (!overlay_file)
+ return -ENOMEM;
+
+ snprintf(overlay_file, len, "%s%s", EFI_DIRNAME,
+ extension->overlay);
+
+ ret = bootmeth_common_read_file(dev, bflow, overlay_file,
+ overlay_addr,
+ (enum bootflow_img_t)IH_TYPE_FLATDT,
+ &size);
+ if (ret) {
+ log_debug("Failed loading overlay %s\n", overlay_file);
+ free(overlay_file);
+ continue;
+ }
+
+ ret = extension_apply(working_fdt, size);
+ if (ret) {
+ log_debug("Failed applying overlay %s\n", overlay_file);
+ free(overlay_file);
+ continue;
+ }
+ bflow->fdt_size += size;
+ free(overlay_file);
}
return 0;
diff --git a/boot/extension-uclass.c b/boot/extension-uclass.c
new file mode 100644
index 00000000000..4b3dd1bc0cd
--- /dev/null
+++ b/boot/extension-uclass.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2025 Köry Maincent <[email protected]>
+ */
+
+#include <alist.h>
+#include <command.h>
+#include <env.h>
+#include <extension_board.h>
+#include <fdt_support.h>
+#include <malloc.h>
+#include <mapmem.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/uclass.h>
+
+struct alist *extension_get_list(void)
+{
+ struct udevice *dev;
+
+ if (uclass_first_device_err(UCLASS_EXTENSION, &dev))
+ return NULL;
+
+ return dev_get_priv(dev);
+}
+
+int extension_probe(struct udevice *dev)
+{
+ struct alist *extension_list = dev_get_priv(dev);
+
+ alist_init_struct(extension_list, struct extension);
+ return 0;
+}
+
+int extension_remove(struct udevice *dev)
+{
+ struct alist *extension_list = dev_get_priv(dev);
+
+ alist_uninit(extension_list);
+ return 0;
+}
+
+int extension_scan(void)
+{
+ struct alist *extension_list = extension_get_list();
+ const struct extension_ops *ops;
+ struct udevice *dev;
+ int ret;
+
+ ret = uclass_first_device_err(UCLASS_EXTENSION, &dev);
+ if (ret)
+ return ret;
+
+ if (!extension_list)
+ return -ENODEV;
+
+ ops = extension_get_ops(dev);
+ alist_empty(extension_list);
+ return ops->scan(dev, extension_list);
+}
+
+int extension_apply(struct fdt_header *working_fdt, ulong size)
+{
+ struct fdt_header *blob;
+ ulong overlay_addr;
+ int ret;
+
+ overlay_addr = env_get_hex("extension_overlay_addr", 0);
+ if (!overlay_addr) {
+ printf("Environment extension_overlay_addr is missing\n");
+ return -EINVAL;
+ }
+
+ fdt_shrink_to_minimum(working_fdt, size);
+
+ blob = map_sysmem(overlay_addr, 0);
+ if (!fdt_valid(&blob)) {
+ printf("Invalid overlay devicetree\n");
+ return -EINVAL;
+ }
+
+ /* Apply method prints messages on error */
+ ret = fdt_overlay_apply_verbose(working_fdt, blob);
+ if (ret)
+ printf("Failed to apply overlay\n");
+
+ return ret;
+}
+
+UCLASS_DRIVER(extension) = {
+ .name = "extension",
+ .id = UCLASS_EXTENSION,
+};
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index eb4d7723481..038416203fc 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -10,6 +10,7 @@
#include <command.h>
#include <dm.h>
#include <env.h>
+#include <extension_board.h>
#include <image.h>
#include <log.h>
#include <malloc.h>
@@ -432,6 +433,95 @@ skip_overlay:
}
#endif
+/*
+ * label_boot_extension - scan extension boards and load overlay associated
+ */
+
+static void label_boot_extension(struct pxe_context *ctx,
+ struct pxe_label *label)
+{
+#if CONFIG_IS_ENABLED(SUPPORT_EXTENSION_SCAN)
+ const struct extension *extension;
+ struct fdt_header *working_fdt;
+ struct alist *extension_list;
+ int ret, dir_len, len;
+ char *overlay_dir;
+ const char *slash;
+ ulong fdt_addr;
+
+ ret = extension_scan();
+ if (ret < 0)
+ return;
+
+ extension_list = extension_get_list();
+ if (!extension_list)
+ return;
+
+ /* Get the main fdt and map it */
+ fdt_addr = env_get_hex("fdt_addr_r", 0);
+ working_fdt = map_sysmem(fdt_addr, 0);
+ if (fdt_check_header(working_fdt))
+ return;
+
+ /* Use fdtdir for now as the overlay devicetree directory */
+ if (label->fdtdir) {
+ len = strlen(label->fdtdir);
+ if (!len)
+ slash = "./";
+ else if (label->fdtdir[len - 1] != '/')
+ slash = "/";
+ else
+ slash = "";
+
+ dir_len = strlen(label->fdtdir) + strlen(slash) + 1;
+ overlay_dir = calloc(1, len);
+ if (!overlay_dir)
+ return;
+
+ snprintf(overlay_dir, dir_len, "%s%s", label->fdtdir,
+ slash);
+ } else {
+ dir_len = 2;
+ snprintf(overlay_dir, dir_len, "/");
+ }
+
+ alist_for_each(extension, extension_list) {
+ char *overlay_file;
+ ulong size;
+
+ len = dir_len + strlen(extension->overlay);
+ overlay_file = calloc(1, len);
+ if (!overlay_file)
+ goto cleanup;
+
+ snprintf(overlay_file, len, "%s%s", overlay_dir,
+ extension->overlay);
+
+ /* Load extension overlay file */
+ ret = get_relfile_envaddr(ctx, overlay_file,
+ "extension_overlay_addr",
+ (enum bootflow_img_t)IH_TYPE_FLATDT,
+ &size);
+ if (ret < 0) {
+ printf("Failed loading overlay %s\n", overlay_file);
+ free(overlay_file);
+ continue;
+ }
+
+ ret = extension_apply(working_fdt, size);
+ if (ret) {
+ printf("Failed applying overlay %s\n", overlay_file);
+ free(overlay_file);
+ continue;
+ }
+ free(overlay_file);
+ }
+
+cleanup:
+ free(overlay_dir);
+#endif
+}
+
/**
* label_boot() - Boot according to the contents of a pxe_label
*
@@ -685,6 +775,8 @@ static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
if (label->fdtoverlays)
label_boot_fdtoverlay(ctx, label);
#endif
+ label_boot_extension(ctx, label);
+
} else {
bootm_argv[3] = NULL;
}
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 9929087a8bb..d9d93c95588 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -545,9 +545,6 @@ config CMD_FDT
help
Do FDT related setup before booting into the Operating System.
-config SUPPORT_EXTENSION_SCAN
- bool
-
config CMD_EXTENSION
bool "Extension board management command"
select CMD_FDT
diff --git a/cmd/extension_board.c b/cmd/extension_board.c
index 317b260bf36..86e4795ba8a 100644
--- a/cmd/extension_board.c
+++ b/cmd/extension_board.c
@@ -4,75 +4,107 @@
* Köry Maincent, Bootlin, <[email protected]>
*/
-#include <bootdev.h>
+#include <alist.h>
+#include <exports.h>
#include <command.h>
-#include <dm.h>
#include <env.h>
-#include <malloc.h>
#include <extension_board.h>
-#include <mapmem.h>
-#include <linux/libfdt.h>
-#include <fdt_support.h>
-static LIST_HEAD(extension_list);
-
-static int extension_apply(struct extension *extension)
+static int
+cmd_extension_load_overlay_from_env(const struct extension *extension,
+ ulong *filesize)
{
+ ulong size, overlay_addr;
char *overlay_cmd;
- ulong extrasize, overlay_addr;
- struct fdt_header *blob;
-
- if (!working_fdt) {
- printf("No FDT memory address configured. Please configure\n"
- "the FDT address via \"fdt addr <address>\" command.\n");
- return CMD_RET_FAILURE;
- }
+ int ret;
overlay_cmd = env_get("extension_overlay_cmd");
if (!overlay_cmd) {
printf("Environment extension_overlay_cmd is missing\n");
- return CMD_RET_FAILURE;
+ return -EINVAL;
}
overlay_addr = env_get_hex("extension_overlay_addr", 0);
if (!overlay_addr) {
printf("Environment extension_overlay_addr is missing\n");
- return CMD_RET_FAILURE;
+ return -EINVAL;
}
env_set("extension_overlay_name", extension->overlay);
- if (run_command(overlay_cmd, 0) != 0)
- return CMD_RET_FAILURE;
+ ret = run_command(overlay_cmd, 0);
+ if (ret)
+ return ret;
- extrasize = env_get_hex("filesize", 0);
- if (!extrasize)
- return CMD_RET_FAILURE;
+ size = env_get_hex("filesize", 0);
+ if (!size)
+ return -EINVAL;
- fdt_shrink_to_minimum(working_fdt, extrasize);
+ *filesize = size;
+ return 0;
+}
- blob = map_sysmem(overlay_addr, 0);
- if (!fdt_valid(&blob))
- return CMD_RET_FAILURE;
+static int cmd_extension_apply(int extension_num)
+{
+ struct alist *extension_list = extension_get_list();
+ const struct extension *extension;
+ ulong size;
+ int ret;
- /* apply method prints messages on error */
- if (fdt_overlay_apply_verbose(working_fdt, blob))
- return CMD_RET_FAILURE;
+ if (!extension_list)
+ return -ENODEV;
- return CMD_RET_SUCCESS;
+ extension = alist_get(extension_list, extension_num,
+ struct extension);
+ if (!extension) {
+ printf("Wrong extension number\n");
+ return -ENODEV;
+ }
+
+ ret = cmd_extension_load_overlay_from_env(extension, &size);
+ if (ret)
+ return ret;
+
+ return extension_apply(working_fdt, size);
+}
+
+static int cmd_extension_apply_all(void)
+{
+ struct alist *extension_list = extension_get_list();
+ const struct extension *extension;
+ int ret;
+
+ if (!extension_list)
+ return -ENODEV;
+
+ alist_for_each(extension, extension_list) {
+ ulong size;
+
+ ret = cmd_extension_load_overlay_from_env(extension, &size);
+ if (ret)
+ return ret;
+
+ ret = extension_apply(working_fdt, size);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
}
static int do_extension_list(struct cmd_tbl *cmdtp, int flag,
int argc, char *const argv[])
{
- int i = 0;
+ struct alist *extension_list;
struct extension *extension;
+ int i = 0;
- if (list_empty(&extension_list)) {
+ extension_list = extension_get_list();
+ if (!alist_get_ptr(extension_list, 0)) {
printf("No extension registered - Please run \"extension scan\"\n");
return CMD_RET_SUCCESS;
}
- list_for_each_entry(extension, &extension_list, list) {
+ alist_for_each(extension, extension_list) {
printf("Extension %d: %s\n", i++, extension->name);
printf("\tManufacturer: \t\t%s\n", extension->owner);
printf("\tVersion: \t\t%s\n", extension->version);
@@ -82,71 +114,45 @@ static int do_extension_list(struct cmd_tbl *cmdtp, int flag,
return CMD_RET_SUCCESS;
}
-static int extension_scan(bool show)
-{
- struct extension *extension, *next;
- int extension_num;
-
- list_for_each_entry_safe(extension, next, &extension_list, list) {
- list_del(&extension->list);
- free(extension);
- }
- extension_num = extension_board_scan(&extension_list);
- if (show && extension_num >= 0)
- printf("Found %d extension board(s).\n", extension_num);
-
- /* either the number of extensions, or -ve for error */
- return extension_num;
-}
-
static int do_extension_scan(struct cmd_tbl *cmdtp, int flag,
int argc, char *const argv[])
{
int extension_num;
- extension_num = extension_scan(true);
- if (extension_num < 0)
+ extension_num = extension_scan();
+ if (extension_num == -ENODEV)
+ extension_num = 0;
+ else if (extension_num < 0)
return CMD_RET_FAILURE;
+ printf("Found %d extension board(s).\n", extension_num);
return CMD_RET_SUCCESS;
}
static int do_extension_apply(struct cmd_tbl *cmdtp, int flag,
int argc, char *const argv[])
{
- struct extension *extension = NULL;
- struct list_head *entry;
- int i = 0, extension_id, ret;
+ int extension_id;
if (argc < 2)
return CMD_RET_USAGE;
+ if (!working_fdt) {
+ printf("No FDT memory address configured. Please configure\n"
+ "the FDT address via \"fdt addr <address>\" command.\n");
+ return -EINVAL;
+ }
+
if (strcmp(argv[1], "all") == 0) {
- ret = CMD_RET_FAILURE;
- list_for_each_entry(extension, &extension_list, list) {
- ret = extension_apply(extension);
- if (ret != CMD_RET_SUCCESS)
- break;
- }
+ if (cmd_extension_apply_all())
+ return CMD_RET_FAILURE;
} else {
extension_id = simple_strtol(argv[1], NULL, 10);
- list_for_each(entry, &extension_list) {
- if (i == extension_id) {
- extension = list_entry(entry, struct extension, list);
- break;
- }
- i++;
- }
-
- if (!extension) {
- printf("Wrong extension number\n");
+ if (cmd_extension_apply(extension_id))
return CMD_RET_FAILURE;
- }
-
- ret = extension_apply(extension);
}
- return ret;
+ return CMD_RET_SUCCESS;
}
static struct cmd_tbl cmd_extension[] = {
@@ -177,26 +183,3 @@ U_BOOT_CMD(extension, 3, 1, do_extensionops,
"extension list - lists available extension(s) board(s)\n"
"extension apply <extension number|all> - applies DT overlays corresponding to extension boards\n"
);
-
-static int extension_bootdev_hunt(struct bootdev_hunter *info, bool show)
-{
- int ret;
-
- ret = env_set_hex("extension_overlay_addr",
- env_get_hex("fdtoverlay_addr_r", 0));
- if (ret)
- return log_msg_ret("env", ret);
-
- ret = extension_scan(show);
- if (ret < 0)
- return log_msg_ret("ext", ret);
-
- return 0;
-}
-
-/* extensions should have a uclass - for now we use UCLASS_SIMPLE_BUS uclass */
-BOOTDEV_HUNTER(extension_bootdev_hunter) = {
- .prio = BOOTDEVP_1_PRE_SCAN,
- .uclass = UCLASS_SIMPLE_BUS,
- .hunt = extension_bootdev_hunt,
-};
diff --git a/doc/usage/cmd/extension.rst b/doc/usage/cmd/extension.rst
index 4c261e74951..fbe95aace79 100644
--- a/doc/usage/cmd/extension.rst
+++ b/doc/usage/cmd/extension.rst
@@ -25,9 +25,8 @@ Device Tree overlays depending on the detected extension boards.
The "extension" command comes with three sub-commands:
- - "extension scan" makes the generic code call the board-specific
- extension_board_scan() function to retrieve the list of detected
- extension boards.
+ - "extension scan" makes the generic code call a board-specific extension
+ function to retrieve the list of detected extension boards.
- "extension list" allows to list the detected extension boards.
@@ -98,17 +97,23 @@ Simple extension_board_scan function example
.. code-block:: c
- int extension_board_scan(struct list_head *extension_list)
+ static int foo_extension_board_scan(struct alist *extension_list)
{
- struct extension *extension;
+ struct extension extension = {0};
- extension = calloc(1, sizeof(struct extension));
- snprintf(extension->overlay, sizeof(extension->overlay), "overlay.dtbo");
- snprintf(extension->name, sizeof(extension->name), "extension board");
- snprintf(extension->owner, sizeof(extension->owner), "sandbox");
- snprintf(extension->version, sizeof(extension->version), "1.1");
- snprintf(extension->other, sizeof(extension->other), "Extension board information");
- list_add_tail(&extension->list, extension_list);
+ snprintf(extension.overlay, sizeof(extension.overlay), "overlay.dtbo");
+ snprintf(extension.name, sizeof(extension.name), "extension board");
+ snprintf(extension.owner, sizeof(extension.owner), "sandbox");
+ snprintf(extension.version, sizeof(extension.version), "1.1");
+ snprintf(extension.other, sizeof(extension.other), "Extension board information");
+ if (!alist_add(extension_list, extension))
+ return -ENOMEM;
return 1;
}
+
+ U_BOOT_EXTENSION(foo_extension_name, foo_extension_board_scan);
+
+ U_BOOT_DRVINFO(foo_extension_name) = {
+ .name = "foo_extension_name",
+ };
diff --git a/doc/usage/pxe.rst b/doc/usage/pxe.rst
index c2dc11f218d..18532f182d5 100644
--- a/doc/usage/pxe.rst
+++ b/doc/usage/pxe.rst
@@ -103,6 +103,10 @@ Environment
``fdt_addr_r``. Required to use the ``fdtoverlays`` command in
the PXE file.
+``extension_overlay_addr``
+ Location in RAM to temporarily store extension fdt overlay(s)
+ before applying them to the fdt blob stored at ``fdt_addr_r``.
+
``pxe_label_override``
Override label to be used, if exists, instead of the default
label. This will allow consumers to choose a pxe label at
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 6be59093160..eb6416b5917 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -63,6 +63,7 @@ enum uclass_id {
UCLASS_ETH, /* Ethernet device */
UCLASS_ETH_PHY, /* Ethernet PHY device */
UCLASS_EXTCON, /* External Connector Class */
+ UCLASS_EXTENSION, /* Extension board */
UCLASS_FFA, /* Arm Firmware Framework for Armv8-A */
UCLASS_FFA_EMUL, /* sandbox FF-A device emulator */
UCLASS_FIRMWARE, /* Firmware */
diff --git a/include/extension_board.h b/include/extension_board.h
index 22e4104bc54..0b9fb99ad7d 100644
--- a/include/extension_board.h
+++ b/include/extension_board.h
@@ -7,10 +7,58 @@
#ifndef __EXTENSION_SUPPORT_H
#define __EXTENSION_SUPPORT_H
+#include <alist.h>
+#include <dm/device.h>
#include <linux/list.h>
+#include <dm/platdata.h>
+extern struct list_head extension_list;
+
+/**
+ * extension_get_list - Get the extension list
+ * Return: The extension alist pointer, or NULL if no such list exists.
+ *
+ * The caller must not free the list.
+ */
+struct alist *extension_get_list(void);
+
+/**
+ * extension_probe - Probe extension device
+ * @dev: Extension device that needs to be probed
+ * Return: Zero on success, negative on failure.
+ */
+int extension_probe(struct udevice *dev);
+
+/**
+ * extension_remove - Remove extension device
+ * @dev: Extension device that needs to be removed
+ * Return: Zero on success, negative on failure.
+ */
+int extension_remove(struct udevice *dev);
+
+/**
+ * extension_scan - Scan extension boards available.
+ * Return: Zero on success, negative on failure.
+ */
+int extension_scan(void);
+
+/**
+ * extension_apply - Apply extension board overlay to the devicetree
+ * @working_fdt: Pointer to working flattened device tree
+ * @size: Size of the devicetree overlay
+ * Return: Zero on success, negative on failure.
+ */
+int extension_apply(struct fdt_header *working_fdt, ulong size);
+
+/**
+ * extension - Description fields of an extension board
+ * @name: Name of the extension
+ * @owner: Owner of the extension
+ * @version: Version of the extension
+ * @overlay: Devicetree overlay name to be loaded for this extension
+ * @other: Other information of this extension
+ */
struct extension {
- struct list_head list;
char name[32];
char owner[32];
char version[32];
@@ -18,16 +66,30 @@ struct extension {
char other[32];
};
-/**
- * extension_board_scan - Add system-specific function to scan extension board.
- * @param extension_list List of extension board information to update.
- * Return: the number of extension.
- *
- * This function is called if CONFIG_CMD_EXTENSION is defined.
- * Needs to fill the list extension_list with elements.
- * Each element need to be allocated to an extension structure.
- *
- */
-int extension_board_scan(struct list_head *extension_list);
+struct extension_ops {
+ /**
+ * scan - Add system-specific function to scan extension boards.
+ * @dev: extension device
+ * @extension_list: alist of extension to expand
+ * Return: The number of extension or a negative value in case of
+ * error.
+ */
+ int (*scan)(struct udevice *dev, struct alist *extension_list);
+};
+
+#define extension_get_ops(dev) ((struct extension_ops *)(dev)->driver->ops)
+
+/* Currently, only one extension driver enabled at a time is supported */
+#define U_BOOT_EXTENSION(_name, _scan_func) \
+ U_BOOT_DRIVER(_name) = { \
+ .name = #_name, \
+ .id = UCLASS_EXTENSION, \
+ .probe = extension_probe, \
+ .remove = extension_remove, \
+ .ops = &(struct extension_ops) { \
+ .scan = _scan_func, \
+ }, \
+ .priv_auto = sizeof(struct alist), \
+ }
#endif /* __EXTENSION_SUPPORT_H */
diff --git a/test/boot/bootdev.c b/test/boot/bootdev.c
index a5f3d4462a9..0820bf10ee0 100644
--- a/test/boot/bootdev.c
+++ b/test/boot/bootdev.c
@@ -380,7 +380,6 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
ut_assert_nextline("Prio Used Uclass Hunter");
ut_assert_nextlinen("----");
ut_assert_nextline(" 6 ethernet eth_bootdev");
- ut_assert_nextline(" 1 simple_bus (none)");
ut_assert_nextline(" 5 ide ide_bootdev");
ut_assert_nextline(" 2 mmc mmc_bootdev");
ut_assert_nextline(" 4 nvme nvme_bootdev");
@@ -389,15 +388,15 @@ static int bootdev_test_hunter(struct unit_test_state *uts)
ut_assert_nextline(" 4 spi_flash sf_bootdev");
ut_assert_nextline(" 5 usb usb_bootdev");
ut_assert_nextline(" 4 virtio virtio_bootdev");
- ut_assert_nextline("(total hunters: 10)");
+ ut_assert_nextline("(total hunters: 9)");
ut_assert_console_end();
ut_assertok(bootdev_hunt("usb1", false));
ut_assert_skip_to_line("Bus usb@1: 5 USB Device(s) found");
ut_assert_console_end();
- /* USB is 7th in the list, so bit 8 */
- ut_asserteq(BIT(8), std->hunters_used);
+ /* USB is 8th in the list, so bit 7 */
+ ut_asserteq(BIT(7), std->hunters_used);
return 0;
}
@@ -418,7 +417,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
ut_assert_nextline("Prio Used Uclass Hunter");
ut_assert_nextlinen("----");
ut_assert_nextline(" 6 ethernet eth_bootdev");
- ut_assert_skip_to_line("(total hunters: 10)");
+ ut_assert_skip_to_line("(total hunters: 9)");
ut_assert_console_end();
/* Use the MMC hunter and see that it updates */
@@ -426,7 +425,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
ut_assertok(run_command("bootdev hunt -l", 0));
ut_assert_skip_to_line(" 5 ide ide_bootdev");
ut_assert_nextline(" 2 * mmc mmc_bootdev");
- ut_assert_skip_to_line("(total hunters: 10)");
+ ut_assert_skip_to_line("(total hunters: 9)");
ut_assert_console_end();
/* Scan all hunters */
@@ -436,8 +435,6 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
ut_assert_nextline("Hunting with: ethernet");
/* This is the extension feature which has no uclass at present */
- ut_assert_nextline("Hunting with: simple_bus");
- ut_assert_nextline("Found 2 extension board(s).");
ut_assert_nextline("Hunting with: ide");
/* mmc hunter has already been used so should not run again */
@@ -457,7 +454,6 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
ut_assert_nextlinen("Prio");
ut_assert_nextlinen("----");
ut_assert_nextline(" 6 * ethernet eth_bootdev");
- ut_assert_nextline(" 1 * simple_bus (none)");
ut_assert_nextline(" 5 * ide ide_bootdev");
ut_assert_nextline(" 2 * mmc mmc_bootdev");
ut_assert_nextline(" 4 * nvme nvme_bootdev");
@@ -466,7 +462,7 @@ static int bootdev_test_cmd_hunt(struct unit_test_state *uts)
ut_assert_nextline(" 4 * spi_flash sf_bootdev");
ut_assert_nextline(" 5 * usb usb_bootdev");
ut_assert_nextline(" 4 * virtio virtio_bootdev");
- ut_assert_nextline("(total hunters: 10)");
+ ut_assert_nextline("(total hunters: 9)");
ut_assert_console_end();
ut_asserteq(GENMASK(MAX_HUNTER, 0), std->hunters_used);
@@ -490,7 +486,7 @@ static int bootdev_test_hunt_scan(struct unit_test_state *uts)
ut_assertok(bootflow_scan_first(NULL, NULL, &iter,
BOOTFLOWIF_SHOW | BOOTFLOWIF_HUNT |
BOOTFLOWIF_SKIP_GLOBAL, &bflow));
- ut_asserteq(BIT(MMC_HUNTER) | BIT(1), std->hunters_used);
+ ut_asserteq(BIT(MMC_HUNTER), std->hunters_used);
return 0;
}
@@ -650,8 +646,8 @@ static int bootdev_test_next_label(struct unit_test_state *uts)
ut_asserteq_str("scsi.id0lun0.bootdev", dev->name);
ut_asserteq(BOOTFLOW_METHF_SINGLE_UCLASS, mflags);
- /* SCSI is 7th in the list, so bit 6 */
- ut_asserteq(BIT(MMC_HUNTER) | BIT(6), std->hunters_used);
+ /* SCSI is 6th in the list, so bit 5 */
+ ut_asserteq(BIT(MMC_HUNTER) | BIT(5), std->hunters_used);
ut_assertok(bootdev_next_label(&iter, &dev, &mflags));
ut_assert_console_end();
@@ -661,7 +657,7 @@ static int bootdev_test_next_label(struct unit_test_state *uts)
mflags);
/* dhcp: Ethernet is first so bit 0 */
- ut_asserteq(BIT(MMC_HUNTER) | BIT(6) | BIT(0), std->hunters_used);
+ ut_asserteq(BIT(MMC_HUNTER) | BIT(5) | BIT(0), std->hunters_used);
ut_assertok(bootdev_next_label(&iter, &dev, &mflags));
ut_assert_console_end();
@@ -671,7 +667,7 @@ static int bootdev_test_next_label(struct unit_test_state *uts)
mflags);
/* pxe: Ethernet is first so bit 0 */
- ut_asserteq(BIT(MMC_HUNTER) | BIT(6) | BIT(0), std->hunters_used);
+ ut_asserteq(BIT(MMC_HUNTER) | BIT(5) | BIT(0), std->hunters_used);
mflags = 123;
ut_asserteq(-ENODEV, bootdev_next_label(&iter, &dev, &mflags));
@@ -679,7 +675,7 @@ static int bootdev_test_next_label(struct unit_test_state *uts)
ut_assert_console_end();
/* no change */
- ut_asserteq(BIT(MMC_HUNTER) | BIT(6) | BIT(0), std->hunters_used);
+ ut_asserteq(BIT(MMC_HUNTER) | BIT(5) | BIT(0), std->hunters_used);
return 0;
}
@@ -724,12 +720,10 @@ static int bootdev_test_next_prio(struct unit_test_state *uts)
ut_assertok(bootdev_next_prio(&iter, &dev));
ut_asserteq_str("mmc2.bootdev", dev->name);
- ut_assert_nextline("Hunting with: simple_bus");
- ut_assert_nextline("Found 2 extension board(s).");
ut_assert_nextline("Hunting with: mmc");
ut_assert_console_end();
- ut_asserteq(BIT(MMC_HUNTER) | BIT(1), std->hunters_used);
+ ut_asserteq(BIT(MMC_HUNTER), std->hunters_used);
ut_assertok(bootdev_next_prio(&iter, &dev));
ut_asserteq_str("mmc1.bootdev", dev->name);
diff --git a/test/boot/bootflow.c b/test/boot/bootflow.c
index cc5eed75d83..a56435d053f 100644
--- a/test/boot/bootflow.c
+++ b/test/boot/bootflow.c
@@ -861,7 +861,7 @@ static int bootflow_cmd_hunt_single(struct unit_test_state *uts)
ut_assert_console_end();
/* check that the hunter was used */
- ut_asserteq(BIT(MMC_HUNTER) | BIT(1), std->hunters_used);
+ ut_asserteq(BIT(MMC_HUNTER), std->hunters_used);
return 0;
}
@@ -883,14 +883,12 @@ static int bootflow_cmd_hunt_label(struct unit_test_state *uts)
ut_assertok(run_command("bootflow scan -l mmc", 0));
/* check that the hunter was used */
- ut_asserteq(BIT(MMC_HUNTER) | BIT(1), std->hunters_used);
+ ut_asserteq(BIT(MMC_HUNTER), std->hunters_used);
/* check that we got the mmc1 bootflow */
ut_assert_nextline("Scanning for bootflows with label 'mmc'");
ut_assert_nextlinen("Seq");
ut_assert_nextlinen("---");
- ut_assert_nextline("Hunting with: simple_bus");
- ut_assert_nextline("Found 2 extension board(s).");
ut_assert_nextline("Hunting with: mmc");
ut_assert_nextline("Scanning bootdev 'mmc2.bootdev':");
ut_assert_nextline("Scanning bootdev 'mmc1.bootdev':");
diff --git a/test/boot/bootstd_common.h b/test/boot/bootstd_common.h
index c61698adc02..dd769313a84 100644
--- a/test/boot/bootstd_common.h
+++ b/test/boot/bootstd_common.h
@@ -21,8 +21,8 @@
#define TEST_VERNUM 0x00010002
enum {
- MAX_HUNTER = 9,
- MMC_HUNTER = 3, /* ID of MMC hunter */
+ MAX_HUNTER = 8,
+ MMC_HUNTER = 2, /* ID of MMC hunter */
};
struct unit_test_state;