summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Gilbert <dgilbert@us.ibm.com>2012-01-25 11:52:29 -0600
committerDouglas R. Gilbert <dgilbert@us.ibm.com>2012-02-03 13:24:03 -0600
commit73a45c77486bc82475c8d24739d1212ab8d9cfad (patch)
tree4aa321357ef984a696a68c2c9e75144927a01bdb
parent672ca9b23baf4923d74152fec4872b5207f96de8 (diff)
downloadtalos-hostboot-73a45c77486bc82475c8d24739d1212ab8d9cfad.tar.gz
talos-hostboot-73a45c77486bc82475c8d24739d1212ab8d9cfad.zip
istep breakpoint support
Change-Id: I592c617963f810209a9ab76345a8c568d14af62c Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/629 Tested-by: Jenkins Server Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com>
-rwxr-xr-xsrc/build/simics/hb-simdebug.py38
-rwxr-xr-xsrc/build/vpo/hb-istep61
-rw-r--r--src/include/usr/hwpf/fapi/fapiUtil.H11
-rw-r--r--src/include/usr/initservice/initsvcbreakpoint.H44
-rw-r--r--src/usr/hwpf/plat/fapiPlatUtil.C6
-rw-r--r--src/usr/hwpf/test/hwpftest.H15
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.C110
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.H17
-rw-r--r--src/usr/initservice/istepdispatcher/splesscommon.H6
9 files changed, 292 insertions, 16 deletions
diff --git a/src/build/simics/hb-simdebug.py b/src/build/simics/hb-simdebug.py
index 4e5dbb2ee..af1a425c3 100755
--- a/src/build/simics/hb-simdebug.py
+++ b/src/build/simics/hb-simdebug.py
@@ -92,6 +92,7 @@ def hb_istep_usage():
print " sN..M - execute IStep N through M"
print " <name1>..<name2> - execute named isteps name1 through name2"
print " debug - enable debugging messages"
+ print " resume - Resume istep execution from break point"
return None
## declare GLOBAL g_SeqNum var, & a routine to manipulate it.
@@ -310,7 +311,35 @@ def runIStep( istep, substep, inList ):
print "-----------------------------------------------------------------"
return
-
+
+def resume_istep():
+
+ bump_g_SeqNum()
+
+ print "resume from breakpoint"
+
+ byte0 = 0x80 + g_SeqNum ## gobit + seqnum
+ command = 0x01
+ cmd = "0x%2.2x%2.2x_000000000000"%(byte0, command)
+ sendCommand( cmd )
+ result = getSyncStatus()
+
+ ## if result is -1 we have a timeout
+ if ( result == -1 ) :
+ print "-----------------------------------------------------------------"
+ else :
+ taskStatus = ( ( result & 0x00ff000000000000 ) >> 48 )
+
+ print "-----------------------------------------------------------------"
+ if ( taskStatus != 0 ) :
+ print "resume Istep FAILED, task status is %d"%( taskStatus )
+ else:
+ print "resume Istep was successful"
+ print "-----------------------------------------------------------------"
+
+ return
+
+
## run command = "sN"
def sCommand( inList, scommand ) :
@@ -355,6 +384,7 @@ def find_in_inList( inList, substepname) :
## sN
## sN..M
## <substepname1>..<substepname2>
+## resume
## declare GLOBAL g_IStep_DEBUG & SPLess memory mapped regs
g_IStep_DEBUG = 0
@@ -425,7 +455,11 @@ def istepHB( symsFile, str_arg1 ):
if ( str_arg1 == "list" ): ## dump command list
print_istep_list( inList )
return
-
+
+ if ( str_arg1 == "resume" ): ## resume from break point
+ resume_istep()
+ return None
+
## check to see if we have an 's' command (string starts with 's' and a number)
if ( re.match("^s+[0-9].*", str_arg1 ) ):
## run "s" command
diff --git a/src/build/vpo/hb-istep b/src/build/vpo/hb-istep
index 2cae8e617..ba4630a14 100755
--- a/src/build/vpo/hb-istep
+++ b/src/build/vpo/hb-istep
@@ -67,6 +67,7 @@ sub print_istep_list;
sub find_in_inlist;
sub parse_command;
sub setMode;
+sub resume_istep;
#------------------------------------------------------------------------------
# Constants
@@ -86,6 +87,7 @@ my $opt_command = "";
my $opt_list = 0;
my $opt_help = 0;
my $opt_cmdfile = 0; ## batchmode, later
+my $opt_resume = 0; ## resume istep from break point
my @inList;
$inList[10][10] = ();
@@ -135,7 +137,8 @@ GetOptions( "help" => \$opt_help,
"normalmode" => \$opt_normalmode,
"list" => \$opt_list,
"command=s" => \$opt_command,
- "cmdfile" => \$opt_cmdfile,
+ "cmdfile" => \$opt_cmdfile,
+ "resume" => \$opt_resume,
"debug" => \$opt_debug,
);
@@ -188,6 +191,15 @@ if ( $opt_list )
}
##
+## Process resume
+##
+if ( $opt_resume )
+{
+ resume_istep();
+ ## exit; ??
+}
+
+##
## process --Istep Mode command
## IStepModeStr = "cpu0_0_0_3->scratch=0x4057b007_4057b007"
## NormalModeStr = "cpu0_0_0_3->scratch=0x700b7504_700b7504"
@@ -212,7 +224,8 @@ if ( $opt_command ne "" )
if ( $opt_debug ) { print STDOUT "== process command \"$opt_command\" \n"; }
parse_command( $opt_command );
}
-
+
+
#==============================================================================
# SUBROUTINES
@@ -230,6 +243,7 @@ sub printUsage()
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 "\n" ;
@@ -562,4 +576,45 @@ sub setMode( )
}
}
-__END__ \ No newline at end of file
+sub resume_istep()
+{
+ my $byte0;
+ my $command;
+ my $cmd;
+ my $result;
+
+ $g_SeqNum++; ## bump
+
+ printf STDOUT "resume istep\n";
+
+ $byte0 = 0x80 + $g_SeqNum; ## gobit + seqnum
+ $command = 0x01;
+ $cmd = sprintf( "0x%2.2x%2.2x000000000000", $byte0, $command );
+ VBU_Cacheline::CLwrite( $commandreg, $cmd );
+
+ $result = getSyncStatus();
+
+ ## if result is -1 we have a timeout
+ if ( $result == -1 )
+ {
+ print "-----------------------------------------------------------------\n";
+ }
+ else
+ {
+ my $taskStatus = ( ( $result & 0x00ff000000000000 ) >> 48 );
+
+ print STDOUT "-----------------------------------------------------------------\n";
+ if ( $taskStatus != 0 )
+ {
+ # This probably means istep was not at a breakpoint.
+ printf STDOUT "resume istep FAILED, task status is %d\n", $taskStatus ;
+ }
+ else
+ {
+ printf STDOUT "resume istep returned success\n" ;
+ }
+ print STDOUT "-----------------------------------------------------------------\n";
+ }
+}
+
+__END__
diff --git a/src/include/usr/hwpf/fapi/fapiUtil.H b/src/include/usr/hwpf/fapi/fapiUtil.H
index 51a8a6dcc..23d34caf5 100644
--- a/src/include/usr/hwpf/fapi/fapiUtil.H
+++ b/src/include/usr/hwpf/fapi/fapiUtil.H
@@ -169,6 +169,17 @@ fapi::ReturnCode fapiLoadInitFile(const fapi::Target & i_Target,
fapi::ReturnCode fapiUnloadInitFile(const char * i_file, const char *& io_addr,
size_t & io_size);
+/** @brief Set a break point in the current procedure
+ *
+ * This function will suspend the calling istep/procedure.
+ * The procedure can be signaled to resume via a cmd through the
+ * istep dispatcher.
+ * @param[in] i_target reference to the target
+ * @param[in] i_info location/info @TODO of the breakpoint
+ */
+
+void fapiBreakPoint(const fapi::Target & i_target, uint64_t i_info);
+
}
namespace fapi
diff --git a/src/include/usr/initservice/initsvcbreakpoint.H b/src/include/usr/initservice/initsvcbreakpoint.H
new file mode 100644
index 000000000..e273b7f74
--- /dev/null
+++ b/src/include/usr/initservice/initsvcbreakpoint.H
@@ -0,0 +1,44 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/include/usr/initservice/initsvcbreakpoint.H $
+//
+// 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
+#if !defined(INITSVCBREAKPOINT_H)
+#define INITSVCBREAKPOINT_H
+
+#include <stdint.h>
+
+namespace fapi
+{
+ class Target;
+};
+
+namespace INITSERVICE
+{
+ /**
+ * Signal that a break point has been hit during an istep
+ * @param[in] i_target, target information
+ * @param[in] i_info, other information/location of bp (TBD @TODO)
+ * @returns nothing
+ * @note Blocks until an outside cmd to resume has been received
+ */
+ void iStepBreakPoint(const fapi::Target & i_target, uint64_t i_info);
+};
+#endif
diff --git a/src/usr/hwpf/plat/fapiPlatUtil.C b/src/usr/hwpf/plat/fapiPlatUtil.C
index 2f155bccd..58b83db0c 100644
--- a/src/usr/hwpf/plat/fapiPlatUtil.C
+++ b/src/usr/hwpf/plat/fapiPlatUtil.C
@@ -35,6 +35,7 @@
#include <errl/errlmanager.H>
#include <fapiPlatHwpInvoker.H>
#include <vfs/vfs.H>
+#include <initservice/initsvcbreakpoint.H>
//******************************************************************************
@@ -193,4 +194,9 @@ fapi::ReturnCode fapiUnloadInitFile(const char * i_file, const char *& io_addr,
return l_rc;
}
+void fapiBreakPoint(const fapi::Target & i_target, uint64_t i_info)
+{
+ INITSERVICE::iStepBreakPoint(i_target, i_info);
+}
+
}
diff --git a/src/usr/hwpf/test/hwpftest.H b/src/usr/hwpf/test/hwpftest.H
index 4776ea41e..c087ed0ca 100644
--- a/src/usr/hwpf/test/hwpftest.H
+++ b/src/usr/hwpf/test/hwpftest.H
@@ -622,6 +622,21 @@ public:
}
}
}
+
+
+// // unit test breakpoint
+// void testHwpf7()
+// {
+// fapi::Target fapiTarget;
+// FAPI_INF("AT breakpoint");
+// fapiBreakPoint(fapiTarget,__LINE__);
+//
+// // requires outside hb-istep resume command to continue
+//
+// FAPI_INF("RESUME from breakpoint");
+// }
+
+
};
#endif
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C
index 0ad8333f2..2777208ee 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.C
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C
@@ -420,12 +420,14 @@ void IStepDispatcher::processSingleIStepCmd(
*
* @return none
*/
-void IStepDispatcher::singleStepISteps( void * io_ptr ) const
+void IStepDispatcher::singleStepISteps( void * io_ptr )
{
SPLessCmd l_cmd;
SPLessSts l_sts;
uint8_t l_seqnum = 0;
+ mutex_lock(&iv_poll_mutex); // make sure this is only poller
+
// initialize command reg
l_cmd.val64 = 0;
writeCmd( l_cmd );
@@ -455,13 +457,19 @@ void IStepDispatcher::singleStepISteps( void * io_ptr ) const
{
switch( l_cmd.hdr.cmdnum )
{
- case SPLESS_SINGLE_ISTEP_CMD:
- // command 0: run istep/substep
- processSingleIStepCmd( l_cmd, l_sts );
- break;
-
- default:
- l_sts.hdr.status = SPLESS_INVALID_COMMAND;
+ case SPLESS_SINGLE_ISTEP_CMD:
+ mutex_unlock(&iv_poll_mutex);
+ // command 0: run istep/substep
+ processSingleIStepCmd( l_cmd, l_sts );
+ mutex_lock(&iv_poll_mutex);
+ break;
+
+ case SPLESS_RESUME_ISTEP_CMD: // not at break point here
+ l_sts.hdr.status = SPLESS_NOT_AT_BREAK_POINT;
+ break;
+
+ default:
+ l_sts.hdr.status = SPLESS_INVALID_COMMAND;
} // endif switch
l_sts.hdr.seqnum = l_seqnum;
@@ -508,6 +516,7 @@ void IStepDispatcher::singleStepISteps( void * io_ptr ) const
l_sts.hdr.status = SPLESS_TASKRC_TERMINATED;
l_sts.hdr.seqnum = l_seqnum;
writeSts( l_sts );
+ mutex_unlock(&iv_poll_mutex);
}
@@ -693,4 +702,89 @@ IStepDispatcher::IStepDispatcher()
IStepDispatcher::~IStepDispatcher()
{ }
+void IStepDispatcher::handleBreakPoint(const fapi::Target & i_target, uint64_t i_info)
+{
+ SPLessCmd l_cmd;
+ SPLessSts l_sts;
+ uint8_t l_seqnum = 0;
+
+ // need to be the only poller
+ mutex_lock(&iv_poll_mutex);
+
+ // init command reg
+ l_cmd.val64 = 0;
+ writeCmd ( l_cmd );
+
+ // init status reg, enable ready bit
+ l_sts.val64 = 0;
+ l_sts.hdr.readybit = true;
+ writeSts( l_sts );
+
+ // TODO Tell the outside world that a break point has been hit?
+ // TODO send i_target & i_info
+
+ // Poll for cmd to resume
+ while(1)
+ {
+ readCmd( l_cmd );
+ l_seqnum = l_cmd.hdr.seqnum;
+
+ if( l_cmd.hdr.gobit)
+ {
+ // only expect this command
+ if (l_cmd.hdr.cmdnum == SPLESS_RESUME_ISTEP_CMD)
+ {
+ l_sts.hdr.seqnum = l_seqnum;
+ writeSts( l_sts );
+ l_cmd.val64 = 0;
+ writeCmd( l_cmd );
+ break; // return to continue istep
+ }
+ else // all other commands are not valid here.
+ {
+ l_sts.hdr.status = SPLESS_AT_BREAK_POINT;
+
+ // write status
+ l_sts.hdr.seqnum = l_seqnum;
+ writeSts( l_sts );
+
+ // clear cmd reg, including go bit
+ l_cmd.val64 = 0;
+ writeCmd( l_cmd );
+ }
+ }
+
+
+
+ // TODO want to do the same kind fo delay as IStepDispatcher::singleStepISteps()
+ /**
+ * @todo Need a common method of doing delays in HostBoot
+ * @VBU workaround
+ */
+ // Don't delay as long in VBU because it will take VERY long to
+ // run the simulator
+ TARGETING::EntityPath syspath(TARGETING::EntityPath::PATH_PHYSICAL);
+ syspath.addLast(TARGETING::TYPE_SYS,0);
+ TARGETING::Target* sys = TARGETING::targetService().toTarget(syspath);
+ uint8_t vpo_mode = 0;
+ if( sys
+ && sys->tryGetAttr<TARGETING::ATTR_IS_SIMULATION>(vpo_mode)
+ && (vpo_mode == 1) )
+ {
+ // VBU delay per Patrick
+ nanosleep(0,TEN_CTX_SWITCHES_NS);
+ }
+ else
+ {
+ nanosleep( SINGLESTEP_PAUSE_S, SINGLESTEP_PAUSE_NS );
+ }
+ }
+ mutex_unlock(&iv_poll_mutex);
+}
+
+void iStepBreakPoint(const fapi::Target & i_target, uint64_t i_info)
+{
+ IStepDispatcher::getTheInstance().handleBreakPoint(i_target, i_info);
+}
+
} // namespace
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.H b/src/usr/initservice/istepdispatcher/istepdispatcher.H
index 48a8df18d..586caa9ec 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.H
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.H
@@ -53,6 +53,11 @@
#include "splesscommon.H"
+namespace fapi
+{
+ class Target;
+};
+
namespace INITSERVICE
{
@@ -99,6 +104,14 @@ public:
*/
void init( void *i_pargs);
+ /**
+ * @brief Handle an istep break point
+ * @param[in] i_target, the target
+ * @param[in] i_info, @TODO - location/info
+ * @note blocks until an outside istep cmd to resume is recieved.
+ */
+ void handleBreakPoint(const fapi::Target & i_target, uint64_t info);
+
protected:
/**
@@ -174,7 +187,7 @@ private:
*
* @return none
*/
- void singleStepISteps( void * io_ptr ) const;
+ void singleStepISteps( void * io_ptr );
/**
@@ -223,6 +236,8 @@ private:
// ----- internal vars -----------------------------
+ mutex_t iv_poll_mutex; //!< protect who's polling istep cmds
+
}; // class IStepDispatcher
diff --git a/src/usr/initservice/istepdispatcher/splesscommon.H b/src/usr/initservice/istepdispatcher/splesscommon.H
index 3cda0986c..3699b4360 100644
--- a/src/usr/initservice/istepdispatcher/splesscommon.H
+++ b/src/usr/initservice/istepdispatcher/splesscommon.H
@@ -95,6 +95,8 @@ enum {
SPLESS_TASKRC_TERMINATED = -6, // terminated the polling loop
SPLESS_INVALID_COMMAND = 10, // invalid command from user console
+ SPLESS_AT_BREAK_POINT = 11, // invalid command at breakpoint
+ SPLESS_NOT_AT_BREAK_POINT = 12, // resume command w/o breakpoint
};
/**
@@ -130,11 +132,11 @@ extern uint64_t g_SPLess_Status_Reg;
extern uint64_t g_SPLess_IStepMode_Reg;
/**
- * @note SPLess commands, and masks for the status. Currently we only
- * support one command through the SPLess interface.
+ * @note SPLess commands, and masks for the status.
*
*/
const uint8_t SPLESS_SINGLE_ISTEP_CMD = 0x00;
+const uint8_t SPLESS_RESUME_ISTEP_CMD = 0x01;
const uint64_t SPLESS_SINGLE_STEP_STS_MASK = 0x00000000ffffffff;
/**
OpenPOWER on IntegriCloud