summaryrefslogtreecommitdiffstats
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
parentfd49726ffcf05ade7e6c71ed1666b2075a999f95 (diff)
downloadblackbird-hostboot-ccf2f3445e15a93f06528c5f077c34e5abce548b.tar.gz
blackbird-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>
-rw-r--r--src/include/usr/targeting/attrrp.H74
-rw-r--r--src/include/usr/targeting/targplatreasoncodes.H1
-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
6 files changed, 210 insertions, 146 deletions
diff --git a/src/include/usr/targeting/attrrp.H b/src/include/usr/targeting/attrrp.H
index 679672160..ab800beb8 100644
--- a/src/include/usr/targeting/attrrp.H
+++ b/src/include/usr/targeting/attrrp.H
@@ -63,10 +63,22 @@ struct NodeInfo
NodeInfo() :
pTargetMap(nullptr),
pSections(nullptr),
- sectionCount(0)
+ sectionCount(0),
+ isValid(false)
{
}
+ // helper to determine if NodeInfo struct has
+ // been initialized or not
+ bool getIsValid() const { return isValid; };
+
+ // set the instance var to indicate the NodeInfo
+ // struct has ben initialized
+ void setIsValid( bool i_valid )
+ {
+ isValid = i_valid;
+ };
+
// Pointer to the targeting image
void* pTargetMap;
@@ -76,18 +88,11 @@ struct NodeInfo
// Count of attribute sections.
size_t sectionCount;
-};
+ // has this node info struct been setup
+ bool isValid;
-/**
- * @brief enumeration of node instance status
- */
-enum NodeInstanceStatus
-{
- SINGLE_NODE,
- MULTI_NODE,
- MULTI_NODE_LT_MAX_INSTANCES,
- MULTI_NODE_INSTANCE_GAP,
};
+
#endif
/**
@@ -371,18 +376,6 @@ class AttrRP
#else
/**
- * @brief Get node instance status of attribute resource provider
- * which indicates if the attribute resource provider is handling
- * a single node or multiple nodes
- *
- * @return Node instance status
- */
- NodeInstanceStatus getInstanceStatus()
- {
- return iv_instanceStatus;
- }
-
- /**
* @brief Get count of nodes handled by attribute resource provider.
*
* @return Number of node containers
@@ -406,8 +399,7 @@ class AttrRP
: iv_msgQ(NULL), iv_sections(NULL), iv_sectionCount(0),
iv_isMpipl(false)
#else
- : iv_isTempInstance(false), iv_instanceStatus(SINGLE_NODE),
- iv_isMpipl(false)
+ : iv_isTempInstance(false), iv_isMpipl(false)
#endif
{
};
@@ -418,13 +410,15 @@ class AttrRP
*
* @par Detailed Description:
* Ensures member variables are initialized to sane values.
+ *
+ * @param[in] i_header, Targeting Header for the node of interest
+ * @param[in] i_nodeId, Node ID for the node of interest
+ * @param[in] i_nodeCount, Number of nodes to initialize
*/
AttrRP(TargetingHeader* i_header,
NODE_ID i_nodeId,
- size_t i_nodeCount,
- NodeInstanceStatus i_instanceStatus)
- : iv_isTempInstance(true), iv_instanceStatus(i_instanceStatus),
- iv_isMpipl(false)
+ size_t i_nodeCount)
+ : iv_isTempInstance(true), iv_isMpipl(false)
{
// Work with nodes before passed in node
for(NODE_ID l_nodeId = NODE0; l_nodeId < i_nodeCount; ++l_nodeId)
@@ -498,6 +492,22 @@ class AttrRP
std::vector <sectionRefData>& o_pages,
const SECTION_TYPE i_sectionType,
const NODE_ID i_nodeId = 0) const;
+#else
+ /**
+ * @brief Check the HB existing image attribute from the system target
+ * in the targeting data for the node. Use image to determine
+ * if node of interest (instance) is a node that is shown to be
+ * present. Also update the maximum node ID as needed.
+ *
+ * @param[in] i_header, Targeting Header for the node of interest
+ * @param[in] i_instance, Specifies the node of interest
+ * @param[in/out] io_maxNodeId, maximum node ID in use on the system
+ *
+ * @return Error log
+ */
+ errlHndl_t checkHbExistingImage(TargetingHeader* i_header,
+ uint8_t i_instance,
+ NODE_ID &io_maxNodeId);
#endif
@@ -623,9 +633,6 @@ class AttrRP
// Node Container
std::vector<NodeInfo> iv_nodeContainer;
-
- // Node instance status
- NodeInstanceStatus iv_instanceStatus;
#endif
bool iv_isMpipl;
@@ -639,7 +646,8 @@ TARG_DECLARE_SINGLETON(TARGETING::AttrRP,theAttrRP);
extern const char* ATTRRP_MSG_Q;
// user-defined message subtype for MSG_MM_RP_RUNTIME_PREP
-/** @enum msg_mm_rp_runtime_prep_t
+/**
+ * @enum msg_mm_rp_runtime_prep_t
* @brief Message type and subtypes for the MSG_MM_RP_RUNTIME_PREP message
*/
enum msg_mm_rp_runtime_prep_t
diff --git a/src/include/usr/targeting/targplatreasoncodes.H b/src/include/usr/targeting/targplatreasoncodes.H
index b38c0c646..274b14757 100644
--- a/src/include/usr/targeting/targplatreasoncodes.H
+++ b/src/include/usr/targeting/targplatreasoncodes.H
@@ -82,6 +82,7 @@ enum PlatTargetingReasonCode
TARG_RT_MISSING_ATTR = TARG_COMP_ID | 0x87,
TARG_RT_BAD_ATTR_SIZES = TARG_COMP_ID | 0x88,
TARG_SVC_MISSING_ATTR = TARG_COMP_ID | 0x89,
+ TARG_RT_NODE_NOT_IN_IMAGE = TARG_COMP_ID | 0x8A,
};
} // End TARGETING namespace
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