summaryrefslogtreecommitdiffstats
path: root/src/usr/isteps/nvdimm/nvdimm.H
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/isteps/nvdimm/nvdimm.H')
-rw-r--r--src/usr/isteps/nvdimm/nvdimm.H344
1 files changed, 340 insertions, 4 deletions
diff --git a/src/usr/isteps/nvdimm/nvdimm.H b/src/usr/isteps/nvdimm/nvdimm.H
index 4d97a9c66..e66e42470 100644
--- a/src/usr/isteps/nvdimm/nvdimm.H
+++ b/src/usr/isteps/nvdimm/nvdimm.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2019 */
+/* Contributors Listed Below - COPYRIGHT 2014,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -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>
@@ -40,6 +41,12 @@ extern trace_desc_t* g_trac_nvdimm;
namespace NVDIMM
{
+#define NVDIMM_SET_USER_DATA_1(left_32_ops_id, right_32_huid) \
+ TWO_UINT32_TO_UINT64(left_32_ops_id, right_32_huid)
+
+#define NVDIMM_SET_USER_DATA_2_TIMEOUT(left_32_polled, right_32_timeout) \
+ NVDIMM_SET_USER_DATA_1(left_32_polled, right_32_timeout)
+
// I2C registers for page 0-3, extracted from JEDEC BAEBI spec
// Refer to BAEBI spec for details
@@ -121,11 +128,13 @@ enum i2cReg : uint16_t
SET_ES_POLICY_STATUS = 0x070,
FIRMWARE_OPS_STATUS = 0x071,
OPERATIONAL_UNIT_OPS_STATUS = 0x072,
- RESTORE_FAIL_INFO = 0x088,
- OPERATIONAL_UNIT_FAIL_INFO = 0x08F,
+ ERASE_FAIL_INFO = 0x073,
+ ARM_FAIL_INFO = 0x076,
CSAVE_INFO = 0x080,
CSAVE_FAIL_INFO0 = 0x084,
CSAVE_FAIL_INFO1 = 0x085,
+ RESTORE_FAIL_INFO = 0x088,
+ OPERATIONAL_UNIT_FAIL_INFO = 0x08F,
NVM_LIFETIME_ERROR_THRESHOLD = 0x090,
ES_LIFETIME_ERROR_THRESHOLD = 0x091,
ES_TEMP_ERROR_HIGH_THRESHOLD0 = 0x094,
@@ -274,6 +283,45 @@ enum i2cReg : uint16_t
TYPED_BLOCK_DATA_BYTE30 = 0x39E,
TYPED_BLOCK_DATA_BYTE31 = 0x39F,
TYPED_BLOCK_DATA_OFFSET = 0x3E0,
+ PANIC_CNT = 0x406,
+ STATUS_EVENT_INT_INFO1 = 0x40A,
+ STATUS_EVENT_INT_INFO2 = 0x40B,
+ FLASH_BAD_BLK_PCT = 0x41D, // Read only; Percentage of flash blocks
+ // in the flash array marked as bad blocks
+ PARITY_ERROR_COUNT = 0x423,
+ FLASH_ERROR_COUNT0 = 0x428, // Read only; LSB[7:0] Flash error count
+ FLASH_ERROR_COUNT1 = 0x429, // Read only; [15:8]
+ FLASH_ERROR_COUNT2 = 0x42A, // Read only; MSB[23:16]
+ FLASH_BAD_BLOCK_COUNT0 = 0x42B,
+ FLASH_BAD_BLOCK_COUNT1 = 0x42C,
+ BPM_MAGIC_REG1 = 0x430,
+ BPM_MAGIC_REG2 = 0x431,
+ SCAP_STATUS = 0x432,
+ SCAP_REG = 0x434,
+ SCAP_DATA = 0x435,
+ I2C_REG_PROTECT = 0x43D,
+ BPM_REG_CMD = 0x440,
+ BPM_CMD_STATUS = 0x441,
+ BPM_PAYLOAD_LENGTH = 0x442,
+ BPM_REG_ERR_STATUS = 0x443,
+ BPM_REG_PAYLOAD_START = 0x444,
+ 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,
};
// i2cReg macros
@@ -292,6 +340,7 @@ enum page : uint8_t
TWO = 0x02,
THREE = 0x03,
FOUR = 0x04,
+ FIVE = 0x05,
};
// Enums for inputs/expected output to/from the i2c registers
@@ -306,6 +355,7 @@ enum i2c_in_values : uint8_t
RESET_CTRLR = 0x01,
VALID_IMAGE = 0x01,
RESET_CONTROLLER = 0x01,
+ FACTORY_DEFAULT = 0x01,
};
enum i2c_out_values : uint8_t
@@ -317,11 +367,20 @@ enum i2c_out_values : uint8_t
CHARGE_IN_PROGRESS = 0x01,
SAVE_SUCCESS = 0x01,
RSTR_SUCCESS = 0X01,
- ARM_SUCCESS = 0X09,
+ ARM_SUCCESS = 0X01,
ERASE_SUCCESS = 0X01,
ES_SUCCESS = 0x05,
CHARGE_SUCCESS = 0x00,
NV_READY = 0xA5,
+ FACTORY_RESET_IN_PROGRESS = 0x03,
+ NO_RESET_N = 0x20,
+ RESET_N_ARMED = 0x08,
+ ES_POLICY_ERROR = 0x02,
+ ARM_ERROR = 0X02,
+ RSTR_ERROR = 0x02,
+ SAVE_ERROR = 0x02,
+ ERASE_ERROR = 0x02,
+ CLEAR_ALL_STATUS = 0x3C, //Clears CAVE, RESTORE, ERASE, and ARM status regs
};
// Timeout-related enum
@@ -330,6 +389,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
@@ -354,6 +414,119 @@ enum misc
};
/**
+ * @brief Encryption key data
+ */
+static constexpr size_t ENC_KEY_SIZE = 32;
+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)
+};
+
+struct scap_status_bits
+{
+ uint8_t Reserved1 : 1; // Bit 7
+ uint8_t Bpm_Bsl_Mode : 1; // Bit 6
+ uint8_t Reserved2 : 1; // Bit 5
+ uint8_t Present : 1; // Bit 4
+ uint8_t Delay : 1; // Bit 3
+ uint8_t Error : 1; // Bit 2
+ uint8_t Busy : 1; // Bit 1
+ uint8_t Enable : 1; // Bit 0
+} PACKED;
+
+/**
+ * @brief Union simplifying manipulation of SCAP_STATUS bits
+ */
+union scap_status_union
+{
+ uint8_t full;
+ scap_status_bits bit;
+
+ /**
+ * @brief Constructor
+ */
+ scap_status_union()
+ : full(0)
+ {}
+} PACKED;
+
+typedef scap_status_union scap_status_register_t;
+
+// Bits in Health Status Check Registers
+enum health_status : uint8_t
+{
+ // Module Health Status0
+ VOLTAGE_REGULATOR_FAILED = 0x01,
+ VDD_LOST = 0x02,
+ VPP_LOST = 0x04,
+ VTT_LOST = 0x08,
+ DRAM_NOT_SELF_REFRESH = 0x10,
+ CONTROLLER_HARDWARE_ERROR = 0x20,
+ NVM_CONTROLLER_ERROR = 0x40,
+ NVM_LIFETIME_ERROR = 0x80,
+ // Module Health Status1
+ NOT_ENOUGH_ENERGY_FOR_CSAVE = 0x01,
+ INVALID_FIRMWARE_ERROR = 0x02,
+ CONFIG_DATA_ERROR = 0x04,
+ NO_ES_PRESENT = 0x08,
+ ES_POLICY_NOT_SET = 0x10,
+ ES_HARDWARE_FAILURE = 0x20,
+ ES_HEALTH_ASSESSMENT_ERROR = 0x40,
+ // Error Threshold Status
+ ES_LIFETIME_ERROR = 0x02,
+ ES_TEMP_ERROR = 0x04,
+};
+
+// Int representation for health status function call
+enum health_function : uint8_t
+{
+ HEALTH_SAVE = 0x01,
+ HEALTH_RESTORE = 0x02,
+ HEALTH_UPDATE = 0x03,
+ HEALTH_PRE_ARM = 0x04,
+ HEALTH_POST_ARM = 0x05,
+};
+
+// Event notification register values
+enum event_n : uint8_t
+{
+ PERSISTENCY_NOTIFICATION = 0x01,
+ SET_EVENT_NOTIFICATION_ERROR = 0x02,
+ WARNING_THRESHOLD_NOTIFICATION = 0x02,
+ PERSISTENCY_ENABLED = 0x04,
+ WARNING_THRESHOLD_ENABLED = 0x08,
+ ENABLE_NOTIFICATIONS = 0x03,
+ NOTIFICATIONS_ENABLED = 0x0C,
+};
+
+// MBACALFIR register addresses
+enum mbacal_addresses : uint32_t
+{
+ MBACALFIR_AND_MASK_REG = 0x07010904,
+ MBACALFIR_OR_MASK_REG = 0x07010905,
+ MBACALFIR_ACTION0_REG = 0x07010906,
+ MBACALFIR_ACTION1_REG = 0x07010907,
+};
+
+// MBACALFIR bit masks for event n
+enum mbacal_bitmask_values : uint64_t
+{
+ MBACALFIR_EVENTN_AND_BIT = 0xff7fffffffffffff,
+ MBACALFIR_EVENTN_OR_BIT = 0x0080000000000000,
+ MBACALFIR_UNMASK_BIT = 0xff7fffffffffffff,
+};
+
+
+/**
+ * @brief Mask MCBACALFIR Event N to prevent PRD from handling event
+ *
+ * @param[in] - i_nvdimm - nvdimm target for operation on its parent MCA
+ */
+void maskMbacalfir_eventn(TARGETING::Target* i_nvdimm);
+
+/**
* @brief Wrapper to call deviceOp to read the NV controller via I2C
*
* @param[in] i_nvdimm - nvdimm target with NV controller
@@ -434,6 +607,169 @@ 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);
+
+
+/**
+ * @brief Helper function to set encryption error
+ * in ATTR_NVDIMM_ARMED
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ */
+void nvdimmSetEncryptionError(TARGETING::Target *i_nvdimm);
+
+
+/**
+ * @brief Helper function to reset the NVDIMM controller
+ *
+ * @param[in] i_nvdimm - nvdimm target
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log
+ */
+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
+
+/**
+ * @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
+
+/**
+ * @brief This function checks for valid image on the given target
+ *
+ * @param[in] i_nvdimm - nvdimm target with NV controller
+ *
+ * @param[out] o_imgValid - return true if the target has a valid image
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t nvdimmValidImage(TARGETING::Target *i_nvdimm, bool &o_imgValid);
+
+
+/**
+ * @brief This function grabs the current slot NVDIMM code is running
+ * Slot 0 is the failure slot, Slot 1 is the updateable slot
+ *
+ * @param[in] i_nvdimm - nvdimm target with NV controller
+ * @param[out] o_slot - 0 or 1
+ *
+ * @return errlHndl_t - Null if successful, otherwise a pointer to
+ * the error log.
+ */
+errlHndl_t nvdimmGetRunningSlot(TARGETING::Target *i_nvdimm, uint8_t & o_slot);
+
} //End NVDIMM namespace
OpenPOWER on IntegriCloud