diff options
author | Brian Stegmiller <bjs@us.ibm.com> | 2017-05-23 10:00:45 -0500 |
---|---|---|
committer | Martha Broyles <mbroyles@us.ibm.com> | 2017-07-20 17:09:16 -0400 |
commit | 7cdcf4db35261a60df8a10ac06ce24d587b7626b (patch) | |
tree | 175cf0ee0bc46df03f2a3461cb222a084089d139 /src/occ_405 | |
parent | b09f435f779579755acbbaa5286e0679a1fd5833 (diff) | |
download | talos-occ-7cdcf4db35261a60df8a10ac06ce24d587b7626b.tar.gz talos-occ-7cdcf4db35261a60df8a10ac06ce24d587b7626b.zip |
OCC: Initial IPL Checkstop analysis support
Change-Id: I60ecc055c840e69d9c86e7eab821889b451db60b
RTC: 173624
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/40850
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Prachi Gupta <pragupta@us.ibm.com>
Reviewed-by: Caleb N. Palmer <cnpalmer@us.ibm.com>
Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com>
Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com>
Reviewed-by: Martha Broyles <mbroyles@us.ibm.com>
Diffstat (limited to 'src/occ_405')
-rw-r--r-- | src/occ_405/firdata/firData.c | 824 | ||||
-rw-r--r-- | src/occ_405/firdata/firDataConst_common.h | 6 | ||||
-rw-r--r-- | src/occ_405/firdata/fir_data_collect.c | 6 | ||||
-rw-r--r-- | src/occ_405/firdata/homerData_common.h | 253 | ||||
-rw-r--r-- | src/occ_405/firdata/pnorData_common.h | 60 | ||||
-rw-r--r-- | src/occ_405/firdata/scom_trgt.c | 59 |
6 files changed, 983 insertions, 225 deletions
diff --git a/src/occ_405/firdata/firData.c b/src/occ_405/firdata/firData.c index 07d7703..03b822b 100644 --- a/src/occ_405/firdata/firData.c +++ b/src/occ_405/firdata/firData.c @@ -35,12 +35,11 @@ * type. */ typedef struct { - uint32_t * glbl; /*/< Global registers */ - uint32_t * fir; /*/< Normal FIRs */ - uint32_t * reg; /*/< Normal registers */ - uint64_t * idFir; /*/< Indirect-SCOM FIRs */ - uint64_t * idReg; /*/< Indirect-SCOM registers */ - + uint32_t * glbl; /*/< Global registers */ + uint32_t * fir; /*/< Normal FIRs */ + uint32_t * reg; /*/< Normal registers */ + uint64_t * idFir; /*/< Indirect-SCOM FIRs */ + uint64_t * idReg; /*/< Indirect-SCOM registers */ } FirData_ListPointers_t; /** Contains pointers and sizes for the HOMER and PNOR data buffers. */ @@ -55,10 +54,38 @@ typedef struct PNOR_Data_t * pData; /*/< Pointer to the PNOR header data */ uint32_t pBufSize; /*/< Current size of the PNOR data buffer */ - FirData_ListPointers_t hPtrs[TRGT_MAX]; /*/< Pointers to the register lists */ + FirData_ListPointers_t hPtrs[TRGT_MAX]; /*/< Pointers to the reg lists */ + + HOMER_ChipSpecAddr_t * ecDepReg; /*/< EC dependent regs */ } FirData_t; + +/** We move the chiplet exist bit fields into this structure left */ +/** justified for easy checking of the fields with a mask */ +typedef struct +{ + uint32_t xbusMask; + uint32_t obusMask; + uint32_t ecMask; + + uint32_t eqMask; + uint32_t exMask; + uint32_t mcbist_mc_Mask; + uint32_t mcs_mi_Mask; + uint32_t mca_dmi_Mask; + + uint32_t cappMask; + uint32_t pecMask; + uint32_t phbMask; + +} FirData_existBits_t; + +/* Uncomment for additional debug traces */ +#if 0 +#define DEBUG_PRD_CHKSTOP_ANALYSIS +#endif + /*------------------------------------------------------------------------------ */ /** @brief Add generic data to the PNOR buffer. @@ -137,6 +164,12 @@ bool FirData_addRegToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, } while (0); +#ifdef DEBUG_PRD_CHKSTOP_ANALYSIS + TRAC_INFO(" addToPnor: Type:%d Pos:%d Unit:%d Addr:%X Full:%d", + i_sTrgt.type, i_sTrgt.procPos, i_sTrgt.procUnitPos, + i_addr, full ); +#endif + return full; } @@ -196,15 +229,21 @@ bool FirData_addIdRegToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, * @param i_sTrgt SCOM target. * @param o_noAttn True, if the global registers showed no active attentions * on the target. False, otherwise. + * @param i_chipStruct Provides chipType and ecLevel we need + * for EC dependent regs + * * @return True if the PNOR buffer is full, false if there was room. */ bool FirData_addGlblsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, - SCOM_Trgt_t i_sTrgt, bool * o_noAttn ) + SCOM_Trgt_t i_sTrgt, bool * o_noAttn, + HOMER_Chip_t *i_chipStruct ) { bool full = false; + bool l_isAnyGlobal = false; /* true when we find global reg */ + bool l_isAnyNonZero = false; /* true if ATTN is active on any reg */ uint8_t t = i_sTrgt.type; - uint8_t cnt = io_fd->hData->counts[t][REG_GLBL]; + uint8_t cnt = io_fd->hData->regCounts[t][REG_GLBL]; uint32_t i = 0; @@ -215,7 +254,9 @@ bool FirData_addGlblsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, if ( 0 != cnt ) { - *o_noAttn = true; /* Assume no attentions. */ + /** If we get here, we have GLOBALS for this target **/ + l_isAnyGlobal = true; + for ( i = 0; i < cnt; i++ ) { addr = io_fd->hPtrs[t].glbl[i]; @@ -225,10 +266,66 @@ bool FirData_addGlblsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, &nonZero ); if ( full ) break; - if ( nonZero ) *o_noAttn = false; + if ( nonZero ) l_isAnyNonZero = true; } } + + /** Handle EC dependent registers, if any */ + HOMER_ChipSpecAddr_t *l_ecAddrtPtr = io_fd->ecDepReg; + cnt = io_fd->hData->ecDepCounts; + + /** We have a structure with one element for each EC dep address. */ + /** Need to loop thru and verify we have same regType among */ + /** other things prior to using the address. */ + for ( i = 0; i < cnt; i++ ) + { +#ifdef DEBUG_PRD_CHKSTOP_ANALYSIS + TRAC_INFO(" addGlblsToPnor In/Array: chipType:%X::%X trgType:%X::%X" + " regType:%X::%X ecLevel %X::%X", + i_chipStruct->chipType, l_ecAddrtPtr->chipType, + t, l_ecAddrtPtr->trgtType, + REG_GLBL, l_ecAddrtPtr->regType, + i_chipStruct->chipEcLevel, l_ecAddrtPtr->ddLevel ); +#endif + + /** Need same chipType (nimbus,cumulus,etc..), same target type, */ + /** same register type and EC level must match too */ + if ( (l_ecAddrtPtr->chipType == i_chipStruct->chipType) && + (l_ecAddrtPtr->trgtType == t ) && + (l_ecAddrtPtr->regType == REG_GLBL) && + (l_ecAddrtPtr->ddLevel == i_chipStruct->chipEcLevel) + ) + { + /** If we get here, we have GLOBALS for this target **/ + l_isAnyGlobal = true; + + /* address is right justified in 64 bits */ + addr = (uint32_t)(l_ecAddrtPtr->address); + nonZero = false; + + full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr, + &nonZero ); + if ( full ) break; + + if ( nonZero ) l_isAnyNonZero = true; + } /* end if we found an EC dep reg */ + + /* prep pointer for next element (if any) */ + l_ecAddrtPtr++; + + } /** end EC dependent reg loop */ + + /* If we have no GLOBALS, we want to collect other regs */ + /* so then we want to return 'attn is active)'. */ + /* If we have GLOBALS, then we need non-zero reg to */ + /* collect the rest of the regs (attn is active). */ + if ( (true == l_isAnyGlobal) && (false == l_isAnyNonZero) ) + { + /* This indicates we won't collect additional regs */ + *o_noAttn = true; /* starts out as false */ + } + return full; } @@ -238,15 +335,19 @@ bool FirData_addGlblsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, * @param io_fd The FIR data stuct. * @param io_pTrgt Pointer to PNOR target. * @param i_sTrgt SCOM target. + * @param i_chipStruct Provides chipType and ecLevel we need + * for EC dependent regs + * * @return True if the PNOR buffer is full, false if there was room. */ bool FirData_addFirsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, - SCOM_Trgt_t i_sTrgt ) + SCOM_Trgt_t i_sTrgt, + HOMER_Chip_t *i_chipStruct ) { bool full = false; uint8_t t = i_sTrgt.type; - uint8_t cnt = io_fd->hData->counts[t][REG_FIR]; + uint8_t cnt = io_fd->hData->regCounts[t][REG_FIR]; uint32_t i = 0; @@ -281,6 +382,65 @@ bool FirData_addFirsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, } } + + /** Handle EC dependent registers, if any */ + HOMER_ChipSpecAddr_t *l_ecAddrtPtr = io_fd->ecDepReg; + cnt = io_fd->hData->ecDepCounts; + + /** We have a structure with one element for each EC dep address. */ + /** Need to loop thru and verify we have same regType among */ + /** other things prior to using the address. */ + for ( i = 0; i < cnt; i++ ) + { +#ifdef DEBUG_PRD_CHKSTOP_ANALYSIS + TRAC_INFO(" addFirsToPnor In/Array: chipType:%X::%X trgType:%X::%X" + " regType:%X::%X ecLevel %X::%X", + i_chipStruct->chipType, l_ecAddrtPtr->chipType, + t, l_ecAddrtPtr->trgtType, + REG_GLBL, l_ecAddrtPtr->regType, + i_chipStruct->chipEcLevel, l_ecAddrtPtr->ddLevel ); +#endif + + /** Need same chipType (nimbus,cumulus,etc..), same target type, */ + /** same register type and EC level must match too */ + if ( (l_ecAddrtPtr->chipType == i_chipStruct->chipType) && + (l_ecAddrtPtr->trgtType == t ) && + (l_ecAddrtPtr->regType == REG_FIR) && + (l_ecAddrtPtr->ddLevel == i_chipStruct->chipEcLevel) + ) + { /* address is right justified in 64 bits */ + addr = (uint32_t)(l_ecAddrtPtr->address); + nonZero = false; + + /* Add FIR */ + full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr, &nonZero ); + if ( full ) break; + + /* Add MASK */ + full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr + 3, &tmp ); + if ( full ) break; + + if ( nonZero ) + { + /* Add ACT0 */ + full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr + 6, + &tmp ); + if ( full ) break; + + /* Add ACT1 */ + full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr + 7, + &tmp ); + if ( full ) break; + } + + } /* end if we found an EC dep reg */ + + /* prep pointer for next element (if any) */ + l_ecAddrtPtr++; + + } /** end EC dependent reg loop */ + + return full; } @@ -290,15 +450,19 @@ bool FirData_addFirsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, * @param io_fd The FIR data stuct. * @param io_pTrgt Pointer to PNOR target. * @param i_sTrgt SCOM target. + * @param i_chipStruct Provides chipType and ecLevel we need + * for EC dependent regs + * * @return True if the PNOR buffer is full, false if there was room. */ bool FirData_addRegsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, - SCOM_Trgt_t i_sTrgt ) + SCOM_Trgt_t i_sTrgt, + HOMER_Chip_t *i_chipStruct ) { bool full = false; uint8_t t = i_sTrgt.type; - uint8_t cnt = io_fd->hData->counts[t][REG_REG]; + uint8_t cnt = io_fd->hData->regCounts[t][REG_REG]; uint32_t i = 0; @@ -313,6 +477,44 @@ bool FirData_addRegsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, if ( full ) break; } + /** Handle EC dependent registers, if any */ + HOMER_ChipSpecAddr_t *l_ecAddrtPtr = io_fd->ecDepReg; + cnt = io_fd->hData->ecDepCounts; + + /** We have a structure with one element for each EC dep address. */ + /** Need to loop thru and verify we have same regType among */ + /** other things prior to using the address. */ + for ( i = 0; i < cnt; i++ ) + { +#ifdef DEBUG_PRD_CHKSTOP_ANALYSIS + TRAC_INFO(" addRegsToPnor In/Array: chipType:%X::%X trgType:%X::%X" + " regType:%X::%X ecLevel %X::%X", + i_chipStruct->chipType, l_ecAddrtPtr->chipType, + t, l_ecAddrtPtr->trgtType, + REG_GLBL, l_ecAddrtPtr->regType, + i_chipStruct->chipEcLevel, l_ecAddrtPtr->ddLevel ); +#endif + + /** Need same chipType (nimbus,cumulus,etc..), same target type, */ + /** same register type and EC level must match too */ + if ( (l_ecAddrtPtr->chipType == i_chipStruct->chipType) && + (l_ecAddrtPtr->trgtType == t ) && + (l_ecAddrtPtr->regType == REG_REG) && + (l_ecAddrtPtr->ddLevel == i_chipStruct->chipEcLevel) + ) + { /* address is right justified in 64 bits */ + addr = (uint32_t)(l_ecAddrtPtr->address); + + full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr, + &tmp ); + if ( full ) break; + } /* end if we found an EC dep reg */ + + /* prep pointer for next element (if any) */ + l_ecAddrtPtr++; + + } /** end EC dependent reg loop */ + return full; } @@ -322,15 +524,19 @@ bool FirData_addRegsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, * @param io_fd The FIR data stuct. * @param io_pTrgt Pointer to PNOR target. * @param i_sTrgt SCOM target. + * @param i_chipStruct Provides chipType and ecLevel we need + * for EC dependent regs + * * @return True if the PNOR buffer is full, false if there was room. */ bool FirData_addIdFirsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, - SCOM_Trgt_t i_sTrgt ) + SCOM_Trgt_t i_sTrgt, + HOMER_Chip_t *i_chipStruct ) { bool full = false; uint8_t t = i_sTrgt.type; - uint8_t cnt = io_fd->hData->counts[t][REG_IDFIR]; + uint8_t cnt = io_fd->hData->regCounts[t][REG_IDFIR]; uint32_t i = 0; @@ -367,6 +573,66 @@ bool FirData_addIdFirsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, } } + + /** Handle EC dependent registers, if any */ + HOMER_ChipSpecAddr_t *l_ecAddrtPtr = io_fd->ecDepReg; + cnt = io_fd->hData->ecDepCounts; + + /** We have a structure with one element for each EC dep address. */ + /** Need to loop thru and verify we have same regType among */ + /** other things prior to using the address. */ + for ( i = 0; i < cnt; i++ ) + { +#ifdef DEBUG_PRD_CHKSTOP_ANALYSIS + TRAC_INFO(" addIdFirsToPnor In/Array: chipType:%X::%X trgType:%X::%X" + " regType:%X::%X ecLevel %X::%X", + i_chipStruct->chipType, l_ecAddrtPtr->chipType, + t, l_ecAddrtPtr->trgtType, + REG_GLBL, l_ecAddrtPtr->regType, + i_chipStruct->chipEcLevel, l_ecAddrtPtr->ddLevel ); +#endif + + /** Need same chipType (nimbus,cumulus,etc..), same target type, */ + /** same register type and EC level must match too */ + if ( (l_ecAddrtPtr->chipType == i_chipStruct->chipType) && + (l_ecAddrtPtr->trgtType == t ) && + (l_ecAddrtPtr->regType == REG_IDFIR) && + (l_ecAddrtPtr->ddLevel == i_chipStruct->chipEcLevel) + ) + { /* need full 64 bit address here */ + addr = l_ecAddrtPtr->address; + nonZero = false; + + /* Add FIR */ + full = FirData_addIdRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr, + &nonZero ); + if ( full ) break; + + /* Add MASK */ + full = FirData_addIdRegToPnor( io_fd, io_pTrgt, i_sTrgt, + addr + 0x300000000ll, &tmp ); + if ( full ) break; + + if ( nonZero ) + { + /* Add ACT0 */ + full = FirData_addIdRegToPnor( io_fd, io_pTrgt, i_sTrgt, + addr + 0x600000000ll, &tmp ); + if ( full ) break; + + /* Add ACT1 */ + full = FirData_addIdRegToPnor( io_fd, io_pTrgt, i_sTrgt, + addr + 0x700000000ll, &tmp ); + if ( full ) break; + } + + } /* end if we found an EC dep reg */ + + /* prep pointer for next element (if any) */ + l_ecAddrtPtr++; + + } /** end EC dependent reg loop */ + return full; } @@ -376,15 +642,19 @@ bool FirData_addIdFirsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, * @param io_fd The FIR data stuct. * @param io_pTrgt Pointer to PNOR target. * @param i_sTrgt SCOM target. + * @param i_chipStruct Provides chipType and ecLevel we need + * for EC dependent regs + * * @return True if the PNOR buffer is full, false if there was room. */ bool FirData_addIdRegsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, - SCOM_Trgt_t i_sTrgt ) + SCOM_Trgt_t i_sTrgt, + HOMER_Chip_t *i_chipStruct ) { bool full = false; uint8_t t = i_sTrgt.type; - uint8_t cnt = io_fd->hData->counts[t][REG_IDREG]; + uint8_t cnt = io_fd->hData->regCounts[t][REG_IDREG]; uint32_t i = 0; @@ -399,9 +669,49 @@ bool FirData_addIdRegsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, if ( full ) break; } + + /** Handle EC dependent registers, if any */ + HOMER_ChipSpecAddr_t *l_ecAddrtPtr = io_fd->ecDepReg; + cnt = io_fd->hData->ecDepCounts; + + /** We have a structure with one element for each EC dep address. */ + /** Need to loop thru and verify we have same regType among */ + /** other things prior to using the address. */ + for ( i = 0; i < cnt; i++ ) + { +#ifdef DEBUG_PRD_CHKSTOP_ANALYSIS + TRAC_INFO(" addIdRegsToPnor In/Array: chipType:%X::%X trgType:%X::%X" + " regType:%X::%X ecLevel %X::%X", + i_chipStruct->chipType, l_ecAddrtPtr->chipType, + t, l_ecAddrtPtr->trgtType, + REG_GLBL, l_ecAddrtPtr->regType, + i_chipStruct->chipEcLevel, l_ecAddrtPtr->ddLevel ); +#endif + + /** Need same chipType (nimbus,cumulus,etc..), same target type, */ + /** same register type and EC level must match too */ + if ( (l_ecAddrtPtr->chipType == i_chipStruct->chipType) && + (l_ecAddrtPtr->trgtType == t ) && + (l_ecAddrtPtr->regType == REG_IDREG) && + (l_ecAddrtPtr->ddLevel == i_chipStruct->chipEcLevel) + ) + { /* Using full 64 bit address here */ + addr = l_ecAddrtPtr->address; + + full = FirData_addIdRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr, &tmp ); + if ( full ) break; + } /* end if we found an EC dep reg */ + + /* prep pointer for next element (if any) */ + l_ecAddrtPtr++; + + } /** end EC dependent reg loop */ + + return full; } + /*------------------------------------------------------------------------------ */ /** @brief Adds a target to the PNOR. @@ -409,10 +719,13 @@ bool FirData_addIdRegsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, * @param i_sTrgt SCOM Target. * @param o_noAttn True, if the global registers showed no active * attentions on the target. False, otherwise. + * @param i_chipStruct Provides chipType and ecLevel we need + * for EC dependent regs + * * @return True if the PNOR buffer is full, false if there was room. */ bool FirData_addTrgtToPnor( FirData_t * io_fd, SCOM_Trgt_t i_sTrgt, - bool * o_noAttn ) + bool * o_noAttn, HOMER_Chip_t *i_chipStruct ) { bool full = false; @@ -442,23 +755,23 @@ bool FirData_addTrgtToPnor( FirData_t * io_fd, SCOM_Trgt_t i_sTrgt, * other registers. */ /* Add the GLBLs. */ - full = FirData_addGlblsToPnor( io_fd, pTrgt, i_sTrgt, o_noAttn ); + full = FirData_addGlblsToPnor( io_fd, pTrgt, i_sTrgt, o_noAttn, i_chipStruct ); if ( full || *o_noAttn ) break; /* Add the FIRs. */ - full = FirData_addFirsToPnor( io_fd, pTrgt, i_sTrgt ); + full = FirData_addFirsToPnor( io_fd, pTrgt, i_sTrgt, i_chipStruct ); if ( full ) break; /* Add the REGs. */ - full = FirData_addRegsToPnor( io_fd, pTrgt, i_sTrgt ); + full = FirData_addRegsToPnor( io_fd, pTrgt, i_sTrgt, i_chipStruct ); if ( full ) break; /* Add the IDFIRs. */ - full = FirData_addIdFirsToPnor( io_fd, pTrgt, i_sTrgt ); + full = FirData_addIdFirsToPnor( io_fd, pTrgt, i_sTrgt, i_chipStruct ); if ( full ) break; /* Add the IDREGs. */ - full = FirData_addIdRegsToPnor( io_fd, pTrgt, i_sTrgt ); + full = FirData_addIdRegsToPnor( io_fd, pTrgt, i_sTrgt, i_chipStruct ); if ( full ) break; } while (0); @@ -466,6 +779,7 @@ bool FirData_addTrgtToPnor( FirData_t * io_fd, SCOM_Trgt_t i_sTrgt, return full; } + /*------------------------------------------------------------------------------ */ /** @brief Iterates through configured targets and adds the data to PNOR. @@ -478,102 +792,367 @@ void FirData_addTrgtsToPnor( FirData_t * io_fd ) uint8_t p = 0; uint8_t u = 0; - uint8_t mu = 0; - uint8_t i = 0; - uint8_t j = 0; + uint8_t l_unit = 0; bool isM = false; uint32_t fsi = 0; SCOM_Trgt_t sTrgt; + FirData_existBits_t l_existBits; do { - /* Iterate all PROCs. */ - for ( p = 0; p < MAX_PROC_PER_NODE; p++ ) + memset(&l_existBits, 0x00, sizeof(FirData_existBits_t) ); + + /* Point past HOMER header to first chiplet info */ + uint8_t *l_bytePtr = io_fd->hBuf + sizeof(HOMER_Data_t); + HOMER_Chip_t *l_chipPtr = NULL; + + TRAC_INFO("AddTgtsMain:numChips:%d", io_fd->hData->chipCount); + + /* Iterate ALL CHIPs */ + for ( p = 0; p < io_fd->hData->chipCount; p++ ) { - /* Check if the PROC is configured. */ - if ( 0 == (io_fd->hData->procMask & (0x80 >> p)) ) continue; + l_chipPtr = (HOMER_Chip_t *)l_bytePtr; - /* Check if this PROC is the master PROC and get the FSI base addr. */ - isM = ( p == io_fd->hData->masterProc ); - fsi = io_fd->hData->procFsiBaseAddr[p]; + /* get FSI base address and chip position (proc or centaur) */ + fsi = l_chipPtr->fsiBaseAddr; + p = l_chipPtr->chipPos; - /* Add this PROC to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(TRGT_PROC, p, 0, fsi, isM); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn ); - if ( full ) break; - if ( noAttn ) continue; /* Skip the PROC, EXs, and MCSs */ + TRAC_INFO( " AddTgtsMain:ChipType:%d ChipNumber:%d", + l_chipPtr->chipType, p ); - for ( u = 0; u < MAX_EX_PER_PROC; u++ ) + /* Is this a PROC or Centaur chip ? */ + if ( (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) || + (HOMER_CHIP_CUMULUS == l_chipPtr->chipType) ) { - /* Check if the EX is configured. */ - if ( 0 == (io_fd->hData->exMasks[p] & (0x8000 >> u)) ) continue; + /* To access the 'chiplet exist' structure */ + l_bytePtr += sizeof(HOMER_Chip_t); + + /* 'Existing chiplet area' varies in size */ + if (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) + { + HOMER_ChipNimbus_t *l_nimExistBitPtr = + (HOMER_ChipNimbus_t *)l_bytePtr; + + /* get master proc indicator */ + isM = l_nimExistBitPtr->isMaster; + + /* Exist bit structure can differ so move to */ + /* common format and left justify for ease of use */ + l_existBits.xbusMask = ((uint32_t)(l_nimExistBitPtr->xbusMask)) + << (32 - MAX_XBUS_PER_PROC); + l_existBits.obusMask = ((uint32_t)(l_nimExistBitPtr->obusMask)) + << (32 - MAX_OBUS_PER_PROC); + l_existBits.ecMask = ((uint32_t)(l_nimExistBitPtr->ecMask)) + << (32 - MAX_EC_PER_PROC); + l_existBits.eqMask = ((uint32_t)(l_nimExistBitPtr->eqMask)) + << (32 - MAX_EQ_PER_PROC); + l_existBits.exMask = ((uint32_t)(l_nimExistBitPtr->exMask)) + << (32 - MAX_EX_PER_PROC); + l_existBits.mcbist_mc_Mask = ((uint32_t)(l_nimExistBitPtr->mcbistMask)) + << (32 - MAX_MCBIST_PER_PROC); + l_existBits.mcs_mi_Mask = ((uint32_t)(l_nimExistBitPtr->mcsMask)) + << (32 - MAX_MCS_PER_PROC); + l_existBits.mca_dmi_Mask = ((uint32_t)(l_nimExistBitPtr->mcaMask)) + << (32 - MAX_MCA_PER_PROC); + l_existBits.cappMask = ((uint32_t)(l_nimExistBitPtr->cappMask)) + << (32 - MAX_CAPP_PER_PROC); + l_existBits.pecMask = ((uint32_t)(l_nimExistBitPtr->pecMask)) + << (32 - MAX_PEC_PER_PROC); + l_existBits.phbMask = ((uint32_t)(l_nimExistBitPtr->phbMask)) + << (32 - MAX_PHB_PER_PROC); + + /* advance our pointer to next chip type */ + l_bytePtr += sizeof(HOMER_ChipNimbus_t); + + } /* if nimbus */ + else if (HOMER_CHIP_CUMULUS == l_chipPtr->chipType) + { + HOMER_ChipCumulus_t *l_cumExistBitPtr = + (HOMER_ChipCumulus_t *)l_bytePtr; + + /* get master proc indicator */ + isM = l_cumExistBitPtr->isMaster; + + /* Exist bit structure can differ so move to */ + /* common format and left justify for ease of use */ + l_existBits.xbusMask = ((uint32_t)(l_cumExistBitPtr->xbusMask)) + << (32 - MAX_XBUS_PER_PROC); + l_existBits.obusMask = ((uint32_t)(l_cumExistBitPtr->obusMask)) + << (32 - MAX_OBUS_PER_PROC); + l_existBits.ecMask = ((uint32_t)(l_cumExistBitPtr->ecMask)) + << (32 - MAX_EC_PER_PROC); + l_existBits.eqMask = ((uint32_t)(l_cumExistBitPtr->eqMask)) + << (32 - MAX_EQ_PER_PROC); + l_existBits.exMask = ((uint32_t)(l_cumExistBitPtr->exMask)) + << (32 - MAX_EX_PER_PROC); + l_existBits.mcbist_mc_Mask = ((uint32_t)(l_cumExistBitPtr->mcMask)) + << (32 - MAX_MC_PER_PROC); + l_existBits.mcs_mi_Mask = ((uint32_t)(l_cumExistBitPtr->miMask)) + << (32 - MAX_MI_PER_PROC); + l_existBits.mca_dmi_Mask = ((uint32_t)(l_cumExistBitPtr->dmiMask)) + << (32 - MAX_DMI_PER_PROC); + l_existBits.cappMask = ((uint32_t)(l_cumExistBitPtr->cappMask)) + << (32 - MAX_CAPP_PER_PROC); + l_existBits.pecMask = ((uint32_t)(l_cumExistBitPtr->pecMask)) + << (32 - MAX_PEC_PER_PROC); + l_existBits.phbMask = ((uint32_t)(l_cumExistBitPtr->phbMask)) + << (32 - MAX_PHB_PER_PROC); + + /* advance our pointer to next chip type */ + l_bytePtr += sizeof(HOMER_ChipCumulus_t); + } /* else if cumulus */ + + TRAC_INFO( " Masks XBUS:%X OBUS:%X EC:%X EQ:%X EX:%X CAPP:%X PEC:%X PHB:%X", + l_existBits.xbusMask, l_existBits.obusMask, l_existBits.ecMask, + l_existBits.eqMask, l_existBits.exMask, l_existBits.cappMask, + l_existBits.pecMask, l_existBits.phbMask ); + TRAC_INFO( " Masks MCBIST:%X MCS:%X MCA:%X", + l_existBits.mcbist_mc_Mask, l_existBits.mcs_mi_Mask, + l_existBits.mca_dmi_Mask ); + + /* Add this PROC to the PNOR. */ + sTrgt = SCOM_Trgt_getTrgt(TRGT_PROC, p, 0, fsi, isM); + full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); + /* noAttn is true when we have global regs but none */ + /* indicate an attention is present */ + if ( full ) break; + if ( noAttn ) continue; /* Skip other proc chiplets */ + + + /* gather other chiplets on the processor */ + for ( u = 0; u < MAX_XBUS_PER_PROC; u++ ) + { + /* Check if the XBUS is configured. */ + if ( 0 == (l_existBits.xbusMask & (0x80000000 >> u)) ) continue; - /* Add this EX to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(TRGT_EX, p, u, fsi, isM); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn ); + /* Add this XBUS to the PNOR. */ + sTrgt = SCOM_Trgt_getTrgt(TRGT_XBUS, p, u, fsi, isM); + full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); + if ( full ) break; + } if ( full ) break; - if ( noAttn ) continue; /* Skip the EX */ - } - if ( full ) break; - for ( u = 0; u < MAX_MCS_PER_PROC; u++ ) - { - /* Check if the MCS is configured. */ - if ( 0 == (io_fd->hData->mcsMasks[p] & (0x80 >> u)) ) continue; + /* gather other chiplets on the processor */ + for ( u = 0; u < MAX_OBUS_PER_PROC; u++ ) + { + /* Check if the OBUS is configured. */ + if ( 0 == (l_existBits.obusMask & (0x80000000 >> u)) ) continue; + + /* Add this OBUS to the PNOR. */ + sTrgt = SCOM_Trgt_getTrgt(TRGT_OBUS, p, u, fsi, isM); + full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); + if ( full ) break; + } + if ( full ) break; - /* Add this MCS to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(TRGT_MCS, p, u, fsi, isM); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn ); + /* gather more proc chiplets */ + for ( u = 0; u < MAX_CAPP_PER_PROC; u++ ) + { + /* Check if the CAPP is configured. */ + if ( 0 == (l_existBits.cappMask & (0x80000000 >> u)) ) continue; + + /* Add this CAPP to the PNOR. */ + sTrgt = SCOM_Trgt_getTrgt(TRGT_CAPP, p, u, fsi, isM); + full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); + if ( full ) break; + } if ( full ) break; - if ( noAttn ) continue; /* Skip the MCS */ - } - if ( full ) break; - } - if ( full ) break; - /* Iterate all MEMBs. Must do this separate of from the PROCs because */ - /* it is possible a MEMBUF could be reporting an attention but the */ - /* connected PROC is not. */ - for ( i = 0; i < MAX_MEMBUF_PER_NODE; i++ ) - { - p = i / MAX_MEMBUF_PER_PROC; - u = i % MAX_MEMBUF_PER_PROC; + /* gather other chiplets on the processor */ + for ( u = 0; u < MAX_PEC_PER_PROC; u++ ) + { + /* Check if the PEC is configured. */ + if ( 0 == (l_existBits.pecMask & (0x80000000 >> u)) ) continue; + + /* Add this PEC to the PNOR. */ + sTrgt = SCOM_Trgt_getTrgt(TRGT_PEC, p, u, fsi, isM); + full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); + if ( full ) break; + if ( noAttn ) continue; /* Skip the rest */ + + /* gather PHB's under the PEC */ + /* ************************** */ + /* PEC0-> PHB0 */ + /* PEC1-> PHB1 PHB2 */ + /* PEC2-> PHB3 PHB4 PHB5 */ + /* ************************** */ + uint32_t l_PhbPos; + + /* u will be 0, l_unit 0 */ + /* u will be 1, l_unit 0 and 1 */ + /* u will be 2, l_unit 0 and 1 and 2 */ + for ( l_unit = 0; l_unit < (u+1); l_unit++ ) + { + l_PhbPos = u + l_unit; + /** When we hit PEC2, need to bump PHB position */ + if ((MAX_PEC_PER_PROC - 1) == u) + { + l_PhbPos++; + } /* if last PEC unit */ + + /* Check if the PHB is configured. */ + if ( 0 == (l_existBits.phbMask & (0x80000000 >> l_PhbPos)) ) continue; + + /* Add this PHB to the PNOR. */ + sTrgt = SCOM_Trgt_getTrgt(TRGT_PHB, p, l_PhbPos, fsi, isM); + full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); + if ( full ) break; + if ( noAttn ) continue; /* Skip the rest */ + + } /* end for on PHB chiplet */ + if ( full ) break; + + } /* end for on PEC chiplet */ + if ( full ) break; - /* Check if the MEMBUF is configured. */ - if ( 0 == (io_fd->hData->membMasks[p] & (0x80 >> u)) ) continue; + /* gather other chiplets on the processor */ + for ( u = 0; u < MAX_EC_PER_PROC; u++ ) + { + /* Check if the EC is configured. */ + if ( 0 == (l_existBits.ecMask & (0x80000000 >> u)) ) continue; - /* Get the FSI base address. */ - fsi = io_fd->hData->membFsiBaseAddr[p][u]; + /* Add this EC to the PNOR. */ + sTrgt = SCOM_Trgt_getTrgt(TRGT_EC, p, u, fsi, isM); + full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); + if ( full ) break; + if ( noAttn ) continue; /* Skip the rest */ - /* Add this MEMBUF to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(TRGT_MEMBUF, p, u, fsi, false); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn ); - if ( full ) break; - if ( noAttn ) continue; /* Skip the MEMBUF and MBAs */ + } /* end for on EC chiplet */ + if ( full ) break; - for ( j = 0; j < MAX_MBA_PER_MEMBUF; j++ ) - { - mu = u * MAX_MBA_PER_MEMBUF + j; + /* gather other chiplets on the processor */ + for ( u = 0; u < MAX_EQ_PER_PROC; u++ ) + { + /* Check if the EQ is configured. */ + if ( 0 == (l_existBits.eqMask & (0x80000000 >> u)) ) continue; + + /* Add this EQ to the PNOR. */ + sTrgt = SCOM_Trgt_getTrgt(TRGT_EQ, p, u, fsi, isM); + full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); + if ( full ) break; + if ( noAttn ) continue; /* Skip the rest */ + + /* gather other chiplets on the processor */ + uint32_t l_ExPerEq = (MAX_EX_PER_PROC/MAX_EQ_PER_PROC); + uint32_t l_ExPos; - /* Check if the MBA is configured. */ - if ( 0 == (io_fd->hData->mbaMasks[p] & (0x8000 >> mu)) ) - continue; + for (l_unit=0; l_unit < l_ExPerEq; l_unit++) + { + l_ExPos = (l_ExPerEq * u) + l_unit; - /* Add this MBA to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(TRGT_MBA, p, mu, fsi, false); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn ); + /* Check if the EX is configured. */ + if ( 0 == (l_existBits.exMask & (0x80000000 >> l_ExPos)) ) continue; + + /* Add this EX to the PNOR. */ + sTrgt = SCOM_Trgt_getTrgt(TRGT_EX, p, l_ExPos, fsi, isM); + full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); + if ( full ) break; + if ( noAttn ) continue; /* Skip the rest */ + + } /* end for on EX chiplet */ + if ( full ) break; + + } /* end for on EQ chiplet */ + if ( full ) break; + + + /* processor type can impact next few units */ + TrgtType_t l_pnorTarget = (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) ? + TRGT_MCBIST : TRGT_MC; + uint32_t l_maxPerProc = (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) ? + MAX_MCBIST_PER_PROC : MAX_MC_PER_PROC; + + TrgtType_t l_pnorTarg2 = (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) ? + TRGT_MCA : TRGT_DMI; + uint32_t l_maxPerProc2 = (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) ? + MAX_MCA_PER_PROC : MAX_DMI_PER_PROC; + + uint32_t l_UnitPerMc = l_maxPerProc2 / l_maxPerProc; + uint8_t l_unitNumber; + + for ( u = 0; u < l_maxPerProc; u++ ) + { + /* Check if MCBIST / MC is configured. */ + if ( 0 == (l_existBits.mcbist_mc_Mask & (0x80000000 >> u)) ) continue; + + /* Add this MCBIST or MC to the PNOR. */ + sTrgt = SCOM_Trgt_getTrgt(l_pnorTarget, p, u, fsi, isM); + full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); + if ( full ) break; + if ( noAttn ) continue; /* Skip the rest */ + + /* Grab underlying MCA/DMI chiplet */ + for ( l_unit = 0; l_unit < l_UnitPerMc; l_unit++ ) + { + /* u=0 or 1 while l_unit is 0 thru 3 */ + /* Leading to unit number 0:3 or 4:7 */ + l_unitNumber = l_unit + (u * l_UnitPerMc); + /* Check if the MCA / DMI is configured. */ + if ( 0 == (l_existBits.mca_dmi_Mask & (0x80000000 >> l_unitNumber)) ) continue; + + /* Add this MCA / DMI to the PNOR. */ + sTrgt = SCOM_Trgt_getTrgt(l_pnorTarg2, p, l_unitNumber, fsi, isM); + full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); + if ( full ) break; + + } /* end for on MCA/DMI */ + if ( full ) break; + + } /* end for on MCBIST */ + if ( full ) break; + + + l_pnorTarget = (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) ? + TRGT_MCS : TRGT_MI; + l_maxPerProc = (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) ? + MAX_MCS_PER_PROC : MAX_MI_PER_PROC; + + for ( u = 0; u < l_maxPerProc; u++ ) + { + /* Check if the MCS / MI is configured. */ + if ( 0 == (l_existBits.mcs_mi_Mask & (0x80000000 >> u)) ) continue; + + /* Add this MCS or MI to the PNOR. */ + sTrgt = SCOM_Trgt_getTrgt(l_pnorTarget, p, u, fsi, isM); + full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); + if ( full ) break; + } if ( full ) break; - if ( noAttn ) continue; /* Skip the MEMBUF */ - } - if ( full ) break; - } - if ( full ) break; + + + } /* if processor chip type */ + else if (HOMER_CHIP_CENTAUR == l_chipPtr->chipType) + { + /* HOMER_ChipCentaur_t *l_cenExistBitPtr = + (HOMER_ChipCentaur_t *)l_bytePtr; */ + /* uint32_t l_mbaMask = ((uint32_t) l_cenExistBitPtr->mbaMask) << + (sizeof(uint32_t) - MAX_MBA_PER_MEMBUF) */ + + /* we have Centaur chipPos in 'p' and fsi address in 'fsi' */ + + /* add this centaur later and iterate thru l_mbaMask */ + /* don't need for initial support */ + /* TODO RTC 173614 -- with CUMULUS */ + + /* advance our pointer to next chip type */ + l_bytePtr += sizeof(HOMER_ChipCentaur_t); + + } /* end if centaur chip type */ + else + { + /* unexpected chip type */ + TRAC_ERR( "addTrgtsToPnor saw invalid chip:0x%X", + l_chipPtr->chipType ); + break; + } /* end if centaur chip type */ + + } /* end for on all CHIPS we have in homer data */ } while (0); -} +} /* end FirData_addTrgtsToPnor */ /*------------------------------------------------------------------------------ */ @@ -641,7 +1220,7 @@ int32_t FirData_init( FirData_t * io_fd, } /* Check for valid HOMER data. */ - if ( HOMER_FIR1 != io_fd->hData->header ) + if ( HOMER_FIR2 != io_fd->hData->header ) { break; /* nothing to analyze. */ } @@ -669,11 +1248,11 @@ int32_t FirData_init( FirData_t * io_fd, for ( t = TRGT_FIRST; t < TRGT_MAX; t++ ) { x[t][REG_GLBL] = curIdx; - x[t][REG_FIR] = x[t][REG_GLBL] + sz_u32 * io_fd->hData->counts[t][REG_GLBL]; - x[t][REG_REG] = x[t][REG_FIR] + sz_u32 * io_fd->hData->counts[t][REG_FIR]; - x[t][REG_IDFIR] = x[t][REG_REG] + sz_u32 * io_fd->hData->counts[t][REG_REG]; - x[t][REG_IDREG] = x[t][REG_IDFIR] + sz_u64 * io_fd->hData->counts[t][REG_IDFIR]; - curIdx = x[t][REG_IDREG] + sz_u64 * io_fd->hData->counts[t][REG_IDREG]; + x[t][REG_FIR] = x[t][REG_GLBL] + sz_u32 * io_fd->hData->regCounts[t][REG_GLBL]; + x[t][REG_REG] = x[t][REG_FIR] + sz_u32 * io_fd->hData->regCounts[t][REG_FIR]; + x[t][REG_IDFIR] = x[t][REG_REG] + sz_u32 * io_fd->hData->regCounts[t][REG_REG]; + x[t][REG_IDREG] = x[t][REG_IDFIR] + sz_u64 * io_fd->hData->regCounts[t][REG_IDFIR]; + curIdx = x[t][REG_IDREG] + sz_u64 * io_fd->hData->regCounts[t][REG_IDREG]; } /* Check to make sure the list data is not larger than the available */ @@ -686,8 +1265,45 @@ int32_t FirData_init( FirData_t * io_fd, break; } - /* Now, get the pointers for each list. */ + /* Now, skip chip sections. */ reglist = io_fd->hBuf + sz_hData; + HOMER_Chip_t *l_chiptPtr = NULL; + + /* Need to skip over chip list **/ + uint32_t l_chipNum; + for ( l_chipNum=0; + (l_chipNum < io_fd->hData->chipCount); + l_chipNum++ ) + { + l_chiptPtr = (HOMER_Chip_t *)reglist; + + /* Skip section on chip type, chip position, etc... */ + reglist += sizeof(HOMER_Chip_t); + + /* 'Existing chiplet area' varies in size */ + if (HOMER_CHIP_NIMBUS == l_chiptPtr->chipType) + { + reglist += sizeof(HOMER_ChipNimbus_t); + } + else if (HOMER_CHIP_CUMULUS == l_chiptPtr->chipType) + { + reglist += sizeof(HOMER_ChipCumulus_t); + } + else if (HOMER_CHIP_CENTAUR == l_chiptPtr->chipType) + { + reglist += sizeof(HOMER_ChipCentaur_t); + } + else + { + TRAC_ERR(FUNC"Chiptype is invalid %X ", l_chiptPtr->chipType); + rc = FAIL; + break; + } + + } /* end for loop skipping chip info sections */ + + + /* Now, get the pointers for each list. */ for ( t = TRGT_FIRST; t < TRGT_MAX; t++ ) { (io_fd->hPtrs[t]).glbl = (uint32_t *)(reglist + x[t][REG_GLBL] ); @@ -697,6 +1313,10 @@ int32_t FirData_init( FirData_t * io_fd, (io_fd->hPtrs[t]).idReg = (uint64_t *)(reglist + x[t][REG_IDREG]); } + /* Set EC level dep reg list ptr - at very end of list */ + io_fd->ecDepReg = (HOMER_ChipSpecAddr_t *)(reglist + curIdx); + + } while (0); return rc; @@ -727,7 +1347,7 @@ int32_t FirData_captureCsFirData( uint8_t * i_hBuf, uint32_t i_hBufSize, } /* Check for valid HOMER data. */ - if ( HOMER_FIR1 != fd.hData->header ) + if ( HOMER_FIR2 != fd.hData->header ) { TRAC_ERR( FUNC"No HOMER data detected: header=0x%08x", fd.hData->header ); @@ -737,8 +1357,8 @@ int32_t FirData_captureCsFirData( uint8_t * i_hBuf, uint32_t i_hBufSize, /* Start adding register data to PNOR for each target. */ FirData_addTrgtsToPnor( &fd ); - /* Write the buffer to PNOR. */ -/* TODO: 175241 + /* Write Buffer to PNOR */ +/* TODO: enable when function is supported. rc = PNOR_writeFirData( fd.hData->pnorInfo, fd.pBuf, fd.pBufSize ); if ( SUCCESS != rc ) { diff --git a/src/occ_405/firdata/firDataConst_common.h b/src/occ_405/firdata/firDataConst_common.h index a30785e..403a028 100644 --- a/src/occ_405/firdata/firDataConst_common.h +++ b/src/occ_405/firdata/firDataConst_common.h @@ -33,10 +33,13 @@ #include <stdint.h> /** Target types for all supported targets. */ +/** NOTE: These are used to build the register list in HOMER data */ +/** and also to create the exiting chiplet masks. Hence, */ +/** the numbers assigned here have to match the sequence */ +/** of chiplets in HOMER_ChipNimbus_t, HOMER_ChipCumulus_t, etc. */ typedef enum { /* NOTE: These will be used as array indexes. */ - TRGT_FIRST = 0, /** Common Nimbus/Cumulus types */ @@ -127,4 +130,3 @@ typedef enum } IplState_t; #endif /* __firDataConst_common_h */ - diff --git a/src/occ_405/firdata/fir_data_collect.c b/src/occ_405/firdata/fir_data_collect.c index d00d55a..a2af34f 100644 --- a/src/occ_405/firdata/fir_data_collect.c +++ b/src/occ_405/firdata/fir_data_collect.c @@ -32,6 +32,7 @@ #include "tpc_register_addresses.h" #include <trac.h> #include <homer.h> +#include <firData.h> FIR_HEAP_BUFFER(uint8_t G_fir_heap[FIR_HEAP_SECTION_SIZE]); FIR_PARMS_BUFFER(uint8_t G_fir_data_parms[FIR_PARMS_SECTION_SIZE]); @@ -49,9 +50,6 @@ uint32_t G_fir_master = FIR_OCC_NOT_FIR_MASTER; void fir_data_collect(void) { -/* TEMP -- NOT YET SUPPORTED */ -TRAC_ERR("fir_data_collect: FirData_captureCsFirData not yet called/enabled"); -#if 0 int32_t l_rc = 0; // Homer data section and size @@ -68,8 +66,6 @@ TRAC_ERR("fir_data_collect: FirData_captureCsFirData not yet called/enabled"); // Trace the rc only, error logs cannot be collected in this state TRAC_IMP("Checkstop FIR data capture completed with rc=%d", l_rc); -#endif - } diff --git a/src/occ_405/firdata/homerData_common.h b/src/occ_405/firdata/homerData_common.h index 1336258..9b09086 100644 --- a/src/occ_405/firdata/homerData_common.h +++ b/src/occ_405/firdata/homerData_common.h @@ -38,26 +38,22 @@ * in the event of a system checkstop. The data will be stored in the following * format: * - * - HOMER_Data_t struct - This has all of the information characterizing what - * hardware is configured and how many addresses are in each register - * list. See the struct definition below. + * - HOMER_Data_t struct - This contains PNOR information, IPL state, number of + * configured chips, and number of register addresses per target type per + * register type. * - * - Rgister address lists - These lists vary in size depending on the number - * of register addresses needed in each list. The list counts are - * stored in HOMER_Data_t::counts. All lists for each target type will - * be stored in the following order: - * - PROC lists - * - EX lists - * - MCS lists - * - MEMB lists - * - MBA lists - * Each target type will have a set of lists that will be stored in the - * following order: - * - Global FIRs 32-bit addresses - * - FIRs 32-bit addresses - * - Registers 32-bit addresses - * - Indirect-SCOM FIRs 64-bit addresses - * - Indirect-SCOM registers 64-bit addresses + * - For each configured chip, the following format will be used: + * - HOMER_Chip_t struct - containing FSI base address, chip type, and chip + * position. + * - Immediately following will be a chip struct that is specific to the + * chip type stored in the preceding struct. These vary in size and + * structure depending on the chip type. + * + * - Register address lists - These lists vary in size depending on the number + * of register addresses needed in each list. The list counts are stored in + * HOMER_Data_t::regCounts. Order of the lists must match the array indexes + * HOMER_Data_t::regCounts, which are specified in TrgtType_t and + * RegType_t. * * Note that FIRs and indirect-SCOM FIRs characterize a set of registers to * capture. In addition to capturing the FIR (or ID FIR), the OCC will need to @@ -77,7 +73,8 @@ typedef enum { - HOMER_FIR1 = 0x46495231, /** FIR data version 1 ("FIR1" in ascii) */ + HOMER_FIR1 = 0x46495231, /** FIR data version 1 ("FIR1" in ascii) P8 */ + HOMER_FIR2 = 0x46495232, /** FIR data version 1 ("FIR2" in ascii) P9 */ } HOMER_Version_t; @@ -97,45 +94,17 @@ typedef struct __attribute__((packed)) { uint32_t header; /** Magic number to indicate valid data and version */ - uint16_t iplState : 1; /** See enum IplState_t */ - uint16_t reserved : 15; - - uint8_t masterProc; /** The position of the master PROC */ - - /** Bitwise mask to indicate which PROCs are configured (max 8). The mask - * bit position is consistant with PROC ATTR_POSITION attribute. */ - uint8_t procMask; - - /** Bitwise masks to indicate which EXs are configured (16 per PROC). The - * array index is the associated PROC position. The mask bit position is - * consistant with the EX's ATTR_CHIP_UNIT attribute. */ - uint16_t exMasks[MAX_PROC_PER_NODE]; - - /** Bitwise masks to indicate which MCSs are configured (8 per PROC). The - * array index is the associated PROC position. The mask bit position is - * consistant with the MCS's ATTR_CHIP_UNIT attribute. */ - uint8_t mcsMasks[MAX_PROC_PER_NODE]; + uint8_t chipCount; /** Number of configured chips per node */ - /** Bitwise masks to indicate which MEMBs are configured (8 per PROC). The - * array index is the associated PROC position. The mask bit position is - * consistant with the ATTR_CHIP_UNIT attribute of the connected MCS. */ - uint8_t membMasks[MAX_PROC_PER_NODE]; - - /** Bitwise masks to indicate which MBAs are configured (16 per PROC). The - * array index is the associated PROC position. The mask bit position is - * calculated as: - * (MEMB position * MAX_MBA_PER_MEMB) + MBA's ATTR_CHIP_UNIT attribute - */ - uint16_t mbaMasks[MAX_PROC_PER_NODE]; + uint8_t iplState : 1; /** See IplState_t. */ + uint8_t reserved : 7; /** Contains number of registers per type for each target type. */ - uint8_t counts[TRGT_MAX][REG_MAX]; - - /** FSI base address for each PROC chip. */ - uint32_t procFsiBaseAddr[MAX_PROC_PER_NODE]; + uint8_t regCounts[TRGT_MAX][REG_MAX]; - /** FSI base address for each MEMB chip. */ - uint32_t membFsiBaseAddr[MAX_PROC_PER_NODE][MAX_MEMBUF_PER_PROC]; + /** Number of regs that are dependent on EC level **/ + /** (these registers follow the normal register list) **/ + uint8_t ecDepCounts; /** Information regarding the PNOR location and size. */ HOMER_PnorInfo_t pnorInfo; @@ -145,29 +114,161 @@ typedef struct __attribute__((packed)) /** @return An initialized HOMER_Data_t struct. */ static inline HOMER_Data_t HOMER_getData() { - HOMER_PnorInfo_t p; - HOMER_Data_t d; - - p.pnorOffset = 0; - p.pnorSize = 0; - p.mmioOffset = 0; - p.norWorkarounds = 0; - - d.header = HOMER_FIR1; - d.reserved = 0; - d.masterProc = 0; - d.procMask = 0; - d.pnorInfo = p; - - memset( d.exMasks, 0x00, sizeof(d.exMasks) ); - memset( d.mcsMasks, 0x00, sizeof(d.mcsMasks) ); - memset( d.membMasks, 0x00, sizeof(d.membMasks) ); - memset( d.mbaMasks, 0x00, sizeof(d.mbaMasks) ); - memset( d.counts, 0x00, sizeof(d.counts) ); - memset( d.procFsiBaseAddr, 0xff, sizeof(d.procFsiBaseAddr) ); - memset( d.membFsiBaseAddr, 0xff, sizeof(d.membFsiBaseAddr) ); + HOMER_Data_t d; memset( &d, 0x00, sizeof(d) ); /* init to zero */ + + d.header = HOMER_FIR2; return d; } +/*----------------------------------------------------------------------------*/ + +/** Supported chip types. */ +typedef enum +{ + HOMER_CHIP_NIMBUS, /** P9 Nimbus processor chip */ + HOMER_CHIP_CUMULUS, /** P9 Cumulus processor chip */ + HOMER_CHIP_CENTAUR, /** Centaur memory buffer chip */ + +} HOMER_ChipType_t; + +/** Information for each configured chip. */ +typedef struct __attribute__((packed)) +{ + uint32_t fsiBaseAddr; /** FSI base address for the chip. */ + + uint16_t chipType : 4; /** Chip type (see HOMER_ChipType_t) */ + uint16_t chipPos : 6; /** Chip position relative to the node. */ + uint16_t reserved : 6; + + uint8_t chipEcLevel; /** EC level for this chip */ + +} HOMER_Chip_t; + + +/** Used for Registers that have EC level dependencies */ +typedef struct __attribute__((packed)) +{ + uint32_t chipType : 4; /** See HOMER_ChipType_t. */ + uint32_t trgtType : 6; /** See TrgtType_t. */ + uint32_t regType : 4; /** See RegType_t. */ + uint32_t ddLevel : 8; /** A zero value applies to all levels on a chip. */ + uint32_t reserved : 10; /** unused at this time */ + + /** The 32 or 64 bit address (right justified). */ + uint64_t address; + +} HOMER_ChipSpecAddr_t; + + +/** @return An initialized HOMER_Chip_t struct. */ +static inline HOMER_Chip_t HOMER_getChip( HOMER_ChipType_t i_type ) +{ + HOMER_Chip_t c; memset( &c, 0x00, sizeof(c) ); /* init to zero */ + + c.fsiBaseAddr = 0xffffffff; + c.chipType = i_type; + + return c; +} + +/*----------------------------------------------------------------------------*/ + +/** Information specific to a P9 Nimbus processor chip. */ +typedef struct __attribute__((packed)) +{ + uint32_t isMaster : 1; /** 1 if this is the master PROC, 0 otherwise */ + uint32_t xbusMask : 3; /** Mask of configured XBUS units (0-2) */ + uint32_t obusMask : 4; /** Mask of configured OBUS units (0-3) */ + uint32_t ecMask : 24; /** Mask of configured EC units (0-23) */ + + uint32_t eqMask : 6; /** Mask of configured EQ units (0-5) */ + uint32_t exMask : 12; /** Mask of configured EX units (0-11) */ + uint32_t mcbistMask : 2; /** Mask of configured MCBIST units (0-1) */ + uint32_t mcsMask : 4; /** Mask of configured MCS units (0-3) */ + uint32_t mcaMask : 8; /** Mask of configured MCA units (0-7) */ + + uint16_t cappMask : 2; /** Mask of configured CAPP units (0-1) */ + uint16_t pecMask : 3; /** Mask of configured PEC units (0-2) */ + uint16_t phbMask : 6; /** Mask of configured PHB units (0-5) */ + uint16_t reserved : 5; + +} HOMER_ChipNimbus_t; + +/** @return An initialized HOMER_ChipNimbus_t struct. */ +static inline HOMER_ChipNimbus_t HOMER_initChipNimbus() +{ + HOMER_ChipNimbus_t c; memset( &c, 0x00, sizeof(c) ); /* init to zero */ + + return c; +} + +/*----------------------------------------------------------------------------*/ + +/** Information specific to a P9 Cumulus processor chip. */ +typedef struct __attribute__((packed)) +{ + uint32_t isMaster : 1; /** 1 if this is the master PROC, 0 otherwise */ + uint32_t xbusMask : 3; /** Mask of configured XBUS units (0-2) */ + uint32_t obusMask : 4; /** Mask of configured OBUS units (0-3) */ + uint32_t ecMask : 24; /** Mask of configured EC units (0-23) */ + + uint32_t eqMask : 6; /** Mask of configured EQ units (0-5) */ + uint32_t exMask : 12; /** Mask of configured EX units (0-11) */ + uint32_t mcMask : 2; /** Mask of configured MC units (0-1) */ + uint32_t miMask : 4; /** Mask of configured MI units (0-3) */ + uint32_t dmiMask : 8; /** Mask of configured DMI units (0-7) */ + + uint16_t cappMask : 2; /** Mask of configured CAPP units (0-1) */ + uint16_t pecMask : 3; /** Mask of configured PEC units (0-2) */ + uint16_t phbMask : 6; /** Mask of configured PHB units (0-5) */ + uint16_t reserved : 5; + +} HOMER_ChipCumulus_t; + +/** @return An initialized HOMER_ChipCumulus_t struct. */ +static inline HOMER_ChipCumulus_t HOMER_initChipCumulus() +{ + HOMER_ChipCumulus_t c; memset( &c, 0x00, sizeof(c) ); /* init to zero */ + + return c; +} + +/*----------------------------------------------------------------------------*/ + +/** Information specific to a Centaur memory buffer chip. */ +typedef struct __attribute__((packed)) +{ + uint8_t mbaMask : 2; /** Mask of configured MBA units (0-1) */ + uint8_t reserved : 6; + +} HOMER_ChipCentaur_t; + +/** @return An initialized HOMER_ChipCentaur_t struct. */ +static inline HOMER_ChipCentaur_t HOMER_initChipCentaur() +{ + HOMER_ChipCentaur_t c; memset( &c, 0x00, sizeof(c) ); /* init to zero */ + + return c; +} + +/** @brief Chip information inserted into HOMER data section after header + * + * There is basically an array of these after the initial HOMER + * section (HOMER_Data_t). The register info then follows. + */ +typedef struct __attribute__((packed)) +{ + HOMER_Chip_t hChipType; /* Nimbus, Centaur, EC Level, etc...*/ + + union + { + HOMER_ChipNimbus_t hChipN; + HOMER_ChipCumulus_t hChipC; + HOMER_ChipCentaur_t hChipM; + }; + +} HOMER_ChipInfo_t; + + #endif /* __homerData_common_h */ diff --git a/src/occ_405/firdata/pnorData_common.h b/src/occ_405/firdata/pnorData_common.h index a020ae9..faf14c0 100644 --- a/src/occ_405/firdata/pnorData_common.h +++ b/src/occ_405/firdata/pnorData_common.h @@ -31,6 +31,7 @@ * because OCC strictly uses C. */ #include <firDataConst_common.h> +#include <string.h> /** This file is used to define the format of the register data captured by the * OCC and stored in PNOR. The data will be stored in the following format: @@ -53,12 +54,9 @@ * - Each target type may have associated global registers. If none exist, * simply capture all registers for that type. However, if they do exist * and the values of ALL the global registers are zero, skip capturing - * the associated targets using the following rules: - * - For a PROC, skip this PROC and all associated EXs, and MCSs. - * - For an EX, skip this EX. - * - For an MCS, skip this MCS. - * - For a MEMB, skip this MEMB and all associated MBAs. - * - For an MBA, skip this MBA. + * the associated registers of the target and any subsequent targets on + * the affinity path. Example, + * - For a MCBIST, skip this MCBIST and all associated MCSs, and MCAs. * - If for some reason we run out of space in the PNOR, do not SCOM any * more registers, set the 'full' bit in the PNOR_Data_t struct, and * write all data successfully captured to PNOR. @@ -66,7 +64,8 @@ typedef enum { - PNOR_FIR1 = 0x46495231, /** FIR data version 1 ("FIR1" in ascii) */ + PNOR_FIR1 = 0x46495231, /** FIR data version 1 ("FIR1" in ascii) P8 */ + PNOR_FIR2 = 0x46495232, /** FIR data version 2 ("FIR2" in ascii) P9 */ } PNOR_Version_t; @@ -75,21 +74,19 @@ typedef struct __attribute__((packed)) { uint32_t header; /** Magic number to indicate valid data and version */ - uint32_t trgts : 8; /** Number of targets with register data */ - uint32_t full : 1; /** 1 if PNOR data is full and data may be missing*/ - uint32_t iplState : 1; /** See enum IplState_t */ - uint32_t reserved : 22; + uint16_t trgts : 12; /** Number of targets with register data */ + uint16_t full : 1; /** 1 if PNOR data is full and data incomplete */ + uint16_t iplState : 1; /** See enum IplState_t */ + uint16_t reserved : 2; } PNOR_Data_t; /** @return An initialized PNOR_Data_t struct. */ static inline PNOR_Data_t PNOR_getData() { - PNOR_Data_t d; - d.header = PNOR_FIR1; - d.trgts = 0; - d.full = 0; - d.reserved = 0; + PNOR_Data_t d; memset( &d, 0x00, sizeof(d) ); /* init to zero */ + + d.header = PNOR_FIR2; return d; }; @@ -99,40 +96,37 @@ typedef enum { PNOR_Trgt_MAX_REGS_PER_TRGT = 511, /* Currently expect 266 on the PROC */ PNOR_Trgt_MAX_ID_REGS_PER_TRGT = 15, /* Currently expect 9 on the MBA */ - PNOR_Trgt_MAX_SCOM_ERRORS = 511, /* Should be plenty */ + PNOR_Trgt_MAX_SCOM_ERRORS = 255, /* Should be plenty */ } PNOR_Trgt_RegLimits_t; /** Information for each target with SCOM data. */ typedef struct __attribute__((packed)) { - uint32_t reserved1: 3; - uint32_t procPos : 3; /** The processor position (0-7) */ - uint32_t unitPos : 4; /** Unit position relative to the processor (0-15) */ + uint32_t chipPos : 6; /** Parent chip position relative to the node */ + uint32_t unitPos : 5; /** Unit position relative to the parent chip */ uint32_t regs : 9; /** Number of normal registers */ uint32_t idRegs : 4; /** Number of indirect-SCOM registers */ - uint32_t scomErrs : 9; /** Number of SCOM errors detected */ + uint32_t scomErrs : 8; /** Number of SCOM errors detected */ uint8_t trgtType : 6; /** Target type. See enum TrgtType_t */ uint8_t reserved : 2; } PNOR_Trgt_t; -/** @param i_type Target type. See enum TrgtType_t. - * @param i_procPos The processor position. - * @param i_procUnitPos Unit position relative to the processor. +/** @param i_trgtType Target type. See enum TrgtType_t. + * @param i_chipPos Parent chip position relative to the node. + * @param i_unitPos Unit position relative to the parent chip. * @return An initialized PNOR_Data_t struct. */ -static inline PNOR_Trgt_t PNOR_getTrgt( uint32_t i_type, uint32_t i_procPos, - uint32_t i_procUnitPos ) +static inline PNOR_Trgt_t PNOR_getTrgt( uint32_t i_trgtType, uint32_t i_chipPos, + uint32_t i_unitPos ) { - PNOR_Trgt_t t; - t.trgtType = i_type; - t.procPos = i_procPos; - t.unitPos = i_procUnitPos; - t.regs = 0; - t.idRegs = 0; - t.scomErrs = 0; + PNOR_Trgt_t t; memset( &t, 0x00, sizeof(t) ); /* init to zero */ + + t.trgtType = i_trgtType; + t.chipPos = i_chipPos; + t.unitPos = i_unitPos; return t; }; diff --git a/src/occ_405/firdata/scom_trgt.c b/src/occ_405/firdata/scom_trgt.c index 468914c..15ad3fc 100644 --- a/src/occ_405/firdata/scom_trgt.c +++ b/src/occ_405/firdata/scom_trgt.c @@ -41,9 +41,15 @@ SCOM_Trgt_t SCOM_Trgt_getTrgt( TrgtType_t i_type, uint8_t i_procPos, .fsiBaseAddr = i_fsiBaseAddr, }; - if ( TRGT_PROC == trgt.type ) trgt.procUnitPos = 0; + if (TRGT_PROC == trgt.type) + { + trgt.procUnitPos = 0; + } - if ( TRGT_MEMBUF == trgt.type || TRGT_MBA == trgt.type ) trgt.isMaster = false; + if ( TRGT_MEMBUF == trgt.type || TRGT_MBA == trgt.type ) + { + trgt.isMaster = false; + } return trgt; } @@ -57,16 +63,25 @@ uint8_t SCOM_Trgt_getChipPos( SCOM_Trgt_t i_trgt ) switch ( i_trgt.type ) { case TRGT_PROC: + case TRGT_CAPP: + case TRGT_XBUS: + case TRGT_OBUS: + case TRGT_PEC: + case TRGT_PHB: + case TRGT_EQ: case TRGT_EX: + case TRGT_EC: + case TRGT_MCBIST: case TRGT_MCS: + case TRGT_MCA: p = i_trgt.procPos; break; - case TRGT_MEMBUF: + case TRGT_MEMBUF: /* TODO RTC 173614 -- with CUMULUS */ p = (i_trgt.procPos * MAX_MEMBUF_PER_PROC) + i_trgt.procUnitPos; break; - case TRGT_MBA: + case TRGT_MBA: /* TODO RTC 173614 -- with CUMULUS */ p = (i_trgt.procPos * MAX_MEMBUF_PER_PROC) + (i_trgt.procUnitPos / MAX_MBA_PER_MEMBUF); break; @@ -88,10 +103,20 @@ uint8_t SCOM_Trgt_getChipUnitPos( SCOM_Trgt_t i_trgt ) case TRGT_PROC: case TRGT_MEMBUF: u = 0; break; + case TRGT_CAPP: + case TRGT_XBUS: + case TRGT_OBUS: + case TRGT_PEC: + case TRGT_PHB: + case TRGT_EQ: case TRGT_EX: - case TRGT_MCS: u = i_trgt.procUnitPos; break; + case TRGT_EC: + case TRGT_MCBIST: + case TRGT_MCS: + case TRGT_MCA: u = i_trgt.procUnitPos; break; case TRGT_MBA: u = i_trgt.procUnitPos % MAX_MBA_PER_MEMBUF; break; + /* TODO RTC 173614 -- with CUMULUS */ default: ; } @@ -107,8 +132,17 @@ SCOM_Trgt_t SCOM_Trgt_getParentChip( SCOM_Trgt_t i_trgt ) switch ( i_trgt.type ) { case TRGT_PROC: + case TRGT_CAPP: + case TRGT_XBUS: + case TRGT_OBUS: + case TRGT_PEC: + case TRGT_PHB: + case TRGT_EQ: case TRGT_EX: - case TRGT_MCS: t = TRGT_PROC; break; + case TRGT_EC: + case TRGT_MCBIST: + case TRGT_MCS: + case TRGT_MCA: t = TRGT_PROC; break; case TRGT_MEMBUF: case TRGT_MBA: t = TRGT_MEMBUF; break; @@ -120,11 +154,22 @@ SCOM_Trgt_t SCOM_Trgt_getParentChip( SCOM_Trgt_t i_trgt ) switch ( i_trgt.type ) { case TRGT_PROC: + case TRGT_CAPP: + case TRGT_XBUS: + case TRGT_OBUS: + case TRGT_PEC: + case TRGT_PHB: + case TRGT_EQ: case TRGT_EX: + case TRGT_EC: + case TRGT_MCBIST: case TRGT_MCS: - case TRGT_MEMBUF: u = i_trgt.procUnitPos; break; + case TRGT_MCA: + case TRGT_MEMBUF: u = i_trgt.procUnitPos; break; + /* TODO RTC 173614 -- with CUMULUS */ case TRGT_MBA: u = i_trgt.procUnitPos / MAX_MBA_PER_MEMBUF; break; + /* TODO RTC 173614 -- with CUMULUS */ default: ; } |