summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJaymes Wilks <mjwilks@us.ibm.com>2017-04-19 08:53:03 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-05-23 11:01:28 -0400
commit096ef9048330813def6681fb0f45271cb3c24259 (patch)
tree720e1aa4b99dfa1b5f7f8befa4d0248a9abc63a1 /src
parent8a22766d0c63f6dd86b1cfefb624c8645becdab3 (diff)
downloadtalos-hostboot-096ef9048330813def6681fb0f45271cb3c24259.tar.gz
talos-hostboot-096ef9048330813def6681fb0f45271cb3c24259.zip
Add TPM Presence Info to HDAT
Populate HDAT TPM Section with TPM Presence Info by refering to link IDs in HDAT PCRD section and verify that the PRCD section's list of link IDs are unique and valid. Change-Id: I49956aae129b325f55a6358caa0af4da1951b58c RTC:170638 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/39658 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Stephen M. Cprek <smcprek@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
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