summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/runtime/runtime.H16
-rw-r--r--src/include/usr/runtime/runtime_reasoncodes.H71
-rw-r--r--src/usr/hdat/hdatcommonutil.C2
-rw-r--r--src/usr/hdat/hdatpcrd.C3
-rw-r--r--src/usr/hdat/hdatpcrd.H3
-rw-r--r--src/usr/hdat/hdattpmdata.H13
-rw-r--r--src/usr/runtime/hdatservice.C123
-rw-r--r--src/usr/runtime/hdatservice.H10
-rw-r--r--src/usr/runtime/hdatstructs.H3
-rw-r--r--src/usr/runtime/populate_hbruntime.C318
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types.xml8
11 files changed, 509 insertions, 61 deletions
diff --git a/src/include/usr/runtime/runtime.H b/src/include/usr/runtime/runtime.H
index bdbcf20a8..04c727409 100644
--- a/src/include/usr/runtime/runtime.H
+++ b/src/include/usr/runtime/runtime.H
@@ -137,7 +137,8 @@ enum SectionId
SPIRA_L, //< Legacy SPIRA
NACA, //< NACA
HBRT, //< Hostboot Runtime
- HBRT_DATA, //< Hostboot Runtime Data
+ HBRT_DATA, //< Hostboot Runtime Data
+ PCRD, //< Processor Chip Related Data
IPMI_DATA, //< IPMI Sensor Mapping Data
NODE_TPM_RELATED, //< Node TPM Related Data
RESERVED_MEM, //< Hostboot's Reserved Mainstore Memory
@@ -165,6 +166,19 @@ errlHndl_t get_host_data_section( SectionId i_section,
const size_t DATA_SIZE_UNKNOWN = 0xFFFFFFFFFFFFFFFF;
/**
+ * @brief Get the number of instances in a given section.
+ *
+ * @param[in] i_section The section for which the instance count is desired
+ *
+ * @param[out] o_count The number of instances in this section
+ *
+ * @return errlHndl_t Returns nullptr on success. Returns an error if the
+ * section id used is invalid or has no concept of instances. Also, can
+ * return an error if the n-tuple is either corrupt or unavailable.
+ */
+errlHndl_t get_instance_count( RUNTIME::SectionId i_section, uint64_t& o_count);
+
+/**
* @brief Store the actual count of a section in local memory.
*
* @param[in] i_section Chunk of data to update
diff --git a/src/include/usr/runtime/runtime_reasoncodes.H b/src/include/usr/runtime/runtime_reasoncodes.H
index f287a5d97..6570e78fe 100644
--- a/src/include/usr/runtime/runtime_reasoncodes.H
+++ b/src/include/usr/runtime/runtime_reasoncodes.H
@@ -43,6 +43,7 @@ namespace RUNTIME
MOD_HDATSERVICE_FINDSPIRA = 0x09, /** hdatservice.C */
MOD_HDATSERVICE_UPDATE_SECTION_ACTUAL = 0x0A, /**< hdatservice.C */
MOD_HDATSERVICE_MAPREGION = 0x0B, /**< hdatservice.C */
+ MOD_HDATSERVICE_GETINSTANCECOUNT = 0x0C, /**< hdatservice.C */
// customize_attrs_for_payload.C
MOD_CUST_COMP_NON_PHYP_RT_TARGET = 0x12,
@@ -52,43 +53,49 @@ namespace RUNTIME
MOD_PM_RT_HCODE_UPDATE = 0x16, /**< rt_pm.C */
MOD_MAP_PHYS_ADDR = 0x17, /**< populate_hbruntime.C */
MOD_UNMAP_VIRT_ADDR = 0x18, /**< populate_hbruntime.C */
+ MOD_POPULATE_TPMINFOBYNODE = 0x19, /**< populate_hbruntime.C */
};
enum RuntimeReasonCode
{
- RC_DO_NOT_USE_THIS = RUNTIME_COMP_ID | 0x00,
- RC_ATTR_GET_FAIL = RUNTIME_COMP_ID | 0x01,
- RC_BAD_HDAT_HEADER = RUNTIME_COMP_ID | 0x02,
- RC_BAD_HDAT_TUPLE = RUNTIME_COMP_ID | 0x03,
- RC_INVALID_STANDALONE = RUNTIME_COMP_ID | 0x04,
- RC_CANNOT_MAP_MEMORY = RUNTIME_COMP_ID | 0x05,
- //RC_XXX = RUNTIME_COMP_ID | 0x06,
- RC_CANNOT_MAP_MEMORY2 = RUNTIME_COMP_ID | 0x07,
- RC_INVALID_PAYLOAD_KIND = RUNTIME_COMP_ID | 0x08,
- RC_NO_HSVC_NODE_DATA_FOUND = RUNTIME_COMP_ID | 0x09,
- RC_BAD_NACA = RUNTIME_COMP_ID | 0x0A,
- RC_INVALID_ADDRESS = RUNTIME_COMP_ID | 0x0B,
- RC_INVALID_SECTION = RUNTIME_COMP_ID | 0x0C,
- RC_CANNOT_MAP_MEMORY3 = RUNTIME_COMP_ID | 0x0D,
- RC_TCE_INVALID_SIZE = RUNTIME_COMP_ID | 0x0E,
- RC_TCE_ADDR_NOT_ALIGNED = RUNTIME_COMP_ID | 0x0F,
- RC_TCE_INIT_NOT_RUN = RUNTIME_COMP_ID | 0x10,
- RC_TCE_DEV_MAP_FAIL = RUNTIME_COMP_ID | 0x11,
- RC_TCE_DEV_UNMAP_FAIL = RUNTIME_COMP_ID | 0x12,
- RC_TCE_NO_ACTIVE_PSI = RUNTIME_COMP_ID | 0x13,
+ RC_DO_NOT_USE_THIS = RUNTIME_COMP_ID | 0x00,
+ RC_ATTR_GET_FAIL = RUNTIME_COMP_ID | 0x01,
+ RC_BAD_HDAT_HEADER = RUNTIME_COMP_ID | 0x02,
+ RC_BAD_HDAT_TUPLE = RUNTIME_COMP_ID | 0x03,
+ RC_INVALID_STANDALONE = RUNTIME_COMP_ID | 0x04,
+ RC_CANNOT_MAP_MEMORY = RUNTIME_COMP_ID | 0x05,
+ //RC_XXX = RUNTIME_COMP_ID | 0x06,
+ RC_CANNOT_MAP_MEMORY2 = RUNTIME_COMP_ID | 0x07,
+ RC_INVALID_PAYLOAD_KIND = RUNTIME_COMP_ID | 0x08,
+ RC_NO_HSVC_NODE_DATA_FOUND = RUNTIME_COMP_ID | 0x09,
+ RC_BAD_NACA = RUNTIME_COMP_ID | 0x0A,
+ RC_INVALID_ADDRESS = RUNTIME_COMP_ID | 0x0B,
+ RC_INVALID_SECTION = RUNTIME_COMP_ID | 0x0C,
+ RC_CANNOT_MAP_MEMORY3 = RUNTIME_COMP_ID | 0x0D,
+ RC_TCE_INVALID_SIZE = RUNTIME_COMP_ID | 0x0E,
+ RC_TCE_ADDR_NOT_ALIGNED = RUNTIME_COMP_ID | 0x0F,
+ RC_TCE_INIT_NOT_RUN = RUNTIME_COMP_ID | 0x10,
+ RC_TCE_DEV_MAP_FAIL = RUNTIME_COMP_ID | 0x11,
+ RC_TCE_DEV_UNMAP_FAIL = RUNTIME_COMP_ID | 0x12,
+ RC_TCE_NO_ACTIVE_PSI = RUNTIME_COMP_ID | 0x13,
RC_TCE_NOT_ENOUGH_FREE_ENTRIES = RUNTIME_COMP_ID | 0x14,
- RC_TCE_ENTRY_NOT_CONTIGUOUS = RUNTIME_COMP_ID | 0x15,
- RC_NO_SPIRA = RUNTIME_COMP_ID | 0x16,
- RC_CANNOT_MAP_HDAT = RUNTIME_COMP_ID | 0x17,
- RC_NOT_ENOUGH_SPACE = RUNTIME_COMP_ID | 0x18,
- RT_UNIT_TARGET_NOT_FOUND = RUNTIME_COMP_ID | 0x19,
- RT_TARGET_TYPE_NOT_SUPPORTED = RUNTIME_COMP_ID | 0x1A,
- RT_NO_PROC_TARGET = RUNTIME_COMP_ID | 0x1B,
- RC_UNMAP_FAIL = RUNTIME_COMP_ID | 0x1C,
- RC_PM_RT_UNKNOWN_MODE = RUNTIME_COMP_ID | 0x1D,
- RC_PM_RT_INTERFACE_ERR = RUNTIME_COMP_ID | 0x1E,
- RC_PM_RT_HCODE_UPDATE_ERR = RUNTIME_COMP_ID | 0x1F,
- RC_INVALID_RHB_INSTANCE = RUNTIME_COMP_ID | 0x20,
+ RC_TCE_ENTRY_NOT_CONTIGUOUS = RUNTIME_COMP_ID | 0x15,
+ RC_NO_SPIRA = RUNTIME_COMP_ID | 0x16,
+ RC_CANNOT_MAP_HDAT = RUNTIME_COMP_ID | 0x17,
+ RC_NOT_ENOUGH_SPACE = RUNTIME_COMP_ID | 0x18,
+ RT_UNIT_TARGET_NOT_FOUND = RUNTIME_COMP_ID | 0x19,
+ RT_TARGET_TYPE_NOT_SUPPORTED = RUNTIME_COMP_ID | 0x1A,
+ RT_NO_PROC_TARGET = RUNTIME_COMP_ID | 0x1B,
+ RC_UNMAP_FAIL = RUNTIME_COMP_ID | 0x1C,
+ RC_PM_RT_UNKNOWN_MODE = RUNTIME_COMP_ID | 0x1D,
+ RC_PM_RT_INTERFACE_ERR = RUNTIME_COMP_ID | 0x1E,
+ RC_PM_RT_HCODE_UPDATE_ERR = RUNTIME_COMP_ID | 0x1F,
+ RC_INVALID_RHB_INSTANCE = RUNTIME_COMP_ID | 0x20,
+ RC_DUPLICATE_I2C_LINK_IDS = RUNTIME_COMP_ID | 0x21,
+ RC_I2C_DEVICE_NOT_IN_MRW = RUNTIME_COMP_ID | 0x22,
+ RC_INSTANCES_UNSUPPORTED = RUNTIME_COMP_ID | 0x23,
+ RC_I2C_DEVICE_DUPLICATE_IN_MRW = RUNTIME_COMP_ID | 0x24,
+ RC_EXTRA_I2C_DEVICE_IN_MRW = RUNTIME_COMP_ID | 0x25,
};
enum UserDetailsTypes
diff --git a/src/usr/hdat/hdatcommonutil.C b/src/usr/hdat/hdatcommonutil.C
index 09d377d96..4e40119dd 100644
--- a/src/usr/hdat/hdatcommonutil.C
+++ b/src/usr/hdat/hdatcommonutil.C
@@ -86,7 +86,7 @@ uint32_t hdatTpmDataCalcMaxSize()
l_size += sizeof(hdatTpmData_t);
// account for the size of the TPM Info array header
- l_size += sizeof(hdatSbTpmInfo_t);
+ l_size += sizeof(hdatHDIFDataArray_t);
// account for each element of the TPM Info array
l_size += ((sizeof(hdatSbTpmInstInfo_t) +
diff --git a/src/usr/hdat/hdatpcrd.C b/src/usr/hdat/hdatpcrd.C
index 8b46f156c..cd5b75ac1 100644
--- a/src/usr/hdat/hdatpcrd.C
+++ b/src/usr/hdat/hdatpcrd.C
@@ -76,9 +76,6 @@ const HdatKeywordInfo l_mvpdKeywords[] =
};
-//Max number of I2c devices for any given proc
-#define HDAT_PCRD_MAX_I2C_DEV 64
-
/*******************************************************************************
* hdatSetPcrdHdrs
*
diff --git a/src/usr/hdat/hdatpcrd.H b/src/usr/hdat/hdatpcrd.H
index 647c8779a..421c7c587 100644
--- a/src/usr/hdat/hdatpcrd.H
+++ b/src/usr/hdat/hdatpcrd.H
@@ -56,6 +56,9 @@ namespace HDAT
const uint16_t HDAT_PCRD_VERSION = 0x20;
const char HDAT_PCRD_STRUCT_NAME[7] = "SPPCRD";
+//Max number of I2c devices for any given proc
+#define HDAT_PCRD_MAX_I2C_DEV 64
+
/** @enum hdatDataPtrs
* Enumeration which defines the data sections of the PCRD
*/
diff --git a/src/usr/hdat/hdattpmdata.H b/src/usr/hdat/hdattpmdata.H
index 369e30f28..b9ee44552 100644
--- a/src/usr/hdat/hdattpmdata.H
+++ b/src/usr/hdat/hdattpmdata.H
@@ -60,6 +60,7 @@ enum {
TpmDataPtrCnt = 1,
TpmDataChildStrCnt = 0,
TpmDataChildStrOffset = 0,
+ TpmDataMinRqrdPcrdVersion = 0x1
};
/**
@@ -82,18 +83,6 @@ struct hdatTpmData_t
uint8_t hdatReserved1[16]; // Padding for alignment and growth/compatibility
} __attribute__ ((packed));
-
-/**
- * @brief Structure definition for Secureboot TPM Info Array
- */
-struct hdatSbTpmInfo_t
-{
- uint32_t hdatSbTpmArrayOffset;
- uint32_t hdatSbTpmArrayNumEntries;
- uint32_t hdatSbTpmArrayEntrySize;
-} __attribute__ ((packed));
-
-
/**
* @brief Structure definition for Secureboot TPM Instance Info
*/
diff --git a/src/usr/runtime/hdatservice.C b/src/usr/runtime/hdatservice.C
index cc289f5fa..f556be180 100644
--- a/src/usr/runtime/hdatservice.C
+++ b/src/usr/runtime/hdatservice.C
@@ -868,6 +868,38 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
o_dataSize = record_size;
o_dataAddr = base_addr + i_instance * o_dataSize;
}
+ else if( RUNTIME::PCRD == i_section )
+ {
+ hdat5Tuple_t* tuple = nullptr;
+ if( iv_spiraS )
+ {
+ tuple = &(iv_spiraS->hdatDataArea[SPIRAS_PCRD]);
+ }
+ else if( unlikely(iv_spiraL != nullptr) )
+ {
+ tuple = &(iv_spiraL->hdatDataArea[SPIRAL_PCRD]);
+ }
+ TRACUCOMP( g_trac_runtime, "PCRD_DATA tuple=%p", tuple );
+
+ errhdl = check_tuple( i_section, tuple );
+ if( errhdl )
+ {
+ break;
+ }
+
+ uint64_t base_addr = 0;
+ errhdl = getSpiraTupleVA(tuple, base_addr);
+ if( errhdl )
+ {
+ break;
+ }
+
+ TRACUCOMP( g_trac_runtime, "pcrd_data=%p", base_addr );
+
+ record_size = tuple->hdatAllocSize;
+ o_dataSize = record_size;
+ o_dataAddr = base_addr + i_instance * o_dataSize;
+ }
// MS DUMP Source Table - MDST
else if( RUNTIME::MS_DUMP_SRC_TBL == i_section )
{
@@ -1425,6 +1457,91 @@ void hdatService::rediscoverHDAT( void )
iv_mem_regions.clear();
}
+/*
+ * @brief Get the number of instances in an HDAT section
+ */
+errlHndl_t hdatService::getInstanceCount(RUNTIME::SectionId i_section,
+ uint64_t& o_count)
+{
+ errlHndl_t errhdl = nullptr;
+ hdat5Tuple_t* tuple = nullptr;
+
+ do
+ {
+ hdatSpiraSDataAreas l_spiraS = SPIRAS_INVALID;
+ hdatSpiraLegacyDataAreas l_spiraL = SPIRAL_INVALID;
+ hdatSpiraHDataAreas l_spiraH = SPIRAH_INVALID;
+
+ switch(i_section)
+ {
+ case RUNTIME::NODE_TPM_RELATED:
+ l_spiraS = SPIRAS_TPM_DATA;
+ l_spiraL = SPIRAL_TPM_DATA;
+ break;
+ case RUNTIME::PCRD:
+ l_spiraS = SPIRAS_PCRD;
+ l_spiraL = SPIRAL_PCRD;
+ break;
+ case RUNTIME::MS_DUMP_SRC_TBL:
+ l_spiraH = SPIRAH_MS_DUMP_SRC_TBL;
+ l_spiraL = SPIRAL_MS_DUMP_SRC_TBL;
+ break;
+ case RUNTIME::MS_DUMP_DST_TBL:
+ l_spiraH = SPIRAH_MS_DUMP_DST_TBL;
+ l_spiraL = SPIRAL_MS_DUMP_DST_TBL;
+ break;
+ case RUNTIME::MS_DUMP_RESULTS_TBL:
+ l_spiraH = SPIRAH_MS_DUMP_RSLT_TBL;
+ l_spiraL = SPIRAL_MS_DUMP_RSLT_TBL;
+ break;
+ default:
+ TRACFCOMP( g_trac_runtime,
+ "getInstanceCount> section %d has no concept of instances",
+ i_section );
+ /*@
+ * @errortype
+ * @moduleid RUNTIME::MOD_HDATSERVICE_GETINSTANCECOUNT
+ * @reasoncode RUNTIME::RC_INSTANCES_UNSUPPORTED
+ * @userdata1 Section Id
+ * @userdata2 <unused>
+ * @devdesc Unsupported section requested
+ * @custdesc Unexpected boot firmware error.
+ */
+ errhdl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_HDATSERVICE_GETINSTANCECOUNT,
+ RUNTIME::RC_INSTANCES_UNSUPPORTED,
+ i_section,
+ 0,
+ true /*Add HB Software Callout*/);
+ errhdl->collectTrace(RUNTIME_COMP_NAME,KILOBYTE);
+ break;
+ }
+
+ if( iv_spiraS )
+ {
+ tuple = &(iv_spiraS->hdatDataArea[l_spiraS]);
+ }
+ else if( iv_spiraH )
+ {
+ tuple = &(iv_spiraH->hdatDataArea[l_spiraH]);
+ }
+ else if( unlikely(iv_spiraL != nullptr) )
+ {
+ tuple = &(iv_spiraL->hdatDataArea[l_spiraL]);
+ }
+ errhdl = check_tuple( i_section, tuple );
+ if( errhdl )
+ {
+ break;
+ }
+ o_count = tuple->hdatActualCnt;
+
+ } while (0);
+
+ return errhdl;
+}
+
/********************
Public Methods
********************/
@@ -1477,6 +1594,12 @@ void rediscover_hdat( void )
Singleton<hdatService>::instance().rediscoverHDAT();
}
+errlHndl_t get_instance_count( RUNTIME::SectionId i_section, uint64_t& o_count )
+{
+ return Singleton<RUNTIME::hdatService>::instance().
+ getInstanceCount(i_section, o_count);
+}
+
};
/********************
diff --git a/src/usr/runtime/hdatservice.H b/src/usr/runtime/hdatservice.H
index a8de9402d..a421459ac 100644
--- a/src/usr/runtime/hdatservice.H
+++ b/src/usr/runtime/hdatservice.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2015 */
+/* Contributors Listed Below - COPYRIGHT 2013,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -98,6 +98,12 @@ namespace RUNTIME
size_t& o_dataSize );
/**
+ * @brief See documentation for get_instance_count in runtime.H
+ */
+ errlHndl_t getInstanceCount( RUNTIME::SectionId i_section,
+ uint64_t& o_count);
+
+ /**
* @brief Update the actual count of section. Only supported for
* memory dump results table
*
@@ -267,7 +273,7 @@ namespace RUNTIME
public:
/**
- * @brief Store the actual count of a section.
+ * @brief Store the actual count of a section.
*
* @param[in] i_section Chunk of data to update
* @param[in] i_count Actual count for MDRT entries
diff --git a/src/usr/runtime/hdatstructs.H b/src/usr/runtime/hdatstructs.H
index b686d7f8c..f601053a3 100644
--- a/src/usr/runtime/hdatstructs.H
+++ b/src/usr/runtime/hdatstructs.H
@@ -74,6 +74,7 @@ struct hdatNaca_t
*/
enum hdatSpiraLegacyDataAreas
{
+ SPIRAL_INVALID = -1,
SPIRAL_FIRST = 0,
SPIRAL_SP_SUBSYS = 0, // service processor subsystem
SPIRAL_IPL_PARMS = 1, // IPL parameters
@@ -111,6 +112,7 @@ enum hdatSpiraLegacyDataAreas
*/
enum hdatSpiraHDataAreas
{
+ SPIRAH_INVALID = -1,
SPIRAH_FIRST = 0,
SPIRAH_HOST_DATA_AREAS = 0, // Reserved memory for FSP-filled data
SPIRAH_PROC_INIT = 1, // phyp-supplied processor init data
@@ -127,6 +129,7 @@ enum hdatSpiraHDataAreas
*/
enum hdatSpiraSDataAreas
{
+ SPIRAS_INVALID = -1,
SPIRAS_FIRST = 0,
SPIRAS_SP_SUBSYS = 0, // service processor subsystem
SPIRAS_IPL_PARMS = 1, // IPL parameters
diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C
index 59e322b53..4be72cce3 100644
--- a/src/usr/runtime/populate_hbruntime.C
+++ b/src/usr/runtime/populate_hbruntime.C
@@ -57,6 +57,7 @@
#include <hdat/hdat.H>
#include <config.h>
#include "../hdat/hdattpmdata.H"
+#include "../hdat/hdatpcrd.H"
#include "../secureboot/trusted/tpmLogMgr.H"
#include "../secureboot/trusted/trustedboot.H"
#include <targeting/common/attributeTank.H>
@@ -1289,7 +1290,7 @@ errlHndl_t populate_TpmInfoByNode()
// populated using the following start offset
auto l_sbTpmInfoStart = l_currOffset;
- auto const l_hdatSbTpmInfo = reinterpret_cast<HDAT::hdatSbTpmInfo_t*>
+ auto const l_hdatSbTpmInfo = reinterpret_cast<HDAT::hdatHDIFDataArray_t*>
(l_baseAddr + l_currOffset);
TARGETING::TargetHandleList tpmList;
@@ -1302,9 +1303,10 @@ errlHndl_t populate_TpmInfoByNode()
auto const l_numTpms = tpmList.size();
// fill in the values for the Secure Boot TPM Info Array Header
- l_hdatSbTpmInfo->hdatSbTpmArrayOffset = sizeof(*l_hdatSbTpmInfo);
- l_hdatSbTpmInfo->hdatSbTpmArrayNumEntries = l_numTpms;
- l_hdatSbTpmInfo->hdatSbTpmArrayEntrySize = sizeof(HDAT::hdatSbTpmInstInfo_t);
+ l_hdatSbTpmInfo->hdatOffset = sizeof(*l_hdatSbTpmInfo);
+ l_hdatSbTpmInfo->hdatArrayCnt = l_numTpms;
+ l_hdatSbTpmInfo->hdatAllocSize = sizeof(HDAT::hdatSbTpmInstInfo_t);
+ l_hdatSbTpmInfo->hdatActSize = l_hdatSbTpmInfo->hdatAllocSize;
// advance current offset to after the Secure Boot TPM info array header
l_currOffset += sizeof(*l_hdatSbTpmInfo);
@@ -1328,7 +1330,8 @@ errlHndl_t populate_TpmInfoByNode()
assert(itr != l_procList.end(), "Bug! TPM must have a processor.");
auto l_proc = *itr;
- l_tpmInstInfo->hdatChipId = l_proc->getAttr<TARGETING::ATTR_CHIP_ID>();
+ l_tpmInstInfo->hdatChipId = l_proc->getAttr<
+ TARGETING::ATTR_ORDINAL_ID>();
l_tpmInstInfo->hdatDbobId = l_node->getAttr<
TARGETING::ATTR_ORDINAL_ID>();
@@ -1421,13 +1424,308 @@ errlHndl_t populate_TpmInfoByNode()
// the following will be used to calculate the second part of pointer pair
auto l_physInterStart = l_currOffset;
- // set up the physical interaction mechanism info header
- // @TODO RTC 170638: Calculate the real IDs
- l_physInter->i2cLinkIdWindowOpen = HDAT::I2C_LINK_ID::NOT_APPLICABLE;
+ // start with an empty list of link IDs
+ std::vector<HDAT::i2cLinkId_t> l_linkIds;
+
+ // obtain a list of i2c targets
+ std::vector<I2C::DeviceInfo_t> l_i2cTargetList;
+ for (auto pProc : l_procList)
+ {
+ I2C::getDeviceInfo(pProc, l_i2cTargetList);
+ }
+ auto i2cDevItr = l_i2cTargetList.begin();
+ while(i2cDevItr != l_i2cTargetList.end())
+ {
+ switch((*i2cDevItr).devicePurpose)
+ {
+ case TARGETING::HDAT_I2C_DEVICE_PURPOSE_WINDOW_OPEN:
+ case TARGETING::HDAT_I2C_DEVICE_PURPOSE_PHYSICAL_PRESENCE:
+ // keep devices with these two purposes
+ ++i2cDevItr;
+ break;
+ default:
+ // remove devices with any other purpose
+ i2cDevItr = l_i2cTargetList.erase(i2cDevItr);
+ break;
+ }
+ }
+
+ uint64_t l_numInstances = 0;
+
+ l_elog = RUNTIME::get_instance_count(RUNTIME::PCRD, l_numInstances);
+ if (l_elog)
+ {
+ TRACFCOMP( g_trac_runtime, ERR_MRK "populate_TpmInfoByNode: get_instance_count() failed for PCRD HDAT section");
+ break;
+ }
+
+ uint64_t l_pcrdAddr = 0;
+ uint64_t l_pcrdSizeMax = 0;
+
+ // Initialize i2cLinkIds to NA before attempting populate
l_physInter->i2cLinkIdPhysicalPresence = HDAT::I2C_LINK_ID::NOT_APPLICABLE;
+ l_physInter->i2cLinkIdWindowOpen = HDAT::I2C_LINK_ID::NOT_APPLICABLE;
+
+ for (uint64_t l_pcrdInstance = 0;
+ l_pcrdInstance < l_numInstances;
+ ++l_pcrdInstance)
+ {
+
+ l_elog = RUNTIME::get_host_data_section(RUNTIME::PCRD,
+ l_pcrdInstance,
+ l_pcrdAddr,
+ l_pcrdSizeMax);
+ if(l_elog)
+ {
+ TRACFCOMP( g_trac_runtime, ERR_MRK "populate_TpmInfoByNode: get_host_data_section() failed for PCRD HDAT section, instance %d", l_pcrdInstance);
+ break;
+ }
+
+ // Get a pointer to the PCRD header
+ auto l_pcrd = reinterpret_cast<const HDAT::hdatSpPcrd_t*>(l_pcrdAddr);
+
+ // Check the version of the PCRD section header
+ assert(l_pcrd->hdatHdr.hdatVersion >= HDAT::TpmDataMinRqrdPcrdVersion,
+ "Bad PCRD section version 0x%X - must be 0x1 or greater",
+ l_pcrd->hdatHdr.hdatVersion);
+
+ // Get offset for the i2c array header
+ auto i2cAryOff =
+ l_pcrd->hdatPcrdIntData[HDAT::HDAT_PCRD_DA_HOST_I2C].hdatOffset;
+
+ // Convert i2c array header offset to a pointer to the i2c array header
+ const auto l_hostI2cPcrdHdrPtr =
+ reinterpret_cast<HDAT::hdatHDIFDataArray_t*>(l_pcrdAddr + i2cAryOff);
+
+ // make sure the array count is within reasonable limits
+ assert(l_hostI2cPcrdHdrPtr->hdatArrayCnt <= HDAT_PCRD_MAX_I2C_DEV,
+ "HDAT PCRD reported more than the max number of i2c devices! Count:%d",
+ l_hostI2cPcrdHdrPtr->hdatArrayCnt);
+
+ // Get the pointer to the first element in the i2c array
+ // This is the address of the header plus the offset given in the header
+ auto l_i2cDevStart =
+ reinterpret_cast<const uint8_t*>(l_hostI2cPcrdHdrPtr)
+ + l_hostI2cPcrdHdrPtr->hdatOffset;
+
+ // Calculate the stop pointer
+ auto l_i2cDevStop = l_i2cDevStart + (l_hostI2cPcrdHdrPtr->hdatArrayCnt *
+ l_hostI2cPcrdHdrPtr->hdatAllocSize);
+
+ // for each link ID in the PCRD
+ for (auto l_cur = l_i2cDevStart;
+ l_cur != l_i2cDevStop;
+ l_cur += l_hostI2cPcrdHdrPtr->hdatAllocSize )
+ {
+ // reinterpret the byte pointer as a struct pointer
+ auto l_i2cDev = reinterpret_cast<const HDAT::hdatI2cData_t*>(l_cur);
+
+ // if we've seen it already
+ auto it = std::find(l_linkIds.begin(),
+ l_linkIds.end(),
+ l_i2cDev->hdatI2cLinkId);
+ if (it != l_linkIds.end())
+ {
+ const auto l_linkId = *it;
+ TRACFCOMP(g_trac_runtime,
+ "populate_TpmInfoByNode: A duplicate link Id was found. %d",
+ l_linkId);
+
+#if 0
+ // TODO RTC 173541 - Renable when HB + FIPS have the uniqueness
+ // change.
+
+ // terminate the boot due to an integrity violation
+ /*@
+ * @errortype
+ * @reasoncode RUNTIME::RC_DUPLICATE_I2C_LINK_IDS
+ * @moduleid RUNTIME::MOD_POPULATE_TPMINFOBYNODE
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @userdata1 I2C Link ID
+ * @devdesc Found duplicate I2C link IDs in PCRD section
+ * of HDAT. System security cannot be guaranteed.
+ * @custdesc Platform security problem detected
+ */
+ auto err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_POPULATE_TPMINFOBYNODE,
+ RUNTIME::RC_DUPLICATE_I2C_LINK_IDS,
+ l_linkId,
+ 0,
+ true);
+
+ SECUREBOOT::handleSecurebootFailure(err);
+
+ assert(true,"Bug! handleSecurebootFailure shouldn't return!");
+#endif
+
+ }
+ else
+ {
+ // add it to a known list to make sure we don't see it again
+ l_linkIds.push_back(l_i2cDev->hdatI2cLinkId);
+ }
+ // use this pointer to avoid having to repeat the switch statement
+ // later
+ HDAT::i2cLinkId_t* l_pLinkId = nullptr;
+
+ switch(l_i2cDev->hdatI2cSlaveDevPurp)
+ {
+ case TARGETING::HDAT_I2C_DEVICE_PURPOSE_WINDOW_OPEN:
+
+ l_pLinkId = &l_physInter->i2cLinkIdWindowOpen;
+ break;
+
+ case TARGETING::HDAT_I2C_DEVICE_PURPOSE_PHYSICAL_PRESENCE:
+
+ l_pLinkId = &l_physInter->i2cLinkIdPhysicalPresence;
+ break;
+
+ default:
+ // Physical Presence Info not supported for this I2c device
+ // purpose. This device will not be referred to by the Node TPM
+ // Related Info Section, but we still ensure uniqueness of all
+ // link IDs in the I2c device list from the PCRD.
+ continue;
+ }
+
+ // now make sure we have a match in the mrw
+ auto itr = std::find_if(l_i2cTargetList.begin(),
+ l_i2cTargetList.end(),
+
+ [&l_i2cDev,&l_pcrd](const I2C::DeviceInfo_t & i_i2cDevMrw)
+ {
+ return
+ i_i2cDevMrw.masterChip->getAttr<
+ TARGETING::ATTR_ORDINAL_ID>() ==
+ l_pcrd->hdatChipData.hdatPcrdProcChipId &&
+ l_i2cDev->hdatI2cEngine == i_i2cDevMrw.engine &&
+ l_i2cDev->hdatI2cMasterPort == i_i2cDevMrw.masterPort &&
+ l_i2cDev->hdatI2cBusSpeed == i_i2cDevMrw.busFreqKhz &&
+ l_i2cDev->hdatI2cSlaveDevType == i_i2cDevMrw.deviceType &&
+ l_i2cDev->hdatI2cSlaveDevAddr == i_i2cDevMrw.addr &&
+ l_i2cDev->hdatI2cSlavePort == i_i2cDevMrw.slavePort &&
+ l_i2cDev->hdatI2cSlaveDevPurp == i_i2cDevMrw.devicePurpose;
+ });
+
+ if (itr == l_i2cTargetList.end())
+ {
+ // couldn't find it, physical presense will not be available
+ TRACFCOMP(g_trac_runtime,
+ "populate_TpmInfoByNode: I2c device in the PCRD with link ID %d does not have a match in the MRW",
+ l_i2cDev->hdatI2cLinkId);
+ /*@
+ * @errortype
+ * @reasoncode RUNTIME::RC_I2C_DEVICE_NOT_IN_MRW
+ * @moduleid RUNTIME::MOD_POPULATE_TPMINFOBYNODE
+ * @severity ERRL_SEV_INFORMATIONAL
+ * @userdata1 I2C Link ID
+ * @devdesc An I2C device in the PCRD does not have a match
+ * in the MRW. Physical presence detection
+ * will not be available.
+ * @custdesc Platform security problem detected
+ */
+ auto err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ RUNTIME::MOD_POPULATE_TPMINFOBYNODE,
+ RUNTIME::RC_I2C_DEVICE_NOT_IN_MRW,
+ l_i2cDev->hdatI2cLinkId,
+ 0,
+ true);
+ ERRORLOG::errlCommit(err, RUNTIME_COMP_ID);
+ }
+ else
+ {
+ if (*l_pLinkId != HDAT::I2C_LINK_ID::NOT_APPLICABLE)
+ {
+ // found a duplicate link id match indicating that there
+ // was an error in the model
+ TRACFCOMP(g_trac_runtime,
+ "populate_TpmInfoByNode: I2c device in the PCRD with link ID %d has a duplicate match in the MRW",
+ l_i2cDev->hdatI2cLinkId);
+ /*@
+ * @errortype
+ * @reasoncode RUNTIME::RC_I2C_DEVICE_DUPLICATE_IN_MRW
+ * @moduleid RUNTIME::MOD_POPULATE_TPMINFOBYNODE
+ * @severity ERRL_SEV_INFORMATIONAL
+ * @userdata1 I2C Link ID
+ * @devdesc An I2C device in the PCRD has a duplicate
+ * match in the MRW. Physical presence
+ * detection will still be available.
+ * @custdesc Platform security problem detected
+ */
+ auto err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ RUNTIME::MOD_POPULATE_TPMINFOBYNODE,
+ RUNTIME::RC_I2C_DEVICE_DUPLICATE_IN_MRW,
+ l_i2cDev->hdatI2cLinkId,
+ 0,
+ true);
+ ERRORLOG::errlCommit(err, RUNTIME_COMP_ID);
+ }
+ else // found a match
+ {
+ *l_pLinkId = l_i2cDev->hdatI2cLinkId;
+ l_i2cTargetList.erase(itr);
+ }
+ }
+
+ } // for each link ID in the current PCRD instance
+
+ } // for each instance
+
+ if (!l_i2cTargetList.empty())
+ {
+ for (auto i2cDev : l_i2cTargetList)
+ {
+ TRACFCOMP(g_trac_runtime,
+ "populate_TpmInfoByNode: I2c device in the MRW was not found in the PCRD having engine: 0x%X masterport: 0x%X devicetype: 0x%X address: 0x%X slaveport: 0x%X devicepurpose: 0x%X master HUID: %X",
+ i2cDev.engine,
+ i2cDev.masterPort,
+ i2cDev.deviceType,
+ i2cDev.addr,
+ i2cDev.slavePort,
+ i2cDev.devicePurpose,
+ TARGETING::get_huid(i2cDev.masterChip));
+ /*@
+ * @errortype
+ * @reasoncode RUNTIME::RC_EXTRA_I2C_DEVICE_IN_MRW
+ * @moduleid RUNTIME::MOD_POPULATE_TPMINFOBYNODE
+ * @severity ERRL_SEV_UNRECOVERABLE
+ * @userdata1 [0:7] I2C engine
+ * @userdata1 [8:15] I2C masterPort
+ * @userdata1 [16:23] I2C slave deviceType
+ * @userdata1 [24:31] I2C slave address
+ * @userdata1 [32:39] I2C slave port
+ * @userdata1 [40:47] I2C device purpose
+ * @userdata1 [48:63] Bus speed in KHz
+ * @userdata2 master chip HUID
+ * @devdesc An I2C device in the MRW has no match
+ * in the PCRD.
+ * @custdesc Platform security problem detected
+ */
+ auto err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ RUNTIME::MOD_POPULATE_TPMINFOBYNODE,
+ RUNTIME::RC_EXTRA_I2C_DEVICE_IN_MRW,
+ TWO_UINT32_TO_UINT64(
+ FOUR_UINT8_TO_UINT32(i2cDevItr->engine,
+ i2cDevItr->masterPort,
+ i2cDevItr->deviceType,
+ i2cDevItr->addr),
+ TWO_UINT16_TO_UINT32(
+ TWO_UINT8_TO_UINT16(i2cDevItr->slavePort,
+ i2cDevItr->devicePurpose),
+ i2cDevItr->busFreqKhz)
+ ),
+ TARGETING::get_huid(i2cDevItr->masterChip),
+ true);
+ ERRORLOG::errlCommit(err, RUNTIME_COMP_ID);
+ }
+ }
- // advance the current offset to account for the physical interaction
- // mechanism info struct
+ // advance the current offset to account for the physical
+ // interaction mechanism info struct
l_currOffset =+ sizeof(*l_physInter);
// populate the second part of the pointer pair from earlier
diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml
index 27fc6b616..6a79205da 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types.xml
@@ -33883,6 +33883,14 @@ Measured in GB</description>
<value>B</value>
</enumerator>
<enumerator>
+ <name>WINDOW_OPEN</name>
+ <value>0xD</value>
+ </enumerator>
+ <enumerator>
+ <name>PHYSICAL_PRESENCE</name>
+ <value>0xE</value>
+ </enumerator>
+ <enumerator>
<name>UNKNOWN</name>
<value>FF</value>
</enumerator>
OpenPOWER on IntegriCloud