summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThi Tran <thi@us.ibm.com>2011-10-05 13:52:52 -0500
committerThi N. Tran <thi@us.ibm.com>2011-10-10 10:42:23 -0500
commit4de170997eee6244b2091bb8bf065ae2da1396d7 (patch)
tree99275148dda9cb03afe005b86ec42746ded135a4
parent9de4a404823c4315d90992d5d08a7fe1794a74c3 (diff)
downloadtalos-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.H7
-rw-r--r--src/include/usr/devicefw/userif.H6
-rw-r--r--src/include/usr/ecmddatabuffer/ecmdDataBuffer.H19
-rw-r--r--src/include/usr/hwpf/plat/fapiPlatReasonCodes.H4
-rwxr-xr-xsrc/usr/ecmddatabuffer/ecmdDataBuffer.C39
-rw-r--r--src/usr/hwpf/fapi/fapiHwAccess.C2
-rw-r--r--src/usr/hwpf/hwp/fapiTestHwp.C219
-rw-r--r--src/usr/hwpf/plat/fapiPlatHwAccess.C342
-rw-r--r--src/usr/xscom/xscom.C4
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);
OpenPOWER on IntegriCloud