fw_loader: Split from fs_loader into separate library file

The script based firmware loader does not use anything from the
fs_loader implementation. Separate it into its own library source
file and convert the mediatek PHY to use this separate code. This
should reduce the amount of code that is pulled in alongside the
firmware loader, as the FS loader is no longer included.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
This commit is contained in:
Marek Vasut
2025-09-22 13:48:27 +02:00
committed by Tom Rini
parent a1fd7a9589
commit 8aa57934e5
8 changed files with 103 additions and 74 deletions

View File

@@ -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];

View File

@@ -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.

View File

@@ -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>

View File

@@ -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

34
include/fw_loader.h Normal file
View File

@@ -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

View File

@@ -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

View File

@@ -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

57
lib/fw_loader.c Normal file
View File

@@ -0,0 +1,57 @@
// 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 *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;
}