summaryrefslogtreecommitdiffstats
path: root/src/usr/errl/errlmanager.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/errl/errlmanager.C')
-rw-r--r--src/usr/errl/errlmanager.C167
1 files changed, 164 insertions, 3 deletions
diff --git a/src/usr/errl/errlmanager.C b/src/usr/errl/errlmanager.C
index c32c2b2b7..2e787d2e0 100644
--- a/src/usr/errl/errlmanager.C
+++ b/src/usr/errl/errlmanager.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2011,2018 */
+/* Contributors Listed Below - COPYRIGHT 2011,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -50,15 +50,18 @@
#include <arch/pirformat.H>
#include <errldisplay/errldisplay.H>
#include <console/consoleif.H>
-#include <config.h>
#include <functional>
#include <hwas/common/deconfigGard.H>
#include <kernel/terminate.H>
#include <debugpointers.H>
+#include <sys/sync.h>
namespace ERRORLOG
{
+// Used in VERSION partition caching
+mutex_t g_errlMutex = MUTEX_INITIALIZER;
+
extern trace_desc_t* g_trac_errl;
#ifdef STORE_ERRL_IN_L3
@@ -103,6 +106,20 @@ bool compareEidToPlid(const uint32_t i_plid,
return (i_pair.first->eid() == i_plid);
}
+const uint8_t* getCachedVersionPartition()
+{
+ return Singleton<ErrlManager>::instance().getCachedVersionPartition();
+}
+
+size_t getCachedVersionPartitionSize()
+{
+ return Singleton<ErrlManager>::instance().getCachedVersionPartitionSize();
+}
+
+errlHndl_t cacheVersionPartition()
+{
+ return Singleton<ErrlManager>::instance().cacheVersionPartition();
+}
class AtLoadFunctions
{
@@ -120,6 +137,7 @@ AtLoadFunctions atLoadFunction;
///////////////////////////////////////////////////////////////////////////////
ErrlManager::ErrlManager() :
iv_pnorReadyForErrorLogs(false),
+ iv_recvdShutdownEvent(false),
iv_hwasProcessCalloutFn(NULL),
iv_msgQ(NULL),
iv_pnorAddr(NULL),
@@ -129,7 +147,9 @@ ErrlManager::ErrlManager() :
iv_isMboxEnabled(false), // assume mbox isn't ready yet..
iv_isIpmiEnabled(false), // assume ipmi isn't ready yet..
iv_nonInfoCommitted(false),
- iv_isErrlDisplayEnabled(false)
+ iv_isErrlDisplayEnabled(false),
+ iv_versionPartitionCache(nullptr),
+ iv_versionPartitionCacheSize(0)
{
TRACFCOMP( g_trac_errl, ENTER_MRK "ErrlManager::ErrlManager constructor" );
@@ -270,6 +290,30 @@ void ErrlManager::errlogMsgHndlr ()
msg_t * theMsg = msg_wait( iv_msgQ );
TRACFCOMP( g_trac_errl, INFO_MRK"Got an error log Msg - Type: 0x%08x",
theMsg->type );
+
+ // if we've been shut down then do nothing except delete the msg or send
+ // a response depending on the message type.
+ if(iv_recvdShutdownEvent)
+ {
+ TRACFCOMP( g_trac_errl, INFO_MRK "Error log service is shutdown. "
+ "Message will be ignored.");
+ switch( theMsg->type )
+ {
+ // Shutdown and flush message types expect a response
+ case ERRLOG_SHUTDOWN_TYPE:
+ case ERRLOG_FLUSH_TYPE:
+ msg_respond ( iv_msgQ, theMsg );
+ break;
+
+ // All other messages just need to be freed
+ default:
+ msg_free(theMsg);
+ break;
+ }
+ // wait for next message
+ continue;
+ }
+
//Process message just received
switch( theMsg->type )
{
@@ -1009,6 +1053,9 @@ void ErrlManager::errlogShutdown()
// prior to the PNOR resource provider shutting down.
PNOR::flush(PNOR::HB_ERRLOGS);
+ // Remember that we have recieved the shutdown event
+ iv_recvdShutdownEvent = true;
+
return;
}
@@ -1031,4 +1078,118 @@ bool ErrlManager::_updateErrlListIter(ErrlListItr_t & io_it)
return l_removed;
}
+const uint8_t* ErrlManager::getCachedVersionPartition() const
+{
+ mutex_lock(&g_errlMutex);
+ const uint8_t* l_versionPtr = iv_versionPartitionCache;
+ mutex_unlock(&g_errlMutex);
+ return l_versionPtr;
+}
+
+size_t ErrlManager::getCachedVersionPartitionSize() const
+{
+ mutex_lock(&g_errlMutex);
+ size_t l_versionSize = iv_versionPartitionCacheSize;
+ mutex_unlock(&g_errlMutex);
+ return l_versionSize;
+}
+
+errlHndl_t ErrlManager::cacheVersionPartition()
+{
+ errlHndl_t l_errl = nullptr;
+ bool l_versionPartitionLoaded = false;
+
+ do {
+
+ if(iv_isVersionPartitionCached ||
+ !PNOR::isSectionAvailable(PNOR::VERSION))
+ {
+ // No need to try to cache more than once or if
+ // there is no VERSION partition
+ break;
+ }
+
+#ifdef CONFIG_SECUREBOOT
+ l_errl = PNOR::loadSecureSection(PNOR::VERSION);
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_errl, ERR_MRK"ErrlManager::cacheVersionPartition() - could not load VERSION partition");
+ break;
+ }
+
+ l_versionPartitionLoaded = true;
+#endif
+
+ PNOR::SectionInfo_t l_pnorVersionSectionInfo;
+ l_errl = getSectionInfo(PNOR::VERSION, l_pnorVersionSectionInfo);
+ if(l_errl)
+ {
+ TRACFCOMP(g_trac_errl, ERR_MRK"ErrlManager::cacheVersionPartition() - could not get VERSION section info");
+ break;
+ }
+
+ // Since multiple errls may be at different stages of commit at the same
+ // time, lock the mutex to prevent atomicity issues
+ mutex_lock(&g_errlMutex);
+
+ iv_versionPartitionCacheSize = 0;
+
+ const char* l_versionSectionPtr =
+ reinterpret_cast<char*>(l_pnorVersionSectionInfo.vaddr);
+
+ // The actual size of the text in the VERSION partition is likely to be less
+ // than the declared size. Calculate the actual size here.
+ while((l_versionSectionPtr[iv_versionPartitionCacheSize] != '\0') &&
+ (iv_versionPartitionCacheSize < l_pnorVersionSectionInfo.size))
+ {
+ ++iv_versionPartitionCacheSize;
+ }
+ iv_versionPartitionCache = new uint8_t[iv_versionPartitionCacheSize];
+
+ memcpy(const_cast<uint8_t*>(iv_versionPartitionCache),
+ reinterpret_cast<uint8_t*>(l_pnorVersionSectionInfo.vaddr),
+ iv_versionPartitionCacheSize);
+
+ mutex_unlock(&g_errlMutex);
+
+ } while(0);
+
+ if(l_versionPartitionLoaded)
+ {
+#ifdef CONFIG_SECUREBOOT
+ errlHndl_t l_unloadSecErr = PNOR::unloadSecureSection(PNOR::VERSION);
+ if(l_unloadSecErr)
+ {
+ TRACFCOMP(g_trac_errl, ERR_MRK"ErrlManager::cacheVersionPartition() - could not unload VERSION partition");
+ if(l_errl)
+ {
+ l_unloadSecErr->plid(l_errl->plid());
+ errlCommit(l_unloadSecErr, ERRL_COMP_ID);
+ }
+ else
+ {
+ l_errl = l_unloadSecErr;
+ l_unloadSecErr = nullptr;
+ }
+ }
+#endif
+ }
+
+ if(l_errl)
+ {
+ if(iv_versionPartitionCache)
+ {
+ delete[] iv_versionPartitionCache;
+ iv_versionPartitionCache = nullptr;
+ }
+ iv_versionPartitionCacheSize = 0;
+ }
+
+ // Set the cache attrmpted flag regardless of whether we actually
+ // were able to cache the partition
+ iv_isVersionPartitionCached = true;
+
+ return l_errl;
+}
+
} // End namespace
OpenPOWER on IntegriCloud