diff options
| author | Patrick Williams <iawillia@us.ibm.com> | 2013-06-24 12:35:57 -0500 |
|---|---|---|
| committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-07-10 16:29:19 -0500 |
| commit | b649b6d8ad62262517b7e0da90fbfd81283f4764 (patch) | |
| tree | 25c868da431cc42dd201512df8b4a1b0048915f3 /src/build/debug | |
| parent | 8e6af8d1488285d670754de8f34ffba9ce57db92 (diff) | |
| download | talos-hostboot-b649b6d8ad62262517b7e0da90fbfd81283f4764.tar.gz talos-hostboot-b649b6d8ad62262517b7e0da90fbfd81283f4764.zip | |
Enhance hb-dump to support full memory extraction.
Change-Id: I74823572a4935d3c8c4d7999d8c00c0286de1523
RTC: 50233
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/5170
Tested-by: Jenkins Server
Reviewed-by: Andrew J. Geissler <andrewg@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/build/debug')
| -rwxr-xr-x | src/build/debug/Hostboot/Dump.pm | 112 | ||||
| -rwxr-xr-x | src/build/debug/fsp-memdump.sh | 161 |
2 files changed, 260 insertions, 13 deletions
diff --git a/src/build/debug/Hostboot/Dump.pm b/src/build/debug/Hostboot/Dump.pm index 9eb4ee11f..43ace962b 100755 --- a/src/build/debug/Hostboot/Dump.pm +++ b/src/build/debug/Hostboot/Dump.pm @@ -6,7 +6,7 @@ # # IBM CONFIDENTIAL # -# COPYRIGHT International Business Machines Corp. 2011,2012 +# COPYRIGHT International Business Machines Corp. 2011,2013 # # p1 # @@ -28,37 +28,123 @@ package Hostboot::Dump; use Exporter; our @EXPORT_OK = ('main'); -use constant L3_SIZE => 0x800000; +use Fcntl qw(SEEK_SET); + +use constant MEMSTATE_NO_MEM => 0x0; +use constant MEMSTATE_HALF_CACHE => 0x4; +use constant MEMSTATE_FULL_CACHE => 0x8; +use constant MEMSTATE_MS_32MEG => 0x20; +use constant MEMSTATE_PRE_SECURE_BOOT => 0xff; + +use constant _KB => 1024; +use constant _MB => 1024 * 1024; + +# Map the available memory at each state. +our %memory_maps = ( + MEMSTATE_NO_MEM() => + # No memory has been initialized so we can only dump our static + # code load up to 512 - 4k. The 4k is a reserved space for the + # Secureboot Header. + [ 0, (512 - 4) * _KB + ], + MEMSTATE_PRE_SECURE_BOOT() => + # Until the early secureboot operations have been done, we can + # only access the top 512k of each 1MB column. Need to avoid + # the hole for the MBOX DMA buffers (64K @ 3MB + 256K). + [ (512 - 4) * _KB, 4 * _KB, + 1 * _MB, 512 * _KB, + 2 * _MB, 512 * _KB, + 3 * _MB, 256 * _KB, + 3 * _MB + (256 + 64) * _KB, (256 - 64) * _KB + ], + MEMSTATE_HALF_CACHE() => + # All of the first 4MB can now be read (except reserved MBOX). + [ 512 * _KB, 512 * _KB, + 1 * _MB + 512 * _KB, 512 * _KB, + 2 * _MB + 512 * _KB, 512 * _KB, + 3 * _MB + 512 * _KB, 512 * _KB + ], + MEMSTATE_FULL_CACHE() => + # Add next full 4MB after we expand to the full cache. + [ 4 * _MB, 1 * _MB, + 5 * _MB, 1 * _MB, + 6 * _MB, 1 * _MB, + 7 * _MB, 1 * _MB + ], + MEMSTATE_MS_32MEG() => + # Add next 24MB after we expand to memory. + [ 8 * _MB, 24 * _MB + ] +); + +# Map the current state to the combined states available. +our %memory_states = ( + MEMSTATE_NO_MEM() => [ MEMSTATE_NO_MEM ], + MEMSTATE_PRE_SECURE_BOOT() => [ MEMSTATE_NO_MEM, MEMSTATE_PRE_SECURE_BOOT ], + MEMSTATE_HALF_CACHE() => [ MEMSTATE_NO_MEM, MEMSTATE_PRE_SECURE_BOOT, + MEMSTATE_HALF_CACHE ], + MEMSTATE_FULL_CACHE() => [ MEMSTATE_NO_MEM, MEMSTATE_PRE_SECURE_BOOT, + MEMSTATE_HALF_CACHE, MEMSTATE_FULL_CACHE ], + MEMSTATE_MS_32MEG() => [ MEMSTATE_NO_MEM, MEMSTATE_PRE_SECURE_BOOT, + MEMSTATE_HALF_CACHE, MEMSTATE_FULL_CACHE, + MEMSTATE_MS_32MEG ] +); sub main { my ($packName,$args) = @_; - #Get current timestamp + # Parse 'debug' option. + my $debug = 0; + if (defined $args->{"debug"}) + { + $debug = 1; + } + + # Read the current memory state. + my ($memstate_addr, $memstate_size) = + ::findSymbolAddress("KernelMemState::state"); + my $memstate = ::read32($memstate_addr + 4); # only need bottom 32 bits + ::userDisplay (sprintf "Current state is %x\n", $memstate) if $debug; + + #Get current timestamp and open a corresponding file. my $timeStamp = `date +%Y%m%d%H%M`; chomp $timeStamp; - #::userDisplay "timestamp: $timeStamp\n"; - my $hbDumpFile = "hbdump.$timeStamp"; - ::userDisplay "Dumping L3 to Open output file $hbDumpFile..\n"; + ::userDisplay "Dumping Hostboot to Open output file $hbDumpFile\n"; open( OUTFH, ">$hbDumpFile" ) or die "can't open $hbDumpFile: $!\n"; + binmode(OUTFH); + + # Read memory regions and output to file. + foreach my $state (@{$memory_states{int $memstate}}) + { + my $regions = $memory_maps{int $state}; + + while (scalar(@{$regions})) + { + my $start = shift @{$regions}; + my $length = shift @{$regions}; + ::userDisplay (sprintf "\t%x@%x\n", $length, $start) if $debug; - ## read in 8 MB!! - my $data = ::readData( 0, L3_SIZE ); - write( OUTFH, $data ); - close( OUTFH ) or die "can't close $hbDumpFile: $!\n"; + my $data = ::readData($start, $length); + seek OUTFH, $start, SEEK_SET; + print OUTFH $data; + } + } + # Close file. + close OUTFH; #Check if hbDumpFile exists and is not empty if (-s "$hbDumpFile" ) { ::userDisplay "\nHostBoot dump saved to $hbDumpFile.\n"; - ::userDisplay "Use hb-parsedump.pl program to parse the dump.\n"; + ::userDisplay "Use the hb-dump-debug program to parse the dump.\n"; } else { - ::userDisplay "\nWARNING: Cannot dump L3. Did you stop instructions?\n\n"; + ::userDisplay "\nWARNING: Cannot dump HB. Did you stop instructions?\n\n"; unlink $hbDumpFile; } } @@ -67,6 +153,6 @@ sub helpInfo { my %info = ( name => "Dump", - intro => ["Dumps the entire L3 buffer to a file."], + intro => ["Dumps the entire Hostboot buffer to a file."], ); } diff --git a/src/build/debug/fsp-memdump.sh b/src/build/debug/fsp-memdump.sh new file mode 100755 index 000000000..25d347fa4 --- /dev/null +++ b/src/build/debug/fsp-memdump.sh @@ -0,0 +1,161 @@ +#!/bin/sh +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/build/debug/fsp-memdump.sh $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2013 +# +# 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 + + +# @fn usage +# Print usage statement. +usage() +{ + echo "memdump.sh <filename> [STATE|discover]" + echo + echo " STATE should be a two nibble hex value corresponding to the" + echo " MemSize enumeration in <kernel/memstate.H> or the ASCII string" + echo " 'discover'." + exit -1 +} + +# @fn dump +# Extract a block of memory using cipgetmempba. +# +# @param addr - Address to extract. +# @param size - Size (in bytes) to extract. +dump() +{ + addr=$1 + size=$2 + + memaddr=`expr $addr + $HRMOR` + + echo "Extracting ${size}@${addr}" + + cipgetmempba `printf "%08x" ${memaddr}` ${size} -fb /tmp/memdump.part + dd bs=1 if=/tmp/memdump.part of=${FILE} seek=${addr} count=${size} \ + conv=notrunc + rm /tmp/memdump.part +} + +# @fn discover +# Read the HB descriptor to determine the current memory state and update the +# STATE variable. +discover() +{ + # Calculate hostboot descriptor address. (0x2000 + 8 + HRMOR) + descriptor_addr=`expr 8200 + $HRMOR` + descriptor_h=`printf "%08x" ${descriptor_addr}` + + # Extract descriptor base address. + state_base_h=`cipgetmempba ${descriptor_h} 8 -ox -quiet | tail -n1` + state_base=`printf "%d" ${state_base_h}` + + # Calculate offset for the state variable within the descriptor. + # Last byte of 3rd 8-byte entry. (16 + 7 + BASE + HRMOR) + state_addr=`expr 16 + 7 + ${state_base} + ${HRMOR}` + state_addr_h=`printf "%08x" ${state_addr}` + + # Read state. + STATE=`cipgetmempba ${state_addr_h} 1 -ox -quiet | tail -n1 | sed "s/0x//"` +} + +# Read filename and state. +FILE=$1 +STATE=$2 +if [[ -z ${FILE} ]]; then + usage +fi + +if [[ -z ${STATE} ]]; then + STATE=08 +fi + +# Calculate HRMOR (in decimal). +HRMOR=`expr 128 \* 1024 \* 1024` + +# Using initial STATE, iterate through all the included states dumping each's +# appropriate memory sections. +while [[ ${STATE} != BREAK ]] +do + case ${STATE} in + 00|0) + dump 0 520192 + STATE=BREAK + ;; + ff|FF) + dump 520192 4096 + dump 1048576 524288 + dump 2097152 524288 + dump 3145728 262144 + dump 3473408 196608 + STATE=00 + ;; + 04|4) + dump 524288 524288 + dump 1572864 524288 + dump 2621440 524288 + dump 3670016 524288 + STATE=ff + ;; + 08|8) + dump 4194304 1048576 + dump 5242880 1048576 + dump 6291456 1048576 + dump 7340032 1048576 + STATE=04 + ;; + 20) + dump 8388608 1048576 + dump 9437184 1048576 + dump 10485760 1048576 + dump 11534336 1048576 + dump 12582912 1048576 + dump 13631488 1048576 + dump 14680064 1048576 + dump 15728640 1048576 + dump 16777216 1048576 + dump 17825792 1048576 + dump 18874368 1048576 + dump 19922944 1048576 + dump 20971520 1048576 + dump 22020096 1048576 + dump 23068672 1048576 + dump 24117248 1048576 + dump 25165824 1048576 + dump 26214400 1048576 + dump 27262976 1048576 + dump 28311552 1048576 + dump 29360128 1048576 + dump 30408704 1048576 + dump 31457280 1048576 + dump 32505856 1048576 + STATE=08 + ;; + discover) # Call discover function to determine state. + discover + ;; + *) + echo Unsupported STATE. + STATE=BREAK + ;; + esac +done + |

