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