diff options
author | CamVan Nguyen <ctnguyen@us.ibm.com> | 2013-01-30 09:51:04 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-05-06 16:17:14 -0500 |
commit | e458eba2ec2c56e37b206e7fec5f1e79f2445fde (patch) | |
tree | 5877c7a91d3079b10e5c834a58ac32495ffb0c34 /src/build | |
parent | 13a771a926e662db5ecb9141debf977bd6bbd3fa (diff) | |
download | blackbird-hostboot-e458eba2ec2c56e37b206e7fec5f1e79f2445fde.tar.gz blackbird-hostboot-e458eba2ec2c56e37b206e7fec5f1e79f2445fde.zip |
Debug Framework tool to Retrieve Attribute Data (non-FAPI)
Change-Id: Ie09bf5486f37e7ce1236f3a6872603266b419488
RTC: 38197
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/3065
Tested-by: Jenkins Server
Reviewed-by: Brian H. Horton <brianh@linux.ibm.com>
Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/build')
-rwxr-xr-x | src/build/debug/Hostboot/Attr.pm | 936 | ||||
-rwxr-xr-x | src/build/debug/Hostboot/_DebugFrameworkVMM.pm | 6 |
2 files changed, 941 insertions, 1 deletions
diff --git a/src/build/debug/Hostboot/Attr.pm b/src/build/debug/Hostboot/Attr.pm new file mode 100755 index 000000000..b5b4241b3 --- /dev/null +++ b/src/build/debug/Hostboot/Attr.pm @@ -0,0 +1,936 @@ +#!/usr/bin/perl +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/build/debug/Hostboot/Attr.pm $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2012,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 + +# +# This perl module can be used in a standalone Hostboot environment +# (Simics or VBU) or with a L3 dump file to dump a specified target's +# attribute(s). +# +# Authors: CamVan Nguyen +# Mark Wenning +# + +use strict; +package Hostboot::Attr; +use Hostboot::_DebugFrameworkVMM; +use Exporter; +our @EXPORT_OK = ('main'); + +use POSIX; +use File::Basename; +use Data::Dumper; +$Data::Dumper::Sortkeys = 1; + + +#------------------------------------------------------------------------------ +# Constants +#------------------------------------------------------------------------------ + +use constant PAGESIZE => 4096; # 4KB + +## each target object takes up space for: +## uint32_t iv_attrs + void *iv_pAttrNames + void *iv_pAttrValues +use constant TARGETSIZE => 20; +## Attribute id's are uint32_t enums +use constant ATTRID_SIZE => 4; +## pointers to attribute values should be 8 bytes +use constant ATTRVALUESPTR_SIZE => 8 ; + +## size of the TargetsHdr struct at the beginning of PNOR +use constant TARGETS_HDR_SIZE => 0x100; + +#------------------------------------------------------------------------------ +# Globals +#------------------------------------------------------------------------------ + +my %pages = (); +my %sections = ( + 'PNOR_RO' => { 'vaddr' => 0x100000000, + 'physaddr' => 0x0, + }, + 'PNOR_RW' => { 'vaddr' => 0x108000000, + 'physaddr' => 0x0, + }, + 'HEAP_ZERO_INIT' => { 'vaddr' => 0x110000000, + 'physaddr' => 0x0, + }, + 'HB_HEAP_ZERO_INIT' => { 'vaddr' => 0x118000000, + 'physaddr' => 0x0, + }, + ); +my @targets = (); +my $attrListRef = {}; + + +#------------------------------------------------------------------------------ +# Forward Declarations +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# Main +#------------------------------------------------------------------------------ +sub main +{ + my ($packName,$args) = @_; + + #-------------------------------------------------------------------------- + # Process input arguments + #-------------------------------------------------------------------------- + my $debug = 0; + if (defined $args->{"debug"}) + { + $debug = $args->{"debug"}; + + my $debugFileName = ::getImgPath() . "Attr.debug"; + open(DEBUG_FILE, "> $debugFileName") + or die "Cannot open file $debugFileName"; + + ::userDisplay "write debug info to $debugFileName\n"; + } + + my $opt_huid = ""; + if (defined $args->{"huid"}) + { + $opt_huid = $args->{"huid"}; + chomp $opt_huid; + + ::userDisplay "huid=$opt_huid option specified. \n"; + } + + my $opt_attrname = ""; + if (defined $args->{"attrname"}) + { + $opt_attrname = $args->{"attrname"}; + chomp $opt_attrname; + + ::userDisplay "attrname=$opt_attrname option specified. \n"; + } + + ## Normally this will not need to be specified, this is the default. + my $attrListFile = "targAttrInfo.csv"; + + ## read --attrfile in case the user wants to override + if (defined $args->{"attrfile"}) + { + $attrListFile = $args->{"attrfile"}; + } + + #-------------------------------------------------------------------------- + # Read in the file that associates the attr name, attr id, and size . + #-------------------------------------------------------------------------- + $attrListFile = ::getImgPath() . $attrListFile; + + unless (-e $attrListFile) + { + ::userDisplay "Cannot find attribute list file \"$attrListFile\".\n"; + die; + } + + ::userDisplay "Using attribute list file \"$attrListFile\"\n\n"; + + #-------------------------------------------------------------------------- + # Process the attribute list file. Save data to a hash. + # + # Format of file is: + # <FAPI-ATTR-ID-STR>,<LAYER-ATTR-ID-STR>,<ATTR-ID-VAL>,<ATTR-TYPE> + # We are not interested in the FAPI-ATTR-ID-STR, parse the rest of + # the csv fields. + #-------------------------------------------------------------------------- + open(FILE, "< $attrListFile") or die "Cannot open file $attrListFile"; + + my @lines = <FILE>; + my $attrIdHex = 0; + + # Get the attribute data and index by ID + foreach my $line (@lines) + { + chomp($line); + my ( $fapi_attr_id_str, + $layer_attr_id_str, + $attr_id_val, + $attr_type ) = split( ',', $line ); + + ## convert to scalar for a clean index + $attrIdHex = hex( $attr_id_val ); + + $attrListRef->{$attrIdHex}->{'str'} = $layer_attr_id_str ; + $attrListRef->{$attrIdHex}->{'type'} = $attr_type ; + } + close(FILE) or die "Cannot close $attrListFile"; + + ## $$ debug + ## ::userDisplay Dumper( $attrListRef ); + + #-------------------------------------------------------------------------- + # Initialize Global Vars + #-------------------------------------------------------------------------- + my $cacheData = 0; + + ## ----------------------------------------------------------------------- + ## Initialize Target and Attribute Section info + ## ----------------------------------------------------------------------- + my $secref = \%sections; + $secref->{'PNOR_RO'}->{'physaddr'} = + getPhysicalAddr( $secref->{'PNOR_RO'}->{'vaddr'} ); + $secref->{'PNOR_RW'}->{'physaddr'} = + getPhysicalAddr( $secref->{'PNOR_RW'}->{'vaddr'} ); + $secref->{'HEAP_ZERO_INIT'}->{'physaddr'} = + getPhysicalAddr( $secref->{'HEAP_ZERO_INIT'}->{'vaddr'} ); + $secref->{'HB_HEAP_ZERO_INIT'}->{'physaddr'} = + getPhysicalAddr( $secref->{'HB_HEAP_ZERO_INIT'}->{'vaddr'} ); + + + if ( $debug ) + { + ## Dump Targeting Header + ::userDisplay "dump Targeting Header: \n" ; + my $data = readData( $secref->{'PNOR_RO'}->{'vaddr'} , + 256, + $cacheData, + $debug ); + userDisplayHex( $data ); + } + + ## The first thing in the first section (i.e. after the TargetHeader) + ## should be a vaddr pointer to the number of targets, followed by an + ## array of all the targets. + ## + ## Read the pointer to numTargets and the targetArray. + ## skip over the 256 byte header to get to the first section + my $numTargetsPtr = 0; + my $numTargets = 0; + $numTargetsPtr = + readDataHex( ($secref->{'PNOR_RO'}->{'vaddr'}+TARGETS_HDR_SIZE), + 8, $cacheData, $debug ); + $numTargets = + readDataHex( $numTargetsPtr, + 4, $cacheData, $debug ); + + ## bump the pointer by a uint32_t. We should now be pointing to the + ## first target. + my $targetsPtr = $numTargetsPtr + 4; + if ( $debug ) + { + ## Sanity check + ::userDisplay + "ptr to numTargets: ", + (sprintf("0x%016x", $numTargetsPtr)), "\n", + "ptr to targets: ", + (sprintf("0x%016x", $targetsPtr)), "\n", + "numTargets: ", + (sprintf("0x%08x", $numTargets)), "\n" ; + } + + ::userDisplay "Reading target and attribute data,", + " this may take a while...\n"; + + + ## Fill in the @targets array with the target info + for ( my $i=0; $i<$numTargets; $i++ ) + { + my $targInfoRef = {}; + my $offset = $i*TARGETSIZE; + my $attrSize = 0; + + ## Read in the number of attributes associated with this target + $targInfoRef->{'iv_attr'} = readDataHex( ($targetsPtr + $offset), + 4, $cacheData, $debug ); + $offset += 4 ; ## bump to iv_AttrNames ptr and store + $targInfoRef->{'iv_pAttrNames'} = readDataHex( ($targetsPtr+$offset), + 8, $cacheData, $debug ); + $offset += 8 ; ## bump to iv_AttrValues ptr and store + $targInfoRef->{'iv_pAttrValues'} = readDataHex( ($targetsPtr+$offset), + 8, $cacheData, $debug ); + + + ## + ## Follow the iv_pAttrNames pointer to read in the attribute id's + ## associated with this target + ## + my @attrIds = getAttrIds( $targInfoRef, + $cacheData, + $debug ); + ## $$ debug + ## ::userDisplay join(", ", @attrIds), "\n"; + + ## follow the iv_AttrValues pointer to read in the value pointers + ## associated with each target. + ## This should be in 1 to 1 correspondence with the @attrIds array + ## above. + my @attrValuePtrs = getAttrValuePtrs( $targInfoRef, + $cacheData, + $debug ); + ## $$ debug + ## ::userDisplay join(", ", @attrValuePtrs), "\n"; + + ## + ## Fill in the attribute values for each attribute id / name, + ## indexed by the name. + ## + + for ( my $j=0; $j<$targInfoRef->{'iv_attr'}; $j++ ) + { + my $thisAttrId = $attrIds[$j]; + my $thisAttrName = $attrListRef->{$thisAttrId}->{'str'} ; + if ( $thisAttrName eq "" ) + { + ## if we can't find the attribute in the attrList file, + ## it is probably not an integer or integer array. + ## Make up a name. When we print all the attributes at the + ## end, these will be skipped unless --debug is turned on. + ## @TODO RTC 68517 Handle non-simple non-integer types + ## as part of the above RTC to make all attr dump tools + ## compatible with cronus. + $thisAttrName = "ATTR_TBD_" . (sprintf("0x%x", $thisAttrId)); + } + + ## save the order that they came in. + $targInfoRef->{$thisAttrName}->{'index'} = $j; + + ## store the attribute id + $targInfoRef->{$thisAttrName}->{'attrid'} = $thisAttrId; + + ## read the type and derive the size from the attrList hash. + my $attrType = $attrListRef->{$thisAttrId}->{'type'}; + $targInfoRef->{$thisAttrName}->{'attrtype'} = $attrType; + + ## parseType will return a size for simple types, for arrays + ## etc it will fill in @parseDesc . + my @parseDesc = (); + my $readSize = parseType( $attrType, \@parseDesc, $debug ); + $targInfoRef->{$thisAttrName}->{'attrsize'} = $readSize; + $targInfoRef->{$thisAttrName}->{'attrDesc'} = \@parseDesc; + + if ( $debug ) + { + print DEBUG_FILE "process $thisAttrName $attrType ", + ", parseDesc= ", scalar(@parseDesc), + ", vaddr=", + (sprintf("0x%X",$attrValuePtrs[$j])), + ", readSize=$readSize", + "\n" ; + } + + ## Save the vaddr for debug. + $targInfoRef->{$thisAttrName}->{'attrvaddr'} = $attrValuePtrs[$j]; + + ## fetch the attribute value. Read and store this as a raw + ## binary hex string (mixed in with "not present" messages) + ## and process it later. + my $rawData = 0; + $rawData = readData( $attrValuePtrs[$j], + $readSize, + $cacheData, $debug ); + + $targInfoRef->{$thisAttrName}->{'attrvalue'} = $rawData; + + } ## endfor $j (attributes) + + $targets[$i] = $targInfoRef; + + } ## endfor $i (targets) + + if ( $debug ) + { + print DEBUG_FILE "\n", Dumper( @targets ); + } + + + ## -------------------------------------------------------------- + ## print out results + ## -------------------------------------------------------------- + my $foundTarget = 0; + + ::userDisplay "# number of targets = $numTargets\n" ; + + foreach my $targetRef ( @targets ) + { + my $targHuid = binToHex( $targetRef->{'ATTR_HUID'}->{'attrvalue'} ); + + if ( $opt_huid eq "" ) + { + displayTargetAttributes( $targetRef, $opt_attrname, $debug ); + } + else + { + my $inHuid = hex( $opt_huid ); + if ( $debug ) + { + ::userDisplay + "inHuid=", (sprintf("0x%X"),$inHuid), + ", targHuid=", (sprintf("0x%X"),$targHuid), + "\n"; + } + if ( $inHuid == $targHuid ) + { + $foundTarget = 1; + displayTargetAttributes( $targetRef, $opt_attrname, $debug ); + } + } + + last if ( $foundTarget ); + + } ## end foreach $targetRef + + + if ( $debug ) + { + close DEBUG_FILE; + } + +} ## end main + +## +## passed a targetref, print all or one of its' attributes in +## more-or-less cronus format +## +sub displayTargetAttributes +{ + my ( $targetRef, $attrname, $debug ) = @_; + my $foundAttr = 0; + + ## print HUID and number of attributes (in a comment) first + ## as a sanity check. + my $huid = binToHex( $targetRef->{'ATTR_HUID'}->{'attrvalue'} ); + + ::userDisplay "\n# huid = ", (sprintf("0x%X",$huid)), "\n"; + ::userDisplay "# number of attributes = ",$targetRef->{'iv_attr'}, "\n"; + ::userDisplay "target = ", cronusTargetStr( $huid ), "\n" ; + + foreach my $attr ( sort keys %$targetRef ) + { + + if ( $attrname ne "" ) + { + if ( $debug ) + { + ::userDisplay "attr=$attr, attrname=$attrname \n"; + } + + ## if the attrname option is defined, skip any other attribute + next if ( $attr ne $attrname ); + } + + if ( $attr eq $attrname ) + { + $foundAttr = 1; + } + + ## skip the "iv_" keys. + next if ( !($attr =~ m/ATTR_/) ); + + ## skip the unknown ones, unless debug is on. + if ( !$debug ) + { + next if ( $attr =~ m/ATTR_TBD/ ); + } + + ## make local copies + my $attrType = $targetRef->{$attr}->{'attrtype'} ; + my @attrDesc = @{$targetRef->{$attr}->{'attrDesc'}}; + my $rawAttrValue = $targetRef->{$attr}->{'attrvalue'} ; + + ## sanity check + if (($rawAttrValue eq Hostboot::_DebugFrameworkVMM::NotFound) || + ($rawAttrValue eq Hostboot::_DebugFrameworkVMM::NotPresent)) + { + ::userDisplay $attr ; + ::userDisplay " $attrType "; + ::userDisplay $rawAttrValue . ": vaddr=" . + (sprintf("0x%X",$targetRef->{$attr}->{'attrvaddr'})) ; + + return; + } + + + if ( scalar( @attrDesc ) == 0 ) + { + ## print attr and type + ::userDisplay $attr, " ", + $attrType, " " ; + + ## Print out value(s) + my $attrValue = binToHex($rawAttrValue); + ::userDisplay (sprintf( "0x%X ", $attrValue )) ; + ::userDisplay "\n" ; + + } + else + { + ## array. + + userDisplayArray( $targetRef, $attr ); + } + + last if ( $foundAttr ); + + } ## end foreach $attr +} + + +sub userDisplayArray +{ + my ( $targetRef, $attr ) = @_; + + my $attrType = $targetRef->{$attr}->{'attrtype'}; + my $rawAttrValue = $targetRef->{$attr}->{'attrvalue'}; + my @attrDesc = @{$targetRef->{$attr}->{'attrDesc'}}; + + ## assume max dimension of 3 deep, and always a good 1st dimension + my $i = 0; + my $j_index = -1; + my $k_index = -1; + my $size = $attrDesc[$i]; $i++; + my $i_index = $attrDesc[$i]; $i++; + my $enum = $attrDesc[$i]; $i++; + if ( $attrDesc[$i] ) + { + $i++; + $j_index = $attrDesc[$i]; $i++; + $i++; + if ( $attrDesc[$i] ) + { + $i++; + $k_index = $attrDesc[$i]; + $i++; + if ( $attrDesc[$i] ) + { + die "array dimensions > 3 are not supported."; + } + } + } + + + if ( $k_index > 0 ) + { + userDisplay3dArray( $attr, + $attrType, + $size, + $i_index, + $j_index, + $k_index, + $rawAttrValue ); + } + elsif ($j_index > 0 ) + { + userDisplay2dArray( $attr, + $attrType, + $size, + $i_index, + $j_index, + $rawAttrValue ); + } + else + { + ## single array + my $upsz = $size*2; + my @values = unpack("(H$upsz)*", $rawAttrValue ); + ## $$ debug + ## ::userDisplay scalar(@values), ": ", join( ", ", @values), "\n" ; + my $valindex = 0; + for ( my $i=0; $i<$i_index; $i++ ) + { + ##$$debug ::userDisplay (sprintf("%02x ", $valindex) ); + ::userDisplay $attr ; + ::userDisplay "[$i]" ; + ::userDisplay " $attrType "; + ::userDisplay $values[$valindex] ; $valindex++; + ::userDisplay "\n"; + } ## endfor i + } ## end else +} + + +sub userDisplay2dArray +{ + my ($attr, + $attrType, + $size, + $i_index, + $j_index, + $rawAttrValue ) = @_; + + my $upsz = $size*2; + my @values = unpack("(H$upsz)*", $rawAttrValue ); + ## $$ debug + ## ::userDisplay scalar(@values), ": ", join( ", ", @values), "\n" ; + my $valindex = 0; + for ( my $i=0; $i<$i_index; $i++ ) + { + for ( my $j=0; $j<$j_index; $j++ ) + { + ##$$debug ::userDisplay (sprintf("%02x", $valindex) ); + ::userDisplay $attr ; + ::userDisplay "[$i][$j]" ; + ::userDisplay " $attrType "; + ::userDisplay $values[$valindex] ; $valindex++; + ::userDisplay "\n"; + } ## endfor j + } ## endfor i + +} + + +sub userDisplay3dArray +{ + my ($attr, + $attrType, + $size, + $i_index, + $j_index, + $k_index, + $rawAttrValue) = @_; + + my $upsz = $size*2; + my @values = unpack("(H$upsz)*", $rawAttrValue ); + ## $$ debug + ## ::userDisplay scalar(@values), ": ", join( ", ", @values), "\n" ; + my $valindex = 0; + for ( my $i=0; $i<$i_index; $i++ ) + { + for ( my $j=0; $j<$j_index; $j++ ) + { + for ( my $k=0; $k<$k_index; $k++ ) + { + ##$$debug ::userDisplay (sprintf("%02x ", $valindex) ); + ::userDisplay $attr ; + ::userDisplay "[$i][$j][$k]" ; + ::userDisplay " $attrType "; + ::userDisplay $values[$valindex] ; $valindex++; + ::userDisplay "\n"; + } ## endfor k + } ## endfor j + } ## endfor i +} + + + +sub cronusTargetStr() +{ + my ( $huid ) = @_; + my $cronusTargetStr = "TBD"; + + ## TBD + + return $cronusTargetStr; +} + + +## +## translate cronus-type type strings to: +## Integer size in bytes +## Number of integers to read +## Enumerated type flag +## Fills in list(s) of these 3 values that describes each field, +## for example: +## u64[5][6][1] +## ( size=8,num=5,enum=0 ), ## dimension 1 +## ( size=8,num=6,enum=0 ), ## dimension 2 +## ( size=8,num=1,enum=0 ), ## dimension 3 +## ( size=0,num=0,enum=0 ), ## endit +## +## if the attr type is a single simpleType, returns the size in bytes. +## If the attr type is more complicated, return the total size in bytes +## and fill in the passed-in parse Description struct. +## +sub parseType +{ + my ( $type, $parseDescRef, $debug ) = @_; + + my $size = 8; ## default + my $num = 1; ## default + my $enum = 0; ## default + my $totalSize = 1; + + $_ = $type; + if ( m/u8/ ) { $size = 1; } + if ( m/u16/ ) { $size = 2; } + if ( m/u32/ ) { $size = 4; } + if ( m/u64/ ) { $size = 8; } + + ## @TODO RTC 68517 Add code to display non-simple non-integer types + + $totalSize = $size; + + ## remove size spec + s/[u][0-9]*[e]*//; + + ## find any arrays + my @arrayDims = split /\[([^\]]*)\]/g ; + + if ( scalar( @arrayDims ) > 0 ) + { + ## Array. Build the description struct and calculate the right size + my $i = 0; + foreach ( @arrayDims ) + { + ## skip empty array entries + next if ( ! m/[0-9]+/ ) ; + + @{$parseDescRef}[$i] = $size; $i++; ## size in bytes + @{$parseDescRef}[$i] = $_; $i++; ## number of vars + @{$parseDescRef}[$i] = $enum; $i++; ## enum flag + + $totalSize *= $_ ; + } + + ## add a terminating record + @{$parseDescRef}[$i] = 0; $i++; + @{$parseDescRef}[$i] = 0; $i++; + @{$parseDescRef}[$i] = 0; $i++; + + } + + return $totalSize; +} + + + +## +## Fetch Attr Ids, passed a pointer to a Target's attrid list. +## return an array of the attr id's +sub getAttrIds() +{ + my ( $targInfoRef, $cacheData, $debug ) = @_; + my $pAttrIds = $targInfoRef->{'iv_pAttrNames'}; + my $numAttrs = $targInfoRef->{'iv_attr'}; + my @attrIds = (); + + my $rawattrids = readData( $pAttrIds, + (ATTRID_SIZE*$numAttrs), + $cacheData, $debug ); + + ## split and convert from binary + my @unpackattrids = unpack( "(H8)*", $rawattrids ); + + my $i = 0; + foreach ( @unpackattrids ) + { + @attrIds[$i] = hex($_); + $i++; + } + + return @attrIds; +} + +## +## fetch the array of pointers to attr values +## return an array of the attr values. +sub getAttrValuePtrs() +{ + my ( $targInfoRef, $pAttrValues, $numAttrs, $cacheData, $debug ) = @_; + my $pAttrValues = $targInfoRef->{'iv_pAttrValues'}; + my $numAttrs = $targInfoRef->{'iv_attr'}; + my @attrvalueptrs = (); + my @attrValues = (); + + my $rawattrvalueptrs = readData( $pAttrValues, + (ATTRVALUESPTR_SIZE*$numAttrs), + $cacheData, $debug ); + + ## split and convert from binary + my @unpackattrvalueptrs = unpack( "(H16)*", $rawattrvalueptrs); + + my $i = 0; + foreach ( @unpackattrvalueptrs ) + { + @attrvalueptrs[$i] = hex($_); + $i++; + } + + return @attrvalueptrs; +} + +# +# Utility to read a block of data. Caches 4K blocks to save time. +# returns "binary" data +# +sub readData +{ + my ($vaddr, $size, $cache_data, $debug) = @_; + + my $result = ""; + + if ($debug == 2) + { + ::userDisplay sprintf("Reading $size bytes from vaddr 0x%X\n", $vaddr); + } + + while($size) + { + my $amount = $size; + + if ((($vaddr % PAGESIZE) + $size) > PAGESIZE) + { + $amount = PAGESIZE - ($vaddr % PAGESIZE); + if ($debug == 2) + { + ::userDisplay sprintf("Data crossing page boundary for addr " . + "0x%X size $size\n", $vaddr); + } + } + + if ($cache_data) + { + # Read the entire page and cache it + my $vpageaddr = $vaddr - ($vaddr % PAGESIZE); + if (!defined $pages{$vpageaddr}) + { + my $paddr = getPhysicalAddr($vpageaddr ); + if ((Hostboot::_DebugFrameworkVMM::NotFound eq $paddr) || + (Hostboot::_DebugFrameworkVMM::NotPresent eq $paddr)) + { + return $paddr; + } + else + { + if ($debug==2) + { + ::userDisplay sprintf("Caching data for address ". + "0x%X = 0x%x\n", $vpageaddr, $paddr); + } + + $pages{$vpageaddr} = ::readData($paddr, PAGESIZE); + } + } + elsif ($debug==2) + { + ::userDisplay sprintf("Using cached data for address 0x%X\n", + $vpageaddr); + } + + $result = $result. + substr($pages{$vpageaddr}, $vaddr % PAGESIZE, + $amount); + } + else + { + my $paddr = getPhysicalAddr($vaddr); + if ((Hostboot::_DebugFrameworkVMM::NotFound eq $paddr) || + (Hostboot::_DebugFrameworkVMM::NotPresent eq $paddr)) + { + return $paddr; + } + else + { + $result = $result.::readData($paddr, $amount); + } + } + + $vaddr = $vaddr + $amount; + $size = $size - $amount; + } + + return $result; +} + + + +## +## Read $bytes amount of data from $vaddr, using readData above. +## return a valid hex scalar number. +## Print an error message and return 0 if VirtToPhys says "not present" +## +sub readDataHex() +{ + my ( $vaddr, $bytes, $cacheData, $debug ) = @_; + + my $data = readData( $vaddr, + $bytes, + $cacheData, + $debug ); + + if ((Hostboot::_DebugFrameworkVMM::NotFound eq $data) || + (Hostboot::_DebugFrameworkVMM::NotPresent eq $data)) + { + + ::userDisplay "readDataHex ERROR: ", + (sprintf("0x%X",$vaddr)), ": $data\n"; + + return 0; + } + + my $result = binToHex( $data ); + + return $result; +} + + +## +## read raw binary string and convert it to a hex scalar +## +sub binToHex() +{ + my ( $rawData ) = @_; + + my $result = hex(unpack("H*",$rawData)); + + return $result; +} + +# Utility to display a block of data +sub userDisplayHex +{ + my $data = shift; + my $count = 0; + + # Make it easier to read by displaying as two bytes chunks + my @twobytes = unpack("(H4)*", $data); + ::userDisplay "\n "; + foreach (@twobytes) + { + ::userDisplay "$_ "; + $count++; + if (!($count % 8)) + { + ::userDisplay "\n "; + } + } + ::userDisplay "\n"; +} + +sub helpInfo +{ + my %info = ( + name => "Attr", + intro => ["Dump the specified target attribute(s)."], + options => { + "huid=<HUID>" => ["HUID of the target as a hex number.", + "If not specified, will output attribute(s) of all ". + "targets."], + "attrname=<attribute name>" => ["Attribute to dump.", + "If not specified, will output all attributes for the ". + "specified target."], + "attrfile" => ["specify an alternate attribute " . + "information file. Normally this will not be needed."], + "debug" => ["More debug output."], + }, + ); +} + + +## modules must return a 1 at the end +1; +__END__ + diff --git a/src/build/debug/Hostboot/_DebugFrameworkVMM.pm b/src/build/debug/Hostboot/_DebugFrameworkVMM.pm index e8c7dfd3b..caa48d534 100755 --- a/src/build/debug/Hostboot/_DebugFrameworkVMM.pm +++ b/src/build/debug/Hostboot/_DebugFrameworkVMM.pm @@ -440,7 +440,11 @@ sub getPhysicalAddr ::userDisplay (sprintf " VirtualToPhy: Did not find a block for v addr: %X\n" , $vaddr); - die; + ## Don't die here, return NotPresent. + ## @TODO Issue RTC 63901 will review this and provide a + ## a permanent fix. + return NotPresent; + } # get the physical address from SPTE entry in this block |