fw_stub.awk revision 154974
133965Sjdp#!/usr/bin/awk -f 2218822Sdim 3104834Sobrien#- 433965Sjdp# Copyright (c) 2006 Max Laier. 533965Sjdp# All rights reserved. 633965Sjdp# 733965Sjdp# Redistribution and use in source and binary forms, with or without 833965Sjdp# modification, are permitted provided that the following conditions 933965Sjdp# are met: 1033965Sjdp# 1. Redistributions of source code must retain the above copyright 1133965Sjdp# notice, this list of conditions and the following disclaimer. 1233965Sjdp# 2. Redistributions in binary form must reproduce the above copyright 1333965Sjdp# notice, this list of conditions and the following disclaimer in the 1433965Sjdp# documentation and/or other materials provided with the distribution. 1533965Sjdp# 1633965Sjdp# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS'' AND 1733965Sjdp# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1833965Sjdp# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19218822Sdim# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2033965Sjdp# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2133965Sjdp# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2233965Sjdp# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2333965Sjdp# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2433965Sjdp# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2533965Sjdp# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2633965Sjdp# SUCH DAMAGE. 2733965Sjdp# 2833965Sjdp# $FreeBSD: head/sys/tools/fw_stub.awk 154974 2006-01-29 02:52:42Z mlaier $ 29218822Sdim 30104834Sobrien# 31104834Sobrien# Script to generate module .c file from a list of firmware images 3233965Sjdp# 3333965Sjdp 3433965Sjdpfunction usage () 35218822Sdim{ 3633965Sjdp print "usage: fw_stub <firmware:name>* [-m modname] [-c outfile]"; 37218822Sdim exit 1; 38218822Sdim} 3933965Sjdp 4033965Sjdp# These are just for convenience ... 4133965Sjdpfunction printc(s) 4233965Sjdp{ 43218822Sdim if (opt_c) 44218822Sdim print s > ctmpfilename; 45218822Sdim else 46218822Sdim print s > "/dev/stdout"; 47218822Sdim} 4833965Sjdp 4933965SjdpBEGIN { 5033965Sjdp 5133965Sjdp# 5233965Sjdp# Process the command line. 5333965Sjdp# 5433965Sjdp 5533965Sjdpnum_files = 0; 5633965Sjdp 5733965Sjdpfor (i = 1; i < ARGC; i++) { 5833965Sjdp if (ARGV[i] ~ /^-/) { 5933965Sjdp # 6089857Sobrien # awk doesn't have getopt(), so we have to do it ourselves. 61130561Sobrien # This is a bit clumsy, but it works. 62130561Sobrien # 63130561Sobrien for (j = 2; j <= length(ARGV[i]); j++) { 64130561Sobrien o = substr(ARGV[i], j, 1); 65130561Sobrien if (o == "c") { 66130561Sobrien if (length(ARGV[i]) > j) { 6733965Sjdp opt_c = substr(ARGV[i], j + 1); 6833965Sjdp break; 6933965Sjdp } 70130561Sobrien else { 71130561Sobrien if (++i < ARGC) 72130561Sobrien opt_c = ARGV[i]; 73130561Sobrien else 74130561Sobrien usage(); 75130561Sobrien } 76130561Sobrien } else if (o == "m") { 77130561Sobrien if (length(ARGV[i]) > j) { 78130561Sobrien opt_m = substr(ARGV[i], j + 1); 79130561Sobrien break; 80130561Sobrien } 81130561Sobrien else { 8289857Sobrien if (++i < ARGC) 8333965Sjdp opt_m = ARGV[i]; 84130561Sobrien else 8533965Sjdp usage(); 8633965Sjdp } 8733965Sjdp } else 8833965Sjdp usage(); 8933965Sjdp } 9033965Sjdp } else { 9133965Sjdp split(ARGV[i], curr, ":"); 92130561Sobrien filenames[num_files] = curr[1]; 9333965Sjdp if (length(curr[2]) > 0) 9433965Sjdp shortnames[num_files] = curr[2]; 9533965Sjdp else 9633965Sjdp shortnames[num_files] = curr[2]; 9733965Sjdp if (length(curr[3]) > 0) 9833965Sjdp versions[num_files] = int(curr[3]); 99130561Sobrien else 10033965Sjdp versions[num_files] = 0; 10133965Sjdp num_files++; 10233965Sjdp } 10333965Sjdp} 10433965Sjdp 10533965Sjdpif (!num_files || !opt_m) 10633965Sjdp usage(); 10733965Sjdp 10833965Sjdpcfilename = opt_c; 10933965Sjdpctmpfilename = cfilename ".tmp"; 11033965Sjdp 11133965Sjdpprintc("#include <sys/param.h>\ 11233965Sjdp#include <sys/errno.h>\ 11333965Sjdp#include <sys/kernel.h>\ 11433965Sjdp#include <sys/module.h>\ 11533965Sjdp#include <sys/linker.h>\ 11633965Sjdp#include <sys/firmware.h>\n"); 11733965Sjdp 11833965Sjdpfor (file_i = 0; file_i < num_files; file_i++) { 11933965Sjdp symb = filenames[file_i]; 12033965Sjdp # '-', '.' and '/' are converted to '_' by ld/objcopy 12133965Sjdp gsub(/-|\.|\//, "_", symb); 12233965Sjdp printc("extern char _binary_" symb "_start[], _binary_" symb "_end[];"); 123130561Sobrien} 12433965Sjdp 12533965Sjdpprintc("\nstatic int\n"\ 12633965Sjdpopt_m "_fw_modevent(module_t mod, int type, void *unused)\ 12733965Sjdp{\ 12833965Sjdp struct firmware *fp;\ 129130561Sobrien switch (type) {\ 13033965Sjdp case MOD_LOAD:"); 13133965Sjdp 13233965Sjdpfor (file_i = 0; file_i < num_files; file_i++) { 13333965Sjdp short = shortnames[file_i]; 13433965Sjdp symb = filenames[file_i]; 13533965Sjdp version = versions[file_i]; 13633965Sjdp # '-', '.' and '/' are converted to '_' by ld/objcopy 13733965Sjdp gsub(/-|\.|\//, "_", symb); 13833965Sjdp 13933965Sjdp if (file_i == 0) 14033965Sjdp reg = "\t\tfp = "; 14133965Sjdp else 14233965Sjdp reg = "\t\t(void)"; 14333965Sjdp 14433965Sjdp reg = reg "firmware_register(\"" short "\", _binary_" symb "_start , "; 14533965Sjdp reg = reg "(size_t)(_binary_" symb "_end - _binary_" symb "_start), "; 14633965Sjdp reg = reg version ", "; 14733965Sjdp 14833965Sjdp if (file_i == 0) 149104834Sobrien reg = reg "NULL);"; 15033965Sjdp else 15133965Sjdp reg = reg "fp);"; 15233965Sjdp 15333965Sjdp printc(reg); 15433965Sjdp} 15533965Sjdp 15633965Sjdpprintc("\t\treturn (0);\ 15733965Sjdp case MOD_UNLOAD:"); 15833965Sjdp 15933965Sjdpfor (file_i = 1; file_i < num_files; file_i++) { 16038889Sjdp printc("\t\tfirmware_unregister(\"" shortnames[file_i] "\");"); 161218822Sdim} 16233965Sjdp 16333965Sjdpprintc("\t\tfirmware_unregister(\"" shortnames[0] "\");"); 16433965Sjdp 16533965Sjdpprintc("\t\treturn (0);\ 16633965Sjdp }\ 16733965Sjdp return (EINVAL);\ 16833965Sjdp}\ 16933965Sjdp\ 17033965Sjdpstatic moduledata_t " opt_m "_fw_mod = {\ 17133965Sjdp \"" opt_m "_fw\",\ 17233965Sjdp " opt_m "_fw_modevent,\ 17333965Sjdp 0\ 17433965Sjdp};\ 17533965SjdpDECLARE_MODULE(" opt_m "_fw, " opt_m "_fw_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);\ 17633965SjdpMODULE_VERSION(" opt_m "_fw, 1);\ 17733965SjdpMODULE_DEPEND(iwi_boot_fw, firmware, 1, 1, 1);\ 178130561Sobrien"); 17933965Sjdp 18033965Sjdpif (opt_c) 18133965Sjdp if ((rc = system("mv -f " ctmpfilename " " cfilename))) { 18233965Sjdp print "'mv -f " ctmpfilename " " cfilename "' failed: " rc \ 18338889Sjdp > "/dev/stderr"; 18438889Sjdp exit 1; 18533965Sjdp } 18633965Sjdp 18733965Sjdpexit 0; 18833965Sjdp 18933965Sjdp} 19033965Sjdp