summaryrefslogtreecommitdiffstats
path: root/src/usr/initservice/istepdispatcher
diff options
context:
space:
mode:
authorTerry J. Opie <opiet@us.ibm.com>2012-06-18 16:48:20 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-07-12 15:46:23 -0500
commitd40d08c719c845213844323ead282a748486d466 (patch)
tree15b2ec8cdcd9da21b11d1a4c373c10ea9de74c4a /src/usr/initservice/istepdispatcher
parentec56bbb81f64a52ab2668befd33fef926a0170b6 (diff)
downloadblackbird-hostboot-d40d08c719c845213844323ead282a748486d466.tar.gz
blackbird-hostboot-d40d08c719c845213844323ead282a748486d466.zip
Istep sync point message support
- Refactor IStepDispatcher for more robust msg handling - Modify sptask to act like real Fsp - Move all Istep Mbox Msg handling to Initservice - Add send sync point interface - Add wait on sync point interface - Modify start_payload istep to use new interfaces - Fix for Istep.pm Change-Id: Ib28b89cd916b9c0a0d15016996dbf1b88a8f79eb RTC: 43554 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1255 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/initservice/istepdispatcher')
-rw-r--r--src/usr/initservice/istepdispatcher/istepWorker.C244
-rw-r--r--src/usr/initservice/istepdispatcher/istepWorker.H81
-rw-r--r--src/usr/initservice/istepdispatcher/istep_mbox_msgs.H126
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.C1176
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.H235
-rw-r--r--src/usr/initservice/istepdispatcher/makefile6
-rw-r--r--src/usr/initservice/istepdispatcher/splesscommon.C12
-rw-r--r--src/usr/initservice/istepdispatcher/splesscommon.H12
-rw-r--r--src/usr/initservice/istepdispatcher/sptask.C60
9 files changed, 1161 insertions, 791 deletions
diff --git a/src/usr/initservice/istepdispatcher/istepWorker.C b/src/usr/initservice/istepdispatcher/istepWorker.C
new file mode 100644
index 000000000..445d988e3
--- /dev/null
+++ b/src/usr/initservice/istepdispatcher/istepWorker.C
@@ -0,0 +1,244 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/initservice/istepdispatcher/istepWorker.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 istepWorker.C
+ *
+ * IStep Dispatcher worker thread.
+ *
+ */
+
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <sys/msg.h>
+
+#include <errl/errlentry.H>
+
+#include <isteps/istepmasterlist.H>
+
+#include "../baseinitsvc/initservice.H"
+
+//#include <initservice/initsvcudistep.H> // InitSvcUserDetailsIstep
+
+#include "istep_mbox_msgs.H"
+#include "istepWorker.H"
+
+// ----- namespace INITSERVICE -------------------------------------------
+namespace INITSERVICE
+{
+/******************************************************************************/
+// Globals/Constants
+/******************************************************************************/
+extern trace_desc_t *g_trac_initsvc;
+
+
+// ----------------------------------------------------------------------------
+// startIStepWorkerThread
+// ----------------------------------------------------------------------------
+void startIStepWorkerThread ( void * io_args )
+{
+ TRACFCOMP( g_trac_initsvc,
+ ENTER_MRK"startIStepWorkerThread()" );
+
+ // detach from main istep dispatcher thread
+ task_detach();
+
+ // Worker thread entry
+ iStepWorkerThread( io_args );
+
+ TRACDCOMP( g_trac_initsvc,
+ EXIT_MRK"startIStepWorkerThread()" );
+
+ // Shutdown.
+ task_end();
+}
+
+
+// ----------------------------------------------------------------------------
+// iStepWorkerThread()
+// ----------------------------------------------------------------------------
+void iStepWorkerThread ( void * i_msgQ )
+{
+ errlHndl_t err = NULL;
+ msg_q_t theQ = static_cast<msg_q_t>( i_msgQ );
+ msg_t * theMsg = NULL;
+ uint32_t istep = 0x0;
+ uint32_t substep = 0x0;
+ uint64_t progressCode = 0x0;
+
+ TRACDCOMP( g_trac_initsvc,
+ ENTER_MRK"iStepWorkerThread()" );
+
+ while( 1 )
+ {
+ // Send More Work Needed msg to the main thread.
+ theMsg = msg_allocate();
+ theMsg->type = MORE_WORK_NEEDED;
+ theMsg->data[0] = 0x0;
+ theMsg->data[1] = 0x0;
+ theMsg->extra_data = err;
+ err = NULL;
+
+ // Wait here until the main thread has work for us.
+ msg_sendrecv( theQ,
+ theMsg );
+
+ // Got a response... The step/substep to execute are in data[0]
+ istep = ((theMsg->data[0] & 0xFF00) >> 8);
+ substep = (theMsg->data[0] & 0xFF);
+
+ // Post the Progress Code
+ // TODO - Covered with RTC: 34046
+ InitService::getTheInstance().setProgressCode( progressCode );
+
+ // Get the Task Info for this step
+ const TaskInfo * theStep = findTaskInfo( istep,
+ substep );
+
+ if( NULL != theStep )
+ {
+ TRACFCOMP( g_trac_initsvc,
+ "IStepDispatcher (worker): Run Istep (%d), substep(%d), "
+ "- %s",
+ istep, substep, theStep->taskname );
+
+ err = InitService::getTheInstance().executeFn( theStep,
+ NULL );
+
+ if( err )
+ {
+ TRACFCOMP( g_trac_initsvc,
+ "IStepDipspatcher (worker): Istep %s returned "
+ "errlog=%p",
+ theStep->taskname, err );
+ }
+ }
+ else
+ {
+ // Nothing to do for this step.
+ TRACDCOMP( g_trac_initsvc,
+ INFO_MRK"Empty Istep, nothing to do!" );
+ }
+
+ msg_free( theMsg );
+ theMsg = NULL;
+ }
+
+ // Something bad happened... this thread should never exit once started
+ assert( 0 );
+ TRACDCOMP( g_trac_initsvc,
+ ENTER_MRK"iStepWorkerThread()" );
+}
+
+
+// ----------------------------------------------------------------------------
+// findTaskInfo()
+// ----------------------------------------------------------------------------
+const TaskInfo * findTaskInfo( const uint32_t i_IStep,
+ const uint32_t i_SubStep )
+{
+ // default return is NULL
+ const TaskInfo *l_pistep = NULL;
+ /**
+ * @todo
+ * everything calling this should feed into the "real" istep/substep
+ * numbers ( starting at 1 ) - this routine should translate to index into
+ * the isteplists ( starting at 0 )
+ *
+ * int32_t l_istepIndex = i_IStep-1;
+ * int32_t l_substepIndex = i_SubStep-1;
+ *
+ * assert( l_istepIndex >= 0 );
+ * assert( l_substepIndex >= 0 );
+ */
+
+ // apply filters
+ do
+ {
+ // Sanity check / dummy IStep
+ if( g_isteps[i_IStep].pti == NULL)
+ {
+ TRACDCOMP( g_trac_initsvc,
+ "g_isteps[%d].pti == NULL (substep=%d)",
+ i_IStep,
+ i_SubStep );
+ break;
+ }
+
+ // check input range - IStep
+ if( i_IStep >= INITSERVICE::MaxISteps )
+ {
+ TRACDCOMP( g_trac_initsvc,
+ "IStep %d out of range. (substep=%d) ",
+ i_IStep,
+ i_SubStep );
+ 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 %d Substep %d 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 %d SubStep %d task_type==END_TASK_LIST.",
+ i_IStep,
+ i_SubStep );
+ break;
+ }
+
+ // check to see if the pointer to the function is NULL.
+ // This is possible if some of the substeps aren't working yet
+ // and are just placeholders.
+ if( g_isteps[i_IStep].pti[i_SubStep].taskfn == NULL )
+ {
+ TRACDCOMP( g_trac_initsvc,
+ "IStep %d SubStep %d fn ptr is NULL.",
+ i_IStep,
+ i_SubStep );
+ break;
+ }
+
+ // we're good, set the istep & return it to caller
+ l_pistep = &( g_isteps[i_IStep].pti[i_SubStep] );
+ } while( 0 );
+
+ return l_pistep;
+}
+
+
+} // namespace
diff --git a/src/usr/initservice/istepdispatcher/istepWorker.H b/src/usr/initservice/istepdispatcher/istepWorker.H
new file mode 100644
index 000000000..f9ed47e24
--- /dev/null
+++ b/src/usr/initservice/istepdispatcher/istepWorker.H
@@ -0,0 +1,81 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/initservice/istepdispatcher/istepWorker.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_TAG
+ */
+#ifndef __ISTEPWORKER_H
+#define __ISTEPWORKER_H
+/**
+ * @file istepWorker.H
+ *
+ * IStep Dispatcher Worker thread
+ */
+
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <stdint.h>
+
+#include <initservice/initsvcstructs.H>
+
+
+namespace INITSERVICE
+{
+
+/**
+* @brief This function is called to start the task.
+*
+* @param[in/out] io_args - This is a void pointer, but the code expects that
+* this will be the msg queue to communicate with the main thread.
+*
+* @return NONE.
+*/
+void startIStepWorkerThread ( void * io_args );
+
+/**
+* @brief This function is the main loop for the Istep dispatcher worker
+* thread.
+*
+* @param[in] i_msgQ - The message queue to talk to the main thread.
+*
+* @return NONE.
+ */
+void iStepWorkerThread ( void * i_msgQ );
+
+/**
+ * @brief This function will be used to query the istep master list and the
+ * other istep headers to know what functions/tasks need to be started
+ * for the Istep/Substep that we are in.
+ *
+ * @param[in] i_IStep - The Istep to run.
+ *
+ * @param[in] i_SubStep - The SubStep to run.
+ *
+ * @return TaskInfo - The task info for the task to start as a result of the
+ * requested Istep/Substep.
+ */
+const TaskInfo * findTaskInfo ( const uint32_t i_IStep,
+ const uint32_t i_SubStep );
+
+
+} // namespace
+
+#endif
diff --git a/src/usr/initservice/istepdispatcher/istep_mbox_msgs.H b/src/usr/initservice/istepdispatcher/istep_mbox_msgs.H
index ae3ca45ff..e002a7aba 100644
--- a/src/usr/initservice/istepdispatcher/istep_mbox_msgs.H
+++ b/src/usr/initservice/istepdispatcher/istep_mbox_msgs.H
@@ -1,62 +1,100 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/initservice/istepdispatcher/istep_mbox_msgs.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
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/initservice/istepdispatcher/istep_mbox_msgs.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_TAG
+ */
#ifndef __INITSERVICE_ISTEP_MBOX_MSGS_H
#define __INITSERVICE_ISTEP_MBOX_MSGS_H
+#include <mbox/mbox_queues.H>
+
/**
* @file istep_mbox_msgs.H
*
* @brief Mailbox types used by IStepDisp to communicate with FSP/SP
*
*/
+namespace INITSERVICE
+{
-#include "splesscommon.H"
+const uint32_t SPLESS_MSG = 0x000F0000;
+const uint32_t ISTEP_WORKER_MSG = 0x00F00000;
-namespace INITSERVICE
+// ------------------------------------------------------------------
+// HwSvr Msg Type Enums
+enum
{
+ HWSVR_BREAKPOINT = 0x00,
+ HWSVR_SYNC_POINT = 0x10,
+};
+// ------------------------------------------------------------------
+// Worker Thread Msg Type Enums
enum
{
- // TODO - I'm not changing this file, but I would really like to put the
- // SYNC_POINT_REACHED message here. Since its related to Isteps and
- // syncing Hostboot and Fsp. But to do that, this needs to be in the
- // src/include/usr side of things.
- //
- // Plus, I think its weird that this file uses definitions from
- // splesscommon.H. It should be the other way around. Define them here
- // and use them from splesscommon. Issue 42491 has been opened to
- // discuss this further.
- //
- // I am going to define my own message in the code that I'm writing until
- // we get something figured out.
- SINGLE_STEP_TYPE = MBOX::FIRST_SECURE_MSG |
- SPLESS::SPLESS_SINGLE_ISTEP_CMD,
- CLEAR_TRACE_TYPE = MBOX::FIRST_SECURE_MSG |
- SPLESS::SPLESS_CLEAR_TRACE_CMD,
- SHUTDOWN_TYPE = MBOX::FIRST_SECURE_MSG |
- SPLESS::SPLESS_SHUTDOWN_CMD,
- BREAKPOINT_TYPE = MBOX::FIRST_UNSECURE_MSG |
- SPLESS::SPLESS_AT_BREAK_POINT
+ WORKER_MORE_WORK_NEEDED = 0x00,
+ WORKER_BREAKPOINT = 0x01,
+};
+
+// ------------------------------------------------------------------
+// SPLess Msg Type Enums
+enum
+{
+ // Randomly picked 0xAA since SPLess mode looks at this to know whether it
+ // got a shutdown. originall was 0x0, and shutdown every time.
+ // TODO - need to check if the simics script needs to know this value.
+ // Opened Issue 45042 to have this as well as hb-istep support of shutdown
+ // removed.
+ SPLESS_SHUTDOWN_CMD = 0xAA,
+};
+
+// ------------------------------------------------------------------
+// Msgs that IstepDispatcher can accept
+enum
+{
+ // --------------------------------------------------------------
+ // General Messages from all sources
+ // --------------------------------------------------------------
+ SYNC_POINT_REACHED = MBOX::FIRST_UNSECURE_MSG |
+ HWSVR_SYNC_POINT,
+ BREAKPOINT = MBOX::FIRST_UNSECURE_MSG |
+ HWSVR_BREAKPOINT,
+
+ // --------------------------------------------------------------
+ // Worker Thread Messages
+ // --------------------------------------------------------------
+ MORE_WORK_NEEDED = MBOX::FIRST_SECURE_MSG |
+ ISTEP_WORKER_MSG |
+ WORKER_MORE_WORK_NEEDED,
+ BREAKPOINT_WORKER = MBOX::FIRST_SECURE_MSG |
+ ISTEP_WORKER_MSG |
+ WORKER_BREAKPOINT,
+
+ // --------------------------------------------------------------
+ // SPLess Messages
+ // --------------------------------------------------------------
+ SHUTDOWN_SPLESS = MBOX::FIRST_SECURE_MSG |
+ SPLESS_MSG |
+ SPLESS_SHUTDOWN_CMD,
+
};
} // namespace
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C
index 38f838871..649b6e3d1 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.C
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C
@@ -38,25 +38,17 @@
#include <stdio.h>
#include <string.h>
-
#include <kernel/console.H> // printk status
-// turn on clearAllBuffers()
-#define __HIDDEN_TRACEIF_CLEARBUFFER
-#include <vfs/vfs.H> // load_module
#include <sys/task.h> // tid_t, task_create, etc
-#include <sys/time.h> // nanosleep
-#include <sys/misc.h> // shutdown
-
-#include <trace/interface.H> // trace support
#include <errl/errlentry.H> // errlHndl_t
+
#include <devicefw/userif.H> // targeting
#include <initservice/isteps_trace.H> // ISTEPS_TRACE buffer
#include <initservice/initsvcudistep.H> // InitSvcUserDetailsIstep
-#include <initservice/taskargs.H> // TASK_ENTRY_MACRO
-
+#include <initservice/taskargs.H> // TASK_ENTRY_MACRO
#include <targeting/common/attributes.H> // ISTEP_MODE attribute
#include <targeting/common/targetservice.H>
@@ -64,13 +56,13 @@
#include <mbox/mbox_queues.H> // HB_ISTEP_MSGQ
#include <mbox/mboxif.H> // register mailbox
+#include <isteps/istepmasterlist.H>
+
#include "istepdispatcher.H"
+#include "istepWorker.H"
#include "splesscommon.H"
-#include <isteps/istepmasterlist.H>
-#include <targeting/common/attributes.H>
-
// ----- namespace ISTEPS_TRACE ---------------------------------------
namespace ISTEPS_TRACE
{
@@ -94,752 +86,782 @@ using namespace SPLESS; // SingleStepMode
/******************************************************************************/
extern trace_desc_t *g_trac_initsvc;
+const MBOX::queue_id_t HWSVRQ = MBOX::IPL_SERVICE_QUEUE;
+
/**
* _start() task entry procedure using the macro in taskargs.H
*/
TASK_ENTRY_MACRO( IStepDispatcher::getTheInstance().init );
+// ----------------------------------------------------------------------------
+// IstepDispatcher()
+// ----------------------------------------------------------------------------
+IStepDispatcher::IStepDispatcher ()
+ : iv_workerMsg( NULL )
+{
+ SPLESS::initIStepMode();
+ mutex_init( &iv_bkPtMutex );
+ mutex_init( &iv_syncMutex );
+ mutex_init( &iv_stepMutex );
+ sync_cond_init( &iv_syncHit );
+
+ iv_curIStep = 0x0;
+ iv_curSubStep = 0x0;
+ iv_sync = false;
+ // init mailbox / message Q.
+ iv_msgQ = msg_q_create();
+}
-void IStepDispatcher::init( errlHndl_t &io_rtaskRetErrl )
+// ----------------------------------------------------------------------------
+// ~IstepDispatcher()
+// ----------------------------------------------------------------------------
+IStepDispatcher::~IStepDispatcher ()
{
- errlHndl_t l_errl = NULL;
+}
- // initialize (and declare) ISTEPS_TRACE here, the rest of the isteps will use it.
- ISTEPS_TRACE::g_trac_isteps_trace = NULL;
- printk( "IstepDispatcher entry.\n" );
+// ----------------------------------------------------------------------------
+// IstepDispatcher::getTheInstance()
+// ----------------------------------------------------------------------------
+IStepDispatcher& IStepDispatcher::getTheInstance ()
+{
+ return Singleton<IStepDispatcher>::instance();
+}
- TRACFCOMP( g_trac_initsvc,
- "IStep Dispatcher entry." );
+// ----------------------------------------------------------------------------
+// IStepDispatcher::init()
+// ----------------------------------------------------------------------------
+void IStepDispatcher::init ( errlHndl_t &io_rtaskRetErrl )
+{
+ errlHndl_t err = NULL;
+
+ // initialize (and declare) ISTEPS_TRACE here, the rest of the isteps will
+ // use it.
+ ISTEPS_TRACE::g_trac_isteps_trace = NULL;
TRAC_INIT(&ISTEPS_TRACE::g_trac_isteps_trace, "ISTEPS_TRACE", 2048 );
+ printk( "IstepDispatcher entry.\n" );
+ TRACFCOMP( g_trac_initsvc,
+ "IStep Dispatcher entry." );
- if ( getIStepMode() == true )
+ do
{
- printk( "IStep single-step\n" );
- TRACFCOMP( g_trac_initsvc,
- "IStep single-step" );
+ if( !(SPLESS::SPLessAttached()) )
+ {
+ // register message Q with FSP Mailbox - only if Fsp attached.
+ err = MBOX::msgq_register( MBOX::HB_ISTEP_MSGQ,
+ iv_msgQ );
+
+ if( err )
+ {
+ break;
+ }
+ }
- if ( SPLESS::SPLessAttached( ) )
+ // Spawn off the Worker thread
+ tid_t l_workerTid = task_create( startIStepWorkerThread,
+ iv_msgQ );
+ assert( l_workerTid > 0 );
+
+ // Check for SPLess operation
+ if( SPLESS::SPLessAttached() )
{
// SPless user console is attached,
// launch SPTask.
-
TRACFCOMP( g_trac_initsvc,
- "IStep single-step enable (SPLESS)" );
+ "IStep single-step enable (SPLESS)" );
- tid_t l_spTaskTid = task_create( spTask, iv_msgQ );
- // should never happen...
+ tid_t l_spTaskTid = task_create( spTask,
+ iv_msgQ );
assert( l_spTaskTid > 0 );
+ }
- // sptask will turn on the ready bit when it is up.
+ if( err )
+ {
+ TRACFCOMP( g_trac_initsvc,
+ "ERROR: Failed to register mailbox, terminating" );
- // IStep single-step
- singleStepISteps( io_rtaskRetErrl );
+ break;
}
- else
+
+ if( getIStepMode() )
{
+ printk( "IStep single-step\n" );
TRACFCOMP( g_trac_initsvc,
- "IStep single-step enable (FSP)" );
+ "IStep single-step" );
- // register message Q with FSP Mailbox
- l_errl = MBOX::msgq_register(
- MBOX::HB_ISTEP_MSGQ,
- iv_msgQ ) ;
- if ( l_errl )
+ err = msgHndlr();
+ if( err )
{
- TRACFCOMP( g_trac_initsvc,
- "ERROR: Failed to register mailbox, terminating" );
- // fall through and report errorlog
- io_rtaskRetErrl = l_errl;
+ break;
}
- else
+ }
+ else
+ {
+ printk( "IStep run-all\n" );
+ TRACFCOMP( g_trac_initsvc,
+ "IStep run all" );
+
+ // Execute all Isteps sequentially in 'normal' mode
+ err = executeAllISteps();
+ if( err )
{
- // IStep single-step
- singleStepISteps( io_rtaskRetErrl );
+ break;
}
}
- }
- else
- {
- printk( "IStep run-all\n" );
-
- TRACFCOMP( g_trac_initsvc,
- "IStep run all" );
-
- // Run all the ISteps sequentially
- runAllISteps( io_rtaskRetErrl );
- } // endelse
-
+ } while( 0 );
TRACFCOMP( g_trac_initsvc,
"IStepDispatcher finished.");
-
printk( "IStepDispatcher exit.\n" );
-
- task_end2( io_rtaskRetErrl );
+ task_end2( err );
}
-void IStepDispatcher::runAllISteps( errlHndl_t &io_rtaskRetErrl )
+
+// ----------------------------------------------------------------------------
+// IStepDispatcher::executeAllISteps()
+// ----------------------------------------------------------------------------
+errlHndl_t IStepDispatcher::executeAllISteps ( void )
{
- errlHndl_t l_errl = NULL;
- uint32_t l_IStep = 0;
- uint32_t l_SubStep = 0;
- const TaskInfo *l_pistep = NULL;
- uint64_t l_progresscode = 0;
+ errlHndl_t err = NULL;
+ msg_t * theMsg = NULL;
+ TRACFCOMP( g_trac_initsvc,
+ ENTER_MRK"IStepDispatcher::executeAllISteps()" );
- for ( l_IStep=0;
- l_IStep<INITSERVICE::MaxISteps;
- l_IStep++ )
+ do
{
- TRACDCOMP( g_trac_initsvc,
- "runAllISteps: IStep %d: %d entries",
- l_IStep,
- g_isteps[l_IStep].numitems );
-
- for ( l_SubStep=0;
- l_SubStep < g_isteps[l_IStep].numitems;
- l_SubStep++)
+ // Sequentially loop through all isteps, executing each by replying to
+ // work needed msg from worker thread.
+ uint32_t prevIstep = 0;
+ uint32_t prevSubStep = 0;
+ for( size_t istep = 0;
+ istep < MaxISteps;
+ istep++ )
{
- /**
- * @todo refactor - replace the following block with
- * processSingleIStepCmd()
- */
-
- l_pistep = findTaskInfo(
- l_IStep,
- l_SubStep );
- if ( l_pistep == NULL )
+ // Run until num items +1, to be sure we know the last step
+ // finished
+ for( size_t substep = 0;
+ substep < (g_isteps[istep].numitems + 1);
+ substep++ )
{
- // continue to end of list
- continue;
- }
+ // Before we can do anything, we need to be sure the worker thread is
+ // ready to start
+ theMsg = msg_wait( iv_msgQ );
+
+ // check for sync msgs
+ if( theMsg->type == SYNC_POINT_REACHED )
+ {
+ TRACFCOMP( g_trac_initsvc,
+ INFO_MRK"Got sync msg (0x%08x)",
+ theMsg->type );
+ handleSyncPointReachedMsg();
+
+ // We didn't really do anything for this substep
+ substep--;
+ continue;
+ }
+
+ // If we just got the msg that the last step finished, break
+ // out
+ if( substep == (g_isteps[istep].numitems + 1) )
+ {
+ TRACFCOMP( g_trac_initsvc,
+ INFO_MRK"Last Step, exit" );
+ break;
+ }
+
+ // Look for an errlog in extra_data
+ if( NULL != theMsg->extra_data )
+ {
+ TRACFCOMP( g_trac_initsvc,
+ ERR_MRK"Error returned from istep(%d), substep(%d)",
+ prevIstep, prevSubStep );
+
+ err = ((errlHndl_t)theMsg->extra_data);
+
+ break;
+ }
+
+ TRACFCOMP( g_trac_initsvc,
+ INFO_MRK"executeAllSteps(0x%08x), istep: %d, substep: %d",
+ theMsg->type, istep, substep );
- // @todo placeholder until progress codes are defined and
- // progress code driver is implemented.
- l_progresscode = 0;
- InitService::getTheInstance().setProgressCode( l_progresscode );
+ // Set the Istep info
+ prevIstep = istep;
+ prevSubStep = substep;
+ uint16_t istepInfo = ((istep << 8 ) | substep);
+ setIstepInfo( istepInfo );
- // print out what we are running
- TRACFCOMP( g_trac_initsvc,
- "IStepDisp: Run IStep %d.%d %s",
- l_IStep,
- l_SubStep,
- l_pistep->taskname );
+ // Put the step/substep into data[0] for the worker thread
+ theMsg->data[0] = istepInfo;
+ msg_respond( iv_msgQ,
+ theMsg );
- l_errl = InitService::getTheInstance().executeFn(
- l_pistep,
- NULL );
+ theMsg = NULL;
+ }
- // check for errors
- if ( l_errl )
+ if( err )
{
- TRACFCOMP( g_trac_initsvc,
- "IStepDisp: istep %s returned errlog=%p",
- l_pistep->taskname,
- l_errl );
- // if we have an errorlog, break out of the inner loop
- // and handle it.
break;
}
- } // endfor l_SubStep
+ }
- if ( l_errl )
+ if( err )
{
- // something left an error log in the inner loop, breakout
break;
}
- } // endfor l_IStep
-
-
- /**
- * @todo detect Can-Continue condition here and reset/rerun ISteps.
- * For now this is pushed to a later sprint.
- */
-
- //
- if ( l_errl )
- {
- TRACFCOMP( g_trac_initsvc,
- "IStepDisp ERROR: errorlog %p",
- l_errl );
+ } while ( 0 );
- // return to _start() with the errorlog set, parent should do shutdown
- io_rtaskRetErrl = l_errl;
- }
+ TRACFCOMP( g_trac_initsvc,
+ EXIT_MRK"IStepDispatcher::executeAllISteps()" );
- // return to init with io_rtaskRetErrl set
+ return err;
}
-void IStepDispatcher::singleStepISteps( errlHndl_t &io_rtaskRetErrl )
+// ----------------------------------------------------------------------------
+// IStepDispatcher::msgHndlr()
+// ----------------------------------------------------------------------------
+errlHndl_t IStepDispatcher::msgHndlr ( void )
{
- uint32_t l_Type = 0;
- uint32_t l_IStep = 0;
- uint32_t l_Substep = 0;
- bool l_quitflag = false;
- uint32_t l_RetSts = 0;
- errlHndl_t l_errl = NULL;
- uint32_t l_PLID = 0;
+ errlHndl_t err = NULL;
+ msg_t * theMsg = NULL;
- mutex_lock(&iv_poll_mutex); // make sure this is only poller
+ // TODO - Issue 45012
+ // There is enough common code between this path and executeAllISteps()
+ // that the issue above will be used to combine the 2 paths into one
+ // commone code path.
- while ( 1 )
+ TRACFCOMP( g_trac_initsvc,
+ ENTER_MRK"IStepDispatcher::msgHndlr()" );
+
+ // We will stay in this loop unless there is a failure or other reason to
+ // exit out and terminate. This loop is the main handler for the Istep
+ // Dispatcher. It receives all messages from the Fsp, Child worker
+ // thread, and the SPLess task.
+ while( 1 )
{
+ theMsg = msg_wait( iv_msgQ );
TRACDCOMP( g_trac_initsvc,
- "IStepDisp wait for message." );
-
- // wait for message from FSP or Dispatcher
- iv_pMsg = msg_wait( iv_msgQ );
+ INFO_MRK"Got Msg - Type: 0x%08x",
+ theMsg->type );
- // unblocked
- if ( msg_is_async( iv_pMsg ) )
+ switch( theMsg->type )
{
- // should not receive async messages here, drop it, post errorlog
- // and go back to waiting.
- TRACFCOMP( g_trac_initsvc,
- "singleStepISteps: ERROR async msg type 0x%x, msg 0x%x.%x",
- iv_pMsg->type,
- static_cast<uint32_t>( iv_pMsg->data[0] >> 32 ),
- static_cast<uint32_t>( iv_pMsg->data[0] & 0xffffffff ) );
-
- /*@ errorlog tag
- * @errortype ERRL_SEV_INFORMATIONAL
- * @moduleid ISTEP_INITSVC_MOD_ID
- * @reasoncode ISTEP_SINGLESTEP_ASYNC_RCVD
- * @userdata1 type of packet
- * @userdata2 first data word
- *
- * @devdesc IStepDisp singleStepISteps was expecting a
- * synchronous message and received an asynchonous
- * message.
- *
- */
- errlHndl_t l_errlAsync = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_INFORMATIONAL,
- INITSERVICE::ISTEP_INITSVC_MOD_ID,
- INITSERVICE::ISTEP_SINGLESTEP_ASYNC_RCVD,
- iv_pMsg->type,
- iv_pMsg->data[0] );
-
- errlCommit( l_errlAsync, INITSVC_COMP_ID );
-
- msg_free(iv_pMsg);
- iv_pMsg = NULL;
-
- continue;
- }
-
-
- l_Type = iv_pMsg->type;
- l_IStep = static_cast<uint32_t>( iv_pMsg->data[0] >>32 ) ;
- l_Substep = static_cast<uint32_t>( iv_pMsg->data[0] & 0x0FFFFFFFF );
-
- TRACDCOMP( g_trac_initsvc,
- "IStepDisp recv msg type 0x%x, 0x%x.%x",
- l_Type,
- l_IStep,
- l_Substep );
-
- // Clear Status and PLID fields for response msg
- l_RetSts = 0;
- l_PLID = 0;
-
- switch( l_Type )
- {
- case SINGLE_STEP_TYPE:
- mutex_unlock(&iv_poll_mutex);
- // command 0: run istep/substep
- TRACDCOMP( g_trac_initsvc,
- "Run istep %d.%d ",
- l_IStep,
- l_Substep );
- l_errl = processSingleIStepCmd( l_IStep, l_Substep, l_RetSts );
- mutex_lock(&iv_poll_mutex);
+ case SYNC_POINT_REACHED:
+ // Sync point reached from Fsp
+ iv_Msg = theMsg;
+ handleSyncPointReachedMsg();
break;
- case BREAKPOINT_TYPE: // not at break point here
- TRACDCOMP( g_trac_initsvc,
- "Not at break point." );
- l_RetSts = SPLESS_NOT_AT_BREAK_POINT;
+ case MORE_WORK_NEEDED:
+ // Worker thread is ready for more work.
+ iv_workerMsg = theMsg;
+ handleMoreWorkNeededMsg();
break;
- case CLEAR_TRACE_TYPE:
- TRAC_CLEAR_BUFFERS();
- TRACFCOMP( g_trac_initsvc,
- "Cleared all trace buffers." );
- l_RetSts = SPLESS_TRACE_BUFFERS_CLEARED;
- break;
+ case SHUTDOWN_SPLESS:
+ // Creat errorlog to return as part of the shutdown.
+ /*@
+ * @errortype
+ * @reasoncode INITSERVICE::ISTEP_SHUTDOWN
+ * @severity ERRORLOG::ERRL_SEV_INFORMATIONAL
+ * @moduleid INITSERVICE::ISTEP_INITSVC_MOD_ID
+ * @userdata1 <UNUSED>
+ * @userdata2 <UNUSED>
+ * @devdesc Istep initiated Shutdown.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ INITSERVICE::ISTEP_INITSVC_MOD_ID,
+ INITSERVICE::ISTEP_SHUTDOWN,
+ 0, 0 );
- case SHUTDOWN_TYPE:
- TRACFCOMP( g_trac_initsvc,
- "Shutting down HostBoot. " );
- l_RetSts = SPLESS_SHUTTING_DOWN;
- l_quitflag = true;
break;
default:
- TRACFCOMP( g_trac_initsvc,
- "ERROR: invalid command 0x%x ",
- l_Type );
- l_RetSts = SPLESS_INVALID_COMMAND;
+ // Default Message
+ // This SHOULD be a message from the Fsp with the Step/substep
+ // to be executed.
+ // Gotta check to make sure Fsp hadn't sent us a 2nd Istep
+ // request for some reason, if so, its an error.
+ if( iv_Msg )
+ {
+ TRACFCOMP( g_trac_initsvc,
+ ERR_MRK"ERROR: IStep Dispatcher already has another "
+ "Istep request for step: 0x%02x, substep: 0x%02x",
+ ((iv_Msg->type & 0xFF00) >> 8),
+ (iv_Msg->type & 0xFF) );
+
+ /*@
+ * @errortype
+ * @reasoncode ISTEP_MULTIPLE_ISTEP_REQ
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid ISTEP_INITSVC_MOD_ID
+ * @userdata1 Current Istep
+ * @userdata2 Current SubStep
+ * @devdesc A Second Istep request has been made
+ * and we are still working on a
+ * previous Istep.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ ISTEP_INITSVC_MOD_ID,
+ ISTEP_MULTIPLE_ISTEP_REQ,
+ ((iv_Msg->type & 0xFF00) >> 8),
+ (iv_Msg->type & 0xFF) );
+
+ break;
+ }
+
+ iv_Msg = theMsg;
+ handleIStepRequestMsg();
break;
- } // end switch
+ };
- if ( l_errl )
+ if( err )
{
- // tell the user console that the IStep returned an errorlog
- l_RetSts = SPLESS_TASKRC_RETURNED_ERRLOG;
- // get the platform log identifier (PLID) to send to FSP
- l_PLID = l_errl->plid();
-
- // go ahead and commit the child errorlog
- errlCommit( l_errl, INITSVC_COMP_ID );
+ // Breaking here will be a BAD thing... It means that we are
+ // exiting not just Istep Dispatcher, but all of Hostboot. There
+ // are 2 cases where we would exit here:
+ // 1. Shutdown requested via istep (SPLESS)
+ // 2. Error during an Istep.
+ errlCommit( err,
+ INITSVC_COMP_ID );
}
+ }
- iv_pMsg->type = l_Type;
- // Return l_RetSts as hi word of data[0]
- // Return l_PLID as lo word of data[0]
- iv_pMsg->data[0] =
- ( static_cast<uint64_t>( l_RetSts ) << 32 ) |
- static_cast<uint64_t>( l_PLID ) ;
+ TRACFCOMP( g_trac_initsvc,
+ EXIT_MRK"IStepDispatcher::msgHndlr()" );
- iv_pMsg->data[1] = 0;
- iv_pMsg->extra_data = NULL;
+ return err;
+}
- TRACDCOMP( g_trac_initsvc,
- "IStepDisp send msg type 0x%x, 0x%x.%x",
- iv_pMsg->type,
- static_cast<uint32_t>( iv_pMsg->data[0] >> 32),
- static_cast<uint32_t>( iv_pMsg->data[0] & 0xFFFFFFFF ));
- // send status back
- msg_respond( iv_msgQ, iv_pMsg );
+// ----------------------------------------------------------------------------
+// waitForSyncPoint()
+// IStepDispatcher::waitForSyncPoint()
+// ----------------------------------------------------------------------------
+void waitForSyncPoint ( void )
+{
+ TRACDCOMP( g_trac_initsvc,
+ ENTER_MRK"waitForSyncPoint()" );
+ IStepDispatcher::getTheInstance().waitForSyncPoint();
- if ( l_quitflag == true )
- {
- // shutdown command issued, break out of loop
-
- /*@ errorlog tag
- * @errortype ERRL_SEV_INFORMATIONAL
- * @moduleid ISTEP_INITSVC_MOD_ID
- * @reasoncode ISTEP_SINGLESTEP_SHUTDOWN
- * @userdata1 0
- * @userdata2 0
- *
- * @devdesc hb-istep terminated
- *
- */
- l_errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_INFORMATIONAL,
- INITSERVICE::ISTEP_INITSVC_MOD_ID,
- INITSERVICE::ISTEP_SINGLESTEP_SHUTDOWN,
- 0,
- 0 );
- break;
- }
+ TRACDCOMP( g_trac_initsvc,
+ EXIT_MRK"waitForSyncPoint()" );
+}
+
+void IStepDispatcher::waitForSyncPoint ( void )
+{
+ TRACDCOMP( g_trac_initsvc,
+ ENTER_MRK"IStepDispatcher::waitForSyncPoint()" );
- } // end while
+ if( getIStepMode() ||
+ spLess() )
+ {
+ TRACFCOMP( g_trac_initsvc,
+ INFO_MRK"Istep mode or SPless, no wait for sync point allowed" );
+ return;
+ }
- // fell out of loop, return with rtaskRetErrl set
- mutex_unlock(&iv_poll_mutex);
- io_rtaskRetErrl = l_errl;
+ // Lock here to hold off all additional callers
+ TRACFCOMP( g_trac_initsvc,
+ INFO_MRK"Wait for sync point" );
+ mutex_lock( &iv_syncMutex );
+ while( !iv_sync )
+ {
+ sync_cond_wait( &iv_syncHit,
+ &iv_syncMutex );
+ }
+ iv_sync = false;
+ mutex_unlock( &iv_syncMutex );
+ TRACDCOMP( g_trac_initsvc,
+ INFO_MRK"Sync point hit." );
+
+ TRACDCOMP( g_trac_initsvc,
+ EXIT_MRK"IStepDispatcher::waitForSyncPoint()" );
}
+// ----------------------------------------------------------------------------
+// sendSyncPoint()
+// IStepDispatcher::sendSyncPoint()
+// ----------------------------------------------------------------------------
+errlHndl_t sendSyncPoint ( void )
+{
+ TRACFCOMP( g_trac_initsvc,
+ ENTER_MRK"sendSyncPoint()" );
+
+ return IStepDispatcher::getTheInstance().sendSyncPoint();
+}
-errlHndl_t IStepDispatcher::processSingleIStepCmd(
- const uint32_t i_IStep,
- const uint32_t i_Substep,
- uint32_t &o_rSts )
+errlHndl_t IStepDispatcher::sendSyncPoint ( void )
{
- errlHndl_t l_errl = NULL;
- const TaskInfo *l_pistep = NULL;
+ errlHndl_t err = NULL;
- o_rSts = 0;
+ TRACDCOMP( g_trac_initsvc,
+ ENTER_MRK"IStepDispatcher::sendSyncPoint()" );
- // look up istep+substep
- l_pistep = IStepDispatcher::getTheInstance().findTaskInfo(
- i_IStep,
- i_Substep );
- do
+ if( getIStepMode() )
{
- if ( l_pistep == NULL )
- {
- // invalid istep, return error
- TRACDCOMP( g_trac_initsvc,
- "processSingleIStepCmd: Invalid IStep %d.%d\n",
- i_IStep,
- i_Substep );
+ TRACFCOMP( g_trac_initsvc,
+ INFO_MRK"Istep mode, no sending sync point allowed" );
+ return err;
+ }
- o_rSts = SPLESS_INVALID_COMMAND;
- break;
- }
+ msg_t * myMsg = msg_allocate();
+ myMsg->type = SYNC_POINT_REACHED;
+ uint64_t tmpVal = iv_curIStep;
+ tmpVal = tmpVal << 32;
+ tmpVal |= iv_curSubStep;
+ myMsg->data[0] = tmpVal;
+ myMsg->data[1] = 0x0;
+ myMsg->extra_data = NULL;
+ err = sendMboxMsg( ISTEP_ASYNC,
+ myMsg );
+
+ TRACDCOMP( g_trac_initsvc,
+ EXIT_MRK"IStepDispatcher::sendSyncPoint()" );
- /**
- * @todo placeholder - set progress code before starting
- * This will not be finalized until the progress code driver
- * is designed and implemented.
- */
- uint64_t l_progresscode = 0;
- InitService::getTheInstance().setProgressCode( l_progresscode );
+ return err;
+}
+// ----------------------------------------------------------------------------
+// sendIstepCompleteMsg()
+// IStepDispatcher::sendIstepCompleteMsg()
+// ----------------------------------------------------------------------------
+errlHndl_t sendIstepCompleteMsg ( void )
+{
+ TRACFCOMP( g_trac_initsvc,
+ ENTER_MRK"sendIstepCompleteMsg()" );
- TRACFCOMP( g_trac_initsvc,
- "processSingleIStepCmd: Run IStep=%d.%d %s",
- i_IStep,
- i_Substep,
- l_pistep->taskname );
+ return IStepDispatcher::getTheInstance().sendIstepCompleteMsg();
+}
+
+errlHndl_t IStepDispatcher::sendIstepCompleteMsg ( void )
+{
+ errlHndl_t err = NULL;
- // launch the istep
- l_errl = InitService::getTheInstance().executeFn(
- l_pistep,
- NULL );
+ TRACDCOMP( g_trac_initsvc,
+ ENTER_MRK"IStepDispatcher::sendIstepCompleteMsg()" );
- if ( l_errl )
+ do
+ {
+ // We just need to respond back to the outstanding iv_Msg we should
+ // already have
+ if( iv_Msg )
+ {
+ iv_Msg->data[0] = 0x0;
+ msg_respond( iv_msgQ,
+ iv_Msg );
+ iv_Msg = NULL;
+ }
+ else
{
- // @todo post informational errl here?
+ TRACFCOMP( g_trac_initsvc,
+ ERR_MRK"Request to send Istep complete, but no outstanding "
+ "message from Fsp found!!" );
+
+ /*@
+ * @errortype
+ * @reasoncode NO_MSG_PRESENT
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid ISTEP_INITSVC_MOD_ID
+ * @userdata1 Current Istep
+ * @userdata2 Current SubStep
+ * @devdesc Request to send Istep Complete msg to Fsp, but no
+ * outstanding message from Fsp found.
+ */
+ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ ISTEP_INITSVC_MOD_ID,
+ NO_MSG_PRESENT,
+ iv_curIStep,
+ iv_curSubStep );
break;
}
- } while(0);
+ } while( 0 );
+ TRACDCOMP( g_trac_initsvc,
+ EXIT_MRK"IStepDispatcher::sendIstepCompleteMsg()" );
- return l_errl;
+ return err;
}
-
-const TaskInfo *IStepDispatcher::findTaskInfo(
- const uint32_t i_IStep,
- const uint32_t i_SubStep ) const
+// ----------------------------------------------------------------------------
+// IStepDispatcher::sendMboxMsg()
+// ----------------------------------------------------------------------------
+errlHndl_t IStepDispatcher::sendMboxMsg ( IStepSync_t i_sendSync,
+ msg_t * i_msg )
{
- // default return is NULL
- const TaskInfo *l_pistep = NULL;
- /**
- * @todo
- * everything calling this should feed into the "real" istep/substep
- * numbers ( starting at 1 ) - this routine should translate to index into
- * the isteplists ( starting at 0 )
- *
- * int32_t l_istepIndex = i_IStep-1;
- * int32_t l_substepIndex = i_SubStep-1;
- *
- * assert( l_istepIndex >= 0 );
- * assert( l_substepIndex >= 0 );
- */
-
- // apply filters
+ errlHndl_t err = NULL;
+
+ TRACDCOMP( g_trac_initsvc,
+ ENTER_MRK"IStepDispatcher::sendMboxMsg()" );
+
do
{
- // Sanity check / dummy IStep
- if ( g_isteps[i_IStep].pti == NULL)
+ if( ISTEP_SYNC == i_sendSync )
{
- TRACDCOMP( g_trac_initsvc,
- "g_isteps[%d].pti == NULL (substep=%d)",
- i_IStep,
- i_SubStep );
- break;
+ err = MBOX::sendrecv( HWSVRQ,
+ i_msg );
}
-
- // check input range - IStep
- if ( i_IStep >= INITSERVICE::MaxISteps )
+ else if( ISTEP_ASYNC == i_sendSync )
{
- TRACDCOMP( g_trac_initsvc,
- "IStep %d out of range. (substep=%d) ",
- i_IStep,
- i_SubStep );
- break; // break out with l_pistep set to NULL
+ err = MBOX::send( HWSVRQ,
+ i_msg );
}
-
- // check input range - ISubStep
- if ( i_SubStep >= g_isteps[i_IStep].numitems )
+ else
{
- TRACDCOMP( g_trac_initsvc,
- "IStep %d Substep %d out of range.",
- i_IStep,
- i_SubStep );
- break; // break out with l_pistep set to NULL
+ // should never get here, but if we do, just return back...
+ // Nothing to send.
}
- // check for end of list.
- if ( g_isteps[i_IStep].pti[i_SubStep].taskflags.task_type
- == END_TASK_LIST )
+ if( err )
{
- TRACDCOMP( g_trac_initsvc,
- "IStep %d SubStep %d task_type==END_TASK_LIST.",
- i_IStep,
- i_SubStep );
break;
}
+ } while( 0 );
- // check to see if the pointer to the function is NULL.
- // This is possible if some of the substeps aren't working yet
- // and are just placeholders.
- if ( g_isteps[i_IStep].pti[i_SubStep].taskfn == NULL )
- {
- TRACDCOMP( g_trac_initsvc,
- "IStep %d SubStep %d fn ptr is NULL.",
- i_IStep,
- i_SubStep );
- break;
- }
+ TRACDCOMP( g_trac_initsvc,
+ EXIT_MRK"IStepDispatcher::sendMboxMsg()" );
+
+ return err;
+}
- // we're good, set the istep & return it to caller
- l_pistep = &( g_isteps[i_IStep].pti[i_SubStep] );
+// ----------------------------------------------------------------------------
+// IStepDispatcher::getIstepInfo()
+// ----------------------------------------------------------------------------
+void IStepDispatcher::getIstepInfo ( uint8_t & o_iStep,
+ uint8_t & o_subStep )
+{
+ mutex_lock( &iv_stepMutex );
+ o_iStep = iv_curIStep;
+ o_subStep = iv_curSubStep;
+ mutex_unlock( &iv_stepMutex );
+}
- } while ( 0 );
- return l_pistep;
+// ----------------------------------------------------------------------------
+// IStepDispatcher::setIstepInfo()
+// ----------------------------------------------------------------------------
+void IStepDispatcher::setIstepInfo ( uint16_t i_type )
+{
+ mutex_lock( &iv_stepMutex );
+ iv_curIStep = ((i_type & 0xFF00) >> 8);
+ iv_curSubStep = (i_type & 0xFF);
+ mutex_unlock( &iv_stepMutex );
}
-bool IStepDispatcher::getIStepMode( ) const
+// ----------------------------------------------------------------------------
+// IStepDispatcher::handleSyncPointReachedMsg()
+// ----------------------------------------------------------------------------
+void IStepDispatcher::handleSyncPointReachedMsg ( void )
{
- using namespace TARGETING;
- Target* l_pTopLevel = NULL;
- bool l_istepmodeflag = false;
- TargetService& l_targetService = targetService();
+ TRACDCOMP( g_trac_initsvc,
+ ENTER_MRK"IStepDispatcher::handleSyncPointReachedMsg()" );
- (void) l_targetService.getTopLevelTarget(l_pTopLevel);
- if (l_pTopLevel == NULL)
- {
- TRACFCOMP( g_trac_initsvc, "Top level handle was NULL" );
- l_istepmodeflag = false;
- }
- else
+ do
{
- l_istepmodeflag = l_pTopLevel->getAttr<ATTR_ISTEP_MODE> ();
- // printk( "IStep Mode flag = 0x%x\n", l_istepmodeflag );
- }
+ // Indicate we hit a sync point, and get anyone waiting moving.
+ mutex_lock( &iv_syncMutex );
+ iv_sync = true;
+ sync_cond_signal( &iv_syncHit );
+ mutex_unlock( &iv_syncMutex );
+ } while( 0 );
- return l_istepmodeflag;
+ TRACDCOMP( g_trac_initsvc,
+ EXIT_MRK"IStepDispatcher::handleSyncPointReachedMsg()" );
}
-bool IStepDispatcher::getCanContinueProcedure( const TaskInfo &i_failingIStep,
- errlHndl_t &i_failingError,
- TaskInfo &io_nextIstep
- ) const
+// ----------------------------------------------------------------------------
+// IStepDispatcher::handleMoreWorkNeededMsg()
+// ----------------------------------------------------------------------------
+void IStepDispatcher::handleMoreWorkNeededMsg ( void )
{
+ TRACDCOMP( g_trac_initsvc,
+ ENTER_MRK"IStepDispatcher::handleMoreWorkNeededMsg()" );
- return false;
-}
+ // Clear out current Istep/substep values. Since worker thread told us
+ // its done, nothing is running right now.
+ iv_curIStep = 0x0;
+ iv_curSubStep = 0x0;
+ // Only something to do if we've gotten a request from Fsp or SPLESS
+ if( iv_Msg )
+ {
+ // Send response back to caller?
+ if( !msg_is_async( iv_Msg ) )
+ {
+ // TODO - Is data[0] status?? Not in HwSvr Doc.
+ iv_Msg->data[0] = 0x0;
+ // Send a possible errlog back to Fsp.
+ iv_Msg->extra_data = iv_workerMsg->extra_data;
+ msg_respond( iv_msgQ,
+ iv_Msg );
+ iv_Msg = NULL;
+ }
+ }
+ else
+ {
+ // We should never be here... Worker message should only be doing
+ // something if it got a request from outside.
+ }
-IStepDispatcher& IStepDispatcher::getTheInstance()
-{
- return Singleton<IStepDispatcher>::instance();
+ TRACDCOMP( g_trac_initsvc,
+ EXIT_MRK"IStepDispatcher::handleMoreWorkNeededMsg()" );
}
-void IStepDispatcher::handleBreakPoint( uint32_t i_info )
+// ----------------------------------------------------------------------------
+// iStepBreakPoint()
+// ----------------------------------------------------------------------------
+void iStepBreakPoint ( uint32_t i_info )
{
- msg_t *l_pBpMsg = msg_allocate();
- errlHndl_t l_errl = NULL;
-
- // need to be the only poller
- mutex_lock(&iv_poll_mutex);
-
+ TRACFCOMP( g_trac_initsvc,
+ ENTER_MRK"handleBreakpointMsg()" );
+ IStepDispatcher::getTheInstance().handleBreakpoint( i_info );
+}
- l_pBpMsg->type = BREAKPOINT_TYPE;
- l_pBpMsg->data[0] =
- ( static_cast<uint64_t>( i_info ) << 32 ) |
- static_cast<uint64_t>( 0 ) ;
- l_pBpMsg->data[1] = 0;
- l_pBpMsg->extra_data = NULL;
- // send new message to FSP
+// ----------------------------------------------------------------------------
+// IStepDispatcher::handleBreakpoint()
+// ----------------------------------------------------------------------------
+void IStepDispatcher::handleBreakpoint ( uint32_t i_info )
+{
+ // Throttle the breakpoints by locking here.
+ mutex_lock( &iv_bkPtMutex );
+ errlHndl_t err = NULL;
TRACDCOMP( g_trac_initsvc,
- "handleBreakPoint: FSP: send sts type 0x%x, msg 0x%x.%x",
- l_pBpMsg->type,
- static_cast<uint32_t>( l_pBpMsg->data[0] >> 32 ),
- static_cast<uint32_t>( l_pBpMsg->data[0] & 0xffffffff ) );
-
- // send status to FSP
- l_errl = MBOX::sendrecv( MBOX::HB_ISTEP_MSGQ, l_pBpMsg );
- if ( l_errl )
+ ENTER_MRK"IStepDispatcher::handleBreakpointMsg()" );
+
+ // Send Breakpoint msg to Fsp.
+ msg_t * myMsg = msg_allocate();
+ myMsg->type = BREAKPOINT;
+ uint64_t tmpVal = 0x0;
+ tmpVal = tmpVal & i_info;
+ myMsg->data[0] = (tmpVal << 32); // TODO - Is this really a Fsp requirement?
+ myMsg->data[1] = 0x0;
+ myMsg->extra_data = NULL;
+
+ if( !(SPLESS::SPLessAttached()) )
{
- TRACFCOMP( g_trac_initsvc,
- "handleBreakPoint: ERROR on MBOX sendrecv" );
- errlCommit( l_errl, INITSVC_COMP_ID );
-
- // If sendrecv fails for some reason, error will be logged and
- // breakpoint will resume anyway.
+ // FSP Attached
+ // Wait for Fsp to respond.
+ err = sendMboxMsg( ISTEP_SYNC,
+ myMsg );
+ // TODO - Do we care what they sent back? Not sure... HwSvr
+ // has no documentation on this...
+ if( err )
+ {
+ errlCommit( err,
+ INITSVC_COMP_ID );
+ }
+ }
+ else
+ {
+ // SPLESS
+ msg_respond( iv_msgQ,
+ myMsg );
+
+ // Now wait for spless code to respond that we're done with the
+ // breakpoint
+ msg_t * rspMsg;
+ rspMsg = msg_wait( iv_msgQ );
}
- // unblocked
+ msg_free( myMsg );
TRACDCOMP( g_trac_initsvc,
- "handleBreakPoint exit: receive msg type 0x%x, msg 0x%x.%x",
- l_pBpMsg->type,
- static_cast<uint32_t>( l_pBpMsg->data[0] >> 32 ),
- static_cast<uint32_t>( l_pBpMsg->data[0] & 0xffffffff ) );
-
- msg_free( l_pBpMsg );
- mutex_unlock(&iv_poll_mutex);
+ EXIT_MRK"IStepDispatcher::handleBreakpointMsg()" );
+ mutex_unlock( &iv_bkPtMutex );
}
-void IStepDispatcher::handleSPlessBreakPoint( uint32_t i_info )
+// ----------------------------------------------------------------------------
+// IStepDispatcher::handleIStepRequestMsg()
+// ----------------------------------------------------------------------------
+void IStepDispatcher::handleIStepRequestMsg ( void )
{
-
- TRACDCOMP( g_trac_initsvc,
- "handleBreakPoint: hijacking message Q" );
-
- // need to be the only poller
- mutex_lock(&iv_poll_mutex);
-
-
- iv_pMsg->type = BREAKPOINT_TYPE;
- iv_pMsg->data[0] =
- ( static_cast<uint64_t>( i_info ) << 32 ) |
- static_cast<uint64_t>( 0 ) ;
- iv_pMsg->data[1] = 0;
- iv_pMsg->extra_data = NULL;
-
TRACDCOMP( g_trac_initsvc,
- "handleBreakPoint: send sts msg type 0x%x, msg 0x%x.%x",
- iv_pMsg->type,
- static_cast<uint32_t>( iv_pMsg->data[0] >> 32 ),
- static_cast<uint32_t>( iv_pMsg->data[0] & 0xffffffff ) );
+ ENTER_MRK"IStepDispatcher::handleIStepRequestMsg()" );
- // respond to SPtask
- msg_respond( iv_msgQ, iv_pMsg );
-
- // Poll for cmd to resume
- while( 1 )
+ // Only something to do, if the worker thread is ready for work
+ if( iv_workerMsg )
{
+ // Set new istep/substep info
+ uint16_t stepInfo = ((iv_Msg->data[0] & 0x000000FF00000000) >> 24);
+ stepInfo = (stepInfo | (iv_Msg->data[0] & 0xFF) );
+ setIstepInfo( stepInfo );
- // wait for message from SPtask
- iv_pMsg = msg_wait( iv_msgQ );
-
- // unblocked
+ TRACFCOMP( g_trac_initsvc,
+ INFO_MRK"Istep req: 0x%04x",
+ stepInfo );
- if ( msg_is_async( iv_pMsg ) )
- {
- // should not receive async messages here, drop it, post errorlog
- // and go back to waiting.
- TRACFCOMP( g_trac_initsvc,
- "handleBreakPoint: ERROR async msg type 0x%x, msg 0x%x.%x",
- iv_pMsg->type,
- static_cast<uint32_t>( iv_pMsg->data[0] >> 32 ),
- static_cast<uint32_t>( iv_pMsg->data[0] & 0xffffffff ) );
-
- /*@ errorlog tag
- * @errortype ERRL_SEV_INFORMATIONAL
- * @moduleid ISTEP_INITSVC_MOD_ID
- * @reasoncode ISTEP_BKPOINT_ASYNC_RCVD
- * @userdata1 type of packet
- * @userdata2 first data word
- *
- * @devdesc IStepDisp handleSPlessBreakPoint was expecting a
- * synchronous message and received an asynchonous
- * message.
- *
- */
- errlHndl_t l_errlAsync = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_INFORMATIONAL,
- INITSERVICE::ISTEP_INITSVC_MOD_ID,
- INITSERVICE::ISTEP_BKPOINT_ASYNC_RCVD,
- iv_pMsg->type,
- iv_pMsg->data[0] );
-
- errlCommit( l_errlAsync, INITSVC_COMP_ID );
-
- msg_free( iv_pMsg );
- iv_pMsg = NULL;
- continue;
- }
+ // Set step/substep in data[0];
+ iv_workerMsg->data[0] = stepInfo;
+ msg_respond( iv_msgQ,
+ iv_workerMsg );
- TRACDCOMP( g_trac_initsvc,
- "handleBreakPoint: receive msg type 0x%x, msg 0x%x.%x",
- iv_pMsg->type,
- static_cast<uint32_t>( iv_pMsg->data[0] >> 32 ),
- static_cast<uint32_t>( iv_pMsg->data[0] & 0xffffffff ) );
+ iv_workerMsg = NULL;
+ }
- // only expect this command
- if ( iv_pMsg->type == BREAKPOINT_TYPE )
- {
- // correct response, return to istep
- break;
- }
- else
- {
- // all other commands are not valid here, return the same status
- iv_pMsg->type = BREAKPOINT_TYPE;
- iv_pMsg->data[0] =
- ( static_cast<uint64_t>( i_info ) << 32 ) |
- static_cast<uint64_t>( 0 ) ;
- iv_pMsg->data[1] = 0;
- iv_pMsg->extra_data = NULL;
-
- TRACDCOMP( g_trac_initsvc,
- "handleBreakPoint: send sts msg type 0x%x, msg 0x%x.%x",
- iv_pMsg->type,
- static_cast<uint32_t>( iv_pMsg->data[0] >> 32 ),
- static_cast<uint32_t>( iv_pMsg->data[0] & 0xffffffff ) );
-
- // reply back FSP/console
- msg_respond( iv_msgQ, iv_pMsg );
- } // end else
- } // end while
-
- mutex_unlock(&iv_poll_mutex);
+ TRACDCOMP( g_trac_initsvc,
+ EXIT_MRK"IStepDispatcher::handleIStepRequestMsg()" );
}
-// route to SPless or FSP depending on what's attached
-void iStepBreakPoint(uint32_t i_info)
+
+// ----------------------------------------------------------------------------
+// IStepDispatcher::getIStepMode()
+// ----------------------------------------------------------------------------
+bool IStepDispatcher::getIStepMode( ) const
{
- if ( SPLESS::SPLessAttached() )
+ using namespace TARGETING;
+ Target* l_pTopLevel = NULL;
+ bool l_istepmodeflag = false;
+ TargetService& l_targetService = targetService();
+
+ (void)l_targetService.getTopLevelTarget( l_pTopLevel );
+ if( l_pTopLevel == NULL )
{
- IStepDispatcher::getTheInstance().handleSPlessBreakPoint( i_info );
+ TRACFCOMP( g_trac_initsvc,
+ "Top level handle was NULL" );
+ l_istepmodeflag = false;
}
else
{
- IStepDispatcher::getTheInstance().handleBreakPoint( i_info );
+ l_istepmodeflag = l_pTopLevel->getAttr<ATTR_ISTEP_MODE> ();
}
-}
-
-void getIstepMsgQ ( msg_q_t & o_msgQ )
-{
- Singleton<IStepDispatcher>::instance().getIstepMsgQ( o_msgQ );
-}
-void IStepDispatcher::getIstepMsgQ ( msg_q_t & o_msgQ )
-{
- o_msgQ = iv_msgQ;
-}
-
-void getIstepMsg ( msg_t* & o_msg )
-{
- Singleton<IStepDispatcher>::instance().getIstepMsg( o_msg );
-}
-void IStepDispatcher::getIstepMsg ( msg_t* & o_msg )
-{
- o_msg = iv_pMsg;
+ return l_istepmodeflag;
}
-IStepDispatcher::IStepDispatcher()
-: iv_sts()
+// ----------------------------------------------------------------------------
+// IStepDispatcher::spLess()
+// ----------------------------------------------------------------------------
+bool IStepDispatcher::spLess ( void )
{
- SPLESS::initIStepMode();
- mutex_init(&iv_poll_mutex);
-
- // init mailbox / message Q.
- iv_msgQ = msg_q_create();
+ bool spless = true;
+ TARGETING::Target * sys = NULL;
+ TARGETING::targetService().getTopLevelTarget( sys );
+ TARGETING::SpFunctions spfuncs;
+ if( sys &&
+ sys->tryGetAttr<TARGETING::ATTR_SP_FUNCTIONS>(spfuncs) &&
+ spfuncs.mailboxEnabled )
+ {
+ spless = false;
+ }
+ return spless;
}
-IStepDispatcher::~IStepDispatcher()
-{ }
-
-
} // namespace
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.H b/src/usr/initservice/istepdispatcher/istepdispatcher.H
index b887a8829..1025704a5 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.H
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.H
@@ -42,23 +42,16 @@
/******************************************************************************/
#include <stdint.h>
#include <util/singleton.H>
-
#include <sys/msg.h>
-#include <mbox/mboxif.H> // mailbox Q
-#include <mbox/mbox_queues.H> // HB_ISTEP_MSGQ
-
+#include <sys/sync.h>
#include <errl/errlentry.H>
#include <initservice/taskargs.H>
#include <initservice/initsvcreasoncodes.H>
#include <initservice/initsvcstructs.H>
-
#include "../baseinitsvc/initservice.H"
-
#include "splesscommon.H"
-
#include "istep_mbox_msgs.H"
-
namespace INITSERVICE
{
@@ -78,9 +71,18 @@ namespace INITSERVICE
* param[in,out] - pointer to any args
*
* @return nothing
- *
*/
-void spTask( void *io_pArgs );
+void spTask ( void *io_pArgs );
+
+/**
+ * @brief enums for whether the messages IStepdispatcher sends are synchronus
+ * or asynchronous.
+ */
+enum IStepSync_t
+{
+ ISTEP_SYNC,
+ ISTEP_ASYNC,
+};
/******************************************************************************/
@@ -105,53 +107,71 @@ public:
*/
static IStepDispatcher& getTheInstance();
-
/**
- * @brief Provide an entry function into the class, called from _start()
+ * @brief This function is what is called to startup the main istep
+ * dispatcher thread.
*
- * @param[in] io_rtaskRetErrl - ref to errlHndl_t passed back to _start().
+ * @param[in/out] io_rtaskRetErrl - Errorlog pointer to be returned for
+ * any errors that might have been encountered.
*
- * @return nothing
+ * @return NONE.
*/
- void init( errlHndl_t &io_rtaskRetErrl );
+ void init ( errlHndl_t &io_rtaskRetErrl );
+ /**
+ * @brief This function is used to send a sync point message from Hostboot
+ * to the Fsp.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+ errlHndl_t sendSyncPoint ( void );
/**
- * @brief Handle an istep break point to FSP
- * @param[in] i_info, @TODO - location/info
+ * @brief This function is used for calling code to be held off waiting
+ * for a syncpoint message from an external source. Anyone calling
+ * this will be blocked on this call until ANY sync point message is
+ * received. Once received, each caller in succession will be
+ * released.
*
- * @note blocks until an outside istep cmd to resume is received.
+ * @return NONE.
*/
- void handleBreakPoint( uint32_t info);
+ void waitForSyncPoint ( void );
/**
- * @brief Handle an istep break point from SPless
- * @param[in] i_info, @TODO - location/info
- * @pre iv_sts contains current istep status + seqnum or
- * 0 if not in step mode
- * @note blocks until an outside istep cmd to resume is recieved.
+ * @brief This function when called will send a Istep complete mailbox
+ * message to the Fsp to indicate that the current Istep is complete.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
*/
- void handleSPlessBreakPoint( uint32_t info);
+ errlHndl_t sendIstepCompleteMsg ( void );
/**
- * @brief This function returns the MBOX Message Queue used by the istep
- * dispatcher.
+ * @brief This function will handle all breakpoint requests from the
+ * running istep code. The running istep code would be initiated via
+ * the istep dispatcher worker thread. Thus, holding off the worker
+ * thread.
*
- * @param[out] o_msgQ - The message queue.
+ * @param[in] i_info - TODO - this needs to be decided yet. But it seems
+ * at least preliminarily that this will contain a unique breakpoint
+ * numbering value.
*
* @return NONE.
*/
- void getIstepMsgQ ( msg_q_t & o_msgQ );
+ void handleBreakpoint ( uint32_t i_info );
/**
- * @brief This function returns the current MBOX Message used by the istep
- * dispatcher.
+ * @brief This function will return the current istep and substep.
+ *
+ * @param[out] o_iStep - The current Istep value.
*
- * @param[out] o_msg - The message.
+ * @param[out] o_subStep - The current SubStep value.
*
* @return NONE.
*/
- void getIstepMsg ( msg_t* & o_msg );
+ void getIstepInfo ( uint8_t & o_iStep,
+ uint8_t & o_subStep );
protected:
@@ -182,104 +202,93 @@ private:
* @retval false if IStep Mode is "OFF"
* true if IStep Mode is "ON"
*/
- bool getIStepMode( ) const;
+ bool getIStepMode( ) const;
+ /**
+ * @brief This function will start at istep 0, substep 0, and cycle
+ * through all possible isteps, returning when complete, or an error
+ * is hit.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to an
+ * error log.
+ */
+ errlHndl_t executeAllISteps ( void );
/**
- * @brief Find a TaskInfo struct in the global istep list(s),
- * addressed by { IStep, SubStep }
+ * @brief This function is the main handler loop for the Istep Dispatcher.
+ * it receives all messages from outside sources and initiates the
+ * proper action and response (if required).
*
- * @param[in] i_IStep - IStepNumber
- * @param[in] i_SubStep - SubStepNumber
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to an
+ * error log.
+ */
+ errlHndl_t msgHndlr ( void );
+
+ /**
+ * @brief This function is used to send mailbox messages to the Fsp.
*
- * @return pointer to a TaskInfo struct
- * @retval pointer to a TaskInfo struct, or NULL
+ * @param[in] i_sendSync - The sync type of message to send. Whether
+ * synchronous or asynchronous.
*
+ * @param[in] i_msg - The message to send to the Fsp.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to an
+ * error log.
*/
- const TaskInfo *findTaskInfo(
- const uint32_t i_IStep,
- const uint32_t i_SubStep ) const;
-
- /**
- * @brief runAllISteps
- *
- * Run all available ISteps sequentially.
- * If an IStep gets an error, report it and stop.
- * Otherwise, return.
- *
- * @param[in,out] - ref to an errlHndl_t that can be passed back to
- * ExtInitSvc .
- *
- * @return none
- */
- void runAllISteps( errlHndl_t &io_rtaskRetErrl ) ;
-
-
- /**
- * @brief singleStepISteps
- *
- * Go into a polling loop, waiting for Istep commands from
- * the FSP or SPTask.
- *
- * @param[in,out] - ref to an errlHndl_t that can be passed back to
- * ExtInitSvc .
- * @return none
- */
- void singleStepISteps( errlHndl_t &io_rtaskRetErrl ) ;
+ errlHndl_t sendMboxMsg ( IStepSync_t i_sendSync,
+ msg_t * i_msg );
+ /**
+ * @brief This function is used for all of the Syncpoint message handling.
+ *
+ * @return NONE.
+ */
+ void handleSyncPointReachedMsg ( void );
/**
- * @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).
+ * @brief This function is used to handle the message from the worker
+ * thread requesting more work.
*
- * @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 NONE.
+ */
+ void handleMoreWorkNeededMsg ( void );
+
+ /**
+ * @brief This function is used to handle the single Istep requests from
+ * outside sources.
+ *
+ * @return NONE.
+ */
+ void handleIStepRequestMsg ( void );
+
+ /**
+ * @brief This function is used to set the current Istep and Substep
+ * values for what is currently running.
*
- * @return bool
- * @retval false if there is no Can-Continue procedure,
- * true otherwise
+ * @return NONE.
+ */
+ void setIstepInfo ( uint16_t i_type );
+
+ /**
+ * @brief This function will return whether or not we are SPless
*
- * @todo 2011-08-22 currently the defs for this procedure are pretty
- * vague - requirements for Can-Continue behaviour have not been
- * defined yet.
+ * @return bool - whether we are SPLESS.
*/
- bool getCanContinueProcedure(
- const TaskInfo &i_failingIStep,
- errlHndl_t &i_failingError,
- TaskInfo &io_nextIStep ) const;
-
-
- /**
- * @brief Command 0: Run the requested IStep/SubStep
- *
- * param[in] i_IStep - IStep number
- * param[in] i_Substep - Substep number
- * param[out] o_rSts - lookup status - returns Invalid if the
- * IStep, Substep doesn't exist
- *
- * @post iv_sts set to current istep status
- *
- * @return errlHndl_t
- */
- errlHndl_t processSingleIStepCmd(
- const uint32_t i_IStep,
- const uint32_t i_Substep,
- uint32_t &o_rSts );
+ bool spLess ( void );
// ----- internal vars -----------------------------
- mutex_t iv_poll_mutex; //!< protect who's polling istep cmds
- SPLESS::SPLessSts iv_sts; //!< Current status of istep mode
- msg_q_t iv_msgQ; //!< Message Q to FSP & SPTask.
- msg_t *iv_pMsg; //!< ptr to msg from FSP or user console
+ mutex_t iv_bkPtMutex;
+ mutex_t iv_syncMutex;
+ mutex_t iv_stepMutex;
+ sync_cond_t iv_syncHit;
+ uint8_t iv_curIStep;
+ uint8_t iv_curSubStep;
+ bool iv_sync;
+ msg_q_t iv_msgQ;
+ msg_t* iv_workerMsg; // More work Needed Msg from Worker
+ msg_t* iv_Msg; // All other Msgs that need to be saved
}; // class IStepDispatcher
diff --git a/src/usr/initservice/istepdispatcher/makefile b/src/usr/initservice/istepdispatcher/makefile
index eaae9b9ea..04a6da054 100644
--- a/src/usr/initservice/istepdispatcher/makefile
+++ b/src/usr/initservice/istepdispatcher/makefile
@@ -1,11 +1,11 @@
-# IBM_PROLOG_BEGIN_TAG
+# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
# $Source: src/usr/initservice/istepdispatcher/makefile $
#
# IBM CONFIDENTIAL
#
-# COPYRIGHT International Business Machines Corp. 2011 - 2012
+# COPYRIGHT International Business Machines Corp. 2011-2012
#
# p1
#
@@ -24,7 +24,7 @@ ROOTPATH = ../../../..
MODULE = istepdisp
OBJS = istepdispatcher.o initsvcudistep.o \
- sptask.o splesscommon.o
+ sptask.o splesscommon.o istepWorker.o
## SUBDIRS = test.d
diff --git a/src/usr/initservice/istepdispatcher/splesscommon.C b/src/usr/initservice/istepdispatcher/splesscommon.C
index fdba904de..809915014 100644
--- a/src/usr/initservice/istepdispatcher/splesscommon.C
+++ b/src/usr/initservice/istepdispatcher/splesscommon.C
@@ -119,6 +119,14 @@ void initIStepMode( )
// $$ save l_readData = mmio_scratch_read( MMIO_SCRATCH_IPLSTEP_CONFIG );
l_readData = g_SPLess_IStepMode_Reg;
+ // Get the Thread 5 scratch reg
+ uint64_t t5ScratchVal = mmio_scratch_read( MMIO_SCRATCH_ISTEP_MODE );
+ TRACFCOMP( INITSERVICE::g_trac_initsvc,
+ INFO_MRK"Thread 5 scratch reg val: 0x%08x",
+ t5ScratchVal );
+ // Only need 1 bit.
+ t5ScratchVal = t5ScratchVal & 0x1;
+
#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 );
@@ -130,8 +138,8 @@ void initIStepMode( )
// check for IStep Mode signature(s)
if ( ( l_readData == ISTEP_MODE_SPLESS_SIGNATURE )
- || ( l_readData == ISTEP_MODE_FSP_SIGNATURE )
- )
+ || ( l_readData == ISTEP_MODE_FSP_SIGNATURE ) ||
+ ( 0x1 == t5ScratchVal ) )
{
l_pTopLevel->setAttr<ATTR_ISTEP_MODE> (true );
diff --git a/src/usr/initservice/istepdispatcher/splesscommon.H b/src/usr/initservice/istepdispatcher/splesscommon.H
index 3dd0f9030..dc3fb30b0 100644
--- a/src/usr/initservice/istepdispatcher/splesscommon.H
+++ b/src/usr/initservice/istepdispatcher/splesscommon.H
@@ -5,7 +5,7 @@
*
* IBM CONFIDENTIAL
*
- * COPYRIGHT International Business Machines Corp. 2011 - 2012
+ * COPYRIGHT International Business Machines Corp. 2011-2012
*
* p1
*
@@ -100,11 +100,11 @@ enum {
* @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 uint8_t SPLESS_CLEAR_TRACE_CMD = 0x02;
-const uint8_t SPLESS_SHUTDOWN_CMD = 0x03;
-const uint64_t SPLESS_SINGLE_STEP_STS_MASK = 0x00000000ffffffff;
+//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;
/**
* @brief init ISTEP_MODE attribute
diff --git a/src/usr/initservice/istepdispatcher/sptask.C b/src/usr/initservice/istepdispatcher/sptask.C
index 842a259be..417754412 100644
--- a/src/usr/initservice/istepdispatcher/sptask.C
+++ b/src/usr/initservice/istepdispatcher/sptask.C
@@ -79,46 +79,6 @@ const uint64_t SINGLESTEP_PAUSE_S = 0;
const uint64_t SINGLESTEP_PAUSE_NS = 10000000;
/**
- * @brief Translate beween commands on SPless user console and FSP commands
- *
- * @param[in] - command from SPLess user console
- *
- * @return FSP command
- *
- */
-uint32_t SPLessToFSP( const uint8_t i_cmd )
-{
- uint32_t l_FSPCmd = 0;
-
- switch( i_cmd )
- {
-
- case SPLESS_SINGLE_ISTEP_CMD:
- l_FSPCmd = SINGLE_STEP_TYPE;
- break;
- case SPLESS_RESUME_ISTEP_CMD:
- l_FSPCmd = BREAKPOINT_TYPE;
- break;
- case SPLESS_CLEAR_TRACE_CMD:
- l_FSPCmd = CLEAR_TRACE_TYPE;
- break;
- case SPLESS_SHUTDOWN_CMD:
- l_FSPCmd = SHUTDOWN_TYPE;
- break;
- default:
- TRACFCOMP( g_trac_initsvc,
- "spTask ERROR: unknown cmd %d",
- i_cmd );
- // should never happen...
- assert( 0 );
- }
-
- return l_FSPCmd;
-}
-
-
-
-/**
* @brief userConsoleComm
*
* Communicate with User Console on VPO or Simics.
@@ -198,10 +158,10 @@ void userConsoleComm( void * io_msgQ )
writeSts( l_sts );
// pass the command on to IstepDisp, block until reply
- l_pCurrentMsg->type = SPLessToFSP( l_cmd.hdr.cmdnum );
- l_pCurrentMsg->data[0] =
- ( static_cast<uint64_t>( l_cmd.istep ) << 32 ) |
- static_cast<uint64_t>( l_cmd.substep ) ;
+ l_pCurrentMsg->type = 0x0;
+ l_pCurrentMsg->data[0] =
+ ( ( static_cast<uint64_t>(l_cmd.istep & 0xFF) << 32) |
+ ( static_cast<uint64_t>(l_cmd.substep & 0xFF ) ) );
l_pCurrentMsg->data[1] = 0;
l_pCurrentMsg->extra_data = NULL;
@@ -233,7 +193,7 @@ void userConsoleComm( void * io_msgQ )
static_cast<uint32_t>( l_pCurrentMsg->data[0] >> 32 ),
static_cast<uint32_t>( l_pCurrentMsg->data[0] & 0x0ffffffff ) );
- if ( l_pCurrentMsg->type == BREAKPOINT_TYPE )
+ if ( l_pCurrentMsg->type == BREAKPOINT )
{
l_sts.hdr.status = SPLESS_AT_BREAK_POINT;
}
@@ -258,6 +218,9 @@ void userConsoleComm( void * io_msgQ )
// if shutdown issued, end this task
if ( l_cmd.hdr.cmdnum == SPLESS_SHUTDOWN_CMD )
{
+ TRACFCOMP( g_trac_initsvc,
+ "sptask: shutdown received" );
+
l_quitflag = true;
}
@@ -274,9 +237,11 @@ void userConsoleComm( void * io_msgQ )
writeCmd( l_cmd );
} // endif gobit
-
if ( l_quitflag == true )
{
+ TRACFCOMP( g_trac_initsvc,
+ "sptask: got quitflag" );
+
// shutdown command issued, break out of loop
break;
}
@@ -300,6 +265,9 @@ void userConsoleComm( void * io_msgQ )
}
} // endwhile
+ TRACFCOMP( g_trac_initsvc,
+ "sptask: Uh-oh, we just exited... what went wrong?" );
+
// @note
// Fell out of loop, clear sts reg and turn off readybit
// disable the ready bit so the user knows.
OpenPOWER on IntegriCloud