diff options
author | Nick Bofferding <bofferdn@us.ibm.com> | 2017-07-05 11:35:21 -0500 |
---|---|---|
committer | Christian R. Geddes <crgeddes@us.ibm.com> | 2017-07-14 15:39:21 -0400 |
commit | 3fbd50ab46e402867da8a5ae6b041aa9330fd6ea (patch) | |
tree | fefcd0aea6d086f91460649ed9b8582603d3a5fc /src/usr/hdat | |
parent | 34514fe03f1e41d838b3f60e06136444e028a0ef (diff) | |
download | talos-hostboot-3fbd50ab46e402867da8a5ae6b041aa9330fd6ea.tar.gz talos-hostboot-3fbd50ab46e402867da8a5ae6b041aa9330fd6ea.zip |
Support new i2c device link ID format
Change-Id: Ie79caad8ec9fe0be5421185360c5ea9b2d5dee3d
RTC: 173541
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/42681
Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Stephen M. Cprek <smcprek@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>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: NAGENDRA K. GURRAM <nagendra.g@in.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src/usr/hdat')
-rwxr-xr-x | src/usr/hdat/hdatmsarea.C | 12 | ||||
-rwxr-xr-x | src/usr/hdat/hdatmsarea.H | 42 | ||||
-rw-r--r-- | src/usr/hdat/hdatpcrd.C | 33 | ||||
-rw-r--r-- | src/usr/hdat/hdatutil.C | 137 | ||||
-rwxr-xr-x | src/usr/hdat/hdatutil.H | 6 |
5 files changed, 170 insertions, 60 deletions
diff --git a/src/usr/hdat/hdatmsarea.C b/src/usr/hdat/hdatmsarea.C index 14736b126..ceb469828 100755 --- a/src/usr/hdat/hdatmsarea.C +++ b/src/usr/hdat/hdatmsarea.C @@ -385,12 +385,14 @@ void HdatMsArea::setMsaI2cInfo( std::vector<hdatI2cData_t> &i_I2cDevEntries ) { HDAT_ENTER(); - iv_msaI2cHdr.hdatOffset = 0x0010; // this is just header of 4 words. arrays start at 0x0010 + // this is just header of 5 words. arrays start at 0x0014 + iv_msaI2cHdr.hdatOffset = sizeof(iv_msaI2cHdr); iv_msaI2cHdr.hdatArrayCnt = i_I2cDevEntries.size(); iv_msaI2cHdr.hdatAllocSize = sizeof(hdatI2cData_t); iv_msaI2cHdr.hdatActSize = sizeof(hdatI2cData_t); + iv_msaI2cHdr.hdatVersion = HOST_I2C_DEV_INFO_VERSION::V2; iv_msaHostI2cCnt = i_I2cDevEntries.size(); - iv_msaHostI2cSize = sizeof(hdatHDIFDataArray_t) + + iv_msaHostI2cSize = sizeof(iv_msaI2cHdr) + (sizeof(hdatI2cData_t) * iv_msaHostI2cCnt); HDAT_INF("iv_msaHostI2cCnt=%d, iv_msaHostI2cSize=%d", iv_msaHostI2cCnt, iv_msaHostI2cSize); @@ -585,7 +587,7 @@ uint32_t HdatMsArea::getMsAreaSize() l_size += (iv_maxEcCnt * sizeof(hdatMsAreaEcLvl_t)); - l_size += sizeof(hdatHDIFDataArray_t); + l_size += sizeof(iv_msaI2cHdr); l_size += (sizeof(hdatI2cData_t) * iv_msaHostI2cCnt); @@ -650,12 +652,12 @@ void HdatMsArea::commit(UtilMem &i_data) i_data.write(iv_ecLvl,iv_maxEcCnt * sizeof(hdatMsAreaEcLvl_t)); - i_data.write(&iv_msaI2cHdr, sizeof(hdatHDIFDataArray_t)); + i_data.write(&iv_msaI2cHdr, sizeof(iv_msaI2cHdr)); if (NULL != iv_msaI2cDataPtr) { i_data.write(iv_msaI2cDataPtr, - (iv_msaHostI2cSize - sizeof(hdatHDIFDataArray_t))); + (iv_msaHostI2cSize - sizeof(iv_msaI2cHdr))); } this->endCommit(i_data); diff --git a/src/usr/hdat/hdatmsarea.H b/src/usr/hdat/hdatmsarea.H index ccd238fa3..850adc0c2 100755 --- a/src/usr/hdat/hdatmsarea.H +++ b/src/usr/hdat/hdatmsarea.H @@ -597,27 +597,27 @@ private: * @li iv_ramPtrs - ptr to storage which contains one of more ptrs * to RAM objects */ - uint32_t iv_kwdSize; - uint32_t iv_maxAddrRngCnt; - uint32_t iv_maxEcCnt; - uint32_t iv_msaHostI2cCnt; - uint32_t iv_msaHostI2cSize; - uint32_t iv_maxRamCnt; - uint32_t iv_actRamCnt; - uint32_t iv_maxRamObjSize; - char *iv_kwd; - bool iv_ramPadReq; - hdatFruId_t iv_fru; - hdatMsAreaId_t iv_msId; - hdatMsAreaSize_t iv_msSize; - hdatHDIFDataArray_t iv_addrRngArrayHdr; - hdatMsAreaAddrRange_t *iv_addrRange; - hdatMsAreaAffinity_t iv_aff; - hdatHDIFDataArray_t iv_ecArrayHdr; - hdatMsAreaEcLvl_t *iv_ecLvl; - hdatHDIFDataArray_t iv_msaI2cHdr; - uint8_t *iv_msaI2cDataPtr; - HdatRam **iv_ramPtrs; + uint32_t iv_kwdSize; + uint32_t iv_maxAddrRngCnt; + uint32_t iv_maxEcCnt; + uint32_t iv_msaHostI2cCnt; + uint32_t iv_msaHostI2cSize; + uint32_t iv_maxRamCnt; + uint32_t iv_actRamCnt; + uint32_t iv_maxRamObjSize; + char *iv_kwd; + bool iv_ramPadReq; + hdatFruId_t iv_fru; + hdatMsAreaId_t iv_msId; + hdatMsAreaSize_t iv_msSize; + hdatHDIFDataArray_t iv_addrRngArrayHdr; + hdatMsAreaAddrRange_t *iv_addrRange; + hdatMsAreaAffinity_t iv_aff; + hdatHDIFDataArray_t iv_ecArrayHdr; + hdatMsAreaEcLvl_t *iv_ecLvl; + hdatHDIFVersionedDataArray_t iv_msaI2cHdr; + uint8_t *iv_msaI2cDataPtr; + HdatRam **iv_ramPtrs; /** Class (static) Data diff --git a/src/usr/hdat/hdatpcrd.C b/src/usr/hdat/hdatpcrd.C index cd5b75ac1..1ecda256b 100644 --- a/src/usr/hdat/hdatpcrd.C +++ b/src/usr/hdat/hdatpcrd.C @@ -143,7 +143,8 @@ HdatPcrd::HdatPcrd(errlHndl_t &o_errlHndl, const hdatMsAddr_t &i_msAddr) // Allocate the CHIP INFO section also iv_numPcrdEntries = HDAT_NUM_P7_PCRD_ENTRIES; iv_spPcrdEntrySize = sizeof(hdatSpPcrd_t) + HDAT_FULL_MVPD_SIZE + - sizeof(hdatHDIFDataArray_t) + (sizeof(hdatI2cData_t) * HDAT_PCRD_MAX_I2C_DEV); + sizeof(hdatHDIFVersionedDataArray_t) + ((sizeof(hdatI2cData_t) + * HDAT_PCRD_MAX_I2C_DEV)); // Allocate space for each CHIP -- will use max amount to start uint64_t l_base_addr = ((uint64_t) i_msAddr.hi << 32) | i_msAddr.lo; @@ -446,9 +447,8 @@ errlHndl_t HdatPcrd::hdatLoadPcrd(uint32_t &o_size, uint32_t &o_count) // Setting Host I2C device entry data uint32_t l_pcrdHI2cTotalSize = 0; - hdatHDIFDataArray_t *l_hostI2cFullPcrdHdrPtr = NULL; - l_hostI2cFullPcrdHdrPtr = - reinterpret_cast<hdatHDIFDataArray_t *> + hdatHDIFVersionedDataArray_t *l_hostI2cFullPcrdHdrPtr = + reinterpret_cast<hdatHDIFVersionedDataArray_t *> (l_FullMvpdAddr+l_FullMvpdSize); // Need to get i2c Master data correctly @@ -456,25 +456,29 @@ errlHndl_t HdatPcrd::hdatLoadPcrd(uint32_t &o_size, uint32_t &o_count) hdatGetI2cDeviceInfo(l_pProcTarget, l_i2cDevEntries); - l_pcrdHI2cTotalSize = sizeof(hdatHDIFDataArray_t) + + l_pcrdHI2cTotalSize = sizeof(*l_hostI2cFullPcrdHdrPtr) + (sizeof(hdatI2cData_t) * l_i2cDevEntries.size()); HDAT_INF("pcrdHI2cNumEntries=0x%x, l_pcrdHI2cTotalSize=0x%x", l_i2cDevEntries.size(), l_pcrdHI2cTotalSize); - l_hostI2cFullPcrdHdrPtr->hdatOffset = 0x0010; // All array entries start right after header which is of 4 word size + // All array entries start right after header which is of 5 word + // size + l_hostI2cFullPcrdHdrPtr->hdatOffset = + sizeof(*l_hostI2cFullPcrdHdrPtr); l_hostI2cFullPcrdHdrPtr->hdatArrayCnt = l_i2cDevEntries.size(); l_hostI2cFullPcrdHdrPtr->hdatAllocSize = sizeof(hdatI2cData_t); l_hostI2cFullPcrdHdrPtr->hdatActSize = sizeof(hdatI2cData_t); + l_hostI2cFullPcrdHdrPtr->hdatVersion = + HOST_I2C_DEV_INFO_VERSION::V2; - hdatI2cData_t *l_hostI2cFullPcrdDataPtr = NULL; - l_hostI2cFullPcrdDataPtr = + hdatI2cData_t *l_hostI2cFullPcrdDataPtr = reinterpret_cast<hdatI2cData_t *> - (reinterpret_cast<uint8_t *>(l_hostI2cFullPcrdHdrPtr) - +sizeof(hdatHDIFDataArray_t)); + (reinterpret_cast<uint8_t *>(l_hostI2cFullPcrdHdrPtr) + +sizeof(*l_hostI2cFullPcrdHdrPtr)); if ( l_i2cDevEntries.size() != 0 ) { @@ -489,15 +493,15 @@ errlHndl_t HdatPcrd::hdatLoadPcrd(uint32_t &o_size, uint32_t &o_count) } this->iv_spPcrd->hdatPcrdIntData[HDAT_PCRD_DA_HOST_I2C]. hdatOffset = this->iv_spPcrd->hdatPcrdIntData - [HDAT_PCRD_DA_CHIP_VPD].hdatOffset + + [HDAT_PCRD_DA_CHIP_VPD].hdatOffset + this->iv_spPcrd->hdatPcrdIntData[HDAT_PCRD_DA_CHIP_VPD]. hdatSize; this->iv_spPcrd->hdatPcrdIntData [HDAT_PCRD_DA_HOST_I2C].hdatSize = l_pcrdHI2cTotalSize; this->iv_spPcrd->hdatHdr.hdatSize += - sizeof(hdatHDIFDataArray_t) + (sizeof(hdatI2cData_t) * HDAT_PCRD_MAX_I2C_DEV); + sizeof(*l_hostI2cFullPcrdHdrPtr) + (sizeof(hdatI2cData_t) + * HDAT_PCRD_MAX_I2C_DEV); - uint8_t* l_temp = reinterpret_cast<uint8_t *> (l_hostI2cFullPcrdHdrPtr); @@ -509,7 +513,8 @@ errlHndl_t HdatPcrd::hdatLoadPcrd(uint32_t &o_size, uint32_t &o_count) this->iv_spPcrd->hdatPcrdIntData[HDAT_PCRD_DA_PNOR].hdatOffset = this->iv_spPcrd->hdatPcrdIntData[HDAT_PCRD_DA_HOST_I2C].hdatOffset + - sizeof(hdatHDIFDataArray_t) + (sizeof(hdatI2cData_t) * HDAT_PCRD_MAX_I2C_DEV); + sizeof(hdatHDIFVersionedDataArray_t) + (sizeof(hdatI2cData_t) + * HDAT_PCRD_MAX_I2C_DEV); if(l_pProcTarget == l_pMasterProc) { diff --git a/src/usr/hdat/hdatutil.C b/src/usr/hdat/hdatutil.C index 3e8ef607e..0e2ba3605 100644 --- a/src/usr/hdat/hdatutil.C +++ b/src/usr/hdat/hdatutil.C @@ -1664,6 +1664,26 @@ errlHndl_t hdatGetFullEepromVpd(TARGETING::Target * i_target, return(err); } +//****************************************************************************** +// byNodeProcAffinty (std::sort comparison function) +//****************************************************************************** + +bool byNodeProcAffinity( + const DeviceInfo_t& i_lhs, + const DeviceInfo_t& i_rhs) +{ + bool lhsLogicallyBeforeRhs = (i_lhs.assocNode < i_rhs.assocNode); + if(i_lhs.assocNode == i_rhs.assocNode) + { + lhsLogicallyBeforeRhs = (i_lhs.assocProc < i_rhs.assocProc); + if(i_lhs.assocProc == i_rhs.assocProc) + { + lhsLogicallyBeforeRhs = (i_lhs.masterChip < i_rhs.masterChip); + } + } + return lhsLogicallyBeforeRhs; +} + /******************************************************************************* * hdatGetI2cDeviceInfo * @@ -1674,46 +1694,123 @@ errlHndl_t hdatGetFullEepromVpd(TARGETING::Target * i_target, * @post None * * @param[in] i_pTarget - * The i2c master target handle + * The i2c master target handle, or nullptr for all i2c masters * @param[out] o_i2cDevEntries * The host i2c dev entries * * @return void * *******************************************************************************/ -void hdatGetI2cDeviceInfo(TARGETING::Target* i_pTarget, - std::vector<hdatI2cData_t>&o_i2cDevEntries) +void hdatGetI2cDeviceInfo( + TARGETING::Target* i_pTarget, + std::vector<hdatI2cData_t>& o_i2cDevEntries) { HDAT_ENTER(); - std::vector<DeviceInfo_t> o_deviceInfo; - getDeviceInfo( i_pTarget, o_deviceInfo); - uint32_t l_I2cLinkId = 0; - if(!o_deviceInfo.size()) + std::vector<DeviceInfo_t> deviceInfo; + getDeviceInfo(nullptr,deviceInfo); + + if(deviceInfo.empty()) { - HDAT_INF(" No i2c connections found for i2c master : 0x08X", - i_pTarget->getAttr<ATTR_HUID>()); + HDAT_INF("No I2C connections found for I2C master with HUID of 0x%08X", + TARGETING::get_huid(i_pTarget)); } - else + else // At least one device, and index [0] is valid { - for ( auto &l_i2cDevEle : o_deviceInfo ) + // Order by node ordinal ID, processor position, I2C master target + // pointer + std::sort(deviceInfo.begin(), deviceInfo.end(), + byNodeProcAffinity); + + union LinkId { + struct + { + uint8_t node; ///< Ordinal ID of node + uint8_t proc; ///< Processor position + uint16_t instance; ///< Link instance (unique across a given + ///< processor and its downstream + ///< membufs) + }; + uint32_t val; ///< Allow access to the raw value + } linkId = { { + .node=static_cast<uint8_t>(deviceInfo[0].assocNode), + .proc=static_cast<uint8_t>(deviceInfo[0].assocProc), + .instance=0 } + }; + + for (const auto& i2cDevice : deviceInfo) + { + if( (i2cDevice.assocNode != linkId.node) + || (i2cDevice.assocProc != linkId.proc)) + { + linkId.node=i2cDevice.assocNode; + linkId.proc=i2cDevice.assocProc; + linkId.instance=0; + } + hdatI2cData_t l_hostI2cObj; memset(&l_hostI2cObj, 0x00, sizeof(hdatI2cData_t)); - l_hostI2cObj.hdatI2cEngine = l_i2cDevEle.engine; - l_hostI2cObj.hdatI2cMasterPort = l_i2cDevEle.masterPort; - l_hostI2cObj.hdatI2cBusSpeed = l_i2cDevEle.busFreqKhz; - l_hostI2cObj.hdatI2cSlaveDevType = l_i2cDevEle.deviceType; - l_hostI2cObj.hdatI2cSlaveDevAddr = l_i2cDevEle.addr; - l_hostI2cObj.hdatI2cSlavePort = l_i2cDevEle.slavePort; - l_hostI2cObj.hdatI2cSlaveDevPurp = l_i2cDevEle.devicePurpose; - l_hostI2cObj.hdatI2cLinkId = l_I2cLinkId++; + l_hostI2cObj.hdatI2cEngine = i2cDevice.engine; + l_hostI2cObj.hdatI2cMasterPort = i2cDevice.masterPort; + l_hostI2cObj.hdatI2cBusSpeed = i2cDevice.busFreqKhz; + l_hostI2cObj.hdatI2cSlaveDevType = i2cDevice.deviceType; + l_hostI2cObj.hdatI2cSlaveDevAddr = i2cDevice.addr; + l_hostI2cObj.hdatI2cSlavePort = i2cDevice.slavePort; + l_hostI2cObj.hdatI2cSlaveDevPurp = i2cDevice.devicePurpose; + l_hostI2cObj.hdatI2cLinkId = linkId.val; + + // @TODO RTC 176759 Populate SLCA and I2C label + l_hostI2cObj.hdatI2cSlcaIndex = 0; + memset(&l_hostI2cObj.hdatI2cLabel,0x00, + sizeof(l_hostI2cObj.hdatI2cLabel)); + + // Don't include the device if the slave address is + // invalid + if(l_hostI2cObj.hdatI2cSlaveDevAddr == UINT8_MAX) + { + continue; + } - o_i2cDevEntries.push_back(l_hostI2cObj); + assert(linkId.instance <= UINT16_MAX,"Illegal link ID instance " + "detected"); + ++linkId.instance; + + if( (i_pTarget == nullptr) + || (i_pTarget == i2cDevice.masterChip)) + { + o_i2cDevEntries.push_back(l_hostI2cObj); + } } } + for(auto const& i2cDevice : o_i2cDevEntries) + { + HDAT_DBG("Unique I2C device attached to HUID=0x%08X: " + "engine=0x%02X, " + "port=0x%02X, " + "speed=0x%04X, " + "slave type=0x%02X, " + "slave address=0x%02X, " + "slave port=0x%02X, " + "slave purpose=0x%08X, " + "link ID=0x%08X, " + "SLCA index=0x%04X, " + "slave label=\"%s\"", + TARGETING::get_huid(i_pTarget), + i2cDevice.hdatI2cEngine, + i2cDevice.hdatI2cMasterPort, + i2cDevice.hdatI2cBusSpeed, + i2cDevice.hdatI2cSlaveDevType, + i2cDevice.hdatI2cSlaveDevAddr, + i2cDevice.hdatI2cSlavePort, + i2cDevice.hdatI2cSlaveDevPurp, + i2cDevice.hdatI2cLinkId, + i2cDevice.hdatI2cSlcaIndex, + i2cDevice.hdatI2cLabel); + } + HDAT_EXIT(); } diff --git a/src/usr/hdat/hdatutil.H b/src/usr/hdat/hdatutil.H index bb29db916..1e730aeba 100755 --- a/src/usr/hdat/hdatutil.H +++ b/src/usr/hdat/hdatutil.H @@ -101,6 +101,10 @@ namespace HDAT extern trace_desc_t* g_trac_hdat; +enum HOST_I2C_DEV_INFO_VERSION : uint32_t +{ + V2 = 0x00000002, +}; /** @brief Defines the Host I2C device info */ @@ -115,6 +119,8 @@ struct hdatI2cData_t uint8_t hdatReserved1; uint32_t hdatI2cSlaveDevPurp; uint32_t hdatI2cLinkId; + uint16_t hdatI2cSlcaIndex; + char hdatI2cLabel[64]; }__attribute__ ((packed)); |