summaryrefslogtreecommitdiffstats
path: root/sys/tools/fw_stub.awk
diff options
context:
space:
mode:
Diffstat (limited to 'sys/tools/fw_stub.awk')
-rw-r--r--sys/tools/fw_stub.awk189
1 files changed, 189 insertions, 0 deletions
diff --git a/sys/tools/fw_stub.awk b/sys/tools/fw_stub.awk
new file mode 100644
index 0000000..72383ba
--- /dev/null
+++ b/sys/tools/fw_stub.awk
@@ -0,0 +1,189 @@
+#!/usr/bin/awk -f
+
+#-
+# Copyright (c) 2006 Max Laier.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+#
+# Script to generate module .c file from a list of firmware images
+#
+
+function usage ()
+{
+ print "usage: fw_stub <firmware:name>* [-m modname] [-c outfile]";
+ exit 1;
+}
+
+# These are just for convenience ...
+function printc(s)
+{
+ if (opt_c)
+ print s > ctmpfilename;
+ else
+ print s > "/dev/stdout";
+}
+
+BEGIN {
+
+#
+# Process the command line.
+#
+
+num_files = 0;
+
+for (i = 1; i < ARGC; i++) {
+ if (ARGV[i] ~ /^-/) {
+ #
+ # awk doesn't have getopt(), so we have to do it ourselves.
+ # This is a bit clumsy, but it works.
+ #
+ for (j = 2; j <= length(ARGV[i]); j++) {
+ o = substr(ARGV[i], j, 1);
+ if (o == "c") {
+ if (length(ARGV[i]) > j) {
+ opt_c = substr(ARGV[i], j + 1);
+ break;
+ }
+ else {
+ if (++i < ARGC)
+ opt_c = ARGV[i];
+ else
+ usage();
+ }
+ } else if (o == "m") {
+ if (length(ARGV[i]) > j) {
+ opt_m = substr(ARGV[i], j + 1);
+ break;
+ }
+ else {
+ if (++i < ARGC)
+ opt_m = ARGV[i];
+ else
+ usage();
+ }
+ } else
+ usage();
+ }
+ } else {
+ split(ARGV[i], curr, ":");
+ filenames[num_files] = curr[1];
+ if (length(curr[2]) > 0)
+ shortnames[num_files] = curr[2];
+ else
+ shortnames[num_files] = curr[2];
+ if (length(curr[3]) > 0)
+ versions[num_files] = int(curr[3]);
+ else
+ versions[num_files] = 0;
+ num_files++;
+ }
+}
+
+if (!num_files || !opt_m)
+ usage();
+
+cfilename = opt_c;
+ctmpfilename = cfilename ".tmp";
+
+printc("#include <sys/param.h>\
+#include <sys/errno.h>\
+#include <sys/kernel.h>\
+#include <sys/module.h>\
+#include <sys/linker.h>\
+#include <sys/firmware.h>\n");
+
+for (file_i = 0; file_i < num_files; file_i++) {
+ symb = filenames[file_i];
+ # '-', '.' and '/' are converted to '_' by ld/objcopy
+ gsub(/-|\.|\//, "_", symb);
+ printc("extern char _binary_" symb "_start[], _binary_" symb "_end[];");
+}
+
+printc("\nstatic int\n"\
+opt_m "_fw_modevent(module_t mod, int type, void *unused)\
+{\
+ struct firmware *fp;\
+ switch (type) {\
+ case MOD_LOAD:");
+
+for (file_i = 0; file_i < num_files; file_i++) {
+ short = shortnames[file_i];
+ symb = filenames[file_i];
+ version = versions[file_i];
+ # '-', '.' and '/' are converted to '_' by ld/objcopy
+ gsub(/-|\.|\//, "_", symb);
+
+ if (file_i == 0)
+ reg = "\t\tfp = ";
+ else
+ reg = "\t\t(void)";
+
+ reg = reg "firmware_register(\"" short "\", _binary_" symb "_start , ";
+ reg = reg "(size_t)(_binary_" symb "_end - _binary_" symb "_start), ";
+ reg = reg version ", ";
+
+ if (file_i == 0)
+ reg = reg "NULL);";
+ else
+ reg = reg "fp);";
+
+ printc(reg);
+}
+
+printc("\t\treturn (0);\
+ case MOD_UNLOAD:");
+
+for (file_i = 1; file_i < num_files; file_i++) {
+ printc("\t\tfirmware_unregister(\"" shortnames[file_i] "\");");
+}
+
+printc("\t\tfirmware_unregister(\"" shortnames[0] "\");");
+
+printc("\t\treturn (0);\
+ }\
+ return (EINVAL);\
+}\
+\
+static moduledata_t " opt_m "_fw_mod = {\
+ \"" opt_m "_fw\",\
+ " opt_m "_fw_modevent,\
+ 0\
+};\
+DECLARE_MODULE(" opt_m "_fw, " opt_m "_fw_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);\
+MODULE_VERSION(" opt_m "_fw, 1);\
+MODULE_DEPEND(iwi_boot_fw, firmware, 1, 1, 1);\
+");
+
+if (opt_c)
+ if ((rc = system("mv -f " ctmpfilename " " cfilename))) {
+ print "'mv -f " ctmpfilename " " cfilename "' failed: " rc \
+ > "/dev/stderr";
+ exit 1;
+ }
+
+exit 0;
+
+}
OpenPOWER on IntegriCloud