Skip to content

Commit

Permalink
Adding interface changes to provide I2C information to HDAT
Browse files Browse the repository at this point in the history
This is the first of two commits, this includes the I2C information
that hostboot is already aware of (EEProm and TPM).  There will be
a later commit that pulls in the new information from the MRW.

Change-Id: I33b0cd7784b242de3b68a3e7b07527604d819c23
RTC:161649
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/32437
Tested-by: Jenkins Server <pfd-jenkins+hostboot@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>
Reviewed-by: Martin Gloff <mgloff@us.ibm.com>
Reviewed-by: NAGENDRA K. GURRAM <nagendra.g@in.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
  • Loading branch information
e-liner authored and dcrowell77 committed Feb 21, 2017
1 parent 988d8d5 commit 2eaec45
Show file tree
Hide file tree
Showing 6 changed files with 445 additions and 36 deletions.
41 changes: 9 additions & 32 deletions src/include/usr/i2c/i2cif.H
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2012,2016 */
/* Contributors Listed Below - COPYRIGHT 2012,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -209,8 +209,6 @@ errlHndl_t i2cEnableSensorCache( TARGETING::Target * i_target );
*/
enum DeviceType_t
{
//@TODO-RTC:161649-Map these directly to some HDAT constants?
// Or something from MRW?
DEVTYPE_955x = 0x01,
DEVTYPE_SEEPROM = 0x02,
DEVTYPE_NUVOTON_TPM = 0x03,
Expand All @@ -219,40 +217,19 @@ enum DeviceType_t
DEVTYPE_UNKNOWN = 0xFF,
};

/**
* Enumeration that defines possible I2C device purposes
*/
enum DevicePurpose_t
{
//@TODO-RTC:161649-Map these directly to some HDAT constants?
// Or something from MRW?
PURPOSE_CABLE_CARD_PRES = 0x01,
PURPOSE_CABLE_CARD_POWER_SENSE = 0x02,
PURPOSE_CABLE_CARD_POWER_CONTROL = 0x03,
PURPOSE_TPM = 0x04,
PURPOSE_MODULE_VPD = 0x05,
PURPOSE_DOMM_SPD = 0x06,
PURPOSE_PROC_MODULE_VPD = 0x07,
PURPOSE_SBE_SEEPROM = 0x08,
PURPOSE_PLANAR_VPD = 0x09,
PURPOSE_PCI_HOTPLUG = 0x0A,
PURPOSE_UNKNOWN = 0xFF,
};

/**
* Structure to return I2C information in
*/
struct DeviceInfo_t
{
//@TODO-RTC:161649-Add more details/comments
TARGETING::Target* masterChip;
uint8_t engine;
uint8_t masterPort;
DeviceType_t deviceType;
uint8_t addr; //Is this left-shifted or not?
uint8_t slavePort;
uint8_t busFreqKhz;
DevicePurpose_t devicePurpose;
TARGETING::Target* masterChip; //< I2C Master Chip
uint8_t engine; //< I2C engine (relative to master chip)
uint8_t masterPort; //< I2C port (relative to engine)
uint8_t deviceType; //< Slave device Type (from enum)
uint8_t addr; //< I2C Slave device address (relative to port)
uint8_t slavePort; //< I2C Slave Port. 0xFF if N/A
uint8_t busFreqKhz; //< Bus speed in KHz
uint8_t devicePurpose; //< Slave device purpose (from enum)
};

/**
Expand Down
195 changes: 194 additions & 1 deletion src/usr/i2c/i2c.C
Expand Up @@ -50,6 +50,10 @@
#include <attributetraits.H>
#include "i2c.H"
#include "errlud_i2c.H"
#include "tpmdd.H"
#include <secureboot/trustedbootif.H>
#include <i2c/eepromif.H>
#include <i2c/tpmddif.H>

// ----------------------------------------------
// Globals
Expand Down Expand Up @@ -3795,7 +3799,196 @@ void getMasterInfo( const TARGETING::Target* i_chip,
void getDeviceInfo( TARGETING::Target* i_i2cMaster,
std::vector<DeviceInfo_t>& o_deviceInfo )
{
//@TODO-RTC:161649-Fill in information for HDAT
TRACFCOMP(g_trac_i2c,"getDeviceInfo>>");

//Get list of all I2C Masters
std::list<I2C::MasterInfo_t> l_i2cInfo;
I2C::getMasterInfo( i_i2cMaster, l_i2cInfo );

//Find all the EEPROMs connected via i2c
std::list<EEPROM::EepromInfo_t> l_eepromInfo;
EEPROM::getEEPROMs( l_eepromInfo );

//Find all TPMs
#ifdef CONFIG_TPMDD
TPMDD::tpm_info_t tpmInfo;
errlHndl_t l_err = NULL;
std::list<TRUSTEDBOOT::TpmTarget> l_tpmTarget;
TRUSTEDBOOT::getTPMs(l_tpmTarget);
#endif

for( std::list<I2C::MasterInfo_t>::iterator i2cm = l_i2cInfo.begin();
i2cm != l_i2cInfo.end();
++i2cm )
{
/* I2C Busses */
std::list<EEPROM::EepromInfo_t>::iterator l_eep = l_eepromInfo.begin();
while( l_eep != l_eepromInfo.end() )
{
DeviceInfo_t l_currentDI;

//ignore the devices that aren't on the current target
if( l_eep->i2cMaster != i_i2cMaster )
{
l_eep = l_eepromInfo.erase(l_eep);
continue;
}

//skip the devices that are on a different engine
else if( l_eep->engine != i2cm->engine)
{
++l_eep;
continue;
}

l_currentDI.masterChip = l_eep->i2cMaster;
l_currentDI.engine = l_eep->engine;
l_currentDI.masterPort = l_eep->port;
l_currentDI.addr = l_eep->devAddr;
l_currentDI.slavePort = 0xFF;
l_currentDI.busFreqKhz = (l_eep->busFreq) * 1000;
l_currentDI.deviceType = TARGETING::HDAT_I2C_DEVICE_TYPE_SEEPROM;
switch(l_eep->device)
{
case EEPROM::VPD_PRIMARY:
case EEPROM::VPD_BACKUP:
l_currentDI.devicePurpose =
TARGETING::HDAT_I2C_DEVICE_PURPOSE_MODULE_VPD;
//TODO RTC:165485 this isn't currently right. we'll need
//to add the changes in the enum and possibly the other
//struct/attribute.
break;
case EEPROM::SBE_PRIMARY:
case EEPROM::SBE_BACKUP:
l_currentDI.devicePurpose =
TARGETING::HDAT_I2C_DEVICE_PURPOSE_SBE_SEEPROM;
break;
case EEPROM::LAST_CHIP_TYPE:
break;
}

o_deviceInfo.push_back(l_currentDI);
l_eep = l_eepromInfo.erase(l_eep);
} //end of eeprom iter

#ifdef CONFIG_TPMDD
std::list<TRUSTEDBOOT::TpmTarget>::iterator l_tpm = l_tpmTarget.begin();
while( l_tpm != l_tpmTarget.end() )
{
DeviceInfo_t l_currentDI;
TPMDD::tpm_locality_t locality = TPMDD::TPM_LOCALITY_0;

// Lookup i2c info for the TPM
l_err = TPMDD::tpmReadAttributes(l_tpm->tpmTarget,
tpmInfo, locality);
if( NULL != l_err )
{
// Unable to get info, so we skip
delete l_err;
l_tpm = l_tpmTarget.erase(l_tpm);
continue;
}
// ignore the devices that aren't on the current target
if( tpmInfo.i2cTarget != i_i2cMaster )
{
l_tpm = l_tpmTarget.erase(l_tpm);
continue;
}
// skip the devices that are on a different engine
else if( tpmInfo.engine != i2cm->engine )
{
++l_tpm;
continue;
}

l_currentDI.masterChip = tpmInfo.i2cTarget;
l_currentDI.engine = tpmInfo.engine;
l_currentDI.masterPort = tpmInfo.port;
l_currentDI.addr = tpmInfo.devAddr;
l_currentDI.slavePort = 0xFF;
l_currentDI.busFreqKhz = (tpmInfo.busFreq) * 1000;
l_currentDI.deviceType =
TARGETING::HDAT_I2C_DEVICE_TYPE_NUVOTON_TPM;
l_currentDI.devicePurpose = TARGETING::HDAT_I2C_DEVICE_PURPOSE_TPM;

o_deviceInfo.push_back(l_currentDI);

l_tpm = l_tpmTarget.erase(l_tpm);

} //end of tpm iter
#endif

} //end of i2cm

#if CONFIG_INCLUDE_XML_OPENPOWER
TARGETING::Target * sys = NULL;
TARGETING::targetService().getTopLevelTarget(sys);

//need to get all targets here, and pull it out.
TARGETING::TargetHandleList pChildList;

TARGETING::targetService().getAssociated(pChildList, sys,
TARGETING::TargetService::CHILD,
TARGETING::TargetService::ALL);
pChildList.push_back(sys);

for(TARGETING::TargetHandleList::const_iterator childItr =
pChildList.begin();
childItr != pChildList.end(); ++childItr)
{
TARGETING::ATTR_HDAT_I2C_ENGINE_type l_i2cEngine;
(*childItr)->tryGetAttr<TARGETING::ATTR_HDAT_I2C_ENGINE>(l_i2cEngine);

if(l_i2cEngine[0] == 0)
{
continue;
}

TARGETING::ATTR_HDAT_I2C_MASTER_PORT_type l_i2cMasterPort;
(*childItr)->tryGetAttr<TARGETING::ATTR_HDAT_I2C_MASTER_PORT>(
l_i2cMasterPort);
TARGETING::ATTR_HDAT_I2C_DEVTYPE_type l_i2cDevType;
(*childItr)->tryGetAttr<TARGETING::ATTR_HDAT_I2C_DEVTYPE>(
l_i2cDevType);
TARGETING::ATTR_HDAT_I2C_ADDR_type l_i2cAddr;
(*childItr)->tryGetAttr<TARGETING::ATTR_HDAT_I2C_ADDR>(l_i2cAddr);
TARGETING::ATTR_HDAT_I2C_SLAVE_PORT_type l_i2cSlavePort;
(*childItr)->tryGetAttr<TARGETING::ATTR_HDAT_I2C_SLAVE_PORT>(
l_i2cSlavePort);
TARGETING::ATTR_HDAT_I2C_BUS_FREQ_type l_i2cBusFreq;
(*childItr)->tryGetAttr<TARGETING::ATTR_HDAT_I2C_BUS_FREQ>(
l_i2cBusFreq);
TARGETING::ATTR_HDAT_I2C_DEV_PURPOSE_type l_i2cDevPurpose;
(*childItr)->tryGetAttr<TARGETING::ATTR_HDAT_I2C_DEV_PURPOSE>(
l_i2cDevPurpose);

uint8_t l_arrayLength =
(*childItr)->getAttr<TARGETING::ATTR_HDAT_I2C_ELEMENTS>();

if(l_arrayLength == 0)
{
//The arrays are empty
continue;
}
for(uint8_t l_idx=0;
l_idx < l_arrayLength;
l_idx++)
{
DeviceInfo_t l_currentDevice;
l_currentDevice.engine = l_i2cEngine[l_idx];
l_currentDevice.masterPort = l_i2cMasterPort[l_idx];
l_currentDevice.addr = l_i2cAddr[l_idx];
l_currentDevice.slavePort = l_i2cSlavePort[l_idx];
l_currentDevice.busFreqKhz = l_i2cBusFreq[l_idx] * 1000;
l_currentDevice.deviceType = l_i2cDevType[l_idx];
l_currentDevice.devicePurpose = l_i2cDevPurpose[l_idx];

o_deviceInfo.push_back(l_currentDevice);
}
}
#endif

TRACFCOMP(g_trac_i2c,"<<getDeviceInfo");
return;
};

Expand Down
23 changes: 22 additions & 1 deletion src/usr/i2c/test/i2ctest.H
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2011,2015 */
/* Contributors Listed Below - COPYRIGHT 2011,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -1029,6 +1029,27 @@ class I2CTest: public CxxTest::TestSuite
}
}

void test_getDeviceInfo( void )
{
TRACFCOMP(g_trac_i2c, "test_getDeviceInfo - Start");

TARGETING::TargetService& tS = TARGETING::targetService();
TARGETING::Target * sys = NULL;
tS.getTopLevelTarget(sys);

std::vector<I2C::DeviceInfo_t> l_deviceInfo;

getDeviceInfo( sys, l_deviceInfo);

std::vector<I2C::DeviceInfo_t>::const_iterator devInfo_iter;
for(devInfo_iter = l_deviceInfo.begin();
devInfo_iter != l_deviceInfo.end();
devInfo_iter++)
{
TRACFCOMP(g_trac_i2c, "Found Device Info: Engine %d",devInfo_iter->engine);
}

}

/**
* @brief Verify the functions that create the userdata values
Expand Down
82 changes: 82 additions & 0 deletions src/usr/targeting/common/xmltohb/attribute_types.xml
Expand Up @@ -33042,4 +33042,86 @@ Measured in GB</description>
</hwpfToHbAttrMap>
</attribute>

<enumerationType>
<id>HDAT_I2C_DEVICE_TYPE</id>
<description>Pulled from the MRW, this describes the device
type to the HDAT. This is for I2C devices only.
</description>
<enumerator>
<name>955X</name>
<value>0</value>
</enumerator>
<enumerator>
<name>SEEPROM</name>
<value>1</value>
</enumerator>
<enumerator>
<name>NUVOTON_TPM</name>
<value>2</value>
</enumerator>
<enumerator>
<name>MEX_FPGA</name>
<value>3</value>
</enumerator>
<enumerator>
<name>UCX90XX</name>
<value>4</value>
</enumerator>
<enumerator>
<name>UNKNOWN</name>
<value>5</value>
</enumerator>
</enumerationType>

<enumerationType>
<id>HDAT_I2C_DEVICE_PURPOSE</id>
<description>Pulled from the MRW, this describes the device
purpose to the HDAT. This is for I2C devices only.
</description>
<enumerator>
<name>CABLE_CARD_PRES</name>
<value>0</value>
</enumerator>
<enumerator>
<name>CABLE_CARD_POWER_SENSE</name>
<value>1</value>
</enumerator>
<enumerator>
<name>CABLE_CARD_POWER_CONTROL</name>
<value>2</value>
</enumerator>
<enumerator>
<name>TPM</name>
<value>3</value>
</enumerator>
<enumerator>
<name>MODULE_VPD</name>
<value>4</value>
</enumerator>
<enumerator>
<name>DIMM_SPD</name>
<value>5</value>
</enumerator>
<enumerator>
<name>PROC_MODULE_VPD</name>
<value>6</value>
</enumerator>
<enumerator>
<name>SBE_SEEPROM</name>
<value>7</value>
</enumerator>
<enumerator>
<name>PLANAR_VPD</name>
<value>8</value>
</enumerator>
<enumerator>
<name>PCI_HOTPLUG</name>
<value>9</value>
</enumerator>
<enumerator>
<name>UNKNOWN</name>
<value>10</value>
</enumerator>
</enumerationType>

</attributes>

0 comments on commit 2eaec45

Please sign in to comment.