From 64c5f756d00f902ce974306c783cd4f1464b3159 Mon Sep 17 00:00:00 2001 From: Matt Derksen Date: Fri, 28 Jul 2017 10:46:18 -0500 Subject: Hostboot HDAT: update to match section 19 in HDAT spec Add new i2cLabel string Change-Id: I007441e3973a16eaae4dbdbe703297f0f6978c8f RTC: 176759 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/44301 Reviewed-by: Martin Gloff Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: Nicholas E. Bofferding Tested-by: FSP CI Jenkins Reviewed-by: Daniel M. Crowell --- src/usr/i2c/i2c.C | 106 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 89 insertions(+), 17 deletions(-) (limited to 'src/usr/i2c') diff --git a/src/usr/i2c/i2c.C b/src/usr/i2c/i2c.C index 6a8463eae..307bef806 100755 --- a/src/usr/i2c/i2c.C +++ b/src/usr/i2c/i2c.C @@ -55,6 +55,7 @@ #include #include + // ---------------------------------------------- // Globals // ---------------------------------------------- @@ -3840,6 +3841,7 @@ void getMasterInfo( const TARGETING::Target* i_chip, } } + //****************************************************************************** // areI2cDevicesLogicallyEqual (std::unique equality comparison) //****************************************************************************** @@ -3883,6 +3885,67 @@ bool byI2cDeviceOrder( return lhsLogicallyBeforeRhs; } +//****************************************************************************** +// removeI2CDeviceDuplicates +//****************************************************************************** +void removeI2cDeviceDuplicates(std::vector& io_deviceInfo) +{ + std::vector l_unique_deviceInfo; + + // Begin by sorting the list + // Order I2C devices by chip, engine, port, address, slave port + std::sort(io_deviceInfo.begin(), io_deviceInfo.end(), + byI2cDeviceOrder); + + // Build up new unique list (thus removing duplicates) + if (io_deviceInfo.size() > 1) + { + auto currentItr = io_deviceInfo.begin(); + auto nextItr = currentItr + 1; + + do { + if (nextItr != io_deviceInfo.end() && (currentItr != NULL)) + { + if (areI2cDevicesLogicallyEqual(*currentItr, *nextItr)) + { + // skip if first letter is ?, these are guessed defaults + if (currentItr->deviceLabel[0] == '?') + { + // don't save currentItr as it is a guessed default + currentItr = nextItr; + } + } + else + { + // Save currentItr as nextItr isn't the same logical device + if (currentItr != NULL) + { + l_unique_deviceInfo.push_back(*currentItr); + } + currentItr = nextItr; + } + } + else + { + // Save currentItr if pointing at something valid + if (currentItr != NULL) + { + l_unique_deviceInfo.push_back(*currentItr); + currentItr = nextItr; + } + } + + if (nextItr != io_deviceInfo.end()) + { + ++nextItr; + } + + } while (currentItr != io_deviceInfo.end()); + + io_deviceInfo = l_unique_deviceInfo; + } +} + /** * Retrieve some information about I2C devices that the Host * needs to know about @@ -4029,11 +4092,15 @@ void getDeviceInfo( TARGETING::Target* i_i2cMaster, //TODO RTC:165485 this isn't currently right. we'll need //to add the changes in the enum and possibly the other //struct/attribute. + strcpy(l_currentDI.deviceLabel, + "?atmel,28c128,vpd,module"); break; case EEPROM::SBE_PRIMARY: case EEPROM::SBE_BACKUP: l_currentDI.devicePurpose = TARGETING::HDAT_I2C_DEVICE_PURPOSE_SBE_SEEPROM; + strcpy(l_currentDI.deviceLabel, + "?atmel,28c128,unknown,unknown"); break; case EEPROM::LAST_CHIP_TYPE: break; @@ -4083,7 +4150,7 @@ void getDeviceInfo( TARGETING::Target* i_i2cMaster, TARGETING::HDAT_I2C_DEVICE_TYPE_NUVOTON_TPM; l_currentDI.devicePurpose = TARGETING::HDAT_I2C_DEVICE_PURPOSE_TPM; - + strcpy(l_currentDI.deviceLabel,"?nuvoton,npct601,tpm,host"); o_deviceInfo.push_back(l_currentDI); } //end of tpm iter @@ -4150,6 +4217,12 @@ void getDeviceInfo( TARGETING::Target* i_i2cMaster, "ATTR_HDAT_I2C_DEVICE_PURPOSE attribute", TARGETING::get_huid(pChipTarget)); + TARGETING::ATTR_HDAT_I2C_DEVICE_LABEL_type l_i2cDevLabel; + present = pChipTarget->tryGetAttr< + TARGETING::ATTR_HDAT_I2C_DEVICE_LABEL>(l_i2cDevLabel); + assert(present,"Target 0x%08X does not have ATTR_HDAT_I2C_DEVICE_LABEL " + "attribute",TARGETING::get_huid(pChipTarget)); + for(TARGETING::ATTR_HDAT_I2C_ELEMENTS_type l_idx=0; l_idx < l_arrayLength; ++l_idx) @@ -4178,8 +4251,17 @@ void getDeviceInfo( TARGETING::Target* i_i2cMaster, l_currentDevice.slavePort = l_i2cSlavePort[l_idx]; l_currentDevice.busFreqKhz = l_i2cBusFreq[l_idx] / FREQ_CONVERSION::HZ_PER_KHZ; - l_currentDevice.deviceType = l_i2cDevType[l_idx]; - l_currentDevice.devicePurpose = l_i2cDevPurpose[l_idx]; + l_currentDevice.deviceType = + static_cast( + l_i2cDevType[l_idx]); + l_currentDevice.devicePurpose = + static_cast( + l_i2cDevPurpose[l_idx]); + + memcpy(l_currentDevice.deviceLabel, l_i2cDevLabel[l_idx], + sizeof(l_currentDevice.deviceLabel)); + l_currentDevice.deviceLabel[sizeof(l_currentDevice.deviceLabel) - 1] + = '\0'; o_deviceInfo.push_back(l_currentDevice); } @@ -4187,23 +4269,13 @@ void getDeviceInfo( TARGETING::Target* i_i2cMaster, } //end of per chip loop - // Order I2C devices by chip, engine, port, address, slave port - std::sort(o_deviceInfo.begin(), o_deviceInfo.end(), - byI2cDeviceOrder); - - // Move logical duplicates to end - std::vector::iterator - pInvalidEntries = std::unique( - o_deviceInfo.begin(), - o_deviceInfo.end(), - areI2cDevicesLogicallyEqual); - - // Erase the duplicates - o_deviceInfo.erase(pInvalidEntries,o_deviceInfo.end()); + // remove duplicates (also use deviceLabel from MRW, when possible) + removeI2cDeviceDuplicates(o_deviceInfo); TRACFCOMP(g_trac_i2c,"<