diff options
author | Thi Tran <thi@us.ibm.com> | 2011-10-05 13:52:52 -0500 |
---|---|---|
committer | Thi N. Tran <thi@us.ibm.com> | 2011-10-10 10:42:23 -0500 |
commit | 4de170997eee6244b2091bb8bf065ae2da1396d7 (patch) | |
tree | 99275148dda9cb03afe005b86ec42746ded135a4 | |
parent | 9de4a404823c4315d90992d5d08a7fe1794a74c3 (diff) | |
download | talos-hostboot-4de170997eee6244b2091bb8bf065ae2da1396d7.tar.gz talos-hostboot-4de170997eee6244b2091bb8bf065ae2da1396d7.zip |
Added putScomUnderMask/get/put/modifyCfamRegister interfaces
Updated with review comments from set 1
Updated with review comments from set 3
Change-Id: Iaea4c37fe130cb04e99ebdea872ff4c690156f4d
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/424
Tested-by: Jenkins Server
Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com>
-rw-r--r-- | src/include/usr/devicefw/driverif.H | 7 | ||||
-rw-r--r-- | src/include/usr/devicefw/userif.H | 6 | ||||
-rw-r--r-- | src/include/usr/ecmddatabuffer/ecmdDataBuffer.H | 19 | ||||
-rw-r--r-- | src/include/usr/hwpf/plat/fapiPlatReasonCodes.H | 4 | ||||
-rwxr-xr-x | src/usr/ecmddatabuffer/ecmdDataBuffer.C | 39 | ||||
-rw-r--r-- | src/usr/hwpf/fapi/fapiHwAccess.C | 2 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/fapiTestHwp.C | 219 | ||||
-rw-r--r-- | src/usr/hwpf/plat/fapiPlatHwAccess.C | 342 | ||||
-rw-r--r-- | src/usr/xscom/xscom.C | 4 |
9 files changed, 596 insertions, 46 deletions
diff --git a/src/include/usr/devicefw/driverif.H b/src/include/usr/devicefw/driverif.H index a7139db19..dd8cd8ae8 100644 --- a/src/include/usr/devicefw/driverif.H +++ b/src/include/usr/devicefw/driverif.H @@ -83,13 +83,6 @@ namespace DeviceFW #define DEVICE_I2C_ADDRESS( i_address )\ DeviceFW::I2C, static_cast<uint64_t>(( i_address )) - /** Construct the device addressing parameters for FSI device ops. - * @param[in] i_address - FSI address to operate on. - */ - #define DEVICE_FSI_ADDRESS(i_address) \ - DeviceFW::FSI, static_cast<uint64_t>((i_address)) - - /** @class InvalidParameterType * @brief Unused type to cause compiler fails for invalid template types. * diff --git a/src/include/usr/devicefw/userif.H b/src/include/usr/devicefw/userif.H index adb46a418..0e9955898 100644 --- a/src/include/usr/devicefw/userif.H +++ b/src/include/usr/devicefw/userif.H @@ -62,6 +62,12 @@ namespace DeviceFW #define DEVICE_PRESENT_ADDRESS() \ DeviceFW::PRESENT + /** Construct the device addressing parameters for FSI device ops. + * @param[in] i_address - FSI address to operate on. + */ + #define DEVICE_FSI_ADDRESS(i_address) \ + DeviceFW::FSI, static_cast<uint64_t>((i_address)) + /** * Construct a PNOR DD address * address = 0000_0000_0000_000c_aaaa_aaaa_aaaa_aaaa diff --git a/src/include/usr/ecmddatabuffer/ecmdDataBuffer.H b/src/include/usr/ecmddatabuffer/ecmdDataBuffer.H index 203a966cc..1b65e643e 100644 --- a/src/include/usr/ecmddatabuffer/ecmdDataBuffer.H +++ b/src/include/usr/ecmddatabuffer/ecmdDataBuffer.H @@ -130,6 +130,25 @@ public: */ uint32_t flushTo0(); + /** + * @brief Set a word of data in buffer + * @param i_wordoffset Offset of word to set + * @param i_value 32 bits of data to put into word + * @retval ECMD_DBUF_SUCCESS on success + * @retval ECMD_DBUF_BUFFER_OVERFLOW i_wordoffset is not contained in the size of this buffer + * + * NOTE : If the buffer length != word boundary, when setting the last word + * data in i_value past the buffer length is cleared before being stored in the buffer + */ + uint32_t setWord(uint32_t i_wordoffset, uint32_t i_value); + + /** + * @brief Fetch a word from ecmdDataBuffer + * @param i_wordoffset Offset of word to fetch + * @retval Value of word requested + */ + uint32_t getWord(uint32_t i_wordoffset) const; + protected: uint32_t iv_Capacity; ///< Actual buffer capacity - always >= getNumWords() uint32_t iv_NumBits; ///< Specified buffer size in bits diff --git a/src/include/usr/hwpf/plat/fapiPlatReasonCodes.H b/src/include/usr/hwpf/plat/fapiPlatReasonCodes.H index 25ba997bc..d5fe9faf1 100644 --- a/src/include/usr/hwpf/plat/fapiPlatReasonCodes.H +++ b/src/include/usr/hwpf/plat/fapiPlatReasonCodes.H @@ -33,6 +33,8 @@ namespace fapi MOD_FAPI_GET_CHILD_CHIPLETS = 0x02, MOD_FAPI_GET_PARENT_CHIP = 0x03, MOD_PLAT_ATTR_SVC_CREATE_ATTR_ACCESS_ERROR = 0x04, + MOD_HANDLE_ECMD_BUF_RC = 0x05, + MOD_VERIFY_CFAM_ACCESS_TARGET = 0x06, }; enum hwpfReasonCode @@ -43,6 +45,8 @@ namespace fapi RC_UNSUPPORTED_REQUEST = HWPF_COMP_ID | 0x04, RC_NO_SINGLE_PARENT = HWPF_COMP_ID | 0x05, RC_FAILED_TO_ACCESS_ATTRIBUTE = HWPF_COMP_ID | 0x06, + RC_ECMD_OPERATION_FAILURE = HWPF_COMP_ID | 0x07, + RC_CFAM_ACCESS_ON_PROC_ERR = HWPF_COMP_ID | 0x08, }; }; diff --git a/src/usr/ecmddatabuffer/ecmdDataBuffer.C b/src/usr/ecmddatabuffer/ecmdDataBuffer.C index 4041a3bcb..4b0323137 100755 --- a/src/usr/ecmddatabuffer/ecmdDataBuffer.C +++ b/src/usr/ecmddatabuffer/ecmdDataBuffer.C @@ -235,3 +235,42 @@ uint64_t ecmdDataBufferBase::getDoubleWord(uint32_t i_doublewordoffset) const return ret; } +uint32_t ecmdDataBufferBase::setWord(uint32_t i_wordOffset, uint32_t i_value) +{ + uint32_t rc = ECMD_DBUF_SUCCESS; + + if (i_wordOffset >= getWordLength()) + { + TRACFCOMP(g_trac_ecmd, "**** ERROR : ecmdDataBuffer::setWord: wordoffset %d >= NumWords (%d)", i_wordOffset, getWordLength()); + return (ECMD_DBUF_BUFFER_OVERFLOW); + } + + // Create mask if part of this word is not in the valid part of the ecmdDataBuffer + if (((i_wordOffset + 1) == getWordLength()) && (iv_NumBits % 32)) + { + /* Create my mask */ + uint32_t bitMask = 0xFFFFFFFF; + /* Shift it left by the amount of unused bits */ + bitMask <<= ((32 * getWordLength()) - iv_NumBits); + /* Clear the unused bits */ + i_value &= bitMask; + } + + iv_Data[i_wordOffset] = i_value; + + return rc; +} + +uint32_t ecmdDataBufferBase::getWord(uint32_t i_wordOffset) const +{ + if (i_wordOffset >= getWordLength()) + { + TRACFCOMP(g_trac_ecmd,"**** ERROR : ecmdDataBuffer::getWord: i_wordOffset %d >= NumWords (%d)", + i_wordOffset, getWordLength()); + return 0; + } + + return this->iv_Data[i_wordOffset]; +} + + diff --git a/src/usr/hwpf/fapi/fapiHwAccess.C b/src/usr/hwpf/fapi/fapiHwAccess.C index ab4d81fb9..62403fdc0 100644 --- a/src/usr/hwpf/fapi/fapiHwAccess.C +++ b/src/usr/hwpf/fapi/fapiHwAccess.C @@ -68,7 +68,7 @@ fapi::ReturnCode fapiGetScom(const fapi::Target& i_target, i_address ); } - // call the platform implemenation + // call the platform implementation l_rc = platGetScom( i_target, i_address, o_data ); diff --git a/src/usr/hwpf/hwp/fapiTestHwp.C b/src/usr/hwpf/hwp/fapiTestHwp.C index 92bb7004e..347c18291 100644 --- a/src/usr/hwpf/hwp/fapiTestHwp.C +++ b/src/usr/hwpf/hwp/fapiTestHwp.C @@ -41,7 +41,7 @@ */ #include <fapiTestHwp.H> - +#include <fapiHwAccess.H> extern "C" { @@ -56,25 +56,214 @@ fapi::ReturnCode hwpInitialTest(const fapi::Target & i_chip) char l_string[fapi::MAX_ECMD_STRING_LEN] = {0}; i_chip.toString(l_string); FAPI_INF("hwpInitialTest: Chip: %s", l_string); - fapi::ReturnCode l_rc; + uint32_t l_ecmdRc = ECMD_DBUF_SUCCESS; + + do + { + // Use this SCOM register for testing + const uint64_t l_addr = 0x13010002; + ecmdDataBufferBase l_ScomData(64); + uint64_t l_originalScomData = 0; - // Figure out the scom address and create a 64 bit data buffer - ecmdDataBufferBase l_data(64); + // -------------------------------------------------------- + // 1. fapiGetScom test + // -------------------------------------------------------- + l_rc = fapiGetScom(i_chip, l_addr, l_ScomData); + if (l_rc != fapi::FAPI_RC_SUCCESS) + { + FAPI_ERR("hwpInitialTest: Error from fapiGetScom"); + break; + } + else + { + // Save the original data so we can restore it later + l_originalScomData = l_ScomData.getDoubleWord(0); + FAPI_INF("hwpInitialTest: GetScom data 0x%.16llX", l_originalScomData); + } - const uint64_t l_addr = 0x13010002; + // -------------------------------------------------------- + // 2. fapiPutScom test + // -------------------------------------------------------- + uint64_t l_scomWriteValue = 0x9000000000000000; - // Perform a GetScom operation on the chip - l_rc = fapiGetScom(i_chip, l_addr, l_data); + l_ecmdRc = l_ScomData.setDoubleWord(0, l_scomWriteValue); + if (l_ecmdRc != ECMD_DBUF_SUCCESS) + { + FAPI_ERR("hwpInitialTest: fapiPutScom test, error from ecmdDataBuffer setDoubleWord() - rc 0x%.8X", l_ecmdRc); + l_rc = fapi::FAPI_RC_ECMD_MASK; + break; + } - if (l_rc != fapi::FAPI_RC_SUCCESS) - { - FAPI_ERR("hwpInitialTest: Error from fapiGetScom"); - } - else - { - FAPI_INF("hwpInitialTest: Data from SCOM:0x%lld", l_data.getDoubleWord(0)); - } + l_rc = fapiPutScom(i_chip, l_addr, l_ScomData); + if (l_rc != fapi::FAPI_RC_SUCCESS) + { + FAPI_ERR("hwpInitialTest: Error from fapiPutScom"); + break; + } + else + { + FAPI_INF("hwpInitialTest: PutScom data 0x%.16llX", l_scomWriteValue); + } + + // -------------------------------------------------------- + // 3. fapiPutScomUnderMask test + // -------------------------------------------------------- + l_scomWriteValue = 0xA000000000000000; + uint64_t l_mask = 0x3000000000000000; + ecmdDataBufferBase l_maskData(64); + + l_ecmdRc = l_ScomData.setDoubleWord(0, l_scomWriteValue); + l_ecmdRc |= l_maskData.setDoubleWord(0, l_mask); + if (l_ecmdRc != ECMD_DBUF_SUCCESS) + { + FAPI_ERR("hwpInitialTest: fapiPutScomUnderMask test, error from ecmdDataBuffer setDoubleWord() - rc 0x%.8X", l_ecmdRc); + l_rc = fapi::FAPI_RC_ECMD_MASK; + break; + } + + + l_rc = fapiPutScomUnderMask(i_chip, l_addr, l_ScomData, l_maskData); + if (l_rc != fapi::FAPI_RC_SUCCESS) + { + FAPI_ERR("hwpInitialTest: Error from fapiPutScomUnderMask"); + break; + } + else + { + FAPI_INF("hwpInitialTest: fapiPutScomUnderMask data 0x%.16llX, mask 0x%.16llX", + l_scomWriteValue, l_mask); + } + + // -------------------------------------------------------- + // 4. fapiPutScom to restore original value + // -------------------------------------------------------- + l_ecmdRc = l_ScomData.setDoubleWord(0, l_originalScomData); + if (l_ecmdRc != ECMD_DBUF_SUCCESS) + { + FAPI_ERR("hwpInitialTest: fapiPutScom to restore, error from ecmdDataBuffer setDoubleWord() - rc 0x%.8X", l_ecmdRc); + l_rc = fapi::FAPI_RC_ECMD_MASK; + break; + } + + l_rc = fapiPutScom(i_chip, l_addr, l_ScomData); + if (l_rc != fapi::FAPI_RC_SUCCESS) + { + FAPI_ERR("hwpInitialTest: Error from fapiPutScom"); + break; + } + else + { + FAPI_INF("hwpInitialTest: PutScom data 0x%.16llX", l_originalScomData); + } + +#if 0 +// @todo +// Per Dean, there's no access to the CFAM engines on the master processor, therefore, +// we *should not* allow access to them on any processor in any position +// from a FAPI standpoint. +// This means that get/put/modifyCfamRegister can't not be called on any of the processors. +// These functions, therefore, can only be called on the Centaur, which is not available +// at this time. +// When Centaur is supported: +// - Don't use i_chip (a processor) as a target. Set the target as one of the Centaurs. +// - Enable this block of code and test the cfam access functions on the Centaur. + + // -------------------------------------------------------- + // 5. fapiGetCfamRegister test + // -------------------------------------------------------- + ecmdDataBufferBase l_cfamData(32); // 32-bit cfam data holder + uint32_t l_originalCfamData = 0; + const uint32_t l_cfamAddr = 0x100A; // ChipID register + l_rc = fapiGetCfamRegister(i_chip, l_cfamAddr, l_cfamData); + if (l_rc != fapi::FAPI_RC_SUCCESS) + { + FAPI_ERR("hwpInitialTest: Error from fapiGetCfamRegister"); + break; + } + else + { + l_originalCfamData = l_cfamData.getWord(0); + FAPI_INF("hwpInitialTest: fapiGetCfamRegister data 0x%.8X", + l_originalCfamData); + } + + // -------------------------------------------------------- + // 6. fapiPutCfamRegister test + // -------------------------------------------------------- + uint32_t l_cfamWriteValue = 0x90000000; + l_ecmdRc = l_cfamData.setWord(0, l_cfamWriteValue); + if (l_ecmdRc != ECMD_DBUF_SUCCESS) + { + FAPI_ERR("hwpInitialTest: fapiPutCfamRegister test, error from ecmdDataBuffer setWord() - rc 0x%.8X", l_ecmdRc); + l_rc = fapi::FAPI_RC_ECMD_MASK; + break; + } + + + l_rc = fapiPutCfamRegister(i_chip, l_cfamAddr, l_cfamData); + if (l_rc != fapi::FAPI_RC_SUCCESS) + { + FAPI_ERR("hwpInitialTest: Error from fapiPutCfamRegister"); + break; + } + else + { + FAPI_INF("hwpInitialTest: fapiPutCfamRegister data 0x%.8X", + l_cfamData.getWord(0)); + } + + // -------------------------------------------------------- + // 7. fapiModifyCfamRegister test + // -------------------------------------------------------- + l_cfamWriteValue = 0xA0000000; + l_ecmdRc = l_cfamData.setWord(0, l_cfamWriteValue); + if (l_ecmdRc != ECMD_DBUF_SUCCESS) + { + FAPI_ERR("hwpInitialTest: fapiModifyCfamRegister test, error from ecmdDataBuffer setWord() - rc 0x%.8X", l_ecmdRc); + l_rc = fapi::FAPI_RC_ECMD_MASK; + break; + } + + l_rc = fapiModifyCfamRegister(i_chip, l_cfamAddr, + l_cfamData, fapi::CHIP_OP_MODIFY_MODE_AND); + if (l_rc != fapi::FAPI_RC_SUCCESS) + { + FAPI_ERR("hwpInitialTest: Error from fapiPutCfamRegister"); + break; + } + else + { + FAPI_INF("hwpInitialTest: fapiPutCfamRegister data 0x%.8X", + l_cfamData.getWord(0)); + } + + // -------------------------------------------------------- + // 8. fapiPutCfamRegister to restore original CFAM value + // -------------------------------------------------------- + l_ecmdRc = l_cfamData.setWord(0, l_originalCfamData); + if (l_ecmdRc != ECMD_DBUF_SUCCESS) + { + FAPI_ERR("hwpInitialTest: fapiPutCfamRegister to restore, error from ecmdDataBuffer setWord() - rc 0x%.8X", l_ecmdRc); + l_rc = fapi::FAPI_RC_ECMD_MASK; + break; + } + + l_rc = fapiPutCfamRegister(i_chip, l_cfamAddr, l_cfamData); + if (l_rc != fapi::FAPI_RC_SUCCESS) + { + FAPI_ERR("hwpInitialTest: Error from fapiPutCfamRegister to restore"); + break; + } + else + { + FAPI_INF("hwpInitialTest: fapiPutCfamRegister data 0x%.8X", + l_cfamData.getWord(0)); + } + +#endif + + } while (0); return l_rc; } diff --git a/src/usr/hwpf/plat/fapiPlatHwAccess.C b/src/usr/hwpf/plat/fapiPlatHwAccess.C index 20543b8c7..79ae69642 100644 --- a/src/usr/hwpf/plat/fapiPlatHwAccess.C +++ b/src/usr/hwpf/plat/fapiPlatHwAccess.C @@ -20,6 +20,27 @@ // Origin: 30 // // IBM_PROLOG_END +// This is an automatically generated prolog. +// +// $Source: src/usr/hwpf/plat/fapiPlatHwAccess.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 /** * @file fapiPlatHwAccess.C * @@ -34,6 +55,8 @@ #include <errl/errlentry.H> #include <targeting/targetservice.H> #include <devicefw/userif.H> +#include <ecmdDataBuffer.H> +#include <fapiPlatReasonCodes.H> extern "C" { @@ -49,13 +72,16 @@ fapi::ReturnCode platGetScom(const fapi::Target& i_target, fapi::ReturnCode l_rc; errlHndl_t l_err = NULL; + uint32_t l_ecmdRc = ECMD_DBUF_SUCCESS; // Extract the component pointer - TARGETING::Target* l_target = reinterpret_cast<TARGETING::Target*>(i_target.get()); + 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, @@ -63,13 +89,25 @@ fapi::ReturnCode platGetScom(const fapi::Target& i_target, if (l_err) { // Add the error log pointer as data to the ReturnCode - FAPI_ERR("GetScom: HostBoot GetScom returns error"); + FAPI_ERR("platGetScom: deviceRead() returns error"); l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA; l_rc.setPlatData(reinterpret_cast<void *> (l_err)); } else { - o_data.setDoubleWord(0, l_data); + // Set buffer to 64-bit long to store data + l_ecmdRc = o_data.setBitLength(64); + if (l_ecmdRc == ECMD_DBUF_SUCCESS) + { + l_ecmdRc = o_data.setDoubleWord(0, l_data); + } + + if (l_ecmdRc) + { + FAPI_ERR("platGetScom: ecmdDataBufferBase setBitLength() or setDoubleWord() returns error, ecmdRc 0x%.8X", + l_ecmdRc); + l_rc = l_ecmdRc; + } } FAPI_DBG(EXIT_MRK "platGetScom"); @@ -88,9 +126,10 @@ fapi::ReturnCode platPutScom(const fapi::Target& i_target, errlHndl_t l_err = NULL; // Extract the component pointer - TARGETING::Target* l_target = reinterpret_cast<TARGETING::Target*>(i_target.get()); + TARGETING::Target* l_target = + reinterpret_cast<TARGETING::Target*>(i_target.get()); - // Perform SCOM read + // Perform SCOM write uint64_t l_data = i_data.getDoubleWord(0); size_t l_size = sizeof(uint64_t); l_err = deviceWrite(l_target, @@ -100,7 +139,7 @@ fapi::ReturnCode platPutScom(const fapi::Target& i_target, if (l_err) { // Add the error log pointer as data to the ReturnCode - FAPI_ERR("Putscom: HostBoot Putscom returns error"); + FAPI_ERR("platPutScom: deviceWrite() returns error"); l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA; l_rc.setPlatData(reinterpret_cast<void *> (l_err)); } @@ -119,15 +158,102 @@ fapi::ReturnCode platPutScomUnderMask(const fapi::Target& i_target, { FAPI_DBG(ENTER_MRK "platPutScomUnderMask"); fapi::ReturnCode l_rc; + errlHndl_t l_err = NULL; + + // Extract the component pointer + TARGETING::Target* l_target = + reinterpret_cast<TARGETING::Target*>(i_target.get()); + + do + { + // Get current value from HW + 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("platPutScomUnderMask: deviceRead() returns error"); + l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA; + l_rc.setPlatData(reinterpret_cast<void *> (l_err)); + break; + } + + // Calculate new value to write to reg + uint64_t l_inData = i_data.getDoubleWord(0); // Data to write + uint64_t l_inMask = i_mask.getDoubleWord(0); // Write mask + uint64_t l_inMaskInverted = ~(l_inMask); // Write mask inverted + uint64_t l_newMask = (l_inData & l_inMask); // Retain set data bits + + // l_data = current data set bits + l_data &= l_inMaskInverted; - // TODO Code needs to be implemented - FAPI_ERR("platPutScomUnderMask not implemented"); - l_rc = fapi::FAPI_RC_NOT_IMPLEMENTED; + // l_data = current data set bit + set mask bits + l_data |= l_newMask; + + // Write new value + 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("platPutScomUnderMask: deviceWrite() returns error"); + l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA; + l_rc.setPlatData(reinterpret_cast<void *> (l_err)); + break; + } + + } + while(0); FAPI_DBG(EXIT_MRK "platPutScomUnderMask"); return l_rc; } +/**************************************************************************** + * @brief Verify target of a cfam access + * We can't access the cfam engine of the master processor; therefore, + * we should not allow a cfam access on any processor in any position + * from a FAPI standpoint + * This function will return an error if the input target is of + * processor type. + * + * @param[in] i_target The target where cfam access is called on. + * + * @return errlHndl_t if target is a processor, NULL otherwise. + ****************************************************************************/ +static errlHndl_t verifyCfamAccessTarget(const fapi::Target& i_target) +{ + errlHndl_t l_err = NULL; + + // Can't access cfam engine on processors + if (i_target.getType() == fapi::TARGET_TYPE_PROC_CHIP) + { + // Add the error log pointer as data to the ReturnCode + FAPI_ERR("verifyCfamAccessTarget: Attempt to access CFAM register on a processor chip"); + + /*@ + * @errortype + * @moduleid MOD_VERIFY_CFAM_ACCESS_TARGET + * @reasoncode RC_CFAM_ACCESS_ON_PROC_ERR + * @userdata1 Target type + * @devdesc Attempt to access CFAM register on a processor chip + */ + l_err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi::MOD_VERIFY_CFAM_ACCESS_TARGET, + fapi::RC_CFAM_ACCESS_ON_PROC_ERR, + i_target.getType()); + } + + return l_err; +} + //****************************************************************************** // platGetCfamRegister function //****************************************************************************** @@ -137,10 +263,59 @@ fapi::ReturnCode platGetCfamRegister(const fapi::Target& i_target, { FAPI_DBG(ENTER_MRK "platGetCfamRegister"); fapi::ReturnCode l_rc; + errlHndl_t l_err = NULL; + uint32_t l_ecmdRc = ECMD_DBUF_SUCCESS; + + do + { + // Can't access cfam engine on processors + l_err = verifyCfamAccessTarget(i_target); + if (l_err) + { + // Add the error log pointer as data to the ReturnCode + FAPI_ERR("platGetCfamRegister: verifyCfamAccessTarget() returns error"); + l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA; + l_rc.setPlatData(reinterpret_cast<void *> (l_err)); + break; + } + + // Extract the component pointer + TARGETING::Target* l_target = + reinterpret_cast<TARGETING::Target*>(i_target.get()); + + // Perform CFAM read via FSI + // Address needs to be multiply by 4 because register addresses are word + // offsets but the FSI addresses are byte offsets + uint64_t l_addr = (i_address << 2); + uint32_t l_data = 0; + size_t l_size = sizeof(uint32_t); + l_err = deviceRead(l_target, + &l_data, + l_size, + DEVICE_FSI_ADDRESS(l_addr)); + if (l_err) + { + // Add the error log pointer as data to the ReturnCode + FAPI_ERR("platGetCfamRegister: deviceRead() returns error"); + l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA; + l_rc.setPlatData(reinterpret_cast<void *> (l_err)); + break; + } - // TODO Code needs to be implemented - FAPI_ERR("platGetCfamRegister not implemented"); - l_rc = fapi::FAPI_RC_NOT_IMPLEMENTED; + // Set buffer to 32-bit long to store data + l_ecmdRc = o_data.setBitLength(32); + if (l_ecmdRc == ECMD_DBUF_SUCCESS) + { + l_ecmdRc = o_data.setWord(0, l_data); + } + if (l_ecmdRc) + { + FAPI_ERR("platGetCfamRegister: ecmdDataBufferBase setBitLength() or setWord() returns error, ecmdRc 0x%.8X", + l_ecmdRc); + l_rc = l_ecmdRc; + } + + } while(0); FAPI_DBG(EXIT_MRK "platGetCfamRegister"); return l_rc; @@ -155,29 +330,154 @@ fapi::ReturnCode platPutCfamRegister(const fapi::Target& i_target, { FAPI_DBG(ENTER_MRK "platPutCfamRegister"); fapi::ReturnCode l_rc; + errlHndl_t l_err = NULL; + + do + { + // Can't access cfam engine on processors + l_err = verifyCfamAccessTarget(i_target); + if (l_err) + { + // Add the error log pointer as data to the ReturnCode + FAPI_ERR("platPutCfamRegister: verifyCfamAccessTarget() returns error"); + l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA; + l_rc.setPlatData(reinterpret_cast<void *> (l_err)); + break; + } + + // Extract the component pointer + TARGETING::Target* l_target = + reinterpret_cast<TARGETING::Target*>(i_target.get()); - // TODO Code needs to be implemented - FAPI_ERR("platPutCfamRegister not implemented"); - l_rc = fapi::FAPI_RC_NOT_IMPLEMENTED; + // Perform CFAM write via FSI + // Address needs to be multiply by 4 because register addresses are word + // offsets but the FSI addresses are byte offsets + uint64_t l_addr = (i_address << 2); + uint32_t l_data = i_data.getWord(0); + size_t l_size = sizeof(uint32_t); + l_err = deviceWrite(l_target, + &l_data, + l_size, + DEVICE_FSI_ADDRESS(l_addr)); + if (l_err) + { + // Add the error log pointer as data to the ReturnCode + FAPI_ERR("platPutCfamRegister: deviceWrite() returns error"); + l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA; + l_rc.setPlatData(reinterpret_cast<void *> (l_err)); + break; + } + + } while (0); FAPI_DBG(EXIT_MRK "platPutCfamRegister"); return l_rc; } + +/**************************************************************************** + * @brief Modifying input 32-bit data with the specified mode + * + * This method modify 32-bit input data (io_modifiedData) by applying the + * specified modify mode along with the input data (i_origData). + * + * @param[in] i_modifyMode Modification mode + * @param[in] i_origData 32-bit data to be used for modification + * @param[out] io_modifiedData 32-bit data to be modified + * + * @return void + * + ****************************************************************************/ +void platProcess32BitModifyMode(const fapi::ChipOpModifyMode i_modifyMode, + const uint32_t i_origDataBuf, + uint32_t& io_modifiedData) +{ + + // OR operation + if (fapi::CHIP_OP_MODIFY_MODE_OR == i_modifyMode) + { + io_modifiedData |= i_origDataBuf; + } + // AND operation + else if (fapi::CHIP_OP_MODIFY_MODE_AND == i_modifyMode) + { + io_modifiedData &= i_origDataBuf; + } + // Must be XOR operation + else + { + io_modifiedData ^= i_origDataBuf; + } + + return; +} + //****************************************************************************** // platModifyCfamRegister function //****************************************************************************** fapi::ReturnCode platModifyCfamRegister(const fapi::Target& i_target, - const uint32_t i_address, - ecmdDataBufferBase & i_data, - const fapi::ChipOpModifyMode i_modifyMode) + const uint32_t i_address, + ecmdDataBufferBase& i_data, + const fapi::ChipOpModifyMode i_modifyMode) { FAPI_DBG(ENTER_MRK "platModifyCfamRegister"); fapi::ReturnCode l_rc; + errlHndl_t l_err = NULL; + + do + { + // Can't access cfam engine on processors + l_err = verifyCfamAccessTarget(i_target); + if (l_err) + { + // Add the error log pointer as data to the ReturnCode + FAPI_ERR("platModifyCfamRegister: verifyCfamAccessTarget() returns error"); + l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA; + l_rc.setPlatData(reinterpret_cast<void *> (l_err)); + break; + } + + // Extract the component pointer + TARGETING::Target* l_target = + reinterpret_cast<TARGETING::Target*>(i_target.get()); + + // Read current value + // Address needs to be multiply by 4 because register addresses are word + // offsets but the FSI addresses are byte offsets + uint64_t l_addr = (i_address << 2); + uint32_t l_data = 0; + size_t l_size = sizeof(uint32_t); + l_err = deviceRead(l_target, + &l_data, + l_size, + DEVICE_FSI_ADDRESS(l_addr)); + if (l_err) + { + // Add the error log pointer as data to the ReturnCode + FAPI_ERR("platModifyCfamRegister: deviceRead() returns error"); + l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA; + l_rc.setPlatData(reinterpret_cast<void *> (l_err)); + break; + } + + // Applying modification + platProcess32BitModifyMode(i_modifyMode, i_data.getWord(0), l_data); + + // Write back + l_err = deviceWrite(l_target, + &l_data, + l_size, + DEVICE_FSI_ADDRESS(l_addr)); + if (l_err) + { + // Add the error log pointer as data to the ReturnCode + FAPI_ERR("platModifyCfamRegister: deviceWrite() returns error"); + l_rc = fapi::FAPI_RC_PLAT_ERR_SEE_DATA; + l_rc.setPlatData(reinterpret_cast<void *> (l_err)); + break; + } - // TODO Code needs to be implemented - FAPI_ERR("platModifyCfamRegister not implemented"); - l_rc = fapi::FAPI_RC_NOT_IMPLEMENTED; + } while (0); FAPI_DBG(EXIT_MRK "platModifyCfamRegister"); return l_rc; diff --git a/src/usr/xscom/xscom.C b/src/usr/xscom/xscom.C index 5f90a8beb..cdc17a76c 100644 --- a/src/usr/xscom/xscom.C +++ b/src/usr/xscom/xscom.C @@ -547,11 +547,11 @@ errlHndl_t xscomPerformOp(DeviceFW::OperationType i_opType, // Done, un-pin task_affinity_unpin(); - TRACFCOMP(g_trac_xscom, "xscomPerformOp: OpType 0x%.16llX, Address 0x%llX, MMIO Address 0x%llX", + TRACDCOMP(g_trac_xscom, "xscomPerformOp: OpType 0x%.16llX, Address 0x%llX, MMIO Address 0x%llX", static_cast<uint64_t>(i_opType), l_addr, static_cast<uint64_t>(l_mmioAddr)); - TRACFCOMP(g_trac_xscom, "xscomPerformOp: l_offset 0x%.16llX; VirtAddr %p; l_virtAddr+l_offset %p", + TRACDCOMP(g_trac_xscom, "xscomPerformOp: l_offset 0x%.16llX; VirtAddr %p; l_virtAddr+l_offset %p", l_offset, l_virtAddr, l_virtAddr + l_offset); |