summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorCorey Swenson <cswenson@us.ibm.com>2019-09-25 22:33:26 -0500
committerDaniel M Crowell <dcrowell@us.ibm.com>2020-01-17 13:45:37 -0600
commita96914fab1c366bb8945fbd08c44e90ecbc0454b (patch)
treea7fa1a2825f918d995ce20914763d892a512d120 /src/usr
parent2a806047e9b0ac157da777b619bdd9a79313cea2 (diff)
downloadtalos-hostboot-a96914fab1c366bb8945fbd08c44e90ecbc0454b.tar.gz
talos-hostboot-a96914fab1c366bb8945fbd08c44e90ecbc0454b.zip
Add support for NVDIMM secure erase verify
Add nvdimm operations to interface Add wrapper for factory default function Add secure erase verify start function Add secure erase verify status function Change-Id: I84774e679593e7df1907c1a442c831b2f4df88d9 CQ:SW475562 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/84301 Reviewed-by: Matt Derksen <mderkse1@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Roland Veloz <rveloz@us.ibm.com> Reviewed-by: Daniel M Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/isteps/nvdimm/ReadMe.md54
-rw-r--r--src/usr/isteps/nvdimm/nvdimm.C464
-rw-r--r--src/usr/isteps/nvdimm/nvdimm.H38
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types.xml4
-rw-r--r--src/usr/util/runtime/rt_fwnotify.C53
5 files changed, 509 insertions, 104 deletions
diff --git a/src/usr/isteps/nvdimm/ReadMe.md b/src/usr/isteps/nvdimm/ReadMe.md
index 2b4fd4901..1f98438b2 100644
--- a/src/usr/isteps/nvdimm/ReadMe.md
+++ b/src/usr/isteps/nvdimm/ReadMe.md
@@ -222,3 +222,57 @@ in the JEDEC document JESD245B
12. Disable firmware update mode
13. Switch from slot0 to slot1 which contains the new image code
14. Validate running new code level
+
+# NVDIMM Secure Erase Verify Flow
+DS8K lpar -> HBRT NVDIMM operation = factory_default + secure_erase_verify_start
+ HBRT executes factory_default and steps 1) and 2)
+DS8K lpar -> HBRT NVDIMM operation = secure_erase_verify_complete
+ HBRT executes step 3)
+ If secure erase verify has not completed, return status with verify_complete bit = 0
+ DS8K lpar is responsible for monitoring elapsed time (2/4 hours) and restart process (step 6)
+ If secure erase verify has completed
+ HBRT executes steps 4) and 5), generating error logs for any non-zero register values
+ Return status with verify_complete bit = 1
+
+## Procedure Flow for NVDIMM Secure Erase Verify
+ *Note: Secure Erase Verify should only be run after a Factory Default operation.
+ Secure Erase Verify is intended to verify whether all NAND blocks have been erased.
+ *Note: Full breakout of all Page 5 Secure Erase Verify registers can be found in
+ SMART document "JEDEC NVDIMM Vendor Page 2 Extensions".
+ 1) Set Page 5 Register 0x1B to value "0x00"
+ // this clears the status register
+ 2) Set Page 5 Register 0x1A to value "0xC0"
+ // this kicks off the erase verify operation
+ 3) Wait for Page 5 Register 0x1A Bit 7 to be reset to value "0"
+ // i.e., the overall register value should be "0x40";
+ this means that erase verify has completed
+ a. If Page 5 Register 0x1A Bit 7 has not reset to value "0"
+ after 2 hours (16GB NVDIMM) or after 4 hours (32GB NVDIMM),
+ report a timeout error and skip to step (6)
+ 4) Read Page 5 Register 0x1B; value should be "0x00"
+ // this is the erase verify status register
+ a. If Page 5 Register 0x1B value is not "0x00",
+ report any/all errors as outlined in the table at the end of this document,
+ then skip to step (6)
+ 5) Read Page 5 Registers 0x1D (MSB) and 0x1C (LSB);
+ combined the two registers should have a value of "0x0000"
+ // this is the number of chunks failing Secure Erase Verify
+ a. If the combined value of the two registers is not "0x0000",
+ report a threshold exceeded error along with the combined value of the two registers,
+ then skip to step (6)
+ 6) If any errors have been reported in steps (3), (4), or (5),
+ retry the secure erase verify operation starting again from step (1)
+ a. If the secure erase verify operation fails even after retrying,
+ report that secure erase verify operation has failed
+ 7) If no errors have been reported, report that secure erase verify operation
+ has been completed successfully
+ *Addendum: Breakout of Page 5 Register 0x1B Erase Verify Status bit values referenced in step (4) above.
+ All these bits should return as "0". Any bits returning as "1" should be reported with the error name below.
+ Bits 7:6 - Reserved
+ Bit 5 - BAD BLOCK
+ Bit 4 - OTHER
+ Bit 3 - ENCRYPTION LOCKED
+ Bit 2 - INVALID PARAMETER
+ Bit 1 - INTERRUPTED
+ Bit 0 - NAND ERROR
+
diff --git a/src/usr/isteps/nvdimm/nvdimm.C b/src/usr/isteps/nvdimm/nvdimm.C
index 2f9f96c2b..a7e263cf3 100644
--- a/src/usr/isteps/nvdimm/nvdimm.C
+++ b/src/usr/isteps/nvdimm/nvdimm.C
@@ -119,6 +119,8 @@ static constexpr uint8_t NV_STATUS_UNPROTECTED_SET = 0x01;
static constexpr uint8_t NV_STATUS_UNPROTECTED_CLR = 0xFE;
static constexpr uint8_t NV_STATUS_ENCRYPTION_SET = 0x10;
static constexpr uint8_t NV_STATUS_ENCRYPTION_CLR = 0xEF;
+static constexpr uint8_t NV_STATUS_ERASE_VERIFY_SET = 0x20;
+static constexpr uint8_t NV_STATUS_ERASE_VERIFY_CLR = 0xDF;
static constexpr uint8_t NV_STATUS_POSSIBLY_UNPROTECTED_SET = 0x40;
// NVDIMM key consts
@@ -157,6 +159,11 @@ static constexpr uint8_t RUNNING_FW_SLOT = 0xF0;
static constexpr size_t ARM_MAX_RETRY_COUNT = 1;
static constexpr uint8_t FW_OPS_UPDATE = 0x04;
+// Secure erase verify operations
+static constexpr uint8_t ERASE_VERIFY_CLEAR = 0x00;
+static constexpr uint8_t ERASE_VERIFY_START = 0xC0;
+static constexpr uint8_t ERASE_VERIFY_TRIGGER = 0x80;
+
#ifndef __HOSTBOOT_RUNTIME
// Warning thresholds
static constexpr uint8_t THRESHOLD_ES_LIFETIME = 0x07; // 7%
@@ -1954,95 +1961,6 @@ void nvdimm_restore(TargetHandleList &i_nvdimmList)
}
/**
- * @brief Force a factory reset of the NV logic and flash
- *
- * @param[in] i_nvdimm - NVDIMM Target
- */
-errlHndl_t nvdimm_factory_reset(Target *i_nvdimm)
-{
- TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_factory_reset() nvdimm[%X]",
- get_huid(i_nvdimm));
- errlHndl_t l_err = nullptr;
-
- do
- {
- // Send the reset command
- l_err = nvdimmWriteReg(i_nvdimm, NVDIMM_FUNC_CMD, FACTORY_DEFAULT);
- if( l_err )
- {
- break;
- }
-
- // Poll 2 minutes for completion
- // We could get the timeout value from the dimm but since we're
- // doing a hard reset anyway I just want to use a big number that
- // can handle any lies that the controller might tell us.
- uint8_t l_data = 0;
- constexpr uint64_t MAX_POLL_SECONDS = 120;
- uint64_t poll = 0;
- for( poll = 0; poll < MAX_POLL_SECONDS; poll++ )
- {
- l_err = nvdimmReadReg(i_nvdimm, NVDIMM_CMD_STATUS0, l_data);
- if( l_err )
- {
- break;
- }
-
- if( l_data != FACTORY_RESET_IN_PROGRESS )
- {
- break;
- }
-
-#ifndef __HOSTBOOT_RUNTIME
- // kick the watchdog since this can take awhile
- INITSERVICE::sendProgressCode();
-#endif
-
- // sleep 1 second
- nanosleep(1, 0);
- }
- if( l_err ) { break; }
-
- // Make an error if it never finished
- if( poll >= MAX_POLL_SECONDS )
- {
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_factory_reset() nvdimm[%X] - factory reset never completed[%d]",
- get_huid(i_nvdimm), l_data);
- /*@
- *@errortype
- *@reasoncode NVDIMM_NOT_READY
- *@severity ERRORLOG_SEV_UNRECOVERABLE
- *@moduleid NVDIMM_FACTORY_RESET
- *@userdata1[0:31] Ret value from ready register
- *@userdata1[32:63] Target Huid
- *@userdata2 Number of seconds waited
- *@devdesc NVDIMM factory reset never completed
- *@custdesc NVDIMM still in reset
- */
- l_err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- NVDIMM_FACTORY_RESET,
- NVDIMM_NOT_READY,
- NVDIMM_SET_USER_DATA_1(l_data, get_huid(i_nvdimm)),
- MAX_POLL_SECONDS,
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
-
- l_err->collectTrace(NVDIMM_COMP_NAME);
- nvdimmAddVendorLog(i_nvdimm, l_err);
-
- // If nvdimm is not ready for access by now, this is
- // a failing indication on the NV controller
- l_err->addPartCallout( i_nvdimm,
- HWAS::NV_CONTROLLER_PART_TYPE,
- HWAS::SRCI_PRIORITY_HIGH);
- nvdimmAddPage4Regs(i_nvdimm,l_err);
- }
- } while(0);
-
- return l_err;
-}
-
-/**
* @brief NVDIMM initialization
* - Checks for ready state
* - Gathers timeout values
@@ -2544,6 +2462,96 @@ errlHndl_t nvdimm_getTPM(Target*& o_tpm)
#endif
+/**
+ * @brief Force a factory reset of the NV logic and flash
+ *
+ * @param[in] i_nvdimm - NVDIMM Target
+ */
+errlHndl_t nvdimm_factory_reset(Target *i_nvdimm)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_factory_reset() nvdimm[%X]",
+ get_huid(i_nvdimm));
+ errlHndl_t l_err = nullptr;
+
+ do
+ {
+ // Send the reset command
+ l_err = nvdimmWriteReg(i_nvdimm, NVDIMM_FUNC_CMD, FACTORY_DEFAULT);
+ if( l_err )
+ {
+ break;
+ }
+
+ // Poll 2 minutes for completion
+ // We could get the timeout value from the dimm but since we're
+ // doing a hard reset anyway I just want to use a big number that
+ // can handle any lies that the controller might tell us.
+ uint8_t l_data = 0;
+ constexpr uint64_t MAX_POLL_SECONDS = 120;
+ uint64_t poll = 0;
+ for( poll = 0; poll < MAX_POLL_SECONDS; poll++ )
+ {
+ l_err = nvdimmReadReg(i_nvdimm, NVDIMM_CMD_STATUS0, l_data);
+ if( l_err )
+ {
+ break;
+ }
+
+ if( l_data != FACTORY_RESET_IN_PROGRESS )
+ {
+ break;
+ }
+
+#ifndef __HOSTBOOT_RUNTIME
+ // kick the watchdog since this can take awhile
+ INITSERVICE::sendProgressCode();
+#endif
+
+ // sleep 1 second
+ nanosleep(1, 0);
+ }
+ if( l_err ) { break; }
+
+ // Make an error if it never finished
+ if( poll >= MAX_POLL_SECONDS )
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_factory_reset() nvdimm[%X] - factory reset never completed[%d]",
+ get_huid(i_nvdimm), l_data);
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_NOT_READY
+ *@severity ERRORLOG_SEV_UNRECOVERABLE
+ *@moduleid NVDIMM_FACTORY_RESET
+ *@userdata1[0:31] Ret value from ready register
+ *@userdata1[32:63] Target Huid
+ *@userdata2 Number of seconds waited
+ *@devdesc NVDIMM factory reset never completed
+ *@custdesc NVDIMM still in reset
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ NVDIMM_FACTORY_RESET,
+ NVDIMM_NOT_READY,
+ NVDIMM_SET_USER_DATA_1(l_data, get_huid(i_nvdimm)),
+ MAX_POLL_SECONDS,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ nvdimmAddVendorLog(i_nvdimm, l_err);
+
+ // If nvdimm is not ready for access by now, this is
+ // a failing indication on the NV controller
+ l_err->addPartCallout( i_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ nvdimmAddPage4Regs(i_nvdimm,l_err);
+ }
+ } while(0);
+
+ return l_err;
+}
+
+
bool nvdimm_encrypt_unlock(TargetHandleList &i_nvdimmList)
{
TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_encrypt_unlock()");
@@ -3663,6 +3671,8 @@ errlHndl_t notifyNvdimmProtectionChange(Target* i_target,
bool l_armed_change = false;
bool l_set_encryption = false;
bool l_clr_encryption = false;
+ bool l_sev_started = false;
+ bool l_sev_completed = false;
switch (i_state)
{
@@ -3695,6 +3705,12 @@ errlHndl_t notifyNvdimmProtectionChange(Target* i_target,
case ENCRYPTION_DISABLED:
l_clr_encryption = true;
break;
+ case ERASE_VERIFY_STARTED:
+ l_sev_started = true;
+ break;
+ case ERASE_VERIFY_COMPLETED:
+ l_sev_completed = true;
+ break;
case SEND_NV_STATUS:
// no action, just send status
break;
@@ -3737,6 +3753,18 @@ errlHndl_t notifyNvdimmProtectionChange(Target* i_target,
l_nv_status &= NV_STATUS_ENCRYPTION_CLR;
}
+ // Clear bit 5 if secure erase verify started
+ if (l_sev_started)
+ {
+ l_nv_status &= NV_STATUS_ERASE_VERIFY_CLR;
+ }
+
+ // Set bit 5 if secure erase verify comlpleted
+ if (l_sev_completed)
+ {
+ l_nv_status |= NV_STATUS_ERASE_VERIFY_SET;
+ }
+
// Set bit 6 if risky error
if (l_armed_state.risky_error_detected)
{
@@ -5585,7 +5613,263 @@ bool nvdimmDisarm(TargetHandleList &i_nvdimmTargetList)
TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmDisarm() returning %d",
o_disarm_successful);
- return o_disarm_successful;
+
+ return o_disarm_successful;
+
+}
+
+
+/*
+ * @brief Wrapper function to return NVDIMMs to factory default
+ */
+bool nvdimmFactoryDefault(TargetHandleList &i_nvdimmList)
+{
+ errlHndl_t l_err = nullptr;
+ bool l_success = true;
+
+ // Factory default for all nvdimms in the list
+ for (const auto & l_nvdimm : i_nvdimmList)
+ {
+ l_err = nvdimm_factory_reset(l_nvdimm);
+ if (l_err)
+ {
+ l_success = false;
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue;
+ }
+
+ // Update nvdimm status
+ l_err = notifyNvdimmProtectionChange(l_nvdimm, NVDIMM_DISARMED);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ }
+ }
+
+ return l_success;
+}
+
+
+/*
+ * @brief Function to start secure erase verify of NVDIMMs
+ */
+bool nvdimmSecureEraseVerifyStart(TargetHandleList &i_nvdimmList)
+{
+ errlHndl_t l_err = nullptr;
+ bool l_success = true;
+
+ // Secure erase verify for all nvdimms in the list
+ for (const auto & l_nvdimm : i_nvdimmList)
+ {
+ // Clear the erase_verify_status reg
+ l_err = nvdimmWriteReg(l_nvdimm,
+ ERASE_VERIFY_STATUS,
+ ERASE_VERIFY_CLEAR);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmSecureEraseVerifyStart() HUID 0x%X"
+ "Failed to write ERASE_VERIFY_STATUS register",
+ get_huid(l_nvdimm));
+ l_success = false;
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue;
+ }
+
+ // Start the erase verify operation
+ l_err = nvdimmWriteReg(l_nvdimm,
+ ERASE_VERIFY_CONTROL,
+ ERASE_VERIFY_START);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmSecureEraseVerifyStart() HUID 0x%X"
+ "Failed to write ERASE_VERIFY_CONTROL register",
+ get_huid(l_nvdimm));
+ l_success = false;
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue;
+ }
+
+ // Call notify to clear NV_STATUS bit
+ l_err = notifyNvdimmProtectionChange(l_nvdimm,
+ ERASE_VERIFY_STARTED);
+ if (l_err)
+ {
+ l_success = false;
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ continue;
+ }
+ }
+
+ return l_success;
+}
+
+
+/*
+ * @brief Function to check status of secure erase verify of NVDIMMs
+ */
+bool nvdimmSecureEraseVerifyStatus(TargetHandleList &i_nvdimmList)
+{
+ errlHndl_t l_err = nullptr;
+ bool l_success = true;
+ uint8_t l_data = 0;
+
+ // Check secure erase verify status for all nvdimms in the list
+ for (const auto & l_nvdimm : i_nvdimmList)
+ {
+ // Check if secure-erase-verify is already complete for this nvdimm
+ ATTR_NV_STATUS_FLAG_type l_nv_status =
+ l_nvdimm->getAttr<ATTR_NV_STATUS_FLAG>();
+ if (l_nv_status & NV_STATUS_ERASE_VERIFY_SET)
+ {
+ continue;
+ }
+
+ l_err = nvdimmReadReg(l_nvdimm, ERASE_VERIFY_CONTROL, l_data);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmSecureEraseVerifyStatus() HUID 0x%X"
+ "Failed to read ERASE_VERIFY_CONTROL register",
+ get_huid(l_nvdimm));
+ l_success = false;
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue; // Continue to next nvdimm
+ }
+
+ // If trigger is set the operation is not yet complete
+ if (l_data & ERASE_VERIFY_TRIGGER)
+ {
+ continue; // Continue to next nvdimm
+ }
+
+ // Secure erase verify on this nvdimm is complete
+ // Call notify to set NV_STATUS bit
+ l_err = notifyNvdimmProtectionChange(l_nvdimm,
+ ERASE_VERIFY_COMPLETED);
+ if (l_err)
+ {
+ l_success = false;
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ }
+
+
+ // Check the status register
+ l_err = nvdimmReadReg(l_nvdimm, ERASE_VERIFY_STATUS, l_data);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmSecureEraseVerifyStatus() HUID 0x%X"
+ "Failed to read ERASE_VERIFY_STATUS register",
+ get_huid(l_nvdimm));
+ l_success = false;
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue; // Continue to next nvdimm
+ }
+
+ // Non-zero status is an error
+ if (l_data)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmSecureEraseVerifyStatus() "
+ "HUID 0x%X ERASE_VERIFY_STATUS returned non-zero status",
+ get_huid(l_nvdimm));
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ERASE_VERIFY_STATUS_NONZERO
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_SECURE_ERASE_VERIFY_STATUS
+ *@userdata1 NVDIMM HUID
+ *@userdata2 ERASE_VERIFY_STATUS
+ *@devdesc Error detected during secure erase verify
+ *@custdesc NVDIMM erase error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_SECURE_ERASE_VERIFY_STATUS,
+ NVDIMM_ERASE_VERIFY_STATUS_NONZERO,
+ get_huid(l_nvdimm),
+ l_data,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ l_err->addPartCallout( l_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ nvdimmAddVendorLog(l_nvdimm, l_err);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ l_success = false;
+ continue; // Continue to next nvdimm
+ }
+
+
+ // Check the result registers
+ uint16_t l_result = 0;
+ l_err = nvdimmReadReg(l_nvdimm, ERASE_VERIFY_RESULT_MSB, l_data);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmSecureEraseVerifyStatus() HUID 0x%X"
+ "Failed to read ERASE_VERIFY_RESULT_MSB register",
+ get_huid(l_nvdimm));
+ l_success = false;
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue; // Continue to next nvdimm
+ }
+
+ // Save result
+ l_result = l_data << 8;
+
+ l_err = nvdimmReadReg(l_nvdimm, ERASE_VERIFY_RESULT_LSB, l_data);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK
+ "nvdimmSecureEraseVerifyStatus() HUID 0x%X"
+ "Failed to read ERASE_VERIFY_RESULT_LSB register",
+ get_huid(l_nvdimm));
+ l_success = false;
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ continue; // Continue to next nvdimm
+ }
+
+ // Save result
+ l_result |= l_data;
+
+ // Non-zero result is an error
+ if (l_result)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmSecureEraseVerifyStatus() "
+ "HUID 0x%X ERASE_VERIFY_RESULT returned non-zero data",
+ get_huid(l_nvdimm));
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ERASE_VERIFY_RESULT_NONZERO
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_SECURE_ERASE_VERIFY_STATUS
+ *@userdata1 NVDIMM HUID
+ *@userdata2 ERASE_VERIFY_RESULT
+ *@devdesc Error detected during secure erase verify
+ *@custdesc NVDIMM erase error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_SECURE_ERASE_VERIFY_STATUS,
+ NVDIMM_ERASE_VERIFY_RESULT_NONZERO,
+ get_huid(l_nvdimm),
+ l_result,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ l_err->addPartCallout( l_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ nvdimmAddVendorLog(l_nvdimm, l_err);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ l_success = false;
+ continue; // Continue to next nvdimm
+ }
+
+ }
+
+ return l_success;
}
diff --git a/src/usr/isteps/nvdimm/nvdimm.H b/src/usr/isteps/nvdimm/nvdimm.H
index 1e4e1596c..e66e42470 100644
--- a/src/usr/isteps/nvdimm/nvdimm.H
+++ b/src/usr/isteps/nvdimm/nvdimm.H
@@ -305,18 +305,23 @@ enum i2cReg : uint16_t
BPM_PAYLOAD_LENGTH = 0x442,
BPM_REG_ERR_STATUS = 0x443,
BPM_REG_PAYLOAD_START = 0x444,
- ENCRYPTION_COMMAND = 0x51F,
- ENCRYPTION_CONFIG_STATUS = 0x520,
- ENCRYPTION_ACCESS_KEY_SET = 0x521,
- ENCRYPTION_ACCESS_KEY_VERIFY = 0x522,
- ENCRYPTION_ACCESS_KEY_UNLOCK = 0x523,
- ENCRYPTION_RAMDOM_STRING_SET = 0x524,
- ENCRYPTION_RANDOM_STRING_VERIFY = 0x525,
- ENCRYPTION_ERASE_KEY_SET = 0x526,
- ENCRYPTION_ERASE_KEY_VERIFY = 0x527,
- ENCRYPTION_ERASE_KEY_TEST = 0x528,
+ ERASE_VERIFY_CONTROL = 0x51A,
+ ERASE_VERIFY_STATUS = 0x51B,
+ ERASE_VERIFY_RESULT_LSB = 0x51C,
+ ERASE_VERIFY_RESULT_MSB = 0x51D,
+ ERASE_VERIFY_TEST = 0x51E,
+ ENCRYPTION_COMMAND = 0x51F,
+ ENCRYPTION_CONFIG_STATUS = 0x520,
+ ENCRYPTION_ACCESS_KEY_SET = 0x521,
+ ENCRYPTION_ACCESS_KEY_VERIFY = 0x522,
+ ENCRYPTION_ACCESS_KEY_UNLOCK = 0x523,
+ ENCRYPTION_RAMDOM_STRING_SET = 0x524,
+ ENCRYPTION_RANDOM_STRING_VERIFY = 0x525,
+ ENCRYPTION_ERASE_KEY_SET = 0x526,
+ ENCRYPTION_ERASE_KEY_VERIFY = 0x527,
+ ENCRYPTION_ERASE_KEY_TEST = 0x528,
ENCRYPTION_ERASE_KEY_TEST_VERIFY = 0x529,
- ENCRYPTION_KEY_VALIDATION = 0x52A,
+ ENCRYPTION_KEY_VALIDATION = 0x52A,
};
// i2cReg macros
@@ -715,6 +720,17 @@ void nvdimmSetEncryptionError(TARGETING::Target *i_nvdimm);
errlHndl_t nvdimmResetController(TARGETING::Target *i_nvdimm);
+/**
+ * @brief Helper function to factory reset NVDIMM
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log
+ */
+errlHndl_t nvdimm_factory_reset(TARGETING::Target *i_nvdimm);
+
+
#ifndef __HOSTBOOT_RUNTIME
/**
diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml
index 0fb3ff9aa..e15880f87 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2012,2019 -->
+<!-- Contributors Listed Below - COPYRIGHT 2012,2020 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -5454,7 +5454,7 @@
0x04: Contents preserved
0x08: Contents not preserved
0x10: Contents are encrypted
- 0x20: Reserved
+ 0x20: Secure erase verify complete
0x40: Error detected, but save/restore might work
0x80: Reserved
0xFF: Memory is invalid
diff --git a/src/usr/util/runtime/rt_fwnotify.C b/src/usr/util/runtime/rt_fwnotify.C
index 6ef3e8fc4..148d3bbeb 100644
--- a/src/usr/util/runtime/rt_fwnotify.C
+++ b/src/usr/util/runtime/rt_fwnotify.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2017,2019 */
+/* Contributors Listed Below - COPYRIGHT 2017,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -645,6 +645,57 @@ int doNvDimmOperation(const hostInterfaces::nvdimm_operation_t& i_nvDimmOp)
}
}
+ // Perform the factory default operation
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_FACTORY_DEFAULT)
+ {
+ if (!nvdimmFactoryDefault(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Factory Default operation failed.");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Factory Default operation succeeded.");
+ }
+ }
+
+ // Perform the secure erase verify start operation
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_SECURE_EV_START)
+ {
+ if (!nvdimmSecureEraseVerifyStart(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Secure Erase Verify Start failed.");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Secure Erase Verify Start succeeded.");
+ }
+ }
+
+ // Perform the secure erase verify status operation
+ if (i_nvDimmOp.opType & hostInterfaces::HBRT_FW_NVDIMM_SECURE_EV_STATUS)
+ {
+ if (!nvdimmSecureEraseVerifyStatus(l_nvDimmTargetList))
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Secure Erase Verify Status failed.");
+ rc = -1;
+ break;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_runtime, "doNvDimmOperation: "
+ "Call to do NVDIMM Secure Erase Verify Status succeeded.");
+ }
+ }
+
} while(0); // end Perform the operations requested
if (l_err)
OpenPOWER on IntegriCloud