summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaymes Wilks <mjwilks@us.ibm.com>2018-03-08 16:30:41 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-04-06 12:30:40 -0400
commitbe53610329532c64c3a924db343c0d474079b95d (patch)
treec3f3e95129ad545d5be44e59bb3d42124d8251cb
parentd5ba4627b254190f6b37ee487b3be1951c056e08 (diff)
downloadtalos-hostboot-be53610329532c64c3a924db343c0d474079b95d.tar.gz
talos-hostboot-be53610329532c64c3a924db343c0d474079b95d.zip
Propagate TPM information into HDAT on non-master nodes
Extends HDAT population to add TPM data to all functional nodes - Added message sends from the master to each node - Each node updates # of instances, sizes of structures, etc. - Each node navigates to its appropriate offset in HDAT - HDAT now populates entries for all TPMs in the blueprint - Physical presence interaction mechanism is master-only obtained - TPM SRTM and DRTM logs are no longer interlaced between TPM info - Single node workaround reverted Change-Id: Ic77cbeb7ba3d35a9f02ba68525ed79f27159e9bf RTC:167290 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/55283 Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: ILYA SMIRNOV <ismirno@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/mbox/ipc_msg_types.H1
-rw-r--r--src/include/usr/mbox/mbox_queues.H1
-rw-r--r--src/include/usr/runtime/runtime.H14
-rw-r--r--src/usr/hdat/hdatcommonutil.C11
-rw-r--r--src/usr/hdat/hdattpmdata.C57
-rw-r--r--src/usr/hdat/hdattpmdata.H17
-rw-r--r--src/usr/mbox/ipcSp.C32
-rw-r--r--src/usr/runtime/populate_hbruntime.C162
8 files changed, 224 insertions, 71 deletions
diff --git a/src/include/usr/mbox/ipc_msg_types.H b/src/include/usr/mbox/ipc_msg_types.H
index 7009c01d1..59582fa9f 100644
--- a/src/include/usr/mbox/ipc_msg_types.H
+++ b/src/include/usr/mbox/ipc_msg_types.H
@@ -42,6 +42,7 @@ namespace IPC
IPC_CLOSE_TCES,
IPC_FREQ_ATTR_DATA, // frequency attribute data from master to other drawers
+ IPC_POPULATE_TPM_INFO_BY_NODE,
};
}; // namespace IPC
diff --git a/src/include/usr/mbox/mbox_queues.H b/src/include/usr/mbox/mbox_queues.H
index 5b76c51f8..d431099ef 100644
--- a/src/include/usr/mbox/mbox_queues.H
+++ b/src/include/usr/mbox/mbox_queues.H
@@ -56,6 +56,7 @@ namespace MBOX
HB_SBE_SYSCONFIG_MSGQ = 12, //For SBE System Config response
HB_CLOSE_TCES_MSGQ = 13, // close/disable TCEs
HB_FREQ_ATTR_DATA_MSGQ = 14, // freq attributes data from master to all other drawers
+ HB_POP_TPM_INFO_MSGQ = 15, // response to populate TPM info by node
// Add HB mbox msg queue ids (services) before this line
HB_LAST_VALID_MSGQ, // end of valid HB mbox msgQ ids
diff --git a/src/include/usr/runtime/runtime.H b/src/include/usr/runtime/runtime.H
index fdb8e9a49..4613b1d73 100644
--- a/src/include/usr/runtime/runtime.H
+++ b/src/include/usr/runtime/runtime.H
@@ -121,11 +121,21 @@ errlHndl_t populate_hbSecurebootData( void );
errlHndl_t populate_hbTpmInfo( void );
/**
- * @brief Fills in Tpm Info in HDAT for current node
+ * @brief Fills in Tpm Info in HDAT for node passed in to the specified HDAT
+ * instance
+ *
+ * @param[in] i_instance - the instance number to use to populate the current
+ * node's data into HDAT, as directed by the master node.
+ * This function is typically called upon receiving a
+ * message of type IPC_POPULATE_TPM_INFO_BY_NODE, which
+ * provides the instance to use as an MBOX parameter. Each
+ * node must have a unique instance number, but beyond that
+ * there is no guaranteed direct correlation between nodes
+ * and instances at all.
*
* @return errlHndl_t nullptr on success else pointer to error log
*/
-errlHndl_t populate_TpmInfoByNode();
+errlHndl_t populate_TpmInfoByNode(const uint64_t i_instance);
/**
* @brief Timer function for safe error handling in sendSBESystemConfig
diff --git a/src/usr/hdat/hdatcommonutil.C b/src/usr/hdat/hdatcommonutil.C
index 1bb9d43ac..ed92e4da8 100644
--- a/src/usr/hdat/hdatcommonutil.C
+++ b/src/usr/hdat/hdatcommonutil.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -72,17 +72,10 @@ uint16_t hdatCalcMaxTpmsPerNode()
return l_maxTpms;
}
-uint32_t hdatTpmDataCalcMaxSize()
+uint32_t hdatTpmDataCalcInstanceSize()
{
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);
diff --git a/src/usr/hdat/hdattpmdata.C b/src/usr/hdat/hdattpmdata.C
index 9ef885227..9337c7b9e 100644
--- a/src/usr/hdat/hdattpmdata.C
+++ b/src/usr/hdat/hdattpmdata.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -55,7 +55,23 @@ HdatTpmData::HdatTpmData(errlHndl_t &o_errlHndl,
const uint64_t l_baseAddr = static_cast<uint64_t>(i_msAddr.hi) << 32
| i_msAddr.lo;
- const auto maxLogicalSize = hdatTpmDataCalcMaxSize();
+
+ // get the top level target
+ TARGETING::Target* sys = nullptr;
+ TARGETING::targetService().getTopLevelTarget( sys );
+ assert(sys != nullptr,
+ "HdatTpmData::HdatTpmData: Bug! Could not obtain top level target");
+
+ // get the node bit string to see what our node layout looks like
+ auto l_nodeBits = sys->getAttr<TARGETING::ATTR_HB_EXISTING_IMAGE>();
+
+ // count the bits to get the functional/present nodes
+ iv_numNodes = __builtin_popcount(l_nodeBits);
+
+ // Must be at least one. Add one in the zero case.
+ iv_numNodes += !iv_numNodes;
+
+ const auto maxLogicalSize = hdatTpmDataCalcInstanceSize() * iv_numNodes;
const uint64_t l_size = ALIGN_PAGE(maxLogicalSize) + PAGESIZE;
const uint64_t l_alignedAddr = ALIGN_PAGE_DOWN(l_baseAddr);
@@ -69,9 +85,6 @@ HdatTpmData::HdatTpmData(errlHndl_t &o_errlHndl,
iv_hdatTpmData = reinterpret_cast<hdatTpmData_t *>(l_virtAddr +
l_offset);
- // TODO RTC 167290 - This memset needs to be revisited for multinode
- // support. We may need to do this memset once per node or use some
- // other approach to initialization.
memset(iv_hdatTpmData, 0x0, maxLogicalSize);
HDAT_DBG("Ctr iv_hdatTpmData addr 0x%.16llX virtual addr 0x%.16llX",
@@ -147,25 +160,35 @@ errlHndl_t HdatTpmData::hdatLoadTpmData(uint32_t &o_size, uint32_t &o_count)
o_count = 0;
- o_size = hdatTpmDataCalcMaxSize();
+ // calculate the size of each instance
+ o_size = hdatTpmDataCalcInstanceSize();
- // Note: HdatTpmData constructor already cleared the memory to the tune of
- // o_size (hdatTpmDataCalcMaxSize()) bytes
+ auto l_hdatTpmData = iv_hdatTpmData;
- // We add the first two fields for a reference to aid in debugging,
- // but the rest will be populated in FSP/OpenPower common code. Any
- // work here would just be duplicated later during the runtime istep.
+ for (uint32_t i_instance = 0; i_instance < iv_numNodes; i_instance++)
+ {
+ // Note: HdatTpmData constructor already cleared the memory to the tune
+ // of o_size (hdatTpmDataCalcInstanceSize()) bytes
+
+ // We add the first two fields for a reference to aid in debugging,
+ // but the rest will be populated in FSP/OpenPower common code. Any
+ // work here would just be duplicated later during the runtime istep.
- // add the format magic number
- iv_hdatTpmData->hdatHdr.hdatStructId = HDAT::HDAT_HDIF_STRUCT_ID;
+ // add the format magic number
+ iv_hdatTpmData->hdatHdr.hdatStructId = HDAT::HDAT_HDIF_STRUCT_ID;
- // add the eyecatcher
- memcpy(iv_hdatTpmData->hdatHdr.hdatStructName,
+ // add the eyecatcher
+ memcpy(iv_hdatTpmData->hdatHdr.hdatStructName,
g_hdatTpmDataEyeCatch,
strlen(g_hdatTpmDataEyeCatch));
- // account for this one instance of Node TPM Related Data
- ++o_count;
+ // Account for this one instance of Node TPM Related Data.
+ ++o_count;
+
+ // Move to the next instance
+ l_hdatTpmData = reinterpret_cast<hdatTpmData_t *>(
+ reinterpret_cast<uint8_t*>(l_hdatTpmData) + o_size);
+ }
return l_errl;
}
diff --git a/src/usr/hdat/hdattpmdata.H b/src/usr/hdat/hdattpmdata.H
index b1ac99676..f04403e1e 100644
--- a/src/usr/hdat/hdattpmdata.H
+++ b/src/usr/hdat/hdattpmdata.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017 */
+/* Contributors Listed Below - COPYRIGHT 2017,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -239,10 +239,11 @@ class HdatTpmData
private:
- HDAT::hdatMsAddr_t iv_msAddr;
+ HDAT::hdatMsAddr_t iv_msAddr;
hdatTpmData_t *iv_hdatTpmData;
+ uint32_t iv_numNodes;
}; // end of HdatTpmData class
@@ -258,15 +259,21 @@ class HdatTpmData
uint16_t hdatCalcMaxTpmsPerNode();
/**
- * @brief Calculate the maximum size of the HDAT TPM data section
+ * @brief Calculate the maximum size of an instance of HDAT TPM data. There
+ * will be one instance per functional node in the system. It is assumed
+ * that this function will be used determine how much space one node's
+ * worth of HDAT TPM data will occupy worst case. It is assumed that each
+ * instance will have the same max size and that the instances will be
+ * placed one after another in memory (not page aligned) with enough
+ * space to accommodate the maximum possible size of each node.
*
* @pre None
*
* @post None
*
- * @retval uint32_t Maximum size of the HDAT TPM data section
+ * @retval uint32_t Maximum size of one instance of HDAT TPM data.
*/
-uint32_t hdatTpmDataCalcMaxSize();
+uint32_t hdatTpmDataCalcInstanceSize();
}
#endif // HDATTPMDATA_H
diff --git a/src/usr/mbox/ipcSp.C b/src/usr/mbox/ipcSp.C
index f04dc81c8..45d85a442 100644
--- a/src/usr/mbox/ipcSp.C
+++ b/src/usr/mbox/ipcSp.C
@@ -101,6 +101,35 @@ void IpcSp::msgHandler()
switch(msg->type)
{
+ case IPC_POPULATE_TPM_INFO_BY_NODE:
+ {
+ // msg->extra_data contains PAYLOAD Base
+ RUNTIME::setPayloadBaseAddress(
+ reinterpret_cast<uint64_t>(msg->extra_data));
+
+ // msg->data[0] contains the HDAT TPM info instance to populate
+ err = RUNTIME::populate_TpmInfoByNode(msg->data[0]);
+
+ if (err)
+ {
+ TRACFCOMP( g_trac_ipc, ERR_MRK"IpcSp::msgHandler: populate_TpmInfoByNode errored - must shutdown now!!!");
+ const auto l_errPlid = err->plid();
+ errlCommit(err, IPC_COMP_ID);
+ INITSERVICE::doShutdown(l_errPlid, true);
+ }
+
+ // give a response back to the sender
+ err = MBOX::send(MBOX::HB_POP_TPM_INFO_MSGQ, msg, msg->data[1]);
+ if (err)
+ {
+ const auto l_errPlid = err->plid();
+ errlCommit(err,IPC_COMP_ID);
+ msg_free(msg);
+ INITSERVICE::doShutdown(l_errPlid, true);
+ }
+ break;
+ }
+
case IPC_POPULATE_ATTRIBUTES:
// make sure runtime module is loaded
if ( !VFS::module_is_loaded( "libruntime.so" ) )
@@ -266,8 +295,7 @@ void IpcSp::msgHandler()
INITSERVICE::doShutdown(l_errPlid, true);
}
break;
- }
-
+ }
case IPC_FREQ_ATTR_DATA:
{
TRACFCOMP( g_trac_ipc,
diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C
index 529f1b3aa..1f59a8d43 100644
--- a/src/usr/runtime/populate_hbruntime.C
+++ b/src/usr/runtime/populate_hbruntime.C
@@ -39,6 +39,7 @@
#include <targeting/common/utilFilter.H>
#include <targeting/common/entitypath.H>
#include <targeting/common/commontargeting.H>
+#include <targeting/targplatutil.H>
#include <runtime/runtime_reasoncodes.H>
#include <runtime/runtime.H>
#include "hdatstructs.H"
@@ -1459,7 +1460,7 @@ errlHndl_t populate_hbSecurebootData ( void )
l_sysParmsPtr->hdatTpmConfBits = tpmRequired? TPM_REQUIRED_BIT: 0;
// get max # of TPMs per drawer and populate hdat with it
- auto l_maxTpms = HDAT::hdatTpmDataCalcMaxSize();
+ auto l_maxTpms = HDAT::hdatCalcMaxTpmsPerNode();
l_sysParmsPtr->hdatTpmDrawer = l_maxTpms;
TRACFCOMP(g_trac_runtime,"Max TPMs = 0x%04X", l_maxTpms);
@@ -1483,7 +1484,7 @@ errlHndl_t populate_hbSecurebootData ( void )
return (l_elog);
} // end populate_hbRuntime
-errlHndl_t populate_TpmInfoByNode()
+errlHndl_t populate_TpmInfoByNode(const uint64_t i_instance)
{
errlHndl_t l_elog = nullptr;
@@ -1491,13 +1492,12 @@ errlHndl_t populate_TpmInfoByNode()
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
+ TRACFCOMP( g_trac_runtime, ERR_MRK "populate_TpmInfoByNode: "
+ "calling get_host_data_section() to populate instance %d",i_instance);
l_elog = RUNTIME::get_host_data_section(RUNTIME::NODE_TPM_RELATED,
- l_instance,
+ i_instance,
l_baseAddr,
l_dataSizeMax);
if(l_elog)
@@ -1524,15 +1524,15 @@ errlHndl_t populate_TpmInfoByNode()
// as we fill the section
uint32_t l_currOffset = 0;
- ////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////
// Section Node Secure and Trusted boot Related Data
- ////////////////////////////////////////////////////////////////////////////
+ ////////////////////////////////////////////////////////////////////////
auto const l_hdatTpmData
= reinterpret_cast<HDAT::hdatTpmData_t*>(l_baseAddr);
// make sure we have enough room
- auto const l_tpmDataCalculatedMax = HDAT::hdatTpmDataCalcMaxSize();
+ auto const l_tpmDataCalculatedMax = HDAT::hdatTpmDataCalcInstanceSize();
if(l_dataSizeMax < l_tpmDataCalculatedMax)
{
@@ -1559,6 +1559,13 @@ errlHndl_t populate_TpmInfoByNode()
break;
}
+ // TODO RTC 190522 - Remove the following two lines of code once FSP
+ // adds missing eyecatch and magic number to non-master nodes
+ l_hdatTpmData->hdatHdr.hdatStructId = HDAT::HDAT_HDIF_STRUCT_ID;
+ memcpy(l_hdatTpmData->hdatHdr.hdatStructName,
+ HDAT::g_hdatTpmDataEyeCatch,
+ strlen(HDAT::g_hdatTpmDataEyeCatch));
+
// check that hdat structure format and eye catch were filled out
if(l_hdatTpmData->hdatHdr.hdatStructId != HDAT::HDAT_HDIF_STRUCT_ID)
{
@@ -1657,7 +1664,7 @@ errlHndl_t populate_TpmInfoByNode()
(l_baseAddr + l_currOffset);
TARGETING::TargetHandleList tpmList;
- TRUSTEDBOOT::getTPMs(tpmList);
+ TRUSTEDBOOT::getTPMs(tpmList, TRUSTEDBOOT::TPM_FILTER::ALL_IN_BLUEPRINT);
TARGETING::TargetHandleList l_procList;
@@ -1678,11 +1685,22 @@ errlHndl_t populate_TpmInfoByNode()
// Section Secure Boot and TPM Instance Info
////////////////////////////////////////////////////////////////////////////
+ // save of a list of TPM / Instance Info pairs to fix up in a second pass
+ std::vector<std::pair<TARGETING::Target*,
+ HDAT::hdatSbTpmInstInfo_t*> > fixList;
+
+ // Calculate the SRTM log offset
+ auto l_srtmLogOffset = 0;
+
// fill in the values for each Secure Boot TPM Instance Info in the array
for (auto pTpm : tpmList)
{
auto l_tpmInstInfo = reinterpret_cast<HDAT::hdatSbTpmInstInfo_t*>
(l_baseAddr + l_currOffset);
+
+ // save for second pass SRTM/DRTM log offset fixups
+ fixList.push_back(std::make_pair(pTpm, l_tpmInstInfo));
+
auto l_tpmInfo = pTpm->getAttr<TARGETING::ATTR_TPM_INFO>();
TARGETING::PredicateAttrVal<TARGETING::ATTR_PHYS_PATH>
@@ -1753,12 +1771,31 @@ errlHndl_t populate_TpmInfoByNode()
// advance the current offset to account for this tpm instance info
l_currOffset += sizeof(*l_tpmInstInfo);
+ // advance the SRTM log offset to account for this tpm instance info
+ l_srtmLogOffset += sizeof(*l_tpmInstInfo);
+
+ }
+
+ for (auto tpmInstPair : fixList)
+ {
+ const auto pTpm = tpmInstPair.first;
+ const auto l_tpmInstInfo = tpmInstPair.second;
+
////////////////////////////////////////////////////////////////////////
// Section Secure Boot TPM Event Log
////////////////////////////////////////////////////////////////////////
- // use the current offset for the beginning of the SRTM event log
- l_tpmInstInfo->hdatTpmSrtmEventLogOffset = sizeof(*l_tpmInstInfo);
+ // The SRTM offset we had been tallying in the previous loop happens to
+ // be the offset from the first TPM Instance Info to the first SRTM log
+ l_tpmInstInfo->hdatTpmSrtmEventLogOffset = l_srtmLogOffset;
+
+ // As we go through the list we remove a TPM instance info length and
+ // add an SRTM log length to the previous offset. The reason is b/c a
+ // TPM Instance info's log offset is counted from the start of the
+ // that instance info. We subtract an instance info length from the
+ // previous offset to account for that difference. We also add a log max
+ // to account for the previous instance info's log.
+ l_srtmLogOffset += (TPM_SRTM_EVENT_LOG_MAX - sizeof(*l_tpmInstInfo));
// 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
@@ -1923,10 +1960,7 @@ errlHndl_t populate_TpmInfoByNode()
// obtain a list of i2c targets
std::vector<I2C::DeviceInfo_t> l_i2cTargetList;
- for (auto pProc : l_procList)
- {
- I2C::getDeviceInfo(pProc, l_i2cTargetList);
- }
+ I2C::getDeviceInfo(mproc, l_i2cTargetList);
auto i2cDevItr = l_i2cTargetList.begin();
while(i2cDevItr != l_i2cTargetList.end())
{
@@ -2257,16 +2291,16 @@ errlHndl_t populate_TpmInfoByNode()
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),
+ FOUR_UINT8_TO_UINT32(i2cDev.engine,
+ i2cDev.masterPort,
+ i2cDev.deviceType,
+ i2cDev.addr),
TWO_UINT16_TO_UINT32(
- TWO_UINT8_TO_UINT16(i2cDevItr->slavePort,
- i2cDevItr->devicePurpose),
- i2cDevItr->busFreqKhz)
+ TWO_UINT8_TO_UINT16(i2cDev.slavePort,
+ i2cDev.devicePurpose),
+ i2cDev.busFreqKhz)
),
- TARGETING::get_huid(i2cDevItr->masterChip),
+ TARGETING::get_huid(i2cDev.masterChip),
true);
err->collectTrace(RUNTIME_COMP_NAME);
ERRORLOG::errlCommit(err, RUNTIME_COMP_ID);
@@ -2374,15 +2408,11 @@ errlHndl_t populate_hbTpmInfo()
// We will use it below to detect a multi-node scenario
auto hb_images = sys->getAttr<TARGETING::ATTR_HB_EXISTING_IMAGE>();
- // @TODO RTC: 167290
- // Until TPM HDAT processing is multi-node aware, pretend the system is
- // a single node system to get the HDAT partially populated
- hb_images = 0;
-
// if single node system
if (!hb_images)
{
- l_elog = populate_TpmInfoByNode();
+ TRACDCOMP( g_trac_runtime, "populate_hbTpmInfo: Single node system");
+ l_elog = populate_TpmInfoByNode(0); // 0 for single node
if(l_elog != nullptr)
{
TRACFCOMP( g_trac_runtime, "populate_hbTpmInfo: "
@@ -2390,13 +2420,40 @@ errlHndl_t populate_hbTpmInfo()
}
break;
}
+ // multinode system / grab payload base to give to the nodes
+ uint64_t payloadBase = sys->getAttr<TARGETING::ATTR_PAYLOAD_BASE>();
+
+ // get the node id for the master chip
+ const auto l_masterNode = TARGETING::UTIL::getCurrentNodePhysId();
+
// 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
+ TRACDCOMP( g_trac_runtime, "populate_hbTpmInfo: l_mask 0x%.16llX hb_images 0x%.16llX",l_mask,hb_images);
+
+ // start at node 0, iterates thru all nodes in blueprint
uint32_t l_node = 0;
+ // As the master node we assign instances to each node for them to
+ // write their HDAT TPM instance info to.
+ // start node instance at 0, counts only present/functional nodes
+ uint32_t l_instance = 0;
+
+ // create a message queue for receipt of responses from nodes
+ msg_q_t msgQ = msg_q_create();
+ l_elog = MBOX::msgq_register(MBOX::HB_POP_TPM_INFO_MSGQ, msgQ);
+
+ if(l_elog)
+ {
+ TRACFCOMP( g_trac_runtime, "populate_hbTpmInfo: MBOX::msgq_register failed!" );
+ break;
+ }
+
+ // keep track of the number of messages we send so we know how
+ // many responses to expect
+ int msg_count = 0;
+
// while the one in the mask hasn't shifted out
while (l_mask)
{
@@ -2404,17 +2461,50 @@ errlHndl_t populate_hbTpmInfo()
if(l_mask & hb_images)
{
TRACFCOMP( g_trac_runtime, "populate_hbTpmInfo: "
- "MsgToNode %d for HBRT TPM Info",
+ "MsgToNode (instance) %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()
+
+ // Send message to the current node
+ msg_t* msg = msg_allocate();
+ msg->type = IPC::IPC_POPULATE_TPM_INFO_BY_NODE;
+ msg->data[0] = l_instance; // instance number
+ msg->data[1] = l_masterNode; // respond to this node
+ msg->extra_data = reinterpret_cast<uint64_t*>(payloadBase);
+
+ l_elog = MBOX::send(MBOX::HB_IPC_MSGQ, msg, l_node);
+
+ if (l_elog)
+ {
+ TRACFCOMP( g_trac_runtime, "MBOX::send to node %d from node %d failed",
+ l_node, l_masterNode);
+ msg_free(msg);
+ break;
+ }
+ msg_count++;
+ l_instance++;
}
l_mask >>= 1; // shift to the right for the next node
l_node++; // go to the next node
}
+ if (l_elog == nullptr)
+ {
+ msg_t* l_response = nullptr;
+ // TODO RTC:189356 - need timeout here
+ while (msg_count)
+ {
+ l_response = msg_wait(msgQ);
+ TRACFCOMP(g_trac_runtime,
+ "populate_hbTpmInfo: drawer %d completed",
+ l_response->data[0]);
+ msg_free(l_response);
+ msg_count--;
+ }
+ }
+
+ MBOX::msgq_unregister(MBOX::HB_POP_TPM_INFO_MSGQ);
+ msg_q_destroy(msgQ);
+
} while(0);
return (l_elog);
OpenPOWER on IntegriCloud