diff options
author | Nick Bofferding <bofferdn@us.ibm.com> | 2013-09-06 16:25:14 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-10-08 16:37:41 -0500 |
commit | 31a07e2cc87a0a24099b6e8d7ccc5cb3d0729b67 (patch) | |
tree | c0d1847802950d4ff41cdc1bc4eed8933a1f5774 | |
parent | 6b7a65cc7ec85b4937c444dd7f3bb8424b9255ab (diff) | |
download | talos-hostboot-31a07e2cc87a0a24099b6e8d7ccc5cb3d0729b67.tar.gz talos-hostboot-31a07e2cc87a0a24099b6e8d7ccc5cb3d0729b67.zip |
Support multinode targeting
- Added support for master processor type attributes
- Made attribute sync multinode aware
- Added platform properties constants
- Added multinode iterator support
- Extended default iterator to skip hidden system targets
- Added raw iterator to "see" hidden system targets
- Updated target service to be multinode aware
- Added new API to query master proc per node
- Modified MRW parser to support cross node peers
- Modified MRW parser to default master proc per node
- Removed cross node peer workarounds in node splitter script
- Added common support for master system targets
- Updated attribute compiler to serialize cross node peer targets
- Updated attribute compiler to generate attribute size map
- Updated attribute compiler to impose special ordering on target layout
- Inhibited XML merge script from merging itself in xmltohb makefile
- Inhibited duplicate weak symbol errors in trace statements
Change-Id: I661eca12f3a7cc16c0ff5476a7ae66cea3bad7d3
RTC: 63940
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/6103
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
30 files changed, 2574 insertions, 467 deletions
diff --git a/src/build/linker/linker.C b/src/build/linker/linker.C index e0ca2adc2..2a4c3ad16 100644 --- a/src/build/linker/linker.C +++ b/src/build/linker/linker.C @@ -374,8 +374,10 @@ int main(int argc, char** argv) j != all_symbols.end(); ++j) { - if ((string::npos != j->find(sym_name)) && - (*i != *j)) + if ( (string::npos != j->find(sym_name)) + && ( string::npos + == j->find("traceData_codeInfo")) + && (*i != *j)) { cout << "\tDuplicate member found: " << *j << endl; throw std::runtime_error( diff --git a/src/include/usr/targeting/attrrp.H b/src/include/usr/targeting/attrrp.H index 80394cb9b..f1d8388f3 100644 --- a/src/include/usr/targeting/attrrp.H +++ b/src/include/usr/targeting/attrrp.H @@ -40,7 +40,6 @@ #include <targeting/common/targetservice.H> #include <targeting/attrsync.H> - namespace TARGETING { @@ -61,14 +60,15 @@ struct AttrRP_Section; */ class AttrRP { - + // add some friends for the attribute sync features - friend bool TargetService::writeSectionData( + friend bool TargetService::writeSectionData( const std::vector<sectionRefData>& i_pages ); - friend void TargetService::readSectionData( + friend void TargetService::readSectionData( std::vector<sectionRefData>& o_pages, - const SECTION_TYPE i_sectionId); + const SECTION_TYPE i_sectionId, + const TARGETING::NODE_ID i_nodeId); public: @@ -76,10 +76,38 @@ class AttrRP * @brief Returns base address of the RO section containing the * targets * + * @param[in] i_nodeIdUnused + * Node ID to get base address for, ignored by Hostboot, which + * always gets base address of local node + * * @return Base address of the RO section containing the targets as * a void* */ - void* getBaseAddress(); + void* getBaseAddress(const NODE_ID i_nodeIdUnused); + + /** + * @brief Translates given address, according to the resource + * provider's translation algorithm + * + * @param[in] i_pAddress + * Address to translate + * + * @param[in] i_pUnused + * Node target used by common code, unused in Hostboot + * + * @return void* Returns the translated address. Common attribute + * code has a static, compile time check that is used to + * determine whether to call this function, however the Hostboot + * compiler complains when this is not provided. Therefore + * while this method exists, Hostboot will never call it, and if + * it does it will always get a no-op translation. + */ + void* translateAddr( + void* i_pAddress, + const Target* i_pUnused) + { + return i_pAddress; + } /** * @brief Translates given address, according to the resource @@ -88,6 +116,9 @@ class AttrRP * @param[in] i_pAddress * Address to translate * + * @param[in] i_unused + * Node ID used by common code, unused in Hostboot + * * @return void* Returns the translated address. Common attribute * code has a static, compile time check that is used to * determine whether to call this function, however the Hostboot @@ -96,7 +127,8 @@ class AttrRP * it does it will always get a no-op translation. */ void* translateAddr( - void* i_pAddress) + void* i_pAddress, + const TARGETING::NODE_ID i_unused) { return i_pAddress; } @@ -125,7 +157,7 @@ class AttrRP */ AttrRP() : iv_msgQ(NULL), iv_sections(NULL), iv_sectionCount(0) - { + { }; /** @@ -159,12 +191,16 @@ class AttrRP * for the data pages specified by the selected section * * @param[out] o_pages, vector of sectionRefData struct + * @param[in] i_sectionType + * Type of section to read + * @param[in] Node associated with the section, unused in HB * * @return void */ void readSectionData( - std::vector <sectionRefData>& o_pages, - const SECTION_TYPE i_sectionType); + std::vector <sectionRefData>& o_pages, + const SECTION_TYPE i_sectionType, + const NODE_ID i_nodeId = 0) const; private: @@ -203,7 +239,7 @@ class AttrRP * * @return errlHndl_t * Returns an error log handle that is NULL on success or !NULL - * on failure + * on failure */ errlHndl_t parseAttrSectHeader(); @@ -226,7 +262,7 @@ class AttrRP * * @par Detailed Description: * This function, being static, can be called from task_create - * and is used to enter the daemon thread's msgServiceTask + * and is used to enter the daemon thread's msgServiceTask * loop to process messages. * * @param[in] i_pInstance diff --git a/src/include/usr/targeting/common/iterators/iterators.H b/src/include/usr/targeting/common/iterators/iterators.H index 5339b33dd..85742c63c 100644 --- a/src/include/usr/targeting/common/iterators/iterators.H +++ b/src/include/usr/targeting/common/iterators/iterators.H @@ -1,25 +1,25 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/include/usr/targeting/common/iterators/iterators.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/targeting/common/iterators/iterators.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #ifndef __TARGETING_COMMON_ITERATORS_H #define __TARGETING_COMMON_ITERATORS_H @@ -31,6 +31,7 @@ */ #include <targeting/common/iterators/targetiterator.H> +#include <targeting/common/iterators/rawtargetiterator.H> #include <targeting/common/iterators/rangefilter.H> // please keep up to date... diff --git a/src/include/usr/targeting/common/iterators/rawtargetiterator.H b/src/include/usr/targeting/common/iterators/rawtargetiterator.H new file mode 100644 index 000000000..f7e9f192e --- /dev/null +++ b/src/include/usr/targeting/common/iterators/rawtargetiterator.H @@ -0,0 +1,140 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/targeting/common/iterators/rawtargetiterator.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __RAW_TARGETING_COMMON_TARGETITERATOR_H +#define __RAW_TARGETING_COMMON_TARGETITERATOR_H + +/** + * @file targeting/common/iterators/rawtargetiterator.H + * + * @brief Interface describing rawiterator/const rawiterator used to iterate + * through all target service targets + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stddef.h> + +// Other Host Boot Components +#include <builtins.h> + +// Targeting Component +#include <targeting/common/iterators/targetiterator.H> + +//****************************************************************************** +// Macros +//****************************************************************************** + +#undef TARG_NAMESPACE +#undef TARG_CLASS +#undef TARG_FUNC + +//****************************************************************************** +// Interface +//****************************************************************************** + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" + +#define TARG_CLASS "_TargetRawIterator<T>::" + +class Target; + +/** + * @brief Class which iterates through targets managed by the target service. + * Provides "Target*" and "const Target*" versions via templates + */ +template<typename T> +class _TargetRawIterator : public _TargetIterator<T> +{ + public: + + /** + * @brief Maps type of iterated element to common alias (Target* or + * const Target*) + */ + typedef T iterator; + typedef T value_type; + + /** + * @brief Create an iterator to a (const/non-const) target handle. + * Defaults to end() + */ + ALWAYS_INLINE + _TargetRawIterator() + : iv_pCurrent(NULL) + { + } + + /** + * @brief Create an iterator to a (const/non-const) target handle + * + * @param[in] i_pTarget Target handle (pointer or const pointer + * depending on flavor) the iterator should reference + */ + ALWAYS_INLINE + explicit _TargetRawIterator(T i_pTarget) + : iv_pCurrent(i_pTarget) + { + } + + /** + * @brief Destroy an iterator to a (const/non-const) target handle + * + * @note Iterator does not own any resources to destroy + */ + ALWAYS_INLINE + ~_TargetRawIterator() + { + } + + + private: + + /** + * @brief Advance the iterator to point to the next item maintained by + * the target service (or end() if end of list) + */ + void advance(); + + T iv_pCurrent; // Pointer to current target +}; + +/** + * @brief Type aliases to simplify user code + */ +typedef _TargetRawIterator<Target*> TargetRawIterator; +typedef _TargetRawIterator<const Target*> ConstTargetRawIterator; + +#undef TARG_CLASS +#undef TARG_NAMESPACE + +} // End namespace TARGETING + +#endif // __RAW_TARGETING_COMMON_TARGETITERATOR_H + diff --git a/src/include/usr/targeting/common/iterators/targetiterator.H b/src/include/usr/targeting/common/iterators/targetiterator.H index 8b3463f70..65e80b8b5 100644 --- a/src/include/usr/targeting/common/iterators/targetiterator.H +++ b/src/include/usr/targeting/common/iterators/targetiterator.H @@ -95,6 +95,9 @@ class _TargetIterator * * @param[in] i_pTarget Target handle (pointer or const pointer * depending on flavor) the iterator should reference + * + * @note User should not assign a hidden system target to the iterator, + * as it does not support hidden targets */ ALWAYS_INLINE inline explicit _TargetIterator(T i_pTarget) diff --git a/src/include/usr/targeting/common/target.H b/src/include/usr/targeting/common/target.H index f3f9be002..ffeecd340 100644 --- a/src/include/usr/targeting/common/target.H +++ b/src/include/usr/targeting/common/target.H @@ -557,16 +557,17 @@ class Target static AttributeTank cv_overrideTank; static AttributeTank cv_syncTank; - friend class PnorBuilderService; - - // Friend functions to allow FAPI Attribute code to directly call - // _tryGetAttr and _trySetAttr for code size optimization - friend fapi::ReturnCode fapi::platAttrSvc::getTargetingAttr( - const fapi::Target *, TARGETING::ATTRIBUTE_ID, const uint32_t, - void *); - friend fapi::ReturnCode fapi::platAttrSvc::setTargetingAttr( - const fapi::Target *, TARGETING::ATTRIBUTE_ID, const uint32_t, - void *); + friend class PnorBuilderService; + friend class TargetCloner; + + // Friend functions to allow FAPI Attribute code to directly call + // _tryGetAttr and _trySetAttr for code size optimization + friend fapi::ReturnCode fapi::platAttrSvc::getTargetingAttr( + const fapi::Target *, TARGETING::ATTRIBUTE_ID, const uint32_t, + void *); + friend fapi::ReturnCode fapi::platAttrSvc::setTargetingAttr( + const fapi::Target *, TARGETING::ATTRIBUTE_ID, const uint32_t, + void *); /* * @brief allow targetattrbulksync access to the target class store. diff --git a/src/include/usr/targeting/common/targetservice.H b/src/include/usr/targeting/common/targetservice.H index 416aeff5d..6dd2cd2f0 100644 --- a/src/include/usr/targeting/common/targetservice.H +++ b/src/include/usr/targeting/common/targetservice.H @@ -44,9 +44,11 @@ // This component #include <targeting/common/attributes.H> +#include <attributetraits.H> #include <targeting/common/iterators/iterators.H> #include <targeting/common/predicates/predicates.H> #include <targeting/adapters/types.H> +#include <targeting/common/error.H> #include <pnortargeting.H> //****************************************************************************** @@ -61,6 +63,24 @@ namespace TARGETING { class TargetService; + /* + * @brief - typedef for node Id + */ + typedef uint8_t NODE_ID; + + /* Node 0 */ + static const NODE_ID NODE0 = 0x00; + + /* Invalid Node Id - to initialize struct variable*/ + static const NODE_ID INVALID_NODE = 0xFF; + + /* Invalid Section Id - to initialize struct variable */ + static const uint8_t INVALID_SECTIONID = 0xFF; + + // Special "not found" fabric node ID is the data type with all bits set + static const ATTR_FABRIC_NODE_ID_type FABRIC_NODE_ID_NOT_FOUND = + INVALID_NODE; + /** * @brief Struct specifying different parameters required for section data * update on the sectionId/NodePtr. @@ -71,6 +91,7 @@ namespace TARGETING * * Struct element details - * sectionId - Section Id + * nodeId - Node Id * pageNumber - PageNumber for the section. * padBytes - PadBytes to fill in 2 extra bytes * dataPtr - Data Ptr @@ -80,11 +101,21 @@ namespace TARGETING struct sectionRefData { - uint8_t sectionId; - uint8_t pageNumber; - uint8_t padBytes[2]; + sectionRefData() : + sectionId(0x00), + nodeId(INVALID_NODE), + pageNumber(0), + dataPtr(NULL), + pNodeTarget(NULL) + { + } + + uint8_t sectionId; + uint8_t nodeId; + uint8_t pageNumber; + uint8_t padBytes; uint8_t* dataPtr; - Target* pNodeTarget; + Target* pNodeTarget; }; @@ -178,15 +209,22 @@ class TargetService /** * @brief Initializes the target service * + * @par Detailed Description: * Initializes the target service, including determining maximum number - * of targets, setting up the target pool, etc. Should be called - * once PNOR is accessible can be mapped + * of targets, setting up the target pool, etc. for each node in the + * system blueprint local to the subsystem. Should be called once PNOR + * is accessible and can be mapped + * + * @param[in] i_maxNodes, max number of nodes to initialize within the + * targetservice. * * @pre N/A * - * @post Target service fully initialized with all possible targets + * @post Target service initialized with all possible targets. User + * would need to call targetservice().initDefaultMasterNode to make + * targetservice fully initialized and ready to be used. */ - void init(); + void init(const size_t i_maxNodes = 1); /** * @brief Returns whether target service has initialized or not @@ -204,48 +242,90 @@ class TargetService /** * @brief Map iterator types to common aliases */ - typedef TargetIterator iterator; - typedef ConstTargetIterator const_iterator; + typedef TargetIterator iterator; + typedef ConstTargetIterator const_iterator; + typedef TargetRawIterator rawiterator; + typedef ConstTargetRawIterator const_rawiterator; /** * @brief Return iterator which points to first target service target * (or end() if none) - * + * * @return Iterator pointing to first target service target */ iterator begin(); - + + /** + * @brief Return rawiterator which points to first target service + * target (or end() if none) + * + * @return RawIterator pointing to first target service target + */ + rawiterator raw_begin(); + /** * @brief Return iterator to const which points to first target service * target (or end() if none) - * + * * @return Iterator to const pointing to first target service target - */ + */ const_iterator begin() const; /** + * @brief Return rawiterator to const which points to first target + * service target (or end() if none) + * + * @return RawIterator to const pointing to first target service target + */ + const_rawiterator raw_begin() const; + + /** * @brief Return iterator which points to the "past the end of the * list" target maintained by the target service - * + * * @return Iterator pointing to the "past the end of the list" target * maintained by the target service */ iterator end(); - + + /** + * @brief Return rawiterator which points to the "past the end of the + * list" target maintained by the target service + * + * @return RawIterator pointing to the "past the end of the list" + * target maintained by the target service + */ + rawiterator raw_end(); + /** * @brief Return iterator to const which points to the "past the end of * the list" target maintained by the target service - * + * * @return Iterator to const pointing to the "past the end of the list" * target maintained by the target service */ const_iterator end() const; /** + * @brief Return rawiterator to const which points to the "past the end + * of the list" target maintained by the target service + * + * @return RawIterator to const pointing to the "past the end of the + * list" target maintained by the target service + */ + const_rawiterator raw_end() const; + + /** * @brief Allow iterator access to the target service's target store */ - friend class _TargetIterator<Target*>; - friend class _TargetIterator<const Target*>; + friend class _TargetIterator<Target*>; + friend class _TargetIterator<const Target*>; + + /** + * @brief Allow rawiterator access to the target service's target store + */ + friend class _TargetRawIterator<Target*>; + friend class _TargetRawIterator<const Target*>; /** * @brief Returns the top level physical target @@ -323,18 +403,56 @@ class TargetService * * @param[out] o_masterProcChipTarget Target handle referring to the * current master processor chip (the one connected to PNOR) - * @param[in] i_node Node that this master resides on (default - * is 0) + * @param[in] i_pNodeTarget + * Handle to the node target to search for the acting master + * processor. If NULL, HB will search whatever node it's + * running on, and FSP will search the physical drawer containing + * the lowest ordered fabric node ID. * + * @pre Target Service must be initialized + * + * @post Master processor chip target returned or NULL is returned if + * targetservice is not yet initialized or user passed an invalid node + * target to get the master proc handle + */ + void masterProcChipTargetHandle( + Target*& o_masterProcChipTargetHandle, + const Target* i_pNodeTarget = NULL) const; + + /** + * @brief Returns the master processor chip target handle + * + * Returns the master processor chip target handle for the given (or + * defaulted) node. On nodes without an alternate master, + * it returns a handle to the only master, if found (NULL otherwise). + * On nodes with multiple potential + * masters, it returns a target handle to the acting master (NULL + * otherwise). If targeting information is not yet accessible (very + * early in the host boot IPL), the returned target handle will be a + * sentinel value representing the master (whichever it may be) * - * @pre None + * @param[out] o_masterProcChipTarget + * Target handle of acting master processor chip for the given + * node (the one connected to PNOR) + * @param[in] i_pNodeTarget + * Target handle of node to search. If NULL, HB will search + * whatver node it's running on, andFSP will search the physical + * drawer containing the lowest orderd fabric node ID * - * @post Master processor chip targets returned or a dummy value + * @pre Target Service must be initialized + * + * @post Master processor chip target returned or a dummy value * representing the acting master processor chip if the targeting * information is not yet initialized + * + * @return Error log handle indicating the status of the request + * + * @retval NULL Success, Master Proc handle is returned to the user + * @retval !NULL Failure, Failed to find the Master Proc Handle & NULL + * is returned to user */ - void masterProcChipTargetHandle( - Target*& o_masterProcChipTargetHandle, - uint8_t i_node = 0) const; + errlHndl_t queryMasterProcChipTargetHandle( + Target*& o_masterProcChipTargetHandle, + const Target* i_pNodeTarget = NULL) const; /** * @brief Returns whether the specified entity path attribute exists @@ -391,10 +509,10 @@ class TargetService * @param[in] i_recursionLevel Whether to return candidate targets * immediately associated to the specified target or recursively * associated to it. - * @param[in] i_pPredicate Pointer to a predicate to be evaluated + * @param[in] i_pPredicate Pointer to a predicate to be evaluated * against each candidate target (as determined by the source * target, type, and recursion level parameters). If the predicate - * returns true, the target will be added to the result list. A + * returns true, the target will be added to the result list. A * value of NULL acts as a predicate that always returns true. * * @pre N/A @@ -423,7 +541,7 @@ class TargetService * This is the top level interface, would basically call the lower * level attribute resource provider interface. The lower level * interface would fetch each vector element and update each section - * with corresponding data from the offset specified. + * with corresponding data from the offset specified. * * @param[in] i_pages, vector of sectionRefData struct * @@ -450,6 +568,7 @@ class TargetService * * @param[out] o_pages, vector of sectionRefData struct * @param[in] i_sectionId, section type + * @param[in] i_nodeId, node Id * * @pre N/A * @@ -461,11 +580,167 @@ class TargetService */ void readSectionData(std::vector<sectionRefData>& o_pages, - const SECTION_TYPE i_sectionId); + const SECTION_TYPE i_sectionId, + const NODE_ID i_nodeId = NODE0); + + /** + * @brief Get the Next initialized node in the Target Service + * This is to support the iterator + * + * It takes the present node id as input and computes the next + * incremental caller-visible node available in the system and + * return it to the user + * + * @param[in] i_nodeId, present node Id + * + * @return returns uint8_t as next node + * + * @retval success case, Node Id, returns the next incremental + * initialized caller-visible node available + * @retval, Failure case, invalid node, if the present node is the + * last initialized caller-visible node available in incremental + * order or user passed an invalid nodeId + */ + NODE_ID getNextInitializedNode(const NODE_ID i_node) const; + + /** + * @brief Get the Next caller-visible Target Handle in incremental + * order. This is to support the iterator. + * + * It is take a target handle as input and compute the next incremental + * available caller-visible target handle in the system and return it + * to the user. + * + * @param[in] i_pTarget, non-NULL Target Handle + * + * @return Target Handle + * + * @retval Target*, returns the next incremental caller-visible + * Target Handle + * @retval NULL, if the target handle passed is the last visible + * target handle available in incremental order in the target service. + */ + Target* getNextTarget(const Target* i_pTarget) const; + + /** + * @brief Sets the isMasterNode Attribute to the Node Target handle + * Passed and takes care of syncing master node's system target handle + * with non-master system target handles. + * + * @par Detailed Description + * It takes the node target handle as input which is required to set as + * master node and sets the isMasterNode Attribute associated to true + * and also unset the isMasterNode associated with all current master + * node target handle. Along with this it also takes care of syncing + * master node's system target attributes with non-master node system + * target's attribute in the system. + * + * @param[in] i_pTarget, Non-Null Node Target handle + * + * @return error handle is return + * @retval Success case, NULL is returned means the master node set and + * sync is successful + * @return, Failure case, !NULL error handle is returned means the + * master node couldn't be set as desired. + */ + errlHndl_t setMasterNode(const Target* i_pTarget); + + /** + * @brief this gives the information whether a system target is + * master-node's system target or non-master-node's system target + * + * It is takes system target handle as input and checks whether the + * system target is from master-node target tree or non-master node + * target tree. + * + * @param[in] i_pTarget, Non-Null System Target handle + * + * @return true, means the system target passed is a non-master node's + * system target. + * @return false, means the system target passed is a master node's + * system target. + */ + bool isNonMasterNodeSystemTarget(const Target* i_pTarget) const; + + /* + * @brief give the total number of nodes in the targeting service + * for which node level binaries have been initialized . + * + * @return total number of nodes in the targeting model initiailized. + */ + uint8_t getNumInitializedNodes() const; + + /** + * @brief set the default Master Node and release the intialize flag + * for targetservice + * + * @par Detailed Description: + * Searches for previous instance of master node, else sets the default + * node (i.e. first initialized node) as master node. And then releases + * the initialized flag of targetservice, Intializing targetservice + * fully + * + * @pre targetservice().init() should have been called before this. + * + * @post Target servicei is fully initialized along with a default + * master node. + */ + + void initDefaultMasterNode(); + + /** + * @brief Returns the Node Target handle of the Master node in the + * system. + * + * @par Detailed Description: + * Returns the Node Target handle of the Master node in the system. + * Caller must check for NULL Target handle + * + * @param[out] o_masterNodeTarget node target handle of the master node + * in the system + * + * @pre TargetService must be initialized. + * + * @post Returns the node target handle of the master node. User + * will always get a valid target else targetservice will assert. + * + * @return void + */ + void getMasterNodeTarget(Target*& o_masterNodeTarget) const; + private: /** + * @brief Structure, Node information specific + */ + struct NodeSpecificInfo + { + + NodeSpecificInfo() : + nodeId(INVALID_NODE), + initialized(false), + isMasterNode(false), + targets(NULL), + maxTargets(0), + pPnor(NULL) + { + } + + NODE_ID nodeId; ///< Node Id for the binary file + bool initialized; ///< Is service initialized or not + bool isMasterNode; ///< Is this the master node + Target (*targets)[]; ///< Pointer to array of target objects + uint32_t maxTargets; ///< Maximum # target objects in the array + const void* pPnor; ///< Pointer to the PNOR targeting section + }; + + /** + * @brief Node Specific information container + */ + typedef std::vector< NodeSpecificInfo > NodeInfo_t; + + /** * @brief Enum specifying which direction to traverse associations * between targets * @@ -506,17 +781,36 @@ class TargetService typedef std::vector< AssociationAttrMap > AssociationMappings_t; /** + * @brief Returns the first Target from the first initialized node + * from the pool of targets. + * + * param[out] o_firstTargetPtr First Target handle + * + * @pre Target service must be initialized + * + * @post Target Service returns the first Target from the first + * initialized node. + * + * @returns void + */ + void _getFirstTargetForIterators (Target*& o_firstTargetPtr) const; + + /** * @brief Configures the pool of targets * * This function computes the maximum number of targets possible based * on the PNOR (or override) image, and updates the target service to * point to the start of the target array, wherever it may reside * + * @param[in] i_nodeInfoContainer, struct to contain all node + * specific information of the type NodeSpecificInfo. May refer to + * structure definition + * * @pre Target service must not be initialized * * @post Target service target pool configured for access */ - void _configureTargetPool(); + void _configureTargetPool(NodeSpecificInfo& i_nodeInfoContainer); /** * @brief Computes the maximum number of targets, caches the value @@ -525,14 +819,17 @@ class TargetService * Computes the maximum number of targets possible based on the PNOR * (or override) image and returns it to the caller * + * @param[in/out] io_nodeInfoContainer, struct to contain all node + * specific information of the type NodeSpecificInfo. May refer to + * structure definition + * * @pre Target service must not already be initialized * - * @post Target service updated with maximum target count. Count also - * returned to caller + * @post Target service updated with maximum target count in + * nodeContainer. * - * @return uint32_t indicating the maximum number of targets possible */ - uint32_t _maxTargets(); + void _maxTargets(NodeSpecificInfo & io_nodeInfoContainer); /** * @brief Returns handles to the targets associated to the @@ -608,11 +905,11 @@ class TargetService // Instance variables bool iv_initialized; ///< Is service initialized or not - Target (*iv_targets)[]; ///< Pointer to array of target objects - uint32_t iv_maxTargets; ///< Maximum # target objects in the array - const void* iv_pPnor; ///< Pointer to the PNOR targeting section + AssociationMappings_t iv_associationMappings; ///< Association map + NodeInfo_t iv_nodeInfo; + // Disable copy constructor / assignment operator TargetService( diff --git a/src/include/usr/targeting/common/util.H b/src/include/usr/targeting/common/util.H index d1e2cff0f..bb11c70f6 100644 --- a/src/include/usr/targeting/common/util.H +++ b/src/include/usr/targeting/common/util.H @@ -54,6 +54,24 @@ class Target; #define TARG_ADDR_TRANSLATION_REQUIRED (1) #endif +namespace PLAT +{ + +/** + * @brief PLAT::PROPERTIES namespace contains constants that control platform + * specific behaviors + */ +namespace PROPERTIES +{ +#ifdef __HOSTBOOT_MODULE + static const bool MULTINODE_AWARE = false; +#else + static const bool MULTINODE_AWARE = true; +#endif +} + +} + /** * @brief Checks to see if we are running in a hardware simulation * environment, i.e. VPO/VBU (not Simics) diff --git a/src/include/usr/targeting/targplatreasoncodes.H b/src/include/usr/targeting/targplatreasoncodes.H new file mode 100644 index 000000000..1f3d18dbc --- /dev/null +++ b/src/include/usr/targeting/targplatreasoncodes.H @@ -0,0 +1,73 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/targeting/targplatreasoncodes.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef TARGPLATREASONCODES_H +#define TARGPLATREASONCODES_H + +/** + * @file targeting/targplatreasoncodes.H + * + * @brief Provides reason codes for various platform specific targeting errors + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +#include <targeting/adapters/types.H> + +//****************************************************************************** +// Constants +//****************************************************************************** + +namespace TARGETING +{ + +/** + * @brief Platform specific targeting module IDs + * + * @note Must always start @ 0x80, since common module IDs occupy 0x00 -> 0x7F + * range + */ +enum PlatTargetingModuleId +{ + TARG_MOD_QUERY_MASTER_PROC_CHIP = 0x80, + TARG_MOD_SET_MASTER_NODE = 0x81, +}; + +/** + * @brief Platform specific targeting reason codes + * + * @note Must always start @ 0x80, since common reasons codes occupy + * 0x00 -> 0x7F range + */ +enum PlatTargetingReasonCode +{ + TARG_RC_INVALID_NODE = TARG_COMP_ID | 0x80, + TARG_RC_TARGET_NOT_FOUND = TARG_COMP_ID | 0x81, +}; + +} // End TARGETING namespace + +#endif // TARGPLATREASONCODES_H + diff --git a/src/include/usr/targeting/targplatutil.H b/src/include/usr/targeting/targplatutil.H new file mode 100644 index 000000000..6f4ce5576 --- /dev/null +++ b/src/include/usr/targeting/targplatutil.H @@ -0,0 +1,255 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/targeting/targplatutil.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef TARGPLATUTIL_H +#define TARGPLATUTIL_H + +/** + * @file targeting/targplatutil.H + * + * @brief Provides interface for general platform specific utilities + * and constants to support core functions. + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <vector> + +// OTHER +#include <errl/errlentry.H> + +// TARG +#include <targeting/common/targreasoncodes.H> +#include <targeting/common/trace.H> +#include <targeting/common/target.H> + +namespace TARGETING +{ + +namespace UTIL +{ + +/** + * @brief Creates a standard error log of tracing type + * + * @par Detailed Description: + * Creates a standard error log of tracing type if it does not already + * exist, otherwise appends new SRC to the existing one. In both cases, + * the return code is updated to equal that of the reason code. + * + * @param[in] i_modId + * Module ID of the function that is attempting to create the error + * (see obj/ppc/hbfw/fsp/targeting/common/targreasoncodes.H + * and src/hbfw/fsp/targeting/targplatreasoncodes.H) + * + * @param[in] i_reasonCode + * Reason code of the function that is attempting to create the error + * (see obj/ppc/hbfw/fsp/targeting/common/targreasoncodes.H + * and src/hbfw/fsp/targeting/targplatreasoncodes.H) + * + * @param[in] i_userData1 + * Caller defined user data word 0 + * + * @param[in] i_userData2 + * Caller defined user data word 1 + * + * @param[in] i_userData3 + * Caller defined user data word 2 + * + * @param[in] i_userData4 + * Caller defined user data word 3 + * + * @param[out] io_pError + * On input: If NULL, function will ceate a new tracing error, else it + * will append new SRC to existing error + * On output: Handle will be updated to reflect the created or updated + * error log (never NULL) + * + * @return Not applicate / void + */ +void createTracingError( + const uint8_t i_modId, + const uint16_t i_reasonCode, + const uint32_t i_userData1, + const uint32_t i_userData2, + const uint32_t i_userData3, + const uint32_t i_userData4, + errlHndl_t& io_pError); + +/** + * @brief Sets the IS_MASTER_NODE attribute in the node target which is going + * to be the Master Node and unsets the IS_MASTER_NODE attribute in current + * master node target. Internally Syncs the New Master Node's System Target + * attributes to other non-master System Target's attribute. + * + * @par Detailed Description: + * It takes to be master node target handle as input, Finds the current + * master node handle, compares the two, if not equal then Simply sets/unsets + * the IS_MASTER_NODE Attr to the tobeMasterNode and currMasterNode Target + * respectively. Also Syncs all the System Target Attributes of the Master node + * to other system target attributes of the non-master node. If both the + * targets are equal it simply returns success. + * + * @param[in] i_pToBeMasterNodeTarget, Non-Null to be Master Node Target handle + * note that TYPE must be "NODE" (not control node) + * + * @return error handle indicating whether resuest was successful or not + * + * @retval error handle is null in successful scenario i.e. Master node's + * IS_MASTER_NODE attribute is Set and system targets synced-up. + * @retval error handle is not null, couldn't set the master node attribute + * or system target sync failed. + * Error log handle points to a valid error log object whose primary + * SRC reason code (pError->getSRC()->reasonCode()) may be set to one of, + * but not limited to, the following: + * TARG_RC_INVALID_NODE: Invalid Node Target + */ +inline errlHndl_t setMasterNode(Target* i_pToBeMasterNodeTarget) +{ + return NULL; +} + +/** + * @brief Sets the IS_MASTER_NODE attribute in the node target passed + * + * @par Detailed Description: + * This method should be used when targetService itself is not initiliazed yet + * This simply takes the node target handle of the node which is requird to be + * set as master node, sets the IS_MASTER_NODE Attribute field and returns. + * This method doesn't try to find out the current master node or any other + * sync related stuff. + * + * @param[in] i_pToBeMasterNodeTarget, Non-Null to be Master Node Target handle + * note that TYPE must be "NODE" (not control node) + * + * @return error handle indicating whether request was successful or not + * + * @retval error handle is null in successful scenario i.e. Master node's + * IS_MASTER_NODE attribute is Set. + * @retval error handle is not null, couldn't set the master node attribute + * Error log handle points to a valid error log object whose primary + * SRC reason code (pError->getSRC()->reasonCode()) may be set to one of, + * but not limited to, the following: + * TARG_RC_INVALID_NODE: Invalid Node Target + */ +inline errlHndl_t setDefaultMasterNodeWithoutSync( + Target* i_pToBeMasterNodeTarget) +{ + return NULL; +} + +/* @brief - returns whether a given target is a master node target or not + * + * @par Detailed Description: + * Takes a target and checks whether it is a master node target. If yes returns + * true to the user else false + * + * @param[in] i_pTarget - Non-Null node Target handle(class=enc, type=node) + * + * @return boolean indicating whether request was successful or not + * @retval, Returns true if the passed target is a master node target + * @retval, Returns false if the passed target is not a master node target. + */ +inline bool isThisMasterNodeTarget(const Target* const i_pTarget) +{ + return true; +} + +/* @brief - Syncs the master system target's attribute with non-master system + * targets. + * + * @par Detailed Description: + * Takes a master system target as input, internally find all the non-master + * system target and syncs the master system target's attribute over others. + * + * @param[in] i_pMasterSysTarget - Non-Null Master System Target + * + * @return error handle indicating whether request was successful or not + * @retval, NULL if it could sync all non-master system targets with the + * master system target. + * @retval, !NULL if the sync is failed. + * Error log handle points to a valid error log object whose primary + * SRC reason code (pError->getSRC()->reasonCode()) may be set to one of, + * but not limited to, the following: + * TARG_RC_MASTER_SYS_SYNC_FAILED: System Target Sync failed + */ +inline errlHndl_t SyncMasterSystemTarget(const Target* const i_pMasterSysTarget) +{ + return NULL; +} + +/* @brief - Tells whether the system target passed is non-master node + * system target + * + * @par Detailed Description: + * Takes non-null system target as input and tells whether it is a non-master + * node system target or master node system target + * + * @param[in] i_pSysTarget - Non-Null System Target + * + * @return boolean indicating whether the request was successful + * @retval, Returns true if system target is non-master node system target + * @retval, Returns false if system target is master node system target + */ +inline bool isNonMasterNodeSystemTarget(const Target* const i_pSysTarget) +{ + return false; +} + +/** + * @brief Returns the Node Target handle of the Master node in the + * system. + * + * @par Detailed Description: + * Returns the Node Target handle of the Master node in the system. + * Caller must check for NULL Target handle + * + * @param[out] o_masterNodeTarget node target handle of the master node + * in the system + * + * @return void + */ +void getMasterNodeTarget(Target*& o_masterNodeTarget); + +/** + * @brief Returns whether Hostboot subsystem is capable of selecting a node to + * act as a master node, whose system target is synchronized to other nodes + * + * @param[out] o_masterNodeCapable + * Indicates whether subsystem (Hostboot) is capable of selecting a node to + * act as a master node, whose system target is synchronized to other + * nodes. NOTE: When called in Hostboot, always returns false + */ +inline void subsystemIsMasterNodeCapable(bool& o_masterNodeCapable) +{ + o_masterNodeCapable = false; +} + +} // End namespace TARGETING::UTIL + +} // End namespace TARGETING + +#endif // TARGPLATUTIL_H diff --git a/src/usr/targeting/attrrp.C b/src/usr/targeting/attrrp.C index b5ae745ef..eaff4fd2b 100644 --- a/src/usr/targeting/attrrp.C +++ b/src/usr/targeting/attrrp.C @@ -73,7 +73,7 @@ namespace TARGETING Singleton<AttrRP>::instance().startup(io_taskRetErrl); } - void* AttrRP::getBaseAddress() + void* AttrRP::getBaseAddress(const NODE_ID i_nodeIdUnused) { return reinterpret_cast<void*>(VMM_VADDR_ATTR_RP); } @@ -568,10 +568,11 @@ namespace TARGETING } void AttrRP::readSectionData( - std::vector<TARGETING::sectionRefData>& o_pages, - const TARGETING::SECTION_TYPE i_sectionId) + std::vector<TARGETING::sectionRefData>& o_pages, + const TARGETING::SECTION_TYPE i_sectionId, + const NODE_ID i_nodeId) const { - sectionRefData sectionData = {0}; + sectionRefData sectionData; uint16_t count = 0; uint16_t pages = 0; diff --git a/src/usr/targeting/common/common.mk b/src/usr/targeting/common/common.mk index 509617f77..7a5cb8c27 100644 --- a/src/usr/targeting/common/common.mk +++ b/src/usr/targeting/common/common.mk @@ -41,6 +41,7 @@ PREDICATES_OBJS = \ ITERATORS_OBJS = \ targetiterator.o \ + rawtargetiterator.o \ rangefilter.o TARGET_OBJS = \ diff --git a/src/usr/targeting/common/genHwsvMrwXml.pl b/src/usr/targeting/common/genHwsvMrwXml.pl index c54368838..349b73054 100755 --- a/src/usr/targeting/common/genHwsvMrwXml.pl +++ b/src/usr/targeting/common/genHwsvMrwXml.pl @@ -865,6 +865,9 @@ my $Mproc = 0; my $fru_id = 0; my @fru_paths; my $hasProc = 0; +my $hash_ax_buses; +my $axBusesHuidInit = 0; + for (my $curnode = 0; $curnode <= $MAXNODE; $curnode++) { @@ -907,6 +910,32 @@ if ($hasProc == 0) next; } +#preCalculate HUID for A-Bus +if($axBusesHuidInit == 0) +{ + $axBusesHuidInit = 1; + for (my $my_curnode = 0; $my_curnode <= $MAXNODE; $my_curnode++) + { + for (my $do_core = 0, my $i = 0; $i <= $#STargets; $i++) + { + if ($STargets[$i][NODE_FIELD] != $my_curnode) + { + next; + } + if ($STargets[$i][NAME_FIELD] eq "mcs") + { + my $proc = $STargets[$i][POS_FIELD]; + if (($STargets[$i+1][NAME_FIELD] eq "pu") || + ($STargets[$i+1][NAME_FIELD] eq "memb")) + { + preCalculateAxBusesHUIDs($my_curnode, $proc, "A"); + preCalculateAxBusesHUIDs($my_curnode, $proc, "X"); + } + } + } + } +} + # Fourth, generate the proc, occ, ex-chiplet, mcs-chiplet # unit-tp (if on fsp), pcie bus and A/X-bus. my $ex_count = 0; @@ -916,6 +945,7 @@ my $proc_ordinal_id =0; #my $fru_id = 0; #my @fru_paths; my $hwTopology =0; + for (my $do_core = 0, my $i = 0; $i <= $#STargets; $i++) { if ($STargets[$i][NODE_FIELD] != $node) @@ -1194,6 +1224,30 @@ exit 0; ########## Subroutines ############## ################################################################################ +# utility function used to preCalculate the AX Buses HUIDs +################################################################################ + +sub preCalculateAxBusesHUIDs +{ + my ($my_node, $proc, $type) = @_; + + my ($minbus, $maxbus, $numperchip, $typenum, $type) = + getBusInfo($type, $CHIPNAME); + + for my $i ( $minbus .. $maxbus ) + { + my $uidstr = sprintf( "0x%02X%02X%04X", + ${my_node}, + $typenum, + $i+$proc*($numperchip)+${my_node}*8*($numperchip)); + my $phys_path = + "physical:sys-$sys/node-$my_node/proc-$proc/${type}bus-$i"; + $hash_ax_buses->{$phys_path} = $uidstr; + #print STDOUT "Phys Path = $phys_path, HUID = $uidstr\n"; + } +} + +################################################################################ # utility function used to call plugins. if none exists, call is skipped. ################################################################################ @@ -1850,9 +1904,20 @@ sub generate_proc <default>$dcm_installed</default> </attribute>"; + if ($master) + { + print " + <!-- Master Proc attribute --> + <attribute> + <id>PROC_MASTER_TYPE</id> + <default>ACTING_MASTER</default> + </attribute>"; + + } if ($slave) { print " + <!-- Slave Proc attribute --> <!-- FSI is connected via node${node}:proc${Mproc}:MFSI-$fsi --> <attribute> <id>FSI_MASTER_CHIP</id> @@ -2221,23 +2286,31 @@ sub generate_a_pcie "; } +sub getBusInfo +{ + my($type, $chipName) = @_; + + my $minbus = ($type eq "A") ? 0 : ($chipName eq "murano") ? 1 : 0; + my $maxbus = ($type eq "A") ? 2 : ($chipName eq "murano") ? 1 : 3; + my $numperchip = ($type eq "A") ? 3 : 4; + my $typenum = ($type eq "A") ? 0x0F : 0x0E; + $type = lc( $type ); + + return ($minbus, $maxbus, $numperchip, $typenum, $type); +} + sub generate_ax_buses { my ($proc, $type, $ordinalId) = @_; my $proc_name = "n${node}p${proc}"; print "\n<!-- $SYSNAME $proc_name ${type}BUS units -->\n"; - my $minbus = ($type eq "A") ? 0 : ($CHIPNAME eq "murano") ? 1 : 0; - my $maxbus = ($type eq "A") ? 2 : ($CHIPNAME eq "murano") ? 1 : 3; - my $numperchip = ($type eq "A") ? 3 : 4; - my $typenum = ($type eq "A") ? 0x0F : 0x0E; - $type = lc( $type ); + + my ($minbus, $maxbus, $numperchip, $typenum, $type) = + getBusInfo($type, $CHIPNAME); + for my $i ( $minbus .. $maxbus ) { - my $uidstr = sprintf( "0x%02X%02X%04X", - ${node}, - $typenum, - $i+$proc*($numperchip)+${node}*8*($numperchip)); my $c_ordinalId = $i+($ordinalId*($numperchip)); my $peer = 0; @@ -2279,14 +2352,19 @@ sub generate_ax_buses last; } } + my $phys_path = + "physical:sys-${sys}/node-${node}/proc-${proc}/${type}bus-${i}"; print " <targetInstance> <id>sys${sys}node${node}proc${proc}${type}bus$i</id> <type>unit-${type}bus-$CHIPNAME</type> - <attribute><id>HUID</id><default>${uidstr}</default></attribute> + <attribute> + <id>HUID</id> + <default>$hash_ax_buses->{$phys_path}</default> + </attribute> <attribute> <id>PHYS_PATH</id> - <default>physical:sys-$sys/node-$node/proc-$proc/${type}bus-$i</default> + <default>$phys_path</default> </attribute> <attribute> <id>AFFINITY_PATH</id> @@ -2302,12 +2380,17 @@ sub generate_ax_buses </attribute>"; if ($peer) { + my $peerPhysPath = "physical:sys-${sys}/node-${p_node}/" + ."proc-${p_proc}/${type}bus-${p_port}"; print " <attribute> <id>PEER_TARGET</id> - <default>physical:sys-$sys/node-$p_node/proc-$p_proc/" - . "${type}bus-$p_port</default> - </attribute>"; + <default>$peerPhysPath</default> + </attribute> + <compileAttribute> + <id>PEER_HUID</id> + <default>$hash_ax_buses->{$peerPhysPath}</default> + </compileAttribute>"; if ($type eq "a") { print " diff --git a/src/usr/targeting/common/genNodeMrwXml.pl b/src/usr/targeting/common/genNodeMrwXml.pl index 8c686b05c..930c8670b 100755 --- a/src/usr/targeting/common/genNodeMrwXml.pl +++ b/src/usr/targeting/common/genNodeMrwXml.pl @@ -154,118 +154,13 @@ foreach my $targetInstance (@{$sysInfo->{targetInstance}}) my $nodeValue = $targetId; $nodeValue =~ s/.*node(\d?).*/$1/; - #TODO: revisit when doing multi-node - #for now the in a multi-node/drawer system the abus goes outside - #the node/drawer boundry. So will remove the peer nodes since there - #in no current method of reaching the peer if ($nodeValue < $#nodeFD ) { - if ($targetId =~ m/abus/) - { - #make the peer target null - my $count =0; - foreach my $attrValue (@{$targetInstance->{'attribute'}}) - { - if ($attrValue->{'id'}[0] eq "PEER_TARGET") - { - splice @{$targetInstance->{'attribute'}},$count,1; - last; - } - $count++; - - } - my $xmlDataNoPeer= XMLout($targetInstance,RootName => "targetInstance"); - #print Dumper($xmlDataNoPeer); - print {$nodeFD[$nodeValue]} $xmlDataNoPeer; - } - elsif ($targetId =~ m/psi/) - { - #TODO: revisit when doing multi-node - #if the psi link is going to node 0 or belongs to node 0 keep - #else set to default. - - my $count =0; - my $nodePeer =-1; - my $spliceLoc =0; - foreach my $attrValue (@{$targetInstance->{'attribute'}}) - { - if($attrValue->{'id'}[0] eq "PEER_TARGET") - { - $nodePeer = $attrValue->{'default'}[0]; - $nodePeer =~ s/.*node-(\d?).*/$1/; - if ($nodePeer == 4) - { - $nodePeer =0; - } - last; - } - - $count++; - } - - if ($nodePeer == $nodeValue ) - { - #in this case the target and peer are pointing to same node - #print Dumper($xmlData); - print {$nodeFD[$nodeValue]} $xmlData; - } - else - { - #the target or the peer is pointing off the node - #so need to remove the peer target - splice @{$targetInstance->{'attribute'}},$count,1; - my $xmlDataNoPeer= XMLout($targetInstance,RootName => "targetInstance"); - #print Dumper($xmlDataNoPeer); - print {$nodeFD[$nodeValue]} $xmlDataNoPeer; - } - } - else - { - print {$nodeFD[$nodeValue]} $xmlData; - } - + print {$nodeFD[$nodeValue]} $xmlData; } elsif ($nodeValue == $#nodeFD) { - #TODO: revisit when doing multi-node - #there should not be node 4 targeting data for node 4 - #because node 4 is a FSP(maxdale) not a node. However - #do need to include node 4 psi info for node 0 - - my $psiValue = $targetId; - #print("psiValue from targ = ",$psiValue,"\n"); - if ($targetId=~ m/psi/) - { - my $count =0; - foreach my $attrValue (@{$targetInstance->{'attribute'}}) - { - if($attrValue->{'id'}[0] eq "PEER_TARGET") - { - if ($attrValue->{'default'}[0] =~ m/node-0/) - { - #print Dumper($xmlData); - #all node-4 targets go into the node 0 targeting binary - print {$nodeFD[0]} $xmlData; - } - else - { - #if not going to node 4 then need to remove the peer target - splice @{$targetInstance->{'attribute'}},$count,1; - my $xmlDataNoPeer= XMLout($targetInstance,RootName => "targetInstance"); - #print Dumper($xmlDataNoPeer); - print {$nodeFD[0]} $xmlDataNoPeer; - } - last; - } - $count++; - } - } - else - { - #this is node 4 information that does not contain psi information - print {$nodeFD[0]} $xmlData; - } - + print {$nodeFD[0]} $xmlData; } else { diff --git a/src/usr/targeting/common/iterators/rangefilter.C b/src/usr/targeting/common/iterators/rangefilter.C index 7e3ddf333..961db1ea7 100644 --- a/src/usr/targeting/common/iterators/rangefilter.C +++ b/src/usr/targeting/common/iterators/rangefilter.C @@ -1,30 +1,30 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/targeting/iterators/rangefilter.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/targeting/common/iterators/rangefilter.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ /** * @file common/targeting/iterators/rangefilter.C * - * @brief Implementation of an object which takes an iterator range and + * @brief Implementation of an object which takes an iterator range and * allows caller to iterate through the elements which match a supplied * predicate (filter) */ @@ -39,6 +39,7 @@ // Targeting Component #include <targeting/common/iterators/iterators.H> +#include <targeting/common/trace.H> //****************************************************************************** // Macros @@ -66,17 +67,21 @@ namespace TARGETING template<typename IteratorType> void RangeFilter<IteratorType>::advance() { + #define TARG_FN "RangeFilter<IteratorType>::advance()" + if(iv_current != iv_end) { while( (++iv_current) != iv_end ) { - if( (!iv_pPredicate) + if( (!iv_pPredicate) || ((*iv_pPredicate)(*iv_current))) { break; } } } + + #undef TARG_FN } //****************************************************************************** @@ -100,8 +105,8 @@ void RangeFilter<IteratorType>::advanceIfNoMatch() template<typename IteratorType> RangeFilter<IteratorType>::operator fake_bool() const -{ - return (iv_current != iv_end) +{ + return (iv_current != iv_end) ? &RangeFilter::notComparable : NULL; } @@ -115,7 +120,7 @@ template void RangeFilter<ConstTargetIterator>::advance(); template void RangeFilter<TargetIterator>::advanceIfNoMatch(); template void RangeFilter<ConstTargetIterator>::advanceIfNoMatch(); -template RangeFilter<TargetIterator>::operator fake_bool() const; +template RangeFilter<TargetIterator>::operator fake_bool() const; template RangeFilter<ConstTargetIterator>::operator fake_bool() const; #undef TARG_CLASS diff --git a/src/usr/targeting/common/iterators/rawtargetiterator.C b/src/usr/targeting/common/iterators/rawtargetiterator.C new file mode 100644 index 000000000..9946a3d0f --- /dev/null +++ b/src/usr/targeting/common/iterators/rawtargetiterator.C @@ -0,0 +1,91 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/targeting/common/iterators/rawtargetiterator.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/** + * @file targeting/common/iterators/rawtargetiterator.C + * + * @brief Implementation of raw iterator/const raw iterator used to iterate + * through all target service targets + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD + +// Other Host Boot Components + +// Targeting Component +#include <targeting/common/iterators/iterators.H> +#include <targeting/common/targetservice.H> + +//****************************************************************************** +// Macros +//****************************************************************************** + +#undef TARG_NAMESPACE +#undef TARG_CLASS +#undef TARG_FUNC + +//****************************************************************************** +// Implementation +//****************************************************************************** + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" + +#define TARG_CLASS "_TargetRawIterator<T>::" + +//****************************************************************************** +// TargetIterator::advance +//****************************************************************************** + +template<typename T> +void _TargetRawIterator<T>::advance() +{ + static TargetService& l_targetService = targetService(); + + // If cursor points to end()/NULL, do nothing. Otherwise, check to see if + // it should advance (possibly to NULL) + if(iv_pCurrent != NULL) + { + iv_pCurrent = l_targetService.getNextTarget(iv_pCurrent); + } +} + +//****************************************************************************** +// Explicit template class member function instantiations +//****************************************************************************** + +template void _TargetRawIterator<Target*>::advance(); +template void _TargetRawIterator<const Target*>::advance(); + +#undef TARG_CLASS + +#undef TARG_NAMESPACE + +} // End namespace TARGETING + diff --git a/src/usr/targeting/common/iterators/targetiterator.C b/src/usr/targeting/common/iterators/targetiterator.C index 76b687641..ff73641ea 100644 --- a/src/usr/targeting/common/iterators/targetiterator.C +++ b/src/usr/targeting/common/iterators/targetiterator.C @@ -1,31 +1,31 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/targeting/iterators/targetiterator.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/targeting/common/iterators/targetiterator.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ /** * @file targeting/common/iterators/targetiterator.C * * @brief Implementation of iterator/const iterator used to iterate through - * target service targets + * target service targets */ //****************************************************************************** @@ -66,30 +66,55 @@ namespace TARGETING template<typename T> void _TargetIterator<T>::advance() { - TargetService& l_targetService = targetService(); + static TargetService& l_targetService = targetService(); - // If cursor points to end()/NULL, do nothing. Otherwise, check to see if + // If cursor points to end()/NULL, do nothing. Otherwise, check to see if // it should advance (possibly to NULL) - if(iv_pCurrent != NULL) + if(likely (iv_pCurrent != NULL) ) { - // Advance to end() if no targets available. Otherwise, check to see if - // it should advance (possibly to NULL) - if (l_targetService.iv_maxTargets > 0) + // In HB the first block will always compile to run and take the optimal + // iterator performance path that assumes only one node's worth of data + if(!PLAT::PROPERTIES::MULTINODE_AWARE) { - // If at or past last element, advance to end() else advance - if(iv_pCurrent >= - &(*l_targetService.iv_targets)[l_targetService.iv_maxTargets-1]) + if ( likely( (!l_targetService.iv_nodeInfo.empty()) ) + && likely( (l_targetService.iv_nodeInfo[0].maxTargets > 0) ) ) { - iv_pCurrent = NULL; + // If at or past last element, advance to end() else advance + if(unlikely ( + iv_pCurrent >= + &(*(l_targetService.iv_nodeInfo[0]).targets) + [l_targetService.iv_nodeInfo[0].maxTargets-1] + )) + { + iv_pCurrent = NULL; + } + else + { + iv_pCurrent++; + } } else { - iv_pCurrent++; + iv_pCurrent = NULL; } + } else { - iv_pCurrent = NULL; + iv_pCurrent = l_targetService.getNextTarget(iv_pCurrent); + if(likely(iv_pCurrent != NULL)) + { + // Targeting XML and compiler ensure that there are no back to + // back hidden system targets; therefore, if the current one is + // a hidden system target, skip it and the next one will either + // be valid or NULL (i.e. end()) + if(unlikely( + l_targetService.isNonMasterNodeSystemTarget(iv_pCurrent))) + { + iv_pCurrent = l_targetService.getNextTarget(iv_pCurrent); + } + } + } } } diff --git a/src/usr/targeting/common/target.C b/src/usr/targeting/common/target.C index 5209c3891..6d619a7ab 100644 --- a/src/usr/targeting/common/target.C +++ b/src/usr/targeting/common/target.C @@ -219,9 +219,11 @@ void Target::_getAttrPtr( if(TARG_ADDR_TRANSLATION_REQUIRED) { pAttrId = static_cast<ATTRIBUTE_ID*>( - TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr(pAttrId)); + TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr(pAttrId, + static_cast<const Target*>(this))); ppAttrAddr = static_cast<AbstractPointer<void>*>( - TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr(ppAttrAddr)); + TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr(ppAttrAddr, + static_cast<const Target*>(this))); } if ((pAttrId != NULL) && (ppAttrAddr != NULL)) @@ -245,7 +247,7 @@ void Target::_getAttrPtr( { l_pAttr = TARG_GET_SINGLETON(TARGETING::theAttrRP).translateAddr( - l_pAttr); + l_pAttr, static_cast<const Target*>(this)); } } } 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 } diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml index f93bb1b89..4f0b42477 100644 --- a/src/usr/targeting/common/xmltohb/attribute_types.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types.xml @@ -12697,4 +12697,39 @@ firmware notes: Platforms should initialize this attribute to AUTO (0)</descript </hwpfToHbAttrMap> </attribute> +<enumerationType> + <id>PROC_MASTER_TYPE</id> + <description> + Enumeration indicating the role of proc as master/alt_master/not_master + </description> + <enumerator> + <name>ACTING_MASTER</name> + <value>0</value> + </enumerator> + <enumerator> + <name>MASTER_CANDIDATE</name> + <value>1</value> + </enumerator> + <enumerator> + <name>NOT_MASTER</name> + <value>2</value> + </enumerator> + <default>NOT_MASTER</default> +</enumerationType> + +<attribute> + <id>PROC_MASTER_TYPE</id> + <description>Type of Master, ACTING_MASTER or MASTER_CANDIDATE or + NOT_MASTER</description> + <simpleType> + <enumeration> + <id>PROC_MASTER_TYPE</id> + </enumeration> + </simpleType> + <persistency>non-volatile</persistency> + <hasStringConversion/> + <readable/> + <writeable/> +</attribute> + </attributes> diff --git a/src/usr/targeting/common/xmltohb/common.mk b/src/usr/targeting/common/xmltohb/common.mk index 8561911fd..c9ca8f874 100644 --- a/src/usr/targeting/common/xmltohb/common.mk +++ b/src/usr/targeting/common/xmltohb/common.mk @@ -37,14 +37,16 @@ XMLTOHB_HEADER_TARGETS = \ pnortargeting.H \ fapiplatattrmacros.H \ test_ep.H \ - mapattrmetadata.H + mapattrmetadata.H \ + mapsystemattrsize.H XMLTOHB_SOURCE_TARGETS = \ attributestrings.C \ attributedump.C \ errludattribute.C \ errludtarget.C \ - mapattrmetadata.C + mapattrmetadata.C \ + mapsystemattrsize.C XMLTOHB_SYSTEM_BINARIES = \ vbu_VENICE_targeting.bin \ diff --git a/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml b/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml index 436c99e9f..c193d4a38 100644 --- a/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml +++ b/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml @@ -264,6 +264,10 @@ <targetInstance> <id>sys0node0proc0</id> <type>chip-processor-murano</type> + <attribute> + <id>PROC_MASTER_TYPE</id> + <default>ACTING_MASTER</default> + </attribute> <attribute><id>HUID</id><default>0x00050000</default></attribute> <attribute><id>POSITION</id><default>0</default></attribute> <attribute><id>SCOM_SWITCHES</id> diff --git a/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml b/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml index c5c822068..3487069cb 100644 --- a/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml +++ b/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml @@ -237,6 +237,10 @@ <targetInstance> <id>sys0node0proc0</id> <type>chip-processor-venice</type> + <attribute> + <id>PROC_MASTER_TYPE</id> + <default>ACTING_MASTER</default> + </attribute> <attribute><id>HUID</id><default>0x00050000</default></attribute> <attribute><id>POSITION</id><default>0</default></attribute> <attribute><id>SCOM_SWITCHES</id> diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml index 977b3927f..f3813d51e 100644 --- a/src/usr/targeting/common/xmltohb/target_types.xml +++ b/src/usr/targeting/common/xmltohb/target_types.xml @@ -260,6 +260,10 @@ <default>PROC</default> </attribute> <attribute> + <id>PROC_MASTER_TYPE</id> + <default>NOT_MASTER</default> + </attribute> + <attribute> <id>PRIMARY_CAPABILITIES</id> <default> <field><id>supportsFsiScom</id><value>1</value></field> diff --git a/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml b/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml index b836f02ca..125574a86 100644 --- a/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml +++ b/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml @@ -252,6 +252,10 @@ <targetInstance> <id>sys0node0proc0</id> <type>chip-processor-murano</type> + <attribute> + <id>PROC_MASTER_TYPE</id> + <default>ACTING_MASTER</default> + </attribute> <attribute><id>HUID</id><default>0x00050000</default></attribute> <attribute><id>POSITION</id><default>0</default></attribute> <attribute><id>SCOM_SWITCHES</id> diff --git a/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml b/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml index 90f549c3c..697eb90db 100644 --- a/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml +++ b/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml @@ -253,6 +253,10 @@ <targetInstance> <id>sys0node0proc0</id> <type>chip-processor-venice</type> + <attribute> + <id>PROC_MASTER_TYPE</id> + <default>ACTING_MASTER</default> + </attribute> <attribute><id>HUID</id><default>0x00050000</default></attribute> <attribute><id>POSITION</id><default>0</default></attribute> <attribute><id>SCOM_SWITCHES</id> diff --git a/src/usr/targeting/common/xmltohb/xmltohb.pl b/src/usr/targeting/common/xmltohb/xmltohb.pl index 335944862..3d519631a 100755 --- a/src/usr/targeting/common/xmltohb/xmltohb.pl +++ b/src/usr/targeting/common/xmltohb/xmltohb.pl @@ -115,6 +115,8 @@ if($cfgVerbose) ################################################################################ use constant INVALID_HUID=>0xffffffff; +use constant PEER_HUID_NOT_PRESENT=>0xfffffffe; + my $xml = new XML::Simple (KeyAttr=>[]); use Digest::MD5 qw(md5_hex); @@ -264,6 +266,22 @@ if( !($cfgSrcOutputDir =~ "none") ) writeAttrMetadataMapCFile($attributes,$attrMetadataMapCFile); writeAttrMetadataMapCFileFooter($attrMetadataMapCFile); close $attrMetadataMapCFile; + + open(MAP_ATTR_SIZE_H_FILE,">$cfgSrcOutputDir"."mapsystemattrsize.H") + or fatal ("Attribute size map file Header: \"$cfgSrcOutputDir" + . "mapsystemattrsize.H\" could not be opened."); + my $attrSizeMapHFile = *MAP_ATTR_SIZE_H_FILE; + writeAttrSizeMapHFile($attrSizeMapHFile); + close $attrSizeMapHFile; + + open(MAP_ATTR_SIZE_C_FILE,">$cfgSrcOutputDir"."mapsystemattrsize.C") + or fatal ("Attribute size map file: \"$cfgSrcOutputDir" + . "mapsystemattrsize.C\" could not be opened."); + my $attrSizeMapCFile = *MAP_ATTR_SIZE_C_FILE; + writeAttrSizeMapCFileHeader($attrSizeMapCFile); + writeAttrSizeMapCFile($attributes,$attrSizeMapCFile); + writeAttrSizeMapCFileFooter($attrSizeMapCFile); + close $attrSizeMapCFile; } if( !($cfgImgOutputDir =~ "none") ) @@ -468,16 +486,27 @@ sub handleTgtPtrAttributesFsp if (exists $attr->{default}) { if( ($attr->{default} ne "NULL") - && ($attr->{id} eq "PEER_TARGET")) + && ($attr->{id} eq "PEER_TARGET") ) { - my $peerHUID = getPeerHuid(${$attributes}, - $attr->{default}); + my $peerHUID = INVALID_HUID; + $peerHUID = getPeerHuid($targetInstance); if($peerHUID == INVALID_HUID) { - fatal("HUID for Peer Target not found"); + fatal("HUID for Peer Target not found for " + . "Peer Target [$attr->{default}]\n"); + } + elsif($peerHUID == PEER_HUID_NOT_PRESENT) + { + # Might require this for debug, so keeping it. + #print STDOUT "****PEER HUID Attribut not present for " + # . "Peer Target [$attr->{default}]... Skip\n"; + $attr->{default} = "NULL"; + } + else + { + $attr->{default} = + sprintf("0x%X",(hex($peerHUID) << 32)); } - $attr->{default} = (hex($peerHUID) << 32); - $attr->{default} = sprintf("0x%X",$attr->{default}); } } } @@ -531,9 +560,10 @@ sub handleTgtPtrAttributesHb{ } else { - fatal("$attr->{id} attribute has an unknown value " - . "$attr->{default}\n" - . "It must be NULL or a valid PHYS_PATH\n"); + print STDOUT ("$attr->{id} attribute has an unknown value " + . "$attr->{default}\n" + . "It must be NULL or a valid PHYS_PATH\n"); + $attr->{default} = "NULL"; } } } @@ -542,42 +572,27 @@ sub handleTgtPtrAttributesHb{ sub getPeerHuid { - my($attributes, $peerPhysPath) = @_; + my($targetInstance) = @_; my $peerHUID = INVALID_HUID; - my $found = 0; - foreach my $targetInstance (@{$attributes->{targetInstance}}) + if(exists $targetInstance->{compileAttribute}->{id}) { - foreach my $attr (@{$targetInstance->{attribute}}) + if ($targetInstance->{compileAttribute}->{id} eq "PEER_HUID") { - if ($attr->{id} eq "PHYS_PATH") - { - if ($attr->{default} eq $peerPhysPath) - { - # $attr->{id} for HUID might have been lost in the iteration - # Need to repeat iteration - foreach my $attr1 (@{$targetInstance->{attribute}}) - { - if ($attr1->{id} eq "HUID") - { - $peerHUID = $attr1->{default}; - $found = 1; - last; - } - } - if($found) - { - last; - } - } - } + $peerHUID = $targetInstance->{compileAttribute}->{default}; } - if($found) + else { - last; + fatal("We should have only PEER_HUID as compileAttribute. " + . "Don't know how to handle this Attribute " + . "$targetInstance->{compileAttribute}->{id}\n"); } } - + else + { + # PEER HUID doesn't exist, Return an pre-defined HUID which is invalid + $peerHUID = PEER_HUID_NOT_PRESENT; + } return $peerHUID; } @@ -3093,6 +3108,302 @@ sub writeTargetErrlHFile { print $outFile "#endif\n"; } # sub writeTargetErrlHFile +################################################################################ +# Writes the map system attr size C file header +################################################################################ + +sub writeAttrSizeMapCFileHeader { + my($outFile) = @_; + +print $outFile <<VERBATIM; + +/** + * \@file mapsystemattrsize.C + * + * \@brief Interface to get the map of system target attributes with respective + * attribute size + */ + +// STD +#include <map> + +// TARG +#include <mapsystemattrsize.H> + + +//****************************************************************************** +// Macros +//****************************************************************************** + +#undef TARG_NAMESPACE +#undef TARG_CLASS +#undef TARG_FUNC + +//****************************************************************************** +// Implementation +//****************************************************************************** + +namespace TARGETING +{ + + +#define TARG_NAMESPACE "TARGETING::" +#define TARG_CLASS "MapSystemAttrSize::" + +//****************************************************************************** +// TARGETING::mapSystemAttrSize +//****************************************************************************** + +TARGETING::MapSystemAttrSize& mapSystemAttrSize() +{ + #define TARG_FN "mapSystemAttrSize()" + + return TARG_GET_SINGLETON(TARGETING::theMapSystemAttrSize); + + #undef TARG_FN +} + +//****************************************************************************** +// TARGETING::MapSystemAttrSize::~MapSystemAttrSize +//****************************************************************************** + +MapSystemAttrSize::~MapSystemAttrSize() +{ + #define TARG_FN "~MapSystemAttrSize()" + #undef TARG_FN +} + +//****************************************************************************** +// TARGETING::MapSystemAttrSize::getMapForWriteableSystemAttributes +//****************************************************************************** + +const AttrSizeMapper& +MapSystemAttrSize::getMapForWriteableSystemAttributes() const +{ + #define TARG_FN "getMapForWriteableSystemAttributes()" + TARG_ENTER(); + + TARG_EXIT(); + return iv_mapSysAttrSize; + + #undef TARG_FN +} + +//****************************************************************************** +// TARGETING::MapSystemAttrSize::MapSystemAttrSize +//****************************************************************************** + +MapSystemAttrSize::MapSystemAttrSize() +{ + #define TARG_FN "MapSystemAttrSize()" +VERBATIM + +} + +###### +# Create a .C file to put System Target Attributes along with there respective +# Size in a map file +###### +sub writeAttrSizeMapCFile{ + my($attributes,$outFile) = @_; + my %finalAttrhash = (); + + # look for type sys-sys-power8 and store all attributes associated + foreach my $targetType (@{$attributes->{targetType}}) + { + if($targetType->{id} =~ m/^sys-sys-/) + { + my %attrhash = (); + getTargetAttributes($targetType->{id}, $attributes,\%attrhash); + foreach my $key ( keys %attrhash ) + { + foreach my $attr (@{$attributes->{attribute}}) + { + if($attr->{id} eq $key) + { + if((exists $attr->{writeable}) && + (!(exists $attr->{hbOnly}))) + { + # we have the attr here.. calculate the size + my $keyVal = "ATTR_"."$key"."_type"; + if(exists $attr->{simpleType}) + { + if(exists $attr->{simpleType}->{array}) + { + my @splitArrSize = split(',', + $attr->{simpleType}->{array}); + foreach my $num (@splitArrSize) + { + $keyVal = "$keyVal"."[$num]"; + } + } + elsif(exists $attr->{simpleType}->{string}) + { + if(exists $attr->{simpleType}->{string}-> + {sizeInclNull}) + { + $keyVal = "$keyVal"."[$attr-> + {simpleType}->{string}-> + {sizeInclNull}]"; + } + } + $finalAttrhash{$key} = $keyVal; + } + elsif(exists $attr->{complexType}) + { + $finalAttrhash{$key} = $keyVal; + } + elsif(exists $attr->{nativeType}) + { + $finalAttrhash{$key} = $keyVal; + } + else + { + print STDOUT "\t// Attribute $key is writable " + . "& Not Supported \n"; + } + } + } + } + } + } + } + print $outFile "\n"; + foreach my $key ( keys %finalAttrhash) + { + print $outFile " iv_mapSysAttrSize[ATTR_" + . "$key] = sizeof($finalAttrhash{$key});\n"; + } + print $outFile "\n"; +} + +################################################################################ +# Writes the map system attr size C file Footer +################################################################################ + +sub writeAttrSizeMapCFileFooter { + my($outFile) = @_; + + print $outFile <<VERBATIM; + #undef TARG_FN +} + +}// namespace TARGETING + +VERBATIM +} + +###### +# Create a .H file to put System Target Attributes along with their respective +# Size in a map file +###### +sub writeAttrSizeMapHFile{ + my($outFile) = @_; + print $outFile <<VERBATIM; + +#ifndef MAPSYSTEMATTRSIZE_H +#define MAPSYSTEMATTRSIZE_H + +/** + * \@file mapsystemattrsize.H + * + * \@brief Interface to get the map of system target attributes with respective + * attribute size + */ + +// STD +#include <map> + +// TARG +#include <targeting/common/trace.H> +#include <targeting/common/target.H> + +//****************************************************************************** +// Macros +//****************************************************************************** + +#undef TARG_NAMESPACE +#undef TARG_CLASS +#undef TARG_FUNC + +//****************************************************************************** +// Interface +//****************************************************************************** + +namespace TARGETING +{ + +class MapSystemAttrSize; + +/** + * \@brief Return the MapSystemAttrSize singleton instance + * + * \@return Reference to the MapSystemAttrSize singleton + */ +TARGETING::MapSystemAttrSize& mapSystemAttrSize(); + + +#define TARG_NAMESPACE "MAPSYSTEMATTRSIZE::" + +#define TARG_CLASS "MapSystemAttrSize::" + +/* + * \@brief Typedef map <attr, attSize> + */ +typedef map<ATTRIBUTE_ID, uint32_t> AttrSizeMapper; + +class MapSystemAttrSize +{ + + public: + /** + * \@brief Destroy the MapSystemAttrSize class + */ + ~MapSystemAttrSize(); + + /** + * \@brief Create the MapSystemAttrSize class + */ + MapSystemAttrSize(); + + /* + * \@brief returns the map of Writeable System attributes as Key and + * size of the attributes as value. + * + * \@return, returns the map which has the Writeable Sytem attributes + * as key and size as value pair, variable <SYSTEM_ATTRIBUTE_ID::Size> + */ + const AttrSizeMapper& getMapForWriteableSystemAttributes() const; + + private: + + /* Map variable for System Attribute Ids Vs the Size */ + AttrSizeMapper iv_mapSysAttrSize; + + /* Disable Copy constructor and assignment operator */ + MapSystemAttrSize( + const MapSystemAttrSize& i_right); + + MapSystemAttrSize& operator = ( + const MapSystemAttrSize& i_right); +}; + +/** + * \@brief Provide singleton access to the MapSystemAttrSize + */ +TARG_DECLARE_SINGLETON(TARGETING::MapSystemAttrSize, theMapSystemAttrSize); + +#undef TARG_CLASS +#undef TARG_NAMESPACE + + +}// namespace TARGETING + +#endif // MAPSYSTEMATTRSIZE_H + +VERBATIM + +} sub UTILITY_FUNCTIONS { } @@ -3409,13 +3720,25 @@ sub getInstantiatedTargetTypes { my %seen = (); my @uniqueTargetTypes = (); + my $targetCount = 0; + my $moveSysTarget = 0; + # To simplify the iterator code, always move a system target that appears as + # the first target to the next position foreach my $targetInstance (@{$attributes->{targetInstance}}) { + if(($targetInstance->{type} =~ m/^sys-sys-/) && ($targetCount == 0)) + { + $targetCount = $targetCount + 1; + $moveSysTarget = 1; + } push (@uniqueTargetTypes, $targetInstance->{type}) unless $seen{$targetInstance->{type}}++; } - + if($moveSysTarget == 1) + { + @uniqueTargetTypes[0,1] = @uniqueTargetTypes[1,0]; + } return @uniqueTargetTypes; } @@ -4412,10 +4735,28 @@ sub generateTargetingImage { # for code update. At minimum, ensure that we always process at this level # in the given order my @targetsAoH = (); + my $targetCount = 0; + my $moveSysTarget = 0; + + # To support the iterator code, we dont want sys target to be the + # first in order. So we have specifically moved system target to second, + # if it is in first place. foreach my $targetInstance (@{$attributes->{targetInstance}}) { + # for the first Target, check if Sys Target + if(($targetCount == 0) && ($targetInstance->{id} eq "sys0")) + { + # mark a flag here that we need to interchange 1&2 targets, + # so as to push system target to second place + $moveSysTarget = 1; + $targetCount = $targetCount + 1; + } push(@targetsAoH, $targetInstance); } + if($moveSysTarget == 1) + { + @targetsAoH[0,1] = @targetsAoH[1,0]; + } my $numTargets = @targetsAoH; my $numAttributes = 0; diff --git a/src/usr/targeting/makefile b/src/usr/targeting/makefile index b9179107f..876c99134 100644 --- a/src/usr/targeting/makefile +++ b/src/usr/targeting/makefile @@ -43,7 +43,8 @@ VPATH = \ ATTR_RP_OBJS = \ attrrp.o \ - attrsync.o + attrsync.o \ + targplatutil.o ENTRY_POINT_OBJS = \ targetservicestart.o diff --git a/src/usr/targeting/targplatutil.C b/src/usr/targeting/targplatutil.C new file mode 100644 index 000000000..f913030e2 --- /dev/null +++ b/src/usr/targeting/targplatutil.C @@ -0,0 +1,110 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/targeting/targplatutil.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/** + * @file targeting/targplatutil.C + * + * @brief Provides implementation for general platform specific utilities + * to support core functions + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdlib.h> + +// TARG +#include <targeting/targplatutil.H> +#include <targeting/common/predicates/predicates.H> +#include <errl/errlmanager.H> + +namespace TARGETING +{ + +namespace UTIL +{ + +#define TARG_NAMESPACE "TARGETING::UTIL" +#define TARG_CLASS "" + +//****************************************************************************** +// createTracingError +//****************************************************************************** + +void createTracingError( + const uint8_t i_modId, + const uint16_t i_reasonCode, + const uint32_t i_userData1, + const uint32_t i_userData2, + const uint32_t i_userData3, + const uint32_t i_userData4, + errlHndl_t& io_pError) +{ + errlHndl_t pNewError = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + i_modId, + i_reasonCode, + static_cast<uint64_t>(i_userData1) << 32 + | (i_userData2 & (0xFFFFFFFF)), + static_cast<uint64_t>(i_userData3) << 32 + | (i_userData4 & (0xFFFFFFFF))); + if(io_pError != NULL) + { + // Tie logs together; existing log primary, new log as secondary + pNewError->plid(io_pError->plid()); + errlCommit(pNewError,TARG_COMP_ID); + } + else + { + io_pError = pNewError; + pNewError = NULL; + } + + return; +} + +void getMasterNodeTarget(Target*& o_masterNodeTarget) +{ + Target* masterNodeTarget = NULL; + PredicateCTM nodeFilter(CLASS_ENC, TYPE_NODE); + TargetRangeFilter localBlueprintNodes( + targetService().begin(), + targetService().end(), + &nodeFilter); + if(localBlueprintNodes) + { + masterNodeTarget = *localBlueprintNodes; + } + + o_masterNodeTarget = masterNodeTarget; +} + +#undef TARG_NAMESPACE +#undef TARG_CLASS + +} // End namespace TARGETING::UTIL + +} // End namespace TARGETING + diff --git a/src/usr/targeting/xmltohb/makefile b/src/usr/targeting/xmltohb/makefile index 8ce66479b..565f5c704 100644 --- a/src/usr/targeting/xmltohb/makefile +++ b/src/usr/targeting/xmltohb/makefile @@ -121,12 +121,12 @@ ${GENDIR}/${XMLTOHB_MERGED_COMMON_TARGET_SOURCES}: \ # generic XML is created from the generic sources only ${GENDIR}/${XMLTOHB_GENERIC_XML}: \ ${XMLTOHB_MERGE_SCRIPT} ${XMLTOHB_GENERIC_SOURCES} - $< $^ > $@ + $< $(wordlist 2,$(words $^),$^) > $@ # merge all FAPI attribute files into one ${GENDIR}/${XMLTOHB_FAPI_XML}: ${XMLTOHB_MERGE_SCRIPT} \ ${XMLTOHB_FAPIATTR_SOURCES} - $< $^ > $@ + $< $(wordlist 2,$(words $^),$^) > $@ # create the header files, only needs generic xml $(call GENTARGET,$(XMLTOHB_TARGETS)) : $(XMLTOHB_RAN_INDICATION) |