summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr')
-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
16 files changed, 1424 insertions, 750 deletions
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