summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Bofferding <bofferdn@us.ibm.com>2013-09-06 16:25:14 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-10-08 16:37:41 -0500
commit31a07e2cc87a0a24099b6e8d7ccc5cb3d0729b67 (patch)
treec0d1847802950d4ff41cdc1bc4eed8933a1f5774
parent6b7a65cc7ec85b4937c444dd7f3bb8424b9255ab (diff)
downloadtalos-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>
-rw-r--r--src/build/linker/linker.C6
-rw-r--r--src/include/usr/targeting/attrrp.H60
-rw-r--r--src/include/usr/targeting/common/iterators/iterators.H45
-rw-r--r--src/include/usr/targeting/common/iterators/rawtargetiterator.H140
-rw-r--r--src/include/usr/targeting/common/iterators/targetiterator.H3
-rw-r--r--src/include/usr/targeting/common/target.H21
-rw-r--r--src/include/usr/targeting/common/targetservice.H373
-rw-r--r--src/include/usr/targeting/common/util.H18
-rw-r--r--src/include/usr/targeting/targplatreasoncodes.H73
-rw-r--r--src/include/usr/targeting/targplatutil.H255
-rw-r--r--src/usr/targeting/attrrp.C9
-rw-r--r--src/usr/targeting/common/common.mk1
-rwxr-xr-xsrc/usr/targeting/common/genHwsvMrwXml.pl111
-rwxr-xr-xsrc/usr/targeting/common/genNodeMrwXml.pl109
-rw-r--r--src/usr/targeting/common/iterators/rangefilter.C59
-rw-r--r--src/usr/targeting/common/iterators/rawtargetiterator.C91
-rw-r--r--src/usr/targeting/common/iterators/targetiterator.C95
-rw-r--r--src/usr/targeting/common/target.C8
-rw-r--r--src/usr/targeting/common/targetservice.C969
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types.xml35
-rw-r--r--src/usr/targeting/common/xmltohb/common.mk6
-rw-r--r--src/usr/targeting/common/xmltohb/simics_MURANO.system.xml4
-rw-r--r--src/usr/targeting/common/xmltohb/simics_VENICE.system.xml4
-rw-r--r--src/usr/targeting/common/xmltohb/target_types.xml4
-rw-r--r--src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml4
-rw-r--r--src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml4
-rwxr-xr-xsrc/usr/targeting/common/xmltohb/xmltohb.pl417
-rw-r--r--src/usr/targeting/makefile3
-rw-r--r--src/usr/targeting/targplatutil.C110
-rw-r--r--src/usr/targeting/xmltohb/makefile4
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)
OpenPOWER on IntegriCloud