From f290f5d4a9efbf70ae99ec0cdff5b676d63431f1 Mon Sep 17 00:00:00 2001 From: Zane Shelley Date: Thu, 7 Jun 2018 13:44:27 -0500 Subject: PRD: fixed parser bugs in TD_CTLR_DATA Change-Id: I28ad97dae57c02b7a2cbf42433bfbc883e4653ff Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/60127 Tested-by: Jenkins Server Reviewed-by: Matt Derksen Reviewed-by: Caleb N. Palmer Reviewed-by: Zane C. Shelley Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/60147 Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW --- src/usr/diag/prdf/common/plugins/prdfMemLogParse.C | 216 +++++++++------------ src/usr/diag/prdf/common/plugins/prdfParserEnums.H | 52 ++++- src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C | 136 +++++++------ 3 files changed, 209 insertions(+), 195 deletions(-) diff --git a/src/usr/diag/prdf/common/plugins/prdfMemLogParse.C b/src/usr/diag/prdf/common/plugins/prdfMemLogParse.C index dd3edf56b..4edb13e87 100644 --- a/src/usr/diag/prdf/common/plugins/prdfMemLogParse.C +++ b/src/usr/diag/prdf/common/plugins/prdfMemLogParse.C @@ -3392,181 +3392,139 @@ bool parseTdCtlrStateData( uint8_t * i_buffer, uint32_t i_buflen, { bool o_rc = true; - if ( Util::hashString(TD_CTLR_DATA::START) == i_sigId ) - i_parser.PrintString( " TDCTLR_STATE_DATA_START", "" ); - else if ( Util::hashString(TD_CTLR_DATA::END) == i_sigId ) - i_parser.PrintString( " TDCTLR_STATE_DATA_END", "" ); + // Make sure we have a valid buffer. + if ( (NULL == i_buffer) || (0 == i_buflen) ) return false; - // These are copies of the enums in prdfMemTdQueue.H and prdfParserEnums.H. + // This is a copy of the enum in prdfMemTdQueue.H. enum TdType { VCM_EVENT = 0, + DSD_EVENT, TPS_EVENT, - }; - - enum Phase - { - TD_PHASE_0, - TD_PHASE_1, - TD_PHASE_2, - }; - - enum Version - { - IPL = 1, - RT = 2, - IPL_PORTS = 3, - RT_PORTS = 4 + INVALID_EVENT = 0xf, }; do { - if ( NULL == i_buffer ) - { - o_rc = false; - break; - } - - BitString bs( (i_buflen*8), (CPU_WORD*)i_buffer ); - - if ( bs.getBitLen() < 22 ) - { - o_rc = false; - break; - } - - uint32_t curPos = 0; - uint8_t port = 0x0F; // not valid + const uint32_t bitLen = i_buflen * 8; + BitString bs ( bitLen, (CPU_WORD*)i_buffer ); + uint32_t pos = 0; //###################################################################### - // Header data (18 bits) + // Header data //###################################################################### - uint8_t version = bs.getFieldJustify( curPos, 4 ); curPos+=4; - uint8_t mrnk = bs.getFieldJustify( curPos, 3 ); curPos+=3; - uint8_t srnk = bs.getFieldJustify( curPos, 3 ); curPos+=3; - uint8_t phase = bs.getFieldJustify( curPos, 4 ); curPos+=4; - uint8_t type = bs.getFieldJustify( curPos, 4 ); curPos+=4; + // Get the data state and version. + if ( bitLen < 4 ) { o_rc = false; break; } - // Verify if we have new format with port information - bool versWithPorts = ( (IPL_PORTS == version) || - (RT_PORTS == version) ) ? true : false; - if ( versWithPorts ) - { - // 0:3 is valid MCA, xF is for MBA case - port = bs.getFieldJustify( curPos, 4 ); curPos+=4; - } // end if new format with ports + uint8_t state = bs.getFieldJustify( pos, 1 ); pos+=1; + uint8_t version = bs.getFieldJustify( pos, 3 ); pos+=3; - const char * version_str = " "; - switch ( version ) + if ( (TD_CTLR_DATA::VERSION_1 != version) && + (TD_CTLR_DATA::VERSION_2 != version) ) { - case IPL: - case IPL_PORTS: - version_str = "IPL"; break; - case RT : - case RT_PORTS: - version_str = "RT "; break; + o_rc = false; break; } - const char * type_str = " "; - switch ( type ) + uint32_t hdrLen = TD_CTLR_DATA::v1_HEADER; + uint32_t entLen = TD_CTLR_DATA::v1_ENTRY; + if ( TD_CTLR_DATA::VERSION_2 == version ) { - case VCM_EVENT: type_str = "VCM_EVENT"; break; - case TPS_EVENT: type_str = "TPS_EVENT"; break; - default : type_str = "INVALID_EVENT"; break; + hdrLen = TD_CTLR_DATA::v2_HEADER; + entLen = TD_CTLR_DATA::v2_ENTRY; } - const char * phase_str = " "; - switch ( phase ) + // Print the title and state. + const char * state_str = ( TD_CTLR_DATA::RT == state ) ? "RT" : "IPL"; + + if ( Util::hashString(TD_CTLR_DATA::START) == i_sigId ) + i_parser.PrintString( " TDCTLR_STATE_DATA_START", state_str ); + else if ( Util::hashString(TD_CTLR_DATA::END) == i_sigId ) + i_parser.PrintString( " TDCTLR_STATE_DATA_END", state_str ); + + // Get the rest of the header data. + if ( bitLen < hdrLen ) { o_rc = false; break; } + + uint8_t curMrnk = bs.getFieldJustify( pos, 3 ); pos+=3; + uint8_t curSrnk = bs.getFieldJustify( pos, 3 ); pos+=3; + uint8_t curPhase = bs.getFieldJustify( pos, 4 ); pos+=4; + uint8_t curType = bs.getFieldJustify( pos, 4 ); pos+=4; + uint8_t queueCount = bs.getFieldJustify( pos, 4 ); pos+=4; + + uint8_t curPort = 0; + if ( TD_CTLR_DATA::VERSION_2 == version ) { - case TD_PHASE_0: phase_str = "TD_PHASE_0"; break; - case TD_PHASE_1: phase_str = "TD_PHASE_1"; break; - case TD_PHASE_2: phase_str = "TD_PHASE_2"; break; + curPort = bs.getFieldJustify( pos, 2 ); pos+=2; } - char rank_str[DATA_SIZE] = " "; - switch ( type ) + // Print the current procedure, if needed. + if ( INVALID_EVENT != curType ) { - case VCM_EVENT: - snprintf( rank_str, DATA_SIZE, "m%d ", mrnk ); break; - case TPS_EVENT: - snprintf( rank_str, DATA_SIZE, "m%ds%d", mrnk, srnk ); break; - default: - snprintf( rank_str, DATA_SIZE, "n/a "); break; - } + const char * curType_str = ""; + switch ( curType ) + { + case VCM_EVENT: curType_str = "VCM"; break; + case DSD_EVENT: curType_str = "DSD"; break; + case TPS_EVENT: curType_str = "TPS"; break; + default : curType_str = "???"; break; + } - i_parser.PrintString( " Version", version_str ); - i_parser.PrintString( " TD Type", type_str ); - i_parser.PrintString( " TD Phase", phase_str ); - i_parser.PrintString( " Target Rank", rank_str ); + char curPort_str[DATA_SIZE] = ""; + if ( TD_CTLR_DATA::VERSION_2 == version ) + { + snprintf( curPort_str, DATA_SIZE, "port %d", curPort ); + } - // Do we actually have MCA port number ? - if ( versWithPorts ) - { - i_parser.PrintNumber( " Port Num ", "%d", port ); - } // end if MCA (not MBA) + char curData_str[DATA_SIZE] = ""; + snprintf( curData_str, DATA_SIZE, "%s phase %d on m%ds%d %s", + curType_str, curPhase, curMrnk, curSrnk, curPort_str ); + i_parser.PrintString( " Current procedure", curData_str ); + } //###################################################################### - // TD Request Queue (min 4 bits, max 164 bits) + // TD Queue entries //###################################################################### - uint8_t queueCount = bs.getFieldJustify( curPos, 4 ); curPos+=4; - - if ( bs.getBitLen() < (curPos+(queueCount*10)) ) + for ( uint8_t n = 0; n < queueCount; n++ ) { - o_rc = false; - break; - } + // Get the entry data. + if ( bitLen < hdrLen + (n+1) * entLen ) { o_rc = false; break; } - for ( uint8_t i = 0; i < queueCount; i++ ) - { - uint8_t queueMrnk = bs.getFieldJustify( curPos, 3 ); curPos+=3; - uint8_t queueSrnk = bs.getFieldJustify( curPos, 3 ); curPos+=3; - uint8_t queueType = bs.getFieldJustify( curPos, 4 ); curPos+=4; + uint8_t itMrnk = bs.getFieldJustify( pos, 3 ); pos+=3; + uint8_t itSrnk = bs.getFieldJustify( pos, 3 ); pos+=3; + uint8_t itType = bs.getFieldJustify( pos, 4 ); pos+=4; - // Verify if we have new format with port information - if ( versWithPorts ) + uint8_t itPort = 0; + if ( TD_CTLR_DATA::VERSION_2 == version ) { - port = bs.getFieldJustify( curPos, 4 ); curPos+=4; - } // end if new format with ports + itPort = bs.getFieldJustify( pos, 2 ); pos+=2; + } - const char * type_str = " "; - switch ( queueType ) + // Print the entry. + const char * itType_str = ""; + switch ( itType ) { - case VCM_EVENT: type_str = "VCM_EVENT"; break; - case TPS_EVENT: type_str = "TPS_EVENT"; break; + case VCM_EVENT: itType_str = "VCM"; break; + case DSD_EVENT: itType_str = "DSD"; break; + case TPS_EVENT: itType_str = "TPS"; break; + default : itType_str = "???"; break; } - char rank_str[DATA_SIZE] = " "; - switch ( type ) + char itPort_str[DATA_SIZE] = ""; + if ( TD_CTLR_DATA::VERSION_2 == version ) { - case VCM_EVENT: - snprintf( rank_str, DATA_SIZE, "m%d ", queueMrnk ); - break; - case TPS_EVENT: - snprintf( rank_str, DATA_SIZE, "m%ds%d", queueMrnk, - queueSrnk ); - break; + snprintf( itPort_str, DATA_SIZE, "port %d", itPort ); } - char data[DATA_SIZE] = ""; + char itData_str[DATA_SIZE] = ""; + snprintf( itData_str, DATA_SIZE, "%s on m%ds%d %s", + itType_str, itMrnk, itSrnk, itPort_str ); - // Verify if we have valid port information - if ( versWithPorts ) - { - snprintf( data, DATA_SIZE, "%s on %s Port:%d", - type_str, rank_str, port ); - } // end if MCA (not MBA) - else - { - snprintf( data, DATA_SIZE, "%s on %s", type_str, rank_str ); - } // end if MCA (not MBA) - - i_parser.PrintString( " TD Request", data ); + i_parser.PrintString( " TD queue entry", itData_str ); } - }while(0); + } while (0); if ( !o_rc ) { diff --git a/src/usr/diag/prdf/common/plugins/prdfParserEnums.H b/src/usr/diag/prdf/common/plugins/prdfParserEnums.H index b0f44b557..bf35fb8ae 100644 --- a/src/usr/diag/prdf/common/plugins/prdfParserEnums.H +++ b/src/usr/diag/prdf/common/plugins/prdfParserEnums.H @@ -337,16 +337,58 @@ namespace TD_CTLR_DATA static const char * const START = "TDCTLR_STATE_DATA_START"; static const char * const END = "TDCTLR_STATE_DATA_END"; + enum State + { + IPL = 0, + RT = 1, + }; + // We don't use 0 as one of the enum values here so we can ensure our data // is non-zero when we add the tdCtlr state to the capture data enum Version { - IPL = 1, - RT = 2, - // These 2 versions include the MCA port number - IPL_PORTS = 3, - RT_PORTS = 4 + // Version 1: + // Header: + // 1-bit state (IPL or RT) + // 3-bit version (VERSION_1) + // 3-bit current procedure master rank (0-7) + // 3-bit current procedure slave rank (0-7) + // 4-bit current procedure phase (see TdEntry::Phase) + // 4-bit current procedure type (see TdEntry::TdType) + // 4-bit number of entries in the queue (0-15) + // For each entry in the queue + // 3-bit entry master rank (0-7) + // 3-bit entry slave rank (0-7) + // 4-bit entry type (see TdEntry::TdType) + VERSION_1 = 1, + + // Version 2 (includes MCA port number): + // Header: + // 1-bit state (IPL or RT) + // 3-bit version (VERSION_2) + // 3-bit current procedure master rank (0-7) + // 3-bit current procedure slave rank (0-7) + // 4-bit current procedure phase (see TdEntry::Phase) + // 4-bit current procedure type (see TdEntry::TdType) + // 4-bit number of entries in the queue (0-15) + // 2-bit current procedure MCA port relative to MCBIST (0-3) + // For each entry in the queue + // 3-bit entry master rank (0-7) + // 3-bit entry slave rank (0-7) + // 4-bit entry type (see TdEntry::TdType) + // 2-bit entry MCA port relative to MCBIST (0-3) + VERSION_2 = 2, + }; + + enum BitLen + { + v1_HEADER = 22, + v1_ENTRY = 10, + + v2_HEADER = 24, + v2_ENTRY = 12, }; + } // namespace TD_CTLR_DATA #if defined(PRDF_HOSTBOOT_ERRL_PLUGIN) || defined(PRDF_FSP_ERRL_PLUGIN) diff --git a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C index 470568c01..bbea01707 100644 --- a/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C +++ b/src/usr/diag/prdf/plat/mem/prdfMemTdCtlr.C @@ -390,96 +390,110 @@ void MemTdCtlr::collectStateCaptureData( STEP_CODE_DATA_STRUCT & io_sc, { #define PRDF_FUNC "[MemTdCtlr::collectStateCaptureData] " - ExtensibleChip *l_memChip = nullptr; - - // Get the number of entries in the TD queue (limit 15) + // Get the number of entries in the TD queue (limit 16) TdQueue::Queue queue = iv_queue.getQueue(); uint8_t queueCount = queue.size(); - if ( 15 < queueCount ) queueCount = 15; + if ( 16 < queueCount ) queueCount = 16; // Don't add anything if there is no data. if ( nullptr == iv_curProcedure && 0 == queueCount ) return; - // Get the buffer - uint32_t bitLen = 32 + queueCount*14; // Header + TD queue - BitStringBuffer bsb( bitLen ); - uint32_t curPos = 0; - uint8_t filler = 0x00; - - //###################################################################### - // Header data (28 bits) - 6 bits currently unused (filler) - //###################################################################### + // Get the version to use. + uint8_t version = TD_CTLR_DATA::VERSION_1; + if ( MODEL_NIMBUS == getChipModel(getMasterProc()) ) + { + version = TD_CTLR_DATA::VERSION_2; + } - // Specifies when running. Also ensures our data is non-zero. 4-bit - #ifndef __HOSTBOOT_RUNTIME - bsb.setFieldJustify( curPos, 4, TD_CTLR_DATA::Version::IPL_PORTS ); - curPos+=4; + // Get the IPL state. + #ifdef __HOSTBOOT_RUNTIME + uint8_t state = TD_CTLR_DATA::RT; #else - bsb.setFieldJustify( curPos, 4, TD_CTLR_DATA::Version::RT_PORTS ); - curPos+=4; + uint8_t state = TD_CTLR_DATA::IPL; #endif - uint8_t mrnk = 0; - uint8_t srnk = 0; - uint8_t phase = TdEntry::Phase::TD_PHASE_0; - uint8_t type = TdEntry::TdType::INVALID_EVENT; - uint8_t port = 0; + // Get the buffer length (header + TD queue) + uint32_t hdrLen = TD_CTLR_DATA::v1_HEADER; + uint32_t entLen = TD_CTLR_DATA::v1_ENTRY; + if ( TD_CTLR_DATA::VERSION_2 == version ) + { + hdrLen = TD_CTLR_DATA::v2_HEADER; + entLen = TD_CTLR_DATA::v2_ENTRY; + } + + uint32_t bitLen = hdrLen + queueCount * entLen; + + // Init the buffer. + BitStringBuffer bsb( bitLen ); + + //########################################################################## + // Header data + //########################################################################## + + uint8_t curMrnk = 0; + uint8_t curSrnk = 0; + uint8_t curPhase = TdEntry::Phase::TD_PHASE_0; + uint8_t curType = TdEntry::TdType::INVALID_EVENT; + uint8_t curPort = 0; if ( nullptr != iv_curProcedure ) { - mrnk = iv_curProcedure->getRank().getMaster(); // 3-bit - srnk = iv_curProcedure->getRank().getSlave(); // 3-bit - phase = iv_curProcedure->getPhase(); // 4-bit - type = iv_curProcedure->getType(); // 4-bit - - // Want MCA port number (if any) - l_memChip = iv_curProcedure->getChip(); - if ( TYPE_MCA == l_memChip->getType() ) - { - port = l_memChip->getPos() % MAX_MCA_PER_MCBIST; // 2-bit - } // if MCBIST + curMrnk = iv_curProcedure->getRank().getMaster(); + curSrnk = iv_curProcedure->getRank().getSlave(); + curPhase = iv_curProcedure->getPhase(); + curType = iv_curProcedure->getType(); - } // if Non-Null iv_curProcedure + if ( TD_CTLR_DATA::VERSION_2 == version ) + { + curPort = iv_curProcedure->getChip()->getPos() % MAX_MCA_PER_MCBIST; + } + } - bsb.setFieldJustify( curPos, 3, mrnk ); curPos+=3; - bsb.setFieldJustify( curPos, 3, srnk ); curPos+=3; - bsb.setFieldJustify( curPos, 4, phase ); curPos+=4; - bsb.setFieldJustify( curPos, 4, type ); curPos+=4; - bsb.setFieldJustify( curPos, 4, port ); curPos+=4; - bsb.setFieldJustify( curPos, 6, filler); curPos+=6; + uint32_t pos = 0; + bsb.setFieldJustify( pos, 1, state ); pos+=1; + bsb.setFieldJustify( pos, 3, version ); pos+=3; + bsb.setFieldJustify( pos, 3, curMrnk ); pos+=3; + bsb.setFieldJustify( pos, 3, curSrnk ); pos+=3; + bsb.setFieldJustify( pos, 4, curPhase ); pos+=4; + bsb.setFieldJustify( pos, 4, curType ); pos+=4; + bsb.setFieldJustify( pos, 4, queueCount ); pos+=4; - //###################################################################### - // TD Request Queue (min 4 bits, max 228 bits) - //###################################################################### + if ( TD_CTLR_DATA::VERSION_2 == version ) + { + bsb.setFieldJustify( pos, 2, curPort ); pos+=2; + } - bsb.setFieldJustify( curPos, 4, queueCount ); curPos+=4; // 4-bit + //########################################################################## + // TD Queue + //########################################################################## for ( uint32_t n = 0; n < queueCount; n++ ) { - uint8_t itMrnk = queue[n]->getRank().getMaster(); // 3-bit - uint8_t itSrnk = queue[n]->getRank().getSlave(); // 3-bit - uint8_t itType = queue[n]->getType(); // 4-bit + uint8_t itMrnk = queue[n]->getRank().getMaster(); + uint8_t itSrnk = queue[n]->getRank().getSlave(); + uint8_t itType = queue[n]->getType(); + uint8_t itPort = 0; - l_memChip = queue[n]->getChip(); - if ( TYPE_MCA == l_memChip->getType() ) + if ( TD_CTLR_DATA::VERSION_2 == version ) { - port = l_memChip->getPos() % MAX_MCA_PER_MCBIST; // 2-bit + itPort = queue[n]->getChip()->getPos() % MAX_MCA_PER_MCBIST; } - else + + bsb.setFieldJustify( pos, 3, itMrnk ); pos+=3; + bsb.setFieldJustify( pos, 3, itSrnk ); pos+=3; + bsb.setFieldJustify( pos, 4, itType ); pos+=4; + + if ( TD_CTLR_DATA::VERSION_2 == version ) { - port = 0xFF; + bsb.setFieldJustify( pos, 2, itPort ); pos+=2; } - - bsb.setFieldJustify( curPos, 3, itMrnk ); curPos+=3; - bsb.setFieldJustify( curPos, 3, itSrnk ); curPos+=3; - bsb.setFieldJustify( curPos, 4, itType ); curPos+=4; - bsb.setFieldJustify( curPos, 4, port ); curPos+=4; } - //###################################################################### + //########################################################################## // Add the capture data - //###################################################################### + //########################################################################## + CaptureData & cd = io_sc.service_data->GetCaptureData(); cd.Add( iv_chip->getTrgt(), Util::hashString(i_startEnd), bsb ); -- cgit v1.2.1