Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Feb 2024 16:37:05 GMT
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 479905a1ed26 - main - firmware: Allow binary files to be loaded by /boot/loader
Message-ID:  <202402291637.41TGb5Wm041754@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=479905a1ed26c54ef29cdff65cf25f7feade654b

commit 479905a1ed26c54ef29cdff65cf25f7feade654b
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2024-02-29 16:36:31 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-02-29 16:36:31 +0000

    firmware: Allow binary files to be loaded by /boot/loader
    
    Files loaded "-t firmware" (or module_type="firmware").  They are
    registered with the firmware system using the full path to the file.
    There's only one firmware per file, and it is the entire file. We do an
    extra firmware_get() on any firmware we find here to prevent them from
    ever being unloaded (we can't handle that case sanely).
    
    Sponsored by:           Netflix
    Reviewed by:            tsoome, jhb
    Differential Revision:  https://reviews.freebsd.org/D43522
---
 sys/kern/subr_firmware.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/sys/kern/subr_firmware.c b/sys/kern/subr_firmware.c
index 059bedeaac1c..33ec2e0cc0e4 100644
--- a/sys/kern/subr_firmware.c
+++ b/sys/kern/subr_firmware.c
@@ -161,6 +161,19 @@ lookup(const char *name)
 	LIST_FOREACH(fp, &firmware_table, link) {
 		if (fp->fw.name != NULL && strcasecmp(name, fp->fw.name) == 0)
 			break;
+
+		/*
+		 * If the name looks like an absolute path, also try to match
+		 * the last part of the string to the requested firmware if it
+		 * matches the trailing components.  This allows us to load
+		 * /boot/firmware/abc/bca2233_fw.bin and match it against
+		 * requests for bca2233_fw.bin or abc/bca2233_fw.bin.
+		 */
+		if (*fp->fw.name == '/' && strlen(fp->fw.name) > strlen(name)) {
+			const char *p = fp->fw.name + strlen(fp->fw.name) - strlen(name);
+			if (p[-1] == '/' && strcasecmp(name, p) == 0)
+				break;
+		}
 	}
 	return (fp);
 }
@@ -548,6 +561,42 @@ restart:
 	mtx_unlock(&firmware_mtx);
 }
 
+/*
+ * Find all the binary firmware that was loaded in the boot loader via load -t
+ * firmware foo.  There is only one firmware per file, it's the whole file, and
+ * there's no meaningful version passed in, so pass 0 for that.  If version is
+ * needed by the consumer (and not just arbitrarily defined), the .ko version
+ * must be used instead.
+ */
+static void
+firmware_binary_files(void)
+{
+	caddr_t file;
+	char *name;
+	const char *type;
+	const void *addr;
+	size_t size;
+	unsigned int version = 0;
+	const struct firmware *fw;
+	struct priv_fw *fp;
+
+	file = 0;
+	for (;;) {
+		file = preload_search_next_name(file);
+		if (file == 0)
+			break;
+		type = (const char *)preload_search_info(file, MODINFO_TYPE);
+		if (type == NULL || strcmp(type, "firmware") != 0)
+			continue;
+		name = preload_search_info(file, MODINFO_NAME);
+		addr = preload_fetch_addr(file);
+		size = preload_fetch_size(file);
+		fw = firmware_register(name, addr, size, version, NULL);
+		fp = PRIV_FW(fw);
+		fp->refcnt++;	/* Hold an extra reference so we never unload */
+	}
+}
+
 /*
  * Module glue.
  */
@@ -566,6 +615,7 @@ firmware_modevent(module_t mod, int type, void *unused)
 		/* NB: use our own loop routine that sets up context */
 		(void) taskqueue_start_threads(&firmware_tq, 1, PWAIT,
 		    "firmware taskq");
+		firmware_binary_files();
 		if (rootvnode != NULL) {
 			/*
 			 * Root is already mounted so we won't get an event;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202402291637.41TGb5Wm041754>