summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/usr/i2c/nvdimmif.H9
-rw-r--r--src/include/usr/isteps/nvdimm/nvdimm.H60
-rw-r--r--src/include/usr/targeting/common/util.H11
-rwxr-xr-xsrc/usr/i2c/eepromdd.C3
-rwxr-xr-xsrc/usr/i2c/nvdimmdd.C56
-rw-r--r--src/usr/isteps/istep14/call_mss_power_cleanup.C35
-rw-r--r--src/usr/isteps/nvdimm/makefile25
-rw-r--r--src/usr/isteps/nvdimm/nvdimm.C94
-rw-r--r--src/usr/isteps/nvdimm/nvdimm.H17
-rw-r--r--src/usr/isteps/nvdimm/nvdimm.mk46
-rw-r--r--src/usr/isteps/pm/runtime/makefile7
-rw-r--r--src/usr/isteps/pm/runtime/rt_pm.C45
-rw-r--r--src/usr/targeting/common/util.C45
13 files changed, 259 insertions, 194 deletions
diff --git a/src/include/usr/i2c/nvdimmif.H b/src/include/usr/i2c/nvdimmif.H
index fb875149f..2b60ac4de 100644
--- a/src/include/usr/i2c/nvdimmif.H
+++ b/src/include/usr/i2c/nvdimmif.H
@@ -30,15 +30,6 @@
namespace NVDIMM
{
-//TODO: move isNVDIMM() to targeting/common/util.C
-/**
- * @brief Determine if the given dimm target is an NVDIMM
- *
- * @param[in] i_target : dimm target to check
- *
- * @return bool - True if the given target is an NVDIMM
- */
-bool isNVDIMM( TARGETING::Target * i_target );
/**
* @brief Return a set of information related to every unique
diff --git a/src/include/usr/isteps/nvdimm/nvdimm.H b/src/include/usr/isteps/nvdimm/nvdimm.H
index 3c448a9ac..bfe39fcd0 100644
--- a/src/include/usr/isteps/nvdimm/nvdimm.H
+++ b/src/include/usr/isteps/nvdimm/nvdimm.H
@@ -22,14 +22,26 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-#ifndef NVDIMM_H__
-#define NVDIMM_H__
+#ifndef NVDIMM_EXT_H__
+#define NVDIMM_EXT_H__
#include <targeting/common/util.H>
namespace NVDIMM
{
-
+enum
+{
+ NSTD_VAL_NOPRSV = 0x08, // memory valid, contents not preserved (genesis)
+ NSTD_VAL_NOPRSV_MASK = 0xF7,
+ NSTD_VAL_PRSV = 0x04, // memory contents preserved
+ NSTD_VAL_PRSV_MASK = 0xFB,
+ NSTD_ERR_NOPRSV = 0x02, // memory failed to preserve contents
+ NSTD_ERR_NOPRSV_MASK = 0xFD,
+ NSTD_ERR_NOBKUP = 0x01, // memory unable to preserve future content
+ NSTD_ERR_NOBKUP_MASK = 0xFE,
+ NSTD_ERR = 0x03, // NSTD_ERR_NOPRSV+NSTD_ERR_NOBKUP
+};
+#ifndef __HOSTBOOT_RUNTIME
/**
* @brief Entry function to NVDIMM management
* - Restore image from NVDIMM NAND flash to DRAM
@@ -41,8 +53,48 @@ namespace NVDIMM
*
**/
void nvdimm_restore(TARGETING::TargetHandleList &i_nvdimmList);
+#endif
+
+/**
+ * @brief This function arms the trigger to enable backup in the event
+ * of power loss (DDR Reset_n goes low)
+ *
+ * @param[in] i_nvdimm - nvdimm target with NV controller
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t nvdimmArmResetN(TARGETING::Target *i_nvdimm);
+
+/**
+ * @brief This function erases image on the nvdimm target
+ *
+ * @param[in] i_nvdimm - nvdimm target with NV controller
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t nvdimmEraseNF(TARGETING::Target *i_nvdimm);
+
+/**
+ * @brief Check nvdimm error state
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @return bool - true if nvdimm is in any error state, false otherwise
+ */
+bool nvdimmInErrorState(TARGETING::Target *i_nvdimm);
+/**
+ * @brief Set the status flag
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[in] i_status_flag - status flag to set for each nvdimm
+ *
+ */
+void nvdimmSetStatusFlag(TARGETING::Target *i_nvdimm, const uint8_t i_status_flag);
}
-#endif // NVDIMM_H__
+#endif // NVDIMM_EXT_H__
diff --git a/src/include/usr/targeting/common/util.H b/src/include/usr/targeting/common/util.H
index 68b61b1f1..971408d16 100644
--- a/src/include/usr/targeting/common/util.H
+++ b/src/include/usr/targeting/common/util.H
@@ -172,6 +172,15 @@ bool orderByNodeAndPosition( Target* i_firstProc,
*/
uint8_t is_fused_mode( );
-} // TARGETING
+/**
+ * @brief Determine if the given dimm target is an NVDIMM
+ *
+ * @param[in] i_target : dimm target to check
+ *
+ * @return bool - True if the given target is an NVDIMM
+ */
+bool isNVDIMM( TARGETING::Target * i_target );
+
+}
#endif // __TARGETING_COMMON_UTIL_H
diff --git a/src/usr/i2c/eepromdd.C b/src/usr/i2c/eepromdd.C
index c1cbf45c8..8f94e0c3b 100755
--- a/src/usr/i2c/eepromdd.C
+++ b/src/usr/i2c/eepromdd.C
@@ -43,6 +43,7 @@
#include <errl/errludtarget.H>
#include <errl/errludstring.H>
#include <targeting/common/targetservice.H>
+#include <targeting/common/util.H>
#include <devicefw/driverif.H>
#include <i2c/eepromddreasoncodes.H>
#include <i2c/eepromif.H>
@@ -2100,7 +2101,7 @@ void getEEPROMs( std::list<EepromInfo_t>& o_info )
{
#ifdef CONFIG_NVDIMM
// Skip if this is an NVDIMM as this will get added later
- if (NVDIMM::isNVDIMM( *dimm_itr ))
+ if (TARGETING::isNVDIMM( *dimm_itr ))
continue;
#endif
add_to_list( o_info, *dimm_itr );
diff --git a/src/usr/i2c/nvdimmdd.C b/src/usr/i2c/nvdimmdd.C
index 6afac1d18..b70fd0915 100755
--- a/src/usr/i2c/nvdimmdd.C
+++ b/src/usr/i2c/nvdimmdd.C
@@ -43,6 +43,7 @@
#include <errl/errludstring.H>
#include <targeting/common/targetservice.H>
#include <targeting/common/utilFilter.H>
+#include <targeting/common/util.H>
#include <devicefw/driverif.H>
#include <i2c/nvdimmddreasoncodes.H>
#include <i2c/nvdimmif.H>
@@ -75,8 +76,6 @@ TRAC_INIT( & g_trac_nvdimmr, "NVDIMMR", KILOBYTE );
// ----------------------------------------------
#define MAX_BYTE_ADDR 2
#define NVDIMM_MAX_RETRIES 2
-#define MCA_PER_MCS 2
-#define DIMM_PER_MCA 2
// ----------------------------------------------
@@ -498,10 +497,10 @@ errlHndl_t nvdimmReadData( TARGETING::Target * i_target,
i_byteAddressSize);
// Printing mux info separately, if combined, nothing is displayed
- char* l_muxPath = i2cInfo.i2cMuxPath.toString();
+ char* l_muxPath = i_i2cInfo.i2cMuxPath.toString();
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReadData(): "
"muxSelector=0x%X, muxPath=%s",
- i2cInfo.i2cMuxBusSelector,
+ i_i2cInfo.i2cMuxBusSelector,
l_muxPath);
free(l_muxPath);
l_muxPath = nullptr;
@@ -535,10 +534,10 @@ errlHndl_t nvdimmReadData( TARGETING::Target * i_target,
i_i2cInfo.devAddr );
// Printing mux info separately, if combined, nothing is displayed
- char* l_muxPath = i2cInfo.i2cMuxPath.toString();
+ char* l_muxPath = i_i2cInfo.i2cMuxPath.toString();
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReadData(): "
"muxSelector=0x%X, muxPath=%s",
- i2cInfo.i2cMuxBusSelector,
+ i_i2cInfo.i2cMuxBusSelector,
l_muxPath);
free(l_muxPath);
l_muxPath = nullptr;
@@ -1459,49 +1458,6 @@ void add_to_list( std::list<EEPROM::EepromInfo_t>& i_list,
}
/**
- * @brief Determine if the given dimm target is an NVDIMM
- *
- * @param[in] i_target : dimm target to check
- *
- * @return bool - True if the given target is an NVDIMM
- */
-bool isNVDIMM( TARGETING::Target * i_target )
-{
- // Not the most elegant way of doing it but the hybrid attributes
- // are at the MCS level. Need to find my way up to MCS and check
- // if the dimm is hybrid
-
- TARGETING::TargetHandleList l_mcaList;
- getParentAffinityTargets(l_mcaList, i_target, TARGETING::CLASS_UNIT, TARGETING::TYPE_MCA);
-
- if (l_mcaList.size())
- {
- TARGETING::TargetHandleList l_mcsList;
- getParentAffinityTargets(l_mcsList, l_mcaList[0], TARGETING::CLASS_UNIT, TARGETING::TYPE_MCS);
-
- if(l_mcsList.size())
- {
- // 2-D array. [MCA][DIMM]
- TARGETING::ATTR_EFF_HYBRID_type l_hybrid;
- TARGETING::ATTR_EFF_HYBRID_MEMORY_TYPE_type l_hybrid_type;
-
- if( l_mcsList[0]->tryGetAttr<TARGETING::ATTR_EFF_HYBRID>(l_hybrid) &&
- l_mcsList[0]->tryGetAttr<TARGETING::ATTR_EFF_HYBRID_MEMORY_TYPE>(l_hybrid_type) )
- {
- //Using huid to lookup the hybrid attribute for the current dimm
- const auto l_dimm_huid = TARGETING::get_huid(i_target);
- const auto l_mca_huid = TARGETING::get_huid(l_mcaList[0]);
-
- return (l_hybrid[l_mca_huid%MCA_PER_MCS][l_dimm_huid%DIMM_PER_MCA] == TARGETING::EFF_HYBRID_IS_HYBRID &&
- l_hybrid_type[l_mca_huid%MCA_PER_MCS][l_dimm_huid%DIMM_PER_MCA] == TARGETING::EFF_HYBRID_MEMORY_TYPE_NVDIMM);
- }
- }
- }
-
- return false;
-}
-
-/**
* @brief Return a set of information related to every unique
* NVDIMM in the system
*/
@@ -1517,7 +1473,7 @@ void getNVDIMMs( std::list<EEPROM::EepromInfo_t>& o_info )
for (auto const l_dimm : l_dimmList)
{
- if (isNVDIMM(l_dimm))
+ if (TARGETING::isNVDIMM(l_dimm))
add_to_list( o_info, l_dimm );
}
diff --git a/src/usr/isteps/istep14/call_mss_power_cleanup.C b/src/usr/isteps/istep14/call_mss_power_cleanup.C
index 861647e09..5c27dcc67 100644
--- a/src/usr/isteps/istep14/call_mss_power_cleanup.C
+++ b/src/usr/isteps/istep14/call_mss_power_cleanup.C
@@ -116,40 +116,9 @@ void* call_mss_power_cleanup (void *io_pArgs)
// Walk the dimm list and collect all the nvdimm targets
for (auto const l_dimm : l_dimmTargetList)
{
- //@TODO replace this with isNVDIMM()
- // Not the most elegant way of doing it but the hybrid attributes
- // are at the MCS level. Need to find my way up to MCS and check
- // if the dimm is hybrid
- TARGETING::TargetHandleList l_mcaList;
- getParentAffinityTargets(l_mcaList, l_dimm, TARGETING::CLASS_UNIT, TARGETING::TYPE_MCA);
-
- if (l_mcaList.size())
+ if (TARGETING::isNVDIMM(l_dimm))
{
- TARGETING::TargetHandleList l_mcsList;
- getParentAffinityTargets(l_mcsList, l_mcaList[0], TARGETING::CLASS_UNIT, TARGETING::TYPE_MCS);
-
- if(l_mcsList.size())
- {
- // 2-D array. [MCA][DIMM]
- TARGETING::ATTR_EFF_HYBRID_type l_hybrid;
- TARGETING::ATTR_EFF_HYBRID_MEMORY_TYPE_type l_hybrid_type;
-
- if( l_mcsList[0]->tryGetAttr<TARGETING::ATTR_EFF_HYBRID>(l_hybrid) &&
- l_mcsList[0]->tryGetAttr<TARGETING::ATTR_EFF_HYBRID_MEMORY_TYPE>(l_hybrid_type) )
- {
- //Using huid to lookup the hybrid attribute for the current dimm
- const auto l_dimm_huid = TARGETING::get_huid(l_dimm);
- const auto l_mca_huid = TARGETING::get_huid(l_mcaList[0]);
- const uint8_t MCA_PER_MCS = 2;
- const uint8_t DIMM_PER_MCA = 2;
-
- if (l_hybrid[l_mca_huid%MCA_PER_MCS][l_dimm_huid%DIMM_PER_MCA] == TARGETING::EFF_HYBRID_IS_HYBRID &&
- l_hybrid_type[l_mca_huid%MCA_PER_MCS][l_dimm_huid%DIMM_PER_MCA] == TARGETING::EFF_HYBRID_MEMORY_TYPE_NVDIMM )
- {
- l_nvdimmTargetList.push_back(l_dimm);
- }
- }
- }
+ l_nvdimmTargetList.push_back(l_dimm);
}
}
diff --git a/src/usr/isteps/nvdimm/makefile b/src/usr/isteps/nvdimm/makefile
index a39be6f0e..ae3cae843 100644
--- a/src/usr/isteps/nvdimm/makefile
+++ b/src/usr/isteps/nvdimm/makefile
@@ -24,30 +24,7 @@
# IBM_PROLOG_END_TAG
ROOTPATH = ../../../..
-PROCEDURE_PATH = ${ROOTPATH}/src/import/chips/p9/procedures
-
-#Add all the extra include paths
-
-EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/
-EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include
-EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2
-EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs/
-EXTRAINCDIR += ${ROOTPATH}/src/import/
-EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory
-EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/common/include/
-EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory/lib/eff_config/
-EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory/lib/
-EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory/lib/mcbist/
-EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory/lib/dimm/
-EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory/lib/dimm/ddr4/
-EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory/
-EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/ffdc/
-
MODULE = nvdimm
-OBJS += nvdimm.o
-
+include nvdimm.mk
include ${ROOTPATH}/config.mk
-
-VPATH += ${PROCEDURE_PATH}/hwp/memory/
-VPATH += ${PROCEDURE_PATH}/hwp/memory/lib/dimm/ddr4/
diff --git a/src/usr/isteps/nvdimm/nvdimm.C b/src/usr/isteps/nvdimm/nvdimm.C
index d98397edb..13ecf0af5 100644
--- a/src/usr/isteps/nvdimm/nvdimm.C
+++ b/src/usr/isteps/nvdimm/nvdimm.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -32,12 +32,12 @@
#include <targeting/common/commontargeting.H>
#include <targeting/common/util.H>
#include <targeting/common/utilFilter.H>
-#include <kernel/timemgr.H>
#include <sys/time.h>
#include <usr/devicefw/userif.H>
#include <fapi2.H>
#include <fapi2/plat_hwp_invoker.H>
#include <lib/dimm/ddr4/nvdimm_utils.H>
+#include <lib/mc/port.H>
#include <isteps/nvdimm/nvdimm.H>
using namespace TARGETING;
@@ -45,7 +45,7 @@ using namespace DeviceFW;
using namespace EEPROM;
trace_desc_t* g_trac_nvdimm = NULL;
-TRAC_INIT(&g_trac_nvdimm, "NVDIMM", 2*KILOBYTE);
+TRAC_INIT(&g_trac_nvdimm, NVDIMM_COMP_NAME, 2*KILOBYTE);
// Easy macro replace for unit testing
// #define TRACUCOMP(args...) TRACFCOMP(args)
@@ -61,19 +61,6 @@ namespace NVDIMM
#define NVDIMM_SET_USER_DATA_2_TIMEOUT(left_32_polled, right_32_timeout) \
NVDIMM_SET_USER_DATA_1(left_32_polled, right_32_timeout)
-enum
-{
- NSTD_VAL_NOPRSV = 0x08, // memory valid, contents not preserved (genesis)
- NSTD_VAL_NOPRSV_MASK = 0xF7,
- NSTD_VAL_PRSV = 0x04, // memory contents preserved
- NSTD_VAL_PRSV_MASK = 0xFB,
- NSTD_ERR_NOPRSV = 0x02, // memory failed to preserve contents
- NSTD_ERR_NOPRSV_MASK = 0xFD,
- NSTD_ERR_NOBKUP = 0x01, // memory unable to preserve future content
- NSTD_ERR_NOBKUP_MASK = 0xFE,
- NSTD_ERR = 0x03, // NSTD_ERR_NOPRSV+NSTD_ERR_NOBKUP
-};
-
typedef struct ops_timeoutInfo{
const char * desc;
uint8_t page;
@@ -83,7 +70,10 @@ typedef struct ops_timeoutInfo{
uint8_t status_progress;
} ops_timeoutInfo_t;
-static bool init = true;
+#ifndef __HOSTBOOT_RUNTIME
+// Init flag to be used upon initial entry to initialize NV_OPS_TIMEOUT_MSEC
+static bool init_nv_timeout = true;
+#endif
// Table containing register info on the timeout registers for different ops
constexpr ops_timeoutInfo_t timeoutInfoTable[] =
@@ -686,7 +676,10 @@ errlHndl_t nvdimmCheckArmSuccess(Target *i_nvdimm)
/**
* @brief This function arms the trigger to enable backup in the event
- * of power loss (DDR Reset_n goes low)
+ * of power loss (DDR Reset_n goes low) in conjunction with
+ * ATOMIC_SAVE_AND_ERASE. A separate erase command is not required
+ * as the image will get erased immediately before backup on the
+ * next catastrophic event.
*
* @param[in] i_nvdimm - nvdimm target with NV controller
*
@@ -700,7 +693,10 @@ errlHndl_t nvdimmArmResetN(Target *i_nvdimm)
errlHndl_t l_err = nullptr;
- l_err = nvdimmWriteReg(i_nvdimm, ARM_CMD, ARM_DIMM);
+ // Setting ATOMIC_SAVE_AND_ERASE in conjunction with ARM_RESETN. With this,
+ // the content of the persistent data is not erased until immediately after
+ // the next catastrophic event has occurred.
+ l_err = nvdimmWriteReg(i_nvdimm, ARM_CMD, ARM_RESETN_AND_ATOMIC_SAVE_AND_ERASE);
if (l_err)
{
@@ -760,6 +756,7 @@ errlHndl_t nvdimmValidImage(Target *i_nvdimm, bool &o_imgValid)
return l_err;
}
+#ifndef __HOSTBOOT_RUNTIME
/**
* @brief This function handles all the restore related operations.
* SRE -> restore -> SRX/RCD/MRS
@@ -775,6 +772,8 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList)
bool l_imgValid;
uint8_t l_rstrValid;
uint32_t l_poll = 0;
+ TARGETING::Target* l_sys = NULL;
+ targetService().getTopLevelTarget(l_sys);
do
{
@@ -864,9 +863,9 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList)
//@TODO RTC 199645 - add HW callout on dimm target
//Restore is taking longer than the allotted time here.
nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOPRSV);
- errlCommit(l_err, NVDIMM_COMP_ID);
TRACFCOMP(g_trac_nvdimm, ERR_MRK"NDVIMM HUID[%X], error restoring!",
TARGETING::get_huid(l_nvdimm));
+ errlCommit(l_err, NVDIMM_COMP_ID);
break;
}
}
@@ -963,6 +962,7 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList)
return l_err;
}
+#endif
/**
* @brief This function checks the erase status register to make sure
@@ -1249,6 +1249,7 @@ errlHndl_t nvdimmGetTimeoutVal(Target* i_nvdimm)
return l_err;
}
+#ifndef __HOSTBOOT_RUNTIME
/**
* @brief Entry function to NVDIMM management
* - Restore image from NVDIMM NAND flash to DRAM
@@ -1261,7 +1262,7 @@ errlHndl_t nvdimmGetTimeoutVal(Target* i_nvdimm)
*/
void nvdimm_restore(TargetHandleList &i_nvdimmList)
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_restore()");
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_restore()");
errlHndl_t l_err = nullptr;
do
@@ -1283,13 +1284,12 @@ void nvdimm_restore(TargetHandleList &i_nvdimmList)
if (l_err)
{
- errlCommit( l_err, NVDIMM_COMP_ID );
-
// @TODO-RTC:200275-Make logic generic for all system configs
// Because of interleaving, if one is garded the other one
// in the pair should be garded by association. So, let's
// move on since there is nothing else to do.
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_restore() - Failing open page");
+ errlCommit( l_err, NVDIMM_COMP_ID );
break;
}
@@ -1310,9 +1310,8 @@ void nvdimm_restore(TargetHandleList &i_nvdimmList)
// If this failing right off the bat,
// something isn't quite right with
// the module
- errlCommit(l_err, NVDIMM_COMP_ID);
-
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_restore() - Failing nvdimmReady()");
+ errlCommit(l_err, NVDIMM_COMP_ID);
break;
}
@@ -1328,13 +1327,13 @@ void nvdimm_restore(TargetHandleList &i_nvdimmList)
// This will prevent future backup, but let's continue
// since we can still restore the data if there is any
nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
- errlCommit( l_err, NVDIMM_COMP_ID );
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_restore() - Failing nvdimmSetESPolicy()");
+ errlCommit( l_err, NVDIMM_COMP_ID );
}
}
// Get the timeout values for the major ops at init
- if (init){
+ if (init_nv_timeout){
for (const auto & l_nvdimm : i_nvdimmList){
l_err = nvdimmGetTimeoutVal(l_nvdimm);
if (l_err)
@@ -1343,13 +1342,13 @@ void nvdimm_restore(TargetHandleList &i_nvdimmList)
break;
}
}
- init = false;
+ init_nv_timeout = false;
}
if (l_err)
{
- errlCommit( l_err, NVDIMM_COMP_ID );
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_restore() - Failing nvdimmGetTimeoutVal()");
+ errlCommit( l_err, NVDIMM_COMP_ID );
break;
}
@@ -1368,8 +1367,8 @@ void nvdimm_restore(TargetHandleList &i_nvdimmList)
if (l_err)
{
- errlCommit( l_err, NVDIMM_COMP_ID );
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_restore() - Failing open page");
+ errlCommit( l_err, NVDIMM_COMP_ID );
break;
}
@@ -1378,8 +1377,8 @@ void nvdimm_restore(TargetHandleList &i_nvdimmList)
if (l_err)
{
- errlCommit( l_err, NVDIMM_COMP_ID );
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_restore() - Failing nvdimmRestore()");
+ errlCommit( l_err, NVDIMM_COMP_ID );
break;
}
@@ -1397,39 +1396,10 @@ void nvdimm_restore(TargetHandleList &i_nvdimmList)
}
}
- // @TODO move arm and erase to pm_common.C, after occ has started
-
- // From this point forward, we only want to set up the trigger on the
- // nvdimm that is not in error state. Any nvdimm in error state will
- // get to preserve the data previously saved and recover if needed.
-
- // Arm the nvdimm to trigger save on RESET_n
- // and erase the image
- for (const auto & l_nvdimm : i_nvdimmList)
- {
- // skip if the nvdimm is in error state
- if (nvdimmInErrorState(l_nvdimm))
- {
- continue;
- }
-
- l_err = nvdimmArmResetN(l_nvdimm);
- if (l_err)
- {
- nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
- errlCommit( l_err, NVDIMM_COMP_ID );
- continue;
- }
-
- l_err = nvdimmEraseNF(l_nvdimm);
- if (l_err){
- errlCommit( l_err, NVDIMM_COMP_ID );
- nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
- }
- }
}while(0);
- TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_restore()");
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_restore()");
}
+#endif
} // end NVDIMM namespace
diff --git a/src/usr/isteps/nvdimm/nvdimm.H b/src/usr/isteps/nvdimm/nvdimm.H
index 12a2ee2aa..b365c405b 100644
--- a/src/usr/isteps/nvdimm/nvdimm.H
+++ b/src/usr/isteps/nvdimm/nvdimm.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2018 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -75,13 +75,13 @@ enum page : uint8_t
// Enums for inputs/expected output to/from the i2c registers
enum i2c_in_values : uint8_t
{
- ARM_DIMM = 0x04, //0x04 to trigger on RESET_n
- ES_DEV_MANAGE = 0x01, //0x01 for device manage
- ERASE_IMAGE = 0x08,
- RESTORE_IMAGE = 0x04,
- RESET_CTRLR = 0x01,
- VALID_IMAGE = 0x01,
- PAGE_SWITCH_POLL_TIME_NS = 100,
+ ARM_RESETN_AND_ATOMIC_SAVE_AND_ERASE = 0x84,
+ ARM_RESETN = 0x04,
+ ES_DEV_MANAGE = 0x01, //0x01 for device manage
+ ERASE_IMAGE = 0x08,
+ RESTORE_IMAGE = 0x04,
+ RESET_CTRLR = 0x01,
+ VALID_IMAGE = 0x01,
};
enum i2c_out_values : uint8_t
@@ -104,6 +104,7 @@ enum i2c_out_values : uint8_t
enum timeout : uint32_t
{
OPS_POLL_TIME_MS = 5000,
+ PAGE_SWITCH_POLL_TIME_NS = 100,
};
// Assign an id to each of the 6 major ops
diff --git a/src/usr/isteps/nvdimm/nvdimm.mk b/src/usr/isteps/nvdimm/nvdimm.mk
new file mode 100644
index 000000000..0c09584d5
--- /dev/null
+++ b/src/usr/isteps/nvdimm/nvdimm.mk
@@ -0,0 +1,46 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/isteps/nvdimm/nvdimm.mk $
+#
+# 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
+PROCEDURE_PATH = ${ROOTPATH}/src/import/chips/p9/procedures
+
+#Add all the extra include paths
+
+EXTRAINCDIR += ${ROOTPATH}/obj/genfiles/
+EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/common/utils/imageProcs/
+EXTRAINCDIR += ${ROOTPATH}/src/import/
+EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory
+EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/common/include/
+EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory/lib/eff_config/
+EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory/lib/
+EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory/lib/mcbist/
+EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory/lib/dimm/
+EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory/lib/dimm/ddr4/
+EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/memory/
+EXTRAINCDIR += ${PROCEDURE_PATH}/hwp/ffdc/
+
+OBJS += nvdimm.o
+
+VPATH += ${PROCEDURE_PATH}/hwp/memory/lib/dimm/ddr4/
diff --git a/src/usr/isteps/pm/runtime/makefile b/src/usr/isteps/pm/runtime/makefile
index ecffa4f37..c3be1b818 100644
--- a/src/usr/isteps/pm/runtime/makefile
+++ b/src/usr/isteps/pm/runtime/makefile
@@ -31,12 +31,17 @@ VPATH += ../
MODULE = pm_rt
+EXTRAINCDIR += ${ROOTPATH}/src/usr/isteps/nvdimm
+
## Objects unique to HBRT
OBJS += rt_pm.o
+## Dependencies for nvdimm.mk
+VPATH += ${ROOTPATH}/src/usr/isteps/nvdimm
+
SUBDIRS += test.d
## Objects common to HBRT and HB IPL
include ../pm.mk
-
+include ${ROOTPATH}/src/usr/isteps/nvdimm/nvdimm.mk
include ${ROOTPATH}/config.mk
diff --git a/src/usr/isteps/pm/runtime/rt_pm.C b/src/usr/isteps/pm/runtime/rt_pm.C
index 163a78b55..3e5ab8c10 100644
--- a/src/usr/isteps/pm/runtime/rt_pm.C
+++ b/src/usr/isteps/pm/runtime/rt_pm.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016,2018 */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -44,9 +44,12 @@
#include <initservice/isteps_trace.H>
// targeting support
+#include <targeting/common/util.H>
#include <targeting/common/utilFilter.H>
#include <targeting/common/targetservice.H>
+#include <isteps/nvdimm/nvdimm.H>
+
#include <scom/scomif.H>
#include <scom/wakeup.H>
@@ -256,7 +259,47 @@ namespace RTPM
l_err->collectTrace(ISTEP_COMP_NAME,1024);
errlCommit( l_err, RUNTIME_COMP_ID );
l_err = nullptr;
+ break;
+ }
+
+#ifdef CONFIG_NVDIMM
+ //@TODO RTC 199645 - additional delay needed to ensure OCC is
+ // full functional
+
+ // Only run this if PM complex started successfully
+ // as EPOW save trigger is done by the OCC
+ TARGETING::TargetHandleList l_dimmTargetList;
+ getChildAffinityTargets( l_dimmTargetList, proc_target, CLASS_NA, TYPE_DIMM );
+
+ for (auto const l_dimm : l_dimmTargetList)
+ {
+ if (TARGETING::isNVDIMM(l_dimm))
+ {
+ // skip if the nvdimm is in error state
+ if (NVDIMM::nvdimmInErrorState(l_dimm))
+ {
+ continue;
+ }
+
+ l_err = NVDIMM::nvdimmArmResetN(l_dimm);
+ // If we run into any error here we will just
+ // commit the error log and move on. Let the
+ // system continue to boot and let the user
+ // salvage the data
+ if (l_err)
+ {
+ NVDIMM::nvdimmSetStatusFlag(l_dimm, NVDIMM::NSTD_ERR_NOBKUP);
+ // Committing the error as we don't want the this to interrupt
+ // the boot. This will notifiy the user that action is needed
+ // on this module
+ l_err->setSev(ERRL_SEV_INFORMATIONAL);
+ l_err->collectTrace(NVDIMM_COMP_NAME,1024);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue;
+ }
+ }
}
+#endif
} while(0);
if ( l_err )
diff --git a/src/usr/targeting/common/util.C b/src/usr/targeting/common/util.C
index c8b8c7c5f..a5a9bb7a9 100644
--- a/src/usr/targeting/common/util.C
+++ b/src/usr/targeting/common/util.C
@@ -38,6 +38,9 @@
#include <targeting/common/utilFilter.H>
#include <targeting/common/trace.H>
+#define MCA_PER_MCS 2
+#define DIMM_PER_MCA 2
+
namespace TARGETING
{
@@ -281,4 +284,46 @@ uint8_t is_fused_mode( )
} // end is_fused_mode
+/**
+ * @brief Determine if the given dimm target is an NVDIMM
+ *
+ * @param[in] i_target : dimm target to check
+ *
+ * @return bool - True if the given target is an NVDIMM
+ */
+bool isNVDIMM( TARGETING::Target * i_target )
+{
+ // Not the most elegant way of doing it but the hybrid attributes
+ // are at the MCS level. Need to find my way up to MCS and check
+ // if the dimm is hybrid
+ TARGETING::TargetHandleList l_mcaList;
+ getParentAffinityTargets(l_mcaList, i_target, TARGETING::CLASS_UNIT, TARGETING::TYPE_MCA);
+
+ if (l_mcaList.size())
+ {
+ TARGETING::TargetHandleList l_mcsList;
+ getParentAffinityTargets(l_mcsList, l_mcaList[0], TARGETING::CLASS_UNIT, TARGETING::TYPE_MCS);
+
+ if(l_mcsList.size())
+ {
+ // 2-D array. [MCA][DIMM]
+ TARGETING::ATTR_EFF_HYBRID_type l_hybrid;
+ TARGETING::ATTR_EFF_HYBRID_MEMORY_TYPE_type l_hybrid_type;
+
+ if( l_mcsList[0]->tryGetAttr<TARGETING::ATTR_EFF_HYBRID>(l_hybrid) &&
+ l_mcsList[0]->tryGetAttr<TARGETING::ATTR_EFF_HYBRID_MEMORY_TYPE>(l_hybrid_type) )
+ {
+ //Using relative position to lookup the hybrid attribute for the current dimm
+ TARGETING::ATTR_REL_POS_type l_dimm_rel_pos = i_target->getAttr<ATTR_REL_POS>();
+ TARGETING::ATTR_REL_POS_type l_mca_rel_pos = l_mcaList[0]->getAttr<ATTR_REL_POS>();
+
+ return (l_hybrid[l_mca_rel_pos][l_dimm_rel_pos] == TARGETING::EFF_HYBRID_IS_HYBRID &&
+ l_hybrid_type[l_mca_rel_pos][l_dimm_rel_pos] == TARGETING::EFF_HYBRID_MEMORY_TYPE_NVDIMM);
+ }
+ }
+ }
+
+ return false;
+}
+
} // end namespace TARGETING
OpenPOWER on IntegriCloud