diff options
-rw-r--r-- | src/include/usr/runtime/runtime.H | 6 | ||||
-rw-r--r-- | src/usr/runtime/hdatservice.C | 19 | ||||
-rw-r--r-- | src/usr/runtime/populate_hbruntime.C | 74 |
3 files changed, 69 insertions, 30 deletions
diff --git a/src/include/usr/runtime/runtime.H b/src/include/usr/runtime/runtime.H index 042ff8002..e8605676b 100644 --- a/src/include/usr/runtime/runtime.H +++ b/src/include/usr/runtime/runtime.H @@ -182,9 +182,9 @@ errlHndl_t sendSBESystemConfig(); // How many pointers/sections there are in HB reserved memory data // HOMER*8/OCC_Common/VPD/ATTR/HBRT_Image/Res/Res/Res -// *Note: Phyp fills in one extra dummy section so make 1 less than -// HDAT_RHB_MAX_RANGE_ENTRIES_PER_NODE in src/hdat/fsp/hdat.H. -#define HB_RSV_MEM_NUM_PTRS 49 +// should be the same as HDAT_RHB_MAX_RANGE_ENTRIES_PER_NODE in +// src/hdat/fsp/hdat.H +#define HB_RSV_MEM_NUM_PTRS 50 //Note this means the Reserved Mem sub-section is the 6th //(0 based) of the MDT section (See HDAT spec 11.1.1) diff --git a/src/usr/runtime/hdatservice.C b/src/usr/runtime/hdatservice.C index c2721fd68..47f7a500c 100644 --- a/src/usr/runtime/hdatservice.C +++ b/src/usr/runtime/hdatservice.C @@ -696,17 +696,22 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, errhdl = getResvMemArrHdr(reservedMemArrayHeader); if( errhdl ) { break; } - uint64_t l_arrCount = reservedMemArrayHeader->arrayEntryCount; - if( i_instance >= l_arrCount ) + // get the total number of entries per node in the hostboot + // reserved memory area, since we are using the instance num + // as an index into the reserved mem array, make sure + // the passed in instance is within the array boundary + uint64_t l_maxArrayIndex = + reservedMemArrayHeader->arrayEntryCount -1; + if( i_instance > l_maxArrayIndex ) { - TRACFCOMP( g_trac_runtime, "Instance %d exceeds max reserved mem entry count %d", - i_instance, l_arrCount); + TRACFCOMP( g_trac_runtime, "Instance %d exceeds max reserved mem entry index %d", + i_instance, l_maxArrayIndex ); /*@ * @errortype * @moduleid RUNTIME::MOD_HDATSERVICE_GETHOSTDATASECTION * @reasoncode RUNTIME::RC_INVALID_RHB_INSTANCE - * @userdata1 Requested instance - * @userdata2 Entry count + * @userdata1 Requested instance (reserved mem array index) + * @userdata2 maximum array index allowed * @devdesc Invalid instance requested for Reserved * Hostboot Memory section * @custdesc Firmware error during boot @@ -716,7 +721,7 @@ errlHndl_t hdatService::getHostDataSection( SectionId i_section, RUNTIME::MOD_HDATSERVICE_GETHOSTDATASECTION, RUNTIME::RC_INVALID_RHB_INSTANCE, i_instance, - l_arrCount, + l_maxArrayIndex, true /*Add HB Software Callout*/); errhdl->collectTrace(RUNTIME_COMP_NAME,KILOBYTE); break; diff --git a/src/usr/runtime/populate_hbruntime.C b/src/usr/runtime/populate_hbruntime.C index 40899ecf5..11adb3892 100644 --- a/src/usr/runtime/populate_hbruntime.C +++ b/src/usr/runtime/populate_hbruntime.C @@ -102,7 +102,52 @@ const uint64_t HB_RES_MEM_LOWER_LIMIT = VMM_MEMORY_SIZE + VMM_HRMOR_OFFSET; trace_desc_t *g_trac_runtime = nullptr; TRAC_INIT(&g_trac_runtime, RUNTIME_COMP_NAME, KILOBYTE); +// Helper function to get the instance number from the +// node number. The instance is derived from the hb_images +// attribute, instance 0 will be the first active drawer +// in the sytem, if hb_images is zero this function will +// also return zero. +uint16_t getHdatNodeInstance(void) +{ + + uint16_t instance = 0; + TARGETING::Target* sys = nullptr; + TARGETING::targetService().getTopLevelTarget( sys ); + assert(sys != nullptr, + "getHdatNodeInstance() - Could not obtain top level target"); + + // This attribute is only set on a multi-node system. + // We will use it below to detect a multi-node scenario + auto hb_images = sys->getAttr<TARGETING::ATTR_HB_EXISTING_IMAGE>(); + + // get the node id + const auto l_node = TARGETING::UTIL::getCurrentNodePhysId(); + + // if hb_images is empty instance is 0 for a single node + if( hb_images ) + { + // leftmost position indicates node 0 + decltype(hb_images) l_mask = 0x1 << (sizeof(hb_images)*BITS_PER_BYTE-1); + + uint16_t i = 0; + + while( i != l_node ) + { + l_mask = l_mask >> 1; + // see if this node is functional + if( hb_images & l_mask ) + { + instance++; + } + i++; + } + } + + TRACFCOMP( g_trac_runtime,"node %d is hdat instance %d", + l_node,instance); + return instance; +} /** * @brief Get a pointer to the next available * HDAT HB Reserved Memory entry @@ -128,24 +173,13 @@ errlHndl_t getNextRhbAddrRange(hdatMsVpdRhbAddrRange_t* & o_rngPtr) uint64_t l_rsvMemDataAddr = 0; uint64_t l_rsvMemDataSizeMax = 0; - // Figure out which node we are running on - TARGETING::Target* mproc = nullptr; - TARGETING::targetService().masterProcChipTargetHandle(mproc); - - TARGETING::EntityPath epath = - mproc->getAttr<TARGETING::ATTR_PHYS_PATH>(); - - const TARGETING::EntityPath::PathElement pe = - epath.pathElementOfType(TARGETING::TYPE_NODE); - - uint64_t nodeid = pe.instance; - // there are 50 reserved memory spots per node, - // use the node number to index into the hb reserved mem pointers + // use the node instance to index into the hb reserved mem pointers // for this node. HB_RSV_MEM_NUM_PTRS is defined as the number // of usable pointers - see runtime.H for some background + uint16_t l_nodeInstance = getHdatNodeInstance(); uint32_t instance = l_nextSection + - ((HB_RSV_MEM_NUM_PTRS + 1) * nodeid); + (HB_RSV_MEM_NUM_PTRS * l_nodeInstance); // Get the address of the next section l_elog = RUNTIME::get_host_data_section( RUNTIME::RESERVED_MEM, @@ -2949,10 +2983,10 @@ errlHndl_t populate_hbRuntimeData( void ) const TARGETING::EntityPath::PathElement pe = epath.pathElementOfType(TARGETING::TYPE_NODE); - uint64_t nodeid = pe.instance; + uint64_t l_masterNodeId = pe.instance; TRACFCOMP( g_trac_runtime, "Master node nodeid = %x", - nodeid); + l_masterNodeId); // ATTR_HB_EXISTING_IMAGE only gets set on a multi-drawer system. // Currently set up in host_sys_fab_iovalid_processing() which only @@ -2972,7 +3006,7 @@ errlHndl_t populate_hbRuntimeData( void ) { if( !TARGETING::is_no_load() ) { - l_elog = populate_HbRsvMem(nodeid,true); + l_elog = populate_HbRsvMem(l_masterNodeId,true); if(l_elog != nullptr) { TRACFCOMP( g_trac_runtime, "populate_HbRsvMem failed" ); @@ -3036,7 +3070,7 @@ errlHndl_t populate_hbRuntimeData( void ) uint64_t payloadBase = sys->getAttr<TARGETING::ATTR_PAYLOAD_BASE>(); // populate our own node specific data + the common stuff - l_elog = populate_HbRsvMem(nodeid,true); + l_elog = populate_HbRsvMem(l_masterNodeId,true); if(l_elog != nullptr) { @@ -3068,7 +3102,7 @@ errlHndl_t populate_hbRuntimeData( void ) for (uint64_t l_node=0; (l_node < MAX_NODES_PER_SYS); l_node++ ) { // skip sending to ourselves, we did our construction above - if(l_node == nodeid) + if(l_node == l_masterNodeId) continue; if( 0 != ((mask >> l_node) & hb_images ) ) @@ -3080,7 +3114,7 @@ errlHndl_t populate_hbRuntimeData( void ) msg_t * msg = msg_allocate(); msg->type = IPC::IPC_POPULATE_ATTRIBUTES; msg->data[0] = l_node; // destination node - msg->data[1] = nodeid; // respond to this node + msg->data[1] = l_masterNodeId; // respond to this node msg->extra_data = reinterpret_cast<uint64_t*>(payloadBase); // send the message to the slave hb instance |