diff options
author | Doug Gilbert <dgilbert@us.ibm.com> | 2012-01-25 11:52:29 -0600 |
---|---|---|
committer | Douglas R. Gilbert <dgilbert@us.ibm.com> | 2012-02-03 13:24:03 -0600 |
commit | 73a45c77486bc82475c8d24739d1212ab8d9cfad (patch) | |
tree | 4aa321357ef984a696a68c2c9e75144927a01bdb | |
parent | 672ca9b23baf4923d74152fec4872b5207f96de8 (diff) | |
download | talos-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-x | src/build/simics/hb-simdebug.py | 38 | ||||
-rwxr-xr-x | src/build/vpo/hb-istep | 61 | ||||
-rw-r--r-- | src/include/usr/hwpf/fapi/fapiUtil.H | 11 | ||||
-rw-r--r-- | src/include/usr/initservice/initsvcbreakpoint.H | 44 | ||||
-rw-r--r-- | src/usr/hwpf/plat/fapiPlatUtil.C | 6 | ||||
-rw-r--r-- | src/usr/hwpf/test/hwpftest.H | 15 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/istepdispatcher.C | 110 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/istepdispatcher.H | 17 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/splesscommon.H | 6 |
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; /** |