summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/usr/devicefw/userif.H25
-rw-r--r--src/usr/isteps/nvdimm/nvdimm.C4
-rw-r--r--src/usr/isteps/nvdimm/nvdimm_update.C2
-rwxr-xr-xsrc/usr/isteps/nvdimm/nvdimmdd.C72
-rwxr-xr-xsrc/usr/isteps/nvdimm/nvdimmdd.H43
5 files changed, 139 insertions, 7 deletions
diff --git a/src/include/usr/devicefw/userif.H b/src/include/usr/devicefw/userif.H
index d626d49c0..772511566 100644
--- a/src/include/usr/devicefw/userif.H
+++ b/src/include/usr/devicefw/userif.H
@@ -68,7 +68,8 @@ namespace DeviceFW
AHB_SIO, // AST Hostbridge via SIO
DVPD, // Direct access memory VPD
NODECOMM, // Internode communication
- NVDIMM, // Non-volatile DIMM controller access
+ NVDIMM, // Routes message to non-volatile DIMM controller access
+ NVDIMM_RAW, // Non-volatile DIMM controller access
FAPI_I2C, // FAPI2-triggered i2c accesses
MMIO, // Memory Mapped I/O
IDEC, // Read and set EC and CHIPID values
@@ -379,12 +380,30 @@ namespace DeviceFW
static_cast<uint64_t>(( i_mailbox_id ))
/**
- * Construct the device addressing parameters for the NVDIMM device ops.
- * @param[i] i_address - NVDIMM address to internal register
+ * @brief Construct the device addressing parameters for the
+ * NVDIMM device ops.
+ * @details This call includes setting the page based off the address
+ * and then performing the read/write of that NVDIMM address.
+ * @see DEVICE_NVDIMM_RAW_ADDRESS for an NVDIMM read/write call without
+ * page setting.
+ * @param[i] i_address - NVDIMM address to an internal register
*/
#define DEVICE_NVDIMM_ADDRESS(i_address)\
DeviceFW::NVDIMM, static_cast<uint64_t>((i_address))
+ /**
+ * @brief Construct the device addressing parameters for the
+ * NVDIMM RAW device ops.
+ * @details This a raw call to read/write a NVDIMM address which means it
+ * will not set the page before it does the read/write call. Hence,
+ * for this call to work properly, the page must have been set
+ * properly beforehand.
+ * @see DEVICE_NVDIMM_ADDRESS for a NVDIMM read/write call with
+ * page setting.
+ * @param[i] i_address - NVDIMM address to an internal register
+ */
+ #define DEVICE_NVDIMM_RAW_ADDRESS(i_address)\
+ DeviceFW::NVDIMM_RAW, static_cast<uint64_t>((i_address))
/**
* Construct the device addressing parameters for the FAPI I2C operation
diff --git a/src/usr/isteps/nvdimm/nvdimm.C b/src/usr/isteps/nvdimm/nvdimm.C
index 852a65a88..db26eb184 100644
--- a/src/usr/isteps/nvdimm/nvdimm.C
+++ b/src/usr/isteps/nvdimm/nvdimm.C
@@ -264,7 +264,7 @@ errlHndl_t nvdimmReadReg(Target* i_nvdimm,
i_nvdimm,
&o_data,
l_numBytes,
- DEVICE_NVDIMM_ADDRESS(l_reg_addr));
+ DEVICE_NVDIMM_RAW_ADDRESS(l_reg_addr));
}while(0);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"NVDIMM Read HUID 0x%X, page 0x%X, addr 0x%X = 0x%X",
@@ -334,7 +334,7 @@ errlHndl_t nvdimmWriteReg(Target* i_nvdimm,
i_nvdimm,
&i_data,
l_numBytes,
- DEVICE_NVDIMM_ADDRESS(l_reg_addr));
+ DEVICE_NVDIMM_RAW_ADDRESS(l_reg_addr));
}while(0);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"NVDIMM Write HUID 0x%X, page = 0x%X, addr 0x%X = 0x%X",
diff --git a/src/usr/isteps/nvdimm/nvdimm_update.C b/src/usr/isteps/nvdimm/nvdimm_update.C
index 3a732ef66..1f42228ce 100644
--- a/src/usr/isteps/nvdimm/nvdimm_update.C
+++ b/src/usr/isteps/nvdimm/nvdimm_update.C
@@ -1432,7 +1432,7 @@ errlHndl_t NvdimmInstalledImage::byteRegionBlockTransfer(const uint8_t * i_data,
iv_dimm,
pCurrentBlockData,
l_numBytes,
- DEVICE_NVDIMM_ADDRESS(l_reg_addr) );
+ DEVICE_NVDIMM_RAW_ADDRESS(l_reg_addr) );
if (l_err)
{
TRACFCOMP(g_trac_nvdimm_upd, ERR_MRK"byteRegionBlockTransfer: "
diff --git a/src/usr/isteps/nvdimm/nvdimmdd.C b/src/usr/isteps/nvdimm/nvdimmdd.C
index b2c8909d3..695a60b93 100755
--- a/src/usr/isteps/nvdimm/nvdimmdd.C
+++ b/src/usr/isteps/nvdimm/nvdimmdd.C
@@ -97,13 +97,83 @@ static bool errorIsRetryable(uint16_t reasonCode)
namespace NVDIMM
{
-// Register the perform Op with the routing code for DIMMs.
+// Register the perform Op router with the routing code for DIMMs.
DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
DeviceFW::NVDIMM,
TARGETING::TYPE_DIMM,
+ nvdimmPerformOpRouter );
+
+// Register the perform Op with the routing code for DIMMs.
+DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
+ DeviceFW::NVDIMM_RAW,
+ TARGETING::TYPE_DIMM,
nvdimmPerformOp );
// ------------------------------------------------------------------
+// nvdimmPerformOpRouter
+// ------------------------------------------------------------------
+errlHndl_t nvdimmPerformOpRouter( 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);
+
+ TRACDCOMP( g_trac_nvdimm,
+ ENTER_MRK"nvdimmPerformOpRouter()" );
+
+ // Get the NVDIMM register's address, where data will be accessed from
+ // Although the data is being retrieved as a 64 bit value
+ // it is really a 16 bit value. Data passed via an arg list
+ // are retrieved in 64 bit chunks.
+ uint16_t l_registerAddress =
+ static_cast<uint16_t>(va_arg(i_args, uint64_t));
+
+ // Get a handle to the data buffer for easy referencing
+ uint8_t* l_data = static_cast<uint8_t*>(io_buffer);
+
+ TRACUCOMP(g_trac_nvdimm, INFO_MRK"nvdimmPerformOpRouter(): "
+ "operation type=%d, target HUID=0x%.8X, access type=%d, "
+ "buffer length=%d, buffer data=0x%.8X, register address=0x%.8X",
+ static_cast<uint64_t>(i_opType), get_huid(i_target), i_accessType,
+ io_buflen, *l_data, l_registerAddress);
+
+ // Make the right read/write call based on operation type
+ if( i_opType == DeviceFW::READ )
+ {
+ l_err = nvdimmReadReg( i_target,
+ l_registerAddress,
+ *l_data,
+ PAGE_VERIFY);
+ if (!l_err)
+ {
+ TRACUCOMP (g_trac_nvdimm, INFO_MRK"nvdimmPerformOpRouter(): "
+ "Read data(0x%X) from register(0x%X)",
+ *l_data, l_registerAddress);
+ }
+ }
+ else if( i_opType == DeviceFW::WRITE )
+ {
+ TRACUCOMP (g_trac_nvdimm, INFO_MRK"nvdimmPerformOpRouter(): "
+ "Writing data(0x%X) to register(0x%X) ...",
+ *l_data, l_registerAddress);
+
+ l_err = nvdimmWriteReg( i_target,
+ l_registerAddress,
+ *l_data,
+ PAGE_VERIFY);
+ }
+
+ TRACDCOMP(g_trac_nvdimm,
+ EXIT_MRK"nvdimmPerformOpRouter() returning with %s",
+ (l_err == nullptr ? "no error, success" : "an error, failure") );
+
+ return l_err;
+}
+
+// ------------------------------------------------------------------
// nvdimmPerformOp
// ------------------------------------------------------------------
errlHndl_t nvdimmPerformOp( DeviceFW::OperationType i_opType,
diff --git a/src/usr/isteps/nvdimm/nvdimmdd.H b/src/usr/isteps/nvdimm/nvdimmdd.H
index 4d599b38a..1e299f2de 100755
--- a/src/usr/isteps/nvdimm/nvdimmdd.H
+++ b/src/usr/isteps/nvdimm/nvdimmdd.H
@@ -138,6 +138,49 @@ errlHndl_t nvdimmPerformOp( DeviceFW::OperationType i_opType,
int64_t i_accessType,
va_list i_args );
+/**
+*
+* @brief Route the read/write operator (i_opType) to the correct
+* nvdimmReadReg/nvdimmWriteReg call.
+*
+* @details This is essentially a wrapper around the nvdimmPerformOp method
+* which is called via the nvdimmReadReg/nvdimmWriteReg call. This
+* ensures that the page is set correctly whenever a NVDIMM register
+* is accessed.
+*
+* @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
+* driververif.H
+*
+* @param[in] i_target - Target device.
+*
+* @param[in/out] io_buffer
+* INPUT: Pointer to the data that will be written to the target
+* device.
+* OUTPUT: Pointer to the data that was read from the target device.
+*
+* @param[in/out] io_buflen
+* INPUT: Length of the buffer to be written to target device.
+* OUTPUT: Length of buffer that was written, or length of buffer
+* to be read from target device.
+*
+* @param [in] i_accessType - Access Type - See DeviceFW::AccessType in
+* usrif.H
+*
+* @param [in] i_args - This is an argument list for the device driver
+* framework. This argument list consists of the internal offset
+* to use on the slave I2C device.
+*
+* @return errlHndl_t - NULL if successful, otherwise a pointer to the
+* error log.
+*
+*/
+errlHndl_t nvdimmPerformOpRouter( DeviceFW::OperationType i_opType,
+ TARGETING::Target * i_target,
+ void * io_buffer,
+ size_t & io_buflen,
+ int64_t i_accessType,
+ va_list i_args );
+
/*
* @brief On the NV Controller, the page is selected by writing to offset
* 0x00 with the page you would like to switch too. e.g. to activate
OpenPOWER on IntegriCloud