diff options
| author | Corey Swenson <cswenson@us.ibm.com> | 2019-06-25 13:39:25 -0500 |
|---|---|---|
| committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2019-07-01 09:34:42 -0500 |
| commit | ac003eb126a0ca9d57c26eb339268854b3019671 (patch) | |
| tree | 58e9d0ea0eb677a7a1aa5db1b01c7d172423ba9a /src | |
| parent | 9f597d2c7a66d1454e37f3b41c95f2b31bd2722d (diff) | |
| download | talos-hostboot-ac003eb126a0ca9d57c26eb339268854b3019671.tar.gz talos-hostboot-ac003eb126a0ca9d57c26eb339268854b3019671.zip | |
Call notifyNvdimmProtectionChange function during IPL
The function updates ATTR_NVDIMM_ARMED and
ATTR_NV_STATUS_FLAG. These need to be kept up-to-date
during IPL as well as runtime.
Change-Id: If2e8ce9bcc78fb54a0852d3d42753898c199570f
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/79472
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Matt Derksen <mderkse1@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/include/usr/isteps/nvdimm/nvdimm.H | 4 | ||||
| -rw-r--r-- | src/usr/isteps/nvdimm/nvdimm.C | 241 | ||||
| -rw-r--r-- | src/usr/isteps/nvdimm/runtime/nvdimm_rt.C | 234 |
3 files changed, 243 insertions, 236 deletions
diff --git a/src/include/usr/isteps/nvdimm/nvdimm.H b/src/include/usr/isteps/nvdimm/nvdimm.H index 9b37765f8..0bcd51bca 100644 --- a/src/include/usr/isteps/nvdimm/nvdimm.H +++ b/src/include/usr/isteps/nvdimm/nvdimm.H @@ -192,6 +192,8 @@ bool nvdimmArm(TARGETING::TargetHandleList &i_nvdimmTargetList); */ bool nvdimmDisarm(TARGETING::TargetHandleList &i_nvdimmTargetList); +#endif + /** * @brief NVDIMM protection state * @@ -227,7 +229,7 @@ enum nvdimm_protection_t */ errlHndl_t notifyNvdimmProtectionChange(TARGETING::Target* i_target, const nvdimm_protection_t i_state); -#endif + /** * @brief Entry function to NVDIMM initialization * - Checks for ready state diff --git a/src/usr/isteps/nvdimm/nvdimm.C b/src/usr/isteps/nvdimm/nvdimm.C index 0c9321f43..9482b02d3 100644 --- a/src/usr/isteps/nvdimm/nvdimm.C +++ b/src/usr/isteps/nvdimm/nvdimm.C @@ -46,6 +46,7 @@ #include <targeting/common/targetUtil.H> #ifdef __HOSTBOOT_RUNTIME #include <runtime/hbrt_utilities.H> +#include <usr/runtime/rt_targeting.H> #endif using namespace TARGETING; @@ -105,9 +106,17 @@ typedef union { } PACKED; } encryption_config_status_t; -// Valid bits to check against (skips reserved and unsupported) +// Valid bits to check against (skips reserved and unsupported) static constexpr uint8_t ENCRYPTION_STATUS_CHECK_MASK = 0x3F; +// NV_STATUS masks +static constexpr uint8_t NV_STATUS_OR_MASK = 0xFB; +static constexpr uint8_t NV_STATUS_AND_MASK = 0x04; +static constexpr uint8_t NV_STATUS_UNPROTECTED_SET = 0x01; +static constexpr uint8_t NV_STATUS_UNPROTECTED_CLEAR = 0xFE; +static constexpr uint8_t NV_STATUS_POSSIBLY_UNPROTECTED_SET = 0x40; +static constexpr uint8_t NV_STATUS_POSSIBLY_UNPROTECTED_CLEAR = 0xBF; + // Definition of ENCRYPTION_KEY_VALIDATION -- page 5 offset 0x2A typedef union { uint8_t whole; @@ -2746,4 +2755,234 @@ bool nvdimm_crypto_erase(TargetHandleList &i_nvdimmList) } +errlHndl_t notifyNvdimmProtectionChange(Target* i_target, + const nvdimm_protection_t i_state) +{ + TRACFCOMP( g_trac_nvdimm, ENTER_MRK + "notifyNvdimmProtectionChange: Target huid 0x%.8X, state %d", + get_huid(i_target), i_state); + + errlHndl_t l_err = nullptr; + + do + { + // Get the type of target passed in + // It could be proc_type for OCC state + // Or dimm_type for ARM/ERROR state + ATTR_TYPE_type l_type = i_target->getAttr<ATTR_TYPE>(); + assert((l_type == TYPE_PROC)||(l_type == TYPE_DIMM), + "notifyNvdimmProtectionChange invalid target type"); + + // Load the nvdimm list + TargetHandleList l_nvdimmTargetList; + Target* l_proc = nullptr; + if (l_type == TYPE_PROC) + { + // Get the nvdimms under this proc target + l_nvdimmTargetList = getProcNVDIMMs(i_target); + + // Only send command if the processor has an NVDIMM under it + if (l_nvdimmTargetList.empty()) + { + TRACFCOMP( g_trac_nvdimm, "notifyNvdimmProtectionChange: " + "No NVDIMM found under processor 0x%.8X", + get_huid(i_target)); + break; + } + + // The proc target is the passed-in target + l_proc = i_target; + } + else + { + // Only a list of one but keep consistent with proc type + l_nvdimmTargetList.push_back(i_target); + + // Find the proc target from nvdimm target passed in + TargetHandleList l_procList; + getParentAffinityTargets(l_procList, + i_target, + CLASS_CHIP, + TYPE_PROC, + UTIL_FILTER_ALL); + assert(l_procList.size() == 1, "notifyNvdimmProtectionChange:" + "getParentAffinityTargets size != 1"); + l_proc = l_procList[0]; + } + + + // Update the nvdimm status attributes + for (auto const l_nvdimm : l_nvdimmTargetList) + { + // Get the armed status attr and update it + ATTR_NVDIMM_ARMED_type l_armed_state = {}; + l_armed_state = l_nvdimm->getAttr<ATTR_NVDIMM_ARMED>(); + + switch (i_state) + { + case NVDIMM_ARMED: + l_armed_state.armed = 1; + break; + case NVDIMM_DISARMED: + l_armed_state.armed = 0; + break; + case OCC_ACTIVE: + l_armed_state.occ_active = 1; + break; + case OCC_INACTIVE: + l_armed_state.occ_active = 0; + break; + case NVDIMM_FATAL_HW_ERROR: + l_armed_state.fatal_error_detected = 1; + break; + case NVDIMM_RISKY_HW_ERROR: + l_armed_state.risky_error_detected = 1; + break; + } + + l_nvdimm->setAttr<ATTR_NVDIMM_ARMED>(l_armed_state); + + + // Get the nv status flag attr and update it + ATTR_NV_STATUS_FLAG_type l_nv_status = + l_nvdimm->getAttr<ATTR_NV_STATUS_FLAG>(); + + // Clear bit 0 if protected nv state + if (l_armed_state.armed && + l_armed_state.occ_active && + !l_armed_state.fatal_error_detected) + { + l_nv_status &= NV_STATUS_UNPROTECTED_CLEAR; + } + + // Set bit 0 if unprotected nv state + else + { + l_nv_status |= NV_STATUS_UNPROTECTED_SET; + } + + // Set bit 6 if risky error + if (l_armed_state.risky_error_detected) + { + l_nv_status |= NV_STATUS_POSSIBLY_UNPROTECTED_SET; + } + + l_nvdimm->setAttr<ATTR_NV_STATUS_FLAG>(l_nv_status); + + } // for nvdimm list + + // Generate combined nvdimm status for the proc + // Bit 2 of NV_STATUS_FLAG is 'Device contents are persisted' + // and must be ANDed for all nvdimms + // the rest of the bits are ORed for all nvdimms + ATTR_NV_STATUS_FLAG_type l_combined_or = 0x00; + ATTR_NV_STATUS_FLAG_type l_combined_and = 0xFF; + ATTR_NV_STATUS_FLAG_type l_combined_status = 0x00; + l_nvdimmTargetList = getProcNVDIMMs(l_proc); + for (auto const l_nvdimm : l_nvdimmTargetList) + { + l_combined_or |= l_nvdimm->getAttr<ATTR_NV_STATUS_FLAG>(); + l_combined_and &= l_nvdimm->getAttr<ATTR_NV_STATUS_FLAG>(); + } + + // Bit 2 of NV_STATUS_FLAG is 'Device contents are persisted' + l_combined_status = + (l_combined_or & NV_STATUS_OR_MASK) | + (l_combined_and & NV_STATUS_AND_MASK); + + TRACFCOMP( g_trac_nvdimm, + "notifyNvdimmProtectionChange: NV_STATUS for proc %X 0x%.02X", + get_huid(l_proc), l_combined_status); + +#ifdef __HOSTBOOT_RUNTIME + + // Send combined status to phyp + // Get the Proc Chip Id + RT_TARG::rtChipId_t l_chipId = 0; + + l_err = RT_TARG::getRtTarget(l_proc, l_chipId); + if(l_err) + { + TRACFCOMP( g_trac_nvdimm, + ERR_MRK"notifyNvdimmProtectionChange: getRtTarget ERROR" ); + break; + } + + // send the notification msg + if ((nullptr == g_hostInterfaces) || + (nullptr == g_hostInterfaces->firmware_request)) + { + TRACFCOMP( g_trac_nvdimm, ERR_MRK"notifyNvdimmProtectionChange: " + "Hypervisor firmware_request interface not linked"); + + /*@ + * @errortype + * @severity ERRL_SEV_PREDICTIVE + * @moduleid NOTIFY_NVDIMM_PROTECTION_CHG + * @reasoncode NVDIMM_NULL_FIRMWARE_REQUEST_PTR + * @userdata1 HUID of processor target + * @userdata2[0:31] NV_STATUS to PHYP + * @userdata2[32:63] In state change + * @devdesc Unable to inform PHYP of NVDIMM protection + * @custdesc Internal firmware error + */ + l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE, + NOTIFY_NVDIMM_PROTECTION_CHG, + NVDIMM_NULL_FIRMWARE_REQUEST_PTR, + get_huid(l_proc), + TWO_UINT32_TO_UINT64( + l_combined_status, + i_state) + ); + + l_err->addProcedureCallout(HWAS::EPUB_PRC_PHYP_CODE, + HWAS::SRCI_PRIORITY_HIGH); + + break; + } + + TRACFCOMP( g_trac_nvdimm, + "notifyNvdimmProtectionChange: 0x%.8X " + "NV_STATUS to PHYP: 0x%02X", + get_huid(l_proc), + l_combined_status ); + + // Create the firmware_request request struct to send data + hostInterfaces::hbrt_fw_msg l_req_fw_msg; + memset(&l_req_fw_msg, 0, sizeof(l_req_fw_msg)); // clear it all + + // actual msg size (one type of hbrt_fw_msg) + uint64_t l_req_fw_msg_size = hostInterfaces::HBRT_FW_MSG_BASE_SIZE + + sizeof(l_req_fw_msg.nvdimm_protection_state); + + // Populate the firmware_request request struct with given data + l_req_fw_msg.io_type = + hostInterfaces::HBRT_FW_MSG_TYPE_NVDIMM_PROTECTION; + l_req_fw_msg.nvdimm_protection_state.i_procId = l_chipId; + l_req_fw_msg.nvdimm_protection_state.i_state = l_combined_status; + + // Create the firmware_request response struct to receive data + hostInterfaces::hbrt_fw_msg l_resp_fw_msg; + uint64_t l_resp_fw_msg_size = sizeof(l_resp_fw_msg); + memset(&l_resp_fw_msg, 0, l_resp_fw_msg_size); + + // Make the firmware_request call + l_err = firmware_request_helper(l_req_fw_msg_size, + &l_req_fw_msg, + &l_resp_fw_msg_size, + &l_resp_fw_msg); + +#endif + + } while (0); + + TRACFCOMP( g_trac_nvdimm, + EXIT_MRK "notifyNvdimmProtectionChange(%.8X, %d) - ERRL %.8X:%.4X", + get_huid(i_target), i_state, + ERRL_GETEID_SAFE(l_err), ERRL_GETRC_SAFE(l_err) ); + + return l_err; +} + + } // end NVDIMM namespace diff --git a/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C b/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C index 7ef798a99..78aab4712 100644 --- a/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C +++ b/src/usr/isteps/nvdimm/runtime/nvdimm_rt.C @@ -50,240 +50,6 @@ using namespace TARGETING; namespace NVDIMM { -const uint8_t NV_STATUS_UNPROTECTED_SET = 0x01; -const uint8_t NV_STATUS_UNPROTECTED_CLEAR = 0xFE; -const uint8_t NV_STATUS_POSSIBLY_UNPROTECTED_SET = 0x40; -const uint8_t NV_STATUS_POSSIBLY_UNPROTECTED_CLEAR = 0xBF; - -const uint8_t NV_STATUS_OR_MASK = 0xFB; -const uint8_t NV_STATUS_AND_MASK = 0x04; - -/** -* @brief Notify PHYP of NVDIMM OCC protection status -*/ -errlHndl_t notifyNvdimmProtectionChange(Target* i_target, - const nvdimm_protection_t i_state) -{ - TRACFCOMP( g_trac_nvdimm, ENTER_MRK - "notifyNvdimmProtectionChange: Target huid 0x%.8X, state %d", - get_huid(i_target), i_state); - - errlHndl_t l_err = nullptr; - - do - { - // Get the type of target passed in - // It could be proc_type for OCC state - // Or dimm_type for ARM/ERROR state - ATTR_TYPE_type l_type = i_target->getAttr<ATTR_TYPE>(); - assert((l_type == TYPE_PROC)||(l_type == TYPE_DIMM), - "notifyNvdimmProtectionChange invalid target type"); - - // Load the nvdimm list - TargetHandleList l_nvdimmTargetList; - Target* l_proc = nullptr; - if (l_type == TYPE_PROC) - { - // Get the nvdimms under this proc target - l_nvdimmTargetList = getProcNVDIMMs(i_target); - - // Only send command if the processor has an NVDIMM under it - if (l_nvdimmTargetList.empty()) - { - TRACFCOMP( g_trac_nvdimm, "notifyNvdimmProtectionChange: " - "No NVDIMM found under processor 0x%.8X", - get_huid(i_target)); - break; - } - - // The proc target is the passed-in target - l_proc = i_target; - } - else - { - // Only a list of one but keep consistent with proc type - l_nvdimmTargetList.push_back(i_target); - - // Find the proc target from nvdimm target passed in - TargetHandleList l_procList; - getParentAffinityTargets(l_procList, - i_target, - CLASS_CHIP, - TYPE_PROC, - UTIL_FILTER_ALL); - assert(l_procList.size() == 1, "notifyNvdimmProtectionChange:" - "getParentAffinityTargets size != 1"); - l_proc = l_procList[0]; - } - - - // Update the nvdimm status attributes - for (auto const l_nvdimm : l_nvdimmTargetList) - { - // Get the armed status attr and update it - ATTR_NVDIMM_ARMED_type l_armed_state = {}; - l_armed_state = l_nvdimm->getAttr<ATTR_NVDIMM_ARMED>(); - - switch (i_state) - { - case NVDIMM_ARMED: - l_armed_state.armed = 1; - break; - case NVDIMM_DISARMED: - l_armed_state.armed = 0; - break; - case OCC_ACTIVE: - l_armed_state.occ_active = 1; - break; - case OCC_INACTIVE: - l_armed_state.occ_active = 0; - break; - case NVDIMM_FATAL_HW_ERROR: - l_armed_state.fatal_error_detected = 1; - break; - case NVDIMM_RISKY_HW_ERROR: - l_armed_state.risky_error_detected = 1; - break; - } - - l_nvdimm->setAttr<ATTR_NVDIMM_ARMED>(l_armed_state); - - - // Get the nv status flag attr and update it - ATTR_NV_STATUS_FLAG_type l_nv_status = - l_nvdimm->getAttr<ATTR_NV_STATUS_FLAG>(); - - // Clear bit 0 if protected nv state - if (l_armed_state.armed && - l_armed_state.occ_active && - !l_armed_state.fatal_error_detected) - { - l_nv_status &= NV_STATUS_UNPROTECTED_CLEAR; - } - - // Set bit 0 if unprotected nv state - else - { - l_nv_status |= NV_STATUS_UNPROTECTED_SET; - } - - // Set bit 6 if risky error - if (l_armed_state.risky_error_detected) - { - l_nv_status |= NV_STATUS_POSSIBLY_UNPROTECTED_SET; - } - - l_nvdimm->setAttr<ATTR_NV_STATUS_FLAG>(l_nv_status); - - } // for nvdimm list - - - // Generate combined nvdimm status for the proc - // Bit 2 of NV_STATUS_FLAG is 'Device contents are persisted' - // and must be ANDed for all nvdimms - // the rest of the bits are ORed for all nvdimms - ATTR_NV_STATUS_FLAG_type l_combined_or = 0x00; - ATTR_NV_STATUS_FLAG_type l_combined_and = 0xFF; - ATTR_NV_STATUS_FLAG_type l_combined_status = 0x00; - l_nvdimmTargetList = getProcNVDIMMs(l_proc); - for (auto const l_nvdimm : l_nvdimmTargetList) - { - l_combined_or |= l_nvdimm->getAttr<ATTR_NV_STATUS_FLAG>(); - l_combined_and &= l_nvdimm->getAttr<ATTR_NV_STATUS_FLAG>(); - } - - // Bit 2 of NV_STATUS_FLAG is 'Device contents are persisted' - l_combined_status = - (l_combined_or & NV_STATUS_OR_MASK) | - (l_combined_and & NV_STATUS_AND_MASK); - - - // Send combined status to phyp - // Get the Proc Chip Id - RT_TARG::rtChipId_t l_chipId = 0; - - l_err = RT_TARG::getRtTarget(l_proc, l_chipId); - if(l_err) - { - TRACFCOMP( g_trac_nvdimm, - ERR_MRK"notifyNvdimmProtectionChange: getRtTarget ERROR" ); - break; - } - - // send the notification msg - if ((nullptr == g_hostInterfaces) || - (nullptr == g_hostInterfaces->firmware_request)) - { - TRACFCOMP( g_trac_nvdimm, ERR_MRK"notifyNvdimmProtectionChange: " - "Hypervisor firmware_request interface not linked"); - - /*@ - * @errortype - * @severity ERRL_SEV_PREDICTIVE - * @moduleid NOTIFY_NVDIMM_PROTECTION_CHG - * @reasoncode NVDIMM_NULL_FIRMWARE_REQUEST_PTR - * @userdata1 HUID of processor target - * @userdata2[0:31] NV_STATUS to PHYP - * @userdata2[32:63] In state change - * @devdesc Unable to inform PHYP of NVDIMM protection - * @custdesc Internal firmware error - */ - l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_PREDICTIVE, - NOTIFY_NVDIMM_PROTECTION_CHG, - NVDIMM_NULL_FIRMWARE_REQUEST_PTR, - get_huid(l_proc), - TWO_UINT32_TO_UINT64( - l_combined_status, - i_state) - ); - - l_err->addProcedureCallout(HWAS::EPUB_PRC_PHYP_CODE, - HWAS::SRCI_PRIORITY_HIGH); - - break; - } - - TRACFCOMP( g_trac_nvdimm, - "notifyNvdimmProtectionChange: 0x%.8X " - "NV_STATUS to PHYP: 0x%02X", - get_huid(l_proc), - l_combined_status ); - - // Create the firmware_request request struct to send data - hostInterfaces::hbrt_fw_msg l_req_fw_msg; - memset(&l_req_fw_msg, 0, sizeof(l_req_fw_msg)); // clear it all - - // actual msg size (one type of hbrt_fw_msg) - uint64_t l_req_fw_msg_size = hostInterfaces::HBRT_FW_MSG_BASE_SIZE + - sizeof(l_req_fw_msg.nvdimm_protection_state); - - // Populate the firmware_request request struct with given data - l_req_fw_msg.io_type = - hostInterfaces::HBRT_FW_MSG_TYPE_NVDIMM_PROTECTION; - l_req_fw_msg.nvdimm_protection_state.i_procId = l_chipId; - l_req_fw_msg.nvdimm_protection_state.i_state = l_combined_status; - - // Create the firmware_request response struct to receive data - hostInterfaces::hbrt_fw_msg l_resp_fw_msg; - uint64_t l_resp_fw_msg_size = sizeof(l_resp_fw_msg); - memset(&l_resp_fw_msg, 0, l_resp_fw_msg_size); - - // Make the firmware_request call - l_err = firmware_request_helper(l_req_fw_msg_size, - &l_req_fw_msg, - &l_resp_fw_msg_size, - &l_resp_fw_msg); - - } while (0); - - TRACFCOMP( g_trac_nvdimm, - EXIT_MRK "notifyNvdimmProtectionChange(%.8X, %d) - ERRL %.8X:%.4X", - get_huid(i_target), i_state, - ERRL_GETEID_SAFE(l_err), ERRL_GETRC_SAFE(l_err) ); - - return l_err; -} - /** * @brief This function polls the command status register for arm completion * (does not indicate success or fail) |

