diff options
author | Mark Wenning <wenning@us.ibm.com> | 2012-05-08 11:54:54 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-05-09 10:16:55 -0500 |
commit | 7362a70f4b11b12578c938cb40a0143f6bfeda7d (patch) | |
tree | 342889696f84719e381ce8956ca144043ec05a6e | |
parent | cd9263254cacd7948aad8ba1bd3a98af469b02af (diff) | |
download | talos-hostboot-7362a70f4b11b12578c938cb40a0143f6bfeda7d.tar.gz talos-hostboot-7362a70f4b11b12578c938cb40a0143f6bfeda7d.zip |
hb-istep SCOM changes.
Modifies vpo/hb-istep to communicate over Mailbox SCOM addresses
instead of memory, in an effort to increase VPO performance.
RTC: 38307
Change-Id: I020886bb2c6cf974a87b8a16d2be2b257f8d9757
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1040
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rwxr-xr-x | src/build/vpo/VBU_Cacheline.pm | 12 | ||||
-rwxr-xr-x | src/build/vpo/hb-istep | 907 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/makefile | 9 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/splesscommon.C | 286 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/splesscommon.H | 223 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/sptask.C | 60 |
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 } |