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 | |
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
-rw-r--r-- | drivers/misc/fs_loader.c | 47 | ||||
-rw-r--r-- | drivers/net/phy/mediatek/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/phy/mediatek/mtk-2p5ge.c | 2 | ||||
-rw-r--r-- | include/fs_loader.h | 25 | ||||
-rw-r--r-- | include/fw_loader.h | 34 | ||||
-rw-r--r-- | lib/Kconfig | 8 | ||||
-rw-r--r-- | lib/Makefile | 2 | ||||
-rw-r--r-- | lib/fw_loader.c | 63 |
8 files changed, 109 insertions, 74 deletions
diff --git a/drivers/misc/fs_loader.c b/drivers/misc/fs_loader.c index d641647e040..2928cf75f89 100644 --- a/drivers/misc/fs_loader.c +++ b/drivers/misc/fs_loader.c @@ -228,53 +228,6 @@ int request_firmware_into_buf(struct udevice *dev, return ret; } -int request_firmware_into_buf_via_script(void *buf, size_t max_size, - const char *script_name, - size_t *retsize) -{ - 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; - } - - /* Find out where the firmware got loaded and how long it is */ - addr = env_get_hex("fw_addr", 0); - size = env_get_hex("fw_size", 0); - - /* Clear the variables set by the firmware loading script */ - env_set("fw_addr", NULL); - env_set("fw_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; -} - static int fs_loader_of_to_plat(struct udevice *dev) { u32 phandlepart[2]; diff --git a/drivers/net/phy/mediatek/Kconfig b/drivers/net/phy/mediatek/Kconfig index bbda951e7d9..933271f01fa 100644 --- a/drivers/net/phy/mediatek/Kconfig +++ b/drivers/net/phy/mediatek/Kconfig @@ -6,8 +6,8 @@ config MTK_NET_PHYLIB config PHY_MEDIATEK_2P5GE bool "MediaTek built-in 2.5Gb ethernet PHYs" depends on OF_CONTROL && (TARGET_MT7987 || TARGET_MT7988) + select FW_LOADER select MTK_NET_PHYLIB - select FS_LOADER help Supports MediaTek SoC built-in 2.5Gb ethernet PHYs. diff --git a/drivers/net/phy/mediatek/mtk-2p5ge.c b/drivers/net/phy/mediatek/mtk-2p5ge.c index 0e704bdb04d..4090db0b474 100644 --- a/drivers/net/phy/mediatek/mtk-2p5ge.c +++ b/drivers/net/phy/mediatek/mtk-2p5ge.c @@ -10,7 +10,7 @@ #include <dm/of_access.h> #include <dm/pinctrl.h> #include <dm/ofnode.h> -#include <fs_loader.h> +#include <fw_loader.h> #include <linux/bitfield.h> #include <linux/delay.h> #include <linux/iopoll.h> diff --git a/include/fs_loader.h b/include/fs_loader.h index 3afd9e62b4a..7e16e0f7030 100644 --- a/include/fs_loader.h +++ b/include/fs_loader.h @@ -65,29 +65,4 @@ int request_firmware_into_buf(struct udevice *dev, */ int get_fs_loader(struct udevice **dev); -/** - * request_firmware_into_buf_via_script() - - * Load firmware using a U-Boot script and copy to buffer - * @buf: Pointer to a pointer where the firmware buffer will be stored. - * @max_size: Maximum allowed size for the firmware to be loaded. - * @script_name: Name of the U-Boot script to execute for firmware loading. - * @retsize: Return the actual firmware data size (optional). - * - * Executes a U-Boot script (@script_name) that loads firmware into - * memory and sets the environment variables 'fw_addr' (address) and - * 'fw_size' (size in bytes). On success, copies the firmware - * from the given address to user buffer @buf. - * - * The script must set these environment variables: - * fw_addr - Address where firmware is loaded in memory - * fw_size - Size of the firmware in bytes - * - * The script should be defined in the U-Boot environment, for example: - * env set script_name 'load mmc 0:1 ${loadaddr} firmware.bin && - * env set fw_addr ${loadaddr} && env set fw_size ${filesize} - * Return: 0 on success, negative value on error. - */ -int request_firmware_into_buf_via_script(void *buf, size_t max_size, - const char *script_name, - size_t *retsize); #endif diff --git a/include/fw_loader.h b/include/fw_loader.h new file mode 100644 index 00000000000..35574482b2b --- /dev/null +++ b/include/fw_loader.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2025 Lucien Jheng <lucienzx159@gmail.com> + */ +#ifndef _FW_LOADER_H_ +#define _FW_LOADER_H_ + +/** + * request_firmware_into_buf_via_script() - + * Load firmware using a U-Boot script and copy to buffer + * @buf: Pointer to a pointer where the firmware buffer will be stored. + * @max_size: Maximum allowed size for the firmware to be loaded. + * @script_name: Name of the U-Boot script to execute for firmware loading. + * @retsize: Return the actual firmware data size (optional). + * + * Executes a U-Boot script (@script_name) that loads firmware into + * memory and sets the environment variables 'fw_addr' (address) and + * 'fw_size' (size in bytes). On success, copies the firmware + * from the given address to user buffer @buf. + * + * The script must set these environment variables: + * fw_addr - Address where firmware is loaded in memory + * fw_size - Size of the firmware in bytes + * + * The script should be defined in the U-Boot environment, for example: + * env set script_name 'load mmc 0:1 ${loadaddr} firmware.bin && + * env set fw_addr ${loadaddr} && env set fw_size ${filesize} + * Return: 0 on success, negative value on error. + */ +int request_firmware_into_buf_via_script(void *buf, size_t max_size, + const char *script_name, + size_t *retsize); + +#endif 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; +} |