summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--img/.gitignore1
-rwxr-xr-xsrc/build/simics/hb-simdebug.py8
-rwxr-xr-xsrc/build/tools/cpfiles.pl2
-rw-r--r--src/include/usr/errl/errlentry.H242
-rw-r--r--src/include/usr/errl/errlmanager.H19
-rw-r--r--src/include/usr/errl/errlprvt.H145
-rw-r--r--src/include/usr/errl/errlsctn.H106
-rw-r--r--src/include/usr/errl/errlsctnhdr.H164
-rw-r--r--src/include/usr/errl/errlsrc.H146
-rw-r--r--src/include/usr/errl/errltypes.H370
-rw-r--r--src/include/usr/errl/errlud.H185
-rw-r--r--src/include/usr/errl/errluh.H165
-rw-r--r--src/include/usr/hbotcompid.H14
-rw-r--r--src/include/usr/trace/trace.H48
-rw-r--r--src/usr/errl/errlentry.C319
-rw-r--r--src/usr/errl/errlffdc.C66
-rw-r--r--src/usr/errl/errlffdc.H96
-rw-r--r--src/usr/errl/errlmanager.C18
-rw-r--r--src/usr/errl/errlprvt.C135
-rw-r--r--src/usr/errl/errlsctn.C114
-rw-r--r--src/usr/errl/errlsctnhdr.C78
-rw-r--r--src/usr/errl/errlsctnhdr.H102
-rw-r--r--src/usr/errl/errlsrc.C164
-rw-r--r--src/usr/errl/errlud.C168
-rw-r--r--src/usr/errl/errluh.C114
-rw-r--r--src/usr/errl/makefile2
-rw-r--r--src/usr/errl/parser/errlparser.C631
-rw-r--r--src/usr/errl/parser/makefile40
-rw-r--r--src/usr/errl/test/errltest.H52
-rw-r--r--src/usr/trace/trace.C75
30 files changed, 2823 insertions, 966 deletions
diff --git a/img/.gitignore b/img/.gitignore
index 476897d14..d026df6f9 100644
--- a/img/.gitignore
+++ b/img/.gitignore
@@ -10,3 +10,4 @@
.*.lnkout
hbotStringFile
*.toc
+errlparser
diff --git a/src/build/simics/hb-simdebug.py b/src/build/simics/hb-simdebug.py
index fbc223705..06b5e4ccd 100755
--- a/src/build/simics/hb-simdebug.py
+++ b/src/build/simics/hb-simdebug.py
@@ -446,7 +446,7 @@ def istepHB( str_arg1, inList):
#------------------------------------------------------------------------------
# Function to dump error logs
#------------------------------------------------------------------------------
-def errlHB(symsFile, errlParser, flag, logid):
+def errlHB(symsFile, errlParser, flag, logid, stringFile):
# "constants"
L3_SIZE = 0x800000
@@ -461,9 +461,9 @@ def errlHB(symsFile, errlParser, flag, logid):
#print result
if logid == "all":
- string = "./%s %s %s %s| tee Errorlogs"%(errlParser,dumpFile,symsFile,flag)
+ string = "./%s %s %s %s -t %s| tee Errorlogs"%(errlParser,dumpFile,symsFile,flag,stringFile)
else:
- string = "./%s %s %s %s %s| tee Errorlogs"%(errlParser,dumpFile,symsFile,flag,logid)
+ string = "./%s %s %s %s %s -t %s| tee Errorlogs"%(errlParser,dumpFile,symsFile,flag,logid,stringFile)
#print string
os.system(string)
os.system("rm hbdump.out")
@@ -656,7 +656,7 @@ def hb_errl(logid, logidStr, flg_list, flg_detail):
print "syms=%s" % str(syms)
print "errlParser=%s" % str(errlParser)
#print "logid=%s" % str(id)
- errlHB(syms, errlParser, flag, id)
+ errlHB(syms, errlParser, flag, id, default_stringFile)
return None
new_command("hb-errl",
diff --git a/src/build/tools/cpfiles.pl b/src/build/tools/cpfiles.pl
index 79c794335..5ee77afe3 100755
--- a/src/build/tools/cpfiles.pl
+++ b/src/build/tools/cpfiles.pl
@@ -58,7 +58,7 @@ sub printUsage;
my @files = ("src/build/tools/hb-parsedump.pl",
"src/build/simics/hb-simdebug.py",
"src/build/simics/post_model_hook.simics",
- "src/usr/errl/parser/bin/errlparser",
+ "img/errlparser",
"img/hbotStringFile",
"img/hbicore.syms",
"img/hbicore_test.syms",
diff --git a/src/include/usr/errl/errlentry.H b/src/include/usr/errl/errlentry.H
index 5e5205fb8..51a0df843 100644
--- a/src/include/usr/errl/errlentry.H
+++ b/src/include/usr/errl/errlentry.H
@@ -38,6 +38,11 @@
#include <stdint.h>
#include <vector>
#include <errl/errltypes.H>
+#include <errl/errlsctn.H>
+#include <errl/errlprvt.H>
+#include <errl/errluh.H>
+#include <errl/errlsrc.H>
+#include <errl/errlud.H>
#include <hbotcompid.H>
namespace ERRORLOG
@@ -47,8 +52,15 @@ namespace ERRORLOG
// Forward class declarations
/*****************************************************************************/
class ErrlManager;
-class ErrlSctn;
-class ErrlFFDC;
+
+
+
+
+// In Sprint 6, the return from errl->addFFDC changed from
+// ErrlFFDC* to ErrlUD*. This typedef is for compatibility in
+// case anybody previously stored the return from errl->addFFDC() as
+// ErrlFFDC *.
+typedef ErrlUD ErrlFFDC;
/**
* @brief Host Boot Error log entry class.
@@ -63,6 +75,8 @@ class ErrlEntry
friend class ErrlManager;
+
+
public:
/**
* @brief ErrlEntry constructor. Builds an error log with info
@@ -123,6 +137,7 @@ public:
*/
errlSeverity_t sev() const;
+
/**
* @brief Set the log's severity
* The severity of a log determines how severe the
@@ -175,6 +190,19 @@ public:
/**
+ * @brief Get the unique platform log identifier (PLID) of the error log.
+ * In legacy FSP, you could have one platform log ID such that a
+ * of entry IDs (EIDs) related to a single PLID. So far in Hostboot,
+ * PLID == EID. As such, there is no setter in the ErrlEntry interface
+ * for EID. When flattened as PEL for export, EID will be set to PLID.
+ *
+ * @return The platform log ID of the error log.
+ */
+ uint32_t plid() const;
+
+
+
+ /**
* @brief Get the event type of the error log.
* See errl/errltypes.H
* @return errlEventType_t
@@ -247,6 +275,8 @@ public:
*/
void setTermState(const errlTermState_t i_termState);
+
+
/**
* @brief Allows the caller to add a chunk of data in a log
*
@@ -263,79 +293,92 @@ public:
* @return Pointer to FFDC section if successfully added.
* NULL if fails
*/
- ErrlFFDC* addFFDC(const compId_t i_compId,
- const void * i_dataPtr,
- const uint32_t i_ffdcLen,
- const uint8_t i_ffdcVer = 0,
- const uint8_t i_ffdcSubSect = 0);
+ ErrlUD * addFFDC(const compId_t i_compId,
+ const void * i_dataPtr,
+ const uint32_t i_ffdcLen,
+ const uint8_t i_ffdcVer = 0,
+ const uint8_t i_ffdcSubSect = 0);
/**
* @brief Append more data to an FFDC section.
*
- * @param[in] i_ffdcSctnPtr Pointer to FFDC section to add data to.
- * This pointer is returned when addFFDC
+ * @param[in] i_pErrlUD Pointer to the user-define section
+ * to add data to. This pointer is
+ * returned when addFFDC
* function is called earlier.
* @param[in] i_dataPtr Points to data block to be added
* @param[in] i_dataLen Length of data in bytes
*
* @return void
*/
- void appendToFFDC(ErrlFFDC* i_ffdcSctnPtr,
- const void *i_dataPtr,
- const uint32_t i_dataLen);
+ void appendToFFDC( ErrlUD * i_pErrlUD,
+ const void *i_dataPtr,
+ const uint32_t i_dataLen);
-
-
- /**
- * @brief Compute the flattened size of an error log.
- *
- * @return size in bytes of the flattened data.
- */
- uint64_t flattenedSize();
-
-
/**
- * @brief Flatten the data to caller's buffer.
+ * @brief Collect component trace
+ * The given component's trace is collected (if possible)
+ * and added to the log's data sections. The amount of data
+ * added is the smallest of the log's available space (up to
+ * 1024 bytes of trace) or the given input max.
*
- * @param[in,out] io_buffer Points to data block to be filled
- * @param[in] i_cbBuffer Count of bytes in buffer supplied
+ * @param[in] i_Name Component Name
+ * @param[in] i_Max Upper limit of trace to capture.
*
- * @return Count of bytes copied to caller's
- * buffer or else zero if it does not fit.
+ * @return A Boolean indication of success. False likely means
+ * the component name input is not found.
*/
- uint64_t flatten( void * io_buffer, const uint64_t i_cbBuffer );
+ bool collectTrace(const char i_name[],
+ const uint32_t i_max = 0);
-private:
+private:
/**
- * @brief Disabled copy constructor and assignment operator
- */
- ErrlEntry(const ErrlEntry& i_right);
- ErrlEntry& operator=(const ErrlEntry& i_right);
+ * @brief The ErrlManager will call here to ask the
+ * ErrlEntry to assign the time of commit, and to assign
+ * the commiter's comp ID.
+ * The ErrlManager is the primary user of this call.
+ *
+ */
+ void commit( compId_t i_commiterComp );
/**
- * @brief Set the log's id
- * This function is called by the ErrlManager to
- * set this log's ID to a unique input number.
- * This is to be called by ErrlManager only.
+ * @brief Compute the flattened size of an error log. It is typical
+ * to call this function for the size of buffer required, then
+ * allocate a buffer, then call flatten().
+ * The ErrlManager is the primary user of this call.
*
- * There is no call to get the log id because it
- * would just be zero until the log is committed.
+ * @return Size in bytes of the flattened data.
+ */
+ uint64_t flattenedSize();
+
+
+ /**
+ * @brief Flatten the data to caller's buffer. The resulting flat
+ * data will be in PEL (platform event log) format.
+ * The ErrlManager is the primary user of this call.
*
- * @param[in] i_val Log ID as assigned by ErrlManager
+ * @param[in,out] o_buffer Points to data block to be filled
+ * @param[in] i_cbBuffer Count of bytes in buffer supplied
*
- * @return void
+ * @return Count of bytes copied to caller's
+ * buffer or else zero if it does not fit.
*/
- void setLogId(const uint32_t i_val);
+ uint64_t flatten( void * o_buffer, const uint64_t i_cbBuffer );
+ /**
+ * @brief Disabled copy constructor and assignment operator
+ */
+ ErrlEntry(const ErrlEntry& i_right);
+ ErrlEntry& operator=(const ErrlEntry& i_right);
@@ -375,21 +418,6 @@ private:
const callOutPriority_t i_priority);
/**
- * @brief Collect component trace
- * The given component's trace is collected ( if possible )
- * and added to the log's data sections. The amount of data
- * added is the smallest of the log's available space (up to
- * 1024 bytes of trace) or the given input max.
- *
- * @param[in] i_Name Component Name
- * @param[in] i_Max Upper limit of trace to capture.
- *
- * @return None
- */
- void CollectTrace(const char i_Name[],
- const uint32_t i_Max = 0);
-
- /**
* @brief Adds a software section to the log which is
* mostly used as a stack call indicator
*
@@ -417,127 +445,101 @@ private:
private:
// Data Members
- uint16_t iv_reasonCode; // Comp ID and reason code, 2 nibbles ea
- errlSeverity_t iv_sev; // Log severity
- errlEventType_t iv_eventType; // Event type
- epubSubSystem_t iv_subSys; // Sub system
- srcType_t iv_srcType; // SRC type
- errlTermState_t iv_termState; // Terminate state
- uint8_t iv_modId; // Module ID
- uint64_t iv_user1; // Optional user data 1
- uint64_t iv_user2; // Optional user data 2
- uint64_t iv_CreationTime; // Time of instantiation
- uint32_t iv_logId; // This log's unique ID
- std::vector<ErrlSctn*> iv_SectionVector; // list of user sections
+ ErrlPrvt iv_Private; // private header object
+ ErrlUH iv_User; // user header object
+ ErrlSrc iv_Src; // primary SRC section
+ std::vector<ErrlUD*> iv_SectionVector; // list of user defined sections
+
+ // TODO need to interpret term state and terminate accordingly.
+ // TODO termstate is presently not being flattend into PEL
+ errlTermState_t iv_termState;
};
+
+
+
+
//-----------------------------------------------------------------------
// In-line functions
//-----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
-inline errlSeverity_t ErrlEntry::sev() const
-{
- return iv_sev;
-}
-
-inline void ErrlEntry::setSev(const errlSeverity_t i_sev)
-{
- iv_sev = i_sev;
- return;
-}
-
-////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////
-inline uint16_t ErrlEntry::reasonCode() const
+inline uint32_t ErrlEntry::plid() const
{
- return iv_reasonCode;
+ return iv_Private.iv_plid;
}
-inline void ErrlEntry::setReasonCode( const uint16_t i_reasonCode )
-{
- iv_reasonCode = i_reasonCode;
- return;
-}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline uint8_t ErrlEntry::moduleId() const
{
- return iv_modId;
+ return iv_Src.iv_modId;
}
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
inline void ErrlEntry::setModuleId( const uint8_t i_moduleId )
{
- iv_modId = i_moduleId;
+ iv_Src.iv_modId = i_moduleId;
return;
}
+
+
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
-inline errlEventType_t ErrlEntry::eventType() const
+inline errlTermState_t ErrlEntry::termState() const
{
- return iv_eventType;
+ return iv_termState;
}
-inline void ErrlEntry::setEventType(const errlEventType_t i_eventType)
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+inline void ErrlEntry::setTermState(const errlTermState_t i_termState)
{
- iv_eventType = i_eventType;
+ iv_termState = i_termState;
return;
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
-inline epubSubSystem_t ErrlEntry::subSys() const
+inline void ErrlEntry::setReasonCode( const uint16_t i_reasonCode )
{
- return iv_subSys;
+ iv_Src.iv_reasonCode = i_reasonCode;
+ return;
}
-inline void ErrlEntry::setSubSys(const epubSubSystem_t i_subSys)
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+inline uint16_t ErrlEntry::reasonCode() const
{
- iv_subSys = i_subSys;
- return;
+ return iv_Src.iv_reasonCode;
}
-
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
inline srcType_t ErrlEntry::srcType() const
{
- return iv_srcType;
+ return iv_Src.iv_srcType;
}
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
inline void ErrlEntry::setSrcType(const srcType_t i_srcType)
{
- iv_srcType = i_srcType;
+ iv_Src.iv_srcType = i_srcType;
return;
}
-////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////
-inline errlTermState_t ErrlEntry::termState() const
-{
- return iv_termState;
-}
-inline void ErrlEntry::setTermState(const errlTermState_t i_termState)
-{
- iv_termState = i_termState;
- return;
-}
-////////////////////////////////////////////////////////////////////////////
-// Called by errlmanager at log commit time.
-inline void ErrlEntry::setLogId(const uint32_t i_val)
-{
- iv_logId = i_val;
-}
} // End namespace
diff --git a/src/include/usr/errl/errlmanager.H b/src/include/usr/errl/errlmanager.H
index 4f1275eef..d6d5c5a05 100644
--- a/src/include/usr/errl/errlmanager.H
+++ b/src/include/usr/errl/errlmanager.H
@@ -39,6 +39,10 @@
#include <sys/sync.h>
#include <vector>
#include <kernel/timemgr.H>
+#include <hbotcompid.H>
+
+
+
namespace ERRORLOG
{
@@ -59,11 +63,14 @@ namespace ERRORLOG
* linker issue in HostBoot (linker can't find singleton outside of
* a module).
*
- * @param[in,out] io_err Error log handle to be committed
+ * @param[in,out] io_err Error log handle to be committed
+ * @param[in] i_comitterComp Component committing the error log
*
* @return None
*/
-void errlCommit(errlHndl_t& io_err);
+
+// TODO Work item 4104 to make comitter comp required, no default.
+void errlCommit(errlHndl_t& io_err, compId_t i_committerComp = 0 );
/*****************************************************************************/
// Forward class declarations
@@ -100,7 +107,7 @@ public:
*
* @return None
*/
- void commitErrLog(errlHndl_t& io_err);
+ void commitErrLog(errlHndl_t& io_err, compId_t i_committerComp );
/**
* @brief Returns a unique error log ID
@@ -139,10 +146,10 @@ private:
ErrlManager(const ErrlManager& i_right);
ErrlManager& operator=(const ErrlManager& i_right);
+
/**
- * @brief
- * Current log ID: increment this when assigning log ID to a new errlog
- * as it is being committed.
+ * @brief Current log ID. As new error logs are created,
+ * this value will be used to assign the new error log its ID.
*/
uint32_t iv_currLogId;
diff --git a/src/include/usr/errl/errlprvt.H b/src/include/usr/errl/errlprvt.H
new file mode 100644
index 000000000..d8086b50b
--- /dev/null
+++ b/src/include/usr/errl/errlprvt.H
@@ -0,0 +1,145 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/include/usr/errl/errlprvt.H $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+#ifndef ERRLPRVT_H
+#define ERRLPRVT_H
+
+/**
+ * @file errlprvt.H
+ *
+ * @brief A class for the private header 'PH' section of an error log.
+ * Manages the data destined for the PEL PH section.
+ *
+*/
+
+#include <errl/errlsctnhdr.H>
+
+
+namespace ERRORLOG
+{
+
+class ErrlPrvt
+{
+
+ // ErrlEntry may access private elements of this class. Data items that
+ // you would expect to be part of ErrlEntry are actually instance data
+ // in this class.
+ friend class ErrlEntry;
+
+
+private:
+
+ enum constants
+ {
+ SLEN = 40, // section length w/o sizeof(ErrlSctnHdr)
+ SST = 0, // section type
+ VER = 1 // section version
+ // CSS_VER = 8 // TODO unused, relates to iv_cssver[]
+ };
+
+ /**
+ * @brief Constructor will initialize as much data in the private
+ * header as it can, including asking the ErrlManager for the error
+ * log ID. Also sets the time of creation.
+ *
+ * @param[in] i_CreatorCompId Creator of this error log.
+ */
+ ErrlPrvt( compId_t i_CreatorCompId );
+
+
+ /**
+ * @brief Destructor
+ */
+ ~ErrlPrvt();
+
+
+ /**
+ * @brief Disable copy constructor and assignment operator.
+ */
+ ErrlPrvt(const ErrlPrvt& i_right);
+ ErrlPrvt& operator=(const ErrlPrvt& i_right);
+
+
+ /**
+ * @brief Calculates the flattened size of this.
+ *
+ * @return Count of bytes needed to flatten this.
+ */
+ uint64_t flatSize() const;
+
+
+ /**
+ * @brief Flatten this to the output buffer given.
+ *
+ * @param[out] o_pBuffer Pointer to memory buffer where data will go.
+ * @param[in] i_cbBuffer Count of bytes in memory buffer.
+ * Call flatSize() first to know how big the
+ * buffer should be before calling flatten()
+ *
+ * @return Count of bytes flattened, or zero on error. The likely error
+ * is that the buffer is of insufficient size.
+ */
+ uint64_t flatten( void * o_pBuffer, const uint64_t i_cbBuffer );
+
+
+
+ // Instance data
+
+ ErrlSctnHdr iv_header; // section header for any/all sections
+
+ uint64_t iv_created; // TODO Expects BCD_time8_t, but using timebase
+ uint64_t iv_committed; // TODO Expects BCD_time8_t, but using timebase
+ uint8_t iv_cid; // Creator 'B' (enum errlCreator)
+ uint8_t iv_sctns; // count of sections
+ uint32_t iv_plid; // error log id
+
+ // uint8_t iv_cssver[CSS_VER]; // TODO unused now, do we need this?
+ // uint32_t iv_eid; // TODO Error ID now same as PLID
+
+
+};
+
+
+
+/*****************************************************************************/
+// Destructor
+
+inline ErrlPrvt::~ErrlPrvt()
+{
+}
+
+
+/*****************************************************************************/
+// Export data size
+
+inline uint64_t ErrlPrvt::flatSize() const
+{
+ return ( iv_header.flatSize() + ErrlPrvt::SLEN );
+}
+
+
+
+
+} // namespace
+
+
+#endif //ERRLPRVT_H
diff --git a/src/include/usr/errl/errlsctn.H b/src/include/usr/errl/errlsctn.H
new file mode 100644
index 000000000..bd31aec40
--- /dev/null
+++ b/src/include/usr/errl/errlsctn.H
@@ -0,0 +1,106 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/include/usr/errl/errlsctn.H $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+#ifndef ERRLSCTN_H
+#define ERRLSCTN_H
+/**
+ * @file errlsctn.H
+ *
+ * @brief Base class for adding sections of data to an error log.
+ * A section may be used to store unique data for the
+ * error such as SRC or user-defined data or
+ * component traces, etc.
+ */
+
+/*****************************************************************************/
+// I n c l u d e s
+/*****************************************************************************/
+#include <stdint.h>
+#include <stdlib.h>
+#include <errl/errltypes.H>
+#include <hbotcompid.H>
+#include <errl/errlsctnhdr.H>
+
+
+
+namespace ERRORLOG
+{
+
+/**
+ * @brief Base class of a section in an error log object. Derivations
+ * may include ErrlCallHome, ErrlExtUH, ErrlSrc, ErrlUD, etc.
+ */
+class ErrlSctn
+{
+
+
+
+protected:
+
+ /**
+ * @brief Constructor
+ * Initializes the base object with section information
+ *
+ * @param[in] i_sid Section id
+ * @param[in] i_slen Section length
+ * @param[in] i_ver Section version
+ * @param[in] i_sst Subsection type
+ * @param[in] i_compId Component id
+ *
+ * @return void
+ */
+ ErrlSctn( const uint16_t i_sid,
+ const uint16_t i_slen,
+ const uint8_t i_ver,
+ const uint8_t i_sst,
+ const compId_t i_compId );
+
+
+ /**
+ * @brief Default destructor
+ *
+ * @return void
+ */
+ virtual ~ErrlSctn();
+
+
+
+ /**
+ * @brief Disabled copy constructor and assignment operator
+ */
+ ErrlSctn(const ErrlSctn& i_right);
+ ErrlSctn& operator=(const ErrlSctn& i_right);
+
+
+
+ // PEL section header for flattening.
+ ErrlSctnHdr iv_header;
+
+};
+
+
+
+} // End namespace
+
+
+#endif //ERRLSCTN_H
+
diff --git a/src/include/usr/errl/errlsctnhdr.H b/src/include/usr/errl/errlsctnhdr.H
new file mode 100644
index 000000000..069fa58ba
--- /dev/null
+++ b/src/include/usr/errl/errlsctnhdr.H
@@ -0,0 +1,164 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/include/usr/errl/errlsctnhdr.H $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+#ifndef ERRLSCTNHDR_H
+#define ERRLSCTNHDR_H
+/**
+ * @file errlsctnhdr.H
+ *
+ * @brief This file contain the class that abstracts the header of
+ * an error log section. Every section in PEL binary data starts with
+ * eight bytes of data. This class manages those 8 bytes for all manner
+ * of PEL sections, including PH (private header), UH (user header),
+ * UD (user defined), etc.
+ *
+ */
+
+/*****************************************************************************/
+// I n c l u d e s
+/*****************************************************************************/
+#include <stdint.h>
+#include <stdlib.h>
+#include <errl/errltypes.H>
+#include <hbotcompid.H>
+#include <string.h>
+
+namespace ERRORLOG
+{
+
+/**
+ * @brief class ErrlSctnHdr abstracts a header of each PEL section in an
+ * error log object. Objects of classes ErrlSctn, ErrlUH, ErrlPrvt
+ * have one of these.
+ */
+class ErrlSctnHdr
+{
+
+
+ // All these classes have a ErrlSctnHdr
+ friend class ErrlSctn;
+ friend class ErrlPrvt;
+ friend class ErrlUH;
+ friend class ErrlUD;
+ friend class ErrlSrc;
+
+
+
+private:
+
+ /**
+ * @brief Section header constructor
+ *
+ * Comp ID, section type and version uniquely identify exactly what
+ * kind of a section it is. These fields can be used by a post-dump
+ * parser to call the user-supplied parser code to interpret and
+ * the data nicely.
+ *
+ * @param[in] i_sid Section ID destined for iv_sid
+ * @param[in] i_slen Section length
+ * @param[in] i_ver Section version
+ * @param[in] i_sst Subsection type
+ * @param[in] i_compId Component Id of the caller
+ *
+ * @return void
+ */
+ ErrlSctnHdr( const uint16_t i_sid,
+ const uint16_t i_slen,
+ const uint8_t i_ver,
+ const uint8_t i_sst,
+ const compId_t i_compId );
+
+
+
+
+ /**
+ * @brief Default destructor
+ *
+ * @return void
+ */
+ ~ErrlSctnHdr();
+
+
+
+ /**
+ * @brief Disabled copy constructor and assignment operator
+ */
+ ErrlSctnHdr(const ErrlSctnHdr& i_right);
+ ErrlSctnHdr& operator=(const ErrlSctnHdr& i_right);
+
+
+
+
+ /**
+ * @brief Compute the flattened size of this.
+ *
+ * @return Size in bytes of the flattened data, which is 8
+ * for an ErrlSctnHdr.
+ */
+ uint64_t flatSize() const;
+
+
+
+ /**
+ * @brief Flatten to buffer provided.
+ *
+ * @param[in,out] o_buffer Points to data block to be filled
+ * @param[in] i_cbBuffer Count of bytes in buffer supplied
+ *
+ * @return Count of bytes copied to caller's
+ * buffer or else zero if it does not fit.
+ */
+ uint64_t flatten( void * o_pbuffer, const uint64_t i_cbBuffer );
+
+
+
+
+
+ // Instance data.
+ uint16_t iv_sid; // section id 'PH' 'UH' etc (errlSectionId_t)
+ uint16_t iv_slen; // section length
+ uint8_t iv_ver; // section version
+ uint8_t iv_sst; // subsection type
+ compId_t iv_compId; // hostboot component id
+
+
+};
+
+
+
+//***************************************************************************
+
+inline uint64_t ErrlSctnHdr::flatSize() const
+{
+ // 2 for section id (errlSectionId)
+ // 2 for section len
+ // 1 for ver
+ // 1 for subsection type
+ // 2 for component id
+ CPPASSERT( 8 == sizeof( pelSectionHeader_t ));
+ return sizeof( pelSectionHeader_t );
+}
+
+} // End namespace
+
+#endif //ERRLSCTNHDR_H
+
diff --git a/src/include/usr/errl/errlsrc.H b/src/include/usr/errl/errlsrc.H
new file mode 100644
index 000000000..ab48a93d8
--- /dev/null
+++ b/src/include/usr/errl/errlsrc.H
@@ -0,0 +1,146 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/include/usr/errl/errlsrc.H $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+#ifndef ERRLSRC_H
+#define ERRLSRC_H
+
+/**
+ * @file errlsrc.H
+ *
+ * @brief Manage the data that make up the 'PS' section in an
+ * error log PEL. PS stands for Primary System Reference Code, or SRC.
+ * Part of that data management is the flattening of data into PEL.
+ *
+*/
+
+#include <errl/errlsctn.H>
+#include <errl/errlsctnhdr.H>
+
+
+namespace ERRORLOG
+{
+
+class ErrlSrc : public ErrlSctn
+{
+
+ // ErrlEntry may access private elements of this class. Data items that
+ // you would expect to be part of ErrlEntry are actually instance data
+ // in this class.
+ friend class ErrlEntry;
+
+
+private:
+
+
+ enum constants
+ {
+ SLEN = 72, // section length w/o sizeof(ErrlSctnHdr)
+ SST = 1, // section type
+ VER = 1, // section version
+ SRCVER = 2, // SRC version (not section version)
+ WORDCOUNT = 9 // SRC word count
+ // CSS_VER = 8 // TODO unused, relates to iv_cssver[]
+ };
+
+
+ /**
+ * @brief Constructor. Pass in items destined for the primary SRC
+ * section in the error log.
+ *
+ * @param[in] i_srcType SRC type
+ * @param[in] i_modId Module ID
+ * @param[in] i_reasonCode Reason code
+ * @param[in] i_user1 User data 1
+ * @param[in] i_user2 User data 2
+ *
+ */
+ ErrlSrc( srcType_t i_srcType,
+ uint8_t i_modId,
+ uint16_t i_reasonCode,
+ uint64_t i_user1,
+ uint64_t i_user2 );
+
+
+ /** @brief Destructor. */
+ ~ErrlSrc();
+
+
+
+ /**
+ * @brief Disable copy constructor and assignment operator.
+ */
+ ErrlSrc(const ErrlSrc& i_right);
+ ErrlSrc& operator=(const ErrlSrc& i_right);
+
+
+
+ /**
+ * @brief Data export facility to flatten data to PEL.
+ * Exports the object into the 'PS' primary SRC PEL section.
+ *
+ * @param[out] o_pBuffer Pointer to buffer where flattened data will go.
+ * @param[in] i_cbBuffer Count of bytes in target buffer
+ *
+ */
+ uint64_t flatten( void * o_pBuffer, const uint64_t i_cbBuffer );
+
+ /**
+ * @brief Data export size. Presently, Hostboot returns
+ * creates an 80-byte PS section: 72 bytes in the SRC
+ * and 8 bytes for the PEL section header. This is the
+ * amount of flat storage (in bytes) required to
+ * store the object.
+ *
+ * @return Size in bytes.
+ *
+ */
+ uint64_t flatSize() const;
+
+
+ // Instance data
+ srcType_t iv_srcType; // SRC type, the ?? in SRC ??xxxxxx
+ uint8_t iv_modId; // module ID
+ uint16_t iv_reasonCode; // reason code
+ epubSubSystem_t iv_ssid; // subsystem type, the ?? in SRC xx??xxxx
+ uint64_t iv_user1; // user data 1
+ uint64_t iv_user2; // user data 2
+
+
+};
+
+
+//**************************************************************************
+// Hostboot PS SRC section generates minimal section with no additional
+// words of data.
+inline uint64_t ErrlSrc::flatSize() const
+{
+ // 72 bytes in SRC structure + 8 byte section header.
+ CPPASSERT( 80 == sizeof( pelSRCSection_t ));
+ return sizeof( pelSRCSection_t );
+}
+
+
+
+} // namespace
+
+#endif //ERRLSRC_H
+
diff --git a/src/include/usr/errl/errltypes.H b/src/include/usr/errl/errltypes.H
index 10d9e7542..af5067ea4 100644
--- a/src/include/usr/errl/errltypes.H
+++ b/src/include/usr/errl/errltypes.H
@@ -79,25 +79,114 @@ typedef ERRORLOG::ErrlEntry* errlHndl_t;
namespace ERRORLOG
{
+
+
+/**
+ * @brief Scope is found in user header section.
+
+ */
+enum errlScope_t
+{
+ ERRL_SCOPE_PLATFORM = 0x03, ///< Entire Platform
+};
+
+
+
+/**
+ * @brief Domain as found in user header section.
+ */
+enum errlDomain_t
+{
+ ERRL_DOMAIN_DEFAULT = 0xFF // Field based on Subsystem ID
+};
+
+
+/**
+ * @brief Vector as found in user header section.
+ */
+enum errlVector_t
+{
+ ERRL_VECTOR_DEFAULT = 0xFF // Vector that triggered the base class
+ // of problem in Problem Domain Field.
+ // Unique field based on Subsystem ID
+};
+
+
+
+/**
+ * @brief Platform Event Log actions
+ *
+ * Several action flags used to trigger various
+ * handling mechanisms for an event log such as
+ * calling home and sending to the hypervisor.
+ */
+enum errlActions_t
+{
+ ERRL_ACTION_NONE = 0x0000, // No action required
+};
+
+
+
+
+/**
+ * @brief Creator types.
+ */
+enum errlCreator_t
+{
+ ERRL_CID_HOSTBOOT = 'B',
+};
+
+
+
+
+/**
+ * @brief Enumeration of PEL section eyecatchers. These are
+ * usually handled as a uint16_t. See
+ * "eCLipz and P7 Platform Event Log and SRC PLDD" documentation
+ * https://mcdoc.boeblingen.de.ibm.com/out/out.ViewDocument.php?documentid=1675
+ */
+enum errlSectionId_t
+{
+ ERRL_SID_PRIVATE_HEADER = 0x5048, // PH private header
+ ERRL_SID_USER_HEADER = 0x5548, // UH user header
+ ERRL_SID_PRIMARY_SRC = 0x5053, // PS
+ ERRL_SID_USER_DEFINED = 0x5544 // UD user defined
+};
+
+
/**
* @brief Enumeration of error log severity.
* Needs to fit into 1 byte for flattening purposes.
+ *
+ * Severity resides in the user header of the PEL log.
+ *
+ * Refer to this ErrlEntry setter:
+ * void ErrlEntry::setSev(const errlSeverity_t i_sev)
*/
enum errlSeverity_t
{
- ERRL_SEV_INFORMATIONAL = 0x00,
- ERRL_SEV_UNRECOVERABLE = 0x10,
+ ERRL_SEV_INFORMATIONAL = 0x00,
+ ERRL_SEV_UNRECOVERABLE = 0x10,
ERRL_SEV_CRITICAL_SYS_TERM = 0x20,
- ERRL_SEV_UNKNOWN = 0xFF
+ ERRL_SEV_UNKNOWN = 0xFF
};
+
+
+
/**
* @brief Event (error) type
* Needs to fit into 1 byte for flattening purposes.
+ *
+ * Event type resides in user header of PEL log.
+ *
+ * Refer to this ErrlEntry setter:
+ * void ErrlEntry::setEventType(const errlEventType_t i_eventType)
*/
enum errlEventType_t
{
ERRL_ETYPE_NOT_APPLICABLE = 0x00,
+ ERRL_ETYPE_MISCELLANEOUS = 0x01,
ERRL_ETYPE_DUMP_NOTIFICATION = 0x08,
ERRL_ETYPE_USER_DECONFIG = 0x20,
ERRL_ETYPE_SYS_DECONFIG = 0x21,
@@ -105,39 +194,54 @@ enum errlEventType_t
ERRL_ETYPE_CAPACITY_UPGRADE = 0x60,
};
-/**
- * @brief Error log call out priority
- * Needs to fit into 1 byte for flattening purposes.
- */
-enum callOutPriority_t
-{
- CALLOUT_PRIORITY_LOW = 1,
- CALLOUT_PRIORITY_MED = 2,
- CALLOUT_PRIORITY_HIGH = 3,
-};
+
+
/**
- * @brief Error log procedure Id
+ * @brief SRC type definitions
* Needs to fit into 1 byte for flattening purposes.
+ *
+ * This represents the byte in an SRC in position
+ * XX...... such as B1 in B181F00B.
+ *
+ * Refer to errlentry.H and this setter:
+ * void ErrlEntry::setSrcType(const srcType_t i_srcType)
+ *
*/
-enum epubProcedureId_t
+enum srcType_t
{
- EPUB_PRC_NONE = 0x00,
+ SRC_INTERVENTION_REQ = 0xA1,
+ SRC_ERR_INFO = 0xB1,
+ SRC_IPL_STATUS = 0xC1,
+ SRC_GENERAL_STATUS = 0xD1,
};
+
+
+
/**
* @brief Sub system definitions
* Needs to fit into 1 byte for flattening purposes.
+ * This represents the byte in an SRC in position
+ * ..XX.... such as 81 in B181F00B.
+ *
+ * Refer to errentry.H and this setter:
+ * void ErrlEntry::setSubSys(const epubSubSystem_t i_subSys);
*/
enum epubSubSystem_t
{
- EPUB_RESERVED_0 = 0x00,
- EPUB_UNKNOWN = 0xFF,
+ EPUB_RESERVED_0 = 0x00,
+ EPUB_FIRMWARE_SUBSYS = 0x80,
+ EPUB_FIRMWARE_SP = 0x81,
+ EPUB_UNKNOWN = 0xFF,
};
+
+
/**
* @brief Terminating flag definitions
* Needs to fit into 1 word (32-bits) for flattening purposes.
+ * TODO Termination state and termination action.
*/
enum errlTermState_t
{
@@ -146,16 +250,41 @@ enum errlTermState_t
};
-/**
- * @brief SRC type definitions
- * Needs to fit into 1 byte for flattening purposes.
- */
-enum srcType_t
+
+
+/** @enum errlUserDataType_t
+ *
+ * These are section type identifiers for the ERRL component for
+ * user-defined data sections. For example, if somebody calls
+ * errl->collectTrace("INITSVC")
+ * then the resulting UD PEL section header will be tagged with
+ * component id: ERRL_COMP_ID
+ * section type: ERRL_UDT_TRACE
+ * version: ERRL_UDV_DEFAULT_VER_1
+ *
+ * Other components will have to code a similar enum so that
+ * the the errl parser/pretty printer can "dispatch" a user-defined
+ * PEL section to them for printing based on the three values in
+ * the UD PEL section: component id, section type, and version.
+ *
+ * The section type field in the PEL header is one byte long.
+ */
+enum errlUserDataType_t
{
- SRC_INTERVENTION_REQ = 0xA1,
- SRC_ERR_INFO = 0xB1,
- SRC_IPL_STATUS = 0xC1,
- SRC_GENERAL_STATUS = 0xD1,
+ ERRL_UDT_TRACE = 0x0C, // A trace buffer
+};
+
+
+/** @enum errlUserDataVersion
+ *
+ * Identifier for the version of user data in an error log.
+ * This value is used in conjuction with the type field to format
+ * of the additional data in an error log. Versions and type should
+ * be unique across subcomponents of the errl component.
+*/
+enum errlUserDataVersion
+{
+ ERRL_UDV_DEFAULT_VER_1 = 0x0001, // Version 1, default info
};
@@ -171,47 +300,6 @@ const uint32_t ERRL_STORAGE_SIZE = 65536;
/**
- * @brief Flattened error log header structure contains the basic
- * instance variables of the ErrlEntry class. Note the
- * alignment of the fields, and that the structure is packed.
- */
-typedef struct errl_header
-{
- uint32_t cbytes; // count of bytes in this struct
- uint32_t csections; // count of sections in this error log
- uint16_t reasonCode; // reason code
- uint8_t unused1; // need this for alignment
- uint8_t modId; // module id
- uint8_t sev; // severity
- uint8_t eventType; // event type
- uint8_t subSys; // subsystem
- uint8_t srcType; // SRC type
- uint32_t termState; // Terminate state
- uint32_t logId; // This log's unique ID
- uint64_t user1; // Optional user data 1
- uint64_t user2; // Optional user data 2
- uint64_t CreationTime; // time error log was created
-} __attribute__((packed)) errl_header_t;
-
-
-
-/**
- * @brief Error logs may have a number of sections/FFDC sections added.
- * This is a section header that preceeds the user-defined
- * data that follows this header. Note the alignment of the fields,
- * and that this structure is packed.
- */
-typedef struct section_header
-{
- uint32_t cbHeader; // count of bytes in this struct (flattening)
- uint32_t cbSection; // count of bytes in the user-added data
- uint16_t compId; // component id
- uint8_t sctnVer; // section version
- uint8_t subSect; // subsection
-} __attribute__((packed)) section_header_t;
-
-
-/**
* @brief The RAM storage for committed error logs starts with this
* header. This structure is org'ed at &g_ErrlStorage[0]. All
* offsets are based from &g_achErrlStorage[0], so the first
@@ -242,6 +330,152 @@ typedef struct marker
+
+
+
+/**
+ * @brief pelSectionHeader_t
+ *
+ * A PEL structure used to flatten error logs to PEL format.
+ *
+ * This structure represents the first 8 bytes of any PEL section.
+ * Populated by the flatten code of class ErrlSctnHdr for any PEL
+ * section. Classes ErrlUH, ErrlPrvt, and ErrlSctn each have a
+ * ErrlSctnHdr. User-defined sections derive from ErrlSctn, so
+ * their section header works though ErrlSctn parent class.
+ *
+ * When parsing a PEL data set, start at offset 0 (the
+ * first section). Then add "len" to know the starting offset
+ * of the second section, and so on.
+ *
+ * When pretty-printing a user-defined PEL section, the
+ * controlling logic will "dispatch" a PEL section to a
+ * user-supplied printing function based on the component ID,
+ * section type, and version.
+ */
+typedef struct pelsectionheader
+{
+ uint16_t sid; // section identifier
+ uint16_t len; // overall length of this section
+ uint8_t ver; // section version
+ uint8_t sst; // section type
+ uint16_t compId; // component ID
+} __attribute__((packed)) pelSectionHeader_t;
+
+
+
+/**
+ * @brief pelPrivateHeaderSection_t
+ *
+ * A PEL structure used to flatten error logs to PEL format.
+ *
+ * This structure represents an entire Private Header (PH)
+ * PEL section. This section is a fixed overall
+ * length of 48 bytes including the PEL section header.
+ * This the first section found in a flat PEL dataset.
+ * Populated by the flatten code of class ErrlPrvt.
+ *
+ * The component named in the section header is the
+ * creating component of the error log.
+ */
+typedef struct pelprivateheadersection
+{
+ pelSectionHeader_t sectionheader;
+ uint64_t creationTime;
+ uint64_t commitTime;
+ uint8_t creatorId; // 'B' for Hostboot
+ uint8_t reserved0;
+ uint8_t reserved1;
+ uint8_t sectionCount;
+ uint32_t reserved2;
+ uint64_t creatorImplementation;
+ uint32_t plid;
+ uint32_t eid;
+} __attribute__((packed)) pelPrivateHeaderSection_t;
+
+
+
+/**
+ * @brief pelUserHeaderSection_t
+ *
+ * A PEL structure used to flatten error logs to PEL format.
+ *
+ * This structure represents an entire User Header (UH)
+ * PEL section. This section is a fixed overall
+ * length of 0x18 bytes including the PEL section header.
+ * This the second section found in a flat PEL dataset.
+ * Populated by the flatten code of class ErrlUH.
+ *
+ * The component named in the section header is the
+ * committing component of the error log.
+ */
+typedef struct peluserheadersection
+{
+ pelSectionHeader_t sectionheader;
+ uint8_t ssid; // subsystem id
+ uint8_t scope; // event scope
+ uint8_t sev; // severity
+ uint8_t etype; // event type
+ uint32_t reserved0; // for error log return code
+ uint8_t domain; // TODO not used in Hostboot
+ uint8_t vector; // TODO not used in Hostboot
+ uint16_t actions; // TODO not used in Hostboot
+ uint32_t reserved1;
+} __attribute__((packed)) pelUserHeaderSection_t;
+
+
+
+
+/**
+ * @brief pelSRCSection_t
+ *
+ * A PEL structure used to flatten error logs to PEL format.
+ *
+ * This structure represents an entire Primary SRC (PS)
+ * PEL section. This section is a fixed overall
+ * length of 80 bytes including the PEL section header.
+ * This the usually the third section found in a flat PEL dataset.
+ * Populated by the flatten code of class ErrlSRC.
+ *
+ * Hostboot generates a minimal SRC as described under
+ * "Common Usage of the SRC Structure" (p.69) in the PEL
+ * reference (mcdoc 1675). The page numbers below refer
+ * to version 0.8 of that document.
+ */
+
+typedef struct pelsrcsection
+{
+ pelSectionHeader_t sectionheader;
+ uint8_t ver; // src version, usually a 2
+ uint8_t flags; // src flags
+ uint8_t reserved0;
+ uint8_t wordcount; // usually 9
+ uint16_t reserved1; // usually 0, but I put reasonCode here
+ uint16_t srcLength; // usually 72
+ // "Hex word 2" is the legacy nomenclature. p. 71.
+ // Low byte of this word is SRC format 0xF0.
+ uint32_t word2;
+ // "Hex word 3" p. 71
+ uint16_t word3;
+ uint8_t moduleId;
+ uint8_t reserved2;
+ // "Hex word 4" p. 71 last progress code
+ uint32_t word4;
+ // "Hex word 5" p. 72 error status flags, etc.
+ uint32_t word5;
+ // "Hex word 6-7" p. 72 optional, iv_user1
+ uint64_t word6;
+ // "Hex word 8-9" p. 72 optional, iv_user2
+ uint64_t word8;
+ char srcString[32];
+} __attribute__((packed)) pelSRCSection_t;
+
+
+
+
+
+
+
} // End namespace
#endif // ERRLTYPES_H
diff --git a/src/include/usr/errl/errlud.H b/src/include/usr/errl/errlud.H
new file mode 100644
index 000000000..30817e112
--- /dev/null
+++ b/src/include/usr/errl/errlud.H
@@ -0,0 +1,185 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/include/usr/errl/errlud.H $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+#ifndef ERRLUD_H
+#define ERRLUD_H
+/**
+ * @file errlud.H
+ *
+ * @brief Derive the ErrlUD (user defined) error log section from the
+ * more general ErrlSctn class.
+*/
+
+
+#include <errl/errlsctn.H>
+#include <errl/errlsctnhdr.H>
+
+
+
+namespace ERRORLOG
+{
+
+
+
+class ErrlUD : public ErrlSctn
+{
+
+
+ // ErrlEntry may access private elements of this class. Data items that
+ // you would expect to be part of ErrlEntry are actually instance data
+ // in this class.
+ friend class ErrlEntry;
+
+
+private:
+
+
+ /**
+ * @brief Constructor
+ *
+ * Create a user data section with the given input data.
+ *
+ * @param i_data Pointer to data
+ * @param i_size Length of data
+ * @param i_cid Component ID of the section
+ * @param i_ver Section version
+ * @param i_sst Section type
+ *
+ */
+ ErrlUD(
+ const void *i_data,
+ uint64_t i_size,
+ compId_t i_cid,
+ uint8_t i_ver,
+ uint8_t i_sst );
+
+
+
+ /**
+ * @brief Destructor
+ *
+ * Releases allocated resources
+ *
+ */
+ virtual ~ErrlUD();
+
+
+ /**
+ * @brief Disable copy constructor and assignment operator.
+ */
+ ErrlUD(const ErrlUD& i_right);
+ ErrlUD& operator=(const ErrlUD& i_right);
+
+
+ /**
+ * @brief Data export size. Amount of flat storage (in bytes) required to
+ * store the object.
+ *
+ * @return size in bytes
+ */
+ uint64_t flatSize();
+
+
+ /**
+ * @brief Data Export facility.
+ * Exports the object into the architecturally
+ * defined format for a user data section.
+ *
+ * @param[in,out] io_pBuffer Pointer to buffer where flat data will go.
+ * @param[in] i_cbBuffer Count of bytes in target buffer
+ *
+ */
+ uint64_t flatten( void * io_pBuffer, const uint64_t i_cbBuffer );
+
+
+
+
+
+ /**
+ * @brief Appends data to the section.
+ * Grows the section by the given amount
+ *
+ * @param[in] i_data Source data
+ * @param[in] i_size Additional size
+ *
+ * @return Size of new data or else zero on error.
+ *
+ */
+ uint64_t addData( const void *i_data, uint64_t i_size );
+
+
+
+
+ /**
+ * @brief Data size of the section
+ *
+ * The distinction is made between data size
+ * and object flat size. This method returns
+ * the size of the data only
+ *
+ * @return Length
+ *
+ */
+ uint64_t dataSize( void ) const;
+
+
+
+ /**
+ * @brief Data access
+ *
+ * Direct Access to the data of the object
+ * ( dangerous - use with caution )
+ *
+ * @return Data pointer
+ *
+ */
+ void * data( void ) const;
+
+
+
+
+ uint8_t * iv_pData; // Data Pointer
+ uint64_t iv_Size; // Data Length
+
+};
+
+
+
+/*****************************************************************************/
+// Get data size
+/*****************************************************************************/
+inline uint64_t ErrlUD::dataSize( void ) const
+{
+ return iv_Size;
+}
+
+
+/*****************************************************************************/
+// Data access pointer
+/*****************************************************************************/
+inline void * ErrlUD::data( void ) const
+{
+ return iv_pData;
+}
+
+} // namespace
+#endif /* ERRLUD_H */
diff --git a/src/include/usr/errl/errluh.H b/src/include/usr/errl/errluh.H
new file mode 100644
index 000000000..5768d85d1
--- /dev/null
+++ b/src/include/usr/errl/errluh.H
@@ -0,0 +1,165 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/include/usr/errl/errluh.H $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+#ifndef ERRLUH_H
+#define ERRLUH_H
+
+/**
+ * @file errluh.H
+ *
+ * @brief A class for the user header 'UH' section of an error log.
+ * This classes manages those ErrlEntry data items that are destined
+ * to be saved in the user header PEL section.
+*/
+
+#include <errl/errlentry.H>
+#include <errl/errlsctnhdr.H>
+
+
+namespace ERRORLOG
+{
+
+
+class ErrlUH
+{
+
+ // ErrlEntry may access private elements of this class. Data items that
+ // you would expect to be part of ErrlEntry are actually instance data
+ // in this class.
+ friend class ErrlEntry;
+
+
+
+private:
+
+ enum constants
+ {
+ // for generating UH section of PEL
+ SLEN = 16, // 16 does not include the 8 bytes of ErrlSctnHdr
+ VER = 1, // section version
+ SST = 0 // section type
+ };
+
+ /** @brief User header constructor. */
+ ErrlUH( errlSeverity_t i_sev );
+
+ /** @brief User header destructor. */
+ ~ErrlUH();
+
+
+ /**
+ * @brief Disable copy constructor and assignment operator.
+ */
+ ErrlUH(const ErrlUH& i_right);
+ ErrlUH& operator=(const ErrlUH& i_right);
+
+
+ /**
+ * @brief Data export size. Amount of flat storage (in bytes) required to
+ * store the object.
+ *
+ * @return size in bytes
+ */
+ uint64_t flatSize() const;
+
+
+ /**
+ * @brief Data Export facility. Flatten the object into PEL for the
+ * 'UH' user header section.
+ *
+ * @param[in,out] io_pBuffer Pointer to buffer where flat data will go.
+ * @param[in] i_cbBuffer Count of bytes in target buffer
+ *
+ */
+ uint64_t flatten( void * io_pBuffer, const uint64_t i_cbBuffer );
+
+
+ /** @brief Set the component ID into the user header.
+ * Only should be called from ErrlEntry instance.
+ * The component ID in the user header identifies
+ * the component that committed the error log.
+ *
+ * @param[in] i_compId component ID
+ */
+ void setComponentId( compId_t i_compId );
+
+
+
+
+ // Instance variables
+ // SctnHdr for 'UH' section
+ ErrlSctnHdr iv_header;
+
+
+ errlSeverity_t iv_severity;
+ errlEventType_t iv_etype;
+
+
+ // TODO may need getters/setters for these fields. Presently,
+ // they are defaulted at object creation time, and not set
+ // or gotten by anyone.
+ epubSubSystem_t iv_ssid;
+ errlDomain_t iv_domain;
+ errlVector_t iv_vector;
+ uint16_t iv_actions;
+ errlScope_t iv_scope;
+
+};
+
+
+
+
+
+/*****************************************************************************/
+// Destructor
+
+inline ErrlUH::~ErrlUH()
+{
+}
+
+
+/*****************************************************************************/
+// Export data size
+
+inline uint64_t ErrlUH::flatSize() const
+{
+ return ( iv_header.flatSize() + SLEN );
+}
+
+
+
+
+/*****************************************************************************/
+// For user headers, the comp ID represents the committing component.
+
+inline void ErrlUH::setComponentId( compId_t i_compId )
+{
+ iv_header.iv_compId = i_compId;
+}
+
+
+
+
+} // namespace
+
+
+#endif //ERRLUH_H
diff --git a/src/include/usr/hbotcompid.H b/src/include/usr/hbotcompid.H
index 94eb2f33d..8f1c6e382 100644
--- a/src/include/usr/hbotcompid.H
+++ b/src/include/usr/hbotcompid.H
@@ -53,10 +53,20 @@ const char MY_COMP_NAME[] = "myname";
//@}
/** @name ERRL
- * Error Logging component
+ * Error Logging component.
+ *
+ * Oct 2011: Temporarily set ERRL component ID to the
+ * same as FSP ERRL in order to make the FSP x86 errl tool
+ * format Hostboot error logs with traces. For user-defined
+ * trace sections, that tools expects component 0x3100,
+ * section ID 0x0C, and version 1.
+ *
+ * Requirement SW105241 is opened for fips8xx errl tool
+ * to start becoming Hostboot aware. TODO When errl becomes
+ * Hostboot aware, ERRL comp id can revert to 0x0100. Monte
*/
//@{
-const compId_t ERRL_COMP_ID = 0x0100;
+const compId_t ERRL_COMP_ID = 0x3100;
const char ERRL_COMP_NAME[] = "errl";
//@}
diff --git a/src/include/usr/trace/trace.H b/src/include/usr/trace/trace.H
index cb4277603..c5d0a0d2a 100644
--- a/src/include/usr/trace/trace.H
+++ b/src/include/usr/trace/trace.H
@@ -40,6 +40,7 @@
#include <sys/sync.h>
#include <stdarg.h>
+
/******************************************************************************/
// Globals/Constants
/******************************************************************************/
@@ -137,6 +138,9 @@ typedef Singleton<Trace> theTrace;
*/
class Trace
{
+ /* ErrlEntry will call getBuffer() */
+ friend class ErrlEntry;
+
public:
/**
@@ -200,6 +204,31 @@ public:
const uint32_t i_size,
const int32_t i_type);
+
+ /**
+ * @brief Retrieve full trace buffer for component i_comp.
+ *
+ * Caller must allocate memory for the output buffer. Caller may
+ * first query the size of the buffer by calling with the desired
+ * component/trace buffer name and with o_data null and with i_bufferSize
+ * zero. The value returned will be the buffer size. Caller then
+ * allocates the buffer and calls again.
+ *
+ * @param [in] i_pComp pointer to name string
+ * @param [out] o_data pointer to where data will be stored
+ * @param [in] i_bufferSize size of buffer in bytes
+ *
+ * @return Count of bytes copied, or if given null parameters,
+ * the size of the buffer, or else zero for error, perhaps the
+ * component name/trace buffer name is not found.
+ */
+ uint64_t getBuffer( const char * i_pComp,
+ void * o_data,
+ uint64_t i_bufferSize );
+
+
+
+
protected:
/**
@@ -212,6 +241,10 @@ protected:
*/
~Trace();
+
+
+
+
private:
/**
@@ -248,21 +281,6 @@ private:
const uint32_t i_size);
- /**
- * @brief Retrieve full trace buffer for component i_comp
- *
- * This function assumes memory has already been allocated for
- * the full trace buffer in o_data.
- *
- * @param [in] i_td_ptr Trace descriptor of buffer to retrieve.
- * @param [out] o_data Pre-allocated pointer to where data will be stored.
- *
- * TODO - Not Supported Yet
- *
- * @return Non-zero return code on error
- */
- int32_t getBuffer(const trace_desc_t * i_td_ptr,
- void *o_data);
/**
* @brief Retrieve partial trace buffer for component i_comp
diff --git a/src/usr/errl/errlentry.C b/src/usr/errl/errlentry.C
index c935ccffc..fc171fbfc 100644
--- a/src/usr/errl/errlentry.C
+++ b/src/usr/errl/errlentry.C
@@ -31,11 +31,10 @@
/*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <hbotcompid.H>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
-#include "errlsctn.H"
-#include "errlffdc.H"
#include <trace/interface.H>
#include <arch/ppc.H>
@@ -53,70 +52,81 @@ ErrlEntry::ErrlEntry(const errlSeverity_t i_sev,
const uint16_t i_reasonCode,
const uint64_t i_user1,
const uint64_t i_user2) :
- iv_reasonCode(i_reasonCode),
- iv_sev(i_sev),
- iv_eventType(ERRL_ETYPE_NOT_APPLICABLE),
- iv_subSys(EPUB_RESERVED_0),
- iv_srcType(SRC_ERR_INFO),
- iv_termState(TERM_STATE_UNKNOWN),
- iv_modId(i_modId),
- iv_user1(i_user1),
- iv_user2(i_user2),
- iv_logId(0)
+ iv_Private( static_cast<compId_t>(i_reasonCode & 0xFF00)),
+ iv_User( i_sev ),
+ // The SRC_ERR_INFO becomes part of the SRC; example, B1 in SRC B180xxxx
+ // iv_Src assigns the epubSubSystem_t; example, 80 in SRC B180xxxx
+ iv_Src( SRC_ERR_INFO, i_modId, i_reasonCode, i_user1, i_user2 ),
+ iv_termState(TERM_STATE_UNKNOWN)
{
- // record time of creation
- iv_CreationTime = getTB();
}
+
+
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ErrlEntry::~ErrlEntry()
{
// Free memory of all sections
- for (std::vector<ErrlSctn*>::iterator l_itr = iv_SectionVector.begin();
+ for (std::vector<ErrlUD*>::iterator l_itr = iv_SectionVector.begin();
l_itr != iv_SectionVector.end(); ++l_itr)
{
delete (*l_itr);
}
+
}
///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-ErrlFFDC* ErrlEntry::addFFDC(const compId_t i_compId,
+// add a new UD section to the list of optional sections
+
+ErrlUD * ErrlEntry::addFFDC(const compId_t i_compId,
const void * i_dataPtr,
const uint32_t i_ffdcLen,
const uint8_t i_ffdcVer,
const uint8_t i_ffdcSubSect)
{
- ErrlFFDC* l_ffdcSection = NULL;
+ ErrlUD * l_ffdcSection = NULL;
if ( (i_dataPtr == NULL) || (i_ffdcLen == 0) )
{
- TRACFCOMP( ERRORLOG::g_trac_errl,
- "Invalid FFDC data pointer or size, no add");
+ TRACFCOMP( g_trac_errl,
+ "ErrlEntry::addFFDC(): Invalid FFDC data pointer or size, no add");
}
else
{
- // Create
- l_ffdcSection = new ErrlFFDC(i_compId, i_dataPtr, i_ffdcLen,
- i_ffdcVer, i_ffdcSubSect);
-
- // Add to the end of the vector of sections for this error log.
+ // Create a user-defined section.
+ l_ffdcSection = new ErrlUD( i_dataPtr,
+ i_ffdcLen,
+ i_compId,
+ i_ffdcVer,
+ i_ffdcSubSect );
+
+ // Add to the vector of sections for this error log.
iv_SectionVector.push_back( l_ffdcSection );
}
return l_ffdcSection;
}
+
+
+
+
+
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-void ErrlEntry::appendToFFDC(ErrlFFDC* i_ffdcPtr,
+void ErrlEntry::appendToFFDC(ErrlUD * i_pErrlUD,
const void *i_dataPtr,
const uint32_t i_dataLen)
{
- // class ErrlFFDC inherits addData() from its parent class ErrlSctn
- i_ffdcPtr->addData( i_dataPtr, i_dataLen );
+ uint64_t l_rc;
+
+ l_rc = i_pErrlUD->addData( i_dataPtr, i_dataLen );
+ if( 0 == l_rc )
+ {
+ TRACFCOMP( g_trac_errl, "ErrlEntry::appendToFFDC() rets zero" );
+ }
return;
}
@@ -124,39 +134,164 @@ void ErrlEntry::appendToFFDC(ErrlFFDC* i_ffdcPtr,
///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
+// Return a Boolean indication of success.
-uint64_t ErrlEntry::flattenedSize()
+bool ErrlEntry::collectTrace(const char i_name[], const uint32_t i_max)
{
- uint64_t l_bytecount = sizeof( errl_header_t );
+ bool l_rc = false;
- // add the bytes in the sections, if any
- std::vector<ErrlSctn*>::iterator it;
- for( it = iv_SectionVector.begin(); it != iv_SectionVector.end(); it++ )
+ do
{
- l_bytecount += (*it)->flattenedSize();
+ // By passing nil arguments, obtain the size of the buffer.
+ uint64_t l_cbFull = TRACE::Trace::getTheInstance().getBuffer( i_name,
+ NULL,
+ 0 );
+ if( 0 == l_cbFull )
+ {
+ TRACFCOMP( g_trac_errl,
+ "ErrlEntry::collectTrace(): getBuffer(%s) rets zero.", i_name );
+ break;
+ }
+
+ if( 0 == i_max )
+ {
+ // Full trace buffer desired. Allocate the buffer.
+ char l_traceBuffer[ l_cbFull ];
+
+ // Get the data into the buffer.
+ TRACE::Trace::getTheInstance().getBuffer( i_name,
+ l_traceBuffer,
+ l_cbFull );
+
+ // Save the trace buffer as a UD section on this.
+ ErrlUD * l_udSection = new ErrlUD( l_traceBuffer,
+ l_cbFull,
+ ERRL_COMP_ID,
+ ERRL_UDV_DEFAULT_VER_1,
+ ERRL_UDT_TRACE );
+
+ // Add the trace section to the vector of sections
+ // for this error log.
+ iv_SectionVector.push_back( l_udSection );
+
+ l_rc = true;
+ break;
+ }
+
+ // else partial buffer desired... future sprint
+ TRACFCOMP( g_trac_errl,
+ "ErrlEntry::collectTrace(): partial buffer not impl'd" );
+ break;
}
+ while(0);
- return l_bytecount;
+ return l_rc;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+errlSeverity_t ErrlEntry::sev() const
+{
+ return iv_User.iv_severity;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+void ErrlEntry::setSev(const errlSeverity_t i_sev)
+{
+ iv_User.iv_severity = i_sev;
+ return;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+errlEventType_t ErrlEntry::eventType() const
+{
+ return iv_User.iv_etype;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+void ErrlEntry::setEventType(const errlEventType_t i_eventType)
+{
+ iv_User.iv_etype = i_eventType;
+ return;
+}
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+epubSubSystem_t ErrlEntry::subSys() const
+{
+ return iv_User.iv_ssid;
}
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+void ErrlEntry::setSubSys(const epubSubSystem_t i_subSys)
+{
+ iv_User.iv_ssid = i_subSys;
+ return;
+}
+
+
///////////////////////////////////////////////////////////////////////////////
-// Flatten object instance data into a packed structure.
-// See errl/erltypes.H and the errl_header_t struct.
+// for use by ErrlManager
+void ErrlEntry::commit( compId_t i_committerComponent )
+{
+ // TODO need a better timepiece, or else apply a transform onto timebase
+ // for an approximation of real time.
+ iv_Private.iv_committed = getTB();
+
+ // User header contains the component ID of the committer.
+ iv_User.setComponentId( i_committerComponent );
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// for use by ErrlManager
+
+uint64_t ErrlEntry::flattenedSize()
+{
+ uint64_t l_bytecount = iv_Private.flatSize() +
+ iv_User.flatSize() +
+ iv_Src.flatSize();
+
+ // plus the sizes of the other optional sections
+
+ std::vector<ErrlUD*>::iterator it;
+ for( it = iv_SectionVector.begin(); it != iv_SectionVector.end(); it++ )
+ {
+ l_bytecount += (*it)->flatSize();
+ }
+ return l_bytecount;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Flatten this object and all its sections into PEL
+// for use by ErrlManager. Return how many bytes flattened to the output
+// buffer, or else zero on error.
-uint64_t ErrlEntry::flatten( void * io_pBuffer, uint64_t i_bufsize )
+uint64_t ErrlEntry::flatten( void * o_pBuffer, uint64_t i_bufsize )
{
uint64_t l_flatCount = 0;
+ uint64_t l_cb = 0;
do
{
l_flatCount = flattenedSize();
if ( i_bufsize < l_flatCount )
{
- // error path; return zero
+ // buffer is not big enough; return zero
TRACFCOMP( ERRORLOG::g_trac_errl, "Invalid buffer size");
l_flatCount = 0;
break;
@@ -165,50 +300,69 @@ uint64_t ErrlEntry::flatten( void * io_pBuffer, uint64_t i_bufsize )
// The CPPASSERT() macro will cause the compile to abend
// when the expression given evaluates to false. If ever
// these cause the compile to fail, then perhaps the size
- // of enum'ed types has grown unexpectedly. At any rate,
- // errl_header_t defined in errl/errltypes.H will need to
- // be adjusted for the changes in size of these instance
- // variables. Monte
- CPPASSERT( 1 == sizeof(iv_sev));
- CPPASSERT( 1 == sizeof(iv_eventType));
- CPPASSERT( 1 == sizeof(iv_subSys));
- CPPASSERT( 1 == sizeof(iv_srcType));
- CPPASSERT( 2 == sizeof(iv_reasonCode));
+ // of enum'ed types has grown unexpectedly.
+ CPPASSERT( 1 == sizeof(iv_Src.iv_srcType));
+ CPPASSERT( 2 == sizeof(iv_Src.iv_reasonCode));
CPPASSERT( 2 == sizeof(compId_t));
- CPPASSERT( 1 == sizeof(iv_modId));
- CPPASSERT( 0 == (sizeof(errl_header_t) % sizeof(uint32_t)));
-
-
- // Marshall the instance var data into a struct.
- errl_header_t l_hdr;
- memset( &l_hdr, 0, sizeof( l_hdr ));
- l_hdr.cbytes = sizeof( l_hdr );
- l_hdr.csections = iv_SectionVector.size();
- l_hdr.reasonCode = iv_reasonCode;
- l_hdr.modId = iv_modId;
- l_hdr.sev = iv_sev;
- l_hdr.eventType = iv_eventType;
- l_hdr.subSys = iv_subSys;
- l_hdr.srcType = iv_srcType;
- l_hdr.termState = iv_termState;
- l_hdr.logId = iv_logId;
- l_hdr.user1 = iv_user1;
- l_hdr.user2 = iv_user2;
- l_hdr.CreationTime = iv_CreationTime;
-
-
- // Write the flat data.
- char * l_pchar = reinterpret_cast<char*>(io_pBuffer);
- memcpy( l_pchar, &l_hdr, sizeof( l_hdr ));
- l_pchar += sizeof( l_hdr );
-
- // Append all the sections.
- std::vector<ErrlSctn*>::iterator it;
- for(it=iv_SectionVector.begin(); it != iv_SectionVector.end(); it++ )
+ CPPASSERT( 1 == sizeof(iv_Src.iv_modId));
+
+ // Inform the private header how many sections there are,
+ // counting the PH, UH, PS, and the optionals.
+ iv_Private.iv_sctns = 3 + iv_SectionVector.size();
+
+ // Flatten the PH private header section
+ char * pBuffer = static_cast<char *>(o_pBuffer);
+ l_cb = iv_Private.flatten( pBuffer, i_bufsize );
+ if( 0 == l_cb )
{
- uint64_t l_countofbytes = (*it)->flattenedSize();
- (*it)->flatten( l_pchar, l_countofbytes );
- l_pchar += l_countofbytes;
+ // Rare.
+ TRACFCOMP( g_trac_errl, "ph.flatten error");
+ l_flatCount = 0;
+ break;
+ }
+
+ pBuffer += l_cb;
+ i_bufsize -= l_cb;
+
+ // flatten the UH user header section
+ l_cb = iv_User.flatten( pBuffer, i_bufsize );
+ if( 0 == l_cb )
+ {
+ // Rare.
+ TRACFCOMP( g_trac_errl, "uh.flatten error");
+ l_flatCount = 0;
+ break;
+ }
+ pBuffer += l_cb;
+ i_bufsize -= l_cb;
+
+ // flatten the PS primary SRC section
+ l_cb = iv_Src.flatten( pBuffer, i_bufsize );
+ if( 0 == l_cb )
+ {
+ // Rare.
+ TRACFCOMP( g_trac_errl, "ps.flatten error");
+ l_flatCount = 0;
+ break;
+ }
+ pBuffer += l_cb;
+ i_bufsize -= l_cb;
+
+
+ // flatten the optional user-defined sections
+ std::vector<ErrlUD*>::iterator it;
+ for(it = iv_SectionVector.begin(); it != iv_SectionVector.end(); it++)
+ {
+ l_cb = (*it)->flatten( pBuffer, i_bufsize );
+ if( 0 == l_cb )
+ {
+ // Rare.
+ TRACFCOMP( g_trac_errl, "ud.flatten error");
+ l_flatCount = 0;
+ break;
+ }
+ pBuffer += l_cb;
+ i_bufsize -= l_cb;
}
}
while( 0 );
@@ -218,6 +372,5 @@ uint64_t ErrlEntry::flatten( void * io_pBuffer, uint64_t i_bufsize )
-
} // End namespace
diff --git a/src/usr/errl/errlffdc.C b/src/usr/errl/errlffdc.C
deleted file mode 100644
index cc8d6e7fc..000000000
--- a/src/usr/errl/errlffdc.C
+++ /dev/null
@@ -1,66 +0,0 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/errl/errlffdc.C $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
-/**
- * @file errlffdc.C
- *
- * @brief Implementation of ErrlFFDC class
- */
-
-/*****************************************************************************/
-// I n c l u d e s
-/*****************************************************************************/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <trace/interface.H>
-#include "errlffdc.H"
-
-
-namespace ERRORLOG
-{
-
-extern trace_desc_t* g_trac_errl;
-
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-ErrlFFDC::ErrlFFDC(const compId_t i_compId,
- const void* i_ffdcPtr,
- const uint32_t i_ffdcLen,
- const uint8_t i_ffdcVer,
- const uint8_t i_ffdcSubSect)
-: ErrlSctn(i_compId, i_ffdcVer, i_ffdcSubSect)
-{
-
- // addData is inherited from parent class ErrlSctn
- addData(i_ffdcPtr, i_ffdcLen);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-ErrlFFDC::~ErrlFFDC()
-{
-}
-
-
-
-} // End namespace
diff --git a/src/usr/errl/errlffdc.H b/src/usr/errl/errlffdc.H
deleted file mode 100644
index c6be4c8a7..000000000
--- a/src/usr/errl/errlffdc.H
+++ /dev/null
@@ -1,96 +0,0 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/errl/errlffdc.H $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
-#ifndef ERRLFFDC_H
-#define ERRLFFDC_H
-/**
- * @file errlffdc.H
- *
- * @brief FFDC data section within ErrlEntry object
- *
- * This header file contains the definition of FFDC data class that
- * is attached within the ErrlEntry object.
- *
- */
-
-/*****************************************************************************/
-// I n c l u d e s
-/*****************************************************************************/
-#include <stdint.h>
-#include <stdlib.h>
-#include "errlsctn.H"
-
-
-namespace ERRORLOG
-{
-
-/**
- * @brief Abstract an FFDC data section in an error log
- * This class contains FFDC data that users add to an error log.
- */
-class ErrlFFDC: public ErrlSctn
-{
-
-public:
-
- /**
- * @brief Constructor
- * Create a user data FFDC section with the given
- * input data.
- *
- * @param[in] i_compId Creator (component id)
- * @param[in] i_ffdcPtr Data pointer
- * @param[in] i_ffdcLen Data length (bytes)
- * @param[in] i_ffdcVer Data identifier
- * @param[in] i_ffdcSubSect Sub section identifier
- *
- * @return void
- */
- ErrlFFDC(const compId_t i_compId,
- const void* i_ffdcPtr,
- const uint32_t i_ffdcLen,
- const uint8_t i_ffdcVer,
- const uint8_t i_ffdcSubSect);
-
-
- /**
- * @brief Cleanup ( destructor )
- *
- * Releases allocated resources
- *
- */
- ~ErrlFFDC();
-
-
-private:
- /**
- * @brief Disabled copy constructor and assignment operator
- */
- ErrlFFDC(const ErrlFFDC& i_right);
- ErrlFFDC& operator=(const ErrlFFDC& i_right);
-
-};
-
-
-} // End namespace
-
-#endif //ERRLFFDC_H
diff --git a/src/usr/errl/errlmanager.C b/src/usr/errl/errlmanager.C
index 42cd3def8..48bc22325 100644
--- a/src/usr/errl/errlmanager.C
+++ b/src/usr/errl/errlmanager.C
@@ -105,6 +105,7 @@ ErrlManager::ErrlManager()
// marker_t* l_pMarker = OFFSET2MARKER( iv_pStorage->offsetStart );
// l_pMarker->offsetNext = 0;
// l_pMarker->length = 0;
+
}
///////////////////////////////////////////////////////////////////////////////
@@ -117,7 +118,7 @@ ErrlManager::~ErrlManager()
//
// Save and delete this error log. On output, io_err will be nul.
//
-void ErrlManager::commitErrLog(errlHndl_t& io_err)
+void ErrlManager::commitErrLog(errlHndl_t& io_err, compId_t i_committerComp )
{
do
{
@@ -132,9 +133,8 @@ void ErrlManager::commitErrLog(errlHndl_t& io_err)
// lock sem
mutex_lock(&iv_mutex);
- // Assign a unique error ID to the committed log
- uint32_t l_errId = getUniqueErrId();
- io_err->setLogId(l_errId);
+ // Ask the ErrlEntry to assign commit component, commit time, etc.
+ io_err->commit( i_committerComp );
// Get flattened count of bytes.
uint32_t l_cbActualFlat = io_err->flattenedSize();
@@ -185,20 +185,18 @@ void ErrlManager::commitErrLog(errlHndl_t& io_err)
///////////////////////////////////////////////////////////////////////////////
-// This operation is protected by the callers use of a mutex.
+// Atomically increment log id and return it.
uint32_t ErrlManager::getUniqueErrId()
{
- /* return (__sync_add_and_fetch(&iv_currLogId, 1)); */
- iv_currLogId++;
- return iv_currLogId;
+ return (__sync_add_and_fetch(&iv_currLogId, 1));
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Global function (not a method on an object) to commit the error log.
-void errlCommit(errlHndl_t& io_err)
+void errlCommit(errlHndl_t& io_err, compId_t i_committerComp )
{
- ERRORLOG::theErrlManager::instance().commitErrLog(io_err);
+ ERRORLOG::theErrlManager::instance().commitErrLog(io_err, i_committerComp );
return;
}
diff --git a/src/usr/errl/errlprvt.C b/src/usr/errl/errlprvt.C
new file mode 100644
index 000000000..064d842b8
--- /dev/null
+++ b/src/usr/errl/errlprvt.C
@@ -0,0 +1,135 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/errl/errlprvt.C $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+/**
+ * @file errlprvt.C
+ *
+ * @brief Implemenation of ErrlPrvt, a class for the management
+ * of the Private Header (PH) section of PEL.
+ *
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <hbotcompid.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+
+
+
+
+namespace ERRORLOG
+{
+
+
+extern trace_desc_t* g_trac_errl;
+
+
+
+/****************************************************************************/
+// Constructor for the private header (PH) section of PEL.
+
+ErrlPrvt::ErrlPrvt( compId_t i_CreatorCompId ) :
+ // contruct the ErrlSctnHdr
+ iv_header( ERRL_SID_PRIVATE_HEADER,
+ ErrlPrvt::SLEN,
+ ErrlPrvt::VER,
+ ErrlPrvt::SST,
+ i_CreatorCompId ),
+ iv_created( 0 ), // created time
+ iv_committed( 0 ), // committed time
+ iv_cid( ERRL_CID_HOSTBOOT ), // 'B' See errlCreator_t in errltypes.H
+ iv_sctns( 0 )
+{
+ // Ask the errl manager for the next ID to assign.
+ iv_plid = ERRORLOG::theErrlManager::instance().getUniqueErrId();
+
+ // Set the time of creation.
+ // TODO The field iv_created and iv_committed expect an 8-byte
+ // BCD-encoded timestamp. However, the FSP errl tool does not complain
+ // about displaying the timebase value. Perhaps we can apply a transform
+ // on time base to get an approximation of real time.
+ iv_created = getTB();
+
+}
+
+
+/*****************************************************************************/
+// Data export.
+// Flatten the data to the output pointer given as PEL as defined in
+// eCLipz and P7 Platform Event Log and SRC PLDD mcdoc 1675
+// Return how many bytes flattened, or else zero for error.
+
+
+uint64_t ErrlPrvt::flatten( void * o_pBuffer, const uint64_t i_cbBuffer )
+{
+ uint64_t l_rc = 0;
+ uint64_t l_cb = 0;
+
+ do
+ {
+
+ if( i_cbBuffer < iv_header.iv_slen )
+ {
+ TRACFCOMP( g_trac_errl, "ErrlPrvt::flatten: buffer too small");
+ break;
+ }
+
+ CPPASSERT( 48 == sizeof( pelPrivateHeaderSection_t ));
+
+ // See errltypes.H for pelPrivateHeaderSection_t
+ pelPrivateHeaderSection_t * p;
+ p = static_cast<pelPrivateHeaderSection_t *>(o_pBuffer);
+ memset( p, 0, sizeof( *p ));
+
+ // Get the ErrlSctnHdr to flatten its data first.
+ l_cb = iv_header.flatten( &p->sectionheader, i_cbBuffer );
+ if( 0 == l_cb )
+ {
+ // Rare.
+ TRACFCOMP(g_trac_errl,"ErrlPrvt::flatten: header.flatten problem");
+ break;
+ }
+
+ // Set the ErrlPrvt instance data items.
+ p->creationTime = iv_created;
+ p->commitTime = iv_committed;
+ p->creatorId = iv_cid;
+ p->sectionCount = iv_sctns;
+ p->plid = iv_plid;
+
+ // TODO In the future, eid may be different than PLID
+ p->eid = iv_plid;
+
+ // return amount of bytes flattened
+ l_rc = iv_header.iv_slen;
+ }
+ while( 0 );
+
+ return l_rc;
+}
+
+
+
+} // namespace
diff --git a/src/usr/errl/errlsctn.C b/src/usr/errl/errlsctn.C
index d82a6869f..14e815bf5 100644
--- a/src/usr/errl/errlsctn.C
+++ b/src/usr/errl/errlsctn.C
@@ -23,15 +23,19 @@
/**
* @file errlsctn.C
*
- * @brief Implementation of ErrlSctn class
+ * @brief Implementation of ErrlSctn class.
*/
/*****************************************************************************/
// I n c l u d e s
/*****************************************************************************/
-#include <trace/interface.H>
-#include "errlsctn.H"
#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+
namespace ERRORLOG
{
@@ -41,110 +45,24 @@ extern trace_desc_t* g_trac_errl;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-ErrlSctn::ErrlSctn(const compId_t i_compId,
- const uint8_t i_sctnVer,
- const uint8_t i_subSect)
-:iv_ErrlSctnHdr(i_compId, i_sctnVer, i_subSect),iv_pData(NULL),iv_cbData(0)
-{
-}
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-ErrlSctn::~ErrlSctn()
+ErrlSctn::ErrlSctn( const uint16_t i_sid,
+ const uint16_t i_slen,
+ const uint8_t i_ver,
+ const uint8_t i_sst,
+ const compId_t i_compId ) :
+ iv_header( i_sid, i_slen, i_ver, i_sst, i_compId )
{
- delete iv_pData;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-uint64_t ErrlSctn::addData(const void *i_data, const uint64_t i_size)
-{
- uint64_t l_rc = 0;
-
- // Expected new size of user data.
- uint64_t l_newsize = iv_cbData + i_size;
-
- // Resize memory block
- iv_pData = static_cast<uint8_t*>(realloc(iv_pData, l_newsize));
- // Make sure reallocate call succeeds
- if (iv_pData != NULL)
- {
- // Copy new data to new area, past existing data (if any)
- memcpy( iv_pData+iv_cbData, i_data, i_size );
-
- // Save new size of the user-provided data.
- l_rc = iv_cbData = l_newsize;
- }
- else
- {
- TRACFCOMP( g_trac_errl,
- "ErrlFFDC::addData() - Reallocate memory failed!");
- }
- return l_rc;
}
-////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////
-uint64_t ErrlSctn::flattenedSize()
-{
- return sizeof(section_header_t) + iv_cbData;
-}
-
-////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////
-uint64_t ErrlSctn::flatten( void* io_pBuffer, uint64_t i_bufsize )
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+ErrlSctn::~ErrlSctn()
{
- uint64_t l_flatCount = 0;
-
- do
- {
- l_flatCount = flattenedSize();
- if( i_bufsize < l_flatCount )
- {
- // error path, return 0
- TRACFCOMP( g_trac_errl, "Invalid buffer size" );
- l_flatCount = 0;
- break;
- }
- // CPPASSERT() makes an assertion to the compiler, and if the
- // expression is false, the compile will end in error. If these
- // compiler asserts should fail, then the packed structures
- // defined in errl/errltypes.H will need to be adjusted.
- CPPASSERT( 2 == sizeof(iv_ErrlSctnHdr.iv_compId));
- CPPASSERT( 1 == sizeof(iv_ErrlSctnHdr.iv_sctnVer));
- CPPASSERT( 1 == sizeof(iv_ErrlSctnHdr.iv_subSect));
- CPPASSERT( 0 == sizeof( section_header_t ) % sizeof( uint32_t ));
-
-
- // Marshall the data into a section_header_t
- section_header_t l_Header;
- memset( &l_Header, 0, sizeof( l_Header ));
- l_Header.cbHeader = sizeof( l_Header );
- l_Header.cbSection = iv_cbData;
- l_Header.compId = iv_ErrlSctnHdr.iv_compId;
- l_Header.sctnVer = iv_ErrlSctnHdr.iv_sctnVer;
- l_Header.subSect = iv_ErrlSctnHdr.iv_subSect;
-
-
- // Write data to caller's memory.
- char * l_pchar = static_cast<char *>(io_pBuffer);
- memcpy( l_pchar, &l_Header, sizeof( l_Header ));
- l_pchar += sizeof( l_Header );
-
- // Write any user-defined data.
- if( iv_cbData )
- {
- memcpy( l_pchar, iv_pData, iv_cbData );
- }
- }
- while( 0 );
-
- return l_flatCount;
}
-
} // end namespace
diff --git a/src/usr/errl/errlsctnhdr.C b/src/usr/errl/errlsctnhdr.C
index 175476e34..dbdefa26a 100644
--- a/src/usr/errl/errlsctnhdr.C
+++ b/src/usr/errl/errlsctnhdr.C
@@ -23,31 +23,36 @@
/**
* @file errlsctnhdr.C
*
- * @brief Abstract header of all error log's sections
- *
- * This header file contains the definition of common section header in
- * each error log's section
+ * @brief Header data for any/all sections in an error log.
*
*/
-/*****************************************************************************/
-// I n c l u d e s
-/*****************************************************************************/
-#include "errlsctnhdr.H"
+
+
+
+#include <assert.h>
+#include <errl/errlsctnhdr.H>
namespace ERRORLOG
{
+extern trace_desc_t* g_trac_errl;
+
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-ErrlSctnHdr::ErrlSctnHdr(const compId_t i_compId,
- const uint8_t i_sctnVer,
- const uint8_t i_subSect)
-:iv_compId(i_compId),
-iv_sctnVer(i_sctnVer),
-iv_subSect(i_subSect)
+ErrlSctnHdr::ErrlSctnHdr( const uint16_t i_sid,
+ const uint16_t i_slen,
+ const uint8_t i_ver,
+ const uint8_t i_sst,
+ const compId_t i_compId ) :
+iv_sid( i_sid ),
+iv_ver( i_ver ),
+iv_sst( i_sst ),
+iv_compId(i_compId)
{
-
+ // Caller/owner of this instance has provided the slen (section length)
+ // for its data, but does not include the size of its ErrlSctnHdr.
+ iv_slen = i_slen + flatSize();
}
@@ -58,4 +63,47 @@ ErrlSctnHdr::~ErrlSctnHdr()
}
+
+///////////////////////////////////////////////////////////////////////////////
+// Flatten the data to the output pointer given as PEL as defined in
+// eCLipz and P7 Platform Event Log and SRC PLDD mcdoc 1675
+
+uint64_t ErrlSctnHdr::flatten( void * o_pBuffer, const uint64_t i_cbBuffer )
+{
+ uint64_t l_rc = 0;
+
+ // Compile-time assertions
+ CPPASSERT( 8 == sizeof( pelSectionHeader_t ));
+ CPPASSERT( 2 == sizeof( iv_sid ));
+ CPPASSERT( 2 == sizeof( iv_slen ));
+ CPPASSERT( 1 == sizeof( iv_ver ));
+ CPPASSERT( 1 == sizeof( iv_sst ));
+ CPPASSERT( 2 == sizeof( iv_compId ));
+
+ if( i_cbBuffer >= sizeof( pelSectionHeader_t ))
+ {
+ // See errltypes.H for pelSectionHeader_t. Flatten to
+ // local, temporary l_header because it will be word aligned,
+ // whereas caller's output address is not guaranteed to be.
+ pelSectionHeader_t l_header;
+
+ l_header.sid = iv_sid;
+ l_header.len = iv_slen;
+ l_header.ver = iv_ver;
+ l_header.sst = iv_sst;
+ l_header.compId = iv_compId;
+
+ // memcpy out to callers buffer
+ memcpy( o_pBuffer, &l_header, sizeof( pelSectionHeader_t ));
+ l_rc = sizeof( pelSectionHeader_t );
+ }
+ else
+ {
+ TRACFCOMP( g_trac_errl, "ErrlSctnHdr::flatten: buffer too small");
+ }
+
+ return l_rc;
+};
+
+
} // End namespace
diff --git a/src/usr/errl/errlsctnhdr.H b/src/usr/errl/errlsctnhdr.H
deleted file mode 100644
index 55e9cf295..000000000
--- a/src/usr/errl/errlsctnhdr.H
+++ /dev/null
@@ -1,102 +0,0 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/usr/errl/errlsctnhdr.H $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
-#ifndef ERRLSCTNHDR_H
-#define ERRLSCTNHDR_H
-/**
- * @file errlsctnhdr.H
- *
- * @brief This file contain the class that abstracts the header of
- * an error log section.
- *
- */
-
-/*****************************************************************************/
-// I n c l u d e s
-/*****************************************************************************/
-#include <stdint.h>
-#include <stdlib.h>
-#include <errl/errltypes.H>
-#include <hbotcompid.H>
-#include <string.h>
-
-namespace ERRORLOG
-{
-
-/**
- * @brief This class abstracts a header of a section in an error log object
- */
-class ErrlSctnHdr
-{
- // ErrlSctn accesses ErrlSctnHdr directly.
- friend class ErrlSctn;
-
- /**
- * @brief Section header constructor
- *
- * @param[in] i_compId Component Id of the caller
- * @param[in] i_sctnVer A user supplied identifier which
- * classifies the data in the section
- * @param[in] i_subSect A user supplied sub section identifier
- * which classifies the data. This in
- * conjunction with the version can be used
- * to decode the data.
- * @return void
- */
- ErrlSctnHdr(const compId_t i_compId,
- const uint8_t i_sctnVer,
- const uint8_t i_subSect);
-
- /**
- * @brief Default destructor
- *
- * @return void
- */
- ~ErrlSctnHdr();
-
- //@todo - Need to add serialization interfaces for ErrlSctnHdr object.
- // Serialization method (boost serialization?) for HostBoot
- // is currently not yet determined.
- // Note: stream is currently not supported
-
-
-
-private:
-
- /**
- * @brief Disabled copy constructor and assignment operator
- */
- ErrlSctnHdr(const ErrlSctnHdr& i_right);
- ErrlSctnHdr& operator=(const ErrlSctnHdr& i_right);
-
- // Data
- // Can/will be accessed by friend class ErrlSctn
- compId_t iv_compId;
- uint8_t iv_sctnVer;
- uint8_t iv_subSect;
-
-};
-
-} // End namespace
-
-#endif //ERRLSCTNHDR_H
-
diff --git a/src/usr/errl/errlsrc.C b/src/usr/errl/errlsrc.C
new file mode 100644
index 000000000..3c50aed25
--- /dev/null
+++ b/src/usr/errl/errlsrc.C
@@ -0,0 +1,164 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/errl/errlsrc.C $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+/**
+ * @file errlsrc.C
+ *
+ * @brief Manage the data items that make up the 'PS' section in an
+ * error log PEL. PS stands for Primary System Reference Code, or SRC.
+ * ErrlSrc is a derivation of ErrlSctn.
+ *
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <hbotcompid.H>
+#include <errl/errlentry.H>
+
+
+
+namespace ERRORLOG
+{
+
+
+extern trace_desc_t* g_trac_errl;
+
+
+
+//**************************************************************************
+// constructor
+
+
+ErrlSrc::ErrlSrc( srcType_t i_srcType,
+ uint8_t i_modId,
+ uint16_t i_reasonCode,
+ uint64_t i_user1,
+ uint64_t i_user2 ) :
+
+ ErrlSctn( ERRL_SID_PRIMARY_SRC,
+ ErrlSrc::SLEN,
+ ErrlSrc::VER,
+ ErrlSrc::SST,
+ 0 ), // Component ID zero for now.
+ iv_srcType( i_srcType ),
+ iv_modId( i_modId ),
+ iv_reasonCode( i_reasonCode ),
+ iv_ssid( EPUB_FIRMWARE_SUBSYS ),
+ iv_user1( i_user1 ),
+ iv_user2( i_user2 )
+{
+
+
+}
+
+
+//****************************************************************************
+//
+
+ErrlSrc::~ErrlSrc()
+{
+
+}
+
+
+
+//**************************************************************************
+// Flatten the PS primary SRC data to a minimum standard 72-byte structure.
+// Page numbers refer to Platform Event Log and SRC PLDD
+// https://mcdoc.boeblingen.de.ibm.com/out/out.ViewDocument.php?documentid=1675
+// Version 0.8 (markup). See also src/include/usr/errl/errltypes.H
+// for the typedef pelSRCSection_t.
+
+uint64_t ErrlSrc::flatten( void * o_pBuffer, const uint64_t i_cbBuffer )
+{
+ uint64_t l_rc = 0;
+
+ do
+ {
+ if( i_cbBuffer < flatSize() )
+ {
+ TRACFCOMP( g_trac_errl, "ErrlSrc::flatten: buffer too small");
+ break;
+ }
+
+ pelSRCSection_t * psrc = static_cast<pelSRCSection_t *>(o_pBuffer);
+
+ // memset zero up to the char array.
+ memset( psrc, 0, flatSize() - sizeof( psrc->srcString ));
+
+ // memset spaces into the char array
+ memset( psrc->srcString, ' ', sizeof( psrc->srcString ));
+
+ l_rc = iv_header.flatten( o_pBuffer, i_cbBuffer );
+ if( 0 == l_rc )
+ {
+ // Rare.
+ TRACFCOMP( g_trac_errl, "ErrlSrc::flatten: header flatten error");
+ break;
+ }
+
+
+ // Place data into the flat structure.
+ psrc->ver = ErrlSrc::SRCVER; // 2; See p.69
+ // psrc->flags = 0; // p.69
+ psrc->wordcount = ErrlSrc::WORDCOUNT; // 9; See p.69
+
+ // TODO FSP firmware puts zero here. Cheat and put reasonCode here.
+ // Makes for easier retrieval than teasing it out of the SRC
+ // ascii string. (Am I missing something?)
+ psrc->reserved1 = iv_reasonCode;
+
+ CPPASSERT( ErrlSrc::SLEN == sizeof(pelSRCSection_t)-iv_header.flatSize());
+ psrc->srcLength = ErrlSrc::SLEN;
+
+ // SRC format p.71 of PEL reference.
+ psrc->word2 = 0xF0;
+
+ // Stash the Hostboot module id into hex word 3
+ psrc->moduleId = iv_modId; // p.71
+
+ // Stash the Hostboot long long words into the hexwords of the SRC.
+ psrc->word6 = iv_user1; // spans 6-7
+ psrc->word8 = iv_user2; // spans 8-9
+
+ // Build the char string for the SRC.
+ uint32_t l_u32;
+ l_u32 = (iv_srcType<< 24)|(iv_ssid<<16)| iv_reasonCode;
+
+ char l_tmpString[ 20 ];
+ uint64_t cb = sprintf( l_tmpString, "%X", l_u32 );
+ memcpy( psrc->srcString, l_tmpString, cb );
+
+ l_rc = flatSize();
+ }
+ while( 0 );
+
+ return l_rc;
+}
+
+
+} // namespace
+
+
+
diff --git a/src/usr/errl/errlud.C b/src/usr/errl/errlud.C
new file mode 100644
index 000000000..f7b51ebd2
--- /dev/null
+++ b/src/usr/errl/errlud.C
@@ -0,0 +1,168 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/errl/errlud.C $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+/**
+ * @file errlud.C
+ *
+ * @brief <Brief Description of this file>
+ *
+ * <Detailed description of what this file does, functions it includes,
+ * etc,>
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <hbotcompid.H>
+#include <errl/errlentry.H>
+
+
+
+namespace ERRORLOG
+{
+
+
+extern trace_desc_t* g_trac_errl;
+
+
+//***************************************************************************
+// Constructor
+
+ErrlUD::ErrlUD(
+ const void * i_data,
+ uint64_t i_size,
+ compId_t i_compid,
+ uint8_t i_ver,
+ uint8_t i_sst ) :
+
+ ErrlSctn( ERRL_SID_USER_DEFINED, 0, i_ver, i_sst, i_compid ),
+ iv_pData( NULL ),
+ iv_Size( 0 )
+{
+ uint64_t l_cb;
+
+ l_cb = addData( i_data, i_size );
+ if( 0 == l_cb )
+ {
+ // Rare.
+ TRACFCOMP( g_trac_errl, "ErrlUD::ErrlUD(): addData rets error");
+ }
+}
+
+
+
+
+
+/*****************************************************************************/
+// Destructor
+
+ErrlUD::~ErrlUD()
+{
+ if( iv_pData ) free( iv_pData );
+}
+
+
+
+
+
+/*****************************************************************************/
+// Add data. This works the first time when there is no data and works for
+// subsequent times when you want to append data. Return [new] size of buffer.
+
+uint64_t ErrlUD::addData(const void *i_data, const uint64_t i_size)
+{
+ uint64_t l_rc = 0;
+
+ // Expected new size of user data.
+ uint64_t l_newsize = iv_Size + i_size;
+
+ // Resize memory block
+ iv_pData = static_cast<uint8_t*>(realloc(iv_pData, l_newsize));
+
+ // Make sure reallocate call succeeds
+ if (iv_pData != NULL)
+ {
+ // Copy new data to new area, past existing data (if any)
+ memcpy( iv_pData + iv_Size, i_data, i_size );
+
+ // Save new size of the user-provided data. This will also
+ // be what this method returns.
+ iv_Size = l_newsize;
+ l_rc = iv_Size;
+
+ // Tell the PEL header what is the new length.
+ iv_header.iv_slen = iv_header.flatSize() + iv_Size;
+ }
+ else
+ {
+ TRACFCOMP( g_trac_errl,
+ "ErrlUD::addData() - Reallocate memory failed!");
+ }
+ return l_rc;
+}
+
+
+
+/*****************************************************************************/
+// Data Export size
+
+uint64_t ErrlUD::flatSize()
+{
+ uint64_t l_rc = 0;
+
+ l_rc = iv_header.flatSize() + iv_Size;
+
+ return l_rc;
+}
+
+
+/*****************************************************************************/
+// Data Export. Return how many bytes were written or zero on error.
+
+uint64_t ErrlUD::flatten( void * o_pBuffer, const uint64_t i_cbBuffer )
+{
+ uint64_t l_rc = 0;
+ uint64_t cb = 0;
+ uint8_t * pBuffer = static_cast<uint8_t *>(o_pBuffer);
+
+ if ( i_cbBuffer >= this->flatSize() )
+ {
+ // flatten the section header
+ cb = iv_header.flatten( pBuffer, i_cbBuffer );
+ pBuffer += cb;
+
+ // followed by the user data
+ memcpy( pBuffer, iv_pData, iv_Size );
+
+ // return how many bytes were flattened
+ l_rc = iv_Size + cb;
+ }
+ else
+ {
+ TRACFCOMP( g_trac_errl, "ErrlUD::flatten: buffer too small");
+ }
+
+
+ return l_rc;
+}
+
+} //namespace
diff --git a/src/usr/errl/errluh.C b/src/usr/errl/errluh.C
new file mode 100644
index 000000000..cdaaa1619
--- /dev/null
+++ b/src/usr/errl/errluh.C
@@ -0,0 +1,114 @@
+// IBM_PROLOG_BEGIN_TAG
+// This is an automatically generated prolog.
+//
+// $Source: src/usr/errl/errluh.C $
+//
+// IBM CONFIDENTIAL
+//
+// COPYRIGHT International Business Machines Corp. 2011
+//
+// p1
+//
+// Object Code Only (OCO) source materials
+// Licensed Internal Code Source Materials
+// IBM HostBoot Licensed Internal Code
+//
+// The source code for this program is not published or other-
+// wise divested of its trade secrets, irrespective of what has
+// been deposited with the U.S. Copyright Office.
+//
+// Origin: 30
+//
+// IBM_PROLOG_END
+/**
+ * @file errluh.C
+ *
+ * @brief Code to manage the contents of the user header
+ * section of an error log.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <hbotcompid.H>
+#include <errl/errlentry.H>
+
+
+
+
+namespace ERRORLOG
+{
+
+
+extern trace_desc_t* g_trac_errl;
+
+
+/*****************************************************************************/
+// Constructor
+
+ErrlUH::ErrlUH( errlSeverity_t i_sev ) :
+ iv_header( ERRL_SID_USER_HEADER,
+ ErrlUH::SLEN,
+ ErrlUH::VER,
+ ErrlUH::SST,
+ 0), // Component ID is zero until commit time
+ iv_severity( i_sev ),
+ iv_etype( ERRL_ETYPE_NOT_APPLICABLE ),
+ iv_ssid( EPUB_FIRMWARE_SUBSYS ), // 0x80 here yields SRC B180xxxx
+ iv_domain( ERRL_DOMAIN_DEFAULT ),
+ iv_vector( ERRL_VECTOR_DEFAULT ),
+ iv_actions( ERRL_ACTION_NONE ),
+ iv_scope( ERRL_SCOPE_PLATFORM )
+{
+
+}
+
+
+
+/***************************************************************************/
+// Data Export
+
+uint64_t ErrlUH::flatten( void * io_pBuffer, const uint64_t i_cbBuffer )
+{
+ uint64_t l_rc = 0;
+
+
+ // compile-type assertion
+ CPPASSERT( 24 == sizeof( pelUserHeaderSection_t ));
+
+
+ if( i_cbBuffer >= iv_header.iv_slen )
+ {
+ pelUserHeaderSection_t * p;
+ p = static_cast<pelUserHeaderSection_t*>(io_pBuffer);
+ memset( p, 0, sizeof(*p));
+
+ // Get the ErrlSctnHdr to flatten its data first.
+ iv_header.flatten( &p->sectionheader, i_cbBuffer );
+
+ // Set the ErrlUH instance data items in to the
+ // flat user header PEL struct.
+ p->ssid = iv_ssid;
+ p->scope = iv_scope;
+ p->sev = iv_severity;
+ p->etype = iv_etype;
+ p->domain = iv_domain;
+ p->vector = iv_vector;
+ p->actions = iv_actions;
+
+ // Return count of bytes flattened
+ l_rc = iv_header.iv_slen;
+ }
+ else
+ {
+ TRACFCOMP( g_trac_errl, "ErrlUH::flatten: buffer too small" );
+ }
+ return l_rc;
+}
+
+
+
+
+
+
+} // namespace
diff --git a/src/usr/errl/makefile b/src/usr/errl/makefile
index 6c53192e7..924f34623 100644
--- a/src/usr/errl/makefile
+++ b/src/usr/errl/makefile
@@ -23,7 +23,7 @@
ROOTPATH = ../../..
MODULE = errl
-OBJS = errlentry.o errlmanager.o errlsctn.o errlffdc.o errlsctnhdr.o
+OBJS = errlentry.o errlmanager.o errlsctn.o errlsctnhdr.o errlprvt.o errluh.o errlud.o errlsrc.o
SUBDIRS = test.d parser.d
diff --git a/src/usr/errl/parser/errlparser.C b/src/usr/errl/parser/errlparser.C
index 5880e6db2..ccf9bf915 100644
--- a/src/usr/errl/parser/errlparser.C
+++ b/src/usr/errl/parser/errlparser.C
@@ -20,11 +20,33 @@
// Origin: 30
//
// IBM_PROLOG_END
+
+
/**
* @file errlparser.C
*
- * @brief Parse and display committed error logs. Enter
- * errlparser ? (or -? or -h or --help) to print help.
+ * @brief Builds a program to display committed Hostboot error logs.
+ * Enter errlparser ? (or -? or -h or --help) to print help.
+ * This program can be run standalone using a Simics
+ * L3 memory image and the HB syms file, however it is more likely
+ * spawned as "simcis> hb-errl" from the Hostboot/Simics python
+ * script.
+ *
+ * This program spawns the FSP x86 version of errl and fsp-trace
+ * which may or may not be in your $PATH. Candidates are:
+ *
+ * Classic FSP errl:
+ * /esw/fips730/Builds/b0829a_1130.730/obj/x86.nfp/errl/nfp/tool/errl
+ *
+ * Or this version in Monte's sandbox which is more Hostboot aware:
+ * /gsa/ausgsa/home/c/o/copelanm/public/bin/errl
+ *
+ * Building Blocks version of fsp-trace:
+ * /opt/mcp/shared/fr_DEV-37/opt/fsp/usr/bin/fsp-trace
+ *
+ * Camvan has a solution for PATHing to fsp-trace when in Simics.
+ * TODO Will need a copy of FSP x86 errl too in the near future.
+ *
*/
@@ -37,32 +59,41 @@
#include <errno.h>
#include <assert.h>
#include <string>
+#include <vector>
using namespace std;
#include <errl/errltypes.H>
#include <hbotcompid.H>
+
+
+// Include the file that was generated by scanforsrcs.pl
#include <hostBootSrcParse.H>
+
+
using namespace ERRORLOG;
+
#define USAGE "\
Usage:\n\
\n\
-errlparser [-i] <imagefile> [[-s] <symsfile>] [-l | -d [<logid>|all]] [-v]\n\
+errlparser [-i]<image> [[-s]<syms>] [-l|-d[<logid>|all]] [-t <stringfile>]\n\
\n\
Arguments:\n\
- <imagefile> data file name\n\
- <symsfile> symbols file name\n\
+ <image> data file name\n\
+ <syms> symbols file name\n\
-l summarize all error logs (default)\n\
-d id print detail from specific error log\n\
- -s name explicitly name the symbols file\n\
-i name explicitly name the image file\n\
+ -s name explicitly name the symbols file\n\
+ -t name name the hbotStringFile\n\
-v verbose output to stdout\n\
\n\
Sample command lines:\n\
errlparser image.bin hbicore.syms # list logs from a full L3 image\n\
- errlparser image.bin hbicore.syms -d 1 # print detail about log 1\n\
+ errlparser image.bin hbicore.syms -d 1 # display log 1\n\
+ errlparser image.bin hbicore.syms -d 1 -t hbotStringFile # display traces\n\
errlparser buffer.bin # list logs from pre-extracted storage buffer\n\
errlparser buffer.bin -d 1 # detail log 1 from pre-extracted storage buffer\n\
\n\
@@ -74,9 +105,13 @@ Remarks:\n\
[] '-s' is optional if the symbols file name contains 'syms'\n\
[] '-i' can be optional in most cases\n\
\n\
+Developer switches:\n\
+ -p -o <dirname> Extract all as PEL binaries to output <dirname>\n\
Contact: Monte Copeland\n\
"
+
+
//------------------------------------------------------------------------
// Stop the program with a message. This message is often USAGE. Since
// this program will be spawned from traceHB.py, I think we're better
@@ -84,6 +119,7 @@ Contact: Monte Copeland\n\
// think Simics is piping stderr to its console.
void halt( const char * msg )
{
+ // stdout out because Simics does not appear to display stderr (?)
fprintf( stdout, "%s", msg );
// exit the process with a non-zero process exit level.
@@ -111,6 +147,8 @@ ERRLCOMPNAME_t g_errlcompnames[] = {
#include <comps.C>
};
+
+//-------------------------------------------------------------
// Given a reason code which has a comp id mangled into
// it, return a char* to the component name. Return
// null if not found, which printf seems to handle
@@ -133,157 +171,110 @@ const char * FindComp( uint16_t reasoncode )
-//------------------------------------------------------------
-// Print a hex dump of the input buffer to the output file
-// given, probably stdout.
-int FormatBytes( FILE * f, char * pchInput, int count, int indent )
+//-------------------------------------------------------------
+// endian switch a uint64
+uint64_t ntohll( uint64_t i )
{
- char szChars[ 80 ];
- char szHex[ 80 ];
- char szOffset[ 64 ];
- char szWork[ 256 ];
- int i;
- unsigned int ul;
- char * pch;
- char * pchLine;
- int cb;
- char * pszIndent = NULL;
-
-
-
- pszIndent = static_cast<char*>(malloc( indent+1 ));
- memset( pszIndent, 0, indent+1 );
- memset( pszIndent, ' ', indent );
-
-
-
- pchLine = pchInput;
-
-
- while( pchLine < pchInput + count )
- {
- /* current offset */
- ul = pchLine - pchInput;
-
- sprintf( szOffset, "%08X", ul );
-
- memset( szHex, ' ', sizeof( szHex ));
- pch = szHex;
-
- cb = ((pchInput+count)-pchLine) > 16 ? 16 : ((pchInput+count)-pchLine);
-
- for( i = 0; i < cb; i++ )
- {
- ul = (unsigned char) pchLine[ i ];
-
- sprintf( szWork, "%02x", ul );
- memcpy( pch, szWork, 2 );
+ uint64_t hi;
+ uint64_t lo;
+ uint32_t * pword = reinterpret_cast<uint32_t*>(&i);
- pch += 3;
- }
+ hi = ntohl( *pword );
+ lo = ntohl( *(pword+1) );
- szHex[ 23 ] = '-';
- szHex[ 48 ] = 0;
+ return (hi<<32)|lo;
+}
- memset( szChars, 0, sizeof( szChars ));
- for( i = 0; i < cb; i++ )
- {
- szChars[i] = '.';
- int t = pchLine[i];
- if( t > 31 )
- {
- szChars[i] = pchLine[ i ];
- }
- }
- sprintf( szWork, "%s %s %s", szOffset, szHex, szChars );
- fprintf( f, "%s%s\n", pszIndent, szWork );
- fflush( f );
- pchLine += 16;
- }
- return 0;
+//-------------------------------------------------------------
+// endian stuff, convert a errl storage marker in place
+marker_t* ConvertMarker( marker_t* p)
+{
+ p->offsetNext = ntohl( p->offsetNext );
+ p->length = ntohl( p->length );
+ return p;
}
-
//-------------------------------------------------------------
-// endian stuff
-section_header_t* ConvertSectionHeader( section_header_t* p)
+// endian stuff, convert the data stored at the beginning of the
+// errl storage buffer
+storage_header_t * ConvertStorageHeader( storage_header_t * p )
{
- p->cbHeader = ntohl( p->cbHeader );
- p->cbSection = ntohl( p->cbSection );
- p->compId = ntohs( p->compId );
- // sctnVer is byte long
- // subSect is byte long
+ p->cbStorage = ntohl( p->cbStorage );
+ p->cInserted = ntohl( p->cInserted );
+ p->offsetMarker = ntohl( p->offsetMarker );
+ p->offsetStart = ntohl( p->offsetStart );
return p;
}
-
//-------------------------------------------------------------
-// endian stuff
-marker_t* ConvertMarker( marker_t* p)
+// endian stuff,convert in place, return a pointer to what
+// you passed in. PEL is made up of multiple sections, each
+// one starting with a header that has these 8 bytes.
+pelSectionHeader_t * ConvertPELSectionHeader( pelSectionHeader_t * p )
{
- p->offsetNext = ntohl( p->offsetNext );
- p->length = ntohl( p->length );
+ p->sid = ntohs( p->sid );
+ p->len = ntohs( p->len );
+ // byte: p->ver
+ // byte: p->sst
+ p->compId = ntohs( p->compId );
return p;
}
-
//-------------------------------------------------------------
-// endian switch a uint64
-uint64_t ntohll( uint64_t i )
+// endian stuff, convert in place. This converts the first section
+// encountered in PEL, the PH section (private header).
+pelPrivateHeaderSection_t* ConvertPrivateHeader(pelPrivateHeaderSection_t* p)
{
- uint64_t hi;
- uint64_t lo;
- uint32_t * pword = reinterpret_cast<uint32_t*>(&i);
-
- hi = ntohl( *pword );
- lo = ntohl( *(pword+1) );
-
- return (hi<<32)|lo;
+ ConvertPELSectionHeader( &p->sectionheader );
+ p->creationTime = ntohll( p->creationTime );
+ p->commitTime = ntohll( p->commitTime );
+ p->creatorImplementation = ntohll( p->creatorImplementation );
+ p->plid = ntohl( p->plid );
+ p->eid = ntohl( p->eid );
+ return p;
}
//-------------------------------------------------------------
-// endian stuff
-errl_header_t* ConvertErrlHeader( errl_header_t* p )
+// endian stuff, convert in place. Convert the 2nd section in PEL,
+// the UH (user header).
+pelUserHeaderSection_t * ConvertUserHeader( pelUserHeaderSection_t * p )
{
- p->cbytes = ntohl( p->cbytes );
- p->csections = ntohl( p->csections );
- p->reasonCode = ntohs( p->reasonCode );
- // p->modId is a byte
- // p->sev is a byte
- // p->eventType is a byte
- // p->subSys is a byte
- // p->srcType is a byte
- p->termState = ntohl( p->termState );
- p->logId = ntohl( p->logId );
- p->user1 = ntohll( p->user1 );
- p->user2 = ntohll( p->user2 );
- p->CreationTime = ntohll( p->CreationTime );
+ ConvertPELSectionHeader( &p->sectionheader );
+ // mostly byte sized stuff
+ p->actions = ntohs( p->actions );
return p;
}
-
//-------------------------------------------------------------
-// endian stuff
-storage_header_t * ConvertStorageHeader( storage_header_t * p )
+// endian stuff, convert in place. The PS (primary SRC) section
+// in PEL is the 3rd section.
+pelSRCSection_t * ConvertSRC( pelSRCSection_t * p )
{
- p->cbStorage = ntohl( p->cbStorage );
- p->cInserted = ntohl( p->cInserted );
- p->offsetMarker = ntohl( p->offsetMarker );
- p->offsetStart = ntohl( p->offsetStart );
+ ConvertPELSectionHeader( &p->sectionheader );
+ // mostly byte sized stuff
+ p->srcLength = ntohs( p->srcLength );
+ p->reserved1 = ntohs( p->reserved1 );
+ p->word2 = ntohl( p->word2 );
+ p->word3 = ntohs( p->word3 );
+ p->word4 = ntohl( p->word4 );
+ p->word5 = ntohl( p->word5 );
+ p->word6 = ntohll( p->word6 );
+ p->word8 = ntohll( p->word8 );
return p;
}
+
//-----------------------------------------------------------------------
// Given the binary image file name, return the errl storage part of the file.
// Caller must endian convert anything/everything in the output buffer.
@@ -418,6 +409,7 @@ uint32_t FindSymbol( char * pszSymbolFile, const char * pszSearch )
pch = strstr( szWork, pszSearch );
if( pch )
{
+ // tease out the address for this symbol
pszAddr = szWork + 2;
pch = strchr( pszAddr, ',' );
assert( pch );
@@ -433,6 +425,7 @@ uint32_t FindSymbol( char * pszSymbolFile, const char * pszSearch )
exit(2);
}
+ // Convert ascii hex representation of address to a unsigned long
int c = sscanf( pszAddr, "%x", &ulAddr );
if( 1 != c )
{
@@ -446,103 +439,111 @@ uint32_t FindSymbol( char * pszSymbolFile, const char * pszSearch )
-// --------------------------------------------------------------------------
-// Print a summary of the error log, no user-defined data nor detail.
-// perrlog is already endian converted
+//-----------------------------------------------------------------------------
+// Output a vector of endian-converted PEL sections, without altering the caller's
+// pchNativePEL input buffer. The vector will have pointers to PEL section
+// headers, and the user of the vector contents will have to cast according to
+// pelSectionHeader_t.sid (section id ).
-void PrintErrlSummary( errl_header_t * perrlog )
+bool ParseForPEL( char * i_pchNativePEL,
+ int i_cbPEL,
+ vector<pelSectionHeader_t*> &o_vector )
{
- // print headline
- // comp id sev rc mod evt u1 u2 csec
- printf( "%-7s %10s %4s %-6s %-4s %-4s %-18s %-18s %5s\n",
- "comp",
- "logid",
- "sev",
- "reason",
- "mod",
- "evnt",
- "user1",
- "user2",
- "csect" );
-
-
- // comp id sev reason mod event user1 user2 csec
- // code
- printf( "%-7s %10d 0x%02x 0x%04x 0x%02x 0x%02x 0x%016llx 0x%016llx %5d\n",
- FindComp( perrlog->reasonCode ),
- perrlog->logId,
- perrlog->sev,
- perrlog->reasonCode,
- perrlog->modId,
- perrlog->eventType,
- perrlog->user1,
- perrlog->user2,
- perrlog->csections // count of sections
- );
-}
-
+ // use pch to bump along through the PEL sections
+ char * pch = i_pchNativePEL;
-//---------------------------------------------------------------------------
-//
-//
-void PrintErrlDetail( errl_header_t * perrlog )
-{
+ while( pch < (i_pchNativePEL+i_cbPEL))
+ {
+ void * pvoid;
+ pelSectionHeader_t sectionHeader;
- // print the summary line
- PrintErrlSummary( perrlog );
+ // Convert a copy of just the PEL section header so I can look at the
+ // sid (section id/type) and the overall section length.
+ memcpy( &sectionHeader, pch, sizeof( pelSectionHeader_t ));
+ ConvertPELSectionHeader( &sectionHeader );
- // print the Errorlog tags
- printErrorTags( perrlog->reasonCode,
- perrlog->modId );
- // print sections if any
- if( perrlog->csections )
- {
- int i;
- section_header_t* psect;
+ // For each section, allocate space for it, endian convert the
+ // section, then insert into output vector.
+ switch( sectionHeader.sid ) {
+ case ERRL_SID_PRIVATE_HEADER:
+ {
+ pvoid = malloc(sectionHeader.len);
+ pelPrivateHeaderSection_t * p;
+ p = static_cast<pelPrivateHeaderSection_t*>(pvoid);
+ memcpy( p, pch, sectionHeader.len );
+ ConvertPrivateHeader( p );
+ o_vector.push_back( reinterpret_cast<pelSectionHeader_t*>(p) );
+ }
+ break;
+ case ERRL_SID_USER_HEADER:
+ {
+ pvoid = malloc(sectionHeader.len);
+ pelUserHeaderSection_t * p;
+ p = static_cast<pelUserHeaderSection_t*>(pvoid);
+ memcpy( p, pch, sectionHeader.len );
+ ConvertUserHeader( p );
+ o_vector.push_back( reinterpret_cast<pelSectionHeader_t*>(p) );
+ }
+ break;
+ case ERRL_SID_PRIMARY_SRC:
+ {
+ pvoid = malloc(sectionHeader.len);
+ pelSRCSection_t * p;
+ p = static_cast<pelSRCSection_t*>(pvoid);
+ memcpy( p, pch, sectionHeader.len );
+ ConvertSRC( p );
+ o_vector.push_back( reinterpret_cast<pelSectionHeader_t*>(p) );
+ }
+ break;
+ case ERRL_SID_USER_DEFINED:
+ {
+ pvoid = malloc(sectionHeader.len);
+ pelSectionHeader_t * p;
+ p = static_cast<pelSectionHeader_t*>(pvoid);
+ memcpy( p, pch, sectionHeader.len );
+ // Only converts the PEL section header, but none of the
+ // user-defined content. No way to know what's in there.
+ ConvertPELSectionHeader(p);
+ o_vector.push_back(p);
+ }
+ break;
+ default:
+ assert( 0 );
+ break;
+ }
- // first section header resides just past the errl_header_t
- psect = reinterpret_cast<section_header_t*>(perrlog+1);
+ pch += sectionHeader.len;
+ }
- // Endian convert it
- ConvertSectionHeader( psect );
+ return true;
+}
- i = 0;
- do
- {
- printf(
- "\nSection %d: %-8s len=0x%04x, ver=0x%04x, subsection=0x%04x\n",
- i,
- FindComp( psect->compId ),
- psect->cbSection,
- psect->sctnVer,
- psect->subSect
- );
- // The user-provided data resides just past the section header.
- char * pUserData = reinterpret_cast<char*>(psect+1);
- // Print a hex dump (for now) of the user-provided data.
- FormatBytes( stdout, pUserData, (int)psect->cbSection, 4 );
- i++;
- if( i >= perrlog->csections )
- {
- // Leave the loop, and do not ConvertSectionHeader().
- break;
- }
+//-----------------------------------------------------------------------------
+// Scan the vector of endian-converted PEL sections. Locate the target section
+// and return it. Return NULL if not found. Caller will have to cast
+// the returned section header pointer to the desired PEL section struct.
- // There's more; point to the next section.
- int cb = psect->cbHeader + psect->cbSection;
- char * p = (reinterpret_cast<char*>(psect)) + cb;
- psect = reinterpret_cast<section_header_t*>(p);
+pelSectionHeader_t * FindPELSection( unsigned int i_target,
+ vector<pelSectionHeader_t*> &o_vector )
+{
+ pelSectionHeader_t * p = NULL;
- // Endian convert it.
- ConvertSectionHeader( psect );
+ vector<pelSectionHeader_t*>::iterator it;
+ for( it = o_vector.begin(); it != o_vector.end(); it++ )
+ {
+ if( (*it)->sid == i_target )
+ {
+ p = *it;
+ break;
}
- while( 1 );
}
+
+ return p;
}
@@ -550,13 +551,25 @@ void PrintErrlDetail( errl_header_t * perrlog )
+
+
+
+
+
+
//-------------------------------------------------------------
int main( int argc, char *argv[] )
{
char * pch;
+ char * pchNativePEL;
+ const char * pszErrlTool = NULL;
char * pszImageFile = NULL;
char * pszSymbolFile = NULL;
+ char * pszStringFile = NULL;
+ char * pszOutputDir = NULL;
char szWork[ 1024 ];
+ char szTmpFilename[ 1024 ];
+ char szCommand[ 128 ];
unsigned char * puch;
char * pszSearch;
char * pszAddr = NULL;
@@ -579,13 +592,17 @@ int main( int argc, char *argv[] )
off_t offsetEnd;
int fVerbose = 0;
int fList = 1;
+ int fListHead = 0;
int fDetail = 0;
int fAll = 0;
int fFound = 0;
+ int fExtractPEL = 0;
+ void * pvoid;
+ struct stat statbuffer;
// build a =========== divider for printfing
- cb = 84;
+ cb = 78;
assert( cb < sizeof( szDivider ));
memset( szDivider, '=', sizeof( szDivider ));
szDivider[ cb ] = 0;
@@ -634,6 +651,41 @@ int main( int argc, char *argv[] )
}
pszImageFile = strdup( argv[i] );
}
+ else if( 0 == strcmp( "-o", argv[i] ))
+ {
+ i++;
+ if( i >= argc )
+ {
+ fprintf( stdout, "Provide -o <dirname>\n" );
+ exit( 2 );
+ }
+ pszOutputDir = strdup( argv[i] );
+ }
+ else if( 0 == strcmp( "-p", argv[i] ))
+ {
+ fExtractPEL = 1;
+ fList = 0;
+ fDetail = 0;
+ }
+ else if( 0 == strcmp( "-t", argv[i] ))
+ {
+ i++;
+ if( i >= argc )
+ {
+ fprintf( stdout, "Provide -t <string file>\n" );
+ exit( 2 );
+ }
+ pszStringFile = strdup( argv[i] );
+
+ // errl messes up ~ somehow, I thought bash
+ // would substitute this.
+ pch = strchr( pszStringFile, '~' );
+ if( pch )
+ {
+ printf( "Don't use ~ for file naming.\n" );
+ exit(2);
+ }
+ }
else if( 0 == strcmp( "-s", argv[i] ))
{
i++;
@@ -694,6 +746,56 @@ int main( int argc, char *argv[] )
halt( USAGE );
}
+ if(( fExtractPEL ) && ( NULL == pszOutputDir ))
+ {
+ printf( "Provide output dir for PEL extraction.\n" );
+ exit(1);
+ }
+
+ // TODO Need to put a copy of FSP x86 errl tool in the simics path.
+ // Try for Monte's sandbox copy, temporary for Sprint 6.
+ pszErrlTool = "/gsa/ausgsa/home/c/o/copelanm/public/bin/errl";
+
+ rc = stat( pszErrlTool, &statbuffer );
+ if( -1 == rc )
+ {
+ // Not found, so this one should be found for most users.
+ pszErrlTool =
+ "/esw/fips730/Builds/b0829a_1130.730/obj/x86.nfp/errl/nfp/tool/errl";
+
+ rc = stat( pszErrlTool, &statbuffer );
+ if( -1 == rc )
+ {
+ printf( "Unable to find a copy of errl, including %s.\n",
+ pszErrlTool );
+ exit(2);
+ }
+ }
+
+ if( fVerbose )
+ {
+ printf( "Using errl tool %s\n", pszErrlTool );
+ }
+
+
+ if( pszStringFile )
+ {
+ int fd = open( pszStringFile, O_RDONLY );
+ if( -1 == fd )
+ {
+ printf( "String file %s not found.\n", pszStringFile );
+ exit(2);
+ }
+ rc = fstat( fd, &statbuffer );
+ close(fd);
+ if( ( -1 == rc ) || !(S_ISREG(statbuffer.st_mode)))
+ {
+ printf( "String file %s is not valid.\n", pszStringFile );
+ exit(2);
+ }
+ }
+
+
if( pszSymbolFile )
{
@@ -717,7 +819,6 @@ int main( int argc, char *argv[] )
}
}
-
// Given the image file, read the portion that contains the
// error log storage buffer.
pchBuffer = ReadStorageBuffer( pszImageFile, ulAddr, cbBuffer );
@@ -770,7 +871,6 @@ int main( int argc, char *argv[] )
if( pMarker->offsetNext == 0 )
{
// This is the list-ending marker.
- printf( "%s\n", szDivider );
break;
}
@@ -778,24 +878,135 @@ int main( int argc, char *argv[] )
logcount++;
- // Flattened struct of an error log resides just past marker.
- errl_header_t* perr = reinterpret_cast<errl_header_t*>(pMarker+1);
- ConvertErrlHeader( perr );
+ // Flattened PEL of an error log resides just past marker
+ // for a length of pMarker->length. It is "native" meaning big endian.
+ pchNativePEL = reinterpret_cast<char*>(pMarker+1);
+
+ // Make a copy of PH that I can endian convert without screwing up
+ // the native one.
+ pvoid = malloc( pMarker->length );
+ pelPrivateHeaderSection_t * pPrivateHdr;
+ pPrivateHdr = static_cast<pelPrivateHeaderSection_t*>(pvoid);
+ memcpy( pPrivateHdr, pchNativePEL, pMarker->length );
+
+ // Convert the PEL private header copy to local endianness.
+ ConvertPrivateHeader( pPrivateHdr );
if( fList )
{
- // Just list the error log headers.
- printf( "%s\n", szDivider );
- PrintErrlSummary( perr );
+ // print a simple list of error log IDs
+ if( !fListHead )
+ {
+ // print a head line
+ printf( "%-16s %8s\n", "Component", "PLID" );
+ printf( "%s\n", szDivider );
+ fListHead = 1;
+ }
+ printf( "%-16s %8d\n",
+ FindComp(pPrivateHdr->sectionheader.compId),
+ pPrivateHdr->plid );
}
- else if(( fDetail ) && (( perr->logId == ulLogId ) || (fAll)))
+ else if(( fDetail ) && (( pPrivateHdr->plid == ulLogId ) || (fAll)))
{
- // Print the detail for the one error log.
- printf( "%s\n", szDivider );
- PrintErrlDetail( perr );
+ // Write the native PEL to a temporary file
+ // for x86 errl tool to display.
+ sprintf( szTmpFilename, "/tmp/pel%d.bin", pPrivateHdr->plid );
+
+ int fd = open( szTmpFilename, O_RDWR | O_CREAT , 0664 );
+ if( -1 == fd )
+ {
+ printf( "Unable to write %s. Exiting.\n", szTmpFilename );
+ exit(2);
+ }
+ cb = write( fd, pchNativePEL, pMarker->length );
+ assert( cb == pMarker->length );
+ close(fd);
+
+ // Spawn the FSP x86 errl tool to display
+ // the detail for this error log.
+ cb=sprintf(szCommand,"%s -d --file=%s",pszErrlTool,szTmpFilename);
+ if( pszStringFile )
+ {
+ sprintf( &szCommand[cb], " --trace=%s", pszStringFile );
+ }
+
+ // Run errl -d to display the error log.
+ system( szCommand );
+
+
+ // Build a vector containing pointers to each PEL section
+ // in the error log. On return, each section will be endian
+ // converted as much as possible. Do not alter the endianness
+ // of the native pel buffer, however.
+ vector<pelSectionHeader_t*> vectorPEL;
+ ParseForPEL( pchNativePEL, pMarker->length, vectorPEL );
+ assert( vectorPEL.size() );
+
+
+
+ // Print the tag detail gleaned from the code by
+ // the errl tag parser. That requires getting the reason
+ // code and module ID from the error log. They live in
+ // the Primary SRC section.
+ uint32_t l_reasonCode = 0;
+
+
+ // Find the PS section in the vector of PEL sections.
+ pelSectionHeader_t* pPELHead;
+ pPELHead = FindPELSection( ERRL_SID_PRIMARY_SRC, vectorPEL );
+ assert( pPELHead );
+
+ // Cast to Primary SRC section.
+ pelSRCSection_t * pSRCSection;
+ pSRCSection = reinterpret_cast<pelSRCSection_t*>(pPELHead);
+
+#if 0
+ // reasonCode has been "stringified" into the SRC string
+ pch = strchr( pSRCSection->srcString, ' ' );
+ assert( pch );
+ *pch = 0;
+ assert( 8 == strlen( pSRCSection->srcString));
+ sscanf( pSRCSection->srcString + 4, "%X", &l_reasonCode );
+#else
+ // I have cheated and put reasonCode here:
+ l_reasonCode = pSRCSection->reserved1;
+#endif
+
+ printf( "%-20s%s\n",
+ "Component",
+ FindComp(pPrivateHdr->sectionheader.compId));
+
+ // print the Errorlog tags from scanforsrcs.pl
+ printErrorTags( l_reasonCode, pSRCSection->moduleId );
+
+ // done with this tmp file
+ unlink( szTmpFilename );
+
+ // found at least one
fFound = 1;
}
+
+ if( fExtractPEL )
+ {
+ // Write the native PEL to a temporary file for debug later.
+ sprintf( szTmpFilename, "%s/pel%d.bin", pszOutputDir, pPrivateHdr->plid );
+
+ int fd = open( szTmpFilename, O_RDWR | O_CREAT , 0664 );
+ if( -1 == fd )
+ {
+ printf( "Unable to write %s. Exiting.\n", szTmpFilename );
+ exit(2);
+ }
+ cb = write( fd, pchNativePEL, pMarker->length );
+ assert( cb == pMarker->length );
+ close(fd);
+
+ printf( "Saved as %s\n", szTmpFilename );
+ }
+
+
+
// next marker/error log
pMarker = ConvertMarker( OFFSET2MARKER(pMarker->offsetNext) );
}
diff --git a/src/usr/errl/parser/makefile b/src/usr/errl/parser/makefile
index a48373c65..8b91e14ab 100644
--- a/src/usr/errl/parser/makefile
+++ b/src/usr/errl/parser/makefile
@@ -20,49 +20,59 @@
# Origin: 30
#
# IBM_PROLOG_END
+
+
# makefile for errlparser,
-# a 32-bit x86 linux binary suitable for running on GFW pool machines.
+# a 32-bit x86 linux binary suitable for running on GFW pool machines.
ROOTPATH=../../../..
-GENFILES = ${ROOTPATH}/obj/genfiles
+GENDIR = ${ROOTPATH}/obj/genfiles
+IMGDIR = ${ROOTPATH}/img
+
+OBJDIR = ${ROOTPATH}/obj/modules/errlparser
SRCPARSE_HEADER_TARGET = \
- ${GENFILES}/hostBootSrcParse.H
+ ${GENDIR}/hostBootSrcParse.H
-CC=g++ -m32
+CC=i686-mcp6-g++ -m32
CFLAGS:=-g -O0 -I $(ROOTPATH)/src/include/usr -D PARSER
-BIN:=bin
all: gen_pass code_pass
gen_pass:
-code_pass: $(BIN)/errlparser ${SRCPARSE_HEADER_TARGET}
+code_pass: makeobjdir ${IMGDIR}/errlparser ${SRCPARSE_HEADER_TARGET}
clean:
- rm -fr $(BIN)
rm -fr ${SRCPARSE_HEADER_TARGET}
+ rm -fr ${OBJDIR}/errlparser.o
+ rm -fr ${GENDIR}/errlparser
+ rm -fr ${GENDIR}/comps.C
+
+beam:
-beam:
-$(BIN)/comps.C: $(ROOTPATH)/src/include/usr/hbotcompid.H
- mkdir -p $(BIN)
+makeobjdir:
+ mkdir -p ${OBJDIR}
+
+${GENDIR}/comps.C: $(ROOTPATH)/src/include/usr/hbotcompid.H
grep "const compId_t [A-Z0-9]*_COMP_ID" $^ | \
grep -v MY_COMP_ID | \
sed 's/const compId_t \([A-Z0-9]*\)_COMP_ID[ =\t]*\(0[xX][0-9a-fA-F]*\).*/{ "\1", \2 },/' \
> $@
-$(BIN)/errlparser.o: errlparser.C $(ROOTPATH)/src/include/usr/errl/errltypes.H $(BIN)/comps.C \
+${OBJDIR}/errlparser.o: errlparser.C $(ROOTPATH)/src/include/usr/errl/errltypes.H ${GENDIR}/comps.C \
${SRCPARSE_HEADER_TARGET}
- mkdir -p $(BIN)
- $(CC) -c $(CFLAGS) -I bin -I${ROOTPATH}/obj/genfiles -o $@ $<
+ $(CC) -c $(CFLAGS) -I${ROOTPATH}/obj/genfiles -o $@ $<
-$(BIN)/errlparser: $(BIN)/errlparser.o
+${IMGDIR}/errlparser: ${OBJDIR}/errlparser.o
$(CC) -o $@ $<
+
${SRCPARSE_HEADER_TARGET} :
- ./scanforsrcs.pl -b ${ROOTPATH} -o ${GENFILES}
+ ./scanforsrcs.pl -b ${ROOTPATH} -o ${GENDIR}
+
diff --git a/src/usr/errl/test/errltest.H b/src/usr/errl/test/errltest.H
index 0ac45d019..c2808b32c 100644
--- a/src/usr/errl/test/errltest.H
+++ b/src/usr/errl/test/errltest.H
@@ -66,15 +66,16 @@ public:
*/
void testErrl1(void)
{
- ERRORLOG::ErrlFFDC * pffdc;
+ bool fOK;
+ ERRORLOG::ErrlUD * pffdc;
// An example that shows how to use macros to stuff data into
// the two 64-bit user data parameters in the error log.
// l_userData1 = 16bit(0):l_bit8_1:l_bit8_2:l_32bit_1
uint8_t l_8bit_1 = TEST_USR_8BIT_1; // 0x80
- uint8_t l_8bit_2 = TEST_USR_8BIT_2; // 0x93
+ uint8_t l_8bit_2 = TEST_USR_8BIT_2; // 0x93
uint32_t l_32bit_1 = TEST_USR_32BIT_1; // 0x80000001
- uint64_t l_userData1 =
+ uint64_t l_userData1 =
TWO_UINT32_TO_UINT64( TO_UINT32(TWO_UINT8_TO_UINT16(l_8bit_1, l_8bit_2)), l_32bit_1);
// yields 0x0000809380000001
@@ -86,8 +87,6 @@ public:
uint64_t l_userData2 = TWO_UINT16_ONE_UINT32_TO_UINT64(l_16bit_1, l_16bit_2, l_32bit_2);
// yields 0x8000900390000003
- TRACDCOMP( g_trac_test, "testErrl1");
- TS_TRACE( "testErrl1, Create error log...");
// Create an error log
errlHndl_t l_err = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_INFORMATIONAL,
@@ -108,7 +107,6 @@ public:
// but errlffdc.H is not publicly includable to give me the definition
// for it. addFFDC() should return a Boolean indication of success.
- TS_TRACE( "Add ffdc1");
const char * pch = "martha washington";
pffdc = l_err->addFFDC( ERRL_COMP_ID, pch, strlen( pch ), 1, 2 );
if ( NULL == pffdc )
@@ -116,23 +114,20 @@ public:
TS_FAIL("testErrl1: addFFDC() output NULL pointer");
}
- TS_TRACE( "Add ffdc2");
- pch = "george washington";
+ pch = "george washington";
pffdc = l_err->addFFDC( DEVFW_COMP_ID, pch, strlen( pch ), 3, 4 );
if ( NULL == pffdc )
{
TS_FAIL("testErrl1: addFFDC() output NULL pointer");
}
- TS_TRACE( "Add ffdc3");
- pch = "dwight eisenhour";
+ pch = "dwight eisenhour";
pffdc = l_err->addFFDC( SCOM_COMP_ID, pch, strlen( pch ), 5, 6 );
if ( NULL == pffdc )
{
TS_FAIL("testErrl1: addFFDC() output NULL pointer");
}
- TS_TRACE( "Add ffdc4");
pch = "ronald ";
pffdc = l_err->addFFDC( ERRL_COMP_ID, pch, strlen( pch ), 7, 8 );
if ( NULL == pffdc )
@@ -140,27 +135,35 @@ public:
TS_FAIL("testErrl1: addFFDC() output NULL pointer");
}
- TS_TRACE( "Append ffdc1");
// Append data to something already added.
pch = "reagan";
l_err->appendToFFDC( pffdc, pch, strlen(pch) );
+ // Collect trace
+ fOK = l_err->collectTrace( "INITSVC" );
+ if( !fOK )
+ {
+ TS_FAIL( "collectTrace(INITSVC) rets false." );
+ }
+
+ fOK = l_err->collectTrace( "XSCOM" );
+ if( !fOK )
+ {
+ TS_FAIL( "collectTrace(XSCOM) rets false." );
+ }
+
+ fOK = l_err->collectTrace( "UNK" );
+ if( fOK )
+ {
+ TS_FAIL( "collectTrace(UNK) rets true" );
+ }
// Add null data.
- TS_TRACE( "Append ffdc2");
pffdc = l_err->addFFDC( ERRL_COMP_ID, NULL, 0, 9, 10 );
if ( NULL != pffdc )
{
TS_FAIL("testErrl1: addFFDC() returned non null");
}
-
-
-
-
-
-
-
-
// Verify log data
else if (l_err->sev() != ERRORLOG::ERRL_SEV_INFORMATIONAL)
{
@@ -174,7 +177,7 @@ public:
{
TS_FAIL("testErrl1: createErrlLog() returns incorrect event type!");
}
- else if (l_err->subSys() != ERRORLOG::EPUB_RESERVED_0)
+ else if (l_err->subSys() != ERRORLOG::EPUB_FIRMWARE_SUBSYS )
{
TS_FAIL("testErrl1: createErrlLog() returns incorrect sub system!");
}
@@ -188,8 +191,8 @@ public:
}
else
{
- // Commit error log
- errlCommit(l_err);
+ // Commit error log with different component ID.
+ errlCommit(l_err, FSI_COMP_ID);
// Make sure error log has been deleted by manager
if (l_err != NULL)
{
@@ -216,7 +219,6 @@ public:
uint64_t l_userData2 =
TWO_UINT32_TO_UINT64(TO_UINT32(l_8bit_1), TO_UINT32(l_16bit_1));
- TS_TRACE( "testErrl2");
// Create an error log
errlHndl_t l_err = new ERRORLOG::ErrlEntry(
ERRORLOG::ERRL_SEV_UNRECOVERABLE,
diff --git a/src/usr/trace/trace.C b/src/usr/trace/trace.C
index f14978854..447fad968 100644
--- a/src/usr/trace/trace.C
+++ b/src/usr/trace/trace.C
@@ -785,47 +785,64 @@ trace_desc_t * Trace::getTd(const char *i_comp)
return(l_td);
}
-/******************************************************************************/
-// getBuffer - TODO
-/******************************************************************************/
-int32_t Trace::getBuffer(const trace_desc_t *i_td_ptr,
- void *o_data)
-{
- /*------------------------------------------------------------------------*/
- /* Local Variables */
- /*------------------------------------------------------------------------*/
- int64_t l_rc = 0;
- /*------------------------------------------------------------------------*/
- /* Code */
- /*------------------------------------------------------------------------*/
- if((i_td_ptr) && (o_data != NULL))
+
+/*****************************************************************************/
+// getBuffer() called by ErrlEntry.CollectTrace()
+// Return how many bytes copied, or if given a null pointer or zero buffer
+// size, then return the size of the buffer.
+//
+// Otherwise return zero on error; perhaps the component name/trace buffer
+// name is not found.
+
+uint64_t Trace::getBuffer( const char * i_pComp,
+ void * o_data,
+ uint64_t i_bufferSize )
+{
+ int64_t l_rc = 0;
+ trace_desc_t * l_pDescriptor = NULL;
+
+ do
{
- // Get the lock
- // TODO Mutex
-#if 0
- l_rc = UTIL_MUTEX_GET(&iv_trac_mutex,TRAC_INTF_MUTEX_TIMEOUT);
- if(l_rc != 0)
+ l_pDescriptor = getTd( i_pComp );
+ if( NULL == l_pDescriptor )
{
- // Badness
+ break;
}
- else
+
+ if( ( NULL == o_data ) || ( 0 == i_bufferSize ))
{
- l_rc = SUCCESS;
+ // return how big is the buffer.
+ l_rc = TRAC_DEFAULT_BUFFER_SIZE;
+ break;
}
-#endif
- // Copy it's buffer into temp one
- memcpy(o_data,i_td_ptr,(size_t)TRAC_DEFAULT_BUFFER_SIZE);
- // Always try to release even if error above
- // TODO - mutex
- //UTIL_MUTEX_PUT(&iv_trac_mutex);
+ // Not to exceed buffer size.
+ uint64_t l_copyCount = i_bufferSize;
+ if( i_bufferSize > TRAC_DEFAULT_BUFFER_SIZE )
+ {
+ l_copyCount = TRAC_DEFAULT_BUFFER_SIZE;
+ }
+
+ // Get the lock
+ mutex_lock(&iv_trac_mutex);
+
+ // Copy buffer to caller's space
+ memcpy( o_data, l_pDescriptor, (size_t)l_copyCount );
+
+ mutex_unlock(&iv_trac_mutex);
+
+ l_rc = l_copyCount;
}
+ while( 0 );
- return(l_rc);
+ return l_rc;
}
+
+
+
#if 0
/******************************************************************************/
// getBufferPartial - TODO
OpenPOWER on IntegriCloud