summaryrefslogtreecommitdiffstats
path: root/src/build/debug/Hostboot
diff options
context:
space:
mode:
authorMark Wenning <wenning@us.ibm.com>2012-05-09 17:19:03 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-05-21 12:59:00 -0500
commit487669b2da18343f648b4984765c36bb11f59b14 (patch)
tree38b47ee244c34deef4abc879ea95c9bcd2362ae4 /src/build/debug/Hostboot
parent8277968ad48681189bf58cb785ebf01c5d6fdf37 (diff)
downloadtalos-hostboot-487669b2da18343f648b4984765c36bb11f59b14.tar.gz
talos-hostboot-487669b2da18343f648b4984765c36bb11f59b14.zip
hb-istep in debug framework
Change-Id: I21d95952e526e3ade6399c2f7e022e0897ae4610 RTC: 38308 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/959 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/build/debug/Hostboot')
-rwxr-xr-xsrc/build/debug/Hostboot/Istep.pm1017
-rwxr-xr-xsrc/build/debug/Hostboot/_DebugFramework.pm32
2 files changed, 1045 insertions, 4 deletions
diff --git a/src/build/debug/Hostboot/Istep.pm b/src/build/debug/Hostboot/Istep.pm
new file mode 100755
index 000000000..e014e26fd
--- /dev/null
+++ b/src/build/debug/Hostboot/Istep.pm
@@ -0,0 +1,1017 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/vpo/hb-istep $
+#
+# 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 other-
+# wise divested of its trade secrets, irrespective of what has
+# been deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
+#
+# Purpose: This perl script works in concert with do_sprint to
+# implement isteps on AWAN.
+#
+# Description:
+# The do_sprint script will run first to set up the AWAN environment,
+# Then call hb_Istep twice:
+# 1) hb_Istep [--]istepmode
+# called after loading but before starting HostBoot
+# this will check to see if the user has set istep mode, if so
+# it will write the Istep_mode signature to L3 memory to put
+# HostBoot mode into single-step mode (spless or FSP).
+# 2) hb_Istep [--]command
+# Periodically call ::executeInstrCycles() to step through HostBoot.
+# Checks for status from previous Isteps, and reports status.
+#
+# Author: Mark Wenning
+#
+# DEVELOPER NOTES:
+# Do NOT put prints or printf's in this script!!!
+# simics-debug-framework.pl and simics-debug-framework.py communicate
+# (recvIPCmsg and sendIPCmsg) overstdin and stdout -
+# if you print to STDOUT you will inadvertently send an empty/corrupted
+# "IPC" message to python/simics which will usually cause ugly crashes.
+#
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use strict;
+use POSIX; # isdigit
+
+## 64-bit input
+use bigint;
+no warnings 'portable';
+
+
+## declare Istep package
+package Hostboot::Istep;
+use Exporter;
+our @EXPORT_OK = ('main');
+
+#------------------------------------------------------------------------------
+# Constants
+#------------------------------------------------------------------------------
+## @todo extract these from splesscommon.H
+use constant SPLESS_MODE_SIGNATURE => 0x4057b0074057b007;
+use constant FSP_MODE_SIGNATURE => 0x700b7504700b7504;
+use constant RUN_ALL_MODE_SIGNATURE => 0xBADC0FFEE0DDF00D;
+
+use constant SPLESS_SINGLE_ISTEP_CMD => 0x00;
+use constant SPLESS_RESUME_ISTEP_CMD => 0x01;
+use constant SPLESS_CLEAR_TRACE_CMD => 0x02;
+use constant SPLESS_SHUTDOWN_CMD => 0x03;
+
+
+use constant MAX_ISTEPS => 25;
+use constant MAX_SUBSTEPS => 25;
+
+## Mailbox Scratchpad regs
+use constant MBOX_SCRATCH0 => 0x00050038;
+use constant MBOX_SCRATCH1 => 0x00050039;
+use constant MBOX_SCRATCH2 => 0x0005003a;
+use constant MBOX_SCRATCH3 => 0x0005003b;
+
+#------------------------------------------------------------------------------
+# Globals
+#------------------------------------------------------------------------------
+my $opt_debug = 0;
+my $opt_splessmode = 0;
+my $opt_fspmode = 0;
+my $opt_command = 0;
+my $opt_list = 0;
+my $opt_resume = 0;
+my $opt_clear_trace = 0;
+
+## deprecated - keep around for now
+my $opt_istepmode = 0;
+
+my $command = "";
+
+
+## initialize inList to "undefined"
+my @inList;
+$inList[MAX_ISTEPS][MAX_SUBSTEPS] = ();
+for( my $i = 0; $i < MAX_ISTEPS; $i++)
+{
+ for(my $j = 0; $j < MAX_SUBSTEPS; $j++)
+ {
+ undef( $inList[$i][$j] );
+ }
+}
+
+## initialize the sequence number - 6 bit field, { 0 - 63 }
+my $g_SeqNum = int(rand(64));
+
+my $THREAD = "0";
+
+
+## --------------------------------------------------------------------------
+## get any environment variables
+## --------------------------------------------------------------------------
+
+## @todo make this an enviroment var?
+## NOTE: this is the # cycles used for simics, it is multiplied by 100
+## in vpo-debug-framework.pl
+## my $hbDefaultCycles = 50000;
+my $hbDefaultCycles = 5000000;
+
+my $hbCount = $ENV{'HB_COUNT'};
+if ( !defined( $hbCount ) || ( $hbCount eq "" ) )
+{
+ ## set default
+ $hbCount = 0xffffffff; ## effectively infinite ...
+}
+
+
+## fetch all the symbols we need.
+my $IstepModeReg = getSymbol( "SPLESS::g_SPLess_IStepMode_Reg" );
+my $ShutDownFlag = getSymbol( "CpuManager::cv_shutdown_requested" );
+my $ShutDownSts = getSymbol( "CpuManager::cv_shutdown_status" );
+
+## @todo deprecated, fetch anyway for now
+my $CommandReg = getSymbol( "SPLESS::g_SPLess_Command_Reg" );
+my $StatusReg = getSymbol( "SPLESS::g_SPLess_Status_Reg" );
+
+
+########################################################################
+## MAIN ROUTINE, called from debug framework
+########################################################################
+sub main
+{
+ ## $packName is the name of the selected tool
+ ## $args is a hashref to all the command-line arguments
+ my ($packName,$args) = @_;
+
+
+ ## debug - save
+ while ( my ($k,$v) = each %$args )
+ {
+ ::userDisplay "args: $k => $v\n";
+ }
+
+ ::userDisplay "Welcome to hb-Istep 3.3 .\n";
+ ::userDisplay "Note that in simics, multiple options must be in quotes\n\n";
+ ## fetch the istep list
+ get_istep_list();
+
+ ## $$ debug, dump all the environment vars that we are interested in
+ dumpEnvVar( "HB_TOOLS" );
+ dumpEnvVar( "HB_IMGDIR" );
+ dumpEnvVar( "HB_VBUTOOLS" );
+ dumpEnvVar( "HB_COUNT" );
+
+ ##--------------------------------------------------------------------------
+ ## Start processing options
+ ## process the "flag" standard options, then use a loop to go through
+ ## the rest
+ ##--------------------------------------------------------------------------
+ ## Get all the command line options in an array
+ my @options = ( keys %$args );
+
+ if ( !(@options) )
+ {
+ ::userDisplay "type \"help hb-istep\" for help\n";
+ exit;
+ }
+
+ ## find all the standard options, set their flag, and remove them from
+ ## the options list.
+ ## vpo and simics have used difference command-line styles, simics
+ ## wanted you to say "hb-istep debug s4", and vpo wanted you to say
+ ## "hb-istep --debug --command s4" . This should accept both styles.
+ ##
+ for ( my $i=0; $i <= $#options; $i++ )
+ {
+ $_ = $options[$i];
+
+ if ( m/\-{0,2}debug/ )
+ {
+ $opt_debug = 1;
+ $options[$i] = "";
+ }
+ if ( m/\-{0,2}list/ )
+ {
+ $opt_list = 1;
+ $options[$i] = "";
+ }
+ if ( m/\-{0,2}istepmode/ )
+ {
+ $opt_istepmode = 1;
+ $options[$i] = "";
+ }
+ if ( m/\-{0,2}splessmode/ )
+ {
+ $opt_splessmode = 1;
+ $options[$i] = "";
+ }
+ if ( m/\-{0,2}fspmode/ )
+ {
+ $opt_fspmode = 1;
+ $options[$i] = "";
+ }
+ if ( m/\-{0,2}command/ )
+ {
+ ## doesn't do much, just eats the option
+ $opt_command = 1;
+ $options[$i] = "";
+ }
+ if ( m/\-{0,2}resume/ )
+ {
+ $opt_resume = 1;
+ $options[$i] = "";
+ }
+ if ( m/\-{0,2}clear-trace/ )
+ {
+ $opt_clear_trace = 1;
+ $options[$i] = "";
+ }
+ } ## endfor
+
+ ## if there's anything left after this, assume it is a command
+ $command = join( "", @options );
+ chomp $command;
+
+ ## print out debug info
+ if ( $opt_debug )
+ {
+ ::userDisplay "\n----- DEBUG: ------------------------------- \n";
+ ::userDisplay "debug = $opt_debug\n";
+ ::userDisplay "list = $opt_list\n";
+ ::userDisplay "splessmode = $opt_splessmode\n";
+ ::userDisplay "fspmode = $opt_fspmode\n";
+
+ ::userDisplay "resume = $opt_resume\n";
+ ::userDisplay "clear-trace = $opt_clear_trace\n";
+ ::userDisplay "command flag = $opt_command\n";
+ ::userDisplay "command = \"$command\"\n";
+
+ ::userDisplay "g_SeqNum = ", sprintf("0x%x",$g_SeqNum), "\n";
+ ::userDisplay "IstepModeReg = ", sprintf("0x%x",$IstepModeReg), "\n";
+ ::userDisplay "CommandReg = ", sprintf("0x%x",$CommandReg), "\n";
+ ::userDisplay "StatusReg = ", sprintf("0x%x",$StatusReg), "\n";
+ ::userDisplay "ShutDownFlag = ", sprintf("0x%x",$ShutDownFlag), "\n";
+ ::userDisplay "ShutDownSts = ", sprintf("0x%x",$ShutDownSts), "\n";
+
+ ::userDisplay "hbCount = ", sprintf("0x%x",$hbCount), "\n";
+
+ ::userDisplay "\n";
+ }
+
+ if ( $opt_debug ) { ::userDisplay "=== check ShutDown Status...\n"; }
+ if ( isShutDown() )
+ {
+ ::userDisplay "Cannot run hb-Istep.\n";
+ exit;
+ }
+
+ ## ----------------------------------------------------------------
+ ## finally, run some commands.
+ ## ----------------------------------------------------------------
+
+ if ( $opt_list )
+ {
+ ::userDisplay "List isteps\n";
+ print_istep_list();
+ exit;
+ }
+
+ if ( $opt_istepmode )
+ {
+ ::userDisplay "istepmode no longer used - use splessmode, or fspmode\n";
+ exit;
+ }
+
+ if ( $opt_splessmode )
+ {
+ ::userDisplay "ENable splessmode\n";
+ setMode( "spless" );
+ exit;
+ }
+
+ if ( $opt_fspmode )
+ {
+ ::userDisplay "ENable fspmode\n";
+ setMode( "fsp" );
+ exit;
+ }
+
+ ## don't do any other commands unless ready bit is on.
+ if ( ! isReadyBitOn() )
+ {
+ ::userDisplay "Ready bit is off, must run splessmode or fspmode first.\n";
+ exit;
+ }
+
+ if ( $opt_clear_trace )
+ {
+ ::userDisplay "Clear Trace\n";
+ clear_trace();
+ exit;
+ }
+
+ if ( $opt_resume )
+ {
+ ::userDisplay "Resume\n";
+ resume_istep();
+ exit;
+ }
+
+ if ( $opt_command || ( $command ne "" ) )
+ {
+ ::userDisplay "Process command \"$command\"\n";
+ process_command( $command );
+ exit;
+ }
+
+ ::userDisplay "Done.\n";
+ exit 0;
+} ## end main
+
+########################################################################
+## SUBROUTINES
+########################################################################
+##
+
+
+sub helpInfo
+{
+ my %info = (
+ name => "Istep",
+ intro => ["Executes isteps."],
+ options => { "list" => [" list out all supported isteps "],
+ "splessmode" => ["enable istep mode"],
+ "fspmode" => ["enable istep mode"],
+ "resume" => ["resume an istep that is at a break point"],
+ "clear-trace" => ["clear trace buffers before starting"],
+ "sN" => ["run istep N"],
+ "sN..M" => ["run isteps N through M"],
+ "<foo>" => ["run named istep \"foo\""],
+ "<foo>..<bar>" => ["run named isteps \"foo\" through \"bar\""],
+ }
+ );
+}
+
+
+## Increment the sequence number, rolling over at 64
+## ---------------------------------------------------------------------------
+sub bumpSeqNum()
+{
+
+ $g_SeqNum++;
+
+ $g_SeqNum %= 64;
+
+ return $g_SeqNum;
+}
+
+## ---------------------------------------------------------------------------
+## Dump environment variable specified.
+## ---------------------------------------------------------------------------
+sub dumpEnvVar( $ )
+{
+ my $envvar = shift;
+
+ if ( defined( $ENV{$envvar} ) )
+ {
+ ::userDisplay "$envvar = $ENV{$envvar}\n";
+ }
+}
+
+##
+## Get symbol address from hbotSymsFile
+##
+sub getSymbol( )
+{
+ my $symbol = shift;
+ my ($symAddr, $symSize) = ::findSymbolAddress( $symbol ) ;
+
+ if ( not defined( $symAddr ) )
+ {
+ ::userDisplay "Cannot find $symbol.\n"; die;
+ }
+
+ return $symAddr;
+}
+
+##
+## read in file with csv istep list and store in inList
+##
+sub get_istep_list()
+{
+ my $istep, my $substep, my $name ;
+
+ my @isteplist = ::getIstepList();
+
+ foreach( @isteplist )
+ {
+ chomp;
+
+ ( $istep, $substep, $name) = split( ",", $_ );
+ chomp $name;
+
+ ## ::userDisplay "$_, $istep, $substep, $name\n" ;
+
+ if ( defined($name) && ( $name ne "" ) )
+ {
+ $inList[$istep][$substep] = $name;
+ }
+ }
+
+}
+
+
+##
+## print the istep list to the screen.
+##
+sub print_istep_list( )
+{
+ my $hdrflag = 1;
+
+ ::userDisplay " IStep Name\n";
+ ::userDisplay "---------------------------------------------------\n";
+
+ for(my $i = 4; $i < MAX_ISTEPS; $i++)
+ {
+ for(my $j = 0; $j < MAX_SUBSTEPS; $j++)
+ {
+ ## print all substeps
+ if ( defined( $inList[$i][$j] ) )
+ {
+ if ( $hdrflag )
+ {
+ ::userDisplay " -- IStep $i -- \n";
+ $hdrflag = 0;
+ }
+ ::userDisplay " $inList[$i][$j]\n" ;
+ }
+ } ## end for $j
+
+ $hdrflag=1;
+ } ## end for $i
+}
+
+
+##
+## Find istep name in inList array.
+##
+## @param[in] - name
+##
+## @return - istep #, substep #, found flag = true for success
+## false for not found
+##
+sub find_in_inList( $ )
+{
+ my ( $substepname ) = @_;
+
+ for(my $i = 0; $i < MAX_ISTEPS; $i++)
+ {
+ for(my $j = 0; $j < MAX_SUBSTEPS; $j++)
+ {
+ if ( defined($inList[$i][$j]) && ($inList[$i][$j] eq $substepname ) )
+ {
+ return ($i, $j, 1 );
+ }
+ }
+ }
+
+ return ( MAX_ISTEPS, MAX_SUBSTEPS, 0 )
+}
+
+##
+## When HostBoot goes into singlestep mode, it turns on the ready bit in the
+## status reg.
+##
+## @return nonzero if ready bit is on, else 0
+##
+sub isReadyBitOn()
+{
+ my $result = 0;
+ my $readybit = 0;
+
+ $result = getStatus( );
+ $readybit = ( ( $result & 0x4000000000000000 ) >> 62 );
+
+ if ( $opt_debug ) { ::userDisplay "=== readybit: $readybit\n"; }
+
+ if ( $readybit )
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+
+
+
+##
+## Check if HostBoot has already run and shutdown.
+##
+## @return nonzero if it has, 0 otherwise
+##
+sub isShutDown()
+{
+
+ my $flag = ::read64( $ShutDownFlag );
+ my $status = ::read64( $ShutDownSts );
+
+ if ( $opt_debug )
+ {
+ ::userDisplay "=== isShutDown : Shutdown Flag = $flag\n";
+ ::userDisplay "=== isShutDown : Shutdown Status = $status\n";
+ }
+
+ if ( $flag )
+ {
+ ::userDisplay "HostBoot has shut down with status $status.\n";
+ return 1;
+ }
+
+ return 0;
+}
+
+##
+## Write to the IstepMode reg in memory. This will not be changed to scom
+##
+## @param[in] - 64-bit value to write to the IstepModeReg
+##
+sub writeIstepModeReg( $ )
+{
+ my $data = shift;
+
+ if ( $opt_debug )
+ { ::userDisplay "=== writeIstepmodeReg ", sprintf("0x%x",$data), "\n"; }
+
+ ::write64( $IstepModeReg, $data );
+
+}
+
+
+##
+## Read IStepModeReg from memory. This will not be changed to scom.
+##
+## @return 64-bit value read from IStepModeReg
+##
+sub readIstepModeReg( )
+{
+ my $data = 0;
+
+ $data = ::read64( $IstepModeReg );
+
+ if ( $opt_debug )
+ { ::userDisplay "=== readIstepmodeReg ", sprintf("0x%x",$data), "\n"; }
+
+ return $data;
+}
+
+## --------------------------------------------------------------------
+## Write command reg
+##
+## @param[in] - HEX STRING containing the 64-bit command word
+##
+## @return none
+##
+## --------------------------------------------------------------------
+sub sendCommand( $ )
+{
+ my $data = shift;
+
+ if ( $opt_debug )
+ { ::userDisplay "=== sendCommand( $data )\n"; }
+
+ ## convert to binary before sending to writescom
+ my $bindata = ( hex $data );
+
+ ## now write the data
+ ::writeScom( MBOX_SCRATCH3, 8, $bindata );
+
+ if ( $opt_debug )
+ {
+ ## sanity check
+ ::executeInstrCycles( 10);
+ my $readback = ::readScom( MBOX_SCRATCH3, 8 );
+ ::userDisplay "=== sendCommand readback: $readback\n";
+ }
+
+}
+
+
+## --------------------------------------------------------------------
+## read status reg
+##
+## Note - mbox scratchpad regs are only 32 bits, so HostBoot will return
+## status in mbox 2 (hi32 bits) and mbox 1 (lo32 bits).
+## mbox 0 is reserved for continuous trace.
+##
+##
+##
+## @return binary 64-bit value
+## --------------------------------------------------------------------
+sub getStatus()
+{
+ my $status = 0;
+ my $statusHi = "";
+ my $statusLo = "";
+
+ $statusHi = ::readScom( MBOX_SCRATCH2, 8 );
+ if ( $opt_debug ) { ::userDisplay "=== statusHi: $statusHi \n"; }
+
+ $statusLo = ::readScom( MBOX_SCRATCH1, 8 );
+ if ( $opt_debug ) { ::userDisplay "=== statusLo: $statusLo \n"; }
+
+ $status = ( ( (hex $statusHi) & 0xffffffff00000000 )
+ | (( (hex $statusLo) & 0xffffffff00000000 ) >> 32)
+ );
+
+ if ( $opt_debug )
+ {
+ ::userDisplay "=== getStatus() returned ", (sprintf( "0x%lx", $status ) ), "\n";
+ }
+
+ return $status;
+}
+
+
+##
+## keep trying to get status until seqnum syncs up
+##
+sub getSyncStatus( )
+{
+ # set # of retries
+ my $count = $hbCount ;
+ my $result = 0;
+ my $seqnum = 0;
+ my $running = 0;
+
+ ## get response. sendCmd() should have bumped g_SeqNum, so we will sit
+ ## here for a reasonable amount of time waiting for the correct sequence
+ ## number to come back.
+ while(1)
+ {
+
+ ## advance HostBoot code by a certain # of cycles, then check the
+ ## sequence number to see if it has changed. rinse and repeat.
+ ::executeInstrCycles( $hbDefaultCycles );
+
+
+ ## check to see if we need to dump trace - no-op in simics
+ ##::checkContTrace();
+
+ $result = getStatus();
+ $seqnum = ( ( $result & 0x3f00000000000000 ) >> 56 );
+ $running = ( ( $result & 0x8000000000000000 ) >> 63 );
+
+ ## @todo great place to add some debug, check running bit BEFORE
+ ## starting the clock (should be off), then run (relatively) small
+ ## number of clocks till the bit turns on.
+ ## If it doesn't go on, command was never received. If so,
+ ## come here to wait for it to go back off again.
+ ## if ( ( $running == 0 )
+ ## && ( $seqnum == $g_SeqNum )
+ if ( $seqnum == $g_SeqNum )
+ {
+ return $result;
+ }
+
+ if ( $count <= 0)
+ {
+ ::userDisplay "TIMEOUT waiting for seqnum=$g_SeqNum\n";
+ return -1;
+ }
+
+ $count--;
+
+ } ## endwhile
+
+}
+
+
+##
+## Run an istep
+##
+sub runIStep( $$ )
+{
+ my ( $istep, $substep) = @_;
+ my $byte0, my $command;
+ my $cmd;
+ my $result;
+
+
+ ## bump the seqnum
+ bumpSeqNum() ;
+
+ ::userDisplay "run $istep.$substep $inList[$istep][$substep]:\n" ;
+
+ $byte0 = 0x80 + $g_SeqNum; ## gobit + seqnum
+ $command = SPLESS_SINGLE_ISTEP_CMD;
+ $cmd = sprintf( "0x%2.2x%2.2x%2.2x%2.2x00000000", $byte0, $command, $istep, $substep );
+
+ sendCommand( $cmd );
+
+
+ $result = getSyncStatus();
+
+ ## if result is -1 we have a timeout
+ if ( $result == -1 )
+ {
+ ::userDisplay "-----------------------------------------------------------------\n";
+ }
+ else
+ {
+ my $taskStatus = ( ( $result & 0x00ff000000000000 ) >> 48 );
+ my $stsIStep = ( ( $result & 0x0000ff0000000000 ) >> 40 );
+ my $stsSubstep = ( ( $result & 0x000000ff00000000 ) >> 32 );
+ my $istepStatus = ( ( $result & 0x00000000ffffffff ) );
+
+ ::userDisplay "---------------------------------\n";
+ if ( $taskStatus != 0 )
+ {
+ ::userDisplay "Istep $stsIStep.$stsSubstep FAILED to launch, task status is $taskStatus\n" ;
+ }
+ else
+ {
+ ::userDisplay "Istep $stsIStep.$stsSubstep $inList[$istep][$substep] returned Status: ",
+ sprintf("0x%x",$istepStatus),
+ "\n" ;
+ if ( $istepStatus == 0xa )
+ {
+ ::userDisplay ": not implemented yet.\n";
+ }
+ }
+ ::userDisplay "------------------------------------------------------- SeqNum: $g_SeqNum\n";
+ }
+}
+
+##
+## run command = "sN"
+##
+sub sCommand( $ )
+{
+ my ( $scommand ) = @_;
+
+ my $i = $scommand;
+ my $j = 0;
+
+ # execute all the substeps in the IStep
+ for( $j=0; $j<MAX_SUBSTEPS; $j++ )
+ {
+
+
+ if ( defined( $inList[$i][$j] ) )
+ {
+ runIStep( $i, $j );
+ }
+ }
+}
+
+
+##
+## parse --command [command] option and execute it.
+##
+sub process_command( $ )
+{
+ my ( $command ) = @_;
+ my @execlist;
+ my $istepM, my $substepM, my $foundit, my $istepN, my $substepN;
+ my $M, my $N, my $scommand;
+ my @ss_list;
+
+ ## check to see if we have an 's' command (string starts with 's' and a number)
+ chomp( $command);
+ if ( $command =~ m/^s+[0-9].*/ )
+ {
+ ## run "s" command
+ if ($opt_debug) { ::userDisplay "=== s command \"$command\" \n"; }
+ substr( $command, 0, 1, "" );
+
+ if ( POSIX::isdigit($command) )
+ {
+ # command = "sN"
+ if ($opt_debug) { ::userDisplay "=== single IStep: ", $command, "\n"; }
+ sCommand( $command );
+ }
+ else
+ {
+ # list of substeps = "sM..N"
+ ( $M, $N ) = split( /\.\./, $command );
+
+ if ($opt_debug) { ::userDisplay "=== multiple ISteps: ", $M, "-", $N, "\n"; }
+ for ( my $x=$M; $x<$N+1; $x++ )
+ {
+ sCommand( $x );
+ }
+ }
+ }
+ else
+ {
+ ## <substep name>, or <substep name>..<substep name>
+ @ss_list = split( /\.\./, $command );
+
+ if ($opt_debug) { ::userDisplay "=== named commands : ", @ss_list, "\n"; }
+
+ ( $istepM, $substepM, $foundit) = find_in_inList( $ss_list[0] );
+ $istepN = $istepM;
+ $substepN = $substepM;
+ if ( ! $foundit )
+ {
+ ::userDisplay "Invalid substep ", $ss_list[0], "\n" ;
+ return -1;
+ }
+
+
+ if ( $#ss_list > 0 )
+ {
+ ( $istepN, $substepN, $foundit) = find_in_inList( $ss_list[1] );
+ if ( ! $foundit )
+ {
+ ::userDisplay "Invalid substep $ss_list[1] \n" ;
+ return -1;
+ }
+ }
+
+
+ for( my $x=$istepM; $x<$istepN+1; $x++ )
+ {
+ for( my $y=$substepM; $y<$substepN+1; $y++ )
+ {
+ runIStep( $x, $y );
+ }
+ }
+
+ }
+}
+
+
+##
+## write to mem to set istep or normal mode, check return status
+##
+## Note that this only happens once at the beginning, when "splessmode"
+## or "fsplessmode" is run.
+##
+sub setMode( $ )
+{
+ my ( $cmd ) = @_;
+ my $count = 0;
+ my $expected = 0;
+ my $readybit = 0;
+ my $result = 0;
+
+ if ( $cmd eq "spless" )
+ {
+ writeIstepModeReg( SPLESS_MODE_SIGNATURE );
+ $expected = 1;
+ }
+ elsif ( $cmd eq "fsp" )
+ {
+ writeIstepModeReg( FSP_MODE_SIGNATURE );
+ $expected = 1;
+ }
+ else
+ {
+ ::userDisplay "invalid setMode command: $cmd\n" ;
+ return -1;
+ }
+
+ if ( $opt_debug )
+ {
+ ## readback and display
+ $result = readIstepModeReg( );
+ ::userDisplay "=== IstepModeReg readback: ", sprintf("0x%x", $result), "\n" ;
+ }
+
+
+ ## Loop, advancing clock, and wait for readybit
+ $count = $hbCount ;
+ while(1)
+ {
+ ## advance HostBoot code by a certain # of cycles, then check the
+ ## sequence number to see if it has changed. rinse and repeat.
+ ::executeInstrCycles( $hbDefaultCycles );
+
+ ## check to see if it's time to dump trace - no-op in simics
+ ::checkContTrace();
+
+ ## check for system crash
+ if ( isShutDown( ) )
+ {
+ ::userDisplay "Cannot run HostBoot\n";
+ return -1;
+ }
+
+ if ( isReadyBitOn() )
+ {
+ return 0;
+ }
+
+ if ( $count <= 0 )
+ {
+ ::userDisplay "TIMEOUT waiting for readybit, status=$result\n" ;
+ return -1;
+ }
+
+ $count--;
+ }
+}
+
+
+sub resume_istep()
+{
+ my $byte0;
+ my $command;
+ my $cmd;
+ my $result;
+
+ bumpSeqNum();
+
+ ::userDisplay "resume istep\n";
+
+ $byte0 = 0x80 + $g_SeqNum; ## gobit + seqnum
+ $command = SPLESS_RESUME_ISTEP_CMD;
+ $cmd = sprintf( "0x%2.2x%2.2x000000000000", $byte0, $command );
+ sendCommand( $cmd );
+
+ $result = getSyncStatus();
+
+ ## if result is -1 we have a timeout
+ if ( $result == -1 )
+ {
+ ::userDisplay "-----------------------------------------------------------------\n";
+ }
+ else
+ {
+ my $taskStatus = ( ( $result & 0x00ff000000000000 ) >> 48 );
+
+ ::userDisplay "-----------------------------------------------------------------\n";
+ if ( $taskStatus != 0 )
+ {
+ # This probably means istep was not at a breakpoint.
+ ::userDisplay "resume istep FAILED, task status is $taskStatus\n", $taskStatus ;
+ }
+ else
+ {
+ ::userDisplay "resume istep returned success\n" ;
+ }
+ ::userDisplay "-----------------------------------------------------------------\n";
+ }
+}
+
+sub clear_trace( )
+{
+ my $byte0, my $command;
+ my $cmd;
+ my $result;
+
+
+ ## bump the seqnum
+ bumpSeqNum();
+
+ $byte0 = 0x80 + $g_SeqNum; ## gobit + seqnum
+ $command = SPLESS_CLEAR_TRACE_CMD;
+ $cmd = sprintf( "0x%2.2x%2.2x%2.2x%2.2x00000000", $byte0, $command, 0, 0 );
+ sendCommand( $cmd );
+
+ $result = getSyncStatus();
+
+ ## if result is -1 we have a timeout
+ if ( $result == -1 )
+ {
+ ::userDisplay "-----------------------------------------------------------------\n";
+ }
+ else
+ {
+ my $taskStatus = ( ( $result & 0x00ff000000000000 ) >> 48 );
+ my $stsIStep = ( ( $result & 0x0000ff0000000000 ) >> 40 );
+ my $stsSubstep = ( ( $result & 0x000000ff00000000 ) >> 32 );
+ my $istepStatus = ( ( $result & 0x00000000ffffffff ) );
+
+ ::userDisplay "-----------------------------------------------------------------\n";
+ if ( $taskStatus != 0 )
+ {
+ ::userDisplay "Clear Trace FAILED, task status is taskStatus\n" ;
+ }
+ else
+ {
+ ::userDisplay "Clear Trace returned Status: $istepStatus\n" ;
+ }
+ ::userDisplay "-----------------------------------------------------------------\n";
+ }
+}
+
+
+__END__
+
diff --git a/src/build/debug/Hostboot/_DebugFramework.pm b/src/build/debug/Hostboot/_DebugFramework.pm
index ae8ef6573..6b7ee622a 100755
--- a/src/build/debug/Hostboot/_DebugFramework.pm
+++ b/src/build/debug/Hostboot/_DebugFramework.pm
@@ -6,7 +6,7 @@
#
# IBM CONFIDENTIAL
#
-# COPYRIGHT International Business Machines Corp. 2011
+# COPYRIGHT International Business Machines Corp. 2011 - 2012
#
# p1
#
@@ -20,8 +20,7 @@
#
# Origin: 30
#
-# IBM_PROLOG_END
-
+# IBM_PROLOG_END_TAG
# _DebugFramework.pm
#
# This module is a set of utility functions for the debug framework, which
@@ -49,7 +48,8 @@ our @EXPORT = ( 'callToolModule', 'callToolModuleHelp', 'callToolModuleHelpInfo'
'findModuleByAddress', 'listModules',
'littleendian',
'read64', 'read32', 'read16', 'read8', 'readStr',
- 'write64', 'write32', 'write16', 'write8'
+ 'write64', 'write32', 'write16', 'write8',
+ 'getIstepList'
);
our ($parsedSymbolFile, %symbolAddress, %symbolTOC,
@@ -586,4 +586,28 @@ sub write8
my $result = ::writeData($addr, 1, $value);
}
+# @sub getIstepList
+#
+# get an array of all the supported istep names from the
+# "isteplist.csv" file
+#
+# @return array of lines in the file
+#
+sub getIstepList
+{
+ my $isteplistFile = ::getImgPath();
+
+ $isteplistFile = $isteplistFile . "isteplist.csv";
+
+ open(FILE, "< $isteplistFile")
+ or die "Cannot open isteplist file $isteplistFile";
+
+ my @isteplist = <FILE>;
+
+ close FILE or die "cannot close isteplist file";
+
+
+ return @isteplist;
+}
+
__END__
OpenPOWER on IntegriCloud