summaryrefslogtreecommitdiffstats
path: root/src/usr/initservice/istepdispatcher
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/initservice/istepdispatcher')
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.C546
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.H135
-rw-r--r--src/usr/initservice/istepdispatcher/isteplist.H81
-rw-r--r--src/usr/initservice/istepdispatcher/makefile3
-rw-r--r--src/usr/initservice/istepdispatcher/splesscommand.C113
-rw-r--r--src/usr/initservice/istepdispatcher/splesscommon.H269
-rw-r--r--src/usr/initservice/istepdispatcher/splessstatus.C93
7 files changed, 1060 insertions, 180 deletions
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C
index 5dfb5a53e..002cc59d4 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.C
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C
@@ -24,7 +24,9 @@
/**
* @file istepdispatcher.C
*
- * IStep Dispatcher interface. Launched from Extended Initialization Service
+ * IStep Dispatcher code. Launched from Extended Initialization Service
+ *
+ * PNOR Driver and Trace should be available by the time this is launched.
*
*/
@@ -36,12 +38,18 @@
#include <stdio.h>
#include <string.h>
-#include <sys/task.h> // tid_t, task_create, etc
-#include <trace/interface.H> // trace support
-#include <errl/errlentry.H> // errlHndl_t
+#include <sys/task.h> // tid_t, task_create, etc
+#include <sys/time.h> // nanosleep
+#include <trace/interface.H> // trace support
+#include <errl/errlentry.H> // errlHndl_t
+#include <devicefw/userif.H> // targeting
+#include <sys/mmio.h> // mmio_scratch_read()
#include "istepdispatcher.H"
-#include "isteplist.H"
+
+#include "splesscommon.H"
+
+#include <isteps/isteplist.H>
namespace INITSERVICE
@@ -53,102 +61,502 @@ namespace INITSERVICE
extern trace_desc_t *g_trac_initsvc;
/**
- * @brief set up _start() task entry procedure using the macro
+ * @enum
+ * SPLess Task return codes
+ *
+ * task return codes for SPless single step
+ * @note future errors will be passed from task_create() and task_exec()
+ * and should be documented in errno.h
+ *
+ */
+enum {
+ SPLESS_TASKRC_INVALID_ISTEP = -3, // invalid istep or substep
+ SPLESS_TASKRC_LAUNCH_FAIL = -4, // failed to launch the task
+ SPLESS_TASKRC_RETURNED_ERRLOG = -5, // istep returned an errorlog
+ SPLESS_TASKRC_TERMINATED = -6, // terminated the polling loop
+};
+
+/**
+ * @note SPLess PAUSE - These two constants are used in a nanosleep() call
+ * below to sleep between polls of the StatusReg. Typically this will
+ * be about 100 ms - the actual value will be determined empirically.
+ *
+ * @debug simics "feature" - set polling time to 1 sec for demo
+ *
+ */
+
+const uint64_t SINGLESTEP_PAUSE_S = 1;
+const uint64_t SINGLESTEP_PAUSE_NS = 100000000;
+
+
+/**
+ * @brief set up _start() task entry procedure using the macro in taskargs.H
*/
TASK_ENTRY_MACRO( IStepDispatcher::getTheInstance().init );
-IStepDispatcher::IStepDispatcher()
-: iv_istepmodeflag(false),
- iv_nextistep( 0 ),
- iv_cancontinueflag(false)
+const TaskInfo *IStepDispatcher::findTaskInfo( const uint16_t i_IStep,
+ const uint16_t i_SubStep ) const
{
+ const TaskInfo *l_pistep = NULL;
+
+ TRACDCOMP( g_trac_initsvc,
+ "g_isteps[%d].numitems = 0x%x",
+ i_IStep,
+ g_isteps[i_IStep].numitems );
+
+ // apply filters
+ do
+ {
+
+ // check input range - IStep
+ if ( i_IStep >= MAX_ISTEPS )
+ {
+ TRACDCOMP( g_trac_initsvc,
+ "IStep 0x%x out of range.",
+ i_IStep );
+ break; // break out with l_pistep set to NULL
+ }
+
+ // check input range - ISubStep
+ if ( i_SubStep >= g_isteps[i_IStep].numitems )
+ {
+ TRACDCOMP( g_trac_initsvc,
+ "IStep 0x%x Substep 0x%x out of range.",
+ i_IStep,
+ i_SubStep );
+ break; // break out with l_pistep set to NULL
+ }
+
+ // check for end of list.
+ if ( g_isteps[i_IStep].pti[i_SubStep].taskflags.task_type
+ == END_TASK_LIST )
+ {
+ TRACDCOMP( g_trac_initsvc,
+ "IStep 0x%x SubSStep 0x%x task_type==END_TASK_LIST.",
+ i_IStep,
+ i_SubStep );
+ break;
+ }
+
+ // looks good, send it back to the caller
+ TRACDCOMP( g_trac_initsvc,
+ "Found TaskInfo 0x%x 0x%x",
+ i_IStep,
+ i_SubStep );
+ l_pistep = &( g_isteps[i_IStep].pti[i_SubStep] );
+ } while ( 0 );
+
+ return l_pistep;
}
-IStepDispatcher::~IStepDispatcher()
+void IStepDispatcher::init( void * io_ptr )
{
+ TRACFCOMP( g_trac_initsvc,
+ ENTER_MRK "starting IStepDispatcher, io_ptr=%p ",
+ io_ptr );
+
+ if ( getIStepMode() )
+ {
+ TRACFCOMP( g_trac_initsvc,
+ "IStep single-step" );
+ // IStep single-step
+ singleStepISteps( io_ptr );
+ }
+ else
+ {
+ TRACFCOMP( g_trac_initsvc,
+ "IStep run all" );
+ // Run all the ISteps sequentially
+ runAllISteps( io_ptr );
+ } // endelse
+
+
+ TRACFCOMP( g_trac_initsvc,
+ EXIT_MRK "IStepDispatcher finished.");
}
-IStepDispatcher& IStepDispatcher::getTheInstance()
+bool IStepDispatcher::getIStepMode( ) const
{
- return Singleton<IStepDispatcher>::instance();
+
+ return iv_istepmodeflag;
+}
+
+
+/**
+ * @todo revisit this when PNOR Driver is implemented
+ *
+ */
+void IStepDispatcher::initIStepMode( )
+{
+ uint64_t l_readData = 0;
+
+ l_readData = mmio_scratch_read( MMIO_SCRATCH_IPLSTEP_CONFIG );
+
+ TRACDCOMP( g_trac_initsvc,
+ "SCOM ScratchPad read, Offset 0x%x, Data 0x%llx",
+ MMIO_SCRATCH_IPLSTEP_CONFIG,
+ l_readData );
+
+ // check for IStep Mode signature
+ if ( l_readData == ISTEP_MODE_SIGNATURE )
+ {
+ iv_istepmodeflag = true;
+ }
+ else
+ {
+ iv_istepmodeflag = false;
+ }
+
}
-void IStepDispatcher::init( void * ptr )
+void IStepDispatcher::singleStepISteps( void * io_ptr ) const
{
- errlHndl_t errl = NULL;
- uint64_t nextIStep = 0;
- const TaskInfo *pistep = NULL;
- TaskArgs::TaskArgs args;
+ errlHndl_t l_errl = NULL;
+ TaskArgs::TaskArgs l_args;
+ const TaskInfo *l_pistep = NULL;
+ bool l_gobit = false;
+ uint16_t l_nextIStep = 0;
+ uint16_t l_nextSubstep = 0;
+ uint16_t l_taskStatus = 0;
+ uint16_t l_istepStatus = 0;
+ uint32_t l_progresscode = 0;
+ uint64_t l_isteprc = 0;
+
+ TRACFCOMP( g_trac_initsvc, "Start IStep single-step.\n" );
+
+ // initialize command reg
+ SPLESSCMD::write( false, // go bit is false
+ 0, // istep = 0
+ 0 ); // substep = 0
+
+ SPLESSSTS::write( false, // running bit
+ true, // ready bit
+ 0, // istep running
+ 0, // substep running
+ 0, // task status
+ 0 ); // istep status
+
+ //
+ // @note Start the polling loop.
+ // Currently this has no exit, user should reset the machine and/or
+ // load the payload, which will wipe HostBoot from memory.
+ // Loop forever, unless something Very Bad happens.
+ //
+ while( 1 )
+ {
+ // read command reg, updates l_gobit, l_nextIStep, l_nextSubstep
+ SPLESSCMD::read( l_gobit,
+ l_nextIStep,
+ l_nextSubstep );
- TRACFCOMP( g_trac_initsvc,
- ENTER_MRK "starting IStepDispatcher, ptr=%p. &args=%p",
- ptr, &args );
+ // process any commands
+ if ( l_gobit )
+ {
+ TRACDCOMP( g_trac_initsvc,
+ "gobit turned on, istep=0x%x, substep=0x%x",
+ l_nextIStep,
+ l_nextSubstep );
+
+ // look up istep+substep
+ l_pistep = findTaskInfo( l_nextIStep,
+ l_nextSubstep );
+ if ( l_pistep == NULL )
+ {
+ // no istep TaskInfo returned, update status & drop to end.
+ TRACFCOMP( g_trac_initsvc,
+ "Invalid IStep 0x%x / substep 0x%x, try again.",
+ l_nextIStep,
+ l_nextSubstep );
+ SPLESSSTS::write( false,
+ true,
+ l_nextIStep,
+ l_nextSubstep,
+ SPLESS_TASKRC_INVALID_ISTEP,
+ 0 );
+ }
+ else
+ {
+ // set running bit, fill in istep and substep
+ SPLESSSTS::write( true, // set running bit
+ true, // ready bit
+ l_nextIStep, // running istep
+ l_nextSubstep, // running substep
+ 0, // task status (=0)
+ 0 ); // istep status(=0)
+
+ /**
+ * @todo placeholder - set progress code before starting
+ * This will not be finalized until the progress code driver
+ * is designed and implemented.
+ */
+ l_progresscode = ( (l_nextIStep<<16) | l_nextSubstep );
+ InitService::getTheInstance().setProgressCode( l_progresscode );
+
+ // launch the istep
+ TRACDCOMP( g_trac_initsvc,
+ "execute Istep=0x%x / Substep=0x%x",
+ l_nextIStep,
+ l_nextSubStep );
+
+ // clear status, etc for the next istep
+ l_taskStatus = 0;
+ l_istepStatus = 0;
+ l_args.clear();
+
+ // launch the istep
+ l_errl = InitService::getTheInstance().executeFn( l_pistep,
+ &l_args );
+ // filter errors returning from executeFn
+ if ( l_errl )
+ {
+ // handle an errorlog from the parent. This means the
+ // launch failed, set the task Status to Bad.
+ // no need to process child info, thus the else.
+ // set the taskStatus to LAUNCH_FAIL; this will fall
+ // out the bottom and be written to SPLESS Status
+ l_taskStatus = SPLESS_TASKRC_LAUNCH_FAIL;
+ TRACFCOMP( g_trac_initsvc,
+ "ERROR 0x%x: function launch FAIL",
+ l_taskStatus );
+ errlCommit( l_errl );
+ }
+ else
+ {
+ // process information returned from the IStep.
+ // make local copies of the info; this has a secondary
+ // effect of clearing the errorlog pointer inside
+ // the TaskArgs struct.
+ l_isteprc = l_args.getReturnCode(); // local copy
+ l_errl = l_args.getErrorLog(); // local copy
+
+ TRACDCOMP( g_trac_initsvc,
+ "IStep TaskArgs return 0x%llx, errlog=%p",
+ l_isteprc,
+ l_errl );
+
+ // check for child errorlog
+ if ( l_errl )
+ {
+ // tell the user that the IStep returned an errorlog
+ l_taskStatus = SPLESS_TASKRC_RETURNED_ERRLOG;
+ // go ahead and commit the child errorlog
+ errlCommit( l_errl);
+ }
+
+ // massage the return code from the IStep -
+ // If the istep did not set an errorcode,
+ // then we report 0
+ if ( l_isteprc == TASKARGS_UNDEFINED64 )
+ {
+ l_istepStatus = 0;
+ }
+ else
+ {
+ // truncate IStep return status to 16 bits.
+ l_isteprc &= 0x000000000000ffff;
+ l_istepStatus = static_cast<uint16_t>(l_isteprc);
+ }
+
+ } // end else parent errlog
+
+ // l_taskStatus and l_istepStatus should be set correctly now,
+ // send it to the user.
+ // clear runningbit, report status
+ TRACDCOMP( g_trac_initsvc,
+ "Write IStep Status: istep=0x%x, substep=0x%x, taskstatus=0x%x, istepstatus=0x%x",
+ l_nextIStep,
+ l_nextSubstep,
+ l_taskStatus,
+ l_istepStatus );
+ SPLESSSTS::write( false, // clear running bit
+ true, // ready bit
+ l_nextIStep, // running istep
+ l_nextSubstep, // running substep
+ l_taskStatus, // task status
+ l_istepStatus // istepStatus
+ );
+
+ SPLESSCMD::setgobit( false ); // clear gobit
+ } // end else l_pistep
+ } // endif gobit
+
+ // sleep, and wait for user to give us something else to do.
+ nanosleep( SINGLESTEP_PAUSE_S, SINGLESTEP_PAUSE_NS );
+ } // endwhile
+
+
+ // @note
+ // Fell out of loop, clear sts reg and turn off readybit
+ // Currently this will never be reached. Later there may be
+ // a reason to break out of the loop, if this happens we want to
+ // disable the ready bit so the user knows.
+ SPLESSSTS::write( false,
+ false,
+ 0,
+ 0,
+ SPLESS_TASKRC_TERMINATED,
+ 0
+ );
+
+ // all errorlogs should have been committed in the loop, we should
+ // not have any errorlogs still set.
+ if ( l_errl )
+ {
+ // if we do then commit it and stop here.
+ errlCommit( l_errl );
+ assert(0);
+ }
+
+}
- for ( nextIStep=0;
- nextIStep<INITSERVICE::MAX_ISTEPS;
- nextIStep++ )
+
+void IStepDispatcher::runAllISteps( void * io_ptr ) const
+{
+ errlHndl_t l_errl = NULL;
+ uint16_t l_IStep = 0;
+ uint16_t l_SubStep = 0;
+ const TaskInfo *l_pistep = NULL;
+ TaskArgs::TaskArgs l_args;
+ uint64_t l_progresscode = 0;
+ uint64_t l_isteprc = 0;
+
+ for ( l_IStep=0;
+ l_IStep<INITSERVICE::MAX_ISTEPS;
+ l_IStep++ )
{
- pistep = &(g_isteps[nextIStep]);
- if ( pistep->taskflags.task_type == END_TASK_LIST )
+ for ( l_SubStep=0;
+ l_SubStep < INITSERVICE::MAX_SUBSTEPS;
+ l_SubStep++)
{
TRACDCOMP( g_trac_initsvc,
- "End of IStep list.\n" );
- break;
- }
+ "Find IStep=%d, SubStep=%d",
+ l_IStep,
+ l_SubStep );
+ l_pistep = findTaskInfo( l_IStep,
+ l_SubStep );
+ if ( l_pistep == NULL )
+ {
- args.clear(); // clear the args struct for the next istep
- errl = InitService::getTheInstance().executeFn( pistep,
- &args );
+ TRACDCOMP( g_trac_initsvc,
+ "End of ISubStep list." );
+ break; // break out of inner for loop
+ }
- // handle an errorlog from the parent, if it exists
- InitService::getTheInstance().reportError( errl );
+ // @todo placeholder until progress codes are defined and
+ // progress code driver is implemented.
+ l_progresscode = ( (l_IStep<<16) | l_SubStep );
+ InitService::getTheInstance().setProgressCode( l_progresscode );
- /**
- * @todo call getCanContinueProcedure when we have some ISteps that
- * require them.
- */
+ l_args.clear();
- if ( args.getReturnCode() != TASKARGS_UNDEFINED64 )
- {
TRACFCOMP( g_trac_initsvc,
- ERR_MRK "IStep TaskArgs returned 0x%llx, errlog=%p",
- args.getReturnCode(),
- args.getErrorLog()
- );
+ "Run IStep 0x%x / Substep 0x%x",
+ l_IStep,
+ l_SubStep );
+
+ l_errl = InitService::getTheInstance().executeFn( l_pistep,
+ &l_args );
+ if ( l_errl )
+ {
+ // Handle an errorlog from the parent, if it exists
+ // an error here is probably fatal, it means we can't
+ // launch the task or it doesn't exist. In either
+ // case we should exit the loop.
+ // Can't commit the errorlog here because we are using it
+ // as a flag to exit the loop.
+ break;
+ }
+
+ // make local copies of the status returned from the istep.
+ // note that this also removes the errorlog from the TaskArgs
+ // struct - it is read-once. See taskargs.H for details
+ l_isteprc = l_args.getReturnCode();
+ l_errl = l_args.getErrorLog();
+
+ TRACDCOMP( g_trac_initsvc,
+ "IStep TaskArgs returned 0x%llx, errlog=%p",
+ l_isteprc,
+ l_errl );
+ if ( l_errl )
+ {
+ // if we have an errorlog, break out of the inner loop
+ // and handle it.
+ break;
+ }
+ else
+ {
+ // Check child results for a valid nonzero return code.
+ // If we have one, and no errorlog, then we create an
+ // errorlog here.
+ if ( ( l_isteprc != TASKARGS_UNDEFINED64 )
+ && ( l_isteprc != 0 )
+ )
+ {
+ TRACFCOMP( g_trac_initsvc,
+ "istep returned 0x%llx, no errlog",
+ l_isteprc );
+
+ /*@ errorlog tag
+ * @errortype ERRL_SEV_CRITICAL_SYS_TERM
+ * @moduleid see task list
+ * @reasoncode ISTEP_FAILED_NO_ERRLOG
+ * @userdata1 returncode from istep
+ * @userdata2 0
+ *
+ * @devdesc The Istep returned with an error,
+ * but there was no errorlog posted
+ * from the IStep.
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM,
+ l_pistep->taskflags.module_id,
+ INITSERVICE::ISTEP_FAILED_NO_ERRLOG,
+ l_isteprc,
+ 0 );
+ // drop out of inner loop with errlog set.
+ break;
+ } // end if ( )
+ }
+ } // endfor l_SubStep
+
+ if ( l_errl )
+ {
+ // something left an error log in the inner loop, breakout
+ break;
}
+ } // endfor l_IStep
- // report an error from the child, if it exists.
- reportIStepErrorLog( pistep, args.getErrorLog() );
- } // endfor
+ /**
+ * @todo detect Can-Continue condition here and reset/rerun ISteps.
+ * For now this is pushed to a later sprint.
+ */
- TRACFCOMP( g_trac_initsvc,
- EXIT_MRK "IStepDispatcher finished.");
+ // Post any errorlogs. If one exists, stop here. Otherwise, return
+ // to caller.
+ if ( l_errl )
+ {
+ TRACFCOMP( g_trac_initsvc,
+ "ERROR: istep=0x%x, substep=0x%x, committing errorlog %p",
+ l_IStep,
+ l_SubStep,
+ l_errl );
+ errlCommit( l_errl );
+ assert( 0 );
+ }
}
-/**
- * @note IStep Mode is hardwired to false for now
- *
- * @todo revisit this when PNOR Driver is implemented
- */
-bool IStepDispatcher::getIStepMode( ) const
-{
-
- return false;
-}
-
-
bool IStepDispatcher::getCanContinueProcedure( const TaskInfo &i_failingIStep,
errlHndl_t &i_failingError,
@@ -159,11 +567,21 @@ bool IStepDispatcher::getCanContinueProcedure( const TaskInfo &i_failingIStep,
return false;
}
-void IStepDispatcher::reportIStepErrorLog( const TaskInfo *i_failingIStep,
- errlHndl_t io_errl )
+
+IStepDispatcher& IStepDispatcher::getTheInstance()
+{
+ return Singleton<IStepDispatcher>::instance();
+}
+
+
+IStepDispatcher::IStepDispatcher()
{
+ initIStepMode(); // set up internal flag
- InitService::getTheInstance().reportError( io_errl );
}
+
+IStepDispatcher::~IStepDispatcher()
+{ }
+
} // namespace
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.H b/src/usr/initservice/istepdispatcher/istepdispatcher.H
index 46f4f87e3..352b0f450 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.H
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.H
@@ -21,8 +21,8 @@
//
// IBM_PROLOG_END
-#ifndef __ISTEP_DISPATCHER_H
-#define __ISTEP_DISPATCHER_H
+#ifndef __ISTEPDISPATCHER_ISTEPDISPATCHER_H
+#define __ISTEPDISPATCHER_ISTEPDISPATCHER_H
/**
* @file istepdispatcher.H
*
@@ -34,21 +34,22 @@
/******************************************************************************/
// Includes
/******************************************************************************/
-#include <stdint.h>
-#include <sys/vfs.h> // VFS_MODULE_NAME_MAX
+#include <stdint.h>
+#include <util/singleton.H>
-#include <errl/errlentry.H>
-#include <initservice/taskargs.H>
-#include <initservice/initsvcreasoncodes.H>
+#include <errl/errlentry.H>
+#include <initservice/taskargs.H>
+#include <initservice/initsvcreasoncodes.H>
+#include <initservice/initsvcstructs.H>
-#include "../baseinitsvc/initservice.H"
-#include "../common/initsvcstructs.H"
+#include "../baseinitsvc/initservice.H"
+
+#include "splesscommon.H"
namespace INITSERVICE
{
-
/******************************************************************************/
// Globals/Constants
/******************************************************************************/
@@ -58,7 +59,7 @@ namespace INITSERVICE
/******************************************************************************/
/******************************************************************************/
-// Class
+// Class IStepDispatcher
/******************************************************************************/
/**
@@ -85,6 +86,8 @@ public:
*
* @param[in] i_pargs pointer to any arguments passed in from
* _start().
+ *
+ * @return nothing
*/
void init( void *i_pargs);
@@ -109,51 +112,115 @@ private:
IStepDispatcher(const IStepDispatcher& i_right);
IStepDispatcher& operator=(const IStepDispatcher& i_right);
+
/**
- * @brief getIStepMode
- * call into PNOR and fetch the "IStepMode flag" .
- * This will tell us if we are locked to the SP (IStepMode=ON) or
- * can run all the ISteps available (IStepMode=OFF).
+ * @brief init iv_istepmode flag, called in constructor
+ *
+ * Call into PNOR and fetch the "IStepMode flag" .
+ *
+ * @todo currently this calls into the kernel to get the value of
+ * an SCOM Scratch Reg - this will change when PNOR is finished
+ *
+ * @return nothing
*
- * @return false if IStep Mode is "OFF"
+ */
+ void initIStepMode( );
+
+
+ /**
+ * @brief getIStepMode - return value of IStep Mode
+ *
+ * @return bool - value of iv_istepmodeflag
+ * @retval false if IStep Mode is "OFF"
* true if IStep Mode is "ON"
*/
- bool getIStepMode( ) const;
+ bool getIStepMode( ) const;
+
+
+ /**
+ * @brief Find a TaskInfo struct in the global istep list(s),
+ * addressed by { IStep, SubStep }
+ *
+ *
+ * @param[in] i_IStep - IStepNumber
+ * @param[in] i_SubStep - SubStepNumber
+ *
+ * @return pointer to a TaskInfo struct
+ * @retval pointer to a TaskInfo struct, or NULL
+ *
+ */
+ const TaskInfo *findTaskInfo( uint16_t i_IStep,
+ uint16_t i_SubStep ) const;
+
+
+ /**
+ * @brief singleStepISteps
+ *
+ * Stop and wait for SP to send the next IStep to run. Run that, then
+ * wait for the next one.
+ * This is not expected to return - errors etc are sent to the user to
+ * handle.
+ *
+ * @param[in,out] io_ptr - pointer to any args passed in from
+ * ExtInitSvc. This may be a pointer to an
+ * TaskArgs struct (or something else) which
+ * can be filled out on return
+ *
+ * @return none
+ */
+ void singleStepISteps( void * io_ptr ) const;
+
+
+ /**
+ * @brief runAllISteps
+ *
+ * Run all available ISteps sequentially.
+ * If an IStep gets an error, report it and stop.
+ * Otherwise, return.
+ *
+ * @param[in,out] io_ptr - pointer to a TaskArgs struct on input
+ * command, returncode and errorlog will be
+ * clear on input
+ * one or more may be filled in on return
+ *
+ * @return none
+ */
+ void runAllISteps( void * io_ptr ) const;
/**
* @brief getCanContinueProcedure
* If an IStep fails, this routine will fetch the recovery procedure
+ * This is only used in "normal" mode, it will not be used when IStep Mode
+ * is ON (i.e. it will not be used when single-stepping).
*
- * @param[in] reference to IStepInfo struct for failing Istep
- * @param[in] reference to errorlog for the failure
- * @param[in,out] reference to IStepInfo struct for next IStep to run
+ * @param[in] i_failingIStep - ref to IStepInfo struct for failing
+ * Istep
+ * @param[in] i_failingError - ref to errorlog for the failure
+ * @param[in,out] io_nextIStep - ref to TaskInfo struct for next
+ * IStep to run. struct will be filled
+ * out with info on the next IStep to
+ * run.
*
- * @return false if there is no Can-Continue procedure
+ * @return bool
+ * @retval false if there is no Can-Continue procedure,
* true otherwise
*
+ * @todo 2011-08-22 currently the defs for this procedure are pretty
+ * vague - requirements for Can-Continue behaviour have not been
+ * defined yet.
*/
bool getCanContinueProcedure( const TaskInfo &i_failingIStep,
errlHndl_t &i_failingError,
- TaskInfo &io_nextIstep ) const;
-
- /**
- * @brief reportIStepErrorLog
- * If an IStep returns an error log, commit it.
- *
- * @todo Later there may be some decision about whether to report it
- * based on the IStep.
- */
- void reportIStepErrorLog( const TaskInfo *i_failingIStep,
- errlHndl_t io_errl );
+ TaskInfo &io_nextIStep ) const;
+ // ----- internal vars -----------------------------
bool iv_istepmodeflag;
- uint64_t iv_nextistep;
- bool iv_cancontinueflag;
}; // class IStepDispatcher
+
} // namespace
#endif
diff --git a/src/usr/initservice/istepdispatcher/isteplist.H b/src/usr/initservice/istepdispatcher/isteplist.H
deleted file mode 100644
index 612fde725..000000000
--- a/src/usr/initservice/istepdispatcher/isteplist.H
+++ /dev/null
@@ -1,81 +0,0 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/initservice/istepdispatcher/isteplist.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
-
-#ifndef __ISTEPS_H
-#define __ISTEPS_H
-
-/**
- * @file isteplist.H
- *
- * TaskInfo structs for each task that will run in the extended image.
- */
-
-#include <initservice/initsvcreasoncodes.H>
-#include "istepdispatcher.H"
-#include "../../isteps/isteps.H"
-
-namespace INITSERVICE
-{
-
-const uint64_t MAX_ISTEPS = 25;
-
-const TaskInfo g_isteps[] = {
-
- // ----- ISteps Image ------------------------------------------
-
- /**
- * @brief targeting task, initializes extended module area
- */
- {
- "istep1" , // istep name
- ISTEPS::IStep1, // pointer to fn
- {
- NONE, // task type
- EXT_IMAGE, // Extended Module
- ISTEP_1_ERRL_ID, // module id
- }
- },
-
- // ---------------------------------------------------------------
- // ----- END OF LIST!!! ---------------------------------------
- // ---------------------------------------------------------------
-
- /**
- * @brief last task in the list
- */
- {
- "end" , // dummy string
- NULL, // pointer to fn
- {
- END_TASK_LIST, // end of list
- UNDEFINED_MT, // dummy module type
- UNDEFINED_MODULE_ERRL_ID, // dummy errorlog
- }
- },
-
-};
-
-
-}; // namespace
-
-#endif
diff --git a/src/usr/initservice/istepdispatcher/makefile b/src/usr/initservice/istepdispatcher/makefile
index 013c6a8f9..d18adfc4f 100644
--- a/src/usr/initservice/istepdispatcher/makefile
+++ b/src/usr/initservice/istepdispatcher/makefile
@@ -20,10 +20,11 @@
# Origin: 30
#
# IBM_PROLOG_END
+
ROOTPATH = ../../../..
MODULE = istepdisp
-OBJS = istepdispatcher.o
+OBJS = istepdispatcher.o splesscommand.o splessstatus.o
## SUBDIRS = test.d
diff --git a/src/usr/initservice/istepdispatcher/splesscommand.C b/src/usr/initservice/istepdispatcher/splesscommand.C
new file mode 100644
index 000000000..563a4be3a
--- /dev/null
+++ b/src/usr/initservice/istepdispatcher/splesscommand.C
@@ -0,0 +1,113 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/initservice/istepdispatcher/splesscommand.C $
+//
+// 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
+
+/**
+ * @file splesscommand.C
+ *
+ * Collection of routines to read/write the spless command reg
+ *
+ */
+
+
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <errl/errlentry.H> // errlHndl_t
+#include <sys/mmio.h> // mmio_scratch_read/write
+
+#include "splesscommon.H"
+
+
+/******************************************************************************/
+// Globals/Constants
+/******************************************************************************/
+
+/******************************************************************************/
+// Typedef/Enumerations
+/******************************************************************************/
+
+namespace SPLESSCMD
+{
+
+
+void read( bool &io_rgobit,
+ uint16_t &io_ristep,
+ uint16_t &io_rsubstep )
+{
+ InternalCommand l_cmd;
+
+ l_cmd.val64 = mmio_scratch_read(MMIO_SCRATCH_IPLSTEP_COMMAND);
+
+ io_rgobit = l_cmd.f.gobit;
+ io_ristep = l_cmd.f.istep;
+ io_rsubstep = l_cmd.f.substep;
+
+}
+
+
+void write( const bool i_gobit,
+ const uint16_t i_istep,
+ const uint16_t i_substep )
+{
+ InternalCommand l_cmd;
+
+ // copy into union
+ l_cmd.f.gobit = i_gobit;
+ l_cmd.f.istep = i_istep;
+ l_cmd.f.substep = i_substep;
+
+ mmio_scratch_write( MMIO_SCRATCH_IPLSTEP_COMMAND, l_cmd.val64 );
+
+}
+
+
+void getgobit( bool &o_rgobit )
+{
+ uint16_t l_istep = 0;
+ uint16_t l_substep = 0;
+
+ // re-use above call...
+ read( o_rgobit,
+ l_istep,
+ l_substep );
+
+}
+
+
+void setgobit( const bool i_gobit )
+{
+ InternalCommand l_cmd;
+
+ l_cmd.val64 = mmio_scratch_read( MMIO_SCRATCH_IPLSTEP_COMMAND);
+
+ l_cmd.f.gobit = i_gobit;
+
+ mmio_scratch_write( MMIO_SCRATCH_IPLSTEP_COMMAND, l_cmd.val64 );
+
+}
+
+} // namespace
diff --git a/src/usr/initservice/istepdispatcher/splesscommon.H b/src/usr/initservice/istepdispatcher/splesscommon.H
new file mode 100644
index 000000000..113d712fd
--- /dev/null
+++ b/src/usr/initservice/istepdispatcher/splesscommon.H
@@ -0,0 +1,269 @@
+// 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
+
+#ifndef __ISTEPDISP_SPLESS_COMMON_H
+#define __ISTEPDISP_SPLESS_COMMON_H
+/**
+ * @file splesscommon.H
+ *
+ * Prototypes for routines to access SPLESS Command and
+ * and SPLESS Status interfaces
+ *
+ */
+
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+/******************************************************************************/
+// Globals/Constants
+/******************************************************************************/
+const uint64_t ISTEP_MODE_SIGNATURE = 0x4057b0074057b007;
+
+/******************************************************************************/
+// SPLESS Command Prototypes
+/******************************************************************************/
+
+/**
+ * @namespace SPLESSCMD
+ *
+ * Contains functions to manipulate the SPLESS Command Register
+ * @todo overload these later to get command and seq fields
+ *
+ */
+namespace SPLESSCMD
+{
+
+/**
+ * @union InternalCommand
+ *
+ * define the fields within the 64-bit Command Register
+ *
+
+ * Bit numbers are in ppc notation, where bit 0 is the most significant bit.
+ * Go Bit : bit 0 (ppc notation, msbit)
+ * - set to 1 by the user to start the IStep
+ * - cleared to 0 by HostBoot
+ * Reserved: bit 1: always 0
+ * Sequence #: bits 2-7
+ * Command Number: bits 8:15 - always 0 (for now)
+ * Reserved: bits 16:31
+ * Reserved: bits 32:39 - always 0
+ * IStep Number: bits 40:47
+ * Substep Number: bits 48:63gobit:
+ *
+ */
+union InternalCommand
+{
+ uint64_t val64;
+ struct
+ {
+ bool gobit:1;
+ uint8_t reserved0:1;
+ uint8_t seqnum:6;
+ uint8_t cmdnum;
+
+ uint16_t reserved2;
+
+ uint16_t reserved3:2;
+ uint16_t istep:14;
+
+ uint16_t substep;
+ } f PACKED;
+
+ // init struct to 0
+ InternalCommand() : val64(0) {};
+} ;
+
+
+/**
+ * @brief Read the command register and return the necessary fields.
+ *
+ * @param[in,out] io_rgobit - ref to a gobit var that will be filled in
+ * on return
+ * @param[in,out] io_ristep - ref to a istep var that will be filled in
+ * on return
+ * @param[in,out] io_rsubstep - ref to a substep var that will be filled
+ * in on return
+ *
+ * @return pointer to errorlog
+ * @retval NULL if success, filled-in errorlog if failure
+ *
+ */
+void read( bool &io_rgobit,
+ uint16_t &io_ristep,
+ uint16_t &io_rsubstep );
+
+
+/**
+ * @brief Write all the necessary fields to the command reg.
+ *
+ * Normally the user writes the command reg; this is only used to
+ * init the command reg at the beginning
+ *
+ * @param[in] i_gobit - gobit value to write
+ * @param[in] i_istep - istep value to write
+ * @param[in] i_substep - substep value to write
+ *
+ * @return errorlog pointer
+ * @retval NULL if success, filled-in errorlog if failure
+ *
+ */
+void write( const bool i_gobit,
+ const uint16_t i_istep,
+ const uint16_t i_substep );
+
+
+/**
+ * @brief Read the gobit from the command register
+ *
+ * @param o_rgobit - ref to a gobit var that will be filled in
+ * on return.
+ *
+ * @return errorlog pointer
+ * @retval NULL if success, filled-in errorlog on failure
+ */
+void getgobit( bool &o_rgobit );
+
+
+/**
+ * @brief Write the gobit to the command register
+ *
+ * @param i_gobit - gobit value to be written
+ *
+ * @return pointer to errlog
+ * @retval NULL if success, filled-in errorlog on failure
+ */
+void setgobit( const bool i_gobit ) ;
+
+} // namespace
+
+
+/******************************************************************************/
+// SPLESS Status Prototypes
+/******************************************************************************/
+
+/**
+ * @namespace SPLESSSTS
+ *
+ * Contains functions to manipulate the SPLESS Status Register
+ * @todo overload these to get seq # later
+ *
+ */
+namespace SPLESSSTS
+{
+
+/**
+ * @union InternalStatus
+ *
+ * define the fields within the 64-bit status register
+ * Running bit, bit 0 (ppc notation, msbit):
+ * = 1 when IStep is running
+ * = 0 when IStep is finished
+ * Ready bit, bit 1:
+ * = 1 when IStep Dispatcher is ready to run individual ISteps
+ * = 0 if IStep Dispatcher is not ready:
+ * - System has not loaded the IStep Dispatcher yet
+ * - IStep Mode Flag = 0
+ * Sequence # : bits 2-7 - echoes the sequence number in the associated
+ * command frame.
+ * IStep Running, bits 8:15 - the IStep number that is currently running.
+ * Sub-step Running, bits 16:31 - the substep that is currently running.
+ * Task Status, bits 32:47 - the status that IStep Dispatcher returns when
+ * trying to run the task. For example:
+ * -3 IStep number is invalid
+ * -1, -2 (return code from kernel) IStep could not be launched as a
+ * task or as a function within a task
+ * IStep Status, bits 48:63 - status returned from the IStep.
+ *
+ */
+union InternalStatus {
+ uint64_t val64;
+ struct {
+ bool runningbit:1; // |
+ bool readybit:1; // |
+ uint8_t seqnum:6; // |
+ uint8_t istep; // | 16 bits
+ uint16_t substep; // 16 bits
+ uint16_t taskStatus; // 16 bits
+ uint16_t istepStatus; // 16 bits
+ } f PACKED;
+
+ // init struct to 0
+ InternalStatus() : val64(0) {};
+} ;
+
+
+
+/**
+ * @brief Read the SPLess Status SCOM Reg and return all its fields
+ *
+ * @param[in,out] io_rrunningbit - ref to runningbit var, to be
+ * filled in on return
+ * @param[in,out] io_rreadybit - ref to readybit var, to be filled in
+ * on return
+ * @param[in,out] io_ristep - ref to istep var, to be filled in on
+ * return
+ * @param[in,out] io_rsubstep - ref to substep var, to be filled in
+ * on return
+ * @param[in,out] io_rtaskStatus - ref to taskStatus var, to be filled
+ * in on return
+ * @param[in,out] io_ristepStatus - ref to istepStatus var, to be filled
+ * in on return
+ *
+ * @return none.
+ */
+void read( bool &io_rrunningbit,
+ bool &io_rreadybit,
+ uint16_t &io_ristep,
+ uint16_t &io_rsubstep,
+ uint16_t &io_rtaskStatus,
+ uint16_t &io_ristepStatus );
+
+/**
+ * @brief write
+ *
+ * Read the SPLess Status SCOM Reg and return all its fields
+ *
+ * @param[in] i_runningbit - runningbit val to write
+ * @param[in] i_readybit - readybit val to write
+ * @param[in] i_istep - istep val to write
+ * @param[in] i_substep - substep val to write
+ * @param[in] i_taskStatus - taskStatus val to write
+ * @param[in] i_istepStatus - istepStatus val to write
+ *
+ * @return none
+ */
+void write( const bool i_runningbit,
+ const bool i_readybit,
+ const uint16_t i_istep,
+ const uint16_t i_substep,
+ const uint16_t i_taskStatus,
+ const uint16_t i_istepStatus );
+
+} // namespace
+
+#endif
diff --git a/src/usr/initservice/istepdispatcher/splessstatus.C b/src/usr/initservice/istepdispatcher/splessstatus.C
new file mode 100644
index 000000000..30818778c
--- /dev/null
+++ b/src/usr/initservice/istepdispatcher/splessstatus.C
@@ -0,0 +1,93 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/initservice/istepdispatcher/splessstatus.C $
+//
+// 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
+/**
+ * @file splessstatus.C
+ *
+ * Routines to read and write spless status reg
+ *
+ */
+
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <errl/errlentry.H> // errlHndl_t
+#include <sys/mmio.h> // mmio_scratch_read/write
+
+#include "splesscommon.H"
+
+/******************************************************************************/
+// Globals/Constants
+/******************************************************************************/
+
+/******************************************************************************/
+// Typedef/Enumerations
+/******************************************************************************/
+
+
+void SPLESSSTS::read( bool &io_rrunningbit,
+ bool &io_rreadybit,
+ uint16_t &io_ristep,
+ uint16_t &io_rsubstep,
+ uint16_t &io_rtaskStatus,
+ uint16_t &io_ristepStatus )
+{
+ InternalStatus l_sts;
+
+ l_sts.val64 = mmio_scratch_read(MMIO_SCRATCH_IPLSTEP_STATUS);
+
+ // read was good
+ io_rrunningbit = l_sts.f.runningbit;
+ io_rreadybit = l_sts.f.readybit;
+ io_ristep = l_sts.f.istep;
+ io_rsubstep = l_sts.f.substep;
+ io_rtaskStatus = l_sts.f.taskStatus;
+ io_ristepStatus = l_sts.f.istepStatus;
+
+}
+
+
+void SPLESSSTS::write( const bool i_runningbit,
+ const bool i_readybit,
+ const uint16_t i_istep,
+ const uint16_t i_substep,
+ const uint16_t i_taskStatus,
+ const uint16_t i_istepStatus )
+{
+ InternalStatus l_sts;
+
+ // copy in all the values
+ l_sts.f.runningbit = i_runningbit;
+ l_sts.f.readybit = i_readybit;
+ l_sts.f.istep = i_istep;
+ l_sts.f.substep = i_substep;
+ l_sts.f.taskStatus = i_taskStatus;
+ l_sts.f.istepStatus = i_istepStatus;
+
+ mmio_scratch_write( MMIO_SCRATCH_IPLSTEP_STATUS, l_sts.val64 );
+
+}
+
OpenPOWER on IntegriCloud