summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorMarty Gloff <mgloff@us.ibm.com>2018-05-29 11:34:33 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-06-21 14:38:36 -0400
commitccf2f3445e15a93f06528c5f077c34e5abce548b (patch)
treeffe6319edd19764336ec110424ed4f6b869b15de /src/usr
parentfd49726ffcf05ade7e6c71ed1666b2075a999f95 (diff)
downloadtalos-hostboot-ccf2f3445e15a93f06528c5f077c34e5abce548b.tar.gz
talos-hostboot-ccf2f3445e15a93f06528c5f077c34e5abce548b.zip
HBRT attrrp depends on node zero being present
Rework the code in the runtime startup() function to not depend on using Node 0 reserved memory data to discover what nodes are present and to create "invalid node" structs in iv_nodeContainer for nodes that are not present. Change-Id: I61f0dbdc94c6dd1a31a3e3453b149e7322311a6e RTC: 192967 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/59497 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: Christian R. Geddes <crgeddes@us.ibm.com> Reviewed-by: Prachi Gupta <pragupta@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr')
-rwxr-xr-xsrc/usr/targeting/attrrp_common.C3
-rw-r--r--src/usr/targeting/common/targetservice.C5
-rw-r--r--src/usr/targeting/runtime/attrrp_rt.C270
-rw-r--r--src/usr/targeting/runtime/rt_targeting.C3
4 files changed, 168 insertions, 113 deletions
diff --git a/src/usr/targeting/attrrp_common.C b/src/usr/targeting/attrrp_common.C
index a78017e29..1adee2edd 100755
--- a/src/usr/targeting/attrrp_common.C
+++ b/src/usr/targeting/attrrp_common.C
@@ -32,7 +32,8 @@ namespace TARGETING
#define TARG_CLASS "AttrRP"
#ifdef __HOSTBOOT_RUNTIME
- // It is defined here to limit the scope within this file
+ // It is defined here to limit the scope within this file,
+ // this file is also included in attrrp_rt.C
#define INVALID_NODE_ID iv_nodeContainer.size()
#endif
diff --git a/src/usr/targeting/common/targetservice.C b/src/usr/targeting/common/targetservice.C
index a0e1298a6..9123e2d6c 100644
--- a/src/usr/targeting/common/targetservice.C
+++ b/src/usr/targeting/common/targetservice.C
@@ -176,10 +176,9 @@ void TargetService::init(const size_t i_maxNodes)
if(NULL == l_pHdr)
{
- TARG_INF("Targeting header is NULL for Node Id [%d]",
+ TARG_INF("Targeting header is NULL for Node Id [%d].. skipping",
l_nodeCnt);
- TARG_ASSERT(0, TARG_ERR_LOC
- "Targeting Header for Node [%d] cannot be NULL", l_nodeCnt);
+ continue;
}
else
{
diff --git a/src/usr/targeting/runtime/attrrp_rt.C b/src/usr/targeting/runtime/attrrp_rt.C
index 8a7b7824b..5227f3f83 100644
--- a/src/usr/targeting/runtime/attrrp_rt.C
+++ b/src/usr/targeting/runtime/attrrp_rt.C
@@ -39,48 +39,22 @@ using namespace ERRORLOG;
namespace TARGETING
{
- void AttrRP::startup(errlHndl_t& io_taskRetErrl, bool isMpipl)
+ errlHndl_t AttrRP::checkHbExistingImage(TargetingHeader* i_header,
+ uint8_t i_instance,
+ NODE_ID &io_maxNodeId)
{
- TRACFCOMP(g_trac_targeting, "AttrRP::startup");
+ TRACFCOMP(g_trac_targeting, "AttrRP::checkHbExistingImage");
errlHndl_t l_errl = nullptr;
- uint8_t l_index = 0;
- uint32_t l_instance[MAX_NODES_PER_SYS];
- l_instance[l_index] = NODE0; // First instance is always NODE 0
- // Initialize rest of the instances to be invalid nodes
- for(l_index = 1; l_index < MAX_NODES_PER_SYS; l_index++)
- {
- l_instance[l_index] = INVALID_NODE;
- }
-
- // Handle first instance
- l_index = 0;
- uint64_t attr_size = 0;
- TargetingHeader* l_header =
- reinterpret_cast<TargetingHeader*>(
- hb_get_rt_rsvd_mem(Util::HBRT_MEM_LABEL_ATTR,
- l_instance[l_index], attr_size));
-
- // Create local copy of node struct
- NodeInfo l_nodeCont;
-
- // Initialize local copy of node struct
- l_errl = nodeInfoInit(l_nodeCont,
- l_header,
- l_instance[l_index]);
-
- // Push back node struct into the node container
- TRACFCOMP(g_trac_targeting,
- "Push node struct for Node %d",
- l_instance[l_index]);
- iv_nodeContainer.push_back(l_nodeCont);
+ // Validity of the node instance
+ bool l_validNode = false;
// Get pointer to number of targets
const AbstractPointer<uint32_t>* l_pNumTargetsPtr =
static_cast<const AbstractPointer<uint32_t>*>(
reinterpret_cast<void*>(
- reinterpret_cast<char*>(l_header) +
- l_header->headerSize));
+ reinterpret_cast<char*>(i_header) +
+ i_header->headerSize));
uint32_t* l_pNumTargets = TARG_TO_PLAT_PTR(*l_pNumTargetsPtr);
// Only translate addresses on platforms where addresses are 4 bytes
@@ -90,14 +64,14 @@ namespace TARGETING
if(TARG_ADDR_TRANSLATION_REQUIRED)
{
l_pNumTargets = static_cast<uint32_t*>(
- this->translateAddr(l_pNumTargets, l_instance[l_index]));
+ this->translateAddr(l_pNumTargets, i_instance));
}
// Get pointer to targets
Target (*l_pTargets)[] =
reinterpret_cast<Target(*)[]> (l_pNumTargets + 1);
- // Walk through targets
+ // Walk through targets until system target is found
for(uint32_t l_targetNum = 1;
l_targetNum <= *l_pNumTargets;
++l_targetNum)
@@ -130,103 +104,176 @@ namespace TARGETING
decltype(l_hb_images) l_mask =
0x1 << ((sizeof(l_hb_images) * 8) - 1);
- uint32_t l_node = NODE0;
- l_index = 0;
- // While multi-node system and valid mask and valid index
- while(l_hb_images && l_mask && (l_index < MAX_NODES_PER_SYS))
- {
- // Change node instance status
- if(iv_instanceStatus == SINGLE_NODE)
- {
- iv_instanceStatus = MULTI_NODE;
- }
+ NODE_ID l_node = NODE0;
- // If node is present
- if(l_mask & l_hb_images)
+ // Check if multi-node system
+ if(l_hb_images)
+ {
+ // While valid mask and valid node
+ while(l_mask && (l_node < MAX_NODES_PER_SYS))
{
- l_instance[l_index] = l_node;
-
- // Check if a previous node was skipped
- if(iv_instanceStatus == MULTI_NODE_LT_MAX_INSTANCES)
+ // If node is present
+ if(l_mask & l_hb_images)
{
- // Flag that instances are not contiguous
- iv_instanceStatus = MULTI_NODE_INSTANCE_GAP;
+ // Check if current node is the node of interest
+ if(l_node == i_instance)
+ {
+ // Flag that input instance is a valid node
+ l_validNode = true;
+ }
+
+ // Check if maximum node ID needs replacing
+ if(l_node > io_maxNodeId)
+ {
+ // Replace maximum node ID
+ io_maxNodeId = l_node;
+ }
}
- }
- else if(iv_instanceStatus == MULTI_NODE)
+
+ l_mask >>= 1; // shift to the right for the next node
+ ++l_node;
+ } // while
+ }
+ else // Single-node system
+ {
+ // Check if current node is the node of interest
+ if(l_node == i_instance)
{
- // Flag that an instance is being skipped
- iv_instanceStatus = MULTI_NODE_LT_MAX_INSTANCES;
+ // Flag that input instance is a valid node
+ l_validNode = true;
}
- l_mask >>= 1; // shift to the right for the next node
- l_node++;
- l_index++;
+ // Replace maximum node ID
+ io_maxNodeId = l_node;
}
- if(iv_instanceStatus == MULTI_NODE_INSTANCE_GAP)
+ // Input instance is not a valid node
+ if(!l_validNode)
{
- TRACFCOMP( g_trac_targeting,
- "There is a gap in the node numbers");
+ TRACFCOMP(g_trac_targeting,
+ ERR_MRK"Node %d not present in HB images %0.2x",
+ i_instance,
+ l_hb_images);
+
+ /*@
+ * @errortype ERRL_SEV_UNRECOVERABLE
+ * @moduleid TARG_MOD_ATTRRP_RT
+ * @reasoncode TARG_RT_NODE_NOT_IN_IMAGE
+ * @userdata1[00:31] Node
+ * @userdata1[32:64] HB Existing Image
+ * @userdata2 Memory address referenced.
+ *
+ * @devdesc Expected node is not present in
+ * ATTR_HB_EXISTING_IMAGE
+ * @custdesc A problem occurred during the IPL of the
+ * system.
+ * Expected resource was not indicated to be
+ * present.
+ */
+ l_errl = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
+ TARG_MOD_ATTRRP_RT,
+ TARG_RT_NODE_NOT_IN_IMAGE,
+ TWO_UINT32_TO_UINT64(
+ TO_UINT32(i_instance),
+ TO_UINT32(l_hb_images)),
+ reinterpret_cast<uint64_t>(i_header)
+ );
+ break;
}
+ // Stop walking targets, system target was found
break;
}
- }
+ } // for
+
+ return l_errl;
+ }
+
+ void AttrRP::startup(errlHndl_t& io_taskRetErrl, bool isMpipl)
+ {
+ TRACFCOMP(g_trac_targeting, "AttrRP::startup");
+ errlHndl_t l_errl = nullptr;
+
+ uint32_t l_instance = NODE0; // Start with NODE 0 for first instance
+ NODE_ID l_maxNodeId = NODE0; // Start with minimal node
+ bool l_rsvd_mem_exists = false; // indicates if an instance of reserved
+ // memory has been found
- // Handle additional instances
- l_index = 1;
do
{
- // Check that a valid node is set for this instnace
- if(l_instance[l_index] == INVALID_NODE)
- {
- l_index++;
-
- // Continue with next instance
- continue;
- }
+ // Create local copy of node struct
+ NodeInfo l_nodeCont;
uint64_t attr_size = 0;
TargetingHeader* l_header =
reinterpret_cast<TargetingHeader*>(
hb_get_rt_rsvd_mem(Util::HBRT_MEM_LABEL_ATTR,
- l_instance[l_index], attr_size));
+ l_instance, attr_size));
// Check if reserved memory does not exist for this instance
- if ((NULL == l_header) && (l_instance[l_index] > NODE0))
+ if ((NULL == l_header) || (0 == attr_size))
{
TRACFCOMP(g_trac_targeting,
- "Reserved memory does not exist for Node %d",
- l_instance[l_index]);
+ "Reserved memory does not exist for Node %d, "
+ "Push empty node struct for this node",
+ l_instance);
+ iv_nodeContainer.push_back(l_nodeCont);
+
+ // Check if we haven't found reserved memory for any node and
+ // if we haven't reached the maximum node ID for the system
+ if(!l_rsvd_mem_exists && (l_maxNodeId < MAX_NODES_PER_SYS - 1))
+ {
+ // Increase maximum node ID to allow checking another node
+ ++l_maxNodeId;
+ }
+ }
+ else
+ {
+ l_rsvd_mem_exists = true;
- l_index++;
+ // Initialize local copy of node struct
+ l_errl = nodeInfoInit(l_nodeCont,
+ l_header,
+ l_instance);
- // Continue with next instance
- continue;
- }
+ if (l_errl)
+ {
+ break;
+ }
- // Create local copy of node struct
- NodeInfo l_nodeCont;
- // Initialize local copy of node struct
- l_errl = nodeInfoInit(l_nodeCont,
- l_header,
- l_instance[l_index]);
+ // Push back node struct into the node container
+ TRACFCOMP(g_trac_targeting,
+ "Push node struct for Node %d",
+ l_instance);
+ iv_nodeContainer.push_back(l_nodeCont);
- // Push back node struct into the node container
- TRACFCOMP(g_trac_targeting,
- "Push node struct for Node %d",
- l_instance[l_index]);
- iv_nodeContainer.push_back(l_nodeCont);
+ // Check this node against the HB existing image attribute
+ l_errl = checkHbExistingImage(l_header,
+ l_instance,
+ l_maxNodeId);
+
+ if (l_errl)
+ {
+ break;
+ }
+ }
- l_index++;
- } while(l_index < MAX_NODES_PER_SYS);
+ ++l_instance;
+ } while(l_instance <= l_maxNodeId);
if (l_errl)
{
l_errl->setSev(ERRORLOG::ERRL_SEV_UNRECOVERABLE);
}
+ else if(l_maxNodeId != (iv_nodeContainer.size() - 1))
+ {
+ TRACFCOMP(g_trac_targeting,
+ ERR_MRK"Node container size, %d, is expected to be 1 "
+ "more than maximum Node ID, %d",
+ iv_nodeContainer.size(),
+ l_maxNodeId);
+ }
io_taskRetErrl = l_errl;
}
@@ -310,6 +357,9 @@ namespace TARGETING
io_nodeCont.pSections[i].pnorAddress,
io_nodeCont.pSections[i].size);
}
+ // mark this node container as valid
+ io_nodeCont.setIsValid(true);
+
} while(false);
return l_errl;
@@ -324,7 +374,8 @@ namespace TARGETING
void* l_pTargetMap = nullptr;
// Cannot use isNodeValid method here since the vector itself is
- // initialized in here.
+ // initialized in here. AttrRP::INVALID_NODE_ID is a dynamic
+ // value and is set to iv_nodeContainer.size()
if((i_nodeId >= NODE0) &&
(i_nodeId < AttrRP::INVALID_NODE_ID))
{
@@ -399,28 +450,33 @@ namespace TARGETING
void* l_pMap = nullptr;
- // The init for a node id might have been done via the other way i.e.
- // setImageName, need to valid if node Id is valid and init is already
- // done validate node Id, It's a special case validation, since the node
- // which is getting validated doesn't yet have a container, so it should
- // always point to the next to be initialized.
+ // if i_nodeId is less than INVALID_NODE_ID then iv_nodeContainer
+ // contains a node info struct for it, however it may be invalid
+ // for some reason (deconfigured) so check that on the next line.
if(i_nodeId < INVALID_NODE_ID)
{
// Check if the Mmap is already done
- if(iv_nodeContainer[i_nodeId].pTargetMap != nullptr)
+ if( iv_nodeContainer[i_nodeId].getIsValid() )
{
l_pMap = iv_nodeContainer[i_nodeId].pTargetMap;
}
else
{
- TARG_ASSERT(0,
- TARG_ERR_LOC "Node Id [%d] should have been already"
- " initialized, before but the Mmap Address is NULL",
- i_nodeId);
+ TARG_INF("getBaseAddr nodeInfo struct for %d is invalid,"
+ " skipping", i_nodeId);
+
}
}
else if(i_nodeId == INVALID_NODE_ID)
{
+ // If i_nodeID is equal to INVALID_NODE_ID then we add an empty
+ // NodeInfo struct to iv_nodeContainer and will attempt to
+ // initalize it with a call to getTargetMapPtr()
+ //
+ // Note: INVALID_NODE_ID is a dynamic value here which gets gets
+ // incremented each time a node info struct is pushed to
+ // iv_nodeContainer
+
// Push back a node struct in the node container
NodeInfo l_nodeCont;
iv_nodeContainer.push_back(l_nodeCont);
diff --git a/src/usr/targeting/runtime/rt_targeting.C b/src/usr/targeting/runtime/rt_targeting.C
index 7a51d05c3..06342633e 100644
--- a/src/usr/targeting/runtime/rt_targeting.C
+++ b/src/usr/targeting/runtime/rt_targeting.C
@@ -417,8 +417,7 @@ errlHndl_t saveRestoreAttrs(void *i_rsvdMemPtr,
l_attrRPLid =
new AttrRP(reinterpret_cast<TargetingHeader*>(io_lidStructPtr),
l_nodeId,
- l_attrRPRsvd->getNodeCount(),
- l_attrRPRsvd->getInstanceStatus());
+ l_attrRPRsvd->getNodeCount());
// Get pointer to array of targets in the targeting image
uint32_t l_maxTargetsLid = 0;
OpenPOWER on IntegriCloud