summaryrefslogtreecommitdiffstats
path: root/src/import/generic/memory/lib/spd
diff options
context:
space:
mode:
authorStephen Glancy <sglancy@us.ibm.com>2019-01-15 14:25:14 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2019-03-15 16:10:36 -0500
commitcd82f3ecbcef777e821b5d457e30f37f1ce15fdf (patch)
tree8fe608464a7fdd7bd810eb68bd509c8e261984e5 /src/import/generic/memory/lib/spd
parent9e1906f95ba3da384eff12814f53ade26528cb0b (diff)
downloadtalos-hostboot-cd82f3ecbcef777e821b5d457e30f37f1ce15fdf.tar.gz
talos-hostboot-cd82f3ecbcef777e821b5d457e30f37f1ce15fdf.zip
Adds DDIMM EFD decoder API
Change-Id: Ib653b02b46f9aea345c3399250da1bd6eae53a68 Original-Change-Id: I6e06b867f93c0c813be1c5f05c486569c8650f6e Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/70509 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Mark Pizzutillo <mark.pizzutillo@ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/73300 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src/import/generic/memory/lib/spd')
-rw-r--r--src/import/generic/memory/lib/spd/ddimm/ddr4/efd_ddr4_custom_microchip_decoder.H865
-rw-r--r--src/import/generic/memory/lib/spd/ddimm/ddr4/efd_fields_ddr4.H491
-rw-r--r--src/import/generic/memory/lib/spd/ddimm/ddr4/efd_traits_ddr4.H1252
-rw-r--r--src/import/generic/memory/lib/spd/ddimm/efd_decoder.H798
-rw-r--r--src/import/generic/memory/lib/spd/ddimm/efd_factory.H44
-rw-r--r--src/import/generic/memory/lib/spd/spd_reader.H2
6 files changed, 3450 insertions, 2 deletions
diff --git a/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_ddr4_custom_microchip_decoder.H b/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_ddr4_custom_microchip_decoder.H
index 27fa1976b..12a292b57 100644
--- a/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_ddr4_custom_microchip_decoder.H
+++ b/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_ddr4_custom_microchip_decoder.H
@@ -22,3 +22,868 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file efd_ddr4_custom_microchip.H
+/// @brief DDIMM Extended Functional Data (EFD) common fields
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _EFD_DDR4_CUSTOM_MICROCHIP_DECODER_H_
+#define _EFD_DDR4_CUSTOM_MICROCHIP_DECODER_H_
+
+
+#include <cstdint>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/spd/ddimm/efd_decoder.H>
+#include <generic/memory/lib/utils/mss_buffer_utils.H>
+
+namespace mss
+{
+
+namespace efd
+{
+
+///
+/// @class decoder
+/// @tparam R SPD revision - partial specialization
+/// @brief RDIMM module SPD DRAM decoder
+///
+template < mss::spd::rev R >
+class decoder<mss::spd::device_type::DDR4, DDR4_CUSTOM_MICROCHIP, R > : public base_decoder
+{
+ private:
+
+ using fields_t = fields<mss::spd::device_type::DDR4, DDR4_CUSTOM_MICROCHIP>;
+
+ public:
+
+ // deleted default ctor
+ decoder() = delete;
+
+ ///
+ /// @brief ctor
+ /// @param[in] i_target dimm target
+ /// @param[in] i_spd_data vector DIMM SPD data
+ ///
+ decoder(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t>& i_spd_data):
+ base_decoder(i_target, i_spd_data)
+ {
+ // Using the emulation value here
+ static_assert( R <= mss::spd::rev::DDIMM_MAX, " R > rev::DDIMM_MAX");
+ }
+
+ ///
+ /// @brief default dtor
+ ///
+ virtual ~decoder() = default;
+ ///
+ /// @brief Decodes Host Speed Supported -> HOST_SPEED_SUPPORTED
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode host_speed_supported(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::HOST_SPEED_SUPPORTED, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PHY ODT impedance -> PHY_ODT_IMPEDANCE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode phy_odt_impedance(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PHY_ODT_IMPEDANCE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PHY Drive impedance pull up -> PHY_DRIVE_IMPEDANCE_PULL_UP
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode phy_drive_impedance_pull_up(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PHY_DRIVE_IMPEDANCE_PULL_UP, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PHY Drive impedance pull down -> PHY_DRIVE_IMPEDANCE_PULL_DOWN
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode phy_drive_impedance_pull_down(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PHY_DRIVE_IMPEDANCE_PULL_DOWN, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PHY Drive Impedance -> PHY_DRIVE_IMPEDANCE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode phy_drive_impedance(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PHY_DRIVE_IMPEDANCE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Master Ranks Supported -> MASTER_RANKS_SUPPORTED
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode master_ranks_supported(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::MASTER_RANKS_SUPPORTED, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PHY Slew Rate DQ_DQS -> PHY_SLEW_RATE_DQ_DQS
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode phy_slew_rate_dq_dqs(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PHY_SLEW_RATE_DQ_DQS, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes ATX impedance -> ATX_IMPEDANCE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode atx_impedance(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::ATX_IMPEDANCE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes ATX Slew rate -> ATX_SLEW_RATE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode atx_slew_rate(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::ATX_SLEW_RATE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CK Impedance -> CK_IMPEDANCE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode ck_impedance(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::CK_IMPEDANCE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes CK Slew rate -> CK_SLEW_RATE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode ck_slew_rate(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::CK_SLEW_RATE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Alert ODT Impedance -> ALERT_ODT_IMPEDANCE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode alert_odt_impedance(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::ALERT_ODT_IMPEDANCE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Nom -> DRAM_RTT_NOM
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_nom(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DRAM_RTT_NOM, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Nom rank0 -> DRAM_RTT_NOM_RANK0
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_nom_rank0(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DRAM_RTT_NOM_RANK0, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Nom rank1 -> DRAM_RTT_NOM_RANK1
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_nom_rank1(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DRAM_RTT_NOM_RANK1, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Nom rank2 -> DRAM_RTT_NOM_RANK2
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_nom_rank2(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DRAM_RTT_NOM_RANK2, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Nom rank3 -> DRAM_RTT_NOM_RANK3
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_nom_rank3(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DRAM_RTT_NOM_RANK3, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT WR -> DRAM_RTT_WR
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_wr(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DRAM_RTT_WR, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT WR rank0 -> DRAM_RTT_WR_RANK0
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_wr_rank0(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DRAM_RTT_WR_RANK0, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT WR rank1 -> DRAM_RTT_WR_RANK1
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_wr_rank1(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DRAM_RTT_WR_RANK1, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT WR rank2 -> DRAM_RTT_WR_RANK2
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_wr_rank2(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DRAM_RTT_WR_RANK2, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT WR rank3 -> DRAM_RTT_WR_RANK3
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_wr_rank3(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DRAM_RTT_WR_RANK3, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Park -> DRAM_RTT_PARK
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DRAM_RTT_PARK, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Park rank0 -> DRAM_RTT_PARK_RANK0
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park_rank0(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DRAM_RTT_PARK_RANK0, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Park rank1 -> DRAM_RTT_PARK_RANK1
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park_rank1(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DRAM_RTT_PARK_RANK1, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Park rank2 -> DRAM_RTT_PARK_RANK2
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park_rank2(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DRAM_RTT_PARK_RANK2, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Park rank3 -> DRAM_RTT_PARK_RANK3
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park_rank3(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DRAM_RTT_PARK_RANK3, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM DIC -> DRAM_DIC
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_dic(uint8_t& o_output) const override
+ {
+ FAPI_TRY( (reader<fields_t::DRAM_DIC, R>
+ (iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM Preamble -> WRITE_PREAMBLE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode write_preamble(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::WRITE_PREAMBLE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DRAM Preamble -> READ_PREAMBLE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode read_preamble(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::READ_PREAMBLE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PHY Equalization -> PHY_EQUALIZATION
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode phy_equalization(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PHY_EQUALIZATION, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Initial WR VREF DQ setting -> WR_VREF_DQ_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode wr_vref_dq_range(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::WR_VREF_DQ_RANGE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Initial WR VREF DQ setting -> WR_VREF_DQ_VALUE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode wr_vref_dq_value(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::WR_VREF_DQ_VALUE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes ODT WR Map CS Byte0 -> ODT_WR_MAP_RANK3
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_wr_map_rank3(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::ODT_WR_MAP_RANK3, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes ODT WR Map CS Byte0 -> ODT_WR_MAP_RANK2
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_wr_map_rank2(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::ODT_WR_MAP_RANK2, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes ODT WR Map CS Byte0 -> ODT_WR_MAP_RANK1
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_wr_map_rank1(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::ODT_WR_MAP_RANK1, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes ODT WR Map CS Byte0 -> ODT_WR_MAP_RANK0
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_wr_map_rank0(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::ODT_WR_MAP_RANK0, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes ODT RD Map CS Byte0 -> ODT_RD_MAP_RANK3
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_rd_map_rank3(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::ODT_RD_MAP_RANK3, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes ODT RD Map CS Byte0 -> ODT_RD_MAP_RANK2
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_rd_map_rank2(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::ODT_RD_MAP_RANK2, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes ODT RD Map CS Byte0 -> ODT_RD_MAP_RANK1
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_rd_map_rank1(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::ODT_RD_MAP_RANK1, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes ODT RD Map CS Byte0 -> ODT_RD_MAP_RANK0
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_rd_map_rank0(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::ODT_RD_MAP_RANK0, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Geardown during training -> GEARDOWN_DURING_TRAINING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode geardown_during_training(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::GEARDOWN_DURING_TRAINING, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWA Volt -> PMIC0_SWA_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swa_setting(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC0_SWA_SETTING, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWA Volt -> PMIC0_SWA_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swa_range(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC0_SWA_RANGE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWB Volt -> PMIC0_SWB_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swb_setting(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC0_SWB_SETTING, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWB Volt -> PMIC0_SWB_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swb_range(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC0_SWB_RANGE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWC Volt -> PMIC0_SWC_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swc_setting(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC0_SWC_SETTING, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWC Volt -> PMIC0_SWC_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swc_range(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC0_SWC_RANGE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWD Volt -> PMIC0_SWD_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swd_setting(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC0_SWD_SETTING, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWD Volt -> PMIC0_SWD_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swd_range(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC0_SWD_RANGE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWA Volt -> PMIC1_SWA_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swa_setting(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC1_SWA_SETTING, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWA Volt -> PMIC1_SWA_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swa_range(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC1_SWA_RANGE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWB Volt -> PMIC1_SWB_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swb_setting(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC1_SWB_SETTING, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWB Volt -> PMIC1_SWB_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swb_range(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC1_SWB_RANGE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWC Volt -> PMIC1_SWC_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swc_setting(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC1_SWC_SETTING, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWC Volt -> PMIC1_SWC_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swc_range(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC1_SWC_RANGE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWD Volt -> PMIC1_SWD_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swd_setting(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC1_SWD_SETTING, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWD Volt -> PMIC1_SWD_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swd_range(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::PMIC1_SWD_RANGE, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes Channels supported byte3
+ /// @param[out] o_output encoding from SPD - multiple fields used
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note Uses the following bytes and fields to build up the combined data:
+ /// Byte 3: CHANNELS_SUPPORTED_BYTE0
+ /// Byte 4: CHANNELS_SUPPORTED_BYTE1
+ /// Byte 5: CHANNELS_SUPPORTED_BYTE2
+ /// Byte 6: CHANNELS_SUPPORTED_BYTE3
+ ///
+ virtual fapi2::ReturnCode channels_supported(uint32_t& o_output) const override
+ {
+ uint8_t l_byte0 = 0;
+ uint8_t l_byte1 = 0;
+ uint8_t l_byte2 = 0;
+ uint8_t l_byte3 = 0;
+
+ FAPI_TRY(( reader<fields_t::CHANNELS_SUPPORTED_BYTE0, R>(iv_target, iv_data, l_byte0)) );
+ FAPI_TRY(( reader<fields_t::CHANNELS_SUPPORTED_BYTE1, R>(iv_target, iv_data, l_byte1)) );
+ FAPI_TRY(( reader<fields_t::CHANNELS_SUPPORTED_BYTE2, R>(iv_target, iv_data, l_byte2)) );
+ FAPI_TRY(( reader<fields_t::CHANNELS_SUPPORTED_BYTE3, R>(iv_target, iv_data, l_byte3)) );
+
+ {
+ fapi2::buffer<uint32_t> l_buffer;
+ right_aligned_insert(l_buffer, l_byte3, l_byte2, l_byte1, l_byte0);
+ o_output = l_buffer;
+ FAPI_INF("%s. Register Manufacturer ID Code: 0x%04x",
+ spd::c_str(iv_target),
+ o_output);
+ }
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+ ///
+ /// @brief Decodes DIMMs supported -> DIMMS_SUPPORTED
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimms_supported(uint8_t& o_output) const override
+ {
+ FAPI_TRY(( reader<fields_t::DIMMS_SUPPORTED, R>(iv_target, iv_data, o_output)) );
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+};
+
+} // ns efd
+} // ns mss
+#endif
diff --git a/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_fields_ddr4.H b/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_fields_ddr4.H
index e2c82f912..4cebb9acb 100644
--- a/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_fields_ddr4.H
+++ b/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_fields_ddr4.H
@@ -22,3 +22,494 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file efd_fields_ddr4.H
+/// @brief DDIMM Extended Functional Data (EFD) common fields
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _EFD_FIELDS_DDR4_H_
+#define _EFD_FIELDS_DDR4_H_
+
+
+#include <cstdint>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/utils/mss_field.H>
+
+namespace mss
+{
+
+namespace efd
+{
+
+///
+/// @class Fields class - specialization for DDR4 custom_microchip_fields
+/// @tparam D device type (DDR4, etc.)
+/// @tparam E EFD type (ie custom EFD type 1)
+///
+template<mss::spd::device_type D, mss::efd::id E>
+class fields;
+
+///
+/// @class Fields class - specialization for DDR4 custom_microchip_fields
+/// @note Stores all field information for the custom microchip DDR4 DDIMM
+///
+template<>
+class fields<mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>
+{
+ private:
+
+ enum
+ {
+
+ // Byte 0: Host Speed Supported
+ HOST_SPEED_SUPPORTED_BYTE = 0,
+ HOST_SPEED_SUPPORTED_START = 1,
+ HOST_SPEED_SUPPORTED_LEN = 7,
+
+ // Byte 2: Master Ranks Supported
+ MASTER_RANKS_SUPPORTED_BYTE = 2,
+ MASTER_RANKS_SUPPORTED_START = 4,
+ MASTER_RANKS_SUPPORTED_LEN = 4,
+
+ // Byte 3: Channels supported byte0
+ CHANNELS_SUPPORTED_BYTE0_BYTE = 3,
+ CHANNELS_SUPPORTED_BYTE0_START = 0,
+ CHANNELS_SUPPORTED_BYTE0_LEN = 8,
+
+ // Byte 4: Channels supported byte1
+ CHANNELS_SUPPORTED_BYTE1_BYTE = 4,
+ CHANNELS_SUPPORTED_BYTE1_START = 0,
+ CHANNELS_SUPPORTED_BYTE1_LEN = 8,
+
+ // Byte 5: Channels supported byte2
+ CHANNELS_SUPPORTED_BYTE2_BYTE = 5,
+ CHANNELS_SUPPORTED_BYTE2_START = 0,
+ CHANNELS_SUPPORTED_BYTE2_LEN = 8,
+
+ // Byte 6: Channels supported byte3
+ CHANNELS_SUPPORTED_BYTE3_BYTE = 6,
+ CHANNELS_SUPPORTED_BYTE3_START = 0,
+ CHANNELS_SUPPORTED_BYTE3_LEN = 8,
+
+ // Byte 7: DIMMs supported
+ DIMMS_SUPPORTED_BYTE = 7,
+ DIMMS_SUPPORTED_START = 6,
+ DIMMS_SUPPORTED_LEN = 2,
+
+ // Byte 16: PHY ODT impedance
+ PHY_ODT_IMPEDANCE_BYTE = 16,
+ PHY_ODT_IMPEDANCE_START = 3,
+ PHY_ODT_IMPEDANCE_LEN = 5,
+
+ // Byte 17: PHY Drive impedance pull up
+ PHY_DRIVE_IMPEDANCE_PULL_UP_BYTE = 17,
+ PHY_DRIVE_IMPEDANCE_PULL_UP_START = 2,
+ PHY_DRIVE_IMPEDANCE_PULL_UP_LEN = 6,
+
+ // Byte 18: PHY Drive impedance pull down
+ PHY_DRIVE_IMPEDANCE_PULL_DOWN_BYTE = 18,
+ PHY_DRIVE_IMPEDANCE_PULL_DOWN_START = 2,
+ PHY_DRIVE_IMPEDANCE_PULL_DOWN_LEN = 6,
+
+ // Byte 19: PHY Drive Impedance
+ PHY_DRIVE_IMPEDANCE_BYTE = 19,
+ PHY_DRIVE_IMPEDANCE_START = 0,
+ PHY_DRIVE_IMPEDANCE_LEN = 8,
+
+ // Byte 20: PHY Slew Rate DQ_DQS
+ PHY_SLEW_RATE_DQ_DQS_BYTE = 20,
+ PHY_SLEW_RATE_DQ_DQS_START = 0,
+ PHY_SLEW_RATE_DQ_DQS_LEN = 8,
+
+ // Byte 21: ATX impedance
+ ATX_IMPEDANCE_BYTE = 21,
+ ATX_IMPEDANCE_START = 4,
+ ATX_IMPEDANCE_LEN = 4,
+
+ // Byte 22: ATX Slew rate
+ ATX_SLEW_RATE_BYTE = 22,
+ ATX_SLEW_RATE_START = 0,
+ ATX_SLEW_RATE_LEN = 8,
+
+ // Byte 23: CK Impedance
+ CK_IMPEDANCE_BYTE = 23,
+ CK_IMPEDANCE_START = 4,
+ CK_IMPEDANCE_LEN = 4,
+
+ // Byte 24: CK Slew rate
+ CK_SLEW_RATE_BYTE = 24,
+ CK_SLEW_RATE_START = 0,
+ CK_SLEW_RATE_LEN = 8,
+
+ // Byte 25: Alert ODT Impedance
+ ALERT_ODT_IMPEDANCE_BYTE = 25,
+ ALERT_ODT_IMPEDANCE_START = 4,
+ ALERT_ODT_IMPEDANCE_LEN = 4,
+
+ // Byte 26: DRAM RTT Nom
+ DRAM_RTT_NOM_BYTE = 26,
+ DRAM_RTT_NOM_START = 0,
+ DRAM_RTT_NOM_LEN = 8,
+
+ // Byte 27: DRAM RTT Nom rank0
+ DRAM_RTT_NOM_RANK0_BYTE = 27,
+ DRAM_RTT_NOM_RANK0_START = 4,
+ DRAM_RTT_NOM_RANK0_LEN = 4,
+
+ // Byte 28: DRAM RTT Nom rank1
+ DRAM_RTT_NOM_RANK1_BYTE = 28,
+ DRAM_RTT_NOM_RANK1_START = 4,
+ DRAM_RTT_NOM_RANK1_LEN = 4,
+
+ // Byte 29: DRAM RTT Nom rank2
+ DRAM_RTT_NOM_RANK2_BYTE = 29,
+ DRAM_RTT_NOM_RANK2_START = 4,
+ DRAM_RTT_NOM_RANK2_LEN = 4,
+
+ // Byte 30: DRAM RTT Nom rank3
+ DRAM_RTT_NOM_RANK3_BYTE = 30,
+ DRAM_RTT_NOM_RANK3_START = 4,
+ DRAM_RTT_NOM_RANK3_LEN = 4,
+
+ // Byte 31: DRAM RTT WR
+ DRAM_RTT_WR_BYTE = 31,
+ DRAM_RTT_WR_START = 0,
+ DRAM_RTT_WR_LEN = 8,
+
+ // Byte 32: DRAM RTT WR rank0
+ DRAM_RTT_WR_RANK0_BYTE = 32,
+ DRAM_RTT_WR_RANK0_START = 4,
+ DRAM_RTT_WR_RANK0_LEN = 4,
+
+ // Byte 33: DRAM RTT WR rank1
+ DRAM_RTT_WR_RANK1_BYTE = 33,
+ DRAM_RTT_WR_RANK1_START = 4,
+ DRAM_RTT_WR_RANK1_LEN = 4,
+
+ // Byte 34: DRAM RTT WR rank2
+ DRAM_RTT_WR_RANK2_BYTE = 34,
+ DRAM_RTT_WR_RANK2_START = 4,
+ DRAM_RTT_WR_RANK2_LEN = 4,
+
+ // Byte 35: DRAM RTT WR rank3
+ DRAM_RTT_WR_RANK3_BYTE = 35,
+ DRAM_RTT_WR_RANK3_START = 4,
+ DRAM_RTT_WR_RANK3_LEN = 4,
+
+ // Byte 36: DRAM RTT Park
+ DRAM_RTT_PARK_BYTE = 36,
+ DRAM_RTT_PARK_START = 0,
+ DRAM_RTT_PARK_LEN = 8,
+
+ // Byte 37: DRAM RTT Park rank0
+ DRAM_RTT_PARK_RANK0_BYTE = 37,
+ DRAM_RTT_PARK_RANK0_START = 4,
+ DRAM_RTT_PARK_RANK0_LEN = 4,
+
+ // Byte 38: DRAM RTT Park rank1
+ DRAM_RTT_PARK_RANK1_BYTE = 38,
+ DRAM_RTT_PARK_RANK1_START = 4,
+ DRAM_RTT_PARK_RANK1_LEN = 4,
+
+ // Byte 39: DRAM RTT Park rank2
+ DRAM_RTT_PARK_RANK2_BYTE = 39,
+ DRAM_RTT_PARK_RANK2_START = 4,
+ DRAM_RTT_PARK_RANK2_LEN = 4,
+
+ // Byte 40: DRAM RTT Park rank3
+ DRAM_RTT_PARK_RANK3_BYTE = 40,
+ DRAM_RTT_PARK_RANK3_START = 4,
+ DRAM_RTT_PARK_RANK3_LEN = 4,
+
+ // Byte 41: DRAM DIC
+ DRAM_DIC_BYTE = 41,
+ DRAM_DIC_START = 4,
+ DRAM_DIC_LEN = 4,
+
+ // Byte 42: DRAM Preamble
+ DRAM_PREAMBLE_BYTE = 42,
+ WRITE_PREAMBLE_START = 6,
+ WRITE_PREAMBLE_LEN = 1,
+ READ_PREAMBLE_START = 7,
+ READ_PREAMBLE_LEN = 1,
+
+ // Byte 43: PHY Equalization
+ PHY_EQUALIZATION_BYTE = 43,
+ PHY_EQUALIZATION_START = 6,
+ PHY_EQUALIZATION_LEN = 2,
+
+ // Byte 44: Initial WR VREF DQ setting
+ WR_VREF_DQ_BYTE = 44,
+ WR_VREF_DQ_RANGE_START = 1,
+ WR_VREF_DQ_RANGE_LEN = 1,
+ WR_VREF_DQ_VALUE_START = 2,
+ WR_VREF_DQ_VALUE_LEN = 6,
+
+ // Byte 45: ODT WR Map CS Byte1
+ ODT_WR_MAP1_BYTE = 45,
+ ODT_WR_MAP_RANK3_START = 0,
+ ODT_WR_MAP_RANK3_LEN = 4,
+ ODT_WR_MAP_RANK2_START = 4,
+ ODT_WR_MAP_RANK2_LEN = 4,
+
+ // Byte 46: ODT WR Map CS Byte0
+ ODT_WR_MAP0_BYTE = 46,
+ ODT_WR_MAP_RANK1_START = 0,
+ ODT_WR_MAP_RANK1_LEN = 4,
+ ODT_WR_MAP_RANK0_START = 4,
+ ODT_WR_MAP_RANK0_LEN = 4,
+
+ // Byte 47: ODT RD Map CS Byte1
+ ODT_RD_MAP1_BYTE = 47,
+ ODT_RD_MAP_RANK3_START = 0,
+ ODT_RD_MAP_RANK3_LEN = 4,
+ ODT_RD_MAP_RANK2_START = 4,
+ ODT_RD_MAP_RANK2_LEN = 4,
+
+ // Byte 48: ODT RD Map CS Byte0
+ ODT_RD_MAP0_BYTE = 48,
+ ODT_RD_MAP_RANK1_START = 0,
+ ODT_RD_MAP_RANK1_LEN = 4,
+ ODT_RD_MAP_RANK0_START = 4,
+ ODT_RD_MAP_RANK0_LEN = 4,
+
+ // Byte 49: Geardown during training
+ GEARDOWN_DURING_TRAINING_BYTE = 49,
+ GEARDOWN_DURING_TRAINING_START = 7,
+ GEARDOWN_DURING_TRAINING_LEN = 1,
+
+ // Byte 50: PMIC0 SWA Volt
+ PMIC0_SWA_BYTE = 50,
+ PMIC0_SWA_SETTING_START = 0,
+ PMIC0_SWA_SETTING_LEN = 7,
+ PMIC0_SWA_RANGE_START = 7,
+ PMIC0_SWA_RANGE_LEN = 1,
+
+ // Byte 51: PMIC0 SWB Volt
+ PMIC0_SWB_BYTE = 51,
+ PMIC0_SWB_SETTING_START = 0,
+ PMIC0_SWB_SETTING_LEN = 7,
+ PMIC0_SWB_RANGE_START = 7,
+ PMIC0_SWB_RANGE_LEN = 1,
+
+ // Byte 52: PMIC0 SWC Volt
+ PMIC0_SWC_BYTE = 52,
+ PMIC0_SWC_SETTING_START = 0,
+ PMIC0_SWC_SETTING_LEN = 7,
+ PMIC0_SWC_RANGE_START = 7,
+ PMIC0_SWC_RANGE_LEN = 1,
+
+ // Byte 53: PMIC0 SWD Volt
+ PMIC0_SWD_BYTE = 53,
+ PMIC0_SWD_SETTING_START = 0,
+ PMIC0_SWD_SETTING_LEN = 7,
+ PMIC0_SWD_RANGE_START = 7,
+ PMIC0_SWD_RANGE_LEN = 1,
+
+ // Byte 54: PMIC1 SWA Volt
+ PMIC1_SWA_BYTE = 54,
+ PMIC1_SWA_SETTING_START = 0,
+ PMIC1_SWA_SETTING_LEN = 7,
+ PMIC1_SWA_RANGE_START = 7,
+ PMIC1_SWA_RANGE_LEN = 1,
+
+ // Byte 55: PMIC1 SWB Volt
+ PMIC1_SWB_BYTE = 55,
+ PMIC1_SWB_SETTING_START = 0,
+ PMIC1_SWB_SETTING_LEN = 7,
+ PMIC1_SWB_RANGE_START = 7,
+ PMIC1_SWB_RANGE_LEN = 1,
+
+ // Byte 56: PMIC1 SWC Volt
+ PMIC1_SWC_BYTE = 56,
+ PMIC1_SWC_SETTING_START = 0,
+ PMIC1_SWC_SETTING_LEN = 7,
+ PMIC1_SWC_RANGE_START = 7,
+ PMIC1_SWC_RANGE_LEN = 1,
+
+ // Byte 57: PMIC1 SWD Volt
+ PMIC1_SWD_BYTE = 57,
+ PMIC1_SWD_SETTING_START = 0,
+ PMIC1_SWD_SETTING_LEN = 7,
+ PMIC1_SWD_RANGE_START = 7,
+ PMIC1_SWD_RANGE_LEN = 1,
+ };
+
+ public:
+ // Syntatic sugar to make member variable declaration easier
+ using field_t = mss::field_t<mss::endian::LITTLE>;
+
+ // First field - SPD byte
+ // Second field - start bit
+ // Third field - bit length
+
+ // Byte 0: Host Speed Supported
+ static constexpr field_t HOST_SPEED_SUPPORTED{HOST_SPEED_SUPPORTED_BYTE, HOST_SPEED_SUPPORTED_START, HOST_SPEED_SUPPORTED_LEN};
+
+ // Byte 2: Master Ranks Supported
+ static constexpr field_t MASTER_RANKS_SUPPORTED{MASTER_RANKS_SUPPORTED_BYTE, MASTER_RANKS_SUPPORTED_START, MASTER_RANKS_SUPPORTED_LEN};
+
+ // Byte 3: Channels supported byte0
+ static constexpr field_t CHANNELS_SUPPORTED_BYTE0{CHANNELS_SUPPORTED_BYTE0_BYTE, CHANNELS_SUPPORTED_BYTE0_START, CHANNELS_SUPPORTED_BYTE0_LEN};
+
+ // Byte 4: Channels supported byte1
+ static constexpr field_t CHANNELS_SUPPORTED_BYTE1{CHANNELS_SUPPORTED_BYTE1_BYTE, CHANNELS_SUPPORTED_BYTE1_START, CHANNELS_SUPPORTED_BYTE1_LEN};
+
+ // Byte 5: Channels supported byte2
+ static constexpr field_t CHANNELS_SUPPORTED_BYTE2{CHANNELS_SUPPORTED_BYTE2_BYTE, CHANNELS_SUPPORTED_BYTE2_START, CHANNELS_SUPPORTED_BYTE2_LEN};
+
+ // Byte 6: Channels supported byte3
+ static constexpr field_t CHANNELS_SUPPORTED_BYTE3{CHANNELS_SUPPORTED_BYTE3_BYTE, CHANNELS_SUPPORTED_BYTE3_START, CHANNELS_SUPPORTED_BYTE3_LEN};
+
+ // Byte 7: DIMMs supported
+ static constexpr field_t DIMMS_SUPPORTED{DIMMS_SUPPORTED_BYTE, DIMMS_SUPPORTED_START, DIMMS_SUPPORTED_LEN};
+
+ // Byte 16: PHY ODT impedance
+ static constexpr field_t PHY_ODT_IMPEDANCE{PHY_ODT_IMPEDANCE_BYTE, PHY_ODT_IMPEDANCE_START, PHY_ODT_IMPEDANCE_LEN};
+
+ // Byte 17: PHY Drive impedance pull up
+ static constexpr field_t PHY_DRIVE_IMPEDANCE_PULL_UP{PHY_DRIVE_IMPEDANCE_PULL_UP_BYTE, PHY_DRIVE_IMPEDANCE_PULL_UP_START, PHY_DRIVE_IMPEDANCE_PULL_UP_LEN};
+
+ // Byte 18: PHY Drive impedance pull down
+ static constexpr field_t PHY_DRIVE_IMPEDANCE_PULL_DOWN{PHY_DRIVE_IMPEDANCE_PULL_DOWN_BYTE, PHY_DRIVE_IMPEDANCE_PULL_DOWN_START, PHY_DRIVE_IMPEDANCE_PULL_DOWN_LEN};
+
+ // Byte 19: PHY Drive Impedance
+ static constexpr field_t PHY_DRIVE_IMPEDANCE{PHY_DRIVE_IMPEDANCE_BYTE, PHY_DRIVE_IMPEDANCE_START, PHY_DRIVE_IMPEDANCE_LEN};
+
+ // Byte 20: PHY Slew Rate DQ_DQS
+ static constexpr field_t PHY_SLEW_RATE_DQ_DQS{PHY_SLEW_RATE_DQ_DQS_BYTE, PHY_SLEW_RATE_DQ_DQS_START, PHY_SLEW_RATE_DQ_DQS_LEN};
+
+ // Byte 21: ATX impedance
+ static constexpr field_t ATX_IMPEDANCE{ATX_IMPEDANCE_BYTE, ATX_IMPEDANCE_START, ATX_IMPEDANCE_LEN};
+
+ // Byte 22: ATX Slew rate
+ static constexpr field_t ATX_SLEW_RATE{ATX_SLEW_RATE_BYTE, ATX_SLEW_RATE_START, ATX_SLEW_RATE_LEN};
+
+ // Byte 23: CK Impedance
+ static constexpr field_t CK_IMPEDANCE{CK_IMPEDANCE_BYTE, CK_IMPEDANCE_START, CK_IMPEDANCE_LEN};
+
+ // Byte 24: CK Slew rate
+ static constexpr field_t CK_SLEW_RATE{CK_SLEW_RATE_BYTE, CK_SLEW_RATE_START, CK_SLEW_RATE_LEN};
+
+ // Byte 25: Alert ODT Impedance
+ static constexpr field_t ALERT_ODT_IMPEDANCE{ALERT_ODT_IMPEDANCE_BYTE, ALERT_ODT_IMPEDANCE_START, ALERT_ODT_IMPEDANCE_LEN};
+
+ // Byte 26: DRAM RTT Nom
+ static constexpr field_t DRAM_RTT_NOM{DRAM_RTT_NOM_BYTE, DRAM_RTT_NOM_START, DRAM_RTT_NOM_LEN};
+
+ // Byte 27: DRAM RTT Nom rank0
+ static constexpr field_t DRAM_RTT_NOM_RANK0{DRAM_RTT_NOM_RANK0_BYTE, DRAM_RTT_NOM_RANK0_START, DRAM_RTT_NOM_RANK0_LEN};
+
+ // Byte 28: DRAM RTT Nom rank1
+ static constexpr field_t DRAM_RTT_NOM_RANK1{DRAM_RTT_NOM_RANK1_BYTE, DRAM_RTT_NOM_RANK1_START, DRAM_RTT_NOM_RANK1_LEN};
+
+ // Byte 29: DRAM RTT Nom rank2
+ static constexpr field_t DRAM_RTT_NOM_RANK2{DRAM_RTT_NOM_RANK2_BYTE, DRAM_RTT_NOM_RANK2_START, DRAM_RTT_NOM_RANK2_LEN};
+
+ // Byte 30: DRAM RTT Nom rank3
+ static constexpr field_t DRAM_RTT_NOM_RANK3{DRAM_RTT_NOM_RANK3_BYTE, DRAM_RTT_NOM_RANK3_START, DRAM_RTT_NOM_RANK3_LEN};
+
+ // Byte 31: DRAM RTT WR
+ static constexpr field_t DRAM_RTT_WR{DRAM_RTT_WR_BYTE, DRAM_RTT_WR_START, DRAM_RTT_WR_LEN};
+
+ // Byte 32: DRAM RTT WR rank0
+ static constexpr field_t DRAM_RTT_WR_RANK0{DRAM_RTT_WR_RANK0_BYTE, DRAM_RTT_WR_RANK0_START, DRAM_RTT_WR_RANK0_LEN};
+
+ // Byte 33: DRAM RTT WR rank1
+ static constexpr field_t DRAM_RTT_WR_RANK1{DRAM_RTT_WR_RANK1_BYTE, DRAM_RTT_WR_RANK1_START, DRAM_RTT_WR_RANK1_LEN};
+
+ // Byte 34: DRAM RTT WR rank2
+ static constexpr field_t DRAM_RTT_WR_RANK2{DRAM_RTT_WR_RANK2_BYTE, DRAM_RTT_WR_RANK2_START, DRAM_RTT_WR_RANK2_LEN};
+
+ // Byte 35: DRAM RTT WR rank3
+ static constexpr field_t DRAM_RTT_WR_RANK3{DRAM_RTT_WR_RANK3_BYTE, DRAM_RTT_WR_RANK3_START, DRAM_RTT_WR_RANK3_LEN};
+
+ // Byte 36: DRAM RTT Park
+ static constexpr field_t DRAM_RTT_PARK{DRAM_RTT_PARK_BYTE, DRAM_RTT_PARK_START, DRAM_RTT_PARK_LEN};
+
+ // Byte 37: DRAM RTT Park rank0
+ static constexpr field_t DRAM_RTT_PARK_RANK0{DRAM_RTT_PARK_RANK0_BYTE, DRAM_RTT_PARK_RANK0_START, DRAM_RTT_PARK_RANK0_LEN};
+
+ // Byte 38: DRAM RTT Park rank1
+ static constexpr field_t DRAM_RTT_PARK_RANK1{DRAM_RTT_PARK_RANK1_BYTE, DRAM_RTT_PARK_RANK1_START, DRAM_RTT_PARK_RANK1_LEN};
+
+ // Byte 39: DRAM RTT Park rank2
+ static constexpr field_t DRAM_RTT_PARK_RANK2{DRAM_RTT_PARK_RANK2_BYTE, DRAM_RTT_PARK_RANK2_START, DRAM_RTT_PARK_RANK2_LEN};
+
+ // Byte 40: DRAM RTT Park rank3
+ static constexpr field_t DRAM_RTT_PARK_RANK3{DRAM_RTT_PARK_RANK3_BYTE, DRAM_RTT_PARK_RANK3_START, DRAM_RTT_PARK_RANK3_LEN};
+
+ // Byte 41: DRAM DIC
+ static constexpr field_t DRAM_DIC{DRAM_DIC_BYTE, DRAM_DIC_START, DRAM_DIC_LEN};
+
+ // Byte 42: DRAM Preamble
+ static constexpr field_t WRITE_PREAMBLE{DRAM_PREAMBLE_BYTE, WRITE_PREAMBLE_START, WRITE_PREAMBLE_LEN};
+ static constexpr field_t READ_PREAMBLE{DRAM_PREAMBLE_BYTE, READ_PREAMBLE_START, READ_PREAMBLE_LEN};
+
+ // Byte 43: PHY Equalization
+ static constexpr field_t PHY_EQUALIZATION{PHY_EQUALIZATION_BYTE, PHY_EQUALIZATION_START, PHY_EQUALIZATION_LEN};
+
+ // Byte 44: Initial WR VREF DQ setting
+ static constexpr field_t WR_VREF_DQ_RANGE{WR_VREF_DQ_BYTE, WR_VREF_DQ_RANGE_START, WR_VREF_DQ_RANGE_LEN};
+ static constexpr field_t WR_VREF_DQ_VALUE{WR_VREF_DQ_BYTE, WR_VREF_DQ_VALUE_START, WR_VREF_DQ_VALUE_LEN};
+
+ // Byte 45: ODT WR Map CS Byte1
+ static constexpr field_t ODT_WR_MAP_RANK3{ODT_WR_MAP1_BYTE, ODT_WR_MAP_RANK3_START, ODT_WR_MAP_RANK3_LEN};
+ static constexpr field_t ODT_WR_MAP_RANK2{ODT_WR_MAP1_BYTE, ODT_WR_MAP_RANK2_START, ODT_WR_MAP_RANK2_LEN};
+
+ // Byte 46: ODT WR Map CS Byte0
+ static constexpr field_t ODT_WR_MAP_RANK1{ODT_WR_MAP0_BYTE, ODT_WR_MAP_RANK1_START, ODT_WR_MAP_RANK1_LEN};
+ static constexpr field_t ODT_WR_MAP_RANK0{ODT_WR_MAP0_BYTE, ODT_WR_MAP_RANK0_START, ODT_WR_MAP_RANK0_LEN};
+
+ // Byte 47: ODT RD Map CS Byte1
+ static constexpr field_t ODT_RD_MAP_RANK3{ODT_RD_MAP1_BYTE, ODT_RD_MAP_RANK3_START, ODT_RD_MAP_RANK3_LEN};
+ static constexpr field_t ODT_RD_MAP_RANK2{ODT_RD_MAP1_BYTE, ODT_RD_MAP_RANK2_START, ODT_RD_MAP_RANK2_LEN};
+
+ // Byte 48: ODT RD Map CS Byte0
+ static constexpr field_t ODT_RD_MAP_RANK1{ODT_RD_MAP0_BYTE, ODT_RD_MAP_RANK1_START, ODT_RD_MAP_RANK1_LEN};
+ static constexpr field_t ODT_RD_MAP_RANK0{ODT_RD_MAP0_BYTE, ODT_RD_MAP_RANK0_START, ODT_RD_MAP_RANK0_LEN};
+
+ // Byte 49: Geardown during training
+ static constexpr field_t GEARDOWN_DURING_TRAINING{GEARDOWN_DURING_TRAINING_BYTE, GEARDOWN_DURING_TRAINING_START, GEARDOWN_DURING_TRAINING_LEN};
+
+ // Byte 50: PMIC0 SWA Volt
+ static constexpr field_t PMIC0_SWA_SETTING{PMIC0_SWA_BYTE, PMIC0_SWA_SETTING_START, PMIC0_SWA_SETTING_LEN};
+ static constexpr field_t PMIC0_SWA_RANGE{PMIC0_SWA_BYTE, PMIC0_SWA_RANGE_START, PMIC0_SWA_RANGE_LEN};
+
+ // Byte 51: PMIC0 SWB Volt
+ static constexpr field_t PMIC0_SWB_SETTING{PMIC0_SWB_BYTE, PMIC0_SWB_SETTING_START, PMIC0_SWB_SETTING_LEN};
+ static constexpr field_t PMIC0_SWB_RANGE{PMIC0_SWB_BYTE, PMIC0_SWB_RANGE_START, PMIC0_SWB_RANGE_LEN};
+
+ // Byte 52: PMIC0 SWC Volt
+ static constexpr field_t PMIC0_SWC_SETTING{PMIC0_SWC_BYTE, PMIC0_SWC_SETTING_START, PMIC0_SWC_SETTING_LEN};
+ static constexpr field_t PMIC0_SWC_RANGE{PMIC0_SWC_BYTE, PMIC0_SWC_RANGE_START, PMIC0_SWC_RANGE_LEN};
+
+ // Byte 53: PMIC0 SWD Volt
+ static constexpr field_t PMIC0_SWD_SETTING{PMIC0_SWD_BYTE, PMIC0_SWD_SETTING_START, PMIC0_SWD_SETTING_LEN};
+ static constexpr field_t PMIC0_SWD_RANGE{PMIC0_SWD_BYTE, PMIC0_SWD_RANGE_START, PMIC0_SWD_RANGE_LEN};
+
+ // Byte 54: PMIC1 SWA Volt
+ static constexpr field_t PMIC1_SWA_SETTING{PMIC1_SWA_BYTE, PMIC1_SWA_SETTING_START, PMIC1_SWA_SETTING_LEN};
+ static constexpr field_t PMIC1_SWA_RANGE{PMIC1_SWA_BYTE, PMIC1_SWA_RANGE_START, PMIC1_SWA_RANGE_LEN};
+
+ // Byte 55: PMIC1 SWB Volt
+ static constexpr field_t PMIC1_SWB_SETTING{PMIC1_SWB_BYTE, PMIC1_SWB_SETTING_START, PMIC1_SWB_SETTING_LEN};
+ static constexpr field_t PMIC1_SWB_RANGE{PMIC1_SWB_BYTE, PMIC1_SWB_RANGE_START, PMIC1_SWB_RANGE_LEN};
+
+ // Byte 56: PMIC1 SWC Volt
+ static constexpr field_t PMIC1_SWC_SETTING{PMIC1_SWC_BYTE, PMIC1_SWC_SETTING_START, PMIC1_SWC_SETTING_LEN};
+ static constexpr field_t PMIC1_SWC_RANGE{PMIC1_SWC_BYTE, PMIC1_SWC_RANGE_START, PMIC1_SWC_RANGE_LEN};
+
+ // Byte 57: PMIC1 SWD Volt
+ static constexpr field_t PMIC1_SWD_SETTING{PMIC1_SWD_BYTE, PMIC1_SWD_SETTING_START, PMIC1_SWD_SETTING_LEN};
+ static constexpr field_t PMIC1_SWD_RANGE{PMIC1_SWD_BYTE, PMIC1_SWD_RANGE_START, PMIC1_SWD_RANGE_LEN};
+};
+
+} // ns efd
+} // ns mss
+#endif
diff --git a/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_traits_ddr4.H b/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_traits_ddr4.H
index 46eb03f75..b292d4180 100644
--- a/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_traits_ddr4.H
+++ b/src/import/generic/memory/lib/spd/ddimm/ddr4/efd_traits_ddr4.H
@@ -22,3 +22,1255 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file efd_traits_ddr4.H
+/// @brief Declaration for assocated traits to reading EFD
+///
+
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB:FSP
+
+#ifndef _EFD_TRAITS_DDR4_H_
+#define _EFD_TRAITS_DDR4_H_
+
+
+#include <cstdint>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/spd/ddimm/ddr4/efd_fields_ddr4.H>
+
+namespace mss
+{
+
+namespace efd
+{
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam F holds EFD field info
+/// @tparam R the revision of the SPD field
+///
+template< const field_t<endian::LITTLE>& F, mss::spd::rev R >
+class readerTraits;
+
+//////////////////////////////////////////////////////////////////////
+/// COMMON TRAITS START HERE
+//////////////////////////////////////////////////////////////////////
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note HOST_SPEED_SUPPORTED field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::HOST_SPEED_SUPPORTED, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x7f;
+ static constexpr const char* FIELD_STR = "Host Speed Supported";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note MASTER_RANKS_SUPPORTED field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::MASTER_RANKS_SUPPORTED, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x0f;
+ static constexpr const char* FIELD_STR = "Master Ranks Supported";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CHANNELS_SUPPORTED_BYTE0 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CHANNELS_SUPPORTED_BYTE0, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0xff;
+ static constexpr const char* FIELD_STR = "Channels supported byte0";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CHANNELS_SUPPORTED_BYTE1 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CHANNELS_SUPPORTED_BYTE1, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0xff;
+ static constexpr const char* FIELD_STR = "Channels supported byte1";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CHANNELS_SUPPORTED_BYTE2 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CHANNELS_SUPPORTED_BYTE2, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0xff;
+ static constexpr const char* FIELD_STR = "Channels supported byte2";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CHANNELS_SUPPORTED_BYTE3 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CHANNELS_SUPPORTED_BYTE3, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0xff;
+ static constexpr const char* FIELD_STR = "Channels supported byte3";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DIMMS_SUPPORTED field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DIMMS_SUPPORTED, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x03;
+ static constexpr const char* FIELD_STR = "DIMMs supported";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+//////////////////////////////////////////////////////////////////////
+/// CUSTOM MICROCHIP SPECIFIC TRAITS START HERE
+//////////////////////////////////////////////////////////////////////
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PHY_ODT_IMPEDANCE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PHY_ODT_IMPEDANCE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x05;
+ static constexpr const char* FIELD_STR = "PHY ODT impedance";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PHY_DRIVE_IMPEDANCE_PULL_UP field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PHY_DRIVE_IMPEDANCE_PULL_UP, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x11;
+ static constexpr const char* FIELD_STR = "PHY ODT impedance Pull up";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PHY_DRIVE_IMPEDANCE_PULL_DOWN field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PHY_DRIVE_IMPEDANCE_PULL_DOWN, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x11;
+ static constexpr const char* FIELD_STR = "PHY ODT impedance Pull up";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PHY_DRIVE_IMPEDANCE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PHY_DRIVE_IMPEDANCE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x00;
+ static constexpr const char* FIELD_STR = "PHY Drive Impedance";
+
+ template <typename T>
+ using COMPARISON_OP = std::equal_to<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PHY_SLEW_RATE_DQ_DQS field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PHY_SLEW_RATE_DQ_DQS, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x00;
+ static constexpr const char* FIELD_STR = "PHY Slew Rate DQ_DQS";
+
+ template <typename T>
+ using COMPARISON_OP = std::equal_to<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note ATX_IMPEDANCE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::ATX_IMPEDANCE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x06;
+ static constexpr const char* FIELD_STR = "ATX impedance";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note ATX_SLEW_RATE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::ATX_SLEW_RATE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x00;
+ static constexpr const char* FIELD_STR = "ATX Slew rate";
+
+ template <typename T>
+ using COMPARISON_OP = std::equal_to<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CK_IMPEDANCE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CK_IMPEDANCE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x06;
+ static constexpr const char* FIELD_STR = "CK Impedance";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note CK_SLEW_RATE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::CK_SLEW_RATE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x00;
+ static constexpr const char* FIELD_STR = "CK Slew rate";
+
+ template <typename T>
+ using COMPARISON_OP = std::equal_to<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note ALERT_ODT_IMPEDANCE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::ALERT_ODT_IMPEDANCE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x06;
+ static constexpr const char* FIELD_STR = "Alert ODT Impedance";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_RTT_NOM field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_RTT_NOM, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x00;
+ static constexpr const char* FIELD_STR = "DRAM RTT Nom";
+
+ template <typename T>
+ using COMPARISON_OP = std::equal_to<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_RTT_NOM_RANK0 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_RTT_NOM_RANK0, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "DRAM RTT Nom rank0";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_RTT_NOM_RANK1 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_RTT_NOM_RANK1, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "DRAM RTT Nom rank1";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_RTT_NOM_RANK2 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_RTT_NOM_RANK2, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "DRAM RTT Nom rank2";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_RTT_NOM_RANK3 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_RTT_NOM_RANK3, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "DRAM RTT Nom rank3";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_RTT_WR field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_RTT_WR, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x00;
+ static constexpr const char* FIELD_STR = "DRAM RTT WR";
+
+ template <typename T>
+ using COMPARISON_OP = std::equal_to<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_RTT_WR_RANK0 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_RTT_WR_RANK0, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x04;
+ static constexpr const char* FIELD_STR = "DRAM RTT WR rank0";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_RTT_WR_RANK1 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_RTT_WR_RANK1, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x04;
+ static constexpr const char* FIELD_STR = "DRAM RTT WR rank1";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_RTT_WR_RANK2 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_RTT_WR_RANK2, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x04;
+ static constexpr const char* FIELD_STR = "DRAM RTT WR rank2";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_RTT_WR_RANK3 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_RTT_WR_RANK3, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x04;
+ static constexpr const char* FIELD_STR = "DRAM RTT WR rank3";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_RTT_PARK field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_RTT_PARK, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x00;
+ static constexpr const char* FIELD_STR = "DRAM RTT Park";
+
+ template <typename T>
+ using COMPARISON_OP = std::equal_to<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_RTT_PARK_RANK0 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_RTT_PARK_RANK0, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "DRAM RTT Park rank0";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_RTT_PARK_RANK1 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_RTT_PARK_RANK1, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "DRAM RTT Park rank1";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_RTT_PARK_RANK2 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_RTT_PARK_RANK2, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "DRAM RTT Park rank2";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_RTT_PARK_RANK3 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_RTT_PARK_RANK3, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x07;
+ static constexpr const char* FIELD_STR = "DRAM RTT Park rank3";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note DRAM_DIC field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::DRAM_DIC, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x02;
+ static constexpr const char* FIELD_STR = "DRAM DIC";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note WRITE_PREAMBLE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::WRITE_PREAMBLE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x01;
+ static constexpr const char* FIELD_STR = "Write Preamble";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note READ_PREAMBLE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::READ_PREAMBLE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x01;
+ static constexpr const char* FIELD_STR = "Read Preamble";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PHY_EQUALIZATION field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PHY_EQUALIZATION, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x03;
+ static constexpr const char* FIELD_STR = "PHY Equalization";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note WR_VREF_DQ_RANGE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::WR_VREF_DQ_RANGE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x01;
+ static constexpr const char* FIELD_STR = "Initial WR VREF DQ Range";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note WR_VREF_DQ_VALUE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::WR_VREF_DQ_VALUE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x32;
+ static constexpr const char* FIELD_STR = "Initial WR VREF DQ Value";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note ODT_WR_MAP_RANK3 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::ODT_WR_MAP_RANK3, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x0f;
+ static constexpr const char* FIELD_STR = "ODT WR Map Rank3";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note ODT_WR_MAP_RANK2 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::ODT_WR_MAP_RANK2, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x0f;
+ static constexpr const char* FIELD_STR = "ODT WR Map Rank2";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note ODT_WR_MAP_RANK1 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::ODT_WR_MAP_RANK1, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x0f;
+ static constexpr const char* FIELD_STR = "ODT WR Map Rank1";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note ODT_WR_MAP_RANK0 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::ODT_WR_MAP_RANK0, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x0f;
+ static constexpr const char* FIELD_STR = "ODT WR Map Rank0";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note ODT_RD_MAP_RANK3 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::ODT_RD_MAP_RANK3, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x0f;
+ static constexpr const char* FIELD_STR = "ODT RD Map Rank3";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note ODT_RD_MAP_RANK2 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::ODT_RD_MAP_RANK2, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x0f;
+ static constexpr const char* FIELD_STR = "ODT RD Map Rank2";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note ODT_RD_MAP_RANK1 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::ODT_RD_MAP_RANK1, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x0f;
+ static constexpr const char* FIELD_STR = "ODT RD Map Rank1";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note ODT_RD_MAP_RANK0 field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::ODT_RD_MAP_RANK0, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x0f;
+ static constexpr const char* FIELD_STR = "ODT RD Map Rank0";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note GEARDOWN_DURING_TRAINING field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits
+ < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::GEARDOWN_DURING_TRAINING, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x01;
+ static constexpr const char* FIELD_STR = "Geardown during training";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC0_SWA_SETTING field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWA_SETTING, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x3f;
+ static constexpr const char* FIELD_STR = "PMIC0 SWA Setting";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC0_SWA_RANGE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWA_RANGE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x01;
+ static constexpr const char* FIELD_STR = "PMIC0 SWA Range";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC0_SWB_SETTING field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWB_SETTING, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x3f;
+ static constexpr const char* FIELD_STR = "PMIC0 SWB Setting";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC0_SWB_RANGE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWB_RANGE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x01;
+ static constexpr const char* FIELD_STR = "PMIC0 SWB Range";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC0_SWC_SETTING field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWC_SETTING, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x3f;
+ static constexpr const char* FIELD_STR = "PMIC0 SWC Setting";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC0_SWC_RANGE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWC_RANGE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x01;
+ static constexpr const char* FIELD_STR = "PMIC0 SWC Range";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC0_SWD_SETTING field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWD_SETTING, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x3f;
+ static constexpr const char* FIELD_STR = "PMIC0 SWD Setting";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC0_SWD_RANGE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC0_SWD_RANGE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x01;
+ static constexpr const char* FIELD_STR = "PMIC0 SWD Range";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC1_SWA_SETTING field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWA_SETTING, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x3f;
+ static constexpr const char* FIELD_STR = "PMIC1 SWA Setting";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC1_SWA_RANGE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWA_RANGE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x01;
+ static constexpr const char* FIELD_STR = "PMIC1 SWA Range";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC1_SWB_SETTING field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWB_SETTING, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x3f;
+ static constexpr const char* FIELD_STR = "PMIC1 SWB Setting";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC1_SWB_RANGE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWB_RANGE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x01;
+ static constexpr const char* FIELD_STR = "PMIC1 SWB Range";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC1_SWC_SETTING field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWC_SETTING, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x3f;
+ static constexpr const char* FIELD_STR = "PMIC1 SWC Setting";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC1_SWC_RANGE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWC_RANGE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x01;
+ static constexpr const char* FIELD_STR = "PMIC1 SWC Range";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC1_SWD_SETTING field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWD_SETTING, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x3f;
+ static constexpr const char* FIELD_STR = "PMIC1 SWD Setting";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+///
+/// @class readerTraits
+/// @brief trait structure to hold static SPD information
+/// @tparam R the revision of the SPD field
+/// @note PMIC1_SWD_RANGE field specialization
+/// @note valid for all revs
+///
+template< mss::spd::rev R >
+class readerTraits < fields< mss::spd::device_type::DDR4, mss::efd::id::DDR4_CUSTOM_MICROCHIP>::PMIC1_SWD_RANGE, R >
+{
+ public:
+
+ static constexpr size_t COMPARISON_VAL = 0x01;
+ static constexpr const char* FIELD_STR = "PMIC1 SWD Range";
+
+ template <typename T>
+ using COMPARISON_OP = std::less_equal<T>;
+};
+
+} // ns efd
+} // ns mss
+#endif
diff --git a/src/import/generic/memory/lib/spd/ddimm/efd_decoder.H b/src/import/generic/memory/lib/spd/ddimm/efd_decoder.H
index 6fc747c0f..d3078c171 100644
--- a/src/import/generic/memory/lib/spd/ddimm/efd_decoder.H
+++ b/src/import/generic/memory/lib/spd/ddimm/efd_decoder.H
@@ -22,3 +22,801 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file efd_decoder.H
+/// @brief DDIMM Extended Functional Data (EFD) decoder
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _EFD_DECODER_H_
+#define _EFD_DECODER_H_
+
+#include <fapi2.H>
+#include <vector>
+#include <generic/memory/lib/utils/shared/mss_generic_consts.H>
+#include <generic/memory/lib/spd/ddimm/ddr4/efd_traits_ddr4.H>
+#include <generic/memory/lib/spd/spd_reader.H>
+
+namespace mss
+{
+
+namespace efd
+{
+///
+/// @brief EFD reader
+/// @tparam F the SPD field to read
+/// @tparam R the SPD revision
+/// @tparam IT data input type
+/// @tparam OT data output type
+/// @tparam TT traits associated with reader, defaulted to readerTraits<F, T>
+/// @param[in] i_target the dimm target
+/// @param[in] i_spd_data the SPD data
+/// @param[out] o_value raw value for this SPD field
+/// @return FAPI2_RC_SUCCESS iff okay
+///
+template< const field_t<endian::LITTLE>& F,
+ mss::spd::rev R,
+ typename IT,
+ typename OT,
+ typename TT = readerTraits<F, R> >
+inline fapi2::ReturnCode reader( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<IT>& i_spd_data,
+ OT& o_value)
+{
+
+ FAPI_TRY( (mss::get_field<endian::LITTLE, F, TT>(i_target, i_spd_data, mss::READ_SPD_FIELD, o_value)),
+ "Failed efd::read_field() for %s", spd::c_str(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @class base_decoder
+/// @brief Abstract class for the base EFD decoder, regardless of size
+/// @note Includes all generic EFD values
+///
+class base_decoder
+{
+ protected:
+
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> iv_target;
+ std::vector<uint8_t> iv_data;
+
+ public:
+
+ ///
+ /// @brief default ctor
+ ///
+ base_decoder() = default;
+
+ ///
+ /// @brief ctor
+ /// @param[in] i_target DIMM target on which to operate
+ /// @param[in] i_target EFD data
+ ///
+ base_decoder(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t>& i_data):
+ iv_target(i_target),
+ iv_data(i_data)
+ {
+ }
+
+ ///
+ /// @brief default dtor
+ ///
+ virtual ~base_decoder() = default;
+
+ ///
+ /// @brief Gets decoder target
+ /// @return fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+ ///
+ virtual fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> get_dimm_target() const
+ {
+ return iv_target;
+ }
+
+ ///
+ /// @brief Gets decoder SPD data
+ /// @return std::vector<uint8_t>
+ ///
+ virtual std::vector<uint8_t> get_data() const
+ {
+ return iv_data;
+ }
+
+ ///
+ /// @brief Sets decoder SPD data
+ /// @param[in] i_spd_data SPD data in a vector reference
+ ///
+ virtual void set_data(const std::vector<uint8_t>& i_spd_data)
+ {
+ iv_data = i_spd_data;
+ }
+
+ ///
+ /// @brief Decodes Host Speed Supported -> HOST_SPEED_SUPPORTED
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode host_speed_supported(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PHY ODT impedance -> PHY_ODT_IMPEDANCE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode phy_odt_impedance(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PHY Drive impedance pull up -> PHY_DRIVE_IMPEDANCE_PULL_UP
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode phy_drive_impedance_pull_up(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PHY Drive impedance pull down -> PHY_DRIVE_IMPEDANCE_PULL_DOWN
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode phy_drive_impedance_pull_down(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PHY Drive Impedance -> PHY_DRIVE_IMPEDANCE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode phy_drive_impedance(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes Master Ranks Supported -> MASTER_RANKS_SUPPORTED
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode master_ranks_supported(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PHY Slew Rate DQ_DQS -> PHY_SLEW_RATE_DQ_DQS
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode phy_slew_rate_dq_dqs(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes ATX impedance -> ATX_IMPEDANCE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode atx_impedance(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes ATX Slew rate -> ATX_SLEW_RATE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode atx_slew_rate(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes CK Impedance -> CK_IMPEDANCE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode ck_impedance(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes CK Slew rate -> CK_SLEW_RATE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode ck_slew_rate(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes Alert ODT Impedance -> ALERT_ODT_IMPEDANCE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode alert_odt_impedance(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Nom -> DRAM_RTT_NOM
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_nom(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Nom rank0 -> DRAM_RTT_NOM_RANK0
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_nom_rank0(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Nom rank1 -> DRAM_RTT_NOM_RANK1
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_nom_rank1(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Nom rank2 -> DRAM_RTT_NOM_RANK2
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_nom_rank2(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Nom rank3 -> DRAM_RTT_NOM_RANK3
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_nom_rank3(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT WR -> DRAM_RTT_WR
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_wr(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT WR rank0 -> DRAM_RTT_WR_RANK0
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_wr_rank0(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT WR rank1 -> DRAM_RTT_WR_RANK1
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_wr_rank1(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT WR rank2 -> DRAM_RTT_WR_RANK2
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_wr_rank2(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT WR rank3 -> DRAM_RTT_WR_RANK3
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_wr_rank3(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Park -> DRAM_RTT_PARK
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Park rank0 -> DRAM_RTT_PARK_RANK0
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park_rank0(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Park rank1 -> DRAM_RTT_PARK_RANK1
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park_rank1(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Park rank2 -> DRAM_RTT_PARK_RANK2
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park_rank2(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM RTT Park rank3 -> DRAM_RTT_PARK_RANK3
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park_rank3(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM DIC -> DRAM_DIC
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dram_dic(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM Preamble -> WRITE_PREAMBLE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode write_preamble(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM Preamble -> READ_PREAMBLE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode read_preamble(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PHY Equalization -> PHY_EQUALIZATION
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode phy_equalization(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes Initial WR VREF DQ setting -> WR_VREF_DQ_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode wr_vref_dq_range(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes Initial WR VREF DQ setting -> WR_VREF_DQ_VALUE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode wr_vref_dq_value(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes ODT WR Map CS Byte0 -> ODT_WR_MAP_RANK3
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_wr_map_rank3(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes ODT WR Map CS Byte0 -> ODT_WR_MAP_RANK2
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_wr_map_rank2(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes ODT WR Map CS Byte0 -> ODT_WR_MAP_RANK1
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_wr_map_rank1(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes ODT WR Map CS Byte0 -> ODT_WR_MAP_RANK0
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_wr_map_rank0(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes ODT RD Map CS Byte0 -> ODT_RD_MAP_RANK3
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_rd_map_rank3(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes ODT RD Map CS Byte0 -> ODT_RD_MAP_RANK2
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_rd_map_rank2(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes ODT RD Map CS Byte0 -> ODT_RD_MAP_RANK1
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_rd_map_rank1(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes ODT RD Map CS Byte0 -> ODT_RD_MAP_RANK0
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode odt_rd_map_rank0(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes Geardown during training -> GEARDOWN_DURING_TRAINING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode geardown_during_training(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWA Volt -> PMIC0_SWA_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swa_setting(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWA Volt -> PMIC0_SWA_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swa_range(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWB Volt -> PMIC0_SWB_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swb_setting(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWB Volt -> PMIC0_SWB_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swb_range(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWC Volt -> PMIC0_SWC_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swc_setting(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWC Volt -> PMIC0_SWC_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swc_range(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWD Volt -> PMIC0_SWD_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swd_setting(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC0 SWD Volt -> PMIC0_SWD_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic0_swd_range(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWA Volt -> PMIC1_SWA_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swa_setting(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWA Volt -> PMIC1_SWA_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swa_range(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWB Volt -> PMIC1_SWB_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swb_setting(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWB Volt -> PMIC1_SWB_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swb_range(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWC Volt -> PMIC1_SWC_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swc_setting(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWC Volt -> PMIC1_SWC_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swc_range(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWD Volt -> PMIC1_SWD_SETTING
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swd_setting(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes PMIC1 SWD Volt -> PMIC1_SWD_RANGE
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode pmic1_swd_range(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes Channels supported byte3
+ /// @param[out] o_output encoding from SPD - multiple fields used
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note Uses the following bytes and fields to build up the combined data:
+ /// Byte 3: CHANNELS_SUPPORTED_BYTE0
+ /// Byte 4: CHANNELS_SUPPORTED_BYTE1
+ /// Byte 5: CHANNELS_SUPPORTED_BYTE2
+ /// Byte 6: CHANNELS_SUPPORTED_BYTE3
+ ///
+ virtual fapi2::ReturnCode channels_supported(uint32_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DIMMs supported -> DIMMS_SUPPORTED
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ ///
+ virtual fapi2::ReturnCode dimms_supported(uint8_t& o_output) const
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+
+};
+
+///
+/// @class decoder
+/// @tparam D device type (DDR4, etc.)
+/// @tparam E EFD type (ie custom EFD type 1)
+/// @tparam R SPD revision (e.g. rev 1.1, 1.2, etc.)
+/// @brief Base SPD DRAM decoder
+///
+template < mss::spd::device_type D, mss::efd::id E, mss::spd::rev R >
+class decoder;
+
+} // ns efd
+} // ns mss
+
+#endif
diff --git a/src/import/generic/memory/lib/spd/ddimm/efd_factory.H b/src/import/generic/memory/lib/spd/ddimm/efd_factory.H
index 77adaf9a2..6a85c86f8 100644
--- a/src/import/generic/memory/lib/spd/ddimm/efd_factory.H
+++ b/src/import/generic/memory/lib/spd/ddimm/efd_factory.H
@@ -22,3 +22,47 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+///
+/// @file efd_decoder.H
+/// @brief DDIMM Extended Functional Data (EFD) decoder
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 3
+// *HWP Consumed by: HB:FSP
+
+#ifndef _EFD_FACTORY_H_
+#define _EFD_FACTORY_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/spd/ddimm/ddr4/efd_ddr4_custom_microchip_decoder.H>
+
+namespace mss
+{
+
+namespace efd
+{
+
+///
+/// @brief Generates the EFD decoder based upon the EFD type
+/// @param[in] i_target DIMM target
+/// @param[in] i_data SPD data
+/// @param[out] o_decoder shared pointer to the decoder in question
+/// @return fapi2::ReturnCode SUCCESS iff the procedure executes successfully
+///
+// TODO:update this for other types of EFD
+inline fapi2::ReturnCode factory(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
+ const std::vector<uint8_t>& i_data,
+ std::shared_ptr<base_decoder>& o_decoder_ptr)
+{
+ o_decoder_ptr =
+ std::make_shared<mss::efd::decoder<mss::spd::device_type::DDR4, DDR4_CUSTOM_MICROCHIP, mss::spd::rev::V0_0>>(i_target,
+ i_data);
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+} // ns efd
+} // ns mss
+
+#endif
diff --git a/src/import/generic/memory/lib/spd/spd_reader.H b/src/import/generic/memory/lib/spd/spd_reader.H
index 3e1300c1c..ead0a1469 100644
--- a/src/import/generic/memory/lib/spd/spd_reader.H
+++ b/src/import/generic/memory/lib/spd/spd_reader.H
@@ -39,9 +39,7 @@
#include <fapi2.H>
#include <cstdint>
-#include <generic/memory/lib/spd/spd_field.H>
#include <generic/memory/lib/spd/spd_traits_ddr4.H>
-#include <generic/memory/lib/utils/mss_field.H>
namespace mss
{
OpenPOWER on IntegriCloud