#!/usr/bin/perl # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # $Source: src/usr/hwpf/plat/fapiPlatCreateHwpErrParser.pl $ # # IBM CONFIDENTIAL # # COPYRIGHT International Business Machines Corp. 2012,2014 # # p1 # # Object Code Only (OCO) source materials # Licensed Internal Code Source Materials # IBM HostBoot Licensed Internal Code # # The source code for this program is not published or otherwise # divested of its trade secrets, irrespective of what has been # deposited with the U.S. Copyright Office. # # Origin: 30 # # IBM_PROLOG_END_TAG # # Purpose: This perl script will parse HWP Error XML files and create a # file containing functions that parses the return code and FFDC # data in HWP error logs # # Author: Mike Jones # use strict; #------------------------------------------------------------------------------ # Print Command Line Help #------------------------------------------------------------------------------ my $numArgs = $#ARGV + 1; if ($numArgs < 2) { print ("Usage: fapiPlatCreateHwpErrParser.pl ...\n"); print (" This perl script will parse HWP Error XML files and create\n"); print (" a file called fapiPlatHwpErrParser.H that contains functions to\n"); print (" parse the return code and FFDC data in HWP error logs\n"); exit(1); } #------------------------------------------------------------------------------ # Specify perl modules to use #------------------------------------------------------------------------------ use Digest::MD5 qw(md5_hex); use XML::Simple; my $xml = new XML::Simple (KeyAttr=>[]); # Uncomment to enable debug output #use Data::Dumper; #------------------------------------------------------------------------------ # Open output files for writing #------------------------------------------------------------------------------ my $rcFile = $ARGV[0]; $rcFile .= "/"; $rcFile .= "fapiPlatHwpErrParser.H"; open(TGFILE, ">", $rcFile); #------------------------------------------------------------------------------ # Print start of file information #------------------------------------------------------------------------------ print TGFILE "// fapiPlatHwpErrParser.H\n"; print TGFILE "// This file is generated by perl script fapiPlatCreateHwpErrParser.pl\n\n"; print TGFILE "#ifndef FAPIPLATHWPERRPARSER_H_\n"; print TGFILE "#define FAPIPLATHWPERRPARSER_H_\n\n"; print TGFILE "#ifdef PARSER\n\n"; print TGFILE "namespace fapi\n"; print TGFILE "{\n\n"; print TGFILE "void fapiParseHwpRc(ErrlUsrParser & i_parser,\n"; print TGFILE " void * i_pBuffer,\n"; print TGFILE " const uint32_t i_buflen)\n"; print TGFILE "{\n"; print TGFILE " uint32_t l_rc = ntohl(*(static_cast(i_pBuffer)));\n\n"; print TGFILE " switch(l_rc)\n"; print TGFILE " {\n"; #------------------------------------------------------------------------------ # For each XML file #------------------------------------------------------------------------------ foreach my $argnum (1 .. $#ARGV) { #-------------------------------------------------------------------------- # Read XML file #-------------------------------------------------------------------------- my $infile = $ARGV[$argnum]; my $errors = $xml->XMLin($infile, ForceArray => ['hwpError']); # Uncomment to get debug output of all errors #print "\nFile: ", $infile, "\n", Dumper($errors), "\n"; #-------------------------------------------------------------------------- # For each Error #-------------------------------------------------------------------------- foreach my $err (@{$errors->{hwpError}}) { #---------------------------------------------------------------------- # Get the description, remove newlines, leading and trailing spaces and # multiple spaces #---------------------------------------------------------------------- my $desc = $err->{description}; $desc =~ s/\n/ /g; $desc =~ s/^ +//g; $desc =~ s/ +$//g; $desc =~ s/ +/ /g; $desc =~ s/\"//g; #---------------------------------------------------------------------- # Print the RC description # Note that this uses the same code to calculate the error enum value # as fapiParseErrorInfo.pl. This code must be kept in sync #---------------------------------------------------------------------- my $errHash128Bit = md5_hex($err->{rc}); my $errHash24Bit = substr($errHash128Bit, 0, 6); print TGFILE " case 0x$errHash24Bit:\n"; print TGFILE " i_parser.PrintString(\"HwpReturnCode\", \"$err->{rc}\");\n"; print TGFILE " i_parser.PrintString(\"HWP Error description\", \"$desc\");\n"; print TGFILE " break;\n"; } } #------------------------------------------------------------------------------ # Print end of fapiParseHwpRc function #------------------------------------------------------------------------------ print TGFILE " default:\n"; print TGFILE " i_parser.PrintNumber(\"Unrecognized Error ID\", \"0x%x\", l_rc);\n"; print TGFILE " }\n"; print TGFILE "}\n\n"; #------------------------------------------------------------------------------ # Print start of fapiParseHwpFfdc function #------------------------------------------------------------------------------ print TGFILE "void fapiParseHwpFfdc(ErrlUsrParser & i_parser,\n"; print TGFILE " void * i_pBuffer,\n"; print TGFILE " const uint32_t i_buflen)\n"; print TGFILE "{\n"; print TGFILE " const uint32_t CFAM_DATA_LEN = 4;\n"; print TGFILE " const uint32_t SCOM_DATA_LEN = 8;\n"; print TGFILE " const uint32_t POS_LEN = 4;\n"; print TGFILE " uint8_t * l_pBuffer = static_cast(i_pBuffer);\n"; print TGFILE " int32_t l_buflen = i_buflen;\n\n"; print TGFILE " // The first uint32_t is the FFDC ID\n"; print TGFILE " uint32_t * l_pFfdcId = static_cast(i_pBuffer);\n"; print TGFILE " uint32_t l_ffdcId = ntohl(*l_pFfdcId);\n"; print TGFILE " l_pBuffer += sizeof(l_ffdcId);\n"; print TGFILE " l_buflen -= sizeof(l_ffdcId);\n"; print TGFILE " switch(l_ffdcId)\n"; print TGFILE " {\n"; #------------------------------------------------------------------------------ # For each XML file #------------------------------------------------------------------------------ foreach my $argnum (1 .. $#ARGV) { #-------------------------------------------------------------------------- # Read XML file #-------------------------------------------------------------------------- my $infile = $ARGV[$argnum]; my $errors = $xml->XMLin($infile, ForceArray => ['hwpError', 'ffdc', 'registerFfdc', 'cfamRegister', 'scomRegister']); # Uncomment to get debug output of all errors #print "\nFile: ", $infile, "\n", Dumper($errors), "\n"; #-------------------------------------------------------------------------- # If it is an FFDC section resulting from a element, print # out the FFDC name and hexdump the data #-------------------------------------------------------------------------- foreach my $err (@{$errors->{hwpError}}) { foreach my $ffdc (@{$err->{ffdc}}) { #------------------------------------------------------------------ # Figure out the FFDC ID stored in the data. This is calculated in # the same way as fapiParseErrorInfo.pl. This code must be kept in # sync #------------------------------------------------------------------ my $ffdcName = $err->{rc} . "_" . $ffdc; my $ffdcHash128Bit = md5_hex($ffdcName); my $ffdcHash32Bit = substr($ffdcHash128Bit, 0, 8); print TGFILE " case 0x$ffdcHash32Bit:\n"; print TGFILE " i_parser.PrintString(\"HwpReturnCode\", \"$err->{rc}\");\n"; print TGFILE " i_parser.PrintString(\"FFDC:\", \"$ffdc\");\n"; print TGFILE " if (l_buflen) "; print TGFILE "{i_parser.PrintHexDump(l_pBuffer, l_buflen);}\n"; print TGFILE " break;\n"; } } #-------------------------------------------------------------------------- # If it is an FFDC section resulting from a element, print # out the ID and walk through the registers, printing each out #-------------------------------------------------------------------------- foreach my $registerFfdc (@{$errors->{registerFfdc}}) { #---------------------------------------------------------------------- # Figure out the FFDC ID stored in the data. This is calculated in the # same way as fapiParseErrorInfo.pl. This code must be kept in sync #---------------------------------------------------------------------- my $ffdcName = $registerFfdc->{id}; my $ffdcHash128Bit = md5_hex($ffdcName); my $ffdcHash32Bit = substr($ffdcHash128Bit, 0, 8); print TGFILE " case 0x$ffdcHash32Bit:\n"; print TGFILE " i_parser.PrintString(\"Register FFDC:\", \"$ffdcName\");\n"; print TGFILE " while (l_buflen > 0)\n"; print TGFILE " {\n"; print TGFILE " if (l_buflen >= POS_LEN)\n"; print TGFILE " {\n"; print TGFILE " uint32_t * l_pBufferTemp = reinterpret_cast(l_pBuffer);\n"; print TGFILE " i_parser.PrintNumber(\"Chip Position:\",\"%X\",ntohl(*l_pBufferTemp));\n"; print TGFILE " l_pBufferTemp = NULL;\n"; print TGFILE " l_pBuffer+= POS_LEN;\n"; print TGFILE " l_buflen -= POS_LEN;\n"; print TGFILE " }\n"; foreach my $cfamRegister (@{$registerFfdc->{cfamRegister}}) { print TGFILE " if (l_buflen >= CFAM_DATA_LEN)\n"; print TGFILE " {\n"; print TGFILE " i_parser.PrintString(\"CFAM Register:\", \"$cfamRegister\");\n"; print TGFILE " i_parser.PrintHexDump(l_pBuffer, CFAM_DATA_LEN);\n"; print TGFILE " l_pBuffer+= CFAM_DATA_LEN;\n"; print TGFILE " l_buflen -= CFAM_DATA_LEN;\n"; print TGFILE " }\n"; } foreach my $scomRegister (@{$registerFfdc->{scomRegister}}) { print TGFILE " if (l_buflen >= SCOM_DATA_LEN)\n"; print TGFILE " {\n"; print TGFILE " i_parser.PrintString(\"SCOM Register:\", \"$scomRegister\");\n"; print TGFILE " i_parser.PrintHexDump(l_pBuffer, SCOM_DATA_LEN);\n"; print TGFILE " l_pBuffer+= SCOM_DATA_LEN;\n"; print TGFILE " l_buflen -= SCOM_DATA_LEN;\n"; print TGFILE " }\n"; } print TGFILE " }\n"; print TGFILE " break;\n"; } } #------------------------------------------------------------------------------ # Print end of fapiParseHwpFfdc function #------------------------------------------------------------------------------ print TGFILE " default:\n"; print TGFILE " i_parser.PrintNumber(\"Unrecognized FFDC\", \"0x%x\", l_ffdcId);\n"; print TGFILE " if (l_buflen) "; print TGFILE "{i_parser.PrintHexDump(l_pBuffer, l_buflen);}\n"; print TGFILE " }\n\n"; print TGFILE "}\n\n"; #------------------------------------------------------------------------------ # Print end of file info #------------------------------------------------------------------------------ print TGFILE "}\n\n"; print TGFILE "#endif\n"; print TGFILE "#endif\n"; #------------------------------------------------------------------------------ # Close output file #------------------------------------------------------------------------------ close(TGFILE);