17aec1d6eScindi#!/bin/perl 27aec1d6eScindi# 37aec1d6eScindi# CDDL HEADER START 47aec1d6eScindi# 57aec1d6eScindi# The contents of this file are subject to the terms of the 6*a307a255Sgavinm# Common Development and Distribution License (the "License"). 7*a307a255Sgavinm# You may not use this file except in compliance with the License. 87aec1d6eScindi# 97aec1d6eScindi# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107aec1d6eScindi# or http://www.opensolaris.org/os/licensing. 117aec1d6eScindi# See the License for the specific language governing permissions 127aec1d6eScindi# and limitations under the License. 137aec1d6eScindi# 147aec1d6eScindi# When distributing Covered Code, include this CDDL HEADER in each 157aec1d6eScindi# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167aec1d6eScindi# If applicable, add the following below this CDDL HEADER, with the 177aec1d6eScindi# fields enclosed by brackets "[]" replaced with your own identifying 187aec1d6eScindi# information: Portions Copyright [yyyy] [name of copyright owner] 197aec1d6eScindi# 207aec1d6eScindi# CDDL HEADER END 217aec1d6eScindi# 227aec1d6eScindi 237aec1d6eScindi# 247aec1d6eScindi# Copyright 2006 Sun Microsystems, Inc. All rights reserved. 257aec1d6eScindi# Use is subject to license terms. 267aec1d6eScindi# 277aec1d6eScindi# ident "%Z%%M% %I% %E% SMI" 287aec1d6eScindi# 297aec1d6eScindi 307aec1d6eScindiuse strict; 317aec1d6eScindiuse File::Basename; 327aec1d6eScindi 337aec1d6eScindimy $PROGNAME = basename($0); 347aec1d6eScindi 357aec1d6eScindimy ($funcunit, $error); 367aec1d6eScindimy @funcunits = (); 377aec1d6eScindi 387aec1d6eScindimy $state = "initial"; 397aec1d6eScindi 407aec1d6eScindisub usage() { 417aec1d6eScindi print STDERR "Usage: $PROGNAME inputfile\n"; 427aec1d6eScindi exit(2); 437aec1d6eScindi} 447aec1d6eScindi 457aec1d6eScindisub bail() { 467aec1d6eScindi print STDERR "$PROGNAME: ", join(" ", @_), "\n"; 477aec1d6eScindi exit(1); 487aec1d6eScindi} 497aec1d6eScindi 507aec1d6eScindisub parsebail() { 517aec1d6eScindi print STDERR "$PROGNAME: $::infile: $.: ", join(" ", @_), "\n"; 527aec1d6eScindi exit(1); 537aec1d6eScindi} 547aec1d6eScindi 557aec1d6eScindisub print_header() { 567aec1d6eScindi print "#include \"ao_mca_disp.h\"\n\n"; 577aec1d6eScindi} 587aec1d6eScindi 597aec1d6eScindisub print_footer() { 607aec1d6eScindi print "const ao_error_disp_t *ao_error_disp[] = {\n"; 617aec1d6eScindi 627aec1d6eScindi foreach my $name (@funcunits) { 637aec1d6eScindi print "\t$name,\n"; 647aec1d6eScindi } 657aec1d6eScindi 667aec1d6eScindi print "};\n"; 677aec1d6eScindi} 687aec1d6eScindi 697aec1d6eScindisub funcunit_begin() { 707aec1d6eScindi my $arrnm = "ao_error_disp_" . $_[0]; 717aec1d6eScindi print "static const ao_error_disp_t " . $arrnm . "[] = {\n"; 727aec1d6eScindi 737aec1d6eScindi @funcunits = (@funcunits, $arrnm); 747aec1d6eScindi} 757aec1d6eScindi 767aec1d6eScindisub funcunit_end() { 777aec1d6eScindi print "\tNULL\n};\n\n"; 787aec1d6eScindi} 797aec1d6eScindi 807aec1d6eScindisub error_begin() { 817aec1d6eScindi my ($ereport_name) = @_; 827aec1d6eScindi 837aec1d6eScindi $ereport_name =~ tr/[a-z]./[A-Z]_/; 847aec1d6eScindi my $flags_name = $ereport_name; 857aec1d6eScindi $flags_name =~ s/EREPORT_/EREPORT_PAYLOAD_FLAGS_/; 867aec1d6eScindi 877aec1d6eScindi print "\tFM_$ereport_name,\n\tFM_$flags_name,\n"; 887aec1d6eScindi} 897aec1d6eScindi 907aec1d6eScindisub error_end() { 917aec1d6eScindi print "\t},\n\n"; 927aec1d6eScindi} 937aec1d6eScindi 947aec1d6eScindisub print_bits() { 957aec1d6eScindi my $name = $_[0]; 967aec1d6eScindi my @bits = @_[1..$#_]; 977aec1d6eScindi 987aec1d6eScindi if (@bits == 0) { 997aec1d6eScindi print "\t0,"; 1007aec1d6eScindi } elsif (@bits == 1) { 1017aec1d6eScindi print "\t$bits[0],"; 1027aec1d6eScindi } else { 1037aec1d6eScindi print "\t( ", join(" | ", @bits), " ),"; 1047aec1d6eScindi } 1057aec1d6eScindi 106*a307a255Sgavinm print " /* $name */" if (defined $name); 107*a307a255Sgavinm print "\n"; 1087aec1d6eScindi} 1097aec1d6eScindi 1107aec1d6eScindisub field_burst() { 1117aec1d6eScindi my ($field, $valuesref, $name, $prefix) = @_; 1127aec1d6eScindi 1137aec1d6eScindi if ($field eq "-") { 1147aec1d6eScindi return (); 1157aec1d6eScindi } 1167aec1d6eScindi 1177aec1d6eScindi map { 1187aec1d6eScindi if (!defined ${$valuesref}{$_}) { 1197aec1d6eScindi &parsebail("unknown $name value `$_'"); 1207aec1d6eScindi } 1217aec1d6eScindi $_ = ${$valuesref}{$_}; 1227aec1d6eScindi tr/[a-z]/[A-Z]/; 1237aec1d6eScindi $prefix . "_" . $_; 1247aec1d6eScindi } split(/\//, $field); 1257aec1d6eScindi} 1267aec1d6eScindi 1277aec1d6eScindisub bin2dec() { 1287aec1d6eScindi my $bin = $_[0]; 1297aec1d6eScindi my $dec = 0; 1307aec1d6eScindi 1317aec1d6eScindi foreach my $bit (split(//, $bin)) { 1327aec1d6eScindi $dec = $dec * 2 + ($bit eq "1" ? 1 : 0); 1337aec1d6eScindi } 1347aec1d6eScindi 1357aec1d6eScindi $dec; 1367aec1d6eScindi} 1377aec1d6eScindi 1387aec1d6eScindisub state_funcunit() { 1397aec1d6eScindi my $val = $_[0]; 1407aec1d6eScindi 1417aec1d6eScindi if (defined $::funcunit) { 1427aec1d6eScindi &funcunit_end(); 1437aec1d6eScindi } 1447aec1d6eScindi 1457aec1d6eScindi $::funcunit = $val; 1467aec1d6eScindi undef $::error; 1477aec1d6eScindi &funcunit_begin($::funcunit); 1487aec1d6eScindi} 1497aec1d6eScindi 1507aec1d6eScindisub state_desc() { 1517aec1d6eScindi my $desc = $_[0]; 1527aec1d6eScindi 1537aec1d6eScindi print "\t/* $desc */\n\t{\n"; 1547aec1d6eScindi} 1557aec1d6eScindi 1567aec1d6eScindisub state_error() { 1577aec1d6eScindi $::error = $_[0]; 1587aec1d6eScindi &error_begin($::error); 1597aec1d6eScindi} 1607aec1d6eScindi 1617aec1d6eScindisub state_mask_on() { 1627aec1d6eScindi @::mask_on = map { tr/[a-z]/[A-Z]/; $_; } split(/,\s*/, $_[0]); 1637aec1d6eScindi} 1647aec1d6eScindi 1657aec1d6eScindisub state_mask_off() { 1667aec1d6eScindi my @mask_off = map { tr/[a-z]/[A-Z]/; $_; } split(/,\s*/, $_[0]); 1677aec1d6eScindi 1687aec1d6eScindi &print_bits("mask", @::mask_on, @mask_off); 1697aec1d6eScindi &print_bits("mask_res", @::mask_on); 1707aec1d6eScindi} 1717aec1d6eScindi 1727aec1d6eScindisub state_code() { 1737aec1d6eScindi my ($ext, $type, $pp, $t, $r4, $ii, $ll, $tt) = split(/\s+/, $_[0]); 1747aec1d6eScindi 1757aec1d6eScindi my %tt_values = ( instr => 1, data => 1, gen => 1, '-' => 1 ); 1767aec1d6eScindi my %ll_values = ( l0 => 1, l1 => 1, l2 => 1, lg => 1 ); 1777aec1d6eScindi 1787aec1d6eScindi my %r4_values = ( 1797aec1d6eScindi gen => 'gen', 1807aec1d6eScindi rd => 'rd', 1817aec1d6eScindi wr => 'wr', 1827aec1d6eScindi drd => 'drd', 1837aec1d6eScindi dwr => 'dwr', 1847aec1d6eScindi ird => 'ird', 1857aec1d6eScindi pf => 'prefetch', 1867aec1d6eScindi ev => 'evict', 1877aec1d6eScindi snp => 'snoop', 1887aec1d6eScindi '-' => '-'); 1897aec1d6eScindi 1907aec1d6eScindi my %pp_values = ( 1917aec1d6eScindi src => 'src', 1927aec1d6eScindi rsp => 'rsp', 1937aec1d6eScindi obs => 'obs', 1947aec1d6eScindi gen => 'gen', 1957aec1d6eScindi '-' => '-' ); 1967aec1d6eScindi 1977aec1d6eScindi my %t_values = ( 0 => 1, 1 => 1, '-' => 1 ); 1987aec1d6eScindi 1997aec1d6eScindi my %ii_values = ( 2007aec1d6eScindi mem => 'mem', 2017aec1d6eScindi io => 'io', 2027aec1d6eScindi gen => 'gen', 2037aec1d6eScindi '-' => '-' ); 2047aec1d6eScindi 2057aec1d6eScindi if (!defined $tt_values{$tt}) { 2067aec1d6eScindi &parsebail("unknown tt value `$tt'"); 2077aec1d6eScindi } 2087aec1d6eScindi 2097aec1d6eScindi if (!defined $ll_values{$ll}) { 2107aec1d6eScindi &parsebail("unknown ll value `$ll'"); 2117aec1d6eScindi } 2127aec1d6eScindi 2137aec1d6eScindi my @r4 = &field_burst($r4, \%r4_values, "r4", "AO_MCA_R4_BIT"); 2147aec1d6eScindi 2157aec1d6eScindi my @pp = ($pp eq '-') ? () : 2167aec1d6eScindi &field_burst($pp, \%pp_values, "pp", "AO_MCA_PP_BIT"); 2177aec1d6eScindi 2187aec1d6eScindi if (!defined $t_values{$t}) { 2197aec1d6eScindi &parsebail("unknown t value `$t'"); 2207aec1d6eScindi } 2217aec1d6eScindi 2227aec1d6eScindi my @ii = ($ii eq '-') ? () : 2237aec1d6eScindi &field_burst($ii, \%ii_values, "ii", "AO_MCA_II_BIT"); 2247aec1d6eScindi 2257aec1d6eScindi map { 2267aec1d6eScindi tr/[a-z]/[A-Z]/; 2277aec1d6eScindi } ($ii, $ll, $tt); 2287aec1d6eScindi 2297aec1d6eScindi if ($type eq "bus") { 2307aec1d6eScindi if ($pp eq "-" || $t eq "-" || $r4 eq "-" || $ii eq "-" || 2317aec1d6eScindi $ll eq "-" || 2327aec1d6eScindi $tt ne "-") { 2337aec1d6eScindi &parsebail("invalid members for bus code type"); 2347aec1d6eScindi } 2357aec1d6eScindi 2367aec1d6eScindi print "\tAMD_ERRCODE_MKBUS(" . 2377aec1d6eScindi "0, " . # pp 2387aec1d6eScindi "AMD_ERRCODE_T_" . ($t ? "TIMEOUT" : "NONE") . ", " . 2397aec1d6eScindi "0, " . # r4 2407aec1d6eScindi "0, " . # ii 2417aec1d6eScindi "AMD_ERRCODE_LL_$ll),\n"; 2427aec1d6eScindi 2437aec1d6eScindi } elsif ($type eq "mem") { 2447aec1d6eScindi if ($r4 eq "-" || $tt eq "-" || $ll eq "-" || 2457aec1d6eScindi $pp ne "-" || $t ne "-" || $ii ne "-") { 2467aec1d6eScindi &parsebail("invalid members for mem code type"); 2477aec1d6eScindi } 2487aec1d6eScindi 2497aec1d6eScindi print "\tAMD_ERRCODE_MKMEM(" . 2507aec1d6eScindi "0, " . # r4 2517aec1d6eScindi "AMD_ERRCODE_TT_$tt, " . 2527aec1d6eScindi "AMD_ERRCODE_LL_$ll),\n"; 2537aec1d6eScindi 2547aec1d6eScindi } elsif ($type eq "tlb") { 2557aec1d6eScindi if ($tt eq "-" || $ll eq "-" || 2567aec1d6eScindi $r4 ne "-" || $pp ne "-" || $t ne "-" || $ii ne "-") { 2577aec1d6eScindi &parsebail("invalid members for tlb code type"); 2587aec1d6eScindi } 2597aec1d6eScindi 2607aec1d6eScindi print "\tAMD_ERRCODE_MKTLB(" . 2617aec1d6eScindi "AMD_ERRCODE_TT_$tt, " . 2627aec1d6eScindi "AMD_ERRCODE_LL_$ll),\n"; 2637aec1d6eScindi } else { 2647aec1d6eScindi &parsebail("unknown code type `$type'"); 2657aec1d6eScindi } 2667aec1d6eScindi 2677aec1d6eScindi print "\t" . &bin2dec($ext) . ", /* ext code $ext */\n"; 2687aec1d6eScindi 2697aec1d6eScindi &print_bits("pp_bits", @pp); 2707aec1d6eScindi &print_bits("ii_bits", @ii); 2717aec1d6eScindi &print_bits("r4_bits", @r4); 2727aec1d6eScindi} 2737aec1d6eScindi 2747aec1d6eScindisub state_panic() { 275*a307a255Sgavinm my @vals = split(/,\s*/, $_[0]); 2767aec1d6eScindi 277*a307a255Sgavinm if ($#vals < 0) { 2787aec1d6eScindi print "\t0, /* panic_when */\n"; 2797aec1d6eScindi } else { 280*a307a255Sgavinm @vals = map { tr/[a-z]/[A-Z]/; "AO_AED_PANIC_" . $_; } @vals; 281*a307a255Sgavinm &print_bits("panic_when", @vals); 2827aec1d6eScindi } 2837aec1d6eScindi} 2847aec1d6eScindi 2857aec1d6eScindisub state_flags() { 2867aec1d6eScindi my @flags = split(/,\s*/, $_[0]); 2877aec1d6eScindi 2887aec1d6eScindi @flags = map { tr/[a-z]/[A-Z]/; "AO_AED_F_" . $_; } @flags; 2897aec1d6eScindi 2907aec1d6eScindi &print_bits("flags", @flags); 2917aec1d6eScindi} 2927aec1d6eScindi 2937aec1d6eScindimy %stateparse = ( 2947aec1d6eScindi funcunit => [ \&state_funcunit, "desc" ], 2957aec1d6eScindi desc => [ \&state_desc, "error" ], 2967aec1d6eScindi error => [ \&state_error, "mask on" ], 2977aec1d6eScindi 'mask on' => [ \&state_mask_on, "mask off" ], 2987aec1d6eScindi 'mask off' => [ \&state_mask_off, "code" ], 2997aec1d6eScindi code => [ \&state_code, "panic" ], 3007aec1d6eScindi panic => [ \&state_panic, "flags" ], 3017aec1d6eScindi flags => [ \&state_flags, "initial" ] 3027aec1d6eScindi); 3037aec1d6eScindi 3047aec1d6eScindiusage unless (@ARGV == 1); 3057aec1d6eScindi 3067aec1d6eScindimy $infile = $ARGV[0]; 3077aec1d6eScindiopen(INFILE, "<$infile") || &bail("failed to open $infile: $!"); 3087aec1d6eScindi 3097aec1d6eScindi&print_header(); 3107aec1d6eScindi 3117aec1d6eScindiwhile (<INFILE>) { 3127aec1d6eScindi chop; 3137aec1d6eScindi 3147aec1d6eScindi /^#/ && next; 3157aec1d6eScindi /^$/ && next; 3167aec1d6eScindi 3177aec1d6eScindi if (!/^\s*(\S[^=]*\S)\s*=\s*(\S.*)?$/) { 3187aec1d6eScindi &parsebail("failed to parse"); 3197aec1d6eScindi } 3207aec1d6eScindi 3217aec1d6eScindi my ($keyword, $val) = ($1, $2); 3227aec1d6eScindi 3237aec1d6eScindi if ($state eq "initial") { 3247aec1d6eScindi if ($keyword eq "funcunit") { 3257aec1d6eScindi $state = "funcunit"; 3267aec1d6eScindi } elsif ($keyword eq "desc") { 3277aec1d6eScindi $state = "desc"; 3287aec1d6eScindi } else { 3297aec1d6eScindi &parsebail("unexpected keyword $keyword between " . 3307aec1d6eScindi "errors"); 3317aec1d6eScindi } 3327aec1d6eScindi 3337aec1d6eScindi } elsif ($state eq "desc") { 3347aec1d6eScindi if ($keyword eq "funcunit") { 3357aec1d6eScindi $state = "funcunit"; 3367aec1d6eScindi } 3377aec1d6eScindi } 3387aec1d6eScindi 3397aec1d6eScindi if ($keyword ne $state) { 3407aec1d6eScindi &parsebail("keyword `$keyword' invalid here; expected `$state'"); 3417aec1d6eScindi } 3427aec1d6eScindi 3437aec1d6eScindi if (!defined $stateparse{$state}) { 3447aec1d6eScindi &parsebail("attempt to transition to invalid state `$state'"); 3457aec1d6eScindi } 3467aec1d6eScindi 3477aec1d6eScindi my ($handler, $next) = @{$stateparse{$state}}; 3487aec1d6eScindi 3497aec1d6eScindi &{$handler}($val); 3507aec1d6eScindi 3517aec1d6eScindi $state = $next; 3527aec1d6eScindi 3537aec1d6eScindi if ($state eq "initial") { 3547aec1d6eScindi &error_end(); 3557aec1d6eScindi } 3567aec1d6eScindi} 3577aec1d6eScindi 3587aec1d6eScindiclose(INFILE); 3597aec1d6eScindi 3607aec1d6eScindiif ($state ne "initial" && $state ne "desc") { 3617aec1d6eScindi &bail("input file ended prematurely"); 3627aec1d6eScindi} 3637aec1d6eScindi 3647aec1d6eScindiif (defined $::funcunit) { 3657aec1d6eScindi &funcunit_end(); 3667aec1d6eScindi} else { 3677aec1d6eScindi &bail("no functional units defined"); 3687aec1d6eScindi} 3697aec1d6eScindi 3707aec1d6eScindi&print_footer; 371