diff options
| author | Kory Maincent (TI.com) <[email protected]> | 2025-10-30 17:45:01 +0100 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2025-11-03 10:02:39 -0600 |
| commit | 78a06090f4860d52dfd1577619f53a7ec75122c9 (patch) | |
| tree | b0c3de30b114003baf8ffe4c1583d81fdd9a9a6b /boot | |
| parent | b7edeac950dae10759527a1ed0d1c306710ec9de (diff) | |
boot: Add UCLASS support for extension boards
Introduce UCLASS-based extension board support to enable more
standardized and automatic loading of extension board device tree
overlays in preparation for integration with bootstd and pxe_utils.
Several #if CONFIG_IS_ENABLED are used in cmd/extension_board.c to ease the
development but don't worry they are removed later in the series.
Signed-off-by: Kory Maincent (TI.com) <[email protected]>
Reviewed-by: Simon Glass <[email protected]>
Diffstat (limited to 'boot')
| -rw-r--r-- | boot/Kconfig | 4 | ||||
| -rw-r--r-- | boot/Makefile | 1 | ||||
| -rw-r--r-- | boot/extension-uclass.c | 151 |
3 files changed, 156 insertions, 0 deletions
diff --git a/boot/Kconfig b/boot/Kconfig index a75f6b641ed..08d666d4b93 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -1910,6 +1910,10 @@ config SUPPORT_EXTENSION_SCAN select OF_LIBFDT_OVERLAY bool +config SUPPORT_DM_EXTENSION_SCAN + select OF_LIBFDT_OVERLAY + bool + config USE_BOOTARGS bool "Enable boot arguments" help diff --git a/boot/Makefile b/boot/Makefile index f60d13130b1..aa26070fbb8 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -10,6 +10,7 @@ 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.o +obj-$(CONFIG_SUPPORT_DM_EXTENSION_SCAN) += extension-uclass.o obj-$(CONFIG_PXE_UTILS) += pxe_utils.o diff --git a/boot/extension-uclass.c b/boot/extension-uclass.c new file mode 100644 index 00000000000..914971215af --- /dev/null +++ b/boot/extension-uclass.c @@ -0,0 +1,151 @@ +// 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 *dm_extension_get_list(void) +{ + struct udevice *dev; + + if (uclass_first_device_err(UCLASS_EXTENSION, &dev)) + return NULL; + + return dev_get_priv(dev); +} + +int dm_extension_probe(struct udevice *dev) +{ + struct alist *extension_list = dev_get_priv(dev); + + alist_init_struct(extension_list, struct extension); + return 0; +} + +int dm_extension_remove(struct udevice *dev) +{ + struct alist *extension_list = dev_get_priv(dev); + + alist_uninit(extension_list); + return 0; +} + +int dm_extension_scan(void) +{ + struct alist *extension_list = dm_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); +} + +static int _extension_apply(const struct extension *extension) +{ + ulong extrasize, overlay_addr; + struct fdt_header *blob; + char *overlay_cmd; + int ret; + + if (!working_fdt) { + printf("No FDT memory address configured. Please configure\n" + "the FDT address via \"fdt addr <address>\" command.\n"); + return -EINVAL; + } + + overlay_cmd = env_get("extension_overlay_cmd"); + if (!overlay_cmd) { + printf("Environment extension_overlay_cmd is missing\n"); + return -EINVAL; + } + + overlay_addr = env_get_hex("extension_overlay_addr", 0); + if (!overlay_addr) { + printf("Environment extension_overlay_addr is missing\n"); + return -EINVAL; + } + + env_set("extension_overlay_name", extension->overlay); + ret = run_command(overlay_cmd, 0); + if (ret) + return ret; + + extrasize = env_get_hex("filesize", 0); + if (!extrasize) + return -EINVAL; + + fdt_shrink_to_minimum(working_fdt, extrasize); + + blob = map_sysmem(overlay_addr, 0); + if (!fdt_valid(&blob)) { + printf("Invalid overlay devicetree %s\n", extension->overlay); + return -EINVAL; + } + + /* Apply method prints messages on error */ + ret = fdt_overlay_apply_verbose(working_fdt, blob); + if (ret) + printf("Failed to apply overlay %s\n", extension->overlay); + + return ret; +} + +int dm_extension_apply(int extension_num) +{ + struct alist *extension_list = dm_extension_get_list(); + const struct extension *extension; + + if (!extension_list) + return -ENOENT; + + extension = alist_get(extension_list, extension_num, + struct extension); + if (!extension) { + printf("Wrong extension number\n"); + return -EINVAL; + } + + return _extension_apply(extension); +} + +int dm_extension_apply_all(void) +{ + struct alist *extension_list = dm_extension_get_list(); + const struct extension *extension; + int ret; + + if (!extension_list) + return -ENOENT; + + alist_for_each(extension, extension_list) { + ret = _extension_apply(extension); + if (ret) + return ret; + } + + return 0; +} + +UCLASS_DRIVER(extension) = { + .name = "extension", + .id = UCLASS_EXTENSION, +}; |
