diff options
author | Mark Pizzutillo <Mark.Pizzutillo@ibm.com> | 2019-09-16 17:08:27 -0400 |
---|---|---|
committer | Daniel M Crowell <dcrowell@us.ibm.com> | 2019-10-17 15:27:03 -0500 |
commit | 8f549e7548fb45819fc4fd8637448f428f14eec1 (patch) | |
tree | 0bd9d8d0361ba7e511794ff4b6e1ea75f2b0ccde /src/import/chips/ocmb/explorer/procedures | |
parent | 70b54e6ae12665ccc0070e896039faadd52333f7 (diff) | |
download | talos-hostboot-8f549e7548fb45819fc4fd8637448f428f14eec1.tar.gz talos-hostboot-8f549e7548fb45819fc4fd8637448f428f14eec1.zip |
Add code and workarounds for *_omi_setup and *_omi_train for Swift
Change-Id: I139357a553e621b25b46bee6303357c712b67be2
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/83848
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Dev-Ready: Steven B Janssen <janssens@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com>
Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com>
Reviewed-by: Christian R Geddes <crgeddes@us.ibm.com>
Reviewed-by: Louis Stermole <stermole@us.ibm.com>
Reviewed-by: Jennifer A Stofer <stofer@us.ibm.com>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/83905
Reviewed-by: Daniel M Crowell <dcrowell@us.ibm.com>
Tested-by: Daniel M Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/ocmb/explorer/procedures')
12 files changed, 431 insertions, 93 deletions
diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_setup.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_setup.C index 0581cb8cf..2eb53635e 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_setup.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_setup.C @@ -34,6 +34,7 @@ // *HWP Consumed by: Memory #include <fapi2.H> +#include <exp_omi_setup.H> #include <generic/memory/lib/utils/c_str.H> #include <lib/exp_attribute_accessors_manual.H> #include <lib/omi/exp_omi_utils.H> @@ -42,6 +43,7 @@ #include <generic/memory/mss_git_data_helper.H> #include <generic/memory/lib/mss_generic_attribute_getters.H> #include <generic/memory/lib/mss_generic_system_attribute_getters.H> +#include <generic/memory/lib/utils/shared/mss_generic_consts.H> extern "C" { @@ -54,17 +56,14 @@ extern "C" fapi2::ReturnCode exp_omi_setup( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) { mss::display_git_commit_info("exp_omi_setup"); + uint8_t l_gem_menterp_workaround = 0; // Declares variables - fapi2::buffer<uint64_t> l_data; - fapi2::buffer<uint64_t> dlx_config1_data; - uint8_t l_edpl_disable = 0; - bool l_is_enterprise = false; - bool l_is_half_dimm = false; - bool l_workaround_required = false; std::vector<uint8_t> l_boot_config_data; + + // BOOT CONFIG 0 uint8_t l_dl_layer_boot_mode = fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_DL_LAYER_BOOT_MODE_NON_DL_TRAINING; - uint8_t l_gem_menterp_workaround = 0; + // Gets the data setup FAPI_TRY(mss::exp::omi::train::setup_fw_boot_config(i_target, l_boot_config_data)); @@ -75,12 +74,27 @@ extern "C" // Note: This does not kick off OMI training FAPI_TRY(mss::exp::i2c::boot_config(i_target, l_boot_config_data)); + // Check FW status for success + FAPI_TRY(mss::exp::i2c::fw_status(i_target, mss::DELAY_1MS, 100)); + FAPI_TRY(mss::exp::workarounds::omi::gem_menterp(i_target, l_gem_menterp_workaround)); - // If no workaround, we can perform menterp reads/writes (explorer) - // If workaround (gem). we need to bypass menterp. Can also bypass dlx_config1 since it's a noop - if (!l_gem_menterp_workaround) + // If no workaround (explorer), we can perform menterp reads/writes + // If workaround (gemini). we need to bypass menterp. Can also bypass dlx_config1 too since it's a noop + if (l_gem_menterp_workaround) + { + return fapi2::FAPI2_RC_SUCCESS; + } + + // Set up DLX_CONFIG1 { + fapi2::buffer<uint64_t> l_data; + fapi2::buffer<uint64_t> l_dlx_config1_data; + + uint8_t l_edpl_disable = 0; + bool l_is_enterprise = false; + bool l_is_half_dimm = false; + // Gets the configuration information from attributes FAPI_TRY(mss::enterprise_mode(i_target, l_is_enterprise)); FAPI_TRY(mss::half_dimm_mode(i_target, l_is_half_dimm)); @@ -102,24 +116,15 @@ extern "C" FAPI_TRY(mss::exp::omi::check_enterprise_mode(i_target, l_is_enterprise, l_data)); // Set the EDPL according the attribute - FAPI_TRY(mss::exp::omi::read_dlx_config1(i_target, dlx_config1_data)); - mss::exp::omi::set_edpl_enable_bit(dlx_config1_data, l_edpl_disable); - FAPI_TRY(mss::exp::omi::write_dlx_config1(i_target, dlx_config1_data)); + FAPI_TRY(mss::exp::omi::read_dlx_config1(i_target, l_dlx_config1_data)); + mss::exp::omi::set_edpl_enable_bit(l_dlx_config1_data, !l_edpl_disable); + FAPI_TRY(mss::exp::omi::write_dlx_config1(i_target, l_dlx_config1_data)); FAPI_INF("%s EDPL enable: %s", mss::c_str(i_target), l_edpl_disable ? "false" : "true"); } - // Run the workaround if it's needed - FAPI_TRY(mss::exp::workarounds::omi::is_prbs_ocmb_required(i_target, l_workaround_required)); - - if (l_workaround_required) - { - uint8_t l_dl_x4_backoff_en = 0; - - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE, i_target, l_dl_x4_backoff_en), - "Error getting ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE"); - - FAPI_TRY(mss::exp::workarounds::omi::prbs_ocmb(i_target, l_dl_x4_backoff_en)); - } + // Perform p9a workaround + // Train mode 6 (state 3) + FAPI_TRY(mss::exp::workarounds::omi::pre_training_prbs(i_target)); fapi_try_exit: return fapi2::current_err; diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train.C index 81b2a601a..0e21e87ef 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train.C @@ -37,8 +37,12 @@ #include <generic/memory/lib/utils/c_str.H> #include <lib/omi/exp_omi_utils.H> #include <lib/i2c/exp_i2c.H> +#include <lib/exp_attribute_accessors_manual.H> +#include <lib/workarounds/exp_omi_workarounds.H> #include <exp_omi_train.H> #include <generic/memory/mss_git_data_helper.H> +#include <generic/memory/lib/mss_generic_attribute_getters.H> +#include <generic/memory/lib/utils/shared/mss_generic_consts.H> extern "C" { @@ -52,18 +56,41 @@ extern "C" { mss::display_git_commit_info("exp_omi_train"); - std::vector<uint8_t> l_data; - uint8_t l_dl_layer_boot_mode = fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_DL_LAYER_BOOT_MODE_ONLY_DL_TRAINING; + // Perform p9a workaround + // Train mode 1 (PATTERN_A) + FAPI_TRY(mss::exp::workarounds::omi::training_prbs(i_target)); - // Gets the data setup - FAPI_TRY(mss::exp::omi::train::setup_fw_boot_config(i_target, l_data)); + // BOOT CONFIG 1 + { + bool l_ocmb_is_explorer = false; - // Sets DL_TRAIN field - FAPI_TRY(mss::exp::i2c::boot_cfg::set_dl_layer_boot_mode( i_target, l_data, l_dl_layer_boot_mode )); + std::vector<uint8_t> l_data; + uint8_t l_dl_layer_boot_mode = fapi2::ENUM_ATTR_MSS_OCMB_EXP_BOOT_CONFIG_DL_LAYER_BOOT_MODE_ONLY_DL_TRAINING; - // Issues the command and checks for completion - // Note: the status check also checks for the OMI training completion, so after we run this command, we're good to go - FAPI_TRY(mss::exp::i2c::boot_config(i_target, l_data)); + // Gets the data setup + FAPI_TRY(mss::exp::omi::train::setup_fw_boot_config(i_target, l_data)); + + // Sets DL_TRAIN field + FAPI_TRY(mss::exp::i2c::boot_cfg::set_dl_layer_boot_mode( i_target, l_data, l_dl_layer_boot_mode )); + + // Issues the command and checks for completion + FAPI_TRY(mss::exp::i2c::boot_config(i_target, l_data)); + + // Check for expected busy status (this won't work for gemini) + FAPI_TRY(mss::exp::workarounds::omi::ocmb_is_explorer(i_target, l_ocmb_is_explorer)); + + if (l_ocmb_is_explorer) + { + // Explorer & P9A environment should see a busy status until auto train is kicked off from both sides + FAPI_TRY(mss::exp::i2c::check_fw_status_busy(i_target)); + } + else + { + // Gemini should return success code + FAPI_TRY(mss::exp::i2c::fw_status(i_target, mss::DELAY_1MS, 100)); + } + + } fapi_try_exit: return fapi2::current_err; diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.C index d106223ac..26bba128b 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.C @@ -22,3 +22,118 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// @file exp_omi_train_check.C +/// @brief Check that omi training was successful from explorer side +/// +/// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com> +/// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com> +/// *HWP Team: Memory +/// *HWP Level: 2 +/// *HWP Consumed by: HB + +#include <fapi2.H> +#include <exp_omi_train_check.H> +#include <lib/omi/exp_omi_utils.H> +#include <generic/memory/mss_git_data_helper.H> +#include <lib/shared/exp_consts.H> +#include <generic/memory/lib/utils/find.H> +#include <lib/i2c/exp_i2c.H> +#include <generic/memory/lib/utils/shared/mss_generic_consts.H> + +/// +/// @brief Check that the OCMB's omi state machine is in its expected state after OMI training +/// @param[in] i_target the OCMB target to check +/// @return FAPI2_RC_SUCCESS iff ok +/// @note the functionality of this procedure was made to match that of p9a_omi_train_check +/// +fapi2::ReturnCode exp_omi_train_check(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) +{ + mss::display_git_commit_info("exp_omi_train_check"); + + FAPI_INF("%s Start exp_omi_train_check", mss::c_str(i_target)); + + // Const + constexpr uint8_t STATE_MACHINE_SUCCESS = 0b111; // This value is from Lonny Lambrecht + constexpr uint8_t MAX_LOOP_COUNT = 10; // Retry times + const auto& l_omi = mss::find_target<fapi2::TARGET_TYPE_OMI>(i_target); + const auto& l_proc = mss::find_target<fapi2::TARGET_TYPE_PROC_CHIP>(i_target); + + // Declares variables + fapi2::buffer<uint64_t> l_omi_status; + fapi2::buffer<uint64_t> l_omi_training_status; + fapi2::buffer<uint64_t> l_dl0_error_hold; + fapi2::buffer<uint64_t> l_expected_dl0_error_hold; + fapi2::buffer<uint64_t> l_dl0_config1; + uint8_t l_state_machine_state = 0; + uint8_t l_tries = 0; + uint32_t l_omi_freq = 0; + + do + { + // Delay + fapi2::delay(500 * mss::DELAY_1MS, 10 * mss::DELAY_1MS); + + // Check OMI training status + FAPI_TRY(mss::exp::omi::train::omi_train_status(i_target, l_state_machine_state, l_omi_status)); + l_tries++; + + } + while (l_tries < MAX_LOOP_COUNT && l_state_machine_state != STATE_MACHINE_SUCCESS); + + // Note: this is very useful debug information while trying to debug training during polling + FAPI_TRY(fapi2::getScom(i_target, EXPLR_DLX_DL0_TRAINING_STATUS, l_omi_training_status)); + FAPI_TRY(fapi2::getScom(i_target, EXPLR_DLX_DL0_CONFIG1, l_dl0_config1)); + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FREQ_OMI_MHZ, l_proc, l_omi_freq)); + + + FAPI_ASSERT(l_state_machine_state == STATE_MACHINE_SUCCESS, + fapi2::EXP_OMI_TRAIN_ERR() + .set_OCMB_TARGET(i_target) + .set_OMI_TARGET(l_omi) + .set_EXPECTED_SM_STATE(STATE_MACHINE_SUCCESS) + .set_ACTUAL_SM_STATE(l_state_machine_state) + .set_DL0_STATUS(l_omi_status) + .set_DL0_TRAINING_STATUS(l_omi_training_status) + .set_DL0_CONFIG1(l_dl0_config1) + .set_OMI_FREQ(l_omi_freq), + "%s EXP OMI Training Failure, expected state:%d/actual state:%d", + mss::c_str(i_target), + STATE_MACHINE_SUCCESS, + l_state_machine_state + ); + + // Finally, make sure fw_status is good + FAPI_TRY(mss::exp::i2c::fw_status(i_target, mss::common_timings::DELAY_1MS, 100)); + + // Check for errors in ERROR_HOLD until we get a proper FIR API setup + FAPI_TRY(fapi2::getScom(i_target, EXPLR_DLX_DL0_ERROR_HOLD, l_dl0_error_hold)); + + // Training done bit + l_expected_dl0_error_hold.setBit<EXPLR_DLX_DL0_ERROR_HOLD_CERR_39>(); + + if (l_dl0_error_hold != l_expected_dl0_error_hold) + { + // To get to this point, we had to have completed training, so these errors are not catastrophic + // We don't need to assert out, but let's make sure we print them out + FAPI_INF("%s EXPLR_DLX_DL0_ERROR_HOLD REG 0x%016llx " + "did not match expected value. REG contents: 0x%016llx Expected: 0x%016llx", + mss::c_str(i_target), + EXPLR_DLX_DL0_ERROR_HOLD, + l_dl0_error_hold, + l_expected_dl0_error_hold); + } + + FAPI_INF("%s End exp_omi_train_check, expected state:%d/actual state:%d, DL0_STATUS:0x%016llx, DL0_TRAINING_STATUS:0x%016llx", + mss::c_str(i_target), + STATE_MACHINE_SUCCESS, + l_state_machine_state, + l_omi_status, + l_omi_training_status); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; + +}// exp_omi_train_check diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.H index 1c9478e67..0adb51ce9 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.H @@ -22,3 +22,32 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// @file exp_omi_train_check.C +/// @brief Check that omi training was successful from explorer side +/// +/// *HWP HWP Owner: Mark Pizzutillo <Mark.Pizzutillo@ibm.com> +/// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com> +/// *HWP Team: Memory +/// *HWP Level: 2 +/// *HWP Consumed by: HB + +#ifndef _EXP_OMI_TRAIN_CHECK_H_ +#define _EXP_OMI_TRAIN_CHECK_H_ + +#include <fapi2.H> + +typedef fapi2::ReturnCode (*exp_omi_train_check_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>&); + +extern "C" +{ + + /// + /// @brief Check that the OCMB's omi state machine is in its expected state after OMI training + /// @param[in] i_target the OCMB target to check + /// @return FAPI2_RC_SUCCESS iff ok + /// + fapi2::ReturnCode exp_omi_train_check(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target); +} + +#endif diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.mk b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.mk index 1d6b16395..93566fadd 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.mk +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/exp_omi_train_check.mk @@ -22,3 +22,8 @@ # permissions and limitations under the License. # # IBM_PROLOG_END_TAG +-include 00exp_common.mk + +PROCEDURE=exp_omi_train_check +$(eval $(call ADD_EXP_MEMORY_INCDIRS,$(PROCEDURE))) +$(call BUILD_PROCEDURE) diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H index 60fd07529..c430c650e 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/i2c/exp_i2c.H @@ -295,11 +295,39 @@ inline fapi2::ReturnCode boot_config(const fapi2::Target<fapi2::TARGET_TYPE_OCMB // The command takes ~300ms and we poll for around 100ms, so wait 250ms here FAPI_TRY( fapi2::delay( (mss::DELAY_1MS * 250), 200) ); - // Poll for status response - // Note: the EXP_FW_BOOT_CONFIG command trains the OMI, which takes a - // significant amount of time. We're waiting 1ms between polls, and poll for 100 loops, - // which totals at least 100ms - FAPI_TRY(fw_status(i_target, DELAY_1MS, 100)); +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Check that the FW status code returns a busy status (expected for exp_omi_train) +/// +/// @param[in] i_target OCMB +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff busy and no error code, else, error code +/// +inline fapi2::ReturnCode check_fw_status_busy(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) +{ + uint8_t l_status = ~(0); + + std::vector<uint8_t> l_data; + FAPI_TRY(get_fw_status(i_target, l_data)); + + FAPI_TRY(status::get_status_code(i_target, l_data, l_status)); + + // Post bootconfig1, we should see a busy status until p9a_omi_train is kicked off (setting axone to AUTO_TRAIN) + // explorer will return busy status until then. if we have another status, then we may not have executed bootconfig1 + // or some previous command correctly, so we should check it here + // After p9a_omi_train, exp_omi_train_check will check fw_status for success (in addition to checking training completion) + // to make sure things went smoothly + FAPI_ASSERT( l_status == status_codes::FW_BUSY, + fapi2::MSS_EXP_I2C_FW_BOOT_CONFIG_STATUS_CODE_INVALID(). + set_TARGET(i_target). + set_STATUS_CODE(l_status). + set_CMD_ID(FW_STATUS), + "Status code did not return BUSY (%d) as expected post BOOT_CONFIG1, received (%d) for " TARGIDFORMAT , + status_codes::FW_BUSY, l_status, TARGID ); + + return fapi2::FAPI2_RC_SUCCESS; fapi_try_exit: return fapi2::current_err; diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.C index 47e85362f..f8133bafb 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.C @@ -40,6 +40,7 @@ #include <generic/memory/lib/mss_generic_attribute_getters.H> #include <mss_explorer_attribute_getters.H> #include <generic/memory/lib/mss_generic_system_attribute_getters.H> +#include <lib/shared/exp_consts.H> namespace mss { @@ -75,12 +76,17 @@ fapi2::ReturnCode setup_omi_dl0_config0( l_config0.insertFromRight<EXPLR_DLX_DL0_CONFIG0_CFG_TRAIN_MODE, EXPLR_DLX_DL0_CONFIG0_CFG_TRAIN_MODE_LEN>(i_train_mode); + l_config0.writeBit<EXPLR_DLX_DL0_CONFIG0_CFG_PWRMGT_ENABLE>(0); + + FAPI_DBG("Writing 0x%16llx to EXPLR_DLX_DL0_CONFIG0 (0x%16llx) of %s", + l_config0, EXPLR_DLX_DL0_CONFIG0, mss::c_str(i_target)); + // All other bits will be left at their default values FAPI_TRY( fapi2::putScom(i_target, EXPLR_DLX_DL0_CONFIG0, l_config0), "Error writing EXPLR_DLX_DL0_CONFIG0 on %s", mss::c_str(i_target)); fapi_try_exit: - return fapi2::FAPI2_RC_SUCCESS; + return fapi2::current_err; } namespace train @@ -142,6 +148,32 @@ fapi_try_exit: return fapi2::current_err; } +/// +/// @brief Check the OMI train status on the OCMB chip +/// +/// @param[in] i_target OCMB chil +/// @param[out] o_state_machine_state training state mahcine +/// @param[out] o_omi_training_status training status +/// @return fapi2::ReturnCode +/// +fapi2::ReturnCode omi_train_status(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + uint8_t& o_state_machine_state, + fapi2::buffer<uint64_t>& o_omi_training_status) +{ + fapi2::buffer<uint64_t> l_omi_status; + + // Check OMI training status + FAPI_TRY(fapi2::getScom(i_target, EXPLR_DLX_DL0_STATUS, l_omi_status)); + + o_omi_training_status = l_omi_status; + o_state_machine_state = 0; + l_omi_status.extractToRight<EXPLR_DLX_DL0_STATUS_STS_TRAINING_STATE_MACHINE, + EXPLR_DLX_DL0_STATUS_STS_TRAINING_STATE_MACHINE_LEN>(o_state_machine_state); + +fapi_try_exit: + return fapi2::current_err; +} + } // ns train } // ns omi diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.H index cb52d1ac0..5022271ee 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/omi/exp_omi_utils.H @@ -230,6 +230,19 @@ namespace train /// fapi2::ReturnCode setup_fw_boot_config( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, std::vector<uint8_t>& o_data ); + +/// +/// @brief Check the OMI train status on the OCMB chip +/// +/// @param[in] i_target OCMB chil +/// @param[out] o_state_machine_state training state mahcine +/// @param[out] o_omi_training_status training status +/// @return fapi2::ReturnCode +/// +fapi2::ReturnCode omi_train_status(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target, + uint8_t& o_state_machine_state, + fapi2::buffer<uint64_t>& o_omi_training_status); + } // ns train } // ns omi diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.C index 1bfe94371..eae18dd1f 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.C @@ -51,46 +51,33 @@ namespace workarounds { namespace omi { + /// -/// @brief Determine if OCMB PRBS workaround needs to be performed +/// @brief Determine if the OCMB is an explorer /// -/// @param[in] i_ocmb_chip OCMB target -/// @param[out] o_required workaround needs to be performed -/// @return FAPI2_RC_SUCCESS iff success +/// @param[in] i_ocmb_chip OCMB chip +/// @param[out] o_explorer true/false is explorer +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// @note Used for exp_omi_train procedure to differentiate fw_status behavior with gemini /// -fapi2::ReturnCode is_prbs_ocmb_required( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> i_ocmb_chip, - bool& o_required) +fapi2::ReturnCode ocmb_is_explorer(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_chip, bool& o_explorer) { - // Check chip type - uint8_t l_proc_type = 0; - const auto& l_proc_chip = mss::find_target<fapi2::TARGET_TYPE_PROC_CHIP>(i_ocmb_chip); - FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, l_proc_chip, l_proc_type), - "Error getting ATTR_NAME of %s", mss::c_str(l_proc_chip)); - - // OCMB Workaround Logic: - // Axone: OCMB workaround off - // Non-axone (Apollo): OCMB workaround on - // P10 - No workaround required (no enum for this yet, so we must revisit this when the time comes) - o_required = l_proc_type != fapi2::ENUM_ATTR_NAME_AXONE; + uint8_t l_name = 0; + FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_NAME, i_ocmb_chip, l_name)); + + o_explorer = (l_name == fapi2::ENUM_ATTR_NAME_EXPLORER); fapi_try_exit: return fapi2::current_err; } - /// -/// @brief Performs OCMB PRBS workaround +/// @brief Set configurable delay based on the PRBS ATTR and SIM mode /// -/// @param[in] i_ocmb_chip OCMB chip -/// @param[in] i_dl_x4_backoff_en backoff enable +/// @param[in] i_ocmb_chip OCMB target /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success /// -fapi2::ReturnCode prbs_ocmb( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> i_ocmb_chip, - const uint8_t i_dl_x4_backoff_en) +fapi2::ReturnCode prbs_delay(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_chip) { - FAPI_DBG("Performing PRBS OCMB workaround on %s", mss::c_str(i_ocmb_chip)); - uint8_t l_sim = 0; uint32_t l_prbs_time = 0; uint64_t l_prbs_time_scaled = 0; @@ -101,23 +88,10 @@ fapi2::ReturnCode prbs_ocmb( "Error from FAPI_ATTR_GET (ATTR_OMI_DL_PREIPL_PRBS_TIME)"); l_prbs_time_scaled = l_prbs_time * mss::common_timings::DELAY_1MS; - // State 6 - FAPI_TRY(mss::exp::omi::setup_omi_dl0_config0(i_ocmb_chip, - mss::omi::train_mode::TX_TRAINING_STATE3, - i_dl_x4_backoff_en)); - - // Set configurable delay based on the PRBS ATTR and SIM mode FAPI_TRY(fapi2::delay(l_prbs_time_scaled, mss::common_timings::DELAY_1US)); FAPI_DBG("OMI Training Pre-ipl PRBS Time = %dns", (l_sim ? mss::common_timings::DELAY_1US : l_prbs_time_scaled)); - // Enable training state 1 to send Pattern A - FAPI_TRY(mss::exp::omi::setup_omi_dl0_config0(i_ocmb_chip, - mss::omi::train_mode::TX_PATTERN_A, - i_dl_x4_backoff_en)); - - // Not calling with ENABLE_AUTO_TRAINING for explorer - fapi_try_exit: return fapi2::current_err; } @@ -174,6 +148,53 @@ fapi_try_exit: return fapi2::current_err; } +/// +/// @brief Workaround for exp_omi_train to perform dlx_config0 setup +/// +/// @param[in] i_target OCMB chip +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode training_prbs(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) +{ + uint8_t l_dl_x4_backoff_en = 0; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE, i_target, l_dl_x4_backoff_en), + "Error getting ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE"); + + // Train mode 1 (PATTERN_A) + FAPI_TRY(mss::exp::omi::setup_omi_dl0_config0(i_target, + mss::omi::train_mode::TX_PATTERN_A, + l_dl_x4_backoff_en)); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Workaround for exp_omi_setup to perform dlx_config0 setup +/// +/// @param[in] i_target OCMB chip +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode pre_training_prbs(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target) +{ + uint8_t l_dl_x4_backoff_en = 0; + + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE, i_target, l_dl_x4_backoff_en), + "Error getting ATTR_CHIP_EC_FEATURE_OMI_DL_X4_BACKOFF_ENABLE"); + + // State 6 + FAPI_TRY(mss::exp::omi::setup_omi_dl0_config0(i_target, + mss::omi::train_mode::TX_TRAINING_STATE3, + l_dl_x4_backoff_en)); + + // Set configurable delay based on the PRBS ATTR and SIM mode + FAPI_TRY(prbs_delay(i_target)); + +fapi_try_exit: + return fapi2::current_err; +} + } // omi } // workarounds } // exp diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.H b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.H index 5d45f2e13..f99eceda5 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.H +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/workarounds/exp_omi_workarounds.H @@ -48,26 +48,22 @@ namespace omi { /// -/// @brief Determine if OCMB PRBS workaround needs to be performed +/// @brief Determine if the OCMB is an explorer /// -/// @param[in] i_ocmb_chip OCMB target -/// @param[out] o_required workaround needs to be performed -/// @return FAPI2_RC_SUCCESS iff success +/// @param[in] i_ocmb_chip OCMB chip +/// @param[out] o_explorer true/false is explorer +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// @note Used for exp_omi_train procedure to differentiate fw_status behavior with gemini /// -fapi2::ReturnCode is_prbs_ocmb_required( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> i_ocmb_chip, - bool& o_required); +fapi2::ReturnCode ocmb_is_explorer(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_chip, bool& o_explorer); /// -/// @brief Performs OCMB PRBS workaround +/// @brief Set configurable delay based on the PRBS ATTR and SIM mode /// -/// @param[in] i_ocmb_chip OCMB chip -/// @param[in] i_dl_x4_backoff_en backoff enable +/// @param[in] i_ocmb_chip OCMB target /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success /// -fapi2::ReturnCode prbs_ocmb( - const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> i_ocmb_chip, - const uint8_t i_dl_x4_backoff_en); +fapi2::ReturnCode prbs_delay(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmb_chip); /// /// @brief Determine if we need to bypass MENTERP register reads/writes @@ -86,6 +82,22 @@ fapi2::ReturnCode gem_menterp(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> /// fapi2::ReturnCode gem_setup_config(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target); +/// +/// @brief Workaround for exp_omi_train to perform dlx_config0 setup +/// +/// @param[in] i_target OCMB chip +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode training_prbs(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target); + +/// +/// @brief Workaround for exp_omi_setup to perform dlx_config0 setup +/// +/// @param[in] i_target OCMB chip +/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success +/// +fapi2::ReturnCode pre_training_prbs(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target); + } // omi } // workarounds } // exp diff --git a/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_train_errors.xml b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_train_errors.xml index 42589401b..9b735dd02 100644 --- a/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_train_errors.xml +++ b/src/import/chips/ocmb/explorer/procedures/xml/error_info/exp_omi_train_errors.xml @@ -23,4 +23,33 @@ <!-- --> <!-- IBM_PROLOG_END_TAG --> <hwpErrors> + <!-- ******************************************************************** --> + <hwpError> + <rc>RC_EXP_OMI_TRAIN_ERR</rc> + <description> + exp_omi_train_check did not see expected trained status from OCMB DL0 status register + </description> + <ffdc>OCMB_TARGET</ffdc> + <ffdc>EXPECTED_SM_STATE</ffdc> + <ffdc>ACTUAL_SM_STATE</ffdc> + <ffdc>DL0_STATUS</ffdc> + <ffdc>DL0_TRAINING_STATUS</ffdc> + <ffdc>DL0_CONFIG1</ffdc> + <ffdc>OMI_FREQ</ffdc> + <callout> + <target>OCMB_TARGET</target> + <priority>HIGH</priority> + </callout> + <callout> + <bus>OMI_TARGET, OCMB_TARGET</bus> + <priority>HIGH</priority> + </callout> + <deconfigure> + <target>OCMB_TARGET</target> + </deconfigure> + <gard> + <target>OCMB_TARGET</target> + </gard> + </hwpError> + <!-- ******************************************************************** --> </hwpErrors> diff --git a/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml b/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml index a081d1cc7..ae2cf7f56 100644 --- a/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml +++ b/src/import/chips/ocmb/explorer/procedures/xml/error_info/mss_exp_errors.xml @@ -373,6 +373,28 @@ </hwpError> <hwpError> + <rc>RC_MSS_EXP_I2C_FW_BOOT_CONFIG_STATUS_CODE_INVALID</rc> + <description> + Unexpected Explorer status code returned during OMI link training pattern handshake. + Expected FW_BUSY, but received STATUS_CODE in FFDC data + </description> + <ffdc>TARGET</ffdc> + <ffdc>STATUS_CODE</ffdc> + <ffdc>CMD_ID</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>MEDIUM</priority> + </callout> + <callout> + <target>TARGET</target> + <priority>HIGH</priority> + </callout> + <deconfigure> + <target>TARGET</target> + </deconfigure> + </hwpError> + + <hwpError> <rc>RC_MSS_EXP_I2C_FW_STATUS_BUSY</rc> <description> Received FW_BUSY status after polling timeout for |