summaryrefslogtreecommitdiffstats
path: root/src/usr/hdat
diff options
context:
space:
mode:
authorNick Bofferding <bofferdn@us.ibm.com>2017-07-05 11:35:21 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2017-07-14 15:39:21 -0400
commit3fbd50ab46e402867da8a5ae6b041aa9330fd6ea (patch)
treefefcd0aea6d086f91460649ed9b8582603d3a5fc /src/usr/hdat
parent34514fe03f1e41d838b3f60e06136444e028a0ef (diff)
downloadtalos-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-xsrc/usr/hdat/hdatmsarea.C12
-rwxr-xr-xsrc/usr/hdat/hdatmsarea.H42
-rw-r--r--src/usr/hdat/hdatpcrd.C33
-rw-r--r--src/usr/hdat/hdatutil.C137
-rwxr-xr-xsrc/usr/hdat/hdatutil.H6
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));
OpenPOWER on IntegriCloud