summaryrefslogtreecommitdiffstats
path: root/src/build/debug
diff options
context:
space:
mode:
Diffstat (limited to 'src/build/debug')
-rw-r--r--src/build/debug/Hostboot/BlTrace.pm1
-rwxr-xr-xsrc/build/debug/Hostboot/Dump.pm14
-rwxr-xr-xsrc/build/debug/Hostboot/Gcov.pm464
-rw-r--r--src/build/debug/Hostboot/GcovModuleUnload.pm69
-rw-r--r--src/build/debug/Hostboot/PrintVMM.pm4
-rwxr-xr-xsrc/build/debug/Hostboot/_DebugFrameworkVMM.pm4
-rwxr-xr-xsrc/build/debug/eSEL.pl44
-rwxr-xr-xsrc/build/debug/ffdcExpander727
-rw-r--r--src/build/debug/simics-debug-framework.py23
9 files changed, 1208 insertions, 142 deletions
diff --git a/src/build/debug/Hostboot/BlTrace.pm b/src/build/debug/Hostboot/BlTrace.pm
index 5fd8baf18..9d9dc9988 100644
--- a/src/build/debug/Hostboot/BlTrace.pm
+++ b/src/build/debug/Hostboot/BlTrace.pm
@@ -83,6 +83,7 @@ my %traceText = (
"FA" => "PNOR Access getHBBSection findTOC no HBB section",
"FB" => "main verifyBaseImage failed",
"FC" => "main verifyBaseImage secure rom invalid",
+ "FD" => "PNOR Access findTOC handleMMIO LPC ERR returned",
);
sub formatTrace
diff --git a/src/build/debug/Hostboot/Dump.pm b/src/build/debug/Hostboot/Dump.pm
index 705638aa2..90b445df9 100755
--- a/src/build/debug/Hostboot/Dump.pm
+++ b/src/build/debug/Hostboot/Dump.pm
@@ -6,7 +6,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2018
+# Contributors Listed Below - COPYRIGHT 2012,2019
# [+] International Business Machines Corp.
#
#
@@ -106,6 +106,13 @@ sub main
$debug = 1;
}
+ # Parse 'quiet' option.
+ my $quiet = 0;
+ if (defined $args->{"quiet"})
+ {
+ $quiet = 1;
+ }
+
# Check for a different output directory
my $outdir = "./";
if (defined $args->{"outdir"})
@@ -128,7 +135,7 @@ sub main
open( OUTFH, ">$hbDumpFile" ) or die "can't open $hbDumpFile: $!\n";
binmode(OUTFH);
- ::userDisplay "Using HRMOR=". ::getHRMOR() . "\n";
+ ::userDisplay "Using HRMOR=". sprintf("0x%X",::getHRMOR()) . "\n";
# Read memory regions and output to file.
foreach my $state (@{$memory_states{int $memstate}})
@@ -152,7 +159,7 @@ sub main
$curlength = $length_remaining;
}
- ::userDisplay (sprintf "...%x@%x\n", $curlength, $curstart);
+ ::userDisplay (sprintf "...%x@%x\n", $curlength, $curstart) if !$quiet;
my $data = ::readData($curstart, $curlength);
seek OUTFH, $curstart, SEEK_SET;
@@ -187,6 +194,7 @@ sub helpInfo
options => {
"outdir=<path>" => ["Output directory for dump file"],
"debug" => ["More debug output."],
+ "quiet" => ["Less output."],
},
);
}
diff --git a/src/build/debug/Hostboot/Gcov.pm b/src/build/debug/Hostboot/Gcov.pm
index 84df2f9f9..48e71d66b 100755
--- a/src/build/debug/Hostboot/Gcov.pm
+++ b/src/build/debug/Hostboot/Gcov.pm
@@ -1,4 +1,3 @@
-#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
@@ -6,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2015
+# Contributors Listed Below - COPYRIGHT 2012,2019
# [+] International Business Machines Corp.
#
#
@@ -23,15 +22,18 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
+#!/usr/bin/perl
use strict;
+use warnings;
use File::Path;
use File::Basename;
+use IO::Handle;
package Hostboot::Gcov;
use Hostboot::_DebugFrameworkVMM qw(NotFound NotPresent getPhysicalAddr);
use Exporter;
-our @EXPORT_OK = ('main');
+our @EXPORT_OK = ('init', 'main', 'parseGcovInfo');
# NOTE:
#
@@ -50,26 +52,37 @@ our @EXPORT_OK = ('main');
use constant GCOV_EXTENDED_IMAGE_ADDRESS => (1024 * 1024 * 1024);
use constant GCOV_INFO_HEAD_SYMBOLNAME => "_gcov_info_head";
+use constant GCOV_INFO_MAGIC_SYMBOLNAME => "_gcov_info_magic";
+use constant GCOV_MAGIC_IDENTIFIER => 0xbeefb055;
-use constant GCOV_INFO_VERSION_OFFSET => 0;
-use constant GCOV_INFO_NEXT_OFFSET => GCOV_INFO_VERSION_OFFSET + 8;
-use constant GCOV_INFO_TIMESTAMP_OFFSET => GCOV_INFO_NEXT_OFFSET + 8;
-use constant GCOV_INFO_FILENAME_OFFSET => GCOV_INFO_TIMESTAMP_OFFSET + 8;
-use constant GCOV_INFO_NFUNCTIONS_OFFSET => GCOV_INFO_FILENAME_OFFSET + 8;
-use constant GCOV_INFO_FUNCTIONS_OFFSET => GCOV_INFO_NFUNCTIONS_OFFSET + 8;
-use constant GCOV_INFO_CTRMASK_OFFSET => GCOV_INFO_FUNCTIONS_OFFSET + 8;
-use constant GCOV_INFO_COUNTS_OFFSET => GCOV_INFO_CTRMASK_OFFSET + 8;
-
-use constant GCOV_FNINFO_IDENT_OFFSET => 0;
-use constant GCOV_FNINFO_CHECKSUM_OFFSET => GCOV_FNINFO_IDENT_OFFSET + 4;
-use constant GCOV_FNINFO_NCTRS_OFFSET => GCOV_FNINFO_CHECKSUM_OFFSET + 4;
+use constant GCOV_COUNTERS_492 => 9;
+use constant SIZEOF_PTR => 8;
+use constant SIZEOF_UINT64 => 8;
-use constant GCOV_CTRINFO_COUNT_OFFSET => 0;
-use constant GCOV_CTRINFO_VALUEPTR_OFFSET => GCOV_CTRINFO_COUNT_OFFSET + 8;
-
-use constant GCOV_GCDA_MAGIC_VALUE => 0x67636461;
use constant GCOV_FUNCTION_TAG => 0x01000000;
use constant GCOV_COUNTERS_TAG => 0x01a10000;
+use constant GCOV_PROGRAM_SUMMARY_TAG => 0xa3000000;
+
+use constant GCOV_GCDA_MAGIC_VALUE => 0x67636461;
+
+# See gcov.h for the structs (gcov_info, gcov_fn_info) from which
+# these offsets derive
+
+use constant GCOV_INFO_VERSION_OFFSET_492 => 0;
+use constant GCOV_INFO_NEXT_OFFSET_492 => 8;
+use constant GCOV_INFO_TIMESTAMP_OFFSET_492 => 16;
+use constant GCOV_INFO_FILENAME_OFFSET_492 => 24;
+use constant GCOV_INFO_MERGE_OFFSET_492 => 32;
+use constant GCOV_INFO_N_FUNCTIONS_OFFSET_492 => 32 + (9 * 8);
+use constant GCOV_INFO_FUNCTIONS_OFFSET_492 => GCOV_INFO_N_FUNCTIONS_OFFSET_492 + 8;
+
+use constant GCOV_FN_INFO_IDENT_OFFSET_492 => 8;
+use constant GCOV_FN_INFO_LINENO_CHECKSUM_OFFSET_492 => 12;
+use constant GCOV_FN_INFO_CFG_CHECKSUM_OFFSET_492 => 16;
+use constant GCOV_FN_INFO_CTR_INFO_OFFSET_492 => 24;
+
+use constant GCOV_CTR_INFO_NUM_OFFSET_492 => 0;
+use constant GCOV_CTR_INFO_VALUES_OFFSET_492 => 8;
# In memory format:
# GCC creates a 'gcov_info' structure for each .o file. The info
@@ -134,20 +147,43 @@ use constant GCOV_COUNTERS_TAG => 0x01a10000;
# uint64_ts, containing instrumented counts, for the preceeding function.
# Global of where we want the output to go.
-our $output_dir;
our $debug_mode;
+our $hbicore_extended_bin_file;
+our $hbicore_extended_bin_file_size;
BEGIN
{
$debug_mode = 0;
- $output_dir = "";
}
-return 1;
+
+sub init
+{
+ # TODO: We need to figure out how to handle reading data from
+ # HBB/HBRT for when those are instrumented. One hurdle is being
+ # able to determine from an address what module it belongs to,
+ # because HBB/HBI/HBRT are not necessarily laid out in memory as
+ # they are in PNOR or anywhere else.
+
+ my $hbicore_extended_bin_fname = "$ENV{SANDBOXROOT}/$ENV{SANDBOXNAME}/src/hbfw/img/hostboot_extended.bin";
+
+ userDebug("Opening " . $hbicore_extended_bin_fname . " for HBI\n");
+
+ unless (open($hbicore_extended_bin_file, "< $hbicore_extended_bin_fname")) {
+ ::userDisplay "Failed to open $hbicore_extended_bin_fname, exiting\n";
+ return 0;
+ }
+
+ binmode($hbicore_extended_bin_file);
+
+ $hbicore_extended_bin_file_size = -s $hbicore_extended_bin_fname;
+
+ return 1;
+}
sub main
{
- # Pick a new output directory based on the time.
- $output_dir = sprintf "gcov.output.%d/", time;
- File::Path::mkpath($output_dir);
+ if (!init()) {
+ return;
+ }
# Find all the hostboot modules.
my @modules = getModules();
@@ -160,7 +196,10 @@ sub main
my $pwd = `pwd`;
chomp $pwd;
- ::userDisplay "GCOV output written to: $pwd/$output_dir\n";
+
+ close $hbicore_extended_bin_file or die;
+
+ ::userDisplay("GCOV info extraction complete.\n");
}
sub parseModuleGcov
@@ -168,8 +207,23 @@ sub parseModuleGcov
my $module = shift;
::userDisplay "Extracting GCOV info for ".$module."\n";
+ # Search for magic symbol.
+ my ($gcov_magic, $unused) =
+ ::findSymbolAddress($module.GCOV_INFO_MAGIC_SYMBOLNAME);
+
+ if (!defined($gcov_magic))
+ {
+ $gcov_magic = 0;
+ }
+
+ if ($gcov_magic == 0 || read32($gcov_magic, 1) != GCOV_MAGIC_IDENTIFIER)
+ {
+ ::userDisplay "\tgcov_magic at address " . (sprintf "0x%x", $gcov_magic) . " is incorrect. Skipped.\n";
+ return;
+ }
+
# Search for gcov_info chain symbol.
- my ($gcov_info, $unused) =
+ my ($gcov_info, $unused2) =
::findSymbolAddress($module.GCOV_INFO_HEAD_SYMBOLNAME);
userDebug("\tFound info at 0x" . (sprintf "%x", $gcov_info) . "\n");
@@ -181,7 +235,7 @@ sub parseModuleGcov
if (($gcov_info eq NotFound) || ($gcov_info eq NotPresent))
{
- ::userDisplay "\tModule data is not present.\n";
+ ::userDisplay "\tModule data is not present, module might have been unloaded, skipping.\n";
return;
}
}
@@ -189,7 +243,7 @@ sub parseModuleGcov
# Check that we found the gcov_info chain.
if ($gcov_info == 0)
{
- ::userDisplay "\tUnable to find gcov_info chain. Skipped.\n";
+ ::userDisplay "\tUnable to find gcov_info chain, module might hvae been unloaded. Skipping.\n";
return;
}
@@ -202,39 +256,44 @@ sub parseGcovInfo
my $info_ptr = shift;
return if (0 eq $info_ptr);
- my $filename = readStr(read64($info_ptr + GCOV_INFO_FILENAME_OFFSET));
- userDebug("\tFile = ".$filename."\n");
+ userDebug("\tReading filename pointer from offset " . (sprintf "0x%x", ($info_ptr + GCOV_INFO_FILENAME_OFFSET_492)) . "\n");
- my $version = read32($info_ptr + GCOV_INFO_VERSION_OFFSET);
- my $stamp = read32($info_ptr + GCOV_INFO_TIMESTAMP_OFFSET);
+ my $filename_addr = read64($info_ptr + GCOV_INFO_FILENAME_OFFSET_492);
- my $func_count = read32($info_ptr + GCOV_INFO_NFUNCTIONS_OFFSET);
- userDebug("\tFunction Count = ".$func_count."\n");
+ userDebug("\tReading filename from offset " . (sprintf "0x%x", $filename_addr) . "\n");
- my $funcs = read64($info_ptr + GCOV_INFO_FUNCTIONS_OFFSET);
- userDebug("\tFunc Address = ".(sprintf "%x", $funcs)."\n");
+ my $filename = readStr($filename_addr);
- my $ctrmask = read32($info_ptr + GCOV_INFO_CTRMASK_OFFSET);
- if ($ctrmask % 2) # Check that COUNTER_ARCS is turned on.
- {
- # COUNTER_ARCS is on. Create file, find arc-values array,
- # parse functions.
+ if ($filename) {
+ ::userDisplay("\tFile = ".$filename."\n");
- my $fd = createGcovFile($filename, $version, $stamp);
+ my $version = read32($info_ptr + GCOV_INFO_VERSION_OFFSET_492);
+ my $stamp = read32($info_ptr + GCOV_INFO_TIMESTAMP_OFFSET_492);
- my $arcs_ptr = read64($info_ptr + GCOV_INFO_COUNTS_OFFSET +
- GCOV_CTRINFO_VALUEPTR_OFFSET);
- parseGcovFuncs($fd, $funcs, $func_count, $ctrmask, $arcs_ptr);
+ my $func_count = read32($info_ptr + GCOV_INFO_N_FUNCTIONS_OFFSET_492);
+ userDebug("\tFunction Count = ".$func_count."\n");
- close $fd;
- }
- else
- {
- userDebug("COUNTER_ARCS is missing!\n");
+ my $funcs = read64($info_ptr + GCOV_INFO_FUNCTIONS_OFFSET_492, 1);
+
+ if ($funcs ne NotFound && $funcs ne NotPresent) {
+ userDebug("\tFunc Address = ".(sprintf "0x%x", $funcs)."\n");
+
+ if ($version ne NotFound && $stamp ne NotFound && $func_count ne NotFound) {
+ my $fd = createGcovFile($filename, $version, $stamp);
+
+ parseGcovFuncs($fd, $funcs, $func_count);
+
+ close $fd or die $!;
+ }
+ } else {
+ userDebug("\tFunc Address is NULL, skipping\n");
+ }
+ } else {
+ userDebug("\tCannot read filename, skipping\n");
}
# Look for next .o in gcov_info chain, parse.
- my $next = read64($info_ptr + GCOV_INFO_NEXT_OFFSET);
+ my $next = read64($info_ptr + GCOV_INFO_NEXT_OFFSET_492);
parseGcovInfo($next);
}
@@ -243,62 +302,95 @@ sub parseGcovFuncs
my $fd = shift;
my $func_ptr = shift;
my $func_count = shift;
- my $mask = shift;
- my $val_ptr = shift;
- my $fn_offset = 0;
+ my $GCOV_COUNTERS_SUMMABLE_492 = 1;
- # Need to calculate the number of counters based on the bits on in
- # the 'mask'. This is used to determine the size of the function
- # descriptor object.
- my $counters = 0;
- {
- my $_mask = $mask;
+ print $fd pack('l', GCOV_PROGRAM_SUMMARY_TAG); # data.program.header.tag
- while (0 != $_mask)
- {
- $counters++;
- $_mask = ($_mask >> 1);
- }
- }
+ # for each GCOV_COUNTERS_SUMMABLE we have ten int32 (num, runs, and bitvector{8})
+ # plus three int64 (sum, max, sum_max) i.e. 10 + 3*2
+ # data.unit.header.length is the number of int32's we have following.
+ print $fd pack('l', 1 + $GCOV_COUNTERS_SUMMABLE_492 * (10 + 3 * 2)); # data.unit.header.length;
- userDebug("\tCounters = ".$counters."\n");
+ print $fd pack('l', 0); # data.summary:object.checksum (must be 0 according to docs)
- # Round up the counter count to the nearest two for alignment of the
- # function descriptor object.
- if ($counters % 2)
- {
- $counters++;
- }
- my $func_size = GCOV_FNINFO_CHECKSUM_OFFSET + 4 * $counters;
+ for (my $i = 0; $i < $GCOV_COUNTERS_SUMMABLE_492; $i++) {
+ print $fd pack('l', 0); # data.summary:object.count-summary.num
+ print $fd pack('l', 0); # data.summary:object.count-summary.runs
+ print $fd pack('l', 0); # data.summary:object.count-summary.sum@lo
+ print $fd pack('l', 0); # data.summary:object.count-summary.sum@hi
+ print $fd pack('l', 0); # data.summary:object.count-summary.max@lo
+ print $fd pack('l', 0); # data.summary:object.count-summary.max@hi
+ print $fd pack('l', 0); # data.summary:object.count-summary.sum_max@lo
+ print $fd pack('l', 0); # data.summary:object.count-summary.sum_max@hi
- userDebug("\tFunction size = ".$func_size."\n");
+ print $fd pack('l8', (0) x 8); # data.summary:object.count-summary.histogram.bitvector{8}
+ }
# Iterate through the functions and parse.
for(my $function = 0; $function < $func_count; $function++)
{
- my $func_off = ($func_ptr + $func_size * $function);
- my $ident = read32($func_off + GCOV_FNINFO_IDENT_OFFSET);
- my $chksum = read32($func_off + GCOV_FNINFO_CHECKSUM_OFFSET);
+ userDebug("\tFunction $function of $func_count\n");
+
+ my $fn_info_ptr = read64($func_ptr + SIZEOF_PTR*$function, 1);
+
+ if (($fn_info_ptr eq NotFound) || ($fn_info_ptr eq NotPresent))
+ {
+ userDebug("\tCannot read function info pointer, skipping\n");
+ next;
+ }
+
+ userDebug("\tfn_info_ptr = " . (sprintf "%x", $fn_info_ptr) . "\n");
+
+ my $ident = read32($fn_info_ptr + GCOV_FN_INFO_IDENT_OFFSET_492, 1);
+ my $lineno_chksum = read32($fn_info_ptr + GCOV_FN_INFO_LINENO_CHECKSUM_OFFSET_492, 1);
+ my $cfg_chksum = read32($fn_info_ptr + GCOV_FN_INFO_CFG_CHECKSUM_OFFSET_492, 1);
+ my $ctr_info_ptr = $fn_info_ptr + GCOV_FN_INFO_CTR_INFO_OFFSET_492;
+
+ if ($ident eq NotFound
+ || $lineno_chksum eq NotFound
+ || $cfg_chksum eq NotFound)
+ {
+ userDebug("Skipping because fn_info structure members are not readable\n");
+ next;
+ }
+
+ my $num_ctrs = read32($ctr_info_ptr + GCOV_CTR_INFO_NUM_OFFSET_492, 1);
+ my $ctrs_ptr = read64($ctr_info_ptr + GCOV_CTR_INFO_VALUES_OFFSET_492, 1);
+
+ if ($ctrs_ptr eq NotFound || $num_ctrs eq NotFound)
+ {
+ userDebug("Skipping because counters length isn't mapped\n");
+ next;
+ }
- userDebug("Ident = ".(sprintf "%x", $ident)."\n");
- userDebug("Chksum = ".(sprintf "%x", $chksum)."\n");
+ my $counters = readData($ctrs_ptr, SIZEOF_UINT64 * $num_ctrs);
+
+ userDebug("Ident = ".(sprintf "0x%x", $ident)."\n");
+ userDebug("lineno Chksum = ".(sprintf "0x%x", $lineno_chksum)."\n");
+ userDebug("cfg Chksum = ".(sprintf "0x%x", $cfg_chksum)."\n");
+ userDebug("Num counters = ".(sprintf "%d", $num_ctrs)."\n");
+ userDebug("ctrs_ptr = ".(sprintf "0x%x", $ctrs_ptr)."\n");
+
+ if (($counters eq NotFound) || ($counters eq NotPresent))
+ {
+ userDebug("Skipping because counter data not resident in memory\n");
+ next;
+ }
print $fd pack('l', GCOV_FUNCTION_TAG); # Write function tag.
- print $fd pack('l', 2); # Write size = 2.
+ print $fd pack('l', 3); # Write size = 3.
print $fd pack('l', $ident); # Write ident.
- print $fd pack('l', $chksum); # Write checksum.
-
- my $nctr_val = read32($func_off + GCOV_FNINFO_NCTRS_OFFSET);
- userDebug("N-Counters = ".$nctr_val."\n");
+ print $fd pack('l', $lineno_chksum); # Write checksum.
+ print $fd pack('l', $cfg_chksum); # Write checksum.
print $fd pack('l', GCOV_COUNTERS_TAG); # Write counter tag.
- print $fd pack('l', $nctr_val * 2); # Write counter length.
+ print $fd pack('l', $num_ctrs * 2); # Write counter length.
# Read each counter value, output.
# Read as one big block for performance reasons.
- my $counters = readData($val_ptr + 8*($fn_offset), 8 * $nctr_val);
- for(my $v_idx = 0; $v_idx < $nctr_val; $v_idx++)
+
+ for(my $v_idx = 0; $v_idx < $num_ctrs; $v_idx++)
{
my $val = substr $counters, 0, 8;
$counters = substr $counters, 8;
@@ -306,15 +398,34 @@ sub parseGcovFuncs
$val = unpack("Q", $val);
userDebug("\tValue[$v_idx] = ".$val."\n");
+ my $preex_read_low = read($fd, my $low_word, 4);
+ my $preex_read_high = read($fd, my $high_word, 4);
+
+ if (!defined($preex_read_low) or !(defined($preex_read_high))) {
+ die;
+ }
+ my $preex_read = $preex_read_low + $preex_read_high;
+
+ if ($preex_read == 8)
+ {
+ my $preex_val = (unpack("l", $high_word) << 32) | unpack("l", $low_word);
+
+ $val += $preex_val;
+ }
+
+ if ($preex_read > 0)
+ {
+ seek $fd, -$preex_read, 1;
+ }
+ else
+ {
+ seek $fd, 0, 2;
+ }
+
print $fd pack('l', $val & 0xFFFFFFFF); # Write lower word.
print $fd pack('l', $val >> 32) ; # Write upper word.
}
-
- # We used up a number of counters, so move the offset forward for
- # the next function.
- $fn_offset += $nctr_val;
}
-
}
# The *.gcda filename found in the gcov_info struct is an absolute path to
@@ -330,16 +441,25 @@ sub createGcovFile
my $version = shift;
my $stamp = shift;
- # Change *./../obj/ into obj/, prepend output_dir.
- $name =~ s/.*\/obj\//obj\//;
- $name = $output_dir.$name;
-
- # Make sure everything after 'obj/' exists (create subdirs).
- my $dir = File::Basename::dirname($name);
- File::Path::mkpath($dir);
+ # if the file exists then we update it, if not we create it
+ my $GCOVFILE;
+ if (-e $name)
+ {
+ if (!open($GCOVFILE, "+<$name"))
+ {
+ ::userDisplay("Failed to open $name for reading/writing gcov information\n");
+ die;
+ }
+ }
+ else
+ {
+ if (!open($GCOVFILE, "+>$name"))
+ {
+ ::userDisplay("Failed to open $name for writing gcov information\n");
+ die;
+ }
+ }
- # Create file.
- open(my $GCOVFILE, "> $name");
binmode($GCOVFILE);
# Write out header.
@@ -377,6 +497,22 @@ sub isVirtualAddress
return ($addr >= GCOV_EXTENDED_IMAGE_ADDRESS);
}
+sub readExtImage
+{
+ my $addr = shift;
+ my $amount = shift;
+
+ if ($addr + $amount >= $hbicore_extended_bin_file_size) {
+ return NotFound;
+ }
+
+ seek $hbicore_extended_bin_file, $addr, 0;
+
+ read $hbicore_extended_bin_file, my ($contents), $amount;
+
+ return $contents;
+}
+
# Utility to read a block of data from eithr memory or using the extended
# image file as a fallback if not present in memory.
use constant PAGESIZE => 4096;
@@ -401,8 +537,13 @@ sub readData
my $paddr = getPhysicalAddr($addr);
if ((NotFound eq $paddr) || (NotPresent eq $paddr))
{
- $paddr = $addr - GCOV_EXTENDED_IMAGE_ADDRESS;
- $result = $result.::readExtImage($paddr, $amount);
+ my $tmpdata = readExtImage($addr - GCOV_EXTENDED_IMAGE_ADDRESS, $amount);
+
+ if ($tmpdata eq NotFound) {
+ return NotFound;
+ }
+
+ $result = $result . $tmpdata;
}
else
{
@@ -423,14 +564,27 @@ sub readData
sub read64
{
my $addr = shift;
+ my $fallback = shift;
+
my $old_addr = $addr;
if (isVirtualAddress($addr))
{
$addr = getPhysicalAddr($addr);
if ((NotFound eq $addr) || (NotPresent eq $addr))
{
+ userDebug((sprintf "0x%x", $old_addr). " not translatable 2\n");
+
+ if (!$fallback) {
+ return NotFound;
+ }
+
$addr = $old_addr - GCOV_EXTENDED_IMAGE_ADDRESS;
- my $result = ::readExtImage($addr, 8);
+ my $result = readExtImage($addr, 8);
+
+ if ($result eq NotFound) {
+ return NotFound;
+ }
+
if (::littleendian()) { $result = reverse($result); }
return unpack("Q", $result);
}
@@ -444,14 +598,25 @@ sub read64
sub read32
{
my $addr = shift;
+ my $fallback = shift;
+
my $old_addr = $addr;
if (isVirtualAddress($addr))
{
$addr = getPhysicalAddr($addr);
if ((NotFound eq $addr) || (NotPresent eq $addr))
{
+ userDebug((sprintf "0x%x", $old_addr). "not translatable 3\n");
+
+ if (!$fallback) {
+ return NotFound;
+ }
+
$addr = $old_addr - GCOV_EXTENDED_IMAGE_ADDRESS;
- my $result = ::readExtImage($addr, 4);
+ my $result = readExtImage($addr, 4);
+ if ($result eq NotFound) {
+ return NotFound;
+ }
if (::littleendian()) { $result = reverse($result); }
return unpack("L", $result);
}
@@ -471,8 +636,10 @@ sub read8
$addr = getPhysicalAddr($addr);
if ((NotFound eq $addr) || (NotPresent eq $addr))
{
+ userDebug((sprintf "0x%x", $addr). "not translatable 4\n");
+
$addr = $old_addr - GCOV_EXTENDED_IMAGE_ADDRESS;
- my $result = ::readExtImage($addr, 1);
+ my $result = readExtImage($addr, 1);
return unpack("C", $result);
}
}
@@ -486,31 +653,82 @@ sub readStr
{
my $addr = shift;
my $old_addr = $addr;
+
if (isVirtualAddress($addr))
{
- $addr = $addr - GCOV_EXTENDED_IMAGE_ADDRESS;
+ userDebug("it is a virtual address, addr is " . (sprintf "%x", $addr) . "\n");
+ my $phys_addr = getPhysicalAddr($addr);
- # Virtual address, so need to read 1 byte at a time from the file.
- my $string = "";
- my $byte = 0;
-
- do
+ if ((NotFound eq $phys_addr) || (NotPresent eq $phys_addr))
{
- $byte = ::readExtImage($addr,1);
- $addr = $addr + 1;
+ userDebug("Translation not found, reading from pnor\n");
+ # Virtual address, so need to read 1 byte at a time from the file.
+ my $string = "";
+ my $byte = 0;
- if (unpack("C",$byte) eq 0)
+ do
{
- return $string;
- }
+ $byte = readExtImage($addr - GCOV_EXTENDED_IMAGE_ADDRESS, 1);
- $string = $string.$byte;
+ if ($byte eq NotFound)
+ {
+ return "";
+ }
- } while (1)
+ $addr = $addr + 1;
+
+ if (unpack("C",$byte) eq 0)
+ {
+ return $string;
+ }
+
+ $string = $string.$byte;
+ } while (1);
+ }
+ else
+ {
+ my $string = "";
+ my $byte = 0;
+
+ do
+ {
+ if (($addr & 0xfff) == 0)
+ {
+ # we have to recalculate the physical address
+ # whenever we cross a page boundary
+ $phys_addr = getPhysicalAddr($addr);
+
+ if ((NotFound eq $phys_addr) || (NotPresent eq $phys_addr))
+ {
+ userDebug((sprintf "0x%x", $addr). "not translatable 10\n");
+ return "";
+ }
+ }
+
+ $byte = read8($phys_addr);
+
+ if ($byte eq NotFound)
+ {
+ userDebug("Cannot read byte from physical address\n");
+ return "";
+ }
+
+ $addr += 1;
+ $phys_addr += 1;
+
+ if ($byte != 0)
+ {
+ $string = $string . pack("C", $byte);
+ }
+ } while ($byte != 0);
+
+ return $string;
+ }
}
else
{
- ::readStr($addr);
+ userDebug("it is NOT a virtual address\n");
+ return ::readStr($addr);
}
}
@@ -531,3 +749,5 @@ sub helpInfo
intro => [ "Extracts the GCOV information."],
);
}
+
+1; # Last expression in a perl module must be truthy.
diff --git a/src/build/debug/Hostboot/GcovModuleUnload.pm b/src/build/debug/Hostboot/GcovModuleUnload.pm
new file mode 100644
index 000000000..1a411cc3c
--- /dev/null
+++ b/src/build/debug/Hostboot/GcovModuleUnload.pm
@@ -0,0 +1,69 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/debug/Hostboot/GcovModuleUnload.pm $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2019
+# [+] 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
+#!/usr/bin/perl
+use strict;
+use File::Path;
+use File::Basename;
+
+package Hostboot::GcovModuleUnload;
+use Hostboot::Gcov qw(parseGcovInfo init);
+
+use Exporter;
+our @EXPORT_OK = ('main', 'parseGcovInfo');
+
+sub main
+{
+ my ($packName, $args) = @_;
+
+ my $gcov_info_address = $args->{"address"};
+
+ ::userDisplay("Dumping gcov module info from " . (sprintf "0x%x", $gcov_info_address) . "\n");
+
+ if ($gcov_info_address <= 0) {
+ ::userDisplay("Can't dump from NULL\n");
+ return -1;
+ }
+
+ if (!Hostboot::Gcov::init()) {
+ return -2;
+ }
+
+ Hostboot::Gcov::parseGcovInfo($gcov_info_address);
+
+ ::userDisplay("Done.\n");
+
+ return 0;
+}
+
+# Debug tool help info.
+sub helpInfo
+{
+ my %info = (
+ name => "GcovModuleUnload",
+ intro => [ "Extracts the GCOV information from modules as they are being unloaded."],
+ );
+}
+
+1; # Last expression in a perl module must be truthy.
diff --git a/src/build/debug/Hostboot/PrintVMM.pm b/src/build/debug/Hostboot/PrintVMM.pm
index 476262d93..57a57a9e2 100644
--- a/src/build/debug/Hostboot/PrintVMM.pm
+++ b/src/build/debug/Hostboot/PrintVMM.pm
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2018
+# Contributors Listed Below - COPYRIGHT 2012,2020
# [+] International Business Machines Corp.
#
#
@@ -73,7 +73,7 @@ sub main
my @segment_manager_addr = ::findPointer("SGMNTMGR",
"Singleton<SegmentManager>::instance()::instance");
- if (not defined @segment_manager_addr)
+ if (not @segment_manager_addr)
{
::userDisplay " VirtualToPhy: Cannot find Device Segment symbol.\n"; die;
}
diff --git a/src/build/debug/Hostboot/_DebugFrameworkVMM.pm b/src/build/debug/Hostboot/_DebugFrameworkVMM.pm
index 128df4ec7..ca323bd32 100755
--- a/src/build/debug/Hostboot/_DebugFrameworkVMM.pm
+++ b/src/build/debug/Hostboot/_DebugFrameworkVMM.pm
@@ -6,7 +6,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2018
+# Contributors Listed Below - COPYRIGHT 2012,2020
# [+] International Business Machines Corp.
#
#
@@ -404,7 +404,7 @@ sub getPhysicalAddr
"Singleton<SegmentManager>::instance()::instance");
- if (not defined @segment_manager_addr)
+ if (not @segment_manager_addr)
{
::userDisplay " VirtualToPhy: Cannot find SegmentManager symbol.\n";
return NotFound;
diff --git a/src/build/debug/eSEL.pl b/src/build/debug/eSEL.pl
index ddce72f50..ed9ef2335 100755
--- a/src/build/debug/eSEL.pl
+++ b/src/build/debug/eSEL.pl
@@ -6,7 +6,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2017,2018
+# Contributors Listed Below - COPYRIGHT 2017,2019
# [+] International Business Machines Corp.
#
#
@@ -588,6 +588,11 @@ sub DecodeObmcEselData
$timestamp_found = 1;
last;
}
+ elsif($next_line =~ /timestamp/)
+ {
+ $timestamp_found = 2;
+ last;
+ }
elsif($next_line =~ /ESEL/ or
$next_line =~ /20 00 04/) # found the next ESEL
{
@@ -601,16 +606,35 @@ sub DecodeObmcEselData
if($timestamp_found)
{
- # strip the "Timestamp", commas, spaces, and the newline
- $next_line =~ s/"Timestamp"://g;
- $next_line =~ s/,//g;
- $next_line =~ s/ //g;
- chomp $next_line;
-
- # convert to date/time (we are given the timestamp in ms, so divide
- # by 1000 to get s).
- $timestamp =
+ if($timestamp_found == 1)
+ {
+ # strip the "Timestamp", commas, spaces, and the newline
+ $next_line =~ s/"Timestamp"://g;
+ $next_line =~ s/,//g;
+ $next_line =~ s/ //g;
+ chomp $next_line;
+
+ # convert to date/time (we are given the timestamp in ms, so divide
+ # by 1000 to get s).
+ $timestamp =
strftime("%m/%d/%Y %H:%M:%S", localtime($next_line/1000));
+ }
+ elsif($timestamp_found == 2)
+ {
+ # Field format :: "timestamp": "2019-10-31 10:20:50"
+ $next_line =~ s/"timestamp"://g;
+ $next_line =~ s/"//g; #drop the quotes
+ my @tmp1 = split( " ", $next_line ); #break the date and time apart
+ my @df = split( /-/, $tmp1[0] ); #break up the date fields
+ # Convert to :: 11/05/2019 12:25:41
+ $timestamp = "$df[1]/$df[2]/$df[0] $tmp1[1]";
+ ($debug) && print "timestamp> $timestamp \n";
+ }
+ else
+ {
+ die "Bad timestamp\n";
+ }
+
($debug) && print "Timestamp for ESEL #$esel_record_count:$next_line\n";
($debug) && print "Decoded timestamp for ESEL #$esel_record_count:$timestamp\n";
diff --git a/src/build/debug/ffdcExpander b/src/build/debug/ffdcExpander
new file mode 100755
index 000000000..95f7c970f
--- /dev/null
+++ b/src/build/debug/ffdcExpander
@@ -0,0 +1,727 @@
+#!/bin/sh
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/debug/ffdcExpander $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2013,2020
+# [+] 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
+
+
+###############################################################################
+# @file ffdcExpander
+# This shell script takes a SYSDUMP file and extracts various debug elements.
+# The caller has the option to post artifacts to a defect.
+#
+# The starting point for this script is at the end of the file.
+###############################################################################
+
+###############################################################################
+# Some helpful constants
+###############################################################################
+FFDC_GUNZIP_TOOL="/bin/gunzip"
+FFDC_DUMP_PARSER="/esw/bin/dumpparser"
+
+
+###############################################################################
+# Some global variables
+###############################################################################
+FFDC_3RD_PARTY_SCRIPT_DIR="/gsa/ausgsa/projects/h/hostboot/optools/" # Location of files updatecq.pl, cqcmd.pl and Slurp.pm
+FFDC_SCRIPT_NAME=$(basename "${0}") # Cache the name of this script
+FFDC_SCRIPT_DIR=$(dirname "${0}") # Location of this script and supporting scripts
+FFDC_SCRIPT_DIR="${FFDC_SCRIPT_DIR}/"
+FFDC_SYSDUMP_FILE_GZ="" # format SYSDUMP.13020B8.20000001.20190725181300.gz
+FFDC_SYSDUMP_FILE="" # format SYSDUMP.13020B8.20000001.20190725181300
+FFDC_HB_DUMP_FILE=""; # format hb.dump.SYSDUMP.13020B8.20000001.20190725181300
+FFDC_FSP_DRIVER_DIR="" # format '/esw/fips922/Builds/b0724a_1931.922'
+FFDC_FSP_DRIVER="" # format 'fips922', 'fips950' , etc
+FFDC_FSP_BUILD_TAG="" # format b0724a_1931.922
+FFDC_DEFECT_NUM="" # format 'SW123456', 'sw123456', 'Sw123456' or 'sW123456'
+FFDC_DEFECT_NUM_CHARS="8" # The number of characters expected in defect including 'SW'
+FFDC_CWD="`pwd -P`/" # The current working directory
+FFDC_DEST_DIR="${FFDC_CWD}" # The destination directory of artifacts, default to CWD
+FFDC_CQ_USER="" # The CQ user ID
+FFDC_CQ_PASS="" # The CQ password
+FFDC_RETURN_VALUE="0" # The return value. Default to success '0'
+FFDC_TIME_STAMP="" # A time stamp is generated to make the files unique
+
+###############################################################################
+# Print the usage line
+#
+# @return 0 if successful, not 0 if a failure occurred
+###############################################################################
+function _ffdcUsage_()
+{
+ echo ""
+ echo " Usage: ${FFDC_SCRIPT_NAME} -g <FFDC_SYSDUMP_FILE.gz> | -s <FFDC_SYSDUMP_FILE> |"
+ echo " -h <HB_FFDC_SYSDUMP_FILE> -b <FSP_BUILD_TAG>"
+ echo " [ OPTIONS ]"
+ echo ""
+ echo " OPTIONS: [ -d <DEST_DIR> ] [ -a <DEFECT_NUM> ] [ -t ]"
+ echo " -t attach a time stamp to the artifacts"
+ echo ""
+ echo " Examples: ${FFDC_SCRIPT_NAME} -g SYSDUMP.13020B8.20000001.20190725181300.raw67117184.gz"
+ echo " ${FFDC_SCRIPT_NAME} -s SYSDUMP.13020B8.20000001.20190725181300.raw67117184"
+ echo " ${FFDC_SCRIPT_NAME} -h hb.dump.SYSDUMP.13020B8.20000001.20190725181300 -b b0724a_1931.922"
+ echo " ${FFDC_SCRIPT_NAME} -s SYSDUMP.13020B8.20000001.20190725181300.raw67117184 -a SW123456 -t"
+ echo " ${FFDC_SCRIPT_NAME} -s SYSDUMP.13020B8.20000001.20190725181300.raw67117184 -d dir"
+ echo ""
+ return 0; # Return success
+}
+
+###############################################################################
+# @brief Get the caller's options and validate them
+#
+# @param [in] $* - All of the caller's inputs after name of script
+#
+# @return 0 if successful, not 0 if a failure occurred
+###############################################################################
+function _getUserInputOptionsAndValidate_()
+{
+ # Default caller options
+ CALLER_SYSDUMP_FILE_GZ=""
+ CALLER_SYSDUMP_FILE=""
+ CALLER_HB_DUMP_FILE=""
+ CALLER_FSP_BUILD_TAG=""
+ CALLER_DEST_DIR=""
+ CALLER_REQUESTS_TIME_STAMP=""
+
+ # Get caller's options
+ FFDC_RETURN_VALUE="22" # Default to 'Invalid argument'
+ MANDATORY_OPTION_CHOSEN="0"
+ echo ""
+ while getopts ts:g:h:b:d:a: option
+ do
+ if [ -n "${option}" ]; then
+ FFDC_RETURN_VALUE="0"; # Found an argument
+ fi
+ case "${option}"
+ in
+ t) CALLER_REQUESTS_TIME_STAMP=1;;
+ s) CALLER_SYSDUMP_FILE=${OPTARG}; MANDATORY_OPTION_CHOSEN="1";;
+ g) CALLER_SYSDUMP_FILE_GZ=${OPTARG}; MANDATORY_OPTION_CHOSEN="1";;
+ h) CALLER_HB_DUMP_FILE=${OPTARG}; MANDATORY_OPTION_CHOSEN="1";;
+ b) CALLER_FSP_BUILD_TAG=${OPTARG};;
+ d) CALLER_DEST_DIR=${OPTARG};;
+ a) CALLER_DEFECT_NUM=${OPTARG};;
+ \?) FFDC_RETURN_VALUE=22;;
+ :) FFDC_RETURN_VALUE=22;;
+ esac
+ done
+
+ # If call to getopts not successful, then propagate error back
+ if [ "$FFDC_RETURN_VALUE" != "0" ]; then
+ _ffdcUsage_
+ return $FFDC_RETURN_VALUE;
+ fi
+
+ # Check for a valid option chosen
+ if [ "$MANDATORY_OPTION_CHOSEN" == "0" ]; then
+ _ffdcUsage_
+ return $FFDC_RETURN_VALUE;
+ fi
+
+ # Check for nonsensical options
+ if [ -n "${CALLER_SYSDUMP_FILE}" ] && [ -n "${CALLER_SYSDUMP_FILE_GZ}" ]; then
+ echo " ERROR: Incompatible options: options -g and -s can't be used together";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi
+
+ if [ -n "${CALLER_SYSDUMP_FILE_GZ}" ] && [ -n "${CALLER_HB_DUMP_FILE}" ]; then
+ echo " ERROR: Incompatible options: options -g and -h can't be used together";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi
+
+ if [ -n "${CALLER_SYSDUMP_FILE_GZ}" ] && [ -n "${CALLER_FSP_BUILD_TAG}" ]; then
+ echo " ERROR: Incompatible options: options -g and -b can't be used together";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi
+
+ if [ -n "${CALLER_SYSDUMP_FILE}" ] && [ -n "${CALLER_FSP_BUILD_TAG}" ]; then
+ echo " ERROR: Incompatible options: options -s and -b can't be used together";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi
+
+ if [ -n "${CALLER_SYSDUMP_FILE}" ] && [ -n "${CALLER_HB_DUMP_FILE}" ]; then
+ echo " ERROR: Incompatible options: options -s and -h can't be used together";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi
+
+ # Verify that if caller is passing in a HB dump file, they must supply the build tag
+ if [ -n "${CALLER_HB_DUMP_FILE}" ] && [ -z "${CALLER_FSP_BUILD_TAG}" ]; then
+ echo " ERROR: Must supply a -b option with the -h option";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi
+
+ if [ -z "${CALLER_HB_DUMP_FILE}" ] && [ -n "${CALLER_FSP_BUILD_TAG}" ]; then
+ echo " ERROR: Must supply a -h option with the -b option";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi
+
+ # If caller requests a time stamp, option -t, then oblige
+ if [ "$CALLER_REQUESTS_TIME_STAMP" == "1" ]; then
+ FFDC_TIME_STAMP=$(date +%s)
+ FFDC_TIME_STAMP="_${FFDC_TIME_STAMP}"
+ fi
+
+ # If caller supplied a gzippped SYSDUMP file, option -g, then confirm it exists
+ if [ -n "${CALLER_SYSDUMP_FILE_GZ}" ]; then
+ if [ ! -e "${CALLER_SYSDUMP_FILE_GZ}" ]; then
+ echo " gzipped SYSDUMP file (${CALLER_SYSDUMP_FILE_GZ}) not found";
+ return 22; # return 'Invalid argument'
+ fi
+
+ # Check if file given is a gzipped file, verify that it ends in .gz
+ if [[ "${CALLER_SYSDUMP_FILE_GZ}" != *\.gz ]]; then
+ echo " ";
+ echo " WARNING: It appears that file (${CALLER_SYSDUMP_FILE_GZ}) is not a gzipped file"
+ while true; do
+ echo ""
+ read -p " Do you wish to continue with file [Y/N] ? " yn
+ case $yn in
+ [Yy] ) break;;
+ [Nn] ) echo " ¯\_(?)_/¯ exiting ..."; echo ""; return 22;; # return 'Invalid argument'
+ * ) echo " Please answer [Y]es or [N]o.";;
+ esac
+ done
+ fi
+
+ # Save caller's gzippped SYSDUMP file, option -g
+ FFDC_SYSDUMP_FILE_GZ="$CALLER_SYSDUMP_FILE_GZ"
+
+ ## Add an absolute path to the gzipped file, if not already an absolute path
+ # Check the first character to see if starting with absolute path
+ FIRST_CHAR="${FFDC_SYSDUMP_FILE_GZ:0:1}"
+ # If first char not a '/' then append an absolute path
+ if [ "${FIRST_CHAR}" != "/" ]; then
+ FFDC_SYSDUMP_FILE_GZ="${FFDC_CWD}${FFDC_SYSDUMP_FILE_GZ}"
+ fi
+ fi # end if [ -n "${CALLER_SYSDUMP_FILE_GZ}" ]; then
+
+
+ # If caller supplied a SYSDUMP file, option -f, then confirm it exists
+ if [ -n "${CALLER_SYSDUMP_FILE}" ]; then
+ if [ ! -e "${CALLER_SYSDUMP_FILE}" ]; then
+ echo " SYSDUMP file (${CALLER_SYSDUMP_FILE}) not found";
+ return 22; # return 'Invalid argument'
+ fi
+
+ # Save caller's SYSDUMP file, option -f
+ FFDC_SYSDUMP_FILE="${CALLER_SYSDUMP_FILE}"
+
+ ## Add an absolute path to the gzipped file, if not already an absolute path
+ # Check the first character to see if starting with absolute path
+ FIRST_CHAR="${FFDC_SYSDUMP_FILE:0:1}"
+ # If first char not a '/' then append an absolute path
+ if [ "${FIRST_CHAR}" != "/" ]; then
+ FFDC_SYSDUMP_FILE="${FFDC_CWD}${FFDC_SYSDUMP_FILE}"
+ fi
+ fi # end if [ -n "${CALLER_SYSDUMP_FILE}" ]; then
+
+
+ # If caller supplied a HB dump file, option -h, then confirm it exists
+ if [ -n "${CALLER_HB_DUMP_FILE}" ]; then
+ if [ ! -e "${CALLER_HB_DUMP_FILE}" ]; then
+ echo " HB dump file (${CALLER_HB_DUMP_FILE}) not found";
+ return 22; # return 'Invalid argument'
+ fi
+
+ # Save caller's HB dump file, option -h
+ FFDC_HB_DUMP_FILE="${CALLER_HB_DUMP_FILE}"
+
+ ## Add an absolute path to the HB dump file, if not already an absolute path
+ # Check the first character to see if starting with absolute path
+ FIRST_CHAR="${FFDC_HB_DUMP_FILE:0:1}"
+ # If first char not a '/' then append an absolute path
+ if [ "${FIRST_CHAR}" != "/" ]; then
+ FFDC_HB_DUMP_FILE="${FFDC_CWD}${FFDC_HB_DUMP_FILE}"
+ fi
+ fi # end if [ -n "${CALLER_HB_DUMP_FILE}" ]; then
+
+
+ # If caller supplied an FSP build tag, option -b, then validate it
+ if [ -n "${CALLER_FSP_BUILD_TAG}" ]; then
+ # Extrapolate the FSP Build Release from the FSP build tag
+ if [[ "${CALLER_FSP_BUILD_TAG}" = *"."* ]]; then
+ FIPS_VERS=$(echo ${CALLER_FSP_BUILD_TAG} | \cut -d"." -f 2)
+ if [ -n "${FIPS_VERS}" ]; then
+ FFDC_FSP_DRIVER="fips${FIPS_VERS}"
+ else
+ echo " ";
+ echo " Build tag (${CALLER_FSP_BUILD_TAG}) appears to be in wrong format";
+ echo " Cannot extrapolate the FIPS version from build tag";
+ return 22; # return 'Invalid argument'
+ fi
+ else
+ echo " ";
+ echo " Build tag (${CALLER_FSP_BUILD_TAG}) appears to be in wrong format";
+ echo " Cannot extrapolate the FIPS version from build tag";
+ _ffdcUsage_
+ return 22; # return 'Invalid argument'
+ fi # end if [[ "${CALLER_FSP_BUILD_TAG}" = *"."* ]]; then
+
+ # Save the caller's FSP build tag
+ FFDC_FSP_BUILD_TAG="${CALLER_FSP_BUILD_TAG}"
+
+ # Save the caller's FSP build tag with the directory to it
+ FFDC_FSP_DRIVER_DIR="/esw/${FFDC_FSP_DRIVER}/Builds/${CALLER_FSP_BUILD_TAG}"
+ fi # end if [ -n "${CALLER_FSP_BUILD_TAG}" ]; then
+
+ # If caller supplied a defect, option -a, just confirm it is in the correct
+ # nomenclature and format
+ if [ -n "${CALLER_DEFECT_NUM}" ]; then
+
+ FFDC_DEFECT_NUM=$(echo ${CALLER_DEFECT_NUM^^})
+ if [[ $FFDC_DEFECT_NUM != SW* ]]; then
+ echo " ERROR: software defect must be preceded with 'SW'";
+ echo " ";
+ return 22; # return 'Invalid argument'
+ fi
+
+ NUM_CHARS=${#FFDC_DEFECT_NUM}
+ if [[ "${NUM_CHARS}" -ne "${FFDC_DEFECT_NUM_CHARS}" ]]; then
+ echo " ERROR: software defect must have a total of ${FFDC_DEFECT_NUM_CHARS} characters, including 'SW'";
+ echo " ";
+ return 22; # return 'Invalid argument'
+ fi
+
+ INTEGER_PART=$(echo ${CALLER_DEFECT_NUM} | sed "s/^SW//g")
+ REG_EXP='^[0-9]+$'
+ if ! [[ $INTEGER_PART =~ $REG_EXP ]]; then
+ echo " ERROR: the characters (${INTEGER_PART}) that follow 'SW' must be an integer";
+ echo " ";
+ return 22; # return 'Invalid argument'
+ fi
+
+ # Prompt username and password for CQ
+ _queryUserPassword_;
+ FFDC_RETURN_VALUE=$?
+ if [ "${FFDC_RETURN_VALUE}" != "0" ]; then
+ echo ""
+ return ${FFDC_RETURN_VALUE}; # Return failure
+ fi
+ fi # end # If caller supplied a defect, option -a, ...
+
+
+ # If caller supplied a destination directory, option -d, then confirm it
+ # exists and determine if it is a relative path or absolute path
+ if [ -n "${CALLER_DEST_DIR}" ]; then
+ if [ ! -e "${CALLER_DEST_DIR}" ]; then
+ echo " Destination directory (${CALLER_DEST_DIR}) not found";
+ while true; do
+ echo ""
+ read -p " Do you wish to ceate it [Y/N] ? " yn
+ case $yn in
+ [Yy] ) break;;
+ [Nn] ) echo " ¯\_(?)_/¯ exiting ..."; echo ""; return 22;; # return 'Invalid argument'
+ * ) echo " Please answer [Y]es or [N]o.";;
+ esac
+ done
+
+ mkdir -p ${CALLER_DEST_DIR}
+ FFDC_RETURN_VALUE=$?
+ if [ "$FFDC_RETURN_VALUE" != "0" ]; then
+ echo ""
+ return $FFDC_RETURN_VALUE; # Propagate failure
+ fi
+ echo " Destination directory (${CALLER_DEST_DIR}) created";
+ echo ""
+ fi
+
+ # Save caller's destination directory option
+ FFDC_DEST_DIR="$CALLER_DEST_DIR"
+ NUM_CHARS=$((${#FFDC_DEST_DIR}-1))
+ LAST_CHAR="${FFDC_DEST_DIR:$NUM_CHARS:1}"
+ # If last char not a '/' then append a '/'
+ if [ "${LAST_CHAR}" != "/" ]; then
+ FFDC_DEST_DIR="${FFDC_DEST_DIR}/"
+ fi
+
+ ## Add an absolute path to the destination directory, if it is not
+ ## already an absolute path.
+ # Inspect the first character to determine path is absolute or not
+ FIRST_CHAR="${FFDC_DEST_DIR:0:1}"
+ # If first char not a '/' then append an absolute path
+ if [ "${FIRST_CHAR}" != "/" ]; then
+ FFDC_DEST_DIR="${FFDC_CWD}${FFDC_DEST_DIR}"
+ fi
+ fi # end if [ -n "${CALLER_DEST_DIR}" ]; then
+
+ return 0; # Return success
+}
+
+###############################################################################
+# @brief Query caller for user name and password
+###############################################################################
+function _queryUserPassword_()
+{
+ if [ -n "${FFDC_DEFECT_NUM}" ]; then
+ read -p 'CQ Username: ' FFDC_CQ_USER
+ read -sp 'CQ Password: ' FFDC_CQ_PASS
+ fi
+
+ return 0;
+}
+
+###############################################################################
+# @brief Unzip the system dump file
+#
+# Example: unzip SYSDUMP.13020B8.20000001.20190725181300.raw67117184.gz =>
+# SYSDUMP.13020B8.20000001.20190725181300.raw67117184
+#
+# @return 0 if successful, not 0 if a failure occurred
+###############################################################################
+function _unzipSysDumpFile_()
+{
+ # Verify that we can get to the dumpparser script
+ if [[ ! -e "${FFDC_GUNZIP_TOOL}" ]]; then
+ echo ""
+ echo " ERROR: Could not find gunzip tool ${FFDC_GUNZIP_TOOL}"
+ echo ""
+ return 2; # Return 'No such file or directory'
+ fi
+
+ ## Extrapolate the SYSDUMP file from the gzipped file
+ # Remove any directories and only get the file name
+ FFDC_SYSDUMP_FILE=$(echo ${FFDC_SYSDUMP_FILE_GZ} | awk -F / '{ print $NF }')
+ # Remove the '.gz' from the gzipped file
+ FFDC_SYSDUMP_FILE=$(echo ${FFDC_SYSDUMP_FILE} | sed "s/\.gz$//")
+ # Prepend the caller's directory
+ FFDC_SYSDUMP_FILE="${FFDC_DEST_DIR}${FFDC_SYSDUMP_FILE}"
+
+ # Check if the SYSDUMP file already exists, if so, ask caller if they wish
+ # to overwrite it
+ if [[ -e "${FFDC_SYSDUMP_FILE}" ]]; then
+ echo ""
+ echo " SYSDUMP file (${FFDC_SYSDUMP_FILE}) already exists ..."
+ while true; do
+ echo ""
+ read -p " Do you wish to override the file and continue [Y/N] ? " yn
+ case $yn in
+ [Yy] ) break;;
+ [Nn] ) echo " Skipping call to ${FFDC_GUNZIP_TOOL} ..."; echo ""; return 0;;
+ * ) echo " Please answer [Y]es or [N]o.";;
+ esac
+ done
+ fi
+
+ # Unzip the gzipped SYSDUMP file
+ echo ""
+ echo " ${FFDC_GUNZIP_TOOL} -c ${FFDC_SYSDUMP_FILE_GZ} > ${FFDC_SYSDUMP_FILE}"
+ `${FFDC_GUNZIP_TOOL} -c ${FFDC_SYSDUMP_FILE_GZ} > ${FFDC_SYSDUMP_FILE}`
+ FFDC_RETURN_VALUE=$?
+ if [ "${FFDC_RETURN_VALUE}" != "0" ]; then
+ echo ""
+ return ${FFDC_RETURN_VALUE}; # Return failure
+ fi
+
+ return 0; # Return success
+}
+
+
+###############################################################################
+# @brief Extract the HB system dump file from the SYSDUMP file
+#
+# Example: /esw/bin/dumpparser -extMem SYSDUMP.13020B8.20000001.20190725181300.raw67117184 =>
+# hb.dump.SYSDUMP.13020B8.20000001.20190725181300
+#
+# @return 0 if successful, not 0 if a failure occurred
+###############################################################################
+function _extractHbSysDumpFile_()
+{
+ # Verify that we can get to the dump parser script
+ if [[ ! -e "${FFDC_DUMP_PARSER}" ]]; then
+ echo ""
+ echo " ERROR: Could not find parser ${FFDC_DUMP_PARSER}"
+ echo ""
+ return 2; # Return 'No such file or directory'
+ fi
+
+ ## Extrapolate the HB dump file name from the SYSDUMP file
+ # Remove any directories and only get the file name
+ FFDC_HB_DUMP_FILE=$(echo ${FFDC_SYSDUMP_FILE} | awk -F / '{ print $NF }')
+ # Remove the .gz from the SYSDUMP, if it exists
+ FFDC_HB_DUMP_FILE=$(echo ${FFDC_HB_DUMP_FILE} | sed "s/\.gz$//")
+ # Remove the postpended '.rawxxx' from the SYSDUMP file, if it exists
+ FFDC_HB_DUMP_FILE=$(echo ${FFDC_HB_DUMP_FILE} | sed "s/\.raw.*$//")
+ # Prepend 'hb.dump.' to file
+ FFDC_HB_DUMP_FILE=$(echo ${FFDC_HB_DUMP_FILE} | sed "s/^/hb.dump./")
+ # Prepend the caller's directory
+ FFDC_HB_DUMP_FILE="${FFDC_DEST_DIR}${FFDC_HB_DUMP_FILE}"
+
+ # Extract the the FSP build info from the SYSDUMP file
+ FSP_BUILD_INFO=$(${FFDC_DUMP_PARSER} -a ${FFDC_SYSDUMP_FILE} | grep "Driver is" | awk '{ print $4 }')
+
+ # Extract the the FSP driver info from the FSP build info
+ FFDC_FSP_DRIVER=$(echo ${FSP_BUILD_INFO} | awk -F / '{ print $1 }')
+
+ # Extract the FSP build tag info from the FSP build info
+ FFDC_FSP_BUILD_TAG=$(echo ${FSP_BUILD_INFO} | awk -F / '{ print $2 }')
+
+ # Create a path to FSP build driver info
+ FFDC_FSP_DRIVER_DIR="/esw/${FFDC_FSP_DRIVER}/Builds/${FFDC_FSP_BUILD_TAG}"
+
+ # Check if the HB dump file already exists, if so, ask caller if they wish
+ # to overwrite it
+ if [[ -e "${FFDC_HB_DUMP_FILE}" ]]; then
+ echo ""
+ echo " HB system dump file (${FFDC_HB_DUMP_FILE}) already exists ..."
+ while true; do
+ echo ""
+ read -p " Do you wish to override the file and continue [Y/N] ? " yn
+ case $yn in
+ [Yy] ) break;;
+ [Nn] ) echo " Skipping call to ${FFDC_DUMP_PARSER} ..."; return 0;;
+ * ) echo " Please answer [Y]es or [N]o.";;
+ esac
+ done
+ fi
+
+ # Change directory to user supplied directory
+ \cd -P ${FFDC_DEST_DIR} ;
+
+ # Parse out the HB dump file using the dump parser
+ echo ""
+ echo " ${FFDC_DUMP_PARSER} -extMem ${FFDC_SYSDUMP_FILE}"
+ ${FFDC_DUMP_PARSER} -extMem ${FFDC_SYSDUMP_FILE}
+
+ FFDC_RETURN_VALUE=$?
+ if [ "${FFDC_RETURN_VALUE}" != "0" ]; then
+ # Return back to current working directory
+ \cd -P ${FFDC_CWD}
+ echo ""
+ return ${FFDC_RETURN_VALUE}; # Return failure
+ fi
+
+ echo " Created file ${FFDC_HB_DUMP_FILE}"
+
+ # Return back to current working directory
+ \cd -P ${FFDC_CWD}
+
+ return 0; # Return success
+}
+
+
+###############################################################################
+# @brief Set the path to the fsp-trace tool
+#
+# @return 0
+###############################################################################
+function _setFSPTracePath_()
+{
+ FFDC_FSP_PATH="/esw/$FFDC_FSP_DRIVER/Builds/built/images/nfs/x86.nfp/bin/"
+ echo ""
+ echo " Using fsp-trace tool: ${FFDC_FSP_PATH}fsp-trace"
+ PATH=${FFDC_FSP_PATH}:$PATH
+
+ # Verify that we can get to the dump parser script
+ if [[ ! -e "${FFDC_FSP_PATH}fsp-trace" ]]; then
+ echo ""
+ echo " ERROR: Could not find fsp trace ${FFDC_DUMP_PARSER}"
+ echo ""
+ return 2; # Return 'No such file or directory'
+ fi
+
+ echo "PATH=${FFDC_FSP_PATH}:\$PATH" >> ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+
+ return 0; # Return success
+}
+
+###############################################################################
+# @brief Extract various HB dump info
+#
+# @param [in] $1 The HB tools directory
+# @param [in] $2 Path to the hb-dump-debug tools directory
+###############################################################################
+function _getInfoFromHBDump_()
+{
+ echo ""
+ echo " Extracting the Trace information from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=Trace --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}TRACE${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=Trace --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}TRACE${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the Printk information from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=Printk --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PRINTK${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=Printk --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PRINTK${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the Errl information (Component/PLID list) from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=Errl --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}ERRL${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=Errl --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}ERRL${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the Errl information (Detailed listing of all Error Logs) from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=Errl --tool-options='display=all' --file=${FFDC_HB_DUMP_FILE} >> ${FFDC_DEST_DIR}ERRL${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=Errl --tool-options='display=all' --file=${FFDC_HB_DUMP_FILE} >> ${FFDC_DEST_DIR}ERRL${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the Ps information from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=Ps --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PS${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=Ps --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PS${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the Ps information from HB dump with backtrace ..."
+ echo " running: $1 --img-path=$2/ --tool=Ps --tool-options="with-backtrace" --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PS_BACKTRACE${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=Ps --tool-options="with-backtrace" --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PS_BACKTRACE${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the MemStats information from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=Ps --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}MEMSTATS${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=MemStats --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}MEMSTATS${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the PageMgr information from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=PageMgr --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PAGEMGR${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=PageMgr --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}PAGEMGR${FFDC_TIME_STAMP}
+
+ echo ""
+ echo " Extracting the BlTrace information from HB dump ..."
+ echo " running: $1 --img-path=$2/ --tool=BlTrace --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}BLTRACE${FFDC_TIME_STAMP}" | tee -a ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ $1 --img-path=$2/ --tool=BlTrace --file=${FFDC_HB_DUMP_FILE} > ${FFDC_DEST_DIR}BLTRACE${FFDC_TIME_STAMP}
+}
+
+###############################################################################
+# @brief Extract various HB dump info and post to defect, if caller wishes to
+###############################################################################
+function _getInfoFromHBDumpAndPost_()
+{
+ _setFSPTracePath_
+ FFDC_RETURN_VALUE=$?
+ # If call to _setFSPTracePath_ not successful, then propagate error back
+ if [ "$FFDC_RETURN_VALUE" != "0" ]; then
+ return $FFDC_RETURN_VALUE;
+ fi
+
+ HB_TOOLS_DIR=$FFDC_FSP_DRIVER_DIR/obj/x86.nfp/hbfw/simics
+ HB_DUMP_DEBUG=$HB_TOOLS_DIR/hb-dump-debug
+ _getInfoFromHBDump_ $HB_DUMP_DEBUG $HB_TOOLS_DIR
+
+ # If supplied a defect number, then post a comment to the defect and add
+ # the generated dump files as attachments
+ if [ -n "${FFDC_DEFECT_NUM}" ]; then
+ PATH=${FFDC_3RD_PARTY_SCRIPT_DIR}:$PATH
+ CQFILE=${FFDC_3RD_PARTY_SCRIPT_DIR}updatecq.pl
+
+ echo ""
+ echo -e "\n Adding attachment TRACE${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}TRACE${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS -s "Hostboot dump files stored at $FFDC_DEST_DIR"
+
+ echo -e "\n Adding attachment PRINTK${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}PRINTK${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS
+
+ echo -e "\n Adding attachment ERRL${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}ERRL${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS
+
+ echo -e "\n Adding attachment PS${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}PS${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS
+
+ echo -e "\n Adding attachment PS_BACKTRACE${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}PS_BACKTRACE${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS
+
+ echo -e "\n Adding attachment MEMSTATS${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}MEMSTATS${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS
+
+ echo -e "\n Adding attachment PAGEMGR${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}PAGEMGR${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS
+
+ echo -e "\n Adding attachment BLTRACE${FFDC_TIME_STAMP} to defect ${FFDC_DEFECT_NUM} ..."
+ perl $CQFILE -id $FFDC_DEFECT_NUM -a ${FFDC_DEST_DIR}BLTRACE${FFDC_TIME_STAMP} -u $FFDC_CQ_USER -p $FFDC_CQ_PASS
+ fi
+}
+
+
+###############################################################################
+# @brief The main. The real starting place of this script
+#
+# @return 0 if successful, not 0 if a failure occurred
+###############################################################################
+function ffdcExpanderMain()
+{
+ # Get user input options and validate
+ _getUserInputOptionsAndValidate_ $*
+ FFDC_RETURN_VALUE=$?
+ # If call to _getUserInputOptionsAndValidate_ not successful, then propagate error back
+ if [ "$FFDC_RETURN_VALUE" != "0" ]; then
+ return $FFDC_RETURN_VALUE;
+ fi
+
+
+ # If caller supplied a gzipped file then unzip it
+ if [ -n "${FFDC_SYSDUMP_FILE_GZ}" ]; then
+ _unzipSysDumpFile_
+ FFDC_RETURN_VALUE=$?
+ fi
+ # If call to _unzipSysDumpFile_ not successful, then propagate error back
+ if [ "$FFDC_RETURN_VALUE" != "0" ]; then
+ return $FFDC_RETURN_VALUE;
+ fi
+
+
+ # If caller supplied a SYSDUMP file then extract HB dump file
+ if [ -n "${FFDC_SYSDUMP_FILE}" ]; then
+ _extractHbSysDumpFile_ ${FFDC_SYSDUMP_FILE}
+ FFDC_RETURN_VALUE=$?
+ fi
+ # If call to _extractHbSysDumpFile_ not successful, then propagate error back
+ if [ "$FFDC_RETURN_VALUE" != "0" ]; then
+ return $FFDC_RETURN_VALUE;
+ fi
+
+
+ # If caller supplied a HB dump file and a FSP build tag, then retrieve HB info
+ if [ -n "${FFDC_HB_DUMP_FILE}" ] && [ -n "${FFDC_FSP_DRIVER_DIR}" ]; then
+ # Save the FSP build tag as a file for the caller's benefit
+ touch ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ # Add some info data to the file
+ echo ${FFDC_FSP_BUILD_TAG} > ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ echo ${FFDC_FSP_DRIVER} >> ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+ echo ${FFDC_FSP_DRIVER_DIR} >> ${FFDC_DEST_DIR}${FFDC_FSP_BUILD_TAG}
+
+ _getInfoFromHBDumpAndPost_ ${FFDC_HB_DUMP_FILE} ${FFDC_FSP_DRIVER_DIR};
+ FFDC_RETURN_VALUE=$?
+ fi
+ # If call to _getInfoFromHBDumpAndPost_ not successful, then propagate error back
+ if [ "$FFDC_RETURN_VALUE" != "0" ]; then
+ return $FFDC_RETURN_VALUE;
+ fi
+
+ echo ""
+ return 0;
+}
+
+
+###############################################################################
+# @brief Call the main starting function, ffdcExpanderMain, the beginning point
+# of this script
+#
+# @return 0 if successful, not 0 if a failure occurred
+###############################################################################
+
+ffdcExpanderMain $*
+exit $?;
+
diff --git a/src/build/debug/simics-debug-framework.py b/src/build/debug/simics-debug-framework.py
index 3176f8cba..fd90806bb 100644
--- a/src/build/debug/simics-debug-framework.py
+++ b/src/build/debug/simics-debug-framework.py
@@ -516,7 +516,7 @@ def magic_instruction_callback(user_arg, cpu, arg):
# Stop the simulation, much like a hard-coded breakpoint
SIM_break_simulation( "Simulation stopped. (hap 7007)" )
- if arg == 7008:
+ if arg == 7008: # MAGIC_RANDOM
cpu.r3 = random.randint(1, 0xffffffffffffffffL)
if arg == 7009: # MAGIC_MEMORYLEAK_FUNCTION
@@ -525,6 +525,10 @@ def magic_instruction_callback(user_arg, cpu, arg):
if arg == 7011: #MAGIC_SIMICS_CHECK
cpu.r3 = 1
print "TimeManager::cv_isSimicsRunning = true"
+ # Clear the dump flag in case it was still set from a previous boot
+ # (this call happens only 1 time and it is very early in the boot)
+ if( os.environ.has_key('HB_DUMP_COMPLETE') ):
+ del os.environ['HB_DUMP_COMPLETE']
if arg == 7012: # MAGIC_LOAD_PAYLOAD
#For P9 the Payload load is much faster due to PNOR
@@ -537,6 +541,17 @@ def magic_instruction_callback(user_arg, cpu, arg):
#SIM_run_alone( run_command, cmd )
print "MAGIC_LOAD_PAYLOAD not implemented\n";
+ if arg == 7014: # MAGIC_HB_DUMP
+ # Collect a hostboot dump
+ # (no args)
+
+ # Make sure we only do 1 dump even though every thread will TI
+ if( not os.environ.has_key('HB_DUMP_COMPLETE') ):
+ print "Generating Hostboot Dump for TI"
+ os.environ['HB_DUMP_COMPLETE']="1"
+ cmd1 = "hb-Dump quiet"
+ SIM_run_alone(run_command, cmd1 )
+
if arg == 7018: # MAGIC_BREAK_ON_ERROR
# Stop the simulation if an env var is set
if( os.environ.has_key('HB_BREAK_ON_ERROR') ):
@@ -573,6 +588,7 @@ def magic_instruction_callback(user_arg, cpu, arg):
percent_s = "%s"
dateCommand = "shell \" date +'%s > TRACE REGS: %d %d' \""%(percent_s,first_num,second_num)
SIM_run_alone(run_command, dateCommand )
+
if arg == 7022: # MAGIC_SET_LOG_LEVEL
if( not os.environ.has_key('ENABLE_HB_SIMICS_LOGS') ):
#print("Skipping Hostboot Simics Logging because ENABLE_HB_SIMICS_LOGS is not set")
@@ -745,7 +761,9 @@ def magic_instruction_callback(user_arg, cpu, arg):
#file = open("hb_trace_debug.dat", "a")
#file.write("%s\n" % (saveCommand))
#file.close()
-
+ if arg == 7056: # MAGIC_GCOV_DUMP_NOW
+ print('Gcov dumping chain from 0x%x' % (cpu.r3,))
+ SIM_run_alone(run_command, 'hb-GcovModuleUnload "address=%d"' % (cpu.r3,))
# Continuous trace: Clear these files.
rc = os.system( "rm -f hbTracMERG" )
@@ -769,4 +787,3 @@ SIM_hap_add_callback_range( "Core_Magic_Instruction", magic_instruction_callback
# Run the registration automatically whenever this script is loaded.
register_hb_debug_framework_tools()
-
OpenPOWER on IntegriCloud