diff options
author | Jaymes Wilks <mjwilks@us.ibm.com> | 2018-03-08 16:30:41 -0600 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2018-04-06 12:30:40 -0400 |
commit | be53610329532c64c3a924db343c0d474079b95d (patch) | |
tree | c3f3e95129ad545d5be44e59bb3d42124d8251cb | |
parent | d5ba4627b254190f6b37ee487b3be1951c056e08 (diff) | |
download | talos-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.H | 1 | ||||
-rw-r--r-- | src/include/usr/mbox/mbox_queues.H | 1 | ||||
-rw-r--r-- | src/include/usr/runtime/runtime.H | 14 | ||||
-rw-r--r-- | src/usr/hdat/hdatcommonutil.C | 11 | ||||
-rw-r--r-- | src/usr/hdat/hdattpmdata.C | 57 | ||||
-rw-r--r-- | src/usr/hdat/hdattpmdata.H | 17 | ||||
-rw-r--r-- | src/usr/mbox/ipcSp.C | 32 | ||||
-rw-r--r-- | src/usr/runtime/populate_hbruntime.C | 162 |
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); |