summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliott Dahle <dedahle@us.ibm.com>2013-10-21 14:56:20 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-11-08 15:23:22 -0600
commitf993373dac7e69fd8cfc54c105f0a793f6f362f5 (patch)
tree3e4f33ce34cccc6771b8a2b50bfb32cc8cdb045f
parentc811df7983a6dbb0d56b96badb58ed785ddd0b72 (diff)
downloadtalos-hostboot-f993373dac7e69fd8cfc54c105f0a793f6f362f5.tar.gz
talos-hostboot-f993373dac7e69fd8cfc54c105f0a793f6f362f5.zip
Support power off in the middle of Hostboot IPL
Change-Id: I7908347e4252400838fc28b14fc8cde69085c908 RTC: 35520 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/6800 Tested-by: Jenkins Server Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com> Reviewed-by: Brian H. Horton <brianh@linux.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--src/include/usr/initservice/initsvcreasoncodes.H2
-rw-r--r--src/usr/initservice/istepdispatcher/istep_mbox_msgs.H3
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.C156
-rw-r--r--src/usr/initservice/istepdispatcher/istepdispatcher.H27
4 files changed, 156 insertions, 32 deletions
diff --git a/src/include/usr/initservice/initsvcreasoncodes.H b/src/include/usr/initservice/initsvcreasoncodes.H
index 03facd4ea..02c422670 100644
--- a/src/include/usr/initservice/initsvcreasoncodes.H
+++ b/src/include/usr/initservice/initsvcreasoncodes.H
@@ -63,6 +63,8 @@ enum InitServiceReasonCode
NO_MSG_PRESENT = INITSVC_COMP_ID | 0x08,
ISTEP_RECONFIG_LOOP_ENTERED = INITSVC_COMP_ID | 0x09,
ISTEP_FAILED_DUE_TO_DECONFIG = INITSVC_COMP_ID | 0x0a,
+ //termination_rc
+ SHUTDOWN_REQUESTED_BY_FSP = INITSVC_COMP_ID | 0x0b,
};
enum InitServiceUserDetailDataSubSection
diff --git a/src/usr/initservice/istepdispatcher/istep_mbox_msgs.H b/src/usr/initservice/istepdispatcher/istep_mbox_msgs.H
index 57bdb9486..c7b97e25b 100644
--- a/src/usr/initservice/istepdispatcher/istep_mbox_msgs.H
+++ b/src/usr/initservice/istepdispatcher/istep_mbox_msgs.H
@@ -57,6 +57,7 @@ enum
HWSVR_SYNC_POINT = 0x10,
HWSVR_IPL_PROGRESS_CODE = 0x11,
HWSVR_DO_IOVALID_PROCESSING = 0xC1,
+ HWSVR_DO_SHUTDOWN = 0x12
};
// ------------------------------------------------------------------
@@ -76,6 +77,8 @@ enum
HWSVR_DO_IOVALID_PROCESSING,
IPL_PROGRESS_CODE = MBOX::FIRST_UNSECURE_MSG |
HWSVR_IPL_PROGRESS_CODE,
+ SHUTDOWN = MBOX::FIRST_UNSECURE_MSG |
+ HWSVR_DO_SHUTDOWN,
};
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C
index 57ce650b8..854aa80ed 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.C
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C
@@ -96,12 +96,12 @@ IStepDispatcher::IStepDispatcher() :
iv_progressThreadStarted(false),
iv_curIStep(0),
iv_curSubStep(0),
- iv_pIstepMsg(NULL)
+ iv_pIstepMsg(NULL),
+ iv_shutdown(false)
{
mutex_init(&iv_bkPtMutex);
mutex_init(&iv_mutex);
- mutex_init(&iv_syncMutex);
- sync_cond_init(&iv_syncHit);
+ sync_cond_init(&iv_cond);
TARGETING::Target* l_pSys = NULL;
TARGETING::targetService().getTopLevelTarget(l_pSys);
@@ -428,25 +428,36 @@ errlHndl_t IStepDispatcher::doIstep(uint32_t i_istep,
if (!iv_istepMode)
{
mutex_lock(&iv_mutex);
+ // Record current IStep, SubStep
iv_curIStep = i_istep;
iv_curSubStep = i_substep;
- // Send Progress Code
- err = this->sendProgressCode(false);
- mutex_unlock(&iv_mutex);
-
- if(err)
+ // If a shutdown request has been received
+ if (iv_shutdown)
{
- // Commit the error and continue
- errlCommit(err, INITSVC_COMP_ID);
+ mutex_unlock(&iv_mutex);
+ // Do not begin new IStep and shutdown
+ shutdownDuringIpl();
}
-
- // Start progress thread, if not yet started
- if (!iv_progressThreadStarted)
+ else
{
- tid_t l_progTid = task_create(startProgressThread,this);
- assert( l_progTid > 0 );
- iv_progressThreadStarted = true;
+ // Send Progress Code
+ err = this->sendProgressCode(false);
+ mutex_unlock(&iv_mutex);
+
+ if(err)
+ {
+ // Commit the error and continue
+ errlCommit(err, INITSVC_COMP_ID);
+ }
+
+ // Start progress thread, if not yet started
+ if (!iv_progressThreadStarted)
+ {
+ tid_t l_progTid = task_create(startProgressThread,this);
+ assert( l_progTid > 0 );
+ iv_progressThreadStarted = true;
+ }
}
}
@@ -769,6 +780,20 @@ void IStepDispatcher::msgHndlr()
TRACFCOMP(g_trac_initsvc, ERR_MRK"msgHndlr: Ignoring IStep msg in non-IStep mode!");
}
break;
+ case SHUTDOWN:
+ // Shutdown requested from Fsp
+ TRACFCOMP(g_trac_initsvc, INFO_MRK"msgHndlr: SHUTDOWN");
+ // If not in IStep mode, further process the shutdown message
+ // otherwise, ignore it
+ if (!iv_istepMode)
+ {
+ handleShutdownMsg(pMsg);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_initsvc, ERR_MRK"msgHndlr: Ignoring shutdown msg in IStep mode!");
+ }
+ break;
default:
TRACFCOMP(g_trac_initsvc, ERR_MRK"msgHndlr: Ignoring unknown message 0x%08x",
pMsg->type);
@@ -793,13 +818,22 @@ void IStepDispatcher::waitForSyncPoint()
else
{
// Wait for the condition variable to be signalled
- mutex_lock(&iv_syncMutex);
- while(!iv_syncPointReached)
+ mutex_lock(&iv_mutex);
+ while((!iv_syncPointReached) && (!iv_shutdown))
{
- sync_cond_wait(&iv_syncHit, &iv_syncMutex);
+ sync_cond_wait(&iv_cond, &iv_mutex);
+ }
+ // If shutdown request has been received from the FSP
+ if (iv_shutdown)
+ {
+ mutex_unlock(&iv_mutex);
+ shutdownDuringIpl();
+ }
+ else
+ {
+ iv_syncPointReached = false;
+ mutex_unlock(&iv_mutex);
}
- iv_syncPointReached = false;
- mutex_unlock(&iv_syncMutex);
}
TRACFCOMP(g_trac_initsvc, EXIT_MRK"IStepDispatcher::waitForSyncPoint");
@@ -908,10 +942,10 @@ void IStepDispatcher::handleSyncPointReachedMsg(msg_t * & io_pMsg)
TRACFCOMP(g_trac_initsvc, ENTER_MRK"IStepDispatcher::handleSyncPointReachedMsg");
// Signal any IStep waiting for a sync point
- mutex_lock(&iv_syncMutex);
+ mutex_lock(&iv_mutex);
iv_syncPointReached = true;
- sync_cond_signal(&iv_syncHit);
- mutex_unlock(&iv_syncMutex);
+ sync_cond_signal(&iv_cond);
+ mutex_unlock(&iv_mutex);
if (msg_is_async(io_pMsg))
{
@@ -930,6 +964,66 @@ void IStepDispatcher::handleSyncPointReachedMsg(msg_t * & io_pMsg)
}
// ----------------------------------------------------------------------------
+// IStepDispatcher::handleShutdownMsg()
+// ----------------------------------------------------------------------------
+void IStepDispatcher::handleShutdownMsg(msg_t * & io_pMsg)
+{
+ TRACFCOMP(g_trac_initsvc, ENTER_MRK"IStepDispatcher::handleShutdownMsg");
+
+ // Set iv_shutdown and signal any IStep waiting for a sync point
+ mutex_lock(&iv_mutex);
+ iv_shutdown = true;
+ sync_cond_broadcast(&iv_cond);
+ mutex_unlock(&iv_mutex);
+
+ if (msg_is_async(io_pMsg))
+ {
+ // It is expected shutdown request messages are async
+ msg_free(io_pMsg);
+ io_pMsg = NULL;
+ }
+ else
+ {
+ // Send the message back as a response
+ msg_respond(iv_msgQ, io_pMsg);
+ io_pMsg = NULL;
+ }
+
+ TRACFCOMP(g_trac_initsvc, EXIT_MRK"IStepDispatcher::handleShutdownMsg");
+}
+
+// ----------------------------------------------------------------------------
+// IStepDispatcher::shutdownDuringIpl()
+// ----------------------------------------------------------------------------
+void IStepDispatcher::shutdownDuringIpl()
+{
+ TRACFCOMP(g_trac_initsvc, ENTER_MRK"IStepDispatcher::shutdownDuringIpl");
+
+ // Create and commit error log for FFDC
+
+ /*@
+ * @errortype
+ * @reasoncode SHUTDOWN_REQUESTED_BY_FSP
+ * @severity ERRORLOG::ERRL_SEV_INFORMATIONAL
+ * @moduleid ISTEP_INITSVC_MOD_ID
+ * @userdata1 Current IStep
+ * @userdata2 Current SubStep
+ * @devdesc Received shutdown request from FSP
+ */
+ errlHndl_t err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ ISTEP_INITSVC_MOD_ID,
+ SHUTDOWN_REQUESTED_BY_FSP,
+ this->iv_curIStep, this->iv_curSubStep);
+
+ errlCommit(err, INITSVC_COMP_ID);
+
+ // Call doShutdown with the RC to initiate a TI
+ INITSERVICE::doShutdown(SHUTDOWN_REQUESTED_BY_FSP);
+
+}
+
+// ----------------------------------------------------------------------------
// IStepDispatcher::iStepBreakPoint()
// ----------------------------------------------------------------------------
void IStepDispatcher::iStepBreakPoint(uint32_t i_info)
@@ -1169,15 +1263,19 @@ void IStepDispatcher::runProgressThread()
l_PrevTime.tv_sec), 0 );
mutex_lock( &iv_mutex );
}
-
+ // If shutdown has been requested by FSP, stop ProgressThread
+ if(iv_shutdown)
+ {
+ break;
+ }
if( l_PrevTime.tv_sec == iv_lastProgressMsgTime.tv_sec &&
l_PrevTime.tv_nsec == iv_lastProgressMsgTime.tv_nsec)
{
#if 0
- /* 15 sec msg constraint not planned for GA1
- err = this->sendProgressCode(false);
- commit error in future
- */
+ /* 15 sec msg constraint not planned for GA1
+ err = this->sendProgressCode(false);
+ commit error in future
+ */
#else
// Normally this would be done in sendProgressCode but do it here
// to prevent thread from becoming a CPU hog.
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.H b/src/usr/initservice/istepdispatcher/istepdispatcher.H
index b83e4300c..dd0ab7512 100644
--- a/src/usr/initservice/istepdispatcher/istepdispatcher.H
+++ b/src/usr/initservice/istepdispatcher/istepdispatcher.H
@@ -218,6 +218,26 @@ private:
void handleSyncPointReachedMsg(msg_t * & io_pMsg);
/**
+ * @brief Handles a shutdown request message.
+ *
+ * Sets iv_shutdown and Signals any IStep thread
+ * waiting for a SyncPoint.
+ *
+ * @param[io] io_pMsg Reference to pointer to message (cleaned up)
+ */
+ void handleShutdownMsg(msg_t * & io_pMsg);
+
+ /**
+ * @brief Initiates the shutdown process based on an FSP request.
+ *
+ * Called by waitForSyncPoint or executeAllISteps if shutdown message
+ * has been received by the msgHndlr, this function creates and
+ * commits an error log indicating shutdown due to FSP request, and
+ * then initiates a TI.
+ */
+ void shutdownDuringIpl();
+
+ /**
* @brief Handles a ProcFabIovalid message.
*
* Executes the processing required for the sys_proc_fab_iovalid istep
@@ -311,11 +331,10 @@ private:
// Mutexes
mutable mutex_t iv_bkPtMutex; // Used to throttle breakpoints
mutable mutex_t iv_mutex; //used to synchronize access to all instance
- //variables except iv_syncPointReached
+ //variables
// Used for waiting for and signalling Sync Points
- mutable mutex_t iv_syncMutex;
- mutable sync_cond_t iv_syncHit;
+ mutable sync_cond_t iv_cond;
bool iv_syncPointReached;
// Set once in the constructor, mutex protection not needed
@@ -333,6 +352,8 @@ private:
uint8_t iv_curSubStep; // Current SubStep
msg_t* iv_pIstepMsg; // External Istep request message
timespec_t iv_lastProgressMsgTime; // Last time progress message sent
+ bool iv_shutdown; // Shutdown request has been received
+ // from the FSP
// Message Queue for receiving message from SP or SPless user console
msg_q_t iv_msgQ;
OpenPOWER on IntegriCloud