diff options
Diffstat (limited to 'src/usr/targeting/common/targetservice.C')
| -rw-r--r-- | src/usr/targeting/common/targetservice.C | 969 |
1 files changed, 819 insertions, 150 deletions
diff --git a/src/usr/targeting/common/targetservice.C b/src/usr/targeting/common/targetservice.C index ce2c3906c..f434765fd 100644 --- a/src/usr/targeting/common/targetservice.C +++ b/src/usr/targeting/common/targetservice.C @@ -36,6 +36,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <map> // This component #include <targeting/common/targetservice.H> @@ -44,6 +45,11 @@ #include <targeting/attrrp.H> #include <targeting/common/trace.H> #include <targeting/adapters/types.H> +#include <targeting/targplatutil.H> +#include <targeting/targplatreasoncodes.H> +#include <attributetraits.H> + +#undef EXTRA_SANITY_CHECKING //****************************************************************************** // targetService @@ -56,6 +62,9 @@ namespace TARGETING #define TARG_CLASS "targetService" +// It is defined here to limit the scope +#define MAX_NODE_ID iv_nodeInfo.size() + //****************************************************************************** // targetService //****************************************************************************** @@ -88,7 +97,7 @@ TRAC_INIT(&g_trac_targeting, "TARG", 4096); //****************************************************************************** TargetService::TargetService() : - iv_initialized(false), iv_maxTargets(0), iv_pPnor(NULL) + iv_initialized(false) { #define TARG_FN "TargetService()" @@ -112,43 +121,76 @@ TargetService::~TargetService() // TargetService::init //****************************************************************************** -void TargetService::init() +void TargetService::init(const size_t i_maxNodes) { #define TARG_FN "init()" TARG_ENTER(); - // Build the association mappings - AssociationAttrMap a1 = {PARENT, INWARDS, ATTR_PHYS_PATH}; - AssociationAttrMap a2 = {CHILD, OUTWARDS, ATTR_PHYS_PATH}; - AssociationAttrMap a3 = {PARENT_BY_AFFINITY, INWARDS, ATTR_AFFINITY_PATH}; - AssociationAttrMap a4 = {CHILD_BY_AFFINITY, OUTWARDS, ATTR_AFFINITY_PATH}; - AssociationAttrMap a5 = {VOLTAGE_SUPPLIER, INWARDS, ATTR_POWER_PATH}; - AssociationAttrMap a6 = {VOLTAGE_CONSUMER, OUTWARDS, ATTR_POWER_PATH}; - iv_associationMappings.push_back(a1); - iv_associationMappings.push_back(a2); - iv_associationMappings.push_back(a3); - iv_associationMappings.push_back(a4); - iv_associationMappings.push_back(a5); - iv_associationMappings.push_back(a6); - - // Cache location of RO section containing all the attribute metadata - TargetingHeader* l_pHdr = reinterpret_cast<TargetingHeader*>( - TARG_GET_SINGLETON(TARGETING::theAttrRP).getBaseAddress()); - - TARG_ASSERT((l_pHdr != NULL), TARG_ERR_LOC - "FATAL: Targeting header is NULL!") - TARG_ASSERT((l_pHdr->eyeCatcher == PNOR_TARG_EYE_CATCHER), TARG_ERR_LOC - "FATAL: Targeting eyecatcher not found; " - "expected 0x%08X but got 0x%08X", - PNOR_TARG_EYE_CATCHER,l_pHdr->eyeCatcher); - - iv_pPnor = reinterpret_cast<uint32_t*>( - (reinterpret_cast<char*>(l_pHdr) + l_pHdr->headerSize)); - - (void)_configureTargetPool(); - - iv_initialized = true; + if(!iv_initialized) + { + TARG_INF("Max Nodes to initialize is [%d]", i_maxNodes); + + // Build the association mappings + AssociationAttrMap a1 = {PARENT, INWARDS, ATTR_PHYS_PATH}; + AssociationAttrMap a2 = {CHILD, OUTWARDS, ATTR_PHYS_PATH}; + AssociationAttrMap a3 = {PARENT_BY_AFFINITY, + INWARDS,ATTR_AFFINITY_PATH}; + AssociationAttrMap a4 = {CHILD_BY_AFFINITY, + OUTWARDS,ATTR_AFFINITY_PATH}; + AssociationAttrMap a5 = {VOLTAGE_SUPPLIER, INWARDS, ATTR_POWER_PATH}; + AssociationAttrMap a6 = {VOLTAGE_CONSUMER, OUTWARDS, ATTR_POWER_PATH}; + iv_associationMappings.push_back(a1); + iv_associationMappings.push_back(a2); + iv_associationMappings.push_back(a3); + iv_associationMappings.push_back(a4); + iv_associationMappings.push_back(a5); + iv_associationMappings.push_back(a6); + + for(uint8_t l_nodeCnt=0; l_nodeCnt<i_maxNodes; l_nodeCnt++) + { + NodeSpecificInfo l_nodeInfo; + l_nodeInfo.nodeId = static_cast<NODE_ID>(l_nodeCnt); + + // Cache location of RO section containing all the attribute + // metadata + TargetingHeader* l_pHdr = reinterpret_cast<TargetingHeader*>( + TARG_GET_SINGLETON(TARGETING::theAttrRP).getBaseAddress( + static_cast<NODE_ID>(l_nodeCnt))); + + if(NULL == l_pHdr) + { + TARG_INF("Targeting header is NULL for Node Id [%d]", + l_nodeCnt); + TARG_ASSERT(0, TARG_ERR_LOC + "Targeting Header for Node [%d] cannot be NULL", l_nodeCnt); + } + else + { + TARG_ASSERT((l_pHdr->eyeCatcher == PNOR_TARG_EYE_CATCHER), + TARG_ERR_LOC "FATAL: Targeting eyecatcher not found; " + "expected 0x%08X but got 0x%08X", + PNOR_TARG_EYE_CATCHER,l_pHdr->eyeCatcher); + + l_nodeInfo.pPnor = reinterpret_cast<uint32_t*>( + (reinterpret_cast<char*>(l_pHdr) + l_pHdr->headerSize)); + + (void)_configureTargetPool(l_nodeInfo); + + l_nodeInfo.initialized = true; + } + iv_nodeInfo.push_back(l_nodeInfo); + } + + bool masterNodeCapable = false; + (void)UTIL::subsystemIsMasterNodeCapable(masterNodeCapable); + if(masterNodeCapable) + { + (void)initDefaultMasterNode(); + } + + iv_initialized = true; + } TARG_EXIT(); @@ -156,26 +198,74 @@ void TargetService::init() } //****************************************************************************** +// TargetService:: _getFirstTargetForIterators +//****************************************************************************** + +void TargetService::_getFirstTargetForIterators(Target*& o_firstTargetPtr) const +{ + #define TARG_FN "_getFirstTargetForIterators()" + TARG_ASSERT(iv_initialized, TARG_ERR_LOC + "USAGE: TargetService not initialized"); + + for(uint8_t l_nodeCnt=0; l_nodeCnt<MAX_NODE_ID; ++l_nodeCnt) + { + /* This will come inside for initialized node only.. Just for safety we + * are checking for maxTargets & whether it is initialized or not */ + if((iv_nodeInfo[l_nodeCnt].initialized == true) && + (iv_nodeInfo[l_nodeCnt].maxTargets > 0)) + { + /* Assumption - + * Here we are assuming that the first target of any binary is not + * the system target, to make sure this ithe binary compiler needs + * to compile the binary in this specific order. + */ + o_firstTargetPtr = &(*(iv_nodeInfo[l_nodeCnt].targets))[0]; + + TARG_ASSERT(o_firstTargetPtr != NULL, TARG_ERR_LOC + "FATAL: Could not find any targets"); + break; + } + } + #undef TARG_FN +} + +//****************************************************************************** // TargetService::begin (non-const version) //****************************************************************************** TargetService::iterator TargetService::begin() { #define TARG_FN "begin()" + Target* l_pFirstTarget = NULL; TARG_ASSERT(iv_initialized, TARG_ERR_LOC "USAGE: TargetService not initialized"); - Target* l_pFirstTarget = (iv_maxTargets == 0) ? NULL : &(*iv_targets)[0]; - TARG_ASSERT(l_pFirstTarget != NULL, TARG_ERR_LOC - "FATAL: Could not find any targets"); - + _getFirstTargetForIterators(l_pFirstTarget); return iterator(l_pFirstTarget); #undef TARG_FN } //****************************************************************************** +// TargetService::raw_begin (non-const version) +//****************************************************************************** + +TargetService::rawiterator TargetService::raw_begin() +{ + #define TARG_FN "raw_begin()" + Target* l_pFirstTarget = NULL; + + TARG_ASSERT(iv_initialized, TARG_ERR_LOC + "USAGE: TargetService not initialized"); + + _getFirstTargetForIterators(l_pFirstTarget); + return rawiterator(l_pFirstTarget); + + #undef TARG_FN +} + +//****************************************************************************** // TargetService::begin (const version) //****************************************************************************** @@ -183,20 +273,40 @@ TargetService::iterator TargetService::begin() _TargetIterator<const Target*> TargetService::begin() const { #define TARG_FN "begin() const" + Target* l_pTmpFirstTarget = NULL; TARG_ASSERT(iv_initialized, TARG_ERR_LOC "USAGE: TargetService not initialized"); - const Target* l_pFirstTarget = - (iv_maxTargets == 0) ? NULL : &(*iv_targets)[0]; - TARG_ASSERT(l_pFirstTarget != NULL, TARG_ERR_LOC - "FATAL: Could not find any targets"); + _getFirstTargetForIterators(l_pTmpFirstTarget); + const Target* l_pFirstTarget = l_pTmpFirstTarget; return const_iterator(l_pFirstTarget); #undef TARG_FN } + +//****************************************************************************** +// TargetService::raw_begin (const version) +//****************************************************************************** + +_TargetRawIterator<const Target*> TargetService::raw_begin() const +{ + #define TARG_FN "raw_begin() const" + Target* l_pTmpFirstTarget = NULL; + + TARG_ASSERT(iv_initialized, TARG_ERR_LOC + "USAGE: TargetService not initialized"); + + _getFirstTargetForIterators(l_pTmpFirstTarget); + const Target* l_pFirstTarget = l_pTmpFirstTarget; + + return const_rawiterator(l_pFirstTarget); + + #undef TARG_FN +} + //****************************************************************************** // TargetService::end (non-const version) //****************************************************************************** @@ -214,6 +324,22 @@ TargetService::iterator TargetService::end() } //****************************************************************************** +// TargetService::raw_end (non-const version) +//****************************************************************************** + +TargetService::rawiterator TargetService::raw_end() +{ + #define TARG_FN "raw_end()" + + TARG_ASSERT(iv_initialized, TARG_ERR_LOC + "USAGE: TargetService not initialized"); + + return rawiterator(NULL); + + #undef TARG_FN +} + +//****************************************************************************** // TargetService::end (const version) //****************************************************************************** @@ -230,6 +356,108 @@ TargetService::const_iterator TargetService::end() const } //****************************************************************************** +// TargetService::raw_end (const version) +//****************************************************************************** + +TargetService::const_rawiterator TargetService::raw_end() const +{ + #define TARG_FN "raw_end() const" + + TARG_ASSERT(iv_initialized, TARG_ERR_LOC + "USAGE: TargetService not initialized"); + + return const_rawiterator(NULL); + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::getNextInitializedNode +//****************************************************************************** + +uint8_t TargetService::getNextInitializedNode(const NODE_ID i_node) const +{ + #define TARG_FN "getNextInitializedNode(...)" + uint8_t l_nodeCnt = 0; + bool l_foundNode = false; + + if(static_cast<uint32_t>(i_node + 1) < MAX_NODE_ID) + { + for(l_nodeCnt=(i_node +1); l_nodeCnt<MAX_NODE_ID; ++l_nodeCnt) + { + if((iv_nodeInfo[l_nodeCnt].initialized) && + (iv_nodeInfo[l_nodeCnt].maxTargets > 0)) + { + l_foundNode = true; + break; + } + } + } + if(l_foundNode == false) + { + // Assign Invalid node + l_nodeCnt = MAX_NODE_ID; + } + return l_nodeCnt; + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::getNextTarget +//****************************************************************************** + +Target* TargetService::getNextTarget(const Target* i_pTarget) const +{ + #define TARG_FN "getNextTarget(...)" + Target* l_pTarget = const_cast<Target*>(i_pTarget); + bool l_targetFound = false; + if(l_pTarget != NULL) + { + for(uint8_t i_node=0; i_node<MAX_NODE_ID; ++i_node) + { + if((iv_nodeInfo[i_node].initialized) && + (iv_nodeInfo[i_node].maxTargets > 0) && + ((l_pTarget >= &(*(iv_nodeInfo[i_node]).targets)[0]) && + (l_pTarget <= &(*(iv_nodeInfo[i_node]).targets)[ + iv_nodeInfo[i_node].maxTargets - 1]))) + { + if( l_pTarget == &(*(iv_nodeInfo[i_node]).targets)[iv_nodeInfo[ + i_node].maxTargets - 1] ) + { + // Go for next node + uint8_t l_nextNode = getNextInitializedNode( + static_cast<NODE_ID>(i_node)); + if(l_nextNode != MAX_NODE_ID) + { + l_pTarget = &(*(iv_nodeInfo[l_nextNode].targets))[0]; + l_targetFound = true; + break; + } + else + { + l_targetFound = false; + break; + } + } + else + { + ++l_pTarget; + l_targetFound = true; + break; + } + } + } + } + if(l_targetFound == false) + { + l_pTarget = NULL; + } + + return l_pTarget; + #undef TARG_FN +} + +//****************************************************************************** // TargetService::getTopLevelTarget //****************************************************************************** @@ -258,21 +486,32 @@ void TargetService::exists( { #define TARG_FN "exists(...)" - bool l_found = false; + o_exists = false; TARG_ASSERT(iv_initialized, TARG_ERR_LOC "USAGE: TargetService not initialized"); - for (uint32_t i = 0; i < iv_maxTargets; ++i) + PredicateAttrVal<TARGETING::ATTR_PHYS_PATH> l_entityPathMatches( + i_entityPath); + + TARGETING::TargetRangeFilter l_targetsWithMatchingEntityPath( + TARGETING::targetService().begin(), + TARGETING::targetService().end(), + &l_entityPathMatches); + + if(l_targetsWithMatchingEntityPath) { - if (i_entityPath == (*iv_targets)[i].getAttr<ATTR_PHYS_PATH> ()) + o_exists = true; + + #ifdef EXTRA_SANITY_CHECKING + ++l_targetsWithMatchingEntityPath; + if(l_targetsWithMatchingEntityPath) { - l_found = true; + TARG_ASSERT(0, TARG_ERR_LOC "Should have found a single match"); } + #endif } - o_exists = l_found; - #undef TARG_FN } @@ -285,36 +524,68 @@ Target* TargetService::toTarget( { #define TARG_FN "toTarget(...)" - // Used by -> operator on EntityPath for convenience (can be dangerous - // though!) Target* l_pTarget = NULL; TARG_ASSERT(iv_initialized, TARG_ERR_LOC - "USAGE: TargetService not initialized"); + "USAGE: TargetService not initialized"); - for (uint32_t i = 0; i < iv_maxTargets; ++i) + if(i_entityPath.type() == EntityPath::PATH_PHYSICAL) { - bool found = false; - switch(i_entityPath.type()) + PredicateAttrVal<TARGETING::ATTR_PHYS_PATH> l_physPathMatches( + i_entityPath); + + TARGETING::TargetRangeFilter l_targetsWithMatchingPhysPath( + TARGETING::targetService().begin(), + TARGETING::targetService().end(), + &l_physPathMatches); + + if(l_targetsWithMatchingPhysPath) { - case EntityPath::PATH_PHYSICAL: - found = ( (i_entityPath) - == (*iv_targets)[i].getAttr<ATTR_PHYS_PATH>()); - break; - case EntityPath::PATH_AFFINITY: - found = ( (i_entityPath) - == (*iv_targets)[i].getAttr<ATTR_AFFINITY_PATH>()); - break; - default: - break; + l_pTarget = *l_targetsWithMatchingPhysPath; + + #ifdef EXTRA_SANITY_CHECKING + ++l_targetsWithMatchingPhysPath; + if(l_targetsWithMatchingPhysPath) + { + TARG_ASSERT(0, TARG_ERR_LOC + "Should have found a single target with HUID of 0x%08X " + "when searching for physical path", + l_pTarget->getAttr<ATTR_HUID>()); + } + #endif } + } + else if(i_entityPath.type() == EntityPath::PATH_AFFINITY) + { + PredicateAttrVal<TARGETING::ATTR_AFFINITY_PATH> l_affinityPathMatches( + i_entityPath); - if (found) + TARGETING::TargetRangeFilter l_targetsWithMatchingAffinityPath( + TARGETING::targetService().begin(), + TARGETING::targetService().end(), + &l_affinityPathMatches); + + if(l_targetsWithMatchingAffinityPath) { - l_pTarget = &(*iv_targets)[i]; - break; + l_pTarget = *l_targetsWithMatchingAffinityPath; + + #ifdef EXTRA_SANITY_CHECKING + ++l_targetsWithMatchingAffinityPath; + if(l_targetsWithMatchingAffinityPath) + { + TARG_ASSERT(0, TARG_ERR_LOC + "Should have found a single target with HUID of 0x%08X " + "when searching for affinity path", + l_pTarget->getAttr<ATTR_HUID>()); + } + #endif } } + else + { + TARG_ERR("EntityPath Type [%s] not supported for toTarget Method", + i_entityPath.pathTypeAsString()); + } return l_pTarget; @@ -326,27 +597,175 @@ Target* TargetService::toTarget( //****************************************************************************** void TargetService::masterProcChipTargetHandle( - Target*& o_masterProcChipTargetHandle, - const uint8_t i_node) const + Target*& o_masterProcChipTargetHandle, + const Target* i_pNodeTarget) const { #define TARG_FN "masterProcChipTargetHandle(...)" + errlHndl_t pError = NULL; - Target* l_pTarget = NULL; + pError = queryMasterProcChipTargetHandle( + o_masterProcChipTargetHandle, + i_pNodeTarget); + if(pError != NULL) + { + /* Error is already traced w.r.t api called, not repeating here*/ + TARG_ERR("Not able to find the Master Proc Chip Target Handle"); + delete pError; + pError = NULL; + o_masterProcChipTargetHandle = NULL; + } + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::queryMasterProcChipTargetHandle +//****************************************************************************** + +errlHndl_t TargetService::queryMasterProcChipTargetHandle( + Target*& o_masterProcChipTargetHandle, + const Target* const i_pNodeTarget) const +{ + #define TARG_FN "queryMasterProcChipTargetHandle(...)" + + errlHndl_t pError = NULL; + Target* pMasterProc = NULL; + o_masterProcChipTargetHandle = NULL; TARG_ASSERT(iv_initialized, TARG_ERR_LOC - "USAGE: TargetService not initialized"); + "USAGE: TargetService not initialized"); + + do { + + if(i_pNodeTarget == NULL) + { + static Target* pActingMasterTarget = NULL; + + if(!pActingMasterTarget || PLAT::PROPERTIES::MULTINODE_AWARE) + { + // Create filter that finds acting master processors + PredicateCTM procFilter(CLASS_CHIP, TYPE_PROC); + PredicateAttrVal<ATTR_PROC_MASTER_TYPE> actingMasterFilter( + PROC_MASTER_TYPE_ACTING_MASTER); + PredicatePostfixExpr actingMasterProcFilter; + actingMasterProcFilter.push(&procFilter).push( + &actingMasterFilter).And(); + + // Find all the acting master processors (max one per physical + // node), sorted by fabric node ID, and return the one with the + // lowest fabric node ID + TargetRangeFilter blueprintProcs( + targetService().begin(), + targetService().end(), + &actingMasterProcFilter); + + TARGETING::ATTR_FABRIC_NODE_ID_type minFabricNodeId = + TARGETING::FABRIC_NODE_ID_NOT_FOUND; + for(; blueprintProcs; ++blueprintProcs) + { + TARGETING::ATTR_FABRIC_NODE_ID_type fabricNodeId = + blueprintProcs->getAttr< + TARGETING::ATTR_FABRIC_NODE_ID>(); + if(fabricNodeId < minFabricNodeId) + { + minFabricNodeId = fabricNodeId; + pMasterProc = *blueprintProcs; + } + } + + if( (pMasterProc) + && (!PLAT::PROPERTIES::MULTINODE_AWARE)) + { + pActingMasterTarget = pMasterProc; + } + } + else + { + pMasterProc = pActingMasterTarget; + } + } - //@TODO RTC 78076 Need to query the actual hardware and cross check it with - // PNOR to determine the master chip - // target; for now, just always report sys0.n0.proc0 - EntityPath l_masterProcChipEntityPath(EntityPath::PATH_PHYSICAL); - l_masterProcChipEntityPath.addLast(TYPE_SYS, 0).addLast(TYPE_NODE, i_node) - .addLast(TYPE_PROC, 0); + /* We have a valid Target at this point */ + /* Would verify if the target given by user is a node target */ + else if( (i_pNodeTarget->getAttr<ATTR_CLASS>() == CLASS_ENC) && + (i_pNodeTarget->getAttr<ATTR_TYPE>() == TYPE_NODE) ) + { + // Create predicate which looks for an acting master processor chip + PredicateAttrVal<ATTR_PROC_MASTER_TYPE> l_procMasterMatches( + PROC_MASTER_TYPE_ACTING_MASTER); + PredicateCTM + l_procPredicate(TARGETING::CLASS_CHIP,TARGETING::TYPE_PROC); + PredicatePostfixExpr l_masterProcFilter; + l_masterProcFilter.push(&l_procPredicate).push( + &l_procMasterMatches).And(); + + // Find the acting master within the node + TARGETING::TargetHandleList l_masterProclist; + getAssociated(l_masterProclist, + const_cast<const Target*>(i_pNodeTarget), CHILD, ALL, + &l_masterProcFilter); + + if(!l_masterProclist.empty()) + { + pMasterProc = l_masterProclist[0]; + } + } + else + { + TARG_ERR("Invalid Node Target to query Master Proc " + "- NULL Master Proc Handle Returned. HUID of Target Passed " + "[0x%08X]", i_pNodeTarget->getAttr<ATTR_HUID>()); + + /*@ + * @errortype + * @refcode LIC_REFCODE + * @subsys EPUB_FIRMWARE_SP + * @moduleid TARG_MOD_QUERY_MASTER_PROC_CHIP + * @reasoncode TARG_RC_INVALID_NODE + * @userData1 HUID of Target Passed + * @devdesc Error: User Passed an invalid Node Target to find the + * master proc handle + */ + UTIL::createTracingError( + TARG_MOD_QUERY_MASTER_PROC_CHIP, + TARG_RC_INVALID_NODE, + i_pNodeTarget->getAttr<ATTR_HUID>(), + 0,0,0, + pError); + break; + } - l_pTarget = l_masterProcChipEntityPath.operator->(); + if(pMasterProc == NULL) + { + TARG_ERR("Failed to find acting master processor, given input node of " + "i_pNodeTarget = %p with HUID of 0x%08X",i_pNodeTarget, + i_pNodeTarget ? i_pNodeTarget->getAttr<ATTR_HUID>() : 0); + + /*@ + * @errortype + * @refcode LIC_REFCODE + * @subsys EPUB_FIRMWARE_SP + * @moduleid TARG_MOD_QUERY_MASTER_PROC_CHIP + * @reasoncode TARG_RC_TARGET_NOT_FOUND + * @userData1 HUID of Target Passed + * @devdesc Error: User Passed an invalid Node Target to find the + * master proc handle + */ + UTIL::createTracingError( + TARG_MOD_QUERY_MASTER_PROC_CHIP, + TARG_RC_TARGET_NOT_FOUND, + i_pNodeTarget ? i_pNodeTarget->getAttr<ATTR_HUID>() : 0, + 0,0,0, + pError); + break; + } + else + { + o_masterProcChipTargetHandle = pMasterProc; + } - o_masterProcChipTargetHandle = l_pTarget; + } while(0); + return pError; #undef TARG_FN } @@ -470,31 +889,36 @@ void TargetService::dump() const TARG_ASSERT(iv_initialized, TARG_ERR_LOC "USAGE: TargetService not initialized"); - TARG_INF("Targets (size=%d):", - sizeof(Target)*iv_maxTargets); + TARGETING::TargetRangeFilter l_allTargets( + TARGETING::targetService().raw_begin(), + TARGETING::targetService().raw_end(), + NULL); - for (uint32_t i = 0; i < iv_maxTargets; ++i) + uint32_t l_totalTargetCnt = 0; + for(;l_allTargets; ++l_allTargets) { + ++l_totalTargetCnt; TARG_INF( "[Target %d] " "Class = 0x%X, " "Type = 0x%X, " "Model = 0x%X", - i, - (*iv_targets)[i].getAttr<ATTR_CLASS>(), - (*iv_targets)[i].getAttr<ATTR_TYPE>(), - (*iv_targets)[i].getAttr<ATTR_MODEL>()); + l_totalTargetCnt, + l_allTargets->getAttr<ATTR_CLASS>(), + l_allTargets->getAttr<ATTR_TYPE>(), + l_allTargets->getAttr<ATTR_MODEL>()); + TARG_INF("Physical"); - (*iv_targets)[i].getAttr<ATTR_PHYS_PATH>().dump(); + l_allTargets->getAttr<ATTR_PHYS_PATH>().dump(); EntityPath l_entityPath; - if( (*iv_targets)[i].tryGetAttr<ATTR_AFFINITY_PATH>(l_entityPath) ) + if( l_allTargets->tryGetAttr<ATTR_AFFINITY_PATH>(l_entityPath) ) { TARG_INF("Affinity"); l_entityPath.dump(); } - if( (*iv_targets)[i].tryGetAttr<ATTR_POWER_PATH>(l_entityPath) ) + if( l_allTargets->tryGetAttr<ATTR_POWER_PATH>(l_entityPath) ) { TARG_INF("Power"); l_entityPath.dump(); @@ -502,24 +926,25 @@ void TargetService::dump() const DUMMY_RW_ATTR l_dummyRw; memset(l_dummyRw,0x00,sizeof(l_dummyRw)); - if ((*iv_targets)[i].tryGetAttr<ATTR_DUMMY_RW> (l_dummyRw)) + if (l_allTargets->tryGetAttr<ATTR_DUMMY_RW> (l_dummyRw)) { TARG_INF("Dummy = 0x%X", l_dummyRw[0][0][0]); } TARG_INF("Supports FSI SCOM = %d", - (*iv_targets)[i].getAttr<ATTR_PRIMARY_CAPABILITIES>() - .supportsFsiScom); + l_allTargets->getAttr< + ATTR_PRIMARY_CAPABILITIES>().supportsFsiScom); TARG_INF("Supports XSCOM SCOM = %d", - (*iv_targets)[i].getAttr<ATTR_PRIMARY_CAPABILITIES>() - .supportsXscom); + l_allTargets->getAttr< + ATTR_PRIMARY_CAPABILITIES>().supportsXscom); TARG_INF("Supports Inband SCOM = %d", - (*iv_targets)[i].getAttr<ATTR_PRIMARY_CAPABILITIES>() - .supportsInbandScom); + l_allTargets->getAttr< + ATTR_PRIMARY_CAPABILITIES>().supportsInbandScom); ScomSwitches l_switches = {0}; - if ( (*iv_targets)[i].tryGetAttr<ATTR_SCOM_SWITCHES>(l_switches) ) + if ( l_allTargets->tryGetAttr< + ATTR_SCOM_SWITCHES>(l_switches) ) { TARG_INF("Use FSI SCOM = %d",l_switches.useFsiScom); TARG_INF("Use XSCOM = %d",l_switches.useXscom); @@ -527,20 +952,22 @@ void TargetService::dump() const } uint64_t l_xscomBaseAddr = 0; - if ( (*iv_targets)[i].tryGetAttr<ATTR_XSCOM_BASE_ADDRESS>( - l_xscomBaseAddr) ) + if ( l_allTargets->tryGetAttr< + ATTR_XSCOM_BASE_ADDRESS>(l_xscomBaseAddr) ) { TARG_INF("XSCOM Base Address = 0x%016llX",l_xscomBaseAddr); } uint8_t l_Node_Id = 0; - if ( (*iv_targets)[i].tryGetAttr<ATTR_FABRIC_NODE_ID>(l_Node_Id)) + if ( l_allTargets->tryGetAttr< + ATTR_FABRIC_NODE_ID>(l_Node_Id)) { TARG_INF("XSCOM Node ID = 0x%X",l_Node_Id); } uint8_t l_Chip_Id = 0; - if ( (*iv_targets)[i].tryGetAttr<ATTR_FABRIC_CHIP_ID>(l_Chip_Id)) + if ( l_allTargets->tryGetAttr< + ATTR_FABRIC_CHIP_ID>(l_Chip_Id)) { TARG_INF("XSCOM Chip ID = 0x%X",l_Chip_Id); } @@ -564,7 +991,8 @@ bool TargetService::writeSectionData( bool l_response = false; if(i_pages.size() != 0) { - l_response = TARG_GET_SINGLETON(TARGETING::theAttrRP).writeSectionData(i_pages); + l_response = + TARG_GET_SINGLETON(TARGETING::theAttrRP).writeSectionData(i_pages); } TARG_EXIT(); @@ -576,14 +1004,15 @@ bool TargetService::writeSectionData( // TargetService::readSectionData //****************************************************************************** void TargetService::readSectionData( - std::vector <sectionRefData>& o_pages, - const SECTION_TYPE i_sectionId) + std::vector <sectionRefData>& o_pages, + const SECTION_TYPE i_sectionId, + const NODE_ID i_nodeId) { #define TARG_FN "readSectionData(...)" TARG_ENTER(); TARG_GET_SINGLETON(TARGETING::theAttrRP).readSectionData( - o_pages, i_sectionId); + o_pages, i_sectionId, i_nodeId); TARG_EXIT(); @@ -594,24 +1023,28 @@ void TargetService::readSectionData( // TargetService::_configureTargetPool //****************************************************************************** -void TargetService::_configureTargetPool() +void TargetService::_configureTargetPool( + NodeSpecificInfo& i_nodeInfoContainer) { #define TARG_FN "_configureTargetPool(...)" TARG_ENTER(); - _maxTargets(); + _maxTargets(i_nodeInfoContainer); // iv_pPnor--> points to uint32_t* --> points to --> uint32_t, targets[] // (uint32_t*)+1 --> points to ------------> targets[] const AbstractPointer<uint32_t>* ppNumTargets - = static_cast<const AbstractPointer<uint32_t>*>(iv_pPnor); - iv_targets = + = static_cast<const AbstractPointer<uint32_t>*>( + i_nodeInfoContainer.pPnor); + + i_nodeInfoContainer.targets = reinterpret_cast< Target(*)[] > ( (TARG_TO_PLAT_PTR_AND_INC(*ppNumTargets,1))); - TARG_ASSERT(iv_targets, TARG_ERR_LOC + + TARG_ASSERT(i_nodeInfoContainer.targets, TARG_ERR_LOC "FATAL: Could not determine location of targets"); - TARG_INF("iv_targets = %p", iv_targets); + TARG_INF("i_nodeInfoContainer.targets = %p", i_nodeInfoContainer.targets); // Only translate addresses on platforms where addresses are 4 bytes wide // (FSP). The compiler should perform dead code elimination of this path on @@ -619,13 +1052,14 @@ void TargetService::_configureTargetPool() // can be statically computed at compile time. if(TARG_ADDR_TRANSLATION_REQUIRED) { - iv_targets = static_cast<Target(*)[]>( - TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr( - iv_targets)); - TARG_ASSERT(iv_targets, TARG_ERR_LOC + i_nodeInfoContainer.targets = static_cast<Target(*)[]>( + TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr( + i_nodeInfoContainer.targets, i_nodeInfoContainer.nodeId)); + TARG_ASSERT(i_nodeInfoContainer.targets, TARG_ERR_LOC "FATAL: Could not determine location of targets after " "address translation"); - TARG_INF("iv_targets after translation = %p", iv_targets); + TARG_INF("i_nodeInfoContainer.targets after translation = %p", + i_nodeInfoContainer.targets); } TARG_EXIT(); @@ -637,14 +1071,15 @@ void TargetService::_configureTargetPool() // TargetService::_maxTargets //****************************************************************************** -uint32_t TargetService::_maxTargets() +void TargetService::_maxTargets(NodeSpecificInfo& io_nodeInfoContainer) { #define TARG_FN "_maxTargets(...)" // Target count found by following the pointer pointed to by the iv_pPnor // pointer. const AbstractPointer<uint32_t>* pNumTargetsPtr - = static_cast<const AbstractPointer<uint32_t>*>(iv_pPnor); + = static_cast<const AbstractPointer<uint32_t>*>( + io_nodeInfoContainer.pPnor); uint32_t* pNumTargets = TARG_TO_PLAT_PTR(*pNumTargetsPtr); // Only translate addresses on platforms where addresses are 4 bytes wide @@ -655,18 +1090,16 @@ uint32_t TargetService::_maxTargets() { pNumTargets = static_cast<uint32_t*>( TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr( - pNumTargets)); + pNumTargets, io_nodeInfoContainer.nodeId)); } TARG_ASSERT(pNumTargets, TARG_ERR_LOC "FATAL: Could not determine location of targets after " "address translation"); - iv_maxTargets = *pNumTargets; - - TARG_INF("Max targets = %d",iv_maxTargets); + io_nodeInfoContainer.maxTargets = *pNumTargets; - return iv_maxTargets; + TARG_INF("Max targets = %d", io_nodeInfoContainer.maxTargets); #undef TARG_FN } @@ -687,17 +1120,26 @@ void TargetService::_getInwards( while (i_entityPath.size() > 1) { i_entityPath.removeLast(); - for (uint32_t i = 0; i < iv_maxTargets; ++i) + + TargetIterator l_allTargets; + + for(l_allTargets = targetService().begin(); + l_allTargets != targetService().end(); + ++l_allTargets) { EntityPath l_candidatePath; - bool l_candidateFound = tryGetPath(i_attr, &(*iv_targets)[i], - l_candidatePath); - if ( l_candidateFound - && (l_candidatePath == i_entityPath) - && ( (i_pPredicate == NULL) - || (*i_pPredicate)( &(*iv_targets)[i]) ) ) + bool l_candidateFound = false; + + l_candidateFound = tryGetPath(i_attr, + (*l_allTargets), + l_candidatePath); + + if ( (l_candidateFound) + && (l_candidatePath == i_entityPath) + && ( (i_pPredicate == NULL) + || (*i_pPredicate)(*l_allTargets) ) ) { - o_list.push_back(&(*iv_targets)[i]); + o_list.push_back(*l_allTargets); break; } } @@ -722,40 +1164,267 @@ void TargetService::_getOutwards( const PredicateBase* const i_pPredicate, TargetHandleList& o_list) const { - #define TARG_FN "_getOutwards()...)" + #define TARG_FN "_getOutwards(...)" + do + { + // If at max depth (a leaf path element), no children possible + if (i_entityPath.size() >= EntityPath::MAX_PATH_ELEMENTS) + { + break; + } - do { + // Find the children (immediate, or all), depending on recursion level + TargetIterator l_allTargets; - // If at max depth (a leaf path element), no children possible - if (i_entityPath.size() >= EntityPath::MAX_PATH_ELEMENTS) + for(l_allTargets = targetService().begin(); + l_allTargets != targetService().end(); + ++l_allTargets) + { + EntityPath l_candidatePath; + bool l_candidateFound = tryGetPath(i_attr, *l_allTargets, + l_candidatePath); + if (l_candidateFound) + { + if ( ( (i_recursionLevel == IMMEDIATE) + && (l_candidatePath.size() == i_entityPath.size() +1)) + || ( (i_recursionLevel == ALL) + && (l_candidatePath.size() > i_entityPath.size()))) + { + if (i_entityPath.equals(l_candidatePath,i_entityPath.size()) + && ( (i_pPredicate == NULL) + || (*i_pPredicate)(*l_allTargets) ) ) + { + o_list.push_back(*l_allTargets); + } + } + } + } + + } while (0); + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::setMasterNode +//****************************************************************************** +errlHndl_t TargetService::setMasterNode(const Target* i_pTarget) +{ + #define TARG_FN "setMasterNode(...)" + errlHndl_t pError = NULL; + + TARG_ASSERT(i_pTarget != NULL, TARG_ERR_LOC + "Error: User cannot pass NULL Target in place of Node Target"); + + // Check for Node Target + PredicateCTM l_nodePredicate(CLASS_ENC, TYPE_NODE); + if(l_nodePredicate(i_pTarget)) { - break; + pError = UTIL::setMasterNode(const_cast<Target*>(i_pTarget)); + if(pError) + { + TARG_ERR("Master Node Attribute Set Failed for Node [0x%08X]", + i_pTarget->getAttr<ATTR_HUID>()); + } + } + else + { + // Create Error + /*@ + * @errortype + * @refcode LIC_REFCODE + * @subsys EPUB_FIRMWARE_SP + * @moduleid TARG_MOD_SET_MASTER_NODE + * @reasoncode TARG_RC_INVALID_NODE + * @userData1 HUID of Target Passed + * @devdesc Error: User Passed an invalid Node Target + */ + UTIL::createTracingError( + TARG_MOD_SET_MASTER_NODE, + TARG_RC_INVALID_NODE, + i_pTarget->getAttr<ATTR_HUID>(), + 0,0,0, + pError); } - // Find the children (immediate, or all), depending on recursion level - for (uint32_t i = 0; i < iv_maxTargets; ++i) + return pError; + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::isNonMasterNodeSystemTarget +//****************************************************************************** + +bool TargetService::isNonMasterNodeSystemTarget(const Target* i_pTarget) const +{ + #define TARG_FN "isNonMasterNodeSystemTarget(...)" + + Target* l_pTarget = const_cast<Target*>(i_pTarget); + bool l_isNonMasterNodeSystemTarget = false; + TARG_ASSERT(l_pTarget != NULL, TARG_ERR_LOC + "Cannot pass a NULL Target"); + + if( (l_pTarget->getAttr<ATTR_CLASS>() == CLASS_SYS) && + (l_pTarget->getAttr<ATTR_TYPE>() == TYPE_SYS) ) { - EntityPath l_candidatePath; - bool l_candidateFound = tryGetPath(i_attr, &(*iv_targets)[i], - l_candidatePath); - if (l_candidateFound) + if(true == UTIL::isNonMasterNodeSystemTarget(i_pTarget)) { - if ( ( (i_recursionLevel == IMMEDIATE) - && (l_candidatePath.size() == i_entityPath.size() + 1)) - || ( (i_recursionLevel == ALL) - && (l_candidatePath.size() > i_entityPath.size()))) + l_isNonMasterNodeSystemTarget = true; + } + } + return l_isNonMasterNodeSystemTarget; + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::getNumInitializedNodes +//****************************************************************************** + +uint8_t TargetService::getNumInitializedNodes() const +{ + #define TARG_FN "getNumInitializedNodes(...)" + return MAX_NODE_ID; + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::initDefaultMasterNode +//****************************************************************************** + +void TargetService::initDefaultMasterNode() +{ + #define TARG_FN "initDefaultMasterNode(...)" + TARG_ENTER(); + errlHndl_t pError = NULL; + if(!iv_initialized) + { + TARG_INF("Default Master Node Selection Mode"); + + // See if we already have a persistent Master node from previous run + // We have to go via this route since iv_initialized flag is not set, + // so we can't use any targetservice api to do this. Have to manual go + // over. + for(uint8_t l_nodeCnt=0; l_nodeCnt<MAX_NODE_ID; ++l_nodeCnt) + { + if((iv_nodeInfo[l_nodeCnt].initialized) && + (iv_nodeInfo[l_nodeCnt].maxTargets > 0)) { - if ( i_entityPath.equals(l_candidatePath,i_entityPath.size()) - && ( (i_pPredicate == NULL) - || (*i_pPredicate)( &(*iv_targets)[i]) ) ) + for(uint32_t l_targetCnt=0; + l_targetCnt<iv_nodeInfo[l_nodeCnt].maxTargets; + ++l_targetCnt) + { + if(((*(iv_nodeInfo[l_nodeCnt].targets))[ + l_targetCnt].getAttr<ATTR_CLASS>() == CLASS_ENC) && + ((*(iv_nodeInfo[l_nodeCnt].targets))[ + l_targetCnt].getAttr<ATTR_TYPE>() == TYPE_NODE)) + { + if(UTIL::isThisMasterNodeTarget( + &((*(iv_nodeInfo[l_nodeCnt].targets))[l_targetCnt]))) + { + // We have found a previous instance of master node + // target, no need for sync here, since it would + // have been taken care of when we updated the + // master node last time around. + iv_initialized = true; + TARG_INF("Previous Master Node Instance Found - " + "Node [%d]", l_nodeCnt); + break; + } + } + } + if(iv_initialized) + { + break; + } + } + } + if(!iv_initialized) + { + TARG_INF("No previous master node found.. Setting a default one"); + for(uint8_t l_nodeCnt=0; l_nodeCnt<MAX_NODE_ID; ++l_nodeCnt) + { + if((iv_nodeInfo[l_nodeCnt].initialized) && + (iv_nodeInfo[l_nodeCnt].maxTargets > 0)) { - o_list.push_back(&(*iv_targets)[i]); + // Need to go over each target to search for Node, cannot + // use rangefilter here since targeting is yet not + // initialized. + for(uint32_t l_targetCnt=0; + l_targetCnt<iv_nodeInfo[l_nodeCnt].maxTargets; + ++l_targetCnt) + { + if(((*(iv_nodeInfo[l_nodeCnt].targets))[ + l_targetCnt].getAttr<ATTR_CLASS>() == CLASS_ENC) && + ((*(iv_nodeInfo[l_nodeCnt].targets))[ + l_targetCnt].getAttr<ATTR_TYPE>() == TYPE_NODE)) + { + // Just do bare minimum stuff i.e. just set the + // Master Node Attribute + pError = UTIL::setDefaultMasterNodeWithoutSync( + &((*(iv_nodeInfo[l_nodeCnt].targets))[ + l_targetCnt])); + if(pError) + { + TARG_ERR("Setting of default master node " + "target failed"); + TARG_ASSERT(0, TARG_ERR_LOC + "Default Master Node Set Failed at" + " Init time"); + } + iv_initialized = true; + break; + } + } + if(iv_initialized == true) + { + // We have setted the default Master Node, let's just + // sync it up. + // Above we had to callup special mode to set Master + // node, since targeting is not initalized yet, cannot + // use the basic features of predicates, rangefilter + // and all. + Target* l_pSysTarget = NULL; + getTopLevelTarget(l_pSysTarget); + TARG_ASSERT(l_pSysTarget != NULL, TARG_ERR_LOC + "Top Level Target cannot be NULL"); + pError = UTIL::SyncMasterSystemTarget(l_pSysTarget); + if(pError) + { + TARG_ASSERT(0, TARG_ERR_LOC + "System Target Sync has failed at Init Time"); + } + break; + } } } } } + else + { + TARG_INF("TargetService already initialized"); + } + TARG_EXIT(); + #undef TARG_FN +} - } while (0); +//****************************************************************************** +// TargetService::getMasterNodeTarget +//****************************************************************************** + +void TargetService::getMasterNodeTarget( + Target*& o_masterNodeTarget) const +{ + #define TARG_FN "getMasterNodeTarget(...)" + + TARG_ASSERT(iv_initialized, TARG_ERR_LOC + "USAGE: TargetService not initialized"); + + // Keep the user target handle initialize to NULL + o_masterNodeTarget = NULL; + UTIL::getMasterNodeTarget(o_masterNodeTarget); + + TARG_ASSERT(o_masterNodeTarget != NULL, TARG_ERR_LOC + "Node Target of the System's Master Node cannot be NULL"); #undef TARG_FN } |

