diff options
author | Thi Tran <thi@us.ibm.com> | 2011-06-28 11:17:12 -0500 |
---|---|---|
committer | Thi N. Tran <thi@us.ibm.com> | 2011-06-30 08:19:52 -0500 |
commit | e93bda2d2a30ff9959384dce0563ab143bc30aad (patch) | |
tree | dea7e740ae61ae2fe343823ad31654fbce6992bf /src | |
parent | a4809cd65ce96d0b56ec316b14836087cf1d647b (diff) | |
download | talos-hostboot-e93bda2d2a30ff9959384dce0563ab143bc30aad.tar.gz talos-hostboot-e93bda2d2a30ff9959384dce0563ab143bc30aad.zip |
Initial HWPF delivery
Update after pass-around review
Change-Id: I8f81dd7820b61607e9a98d17c81e74fface42c54
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/160
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
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 |