summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaymes Wilks <mjwilks@us.ibm.com>2017-02-24 15:08:57 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-04-10 13:48:29 -0400
commit5bdb1f8ec34124c68db869dbb46b27e5a5fc24b5 (patch)
tree84ccf175a63ea0c362d2221cc12b59669ec0a51f
parentd85536ac35dd97a666b7b8de090f255b1a33c7d8 (diff)
downloadtalos-hostboot-5bdb1f8ec34124c68db869dbb46b27e5a5fc24b5.tar.gz
talos-hostboot-5bdb1f8ec34124c68db869dbb46b27e5a5fc24b5.zip
Populate HDAT TPM Info
Populate TPM Info during the secureboot runtime routine. Change-Id: I02b960c175d51dc9b5941e15a529bd1587747444 RTC:166834 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/37187 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: Stephen M. Cprek <smcprek@us.ibm.com> Reviewed-by: Michael Baiocchi <mbaiocch@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rw-r--r--src/include/usr/isteps/istep20list.H3
-rw-r--r--src/include/usr/runtime/runtime.H22
-rw-r--r--src/usr/hdat/hdatcommonutil.C109
-rwxr-xr-xsrc/usr/hdat/hdathdif.C6
-rw-r--r--src/usr/hdat/hdattpmdata.C60
-rw-r--r--src/usr/hdat/hdattpmdata.H42
-rw-r--r--src/usr/hdat/hdatutil.C6
-rw-r--r--src/usr/isteps/istep21/call_host_runtime_setup.C11
-rw-r--r--src/usr/runtime/hdatservice.C28
-rw-r--r--src/usr/runtime/hdatstructs.H8
-rw-r--r--src/usr/runtime/makefile5
-rw-r--r--src/usr/runtime/populate_hbruntime.C330
12 files changed, 523 insertions, 107 deletions
diff --git a/src/include/usr/isteps/istep20list.H b/src/include/usr/isteps/istep20list.H
index 4de197e13..a12f9bdea 100644
--- a/src/include/usr/isteps/istep20list.H
+++ b/src/include/usr/isteps/istep20list.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2016 */
+/* Contributors Listed Below - COPYRIGHT 2012,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -91,6 +91,7 @@ const DepModInfo g_istep20Dependancies = {
{
DEP_LIB(libistep20.so),
DEP_LIB(libxz.so),
+ DEP_LIB(libruntime.so),
NULL
}
};
diff --git a/src/include/usr/runtime/runtime.H b/src/include/usr/runtime/runtime.H
index 0ece1744a..7086ef55b 100644
--- a/src/include/usr/runtime/runtime.H
+++ b/src/include/usr/runtime/runtime.H
@@ -75,11 +75,29 @@ errlHndl_t populate_hbRuntimeData( void );
* values acquired via the secureboot module from a verified source, and
* so, henceforth are available to the host at runtime.
*
- * @return errlHndl_t NULL on Success
+ * @return errlHndl_t nullptr on Success else pointer to error log
*/
errlHndl_t populate_hbSecurebootData( void );
/**
+ * @brief Populate TPM Info in mainstore
+ *
+ * @description Populates the Secure Boot TPM Instance Info section of HDAT
+ * with trusted information acquired via secure methods, and overwrites
+ * any untrusted information that was already there.
+ *
+ * @return errlHndl_t nullptr on Success else pointer to error log
+ */
+errlHndl_t populate_hbTpmInfo( void );
+
+/**
+ * @brief Fills in Tpm Info in HDAT for current node
+ *
+ * @return errlHndl_t nullptr on success else pointer to error log
+ */
+errlHndl_t populate_TpmInfoByNode();
+
+/**
* @brief Fills in HBRT for given NODE
*
* @param[in] iNodeId : Node number from 0 to 7 ..etc...
@@ -127,6 +145,8 @@ enum SectionId
NACA, //< NACA
HBRT, //< Hostboot Runtime
HBRT_DATA, //< Hostboot Runtime Data
+ IPMI_DATA, //< IPMI Sensor Mapping Data
+ NODE_TPM_RELATED, //< Node TPM Related Data
RESERVED_MEM, //< Hostboot's Reserved Mainstore Memory
LAST_SECTION = RESERVED_MEM //< Placeholder for arrays
};
diff --git a/src/usr/hdat/hdatcommonutil.C b/src/usr/hdat/hdatcommonutil.C
new file mode 100644
index 000000000..350b5b727
--- /dev/null
+++ b/src/usr/hdat/hdatcommonutil.C
@@ -0,0 +1,109 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hdat/hdatcommonutil.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <ctype.h>
+#include "hdattpmdata.H"
+#include <util/align.H>
+#include <algorithm>
+
+#include <targeting/common/util.H>
+#include <targeting/common/target.H>
+#include <targeting/common/targetservice.H>
+
+namespace HDAT
+{
+trace_desc_t *g_trac_hdat = nullptr;
+TRAC_INIT(&g_trac_hdat,HDAT_COMP_NAME,4096);
+
+/** @brief Structure id for an HDIF structure*/
+const uint16_t HDAT_HDIF_STRUCT_ID = 0xD1F0;
+
+/** @brief Align value for HDAT instances */
+const uint8_t HDAT_HDIF_ALIGN = 128;
+
+const char g_hdatTpmDataEyeCatch[] = "TPMREL";
+
+uint16_t hdatCalcMaxTpmsPerNode()
+{
+ size_t l_maxTpms = 0;
+
+ // calculate max # of TPMs per node
+
+ // look for class ENC type NODE and class chip TPM to find TPMs
+ TARGETING::TargetHandleList l_nodeEncList;
+
+ getEncResources(l_nodeEncList, TARGETING::TYPE_NODE,
+ TARGETING::UTIL_FILTER_ALL);
+
+ // loop thru the nodes and check number of TPMs
+ std::for_each(l_nodeEncList.begin(), l_nodeEncList.end(),
+ [&l_maxTpms](const TARGETING::Target* const i_pNode)
+ {
+ // for this Node, get a list of tpms
+ TARGETING::TargetHandleList l_tpmChipList;
+
+ getChildAffinityTargets ( l_tpmChipList, i_pNode,
+ TARGETING::CLASS_CHIP, TARGETING::TYPE_TPM, false );
+
+ l_maxTpms = std::max(l_maxTpms, l_tpmChipList.size());
+ } );
+ return l_maxTpms;
+}
+
+uint32_t hdatTpmDataCalcMaxSize()
+{
+ uint32_t l_size = 0;
+
+ // TODO RTC 167290 - In order to support multiple nodes, this calculation
+ // needs to be #nodes * [ the entire 18.x set of structures ] and the
+ // initialization needs to be done on each instance. The reported size
+ // (in variable o_size) needs to be the size of a single instance and the
+ // reported count (via o_count) needs to be the number of nodes. For now,
+ // we assume one node.
+
+ // account for the size of the TPM data header
+ l_size += sizeof(hdatTpmData_t);
+
+ // account for the size of the TPM Info array header
+ l_size += sizeof(hdatSbTpmInfo_t);
+
+ // account for each element of the TPM Info array
+ l_size += ((sizeof(hdatSbTpmInstInfo_t) +
+ TPM_SRTM_EVENT_LOG_MAX +
+ TPM_DRTM_EVENT_LOG_MAX)
+ * hdatCalcMaxTpmsPerNode());
+
+ // account for User physical interaction mechanism info struct
+ // and Host I2C device information pointers
+ l_size += (sizeof(hdatPhysInterMechInfo_t) + sizeof(hdatI2cDevInfoPtrs_t) *
+ NUM_I2C_PHYS_PRESENCE_DEVICES);
+
+ // Align size value to match actual allocated size, because we also want to
+ // zero the padded part, and thus simplify multinode support going forward.
+ l_size = ALIGN_X(l_size, HDAT_HDIF_ALIGN);
+
+ return l_size;
+}
+
+}
diff --git a/src/usr/hdat/hdathdif.C b/src/usr/hdat/hdathdif.C
index 7ce7d1bfb..329a1bd37 100755
--- a/src/usr/hdat/hdathdif.C
+++ b/src/usr/hdat/hdathdif.C
@@ -58,9 +58,6 @@ const int32_t HDAT_FAILURE = -1;
/** @brief No children for a data structure*/
const uint32_t HDAT_NO_CHILD = 0;
-/** @brief Structure id for an HDIF structure*/
-const uint16_t HDAT_HDIF_STRUCT_ID = 0xD1F0;
-
/** @brief FFDC Version to classify data in error log */
const uint8_t HDAT_VERSION1 = 1;
@@ -72,9 +69,6 @@ const uint8_t HDAT_NACA_FFDC_SUBSEC2 = 3;
const uint32_t HDAT_REAL_ADDRESS_MASK = 0x80000000;
const uint64_t HDAT_REAL_ADDRESS_MASK64 = 0x8000000000000000ull;
-/** @brief Align value for HDAT instances */
-const uint8_t HDAT_HDIF_ALIGN = 128;
-
/** @brief See the prologue in hdathdif.H
*/
diff --git a/src/usr/hdat/hdattpmdata.C b/src/usr/hdat/hdattpmdata.C
index 8b13fe4e8..dddfc6c67 100644
--- a/src/usr/hdat/hdattpmdata.C
+++ b/src/usr/hdat/hdattpmdata.C
@@ -46,8 +46,6 @@ namespace HDAT
extern trace_desc_t *g_trac_hdat;
-const uint8_t g_hdatTpmDataEyeCatch[] = {'T', 'P', 'M', 'R', 'E', 'L'};
-
HdatTpmData::HdatTpmData(errlHndl_t &o_errlHndl,
const HDAT::hdatMsAddr_t &i_msAddr):
iv_msAddr(i_msAddr),
@@ -147,36 +145,9 @@ errlHndl_t HdatTpmData::hdatLoadTpmData(uint32_t &o_size, uint32_t &o_count)
{
errlHndl_t l_errl = nullptr;
- o_size = 0;
o_count = 0;
- // TODO RTC 167290 - In order to support multiple nodes, this calculation
- // needs to be #nodes * [ the entire 18.x set of structures ] and the
- // initialization needs to be done on each instance. The reported size
- // (in variable o_size) needs to be the size of a single instance and the
- // reported count (via o_count) needs to be the number of nodes. For now,
- // we assume one node.
-
- // account for the size of the TPM data header
- o_size += sizeof(hdatTpmData_t);
-
- // account for the size of the TPM Info array header
- o_size += sizeof(hdatSbTpmInfo_t);
-
- // account for each element of the TPM Info array
- o_size += ((sizeof(hdatSbTpmInstInfo_t) +
- TPM_SRTM_EVENT_LOG_MAX +
- TPM_DRTM_EVENT_LOG_MAX)
- * hdatCalcMaxTpmsPerNode());
-
- // account for User physical interaction mechanism info struct
- // and Host I2C device information pointers
- o_size += (sizeof(hdatPhysInterMechInfo_t) + sizeof(hdatI2cDevInfoPtrs_t) *
- NUM_I2C_PHYS_PRESENCE_DEVICES);
-
- // Align size value to match actual allocated size, because we also want to
- // zero the padded part, and thus simplify multinode support going forward.
- o_size = ALIGN_X(o_size, HDAT_HDIF_ALIGN);
+ o_size = hdatTpmDataCalcMaxSize();
// zero all of it
memset(iv_hdatTpmData,0,o_size);
@@ -191,7 +162,7 @@ errlHndl_t HdatTpmData::hdatLoadTpmData(uint32_t &o_size, uint32_t &o_count)
// add the eyecatcher
memcpy(iv_hdatTpmData->hdatHdr.hdatStructName,
g_hdatTpmDataEyeCatch,
- sizeof(g_hdatTpmDataEyeCatch));
+ strlen(g_hdatTpmDataEyeCatch));
// account for this one instance of Node TPM Related Data
++o_count;
@@ -199,31 +170,4 @@ errlHndl_t HdatTpmData::hdatLoadTpmData(uint32_t &o_size, uint32_t &o_count)
return l_errl;
}
-uint16_t hdatCalcMaxTpmsPerNode()
-{
- size_t l_maxTpms = 0;
-
- // calculate max # of TPMs per node
-
- // look for class ENC type NODE and class chip TPM to find TPMs
- TARGETING::TargetHandleList l_nodeEncList;
-
- getEncResources(l_nodeEncList, TARGETING::TYPE_NODE,
- TARGETING::UTIL_FILTER_ALL);
-
- // loop thru the nodes and check number of TPMs
- std::for_each(l_nodeEncList.begin(), l_nodeEncList.end(),
- [&l_maxTpms](const TARGETING::Target* const i_pNode)
- {
- // for this Node, get a list of tpms
- TARGETING::TargetHandleList l_tpmChipList;
-
- getChildAffinityTargets ( l_tpmChipList, i_pNode,
- TARGETING::CLASS_CHIP, TARGETING::TYPE_TPM, false );
-
- l_maxTpms = std::max(l_maxTpms, l_tpmChipList.size());
- } );
- return l_maxTpms;
-}
-
}
diff --git a/src/usr/hdat/hdattpmdata.H b/src/usr/hdat/hdattpmdata.H
index d17172366..ec7ccb3e5 100644
--- a/src/usr/hdat/hdattpmdata.H
+++ b/src/usr/hdat/hdattpmdata.H
@@ -50,6 +50,28 @@ namespace HDAT
{
/**
+ * @brief Enumeration definition for known defaults to TPM data fields
+ */
+enum {
+ TpmDataInstance = 0,
+ TpmDataVersion = 0x10,
+ TpmDataHdrSize = 0x20,
+ TpmDataPtrOffset = 0x20,
+ TpmDataPtrCnt = 1,
+ TpmDataChildStrCnt = 0,
+ TpmDataChildStrOffset = 0,
+};
+
+/**
+ * @brief Enumeration definition for the TPM states of existence
+ */
+enum TpmState {
+ TpmPresentAndFunctional = 0x1,
+ TpmPresentNonFunctional = 0x2,
+ TpmNonPresent = 0x3,
+};
+
+/**
* @brief Structure definition for HDAT Tpm Node Data Header
*/
struct hdatTpmData_t
@@ -68,7 +90,7 @@ struct hdatSbTpmInfo_t
{
uint32_t hdatSbTpmArrayOffset;
uint32_t hdatSbTpmArrayNumEntries;
- uint32_t hdatSbTpmArraySize;
+ uint32_t hdatSbTpmArrayEntrySize;
} __attribute__ ((packed));
@@ -91,9 +113,8 @@ struct hdatSbTpmInstInfo_t
uint32_t hdatTpmDrtmEventLogEntrySize;
} __attribute__ ((packed));
-
/**
- * @brief Structure definition for HDAT physical interaction mechanism info
+ * @brief Structure definition for HDAT physical interaction mechanism info
*/
struct hdatPhysInterMechInfo_t
{
@@ -102,9 +123,8 @@ struct hdatPhysInterMechInfo_t
uint32_t hdatSizeOfI2cDevInfoPtrs;
} __attribute__ ((packed));
-
/**
- * @brief Structure definition for HDAT Host I2c Device Information pointers
+ * @brief Structure definition for HDAT Host I2C Device Info pointers
*/
struct hdatI2cDevInfoPtrs_t
{
@@ -113,6 +133,7 @@ struct hdatI2cDevInfoPtrs_t
uint32_t hdatHostI2cLinkId;
} __attribute__ ((packed));
+extern const char g_hdatTpmDataEyeCatch[];
/** Begin Class Description
*
@@ -226,5 +247,16 @@ class HdatTpmData
*/
uint16_t hdatCalcMaxTpmsPerNode();
+/**
+ * @brief Calculate the maximum size of the HDAT TPM data section
+ *
+ * @pre None
+ *
+ * @post None
+ *
+ * @retval uint32_t Maximum size of the HDAT TPM data section
+ */
+uint32_t hdatTpmDataCalcMaxSize();
+
}
#endif // HDATTPMDATA_H
diff --git a/src/usr/hdat/hdatutil.C b/src/usr/hdat/hdatutil.C
index 456584316..3e8ef607e 100644
--- a/src/usr/hdat/hdatutil.C
+++ b/src/usr/hdat/hdatutil.C
@@ -34,11 +34,9 @@
using namespace TARGETING;
namespace HDAT
{
-trace_desc_t *g_trac_hdat = NULL;
-TRAC_INIT(&g_trac_hdat,HDAT_COMP_NAME,4096);
+extern trace_desc_t *g_trac_hdat;
-
-/*******************************************************************************
+/*****************************************************************************n
* hdatBldErrLog
*******************************************************************************/
void hdatBldErrLog(errlHndl_t & io_err,
diff --git a/src/usr/isteps/istep21/call_host_runtime_setup.C b/src/usr/isteps/istep21/call_host_runtime_setup.C
index d3c8602e8..801f08a11 100644
--- a/src/usr/isteps/istep21/call_host_runtime_setup.C
+++ b/src/usr/isteps/istep21/call_host_runtime_setup.C
@@ -144,7 +144,16 @@ void* call_host_runtime_setup (void *io_pArgs)
if ( l_err )
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "Failed hbSecurebotData setup" );
+ "Failed hbSecurebootData setup" );
+ break;
+ }
+
+ // API call to populate the TPM Info fields
+ l_err = RUNTIME::populate_hbTpmInfo();
+ if ( l_err )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "Failed hbTpmInfo setup" );
break;
}
diff --git a/src/usr/runtime/hdatservice.C b/src/usr/runtime/hdatservice.C
index 32b266788..ab306c381 100644
--- a/src/usr/runtime/hdatservice.C
+++ b/src/usr/runtime/hdatservice.C
@@ -819,6 +819,34 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section,
o_dataAddr = internal_data_ptrs[0].hdatOffset + base_addr;
o_dataSize = internal_data_ptrs[0].hdatSize;
}
+ else if( RUNTIME::NODE_TPM_RELATED == i_section )
+ {
+ // Find the right tuple and verify it makes sense
+ hdat5Tuple_t* tuple = nullptr;
+ if( iv_spiraS )
+ {
+ tuple = &(iv_spiraS->hdatDataArea[SPIRAS_TPM_DATA]);
+ }
+ else if( unlikely(iv_spiraL != nullptr) )
+ {
+ tuple = &(iv_spiraL->hdatDataArea[SPIRAL_TPM_DATA]);
+ }
+ TRACUCOMP( g_trac_runtime, "NODE_TPM_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, "tpm_data=%p", base_addr );
+
+ // set the base address and size for the section
+ 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 )
{
diff --git a/src/usr/runtime/hdatstructs.H b/src/usr/runtime/hdatstructs.H
index 8fbea2eee..887ecf7fc 100644
--- a/src/usr/runtime/hdatstructs.H
+++ b/src/usr/runtime/hdatstructs.H
@@ -100,7 +100,9 @@ enum hdatSpiraLegacyDataAreas
SPIRAL_PCRD = 22, // PCRD (Chip related data area)
SPIRAL_HSVC_DATA = 23, // Host Services Data
SPIRAL_HBRT_DATA = 24, // Hostboot Runtime Data
- SPIRAL_LAST = 24
+ SPIRAL_IPMI_DATA = 25, // IPMI Data
+ SPIRAL_TPM_DATA = 26, // TPM Node Related Data
+ SPIRAL_LAST = 26
};
/** @enum hdatSpiraHDataAreas
@@ -141,7 +143,9 @@ enum hdatSpiraSDataAreas
SPIRAS_PCRD = 13, // PCRD (Chip related data area)
SPIRAS_HSVC_DATA = 14, // Host Services Data
SPIRAS_HBRT_DATA = 15, // Hostboot Runtime Data
- SPIRAS_LAST = 15
+ SPIRAS_IPMI_DATA = 16, // IPMI Data
+ SPIRAS_TPM_DATA = 17, // Node TPM Related Data
+ SPIRAS_LAST = 17
};
diff --git a/src/usr/runtime/makefile b/src/usr/runtime/makefile
index 14838e18d..d0e0abd93 100644
--- a/src/usr/runtime/makefile
+++ b/src/usr/runtime/makefile
@@ -32,6 +32,8 @@
ROOTPATH = ../../..
MODULE = runtime
+VPATH += ${ROOTPATH}/src/usr/hdat
+
#@TODO RTC:132750
#OBJS += populate_attributes.o
OBJS += populate_hbruntime.o
@@ -39,7 +41,10 @@ OBJS += hdatservice.o
OBJS += fakepayload.o
OBJS += errlud_hdat.o
OBJS += customize_attrs_for_payload.o
+OBJS += hdatcommonutil.o
SUBDIRS += test.d
+EXTRAINCDIR += ${ROOTPATH}/src/usr/hdat
+
include ${ROOTPATH}/config.mk
diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C
index 89456969d..0be167fdf 100644
--- a/src/usr/runtime/populate_hbruntime.C
+++ b/src/usr/runtime/populate_hbruntime.C
@@ -38,6 +38,7 @@
#include <targeting/common/targetservice.H>
#include <targeting/common/utilFilter.H>
#include <targeting/common/entitypath.H>
+#include <targeting/common/commontargeting.H>
#include <runtime/runtime_reasoncodes.H>
#include <runtime/runtime.H>
#include "hdatstructs.H"
@@ -54,6 +55,8 @@
#include <secureboot/trustedbootif.H>
#include <secureboot/service.H>
#include <config.h>
+#include "../hdat/hdattpmdata.H"
+#include "../secureboot/trusted/tpmLogMgr.H"
namespace RUNTIME
@@ -64,6 +67,8 @@ mutex_t g_rhbMutex = MUTEX_INITIALIZER;
// used for populating the TPM required bit in HDAT
const uint16_t TPM_REQUIRED_BIT = 0x8000; //leftmost bit of uint16_t set to 1
+const uint8_t BITS_PER_BYTE = 8;
+
trace_desc_t *g_trac_runtime = nullptr;
TRAC_INIT(&g_trac_runtime, RUNTIME_COMP_NAME, KILOBYTE);
@@ -810,57 +815,324 @@ errlHndl_t populate_hbSecurebootData ( void )
// populate TPM config bits in hdat
bool tpmRequired = false;
- #ifdef CONFIG_TRUSTEDBOOT
+ #ifdef CONFIG_TPMDD
tpmRequired = TRUSTEDBOOT::isTpmRequired();
#endif
l_sysParmsPtr->hdatTpmConfBits = tpmRequired? TPM_REQUIRED_BIT: 0;
- // find max # of TPMs per drawer and populate hdat with it
+ // get max # of TPMs per drawer and populate hdat with it
+ auto l_maxTpms = HDAT::hdatTpmDataCalcMaxSize();
+
+ l_sysParmsPtr->hdatTpmDrawer = l_maxTpms;
+ TRACFCOMP(g_trac_runtime,"Max TPMs = 0x%04X", l_maxTpms);
+
+ // populate hw key hash in hdat
+ #ifdef CONFIG_SECUREBOOT
+ auto hash = l_sysParmsPtr->hdatHwKeyHashValue;
+ SECUREBOOT::getHwKeyHash(hash);
+ #else
+ memset(l_sysParmsPtr->hdatHwKeyHashValue,0,
+ sizeof(l_sysParmsPtr->hdatHwKeyHashValue));
+ #endif
+
+ } while(0);
+
+ return (l_elog);
+} // end populate_hbRuntime
+
+errlHndl_t populate_TpmInfoByNode()
+{
+ errlHndl_t l_elog = nullptr;
+
+ do {
+
+ uint64_t l_baseAddr = 0;
+ uint64_t l_dataSizeMax = 0;
+ const uint64_t l_instance = 0; // pass 0 since there is only one record
+
+ // TODO RTC 167290 - We will need to pass the appropriate instance value
+ // when we implement multinode support
+
+ l_elog = RUNTIME::get_host_data_section(RUNTIME::NODE_TPM_RELATED,
+ l_instance,
+ l_baseAddr,
+ l_dataSizeMax);
+ if(l_elog)
+ {
+ TRACFCOMP( g_trac_runtime, ERR_MRK "populate_TpmInfoByNode: "
+ "get_host_data_section() failed for Node TPM-related Data section");
+ break;
+ }
+
+ // obtain the node target, used later to populate fields
+ TARGETING::Target* mproc = nullptr;
+ l_elog = TARGETING::targetService().queryMasterProcChipTargetHandle(mproc);
+ if(l_elog)
+ {
+ TRACFCOMP( g_trac_runtime, ERR_MRK "populate_TpmInfoByNode: "
+ "could not obtain the master processor from targeting");
+ break;
+ }
+ auto targetType = TARGETING::TYPE_NODE;
+ const TARGETING::Target* l_node = getParent(mproc, targetType);
+ assert(l_node != nullptr, "Bug! getParent on master proc returned null.");
+
+ // this will additively keep track of the next available offset
+ // as we fill the section
+ uint32_t l_currOffset = 0;
+
+ auto const l_hdatTpmData
+ = reinterpret_cast<HDAT::hdatTpmData_t*>(l_baseAddr);
+
+ // make sure we have enough room
+ auto const l_tpmDataCalculatedMax = HDAT::hdatTpmDataCalcMaxSize();
+ assert(l_dataSizeMax >= l_tpmDataCalculatedMax,
+ "Bug! The TPM data hdat section doesn't have enough space");
+
+ // check that hdat structure format and eye catch were filled out
+ assert(l_hdatTpmData->hdatHdr.hdatStructId == HDAT::HDAT_HDIF_STRUCT_ID,
+ "Bug! The TPM data hdat struct format value doesn't match");
+
+ auto l_eyeCatchLen = strlen(HDAT::g_hdatTpmDataEyeCatch);
+ assert(memcmp(l_hdatTpmData->hdatHdr.hdatStructName,
+ HDAT::g_hdatTpmDataEyeCatch,
+ l_eyeCatchLen)==0,
+ "Bug! The TPM data hdat struct name eye catcher doesn't match");
+
+ l_hdatTpmData->hdatHdr.hdatInstance = HDAT::TpmDataInstance;
+ l_hdatTpmData->hdatHdr.hdatVersion = HDAT::TpmDataVersion;
+ l_hdatTpmData->hdatHdr.hdatHdrSize = HDAT::TpmDataHdrSize;
+ l_hdatTpmData->hdatHdr.hdatDataPtrOffset = HDAT::TpmDataPtrOffset;
+ l_hdatTpmData->hdatHdr.hdatDataPtrCnt = HDAT::TpmDataPtrCnt;
+ l_hdatTpmData->hdatHdr.hdatChildStrCnt = HDAT::TpmDataChildStrCnt;
+ l_hdatTpmData->hdatHdr.hdatChildStrOffset = HDAT::TpmDataChildStrOffset;
+
+ TRACFCOMP(g_trac_runtime,"populate_TpmInfoByNode: "
+ "HDAT TPM Data successfully read. Struct Format:0x%X",
+ l_hdatTpmData->hdatHdr.hdatStructId);
+ TRACFBIN(g_trac_runtime, "populate_TpmINfoByNode - EyeCatch: ",
+ l_hdatTpmData->hdatHdr.hdatStructName, l_eyeCatchLen);
+
+ // go past the end of the first struct to get to the next one
+ l_currOffset += sizeof(*l_hdatTpmData);
+
+ // populate first part of pointer pair for secure boot TPM info
+ l_hdatTpmData->hdatSbTpmInfo.hdatOffset = l_currOffset;
+
+ // the second part of the pointer pair for secure boot TPM info will be
+ // populated using the following start offset
+ auto l_sbTpmInfoStart = l_currOffset;
+
+ auto const l_hdatSbTpmInfo = reinterpret_cast<HDAT::hdatSbTpmInfo_t*>
+ (l_baseAddr + l_currOffset);
+
+ std::list<TRUSTEDBOOT::TpmTarget> l_tpmList;
+ #ifdef CONFIG_TPMDD
+ TRUSTEDBOOT::getTPMs(l_tpmList);
+ #endif
+
+ TARGETING::TargetHandleList l_procList;
+
+ getAllChips(l_procList,TARGETING::TYPE_PROC,false);
- // look for class ENC type NODE and class chip TPM to find TPMs
- TARGETING::TargetHandleList l_nodeEncList;
+ auto const l_numTpms = l_tpmList.size();
- getEncResources(l_nodeEncList, TYPE_NODE, UTIL_FILTER_ALL);
+ // 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);
- uint16_t l_maxTpms = 0;
+ // advance current offset to after the Secure Boot TPM info array header
+ l_currOffset += sizeof(*l_hdatSbTpmInfo);
- // loop thru the nodes and check number of TPMs
- for (TargetHandleList::const_iterator
- l_node_iter = l_nodeEncList.begin();
- l_node_iter != l_nodeEncList.end();
- ++l_node_iter)
+ // fill in the values for each Secure Boot TPM Instance Info in the array
+ for (auto itpm : l_tpmList)
{
- // for this Node, get a list of tpms
- TARGETING::TargetHandleList l_tpmChipList;
+ auto l_tpmInstInfo = reinterpret_cast<HDAT::hdatSbTpmInstInfo_t*>
+ (l_baseAddr + l_currOffset);
+ auto l_tpmInfo = itpm.tpmTarget->getAttr<TARGETING::ATTR_TPM_INFO>();
+
+ TARGETING::PredicateAttrVal<TARGETING::ATTR_PHYS_PATH>
+ hasSameI2cMaster(l_tpmInfo.i2cMasterPath);
+
+ auto itr = std::find_if(l_procList.begin(),l_procList.end(),
+ [&hasSameI2cMaster](const TARGETING::TargetHandle_t & t)
+ {
+ return hasSameI2cMaster(t);
+ });
- getChildAffinityTargets ( l_tpmChipList, *l_node_iter,
- TARGETING::CLASS_CHIP, TYPE_TPM, false );
+ assert(itr != l_procList.end(), "Bug! TPM must have a processor.");
+ auto l_proc = *itr;
- size_t l_numTpms = l_tpmChipList.size();
+ l_tpmInstInfo->hdatChipId = l_proc->getAttr<TARGETING::ATTR_CHIP_ID>();
- if (l_numTpms > l_maxTpms)
+ l_tpmInstInfo->hdatDbobId = l_node->getAttr<
+ TARGETING::ATTR_ORDINAL_ID>();
+
+ l_tpmInstInfo->hdatLocality1Addr = l_tpmInfo.devAddrLocality1;
+ l_tpmInstInfo->hdatLocality2Addr = l_tpmInfo.devAddrLocality2;
+ l_tpmInstInfo->hdatLocality3Addr = l_tpmInfo.devAddrLocality3;
+ l_tpmInstInfo->hdatLocality4Addr = l_tpmInfo.devAddrLocality4;
+
+ uint8_t functional = !itpm.failed;
+ // TODO RTC 168781 Replace above with something like below
+ // itpm.tpmTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().functional;
+
+ uint8_t present = itpm.available;
+ // TODO RTC 168781 Replace above with something like below
+ // itpm.tpmTarget->getAttr<TARGETING::ATTR_HWAS_STATE>().present;
+
+ if (functional && present)
{
- l_maxTpms = static_cast<uint16_t>(l_numTpms);
+ // present and functional
+ l_tpmInstInfo->hdatFunctionalStatus = HDAT::TpmPresentAndFunctional;
}
+ else if (present)
+ {
+ // present and not functional
+ l_tpmInstInfo->hdatFunctionalStatus = HDAT::TpmPresentNonFunctional;
+ }
+ else
+ {
+ // not present
+ l_tpmInstInfo->hdatFunctionalStatus = HDAT::TpmNonPresent;
+ }
+
+ // advance the current offset to account for this tpm instance info
+ l_currOffset += sizeof(*l_tpmInstInfo);
+
+ // use the current offset for the beginning of the SRTM event log
+ l_tpmInstInfo->hdatTpmSrtmEventLogOffset = sizeof(*l_tpmInstInfo);
+
+ #ifdef CONFIG_TPMDD
+ // copy the contents of the SRTM event log into HDAT picking the
+ // min of log size and log max (to make sure log size never goes
+ // over the max
+ memcpy(reinterpret_cast<void*>(l_baseAddr + l_currOffset),
+ TpmLogMgr_getLogStartPtr(itpm.logMgr),
+ itpm.logMgr->logSize < TPM_SRTM_EVENT_LOG_MAX ?
+ itpm.logMgr->logSize : TPM_SRTM_EVENT_LOG_MAX);
+
+ // set the size value for the data that was copied
+ l_tpmInstInfo->hdatTpmSrtmEventLogEntrySize = itpm.logMgr->logSize;
+ #else
+ l_tpmInstInfo->hdatTpmSrtmEventLogEntrySize = 0;
+ #endif
+
+ // advance the current offset to account for the SRTM event log
+ l_currOffset += TPM_SRTM_EVENT_LOG_MAX;
+
+ // set the DRTM offset to zero as it is not yet supported
+ l_tpmInstInfo->hdatTpmDrtmEventLogOffset = 0;
+
+ // set the DRTM event log size to zero as it is not yet supported
+ l_tpmInstInfo->hdatTpmDrtmEventLogEntrySize = 0;
+
+ // Note: We don't advance the current offset, because the size of the
+ // DRTM event log is zero
}
- l_sysParmsPtr->hdatTpmDrawer = l_maxTpms;
- TRACFCOMP(g_trac_runtime,"Max TPMs = 0x%04X", l_maxTpms);
+ // populate second part of pointer pair for secure boot TPM info
+ l_hdatTpmData->hdatSbTpmInfo.hdatSize = l_currOffset - l_sbTpmInfoStart;
- // populate hw key hash in hdat
- #ifdef CONFIG_SECUREBOOT
- auto hash = l_sysParmsPtr->hdatHwKeyHashValue;
- SECUREBOOT::getHwKeyHash(hash);
- #else
- memset(l_sysParmsPtr->hdatHwKeyHashValue,0,
- sizeof(l_sysParmsPtr->hdatHwKeyHashValue));
- #endif
+ // the current offset now corresponds to the physical interaction mechanism
+ // info array header
+ auto l_physInter = reinterpret_cast<HDAT::hdatPhysInterMechInfo_t*>
+ (l_baseAddr + l_currOffset);
+
+ // populate the first part of pointer pair from earlier to point here
+ l_hdatTpmData->hdatPhysInter.hdatOffset = l_currOffset;
+
+ // 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
+ l_physInter->hdatOffsetI2cDevInfoPtrs = sizeof(*l_physInter);
+ l_physInter->hdatNumEntries = 0;
+ l_physInter->hdatSizeOfI2cDevInfoPtrs = sizeof(HDAT::hdatI2cDevInfoPtrs_t);
+
+ // 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
+ l_hdatTpmData->hdatPhysInter.hdatSize = l_currOffset - l_physInterStart;
+
+ // set the total structure length to the current offset
+ l_hdatTpmData->hdatHdr.hdatSize = l_currOffset;
+
+ } while (0);
+
+ return (l_elog);
+}
+
+errlHndl_t populate_hbTpmInfo()
+{
+ errlHndl_t l_elog = nullptr;
+
+ do {
+ // TODO RTC 171851 Remove FSP restriction when FSP code provides
+ // Node TPM Related Data
+
+ // Skip populating HDAT TPM Node Related Data on FSP systems
+ if (INITSERVICE::spBaseServicesEnabled())
+ {
+ break;
+ }
+
+ TRACFCOMP(g_trac_runtime, "Running populate_hbTpmInfo");
+
+ TARGETING::Target* sys = nullptr;
+ TARGETING::targetService().getTopLevelTarget( sys );
+ assert(sys != nullptr,
+ "populate_hbTpmInfo: Bug! Could not obtain top level target");
+
+ // This attribute is only set on a multi-node system.
+ // We will use it below to detect a multi-node scenario
+ auto hb_images = sys->getAttr<TARGETING::ATTR_HB_EXISTING_IMAGE>();
+
+ // if single node system
+ if (!hb_images)
+ {
+ l_elog = populate_TpmInfoByNode();
+ if(l_elog != nullptr)
+ {
+ TRACFCOMP( g_trac_runtime, "populate_hbTpmInfo: "
+ "populate_RtDataByNode failed" );
+ }
+ break;
+ }
+
+ // start the 1 in the mask at leftmost position
+ decltype(hb_images) l_mask = 0x1 << (sizeof(hb_images)*BITS_PER_BYTE-1);
+
+ // start at node 0
+ uint32_t l_node = 0;
+
+ // while the one in the mask hasn't shifted out
+ while (l_mask)
+ {
+ // if this node is present
+ if(l_mask & hb_images)
+ {
+ TRACFCOMP( g_trac_runtime, "populate_hbTpmInfo: "
+ "MsgToNode %d for HBRT TPM Info",
+ l_node );
+ // @TODO RTC 167290
+ // Need to send message to the current node
+ // When node receives a message it should call
+ // populate_TpmInfoByNode()
+ }
+ l_mask >>= 1; // shift to the right for the next node
+ l_node++; // go to the next node
+ }
} while(0);
return (l_elog);
-} // end populate_hbRuntiome
+} // end populate_hbTpmInfo
+
errlHndl_t populate_hbRuntimeData( void )
OpenPOWER on IntegriCloud