diff options
author | Paul Nguyen <nguyenp@us.ibm.com> | 2012-10-03 13:57:02 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-10-30 14:05:30 -0500 |
commit | bc18309697f7a711b04736a4260094377b33f478 (patch) | |
tree | c661d34edf0e77ad7968760053cad481ec95c9c5 | |
parent | c7f00b4ca316fa8296f350cddb7149c09fa21551 (diff) | |
download | blackbird-hostboot-bc18309697f7a711b04736a4260094377b33f478.tar.gz blackbird-hostboot-bc18309697f7a711b04736a4260094377b33f478.zip |
Report host boot error log to FSP
Change-Id: Iad4be4f0a45a607f7b56fc5d194f1812f74fbfe8
RTC: 34235
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1949
Tested-by: Jenkins Server
Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com>
Reviewed-by: Brian H. Horton <brianh@linux.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r-- | src/include/usr/errl/errlmanager.H | 94 | ||||
-rw-r--r-- | src/include/usr/errl/hberrltypes.H | 53 | ||||
-rw-r--r-- | src/include/usr/mbox/mbox_queues.H | 4 | ||||
-rw-r--r-- | src/usr/errl/errlentry.C | 10 | ||||
-rw-r--r-- | src/usr/errl/errlmanager.C | 358 | ||||
-rw-r--r-- | src/usr/errl/test/errlReportTest.H | 269 |
6 files changed, 718 insertions, 70 deletions
diff --git a/src/include/usr/errl/errlmanager.H b/src/include/usr/errl/errlmanager.H index 2ac6bd69f..3b9ad6572 100644 --- a/src/include/usr/errl/errlmanager.H +++ b/src/include/usr/errl/errlmanager.H @@ -32,15 +32,15 @@ /*****************************************************************************/ // I n c l u d e s /*****************************************************************************/ -#include <stdint.h> -#include <stdlib.h> #include <util/singleton.H> #include <errl/errlentry.H> #include <sys/sync.h> -#include <vector> #include <kernel/timemgr.H> #include <hbotcompid.H> #include <hwas/common/hwasCallout.H> +#include <mbox/mbox_queues.H> +#include <mbox/mboxif.H> + namespace ERRORLOG { @@ -66,6 +66,7 @@ namespace ERRORLOG */ void errlCommit(errlHndl_t& io_err, compId_t i_committerComp ); + /*****************************************************************************/ // Forward class declarations /*****************************************************************************/ @@ -124,6 +125,7 @@ public: */ static void setHwasProcessCalloutFn(HWAS::processCalloutFn i_fn); + /** * @brief Returns the HWAS ProcessCallout function pointer * @@ -161,11 +163,88 @@ protected: private: /** + * @enum ERRLOG_MSG_TYPE + * + * @brief Message types that recognized by the error log message queue + */ + enum ERRLOG_MSG_TYPE + { + ERRLOG_NEEDS_TO_BE_COMMITTED_TYPE = 0x00000030 | MBOX::FIRST_SECURE_MSG, + ERRLOG_SEND_TO_FSP_TYPE = 0x00000031 | MBOX::FIRST_SECURE_MSG, + ERRLOG_COMMITTED_ACK_RESPONSE_TYPE = 0x00000032 | MBOX::FIRST_UNSECURE_MSG, + ERRLOG_SHUTDOWN = 0x00000033 | MBOX::FIRST_SECURE_MSG, + }; + + /** * @brief Disabled copy constructor and assignment operator */ ErrlManager(const ErrlManager& i_right); ErrlManager& operator=(const ErrlManager& i_right); + /** + * @brief Create and register the error log message queue + * + * @param[in/out] NONE + * @return NONE. + */ + void msgQueueInit ( void ); + + + /** + * @brief Performs startup of the error log processing thread. + * + * @param[in/out] + * @return NONE + */ + static void * startup ( void* i_self ); + + /** + * @brief Message handler for process Hostboot error log message + * and send it to FSP. + * + * @param[in/out] NONE + * @return NONE + * + */ + void errlogMsgHndlr ( void ); + + /** + * @brief Send Host boot error log to error message queue for committing. + * + * @param[in,out] io_err Error log handle to be committed + * @param[in] i_committerComp Component id that committed the error + * + * @return NONE + * + */ + void sendErrlogToMessageQueue ( errlHndl_t& io_err, compId_t i_committerComp ); + + /** + * @brief Create a mailbox message with the error log and send it to Fsp. + * + * @param[in,out] io_err Error log handle to be committed + * @return NONE + * + */ + void sendMboxMsg ( errlHndl_t& io_err ); + + /** + * @brief Save errlog entry in the memory + * + * @param[in,out] io_err Error log handle to be committed + * @return NULL + * + */ + void saveErrLogEntry( errlHndl_t& io_err ); + + /** + * @brief Shutdown error log manager + * + * @param[in,out] None + * @return NULL + * + */ + void errlogShutdown( void ); /** * @brief Current log ID. As new error logs are created, @@ -173,7 +252,6 @@ private: */ uint32_t iv_currLogId; - /** * @brief * Pointer to the header that preceeds the error log storage buffer @@ -184,14 +262,14 @@ private: storage_header_t * iv_pStorage; /** - * @brief Serialization for error log commits. + * @brief Pointer to the HWAS processCallout function */ - mutex_t iv_commitMutex; + HWAS::processCalloutFn iv_hwasProcessCalloutFn; /** - * @brief Pointer to the HWAS processCallout function + * @brief Message queue for error log */ - HWAS::processCalloutFn iv_hwasProcessCalloutFn; + msg_q_t iv_msgQ; }; diff --git a/src/include/usr/errl/hberrltypes.H b/src/include/usr/errl/hberrltypes.H index bea8b8345..418a80b21 100644 --- a/src/include/usr/errl/hberrltypes.H +++ b/src/include/usr/errl/hberrltypes.H @@ -1,26 +1,25 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/include/usr/errl/hberrltypes.H $ - * - * IBM CONFIDENTIAL - * - * COPYRIGHT International Business Machines Corp. 2011-2012 - * - * 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_TAG - */ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/errl/hberrltypes.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* */ +/* 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 otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #ifndef HBERRLTYPES_H #define HBERRLTYPES_H /** @@ -181,10 +180,10 @@ enum errlSectionId_t */ enum errlSeverity_t { - ERRL_SEV_INFORMATIONAL = 0x00, - ERRL_SEV_UNRECOVERABLE = 0x10, - ERRL_SEV_CRITICAL_SYS_TERM = 0x20, - ERRL_SEV_UNKNOWN = 0xFF + ERRL_SEV_INFORMATIONAL = 0x00, //Information + ERRL_SEV_UNRECOVERABLE = 0x40, //Unrecoverable, general + ERRL_SEV_CRITICAL_SYS_TERM = 0x51, //Critical, System Termination + ERRL_SEV_UNKNOWN = 0xFF //Reserved }; diff --git a/src/include/usr/mbox/mbox_queues.H b/src/include/usr/mbox/mbox_queues.H index a940c1098..0fba7ca30 100644 --- a/src/include/usr/mbox/mbox_queues.H +++ b/src/include/usr/mbox/mbox_queues.H @@ -43,6 +43,7 @@ namespace MBOX HB_MAILBOX_MSGQ, HB_ISTEP_MSGQ, HB_ATTR_SYNC_MSGQ, + HB_ERROR_MSGQ, // Add HB services here: HB_TEST_MSGQ = 0x7FFFFFFF, @@ -52,9 +53,10 @@ namespace MBOX FSP_MAILBOX_MSGQ, FSP_PROGRESS_CODES_MSGQ, FSP_TRACE_MSGQ, - FSP_ERRL_MSGQ, + FSP_ERROR_MSGQ = 0x80000004, IPL_SERVICE_QUEUE = 0x80000008, // Defined by Fsp team FSP_ATTR_SYNC_MSGQ = 0x80000009, + // Add FSP services here: FSP_ECHO_MSGQ = 0xFFFFFFFF, // Fake FSP for test }; diff --git a/src/usr/errl/errlentry.C b/src/usr/errl/errlentry.C index 76d4a99de..4dff81688 100644 --- a/src/usr/errl/errlentry.C +++ b/src/usr/errl/errlentry.C @@ -300,16 +300,6 @@ void ErrlEntry::commit( compId_t i_committerComponent ) iv_User.setComponentId( i_committerComponent ); // see if HWAS has been loaded and has set the processCallout function - // TODO RTC 46680 - // If the PNOR resource provider commits an error then this function will - // call HWAS to process the callouts/deconfigure/GARD requests in the - // error log, if the HWAS function is not paged into memory then VMM will - // attempt to page it in which will invoke the PNOR resource provider, - // this will deadlock if the PNOR resource provider is waiting for the - // error log commit to complete before processing further requests. There - // may be other similar deadlock scenarios involving 'base' functions - // logging errors. This can be solved with a separate errl-manager task - // that processes error logs HWAS::processCalloutFn pFn; pFn = ERRORLOG::theErrlManager::instance().getHwasProcessCalloutFn(); if (pFn != NULL) diff --git a/src/usr/errl/errlmanager.C b/src/usr/errl/errlmanager.C index 132ec49c1..e95b6d2fa 100644 --- a/src/usr/errl/errlmanager.C +++ b/src/usr/errl/errlmanager.C @@ -32,12 +32,14 @@ #include <errl/errlmanager.H> #include <trace/interface.H> #include <errl/errlentry.H> +#include <sys/task.h> #include <stdlib.h> #include <string.h> - - - - +#include <mbox/mbox_queues.H> +#include <mbox/mboxif.H> +#include <initservice/initserviceif.H> +#include <pnor/pnorif.H> +#include <sys/mm.h> namespace ERRORLOG { @@ -45,7 +47,6 @@ namespace ERRORLOG extern trace_desc_t* g_trac_errl; - // Scaffolding // Store error logs in this memory buffer in L3 RAM. char* g_ErrlStorage = new char[ ERRL_STORAGE_SIZE ]; @@ -83,7 +84,7 @@ ErrlManager::ErrlManager() iv_hwasProcessCalloutFn = NULL; - mutex_init(&iv_commitMutex); + TRACFCOMP( g_trac_errl, ENTER_MRK "ErrlManager::ErrlManager constructor" ); // Scaffolding. // For now, put error logs in a 64KB buffer in L3 RAM @@ -104,37 +105,268 @@ ErrlManager::ErrlManager() l_pMarker->offsetNext = 0; l_pMarker->length = 0; + // Create and register error log message queue. + msgQueueInit(); + + // Startup the error log processing thread. + task_create( ErrlManager::startup, this ); + + TRACFCOMP( g_trac_errl, EXIT_MRK "ErrlManager::ErrlManager constructor." ); } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// ErrlManager::~ErrlManager() { + TRACFCOMP( g_trac_errl, ENTER_MRK "ErrlManager::ErrlManager destructor" ); + + // Singleton destructor gets run when module gets unloaded. + // This errorlog module never gets unloaded. So rather to send a + // message to error log daemon and tell it to shutdow and delete + // the queue we will assert here because the destructor never gets + // call. + assert(0); + + TRACFCOMP( g_trac_errl, EXIT_MRK "ErrlManager::ErrlManager destructor." ); +} + +/////////////////////////////////////////////////////////////////////////////// +// ErrlManager::msgQueueInit() +/////////////////////////////////////////////////////////////////////////////// +void ErrlManager::msgQueueInit ( void ) +{ + errlHndl_t l_err = NULL; + + TRACFCOMP( g_trac_errl, ENTER_MRK "ErrlManager::msgQueueInit ..." ); + + do + { + // Create error log message queue. + iv_msgQ = msg_q_create(); + + // Register messageQ with Mailbox to receive message. + l_err = MBOX::msgq_register( MBOX::HB_ERROR_MSGQ, + iv_msgQ ); + if( l_err ) + { + TRACFCOMP(g_trac_errl, ERR_MRK "Msg queue already registered"); + + delete( l_err ); + l_err = NULL; + + //If we got an error then it means the message queue is + //registered with mailbox. This should not happen. + //So assert here. + assert(0); + + break; + } + + // Register for error log manager shutdown event + INITSERVICE::registerShutdownEvent( iv_msgQ, ERRLOG_SHUTDOWN, + INITSERVICE::NO_PRIORITY ); + + } while (0); + + TRACFCOMP( g_trac_errl, EXIT_MRK "ErrlManager::msgQueueInit" ); + + return; +} + +/////////////////////////////////////////////////////////////////////////////// +// ErrlManager::startup() +/////////////////////////////////////////////////////////////////////////////// +void * ErrlManager::startup ( void* i_self ) +{ + + TRACFCOMP( g_trac_errl, ENTER_MRK "ErrlManager::startup..." ); + + //Start a thread and let error log message handler running. + reinterpret_cast<ErrlManager *>(i_self)->errlogMsgHndlr(); + + TRACFCOMP( g_trac_errl, EXIT_MRK "ErrlManager::startup" ); + + return NULL; +} + + +/////////////////////////////////////////////////////////////////////////////// +// ErrlManager::errlogMsgHndlr() +/////////////////////////////////////////////////////////////////////////////// +void ErrlManager::errlogMsgHndlr ( void ) +{ + errlHndl_t l_err = NULL; + msg_t * theMsg = NULL; + + TRACFCOMP( g_trac_errl, ENTER_MRK "Enter ErrlManager::errlogMsgHndlr" ); + + while( 1 ) + { + theMsg = msg_wait( iv_msgQ ); + TRACFCOMP( g_trac_errl, INFO_MRK"Got an error log Msg - Type: 0x%08x", + theMsg->type ); + //Process message just received + switch( theMsg->type ) + { + case ERRLOG_NEEDS_TO_BE_COMMITTED_TYPE: + + //Extract error log handle from the message. We need the error + //log handle to pass along to saveErrlogEntry and sendMboxMsg + l_err = (errlHndl_t) theMsg->extra_data; + + //Ask the ErrlEntry to assign commit component, commit time + //and callout information + l_err->commit( (compId_t) theMsg->data[0] ); + + //Write the error log to L3 memory till PNOR is implemented + //RTC #47517 for future task to write error log to PNOR + saveErrLogEntry ( l_err ); + + //Create a mbox message with the error log and send it to FSP + //We only send error log to FSP when mailbox is enabled + if( MBOX::mailbox_enabled() ) + { + sendMboxMsg ( l_err ); + } + + //We are done with the error log handle so delete it. + delete l_err; + l_err = NULL; + + //We are done with the msg so go back and wait for a next one + msg_free(theMsg); + + break; + + case ERRLOG_COMMITTED_ACK_RESPONSE_TYPE: + //Hostboot must keep track and clean up hostboot error + //logs in PNOR after it is committed by FSP. + + //TODO: We have an RTC 47517 for this work. New code need + //to be added to mark the error log in PNOR as committed. + + TRACFCOMP( g_trac_errl, INFO_MRK"Got a acked msg - Type: 0x%08x", + theMsg->type ); + msg_free(theMsg); + break; + + case ERRLOG_SHUTDOWN: + TRACFCOMP( g_trac_errl, INFO_MRK "Shutdown event received" ); + + //Start shutdown process for error log + errlogShutdown(); + msg_respond ( iv_msgQ, theMsg ); + break; + + default: + // Default Message + TRACFCOMP( g_trac_errl, ERR_MRK "Unexpected message type 0x%08x", + theMsg->type ); + + msg_free(theMsg); + break; + } + } + + //The errlogMsgHndlr should run all the time. It only + //exits when error log message thread is killed. + TRACFCOMP( g_trac_errl, EXIT_MRK "Exit ErrlManager::errlogMsgHndlr" ); + return; } + +/////////////////////////////////////////////////////////////////////////////// +// ErrlManager::sendMboxMsg() +/////////////////////////////////////////////////////////////////////////////// +void ErrlManager::sendMboxMsg ( errlHndl_t& io_err ) +{ + errlHndl_t l_err = NULL; + msg_t * msg = NULL; + + TRACFCOMP( g_trac_errl, ENTER_MRK"ErrlManager::sendMboxMsg" ); + do + { + //Create a mailbox message to send to FSP + msg = msg_allocate(); + msg->type = ERRLOG_SEND_TO_FSP_TYPE; + + uint32_t l_msgSize = io_err->flattenedSize(); + + //Data[0] will be hostboot error log ID so Hostboot can + //keep track of the error log when FSP responses back. + //The error log ID is also the plid (platform log identify) + + msg->data[0] = io_err->plid(); + msg->data[1] = l_msgSize; + + void * temp_buff = malloc( l_msgSize ); + io_err->flatten ( temp_buff, l_msgSize ); + msg->extra_data = temp_buff; + + TRACDCOMP( g_trac_errl, INFO_MRK"Send msg to FSP for errlogId [0x%08x]", + io_err->plid() ); + + l_err = MBOX::send( MBOX::FSP_ERROR_MSGQ, msg ); + if( l_err ) + { + TRACFCOMP(g_trac_errl, ERR_MRK "Failed sending error log to FSP"); + + //Free the extra data due to the error + if( msg != NULL && msg->extra_data != NULL ) + { + free( msg->extra_data ); + msg_free( msg ); + } + + delete l_err; + l_err = NULL; + + } + } while (0); + + TRACFCOMP( g_trac_errl, EXIT_MRK"sendMboxMsg()" ); + return; +} + +/////////////////////////////////////////////////////////////////////////////// +// Handling commit error log. /////////////////////////////////////////////////////////////////////////////// -// -// Save and delete this error log. On output, io_err will be nul. -// void ErrlManager::commitErrLog(errlHndl_t& io_err, compId_t i_committerComp ) { + + TRACDCOMP( g_trac_errl, ENTER_MRK"ErrlManager::commitErrLog" ); do { if (io_err == NULL) { // put out warning trace - TRACFCOMP(g_trac_errl, "commitErrLog() - NULL pointer"); + TRACFCOMP(g_trac_errl, ERR_MRK "commitErrLog() - NULL pointer"); break; } - TRACFCOMP(g_trac_errl, "commitErrLog() called by %.4X for plid=0x%X, Reasoncode=%.4X", i_committerComp, io_err->plid(), io_err->reasonCode() ); + TRACFCOMP(g_trac_errl, "commitErrLog() called by %.4X for plid=0x%X," + "Reasoncode=%.4X", i_committerComp, + io_err->plid(), io_err->reasonCode() ); - // lock sem - mutex_lock(&iv_commitMutex); + //Offload the error log to the errlog message queue + sendErrlogToMessageQueue ( io_err, i_committerComp ); + io_err = NULL; + + } while( 0 ); + + TRACDCOMP( g_trac_errl, EXIT_MRK"ErrlManager::commitErrLog" ); - // Ask the ErrlEntry to assign commit component, commit time, etc. - io_err->commit( i_committerComp ); + return; +} +/////////////////////////////////////////////////////////////////////////////// +// ErrlManager::saveErrLogEntry() +/////////////////////////////////////////////////////////////////////////////// +void ErrlManager::saveErrLogEntry( errlHndl_t& io_err ) +{ + TRACFCOMP( g_trac_errl, ENTER_MRK"ErrlManager::saveErrLogEntry" ); + do + { // Get flattened count of bytes. uint32_t l_cbActualFlat = io_err->flattenedSize(); @@ -165,19 +397,12 @@ void ErrlManager::commitErrLog(errlHndl_t& io_err, compId_t i_committerComp ) pNew->length = 0; } - // Count of error logs called to commit, regardless if there was // room to commit them or not. iv_pStorage->cInserted++; - - // unlock sem - mutex_unlock(&iv_commitMutex); - - delete io_err; - io_err = NULL; - } - while( 0 ); + } while( 0 ); + TRACFCOMP( g_trac_errl, EXIT_MRK"ErrlManager::saveErrLogEntry" ); return; } @@ -209,4 +434,89 @@ void errlCommit(errlHndl_t& io_err, compId_t i_committerComp ) return; } + +/////////////////////////////////////////////////////////////////////////////// +// ErrlManager::sendErrlogToMessageQueue() +/////////////////////////////////////////////////////////////////////////////// +void ErrlManager::sendErrlogToMessageQueue ( errlHndl_t& io_err, + compId_t i_committerComp ) +{ + msg_t * msg = NULL; + + TRACFCOMP( g_trac_errl, ENTER_MRK"ErrlManager::sendErrlogToMessageQueue" ); + + do + { + //Create a message to send to Host boot error message queue. + msg = msg_allocate(); + + msg->type = ERRLOG_NEEDS_TO_BE_COMMITTED_TYPE; + + //Pass along the component id in the message + msg->data[0] = i_committerComp; + + //Pass along the error log handle in the message + msg->data[1] = 8; + msg->extra_data = io_err; + + TRACFCOMP( g_trac_errl, INFO_MRK"Send an error log to message queue" + " to commit. plid=0x%X", io_err->plid() ); + + //Send the error log to error message queue to handle. + //Message is sent as asynchronous. + int rc = msg_send ( iv_msgQ, msg ); + + //Return code is non-zero when the message queue is invalid + //or the message type is invalid. + if ( rc ) + { + TRACFCOMP( g_trac_errl, ERR_MRK "Failed to send mailbox message" + "to message queue. plid=0x%X", io_err->plid() ); + break; + } + + } while (0); + TRACFCOMP( g_trac_errl, EXIT_MRK"ErrlManager::sendErrlogToMessageQueue" ); + return; +} + +/////////////////////////////////////////////////////////////////////////////// +// ErrlManager::errlogShutdown() +/////////////////////////////////////////////////////////////////////////////// +void ErrlManager::errlogShutdown(void) +{ + errlHndl_t l_err = NULL; + PNOR::SectionInfo_t l_section; + + // Ensure that all the error logs are pushed out to PNOR + // prior to the PNOR resource provider shutting down. + + l_err = PNOR::getSectionInfo(PNOR::HB_ERRLOGS, PNOR::CURRENT_SIDE, l_section); + + if(l_err) + { + TRACFCOMP(g_trac_errl, ERR_MRK "Error in getting PNOR section info"); + //We are shutting the error log manager so we can not commit + //error. So just log the error trace for the error. + delete l_err; + l_err = NULL; + } + else + { + int l_rc = mm_remove_pages(FLUSH, (void *) l_section.vaddr, + l_section.size); + if( l_rc ) + { + //If mm_remove_pages returns none zero for error then + //log an error trace in this case. + TRACFCOMP(g_trac_errl, ERR_MRK "Fail to flush the page"); + } + } + + // Un-register error log message queue from the mailbox service + MBOX::msgq_unregister( MBOX::HB_ERROR_MSGQ ); + + return; +} + } // End namespace diff --git a/src/usr/errl/test/errlReportTest.H b/src/usr/errl/test/errlReportTest.H new file mode 100644 index 000000000..2114a77ce --- /dev/null +++ b/src/usr/errl/test/errlReportTest.H @@ -0,0 +1,269 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/errl/test/errlReportTest.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2012 */ +/* */ +/* 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 otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __ERRLREPORTTEST_H +#define __ERRLREPORTTEST_H + +/** + * @file errlReportTest.H + * + * @brief Test case for Error Logging Reporting +*/ + +#include <cxxtest/TestSuite.H> +#include <errl/errlmanager.H> +#include <errl/errlentry.H> +#include <errl/errlreasoncodes.H> +#include <trace/trace.H> +#include <hbotcompid.H> +#include <errl/errludtarget.H> +#include <targeting/common/target.H> +#include <targeting/common/iterators/rangefilter.H> +#include <targeting/common/predicates/predicates.H> +#include <hwas/common/hwasCallout.H> +#include <kernel/syscalls.H> +#include <sys/time.h> + + +class ErrlReportTest: public CxxTest::TestSuite +{ +public: + + /** + * @brief Send a small size error log to FSP + * - Create an error log with only 192 bytes + * - Verify that hostbot created error log and sent it to FSP + * - Found an issue with FSI mailbox DMA code to realign data len + * - The problem should be fixed in Feature 855338 (fips810) + */ + + void testErrlReport1(void) + { + errlHndl_t l_err = NULL; + uint64_t l_userData1 = 0xDEADBEEF; + uint64_t l_userData2 = 0xDEADBEEF; + + TS_TRACE( "test testErrlReport1"); + do + { + // Create an error log + l_err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + HBERRL_TEST_MOD_ID, + HBERRL_TEST_REASON_CODE, + l_userData1, + l_userData2); + if (l_err == NULL) + { + TS_FAIL("testErrlReport1: createErrlLog() failed."); + break; + } + + // Commit error log. + errlCommit(l_err, CXXTEST_COMP_ID); + + } while(0); + } + + + /** + * @brief Send multiple error logs back to back to FSP + * - Create several error logs and send them to FSP in a loop. + * - Verify that error logs are created and sent to FSP + * - Verify that FSP received all the error logs and log them properly. + */ + void testErrlReport2( void ) + { + errlHndl_t l_err = NULL; + uint32_t l_loopi = 0 ; + + TS_TRACE( "test testErrlReport2"); + + do + { + for (l_loopi = 0; l_loopi < 5; l_loopi++) + { + + // Create an error log + l_err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + HBERRL_TEST_MOD_ID, + HBERRL_TEST_REASON_CODE, + l_loopi, + l_loopi); + if (l_err == NULL) + { + TS_FAIL("testErrlReport2: createErrlLog() failed."); + break; + } + + // Commit error log + errlCommit(l_err, CXXTEST_COMP_ID); + } + } while(0); + } + + + + /** + * @brief Send an unrecoverable error log to FSP + * - Verify that an error log with severity unrecoverable created successfully + * - Verify that the error log is sent to FSP + * - Verify that FSP log the error as unrecoverable one. + * + */ + + void testErrlReport3(void) + { + errlHndl_t l_err = NULL; + uint64_t l_userData1 = 0xEEEEEEEE; + uint64_t l_userData2 = 0xEEEEEEEE; + + TS_TRACE( "test testErrlReport3"); + do + { + // Create an error log + l_err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + HBERRL_TEST_MOD_ID, + HBERRL_TEST_REASON_CODE, + l_userData1, + l_userData2); + if (l_err == NULL) + { + TS_FAIL("testErrlReport3: createErrlLog() failed"); + break; + } + + // Commit error log. + errlCommit(l_err, CXXTEST_COMP_ID); + } while(0); + } + + + /** + * @brief Send a critical system terminate error log from Hostboot to FSP + * - Verify that hostbot errorlog is sent to FSP. + * - Verify that FSP logged the error as critical system terminate one. + * + */ + + void testErrlReport4(void) + { + errlHndl_t l_err = NULL; + uint64_t l_userData1 = 0xAAAAAAAA; + uint64_t l_userData2 = 0xBBBBBBBB; + + TS_TRACE( "test testErrlReport4"); + do + { + // Create an error log + l_err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, + HBERRL_TEST_MOD_ID, + HBERRL_TEST_REASON_CODE, + l_userData1, + l_userData2); + if (l_err == NULL) + { + TS_FAIL("testErrlReport4: createErrlLog() failed."); + break; + } + + // Commit error log. + errlCommit(l_err, CXXTEST_COMP_ID); + } while(0); + } + + /** + * @brief Send a big size error log to FSP + * - Verfiy that an error log with ffdc and traces is created successfully + * - Verify that the error log is sent to FSP + * - Verify that FSP logged the error with correct data successfully + */ + void testErrlReport5(void) + { + bool l_rc; + ERRORLOG::ErrlUD * pffdc; + uint64_t l_userData1 = 0xFFFFFFFF; + uint64_t l_userData2 = 0xFFFFFFFF; + + TS_TRACE( "test testErrlReport5"); + do + { + // Create an error log + errlHndl_t l_err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + HBERRL_TEST_MOD_ID, + HBERRL_TEST_REASON_CODE, + l_userData1, + l_userData2); + + + // Make sure log is created + if (l_err == NULL) + { + TS_FAIL("testErrlReport5: createErrlLog() failed"); + break; + } + + // add FFDC + const char * l_str = "Error log report testing."; + pffdc = l_err->addFFDC( DEVFW_COMP_ID, l_str, strlen( l_str ), 0, 0); + if ( NULL == pffdc ) + { + TS_FAIL("testErrlReport5: addFFDC() failed"); + break; + } + + // Collect traces + l_rc = l_err->collectTrace( "XSCOM" , 0x7D0 ); + if( !l_rc ) + { + TS_FAIL( "testErrlReport5: collectTrace(XSCOM) returns false." ); + break; + } + + l_rc = l_err->collectTrace( "TARG" , 4003 ); + if( !l_rc ) + { + TS_FAIL( "testErrlReport5: collectTrace(TARG,4003) returns false" ); + break; + } + + // Add null data. + pffdc = l_err->addFFDC( HBERRL_COMP_ID, NULL, 0, 9, 10 ); + if ( NULL != pffdc ) + { + TS_FAIL(" addFFDC() returned non null"); + break; + } + + // Commit error log. + errlCommit(l_err, CXXTEST_COMP_ID); + + } while(0); + } + +}; + +#endif |