summaryrefslogtreecommitdiffstats
path: root/src/build
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
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')
-rwxr-xr-xsrc/build/debug/Hostboot/Istep.pm1017
-rwxr-xr-xsrc/build/debug/Hostboot/_DebugFramework.pm32
-rwxr-xr-xsrc/build/debug/simics-debug-framework.pl130
-rwxr-xr-xsrc/build/debug/simics-debug-framework.py64
-rwxr-xr-xsrc/build/debug/vpo-debug-framework.pl207
-rwxr-xr-xsrc/build/simics/hb-simdebug.py570
6 files changed, 1443 insertions, 577 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__
diff --git a/src/build/debug/simics-debug-framework.pl b/src/build/debug/simics-debug-framework.pl
index 90a7822a9..6c23b1efd 100755
--- a/src/build/debug/simics-debug-framework.pl
+++ b/src/build/debug/simics-debug-framework.pl
@@ -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
# @file simics-debug-framework.pl
# @brief Implementation of the common debug framework for running in simics.
#
@@ -157,6 +156,131 @@ sub getIsTest
}
+# @sub getEnv
+#
+# Return the environment that we are running in, simics or vpo
+#
+sub getEnv
+{
+ return "simics";
+}
+
+#
+# @sub translateAddr
+# Do scom -> "phys_mem.read" address translation here.
+# The xscom address looks like this:
+# // Layout of XSCOM address parts
+# union
+# {
+# uint64_t mMmioAddress; // mMmio address
+# struct
+# {
+# uint64_t mReserved1:18; // Not currently used (0:17)
+# uint64_t mBaseAddress:5; // Base address (18:22)
+# uint64_t mNodeId:3; // Node where target resides (23:25)
+# uint64_t mChipId:3; // Targeted chip ID (26:28)
+# uint64_t mSComAddrHi:27; // PCB Address High (29:55)
+# uint64_t mCacheLine:1; // Cached line (56)
+# uint64_t mSComAddrLo:4; // PCB Address low (57:60)
+# uint64_t mAlign:3; // Align (61:63)
+# } mAddressParts;
+#
+# @param[in] - 64-bit scom address
+#
+# @return = address to send to python to do mm.read
+#
+# @note: "host_xscom_device_mm.read/write " doesn't seem to work with this
+# translated address, use "phys_mem.read/write " (in python) instead.
+#
+sub translateAddr
+{
+ my $addr = shift;
+ my $simicsaddr = 0;
+
+ my $mSComAddrHi = ( $addr >> 4 );
+ my $mSComAddrLo = ( $addr & 0x000000000000000f ) ;
+
+ $simicsaddr = ( 0x0000300000000000 ## Base addr
+ | (($mSComAddrHi & 0x0000000007ffffff) << 8 ) ## 27 bits, shift 8
+ | (($mSComAddrLo & 0x000000000000000f) << 3 ) ## 4 bits, shift 3
+ );
+
+ return $simicsaddr;
+}
+
+
+# @sub readScom
+# @brief Send a 'read-scom' type message to Python.
+#
+# @param[in] scom address to read
+# @param[in] data size IN BYTES
+#
+# @return hex string containing data read
+#
+# @todo: handle littleendian
+#
+sub readScom
+{
+ my $addr = shift;
+ my $size = shift;
+
+ my $simicsaddr = translateAddr( $addr);
+
+ ## debug
+ ## ::userDisplay "--- readScom: ", (sprintf("0x%x-->0x%x, 0x%x",$addr,$simicsaddr,$size)), "\n";
+
+ sendIPCMsg("read-scom", "$simicsaddr,$size");
+
+ my ($type, $data) = recvIPCMsg();
+
+ return $data;
+}
+
+# @sub writeScom
+# @brief Send a 'write-scom' type message to Python.
+#
+# @param[in] - xscom address
+# @param[in] - data size IN BYTES
+# @param[in] - binary data value. Scom value is aways assumed to be 64bits
+#
+# @return none
+#
+# @todo: handle littleendian
+#
+sub writeScom
+{
+ my $addr = shift;
+ my $size = shift;
+ my $value = shift;
+
+ my $simicsaddr = translateAddr( $addr);
+
+ ## debug
+ ## ::userDisplay "--- writeScom: ", (sprintf("0x%x-->0x%x, 0x%x, 0x%x",$addr,$simicsaddr,$size,$value)), "\n";
+
+ my $ipctype = "write-scom";
+ my $ipcdata = "$simicsaddr,$size,$value";
+
+
+ sendIPCMsg( $ipctype, $ipcdata );
+
+ ## $$ debug
+ ## $$my $debugstr = "[ \"$ipctype\", \"".unpack("H*",$ipcdata)."\" ]\n";
+ ## $$::userDisplay "--- $debugstr\n";
+
+ return;
+}
+
+
+##
+## Dummy module to match continuous trace call in VPO
+##
+sub checkContTrace()
+{
+
+}
+
+
# Get tool name.
sendIPCMsg("get-tool","");
my ($unused, $tool) = recvIPCMsg();
diff --git a/src/build/debug/simics-debug-framework.py b/src/build/debug/simics-debug-framework.py
index 39a186666..edf5f0bdd 100755
--- a/src/build/debug/simics-debug-framework.py
+++ b/src/build/debug/simics-debug-framework.py
@@ -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
# @file simics-debug-framework.py
# @brief Simics/Python implementation of the common debug framework.
#
@@ -72,9 +71,12 @@ class DebugFrameworkIPCMessage:
def loads(self,string):
pattern = re.compile("\[ \"([^\"]+)\", \"([0-9a-f]*)\" ]")
match = pattern.search(string)
-
- self.msgtype = match.group(1)
- self.msg = match.group(2).decode("hex")
+ if match is None:
+ print "error: empty message >%s< received from perl"%(string)
+ print " Check for print's in your perl script!!!"
+ else:
+ self.msgtype = match.group(1)
+ self.msg = match.group(2).decode("hex")
# @class DebugFrameworkProcess
# @brief Provides a wrapper to the 'subprocess' interface and IPC bridge.
@@ -188,6 +190,36 @@ class DebugFrameworkProcess:
def get_img_path(self,data):
self.sendMsg("data-response", self.imgPath)
+ # Read data from xscom address.
+ # This message has data of the format "0dADDRESS,0dSIZE".
+ def read_xscom(self,data):
+ pattern = re.compile("([0-9]+),([0-9]+)")
+ match = pattern.search(data)
+
+ addr = int(match.group(1))
+ size = int(match.group(2))
+
+ ## read the register using xscom reg addresses
+ runStr = "phys_mem.read 0x%x 0x%x"%(addr, size)
+ ( result, out ) = quiet_run_command( runStr, output_modes.regular )
+ ## DEBUG print ">> %s: "%(runStr) + "0x%16.16x"%(result) + " : " + out
+ self.sendMsg("data-response", "%16.16x"%(result) )
+
+
+ # Write data to xscom address..
+ # This message has data of the format "0dADDR,0dSIZE,hDATA".
+ def write_xscom(self,data):
+ pattern = re.compile("([0-9]+),([0-9]+),([0-9]+)")
+ match = pattern.search(data)
+
+ addr = int(match.group(1))
+ size = int(match.group(2))
+ data = int(match.group(3) )
+
+ runStr = "phys_mem.write 0x%x 0x%x 0x%x"%(addr, data, size)
+ ( result, out ) = quiet_run_command( runStr, output_modes.regular )
+ ## DEBUG print ">> %s : "%(runStr) + " 0x%16.16x"%(result) + " : " + out
+
# @fn run_hb_debug_framework
# @brief Wrapper function to execute a tool module.
#
@@ -213,6 +245,8 @@ def run_hb_debug_framework(tool = "Printk", toolOpts = "",
"get-tool" : DebugFrameworkProcess.get_tool,
"get-tool-options" : DebugFrameworkProcess.get_tool_options,
"get-img-path" : DebugFrameworkProcess.get_img_path,
+ "write-scom" : DebugFrameworkProcess.write_xscom,
+ "read-scom" : DebugFrameworkProcess.read_xscom,
"exit" : DebugFrameworkProcess.endProcess,
}
operations[msg[0]](fp,msg[1])
@@ -266,9 +300,9 @@ def register_hb_debug_framework_tools():
# Return a number/address built from the input list elements. Each element
-# in the input is a string representation of a byte-sized hex number, for
+# in the input is a string representation of a byte-sized hex number, for
# example '0x2b' or '0x0' or '0xa'. This does no endian conversion, thus
-# the input needs to be big endian. The length of the input list can be
+# the input needs to be big endian. The length of the input list can be
# any size, usually 2, 4, or 8.
def hexDumpToNumber(hexlist):
strNumber=""
@@ -284,7 +318,7 @@ def hexDumpToNumber(hexlist):
# Read simics memory and return a list of strings such as ['0x0','0x2b','0x8']
# representing the data read from simics. The list returned may be handed
-# to hexDumpToNumber() to turn the list into a number.
+# to hexDumpToNumber() to turn the list into a number.
def dumpSimicsMemory(address,bytecount):
hexlist = map(hex,conf.phys_mem.memory[[address,address+bytecount-1]])
return hexlist
@@ -325,7 +359,7 @@ def writeLongLong(address,n):
writeSimicsMemory(address,intToList(n,8))
-# MAGIC_INSTRUCTION hap handler
+# MAGIC_INSTRUCTION hap handler
# arg contains the integer parameter n passed to MAGIC_INSTRUCTION(n)
# See src/include/arch/ppc.H for the definitions of the magic args.
# Hostboot magic args should range 7000..7999.
@@ -333,15 +367,15 @@ def magic_instruction_callback(user_arg, cpu, arg):
if arg == 7006: # MAGIC_SHUTDOWN
# KernelMisc::shutdown()
print "KernelMisc::shutdown() called."
- # Could break/stop/pause the simics run, but presently
+ # Could break/stop/pause the simics run, but presently
# shutdown() is called four times. --Monte Jan 2012
# SIM_break_simulation( "Shutdown. Simulation stopped." )
if arg == 7007: # MAGIC_BREAK
- # Stop the simulation, much like a hard-coded breakpoint
+ # Stop the simulation, much like a hard-coded breakpoint
SIM_break_simulation( "Simulation stopped. (hap 7007)" )
- if arg == 7055: # MAGIC_CONTINUOUS_TRACE
+ if arg == 7055: # MAGIC_CONTINUOUS_TRACE
# Set execution environment flag to 0
writeLongLong(contTraceTrigInfo+32,0)
# Continuous trace.
@@ -370,10 +404,10 @@ def magic_instruction_callback(user_arg, cpu, arg):
# Run fsp-trace on tracBINARY file (implied), append output to tracMERG
os.system( "fsp-trace ./ -s hbotStringFile >>tracMERG 2>/dev/null" )
-# Continuous trace: Open the symbols and find the address for
+# Continuous trace: Open the symbols and find the address for
# "g_tracBinaryInfo" Convert to a number and save in tracBinaryInfoAddr
# The layout of g_tracBinaryInfo is a 64-bit pointer to the mixed buffer
-# followed by a 64-bit count of bytes used in the buffer. See
+# followed by a 64-bit count of bytes used in the buffer. See
# src/usr/trace/trace.C and mixed_trace_info_t.
for line in open('hbicore.syms'):
if "g_tracBinaryInfo" in line:
diff --git a/src/build/debug/vpo-debug-framework.pl b/src/build/debug/vpo-debug-framework.pl
index 057e847b1..12cee677c 100755
--- a/src/build/debug/vpo-debug-framework.pl
+++ b/src/build/debug/vpo-debug-framework.pl
@@ -20,7 +20,7 @@
#
# Origin: 30
#
-# IBM_PROLOG_END
+# IBM_PROLOG_END_TAG
# @file vpo-debug-framework.pl
# @brief Implementation of the common debug framework for running in vpo.
#
@@ -69,6 +69,7 @@ my %optionInfo = (
#--------------------------------------------------------------------------------
my $name = "vpo-debug-framework.pl";
my $self = ($0 =~ m/$name/); #flag showing whether script invoked using a different name; i.e symlink
+my $callmodule = $0;
my $tool = "";
my $testImage = 0;
my $outPath = "";
@@ -96,6 +97,7 @@ if (defined ($vbuToolDir))
}
my $imgPath = "";
+
my $hbDir = $ENV{'HB_IMGDIR'};
if (defined ($hbDir))
{
@@ -105,6 +107,16 @@ if (defined ($hbDir))
}
}
+## we need hbToolsDir for checkContTrace() (vpo only)
+my $pgmDir = `dirname $0`;
+chomp( $pgmDir );
+my $hbToolsDir = $ENV{'HB_TOOLS'};
+if ( ! defined( $hbToolsDir) || ( $hbToolsDir eq "" ) )
+{
+ $hbToolsDir = $pgmDir; ## Set to tool directory
+}
+
+
Getopt::Long::Configure ("bundling");
if ($self)
@@ -125,7 +137,7 @@ if ($self)
"s=i" => \&processEcmdOpts,
"p=i" => \&processEcmdOpts,
"c=i" => \&processEcmdOpts) || pod2usage(-verbose => 0);
-
+
pod2usage(-verbose => 1) if ($cfgHelp && $self);
pod2usage(-verbose => 2) if ($cfgMan && $self);
pod2usage(-verbose => 0) if (($tool eq "") && $self);
@@ -200,7 +212,7 @@ callToolModule($tool);
if (!$nosavestates)
{
restoreThreadStates();
-}
+}
if (!$mute)
{
@@ -270,7 +282,9 @@ sub flushL2
if (0 == $l2Flushed)
{
#stop instructions
- stopInstructions("all");
+ ## @todo problems with the model, just use thread 0 for now
+ ## $$ stopInstructions("all");
+ stopInstructions("0");
my $command = "$vbuToolDir/proc_l2_flush_wrap.x86 @ecmdOpt $flag";
die "ERROR: cannot flush L2" if (system("$command") != 0);
@@ -404,7 +418,7 @@ sub stopInstructions
if ($debug)
{
- print "$command\n";
+ print "--- stopInstructions: run $command\n";
}
die "ERROR: cannot stop instructions" if (system("$command") != 0);
@@ -420,7 +434,7 @@ sub startInstructions
if ($debug)
{
- print "$command\n";
+ print "--- startInstructions: run $command\n";
}
if (system("$command") != 0)
@@ -432,7 +446,7 @@ sub startInstructions
else
{
if ($debug)
- {
+ {
print "Cannot start instructions since Hostboot has shutdown";
}
}
@@ -449,6 +463,11 @@ sub queryThreadState
my $thread = shift;
my $command = "$vbuToolDir/proc_thread_control_wrap.x86 @ecmdOpt -query -t$thread";
+ if ($debug)
+ {
+ print STDERR "--- queryThreadState: run $command\n";
+ }
+
my $result = `$command`;
if ($debug)
@@ -539,12 +558,26 @@ sub executeInstrCycles
}
#start instructions
- startInstructions("all");
+ ## @todo problems with the model - use just thread 0 for now
+ ## $$ startInstructions("all");
+ startInstructions("0");
# run clock cycles
my $cycles = shift;
- $cycles = $cycles * 100; #increase cycles since VBU takes longer
+
+ ## for Istep.pm, the number of cycles should be approximately
+ ## the same between vpo and simics.
+ ## callFunc needs a multiplier of 100.
+ ## Add tweaks for any other module here.
+ if ( !($callmodule =~ m/Istep/) )
+ {
+ $cycles = $cycles * 100; #increase cycles since VBU takes longer
+ }
my $command = "simclock $cycles $flag";
+ if ($debug)
+ {
+ print "--- executeInstrCycles: run $command\n";
+ }
my $noshow = shift;
if (!$noshow)
{
@@ -697,6 +730,162 @@ sub displayToolModuleHelp
}
}
+
+# @sub getEnv
+#
+# Return the environment that we are running in, simics or vpo
+#
+sub getEnv
+{
+
+ return "vpo";
+}
+
+# @sub translateAddr
+#
+# @param[in] - 64-bit scom address
+#
+# @return = GET/STK FAC string to apply to VPO
+sub translateAddr
+{
+ my $addr = shift;
+
+ my $vpoaddr = "";
+
+ if ( $addr == 0x00050038 )
+ {
+ ## 50038 is mbox scratch 0 xscom addr
+ $vpoaddr = "GMB2E0";
+ }
+ elsif ( $addr == 0x00050039 )
+ {
+ ## 50039 is mbox scratch 1 xscom addr
+ $vpoaddr = "GMB2E4";
+ }
+ elsif ( $addr == 0x0005003a )
+ {
+ ## 5003a is mbox scratch 2 xscom addr
+ $vpoaddr = "GMB2E8";
+ }
+ elsif ( $addr == 0x0005003b )
+ {
+ ## 5003b is mbox scratch 3 xscom addr
+ $vpoaddr = "GMB2EC";
+ }
+ else
+ {
+ die "invalid mailbox reg: $addr\n";
+ }
+
+ return $vpoaddr;
+}
+
+
+# @sub readScom
+# @brief Read a scom address in VPO
+# Scom size is always 64-bit
+#
+# @param[in] scom address to read
+# @param[in] data size IN BYTES - currently ignored, assumed to be 8
+#
+# @return hex string containing data read
+#
+# @todo: handle littleendian
+#
+sub readScom
+{
+ my $addr = shift;
+ my $size = shift;
+
+ my $vpoaddr = ::translateAddr( $addr );
+
+ my $cmd = "simGETFAC " .
+ "B0.C0.S0.P0.E8.TPC.FSI.FSI_MAILBOX.FSXCOMP." .
+ "FSXLOG.LBUS_MAILBOX.Q_$vpoaddr.NLC.L2 32";
+
+ my $result = `$cmd`;
+
+ if ( $? ) { die "$cmd failed with $? : $!"; }
+
+ $result =~ s/.*\n0xr(.*)\n.*/$1/g;
+ $result =~ s/\n//g;
+
+ ## debug
+ ## ::userDisplay "--- readScom: ",
+ ## (sprintf("0x%x-->%s, 0x%x : %s", $addr,$vpoaddr,$size,$result)), "\n";
+
+ ## comes in as a 32-bit #, need to shift 32 to match simics
+ return ( "0x" . $result . "00000000" );
+}
+
+# @sub writeScom
+# @brief Write a scom address in VPO.
+#
+# @param[in] - scom address
+# @param[in] - data size IN BYTES - ignored, assumed to be 8
+# @param[in] - binary data value. Scom value is aways assumed to be 64bits
+#
+# @return none
+#
+# @todo: handle littleendian
+#
+sub writeScom
+{
+ my $addr = shift;
+ my $size = shift;
+ my $value = shift;
+
+ my $cmd = "";
+
+ my $vpoaddr = ::translateAddr( $addr );
+
+ ## vpo takes a 32 bit value in the lower 32 bits
+ my $value32 = ( ( $value >> 32 ) & 0x00000000ffffffff );
+ my $valuestr = sprintf( "0x%x", $value32 );
+
+ ## debug
+ ## ::userDisplay "--- writeScom: ",
+ ## (sprintf("0x%x-->%s, 0x%x, %s",$addr,$vpoaddr,$size,$valuestr)), "\n";
+
+ ## now go ahead and write the real value
+ $cmd = "simSTKFAC " .
+ "B0.C0.S0.P0.E8.TPC.FSI.FSI_MAILBOX.FSXCOMP." .
+ "FSXLOG.LBUS_MAILBOX.Q_$vpoaddr.NLC.L2 $valuestr 32 -quiet";
+
+ ( system( $cmd ) == 0 )
+ or die "$cmd failed, $? : $! \n";
+
+ return;
+}
+
+##
+## Special case: only used in VPO
+## Check the continuous trace Scom reg to see if we need to dump
+## trace.
+## This has to be executed as an external procedure so that it goes to the
+## proper output file.
+##
+sub checkContTrace()
+{
+ my $SCRATCH_MBOX0 = 0x00050038;
+ my $contTrace = "";
+
+ $contTrace = ::readScom( $SCRATCH_MBOX0, 8 );
+ if ( ( hex $contTrace ) != 0 )
+ {
+ ## activate continuous trace
+ system ("$hbToolsDir/hb-ContTrace --mute > /dev/null" );
+ system ("cat hb-ContTrace.output >> tracMERG");
+
+ ## ContTrace might leave instructions stopped, turn them
+ ## back on here to make sure.
+ ## @todo problems with the model, use just thread 0 for now
+ ::startInstructions("0");
+ }
+
+}
+
+
__END__
=head1 NAME
diff --git a/src/build/simics/hb-simdebug.py b/src/build/simics/hb-simdebug.py
index e0c9a0a38..9b779dd67 100755
--- a/src/build/simics/hb-simdebug.py
+++ b/src/build/simics/hb-simdebug.py
@@ -5,7 +5,7 @@
#
# IBM CONFIDENTIAL
#
-# COPYRIGHT International Business Machines Corp. 2011
+# COPYRIGHT International Business Machines Corp. 2011 - 2012
#
# p1
#
@@ -19,8 +19,7 @@
#
# Origin: 30
#
-# IBM_PROLOG_END
-
+# IBM_PROLOG_END_TAG
import os,sys
import conf
import configuration
@@ -54,524 +53,12 @@ def dumpL3():
return
-
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-# Functions to run isteps
-#------------------------------------------------------------------------------
-#------------------------------------------------------------------------------
-
-def findAddr( symsFile, symName ):
-
-
- #Find location of the variable from the image's .syms file
- for line in open(symsFile):
- if symName in line : #if found
- #print line
- x = line.split(",")
- addr = int(x[1],16)
- #print "addr = 0x%x"%(addr)
- size = int(x[3],16)
- #print "size = 0x%x"%(size)
- break
-
- #print line
- if symName not in line: #if not found
- print "\nCannot find %s in %s"%( symName,symsFile)
- return "0"
-
- ## returns an int
- return addr
-
-
-def hb_istep_usage():
- print "hb-istep usage:"
- ##print " istepmode - enable IStep Mode and the SPless user console."
- ##print " normalmode - enable IStep Mode and the FSP interface. "
- print " splessmode - enable IStep Mode and the SPless user console."
- print " fspmode - enable IStep Mode and the FSP interface. "
- print " list - list all named isteps"
- print " sN - execute IStep N"
- print " sN..M - execute IStep N through M"
- print " <name1>..<name2> - execute named isteps name1 through name2"
- print " debug - enable debugging messages"
- print " resume - Resume istep execution from break point"
- return None
-
-## declare GLOBAL g_SeqNum var, & a routine to manipulate it.
-## TODO: make this into a class, etc. to do it The Python Way.
-##g_SeqNum = 0
-g_SeqNum = random.randint(0, 63)
-print "g_SeqNum = %d"%(g_SeqNum)
-def bump_g_SeqNum() :
- global g_SeqNum
- g_SeqNum = ( (g_SeqNum +1) & 0x3f)
- return g_SeqNum
-
-## clock a certain amount of CPU cycles so the IStep will run (this will be
-## different for each simulation environment) and then return.
-## simics clock is a somewhat arbitrary value, may need to be adjusted.
-##
-## Handle following environments:
-## 1. [x] simics value = 100,000 (from Patrick)
-## 2. VPO value = ??? (don't know yet)
-## 3. hardware value = ??? ( ditto)
-##
-def runClocks() :
-
- SIM_continue( 250000 )
- return None
-
-##
-## send a command to the SPLess Command register (scratchpad reg 1)
-## cmd is passed in as a 64-bit ppc formatted hex string, i.e.
-## "0x80000000_00000000"
-##
-## Handle following environments:
-## 1. [x] simics
-## 2. VPO
-## 3. hardware
-def sendCommand( cmd ):
- global g_IStep_DEBUG
- ## CommandStr = "cpu0_0_0_1->scratch=%s"%(cmd)
- CommandStr = "phys_mem.write 0x%8.8x %s 8"%(g_SPLess_Command_Reg, cmd )
-
- ## send command to Hostboot
- if ( g_IStep_DEBUG ) :
- print CommandStr
- (result, out) = quiet_run_command(CommandStr, output_modes.regular )
-
- if ( g_IStep_DEBUG ) :
- print "sendCommand( \"%s\" ) returns : "%(cmd) + "0x%x"%(result) + " : " + out
-
- return result
-
-def printStsHdr( status ):
-
- runningbit = ( ( status & 0x8000000000000000 ) >> 63 )
- readybit = ( ( status & 0x4000000000000000 ) >> 62 )
- seqnum = ( ( status & 0x3f00000000000000 ) >> 56 )
- taskStatus = ( ( status & 0x00ff000000000000 ) >> 48 )
-
- print "runningbit = 0x%x, readybit=0x%x, seqnum=0x%x, taskStatus=0x%x"%(runningbit, readybit, seqnum, taskStatus )
- return None
-
-## get status from the SPLess Status Register (scratchpad reg 2)
-## returns a 64-bit int.
-##
-## Handle following environments:
-## 1. [x] simics
-## 2. VPO
-## 3. hardware
-##
-def getStatus():
- global g_IStep_DEBUG
-
- ## StatusStr = "cpu0_0_0_2->scratch"
- StatusStr = "phys_mem.read 0x%8.8x 8"%(g_SPLess_Status_Reg )
-
- ( result, out ) = quiet_run_command( StatusStr, output_modes.regular )
- if ( g_IStep_DEBUG ) :
- print ">> getStatus(): " + "0x%x"%(result) + " : " + out
- ## printStsHdr(result)
-
- return result
-
-
-## check for status, waiting for the readybit and the sent g_SeqNum.
-## default is to check the readybit, in rare cases we want to skip this.
-def getSyncStatus( ) :
- # set # of retries
- ## @todo revisit
- count = 1000
-
- ## 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 True :
-
- ## advance HostBoot code by a certain # of cycles, then check the
- ## running bit and sequence number to see if they have changed.
- ## IstepDisp will set running bit ASAP and then turn it off when
- ## the command is complete.
- runClocks()
-
- ## print a dot (with no carriage return) so that the user knows that
- ## it's still doing something
- # print "." ,
-
- result = getStatus()
-
- runningbit = ( ( result & 0x8000000000000000 ) >> 63 )
- seqnum = ( ( result & 0x3f00000000000000 ) >> 56 )
-
- if ( ( runningbit == 0 )
- and ( seqnum == g_SeqNum ) ) :
- # print # print a final carriage return
- return result
-
- if ( count <= 0 ):
- print # print a final carriage return
- print "TIMEOUT waiting for seqnum=%d"%( g_SeqNum )
- return -1
- count -= 1
-
-## write to istepmode reg to set istep or fsp mode, check return status
-def setMode( cmd ) :
- global g_IStep_DEBUG
- global g_SPLess_IStepMode_Reg
-
- ##IStepModeStr = "cpu0_0_0_3->scratch=0x4057b007_4057b007"
- ##NormalModeStr = "cpu0_0_0_3->scratch=0x700b7504_700b7504"
-
- SPlessModeStr = "phys_mem.write 0x%8.8x 0x4057b007_4057b007 8"%(g_SPLess_IStepMode_Reg)
- FSPModeStr = "phys_mem.write 0x%8.8x 0x700b7504_700b7504 8"%(g_SPLess_IStepMode_Reg)
-
- ## @todo revisit
- count = 1000
-
- if ( cmd == "spless" ) :
- (result, out) = quiet_run_command( SPlessModeStr )
- expected = 1
- elif ( cmd == "fsp" ) :
- (result, out) = quiet_run_command( FSPModeStr )
- expected = 1
- else :
- print "invalid setMode command: %s"%(cmd)
- return None
-
- print "setMode: %s :"%( cmd )
-
- ## Loop, advancing clock, and wait for readybit
- while True :
- runClocks()
-
- result = getStatus()
- readybit = ( ( result & 0x4000000000000000 ) >> 62 )
- if ( g_IStep_DEBUG ) :
- print "Setting %s mode, readybit=%d..."%( cmd, readybit )
- if ( readybit == expected ) :
- print "Set %s Mode success."%(cmd)
- return 0
-
- if ( count <= 0 ):
- print "TIMEOUT waiting for readybit, status=0x%x"%( result )
- return -1
- count -= 1
-
-
-## read in file with csv istep list and store in inList
-def get_istep_list( inList ):
- istep_file = open('./isteplist.csv')
- for line in istep_file.readlines():
- ( istep, substep, name) = line.split(',')
- i = int(istep)
- j = int(substep)
-
- ## print ":: %d %d %s"%(i, j, name)
- if ( name.strip() != "" ):
- inList[i][j] = name.strip()
-
- istep_file.close()
-
- return None
-
-
-def print_istep_list( inList ):
- hdrflag = 1
- print "IStep\tSubStep\tName"
- print "---------------------------------------------------"
- for i in range(0,len(inList)) :
- for j in range( 0, len(inList[i])) :
- # print "%d %d"%(i,j)
- if ( inList[i][j] != None ) :
- if ( hdrflag ) :
- print "-- %d"%(i)
- hdrflag = 0
- ## print "%d\t%d\t%s"%( i,j, inList[i][j] )
- print "%s"%( inList[i][j] )
-
- hdrflag = 1
-
-
- print " "
- return None
-
-
-def runIStep( istep, substep, inList ):
- global g_SeqNum
-
- bump_g_SeqNum()
-
- print "run %d.%d %s :"%( istep, substep, inList[istep][substep] )
- ## print " istep # = 0x%x / substep # = 0x%x :"%(istep, substep)
-
- byte0 = 0x80 + g_SeqNum ## gobit + seqnum
- command = 0x00
- cmd = "0x%2.2x%2.2x%2.2x%2.2x_00000000"%(byte0, command, istep, substep );
- sendCommand( cmd )
-
- result = getSyncStatus()
-
- ## getSyncStatus waits for seqNum in status to be what last cmd sent
-
- ## if result is -1 we have a timeout
- if ( result == -1 ) :
- print "-----------------------------------------------------------------"
- else :
- taskStatus = ( ( result & 0x00ff000000000000 ) >> 48 )
- stsIStep = ( ( result & 0x0000ff0000000000 ) >> 40 )
- stsSubstep = ( ( result & 0x000000ff00000000 ) >> 32 )
- istepStatus = ( ( result & 0x00000000ffffffff ) )
-
-
- print "-----------------------------------------------------------------"
-
- ## printStsHdr(result)
- ## print "Istep 0x%x / Substep 0x%x Status: 0x%x"%( stsIStep, stsSubstep, istepStatus )
- if ( taskStatus != 0 ) :
- # check for break point
- if ( taskStatus == 11 ) :
- print "At breakpoint 0x%x"%( istepStatus )
- else :
- print "Istep %d.%d FAILED to launch, task status is %d"%( stsIStep, stsSubstep, taskStatus )
- else:
- print "Istep %d.%d returned Status: 0x%x"%( stsIStep, stsSubstep, istepStatus )
- if ( istepStatus == 0xa ) :
- print " (not supported yet)"
- print "-------------------------------------------------------------- %d"%(g_SeqNum)
-
- return
-
-def resume_istep():
-
- bump_g_SeqNum()
-
- print "resume from breakpoint"
-
- byte0 = 0x80 + g_SeqNum ## gobit + seqnum
- command = 0x01
- cmd = "0x%2.2x%2.2x_000000000000"%(byte0, command)
- sendCommand( cmd )
-
- while True :
- result = getSyncStatus()
-
- ## if result is -1 we have a timeout
- if ( result == -1 ) :
- break;
- else :
- taskStatus = ( ( result & 0x00ff000000000000 ) >> 48 )
- stsIStep = ( ( result & 0x0000ff0000000000 ) >> 40 )
- stsSubstep = ( ( result & 0x000000ff00000000 ) >> 32 )
- istepStatus = ( ( result & 0x00000000ffffffff ) )
- running = ( ( result & 0x8000000000000000 ) >> 63 )
- readybit = ( ( result & 0x4000000000000000 ) >> 62 )
- print "-----------------------------------------------------------------"
-
- ## At this point the status is:
- ## 1) hostboot code was not at a breakpoint - resume ignored (result == 12)
- ## 2) hostboot resumed from breakpoint, but has not reached the end of
- ## the istep. (running flag on, result is 0)
- ## 3) hostboot resumed, but is at a new breakpoint
- ## 4) hostboot resumed and is at the end of the istep
- ## (running flag off, result is rc from istep
-
-
- if ( taskStatus != 0 ) :
- if (taskStatus == 11 ) :
- # at new breakpoint bail-out
- print " At breakpoint 0x%x."%( istepStatus )
- break
- elif ( taskStatus == 12 ) :
- print "resume Istep ignored. Not at breakpoint"
- break
- else :
- # all other errors must have come from the result of the istep
- print "Istep %d.%d returned Status: 0x%x"%( stsIStep, stsSubstep, istepStatus )
- break
- else:
- if(running == 0) :
- print "Istep %d.%d returned Status: 0x%x"%( stsIStep, stsSubstep, istepStatus )
- break
- elif (readybit == 0) :
- # not in istep mode - leave (mainly for unit testing)
- print "Istep resume was successful"
- break
-
- # still waiting for istep to complete
- # continue
- print "-----------------------------------------------------------------"
-
-
- return
-
-
-
-## run command = "sN"
-def sCommand( inList, scommand ) :
-
- i = int(scommand)
-
- # execute all the substeps in the IStep
- for j in range( 0, len(inList[i]) ) :
- ## print "-----------------"
- ## print "$$$$ run IStep %d %d ..."%(i, j)
- ##print "-----------------"
- if ( inList[i][j] != None ) :
- runIStep( i, j, inList )
- return
-
-
-def find_in_inList( inList, substepname) :
- for i in range(0,len(inList)) :
- for j in range( 0, len(inList[i])) :
- #print "%d %d"%(i,j)
- if ( inList[i][j] == substepname ) :
- #print "%s %d %d"%( inList[i][j], i, j )
- return (i,j, True )
- break;
-
- return ( len(inList), len(inList[i]), False )
-
-## ---------------------------------------------------------------------------
-## High Level Routine for ISteps.
-## ---------------------------------------------------------------------------
-## possible commands:
-## list
-## splessmode
-## fspmode
-## sN
-## sN..M
-## <substepname1>..<substepname2>
-## resume
-
-## declare GLOBAL g_IStep_DEBUG & SPLess memory mapped regs
-g_IStep_DEBUG = 0
-g_SPLess_IStepMode_Reg = ""
-g_SPLess_Command_Reg = ""
-g_SPLess_Status_Reg = ""
-def istepHB( symsFile, str_arg1 ):
- global g_IStep_DEBUG
- global g_SPLess_IStepMode_Reg
- global g_SPLess_Command_Reg
- global g_SPLess_Status_Reg
-
- ## find addresses of the memory-mapped SPLess regs in the image
- g_SPLess_IStepMode_Reg = findAddr( symsFile, "SPLESS::g_SPLess_IStepMode_Reg" )
- g_SPLess_Command_Reg = findAddr( symsFile, "SPLESS::g_SPLess_Command_Reg" )
- g_SPLess_Status_Reg = findAddr( symsFile, "SPLESS::g_SPLess_Status_Reg" )
-
- ## simics cannot be running when we start, or SIM_continue() will not work
- ## and the Status reg will not be updated.
- if ( SIM_simics_is_running() ) :
- print "simics must be halted before issuing an istep command."
- return;
-
- ## start with empty inList. Put some dummy isteps in istep4 for debug.
- n = 25 ## size of inlist array
-
- inList = [[None]*n for x in xrange(n)] ## init to nothing
-
- ## bump seqnum
- bump_g_SeqNum()
-
- ## print "run istepHB...."
-
- if ( str_arg1 == "debug" ) :
- print "enable istep debug - restart simics to reset"
- g_IStep_DEBUG = 1
- return
-
- if ( str_arg1 == "istepmode" ):
- # print "Set Istep Mode"
- print "istepmode no longer used - use splessmode, or fspmode"
- return
-
- if ( str_arg1 == "splessmode" ):
- # print "Start Istep on SPless console"
- setMode( "spless" )
- return
-
- if ( str_arg1 == "fspmode" ):
- # print "Start Istep on FSP "
- setMode( "fsp" )
- return
-
- ## get readybit to see if we are running in IStep Mode.
- StatusReg = getStatus()
- readybit = ( ( StatusReg & 0x4000000000000000 ) >> 62 )
- if ( not readybit ):
- print "ERROR: HostBoot Status reg is 0x%16.16x"%( StatusReg )
- print " Ready bit is not on, did you remember to run hb-istep spless ??"
- print " "
- hb_istep_usage()
- return None
-
- if ( str_arg1 == "resume" ): ## resume from break point
- resume_istep()
- return None
-
- ## get the list of isteps from HostBoot...
- # print"get istep list"
- get_istep_list( inList )
-
- if ( str_arg1 == "list" ): ## dump command list
- print_istep_list( inList )
- return
-
-
- ## check to see if we have an 's' command (string starts with 's' and a number)
- if ( re.match("^s+[0-9].*", str_arg1 ) ):
- ## run "s" command
- # print "s command"
- scommand = str_arg1.lstrip('s')
-
- if scommand.isdigit():
- # command = "sN"
- # print "single IStep: " + scommand
- sCommand( inList, scommand )
- else:
- # list of substeps = "sM..N"
- (M, N) = scommand.split('..')
- # print "multiple ISteps: " + M + "-" + N
- for x in range( (int(M,16)), (int(N,16)+1) ) :
- sCommand( inList, x )
- return
- else:
- ## substep name .. substep name
- ## print "named istep(s) : " + str_arg1
- ## (ss_nameM, ss_nameN) = str_arg1.split("..")
- ss_list = str_arg1.split("..")
-
- (istepM, substepM, foundit) = find_in_inList( inList, ss_list[0] )
- istepN = istepM
- substepN = substepM
- if ( not foundit ) :
- print( "Invalid substep %s"%(ss_list[0] ) )
- return
-
- if ( len(ss_list) > 1 ) :
- (istepN, substepN, foundit) = find_in_inList( inList, ss_list[1] )
- if ( not foundit ) :
- print( "Invalid substep %s"%(ss_list[1] ) )
- return
-
- ## @todo - this does not work correctly across istep boundaries
- for x in range( istepM, istepN+1 ) :
- for y in range( substepM, substepN+1 ) :
- if ( inList[x][y] != None ) :
- runIStep( x, y, inList )
- return
-
-
#===============================================================================
# HOSTBOOT Commands
#===============================================================================
default_syms = "hbicore.syms"
default_stringFile = "hbotStringFile"
-
#------------------------------------------------
#------------------------------------------------
new_command("hb-trace",
@@ -641,44 +128,35 @@ Examples: \n
hb-dump \n
""")
+
#------------------------------------------------
-# implement isteps
+# Disable for now, need to pass in lots of options
#------------------------------------------------
-def hb_istep(str_arg1):
-
- syms = default_syms
-
- if ( str_arg1 == None):
- hb_istep_usage()
- else:
- ## print "args=%s" % str(str_arg1)
- istepHB( syms, str_arg1 )
-
- return None
-
new_command("hb-istep",
- hb_istep,
- [ arg(str_t, "syms", "?", None),
- # arg(flag_t,"-s", "?", None),
- ],
- type = ["hostboot-commands"],
- see_also = [ ],
- short = "Run IStep commands using the SPLess HostBoot interface",
- doc = """
+ lambda istep: run_hb_debug_framework("Istep", istep,
+ outputFile = "hb-istep.output"),
+ [ arg( str_t, "istep", "?", "") ],
+ type = ["hostboot-commands"],
+ see_also = [ ],
+ short = "Run IStep commands",
+ doc = """
Parameters: \n
-
+
Defaults: \n
Examples: \n
- hb-istep \n
- hb-istep -s4 \n
- hb-istep -s4..N
- hb-istep -4.1
- hb-istep -4.1..4.3 \n
- hb-istep poweron \n
- hb-istep poweron..clock_frequency_set /n
- """)
-
+ hb-istep \n
+ hb-istep list \n
+ hb-istep splessmode \n
+ hb-istep fspmode \n
+ hb-istep clear-trace \n
+ hb-istep resume \n
+ hb-istep s4 \n
+ hb-istep s4..N
+ hb-istep poweron \n
+ hb-istep poweron..clock_frequency_set /n
+ """)
+
#------------------------------------------------
#------------------------------------------------
new_command("hb-errl",
OpenPOWER on IntegriCloud