summaryrefslogtreecommitdiffstats
path: root/src/build/debug
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2017-01-30 12:15:20 -0600
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2017-02-17 19:10:01 -0500
commit6527a98aab49b2461b986e910b356d6bdd9b9409 (patch)
tree90cc0c4699a9b94ad5d4b0b2ae486989eb496e6b /src/build/debug
parentd5656f1005c5d36ab6077d980fb0c1fa19350a6e (diff)
downloadtalos-hostboot-6527a98aab49b2461b986e910b356d6bdd9b9409.tar.gz
talos-hostboot-6527a98aab49b2461b986e910b356d6bdd9b9409.zip
Script to fetch eSEL records and format the PEL data.
Adding the eSEL.pl script into master (was already in master-p8) as eSEL_ami.pl. This script is used to fetch extended SEL data from a AMI (or compatible) BMC then format it using an available errl binary. Change-Id: I9f7d5050fe3a872762f970979873ad640fc5476c Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/35591 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Matthew A. Ploetz <maploetz@us.ibm.com> Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Diffstat (limited to 'src/build/debug')
-rwxr-xr-xsrc/build/debug/eSEL_ami.pl474
1 files changed, 474 insertions, 0 deletions
diff --git a/src/build/debug/eSEL_ami.pl b/src/build/debug/eSEL_ami.pl
new file mode 100755
index 000000000..251b0a10d
--- /dev/null
+++ b/src/build/debug/eSEL_ami.pl
@@ -0,0 +1,474 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/debug/eSEL_ami.pl $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2015,2017
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+
+use strict;
+use Cwd;
+use POSIX;
+use Switch;
+use Getopt::Long;
+use File::Basename;
+
+# options and usage
+my $target = ''; # Target BMC name / IP (convert to IP)
+my $userid = 'ADMIN'; # BMC user id to use for the ipmitool cmd
+my $passwd = 'admin'; # BMC password to use for the ipmitool cmd
+my $dirname = dirname(__FILE__);
+my $errl_path = $dirname;
+my $fspt_path = $dirname;
+my $img_path = $dirname;
+my $output_path = cwd();
+my $debug = 0;
+my $usage = 0;
+my $version = "201510021400";
+
+sub printUsage
+{
+ print "All directory paths passed as arguments to the tool MUST be Fully qualified path names.\n";
+ print "Usage: eSEL_ami.pl [-h] -t <BMC Name / IP> [-U <userid>] [-P <password>]\n";
+ print " [-o <output dir>] # default: $output_path\n";
+ print " [-e <errl dir>] # default: $errl_path \n";
+ print " [-f <fsp-trace dir>] # default $fspt_path\n";
+ print " [-i <img dir (for hbotStringFile & hbicore.syms>] # default $img_path\n";
+ print "version: $version\n";
+ print "\n";
+ print "This tool will ONLY process hostboot eSEL entries that contain PEL data.\n";
+ exit;
+}
+
+GetOptions(
+ "t:s" => \$target,
+ "U:s" => \$userid,
+ "P:s" => \$passwd,
+ "e:s" => \$errl_path,
+ "f:s" => \$fspt_path,
+ "i:s" => \$img_path,
+ "o:s" => \$output_path,
+ "v+" => \$debug,
+ "h" => \$usage,
+ ) || printUsage();
+
+if ($usage)
+{
+ printUsage();
+}
+
+#################################
+# Variables used for the script #
+#################################
+my $cmd = ''; # Used to store the ipmitool commands
+my $string_file = '';
+my $cd_syms_dir = '';
+
+###############################################################
+# Add code to check that we have the needed fields filled in #
+###############################################################
+($target) || die "Missing BMC target name / IP\n";
+($userid) || die "Missing BMC user id\n";
+($passwd) || die "Missing BMC password\n";
+
+# check if we can find the fsp-trace program
+if ( -e "$fspt_path/fsp-trace")
+{
+ # it's good, build PATH so errl can find it.
+ $fspt_path = "PATH=$fspt_path:\$PATH";
+}
+else
+{
+ print "can't find fsp-trace in \"$fspt_path\"; no fsp-traces\n";
+ $fspt_path = "";
+}
+
+$img_path = glob($img_path);
+# check if we can get to the string file
+if (-e "$img_path/hbotStringFile")
+{
+ # it's good, build errl option
+ $string_file = "-t $img_path/hbotStringFile";
+}
+else
+{
+ print "can't find hbotStringFile in \"$img_path\"; incomplete fsp-traces\n";
+ $string_file = "";
+}
+
+# check if we can find a syms file (for backtrace decoding)
+if (-e "$img_path/hbicore.syms")
+{
+ # it's good, build cd option
+ $cd_syms_dir = "cd $img_path &&";
+}
+else
+{
+ print "can't find hbicore.syms in \"$img_path\"; no backtrace resolution\n";
+ $cd_syms_dir = "";
+}
+
+if ($debug > 0)
+{
+ print "target: \"$target\"\n";
+ print "userid: \"$userid\"\n";
+ print "passwd: \"$passwd\"\n";
+ print "errl_path: \"$errl_path\"\n";
+ print "fspt_path: \"$fspt_path\"\n";
+ print "img_path: \"$img_path\"\n";
+ print "output_path: \"$output_path\"\n";
+ print "debug: $debug\n";
+ print "string_file: $string_file\n";
+ print "cd_syms_dir: $cd_syms_dir\n";
+ print "version: $version\n";
+}
+
+#########################################################################################
+# Main body #
+#########################################################################################
+
+# Figure out the file name for logging the status.
+my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
+my $nice_timestamp = sprintf ( "%02d%02d%02d.%02d%02d%02d",$year-100,$mon+1,$mday,$hour,$min,$sec);
+chomp($target);
+my $log_file = "$output_path/$target.$nice_timestamp.eSel";
+open LOG_FILE, ">$log_file" or die "Unable to open the eSEL text file $log_file\n";
+
+################################################################
+# Run ipmitool setl list to get the list of sels and flag eSEL #
+################################################################
+my @eSEL_length; # size of each eSEL
+my $total_size = 0; # total errlog buffer size
+my @SEL_list; # full SEL list
+my @eSEL_list; # entries that have eSEL data
+
+$cmd = "ipmitool -I lanplus -H $target -U $userid -P $passwd sel list 2>&1";
+$debug && print ">>$cmd\n";
+@SEL_list = qx/$cmd/; # Execute the command
+($debug > 1) && print " @SEL_list";
+if (@SEL_list[0] =~ /RAKP/) # some sort of error on the ipmi cmd
+{
+ print "ERROR: \"$cmd\" failed:\n";
+ print " @SEL_list";
+ exit 1;
+}
+
+my $sel_count = @SEL_list; # Count the number of SELs found
+for(my $i=0; $i<$sel_count; $i++)
+{
+ # If the SEL entry contains the "df" key, AND it has '040020' it's our eSEL
+ if (($SEL_list[$i] =~ / OEM record df /) && ($SEL_list[$i] =~ /040020/))
+ {
+ push @eSEL_list, $SEL_list[$i];
+ }
+}
+
+# Check if there's no eSEL
+my $esel_count = @eSEL_list;
+if ($esel_count == 0)
+{
+ print "No eSEL records with PEL data found.\n";
+ exit 0;
+}
+print "Found $esel_count eSELs with PEL data\n";
+
+for(my $i=0; $i<$esel_count; $i++)
+{
+ my @tmp = split(/\|/, $eSEL_list[$i]); # Split the entry on the |
+ $tmp[0] =~ s/^\s+//; # Remove the extra white space
+ my $sel_record = hex($tmp[0]); # Convert the hex value of the record to ascii
+
+ $cmd = "ipmitool -I lanplus -H $target -U $userid -P $passwd sel get $sel_record 2>&1";
+ $debug && print ">>$cmd\n";
+ print "<";
+ print LOG_FILE "\n$cmd\n";
+ my @eSEL = qx/$cmd/; # Execute the command
+ ($debug > 1) && print "@eSEL";
+ print LOG_FILE " @eSEL\n";
+
+ # get the eSEL data
+ my $eSEL_hex = ConvertToHex($sel_record); # 2 bytes, ie: 0x01 0x02 for record 0x0201
+ # raw 0x32 0xf1 is AMI partial_get_esel command. command format is (bytes)
+ # 1:2 SEL Record ID (byte reversed)
+ # 3:4 Offset within the Record to be fetched. (byte reversed)
+ $cmd = "ipmitool -I lan -H $target -U $userid -P $passwd raw 0x32 0xf1 $eSEL_hex 0x00 0x00 2>&1";
+ print ">";
+ $debug && print ">>$cmd\n";
+ print LOG_FILE "$cmd\n";
+ @eSEL = qx/$cmd/; # Execute the command
+ ($debug > 1) && print " @eSEL";
+ print LOG_FILE " @eSEL";
+
+ #################################################
+ # check to see if there is more data
+ #################################################
+ # response (bytes) from partial_get_esel is:
+ # 1:2 Total Length of the Extended SEL (byte reversed)
+ # 3 Progress
+ # 1 Last chunk
+ # 0 Still there is some record to read
+ # 4:5 Remaining Bytes to Read (byte reversed)
+ # 6:N Extended SEL data. [ Max size of 2K]
+ my @response = split(' ', "@eSEL[0]");
+ if ($response[0] =~ /Unable/) # some sort of error on the ipmi cmd
+ {
+ if( "@eSEL[0]" =~ /rsp=0x83/ )
+ {
+ # Unable to send RAW command (channel=0x0 netfn=0x32 lun=0x0 cmd=0xf1 rsp=0x83): Unknown (0x83)
+ print "esel $sel_record has been purged from BMC -- skipping\n";
+ }
+ else
+ {
+ print "Error on partial_get_esel of sel $sel_record\n";
+ print "@eSEL[0]\n";
+ }
+ push @eSEL_length, 0; # 0 PEL length
+ next;
+ }
+
+ my $progress = $response[2];
+ $debug && print "progress code $progress\n";
+ my $tmph = "$response[1]$response[0]";
+ my $tmp = hex($tmph);
+ my $selSizeHex = $tmph;
+ my $selSizeDec = $tmp;
+ push @eSEL_length, $tmp - 16; # PEL length is SEL size - 16 (SELRecord)
+ $total_size += $tmp-16;
+
+ while ($progress == 0)
+ {
+ $tmph = "$response[4]$response[3]";
+ $debug && print "remaining size is 0x$tmph\n";
+
+ my $size_left = $selSizeDec - hex($tmph); # offset for this next chunk
+ my $hex_offset = ConvertToHex($size_left); # 2 bytes, ie: 0x01 0x02 for offset 0x0201
+
+ ################################
+ # Run the raw command we built #
+ ################################
+ $cmd = "ipmitool -I lan -H $target -U $userid -P $passwd raw 0x32 0xf1 $eSEL_hex $hex_offset 2>&1";
+ $debug && print ">>$cmd\n";
+ print LOG_FILE "$cmd\n";
+ @eSEL = qx/$cmd/; # Execute the command
+ ($debug > 1) && print " @eSEL";
+ print LOG_FILE " @eSEL";
+
+ @response = split(' ', "@eSEL[0]");
+ if ($response[0] =~ /Unable/) # some sort of error on the ipmi cmd
+ {
+ $progress = -1;
+ $debug && print "Error on partial_get_esel of sel $eSEL_hex\n";
+ }
+ else
+ {
+ $progress = $response[2];
+ $debug && print "progress code $progress\n";
+ }
+ }
+ if ($progress == 1) # successful 'exit'
+ {
+ $debug && print "eSEL Size = 0x$selSizeHex ($selSizeDec) bytes\n\n";
+ print LOG_FILE "eSEL Size = 0x$selSizeHex ($selSizeDec) bytes\n\n";
+ }
+ else
+ {
+ # error - ignore this eSEL
+ }
+}
+
+close LOG_FILE;
+print "\neSEL text file: $log_file\n";
+
+# convert to binary errorlog buffer
+ConvertToErrorlogBuffer($log_file);
+
+# open and create errorlog text output file, is possible
+if (-e "$errl_path/errl")
+{
+ my $txt_file_name = "$log_file.text";
+ open TXT_FILE, ">", $txt_file_name or die "Unable to open TXT_FILE $txt_file_name\n";
+ print "Error log text file: $txt_file_name\n";
+
+ my $bin_file_name = "$log_file.binary";
+
+ $cmd = "$cd_syms_dir $fspt_path $errl_path/errl --file=$bin_file_name $string_file -d 2>&1";
+ $debug && print "$cmd\n";
+ my @txt = qx/$cmd/; # Execute the command
+ print TXT_FILE " @txt";
+ ($debug > 1) && print " @txt";
+
+ close TXT_FILE;
+}
+else
+{
+ print "can't find errl in $errl_path; no formatted PEL data\n";
+}
+
+# all done
+exit;
+
+#########################################################################################
+# Functions #
+#########################################################################################
+sub ConvertToHex
+{
+ my $in = @_[0];
+ my $hex = sprintf("%04x",$in); # Convert the value passed to a 4 digit hex
+ $hex = sprintf("%s",$hex); # Convert the hex value to a string
+ my $a = substr $hex, 0, 2; # Break the string into 2 parts
+ my $b = substr $hex, 2, 2;
+
+ my $ret = "0x$b 0x$a";
+ ########## Must return in the format 0x00 0x00 ##########
+ return $ret;
+}
+sub ConvertToErrorlogBuffer()
+{
+ my $file = @_[0];
+
+ # Open input file for reading
+ open LOG_FILE, $file or die "Unable to open LOG_FILE $file\n";
+
+ # Open file for binary error log buffer
+ my $bin_file_name = "$file.binary";
+ print "Error log binary file: $bin_file_name\n";
+ open OUT_FILE, ">", $bin_file_name or die "Unable to open OUT_FILE $bin_file_name\n";
+
+ # Read a line, convert to unsigned long, then write to target file
+ my $skip = 0;
+ my $pel_length = 0;
+ my $first_raw = 0;
+ my $esel_index = 0;
+ while (<LOG_FILE>)
+ {
+ if($_ =~ /lanplus/)
+ {
+ $pel_length = $eSEL_length[$esel_index];
+ $debug && print "eSEL $esel_index has length $pel_length\n";
+ $esel_index = $esel_index+1;
+ $first_raw = 1; # look for first ipmitool raw command
+ $skip = 0;
+ next;
+ }
+ if ($first_raw)
+ {
+ # skip all lines until we get to the ipmitool raw command
+ if (!($_ =~ /raw/))
+ {
+ next;
+ }
+ }
+ if($_ =~ /raw/)
+ {
+ #############################################
+ # If we are at the raw command, we are at the
+ # start of the eSEL data
+ #############################################
+ # first raw commands returns
+ # >> response header:
+ # RECID 00: more bytes remaining
+ # 44 01 00 3a 00
+ # >> SEL data (16 bytes)
+ # 00 00 df 00 00 00 00 20 00 04 ff
+ # ff 07 aa 00 00
+ # >> PEL
+ # 50 48 00 30 01 00 05 00 00 00 00
+ # 0d 0d b3 9f e4 00 00 00 0d 0d b4 5f 4a 42 00 00
+ # 09 90 00 00 09 55 48 00 18 01 00 05 00 8a 03 40
+ #############################################
+ # following raw commands return
+ # >> response header:
+ # RECID 01: done bytes remaining
+ # 44 01 01 00 00
+ # >> rest of PEL
+ # 11 00 00 0d 0d b4 5f 4a 42 00 00
+ # 09 90 00 00 09 55 48 00 18 01 00 05 00 8a 03 40
+ # ...
+ #############################################
+ if ($first_raw)
+ {
+ # first raw cmd - skip SEL data
+ $first_raw = 0;
+ $skip = 1;
+ }
+ else
+ {
+ # rest of the raw cmds - no SEL data, all PEL
+ $skip = 2;
+ }
+ next;
+ }
+ # if it is the first raw command skip first line (SEL data)
+ if($skip == 1)
+ {
+ $skip = 2;
+ next;
+ }
+
+ my $input = $_;
+
+ # for second line in first raw command and first line of other raw
+ # commands skip the response header (5 bytes)
+ if($skip == 2) # ff 07 aa 00 00 50 48 00 30 01 00 05 00 00 00 00
+ {
+ $input = substr($input, 17);
+ ($debug) && print "s2> :$input:\n";
+ $skip = 0;
+ }
+ if ($pel_length <= 0)
+ {
+ next;
+ }
+ chomp($input);
+ if($input)
+ {
+ if ($input eq " ")
+ {
+ next;
+ }
+ #remove end of line character
+ $input =~ s/^\s+|\s+$//g;
+ my $linesize = split(/ /, $input);
+ $pel_length -= $linesize;
+ ($debug) && print ">$linesize> :$input:\n";
+ print OUT_FILE HexPack($input, $linesize);
+ }
+ }
+
+ # Close files
+ close LOG_FILE;
+ close OUT_FILE;
+}
+sub HexPack
+{
+ my $input = @_[0];
+ $input =~ s/^\s+|\s+$//g;
+ my @in = split(/ /, $input); # Hold the split version of the input variable
+ my $count = @_[1]; # Number of hex we want
+ my $tmp = '';
+
+ for(my $i=0; $i<$count; $i++)
+ {
+ $tmp = "$tmp$in[$i]"; # Remove the whitespace
+ }
+ my $ret = pack('H*', $tmp);
+ return $ret;
+}
OpenPOWER on IntegriCloud