summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/build/vpo/VBU_Cacheline.pm12
-rwxr-xr-xsrc/build/vpo/hb-istep907
-rw-r--r--src/usr/initservice/istepdispatcher/makefile9
-rw-r--r--src/usr/initservice/istepdispatcher/splesscommon.C286
-rw-r--r--src/usr/initservice/istepdispatcher/splesscommon.H223
-rw-r--r--src/usr/initservice/istepdispatcher/sptask.C60
6 files changed, 982 insertions, 515 deletions
diff --git a/src/build/vpo/VBU_Cacheline.pm b/src/build/vpo/VBU_Cacheline.pm
index af9a502a1..b44a0a7ea 100755
--- a/src/build/vpo/VBU_Cacheline.pm
+++ b/src/build/vpo/VBU_Cacheline.pm
@@ -20,7 +20,7 @@
#
# Origin: 30
#
-# IBM_PROLOG_END
+# IBM_PROLOG_END_TAG
#
# Name: src/build/vpo/VBU_Cacheline.pm
#
@@ -105,19 +105,19 @@ my $FLUSHCMD = "$vbuToolsDir/proc_l2_flush_wrap.x86 $CORE -quiet";
my $FLUSHQUERY = "$vbuToolsDir/p8_check_l3";
my $RUNCLKSCMD = "simclock";
-## @todo $$$$$
+## @todo
## NOTE: need to be able to specify thread (-t ) and core (-c ), they
## should not be hardwired
-##my $QUERYCMD = "$vbuToolsDir/proc_thread_control.x86 -query $CORE -t0";
-##my $STOPCMD = "$vbuToolsDir/proc_thread_control.x86 -stop $CORE -tall";
-##my $STARTCMD = "$vbuToolsDir/proc_thread_control.x86 -start $CORE -tall";
+## my $QUERYCMD = "$vbuToolsDir/proc_thread_control.x86 -query $CORE -t0";
+## my $STOPCMD = "$vbuToolsDir/proc_thread_control.x86 -stop $CORE -tall";
+## my $STARTCMD = "$vbuToolsDir/proc_thread_control.x86 -start $CORE -tall";
+my $RESETCMD = "$vbuToolsDir/proc_thread_control.x86 -sreset_auto $CORE";
## Jim McGuire's older versions.
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";
-my $RESETCMD = "$vbuToolsDir/proc_thread_control.x86 -sreset_auto $CORE";
##
#==============================================================================
diff --git a/src/build/vpo/hb-istep b/src/build/vpo/hb-istep
index 81d96e190..729d5ec46 100755
--- a/src/build/vpo/hb-istep
+++ b/src/build/vpo/hb-istep
@@ -6,7 +6,7 @@
#
# IBM CONFIDENTIAL
#
-# COPYRIGHT International Business Machines Corp. 2011
+# COPYRIGHT International Business Machines Corp. 2011 - 2012
#
# p1
#
@@ -20,25 +20,22 @@
#
# Origin: 30
#
-# IBM_PROLOG_END
+# IBM_PROLOG_END_TAG
#
-# Purpose: This perl script works in concert with do_p8vbu_script_hbi_* to
+# Purpose: This perl script works in concert with do_sprint 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:
-#
+# 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 RunClocks() to step through HostBoot.
+# Checks for status from previous Isteps, and reports status.
#
# Author: Mark Wenning
#
@@ -54,7 +51,7 @@ use File::Basename;
use lib dirname (__FILE__);
## 64-bit input
-## argh, not compatable with GetOpt!! use bigint;
+use bigint;
no warnings 'portable';
# read/write cachelines to L3
@@ -71,7 +68,9 @@ sub find_in_inlist;
sub parse_command;
sub setMode;
sub resume_istep;
-sub getShutDownStatus;
+sub isShutDown;
+sub getSymbol;
+sub dumpEnvVar;
#------------------------------------------------------------------------------
# Constants
@@ -80,12 +79,14 @@ my $CORE = "-c3";
## @todo extract these from splesscommon.H
-use constant ISTEP_MODE_ON_SIGNATURE => "4057b0074057b007";
-use constant ISTEP_MODE_OFF_SIGNATURE => "700b7504700b7504";
+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;
@@ -95,143 +96,227 @@ use constant MAX_SUBSTEPS => 25;
# Globals
#------------------------------------------------------------------------------
my $opt_debug = 0;
+my $opt_help = 0;
my $opt_istepmode = 0;
-my $opt_normalmode = 0;
+my $opt_splessmode = 0;
+my $opt_fspmode = 0;
my $opt_command = "";
my $opt_list = 0;
-my $opt_help = 0;
my $opt_resume = 0; ## resume istep from break point
-my $opt_clear_trace = 0; ## submit command 01
-my $opt_cmdfile = 0; ## batchmode, later
-my $opt_setup = ""; ## run Jim's script to start up the model
+my $opt_clear_trace = 0; ## submit command 02
+my $opt_cmdfile = 0; ## batchmode, later
+my $opt_setup = ""; ## run Jim's script to start up the model
+
+## initialize inList to "undefined"
my @inList;
$inList[MAX_ISTEPS][MAX_SUBSTEPS] = ();
-## initialize inList to "undefined"
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 $g_SeqNum = int(rand(64));
#==============================================================================
# MAIN
#==============================================================================
-## get any environment variables
-## Assume that all the tools, files, etc are in the same directory that
+## Assume that all the tools, files, etc are in the same directory that
## we are in.
-
+## --------------------------------------------------------------------------
+## get any environment variables
+## --------------------------------------------------------------------------
my $pgmDir = `dirname $0`;
chomp( $pgmDir );
my $hbToolsDir = $ENV{'HB_TOOLS'};
if ( ! defined( $hbToolsDir) || ( $hbToolsDir eq "" ) )
{
- $hbToolsDir = $pgmDir; ## Set to tool directory
-}
+ $hbToolsDir = $pgmDir; ## Set to tool directory
+}
my $hbDir = $ENV{'HB_IMGDIR'};
if ( ! defined( $hbDir) || ( $hbDir eq "" ) )
{
$hbDir = $pgmDir; ## Set to tool directory
-}
+}
my $vbuToolsDir = $ENV{'HB_VBUTOOLS'};
if (defined ($vbuToolsDir))
{
unless ($vbuToolsDir ne "")
{
- $vbuToolsDir = "/gsa/ausgsa/projects/h/hostboot/vbutools/dev";
+ $vbuToolsDir = "/gsa/ausgsa/projects/h/hostboot/vbutools/latest";
}
}
+my $hbCount = $ENV{'HB_COUNT'};
+if ( !defined( $hbCount ) || ( $hbCount eq "" ) )
+{
+ ## set default
+ $hbCount = 0xffffffff; ## effectively infinite ...
+}
my $CSVfile = "$hbDir/isteplist.csv";
my $hbSymsFile = "$hbDir/hbicore.syms"; #Use hbicore.syms
-
-## print $#ARGV;
+if ( ! -e "$hbSymsFile" ) { die "Can't find symbols file $hbSymsFile\n"; }
+if ( ! -e "$CSVfile" ) { die "Can't find isteplist file $hbSymsFile\n"; }
+
+
+print STDOUT "Welcome to hb-istep 3.0 . \n";
+
+
+## exit if no args
if ( $#ARGV < 0 )
{
printUsage();
exit 0 ;
-}
+}
+
+
#------------------------------------------------------------------------------
# Parse optional input arguments
#------------------------------------------------------------------------------
-GetOptions( "help|?" => \$opt_help,
- "istepmode" => \$opt_istepmode,
- "normalmode" => \$opt_normalmode,
- "list" => \$opt_list,
- "command=s" => \$opt_command,
- "resume" => \$opt_resume,
- "clear-trace" => \$opt_clear_trace,
- "cmdfile" => \$opt_cmdfile,
- "setup=s" => \$opt_setup,
-
- "debug" => \$opt_debug,
- );
-
-
-
-##-----------------------------------------------------------------------------
-## check for access to the files we need.
-##-----------------------------------------------------------------------------
-if ( ! -e "$hbSymsFile" ) { die "Can't find symbols file $hbSymsFile\n"; }
-if ( ! -e "$CSVfile" ) { die "Can't find isteplist file $hbSymsFile\n"; }
+## GetOptions( "help|?" => \$opt_help,
+## "istepmode" => \$opt_istepmode,
+## "normalmode" => \$opt_normalmode,
+## "list" => \$opt_list,
+## "command=s" => \$opt_command,
+## "resume" => \$opt_resume,
+## "clear-trace" => \$opt_clear_trace,
+## "cmdfile" => \$opt_cmdfile,
+## "setup=s" => \$opt_setup,
+##
+## "debug" => \$opt_debug,
+## );
+
+##--------------------------------------------------------------------------
+## 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 = @ARGV;
+
+if ( !(@Options) )
+{
+ printUsage();
+ exit;
+}
##
-## find the istep mode, command, and status registers in the syms file
+## find all the standard options, set their flag, and remove them from
+## the options list.
+## vpo and simics used to use different command-line styles,
+## simics wanted you to say "hb-istep debug s4", and
+## vpo wanted you to say "hb-istep --debug --command s4" .
+## With this change, vpo should accept both styles.
##
-my $istepmodereg = `grep "SPLESS::g_SPLess_IStepMode_Reg" $hbSymsFile | awk -F"," '{print \$2}'`;
-chomp $istepmodereg;
+for ( my $i=0; $i <= $#Options; $i++ )
+{
+ $_ = $Options[$i];
-my $commandreg = `grep "SPLESS::g_SPLess_Command_Reg" $hbSymsFile | awk -F"," '{print \$2}'`;
-chomp $commandreg;
+ if ( m/\-{0,2}help/ )
+ {
+ $opt_help = 1;
+ $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/ )
+ {
+ ## does nothing except eat the "[--]command" 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] = "";
+ }
-my $statusreg = `grep "SPLESS::g_SPLess_Status_Reg" $hbSymsFile | awk -F"," '{print \$2}'` ;
-chomp $statusreg;
+} ## endfor
-my $shutdownflag = `grep "CpuManager::cv_shutdown_requested" $hbSymsFile | awk -F"," '{print \$2}'` ;
-chomp $shutdownflag;
+## if there's anything left after this, assume it is a command
+my $command = join( "", @Options );
-my $shutdownsts = `grep "CpuManager::cv_shutdown_status" $hbSymsFile | awk -F"," '{print \$2}'` ;
-chomp $shutdownsts;
+chomp $command;
-##-----------------------------------------------------------------------------
-## Start processing options
-##-----------------------------------------------------------------------------
+## ---------------------------------------------------------------------------
+## Fetch the symbols we need from syms file
+## ---------------------------------------------------------------------------
+
+my $IstepModeReg = getSymbol( "SPLESS::g_SPLess_IStepMode_Reg" );
+my $CommandReg = getSymbol( "SPLESS::g_SPLess_Command_Reg" );
+my $StatusReg = getSymbol( "SPLESS::g_SPLess_Status_Reg" );
+
+my $ShutDownFlag = getSymbol( "CpuManager::cv_shutdown_requested" );
+my $ShutDownSts = getSymbol( "CpuManager::cv_shutdown_status" );
+
if ( $opt_debug )
{
print STDERR "\n----- DEBUG: ----------------------------------- \n";
print STDERR "help = $opt_help\n";
+ print STDERR "debug = $opt_debug\n";
+ print STDERR "list = $opt_list\n";
print STDERR "istepmode = $opt_istepmode\n";
- print STDERR "normalmode = $opt_normalmode\n";
- print STDERR "list = $opt_list\n";
- print STDERR "command = $opt_command\n";
- print STDERR "cmdfile = $opt_cmdfile\n";
- print STDERR "setup = $opt_setup\n";
+ print STDERR "splessmode = $opt_splessmode\n";
+ print STDERR "fspmode = $opt_fspmode\n";
+
+ print STDERR "resume = $opt_resume\n";
print STDERR "clear-trace = $opt_clear_trace\n";
- print STDERR "debug = $opt_debug\n";
-
+ print STDERR "command flag = $opt_command\n";
+ print STDERR "command = \"$command\"\n";
+
print STDERR "pgmDir = $pgmDir\n";
- print STDERR "hbDir = $hbDir\n";
- print STDERR "hbSymsFile = $hbSymsFile\n";
- print STDERR "istepmodereg = $istepmodereg\n";
- print STDERR "commandreg = $commandreg\n";
- print STDERR "statusreg = $statusreg\n";
- print STDERR "shutdownflag reg = $shutdownflag\n";
- print STDERR "shutdownsts reg = $shutdownsts\n";
-
- VBU_Cacheline::SetFlags( 1, 0 );
+ print STDERR "hbDir = $hbDir\n";
+ print STDERR "hbCount = $hbCount\n";
+
+ print STDERR "hbSymsFile = $hbSymsFile \n" ;
+ print STDERR "IstepModeReg = $IstepModeReg \n" ;
+ print STDERR "CommandReg = $CommandReg \n" ;
+ print STDERR "StatusReg = $StatusReg \n" ;
+ print STDERR "ShutDownFlag = $ShutDownFlag \n" ;
+ print STDERR "ShutDownSts = $ShutDownSts \n" ;
+
+ ## turn on the debug flag in VBU_Cacheline.pm
+ VBU_Cacheline::SetFlags( 1, 0 );
}
if ( $opt_help )
@@ -240,13 +325,10 @@ if ( $opt_help )
exit;
}
-##
-## run the main loop. Yes, I did this on purpose.
-## Idea is (later) to pass this an array / hash of options and use
-## GetOptionsFromArray() to parse them.
-## That way I can either pass it @ARGV or an array processed from the cmdfile
-##
-main();
+## ---------------------------------------------------------------------------
+## run the main loop.
+## ---------------------------------------------------------------------------
+main();
@@ -258,7 +340,7 @@ sub main()
print STDOUT "\n";
## fetch the ISTEP csv list
- get_istep_list();
+ get_istep_list();
if ( $opt_list )
{
@@ -266,8 +348,21 @@ sub main()
exit;
}
+ if ( $opt_istepmode )
+ {
+ print STDOUT "istepmode no longer used - use splessmode, or fspmode\n";
+ exit;
+ }
- ## VPO cannot be running when we start.
+ ##
+ ## Before we start, we must make sure the system is stopped and memory
+ ## is flushed so that we can read the state. This includes:
+ ## - make sure that HostBoot has not already started and run to
+ ## completion (shutdown status )
+ ## - read/write memory location to set single-step mode (SPLESS or
+ ## FSP)
+ ## - etc??
+ ##
my $qstr = VBU_Cacheline::P8_Ins_Query();
if ( $qstr ne "STOPPED" )
{
@@ -275,63 +370,83 @@ sub main()
VBU_Cacheline::P8_Ins_Stop();
VBU_Cacheline::P8_Flush_L2();
}
-
- ( my $flag, my $sts ) = getShutDownStatus();
- if ( $flag )
+
+ if ( isShutDown() )
{
- print STDOUT "Sorry, HostBoot has already shut down with status $sts, cannot run isteps.\n";
+ print STDOUT "HostBoot has shut down.\n";
exit;
}
- ##
- ## Process resume
- ##
- if ( $opt_resume )
+
+ if ( ( $opt_splessmode == 1 )
+ || ( $opt_fspmode == 1 )
+ )
{
- resume_istep();
- ## exit; ??
+ my $result = VBU_Cacheline::CLread( sprintf( "%x", $IstepModeReg ) );
+
+ if ( $opt_debug )
+ {
+ printf STDERR "=== Entry: IStep Mode Reg = 0x%x\n", $result;
+ }
+
+ if ( $result =~ /^.*RUN_ALL_MODE_SIGNATURE/ )
+ {
+ print STDOUT "HostBoot has already started in automatic mode. Please restart and then try again.\n";
+ exit;
+ }
}
+
##
## process --Istep Mode command
- ## IStepModeStr = "cpu0_0_0_3->scratch=0x4057b007_4057b007"
- ## NormalModeStr = "cpu0_0_0_3->scratch=0x700b7504_700b7504"
##
- if ( $opt_istepmode == 1 )
+ if ( $opt_splessmode == 1 )
{
- my $result = VBU_Cacheline::CLread( $istepmodereg );
- if ( $opt_debug ) { print STDERR __LINE__, "-- Entry: IStep Mode Reg = $result"; }
- if ( $result =~ /^.*ISTEP_MODE_OFF_SIGNATURE/ )
- {
- print STDOUT "Sorry, HostBoot has already started in automatic mode. Please restart and then try again.\n";
- exit;
- }
-
- print STDOUT "ENable istepmode\n";
- setMode( "istep" );
+ print STDOUT "ENable splessmode\n";
+ setMode( "spless" );
+ exit;
}
- if ( $opt_normalmode == 1 )
+ if ( $opt_fspmode == 1 )
{
- print STDOUT "DISable istepmode\n";
- setMode( "normal" );
+ print STDOUT "ENable fspmode\n";
+ print STDOUT "WARNING: fspmode is not currently supported on VPO\n";
+ setMode( "fsp" );
+ exit;
}
if ( $opt_clear_trace )
{
print STDOUT "Clear Trace Buffers\n";
clear_trace();
+ exit;
+ }
+
+
+
+ ##
+ ## Process resume
+ ##
+ if ( $opt_resume )
+ {
+ resume_istep();
+ ## exit; ??
}
##
## Process other commands
##
- if ( $opt_command ne "" )
+ if ( $command ne "" )
{
- if ( $opt_debug ) { print STDERR "== __LINE__ process command \"$opt_command\" \n"; }
- parse_command( $opt_command );
+ if ( $opt_debug )
+ {
+ print STDERR "=== process istep command: \"$opt_command\" \n";
+ }
+
+ parse_command( $command );
+ exit;
}
-
+
} ## end main
@@ -341,60 +456,91 @@ sub main()
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 " [--splessmode] (enable spless mode)\n" ;
+ print STDOUT " [--fspmode] (enable fsp 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 " [--resume] (resume an istep that is at a break point)\n" ;
+ print STDOUT " [--clear-trace] (clear trace buffers before starting)\n";
+
print STDOUT "\n" ;
- print STDOUT " [--clear-trace] (clear trace buffers before starting)\n";
-## print STDOUT " [--cmdfile] (get commands from a batchfile)\n";
-## print STDOUT " [--setup] (bring up AWAN and wait for further commands)\n";
-## print STDOUT "\n" ;
}
+
##
## Increment the sequence number, rolling over at 64
##
sub bumpSeqNum()
{
- $g_SeqNum++;
-
+ $g_SeqNum++;
+
$g_SeqNum %= 64;
-
+
return $g_SeqNum;
}
+sub dumpEnvVar( $ )
+{
+ my $envvar = shift;
+
+ if ( defined( $ENV{$envvar} ) )
+ {
+ ## $$::userDisplay "$envvar = $ENV{$envvar}\n";
+ print STDOUT "$envvar = $ENV{$envvar}\n";
+ }
+}
+
+##
+## Get symbol address from hbotSymsFile
+##
+sub getSymbol( $ )
+{
+ my $symbol = shift;
+ my $hexstr = "";
+ my $symAddr = 0;
+
+ $hexstr = `grep "$symbol" $hbSymsFile | awk -F"," '{print \$2}'`;
+ chomp $hexstr;
+
+ ## print STDERR __LINE__, ": $hexstr\n";
+ $symAddr = hex "0x$hexstr";
+
+ return $symAddr;
+}
+
+
##
## read in file with csv istep list and store in inList
##
sub get_istep_list()
{
my $istep, my $substep, my $name ;
-
+
open( FH, "< $CSVfile") or die "can't open $CSVfile : $!";
while( <FH> )
{
chomp;
- ( $istep, $substep, $name) = split( ",", $_ );
+ ( $istep, $substep, $name) = split( ",", $_ );
chomp $name;
+
## print STDERR "$_, $istep, $substep, $name\n" ;
-
+
if ( defined($name) && ( $name ne "" ) )
{
$inList[$istep][$substep] = $name;
- }
- }
-
- close( FH );
+ }
+ }
+
+ close( FH );
}
+
##
## print the istep list to the screen.
##
@@ -402,140 +548,270 @@ sub print_istep_list( )
{
my $hdrflag = 1;
- ## print STDOUT "IStep\tSubStep\tName\n";
- print STDOUT " IStep Name\n";
+ print STDOUT " IStep Name\n";
print STDOUT "---------------------------------------------------\n";
-
+
for(my $i = 0; $i < MAX_ISTEPS; $i++)
{
for(my $j = 0; $j < MAX_SUBSTEPS; $j++)
{
## print "==$i.$j $inList[$i][$j] \n";
+
if ( defined( $inList[$i][$j] ) )
{
- if ( $hdrflag )
- {
- printf STDOUT " -- IStep $i -- \n";
+ 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] ;
- }
+
+ printf STDOUT " %s\n", $inList[$i][$j] ;
+ }
} ## end for $j
+
$hdrflag=1;
- } ## end for $i
+ } ## end for $i
}
##
-##
+## Find istep name in inList array.
+##
+## @param[in] - name
##
-sub find_in_inList( $ )
+## @return - istep #, substep #, found flag = true for success
+## fount flag = 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]) ) { 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 ( MAX_ISTEPS, MAX_SUBSTEPS, 0 )
+}
- return ( MAX_ISTEPS, MAX_SUBSTEPS, 0 )
-}
##
-## Check if HostBoot has already run and shutdown.
-sub getShutDownStatus()
+## Read memory locations to check if HostBoot has already run and shutdown.
+## return nonzero if it has, 0 otherwise
+##
+sub isShutDown()
{
+ ## check to make sure that system is stopped and flushed.
+ my $qstr = VBU_Cacheline::P8_Ins_Query();
+ if ( $qstr ne "STOPPED" )
+ {
+ ## Stop instructions, flush L2
+ VBU_Cacheline::P8_Ins_Stop();
+ VBU_Cacheline::P8_Flush_L2();
+ }
+
+ my $flag = VBU_Cacheline::CLread( sprintf( "%x", $ShutDownFlag ) );
+ my $status = VBU_Cacheline::CLread( sprintf( "%x", $ShutDownSts ) );
- my $flag = VBU_Cacheline::CLread( $shutdownflag );
- my $status = VBU_Cacheline::CLread( $shutdownsts );
-
- if ( $opt_debug )
- {
+ if ( $opt_debug )
+ {
print STDERR "Shutdown Flag = $flag\n";
- print STDERR "Shutdown Status = $status\n";
+ print STDERR "Shutdown Status = $status\n";
}
- return ( $flag, $status );
+ if ( $flag )
+ {
+ print STDOUT "HostBoot has shut down with status $status.\n";
+ return 1;
+ }
+
+ return 0;
}
+
+##
+## run clocks using calls to VBU_Cacheline
+##
+## This will also start instructions if necessary
##
-## keep trying to get status until seqnum syncs up
+sub runClocks()
+{
+
+ VBU_Cacheline::RunClocks();
+}
+
+
+##
+## send command using the command register
+##
+## NOTES: PUTFAC does not work correctly. STKFAC will latch the value
+## in the register forever, i.e. HostBoot cannot change it. This
+## is OK from our viewpoint since HostBoot does not need to modify
+## the command reg.
+##
+sub sendCommand( $ )
+{
+ my ( $data ) = @_;
+ my $cmd = "";
+
+ ##$$ VBU_Cacheline::CLwrite( $commandreg, $cmd );
+
+ ## Use STKFAC here to clear the command reg- GMB2EC is mailbox scratchpad 3.
+ $cmd = "simSTKFAC " .
+ "B0.C0.S0.P0.E8.TPC.FSI.FSI_MAILBOX.FSXCOMP." .
+ "FSXLOG.LBUS_MAILBOX.Q_GMB2EC.NLC.L2 0 32 -quiet ";
+
+ if ( $opt_debug ) { print STDERR __LINE__, "-- run $cmd ...\n"; }
+ ( system( $cmd ) == 0 )
+ or die "$cmd failed, $? : $! \n";
+
+
+ ## bump the clock a few so that the clear takes effect
+ ## vbu_cacheline does not take # of cycles, so just run a raw command
+ ## here.
+ $cmd = "simclock 10 -quiet";
+
+ if ( $opt_debug ) { print STDERR __LINE__, "-- run $cmd ...\n"; }
+ ( system( $cmd ) == 0 )
+ or die "$cmd failed, $? : $! \n";
+
+
+ ## $data comes in as a 64-bit reg, we are only allowed 32 bits with
+ ## mailbox scoms, so we shift 32 bits here.
+ ## The lower 32 bits of the command reg are not used anyway.
+ my $cmd32 = ( ( $data & 0xffffffff00000000 ) >> 32 );
+ my $hexstr = sprintf( "0x%x", $cmd32 );
+
+ ## Use STKFAC here - GMB2EC is mailbox scratchpad 3.
+ $cmd = "simSTKFAC " .
+ "B0.C0.S0.P0.E8.TPC.FSI.FSI_MAILBOX.FSXCOMP." .
+ "FSXLOG.LBUS_MAILBOX.Q_GMB2EC.NLC.L2 $hexstr 32 -quiet";
+
+ if ( $opt_debug ) { print STDERR __LINE__, "-- run $cmd ...\n"; }
+ ( system( $cmd ) == 0 )
+ or die "$cmd failed, $? : $! \n";
+}
+
+
+##
+## get status using the status register.
+##
+sub getStatus()
+{
+ my $result = 0;
+ my $resultHi = 0;
+ my $resultLo = 0;
+ my $cmd = "";
+ my $hexresult = 0;
+
+ ## $$ mem $$ $result = VBU_Cacheline::CLread( $statusreg );
+
+ ## Use GetFac here for Hi status - GMB2E8 is mailbox scratchpad 2
+ $cmd = "simGETFAC B0.C0.S0.P0.E8.TPC.FSI.FSI_MAILBOX.FSXCOMP." .
+ "FSXLOG.LBUS_MAILBOX.Q_GMB2E8.NLC.L2 32";
+
+ if ( $opt_debug ) { print STDERR __LINE__, "-- run $cmd ...\n"; }
+ $resultHi = `$cmd` ;
+ ## print STDERR __LINE__, "=== raw resultHi=$resultHi ...\n";
+ $resultHi =~ s/.*\n0xr(.*)\n.*/$1/g;
+ $resultHi =~ s/\n//g;
+
+ ## Use GetFac here for Lo status - GMB2E4 is mailbox scratchpad 1
+ $cmd = "simGETFAC B0.C0.S0.P0.E8.TPC.FSI.FSI_MAILBOX.FSXCOMP." .
+ "FSXLOG.LBUS_MAILBOX.Q_GMB2E4.NLC.L2 32";
+
+ if ( $opt_debug ) { print STDERR __LINE__, "-- run $cmd ...\n"; }
+ $resultLo = `$cmd` ;
+ ## print STDERR __LINE__, "=== raw resultLo=$resultLo ...\n";
+ $resultLo =~ s/.*\n0xr(.*)\n.*/$1/g;
+ $resultLo =~ s/\n//g;
+
+ $result = sprintf( "0x%8.8x%8.8x", (hex "0x$resultHi"), (hex "0x$resultLo") );
+
+ $hexresult = hex $result;
+
+ if ( $opt_debug ) { printf STDERR "=== result=0x%lx ...\n", $hexresult; }
+
+ return $hexresult;
+}
+
+
+##
+## keep trying to get status until seqnum syncs up
##
sub getSyncStatus( )
{
# set # of retries
## @todo revisit
- my $count = 1000;
- my $result = 0;
- my $seqnum = 0;
+ 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.
+ ## number to come back.
while(1)
{
-
-
- ## advance HostBoot code by a certain # of cycles, then check the
+ ## advance HostBoot code by a certain # of cycles, then check the
## sequence number to see if it has changed. rinse and repeat.
- ## Note: RunClocks will start instructions
- VBU_Cacheline::RunClocks();
- system ("$hbToolsDir/hb-ContTrace --mute > /dev/null");
- system ("cat hb-ContTrace.output >> tracMERG");
+ ## Note: RunClocks will also start instructions
- ## Stop instructions, flush L2
- VBU_Cacheline::P8_Ins_Stop();
- VBU_Cacheline::P8_Flush_L2();
+ ## $$VBU_Cacheline::RunClocks();
+ runClocks();
-
- ## dump printk similar to the Jim McGuire's script
- ## NOPE, CRASHES AWAN dumpPrintk();
+ ## activate continuous trace
+ system ("$hbToolsDir/hb-ContTrace --mute > /dev/null" );
+ system ("cat hb-ContTrace.output >> tracMERG");
- ## check for system crash
- my ( $flag, $status ) = getShutDownStatus();
- if ( $flag )
- {
- print STDOUT "HostBoot has shut down with status $status";
- return -1;
- }
+ ## $$ for old memory-based regs, stop instructions, flush L2
+ ## $$ VBU_Cacheline::P8_Ins_Stop();
+ ## $$ VBU_Cacheline::P8_Flush_L2();
+ ## $$ VBU_Cacheline::CLread( $statusreg );
- $result = VBU_Cacheline::CLread( $statusreg );
+ ## Fetch status reg(s)
+ $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 100-200 clocks till
+ ## the bit turns on. If it doesn't go on, command was never received.
+ ## Then come here to wait for it to go back off again.
## if ( ( $running == 0 )
## && ( $seqnum == $g_SeqNum )
if ( $seqnum == $g_SeqNum )
{
return $result;
}
-
- if ($opt_debug)
- { printf STDERR __LINE__, "===== getSyncStatus: count=%d, result=0x%lx\n", $count, $result }
-
+
+ if ($opt_debug)
+ {
+ printf STDERR "=== getSyncStatus: count=%d, result=0x%lx\n", $count, $result ;
+ }
+
if ( $count <= 0 )
{
print STDOUT "TIMEOUT waiting for seqnum=$g_SeqNum\n";
return -1;
}
-
+
$count--;
- } ## endwhile
-
-}
+ } ## endwhile
+
+}
##
## Run an istep
@@ -546,20 +822,23 @@ sub runIStep( $$ )
my $byte0, my $command;
my $cmd;
my $result;
-
-
+
+
## bump the seqnum
bumpSeqNum();
-
+
printf STDOUT "run %d.%d %s:\n", $istep, $substep, $inList[$istep][$substep];
-
+
$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 );
- VBU_Cacheline::CLwrite( $commandreg, $cmd );
-
+ ## $$VBU_Cacheline::CLwrite( $commandreg, $cmd );
+
+ sendCommand( $cmd );
+
$result = getSyncStatus();
-
+
## if result is -1 we have a timeout
if ( $result == -1 )
{
@@ -573,7 +852,7 @@ sub runIStep( $$ )
my $istepStatus = ( ( $result & 0x00000000ffffffff ) );
print STDOUT "-----------------------------------------------------------------\n";
- ## printf STDOUT "Istep %d.%d Status: 0x%x\n", $stsIStep, $stsSubstep, $istepStatus ;
+ ## printf STDOUT "Istep %d.%d Status: 0x%x\n", $stsIStep, $stsSubstep, $istepStatus ;
if ( $taskStatus != 0 )
{
if ( $taskStatus == 11 )
@@ -582,50 +861,50 @@ sub runIStep( $$ )
}
else
{
- printf STDOUT "Istep %d.%d FAILED to launch, task status is %d\n",
- $stsIStep, $stsSubstep, $taskStatus ;
+ printf STDOUT "Istep %d.%d %s FAILED to launch, task status is %d\n",
+ $stsIStep, $stsSubstep,
+ $inList[$istep][$substep],
+ $taskStatus ;
}
}
else
- {
- printf STDOUT "Istep %d.%d returned Status: 0x%x", $stsIStep, $stsSubstep, $istepStatus ;
+ {
+ printf STDOUT "Istep %d.%d %s returned Status: 0x%x\n",
+ $stsIStep, $stsSubstep,
+ $inList[$istep][$substep],
+ $istepStatus ;
if ( $istepStatus == 0xa )
{
- printf STDOUT ": not implemented yet.\n";
- }
- else
- {
- printf STDOUT "\n";
+ printf STDOUT ": not implemented yet.\n";
}
}
-
+
print STDOUT "-------------------------------------------------------------- $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<$#inList; $j++ )
+ for( $j=0; $j<MAX_SUBSTEPS; $j++ )
{
- ## print "-----------------"
##print STDOUT "run IStep %d %s ...\n", $i, $inList[$i][$j] );
- ##print "-----------------"
+
if ( defined( $inList[$i][$j] ) )
{
runIStep( $i, $j );
}
}
}
-
+
##
## parse --command [command] option and execute it.
##
@@ -636,40 +915,40 @@ sub parse_command( $ )
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);
+
+ ## 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 STDERR __LINE__, "===== s command : ", $command, ":\n"; }
+ if ($opt_debug) { print STDERR __LINE__, "=== s command : ", $command, ":\n"; }
substr( $command, 0, 1, "" );
-
+
if ( isdigit( $command ) )
{
# command = "sN"
- if ($opt_debug) { print STDERR __LINE__, "===== single IStep: ", $command, "\n"; }
- sCommand( $command );
+ if ($opt_debug) { print STDERR __LINE__, "=== single IStep: ", $command, "\n"; }
+ sCommand( $command );
}
else
{
# list of substeps = "sM..N"
( $M, $N ) = split( /\.\./, $command );
-
- if ($opt_debug) { print STDERR "===== multiple ISteps: ", $M, "-", $N, "\n"; }
+
+ if ($opt_debug) { print STDERR "=== 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 STDERR __LINE__, "===== named commands : ", @ss_list, "\n"; }
-
+ @ss_list = split( /\.\./, $command );
+
+ if ($opt_debug) { print STDERR __LINE__, "=== named commands : ", @ss_list, "\n"; }
+
( $istepM, $substepM, $foundit) = find_in_inList( $ss_list[0] );
$istepN = $istepM;
$substepN = $substepM;
@@ -678,10 +957,10 @@ sub parse_command( $ )
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 )
{
@@ -689,7 +968,7 @@ sub parse_command( $ )
return -1;
}
}
-
+
## print "got it, running isteps:\n";
for( my $x=$istepM; $x<$istepN+1; $x++ )
{
@@ -702,55 +981,74 @@ sub parse_command( $ )
}
}
}
-
- }
+
+ }
}
##
-## write to scratch reg 3 to set istep or normal mode, check return status
-##
+## write IStepModeReg in memory to set istep or fsp mode, check return status
+## This does not write to a scom reg, I don't have one to write to.
+##
sub setMode( $ )
{
my ( $cmd ) = @_;
-
- my $count = 1000;
+
+ my $count = $hbCount;
my $expected = 0;
my $readybit = 0;
my $result = 0;
-
+ my $hexstr = sprintf( "%x",$IstepModeReg );
+
+
+ ## check to make sure that system is stopped and flushed.
+ my $qstr = VBU_Cacheline::P8_Ins_Query();
+ if ( $qstr ne "STOPPED" )
+ {
+ ## Stop instructions, flush L2
+ VBU_Cacheline::P8_Ins_Stop();
+ VBU_Cacheline::P8_Flush_L2();
+ }
- if ( $cmd eq "istep" )
+ if ( $cmd eq "spless" )
{
- VBU_Cacheline::CLwrite( $istepmodereg, "0x4057b0074057b007" );
- $expected = 1;
+ ## $$ VBU_Cacheline::CLwrite( $IstepModeReg, "0x4057b0074057b007" );
+
+ VBU_Cacheline::CLwrite( $hexstr, SPLESS_MODE_SIGNATURE );
+ $expected = 1;
}
- elsif ( $cmd eq "normal" )
+ elsif ( $cmd eq "fsp" )
{
- VBU_Cacheline::CLwrite( $istepmodereg, "0x700b7504700b7504" );
- $expected = 0;
+ ##$$VBU_Cacheline::CLwrite( $IstepModeReg, "0x700b7504700b7504" );
+
+ VBU_Cacheline::CLwrite( $hexstr, FSP_MODE_SIGNATURE );
+ $expected = 1;
}
else
- {
+ {
print "invalid setMode command: %s\n", $cmd ;
return -1;
- }
-
- if ( $opt_debug )
+ }
+
+ if ( $opt_debug )
{
- ## readback and display
- $result = VBU_Cacheline::CLread( $istepmodereg );
- printf STDERR __LINE__, "===== istepmodereg readback: 0x%lx\n", $result ;
+ ## readback and display
+ ##$result = VBU_Cacheline::CLread( $IstepModeReg );
+ $result = VBU_Cacheline::CLread( $hexstr );
+ printf STDERR "=== istepmodereg readback: 0x%lx\n", $result ;
}
-
+
## Loop, advancing clock, and wait for readybit
## @todo revisit
while(1)
{
- ## advance HostBoot code by a certain # of cycles, then check the
+ ## 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();
- system ("$hbToolsDir/hb-ContTrace --mute > /dev/null");
+ ## $$VBU_Cacheline::RunClocks();
+ runClocks( );
+
+ ## activate continuous trace
+ system ("$hbToolsDir/hb-ContTrace --mute > /dev/null" );
system ("cat hb-ContTrace.output >> tracMERG");
## Stop instructions, flush L2
@@ -758,36 +1056,38 @@ sub setMode( $ )
VBU_Cacheline::P8_Flush_L2();
-
## check for system crash
- my ( $flag, $status ) = getShutDownStatus();
- if ( $flag )
+ if ( isShutDown( ) )
{
- print STDOUT "HostBoot has shut down with status $status";
+ print STDOUT "HostBoot has shut down.";
return -1;
}
-
- $result = VBU_Cacheline::CLread( $statusreg );
-
+
+ ## $$$result = VBU_Cacheline::CLread( $statusreg );
+ $result = getStatus( );
+
$readybit = ( ( $result & 0x4000000000000000 ) >> 62 );
-
- if ($opt_debug)
- { printf STDERR __LINE__, "===== setMode: count=%d, result=0x%lx, readybit=0x%x\n", $count, $result, $readybit }
+
+ if ($opt_debug)
+ {
+ printf STDERR "=== 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--;
- }
+ }
}
@@ -800,12 +1100,13 @@ sub resume_istep()
bumpSeqNum(); ## bump
- printf STDOUT "resume from breakpoint\n";
+ print STDOUT "resume from breakpoint\n";
$byte0 = 0x80 + $g_SeqNum; ## gobit + seqnum
$command = SPLESS_RESUME_ISTEP_CMD;
$cmd = sprintf( "0x%2.2x%2.2x000000000000", $byte0, $command );
- VBU_Cacheline::CLwrite( $commandreg, $cmd );
+ ## $$ VBU_Cacheline::CLwrite( $commandreg, $cmd );
+ sendCommand( $cmd );
## dgxx
while(1)
@@ -858,7 +1159,7 @@ sub resume_istep()
$stsIStep, $stsSubstep, $istepStatus ;
last;
}
-
+
## continue to wait for istep to complete
}
@@ -872,18 +1173,20 @@ 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 );
- VBU_Cacheline::CLwrite( $commandreg, $cmd );
-
+
+ ## $$ VBU_Cacheline::CLwrite( $commandreg, $cmd );
+ sendCommand( $cmd );
+
$result = getSyncStatus();
-
+
## if result is -1 we have a timeout
if ( $result == -1 )
{
@@ -894,9 +1197,9 @@ sub clear_trace( )
print STDOUT "---------------------------------------------------------------\n";
print STDOUT "Trace Buffers Cleared.\n" ;
}
-
+
print STDOUT "---------------------------------------------------------------\n";
-}
+}
diff --git a/src/usr/initservice/istepdispatcher/makefile b/src/usr/initservice/istepdispatcher/makefile
index d2e094b5a..eaae9b9ea 100644
--- a/src/usr/initservice/istepdispatcher/makefile
+++ b/src/usr/initservice/istepdispatcher/makefile
@@ -5,7 +5,7 @@
#
# IBM CONFIDENTIAL
#
-# COPYRIGHT International Business Machines Corp. 2011
+# COPYRIGHT International Business Machines Corp. 2011 - 2012
#
# p1
#
@@ -19,13 +19,12 @@
#
# Origin: 30
#
-# IBM_PROLOG_END
-
+# IBM_PROLOG_END_TAG
ROOTPATH = ../../../..
MODULE = istepdisp
-OBJS = istepdispatcher.o initsvcudistep.o \
- sptask.o
+OBJS = istepdispatcher.o initsvcudistep.o \
+ sptask.o splesscommon.o
## SUBDIRS = test.d
diff --git a/src/usr/initservice/istepdispatcher/splesscommon.C b/src/usr/initservice/istepdispatcher/splesscommon.C
new file mode 100644
index 000000000..9dc615a24
--- /dev/null
+++ b/src/usr/initservice/istepdispatcher/splesscommon.C
@@ -0,0 +1,286 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/initservice/istepdispatcher/splesscommon.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 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
+ */
+/**
+ * @file splesscommon.C
+ *
+ * Routines to access SPLESS Command and
+ * and SPLESS Status interfaces
+ *
+ * Currently SPLess only supports the one command 0x00, this rewrite will
+ * allow support of other SPLess commands.
+ *
+ */
+
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+// $$$$$$$ undefine this before checking in....
+// #define SPLESS_DEBUG 1
+
+#ifdef SPLESS_DEBUG
+ #include <kernel/console.H> // printk DEBUG
+#endif
+
+#include <sys/mmio.h> // mmio_scratch_read()
+#include <devicefw/userif.H> // deviceRead(), deviceWrite()
+
+#include <targeting/common/attributes.H> // ISTEP_MODE attribute
+#include <targeting/common/targetservice.H>
+
+#include "splesscommon.H"
+
+
+// external reference
+namespace INITSERVICE
+{
+ extern trace_desc_t *g_trac_initsvc;
+} // end namespace INITSERVICE
+
+
+
+namespace SPLESS
+{
+
+using namespace TARGETING;
+
+// extern declarations for regs.
+extern uint64_t g_SPLess_Command_Reg;
+extern uint64_t g_SPLess_Status_Reg;
+
+extern uint64_t g_SPLess_IStepMode_Reg;
+
+/**
+ * @def g_SPLess_pMasterProcChip
+ *
+ * pointer to master proc chip used for deviceRead deviceWrite
+ */
+TARGETING::Target* g_SPLess_pMasterProcChip = NULL;
+
+
+/******************************************************************************/
+// SPLESS support functions
+/******************************************************************************/
+
+bool SPLessAttached( )
+{
+ bool l_rc = false;
+
+ // check for IStep Mode signature(s)
+ if ( g_SPLess_IStepMode_Reg == ISTEP_MODE_SPLESS_SIGNATURE )
+ {
+ l_rc = true;
+ }
+
+ return l_rc;
+}
+
+
+void initIStepMode( )
+{
+ using namespace TARGETING;
+ uint64_t l_readData = 0;
+ Target *l_pTopLevel = NULL;
+ TargetService& l_targetService = targetService();
+
+ (void) l_targetService.getTopLevelTarget(l_pTopLevel);
+ if (l_pTopLevel == NULL)
+ {
+ TRACFCOMP( INITSERVICE::g_trac_initsvc, "Top level handle was NULL" );
+ // drop through, default of attribute is is false
+ }
+ else
+ {
+ // got a pointer to Targeting, complete setting the flag
+ // $$ save l_readData = mmio_scratch_read( MMIO_SCRATCH_IPLSTEP_CONFIG );
+ l_readData = g_SPLess_IStepMode_Reg;
+
+#ifdef SPLESS_DEBUG
+ printk( "IStepMode Reg = 0x%p, 0x%lx\n", &g_SPLess_IStepMode_Reg, l_readData );
+ printk( "Status Reg = 0x%p\n", &g_SPLess_Status_Reg );
+ printk( "Command Reg = 0x%p\n", &g_SPLess_Command_Reg );
+#endif
+ TRACDCOMP( INITSERVICE::g_trac_initsvc,
+ "IStepMode Reg = 0x%llx",
+ l_readData );
+
+ // check for IStep Mode signature(s)
+ if ( ( l_readData == ISTEP_MODE_SPLESS_SIGNATURE )
+ || ( l_readData == ISTEP_MODE_FSP_SIGNATURE )
+ )
+ {
+ l_pTopLevel->setAttr<ATTR_ISTEP_MODE> (true );
+
+ TRACDCOMP( INITSERVICE::g_trac_initsvc,
+ "ISTEP_MODE attribute set to TRUE." );
+ }
+ else
+ {
+ // If not either of the above, set to run-all
+ l_readData = RUN_ALL_MODE_SIGNATURE;
+ // $$ save mmio_scratch_write( MMIO_SCRATCH_IPLSTEP_CONFIG, l_readData );
+ l_pTopLevel->setAttr<ATTR_ISTEP_MODE> ( false );
+
+ TRACDCOMP( INITSERVICE::g_trac_initsvc,
+ "ISTEP_MODE attribute set to FALSE." );
+ }
+ }
+
+}
+
+/******************************************************************************/
+// SPLESS Command functions
+/******************************************************************************/
+
+void readCmd( SPLessCmd &io_rcmd )
+{
+ // Do this once and save it...
+ if ( g_SPLess_pMasterProcChip == NULL )
+ {
+ (void)TARGETING::targetService().masterProcChipTargetHandle(
+ g_SPLess_pMasterProcChip );
+ }
+
+ // $$ save - mem io_rcmd.val64 = g_SPLess_Command_Reg;
+ // $$ save -io_rcmd.val64 = mmio_scratch_read(MMIO_SCRATCH_IPLSTEP_COMMAND);
+
+ // command reg is GMB2EC is mailbox scratchpad 3 { regs 0 - 3 }.
+ size_t op_size = sizeof( uint64_t );
+ DeviceFW::deviceRead(
+ g_SPLess_pMasterProcChip,
+ &(io_rcmd.val64),
+ op_size,
+ DEVICE_SCOM_ADDRESS( MBOX_SCRATCH_REG3 ) );
+
+#ifdef SPLESS_DEBUG
+ printk( "readCmd hi 0x%x\n", io_rcmd.hi32 );
+ printk( "readCmd lo 0x%x\n", io_rcmd.lo32 );
+#endif
+}
+
+
+void writeCmd( SPLessCmd &io_rcmd )
+{
+ // Do this once and save it...
+ if ( g_SPLess_pMasterProcChip == NULL )
+ {
+ (void)TARGETING::targetService().masterProcChipTargetHandle(
+ g_SPLess_pMasterProcChip );
+ }
+
+ // save - mem g_SPLess_Command_Reg = io_rcmd.val64;
+ // save mmio_scratch_write( MMIO_SCRATCH_IPLSTEP_COMMAND, io_rcmd.val64 );
+
+ // command reg is GMB2EC is mailbox scratchpad 3 { regs 0 - 3 }.
+ size_t op_size = sizeof( uint64_t );
+ DeviceFW::deviceWrite(
+ g_SPLess_pMasterProcChip,
+ &(io_rcmd.val64),
+ op_size,
+ DEVICE_SCOM_ADDRESS( MBOX_SCRATCH_REG3 ) );
+
+#ifdef SPLESS_DEBUG
+ printk( "writeCmd hi 0x%x\n", io_rcmd.hi32 );
+ printk( "writeCmd lo 0x%x\n", io_rcmd.lo32 );
+#endif
+}
+
+
+/******************************************************************************/
+// SPLESS Status
+/******************************************************************************/
+
+void readSts( SPLessSts &io_rsts )
+{
+ // Do this once and save it...
+ if ( g_SPLess_pMasterProcChip == NULL )
+ {
+ (void)TARGETING::targetService().masterProcChipTargetHandle(
+ g_SPLess_pMasterProcChip );
+ }
+
+ // $$ save - mem io_rsts.val64 = g_SPLess_Status_Reg;
+ // $$ io_rsts.val64 = mmio_scratch_read(MMIO_SCRATCH_IPLSTEP_STATUS);
+
+ // status reg (Hi 32) is now GMB2E8 is mailbox scratchpad 2 {regs 0 - 3 }
+ size_t op_size = sizeof( uint64_t );
+ DeviceFW::deviceRead(
+ g_SPLess_pMasterProcChip,
+ &(io_rsts.val64),
+ op_size,
+ DEVICE_SCOM_ADDRESS( MBOX_SCRATCH_REG2 ) );
+ // status reg lo is GMB2E4 - mailbox scratchpad 1 { regs 0 -3 }
+ uint64_t swap = 0;
+ DeviceFW::deviceRead(
+ g_SPLess_pMasterProcChip,
+ &(swap),
+ op_size,
+ DEVICE_SCOM_ADDRESS( MBOX_SCRATCH_REG1 ) );
+ io_rsts.lo32 =
+ static_cast<uint32_t>( ((swap >> 32) & 0x00000000ffffffff) );
+
+#ifdef SPLESS_DEBUG
+ printk( "readSts hi 0x%x\n", io_rsts.hi32 );
+ printk( "readSts lo 0x%x\n", io_rsts.lo32 );
+#endif
+}
+
+
+void writeSts( SPLessSts &io_rsts )
+{
+ // Do this once and save it...
+ if ( g_SPLess_pMasterProcChip == NULL )
+ {
+ (void)TARGETING::targetService().masterProcChipTargetHandle(
+ g_SPLess_pMasterProcChip );
+ }
+
+ // $$ save - mem g_SPLess_Status_Reg = io_rsts.val64;
+ // $$ save mmio_scratch_write( MMIO_SCRATCH_IPLSTEP_STATUS, io_rsts.val64 );
+ size_t op_size = sizeof( uint64_t );
+ DeviceFW::deviceWrite(
+ g_SPLess_pMasterProcChip,
+ &(io_rsts.val64),
+ op_size,
+ DEVICE_SCOM_ADDRESS( MBOX_SCRATCH_REG2 ) );
+ // status reg lo is GMB2E4 - mailbox scratchpad 1 { regs 0 -3 }
+ uint64_t swap =
+ ((static_cast<uint64_t>(io_rsts.lo32) << 32 ) & 0xffffffff00000000) ;
+ DeviceFW::deviceWrite(
+ g_SPLess_pMasterProcChip,
+ &(swap),
+ op_size,
+ DEVICE_SCOM_ADDRESS( MBOX_SCRATCH_REG1 ) );
+
+#ifdef SPLESS_DEBUG
+ printk( "writeSts hi 0x%x\n", io_rsts.hi32 );
+ printk( "writeSts lo 0x%x\n", io_rsts.lo32 );
+#endif
+}
+
+} // namespace
+
diff --git a/src/usr/initservice/istepdispatcher/splesscommon.H b/src/usr/initservice/istepdispatcher/splesscommon.H
index 6d5d84953..3dd0f9030 100644
--- a/src/usr/initservice/istepdispatcher/splesscommon.H
+++ b/src/usr/initservice/istepdispatcher/splesscommon.H
@@ -1,26 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/initservice/istepdispatcher/splesscommon.H $
-//
-// 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
-
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/initservice/istepdispatcher/splesscommon.H $
+ *
+ * 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
+ */
#ifndef __ISTEPDISP_SPLESS_COMMON_H
#define __ISTEPDISP_SPLESS_COMMON_H
/**
@@ -41,32 +41,19 @@
#include <stdio.h>
#include <string.h>
-// $$$$$$$ undefine this before checking in....
-// #define SPLESS_DEBUG 1
-
-#ifdef SPLESS_DEBUG
- #include <kernel/console.H> // printk DEBUG
-#endif
-
#include <sys/mmio.h> // mmio_scratch_read()
+#include <devicefw/userif.H> // deviceRead(), deviceWrite()
#include <targeting/common/attributes.H> // ISTEP_MODE attribute
#include <targeting/common/targetservice.H>
-// external reference
-namespace INITSERVICE
-{
- extern trace_desc_t *g_trac_initsvc;
-} // end namespace INITSERVICE
-
-
/******************************************************************************/
// SPLESS Command and Status Prototypes
/******************************************************************************/
/**
- * @namespace SPLESSCMD
+ * @namespace SPLESS
*
* Contains functions to manipulate the SPLESS Command Register
*
@@ -74,14 +61,14 @@ namespace INITSERVICE
namespace SPLESS
{
-/**
- * @note Since ISTEP_MODE attribute is nonvolatile (persists across boots),
- * we must have a way to turn the attribute both ON and OFF - we
- * cannot depend on the FSP to do it since we may not have a FSP.
- */
const uint64_t ISTEP_MODE_SPLESS_SIGNATURE = 0x4057b0074057b007;
const uint64_t ISTEP_MODE_FSP_SIGNATURE = 0x700b7504700b7504;
const uint64_t RUN_ALL_MODE_SIGNATURE = 0xBADC0FFEE0DDF00D;
+const uint32_t MBOX_SCRATCH_REG0 = 0x00050038;
+const uint32_t MBOX_SCRATCH_REG1 = 0x00050039;
+const uint32_t MBOX_SCRATCH_REG2 = 0x0005003a;
+const uint32_t MBOX_SCRATCH_REG3 = 0x0005003b;
+
/**
* @enum
@@ -108,37 +95,6 @@ enum {
SPLESS_TRACE_BUFFERS_CLEARED = 16, // trace buffers cleared
};
-/**
- * @note declare global regs to implement SPLess.
- * These replace the SCOM regs that are accessed by mmio; the reason we
- * are changing this is that there is no support at present for read/writing
- * SCOM in the Debug Framework.
- * This will have to be modified again when we get to Secure Boot
- *
- * @todo An review issue came up about when and how these are updated -
- * While hostboot is running in SIMICS or VBU, the user console (i.e. a
- * perl script, see src/build/vpo/hb_istep) will stop the instruction clock,
- * write a command to g_SPLess_Command_Reg, and then restart the clock.
- *
- * Q1) In non-VPO mode (real FSP) are we always going to stop instructions
- * to the processor to modify these variables?
- * A: Yes, at this writing. If this changes, we should revisit this
- * implementation.
- *
- * Q1a) Do these memory locations need to be accessed atomically (i.e. using
- * __sync_add_and_fetch() and/or isync()/sync() )?
- * A: No, not at this writing.
- *
- * Q2) When we stop instructions to the processor is the instruction pipeline
- * and load/store queues flushed?
- *
- * A: No. The stop commands used in the simulator user console should
- * quiesce the processor; this should guarantee that there are no
- * outstanding loads or stores.
- */
-extern uint64_t g_SPLess_Command_Reg;
-extern uint64_t g_SPLess_Status_Reg;
-extern uint64_t g_SPLess_IStepMode_Reg;
/**
* @note SPLess commands, and masks for the status.
@@ -148,7 +104,6 @@ const uint8_t SPLESS_SINGLE_ISTEP_CMD = 0x00;
const uint8_t SPLESS_RESUME_ISTEP_CMD = 0x01;
const uint8_t SPLESS_CLEAR_TRACE_CMD = 0x02;
const uint8_t SPLESS_SHUTDOWN_CMD = 0x03;
-
const uint64_t SPLESS_SINGLE_STEP_STS_MASK = 0x00000000ffffffff;
/**
@@ -157,18 +112,7 @@ const uint64_t SPLESS_SINGLE_STEP_STS_MASK = 0x00000000ffffffff;
* @return nothing
*
*/
-inline bool SPLessAttached( )
-{
- bool l_rc = false;
-
- // check for IStep Mode signature(s)
- if ( g_SPLess_IStepMode_Reg == ISTEP_MODE_SPLESS_SIGNATURE )
- {
- l_rc = true;
- }
-
- return l_rc;
-}
+bool SPLessAttached( );
/**
* @brief init ISTEP_MODE attribute
@@ -176,57 +120,7 @@ inline bool SPLessAttached( )
* @return nothing
*
*/
-inline void initIStepMode( )
-{
- using namespace TARGETING;
- uint64_t l_readData = 0;
- Target *l_pTopLevel = NULL;
- TargetService& l_targetService = targetService();
-
- (void) l_targetService.getTopLevelTarget(l_pTopLevel);
- if (l_pTopLevel == NULL)
- {
- TRACFCOMP( INITSERVICE::g_trac_initsvc, "Top level handle was NULL" );
- // drop through, default of attribute is is false
- }
- else
- {
- // got a pointer to Targeting, complete setting the flag
- // $$ save l_readData = mmio_scratch_read( MMIO_SCRATCH_IPLSTEP_CONFIG );
- l_readData = g_SPLess_IStepMode_Reg;
-
-#ifdef SPLESS_DEBUG
- printk( "IStepMode Reg = 0x%p, 0x%lx\n", &g_SPLess_IStepMode_Reg, l_readData );
- printk( "Status Reg = 0x%p\n", &g_SPLess_Status_Reg );
- printk( "Command Reg = 0x%p\n", &g_SPLess_Command_Reg );
-#endif
- TRACDCOMP( INITSERVICE::g_trac_initsvc,
- "IStepMode Reg = 0x%llx",
- l_readData );
-
- // check for IStep Mode signature(s)
- if ( ( l_readData == ISTEP_MODE_SPLESS_SIGNATURE )
- || ( l_readData == ISTEP_MODE_FSP_SIGNATURE )
- )
- {
- l_pTopLevel->setAttr<ATTR_ISTEP_MODE> (true );
-
- TRACDCOMP( INITSERVICE::g_trac_initsvc,
- "ISTEP_MODE attribute set to TRUE." );
- }
- else
- {
- // If not either of the above, set to run-all
- l_readData = RUN_ALL_MODE_SIGNATURE;
- // $$ save mmio_scratch_write( MMIO_SCRATCH_IPLSTEP_CONFIG, l_readData );
- l_pTopLevel->setAttr<ATTR_ISTEP_MODE> ( false );
-
- TRACDCOMP( INITSERVICE::g_trac_initsvc,
- "ISTEP_MODE attribute set to FALSE." );
- }
- }
-
-}
+void initIStepMode( );
/**
* @struct CommandHdr
@@ -261,7 +155,12 @@ struct CommandHdr
*/
union SPLessCmd
{
- uint64_t val64;
+ uint64_t val64;
+ struct
+ {
+ uint32_t hi32;
+ uint32_t lo32;
+ } __attribute__((packed));
struct
{
CommandHdr hdr;
@@ -282,15 +181,7 @@ union SPLessCmd
*
* @return none
*/
-inline void readCmd( SPLessCmd &io_rcmd )
-{
-
- // $$ save io_rcmd.val64 = mmio_scratch_read(MMIO_SCRATCH_IPLSTEP_COMMAND);
- io_rcmd.val64 = g_SPLess_Command_Reg;
-#ifdef SPLESS_DEBUG
- printk( "readCmd 0x%lx\n", g_SPLess_Command_Reg );
-#endif
-}
+void readCmd( SPLessCmd &io_rcmd );
/**
@@ -303,15 +194,7 @@ inline void readCmd( SPLessCmd &io_rcmd )
*
* @return none
*/
-inline void writeCmd( SPLessCmd &io_rcmd )
-{
-
- // $$ save mmio_scratch_write( MMIO_SCRATCH_IPLSTEP_COMMAND, io_rcmd.val64 );
- g_SPLess_Command_Reg = io_rcmd.val64;
-#ifdef SPLESS_DEBUG
- printk( "writeCmd 0x%lx\n", g_SPLess_Command_Reg );
-#endif
-}
+void writeCmd( SPLessCmd &io_rcmd );
@@ -358,7 +241,12 @@ struct StatusHdr
*
*/
union SPLessSts {
- uint64_t val64;
+ uint64_t val64;
+ struct
+ {
+ uint32_t hi32;
+ uint32_t lo32;
+ } __attribute((packed));
struct {
StatusHdr hdr;
uint8_t istep;
@@ -378,15 +266,8 @@ union SPLessSts {
*
* @return none.
*/
-inline void readSts( SPLessSts &io_rsts )
-{
+void readSts( SPLessSts &io_rsts );
- // $$ save io_rsts.val64 = mmio_scratch_read(MMIO_SCRATCH_IPLSTEP_STATUS);
- io_rsts.val64 = g_SPLess_Status_Reg;
-#ifdef SPLESS_DEBUG
- printk( "readSts 0x%lx\n", g_SPLess_Status_Reg );
-#endif
-}
/**
* @brief Write a filled in SPLessSts struct to the SPLess Status Reg
@@ -395,14 +276,8 @@ inline void readSts( SPLessSts &io_rsts )
*
* @return none
*/
-inline void writeSts( SPLessSts &io_rsts )
-{
- // $$ save mmio_scratch_write( MMIO_SCRATCH_IPLSTEP_STATUS, io_rsts.val64 );
- g_SPLess_Status_Reg = io_rsts.val64;
-#ifdef SPLESS_DEBUG
- printk( "writeSts 0x%lx\n", g_SPLess_Status_Reg );
-#endif
-}
+void writeSts( SPLessSts &io_rsts );
+
} // namespace
diff --git a/src/usr/initservice/istepdispatcher/sptask.C b/src/usr/initservice/istepdispatcher/sptask.C
index 946aad7df..34d8a013a 100644
--- a/src/usr/initservice/istepdispatcher/sptask.C
+++ b/src/usr/initservice/istepdispatcher/sptask.C
@@ -1,26 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/initservice/istepdispatcher/sptask.C $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 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
-
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/initservice/istepdispatcher/sptask.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 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
+ */
/**
* @file sptask.C
*
@@ -254,8 +254,12 @@ void userConsoleComm( void * io_msgQ )
}
// clear command reg, including go bit (i.e. set to false)
- l_cmd.val64 = 0;
- writeCmd( l_cmd );
+ // 2012-04-27 hb-istep will clear the command reg after it sees
+ // the running bit turn on.
+ // Please save the following in case we have to turn this
+ // back on.
+ // $$ l_cmd.val64 = 0;
+ // $$ writeCmd( l_cmd );
} // endif gobit
@@ -283,9 +287,6 @@ void userConsoleComm( void * io_msgQ )
}
} // endwhile
- // free the message struct
- msg_free( l_pMsg );
-
// @note
// Fell out of loop, clear sts reg and turn off readybit
// disable the ready bit so the user knows.
@@ -297,6 +298,9 @@ void userConsoleComm( void * io_msgQ )
TRACFCOMP( g_trac_initsvc,
"userConsoleComm exit" );
+ // free the message struct
+ msg_free( l_pMsg );
+
// return to main to end task
}
OpenPOWER on IntegriCloud