summaryrefslogtreecommitdiffstats
path: root/src/build/debug/Hostboot
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2012-09-19 14:23:54 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-10-09 17:06:49 -0500
commitfb1836fd7b1b8839815595db08ae740ec7b86347 (patch)
tree54ff93536489c27b80af1f503520bd9894cdcfd3 /src/build/debug/Hostboot
parent84e4274fe412a577f67805cc701f4fb66a3feb2f (diff)
downloadtalos-hostboot-fb1836fd7b1b8839815595db08ae740ec7b86347.tar.gz
talos-hostboot-fb1836fd7b1b8839815595db08ae740ec7b86347.zip
Support code coverage in extended modules.
- Reduce optimization (to -Os) to fit when doing coverage profile. - Remove errl storage area from base image. - Add GCC function attributes to sys library functions. RTC: 36933 Change-Id: Ic83011a2444ef5b735db0446a14a0af34187eebf Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1908 Tested-by: Jenkins Server Reviewed-by: Brian H. Horton <brianh@linux.ibm.com> Reviewed-by: ADAM R. MUHLE <armuhle@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: Melissa J. Connell <missyc@us.ibm.com> Reviewed-by: Paul Nguyen <nguyenp@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/build/debug/Hostboot')
-rwxr-xr-xsrc/build/debug/Hostboot/Errl.pm45
-rwxr-xr-xsrc/build/debug/Hostboot/Gcov.pm193
-rwxr-xr-xsrc/build/debug/Hostboot/_DebugFrameworkVMM.pm33
3 files changed, 214 insertions, 57 deletions
diff --git a/src/build/debug/Hostboot/Errl.pm b/src/build/debug/Hostboot/Errl.pm
index ca4564d24..46d510b5a 100755
--- a/src/build/debug/Hostboot/Errl.pm
+++ b/src/build/debug/Hostboot/Errl.pm
@@ -1,26 +1,26 @@
#!/usr/bin/perl
-# IBM_PROLOG_BEGIN_TAG
-# This is an automatically generated prolog.
-#
-# $Source: src/build/debug/Hostboot/Errl.pm $
-#
-# IBM CONFIDENTIAL
-#
-# COPYRIGHT International Business Machines Corp. 2011
-#
-# 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 other-
-# wise divested of its trade secrets, irrespective of what has
-# been deposited with the U.S. Copyright Office.
-#
-# Origin: 30
-#
-# IBM_PROLOG_END
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/debug/Hostboot/Errl.pm $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2011,2012
+#
+# 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
use strict;
use File::Temp;
@@ -83,6 +83,7 @@ sub main
::userDisplay "Couldn't find symbol ERRORLOG::g_ErrlStorage\n";
die;
}
+ $symAddr = ::read64($symAddr); # Dereference g_ErrlStorage pointer.
# Size of buffer resides at offset zero of buffer for length of 4
my $errlSize;
diff --git a/src/build/debug/Hostboot/Gcov.pm b/src/build/debug/Hostboot/Gcov.pm
index 73325f58c..0ebfaaef3 100755
--- a/src/build/debug/Hostboot/Gcov.pm
+++ b/src/build/debug/Hostboot/Gcov.pm
@@ -26,6 +26,8 @@ use File::Path;
use File::Basename;
package Hostboot::Gcov;
+use Hostboot::_DebugFrameworkVMM qw(NotFound NotPresent getPhysicalAddr);
+
use Exporter;
our @EXPORT_OK = ('main');
@@ -170,12 +172,16 @@ sub parseModuleGcov
userDebug("\tFound info at 0x" . (sprintf "%x", $gcov_info) . "\n");
- # TODO: We don't support extended image modules yet because the VMM
- # debug tools don't exist yet.
- if ($gcov_info > GCOV_EXTENDED_IMAGE_ADDRESS)
+ # Translate gcov_info chain to a physical address if in a module.
+ if (isVirtualAddress($gcov_info))
{
- ::userDisplay "\tUnable to parse extended image modules. Skipped.\n";
- return;
+ $gcov_info = getPhysicalAddr($gcov_info);
+
+ if (($gcov_info eq NotFound) || ($gcov_info eq NotPresent))
+ {
+ ::userDisplay "\tModule data is not present.\n";
+ return;
+ }
}
# Check that we found the gcov_info chain.
@@ -186,7 +192,7 @@ sub parseModuleGcov
}
# Parse info chain.
- parseGcovInfo(::read64($gcov_info));
+ parseGcovInfo(read64($gcov_info));
}
sub parseGcovInfo
@@ -194,19 +200,19 @@ sub parseGcovInfo
my $info_ptr = shift;
return if (0 eq $info_ptr);
- my $filename = ::readStr(::read64($info_ptr + GCOV_INFO_FILENAME_OFFSET));
+ my $filename = readStr(read64($info_ptr + GCOV_INFO_FILENAME_OFFSET));
userDebug("\tFile = ".$filename."\n");
- my $version = ::read32($info_ptr + GCOV_INFO_VERSION_OFFSET);
- my $stamp = ::read32($info_ptr + GCOV_INFO_TIMESTAMP_OFFSET);
+ my $version = read32($info_ptr + GCOV_INFO_VERSION_OFFSET);
+ my $stamp = read32($info_ptr + GCOV_INFO_TIMESTAMP_OFFSET);
- my $func_count = ::read32($info_ptr + GCOV_INFO_NFUNCTIONS_OFFSET);
+ my $func_count = read32($info_ptr + GCOV_INFO_NFUNCTIONS_OFFSET);
userDebug("\tFunction Count = ".$func_count."\n");
- my $funcs = ::read64($info_ptr + GCOV_INFO_FUNCTIONS_OFFSET);
+ my $funcs = read64($info_ptr + GCOV_INFO_FUNCTIONS_OFFSET);
userDebug("\tFunc Address = ".(sprintf "%x", $funcs)."\n");
- my $ctrmask = ::read32($info_ptr + GCOV_INFO_CTRMASK_OFFSET);
+ 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,
@@ -214,7 +220,7 @@ sub parseGcovInfo
my $fd = createGcovFile($filename, $version, $stamp);
- my $arcs_ptr = ::read64($info_ptr + GCOV_INFO_COUNTS_OFFSET +
+ my $arcs_ptr = read64($info_ptr + GCOV_INFO_COUNTS_OFFSET +
GCOV_CTRINFO_VALUEPTR_OFFSET);
parseGcovFuncs($fd, $funcs, $func_count, $ctrmask, $arcs_ptr);
@@ -226,7 +232,7 @@ sub parseGcovInfo
}
# 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);
parseGcovInfo($next);
}
@@ -270,8 +276,8 @@ sub parseGcovFuncs
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);
+ my $ident = read32($func_off + GCOV_FNINFO_IDENT_OFFSET);
+ my $chksum = read32($func_off + GCOV_FNINFO_CHECKSUM_OFFSET);
userDebug("Ident = ".(sprintf "%x", $ident)."\n");
userDebug("Chksum = ".(sprintf "%x", $chksum)."\n");
@@ -281,16 +287,21 @@ sub parseGcovFuncs
print $fd pack('l', $ident); # Write ident.
print $fd pack('l', $chksum); # Write checksum.
- my $nctr_val = ::read32($func_off + GCOV_FNINFO_NCTRS_OFFSET);
+ my $nctr_val = read32($func_off + GCOV_FNINFO_NCTRS_OFFSET);
userDebug("N-Counters = ".$nctr_val."\n");
print $fd pack('l', GCOV_COUNTERS_TAG); # Write counter tag.
print $fd pack('l', $nctr_val * 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++)
{
- my $val = ::read64($val_ptr + 8*($fn_offset + $v_idx));
+ my $val = substr $counters, 0, 8;
+ $counters = substr $counters, 8;
+ if (::littleendian()) { $val = reverse($val); }
+ $val = unpack("Q", $val);
userDebug("\tValue[$v_idx] = ".$val."\n");
print $fd pack('l', $val & 0xFFFFFFFF); # Write lower word.
@@ -356,6 +367,152 @@ sub getModules
return @result;
}
+# Determine if an address is virtual.
+sub isVirtualAddress
+{
+ my $addr = shift;
+
+ return ($addr >= GCOV_EXTENDED_IMAGE_ADDRESS);
+}
+
+# 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;
+sub readData
+{
+ my $addr = shift;
+ my $size = shift;
+
+ if (isVirtualAddress($addr))
+ {
+ my $result = "";
+
+ while($size)
+ {
+ my $amount = $size;
+
+ if ((($addr % PAGESIZE) + $size) >= PAGESIZE)
+ {
+ $amount = PAGESIZE - ($addr % PAGESIZE);
+ }
+
+ my $paddr = getPhysicalAddr($addr);
+ if ((NotFound eq $paddr) || (NotPresent eq $paddr))
+ {
+ $paddr = $addr - GCOV_EXTENDED_IMAGE_ADDRESS;
+ $result = $result.::readExtImage($paddr, $amount);
+ }
+ else
+ {
+ $result = $result.::readData($paddr, $amount);
+ }
+
+ $size = $size - $amount;
+ }
+
+ return $result;
+ }
+
+ return ::readData($addr, $size);
+}
+
+# Utility to read 64 bits from either memory or using the extended image file
+# as a fallback if not present in memory.
+sub read64
+{
+ my $addr = shift;
+ my $old_addr = $addr;
+ if (isVirtualAddress($addr))
+ {
+ $addr = getPhysicalAddr($addr);
+ if ((NotFound eq $addr) || (NotPresent eq $addr))
+ {
+ $addr = $old_addr - GCOV_EXTENDED_IMAGE_ADDRESS;
+ my $result = ::readExtImage($addr, 8);
+ if (::littleendian()) { $result = reverse($result); }
+ return unpack("Q", $result);
+ }
+ }
+
+ return ::read64($addr);
+}
+
+# Utility to read 32 bits from either memory or using the extended image file
+# as a fallback if not present in memory.
+sub read32
+{
+ my $addr = shift;
+ my $old_addr = $addr;
+ if (isVirtualAddress($addr))
+ {
+ $addr = getPhysicalAddr($addr);
+ if ((NotFound eq $addr) || (NotPresent eq $addr))
+ {
+ $addr = $old_addr - GCOV_EXTENDED_IMAGE_ADDRESS;
+ my $result = ::readExtImage($addr, 4);
+ if (::littleendian()) { $result = reverse($result); }
+ return unpack("L", $result);
+ }
+ }
+
+ return ::read32($addr);
+}
+
+# Utility to read 8 bits from either memory or using the extended image file
+# as a fallback if not present in memory.
+sub read8
+{
+ my $addr = shift;
+ my $old_addr = $addr;
+ if (isVirtualAddress($addr))
+ {
+ $addr = getPhysicalAddr($addr);
+ if ((NotFound eq $addr) || (NotPresent eq $addr))
+ {
+ $addr = $old_addr - GCOV_EXTENDED_IMAGE_ADDRESS;
+ my $result = ::readExtImage($addr, 1);
+ return unpack("C", $result);
+ }
+ }
+
+ return ::read8($addr);
+}
+
+# Utility to read a string from either memory or using the extended image file
+# as a fallback if not present in memory.
+sub readStr
+{
+ my $addr = shift;
+ my $old_addr = $addr;
+ if (isVirtualAddress($addr))
+ {
+ $addr = $addr - GCOV_EXTENDED_IMAGE_ADDRESS;
+
+ # Virtual address, so need to read 1 byte at a time from the file.
+ my $string = "";
+ my $byte = 0;
+
+ do
+ {
+ $byte = ::readExtImage($addr,1);
+ $addr = $addr + 1;
+
+ if (unpack("C",$byte) eq 0)
+ {
+ return $string;
+ }
+
+ $string = $string.$byte;
+
+ } while (1)
+ }
+ else
+ {
+ ::readStr($addr);
+ }
+}
+
+
sub userDebug
{
return if (!$debug_mode);
diff --git a/src/build/debug/Hostboot/_DebugFrameworkVMM.pm b/src/build/debug/Hostboot/_DebugFrameworkVMM.pm
index dc5cbfa59..7de8d548d 100755
--- a/src/build/debug/Hostboot/_DebugFrameworkVMM.pm
+++ b/src/build/debug/Hostboot/_DebugFrameworkVMM.pm
@@ -1,26 +1,26 @@
#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
-#
+#
# $Source: src/build/debug/Hostboot/_DebugFrameworkVMM.pm $
-#
+#
# IBM CONFIDENTIAL
-#
+#
# COPYRIGHT International Business Machines Corp. 2011,2012
-#
+#
# 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
+#
+# IBM_PROLOG_END_TAG
# _DebugFrameworkVMM.pm
#
# This module is a set of utility functions for the debug framework, which
@@ -51,7 +51,6 @@ our @EXPORT = (
'printDeviceSegments'
);
-
use constant NotFound => 'not found';
use constant NotPresent => 'not present';
@@ -86,9 +85,9 @@ use constant BLOCK_SPTE_OFFSET => 32;
-our @EXPORT_OK = ('NotFound');
-our @EXPORT_OK = ('NotPresent');
-our @EXPORT_OK = ('SEGMGR_BASE_SEGMENT_OFFSET',
+our @EXPORT_OK = ('NotFound',
+ 'NotPresent',
+ 'SEGMGR_BASE_SEGMENT_OFFSET',
'SEGMGR_STACK_SEGMENT_OFFSET',
'SEGMGR_FIRSTDEVICE_SEGMENT_OFFSET',
'STACKSEGMENT_BASEADDR_OFFSET',
@@ -797,7 +796,7 @@ sub getNumPresentPages
while( $i<$pages)
{
- my $SPTE_entry = ::read32 ($SPTE_ptr + $i, 4);
+ my $SPTE_entry = ::read32 ($SPTE_ptr + (4*$i), 4);
# if found present
if ($SPTE_entry & 0x00000800)
@@ -823,7 +822,7 @@ sub getNumPresentPages
# their info.
# In addition each individual device segment could have
# up to 32 mmio devices populated so this routine will print
-# out those as well.
+# out those as well.
#
# @param Ptr to the Address of the First Device segment
# we need to work with from the segment manager
@@ -856,7 +855,7 @@ sub printDeviceSegments
DEVICESEGMENT_BASEADDR_OFFSET, 8);
# If the device segment is valid, then print out its info and
- # check for MMIO devices populated.
+ # check for MMIO devices populated.
if ($deviceSegmentPtr != 0)
{
#::userDisplay (sprintf " segmentbaseaddr: %X\n" , $segmentbaseaddr);
@@ -912,6 +911,6 @@ sub printDeviceSegments
}
-
+1;
__END__
OpenPOWER on IntegriCloud