diff options
Diffstat (limited to 'src/usr')
| -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 |
5 files changed, 143 insertions, 11 deletions
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; /** |

