diff options
author | Dzuy Nguyen <dzuy@us.ibm.com> | 2016-11-23 16:57:16 -0600 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-01-19 18:03:32 -0500 |
commit | 7fd14de1394f507935cd60f6215ca5f65b97df51 (patch) | |
tree | 57aee80a5e9627f76fa9b09068568fc07f05df6c /src/usr | |
parent | e671bf2e25b6902a76212ab830c1f6e2841042cc (diff) | |
download | talos-hostboot-7fd14de1394f507935cd60f6215ca5f65b97df51.tar.gz talos-hostboot-7fd14de1394f507935cd60f6215ca5f65b97df51.zip |
SBE FIFO device driver FFDC and error recovery
Add SBE FFDC error handling to FIFO driver
Change-Id: I6ae81062eac1d5362c5fa5651c8ca5a2043b5c73
RTC: 149454
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/32969
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Shakeeb A. Pasha B K <shakeebbk@in.ibm.com>
Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/sbeio/makefile | 7 | ||||
-rw-r--r-- | src/usr/sbeio/sbe_ffdc_parser.C | 260 | ||||
-rw-r--r-- | src/usr/sbeio/sbe_fifodd.C | 179 | ||||
-rw-r--r-- | src/usr/sbeio/sbe_fifodd.H | 756 | ||||
-rw-r--r-- | src/usr/sbeio/sbe_psudd.C | 153 | ||||
-rw-r--r-- | src/usr/sbeio/sbe_scomAccess.C | 36 | ||||
-rw-r--r-- | src/usr/sbeio/test/sbe_ffdctest.H | 245 |
7 files changed, 1019 insertions, 617 deletions
diff --git a/src/usr/sbeio/makefile b/src/usr/sbeio/makefile index e92dbd89b..688d5edc5 100644 --- a/src/usr/sbeio/makefile +++ b/src/usr/sbeio/makefile @@ -26,6 +26,12 @@ ROOTPATH = ../../.. MODULE = sbeio +EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2 +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/imageProcs +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc + OBJS += sbe_psudd.o OBJS += sbe_coreStateControl.o OBJS += sbe_psuQuiesce.o @@ -33,6 +39,7 @@ OBJS += sbe_systemConfig.o OBJS += sbe_fifodd.o OBJS += sbe_scomAccess.o OBJS += sbe_scomAccessdd.o +OBJS += sbe_ffdc_parser.o SUBDIRS = test.d diff --git a/src/usr/sbeio/sbe_ffdc_parser.C b/src/usr/sbeio/sbe_ffdc_parser.C new file mode 100644 index 000000000..57a174e72 --- /dev/null +++ b/src/usr/sbeio/sbe_ffdc_parser.C @@ -0,0 +1,260 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/sbeio/sbe_ffdc_parser.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#include <stdlib.h> +#include <errl/errlentry.H> +#include <errl/errlreasoncodes.H> +#include <sbeio/sbeioreasoncodes.H> +#include <errl/errlmanager.H> +#include <util/utilbyte.H> +#include <sbeio/sbe_ffdc_parser.H> + +/** + * @file sbe_ffdc_pader.C + * @brief SBE FFDC package parder + */ + + +extern trace_desc_t* g_trac_sbeio; + +#define SBE_TRACF(printf_string,args...) \ + TRACFCOMP(g_trac_sbeio,"ffdcParser: " printf_string,##args) +#define SBE_TRACD(printf_string,args...) \ + TRACDCOMP(g_trac_sbeio,"ffdcParser: " printf_string,##args) +#define SBE_TRACU(args...) +#define SBE_TRACFBIN(printf_string,args...) \ + TRACFBIN(g_trac_sbeio,"ffdcParser: " printf_string,##args) +#define SBE_TRACDBIN(printf_string,args...) \ + TRACDBIN(g_trac_sbeio,"ffdcParser: " printf_string,##args) + + +namespace SBEIO +{ + +SbeFFDCParser::~SbeFFDCParser() +{ + uint8_t i; + for(i = 0; i < iv_ffdcPackages.size(); i++) + { + if(iv_ffdcPackages[i]->ffdcPtr != NULL) + { + free((void *) iv_ffdcPackages[i]->ffdcPtr); + } + } + iv_ffdcPackages.clear(); +} + +/* + * @brief Parses FFDC package(s) ffdcPackageBuffer + * + * FFDC package according to the SBE Interface Specification: + * Dword 0: + * byte 0,1: Magic Byte: 0xFFDC + * byte 2,3: Length in words (N + 4) + * byte 4,5: Sequence Id + * byte 6 : Command Class + * byte 7 : Command + * Dword 1: + * byte 0-3: Return Code + * byte 4-7: Word 0 + * Dword M: + * byte 0-3: Word N - 1 + * byte 4-7: Word N + */ + +void SbeFFDCParser::parseFFDCData(void * i_ffdcPackageBuffer) +{ + uint16_t l_magicByte = 0x00; + uint8_t i = 0; + errlHndl_t errl = NULL; + + SBE_TRACD(ENTER_MRK "parseFFDCData"); + do { + // Magic Byte is 1st 2 bytes + l_magicByte = UtilByte::bufferTo16uint( + static_cast<char *>(i_ffdcPackageBuffer) + i); + + if(l_magicByte == iv_ffdcMagicByte) + { + /* + * Length is next 2 bytes (in words, each word is 4 bytes) + * In FFDC packet, byte 2 & byte 3 holds the length in words, + * which is 4 words less than the total package length. + */ + uint16_t l_packageLengthInWords = UtilByte::bufferTo16uint( + static_cast<char *>(i_ffdcPackageBuffer) + + i + sizeof(l_magicByte)); + + /* + * Get the Return Code - should be 8 bytes from beginning + */ + uint32_t l_rc = UtilByte::bufferTo32uint( + static_cast<char *>(i_ffdcPackageBuffer) + + i + iv_headerWordInBytes); + + /* + * Get the size of the ffdc package = the entire package length + * minus the header (2 words), and the rc (1 word) + */ + uint8_t l_bufLenInBytes = iv_ffdcWordLen * l_packageLengthInWords - + iv_headerWordInBytes - sizeof(l_rc); + + // Check to see if what we're copying is beyond the buffer size + uint8_t l_bufferMarker = i + iv_headerWordInBytes + + sizeof(l_rc) + l_bufLenInBytes; + if(l_bufferMarker > PAGESIZE * iv_ffdcPackageSize) + { + SBE_TRACF(ERR_MRK"parseFFDCData: FFDC Package buffer overflow detected."); + + /*@ + * @errortype + * @moduleid SBEIO_FFDC_PARSER + * @reasoncode SBEIO_FFDC_PARSER_BUFF_OVERFLOW + * @userdata1 size of FFDC package that overflows the buffer + * @devdesc If the size of the FFDC package exceeds our + * allocated buffer size, we log it. + */ + + errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + SBEIO_FFDC_PARSER, + SBEIO_FFDC_PARSER_BUFF_OVERFLOW, + TO_UINT64(l_bufferMarker), + 0); + errl->collectTrace(SBEIO_COMP_NAME); + errlCommit(errl, SBEIO_COMP_ID); + + break; + } + else + { + // Extract the words and add to errl + void * l_wordBuffer = (void *) malloc(l_bufLenInBytes); + if(l_wordBuffer == NULL) + { + SBE_TRACF(ERR_MRK"parseFFDCData: Failure to allocate memory: wordBuffer."); + break; + } + + // Copy data from ffdcPackageBuffer to wordBuffer + // starting at 12 byte from current pointer + memcpy(l_wordBuffer, + static_cast<char *>(i_ffdcPackageBuffer) + + i + iv_headerWordInBytes + sizeof(l_rc), + l_bufLenInBytes); + + addFFDCPackage(l_wordBuffer, l_rc, l_bufLenInBytes); + + free(l_wordBuffer); + } + + // Skip length of whole package + i += l_packageLengthInWords * iv_ffdcWordLen; + } + else + { + SBE_TRACD(ERR_MRK"parseFFDCData: Invalid FFDC Magic Byte: 0x%04lx", + l_magicByte); + break; + } + } while (l_magicByte != 0x00); + + + SBE_TRACD(EXIT_MRK "parseFFDCData"); +} + +/* + * @brief returns total FFDC packages found + */ +uint8_t SbeFFDCParser::getTotalPackages() +{ + return iv_ffdcPackages.size(); +} + +/* + * @brief returns the size (bytes) of the FFDC package + */ +uint8_t SbeFFDCParser::getPackageLength(uint8_t i_index) +{ + uint8_t l_retLen = 0; + uint8_t l_size = getTotalPackages(); + if((i_index >= 0) && (i_index <= l_size)) + { + ffdc_package *l_ffdcPkg = iv_ffdcPackages.at(i_index); + l_retLen = l_ffdcPkg->size; + } + return l_retLen; +} + +/* + * @brief returns the pointer to the FFDC package + */ +void * SbeFFDCParser::getFFDCPackage(uint8_t i_index) +{ + void *l_retPtr = NULL; + uint8_t l_size = getTotalPackages(); + if((i_index >= 0) && (i_index <= l_size)) + { + l_retPtr = iv_ffdcPackages.at(i_index); + } + return l_retPtr; +} + +/* + * @brief returns the RC word + */ +uint32_t SbeFFDCParser::getPackageRC(uint8_t i_index) +{ + uint32_t l_retRc = 0; + uint8_t l_size = getTotalPackages(); + if((i_index >= 0) && (i_index <= l_size)) + { + ffdc_package *l_ffdcPkg = iv_ffdcPackages.at(i_index); + l_retRc = l_ffdcPkg->rc; + } + return l_retRc; +} + +/* + * @brief add ffdc package into the ffdc_package struct + * and push it to the list + */ +void SbeFFDCParser::addFFDCPackage(void * i_ffdcPackage, + uint32_t i_rc, uint8_t i_packageLen) +{ + ffdc_package * l_ffdcPkg = new ffdc_package(); + l_ffdcPkg->rc = i_rc; + l_ffdcPkg->size = i_packageLen; + + l_ffdcPkg->ffdcPtr = (void *) malloc(i_packageLen); + if(l_ffdcPkg->ffdcPtr == NULL) + { + SBE_TRACF(ERR_MRK"parseFFDCData: Failure to allocate memory: FFDC ptr."); + return; + } + memcpy((void *) l_ffdcPkg->ffdcPtr, i_ffdcPackage, i_packageLen); + iv_ffdcPackages.push_back(l_ffdcPkg); +} + +} diff --git a/src/usr/sbeio/sbe_fifodd.C b/src/usr/sbeio/sbe_fifodd.C index 9386ca255..fae31ec5d 100644 --- a/src/usr/sbeio/sbe_fifodd.C +++ b/src/usr/sbeio/sbe_fifodd.C @@ -36,9 +36,13 @@ #include <targeting/common/target.H> #include <targeting/common/targetservice.H> #include <sbeio/sbeioreasoncodes.H> +#include <errl/errlreasoncodes.H> #include "sbe_fifodd.H" -#include <initservice/initserviceif.H> //@todo-RTC:149454-Remove -#include <arch/ppc.H> +#include <sbeio/sbe_ffdc_parser.H> +#include <initservice/initserviceif.H> +#include <kernel/pagemgr.H> +#include <fapi2.H> +#include <error_info_defs.H> extern trace_desc_t* g_trac_sbeio; @@ -58,15 +62,38 @@ extern trace_desc_t* g_trac_sbeio; using namespace ERRORLOG; -//TODO RTC 149454 implement error recovery and ffdc - namespace SBEIO { +SbeFifo & SbeFifo::getTheInstance() +{ + return Singleton<SbeFifo>::instance(); +} + +/** + * @brief Constructor + */ +SbeFifo::SbeFifo() +{ + iv_ffdcPackageBuffer = PageManager::allocatePage(ffdcPackageSize, true); + initFFDCPackageBuffer(); +} + +/** + * @brief Destructor + */ +SbeFifo::~SbeFifo() +{ + if(iv_ffdcPackageBuffer != NULL) + { + PageManager::freePage(iv_ffdcPackageBuffer); + } +} + /** * @brief perform SBE PSU chip-op */ -errlHndl_t performFifoChipOp(TARGETING::Target * i_target, +errlHndl_t SbeFifo::performFifoChipOp(TARGETING::Target * i_target, uint32_t * i_pFifoRequest, uint32_t * i_pFifoResponse, uint32_t i_responseSize) @@ -96,8 +123,6 @@ errlHndl_t performFifoChipOp(TARGETING::Target * i_target, mutex_unlock(&l_fifoOpMux); - //@todo-RTC:149454-Remove when we have our FFDC in place - //Temporarily crash with a known RC so that HWSV collects the SBE FFDC if( errl && (SBE_COMP_ID == errl->moduleId()) ) { SBE_TRACF( "Forcing shutdown for FSP to collect FFDC" ); @@ -123,9 +148,6 @@ errlHndl_t performFifoChipOp(TARGETING::Target * i_target, SBEIO_HWSV_COLLECT_SBE_RC, orig_plid, TWO_UINT32_TO_UINT64(orig_rc,orig_mod)); - MAGIC_INST_GET_SBE_TRACES( - i_target->getAttr<TARGETING::ATTR_POSITION>(), - SBEIO_HWSV_COLLECT_SBE_RC); INITSERVICE::doShutdown( SBEIO_HWSV_COLLECT_SBE_RC ); } @@ -138,7 +160,7 @@ errlHndl_t performFifoChipOp(TARGETING::Target * i_target, /** * @brief write FIFO request message */ -errlHndl_t writeRequest(TARGETING::Target * i_target, +errlHndl_t SbeFifo::writeRequest(TARGETING::Target * i_target, uint32_t * i_pFifoRequest) { errlHndl_t errl = NULL; @@ -195,7 +217,7 @@ errlHndl_t writeRequest(TARGETING::Target * i_target, /** * @brief wait for room in upstream fifo to send data */ -errlHndl_t waitUpFifoReady(TARGETING::Target * i_target) +errlHndl_t SbeFifo::waitUpFifoReady(TARGETING::Target * i_target) { errlHndl_t errl = NULL; @@ -222,9 +244,6 @@ errlHndl_t waitUpFifoReady(TARGETING::Target * i_target) SBE_TRACF(ERR_MRK "waitUpFifoReady: " "timeout waiting for upstream FIFO to be not full"); - //TODO RTC 149454 implement error recovery and ffdc - // Consider a new callout for SBE problems. - /*@ * @errortype * @moduleid SBEIO_FIFO @@ -233,11 +252,7 @@ errlHndl_t waitUpFifoReady(TARGETING::Target * i_target) * @devdesc Timeout waiting for upstream FIFO to have * room to write */ - errl = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, - SBEIO_FIFO, - SBEIO_FIFO_UPSTREAM_TIMEOUT, - MAX_UP_FIFO_TIMEOUT_NS, - 0); + errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, HWAS::SRCI_PRIORITY_HIGH); errl->addHwCallout( i_target, @@ -245,9 +260,6 @@ errlHndl_t waitUpFifoReady(TARGETING::Target * i_target) HWAS::NO_DECONFIG, HWAS::GARD_NULL ); errl->collectTrace(SBEIO_COMP_NAME); - MAGIC_INST_GET_SBE_TRACES( - i_target->getAttr<TARGETING::ATTR_POSITION>(), - SBEIO_FIFO_UPSTREAM_TIMEOUT); break; } @@ -265,7 +277,7 @@ errlHndl_t waitUpFifoReady(TARGETING::Target * i_target) /** * @brief Read FIFO response messages */ -errlHndl_t readResponse(TARGETING::Target * i_target, +errlHndl_t SbeFifo::readResponse(TARGETING::Target * i_target, uint32_t * i_pFifoRequest, uint32_t * o_pFifoResponse, uint32_t i_responseSize) @@ -343,9 +355,6 @@ errlHndl_t readResponse(TARGETING::Target * i_target, SBE_TRACF(ERR_MRK "readResponse: no EOT cmd=0x%08x size=%d", i_pFifoRequest[1],i_responseSize); - //TODO RTC 149454 implement error recovery and ffdc - // Consider a new callout for SBE problems. - /*@ * @errortype * @moduleid SBEIO_FIFO @@ -359,6 +368,8 @@ errlHndl_t readResponse(TARGETING::Target * i_target, SBEIO_FIFO_NO_DOWNSTREAM_EOT, i_pFifoRequest[1], i_responseSize); + + errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, HWAS::SRCI_PRIORITY_HIGH); errl->addHwCallout( i_target, @@ -366,9 +377,6 @@ errlHndl_t readResponse(TARGETING::Target * i_target, HWAS::NO_DECONFIG, HWAS::GARD_NULL ); errl->collectTrace(SBEIO_COMP_NAME); - MAGIC_INST_GET_SBE_TRACES( - i_target->getAttr<TARGETING::ATTR_POSITION>(), - SBEIO_FIFO_NO_DOWNSTREAM_EOT); break; } @@ -396,9 +404,6 @@ errlHndl_t readResponse(TARGETING::Target * i_target, SBE_TRACFBIN("Invalid Response from SBE", o_pFifoResponse,l_recWords*sizeof(l_last)); - //TODO RTC 149454 implement error recovery and ffdc - // Consider a new callout for SBE problems. - /*@ * @errortype * @moduleid SBEIO_FIFO @@ -418,6 +423,7 @@ errlHndl_t readResponse(TARGETING::Target * i_target, TWO_UINT16_TO_UINT32(l_last, l_recWords*sizeof(uint32_t)), i_responseSize)); + errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, HWAS::SRCI_PRIORITY_HIGH); errl->addHwCallout( i_target, @@ -425,9 +431,6 @@ errlHndl_t readResponse(TARGETING::Target * i_target, HWAS::NO_DECONFIG, HWAS::GARD_NULL ); errl->collectTrace(SBEIO_COMP_NAME); - MAGIC_INST_GET_SBE_TRACES( - i_target->getAttr<TARGETING::ATTR_POSITION>(), - SBEIO_FIFO_INVALID_STATUS_DISTANCE); break; } @@ -447,12 +450,6 @@ errlHndl_t readResponse(TARGETING::Target * i_target, l_pStatusHeader->primaryStatus, l_pStatusHeader->secondaryStatus); - //TODO RTC 149454 implement error recovery and ffdc - // pibpcb status or ffdc follows the status header - // Might have different behavior for something messed up - // like !Magic versus bad status returned by the SBE in which - // case may be able to parse SBE RCs. - /*@ * @errortype * @moduleid SBEIO_FIFO @@ -465,6 +462,7 @@ errlHndl_t readResponse(TARGETING::Target * i_target, * @devdesc Status header does not start with magic number or * non-zero primary or secondary status */ + errl = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, SBEIO_FIFO, SBEIO_FIFO_RESPONSE_ERROR, @@ -474,6 +472,54 @@ errlHndl_t readResponse(TARGETING::Target * i_target, l_pStatusHeader->magic, l_pStatusHeader->primaryStatus, l_pStatusHeader->secondaryStatus)); + + /* + * The FFDC package should start at l_pReceived. + * Size of the FFDC package should be l_maxWords - l_recWords + */ + + writeFFDCBuffer(l_pReceived, + sizeof(uint32_t) * (l_maxWords - l_recWords - 1)); + SbeFFDCParser * l_ffdc_parser = new SbeFFDCParser(); + l_ffdc_parser->parseFFDCData(iv_ffdcPackageBuffer); + + // Go through the buffer, get the RC + uint8_t l_pkgs = l_ffdc_parser->getTotalPackages(); + for(uint8_t i = 0; i < l_pkgs; i++) + { + uint32_t l_rc = l_ffdc_parser->getPackageRC(i); + // If fapiRC, add data to errorlog + if(l_rc == fapi2::FAPI2_RC_PLAT_ERR_SEE_DATA) + { + errl->addFFDC( SBE_COMP_ID, + l_ffdc_parser->getFFDCPackage(i), + l_ffdc_parser->getPackageLength(i), + 0, + ERRORLOG::ERRL_UDT_NOFORMAT, + false ); + } + else + { + using namespace fapi2; + + fapi2::ReturnCode l_fapiRC; + + /* + * Put FFDC into sbeFfdc_t struct and + * call FAPI_SET_SBE_ERROR + */ + sbeFfdc_t * l_ffdcBuf = new sbeFfdc_t(); + l_ffdcBuf->size = l_ffdc_parser->getPackageLength(i); + l_ffdcBuf->data = reinterpret_cast<uint64_t>( + l_ffdc_parser->getFFDCPackage(i)); + + FAPI_SET_SBE_ERROR(l_fapiRC, + l_rc, + l_ffdcBuf, + i_target->getAttr<TARGETING::ATTR_FAPI_POS>()); + } + } + errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, HWAS::SRCI_PRIORITY_HIGH); errl->addHwCallout( i_target, @@ -481,9 +527,8 @@ errlHndl_t readResponse(TARGETING::Target * i_target, HWAS::NO_DECONFIG, HWAS::GARD_NULL ); errl->collectTrace(SBEIO_COMP_NAME); - MAGIC_INST_GET_SBE_TRACES( - i_target->getAttr<TARGETING::ATTR_POSITION>(), - SBEIO_FIFO_RESPONSE_ERROR); + + delete l_ffdc_parser; break; } } @@ -501,7 +546,7 @@ errlHndl_t readResponse(TARGETING::Target * i_target, * On return, either a valid word is ready to read, * or the EOT will be set in the returned doorbell status. */ -errlHndl_t waitDnFifoReady(TARGETING::Target * i_target, +errlHndl_t SbeFifo::waitDnFifoReady(TARGETING::Target * i_target, uint32_t & o_status) { errlHndl_t errl = NULL; @@ -536,8 +581,6 @@ errlHndl_t waitDnFifoReady(TARGETING::Target * i_target, SBE_TRACF(ERR_MRK "waitDnFifoReady: " "timeout waiting for downstream FIFO to be not full"); - //TODO RTC 149454 implement error recovery and ffdc - /*@ * @errortype * @moduleid SBEIO_FIFO @@ -546,11 +589,7 @@ errlHndl_t waitDnFifoReady(TARGETING::Target * i_target, * @devdesc Timeout waiting for downstream FIFO to have * data to receive */ - errl = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, - SBEIO_FIFO, - SBEIO_FIFO_DOWNSTREAM_TIMEOUT, - MAX_UP_FIFO_TIMEOUT_NS, - 0); + errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, HWAS::SRCI_PRIORITY_HIGH); errl->addHwCallout( i_target, @@ -558,9 +597,6 @@ errlHndl_t waitDnFifoReady(TARGETING::Target * i_target, HWAS::NO_DECONFIG, HWAS::GARD_NULL ); errl->collectTrace(SBEIO_COMP_NAME); - MAGIC_INST_GET_SBE_TRACES( - i_target->getAttr<TARGETING::ATTR_POSITION>(), - SBEIO_FIFO_DOWNSTREAM_TIMEOUT); break; } @@ -578,7 +614,7 @@ errlHndl_t waitDnFifoReady(TARGETING::Target * i_target, /** * @brief read FSI */ -errlHndl_t readFsi(TARGETING::Target * i_target, +errlHndl_t SbeFifo::readFsi(TARGETING::Target * i_target, uint64_t i_addr, uint32_t * o_pData) { @@ -600,7 +636,7 @@ errlHndl_t readFsi(TARGETING::Target * i_target, /** * @brief write FSI */ -errlHndl_t writeFsi(TARGETING::Target * i_target, +errlHndl_t SbeFifo::writeFsi(TARGETING::Target * i_target, uint64_t i_addr, uint32_t * i_pData) { @@ -618,4 +654,31 @@ errlHndl_t writeFsi(TARGETING::Target * i_target, return errl; } +/** + * @brief zero out FFDC Package Buffer + */ + +void SbeFifo::initFFDCPackageBuffer() +{ + memset(iv_ffdcPackageBuffer, 0x00, PAGESIZE * ffdcPackageSize); +} + +/** + * @brief populate FFDC package buffer + * @param[in] i_data FFDC error data + * @param[in] i_len data buffer len to copy + */ +void SbeFifo::writeFFDCBuffer( void * i_data, uint32_t i_len) { + if(i_len <= PAGESIZE * ffdcPackageSize) + { + initFFDCPackageBuffer(); + memcpy(iv_ffdcPackageBuffer, i_data, i_len); + } + else + { + SBE_TRACF(ERR_MRK"writeFFDCBuffer: Buffer size too large: %d", + i_len); + } +} + } //end of namespace SBEIO diff --git a/src/usr/sbeio/sbe_fifodd.H b/src/usr/sbeio/sbe_fifodd.H index e9ccb7e84..ee4b8e30f 100644 --- a/src/usr/sbeio/sbe_fifodd.H +++ b/src/usr/sbeio/sbe_fifodd.H @@ -36,6 +36,7 @@ #include <sys/time.h> #include <errl/errlentry.H> +#include <util/singleton.H> namespace SBEIO { @@ -45,359 +46,418 @@ namespace SBEIO // within this component. //----------------------------------------------------------------------------- - /** - * @brief enums for SBE command class - */ - enum fifoCommandClass - { - SBE_FIFO_CLASS_UNKNOWN = 0, - SBE_FIFO_CLASS_IPL_CONTROL = 0xA1, - SBE_FIFO_CLASS_SCOM_ACCESS = 0xA2, - SBE_FIFO_CLASS_RING_ACCESS = 0xA3, - SBE_FIFO_CLASS_MEMORY_ACCESS = 0xA4, - SBE_FIFO_CLASS_REGISTER_ACCESS = 0xA5, - SBE_FIFO_CLASS_ARRAY_ACCESS = 0xA6, - SBE_FIFO_CLASS_INSTRUCTION_CONTROL = 0xA7, - SBE_FIFO_CLASS_GENERIC_MESSAGE = 0xA8, - SBE_FIFO_CLASS_MPIPL_COMMANDS = 0xA9, - }; - - /** - * @brief enums for FIFO SCOM Access Messages - */ - enum fifoScomAccessMessage - { - SBE_FIFO_CMD_GET_SCOM = 0x01, - SBE_FIFO_CMD_PUT_SCOM = 0x02, - SBE_FIFO_CMD_MODIFY_SCOM = 0x03, - SBE_FIFO_CMD_PUT_SCOM_UNDER_MASK = 0x04, - }; - - /** - * @brief Struct for FIFO Get SCOM request - * - */ - struct fifoGetScomRequest - { - uint32_t wordCnt; - uint16_t reserved; - uint8_t commandClass; - uint8_t command; - uint64_t address; // Register Address (0..31) + (32..63) - fifoGetScomRequest() : - wordCnt(4), - reserved(0) +/** @class SbeFifo + * * @brief Class for SBE/PSU communication + * */ + +class SbeFifo +{ + public: + + /** + * @brief get the instance of this class + * + * @return the (one and only) instance of SbeFifo + */ + + static SbeFifo & getTheInstance(); + + /** + * @brief enums for SBE command class + */ + enum fifoCommandClass + { + SBE_FIFO_CLASS_UNKNOWN = 0, + SBE_FIFO_CLASS_IPL_CONTROL = 0xA1, + SBE_FIFO_CLASS_SCOM_ACCESS = 0xA2, + SBE_FIFO_CLASS_RING_ACCESS = 0xA3, + SBE_FIFO_CLASS_MEMORY_ACCESS = 0xA4, + SBE_FIFO_CLASS_REGISTER_ACCESS = 0xA5, + SBE_FIFO_CLASS_ARRAY_ACCESS = 0xA6, + SBE_FIFO_CLASS_INSTRUCTION_CONTROL = 0xA7, + SBE_FIFO_CLASS_GENERIC_MESSAGE = 0xA8, + SBE_FIFO_CLASS_MPIPL_COMMANDS = 0xA9, + }; + + /** + * @brief enums for FIFO SCOM Access Messages + */ + enum fifoScomAccessMessage + { + SBE_FIFO_CMD_GET_SCOM = 0x01, + SBE_FIFO_CMD_PUT_SCOM = 0x02, + SBE_FIFO_CMD_MODIFY_SCOM = 0x03, + SBE_FIFO_CMD_PUT_SCOM_UNDER_MASK = 0x04, + }; + + /** + * @brief Struct for FIFO Get SCOM request + * + */ + struct fifoGetScomRequest + { + uint32_t wordCnt; + uint16_t reserved; + uint8_t commandClass; + uint8_t command; + uint64_t address; // Register Address (0..31) + (32..63) + fifoGetScomRequest() : + wordCnt(4), + reserved(0) + { + } + } PACKED; + + /** + * @brief Struct for FIFO Put SCOM request + * + */ + struct fifoPutScomRequest + { + uint32_t wordCnt; + uint16_t reserved; + uint8_t commandClass; + uint8_t command; + uint64_t address; // Register Address (0..31) + (32..63) + uint64_t data; // Data (0..31) + (32..63) + fifoPutScomRequest() : + wordCnt(6), + reserved(0), + data(0) + { + } + } PACKED; + + /** + * @brief Struct for FIFO Put SCOM Under Mask request + * + */ + struct fifoPutScomUnderMaskRequest + { + uint32_t wordCnt; + uint16_t reserved; + uint8_t commandClass; + uint8_t command; + uint64_t address; // Register Address (0..31) + (32..63) + uint64_t data; // Data (0..31) + (32..63) + uint64_t mask; // Mask Data (0..31) + (32..63) + fifoPutScomUnderMaskRequest() : + wordCnt(8), + reserved(0), + data(0), + mask(0) + { + } + } PACKED; + + /** + * @brief Struct for FIFO status + * + */ + struct statusHeader + { + uint16_t magic; // set to 0xC0DE + uint8_t commandClass; + uint8_t command; + uint16_t primaryStatus; + uint16_t secondaryStatus; + } PACKED; + const uint16_t FIFO_STATUS_MAGIC = 0xC0DE; + + /** + * @brief Struct for FIFO Put SCOM and Put SCOM under mask response + * + * The actual number of returned words varies based on whether there was + * an error. + */ + struct fifoPutScomResponse + { + statusHeader status; + uint32_t pcbpibStatus; // only present on errors + // ffdc will go here on errors + uint32_t status_distance; // distance to status + uint32_t EOT; // dummy EOT word to ignore + fifoPutScomResponse() {} + } PACKED; + + /** + * @brief Struct for FIFO Get SCOM response + * + * The actual number of returned words varies based on whether there was + * an error. + */ + struct fifoGetScomResponse { - } - } PACKED; - - /** - * @brief Struct for FIFO Put SCOM request - * - */ - struct fifoPutScomRequest - { - uint32_t wordCnt; - uint16_t reserved; - uint8_t commandClass; - uint8_t command; - uint64_t address; // Register Address (0..31) + (32..63) - uint64_t data; // Data (0..31) + (32..63) - fifoPutScomRequest() : - wordCnt(6), - reserved(0), - data(0) + uint64_t data; // Data (0..31) + (32..63) + statusHeader status; + uint32_t pcbpibStatus; // only present on errors + // ffdc will go here on errors + uint32_t status_distance; // distance to status + uint32_t EOT; // dummy EOT word to ignore + fifoGetScomResponse() {} + } PACKED; + + /** + * @brief enums for primary SBE response + * + */ + enum sbePrimResponse { - } - } PACKED; - - /** - * @brief Struct for FIFO Put SCOM Under Mask request - * - */ - struct fifoPutScomUnderMaskRequest - { - uint32_t wordCnt; - uint16_t reserved; - uint8_t commandClass; - uint8_t command; - uint64_t address; // Register Address (0..31) + (32..63) - uint64_t data; // Data (0..31) + (32..63) - uint64_t mask; // Mask Data (0..31) + (32..63) - fifoPutScomUnderMaskRequest() : - wordCnt(8), - reserved(0), - data(0), - mask(0) + FIFO_PRI_OPERATION_SUCCESSFUL = 0x00, + FIFO_PRI_INVALID_COMMAND = 0x01, + FIFO_PRI_INVALID_DATA = 0x02, + FIFO_PRI_SEQUENCE_ERROR = 0x03, + FIFO_PRI_INTERNAL_ERROR = 0x04, + FIFO_PRI_GENERIC_EXECUTION_FAILURE = 0xFE, + }; + + /** + * @brief enums for secondary SBE response + * + */ + enum sbeSecondaryResponse { - } - } PACKED; - - /** - * @brief Struct for FIFO status - * - */ - struct statusHeader - { - uint16_t magic; // set to 0xC0DE - uint8_t commandClass; - uint8_t command; - uint16_t primaryStatus; - uint16_t secondaryStatus; - } PACKED; - const uint16_t FIFO_STATUS_MAGIC = 0xC0DE; - - /** - * @brief Struct for FIFO Put SCOM and Put SCOM under mask response - * - * The actual number of returned words varies based on whether there was - * an error. - */ - struct fifoPutScomResponse - { - statusHeader status; - uint32_t pcbpibStatus; // only present on errors - // ffdc will go here on errors - uint32_t status_distance; // distance to status - uint32_t EOT; // dummy EOT word to ignore - fifoPutScomResponse() {} - } PACKED; - - /** - * @brief Struct for FIFO Get SCOM response - * - * The actual number of returned words varies based on whether there was - * an error. - */ - struct fifoGetScomResponse - { - uint64_t data; // Data (0..31) + (32..63) - statusHeader status; - uint32_t pcbpibStatus; // only present on errors - // ffdc will go here on errors - uint32_t status_distance; // distance to status - uint32_t EOT; // dummy EOT word to ignore - fifoGetScomResponse() {} - } PACKED; - - /** - * @brief enums for primary SBE response - * - */ - enum sbePrimResponse - { - FIFO_PRI_OPERATION_SUCCESSFUL = 0x00, - FIFO_PRI_INVALID_COMMAND = 0x01, - FIFO_PRI_INVALID_DATA = 0x02, - FIFO_PRI_SEQUENCE_ERROR = 0x03, - FIFO_PRI_INTERNAL_ERROR = 0x04, - FIFO_PRI_GENERIC_EXECUTION_FAILURE = 0xFE, - }; - - /** - * @brief enums for secondary SBE response - * - */ - enum sbeSecondaryResponse - { - FIFO_SEC_OPERATION_SUCCESSFUL = 0x00, - FIFO_SEC_COMMAND_CLASS_NOT_SUPPORTED = 0x01, - FIFO_SEC_COMMAND_NOT_SUPPORTED = 0x02, - FIFO_SEC_INVALID_ADDRESS_PASSED = 0x03, - FIFO_SEC_INVALID_TARGET_TYPE_PASSED = 0x04, - FIFO_SEC_INVALID_TARGET_ID_PASSED = 0x05, - FIFO_SEC_SPECIFIED_TARGET_NOT_PRESENT = 0x06, - FIFO_SEC_SPECIFIED_TARGET_NOT_FUNCTIONAL = 0x07, - FIFO_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE = 0x08, - FIFO_SEC_FUNCTIONALITY_NOT_SUPPORTED = 0x09, - FIFO_SEC_GENERIC_FAILURE_IN_EXECUTION = 0x0A, - FIFO_SEC_BACKLISTED_ACCESS = 0x0B, - FIFO_SEC_OS_FAILURE = 0x0C, - FIFO_SEC_FIFO_ACCESS_FAILURE = 0x0D, - FIFO_SEC_INSUFFICIENT_DATA_PASSED = 0x0E, - FIFO_SEC_EXCESS_DATA_PASSED = 0x0F, - }; - - /** - * @Brief perform SBE FIFO chip-op - * - * @param[in] i_target Target to access - * @param[in] i_pFifoRequest Pointer to request - * @param[in] i_pFifoResponse Pointer to response - * @param[in] i_responseSize Size of response in bytes - * - * @return errlHndl_t Error log handle on failure. - */ - errlHndl_t performFifoChipOp(TARGETING::Target * i_target, - uint32_t * i_pFifoRequest, - uint32_t * i_pFifoResponse, - uint32_t i_responseSize); + FIFO_SEC_OPERATION_SUCCESSFUL = 0x00, + FIFO_SEC_COMMAND_CLASS_NOT_SUPPORTED = 0x01, + FIFO_SEC_COMMAND_NOT_SUPPORTED = 0x02, + FIFO_SEC_INVALID_ADDRESS_PASSED = 0x03, + FIFO_SEC_INVALID_TARGET_TYPE_PASSED = 0x04, + FIFO_SEC_INVALID_TARGET_ID_PASSED = 0x05, + FIFO_SEC_SPECIFIED_TARGET_NOT_PRESENT = 0x06, + FIFO_SEC_SPECIFIED_TARGET_NOT_FUNCTIONAL = 0x07, + FIFO_SEC_COMMAND_NOT_ALLOWED_IN_THIS_STATE = 0x08, + FIFO_SEC_FUNCTIONALITY_NOT_SUPPORTED = 0x09, + FIFO_SEC_GENERIC_FAILURE_IN_EXECUTION = 0x0A, + FIFO_SEC_BACKLISTED_ACCESS = 0x0B, + FIFO_SEC_OS_FAILURE = 0x0C, + FIFO_SEC_FIFO_ACCESS_FAILURE = 0x0D, + FIFO_SEC_INSUFFICIENT_DATA_PASSED = 0x0E, + FIFO_SEC_EXCESS_DATA_PASSED = 0x0F, + }; + + /** + * @Brief perform SBE FIFO chip-op + * + * @param[in] i_target Target to access + * @param[in] i_pFifoRequest Pointer to request + * @param[in] i_pFifoResponse Pointer to response + * @param[in] i_responseSize Size of response in bytes + * + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t performFifoChipOp(TARGETING::Target * i_target, + uint32_t * i_pFifoRequest, + uint32_t * i_pFifoResponse, + uint32_t i_responseSize); + + + protected: + + /** + * @Brief Constructor + */ + + SbeFifo(); + + /** + * @Brief Destructor + */ + + ~SbeFifo(); + + /** + * @brief populate the iv_ffdcPackageBuffer + * @param[in] i_data FFDC error data + * @param[in] i_len data buffer len to copy + */ + + void writeFFDCBuffer(void * i_data, uint32_t i_len); + + private: + + /** + * @brief Write FFDC package buffer - holds information exchanged + * between SBE and HB + */ + void * iv_ffdcPackageBuffer; + + /** + * @brief FFDC package needs to be 2 pages + */ + const uint8_t ffdcPackageSize = 2; + + /** + * @brief zero out the FFDC package buffer + */ + void initFFDCPackageBuffer(); + + //------------------------------------------------------------------- + // Local definitions for the device driver + //------------------------------------------------------------------- + + /** + * @brief send a request via SBE FIFO + * + * @param[in] i_target Target to access + * @param[in] i_pFifoRequest Pointer to FIFO request. + * First word has count of unit32_t words. + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t writeRequest(TARGETING::Target * i_target, + uint32_t * i_pFifoRequest); + + /** + * @brief read the response via SBE FIFO + * + * @param[in] i_target Target to access + * @param[in] i_pFifoRequest Pointer to FIFO request. + * @param[out] o_pFifoResponse Pointer to FIFO response. + * @param[in] i_responseSize Size of response buffer in bytes. + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t readResponse(TARGETING::Target * i_target, + uint32_t * i_pFifoRequest, + uint32_t * o_pFifoResponse, + uint32_t i_responseSize); + + /** + * @brief poll until uplift Fifo has room to write into + * + * @param[in] i_target Target to access + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t waitUpFifoReady(TARGETING::Target * i_target); + + /** + * @brief poll until downlift Fifo has a value to read + * or has hit EOT. + * + * @param[in] i_target Target to access + * @param[out] o_status Down load door bell status + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t waitDnFifoReady(TARGETING::Target * i_target, + uint32_t & o_status); + + /** + * @brief encapulate FSI read + * + * @param[in] i_target Target to access + * @param[in] i_addr FSI addressd + * @param[out] o_pData Pointer to receive data + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t readFsi(TARGETING::Target * i_target, + uint64_t i_addr, + uint32_t * o_pData); + /** + * @brief encapulate FSI write + * + * @param[in] i_target Target to access + * @param[in] i_addr FSI addressd + * @param[in] i_pData Pointer to receive data + * @return errlHndl_t Error log handle on failure. + */ + errlHndl_t writeFsi(TARGETING::Target * i_target, + uint64_t i_addr, + uint32_t * i_pData); + + /** + * @brief SBE FIFO FSI register addresses + */ + enum fifoRegisterAddress + { + SBE_FIFO_UPFIFO_DATA_IN = 0x00002400, + SBE_FIFO_UPFIFO_STATUS = 0x00002404, + SBE_FIFO_UPFIFO_SIG_EOT = 0x00002408, + SBE_FIFO_UPFIFO_REQ_RESET = 0x0000240C, + SBE_FIFO_DNFIFO_DATA_OUT = 0x00002440, + SBE_FIFO_DNFIFO_STATUS = 0x00002444, + SBE_FIFO_DNFIFO_RESET = 0x00002450, + SBE_FIFO_DNFIFO_ACK_EOT = 0x00002454, + SBE_FIFO_DNFIFO_MAX_TSFR = 0x00002458, + }; + + enum sbeFifoUpstreamStatus + { + // Reserved + UPFIFO_STATUS_RESERVED0 =0xC0000000, + // Parity Error: dequeuing operation has detected a data parity error + UPFIFO_STATUS_PARITY_ERROR =0x20000000, + // Reserved + UPFIFO_STATUS_RESERVED3 =0x1C000000, + // External Service Processor (SP) is requesting a FIFO reset + UPFIFO_STATUS_REQ_RESET_FR_SP =0x02000000, + // SBE is requesting a FIFO reset through downstream path + UPFIFO_STATUS_REQ_RESET_FR_SBE =0x01000000, + // A fifo entry has been dequeued with set EOT flag + UPFIFO_STATUS_DEQUEUED_EOT_FLAG =0x00800000, + // Reserved + UPFIFO_STATUS_RESERVED9 =0x00400000, + // Upstream FIFO is full + UPFIFO_STATUS_FIFO_FULL =0x00200000, + // Upstream FIFO is empty + UPFIFO_STATUS_FIFO_EMPTY =0x00100000, + // Number of entries currently in FIFO + UPFIFO_STATUS_FIFO_ENTRY_COUNT =0x000F0000, + // Valid flags of entries currently in FIFO + UPFIFO_STATUS_FIFO_VALID_FLAGS =0x0000FF00, + // EOT flags of entries currently in FIFO + UPFIFO_STATUS_FIFO_EOT_FLAGS =0x000000FF, + }; + + enum sbeUpstreamEot + { + FSB_UPFIFO_SIG_EOT =0x80000000, + }; -//----------------------------------------------------------------------------- -// Local definitions for the device driver -//----------------------------------------------------------------------------- + enum sbeFifoReqUpstreamFifoReset + { + FSB_UPFIFO_REQ_RESET =0x80000000, + }; + + enum sbeFifoDownstreamStatus + { + // Reserved + DNFIFO_STATUS_RESERVED0 =0xC0000000, + // Parity Error: dequeuing operation has detected a data parity error + DNFIFO_STATUS_PARITY_ERROR =0x20000000, + // Reserved + DNFIFO_STATUS_RESERVED3 =0x1C000000, + // SBE is requesting a FIFO reset + DNFIFO_STATUS_REQ_RESET_FR_SP =0x02000000, + // Service Processor (SP) is requesting a FIFO reset + // through downstream path + DNFIFO_STATUS_REQ_RESET_FR_SBE =0x01000000, + // A fifo entry has been dequeued with set EOT flag + DNFIFO_STATUS_DEQUEUED_EOT_FLAG =0x00800000, + // Reserved + DNFIFO_STATUS_RESERVED9 =0x00400000, + // Downstream FIFO is full + DNFIFO_STATUS_FIFO_FULL =0x00200000, + // Downstream FIFO is empty + DNFIFO_STATUS_FIFO_EMPTY =0x00100000, + // Number of currently hold entries + DNFIFO_STATUS_FIFO_ENTRY_COUNT =0x000F0000, + // Valid flags of ALL currently hold entries + DNFIFO_STATUS_FIFO_VALID_FLAGS =0x0000FF00, + // EOT flags of ALL currently hold entries + DNFIFO_STATUS_FIFO_EOT_FLAGS =0x000000FF, + }; + + enum sbeFifoReqDownstreamFifoReset + { + FSB_DNFIFO_REQ_RESET =0x80000000, + }; + + enum sbeDownstreamEot + { + FSB_DNFIFO_ACK_EOT =0x80000000, + }; + + enum { MAX_UP_FIFO_TIMEOUT_NS = 10*NS_PER_MSEC }; //=10ms - /** - * @brief send a request via SBE FIFO - * - * @param[in] i_target Target to access - * @param[in] i_pFifoRequest Pointer to FIFO request. - * First word has count of unit32_t words. - * @return errlHndl_t Error log handle on failure. - */ - errlHndl_t writeRequest(TARGETING::Target * i_target, - uint32_t * i_pFifoRequest); - - /** - * @brief read the response via SBE FIFO - * - * @param[in] i_target Target to access - * @param[in] i_pFifoRequest Pointer to FIFO request. - * @param[out] o_pFifoResponse Pointer to FIFO response. - * @param[in] i_responseSize Size of response buffer in bytes. - * @return errlHndl_t Error log handle on failure. - */ - errlHndl_t readResponse(TARGETING::Target * i_target, - uint32_t * i_pFifoRequest, - uint32_t * o_pFifoResponse, - uint32_t i_responseSize); - - /** - * @brief poll until uplift Fifo has room to write into - * - * @param[in] i_target Target to access - * @return errlHndl_t Error log handle on failure. - */ - errlHndl_t waitUpFifoReady(TARGETING::Target * i_target); - - /** - * @brief poll until downlift Fifo has a value to read - * or has hit EOT. - * - * @param[in] i_target Target to access - * @param[out] o_status Down load door bell status - * @return errlHndl_t Error log handle on failure. - */ - errlHndl_t waitDnFifoReady(TARGETING::Target * i_target, - uint32_t & o_status); - - /** - * @brief encapulate FSI read - * - * @param[in] i_target Target to access - * @param[in] i_addr FSI addressd - * @param[out] o_pData Pointer to receive data - * @return errlHndl_t Error log handle on failure. - */ - errlHndl_t readFsi(TARGETING::Target * i_target, - uint64_t i_addr, - uint32_t * o_pData); - /** - * @brief encapulate FSI write - * - * @param[in] i_target Target to access - * @param[in] i_addr FSI addressd - * @param[in] i_pData Pointer to receive data - * @return errlHndl_t Error log handle on failure. - */ - errlHndl_t writeFsi(TARGETING::Target * i_target, - uint64_t i_addr, - uint32_t * i_pData); - - /** - * @brief SBE FIFO FSI register addresses - */ - enum fifoRegisterAddress - { - SBE_FIFO_UPFIFO_DATA_IN = 0x00002400, - SBE_FIFO_UPFIFO_STATUS = 0x00002404, - SBE_FIFO_UPFIFO_SIG_EOT = 0x00002408, - SBE_FIFO_UPFIFO_REQ_RESET = 0x0000240C, - SBE_FIFO_DNFIFO_DATA_OUT = 0x00002440, - SBE_FIFO_DNFIFO_STATUS = 0x00002444, - SBE_FIFO_DNFIFO_RESET = 0x00002450, - SBE_FIFO_DNFIFO_ACK_EOT = 0x00002454, - SBE_FIFO_DNFIFO_MAX_TSFR = 0x00002458, - }; - - enum sbeFifoUpstreamStatus - { - // Reserved - UPFIFO_STATUS_RESERVED0 =0xC0000000, - // Parity Error: dequeuing operation has detected a data parity error - UPFIFO_STATUS_PARITY_ERROR =0x20000000, - // Reserved - UPFIFO_STATUS_RESERVED3 =0x1C000000, - // External Service Processor (SP) is requesting a FIFO reset - UPFIFO_STATUS_REQ_RESET_FR_SP =0x02000000, - // SBE is requesting a FIFO reset through downstream path - UPFIFO_STATUS_REQ_RESET_FR_SBE =0x01000000, - // A fifo entry has been dequeued with set EOT flag - UPFIFO_STATUS_DEQUEUED_EOT_FLAG =0x00800000, - // Reserved - UPFIFO_STATUS_RESERVED9 =0x00400000, - // Upstream FIFO is full - UPFIFO_STATUS_FIFO_FULL =0x00200000, - // Upstream FIFO is empty - UPFIFO_STATUS_FIFO_EMPTY =0x00100000, - // Number of entries currently in FIFO - UPFIFO_STATUS_FIFO_ENTRY_COUNT =0x000F0000, - // Valid flags of entries currently in FIFO - UPFIFO_STATUS_FIFO_VALID_FLAGS =0x0000FF00, - // EOT flags of entries currently in FIFO - UPFIFO_STATUS_FIFO_EOT_FLAGS =0x000000FF, - }; - - enum sbeUpstreamEot - { - FSB_UPFIFO_SIG_EOT =0x80000000, - }; - - enum sbeFifoReqUpstreamFifoReset - { - FSB_UPFIFO_REQ_RESET =0x80000000, - }; - - enum sbeFifoDownstreamStatus - { - // Reserved - DNFIFO_STATUS_RESERVED0 =0xC0000000, - // Parity Error: dequeuing operation has detected a data parity error - DNFIFO_STATUS_PARITY_ERROR =0x20000000, - // Reserved - DNFIFO_STATUS_RESERVED3 =0x1C000000, - // SBE is requesting a FIFO reset - DNFIFO_STATUS_REQ_RESET_FR_SP =0x02000000, - // Service Processor (SP) is requesting a FIFO reset - // through downstream path - DNFIFO_STATUS_REQ_RESET_FR_SBE =0x01000000, - // A fifo entry has been dequeued with set EOT flag - DNFIFO_STATUS_DEQUEUED_EOT_FLAG =0x00800000, - // Reserved - DNFIFO_STATUS_RESERVED9 =0x00400000, - // Downstream FIFO is full - DNFIFO_STATUS_FIFO_FULL =0x00200000, - // Downstream FIFO is empty - DNFIFO_STATUS_FIFO_EMPTY =0x00100000, - // Number of currently hold entries - DNFIFO_STATUS_FIFO_ENTRY_COUNT =0x000F0000, - // Valid flags of ALL currently hold entries - DNFIFO_STATUS_FIFO_VALID_FLAGS =0x0000FF00, - // EOT flags of ALL currently hold entries - DNFIFO_STATUS_FIFO_EOT_FLAGS =0x000000FF, - }; - - enum sbeFifoReqDownstreamFifoReset - { - FSB_DNFIFO_REQ_RESET =0x80000000, - }; - - enum sbeDownstreamEot - { - FSB_DNFIFO_ACK_EOT =0x80000000, - }; - - enum { MAX_UP_FIFO_TIMEOUT_NS = 10*NS_PER_MSEC }; //=10ms +}; // End of classSbeFifo } diff --git a/src/usr/sbeio/sbe_psudd.C b/src/usr/sbeio/sbe_psudd.C index f1e200c34..ef1e78fa8 100644 --- a/src/usr/sbeio/sbe_psudd.C +++ b/src/usr/sbeio/sbe_psudd.C @@ -40,8 +40,8 @@ #include <sbeio/sbeioreasoncodes.H> #include <initservice/initserviceif.H> //@todo-RTC:149454-Remove #include <sbeio/sbe_psudd.H> +#include <sbeio/sbe_ffdc_parser.H> #include <arch/ppc.H> -#include <util/utilbyte.H> #include <kernel/pagemgr.H> trace_desc_t* g_trac_sbeio; @@ -253,13 +253,28 @@ errlHndl_t SbePsu::writeRequest(TARGETING::Target * i_target, i_pPsuRequest->mbxReg0, l_data); - handleFFDCError(errl); + SbeFFDCParser * l_ffdc_parser = new SbeFFDCParser(); + l_ffdc_parser->parseFFDCData(iv_ffdcPackageBuffer); + uint8_t l_pkgs = l_ffdc_parser->getTotalPackages(); + uint8_t i; + for(i = 0; i < l_pkgs; i++) + { + errl->addFFDC( SBE_COMP_ID, + l_ffdc_parser->getFFDCPackage(i), + l_ffdc_parser->getPackageLength(i), + 0, // version + ERRORLOG::ERRL_UDT_NOFORMAT, // subversion + false ); + } + errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, HWAS::SRCI_PRIORITY_HIGH); errl->collectTrace(SBEIO_COMP_NAME); MAGIC_INST_GET_SBE_TRACES( i_target->getAttr<TARGETING::ATTR_POSITION>(), SBEIO_PSU_NOT_READY); + + delete l_ffdc_parser; break; // return with error } @@ -372,13 +387,28 @@ errlHndl_t SbePsu::readResponse(TARGETING::Target * i_target, i_pPsuRequest->mbxReg0, o_pPsuResponse->mbxReg4); - handleFFDCError(errl); + SbeFFDCParser * l_ffdc_parser = new SbeFFDCParser(); + l_ffdc_parser->parseFFDCData(iv_ffdcPackageBuffer); + uint8_t l_pkgs = l_ffdc_parser->getTotalPackages(); + uint8_t i; + for(i = 0; i < l_pkgs; i++) + { + errl->addFFDC( SBE_COMP_ID, + l_ffdc_parser->getFFDCPackage(i), + l_ffdc_parser->getPackageLength(i), + 0, // version + ERRORLOG::ERRL_UDT_NOFORMAT, // subversion + false ); + } + errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, HWAS::SRCI_PRIORITY_HIGH); errl->collectTrace(SBEIO_COMP_NAME); MAGIC_INST_GET_SBE_TRACES( i_target->getAttr<TARGETING::ATTR_POSITION>(), SBEIO_PSU_RESPONSE_ERROR); + + delete l_ffdc_parser; break; } @@ -437,13 +467,28 @@ errlHndl_t SbePsu::pollForPsuComplete(TARGETING::Target * i_target, i_timeout, 0); - handleFFDCError(errl); + SbeFFDCParser * l_ffdc_parser = new SbeFFDCParser(); + l_ffdc_parser->parseFFDCData(iv_ffdcPackageBuffer); + uint8_t l_pkgs = l_ffdc_parser->getTotalPackages(); + uint8_t i; + for(i = 0; i < l_pkgs; i++) + { + errl->addFFDC( SBE_COMP_ID, + l_ffdc_parser->getFFDCPackage(i), + l_ffdc_parser->getPackageLength(i), + 0, // version + ERRORLOG::ERRL_UDT_NOFORMAT, // subversion + false ); + } + errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, HWAS::SRCI_PRIORITY_HIGH); errl->collectTrace(SBEIO_COMP_NAME); MAGIC_INST_GET_SBE_TRACES( i_target->getAttr<TARGETING::ATTR_POSITION>(), SBEIO_PSU_RESPONSE_TIMEOUT); + + delete l_ffdc_parser; break; } @@ -541,104 +586,4 @@ void SbePsu::writeFFDCBuffer( void * i_data, uint8_t i_len) { } } -/** - * @brief Read FFDC package(s) iv_ffdcPackageBuffer - * - * @param[in] io_errl Error entry object to inject FFDC errors - * - * FFDC package according to the SBE Interface Specification: - * Dword 0: - * byte 0,1: Magic Byte: 0xFFDC - * byte 2,3: Length in words (N + 6) - * byte 4,5: Sequence Id - * byte 6 : Command Class - * byte 7 : Command - * Dword 1: - * byte 0-3: Return Code - * byte 4-7: Word 0 - * Dword M: - * byte 0-3: Word N - 1 - * byte 4-7: Word N - */ - -bool SbePsu::handleFFDCError(ERRORLOG::ErrlEntry * io_errl) -{ - uint16_t l_magicByte = 0x00; - uint8_t i = 0; - bool rc = true; - - SBE_TRACD(ENTER_MRK "handleFFDCError"); - do { - // Magic Byte is 1st 2 bytes - l_magicByte = UtilByte::bufferTo16uint( - static_cast<char *>(iv_ffdcPackageBuffer) + i); - - if(l_magicByte == ffdcMagicByte) - { - // Length is next 2 bytes (in words, each word is 4 bytes) - uint16_t l_packageLen = UtilByte::bufferTo16uint( - static_cast<char *>(iv_ffdcPackageBuffer) + (i + 2)); - // In FFDC packet, byte 2 & byte 3 holds the length in words, - // which is 6 bytes less than the total package length. - uint8_t l_words = l_packageLen - ffdcPadLen; - uint8_t l_wordLen = ffdcWordLen * l_words; - SBE_TRACD(INFO_MRK"handleFFDCError: Package length: %d, Words: %d", l_packageLen, l_words); - - // Check to see if what we're copying is beyond the buffer size - if((uint8_t) (i + wordPadding + l_wordLen) > - PAGESIZE * ffdcPackageSize) - { - SBE_TRACF(ERR_MRK"handleFFDCError: FFDC Package buffer overflow detected."); - rc = false; - break; - } - else - { - // Extract the words and add to errl - void * l_wordBuffer = (void *) malloc(l_wordLen); - if(l_wordBuffer == NULL) - { - SBE_TRACF(ERR_MRK"handleFFDCError: Failure to allocate memory."); - rc = false; - break; - } - // Copy data from ffdcPackageBuffer to wordBuffer - // starting at 12th byte from current pointer - memcpy(static_cast<char *>(iv_ffdcPackageBuffer) + wordPadding, - l_wordBuffer, l_wordLen); - - ErrlUD *l_errlud = io_errl->addFFDC( SBE_COMP_ID, - l_wordBuffer, - sizeof(l_wordBuffer), - 0, // version - ERRL_UDT_NOFORMAT, // subversion - false ); - - if(l_errlud == NULL) - { - SBE_TRACF(ERR_MRK"handleFFDCError: Failure to add FFDC to error log."); - rc = false; - } - - free(l_wordBuffer); - } - // Skip length of whole package - i += l_wordLen + wordPadding; - } - else - { - SBE_TRACD(ERR_MRK"handleFFDCError: Invalid FFDC Magic Byte: 0x%04lx", - l_magicByte); - break; - } - } while (l_magicByte != 0x00); - - // zero out the whole thing - initFFDCPackageBuffer(); - - SBE_TRACD(EXIT_MRK "handleFFDCError"); - return rc; - -} - } //end of namespace SBEIO diff --git a/src/usr/sbeio/sbe_scomAccess.C b/src/usr/sbeio/sbe_scomAccess.C index 44c1ac37f..8d013799c 100644 --- a/src/usr/sbeio/sbe_scomAccess.C +++ b/src/usr/sbeio/sbe_scomAccess.C @@ -153,19 +153,19 @@ errlHndl_t getFifoScom(TARGETING::Target * i_target, if (errl) break; // set up FIFO request message - fifoGetScomRequest l_fifoRequest; - fifoGetScomResponse l_fifoResponse; - l_fifoRequest.commandClass = SBE_FIFO_CLASS_SCOM_ACCESS; - l_fifoRequest.command = SBE_FIFO_CMD_GET_SCOM; + SbeFifo::fifoGetScomRequest l_fifoRequest; + SbeFifo::fifoGetScomResponse l_fifoResponse; + l_fifoRequest.commandClass = SbeFifo::SBE_FIFO_CLASS_SCOM_ACCESS; + l_fifoRequest.command = SbeFifo::SBE_FIFO_CMD_GET_SCOM; l_fifoRequest.address = i_addr; SBE_TRACU("getFifoScom: i_addr=%llX, target=%.8X", i_addr, TARGETING::get_huid(i_target)); - errl = performFifoChipOp(i_target, + errl = SbeFifo::getTheInstance().performFifoChipOp(i_target, (uint32_t *)&l_fifoRequest, (uint32_t *)&l_fifoResponse, - sizeof(fifoGetScomResponse)); + sizeof(SbeFifo::fifoGetScomResponse)); //always return data even if there is an error o_data = l_fifoResponse.data; } @@ -191,20 +191,20 @@ errlHndl_t putFifoScom(TARGETING::Target * i_target, if (errl) break; // set up FIFO request message - fifoPutScomRequest l_fifoRequest; - fifoPutScomResponse l_fifoResponse; - l_fifoRequest.commandClass = SBE_FIFO_CLASS_SCOM_ACCESS; - l_fifoRequest.command = SBE_FIFO_CMD_PUT_SCOM; + SbeFifo::fifoPutScomRequest l_fifoRequest; + SbeFifo::fifoPutScomResponse l_fifoResponse; + l_fifoRequest.commandClass = SbeFifo::SBE_FIFO_CLASS_SCOM_ACCESS; + l_fifoRequest.command = SbeFifo::SBE_FIFO_CMD_PUT_SCOM; l_fifoRequest.address = i_addr; l_fifoRequest.data = i_data; SBE_TRACU("putFifoScom: i_addr=%llX, target=%.8X", i_addr, TARGETING::get_huid(i_target)); - errl = performFifoChipOp(i_target, + errl = SbeFifo::getTheInstance().performFifoChipOp(i_target, (uint32_t *)&l_fifoRequest, (uint32_t *)&l_fifoResponse, - sizeof(fifoPutScomResponse)); + sizeof(SbeFifo::fifoPutScomResponse)); } while (0); @@ -230,10 +230,10 @@ errlHndl_t putFifoScomUnderMask(TARGETING::Target * i_target, if (errl) break; // set up FIFO request message - fifoPutScomUnderMaskRequest l_fifoRequest; - fifoPutScomResponse l_fifoResponse; - l_fifoRequest.commandClass = SBE_FIFO_CLASS_SCOM_ACCESS; - l_fifoRequest.command = SBE_FIFO_CMD_PUT_SCOM_UNDER_MASK; + SbeFifo::fifoPutScomUnderMaskRequest l_fifoRequest; + SbeFifo::fifoPutScomResponse l_fifoResponse; + l_fifoRequest.commandClass = SbeFifo::SBE_FIFO_CLASS_SCOM_ACCESS; + l_fifoRequest.command = SbeFifo::SBE_FIFO_CMD_PUT_SCOM_UNDER_MASK; l_fifoRequest.address = i_addr; l_fifoRequest.data = i_data; l_fifoRequest.mask = i_mask; @@ -242,10 +242,10 @@ errlHndl_t putFifoScomUnderMask(TARGETING::Target * i_target, "i_addr=%llX, target=%.8X, mask=%llX", i_addr, TARGETING::get_huid(i_target),i_mask); - errl = performFifoChipOp(i_target, + errl = SbeFifo::getTheInstance().performFifoChipOp(i_target, (uint32_t *)&l_fifoRequest, (uint32_t *)&l_fifoResponse, - sizeof(fifoPutScomResponse)); + sizeof(SbeFifo::fifoPutScomResponse)); } while (0); diff --git a/src/usr/sbeio/test/sbe_ffdctest.H b/src/usr/sbeio/test/sbe_ffdctest.H index 51105f997..f48206a35 100644 --- a/src/usr/sbeio/test/sbe_ffdctest.H +++ b/src/usr/sbeio/test/sbe_ffdctest.H @@ -32,13 +32,17 @@ */ #include <cxxtest/TestSuite.H> +#include <util/utilbyte.H> #include <errl/errlentry.H> #include <errl/errlmanager.H> -#include <sbeio/sbe_psudd.H> +#include <sbeio/sbe_ffdc_parser.H> + +#define SBE_TRACF(printf_string,args...) \ + TRACFCOMP(g_trac_sbeio,"ffdcParserTest: " printf_string,##args) extern trace_desc_t* g_trac_sbeio; -class SbeFFDCTest : public CxxTest::TestSuite, public SBEIO::SbePsu +class SbeFFDCTest : public CxxTest::TestSuite { public: @@ -47,22 +51,34 @@ class SbeFFDCTest : public CxxTest::TestSuite, public SBEIO::SbePsu */ void testSBEFFDC1(void) { - TS_TRACE(ENTER_MRK "sbeioTestFFDC test 1: no data"); + uint8_t l_num = 0; + uint8_t data[16] = { + 0, 0, // magic byte + 0, 0, // package length + 0, 0, // arbitrary sequence ID + 0, 0, // arbitrary command class and commamd + 0, 0, 0, 0, // return code + 0, 0, 0, 0 // arbitrary data + }; + + TS_TRACE("ffdcParserTest test 1 - no data"); - errlHndl_t l_errl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - 0, - 0, - 0, - 0); + SBEIO::SbeFFDCParser * l_ffdc_parser = new SBEIO::SbeFFDCParser(); + l_ffdc_parser->parseFFDCData(&data); - if(!SBEIO::SbePsu::handleFFDCError(l_errl)) + l_num = l_ffdc_parser->getTotalPackages(); + if(l_num != 0) { - TS_FAIL(EXIT_MRK "sbeioTestFFDC test 1 failed."); + TS_FAIL("ffdcParserTest test 1 FAILED: 0 expected, got %d", l_num); } + else + { + SBE_TRACF("package test 1 PASSED: 0 expected, got %d", l_num); + } + + delete l_ffdc_parser; - delete l_errl; - TS_TRACE(EXIT_MRK "sbeioTestFFDC test 1: no data"); + TS_TRACE("ffdcParserTest test 1 - no data PASSED"); } /** @@ -70,32 +86,46 @@ class SbeFFDCTest : public CxxTest::TestSuite, public SBEIO::SbePsu */ void testSBEFFDC2(void) { + uint8_t i; + uint8_t l_num = 0; uint8_t data[16] = { - 255, 220, // magic byte - 0, 7, // length of 1 word + 6 + 0xff, 0xdc, // magic byte + 0, 4, // package length of 0, 1, // arbitrary sequence ID 1, 1, // arbitrary command class and commamd - 0, 1, 0, 1, // arbitrary return code + 0x00, 0x01, 0x02, 0x03, // return code 1, 1, 1, 1 // arbitrary data }; - TS_TRACE(ENTER_MRK "sbeioTestFFDC test 2: 1 package, 1 word data"); + TS_TRACE("ffdcParserTest test 2 - 1 package, 1 word data"); - errlHndl_t l_errl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - 0, - 0, - 0, - 0); + SBEIO::SbeFFDCParser * l_ffdc_parser = new SBEIO::SbeFFDCParser(); + l_ffdc_parser->parseFFDCData(&data); - SBEIO::SbePsu::writeFFDCBuffer(&data, 16); - if(!SBEIO::SbePsu::handleFFDCError(l_errl)) + l_num = l_ffdc_parser->getTotalPackages(); + if(l_num != 1) { - TS_FAIL(EXIT_MRK "sbeioTestFFDC test 2 failed."); + TS_FAIL("ffdcParserTest test 2 FAILED: 1 expected, got %d", l_num); + } + else + { + SBE_TRACF("package test 2 PASSED: 1 expected, got %d", l_num); + for(i=0; i<l_num; i++) + { + uint32_t l_rc = l_ffdc_parser->getPackageRC(i); + if(l_rc != 66051) + { + TS_FAIL("ffdcParserTest test 2 FAILED RC: expected 66051, got %d", l_rc); + } + else + { + SBE_TRACF("RC test 2 PASSED: 66051 expected, got %d", l_rc); + } + } } - delete l_errl; - TS_TRACE(EXIT_MRK "sbeioTestFFDC test 2: 1 package, 1 word data"); + delete l_ffdc_parser; + TS_TRACE("ffdcParserTest test 2 - 1 package, 1 word data PASSED"); } /** @@ -103,34 +133,47 @@ class SbeFFDCTest : public CxxTest::TestSuite, public SBEIO::SbePsu */ void testSBEFFDC3(void) { - + uint8_t i; + uint8_t l_num = 0; uint8_t data[20] = { - 255, 220, // magic byte - 0, 8, // length of 2 word + 6 + 0xff, 0xdc, // magic byte + 0, 5, // package length 0, 2, // arbitrary sequence ID 1, 1, // arbitrary command class and commamd - 0, 1, 0, 1, // arbitrary return code + 0x01, 0x02, 0x03, 0x04, // return code 1, 1, 1, 1, // arbitrary data 1, 1, 1, 1 // arbitrary data }; - errlHndl_t l_errl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - 0, - 0, - 0, - 0); - TS_TRACE(ENTER_MRK "sbeioTestFFDC test 3: 1 package, 2 word data"); + TS_TRACE("ffdcParserTest test 3 - 1 package, 2 word data"); + + SBEIO::SbeFFDCParser * l_ffdc_parser = new SBEIO::SbeFFDCParser(); + l_ffdc_parser->parseFFDCData(&data); - SBEIO::SbePsu::writeFFDCBuffer(&data, 20); - if(!SBEIO::SbePsu::handleFFDCError(l_errl)) + l_num = l_ffdc_parser->getTotalPackages(); + if(l_num != 1) { - TS_FAIL(EXIT_MRK "sbeioTestFFDC test 3 failed."); + TS_FAIL("ffdcParserTest test 3 FAILED: 1 expected, got %d", l_num); + } + else + { + SBE_TRACF("package test 3 PASSED: 1 expected, got %d", l_num); + for(i=0; i<l_num; i++) + { + uint32_t l_rc = l_ffdc_parser->getPackageRC(i); + if(l_rc != 16909060) + { + TS_FAIL("ffdcParserTest test 3 FAILED RC: expect 16909060, got %d", l_rc); + } + else + { + SBE_TRACF("RC test 3 PASSED: 16909060 expected, got %d", l_rc); + } + } } - delete l_errl; - TS_TRACE(EXIT_MRK "sbeioTestFFDC test 3: 1 package, 2 word data"); - + delete l_ffdc_parser; + TS_TRACE("ffdcParserTest test 3 - 1 package, 2 word data PASSED"); } /** @@ -138,83 +181,107 @@ class SbeFFDCTest : public CxxTest::TestSuite, public SBEIO::SbePsu */ void testSBEFFDC4(void) { - + uint8_t i; + uint8_t l_num = 0; uint8_t data[36] = { - 255, 220, // magic byte - 0, 8, // length of 1 word + 6 + 0xff, 0xdc, // magic byte + 0, 5, // package length 0, 2, // arbitrary sequence ID 1, 1, // arbitrary command class and commamd - 0, 1, 0, 1, // arbitrary return code + 0x02, 0x03, 0x04, 0x05, // return code 1, 1, 1, 1, // arbitrary data 1, 1, 1, 1, - 255, 220, // package 2 - 0, 7, // length of 1 word + 6 + 0xff, 0xdc, // package 2 + 0, 4, // length of 1 word + 6 0, 2, // arbitrary sequence ID 1, 1, // arbitrary command class and commamd - 0, 1, 0, 1, // arbitrary return code + 0x02, 0x03, 0x04, 0x05, // return code 2, 2, 2, 2 }; - TS_TRACE(ENTER_MRK "sbeioTestFFDC test 4: 2 packages, 2 word data"); + TS_TRACE("ffdcParserTest test 4 - 2 packages, 2 word data"); + + SBEIO::SbeFFDCParser * l_ffdc_parser = new SBEIO::SbeFFDCParser(); + l_ffdc_parser->parseFFDCData(&data); - errlHndl_t l_errl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - 0, - 0, - 0, - 0); - SBEIO::SbePsu::writeFFDCBuffer(&data, 36); - if(!SBEIO::SbePsu::handleFFDCError(l_errl)) + l_num = l_ffdc_parser->getTotalPackages(); + if(l_num != 2) { - TS_FAIL(EXIT_MRK "sbeioTestFFDC test 4 failed."); + TS_FAIL("ffdcParserTest test 4 FAILED: 2 expected, got %d", l_num); + } + else + { + SBE_TRACF("package test 4 PASSED: 2 expected, got %d", l_num); + for(i=0; i<l_num; i++) + { + uint32_t l_rc = l_ffdc_parser->getPackageRC(i); + if(l_rc != 33752069) + { + TS_FAIL("ffdcParserTest test 4 FAILED RC: expect 33752069, got %d", l_rc); + } + else + { + SBE_TRACF("RC test 4 PASSED: 33752069 expected, got %d", l_rc); + } + } } - delete l_errl; - TS_TRACE(EXIT_MRK "sbeioTestFFDC test 4: 2 packages, 2 word data"); - + delete l_ffdc_parser; + TS_TRACE("ffdcParserTest test 4 - 2 packages, 2 word data PASSED"); } /** * @brief Test with valid magic byte, 2 package, 2nd magic byte is bad */ void testSBEFFDC5(void) { - + uint8_t i; + uint8_t l_num = 0; uint8_t data[40] = { - 255, 220, // magic byte - 0, 8, // length of 1 word + 6 + 0xff, 0xdc, // magic byte + 0, 6, // package length 0, 2, // arbitrary sequence ID 1, 1, // arbitrary command class and commamd - 0, 1, 0, 1, // arbitrary return code + 0x04, 0x05, 0x06, 0x07, // return code 1, 1, 1, 1, // arbitrary data 1, 1, 1, 1, - 220, 220, // package 2 - bad magic byte + 1, 1, 1, 1, + 0xdc, 0xdc, // package 2 - bad magic byte 0, 7, // length of 1 word + 6 0, 2, // arbitrary sequence ID 1, 1, // arbitrary command class and commamd - 0, 1, 0, 1, // arbitrary return code - 1, 1, 1, 1, // arbitrary data - 2, 2, 2, 2 + 0x05, 0x06, 0x07, 0x08, // return code + 1, 1, 1, 1 // arbitrary data }; - TS_TRACE(ENTER_MRK"sbeioTestFFDC test 5:\ - 2 packages, bad 2nd magic byte"); - - errlHndl_t l_errl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - 0, - 0, - 0, - 0); - SBEIO::SbePsu::writeFFDCBuffer(&data, 40); - if(!SBEIO::SbePsu::handleFFDCError(l_errl)) + TS_TRACE("ffdcParserTest test 5 - 2 packages, bad 2nd magic byte"); + + SBEIO::SbeFFDCParser * l_ffdc_parser = new SBEIO::SbeFFDCParser(); + l_ffdc_parser->parseFFDCData(&data); + l_num = l_ffdc_parser->getTotalPackages(); + if(l_num != 1) { - TS_FAIL(EXIT_MRK "sbeioTestFFDC test 5 failed."); + TS_FAIL("ffdcParserTest test 5 FAILED: 1 expected, got %d", l_num); + } + else + { + SBE_TRACF("package test 5 PASSED: 1 expected, got %d", l_num); + for(i=0; i<l_num; i++) + { + uint32_t l_rc = l_ffdc_parser->getPackageRC(i); + if(l_rc != 67438087) + { + TS_FAIL("ffdcParserTest test 5 FAIL RC: 67438087, got %d", l_rc); + } + else + { + SBE_TRACF("RC test 5 PASSED: 67438087 expected, got %d", l_rc); + } + } } - delete l_errl; - TS_TRACE(EXIT_MRK"sbeioTestFFDC test 5:\ - 2 packages, bad 2nd magic byte"); - + delete l_ffdc_parser; + TS_TRACE("ffdcParserTest test 5 -\ + 2 packages, bad 2nd magic byte PASSED"); } }; |