diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs00.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs00.C index 2ff145bf753..1c1e8666afb 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs00.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs00.C @@ -22,3 +22,80 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file exp_mrs00.C +/// @brief Run and manage the DDR4 MRS00 loading +/// +// *HWP HWP Owner: Matthew Hickman +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +namespace ddr4 +{ + +/// +/// @brief mrs0_data ctor +/// @param[in] a fapi2::TARGET_TYPE_DIMM target +/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok +/// @note Burst Length will always be set to fixed x8 (0) +/// @note Burst Chop (x4) is not supported +/// +template<> +mrs00_data::mrs00_data( const fapi2::Target& i_target, + fapi2::ReturnCode& o_rc ): + iv_burst_length(0), + iv_read_burst_type(fapi2::ENUM_ATTR_MSS_EXP_RESP_DRAM_RBT_SEQUENTIAL), + iv_dll_reset(fapi2::ENUM_ATTR_MSS_EXP_RESP_DRAM_DLL_RESET_NO), + iv_test_mode(fapi2::ENUM_ATTR_MSS_EXP_RESP_DRAM_TM_NORMAL), + iv_write_recovery(0), + iv_cas_latency(0) +{ + const auto l_port_target = mss::find_target(i_target); + + FAPI_TRY( mss::attr::get_exp_resp_dram_rbt(l_port_target, iv_read_burst_type), "Error in mrs00_data()" ); + FAPI_TRY( mss::attr::get_dram_cl(l_port_target, iv_cas_latency), "Error in mrs00_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_dram_dll_reset(l_port_target, iv_dll_reset), "Error in mrs00_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_dram_tm(l_port_target, iv_test_mode), "Error in mrs00_data()" ); + FAPI_TRY( mss::attr::get_dram_twr(l_port_target, iv_write_recovery), "Error in mrs00_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_dram_burst_length(l_port_target, iv_burst_length), "Error in mrs00_data()" ); + + FAPI_INF("%s MR0 Attributes: BL: 0x%x, RBT: 0x%x, CL: 0x%x, TM: 0x%x, DLL_RESET: 0x%x, WR: 0x%x", + mss::c_str(i_target), iv_burst_length, iv_read_burst_type, iv_cas_latency, iv_test_mode, iv_dll_reset, + iv_write_recovery); + + o_rc = fapi2::FAPI2_RC_SUCCESS; + return; +fapi_try_exit: + o_rc = fapi2::current_err; + FAPI_ERR("%s unable to get attributes for mrs00", mss::c_str(i_target)); + return; +} + +template<> +fapi2::ReturnCode (*mrs00_data::make_ccs_instruction)(const + fapi2::Target& i_target, + const mrs00_data& i_data, + ccs::instruction_t& io_inst, + const uint64_t i_rank) = &mrs00; + +template<> +fapi2::ReturnCode (*mrs00_data::decode)(const ccs::instruction_t& i_inst, + const uint64_t i_rank) = &mrs00_decode; + +} // ns ddr4 + +} // ns mss diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs01.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs01.C index ba59c2277fc..8d97c6c4c13 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs01.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs01.C @@ -22,3 +22,108 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file exp_mrs01.C +/// @brief Run and manage the DDR4 MRS01 loading +/// +// *HWP HWP Owner: Matt Hickman +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +namespace ddr4 +{ + +/// +/// @brief Helper function to decode ODIC to the MRS value - explorer specialization +/// @param[in] i_target a fapi2::Target +/// @param[in] i_odic_value the value to be decoded for ODIC +/// @param[out] o_odic_decode the MRS decoded value for ODIC +/// @return FAPI2_RC_SUCCESS iff OK +/// +template<> +fapi2::ReturnCode odic_helper(const fapi2::Target& i_target, + const uint8_t i_odic_value, + fapi2::buffer& o_odic_decode) +{ + constexpr uint8_t MAX_ODIC_VALUE = 0b01; + FAPI_ASSERT( i_odic_value < MAX_ODIC_VALUE, + fapi2::MSS_BAD_MR_PARAMETER() + .set_MR_NUMBER(1) + .set_PARAMETER(OUTPUT_IMPEDANCE) + .set_PARAMETER_VALUE(i_odic_value) + .set_DIMM_IN_ERROR(i_target), + "Bad value for output driver impedance: %d (%s)", + i_odic_value, + mss::c_str(i_target)); + + o_odic_decode = i_odic_value; + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief mrs01_data ctor +/// @param[in] a fapi2::TARGET_TYPE_DIMM target +/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok +/// +template<> +mrs01_data::mrs01_data( const fapi2::Target& i_target, + fapi2::ReturnCode& o_rc ): + iv_dll_enable(fapi2::ENUM_ATTR_MSS_EXP_RESP_DRAM_DLL_ENABLE_ENABLE), + iv_additive_latency(0), + iv_wl_enable(0), + iv_tdqs(0), + iv_qoff(0) +{ + const auto l_port_target = mss::find_target(i_target); + + FAPI_TRY( mss::attr::get_exp_resp_dram_dll_enable(l_port_target, iv_dll_enable), + "Error in mrs01_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_dram_odic(i_target, iv_odic), "Error in mrs01_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_dram_al(l_port_target, iv_additive_latency), "Error in mrs01_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_dram_wr_lvl_enable(l_port_target, iv_wl_enable), + "Error in mrs01_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_dram_rtt_nom(i_target, iv_rtt_nom), "Error in mrs01_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_dram_tdqs(l_port_target, iv_tdqs), "Error in mrs01_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_dram_output_buffer(l_port_target, iv_qoff), "Error in mrs01_data()" ); + + o_rc = fapi2::FAPI2_RC_SUCCESS; + return; + +fapi_try_exit: + o_rc = fapi2::current_err; + FAPI_ERR("%s unable to get attributes for mrs01"); + return; +} + +template<> +fapi2::ReturnCode (*mrs01_data::make_ccs_instruction)(const + fapi2::Target& i_target, + const mrs01_data& i_data, + ccs::instruction_t& io_inst, + const uint64_t i_rank) = &mrs01; + +template<> +fapi2::ReturnCode (*mrs01_data::decode)(const ccs::instruction_t& i_inst, + const uint64_t i_rank) = &mrs01_decode; + +} // ns ddr4 + +} // ns mss diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs02.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs02.C index 3868c86bb82..8598719ae3f 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs02.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs02.C @@ -22,3 +22,71 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file exp_mrs02.C +/// @brief Run and manage the DDR4 MRS02 loading +/// +// *HWP HWP Owner: Matthew Hickman +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +namespace ddr4 +{ + +/// +/// @brief mrs02_data ctor +/// @param[in] a fapi2::TARGET_TYPE_DIMM target +/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok +/// +template<> +mrs02_data::mrs02_data( const fapi2::Target& i_target, + fapi2::ReturnCode& o_rc ): + iv_lpasr(0), + iv_cwl(0), + iv_write_crc(0) +{ + const auto l_port_target = mss::find_target(i_target); + + FAPI_TRY( mss::attr::get_exp_resp_dram_lpasr(l_port_target, iv_lpasr), "Error in mrs02_data()" ); + FAPI_TRY( mss::attr::get_dram_cwl(l_port_target, iv_cwl), "Error in mrs02_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_dram_rtt_wr(i_target, iv_dram_rtt_wr), "Error in mrs02_data()" ); + FAPI_TRY( mss::attr::get_mrw_dram_write_crc(iv_write_crc), "Error in mrs02_data()" ); + + o_rc = fapi2::FAPI2_RC_SUCCESS; + return; + +fapi_try_exit: + o_rc = fapi2::current_err; + FAPI_ERR("%s unable to get attributes for mrs02", mss::c_str(i_target)); + return; +} + +template<> +fapi2::ReturnCode (*mrs02_data::make_ccs_instruction)(const + fapi2::Target& i_target, + const mrs02_data& i_data, + ccs::instruction_t& io_inst, + const uint64_t i_rank) = &mrs02; + +template<> +fapi2::ReturnCode (*mrs02_data::decode)(const ccs::instruction_t& i_inst, + const uint64_t i_rank) = &mrs02_decode; + +} // ns ddr4 + +} // ns mss diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs03.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs03.C index 3b4a79d3c20..200f7f79f4d 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs03.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs03.C @@ -22,3 +22,115 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file exp_mrs03.C +/// @brief Run and manage mrs03 +/// +// *HWP HWP Owner: Matt Hickman +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +namespace ddr4 +{ + +/// +/// @brief Helper function to decode CRC WR latency to the MRS value - explorer specialization +/// @param[in] i_target a fapi2::Target +/// @param[in] i_value the value to be decoded +/// @param[out] o_decode the MRS decoded value +/// @return FAPI2_RC_SUCCESS iff OK +/// +template<> +fapi2::ReturnCode crc_wr_latency_helper(const fapi2::Target& i_target, + const uint8_t i_value, + fapi2::buffer& o_decode) +{ + constexpr uint8_t MAX_VALUE = 0b10; + FAPI_ASSERT( i_value < MAX_VALUE, + fapi2::MSS_BAD_MR_PARAMETER() + .set_MR_NUMBER(3) + .set_PARAMETER(OUTPUT_IMPEDANCE) + .set_PARAMETER_VALUE(i_value) + .set_DIMM_IN_ERROR(i_target), + "Bad value for Write CMD Latency: %d (%s)", + i_value, + mss::c_str(i_target)); + + o_decode = i_value; + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief mrs03_data ctor +/// @param[in] a fapi2::TARGET_TYPE_DIMM target +/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok +/// +template<> +mrs03_data::mrs03_data( const fapi2::Target& i_target, + fapi2::ReturnCode& o_rc ): + iv_mpr_mode(fapi2::ENUM_ATTR_MSS_EXP_RESP_MPR_MODE_DISABLE), + iv_mpr_page(fapi2::ENUM_ATTR_MSS_EXP_RESP_MPR_PAGE_PG0), + iv_geardown(0), + iv_pda(fapi2::ENUM_ATTR_MSS_EXP_RESP_PER_DRAM_ACCESS_DISABLE), + iv_crc_wr_latency(0), + iv_temp_readout(fapi2::ENUM_ATTR_MSS_EXP_RESP_TEMP_READOUT_DISABLE), + iv_fine_refresh(0), + iv_read_format(fapi2::ENUM_ATTR_MSS_EXP_RESP_MPR_RD_FORMAT_SERIAL) +{ + const auto l_port_target = mss::find_target(i_target); + + FAPI_TRY( mss::attr::get_exp_resp_mpr_mode(l_port_target, iv_mpr_mode), "Error in mrs03_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_mpr_page(l_port_target, iv_mpr_page), "Error in mrs03_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_geardown_mode(l_port_target, iv_geardown), "Error in mrs03_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_per_dram_access(l_port_target, iv_pda), "Error in mrs03_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_temp_readout(l_port_target, iv_temp_readout), "Error in mrs03_data()" ); + FAPI_TRY( mss::attr::get_mrw_fine_refresh_mode(iv_fine_refresh), "Error in mrs03_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_crc_wr_latency(l_port_target, iv_crc_wr_latency), "Error in mrs03_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_mpr_rd_format(l_port_target, iv_read_format), "Error in mrs03_data()" ); + + FAPI_INF("%s MR3 attributes: MPR_MODE: 0x%x, MPR_PAGE: 0x%x, GD: 0x%x, PDA: 0x%x, " + "TEMP: 0x%x FR: 0x%x, CRC_WL: 0x%x, RF: 0x%x", + mss::c_str(i_target), iv_mpr_mode, iv_mpr_page, iv_geardown, iv_pda, + iv_temp_readout, iv_fine_refresh, iv_crc_wr_latency, iv_read_format); + + o_rc = fapi2::FAPI2_RC_SUCCESS; + return; + +fapi_try_exit: + o_rc = fapi2::current_err; + FAPI_ERR("%s unable to get attributes for mrs03"); + return; +} + +template<> +fapi2::ReturnCode (*mrs03_data::make_ccs_instruction)(const + fapi2::Target& i_target, + const mrs03_data& i_data, + ccs::instruction_t& io_inst, + const uint64_t i_rank) = &mrs03; + +template<> +fapi2::ReturnCode (*mrs03_data::decode)(const ccs::instruction_t& i_inst, + const uint64_t i_rank) = &mrs03_decode; + +} // ns ddr4 +} // ns mss diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs04.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs04.C index f68617afc6e..75e827d4480 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs04.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs04.C @@ -22,3 +22,94 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file exp_mrs04.C +/// @brief Run and manage the DDR4 MRS04 loading +/// +// *HWP HWP Owner: Matthew Hickman +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +namespace ddr4 +{ + +/// +/// @brief mrs04_data ctor +/// @param[in] a fapi2::TARGET_TYPE_DIMM target +/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok +/// +template<> +mrs04_data::mrs04_data( const fapi2::Target& i_target, + fapi2::ReturnCode& o_rc ): + iv_max_pd_mode(static_cast(fapi2::ENUM_ATTR_MSS_EXP_RESP_MAX_POWERDOWN_MODE_DISABLE)), + iv_temp_refresh_range(static_cast(fapi2::ENUM_ATTR_MSS_MRW_TEMP_REFRESH_RANGE_NORMAL)), + iv_temp_ref_mode(static_cast(fapi2::ENUM_ATTR_MSS_MRW_TEMP_REFRESH_MODE_DISABLE)), + iv_vref_mon(static_cast(fapi2::ENUM_ATTR_MSS_EXP_RESP_INTERNAL_VREF_MONITOR_DISABLE)), + iv_cs_cmd_latency(static_cast(fapi2::ENUM_ATTR_MEM_CS_CMD_LATENCY_DISABLE)), + iv_ref_abort(static_cast(fapi2::ENUM_ATTR_MSS_EXP_RESP_SELF_REF_ABORT_DISABLE)), + iv_rd_pre_train_mode(static_cast(fapi2::ENUM_ATTR_MSS_EXP_RESP_RD_PREAMBLE_TRAIN_DISABLE)), + iv_rd_preamble(static_cast(fapi2::ENUM_ATTR_MSS_EXP_RESP_RD_PREAMBLE_TRAIN_DISABLE)), + iv_wr_preamble(static_cast(fapi2::ENUM_ATTR_MSS_EXP_RESP_RD_PREAMBLE_1NCLK)), + iv_ppr(static_cast(fapi2::ENUM_ATTR_MEM_EFF_DRAM_PPR_NOT_SUPPORTED)), + iv_soft_ppr(static_cast(fapi2::ENUM_ATTR_MEM_EFF_DRAM_SOFT_PPR_NOT_SUPPORTED)) +{ + const auto l_port_target = mss::find_target(i_target); + + // From DDR4 Spec: 3.3 RESET and Initialization Procedure + // PPR and soft PPR must be disabled during initialization + // so we don't call the attribute accessor for them + FAPI_TRY( mss::attr::get_exp_resp_max_powerdown_mode(l_port_target, iv_max_pd_mode), "Error in mrs04_data()" ); + FAPI_TRY( mss::attr::get_mrw_temp_refresh_range(iv_temp_refresh_range), "Error in mrs04_data()" ); + FAPI_TRY( mss::attr::get_mrw_temp_refresh_mode(iv_temp_ref_mode), "Error in mrs04_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_internal_vref_monitor(l_port_target, iv_vref_mon), "Error in mrs04_data()" ); + FAPI_TRY( mss::attr::get_cs_cmd_latency(i_target, iv_cs_cmd_latency), "Error in mrs04_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_self_ref_abort(l_port_target, iv_ref_abort), "Error in mrs04_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_rd_preamble_train(l_port_target, iv_rd_pre_train_mode), "Error in mrs04_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_rd_preamble(l_port_target, iv_rd_preamble), "Error in mrs04_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_wr_preamble(l_port_target, iv_wr_preamble), "Error in mrs04_data()" ); + + FAPI_INF("%s MR4 attributes: MAX_PD: 0x%x, TEMP_REFRESH_RANGE: 0x%x, TEMP_REF_MODE: 0x%x " + "VREF_MON: 0x%x, CSL: 0x%x, REF_ABORT: 0x%x, RD_PTM: 0x%x, RD_PRE: 0x%x, " + "WR_PRE: 0x%x, PPR: 0x%x, SOFT PPR: 0x%x", + mss::c_str(i_target), iv_max_pd_mode, iv_temp_refresh_range, iv_temp_ref_mode, iv_vref_mon, + iv_cs_cmd_latency, iv_ref_abort, + iv_rd_pre_train_mode, iv_rd_preamble, iv_wr_preamble, iv_ppr, iv_soft_ppr); + + //Let's make sure the temp_refresh_mode attribute is valid, even though it's mrw, gotta double check spec + o_rc = fapi2::FAPI2_RC_SUCCESS; + return; + +fapi_try_exit: + o_rc = fapi2::current_err; + FAPI_ERR("%s unable to get attributes for mrs04", mss::c_str(i_target)); + return; +} + +template<> +fapi2::ReturnCode (*mrs04_data::make_ccs_instruction)(const + fapi2::Target& i_target, + const mrs04_data& i_data, + ccs::instruction_t& io_inst, + const uint64_t i_rank) = &mrs04; + +template<> +fapi2::ReturnCode (*mrs04_data::decode)(const ccs::instruction_t& i_inst, + const uint64_t i_rank) = &mrs04_decode; + +} // ns ddr4 +} // ns mss diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs05.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs05.C index 5464e36e9b0..e332f8ddde1 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs05.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs05.C @@ -22,3 +22,87 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file exp_mrs05.C +/// @brief Run and manage the DDR4 MRS05 loading +/// +// *HWP HWP Owner: Matthew Hickman +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using fapi2::TARGET_TYPE_MEM_PORT; +using fapi2::TARGET_TYPE_DIMM; +using fapi2::FAPI2_RC_SUCCESS; + +namespace mss +{ + +namespace ddr4 +{ + +/// +/// @brief mrs05_data ctor +/// @param[in] a fapi2::TARGET_TYPE_DIMM target +/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok +/// +template<> +mrs05_data::mrs05_data( const fapi2::Target& i_target, + fapi2::ReturnCode& o_rc ): + iv_ca_parity_latency(static_cast(fapi2::ENUM_ATTR_MEM_CA_PARITY_LATENCY_DISABLE)), + iv_crc_error_clear(static_cast(fapi2::ENUM_ATTR_MSS_EXP_RESP_CRC_ERROR_CLEAR_CLEAR)), + iv_ca_parity_error_status(static_cast(fapi2::ENUM_ATTR_MSS_EXP_RESP_CA_PARITY_ERROR_STATUS_CLEAR)), + iv_odt_input_buffer(static_cast(fapi2::ENUM_ATTR_MSS_EXP_RESP_ODT_INPUT_BUFF_DEACTIVATED)), + iv_ca_parity(static_cast(fapi2::ENUM_ATTR_MSS_EXP_RESP_CA_PARITY_DISABLE)), + iv_data_mask(static_cast(fapi2::ENUM_ATTR_MSS_EXP_RESP_DATA_MASK_DISABLE)), + iv_write_dbi(static_cast(fapi2::ENUM_ATTR_MSS_EXP_RESP_WRITE_DBI_DISABLE)), + iv_read_dbi(static_cast(fapi2::ENUM_ATTR_MSS_EXP_RESP_READ_DBI_DISABLE)) +{ + const auto l_port_target = mss::find_target(i_target); + + FAPI_TRY( mss::attr::get_ca_parity_latency(i_target, iv_ca_parity_latency), "Error in mrs05_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_crc_error_clear(l_port_target, iv_crc_error_clear), "Error in mrs05_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_ca_parity_error_status(l_port_target, iv_ca_parity_error_status), + "Error in mrs05_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_odt_input_buff(l_port_target, iv_odt_input_buffer), "Error in mrs05_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_dram_rtt_park(i_target, iv_rtt_park), "Error in mrs05_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_ca_parity(l_port_target, iv_ca_parity), "Error in mrs05_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_data_mask(l_port_target, iv_data_mask), "Error in mrs05_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_write_dbi(l_port_target, iv_write_dbi), "Error in mrs05_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_read_dbi(l_port_target, iv_read_dbi), "Error in mrs05_data()" ); + + o_rc = fapi2::FAPI2_RC_SUCCESS; + return; + +fapi_try_exit: + o_rc = fapi2::current_err; + FAPI_ERR("%s unable to get attributes for mrs05", mss::c_str(i_target)); + return; +} + +template<> +fapi2::ReturnCode (*mrs05_data::make_ccs_instruction)(const + fapi2::Target& i_target, + const mrs05_data& i_data, + ccs::instruction_t& io_inst, + const uint64_t i_rank) = &mrs05; + +template<> +fapi2::ReturnCode (*mrs05_data::decode)(const ccs::instruction_t& i_inst, + const uint64_t i_rank) = &mrs05_decode; + +} // ns ddr4 +} // ns mss diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs06.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs06.C index 6236ff1ea34..4d6d80ca042 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs06.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/exp_mrs06.C @@ -22,3 +22,82 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file exp_mrs06.C +/// @brief Run and manage the DDR4 MRS06 loading +/// +// *HWP HWP Owner: Matthew Hickman +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +namespace ddr4 +{ + +/// +/// @brief mrs0_data ctor +/// @param[in] a fapi2::TARGET_TYPE_DIMM target +/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok +/// @note Burst Length will always be set to fixed x8 (0) +/// @note Burst Chop (x4) is not supported +/// +template<> +mrs06_data::mrs06_data( const fapi2::Target& i_target, + fapi2::ReturnCode& o_rc ): + iv_tccd_l(0) +{ + const auto l_port_target = mss::find_target(i_target); + uint8_t l_vrefdq_train_value[mss::exp::MAX_RANK_PER_DIMM][mss::exp::MAX_NIBBLES_PER_PORT] = {0}; + uint8_t l_vrefdq_train_range[mss::exp::MAX_RANK_PER_DIMM][mss::exp::MAX_NIBBLES_PER_PORT] = {0}; + uint8_t l_vrefdq_train_enable[mss::exp::MAX_RANK_PER_DIMM][mss::exp::MAX_NIBBLES_PER_PORT] = {0}; + + FAPI_TRY( mss::attr::get_exp_resp_vref_dq_train_value(i_target, l_vrefdq_train_value), "Error in mrs06_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_vref_dq_train_range(i_target, l_vrefdq_train_range), "Error in mrs06_data()" ); + FAPI_TRY( mss::attr::get_exp_resp_vref_dq_train_enable(i_target, l_vrefdq_train_enable), "Error in mrs06_data()" ); + FAPI_TRY( mss::attr::get_dram_tccd_l(l_port_target, iv_tccd_l), "Error in mrs06_data()" ); + + for (int i = 0; i < mss::exp::MAX_RANK_PER_DIMM; i++) + { + // Using DRAM 0 values due to missing values + // From skipped DRAMs or spares that DNE + iv_vrefdq_train_value[i] = l_vrefdq_train_value[i][0]; + iv_vrefdq_train_range[i] = l_vrefdq_train_range[i][0]; + iv_vrefdq_train_enable[i] = l_vrefdq_train_enable[i][0]; + } + + o_rc = fapi2::FAPI2_RC_SUCCESS; + return; + +fapi_try_exit: + o_rc = fapi2::current_err; + FAPI_ERR("%s unable to get attributes for mrs06", mss::c_str(i_target)); + return; +} + +template<> +fapi2::ReturnCode (*mrs06_data::make_ccs_instruction)(const + fapi2::Target& i_target, + const mrs06_data& i_data, + ccs::instruction_t& io_inst, + const uint64_t i_rank) = &mrs06; + +template<> +fapi2::ReturnCode (*mrs06_data::decode)(const ccs::instruction_t& i_inst, + const uint64_t i_rank) = &mrs06_decode; + +} // ns ddr4 + +} // ns mss diff --git a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4_explorer.C b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4_explorer.C index 0a962035aff..bdaa72ca2b8 100644 --- a/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4_explorer.C +++ b/src/import/chips/ocmb/explorer/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4_explorer.C @@ -22,3 +22,83 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file mrs_load_ddr4_explorer.C +/// @brief Specializations for Explorer's MRS code +/// +// *HWP HWP Owner: Matthew Hickman +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +/// +/// @brief Helper function to determine whether the A17 is needed +/// @param[in] i_target the DIMM target +/// @param[out] o_is_needed boolean whether A17 should be turned on or off +/// @return fapi2::FAPI2_RC_SUCCESS if okay +/// @note Based off of Table 2.8 Proposed DDR4 Full spec update(79-4B) page 28 +/// +template<> +fapi2::ReturnCode is_a17_needed(const fapi2::Target& i_target, + bool& o_is_needed) +{ + uint8_t l_dram_density = 0; + uint8_t l_dram_width = 0; + + FAPI_TRY( mss::attr::get_dram_density( i_target, l_dram_density) ); + FAPI_TRY( mss::attr::get_dram_width( i_target, l_dram_width) ); + + o_is_needed = (l_dram_density == fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G + && l_dram_width == fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4); + FAPI_INF("%s Turning A17 %s", mss::c_str(i_target), o_is_needed ? "on" : "off" ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Helper function to determine whether the A17 is needed +/// @param[in] i_target the MCA target +/// @param[out] o_is_needed boolean whether A17 should be turned on or off +/// @return fapi2::FAPI2_RC_SUCCESS if okay +/// @note Based off of Table 2.8 Proposed DDR4 Full spec update(79-4B) page 28 +/// +template<> +fapi2::ReturnCode is_a17_needed(const fapi2::Target& i_target, + bool& o_is_needed) +{ + o_is_needed = false; + + // Loop over the DIMMs and see if A17 is needed for one of them + // If so, we enable the parity bit in the PHY + for (const auto& l_dimm : mss::find_targets(i_target) ) + { + // Default to not used + // Using temp because we want to OR the two results together. Don't want the false to overwrite + bool l_temp = false; + FAPI_TRY( is_a17_needed( l_dimm, l_temp), "%s Failed to get a17 boolean", mss::c_str(l_dimm) ); + + o_is_needed = o_is_needed | l_temp; + } + + // Returning success here for safety - if we don't have DIMM's we want to return successfully + return fapi2::FAPI2_RC_SUCCESS; +fapi_try_exit: + return fapi2::current_err; +} + +} // ns mss diff --git a/src/import/generic/memory/lib/dimm/ddr4/mrs00.H b/src/import/generic/memory/lib/dimm/ddr4/mrs00.H index 2f78bb6a310..dbc5109e425 100644 --- a/src/import/generic/memory/lib/dimm/ddr4/mrs00.H +++ b/src/import/generic/memory/lib/dimm/ddr4/mrs00.H @@ -22,3 +22,227 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file mrs00.H +/// @brief Run and manage the DDR4 MRS00 loading +/// +// *HWP HWP Owner: Matthew Hickman +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#ifndef _GENERIC_DDR4_MRS00_H_ +#define _GENERIC_DDR4_MRS00_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +namespace ddr4 +{ + +/// +/// @brief Configure the ARR0 of the CCS instruction for mrs00, data object as input +/// @tparam MC mss::mc_type memory controller type +/// @tparam TT traits type defaults to ccsTraits +/// @tparam MRS traits type defaults to mrsTraits +/// @param[in] i_target a fapi2::Target +/// @param[in] i_data an mrs00_data object, filled in +/// @param[in,out] io_inst the instruction to fixup +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = ccsTraits, typename MRS = mrsTraits > +fapi2::ReturnCode mrs00(const fapi2::Target& i_target, + const mrs00_data& i_data, + ccs::instruction_t& io_inst, + const uint64_t i_rank) +{ + // Map from Write Recovery attribute value to bits in the MRS. + // Bit 4 is A13, bits 5:7 are A11:A9 + constexpr uint64_t LOWEST_WR = 10; + constexpr uint64_t WR_COUNT = 17; + constexpr uint8_t wr_map[WR_COUNT] = + { + // 10 12 14 16 18 20 22 24 26 + 0b0000, 0, 0b0001, 0, 0b0010, 0, 0b0011, 0, 0b0100, 0, 0b0101, 0, 0b0111, 0, 0b0110, 0, 0b1000 + }; + + // Map from the CAS Latency attribute to the bits in the MRS + constexpr uint64_t LOWEST_CL = 9; + constexpr uint64_t CL_COUNT = 25; + constexpr uint8_t cl_map[CL_COUNT] = + { + // 9 10 11 12 13 14 15 16 + 0b00000, 0b00001, 0b00010, 0b00011, 0b00100, 0b00101, 0b00110, 0b00111, + // 17, 18 19 20 21 22 23 24 + 0b01101, 0b01000, 0b01110, 0b01001, 0b01111, 0b01010, 0b01100, 0b01011, + // 25 26 27 28 29 30 31 32 33 + 0b10000, 0b10001, 0b10010, 0b10011, 0b10100, 0b10101, 0b10110, 0b10111, 0b11000 + }; + constexpr uint64_t BURST_LENGTH_LEN = 2; + constexpr uint64_t BURST_LENGTH = 7; + + fapi2::buffer l_cl; + fapi2::buffer l_wr; + fapi2::buffer l_burst_length(i_data.iv_burst_length); + + FAPI_ASSERT((i_data.iv_write_recovery >= LOWEST_WR) && (i_data.iv_write_recovery < (LOWEST_WR + WR_COUNT)), + fapi2::MSS_BAD_MR_PARAMETER() + .set_MR_NUMBER(0) + .set_PARAMETER(WRITE_RECOVERY) + .set_PARAMETER_VALUE(i_data.iv_write_recovery) + .set_DIMM_IN_ERROR(i_target), + "Bad value for Write Recovery: %d (%s)", + i_data.iv_write_recovery, + mss::c_str(i_target)); + + FAPI_ASSERT((i_data.iv_cas_latency >= LOWEST_CL) && (i_data.iv_cas_latency < (LOWEST_CL + CL_COUNT)), + fapi2::MSS_BAD_MR_PARAMETER() + .set_MR_NUMBER(0) + .set_PARAMETER(CAS_LATENCY) + .set_PARAMETER_VALUE(i_data.iv_cas_latency) + .set_DIMM_IN_ERROR(i_target), + "Bad value for CAS Latency: %d (%s)", + i_data.iv_cas_latency, + mss::c_str(i_target)); + + mss::swizzle(l_burst_length, io_inst.arr0); + + io_inst.arr0.writeBit(i_data.iv_read_burst_type); + io_inst.arr0.writeBit(i_data.iv_test_mode); + io_inst.arr0.writeBit(i_data.iv_dll_reset); + + // CAS Latency takes a little effort - the bits aren't contiguous + l_cl = cl_map[i_data.iv_cas_latency - LOWEST_CL]; + io_inst.arr0.writeBit(l_cl.getBit<3>()); + io_inst.arr0.writeBit(l_cl.getBit<4>()); + io_inst.arr0.writeBit(l_cl.getBit<5>()); + io_inst.arr0.writeBit(l_cl.getBit<6>()); + io_inst.arr0.writeBit(l_cl.getBit<7>()); + + // Write Recovery/Read to Precharge is not contiguous either. + l_wr = wr_map[i_data.iv_write_recovery - LOWEST_WR]; + io_inst.arr0.writeBit(l_wr.getBit<4>()); + io_inst.arr0.writeBit(l_wr.getBit<5>()); + io_inst.arr0.writeBit(l_wr.getBit<6>()); + io_inst.arr0.writeBit(l_wr.getBit<7>()); + + FAPI_INF("%s MR0: 0x%016llx", mss::c_str(i_target), uint64_t(io_inst.arr0)); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Configure the ARR0 of the CCS instruction for mrs00 +/// @tparam MC mss::mc_type memory controller type +/// @param[in] i_target a fapi2::Target +/// @param[in,out] io_inst the instruction to fixup +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE > +fapi2::ReturnCode mrs00(const fapi2::Target& i_target, + ccs::instruction_t& io_inst, + const uint64_t i_rank) +{ + // Check to make sure our ctor worked ok + mrs00_data l_data( i_target, fapi2::current_err ); + FAPI_TRY( fapi2::current_err, "%s Unable to construct MRS00 data from attributes", mss::c_str(i_target) ); + FAPI_TRY( mrs00(i_target, l_data, io_inst, i_rank) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Helper function for mrs00_decode +/// @tparam MC mss::mc_type memory controller type +/// @tparam TT traits type defaults to ccsTraits +/// @param[in] i_inst the CCS instruction +/// @param[in] i_rank ths rank in question +/// @param[out] o_burst_length the burst length +/// @param[out] o_read_burst_type the burst type +/// @param[out] o_dll_reset the dll reset bit +/// @param[out] o_test_mode the test mode bit +/// @param[out] o_wr_index the write index +/// @param[out] o_cas_latency the cas latency +/// @return FAPI2_RC_SUCCESS iff ok +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = ccsTraits > +fapi2::ReturnCode mrs00_decode_helper(const ccs::instruction_t& i_inst, + const uint64_t i_rank, + uint8_t& o_burst_length, + uint8_t& o_read_burst_type, + uint8_t& o_dll_reset, + uint8_t& o_test_mode, + fapi2::buffer& o_wr_index, + fapi2::buffer& o_cas_latency) +{ + static const uint8_t wr_map[9] = { 10, 12, 14, 16, 18, 20, 24, 22, 26 }; + + o_wr_index = 0; + o_cas_latency = 0; + + i_inst.arr0.extractToRight(o_burst_length); + o_read_burst_type = i_inst.arr0.getBit(); + o_test_mode = i_inst.arr0.getBit(); + o_dll_reset = i_inst.arr0.getBit(); + + // CAS Latency takes a little effort - the bits aren't contiguous + o_cas_latency.writeBit<3>(i_inst.arr0.getBit()); + o_cas_latency.writeBit<4>(i_inst.arr0.getBit()); + o_cas_latency.writeBit<5>(i_inst.arr0.getBit()); + o_cas_latency.writeBit<6>(i_inst.arr0.getBit()); + o_cas_latency.writeBit<7>(i_inst.arr0.getBit()); + + // Write Recovery/Read to Precharge is not contiguous either. + o_wr_index.writeBit<4>(i_inst.arr0.getBit()); + o_wr_index.writeBit<5>(i_inst.arr0.getBit()); + o_wr_index.writeBit<6>(i_inst.arr0.getBit()); + o_wr_index.writeBit<7>(i_inst.arr0.getBit()); + + FAPI_INF("MR0 Decode BL: 0x%x, RBT: 0x%x, CL: 0x%x, TM: 0x%x, DLL_RESET: 0x%x, WR: (0x%x)0x%x", + o_burst_length, o_read_burst_type, uint8_t(o_cas_latency), o_test_mode, o_dll_reset, + wr_map[uint8_t(o_wr_index)], uint8_t(o_wr_index)); + + return fapi2::FAPI2_RC_SUCCESS; +} + +/// +/// @brief Given a CCS instruction which contains address bits with an encoded MRS0, +/// decode and trace the contents +/// @param[in] i_inst the CCS instruction +/// @param[in] i_rank ths rank in question +/// @return FAPI2_RC_SUCCESS iff ok +/// +inline fapi2::ReturnCode mrs00_decode(const ccs::instruction_t& i_inst, + const uint64_t i_rank) +{ + uint8_t l_burst_length = 0; + uint8_t l_read_burst_type = 0; + uint8_t l_dll_reset = 0; + uint8_t l_test_mode = 0; + fapi2::buffer l_wr_index; + fapi2::buffer l_cas_latency; + + return mrs00_decode_helper(i_inst, i_rank, l_burst_length, l_read_burst_type, l_dll_reset, l_test_mode, + l_wr_index, l_cas_latency); +} + +} // ns ddr4 + +} // ns mss +#endif diff --git a/src/import/generic/memory/lib/dimm/ddr4/mrs01.H b/src/import/generic/memory/lib/dimm/ddr4/mrs01.H index d957eeb133a..4fee8341d97 100644 --- a/src/import/generic/memory/lib/dimm/ddr4/mrs01.H +++ b/src/import/generic/memory/lib/dimm/ddr4/mrs01.H @@ -22,3 +22,211 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file mrs01.H +/// @brief Run and manage the DDR4 MRS01 loading +/// +// *HWP HWP Owner: Matt Hickman +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#ifndef _GENERIC_DDR4_MRS01_H_ +#define _GENERIC_DDR4_MRS01_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +namespace ddr4 +{ + +/// +/// @brief Helper function to decode ODIC to the MRS value +/// @tparam MC mss::mc_type memory controller type +/// @param[in] i_target a fapi2::Target +/// @param[in] i_odic_value the value to be decoded for ODIC +/// @param[out] o_odic_decode the MRS decoded value for ODIC +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC > +fapi2::ReturnCode odic_helper(const fapi2::Target& i_target, + const uint8_t i_odic_value, + fapi2::buffer& o_odic_decode); + + +/// +/// @brief Configure the ARR0 of the CCS instruction for mrs01, data object as input +/// @tparam MC mss::mc_type memory controller type +/// @tparam TT traits type defaults to ccsTraits +/// @tparam MRS traits type defaults to mrsTraits +/// @param[in] i_target a fapi2::Target +/// @param[in] i_data an mrs01_data object, filled in +/// @param[in,out] io_inst the instruction to fixup +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = ccsTraits, typename MRS = mrsTraits > +fapi2::ReturnCode mrs01(const fapi2::Target& i_target, + const mrs01_data& i_data, + ccs::instruction_t& io_inst, + const uint64_t i_rank) +{ + constexpr uint64_t ODIC_LENGTH = 2; + constexpr uint64_t ODIC_START_BIT = 7; + constexpr uint64_t ADDITIVE_LATENCE_LENGTH = 2; + constexpr uint64_t ADDITIVE_LATENCE_START_BIT = 7; + constexpr uint64_t RTT_NOM_LENGTH = 3; + constexpr uint64_t RTT_NOM_START_BIT = 7; + + + fapi2::buffer l_additive_latency; + fapi2::buffer l_odic_buffer; + fapi2::buffer l_rtt_nom_buffer; + + // check here to make sure the rank indexes correctly into the attribute array + // It's equivalent to mss::index(i_rank) < l_rtt_nom.size() if C arrays had a .size() method + const auto l_dimm_rank = mss::index(i_rank); + FAPI_ASSERT(l_dimm_rank < MAX_RANK_PER_DIMM, + fapi2::MSS_INVALID_RANK() + .set_PORT_TARGET(mss::find_target(i_target)) + .set_RANK(i_rank) + .set_FUNCTION(generic_ffdc_codes::MRS01_GEN), + "%s MRS01 rank out of bounds rank%u", mss::c_str(i_target), i_rank); + + // ODIC decode + FAPI_TRY(odic_helper(i_target, i_data.iv_odic[l_dimm_rank], l_odic_buffer)); + + // Map from RTT_NOM array to the value in the map + l_rtt_nom_buffer = i_data.iv_rtt_nom[l_dimm_rank]; + + // Print this here as opposed to the MRS01 ctor as we want to see the specific rtt now information + FAPI_INF("%s MR1 rank %d attributes: DLL_ENABLE: 0x%x, ODIC: 0x%x(0x%x), AL: 0x%x, WLE: 0x%x, " + "RTT_NOM:0x%x, TDQS: 0x%x, QOFF: 0x%x", + mss::c_str(i_target), i_rank, i_data.iv_dll_enable, + i_data.iv_odic[l_dimm_rank], uint8_t(l_odic_buffer), + uint8_t(l_additive_latency), i_data.iv_wl_enable, + uint8_t(l_rtt_nom_buffer), i_data.iv_tdqs, i_data.iv_qoff); + + io_inst.arr0.writeBit(i_data.iv_dll_enable); + mss::swizzle(l_odic_buffer, io_inst.arr0); + mss::swizzle(fapi2::buffer + (i_data.iv_additive_latency), io_inst.arr0); + io_inst.arr0.writeBit(i_data.iv_wl_enable); + mss::swizzle(l_rtt_nom_buffer, io_inst.arr0); + io_inst.arr0.writeBit(i_data.iv_tdqs); + io_inst.arr0.writeBit(i_data.iv_qoff); + + FAPI_INF("%s MR1: 0x%016llx", mss::c_str(i_target), uint64_t(io_inst.arr0)); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Configure the ARR0 of the CCS instruction for mrs01 +/// @tparam MC mss::mc_type memory controller type +/// @param[in] i_target a fapi2::Target +/// @param[in,out] io_inst the instruction to fixup +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE > +fapi2::ReturnCode mrs01(const fapi2::Target& i_target, + ccs::instruction_t& io_inst, + const uint64_t i_rank) +{ + // Check to make sure our ctor worked ok + mrs01_data l_data( i_target, fapi2::current_err ); + FAPI_TRY( fapi2::current_err, "%s Unable to construct MRS01 data from attributes", mss::c_str(i_target) ); + FAPI_TRY( mrs01(i_target, l_data, io_inst, i_rank) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Helper function for mrs01_decode +/// @tparam MC mss::mc_type memory controller type +/// @tparam TT traits type defaults to ccsTraits +/// @param[in] i_inst the CCS instruction +/// @param[in] i_rank ths rank in question +/// @param[out] o_dll_enable the dll enable bit +/// @param[out] o_wrl_enable the write leveling enable bit +/// @param[out] o_tdqs the tdqs enable bit +/// @param[out] o_qoff the qoff bit +/// @param[out] o_odic the output driver impedance control setting +/// @param[out] o_additive_latency the additive latency setting +/// @param[out] o_rtt_nom the rtt_nom setting +/// @return FAPI2_RC_SUCCESS iff ok +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = ccsTraits > +fapi2::ReturnCode mrs01_decode_helper(const ccs::instruction_t& i_inst, + const uint64_t i_rank, + uint8_t& o_dll_enable, + uint8_t& o_wrl_enable, + uint8_t& o_tdqs, + uint8_t& o_qoff, + fapi2::buffer& o_odic, + fapi2::buffer& o_additive_latency, + fapi2::buffer& o_rtt_nom) +{ + o_odic = 0; + o_additive_latency = 0; + o_rtt_nom = 0; + + o_dll_enable = i_inst.arr0.getBit(); + o_wrl_enable = i_inst.arr0.getBit(); + o_tdqs = i_inst.arr0.getBit(); + o_qoff = i_inst.arr0.getBit(); + + mss::swizzle<6, 2, TT::A2>(i_inst.arr0, o_odic); + mss::swizzle<6, 2, TT::A4>(i_inst.arr0, o_additive_latency); + mss::swizzle<5, 3, TT::A10>(i_inst.arr0, o_rtt_nom); + + FAPI_INF("MR1 rank %d decode: DLL_ENABLE: 0x%x, ODIC: 0x%x, AL: 0x%x, WLE: 0x%x, " + "RTT_NOM: 0x%x, TDQS: 0x%x, QOFF: 0x%x", + i_rank, o_dll_enable, uint8_t(o_odic), uint8_t(o_additive_latency), + o_wrl_enable, uint8_t(o_rtt_nom), o_tdqs, o_qoff); + + return fapi2::FAPI2_RC_SUCCESS; +} + +/// +/// @brief Given a CCS instruction which contains address bits with an encoded MRS1, +/// decode and trace the contents +/// @param[in] i_inst the CCS instruction +/// @param[in] i_rank ths rank in question +/// @return FAPI2_RC_SUCCESS iff ok +/// +inline fapi2::ReturnCode mrs01_decode(const ccs::instruction_t& i_inst, + const uint64_t i_rank) +{ + uint8_t l_dll_enable = 0; + uint8_t l_wrl_enable = 0; + uint8_t l_tdqs = 0; + uint8_t l_qoff = 0; + fapi2::buffer l_odic; + fapi2::buffer l_additive_latency; + fapi2::buffer l_rtt_nom; + + return mrs01_decode_helper(i_inst, i_rank, l_dll_enable, l_wrl_enable, l_tdqs, l_qoff, l_odic, + l_additive_latency, l_rtt_nom); +} + + +} // ns ddr4 + +} // ns mss +#endif diff --git a/src/import/generic/memory/lib/dimm/ddr4/mrs02.H b/src/import/generic/memory/lib/dimm/ddr4/mrs02.H index 9b0afa9281d..a6b4fa1a16c 100644 --- a/src/import/generic/memory/lib/dimm/ddr4/mrs02.H +++ b/src/import/generic/memory/lib/dimm/ddr4/mrs02.H @@ -22,3 +22,190 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file mrs02.H +/// @brief Run and manage the DDR4 MRS02 loading +/// +// *HWP HWP Owner: Matt Hickman +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#ifndef _GENERIC_DDR4_MRS02_H_ +#define _GENERIC_DDR4_MRS02_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +namespace ddr4 +{ + +/// +/// @brief Configure the ARR0 of the CCS instruction for mrs02, data object as input +/// @tparam MC mss::mc_type memory controller type +/// @tparam TT traits type defaults to ccsTraits +/// @tparam MRS traits type defaults to mrsTraits +/// @param[in] i_target a fapi2::Target +/// @param[in] i_data an mrs02_data object, filled in +/// @param[in,out] io_inst the instruction to fixup +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = ccsTraits, typename MRS = mrsTraits > +fapi2::ReturnCode mrs02(const fapi2::Target& i_target, + const mrs02_data& i_data, + ccs::instruction_t& io_inst, + const uint64_t i_rank) +{ + constexpr uint64_t CWL_LENGTH = 3; + constexpr uint64_t CWL_START = 7; + constexpr uint64_t LPASR_LENGTH = 2; + constexpr uint64_t LPASR_START = 7; + constexpr uint64_t RTT_WR_LENGTH = 3; + constexpr uint64_t RTT_WR_START = 7; + + // Index this by subtracting 9 from the CWL attribute value. The table maps CWL attribute value + // (in clks) to the bit setting in MR2. See the table in the JEDEC spec for the mapping. + constexpr uint64_t LOWEST_CWL = 9; + constexpr uint64_t CWL_COUNT = 12; + // 9 10 11 12 14 16 18 20 + constexpr uint8_t cwl_map[CWL_COUNT] = { 0b000, 0b001, 0b010, 0b011, 0, 0b100, 0, 0b101, 0, 0b110, 0, 0b111 }; + + fapi2::buffer l_cwl_buffer; + + // Ensures our rank is inbounds for the attribute array + const auto l_dimm_rank = mss::index(i_rank); + FAPI_ASSERT(l_dimm_rank < MAX_RANK_PER_DIMM, + fapi2::MSS_INVALID_RANK() + .set_PORT_TARGET(mss::find_target(i_target)) + .set_RANK(i_rank) + .set_FUNCTION(generic_ffdc_codes::MRS01_GEN), + "%s MRS01 rank out of bounds rank%u", mss::c_str(i_target), i_rank); + + { + fapi2::buffer l_rtt_wr_buffer = i_data.iv_dram_rtt_wr[l_dimm_rank]; + + FAPI_ASSERT((i_data.iv_cwl >= LOWEST_CWL) && (i_data.iv_cwl < (LOWEST_CWL + CWL_COUNT)), + fapi2::MSS_BAD_MR_PARAMETER() + .set_MR_NUMBER(2) + .set_PARAMETER(CAS_WRITE_LATENCY) + .set_PARAMETER_VALUE(i_data.iv_cwl) + .set_DIMM_IN_ERROR(i_target), + "Bad value for CWL: %d (%s)", i_data.iv_cwl, mss::c_str(i_target)); + + l_cwl_buffer = cwl_map[i_data.iv_cwl - LOWEST_CWL]; + + + // Printed here as opposed to the ctor as it uses the rank information + FAPI_INF("%s MR2 rank %d attributes: LPASR: 0x%x, CWL: 0x%x, RTT_WR: 0x%x(0x%x), WRITE_CRC: 0x%x", + mss::c_str(i_target), i_rank, uint8_t(i_data.iv_lpasr), i_data.iv_cwl, + uint8_t(l_cwl_buffer), uint8_t(l_rtt_wr_buffer), i_data.iv_write_crc); + + mss::swizzle(l_cwl_buffer, io_inst.arr0); + + mss::swizzle(fapi2::buffer(i_data.iv_lpasr), io_inst.arr0); + + mss::swizzle(l_rtt_wr_buffer, io_inst.arr0); + + io_inst.arr0.writeBit(i_data.iv_write_crc); + + FAPI_INF("MR2: 0x%016llx", uint64_t(io_inst.arr0)); + } + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Configure the ARR0 of the CCS instruction for mrs02 +/// @tparam MC mss::mc_type memory controller type +/// @param[in] i_target a fapi2::Target +/// @param[in,out] io_inst the instruction to fixup +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE > +fapi2::ReturnCode mrs02(const fapi2::Target& i_target, + ccs::instruction_t& io_inst, + const uint64_t i_rank) +{ + // Check to make sure our ctor worked ok + mrs02_data l_data( i_target, fapi2::current_err ); + FAPI_TRY( fapi2::current_err, + "%s Unable to construct MRS02 data from attributes", + mss::c_str(i_target) ); + FAPI_TRY( mrs02(i_target, l_data, io_inst, i_rank) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Helper function for mrs02_decode +/// @tparam MC mss::mc_type memory controller type +/// @tparam TT traits type defaults to ccsTraits +/// @param[in] i_inst the CCS instruction +/// @param[in] i_rank the rank in question +/// @param[out] o_write_crc the write crc bit +/// @param[out] o_lpasr the low power array self refresh setting +/// @param[out] o_cwl the cas write latency setting +/// @param[out] o_rtt_wr the rtt_wr setting +/// @return FAPI2_RC_SUCCESS iff ok +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = ccsTraits > +fapi2::ReturnCode mrs02_decode_helper(const ccs::instruction_t& i_inst, + const uint64_t i_rank, + uint8_t& o_write_crc, + fapi2::buffer& o_lpasr, + fapi2::buffer& o_cwl, + fapi2::buffer& o_rtt_wr) +{ + o_lpasr = 0; + o_cwl = 0; + o_rtt_wr = 0; + + o_write_crc = i_inst.arr0.getBit(); + mss::swizzle<5, 3, TT::A5>(i_inst.arr0, o_cwl); + mss::swizzle<6, 2, TT::A7>(i_inst.arr0, o_lpasr); + mss::swizzle<5, 3, TT::A11>(i_inst.arr0, o_rtt_wr); + + FAPI_INF("MR2 rank %d deocode: LPASR: 0x%x, CWL: 0x%x, RTT_WR: 0x%x, WRITE_CRC: 0x%x", + i_rank, uint8_t(o_lpasr), uint8_t(o_cwl), uint8_t(o_rtt_wr), o_write_crc); + + return fapi2::FAPI2_RC_SUCCESS; +} + +/// +/// @brief Given a CCS instruction which contains address bits with an encoded MRS2, +/// decode and trace the contents +/// @param[in] i_inst the CCS instruction +/// @param[in] i_rank ths rank in question +/// @return FAPI2_RC_SUCCESS iff ok +/// +inline fapi2::ReturnCode mrs02_decode(const ccs::instruction_t& i_inst, + const uint64_t i_rank) +{ + uint8_t l_write_crc = 0; + fapi2::buffer l_lpasr; + fapi2::buffer l_cwl; + fapi2::buffer l_rtt_wr; + + return mrs02_decode_helper(i_inst, i_rank, l_write_crc, l_lpasr, l_cwl, l_rtt_wr); +} + +} // ns ddr4 + +} // ns mss +#endif diff --git a/src/import/generic/memory/lib/dimm/ddr4/mrs03.H b/src/import/generic/memory/lib/dimm/ddr4/mrs03.H index fff30d2b199..c5999961b5c 100644 --- a/src/import/generic/memory/lib/dimm/ddr4/mrs03.H +++ b/src/import/generic/memory/lib/dimm/ddr4/mrs03.H @@ -22,3 +22,197 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file mrs03.H +/// @brief Run and manage mrs03 +/// +// *HWP HWP Owner: Matt Hickman +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#ifndef _GENERIC_DDR4_MRS03_H_ +#define _GENERIC_DDR4_MRS03_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +namespace ddr4 +{ +enum swizzle : uint64_t +{ + MPR_PAGE_LENGTH = 2, + MPR_PAGE_START = 7, + FINE_REFRESH_LENGTH = 3, + FINE_REFRESH_START = 7, + CRC_WR_LATENCY_LENGTH = 2, + CRC_WR_LATENCY_START = 7, + READ_FORMAT_LENGTH = 2, + READ_FORMAT_START = 7, +}; + +/// +/// @brief Helper function to decode CRC WR latency to the MRS value +/// @tparam MC mss::mc_type memory controller type +/// @param[in] i_target a fapi2::Target +/// @param[in] i_value the value to be decoded +/// @param[out] o_decode the MRS decoded value +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC > +fapi2::ReturnCode crc_wr_latency_helper(const fapi2::Target& i_target, + const uint8_t i_value, + fapi2::buffer& o_decode); + +/// +/// @brief Configure the ARR0 of the CCS instruction for mrs03, data object as input +/// @tparam MC mss::mc_type memory controller type +/// @tparam TT traits type defaults to ccsTraits +/// @tparam MRS traits type defaults to mrsTraits +/// @param[in] i_target a fapi2::Target +/// @param[in] i_data an mrs00_data object, filled in +/// @param[in,out] io_inst the instruction to fixup +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = ccsTraits, typename MRS = mrsTraits > +fapi2::ReturnCode mrs03(const fapi2::Target& i_target, + const mrs03_data& i_data, + ccs::instruction_t& io_inst, + const uint64_t i_rank) +{ + // Decode CRC WR latency + fapi2::buffer l_crc_wr_latency_buffer; + FAPI_TRY(crc_wr_latency_helper(i_target, i_data.iv_crc_wr_latency, l_crc_wr_latency_buffer)); + + mss::swizzle(fapi2::buffer(i_data.iv_mpr_page), io_inst.arr0); + io_inst.arr0.writeBit(i_data.iv_mpr_mode); + io_inst.arr0.writeBit(i_data.iv_geardown); + io_inst.arr0.writeBit(i_data.iv_pda); + io_inst.arr0.writeBit(i_data.iv_temp_readout); + + mss::swizzle(fapi2::buffer(i_data.iv_fine_refresh), + io_inst.arr0); + mss::swizzle(l_crc_wr_latency_buffer, io_inst.arr0); + mss::swizzle(fapi2::buffer(i_data.iv_read_format), + io_inst.arr0); + + FAPI_INF("%s MR3: 0x%016llx", mss::c_str(i_target), uint64_t(io_inst.arr0)); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Configure the ARR0 of the CCS instruction for mrs03 +/// @tparam MC mss::mc_type memory controller type +/// @param[in] i_target a fapi2::Target +/// @param[in,out] io_inst the instruction to fixup +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE > +fapi2::ReturnCode mrs03(const fapi2::Target& i_target, + ccs::instruction_t& io_inst, + const uint64_t i_rank) +{ + // Check to make sure our ctor worked ok + mrs03_data l_data( i_target, fapi2::current_err ); + FAPI_TRY( fapi2::current_err, + "%s Unable to construct MRS03 data from attributes", + mss::c_str(i_target) ); + FAPI_TRY( mrs03(i_target, l_data, io_inst, i_rank) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Helper function for mrs03_decode +/// @tparam MC mss::mc_type memory controller type +/// @tparam TT traits type defaults to ccsTraits +/// @param[in] i_inst the CCS instruction +/// @param[in] i_rank the rank in question +/// @param[out] o_mpr_mode the mpr operation setting +/// @param[out] o_geardown the geardown mode setting +/// @param[out] o_pda the per dram addressability setting +/// @param[out] o_temp_readout the temperature sensor readout setting +/// @param[out] o_mpr_page the mpr page selection +/// @param[out] o_fine_refresh the fine granularity refresh mode setting +/// @param[out] o_crc_wr_latency_buffer the write cmd latency when crc and dm are enabled +/// @param[out] o_read_fromat the mpr read format setting +/// @return FAPI2_RC_SUCCESS iff ok +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = ccsTraits > +fapi2::ReturnCode mrs03_decode_helper(const ccs::instruction_t& i_inst, + const uint64_t i_rank, + uint8_t& o_mpr_mode, + uint8_t& o_geardown, + uint8_t& o_pda, + uint8_t& o_temp_readout, + fapi2::buffer& o_mpr_page, + fapi2::buffer& o_fine_refresh, + fapi2::buffer& o_crc_wr_latency_buffer, + fapi2::buffer& o_read_format) +{ + o_mpr_page = 0; + o_fine_refresh = 0; + o_crc_wr_latency_buffer = 0; + o_read_format = 0; + + o_mpr_mode = i_inst.arr0.getBit(); + o_geardown = i_inst.arr0.getBit(); + o_pda = i_inst.arr0.getBit(); + o_temp_readout = i_inst.arr0.getBit(); + + mss::swizzle<6, 2, TT::A1>(i_inst.arr0, o_mpr_page); + mss::swizzle<5, 3, TT::A8>(i_inst.arr0, o_fine_refresh); + mss::swizzle<6, 2, TT::A10>(i_inst.arr0, o_crc_wr_latency_buffer); + mss::swizzle<6, 2, TT::A12>(i_inst.arr0, o_read_format); + + FAPI_INF("MR3 rank %d decode: MPR_MODE: 0x%x, MPR_PAGE: 0x%x, GD: 0x%x, PDA: 0x%x, " + "TEMP: 0x%x FR: 0x%x, CRC_WL: 0x%x, RF: 0x%x", i_rank, + uint8_t(o_mpr_mode), o_mpr_page, o_geardown, o_pda, uint8_t(o_temp_readout), + uint8_t(o_fine_refresh), uint8_t(o_crc_wr_latency_buffer), uint8_t(o_read_format)); + + return fapi2::FAPI2_RC_SUCCESS; +} + +/// +/// @brief Given a CCS instruction which contains address bits with an encoded MRS3, +/// decode and trace the contents +/// @param[in] i_inst the CCS instruction +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff ok +/// +inline fapi2::ReturnCode mrs03_decode(const ccs::instruction_t& i_inst, + const uint64_t i_rank) +{ + uint8_t l_mpr_mode = 0; + uint8_t l_geardown = 0; + uint8_t l_pda = 0; + uint8_t l_temp_readout = 0; + fapi2::buffer l_mpr_page; + fapi2::buffer l_fine_refresh; + fapi2::buffer l_crc_wr_latency_buffer; + fapi2::buffer l_read_format; + + return mrs03_decode_helper(i_inst, i_rank, l_mpr_mode, l_geardown, l_pda, l_temp_readout, + l_mpr_page, l_fine_refresh, l_crc_wr_latency_buffer, l_read_format); +} + +} // ns ddr4 +} // ns mss +#endif diff --git a/src/import/generic/memory/lib/dimm/ddr4/mrs04.H b/src/import/generic/memory/lib/dimm/ddr4/mrs04.H index 221dfeaf43f..c9bc6f78d2e 100644 --- a/src/import/generic/memory/lib/dimm/ddr4/mrs04.H +++ b/src/import/generic/memory/lib/dimm/ddr4/mrs04.H @@ -22,3 +22,200 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file mrs04.H +/// @brief Run and manage the DDR4 MRS04 loading +/// +// *HWP HWP Owner: Matthew Hickman +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#ifndef _GENERIC_DDR4_MRS04_H_ +#define _GENERIC_DDR4_MRS04_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +namespace ddr4 +{ + +/// +/// @brief Configure the ARR0 of the CCS instruction for mrs04, data object as input +/// @tparam MC mss::mc_type memory controller type +/// @tparam TT traits type defaults to ccsTraits +/// @tparam MRS traits type defaults to mrsTraits +/// @param[in] i_target a fapi2::Target +/// @param[in] i_data an mrs04_data object, filled in +/// @param[in,out] io_inst the instruction to fixup +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = ccsTraits, typename MRS = mrsTraits > +fapi2::ReturnCode mrs04(const fapi2::Target& i_target, + const mrs04_data& i_data, + ccs::instruction_t& io_inst, + const uint64_t i_rank) +{ + constexpr uint64_t CS_CMD_LATENCY_LENGTH = 3; + constexpr uint64_t CS_CMD_LATENCY_START = 7; + + constexpr uint64_t CS_CMD_COUNT = 9; + // 0 3 4 5 6 8 + constexpr uint8_t cs_cmd_latency_map[CS_CMD_COUNT] = { 0b000, 0, 0, 0b001, 0b010, 0b011, 0b100, 0, 0b101 }; + + fapi2::buffer l_cs_cmd_latency_buffer; + + FAPI_ASSERT( (i_data.iv_cs_cmd_latency < CS_CMD_COUNT), + fapi2::MSS_BAD_MR_PARAMETER() + .set_MR_NUMBER(4) + .set_PARAMETER(CS_CMD_LATENCY) + .set_PARAMETER_VALUE(i_data.iv_cs_cmd_latency) + .set_DIMM_IN_ERROR(i_target), + "Bad value for CS to CMD/ADDR Latency: %d (%s)", i_data.iv_cs_cmd_latency, mss::c_str(i_target)); + + l_cs_cmd_latency_buffer = cs_cmd_latency_map[i_data.iv_cs_cmd_latency]; + + io_inst.arr0.writeBit(i_data.iv_max_pd_mode); + io_inst.arr0.writeBit(i_data.iv_temp_refresh_range); + io_inst.arr0.writeBit(i_data.iv_temp_ref_mode); + io_inst.arr0.writeBit(i_data.iv_vref_mon); + io_inst.arr0.writeBit(i_data.iv_soft_ppr); + + mss::swizzle(l_cs_cmd_latency_buffer, io_inst.arr0); + io_inst.arr0.writeBit(i_data.iv_ref_abort); + io_inst.arr0.writeBit(i_data.iv_rd_pre_train_mode); + io_inst.arr0.writeBit(i_data.iv_rd_preamble); + io_inst.arr0.writeBit(i_data.iv_wr_preamble); + io_inst.arr0.writeBit(i_data.iv_ppr); + + FAPI_INF("%s MR4: 0x%016llx", mss::c_str(i_target), uint64_t(io_inst.arr0)); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Configure the ARR0 of the CCS instruction for mrs04 +/// @tparam MC mss::mc_type memory controller type +/// @param[in] i_target a fapi2::Target +/// @param[in,out] io_inst the instruction to fixup +/// @param[in] i_rank thes rank in question +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE > +fapi2::ReturnCode mrs04(const fapi2::Target& i_target, + ccs::instruction_t& io_inst, + const uint64_t i_rank) +{ + // Check to make sure our ctor worked ok + mrs04_data l_data( i_target, fapi2::current_err ); + FAPI_TRY( fapi2::current_err, "%s Unable to construct MRS04 data from attributes", mss::c_str(i_target) ); + FAPI_TRY( mrs04(i_target, l_data, io_inst, i_rank) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Helper function for mrs04_decode +/// @tparam MC mss::mc_type memory controller type +/// @tparam TT traits type defaults to ccsTraits +/// @param[in] i_inst the CCS instruction +/// @param[in] i_rank the rank in question +/// @param[out] o_max_pd_mode the maximum power down mode setting +/// @param[out] o_temp_refresh_range the temperature controlled refresh range setting +/// @param[out] o_temp_ref_mode the temperature controlled refresh mode setting +/// @param[out] o_vref_mon the internal vref monitor setting +/// @param[out] o_ref_abort the self refresh abort setting +/// @param[out] o_rd_pre_train_mode the read preamble training mode setting +/// @param[out] o_rd_preamble the read preamble setting +/// @param[out] o_wr_preamble the write preamble setting +/// @param[out] o_ppr the ppr setting +/// @param[out] o_cs_cmd_latency_buffer the cs to cmd/addr latency mode setting +/// @return FAPI2_RC_SUCCESS iff ok +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = ccsTraits > +fapi2::ReturnCode mrs04_decode_helper(const ccs::instruction_t& i_inst, + const uint64_t i_rank, + uint8_t& o_max_pd_mode, + uint8_t& o_temp_refresh_range, + uint8_t& o_temp_ref_mode, + uint8_t& o_vref_mon, + uint8_t& o_ref_abort, + uint8_t& o_rd_pre_train_mode, + uint8_t& o_rd_preamble, + uint8_t& o_wr_preamble, + uint8_t& o_ppr, + uint8_t& o_soft_ppr, + fapi2::buffer& o_cs_cmd_latency_buffer) +{ + o_max_pd_mode = i_inst.arr0.getBit(); + o_temp_refresh_range = i_inst.arr0.getBit(); + o_temp_ref_mode = i_inst.arr0.getBit(); + o_vref_mon = i_inst.arr0.getBit(); + o_soft_ppr = i_inst.arr0.getBit(); + + o_cs_cmd_latency_buffer = 0; + mss::swizzle<5, 3, TT::A8>(i_inst.arr0, o_cs_cmd_latency_buffer); + + o_ref_abort = i_inst.arr0.getBit(); + o_rd_pre_train_mode = i_inst.arr0.getBit(); + o_rd_preamble = i_inst.arr0.getBit(); + o_wr_preamble = i_inst.arr0.getBit(); + o_ppr = i_inst.arr0.getBit(); + + FAPI_INF("MR4 rank %d decode: MAX_PD: 0x%x, TEMP_REFRESH_RANGE: 0x%x, TEMP_REF_MODE: 0x%x " + "VREF_MON: 0x%x, CSL: 0x%x, REF_ABORT: 0x%x, RD_PTM: 0x%x, RD_PRE: 0x%x, " + "WR_PRE: 0x%x, PPR: 0x%x", + i_rank, o_max_pd_mode, o_temp_refresh_range, o_temp_ref_mode, + o_vref_mon, uint8_t(o_cs_cmd_latency_buffer), o_ref_abort, + o_rd_pre_train_mode, o_rd_preamble, o_wr_preamble, o_ppr); + + return fapi2::FAPI2_RC_SUCCESS; +} + +/// +/// @brief Given a CCS instruction which contains address bits with an encoded MRS4, +/// decode and trace the contents +/// @param[in] i_inst the CCS instruction +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff ok +/// +inline fapi2::ReturnCode mrs04_decode(const ccs::instruction_t& i_inst, + const uint64_t i_rank) +{ + uint8_t l_max_pd_mode = 0; + uint8_t l_temp_refresh_range = 0; + uint8_t l_temp_ref_mode = 0; + uint8_t l_vref_mon = 0; + uint8_t l_ref_abort = 0; + uint8_t l_rd_pre_train_mode = 0; + uint8_t l_rd_preamble = 0; + uint8_t l_wr_preamble = 0; + uint8_t l_ppr = 0; + uint8_t l_soft_ppr = 0; + + fapi2::buffer l_cs_cmd_latency_buffer; + + return mrs04_decode_helper(i_inst, i_rank, l_max_pd_mode, l_temp_refresh_range, l_temp_ref_mode, + l_vref_mon, l_ref_abort, l_rd_pre_train_mode, l_rd_preamble, + l_wr_preamble, l_ppr, l_soft_ppr, l_cs_cmd_latency_buffer); +} + + +} // ns ddr4 +} // ns mss +#endif diff --git a/src/import/generic/memory/lib/dimm/ddr4/mrs05.H b/src/import/generic/memory/lib/dimm/ddr4/mrs05.H index ae1a00ec5f8..6d9b7a5da8d 100644 --- a/src/import/generic/memory/lib/dimm/ddr4/mrs05.H +++ b/src/import/generic/memory/lib/dimm/ddr4/mrs05.H @@ -22,3 +22,211 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file mrs05.H +/// @brief Run and manage the DDR4 MRS05 loading +/// +// *HWP HWP Owner: Matthew Hickman +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#ifndef _GENERIC_DDR4_MRS05_H_ +#define _GENERIC_DDR4_MRS05_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +namespace ddr4 +{ + +/// +/// @brief Configure the ARR0 of the CCS instruction for mrs05, data object as input +/// @tparam MC mss::mc_type memory controller type +/// @tparam TT traits type defaults to ccsTraits +/// @tparam MRS traits type defaults to mrsTraits +/// @param[in] i_target a fapi2::Target +/// @param[in] i_data an mrs05_data object, filled in +/// @param[in,out] io_inst the instruction to fixup +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = ccsTraits, typename MRS = mrsTraits > +fapi2::ReturnCode mrs05(const fapi2::Target& i_target, + const mrs05_data& i_data, + ccs::instruction_t& io_inst, + const uint64_t i_rank) +{ + constexpr uint64_t CA_PARITY_LATENCY_LENGTH = 3; + constexpr uint64_t CA_PARITY_LATENCY_START = 7; + constexpr uint64_t RTT_PARK_LENGTH = 3; + constexpr uint64_t RTT_PARK_START = 7; + + constexpr uint64_t CA_PARITY_COUNT = 9; + // 0 4 5 6 8 + constexpr uint8_t ca_parity_latency_map[CA_PARITY_COUNT] = { 0b000, 0, 0, 0, 0b001, 0b010, 0b011, 0, 0b100 }; + + fapi2::buffer l_ca_parity_latency_buffer; + + fapi2::buffer l_rtt_park_buffer = i_data.iv_rtt_park[mss::index(i_rank)]; + + //check here to make sure the rank indexes correctly into the attribute array + FAPI_ASSERT( (mss::index(i_rank) < MAX_RANK_PER_DIMM), + fapi2::MSS_BAD_MR_PARAMETER() + .set_MR_NUMBER(5) + .set_PARAMETER(RANK) + .set_PARAMETER_VALUE(i_rank) + .set_DIMM_IN_ERROR(i_target), + "Bad value for RTT park: %d (%s)", i_rank, mss::c_str(i_target)); + + FAPI_ASSERT( (i_data.iv_ca_parity_latency < CA_PARITY_COUNT), + fapi2::MSS_BAD_MR_PARAMETER() + .set_MR_NUMBER(5) + .set_PARAMETER(CA_PARITY_LATENCY) + .set_PARAMETER_VALUE(i_data.iv_ca_parity_latency) + .set_DIMM_IN_ERROR(i_target), + "Bad value for CA parity latency: %d (%s)", i_data.iv_ca_parity_latency, mss::c_str(i_target)); + + l_ca_parity_latency_buffer = ca_parity_latency_map[i_data.iv_ca_parity_latency]; + + FAPI_INF("%s MR5 rank %d attributes: CAPL: 0x%x(0x%x), CRC_EC: 0x%x, CA_PES: 0x%x, ODT_IB: 0x%x " + "RTT_PARK: 0x%x, CAP: 0x%x, DM: 0x%x, WDBI: 0x%x, RDBI: 0x%x", + mss::c_str(i_target), i_rank, i_data.iv_ca_parity_latency, uint8_t(l_ca_parity_latency_buffer), + i_data.iv_crc_error_clear, i_data.iv_ca_parity_error_status, i_data.iv_odt_input_buffer, + uint8_t(l_rtt_park_buffer), i_data.iv_ca_parity, + i_data.iv_data_mask, i_data.iv_write_dbi, i_data.iv_read_dbi); + + mss::swizzle(l_ca_parity_latency_buffer, io_inst.arr0); + io_inst.arr0.writeBit(i_data.iv_crc_error_clear); + io_inst.arr0.writeBit(i_data.iv_ca_parity_error_status); + io_inst.arr0.writeBit(i_data.iv_odt_input_buffer); + mss::swizzle(l_rtt_park_buffer, io_inst.arr0); + io_inst.arr0.writeBit(i_data.iv_ca_parity); + io_inst.arr0.writeBit(i_data.iv_data_mask); + io_inst.arr0.writeBit(i_data.iv_write_dbi); + io_inst.arr0.writeBit(i_data.iv_read_dbi); + + FAPI_INF("%s MR5: 0x%016llx", mss::c_str(i_target), uint64_t(io_inst.arr0)); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Configure the ARR0 of the CCS instruction for mrs05 +/// @tparam MC mss::mc_type memory controller type +/// @param[in] i_target a fapi2::Target +/// @param[in,out] io_inst the instruction to fixup +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE > +fapi2::ReturnCode mrs05(const fapi2::Target& i_target, + ccs::instruction_t& io_inst, + const uint64_t i_rank) +{ + // Check to make sure our ctor worked ok + mrs05_data l_data( i_target, fapi2::current_err ); + FAPI_TRY( fapi2::current_err, "%s Unable to construct MRS05 data from attributes", mss::c_str(i_target) ); + FAPI_TRY( mrs05(i_target, l_data, io_inst, i_rank) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Helper function for mrs05_decode +/// @tparam MC mss::mc_type memory controller type +/// @tparam TT traits type defaults to ccsTraits +/// @param[in] i_inst the CCS instruction +/// @param[in] i_rank the rank in question +/// @param[out] o_crc_error_clear the crc error clear setting +/// @param[out] o_ca_parity_error_status the c/a parity error status +/// @param[out] o_odt_input_buffer the odt input buffer during power down mode setting +/// @param[out] o_ca_parity the c/a parity persistent error setting +/// @param[out] o_data_mask the data mask setting +/// @param[out] o_write_dbi the write dbi setting +/// @param[out] o_read_dbi the read dbi setting +/// @param[out] o_ca_parity_latency_buffer the c/a parity latency mode setting +/// @param[out] o_rtt_park_buffer the rtt_park setting +/// @return FAPI2_RC_SUCCESS iff ok +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = ccsTraits > +fapi2::ReturnCode mrs05_decode_helper(const ccs::instruction_t& i_inst, + const uint64_t i_rank, + uint8_t& o_crc_error_clear, + uint8_t& o_ca_parity_error_status, + uint8_t& o_odt_input_buffer, + uint8_t& o_ca_parity, + uint8_t& o_data_mask, + uint8_t& o_write_dbi, + uint8_t& o_read_dbi, + fapi2::buffer& o_ca_parity_latency_buffer, + fapi2::buffer& o_rtt_park_buffer) +{ + o_ca_parity_latency_buffer = 0; + o_rtt_park_buffer = 0; + + mss::swizzle<5, 3, TT::A2>(i_inst.arr0, o_ca_parity_latency_buffer); + mss::swizzle<5, 3, TT::A8>(i_inst.arr0, o_rtt_park_buffer); + + o_crc_error_clear = i_inst.arr0.getBit(); + o_ca_parity_error_status = i_inst.arr0.getBit(); + o_odt_input_buffer = i_inst.arr0.getBit(); + + o_ca_parity = i_inst.arr0.getBit(); + o_data_mask = i_inst.arr0.getBit(); + o_write_dbi = i_inst.arr0.getBit(); + o_read_dbi = i_inst.arr0.getBit(); + + FAPI_INF("MR5 rank %d decode: CAPL: 0x%x, CRC_EC: 0x%x, CA_PES: 0x%x, ODT_IB: 0x%x " + "RTT_PARK: 0x%x, CAP: 0x%x, DM: 0x%x, WDBI: 0x%x, RDBI: 0x%x", + i_rank, uint8_t(o_ca_parity_latency_buffer), o_crc_error_clear, o_ca_parity_error_status, + o_odt_input_buffer, uint8_t(o_rtt_park_buffer), o_ca_parity, o_data_mask, + o_write_dbi, o_read_dbi); + + return fapi2::FAPI2_RC_SUCCESS; +} + +/// +/// @brief Given a CCS instruction which contains address bits with an encoded MRS5, +/// decode and trace the contents +/// @param[in] i_inst the CCS instruction +/// @param[in] i_rank ths rank in question +/// @return FAPI2_RC_SUCCESS iff ok +/// +inline fapi2::ReturnCode mrs05_decode(const ccs::instruction_t& i_inst, + const uint64_t i_rank) +{ + fapi2::buffer l_ca_parity_latency_buffer; + fapi2::buffer l_rtt_park_buffer; + + uint8_t l_crc_error_clear = 0; + uint8_t l_ca_parity_error_status = 0; + uint8_t l_odt_input_buffer = 0; + uint8_t l_ca_parity = 0; + uint8_t l_data_mask = 0; + uint8_t l_write_dbi = 0; + uint8_t l_read_dbi = 0; + + return mrs05_decode_helper(i_inst, i_rank, l_crc_error_clear, l_ca_parity_error_status, + l_odt_input_buffer, l_ca_parity, l_data_mask, l_write_dbi, + l_read_dbi, l_ca_parity_latency_buffer, l_rtt_park_buffer); +} + + +} // ns ddr4 +} // ns mss +#endif diff --git a/src/import/generic/memory/lib/dimm/ddr4/mrs06.H b/src/import/generic/memory/lib/dimm/ddr4/mrs06.H index 0ff106aaee8..cc5a8c6f986 100644 --- a/src/import/generic/memory/lib/dimm/ddr4/mrs06.H +++ b/src/import/generic/memory/lib/dimm/ddr4/mrs06.H @@ -22,3 +22,172 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ + +/// +/// @file mrs06.H +/// @brief Run and manage the DDR4 MRS06 loading +/// +// *HWP HWP Owner: Matthew Hickman +// *HWP HWP Backup: Andre Marin +// *HWP Team: Memory +// *HWP Level: 3 +// *HWP Consumed by: FSP:HB + +#ifndef _GENERIC_DDR4_MRS06_H_ +#define _GENERIC_DDR4_MRS06_H_ + +#include +#include +#include +#include +#include +#include +#include + +namespace mss +{ + +namespace ddr4 +{ + +/// +/// @brief Configure the ARR0 of the CCS instruction for mrs06, data object as input +/// @tparam MC mss::mc_type memory controller type +/// @tparam TT traits type defaults to ccsTraits +/// @tparam MRS traits type defaults to mrsTraits +/// @param[in] i_target a fapi2::Target +/// @param[in] i_data an mrs06_data object, filled in +/// @param[in,out] io_inst the instruction to fixup +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = ccsTraits, typename MRS = mrsTraits > +fapi2::ReturnCode mrs06(const fapi2::Target& i_target, + const mrs06_data& i_data, + ccs::instruction_t& io_inst, + const uint64_t i_rank) +{ + constexpr uint64_t VREFDQ_TRAIN_LENGTH = 6; + constexpr uint64_t VREFDQ_TRAIN_START = 7; + constexpr uint64_t TCCD_L_LENGTH = 3; + constexpr uint64_t TCCD_L_START = 7; + + constexpr uint64_t LOWEST_TCCD = 4; + constexpr uint64_t TCCD_COUNT = 5; + // 4 5 6 7 8 + constexpr uint8_t tccd_l_map[TCCD_COUNT] = { 0b000, 0b001, 0b010, 0b011, 0b100 }; + + fapi2::buffer l_tccd_l_buffer; + fapi2::buffer l_vrefdq_train_value_buffer; + + FAPI_ASSERT((i_data.iv_tccd_l >= LOWEST_TCCD) && (i_data.iv_tccd_l < (LOWEST_TCCD + TCCD_COUNT)), + fapi2::MSS_BAD_MR_PARAMETER() + .set_MR_NUMBER(6) + .set_PARAMETER(TCCD) + .set_PARAMETER_VALUE(i_data.iv_tccd_l) + .set_DIMM_IN_ERROR(i_target), + "Bad value for TCCD: %d (%s)", + i_data.iv_tccd_l, + mss::c_str(i_target)); + + l_tccd_l_buffer = tccd_l_map[i_data.iv_tccd_l - LOWEST_TCCD]; + l_vrefdq_train_value_buffer = i_data.iv_vrefdq_train_value[mss::index(i_rank)]; + + FAPI_INF("%s MR6 rank %d attributes: TRAIN_V: 0x%x(0x%x), TRAIN_R: 0x%x, TRAIN_E: 0x%x, TCCD_L: 0x%x(0x%x)", + mss::c_str(i_target), i_rank, i_data.iv_vrefdq_train_value[mss::index(i_rank)], + uint8_t(l_vrefdq_train_value_buffer), i_data.iv_vrefdq_train_range[mss::index(i_rank)], + i_data.iv_vrefdq_train_enable[mss::index(i_rank)], i_data.iv_tccd_l, uint8_t(l_tccd_l_buffer)); + + mss::swizzle(l_vrefdq_train_value_buffer, io_inst.arr0); + io_inst.arr0.writeBit(i_data.iv_vrefdq_train_range[mss::index(i_rank)]); + io_inst.arr0.writeBit(i_data.iv_vrefdq_train_enable[mss::index(i_rank)]); + mss::swizzle(l_tccd_l_buffer, io_inst.arr0); + + FAPI_INF("%s MR6: 0x%016llx", mss::c_str(i_target), uint64_t(io_inst.arr0)); + + return fapi2::FAPI2_RC_SUCCESS; + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Configure the ARR0 of the CCS instruction for mrs06 +/// @tparam MC mss::mc_type memory controller type +/// @param[in] i_target a fapi2::Target +/// @param[in,out] io_inst the instruction to fixup +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff OK +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE > +fapi2::ReturnCode mrs06(const fapi2::Target& i_target, + ccs::instruction_t& io_inst, + const uint64_t i_rank) +{ + // Check to make sure our ctor worked ok + mrs06_data l_data( i_target, fapi2::current_err ); + FAPI_TRY( fapi2::current_err, "%s Unable to construct MRS06 data from attributes", mss::c_str(i_target) ); + FAPI_TRY( mrs06(i_target, l_data, io_inst, i_rank) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Helper function for mrs06_decode +/// @tparam MC mss::mc_type memory controller type +/// @tparam TT traits type defaults to ccsTraits +/// @param[in] i_inst the CCS instruction +/// @param[in] i_rank the rank in question +/// @param[out] o_vrefdq_train_range the vrefdq training range setting +/// @param[out] o_vrefdq_train_enable the vrefdq training enable setting +/// @param[out] o_tccd_l_buffer the tccd_l setting +/// @param[out] o_vrefdq_train_value_buffer the vrefdq training value +/// @return FAPI2_RC_SUCCESS iff ok +/// +template< mss::mc_type MC = DEFAULT_MC_TYPE, typename TT = ccsTraits > +fapi2::ReturnCode mrs06_decode_helper(const ccs::instruction_t& i_inst, + const uint64_t i_rank, + uint8_t& o_vrefdq_train_range, + uint8_t& o_vrefdq_train_enable, + fapi2::buffer& o_tccd_l_buffer, + fapi2::buffer& o_vrefdq_train_value_buffer) +{ + o_tccd_l_buffer = 0; + o_vrefdq_train_value_buffer = 0; + + mss::swizzle<2, 6, TT::A5>(i_inst.arr0, o_vrefdq_train_value_buffer); + o_vrefdq_train_range = i_inst.arr0.getBit(); + o_vrefdq_train_enable = i_inst.arr0.getBit(); + mss::swizzle<5, 3, TT::A12>(i_inst.arr0, o_tccd_l_buffer); + + FAPI_INF("MR6 rank %d decode: TRAIN_V: 0x%x, TRAIN_R: 0x%x, TRAIN_E: 0x%x, TCCD_L: 0x%x", + i_rank, uint8_t(o_vrefdq_train_value_buffer), o_vrefdq_train_range, + o_vrefdq_train_enable, uint8_t(o_tccd_l_buffer)); + + return fapi2::FAPI2_RC_SUCCESS; +} + +/// +/// @brief Given a CCS instruction which contains address bits with an encoded MRS6, +/// decode and trace the contents +/// @param[in] i_inst the CCS instruction +/// @param[in] i_rank the rank in question +/// @return FAPI2_RC_SUCCESS iff ok +/// +inline fapi2::ReturnCode mrs06_decode(const ccs::instruction_t& i_inst, + const uint64_t i_rank) +{ + fapi2::buffer l_tccd_l_buffer; + fapi2::buffer l_vrefdq_train_value_buffer; + uint8_t l_vrefdq_train_range = 0; + uint8_t l_vrefdq_train_enable = 0; + + return mrs06_decode_helper(i_inst, i_rank, l_vrefdq_train_range, l_vrefdq_train_enable, + l_tccd_l_buffer, l_vrefdq_train_value_buffer); +} + + +} // ns ddr4 +} // ns mss +#endif