summaryrefslogtreecommitdiffstats
path: root/src/build
diff options
context:
space:
mode:
Diffstat (limited to 'src/build')
-rwxr-xr-xsrc/build/simics/hb-simdebug.py81
-rwxr-xr-xsrc/build/tools/cpfiles.pl27
-rwxr-xr-xsrc/build/vpo/VBU_Cacheline.pm474
-rwxr-xr-xsrc/build/vpo/hb-istep565
-rwxr-xr-xsrc/build/vpo/hb-virtdebug.pl2
5 files changed, 1131 insertions, 18 deletions
diff --git a/src/build/simics/hb-simdebug.py b/src/build/simics/hb-simdebug.py
index 0f5774a2e..4e5dbb2ee 100755
--- a/src/build/simics/hb-simdebug.py
+++ b/src/build/simics/hb-simdebug.py
@@ -59,6 +59,30 @@ def dumpL3():
# 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. Must be executed before simics run command"
@@ -89,7 +113,7 @@ def bump_g_SeqNum() :
##
def runClocks() :
- SIM_continue( 100000 )
+ SIM_continue( 250000 )
return None
##
@@ -103,14 +127,16 @@ def runClocks() :
## 3. hardware
def sendCommand( cmd ):
global g_IStep_DEBUG
- CommandStr = "cpu0_0_0_1->scratch=%s"%(cmd)
+ ## 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
- ## print CommandStr
+ if ( g_IStep_DEBUG ) :
+ print CommandStr
(result, out) = quiet_run_command(CommandStr, output_modes.regular )
if ( g_IStep_DEBUG ) :
- print "sendCommand( 0x%x ) returns : " + "0x%x"%(cmd, result) + " : " + out
+ print "sendCommand( \"%s\" ) returns : "%(cmd) + "0x%x"%(result) + " : " + out
return result
@@ -134,7 +160,9 @@ def printStsHdr( status ):
##
def getStatus():
global g_IStep_DEBUG
- StatusStr = "cpu0_0_0_2->scratch"
+
+ ## 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 ) :
@@ -177,14 +205,20 @@ def getSyncStatus( ) :
## write to scratch reg 3 to set istep or normal mode, check return status
def setMode( cmd ) :
- IStepModeStr = "cpu0_0_0_3->scratch=0x4057b007_4057b007"
- NormalModeStr = "cpu0_0_0_3->scratch=0x700b7504_700b7504"
+ 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"
+ IStepModeStr = "phys_mem.write 0x%8.8x 0x4057b007_4057b007 8"%(g_SPLess_IStepMode_Reg)
+ NormalModeStr = "phys_mem.write 0x%8.8x 0x700b7504_700b7504 8"%(g_SPLess_IStepMode_Reg)
- count = 10
+ count = 50
if ( cmd == "istep" ) :
(result, out) = quiet_run_command( IStepModeStr )
+ # print IStepModeStr
# print "set istepmode returned 0x%x"%(result) + " : " + out
expected = 1
elif ( cmd == "normal" ) :
@@ -201,7 +235,8 @@ def setMode( cmd ) :
result = getStatus()
readybit = ( ( result & 0x4000000000000000 ) >> 62 )
- print "Setting %s mode, readybit=%d..."%( cmd, readybit )
+ if ( g_IStep_DEBUG ) :
+ print "Setting %s mode, readybit=%d..."%( cmd, readybit )
if ( readybit == expected ) :
print "Set %s Mode success."%(cmd)
return 0
@@ -229,7 +264,6 @@ def get_istep_list( inList ):
return None
-
def print_istep_list( inList ):
print "IStep\tSubStep\tName"
print "---------------------------------------------------"
@@ -322,17 +356,28 @@ def find_in_inList( inList, substepname) :
## sN..M
## <substepname1>..<substepname2>
-## declare GLOBAL g_IStep_DEBUG
+## declare GLOBAL g_IStep_DEBUG & SPLess memory mapped regs
g_IStep_DEBUG = 0
-def istepHB( str_arg1 ):
-
+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;
-
-
+ return;
+
## start with empty inList. Put some dummy isteps in istep4 for debug.
n = 10 ## size of inlist array
inList = [[None]*n for x in xrange(n)] ## init to nothing
@@ -503,12 +548,14 @@ Examples: \n
# implement isteps
#------------------------------------------------
def hb_istep(str_arg1):
+
+ syms = default_syms
if ( str_arg1 == None):
hb_istep_usage()
else:
## print "args=%s" % str(str_arg1)
- istepHB( str_arg1 )
+ istepHB( syms, str_arg1 )
return None
diff --git a/src/build/tools/cpfiles.pl b/src/build/tools/cpfiles.pl
index 3c71b55fa..520c6a1c1 100755
--- a/src/build/tools/cpfiles.pl
+++ b/src/build/tools/cpfiles.pl
@@ -79,6 +79,16 @@ my @files = ("src/build/tools/hb-parsedump.pl",
"img/vbu_targeting.bin",
"img/isteplist.csv",
);
+
+# copy vpo files into working dir for AWAN
+my @vpofiles = ("src/build/vpo/hb-dump",
+ "src/build/vpo/hb-errl",
+ "src/build/vpo/hb-istep",
+ "src/build/vpo/hb-printk",
+ "src/build/vpo/hb-trace",
+ "src/build/vpo/hb-virtdebug.pl",
+ "src/build/vpo/VBU_Cacheline.pm",
+ );
#Directories in base git repository
my @gitRepoDirs = ("img",
@@ -98,8 +108,9 @@ my $numArgs = $#ARGV + 1;
my $test = 0; #Flag to overwrite hbicore.<syms|bin|list> with the test versions
my $inDir = ""; #User specified directory to copy files to
+my $vpo = 0; # copy extra vpo files to inDir
-if ($numArgs > 2)
+if ($numArgs > 3)
{
#Print command line help
print ("ERROR: Too many arguments entered.\n");
@@ -121,6 +132,11 @@ else
#Set flag to copy hbicore_test.<syms|bin> to hbcore_test.<syms|bin>
$test = 1;
}
+ elsif ($_ eq "--vpo")
+ {
+ #Set flag to copy list of vpo files to $inDir
+ $vpo = 1;
+ }
else
{
#Save user specified directory
@@ -187,6 +203,14 @@ else
}
#------------------------------------------------------------------------------
+# If vpo flag is set, add the vpo files to the @files array
+#------------------------------------------------------------------------------
+if ( $vpo )
+{
+ push( @files, @vpofiles );
+}
+
+#------------------------------------------------------------------------------
# Get the base dir of the git repository
#------------------------------------------------------------------------------
my $cwd = getcwd();
@@ -322,5 +346,6 @@ sub printUsage()
print (" if it is defined.\n\n");
print (" --help: prints usage information\n");
print (" --test: Copy hbicore_test.<syms|bin|list> to hbicore.<syms|bin|list>\n");
+ print (" --vpo: Copy files in src/build/vpo to support vpo operation\n");
}
diff --git a/src/build/vpo/VBU_Cacheline.pm b/src/build/vpo/VBU_Cacheline.pm
new file mode 100755
index 000000000..23a1d30da
--- /dev/null
+++ b/src/build/vpo/VBU_Cacheline.pm
@@ -0,0 +1,474 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/build/vpo/VBU_Cacheline.pm $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2011 - 2012
+#
+# p1
+#
+# Object Code Only (OCO) source materials
+# Licensed Internal Code Source Materials
+# IBM HostBoot Licensed Internal Code
+#
+# The source code for this program is not published or other-
+# wise divested of its trade secrets, irrespective of what has
+# been deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END
+#
+# Name: hb-modify-cacheline.pm
+#
+# Purpose: routines for reading and writing a 64-bit value into L3 in an
+# AWAN session. Accepts an address into L3, and 64-bit data hex word
+# (write).
+# VBU can only read/write to memory in 128-byte cachelines, so if
+# we want to write a memory location we must read in the entire
+# cacheline, modify the correct byte(s) and then write it back.
+# Called from shell script do_p8vbu_script_hbi*
+# Written in perl because that is what is being used for the debug
+# framework
+#
+# Author: Mark Wenning
+#
+
+package VBU_Cacheline;
+require Exporter;
+
+our @ISA = qw( Exporter );
+our @EXPORT = qw( CLread CLwrite RunClocks P8_Ins_Start P8_Ins_Stop P8_Ins_Query SetFlags);
+
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use strict;
+use warnings;
+use POSIX;
+use Fcntl;
+
+## 64-bit input
+use bigint;
+no warnings 'portable';
+
+#------------------------------------------------------------------------------
+# Forward declarations
+#------------------------------------------------------------------------------
+sub CLread;
+sub CLwrite;
+sub RunClocks;
+sub P8_Ins_Start;
+sub P8_Ins_Stop;
+sub P8_Ins_Query;
+sub P8_Flush_L2;
+sub SetFlags;
+
+
+############################################
+## constants
+## use constant MAX_NUM_TRACE_BUFFERS => 24;
+############################################
+my $CLfile = "./istepmodereg.dma";
+my $CORE = "-c3";
+my $SIM_CLOCKS = "4000000";
+
+## later...
+my $vbuToolsDir = "/gsa/ausgsa/projects/h/hostboot/vbutools";
+
+
+my $DUMPCMD = "/afs/awd/projects/eclipz/lab/p8/gsiexe/p8_dump_l3";
+my $LOADCMD = "/afs/awd/projects/eclipz/lab/p8/gsiexe/p8_load_l3";
+## my $FLUSHCMD = "/afs/awd/projects/eclipz/lab/p8/gsiexe/p8_l2_flush.x86 $CORE";
+my $FLUSHCMD = "/afs/awd/projects/eclipz/lab/p8/compiled_procs/procs/p8_l2_flush_wrap.x86 $CORE -quiet";
+my $FLUSHQUERY = "/afs/awd.austin.ibm.com/projects/eclipz/lab/p8/gsiexe/p8_check_l3";
+my $RUNCLKSCMD = "simclock";
+
+my $QUERYCMD = "/gsa/pokgsa/home/m/c/mcguirej/public/auto/rel/P8bin/p8_ins_query";
+my $STOPCMD = "/gsa/pokgsa/home/m/c/mcguirej/public/auto/rel/P8bin/p8_ins_stop";
+my $STARTCMD = "/gsa/pokgsa/home/m/c/mcguirej/public/auto/rel/P8bin/p8_ins_start";
+## ## later...
+## ## my $QUERYCMD = "/afs/awd/projects/eclipz/lab/p8/u/karm/ekb/eclipz/chips/p8/working/procedures/utils/p8_thread_control.x86 -query";
+## ## my $STOPCMD = "/afs/awd/projects/eclipz/lab/p8/u/karm/ekb/eclipz/chips/p8/working/procedures/utils/p8_thread_control.x86 -stop";
+## ## my $STARTCMD = "/afs/awd/projects/eclipz/lab/p8/u/karm/ekb/eclipz/chips/p8/working/procedures/utils/p8_thread_control.x86 -start";
+
+#############################################
+## Internal Globals
+#############################################
+my $CLdebug = 0;
+my $CLtest = 0;
+
+## flushed Flag, if 0, it means the L2 cache has not been flushed.
+## It must be flushed once before doing L3 reads
+my $L2_Flushed = 0;
+
+
+##
+#==============================================================================
+# SUBROUTINES
+#==============================================================================
+
+
+##
+## Read the cacheline at addr from L3 and dump it to a binary file.
+## Assumes that the input address is a binary addr on a 128 byte boundary
+##
+sub readcacheline( $ )
+{
+ my ( $addr ) = @_;
+ my $cmd;
+ ## my $hexaddr = sprintf( "0x%x", $addr );
+ my $hexaddr = sprintf( "%x", $addr );
+
+ if ( $CLdebug ) { print STDOUT "-- Read cacheline at $hexaddr...\n"; }
+
+ ## Stop simulation so we can read L3 properly
+ P8_Ins_Stop();
+
+ ## flush L2 if necessary
+ P8_Flush_L2();
+
+ $cmd = "$DUMPCMD $hexaddr 1 -f $CLfile -b $CORE";
+ if ( $CLdebug ) { print STDOUT "-- run $cmd ...\n"; }
+ ( system( $cmd ) == 0 )
+ or die "$cmd failed $? : $! \n";
+
+ ## Start simulation back up.
+ ## P8_Ins_Start();
+
+}
+
+
+##
+## derived from Perl Cookbook, 8.13
+## pack/unpack format is unsigned big endian 32-bit hi, lo
+## however, the input data from getopts still assumes that perl is compiled
+## for 64-bit #s
+##
+sub modifycacheline( $$ )
+{
+ my ( $offset, $data ) = @_;
+
+ my $typedef = 'N N'; # 2 32-bit network order
+ my $sizeof = length( pack($typedef,() ) );
+ my $filesize = -s $CLfile;
+ my $buffer;
+
+ open( FH, "+< $CLfile") or die "can't open $CLfile : $!";
+ binmode FH; ## not really necessary, but....
+ seek( FH, $offset, SEEK_SET) or die "seek $CLfile failed: $!";
+ read( FH, $buffer, $sizeof) == $sizeof or die "read failed: $!";
+
+ ( my $hi, my $lo ) = unpack($typedef, $buffer);
+
+ $hi = ($data >> 32) ;
+ $lo = ($data & 0x00000000ffffffff);
+
+ $buffer = pack($typedef, $hi, $lo );
+
+ # back up one record
+ seek( FH, -$sizeof, SEEK_CUR) or die "seek $CLfile failed: $!";
+
+ print FH $buffer;
+
+ close( FH ) or die "close $CLfile failed: $!";
+}
+
+##
+## Write modified file back to L3 cacheline.
+## This assumes that addr has already been converted to binary addr on a
+## 128 byte boundary
+##
+sub writecacheline( $ )
+{
+ my ( $addr ) = @_;
+ my $cmd;
+ ## my $hexaddr = sprintf( "0x%x", $addr );
+ my $hexaddr = sprintf( "%x", $addr );
+
+ ## Stop simulation so we can write L3
+ P8_Ins_Stop();
+
+ $cmd = "$LOADCMD -o $hexaddr -f $CLfile -b $CORE";
+ if ( $CLdebug ) { print STDOUT "-- run $cmd ...\n"; }
+ ( system( $cmd ) == 0 )
+ or die "$cmd failed, $? : $! \n";
+
+ ## Start sim back up
+ ## P8_Ins_Start();
+
+}
+
+
+##
+## Query the state of the simulator, "RUNNING" or "STOPPED".
+##
+sub P8_Ins_Query()
+{
+ my $cmd = "$QUERYCMD";
+ my $retstr = "";
+
+ if ( $CLdebug ) { print STDOUT "-- run $cmd ...\n"; }
+
+ ## execute it with backticks so we can get the output.
+ $retstr = `$cmd`;
+ if ( $? != 0 ) { die "$cmd failed $? : $! \n"; }
+
+ chomp( $retstr );
+
+ if ( $CLdebug ) { print STDOUT "-- P8_Ins_Query returned $retstr\n"; }
+
+ if ( ($retstr ne "STOPPED" )
+ && ($retstr ne "RUNNING" )
+ )
+ {
+ die "invalid string \"$retstr\" from P8_Ins_Query\n";
+ }
+
+ return $retstr;
+}
+
+
+##
+## Stop the simulation. Necessary to read and write L3 .
+##
+sub P8_Ins_Start()
+{
+ my $cmd = "$STARTCMD";
+
+ if ( P8_Ins_Query() eq "STOPPED" )
+ {
+ if ( $CLdebug ) { print STDOUT "-- run $cmd ...\n"; }
+
+ ( system( $cmd ) == 0 )
+ or die "$cmd failed $? : $! \n";
+
+
+ ## reset the flushFlag, need to flush again before a read.
+ $L2_Flushed = 0;
+ }
+ else
+ {
+ if ($CLdebug) { print STDOUT "-- P8_Ins_Start: already RUNNING\n"; }
+ }
+
+}
+
+
+##
+## Stop the simulation.
+##
+sub P8_Ins_Stop()
+{
+ my $cmd = "$STOPCMD";
+
+ if ( P8_Ins_Query() eq "RUNNING" )
+ {
+ if ( $CLdebug ) { print STDOUT "-- run $cmd ...\n"; }
+ ( system( $cmd ) == 0 )
+ or die "$cmd failed $? : $! \n";
+
+ }
+ else
+ {
+ if ($CLdebug) { print STDOUT "-- P8_Ins_Stop: already STOPPED\n"; }
+ }
+
+}
+
+##
+## Check if cache is flushed.
+## $TODO
+## p8_check_L3 will scan the L3 directory for unfilled cachelines and
+## return a string:
+## $ p8_check_l3 100 4 -c3 -f $labhome/foo -x -o
+## p8_check_l3 - address (0x100) not found in L3 directory.
+##
+## $ p8_check_l3 100 4 -c3 -f $labhome/foo -x -o
+## p8_check_l3 - all addresses found in L3 directory.
+##
+sub P8_Check_Flushed
+{
+ my ( $addr, $lines ) = @_;
+ my $tmpfile = "./tmpflush";
+ my $cmd = "$FLUSHQUERY";
+ my $rc = 0;
+
+ ## execute it with backticks so we can get the output.
+ my $retstr = `$cmd $CORE -f $tmpfile -x -o`;
+ if ( $? != 0 ) { die "$cmd failed $? : $! \n"; }
+
+ chomp( $retstr );
+
+ if ( $retstr =~ /^.*.all addresses.*/ )
+ {
+ $rc = 1;
+ }
+
+ return $rc;
+}
+
+##
+## Flush L2 Cache
+## This only needs to be done once after the clock is stopped,
+## thus the toggle flag
+##
+sub P8_Flush_L2()
+{
+ my $cmd = "$FLUSHCMD";
+
+ if ( !$L2_Flushed )
+ {
+ if ( $CLdebug ) { print STDOUT "-- run $cmd ...\n"; }
+ ( system( $cmd ) == 0 )
+ or die "$cmd failed $? : $! \n";
+
+ ## mark the CPU as flushed.
+ $L2_Flushed = 1;
+ }
+
+ if ($CLdebug) { print STDOUT "-- P8_FLush_L2 : $L2_Flushed\n"; }
+}
+
+
+##
+## tell the simulator to run for so many clock cycles.
+## If simulator is stopped, then start it up first.
+##
+sub RunClocks()
+{
+ my $cmd = 0;
+
+ if ( $CLdebug ) { printf STDOUT "-- RunClocks()\n"; }
+
+ ## Check, and start instructions if necessary
+ if ( P8_Ins_Query( ) ne "RUNNING" )
+ {
+
+ P8_Ins_Start();
+ }
+
+ $cmd = "$RUNCLKSCMD $SIM_CLOCKS -quiet";
+ if ( $CLdebug ) { print STDOUT "-- run $cmd ...\n"; }
+ ( system( $cmd ) == 0 )
+ or die "$cmd failed, $? : $! \n";
+
+}
+
+
+##
+## Read a 64-bit value from L3 at hex addr.
+## Input is expected to be a hex ascii string
+##
+sub CLread( $ )
+{
+ my ( $addr ) = @_;
+ my $cmd;
+ my $CLbase = ( hex($addr) & 0xffffff80);
+ my $CLoffset = ( hex($addr) & (~0xffffff80) );
+ my $result = 0; ## 64-bit hex
+
+ if ( $CLdebug ) { printf STDOUT "-- CLread( %s ) : CLbase=0x%x, CLoffset=0x%x\n", $addr, $CLbase, $CLoffset }
+
+ readcacheline( $CLbase );
+
+ ## extract quadword from cacheline file
+ my $typedef = 'N N'; # QuadWord
+ my $sizeof = length( pack($typedef,() ) );
+ my $filesize = -s $CLfile;
+ my $buffer;
+ open( FH, "+< $CLfile") or die "can't open $CLfile : $!";
+ binmode FH; ## not really necessary, but....
+ seek( FH, $CLoffset, SEEK_SET) or die "seek $CLfile failed: $!";
+ read( FH, $buffer, $sizeof) == $sizeof or die "read failed: $!";
+ close( FH ) or die "close $CLfile failed: $!";
+
+ ## unpack and reassemble as big-endian
+ ( my $hi, my $lo ) = unpack($typedef, $buffer);
+ $result = ( ( ( $hi << 32 ) & 0xffffffff00000000 ) | $lo );
+
+ if ( $CLdebug )
+ {
+ printf STDOUT "-- CLread( %s ) = 0x%lx ", $addr, $result;
+ dumpcacheline(" " );
+ }
+
+ return ( $result );
+}
+
+##
+## Write command byte to cacheline
+## Inputs are expected to be hex ascii strings
+##
+sub CLwrite( $$ )
+{
+ my ( $addr, $data ) = @_;
+ my $CLbase = ( hex($addr) & 0xffffff80 );
+ my $CLoffset = ( hex($addr) & (~0xffffff80) );
+ my $CLdata = hex($data);
+ my $result = 0;
+
+ if ( $CLdebug ) { printf STDOUT "-- CLwrite( %s, %s ) : CLbase=0x%x, CLoffset=0x%x, CLdata=0x%lx\n",
+ $addr, $data, $CLbase, $CLoffset, $CLdata; }
+
+ ## clear the cacheline file
+ system( "rm -f $CLfile" );
+
+ ## issue the command to dump the cacheline to a file
+ readcacheline( $CLbase );
+
+ ## dumpcacheline( "after read", $CLfile );
+
+ ## modify the cacheline file
+ modifycacheline( $CLoffset, $data );
+
+ ## dumpcacheline( "after modify", $CLfile );
+
+ ## write the cacheline back to L3
+ writecacheline( $CLbase );
+
+ if ( $CLdebug )
+ {
+ ## check, clear the cacheline file and read again
+ system( "rm -f $CLfile" );
+ readcacheline( $CLbase );
+ dumpcacheline( "Readback", $CLfile );
+ }
+
+}
+
+
+sub dumpcacheline()
+{
+ my ( $comment ) = @_;
+
+ if ( $CLdebug )
+ {
+ print STDOUT "-- $comment, dump cache file :\n";
+ system( "xxd $CLfile" );
+ }
+
+}
+
+sub SetFlags( $$ )
+{
+ my ( $debug, $test ) = @_;
+
+ $CLdebug = $debug;
+ $CLtest = $test;
+
+ if ( $CLdebug )
+ {
+ print STDOUT "-- CLdebug=$CLdebug, CLtest=$CLtest\n";
+ }
+}
+
+
+## required at the end of perl modules
+1;
+
+__END__
diff --git a/src/build/vpo/hb-istep b/src/build/vpo/hb-istep
new file mode 100755
index 000000000..2cae8e617
--- /dev/null
+++ b/src/build/vpo/hb-istep
@@ -0,0 +1,565 @@
+#!/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
+#
+# 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
+#
+# Purpose: This perl script works in concert with do_p8vbu_script_hbi_* to
+# implement isteps on AWAN.
+#
+# Description:
+# The do.. 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.
+# 2) hb_istep --command
+# Periodically call RunClocks() to step through HostBoot.
+# Checks for status from previous Isteps, and reports status.
+#
+# Comments:
+#
+#
+# Author: Mark Wenning
+#
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use strict;
+use warnings;
+use POSIX;
+use Getopt::Long;
+
+## 64-bit input
+## argh, not compatable with GetOpt!! use bigint;
+no warnings 'portable';
+
+# read/write cachelines to L3
+use VBU_Cacheline;
+
+#------------------------------------------------------------------------------
+# Forward Declaration
+#------------------------------------------------------------------------------
+sub printUsage;
+sub get_istep_list;
+sub print_istep_list;
+sub find_in_inlist;
+sub parse_command;
+sub setMode;
+
+#------------------------------------------------------------------------------
+# Constants
+#------------------------------------------------------------------------------
+my $CSVfile = "isteplist.csv";
+my $hbSymsFile = "hbicore.syms"; #Use hbicore.syms
+my $CORE = "-c3";
+
+
+#------------------------------------------------------------------------------
+# Globals
+#------------------------------------------------------------------------------
+my $opt_debug = 0;
+my $opt_istepmode = 0;
+my $opt_normalmode = 0;
+my $opt_command = "";
+my $opt_list = 0;
+my $opt_help = 0;
+my $opt_cmdfile = 0; ## batchmode, later
+
+my @inList;
+$inList[10][10] = ();
+## initialize inList to "undefined"
+for( my $i = 0; $i <= $#inList; $i++)
+{
+ for(my $j = 0; $j <= $#inList; $j++)
+ {
+ undef( $inList[$i][$j] );
+ }
+}
+
+my $g_SeqNum = 0;
+
+
+#==============================================================================
+# MAIN
+#==============================================================================
+## get any environment variables
+
+my $hbDir = $ENV{'HBDIR'};
+if (defined ($hbDir))
+{
+ unless ($hbDir ne "")
+ {
+ $hbDir = '.'; #Set to current directory
+ }
+}
+else
+{
+ $hbDir = '.'; #Set to current directory
+}
+
+# print $#ARGV;
+if ( ($#ARGV < 0) or ($opt_help) )
+{
+ printUsage();
+ exit 0 ;
+}
+
+
+#------------------------------------------------------------------------------
+# Parse optional input arguments
+#------------------------------------------------------------------------------
+GetOptions( "help" => \$opt_help,
+ "istepmode" => \$opt_istepmode,
+ "normalmode" => \$opt_normalmode,
+ "list" => \$opt_list,
+ "command=s" => \$opt_command,
+ "cmdfile" => \$opt_cmdfile,
+
+ "debug" => \$opt_debug,
+ );
+
+##
+## find the istep mode, command, and status registers in the syms file
+##
+my $istepmodereg = `grep "SPLESS::g_SPLess_IStepMode_Reg" $hbDir/$hbSymsFile | awk -F"," '{print \$2}'`;
+chomp $istepmodereg;
+
+my $commandreg = `grep "SPLESS::g_SPLess_Command_Reg" $hbDir/$hbSymsFile | awk -F"," '{print \$2}'`;
+chomp $commandreg;
+
+my $statusreg = `grep "SPLESS::g_SPLess_Status_Reg" $hbDir/$hbSymsFile | awk -F"," '{print \$2}'` ;
+chomp $statusreg;
+
+if ( $opt_debug )
+{
+ print STDOUT "istepmode = $opt_istepmode\n";
+ print STDOUT "normalmode = $opt_normalmode\n";
+ print STDOUT "command = $opt_command\n";
+ print STDOUT "debug = $opt_debug\n";
+
+ print STDOUT "hbDir = $hbDir\n";
+ print STDOUT "hbSymsFile = $hbSymsFile\n";
+ print STDOUT "istepmodereg = $istepmodereg\n";
+ print STDOUT "commandreg = $commandreg\n";
+ print STDOUT "statusreg = $statusreg\n";
+
+ VBU_Cacheline::SetFlags( 1, 0 );
+
+}
+
+
+## fetch the ISTEP csv list
+get_istep_list();
+
+if ( $opt_list )
+{
+ print_istep_list();
+ exit;
+}
+
+ ## VPO cannot be running when we start.
+ my $qstr = VBU_Cacheline::P8_Ins_Query();
+ if ( $qstr ne "STOPPED" )
+ {
+ print STDOUT "VPO is \"$qstr\", setting to STOPPED.\n";
+ VBU_Cacheline::P8_Ins_Stop();
+ }
+
+##
+## process --Istep Mode command
+## IStepModeStr = "cpu0_0_0_3->scratch=0x4057b007_4057b007"
+## NormalModeStr = "cpu0_0_0_3->scratch=0x700b7504_700b7504"
+##
+if ( $opt_istepmode == 1 )
+{
+ print STDOUT "ENable istepmode\n";
+ setMode( "istep" );
+}
+
+if ( $opt_normalmode == 1 )
+{
+ print STDOUT "DISable istepmode\n";
+ setMode( "normal" );
+}
+
+##
+## Process other commands
+##
+if ( $opt_command ne "" )
+{
+ if ( $opt_debug ) { print STDOUT "== process command \"$opt_command\" \n"; }
+ parse_command( $opt_command );
+}
+
+
+#==============================================================================
+# SUBROUTINES
+#==============================================================================
+
+#------------------------------------------------------------------------------
+# Print command line help
+#------------------------------------------------------------------------------
+sub printUsage()
+{
+ print STDOUT "\nUsage: hb-istep [--help]\n";
+ print STDOUT " [--istepmode] (enable istep mode)\n" ;
+ print STDOUT " [--normalmode] (disable istep mode)\n" ;
+ print STDOUT " [--command sN] (run istep N)\n" ;
+ print STDOUT " [--command sN..M] (run isteps N through M)\n" ;
+ print STDOUT " [--command <foo>] (run named istep \"foo\")\n" ;
+ print STDOUT " [--command <foo>..<bar>] (run named isteps \"foo\" through \"bar\")\n" ;
+
+ print STDOUT "\n" ;
+
+}
+
+
+## read in file with csv istep list and store in inList
+sub get_istep_list()
+{
+ my $istep, my $substep, my $name ;
+
+ open( FH, "< $hbDir/$CSVfile") or die "can't open $hbDir/$CSVfile : $!";
+
+ while( <FH> )
+ {
+ chomp;
+
+ ( $istep, $substep, $name) = split( ",", $_ );
+ ## print STDERR "$_, $istep, $substep, $name\n" ;
+
+ $inList[$istep][$substep] = $name;
+ }
+
+ close( FH );
+}
+
+sub print_istep_list( )
+{
+ my $hdrflag = 1;
+
+ ## print STDOUT "IStep\tSubStep\tName\n";
+ print STDOUT " IStep Name\n";
+ print STDOUT "---------------------------------------------------\n";
+
+ for(my $i = 4; $i <= $#inList; $i++)
+ {
+ for(my $j = 0; $j <= $#inList; $j++)
+ {
+ ## print all substeps
+ # print "==$inList[$i][$j] \n";
+ if ( defined( $inList[$i][$j] ) )
+ {
+ if ( $hdrflag )
+ {
+ printf STDOUT " -- IStep $i -- \n";
+ $hdrflag = 0;
+ }
+ ## printf STDOUT "%d\t%d\t%s\n", $i, $j, $inList[$i][$j] ;
+ printf STDOUT " %s\n", $inList[$i][$j] ;
+ }
+ } ## end for $j
+ $hdrflag=1;
+ } ## end for $i
+}
+
+sub find_in_inList( $ )
+{
+ my ( $substepname ) = @_;
+
+ for(my $i = 0; $i <= $#inList; $i++)
+ {
+ for(my $j = 0; $j <= $#inList; $j++)
+ {
+ ## if ( defined($inList[$i][$j]) ) { print ".$inList[$i][$j]?$substepname. \n"; }
+
+ if ( defined($inList[$i][$j]) && ($inList[$i][$j] eq $substepname ) )
+ {
+ ## print "== $i $j $inList[$i][$j] \n";
+ return ($i, $j, 1 );
+ }
+ }
+ }
+
+ return ( $#inList, $#inList, 0 )
+}
+
+##
+## keep trying to get status until seqnum syncs up
+
+sub getSyncStatus( )
+{
+ # set # of retries
+ my $count = 100;
+ my $result = 0;
+ my $seqnum = 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.
+ VBU_Cacheline::RunClocks();
+
+ ## dump printk similar to the Jim McGuire's script
+ ## dumpPrintk();
+
+ $result = CLread( $statusreg );
+ $seqnum = ( ( $result & 0x3f00000000000000 ) >> 56 );
+ if ( $seqnum == $g_SeqNum )
+ {
+ return $result;
+ }
+
+ if ( $count <= 0 )
+ {
+ print STDOUT "TIMEOUT waiting for seqnum=$g_SeqNum\n";
+ return -1;
+ }
+ $count--;
+ } ## endwhile
+
+}
+
+sub runIStep( $$ )
+{
+ my ( $istep, $substep) = @_;
+ my $byte0, my $command;
+ my $cmd;
+ my $result;
+
+
+ ## bump the seqnum
+ $g_SeqNum++;
+
+ printf STDOUT "run %d.%d %s:\n", $istep, $substep, $inList[$istep][$substep];
+
+ $byte0 = 0x80 + $g_SeqNum; ## gobit + seqnum
+ $command = 0x00;
+ $cmd = sprintf( "0x%2.2x%2.2x%2.2x%2.2x00000000", $byte0, $command, $istep, $substep );
+ VBU_Cacheline::CLwrite( $commandreg, $cmd );
+
+ $result = getSyncStatus();
+
+ ## if result is -1 we have a timeout
+ if ( $result == -1 )
+ {
+ print "-----------------------------------------------------------------\n";
+ }
+ else
+ {
+ my $taskStatus = ( ( $result & 0x00ff000000000000 ) >> 48 );
+ my $stsIStep = ( ( $result & 0x0000ff0000000000 ) >> 40 );
+ my $stsSubstep = ( ( $result & 0x000000ff00000000 ) >> 32 );
+ my $istepStatus = ( ( $result & 0x00000000ffffffff ) );
+
+ print STDOUT "-----------------------------------------------------------------\n";
+ ## printf STDOUT "Istep %d.%d Status: 0x%x\n", $stsIStep, $stsSubstep, $istepStatus ;
+ if ( $taskStatus != 0 )
+ {
+ printf STDOUT "Istep %d.%d FAILED to launch, task status is %d\n", $stsIStep, $stsSubstep, $taskStatus ;
+ }
+ else
+ {
+ printf STDOUT "Istep %d.%d returned Status: 0x%x\n", $stsIStep, $stsSubstep, $istepStatus ;
+ }
+ print STDOUT "-----------------------------------------------------------------\n";
+ }
+
+}
+
+
+## run command = "sN"
+sub sCommand( $ )
+{
+ my ( $scommand ) = @_;
+
+ my $i = $scommand;
+ my $j = 0;
+
+ # sanity check
+ if ( !defined($inList[$i][0]) )
+ {
+ printf STDOUT "IStep %d.0 does not exist.\n", $i;
+ return -1;
+ }
+
+ # execute all the substeps in the IStep
+ for( $j=0; $j<$#inList; $j++ )
+ {
+ ## print "-----------------"
+ ##print STDOUT "run IStep %d %s ...\n", $i, $inList[$i][$j] );
+ ##print "-----------------"
+ if ( defined( $inList[$i][$j] ) )
+ {
+ runIStep( $i, $j );
+ }
+ }
+}
+
+
+sub parse_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) { print STDOUT "===== s command : ", $command, ":\n"; }
+ substr( $command, 0, 1, "" );
+
+ if ( isdigit( $command ) )
+ {
+ # command = "sN"
+ if ($opt_debug) { print STDOUT "===== single IStep: ", $command, "\n"; }
+ sCommand( $command );
+ }
+ else
+ {
+ # list of substeps = "sM..N"
+ ( $M, $N ) = split( /\.\./, $command );
+
+ if ($opt_debug) { print STDOUT "===== 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) { print STDOUT "===== named commands : ", @ss_list, "\n"; }
+
+ ( $istepM, $substepM, $foundit) = find_in_inList( $ss_list[0] );
+ $istepN = $istepM;
+ $substepN = $substepM;
+ if ( ! $foundit )
+ {
+ print STDOUT "Invalid substep ", $ss_list[0], "\n" ;
+ return -1;
+ }
+
+
+ if ( $#ss_list > 0 )
+ {
+ ( $istepN, $substepN, $foundit) = find_in_inList( $ss_list[1] );
+ if ( ! $foundit )
+ {
+ print STDOUT "Invalid substep %s", $ss_list[1], "\n" ;
+ return -1;
+ }
+ }
+
+ ## print "got it, running isteps:\n";
+ for( my $x=$istepM; $x<$istepN+1; $x++ )
+ {
+ for( my $y=$substepM; $y<$substepN+1; $y++ )
+ {
+ ## print STDOUT "run $x $y $inList[$x][$y]\n";
+ runIStep( $x, $y );
+ }
+ }
+
+ }
+}
+
+## write to scratch reg 3 to set istep or normal mode, check return status
+sub setMode( )
+{
+ my ( $cmd ) = @_;
+ my $count = 0;
+ my $expected = 0;
+ my $readybit = 0;
+ my $result = 0;
+
+
+ if ( $cmd eq "istep" )
+ {
+ VBU_Cacheline::CLwrite( $istepmodereg, "0x4057b0074057b007" );
+ $expected = 1;
+ }
+ elsif ( $cmd eq "normal" )
+ {
+ VBU_Cacheline::CLwrite( $istepmodereg, "0x700b7504700b7504" );
+ $expected = 0;
+ }
+ else
+ {
+ print "invalid setMode command: %s\n", $cmd ;
+ return -1;
+ }
+
+ if ( $opt_debug )
+ {
+ ## readback and display
+ $result = CLread( $istepmodereg );
+ printf STDOUT "===== istepmodereg readback: 0x%lx\n", $result ;
+ }
+
+
+ ## Loop, advancing clock, and wait for readybit
+ $count = 30;
+ while(1)
+ {
+ ## advance HostBoot code by a certain # of cycles, then check the
+ ## sequence number to see if it has changed. rinse and repeat.
+ VBU_Cacheline::RunClocks();
+
+ $result = CLread( $statusreg );
+
+ $readybit = ( ( $result & 0x4000000000000000 ) >> 62 );
+
+ if ($opt_debug)
+ { printf STDOUT "===== setMode: count=%d, result=0x%lx, readybit=0x%x\n", $count, $result, $readybit }
+
+ if ( $readybit == $expected )
+ {
+ print STDOUT "Set $cmd Mode success.\n" ;
+ return 0;
+ }
+
+ if ( $count <= 0 )
+ {
+ print STDOUT "TIMEOUT waiting for readybit, status=0x%x\n", $result ;
+ return -1;
+ }
+
+ $count--;
+ }
+}
+
+__END__ \ No newline at end of file
diff --git a/src/build/vpo/hb-virtdebug.pl b/src/build/vpo/hb-virtdebug.pl
index 74013231c..19dc38d3f 100755
--- a/src/build/vpo/hb-virtdebug.pl
+++ b/src/build/vpo/hb-virtdebug.pl
@@ -568,6 +568,8 @@ if ($dumpAll)
}
+
+
#==============================================================================
# SUBROUTINES
#==============================================================================
OpenPOWER on IntegriCloud