diff options
author | Brian Stegmiller <bjs@us.ibm.com> | 2017-06-15 15:15:27 -0500 |
---|---|---|
committer | Zane C. Shelley <zshelle@us.ibm.com> | 2017-07-13 12:02:56 -0400 |
commit | d80986cf024b4f392e07f93d957c164c05190836 (patch) | |
tree | 96ad72845c36fc35a62616ddf70d8eb37ba1d264 | |
parent | 1aa0813d81f7a224583a46e20fd03a437d0ff479 (diff) | |
download | talos-hostboot-d80986cf024b4f392e07f93d957c164c05190836.tar.gz talos-hostboot-d80986cf024b4f392e07f93d957c164c05190836.zip |
PRD: Add EC Level support for HOMER Data
Change-Id: Ic83a0cb7d73781010b21ec7b5708be9febc06c56
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/41908
Tested-by: Jenkins Server <pfd-jenkins+hostboot@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-on: http://ralgit01.raleigh.ibm.com/gerrit1/43053
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
-rw-r--r-- | src/usr/diag/prdf/occ_firdata/firDataConst_common.h | 4 | ||||
-rw-r--r-- | src/usr/diag/prdf/occ_firdata/homerData_common.h | 24 | ||||
-rw-r--r-- | src/usr/diag/prdf/occ_firdata/prdfWriteHomerFirData.C | 247 |
3 files changed, 193 insertions, 82 deletions
diff --git a/src/usr/diag/prdf/occ_firdata/firDataConst_common.h b/src/usr/diag/prdf/occ_firdata/firDataConst_common.h index d9e870309..0482bc660 100644 --- a/src/usr/diag/prdf/occ_firdata/firDataConst_common.h +++ b/src/usr/diag/prdf/occ_firdata/firDataConst_common.h @@ -69,10 +69,6 @@ typedef enum TRGT_MEMBUF, TRGT_MBA, - /* EC level handling -- special case for NIMBUS */ - TRGT_PROC_NIMBUS_10, - TRGT_PROC_NIMBUS_20, - TRGT_MAX, } TrgtType_t; diff --git a/src/usr/diag/prdf/occ_firdata/homerData_common.h b/src/usr/diag/prdf/occ_firdata/homerData_common.h index c470ce6dc..03b36ad66 100644 --- a/src/usr/diag/prdf/occ_firdata/homerData_common.h +++ b/src/usr/diag/prdf/occ_firdata/homerData_common.h @@ -102,6 +102,10 @@ typedef struct __attribute__((packed)) /** Contains number of registers per type for each target type. */ uint8_t regCounts[TRGT_MAX][REG_MAX]; + /** 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; @@ -137,8 +141,26 @@ typedef struct __attribute__((packed)) 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 ) { @@ -237,7 +259,7 @@ static inline HOMER_ChipCentaur_t HOMER_initChipCentaur() */ typedef struct __attribute__((packed)) { - HOMER_Chip_t hChipType; + HOMER_Chip_t hChipType; /* Nimbus, Centaur, EC Level, etc...*/ union { diff --git a/src/usr/diag/prdf/occ_firdata/prdfWriteHomerFirData.C b/src/usr/diag/prdf/occ_firdata/prdfWriteHomerFirData.C index 9ea1fd295..b65aeb90a 100644 --- a/src/usr/diag/prdf/occ_firdata/prdfWriteHomerFirData.C +++ b/src/usr/diag/prdf/occ_firdata/prdfWriteHomerFirData.C @@ -270,7 +270,6 @@ void getAddresses( TrgtMap_t & io_targMap ) io_targMap[TRGT_PROC][REG_FIR] = { - 0x05011440, // NPU FIR1 0x01010800, // OCCFIR 0x050129C0, // PBAMFIR 0x0104000a, // TP_LFIR @@ -649,17 +648,8 @@ void getAddresses( TrgtMap_t & io_targMap ) 0x8001D0070301143Fll, // DDRPHY_APB_FIR_ERR1_P1 }; - // EC level handling will be done with - // different target types. - io_targMap[TRGT_PROC_NIMBUS_10][REG_FIR] = - { - 0x05011400, // NPU FIR0 (differs on DD level) - }; - - io_targMap[TRGT_PROC_NIMBUS_20][REG_FIR] = - { - 0x05013C00, // NPU FIR0 (differs on DD level) - }; + // EC level handling will be done with a + // structure and separate register count field. } // end getAddresses @@ -755,6 +745,9 @@ errlHndl_t getHwConfig( std::vector<HOMER_ChipInfo_t> &io_chipInfVector, l_chipItem.hChipType.chipPos = procPos; l_chipItem.hChipType.fsiBaseAddr = fsiInfo.baseAddr; + // save EC level for the chip + l_chipItem.hChipType.chipEcLevel = (*procIt)->getAttr<ATTR_EC>(); + // is this the MASTER processor ? l_chipItem.hChipN.isMaster = (*procIt == masterProc) ? 1 : 0; @@ -864,6 +857,9 @@ errlHndl_t getHwConfig( std::vector<HOMER_ChipInfo_t> &io_chipInfVector, // Get the MEMBUF FSI address. getFsiLinkInfo( *membIt, fsiInfo ); + // save EC level for the chip + l_chipItem.hChipType.chipEcLevel=(*membIt)->getAttr<ATTR_EC>(); + // Fill in our HOMER chip info l_chipItem.hChipType = HOMER_getChip(HOMER_CHIP_CENTAUR); l_chipItem.hChipType.chipPos = membPos; @@ -906,6 +902,63 @@ errlHndl_t getHwConfig( std::vector<HOMER_ChipInfo_t> &io_chipInfVector, //------------------------------------------------------------------------------ +/***************************************************/ +/* Define EC level dependent registers here */ +/* chipType Target RegType EC level */ +/* Unused - scomAddress */ +/***************************************************/ +static HOMER_ChipSpecAddr_t s_ecDepProcRegisters[] +{ + { HOMER_CHIP_NIMBUS, TRGT_PROC, REG_FIR, 0x10, + 0, 0x0000000005011400ll }, // NPU0FIR DD1 + + { HOMER_CHIP_NIMBUS, TRGT_PROC, REG_FIR, 0x10, + 0, 0x0000000005011440ll }, // NPU1FIR DD1 + + { HOMER_CHIP_NIMBUS, TRGT_PROC, REG_FIR, 0x20, + 0, 0x0000000005013C00ll }, // NPU0FIR DD2 + + { HOMER_CHIP_NIMBUS, TRGT_PROC, REG_FIR, 0x20, + 0, 0x0000000005013C40ll }, // NPU1FIR DD2 + + { HOMER_CHIP_NIMBUS, TRGT_PROC, REG_FIR, 0x20, + 0, 0x000000005013C80ll } // NPU2FIR DD2 +}; + +//------------------------------------------------------------------------------ +errlHndl_t homerVerifySizeFits( const size_t i_maxSize, + const size_t i_currentSize ) +{ + errlHndl_t l_errl = NULL; + + + // Verify we haven't exceeded max size + if ( i_currentSize > i_maxSize ) + { + PRDF_ERR( "HOMER SIZE issue: curDataSize %d is greater than max " + "HOMER data %d", i_currentSize, i_maxSize ); + /*@ + * @errortype + * @reasoncode PRDF_INVALID_CONFIG + * @severity ERRL_SEV_UNRECOVERABLE + * @moduleid PRDF_CS_FIRDATA_WRITE + * @userdata1 Size needed + * @userdata2 Size available + * @devdesc Invalid configuration in CS FIR Data handling. + */ + l_errl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, + PRDF_CS_FIRDATA_WRITE, + PRDF_INVALID_CONFIG, + i_currentSize, + i_maxSize ); + } // end if too big of size + + return(l_errl); + +} // end routine homerVerifySizeFits + +//------------------------------------------------------------------------------ + errlHndl_t writeData( uint8_t * i_hBuf, size_t i_hBufSize, const HwInitialized_t i_curHw, std::vector<HOMER_ChipInfo_t> &i_chipVector, @@ -931,8 +984,7 @@ errlHndl_t writeData( uint8_t * i_hBuf, size_t i_hBufSize, // initialize SCOM addresses for all targets & regs getAddresses(l_targMap); - - // loop thru targets + // loop thru targets to get register counts for ( auto & t : l_targMap ) { // loop thru register types @@ -963,30 +1015,10 @@ errlHndl_t writeData( uint8_t * i_hBuf, size_t i_hBufSize, } // end for on Targets - // Verify data will fit in HOMER. - if ( i_hBufSize < sz_hBuf ) - { - - PRDF_ERR( FUNC "Required data size %d is greater that available " - "HOMER data %d", sz_hBuf, i_hBufSize ); - - /*@ - * @errortype - * @reasoncode PRDF_INVALID_CONFIG - * @severity ERRL_SEV_UNRECOVERABLE - * @moduleid PRDF_CS_FIRDATA_WRITE - * @userdata1 Size needed - * @userdata2 Size available - * @devdesc Invalid configuration in CS FIR Data handling. - */ - errl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, - PRDF_CS_FIRDATA_WRITE, - PRDF_INVALID_CONFIG, - sz_hBuf, - i_hBufSize ); - break; - } - + // Setup EC level dependent register counts + // (currently just proc has some) + io_homerData.ecDepCounts = + sizeof(s_ecDepProcRegisters) / sizeof(HOMER_ChipSpecAddr_t); // Add everything to the buffer. uint32_t idx = 0; @@ -1008,6 +1040,11 @@ errlHndl_t writeData( uint8_t * i_hBuf, size_t i_hBufSize, (l_chipItr < i_chipVector.end()); l_chipItr++ ) { + // Ensure we won't copy beyond space allowed + sz_hBuf += l_chipTypeSize; + errl = homerVerifySizeFits(i_hBufSize, sz_hBuf); + if (NULL != errl) { break; } + // place the CHIP information memcpy( &i_hBuf[idx], &(l_chipItr->hChipType), l_chipTypeSize ); idx += l_chipTypeSize; @@ -1015,6 +1052,11 @@ errlHndl_t writeData( uint8_t * i_hBuf, size_t i_hBufSize, // place the configured chiplet information if (HOMER_CHIP_CENTAUR != l_chipItr->hChipType.chipType) { + // Ensure we won't copy beyond space allowed + sz_hBuf += sizeof(HOMER_ChipNimbus_t); + errl = homerVerifySizeFits(i_hBufSize, sz_hBuf); + if (NULL != errl) { break; } + // Cumulus and Nimbus are the same size area memcpy( &i_hBuf[idx], &(l_chipItr->hChipN), sizeof(HOMER_ChipNimbus_t) ); @@ -1023,6 +1065,11 @@ errlHndl_t writeData( uint8_t * i_hBuf, size_t i_hBufSize, } // end if PROC (not-centaur) else { + // Ensure we won't copy beyond space allowed + sz_hBuf += sizeof(HOMER_ChipCentaur_t); + errl = homerVerifySizeFits(i_hBufSize, sz_hBuf); + if (NULL != errl) { break; } + // Centaur is smaller area than PROC chips memcpy( &i_hBuf[idx], &(l_chipItr->hChipM), sizeof(HOMER_ChipCentaur_t) ); @@ -1032,57 +1079,102 @@ errlHndl_t writeData( uint8_t * i_hBuf, size_t i_hBufSize, } // end for loop on chip vector - } // end if chipCount non-zero + // ensure size is ok before any other copy + if (NULL != errl) { break; } + // Verify registers will fit before copying them + uint32_t l_reg32Count = 0; + uint32_t l_reg64Count = 0; - // loop thru targets - for ( auto & t : l_targMap ) - { - // TODO RTC 173614: story for CUMULUS when we know the regs for sure - // TRGT_MC TRGT_MI TRGT_DMI -- probably NOOP now - if ( (ALL_PROC_MEM_MASTER_CORE == i_curHw) || - (ALL_HARDWARE == i_curHw) || - ( (TRGT_MCBIST != t.first) && - (TRGT_MCS != t.first) && - (TRGT_MCA != t.first) && - (TRGT_MEMBUF != t.first) && - (TRGT_MBA != t.first) - ) - ) + // Count number of 32 bit addresses first + for ( uint32_t l_regIdx = REG_FIRST; + (l_regIdx < REG_IDFIR); l_regIdx++ ) + { + for ( uint32_t l_tgtIndex = TRGT_FIRST; + (l_tgtIndex < TRGT_MAX); l_tgtIndex++ ) + { + l_reg32Count +=io_homerData.regCounts[l_tgtIndex][l_regIdx]; + } // end for on target index + } // end for on register index + + + // Count number of 64 bit addresses now + for ( uint32_t l_regIdx = REG_IDFIR; + (l_regIdx < REG_MAX); l_regIdx++ ) + { + for ( uint32_t l_tgtIndex = TRGT_FIRST; + (l_tgtIndex < TRGT_MAX); l_tgtIndex++ ) + { + l_reg64Count +=io_homerData.regCounts[l_tgtIndex][l_regIdx]; + } // end for on target index + } // end for on register index + + // Calculate additional size we need from the counts. + // We have 32 bit addrs, 64 bit addrs, then EC level structures. + sz_hBuf +=(l_reg32Count * sizeof(uint32_t)) + + (l_reg64Count * sizeof(uint64_t)) + + (io_homerData.ecDepCounts * sizeof(HOMER_ChipSpecAddr_t)); + + // ensure we fit in HOMER before doing register copies + errl = homerVerifySizeFits(i_hBufSize, sz_hBuf); + if (NULL != errl) { break; } + + // loop thru targets + for ( auto & t : l_targMap ) { - // loop thru register types - for ( auto & r : t.second ) + // TODO RTC 173614: story for CUMULUS when we know the regs + // for sure TRGT_MC TRGT_MI TRGT_DMI -- probably NOOP now + if ( (ALL_PROC_MEM_MASTER_CORE == i_curHw) || + (ALL_HARDWARE == i_curHw) || + ( (TRGT_MCBIST != t.first) && + (TRGT_MCS != t.first) && + (TRGT_MCA != t.first) && + (TRGT_MEMBUF != t.first) && + (TRGT_MBA != t.first) + ) + ) { - // loop thru SCOM addresses for reg type - for ( auto & rAddr : r.second ) + // loop thru register types + for ( auto & r : t.second ) { - if ( (REG_IDFIR == r.first) || - (REG_IDREG == r.first) - ) + // loop thru SCOM addresses for reg type + for ( auto & rAddr : r.second ) { - memcpy( &i_hBuf[idx], - &rAddr, - u64 ); + if ( (REG_IDFIR == r.first) || + (REG_IDREG == r.first) + ) + { + memcpy( &i_hBuf[idx], + &rAddr, + u64 ); - idx += u64; - } - else - { - uint32_t tempAddr = (uint32_t)rAddr; - memcpy( &i_hBuf[idx], - &tempAddr, - u32 ); + idx += u64; + } + else + { + uint32_t tempAddr = (uint32_t)rAddr; + memcpy( &i_hBuf[idx], + &tempAddr, + u32 ); + + idx += u32; + } - idx += u32; - } + } // end for on register addresses - } // end for on register addresses + } // end for on regs - } // end for on regs + } // end if we need this target - } // end if we need this target + } // end for on targets + + // Add EC Level dependencies at the end + uint8_t *l_ecDepSourceRegs = (uint8_t *)(&s_ecDepProcRegisters[0]); + memcpy( &i_hBuf[idx], l_ecDepSourceRegs, + sizeof(s_ecDepProcRegisters) ); + + } // end if chipCount non-zero - } // end for on targets } while(0); @@ -1104,6 +1196,7 @@ void dumpInfoVector( std::vector<HOMER_ChipInfo_t> &i_chipVector ) l_chipItr++ ) { PRDF_ERR("HOMER: ChipPosition:%d", l_chipItr->hChipType.chipPos); + PRDF_ERR("HOMER: EC Level:%X", l_chipItr->hChipType.chipEcLevel); PRDF_ERR("HOMER: FSI Addr:%X", l_chipItr->hChipType.fsiBaseAddr); switch (l_chipItr->hChipType.chipType) |