#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
#
use strict;
my @funcunits = ();
my @errorrefs = ();
my $state = "initial";
sub usage() {
print STDERR "Usage: $PROGNAME inputfile\n";
exit(2);
}
sub bail() {
exit(1);
}
sub parsebail() {
exit(1);
}
sub error_alloc() {
my @a = ();
push(@::errorrefs, \@a);
return (\@a);
}
sub error_dup() {
my ($drop) = @_;
my $newref = &error_alloc();
my $n = $#$zeroref - $drop;
}
sub code_lines() {
return ($::codelinesin++);
}
sub error_init() {
&error_alloc();
$::codelinesin = 0;
}
sub error_reset() {
@::errorrefs = ();
$::codelinesin = 0;
$::codeoutlen = 0;
}
sub errout() {
my ($line) = @_;
}
}
sub errout_N() {
return 1;
}
sub print_errout() {
print @$ref;
}
}
sub print_header() {
print "#include \"ao_mca_disp.h\"\n\n";
}
sub print_footer() {
print 'const ao_error_disp_t *ao_error_disp[] = {' . "\n";
print "\t$name,\n";
}
print "};\n";
}
sub funcunit_begin() {
}
sub funcunit_end() {
print "\t{ NULL }\n};\n\n";
}
sub error_begin() {
my ($ereport_name) = @_;
$ereport_name =~ tr/[a-z]./[A-Z]_/;
my $flags_name = $ereport_name;
&errout("\tFM_$ereport_name,\n\tFM_$flags_name,\n");
}
sub error_end() {
&errout("\t},\n\n");
&print_errout();
&error_reset();
}
sub print_bits() {
my $name = $_[0];
my $out = "";
if (@bits == 0) {
$out = "\t0,";
} elsif (@bits == 1) {
$out = "\t$bits[0],";
} else {
}
$out .= "\n";
return ($out);
}
sub field_burst() {
if ($field eq "-") {
return ();
}
map {
if (!defined ${$valuesref}{$_}) {
&parsebail("unknown $name value `$_'");
}
$_ = ${$valuesref}{$_};
tr/[a-z]/[A-Z]/;
$prefix . "_" . $_;
} split(/\//, $field);
}
sub bin2dec() {
my $bin = $_[0];
my $dec = 0;
}
$dec;
}
sub state_funcunit() {
my $val = $_[0];
if (defined $::funcunit) {
&funcunit_end();
}
undef $::error;
&funcunit_begin($::funcunit);
}
sub state_desc() {
my $desc = $_[0];
&error_init();
&errout("\t/* $desc */\n\t{\n");
}
sub state_error() {
$::error = $_[0];
&error_begin($::error);
}
sub state_mask_on() {
@::mask_on = map { tr/[a-z]/[A-Z]/; $_; } split(/,\s*/, $_[0]);
}
sub state_mask_off() {
my @mask_off = map { tr/[a-z]/[A-Z]/; $_; } split(/,\s*/, $_[0]);
}
sub state_code() {
split(/\s+/, $_[0]);
my %r4_values = (
'err' => 'err',
'rd' => 'rd',
'wr' => 'wr',
'drd' => 'drd',
'dwr' => 'dwr',
'ird' => 'ird',
'pf' => 'prefetch',
'ev' => 'evict',
'snp' => 'snoop',
'-' => '-');
my %pp_values = (
'src' => 'src',
'res' => 'res',
'obs' => 'obs',
'gen' => 'gen',
'-' => '-' );
my %ii_values = (
'mem' => 'mem',
'io' => 'io',
'gen' => 'gen',
'-' => '-' );
my $instance = &code_lines();
if ($instance > 0) {
}
&parsebail("unknown tt value `$tt'");
}
&parsebail("unknown ll value `$ll'");
}
if (!defined $t_values{$t}) {
&parsebail("unknown t value `$t'");
}
map {
tr/[a-z]/[A-Z]/;
if ($type eq "bus") {
$ll eq "-" ||
$tt ne "-") {
&parsebail("invalid members for bus code type");
}
"0, " . # pp
"MCAX86_ERRCODE_T_" . ($t ? "TIMEOUT" : "NONE") . ", " .
"0, " . # r4
"0, " . # ii
"MCAX86_ERRCODE_LL_$ll),\n");
} elsif ($type eq "mem") {
&parsebail("invalid members for mem code type");
}
"0, " . # r4
"MCAX86_ERRCODE_TT_$tt, " .
"MCAX86_ERRCODE_LL_$ll),\n");
} elsif ($type eq "tlb") {
&parsebail("invalid members for tlb code type");
}
"MCAX86_ERRCODE_TT_$tt, " .
"MCAX86_ERRCODE_LL_$ll),\n");
} else {
&parsebail("unknown code type `$type'");
}
", /* ext code $ext */\n");
my $valid_hi;
my $valid_lo;
if ($addr eq "none") {
} elsif ($addr =~ /<(\d+):(\d+)>/) {
$valid_hi = $1;
$valid_lo = $2;
} else {
&parsebail("invalid addr specification");
}
", /* addr valid hi */\n");
", /* addr valid lo */\n");
}
sub state_panic() {
my @vals = split(/,\s*/, $_[0]);
if ($#vals < 0) {
&errout("\t0, /* panic_when */\n");
} else {
}
}
sub state_flags() {
my @flags = split(/,\s*/, $_[0]);
}
sub state_errtype() {
my @types = split(/,\s*/, $_[0]);
}
my %stateparse = (
);
&print_header();
while (<INFILE>) {
chop;
/^#/ && next;
/^$/ && next;
if (!/^\s*(\S[^=]*\S)\s*=\s*(\S.*)?$/) {
&parsebail("failed to parse");
}
if ($state eq "initial") {
if ($keyword eq "funcunit") {
$state = "funcunit";
} elsif ($keyword eq "desc") {
$state = "desc";
} else {
&parsebail("unexpected keyword $keyword between " .
"errors");
}
} elsif ($state eq "desc") {
if ($keyword eq "funcunit") {
$state = "funcunit";
}
}
&parsebail("keyword `$keyword' invalid here; expected " .
"`$state'");
}
if (!defined $stateparse{$state}) {
&parsebail("attempt to transition to invalid state `$state'");
}
if ($state eq "initial") {
&error_end();
}
}
close(INFILE);
&bail("input file ended prematurely");
}
if (defined $::funcunit) {
&funcunit_end();
} else {
&bail("no functional units defined");
}