fw_stub.awk revision 166756
1154974Smlaier#!/usr/bin/awk -f 2154974Smlaier 3154974Smlaier#- 4154974Smlaier# Copyright (c) 2006 Max Laier. 5154974Smlaier# All rights reserved. 6154974Smlaier# 7154974Smlaier# Redistribution and use in source and binary forms, with or without 8154974Smlaier# modification, are permitted provided that the following conditions 9154974Smlaier# are met: 10154974Smlaier# 1. Redistributions of source code must retain the above copyright 11154974Smlaier# notice, this list of conditions and the following disclaimer. 12154974Smlaier# 2. Redistributions in binary form must reproduce the above copyright 13154974Smlaier# notice, this list of conditions and the following disclaimer in the 14154974Smlaier# documentation and/or other materials provided with the distribution. 15154974Smlaier# 16154974Smlaier# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS `AS IS'' AND 17154974Smlaier# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18154974Smlaier# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19154974Smlaier# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20154974Smlaier# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21154974Smlaier# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22154974Smlaier# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23154974Smlaier# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24154974Smlaier# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25154974Smlaier# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26154974Smlaier# SUCH DAMAGE. 27154974Smlaier# 28154974Smlaier# $FreeBSD: head/sys/tools/fw_stub.awk 166756 2007-02-15 17:21:31Z luigi $ 29154974Smlaier 30154974Smlaier# 31154974Smlaier# Script to generate module .c file from a list of firmware images 32154974Smlaier# 33154974Smlaier 34154974Smlaierfunction usage () 35154974Smlaier{ 36154974Smlaier print "usage: fw_stub <firmware:name>* [-m modname] [-c outfile]"; 37154974Smlaier exit 1; 38154974Smlaier} 39154974Smlaier 40154974Smlaier# These are just for convenience ... 41154974Smlaierfunction printc(s) 42154974Smlaier{ 43154974Smlaier if (opt_c) 44154974Smlaier print s > ctmpfilename; 45154974Smlaier else 46154974Smlaier print s > "/dev/stdout"; 47154974Smlaier} 48154974Smlaier 49154974SmlaierBEGIN { 50154974Smlaier 51154974Smlaier# 52154974Smlaier# Process the command line. 53154974Smlaier# 54154974Smlaier 55154974Smlaiernum_files = 0; 56154974Smlaier 57154974Smlaierfor (i = 1; i < ARGC; i++) { 58154974Smlaier if (ARGV[i] ~ /^-/) { 59154974Smlaier # 60154974Smlaier # awk doesn't have getopt(), so we have to do it ourselves. 61154974Smlaier # This is a bit clumsy, but it works. 62154974Smlaier # 63154974Smlaier for (j = 2; j <= length(ARGV[i]); j++) { 64154974Smlaier o = substr(ARGV[i], j, 1); 65154974Smlaier if (o == "c") { 66154974Smlaier if (length(ARGV[i]) > j) { 67154974Smlaier opt_c = substr(ARGV[i], j + 1); 68154974Smlaier break; 69154974Smlaier } 70154974Smlaier else { 71154974Smlaier if (++i < ARGC) 72154974Smlaier opt_c = ARGV[i]; 73154974Smlaier else 74154974Smlaier usage(); 75154974Smlaier } 76154974Smlaier } else if (o == "m") { 77154974Smlaier if (length(ARGV[i]) > j) { 78154974Smlaier opt_m = substr(ARGV[i], j + 1); 79154974Smlaier break; 80154974Smlaier } 81154974Smlaier else { 82154974Smlaier if (++i < ARGC) 83154974Smlaier opt_m = ARGV[i]; 84154974Smlaier else 85154974Smlaier usage(); 86154974Smlaier } 87154974Smlaier } else 88154974Smlaier usage(); 89154974Smlaier } 90154974Smlaier } else { 91154974Smlaier split(ARGV[i], curr, ":"); 92154974Smlaier filenames[num_files] = curr[1]; 93154974Smlaier if (length(curr[2]) > 0) 94154974Smlaier shortnames[num_files] = curr[2]; 95154974Smlaier else 96154974Smlaier shortnames[num_files] = curr[2]; 97154974Smlaier if (length(curr[3]) > 0) 98154974Smlaier versions[num_files] = int(curr[3]); 99154974Smlaier else 100154974Smlaier versions[num_files] = 0; 101154974Smlaier num_files++; 102154974Smlaier } 103154974Smlaier} 104154974Smlaier 105154974Smlaierif (!num_files || !opt_m) 106154974Smlaier usage(); 107154974Smlaier 108154974Smlaiercfilename = opt_c; 109154974Smlaierctmpfilename = cfilename ".tmp"; 110154974Smlaier 111154974Smlaierprintc("#include <sys/param.h>\ 112154974Smlaier#include <sys/errno.h>\ 113154974Smlaier#include <sys/kernel.h>\ 114154974Smlaier#include <sys/module.h>\ 115154974Smlaier#include <sys/linker.h>\ 116154974Smlaier#include <sys/firmware.h>\n"); 117154974Smlaier 118154974Smlaierfor (file_i = 0; file_i < num_files; file_i++) { 119154974Smlaier symb = filenames[file_i]; 120154974Smlaier # '-', '.' and '/' are converted to '_' by ld/objcopy 121154974Smlaier gsub(/-|\.|\//, "_", symb); 122154974Smlaier printc("extern char _binary_" symb "_start[], _binary_" symb "_end[];"); 123154974Smlaier} 124154974Smlaier 125154974Smlaierprintc("\nstatic int\n"\ 126154974Smlaieropt_m "_fw_modevent(module_t mod, int type, void *unused)\ 127154974Smlaier{\ 128166756Sluigi const struct firmware *fp, *parent;\ 129159670Sjhb int error;\ 130154974Smlaier switch (type) {\ 131154974Smlaier case MOD_LOAD:"); 132154974Smlaier 133154974Smlaierfor (file_i = 0; file_i < num_files; file_i++) { 134154974Smlaier short = shortnames[file_i]; 135154974Smlaier symb = filenames[file_i]; 136154974Smlaier version = versions[file_i]; 137154974Smlaier # '-', '.' and '/' are converted to '_' by ld/objcopy 138154974Smlaier gsub(/-|\.|\//, "_", symb); 139154974Smlaier 140159670Sjhb reg = "\t\tfp = "; 141154974Smlaier reg = reg "firmware_register(\"" short "\", _binary_" symb "_start , "; 142154974Smlaier reg = reg "(size_t)(_binary_" symb "_end - _binary_" symb "_start), "; 143154974Smlaier reg = reg version ", "; 144154974Smlaier 145154974Smlaier if (file_i == 0) 146154974Smlaier reg = reg "NULL);"; 147154974Smlaier else 148159670Sjhb reg = reg "parent);"; 149154974Smlaier 150154974Smlaier printc(reg); 151159670Sjhb 152159670Sjhb printc("\t\tif (fp == NULL)"); 153159670Sjhb printc("\t\t\tgoto fail_" file_i ";"); 154159670Sjhb if (file_i == 0) 155159670Sjhb printc("\t\tparent = fp;"); 156154974Smlaier} 157154974Smlaier 158159670Sjhbprintc("\t\treturn (0);"); 159154974Smlaier 160159670Sjhbfor (file_i = num_files - 1; file_i > 0; file_i--) { 161159670Sjhb printc("\tfail_" file_i ":") 162159670Sjhb printc("\t\t(void)firmware_unregister(\"" shortnames[file_i - 1] "\");"); 163159670Sjhb} 164159670Sjhb 165159670Sjhbprintc("\tfail_0:"); 166159670Sjhbprintc("\t\treturn (ENXIO);"); 167159670Sjhb 168159670Sjhbprintc("\tcase MOD_UNLOAD:"); 169159670Sjhb 170154974Smlaierfor (file_i = 1; file_i < num_files; file_i++) { 171159670Sjhb printc("\t\terror = firmware_unregister(\"" shortnames[file_i] "\");"); 172159670Sjhb printc("\t\tif (error)"); 173159670Sjhb printc("\t\t\treturn (error);"); 174154974Smlaier} 175154974Smlaier 176159670Sjhbprintc("\t\terror = firmware_unregister(\"" shortnames[0] "\");"); 177154974Smlaier 178159670Sjhbprintc("\t\treturn (error);\ 179154974Smlaier }\ 180154974Smlaier return (EINVAL);\ 181154974Smlaier}\ 182154974Smlaier\ 183154974Smlaierstatic moduledata_t " opt_m "_fw_mod = {\ 184154974Smlaier \"" opt_m "_fw\",\ 185154974Smlaier " opt_m "_fw_modevent,\ 186154974Smlaier 0\ 187154974Smlaier};\ 188154974SmlaierDECLARE_MODULE(" opt_m "_fw, " opt_m "_fw_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);\ 189154974SmlaierMODULE_VERSION(" opt_m "_fw, 1);\ 190155055SmlaierMODULE_DEPEND(" opt_m "_fw, firmware, 1, 1, 1);\ 191154974Smlaier"); 192154974Smlaier 193154974Smlaierif (opt_c) 194154974Smlaier if ((rc = system("mv -f " ctmpfilename " " cfilename))) { 195154974Smlaier print "'mv -f " ctmpfilename " " cfilename "' failed: " rc \ 196154974Smlaier > "/dev/stderr"; 197154974Smlaier exit 1; 198154974Smlaier } 199154974Smlaier 200154974Smlaierexit 0; 201154974Smlaier 202154974Smlaier} 203