diff options
| author | Doug Gilbert <dgilbert@us.ibm.com> | 2012-05-14 17:13:24 -0500 |
|---|---|---|
| committer | Douglas R. Gilbert <dgilbert@us.ibm.com> | 2012-05-21 15:50:06 -0500 |
| commit | 1257ee668b165ce17a07f94c5d5deb8d361bd010 (patch) | |
| tree | 752188bb47447762bcf70590f619d5b409417232 /src/usr/initservice/baseinitsvc | |
| parent | 487669b2da18343f648b4984765c36bb11f59b14 (diff) | |
| download | blackbird-hostboot-1257ee668b165ce17a07f94c5d5deb8d361bd010.tar.gz blackbird-hostboot-1257ee668b165ce17a07f94c5d5deb8d361bd010.zip | |
Register service with initservice to get notified on shutdown
RTC: 41263
Change-Id: Ic44026c55453d41e1e5e0921339ec126dc665566
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1061
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/initservice/baseinitsvc')
| -rw-r--r-- | src/usr/initservice/baseinitsvc/initservice.C | 84 | ||||
| -rw-r--r-- | src/usr/initservice/baseinitsvc/initservice.H | 50 |
2 files changed, 133 insertions, 1 deletions
diff --git a/src/usr/initservice/baseinitsvc/initservice.C b/src/usr/initservice/baseinitsvc/initservice.C index e9b6b25c2..6c3b6179d 100644 --- a/src/usr/initservice/baseinitsvc/initservice.C +++ b/src/usr/initservice/baseinitsvc/initservice.C @@ -616,6 +616,23 @@ void InitService::doShutdown(uint64_t i_status, { int l_rc = 0; errlHndl_t l_err = NULL; + + // Call registered services and notify of shutdown + msg_t * l_msg = msg_allocate(); + l_msg->data[0] = i_status; + l_msg->data[1] = 0; + l_msg->extra_data = 0; + + for(EventRegistry_t::iterator i = iv_regMsgQ.begin(); + i != iv_regMsgQ.end(); + ++i) + { + l_msg->type = i->msgType; + msg_sendrecv(i->msgQ,l_msg); + } + + msg_free(l_msg); + std::vector<regBlock_t*>::iterator l_rb_iter = iv_regBlock.begin(); //FLUSH each registered block in order while (l_rb_iter!=iv_regBlock.end()) @@ -648,4 +665,71 @@ void InitService::doShutdown(uint64_t i_status, shutdown(i_status, i_payload_base, i_payload_entry); } +bool InitService::registerShutdownEvent(msg_q_t i_msgQ, + uint32_t i_msgType, + EventPriority_t i_priority) +{ + bool result = true; + EventRegistry_t::iterator in_pos = iv_regMsgQ.end(); + + for(EventRegistry_t::iterator r = iv_regMsgQ.begin(); + r != iv_regMsgQ.end(); + ++r) + { + if(r->msgQ == i_msgQ) + { + result = false; + break; + } + + if(r->msgPriority <= (uint32_t)i_priority) + { + in_pos = r; + } + } + + if(result) + { + in_pos = iv_regMsgQ.insert(in_pos, + regMsgQ_t(i_msgQ, i_msgType, i_priority)); + } + + return result; +} + +bool InitService::unregisterShutdownEvent(msg_q_t i_msgQ) +{ + bool result = false; + for(EventRegistry_t::iterator r = iv_regMsgQ.begin(); + r != iv_regMsgQ.end(); + ++r) + { + if(r->msgQ == i_msgQ) + { + result = true; + iv_regMsgQ.erase(r); + break; + } + } + return result; +} + +/** + * @see src/include/usr/initservice/initservicif.H + */ +bool registerShutdownEvent(msg_q_t i_msgQ, + uint32_t i_msgType, + EventPriority_t i_priority) +{ + return + Singleton<InitService>::instance().registerShutdownEvent(i_msgQ, + i_msgType, + i_priority); +} + +bool unregisterShutdownEvent(msg_q_t i_msgQ) +{ + return Singleton<InitService>::instance().unregisterShutdownEvent(i_msgQ); +} + } // namespace diff --git a/src/usr/initservice/baseinitsvc/initservice.H b/src/usr/initservice/baseinitsvc/initservice.H index 8c8badbbd..5a3820d36 100644 --- a/src/usr/initservice/baseinitsvc/initservice.H +++ b/src/usr/initservice/baseinitsvc/initservice.H @@ -40,6 +40,7 @@ #include <stdint.h> #include <util/singleton.H> #include <sys/vfs.h> // VFS_MODULE_NAME_MAX +#include <sys/msg.h> #include <trace/interface.H> #include <errl/errlentry.H> // errlHndl_t @@ -47,6 +48,7 @@ #include <initservice/initsvcreasoncodes.H> #include <initservice/initsvcstructs.H> #include <vmmconst.h> +#include <initservice/initserviceif.H> namespace INITSERVICE { @@ -174,7 +176,31 @@ public: void registerBlock(void* i_vaddr, uint64_t i_size, BlockPriority i_priority); /** - * @brief Perform necessary steps, such as FLUSHing, to registered blocks. + * @brief Register a service to be notified during shutdown + * + * @param[in] i_msgQ, A message queue to send a message to on shutdown + * @param[in] i_msgType, The message type to send. + * @param[in] i_priority, @See src/include/usr/initservice/initserviceif.H + * + * @return true - i_msgQ registered + * false - i_msgQ already registered.- not registered again. + */ + bool registerShutdownEvent(msg_q_t i_msgQ, + uint32_t i_msgType, + EventPriority_t i_priority); + + /** + * @brief Un register a service for a Shutdown event + * + * @param[in] i_msgQ, The message queue to be removed. + * + * @return true - i_msgQ was removed from the event notification list. | + * false - i_msgQ was not registered in the event notification list. + */ + bool unregisterShutdownEvent(msg_q_t i_msgQ); + + /** + * @brief Perform necessary shut down steps. * * @param[in] i_status - Shutdown status to be passed along on shutdown * @param[in] i_payload_base - The base address (target HRMOR) of the @@ -183,6 +209,8 @@ public: * payload entry-point. * * @return Nothing + * @note This calls registered services to notify them of shutdown and it + * flushes the virtual memory. */ void doShutdown(uint64_t i_status, uint64_t i_payload_base = 0, @@ -246,6 +274,26 @@ private: //Store a list of registered blocks std::vector<regBlock_t*> iv_regBlock; + struct regMsgQ_t + { + msg_q_t msgQ; + uint32_t msgType; + uint32_t msgPriority; + + /** + * @brief Constructor + */ + regMsgQ_t(msg_q_t i_msgQ, + uint32_t i_msgType, + EventPriority_t i_priority) : + msgQ(i_msgQ), msgType(i_msgType), msgPriority((uint32_t)i_priority) {} + }; + + typedef std::vector<regMsgQ_t> EventRegistry_t; + + // List of Services to notify on shutdown + EventRegistry_t iv_regMsgQ; + }; // class InitService } // namespace INITSERVICE |

