summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMarek Vasut <[email protected]>2025-09-22 13:48:27 +0200
committerTom Rini <[email protected]>2025-10-09 13:50:40 -0600
commit8aa57934e52f254064338cfb2a445af9a1f592f9 (patch)
tree54581ff7e27dc1839b7d2adf7e31f821c79a08b7 /lib
parenta1fd7a9589bf150c6f79d3a37fbc426f00a8af94 (diff)
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 <[email protected]>
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig8
-rw-r--r--lib/Makefile2
-rw-r--r--lib/fw_loader.c57
3 files changed, 67 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..207f5fadd1e
--- /dev/null
+++ b/lib/fw_loader.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 Lucien Jheng <[email protected]>
+ */
+
+#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;
+}