diff options
author | Monte Copeland <copelanm@us.ibm.com> | 2011-10-24 09:30:49 -0500 |
---|---|---|
committer | Monte K. Copeland <copelanm@us.ibm.com> | 2011-10-31 11:07:10 -0500 |
commit | 723239d5a14fe82713a2aa57fef3130534b15a41 (patch) | |
tree | b6d19b1d1d66ec9ea4acd19c0dfdb47bcf86babd /src/usr | |
parent | f2794eed87ca9c35140c601dfcbb5baf299d834b (diff) | |
download | talos-hostboot-723239d5a14fe82713a2aa57fef3130534b15a41.tar.gz talos-hostboot-723239d5a14fe82713a2aa57fef3130534b15a41.zip |
Error log changes for Sprint 6
Change-Id: I44ad678cfae8cd84e5370391dc7e20d74f59c9ca
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/449
Tested-by: Jenkins Server
Reviewed-by: Mark W. Wenning <wenning@us.ibm.com>
Reviewed-by: Monte K. Copeland <copelanm@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/errl/errlentry.C | 319 | ||||
-rw-r--r-- | src/usr/errl/errlffdc.C | 66 | ||||
-rw-r--r-- | src/usr/errl/errlffdc.H | 96 | ||||
-rw-r--r-- | src/usr/errl/errlmanager.C | 18 | ||||
-rw-r--r-- | src/usr/errl/errlprvt.C | 135 | ||||
-rw-r--r-- | src/usr/errl/errlsctn.C | 114 | ||||
-rw-r--r-- | src/usr/errl/errlsctnhdr.C | 78 | ||||
-rw-r--r-- | src/usr/errl/errlsctnhdr.H | 102 | ||||
-rw-r--r-- | src/usr/errl/errlsrc.C | 164 | ||||
-rw-r--r-- | src/usr/errl/errlud.C | 168 | ||||
-rw-r--r-- | src/usr/errl/errluh.C | 114 | ||||
-rw-r--r-- | src/usr/errl/makefile | 2 | ||||
-rw-r--r-- | src/usr/errl/parser/errlparser.C | 631 | ||||
-rw-r--r-- | src/usr/errl/parser/makefile | 40 | ||||
-rw-r--r-- | src/usr/errl/test/errltest.H | 52 | ||||
-rw-r--r-- | src/usr/trace/trace.C | 75 |
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( §ionHeader, pch, sizeof( pelSectionHeader_t )); + ConvertPELSectionHeader( §ionHeader ); - // 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 |