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