5 # The contents of this file are subject to the terms of the
6 # Common Development and Distribution License (the "License").
7 # You may not use this file except in compliance with the License.
9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 # or http://www.opensolaris.org/os/licensing.
11 # See the License for the specific language governing permissions
12 # and limitations under the License.
14 # When distributing Covered Code, include this CDDL HEADER in each
15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 # If applicable, add the following below this CDDL HEADER, with the
17 # fields enclosed by brackets "[]" replaced with your own identifying
18 # information: Portions Copyright [yyyy] [name of copyright owner]
24 # Copyright 2007 Sun Microsystems, Inc. All rights reserved.
25 # Use is subject to license terms.
27 # ident "%Z%%M% %I% %E% SMI"
33 my $PROGNAME = basename
($0);
35 my ($funcunit, $error);
39 my $codelinesin = 0; # number of input 'code' lines for an ereport type
40 my $codeoutlen = 0; # number of output lines from sub state_code
42 my $state = "initial";
45 print STDERR
"Usage: $PROGNAME inputfile\n";
50 print STDERR
"$PROGNAME: ", join(" ", @_), "\n";
55 print STDERR
"$PROGNAME: $::infile: $.: ", join(" ", @_), "\n";
62 push(@
::errorrefs
, \
@a);
68 my $newref = &error_alloc
();
70 my $zeroref = $::errorrefs
[0];
72 my $n = $#$zeroref - $drop;
74 @
$newref = @
$zeroref[0 .. $n];
78 return ($::codelinesin
++);
95 foreach my $ref (@
::errorrefs
) {
101 my ($instance, $line) = @_;
102 my $ref = @
::errorrefs
[$instance];
108 foreach my $ref (@
::errorrefs
) {
114 print "#include <sys/mca_x86.h>\n";
115 print "#include \"ao_mca_disp.h\"\n\n";
119 print 'const ao_error_disp_t *ao_error_disp[] = {' . "\n";
121 foreach my $name (@funcunits) {
128 sub funcunit_begin
() {
129 my $arrnm = "ao_error_disp_" . $_[0];
130 print "static const ao_error_disp_t " . $arrnm . "[] = {\n";
132 @funcunits = (@funcunits, $arrnm);
136 print "\t{ NULL }\n};\n\n";
140 my ($ereport_name) = @_;
142 $ereport_name =~ tr/[a-z]./[A-Z]_/;
143 my $flags_name = $ereport_name;
144 $flags_name =~ s/EREPORT_/EREPORT_PAYLOAD_FLAGS_/;
146 &errout
("\tFM_$ereport_name,\n\tFM_$flags_name,\n");
159 my @bits = @_[1..$#_];
164 } elsif (@bits == 1) {
165 $out = "\t$bits[0],";
167 $out = "\t( " . join(" | ", @bits) . " ),";
170 $out .= " /* $name */" if (defined $name);
177 my ($field, $valuesref, $name, $prefix) = @_;
184 if (!defined ${$valuesref}{$_}) {
185 &parsebail
("unknown $name value `$_'");
187 $_ = ${$valuesref}{$_};
190 } split(/\//, $field);
197 foreach my $bit (split(//, $bin)) {
198 $dec = $dec * 2 + ($bit eq "1" ?
1 : 0);
204 sub state_funcunit
() {
207 if (defined $::funcunit
) {
213 &funcunit_begin
($::funcunit
);
221 &errout
("\t/* $desc */\n\t{\n");
226 &error_begin
($::error
);
229 sub state_mask_on
() {
230 @
::mask_on
= map { tr/[a-z]/[A-Z]/; $_; } split(/,\s*/, $_[0]);
233 sub state_mask_off
() {
234 my @mask_off = map { tr/[a-z]/[A-Z]/; $_; } split(/,\s*/, $_[0]);
236 &errout
(&print_bits
("mask", @
::mask_on
, @mask_off));
237 &errout
(&print_bits
("mask_res", @
::mask_on
));
241 my ($ext, $type, $pp, $t, $r4, $addr, $ii, $ll, $tt) =
244 my %tt_values = ( instr
=> 1, data
=> 1, gen
=> 1, '-' => 1 );
245 my %ll_values = ( l0
=> 1, l1
=> 1, l2
=> 1, lg
=> 1 );
266 my %t_values = ( 0 => 1, 1 => 1, '-' => 1 );
274 my $instance = &code_lines
();
276 &error_dup
($::codeoutlen
); # dup info thus far
279 if (!defined $tt_values{$tt}) {
280 &parsebail
("unknown tt value `$tt'");
283 if (!defined $ll_values{$ll}) {
284 &parsebail
("unknown ll value `$ll'");
287 my @r4 = &field_burst
($r4, \
%r4_values, "r4", "AO_MCA_R4_BIT");
289 my @pp = ($pp eq '-') ?
() :
290 &field_burst
($pp, \
%pp_values, "pp", "AO_MCA_PP_BIT");
292 if (!defined $t_values{$t}) {
293 &parsebail
("unknown t value `$t'");
296 my @ii = ($ii eq '-') ?
() :
297 &field_burst
($ii, \
%ii_values, "ii", "AO_MCA_II_BIT");
303 if ($type eq "bus") {
304 if ($pp eq "-" || $t eq "-" || $r4 eq "-" || $ii eq "-" ||
307 &parsebail
("invalid members for bus code type");
310 $::codeoutlen
+= &errout_N
($instance, "\tAMD_ERRCODE_MKBUS(" .
312 "MCAX86_ERRCODE_T_" . ($t ?
"TIMEOUT" : "NONE") . ", " .
315 "MCAX86_ERRCODE_LL_$ll),\n");
317 } elsif ($type eq "mem") {
318 if ($r4 eq "-" || $tt eq "-" || $ll eq "-" ||
319 $pp ne "-" || $t ne "-" || $ii ne "-") {
320 &parsebail
("invalid members for mem code type");
323 $::codeoutlen
+= &errout_N
($instance, "\tAMD_ERRCODE_MKMEM(" .
325 "MCAX86_ERRCODE_TT_$tt, " .
326 "MCAX86_ERRCODE_LL_$ll),\n");
328 } elsif ($type eq "tlb") {
329 if ($tt eq "-" || $ll eq "-" ||
330 $r4 ne "-" || $pp ne "-" || $t ne "-" || $ii ne "-") {
331 &parsebail
("invalid members for tlb code type");
334 $::codeoutlen
+= &errout_N
($instance, "\tAMD_ERRCODE_MKTLB(" .
335 "MCAX86_ERRCODE_TT_$tt, " .
336 "MCAX86_ERRCODE_LL_$ll),\n");
338 &parsebail
("unknown code type `$type'");
341 $::codeoutlen
+= &errout_N
($instance, "\t" . &bin2dec
($ext) .
342 ", /* ext code $ext */\n");
344 $::codeoutlen
+= &errout_N
($instance, &print_bits
("pp_bits", @pp));
345 $::codeoutlen
+= &errout_N
($instance, &print_bits
("ii_bits", @ii));
346 $::codeoutlen
+= &errout_N
($instance, &print_bits
("r4_bits", @r4));
351 if ($addr eq "none") {
352 $valid_hi = $valid_lo = 0;
353 } elsif ($addr =~ /<(\d+):(\d+)>/) {
357 &parsebail
("invalid addr specification");
359 $::codeoutlen
+= &errout_N
($instance, "\t" . $valid_hi .
360 ", /* addr valid hi */\n");
361 $::codeoutlen
+= &errout_N
($instance, "\t" . $valid_lo .
362 ", /* addr valid lo */\n");
366 my @vals = split(/,\s*/, $_[0]);
369 &errout
("\t0, /* panic_when */\n");
371 @vals = map { tr/[a-z]/[A-Z]/; "AO_AED_PANIC_" . $_; } @vals;
372 &errout
(&print_bits
("panic_when", @vals));
377 my @flags = split(/,\s*/, $_[0]);
379 @flags = map { tr/[a-z]/[A-Z]/; "AO_AED_F_" . $_; } @flags;
381 &errout
(&print_bits
("flags", @flags));
384 sub state_errtype
() {
385 my @types = split(/,\s*/, $_[0]);
387 @types = map { tr/[a-z]/[A-Z]/; "AO_AED_ET_" . $_; } @types;
389 &errout
(&print_bits
("errtype", @types));
393 funcunit
=> [ \
&state_funcunit
, 'desc' ],
394 desc
=> [ \
&state_desc
, 'error' ],
395 error
=> [ \
&state_error
, 'mask on' ],
396 'mask on' => [ \
&state_mask_on
, 'mask off' ],
397 'mask off' => [ \
&state_mask_off
, 'code' ],
398 code
=> [ \
&state_code
, 'code|panic' ],
399 panic
=> [ \
&state_panic
, 'flags' ],
400 flags
=> [ \
&state_flags
, 'errtype' ],
401 errtype
=> [ \
&state_errtype
, 'initial' ]
404 usage
unless (@ARGV == 1);
406 my $infile = $ARGV[0];
407 open(INFILE
, "<$infile") || &bail
("failed to open $infile: $!");
417 if (!/^\s*(\S[^=]*\S)\s*=\s*(\S.*)?$/) {
418 &parsebail
("failed to parse");
421 my ($keyword, $val) = ($1, $2);
423 if ($state eq "initial") {
424 if ($keyword eq "funcunit") {
426 } elsif ($keyword eq "desc") {
429 &parsebail
("unexpected keyword $keyword between " .
433 } elsif ($state eq "desc") {
434 if ($keyword eq "funcunit") {
439 if (!($keyword =~ /$state/)) {
440 &parsebail
("keyword `$keyword' invalid here; expected " .
443 $state = $keyword; # disambiguate between multiple legal states
445 if (!defined $stateparse{$state}) {
446 &parsebail
("attempt to transition to invalid state `$state'");
449 my ($handler, $next) = @
{$stateparse{$state}};
455 if ($state eq "initial") {
462 if ($state ne "initial" && $state ne "desc") {
463 &bail
("input file ended prematurely");
466 if (defined $::funcunit
) {
469 &bail
("no functional units defined");