summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Gilbert <dgilbert@us.ibm.com>2012-05-14 17:13:24 -0500
committerDouglas R. Gilbert <dgilbert@us.ibm.com>2012-05-21 15:50:06 -0500
commit1257ee668b165ce17a07f94c5d5deb8d361bd010 (patch)
tree752188bb47447762bcf70590f619d5b409417232
parent487669b2da18343f648b4984765c36bb11f59b14 (diff)
downloadtalos-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.H34
-rw-r--r--src/include/usr/intr/interrupt.H1
-rw-r--r--src/usr/initservice/baseinitsvc/initservice.C84
-rw-r--r--src/usr/initservice/baseinitsvc/initservice.H50
-rw-r--r--src/usr/intr/intrrp.C21
-rw-r--r--src/usr/intr/intrrp.H7
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:
/**
OpenPOWER on IntegriCloud