diff options
author | Tom Rini <trini@konsulko.com> | 2025-10-09 13:50:59 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2025-10-09 13:50:59 -0600 |
commit | 8cc77c78b0bc44aab44aa00e9a0ceab14ffe2017 (patch) | |
tree | d2d86c319404adb0d6311615c9c513983dcfc51d /lib | |
parent | a1fd7a9589bf150c6f79d3a37fbc426f00a8af94 (diff) | |
parent | 50fc92938623be4a1cf1993c703812643afc9cdd (diff) |
Merge patch series "fw_loader: Split from fs_loader into separate library file"
This series from Marek Vasut <marek.vasut+renesas@mailbox.org> splits
the fw_loader "script" code out from the fs_loader code as the former
does not require the latter.
Link: https://lore.kernel.org/r/20250922114926.51984-1-marek.vasut+renesas@mailbox.org
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig | 8 | ||||
-rw-r--r-- | lib/Makefile | 2 | ||||
-rw-r--r-- | lib/fw_loader.c | 63 |
3 files changed, 73 insertions, 0 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index 7e48b179f6d..f5c1731f456 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -71,6 +71,14 @@ config DYNAMIC_CRC_TABLE Enable this option to calculate entries for CRC tables at runtime. This can be helpful when reducing the size of the build image +config FW_LOADER + bool "Enable firmware loader using environment script" + depends on CMDLINE + depends on ENV_SUPPORT + help + Enable this option to make firmware loading using user-provided + U-Boot environment script functionality accessible to U-Boot code. + config HAVE_ARCH_IOMAP bool help diff --git a/lib/Makefile b/lib/Makefile index 2643bfc867c..a2e60668864 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -22,6 +22,8 @@ obj-$(CONFIG_AES) += aes.o obj-$(CONFIG_AES) += aes/ obj-$(CONFIG_$(PHASE_)BINMAN_FDT) += binman.o +obj-$(CONFIG_FW_LOADER) += fw_loader.o + ifndef API_BUILD ifneq ($(CONFIG_CHARSET),) obj-y += charset.o diff --git a/lib/fw_loader.c b/lib/fw_loader.c new file mode 100644 index 00000000000..f776e09523a --- /dev/null +++ b/lib/fw_loader.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2025 Lucien Jheng <lucienzx159@gmail.com> + */ + +#include <command.h> +#include <env.h> +#include <errno.h> +#include <linux/types.h> +#include <log.h> + +int request_firmware_into_buf_via_script(void *buf, size_t max_size, + const char *script_name, + size_t *retsize) +{ + char env_addr[CONFIG_SYS_CBSIZE] = { 0 }; + char env_size[CONFIG_SYS_CBSIZE] = { 0 }; + char *args[2] = { "run", (char *)script_name }; + int ret, repeatable; + ulong addr, size; + + if (!buf || !script_name || !max_size) + return -EINVAL; + + /* Run the firmware loading script */ + ret = cmd_process(0, 2, args, &repeatable, NULL); + if (ret) { + log_err("Firmware loading script '%s' not defined or failed.\n", + script_name); + return -EINVAL; + } + + /* Prefix the FW loader variables with the script prefix */ + snprintf(env_addr, sizeof(env_addr), "%s_addr", script_name); + snprintf(env_size, sizeof(env_size), "%s_size", script_name); + + /* Find out where the firmware got loaded and how long it is */ + addr = env_get_hex(env_addr, 0); + size = env_get_hex(env_size, 0); + + /* Clear the variables set by the firmware loading script */ + env_set(env_addr, NULL); + env_set(env_size, NULL); + + if (!addr || !size) { + log_err("Firmware address (0x%lx) or size (0x%lx) are invalid.\n", + addr, size); + return -EINVAL; + } + + if (size > max_size) { + log_err("Loaded firmware size 0x%lx exceeded maximum allowed size 0x%zx.\n", + size, max_size); + return -E2BIG; + } + + if (retsize) + *retsize = size; + + memcpy(buf, (void *)addr, size); + + return 0; +} |