3 # Copyright (c) 2017 The DragonFly Project. All rights reserved.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
9 # Redistributions of source code must retain the above copyright notice,
10 # this list of conditions and the following disclaimer.
12 # Redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in the
14 # documentation and/or other materials provided with the distribution.
16 # Neither the name of The DragonFly Project nor the names of its
17 # contributors may be used to endorse or promote products derived from
18 # this software without specific, prior written permission.
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS
21 # IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 # HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 # INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
29 # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
30 # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
33 # Prefixes for a files generated by parsing ISP driver C header file
34 # with firmware. For their meaning see the parse_isp_firmware_header()
36 license_file="license"
40 # Prefix for a binary file for firmware binary data. The binary file
41 # contains output of sh execution of printf commands in "data_N" file.
43 # Suffix for output files which this script produces
44 firmware_suffix=".fw.uu"
45 # This string (and a number) will be added to the names of the other
46 # variants of one firmware to form a unique filenames for the script
48 variant_string="_variant_"
50 # Function usage: parse_isp_firmware_header FILE
52 # FILE - Path to ISP driver C header file with firmware data.
54 # Result of this function are files containing parts of the header
55 # file and generated sh commands. One header file can contain multiple
56 # firmware images. Because of that, each file which contains image
57 # specific info has a number N appended to its name. N is integer
58 # number starting from 0. Files with the same N belongs to the same
61 # license - Firmware license.
62 # name_N - Image name. This will be the name of the final firmware .uu file.
63 # info_N - Comment blocks with info about firmware image.
64 # data_N - Printf calls that convert image words hex numbers to their
65 # values. This file is intended to be executed by sh and the stdout
66 # to be redirected to a file.
68 # NOTE: Resulting image words values will be in little-endian format.
69 parse_isp_firmware_header()
72 # This function converts chars from "a" to "f" to decimal numbers from
73 # 10 to 15 respectively. Every other character is returned as is.
74 # Parameters "chars" and "char_array" are local variables.
75 function hex_alpha_to_dec(a, chars, char_array) {
77 split(chars, char_array, ",")
81 if (char_array[j] == a) {
90 # This function converts two-digit hex number to decimal number.
91 # The input hex number is without "0x" prefix and "h" suffix.
92 # Parameters "a" and "b" are local variables.
93 function hex_to_dec(h, a, b) {
95 a = hex_alpha_to_dec(substr(h, 1, 1))
96 b = hex_alpha_to_dec(substr(h, 2, 1))
102 license_file = "'"${license_file}"'"
103 name_file = "'"${name_file}"'"
104 info_file = "'"${info_file}"'"
105 data_file = "'"${data_file}"'"
109 # Filter out file information line(s) (file path, version, date, author, ...)
110 /^\/\* \$.*\$ \*\// {
114 # Print the first line of the license contained in one comment block
115 (state == "license") && /\/\*/ {
116 print $0 > license_file
117 state = "inside_license"
121 # Print the last line of the license contained in one comment block
122 (state == "inside_license") && /\*\// {
123 print $0 > license_file
124 # License has been read, process comment blocks which contains info
125 # about the next firmware
130 # Print lines inside the license comment block
131 (state == "inside_license") {
132 print $0 > license_file
136 # Print info text of the next firmware contained in one comment block
137 (state == "info") && /\/\*/,/\*\// {
138 out = sprintf("%s%s", info_file, image_number);
143 # Process array declaration line, get the name of the firmware and data type of
148 split(decl[4], name, "_risc_code")
152 if (array_type ~ /int16/) {
153 # Data type of the array values is 16-bit
156 # Data type of the array values is 32-bit
159 # Save the firmware name
160 out = sprintf("%s%s", name_file, image_number);
161 printf "%s", array_name > out
165 # Current array has ended, process the next one
166 ((state == "data16") || ((state == "data32"))) && /\}/ {
172 # Process one line of array content definition
173 # Generate shell printf calls for the array values
174 (state == "data16") || (state == "data32") {
175 gsub("[ \t]", "", $0)
176 split($0, values, ",")
178 for (i = 1; length(values[i]) > 0; ++i) {
179 # Get the single bytes
180 a = substr(values[i], 3, 2)
181 b = substr(values[i], 5, 2)
182 if (state == "data32") {
183 c = substr(values[i], 7, 2)
184 d = substr(values[i], 9, 2)
186 # POSIX printf needs the number to be in octal format in the escape
188 # Swap the bytes to be in little-endian format
190 if (state == "data32") {
191 v = "\\" sprintf("%o", hex_to_dec(d)) "\\" sprintf("%o", hex_to_dec(c))
193 v = v "\\" sprintf("%o", hex_to_dec(b)) "\\" sprintf("%o", hex_to_dec(a))
194 out = sprintf("%s%s", data_file, image_number);
195 printf "printf \"%s\"\n", v > out
202 # Check input file and its existence
203 if [ $# -ne 1 ]; then
204 printf "Usage: $0 HEADER_FILE\n" >&2
206 elif [ ! -f "$1" ]; then
207 printf "Error: file '$1' does not exists\n" >&2
211 parse_isp_firmware_header "$1"
213 # Concatenate the files to form a firmware .uu files
216 while [ -f "${name_file}${image_number}" ]; do
217 output_file="$(cat ${name_file}${image_number})"
218 # Some ISP firmware header files (asm_2100.h) contains more
219 # variants of the same firmware image. Append _var_M to the second
220 # and the following image's names, where 1 <= M. Name of the first
221 # image in the header file will get nothing appended.
222 if [ -f "${output_file}${firmware_suffix}" ]; then
223 # Find unused variant number
225 tmp_name="${output_file}${variant_string}${variant_number}"
226 while [ -f "$tmp_name" ];do
227 variant_number=$((variant_number + 1))
228 tmp_name="${output_file}${variant_string}${variant_number}"
231 output_file="$tmp_name"
233 output_file="${output_file}${firmware_suffix}"
236 cat "$license_file" > "$output_file"
237 # Add the firmware information if it exists
238 [ -f "${info_file}${image_number}" ] && \
239 cat "${info_file}${image_number}" >> "$output_file"
240 # Generate firmware binary data
241 cat "${data_file}${image_number}" | sh > "${binary_file}${image_number}"
242 # uuencode the data and add it to the output file
243 uuencode "${binary_file}${image_number}" \
244 "${binary_file}${image_number}" >> "$output_file"
246 image_number=$((image_number + 1))
249 # Remove temporary files generated by parsing the ISP driver C header
250 # file with firmware data
251 eval rm -f \"${license_file}\"\* \