summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Crowell <dcrowell@us.ibm.com>2018-06-08 16:03:18 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-06-10 21:28:53 -0400
commit4189613d36cc98d9b52ae72c1bb3727cdb16e34b (patch)
tree7dafbc7a76492288aa2c297d9a2a2f0016bc737c
parentf290f5d4a9efbf70ae99ec0cdff5b676d63431f1 (diff)
downloadtalos-hostboot-4189613d36cc98d9b52ae72c1bb3727cdb16e34b.tar.gz
talos-hostboot-4189613d36cc98d9b52ae72c1bb3727cdb16e34b.zip
Fix for multinode HBRT use of VPD
Node0 VPD memory is being used for all nodes because we were using a Singleton pointer across modules. This is a problem because static memory is specific to each module which meant we were getting a new copy of the AttrRP object instead of the real version that had real data in it. The change here is to create a new static interface that external modules can call to retrieve the node associated with a given Target. There is also a change to cache this data into a map as I noticed hundreds of accesses during the one function call I was using to test with. Change-Id: I148bf1f405d076276193d526d8a4b1f0649b2c1c CQ: SW431462 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/60276 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> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
-rw-r--r--src/include/usr/targeting/attrrp.H15
-rw-r--r--src/usr/targeting/runtime/attrrp_rt.C31
-rw-r--r--src/usr/util/runtime/rt_cmds.C8
-rw-r--r--src/usr/util/runtime/util_rt.C2
-rw-r--r--src/usr/vpd/runtime/rt_vpd.C8
5 files changed, 57 insertions, 7 deletions
diff --git a/src/include/usr/targeting/attrrp.H b/src/include/usr/targeting/attrrp.H
index bc9425007..679672160 100644
--- a/src/include/usr/targeting/attrrp.H
+++ b/src/include/usr/targeting/attrrp.H
@@ -184,7 +184,7 @@ class AttrRP
void* getBaseAddress(const NODE_ID i_nodeId);
/**
- * @brief Returns Node Id of the Target handle passed
+ * @brief Returns Node Id of the Target handle passed (internal)
*
* @param[in] i_pTarget
* Non-NULL Target handle for which node ID is required.
@@ -197,6 +197,19 @@ class AttrRP
void getNodeId(const Target* i_pTarget,
NODE_ID& o_nodeId) const;
+#ifdef __HOSTBOOT_RUNTIME
+ /**
+ * @brief Returns Node Id of the Target handle passed (external)
+ *
+ * @param[in] i_pTarget
+ * Non-NULL Target handle for which node ID is required.
+ * @return NODE_ID
+ * Node ID of the Target Handle requested. If Target not found
+ * the invalid node will be return in here.
+ */
+ static NODE_ID getNodeId(const Target* i_pTarget);
+#endif
+
/**
* @brief Translates given address, according to the resource
* provider's translation algorithm
diff --git a/src/usr/targeting/runtime/attrrp_rt.C b/src/usr/targeting/runtime/attrrp_rt.C
index 55be8eaf9..8a7b7824b 100644
--- a/src/usr/targeting/runtime/attrrp_rt.C
+++ b/src/usr/targeting/runtime/attrrp_rt.C
@@ -31,6 +31,7 @@
#include <targeting/targplatreasoncodes.H>
#include <util/runtime/util_rt.H>
#include <sys/internode.h>
+#include <map>
#include "../attrrp_common.C"
@@ -436,6 +437,20 @@ namespace TARGETING
#undef TARG_FN
}
+ NODE_ID AttrRP::getNodeId(const Target* i_pTarget)
+ {
+ #define TARG_FN "getNodeId"
+
+ NODE_ID l_nodeId = 0;
+
+ // Call the class function with my module-local singleton
+ TARGETING::AttrRP *l_attrRP = &TARG_GET_SINGLETON(TARGETING::theAttrRP);
+ l_attrRP->getNodeId(i_pTarget, l_nodeId);
+
+ return l_nodeId;
+ #undef TARG_FN
+ }
+
void AttrRP::getNodeId(const Target* i_pTarget, NODE_ID& o_nodeId) const
{
#define TARG_FN "getNodeId"
@@ -445,6 +460,15 @@ namespace TARGETING
// Initialize with invalid
o_nodeId = INVALID_NODE_ID;
+ // Check if we have a cached version first
+ static std::map<const Target*,NODE_ID> s_targToNodeMap;
+ auto l_nodeItr = s_targToNodeMap.find(i_pTarget);
+ if( l_nodeItr != s_targToNodeMap.end() )
+ {
+ o_nodeId = l_nodeItr->second;
+ return;
+ }
+
//find the node to which this target belongs
for(uint8_t i=0; i<INVALID_NODE_ID; ++i)
{
@@ -453,6 +477,11 @@ namespace TARGETING
if( iv_nodeContainer[i].pSections[j].type ==
SECTION_TYPE_PNOR_RO)
{
+ TARG_DBG("%d/%d> pTargetMap=%p, end=%p", i, j, iv_nodeContainer[i].pTargetMap, (
+ reinterpret_cast<uint8_t*>(
+ iv_nodeContainer[i].pTargetMap) +
+ iv_nodeContainer[i].pSections[j].size) );
+
// This expects the pTarget to be always in range and !NULL.
// If any invalid target is passed (which is still within the
// RO Section scope) then behaviour is undefined.
@@ -464,6 +493,8 @@ namespace TARGETING
{
l_found = true;
o_nodeId = i;
+ s_targToNodeMap[i_pTarget] = i;
+ TARG_DBG("Target %p is on node %d @ %p", i_pTarget, o_nodeId, &o_nodeId );
break;
}
}
diff --git a/src/usr/util/runtime/rt_cmds.C b/src/usr/util/runtime/rt_cmds.C
index ce7df1daf..4ce0f9a11 100644
--- a/src/usr/util/runtime/rt_cmds.C
+++ b/src/usr/util/runtime/rt_cmds.C
@@ -471,8 +471,14 @@ void cmd_readwritevpd(char*& o_output, DeviceFW::OperationType i_rtCmd,
size_t i(0);
for (; i < l_dataVec.size() -1; ++i )
{
+ if( i % 4 == 0 )
+ {
+ sprintf(&o_output[l_len],"\n");
+ l_len = strlen(o_output);
+ }
+
l_tempValue = l_dataVec[i];
- sprintf(&o_output[l_len],"\n%.8X ",(uint32_t)(l_tempValue>>32));
+ sprintf(&o_output[l_len],"%.8X ",(uint32_t)(l_tempValue>>32));
l_len = strlen(o_output);
sprintf(&o_output[l_len],"%.8X",(uint32_t)(l_tempValue));
diff --git a/src/usr/util/runtime/util_rt.C b/src/usr/util/runtime/util_rt.C
index 744462930..447e42656 100644
--- a/src/usr/util/runtime/util_rt.C
+++ b/src/usr/util/runtime/util_rt.C
@@ -89,7 +89,7 @@ uint64_t hb_get_rt_rsvd_mem(Util::hbrt_mem_label_t i_label,
}
TRACFCOMP(TARGETING::g_trac_targeting,
- EXIT_MRK"hb_get_rt_rsvd_mem(0x%X, %d, %ld) -> 0x%.16llX",
+ EXIT_MRK"hb_get_rt_rsvd_mem(0x%llX, %d, %ld) -> 0x%.16llX",
i_label, i_instance, o_size,l_label_data_addr);
return l_label_data_addr;
diff --git a/src/usr/vpd/runtime/rt_vpd.C b/src/usr/vpd/runtime/rt_vpd.C
index 4ced81370..7e4a21ebe 100644
--- a/src/usr/vpd/runtime/rt_vpd.C
+++ b/src/usr/vpd/runtime/rt_vpd.C
@@ -132,6 +132,8 @@ errlHndl_t getPnorAddr( pnorInformation & i_pnorInfo,
// Get the reserved_mem_addr only once
else if( g_reserved_mem_addr[i_instance] == 0 )
{
+ TRACDCOMP( g_trac_vpd, "Grabbing rsvd mem for instance %d", i_instance );
+
uint64_t l_vpdSize;
g_reserved_mem_addr[i_instance] =
hb_get_rt_rsvd_mem(Util::HBRT_MEM_LABEL_VPD,
@@ -232,7 +234,7 @@ errlHndl_t readPNOR ( uint64_t i_byteAddr,
mutex_t * i_mutex )
{
errlHndl_t err = NULL;
- TARGETING::NODE_ID l_nodeId = TARGETING::NODE0;
+ TARGETING::NODE_ID l_nodeId = 0xFF;
int64_t vpdLocation = 0;
uint64_t addr = 0x0;
const char * readAddr = NULL;
@@ -240,10 +242,8 @@ errlHndl_t readPNOR ( uint64_t i_byteAddr,
TRACSSCOMP( g_trac_vpd,
ENTER_MRK"RT fake readPNOR()" );
- // Get AttrRP pointer
- TARGETING::AttrRP *l_attrRP = &TARG_GET_SINGLETON(TARGETING::theAttrRP);
// Get the node ID associated with the input target
- l_attrRP->getNodeId(i_target, l_nodeId);
+ l_nodeId = TARGETING::AttrRP::getNodeId(i_target);
do
{
OpenPOWER on IntegriCloud