diff options
author | Nick Bofferding <bofferdn@us.ibm.com> | 2011-06-08 08:11:59 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2011-06-17 16:02:44 -0500 |
commit | 36d3996114b47cac0f12f16bf5a5c51a2f5f2ecf (patch) | |
tree | 8a8175b9d1bb5f6ef76a1d32eb2226fc6067eb98 /src | |
parent | cdaabfdbec148d9ce85f422507c596a8ae6ced08 (diff) | |
download | talos-hostboot-36d3996114b47cac0f12f16bf5a5c51a2f5f2ecf.tar.gz talos-hostboot-36d3996114b47cac0f12f16bf5a5c51a2f5f2ecf.zip |
Added support for base targeting infrastructure
Change-Id: Ie32d18b421b63f067eaf49a3592368f4adc444aa
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/139
Tested-by: Jenkins Server
Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/include/usr/targeting/attributeenums.H | 158 | ||||
-rw-r--r-- | src/include/usr/targeting/attributes.H | 25 | ||||
-rw-r--r-- | src/include/usr/targeting/attributestrings.H | 66 | ||||
-rw-r--r-- | src/include/usr/targeting/attributestructs.H | 86 | ||||
-rw-r--r-- | src/include/usr/targeting/attributetraits.H | 160 | ||||
-rw-r--r-- | src/include/usr/targeting/entitypath.H | 400 | ||||
-rw-r--r-- | src/include/usr/targeting/target.H | 304 | ||||
-rw-r--r-- | src/include/usr/targeting/targetservice.H | 461 | ||||
-rw-r--r-- | src/makefile | 7 | ||||
-rw-r--r-- | src/usr/makefile | 3 | ||||
-rw-r--r-- | src/usr/targeting/entitypath.C | 400 | ||||
-rw-r--r-- | src/usr/targeting/fakepnordata.C | 523 | ||||
-rw-r--r-- | src/usr/targeting/fakepnordata.H | 671 | ||||
-rw-r--r-- | src/usr/targeting/makefile | 8 | ||||
-rw-r--r-- | src/usr/targeting/target.C | 123 | ||||
-rw-r--r-- | src/usr/targeting/targetservice.C | 567 | ||||
-rw-r--r-- | src/usr/targeting/test/attributestrings.C | 84 | ||||
-rw-r--r-- | src/usr/targeting/test/makefile | 8 | ||||
-rw-r--r-- | src/usr/targeting/test/targetingtest.H | 457 | ||||
-rw-r--r-- | src/usr/targeting/trace.H | 43 |
20 files changed, 4550 insertions, 4 deletions
diff --git a/src/include/usr/targeting/attributeenums.H b/src/include/usr/targeting/attributeenums.H new file mode 100644 index 000000000..c08689e39 --- /dev/null +++ b/src/include/usr/targeting/attributeenums.H @@ -0,0 +1,158 @@ + +#ifndef TARG_ATTRIBUTEENUMS_H +#define TARG_ATTRIBUTEENUMS_H + +/** + * @file attributeenums.H + * + * @brief Defined enums for platform attributes + * + * This header file contains enumerations for supported platform attributes + * (as opposed to HWPF attributes). Eventually this file will be automatically + * generated + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +#include <stdint.h> +#include <stdlib.h> + +//****************************************************************************** +// Enumerations +//****************************************************************************** + +namespace TARGETING +{ + +/** + * @brief Platform attribute IDs + * + * Enumeration defining every possible platform attribute that can be + * associated with a target + */ +enum ATTRIBUTE_ID +{ + ATTR_CLASS = 0x01, + ATTR_TYPE = 0x02, + ATTR_MODEL = 0x03, + ATTR_PHYS_PATH = 0x04, + ATTR_AFFINITY_PATH = 0x05, + ATTR_POWER_PATH = 0x06, + ATTR_PRIMARY_CAPABILITIES = 0x07, + ATTR_XSCOM_BASE_ADDRESS = 0x08, + ATTR_SCOM_SWITCHES = 0x09, + ATTR_XSCOM_CHIP_INFO = 0x0A, + ATTR_INBAND_SCOM_CHIP_INFO = 0x0B, + ATTR_FSI_SCOM_CHIP_INFO = 0x0C, + + ATTR_DUMMY_WO = 0xFD, + ATTR_DUMMY_RO = 0xFE, + ATTR_DUMMY_RW = 0xFF, +}; + +/** + * @brief Target Classes + * + * Enumeration which identifies the general class of a target + */ +enum CLASS +{ + CLASS_NA = 0x00, + CLASS_CARD = 0x01, + CLASS_ENC = 0x02, + CLASS_CHIP = 0x03, + CLASS_UNIT = 0x04, + CLASS_DEV = 0x05, + CLASS_SYS = 0x06, + CLASS_MAX = 0x07, + +}; + +/** + * @brief Target Types + * + * Enumeration which identifies the specific type of target + */ +enum TYPE +{ + TYPE_NA = 0x00, + + // System + TYPE_SYS, + + // Enclosures + TYPE_NODE, + + // Cards + TYPE_DIMM, + TYPE_SCM, + TYPE_DCM, + + // Chips + TYPE_MEMBUF, + TYPE_PROC, + + // Voltage Suppliers + TYPE_MEMVRM, + TYPE_PROCVRM, + + // Processor/Centaur Units + TYPE_EX, + TYPE_CORE, + TYPE_L2, + TYPE_L3, + TYPE_L4, + TYPE_MCS, + TYPE_MBS, + TYPE_MBA, + TYPE_MEM_PORT, + TYPE_PERVASIVE, + TYPE_POWERBUS, + TYPE_XBUS, + TYPE_ABUS, + TYPE_PCI, + + TYPE_LAST_IN_RANGE = TYPE_ABUS + +}; + +/** + * @brief Target Models + * + * Enumeration which identifies the specific model of a target + */ +enum MODEL +{ + MODEL_NA = 0x00, + + // Proc chips/proc units + MODEL_SALERNO = 0x10, + MODEL_VENICE = 0x11, + + // Memory buffers/memory buffer units + MODEL_CENTAUR = 0x30, + + // DIMMs + MODEL_JEDEC = 0x50, + MODEL_CDIMM = 0x51, + + // Systems + MODEL_POWER8 = 0x70, + +}; + +/** + * @brief FSI Engine Types + * + * Enumeration which identifies a specific FSI engine type + */ +enum ENGINE_TYPE +{ + // TBD in future sprint +}; + +} // End namespace TARGETING + +#endif // TARG_ATTRIBUTEENUMS_H diff --git a/src/include/usr/targeting/attributes.H b/src/include/usr/targeting/attributes.H new file mode 100644 index 000000000..bec6e028b --- /dev/null +++ b/src/include/usr/targeting/attributes.H @@ -0,0 +1,25 @@ + +#ifndef TARG_ATTRIBUTES_H +#define TARG_ATTRIBUTES_H + +/** + * @file attributes.H + * + * @brief Enums/type/properties of platform specific attributes + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdint.h> +#include <stdlib.h> + +// This component +#include <targeting/attributeenums.H> +#include <targeting/attributestructs.H> +#include <targeting/attributetraits.H> +#include <targeting/attributestrings.H> + +#endif // TARG_ATTRIBUTES_H diff --git a/src/include/usr/targeting/attributestrings.H b/src/include/usr/targeting/attributestrings.H new file mode 100644 index 000000000..df36f67d2 --- /dev/null +++ b/src/include/usr/targeting/attributestrings.H @@ -0,0 +1,66 @@ + +#ifndef TARG_ATTRIBUTESTRINGS_H +#define TARG_ATTRIBUTESTRINGS_H + +/** + * @file attributestrings.H + * + * @brief Attribute string conversion routines. This file will be auto + * generated in the future + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdint.h> +#include <stdlib.h> + +namespace TARGETING +{ + +/** + * @brief Class used to clarify compiler error when caller attempts to + * stringify an unsupported attribute + */ +class InvalidAttributeForStringification; + +/** + * @brief Return attribute as a string + * + * @param[in] i_attrValue Value of the attribute + * + * @return String which decodes the attribute value + */ +template<const ATTRIBUTE_ID A> +const char* attrToString( + typename AttributeTraits<A>::Type const& i_attrValue) +{ + return InvalidAttributeForStringification(); //"Cannot stringify attr"; +} + +/** + * @brief See attrToString<const ATTRIBUTE_ID A> + */ +template<> +const char* attrToString<ATTR_CLASS>( + AttributeTraits<ATTR_CLASS>::Type const& i_attrValue); + +/** + * @brief See attrToString<const ATTRIBUTE_ID A> + */ +template<> +const char* attrToString<ATTR_TYPE>( + AttributeTraits<ATTR_TYPE>::Type const& i_attrValue); + +/** + * @brief See attrToString<const ATTRIBUTE_ID A> + */ +template<> +const char* attrToString<ATTR_MODEL>( + AttributeTraits<ATTR_MODEL>::Type const& i_attrValue); + +} // End namespace TARGETING + +#endif // TARG_ATTRIBUTESTRINGS_H diff --git a/src/include/usr/targeting/attributestructs.H b/src/include/usr/targeting/attributestructs.H new file mode 100644 index 000000000..e24d5dc71 --- /dev/null +++ b/src/include/usr/targeting/attributestructs.H @@ -0,0 +1,86 @@ + +#ifndef TARG_ATTRIBUTESTRUCTS_H +#define TARG_ATTRIBUTESTRUCTS_H + +/** + * @file attributestructs.H + * + * @brief Complex attribute types + * + * This header file contains definitions for complex attribute types. Note: + * in the future this file may be autogenerated + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdint.h> +#include <stdlib.h> + +// This component +#include <targeting/entitypath.H> + +//****************************************************************************** +// Complex Types +//****************************************************************************** + +namespace TARGETING +{ + +/** + * @brief Structure which defines a target's primary capabilities + * + * Structure which defines a target's primary capabilities. A target can only + * support at most FSI SCOM and one of the other two SCOM types. Applicable + * for all targets. Structure is read-only. + */ +struct PrimaryCapabilities +{ + uint8_t supportsFsiScom : 1; ///< 0b0: Target does not support FSI SCOM + ///< 0b1: Target supports FSI SCOM + uint8_t supportsXscom : 1; ///< 0b0: Target does not support XSCOM + ///< 0b1: Target supports FSI XSCOM + uint8_t supportsInbandScom : 1; ///< 0b0: Target does not support inband + ///< SCOM + ///< 0b1: Target supports inband SCOM + uint8_t reserved : 5; + +} PACKED; + +/** + * @brief Structure which defines which SCOM method to use at a point in time + * + * Structure which defines which SCOM to use at a point in time. Only + * applicable if target supports one or more SCOM types. Only one bit (of the + * first three) can ever be set at any one time. Structure is read-writeable. + */ +struct ScomSwitches +{ + uint8_t useFsiScom : 1; ///< 0b0: Do not use FSI SCOM at this time + ///< 0b1: Use FSI SCOM at this time + uint8_t useXscom : 1; ///< 0b0: Do not use XSCOM at this time + ///< 0b1: Use XSCOM at this time + uint8_t useInbandScom : 1; ///< 0b0: Do not use inband SCOM at this time + ///< 0b1: Use inband SCOM at this time + uint8_t reserved : 5; ///< Reserved bits + +} PACKED; + +/** + * @brief Structure which defines chip info necessary for XSCOM + * + * Structure which defines chip info necessary for XSCOM. Only + * applicable for chip targets which support XSCOM. Structure is read-only. + */ +struct XscomChipInfo +{ + uint8_t nodeId; // Unique ID of node containing the chip + uint8_t chipId; // Unique ID of chip, relative to node + +} PACKED; + +} // End namespace TARGETING + +#endif // TARG_ATTRIBUTESTRUCTS_H diff --git a/src/include/usr/targeting/attributetraits.H b/src/include/usr/targeting/attributetraits.H new file mode 100644 index 000000000..b9931563a --- /dev/null +++ b/src/include/usr/targeting/attributetraits.H @@ -0,0 +1,160 @@ + +#ifndef TARG_ATTRIBUTETRAITS_H +#define TARG_ATTRIBUTETRAITS_H + +/** + * @file attributetraits.H + * + * @brief Templates which map attributes to their type/properties + * + * This header file contains templates which map attributes to their + * type/properties + * + * This file -will- be autogenerated in the future + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdint.h> +#include <stdlib.h> + +namespace TARGETING +{ + +//****************************************************************************** +// Attribute Property Mappings +//****************************************************************************** + +/** + * @brief Template associating a specific attribute with a type and other + * properties, such as whether it is readable/writable + * + * This will eventually be automatically generated + * + * enum { + * disabled = Special value for the basic attribute + * readable = Attribute is readable + * writable = Attribute is writable + * hasStringConversion = Attribute has debug string conversion + * } + * + * typedef <type> TYPE // <type> is the Attribute's valid type + */ +template<const ATTRIBUTE_ID A> +class AttributeTraits +{ + private: + enum { disabled }; + typedef void* Type; +}; + +template<> +class AttributeTraits<ATTR_CLASS> +{ + public: + enum { readable, hasStringConversion }; + typedef CLASS Type; +}; + +template<> +class AttributeTraits<ATTR_TYPE> +{ + public: + enum { readable, hasStringConversion }; + typedef TYPE Type; +}; + +template<> +class AttributeTraits<ATTR_MODEL> +{ + public: + enum { readable, hasStringConversion }; + typedef MODEL Type; +}; + +template<> +class AttributeTraits<ATTR_DUMMY_RW> +{ + public: + enum { readable, writeable }; + typedef uint8_t Type; +}; + +template<> +class AttributeTraits<ATTR_DUMMY_WO> +{ + public: + enum { writeable }; + typedef uint8_t Type; +}; + +template<> +class AttributeTraits<ATTR_DUMMY_RO> +{ + public: + enum { readable }; + typedef uint8_t Type; +}; + +template<> +class AttributeTraits<ATTR_PHYS_PATH> +{ + public: + enum { readable }; + typedef EntityPath Type; +}; + +template<> +class AttributeTraits<ATTR_AFFINITY_PATH> +{ + public: + enum { readable }; + typedef EntityPath Type; +}; + +template<> +class AttributeTraits<ATTR_POWER_PATH> +{ + public: + enum { readable }; + typedef EntityPath Type; +}; + +template<> +class AttributeTraits<ATTR_PRIMARY_CAPABILITIES> +{ + public: + enum { readable }; + typedef PrimaryCapabilities Type; +}; + +template<> +class AttributeTraits<ATTR_SCOM_SWITCHES> +{ + public: + enum { readable, writable }; + typedef ScomSwitches Type; +}; + +template<> +class AttributeTraits<ATTR_XSCOM_BASE_ADDRESS> +{ + public: + enum { readable }; + typedef uint64_t Type; +}; + +template<> +class AttributeTraits<ATTR_XSCOM_CHIP_INFO> +{ + public: + enum { readable }; + typedef XscomChipInfo Type; +}; + +} // End namespace TARGETING + +#endif // TARG_ATTRIBUTETRAITS_H diff --git a/src/include/usr/targeting/entitypath.H b/src/include/usr/targeting/entitypath.H new file mode 100644 index 000000000..27af7120c --- /dev/null +++ b/src/include/usr/targeting/entitypath.H @@ -0,0 +1,400 @@ + +#ifndef TARG_ENTITYPATH_H +#define TARG_ENTITYPATH_H + +/** + * @file entitypath.H + * + * @brief Interface for the EntityPath class + * + * This header file contains the interface for the EntityPath class which + * supports hierarchical path representation of various flavors + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdint.h> +#include <stdlib.h> +#include <vector> + +namespace TARGETING +{ + +class Target; + +/** + * @brief Entity path class which represents a target's relationship(s) to + * other targets + * + * Entity path class which represents a target's relationship(s) to other + * targets via hierarchical paths. Entity paths can represent different + * relationships, such as logical containment (where part X contains part Y + * contains part Z), hardware affinity, etc. An entity path is composed of + * a number of type/instance pairs that represent a given target in a given + * hierarchy. In the logical containment example, part Z's logical containment + * path would look something like partX-0/partY-1/partZ-0. + */ +class EntityPath +{ + public: + + /** + * @brief Maximum number of path elements than an entity path can have + */ + enum + { + MAX_PATH_ELEMENTS = 8, + }; + + /** + * @brief Entity Path Types + * + * An entity path type indicates which specific set of relationships is + * modeled by a particular entity path. For example, PATH_AFFINITY + * models how targets are connected to each other from a hardware + * affinity perspective. + */ + enum PATH_TYPE + { + PATH_NA = 0x00, ///< Not applicable + PATH_AFFINITY = 0x01, ///< Entity path models hardware affinity + ///< relationships + PATH_PHYSICAL = 0x02, ///< Entity path models logical containment + ///< relationships + PATH_DEVICE = 0x03, ///< Entity path models a device driver path + PATH_POWER = 0x04, ///< Entity path models power provider and + ///< power consumer relationships + }; + + /** + * @brief Entity Path Element Definition + * + * Any entity path models one level of an entity path hierarchy + */ + struct PathElement + { + TYPE type; ///< Type of element at this level in the hierarchy + uint8_t instance; ///< Instance ID for the element, relative to + ///< the parent + + } PACKED; + + /** + * @brief Creates an entity path object, based on path type + * + * Creates an entity path of the specified type, but does not populate + * it with any path elements. + * + * @param[in] i_pathType Type of entity path to create + * + * @post Entity path of specified type created with no path elements + */ + EntityPath( + PATH_TYPE i_pathType); + + /** + * @brief Creates an empty entity path object + * + * Creates an empty entity path of N/A type and does not populate it + * with any path elements. The caller must initialize the type and + * populate it with path elements as needed + * + * @post Entity path created with default type and no path elements + */ + EntityPath(); + + /** + * @brief Destroys an entity path object + * + * Destroys an entity path object and frees all resources it + * exclusively owns. + * + * @post Entity path destroyed and all previously owned exclusive + * resources freed + */ + ~EntityPath(); + + /** + * @brief Removes/clears the last path element from an entity path + * + * Removes/clears the last path element from an entity path. If the + * caller attempts this operation and no path elements exist, the + * routine asserts. + * + * @post Entity path element removed from path + */ + EntityPath& removeLast(); + + /** + * @brief Returns a copy of the entity path with the last path + * element removed. The original entity path is not altered + * + * Returns a copy of the entity path with the last path + * element removed, useful for non-destructive transformations. + * caller attempts this operation and no path elements exist, the + * routine asserts. The original entity path is not altered. + * Equivalent to p1 = p2; p1.removeLast(); + * + * @post Copy of entity path with last element removed returned + */ + EntityPath copyRemoveLast() const; + + /** + * @brief Adds a path element to the end of an existing entity path + * object + * + * Adds a path element to the end of an existing entity path object. + * If the new path exceeds the maximum allowable number of path + * elements, the routine asserts + * + * @param[in] i_type Type of path element to add + * @param[in] i_instance Instance # of path element to add + * + * @pre N/A + * + * @post Entity path will increased by one path element, as specified + * by the input parameters + * + * @return Reference to the larger entity path + */ + EntityPath& addLast( + TYPE i_type, + uint8_t i_instance); + + /** + * @brief Returns a copy of the entity path with the specified + * path element added to the end. The original entity path is not + * altered + * + * Returns a copy of the entity path with the specified path element + * added to the end. If the new path exceeds the maximum allowable + * number of path elements, the routine asserts. The original entity + * path is not altered. Equivalent to p1 = p2. p1.addLast(..); + * + * @param[in] i_type Type of path element to add + * @param[in] i_instance Instance # of path element to add + * + * @pre N/A + * + * @post Copy of entity path with additional path element returned to + * caller + * + * @return Copy of the entity path with an additional path element + */ + EntityPath copyAddLast( + TYPE i_type, + uint8_t i_instance) const; + + /** + * @brief Returns a target handle to the target referred to by the + * entity path object + * + * Returns a target handle to the target referred to by the + * entity path object if it exists (NULL otherwise) + * + * @pre N/A + * + * @post Target handle returned to caller or NULL (if related target + * doesn't exist) + * + * @return Target handle + * + * @retval NULL Target doesn't exist + * @retval !NULL Target handle to the target referred to by the entity + * path + */ + Target* operator->(void); + + /** + * @brief Returns whether two entity paths are logically equal + * + * Returns whether two entity paths are logically equal. This + * determination takes into account the entity path type, the number + * of path elements, and the values of the path elements themselves. + * + * @param[in] i_rhs Const reference to entity path to compare + * + * @pre N/A + * + * @post Equality returned to caller + * + * @return bool indicating whether two entity paths are logically equal + * + * @retval true The entity paths are logically equal + * @retval false The entity paths are not logically equal + */ + bool operator==( + const EntityPath& i_rhs) const; + + /** + * @brief Returns whether two entity paths are logically equal, but + * only for the specified number of path elements + * + * Returns whether two entity paths are logically equal, but only for + * the specified number of path elements. This determination takes + * into account the entity path type, the specified number of path + * elements, and the values of the subset of path elements to be + * compared. For example, a device path of + * fsi0/cfam0/fsi0/cfam1/engine0 is equal to fsi0/cfam0 if the + * specified number of path elements is 1 or 2. + * + * @param[in] i_rhs Const reference to entity path to compare + * @param[in] i_size Number of path elements to compare; must be + * <= this->size() (otherwise routine will assert) + * + * @pre N/A + * + * @post Equality (for specified number of path elements) returned to + * caller + * + * @return bool indicating whether two entity paths are logically equal + * for the specified number of path elements (or assertion if + * specified size > this->size()) + * + * @retval true The entity paths are logically equal for the specified + * number of path elements + * @retval false The entity paths are not logically equal for the + * specified number of path elements + */ + bool equals( + const EntityPath& i_rhs, + uint32_t i_size) const; + + /** + * @brief Returns the path element at the specified index + * + * Returns the path element at the specified index (zero based). The + * routine will assert if the index exceeds this->size()-1; + * + * @param[in] i_index Path element to return (0 based indexing) + * + * @pre N/A + * + * @post Path element returned to caller on valid index. Assert + * triggered on invalid index. + * + * @return PathElement at the position in the entity path specified by + * index + */ + const PathElement& operator[]( + uint32_t i_index) const; + + /** + * @brief Returns the number of path elements + * + * Returns the number of path elements for the entity path. + * + * @pre N/A + * + * @post Number of path elements returned to caller + * + * @return uint32_t giving the number of path elements + */ + uint32_t size() const; + + /** + * @brief Sets the path type + * + * Sets the path type for the entity path + * + * @param[in] i_pathType Path type specifier + * + * @pre N/A + * + * @post Path type set to the specified value + * + * @return N/A + */ + void setType( + PATH_TYPE i_pathType); + + /** + * @brief Returns the path type + * + * Returns the path type for the entity path + * + * @pre N/A + * + * @post Path type returned to caller + * + * @return PATH_TYPE indicating the entity path's path type + */ + PATH_TYPE type() const; + + /** + * @brief DEBUG ONLY. Returns the path type as a string. + * + * Returns the string encoding of the path type + * + * @pre N/A + * + * @post Path type string returned to caller + * + * @return String representation of the path type + */ + const char* pathTypeAsString() const; + + /** + * @brief DEBUG ONLY. Returns the path element type as a string. + * + * Returns the string encoding of the path element type + * + * @param[in] i_type Path element type to translate + * + * @pre N/A + * + * @post Path element type string returned to caller + * + * @return String representation of the path element type + */ + const char* pathElementTypeAsString( + TYPE i_type) const; + + /** + * @brief DEBUG ONLY. Returns the path element engine instance as a + * string. + * + * @param[in] i_engine Path element engine instance to translate + * + * Returns the string encoding of the path element engine instance + * + * @pre N/A + * + * @post Path element engine instance string returned to caller + * + * @return String representation of the path element engine instance + */ + const char* pathEngineInstanceAsString( + ENGINE_TYPE i_engine) const; + + /** + * @brief DEBUG ONLY. Dump the entity path + * + * Dumps the entity path + * + * @pre N/A + * + * @post Entity path dumped + * + * @return N/A + */ + void dump() const; + + private: + + PATH_TYPE iv_type : 4; ///< Entity path type (4 bits) + uint8_t iv_size : 4; ///< Number of path elements (4 bits) + PathElement iv_pathElement[MAX_PATH_ELEMENTS]; ///< Array of path + ///< elements + + // Compiler generated copy and assignment operators explicitly + // allowed and used + +} PACKED; + +} // End namespace TARGETING + +#endif // TARG_ENTITYPATH_H diff --git a/src/include/usr/targeting/target.H b/src/include/usr/targeting/target.H new file mode 100644 index 000000000..f2764aca8 --- /dev/null +++ b/src/include/usr/targeting/target.H @@ -0,0 +1,304 @@ + +#ifndef TARG_TARGET_H +#define TARG_TARGET_H + +/** + * @file target.H + * + * @brief Interface for the target class + * + * This header file contains the interface for the target class which + * associates entities of interest to host boot to their various attributes + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdint.h> +#include <stdlib.h> +#include <assert.h> +#include <vector> + +// This component +#include <targeting/attributes.H> + +namespace TARGETING +{ + +//****************************************************************************** +// Type Aliases +//****************************************************************************** + +class Target; +typedef const Target* ConstTargetHandle_t; +typedef Target* TargetHandle_t; + +typedef std::vector<TargetHandle_t> TargetHandleList; +typedef std::vector<Target> TargetList; + +class Target +{ + public: // Constructors and destructors + + /** + * @brief Destroys the target + * + * Destroys the target, and any exclusively owned resources + * + * @post Target is destroyed, and all exclusively owned resources are + * reclaimed + */ + ~Target(); + + public: // User interface + + /** + * @brief Try to get the target's specified attribute value + * + * Attempts to return the target's specified attribute value. It + * returns false (with invalid o_attrValue) if the specified attribute + * does not exist for the associated target, true (with a valid + * o_attrValue) otherwise. + * + * @param[out] o_attrValue Value of the attribute + * + * @pre Target service must be initialized + * + * @post See "return" + * + * @return bool indicating whether the specified attribute was returned + * or not + * + * @retval true Attribute returned in o_attrValue + * @retval false Attribute not found; o_attValue not valid + */ + template<const ATTRIBUTE_ID A> + inline bool tryGetAttr( + typename AttributeTraits<A>::Type& o_attrValue) const + { + // Note: the compiler optimizes the following check (which fails + // at compile time if the attribute is not readable) away + if(AttributeTraits<A>::readable) { } + return _tryGetAttr(A,sizeof(o_attrValue),&o_attrValue); + } + + /** + * @brief Get the target's specified attribute value + * + * Returns the target's specified attribute value. If the specified + * attribute does not exist for the associated target, the routine + * asserts. Thus callers must be sure the attribute exists for the + * given target. + * + * @pre Target service must be initialized + * + * @post Target's specified attribute value returned, or assert + * called if specified attribute doesn't exist for the + * associated target + * + * @return Data type associated with the attribute being returned + * + * @retval Varies The attribute data + */ + template<const ATTRIBUTE_ID A> + typename AttributeTraits<A>::Type getAttr() const; + + /** + * @brief DEBUG ONLY! Returns the requested attribute as a string + * + * Returns the attribute value (for the associated target) as a string. + * If the specified attribute does not have a string conversion, the + * compile will fail. + * + * @pre Target service must be initialized + * + * @post Specified attribute's value returned as a string. If the + * specified attribute does not exist, the routine asserts. + * + * @return String representing the attribute + * + * @retval Varies based on the attribute type and value + */ + template<const ATTRIBUTE_ID A> + const char* getAttrAsString() const; + + /** + * @brief Tries to set the target's specified attribute value + * + * Attempts to set the target's specified attribute value. It + * returns false if the specified attribute does not exist for the + * associated target, true otherwise. + * + * @param[in] i_attrValue Value of the attribute + * + * @pre Target service must be initialized + * + * @post Target's attribute value updated (if it exists), and caller + * notified whether the update occurred or not. + * + * @return bool indicating whether the specified attribute was updated + * or not + * + * @retval true Attribute updated + * @retval false Attribute not updated + */ + template<const ATTRIBUTE_ID A> + bool trySetAttr( + typename AttributeTraits<A>::Type const& i_attrValue) + { + // Note: the compiler optimizes the following check (which fails + // at compile time if the attribute is not writable) away + if(AttributeTraits<A>::writeable) { } + return _trySetAttr(A,sizeof(i_attrValue),&i_attrValue); + } + + /** + * @brief Sets the target's specified attribute value + * + * Sets the target's specified attribute value. + * + * @param[in] i_attrValue Value of the attribute + * + * @pre Target service must be initialized + * + * @post Target's attribute value updated if it exists, otherwise + * routine asserts + */ + template<const ATTRIBUTE_ID A> + void setAttr( + typename AttributeTraits<A>::Type const& i_attrValue) + { + bool l_wrote = trySetAttr<A>(i_attrValue); + assert(l_wrote); + } + + private: // Private helper interfaces + + /** + * @brief Tries to get the target's specified attribute value + * + * Tries to get the target's specified attribute value + * + * @param[in] i_attr Attribute to retrieve + * @param[in] i_size Size of the attribute + * @param[in/out] io_attrData On input, location to store the attribute. + * On output, location updated with attribute data + * + * @pre Target service must be initialized + * + * @post Caller notified if attribute retrieval succeeded or not. If + * so, the attribute data is stored at io_addrData + * + * @return bool indicating if attribute retrieval succeeded or not + * + * @retval true Attribute retrieval succeeded + * @retval false Attribute retrieval failed + */ + bool _tryGetAttr( + ATTRIBUTE_ID i_attr, + uint32_t i_size, + void* io_attrData) const; + + /** + * @brief Tries to set the target's specified attribute value + * + * Tries to set the target's specified attribute value + * + * @param[in] i_attr Attribute to retrieve + * @param[in] i_size Size of the attribute + * @param[in] i_pAttrData Location holding the attribute data to set + * + * @pre Target service must be initialized + * + * @post If attribute exists for the associated target, attribute value + * updated and success (true) returned. Otherwise, attribute value + * not updated and failure (false) returned. + * + * @return bool indicating if attribute update succeeded or not + * + * @retval true Attribute update succeeded + * @retval false Attribute update failed + */ + bool _trySetAttr( + ATTRIBUTE_ID i_attr, + uint32_t i_size, + const void* i_pAttrData) const; + + /** + * @brief Gets a pointer to the target's associated attribute + * + * Gets a pointer to the target's associated attribute + * + * @param[in] i_attr Attribute to retrieve + * @param[out] o_pAttr Pointer to data location to hold the attribute + * data + * + * @pre Target service must be initialized + * + * @post If attribute exists for the associated target, caller's + * pointer updated with associated attribute pointer. Otherwise, + * caller's pointer updated to NULL. + */ + void _getAttrPtr( + ATTRIBUTE_ID i_attr, + void*& o_pAttr) const; + + private: // Private instance variables + + uint32_t iv_attrs; ///< Total attributes allowed for this + ///< instance + ATTRIBUTE_ID (*iv_pAttrNames)[]; ///< Pointer to array of valid + ///< attributes + void* (*iv_pAttrValues)[]; ///< Pointer to array of void*'s + ///< (which point to individual + ///< attributes) + + private: // Private CTORs/DTORs/Operators + + /** + * @brief Build a target object + * + * Builds a target object; currently there is little to no need to + * construct new targets; they are already preloaded in PNOR. + */ + Target(); + + // Disable the copy constructor/assignment operator. + + Target( + const Target& i_right); + + Target& operator=( + const Target& i_right); + + friend class PnorBuilderService; + +} PACKED; + +template<const ATTRIBUTE_ID A> +typename AttributeTraits<A>::Type Target::getAttr() const +{ + typename AttributeTraits<A>::Type l_attrValue; + bool l_read = tryGetAttr<A>(l_attrValue); + assert(l_read); + return l_attrValue; +} + +template<const ATTRIBUTE_ID A> +const char* Target::getAttrAsString() const +{ + // Note: the compiler optimizes the following check (which fails + // at compile time if the attribute does not have a string + // conversion) away + if(AttributeTraits<A>::hasStringConversion) { } + typename AttributeTraits<A>::Type l_attrValue; + bool l_read = tryGetAttr<A>(l_attrValue); + assert(l_read); + return attrToString<A>(l_attrValue); +} + +} // End namespace TARGETING + +#endif // TARG_TARGET_H diff --git a/src/include/usr/targeting/targetservice.H b/src/include/usr/targeting/targetservice.H new file mode 100644 index 000000000..2797890c5 --- /dev/null +++ b/src/include/usr/targeting/targetservice.H @@ -0,0 +1,461 @@ + +#ifndef TARG_TARGETSERVICE_H +#define TARG_TARGETSERVICE_H + +/** + * @file targetservice.H + * + * @brief Interface for the target service + * + * This header file contains the interface definition for the target service + * which is responsible for configuring and aggregating the pool of valid + * targets, and providing services to access targets based on various criteria + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdint.h> +#include <stdlib.h> +#include <vector> + +// Other components +#include <util/singleton.H> + +// This component +#include <targeting/attributeenums.H> +#include <targeting/target.H> +#include <targeting/entitypath.H> + +//****************************************************************************** +// Interface Definitions +//****************************************************************************** + +//****************************************************************************** +// Method to access the targeting service externally +//****************************************************************************** + +namespace TARGETING +{ + class TargetService; + + /** + * @brief Returns a reference to the targeting service singleton + * + * @return Reference to the targeting service + */ + TARGETING::TargetService& targetService(); + +/** + * @brief Sentinel representing the master processor chip target early in + * host boot prior to initialization of the target service. Needed by the + * DD framework to bring PNOR device driver online. Note this target + * cannot be used as input to any target service APIs. + */ +static Target* const MASTER_PROCESSOR_CHIP_TARGET_SENTINEL + = reinterpret_cast<TARGETING::Target* const>(0xFFFFFFFFFFFFFFFFULL); + +/** + * @brief TargetService class + * + * This class manages the set of possible targets and provides facility to + * access specific targets, based on given criteria + */ +class TargetService +{ + public: + + /** + * @brief Enum specifying the recursion depth for target searching + * + * Indicates whether to return only IMMEDIATE children/parent of a + * target, or ALL children/parents of a target + */ + enum RECURSION_LEVEL + { + IMMEDIATE = 0x01, ///< Return immediate children/parent of a target + ALL = 0x02, ///< Return all children/parents of a target + }; + + /** + * @brief Enum specifying the type of association between targets + * + * Indicates what relationship the result target should have to the + * target in question + */ + enum ASSOCIATION_TYPE + { + PARENT, ///< The result target(s) should be parents by + ///< containment + CHILD, ///< The result target(s) should be children by + ///< containment + PARENT_BY_AFFINITY, ///< The result target(s) should be the parents + ///< by hardware affinity + CHILD_BY_AFFINITY, ///< The result target(s) should be children by + ///< Hardware affinity. For example the child + ///< of a memory controller channel target might + ///< be a DIMM target + VOLTAGE_SUPPLIER, ///< The result target(s) should be the voltage + ///< supplier + VOLTAGE_CONSUMER, ///< The result target(s) should be the voltage + ///< consumer + }; + + public: + + /** + * @brief Construct the target service + * + * Constructs the target service, but does not actually initialize the + * target pool + * + * @post Target service instantiated, but target pool not initialized + */ + TargetService(); + + /** + * @brief Destroys the target service + * + * Destroys the target service; it should never be run since it hides + * behind a singleton, but is included for completeness + * + * @post Target service is destroyed, and all owned resources are + * reclaimed + */ + ~TargetService(); + + /** + * @brief Initializes the target service + * + * 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 + * + * @pre N/A + * + * @post Target service fully initialized with all possible targets + */ + void init(); + + /** + * @brief Returns the top level physical target + * + * Returns the top level (usually system) target. Caller must check + * for a NULL top level target + * + * @param[out] o_targetHandle Top level target handle + * + * @pre N/A + * + * @post The returned handle is NULL if a top level target doesn't + * exist or service not initialized, otherwise it references a + * valid top level target + */ + void getTopLevelTarget( + Target*& o_targetHandle) const; + + /** + * @brief Returns whether specified entity path corresponds to a real + * target + * + * Consults the specified entity path and searches through all + * available targets to find a matching entity path attribute. If it + * finds a match, then the associated target exists, otherwise it does + * not exist + * + * @param[in] i_entityPath Entity path to verify for existence + * @param[out] o_exists Whether the entity path corresponds to a + * target + * + * @pre N/A + * + * @post "true" returned to caller if specified entity path exists, + * "false" if not or service not initialized + */ + void exists( + const EntityPath& i_entityPath, + bool& o_exists) const; + + /** + * @brief Returns a target handle which has an associated entity path + * matching the specified entity path + * + * Returns a target handle which has an associated entity path + * matching the specified entity path. Caller must check the + * returned handle for NULL. + * + * @param[in] i_entityPath Entity path for which to find the matching + * target handle + * + * @pre N/A + * + * @post NULL returned to caller if no match was found or service + * not initialized, otherwise a valid handle returned + * + * @return Target handle + * + * @retval NULL No target match found + * @retval !NULL Handle to the corresponding target + */ + Target* toTarget( + const EntityPath& i_entityPath) const; + + /** + * @brief Returns the master processor chip target handle + * + * Returns the master processor chip target handle. On systems + * without an alternate master, it returns a handle to the only master, + * if found (NULL otherwise). On systems 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) + * + * @param[out] o_masterProcChipTarget Target handle referring to the + * current master processor chip (the one connected to PNOR) + * + * @pre None + * + * @post Master processor chip targets returned or a dummy value + * representing the acting master processor chip if the targeting + * information is not yet initialized + */ + void masterProcChipTargetHandle( + Target*& o_masterProcChipTargetHandle) const; + + /** + * @brief Returns whether the specified entity path attribute exists + * for a specified target, and if so, the value of that attribute + * + * Returns whether the specified entity path attribute exists for a + * specified target, and if so, the value of that attribute. If the + * target doesn't exist, or the attribute doesn't correspond to an + * entity path attribute, or the entity path attribute doesn't exist + * for the target, then the routine returns false and the entity path + * value is invalid. + * + * @param[in] i_attr Entity path attribute to read + * @param[in] i_pTarget Target handle to read the attribute from + * @param[out] o_entityPath Value of the target's associated entity + * path value + * + * @pre N/A + * + * @post See "return" + * + * @return bool indicating whether the specified attribute exists + * for the specified target and whether the returned entity path + * value is valid + * + * @retval true Specified attribute exists, entity path is valid + * @retval false Specified attribute does not exist, entity path is + * invalid + */ + bool tryGetPath( + ATTRIBUTE_ID i_attr, + const Target* i_pTarget, + EntityPath& o_entityPath) const; + + /** + * @brief Returns entity paths of targets associated to the specified + * target in a specific way + * + * Returns entity paths of targets associated to the specified target, + * as indicated by an association type. Based on the specified + * recursion level, the routine will determine the immediate + * associations, or all possible associations. For example, if caller + * supplies a processor chip target and asks for its children targets, + * the routine will return the next set of targets in the physical + * hierarchy. Conversely if the caller asks for ALL children targets + * for said source target, the routine will return all targets + * contained within the processor chip. + * + * @param[in] i_pTarget Target from which to search for other targets + * @param[in] i_type Type of association linking the specified target + * to candidate result targets + * @param[in] i_recursionLevel Whether to return candidate targets + * immediately associated to the specified target or recursively + * associated to it. + * @param[out] o_list List of target handles that match the specified + * criteria + * + * @pre N/A + * + * @post Caller's list cleared; list of target handles matching the + * specified criteria returned + */ + void getAssociated( + const Target* i_pTarget, + ASSOCIATION_TYPE i_type, + RECURSION_LEVEL i_recursionLevel, + TargetHandleList& o_list) const; + + /** + * @brief Dump the target service for debug only + * + * @post Output written to buffer + */ + void dump() const; + + private: + + /** + * @brief Enum specifying which direction to traverse associations + * between targets + * + * Given a general class of association between targets, this enum + * tells the target service which direction to search along an entity + * path for the result targets + */ + enum ASSOCIATION_DIRECTION + { + INWARDS, ///< Search for associated targets of the specified target + ///< that happen to be closer to the top level target + OUTWARDS, ///< Search for associated targets of the specified target + ///< that happen to be farther from the top level target + }; + + /** + * @brief Structure mapping an association type to an entity path + * attribute and entity path search direction + * + * This map allows the target service to accept an association type + * from a caller and determine the appropriate entity path to search + * along for the result target, and in which direction along the path + */ + struct AssociationAttrMap + { + ASSOCIATION_TYPE associationType; ///< Specifies the type of + ///< association to traverse + ASSOCIATION_DIRECTION associationDir; ///< Specifies which + ///< direction along an + ///< entity path to search + ATTRIBUTE_ID attr; ///< Specifies which entity + ///< path to search along + }; + + /** + * @brief Aliases a vector of association mappings + */ + typedef std::vector< AssociationAttrMap > AssociationMappings_t; + + /** + * @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 + * + * @pre Target service must not be initialized + * + * @post Target service target pool configured for access + */ + void _configureTargetPool(); + + /** + * @brief Computes the maximum number of targets, caches the value + * and returns it to the caller + * + * Computes the maximum number of targets possible based on the PNOR + * (or override) image and returns it to the caller + * + * @pre Target service must not already be initialized + * + * @post Target service updated with maximum target count. Count also + * returned to caller + * + * @return uint32_t indicating the maximum number of targets possible + */ + uint32_t _maxTargets(); + + /** + * @brief Returns handles to the targets associated to the + * target represented by the specified entity path such that the + * results are closer to the top level target than the source + * + * Returns handles to the targets associated to the target represented + * by the specified entity path such that the results are closer to the + * top level target than the source. An IMMEDIATE recursion level + * returns handles to targets that are one association away from the + * target referenced by the supplied entity path. A recursion level of + * ALL recursively returns results. + * + * @param[in] i_attr Entity path attribute that is used as the basis + * for lookups on candidate targets + * @param[in] i_recursionLevel Whether to provide immediate or + * recursive results + * @param[in] i_entityPath Entity path to start search from + * @param[out] o_list List of returned target handles + * + * @pre Target service must be initialized + * + * @post List of target handles corresponding to targets closer to the + * top level target than the one referenced by the specified entity + * path returned + */ + void _getInwards( + ATTRIBUTE_ID i_attr, + RECURSION_LEVEL i_recursionLevel, + EntityPath i_entityPath, + TargetHandleList& o_list) const; + + /** + * @brief Returns handles to the targets associated to the + * target represented by the specified entity path such that the + * results are farther from the top level target than the source + * + * Returns handles to the targets associated to the target represented + * by the specified entity path such that the results are farther from + * the top level target than the source. An IMMEDIATE recursion level + * returns handles to targets that are one association away from the + * target referenced by the supplied entity path. A recursion level of + * ALL recursively returns results. + * + * @param[in] i_attr Entity path attribute that is used as the basis + * for lookups on candidate targets + * @param[in] i_recursionLevel Whether to provide immediate or + * recursive results + * @param[in] i_entityPath Entity path to look from + * @param[out] o_list List of returned target handles + * + * @pre Target service must be initialized + * + * @post List of target handles corresponding to targets farther from + * the top level target than the one referenced by the specified + * entity path returned. + */ + void _getOutwards( + ATTRIBUTE_ID i_attr, + RECURSION_LEVEL i_recursionLevel, + EntityPath i_entityPath, + TargetHandleList& o_list ) const; + + // 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 + + // Disable copy constructor / assignment operator + + TargetService( + const TargetService& i_right); + + TargetService& operator=( + const TargetService& i_right); +}; + +/** + * @brief Singleton to access the only TargetService; deemphasized + * intentionally + */ +class TargetService; +typedef Singleton<TARGETING::TargetService> theTargetService; + +} // End namespace TARGETING + +#endif // TARG_TARGETSERVICE_H diff --git a/src/makefile b/src/makefile index 351caa289..5411d747a 100644 --- a/src/makefile +++ b/src/makefile @@ -16,22 +16,23 @@ DIRECT_BOOT_OBJECTS = start.o kernel.o taskmgr.o cpumgr.o syscall.o \ RUNTIME_OBJECTS = BASE_MODULES = trace errl devicefw scom xscom +EXTENDED_MODULES = targeting DIRECT_BOOT_MODULES = example RUNTIME_MODULES = TESTCASE_MODULES = cxxtest testerrl testdevicefw testsyslib \ - testscom testxscom + testscom testxscom testtargeting RELOCATABLE_IMAGE_LDFLAGS = -pie --export-dynamic hbicore_OBJECTS = ${BASE_OBJECTS} ${DIRECT_BOOT_OBJECTS} -hbicore_MODULES = ${BASE_MODULES} ${DIRECT_BOOT_MODULES} +hbicore_MODULES = ${BASE_MODULES} ${EXTENDED_MODULES} ${DIRECT_BOOT_MODULES} hbicore_LIDNUMBER = 80f00100 hbicore_test_OBJECTS = ${hbicore_OBJECTS} hbicore_test_MODULES = ${hbicore_MODULES} ${TESTCASE_MODULES} #halruntime_OBJECTS = ${BASE_OBJECTS} ${RUNTIME_OBJECTS} -#halruntime_MODULES = ${BASE_MODULES} ${RUNTIME_MODULES} +#halruntime_MODULES = ${BASE_MODULES} ${EXTENDED_MODULES} ${RUNTIME_MODULES} #halruntime_LDFLAGS = ${RELOCATABLE_IMAGE_LDFLAGS} #halruntime_LIDNUMBER = 80f00101 diff --git a/src/usr/makefile b/src/usr/makefile index c1a57cddb..0f0ec8e65 100644 --- a/src/usr/makefile +++ b/src/usr/makefile @@ -1,7 +1,8 @@ ROOTPATH = ../.. OBJS = module_init.o + SUBDIRS = example.d trace.d cxxtest.d testcore.d errl.d devicefw.d \ - scom.d xscom.d + scom.d xscom.d targeting.d include ${ROOTPATH}/config.mk diff --git a/src/usr/targeting/entitypath.C b/src/usr/targeting/entitypath.C new file mode 100644 index 000000000..024c563ee --- /dev/null +++ b/src/usr/targeting/entitypath.C @@ -0,0 +1,400 @@ + +/** + * @file entitypath.C + * + * @brief Implementation of the EntityPath class + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <trace/interface.H> + +// This component +#include <targeting/target.H> +#include <targeting/targetservice.H> +#include "trace.H" + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" +#define TARG_CLASS "EntityPath::" + +extern trace_desc_t* g_trac_targeting; + +//****************************************************************************** +// EntityPath::EntityPath (Path Type Constructor) +//****************************************************************************** + +EntityPath::EntityPath( + const PATH_TYPE i_pathType) + : iv_type(i_pathType), iv_size(0) +{ + #define TARG_FN "EntityPath(...)" + + memset(&iv_pathElement[0], 0x00, sizeof(iv_pathElement)); + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::EntityPath (Full Constructor) +//****************************************************************************** + +EntityPath::EntityPath() + : iv_type(PATH_NA), iv_size(0) +{ + #define TARG_FN "EntityPath()" + + memset(&iv_pathElement[0], 0x00, sizeof(iv_pathElement)); + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::~EntityPath +//****************************************************************************** + +EntityPath::~EntityPath() +{ + #define TARG_FN "~EntityPath()" + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::removeLast +//****************************************************************************** + +EntityPath& EntityPath::removeLast() +{ + #define TARG_FN "removeLast()" + + if(size() < 1) + { + TARG_ERR("Entity path empty (%d); cannot remove any path elements", + size()); + assert(0); + } + + iv_pathElement[size() - 1].type = TYPE_NA; + iv_pathElement[size() - 1].instance = 0; + --iv_size; + return *this; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::copyRemoveLast +//****************************************************************************** + +EntityPath EntityPath::copyRemoveLast() const +{ + #define TARG_FN "copyRemoveLast()" + + EntityPath l_newPath = *this; + l_newPath.removeLast(); + return l_newPath; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::addLast +//****************************************************************************** + +EntityPath& EntityPath::addLast( + const TYPE i_type, + const uint8_t i_instance) +{ + #define TARG_FN "addLast(...)" + + if(size() >= MAX_PATH_ELEMENTS) + { + TARG_ERR("Entity path cannot store any more path elements with size %d", + size()); + assert(size() < MAX_PATH_ELEMENTS); + } + + iv_pathElement[size()].type = i_type; + iv_pathElement[size()].instance = i_instance; + ++iv_size; + return *this; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::copyAddLast +//****************************************************************************** + +EntityPath EntityPath::copyAddLast( + const TYPE i_type, + const uint8_t i_instance) const +{ + #define TARG_FN "copyAddLast(...)" + + EntityPath l_newPath = *this; + l_newPath.addLast(i_type,i_instance); + return l_newPath; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::operator-> +//****************************************************************************** + +Target* EntityPath::operator->(void) +{ + #define TARG_FN "operator->()" + + return theTargetService::instance().toTarget(*this); + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::operator== +//****************************************************************************** + +bool EntityPath::operator==( + const EntityPath &i_rhs) const +{ + #define TARG_FN "operator==(...)" + + return ( (i_rhs.iv_type == iv_type) + && (i_rhs.iv_size == iv_size) + && (memcmp(&iv_pathElement[0], + &i_rhs.iv_pathElement[0], + (sizeof(iv_pathElement[0])*iv_size)) == 0)); + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::equals +//****************************************************************************** + +bool EntityPath::equals( + const EntityPath& i_rhs, + const uint32_t i_size) const +{ + #define TARG_FN "equals(...)" + + if(i_size > MAX_PATH_ELEMENTS) + { + TARG_ERR("Caller specified invalid entity path size of %d which " + "is greater than MAX_PATH_ELEMENTS",i_size,size()); + assert(i_size <= MAX_PATH_ELEMENTS); + } + + return ( (i_rhs.iv_type == iv_type) + && (i_size <= i_rhs.size()) + && (i_size <= size()) + && (memcmp(&iv_pathElement[0], + &i_rhs.iv_pathElement[0], + (sizeof(iv_pathElement[0])*i_size)) == 0)); + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::operator[] +//****************************************************************************** + +const EntityPath::PathElement& EntityPath::operator[]( + const uint32_t i_index) const +{ + #define TARG_FN "operator[](...)" + + if(i_index >= size()) + { + TARG_ERR("Caller specified invalid entity path subscript of %d when " + "size is only %d",i_index,size()); + assert(0); + } + return iv_pathElement[i_index]; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::size +//****************************************************************************** + +uint32_t EntityPath::size() const +{ + #define TARG_FN "size()" + + return iv_size; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::setType +//****************************************************************************** + +void EntityPath::setType( + const PATH_TYPE i_pathType) +{ + #define TARG_FN "setType(...)" + + iv_type = i_pathType; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::type +//****************************************************************************** + +EntityPath::PATH_TYPE EntityPath::type() const +{ + #define TARG_FN "type()" + + return iv_type; + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::pathTypeAsString (DEBUG) +//****************************************************************************** + +const char* EntityPath::pathTypeAsString() const +{ + #define TARG_FN "pathTypeAsString()" + + switch (iv_type) + { + case PATH_DEVICE: + return "Device"; + case PATH_AFFINITY: + return "Logical"; + case PATH_PHYSICAL: + return "Physical"; + case PATH_POWER: + return "Power"; + default: + return "Unknown entity path type"; + } + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::pathElementTypeAsString (DEBUG) +//****************************************************************************** + +const char* EntityPath::pathElementTypeAsString( + const TYPE i_type) const +{ + #define TARG_FN "pathElementTypeAsString(...)" + + switch (i_type) + { + case TYPE_PROC: + return "Proc"; + case TYPE_NODE: + return "Node"; + case TYPE_CORE: + return "Core"; + case TYPE_L2: + return "L2"; + case TYPE_MCS: + return "MCS"; + case TYPE_MBA: + return "MBA"; + case TYPE_MEM_PORT: + return "MemPort"; + case TYPE_L3: + return "L3"; + case TYPE_PERVASIVE: + return "Pervasive"; + case TYPE_POWERBUS: + return "Powerbus"; + case TYPE_SCM: + return "SCM"; + case TYPE_SYS: + return "Sys"; + case TYPE_DCM: + return "DCM"; + case TYPE_EX: + return "EX"; + case TYPE_PCI: + return "PCI"; +// case TYPE_FSI_LINK: +// return "FSI-link"; +// case TYPE_CFAM: +// return "CFAM"; +// case TYPE_ENGINE: +// return "Engine"; + default: + return "Unknown path type"; + } + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::pathEngineInstanceAsString (DEBUG) +//****************************************************************************** + +const char* EntityPath::pathEngineInstanceAsString( + const ENGINE_TYPE i_engine) const +{ + #define TARG_FN "pathEngineInstanceAsString(...)" + + switch (i_engine) + { +// case ENGINE_IIC: +// return "IIC"; +// case ENGINE_SCOM: +// return "SCOM"; + default: + return "Unknown engine type"; + } + + #undef TARG_FN +} + +//****************************************************************************** +// EntityPath::dump (DEBUG) +//****************************************************************************** + +void EntityPath::dump() const +{ + #define TARG_FN "dump()" + + char l_pBuf[200]; + char* l_pCursor = l_pBuf; + l_pCursor+=sprintf(l_pCursor,"%s:",pathTypeAsString()); + for(uint32_t i=0; i<size(); ++i) + { + l_pCursor+=sprintf(l_pCursor,"/%s%d", + pathElementTypeAsString(operator[](i).type), + operator[](i).instance); + } + + TRACFBIN(g_trac_targeting, + "EntityPath", + l_pBuf, + l_pCursor-l_pBuf); + + #undef TARG_FN +} + +#undef TARG_CLASS + +#undef TARG_NAMESPACE + +} // End namespace TARGETING diff --git a/src/usr/targeting/fakepnordata.C b/src/usr/targeting/fakepnordata.C new file mode 100644 index 000000000..ea7295ee1 --- /dev/null +++ b/src/usr/targeting/fakepnordata.C @@ -0,0 +1,523 @@ + +/** + * @file fakepnordata.C + * + * @brief Generates a fake PNOR image for supporting host boot while PNOR + * is not available (i.e. bringup) +*/ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <string.h> +#include <assert.h> +#include <stdio.h> +#include <vector> + +// Other components +#include <util/singleton.H> +#include <trace/interface.H> + +// This component +#include <targeting/attributes.H> +#include <targeting/target.H> +#include "fakepnordata.H" +#include "trace.H" + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" +#define TARG_CLASS "PnorBuilderService::" + + + +//****************************************************************************** +// PnorBuilderService::~PnorBuilderService +//****************************************************************************** + +PnorBuilderService::~PnorBuilderService() +{ + free(iv_pPnor); + free(iv_pHeap); +} + +//****************************************************************************** +// PnorBuilderService::heapBase +//****************************************************************************** + +uint8_t* PnorBuilderService::heapBase() const +{ + return reinterpret_cast<uint8_t*>(iv_pHeap); +} + +//****************************************************************************** +// PnorBuilderService::pnorBase +//****************************************************************************** + +uint8_t* PnorBuilderService::pnorBase() const +{ + return reinterpret_cast<uint8_t*>(iv_pPnor); +} + +//****************************************************************************** +// PnorBuilderService::clearPnorSection +//****************************************************************************** + +void PnorBuilderService::clearPnorSection() +{ + memset(pnorBase(),0x00,PNOR_SIZE); +} + +//****************************************************************************** +// PnorBuilderService::clearHeapSection +//****************************************************************************** + +void PnorBuilderService::clearHeapSection() +{ + memset(heapBase(),0x00,HEAP_SIZE); +} + +//****************************************************************************** +// PnorBuilderService::populateValidAttrIds +//****************************************************************************** + +void PnorBuilderService::populateValidAttrIds( + uint8_t*& i_pPnor, + const std::vector<AttrInfo>& i_attrInfo, + ATTRIBUTE_ID*& o_pAttrNames) +{ + uint32_t l_numAttr = i_attrInfo.size(); + *(reinterpret_cast<uint32_t*>(i_pPnor)) = l_numAttr; + i_pPnor+=sizeof(l_numAttr); + ATTRIBUTE_ID (*l_pAttr)[] = (ATTRIBUTE_ID (*)[])i_pPnor; + for(uint32_t i=0; i<l_numAttr; ++i) + { + memcpy(i_pPnor,&i_attrInfo[i].attrId,sizeof(i_attrInfo[i].attrId)); + i_pPnor+=sizeof(i_attrInfo[i].attrId); + } + o_pAttrNames = (ATTRIBUTE_ID*)l_pAttr; +} + +//****************************************************************************** +// PnorBuilderService::populateAttrs +//****************************************************************************** + +void PnorBuilderService::populateAttrs( + const ATTRIBUTE_ID* i_pAttrNames, + uint8_t*& i_pPnor, + uint8_t*& i_pHeap, + std::vector< Target* >& o_targets, + const std::vector<AttrInfo>& i_attrInfo) +{ + void* (*l_pAttrValues)[] = (void* (*)[])i_pPnor; + + // Reserve space for number of pointers + i_pPnor += sizeof(void*) * i_attrInfo.size(); + + // Iterate through the data + for(uint32_t i=0; i<i_attrInfo.size(); ++i) + { + void* l_pData = (i_attrInfo[i].location == PNOR) + ? (void*)i_pPnor : (void*)i_pHeap; + memcpy(l_pData,i_attrInfo[i].pData,i_attrInfo[i].size); + if(i_attrInfo[i].location == PNOR) + { + i_pPnor+=i_attrInfo[i].size; + } + else + { + i_pHeap+=i_attrInfo[i].size; + } + (*l_pAttrValues)[i] = l_pData; + } + + Target* l_pTarget = new Target(); + l_pTarget->iv_attrs = i_attrInfo.size(); + l_pTarget->iv_pAttrNames = (ATTRIBUTE_ID (*)[])i_pAttrNames; + l_pTarget->iv_pAttrValues = l_pAttrValues; + o_targets.push_back(l_pTarget); +} + +//****************************************************************************** +// PnorBuilderService::buildTargetingImage +//****************************************************************************** + +void PnorBuilderService::buildTargetingImage() +{ + #define TARG_FN "buildTargetingImage()" + + TARG_INF(">>Build targeting image"); + + clearPnorSection(); + clearHeapSection(); + + std::vector<Target*> l_targets; + + uint8_t* l_pPnor = pnorBase(); + uint8_t* l_pHeap = heapBase(); + ATTRIBUTE_ID* l_pAttrNames = NULL; + + uint32_t** l_numTargets = (uint32_t**)l_pPnor; + l_pPnor+=sizeof(uint32_t*); + std::vector<AttrInfo> l_attrs; + + TARG_INF("Populate sys 0"); + + // Populate the system target + SysSysPower8 l_sysSysPower8_0; + EntityPath l_sysContainment(EntityPath::PATH_PHYSICAL); + EntityPath l_sysAffinity(EntityPath::PATH_AFFINITY); + l_sysContainment.addLast(TYPE_SYS,0); + l_sysAffinity.addLast(TYPE_SYS,0); + l_sysSysPower8_0.iv_physicalPath.set(l_sysContainment); + l_sysSysPower8_0.iv_affinityPath.set(l_sysAffinity); + l_sysSysPower8_0.iv_xscomBaseAddr.set(0x300000000000); + l_sysSysPower8_0.getAttrInfo(l_attrs); + populateValidAttrIds(l_pPnor,l_attrs,l_pAttrNames); + populateAttrs(l_pAttrNames,l_pPnor,l_pHeap,l_targets,l_attrs); + l_attrs.clear(); + + // Populate the sys0/node0 target + EncNodePower8 l_encNodePower8_0; + EntityPath l_nodeContainment = l_sysContainment; + l_nodeContainment.addLast(TYPE_NODE,0); + EntityPath l_nodeAffinity = l_sysAffinity; + l_nodeAffinity.addLast(TYPE_NODE,0); + l_encNodePower8_0.iv_physicalPath.set(l_nodeContainment); + l_encNodePower8_0.iv_affinityPath.set(l_nodeAffinity); + l_encNodePower8_0.getAttrInfo(l_attrs); + populateValidAttrIds(l_pPnor,l_attrs,l_pAttrNames); + populateAttrs(l_pAttrNames,l_pPnor,l_pHeap,l_targets,l_attrs); + l_attrs.clear(); + +// // Populate the sys0/node0/SCM0 target +// CardScmPower8 l_cardScmPower8_0; +// EntityPath l_scmContainment = l_nodeContainment; +// l_scmContainment.addLast(TYPE_SCM,0); +// EntityPath l_scmAffinity = l_nodeAffinity; +// l_scmAffinity.addLast(TYPE_SCM,0); +// l_cardScmPower8_0.iv_physicalPath.set(l_scmContainment); +// l_cardScmPower8_0.iv_affinityPath.set(l_scmAffinity); +// l_cardScmPower8_0.getAttrInfo(l_attrs); +// populateValidAttrIds(l_pPnor,l_attrs,l_pAttrNames); +// populateAttrs(l_pAttrNames,l_pPnor,l_pHeap,l_targets,l_attrs); +// l_attrs.clear(); + + TARG_INF("Populate proc 0"); + + // Populate the sys0/node0/proc0 Salerno processor chip targets + ProcChipSalerno l_procChipSalerno_0; + EntityPath l_procContainment = l_nodeContainment; + l_procContainment.addLast(TYPE_PROC,0); + EntityPath l_procAffinity = l_nodeAffinity; + l_procAffinity.addLast(TYPE_PROC,0); + l_procChipSalerno_0.iv_physicalPath.set(l_procContainment); + l_procChipSalerno_0.iv_affinityPath.set(l_procAffinity); + XscomChipInfo l_xscomChipInfo = {0,0}; + l_procChipSalerno_0.iv_xscomChipInfo.set(l_xscomChipInfo); + l_procChipSalerno_0.getAttrInfo(l_attrs); + populateValidAttrIds(l_pPnor,l_attrs,l_pAttrNames); + populateAttrs(l_pAttrNames,l_pPnor,l_pHeap,l_targets,l_attrs); + + + +#define EX_PER_SALERNO 6 + + ATTRIBUTE_ID* l_pExAttrNames = NULL; + ATTRIBUTE_ID* l_pCoreAttrNames = NULL; + ATTRIBUTE_ID* l_pL2AttrNames = NULL; + ATTRIBUTE_ID* l_pL3AttrNames = NULL; + TARG_INF("Populate EXs and sub-units"); + + for(int i=0; i<EX_PER_SALERNO; ++i) + { + TARG_INF("Populate EX"); + std::vector<AttrInfo> l_exInstAttrs; + UnitExSalerno l_unitExSalerno; + + // Customize + EntityPath l_exContainment = l_procContainment; + l_exContainment.addLast(TYPE_EX,i); + EntityPath l_exAffinity = l_procAffinity; + l_exAffinity.addLast(TYPE_EX,i); + l_unitExSalerno.iv_physicalPath.set(l_exContainment); + l_unitExSalerno.iv_affinityPath.set(l_exAffinity); + l_unitExSalerno.getAttrInfo(l_exInstAttrs); + + // If valid attributes are empty for this class + if(l_pExAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_exInstAttrs,l_pExAttrNames); + } + + populateAttrs(l_pExAttrNames,l_pPnor,l_pHeap,l_targets,l_exInstAttrs); + + TARG_INF("Populate Core"); + + // Populate core + std::vector<AttrInfo> l_coreInstAttrs; + UnitCoreSalerno l_unitCoreSalerno; + EntityPath l_coreContainment = l_procContainment; + l_coreContainment.addLast(TYPE_CORE,i); + EntityPath l_coreAffinity = l_exAffinity; + l_coreAffinity.addLast(TYPE_CORE,0); + l_unitCoreSalerno.iv_physicalPath.set(l_coreContainment); + l_unitCoreSalerno.iv_affinityPath.set(l_coreAffinity); + l_unitCoreSalerno.getAttrInfo(l_coreInstAttrs); + if(l_pCoreAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_coreInstAttrs,l_pCoreAttrNames); + } + populateAttrs(l_pCoreAttrNames,l_pPnor,l_pHeap,l_targets,l_coreInstAttrs); + + TARG_INF("Populate L2"); + + // Populate L2 + std::vector<AttrInfo> l_l2InstAttrs; + UnitL2Salerno l_unitL2Salerno; + EntityPath l_l2Containment = l_procContainment; + l_l2Containment.addLast(TYPE_L2,i); + EntityPath l_l2Affinity = l_exAffinity; + l_l2Affinity.addLast(TYPE_L2,0); + l_unitL2Salerno.iv_physicalPath.set(l_l2Containment); + l_unitL2Salerno.iv_affinityPath.set(l_l2Affinity); + l_unitL2Salerno.getAttrInfo(l_l2InstAttrs); + if(l_pL2AttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_l2InstAttrs,l_pL2AttrNames); + } + populateAttrs(l_pL2AttrNames,l_pPnor,l_pHeap,l_targets,l_l2InstAttrs); + + TARG_INF("Populate L3"); + + // Populate L3 + std::vector<AttrInfo> l_l3InstAttrs; + UnitL3Salerno l_unitL3Salerno; + EntityPath l_l3Containment = l_procContainment; + l_l3Containment.addLast(TYPE_L3,i); + EntityPath l_l3Affinity = l_exAffinity; + l_l3Affinity.addLast(TYPE_L3,0); + l_unitL3Salerno.iv_physicalPath.set(l_l3Containment); + l_unitL3Salerno.iv_affinityPath.set(l_l3Affinity); + l_unitL3Salerno.getAttrInfo(l_l3InstAttrs); + if(l_pL3AttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_l3InstAttrs,l_pL3AttrNames); + } + populateAttrs(l_pL3AttrNames,l_pPnor,l_pHeap,l_targets,l_l3InstAttrs); + } + + + // Populate Mcs + ATTRIBUTE_ID* l_pMcsAttrNames = NULL; + + std::vector<AttrInfo> l_McsInstAttrs; + UnitMcsSalerno l_unitMcsSalerno; + EntityPath l_McsContainment = l_procContainment; + l_McsContainment.addLast(TYPE_MCS,0); + EntityPath l_McsAffinity = l_procAffinity; + l_McsAffinity.addLast(TYPE_MCS,0); + l_unitMcsSalerno.iv_physicalPath.set(l_McsContainment); + l_unitMcsSalerno.iv_affinityPath.set(l_McsAffinity); + l_unitMcsSalerno.getAttrInfo(l_McsInstAttrs); + if(l_pMcsAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_McsInstAttrs,l_pMcsAttrNames); + } + populateAttrs(l_pMcsAttrNames,l_pPnor,l_pHeap,l_targets,l_McsInstAttrs); + + ATTRIBUTE_ID* l_pMbaAttrNames = NULL; + ATTRIBUTE_ID* l_pMemPortAttrNames = NULL; + + for(int i=0; i<2; ++i) + { + // Populate MBAs + std::vector<AttrInfo> l_MbaInstAttrs; + UnitMbaSalerno l_unitMbaSalerno; + EntityPath l_mbaContainment = l_procContainment; + l_mbaContainment.addLast(TYPE_MBA,i); + EntityPath l_mbaAffinity = l_McsAffinity; + l_mbaAffinity.addLast(TYPE_MBA,i); + l_unitMbaSalerno.iv_physicalPath.set(l_mbaContainment); + l_unitMbaSalerno.iv_affinityPath.set(l_mbaAffinity); + l_unitMbaSalerno.getAttrInfo(l_MbaInstAttrs); + if(l_pMbaAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_MbaInstAttrs,l_pMbaAttrNames); + } + populateAttrs(l_pMbaAttrNames,l_pPnor,l_pHeap,l_targets,l_MbaInstAttrs); + + for(uint32_t l_ports=0; l_ports<1; ++l_ports) + { + // Populate Memory Ports + std::vector<AttrInfo> l_MemPortInstAttrs; + UnitMemPortSalerno l_unitMemPortSalerno; + EntityPath l_MemPortContainment = l_procContainment; + l_MemPortContainment.addLast(TYPE_MEM_PORT,i); + EntityPath l_MemPortAffinity = l_mbaAffinity; + l_MemPortAffinity.addLast(TYPE_MEM_PORT,l_ports); + l_unitMemPortSalerno.iv_physicalPath.set(l_MemPortContainment); + l_unitMemPortSalerno.iv_affinityPath.set(l_MemPortAffinity); + l_unitMemPortSalerno.getAttrInfo(l_MemPortInstAttrs); + if(l_pMemPortAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_MemPortInstAttrs,l_pMemPortAttrNames); + } + populateAttrs(l_pMemPortAttrNames,l_pPnor,l_pHeap,l_targets,l_MemPortInstAttrs); + + // DIMMs will get linked up later + } + } + + // Populate Pervasive Unit + ATTRIBUTE_ID* l_pPervasiveAttrNames = NULL; + std::vector<AttrInfo> l_PervasiveInstAttrs; + UnitPervasiveSalerno l_unitPervasiveSalerno; + EntityPath l_PervasiveContainment = l_procContainment; + l_PervasiveContainment.addLast(TYPE_PERVASIVE,0); + EntityPath l_PervasiveAffinity = l_procAffinity; + l_PervasiveAffinity.addLast(TYPE_PERVASIVE,0); + l_unitPervasiveSalerno.iv_physicalPath.set(l_PervasiveContainment); + l_unitPervasiveSalerno.iv_affinityPath.set(l_PervasiveAffinity); + l_unitPervasiveSalerno.getAttrInfo(l_PervasiveInstAttrs); + if(l_pPervasiveAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_PervasiveInstAttrs,l_pPervasiveAttrNames); + } + populateAttrs(l_pPervasiveAttrNames,l_pPnor,l_pHeap,l_targets,l_PervasiveInstAttrs); + + // Populate Powerbus Unit + ATTRIBUTE_ID* l_pPowerbusAttrNames = NULL; + std::vector<AttrInfo> l_PowerbusInstAttrs; + UnitPowerbusSalerno l_unitPowerbusSalerno; + EntityPath l_PowerbusContainment = l_procContainment; + l_PowerbusContainment.addLast(TYPE_POWERBUS,0); + EntityPath l_PowerbusAffinity = l_procAffinity; + l_PowerbusAffinity.addLast(TYPE_POWERBUS,0); + l_unitPowerbusSalerno.iv_physicalPath.set(l_PowerbusContainment); + l_unitPowerbusSalerno.iv_affinityPath.set(l_PowerbusAffinity); + l_unitPowerbusSalerno.getAttrInfo(l_PowerbusInstAttrs); + if(l_pPowerbusAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_PowerbusInstAttrs,l_pPowerbusAttrNames); + } + populateAttrs(l_pPowerbusAttrNames,l_pPnor,l_pHeap,l_targets,l_PowerbusInstAttrs); + + // Populate PCI Units + ATTRIBUTE_ID* l_pPciAttrNames = NULL; + + for(int i=0; i<3; ++i) + { + std::vector<AttrInfo> l_PciInstAttrs; + UnitPciSalerno l_unitPciSalerno; + EntityPath l_pciContainment = l_procContainment; + l_pciContainment.addLast(TYPE_PCI,i); + EntityPath l_pciAffinity = l_procAffinity; + l_pciAffinity.addLast(TYPE_PCI,i); + l_unitPciSalerno.iv_physicalPath.set(l_pciContainment); + l_unitPciSalerno.iv_affinityPath.set(l_pciAffinity); + l_unitPciSalerno.getAttrInfo(l_PciInstAttrs); + if(l_pPciAttrNames == NULL) + { + populateValidAttrIds(l_pPnor,l_PciInstAttrs,l_pPciAttrNames); + } + populateAttrs(l_pPciAttrNames,l_pPnor,l_pHeap,l_targets,l_PciInstAttrs); + } + + + /* + TARG_INF("Populate proc 1"); + + + // Populate the sys0/node0/DCM0/proc1 Salerno processor chip targets + ProcChipSalerno l_procChipSalerno_1; + l_containment.removeLast(); + l_affinity.removeLast(); + l_containment.addLast(TYPE_PROC,1); + l_affinity.addLast(TYPE_PROC,1); + l_procChipSalerno_1.iv_physicalPath.set(l_containment); + l_procChipSalerno_1.iv_affinityPath.set(l_affinity); + std::vector<AttrInfo> l_attrs1; + l_procChipSalerno_1.getAttrInfo(l_attrs1); + populateAttrs(l_pAttrNames,l_pPnor,l_pHeap,l_targets,l_attrs1); + l_attrs.clear(); + l_attrs1.clear(); + */ + + TARG_INF("Finalize PNOR"); + + // Populate pointer to total # of targets at beginning of + // targeting section + *l_numTargets = (uint32_t*)l_pPnor; + + // Add number of targets + uint32_t l_instance = l_targets.size(); + memcpy(l_pPnor,&l_instance,sizeof(l_instance)); + l_pPnor+= sizeof(l_instance); + + // Add actual targets + for(uint32_t i=0; i<l_targets.size(); ++i) + { + memcpy(l_pPnor,l_targets[i],sizeof(Target)); + l_pPnor+=sizeof(Target); + } + + // Compute the actual PNOR and heap sizes and reallocate the memory + uint32_t l_pnorSize = (l_pPnor - pnorBase()); + uint32_t l_heapSize = (l_pHeap - heapBase()); + // realloc(iv_pPnor,l_pnorSize); + // realloc(iv_pHeap,l_heapSize); + + TARG_INF( + "Targeting PNOR size = %d bytes, " + "heap size = %d bytes, " + "est stack size = %d bytes",l_pnorSize,l_heapSize, + (uint32_t)((uint64_t)&l_targets-(uint64_t)&l_heapSize)); + + + // PNOR/HEAP image now ready for bringup use + + #undef TARG_FN +} + +//****************************************************************************** +// PnorBuilderService::getTargetingImageBaseAddress +//****************************************************************************** + +void PnorBuilderService::getTargetingImageBaseAddress( + const void*& o_pTargetsArea) +{ + o_pTargetsArea = reinterpret_cast<void*>(iv_pPnor); +} + +//****************************************************************************** +// PnorBuilderService::PnorBuilderService +//****************************************************************************** + +PnorBuilderService::PnorBuilderService() +{ + TARG_INF(">>PnorBuilderService"); + + + iv_pPnor = reinterpret_cast<uint8_t*>(malloc(PNOR_SIZE)); + + TARG_INF(">>malloc(HEAP_SIZE)"); + + iv_pHeap = reinterpret_cast<uint8_t*>(malloc(HEAP_SIZE)); + + TARG_INF("Calling buildTargetingImage"); + + (void)buildTargetingImage(); + + TARG_INF("<<PnorBuilderService"); + +} + +#undef TARG_NAMESPACE +#undef TARG_CLASS + +} // End namespace TARGETING + diff --git a/src/usr/targeting/fakepnordata.H b/src/usr/targeting/fakepnordata.H new file mode 100644 index 000000000..bd6f0494a --- /dev/null +++ b/src/usr/targeting/fakepnordata.H @@ -0,0 +1,671 @@ + +#ifndef TARG_FAKEPNORDATA_H +#define TARG_FAKEPNORDATA_H + +/** + * @file fakepnordata.H + * + * @brief Interface to generate targets/attributes and fake out PNOR + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdint.h> +#include <stdlib.h> +#include <vector> + +namespace TARGETING +{ + +/** + * @brief Enum which describes where an attribute resides + */ +enum LOCATION +{ + PNOR, ///< Attribute resides in PNOR + HEAP, ///< Attribute resides in heap memory, not backed to PNOR +}; + +/** + * @brief Structure which holds attribute information for the PNOR targeting + * image generator + */ +struct AttrInfo +{ + uint32_t size; ///< Size of attribute + ATTRIBUTE_ID attrId; ///< Attribute ID + LOCATION location; ///< Location where attribute resides + const void* pData; ///< Address of attribute +}; + +/** + * @brief Property class which maintains info about a property to serialize + */ +template<ATTRIBUTE_ID A,LOCATION L> +class Property +{ + public: + + /** + * @brief Map the attribute's type to something more intuitive + */ + typedef typename AttributeTraits<A>::Type _Type; + + /** + * @brief Build a property + */ + Property() + { + info.size = sizeof(_Type); + info.attrId = A; + info.location = L; + info.pData = &iv_data; + iv_initialized = false; + memset(&iv_data,0x00,sizeof(iv_data)); + } + + /** + * @brief Push attribute info to the attribute array + * + * @param[out] o_info Array of attribute structures + */ + void addAttrInfo( + std::vector<AttrInfo>& o_info) const + { + if(info.location == PNOR) + { + assert(iv_initialized); + } + o_info.push_back(info); + } + + /** + * @brief Sets the attribute value + * + * @param[in] i_value Value of the attribute to set + */ + void set( + _Type const& i_value) + { + iv_data = i_value; + iv_initialized = true; + } + + /** + * @brief Return size of the attribute + * + * @return uint32_t giving the size of the attribute in bytes + */ + uint32_t size() const + { + return sizeof(iv_data); + } + + /** + * @brief Return attribute's corresponding attribute ID + * + * @return Attribute ID of the attribute + */ + ATTRIBUTE_ID id() const + { + return info.attrId; + } + + /** + * @brief Return address of the attribute data + * + * @return Address of the attribute data + */ + const _Type* data() const + { + return &iv_data; + } + + /** + * @brief Return location where attribute resides + * + * @return Location specifier + */ + LOCATION location() const + { + return info.location; + } + + public: + + AttrInfo info; ///< Attribute information + _Type iv_data; ///< Attribute data + bool iv_initialized; ///< Whether attribute was set or not +}; + +/** + * @brief Base class describing attributes that all targets have. + * + * Note: will not repeat documentation for subclasses, since they act the same + */ +class Base +{ + public: + + /** + * @brief Build the base object for attributes + */ + Base() + { + } + + /** + * @brief Populate the list with information on all the attributes + * + * @param[out] o_info List containing all the attribute information + */ + void getAttrInfo( + std::vector<AttrInfo>& o_info) const + { + iv_class.addAttrInfo(o_info); + iv_type.addAttrInfo(o_info); + iv_model.addAttrInfo(o_info); + iv_physicalPath.addAttrInfo(o_info); + iv_affinityPath.addAttrInfo(o_info); + iv_interfaces.addAttrInfo(o_info); + } + + public: + + Property<ATTR_CLASS,PNOR> iv_class; + Property<ATTR_TYPE,PNOR> iv_type; + Property<ATTR_MODEL,PNOR> iv_model; + Property<ATTR_PHYS_PATH,PNOR> iv_physicalPath; + Property<ATTR_AFFINITY_PATH,PNOR> iv_affinityPath; + Property<ATTR_PRIMARY_CAPABILITIES,PNOR> iv_interfaces; +}; + +/** + * @brief Class describing the data for all cards + */ +class Card : public Base +{ + public: + + Card() + { + iv_class.set(CLASS_CARD); + + PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo( + std::vector<AttrInfo>& o_info) const + { + Base::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for all DCM cards + */ +class CardScmPower8 : public Card +{ + public: + + CardScmPower8() + { + iv_type.set(TYPE_SCM); + iv_model.set(MODEL_POWER8); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Card::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for the top level system + */ +class SysSysPower8 : public Base +{ + public: + + SysSysPower8() + { + iv_class.set(CLASS_SYS); + iv_type.set(TYPE_SYS); + iv_model.set(MODEL_POWER8); + + PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Base::getAttrInfo(o_info); + + iv_xscomBaseAddr.addAttrInfo(o_info); + } + + Property<ATTR_XSCOM_BASE_ADDRESS,PNOR> iv_xscomBaseAddr; +}; + +/** + * @brief Class describing the data for a chip + */ +class Chip : public Base +{ + public: + + Chip() + { + iv_class.set(CLASS_CHIP); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Base::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for a node + */ +class EncNodePower8 : public Base +{ + public: + + EncNodePower8() + { + iv_class.set(CLASS_ENC); + iv_type.set(TYPE_NODE); + iv_model.set(MODEL_POWER8); + + PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Base::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for the Salerno chip + */ +class ProcChipSalerno : public Chip +{ + public: + + ProcChipSalerno() + { + iv_type.set(TYPE_PROC); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + l_capabilities.supportsFsiScom = true; + l_capabilities.supportsXscom = true; + iv_interfaces.set(l_capabilities); + + ScomSwitches l_switches = {0}; + l_switches.useXscom = 1; + iv_scomSwitches.set(l_switches); + + iv_dummyRw.set(0); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Chip::getAttrInfo(o_info); + + iv_dummyRw.addAttrInfo(o_info); + iv_scomSwitches.addAttrInfo(o_info); + iv_xscomChipInfo.addAttrInfo(o_info); + } + + Property<ATTR_DUMMY_RW,PNOR> iv_dummyRw; + Property<ATTR_SCOM_SWITCHES,HEAP> iv_scomSwitches; + Property<ATTR_XSCOM_CHIP_INFO,PNOR> iv_xscomChipInfo; + +}; + +/** + * @brief Class describing the data for a logical entity + */ +class Logical : public Base +{ + public: + + Logical() + { + iv_class.set(CLASS_UNIT); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Base::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for an EX unit + */ +class UnitExSalerno : public Logical +{ + public: + + UnitExSalerno() + { + iv_type.set(TYPE_EX); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for a core unit + */ +class UnitCoreSalerno : public Logical +{ + public: + + UnitCoreSalerno() + { + iv_type.set(TYPE_CORE); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for an L3 unit + */ +class UnitL3Salerno : public Logical +{ + public: + + UnitL3Salerno() + { + iv_type.set(TYPE_L3); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } + +}; + +/** + * @brief Class describing the data for an L2 unit + */ +class UnitL2Salerno : public Logical +{ + public: + + UnitL2Salerno() + { + iv_type.set(TYPE_L2); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for an MCA unit + */ +class UnitMcsSalerno : public Logical +{ + public: + + UnitMcsSalerno() + { + iv_type.set(TYPE_MCS); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } + + Property<ATTR_SCOM_SWITCHES,HEAP> iv_scomSwitches; +}; + +/** + * @brief Class describing the data for an MCA unit + */ +class UnitMbaSalerno : public Logical +{ + public: + + UnitMbaSalerno() + { + iv_type.set(TYPE_MBA); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } +}; + +/** + * @brief Class describing the data for the pervasive unit + */ +class UnitPervasiveSalerno : public Logical +{ + public: + + UnitPervasiveSalerno() + { + iv_type.set(TYPE_PERVASIVE); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } + +}; + +class UnitPciSalerno : public Logical +{ + public: + + UnitPciSalerno() + { + iv_type.set(TYPE_PCI); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } +}; + +class UnitPowerbusSalerno : public Logical +{ + public: + + UnitPowerbusSalerno() + { + iv_type.set(TYPE_POWERBUS); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } +}; + +class UnitMemPortSalerno : public Logical +{ + public: + + UnitMemPortSalerno() + { + iv_type.set(TYPE_MEM_PORT); + iv_model.set(MODEL_SALERNO); + + TARGETING::PrimaryCapabilities l_capabilities = {0}; + iv_interfaces.set(l_capabilities); + } + + void getAttrInfo(std::vector<AttrInfo>& o_info) const + { + Logical::getAttrInfo(o_info); + } +}; + +//****************************************************************************** +// PNOR Builder Service +//****************************************************************************** + +/** + * @brief Class which builds fake PNOR image for bringup + */ +class PnorBuilderService +{ + public: + + /** + * @brief Initial PNOR sizes + */ + static const uint32_t PNOR_SIZE = 8000; + static const uint32_t HEAP_SIZE = 8000; + + /** + * @brief Constructs the PnorBuilderService + */ + PnorBuilderService(); + + /** + * @brief Destructs the PnorBuilderService + */ + ~PnorBuilderService(); + + /** + * @brief Returns pointer to the start of the heap section + */ + uint8_t* heapBase() const; + + /** + * @brief Returns pointer to the start of the PNOR section + */ + uint8_t* pnorBase() const; + + /** + * @brief Clears the PNOR section + */ + void clearPnorSection(); + + /** + * @brief Clears the PNOR section + */ + void clearHeapSection(); + + /** + * @brief Populates attributes valid attributes for a class/type/model + * into the targeting image + * + * @param[in] i_pPnor On input and output, pointer to next valid + * location to write to in PNOR + * @param[in] i_attrInfo List of attributes to process + * @param[in] o_pAttrNames Pointer to where the list was stored + */ + void populateValidAttrIds( + uint8_t*& io_pPnor, + const std::vector<AttrInfo>& i_attrInfo, + ATTRIBUTE_ID*& o_pAttrNames); + + /** + * @brief Populates attributes into the targeting image + * + * @param[in] i_pAttrNames Pointer to array of valid attributes for + * the class/type/model in question + * @param[in/out] io_pPnor On both input and output, a pointer to the + * next free position in PNOR to populate. + * @param[in/out] io_pHeap On both input and output, a pointer to the + * next free position on the heap to populate. + * @param[out] o_targets List of targets to serialize + * @param[in] i_attrInfo List of attribute infor structures + */ + void populateAttrs( + const ATTRIBUTE_ID* i_pAttrNames, + uint8_t*& io_pPnor, + uint8_t*& io_pHeap, + std::vector< Target* >& o_targets, + const std::vector<AttrInfo>& i_attrInfo); + + /** + * @brief Builds the targeting image + */ + void buildTargetingImage(); + + /** + * @brief Updates caller's pointer with the address of the targeting + * layout + * + * @param[out] o_pTargetsArea Pointer to the address of the targeting + * layout + */ + void getTargetingImageBaseAddress( + const void*& o_pTargetsArea); + + uint8_t* iv_pPnor; + uint8_t* iv_pHeap; + +} PACKED; + +typedef Singleton<PnorBuilderService> thePnorBuilderService; + +} // End namespace TARGETING + +#endif // TARG_FAKEPNORDATA_H diff --git a/src/usr/targeting/makefile b/src/usr/targeting/makefile new file mode 100644 index 000000000..09b9d3be3 --- /dev/null +++ b/src/usr/targeting/makefile @@ -0,0 +1,8 @@ +ROOTPATH = ../../.. +MODULE = targeting + +OBJS = target.o targetservice.o entitypath.o fakepnordata.o + +SUBDIRS = test.d + +include ${ROOTPATH}/config.mk diff --git a/src/usr/targeting/target.C b/src/usr/targeting/target.C new file mode 100644 index 000000000..590fc66bc --- /dev/null +++ b/src/usr/targeting/target.C @@ -0,0 +1,123 @@ + +/** + * @file target.C + * + * @brief Implementation of the Target class + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +// This component +#include <targeting/target.H> +#include "trace.H" + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" +#define TARG_CLASS "Target::" + +//****************************************************************************** +// Target::~Target +//****************************************************************************** + +Target::~Target() +{ + #define TARG_FN "~Target()" + + #undef TARG_FN +} + +//****************************************************************************** +// Target::_tryGetAttr +//****************************************************************************** + +bool Target::_tryGetAttr( + const ATTRIBUTE_ID i_attr, + const uint32_t i_size, + void* const io_pAttrData) const +{ + #define TARG_FN "_tryGetAttr()" + + void* l_pAttrData = NULL; + (void) _getAttrPtr(i_attr, l_pAttrData); + if (l_pAttrData) + { + memcpy(io_pAttrData, l_pAttrData, i_size); + } + return (l_pAttrData != NULL); + + #undef TARG_FN +} + +//****************************************************************************** +// Target::_trySetAttr +//****************************************************************************** + +bool Target::_trySetAttr( + const ATTRIBUTE_ID i_attr, + const uint32_t i_size, + const void* const i_pAttrData) const +{ + #define TARG_FN "_trySetAttr()" + + void* l_pAttrData = NULL; + (void) _getAttrPtr(i_attr, l_pAttrData); + if (l_pAttrData) + { + memcpy(l_pAttrData, i_pAttrData, i_size); + } + return (l_pAttrData != NULL); + + #undef TARG_FN +} + +//****************************************************************************** +// Target::_getAttrPtr +//****************************************************************************** + +void Target::_getAttrPtr( + const ATTRIBUTE_ID i_attr, + void*& o_pAttr) const +{ + #define TARG_FN "_getAttrPtr()" + + void* l_pAttr = NULL; + for (uint32_t i = 0; i < iv_attrs; ++i) + { + if ((*iv_pAttrNames)[i] == i_attr) + { + l_pAttr = (*iv_pAttrValues)[i]; + } + } + o_pAttr = l_pAttr; + + #undef TARG_FN +} + +//****************************************************************************** +// Target::Target +//****************************************************************************** + +Target::Target() +{ + #define TARG_FN "Target()" + + // Note there is no intialization of a target, since it's mapped to memory + // directly. + + #undef TARG_FN +} + +#undef TARG_CLASS + +#undef TARG_NAMESPACE + +} // End namespace TARGETING diff --git a/src/usr/targeting/targetservice.C b/src/usr/targeting/targetservice.C new file mode 100644 index 000000000..e90449d23 --- /dev/null +++ b/src/usr/targeting/targetservice.C @@ -0,0 +1,567 @@ + +/** + * @file targetservice.C + * + * @brief Implementation of the TargetService class + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +// Other components +#include <trace/interface.H> + +// This component +#include <targeting/targetservice.H> +#include "trace.H" +#include "fakepnordata.H" + +//****************************************************************************** +// targetService +//****************************************************************************** + +namespace TARGETING +{ + +#define TARG_NAMESPACE "TARGETING::" + +//****************************************************************************** +// targetService +//****************************************************************************** + +TARGETING::TargetService& targetService() +{ + #define TARG_FN "targetService()" + + return TARGETING::theTargetService::instance(); + + #undef TARG_FN +} + +//****************************************************************************** +// Component trace buffer +//****************************************************************************** + +trace_desc_t* g_trac_targeting = NULL; +TRAC_INIT(&g_trac_targeting, "TARG", 4096); + +#define TARG_CLASS "TargetService::" + +//****************************************************************************** +// TargetService::TargetService +//****************************************************************************** + +TargetService::TargetService() : + iv_initialized(false), iv_maxTargets(0), iv_pPnor(NULL) +{ + #define TARG_FN "TargetService()" + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::~TargetService +//****************************************************************************** + +TargetService::~TargetService() +{ + #define TARG_FN "~TargetService()" + + // Nothing to do; Target[] memory not owned by this object + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::init +//****************************************************************************** + +void TargetService::init() +{ + #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); + + // Get+save pointer to beginning of targeting's swappable config in + // PNOR. Note that this will change once PNOR is accessible + (void)thePnorBuilderService::instance() + .getTargetingImageBaseAddress(iv_pPnor); + + (void)_configureTargetPool(); + + iv_initialized = true; + + TARG_EXIT(); + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::getTopLevelTarget +//****************************************************************************** + +void TargetService::getTopLevelTarget( + Target*& o_targetHandle) const +{ + #define TARG_FN "getTopLevelTarget(...)" + + if (iv_initialized) + { + EntityPath l_topLevelPhysicalPath(EntityPath::PATH_PHYSICAL); + l_topLevelPhysicalPath.addLast(TYPE_SYS, 0); + o_targetHandle = toTarget(l_topLevelPhysicalPath); + } + else + { + o_targetHandle = NULL; + assert(iv_initialized); + } + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::exists +//****************************************************************************** + +void TargetService::exists( + const EntityPath& i_entityPath, + bool& o_exists) const +{ + #define TARG_FN "exists(...)" + + bool l_found = false; + if (iv_initialized) + { + for (uint32_t i = 0; i < iv_maxTargets; ++i) + { + if (i_entityPath == (*iv_targets)[i].getAttr<ATTR_PHYS_PATH> ()) + { + l_found = true; + } + } + } + else + { + assert(iv_initialized); + } + + o_exists = l_found; + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::toTarget +//****************************************************************************** + +Target* TargetService::toTarget( + const EntityPath& i_entityPath) const +{ + #define TARG_FN "toTarget(...)" + + // Used by -> operator on EntityPath for convenience (can be dangerous + // though!) + Target* l_pTarget = NULL; + if (iv_initialized) + { + for (uint32_t i = 0; i < iv_maxTargets; ++i) + { + if (i_entityPath == (*iv_targets)[i].getAttr<ATTR_PHYS_PATH> ()) + { + l_pTarget = &(*iv_targets)[i]; + break; + } + } + } + else + { + assert(iv_initialized); + } + + return l_pTarget; + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::masterProcChipTarget +//****************************************************************************** + +void TargetService::masterProcChipTargetHandle( + Target*& o_masterProcChipTargetHandle) const +{ + #define TARG_FN "masterProcChipTargetHandle(...)" + + Target* l_pTarget = NULL; + if (iv_initialized) + { + //@TODO 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, 0) + .addLast(TYPE_PROC, 0); + + l_pTarget = l_masterProcChipEntityPath.operator->(); + } + else + { + assert(iv_initialized); + } + + o_masterProcChipTargetHandle = l_pTarget; + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::tryGetPath +//****************************************************************************** + +bool TargetService::tryGetPath( + const ATTRIBUTE_ID i_attr, + const Target* const i_pTarget, + EntityPath& o_entityPath) const +{ + #define TARG_FN "tryGetPath(...)" + + bool l_exist = false; + if (iv_initialized) + { + switch (i_attr) + { + case ATTR_PHYS_PATH: + l_exist = i_pTarget->tryGetAttr<ATTR_PHYS_PATH> (o_entityPath); + break; + case ATTR_AFFINITY_PATH: + l_exist = i_pTarget->tryGetAttr<ATTR_AFFINITY_PATH> ( + o_entityPath); + break; + case ATTR_POWER_PATH: + l_exist = i_pTarget->tryGetAttr<ATTR_POWER_PATH> (o_entityPath); + break; + default: + TARG_ERR("BUG; i_attr = 0x%08X does not map to an entity " + "path"); + assert(0); + break; + } + } + else + { + assert(iv_initialized); + } + + return l_exist; + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::getAssociated +//****************************************************************************** + +void TargetService::getAssociated( + const Target* const i_pTarget, + const ASSOCIATION_TYPE i_type, + const RECURSION_LEVEL i_recursionLevel, + TargetHandleList& o_list) const +{ + #define TARG_FN "getAssociated(...)" + + do { + + assert(iv_initialized); + + if( (i_pTarget == NULL) + || (i_pTarget == MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) ) + { + TARG_ERR("BUG; caller tried to get association using a NULL target " + "handle or the master processor chip target handle sentinel. " + "i_pTarget = %p",i_pTarget); + assert(0); + } + + // Start with no elements + o_list.clear(); + + // Figure out which attribute to look up + for (uint32_t i = 0; i < iv_associationMappings.size(); ++i) + { + if (i_type == iv_associationMappings[i].associationType) + { + EntityPath l_entityPath; + + bool l_exist = tryGetPath(iv_associationMappings[i].attr, + i_pTarget, l_entityPath); + + if (l_exist) + { + if (iv_associationMappings[i].associationDir == INWARDS) + { + (void) _getInwards(iv_associationMappings[i].attr, + i_recursionLevel, l_entityPath, o_list); + } + else if (iv_associationMappings[i].associationDir + == OUTWARDS) + { + (void) _getOutwards(iv_associationMappings[i].attr, + i_recursionLevel, l_entityPath, o_list); + } + else + { + TARG_ERR("BUG; iv_associationMappings[i].associationDir " + "= 0x%X not supported", + iv_associationMappings[i].associationDir); + assert(0); + } + } + break; + } + } + + } while (0); + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::dump() +//****************************************************************************** + +void TargetService::dump() const +{ + #define TARG_FN "dump(...)" + + if (iv_initialized) + { + TARG_INF("Targets (size=%d):", + sizeof(Target)*iv_maxTargets); + + for (uint32_t i = 0; i < iv_maxTargets; ++i) + { + 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>()); + TARG_INF("Physical"); + (*iv_targets)[i].getAttr<ATTR_PHYS_PATH>().dump(); + + EntityPath l_entityPath; + if( (*iv_targets)[i].tryGetAttr<ATTR_AFFINITY_PATH>(l_entityPath) ) + { + TARG_INF("Affinity"); + l_entityPath.dump(); + } + + if( (*iv_targets)[i].tryGetAttr<ATTR_POWER_PATH>(l_entityPath) ) + { + TARG_INF("Power"); + l_entityPath.dump(); + } + + uint8_t l_dummyRw = 0; + if ((*iv_targets)[i].tryGetAttr<ATTR_DUMMY_RW> (l_dummyRw)) + { + TARG_INF("Dummy = 0x%X", + l_dummyRw); + } + + TARG_INF("Supports FSI SCOM = %d", + (*iv_targets)[i].getAttr<ATTR_PRIMARY_CAPABILITIES>() + .supportsFsiScom); + TARG_INF("Supports XSCOM SCOM = %d", + (*iv_targets)[i].getAttr<ATTR_PRIMARY_CAPABILITIES>() + .supportsXscom); + TARG_INF("Supports Inband SCOM = %d", + (*iv_targets)[i].getAttr<ATTR_PRIMARY_CAPABILITIES>() + .supportsInbandScom); + + ScomSwitches l_switches = {0}; + if ( (*iv_targets)[i].tryGetAttr<ATTR_SCOM_SWITCHES>(l_switches) ) + { + TARG_INF("Use FSI SCOM = %d",l_switches.useFsiScom); + TARG_INF("Use XSCOM = %d",l_switches.useXscom); + TARG_INF("Use inband SCOM = %d",l_switches.useInbandScom); + } + + uint64_t l_xscomBaseAddr = 0; + if ( (*iv_targets)[i].tryGetAttr<ATTR_XSCOM_BASE_ADDRESS>( + l_xscomBaseAddr) ) + { + TARG_INF("XSCOM Base Address = 0x%X",l_xscomBaseAddr); + } + + XscomChipInfo l_xscomChipInfo = {0}; + if ( (*iv_targets)[i].tryGetAttr<ATTR_XSCOM_CHIP_INFO>( + l_xscomChipInfo) ) + { + TARG_INF("XSCOM Node ID = 0x%X",l_xscomChipInfo.nodeId); + TARG_INF("XSCOM Chip ID = 0x%X",l_xscomChipInfo.chipId); + } + + } + } + else + { + assert(iv_initialized); + } + + return; + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::_configureTargetPool +//****************************************************************************** + +void TargetService::_configureTargetPool() +{ + #define TARG_FN "_configureTargetPool(...)" + + TARG_ENTER(); + + _maxTargets(); + + // iv_pPnor--> points to uint32_t* --> points to --> uint32_t, targets[] + // (uint32_t*)+1 --> points to ------------> targets[] + + iv_targets = + reinterpret_cast< Target(*)[] > ( + *(reinterpret_cast<uint32_t**>( + const_cast<void*>(iv_pPnor))) + 1); + TARG_EXIT(); + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::_maxTargets +//****************************************************************************** + +uint32_t TargetService::_maxTargets() +{ + #define TARG_FN "_maxTargets(...)" + + // Target count found by following the pointer pointed to by the iv_pPnor + // pointer. + iv_maxTargets = *(*(reinterpret_cast<const uint32_t * const *>(iv_pPnor))); + return iv_maxTargets; + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::_getInwards +//****************************************************************************** + +void TargetService::_getInwards( + const ATTRIBUTE_ID i_attr, + const RECURSION_LEVEL i_recursionLevel, + EntityPath i_entityPath, + TargetHandleList& o_list) const +{ + #define TARG_FN "_getInwards(...)" + + while (i_entityPath.size() > 1) + { + i_entityPath.removeLast(); + for (uint32_t i = 0; i < iv_maxTargets; ++i) + { + EntityPath l_candidatePath; + bool l_candidateFound = tryGetPath(i_attr, &(*iv_targets)[i], + l_candidatePath); + if (l_candidateFound && (l_candidatePath == i_entityPath)) + { + o_list.push_back(&(*iv_targets)[i]); + break; + } + } + + if (i_recursionLevel == IMMEDIATE) + { + break; + } + } + + #undef TARG_FN +} + +//****************************************************************************** +// TargetService::_getOutwards +//****************************************************************************** + +void TargetService::_getOutwards( + const ATTRIBUTE_ID i_attr, + const RECURSION_LEVEL i_recursionLevel, + EntityPath i_entityPath, + TargetHandleList& o_list) const +{ + #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; + } + + // Find the children (immediate, or all), depending on recursion level + for (uint32_t i = 0; i < iv_maxTargets; ++i) + { + EntityPath l_candidatePath; + bool l_candidateFound = tryGetPath(i_attr, &(*iv_targets)[i], + 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())) + { + o_list.push_back(&(*iv_targets)[i]); + } + } + } + } + + } while (0); + + #undef TARG_FN +} + +#undef TARG_CLASS + +#undef TARG_NAMESPACE + +} // End namespace TARGETING diff --git a/src/usr/targeting/test/attributestrings.C b/src/usr/targeting/test/attributestrings.C new file mode 100644 index 000000000..0cc2eda9c --- /dev/null +++ b/src/usr/targeting/test/attributestrings.C @@ -0,0 +1,84 @@ +/** + * @file attributestrings.C + * + * @brief Attribute string implementation. This file will be autogenerated in + * the future + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdint.h> +#include <stdlib.h> + +// This component +#include <targeting/attributes.H> +#include <targeting/attributetraits.H> +#include <targeting/attributestrings.H> + +namespace TARGETING { + +//****************************************************************************** +// attrToString<ATTR_CLASS> +//****************************************************************************** + +template<> +const char* attrToString<ATTR_CLASS> ( + AttributeTraits<ATTR_CLASS>::Type const& i_attrValue) +{ + switch (i_attrValue) + { + case CLASS_CARD: + return "Card"; + case CLASS_ENC: + return "Enclosure"; + case CLASS_CHIP: + return "Chip"; + case CLASS_UNIT: + return "Unit"; + case CLASS_DEV: + return "Device"; + default: + return "Cannot decode class"; + } +} + +//****************************************************************************** +// attrToString<ATTR_TYPE> +//****************************************************************************** + +template<> +const char* attrToString<ATTR_TYPE> ( + AttributeTraits<ATTR_TYPE>::Type const& i_attrValue) +{ + switch (i_attrValue) + { + case TYPE_PROC: + return "Processor"; + case TYPE_EX: + return "EX chiplet"; + default: + return "Cannot decode type"; + } +} + +//****************************************************************************** +// attrToString<ATTR_MODEL> +//****************************************************************************** + +template<> +const char* attrToString<ATTR_MODEL> ( + AttributeTraits<ATTR_MODEL>::Type const& i_attrValue) +{ + switch (i_attrValue) + { + case MODEL_SALERNO: + return "Salerno"; + default: + return "Cannot decode model"; + } +} + +} // End namespace TARGETING diff --git a/src/usr/targeting/test/makefile b/src/usr/targeting/test/makefile new file mode 100644 index 000000000..4f0ff8b66 --- /dev/null +++ b/src/usr/targeting/test/makefile @@ -0,0 +1,8 @@ +ROOTPATH = ../../../.. + +MODULE = testtargeting +TESTS = *.H + +OBJS = attributestrings.o + +include ${ROOTPATH}/config.mk diff --git a/src/usr/targeting/test/targetingtest.H b/src/usr/targeting/test/targetingtest.H new file mode 100644 index 000000000..bd8ffdb0e --- /dev/null +++ b/src/usr/targeting/test/targetingtest.H @@ -0,0 +1,457 @@ +#ifndef __TESTTARGETING_H +#define __TESTTARGETING_H + +/** + * @file testtargeting.H + * + * @brief All unit tests for the targeting infrastructure + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// STD +#include <stdio.h> +#include <sys/time.h> + +// CXXTEST +#include <cxxtest/TestSuite.H> + +// This component +#include <targeting/attributes.H> +#include <targeting/entitypath.H> +#include <targeting/target.H> +#include <targeting/targetservice.H> + +class TargetingTestSuite: public CxxTest::TestSuite +{ + public: + + /** + * @brief Test the TargetService class (except debug cases) + */ + void testTargetServiceClass() + { + nanosleep(1,0); + TS_TRACE(ENTER_MRK "testTargetServiceClass" ); + + using namespace TARGETING; + + TargetService& l_targetService = targetService(); + + l_targetService.init(); + + // Post init + // Test: void masterProcChipTarget( + // TargetHandleList& o_masterProcChipTarget) const; + + Target* l_pMasterProcChipTargetHandle = NULL; + (void) l_targetService.masterProcChipTargetHandle( + l_pMasterProcChipTargetHandle); + + if ( l_pMasterProcChipTargetHandle + == MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) + { + TS_FAIL("Post init; master proc chip target handle should not " + "be the sentinel value"); + } + + if (l_pMasterProcChipTargetHandle == NULL) + { + TS_FAIL("Post init; master proc chip target handle should not " + "be the NULL value"); + } + + if ( l_pMasterProcChipTargetHandle->getAttr<ATTR_CLASS> () + != CLASS_CHIP) + { + TS_FAIL("Post init; master proc chip target handle was not of " + "chip class"); + } + + if ( l_pMasterProcChipTargetHandle->getAttr<ATTR_TYPE> () + != TYPE_PROC) + { + TS_FAIL("Post init; master proc chip target handle was not of " + "proc type"); + } + + // Post init + // Test: void getTopLevelTarget(Target*& o_targetHandle) const; + + Target* l_pTopLevel = NULL; + (void) l_targetService.getTopLevelTarget(l_pTopLevel); + if (l_pTopLevel == NULL) + { + TS_FAIL("Top level handle was NULL when initialization " + "complete"); + } + + if (l_pTopLevel->getAttr<ATTR_CLASS> () != CLASS_SYS) + { + TS_FAIL("Post init; top level target class != CLASS_SYS"); + } + + // Post init + // Test: void exists( + // const EntityPath& i_entityPath, + // bool& o_exists) const; + + bool l_exists = false; + (void) l_targetService.exists( + l_pTopLevel->getAttr<ATTR_PHYS_PATH> (), l_exists); + + if (l_exists != true) + { + TS_FAIL("Expected top level target to exist"); + } + + // Post init + // Test: Target* toTarget( + // const EntityPath& i_entityPath) const; + + Target* l_pInverseTarget = NULL; + l_pInverseTarget = l_targetService.toTarget( + l_pTopLevel->getAttr<ATTR_PHYS_PATH> ()); + + if (l_pInverseTarget != l_pTopLevel) + { + TS_FAIL("Expected to get the original target"); + } + + // Post init + // Test: void getAssociated( + // const Target* i_pTarget, + // ASSOCIATION_TYPE i_type, + // RECURSION_LEVEL i_recursionLevel, + // TargetHandleList& o_list) const; + + TargetHandleList l_list; + (void) l_targetService.getAssociated(l_pTopLevel, + TARGETING::TargetService::CHILD, + TARGETING::TargetService::IMMEDIATE, l_list); + if (!l_list.size()) + { + TS_FAIL("Should have found some child elements" ); + } + + // Verify child of given target has a parent that is the original + // target + + TargetHandleList l_parentList; + (void) l_targetService.getAssociated(l_list[0], + TARGETING::TargetService::PARENT, + TARGETING::TargetService::IMMEDIATE, l_parentList); + + if (l_parentList.size() != 1) + { + TS_FAIL("Should have found a parent element" ); + } + + if (l_parentList[0] != l_pTopLevel) + { + TS_FAIL("Parent handle should have matched original target " + "handle" ); + } + + (void) l_targetService.getAssociated(l_pTopLevel, + TARGETING::TargetService::CHILD_BY_AFFINITY, + TARGETING::TargetService::IMMEDIATE, l_list); + + if (!l_list.size()) + { + TS_FAIL("Should have found some child elements" ); + } + + (void) l_targetService.getAssociated(l_pTopLevel, + TARGETING::TargetService::CHILD_BY_AFFINITY, + TARGETING::TargetService::ALL, l_list); + + if (!l_list.size()) + { + TS_FAIL("Should have found more child elements" ); + } + + l_targetService.dump(); + + TS_TRACE(EXIT_MRK "testTargetServiceClass" ); + } + + /** + * @test Tests the EntityPath class (except debug cases) + */ + void testEntityPathClass(void) + { + TS_TRACE(ENTER_MRK "testEntityPathClass" ); + + using namespace TARGETING; + + EntityPath l_defaultPath; + if(l_defaultPath.size() != 0) + { + TS_FAIL("Default entity path's size was not 0"); + } + + if(l_defaultPath.type() != EntityPath::PATH_NA) + { + TS_FAIL("Default entity path's type was not PATH_NA"); + } + + EntityPath l_nonDefaultPath(EntityPath::PATH_PHYSICAL); + if(l_nonDefaultPath.size() != 0) + { + TS_FAIL("Non-default entity path's size was not 0"); + } + + if(l_nonDefaultPath.type() != EntityPath::PATH_PHYSICAL) + { + TS_FAIL("Non-default entity path's type was not " + "EntityPath::PATH_PHYSICAL"); + } + + l_defaultPath.setType(EntityPath::PATH_AFFINITY); + if(l_defaultPath.type() != EntityPath::PATH_AFFINITY) + { + TS_FAIL("Default entity path's type was not " + "EntityPath::PATH_AFFINITY after setting"); + } + + l_defaultPath.setType(EntityPath::PATH_PHYSICAL); + if(!(l_defaultPath == l_nonDefaultPath)) + { + TS_FAIL("Default entity path should have been equal to " + "the non-default entity path"); + } + + if(!l_defaultPath.equals(l_nonDefaultPath,0)) + { + TS_FAIL("Default entity path should have been equal to " + "the non-default entity path (equals API)"); + } + + l_defaultPath.addLast(TYPE_PROC,0); + if(l_defaultPath == l_nonDefaultPath) + { + TS_FAIL("Default entity path should NOT have been equal to " + "the non-default entity path"); + } + + if(l_defaultPath.equals(l_nonDefaultPath,1)) + { + TS_FAIL("Default entity path should NOT have been equal to " + "the non-default entity path (equals API, comparing 1 " + "element)"); + } + + if(l_defaultPath.size() != 1) + { + TS_FAIL("Default entity path should have had one path element" + "after adding PROC0"); + } + + l_nonDefaultPath.addLast(TYPE_PROC,0); + if(! (l_defaultPath == l_nonDefaultPath) ) + { + TS_FAIL("Default entity path should have been equal to " + "the non-default entity path since they now" + "both have the same 1 path element"); + } + + l_defaultPath.addLast(TYPE_MBA,1).addLast(TYPE_MBS,2); + if(l_defaultPath.size() != 3) + { + TS_FAIL("Default entity path should have had two path elements" + "after adding MBA1 and MBS2"); + } + + if( (l_defaultPath[0].type != TYPE_PROC) + || (l_defaultPath[0].instance != 0) + || (l_defaultPath[1].type != TYPE_MBA) + || (l_defaultPath[1].instance != 1) + || (l_defaultPath[2].type != TYPE_MBS) + || (l_defaultPath[2].instance != 2)) + { + TS_FAIL("Default entity path should have had correct 3 path " + "elements"); + } + + l_defaultPath.removeLast(); + if(l_defaultPath.size() != 2) + { + TS_FAIL("Default entity path should have had two path elements" + "after removing MBS2"); + } + + if( (l_defaultPath[0].type != TYPE_PROC) + || (l_defaultPath[0].instance != 0) + || (l_defaultPath[1].type != TYPE_MBA) + || (l_defaultPath[1].instance != 1)) + { + TS_FAIL("Default entity path should have had correct 2 path " + "elements"); + } + + l_nonDefaultPath.addLast(TYPE_MBA,1).addLast(TYPE_MBS,2); + + // Default now has proc/mba/ + // Non-default now has proc/mba/mbs + if(l_defaultPath == l_nonDefaultPath) + { + TS_FAIL("Default entity path should NOT have been equal to " + "the non-default entity path since they now" + "have different number of path elements"); + } + + if( !l_defaultPath.equals(l_nonDefaultPath,2) ) + { + TS_FAIL("Default entity path should have been equal to " + "the non-default entity path since they have the same" + "first two path elements"); + } + + l_defaultPath.removeLast().removeLast(); + if(l_defaultPath.size() != 0) + { + TS_FAIL("Default entity path should have had no path element" + "after removing MBA1 and PROC0"); + } + + TargetService& l_targetService = targetService(); + l_targetService.init(); + + EntityPath l_realPath(EntityPath::PATH_PHYSICAL); + l_realPath.addLast(TYPE_SYS,0).addLast(TYPE_NODE,0) + .addLast(TYPE_PROC,0); + + Target* l_pTarget = l_realPath.operator->(); + if(l_pTarget == NULL) + { + TS_FAIL("Real entity path should have mapped to an existing " + "target"); + } + + EntityPath l_path(EntityPath::PATH_PHYSICAL); + l_path.addLast(TYPE_SYS,0); + EntityPath l_changedPath = l_path.copyRemoveLast(); + if( (l_changedPath.size() != 0) + || (l_path.size() != 1)) + { + TS_FAIL("Const entity path should not have been altered in " + "const add test"); + } + + l_changedPath = l_path.copyAddLast(TYPE_NODE,0); + if( (l_changedPath.size() != 2) + || (l_path.size() != 1)) + { + TS_FAIL("Const entity path should not have been altered " + "in const add test"); + } + + TS_TRACE(EXIT_MRK "testEntityPathClass" ); + } + + /** + * @test Tests the EntityPath class (except debug cases) + */ + void testTargetClass(void) + { + TS_TRACE(ENTER_MRK "testTargetClass" ); + + using namespace TARGETING; + TargetService& l_targetService = targetService(); + l_targetService.init(); + + EntityPath l_realPath(EntityPath::PATH_PHYSICAL); + l_realPath.addLast(TYPE_SYS,0).addLast(TYPE_NODE,0) + .addLast(TYPE_PROC,0); + l_realPath.dump(); + + Target* l_pTarget = l_realPath.operator->(); + if(l_pTarget == NULL) + { + TS_FAIL("Failed to convert entity path to initial target"); + } + + CLASS l_class = l_pTarget->getAttr<ATTR_CLASS>(); + if(l_class != CLASS_CHIP) + { + TS_FAIL("Failed to get the class attribute"); + } + + l_class = CLASS_NA; + if( !l_pTarget->tryGetAttr<ATTR_CLASS>(l_class) ) + { + TS_FAIL("Failed to get the class attribute"); + } + + if(l_class != CLASS_CHIP) + { + TS_FAIL("Failed to try/get the class attribute"); + } + + attrToString<ATTR_CLASS>(l_class); + + uint8_t l_scom = 0; + if( l_pTarget->tryGetAttr<ATTR_DUMMY_RO>(l_scom) ) + { + TS_FAIL("ATTR_DUMMY_RO attribute should not have been available " + "to read"); + } + + if(l_scom != 0) + { + TS_FAIL("Failed ! try/get should not have set the SCOM attribute"); + } + + l_scom = 5; + if( l_pTarget->trySetAttr<ATTR_DUMMY_WO>(l_scom) ) + { + TS_FAIL("ATTR_DUMMY_WO attribute should not have been available " + "to write"); + } + + if(l_scom != 5) + { + TS_FAIL("SCOM attribute should not have been altered in the failed " + "write"); + } + + uint8_t l_wo = 6; + if( !l_pTarget->trySetAttr<ATTR_DUMMY_RW>(l_wo) ) + { + TS_FAIL("ATTR_DUMMY_RW should have been available for write"); + } + + if(l_wo != 6) + { + TS_FAIL("ATTR_DUMMY_RW local attribute should not have been " + "altered in the successful write"); + } + + uint8_t l_read = l_pTarget->getAttr<ATTR_DUMMY_RW>(); + if(l_read != l_wo) + { + TS_FAIL("Failed to read back the correct ATTR_DUMMY_RW"); + } + + uint8_t l_setWo = 9; + l_pTarget->setAttr<ATTR_DUMMY_RW>(l_setWo); + if(l_setWo != 9) + { + TS_FAIL("ATTR_DUMMY_RW local attribute should not have been " + "altered in the successful setAttr"); + } + + uint8_t l_setWoVerify = l_pTarget->getAttr<ATTR_DUMMY_RW>(); + if(l_setWoVerify != l_setWo) + { + TS_FAIL("ATTR_DUMMY_RW read should have matched prior write"); + } + + TS_TRACE(EXIT_MRK "testTargetClass" ); + } +}; + +#endif // End __TESTTARGETING_H diff --git a/src/usr/targeting/trace.H b/src/usr/targeting/trace.H new file mode 100644 index 000000000..d16ef8ece --- /dev/null +++ b/src/usr/targeting/trace.H @@ -0,0 +1,43 @@ + +#ifndef TARG_TRACE_H +#define TARG_TRACE_H + +/** + * @file trace.H + * + * @brief Targeting related trace macros. Callers of these macros must + * define TARG_NAMESPACE, TARG_CLASS, and TARG_FN as appropriate + */ + +//****************************************************************************** +// Includes +//****************************************************************************** + +// Other Components +#include <trace/interface.H> + +// Give callers access to the trace buffer +namespace TARGETING +{ + extern trace_desc_t* g_trac_targeting; +} + +#define TARG_TAG "[TARG]" +#define TARG_ENTER(args...) \ + TRACFCOMP(TARGETING::g_trac_targeting,TARG_TAG " " ENTER_MRK " " TARG_NAMESPACE \ + TARG_CLASS TARG_FN " " args) + +#define TARG_EXIT(args...) \ + TRACFCOMP(TARGETING::g_trac_targeting,TARG_TAG " " EXIT_MRK " " TARG_NAMESPACE \ + TARG_CLASS TARG_FN " " args) + +#define TARG_ERR(args...) \ + TRACFCOMP(TARGETING::g_trac_targeting,TARG_TAG " " ERR_MRK " " args) + +#define TARG_INF(args...) \ + TRACFCOMP(TARGETING::g_trac_targeting,TARG_TAG " " INFO_MRK " " args) + +#define TARG_BIN(args...) \ + TRACFBIN(TARGETING::g_trac_targeting,TARG_TAG " " args) + +#endif // TARG_TRACE_H |