diff options
author | Stephen Glancy <sglancy@us.ibm.com> | 2017-08-18 10:53:44 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-08-29 11:39:24 -0400 |
commit | 2b881ebf90218af1ce41918b214498c2574940e1 (patch) | |
tree | 5acce76de62c874ae32eff6c12d3ffa1094fc44f /src/import/chips | |
parent | 598111fc4b49f16495b41b8461fc01d49239eb42 (diff) | |
download | talos-hostboot-2b881ebf90218af1ce41918b214498c2574940e1.tar.gz talos-hostboot-2b881ebf90218af1ce41918b214498c2574940e1.zip |
Adds DDR4 hybrid NV-RDIMM support
Change-Id: Ie5cc0ed4dc6337c35df2e222cc4e220e5720f0bd
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/44974
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com>
Reviewed-by: Louis Stermole <stermole@us.ibm.com>
Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/45182
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips')
12 files changed, 291 insertions, 52 deletions
diff --git a/src/import/chips/p9/initfiles/p9n.mca.scom.initfile b/src/import/chips/p9/initfiles/p9n.mca.scom.initfile index 4cd2779a6..1b5eddf9b 100644 --- a/src/import/chips/p9/initfiles/p9n.mca.scom.initfile +++ b/src/import/chips/p9/initfiles/p9n.mca.scom.initfile @@ -23,7 +23,7 @@ #--****************************************************************************** #-- REFERENCES FOR FILE (note: exact paths may move) #--****************************************************************************** -# Files used to check what target type attributes are +# Files used to check what target type attributes are # ekb/chips/p9/procedures/xml/attribute_info/*.xml # Example: # <id>ATTR_EFF_NUM_RANKS_PER_DIMM</id> @@ -128,12 +128,12 @@ define def_SLOT1_DRAM_STACK_HEIGHT = ( MCS.ATTR_EFF_NUM_RANKS_PER_DIMM[def_POR # Entire window of possible actual waits must be > required wait # Working this out in a table # EPS NEEDED | SETTING | RESULTANT WAIT -# 5 | 2 | 5 - 8 -# 6 | 3 | 9 - 12 -# 7 | 3 | 9 - 12 -# 8 | 3 | 9 - 12 -# 9 | 3 | 9 - 12 -# 10 | 4 | 13 - 16 +# 5 | 2 | 5 - 8 +# 6 | 3 | 9 - 12 +# 7 | 3 | 9 - 12 +# 8 | 3 | 9 - 12 +# 9 | 3 | 9 - 12 +# 10 | 4 | 13 - 16 # Resulting formula: setting = ( required + 6 ) / 4 define def_MC_EPSILON_CFG_T0 = ( SYS.ATTR_PROC_EPS_READ_CYCLES_T0 + 6 ) / 4; @@ -287,7 +287,7 @@ ispy MCP.PORT0.SRQ.MBA_DSM0Q_CFG_RDTAG_DLY [when=S] { # ATTR_EFF_DIMM_T spyv, expr; # 1/17/2017 INITIAL CONCEPT (HAS SINCE BEEN ADJUSTED): - # rdtag_dly + 3 + rdptrdly > PHY DELAY + CL + # rdtag_dly + 3 + rdptrdly > PHY DELAY + CL # rdtag_dly > PHY DELAY + CL - 3 - rdptrdly # PHY DELAY = 12 for 1866 and 2133, 13 for 2400 and 2666, +1 for LRDIMM # rdptrdly = 1 @@ -755,7 +755,7 @@ ispy MC01.PORT0.ATCL.CL.CLSCOM.MCEPSQ_VECTOR_GROUP_EPSILON [when=S] { # New values 6/13/2017 in light of HW413361 # L T D dn h | m/n min m/n max # --------------------------------------------- -# 5 2(off) 1 0(off) 0(off) | SYNC +# 5 2(off) 1 0(off) 0(off) | SYNC # 3 3(on) 1 0(off) 0(off) | 727 915 # 4 3(on) 1 0(off) 0(off) | 915 1040 # 4 3(on) 0 0(off) 0(off) | 1040 1150 @@ -810,11 +810,11 @@ espy MCP.PORT0.ECC64.SCOM.MBSECCQ_DELAY_VALID_1X [when=S && ATTR_CHIP_EC_FEATURE # "L" field ispy MCP.PORT0.ECC64.ECC.SCOM.MBSECCQ_VAL_TO_DATA_DELAY [when=S && !ATTR_CHIP_EC_FEATURE_MCA_P9NDD1_ASYNC] { spyv, expr; - 5, (PROC.ATTR_MC_SYNC_MODE==1); + 5, (PROC.ATTR_MC_SYNC_MODE==1); 3, (PROC.ATTR_MC_SYNC_MODE==0) && (def_mn_freq_ratio < 915); 4, (PROC.ATTR_MC_SYNC_MODE==0) && (def_mn_freq_ratio >= 915) && (def_mn_freq_ratio < 1150); 5, (PROC.ATTR_MC_SYNC_MODE==0) && (def_mn_freq_ratio >= 1150) && (def_mn_freq_ratio < 1300); - 6, (PROC.ATTR_MC_SYNC_MODE==0) && (def_mn_freq_ratio >= 1300); + 6, (PROC.ATTR_MC_SYNC_MODE==0) && (def_mn_freq_ratio >= 1300); } # "T" field (new for DD2) @@ -827,21 +827,21 @@ espy MCP.PORT0.ECC64.ECC.SCOM.MBSECCQ_BYPASS_TENURE_3 [when=S && !ATTR_CHIP_EC_F # "D" field ispy MCP.PORT0.ECC64.ECC.SCOM.MBSECCQ_NEST_VAL_TO_DATA_DELAY [when=S && !ATTR_CHIP_EC_FEATURE_MCA_P9NDD1_ASYNC] { spyv, expr; - 1, (PROC.ATTR_MC_SYNC_MODE==1); + 1, (PROC.ATTR_MC_SYNC_MODE==1); 1, (PROC.ATTR_MC_SYNC_MODE==0) && (def_mn_freq_ratio < 1040); 0, (PROC.ATTR_MC_SYNC_MODE==0) && (def_mn_freq_ratio >= 1040) && (def_mn_freq_ratio < 1150); 1, (PROC.ATTR_MC_SYNC_MODE==0) && (def_mn_freq_ratio >= 1150) && (def_mn_freq_ratio < 1215); 0, (PROC.ATTR_MC_SYNC_MODE==0) && (def_mn_freq_ratio >= 1215) && (def_mn_freq_ratio < 1300); 1, (PROC.ATTR_MC_SYNC_MODE==0) && (def_mn_freq_ratio >= 1300) && (def_mn_freq_ratio < 1400); - 0, (PROC.ATTR_MC_SYNC_MODE==0) && (def_mn_freq_ratio >= 1400); + 0, (PROC.ATTR_MC_SYNC_MODE==0) && (def_mn_freq_ratio >= 1400); } # "dn" field espy MCP.PORT0.ECC64.ECC.SCOM.MBSECCQ_DELAY_NONBYPASS [when=S && !ATTR_CHIP_EC_FEATURE_MCA_P9NDD1_ASYNC] { spyv, expr; - OFF, (PROC.ATTR_MC_SYNC_MODE==1); + OFF, (PROC.ATTR_MC_SYNC_MODE==1); OFF, (PROC.ATTR_MC_SYNC_MODE==0) && (def_mn_freq_ratio < 1215); - ON, (PROC.ATTR_MC_SYNC_MODE==0) && (def_mn_freq_ratio >= 1215); + ON, (PROC.ATTR_MC_SYNC_MODE==0) && (def_mn_freq_ratio >= 1215); } # "h" field diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C index 9df9a63a9..2f8ee1126 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C @@ -495,7 +495,7 @@ fapi2::ReturnCode eff_dimm::dram_mfg_id() fapi_try_exit: return fapi2::current_err; -}// dimm_type +} /// /// @brief Determines & sets effective config for dram width @@ -727,27 +727,6 @@ fapi_try_exit: } /// -/// @brief Determines & sets effective config for Hybrid memory type from SPD -/// @return fapi2::FAPI2_RC_SUCCESS if okay -/// -fapi2::ReturnCode eff_dimm::hybrid_memory_type() -{ - uint8_t l_decoder_val = 0; - uint8_t l_mcs_attrs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {}; - - // Get & update MCS attribute - FAPI_TRY( eff_hybrid_memory_type(iv_mcs, &l_mcs_attrs[0][0]), "Failed to get ATTR_MSS_HYBRID_MEMORY_TYPE" ); - FAPI_TRY(iv_pDecoder->hybrid_media(l_decoder_val), "Failed to get Hybrid_media from SPD %s", mss::c_str(iv_dimm)); - - l_mcs_attrs[iv_port_index][iv_dimm_index] = l_decoder_val; - FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE, iv_mcs, l_mcs_attrs), - "Failed to set ATTR_EFF_HYBRID_MEMORY_TYPE" ); - -fapi_try_exit: - return fapi2::current_err; -} - -/// /// @brief Determines & sets effective config for refresh interval time (tREFI) /// @return fapi2::FAPI2_RC_SUCCESS if okay /// diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H index 2bbcdc44d..6da286528 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H @@ -179,12 +179,6 @@ class eff_dimm fapi2::ReturnCode primary_stack_type(); /// - /// @brief Determines & sets effective config for Hybrid memory type from SPD - /// @return fapi2::FAPI2_RC_SUCCESS if okay - /// - fapi2::ReturnCode hybrid_memory_type(); - - /// /// @brief Determines & sets effective config for refresh interval time (tREFI) /// @return fapi2::FAPI2_RC_SUCCESS if okay /// diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C b/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C index fa8da7c13..17563fc83 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C @@ -1864,7 +1864,7 @@ fapi_try_exit: /// /// @brief Helper to setup the translation map - useful for testing /// @param[in,out] io_dimm_kinds std::vector of DIMM kind's representing the DIMM (Not const as we sort the vector) -/// @param[out] fapi2::buffer<uint64_t> io_xlate00 - xlt register 0's value +/// @param[out] fapi2::buffer<uint64_t> io_xlate0 - xlt register 0's value /// @param[out] fapi2::buffer<uint64_t> io_xlate1 - xlt register 1's value /// @param[out] fapi2::buffer<uint64_t> io_xlate2 - xlt register 2's value /// @return FAPI2_RC_SUCCESS iff ok diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H index 8c60d8e35..25579e105 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H @@ -17467,7 +17467,7 @@ fapi_try_exit: /// @note Generated by gen_accessors.pl generateParameters (F) /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK /// @note Base Module Type. Decodes SPD Byte 3 (bits 3~0). Type of DIMM: RDIMM, UDIMM, -/// LRDIMM as specified by the JEDIC standard. creator: mss_eff_config consumer: +/// LRDIMM as specified by the JEDEC standard. creator: mss_eff_config consumer: /// various firmware notes: /// none /// @@ -17494,7 +17494,7 @@ fapi_try_exit: /// @note Generated by gen_accessors.pl generateParameters (G) /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK /// @note Base Module Type. Decodes SPD Byte 3 (bits 3~0). Type of DIMM: RDIMM, UDIMM, -/// LRDIMM as specified by the JEDIC standard. creator: mss_eff_config consumer: +/// LRDIMM as specified by the JEDEC standard. creator: mss_eff_config consumer: /// various firmware notes: /// none /// @@ -17526,7 +17526,7 @@ fapi_try_exit: /// @note Generated by gen_accessors.pl generateParameters (H) /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK /// @note Base Module Type. Decodes SPD Byte 3 (bits 3~0). Type of DIMM: RDIMM, UDIMM, -/// LRDIMM as specified by the JEDIC standard. creator: mss_eff_config consumer: +/// LRDIMM as specified by the JEDEC standard. creator: mss_eff_config consumer: /// various firmware notes: /// none /// diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H index 613ac3570..a0de4e1e8 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -82,7 +82,7 @@ static const std::vector< std::pair<uint8_t , uint8_t> > DIMM_TYPE_MAP = { {fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM, 0b00}, {fapi2::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM, 0b01}, - {fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM, 0b10} + {fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM, 0b10}, }; static const std::vector< std::pair<uint8_t , uint8_t> > DRAM_GEN_MAP = diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C b/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C index fd032e167..87effa9d6 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C @@ -73,6 +73,10 @@ enum factory_byte_extract ADDITIONS_LEVEL_LEN = 4, ///< SPD additions level bit length // Byte 3 + HYBRID_START = 0, ///< SPD hybrid start bit + HYBRID_LEN = 1, ///< SPD hybrid bit length + HYBRID_TYPE_START = 1, ///< SPD hybrid type start bit + HYBRID_TYPE_LEN = 3, ///< SPD hybrid type bit length BASE_MODULE_START = 4, ///< SPD base module start bit BASE_MODULE_LEN = 4, ///< SPD base module bit length }; @@ -163,6 +167,114 @@ fapi_try_exit: } /// +/// @brief Decodes hybrid type (whether or not the DIMM is a hybrid) from SPD +/// @param[in] i_target dimm target +/// @param[in] i_spd_data SPD data +/// @param[out] o_value hybrid +/// @return FAPI2_RC_SUCCESS if okay +/// @note Decodes SPD Byte 3 (bit 7) +/// @note Item JC-45-2220.01x +/// @note Page 17 +/// @note DDR4 SPD Document Release 3 +/// +fapi2::ReturnCode hybrid(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_spd_data, + uint8_t& o_value) +{ + // ========================================================= + // Byte 3 maps + // Item JC-45-2220.01x + // Page 17 + // DDR4 SPD Document Release 3 + // Byte 3 (0x003): Key Byte / Module Type - Hybrid + // ========================================================= + static const std::vector<std::pair<uint8_t, uint8_t> > HYBRID_MAP = + { + //{key byte, dimm type} + {0, fapi2::ENUM_ATTR_EFF_HYBRID_NOT_HYBRID}, + {1, fapi2::ENUM_ATTR_EFF_HYBRID_IS_HYBRID}, + // All others reserved or not supported + }; + + constexpr size_t BYTE_INDEX = 3; + constexpr field_t HYBRID{BYTE_INDEX, HYBRID_START, HYBRID_LEN}; + + // Extracting desired bits + const uint8_t l_field_bits = extract_spd_field(i_target, HYBRID, i_spd_data); + FAPI_DBG("%s. Field Bits value: %d", mss::c_str(i_target), l_field_bits); + + // Check that value is valid + const bool l_is_val_found = find_value_from_key(HYBRID_MAP, l_field_bits, o_value); + + FAPI_TRY( mss::check::spd::fail_for_invalid_value(i_target, + l_is_val_found, + HYBRID.iv_byte, + l_field_bits, + "Failed check on Hybrid") ); + + FAPI_INF("%s. Hybrid Media: %d", + mss::c_str(i_target), + o_value); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Decodes hybrid type (hybrid DIMM type) from SPD +/// @param[in] i_target dimm target +/// @param[in] i_spd_data SPD data +/// @param[out] o_value hybrid module type +/// @return FAPI2_RC_SUCCESS if okay +/// @note Decodes SPD Byte 3 (bits 6~4) +/// @note Item JC-45-2220.01x +/// @note Page 17 +/// @note DDR4 SPD Document Release 3 +/// +fapi2::ReturnCode hybrid_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_spd_data, + uint8_t& o_value) +{ + // ========================================================= + // Byte 3 maps + // Item JC-45-2220.01x + // Page 17 + // DDR4 SPD Document Release 3 + // Byte 3 (0x003): Key Byte / Module Type - Hybrid + // ========================================================= + static const std::vector<std::pair<uint8_t, uint8_t> > HYBRID_TYPE_MAP = + { + //{key byte, dimm type} + {0, fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NONE}, + {1, fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NVDIMM}, + // All others reserved or not supported + }; + + constexpr size_t BYTE_INDEX = 3; + constexpr field_t HYBRID_TYPE{BYTE_INDEX, HYBRID_TYPE_START, HYBRID_TYPE_LEN}; + + // Extracting desired bits + const uint8_t l_field_bits = extract_spd_field(i_target, HYBRID_TYPE, i_spd_data); + FAPI_DBG("%s. Field Bits value: %d", mss::c_str(i_target), l_field_bits); + + // Check that value is valid + const bool l_is_val_found = find_value_from_key(HYBRID_TYPE_MAP, l_field_bits, o_value); + + FAPI_TRY( mss::check::spd::fail_for_invalid_value(i_target, + l_is_val_found, + HYBRID_TYPE.iv_byte, + l_field_bits, + "Failed check on Hybrid Memory Type") ); + + FAPI_INF("%s. Hybrid Memory Type: %d", + mss::c_str(i_target), + o_value); + +fapi_try_exit: + return fapi2::current_err; +} + +/// /// @brief Decodes base module type (DIMM type) from SPD /// @param[in] i_target dimm target /// @param[in] i_spd_data SPD data @@ -189,7 +301,7 @@ fapi2::ReturnCode base_module_type(const fapi2::Target<TARGET_TYPE_DIMM>& i_targ //{key byte, dimm type} {1, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM}, {2, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM}, - {4, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM} + {4, fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM}, // All others reserved or not supported }; @@ -340,6 +452,68 @@ fapi_try_exit: } /// +/// @brief Helper function to set hybrid attribute +/// @param[in] i_target dimm target +/// @param[in] i_spd_data SPD data +/// @param[out] o_hybrid dimm type encoding needed by factory +/// @return FAPI2_RC_SUCCESS if okay +/// +static fapi2::ReturnCode hybrid_setter(const fapi2::Target<TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_spd_data, + uint8_t& o_hybrid) +{ + const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) ); + const auto l_dimm_num = index(i_target); + const auto l_mcs = mss::find_target<TARGET_TYPE_MCS>(i_target); + + // Get dimm type & set attribute (needed by c_str) + uint8_t l_dimm_types_mcs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {}; + + FAPI_TRY( hybrid(i_target, i_spd_data, o_hybrid), + "%s. Failed to find hybrid", mss::c_str(i_target) ); + FAPI_TRY( eff_hybrid(l_mcs, &l_dimm_types_mcs[0][0]), + "%s. Failed to invoke hybrid accessor", mss::c_str(i_target)); + + l_dimm_types_mcs[l_port_num][l_dimm_num] = o_hybrid; + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_HYBRID, l_mcs, l_dimm_types_mcs), + "%s. Failed to set ATTR_EFF_HYBRID", mss::c_str(i_target)); + +fapi_try_exit: + return fapi2::current_err; +} + +/// +/// @brief Helper function to set hybrid_type attribute +/// @param[in] i_target dimm target +/// @param[in] i_spd_data SPD data +/// @param[out] o_hybrid_type dimm type encoding needed by factory +/// @return FAPI2_RC_SUCCESS if okay +/// +static fapi2::ReturnCode hybrid_type_setter(const fapi2::Target<TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_spd_data, + uint8_t& o_hybrid_type) +{ + const auto l_port_num = index( find_target<TARGET_TYPE_MCA>(i_target) ); + const auto l_dimm_num = index(i_target); + const auto l_mcs = mss::find_target<TARGET_TYPE_MCS>(i_target); + + // Get dimm type & set attribute (needed by c_str) + uint8_t l_dimm_types_mcs[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {}; + + FAPI_TRY( hybrid_type(i_target, i_spd_data, o_hybrid_type), + "%s. Failed to find hybrid_memory_type", mss::c_str(i_target) ); + FAPI_TRY( eff_hybrid_memory_type(l_mcs, &l_dimm_types_mcs[0][0]), + "%s. Failed to invoke hybrid_memory_type accessor", mss::c_str(i_target)); + + l_dimm_types_mcs[l_port_num][l_dimm_num] = o_hybrid_type; + FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_HYBRID_MEMORY_TYPE, l_mcs, l_dimm_types_mcs), + "%s. Failed to set ATTR_EFF_HYBRID_MEMORY", mss::c_str(i_target)); + +fapi_try_exit: + return fapi2::current_err; +} + +/// /// @brief Helper function to set dram gen attribute /// @param[in] i_target dimm target /// @param[in] i_spd_data SPD data @@ -618,11 +792,15 @@ fapi2::ReturnCode raw_card_factory(const fapi2::Target<TARGET_TYPE_DIMM>& i_targ rcw_settings& o_raw_card) { uint8_t l_dimm_type = 0; + uint8_t l_hybrid = 0; + uint8_t l_hybrid_type = 0; uint8_t l_ref_raw_card_rev = 0; // Lets find out what raw card we are and grab the right // raw card settings FAPI_TRY( mss::eff_dimm_type(i_target, l_dimm_type) ); + FAPI_TRY( mss::eff_hybrid(i_target, l_hybrid) ); + FAPI_TRY( mss::eff_hybrid_memory_type(i_target, l_hybrid_type) ); FAPI_TRY( reference_raw_card(i_target, i_spd_data, l_ref_raw_card_rev) ); FAPI_INF( "Retrieved dimm_type: %d, raw card reference: 0x%lx from SPD", @@ -632,6 +810,15 @@ fapi2::ReturnCode raw_card_factory(const fapi2::Target<TARGET_TYPE_DIMM>& i_targ { case fapi2::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM: + // TODO:RTC178807 - Update how NVDIMMs are handled once more are up and running in the lab + // NVDIMM is currently considered differently than all other rdimm raw cards, due to settings differences + if((l_hybrid == fapi2::ENUM_ATTR_EFF_HYBRID_IS_HYBRID) && + (l_hybrid_type == fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NVDIMM)) + { + l_ref_raw_card_rev = mss::rdimm::raw_card_rev::NVDIMM; + FAPI_INF("%s is an NVDIMM, overwrote l_ref_raw_card_rev to be 0x%02x", mss::c_str(i_target), l_ref_raw_card_rev); + } + FAPI_ASSERT( find_value_from_key( mss::rdimm::RAW_CARDS, l_ref_raw_card_rev, o_raw_card), fapi2::MSS_INVALID_RAW_CARD() .set_DIMM_TYPE(l_dimm_type) @@ -688,6 +875,8 @@ fapi2::ReturnCode factory(const fapi2::Target<TARGET_TYPE_DIMM>& i_target, } uint8_t l_dimm_type = 0; + uint8_t l_hybrid = 0; + uint8_t l_hybrid_type = 0; uint8_t l_encoding_rev = 0; uint8_t l_additions_rev = 0; rcw_settings l_raw_card; @@ -696,6 +885,10 @@ fapi2::ReturnCode factory(const fapi2::Target<TARGET_TYPE_DIMM>& i_target, // the SPD decoder for debugging help FAPI_TRY( dimm_type_setter(i_target, i_spd_data, l_dimm_type), "%s. Failed to set DIMM type", mss::c_str(i_target) ); + FAPI_TRY( hybrid_setter(i_target, i_spd_data, l_hybrid), + "%s. Failed to set hybrid", mss::c_str(i_target) ); + FAPI_TRY( hybrid_type_setter(i_target, i_spd_data, l_hybrid_type), + "%s. Failed to set hybrid_type", mss::c_str(i_target) ); FAPI_TRY( dram_gen_setter(i_target, i_spd_data), "%s. Failed to set DRAM generation", mss::c_str(i_target) ); FAPI_TRY( raw_card_factory(i_target, i_spd_data, l_raw_card), diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.H b/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.H index 4087bf464..bb19eaf34 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.H @@ -83,6 +83,36 @@ fapi2::ReturnCode rev_additions_level(const fapi2::Target<fapi2::TARGET_TYPE_DIM uint8_t& o_value); /// +/// @brief Decodes hybrid type (whether or not the DIMM is a hybrid) from SPD +/// @param[in] i_target dimm target +/// @param[in] i_spd_data SPD data +/// @param[out] o_value hybrid +/// @return FAPI2_RC_SUCCESS if okay +/// @note Decodes SPD Byte 3 (bit 7) +/// @note Item JC-45-2220.01x +/// @note Page 17 +/// @note DDR4 SPD Document Release 3 +/// +fapi2::ReturnCode hybrid(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_spd_data, + uint8_t& o_value); + +/// +/// @brief Decodes hybrid type (hybrid DIMM type) from SPD +/// @param[in] i_target dimm target +/// @param[in] i_spd_data SPD data +/// @param[out] o_value hybrid module type +/// @return FAPI2_RC_SUCCESS if okay +/// @note Decodes SPD Byte 3 (bits 6~4) +/// @note Item JC-45-2220.01x +/// @note Page 17 +/// @note DDR4 SPD Document Release 3 +/// +fapi2::ReturnCode hybrid_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, + const std::vector<uint8_t>& i_spd_data, + uint8_t& o_value); + +/// /// @brief Decodes base module type (DIMM type) from SPD /// @param[in] i_target dimm target /// @param[in] i_spd_data SPD data diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/fake_spd.C b/src/import/chips/p9/procedures/hwp/memory/lib/utils/fake_spd.C index 41bc0b0c6..dd3322fb5 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/fake_spd.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/fake_spd.C @@ -231,6 +231,43 @@ constexpr uint8_t CUSTOM_16GB_2RX8_SPD[] = 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; +// Liberally pirated from an NVDIMM and xxd +constexpr uint8_t RDIMM_NVDIMM_HYBRID_16GB_1RX4_2400_DDR4_SPD[] = +{ + 0x23, 0x10, 0x0c, 0x91, 0x85, 0x29, 0x00, 0x08, 0x00, 0x60, 0x00, 0x03, 0x00, 0x0b, 0x80, 0x00, + 0x00, 0x00, 0x07, 0x0d, 0xf8, 0x7f, 0x00, 0x00, 0x6e, 0x6e, 0x6e, 0x11, 0x00, 0x6e, 0xf0, 0x0a, + 0x20, 0x08, 0x00, 0x05, 0x00, 0x68, 0x1b, 0x28, 0x28, 0x00, 0x78, 0x00, 0x14, 0x3c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x16, 0x04, 0x16, + 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x04, 0x16, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xb5, 0x00, 0x00, 0x00, 0x00, 0xe7, 0xd6, 0x04, 0x4e, + 0x11, 0x44, 0x1f, 0x15, 0x00, 0x80, 0xb3, 0x51, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x5c, 0x01, 0x94, 0x4e, 0x5c, 0x04, 0x1f, 0x00, 0x06, 0x00, 0x05, 0x21, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x75, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x94, 0x01, 0x17, 0x09, 0x01, 0xcc, 0xd0, 0xc1, 0x53, 0x48, 0x4e, 0x37, 0x32, 0x32, 0x47, + 0x34, 0x49, 0x42, 0x4d, 0x32, 0x34, 0x4b, 0x50, 0x31, 0x53, 0x42, 0x20, 0x20, 0x00, 0x80, 0xce, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + /// /// @brief Return a blob of SPD data from a DIMM /// @param[in] i_target a DIMM target representing the DIMM in question @@ -277,6 +314,12 @@ fapi2::ReturnCode getSPD( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target return fapi2::FAPI2_RC_SUCCESS; break; + case spd_type::RDIMM_NVDIMM_HYBRID_16GB_1RX4_2400_DDR4: + FAPI_INF("Selected SPD for RDIMM_NVDIMM_HYBRID_16GB_1RX4_2400_DDR4"); + spd_helper(RDIMM_NVDIMM_HYBRID_16GB_1RX4_2400_DDR4_SPD, o_blob, o_size); + return fapi2::FAPI2_RC_SUCCESS; + break; + default: FAPI_ERR( "Recieved invalid SPD Type: %d", static_cast<uint8_t>(i_type) ); return fapi2::FAPI2_RC_INVALID_PARAMETER; diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/fake_spd.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/fake_spd.H index 1084494b7..d74f111df 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/fake_spd.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/fake_spd.H @@ -53,6 +53,7 @@ enum class spd_type MICRON_32GB_2RX4_2400_DDR4_LRDIMM, SAMSUNG_64GB_2S2RX4_2400_DDR4_RDIMM_3DS, CUSTOM_16GB_2RX8, + RDIMM_NVDIMM_HYBRID_16GB_1RX4_2400_DDR4, }; /// 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 5a12f1e4f..54d071b5a 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 @@ -106,7 +106,6 @@ fapi2::ReturnCode p9_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MCS> FAPI_TRY( l_eff_dimm->prim_die_count(), "Error from p9_mss_eff_config"); FAPI_TRY( l_eff_dimm->primary_stack_type(), "Error from p9_mss_eff_config"); FAPI_TRY( l_eff_dimm->dimm_size(), "Error from p9_mss_eff_config"); - FAPI_TRY( l_eff_dimm->hybrid_memory_type(), "Error from p9_mss_eff_config"); FAPI_TRY( l_eff_dimm->dram_trefi(), "Error from p9_mss_eff_config"); FAPI_TRY( l_eff_dimm->dram_trfc(), "Error from p9_mss_eff_config"); FAPI_TRY( l_eff_dimm->dram_trfc_dlr(), "Error from p9_mss_eff_config"); diff --git a/src/import/chips/p9/procedures/xml/attribute_info/memory_spd_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/memory_spd_attributes.xml index c80160d5e..cad97abf9 100755 --- a/src/import/chips/p9/procedures/xml/attribute_info/memory_spd_attributes.xml +++ b/src/import/chips/p9/procedures/xml/attribute_info/memory_spd_attributes.xml @@ -49,7 +49,7 @@ <description> Base Module Type. Decodes SPD Byte 3 (bits 3~0). - Type of DIMM: RDIMM, UDIMM, LRDIMM as specified by the JEDIC standard. + Type of DIMM: RDIMM, UDIMM, LRDIMM as specified by the JEDEC standard. creator: mss_eff_config consumer: various firmware notes: none |