diff options
Diffstat (limited to 'src/usr/isteps/nvdimm/runtime/nvdimm_rt.C')
-rw-r--r-- | src/usr/isteps/nvdimm/runtime/nvdimm_rt.C | 147 |
1 files changed, 128 insertions, 19 deletions
diff --git a/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C b/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C index 42a7b49d3..d615aa546 100644 --- a/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C +++ b/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C @@ -41,7 +41,6 @@ #include <usr/runtime/rt_targeting.H> #include <runtime/interface.h> #include <arch/ppc.H> -#include <lib/shared/nimbus_defaults.H> #include <isteps/nvdimm/nvdimmreasoncodes.H> #include "../errlud_nvdimm.H" #include "../nvdimmErrorLog.H" @@ -142,10 +141,9 @@ errlHndl_t nvdimmCheckArmSuccess(Target *i_nvdimm, bool i_arm_timeout) // Failure to arm could mean internal NV controller error or // even error on the battery pack. NVDIMM will lose persistency // if failed to arm trigger - l_err->addPartCallout( i_nvdimm, - HWAS::NV_CONTROLLER_PART_TYPE, + l_err->addHwCallout( i_nvdimm, HWAS::SRCI_PRIORITY_HIGH, - HWAS::DECONFIG, + HWAS::NO_DECONFIG, HWAS::GARD_Fatal); } @@ -162,6 +160,9 @@ bool nvdimmArm(TargetHandleList &i_nvdimmTargetList) bool l_arm_timeout = false; uint8_t l_data; auto l_RegInfo = nvdimm_reg_t(); + uint64_t l_writeData; + uint32_t l_writeAddress; + size_t l_writeSize = sizeof(l_writeData); TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmArm() %d", i_nvdimmTargetList.size()); @@ -169,6 +170,27 @@ bool nvdimmArm(TargetHandleList &i_nvdimmTargetList) errlHndl_t l_err = nullptr; errlHndl_t l_err_t = nullptr; + // Mask MBACALFIR EventN to separate ARM handling + for (TargetHandleList::iterator it = i_nvdimmTargetList.begin(); + it != i_nvdimmTargetList.end();) + { + TargetHandleList l_mcaList; + getParentAffinityTargets(l_mcaList, *it, CLASS_UNIT, TYPE_MCA); + assert(l_mcaList.size(), "nvdimmArm() failed to find parent MCA."); + + l_writeAddress = MBACALFIR_OR_MASK_REG; + l_writeData = MBACALFIR_EVENTN_OR_BIT; + l_err = deviceWrite(l_mcaList[0], &l_writeData, l_writeSize, + DEVICE_SCOM_ADDRESS(l_writeAddress)); + if(l_err) + { + TRACFCOMP(g_trac_nvdimm, "SCOM to address 0x%08x failed", + l_writeAddress); + errlCommit( l_err, NVDIMM_COMP_ID ); + } + it++; + } + for (auto const l_nvdimm : i_nvdimmTargetList) { l_arm_timeout = false; @@ -202,9 +224,8 @@ bool nvdimmArm(TargetHandleList &i_nvdimmTargetList) l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE); l_err->collectTrace(NVDIMM_COMP_NAME); - // Callout nvdimm on high, gard and deconfig - l_err->addPartCallout( l_nvdimm, - HWAS::NV_CONTROLLER_PART_TYPE, + // Callout the nvdimm on high and gard + l_err->addHwCallout( l_nvdimm, HWAS::SRCI_PRIORITY_HIGH, HWAS::NO_DECONFIG, HWAS::GARD_Fatal); @@ -213,6 +234,15 @@ bool nvdimmArm(TargetHandleList &i_nvdimmTargetList) break; } + // Clear ARM status register + l_err = nvdimmWriteReg(l_nvdimm, NVDIMM_MGT_CMD0, ARM_CLEAR); + if (l_err) + { + TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmArm() nvdimm[%X] - error clearing ARM status register", + get_huid(l_nvdimm)); + break; + } + l_err = NVDIMM::nvdimmChangeArmState(l_nvdimm, ARM_TRIGGER); // If we run into any error here we will just // commit the error log and move on. Let the @@ -365,24 +395,26 @@ bool nvdimmArm(TargetHandleList &i_nvdimmTargetList) errlCommit(l_err, NVDIMM_COMP_ID); } - // Enable event notification - l_err = nvdimmWriteReg(l_nvdimm, SET_EVENT_NOTIFICATION_CMD, PERSISTENCY_NOTIFICATION); + // Enable Persistency and Warning Threshold notifications + l_err = nvdimmWriteReg(l_nvdimm, SET_EVENT_NOTIFICATION_CMD, ENABLE_NOTIFICATIONS); if (l_err) { - TRACFCOMP(g_trac_nvdimm, ERR_MRK"NDVIMM HUID[%X] error initiating erase!!", + TRACFCOMP(g_trac_nvdimm, ERR_MRK"NDVIMM HUID[%X] setting persistency notification", TARGETING::get_huid(l_nvdimm)); - errlCommit(l_err, NVDIMM_COMP_ID); + break; } // Check notification status and errors l_err = nvdimmReadReg(l_nvdimm, SET_EVENT_NOTIFICATION_STATUS, l_data); if (l_err) { - errlCommit( l_err, NVDIMM_COMP_ID ); + break; } - else if (((l_data & SET_EVENT_NOTIFICATION_ERROR) == SET_EVENT_NOTIFICATION_ERROR) || ((l_data & PERSISTENCY_ENABLED) != PERSISTENCY_ENABLED)) + else if (((l_data & SET_EVENT_NOTIFICATION_ERROR) == SET_EVENT_NOTIFICATION_ERROR) + || ((l_data & NOTIFICATIONS_ENABLED) != NOTIFICATIONS_ENABLED)) { - TRACFCOMP(g_trac_nvdimm, "nvdimmArm() nvdimm[%X] failed to set event notification", get_huid(l_nvdimm)); + TRACFCOMP(g_trac_nvdimm, "nvdimmArm() nvdimm[%X] failed to set event notification", + get_huid(l_nvdimm)); // Set NVDIMM Status flag to partial working, as error detected but data might persist nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_VAL_SR); @@ -407,11 +439,11 @@ bool nvdimmArm(TargetHandleList &i_nvdimmTargetList) l_err->collectTrace( NVDIMM_COMP_NAME ); - // Callout, deconfig and gard the dimm - l_err->addPartCallout( l_nvdimm, - HWAS::NV_CONTROLLER_PART_TYPE, - HWAS::SRCI_PRIORITY_LOW); - + // Callout the dimm + l_err->addHwCallout( l_nvdimm, + HWAS::SRCI_PRIORITY_LOW, + HWAS::NO_DECONFIG, + HWAS::GARD_NULL); // Read relevant regs for trace data nvdimmTraceRegs(l_nvdimm, l_RegInfo); @@ -438,6 +470,83 @@ bool nvdimmArm(TargetHandleList &i_nvdimmTargetList) } + // Check for uncommited i2c fail error logs + if (l_err) + { + TRACFCOMP(g_trac_nvdimm, "nvdimmArm() failed an i2c read/write"); + errlCommit( l_err, NVDIMM_COMP_ID ); + nvdimmDisarm(i_nvdimmTargetList); + return false; + } + + // Unmask MBACALFIR EventN and set to recoverable + for (TargetHandleList::iterator it = i_nvdimmTargetList.begin(); + it != i_nvdimmTargetList.end();) + { + TargetHandleList l_mcaList; + getParentAffinityTargets(l_mcaList, *it, CLASS_UNIT, TYPE_MCA); + assert(l_mcaList.size(), "nvdimmArm() failed to find parent MCA."); + + // Set MBACALFIR_ACTION0 to recoverable + l_writeAddress = MBACALFIR_ACTION0_REG; + l_writeData = 0; + l_err = deviceRead(l_mcaList[0], &l_writeData, l_writeSize, + DEVICE_SCOM_ADDRESS(l_writeAddress)); + if(l_err) + { + TRACFCOMP(g_trac_nvdimm, "SCOM to address 0x%08x failed", + l_writeAddress); + errlCommit( l_err, NVDIMM_COMP_ID ); + } + + + l_writeData &= MBACALFIR_EVENTN_AND_BIT; + l_err = deviceWrite(l_mcaList[0], &l_writeData, l_writeSize, + DEVICE_SCOM_ADDRESS(l_writeAddress)); + if(l_err) + { + TRACFCOMP(g_trac_nvdimm, "SCOM to address 0x%08x failed", + l_writeAddress); + errlCommit( l_err, NVDIMM_COMP_ID ); + } + + // Set MBACALFIR_ACTION1 to recoverable + l_writeAddress = MBACALFIR_ACTION1_REG; + l_writeData = 0; + l_err = deviceRead(l_mcaList[0], &l_writeData, l_writeSize, + DEVICE_SCOM_ADDRESS(l_writeAddress)); + if(l_err) + { + TRACFCOMP(g_trac_nvdimm, "SCOM to address 0x%08x failed", + l_writeAddress); + errlCommit( l_err, NVDIMM_COMP_ID ); + } + + l_writeData |= MBACALFIR_EVENTN_OR_BIT; + l_err = deviceWrite(l_mcaList[0], &l_writeData, l_writeSize, + DEVICE_SCOM_ADDRESS(l_writeAddress)); + if(l_err) + { + TRACFCOMP(g_trac_nvdimm, "SCOM to address 0x%08x failed", + l_writeAddress); + errlCommit( l_err, NVDIMM_COMP_ID ); + } + + // Unmask MBACALFIR[8] + l_writeAddress = MBACALFIR_AND_MASK_REG; + l_writeData = MBACALFIR_UNMASK_BIT; + l_err = deviceWrite(l_mcaList[0], &l_writeData, l_writeSize, + DEVICE_SCOM_ADDRESS(l_writeAddress)); + if(l_err) + { + TRACFCOMP(g_trac_nvdimm, "SCOM to address 0x%08x failed", + l_writeAddress); + errlCommit( l_err, NVDIMM_COMP_ID ); + } + + it++; + } + TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmArm() returning %d", o_arm_successful); return o_arm_successful; |