diff options
| author | Marty Gloff <mgloff@us.ibm.com> | 2018-05-29 11:34:33 -0500 |
|---|---|---|
| committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2018-06-21 14:38:36 -0400 |
| commit | ccf2f3445e15a93f06528c5f077c34e5abce548b (patch) | |
| tree | ffe6319edd19764336ec110424ed4f6b869b15de | |
| parent | fd49726ffcf05ade7e6c71ed1666b2075a999f95 (diff) | |
| download | blackbird-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.H | 74 | ||||
| -rw-r--r-- | src/include/usr/targeting/targplatreasoncodes.H | 1 | ||||
| -rwxr-xr-x | src/usr/targeting/attrrp_common.C | 3 | ||||
| -rw-r--r-- | src/usr/targeting/common/targetservice.C | 5 | ||||
| -rw-r--r-- | src/usr/targeting/runtime/attrrp_rt.C | 270 | ||||
| -rw-r--r-- | src/usr/targeting/runtime/rt_targeting.C | 3 |
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; |

