summaryrefslogtreecommitdiffstats
path: root/src/usr/isteps
diff options
context:
space:
mode:
authorCorey Swenson <cswenson@us.ibm.com>2019-05-02 15:20:15 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2019-06-03 10:26:25 -0500
commit5fd22b47f8d633b118265bae079793e8d90a51c1 (patch)
treee923f832604423f163e11b95cd05c49e7442bbac /src/usr/isteps
parentaf06bf24063e067ec0c6d7596588fc1716b2d4b9 (diff)
downloadtalos-hostboot-5fd22b47f8d633b118265bae079793e8d90a51c1.tar.gz
talos-hostboot-5fd22b47f8d633b118265bae079793e8d90a51c1.zip
NVDIMM encryption HW function support
Update random number generation, IPL and runtime. Write encryption regs to enable nvdimm encryption, crypto-erase, disable encryption. Read config-status reg to verify encryption state. Change-Id: I25625b53f90eeb542767fa729ebb47f8f8455a4b RTC:201474 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/77321 Reviewed-by: Nicholas E. Bofferding <bofferdn@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: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Matthew Raybuck <matthew.raybuck@ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/isteps')
-rw-r--r--src/usr/isteps/istep14/call_mss_power_cleanup.C5
-rw-r--r--src/usr/isteps/nvdimm/nvdimm.C1571
-rw-r--r--src/usr/isteps/nvdimm/nvdimm.H141
-rw-r--r--src/usr/isteps/nvdimm/runtime/nvdimm_rt.C146
4 files changed, 1561 insertions, 302 deletions
diff --git a/src/usr/isteps/istep14/call_mss_power_cleanup.C b/src/usr/isteps/istep14/call_mss_power_cleanup.C
index c86d172be..db6bdf228 100644
--- a/src/usr/isteps/istep14/call_mss_power_cleanup.C
+++ b/src/usr/isteps/istep14/call_mss_power_cleanup.C
@@ -131,9 +131,10 @@ void* call_mss_power_cleanup (void *io_pArgs)
// Run the nvdimm management functions if the list is not empty
if (!l_nvdimmTargetList.empty()){
- // Must generate encryption keys before the restore
- NVDIMM::nvdimm_gen_keys(l_nvdimmTargetList);
+ NVDIMM::nvdimm_gen_keys();
+ NVDIMM::nvdimm_encrypt_unlock(l_nvdimmTargetList);
NVDIMM::nvdimm_restore(l_nvdimmTargetList);
+ NVDIMM::nvdimm_encrypt_enable(l_nvdimmTargetList);
}
}
#endif
diff --git a/src/usr/isteps/nvdimm/nvdimm.C b/src/usr/isteps/nvdimm/nvdimm.C
index b4bded78d..1cae5d9f3 100644
--- a/src/usr/isteps/nvdimm/nvdimm.C
+++ b/src/usr/isteps/nvdimm/nvdimm.C
@@ -85,8 +85,32 @@ constexpr ops_timeoutInfo_t timeoutInfoTable[] =
{"CHARGE", {ES_CHARGE_TIMEOUT1, ES_CHARGE_TIMEOUT0}, CHARGE , MODULE_HEALTH_STATUS1, CHARGE_IN_PROGRESS},
};
-const size_t NUM_KEYS_IN_ATTR = 3;
-const size_t MAX_KEY_SIZE = 32;
+// Definition of ENCRYPTION_CONFIG_STATUS -- page 5 offset 0x20
+typedef union {
+ uint8_t whole;
+ struct
+ {
+ uint8_t reserved : 2; // [7:6
+ uint8_t erase_pending : 1; // [5]
+ uint8_t encryption_unlocked : 1; // [4]
+ uint8_t encryption_enabled : 1; // [3]
+ uint8_t erase_key_present : 1; // [2]
+ uint8_t random_string_present : 1; // [1]
+ uint8_t encryption_supported : 1; // [0]
+ } PACKED;
+} encryption_config_status_t;
+
+// Definition of ENCRYPTION_KEY_VALIDATION -- page 5 offset 0x2A
+typedef union {
+ uint8_t whole;
+ struct
+ {
+ uint8_t reserved : 5; // [7:3]
+ uint8_t keys_validated : 1; // [2]
+ uint8_t access_key_valid : 1; // [1]
+ uint8_t erase_key_valid : 1; // [0]
+ } PACKED;
+} encryption_key_validation_t;
/**
* @brief Wrapper to call deviceOp to read the NV controller via I2C
@@ -108,8 +132,8 @@ errlHndl_t nvdimmReadReg(Target* i_nvdimm,
uint8_t & o_data,
const bool page_verify)
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"NVDIMM Read HUID %X, addr 0x%X",
- TARGETING::get_huid(i_nvdimm), i_addr);
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"NVDIMM Read HUID 0x%X, addr 0x%X",
+ get_huid(i_nvdimm), i_addr);
errlHndl_t l_err = nullptr;
size_t l_numBytes = 1;
@@ -128,7 +152,7 @@ errlHndl_t nvdimmReadReg(Target* i_nvdimm,
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReadReg() nvdimm[%X] - failed to read the current page",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
break;
}
@@ -139,7 +163,7 @@ errlHndl_t nvdimmReadReg(Target* i_nvdimm,
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReadReg() nvdimm[%X] - failed to verify page",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
break;
}
}
@@ -152,8 +176,8 @@ errlHndl_t nvdimmReadReg(Target* i_nvdimm,
DEVICE_NVDIMM_ADDRESS(l_reg_addr));
}while(0);
- TRACUCOMP(g_trac_nvdimm, EXIT_MRK"NVDIMM Read HUID %X, page 0x%X, addr 0x%X = %X",
- TARGETING::get_huid(i_nvdimm), l_reg_page, l_reg_addr, o_data);
+ TRACUCOMP(g_trac_nvdimm, EXIT_MRK"NVDIMM Read HUID 0x%X, page 0x%X, addr 0x%X = 0x%X",
+ get_huid(i_nvdimm), l_reg_page, l_reg_addr, o_data);
return l_err;
}
@@ -178,8 +202,8 @@ errlHndl_t nvdimmWriteReg(Target* i_nvdimm,
uint8_t i_data,
const bool page_verify)
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"NVDIMM Write HUID %X, addr 0x%X = %X",
- TARGETING::get_huid(i_nvdimm), i_addr, i_data);
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"NVDIMM Write HUID 0x%X, addr 0x%X = 0x%X",
+ get_huid(i_nvdimm), i_addr, i_data);
errlHndl_t l_err = nullptr;
size_t l_numBytes = 1;
@@ -198,7 +222,7 @@ errlHndl_t nvdimmWriteReg(Target* i_nvdimm,
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmWriteReg() nvdimm[%X] - failed to read the current page",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
break;
}
@@ -209,7 +233,7 @@ errlHndl_t nvdimmWriteReg(Target* i_nvdimm,
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmWriteReg() nvdimm[%X] - failed to verify page",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
break;
}
}
@@ -222,8 +246,8 @@ errlHndl_t nvdimmWriteReg(Target* i_nvdimm,
DEVICE_NVDIMM_ADDRESS(l_reg_addr));
}while(0);
- TRACUCOMP(g_trac_nvdimm, EXIT_MRK"NVDIMM Write HUID %X, page = 0x%X, addr 0x%X = %X",
- TARGETING::get_huid(i_nvdimm), l_reg_page, l_reg_addr, i_data);
+ TRACUCOMP(g_trac_nvdimm, EXIT_MRK"NVDIMM Write HUID 0x%X, page = 0x%X, addr 0x%X = 0x%X",
+ get_huid(i_nvdimm), l_reg_page, l_reg_addr, i_data);
return l_err;
}
@@ -239,9 +263,9 @@ errlHndl_t nvdimmWriteReg(Target* i_nvdimm,
void nvdimmSetStatusFlag(Target *i_nvdimm, const uint8_t i_status_flag)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmSetStatusFlag() HUID[%X], i_status_flag[%X]"
- ,TARGETING::get_huid(i_nvdimm), i_status_flag);
+ ,get_huid(i_nvdimm), i_status_flag);
- auto l_statusFlag = i_nvdimm->getAttr<TARGETING::ATTR_NV_STATUS_FLAG>();
+ auto l_statusFlag = i_nvdimm->getAttr<ATTR_NV_STATUS_FLAG>();
switch(i_status_flag)
{
@@ -268,14 +292,14 @@ void nvdimmSetStatusFlag(Target *i_nvdimm, const uint8_t i_status_flag)
default:
assert(0, "nvdimmSetStatusFlag() HUID[%X], i_status_flag[%X] invalid flag!",
- TARGETING::get_huid(i_nvdimm), i_status_flag);
+ get_huid(i_nvdimm), i_status_flag);
break;
}
- i_nvdimm->setAttr<TARGETING::ATTR_NV_STATUS_FLAG>(l_statusFlag);
+ i_nvdimm->setAttr<ATTR_NV_STATUS_FLAG>(l_statusFlag);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmSetStatusFlag() HUID[%X], i_status_flag[%X]"
- ,TARGETING::get_huid(i_nvdimm), i_status_flag);
+ ,get_huid(i_nvdimm), i_status_flag);
}
@@ -289,7 +313,7 @@ void nvdimmSetStatusFlag(Target *i_nvdimm, const uint8_t i_status_flag)
*/
errlHndl_t nvdimmReady(Target *i_nvdimm)
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmReady() HUID[%X]",TARGETING::get_huid(i_nvdimm));
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmReady() HUID[%X]",get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
uint8_t l_data = 0x0;
@@ -305,12 +329,12 @@ errlHndl_t nvdimmReady(Target *i_nvdimm)
DEVICE_SPD_ADDRESS(SPD::NVM_INIT_TIME));
TRACUCOMP(g_trac_nvdimm, "nvdimmReady() HUID[%X] l_nvm_init_time = %u",
- TARGETING::get_huid(i_nvdimm), l_nvm_init_time);
+ get_huid(i_nvdimm), l_nvm_init_time);
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReady() nvdimm[%X] - failed to retrieve NVM_INIT_TIME from SPD",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
break;
}
@@ -325,7 +349,7 @@ errlHndl_t nvdimmReady(Target *i_nvdimm)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReady() nvdimm[%X] - error getting ready status[%d]",
- TARGETING::get_huid(i_nvdimm), l_data);
+ get_huid(i_nvdimm), l_data);
break;
}
@@ -342,7 +366,7 @@ errlHndl_t nvdimmReady(Target *i_nvdimm)
if ((l_data != NV_READY) && !l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmReady() nvdimm[%X] - nvdimm not ready[%d]",
- TARGETING::get_huid(i_nvdimm), l_data);
+ get_huid(i_nvdimm), l_data);
/*@
*@errortype
*@reasoncode NVDIMM_NOT_READY
@@ -355,14 +379,15 @@ errlHndl_t nvdimmReady(Target *i_nvdimm)
* for host access. (userdata1 != 0xA5)
*@custdesc NVDIMM not ready
*/
- l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- NVDIMM_CHECK_READY,
- NVDIMM_NOT_READY,
- NVDIMM_SET_USER_DATA_1(l_data, TARGETING::get_huid(i_nvdimm)),
- 0x0,
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ NVDIMM_CHECK_READY,
+ NVDIMM_NOT_READY,
+ NVDIMM_SET_USER_DATA_1(l_data, get_huid(i_nvdimm)),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024 );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
// If nvdimm is not ready for access by now, this is
// a failing indication on the NV controller
@@ -374,7 +399,7 @@ errlHndl_t nvdimmReady(Target *i_nvdimm)
}while(0);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmReady() HUID[%X] ready[%X]",
- TARGETING::get_huid(i_nvdimm), l_data);
+ get_huid(i_nvdimm), l_data);
return l_err;
}
@@ -391,7 +416,7 @@ errlHndl_t nvdimmReady(Target *i_nvdimm)
*/
errlHndl_t nvdimmResetController(Target *i_nvdimm)
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmResetController() HUID[%X]",TARGETING::get_huid(i_nvdimm));
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmResetController() HUID[%X]",get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
do
@@ -401,7 +426,7 @@ errlHndl_t nvdimmResetController(Target *i_nvdimm)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmResetController() nvdimm[%X] - error reseting the controller",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
break;
}
@@ -409,12 +434,12 @@ errlHndl_t nvdimmResetController(Target *i_nvdimm)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmResetController() nvdimm[%X] - not ready after reset.",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
}
}while(0);
- TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmResetController() HUID[%X]",TARGETING::get_huid(i_nvdimm));
+ TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmResetController() HUID[%X]",get_huid(i_nvdimm));
return l_err;
}
@@ -441,8 +466,8 @@ errlHndl_t nvdimmPollStatus ( Target *i_nvdimm,
bool l_done = false;
// Get the timeout value for ops_id
- assert(i_nvdimm->tryGetAttr<TARGETING::ATTR_NV_OPS_TIMEOUT_MSEC>(l_target_timeout_values),
- "nvdimmPollStatus() HUID[%X], failed reading ATTR_NV_OPS_TIMEOUT_MSEC!", TARGETING::get_huid(i_nvdimm));
+ assert(i_nvdimm->tryGetAttr<ATTR_NV_OPS_TIMEOUT_MSEC>(l_target_timeout_values),
+ "nvdimmPollStatus() HUID[%X], failed reading ATTR_NV_OPS_TIMEOUT_MSEC!", get_huid(i_nvdimm));
uint32_t l_timeout = l_target_timeout_values[i_ops_id];
do
@@ -472,7 +497,7 @@ errlHndl_t nvdimmPollStatus ( Target *i_nvdimm,
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmPollStatus() nvdimm[%X] - Status timed out ops_id[%d]",
- TARGETING::get_huid(i_nvdimm), i_ops_id);
+ get_huid(i_nvdimm), i_ops_id);
/*@
*@errortype
*@reasoncode NVDIMM_STATUS_TIMEOUT
@@ -486,14 +511,15 @@ errlHndl_t nvdimmPollStatus ( Target *i_nvdimm,
* Refer to userdata1 for which operation it timed out.
*@custdesc NVDIMM timed out
*/
- l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
- NVDIMM_POLL_STATUS,
- NVDIMM_STATUS_TIMEOUT,
- NVDIMM_SET_USER_DATA_1(i_ops_id, TARGETING::get_huid(i_nvdimm)),
- NVDIMM_SET_USER_DATA_2_TIMEOUT(o_poll, l_timeout),
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_POLL_STATUS,
+ NVDIMM_STATUS_TIMEOUT,
+ NVDIMM_SET_USER_DATA_1(i_ops_id, get_huid(i_nvdimm)),
+ NVDIMM_SET_USER_DATA_2_TIMEOUT(o_poll, l_timeout),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024 );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
// May have to move the error handling to the caller
// as different op could have different error severity
@@ -521,14 +547,14 @@ errlHndl_t nvdimmPollBackupDone(Target* i_nvdimm,
uint32_t &o_poll)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmPollBackupDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
l_err = nvdimmPollStatus ( i_nvdimm, SAVE, o_poll);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmPollBackupDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
return l_err;
}
@@ -548,14 +574,14 @@ errlHndl_t nvdimmPollRestoreDone(Target* i_nvdimm,
uint32_t &o_poll)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmPollRestoreDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
l_err = nvdimmPollStatus ( i_nvdimm, RESTORE, o_poll );
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmPollRestoreDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
return l_err;
}
@@ -575,14 +601,14 @@ errlHndl_t nvdimmPollEraseDone(Target* i_nvdimm,
uint32_t &o_poll)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmPollEraseDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
l_err = nvdimmPollStatus ( i_nvdimm, ERASE, o_poll);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmPollEraseDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
return l_err;
}
@@ -603,14 +629,14 @@ errlHndl_t nvdimmPollESChargeStatus(Target* i_nvdimm,
uint32_t &o_poll)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmPollESChargeDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
l_err = nvdimmPollStatus ( i_nvdimm, CHARGE, o_poll );
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmPollESChargeDone() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
return l_err;
}
@@ -628,7 +654,7 @@ errlHndl_t nvdimmPollESChargeStatus(Target* i_nvdimm,
errlHndl_t nvdimmGetRestoreValid(Target* i_nvdimm, uint8_t & o_rstrValid)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmGetRestoreValid() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
@@ -636,11 +662,11 @@ errlHndl_t nvdimmGetRestoreValid(Target* i_nvdimm, uint8_t & o_rstrValid)
if (l_err){
TRACFCOMP(g_trac_nvdimm, ERR_MRK"NDVIMM HUID[%X], Error getting restore status!",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
}
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmGetRestoreValid() nvdimm[%X], restore_status[%x],",
- TARGETING::get_huid(i_nvdimm), o_rstrValid);
+ get_huid(i_nvdimm), o_rstrValid);
return l_err;
}
@@ -656,7 +682,7 @@ errlHndl_t nvdimmGetRestoreValid(Target* i_nvdimm, uint8_t & o_rstrValid)
errlHndl_t nvdimmSetESPolicy(Target* i_nvdimm)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmSetESPolicy() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
uint8_t l_data;
@@ -670,7 +696,7 @@ errlHndl_t nvdimmSetESPolicy(Target* i_nvdimm)
{
nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_NOBKUP);
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmSetESPolicy() nvdimm[%X]"
- "failed to write ES register!",TARGETING::get_huid(i_nvdimm));
+ "failed to write ES register!",get_huid(i_nvdimm));
break;
}
@@ -684,14 +710,14 @@ errlHndl_t nvdimmSetESPolicy(Target* i_nvdimm)
{
nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_NOBKUP);
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmSetESPolicy() nvdimm[%X]"
- "failed to read ES register!",TARGETING::get_huid(i_nvdimm));
+ "failed to read ES register!",get_huid(i_nvdimm));
break;
}
if ((l_data & ES_SUCCESS) != ES_SUCCESS)
{
TRACFCOMP(g_trac_nvdimm, EXIT_MRK"NDVIMM HUID[%X], nvdimmSetESPolicy() "
- "failed!",TARGETING::get_huid(i_nvdimm));
+ "failed!",get_huid(i_nvdimm));
/*@
*@errortype
*@reasoncode NVDIMM_SET_ES_ERROR
@@ -705,14 +731,15 @@ errlHndl_t nvdimmSetESPolicy(Target* i_nvdimm)
* NVDIMM is intact
*@custdesc NVDIMM encountered error setting the energy source policy
*/
- l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
- NVDIMM_SET_ES,
- NVDIMM_SET_ES_ERROR,
- NVDIMM_SET_USER_DATA_1(CHARGE, TARGETING::get_huid(i_nvdimm)),
- 0x0,
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_SET_ES,
+ NVDIMM_SET_ES_ERROR,
+ NVDIMM_SET_USER_DATA_1(CHARGE, get_huid(i_nvdimm)),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024 );
+ l_err->collectTrace(NVDIMM_COMP_NAME);
// Failure setting the energy source policy could mean error on the
// battery or even the cabling
@@ -726,7 +753,7 @@ errlHndl_t nvdimmSetESPolicy(Target* i_nvdimm)
}while(0);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"NDVIMM HUID[%X], nvdimmSetESPolicy(),"
- ,TARGETING::get_huid(i_nvdimm));
+ ,get_huid(i_nvdimm));
return l_err;
}
@@ -744,7 +771,7 @@ errlHndl_t nvdimmSetESPolicy(Target* i_nvdimm)
errlHndl_t nvdimmChangeArmState(Target *i_nvdimm, bool i_state)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmChangeArmState() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
@@ -758,11 +785,11 @@ errlHndl_t nvdimmChangeArmState(Target *i_nvdimm, bool i_state)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmChangeArmState() nvdimm[%X] error %s nvdimm!!",
- TARGETING::get_huid(i_nvdimm), i_state? "arming" : "disarming");
+ get_huid(i_nvdimm), i_state? "arming" : "disarming");
}
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmChangeArmState() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
return l_err;
}
@@ -779,7 +806,7 @@ errlHndl_t nvdimmChangeArmState(Target *i_nvdimm, bool i_state)
errlHndl_t nvdimmValidImage(Target *i_nvdimm, bool &o_imgValid)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmValidImage(): nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
uint8_t l_data = 0x0;
@@ -790,7 +817,7 @@ errlHndl_t nvdimmValidImage(Target *i_nvdimm, bool &o_imgValid)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmValidImage() nvdimm[%X]"
- "failed to for image!",TARGETING::get_huid(i_nvdimm) );
+ "failed to for image!",get_huid(i_nvdimm) );
}
else if(l_data & VALID_IMAGE)
{
@@ -798,7 +825,7 @@ errlHndl_t nvdimmValidImage(Target *i_nvdimm, bool &o_imgValid)
}
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmValidImage(): nvdimm[%X] ret[%X]",
- TARGETING::get_huid(i_nvdimm), l_data);
+ get_huid(i_nvdimm), l_data);
return l_err;
}
@@ -845,8 +872,8 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
continue;
}
- TARGETING::TargetHandleList l_mcaList;
- getParentAffinityTargets(l_mcaList, *it, TARGETING::CLASS_UNIT, TARGETING::TYPE_MCA);
+ TargetHandleList l_mcaList;
+ getParentAffinityTargets(l_mcaList, *it, CLASS_UNIT, TYPE_MCA);
assert(l_mcaList.size(), "nvdimmRestore() failed to find parent MCA.");
fapi2::Target<fapi2::TARGET_TYPE_MCA> l_fapi_mca(l_mcaList[0]);
@@ -860,7 +887,7 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmRestore() HUID[%X] i_mpipl[%u] failed to de-assert resetn!",
- TARGETING::get_huid(*it), i_mpipl);
+ get_huid(*it), i_mpipl);
nvdimmSetStatusFlag(*it, NSTD_ERR_NOPRSV);
//@TODO RTC 199645 - add HW callout on dimm target
@@ -878,7 +905,7 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmRestore() HUID[%X] self_refresh_entry failed!",
- TARGETING::get_huid(*it));
+ get_huid(*it));
nvdimmSetStatusFlag(*it, NSTD_ERR_NOPRSV);
//@TODO RTC 199645 - add HW callout on dimm target
@@ -909,7 +936,7 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
{
nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOPRSV);
TRACFCOMP(g_trac_nvdimm, ERR_MRK"NDVIMM HUID[%X], error initiating restore!!",
- TARGETING::get_huid(l_nvdimm));
+ get_huid(l_nvdimm));
break;
}
}
@@ -930,7 +957,7 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
{
nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOPRSV);
TRACFCOMP(g_trac_nvdimm, ERR_MRK"NDVIMM HUID[%X], error restoring!",
- TARGETING::get_huid(l_nvdimm));
+ get_huid(l_nvdimm));
errlCommit(l_err, NVDIMM_COMP_ID);
break;
}
@@ -949,14 +976,14 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
{
nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOPRSV);
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmRestore Target[%X] error validating restore status!",
- TARGETING::get_huid(l_nvdimm));
+ get_huid(l_nvdimm));
break;
}
if ((l_rstrValid & RSTR_SUCCESS) != RSTR_SUCCESS){
TRACFCOMP(g_trac_nvdimm, ERR_MRK"NDVIMM HUID[%X] restoreValid[%d], restore failed!",
- TARGETING::get_huid(l_nvdimm), l_rstrValid);
+ get_huid(l_nvdimm), l_rstrValid);
/*@
*@errortype
*@reasoncode NVDIMM_RESTORE_FAILED
@@ -969,14 +996,15 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
* restore timeout (Controller error)
*@custdesc NVDIMM failed to restore data
*/
- l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- NVDIMM_RESTORE,
- NVDIMM_RESTORE_FAILED,
- TARGETING::get_huid(l_nvdimm),
- 0x0,
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT);
-
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024 );
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ NVDIMM_RESTORE,
+ NVDIMM_RESTORE_FAILED,
+ get_huid(l_nvdimm),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT);
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOPRSV);
// Invalid restore could be due to dram not in self-refresh
@@ -997,8 +1025,8 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
for (const auto & l_nvdimm : i_nvdimmList)
{
- TARGETING::TargetHandleList l_mcaList;
- getParentAffinityTargets(l_mcaList, l_nvdimm, TARGETING::CLASS_UNIT, TARGETING::TYPE_MCA);
+ TargetHandleList l_mcaList;
+ getParentAffinityTargets(l_mcaList, l_nvdimm, CLASS_UNIT, TYPE_MCA);
assert(l_mcaList.size(), "nvdimmRestore() failed to find parent MCA.");
fapi2::Target<fapi2::TARGET_TYPE_MCA> l_fapi_mca(l_mcaList[0]);
@@ -1010,7 +1038,7 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmRestore() HUID[%X] post_restore_transition failed!",
- TARGETING::get_huid(l_nvdimm));
+ get_huid(l_nvdimm));
// Commit the error from the HWP
nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOPRSV);
@@ -1043,7 +1071,7 @@ errlHndl_t nvdimmRestore(TargetHandleList i_nvdimmList, uint8_t &i_mpipl)
errlHndl_t nvdimmCheckEraseSuccess(Target *i_nvdimm)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmCheckEraseSuccess() : nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
uint8_t l_data = 0;
errlHndl_t l_err = nullptr;
@@ -1053,13 +1081,13 @@ errlHndl_t nvdimmCheckEraseSuccess(Target *i_nvdimm)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmCheckEraseSuccess() nvdimm[%X]"
- "failed to read erase status reg!",TARGETING::get_huid(i_nvdimm));
+ "failed to read erase status reg!",get_huid(i_nvdimm));
}
else if ((l_data & ERASE_SUCCESS) != ERASE_SUCCESS)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmCheckEraseSuccess() nvdimm[%X]"
- "failed to erase!",TARGETING::get_huid(i_nvdimm));
+ "failed to erase!",get_huid(i_nvdimm));
/*@
*@errortype
*@reasoncode NVDIMM_ERASE_FAILED
@@ -1072,14 +1100,15 @@ errlHndl_t nvdimmCheckEraseSuccess(Target *i_nvdimm)
* on NVDIMM. Likely due to timeout and/or controller error
*@custdesc NVDIMM error erasing data image
*/
- l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE,
- NVDIMM_CHECK_ERASE,
- NVDIMM_ERASE_FAILED,
- NVDIMM_SET_USER_DATA_1(ERASE, TARGETING::get_huid(i_nvdimm)),
- 0x0,
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
-
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024 );
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_CHECK_ERASE,
+ NVDIMM_ERASE_FAILED,
+ NVDIMM_SET_USER_DATA_1(ERASE, get_huid(i_nvdimm)),
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
errlCommit( l_err, NVDIMM_COMP_ID );
// Failure to erase could mean internal NV controller error and/or
@@ -1091,7 +1120,7 @@ errlHndl_t nvdimmCheckEraseSuccess(Target *i_nvdimm)
}
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmCheckEraseSuccess(): nvdimm[%X] ret[%X]",
- TARGETING::get_huid(i_nvdimm), l_data);
+ get_huid(i_nvdimm), l_data);
return l_err;
}
@@ -1107,7 +1136,7 @@ errlHndl_t nvdimmCheckEraseSuccess(Target *i_nvdimm)
errlHndl_t nvdimmEraseNF(Target *i_nvdimm)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmEraseNF() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
@@ -1117,7 +1146,7 @@ errlHndl_t nvdimmEraseNF(Target *i_nvdimm)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"NDVIMM HUID[%X] error initiating erase!!",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
break;
}
@@ -1132,7 +1161,7 @@ errlHndl_t nvdimmEraseNF(Target *i_nvdimm)
}while(0);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmEraseNF() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ get_huid(i_nvdimm));
return l_err;
}
@@ -1151,15 +1180,15 @@ errlHndl_t nvdimmEraseNF(Target *i_nvdimm)
errlHndl_t nvdimmOpenPage(Target *i_nvdimm,
uint8_t i_page)
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmOpenPage nvdimm[%X]", TARGETING::get_huid(i_nvdimm));
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmOpenPage nvdimm[%X]", get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
bool l_success = false;
uint8_t l_data;
uint32_t l_poll = 0;
uint32_t l_target_timeout_values[6];
- assert(i_nvdimm->tryGetAttr<TARGETING::ATTR_NV_OPS_TIMEOUT_MSEC>(l_target_timeout_values),
- "nvdimmOpenPage() HUID[%X], failed reading ATTR_NV_OPS_TIMEOUT_MSEC!", TARGETING::get_huid(i_nvdimm));
+ assert(i_nvdimm->tryGetAttr<ATTR_NV_OPS_TIMEOUT_MSEC>(l_target_timeout_values),
+ "nvdimmOpenPage() HUID[%X], failed reading ATTR_NV_OPS_TIMEOUT_MSEC!", get_huid(i_nvdimm));
uint32_t l_timeout = l_target_timeout_values[PAGE_SWITCH];
@@ -1172,7 +1201,7 @@ errlHndl_t nvdimmOpenPage(Target *i_nvdimm,
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmOpenPage nvdimm[%X]"
- "error writing to page change reg", TARGETING::get_huid(i_nvdimm));
+ "error writing to page change reg", get_huid(i_nvdimm));
break;
}
@@ -1205,7 +1234,7 @@ errlHndl_t nvdimmOpenPage(Target *i_nvdimm,
if (!l_success && !l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmOpenPage nvdimm[%X] openpage_success[%d],"
- "failure to open page!", TARGETING::get_huid(i_nvdimm), static_cast<uint8_t>(l_success));
+ "failure to open page!", get_huid(i_nvdimm), static_cast<uint8_t>(l_success));
/*@
*@errortype
@@ -1220,12 +1249,13 @@ errlHndl_t nvdimmOpenPage(Target *i_nvdimm,
*@custdesc Encountered error performing internal operaiton
* on NVDIMM
*/
- l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- NVDIMM_POLL_STATUS,
- NVDIMM_STATUS_TIMEOUT,
- NVDIMM_SET_USER_DATA_1(PAGE_SWITCH, TARGETING::get_huid(i_nvdimm)),
- NVDIMM_SET_USER_DATA_2_TIMEOUT(l_poll, l_timeout),
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ NVDIMM_OPEN_PAGE,
+ NVDIMM_OPEN_PAGE_TIMEOUT,
+ NVDIMM_SET_USER_DATA_1(PAGE_SWITCH, get_huid(i_nvdimm)),
+ NVDIMM_SET_USER_DATA_2_TIMEOUT(l_poll, l_timeout),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
l_err->collectTrace(NVDIMM_COMP_NAME, 256 );
@@ -1238,7 +1268,7 @@ errlHndl_t nvdimmOpenPage(Target *i_nvdimm,
}while(0);
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmOpenPage nvdimm[%X] nvdimmOpenPage.success[%d],"
- ,TARGETING::get_huid(i_nvdimm), static_cast<uint8_t>(l_success));
+ ,get_huid(i_nvdimm), static_cast<uint8_t>(l_success));
return l_err;
}
@@ -1255,12 +1285,12 @@ errlHndl_t nvdimmOpenPage(Target *i_nvdimm,
errlHndl_t nvdimmGetTimeoutVal(Target* i_nvdimm)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmGetTimeoutVal() HUID[%X]"
- ,TARGETING::get_huid(i_nvdimm));
+ ,get_huid(i_nvdimm));
errlHndl_t l_err = nullptr;
uint8_t l_data = 0;
uint32_t timeout_map[6];
- i_nvdimm->tryGetAttr<TARGETING::ATTR_NV_OPS_TIMEOUT_MSEC>(timeout_map);
+ i_nvdimm->tryGetAttr<ATTR_NV_OPS_TIMEOUT_MSEC>(timeout_map);
//Get the 6 main timeout values
for (uint8_t i = SAVE; i <= CHARGE; i++)
@@ -1287,7 +1317,7 @@ errlHndl_t nvdimmGetTimeoutVal(Target* i_nvdimm)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmGetTimeoutVal() HUID[%X] "
- "error reading timeout value for op[%d]!", TARGETING::get_huid(i_nvdimm), i);
+ "error reading timeout value for op[%d]!", get_huid(i_nvdimm), i);
break;
}
@@ -1299,16 +1329,16 @@ errlHndl_t nvdimmGetTimeoutVal(Target* i_nvdimm)
}
TRACUCOMP(g_trac_nvdimm, "nvdimmGetTimeoutVal() HUID[%X], timeout_idx[%d], timeout_ms[%d]"
- ,TARGETING::get_huid(i_nvdimm), timeoutInfoTable[i].idx, timeout_map[i]);
+ ,get_huid(i_nvdimm), timeoutInfoTable[i].idx, timeout_map[i]);
}
if (!l_err)
{
- i_nvdimm->setAttr<TARGETING::ATTR_NV_OPS_TIMEOUT_MSEC>(timeout_map);
+ i_nvdimm->setAttr<ATTR_NV_OPS_TIMEOUT_MSEC>(timeout_map);
}
TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmGetTimeoutVal() HUID[%X]"
- ,TARGETING::get_huid(i_nvdimm));
+ ,get_huid(i_nvdimm));
return l_err;
}
@@ -1332,8 +1362,8 @@ errlHndl_t nvdimmEpowSetup(TargetHandleList &i_nvdimmList)
for (TargetHandleList::iterator it = i_nvdimmList.begin();
it != i_nvdimmList.end();)
{
- TARGETING::TargetHandleList l_mcaList;
- getParentAffinityTargets(l_mcaList, *it, TARGETING::CLASS_UNIT, TARGETING::TYPE_MCA);
+ TargetHandleList l_mcaList;
+ getParentAffinityTargets(l_mcaList, *it, CLASS_UNIT, TYPE_MCA);
assert(l_mcaList.size(), "nvdimmEpowSetup() failed to find parent MCA.");
fapi2::Target<fapi2::TARGET_TYPE_MCA> l_fapi_mca(l_mcaList[0]);
@@ -1345,7 +1375,7 @@ errlHndl_t nvdimmEpowSetup(TargetHandleList &i_nvdimmList)
if (l_err)
{
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmEpowSetup() HUID[%X] failed to setup epow!",
- TARGETING::get_huid(*it));
+ get_huid(*it));
nvdimmSetStatusFlag(*it, NSTD_ERR_NOPRSV);
break;
@@ -1359,6 +1389,8 @@ errlHndl_t nvdimmEpowSetup(TargetHandleList &i_nvdimmList)
return l_err;
}
+
+
/**
* @brief Entry function to NVDIMM restore
* - Restore image from NVDIMM NAND flash to DRAM
@@ -1371,8 +1403,8 @@ void nvdimm_restore(TargetHandleList &i_nvdimmList)
{
TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_restore()");
errlHndl_t l_err = nullptr;
- TARGETING::Target* l_sys = nullptr;
- TARGETING::targetService().getTopLevelTarget( l_sys );
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
assert(l_sys, "nvdimm_restore: no TopLevelTarget");
uint8_t l_mpipl = l_sys->getAttr<ATTR_IS_MPIPL_HB>();
@@ -1408,7 +1440,7 @@ void nvdimm_restore(TargetHandleList &i_nvdimmList)
{
nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOPRSV);
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_restore() nvdimm[%X], error backing up the DRAM!",
- TARGETING::get_huid(l_nvdimm));
+ get_huid(l_nvdimm));
errlCommit(l_err, NVDIMM_COMP_ID);
break;
}
@@ -1456,13 +1488,565 @@ void nvdimm_restore(TargetHandleList &i_nvdimmList)
}
/**
- * @brief Entry function to NVDIMM generate keys
- * Generate encryption keys if required and set the FW key attribute
+ * @brief NVDIMM initialization
+ * - Checks for ready state
+ * - Gathers timeout values
+ * - Waits for the ongoing backup to complete
+ * - Disarms the trigger for draminit
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
*/
-void nvdimm_gen_keys(TargetHandleList &i_nvdimmList)
+void nvdimm_init(Target *i_nvdimm)
+{
+ TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_init() nvdimm[%X]",
+ get_huid(i_nvdimm));
+
+ errlHndl_t l_err = nullptr;
+
+ do
+ {
+ l_err = nvdimmReady(i_nvdimm);
+
+ if (l_err)
+ {
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_int() nvdimm[%X], controller not ready",
+ get_huid(i_nvdimm));
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ break;
+ }
+
+ // Get the timeout values for the major ops at init
+ l_err = nvdimmGetTimeoutVal(i_nvdimm);
+ if (l_err)
+ {
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_int() nvdimm[%X], error retrieving timeout values",
+ get_huid(i_nvdimm));
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ break;
+ }
+
+ //Check save progress
+ uint32_t l_poll = 0;
+ l_err = nvdimmPollBackupDone(i_nvdimm, l_poll);
+
+ if (l_err)
+ {
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_NOPRSV);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_int() nvdimm[%X], error backing up the DRAM!",
+ get_huid(i_nvdimm));
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ break;
+ }
+
+ // Disarm the ddr_resetn here in case it came in armed. When the nvdimm is
+ // armed the reset_n is masked off from the host, meaning the drams won't
+ // be able to get reset properly later, causing training to fail.
+ l_err = nvdimmChangeArmState(i_nvdimm, DISARM_TRIGGER);
+
+ if (l_err)
+ {
+ nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_NOPRSV);
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_init() nvdimm[%X], error disarming the nvdimm!",
+ get_huid(i_nvdimm));
+ errlCommit(l_err, NVDIMM_COMP_ID);
+ break;
+ }
+
+ }while(0);
+
+ TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_init() nvdimm[%X]",
+ get_huid(i_nvdimm));
+}
+
+
+errlHndl_t nvdimm_getRandom(uint8_t* o_genData)
+{
+ errlHndl_t l_err = nullptr;
+ uint8_t l_xtraData[ENC_KEY_SIZE] = {0};
+
+ do
+ {
+ // Get a pointer to the TPM
+ Target* l_tpm = nullptr;
+ l_err = nvdimm_getTPM(l_tpm);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Get a random number from the TPM
+ l_err = TRUSTEDBOOT::GetRandom(l_tpm, ENC_KEY_SIZE, o_genData);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Validate and update the random number
+ // Retry if more randomness required
+ do
+ {
+ //Get replacement data
+ l_err = TRUSTEDBOOT::GetRandom(l_tpm, ENC_KEY_SIZE, l_xtraData);
+ if (l_err)
+ {
+ break;
+ }
+
+ }while (nvdimm_keyifyRandomNumber(o_genData, l_xtraData));
+
+ } while(0);
+
+ return l_err;
+}
+
+
+errlHndl_t nvdimm_getTPM(Target*& o_tpm)
+{
+ errlHndl_t l_err = nullptr;
+
+ do
+ {
+ // Get all functional TPMs
+ TargetHandleList l_tpmList;
+ TRUSTEDBOOT::getTPMs(l_tpmList,
+ TRUSTEDBOOT::TPM_FILTER::ALL_FUNCTIONAL);
+
+ if (l_tpmList.size())
+ {
+ o_tpm = l_tpmList[0];
+ break;
+ }
+
+ // No TPMs, generate error
+ TRACFCOMP(g_trac_nvdimm,ERR_MRK"nvdimm_getTPM() No functional TPMs found");
+
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_TPM_NOT_FOUND
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_GET_TPM
+ *@devdesc Functional TPM required to generate encryption keys
+ *@custdesc NVDIMM error generating encryption keys
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_GET_TPM,
+ NVDIMM_TPM_NOT_FOUND,
+ 0x0,
+ 0x0,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+
+ // Get all TPMs
+ TRUSTEDBOOT::getTPMs(l_tpmList,
+ TRUSTEDBOOT::TPM_FILTER::ALL_IN_BLUEPRINT);
+ if (l_tpmList.size() == 0)
+ {
+ // No TPMs, we probably have nvdimms enabled
+ // when they should not be
+ l_err->addProcedureCallout(
+ HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ }
+ else
+ {
+ // If a TPM exists it must be deconfigured
+ l_err->addProcedureCallout(
+ HWAS::EPUB_PRC_FIND_DECONFIGURED_PART,
+ HWAS::SRCI_PRIORITY_HIGH);
+ l_err->addProcedureCallout(
+ HWAS::EPUB_PRC_HB_CODE,
+ HWAS::SRCI_PRIORITY_MED);
+ }
+
+ }while(0);
+
+ // Functional TPM not found
+ return l_err;
+}
+
+
+bool nvdimm_encrypt_unlock(TargetHandleList &i_nvdimmList)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_encrypt_unlock()");
+ errlHndl_t l_err = nullptr;
+ bool l_success = true;
+
+ do
+ {
+ // Get the sys pointer, attribute keys are system level
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "nvdimm_encrypt_unlock() no TopLevelTarget");
+
+ // Exit if encryption is not enabled via the attribute
+ if (!l_sys->getAttr<ATTR_NVDIMM_ENCRYPTION_ENABLE>())
+ {
+ TRACFCOMP(g_trac_nvdimm,"ATTR_NVDIMM_ENCRYPTION_ENABLE=0");
+ break;
+ }
+
+ // Get the FW key attributes
+ auto l_attrKeysFw =
+ l_sys->getAttrAsStdArr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>();
+
+ // Cast to key data struct type for easy access to each key
+ nvdimmKeyData_t* l_keysFw =
+ reinterpret_cast<nvdimmKeyData_t*>(&l_attrKeysFw);
+
+ // Check for valid key attribute data
+ l_err = nvdimm_checkValidAttrKeys(l_keysFw);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Check encryption unlock for all nvdimms
+ for (const auto & l_nvdimm : i_nvdimmList)
+ {
+ // Get encryption state in the config/status reg
+ encryption_config_status_t l_encStatus;
+ l_encStatus.whole = 0;
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_CONFIG_STATUS,
+ l_encStatus.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_encrypt_unlock() nvdimm[%X] error reading ENCRYPTION_CONFIG_STATUS",get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ continue;
+ }
+
+ // Already unlocked or not enabled then exit
+ if (l_encStatus.encryption_unlocked ||
+ !l_encStatus.encryption_enabled)
+ {
+ break;
+ }
+
+ // Else encryption is enabled but needs unlock
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_encrypt_unlock() nvdimm[%X] enabled, unlocking...",get_huid(l_nvdimm));
+
+ // Set the Unlock Access Key Reg
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_keysFw->ak,
+ ENCRYPTION_ACCESS_KEY_UNLOCK,
+ ENCRYPTION_ACCESS_KEY_VERIFY,
+ false);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ continue;
+ }
+
+ // Verify encryption is unlocked
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_CONFIG_STATUS,
+ l_encStatus.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_encrypt_unlock() nvdimm[%X] error reading ENCRYPTION_CONFIG_STATUS after unlock",get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ continue;
+ }
+
+ if (!l_encStatus.encryption_unlocked)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_encrypt_unlock() nvdimm[%X] encryption unlock failed, expected ENCRYPTION_CONFIG_STATUS=0x%.02X, expected=0x1F ",get_huid(l_nvdimm),l_encStatus.whole);
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ENCRYPTION_UNLOCK_FAILED
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_ENCRYPT_UNLOCK
+ *@userdata1 NVDIMM HUID
+ *@userdata2 ENCRYPTION_CONFIG_STATUS
+ *@devdesc NVDIMM failed to unlock encryption
+ *@custdesc NVDIMM encryption error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_ENCRYPT_UNLOCK,
+ NVDIMM_ENCRYPTION_UNLOCK_FAILED,
+ get_huid(l_nvdimm),
+ l_encStatus.whole,
+ 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);
+
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ l_success = false;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_encrypt_unlock() nvdimm[%X] encryption is unlocked 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ }
+ }
+ }while(0);
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_encrypt_unlock()");
+ return l_success;
+}
+
+
+#endif
+
+
+bool nvdimm_keyifyRandomNumber(uint8_t* o_genData, uint8_t* i_xtraData)
+{
+ bool l_failed = false;
+ uint32_t l_xtraByte = 0;
+
+ for (uint32_t l_byte = 0; l_byte < ENC_KEY_SIZE; l_byte++)
+ {
+ if ((o_genData[l_byte] != KEY_TERMINATE_BYTE) &&
+ (o_genData[l_byte] != KEY_ABORT_BYTE))
+ {
+ // This byte is valid
+ continue;
+ }
+
+ // This byte is not valid, replace it
+ // Find a valid byte in the replacement data
+ while ((i_xtraData[l_xtraByte] == KEY_TERMINATE_BYTE) ||
+ (i_xtraData[l_xtraByte] == KEY_ABORT_BYTE))
+ {
+ l_xtraByte++;
+
+ if (l_xtraByte == ENC_KEY_SIZE)
+ {
+ l_failed = true;
+ break;
+ }
+ }
+
+ if (l_failed)
+ {
+ break;
+ }
+
+ // Replace the invalid byte with the valid extra byte
+ o_genData[l_byte] = i_xtraData[l_xtraByte];
+ }
+
+ return l_failed;
+}
+
+
+bool nvdimm_validRandomNumber(uint8_t* i_genData)
+{
+ bool l_valid = true;
+ for (uint32_t l_byte = 0; l_byte < ENC_KEY_SIZE; l_byte++)
+ {
+ if ((i_genData[l_byte] == KEY_TERMINATE_BYTE) ||
+ (i_genData[l_byte] == KEY_ABORT_BYTE))
+ {
+ l_valid = false;
+ break;
+ }
+ }
+ return l_valid;
+}
+
+
+errlHndl_t nvdimm_checkValidAttrKeys( nvdimmKeyData_t* i_attrData )
{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_gen_keys()");
errlHndl_t l_err = nullptr;
+ bool l_valid = false;
+
+ do
+ {
+ l_valid = nvdimm_validRandomNumber(i_attrData->rs);
+ if (!l_valid)
+ {
+ break;
+ }
+ l_valid = nvdimm_validRandomNumber(i_attrData->ek);
+ if (!l_valid)
+ {
+ break;
+ }
+ l_valid = nvdimm_validRandomNumber(i_attrData->ak);
+ if (!l_valid)
+ {
+ break;
+ }
+ }while(0);
+
+ if (!l_valid)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_checkValidAttrKeys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW contains invalid data");
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ENCRYPTION_INVALID_ATTRIBUTE
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_CHECK_VALID_ATTR_DATA
+ *@devdesc ATTR_NVDIMM_ENCRYPTION_KEYS_FW has invalid data
+ *@custdesc NVDIMM encryption error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_CHECK_VALID_ATTR_DATA,
+ NVDIMM_ENCRYPTION_INVALID_ATTRIBUTE,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ }
+
+ return l_err;
+}
+
+
+errlHndl_t nvdimm_handleConflictingKeys(
+ ATTR_NVDIMM_ENCRYPTION_KEYS_FW_typeStdArr& i_attrKeysFw,
+ ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR_typeStdArr& i_attrKeysAnchor)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_handleConflictingKeys()");
+ errlHndl_t l_err = nullptr;
+ bool l_validKeyFound = false;
+
+ // Recast to key data type to simplify parsing
+ nvdimmKeyData_t* l_keysFw =
+ reinterpret_cast<nvdimmKeyData_t*>(&i_attrKeysFw);
+ nvdimmKeyData_t* l_keysAnchor =
+ reinterpret_cast<nvdimmKeyData_t*>(&i_attrKeysAnchor);
+
+ // Get the nvdimm target pointers
+ TargetHandleList l_nvdimmTargetList;
+ nvdimm_getNvdimmList(l_nvdimmTargetList);
+ for (const auto & l_nvdimm : l_nvdimmTargetList)
+ {
+ // Write the EK test reg with the FW attr value
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_keysFw->ek,
+ ENCRYPTION_ERASE_KEY_TEST,
+ ENCRYPTION_ERASE_KEY_TEST_VERIFY,
+ false);
+ if (l_err)
+ {
+ // RTC 210689 Handle return values
+ break;
+ }
+
+ // Check for erase key valid in the validation reg
+ encryption_key_validation_t l_keyValid = {0};
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_KEY_VALIDATION,
+ l_keyValid.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_handleConflictingKeys() nvdimm[%X] error reading ENCRYPTION_KEY_VALIDATION",get_huid(l_nvdimm));
+ // RTC 210689 Handle return values
+ break;
+ }
+ if (l_keyValid.erase_key_valid)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_handleConflictingKeys() nvdimm[%X] ATTR_NVDIMM_ENCRYPTION_KEYS_FW valid",get_huid(l_nvdimm));
+ l_validKeyFound = true;
+ // Send attr to HWSV if at runtime
+ // RTC:210692 Update HWSV with key attribute value
+ break;
+ }
+
+ // Write the EK test reg with the Anchor attr value
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_keysAnchor->ek,
+ ENCRYPTION_ERASE_KEY_TEST,
+ ENCRYPTION_ERASE_KEY_TEST_VERIFY,
+ false);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Check for erase key valid in the validation reg
+ l_keyValid.whole = 0;
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_KEY_VALIDATION,
+ l_keyValid.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_handleConflictingKeys() nvdimm[%X] error reading ENCRYPTION_KEY_VALIDATION",get_huid(l_nvdimm));
+ break;
+ }
+ if (l_keyValid.erase_key_valid)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_handleConflictingKeys() nvdimm[%X] ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR valid",get_huid(l_nvdimm));
+ l_validKeyFound = true;
+ // Copy anchor attr value to FW attribute
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "nvdimm_handleConflictingKeys: no TopLevelTarget");
+ l_sys->setAttr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>(reinterpret_cast<ATTR_NVDIMM_ENCRYPTION_KEYS_FW_type&>(i_attrKeysAnchor));
+ break;
+ }
+ }
+
+ if (!l_validKeyFound)
+ {
+ // Neither key attribute is valid
+ TRACFCOMP(g_trac_nvdimm,ERR_MRK"nvdimm_handleConflictingKeys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW and ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR invalid.");
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ENCRYPTION_KEY_ATTRS_INVALID
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_HANDLE_CONFLICTING_KEYS
+ *@devdesc NVDIMM encryption key attributes invalid
+ *@custdesc NVDIMM encryption error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_HANDLE_CONFLICTING_KEYS,
+ NVDIMM_ENCRYPTION_KEY_ATTRS_INVALID,
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ }
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_handleConflictingKeys()");
+ return l_err;
+}
+
+
+void nvdimm_getNvdimmList(TargetHandleList &o_nvdimmTargetList)
+{
+ // Check for any NVDIMMs after the mss_power_cleanup
+ TargetHandleList l_dimmTargetList;
+ getAllLogicalCards(l_dimmTargetList, TYPE_DIMM);
+
+ // Walk the dimm list and collect all the nvdimm targets
+ for (auto const l_dimm : l_dimmTargetList)
+ {
+ if (isNVDIMM(l_dimm))
+ {
+ o_nvdimmTargetList.push_back(l_dimm);
+ }
+ }
+}
+
+
+bool nvdimm_gen_keys(void)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_gen_keys()");
+ errlHndl_t l_err = nullptr;
+ bool l_success = true;
do
{
@@ -1474,235 +2058,634 @@ void nvdimm_gen_keys(TargetHandleList &i_nvdimmList)
// Exit if encryption is not enabled via the attribute
if (!l_sys->getAttr<ATTR_NVDIMM_ENCRYPTION_ENABLE>())
{
+ TRACFCOMP(g_trac_nvdimm,"ATTR_NVDIMM_ENCRYPTION_ENABLE=0");
break;
}
- // Get the FW attribute
- ATTR_NVDIMM_ENCRYPTION_KEYS_FW_type l_attrKeysFw = {0};
- assert(l_sys->tryGetAttr
- <ATTR_NVDIMM_ENCRYPTION_KEYS_FW>(l_attrKeysFw),
- "nvdimm_gen_keys() Failed getting ATTR_NVDIMM_ENCRYPTION_KEYS_FW");
-
- // FW attribute checks
- size_t l_attrSizeFw = sizeof(ATTR_NVDIMM_ENCRYPTION_KEYS_FW_type);
- // Attribute size must be a multiple of the key size
- assert((l_attrSizeFw % NUM_KEYS_IN_ATTR) == 0,
- "nvdimm_gen_keys() Size of ATTR_NVDIMM_ENCRYPTION_KEYS_FW is not a multiple of the key size");
- // Attribute key size must not exceed max size
- assert((l_attrSizeFw / NUM_KEYS_IN_ATTR) <= MAX_KEY_SIZE,
- "nvdimm_gen_keys() Size of keys in ATTR_NVDIMM_ENCRYPTION_KEYS_FW is greater than MAX_KEY_SIZE");
-
- // Check for FW attribute = zero
- ATTR_NVDIMM_ENCRYPTION_KEYS_FW_type l_fwCompare = {0};
- bool l_attrIsZeroFw = memcmp(l_attrKeysFw, l_fwCompare, l_attrSizeFw) == 0;
-
- // Get the anchor attribute
- ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR_type l_attrKeysAnchor = {0};
- assert(l_sys->tryGetAttr
- <ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR>(l_attrKeysAnchor),
- "nvdimm_gen_keys() Failed getting ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR");
-
- // Anchor attribute checks
- size_t l_attrSizeAnchor = sizeof(ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR_type);
- // Attribute size must be a multiple of the key size
- assert((l_attrSizeAnchor % NUM_KEYS_IN_ATTR) == 0,
- "nvdimm_gen_keys() Size of ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR is not a multiple of the key size");
- // Attribute key size must not exceed max size
- assert((l_attrSizeAnchor / NUM_KEYS_IN_ATTR) <= MAX_KEY_SIZE,
- "nvdimm_gen_keys() Size of keys in ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR is greater than MAX_KEY_SIZE");
-
- // Check for Anchor attribute = zero
- ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR_type l_anchorCompare = {0};
- bool l_attrIsZeroAnchor = memcmp(l_attrKeysAnchor, l_anchorCompare, l_attrSizeAnchor) == 0;
+ // Key size must be less that max TPM random generator size
+ static_assert(ENC_KEY_SIZE <= MAX_TPM_SIZE,
+ "nvdimm_gen_keys() ENC_KEY_SIZE is greater than MAX_TPM_SIZE");
+
+ // Key attributes should be same size
+ static_assert( sizeof(ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR_type) ==
+ sizeof(ATTR_NVDIMM_ENCRYPTION_KEYS_FW_type),
+ "nvdimm_gen_keys() size of ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR_type does not match ATTR_NVDIMM_ENCRYPTION_KEYS_FW_type");
+
+ // Get the key attributes
+ auto l_attrKeysFw =
+ l_sys->getAttrAsStdArr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>();
+ auto l_attrKeysAn =
+ l_sys->getAttrAsStdArr<ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR>();
+
+ // Check the attribute sizes
+ static_assert(sizeof(l_attrKeysFw) == (NUM_KEYS_IN_ATTR * ENC_KEY_SIZE),
+ "nvdimm_gen_keys() Size of ATTR_NVDIMM_ENCRYPTION_KEYS_FW does not match NUM_KEYS_IN_ATTR * ENC_KEY_SIZE");
+ static_assert(sizeof(l_attrKeysAn) == (NUM_KEYS_IN_ATTR * ENC_KEY_SIZE),
+ "nvdimm_gen_keys() Size of ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR does not match NUM_KEYS_IN_ATTR * ENC_KEY_SIZE");
+
+ // Compare attributes to zero
+ std::array<uint8_t,sizeof(l_attrKeysFw)> l_zero = {0};
+ bool l_fwZero = (l_attrKeysFw == l_zero);
+ bool l_anZero = (l_attrKeysAn == l_zero);
// Compare the attribute values
- if (!l_attrIsZeroFw && !l_attrIsZeroAnchor)
+ if (!l_fwZero && !l_anZero)
{
- if (memcmp(l_attrKeysFw,l_attrKeysAnchor,l_attrSizeFw) == 0)
+ if (l_attrKeysFw != l_attrKeysAn)
{
- TRACFCOMP(g_trac_nvdimm, "nvdimm_gen_keys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW = ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR");
+ // Handle conflicting keys
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_gen_keys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW != ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR");
+ l_err = nvdimm_handleConflictingKeys(l_attrKeysFw,l_attrKeysAn);
}
- if (memcmp(l_attrKeysFw,l_attrKeysAnchor,l_attrSizeFw) != 0)
+ else
{
- TRACFCOMP(g_trac_nvdimm, "nvdimm_gen_keys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW != ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR");
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_gen_keys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW == ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR");
}
break;
}
- if (!l_attrIsZeroFw && l_attrIsZeroAnchor)
+ else if (!l_fwZero && l_anZero)
{
TRACFCOMP(g_trac_nvdimm, "nvdimm_gen_keys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW != 0 and ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR = 0");
break;
}
- if (l_attrIsZeroFw && !l_attrIsZeroAnchor)
+ else if (l_fwZero && !l_anZero)
{
// Set FW attr = Anchor attr
TRACFCOMP(g_trac_nvdimm, "nvdimm_gen_keys() Setting ATTR_NVDIMM_ENCRYPTION_KEYS_FW = ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR");
- l_sys->setAttr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>(l_attrKeysAnchor);
+ l_sys->setAttrFromStdArr
+ <ATTR_NVDIMM_ENCRYPTION_KEYS_FW>(l_attrKeysAn);
break;
}
- // Both key attributes are zero
- // Generate random keys using the TPM hardware
- TargetHandleList l_tpmList;
- TRUSTEDBOOT::getTPMs(l_tpmList,
- TRUSTEDBOOT::TPM_FILTER::ALL_FUNCTIONAL);
- if (l_tpmList.size() == 0)
+ // If we get here then both key attributes are zero, generate new keys
+ assert(sizeof(l_attrKeysFw) == sizeof(nvdimmKeyData_t),
+ "nvdimm_gen_keys() ATTR_NVDIMM_ENCRYPTION_KEYS_FW size does not match nvdimmKeyData_t");
+ nvdimmKeyData_t* l_keys =
+ reinterpret_cast<nvdimmKeyData_t*>(&l_attrKeysFw);
+
+ // Generate Random String (RS)
+ l_err = nvdimm_getRandom(l_keys->rs);
+ if (l_err)
{
- TRACFCOMP(g_trac_nvdimm,ERR_MRK"No functional TPM found, encryption keys not generated.");
+ break;
+ }
- /*@
- *@errortype
- *@reasoncode NVDIMM_TPM_NOT_FOUND
- *@severity ERRORLOG_SEV_PREDICTIVE
- *@moduleid NVDIMM_GEN_KEYS
- *@userdata1 <UNUSED>
- *@userdata2 <UNUSED>
- *@devdesc Encountered error generating NVDIMM encryption keys
- *@custdesc NVDIMM error generating encryption keys
- */
- l_err = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_PREDICTIVE,
- NVDIMM_GEN_KEYS,
- NVDIMM_TPM_NOT_FOUND,
- 0x0,
- 0x0,
- ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+ // Generate Erase Key (EK)
+ l_err = nvdimm_getRandom(l_keys->ek);
+ if (l_err)
+ {
+ break;
+ }
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024 );
+ // Generate Access Key (AK)
+ l_err = nvdimm_getRandom(l_keys->ak);
+ if (l_err)
+ {
+ break;
+ }
- // Get all TPMs
- TRUSTEDBOOT::getTPMs(l_tpmList,
- TRUSTEDBOOT::TPM_FILTER::ALL_IN_BLUEPRINT);
- if (l_tpmList.size() == 0)
- {
- // No TPMs, we probably have nvdimms enabled
- // when they should not be
- l_err->addProcedureCallout(
- HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_HIGH);
- }
- else
- {
- // If a TPM exists it must be deconfigured,
- // add callouts accordingly
- l_err->addProcedureCallout(
- HWAS::EPUB_PRC_FIND_DECONFIGURED_PART,
- HWAS::SRCI_PRIORITY_HIGH);
- l_err->addProcedureCallout(
- HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_MED);
- }
+ // Set the FW attribute
+ l_sys->setAttrFromStdArr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>(l_attrKeysFw);
- errlCommit( l_err, NVDIMM_COMP_ID );
+ }while(0);
- // Set the status flag for all nvdimms
- for (const auto & l_nvdimm : i_nvdimmList)
- {
- nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
- }
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_gen_keys() Failed to generate keys, will not set ATTR_NVDIMM_ENCRYPTION_KEYS_FW");
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ l_success = false;
+
+ // Set the status flag for all nvdimms
+ TargetHandleList l_nvdimmTargetList;
+ nvdimm_getNvdimmList(l_nvdimmTargetList);
+ for (const auto & l_nvdimm : l_nvdimmTargetList)
+ {
+ nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ }
+ }
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_gen_keys()");
+ return l_success;
+}
+
+
+bool nvdimm_remove_keys(void)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_remove_keys()");
+ bool l_success = true;
+
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "nvdimm_remove_keys() no TopLevelTarget");
+
+ // Set the FW attribute = 0
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_remove_keys() Setting ATTR_NVDIMM_ENCRYPTION_KEYS_FW=0");
+ ATTR_NVDIMM_ENCRYPTION_KEYS_FW_type l_attrKeysFw = {0};
+ l_sys->setAttr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>(l_attrKeysFw);
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_remove_keys()");
+ return l_success;
+}
+
+
+errlHndl_t nvdimm_setKeyReg(Target* i_nvdimm,
+ uint8_t* i_keyData,
+ uint32_t i_keyReg,
+ uint32_t i_verifyReg,
+ bool i_secondAttempt)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_setKeyReg(0x%X) reg=0x%X",get_huid(i_nvdimm),i_keyReg);
+ errlHndl_t l_err = nullptr;
+ do
+ {
+ uint32_t l_byte = 0;
+ uint8_t l_verifyData = 0x0;
+
+ // Before setting the key reg we need to
+ // init the verif reg with a random value
+ uint8_t l_genData[ENC_KEY_SIZE] = {0};
+ l_err = nvdimm_getRandom(l_genData);
+ if (l_err)
+ {
break;
}
+ // Write the verif reg one byte at a time
+ for (l_byte = 0; l_byte < ENC_KEY_SIZE; l_byte++)
+ {
+ // Write the verification byte
+ l_err = nvdimmWriteReg(i_nvdimm, i_verifyReg, l_genData[l_byte]);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_setKeyReg() huid=0x%X, error writing verif reg=0x%.03X byte=0x%d", get_huid(i_nvdimm), i_verifyReg, l_byte);
+ break;
+ }
+ }
- // TPM can only generate up to 34 bytes so gen 1 key at a time
- size_t l_genSize = l_attrSizeFw / NUM_KEYS_IN_ATTR;
- uint8_t l_genData[l_genSize] = {0};
- for (uint32_t l_key=0; l_key<NUM_KEYS_IN_ATTR; l_key++)
+ // Delay to allow verif write to complete
+ nanosleep(0, KEY_WRITE_DELAY_MS*NS_PER_MSEC);
+
+ // Write the reg, one byte at a time
+ for (l_byte = 0; l_byte < ENC_KEY_SIZE; l_byte++)
{
- l_err = TRUSTEDBOOT::GetRandom(l_tpmList[0], l_genSize, l_genData);
+ // Write the key byte
+ l_err = nvdimmWriteReg(i_nvdimm, i_keyReg, i_keyData[l_byte]);
if (l_err)
{
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_gen_keys() Failing Trustedboot::GetRandom()");
- errlCommit( l_err, NVDIMM_COMP_ID );
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_setKeyReg() huid=0x%X, error writing key reg 0x%.03X byte=0x%d", get_huid(i_nvdimm), i_keyReg, l_byte);
+ break;
+ }
+
+ // Read the verification byte
+ l_err = nvdimmReadReg(i_nvdimm, i_verifyReg, l_verifyData);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_setKeyReg() huid=0x%X, error reading verif reg=0x%.03X byte=0x%d", get_huid(i_nvdimm), i_verifyReg, l_byte);
+ break;
+ }
+
+ // Verify the key byte
+ if (l_verifyData != i_keyData[l_byte])
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_setKeyReg() huid=0x%X, key verification failed reg=0x%.03X byte=0x%d set=0x%.02x get=0x%.02x", get_huid(i_nvdimm), i_keyReg, l_byte, i_keyData[l_byte], l_verifyData);
+ // Write KEY_ABORT_BYTE to abort the key write sequence
+ l_err = nvdimmWriteReg(i_nvdimm, i_keyReg, KEY_ABORT_BYTE);
+ if (i_secondAttempt)
+ {
+ // Verify check byte failed for the second time
+ TRACFCOMP(g_trac_nvdimm,ERR_MRK"nvdimm_getTPM() Key verification byte check failed on second attempt.");
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_VERIF_BYTE_CHECK_FAILED
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_SET_KEY_REG
+ *@userdata1 NVDIMM HUID
+ *@userdata2[0:31] Key Register
+ *@userdata2[32:63] Verif Register
+ *@devdesc NVDIMM failed to set encryption register
+ *@custdesc NVDIMM register error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_SET_KEY_REG,
+ NVDIMM_VERIF_BYTE_CHECK_FAILED,
+ get_huid(i_nvdimm),
+ NVDIMM_SET_USER_DATA_1(i_keyReg,i_verifyReg),
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ l_err->addPartCallout( i_nvdimm,
+ HWAS::NV_CONTROLLER_PART_TYPE,
+ HWAS::SRCI_PRIORITY_HIGH);
+ }
+ else
+ {
+ // Try writing the reg again
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_setKeyReg() huid=0x%X, writing reg=0x%.03X again", get_huid(i_nvdimm), i_keyReg);
+ l_err = nvdimm_setKeyReg(i_nvdimm,
+ i_keyData,
+ i_keyReg,
+ i_verifyReg,
+ true);
+ }
+ break;
}
- memcpy(
- reinterpret_cast<uint8_t*>(l_attrKeysFw) + (l_key*l_genSize),
- l_genData,
- l_genSize );
}
- // Set the FW attribute
- l_sys->setAttr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>(l_attrKeysFw);
+ // Delay to allow write to complete
+ nanosleep(0, KEY_WRITE_DELAY_MS*NS_PER_MSEC);
}while(0);
- TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_gen_keys()");
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_setKeyReg(0x%X) reg=0x%X",get_huid(i_nvdimm),i_keyReg);
+ return l_err;
}
-/**
- * @brief NVDIMM initialization
- * - Checks for ready state
- * - Gathers timeout values
- * - Waits for the ongoing backup to complete
- * - Disarms the trigger for draminit
- *
- * @param[in] i_nvdimm - nvdimm target
- *
- */
-void nvdimm_init(Target *i_nvdimm)
-{
- TRACUCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_init() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+bool nvdimm_encrypt_enable(TargetHandleList &i_nvdimmList)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_encrypt_enable()");
errlHndl_t l_err = nullptr;
+ bool l_success = true;
do
{
- l_err = nvdimmReady(i_nvdimm);
+ // Get the sys pointer, attribute keys are system level
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "nvdimm_encrypt_enable() no TopLevelTarget");
- if (l_err)
+ // Exit if encryption is not enabled via the attribute
+ if (!l_sys->getAttr<ATTR_NVDIMM_ENCRYPTION_ENABLE>())
{
- nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR);
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_int() nvdimm[%X], controller not ready",
- TARGETING::get_huid(i_nvdimm));
- errlCommit(l_err, NVDIMM_COMP_ID);
+ TRACFCOMP(g_trac_nvdimm,"ATTR_NVDIMM_ENCRYPTION_ENABLE=0");
break;
}
- // Get the timeout values for the major ops at init
- l_err = nvdimmGetTimeoutVal(i_nvdimm);
+ // Get the FW key attributes
+ auto l_attrKeysFw =
+ l_sys->getAttrAsStdArr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>();
+
+ // Cast to key data struct type for easy access to each key
+ nvdimmKeyData_t* l_keysFw =
+ reinterpret_cast<nvdimmKeyData_t*>(&l_attrKeysFw);
+
+ // Check for valid key attribute key data
+ l_err = nvdimm_checkValidAttrKeys(l_keysFw);
if (l_err)
{
- nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR);
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_int() nvdimm[%X], error retrieving timeout values",
- TARGETING::get_huid(i_nvdimm));
- errlCommit(l_err, NVDIMM_COMP_ID);
break;
}
- //Check save progress
- uint32_t l_poll = 0;
- l_err = nvdimmPollBackupDone(i_nvdimm, l_poll);
+ // Handle encryption for all nvdimms
+ for (const auto & l_nvdimm : i_nvdimmList)
+ {
+ // Check encryption state in the config/status reg
+ encryption_config_status_t l_encStatus;
+ l_encStatus.whole = 0;
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_CONFIG_STATUS,
+ l_encStatus.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_encrypt_enable() nvdimm[%X] error reading ENCRYPTION_CONFIG_STATUS",get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ continue;
+ }
- if (l_err)
+ // Encryption is enabled and unlocked
+ if (l_encStatus.encryption_unlocked &&
+ l_encStatus.encryption_enabled)
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_encrypt_enable() nvdimm[%X] enabled and unlocked",get_huid(l_nvdimm));
+ continue;
+ }
+
+ // Need to handle these cases?
+ if (!(l_encStatus.whole == 0x01))
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_encrypt_enable() nvdimm[%X] unsupported state 0x%.02X",get_huid(l_nvdimm),l_encStatus.whole);
+ continue;
+ }
+
+ // Status = 0x01, enable encryption
+ // Set the Random String (RS) reg
+ TRACFCOMP(g_trac_nvdimm,"nvdimm_encrypt_enable() nvdimm[%X] status=0x01 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_keysFw->rs,
+ ENCRYPTION_RAMDOM_STRING_SET,
+ ENCRYPTION_RANDOM_STRING_VERIFY,
+ false);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ continue;
+ }
+
+ // Set the Erase Key (EK) Reg
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_keysFw->ek,
+ ENCRYPTION_ERASE_KEY_SET,
+ ENCRYPTION_ERASE_KEY_VERIFY,
+ false);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ continue;
+ }
+
+ // Set the Access Key (AK) Reg
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_keysFw->ak,
+ ENCRYPTION_ACCESS_KEY_SET,
+ ENCRYPTION_ACCESS_KEY_VERIFY,
+ false);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ continue;
+ }
+
+ // Verify encryption is enabled
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_CONFIG_STATUS,
+ l_encStatus.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_encrypt_enable() nvdimm[%X] error reading ENCRYPTION_CONFIG_STATUS after enable",get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ continue;
+ }
+ if (!(l_encStatus.whole == 0x1F))
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_encrypt_enable() nvdimm[%X] encryption enable failed, ENCRYPTION_CONFIG_STATUS=0x%.02X, expected=0x1F ",get_huid(l_nvdimm),l_encStatus.whole);
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ENCRYPTION_ENABLE_FAILED
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_ENCRYPT_ENABLE
+ *@userdata1 NVDIMM HUID
+ *@userdata2 ENCRYPTION_CONFIG_STATUS
+ *@devdesc NVDIMM failed to enable encryption
+ *@custdesc NVDIMM encryption error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_ENCRYPT_ENABLE,
+ NVDIMM_ENCRYPTION_ENABLE_FAILED,
+ get_huid(l_nvdimm),
+ l_encStatus.whole,
+ 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);
+
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_encrypt_enable() nvdimm[%X] encryption is enabled 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ }
+ }
+ }while(0);
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_encrypt_enable()");
+ return l_success;
+}
+
+
+bool nvdimm_crypto_erase(TargetHandleList &i_nvdimmList)
+{
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimm_crypto_erase()");
+ errlHndl_t l_err = nullptr;
+ bool l_success = true;
+
+ do
+ {
+ // Get the sys pointer, attribute keys are system level
+ Target* l_sys = nullptr;
+ targetService().getTopLevelTarget( l_sys );
+ assert(l_sys, "nvdimm_crypto_erase: no TopLevelTarget");
+
+ // Exit if encryption is not enabled via the attribute
+ if (!l_sys->getAttr<ATTR_NVDIMM_ENCRYPTION_ENABLE>())
{
- nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_NOPRSV);
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_int() nvdimm[%X], error backing up the DRAM!",
- TARGETING::get_huid(i_nvdimm));
- errlCommit(l_err, NVDIMM_COMP_ID);
+ TRACFCOMP(g_trac_nvdimm,"ATTR_NVDIMM_ENCRYPTION_ENABLE=0");
break;
}
- // Disarm the ddr_resetn here in case it came in armed. When the nvdimm is
- // armed the reset_n is masked off from the host, meaning the drams won't
- // be able to get reset properly later, causing training to fail.
- l_err = nvdimmChangeArmState(i_nvdimm, DISARM_TRIGGER);
+ // Get the FW key attributes
+ auto l_attrKeysFw =
+ l_sys->getAttrAsStdArr<ATTR_NVDIMM_ENCRYPTION_KEYS_FW>();
+
+ // Cast to key data struct type for easy access to each key
+ nvdimmKeyData_t* l_keysFw =
+ reinterpret_cast<nvdimmKeyData_t*>(&l_attrKeysFw);
+ // Check for valid key attribute key data
+ l_err = nvdimm_checkValidAttrKeys(l_keysFw);
if (l_err)
{
- nvdimmSetStatusFlag(i_nvdimm, NSTD_ERR_NOPRSV);
- TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_init() nvdimm[%X], error disarming the nvdimm!",
- TARGETING::get_huid(i_nvdimm));
- errlCommit(l_err, NVDIMM_COMP_ID);
break;
}
+ // Handle erase for all nvdimms
+ for (const auto & l_nvdimm : i_nvdimmList)
+ {
+ // Check encryption state in the config/status reg
+ encryption_config_status_t l_encStatus = {0};
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_CONFIG_STATUS,
+ l_encStatus.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_crypto_erase() nvdimm[%X] error reading ENCRYPTION_CONFIG_STATUS",get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ l_success = false;
+ continue;
+ }
+ // Encryption enabled must be set to crypto erase
+ if (!l_encStatus.encryption_enabled)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_crypto_erase() nvdimm[%X] encryption not enabled, will not cypto erase 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ // TODO RTC:210689 Handle function return pass/fail
+ continue;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nvdimm, "nvdimm_crypto_erase() nvdimm[%X] encryption enabled 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ }
+
+ // Set the Erase Key (EK) Reg
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_keysFw->ek,
+ ENCRYPTION_ERASE_KEY_SET,
+ ENCRYPTION_ERASE_KEY_VERIFY,
+ false);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ continue;
+ }
+
+ // Check encryption state in the config/status reg
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_CONFIG_STATUS,
+ l_encStatus.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_crypto_erase() nvdimm[%X] error reading ENCRYPTION_CONFIG_STATUS",get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ continue;
+ }
+ // Erase pending bit should be set
+ if (!l_encStatus.erase_pending)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_crypto_erase() nvdimm[%X] expected erase pending = 1 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ENCRYPTION_ERASE_PENDING_FAILED
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_CRYPTO_ERASE
+ *@userdata1 NVDIMM HUID
+ *@userdata2 ENCRYPTION_CONFIG_STATUS
+ *@devdesc NVDIMM failed to set encryption register
+ *@custdesc NVDIMM register error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_CRYPTO_ERASE,
+ NVDIMM_ENCRYPTION_ERASE_PENDING_FAILED,
+ get_huid(l_nvdimm),
+ l_encStatus.whole,
+ 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);
+
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ continue;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nvdimm,"nvdimm_crypto_erase() nvdimm[%X] erase pending 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ }
+
+ // Generate a generic erase key
+ uint8_t l_genData[ENC_KEY_SIZE] = {0};
+ l_err = nvdimm_getRandom(l_genData);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ continue;
+ }
+
+ // Set the Erase Key (EK) Reg
+ l_err = nvdimm_setKeyReg(l_nvdimm,
+ l_genData,
+ ENCRYPTION_ERASE_KEY_SET,
+ ENCRYPTION_ERASE_KEY_VERIFY,
+ false);
+ if (l_err)
+ {
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ continue;
+ }
+
+ // Check encryption state in the config/status reg
+ l_err = nvdimmReadReg(l_nvdimm,
+ ENCRYPTION_CONFIG_STATUS,
+ l_encStatus.whole);
+ if (l_err)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_crypto_erase() nvdimm[%X] error reading ENCRYPTION_CONFIG_STATUS",get_huid(l_nvdimm));
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ continue;
+ }
+ // Encryption enabled bit should not be set
+ if (l_encStatus.encryption_enabled)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_crypto_erase() nvdimm[%X] expected encryption enabled = 0 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ENCRYPTION_ERASE_FAILED
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_CRYPTO_ERASE
+ *@userdata1 NVDIMM HUID
+ *@userdata2 ENCRYPTION_CONFIG_STATUS
+ *@devdesc NVDIMM failed to set encryption register
+ *@custdesc NVDIMM register error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_CRYPTO_ERASE,
+ NVDIMM_ENCRYPTION_ERASE_FAILED,
+ get_huid(l_nvdimm),
+ l_encStatus.whole,
+ 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);
+
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ // TODO RTC:210689 Handle status flag
+ //nvdimmSetStatusFlag(l_nvdimm, NSTD_ERR_NOBKUP);
+ l_success = false;
+ continue;
+ }
+ else
+ {
+ TRACFCOMP(g_trac_nvdimm,"nvdimm_crypto_erase() nvdimm[%X] erase complete 0x%.02x",get_huid(l_nvdimm),l_encStatus.whole);
+ }
+ }
}while(0);
- TRACUCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_init() nvdimm[%X]",
- TARGETING::get_huid(i_nvdimm));
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimm_crypto_erase()");
+ return l_success;
}
-#endif
+
} // end NVDIMM namespace
diff --git a/src/usr/isteps/nvdimm/nvdimm.H b/src/usr/isteps/nvdimm/nvdimm.H
index 4d97a9c66..3caa2c6e3 100644
--- a/src/usr/isteps/nvdimm/nvdimm.H
+++ b/src/usr/isteps/nvdimm/nvdimm.H
@@ -27,6 +27,7 @@
#define NVDIMM_H__
#include <usr/errl/errlentry.H>
+#include <targeting/common/target.H>
#include <targeting/common/commontargeting.H>
#include <targeting/common/util.H>
#include <targeting/common/utilFilter.H>
@@ -274,6 +275,18 @@ enum i2cReg : uint16_t
TYPED_BLOCK_DATA_BYTE30 = 0x39E,
TYPED_BLOCK_DATA_BYTE31 = 0x39F,
TYPED_BLOCK_DATA_OFFSET = 0x3E0,
+ 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,
};
// i2cReg macros
@@ -292,6 +305,7 @@ enum page : uint8_t
TWO = 0x02,
THREE = 0x03,
FOUR = 0x04,
+ FIVE = 0x05,
};
// Enums for inputs/expected output to/from the i2c registers
@@ -330,6 +344,7 @@ enum timeout : uint32_t
OPS_POLL_TIME_MS = 5000,
NV_READY_POLL_TIME_MS = 1000,
PAGE_SWITCH_POLL_TIME_NS = 100,
+ KEY_WRITE_DELAY_MS = 100,
};
// Assign an id to each of the 6 major ops
@@ -353,6 +368,26 @@ enum misc
HIGH = 1,
};
+const size_t NUM_KEYS_IN_ATTR = 3;
+const size_t ENC_KEY_SIZE = 32;
+const size_t MAX_TPM_SIZE = 34;
+const uint8_t KEY_TERMINATE_BYTE = 0x00;
+const uint8_t KEY_ABORT_BYTE = 0xFF;
+const uint64_t DARN_ERROR_CODE = 0xFFFFFFFFFFFFFFFFull;
+const uint32_t MAX_DARN_ERRORS = 10;
+const uint32_t MAX_RANDOM_ATTEMPTS = 100;
+
+
+/**
+ * @brief Encryption key data
+ */
+struct nvdimmKeyData_t
+{
+ uint8_t rs[ENC_KEY_SIZE]; // Random String (RS)
+ uint8_t ek[ENC_KEY_SIZE]; // Erase Key (EK)
+ uint8_t ak[ENC_KEY_SIZE]; // Access Key (AK)
+};
+
/**
* @brief Wrapper to call deviceOp to read the NV controller via I2C
*
@@ -434,6 +469,112 @@ errlHndl_t nvdimmPollStatus(TARGETING::Target *i_nvdimm, ops_id i_ops_id, uint32
* the error log.
*/
errlHndl_t nvdimmSetESPolicy(TARGETING::Target* i_nvdimm);
+
+
+/**
+ * @brief Helper function to handle conflicting attribute keys
+ *
+ * @param[in] i_attrKeysFw - firmware key attribute
+ *
+ * @param[in] i_attrKeysAnchor - anchor key attribute
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log
+ */
+errlHndl_t nvdimm_handleConflictingKeys(
+ TARGETING::ATTR_NVDIMM_ENCRYPTION_KEYS_FW_typeStdArr& i_attrKeysFw,
+ TARGETING::ATTR_NVDIMM_ENCRYPTION_KEYS_ANCHOR_typeStdArr& i_attrKeysAnchor);
+
+
+/**
+ * @brief Helper function to validate attribute keys
+ *
+ * @param[in] i_attrData - pointer to attribute key data
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log
+ */
+errlHndl_t nvdimm_checkValidAttrKeys( nvdimmKeyData_t* i_attrData );
+
+
+/**
+ * @brief Helper function to write encryption key regs (RS/EK/AK)
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @param[in] i_keyData - data to write to the key reg
+ *
+ * @param[in] i_keyReg - enum register to write key
+ *
+ * @param[in] i_verifyReg - enum register to verify key written
+ *
+ * @param[in] i_secondAttempt - normally false, true if verif check failed
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log
+ */
+errlHndl_t nvdimm_setKeyReg(TARGETING::Target* i_nvdimm,
+ uint8_t* i_keyData,
+ uint32_t i_keyReg,
+ uint32_t i_verifyReg,
+ bool i_secondAttempt);
+
+
+/**
+ * @brief Helper function to generate randon number for encryption keys
+ * Generates ENC_KEY_SIZE bytes of data
+ * Different implementations for boot vs runtime
+ *
+ * @param[out] o_genData - pointer to generated data
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log
+ */
+errlHndl_t nvdimm_getRandom(uint8_t* o_genData);
+
+
+/**
+ * @brief Helper function to make a random number valid for keys
+ * Keys must not contain 0x00 or 0xFF
+ * - 0x00 KEY_TERMINATE_BYTE terminates a key < 32 bytes
+ * - 0xFF KEY_ABORT_BYTE aborts the key reg write process
+ * This function finds invalid bytes in the first random number
+ * and replaces with bytes from the second random number
+ *
+ * @param[out] o_genData - pointer to final generated data
+ *
+ * @param[in] i_xtraData - pointer to extra generated data
+ *
+ * @return - false if successful, true if failed
+ *
+ */
+bool nvdimm_keyifyRandomNumber(uint8_t* o_genData, uint8_t* i_xtraData);
+
+
+/**
+ * @brief Helper function to validate a random number
+ *
+ * @param[in] i_genData - pointer to generated data
+ *
+ * @return - true if valid, false if invalid
+ *
+ */
+bool nvdimm_validRandomNumber(uint8_t* i_genData);
+
+#ifndef __HOSTBOOT_RUNTIME
+
+/**
+ * @brief Helper function to get TPM pointer for random number generation
+ *
+ * @param[out] - pointer to a functional TPM or nullptr if no TPM found
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log
+ */
+errlHndl_t nvdimm_getTPM(TARGETING::Target*& o_tpm);
+
+#endif
+
} //End NVDIMM namespace
diff --git a/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C b/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C
index 267fab07c..75515a761 100644
--- a/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C
+++ b/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C
@@ -37,6 +37,7 @@
#include <targeting/common/utilFilter.H>
#include <usr/runtime/rt_targeting.H>
#include <runtime/interface.h>
+#include <arch/ppc.H>
#include <isteps/nvdimm/nvdimmreasoncodes.H>
#include <isteps/nvdimm/nvdimm.H> // implements some of these
#include "../nvdimm.H" // for g_trac_nvdimm
@@ -358,7 +359,7 @@ bool nvdimmArm(TARGETING::TargetHandleList &i_nvdimmTargetList)
// the boot. This will notify the user that action is needed
// on this module
l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
errlCommit( l_err, NVDIMM_COMP_ID );
continue;
}
@@ -375,7 +376,7 @@ bool nvdimmArm(TARGETING::TargetHandleList &i_nvdimmTargetList)
// the boot. This will notify the user that action is needed
// on this module
l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
errlCommit( l_err, NVDIMM_COMP_ID );
o_arm_successful = false;
continue;
@@ -391,7 +392,7 @@ bool nvdimmArm(TARGETING::TargetHandleList &i_nvdimmTargetList)
// the boot. This will notify the user that action is needed
// on this module
l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
errlCommit( l_err, NVDIMM_COMP_ID );
o_arm_successful = false;
continue;
@@ -405,7 +406,7 @@ bool nvdimmArm(TARGETING::TargetHandleList &i_nvdimmTargetList)
// the boot. This will notify the user that action is needed
// on this module
l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
errlCommit( l_err, NVDIMM_COMP_ID );
o_arm_successful = false;
continue;
@@ -422,7 +423,7 @@ bool nvdimmArm(TARGETING::TargetHandleList &i_nvdimmTargetList)
// the boot. This will notify the user that action is needed
// on this module
l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
errlCommit( l_err, NVDIMM_COMP_ID );
o_arm_successful = false;
@@ -433,7 +434,7 @@ bool nvdimmArm(TARGETING::TargetHandleList &i_nvdimmTargetList)
TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimmArm() nvdimm[%X], error disarming the nvdimm!",
TARGETING::get_huid(l_nvdimm));
l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
- l_err->collectTrace(NVDIMM_COMP_NAME, 1024);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
errlCommit(l_err, NVDIMM_COMP_ID);
}
@@ -446,6 +447,50 @@ bool nvdimmArm(TARGETING::TargetHandleList &i_nvdimmTargetList)
return o_arm_successful;
}
+bool nvdimmDisarm(TARGETING::TargetHandleList &i_nvdimmTargetList)
+{
+ bool o_disarm_successful = true;
+
+ TRACFCOMP(g_trac_nvdimm, ENTER_MRK"nvdimmDisarm() %d",
+ i_nvdimmTargetList.size());
+
+ errlHndl_t l_err = nullptr;
+
+ for (auto const l_nvdimm : i_nvdimmTargetList)
+ {
+ // skip if the nvdimm is in error state
+ if (NVDIMM::nvdimmInErrorState(l_nvdimm))
+ {
+ // error state means arming not successful
+ // RTC 210689 Handle return values
+ o_disarm_successful = false;
+ continue;
+ }
+
+ l_err = NVDIMM::nvdimmChangeArmState(l_nvdimm, DISARM_TRIGGER);
+ // 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_nvdimm, NVDIMM::NSTD_ERR_NOBKUP);
+ // Committing the error as we don't want this to interrupt
+ // the boot. This will notify the user that action is needed
+ // on this module
+ l_err->setSev(ERRORLOG::ERRL_SEV_PREDICTIVE);
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ errlCommit( l_err, NVDIMM_COMP_ID );
+ o_disarm_successful = false;
+ continue;
+ }
+ }
+
+ TRACFCOMP(g_trac_nvdimm, EXIT_MRK"nvdimmDisarm() returning %d",
+ o_disarm_successful);
+ return o_disarm_successful;
+}
+
/**
* @brief Check nvdimm error state
*
@@ -467,4 +512,93 @@ bool nvdimmInErrorState(TARGETING::Target *i_nvdimm)
return l_ret;
}
+
+// This could be made a generic utility
+errlHndl_t nvdimm_getDarnNumber(size_t i_genSize, uint8_t* o_genData)
+{
+ assert(i_genSize % sizeof(uint64_t) == 0,"nvdimm_getDarnNumber() bad i_genSize");
+
+ errlHndl_t l_err = nullptr;
+ uint64_t* l_darnData = reinterpret_cast<uint64_t*>(o_genData);
+
+ for (uint32_t l_loop = 0; l_loop < (i_genSize / sizeof(uint64_t)); l_loop++)
+ {
+ // Darn could return an error code
+ uint32_t l_darnErrors = 0;
+
+ while (l_darnErrors < MAX_DARN_ERRORS)
+ {
+ // Get a 64-bit random number with the darn instruction
+ l_darnData[l_loop] = getDarn();
+
+ if ( l_darnData[l_loop] != DARN_ERROR_CODE )
+ {
+ break;
+ }
+ else
+ {
+ l_darnErrors++;
+ }
+ }
+
+ if (l_darnErrors == MAX_DARN_ERRORS)
+ {
+ TRACFCOMP(g_trac_nvdimm, ERR_MRK"nvdimm_getDarnNumber() reached MAX_DARN_ERRORS");
+ /*@
+ *@errortype
+ *@reasoncode NVDIMM_ENCRYPTION_MAX_DARN_ERRORS
+ *@severity ERRORLOG_SEV_PREDICTIVE
+ *@moduleid NVDIMM_GET_DARN_NUMBER
+ *@userdata1 MAX_DARN_ERRORS
+ *@devdesc Error using darn instruction
+ *@custdesc NVDIMM encryption error
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_PREDICTIVE,
+ NVDIMM_GET_DARN_NUMBER,
+ NVDIMM_ENCRYPTION_MAX_DARN_ERRORS,
+ MAX_DARN_ERRORS,
+ ERRORLOG::ErrlEntry::NO_SW_CALLOUT );
+
+ l_err->collectTrace(NVDIMM_COMP_NAME);
+ break;
+ }
+ }
+
+ return l_err;
+}
+
+
+errlHndl_t nvdimm_getRandom(uint8_t* o_genData)
+{
+ errlHndl_t l_err = nullptr;
+ uint8_t l_xtraData[ENC_KEY_SIZE] = {0};
+
+ do
+ {
+ // Get a random number with the darn instruction
+ l_err = nvdimm_getDarnNumber(ENC_KEY_SIZE, o_genData);
+ if (l_err)
+ {
+ break;
+ }
+
+ // Validate and update the random number
+ // Retry if more randomness required
+ do
+ {
+ //Get replacement data
+ l_err = nvdimm_getDarnNumber(ENC_KEY_SIZE, l_xtraData);
+ if (l_err)
+ {
+ break;
+ }
+
+ }while (nvdimm_keyifyRandomNumber(o_genData, l_xtraData));
+
+ }while (0);
+
+ return l_err;
+}
+
} // end NVDIMM namespace
OpenPOWER on IntegriCloud