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 | |
parent | 487669b2da18343f648b4984765c36bb11f59b14 (diff) | |
download | talos-hostboot-1257ee668b165ce17a07f94c5d5deb8d361bd010.tar.gz talos-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>
-rw-r--r-- | src/include/usr/initservice/initserviceif.H | 34 | ||||
-rw-r--r-- | src/include/usr/intr/interrupt.H | 1 | ||||
-rw-r--r-- | src/usr/initservice/baseinitsvc/initservice.C | 84 | ||||
-rw-r--r-- | src/usr/initservice/baseinitsvc/initservice.H | 50 | ||||
-rw-r--r-- | src/usr/intr/intrrp.C | 21 | ||||
-rw-r--r-- | src/usr/intr/intrrp.H | 7 |
6 files changed, 182 insertions, 15 deletions
diff --git a/src/include/usr/initservice/initserviceif.H b/src/include/usr/initservice/initserviceif.H index dabb81e68..ba29d93a8 100644 --- a/src/include/usr/initservice/initserviceif.H +++ b/src/include/usr/initservice/initserviceif.H @@ -24,10 +24,21 @@ #define __INITSERVICE_INITSERVICEIF_H #include <vmmconst.h> +#include <sys/msg.h> namespace INITSERVICE { + /** + * Priority scheme, if needed + */ + enum EventPriority_t + { + LOWEST_PRIORITY = 0, //!<< Notifiy last, LIFO order + NO_PRIORITY = 16, //!<< No dependency / dont' care, LIFO order + HIGHEST_PRIORITY = 127, //!<< Nofity first, LIFO order + }; + /** * @brief Register a block/range of vitual memory to be handled during a * shutdown. @@ -40,6 +51,29 @@ namespace INITSERVICE */ void registerBlock(void* i_vaddr, uint64_t i_size, BlockPriority i_priority); +/** + * @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 EventPriority + * @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 = NO_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); + } #endif diff --git a/src/include/usr/intr/interrupt.H b/src/include/usr/intr/interrupt.H index ddc81ed87..5d0633051 100644 --- a/src/include/usr/intr/interrupt.H +++ b/src/include/usr/intr/interrupt.H @@ -52,6 +52,7 @@ namespace INTR MSG_INTR_UNREGISTER_MSGQ, //!< Un register a msgQ MSG_INTR_ENABLE, //!< Enable external Interrupts MSG_INTR_DISABLE, //!< Disable external interrupts + MSG_INTR_SHUTDOWN, //!< Call to shutdown interrupt presenter }; 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 diff --git a/src/usr/intr/intrrp.C b/src/usr/intr/intrrp.C index d05c6c44e..61f537932 100644 --- a/src/usr/intr/intrrp.C +++ b/src/usr/intr/intrrp.C @@ -29,6 +29,7 @@ #include <trace/interface.H> #include <errno.h> #include <initservice/taskargs.H> +#include <initservice/initserviceif.H> #include <util/singleton.H> #include <intr/intr_reasoncodes.H> #include <sys/mmio.h> @@ -155,6 +156,11 @@ errlHndl_t IntrRp::_init() msg_q_register(iv_msgQ, INTR_MSGQ); task_create(IntrRp::msg_handler, NULL); + + // Register event to be called on shutdown + INITSERVICE::registerShutdownEvent(iv_msgQ, + MSG_INTR_SHUTDOWN, + INITSERVICE::LOWEST_PRIORITY); } return err; @@ -380,6 +386,14 @@ void IntrRp::msgHandler() } break; + case MSG_INTR_SHUTDOWN: + { + TRACFCOMP(g_trac_intr,"Shutdown event received"); + // TODO rtc story 39878 for content + msg_respond(iv_msgQ, msg); + } + break; + default: msg->data[1] = -EINVAL; msg_respond(iv_msgQ, msg); @@ -566,13 +580,6 @@ errlHndl_t IntrRp::checkAddress(uint64_t i_addr) return err; } -// TODO rtc story 39878 -errlHndl_t IntrRp::shutDown() -{ - errlHndl_t err = NULL; - return err; -} - // Register a message queue with a particular intr type errlHndl_t INTR::registerMsgQ(msg_q_t i_msgQ, ext_intr_t i_type) { diff --git a/src/usr/intr/intrrp.H b/src/usr/intr/intrrp.H index 2900c5276..646d0761d 100644 --- a/src/usr/intr/intrrp.H +++ b/src/usr/intr/intrrp.H @@ -51,13 +51,6 @@ namespace INTR */ static void init( errlHndl_t &io_rtaskRetErrl ); - /** - * This function is registered with init for shutdown - * processing of the interrupt presenter. - * TODO Story 39878 - */ - static errlHndl_t shutDown(); - protected: /** |