diff options
-rw-r--r-- | src/include/usr/devicefw/driverif.H | 85 | ||||
-rw-r--r-- | src/include/usr/devicefw/userif.H | 45 | ||||
-rw-r--r-- | src/include/usr/errl/errlreasoncodes.H | 11 | ||||
-rw-r--r-- | src/include/usr/errl/errludlogregister.H | 325 | ||||
-rw-r--r-- | src/include/usr/errl/errludparserfactoryerrl.H | 2 | ||||
-rw-r--r-- | src/include/usr/errl/hberrltypes.H | 1 | ||||
-rw-r--r-- | src/usr/devicefw/driverif.C | 85 | ||||
-rw-r--r-- | src/usr/devicefw/userif.C | 45 | ||||
-rw-r--r-- | src/usr/errl/errludlogregister.C | 382 | ||||
-rw-r--r-- | src/usr/errl/makefile | 2 | ||||
-rw-r--r-- | src/usr/errl/test/errluserdetailtest.H | 243 | ||||
-rw-r--r-- | src/usr/fsi/fsidd.C | 2 | ||||
-rw-r--r-- | src/usr/fsi/fsipres.C | 2 |
13 files changed, 1111 insertions, 119 deletions
diff --git a/src/include/usr/devicefw/driverif.H b/src/include/usr/devicefw/driverif.H index b17515abc..219644190 100644 --- a/src/include/usr/devicefw/driverif.H +++ b/src/include/usr/devicefw/driverif.H @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/include/usr/devicefw/driverif.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/include/usr/devicefw/driverif.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2011-2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ /** @file driverif.H * @brief Provides the device driver interfaces for performing device access * and enabling routing registration. @@ -233,6 +234,31 @@ namespace DeviceFW // the explicit template specializations. } + /** + * @brief Perform a device operation by routing through the framework and + * calling the appropriate registered operation. + * + * @param[in] i_opType - Operation request (READ vs WRITE). + * @param[in] i_target - Target to perform operation on. + * @param[in,out] io_buffer - Data buffer for operation. + * @param[in,out] io_buflen - Length of buffer / result size. + * @param[in] i_accessType - Type of hardware access method to perform. + * @param[in] i_args - va_list of parameters for device operation. + * + * This function has similar behavior as the user-visible deviceRead and + * deviceWrite functions and is meant as a method for device drivers to + * perform accesses which may be only visible to internal drivers. + */ + template <typename AccType> + errlHndl_t deviceOpValist(OperationType i_opType, + TARGETING::Target* i_target, + void* io_buffer, size_t& io_buflen, + AccType i_accessType, va_list i_args) + { + return InvalidParameterType(); // Cause a compile fail if not one of + // the explicit template specializations. + } + // --- Below are template specializations to aid in type-safety. --- // deviceRegisterRoute: @@ -296,6 +322,21 @@ namespace DeviceFW void* io_buffer, size_t& io_buflen, AccessType_DriverOnly i_accessType, ...); + // deviceOpValist: + // OpType - OperationType only. + // TargType - TargetType only. + // AccType - AccessType, AccessType_DriverOnly (no WILDCARD). + // args - va_list of parameters + template <> + errlHndl_t deviceOpValist<>(OperationType i_opType, + TARGETING::Target* i_target, + void* io_buffer, size_t& io_buflen, + AccessType i_accessType, va_list i_args); + template <> + errlHndl_t deviceOpValist<>(OperationType i_opType, + TARGETING::Target* i_target, + void* io_buffer, size_t& io_buflen, + AccessType_DriverOnly i_accessType, va_list i_args); }; #endif diff --git a/src/include/usr/devicefw/userif.H b/src/include/usr/devicefw/userif.H index 4c7a116dd..5fa17dae7 100644 --- a/src/include/usr/devicefw/userif.H +++ b/src/include/usr/devicefw/userif.H @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/include/usr/devicefw/userif.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/include/usr/devicefw/userif.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2011-2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ /** @file userif.H * @brief Provides the user application interfaces for performing device * access. diff --git a/src/include/usr/errl/errlreasoncodes.H b/src/include/usr/errl/errlreasoncodes.H index 6bff54568..fda12fcf9 100644 --- a/src/include/usr/errl/errlreasoncodes.H +++ b/src/include/usr/errl/errlreasoncodes.H @@ -45,12 +45,13 @@ enum // Reason codes for ERRL component enum errlReasonCode { - HBERRL_FIRST_ERR = HBERRL_COMP_ID | 0x01, - HBERRL_TEST_STRING_UD = HBERRL_COMP_ID | 0x02, - HBERRL_TEST_REASON_CODE = HBERRL_COMP_ID | 0x03, - HBERRL_TEST_ATTRIBUTE_UD = HBERRL_COMP_ID | 0x04, + HBERRL_FIRST_ERR = HBERRL_COMP_ID | 0x01, + HBERRL_TEST_STRING_UD = HBERRL_COMP_ID | 0x02, + HBERRL_TEST_REASON_CODE = HBERRL_COMP_ID | 0x03, + HBERRL_TEST_ATTRIBUTE_UD = HBERRL_COMP_ID | 0x04, + HBERRL_TEST_LOGREGISTER_UD = HBERRL_COMP_ID | 0x05, //........ - HBERRL_LAST_ERR = HBERRL_COMP_ID | 0xFF + HBERRL_LAST_ERR = HBERRL_COMP_ID | 0xFF }; diff --git a/src/include/usr/errl/errludlogregister.H b/src/include/usr/errl/errludlogregister.H new file mode 100644 index 000000000..27e4c4bb8 --- /dev/null +++ b/src/include/usr/errl/errludlogregister.H @@ -0,0 +1,325 @@ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/include/usr/errl/errludlogregister.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ +#ifndef ERRL_UDLOGREGISTER_H +#define ERRL_UDLOGREGISTER_H + +/** + * @file errludlogregister.H + * + * Defines the following classes: + * + * ErrlUserDetailsLogRegister: Adds register FFDC to an error log as + * user detail data + * ErrlUserDetailsParserLogRegister: Parses register FFDC user detail in + * an error log +*/ + +#include <errl/errluserdetails.H> + +#ifndef PARSER + +// Forward reference +namespace TARGETING +{ + class Target; +} + +#include <devicefw/userif.H> + +namespace ERRORLOG +{ + +/** + * @class ErrlUserDetailsLogRegister + * + * Adds LogRegister FFDC to an error log as user detail data + */ +class ErrlUserDetailsLogRegister : public ErrlUserDetails +{ +public: + /** + * @brief Constructor - target only + * + * @param[in] i_pTarget - target of the register reads + * + * Creates a LogRegister UserDetail, storing the HUID. User will + * next need to call addData() in order to get data into this object, + * and addToLog() in order to push the data to the error log. + * + */ + ErrlUserDetailsLogRegister(TARGETING::Target * i_pTarget); + + /** + * @brief Constructor - target and register type/address + * + * @param[in] i_pTarget - target of the register reads + * @param[in] i_accessType - type of register access + * @param[in] ... - these are generated by the devicefw/userif.H + * macros (ie, DEVICE_SCOM_ADDRESS). + * + * Creates a LogRegister UserDetail, storing the HUID, and perform + * the deviceOp() of the specified register type and address, storing + * that (type and address) as well as the result in this object. + * + * Note that this can only be used for devicefw/userif.H register + * interface (DeviceFW::AccessType) types. + * + */ + ErrlUserDetailsLogRegister(TARGETING::Target * i_pTarget, + DeviceFW::AccessType i_accessType, ...); + + /** + * @brief Constructor - target, register type/address and data + * + * @param[in] i_pTarget - target of the register reads + * @param[in] i_dataBuf - pointer to area with register data + * @param[in] i_dataSize - size of data pointed at by i_dataBuf + * @param[in] i_accessType - type of register access + * @param[in] ... - these are generated by the devicefw/userif.H + * macros (ie, DEVICE_SCOM_ADDRESS). + * + * Creates a LogRegister UserDetail, storing the HUID, and stores + * the register type and address, as well as the passed-in result + * in this object. The deviceOp() operation is NOT performed UNLESS + * i_dataBuf is NULL. + * + * Note that this can only be used for devicefw/userif.H register + * interface (DeviceFW::AccessType) types. + */ + ErrlUserDetailsLogRegister(TARGETING::Target * i_pTarget, + void *i_dataBuf, + size_t i_dataSize, + DeviceFW::AccessType i_accessType, ...); + + /** + * + * @brief addData - do the register read and store the data + * + * @param[in] i_accessType - type of register access + * @param[in] ... - these are generated by the devicefw/userif.H + * macros (ie, DEVICE_SCOM_ADDRESS). + * + * Performs the deviceOp() of the specified register type and address, + * storing that (type and address) as well as the result in this object. + * + * The template allows for userif.H AND deviceif.H register interfaces + * to be used. (ie, DeviceFW::AccessType_DriverOnly in addition to + * DeviceFW::AccessType). + */ + template <typename ACCESS_TYPE> + void addData(ACCESS_TYPE i_accessType, ...); + + /** + * + * @brief addDataBuffer - store the buffer of register data + * + * @param[in] i_dataBuf - pointer to buffer with register data + * @param[in] i_dataSize - size of buffer pointed at by i_dataBuf + * @param[in] i_accessType - type of register access + * @param[in] ... - these are generated by the devicefw/userif.H + * macros (ie, DEVICE_SCOM_ADDRESS). + * + * Stores the specified register type and address, as well as the + * passed-in result in this object. The deviceOp() operation is NOT + * performed UNLESS i_dataBuf is NULL. + * + * The template allows for userif.H AND deviceif.H register interfaces + * to be used. (ie, DeviceFW::AccessType_DriverOnly in addition to + * DeviceFW::AccessType). + */ + template <typename ACCESS_TYPE> + void addDataBuffer(void *i_dataBuf, size_t i_dataSize, + ACCESS_TYPE i_accessType, ...); + + /** + * @brief Destructor + */ + virtual ~ErrlUserDetailsLogRegister() { }; + +private: + // Disabled + ErrlUserDetailsLogRegister(const ErrlUserDetailsLogRegister &); + ErrlUserDetailsLogRegister & operator=(const ErrlUserDetailsLogRegister &); + + // internal functions: + + /** + * + * @brief setStateLogHUID - set state and log HUID. + * + * Worker function that will set the ErrlUserDetails instance variables + * and puts the HUID into the error log. + */ + void setStateLogHUID(); + + /** + * + * @brief writeRegisterData - write the register data to the log + * + * @param[in] i_dataBuf - pointer to buffer with register data + * @param[in] i_dataSize - size of buffer pointed at by i_dataBuf + * @param[in] i_numAddressArgs - number of arguments in i_args va_list + * @param[in] i_accessType - type of register access + * @param[in] i_args - va_list of parameters of device access method + * + * Worker function that will write the register data (access type and + * deviceOp() parameters, and contents of the register) to the error + * log. + */ + void writeRegisterData(void *i_dataBuf, size_t i_dataSize, + int32_t i_numAddressArgs, + uint8_t i_accessType, va_list i_args); + + /** + * + * @brief readRegister - worker function to do and log the deviceOp() + * + * @param[in] i_accessType - type of register access + * @param[in] i_args - these are generated by the devicefw/userif.H + * macros (ie, DEVICE_SCOM_ADDRESS). + * + * Performs the deviceOp() of the specified register type and address, + * storing that (type and address) as well as the result in this object. + * This is called by the addData() and constructor that do not have + * passed-in register data. + */ + void readRegister(uint8_t i_accessType, va_list i_args); + + /** + * + * @brief copyRegisterData - worker function to log the register data + * + * @param[in] i_dataBuf - pointer to area with register data + * @param[in] i_dataSize - size of data pointed at by i_dataBuf + * @param[in] i_accessType - type of register access + * @param[in] i_args - these are generated by the devicefw/userif.H + * macros (ie, DEVICE_SCOM_ADDRESS). + * + * Stores the specified register type and address, as well as the + * passed-in result in this object. The deviceOp() operation is NOT + * performed. + * This is called by the addDataBuffer() and constructor that have the + * passed-in register data. + */ + void copyRegisterData(void *i_dataBuf, size_t i_dataSize, + uint8_t i_accessType, va_list i_args); + + /** + * + * @brief __addData - do the register read and store the data + * + * @param[in] i_accessType - type of register access + * @param[in] ... - these are generated by the devicefw/userif.H + * macros (ie, DEVICE_SCOM_ADDRESS). + * + * Performs the deviceOp() of the specified register type and address, + * storing that (type and address) as well as the result in this object. + * + * This is the actual function that does the work, where the AccessType + * and AccessType_DriverOnly enum is used as a generic uint8_t. The + * public addData() template functions are aliased to this function. + */ + void __addData(uint8_t i_accessType, ...); + + /** + * + * @brief addDataBuffer - store the buffer of register data + * + * @param[in] i_dataBuf - pointer to buffer with register data + * @param[in] i_dataSize - size of data pointed at by i_dataBuf + * @param[in] i_accessType - type of register access + * @param[in] ... - these are generated by the devicefw/userif.H + * macros (ie, DEVICE_SCOM_ADDRESS). + * + * Stores the specified register type and address, as well as the + * passed-in result in this object. The deviceOp() operation is NOT + * performed. + * + * This is the actual function that does the work, where the AccessType + * and AccessType_DriverOnly enum is used as a generic uint8_t. The + * public addDataBuffer() template functions are aliased to this function. + */ + void __addDataBuffer(void *i_dataBuf, size_t i_dataSize, + uint8_t i_accessType, ...); + + // allow for multiple calls to addData by user + TARGETING::Target * iv_pTarget; + uint32_t iv_dataSize; +}; + +} + +#else // (if PARSER defined) + +namespace ERRORLOG +{ + +/** + * @class ErrlUserDetailsLogRegister + * + * Parses LogRegister user detail in an error log +*/ +class ErrlUserDetailsParserLogRegister : public ErrlUserDetailsParser +{ +public: + /** + * @brief Constructor + */ + ErrlUserDetailsParserLogRegister() {} + + /** + * @brief Destructor + */ + virtual ~ErrlUserDetailsParserLogRegister() {} + + /** + * @brief Parses register user detail data from an error log + * + * @param i_version Version of the data + * @param i_parse ErrlUsrParser object for outputting information + * @param i_pBuffer Pointer to buffer containing detail data + * @param i_buflen Length of the buffer + */ + virtual void parse(errlver_t i_version, + ErrlUsrParser & i_parser, + void * i_pBuffer, + const uint32_t i_buflen) const + { + // TODO fix when parser if fix + // RTC 41707 + } + +private: + // Disabled + ErrlUserDetailsParserLogRegister(const ErrlUserDetailsParserLogRegister &); + ErrlUserDetailsParserLogRegister & operator=( + const ErrlUserDetailsParserLogRegister &); +}; + +} + +#endif + +#endif + diff --git a/src/include/usr/errl/errludparserfactoryerrl.H b/src/include/usr/errl/errludparserfactoryerrl.H index f535b562d..b38059465 100644 --- a/src/include/usr/errl/errludparserfactoryerrl.H +++ b/src/include/usr/errl/errludparserfactoryerrl.H @@ -34,6 +34,7 @@ #include <errl/errludtarget.H> #include <errl/errludbacktrace.H> #include <errludattribute.H> +#include <errl/errludlogregister.H> #include <errl/errludparserfactory.H> namespace ERRORLOG @@ -58,6 +59,7 @@ public: registerParser<ErrlUserDetailsParserTarget>(HBERRL_UDT_TARGET); registerParser<ErrlUserDetailsParserBackTrace>(HBERRL_UDT_BACKTRACE); registerParser<ErrlUserDetailsParserAttribute>(HBERRL_UDT_ATTRIBUTE); + registerParser<ErrlUserDetailsParserLogRegister>(HBERRL_UDT_LOGREGISTER); } private: diff --git a/src/include/usr/errl/hberrltypes.H b/src/include/usr/errl/hberrltypes.H index 2328bd6e3..b9727a694 100644 --- a/src/include/usr/errl/hberrltypes.H +++ b/src/include/usr/errl/hberrltypes.H @@ -51,6 +51,7 @@ enum errlUserDataType_t HBERRL_UDT_TARGET = 2, HBERRL_UDT_BACKTRACE = 3, HBERRL_UDT_ATTRIBUTE = 4, + HBERRL_UDT_LOGREGISTER = 5, }; diff --git a/src/usr/devicefw/driverif.C b/src/usr/devicefw/driverif.C index 2536bddf0..9cfb79251 100644 --- a/src/usr/devicefw/driverif.C +++ b/src/usr/devicefw/driverif.C @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/devicefw/driverif.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/devicefw/driverif.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2011-2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ /** @file driverif.C * Implement the template specializations of functions from driverif.H. */ @@ -159,4 +160,44 @@ namespace DeviceFW AccessType_DriverOnly i_accessType, ...) __attribute__((alias("DeviceFW_deviceOp"))); + /** @brief Wrapper function to call singleton instance for performOp. + * + * This is defined as an extern "C" function so that it can be aliased + * by the template type-safe implementations of deviceOpValist(). + * This causes the compiler to generate just a single copy of the code. + */ + extern "C" + errlHndl_t DeviceFW_deviceOpValist(OperationType i_opType, + TARGETING::Target* i_target, + void* io_buffer, size_t& io_buflen, + int64_t i_accessType, va_list i_args) + { + errlHndl_t errl; + + errl = Singleton<Associator>::instance().performOp( + i_opType, i_target, io_buffer, io_buflen, + i_accessType, i_args); + + return errl; + } + + // deviceOpValist: + // OpType - OperationType only. + // TargType - TargetType only. + // AccType - AccessType, AccessType_DriverOnly (no WILDCARD). + // args - va_list of parameters + template <> + errlHndl_t deviceOpValist<>(OperationType i_opType, + TARGETING::Target* i_target, + void* io_buffer, size_t& io_buflen, + AccessType i_accessType, va_list i_args) + __attribute__((alias("DeviceFW_deviceOpValist"))); + + template <> + errlHndl_t deviceOpValist<>(OperationType i_opType, + TARGETING::Target* i_target, + void* io_buffer, size_t& io_buflen, + AccessType_DriverOnly i_accessType, va_list i_args) + __attribute__((alias("DeviceFW_deviceOpValist"))); + }; diff --git a/src/usr/devicefw/userif.C b/src/usr/devicefw/userif.C index 5955d13d0..130c090d1 100644 --- a/src/usr/devicefw/userif.C +++ b/src/usr/devicefw/userif.C @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/devicefw/userif.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/devicefw/userif.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2011-2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ /** @file driverif.C * Implement the functions from userif.H. */ diff --git a/src/usr/errl/errludlogregister.C b/src/usr/errl/errludlogregister.C new file mode 100644 index 000000000..a16c291f8 --- /dev/null +++ b/src/usr/errl/errludlogregister.C @@ -0,0 +1,382 @@ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/errl/errludlogregister.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ +/** + * @file errludlogregister.C + * + * @brief Implementation of ErrlUserDetailsLogRegister + */ +#include <errl/errludlogregister.H> + +#include <targeting/common/targetservice.H> +#include <targeting/common/util.H> +#include <targeting/common/trace.H> + +#include <devicefw/driverif.H> + +namespace ERRORLOG +{ + +using namespace TARGETING; + +extern TARG_TD_t g_trac_errl; + +// internal function: +void ErrlUserDetailsLogRegister::setStateLogHUID() +{ + // Set up ErrlUserDetails instance variables + iv_CompId = HBERRL_COMP_ID; + iv_Version = 1; + iv_SubSection = HBERRL_UDT_LOGREGISTER; + + // override the default of false. + iv_merge = true; + + // write the HUID of the target into the error log buffer + uint32_t attrHuid = get_huid(iv_pTarget); + char *pBuf; + pBuf = reinterpret_cast<char *>(reallocUsrBuf(sizeof(attrHuid))); + memcpy(pBuf, &attrHuid, sizeof(attrHuid)); + iv_dataSize += sizeof(attrHuid); + +} // setStateLogHUID + +// internal function: +void ErrlUserDetailsLogRegister::writeRegisterData( + void *i_dataBuf, size_t i_dataSize, + int32_t i_numAddressArgs, + uint8_t i_accessType, va_list i_args) +{ + + uint64_t regParam[i_numAddressArgs]; + for (int32_t i = 0;i < i_numAddressArgs;i++) + { + regParam[i] = va_arg(i_args, uint64_t); + } // for + + // write the data into the buffer; format is: + // i_accessType, regParam[i], uint8_t(i_dataSize), i_dataBuf + uint32_t newSize = sizeof(i_accessType) + + sizeof(regParam) + + sizeof(uint8_t) + + i_dataSize; + + uint8_t *pBuf; + pBuf = reinterpret_cast<uint8_t *>(reallocUsrBuf(iv_dataSize + newSize)); + memcpy(pBuf + iv_dataSize, &i_accessType, sizeof(i_accessType) ); + iv_dataSize += sizeof(i_accessType); + for (int32_t i = 0;i < i_numAddressArgs;i++) + { + memcpy(pBuf + iv_dataSize, ®Param[i], sizeof(regParam[i]) ); + iv_dataSize += sizeof(regParam[i]); + } // for + uint8_t regSize = (uint8_t)i_dataSize; + memcpy(pBuf + iv_dataSize, ®Size, sizeof(regSize) ); + iv_dataSize += sizeof(regSize); + if (i_dataSize > 0) + { + memcpy(pBuf + iv_dataSize, i_dataBuf, i_dataSize); + iv_dataSize += i_dataSize; + } +} // writeRegisterData + +// internal function: +void ErrlUserDetailsLogRegister::readRegister( + uint8_t i_accessType, va_list i_args) +{ + // we allow 0 in case there is some future type that has no parameter. + // (DeviceFW::PRESENT is an example, but we chose not to log that type) + int32_t numAddressArgs = -1; + + // do we do the deviceOpValist or not, and how many + // parameters are there to be logged + switch (i_accessType) + { + // one parameter + case DeviceFW::SCOM: // userif.H + case DeviceFW::FSI: // userif.H + case DeviceFW::SPD: // userif.H + case DeviceFW::XSCOM: // driverif.H + case DeviceFW::FSISCOM: // driverif.H + { + numAddressArgs = 1; + break; + } + // two parameters + case DeviceFW::MVPD: // userif.H + case DeviceFW::EEPROM: // driverif.H + { + numAddressArgs = 2; + break; + } + // three parameters + case DeviceFW::I2C: // driverif.H + { + numAddressArgs = 3; + break; + } + // not logged! + case DeviceFW::PRESENT: // userif.H + case DeviceFW::PNOR: // userif.H + case DeviceFW::MAILBOX: // userif.H + default: + { // no action - not logged + TRACFCOMP(g_trac_errl, "LogRegister: AccessType %x not logged", + i_accessType); + break; + } // default + } // switch i_accessType + + if (numAddressArgs != -1) + { + // place for register data to go, and (max) size we expect. + uint64_t reg_data = 0; + size_t reg_size = sizeof(reg_data); + + TRACDCOMP(g_trac_errl, "LogRegister: deviceOpValist()"); + errlHndl_t errl; + errl = DeviceFW::deviceOpValist(DeviceFW::READ, iv_pTarget, + ®_data, reg_size, + (DeviceFW::AccessType) i_accessType, i_args); + + if (unlikely(errl != NULL)) + { // error! + TRACFCOMP(g_trac_errl, "LogRegister: deviceOpValist type %d" + " threw errl! deleting errl.", + i_accessType); + delete errl; // eat the error - just delete it + + reg_size = 0; // in case deviceOpValist didn't reset + } + + // internal worker function to put reg data into the log + writeRegisterData(®_data, reg_size, numAddressArgs, + i_accessType, i_args); + TRACDCOMP(g_trac_errl, "LogRegister: iv_dataSize %d", iv_dataSize); + } +} // readRegister + +// internal function: +void ErrlUserDetailsLogRegister::copyRegisterData( + void *i_dataBuf, size_t i_dataSize, + uint8_t i_accessType, va_list i_args) +{ + // we allow 0 in case there is some future type that has no parameter. + // (DeviceFW::PRESENT is an example, but we chose not to log that type) + int32_t numAddressArgs = -1; + + // do we do the deviceOpValist or not, and how many + // parameters are there to be logged + switch (i_accessType) + { + // one parameter + case DeviceFW::SCOM: // userif.H + case DeviceFW::FSI: // userif.H + case DeviceFW::SPD: // userif.H + case DeviceFW::XSCOM: // driverif.H + case DeviceFW::FSISCOM: // driverif.H + { + numAddressArgs = 1; + break; + } + // two parameters + case DeviceFW::MVPD: // userif.H + case DeviceFW::EEPROM: // driverif.H + { + numAddressArgs = 2; + break; + } + // three parameters + case DeviceFW::I2C: // driverif.H + { + numAddressArgs = 3; + break; + } + // not logged! + case DeviceFW::PRESENT: // userif.H + case DeviceFW::PNOR: // userif.H + case DeviceFW::MAILBOX: // userif.H + default: + { // no action - not logged + TRACFCOMP(g_trac_errl, "LogRegister: AccessType %x not logged", + i_accessType); + break; + } // default + } // switch i_accessType + + if (numAddressArgs != -1) + { + // internal worker function to put reg data into the log + writeRegisterData(i_dataBuf, i_dataSize, numAddressArgs, + i_accessType, i_args); + TRACDCOMP(g_trac_errl, "LogRegister: iv_dataSize %d", iv_dataSize); + } +} // copyRegisterData + +//------------------------------------------------------------------------------ +/* + * The public addData() function are templates allowing i_accesstype to change: + * either the DeviceFW::AccessType values in devicefw/userif.H + * OR the DeviceFW::AccessType_DriverOnly values in devicefw/driverif.H + * We don't want to include driverif.H in the errludlogregister.H file, so + * we do the template. + * + * We don't want/need to include a different separate addData() for each of + * those instances tho, so we create one __addData() function, and then use + * this alias to have both public template functions point to this function. + * + * This function will call the readRegister() function to log and do the read. + */ +template <> +void ErrlUserDetailsLogRegister::addData<>( + DeviceFW::AccessType i_accessType, ...) +__attribute__((alias("_ZN8ERRORLOG26ErrlUserDetailsLogRegister9__addDataEhz"))); +template <> +void ErrlUserDetailsLogRegister::addData<>( + DeviceFW::AccessType_DriverOnly i_accessType, ...) +__attribute__((alias("_ZN8ERRORLOG26ErrlUserDetailsLogRegister9__addDataEhz"))); + +void ErrlUserDetailsLogRegister::__addData( + uint8_t i_accessType, ...) +{ + TRACDCOMP(g_trac_errl, "LogRegister::addData: type %x", + i_accessType); + + // get the data - do the read + va_list args; + va_start(args, i_accessType); + readRegister(i_accessType, args); + va_end(args); + +} // __addData + +/* + * Same as above with regards to templates and alias. + * + * This function will just store the passed-in data, unless it's NULL. + */ +template <> +void ErrlUserDetailsLogRegister::addDataBuffer<>( + void *i_dataBuf, size_t i_dataSize, + DeviceFW::AccessType i_accessType, ...) +__attribute__((alias("_ZN8ERRORLOG26ErrlUserDetailsLogRegister15__addDataBufferEPvmhz"))); +template <> +void ErrlUserDetailsLogRegister::addDataBuffer<>( + void *i_dataBuf, size_t i_dataSize, + DeviceFW::AccessType_DriverOnly i_accessType, ...) +__attribute__((alias("_ZN8ERRORLOG26ErrlUserDetailsLogRegister15__addDataBufferEPvmhz"))); + +void ErrlUserDetailsLogRegister::__addDataBuffer( + void *i_dataBuf, size_t i_dataSize, + uint8_t i_accessType, ...) +{ + TRACDCOMP(g_trac_errl, "LogRegister::addDataBuffer: type %x from %p size %d", + i_accessType, i_dataBuf, i_dataSize); + + // if there's data, just copy it thru. + if (i_dataBuf != NULL) + { + // get the data - do the copy + va_list args; + va_start(args, i_accessType); + copyRegisterData(i_dataBuf, i_dataSize, i_accessType, args); + va_end(args); + } + else + { // user didn't give us any data - + // get the data ourselves - do the read + va_list args; + va_start(args, i_accessType); + readRegister(i_accessType, args); + va_end(args); + } +} // __addDataBuffer + + +//------------------------------------------------------------------------------ +ErrlUserDetailsLogRegister::ErrlUserDetailsLogRegister( + TARGETING::Target * i_pTarget) + : iv_pTarget(i_pTarget), iv_dataSize(0) +{ + TRACDCOMP(g_trac_errl, "LogRegister: target %p", + i_pTarget); + + setStateLogHUID(); + + // done - user will have to do addData() or addDataBuffer() calls. +} // ctor with target only + +//------------------------------------------------------------------------------ +ErrlUserDetailsLogRegister::ErrlUserDetailsLogRegister( + TARGETING::Target * i_pTarget, + DeviceFW::AccessType i_accessType, ...) + : iv_pTarget(i_pTarget), iv_dataSize(0) +{ + TRACDCOMP(g_trac_errl, "LogRegister: target %p type %x", + i_pTarget, i_accessType); + + setStateLogHUID(); + + // get the data - do the read + va_list args; + va_start(args, i_accessType); + readRegister(i_accessType, args); + va_end(args); + +} // ctor with target and register type/address + +//------------------------------------------------------------------------------ +ErrlUserDetailsLogRegister::ErrlUserDetailsLogRegister( + TARGETING::Target * i_pTarget, + void *i_dataBuf, + size_t i_dataSize, + DeviceFW::AccessType i_accessType, ...) + : iv_pTarget(i_pTarget), iv_dataSize(0) +{ + TRACDCOMP(g_trac_errl, "LogRegister: target %p type %x dataBuf %p size %d", + i_pTarget, i_accessType, + i_dataBuf, i_dataSize + ); + + setStateLogHUID(); + + // if there's data, just copy it thru. + if (i_dataBuf != NULL) + { + // get the data - do the copy + va_list args; + va_start(args, i_accessType); + copyRegisterData(i_dataBuf, i_dataSize, i_accessType, args); + va_end(args); + } + else + { // user didn't give us any data - + // get the data ourselves - do the read + va_list args; + va_start(args, i_accessType); + readRegister(i_accessType, args); + va_end(args); + } +} // ctor with target, register type/address and already-read data + +} diff --git a/src/usr/errl/makefile b/src/usr/errl/makefile index 0a12e57f0..72f9ab76f 100644 --- a/src/usr/errl/makefile +++ b/src/usr/errl/makefile @@ -25,7 +25,7 @@ MODULE = errl OBJS = errlentry.o errlmanager.o errlsctn.o errlsctnhdr.o errlprvt.o errluh.o \ errlud.o errlsrc.o errluserdetails.o backtrace.o errludtarget.o \ - errludstring.o errludbacktrace.o errludattribute.o + errludstring.o errludbacktrace.o errludattribute.o errludlogregister.o SUBDIRS = test.d parser.d diff --git a/src/usr/errl/test/errluserdetailtest.H b/src/usr/errl/test/errluserdetailtest.H index a4a507692..2adeefd86 100644 --- a/src/usr/errl/test/errluserdetailtest.H +++ b/src/usr/errl/test/errluserdetailtest.H @@ -1,25 +1,26 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/errl/test/errluserdetailtest.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/errl/test/errluserdetailtest.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2011-2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __TEST_ERRLUSERDETAILSTEST_H #define __TEST_USERUSERDETAILSTEST_H @@ -37,12 +38,15 @@ #include <errl/errludstring.H> #include <errl/errludbacktrace.H> #include <errl/errludtarget.H> +#include <errl/errludlogregister.H> #include <errludattribute.H> #include <targeting/common/targetservice.H> #include <targeting/common/iterators/rangefilter.H> #include <targeting/common/predicates/predicates.H> #include <targeting/common/util.H> +#include <devicefw/driverif.H> + using namespace ERRORLOG; class UtilErrlUsrDataTest: public CxxTest::TestSuite @@ -246,8 +250,201 @@ public: // commit the errorlog errlCommit(errl, CXXTEST_COMP_ID); TS_TRACE( "testAttribute done"); - } + } // testAttribute + + /** + * @test testLogRegister - Capture a register in an error log + */ + void testLogRegister(void) + { + errlHndl_t errl = NULL; + + TS_TRACE( "testLogRegister errorlog user detail data"); + /*@ + * @errortype + * @severity ERRORLOG_SEV_INFORMATIONAL + * @moduleid HBERRL_USERDATA_TEST_MOD_ID + * @reasoncode HBERRL_TEST_LOGREGISTER_UD + * @userdata1 Test data 1 + * @userdata2 Test data 2 + * @devdesc User Details unit test - create log register user detail data + */ + errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + HBERRL_USERDATA_TEST_MOD_ID, + HBERRL_TEST_LOGREGISTER_UD, + 0x008900AB00CD00EF, // user1 + 0x0001002300450067 ); // user2 + + using namespace TARGETING; + ErrlUserDetailsString("LogRegister test").addToLog(errl); + + // find a proc target + PredicateCTM procChipFilter(CLASS_CHIP,TYPE_PROC); + TargetRangeFilter pProc( + targetService().begin(), targetService().end(), + &procChipFilter); + + // find a membuf target + PredicateCTM membufChipFilter(CLASS_CHIP,TYPE_MEMBUF); + TargetRangeFilter pMembuf( + targetService().begin(), targetService().end(), + &membufChipFilter); + + // find a dimm target + PredicateCTM dimmChipFilter(CLASS_NA,TYPE_DIMM); + TargetRangeFilter pDimm( + targetService().begin(), targetService().end(), + &dimmChipFilter); + + Target* c_target; + // first do a test w/ the special MASTER SENTINAL constant + c_target = MASTER_PROCESSOR_CHIP_TARGET_SENTINEL; + ErrlUserDetailsTarget(c_target).addToLog(errl); + { + ErrlUserDetailsLogRegister eudlr(c_target); + eudlr.addData(DEVICE_XSCOM_ADDRESS(0x000F000Full)); + eudlr.addData(DEVICE_SCOM_ADDRESS(0x000F000Full)); + eudlr.addToLog(errl); + } + + c_target = *pProc; + ErrlUserDetailsTarget(c_target).addToLog(errl); + + // 1-shot way first - each will have HUID before register data + ErrlUserDetailsLogRegister(c_target, + DEVICE_SCOM_ADDRESS(0x000F000Full)).addToLog(errl); + ErrlUserDetailsLogRegister(c_target, + DEVICE_MVPD_ADDRESS(3,0)).addToLog(errl); + // error: + ErrlUserDetailsLogRegister(c_target, + DEVICE_FSI_ADDRESS(0x01028)).addToLog(errl); + // can't do this - use the addData methodology for driverif.H addresses + //ErrlUserDetailsLogRegister(c_target, + //DEVICE_FSISCOM_ADDRESS(0x000F000Full)).addToLog(errl); + + // more efficient - HUID then each register + { + ErrlUserDetailsLogRegister eudlr(c_target); + eudlr.addData(DEVICE_SCOM_ADDRESS(0x000F000Full)); + eudlr.addData(DEVICE_MVPD_ADDRESS(3,0)); + // error: + eudlr.addData(DEVICE_FSI_ADDRESS(0x01028)); + eudlr.addToLog(errl); + } + + // do the read first, then capture the data + // this mirrors the previous set of LogRegister calls at the + // top of this function, so the results should match.. + ErrlUserDetailsTarget(c_target).addToLog(errl); + errlHndl_t errl_deviceRead; + + uint64_t reg1_data = 0; + size_t reg1_size = sizeof(reg1_data); + errl_deviceRead = DeviceFW::deviceRead(c_target, + ®1_data, reg1_size, + DEVICE_SCOM_ADDRESS(0x000F000Full)); + + if (errl_deviceRead != NULL) + { + TS_TRACE( "testLogRegister deviceRead return errl; deleting;"); + delete errl_deviceRead; + reg1_size = 0; + } + ErrlUserDetailsLogRegister(c_target, ®1_data, reg1_size, + DEVICE_SCOM_ADDRESS(0x000F000Full)).addToLog(errl); + + uint64_t reg2_data = 0; + size_t reg2_size = sizeof(reg2_data); + errl_deviceRead = DeviceFW::deviceRead(c_target, + ®2_data, reg2_size, + DEVICE_MVPD_ADDRESS(3,0)); + + if (errl_deviceRead != NULL) + { + TS_TRACE( "testLogRegister deviceRead return errl; deleting;"); + delete errl_deviceRead; + reg2_size = 0; + } + ErrlUserDetailsLogRegister(c_target, ®2_data, reg2_size, + DEVICE_MVPD_ADDRESS(3,0)).addToLog(errl); + + uint64_t reg3_data = 0; + size_t reg3_size = sizeof(reg3_data); + errl_deviceRead = DeviceFW::deviceRead(c_target, + ®3_data, reg3_size, + DEVICE_FSI_ADDRESS(0x01028)); + + if (errl_deviceRead != NULL) + { + TS_TRACE( "testLogRegister deviceRead return errl; deleting;"); + delete errl_deviceRead; + reg3_size = 0; + } + else + { // we expect an error here + TS_TRACE( "testLogRegister deviceRead DIDNT return errl!"); + } + ErrlUserDetailsLogRegister(c_target, ®3_data, reg3_size, + DEVICE_FSI_ADDRESS(0x01028)).addToLog(errl); + + // more efficient - HUID then each register + { + ErrlUserDetailsLogRegister eudlr(c_target); + eudlr.addDataBuffer(®1_data, reg1_size, + DEVICE_SCOM_ADDRESS(0x000F000Full)); + eudlr.addDataBuffer(®2_data, reg2_size, + DEVICE_MVPD_ADDRESS(3,0)); + eudlr.addDataBuffer(®3_data, reg3_size, + DEVICE_FSI_ADDRESS(0x01028)); + eudlr.addToLog(errl); + } + + // send some that aren't logged: + ErrlUserDetailsLogRegister(c_target, + DEVICE_PRESENT_ADDRESS()).addToLog(errl); + ErrlUserDetailsLogRegister(c_target, + DEVICE_PNOR_ADDRESS(0, 0)).addToLog(errl); + ErrlUserDetailsLogRegister(c_target, + DEVICE_MBOX_ADDRESS(0)).addToLog(errl); + + c_target = *pMembuf; + ErrlUserDetailsTarget(c_target).addToLog(errl); + + // HUID then each register + { + ErrlUserDetailsLogRegister eudlr(c_target); + eudlr.addData(DEVICE_FSI_ADDRESS(0x01028)); + eudlr.addData(DEVICE_SCOM_ADDRESS(0x000F000Full)); + eudlr.addToLog(errl); + } + + c_target = *pDimm; + ErrlUserDetailsTarget(c_target).addToLog(errl); + + // HUID then each register + { + ErrlUserDetailsLogRegister eudlr(c_target); + eudlr.addData(DEVICE_SPD_ADDRESS(0)); + eudlr.addData(DEVICE_FSI_ADDRESS(0x01028)); + eudlr.addData(DEVICE_SCOM_ADDRESS(0x000F000Full)); + eudlr.addToLog(errl); + } + + { + ErrlUserDetailsLogRegister eudlr(c_target); + eudlr.addData(DEVICE_FSISCOM_ADDRESS(0x01028)); + eudlr.addData(DEVICE_XSCOM_ADDRESS(0x000F000Full)); + eudlr.addData(DEVICE_I2C_ADDRESS(0,0,0x50)); + eudlr.addData(DEVICE_EEPROM_ADDRESS(0x1111,0)); + eudlr.addToLog(errl); + } + + // commit the errorlog + errlCommit(errl, CXXTEST_COMP_ID); + TS_TRACE( "testLogRegister errorlog user detail data - complete"); + } // testLogRegister }; #endif diff --git a/src/usr/fsi/fsidd.C b/src/usr/fsi/fsidd.C index ba9838865..73d6ebece 100644 --- a/src/usr/fsi/fsidd.C +++ b/src/usr/fsi/fsidd.C @@ -90,7 +90,7 @@ errlHndl_t ddOp(DeviceFW::OperationType i_opType, TRACUCOMP( g_trac_fsi, "FSI::ddOp> i_addr=%llX, target=%.8X", i_addr, TARGETING::get_huid(i_target) ); do{ - if( io_buflen != sizeof(uint32_t) ) + if (unlikely(io_buflen < sizeof(uint32_t))) { TRACFCOMP( g_trac_fsi, ERR_MRK "FSI::ddOp> Invalid data length : io_buflen=%d", io_buflen ); /*@ diff --git a/src/usr/fsi/fsipres.C b/src/usr/fsi/fsipres.C index 9954204c0..a22002a44 100644 --- a/src/usr/fsi/fsipres.C +++ b/src/usr/fsi/fsipres.C @@ -58,7 +58,7 @@ errlHndl_t presenceDetect(DeviceFW::OperationType i_opType, int64_t i_accessType, va_list i_args) { - if (io_buflen != sizeof(bool)) + if (unlikely(io_buflen < sizeof(bool))) { TRACFCOMP(g_trac_fsi, ERR_MRK "FSI::presenceDetect> Invalid data length: %d", |