summaryrefslogtreecommitdiffstats
path: root/src/build
diff options
context:
space:
mode:
authorMark Wenning <wenning@us.ibm.com>2011-12-12 16:53:40 -0600
committerMark W. Wenning <wenning@us.ibm.com>2012-01-20 16:42:41 -0600
commitd62d15ecce724013e04106ad4cf217b9b341ccfc (patch)
tree9ca43d67fb2570e5afd85578ce03d2323a3fc725 /src/build
parent0408868bb339cab3222c5728012fca2306aa982b (diff)
downloadtalos-hostboot-d62d15ecce724013e04106ad4cf217b9b341ccfc.tar.gz
talos-hostboot-d62d15ecce724013e04106ad4cf217b9b341ccfc.zip
RTC4420 SPless on VPO
Modify SPLess code to use memory-mapped locations instead of SCOM scratchpad regs - Debug Framework does not support this at this time. VBU_Cacheline.pm is intended to be a module to read a single 64-bit word (which will be the spless command, status, and istepmode regs) from L3 memory within the AWAN model. CLread() will read the cacheline (at 128-byte boundaries) and then extract the quadword from the offet within the cacheline. CLwrite() will read/modify/write the quadword and cacheline. Note: There is a code block within VBU_Cacheline.pm called TEST - this returns dummy values to CLread and CLwrite so that I can run the perl script on a local system without connecting to simics or AWAN. It is not normally used. hb_istep is meant to be run after running a modified version of Jim McGuire's do_p8vbu_script_hbi-Sprint7 . See my public directory /gsa/ausgsa/home/w/e/wenning/Public/HBI/scripts for the modified script. These changes will be merged back into Jim McGuire's script later. The modified version loads the binaries into L3, sets up all the rest of the environment, and then exits BEFORE going into the execution loop. At that point, the user should run hb-istep --istepmode to set HostBoot up to run IStep SPLess (Single Step) . The user can then run hb-istep commands to execute isteps, etc. hb-istep use is documented on the wiki at https://w3-connections.ibm.com/wikis/home?lang=en_US#/wiki/Host%20Boot/page/HB%20ISteps%20on%20AWAN Please look there for updates. - first commit, branch vbu2 - modify spless to use memory locations instead of SCOM regs - add VBU_Cacheline.pm - archive temporary version of do_p8vbu_script_hbi-mark until we can get the hb-istep hooks into Jim McGuire's scripts - add test calls to VBU_Cacheline.pm - change flush call to Joe McGills "quiet" version - add note that p8_ins* calls are in Jim McGuires dir and will be replaced by the "official" ones soon. - experiment with git notes command, sorry for the thrash - add check to see if VPO is STOPPED before accessing anything - partial review fixes - blocked on model: can't test Change-Id: I07431dc525844c5c504175d92eae113457eac063 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/592 Tested-by: Jenkins Server Reviewed-by: CAMVAN T. NGUYEN <ctnguyen@us.ibm.com> Reviewed-by: Mark W. Wenning <wenning@us.ibm.com>
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