summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/ecmddatabuffer/ecmdDataBuffer.H120
-rw-r--r--src/include/usr/hwpf/fapi/fapi.H22
-rw-r--r--src/include/usr/hwpf/fapi/fapiAttributeService.H426
-rw-r--r--src/include/usr/hwpf/fapi/fapiHwAccess.H115
-rw-r--r--src/include/usr/hwpf/fapi/fapiReturnCode.H174
-rw-r--r--src/include/usr/hwpf/fapi/fapiReturnCodeDataRef.H106
-rw-r--r--src/include/usr/hwpf/fapi/fapiReturnCodes.H39
-rw-r--r--src/include/usr/hwpf/fapi/fapiSystemConfig.H73
-rw-r--r--src/include/usr/hwpf/fapi/fapiTarget.H195
-rw-r--r--src/include/usr/hwpf/fapi/fapiUtil.H28
-rw-r--r--src/include/usr/hwpf/hwp/fapiTestHwp.H31
-rw-r--r--src/include/usr/hwpf/plat/fapiPlatHwpExecutor.H22
-rw-r--r--src/include/usr/hwpf/plat/fapiPlatHwpInvoker.H32
-rw-r--r--src/include/usr/hwpf/plat/fapiPlatTrace.H46
-rw-r--r--src/makefile6
-rwxr-xr-xsrc/usr/ecmddatabuffer/ecmdDataBuffer.C215
-rw-r--r--src/usr/ecmddatabuffer/makefile10
-rw-r--r--src/usr/ecmddatabuffer/test/ecmddatabuffertest.H26
-rw-r--r--src/usr/ecmddatabuffer/test/makefile6
-rw-r--r--src/usr/hwpf/fapi/fapiAttributeService.C187
-rwxr-xr-xsrc/usr/hwpf/fapi/fapiParseAttributeInfo.pl144
-rwxr-xr-xsrc/usr/hwpf/fapi/fapiParseErrorInfo.pl79
-rw-r--r--src/usr/hwpf/fapi/fapiReturnCode.C192
-rw-r--r--src/usr/hwpf/fapi/fapiReturnCodeDataRef.C85
-rw-r--r--src/usr/hwpf/fapi/fapiTarget.C118
-rw-r--r--src/usr/hwpf/fapi/makefile13
-rw-r--r--src/usr/hwpf/hwp/fapiHwpAttributeInfo.xml50
-rw-r--r--src/usr/hwpf/hwp/fapiHwpErrorInfo.xml15
-rw-r--r--src/usr/hwpf/hwp/fapiTestHwp.C121
-rw-r--r--src/usr/hwpf/hwp/makefile11
-rw-r--r--src/usr/hwpf/makefile16
-rw-r--r--src/usr/hwpf/plat/fapiPlatHwAccess.C142
-rw-r--r--src/usr/hwpf/plat/fapiPlatHwpInvoker.C84
-rw-r--r--src/usr/hwpf/plat/fapiPlatReturnCodeDataRef.C28
-rw-r--r--src/usr/hwpf/plat/fapiPlatSystemConfig.C72
-rw-r--r--src/usr/hwpf/plat/fapiPlatTarget.C50
-rw-r--r--src/usr/hwpf/plat/fapiPlatUtil.C39
-rw-r--r--src/usr/hwpf/plat/makefile16
-rw-r--r--src/usr/hwpf/test/fapirctest.H461
-rw-r--r--src/usr/hwpf/test/fapitargettest.H266
-rw-r--r--src/usr/hwpf/test/hwpftest.H94
-rw-r--r--src/usr/hwpf/test/makefile11
-rw-r--r--src/usr/makefile2
-rw-r--r--src/usr/xscom/test/xscomtest.H48
-rw-r--r--src/usr/xscom/xscom.C66
-rw-r--r--src/usr/xscom/xscom.H18
46 files changed, 4063 insertions, 57 deletions
diff --git a/src/include/usr/ecmddatabuffer/ecmdDataBuffer.H b/src/include/usr/ecmddatabuffer/ecmdDataBuffer.H
new file mode 100644
index 000000000..afb438431
--- /dev/null
+++ b/src/include/usr/ecmddatabuffer/ecmdDataBuffer.H
@@ -0,0 +1,120 @@
+#ifndef ECMDDATABUFFER_H
+#define ECMDDATABUFFER_H
+
+/**
+ * @file ecmdDataBuffer.H
+ * @brief Provides a means to handle data from the eCMD C API
+ *
+ * @todo - This is only created to compile code. Needs to be replaced with John Farrugia's version
+ *
+ */
+
+//----------------------------------------------------------------------
+// Constants
+//----------------------------------------------------------------------
+/* Define these if for some reason we are building without ecmdReturnCodes.H */
+#define ECMD_ERR_ECMD 0x01000000 ///< Error came from eCMD
+#define ECMD_DBUF_SUCCESS 0x0 ///< DataBuffer returned successfully
+
+/**
+ @brief Provides a means to handle data from the eCMD C API
+*/
+class ecmdDataBufferBase {
+
+public:
+
+ /** @name ecmdDataBufferBase Constructors */
+ /**
+ * @brief Default Constructor
+ * @post buffer is not allocated, can be allocated later with setWordLength, setCapacity or setBitLength
+ */
+ ecmdDataBufferBase();
+
+ /**
+ * @brief Constructor
+ * @param i_numBits Size of data in bits to initialize
+ * @post ecmdDataBufferBase is initialized and zero'd out
+ */
+ explicit ecmdDataBufferBase(uint32_t i_numBits);
+
+ /**
+ * @brief Default Destructor
+ */
+ virtual ~ecmdDataBufferBase();
+
+ /**
+ * @brief Called by the destructor, available to user to reset buffer to default constructor state
+ * @retval ECMD_DBUF_SUCCESS on success
+ * @retval ECMD_DBUF_NOT_OWNER when called on buffer not owned
+ * @retval nonzero on failure
+ * @post Memory deallocated and size set to 0
+ */
+ uint32_t clear();
+
+ /**
+ * @brief Reinitialize the Buffer to specified length
+ * @param i_newNumBits Length of new buffer in bits
+ * @retval ECMD_DBUF_SUCCESS on success
+ * @retval ECMD_DBUF_INIT_FAIL failure occurred setting new length
+ * @retval ECMD_DBUF_NOT_OWNER when called on buffer not owned
+ * @post Buffer is reinitialized and zero'd out
+ *
+ * NOTE : Capacity will be adjusted to fit new size if neccesary
+ * CAUTION : All data stored in buffer will be lost
+ */
+ uint32_t setBitLength(uint32_t i_newNumBits);
+
+ /**
+ * @brief Reinitialize the internal buffer to specified length
+ * @param i_newNumWords length of internal data buffer in words
+ * @retval ECMD_DBUF_SUCCESS on success
+ * @retval ECMD_DBUF_INIT_FAIL failure occurred setting new length
+ * @retval ECMD_DBUF_NOT_OWNER when called on buffer not owned
+ * @post Internal buffer is reinitialized and zero'd out. Requests to decrease the capacity are ignored
+ *
+ * CAUTION : All data stored in buffer will be lost
+ */
+ uint32_t setCapacity (uint32_t i_newNumWords);
+
+
+ /**
+ * @brief Set a doubleword of data in buffer
+ * @param i_doublewordoffset Offset of doubleword to set
+ * @param i_value 64 bits of data to put into doubleword
+ * @retval ECMD_DBUF_SUCCESS on success
+ * @retval ECMD_DBUF_BUFFER_OVERFLOW i_doublewordoffset is not contained in the size of this buffer
+ *
+ * NOTE : If the buffer length != double word boundary, when setting the last double word
+ * data in i_value past the buffer length is cleared before being stored in the buffer
+ */
+ uint32_t setDoubleWord(uint32_t i_doublewordoffset, uint64_t i_value);
+
+ /**
+ * @brief Fetch a doubleword from ecmdDataBuffer
+ * @param i_doublewordoffset Offset of doubleword to fetch
+ * @retval Value of doubleword requested
+ */
+ uint64_t getDoubleWord(uint32_t i_doublewordoffset) const;
+
+ /**
+ * @brief Return the length of the buffer in words
+ * @retval Buffer length in words rounded up
+ */
+ uint32_t getWordLength() const;
+
+ /**
+ * @brief Clear entire buffer to 0's
+ * @retval ECMD_DBUF_SUCCESS on success
+ */
+ uint32_t flushTo0();
+
+protected:
+ uint32_t iv_Capacity; ///< Actual buffer capacity - always >= getNumWords()
+ uint32_t iv_NumBits; ///< Specified buffer size in bits
+ uint32_t *iv_Data; ///< Pointer to buffer inside iv_RealData
+ uint32_t *iv_RealData; ///< Real buffer - with header and tail
+ uint32_t iv_LocalData[4]; ///< If the buffer is <= 64 bits, we'll store the data locally in the class
+ bool iv_UserOwned; ///< Whether or not this buffer owns the data
+};
+
+#endif /* ECMDDATABUFFER_H */
diff --git a/src/include/usr/hwpf/fapi/fapi.H b/src/include/usr/hwpf/fapi/fapi.H
new file mode 100644
index 000000000..cc2066990
--- /dev/null
+++ b/src/include/usr/hwpf/fapi/fapi.H
@@ -0,0 +1,22 @@
+/**
+ * @file fapi.H
+ *
+ * @brief Includes all the header files necessary for the FAPI interface.
+ */
+
+#ifndef FAPI_H_
+#define FAPI_H_
+
+#include <fapiTarget.H>
+#include <fapiReturnCode.H>
+#include <fapiUtil.H>
+#include <fapiHwAccess.H>
+#include <fapiSystemConfig.H>
+#include <fapiPlatTrace.H>
+#include <fapiPlatHwpExecutor.H>
+#include <fapiAttributeService.H>
+#include <fapiHwpReturnCodes.H> // Generated file
+#include <fapiAttributeIds.H> // Generated file
+#include <ecmdDataBuffer.H>
+
+#endif // FAPI_H_
diff --git a/src/include/usr/hwpf/fapi/fapiAttributeService.H b/src/include/usr/hwpf/fapi/fapiAttributeService.H
new file mode 100644
index 000000000..52981318a
--- /dev/null
+++ b/src/include/usr/hwpf/fapi/fapiAttributeService.H
@@ -0,0 +1,426 @@
+/**
+ * @file fapiAttributeService.H
+ *
+ * @brief Defines the FAPI_ATTR_GET and FAPI_ATTR_SET macros that a user calls
+ * to get/set attributes and the AttributeService functions that the
+ * macros use to get/set attributes
+ */
+
+#ifndef FAPIATTRIBUTESERVICE_H_
+#define FAPIATTRIBUTESERVICE_H_
+#include <stdint.h>
+#include <fapiAttributeIds.H>
+#include <fapiReturnCode.H>
+#include <fapiTarget.H>
+
+/**
+ * @brief Macros called by user to get/set attributes
+ *
+ * @note The user must use these macros rather than use the AttributeService
+ * _get/_set functions so that the type can be checked at compile time
+ *
+ * Code must have a pointer to a Target and an attribute ID (from XML file):
+ * fapi::ReturnCode l_rc;
+ * fapi::Target * l_pTarget = ????;
+ * AttributeId l_id = ????;
+ *
+ * To get a copy of a string attribute
+ * char * l_pString = NULL;
+ * l_rc = FAPI_ATTR_GET(l_id, l_pTarget, l_pString);
+ * delete[] l_pString; // When finished with the attribute
+ *
+ * To set a string attribute
+ * l_rc = FAPI_ATTR_SET(l_id, l_pTarget, "string-literal");
+ * l_rc = FAPI_ATTR_SET(l_id, l_pTarget, l_pString);
+ *
+ * To get a copy of an integer attribute and set the attribute
+ * uint64_t l_val = 0;
+ * l_rc = FAPI_ATTR_GET(l_id, l_pTarget, l_val);
+ * l_rc = FAPI_ATTR_SET(l_id, l_pTarget, l_val);
+ *
+ * To get a copy of an integer array attribute and set the attribute
+ * uint32_t l_pVal[4] = {0};
+ * l_rc = FAPI_ATTR_GET(l_id, l_pTarget, l_pVal);
+ * l_rc = FAPI_ATTR_SET(l_id, l_pTarget, l_pVal);
+ */
+#define FAPI_ATTR_GET(ID, PTARGET, VAL) \
+ fapi::AttributeService::_get<fapi::ID##_Type>(fapi::ID, PTARGET, VAL)
+#define FAPI_ATTR_SET(ID, PTARGET, VAL) \
+ fapi::AttributeService::_set<fapi::ID##_Type>(fapi::ID, PTARGET, VAL)
+
+namespace fapi
+{
+
+/**
+ * @namespace AttributeService
+ *
+ * This class defines the attribute access functions. These functions must not
+ * be accessed directly, they should only be called by the FAPI_ATTR_GET and
+ * FAPI_ATTR_SET macros.
+ *
+ * Each function comes in two parts. If the caller of FAPI_ATTR_GET attempts to
+ * get an incorrect type then the normal template function will be instantiated
+ * and the construction of the undefined InvalidTypeRequestedForAttribute class
+ * will cause a compile failure. Only if the caller attempts to get the correct
+ * type will the specialized function be called which will work.
+ */
+namespace AttributeService
+{
+
+/**
+ * @brief Forward declaration of class that will never be defined
+ */
+class InvalidTypeRequestedForAttribute;
+
+/**
+ * @brief Get a copy of a string attribute
+ *
+ * @param[in] i_id Attribute ID
+ * @param[in] i_pTarget Pointer to Target that the attribute is associated with
+ * (NULL if system attribute)
+ * @param[out] o_pValue Reference to pointer that will be set to point to newly
+ * allocated memory holding the attribute value
+ *
+ * @return ReturnCode. Zero on success, else error.
+ *
+ * @note The caller must free the data with "delete [] o_pValue"
+ */
+template<typename T>
+ReturnCode _get(const AttributeId i_id,
+ const Target * const i_pTarget,
+ char * & o_pValue)
+{
+ InvalidTypeRequestedForAttribute();
+ return FAPI_RC_SUCCESS;
+}
+template<> // Specialized template function defined in fapiAttributeService.C
+ReturnCode _get<char *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ char * & o_value);
+
+/**
+ * @brief Get a copy of a uint8_t attribute
+ *
+ * @param[in] i_id Attribute ID
+ * @param[in] i_pTarget Pointer to Target that the attribute is associated with
+ * (NULL if system attribute)
+ * @param[out] o_value Reference to data that will be set to the attribute val
+ *
+ * @return ReturnCode. Zero on success, else error.
+ */
+template<typename T>
+ReturnCode _get(const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint8_t& o_value)
+{
+ InvalidTypeRequestedForAttribute();
+ return FAPI_RC_SUCCESS;
+}
+template<> // Specialized template function defined in fapiAttributeService.C
+ReturnCode _get<uint8_t> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint8_t & o_value);
+
+/**
+ * @brief Get a copy of a uint32_t attribute
+ *
+ * @param[in] i_id Attribute ID
+ * @param[in] i_pTarget Pointer to Target that the attribute is associated with
+ * (NULL if system attribute)
+ * @param[out] o_value Reference to data that will be set to the attribute val
+ *
+ * @return ReturnCode. Zero on success, else error.
+ */
+template<typename T>
+ReturnCode _get(const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint32_t& o_value)
+{
+ InvalidTypeRequestedForAttribute();
+ return FAPI_RC_SUCCESS;
+}
+template<> // Specialized template function defined in fapiAttributeService.C
+ReturnCode _get<uint32_t> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint32_t & o_value);
+
+/**
+ * @brief Get a copy of a uint64_t attribute
+ *
+ * @param[in] i_id Attribute ID
+ * @param[in] i_pTarget Pointer to Target that the attribute is associated with
+ * (NULL if system attribute)
+ * @param[out] o_value Reference to data that will be set to the attribute val
+ *
+ * @return ReturnCode. Zero on success, else error.
+ */
+template<typename T>
+ReturnCode _get(const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint64_t& o_value)
+{
+ InvalidTypeRequestedForAttribute();
+ return FAPI_RC_SUCCESS;
+}
+template<> // Specialized template function defined in fapiAttributeService.C
+ReturnCode _get<uint64_t> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint64_t & o_value);
+
+/**
+ * @brief Get a copy of a uint8_t array attribute
+ *
+ * @param[in] i_id Attribute ID
+ * @param[in] i_pTarget Pointer to Target that the attribute is associated with
+ * (NULL if system attribute)
+ * @param[out] o_pValues Pointer to data that will be set to the attribute value
+ *
+ * @return ReturnCode. Zero on success, else error.
+ *
+ * @note The caller's o_pValues pointer must point to memory large enough to
+ * hold the attribute.
+ */
+template<typename T>
+ReturnCode _get(const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint8_t * const o_pValues)
+{
+ InvalidTypeRequestedForAttribute();
+ return FAPI_RC_SUCCESS;
+}
+template<> // Specialized template function defined in fapiAttributeService.C
+ReturnCode _get<uint8_t *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint8_t * const o_pValues);
+
+/**
+ * @brief Get a copy of a uint32_t array attribute
+ *
+ * @param[in] i_id Attribute ID
+ * @param[in] i_pTarget Pointer to Target that the attribute is associated with
+ * (NULL if system attribute)
+ * @param[out] o_pValues Pointer to data that will be set to the attribute value
+ *
+ * @return ReturnCode. Zero on success, else error.
+ *
+ * @note The caller's o_pValues pointer must point to memory large enough to
+ * hold the attribute.
+ */
+template<typename T>
+ReturnCode _get(const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint32_t * const o_pValues)
+{
+ InvalidTypeRequestedForAttribute();
+ return FAPI_RC_SUCCESS;
+}
+template<> // Specialized template function defined in fapiAttributeService.C
+ReturnCode _get<uint32_t *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint32_t * const o_pValues);
+
+/**
+ * @brief Get a copy of a uint64_t array attribute
+ *
+ * @param[in] i_id Attribute ID
+ * @param[in] i_pTarget Pointer to Target that the attribute is associated with
+ * (NULL if system attribute)
+ * @param[out] o_pValues Pointer to data that will be set to the attribute value
+ *
+ * @return ReturnCode. Zero on success, else error.
+ *
+ * @note The caller's o_pValues pointer must point to memory large enough to
+ * hold the attribute.
+ */
+template<typename T>
+ReturnCode _get(const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint64_t * const o_pValues)
+{
+ InvalidTypeRequestedForAttribute();
+ return FAPI_RC_SUCCESS;
+}
+template<> // Specialized template function defined in fapiAttributeService.C
+ReturnCode _get<uint64_t *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint64_t * const o_pValues);
+
+/**
+ * @brief Set a string attribute
+ *
+ * @param[in] i_id Attribute ID
+ * @param[in] i_pTarget Pointer to Target that the attribute is associated with
+ * (NULL if system attribute)
+ * @param[in] i_pValue Pointer to string containing the attribute value to set
+ *
+ * @return ReturnCode. Zero on success, else error.
+ */
+template<typename T>
+ReturnCode _set(const AttributeId i_id,
+ const Target * const i_pTarget,
+ const char * const i_pValue)
+{
+ InvalidTypeRequestedForAttribute();
+ return FAPI_RC_SUCCESS;
+}
+template<> // Specialized template function defined in fapiAttributeService.C
+ReturnCode _set<char *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ const char * const i_pValue);
+
+/**
+ * @brief Set a uint8_t attribute
+ *
+ * @param[in] i_id Attribute ID
+ * @param[in] i_pTarget Pointer to Target that the attribute is associated with
+ * (NULL if system attribute)
+ * @param[in] i_value Attribute value to set
+ *
+ * @return ReturnCode. Zero on success, else error.
+ */
+template<typename T>
+ReturnCode _set(const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint8_t i_value)
+{
+ InvalidTypeRequestedForAttribute();
+ return FAPI_RC_SUCCESS;
+}
+template<> // Specialized template function defined in fapiAttributeService.C
+ReturnCode _set<uint8_t> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint8_t i_value);
+
+/**
+ * @brief Set a uint32_t attribute
+ *
+ * @param[in] i_id Attribute ID
+ * @param[in] i_pTarget Pointer to Target that the attribute is associated with
+ * (NULL if system attribute)
+ * @param[in] i_value Attribute value to set
+ *
+ * @return ReturnCode. Zero on success, else error.
+ */
+template<typename T>
+ReturnCode _set(const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint32_t i_value)
+{
+ InvalidTypeRequestedForAttribute();
+ return FAPI_RC_SUCCESS;
+}
+template<> // Specialized template function defined in fapiAttributeService.C
+ReturnCode _set<uint32_t> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint32_t i_value);
+
+/**
+ * @brief Set a uint64_t attribute
+ *
+ * @param[in] i_id Attribute ID
+ * @param[in] i_pTarget Pointer to Target that the attribute is associated with
+ * (NULL if system attribute)
+ * @param[in] i_value Attribute value to set
+ *
+ * @return ReturnCode. Zero on success, else error.
+ */
+template<typename T>
+ReturnCode _set(const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint64_t i_value)
+{
+ InvalidTypeRequestedForAttribute();
+ return FAPI_RC_SUCCESS;
+}
+template<> // Specialized template function defined in fapiAttributeService.C
+ReturnCode _set<uint64_t> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint64_t i_value);
+
+/**
+ * @brief Set a uint8_t array attribute
+ *
+ * @param[in] i_id Attribute ID
+ * @param[in] i_pTarget Pointer to Target that the attribute is associated
+ * with (NULL if system attribute)
+ * @param[out] i_pValues Pointer to array containing the attribute values to
+ * set
+ *
+ * @return ReturnCode. Zero on success, else error.
+ *
+ * @note The caller's o_pValues pointer must point to memory large enough to
+ * hold the attribute.
+ */
+template<typename T>
+ReturnCode _set(const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint8_t * const i_pValues)
+{
+ InvalidTypeRequestedForAttribute();
+ return FAPI_RC_SUCCESS;
+}
+template<> // Specialized template function defined in fapiAttributeService.C
+ReturnCode _set<uint8_t *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint8_t * const i_pValues);
+
+/**
+ * @brief Set a uint32_t array attribute
+ *
+ * @param[in] i_id Attribute ID
+ * @param[in] i_pTarget Pointer to Target that the attribute is associated
+ * with (NULL if system attribute)
+ * @param[out] i_pValues Pointer to array containing the attribute values to
+ * set
+ *
+ * @return ReturnCode. Zero on success, else error.
+ *
+ * @note The caller's o_pValues pointer must point to memory large enough to
+ * hold the attribute.
+ */
+template<typename T>
+ReturnCode _set(const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint32_t * const i_pValues)
+{
+ InvalidTypeRequestedForAttribute();
+ return FAPI_RC_SUCCESS;
+}
+template<> // Specialized template function defined in fapiAttributeService.C
+ReturnCode _set<uint32_t *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint32_t * const i_pValues);
+
+/**
+ * @brief Set a uint64_t array attribute
+ *
+ * @param[in] i_id Attribute ID
+ * @param[in] i_pTarget Pointer to Target that the attribute is associated
+ * with (NULL if system attribute)
+ * @param[out] i_pValues Pointer to array containing the attribute values to
+ * set
+ *
+ * @return ReturnCode. Zero on success, else error.
+ *
+ * @note The caller's o_pValues pointer must point to memory large enough to
+ * hold the attribute.
+ */
+template<typename T>
+ReturnCode _set(const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint64_t * const i_pValues)
+{
+ InvalidTypeRequestedForAttribute();
+ return FAPI_RC_SUCCESS;
+}
+template<> // Specialized template function defined in fapiAttributeService.C
+ReturnCode _set<uint64_t *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint64_t * const i_pValues);
+
+
+} // namespace AttributeService
+
+} // namespace fapi
+
+#endif // FAPIATTRIBUTESERVICE_H_
diff --git a/src/include/usr/hwpf/fapi/fapiHwAccess.H b/src/include/usr/hwpf/fapi/fapiHwAccess.H
new file mode 100644
index 000000000..948d4feb0
--- /dev/null
+++ b/src/include/usr/hwpf/fapi/fapiHwAccess.H
@@ -0,0 +1,115 @@
+/**
+ * @file fapiHwAccess.H
+ *
+ * @brief Defines the hardware access functions that platform code must
+ * implement. It is a HWP requirement that these be "C" functions.
+ */
+
+#ifndef FAPIHWACCESS_H_
+#define FAPIHWACCESS_H_
+
+#include <stdint.h>
+#include <fapiReturnCode.H>
+#include <fapiTarget.H>
+#include <ecmdDataBuffer.H>
+
+namespace fapi
+{
+ /**
+ * @brief Enumeration of modify modes used in modify operations
+ */
+ enum ChipOpModifyMode
+ {
+ CHIP_OP_MODIFY_MODE_OR = 1,
+ CHIP_OP_MODIFY_MODE_AND = 2,
+ CHIP_OP_MODIFY_MODE_XOR = 3,
+ };
+}
+
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+// HW Communication Functions
+//------------------------------------------------------------------------------
+
+/**
+ * @brief Reads a SCOM register from a Chip
+ * @param[in] i_target Target to operate on
+ * @param[in] i_address Scom address to read from
+ * @param[out] o_data ecmdDataBufferBase object that holds data read from
+ * address
+ * @return ReturnCode. Zero on success, else platform specified error
+ */
+fapi::ReturnCode GetScom(const fapi::Target& i_target,
+ const uint64_t i_address,
+ ecmdDataBufferBase & o_data);
+
+/**
+ * @brief Writes a SCOM register on a Chip
+ * @param[in] i_target Target to operate on
+ * @param[in] i_address Scom address to write to
+ * @param[in] i_data ecmdDataBufferBase object that holds data to write into
+ * address
+ * @return ReturnCode. Zero on success, else platform specified error
+ */
+fapi::ReturnCode PutScom(const fapi::Target& i_target,
+ const uint64_t i_address,
+ ecmdDataBufferBase & i_data);
+
+/**
+ * @brief Writes a SCOM register under mask to a chip
+ * @param[in] i_target Target to operate on
+ * @param[in] i_address Scom address to write to
+ * @param[in] i_data ecmdDataBufferBase object that holds the data
+ * @param[in] i_mask ecmdDataBufferBase object that holds the mask (i_data to
+ * write)
+ * @return ReturnCode. Zero on success, else platform specified error
+ */
+fapi::ReturnCode PutScomUnderMask(const fapi::Target& i_target,
+ const uint64_t i_address,
+ ecmdDataBufferBase & i_data,
+ ecmdDataBufferBase & i_mask);
+
+
+/**
+ * @brief Reads a CFAM register from a chip
+ * @param[in] i_target Target to operate on
+ * @param[in] i_address CFAM address to read from
+ * @param[out] o_data ecmdDataBufferBase object that holds data read from
+ * address
+ * @return ReturnCode. Zero on success, else platform specified error
+ */
+fapi::ReturnCode GetCfamRegister(const fapi::Target& i_target,
+ const uint32_t i_address,
+ ecmdDataBufferBase & o_data);
+
+/**
+ * @brief Writes a CFAM register to a chip
+ * @param[in] i_target Target to operate on
+ * @param[in] i_address CFAM address to write to
+ * @param[in] i_data ecmdDataBufferBase object that holds data to write into
+ * address
+ * @return ReturnCode. Zero on success, else platform specified error
+ */
+fapi::ReturnCode PutCfamRegister(const fapi::Target& i_target,
+ const uint32_t i_address,
+ ecmdDataBufferBase & i_data);
+
+/**
+ * @brief Read-modify-write a CFAM register on a chip
+ * @param[in] i_target Target to operate on
+ * @param[in] i_address CFAM address to write to
+ * @param[in] i_data ecmdDataBufferBase object that holds the modifying data
+ * @param[in] i_modifyMode The modify mode (or/and/xor)
+ * @return ReturnCode. Zero on success, else platform specified error
+ */
+fapi::ReturnCode ModifyCfamRegister(const fapi::Target& i_target,
+ const uint32_t i_address,
+ ecmdDataBufferBase & i_data,
+ const fapi::ChipOpModifyMode i_modifyMode);
+
+
+} // extern "C"
+
+#endif // FAPIHWACCESS_H_
diff --git a/src/include/usr/hwpf/fapi/fapiReturnCode.H b/src/include/usr/hwpf/fapi/fapiReturnCode.H
new file mode 100644
index 000000000..29b448add
--- /dev/null
+++ b/src/include/usr/hwpf/fapi/fapiReturnCode.H
@@ -0,0 +1,174 @@
+/**
+ * @file fapiReturnCode.H
+ *
+ * @brief Defines the ReturnCode class that is a generic return code.
+ */
+
+#ifndef FAPIRETURNCODE_H_
+#define FAPIRETURNCODE_H_
+
+#include <stdint.h>
+#include <stddef.h>
+#include <fapiReturnCodes.H>
+
+namespace fapi
+{
+
+// Forward declaration
+class ReturnCodeDataRef;
+
+/**
+ * @class ReturnCode
+ *
+ * This class provides a generic return code. It contains the rcValue (return
+ * code value) which is of type uint32_t. A user can treat a ReturnCode just
+ * as if it were a uint32_t.
+ *
+ * FAPI, PLAT and HWP code can all create a ReturnCode. PLAT can optionally add
+ * platform specific ReturnCodeData to it.
+ *
+ * A ReturnCode is copyable and assignable. Therefore, it cannot be subclassed.
+ *
+ * When a ReturnCode is copied, any ReturnCodeData is not copied because it may
+ * be heavyweight. Both ReturnCodes will refer to the same ReturnCodeData.
+ * ReturnCodeData is only deleted when the last ReturnCode with a reference to
+ * it is deleted. It is possible for PLAT to get a pointer to the ReturnCodeData
+ * and to optionally release the data (ReturnCode no longer responsible for
+ * deleting). This is done using the intermediate ReturnCodeDataRef class.
+ *
+ * A ReturnCode object is not thread safe, multiple threads must not use the
+ * same ReturnCode object concurrently.
+ */
+class ReturnCode
+{
+public:
+
+ /**
+ * @brief Enumeration of return code creators
+ */
+ enum returnCodeCreator
+ {
+ CREATOR_FAPI = 1,
+ CREATOR_PLAT = 2,
+ CREATOR_HWP = 3,
+ };
+
+ /**
+ * @brief Default constructor. Sets rcValue to success
+ */
+ ReturnCode();
+
+ /**
+ * @brief Constructor. Sets rcValue to the specified value
+ *
+ * @note This allows an implicit conversion between a uint32_t and a
+ * ReturnCode. A user is allowed to return a uint32_t from a function
+ * that returns a ReturnCode or is allowed to pass a uint32_t to a
+ * function that expects a ReturnCode and in both cases, the uint32_t
+ * will be automatically converted to a ReturnCode.
+ *
+ * @param[in] i_rcValue The rcValue to set
+ */
+ ReturnCode(const uint32_t i_rcValue);
+
+ /**
+ * @brief Copy Constructor
+ *
+ * @param[in] i_right Reference to ReturnCode to copy
+ */
+ ReturnCode(const ReturnCode & i_right);
+
+ /**
+ * @brief Destructor
+ */
+ ~ReturnCode();
+
+ /**
+ * @brief Assignment Operator.
+ *
+ * @param[in] i_right Reference to ReturnCode to assign from.
+ *
+ * @return Reference to 'this' ReturnCode
+ */
+ ReturnCode & operator=(const ReturnCode & i_right);
+
+ /**
+ * @brief Assignment Operator.
+ *
+ * @param[in] i_rc Reference to rcValue to assign
+ *
+ * @return Reference to 'this' ReturnCode
+ */
+ ReturnCode & operator=(const uint32_t i_rcValue);
+
+ /**
+ * @brief Returns if the return code indicates success
+ *
+ * @return bool. True if ok, else false
+ */
+ bool ok() const;
+
+ /**
+ * @brief uint32_t conversion function. Returns the rcValue
+ *
+ * @note This allows a user to directly compare:
+ * 1/ ReturnCode to uint32_t (ReturnCode converted to uint32_t)
+ * 2/ ReturnCode to ReturnCode (Both ReturnCode converted to uint32_t)
+ */
+ operator uint32_t() const;
+
+ /**
+ * @brief Get a pointer to any ReturnCodeData. ReturnCode is still
+ * responsible for deletion of the data. The caller must not delete
+ *
+ * The data pointed to is only meaningful to platform code.
+ *
+ * @return void *. Pointer to any ReturnCodeData. If NULL then no data
+ */
+ void * getData() const;
+
+ /**
+ * @brief Get a pointer to any ReturnCodeData and release ownership from
+ * ReturnCode. The caller is responsible for deletion.
+ *
+ * The data pointed to is only meaningful to platform code.
+ *
+ * @return void *. Pointer to any ReturnCodeData. If NULL then no data
+ */
+ void * releaseData();
+
+ /**
+ * @brief Sets ReturnCodeData. The ReturnCode object takes responsibility
+ * for deleting the data (platform code actually implements the
+ * delete function and must know the type and how to delete it).
+ *
+ * The data pointed to is only meaningful to platform code.
+ *
+ * param[in] i_pData Pointer to ReturnCodeData (on the heap)
+ */
+ void setData(const void * i_pData);
+
+ /**
+ * @brief Gets the creator of the return code
+ *
+ * @return ReturnCodeCreator
+ */
+ returnCodeCreator getCreator() const;
+
+private:
+
+ /**
+ * @brief Removes interest in pointed to ReturnCodeDataRef
+ */
+ void removeData();
+
+ // The rcValue
+ uint32_t iv_rcValue;
+
+ // Pointer to ReturnCodeDataRef
+ ReturnCodeDataRef * iv_pDataRef;
+};
+
+}
+
+#endif // FAPIRETURNCODE_H_
diff --git a/src/include/usr/hwpf/fapi/fapiReturnCodeDataRef.H b/src/include/usr/hwpf/fapi/fapiReturnCodeDataRef.H
new file mode 100644
index 000000000..683438add
--- /dev/null
+++ b/src/include/usr/hwpf/fapi/fapiReturnCodeDataRef.H
@@ -0,0 +1,106 @@
+/**
+ * @file fapiReturnCodeDataRef.H
+ *
+ * @brief Defines the ReturnCodeDataRef class that provides a pointer and a
+ * reference count to a platform specific ReturnCodeData object.
+ */
+
+#ifndef FAPIRETURNCODEDATAREF_H_
+#define FAPIRETURNCODEDATAREF_H_
+
+#include <stdint.h>
+#include <stddef.h>
+
+namespace fapi
+{
+
+/**
+ * @class ReturnCodeDataRef
+ *
+ * This class contains a pointer to platform specific ReturnCodeData and a
+ * reference count recording how many ReturnCodes have a pointer to itself.
+ *
+ * It is used exclusively by the ReturnCode class. Multiple copies of a
+ * ReturnCode will all point to the same ReturnCodeDataRef. The ReturnCodes
+ * maintain the reference count, the last ReturnCode to remove its reference
+ * will delete the ReturnCodeDataRef which in turn deletes the ReturnCodeData.
+ * The ReturnCodeData pointer is maintained in this class so that releasing the
+ * data releases it from all ReturnCode copies.
+ *
+ * A ReturnCodeDataRef object is not thread safe, multiple threads must not use
+ * the same ReturnCodeDataRef object concurrently.
+ */
+class ReturnCodeDataRef
+{
+public:
+
+ /**
+ * @brief Constructor
+ *
+ * @param[in] i_pData Pointer to platform specific ReturnCodeData
+ */
+ explicit ReturnCodeDataRef(const void * i_pData);
+
+ /**
+ * @brief Destructor
+ */
+ ~ReturnCodeDataRef();
+
+ /**
+ * @brief Increments the ref count
+ */
+ void incRefCount();
+
+ /**
+ * @brief Decrements the ref count
+ *
+ * @return bool True if zero reached
+ */
+ bool decRefCountCheckZero();
+
+ /**
+ * @brief Get a pointer to ReturnCodeData. ReturnCodeDataRef is still
+ * responsible for deletion of the data. The caller must not delete
+ *
+ * The pointer is only meaningful to platform code.
+ *
+ * @return void *. Pointer to ReturnCodeData. If NULL then no data (must
+ * have been released)
+ */
+ const void * getData() const;
+
+ /**
+ * @brief Get a pointer to any ReturnCodeData and release ownership from
+ * ReturnCodeDataRef. The caller is responsible for deletion.
+ *
+ * The pointer is only meaningful to platform code.
+ *
+ * @return void *. Pointer to ReturnCodeData. If NULL then no data (must
+ * have been released)
+ */
+ const void * releaseData();
+
+private:
+
+ // Copy constructor and assignment operator disabled
+ ReturnCodeDataRef(const ReturnCodeDataRef & i_right);
+ ReturnCodeDataRef & operator=(const ReturnCodeDataRef & i_right);
+
+ /**
+ * @brief Deletes the ReturnCodeData
+ *
+ * @note Implemented by platform code because only platform code knows the
+ * type of the data and how to delete it.
+ */
+ void deleteData();
+
+ // The reference count (how many ReturnCodes are pointing to this object)
+ uint32_t iv_refCount;
+
+ // Pointer to platform specific ReturnCodeData
+ const void * iv_pData;
+};
+
+}
+
+#endif // FAPIRETURNCODEDATAREF_H_
diff --git a/src/include/usr/hwpf/fapi/fapiReturnCodes.H b/src/include/usr/hwpf/fapi/fapiReturnCodes.H
new file mode 100644
index 000000000..4d3cc7db2
--- /dev/null
+++ b/src/include/usr/hwpf/fapi/fapiReturnCodes.H
@@ -0,0 +1,39 @@
+/**
+ * @file fapiReturnCodes.H
+ *
+ * @brief Defines the returns codes generated by HWPF code.
+ */
+
+#ifndef FAPIRETURNCODES_H_
+#define FAPIRETURNCODES_H_
+
+#include <ecmdDataBuffer.H>
+
+namespace fapi
+{
+
+/**
+ * @brief Enumeration of return codes
+ */
+enum
+{
+ FAPI_RC_SUCCESS = 0,
+
+ // Flag bits indicating which code generated the error If no flag set then
+ // it is generated by HWP
+ FAPI_RC_FAPI_MASK = 0x04000000, // FAPI generated error
+ FAPI_RC_PLAT_MASK = 0x02000000, // PLAT generated error
+ FAPI_RC_ECMD_MASK = ECMD_ERR_ECMD, // ECMD generated error (0x01000000)
+
+ // FAPI generated return codes
+ FAPI_RC_NOT_IMPLEMENTED = FAPI_RC_FAPI_MASK | 0x01,
+
+ // PLAT generated return codes
+ FAPI_RC_PLAT_ERR_SEE_DATA = FAPI_RC_PLAT_MASK | 0x01,
+ // Error details in attached ReturnCodeData
+ FAPI_RC_PLAT_NOT_IMPLEMENTED = FAPI_RC_PLAT_MASK | 0x02,
+};
+
+}
+
+#endif // FAPIRETURNCODES_H_
diff --git a/src/include/usr/hwpf/fapi/fapiSystemConfig.H b/src/include/usr/hwpf/fapi/fapiSystemConfig.H
new file mode 100644
index 000000000..29eca2cc4
--- /dev/null
+++ b/src/include/usr/hwpf/fapi/fapiSystemConfig.H
@@ -0,0 +1,73 @@
+/**
+ * @file fapiSystemConfig.H
+ *
+ * @brief Defines the System Config query functions that platform code must
+ * implement. It is an eCMD requirement that these be "C" functions.
+ */
+
+#ifndef FAPISYSTEMCONFIG_H_
+#define FAPISYSTEMCONFIG_H_
+
+#include <stdint.h>
+#include <vector>
+#include <fapiReturnCode.H>
+#include <fapiTarget.H>
+
+extern "C"
+{
+
+/**
+ * @brief Gets the functional chiplets that are children of the supplied target
+ *
+ * @param[in] i_target Parent target
+ * @param[in] i_targetType Type of chiplet required
+ * @param[out] o_chiplets Reference to vector that is filled in with the
+ * result chiplets
+ *
+ * @return ReturnCode. Zero on success, else error
+ */
+fapi::ReturnCode GetFunctionalChiplets(const fapi::Target& i_target,
+ const fapi::TargetType i_chipletType,
+ std::vector<fapi::Target> & o_chiplets);
+
+/**
+ * @brief Gets the existing chiplets that are children of the supplied target
+ *
+ * @param[in] i_target Parent target
+ * @param[in] i_targetType Type of chiplet required
+ * @param[out] o_chiplets Reference to vector that is filled in with the
+ * result chiplets
+ *
+ * @return ReturnCode. Zero on success, else error
+ */
+fapi::ReturnCode GetExistingChiplets(const fapi::Target& i_target,
+ const fapi::TargetType i_chipletType,
+ std::vector<fapi::Target> & o_chiplets);
+
+/**
+ * @brief Gets the functional DIMMs that are children of the supplied target
+ *
+ * @param[in] i_target Parent target
+ * @param[out] o_dimms Reference to vector that is filled in with the result
+ * DIMMs
+ *
+ * @return ReturnCode. Zero on success, else error
+ */
+fapi::ReturnCode GetFunctionalDimms(const fapi::Target& i_target,
+ std::vector<fapi::Target> & o_dimms);
+
+/**
+ * @brief Gets the existing DIMMs that are children of the supplied target
+ *
+ * @param[in] i_target Parent target
+ * @param[out] o_dimms Reference to vector that is filled in with the result
+ * DIMMs
+ *
+ * @return ReturnCode. Zero on success, else error
+ */
+fapi::ReturnCode GetExistingDimms(const fapi::Target& i_target,
+ std::vector<fapi::Target> & o_dimms);
+
+} // extern "C"
+
+#endif // FAPISYSTEMCONFIG_H_
diff --git a/src/include/usr/hwpf/fapi/fapiTarget.H b/src/include/usr/hwpf/fapi/fapiTarget.H
new file mode 100644
index 000000000..af22137b9
--- /dev/null
+++ b/src/include/usr/hwpf/fapi/fapiTarget.H
@@ -0,0 +1,195 @@
+/**
+ * @file fapiTarget.H
+ *
+ * @brief Defines the Target class that is a generic target of a Hardware
+ * Procedure operation.
+ */
+
+#ifndef FAPITARGET_H_
+#define FAPITARGET_H_
+
+#include <stdint.h>
+#include <stddef.h>
+
+namespace fapi
+{
+
+/**
+ * @brief Enumeration of target types values (bitmask values)
+ */
+enum TargetType
+{
+ TARGET_TYPE_NONE = 0x00000000,
+ TARGET_TYPE_SYSTEM = 0x00000001,
+ TARGET_TYPE_DIMM = 0x00000002,
+ TARGET_TYPE_PROC_CHIP = 0x00000004,
+ TARGET_TYPE_MEMBUF_CHIP = 0x00000008,
+ TARGET_TYPE_EX_CHIPLET = 0x00000010,
+ TARGET_TYPE_MBA_CHIPLET = 0x00000020,
+ TARGET_TYPE_MBS_CHIPLET = 0x80000040,
+ TARGET_TYPE_MCS_CHIPLET = 0x80000080,
+};
+
+/**
+ * @brief Typedef used when passing multiple TargetType values
+ */
+typedef uint32_t TargetTypes_t;
+
+/**
+ * @class Target
+ *
+ * This class provides a generic Target of a Hardware Procedure Operation.
+ *
+ * A Target contains a void * pointer to a handle which is only meaningful to
+ * platform code.
+ *
+ * A Target object is copyable and assignable. Therefore, it cannot be
+ * subclassed.
+ *
+ * A Target object is not thread safe, multiple threads must not use the same
+ * Target object concurrently.
+ */
+class Target
+{
+public:
+
+ /**
+ * @brief Default constructor
+ */
+ Target();
+
+ /**
+ * @brief Constructor
+ *
+ * @param[in] i_type Target type
+ * @param[in] i_pHandle Pointer to platform specific Target handle
+ */
+ Target(const TargetType i_type,
+ const void * i_pHandle);
+
+ /**
+ * @brief Copy Constructor
+ *
+ * @param[in] i_right Reference to Target to copy
+ */
+ Target(const Target & i_right);
+
+ /**
+ * @brief Destructor
+ */
+ ~Target();
+
+ /**
+ * @brief Assignment Operator.
+ *
+ * @param[in] i_right Reference to Target to assign from.
+ *
+ * @return Reference to 'this' Target
+ */
+ Target & operator=(const Target & i_right);
+
+ /**
+ * @brief Equality Comparison Operator
+ *
+ * @param[in] i_right Reference to Target to compare.
+ *
+ * @return bool. True if equal.
+ */
+ bool operator==(const Target & i_right) const;
+
+ /**
+ * @brief Inequality Comparison Operator
+ *
+ * @param[in] i_right Reference to Target to compare.
+ *
+ * @return bool. True if not equal.
+ */
+ bool operator!=(const Target & i_right) const;
+
+ /**
+ * @brief Get the handle pointer.
+ *
+ * The handle is only meaningful to platform code.
+ *
+ * @return Handle_t. The handle.
+ */
+ void * get() const;
+
+ /**
+ * @brief Set the handle. Platform using Handle_t as handle
+ *
+ * The handle is only meaningful to platform code.
+ *
+ * @param[in] i_pHandle Pointer to platform specific handle
+ */
+ void set(const void * i_pHandle);
+
+ /**
+ * @brief Get the target type
+ *
+ * @return The type of target represented by this target
+ */
+ TargetType getType() const;
+
+ /**
+ * @brief Set the target type
+ *
+ * @param[in] i_type The type of target represented by this target
+ */
+ void setType(const TargetType i_type);
+
+ /**
+ * @brief Convert a target to an ecmd-format target string
+ *
+ * @note Implemented by platform code
+ *
+ * @return A pointer to a c-string. If the object cannot be converted to a
+ * valid ecmd string, a NULL pointer is returned.
+ *
+ * IMPORTANT: It is the caller's responsibility to free the returned string
+ * when done with it by calling "free(char*)".
+ */
+ const char * toString() const;
+
+private:
+
+ /**
+ * @brief Compare the handle
+ *
+ * @note Implemented by platform code because only platform code knows the
+ * type pointed to by iv_pHandle to compare
+ *
+ * @param[in] i_right Reference to Target to compare handle to
+ *
+ * @return bool. True if the same
+ */
+ bool compareHandle(const Target & i_right) const;
+
+ /**
+ * @brief Copy the handle
+ *
+ * @note Implemented by platform code because only platform code knows the
+ * type pointed to by iv_pHandle to copy
+ *
+ * @param[in] i_right Reference to Target to copy handle from
+ */
+ void copyHandle(const Target & i_right);
+
+ /**
+ * @brief Delete the handle
+ *
+ * @note Implemented by platform code because only platform code knows the
+ * type to delete and if it should actually be deleted
+ */
+ void deleteHandle();
+
+ // Type of target
+ TargetType iv_type;
+
+ // Pointer to platform specific Target Handle
+ const void * iv_pHandle;
+};
+
+}
+
+#endif // FAPITARGET_H_
diff --git a/src/include/usr/hwpf/fapi/fapiUtil.H b/src/include/usr/hwpf/fapi/fapiUtil.H
new file mode 100644
index 000000000..291410454
--- /dev/null
+++ b/src/include/usr/hwpf/fapi/fapiUtil.H
@@ -0,0 +1,28 @@
+/**
+ * @file fapiUtil.H
+ *
+ * @brief Defines utility functions that the platform code must implement.
+ */
+
+#ifndef FAPIUTIL_H_
+#define FAPIUTIL_H_
+
+#include <stdint.h>
+#include <stddef.h>
+#include <fapi.H>
+
+
+namespace fapi
+{
+/**
+ * @brief Assert that an expression is true. Aborting the process if false.
+ *
+ * @note Implemented by platform code
+ *
+ * @param[in] i_expression If not true then process should be aborted
+ */
+void fapiAssert(bool i_expression);
+
+}
+
+#endif // FAPIUTIL_H_
diff --git a/src/include/usr/hwpf/hwp/fapiTestHwp.H b/src/include/usr/hwpf/hwp/fapiTestHwp.H
new file mode 100644
index 000000000..db619737f
--- /dev/null
+++ b/src/include/usr/hwpf/hwp/fapiTestHwp.H
@@ -0,0 +1,31 @@
+/**
+ * @file fapiTestHwp.H
+ *
+ * @brief Defines test Hardware Procedures that are intended to test out the
+ * Hardware Procedure Framework
+ */
+
+#ifndef FAPITESTHWPROC_H_
+#define FAPITESTHWPROC_H_
+
+#include <fapi.H>
+
+// HWPs are defined as C functions because platforms may wish to package them
+// in linux shared libraries which are DL-Opened
+extern "C"
+{
+
+/**
+ * @brief Finds if a P7 EM0 chiplet clock is on
+ *
+ * @param[in] i_chip Target chip
+ * @param[out] o_clocksOn True if clocks are on, else false
+ *
+ * @return ReturnCode
+ */
+fapi::ReturnCode hwpIsP7EM0ChipletClockOn(const fapi::Target & i_chip,
+ bool & o_clocksOn);
+
+} // extern "C"
+
+#endif // FAPITESTHWPROC_H_
diff --git a/src/include/usr/hwpf/plat/fapiPlatHwpExecutor.H b/src/include/usr/hwpf/plat/fapiPlatHwpExecutor.H
new file mode 100644
index 000000000..c2b7e5e10
--- /dev/null
+++ b/src/include/usr/hwpf/plat/fapiPlatHwpExecutor.H
@@ -0,0 +1,22 @@
+/**
+ * @file fapiPlatHwpExecutor.H
+ *
+ * @brief Defines the FAPI HWP Executor Macro.
+ *
+ * The HWP Executor macro is called when a PLAT invoker function or a HWP wants
+ * to execute a HWP. Each platform can modify the macro to do any platform
+ * specific work to execute the HWP (e.g. dlopening a shared library)
+ */
+
+#ifndef FAPIPLATHWPEXECUTOR_H_
+#define FAPIPLATHWPEXECUTOR_H_
+
+/**
+ * @brief HWP Executor macro
+ *
+ * By default, this macro just calls the HWP directly. If this cannot be done
+ * then the platform needs to modify
+ */
+#define FAPI_EXEC_HWP(RC, FUNC, _args_...) RC = FUNC(_args_)
+
+#endif // FAPIPLATHWPEXECUTOR_H_
diff --git a/src/include/usr/hwpf/plat/fapiPlatHwpInvoker.H b/src/include/usr/hwpf/plat/fapiPlatHwpInvoker.H
new file mode 100644
index 000000000..232cb981c
--- /dev/null
+++ b/src/include/usr/hwpf/plat/fapiPlatHwpInvoker.H
@@ -0,0 +1,32 @@
+/**
+ * @file fapiPlatHwpInvoker.H
+ *
+ * @brief Defines the platform specific HW Procedure invoker functions.
+ *
+ * Note that each platform needs to provide an invoker function for each HW
+ * procedure. Prototypes cannot be provided because each platform will have
+ * functions that take platform specific targets and return platform specific
+ * return codes.
+ */
+
+#ifndef FAPIPLATHWPINVOKER_H_
+#define FAPIPLATHWPINVOKER_H_
+
+#include <targeting/targetservice.H>
+#include <errl/errlentry.H>
+
+namespace fapi
+{
+
+/**
+ * @brief Invokes hwpIsP7EM0ChipletClockOn procedure
+ *
+ * @param[in] i_target Pointer to Chip
+ * @param[out] o_clocksOn True if EM0 clocks are on, else false
+ */
+errlHndl_t invokeHwpIsP7EM0ChipletClockOn(TARGETING::Target* i_target,
+ bool & o_clocksOn);
+
+}
+
+#endif // FAPIPLATHWPINVOKER_H_
diff --git a/src/include/usr/hwpf/plat/fapiPlatTrace.H b/src/include/usr/hwpf/plat/fapiPlatTrace.H
new file mode 100644
index 000000000..e02bd481a
--- /dev/null
+++ b/src/include/usr/hwpf/plat/fapiPlatTrace.H
@@ -0,0 +1,46 @@
+/**
+ * @file platTrace.H
+ *
+ * @brief Defines the FAPI trace macros.
+ *
+ * Note that platform code must provide the implementation.
+ *
+ * FAPI has provided a default implementation of printfs. Platform code must
+ * provide an alternate implementation if needed.
+ */
+
+#ifndef PLATTRACE_H_
+#define PLATTRACE_H_
+
+#include <stdio.h>
+#include <trace/interface.H>
+
+//******************************************************************************
+// Trace buffer names
+//******************************************************************************
+const char * const FAPI_INF_TRACE_NAME = "FAPI_T";
+const char * const FAPI_IMP_TRACE_NAME = "FAPI_I";
+const char * const FAPI_ERR_TRACE_NAME = "FAPI_E";
+const char * const FAPI_DBG_TRACE_NAME = "FAPI_D";
+
+//******************************************************************************
+// Trace descriptors that are defined in a C file
+//******************************************************************************
+extern trace_desc_t* g_fapiInfTd;
+extern trace_desc_t* g_fapiImpTd;
+extern trace_desc_t* g_fapiErrTd;
+extern trace_desc_t* g_fapiDbgTd;
+
+// Information traces (standard flight recorder that can wrap often)
+#define FAPI_INF(_fmt_, _args_...) TRACFCOMP(g_fapiInfTd, _fmt_, ##_args_ )
+
+// Important traces (should not wrap often)
+#define FAPI_IMP(_fmt_, _args_...) TRACFCOMP(g_fapiImpTd, _fmt_, ##_args_ )
+
+// Error traces (should not wrap often)
+#define FAPI_ERR(_fmt_, _args_...) TRACFCOMP(g_fapiErrTd, _fmt_, ##_args_ )
+
+// Debug traces (can wrap often)
+#define FAPI_DBG(_fmt_, _args_...) TRACDCOMP(g_fapiDbgTd, _fmt_, ##_args_)
+
+#endif // PLATTRACE_H_
diff --git a/src/makefile b/src/makefile
index b5c6947fb..656aedb80 100644
--- a/src/makefile
+++ b/src/makefile
@@ -16,11 +16,13 @@ DIRECT_BOOT_OBJECTS = start.o kernel.o taskmgr.o cpumgr.o syscall.o \
RUNTIME_OBJECTS =
BASE_MODULES = trace errl devicefw scom xscom initservice
-EXTENDED_MODULES = targeting
+EXTENDED_MODULES = targeting ecmddatabuffer hwpf fapi hwp initservice plat
+
DIRECT_BOOT_MODULES = example
RUNTIME_MODULES =
TESTCASE_MODULES = cxxtest testerrl testdevicefw testsyslib \
- testscom testxscom testtargeting testinitservice testkernel
+ testscom testxscom testtargeting testinitservice testkernel \
+ testhwpf testecmddatabuffer
RELOCATABLE_IMAGE_LDFLAGS = -pie --export-dynamic
diff --git a/src/usr/ecmddatabuffer/ecmdDataBuffer.C b/src/usr/ecmddatabuffer/ecmdDataBuffer.C
new file mode 100755
index 000000000..b28a1d3e0
--- /dev/null
+++ b/src/usr/ecmddatabuffer/ecmdDataBuffer.C
@@ -0,0 +1,215 @@
+/**
+ * @file ecmdDataBuffer.C
+ * @brief Provides a means to handle data from the eCMD C API
+ *
+ ********************************************************************
+ * @todo - This is only a temporary file created to compile code.
+ * We will use John Farrugia's version
+ *********************************************************************
+ */
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <stdint.h>
+#include <string.h>
+#include <trace/interface.H>
+#include <ecmdDataBuffer.H>
+
+#define EDB_ADMIN_TOTAL_SIZE 2
+#define EDB_ADMIN_HEADER_SIZE 1
+#define EDB_ADMIN_FOOTER_SIZE 1
+#define EDB_ADMIN_TOTAL_SIZE 2
+#define EDB_RETURN_CODE 0
+#define EDB_RANDNUM 0x12345678
+#define ECMD_DBUF_BUFFER_OVERFLOW (ECMD_ERR_ECMD | 0x2011)
+
+// Trace definition
+trace_desc_t* g_trac_ecmd = NULL;
+TRAC_INIT(&g_trac_ecmd, "ECMD", 4096);
+
+//---------------------------------------------------------------------
+// Constructors
+//---------------------------------------------------------------------
+ecmdDataBufferBase::ecmdDataBufferBase() // Default constructor
+: iv_Capacity(0), iv_NumBits(0), iv_Data(NULL), iv_RealData(NULL)
+{
+ iv_UserOwned = true;
+}
+
+ecmdDataBufferBase::ecmdDataBufferBase(uint32_t i_numBits)
+: iv_Capacity(0), iv_NumBits(0), iv_Data(NULL), iv_RealData(NULL)
+{
+ iv_UserOwned = true;
+ if (i_numBits > 0)
+ {
+ setBitLength(i_numBits);
+ }
+}
+
+//---------------------------------------------------------------------
+// Destructor
+//---------------------------------------------------------------------
+ecmdDataBufferBase::~ecmdDataBufferBase()
+{
+ // Only call clear() if buffer is owned by this user (ie, not shared)
+ if (iv_UserOwned)
+ {
+ clear();
+ }
+}
+
+uint32_t ecmdDataBufferBase::getWordLength() const
+{
+ return (iv_NumBits + 31) / 32;
+}
+
+uint32_t ecmdDataBufferBase::flushTo0()
+{
+ uint32_t rc = ECMD_DBUF_SUCCESS;
+ if (getWordLength() > 0)
+ {
+ memset(iv_Data, 0x00, getWordLength() * 4); /* init to 0 */
+ }
+ return rc;
+}
+
+
+uint32_t ecmdDataBufferBase::clear() {
+ uint32_t rc = ECMD_DBUF_SUCCESS;
+
+ if (iv_RealData != NULL)
+ {
+ /* That looked okay, reset everything else */
+ /* Only do the delete if we alloc'd something */
+ if (iv_RealData != iv_LocalData)
+ {
+ delete[] iv_RealData;
+ }
+ iv_RealData = NULL;
+ iv_Capacity = 0;
+ iv_NumBits = 0;
+ }
+ return rc;
+}
+
+uint32_t ecmdDataBufferBase::setCapacity(uint32_t i_newCapacity) {
+ uint32_t rc = ECMD_DBUF_SUCCESS;
+
+ if(!iv_UserOwned) {
+ TRACFCOMP(g_trac_ecmd, "**** ERROR (ecmdDataBuffer) : Attempt to modify non user owned buffer size.");
+ return 0;
+ }
+
+ /* for case where i_newCapacity is 0 (like in unflatten) use iv_LocalData for iv_RealData */
+ /* This allows for iv_Data, the header, and the tail to be setup right */
+ if (iv_Capacity == 0) {
+ /* We are using iv_LocalData, so point iv_RealData to the start of that */
+ iv_RealData = iv_LocalData;
+ }
+
+ /* only resize to make the capacity bigger */
+ if (iv_Capacity < i_newCapacity) {
+ iv_Capacity = i_newCapacity;
+
+ /* Now setup iv_RealData */
+ if (iv_Capacity <= 2) {
+ /* We are using iv_LocalData, so point iv_RealData to the start of that */
+ iv_RealData = iv_LocalData;
+ } else {
+ /* If we are going from <= 64 to > 64, there was no malloc done so can't do delete */
+ if ((iv_RealData != NULL) && (iv_RealData != iv_LocalData)) {
+ delete[] iv_RealData;
+ }
+ iv_RealData = NULL;
+
+ iv_RealData = new uint32_t[iv_Capacity + EDB_ADMIN_TOTAL_SIZE];
+ if (iv_RealData == NULL) {
+ TRACFCOMP(g_trac_ecmd, "**** ERROR : ecmdDataBuffer::setCapacity : Unable to allocate memory for new databuffer");
+ return 0;
+ }
+ }
+ }
+
+ /* Now setup iv_Data to point into the offset inside of iv_RealData */
+ iv_Data = iv_RealData + EDB_ADMIN_HEADER_SIZE;
+
+ /* We are all setup, now init everything to 0 */
+ /* We want to do this regardless of if the buffer was resized. */
+ /* This function is meant to be a destructive operation */
+ /* Ok, now setup the header, and tail */
+ iv_RealData[EDB_RETURN_CODE] = 0; ///< Reset error code
+ iv_RealData[getWordLength() + EDB_ADMIN_HEADER_SIZE] = EDB_RANDNUM;
+
+ rc = flushTo0();
+ if (rc) return rc;
+
+ return rc;
+}
+
+uint32_t ecmdDataBufferBase::setBitLength(uint32_t i_newNumBits) {
+ uint32_t rc = ECMD_DBUF_SUCCESS;
+
+ if ((i_newNumBits == 0) && (iv_NumBits == 0)) {
+ // Do Nothing: this data doesn't already have iv_RealData,iv_Data defined, and it doesn't want to define it
+ return rc;
+ }
+
+ /* Assign i_newNumBits to iv_NumBits and figure out how many words that is */
+ iv_NumBits = i_newNumBits;
+
+ /* Now call setCapacity to do all the data buffer resizing and setup */
+ rc = setCapacity(getWordLength());
+ if (rc) return rc;
+
+ return rc;
+}
+
+uint32_t ecmdDataBufferBase::setDoubleWord(uint32_t i_doublewordoffset, uint64_t i_value)
+{
+ uint32_t rc = ECMD_DBUF_SUCCESS;
+ if (i_doublewordoffset >= ((getWordLength()+1)/2))
+ {
+ TRACFCOMP(g_trac_ecmd, "**** ERROR : ecmdDataBuffer::setDoubleWord: doubleWordOffset %d >= NumDoubleWords (%d)",
+ i_doublewordoffset, ((getWordLength()+1)/2));
+ return (ECMD_DBUF_BUFFER_OVERFLOW);
+ }
+
+ // Create mask if part of this byte is not in the valid part of the ecmdDataBuffer
+ if (((i_doublewordoffset + 1) == ((getWordLength()+1)/2)) && (iv_NumBits % 64))
+ {
+ uint64_t bitMask = 0xFFFFFFFFFFFFFFFFul;
+ /* Shift it left by the amount of unused bits */
+ bitMask <<= ((64 * ((getWordLength()+1)/2)) - iv_NumBits);
+ /* Clear the unused bits */
+ i_value &= bitMask;
+ }
+ uint32_t hivalue = (uint32_t)((i_value & 0xFFFFFFFF00000000ul) >> 32);
+ uint32_t lovalue = (uint32_t)((i_value & 0x00000000FFFFFFFFul));
+
+ iv_Data[i_doublewordoffset*2] = hivalue;
+ /* Don't set the second word if we are on oddwords */
+ if (!((i_doublewordoffset*2)+1 >= getWordLength()) ) {
+ iv_Data[(i_doublewordoffset*2)+1] = lovalue;
+ }
+ return rc;
+}
+
+uint64_t ecmdDataBufferBase::getDoubleWord(uint32_t i_doublewordoffset) const
+{
+ // Round up to the next word and check length
+ if (i_doublewordoffset >= ((getWordLength()+1)/2))
+ {
+ TRACFCOMP(g_trac_ecmd, "**** ERROR : ecmdDataBuffer::getDoubleWord: doubleWordOffset %d >= NumDoubleWords (%d)",
+ i_doublewordoffset, ((getWordLength()+1)/2));
+ return 0;
+ }
+ uint64_t ret;
+ ret = ((uint64_t)(iv_Data[i_doublewordoffset*2])) << 32;
+ // If we have an odd length of words we can't pull the second word if we are at the end
+ if (!((i_doublewordoffset*2)+1 >= getWordLength()) ) {
+ ret |= iv_Data[(i_doublewordoffset*2)+1];
+ }
+ return ret;
+}
+
diff --git a/src/usr/ecmddatabuffer/makefile b/src/usr/ecmddatabuffer/makefile
new file mode 100644
index 000000000..1f0938ae0
--- /dev/null
+++ b/src/usr/ecmddatabuffer/makefile
@@ -0,0 +1,10 @@
+ROOTPATH = ../../..
+MODULE = ecmddatabuffer
+
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer
+
+OBJS = ecmdDataBuffer.o
+
+SUBDIRS = test.d
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/ecmddatabuffer/test/ecmddatabuffertest.H b/src/usr/ecmddatabuffer/test/ecmddatabuffertest.H
new file mode 100644
index 000000000..e3bec53c8
--- /dev/null
+++ b/src/usr/ecmddatabuffer/test/ecmddatabuffertest.H
@@ -0,0 +1,26 @@
+#ifndef __ECMDDATABUFFERTEST_H
+#define __ECMDDATABUFFERTEST_H
+
+/**
+ * @file ecmddatabuffertest.H
+ *
+ * @brief Test case for ECMD data buffer
+*/
+
+#include <cxxtest/TestSuite.H>
+
+class EcmddatabufferTest: public CxxTest::TestSuite
+{
+public:
+
+
+ /**
+ * @brief Test #1
+ */
+ void testEcmddatabuffer1(void)
+ {
+ }
+
+};
+
+#endif
diff --git a/src/usr/ecmddatabuffer/test/makefile b/src/usr/ecmddatabuffer/test/makefile
new file mode 100644
index 000000000..05e3c3032
--- /dev/null
+++ b/src/usr/ecmddatabuffer/test/makefile
@@ -0,0 +1,6 @@
+ROOTPATH = ../../../..
+
+MODULE = testecmddatabuffer
+TESTS = *.H
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/hwpf/fapi/fapiAttributeService.C b/src/usr/hwpf/fapi/fapiAttributeService.C
new file mode 100644
index 000000000..c48557398
--- /dev/null
+++ b/src/usr/hwpf/fapi/fapiAttributeService.C
@@ -0,0 +1,187 @@
+/**
+ * @file fapiAttributeService.C
+ *
+ * @brief Implements the AttributeService functions.
+ */
+
+#include <stdio.h>
+#include <fapiAttributeService.H>
+#include <fapiPlatTrace.H>
+
+namespace fapi
+{
+
+namespace AttributeService
+{
+
+//******************************************************************************
+// Get string
+//******************************************************************************
+template<>
+ReturnCode _get<char *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ char * & o_value)
+{
+ FAPI_ERR("Get string attribute not implemented");
+ return FAPI_RC_NOT_IMPLEMENTED;
+}
+
+//******************************************************************************
+// Get uint8_t
+//******************************************************************************
+template<>
+ReturnCode _get<uint8_t> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint8_t & o_value)
+{
+ FAPI_ERR("Get uint8 attribute not implemented");
+ return FAPI_RC_NOT_IMPLEMENTED;
+}
+
+//******************************************************************************
+// Get uint32_t
+//******************************************************************************
+template<>
+ReturnCode _get<uint32_t> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint32_t & o_value)
+{
+ FAPI_ERR("Get uint32 attribute not implemented");
+ return FAPI_RC_NOT_IMPLEMENTED;
+}
+
+//******************************************************************************
+// Get uint64_t
+//******************************************************************************
+template<>
+ReturnCode _get<uint64_t> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint64_t & o_value)
+{
+ FAPI_ERR("Get uint64 attribute not implemented");
+ return FAPI_RC_NOT_IMPLEMENTED;
+}
+
+//******************************************************************************
+// Get uint8_t array
+//******************************************************************************
+template<>
+ReturnCode _get<uint8_t *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint8_t * const o_pValues)
+{
+ FAPI_ERR("Get uint8 array attribute not implemented");
+ return FAPI_RC_NOT_IMPLEMENTED;
+}
+
+//******************************************************************************
+// Get uint32_t array
+//******************************************************************************
+template<>
+ReturnCode _get<uint32_t *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint32_t * const o_pValues)
+{
+ FAPI_ERR("Get uint32 array attribute not implemented");
+ return FAPI_RC_NOT_IMPLEMENTED;
+}
+
+//******************************************************************************
+// Get uint64_t array
+//******************************************************************************
+template<>
+ReturnCode _get<uint64_t *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ uint64_t * const o_pValues)
+{
+ FAPI_ERR("Get uint64 array attribute not implemented");
+ return FAPI_RC_NOT_IMPLEMENTED;
+}
+
+//******************************************************************************
+// Set string
+//******************************************************************************
+template<>
+ReturnCode _set<char *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ const char * const i_pValue)
+{
+ FAPI_ERR("Set string attribute not implemented");
+ return FAPI_RC_NOT_IMPLEMENTED;
+}
+
+//******************************************************************************
+// Set uint8_t
+//******************************************************************************
+template<>
+ReturnCode _set<uint8_t> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint8_t i_value)
+{
+ FAPI_ERR("Set uint8 attribute not implemented");
+ return FAPI_RC_NOT_IMPLEMENTED;
+}
+
+//******************************************************************************
+// Set uint32_t
+//******************************************************************************
+template<>
+ReturnCode _set<uint32_t> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint32_t i_value)
+{
+ FAPI_ERR("Set uint32 attribute not implemented");
+ return FAPI_RC_NOT_IMPLEMENTED;
+}
+
+//******************************************************************************
+// Set uint64_t
+//******************************************************************************
+template<>
+ReturnCode _set<uint64_t> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint64_t i_value)
+{
+ FAPI_ERR("Set uint64 attribute not implemented");
+ return FAPI_RC_NOT_IMPLEMENTED;
+}
+
+//******************************************************************************
+// Set uint8_t array
+//******************************************************************************
+template<>
+ReturnCode _set<uint8_t *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint8_t * const i_pValues)
+{
+ FAPI_ERR("Set uint8 array attribute not implemented");
+ return FAPI_RC_NOT_IMPLEMENTED;
+}
+
+//******************************************************************************
+// Set uint32_t array
+//******************************************************************************
+template<>
+ReturnCode _set<uint32_t *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint32_t * const i_pValues)
+{
+ FAPI_ERR("Set uint32 array attribute not implemented");
+ return FAPI_RC_NOT_IMPLEMENTED;
+}
+
+//******************************************************************************
+// Set uint64_t array
+//******************************************************************************
+template<>
+ReturnCode _set<uint64_t *> (const AttributeId i_id,
+ const Target * const i_pTarget,
+ const uint64_t * const i_pValues)
+{
+ FAPI_ERR("Set uint64 array attribute not implemented");
+ return FAPI_RC_NOT_IMPLEMENTED;
+}
+
+} // namespace AttributeService
+
+} // namespace fapi
diff --git a/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl b/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl
new file mode 100755
index 000000000..8151b0ef6
--- /dev/null
+++ b/src/usr/hwpf/fapi/fapiParseAttributeInfo.pl
@@ -0,0 +1,144 @@
+#!/usr/bin/perl
+
+#
+# Usage:
+# fapiParseAttributeInfo.pl <filename1> <filename2> .... <filenameN>
+
+use strict;
+
+my $numArgs = $#ARGV + 1;
+#print $numArgs, "\n";
+
+if ($numArgs < 1)
+{
+ print ("Usage: fapiParseAttributeInfo.pl <filename1> <filename2> .... <filenameN>\n");
+ print (" This perl script will parse attribute XML files,\n");
+ print (" pull out the attribute IDs/types and create a header file\n");
+ print (" fapiAttributeIds.H containing the information.\n");
+ exit(1);
+}
+
+
+
+# use module
+use XML::Simple;
+#use Data::Dumper;
+
+#open output file for writing
+open(OUTFILE, ">fapiAttributeIds.H");
+print OUTFILE "// fapiAttributeIds.H\n";
+print OUTFILE "// This file is generated by perl script fapiParseAttributeInfo.pl\n\n";
+print OUTFILE "#ifndef FAPIATTRIBUTEIDS_H_\n";
+print OUTFILE "#define FAPIATTRIBUTEIDS_H_\n\n";
+print OUTFILE "namespace fapi\n";
+print OUTFILE "{\n\n";
+print OUTFILE "\/**\n";
+print OUTFILE " * \@brief Enumeration of attribute IDs\n";
+print OUTFILE " *\/\n";
+print OUTFILE "enum AttributeId\n";
+print OUTFILE "{\n";
+
+# create object
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+#for each Hwp Attribute XML file
+my $infile;
+foreach $infile(@ARGV)
+{
+ #print filename
+ #print $ifile, "\n\n";
+
+ # read XML file
+ my $attributes = $xml->XMLin($infile);
+
+ # print output
+ #print Dumper($attributes);
+ #print "\n";
+
+ # print attribute id to file
+ my $attr;
+ foreach $attr (@{$attributes->{attribute}})
+ {
+ if ($attr->{id})
+ {
+ print OUTFILE " ", $attr->{id}, ",\n";
+ }
+ else
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. Attribute ID missing\n");
+ exit(1);
+ }
+ };
+}
+
+print OUTFILE "};\n\n";
+
+print OUTFILE "\/**\n";
+print OUTFILE " * \@brief Typedefs for the attribute value types\n";
+print OUTFILE " *\/\n";
+
+#for each Hwp Attribute XML file
+foreach $infile(@ARGV)
+{
+ # read XML file
+ my $attributes = $xml->XMLin($infile);
+
+ # print attribute id to file
+ my $attr;
+ foreach $attr (@{$attributes->{attribute}})
+ {
+ print OUTFILE "typedef ";
+
+ if ($attr->{valueType} eq 'uint8')
+ {
+ if ($attr->{array})
+ {
+ print OUTFILE "uint8_t * ";
+ }
+ else
+ {
+ print OUTFILE "uint8_t ";
+ }
+ }
+ elsif ($attr->{valueType} eq 'uint32')
+ {
+ if ($attr->{array})
+ {
+ print OUTFILE "uint32_t * ";
+ }
+ else
+ {
+ print OUTFILE "uint32_t ";
+ }
+ }
+ elsif ($attr->{valueType} eq 'uint64')
+ {
+ if ($attr->{array})
+ {
+ print OUTFILE "uint64_t * ";
+ }
+ else
+ {
+ print OUTFILE "uint64_t ";
+ }
+ }
+ elsif ($attr->{valueType} eq 'string')
+ {
+ print OUTFILE "char * ";
+ }
+ else
+ {
+ print ("fapiParseAttributeInfo.pl ERROR. valueType not recognized: ");
+ print $attr->{valueType}, "\n";
+ exit(1);
+ }
+
+ print OUTFILE $attr->{id}, "_Type;\n";
+ };
+}
+
+print OUTFILE "\n}\n\n";
+print OUTFILE "#endif\n";
+
+#close output file
+close(OUTFILE);
diff --git a/src/usr/hwpf/fapi/fapiParseErrorInfo.pl b/src/usr/hwpf/fapi/fapiParseErrorInfo.pl
new file mode 100755
index 000000000..e0dc8b652
--- /dev/null
+++ b/src/usr/hwpf/fapi/fapiParseErrorInfo.pl
@@ -0,0 +1,79 @@
+#!/usr/bin/perl
+
+#
+# Usage:
+# fapiParseErrorInfo.pl <filename1> <filename2> .... <filenameN>
+
+use strict;
+
+my $numArgs = $#ARGV + 1;
+#print $numArgs, "\n";
+
+if ($numArgs < 1)
+{
+ print ("Usage: fapiParseErrorInfo.pl <filename1> <filename2> .... <filenameN>\n");
+ print (" This perl script will parse HWP Error XML files,\n");
+ print (" pull out the error Return Codes and create a header file\n");
+ print (" hwp/fapiHwpReturnCodes.H containing an enumeration of them.\n");
+ exit(1);
+}
+
+
+
+# use module
+use XML::Simple;
+#use Data::Dumper;
+
+#open output file for writing
+open(OUTFILE, ">fapiHwpReturnCodes.H");
+print OUTFILE "// fapiHwpReturnCodes.H\n";
+print OUTFILE "// This file is generated by perl script fapiParseErrorInfo.pl\n\n";
+print OUTFILE "#ifndef FAPIHWPRETURNCODES_H_\n";
+print OUTFILE "#define FAPIHWPRETURNCODES_H_\n\n";
+print OUTFILE "namespace fapi\n";
+print OUTFILE "{\n\n";
+print OUTFILE "/**\n";
+print OUTFILE " * \@brief Enumeration of HWP return codes\n";
+print OUTFILE " *\/\n";
+print OUTFILE "enum HwpReturnCode\n";
+print OUTFILE "{\n";
+
+# create object
+my $xml = new XML::Simple (KeyAttr=>[]);
+my $infile;
+
+#for each Hwp Attribute XML file
+foreach $infile(@ARGV)
+{
+ #print filename
+ #print $ifile, "\n\n";
+
+ # read XML file
+ my $errors = $xml->XMLin($infile);
+
+ # print output
+ #print Dumper($errors);
+ #print "\n";
+
+ # print return code to file
+ my $err;
+ foreach $err (@{$errors->{hwpError}})
+ {
+ if ($err->{id})
+ {
+ print OUTFILE " ", $err->{id}, ",\n";
+ }
+ else
+ {
+ print ("fapiParseErrorInfo.pl ERROR. ID missing\n");
+ exit(1);
+ }
+ };
+}
+
+print OUTFILE "};\n\n";
+print OUTFILE "}\n\n";
+print OUTFILE "#endif\n";
+
+#close output file
+close(OUTFILE);
diff --git a/src/usr/hwpf/fapi/fapiReturnCode.C b/src/usr/hwpf/fapi/fapiReturnCode.C
new file mode 100644
index 000000000..b32ae0f2f
--- /dev/null
+++ b/src/usr/hwpf/fapi/fapiReturnCode.C
@@ -0,0 +1,192 @@
+/**
+ * @file fapiReturnCode.C
+ *
+ * @brief Implements the ReturnCode class.
+ */
+
+#include <fapiReturnCode.H>
+#include <fapiReturnCodeDataRef.H>
+
+namespace fapi
+{
+
+//******************************************************************************
+// Default Constructor
+//******************************************************************************
+ReturnCode::ReturnCode() :
+ iv_rcValue(FAPI_RC_SUCCESS), iv_pDataRef(NULL)
+{
+
+}
+
+//******************************************************************************
+// Constructor
+//******************************************************************************
+ReturnCode::ReturnCode(const uint32_t i_rcValue) :
+ iv_rcValue(i_rcValue), iv_pDataRef(NULL)
+{
+
+}
+
+//******************************************************************************
+// Copy Constructor
+//******************************************************************************
+ReturnCode::ReturnCode(const ReturnCode & i_right) :
+ iv_rcValue(i_right.iv_rcValue), iv_pDataRef(i_right.iv_pDataRef)
+{
+ // Note shallow copy (in initializer list) of iv_pDataRef pointer. Both
+ // ReturnCodes now points to the same ReturnCodeDataRef
+
+ if (iv_pDataRef)
+ {
+ // Increase the ReturnCodeDataRef reference count
+ (void) iv_pDataRef->incRefCount();
+ }
+}
+
+//******************************************************************************
+// Destructor
+//******************************************************************************
+ReturnCode::~ReturnCode()
+{
+ // Remove interest in any pointed to ReturnCodeDataRef
+ (void) removeData();
+}
+
+//******************************************************************************
+// Assignment Operator
+//******************************************************************************
+ReturnCode & ReturnCode::operator=(const ReturnCode & i_right)
+{
+ // Test for self assignment
+ if (this != &i_right)
+ {
+ // Remove interest in any pointed to ReturnCodeDataRef
+ (void) removeData();
+
+ // Copy instance variables. Note shallow copy of iv_pDataRef pointer.
+ // Both ReturnCodes now points to the same ReturnCodeDataRef
+ iv_rcValue = i_right.iv_rcValue;
+ iv_pDataRef = i_right.iv_pDataRef;
+
+ if (iv_pDataRef)
+ {
+ // Increase the ReturnCodeDataRef reference count
+ (void) iv_pDataRef->incRefCount();
+ }
+ }
+ return *this;
+}
+
+//******************************************************************************
+// Assignment Operator
+//******************************************************************************
+ReturnCode & ReturnCode::operator=(const uint32_t i_rcValue)
+{
+ iv_rcValue = i_rcValue;
+ return *this;
+}
+
+//******************************************************************************
+// ok function
+//******************************************************************************
+bool ReturnCode::ok() const
+{
+ return (iv_rcValue == FAPI_RC_SUCCESS);
+}
+
+//******************************************************************************
+// returnCode_t cast
+//******************************************************************************
+ReturnCode::operator uint32_t() const
+{
+ return iv_rcValue;
+}
+
+//******************************************************************************
+// getData function
+//******************************************************************************
+void * ReturnCode::getData() const
+{
+ const void * l_pData = NULL;
+
+ if (iv_pDataRef)
+ {
+ // Get the data
+ l_pData = iv_pDataRef->getData();
+ }
+
+ // Remove the constness and return
+ return const_cast<void *>(l_pData);
+}
+
+//******************************************************************************
+// releaseData function
+//******************************************************************************
+void * ReturnCode::releaseData()
+{
+ const void * l_pData = NULL;
+
+ if (iv_pDataRef)
+ {
+ // Release the data
+ l_pData = iv_pDataRef->releaseData();
+
+ // Remove interest in pointed to ReturnCodeDataRef
+ (void) removeData();
+ }
+
+ // Remove the constness and return
+ return const_cast<void *>(l_pData);
+}
+
+//******************************************************************************
+// setData function
+//******************************************************************************
+void ReturnCode::setData(const void * i_pData)
+{
+ // Remove interest in pointed to ReturnCodeDataRef
+ (void) removeData();
+
+ // Create new ReturnCodeDataRef which points to the data
+ iv_pDataRef = new ReturnCodeDataRef(i_pData);
+}
+
+//******************************************************************************
+// getCreator function
+//******************************************************************************
+ReturnCode::returnCodeCreator ReturnCode::getCreator() const
+{
+ returnCodeCreator l_creator = CREATOR_HWP;
+
+ if ((iv_rcValue & FAPI_RC_FAPI_MASK) || (iv_rcValue & FAPI_RC_ECMD_MASK))
+ {
+ l_creator = CREATOR_FAPI;
+ }
+ else if (iv_rcValue & FAPI_RC_PLAT_MASK)
+ {
+ l_creator = CREATOR_PLAT;
+ }
+
+ return l_creator;
+}
+
+//******************************************************************************
+// removeData function
+//******************************************************************************
+void ReturnCode::removeData()
+{
+ if (iv_pDataRef)
+ {
+ // Decrement the ReturnCodeDataRef refcount
+ if (iv_pDataRef->decRefCountCheckZero())
+ {
+ // Refcount decremented to zero. No other ReturnCode points to the
+ // ReturnCodeDataRef object, delete it
+ delete iv_pDataRef;
+ }
+ iv_pDataRef = NULL;
+ }
+}
+
+}
diff --git a/src/usr/hwpf/fapi/fapiReturnCodeDataRef.C b/src/usr/hwpf/fapi/fapiReturnCodeDataRef.C
new file mode 100644
index 000000000..910d1653e
--- /dev/null
+++ b/src/usr/hwpf/fapi/fapiReturnCodeDataRef.C
@@ -0,0 +1,85 @@
+/**
+ * @file fapiReturnCodeDataRef.C
+ *
+ * @brief Implements the FAPI part of the ReturnCodeDataRef class.
+ */
+
+#include <fapiReturnCodeDataRef.H>
+#include <fapiUtil.H>
+
+namespace fapi
+{
+
+//******************************************************************************
+// Constructor
+//******************************************************************************
+ReturnCodeDataRef::ReturnCodeDataRef(const void * i_pData) :
+ iv_refCount(1), iv_pData(i_pData)
+{
+
+}
+
+//******************************************************************************
+// Destructor
+//******************************************************************************
+ReturnCodeDataRef::~ReturnCodeDataRef()
+{
+ if (iv_refCount != 0)
+ {
+ FAPI_ERR("ReturnCodeDataRef. Bug. Destruct with refcount");
+ fapiAssert(false);
+ }
+ else
+ {
+ // Call platform implemented deleteData
+ (void) deleteData();
+ }
+}
+
+//******************************************************************************
+// incRefCount function
+//******************************************************************************
+void ReturnCodeDataRef::incRefCount()
+{
+ FAPI_DBG("ReturnCodeDataRef::incRefCount: iv_refCount = %i on entry", iv_refCount);
+ iv_refCount++;
+}
+
+//******************************************************************************
+// decRefCountCheckZero function
+//******************************************************************************
+bool ReturnCodeDataRef::decRefCountCheckZero()
+{
+ FAPI_DBG("ReturnCodeDataRef::decRefCountCheckZero: iv_refCount = %i on entry", iv_refCount);
+
+ if (iv_refCount == 0)
+ {
+ FAPI_ERR("ReturnCodeDataRef. Bug. Dec with zero refcount");
+ fapiAssert(false);
+ }
+ else
+ {
+ iv_refCount--;
+ }
+ return (iv_refCount == 0);
+}
+
+//******************************************************************************
+// getData function
+//******************************************************************************
+const void * ReturnCodeDataRef::getData() const
+{
+ return iv_pData;
+}
+
+//******************************************************************************
+// releaseData function
+//******************************************************************************
+const void * ReturnCodeDataRef::releaseData()
+{
+ const void * l_pData = iv_pData;
+ iv_pData = NULL;
+ return l_pData;
+}
+
+}
diff --git a/src/usr/hwpf/fapi/fapiTarget.C b/src/usr/hwpf/fapi/fapiTarget.C
new file mode 100644
index 000000000..463a13ed3
--- /dev/null
+++ b/src/usr/hwpf/fapi/fapiTarget.C
@@ -0,0 +1,118 @@
+/**
+ * @file fapiTarget.C
+ *
+ * @brief Implements the FAPI part of the Target class.
+ */
+
+#include <fapiTarget.H>
+
+namespace fapi
+{
+
+//******************************************************************************
+// Default Constructor
+//******************************************************************************
+Target::Target() :
+ iv_type(TARGET_TYPE_NONE), iv_pHandle(NULL)
+{
+
+}
+
+//******************************************************************************
+// Constructor.
+//******************************************************************************
+Target::Target(const TargetType i_type,
+ const void * i_pHandle) :
+ iv_type(i_type), iv_pHandle(i_pHandle)
+{
+
+}
+
+//******************************************************************************
+// Copy Constructor
+//******************************************************************************
+Target::Target(const Target & i_right) :
+ iv_type(i_right.iv_type)
+{
+ (void) copyHandle(i_right);
+}
+
+//******************************************************************************
+// Destructor
+//******************************************************************************
+Target::~Target()
+{
+ (void) deleteHandle();
+}
+
+//******************************************************************************
+// Assignment Operator
+//******************************************************************************
+Target & Target::operator=(const Target & i_right)
+{
+ // Test for self assignment
+ if (this != &i_right)
+ {
+ iv_type = i_right.iv_type;
+ (void) copyHandle(i_right);
+ }
+ return *this;
+}
+
+//******************************************************************************
+// Equality Comparison Operator
+//******************************************************************************
+bool Target::operator==(const Target & i_right) const
+{
+ bool l_equal = false;
+
+ if (iv_type == i_right.iv_type)
+ {
+ l_equal = compareHandle(i_right);
+ }
+
+ return l_equal;
+}
+
+//******************************************************************************
+// Inequality Comparison Operator
+//******************************************************************************
+bool Target::operator!=(const Target & i_right) const
+{
+ // Determine inequality by calling the equality comparison operator
+ return (!(*this == i_right));
+}
+
+//******************************************************************************
+// Get the handle.
+//******************************************************************************
+void * Target::get() const
+{
+ return const_cast<void *>(iv_pHandle);
+}
+
+//******************************************************************************
+// Set the handle.
+//******************************************************************************
+void Target::set(const void * i_pHandle)
+{
+ iv_pHandle = i_pHandle;
+}
+
+//******************************************************************************
+// Get the target type
+//******************************************************************************
+TargetType Target::getType() const
+{
+ return iv_type;
+}
+
+//******************************************************************************
+// Set the target type
+//******************************************************************************
+void Target::setType(const TargetType i_type)
+{
+ iv_type = i_type;
+}
+
+}
diff --git a/src/usr/hwpf/fapi/makefile b/src/usr/hwpf/fapi/makefile
new file mode 100644
index 000000000..59df28b20
--- /dev/null
+++ b/src/usr/hwpf/fapi/makefile
@@ -0,0 +1,13 @@
+ROOTPATH = ../../../..
+MODULE = fapi
+
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat
+
+OBJS = fapiAttributeService.o \
+ fapiReturnCode.o \
+ fapiReturnCodeDataRef.o \
+ fapiTarget.o
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/hwpf/hwp/fapiHwpAttributeInfo.xml b/src/usr/hwpf/hwp/fapiHwpAttributeInfo.xml
new file mode 100644
index 000000000..d1316bc0f
--- /dev/null
+++ b/src/usr/hwpf/hwp/fapiHwpAttributeInfo.xml
@@ -0,0 +1,50 @@
+<!-- XML file specifying HW Procedure requested attributes. -->
+<!-- This is just the initial test version. HWPs will replace with an official version. -->
+
+<attributes>
+ <!-- *********************************************************************** -->
+ <attribute>
+ <id>ATTR_TEST_UINT8</id>
+ <description>Test Attribute UINT8</description>
+ <valueType>uint8</valueType>
+ </attribute>
+ <!-- *********************************************************************** -->
+ <attribute>
+ <id>ATTR_TEST_UINT32</id>
+ <description>Test Attribute UINT32</description>
+ <valueType>uint32</valueType>
+ </attribute>
+ <!-- *********************************************************************** -->
+ <attribute>
+ <id>ATTR_TEST_UINT64</id>
+ <description>Test Attribute UINT64</description>
+ <valueType>uint64</valueType>
+ </attribute>
+ <!-- *********************************************************************** -->
+ <attribute>
+ <id>ATTR_TEST_UINT8_ARRAY</id>
+ <description>Test Attribute UINT8 ARRAY</description>
+ <valueType>uint8</valueType>
+ <array>3</array>
+ </attribute>
+ <!-- *********************************************************************** -->
+ <attribute>
+ <id>ATTR_TEST_UINT32_ARRAY</id>
+ <description>Test Attribute UINT32 ARRAY</description>
+ <valueType>uint32</valueType>
+ <array>4</array>
+ </attribute>
+ <!-- *********************************************************************** -->
+ <attribute>
+ <id>ATTR_TEST_UINT64_ARRAY</id>
+ <description>Test Attribute UINT64 ARRAY</description>
+ <valueType>uint64</valueType>
+ <array>5</array>
+ </attribute>
+ <!-- *********************************************************************** -->
+ <attribute>
+ <id>ATTR_TEST_STRING</id>
+ <description>Test Attribute STRING</description>
+ <valueType>string</valueType>
+ </attribute>
+</attributes>
diff --git a/src/usr/hwpf/hwp/fapiHwpErrorInfo.xml b/src/usr/hwpf/hwp/fapiHwpErrorInfo.xml
new file mode 100644
index 000000000..e4c5e68b1
--- /dev/null
+++ b/src/usr/hwpf/hwp/fapiHwpErrorInfo.xml
@@ -0,0 +1,15 @@
+<!-- XML file specifying HW Procedure generated errors. -->
+<!-- This is just the initial test version. HWPs will replace with an official version. -->
+
+<hwpErrors>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <id>RC_TEST_ERROR_A</id>
+ <description>Test Error A</description>
+ </hwpError>
+ <!-- *********************************************************************** -->
+ <hwpError>
+ <id>RC_TEST_ERROR_B</id>
+ <description>Test Error B</description>
+ </hwpError>
+</hwpErrors>
diff --git a/src/usr/hwpf/hwp/fapiTestHwp.C b/src/usr/hwpf/hwp/fapiTestHwp.C
new file mode 100644
index 000000000..54dff5a66
--- /dev/null
+++ b/src/usr/hwpf/hwp/fapiTestHwp.C
@@ -0,0 +1,121 @@
+/**
+ * @file fapiTestHwp.C
+ *
+ * @brief Implements test Hardware Procedures.
+ */
+
+#include <fapiTestHwp.H>
+
+extern "C"
+{
+
+//******************************************************************************
+// hwpIsP7ChipletClockOn function
+//******************************************************************************
+fapi::ReturnCode hwpIsP7EM0ChipletClockOn(const fapi::Target & i_chip,
+ bool & o_clocksOn)
+{
+ // Ported from a combination of
+ // hwsvClockAlgP7.C : hwsvClockQueryOnP7 (main HWP)
+ // hwsvClockAlgP7.C : isChipletClockOn (sub function)
+
+ // Attempt to call the attribute get/set functions for the test attributes
+ fapi::ReturnCode l_rc;
+
+ // Test getting and setting attributes
+ {
+ char * l_pString = NULL;
+ uint8_t l_uint8 = 0;
+ uint32_t l_uint32 = 0;
+ uint64_t l_uint64 = 0;
+ uint8_t l_pUint8Array[3] = {0};
+ uint32_t l_pUint32Array[4] = {0};
+ uint64_t l_pUint64Array[5] = {0};
+
+ // All of the following should currently compile (not checking RC which
+ // should be FAPI_RC_NOT_IMPLEMENTED). The get/set functions do not
+ // currently do anything so passing NULL will work.
+ l_rc = FAPI_ATTR_GET(ATTR_TEST_STRING, &i_chip, l_pString);
+ l_rc = FAPI_ATTR_GET(ATTR_TEST_UINT8, &i_chip, l_uint8);
+ l_rc = FAPI_ATTR_GET(ATTR_TEST_UINT32, &i_chip, l_uint32);
+ l_rc = FAPI_ATTR_GET(ATTR_TEST_UINT64, &i_chip, l_uint64);
+ l_rc = FAPI_ATTR_GET(ATTR_TEST_UINT8_ARRAY, &i_chip, l_pUint8Array);
+ l_rc = FAPI_ATTR_GET(ATTR_TEST_UINT32_ARRAY, &i_chip, l_pUint32Array);
+ l_rc = FAPI_ATTR_GET(ATTR_TEST_UINT64_ARRAY, &i_chip, l_pUint64Array);
+
+ l_rc = FAPI_ATTR_SET(ATTR_TEST_STRING, &i_chip, l_pString);
+ l_rc = FAPI_ATTR_SET(ATTR_TEST_STRING, &i_chip, "test-string");
+ l_rc = FAPI_ATTR_SET(ATTR_TEST_UINT8, &i_chip, l_uint8);
+ l_rc = FAPI_ATTR_SET(ATTR_TEST_UINT32, &i_chip, l_uint32);
+ l_rc = FAPI_ATTR_SET(ATTR_TEST_UINT64, &i_chip, l_uint64);
+ l_rc = FAPI_ATTR_SET(ATTR_TEST_UINT8_ARRAY, &i_chip, l_pUint8Array);
+ l_rc = FAPI_ATTR_SET(ATTR_TEST_UINT32_ARRAY, &i_chip, l_pUint32Array);
+ l_rc = FAPI_ATTR_SET(ATTR_TEST_UINT64_ARRAY, &i_chip, l_pUint64Array);
+
+ // All of the following should not compile due to wrong types used
+ //l_rc = FAPI_ATTR_GET(ATTR_TEST_STRING, &i_chip, l_uint8);
+ //l_rc = FAPI_ATTR_GET(ATTR_TEST_STRING, &i_chip, l_uint32);
+ //l_rc = FAPI_ATTR_GET(ATTR_TEST_STRING, &i_chip, l_uint64);
+ //l_rc = FAPI_ATTR_GET(ATTR_TEST_STRING, &i_chip, l_pUint8Array);
+ //l_rc = FAPI_ATTR_GET(ATTR_TEST_UINT8, &i_chip, l_pString);
+ //l_rc = FAPI_ATTR_GET(ATTR_TEST_UINT32, &i_chip, l_uint8);
+ //l_rc = FAPI_ATTR_GET(ATTR_TEST_UINT64, &i_chip, l_pUint8Array);
+ //l_rc = FAPI_ATTR_GET(ATTR_TEST_UINT64, &i_chip, l_pUint64Array);
+ //l_rc = FAPI_ATTR_GET(ATTR_TEST_UINT8_ARRAY, &i_chip, l_pString);
+ //l_rc = FAPI_ATTR_GET(ATTR_TEST_UINT32_ARRAY, &i_chip, l_uint8);
+ //l_rc = FAPI_ATTR_GET(ATTR_TEST_UINT64_ARRAY, &i_chip, l_uint64);
+ //l_rc = FAPI_ATTR_GET(ATTR_TEST_UINT64_ARRAY, &i_chip, l_pUint32Array);
+
+ //l_rc = FAPI_ATTR_SET(ATTR_TEST_STRING, &i_chip, l_uint8);
+ //l_rc = FAPI_ATTR_SET(ATTR_TEST_STRING, &i_chip, l_uint32);
+ //l_rc = FAPI_ATTR_SET(ATTR_TEST_STRING, &i_chip, l_uint64);
+ //l_rc = FAPI_ATTR_SET(ATTR_TEST_STRING, &i_chip, l_pUint64Array);
+ //l_rc = FAPI_ATTR_SET(ATTR_TEST_UINT8, &i_chip, l_pString);
+ //l_rc = FAPI_ATTR_SET(ATTR_TEST_UINT32, &i_chip, l_uint64);
+ //l_rc = FAPI_ATTR_SET(ATTR_TEST_UINT64, &i_chip, l_pUint32Array);
+ //l_rc = FAPI_ATTR_SET(ATTR_TEST_UINT64, &i_chip, l_pUint64Array);
+ //l_rc = FAPI_ATTR_SET(ATTR_TEST_UINT8_ARRAY, &i_chip, l_pString);
+ //l_rc = FAPI_ATTR_SET(ATTR_TEST_UINT32_ARRAY, &i_chip, l_uint8);
+ //l_rc = FAPI_ATTR_SET(ATTR_TEST_UINT64_ARRAY, &i_chip, l_uint64);
+ //l_rc = FAPI_ATTR_SET(ATTR_TEST_UINT64_ARRAY, &i_chip, l_pUint8Array);
+
+ l_rc = fapi::FAPI_RC_SUCCESS;
+ }
+
+ // Constants
+ const uint64_t EM_CLOCK_STATUS_MASK = 0xEEC0000000000000ULL;
+ const uint32_t EM0_CHIPLET_BASE_ADDR = 0x06000000;
+ const uint32_t CHIPLET_CLOCK_ON_SCOM_ADDR = 0x00030008;
+
+ // Set caller's result to default
+ o_clocksOn = false;
+
+ // Figure out the scom address and create a 64 bit data buffer
+ uint32_t l_addr = (EM0_CHIPLET_BASE_ADDR | CHIPLET_CLOCK_ON_SCOM_ADDR);
+ ecmdDataBufferBase l_data(64);
+
+ // Perform a GetScom operation on the chip
+ l_rc = GetScom(i_chip, l_addr, l_data);
+
+ if (l_rc != fapi::FAPI_RC_SUCCESS)
+ {
+ FAPI_ERR("hwpIsP7EM0ChipletClockOn: Error from GetScomChip");
+ }
+ else
+ {
+ if (!(l_data.getDoubleWord(0) & EM_CLOCK_STATUS_MASK))
+ {
+ FAPI_INF("hwpIsP7EM0ChipletClockOn: Clocks are on");
+ o_clocksOn = true;
+ }
+ else
+ {
+ FAPI_INF("hwpIsP7EM0ChipletClockOn: Clocks are off");
+ }
+ }
+
+ return l_rc;
+}
+
+
+} // extern "C"
diff --git a/src/usr/hwpf/hwp/makefile b/src/usr/hwpf/hwp/makefile
new file mode 100644
index 000000000..ef38aa8c9
--- /dev/null
+++ b/src/usr/hwpf/hwp/makefile
@@ -0,0 +1,11 @@
+ROOTPATH = ../../../..
+MODULE = hwp
+
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat
+
+OBJS = fapiTestHwp.o
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/hwpf/makefile b/src/usr/hwpf/makefile
new file mode 100644
index 000000000..be8828a60
--- /dev/null
+++ b/src/usr/hwpf/makefile
@@ -0,0 +1,16 @@
+ROOTPATH = ../../..
+MODULE = hwpf
+
+GENFILES = fapiHwpReturnCodes.H fapiAttributeIds.H
+
+SUBDIRS = fapi.d hwp.d plat.d test.d
+
+include ${ROOTPATH}/config.mk
+
+${GENDIR}/fapiHwpReturnCodes.H : fapi/fapiParseErrorInfo.pl hwp/fapiHwpErrorInfo.xml
+ $^
+ mv $(notdir $@) $@
+
+${GENDIR}/fapiAttributeIds.H : fapi/fapiParseAttributeInfo.pl hwp/fapiHwpAttributeInfo.xml
+ $^
+ mv $(notdir $@) $@
diff --git a/src/usr/hwpf/plat/fapiPlatHwAccess.C b/src/usr/hwpf/plat/fapiPlatHwAccess.C
new file mode 100644
index 000000000..d1058520c
--- /dev/null
+++ b/src/usr/hwpf/plat/fapiPlatHwAccess.C
@@ -0,0 +1,142 @@
+/**
+ * @file fapiPlatHwAccess.C
+ *
+ * @brief Implements the fapiHwAccess.H functions.
+ *
+ * Note that platform code must provide the implementation.
+ */
+
+#include <fapiHwAccess.H>
+#include <fapiPlatTrace.H>
+#include <errl/errlentry.H>
+#include <targeting/targetservice.H>
+#include <devicefw/userif.H>
+
+extern "C"
+{
+
+//******************************************************************************
+// GetScom function
+//******************************************************************************
+fapi::ReturnCode GetScom(const fapi::Target& i_target,
+ const uint64_t i_address,
+ ecmdDataBufferBase & o_data)
+{
+ FAPI_DBG(ENTER_MRK "GetScom");
+
+ fapi::ReturnCode l_rc;
+ errlHndl_t l_err = NULL;
+
+ // Extract the component pointer
+ TARGETING::Target* l_target = reinterpret_cast<TARGETING::Target*>(i_target.get());
+
+ // Perform SCOM read
+ uint64_t l_data = 0;
+ size_t l_size = sizeof(uint64_t);
+ l_err = deviceRead(l_target,
+ &l_data,
+ l_size,
+ DEVICE_SCOM_ADDRESS(i_address));
+ if (l_err)
+ {
+ // Add the error log pointer as data to the ReturnCode
+ FAPI_ERR("GetScom: HostBoot GetScom returns error");
+ l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA;
+ l_rc.setData(reinterpret_cast<void *> (l_err));
+ }
+ else
+ {
+ o_data.setDoubleWord(0, l_data);
+ }
+
+ FAPI_DBG(EXIT_MRK "GetScom");
+ return l_rc;
+}
+
+//******************************************************************************
+// PutScom function
+//******************************************************************************
+fapi::ReturnCode PutScom(const fapi::Target& i_target,
+ const uint64_t i_address,
+ ecmdDataBufferBase & i_data)
+{
+ FAPI_DBG(ENTER_MRK "PutScom");
+ fapi::ReturnCode l_rc;
+ errlHndl_t l_err = NULL;
+
+ // Extract the component pointer
+ TARGETING::Target* l_target = reinterpret_cast<TARGETING::Target*>(i_target.get());
+
+ // Perform SCOM read
+ uint64_t l_data = i_data.getDoubleWord(0);
+ size_t l_size = sizeof(uint64_t);
+ l_err = deviceWrite(l_target,
+ &l_data,
+ l_size,
+ DEVICE_SCOM_ADDRESS(i_address));
+ if (l_err)
+ {
+ // Add the error log pointer as data to the ReturnCode
+ FAPI_ERR("Putscom: HostBoot Putscom returns error");
+ l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA;
+ l_rc.setData(reinterpret_cast<void *> (l_err));
+ }
+
+ FAPI_DBG(EXIT_MRK "PutScom");
+ return l_rc;
+}
+
+//@todo - Implement these functions later
+#if 0
+//******************************************************************************
+// PutScomUnderMask function
+//******************************************************************************
+fapi::ReturnCode PutScomUnderMask(const fapi::Target& i_target,
+ const uint64_t i_address,
+ ecmdDataBufferBase & i_data,
+ ecmdDataBufferBase & i_mask)
+{
+ FAPI_DBG(ENTER_MRK "PutScomUnderMask");
+
+ FAPI_DBG(EXIT_MRK "PutScomUnderMask");
+}
+
+//******************************************************************************
+// GetCfamRegister function
+//******************************************************************************
+fapi::ReturnCode GetCfamRegister(const fapi::Target& i_target,
+ const uint32_t i_address,
+ ecmdDataBufferBase & o_data)
+{
+ FAPI_DBG(ENTER_MRK "GetCfamRegister");
+
+ FAPI_DBG(EXIT_MRK "GetCfamRegister");
+}
+
+//******************************************************************************
+// PutCfamRegister function
+//******************************************************************************
+fapi::ReturnCode PutCfamRegister(const fapi::Target& i_target,
+ const uint32_t i_address,
+ ecmdDataBufferBase & i_data)
+{
+ FAPI_DBG(ENTER_MRK "PutCfamRegister");
+
+ FAPI_DBG(EXIT_MRK "PutCfamRegister");
+}
+
+//******************************************************************************
+// ModifyCfamRegister function
+//******************************************************************************
+fapi::ReturnCode ModifyCfamRegister(const fapi::Target& i_target,
+ const uint32_t i_address,
+ ecmdDataBufferBase & i_data,
+ const fapi::ChipOpModifyMode i_modifyMode)
+{
+ FAPI_DBG(ENTER_MRK "ModifyCfamRegister");
+
+ FAPI_DBG(EXIT_MRK "ModifyCfamRegister");
+}
+#endif
+
+} // extern "C"
diff --git a/src/usr/hwpf/plat/fapiPlatHwpInvoker.C b/src/usr/hwpf/plat/fapiPlatHwpInvoker.C
new file mode 100644
index 000000000..d6d8cbaad
--- /dev/null
+++ b/src/usr/hwpf/plat/fapiPlatHwpInvoker.C
@@ -0,0 +1,84 @@
+/**
+ * @file fapiPlatHwpInvoker.C
+ *
+ * @brief Implements the platform specific HW Procedure invoker functions.
+ */
+
+#include <fapiPlatHwpInvoker.H>
+#include <fapiReturnCode.H>
+#include <fapiPlatTrace.H>
+#include <fapiTestHwp.H>
+
+namespace fapi
+{
+
+//******************************************************************************
+// rcToErrl function
+//******************************************************************************
+errlHndl_t rcToErrl(ReturnCode i_rc)
+{
+ errlHndl_t l_err = NULL;
+
+ ReturnCode::returnCodeCreator l_creator = i_rc.getCreator();
+
+ if (l_creator == ReturnCode::CREATOR_PLAT)
+ {
+ // Release the errlHndl_t
+ l_err = reinterpret_cast<errlHndl_t> (i_rc.releaseData());
+ }
+ else
+ {
+ //@todo Figure out how to convert FAPI/HWP error to Host Boot error log
+ }
+
+ return l_err;
+}
+
+
+//******************************************************************************
+// invokeHwpIsP7EM0ChipletClockOn function
+//******************************************************************************
+errlHndl_t invokeHwpIsP7EM0ChipletClockOn(TARGETING::Target* i_target,
+ bool & o_clocksOn)
+{
+
+ FAPI_DBG(ENTER_MRK "HostBootHwpIsP7EM0ChipletClockOn");
+
+ errlHndl_t l_err = NULL;
+
+ // Create a generic Target object
+ Target l_target(TARGET_TYPE_PROC_CHIP, reinterpret_cast<void *> (i_target));
+
+ //@todo
+ // Double check to see if any locking is needed here.
+ // Lower XSCOM already has a mutex lock.
+
+ // Call the HWP executor macro
+ ReturnCode l_rc;
+ FAPI_EXEC_HWP(l_rc, hwpIsP7EM0ChipletClockOn, l_target, o_clocksOn);
+
+ if (l_rc != FAPI_RC_SUCCESS)
+ {
+ FAPI_ERR("hwpIsP7EM0ChipletClockOn: Error (0x%x) from "
+ "execHwpIsP7EM0ChipletClockOn",
+ static_cast<uint32_t> (l_rc));
+ l_err = rcToErrl(l_rc);
+ }
+ else
+ {
+ if (o_clocksOn)
+ {
+ FAPI_INF("hwpIsP7EM0ChipletClockOn: Clocks are on");
+ }
+ else
+ {
+ FAPI_INF("hwpIsP7EM0ChipletClockOn: Clocks are off");
+ }
+ }
+
+ FAPI_DBG(EXIT_MRK "HostBootHwpIsP7EM0ChipletClockOn");
+
+ return l_err;
+}
+
+} // End namespace
diff --git a/src/usr/hwpf/plat/fapiPlatReturnCodeDataRef.C b/src/usr/hwpf/plat/fapiPlatReturnCodeDataRef.C
new file mode 100644
index 000000000..9906f781f
--- /dev/null
+++ b/src/usr/hwpf/plat/fapiPlatReturnCodeDataRef.C
@@ -0,0 +1,28 @@
+/**
+ * @file platReturnCodeDataRef.C
+ *
+ * @brief Implements the platform part of the ReturnCodeDataRef class.
+ *
+ * Note that platform code must provide the implementation. FAPI has provided
+ * an example for platforms that do not attach ReturnCodeData to a ReturnCode.
+ */
+
+#include <fapiReturnCodeDataRef.H>
+#include <fapiPlatTrace.H>
+#include <errl/errlentry.H>
+
+namespace fapi
+{
+
+//******************************************************************************
+// deleteData function
+//******************************************************************************
+void ReturnCodeDataRef::deleteData()
+{
+ FAPI_DBG("ReturnCodeDataRef::deleteData");
+
+ // FSP platform uses iv_pData to point at a FipS error log.
+ delete (reinterpret_cast<errlHndl_t>(const_cast<void *>(iv_pData)));
+}
+
+}
diff --git a/src/usr/hwpf/plat/fapiPlatSystemConfig.C b/src/usr/hwpf/plat/fapiPlatSystemConfig.C
new file mode 100644
index 000000000..05fbd6250
--- /dev/null
+++ b/src/usr/hwpf/plat/fapiPlatSystemConfig.C
@@ -0,0 +1,72 @@
+/**
+ * @file fapiPlatSystemConfig.C
+ *
+ * @brief Implements the fapiSystemConfig.H functions.
+ *
+ * Note that platform code must provide the implementation.
+ */
+
+#include <fapiSystemConfig.H>
+#include <fapiPlatTrace.H>
+
+extern "C"
+{
+
+//******************************************************************************
+// GetFunctionalChiplets function
+//******************************************************************************
+fapi::ReturnCode GetFunctionalChiplets(const fapi::Target& i_target,
+ const fapi::TargetType i_chipletType,
+ std::vector<fapi::Target> & o_chiplets)
+{
+ FAPI_DBG(ENTER_MRK "GetFunctionalChiplets");
+
+ FAPI_DBG(EXIT_MRK "GetFunctionalChiplets");
+
+ return fapi::FAPI_RC_PLAT_NOT_IMPLEMENTED;
+}
+
+//******************************************************************************
+// GetExistingChiplets function
+//******************************************************************************
+fapi::ReturnCode GetExistingChiplets(const fapi::Target& i_target,
+ const fapi::TargetType i_chipletType,
+ std::vector<fapi::Target> & o_chiplets)
+{
+ FAPI_DBG(ENTER_MRK "GetExistingChiplets");
+
+ FAPI_DBG(EXIT_MRK "GetExistingChiplets");
+
+ return fapi::FAPI_RC_PLAT_NOT_IMPLEMENTED;
+
+}
+
+//******************************************************************************
+// GetFunctionalDimms function
+//******************************************************************************
+fapi::ReturnCode GetFunctionalDimms(const fapi::Target& i_target,
+ std::vector<fapi::Target> & o_dimms)
+{
+ FAPI_DBG(ENTER_MRK "GetFunctionalDimms");
+
+ FAPI_DBG(EXIT_MRK "GetFunctionalDimms");
+
+ return fapi::FAPI_RC_PLAT_NOT_IMPLEMENTED;
+
+}
+
+//******************************************************************************
+// GetExistingDimms function
+//******************************************************************************
+fapi::ReturnCode GetExistingDimms(const fapi::Target& i_target,
+ std::vector<fapi::Target> & o_dimms)
+{
+ FAPI_DBG(ENTER_MRK "GetExistingDimms");
+
+ FAPI_DBG(EXIT_MRK "GetExistingDimms");
+
+ return fapi::FAPI_RC_PLAT_NOT_IMPLEMENTED;
+
+}
+
+} // extern "C"
diff --git a/src/usr/hwpf/plat/fapiPlatTarget.C b/src/usr/hwpf/plat/fapiPlatTarget.C
new file mode 100644
index 000000000..0fff06556
--- /dev/null
+++ b/src/usr/hwpf/plat/fapiPlatTarget.C
@@ -0,0 +1,50 @@
+/**
+ * @file platTarget.C
+ *
+ * @brief Implements the platform part of the Target class.
+ *
+ * Note that platform code must provide the implementation.
+ *
+ * FAPI has provided a default implementation for platforms that use the
+ * handle pointer to point to a Component that is not created/deleted when a
+ * Target object is created/deleted (i.e. two Target objects that reference
+ * the same component have the same pointer). It could be possible for a
+ * platform specific ID structure to be created and pointed to each time a new
+ * Target is created, in that case, the pointed to object's type needs to be
+ * be known in order to do a deep compare/copy and a delete.
+ */
+
+#include <fapiTarget.H>
+
+namespace fapi
+{
+
+//******************************************************************************
+// Compare the handle
+//
+// If the pointers point to the same component then the handles are the same
+//******************************************************************************
+bool Target::compareHandle(const Target & i_right) const
+{
+ return (iv_pHandle == i_right.iv_pHandle);
+}
+
+//******************************************************************************
+// Copy the handle
+//
+// Note shallow copy of iv_pHandle. Both Targets point to the same component
+//******************************************************************************
+void Target::copyHandle(const Target & i_right)
+{
+ iv_pHandle = i_right.iv_pHandle;
+}
+
+//******************************************************************************
+// Delete the handle
+//******************************************************************************
+void Target::deleteHandle()
+{
+ // Intentionally does nothing. The component must not be deleted
+}
+
+}
diff --git a/src/usr/hwpf/plat/fapiPlatUtil.C b/src/usr/hwpf/plat/fapiPlatUtil.C
new file mode 100644
index 000000000..b8d47619a
--- /dev/null
+++ b/src/usr/hwpf/plat/fapiPlatUtil.C
@@ -0,0 +1,39 @@
+/**
+ * @file platUtil.C
+ *
+ * @brief Implements the fapiUtil.H utility functions.
+ *
+ * Note that platform code must provide the implementation.
+ */
+
+#include <trace/interface.H>
+#include <fapi.H>
+
+//******************************************************************************
+// Trace descriptors
+//******************************************************************************
+trace_desc_t* g_fapiInfTd;
+trace_desc_t* g_fapiImpTd;
+trace_desc_t* g_fapiErrTd;
+trace_desc_t* g_fapiDbgTd;
+
+//******************************************************************************
+// Global TracInit objects. Construction will initialize the trace buffer
+//******************************************************************************
+TRAC_INIT(&g_fapiInfTd, FAPI_INF_TRACE_NAME, 4096);
+TRAC_INIT(&g_fapiImpTd, FAPI_IMP_TRACE_NAME, 4096);
+TRAC_INIT(&g_fapiErrTd, FAPI_ERR_TRACE_NAME, 4096);
+TRAC_INIT(&g_fapiDbgTd, FAPI_DBG_TRACE_NAME, 4096);
+
+namespace fapi
+{
+
+//******************************************************************************
+// fapiAssert
+//******************************************************************************
+void fapiAssert(bool i_expression)
+{
+ assert(i_expression);
+}
+
+}
diff --git a/src/usr/hwpf/plat/makefile b/src/usr/hwpf/plat/makefile
new file mode 100644
index 000000000..1353ad9b9
--- /dev/null
+++ b/src/usr/hwpf/plat/makefile
@@ -0,0 +1,16 @@
+ROOTPATH = ../../../..
+MODULE = plat
+
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp
+
+OBJS = fapiPlatHwAccess.o \
+ fapiPlatHwpInvoker.o \
+ fapiPlatReturnCodeDataRef.o \
+ fapiPlatSystemConfig.o \
+ fapiPlatTarget.o \
+ fapiPlatUtil.o
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/hwpf/test/fapirctest.H b/src/usr/hwpf/test/fapirctest.H
new file mode 100644
index 000000000..140882483
--- /dev/null
+++ b/src/usr/hwpf/test/fapirctest.H
@@ -0,0 +1,461 @@
+#ifndef __FAPItestRc_H
+#define __FAPItestRc_H
+
+/**
+ * @file fapitestRc.H
+ *
+ * @brief Test case for FAPI return codes
+*/
+
+#include <cxxtest/TestSuite.H>
+#include <fapi.H>
+
+using namespace fapi;
+
+class FapitestRc: public CxxTest::TestSuite
+{
+public:
+
+ /**
+ * @brief Test FAPI return codes #1
+ */
+ void testRc1(void)
+ {
+ // Create ReturnCode using default constructor
+ ReturnCode l_rc;
+
+ // Ensure that the embedded return code is success
+ if (l_rc != FAPI_RC_SUCCESS)
+ {
+ TS_FAIL("testRc1. ReturnCode init is not FAPI_RC_SUCCESS");
+ }
+ else
+ {
+ // Ensure that OK function works
+ if (l_rc.ok() == false)
+ {
+ TS_FAIL("testRc1. ok() returned false");
+ }
+ else
+ {
+ // Ensure that testing l_rc works
+ if (l_rc)
+ {
+ TS_FAIL("testRc1. testing rc returned true");
+ }
+ }
+ }
+ return;
+ }
+
+
+ /**
+ * @brief Test FAPI return codes #2
+ */
+ void testRc2()
+ {
+
+ // Create ReturnCode using default constructor
+ ReturnCode l_rc;
+
+ // Set the return code to a FAPI code
+ l_rc = FAPI_RC_FAPI_MASK | 0x05;
+
+ // Ensure that the creator is FAPI
+ ReturnCode::returnCodeCreator l_creator = l_rc.getCreator();
+
+ if (l_creator != ReturnCode::CREATOR_FAPI)
+ {
+ TS_FAIL("testRc2. Creator is not CREATOR_FAPI");
+ }
+ else
+ {
+ // Set the return code to a PLAT code
+ l_rc = FAPI_RC_PLAT_ERR_SEE_DATA;
+
+ // Ensure that the creator is PLAT
+ l_creator = l_rc.getCreator();
+
+ if (l_creator != ReturnCode::CREATOR_PLAT)
+ {
+ TS_FAIL("testRc2. Creator is not CREATOR_PLAT");
+ }
+ else
+ {
+ l_rc = 5;
+
+ // Ensure that the creator is HWP
+ l_creator = l_rc.getCreator();
+
+ if (l_creator != ReturnCode::CREATOR_HWP)
+ {
+ TS_FAIL("testRc2. Creator is not CREATOR_HWP");
+ }
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * @brief Test FAPI return codes #3
+ */
+ void testRc3()
+ {
+ uint32_t l_code = 4;
+
+ // Create ReturnCode specifying a return code
+ ReturnCode l_rc(l_code);
+
+ // Ensure that the embedded return code is as expected
+ uint32_t l_codeCheck = l_rc;
+
+ if (l_codeCheck != l_code)
+ {
+ TS_FAIL("testRc3. Code is not set as desired");
+ }
+ else
+ {
+ // Ensure that ok function returns false
+ if (l_rc.ok())
+ {
+ TS_FAIL("testRc3. ok returned true");
+ }
+ else
+ {
+ // Ensure that testing l_rc works
+ if (!l_rc)
+ {
+ TS_FAIL("testRc3. testing rc returned false");
+ }
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * @brief Test FAPI return codes #4
+ */
+ void testRc4()
+ {
+ uint32_t l_code = 6;
+ uint32_t l_code2 = 7;
+
+ // Create similar ReturnCodes
+ ReturnCode l_rc(l_code);
+ ReturnCode l_rc2(l_code);
+
+ // Ensure that the equality comparison returns true
+ if (!(l_rc == l_rc2))
+ {
+ TS_FAIL("testRc4. Equality comparison false");
+ }
+ else
+ {
+ // Ensure that the inequality comparison returns false
+ if (l_rc != l_rc2)
+ {
+ TS_FAIL("testRc4.Inequality comparison true");
+ }
+ else
+ {
+ // Change the code of l_rc2
+ l_rc2 = l_code2;
+
+ // Ensure that the equality comparison returns false
+ if (l_rc == l_rc2)
+ {
+ TS_FAIL("testRc4. Equality comparison true");
+ }
+ else
+ {
+ // Ensure that the inequality comparison returns true
+ if (!(l_rc != l_rc2))
+ {
+ TS_FAIL("testRc4. Inequality comparison false");
+ }
+ }
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * @brief Test FAPI return codes #5
+ */
+ void testRc5()
+ {
+ uint32_t l_code = 6;
+ uint32_t l_code2 = 7;
+
+ // Create a ReturnCode
+ ReturnCode l_rc(l_code);
+
+ // Ensure that the equality comparison returns true when comparing to the
+ // same return code value
+ if (!(l_rc == l_code))
+ {
+ TS_FAIL("testRc5. 1. Equality comparison false");
+ }
+ else
+ {
+ // Ensure that the inequality comparison returns false when comparing to
+ // the same return code value
+ if (l_rc != l_code)
+ {
+ TS_FAIL("testRc5. 2. Inequality comparison true");
+ }
+ else
+ {
+ // Ensure that the equality comparison returns false when comparing
+ // to a different return code value
+ if (l_rc == l_code2)
+ {
+ TS_FAIL("testRc5. 3. Equality comparison true");
+ }
+ else
+ {
+ // Ensure that the inequality comparison returns true when
+ // comparing to a different return code value
+ if (!(l_rc != l_code2))
+ {
+ TS_FAIL("testRc5. 4. Inequality comparison false");
+ }
+ }
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * @brief Test FAPI return codes #6
+ */
+ void testRc6()
+ {
+ uint32_t l_code = 6;
+
+ // Create a ReturnCode
+ ReturnCode l_rc(l_code);
+
+ // Ensure that the getData function returns NULL
+ void * l_pData = reinterpret_cast<void *> (0x12345678);
+
+ l_pData = l_rc.getData();
+ if (l_pData != NULL)
+ {
+ TS_FAIL("testRc6. getData did not return NULL");
+ }
+ else
+ {
+ // Ensure that the releaseData function returns NULL
+ l_pData = reinterpret_cast<void *> (0x12345678);
+
+ l_pData = l_rc.releaseData();
+
+ if (l_pData != NULL)
+ {
+ TS_FAIL("testRc6. releaseData did not return NULL");
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * @brief Test FAPI return codes #7
+ */
+ void testRc7()
+ {
+ uint32_t l_code = 10;
+
+ // Create a ReturnCode
+ ReturnCode l_rc(l_code);
+
+ // Assign ReturnCodeData. Note that this should really be an errlHndl_t,
+ // because the FSP deleteData function will attempt to delete an error
+ // log, but this is just for test, the data will be released before the
+ // ReturnCode is destructed.
+ uint32_t l_myData = 6;
+ void * l_pMyData = reinterpret_cast<void *> (&l_myData);
+ (void) l_rc.setData(l_pMyData);
+
+ // Ensure that getData retrieves the ReturnCodeData
+ void * l_pMyDataCheck = l_rc.getData();
+
+ if (l_pMyDataCheck != l_pMyData)
+ {
+ TS_FAIL("testRc7. getData returned unexpected data ptr");
+ }
+ else
+ {
+ // Ensure that getData retrieves the ReturnCodeData again
+ l_pMyDataCheck = NULL;
+ l_pMyDataCheck = l_rc.getData();
+
+ if (l_pMyDataCheck != l_pMyData)
+ {
+ TS_FAIL("testRc7. getData returned unexpected data ptr");
+ }
+ }
+
+ // Release the data to avoid ReturnCode from deleting in on destruction
+ l_pMyDataCheck = l_rc.releaseData();
+
+ return;
+ }
+
+ /**
+ * @brief Test FAPI return codes #8
+ */
+ void testRc8()
+ {
+ uint32_t l_code = 10;
+
+ // Create a ReturnCode
+ ReturnCode l_rc(l_code);
+
+ // Assign ReturnCodeData. Note that this should really be an errlHndl_t,
+ // because the FSP deleteData function will attempt to delete an error
+ // log, but this is just for test, the data will be released before the
+ // ReturnCode is destructed.
+ uint32_t l_myData = 6;
+ void * l_pMyData = reinterpret_cast<void *> (&l_myData);
+ (void) l_rc.setData(l_pMyData);
+
+ // Ensure that releaseData retrieves the ReturnCodeData
+ void * l_pMyDataCheck = l_rc.releaseData();
+
+ if (l_pMyDataCheck != l_pMyData)
+ {
+ TS_FAIL("testRc8. getData returned unexpected data ptr");
+ }
+ else
+ {
+ // Ensure that releaseData now returns NULL
+ l_pMyDataCheck = NULL;
+ l_pMyDataCheck = l_rc.releaseData();
+
+ if (l_pMyDataCheck != NULL)
+ {
+ TS_FAIL("testRc8. getData returned non NULL ptr");
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * @brief Test FAPI return codes #9
+ */
+ void testRc9()
+ {
+ uint32_t l_code = 10;
+
+ // Create a ReturnCode
+ ReturnCode l_rc(l_code);
+
+ // Assign ReturnCodeData. Note that this should really be an errlHndl_t,
+ // because the FSP deleteData function will attempt to delete an error
+ // log, but this is just for test, the data will be released before the
+ // ReturnCode is destructed.
+ uint32_t l_myData = 6;
+ void * l_pMyData = reinterpret_cast<void *> (&l_myData);
+ (void) l_rc.setData(l_pMyData);
+
+ // Create a ReturnCode using the copy constructor
+ ReturnCode l_rc2(l_rc);
+
+ // Ensure that the two ReturnCodes are the same
+ if (l_rc != l_rc2)
+ {
+ TS_FAIL("testRc9. ReturnCodes differ");
+ }
+ else
+ {
+ // Ensure that getData retrieves the ReturnCodeData from l_rc
+ void * l_pMyDataCheck = l_rc.getData();
+
+ if (l_pMyDataCheck != l_pMyData)
+ {
+ TS_FAIL("testRc9. getData returned unexpected data ptr (1)");
+ }
+ else
+ {
+ // Ensure that getData retrieves the ReturnCodeData from l_rc2
+ l_pMyDataCheck = NULL;
+ l_pMyDataCheck = l_rc2.getData();
+
+ if (l_pMyDataCheck != l_pMyData)
+ {
+ TS_FAIL("testRc9. getData returned unexpected data ptr (2)");
+ }
+ }
+ }
+
+ // Release the data to avoid ReturnCode from deleting in on destruction.
+ // This will release the data from both copies of the ReturnCode.
+ (void) l_rc.releaseData();
+
+ return;
+ }
+
+ /**
+ * @brief Test FAPI return codes #10
+ */
+ void testRc10()
+ {
+ uint32_t l_code = 10;
+
+ // Create a ReturnCode
+ ReturnCode l_rc(l_code);
+
+ // Assign ReturnCodeData. Note that this should really be an errlHndl_t,
+ // because the FSP deleteData function will attempt to delete an error
+ // log, but this is just for test, the data will be released before the
+ // ReturnCode is destructed.
+ uint32_t l_myData = 6;
+ void * l_pMyData = reinterpret_cast<void *> (&l_myData);
+ (void) l_rc.setData(l_pMyData);
+
+ // Create a ReturnCode using the assignment operator
+ ReturnCode l_rc2;
+ l_rc2 = l_rc;
+
+ // Ensure that the two ReturnCodes are the same
+ if (l_rc != l_rc2)
+ {
+ TS_FAIL("testRc10. ReturnCodes differ");
+ }
+ else
+ {
+ // Ensure that releaseData retrieves the ReturnCodeData from l_rc
+ void * l_pMyDataCheck = l_rc.releaseData();
+
+ if (l_pMyDataCheck != l_pMyData)
+ {
+ TS_FAIL("testRc10. releaseData returned unexpected data ptr");
+ }
+ else
+ {
+ // Ensure that releaseData retrieves NULL from l_rc2
+ l_pMyDataCheck = NULL;
+ l_pMyDataCheck = l_rc2.releaseData();
+
+ if (l_pMyDataCheck != NULL)
+ {
+ TS_FAIL("testRc10. releaseData returned non NULL ptr");
+ }
+ }
+ }
+
+ return;
+ }
+
+
+
+};
+
+#endif
diff --git a/src/usr/hwpf/test/fapitargettest.H b/src/usr/hwpf/test/fapitargettest.H
new file mode 100644
index 000000000..6cd8fd9b8
--- /dev/null
+++ b/src/usr/hwpf/test/fapitargettest.H
@@ -0,0 +1,266 @@
+#ifndef __FAPITARGETTEST_H
+#define __FAPITARGETTEST_H
+
+/**
+ * @file fapitargettest.H
+ *
+ * @brief Test case for FAPI targets
+*/
+
+#include <cxxtest/TestSuite.H>
+#include <fapi.H>
+
+using namespace fapi;
+
+class FapiTargetTest: public CxxTest::TestSuite
+{
+public:
+
+ /**
+ * @brief Test target #1
+ */
+ void testTarget1()
+ {
+ // Create Target using default constructor
+ Target l_target;
+
+ // Ensure that the handle pointer is NULL
+ void * l_pHandle = l_target.get();
+
+ if (l_pHandle != NULL)
+ {
+ TS_FAIL("testTarget1. Handle is not NULL");
+ }
+ else
+ {
+ // Ensure that the type is TARGET_TYPE_NONE
+ TargetType l_type = l_target.getType();
+ if (l_type != TARGET_TYPE_NONE)
+ {
+ TS_FAIL("testTarget1. Type is not TARGET_TYPE_NONE");
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * @brief Test target #2
+ */
+ void testTarget2()
+ {
+ uint8_t l_handle = 7;
+ void * l_pHandle = reinterpret_cast<void *>(&l_handle);
+
+ // Create Target
+ Target l_target(TARGET_TYPE_DIMM, l_pHandle);
+
+ // Ensure that the handle pointer is as expected
+ void * l_pHandleCheck = l_target.get();
+
+ if (l_pHandleCheck != l_pHandle)
+ {
+ TS_FAIL("testTarget2. Handle is not as expected");
+ }
+ else
+ {
+ // Ensure that the type is TARGET_TYPE_DIMM
+ TargetType l_type = l_target.getType();
+
+ if (l_type != TARGET_TYPE_DIMM)
+ {
+ TS_FAIL("testTarget2. Type is not TARGET_TYPE_DIMM");
+ }
+ }
+
+ // Set the handle pointer to NULL to prevent any problem on destruction
+ l_target.set(NULL);
+
+ return;
+ }
+
+ /**
+ * @brief Test target #3
+ */
+ void testTarget3()
+ {
+ // Create Target using default constructor
+ Target l_target;
+
+ // Set the handle
+ uint8_t l_handle = 7;
+ void * l_pHandle = reinterpret_cast<void *>(&l_handle);
+ l_target.set(l_pHandle);
+
+ // Ensure that the handle pointer is as expected
+ void * l_pHandleCheck = l_target.get();
+
+ if (l_pHandleCheck != l_pHandle)
+ {
+ TS_FAIL("testTarget3. Handle is not as expected");
+ }
+ else
+ {
+ // Set the type
+ l_target.setType(TARGET_TYPE_DIMM);
+
+ // Ensure that the type is TARGET_TYPE_DIMM
+ TargetType l_type = l_target.getType();
+
+ if (l_type != TARGET_TYPE_DIMM)
+ {
+ TS_FAIL("testTarget3. Type is not TARGET_TYPE_DIMM");
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * @brief Test target #4
+ */
+ void testTarget4()
+ {
+ // Create Target
+ uint8_t l_handle = 7;
+ void * l_pHandle = reinterpret_cast<void *>(&l_handle);
+ Target l_target(TARGET_TYPE_DIMM, l_pHandle);
+
+ // Create Target using copy constructor
+ Target l_target2(l_target);
+
+ // Ensure that the target types are the same
+ TargetType l_type = l_target.getType();
+ TargetType l_type2 = l_target2.getType();
+
+ if (l_type != l_type2)
+ {
+ TS_FAIL("testTarget4. Types are not the same ");
+ }
+ else
+ {
+ // Ensure that the handles are the same
+ void * l_han1 = l_target.get();
+ void * l_han2 = l_target2.get();
+
+ if (l_han1 != l_han2)
+ {
+ TS_FAIL("testTarget4. Handles are not the same");
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * @brief Test target #5
+ */
+ void testTarget5()
+ {
+ // Create Target
+ uint8_t l_handle = 7;
+ void * l_pHandle = reinterpret_cast<void *>(&l_handle);
+ Target l_target(TARGET_TYPE_DIMM, l_pHandle);
+
+ // Create Target using assignment operator
+ Target l_target2;
+ l_target2 = l_target;
+
+ // Ensure that the target types are the same
+ TargetType l_type = l_target.getType();
+ TargetType l_type2 = l_target2.getType();
+
+ if (l_type != l_type2)
+ {
+ TS_FAIL("testTarget5. Types are not the same");
+ }
+ else
+ {
+ // Ensure that the handles are the same
+ void * l_han1 = l_target.get();
+ void * l_han2 = l_target2.get();
+
+ if (l_han1 != l_han2)
+ {
+ TS_FAIL("testTarget5. Handles are not the same");
+ }
+ }
+
+ return;
+ }
+
+ /**
+ * @brief Test target #6
+ */
+ void testTarget6()
+ {
+ // Create similar Targets
+ uint8_t l_handle = 7;
+ void * l_pHandle = reinterpret_cast<void *>(&l_handle);
+ Target l_target(TARGET_TYPE_DIMM, l_pHandle);
+ Target l_target2(TARGET_TYPE_DIMM, l_pHandle);
+
+ // Ensure that the equality comparison returns true
+ if (!(l_target == l_target2))
+ {
+ TS_FAIL("testTarget6. 1. Equality comparison false");
+ }
+ else
+ {
+ // Ensure that the inequality comparison returns false
+ if (l_target != l_target2)
+ {
+ TS_FAIL("testTarget6. 2. Inequality comparison true");
+ }
+ else
+ {
+ // Change the target type of l_target2
+ (void)l_target2.setType(TARGET_TYPE_PROC_CHIP);
+
+ // Ensure that the equality comparison returns false
+ if (l_target == l_target2)
+ {
+ TS_FAIL("testTarget6. 3. Equality comparison true");
+ }
+ else
+ {
+ // Ensure that the inequality comparison returns true
+ if (!(l_target != l_target2))
+ {
+ TS_FAIL("testTarget6. 4. Inequality comparison false");
+ }
+ else
+ {
+ // Reset the target type of l_target2
+ (void)l_target2.setType(TARGET_TYPE_DIMM);
+
+ // Change the handle of l_target
+ uint8_t l_handle2 = 7;
+ void * l_pHandle2 = reinterpret_cast<void *>(&l_handle2);
+ (void)l_target.set(l_pHandle2);
+
+ // Ensure that the equality comparison returns false
+ if (l_target == l_target2)
+ {
+ TS_FAIL("testTarget6. 5. Equality comparison true");
+ }
+ else
+ {
+ // Ensure that the inequality comparison returns true
+ if (!(l_target != l_target2))
+ {
+ TS_FAIL("testTarget6. 6. Inequality comparison "
+ "false");
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return;
+ }
+
+};
+
+#endif
diff --git a/src/usr/hwpf/test/hwpftest.H b/src/usr/hwpf/test/hwpftest.H
new file mode 100644
index 000000000..fa9a1c555
--- /dev/null
+++ b/src/usr/hwpf/test/hwpftest.H
@@ -0,0 +1,94 @@
+#ifndef __HWPFTEST_H
+#define __HWPFTEST_H
+
+/**
+ * @file hwpftest.H
+ *
+ * @brief Test case for HWPF implementation
+*/
+
+#include <cxxtest/TestSuite.H>
+#include <fapi.H>
+#include <fapiPlatHwpInvoker.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <targeting/targetservice.H>
+
+using namespace fapi;
+using namespace TARGETING;
+
+class HwpfTest: public CxxTest::TestSuite
+{
+public:
+
+ /**
+ * @brief Test HWPF trace
+ */
+ void testHwpf1()
+ {
+ // Trace into all the FAPI trace buffers
+ uint32_t l_val = 4;
+ const char * l_pStr = "test-str";
+
+ FAPI_INF("Test INF Trace");
+ FAPI_INF("Test INF Trace. hex: 0x%x", l_val);
+ FAPI_INF("Test INF Trace. string: %s", l_pStr);
+ FAPI_INF("Test INF Trace. 0x%x, %s", l_val, l_pStr);
+
+ FAPI_IMP("Test IMP Trace");
+ FAPI_IMP("Test IMP Trace. hex: 0x%x", l_val);
+ FAPI_IMP("Test IMP Trace. string: %s", l_pStr);
+ FAPI_IMP("Test IMP Trace. 0x%x, %s", l_val, l_pStr);
+
+ FAPI_ERR("Test ERR Trace");
+ FAPI_ERR("Test ERR Trace. hex: 0x%x", l_val);
+ FAPI_ERR("Test ERR Trace. string: %s", l_pStr);
+ FAPI_ERR("Test ERR Trace. 0x%x, %s", l_val, l_pStr);
+
+ FAPI_DBG("Test DBG Trace");
+ FAPI_DBG("Test DBG Trace. hex: 0x%x", l_val);
+ FAPI_DBG("Test DBG Trace. string: %s", l_pStr);
+ FAPI_DBG("Test DBG Trace. 0x%x, %s", l_val, l_pStr);
+
+ return;
+ }
+
+
+ /**
+ * @brief Test HWPF: calling a procedure
+ */
+ void testHwpf2()
+ {
+ // Call a test hardware procedure
+ errlHndl_t l_err = NULL;
+
+ // Set processor chip to the master
+ TARGETING::Target* l_testTarget = MASTER_PROCESSOR_CHIP_TARGET_SENTINEL;
+
+ // Call the hardware procedure
+ bool l_clocksOn = false;
+ l_err = invokeHwpIsP7EM0ChipletClockOn(l_testTarget, l_clocksOn);
+ if (l_err)
+ {
+ TS_FAIL("testHwpf2: Unit Test failed. HWP failed. Error logged");
+ // Commit/delete error
+ errlCommit(l_err);
+ }
+ else
+ {
+ if (l_clocksOn)
+ {
+ TS_TRACE("testHwpf2: Success. Clocks are on");
+ }
+ else
+ {
+ TS_TRACE("testHwpf2: Success. Clocks are off");
+ }
+ }
+
+ return;
+ }
+
+};
+
+#endif
diff --git a/src/usr/hwpf/test/makefile b/src/usr/hwpf/test/makefile
new file mode 100644
index 000000000..c32529276
--- /dev/null
+++ b/src/usr/hwpf/test/makefile
@@ -0,0 +1,11 @@
+ROOTPATH = ../../../..
+
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat
+
+MODULE = testhwpf
+TESTS = *.H
+
+include ${ROOTPATH}/config.mk
+
diff --git a/src/usr/makefile b/src/usr/makefile
index ec5d3d7e6..015970ebc 100644
--- a/src/usr/makefile
+++ b/src/usr/makefile
@@ -3,6 +3,6 @@ ROOTPATH = ../..
OBJS = module_init.o
SUBDIRS = example.d trace.d cxxtest.d testcore.d errl.d devicefw.d \
- scom.d xscom.d targeting.d initservice.d
+ scom.d xscom.d targeting.d initservice.d hwpf.d ecmddatabuffer.d
include ${ROOTPATH}/config.mk
diff --git a/src/usr/xscom/test/xscomtest.H b/src/usr/xscom/test/xscomtest.H
index 4627344b3..f1c7a017a 100644
--- a/src/usr/xscom/test/xscomtest.H
+++ b/src/usr/xscom/test/xscomtest.H
@@ -13,6 +13,8 @@
#include <errl/errltypes.H>
#include <devicefw/userif.H>
+extern trace_desc_t* g_trac_xscom;
+
using namespace TARGETING;
// Address and data to read/write
@@ -44,32 +46,25 @@ public:
*/
void testXscom1(void)
{
-
- //@todo - Replace printk with traces
-
TARGETING::Target* l_testTarget = MASTER_PROCESSOR_CHIP_TARGET_SENTINEL;
size_t l_size = sizeof(uint64_t);
// Loop thru table
+ errlHndl_t l_err = NULL;
for( uint32_t l_num=0; l_num < g_xscomAddrTableSz; l_num++)
{
testXscomAddrData l_testEntry = g_xscomAddrTable[l_num];
// Perform XSComOM read
uint64_t l_data = 0;
- errlHndl_t l_err = deviceRead(l_testTarget,
+ l_err = deviceRead(l_testTarget,
&l_data,
l_size,
DEVICE_SCOM_ADDRESS(l_testEntry.addr));
if (l_err)
{
- printk("\ntestXscom1: XSCom read: deviceRead() fails (1) !\n");
- }
- else
- {
- printk("\ntestXscom1: XSCom read (1) Address 0x%.8X, Data %llx\n\n\n",
- l_testEntry.addr,
- (long long unsigned)l_data);
+ TS_FAIL("testXscom1: XSCom read: deviceRead() fails! Error committed.");
+ break;
}
// Perform an XSCom write
@@ -81,15 +76,9 @@ public:
if (l_err)
{
- printk("\ntestXscom1: XSCom write: deviceWrite() fails!\n");
+ TS_FAIL("testXscom1: XSCom write: deviceWrite() fails!");
break;
}
- else
- {
- printk("\ntestXscom1: XSCom write Address 0x%.8X, Data %llx\n",
- l_testEntry.addr,
- (long long unsigned)l_testEntry.data);
- }
// Read back
l_data = 0;
@@ -99,16 +88,21 @@ public:
DEVICE_SCOM_ADDRESS(l_testEntry.addr));
if (l_err)
{
- printk("\ntestXscom1: XSCom read: deviceRead() fails (2) !\n");
- }
- else
- {
- printk("\ntestXscom1: XSCom read (2) Address 0x%.8X, Data %llx\n\n\n",
- l_testEntry.addr,
- (long long unsigned)l_data);
+ TS_FAIL("testXscom1: XSCom read back: deviceRead() fails!");
+ break;
}
- }
- return;
+ }
+
+ if (l_err)
+ {
+ TS_FAIL("testXscom1 failed! Error committed.");
+ errlCommit(l_err);
+ }
+ else
+ {
+ TS_TRACE("testXscom1 runs successfully!");
+ }
+ return;
}
};
diff --git a/src/usr/xscom/xscom.C b/src/usr/xscom/xscom.C
index c69a389c3..f06047a6d 100644
--- a/src/usr/xscom/xscom.C
+++ b/src/usr/xscom/xscom.C
@@ -15,6 +15,7 @@
#include <trace/interface.H>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
+#include <targeting/targetservice.H>
#include <xscom/xscomreasoncodes.H>
#include "xscom.H"
@@ -199,11 +200,22 @@ errlHndl_t xscomPerformOp(DeviceFW::OperationType i_opType,
io_buflen = 0;
// Setup the address
- // @todo: Hard code chipId and Base address for now
- XSComChipId_t l_chipId = 0;
- XSComBase_t l_XSComBaseAddr = 0x300000000000; // Node0,chip0, Simics map
- XSComP8Address l_mmioAddr(va_arg(i_args,uint64_t), l_chipId,
- l_XSComBaseAddr);
+
+ // Init values are for master processor, as PNOR may not
+ // yet available
+ XSComBase_t l_XSComBaseAddr = MASTER_PROC_XSCOM_BASE_ADDR;
+ TARGETING::XscomChipInfo l_xscomChipInfo = {0};
+ if (i_target != TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL)
+ {
+ l_XSComBaseAddr =
+ i_target->getAttr<TARGETING::ATTR_XSCOM_BASE_ADDRESS>();
+ l_xscomChipInfo =
+ i_target->getAttr<TARGETING::ATTR_XSCOM_CHIP_INFO>();
+ }
+
+ // Build the XSCom address
+ XSComP8Address l_mmioAddr(va_arg(i_args,uint64_t), l_xscomChipInfo.nodeId,
+ l_xscomChipInfo.chipId, l_XSComBaseAddr);
// Re-init l_retry for loop
l_retry = false;
@@ -215,22 +227,22 @@ errlHndl_t xscomPerformOp(DeviceFW::OperationType i_opType,
l_XSComMutex = mmio_xscom_mutex();
mutex_lock(l_XSComMutex);
- // Single XSCom read
- // Keep MMIO reading until XSCOM successfully done or error
+ // Calculate MMIO addr
+ uint64_t l_page = l_mmioAddr.page();
+ uint64_t l_offset_64 = (l_mmioAddr.offset()/sizeof(uint64_t));
+ uint64_t* l_virtAddr = static_cast<uint64_t*>
+ (mmio_map(reinterpret_cast<void*>(l_page), 1));
+
+ // Keep MMIO access until XSCOM successfully done or error
+ uint64_t l_data = 0;
do
{
// Reset status
resetHMERStatus();
- // Calculate MMIO addr
- uint64_t l_page = l_mmioAddr.page();
- uint64_t l_offset_64 = (l_mmioAddr.offset()/sizeof(uint64_t));
- uint64_t* l_virtAddr = static_cast<uint64_t*>
- (mmio_map(reinterpret_cast<void*>(l_page), 1));
-
// The dereferencing should handle Cache inhibited internally
// Use local variable and memcpy to avoid unaligned memory access
- uint64_t l_data = 0;
+ l_data = 0;
if (i_opType == DeviceFW::READ)
{
l_data = *(l_virtAddr + l_offset_64);
@@ -242,17 +254,13 @@ errlHndl_t xscomPerformOp(DeviceFW::OperationType i_opType,
*(l_virtAddr + l_offset_64) = l_data;
}
- // @todo - Need to un-map for now
- mmio_unmap(l_virtAddr, 1);
-
- TRACFCOMP(g_trac_xscom, "xscomPerformOp: OpType 0x%.8X, Address %llx, Page %llx; Offset %llx; VirtAddr %llx; l_virtAddr+l_offset %llx",
- i_opType, static_cast<uint64_t>(l_mmioAddr), l_page,
- l_offset_64, l_virtAddr, l_virtAddr + l_offset_64);
-
- // Check for error or done
+ // Check for error or done
l_hmer = waitForHMERStatus();
- } while (l_hmer.mXSComStatus == HMER::XSCOM_BLOCKED); // Single read
+ } while (l_hmer.mXSComStatus == HMER::XSCOM_BLOCKED);
+
+ // @todo - Need to un-map for now
+ mmio_unmap(l_virtAddr, 1);
// Unlock
mutex_unlock(l_XSComMutex);
@@ -260,6 +268,18 @@ errlHndl_t xscomPerformOp(DeviceFW::OperationType i_opType,
// Done, un-pin
task_affinity_unpin();
+ TRACFCOMP(g_trac_xscom, "xscomPerformOp: OpType 0x%.8X, Address %llx, Page %llx; Offset %llx; VirtAddr %llx; l_virtAddr+l_offset %llx",
+ i_opType, static_cast<uint64_t>(l_mmioAddr), l_page,
+ l_offset_64, l_virtAddr, l_virtAddr + l_offset_64);
+
+ if (i_opType == DeviceFW::READ)
+ {
+ TRACFCOMP(g_trac_xscom, "xscomPerformOp: Read data: %llx", l_data); }
+ else
+ {
+ TRACFCOMP(g_trac_xscom, "xscomPerformOp: Write data: %llx", l_data);
+ }
+
// Handle error
if (l_hmer.mXSComStatus != HMER::XSCOM_GOOD)
{
diff --git a/src/usr/xscom/xscom.H b/src/usr/xscom/xscom.H
index 22af50afe..cb2221be1 100644
--- a/src/usr/xscom/xscom.H
+++ b/src/usr/xscom/xscom.H
@@ -11,13 +11,20 @@
/**
* @brief Max number of retries if XSCOM fails with certain errors
*/
-#define MAX_XSCOM_RETRY 1
+#define MAX_XSCOM_RETRY 1
+
+/**
+ * @brief The (fixed) base address value for master proc
+ */
+//@todo - Verify this value for HW
+#define MASTER_PROC_XSCOM_BASE_ADDR 0x300000000000
/**
* @brief Type definition for XSCom address and Chip ID
*/
typedef uint32_t XSComAddress_t;
typedef uint16_t XSComChipId_t;
+typedef uint16_t XSComNodeId_t;
typedef uint64_t XSComBase_t;
namespace XSCOM
@@ -135,15 +142,15 @@ class XSComP8Address
* @brief Constructor of XSComP8Address class
*
* @param[in] i_addr PCB address of the register being accessed
- *
+ * @param[in] i_nodeId Node number where the processor chip resides
* @param[in] i_chipId Chip number of the processor chip that
* holds the register being accessed.
- *
* @param[in] i_mXSComBase Base address of XSCom address range.
*
* @return None
*/
ALWAYS_INLINE inline XSComP8Address(const XSComAddress_t i_addr,
+ const XSComNodeId_t i_nodeId,
const XSComChipId_t i_chipId,
const XSComBase_t i_mXSComBase);
@@ -181,7 +188,8 @@ class XSComP8Address
{
uint64_t mReserved1:18; // Not currently used (0:17)
uint64_t mBaseAddress:5; // Base address (18:22)
- uint64_t mChipId:6; // Targeted chip ID (23:28)
+ uint64_t mNodeId:3; // Node where target resides (23:25)
+ uint64_t mChipId:3; // Targeted chip ID (26:28)
uint64_t mSComAddrHi:27; // PCB Address High (29:55)
uint64_t mCacheLine:1; // Cached line (56)
uint64_t mSComAddrLo:4; // PCB Address low (57:60)
@@ -198,10 +206,12 @@ class XSComP8Address
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
XSComP8Address::XSComP8Address(const XSComAddress_t i_addr,
+ const XSComNodeId_t i_nodeId,
const XSComChipId_t i_chipId,
const XSComBase_t i_mXSComBase)
:mMmioAddress(i_mXSComBase)
{
+ mAddressParts.mNodeId = i_nodeId;
mAddressParts.mChipId = i_chipId;
mAddressParts.mSComAddrHi = i_addr >> 4; // Get 27-bits
mAddressParts.mSComAddrLo = i_addr; // Get 4 bits
OpenPOWER on IntegriCloud