diff options
author | Elliott Dahle <dedahle@us.ibm.com> | 2013-10-21 14:56:20 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-11-08 15:23:22 -0600 |
commit | f993373dac7e69fd8cfc54c105f0a793f6f362f5 (patch) | |
tree | 3e4f33ce34cccc6771b8a2b50bfb32cc8cdb045f | |
parent | c811df7983a6dbb0d56b96badb58ed785ddd0b72 (diff) | |
download | talos-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>
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; |