fw_stub.awk revision 159670
118099Spst#!/usr/bin/awk -f 218099Spst 318099Spst#- 418099Spst# Copyright (c) 2006 Max Laier. 518099Spst# All rights reserved. 618099Spst# 718099Spst# Redistribution and use in source and binary forms, with or without 818099Spst# modification, are permitted provided that the following conditions 918099Spst# are met: 1018099Spst# 1. Redistributions of source code must retain the above copyright 1118099Spst# notice, this list of conditions and the following disclaimer. 1218099Spst# 2. Redistributions in binary form must reproduce the above copyright 1318099Spst# notice, this list of conditions and the following disclaimer in the 1418099Spst# documentation and/or other materials provided with the distribution. 1518099Spst# 1618099Spst# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS'' AND 1718099Spst# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1818099Spst# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1918099Spst# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2055839Sasmodai# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2118099Spst# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2255839Sasmodai# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2318099Spst# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2418099Spst# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2555839Sasmodai# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2618099Spst# SUCH DAMAGE. 2718099Spst# 2818099Spst# $FreeBSD: head/sys/tools/fw_stub.awk 159670 2006-06-16 21:06:03Z jhb $ 2918099Spst 3018099Spst# 3118099Spst# Script to generate module .c file from a list of firmware images 3255839Sasmodai# 3318099Spst 3455839Sasmodaifunction usage () 3518099Spst{ 3618099Spst print "usage: fw_stub <firmware:name>* [-m modname] [-c outfile]"; 3718099Spst exit 1; 3818099Spst} 3918099Spst 4018099Spst# These are just for convenience ... 4118099Spstfunction printc(s) 4218099Spst{ 4355839Sasmodai if (opt_c) 4455839Sasmodai print s > ctmpfilename; 4518099Spst else 4618099Spst print s > "/dev/stdout"; 4718099Spst} 4818099Spst 4918099SpstBEGIN { 5018099Spst 5118099Spst# 5255839Sasmodai# Process the command line. 5355839Sasmodai# 5418099Spst 5518099Spstnum_files = 0; 5655839Sasmodai 5718099Spstfor (i = 1; i < ARGC; i++) { 5818099Spst if (ARGV[i] ~ /^-/) { 5955839Sasmodai # 6055839Sasmodai # awk doesn't have getopt(), so we have to do it ourselves. 6118099Spst # This is a bit clumsy, but it works. 6255839Sasmodai # 6318099Spst for (j = 2; j <= length(ARGV[i]); j++) { 6418099Spst o = substr(ARGV[i], j, 1); 6518099Spst if (o == "c") { 6618099Spst if (length(ARGV[i]) > j) { 6718099Spst opt_c = substr(ARGV[i], j + 1); 6818099Spst break; 6918099Spst } 7018099Spst else { 7118099Spst if (++i < ARGC) 7255839Sasmodai opt_c = ARGV[i]; 7318099Spst else 7418099Spst usage(); 7518099Spst } 7618099Spst } else if (o == "m") { 7755839Sasmodai if (length(ARGV[i]) > j) { 7855839Sasmodai opt_m = substr(ARGV[i], j + 1); 7955839Sasmodai break; 8018099Spst } 8155839Sasmodai else { 8218099Spst if (++i < ARGC) 8318099Spst opt_m = ARGV[i]; 8418099Spst else 8518099Spst usage(); 8618099Spst } 8718099Spst } else 8818099Spst usage(); 8918099Spst } 9018099Spst } else { 9118099Spst split(ARGV[i], curr, ":"); 9218099Spst filenames[num_files] = curr[1]; 9355839Sasmodai if (length(curr[2]) > 0) 9455839Sasmodai shortnames[num_files] = curr[2]; 9518099Spst else 9618099Spst shortnames[num_files] = curr[2]; 9718099Spst if (length(curr[3]) > 0) 9818099Spst versions[num_files] = int(curr[3]); 9918099Spst else 10018099Spst versions[num_files] = 0; 10118099Spst num_files++; 10218099Spst } 10318099Spst} 10455839Sasmodai 10555839Sasmodaiif (!num_files || !opt_m) 10618099Spst usage(); 10718099Spst 10818099Spstcfilename = opt_c; 10918099Spstctmpfilename = cfilename ".tmp"; 11055839Sasmodai 11155839Sasmodaiprintc("#include <sys/param.h>\ 11255839Sasmodai#include <sys/errno.h>\ 11318099Spst#include <sys/kernel.h>\ 11418099Spst#include <sys/module.h>\ 11518099Spst#include <sys/linker.h>\ 11618099Spst#include <sys/firmware.h>\n"); 11755839Sasmodai 11855839Sasmodaifor (file_i = 0; file_i < num_files; file_i++) { 11918099Spst symb = filenames[file_i]; 12018099Spst # '-', '.' and '/' are converted to '_' by ld/objcopy 12155839Sasmodai gsub(/-|\.|\//, "_", symb); 12255839Sasmodai printc("extern char _binary_" symb "_start[], _binary_" symb "_end[];"); 12318099Spst} 12418099Spst 12518099Spstprintc("\nstatic int\n"\ 12618099Spstopt_m "_fw_modevent(module_t mod, int type, void *unused)\ 12718099Spst{\ 12855839Sasmodai struct firmware *fp, *parent;\ 12955839Sasmodai int error;\ 13055839Sasmodai switch (type) {\ 13118099Spst case MOD_LOAD:"); 13255839Sasmodai 13355839Sasmodaifor (file_i = 0; file_i < num_files; file_i++) { 13418099Spst short = shortnames[file_i]; 13518099Spst symb = filenames[file_i]; 13618099Spst version = versions[file_i]; 13718099Spst # '-', '.' and '/' are converted to '_' by ld/objcopy 13818099Spst gsub(/-|\.|\//, "_", symb); 13955839Sasmodai 14055839Sasmodai reg = "\t\tfp = "; 14118099Spst reg = reg "firmware_register(\"" short "\", _binary_" symb "_start , "; 14218099Spst reg = reg "(size_t)(_binary_" symb "_end - _binary_" symb "_start), "; 14355839Sasmodai reg = reg version ", "; 14455839Sasmodai 14518099Spst if (file_i == 0) 14618099Spst reg = reg "NULL);"; 14718099Spst else 14818099Spst reg = reg "parent);"; 14918099Spst 15055839Sasmodai printc(reg); 15155839Sasmodai 15218099Spst printc("\t\tif (fp == NULL)"); 15318099Spst printc("\t\t\tgoto fail_" file_i ";"); 15455839Sasmodai if (file_i == 0) 15555839Sasmodai printc("\t\tparent = fp;"); 15655839Sasmodai} 15755839Sasmodai 15855839Sasmodaiprintc("\t\treturn (0);"); 15955839Sasmodai 16055839Sasmodaifor (file_i = num_files - 1; file_i > 0; file_i--) { 16155839Sasmodai printc("\tfail_" file_i ":") 16255839Sasmodai printc("\t\t(void)firmware_unregister(\"" shortnames[file_i - 1] "\");"); 16355839Sasmodai} 16455839Sasmodai 16555839Sasmodaiprintc("\tfail_0:"); 16655839Sasmodaiprintc("\t\treturn (ENXIO);"); 16755839Sasmodai 16855839Sasmodaiprintc("\tcase MOD_UNLOAD:"); 16955839Sasmodai 17055839Sasmodaifor (file_i = 1; file_i < num_files; file_i++) { 17155839Sasmodai printc("\t\terror = firmware_unregister(\"" shortnames[file_i] "\");"); 17255839Sasmodai printc("\t\tif (error)"); 17355839Sasmodai printc("\t\t\treturn (error);"); 17455839Sasmodai} 17555839Sasmodai 17655839Sasmodaiprintc("\t\terror = firmware_unregister(\"" shortnames[0] "\");"); 17755839Sasmodai 17855839Sasmodaiprintc("\t\treturn (error);\ 17955839Sasmodai }\ 18055839Sasmodai return (EINVAL);\ 18155839Sasmodai}\ 18255839Sasmodai\ 18355839Sasmodaistatic moduledata_t " opt_m "_fw_mod = {\ 18455839Sasmodai \"" opt_m "_fw\",\ 18555839Sasmodai " opt_m "_fw_modevent,\ 18655839Sasmodai 0\ 18755839Sasmodai};\ 18855839SasmodaiDECLARE_MODULE(" opt_m "_fw, " opt_m "_fw_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);\ 18955839SasmodaiMODULE_VERSION(" opt_m "_fw, 1);\ 19055839SasmodaiMODULE_DEPEND(" opt_m "_fw, firmware, 1, 1, 1);\ 19118099Spst"); 19218099Spst 19318099Spstif (opt_c) 19418099Spst if ((rc = system("mv -f " ctmpfilename " " cfilename))) { 19518099Spst print "'mv -f " ctmpfilename " " cfilename "' failed: " rc \ 19655839Sasmodai > "/dev/stderr"; 19755839Sasmodai exit 1; 19818099Spst } 19918099Spst 20055839Sasmodaiexit 0; 20155839Sasmodai 20218099Spst} 20318099Spst