]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/bnxt/convert_hsi.pl
unbound: Vendor import 1.18.0
[FreeBSD/FreeBSD.git] / sys / dev / bnxt / convert_hsi.pl
1 #!/usr/bin/env perl
2
3 # This script cleans up the "official" Broadcom hsi_struct_defs.h file as distributed
4 # to something somewhat more programmer friendly.
5 #
6
7 my $do_decode = 0;
8
9 if (! -f $ARGV[0]) {
10         print "Input file not specified (should be path to hsi_struct_defs.h)\n";
11         exit 1;
12 }
13
14 if (!open(IN, "<", $ARGV[0])) {
15         print "Failure to open input file\n";
16         exit 1;
17 }
18
19 if (!open(OUT, ">", "hsi_struct_def.h")) {
20         print "Failure to open output file\n";
21         exit 1;
22 }
23
24 $/=undef;
25 my $header = <IN>;
26 close IN;
27
28 print OUT <<END_OF_NOTICE;
29 /*-
30  *   BSD LICENSE
31  *
32  *   Copyright (c) 2016 Broadcom, All Rights Reserved.
33  *   The term Broadcom refers to Broadcom Limited and/or its subsidiaries
34  *
35  *   Redistribution and use in source and binary forms, with or without
36  *   modification, are permitted provided that the following conditions
37  *   are met:
38  *     * Redistributions of source code must retain the above copyright
39  *       notice, this list of conditions and the following disclaimer.
40  *     * Redistributions in binary form must reproduce the above copyright
41  *       notice, this list of conditions and the following disclaimer in
42  *       the documentation and/or other materials provided with the
43  *       distribution.
44  *
45  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
46  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
47  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
48  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
49  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
52  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
53  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
54  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
55  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56  */
57
58 #include <sys/cdefs.h>
59 __FBSDID("\$FreeBSD\$");
60
61 END_OF_NOTICE
62
63 # Convert line endings
64 $header =~ s/\r\n/\n/gs;
65
66 # Convert arrays of two u32_t to a single uint64_t
67 $header =~ s/\bu32_t(\s+[a-zA-Z0-9_]+)\[2\]/uint64_t$1/gs;
68
69 # Convert uint32_t *_lo/uint32_t *_hi to a single uint64_t
70 $header =~ s/\bu32_t(\s+[a-zA-Z0-9_]+)_lo;\s*\r?\n\s*u32_t(\s+[a-zA-Z0-9_]+)_hi/uint64_t$1/gs;
71
72 # Convert types
73 $header =~ s/\bu([0-9]+)_t\b/uint$1_t/gs;
74
75 # Convert literals
76 $header =~ s/\b((?:0x)?[0-9a-f]+)UL/UINT32_C($1)/gs;
77
78 # Strip comments
79 #$header =~ s/^(\s*[^\/\s][^\/]+?)\s*\/\*.*?\*\/\s*?$/$1/gm;
80 #$header =~ s/[ \t]*\/\*.*?\*\/\s*?\n?//gs;
81
82 # Pack structs
83 #$header =~ s/}(\s+)([^\s]+_t[,;])/} __attribute__((packed))$1$2/gs;
84
85 # Normalize indent
86 $header =~ s/(    ) +(#define)/$1$2/gs;
87 $header =~ s/^(}[^\n]*;)\n([^\n])/$1\n\n$2/gsm;
88 $header =~ s/([^\n])\n(typedef)/$1\n\n$2/gs;
89 $header =~ s/        /\t/g;
90 $header =~ s/    /\t/g;
91 $header =~ s/([^\s]\t+) +/$1/g;
92
93 # Remove typedefs and pack structs
94 $header =~ s/^typedef struct (.*?)\n{\n(.*?)}[^\n]*;/struct $1 {\n$2} __attribute__((packed));/gsm;
95
96 print OUT $header;
97 close OUT;
98
99 if ($do_decode) {
100         if(!open(OUT, ">", "hsi_struct_decode.c")) {
101                 print "Failure to open decoder output file\n";
102                 exit 1;
103         }
104
105         print OUT <<END_OF_NOTICE;
106         /*-
107          *   BSD LICENSE
108          *
109          *   Copyright (c) 2016 Broadcom, All Rights Reserved.
110          *   The term Broadcom refers to Broadcom Limited and/or its subsidiaries
111          *
112          *   Redistribution and use in source and binary forms, with or without
113          *   modification, are permitted provided that the following conditions
114          *   are met:
115          *     * Redistributions of source code must retain the above copyright
116          *       notice, this list of conditions and the following disclaimer.
117          *     * Redistributions in binary form must reproduce the above copyright
118          *       notice, this list of conditions and the following disclaimer in
119          *       the documentation and/or other materials provided with the
120          *       distribution.
121          *
122          *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
123          *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
124          *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
125          *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
126          *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
127          *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
128          *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
129          *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
130          *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131          *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
132          *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
133          */
134
135         #include <sys/cdefs.h>
136         __FBSDID("\$FreeBSD\$");
137
138 END_OF_NOTICE
139
140         if(!open(HDR, ">", "hsi_struct_decode.h")) {
141                 print "Failure to open decoder output header file\n";
142                 exit 1;
143         }
144
145         print HDR <<END_OF_NOTICE;
146         /*-
147          *   BSD LICENSE
148          *
149          *   Copyright(c) 2014-2015 Broadcom Corporation.
150          *   All rights reserved.
151          *
152          *   Redistribution and use in source and binary forms, with or without
153          *   modification, are permitted provided that the following conditions
154          *   are met:
155          *
156          *     * Redistributions of source code must retain the above copyright
157          *       notice, this list of conditions and the following disclaimer.
158          *     * Redistributions in binary form must reproduce the above copyright
159          *       notice, this list of conditions and the following disclaimer in
160          *       the documentation and/or other materials provided with the
161          *       distribution.
162          *     * Neither the name of Broadcom Corporation nor the names of its
163          *       contributors may be used to endorse or promote products derived
164          *       from this software without specific prior written permission.
165          *
166          *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
167          *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
168          *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
169          *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
170          *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
171          *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
172          *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
173          *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
174          *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
175          *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
176          *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
177          */
178
179 END_OF_NOTICE
180
181         print OUT "#ifdef HSI_DEBUG\n#include <inttypes.h>\n#include <rte_common.h>\n#include <rte_log.h>\n#include \"hsi_struct_def_dpdk.h\"\n#include \"hsi_struct_decode.h\"\n#include \"hsi_struct_decode.h\"\n\n";
182         print HDR "#ifdef HSI_DEBUG\n#include \"hsi_struct_def_dpdk.h\"\n\n";
183
184         my $hdr_defs = '';
185
186         sub print_single_val
187         {
188                 my $field=shift;
189                 my $type=shift;
190                 my $max_field_len=shift;
191                 my $name = shift;
192                 my $macroshash = shift;
193                 my %macros = %$macroshash;
194                 $macrosref = shift;
195                 my @macros = @$macrosref;
196                 $macrosref = shift;
197                 my @fields = @$macrosref;
198
199                 if ($type eq 'uint32_t') {
200                         printf OUT "\tRTE_LOG(DEBUG, PMD, \"  % *s = 0x%%08\"PRIX32\"\\n\", data->$field);\n",$max_field_len,$field;
201                 }
202                 elsif ($type eq 'uint16_t') {
203                         printf OUT "\tRTE_LOG(DEBUG, PMD, \"  % *s = 0x%%04\"PRIX16\"\\n\", data->$field);\n",$max_field_len,$field;
204                 }
205                 elsif ($type eq 'uint8_t') {
206                         printf OUT "\tRTE_LOG(DEBUG, PMD, \"  % *s = 0x%%02\"PRIX8\"\\n\", data->$field);\n",$max_field_len,$field;
207                 }
208                 elsif ($type eq 'uint64_t') {
209                         printf OUT "\tRTE_LOG(DEBUG, PMD, \"  % *s = 0x%%016\"PRIX64\"\\n\", data->$field);\n",$max_field_len,$field;
210                 }
211                 elsif ($type eq 'char') {
212                         if ($field =~ s/\[([0-9]+)\]//) {
213                                 printf OUT "\tRTE_LOG(DEBUG, PMD, \"  % *s = \\\"%%.$1s\\\"\\n\", data->$field);\n",$max_field_len,$field;
214                         }
215                         else {
216                                 printf OUT "\tRTE_LOG(DEBUG, PMD, \"  % *s = 0x%%02\"PRIX8\"\\n\", data->$field);\n",$max_field_len,$field;
217                         }
218                 }
219                 else {
220                         print "Unhandled type: '$type'\n";
221                 }
222
223                 my $macro_prefix = uc($name).'_'.uc($field).'_';
224                 # Special handling for the common flags_type field
225                 $macro_prefix =~ s/FLAGS_TYPE_$/FLAGS_/ if ($field eq 'flags_type');
226                 # Special handling for _hi types
227                 $macro_prefix =~ s/_HI_/_/ if ($name =~ /_hi$/);
228
229                 $macro_prefix =~ s/\[[0-9]+\]//;
230                 my %vmacros;
231                 my $vmacros_have_mask = 0;
232                 my @vmacros;
233                 my %subfields;
234                 my $all_single_bits=1;
235         MACRO:
236                 foreach my $macro (@macros) {
237                         if ($macro =~ /^$macro_prefix(.*)_MASK$/) {
238                                 my $macro = $&;
239                                 my $maskdef = $macros{$macro};
240                                 my $subfield = $1;
241                                 my $subfield_value = "(data->$field & $macro)";
242                                 if (defined $macros{"$macro_prefix$subfield\_SFT"}) {
243                                         $subfield_value = "($subfield_value >> $macro_prefix$subfield\_SFT)";
244                                 }
245                                 $maskdef =~ s/[x0 ]//g;
246                                 if ($type eq 'uint64_t') {
247                                         printf OUT "\tRTE_LOG(DEBUG, PMD, \"  % *s   $subfield = %%0*\" PRIX64 \"\\n\", %u, $subfield_value);\n", $max_field_len, '', length($maskdef);
248                                 }
249                                 else {
250                                         printf OUT "\tRTE_LOG(DEBUG, PMD, \"  % *s   $subfield = %%0*X\\n\", %u, $subfield_value);\n", $max_field_len, '', length($maskdef);
251                                 }
252                                 delete $$macroshash{$macro};
253                         }
254                         elsif ($macro =~ /^$macro_prefix(.*)_SFT$/) {
255                                 delete $$macroshash{$macro};
256                         }
257                         elsif ($macro =~ /^$macro_prefix\MASK$/) {
258                                 $vmacros_have_mask = 1;
259                                 delete $$macroshash{$macro};
260                         }
261                         elsif ($macro =~ /^$macro_prefix(.*)$/) {
262                                 my $macro = $&;
263                                 my $subfield = $1;
264
265                                 # Check for longer fields with the same base... ie: link and link_speed
266                                 foreach my $extra_field (@fields) {
267                                         next if ($extra_field eq $field);
268                                         if ($extra_field =~ /^$field/) {
269                                                 my $extra_prefix = uc($name).'_'.uc($extra_field).'_';
270                                                 next MACRO if ($macro =~ /^$extra_prefix/);
271                                         }
272                                 }
273
274                                 push @vmacros, $macro;
275                                 my $macroeval = $macros{$macro};
276                                 $macroeval =~ s/UINT32_C\((.*?)\)/$1/g;
277                                 $vmacros{$macro} = eval("$macroeval");
278                                 $subfields{$macro} = $subfield;
279
280                                 $all_single_bits = 0 if ($vmacros{$macro} & ($vmacros{$macro}-1));
281                                 $all_single_bits = 0 if ($vmacros{$macro} == 0);
282                         }
283                 }
284                 if ($all_single_bits) {
285                         foreach my $macro (@vmacros) {
286                                 my $subfield_value = "(data->$field & $macro)";
287                                 printf OUT "\tRTE_LOG(DEBUG, PMD, \"  % *s   $subfields{$macro} : %%s\\n\", $subfield_value?\"ON\":\"OFF\");\n", $max_field_len, '';
288                                 delete $$macroshash{$macro};
289                         }
290                 }
291                 else {
292                         printf OUT "\tRTE_LOG(DEBUG, PMD, \"  % *s   Value : %%s\\n\",\n", $max_field_len, '';
293                         foreach my $macro (@vmacros) {
294                                 my $subfield_value = "data->$field";
295                                 $subfield_value = "($subfield_value & $macro_prefix\MASK)" if $vmacros_have_mask;
296                                 print OUT "\t\t$subfield_value == $macro ? \"$subfields{$macro}\" :\n";
297                                 delete $$macroshash{$macro};
298                         }
299                         print OUT "\t\t\"Unknown\");\n";
300                 }
301         }
302
303         while ($header =~ /^typedef\s+struct\s+(.*?)\s+{(.*?)^}/msg) {
304                 my ($name,$def) = ($1, $2);
305                 my @fields=();
306                 my %type=();
307                 my @macros=();
308                 my %macros=();
309                 my $max_field_len=0;
310
311                 # First, pull out all the fields in order...
312                 while($def =~ /^\s*([^\s#\/]+?)\s+([^;\/\s]+?)\s*;/mg) {
313                         my ($type, $name) = ($1, $2);
314                         push @fields, $name;
315                         $type{$name}=$type;
316                         $max_field_len = length($name) if length($name) > $max_field_len;
317                 }
318                 # Now, pull out the macros...
319                 while($def =~ /^\s*\#define\s+([^\s]+?)\s+(.*?)\s*$/mg) {
320                         push @macros, $1;
321                         $macros{$1}=$2;
322                 }
323
324                 # Now, generate code to print the struct...
325                 print OUT "void decode_$name(const char *string __rte_unused, struct $name *data) {\n\tRTE_LOG(DEBUG, PMD, \"$name\\n\");\n";
326                 print HDR "void decode_$name(const char *string __rte_unused, struct $name *data);\n";
327                 $hdr_defs .= "#define decode_$name(x, y) {}\n";
328                 foreach my $field (@fields) {
329                         if ($field =~ /\[([0-9]+)\]/) {
330                                 if ($type{$field} eq 'char') {
331                                         print_single_val($field, $type{$field}, $max_field_len, $name, \%macros, \@macros, \@fields);
332                                 }
333                                 else {
334                                         foreach my $idx (0..$1-1) {
335                                                 my $item = $field;
336                                                 $item =~ s/\[[0-9]+\]/[$idx]/;
337                                                 print_single_val($item, $type{$field}, $max_field_len, $name, \%macros, \@macros, \@fields);
338                                         }
339                                 }
340                         }
341                         else {
342                                 print_single_val($field, $type{$field}, $max_field_len, $name, \%macros, \@macros, \@fields);
343                         }
344                 }
345         #       print "Unhandled macros:\n",join("\n", keys %macros),"\n" if (keys %macros > 0);
346                 print OUT "}\n\n";
347         }
348         print OUT "#endif\n";
349
350         print HDR "#else\n";
351         print HDR $hdr_defs;
352         print HDR "#endif\n";
353         close OUT;
354         close HDR;
355 }