summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr')
-rwxr-xr-xsrc/usr/fapi2/fapi2.mk1
-rw-r--r--src/usr/fapi2/plat_i2c_access.C261
-rw-r--r--src/usr/i2c/fapi_i2c_dd.C413
-rw-r--r--src/usr/i2c/fapi_i2c_dd.H103
-rw-r--r--src/usr/i2c/makefile1
-rwxr-xr-xsrc/usr/targeting/common/xmltohb/attribute_types.xml314
-rw-r--r--src/usr/targeting/common/xmltohb/target_types.xml21
7 files changed, 967 insertions, 147 deletions
diff --git a/src/usr/fapi2/fapi2.mk b/src/usr/fapi2/fapi2.mk
index 56edc7995..d55521a02 100755
--- a/src/usr/fapi2/fapi2.mk
+++ b/src/usr/fapi2/fapi2.mk
@@ -80,6 +80,7 @@ OBJS += plat_vpd_access.o
OBJS += plat_wof_access.o
OBJS += dimmBadDqBitmapFuncs.o
OBJS += rowRepairsFuncs.o
+OBJS += plat_i2c_access.o
#Required include before all the procedure.mk are included
include ${ROOTPATH}/procedure.rules.mk
diff --git a/src/usr/fapi2/plat_i2c_access.C b/src/usr/fapi2/plat_i2c_access.C
new file mode 100644
index 000000000..a17d013b0
--- /dev/null
+++ b/src/usr/fapi2/plat_i2c_access.C
@@ -0,0 +1,261 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/fapi2/plat_i2c_access.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2018 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file plat_i2c_access.C
+ *
+ * @brief Implements FAPI i2c functions at the platform layer.
+ */
+
+#include <stdint.h>
+#include <errl/errlentry.H>
+#include <devicefw/userif.H>
+#include <return_code.H>
+#include <target.H>
+#include <target_types.H>
+#include <plat_utils.H>
+#include <attribute_service.H>
+#include <hwpf_fapi2_reasoncodes.H>
+#include <fapi2/plat_i2c_access.H>
+
+
+
+namespace fapi2
+{
+
+//------------------------------------------------------------------------------
+// HW Communication Functions to be implemented at the platform layer.
+//------------------------------------------------------------------------------
+
+/// @brief Platform-level implementation called by FAPI getI2c()
+ReturnCode platGetI2c( const Target<TARGET_TYPE_ALL>& i_target,
+ const size_t i_get_size,
+ const std::vector<uint8_t>& i_cfgData,
+ std::vector<uint8_t>& o_data )
+{
+ ReturnCode l_rc;
+ errlHndl_t l_err = nullptr;
+
+ FAPI_DBG(ENTER_MRK "platGetI2c");
+ // Note: Trace is placed here in plat code because PPE doesn't support
+ // trace in common fapi2_i2c_access.H
+ bool l_traceit = platIsScanTraceEnabled();
+
+ // Grab the name of the target
+ TARGETING::ATTR_FAPI_NAME_type l_targName = {0};
+ fapi2::toString(i_target, l_targName, sizeof(l_targName));
+
+
+ size_t l_get_size = i_get_size; // need non-const
+
+ // create a temporary buffer for read data
+ uint8_t * l_data_read = new uint8_t[ l_get_size ];
+
+ do
+ {
+ // Extract the component pointer
+ TARGETING::Target * l_target = nullptr;
+ l_err = fapi2::platAttrSvc::getTargetingTarget(i_target, l_target);
+ if ( l_err )
+ {
+ FAPI_ERR( "platGetI2c: Error from getTargetingTarget on %s",
+ l_targName );
+ break; //return with error
+ }
+
+ // Perform i2c read
+ uint64_t l_traceCfgData = 0;
+
+ if ( i_cfgData.empty() )
+ {
+ l_err = deviceRead(
+ l_target,
+ l_data_read,
+ l_get_size,
+ DEVICE_FAPI_I2C_ADDRESS()
+ );
+ }
+ else
+ {
+ // deviceRead() requires data pointer
+ // copy data from const vector to data ptr
+ uint8_t * l_configDataPtr = new uint8_t[ i_cfgData.size() ];
+ std::copy(i_cfgData.begin(), i_cfgData.end(), l_configDataPtr);
+
+ // if trace is enabled,
+ // save the config data into l_traceCfgData variable
+ if (l_traceit)
+ {
+ // copy the first 8 bytes of config data into trace variable
+ if (i_cfgData.size() >= sizeof(l_traceCfgData))
+ {
+ // only copy what fits into l_traceCfgData variable
+ memcpy(&l_traceCfgData, l_configDataPtr,sizeof(l_traceCfgData));
+ }
+ else
+ {
+ // all the config data bytes fit into l_traceCfgData variable
+ memcpy(&l_traceCfgData, l_configDataPtr, i_cfgData.size());
+ }
+ }
+
+ l_err = deviceRead(
+ l_target,
+ l_data_read,
+ l_get_size,
+ DEVICE_FAPI_I2C_ADDRESS_WCONFIG(i_cfgData.size(),
+ l_configDataPtr)
+ );
+
+ delete [] l_configDataPtr;
+ }
+
+ if (l_err)
+ {
+ FAPI_ERR("platGetI2c: error from FAPI_I2C deviceRead() of target %s"
+ , l_targName );
+ }
+
+ if (l_traceit)
+ {
+ // Only trace the first 8 bytes of data read
+ // (don't want to overflow trace buffer)
+ uint64_t l_traceDataRead = 0;
+ if (l_get_size >= sizeof(l_traceDataRead))
+ {
+ memcpy(&l_traceDataRead, l_data_read, sizeof(l_traceDataRead));
+ }
+ else if (l_get_size > 0)
+ {
+ memcpy(&l_traceDataRead, l_data_read, l_get_size);
+ }
+ if ( i_cfgData.empty() )
+ {
+ FAPI_SCAN("TRACE : GETI2C : %s : %d %.16llX",
+ l_targName,
+ l_get_size,
+ l_traceDataRead);
+ }
+ else
+ {
+ FAPI_SCAN("TRACE : GETI2C w/config %.16llX : %s : %d %.16llX",
+ l_traceCfgData,
+ l_targName,
+ l_get_size,
+ l_traceDataRead);
+ }
+ }
+
+ } while(0);
+
+ if (l_err)
+ {
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err));
+ }
+ else
+ {
+ // read was successful so copy data into o_data
+ o_data.clear();
+ o_data.insert( o_data.end(),
+ &l_data_read[0],
+ &l_data_read[l_get_size] );
+ }
+
+ // cleanup allocated memory
+ delete [] l_data_read;
+
+ FAPI_DBG(EXIT_MRK "platGetI2c");
+ return l_rc;
+}
+
+/// @brief Platform-level implementation called by FAPI putI2c()
+ReturnCode platPutI2c(const Target<TARGET_TYPE_ALL>& i_target,
+ const std::vector<uint8_t>& i_data)
+{
+ ReturnCode l_rc;
+ errlHndl_t l_err = nullptr;
+
+ FAPI_DBG(ENTER_MRK "platPutI2c");
+ // Note: Trace is placed here in plat code because PPE doesn't support
+ // trace in common fapi2_i2c_access.H
+ bool l_traceit = platIsScanTraceEnabled();
+
+ // Grab the name of the target
+ TARGETING::ATTR_FAPI_NAME_type l_targName = {0};
+ fapi2::toString(i_target, l_targName, sizeof(l_targName));
+
+ do {
+ // Extract the component pointer
+ TARGETING::Target * l_target = nullptr;
+ l_err = fapi2::platAttrSvc::getTargetingTarget(i_target, l_target);
+ if (l_err)
+ {
+ FAPI_ERR( "platPutI2c: Error from getTargetingTarget on %s",
+ l_targName );
+ break; //return with error
+ }
+
+ //copy data from const vector to data ptr
+ uint8_t * l_dataPtr = new uint8_t[ i_data.size() ];
+ std::copy(i_data.begin(), i_data.end(), l_dataPtr);
+ size_t l_dataSize = i_data.size();
+
+ l_err = deviceWrite( l_target,
+ l_dataPtr,
+ l_dataSize,
+ DEVICE_FAPI_I2C_ADDRESS() );
+ if (l_traceit)
+ {
+ // trace the first 8 bytes of written data
+ // (avoid trace buffer overflow)
+ uint64_t traceWriteData = 0;
+ if (l_dataSize > sizeof(traceWriteData))
+ {
+ // copy what will fit into traceWriteData variable
+ memcpy(&traceWriteData, l_dataPtr, sizeof(traceWriteData));
+ }
+ else
+ {
+ memcpy(&traceWriteData, l_dataPtr, l_dataSize);
+ }
+ FAPI_SCAN( "TRACE : PUTI2C : %s : %d %.16llX",
+ l_targName,
+ l_dataSize,
+ traceWriteData );
+ }
+
+ delete [] l_dataPtr;
+
+ } while (0);
+
+ if (l_err)
+ {
+ l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_err));
+ }
+
+ FAPI_DBG(EXIT_MRK "platPutI2c");
+ return l_rc;
+}
+
+} // End namespace
diff --git a/src/usr/i2c/fapi_i2c_dd.C b/src/usr/i2c/fapi_i2c_dd.C
new file mode 100644
index 000000000..23bf5bdbe
--- /dev/null
+++ b/src/usr/i2c/fapi_i2c_dd.C
@@ -0,0 +1,413 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/i2c/fapi_i2c_dd.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2018 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file fapi_i2c_dd.C
+ *
+ * @brief Provides a thin layer on top of our I2C device driver to
+ * serve as the back-end for the FAPI i2c interfaces.
+ * It will locate the appropriate i2c device information
+ * and will perform retries as needed.
+ */
+
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <errl/errludtarget.H>
+#include <errl/errludstring.H>
+#include <targeting/common/targetservice.H>
+#include <targeting/common/commontargeting.H>
+#include <devicefw/driverif.H>
+#include <i2c/i2creasoncodes.H>
+#include "fapi_i2c_dd.H"
+
+extern trace_desc_t* g_trac_i2c;
+
+using namespace DeviceFW;
+
+namespace FAPI_I2C_DD
+{
+
+// Easy macro replace for unit testing
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
+
+
+// ------------------------------------------------------------------
+// errorIsRetryable
+// ------------------------------------------------------------------
+static bool errorIsRetryable(uint16_t reasonCode)
+{
+ return reasonCode == I2C::I2C_NACK_ONLY_FOUND ||
+ reasonCode == I2C::I2C_ARBITRATION_LOST_ONLY_FOUND;
+}
+
+// Link to device driver interface
+DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
+ DeviceFW::FAPI_I2C,
+ TARGETING::TYPE_OCMB_CHIP,
+ fapiI2cPerformOp );
+
+errlHndl_t fapiI2cPerformOp(DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ va_list i_args)
+{
+ errlHndl_t l_err = nullptr;
+ errlHndl_t l_err_retryable = nullptr;
+ const uint8_t FAPI_I2C_MAX_RETRIES = 2;
+
+ TARGETING::ATTR_FAPI_I2C_CONTROL_INFO_type l_i2cInfo;
+ uint8_t * l_cfgData = nullptr;
+
+ size_t l_cfgSize = va_arg( i_args, size_t );
+ if (l_cfgSize > 0)
+ {
+ l_cfgData = va_arg( i_args, uint8_t* );
+ }
+
+ TRACUCOMP(g_trac_i2c, ENTER_MRK"fapiI2cPerformOp(): "
+ "%s operation on target %.8X",
+ (i_opType==DeviceFW::READ)?"READ":"WRITE",
+ TARGETING::get_huid(i_target) );
+
+ do
+ {
+ // Grab i2c access information
+ l_err = readI2cAttributes (i_target, l_i2cInfo);
+ if( l_err )
+ {
+ break;
+ }
+
+ // grab target pointer to master
+ TARGETING::TargetService& ts = TARGETING::targetService();
+ TARGETING::Target * i2cm = ts.toTarget(l_i2cInfo.i2cMasterPath);
+
+ TARGETING::Target * sys = nullptr;
+ ts.getTopLevelTarget( sys );
+
+ // master target has to exist and can not be just sys target
+ if( (i2cm == nullptr) || (i2cm == sys) )
+ {
+ TRACFCOMP( g_trac_i2c, ERR_MRK"fapiI2cPerformOp() - "
+ "I2C Master path (%s) not valid",
+ l_i2cInfo.i2cMasterPath.toString() );
+ /*@
+ * @errortype
+ * @reasoncode I2C::INVALID_MASTER_TARGET
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid I2C::FAPI_I2C_PERFORM_OP
+ * @userdata1 HUID of target with FAPI_I2C_CONTROL_INFO
+ * @devdesc Invalid I2C master path
+ * @custdesc A problem occurred during the IPL
+ * of the system.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ I2C::FAPI_I2C_PERFORM_OP,
+ I2C::INVALID_MASTER_TARGET,
+ TARGETING::get_huid(i_target),
+ 0,
+ true /*Add HB SW Callout*/ );
+
+ l_err->collectTrace( I2C_COMP_NAME );
+ break;
+ }
+
+ // Verify valid operation type
+ if ((i_opType != DeviceFW::READ) && (i_opType != DeviceFW::WRITE))
+ {
+ TRACFCOMP( g_trac_i2c,
+ ERR_MRK"fapiI2cPerformOp() - Invalid OP type %d.",
+ i_opType );
+ /*@
+ * @errortype
+ * @reasoncode I2C::I2C_INVALID_OP_TYPE
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid I2C::FAPI_I2C_PERFORM_OP
+ * @userdata1 OP type
+ * @userdata2 HUID of target
+ * @devdesc Invalid I2C device type
+ * @custdesc A problem occurred during the IPL
+ * of the system.
+ */
+ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ I2C::FAPI_I2C_PERFORM_OP,
+ I2C::I2C_INVALID_OP_TYPE,
+ i_opType,
+ TARGETING::get_huid(i_target),
+ true /*Add HB SW Callout*/ );
+
+ l_err->collectTrace( I2C_COMP_NAME );
+ break;
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+ // Attempt valid i2c operation multiple times ONLY on retryable fails
+ ////////////////////////////////////////////////////////////////////////
+ for ( uint8_t retry = 0; retry <= FAPI_I2C_MAX_RETRIES; ++retry )
+ {
+ if( i_opType == DeviceFW::READ )
+ {
+ l_err = i2cRead( i2cm,
+ io_buffer,
+ io_buflen,
+ &l_i2cInfo,
+ l_cfgData,
+ l_cfgSize );
+ }
+ else if (i_opType == DeviceFW::WRITE )
+ {
+ l_err = i2cWrite( i2cm,
+ io_buffer,
+ io_buflen,
+ &l_i2cInfo );
+ }
+
+ if ( nullptr == l_err )
+ {
+ // Operation completed successfully
+ // break from retry loop
+ break;
+ }
+ else if ( !errorIsRetryable( l_err->reasonCode() ) )
+ {
+ // Non-retryable failure
+ TRACFCOMP( g_trac_i2c, ERR_MRK"fapiI2cPerformOp(): Non-Nack "
+ "Error: rc=0x%X, tgt=0x%X, No Retry (retry=%d)",
+ l_err->reasonCode(),
+ TARGETING::get_huid(i_target), retry);
+ l_err->collectTrace(I2C_COMP_NAME);
+
+ // break from retry loop
+ break;
+ }
+ else // Handle retryable error
+ {
+ // If op will be attempted again: save log and continue
+ if ( retry < FAPI_I2C_MAX_RETRIES )
+ {
+ // Only save original retryable error
+ if ( nullptr == l_err_retryable )
+ {
+ // Save original retryable error
+ l_err_retryable = l_err;
+
+ TRACFCOMP( g_trac_i2c, ERR_MRK"fapiI2cPerformOp(): "
+ "Retryable Error rc=0x%X, eid=0x%X, tgt=0x%X, "
+ "retry/MAX=%d/%d. Save error and retry",
+ l_err_retryable->reasonCode(),
+ l_err_retryable->eid(),
+ TARGETING::get_huid(i_target),
+ retry, FAPI_I2C_MAX_RETRIES);
+ }
+ else
+ {
+ // Add data to original retryable error
+ TRACFCOMP( g_trac_i2c, ERR_MRK"fapiI2cPerformOp(): "
+ "Another Retryable Error rc=0x%X, eid=0x%X "
+ "plid=0x%X, tgt=0x%X, retry/MAX=%d/%d. "
+ "Delete error and retry",
+ l_err->reasonCode(), l_err->eid(),
+ l_err->plid(), TARGETING::get_huid(i_target),
+ retry, FAPI_I2C_MAX_RETRIES );
+
+ ERRORLOG::ErrlUserDetailsString(
+ "Another Retryable Error found")
+ .addToLog(l_err_retryable);
+
+ // Delete this new retryable error
+ delete l_err;
+ l_err = nullptr;
+ }
+
+ // continue to retry
+ continue;
+ }
+ else // no more retries: trace and break
+ {
+ TRACFCOMP( g_trac_i2c, ERR_MRK"fapiI2cPerformOp(): "
+ "Error rc=0x%X, eid=%d, tgt=0x%X. No More "
+ "Retries (retry/MAX=%d/%d). Returning Error",
+ l_err->reasonCode(), l_err->eid(),
+ TARGETING::get_huid(i_target),
+ retry, FAPI_I2C_MAX_RETRIES);
+
+ // break from retry loop
+ break;
+ }
+ } // end of handle retryable error else leg
+
+ } // end of retryable error loop
+
+ // Handle saved retryable error, if any
+ if (l_err_retryable)
+ {
+ if (l_err)
+ {
+ // commit original retryable error with new err PLID
+ l_err_retryable->plid(l_err->plid());
+ TRACFCOMP(g_trac_i2c, "fapiI2cPerformOp(): Committing saved "
+ "retryable error eid=0x%X with plid of returned err 0x%X",
+ l_err_retryable->eid(), l_err_retryable->plid());
+
+ ERRORLOG::ErrlUserDetailsTarget(i_target)
+ .addToLog(l_err_retryable);
+ l_err_retryable->collectTrace(I2C_COMP_NAME);
+ errlCommit(l_err_retryable, I2C_COMP_ID);
+ }
+ else
+ {
+ // Since we eventually succeeded,
+ // delete original retryable error
+ TRACUCOMP(g_trac_i2c, "fapiI2cPerformOp(): Op successful, "
+ "deleting saved retryable err eid=0x%X, plid=0x%X",
+ l_err_retryable->eid(), l_err_retryable->plid());
+
+ delete l_err_retryable;
+ l_err_retryable = nullptr;
+ }
+ }
+
+ } while (0);
+
+ return l_err;
+}
+
+
+
+errlHndl_t i2cRead( TARGETING::Target * i_target,
+ void * o_buffer,
+ size_t & io_buffer_size,
+ TARGETING::ATTR_FAPI_I2C_CONTROL_INFO_type * i_i2cInfo,
+ uint8_t * i_offset_data,
+ const size_t i_offset_data_size)
+{
+ errlHndl_t l_err = nullptr;
+
+ TRACUCOMP(g_trac_i2c, ENTER_MRK"i2cRead()");
+
+ // This i2c interface writes the offset data to the device then
+ // reads the value of the port w/o a stop bit in between ops
+ // Note: if i_offset_data_size == 0, it will skip the write
+ l_err = deviceOp( DeviceFW::READ,
+ i_target,
+ o_buffer,
+ io_buffer_size,
+ DEVICE_I2C_ADDRESS_OFFSET(i_i2cInfo->port,
+ i_i2cInfo->engine,
+ i_i2cInfo->devAddr,
+ i_offset_data_size,
+ i_offset_data) );
+
+ if( l_err )
+ {
+ TRACFCOMP(g_trac_i2c,
+ ERR_MRK"fapi i2cRead(): read failed on %d/%d/0x%X offsetSize=%d "
+ "with eid 0x%x", i_i2cInfo->port, i_i2cInfo->engine,
+ i_i2cInfo->devAddr, i_offset_data_size, l_err->eid());
+
+ if (i_offset_data_size > 0)
+ {
+ TRACFBIN(g_trac_i2c, "i_offset_data[]",
+ i_offset_data, i_offset_data_size);
+ }
+ }
+
+ TRACUCOMP(g_trac_i2c, EXIT_MRK"i2cRead");
+
+ return l_err;
+}
+
+
+errlHndl_t i2cWrite( TARGETING::Target * i_target,
+ void * i_buffer,
+ size_t & io_buffer_size,
+ TARGETING::ATTR_FAPI_I2C_CONTROL_INFO_type * i_i2cInfo )
+{
+ TRACUCOMP(g_trac_i2c, ENTER_MRK"i2cWrite");
+
+ errlHndl_t l_err = nullptr;
+
+ // Do the actual data write
+ l_err = deviceOp( DeviceFW::WRITE,
+ i_target,
+ i_buffer,
+ io_buffer_size,
+ DEVICE_I2C_ADDRESS(i_i2cInfo->port,
+ i_i2cInfo->engine,
+ i_i2cInfo->devAddr) );
+ if( l_err )
+ {
+ TRACFCOMP(g_trac_i2c,
+ ERR_MRK"fapi i2cWrite(): write failed on %d/%d/0x%X length %d "
+ "with eid 0x%x", i_i2cInfo->port, i_i2cInfo->engine,
+ i_i2cInfo->devAddr, io_buffer_size, l_err->eid());
+ }
+
+
+ TRACUCOMP(g_trac_i2c, EXIT_MRK"i2cWrite");
+ return l_err;
+}
+
+
+errlHndl_t readI2cAttributes( TARGETING::Target * i_target,
+ TARGETING::ATTR_FAPI_I2C_CONTROL_INFO_type & io_i2cInfo )
+{
+ errlHndl_t l_err = nullptr;
+
+ if( !(i_target->tryGetAttr<TARGETING::ATTR_FAPI_I2C_CONTROL_INFO>
+ (io_i2cInfo)) )
+ {
+ TRACFCOMP( g_trac_i2c,
+ ERR_MRK"readI2cAttributes() - ERROR reading "
+ "attributes for target huid %.8X",
+ TARGETING::get_huid(i_target) );
+
+ /*@
+ * @errortype
+ * @reasoncode I2C::I2C_ATTRIBUTE_NOT_FOUND
+ * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE
+ * @moduleid I2C::READ_I2C_ATTRIBUTES
+ * @userdata1 HUID of target
+ * @devdesc FAPI_I2C_CONTROL_INFO attribute was not found
+ * @custdesc A problem occurred during the IPL
+ * of the system.
+ */
+ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ I2C::READ_I2C_ATTRIBUTES,
+ I2C::I2C_ATTRIBUTE_NOT_FOUND,
+ TARGETING::get_huid(i_target),
+ 0,
+ true /*Add HB SW Callout*/ );
+
+ l_err->collectTrace( I2C_COMP_NAME );
+ }
+ return l_err;
+}
+
+}; // end namespace FAPI_I2C
+
diff --git a/src/usr/i2c/fapi_i2c_dd.H b/src/usr/i2c/fapi_i2c_dd.H
new file mode 100644
index 000000000..e7bef8396
--- /dev/null
+++ b/src/usr/i2c/fapi_i2c_dd.H
@@ -0,0 +1,103 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/i2c/fapi_i2c_dd.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2018 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __FAPII2CDD_H
+#define __FAPII2CDD_H
+
+#include <errl/errlentry.H>
+#include <i2c/i2cif.H>
+#include <targeting/common/targetservice.H>
+#include <devicefw/driverif.H>
+
+namespace FAPI_I2C_DD
+{
+ /**
+ * @brief Perform a FAPI i2c operation
+ *
+ * @param[in] i_optype - Operation Type - @see devicefw/userif.H
+ * @param[in] i_target - Target device (contains attr with fapiI2c info)
+ * @param[in/out] io_buffer - Ptr to data buffer to be written/read into
+ * @param[in/out] io_buflen - Length of the data buffer
+ * @param[in] i_accessType @see devicefw/userif.H
+ * @param[in] i_args Device argument list.
+ * ConfigDataSize as size_t
+ * ConfigData as uint8_t*
+ *
+ *
+ * @return errlHndl_t NULL on success or error handle on error.
+ */
+ errlHndl_t fapiI2cPerformOp(DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ va_list i_args);
+
+ /**
+ * @brief Read from a i2c device and port
+ *
+ * @param[in] i_target - Target of the i2c master for this i2c device
+ * @param[in] i_data - Configuration data to write before the read
+ * @param[out] o_buffer - Buffer to contain what was read
+ * @param[in] i_i2cInfo - i2c addressing information
+ *
+ * @return errlHndl_t - Null on Success or error handle on error
+ */
+ errlHndl_t i2cRead( TARGETING::Target * i_target,
+ void * o_buffer,
+ size_t & io_buffer_size,
+ TARGETING::ATTR_FAPI_I2C_CONTROL_INFO_type * i_i2cInfo,
+ uint8_t * i_offset_data,
+ const size_t i_offset_data_size );
+
+ /**
+ * @brief Write to an i2c target
+ *
+ * @param[in] i_target - Target of the i2c master for this i2c device
+ * @param[in] i_buffer - Buffer containing the value to write
+ * @param[in] io_buffer_size - Number of bytes to write
+ * Returns number of bytes written
+ * @param[in] i_i2cInfo - i2c addressing information
+ *
+ * @return errlHndl_t - NULL on Success or error handle on error
+ */
+ errlHndl_t i2cWrite( TARGETING::Target * i_target,
+ void * i_buffer,
+ size_t & io_buffer_size,
+ TARGETING::ATTR_FAPI_I2C_CONTROL_INFO_type * i_i2cInfo );
+
+
+ /**
+ * @brief Read the FAPI I2C attributes associated with target
+ *
+ * @param[in] i_target - Target that contains the attritutes for the device
+ * @param[in/out] io_i2cInfo I2C address information.
+ *
+ * @return errlHndl_t - NULL on Success or error handle on error
+ */
+ errlHndl_t readI2cAttributes ( TARGETING::Target * i_target,
+ TARGETING::ATTR_FAPI_I2C_CONTROL_INFO_type &io_i2cInfo );
+};
+
+#endif
diff --git a/src/usr/i2c/makefile b/src/usr/i2c/makefile
index a0a7e0f26..baefb1bed 100644
--- a/src/usr/i2c/makefile
+++ b/src/usr/i2c/makefile
@@ -31,6 +31,7 @@ include i2c.mk
#include unique objects
OBJS += i2c.o
OBJS += $(if $(CONFIG_TPMDD),tpmdd.o,)
+OBJS += fapi_i2c_dd.o
SUBDIRS += test.d
SUBDIRS += runtime.d
diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml
index 4995ee0e7..cf2d4ae47 100755
--- a/src/usr/targeting/common/xmltohb/attribute_types.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types.xml
@@ -876,6 +876,94 @@
</attribute>
<attribute>
+ <id>EEPROM_NV_INFO</id>
+ <description>Information needed to address the NV controller on the NVDIMM</description>
+ <complexType>
+ <description>Structure to define the addressing for NV controller.</description>
+ <field>
+ <name>i2cMasterPath</name>
+ <description>Entity path to the chip that contains the I2C
+ master.
+ </description>
+ <type>EntityPath</type>
+ <default>physical:sys-0</default>
+ </field>
+ <field>
+ <name>port</name>
+ <description>Port from the I2C Master device. This is a 6-bit
+ value, but then shifted 2 bits left.
+ </description>
+ <type>uint8_t</type>
+ <default>0x80</default>
+ </field>
+ <field>
+ <name>devAddr</name>
+ <description>Device address on the I2C bus. This is a 7-bit value,
+ but then shifted 1 bit left.
+ </description>
+ <type>uint8_t</type>
+ <default>0x80</default>
+ </field>
+ <field>
+ <name>engine</name>
+ <description>I2C master engine. This is a 2-bit value,
+ but then shifted 6 bits left.
+ </description>
+ <type>uint8_t</type>
+ <default>0x80</default>
+ </field>
+ <field>
+ <name>byteAddrOffset</name>
+ <description>
+ The number of bytes a device requires to set its
+ internal address/offset. For NV controller it's only
+ one byte addressing with no page select (3)
+ 0 = Zero Byte Addressing
+ 1 = One Byte Addressing with page select
+ 2 = Two Byte Addressing
+ 3 = OneByte Addressing with no page select
+ </description>
+ <type>uint8_t</type>
+ <default>0x03</default>
+ </field>
+ <field>
+ <name>maxMemorySizeKB</name>
+ <description>The number of kilobytes a device can hold. 'Zero'
+ value possible for some devices.
+ </description>
+ <type>uint64_t</type>
+ <default>0x01</default>
+ </field>
+ <field>
+ <name>chipCount</name>
+ <description>The number of chips making up an eeprom device.
+ </description>
+ <type>uint8_t</type>
+ <default>0x01</default>
+ </field>
+ <field>
+ <name>writePageSize</name>
+ <description>The maximum number of bytes that can be written to
+ a device at one time. 'Zero' value means no maximum value is
+ expected or checked.
+ </description>
+ <type>uint64_t</type>
+ <default>0x01</default>
+ </field>
+ <field>
+ <name>writeCycleTime</name>
+ <description>The amount of time in milliseconds a device requires
+ on the completion of a write command to update its internal memory.
+ </description>
+ <type>uint64_t</type>
+ <default>0x05</default>
+ </field>
+ </complexType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ </attribute>
+
+ <attribute>
<complexType>
<description>Structure to define the addressing for an I2C
slave device.</description>
@@ -1187,144 +1275,6 @@
</attribute>
<attribute>
- <id>EEPROM_NV_INFO</id>
- <description>Information needed to address the NV controller on the NVDIMM</description>
- <complexType>
- <description>Structure to define the addressing for NV controller.</description>
- <field>
- <name>i2cMasterPath</name>
- <description>Entity path to the chip that contains the I2C
- master.
- </description>
- <type>EntityPath</type>
- <default>physical:sys-0</default>
- </field>
- <field>
- <name>port</name>
- <description>Port from the I2C Master device. This is a 6-bit
- value, but then shifted 2 bits left.
- </description>
- <type>uint8_t</type>
- <default>0x80</default>
- </field>
- <field>
- <name>devAddr</name>
- <description>Device address on the I2C bus. This is a 7-bit value,
- but then shifted 1 bit left.
- </description>
- <type>uint8_t</type>
- <default>0x80</default>
- </field>
- <field>
- <name>engine</name>
- <description>I2C master engine. This is a 2-bit value,
- but then shifted 6 bits left.
- </description>
- <type>uint8_t</type>
- <default>0x80</default>
- </field>
- <field>
- <name>byteAddrOffset</name>
- <description>
- The number of bytes a device requires to set its
- internal address/offset. For NV controller it's only
- one byte addressing with no page select (3)
- 0 = Zero Byte Addressing
- 1 = One Byte Addressing with page select
- 2 = Two Byte Addressing
- 3 = OneByte Addressing with no page select
- </description>
- <type>uint8_t</type>
- <default>0x03</default>
- </field>
- <field>
- <name>maxMemorySizeKB</name>
- <description>The number of kilobytes a device can hold. 'Zero'
- value possible for some devices.
- </description>
- <type>uint64_t</type>
- <default>0x01</default>
- </field>
- <field>
- <name>chipCount</name>
- <description>The number of chips making up an eeprom device.
- </description>
- <type>uint8_t</type>
- <default>0x01</default>
- </field>
- <field>
- <name>writePageSize</name>
- <description>The maximum number of bytes that can be written to
- a device at one time. 'Zero' value means no maximum value is
- expected or checked.
- </description>
- <type>uint64_t</type>
- <default>0x01</default>
- </field>
- <field>
- <name>writeCycleTime</name>
- <description>The amount of time in milliseconds a device requires
- on the completion of a write command to update its internal memory.
- </description>
- <type>uint64_t</type>
- <default>0x05</default>
- </field>
- </complexType>
- <persistency>non-volatile</persistency>
- <readable></readable>
- </attribute>
-
- <attribute>
- <id>NV_OPS_TIMEOUT_MSEC</id>
- <description>
- NVDIMM timeout value for 6 main operations
- 0 - CSAVE
- 1 - Page Switch
- 2 - Restore
- 3 - ERASE
- 4 - ARM
- 5 - CHARGE
-
- This attribute is set to volatile because the timeout values vary
- depending on the vendor and capacity. The timeout values will be
- determined during init by reading the i2c registers on the NV
- controller.
- The indices are defined in src/usr/isteps/nvdimm.H and the attribute
- is consumed in nvdimm.C
- </description>
- <simpleType>
- <array>6</array>
- <uint32_t>
- <default>0,0,0,0,0,0</default>
- </uint32_t>
- </simpleType>
- <persistency>volatile-zeroed</persistency>
- <readable/>
- <writeable/>
- </attribute>
-
- <attribute>
- <id>NV_STATUS_FLAG</id>
- <description>
- NVDIMM status flag. This is used to record the status and
- later report to OPAL. Possible values:
-
- 0x0080 - memory valid, contents not preserved (genesis)
- 0x0040 - memory contents preserved
- 0x0020 - memory failed to preserve contents
- 0x0010 - memory unable to preserve future contents
- </description>
- <simpleType>
- <uint16_t>
- <default>0x0000</default>
- </uint16_t>
- </simpleType>
- <persistency>volatile-zeroed</persistency>
- <readable/>
- <writeable/>
- </attribute>
-
- <attribute>
<description>
Holds the effective EC of the system. Effective EC is the lowest EC
among all the functional procs in the system. Some cards may "downbin"
@@ -1472,6 +1422,44 @@
</attribute>
<attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ <description>Information needed to address an I2C slave device</description>
+ <complexType>
+ <description>Structure to define addressing this I2C slave device.
+ </description>
+ <field>
+ <default>physical:sys-0</default>
+ <description>Entity path to the chip that contains the I2C master
+ </description>
+ <name>i2cMasterPath</name>
+ <type>EntityPath</type>
+ </field>
+ <field>
+ <default>0x80</default>
+ <description>I2C master engine. This is a 2-bit value.</description>
+ <name>engine</name>
+ <type>uint8_t</type>
+ </field>
+ <field>
+ <default>0x80</default>
+ <description>Port from the I2C Master device. This is a 6-bit value.
+ </description>
+ <name>port</name>
+ <type>uint8_t</type>
+ </field>
+ <field>
+ <default>0x80</default>
+ <description>Device address on the I2C bus. This is a 7-bit value,
+ but then shifted 1 bit left.</description>
+ <name>devAddr</name>
+ <type>uint8_t</type>
+ </field>
+ </complexType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+ </attribute>
+
+ <attribute>
<description>Common name across FAPI environments
chip target -&gt; pu:k0:n0:s0:p00
DIMM target -&gt; dimm:k0:n0:s0:p00
@@ -4809,6 +4797,56 @@
</attribute>
<attribute>
+ <id>NV_OPS_TIMEOUT_MSEC</id>
+ <description>
+ NVDIMM timeout value for 6 main operations
+ 0 - CSAVE
+ 1 - Page Switch
+ 2 - Restore
+ 3 - ERASE
+ 4 - ARM
+ 5 - CHARGE
+
+ This attribute is set to volatile because the timeout values vary
+ depending on the vendor and capacity. The timeout values will be
+ determined during init by reading the i2c registers on the NV
+ controller.
+ The indices are defined in src/usr/isteps/nvdimm.H and the attribute
+ is consumed in nvdimm.C
+ </description>
+ <simpleType>
+ <array>6</array>
+ <uint32_t>
+ <default>0,0,0,0,0,0</default>
+ </uint32_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+ </attribute>
+
+ <attribute>
+ <id>NV_STATUS_FLAG</id>
+ <description>
+ NVDIMM status flag. This is used to record the status and
+ later report to OPAL. Possible values:
+
+ 0x0080 - memory valid, contents not preserved (genesis)
+ 0x0040 - memory contents preserved
+ 0x0020 - memory failed to preserve contents
+ 0x0010 - memory unable to preserve future contents
+ </description>
+ <simpleType>
+ <uint16_t>
+ <default>0x0000</default>
+ </uint16_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+ </attribute>
+
+ <attribute>
<id>OBUS_BRICK_LANE_MASK</id>
<description>
Lane mask for which 8 lanes belong to this brick
diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml
index 7a2f9b6d9..22491a14e 100644
--- a/src/usr/targeting/common/xmltohb/target_types.xml
+++ b/src/usr/targeting/common/xmltohb/target_types.xml
@@ -372,6 +372,9 @@
<id>chip-ocmb-explorer</id>
<parent>chip-ocmb</parent>
<attribute>
+ <id>FAPI_I2C_CONTROL_INFO</id>
+ </attribute>
+ <attribute>
<default>EXPLORER</default>
<id>MODEL</id>
</attribute>
@@ -923,6 +926,9 @@
<id>DECONFIG_GARDABLE</id>
</attribute>
<attribute>
+ <id>EEPROM_NV_INFO</id>
+ </attribute>
+ <attribute>
<id>FRU_ID</id>
</attribute>
<attribute>
@@ -941,6 +947,12 @@
<id>MEM_PORT</id>
</attribute>
<attribute>
+ <id>NV_OPS_TIMEOUT_MSEC</id>
+ </attribute>
+ <attribute>
+ <id>NV_STATUS_FLAG</id>
+ </attribute>
+ <attribute>
<id>POSITION</id>
</attribute>
<attribute>
@@ -959,15 +971,6 @@
<attribute>
<id>VPD_REC_NUM</id>
</attribute>
- <attribute>
- <id>EEPROM_NV_INFO</id>
- </attribute>
- <attribute>
- <id>NV_OPS_TIMEOUT_MSEC</id>
- </attribute>
- <attribute>
- <id>NV_STATUS_FLAG</id>
- </attribute>
</targetType>
<targetType>
OpenPOWER on IntegriCloud