diff options
author | Bill Hoffa <wghoffa@us.ibm.com> | 2014-02-13 09:16:39 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2014-03-07 12:52:20 -0600 |
commit | bfddb6f15f4b2cbde3ec591dc77fb2a23f00c82f (patch) | |
tree | 1e0307bd2c8be7dcc850846e9f21622834732403 /src | |
parent | 877481578bfb4b8f30c3f3f7b93b72a9a9efe172 (diff) | |
download | blackbird-hostboot-bfddb6f15f4b2cbde3ec591dc77fb2a23f00c82f.tar.gz blackbird-hostboot-bfddb6f15f4b2cbde3ec591dc77fb2a23f00c82f.zip |
Power off feature to tell Hostboot to first get to certain istep
Change-Id: I841e24442dae084ab6150a4e96a649971d0823ee
RTC:94658
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/8824
Tested-by: Jenkins Server
Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/usr/initservice/istepdispatcher/istepdispatcher.C | 119 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/istepdispatcher.H | 11 |
2 files changed, 122 insertions, 8 deletions
diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C index 86968b996..15d1c3652 100644 --- a/src/usr/initservice/istepdispatcher/istepdispatcher.C +++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C @@ -98,7 +98,11 @@ IStepDispatcher::IStepDispatcher() : iv_curIStep(0), iv_curSubStep(0), iv_pIstepMsg(NULL), - iv_shutdown(false) + iv_shutdown(false), + iv_futureShutdown(false), + iv_istepToCompleteBeforeShutdown(0), + iv_substepToCompleteBeforeShutdown(0) + { mutex_init(&iv_bkPtMutex); mutex_init(&iv_mutex); @@ -454,16 +458,17 @@ errlHndl_t IStepDispatcher::doIstep(uint32_t i_istep, // Record current IStep, SubStep iv_curIStep = i_istep; iv_curSubStep = i_substep; + mutex_unlock(&iv_mutex); // If a shutdown request has been received - if (iv_shutdown) + if (isShutdownRequested()) { - mutex_unlock(&iv_mutex); // Do not begin new IStep and shutdown shutdownDuringIpl(); } else { + mutex_lock(&iv_mutex); // Send Progress Code err = this->sendProgressCode(false); mutex_unlock(&iv_mutex); @@ -1019,11 +1024,56 @@ 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); + // find the step/substep. The step is in the top 32bits, the substep is in + // the bottom 32bits and is a byte + uint8_t istep = ((io_pMsg->data[0] & 0x000000FF00000000) >> 32); + uint8_t substep = (io_pMsg->data[0] & 0x00000000000000FF); + + if (istep == 0 && substep == 0) + { + //Immediate shutdown - 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); + } + else + { + mutex_lock(&iv_mutex); + if (iv_futureShutdown) + { + //Multiple shutdown messages have been received use the one that + // will happen first + if ((istep < iv_istepToCompleteBeforeShutdown) || + (istep == iv_istepToCompleteBeforeShutdown + && substep < iv_substepToCompleteBeforeShutdown) ) + { + TRACFCOMP(g_trac_initsvc, INFO_MRK"handleShutdownMsg: Future " + "shutdown msg rcvd, updating future poweroff to istep" + " [%d], substep [%d]", istep, substep); + iv_istepToCompleteBeforeShutdown = istep; + iv_substepToCompleteBeforeShutdown = substep; + } + else + { + TRACFCOMP(g_trac_initsvc, INFO_MRK"handleShutdownMsg: Future " + "shutdown msg rcvd, but istep [%d], substep [%d] is after " + "previous future shutdown request. This request will be " + "ignored.", istep, substep); + } + } + else + { + TRACFCOMP(g_trac_initsvc, INFO_MRK"handleShutdownMsg: Future" + " Shutdown Message for istep [%d], substep [%d]", + istep, substep); + iv_istepToCompleteBeforeShutdown = istep; + iv_substepToCompleteBeforeShutdown = substep; + iv_futureShutdown = true; + } + mutex_unlock(&iv_mutex); + } if (msg_is_async(io_pMsg)) { @@ -1041,6 +1091,7 @@ void IStepDispatcher::handleShutdownMsg(msg_t * & io_pMsg) TRACFCOMP(g_trac_initsvc, EXIT_MRK"IStepDispatcher::handleShutdownMsg"); } + // ---------------------------------------------------------------------------- // IStepDispatcher::shutdownDuringIpl() // ---------------------------------------------------------------------------- @@ -1120,10 +1171,62 @@ bool IStepDispatcher::isShutdownRequested() bool isShutdownRequested = iv_shutdown; mutex_unlock(&iv_mutex); + if (!isShutdownRequested) + { + isShutdownRequested = isFutureShutdownRequested(); + } + TRACFCOMP(g_trac_initsvc, EXIT_MRK"IStepDispatcher::isShutdownRequested"); return isShutdownRequested; } + + +// ---------------------------------------------------------------------------- +// IStepDispatcher::isFutureShutdownRequested() +// ---------------------------------------------------------------------------- +bool IStepDispatcher::isFutureShutdownRequested() +{ + TRACDCOMP(g_trac_initsvc, + ENTER_MRK"IStepDispatcher::isFutureShutdownRequested"); + + bool isFutureShutdownRequested = false; + mutex_lock(&iv_mutex); + + if (iv_futureShutdown) + { + if (iv_curIStep == iv_istepToCompleteBeforeShutdown) + { + if (iv_curSubStep > iv_substepToCompleteBeforeShutdown) + { + isFutureShutdownRequested = true; + } + else + { + isFutureShutdownRequested = false; + } + } + else if (iv_curIStep > iv_istepToCompleteBeforeShutdown) + { + isFutureShutdownRequested = true; + } + else + { + isFutureShutdownRequested = false; + } + } + else + { + //No Future shutdown set, always return false + isFutureShutdownRequested = false; + } + mutex_unlock(&iv_mutex); + + TRACDCOMP(g_trac_initsvc, + EXIT_MRK"IStepDispatcher::isFutureShutdownRequested"); + return isFutureShutdownRequested; +} + // ---------------------------------------------------------------------------- // IStepDispatcher::handleIStepRequestMsg() // ---------------------------------------------------------------------------- diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.H b/src/usr/initservice/istepdispatcher/istepdispatcher.H index ba6209d3c..37be40610 100644 --- a/src/usr/initservice/istepdispatcher/istepdispatcher.H +++ b/src/usr/initservice/istepdispatcher/istepdispatcher.H @@ -168,6 +168,14 @@ public: */ bool isShutdownRequested(); + /** + * @brief This function determines if a future shutdown request + * has happened where the future istep has been reached + + * @return bool - true if shutdown requested, false if not + */ + bool isFutureShutdownRequested(); + protected: /** @@ -378,6 +386,9 @@ private: timespec_t iv_lastProgressMsgTime; // Last time progress message sent bool iv_shutdown; // Shutdown request has been received // from the FSP + bool iv_futureShutdown; + uint8_t iv_istepToCompleteBeforeShutdown; + uint8_t iv_substepToCompleteBeforeShutdown; // Message Queue for receiving message from SP or SPless user console msg_q_t iv_msgQ; |