diff options
author | Brian Silver <bsilver@us.ibm.com> | 2016-08-07 12:47:05 -0500 |
---|---|---|
committer | William G. Hoffa <wghoffa@us.ibm.com> | 2016-08-09 11:23:44 -0400 |
commit | 481d34db3c9cb6fcc016daf5f70f9f8f63791256 (patch) | |
tree | 9a964acdf1a0042f62e40a2d738b3ab302641c3f /src/import | |
parent | a813cd37381b61b4021a012b0ceb8612b64f6790 (diff) | |
download | talos-hostboot-481d34db3c9cb6fcc016daf5f70f9f8f63791256.tar.gz talos-hostboot-481d34db3c9cb6fcc016daf5f70f9f8f63791256.zip |
Change VPD decoding to account for MCA VPD spread over MCS blobs
Update formatting of eff_config error xml
Change eff_config ctor to decode VPD to ensure ordering
Change-Id: I29f4fe7b73cdc9c25fc524e84a1e8dc9d85bd5cb
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/27964
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Louis Stermole <stermole@us.ibm.com>
Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/27965
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Diffstat (limited to 'src/import')
5 files changed, 868 insertions, 619 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C index 0fcc69039..97601d088 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C @@ -3398,8 +3398,11 @@ fapi_try_exit: /// fapi2::ReturnCode eff_config::decode_vpd(const fapi2::Target<TARGET_TYPE_MCS>& i_target) { - uint8_t l_mt_blob[mss::VPD_KEYWORD_MAX]; - uint8_t l_mr_blob[mss::VPD_KEYWORD_MAX]; + uint8_t l_mr_blob[mss::VPD_KEYWORD_MAX] = {0}; + std::vector<uint8_t*> l_mt_blobs(PORTS_PER_MCS, nullptr); + + // For sanity. Not sure this will break us, but we're certainly making assumptions below. + static_assert(MAX_DIMM_PER_PORT == 2, "Max DIMM per port isn't 2"); // Get MT data { @@ -3415,8 +3418,41 @@ fapi2::ReturnCode eff_config::decode_vpd(const fapi2::Target<TARGET_TYPE_MCS>& i } // For MT we need to fill in the rank information - // TODO RTC:157758 Seems the interface is incorrect, but we're just returning fake VPD here anyway - FAPI_TRY( mss::getVPD(i_target, l_vpd_info, &(l_mt_blob[0])) ); + // But, of course, the rank information can differ per port. However, the vpd interface doesn't + // allow this in a straight-forward way. So, we have to get VPD blobs for MCS which contain + // ports which have the rank configuration in question. This means, basically, we pass a MCS MT + // blob to the decoder for each MCA, regardless of whether the port configurations are the same. + for (const auto& p : find_targets<TARGET_TYPE_MCA>(i_target)) + { + uint8_t* l_mt_blob = new uint8_t[mss::VPD_KEYWORD_MAX]; + uint64_t l_rank_count_dimm[MAX_DIMM_PER_PORT] = {0}; + + // Make sure the mt blob is all 0's. In the event that we get an MCA who has 0 ranks (no DIMM) + // we don't want to get the VPD (that will fail) but we can't give up. Cronus will + // give us MCA with 0 DIMM, so we'll just use a 0-filled VPD for those MCA. + memset(l_mt_blob, 0, mss::VPD_KEYWORD_MAX); + + for (const auto& d : find_targets<TARGET_TYPE_DIMM>(p)) + { + uint8_t l_num_master_ranks = 0; + FAPI_TRY( mss::eff_num_master_ranks_per_dimm(d, l_num_master_ranks) ); + l_rank_count_dimm[mss::index(d)] = l_num_master_ranks; + } + + // This value will, of course, be 0 if there is no DIMM in the port. + l_vpd_info.iv_rank_count_dimm_0 = l_rank_count_dimm[0]; + l_vpd_info.iv_rank_count_dimm_1 = l_rank_count_dimm[1]; + + // Get the MCS blob for this specific rank combination *only if* we have DIMM. Remember, + // Cronus can give us functional MCA which have no DIMM - and we'd puke getting the VPD. + if ((l_vpd_info.iv_rank_count_dimm_0 != 0) || (l_vpd_info.iv_rank_count_dimm_1 != 0)) + { + FAPI_TRY( mss::getVPD(i_target, l_vpd_info, &(l_mt_blob[0])) ); + } + + // Put it in the vector in the right place. + l_mt_blobs[mss::index(p)] = l_mt_blob; + } } // Get MR data @@ -3433,13 +3469,31 @@ fapi2::ReturnCode eff_config::decode_vpd(const fapi2::Target<TARGET_TYPE_MCS>& i } // For MR we need to tell the VPDInfo the frequency (err ... mt/s - why is this mhz?) - FAPI_TRY( mss::freq(mss::find_target<TARGET_TYPE_MCBIST>(i_target), l_vpd_info.iv_freq_mhz) ); - FAPI_TRY( mss::getVPD(i_target, l_vpd_info, &(l_mr_blob[0])) ); + FAPI_TRY( mss::freq(find_target<TARGET_TYPE_MCBIST>(i_target), l_vpd_info.iv_freq_mhz) ); + + // Only get the MR blob if we have a freq. It's possible for Cronus to give us an MCS which + // is connected to a controller which has 0 DIMM installed. In this case, we won't have + // a frequency, and thus we'd fail getting the VPD. So we initiaized the VPD to 0's and if + // there's no freq, we us a 0 filled VPD. + if (l_vpd_info.iv_freq_mhz != 0) + { + FAPI_TRY( mss::getVPD(i_target, l_vpd_info, &(l_mr_blob[0])) ); + } } - FAPI_TRY( mss::eff_decode(i_target, l_mt_blob, l_mr_blob) ); + FAPI_TRY( mss::eff_decode(i_target, l_mt_blobs, l_mr_blob) ); fapi_try_exit: + + // delete the mt blobs + for (auto p : l_mt_blobs) + { + if (p != nullptr) + { + delete[] p; + } + } + return fapi2::current_err; } diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.H index d4d6c874a..98ec81ddc 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.H @@ -56,10 +56,19 @@ class eff_config // state of decoder timebases, target, fapi2 positions, // and clock period eliminate code duplication. - // - // @brief Constructor - // - eff_config() = default; + /// + /// @brief Constructor + /// @tparam T, the fapi2::TargetType of the target + /// @param[in] i_target, the fapi2::Target which we're configuring + /// @param[out] o_rc, a return code which determines the success of the constructor + /// + template< fapi2::TargetType T > + eff_config( const fapi2::Target<T>& i_target, fapi2::ReturnCode& o_rc ) + { + // Decode the VPD for this MCS and stick it in the attributes. + o_rc = decode_vpd(i_target); + return; + } // // @brief Destructor @@ -768,6 +777,7 @@ class eff_config /// fapi2::ReturnCode dram_trtp(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target); + private: /// /// @brief Grab the VPD blobs and decode into attributes /// @param[in] i_target FAPI2 target (MCS) diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss_vpd_decoder.H b/src/import/chips/p9/procedures/hwp/memory/lib/mss_vpd_decoder.H index db3f2a30a..ede76118a 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mss_vpd_decoder.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss_vpd_decoder.H @@ -38,6 +38,759 @@ namespace decoder // VPD Keyword Version Byte: 00 /// +/// @brief ATTR_MSS_VPD_MT_0_VERSION_LAYOUT decode and set +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note MT Keyword Layout Version Number. Increases when attributes are added, removed, or redefined. Does not reset. +/// +inline fapi2::ReturnCode vpd_mt_0_version_layout(const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value; + + memcpy(&l_value, i_blobs[0] + 0, 1); + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_0_VERSION_LAYOUT, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_0_VERSION_LAYOUT start: 0, len: 1"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_1_VERSION_DATA decode and set +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note MT Keyword Data Version Number. Increases when data changes with the above layout version. Resets when layout version number increments. +/// +inline fapi2::ReturnCode vpd_mt_1_version_data(const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value; + + memcpy(&l_value, i_blobs[0] + 1, 1); + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_1_VERSION_DATA, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_1_VERSION_DATA start: 1, len: 1"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_2_SIGNATURE_HASH decode and set +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note Hash Signature for the MT Keyword. The hash signature is 32bits for 256 bytes of data. +/// +inline fapi2::ReturnCode vpd_mt_2_signature_hash(const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint32_t l_value; + + memcpy(&l_value, i_blobs[0] + 2, 4); + l_value = be32toh(l_value); + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_2_SIGNATURE_HASH, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_2_SIGNATURE_HASH start: 2, len: 4"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_DIMM_RCD_IBT decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note Register Clock Driver, Input Bus Termination in tens of Ohms. +/// +inline fapi2::ReturnCode vpd_mt_dimm_rcd_ibt(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value[2][2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 4 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 6 + (l_index * l_length); + memcpy(&(l_value[l_index][0]), l_blob + l_start, l_length); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_DIMM_RCD_IBT, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_DIMM_RCD_IBT start: 6, len: 4"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note DQ and DQS Drive Impedance for [Port][DIMM][RANK]. +/// +inline fapi2::ReturnCode vpd_mt_dram_drv_imp_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value[2][2][2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 8 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 10 + (l_index * l_length); + memcpy(&(l_value[l_index][0][0]), l_blob + l_start, l_length); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS start: 10, len: 8"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_DRAM_RTT_NOM decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note DRAM side Nominal Termination Resistance in Ohms. +/// +inline fapi2::ReturnCode vpd_mt_dram_rtt_nom(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value[2][2][2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 8 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 18 + (l_index * l_length); + memcpy(&(l_value[l_index][0][0]), l_blob + l_start, l_length); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_DRAM_RTT_NOM, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_DRAM_RTT_NOM start: 18, len: 8"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_DRAM_RTT_PARK decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note DRAM side Park Termination Resistance in Ohms. +/// +inline fapi2::ReturnCode vpd_mt_dram_rtt_park(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value[2][2][2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 8 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 26 + (l_index * l_length); + memcpy(&(l_value[l_index][0][0]), l_blob + l_start, l_length); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_DRAM_RTT_PARK, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_DRAM_RTT_PARK start: 26, len: 8"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_DRAM_RTT_WR decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note DRAM side Write Termination Resistance in Ohms. +/// +inline fapi2::ReturnCode vpd_mt_dram_rtt_wr(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value[2][2][2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 8 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 34 + (l_index * l_length); + memcpy(&(l_value[l_index][0][0]), l_blob + l_start, l_length); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_DRAM_RTT_WR, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_DRAM_RTT_WR start: 34, len: 8"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_RD_UP decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note Selects the number of enabled pullup branches during READ mode. ONLY set range 0-7. Eg. 0x02 = b010 (1 branch selected), 0x06 = b110 (2 branches selected) +/// Bit 0-2 = DP16 Block 0 (DQ Bits 0-7) +/// Bit 3-5 = DP16 Block 0 (DQ Bits 8-15) +/// Bit 6-8 = DP16 Block 1 (DQ Bits 0-7) +/// Bit 9-11 = DP16 Block 1 (DQ Bits 8-15) +/// Bit 12-14 = DP16 Block 2 (DQ Bits 0-7) +/// Bit 15-17 = DP16 Block 2 (DQ Bits 8-15) +/// Bit 18-20 = DP16 Block 3 (DQ Bits 0-7) +/// Bit 21-23 = DP16 Block 3 (DQ Bits 8-15) +/// Bit 24-26 = DP16 Block 4 (DQ Bits 0-7) +/// Bit 27-29 = DP16 Block 4 (DQ Bits 8-15) +/// +inline fapi2::ReturnCode vpd_mt_mc_dq_acboost_rd_up(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint32_t l_value[2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 8 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 42 + (l_index * l_length); + memcpy(&(l_value[l_index]), l_blob + l_start, l_length); + } + + for (size_t i = 0; i < 2; ++i) + { + l_value[i] = be32toh(l_value[i]); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_RD_UP, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_RD_UP start: 42, len: 8"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_WR_DOWN decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note Selects the number of enabled pulldown branches during WRITE mode. ONLY set range 0-7. Eg. 0x02 = b010 (1 branch selected), 0x06 = b110 (2 branches selected) +/// Bit 0-2 = DP16 Block 0 (DQ Bits 0-7) +/// Bit 3-5 = DP16 Block 0 (DQ Bits 8-15) +/// Bit 6-8 = DP16 Block 1 (DQ Bits 0-7) +/// Bit 9-11 = DP16 Block 1 (DQ Bits 8-15) +/// Bit 12-14 = DP16 Block 2 (DQ Bits 0-7) +/// Bit 15-17 = DP16 Block 2 (DQ Bits 8-15) +/// Bit 18-20 = DP16 Block 3 (DQ Bits 0-7) +/// Bit 21-23 = DP16 Block 3 (DQ Bits 8-15) +/// Bit 24-26 = DP16 Block 4 (DQ Bits 0-7) +/// Bit 27-29 = DP16 Block 4 (DQ Bits 8-15) +/// +inline fapi2::ReturnCode vpd_mt_mc_dq_acboost_wr_down(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint32_t l_value[2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 8 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 50 + (l_index * l_length); + memcpy(&(l_value[l_index]), l_blob + l_start, l_length); + } + + for (size_t i = 0; i < 2; ++i) + { + l_value[i] = be32toh(l_value[i]); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_WR_DOWN, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_WR_DOWN start: 50, len: 8"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_WR_UP decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note Selects the number of enabled pullup branches during WRITE mode. ONLY set range 0-7. Eg. 0x02 = b010 (1 branch selected), 0x06 = b110 (2 branches selected) +/// Bit 0-2 = DP16 Block 0 (DQ Bits 0-7) +/// Bit 3-5 = DP16 Block 0 (DQ Bits 8-15) +/// Bit 6-8 = DP16 Block 1 (DQ Bits 0-7) +/// Bit 9-11 = DP16 Block 1 (DQ Bits 8-15) +/// Bit 12-14 = DP16 Block 2 (DQ Bits 0-7) +/// Bit 15-17 = DP16 Block 2 (DQ Bits 8-15) +/// Bit 18-20 = DP16 Block 3 (DQ Bits 0-7) +/// Bit 21-23 = DP16 Block 3 (DQ Bits 8-15) +/// Bit 24-26 = DP16 Block 4 (DQ Bits 0-7) +/// Bit 27-29 = DP16 Block 4 (DQ Bits 8-15) +/// +inline fapi2::ReturnCode vpd_mt_mc_dq_acboost_wr_up(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint32_t l_value[2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 8 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 58 + (l_index * l_length); + memcpy(&(l_value[l_index]), l_blob + l_start, l_length); + } + + for (size_t i = 0; i < 2; ++i) + { + l_value[i] = be32toh(l_value[i]); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_WR_UP, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_WR_UP start: 58, len: 8"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_MC_DQ_CTLE_CAP decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note Sets the capacitance value in the RC source degeneration. ONLY set range 0-3. (b00 = No capacitor selected, b01 = more caps selected, b10 = even more caps selected, b11 = maximum capacitors selected) +/// Bit 0-1 = DP16 Block 0 Nibble 0 Bit 16-17 = DP16 Block 2 Nibble 0 Bit 32-33 = DP16 Block 4 Nibble 0 +/// Bit 2-3 = DP16 Block 0 Nibble 1 Bit 18-19 = DP16 Block 2 Nibble 1 Bit 34-35 = DP16 Block 4 Nibble 1 +/// Bit 4-5 = DP16 Block 0 Nibble 2 Bit 20-21 = DP16 Block 2 Nibble 2 Bit 36-37 = DP16 Block 4 Nibble 2 +/// Bit 6-7 = DP16 Block 0 Nibble 3 Bit 22-23 = DP16 Block 2 Nibble 3 Bit 38-39 = DP16 Block 4 Nibble 3 +/// Bit 8-9 = DP16 Block 1 Nibble 0 Bit 24-25 = DP16 Block 3 Nibble 0 +/// Bit 10-11 = DP16 Block 1 Nibble 1 Bit 26-27 = DP16 Block 3 Nibble 1 +/// Bit 12-13 = DP16 Block 1 Nibble 2 Bit 28-29 = DP16 Block 3 Nibble 2 +/// Bit 14-15 = DP16 Block 1 Nibble 3 Bit 30-31 = DP16 Block 3 Nibble 3 +/// +inline fapi2::ReturnCode vpd_mt_mc_dq_ctle_cap(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint64_t l_value[2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 16 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 66 + (l_index * l_length); + memcpy(&(l_value[l_index]), l_blob + l_start, l_length); + } + + for (size_t i = 0; i < 2; ++i) + { + l_value[i] = be64toh(l_value[i]); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DQ_CTLE_CAP, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_MC_DQ_CTLE_CAP start: 66, len: 16"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_MC_DQ_CTLE_RES decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note Sets the resistance value in the RC source degeneration. Also defines the CTLE's DC Gain. ONLY set range 0-7. (b000 = max resistance, b001 to b110 = decreasing resistance, b111 = min resistance) +/// Bit 0-2 = DP16 Block 0 Nibble 0 Bit 24-26 = DP16 Block 2 Nibble 0 Bit 48-50 = DP16 Block 4 Nibble 0 +/// Bit 3-5 = DP16 Block 0 Nibble 1 Bit 27-29 = DP16 Block 2 Nibble 1 Bit 51-53 = DP16 Block 4 Nibble 1 +/// Bit 6-8 = DP16 Block 0 Nibble 2 Bit 30-32 = DP16 Block 2 Nibble 2 Bit 54-56 = DP16 Block 4 Nibble 2 +/// Bit 9-11 = DP16 Block 0 Nibble 3 Bit 33-35 = DP16 Block 2 Nibble 3 Bit 57-59 = DP16 Block 4 Nibble 3 +/// Bit 12-14 = DP16 Block 1 Nibble 0 Bit 36-38 = DP16 Block 3 Nibble 0 +/// Bit 15-17 = DP16 Block 1 Nibble 1 Bit 39-41 = DP16 Block 3 Nibble 1 +/// Bit 18-20 = DP16 Block 1 Nibble 2 Bit 42-44 = DP16 Block 3 Nibble 2 +/// Bit 21-23 = DP16 Block 1 Nibble 3 Bit 45-47 = DP16 Block 3 Nibble 3 +/// +inline fapi2::ReturnCode vpd_mt_mc_dq_ctle_res(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint64_t l_value[2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 16 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 82 + (l_index * l_length); + memcpy(&(l_value[l_index]), l_blob + l_start, l_length); + } + + for (size_t i = 0; i < 2; ++i) + { + l_value[i] = be64toh(l_value[i]); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DQ_CTLE_RES, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_MC_DQ_CTLE_RES start: 82, len: 16"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_MC_DRV_IMP_ADDR decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note Memory Controller side Drive Impedance for Address Lines in Ohms. +/// +inline fapi2::ReturnCode vpd_mt_mc_drv_imp_addr(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value[2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 2 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 98 + (l_index * l_length); + memcpy(&(l_value[l_index]), l_blob + l_start, l_length); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DRV_IMP_ADDR, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_MC_DRV_IMP_ADDR start: 98, len: 2"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_MC_DRV_IMP_CLK decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note Memory Controller side Drive Impedance for Clock in Ohms. +/// +inline fapi2::ReturnCode vpd_mt_mc_drv_imp_clk(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value[2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 2 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 100 + (l_index * l_length); + memcpy(&(l_value[l_index]), l_blob + l_start, l_length); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DRV_IMP_CLK, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_MC_DRV_IMP_CLK start: 100, len: 2"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_MC_DRV_IMP_CNTL decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note Memory Controller side Drive Impedance for Control Lines in Ohms. +/// +inline fapi2::ReturnCode vpd_mt_mc_drv_imp_cntl(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value[2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 2 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 102 + (l_index * l_length); + memcpy(&(l_value[l_index]), l_blob + l_start, l_length); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DRV_IMP_CNTL, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_MC_DRV_IMP_CNTL start: 102, len: 2"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_MC_DRV_IMP_DQ_DQS decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note Memory Controller side Drive Impedance for Data and Data Strobe Lines in Ohms. +/// +inline fapi2::ReturnCode vpd_mt_mc_drv_imp_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value[2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 2 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 104 + (l_index * l_length); + memcpy(&(l_value[l_index]), l_blob + l_start, l_length); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DRV_IMP_DQ_DQS, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_MC_DRV_IMP_DQ_DQS start: 104, len: 2"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_MC_DRV_IMP_SPCKE decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note Memory Controller side Drive Impedance for Clock Enable Spare Line in Ohms. +/// +inline fapi2::ReturnCode vpd_mt_mc_drv_imp_spcke(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value[2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 2 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 106 + (l_index * l_length); + memcpy(&(l_value[l_index]), l_blob + l_start, l_length); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DRV_IMP_SPCKE, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_MC_DRV_IMP_SPCKE start: 106, len: 2"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_MC_RCV_IMP_DQ_DQS decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note Memory Controller side Receiver Impedance for Data and Data Strobe Lines in Ohms. +/// +inline fapi2::ReturnCode vpd_mt_mc_rcv_imp_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value[2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 2 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 108 + (l_index * l_length); + memcpy(&(l_value[l_index]), l_blob + l_start, l_length); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_RCV_IMP_DQ_DQS, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_MC_RCV_IMP_DQ_DQS start: 108, len: 2"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_ODT_RD decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note READ, On Die Termination triggering bitmap. +/// +inline fapi2::ReturnCode vpd_mt_odt_rd(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value[2][2][2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 8 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 110 + (l_index * l_length); + memcpy(&(l_value[l_index][0][0]), l_blob + l_start, l_length); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_ODT_RD, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_ODT_RD start: 110, len: 8"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_ODT_WR decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note WRITE, On Die Termination triggering bitmap. +/// +inline fapi2::ReturnCode vpd_mt_odt_wr(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value[2][2][2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 8 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 118 + (l_index * l_length); + memcpy(&(l_value[l_index][0][0]), l_blob + l_start, l_length); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_ODT_WR, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_ODT_WR start: 118, len: 8"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_VREF_DRAM_WR decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note DRAM side Write Vref setting for DDR4. Bit encode is 01234567. Bit 0 is unused. Bit 1 is the Range. Bits 2-7 is the Value. Refer to the VrefDQ Training Table in JEDEC. +/// +inline fapi2::ReturnCode vpd_mt_vref_dram_wr(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint8_t l_value[2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 2 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 126 + (l_index * l_length); + memcpy(&(l_value[l_index]), l_blob + l_start, l_length); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_VREF_DRAM_WR, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_VREF_DRAM_WR start: 126, len: 2"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_VREF_MC_RD decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note Memory Controller side Read Vref setting. Dividing by 1000 gives you percentage of Vdd +/// +inline fapi2::ReturnCode vpd_mt_vref_mc_rd(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint32_t l_value[2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 8 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 128 + (l_index * l_length); + memcpy(&(l_value[l_index]), l_blob + l_start, l_length); + } + + for (size_t i = 0; i < 2; ++i) + { + l_value[i] = be32toh(l_value[i]); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_VREF_MC_RD, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_VREF_MC_RD start: 128, len: 8"); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief ATTR_MSS_VPD_MT_WINDAGE_RD_CTR decode and set (array) +/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> +/// @param[in] i_blobs a std::vector of pointers to VPD blobs for this MCS's MCAs +/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK +/// @note Derived from calibration/characterization of read centering. Number of windage offset in units of pico-seconds[ps] with sign bit0 (0b0=positive, 0b1=negative) and value in bits1..31, so 0x8023 for example would mean "-35ps". If this is enabled, disable periodic rd_ctr in draminit_mc. Default +/// +inline fapi2::ReturnCode vpd_mt_windage_rd_ctr(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_blobs) +{ + uint16_t l_value[2]; + const auto& l_mcas = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const uint64_t l_length = 4 / l_mcas.size(); + + for (const auto& l_mca : l_mcas) + { + const uint64_t l_index = mss::index(l_mca); + const uint8_t* l_blob = i_blobs[l_index]; + const uint64_t l_start = 136 + (l_index * l_length); + memcpy(&(l_value[l_index]), l_blob + l_start, l_length); + } + + for (size_t i = 0; i < 2; ++i) + { + l_value[i] = be16toh(l_value[i]); + } + + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_WINDAGE_RD_CTR, i_target, l_value), + "Unable to decode and set ATTR_MSS_VPD_MT_WINDAGE_RD_CTR start: 136, len: 4"); + +fapi_try_exit: + return fapi2::current_err; +} + + +// VPD Keyword Version Byte: 00 +/// /// @brief ATTR_MSS_VPD_MR_0_VERSION_LAYOUT decode and set /// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> /// @param[in] i_blob the VPD blob for this MCS @@ -978,587 +1731,43 @@ fapi_try_exit: return fapi2::current_err; } - -// VPD Keyword Version Byte: 00 -/// -/// @brief ATTR_MSS_VPD_MT_0_VERSION_LAYOUT decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note MT Keyword Layout Version Number. Increases when attributes are added, removed, or redefined. Does not reset. -/// -inline fapi2::ReturnCode vpd_mt_0_version_layout(const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& i_target, - const uint8_t* i_blob) -{ - uint8_t l_value; - - memcpy(&l_value, i_blob + 0, 1); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_0_VERSION_LAYOUT, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_0_VERSION_LAYOUT start: 0, len: 1"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_1_VERSION_DATA decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note MT Keyword Data Version Number. Increases when data changes with the above layout version. Resets when layout version number increments. -/// -inline fapi2::ReturnCode vpd_mt_1_version_data(const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& i_target, - const uint8_t* i_blob) -{ - uint8_t l_value; - - memcpy(&l_value, i_blob + 1, 1); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_1_VERSION_DATA, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_1_VERSION_DATA start: 1, len: 1"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_2_SIGNATURE_HASH decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note Hash Signature for the MT Keyword. The hash signature is 32bits for 256 bytes of data. -/// -inline fapi2::ReturnCode vpd_mt_2_signature_hash(const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>& i_target, - const uint8_t* i_blob) -{ - uint32_t l_value; - - memcpy(&l_value, i_blob + 2, 4); - l_value = be32toh(l_value); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_2_SIGNATURE_HASH, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_2_SIGNATURE_HASH start: 2, len: 4"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_DIMM_RCD_IBT decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note Register Clock Driver, Input Bus Termination in tens of Ohms. -/// -inline fapi2::ReturnCode vpd_mt_dimm_rcd_ibt(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint8_t l_value[2][2]; - - memcpy(&l_value, i_blob + 6, 4); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_DIMM_RCD_IBT, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_DIMM_RCD_IBT start: 6, len: 4"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note DQ and DQS Drive Impedance for [Port][DIMM][RANK]. -/// -inline fapi2::ReturnCode vpd_mt_dram_drv_imp_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint8_t l_value[2][2][2]; - - memcpy(&l_value, i_blob + 10, 8); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_DRAM_DRV_IMP_DQ_DQS start: 10, len: 8"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_DRAM_RTT_NOM decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note DRAM side Nominal Termination Resistance in Ohms. -/// -inline fapi2::ReturnCode vpd_mt_dram_rtt_nom(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint8_t l_value[2][2][2]; - - memcpy(&l_value, i_blob + 18, 8); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_DRAM_RTT_NOM, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_DRAM_RTT_NOM start: 18, len: 8"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_DRAM_RTT_PARK decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note DRAM side Park Termination Resistance in Ohms. -/// -inline fapi2::ReturnCode vpd_mt_dram_rtt_park(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint8_t l_value[2][2][2]; - - memcpy(&l_value, i_blob + 26, 8); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_DRAM_RTT_PARK, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_DRAM_RTT_PARK start: 26, len: 8"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_DRAM_RTT_WR decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note DRAM side Write Termination Resistance in Ohms. -/// -inline fapi2::ReturnCode vpd_mt_dram_rtt_wr(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint8_t l_value[2][2][2]; - - memcpy(&l_value, i_blob + 34, 8); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_DRAM_RTT_WR, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_DRAM_RTT_WR start: 34, len: 8"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_RD_UP decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note Selects the number of enabled pullup branches during READ mode. ONLY set range 0-7. Eg. 0x02 = b010 (1 branch selected), 0x06 = b110 (2 branches selected) -/// Bit 0-2 = DP16 Block 0 (DQ Bits 0-7) -/// Bit 3-5 = DP16 Block 0 (DQ Bits 8-15) -/// Bit 6-8 = DP16 Block 1 (DQ Bits 0-7) -/// Bit 9-11 = DP16 Block 1 (DQ Bits 8-15) -/// Bit 12-14 = DP16 Block 2 (DQ Bits 0-7) -/// Bit 15-17 = DP16 Block 2 (DQ Bits 8-15) -/// Bit 18-20 = DP16 Block 3 (DQ Bits 0-7) -/// Bit 21-23 = DP16 Block 3 (DQ Bits 8-15) -/// Bit 24-26 = DP16 Block 4 (DQ Bits 0-7) -/// Bit 27-29 = DP16 Block 4 (DQ Bits 8-15) -/// -inline fapi2::ReturnCode vpd_mt_mc_dq_acboost_rd_up(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint32_t l_value[2]; - - memcpy(&l_value, i_blob + 42, 8); - - for (size_t i = 0; i < 2; ++i) - { - l_value[i] = be32toh(l_value[i]); - } - - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_RD_UP, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_RD_UP start: 42, len: 8"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_WR_DOWN decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note Selects the number of enabled pulldown branches during WRITE mode. ONLY set range 0-7. Eg. 0x02 = b010 (1 branch selected), 0x06 = b110 (2 branches selected) -/// Bit 0-2 = DP16 Block 0 (DQ Bits 0-7) -/// Bit 3-5 = DP16 Block 0 (DQ Bits 8-15) -/// Bit 6-8 = DP16 Block 1 (DQ Bits 0-7) -/// Bit 9-11 = DP16 Block 1 (DQ Bits 8-15) -/// Bit 12-14 = DP16 Block 2 (DQ Bits 0-7) -/// Bit 15-17 = DP16 Block 2 (DQ Bits 8-15) -/// Bit 18-20 = DP16 Block 3 (DQ Bits 0-7) -/// Bit 21-23 = DP16 Block 3 (DQ Bits 8-15) -/// Bit 24-26 = DP16 Block 4 (DQ Bits 0-7) -/// Bit 27-29 = DP16 Block 4 (DQ Bits 8-15) -/// -inline fapi2::ReturnCode vpd_mt_mc_dq_acboost_wr_down(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint32_t l_value[2]; - - memcpy(&l_value, i_blob + 50, 8); - - for (size_t i = 0; i < 2; ++i) - { - l_value[i] = be32toh(l_value[i]); - } - - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_WR_DOWN, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_WR_DOWN start: 50, len: 8"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_WR_UP decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note Selects the number of enabled pullup branches during WRITE mode. ONLY set range 0-7. Eg. 0x02 = b010 (1 branch selected), 0x06 = b110 (2 branches selected) -/// Bit 0-2 = DP16 Block 0 (DQ Bits 0-7) -/// Bit 3-5 = DP16 Block 0 (DQ Bits 8-15) -/// Bit 6-8 = DP16 Block 1 (DQ Bits 0-7) -/// Bit 9-11 = DP16 Block 1 (DQ Bits 8-15) -/// Bit 12-14 = DP16 Block 2 (DQ Bits 0-7) -/// Bit 15-17 = DP16 Block 2 (DQ Bits 8-15) -/// Bit 18-20 = DP16 Block 3 (DQ Bits 0-7) -/// Bit 21-23 = DP16 Block 3 (DQ Bits 8-15) -/// Bit 24-26 = DP16 Block 4 (DQ Bits 0-7) -/// Bit 27-29 = DP16 Block 4 (DQ Bits 8-15) -/// -inline fapi2::ReturnCode vpd_mt_mc_dq_acboost_wr_up(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint32_t l_value[2]; - - memcpy(&l_value, i_blob + 58, 8); - - for (size_t i = 0; i < 2; ++i) - { - l_value[i] = be32toh(l_value[i]); - } - - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_WR_UP, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_MC_DQ_ACBOOST_WR_UP start: 58, len: 8"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_MC_DQ_CTLE_CAP decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note Sets the capacitance value in the RC source degeneration. ONLY set range 0-3. (b00 = No capacitor selected, b01 = more caps selected, b10 = even more caps selected, b11 = maximum capacitors selected) -/// Bit 0-1 = DP16 Block 0 Nibble 0 Bit 16-17 = DP16 Block 2 Nibble 0 Bit 32-33 = DP16 Block 4 Nibble 0 -/// Bit 2-3 = DP16 Block 0 Nibble 1 Bit 18-19 = DP16 Block 2 Nibble 1 Bit 34-35 = DP16 Block 4 Nibble 1 -/// Bit 4-5 = DP16 Block 0 Nibble 2 Bit 20-21 = DP16 Block 2 Nibble 2 Bit 36-37 = DP16 Block 4 Nibble 2 -/// Bit 6-7 = DP16 Block 0 Nibble 3 Bit 22-23 = DP16 Block 2 Nibble 3 Bit 38-39 = DP16 Block 4 Nibble 3 -/// Bit 8-9 = DP16 Block 1 Nibble 0 Bit 24-25 = DP16 Block 3 Nibble 0 -/// Bit 10-11 = DP16 Block 1 Nibble 1 Bit 26-27 = DP16 Block 3 Nibble 1 -/// Bit 12-13 = DP16 Block 1 Nibble 2 Bit 28-29 = DP16 Block 3 Nibble 2 -/// Bit 14-15 = DP16 Block 1 Nibble 3 Bit 30-31 = DP16 Block 3 Nibble 3 -/// -inline fapi2::ReturnCode vpd_mt_mc_dq_ctle_cap(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint64_t l_value[2]; - - memcpy(&l_value, i_blob + 66, 16); - - for (size_t i = 0; i < 2; ++i) - { - l_value[i] = be64toh(l_value[i]); - } - - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DQ_CTLE_CAP, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_MC_DQ_CTLE_CAP start: 66, len: 16"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_MC_DQ_CTLE_RES decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note Sets the resistance value in the RC source degeneration. Also defines the CTLE's DC Gain. ONLY set range 0-7. (b000 = max resistance, b001 to b110 = decreasing resistance, b111 = min resistance) -/// Bit 0-2 = DP16 Block 0 Nibble 0 Bit 24-26 = DP16 Block 2 Nibble 0 Bit 48-50 = DP16 Block 4 Nibble 0 -/// Bit 3-5 = DP16 Block 0 Nibble 1 Bit 27-29 = DP16 Block 2 Nibble 1 Bit 51-53 = DP16 Block 4 Nibble 1 -/// Bit 6-8 = DP16 Block 0 Nibble 2 Bit 30-32 = DP16 Block 2 Nibble 2 Bit 54-56 = DP16 Block 4 Nibble 2 -/// Bit 9-11 = DP16 Block 0 Nibble 3 Bit 33-35 = DP16 Block 2 Nibble 3 Bit 57-59 = DP16 Block 4 Nibble 3 -/// Bit 12-14 = DP16 Block 1 Nibble 0 Bit 36-38 = DP16 Block 3 Nibble 0 -/// Bit 15-17 = DP16 Block 1 Nibble 1 Bit 39-41 = DP16 Block 3 Nibble 1 -/// Bit 18-20 = DP16 Block 1 Nibble 2 Bit 42-44 = DP16 Block 3 Nibble 2 -/// Bit 21-23 = DP16 Block 1 Nibble 3 Bit 45-47 = DP16 Block 3 Nibble 3 -/// -inline fapi2::ReturnCode vpd_mt_mc_dq_ctle_res(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint64_t l_value[2]; - - memcpy(&l_value, i_blob + 82, 16); - - for (size_t i = 0; i < 2; ++i) - { - l_value[i] = be64toh(l_value[i]); - } - - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DQ_CTLE_RES, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_MC_DQ_CTLE_RES start: 82, len: 16"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_MC_DRV_IMP_ADDR decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note Memory Controller side Drive Impedance for Address Lines in Ohms. -/// -inline fapi2::ReturnCode vpd_mt_mc_drv_imp_addr(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint8_t l_value[2]; - - memcpy(&l_value, i_blob + 98, 2); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DRV_IMP_ADDR, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_MC_DRV_IMP_ADDR start: 98, len: 2"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_MC_DRV_IMP_CLK decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note Memory Controller side Drive Impedance for Clock in Ohms. -/// -inline fapi2::ReturnCode vpd_mt_mc_drv_imp_clk(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint8_t l_value[2]; - - memcpy(&l_value, i_blob + 100, 2); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DRV_IMP_CLK, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_MC_DRV_IMP_CLK start: 100, len: 2"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_MC_DRV_IMP_CNTL decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note Memory Controller side Drive Impedance for Control Lines in Ohms. -/// -inline fapi2::ReturnCode vpd_mt_mc_drv_imp_cntl(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint8_t l_value[2]; - - memcpy(&l_value, i_blob + 102, 2); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DRV_IMP_CNTL, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_MC_DRV_IMP_CNTL start: 102, len: 2"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_MC_DRV_IMP_DQ_DQS decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note Memory Controller side Drive Impedance for Data and Data Strobe Lines in Ohms. -/// -inline fapi2::ReturnCode vpd_mt_mc_drv_imp_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint8_t l_value[2]; - - memcpy(&l_value, i_blob + 104, 2); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DRV_IMP_DQ_DQS, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_MC_DRV_IMP_DQ_DQS start: 104, len: 2"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_MC_DRV_IMP_SPCKE decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note Memory Controller side Drive Impedance for Clock Enable Spare Line in Ohms. -/// -inline fapi2::ReturnCode vpd_mt_mc_drv_imp_spcke(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint8_t l_value[2]; - - memcpy(&l_value, i_blob + 106, 2); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_DRV_IMP_SPCKE, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_MC_DRV_IMP_SPCKE start: 106, len: 2"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_MC_RCV_IMP_DQ_DQS decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note Memory Controller side Receiver Impedance for Data and Data Strobe Lines in Ohms. -/// -inline fapi2::ReturnCode vpd_mt_mc_rcv_imp_dq_dqs(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint8_t l_value[2]; - - memcpy(&l_value, i_blob + 108, 2); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_MC_RCV_IMP_DQ_DQS, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_MC_RCV_IMP_DQ_DQS start: 108, len: 2"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_ODT_RD decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note READ, On Die Termination triggering bitmap. -/// -inline fapi2::ReturnCode vpd_mt_odt_rd(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, const uint8_t* i_blob) -{ - uint8_t l_value[2][2][2]; - - memcpy(&l_value, i_blob + 110, 8); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_ODT_RD, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_ODT_RD start: 110, len: 8"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_ODT_WR decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note WRITE, On Die Termination triggering bitmap. -/// -inline fapi2::ReturnCode vpd_mt_odt_wr(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, const uint8_t* i_blob) -{ - uint8_t l_value[2][2][2]; - - memcpy(&l_value, i_blob + 118, 8); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_ODT_WR, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_ODT_WR start: 118, len: 8"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_VREF_DRAM_WR decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note DRAM side Write Vref setting for DDR4. Bit encode is 01234567. Bit 0 is unused. Bit 1 is the Range. Bits 2-7 is the Value. Refer to the VrefDQ Training Table in JEDEC. -/// -inline fapi2::ReturnCode vpd_mt_vref_dram_wr(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint8_t l_value[2]; - - memcpy(&l_value, i_blob + 126, 2); - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_VREF_DRAM_WR, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_VREF_DRAM_WR start: 126, len: 2"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_VREF_MC_RD decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note Memory Controller side Read Vref setting. Dividing by 1000 gives you percentage of Vdd -/// -inline fapi2::ReturnCode vpd_mt_vref_mc_rd(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, const uint8_t* i_blob) -{ - uint32_t l_value[2]; - - memcpy(&l_value, i_blob + 128, 8); - - for (size_t i = 0; i < 2; ++i) - { - l_value[i] = be32toh(l_value[i]); - } - - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_VREF_MC_RD, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_VREF_MC_RD start: 128, len: 8"); - -fapi_try_exit: - return fapi2::current_err; -} - -/// -/// @brief ATTR_MSS_VPD_MT_WINDAGE_RD_CTR decode and set -/// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_blob the VPD blob for this MCS -/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK -/// @note Derived from calibration/characterization of read centering. Number of windage offset in units of pico-seconds[ps] with sign bit0 (0b0=positive, 0b1=negative) and value in bits1..31, so 0x8023 for example would mean "-35ps". If this is enabled, disable periodic rd_ctr in draminit_mc. Default -/// -inline fapi2::ReturnCode vpd_mt_windage_rd_ctr(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, - const uint8_t* i_blob) -{ - uint16_t l_value[2]; - - memcpy(&l_value, i_blob + 136, 4); - - for (size_t i = 0; i < 2; ++i) - { - l_value[i] = be16toh(l_value[i]); - } - - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MT_WINDAGE_RD_CTR, i_target, l_value), - "Unable to decode and set ATTR_MSS_VPD_MT_WINDAGE_RD_CTR start: 136, len: 4"); - -fapi_try_exit: - return fapi2::current_err; -} - }; // close decoder ns /// /// @brief eff_decode /// @param[in] i_target fapi2::Target<fapi2::TARGET_TYPE_MCS> -/// @param[in] i_mt_blob the MT VPD blob for this MCS +/// @param[in] i_mt_blobs std::vector of pointers to the the MT VPD blobs for this MCS's MCA /// @param[in] i_mr_blob the MR VPD blob for this MCS /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff set is OK /// @note Decodes the blobs and sets all the attributes. /// -inline fapi2::ReturnCode eff_decode(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, const uint8_t* i_mt_blob, - const uint8_t* i_mr_blob) +inline fapi2::ReturnCode eff_decode(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + const std::vector<uint8_t*>& i_mt_blob, const uint8_t* i_mr_blob) { + FAPI_TRY (decoder::vpd_mt_0_version_layout(fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_1_version_data(fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_2_signature_hash(fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_dimm_rcd_ibt(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_dram_drv_imp_dq_dqs(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_dram_rtt_nom(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_dram_rtt_park(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_dram_rtt_wr(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_mc_dq_acboost_rd_up(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_mc_dq_acboost_wr_down(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_mc_dq_acboost_wr_up(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_mc_dq_ctle_cap(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_mc_dq_ctle_res(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_mc_drv_imp_addr(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_mc_drv_imp_clk(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_mc_drv_imp_cntl(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_mc_drv_imp_dq_dqs(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_mc_drv_imp_spcke(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_mc_rcv_imp_dq_dqs(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_odt_rd(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_odt_wr(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_vref_dram_wr(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_vref_mc_rd(i_target, i_mt_blob) ); + FAPI_TRY (decoder::vpd_mt_windage_rd_ctr(i_target, i_mt_blob) ); FAPI_TRY (decoder::vpd_mr_0_version_layout(fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), i_mr_blob) ); FAPI_TRY (decoder::vpd_mr_1_version_data(fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), i_mr_blob) ); FAPI_TRY (decoder::vpd_mr_2_signature_hash(fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), i_mr_blob) ); @@ -1606,30 +1815,6 @@ inline fapi2::ReturnCode eff_decode(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& FAPI_TRY (decoder::vpd_mr_mc_phase_rot_cntl_d1_odt0(i_target, i_mr_blob) ); FAPI_TRY (decoder::vpd_mr_mc_phase_rot_cntl_d1_odt1(i_target, i_mr_blob) ); FAPI_TRY (decoder::vpd_mr_mc_2n_mode_autoset(i_target, i_mr_blob) ); - FAPI_TRY (decoder::vpd_mt_0_version_layout(fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_1_version_data(fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_2_signature_hash(fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_dimm_rcd_ibt(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_dram_drv_imp_dq_dqs(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_dram_rtt_nom(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_dram_rtt_park(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_dram_rtt_wr(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_mc_dq_acboost_rd_up(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_mc_dq_acboost_wr_down(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_mc_dq_acboost_wr_up(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_mc_dq_ctle_cap(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_mc_dq_ctle_res(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_mc_drv_imp_addr(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_mc_drv_imp_clk(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_mc_drv_imp_cntl(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_mc_drv_imp_dq_dqs(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_mc_drv_imp_spcke(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_mc_rcv_imp_dq_dqs(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_odt_rd(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_odt_wr(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_vref_dram_wr(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_vref_mc_rd(i_target, i_mt_blob) ); - FAPI_TRY (decoder::vpd_mt_windage_rd_ctr(i_target, i_mt_blob) ); fapi_try_exit: return fapi2::current_err; diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C index 181995b20..25b2869af 100644 --- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C +++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C @@ -50,15 +50,15 @@ /// fapi2::ReturnCode p9_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target ) { - mss::eff_config l_eff_config; + fapi2::ReturnCode l_rc; + std::map<uint32_t, std::shared_ptr<mss::spd::decoder> > l_factory_caches; + + mss::eff_config l_eff_config(i_target, l_rc); + FAPI_TRY(l_rc, "Unable to decode VPD for %s", mss::c_str(i_target) ); // Caches - std::map<uint32_t, std::shared_ptr<mss::spd::decoder> > l_factory_caches; FAPI_TRY( mss::spd::populate_decoder_caches(i_target, l_factory_caches) ); - // Decode the VPD for this MCS and stick it in the attributes. - FAPI_TRY( l_eff_config.decode_vpd(i_target) ); - for( const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target) ) { const auto l_dimm_pos = mss::pos(l_dimm); diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml index 4bb33c98c..e43dedb89 100644 --- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml +++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml @@ -36,7 +36,7 @@ <hwpErrors> - <hwpError> + <hwpError> <rc>RC_MSS_INVALID_TEMP_REF_RANGE</rc> <description> Invalid Temperature refresh range recieved @@ -50,9 +50,9 @@ <deconfigure> <target>DIMM_TARGET</target> </deconfigure> - </hwpError> + </hwpError> - <hwpError> + <hwpError> <rc>RC_MSS_INVALID_FINE_REFRESH_MODE</rc> <description> Invalid fine refresh mode recieved @@ -66,9 +66,9 @@ <deconfigure> <target>DIMM_TARGET</target> </deconfigure> - </hwpError> + </hwpError> - <hwpError> + <hwpError> <rc>RC_MSS_INVALID_KEY</rc> <description> Conditional that tests whether a certain key value is located in a map. @@ -82,9 +82,9 @@ <deconfigure> <target>DIMM_TARGET</target> </deconfigure> - </hwpError> + </hwpError> - <hwpError> + <hwpError> <rc>RC_MSS_INVALID_VPD_VREF_DRAM_WR_RANGE</rc> <description> Value in the VPD for VREF dram WR range is outside of the JEDEC spec's range. @@ -98,6 +98,6 @@ <deconfigure> <target>DIMM_TARGET</target> </deconfigure> - </hwpError> + </hwpError> </hwpErrors> |