summaryrefslogtreecommitdiffstats
path: root/src/import/chips
diff options
context:
space:
mode:
authorAndre Marin <aamarin@us.ibm.com>2016-09-01 19:23:05 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2016-09-21 16:39:30 -0400
commit142582dcca86c52698662aec925495bac8dc7059 (patch)
tree127123c92d7e8200809aaff28766f10b0077d3d5 /src/import/chips
parent92fbd675918101f1b5ab446c061ea33881b3c62b (diff)
downloadtalos-hostboot-142582dcca86c52698662aec925495bac8dc7059.tar.gz
talos-hostboot-142582dcca86c52698662aec925495bac8dc7059.zip
Add LRDIMM decoder and unit tests
Change-Id: Ic213fe7883b4090aef8afc3d481bb63d5cdc49fe Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29811 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Brian R. Silver <bsilver@us.ibm.com> Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29812 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src/import/chips')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/spd/common/dimm_module_decoder.H399
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/spd/common/spd_decoder.H56
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder.H637
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder_v1_0.C1333
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder_v1_1.C309
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder_v1_2.C203
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/spd/rdimm/rdimm_decoder_v1_0.C2
7 files changed, 2887 insertions, 52 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/dimm_module_decoder.H b/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/dimm_module_decoder.H
index cec0698b9..b737d196b 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/dimm_module_decoder.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/dimm_module_decoder.H
@@ -65,13 +65,11 @@ class dimm_module_decoder
virtual ~dimm_module_decoder() = default;
///
- /// @brief Decodes module nominal height max, in mm
+ /// @brief Decodes module nominal height max
/// @param[out] o_output height range encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
/// @note SPD Byte 128 (Bits 4~0)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 48
///
virtual fapi2::ReturnCode max_module_nominal_height(uint8_t& o_output)
{
@@ -80,13 +78,24 @@ class dimm_module_decoder
}
///
- /// @brief Decodes front module maximum thickness max, in mm
+ /// @brief Decodes raw card extension
+ /// @param[out] o_output height range encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 128 (Bits 7~5)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode raw_card_extension(uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes front module maximum thickness max
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
/// @note SPD Byte 129 (Bits 3~0)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 48
///
virtual fapi2::ReturnCode front_module_max_thickness(uint8_t& o_output)
{
@@ -95,13 +104,11 @@ class dimm_module_decoder
}
///
- /// @brief Decodes back module maximum thickness max, in mm
+ /// @brief Decodes back module maximum thickness max
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
/// @note SPD Byte 129 (Bits 7~4)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 48
///
virtual fapi2::ReturnCode back_module_max_thickness(uint8_t& o_output)
{
@@ -115,8 +122,6 @@ class dimm_module_decoder
/// @return FAPI2_RC_SUCCESS if okay
/// @note SPD Byte 131 (Bits 1~0)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 50
///
virtual fapi2::ReturnCode num_registers_used(uint8_t& o_output)
{
@@ -130,8 +135,6 @@ class dimm_module_decoder
/// @return FAPI2_RC_SUCCESS if okay
/// @note SPD Byte 131 (Bits 3~2)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 50
///
virtual fapi2::ReturnCode num_rows_of_drams(uint8_t& o_output)
{
@@ -140,16 +143,28 @@ class dimm_module_decoder
}
///
+ /// @brief Decodes number of rows of DRAMs on RDIMM
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 131 (Bits 7~4)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode register_and_buffer_type(uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
/// @brief Decodes heat spreader thermal characteristics
/// @param[out] o_output drive strength encoding from SPD
/// @return FAPI2_RC_SUCCEawSS if okay
/// @note SPD Byte 132 (Bits 6~0)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 51
///
virtual fapi2::ReturnCode heat_spreader_thermal_char(uint8_t& o_output)
{
+ // Undefined must be coded as 0x00
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
@@ -160,8 +175,6 @@ class dimm_module_decoder
/// @return FAPI2_RC_SUCCESS if okay
/// @note SPD Byte 132 (Bit 7)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 51
///
virtual fapi2::ReturnCode heat_spreader_solution(uint8_t& o_output)
{
@@ -173,10 +186,8 @@ class dimm_module_decoder
/// @brief Decodes number of continuation codes
/// @param[out] o_output drive strength encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 133 (bit 6~0)
+ /// @note SPD Byte 133 (Bits 6~0)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 51
///
virtual fapi2::ReturnCode num_continuation_codes(uint8_t& o_output)
{
@@ -188,10 +199,8 @@ class dimm_module_decoder
/// @brief Decodes manufacturer ID code
/// @param[out] o_output drive strength encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 133 (bit 6~0)
+ /// @note SPD Byte 134 (Bits 7~0)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 51
///
virtual fapi2::ReturnCode manufacturer_id_code(uint8_t& o_output)
{
@@ -203,10 +212,8 @@ class dimm_module_decoder
/// @brief Decodes register revision number
/// @param[out] o_output drive strength encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 135 (bit 7~0)
+ /// @note SPD Byte 135 (Bits 7~0)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 51
///
virtual fapi2::ReturnCode register_rev_num(uint8_t& o_output)
{
@@ -218,10 +225,8 @@ class dimm_module_decoder
/// @brief Decodes address mapping from register to dram
/// @param[out] o_output drive strength encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 136 (bit 0)
+ /// @note SPD Byte 136 (Bit 0)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 52
///
virtual fapi2::ReturnCode register_to_dram_addr_mapping(uint8_t& o_output)
{
@@ -233,10 +238,8 @@ class dimm_module_decoder
/// @brief Decodes register output drive strength for CKE signal
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 137 (bit 1~0)
- /// @note Item JC-45-2220.01x
- /// @note Page 76
- /// @note DDR4 SPD Document Release 4
+ /// @note SPD Byte 137 (Bits 1~0)
+ /// @note Item JEDEC Standard No. 21-C
///
virtual fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_output)
{
@@ -248,10 +251,8 @@ class dimm_module_decoder
/// @brief Decodes register output drive strength for ODT signal
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 137 (bit 3~2)
- /// @note Item JC-45-2220.01x
- /// @note Page 76
- /// @note DDR4 SPD Document Release 4
+ /// @note SPD Byte 137 (Bits 3~2)
+ /// @note Item JEDEC Standard No. 21-C
///
virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output)
{
@@ -263,10 +264,8 @@ class dimm_module_decoder
/// @brief Decodes register output drive strength for command/address (CA) signal
/// @param[out] o_output drive strength encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 137 (bit 5~4)
+ /// @note SPD Byte 137 (Bits 5~4)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 53
///
virtual fapi2::ReturnCode ca_signal_output_driver(uint8_t& o_output)
{
@@ -278,10 +277,8 @@ class dimm_module_decoder
/// @brief Decodes register output drive strength for chip select (CS) signal
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 137 (bit 6~7)
- /// @note Item JC-45-2220.01x
- /// @note Page 76
- /// @note DDR4 SPD Document Release 4
+ /// @note SPD Byte 137 (Bits 6~7)
+ /// @note Item JEDEC Standard No. 21-C
///
virtual fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_output)
{
@@ -293,10 +290,8 @@ class dimm_module_decoder
/// @brief Decodes register output drive strength for clock (B side)
/// @param[out] o_output drive strength encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 138 (bit 1~0)
+ /// @note SPD Byte 138 (Bits 1~0)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 53
///
virtual fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_output)
{
@@ -308,18 +303,322 @@ class dimm_module_decoder
/// @brief Decodes register output drive strength for clock (A side)
/// @param[out] o_output drive strength encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
- /// @note SPD Byte 138 (bit 3~2)
+ /// @note SPD Byte 138 (Bits 3~2)
/// @note Item JEDEC Standard No. 21-C
- /// @note DDR4 SPD Document Release 2
- /// @note Page 4.1.2.12 - 53
///
virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output)
{
o_output = 0;
return fapi2::FAPI2_RC_SUCCESS;
}
+
+ ///
+ /// @brief Decodes register output drive strength for data buffer control (BCOM, BODT, BKCE)
+ /// @param[out] o_output encoded drive strength
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 138 (Bit 4)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode bcom_bcke_bodt_drive_strength(uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+
+ }
+
+ ///
+ /// @brief Decodes register output drive strength for data buffer control (BCK)
+ /// @param[out] o_output encoded drive strength
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 138 (Bit 5)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode bck_output_drive_strength(uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes RCD output slew rate control
+ /// @param[out] o_output encoded drive strength
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 138 (Bit 6)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode slew_rate_control(uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes data buffer revision number
+ /// @param[out] o_output revision number
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 139 (Bits 7~0)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode data_buffer_rev(uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM VrefDQ for Package Rank 0
+ /// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 140 (Bits 5~0)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode dram_vref_dq_rank0(uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM VrefDQ for Package Rank 1
+ /// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 141 (Bits 5~0)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode dram_vref_dq_rank1(uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM VrefDQ for Package Rank 2
+ /// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 142 (Bits 5~0)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode dram_vref_dq_rank2(uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM VrefDQ for Package Rank 3
+ /// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 143 (Bits 5~0)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode dram_vref_dq_rank3(uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes data buffer VrefDQ for DRAM interface
+ /// @param[out] o_output encoding of F5BC6x in DDR4DB01 spec
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 144 (Bits 5~0)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode data_buffer_vref_dq(uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM interface MDQ Drive Strenth
+ /// of the data buffer component for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_output encoding of F5BC6x in
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 145 - 147 (Bits 6~4)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode data_buffer_mdq_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM interface MDQ read termination strength
+ /// of the data buffer component for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_output encoding of F5BC6x in
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 145 - 147 (Bits 2~0)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode data_buffer_mdq_rtt(const uint64_t i_dimm_speed, uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM drive strenth
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_output DRAM drive strength (in ohms)
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 148 (Bits 5~0)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode dram_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM ODT for RTT_NOM
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_output ODT termination strength (in ohms)
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 149 - 151 (Bits 2~0)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode dram_rtt_nom(const uint64_t i_dimm_speed, uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM ODT for RTT_WR
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_output ODT termination strength (in ohms)
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 149 - 151 (Bits 5~3)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode dram_rtt_wr(const uint64_t i_dimm_speed, uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM ODT for RTT_PARK, package ranks 0 & 1
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_output ODT termination strength (in ohms)
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 152 - 154 (Bits 2~0)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park_ranks0_1(const uint64_t i_dimm_speed, uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes DRAM ODT for RTT_PARK, package ranks 2 & 3
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_output ODT termination strength (in ohms)
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 152 - 154 (Bits 5~3)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park_ranks2_3(const uint64_t i_dimm_speed, uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes VrefDQ range for DRAM interface range
+ /// @param[out] o_output spd encoding
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 155 (Bits 3~0)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode dram_vref_dq_range(uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes data buffer VrefDQ range for DRAM interface range
+ /// @param[out] o_output spd encoding
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 155 (Bit 4)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode data_buffer_vref_dq_range(uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes data buffer gain adjustment
+ /// @param[out] o_output spd encoding
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 156 (Bit 0)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode data_buffer_gain_adjustment(uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Decodes data buffer Decision Feedback Equalization (DFE)
+ /// @param[out] o_output spd encoding
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 156 (Bit 1)
+ /// @note Item JEDEC Standard No. 21-C
+ ///
+ virtual fapi2::ReturnCode data_buffer_dfe(uint8_t& o_output)
+ {
+ o_output = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
};
+///
+/// @brief data structure for byte fields
+///
+struct field_t
+{
+ const uint64_t iv_byte;
+ const uint64_t iv_start;
+ const uint64_t iv_length;
+
+ // default ctor deleted
+ constexpr field_t() = delete;
+
+ ///
+ /// @brief ctor
+ /// @param[in] i_byte_index
+ /// @param[in] i_start_bit
+ /// @param[in] i_bit_length
+ ///
+ constexpr field_t(const uint64_t i_byte_index,
+ const uint64_t i_start_bit,
+ const uint64_t i_bit_length)
+ : iv_byte(i_byte_index), iv_start(i_start_bit), iv_length(i_bit_length)
+ {}
+
+ ///
+ /// @brief default dtor
+ ///
+ ~field_t() = default;
+
+};// field_t
+
}// spd
}// mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/spd_decoder.H b/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/spd_decoder.H
index 439821411..3bfcdc4ab 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/spd_decoder.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/spd_decoder.H
@@ -45,7 +45,9 @@
#include <fapi2.H>
// mss lib
+#include <lib/spd/common/dimm_module_decoder.H>
#include <lib/spd/rdimm/rdimm_decoder.H>
+#include <lib/spd/lrdimm/lrdimm_decoder.H>
#include <lib/spd/rdimm/raw_cards.H>
#include <lib/utils/c_str.H>
@@ -94,6 +96,8 @@ enum factory_byte_extract
/// @tparam I Byte index
/// @tparam S Start bit
/// @tparam L Bit length
+/// @param[in] i_target the dimm target
+/// @param[in] i_spd_data the SPD data
/// @return extracted byte (right aligned)
///
template<uint8_t I, uint8_t S, uint8_t L>
@@ -116,6 +120,56 @@ inline uint8_t extract_spd_field(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i
}
///
+/// @brief Helper function to extract byte information
+/// @tparam F the SPD field to extract
+/// @param[in] i_target the dimm target
+/// @param[in] i_spd_data the SPD data
+/// @return extracted byte (right aligned)
+///
+template< const field_t& F >
+inline uint8_t extract_spd_field(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_spd_data)
+{
+ FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
+ mss::c_str(i_target),
+ F.iv_byte,
+ i_spd_data[F.iv_byte]);
+
+ fapi2::buffer<uint8_t> l_buffer(i_spd_data[F.iv_byte]);
+
+ // Extracting desired bits
+ uint8_t l_field_bits = 0;
+ l_buffer.extractToRight<F.iv_start, F.iv_length>(l_field_bits);
+
+ return l_field_bits;
+}
+
+///
+/// @brief Helper function to extract byte information
+/// @param[in] i_target the dimm target
+/// @param[in] i_field the SPD field
+/// @param[in] i_spd_data the SPD data
+/// @return extracted byte (right aligned)
+///
+inline uint8_t extract_spd_field(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const field_t& i_field,
+ const std::vector<uint8_t>& i_spd_data)
+{
+ FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
+ mss::c_str(i_target),
+ i_field.iv_byte,
+ i_spd_data[i_field.iv_byte]);
+
+ fapi2::buffer<uint8_t> l_buffer(i_spd_data[i_field.iv_byte]);
+
+ // Extracting desired bits
+ uint8_t l_field_bits = 0;
+ l_buffer.extractToRight( l_field_bits, i_field.iv_start, i_field.iv_length );
+
+ return l_field_bits;
+}
+
+///
/// @class decoder
/// @brief Base SPD DRAM decoder
///
@@ -1454,4 +1508,4 @@ class decoder_v1_1 : public decoder
}// spd
}// mss
-#endif //_MSS_SPD_DECODER_H_
+#endif //_MSSS_PD_DECODER_H_
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder.H b/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder.H
index 0126e55eb..4e3c5694a 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder.H
@@ -32,3 +32,640 @@
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: HB:FSP
+
+
+#ifndef _MSS_LRDIMM_DECODER_H_
+#define _MSS_LRDIMM_DECODER_H_
+
+#include <fapi2.H>
+#include <vector>
+#include <lib/spd/common/dimm_module_decoder.H>
+
+namespace mss
+{
+namespace spd
+{
+namespace lrdimm
+{
+
+///
+/// @brief LRDIMM module decoder for revision 1.0
+///
+class decoder_v1_0 : public dimm_module_decoder
+{
+ protected:
+
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
+
+ constexpr static field_t MODULE_NOMINAL_HEIGHT{128, 3, 5};
+ constexpr static field_t RAW_CARD_EXTENSION{128, 0, 3};
+
+ constexpr static field_t FRONT_MODULE_THICKNESS{129, 4, 4};
+ constexpr static field_t BACK_MODULE_THICKNESS{129, 0, 4};
+
+ constexpr static field_t NUM_REGISTERS_USED{131, 6, 2};
+ constexpr static field_t NUM_ROWS_OF_DRAMS{131, 4, 2};
+ constexpr static field_t REGISTER_TYPE{131, 0, 4};
+
+ constexpr static field_t HEAT_SPREADER_THERM_CHAR{132, 1, 7};
+ constexpr static field_t HEAT_SPREADER_SOLUTION{132, 0, 1};
+
+ constexpr static field_t CONTINUATION_CODES{133, 1, 7};
+ constexpr static field_t ADDR_MAPPING{136, 7, 1};
+
+ constexpr static field_t CKE_DRIVE_STRENGTH{137, 6, 2};
+ constexpr static field_t ODT_DRIVE_STRENGTH{137, 4, 2};
+ constexpr static field_t CA_DRIVE_STRENGTH{137, 2, 2};
+ constexpr static field_t CS_DRIVE_STRENGTH{137, 0, 2};
+
+ constexpr static field_t B_SIDE_DRIVE_STRENGTH{138, 6, 2};
+ constexpr static field_t A_SIDE_DRIVE_STRENGTH{138, 4, 2};
+ constexpr static field_t BCOM_BODT_BCKE_DRIVE_STRENGTH{138, 3, 1};
+ constexpr static field_t BCK_DRIVE_STRENGTH{138, 2, 1};
+ constexpr static field_t RCD_SLEW_CNTRL{138, 1, 1 };
+
+ constexpr static field_t VREF_DQ_RANK0{140, 2, 6};
+ constexpr static field_t VREF_DQ_RANK1{141, 2, 6};
+ constexpr static field_t VREF_DQ_RANK2{142, 2, 6};
+ constexpr static field_t VREF_DQ_RANK3{143, 2, 6};
+
+ constexpr static field_t DATA_BUFFER_MDQ{145, 1, 3};
+
+ constexpr static field_t DRAM_VREF_DQ_RANGE{155, 4, 4};
+ constexpr static field_t DATA_BUFFER_VREF_DQ{155, 3, 1};
+
+ constexpr static field_t DATA_BUFFER_GAIN_ADJUST{156, 7, 1};
+ constexpr static field_t DATA_BUFFER_DFE{156, 6, 1};
+
+ public:
+ // Allows injection of errors for testing
+ // TK - Consider API change to use setter/getters
+ // for this instance variable, RDIMM decoder
+ // uses this interface so they have to match - AAM
+ std::vector<uint8_t> iv_spd_data;
+
+ // deleted default ctor
+ decoder_v1_0() = delete;
+
+ ///
+ /// @brief ctor
+ /// @param[in] i_target dimm target
+ /// @param[in] i_spd_data vector DIMM SPD data
+ ///
+ decoder_v1_0(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_spd_data)
+ : iv_target(i_target), iv_spd_data(i_spd_data)
+ {}
+
+ ///
+ /// @brief default dtor
+ ///
+ virtual ~decoder_v1_0() = default;
+
+ ///
+ /// @brief Decodes module nominal height max
+ /// @param[out] o_output height range encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 128 (Bits 4~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 55
+ ///
+ virtual fapi2::ReturnCode max_module_nominal_height(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes raw card extension
+ /// @param[out] o_output raw card rev. encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 128 (Bits 7~5)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 55
+ ///
+ virtual fapi2::ReturnCode raw_card_extension(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes front module maximum thickness max
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 129 (Bits 3~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 55
+ ///
+ virtual fapi2::ReturnCode front_module_max_thickness(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes back module maximum thickness max
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 129 (Bits 7~4)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 55
+ ///
+ virtual fapi2::ReturnCode back_module_max_thickness(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes number of registers used on LRDIMM
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 131 (Bits 1~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 57
+ ///
+ virtual fapi2::ReturnCode num_registers_used(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes number of rows of DRAMs on LRDIMM
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 131 (Bits 3~2)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 57
+ ///
+ virtual fapi2::ReturnCode num_rows_of_drams(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes heat spreader solution
+ /// @param[out] o_output drive strength encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 132 (Bit 7)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 58
+ ///
+ virtual fapi2::ReturnCode heat_spreader_solution(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes number of continuation codes
+ /// @param[out] o_output drive strength encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 133 (Bits 6~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 58
+ ///
+ virtual fapi2::ReturnCode num_continuation_codes(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes manufacturer ID code
+ /// @param[out] o_output drive strength encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 134 (Bits 7~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 58
+ ///
+ virtual fapi2::ReturnCode manufacturer_id_code(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes register revision number
+ /// @param[out] o_output drive strength encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 135 (Bits 7~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 58
+ ///
+ virtual fapi2::ReturnCode register_rev_num(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes address mapping from register to dram
+ /// @param[out] o_output drive strength encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 136 (Bit 0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 59
+ ///
+ virtual fapi2::ReturnCode register_to_dram_addr_mapping(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes register output drive strength for CKE signal
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 60
+ ///
+ virtual fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes register output drive strength for ODT signal
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 137 (Bits 3~2)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 60
+ ///
+ virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes register output drive strength for command/address (CA) signal
+ /// @param[out] o_output drive strength encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 137 (Bits 5~4)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 60
+ ///
+ virtual fapi2::ReturnCode ca_signal_output_driver(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes register output drive strength for chip select (CS) signal
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 137 (Bits 6~7)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 60
+ ///
+ virtual fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes register output drive strength for clock (B side)
+ /// @param[out] o_output drive strength encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 138 (Bits 1~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 60
+ ///
+ virtual fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes register output drive strength for clock (A side)
+ /// @param[out] o_output drive strength encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 138 (Bits 3~2)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 60
+ ///
+ virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes data buffer revision number
+ /// @param[out] o_output revision number
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 139 (Bits 7~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 60
+ ///
+ virtual fapi2::ReturnCode data_buffer_rev(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes DRAM VrefDQ for Package Rank 0
+ /// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 140 (Bits 5~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 61
+ ///
+ virtual fapi2::ReturnCode dram_vref_dq_rank0(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes DRAM VrefDQ for Package Rank 1
+ /// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 141 (Bits 5~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 61
+ ///
+ virtual fapi2::ReturnCode dram_vref_dq_rank1(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes DRAM VrefDQ for Package Rank 2
+ /// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 142 (Bits 5~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 61
+ ///
+ virtual fapi2::ReturnCode dram_vref_dq_rank2(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes DRAM VrefDQ for Package Rank 3
+ /// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 143 (Bits 5~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 61
+ ///
+ virtual fapi2::ReturnCode dram_vref_dq_rank3(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes data buffer VrefDQ for DRAM interface
+ /// @param[out] o_output encoding of F5BC6x in DDR4DB01 spec
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 144 (Bits 5~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 61
+ ///
+ virtual fapi2::ReturnCode data_buffer_vref_dq(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes DRAM interface MDQ Drive Strenth
+ /// of the data buffer component for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_output encoding of F5BC6x in
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 145 - 147 (Bits 6~4)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 62
+ ///
+ virtual fapi2::ReturnCode data_buffer_mdq_drive_strength(const uint64_t i_dimm_speed,
+ uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes DRAM interface MDQ read termination strength
+ /// of the data buffer component for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_output encoding of F5BC6x in
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 145 - 147 (Bits 2~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 62
+ ///
+ virtual fapi2::ReturnCode data_buffer_mdq_rtt(const uint64_t i_dimm_speed, uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes DRAM drive strenth
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_output DRAM drive strength (in ohms)
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 148 (Bits 5~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 63
+ ///
+ virtual fapi2::ReturnCode dram_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes DRAM ODT for RTT_NOM
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_output ODT termination strength (in ohms)
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 149 - 151 (Bits 2~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - (64 - 65)
+ ///
+ virtual fapi2::ReturnCode dram_rtt_nom(const uint64_t i_dimm_speed, uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes DRAM ODT for RTT_WR
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_output ODT termination strength (in ohms)
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 149 - 151 (Bits 5~3)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - (64 - 65)
+ ///
+ virtual fapi2::ReturnCode dram_rtt_wr(const uint64_t i_dimm_speed, uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes DRAM ODT for RTT_PARK, package ranks 0 & 1
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_output ODT termination strength (in ohms)
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 152 - 154 (Bits 2~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 65
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park_ranks0_1(const uint64_t i_dimm_speed, uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes DRAM ODT for RTT_PARK, package ranks 2 & 3
+ /// for a particular dimm speed
+ /// @param[in] i_dimm_speed the dimm speed in MT/s
+ /// @param[out] o_output ODT termination strength (in ohms)
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 152 - 154 (Bits 5~3)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12.2 - 65
+ ///
+ virtual fapi2::ReturnCode dram_rtt_park_ranks2_3(const uint64_t i_dimm_speed, uint8_t& o_output) override;
+
+};//decoder
+
+///
+/// @brief LRDIMM module decoder for revision 1.1
+///
+class decoder_v1_1 : public decoder_v1_0
+{
+ public:
+
+ // deleted default ctor
+ decoder_v1_1() = delete;
+
+ ///
+ /// @brief ctor
+ /// @param[in] i_target dimm target
+ /// @param[in] i_spd_data vector DIMM SPD data
+ ///
+ decoder_v1_1(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_spd_data)
+ : decoder_v1_0(i_target, i_spd_data)
+ {}
+
+ ///
+ /// @brief default dtor
+ ///
+ virtual ~decoder_v1_1() = default;
+
+ ///
+ /// @brief Decodes register and data buffer types
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 131 (Bits 7~4)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 3
+ /// @note Page 4.1.2.12.3 - 63
+ ///
+ virtual fapi2::ReturnCode register_and_buffer_type(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes register output drive strength for CKE signal
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 137 (Bits 1~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 3
+ /// @note Page 4.1.2.12.3 - 65
+ ///
+ virtual fapi2::ReturnCode cke_signal_output_driver(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes register output drive strength for ODT signal
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 137 (Bits 3~2)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 3
+ /// @note Page 4.1.2.12.3 - 65
+ ///
+ virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes register output drive strength for chip select (CS) signal
+ /// @param[out] o_output encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 137 (Bits 6~7)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 3
+ /// @note Page 4.1.2.12.3 - 65
+ ///
+ virtual fapi2::ReturnCode cs_signal_output_driver(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes register output drive strength for clock (B side)
+ /// @param[out] o_output drive strength encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 138 (Bits 1~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 3
+ /// @note Page 4.1.2.12.3 - 66
+ ///
+ virtual fapi2::ReturnCode b_side_clk_output_driver(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes register output drive strength for clock (A side)
+ /// @param[out] o_output drive strength encoding from SPD
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 138 (Bits 3~2)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 3
+ /// @note Page 4.1.2.12.3 - 66
+ ///
+ virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes register output drive strength for data buffer control (BCOM, BODT, BKCE)
+ /// @param[out] o_output encoded drive strength
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 138 (Bit 4)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 3
+ /// @note Page 4.1.2.12.3 - 66
+ ///
+ virtual fapi2::ReturnCode bcom_bcke_bodt_drive_strength(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes register output drive strength for data buffer control (BCK)
+ /// @param[out] o_output encoded drive strength
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 138 (Bit 5)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 3
+ /// @note Page 4.1.2.12.3 - 66
+ ///
+ virtual fapi2::ReturnCode bck_output_drive_strength(uint8_t& o_output) override;
+
+};
+
+///
+/// @brief LRDIMM module decoder for revision 1.2
+///
+class decoder_v1_2 : public decoder_v1_1
+{
+ public:
+
+ // deleted default ctor
+ decoder_v1_2() = delete;
+
+ ///
+ /// @brief ctor
+ /// @param[in] i_target dimm target
+ /// @param[in] i_spd_data vector DIMM SPD data
+ ///
+ decoder_v1_2(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_spd_data)
+ : decoder_v1_1(i_target, i_spd_data)
+ {}
+
+ ///
+ /// @brief default dtor
+ ///
+ virtual ~decoder_v1_2() = default;
+
+ ///
+ /// @brief Decodes RCD output slew rate control
+ /// @param[out] o_output encoded drive strength
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 138 (Bit 6)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 4
+ /// @note Page 4.1.2.L-4 - 70
+ ///
+ virtual fapi2::ReturnCode slew_rate_control(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes VrefDQ range for DRAM interface range
+ /// @param[out] o_output spd encoding
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 155 (Bits 3~0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 4
+ /// @note Page 4.1.2.L-4 - 76
+ ///
+ virtual fapi2::ReturnCode dram_vref_dq_range(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes data buffer VrefDQ range for DRAM interface range
+ /// @param[out] o_output spd encoding
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 155 (Bit 4)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 4
+ /// @note Page 4.1.2.L-4 - 76
+ ///
+ virtual fapi2::ReturnCode data_buffer_vref_dq_range(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes data buffer gain adjustment
+ /// @param[out] o_output spd encoding
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 156 (Bit 0)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 4
+ /// @note Page 4.1.2.L-4 - 77
+ ///
+ virtual fapi2::ReturnCode data_buffer_gain_adjustment(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes data buffer Decision Feedback Equalization (DFE)
+ /// @param[out] o_output spd encoding
+ /// @return FAPI2_RC_SUCCESS if okay
+ /// @note SPD Byte 156 (Bit 1)
+ /// @note Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 4
+ /// @note Page 4.1.2.L-4 - 77
+ ///
+ virtual fapi2::ReturnCode data_buffer_dfe(uint8_t& o_output) override;
+};
+
+}// lrdimm
+}// spd
+}// mss
+
+#endif //_MSS_LRDIMM_DECODER_H_
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder_v1_0.C b/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder_v1_0.C
index c0eb14710..e46a09a50 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder_v1_0.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder_v1_0.C
@@ -32,3 +32,1336 @@
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: HB:FSP
+
+// std lib
+#include <vector>
+
+// fapi2
+#include <fapi2.H>
+
+// mss lib
+#include <lib/spd/lrdimm/lrdimm_decoder.H>
+#include <lib/spd/common/spd_decoder.H>
+#include <lib/utils/checker.H>
+#include <lib/utils/c_str.H>
+#include <lib/utils/find.H>
+
+using fapi2::TARGET_TYPE_MCA;
+using fapi2::TARGET_TYPE_MCS;
+using fapi2::TARGET_TYPE_DIMM;
+
+
+namespace mss
+{
+namespace spd
+{
+namespace lrdimm
+{
+
+/////////////////////////
+// Non-member helper functions
+// For LRDIMM module rev 1.0
+/////////////////////////
+
+/// @brief Helper function to find SPD byte based on freq
+/// @param[in] i_dimm_speed DIMM speed in MT/s
+/// @param[out] o_byte byte to extract spd from
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD spec sets encoding based on freq ranges such as, 1866 < data rate <= 2400,
+/// But for Nimbus we can only be 1866, 2133, 2400, and 2666. No intermediate values
+/// so we use a simple case statement to get our results.
+static fapi2::ReturnCode mdq_helper(const uint64_t i_dimm_speed, uint8_t& o_byte)
+{
+ switch(i_dimm_speed)
+ {
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
+ o_byte = 145;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
+ o_byte = 146;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
+ o_byte = 147;
+ break;
+
+ default:
+ FAPI_ERR("Invalid dimm speed received: %d", i_dimm_speed);
+ return fapi2::FAPI2_RC_INVALID_PARAMETER;
+ break;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+};
+
+/// @brief Helper function to find start bit based on freq
+/// @param[in] i_dimm_speed DIMM speed in MT/s
+/// @param[out] o_start_bit start bit to extract SPD from
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD spec sets encoding based on freq ranges such as, 1866 < data rate <= 2400,
+/// But for Nimbus we can only be 1866, 2133, 2400, and 2666. No intermediate values
+/// so we use a simple case statement to get our results.
+static fapi2::ReturnCode drive_strength_start_bit_finder(const uint64_t i_dimm_speed, size_t& o_start_bit)
+{
+ switch(i_dimm_speed)
+ {
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
+ o_start_bit = 6;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
+ o_start_bit = 4;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
+ o_start_bit = 2;
+ break;
+
+ default:
+ FAPI_ERR("Invalid dimm speed received: %d", i_dimm_speed);
+ return fapi2::FAPI2_RC_INVALID_PARAMETER;
+ break;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+/// @brief Helper function to find SPD byte based on freq
+/// @param[in] i_dimm_speed DIMM speed in MT/s
+/// @param[out] o_byte byte to extract spd from
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD spec sets encoding based on freq ranges such as, 1866 < data rate <= 2400,
+/// But for Nimbus we can only be 1866, 2133, 2400, and 2666. No intermediate values
+/// so we use a simple case statement to get our results.
+static fapi2::ReturnCode rtt_wr_and_nom_byte_finder(const uint64_t i_dimm_speed, size_t& o_byte)
+{
+ switch(i_dimm_speed)
+ {
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
+ o_byte = 149;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
+ o_byte = 150;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
+ o_byte = 151;
+ break;
+
+ default:
+ FAPI_ERR("Invalid dimm speed received: %d", i_dimm_speed);
+ return fapi2::FAPI2_RC_INVALID_PARAMETER;
+ break;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+/// @brief Helper function to find SPD byte based on freq
+/// @param[in] i_dimm_speed DIMM speed in MT/s
+/// @param[out] o_byte byte to extract spd from
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD spec sets encoding based on freq ranges such as, 1866 < data rate <= 2400,
+/// But for Nimbus we can only be 1866, 2133, 2400, and 2666. No intermediate values
+/// so we use a simple case statement to get our results.
+static fapi2::ReturnCode rtt_park_byte_finder(const uint64_t i_dimm_speed, size_t& o_byte)
+{
+ switch(i_dimm_speed)
+ {
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT1866:
+ o_byte = 152;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2133:
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2400:
+ o_byte = 153;
+ break;
+
+ case fapi2::ENUM_ATTR_MSS_FREQ_MT2666:
+ o_byte = 154;
+ break;
+
+ default:
+ FAPI_ERR("Invalid dimm speed received: %d", i_dimm_speed);
+ return fapi2::FAPI2_RC_INVALID_PARAMETER;
+ break;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+/////////////////////////
+// Member Method implementation
+// For LRDIMM module rev 1.0
+/////////////////////////
+
+///
+/// @brief Decodes module nominal height max
+/// @param[out] o_output height range encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 128 (Bits 4~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 55
+///
+fapi2::ReturnCode decoder_v1_0::max_module_nominal_height(uint8_t& o_output)
+{
+ uint8_t l_field_bits = extract_spd_field< MODULE_NOMINAL_HEIGHT >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VALUE = 0b11111;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VALUE,
+ MODULE_NOMINAL_HEIGHT.iv_byte,
+ l_field_bits,
+ "Failed bound check for module nominal height max") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Max module nominal height: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes raw card extension
+/// @param[out] o_output raw card rev. encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 128 (Bits 7~5)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 55
+///
+fapi2::ReturnCode decoder_v1_0::raw_card_extension(uint8_t& o_output)
+{
+ uint8_t l_field_bits = extract_spd_field< RAW_CARD_EXTENSION >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VALUE = 0b111;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VALUE,
+ RAW_CARD_EXTENSION.iv_byte,
+ l_field_bits,
+ "Failed bound check for raw card extension") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Raw card extension: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes front module maximum thickness max
+/// @param[out] o_output encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 129 (Bits 3~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 55
+///
+fapi2::ReturnCode decoder_v1_0::front_module_max_thickness(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< FRONT_MODULE_THICKNESS >(iv_target, iv_spd_data);
+
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VALUE = 0b1111;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VALUE,
+ FRONT_MODULE_THICKNESS.iv_byte,
+ l_field_bits,
+ "Failed bound check for front module max thickness") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Front module max thickness: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief Decodes back module maximum thickness max
+/// @param[out] o_output encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 129 (Bits 7~4)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 55
+///
+fapi2::ReturnCode decoder_v1_0::back_module_max_thickness(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< BACK_MODULE_THICKNESS >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VALUE = 0b1111;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VALUE,
+ BACK_MODULE_THICKNESS.iv_byte,
+ l_field_bits,
+ "Failed bound check for back module max thickness") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Back module max thickness: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief Decodes number of registers used on LRDIMM
+/// @param[out] o_output encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 131 (Bits 1~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 57
+///
+fapi2::ReturnCode decoder_v1_0::num_registers_used(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< NUM_REGISTERS_USED >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t RESERVED = 0b10;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits < RESERVED,
+ NUM_REGISTERS_USED.iv_byte,
+ l_field_bits,
+ "Failed bound check for number of registers used on RDIMM ") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Number of registers used on LRDIMM : %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes number of rows of DRAMs on LRDIMM
+/// @param[out] o_output encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 131 (Bits 3~2)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 57
+///
+fapi2::ReturnCode decoder_v1_0::num_rows_of_drams(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< NUM_ROWS_OF_DRAMS >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t RESERVED = 0b11;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits < RESERVED,
+ NUM_REGISTERS_USED.iv_byte,
+ l_field_bits,
+ "Failed bound check for number of rows of DRAMs on LRDIMM ") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Number of rows of DRAMs on LRDIMM : %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief Decodes heat spreader solution
+/// @param[out] o_output drive strength encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 132 (Bit 7)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 58
+///
+fapi2::ReturnCode decoder_v1_0::heat_spreader_solution(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< HEAT_SPREADER_SOLUTION >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VALUE = 1;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VALUE,
+ HEAT_SPREADER_SOLUTION.iv_byte,
+ l_field_bits,
+ "Failed bound check for heat spreader solution") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Heat spreader solution: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes number of continuation codes
+/// @param[out] o_output encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 133 (bit 6~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 58
+///
+fapi2::ReturnCode decoder_v1_0::num_continuation_codes(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< CONTINUATION_CODES >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VALUE = 10; // JEP106AS spec
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VALUE,
+ CONTINUATION_CODES.iv_byte,
+ l_field_bits,
+ "Failed bound check for number of continuation codes") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Number of continuation codes: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes manufacturer ID code
+/// @param[out] o_output drive strength encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 134 (bit 7~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 58
+///
+fapi2::ReturnCode decoder_v1_0::manufacturer_id_code(uint8_t& o_output)
+{
+ constexpr size_t BYTE_INDEX = 134;
+ uint8_t l_raw_byte = iv_spd_data[BYTE_INDEX];
+
+ // Trace in the front assists w/ debug
+ FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
+ mss::c_str(iv_target),
+ BYTE_INDEX,
+ l_raw_byte);
+
+ // All bits used for encoding, no bounds to check
+ o_output = l_raw_byte;
+
+ FAPI_INF("%s. Register revision number: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+///
+/// @brief Decodes register revision number
+/// @param[out] o_output drive strength encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 135 (bit 7~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 58
+///
+fapi2::ReturnCode decoder_v1_0::register_rev_num(uint8_t& o_output)
+{
+ constexpr size_t BYTE_INDEX = 135;
+ uint8_t l_raw_byte = iv_spd_data[BYTE_INDEX];
+
+ // Trace in the front assists w/ debug
+ FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
+ mss::c_str(iv_target),
+ BYTE_INDEX,
+ l_raw_byte);
+
+ // All bits used for encoding, no bounds to check
+ o_output = l_raw_byte;
+
+ FAPI_INF("%s. Register revision number: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+///
+/// @brief Decodes address mapping from register to dram
+/// @param[out] o_output drive strength encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 136 (bit 0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 59
+///
+fapi2::ReturnCode decoder_v1_0::register_to_dram_addr_mapping(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< ADDR_MAPPING >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VAL = 1;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VAL, // extract sanity check
+ ADDR_MAPPING.iv_byte,
+ l_field_bits,
+ "Failed bound check for to register to dram addr mapping") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Address mapping from register to dram: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes register output drive strength for CKE signal
+/// @param[out] o_output drive strength encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 137 (bit 1~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 60
+///
+fapi2::ReturnCode decoder_v1_0::cke_signal_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< CKE_DRIVE_STRENGTH >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t RESERVED = 3;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits < RESERVED, // extract sanity check
+ CKE_DRIVE_STRENGTH.iv_byte,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for CKE") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Register Output Driver for CKE: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes register output drive strength for ODT signal
+/// @param[out] o_output drive strength encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 137 (bit 3~2)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 60
+///
+fapi2::ReturnCode decoder_v1_0::odt_signal_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< ODT_DRIVE_STRENGTH >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t RESERVED = 3;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits < RESERVED, // extract sanity check
+ ODT_DRIVE_STRENGTH.iv_byte,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for ODT") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Register Output Driver for ODT: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes register output drive strength for command/address (CA) signal
+/// @param[out] o_output drive strength encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 137 (bit 5~4)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 60
+///
+fapi2::ReturnCode decoder_v1_0::ca_signal_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< CA_DRIVE_STRENGTH >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t INVALID_VAL = 4;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits < INVALID_VAL, // extract sanity check
+ CA_DRIVE_STRENGTH.iv_byte,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for CA") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Register Output Driver for CA: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes register output drive strength for chip select (CS) signal
+/// @param[out] o_output drive strength encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 137 (bit 6~7)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 60
+///
+fapi2::ReturnCode decoder_v1_0::cs_signal_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< CS_DRIVE_STRENGTH >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t RESERVED = 3;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits < RESERVED, // extract sanity check
+ CS_DRIVE_STRENGTH.iv_byte,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for CS") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Register Output Driver for CS: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes register output drive strength for clock (B side)
+/// @param[out] o_output drive strength encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 138 (bit 1~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 60
+///
+fapi2::ReturnCode decoder_v1_0::b_side_clk_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< B_SIDE_DRIVE_STRENGTH >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t RESERVED = 3;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits < RESERVED, // extract sanity check
+ B_SIDE_DRIVE_STRENGTH.iv_byte,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for clock (Y0,Y2)") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Register Output Driver for clock (Y0,Y2): %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes register output drive strength for clock (A side)
+/// @param[out] o_output drive strength encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 138 (bit 3~2)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 60
+///
+fapi2::ReturnCode decoder_v1_0::a_side_clk_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< A_SIDE_DRIVE_STRENGTH >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t RESERVED = 3;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits < RESERVED,
+ A_SIDE_DRIVE_STRENGTH.iv_byte,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for clock (Y1,Y3)") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Register Output Driver for clock (Y1,Y3): %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes data buffer revision number
+/// @param[out] o_output revision number
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 139 (Bits 7~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 60
+///
+fapi2::ReturnCode decoder_v1_0::data_buffer_rev(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE_INDEX = 139;
+ const uint8_t l_raw_byte = iv_spd_data[BYTE_INDEX];
+
+ // Trace in the front assists w/ debug
+ FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
+ mss::c_str(iv_target),
+ BYTE_INDEX,
+ l_raw_byte);
+
+ // This checks JEDEC range is met
+ constexpr size_t UNDEFINED = 0xFF;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_raw_byte != UNDEFINED,
+ BYTE_INDEX,
+ l_raw_byte,
+ "Failed bounds check for data buffer revision number") );
+
+ // Update output only if check passes
+ o_output = l_raw_byte;
+
+ FAPI_INF("%s. Data buffer rev: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief Decodes DRAM VrefDQ for Package Rank 0
+/// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 140 (Bits 5~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 61
+///
+fapi2::ReturnCode decoder_v1_0::dram_vref_dq_rank0(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< VREF_DQ_RANK0 >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // JESD79-4 specification
+ constexpr size_t RESERVED = 0b110011;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits < RESERVED,
+ VREF_DQ_RANK0.iv_byte,
+ l_field_bits,
+ "Failed bounds check for DRAM VrefDQ for Package Rank 0") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. DRAM VrefDQ for Package Rank 0: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes DRAM VrefDQ for Package Rank 1
+/// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 141 (Bits 5~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 61
+///
+fapi2::ReturnCode decoder_v1_0::dram_vref_dq_rank1(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< VREF_DQ_RANK1 >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // JESD79-4 specification
+ constexpr size_t RESERVED = 0b110011;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits < RESERVED,
+ VREF_DQ_RANK1.iv_byte,
+ l_field_bits,
+ "Failed bounds check for DRAM VrefDQ for Package Rank 1") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. DRAM VrefDQ for Package Rank 1: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes DRAM VrefDQ for Package Rank 2
+/// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 142 (Bits 5~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 61
+///
+fapi2::ReturnCode decoder_v1_0::dram_vref_dq_rank2(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< VREF_DQ_RANK2 >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // JESD79-4 specification
+ constexpr size_t RESERVED = 0b110011;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits < RESERVED,
+ VREF_DQ_RANK2.iv_byte,
+ l_field_bits,
+ "Failed bounds check for DRAM VrefDQ for Package Rank 2") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. DRAM VrefDQ for Package Rank 2: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes DRAM VrefDQ for Package Rank 3
+/// @param[out] o_output encoding of MR6 A5:A0 in JESD790-4 spec
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 143 (Bits 5~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 4
+/// @note Page 4.1.2.12.2 - 61
+///
+fapi2::ReturnCode decoder_v1_0::dram_vref_dq_rank3(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< VREF_DQ_RANK3 >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // JESD79-4 specification
+ constexpr size_t RESERVED = 0b110011;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits < RESERVED,
+ VREF_DQ_RANK3.iv_byte,
+ l_field_bits,
+ "Failed bounds check for DRAM VrefDQ for Package Rank 3") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. DRAM VrefDQ for Package Rank 3: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes data buffer VrefDQ for DRAM interface
+/// @param[out] o_output encoding of F5BC6x in DDR4DB01 spec
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 144 (Bits 5~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 61
+///
+fapi2::ReturnCode decoder_v1_0::data_buffer_vref_dq(uint8_t& o_output)
+{
+ constexpr size_t BYTE_INDEX = 144;
+ uint8_t l_raw_data = iv_spd_data[BYTE_INDEX];
+
+ // Trace in the front assists w/ debug
+ FAPI_INF("%s SPD data at Byte %d: 0x%llX.",
+ mss::c_str(iv_target),
+ BYTE_INDEX,
+ l_raw_data);
+
+ // DDR4DB01 spec
+ constexpr size_t RESERVED = 0b00110011;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_raw_data < RESERVED,
+ BYTE_INDEX,
+ l_raw_data,
+ "Failed bounds check for data buffer VrefDQ for DRAM interface") );
+
+ // Update output only if check passes
+ o_output = l_raw_data;
+
+ FAPI_INF("%s. Data buffer VrefDQ for DRAM interface: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes DRAM interface MDQ Drive Strenth
+/// of the data buffer component for a particular dimm speed
+/// @param[in] i_dimm_speed the dimm speed in MT/s
+/// @param[out] o_output encoding of F5BC6x in
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 145 - 147 (Bits 6~4)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 62
+///
+fapi2::ReturnCode decoder_v1_0::data_buffer_mdq_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_output)
+{
+ uint8_t l_byte = 0;
+ uint8_t l_field_bits = 0;
+
+ FAPI_TRY( mdq_helper(i_dimm_speed, l_byte) );
+
+ {
+ constexpr size_t START = 1;
+ constexpr size_t LEN = 3;
+ const field_t MDQ_DRIVE_STRENGTH(l_byte, START, LEN);
+
+ l_field_bits = extract_spd_field( iv_target, MDQ_DRIVE_STRENGTH, iv_spd_data );
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // Lets make sure we aren't being set to a reserved field
+ bool is_reserved_bit = false;
+
+ switch(l_field_bits)
+ {
+ case 0b011:
+ case 0b100:
+ case 0b110:
+ case 0b111:
+ is_reserved_bit = true;
+ break;
+
+ default:
+ is_reserved_bit = false;
+ break;
+ }
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VALUE = 7;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ (l_field_bits <= MAX_VALID_VALUE) &&
+ (is_reserved_bit != true),
+ l_byte,
+ l_field_bits,
+ "Failed bounds check for DRAM interface MDQ Drive Strenth") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. DRAM interface MDQ Drive Strenth: %d",
+ mss::c_str(iv_target),
+ o_output);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes DRAM interface MDQ read termination strength
+/// of the data buffer component for a particular dimm speed
+/// @param[in] i_dimm_speed the dimm speed in MT/s
+/// @param[out] o_output encoding of F5BC6x in
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 145 - 147 (Bits 2~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 62
+///
+fapi2::ReturnCode decoder_v1_0::data_buffer_mdq_rtt(const uint64_t i_dimm_speed, uint8_t& o_output)
+{
+ uint8_t l_byte = 0;
+ uint8_t l_field_bits = 0;
+
+ FAPI_TRY( mdq_helper(i_dimm_speed, l_byte) );
+
+ {
+ constexpr size_t START = 1;
+ constexpr size_t LEN = 3;
+ const field_t DATA_BUFFER_MDQ_RTT(l_byte, START, LEN);
+
+ l_field_bits = extract_spd_field( iv_target, DATA_BUFFER_MDQ_RTT, iv_spd_data );
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VALUE = 7;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VALUE,
+ l_byte,
+ l_field_bits,
+ "Failed bounds check for DRAM interface MDQ RTT:") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. DRAM interface MDQ RTT: %d",
+ mss::c_str(iv_target),
+ o_output);
+ }
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes DRAM drive strenth
+/// for a particular dimm speed
+/// @param[in] i_dimm_speed the dimm speed in MT/s
+/// @param[out] o_output DRAM drive strength (encoding)
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 148 (Bits 5~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 63
+///
+fapi2::ReturnCode decoder_v1_0::dram_drive_strength(const uint64_t i_dimm_speed, uint8_t& o_output)
+{
+ size_t l_start = 0;
+ FAPI_TRY( drive_strength_start_bit_finder(i_dimm_speed, l_start) );
+
+ {
+ constexpr size_t BYTE_INDEX = 148;
+ constexpr size_t LEN = 2;
+ const field_t DRAM_DRIVE_STRENGTH(BYTE_INDEX, l_start, LEN);
+
+ uint8_t l_field_bits = extract_spd_field( iv_target, DRAM_DRIVE_STRENGTH, iv_spd_data );
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // SPD JEDEC specification
+ constexpr size_t RESERVED = 0b11;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits < RESERVED,
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bounds check for DRAM VrefDQ for Package Rank 3") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. DRAM drive strenth: %d",
+ mss::c_str(iv_target),
+ o_output);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes DRAM ODT for RTT_NOM
+/// for a particular dimm speed
+/// @param[in] i_dimm_speed the dimm speed in MT/s
+/// @param[out] o_output ODT termination strength (encoding)
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 149 - 151 (Bits 2~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - (64 - 65)
+///
+fapi2::ReturnCode decoder_v1_0::dram_rtt_nom(const uint64_t i_dimm_speed, uint8_t& o_output)
+{
+ size_t l_byte = 0;
+ FAPI_TRY( rtt_wr_and_nom_byte_finder(i_dimm_speed, l_byte) );
+
+ {
+ constexpr size_t START = 5;
+ constexpr size_t LEN = 3;
+ const field_t DRAM_RTT_NOM(l_byte, START, LEN);
+
+ uint8_t l_field_bits = extract_spd_field(iv_target, DRAM_RTT_NOM, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VALUE = 7;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VALUE,
+ l_byte,
+ l_field_bits,
+ "Failed bounds check for DRAM RTT_NOM") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. DRAM RTT_NOM: %d",
+ mss::c_str(iv_target),
+ o_output);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes DRAM ODT for RTT_WR
+/// for a particular dimm speed
+/// @param[in] i_dimm_speed the dimm speed in MT/s
+/// @param[out] o_output ODT termination strength (encoding)
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 149 - 151 (Bits 5~3)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - (64 - 65)
+///
+fapi2::ReturnCode decoder_v1_0::dram_rtt_wr(const uint64_t i_dimm_speed, uint8_t& o_output)
+{
+ size_t l_byte = 0;
+ FAPI_TRY( rtt_wr_and_nom_byte_finder(i_dimm_speed, l_byte) );
+
+ {
+ constexpr size_t START = 2;
+ constexpr size_t LEN = 3;
+ const field_t DRAM_RTT_WR(l_byte, START, LEN);
+
+ uint8_t l_field_bits = extract_spd_field(iv_target, DRAM_RTT_WR, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // Lets make sure we aren't being set to a reserved field
+ bool is_reserved_bit = false;
+
+ switch(l_field_bits)
+ {
+ case 0b101:
+ case 0b110:
+ case 0b111:
+ is_reserved_bit = true;
+ break;
+
+ default:
+ is_reserved_bit = false;
+ break;
+ }
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VALUE = 7;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ (l_field_bits <= MAX_VALID_VALUE) &&
+ (is_reserved_bit != true),
+ l_byte,
+ l_field_bits,
+ "Failed bounds check for DRAM RTT_WR") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. DRAM_RTT_WR: %d",
+ mss::c_str(iv_target),
+ o_output);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes DRAM ODT for RTT_PARK, package ranks 0 & 1
+/// for a particular dimm speed
+/// @param[in] i_dimm_speed the dimm speed in MT/s
+/// @param[out] o_output ODT termination strength (encoding)
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 152 - 154 (Bits 2~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 65
+///
+fapi2::ReturnCode decoder_v1_0::dram_rtt_park_ranks0_1(const uint64_t i_dimm_speed, uint8_t& o_output)
+{
+ size_t l_byte = 0;
+ FAPI_TRY( rtt_park_byte_finder(i_dimm_speed, l_byte) );
+
+ {
+ constexpr size_t START = 5;
+ constexpr size_t LEN = 3;
+ const field_t DRAM_RTT_PARK(l_byte, START, LEN);
+
+ uint8_t l_field_bits = extract_spd_field(iv_target, DRAM_RTT_PARK, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VALUE = 7;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VALUE,
+ l_byte,
+ l_field_bits,
+ "Failed bounds check for DRAM RTT_PARK (package ranks 0,1)") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. DRAM RTT_PARK (package ranks 0,1): %d",
+ mss::c_str(iv_target),
+ o_output);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes DRAM ODT for RTT_PARK, package ranks 2 & 3
+/// for a particular dimm speed
+/// @param[in] i_dimm_speed the dimm speed in MT/s
+/// @param[out] o_output ODT termination strength (encoding)
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 152 - 154 (Bits 5~3)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12.2 - 65
+///
+fapi2::ReturnCode decoder_v1_0::dram_rtt_park_ranks2_3(const uint64_t i_dimm_speed, uint8_t& o_output)
+{
+ size_t l_byte = 0;
+ FAPI_TRY( rtt_park_byte_finder(i_dimm_speed, l_byte) );
+
+ {
+ constexpr size_t START = 2;
+ constexpr size_t LEN = 3;
+ const field_t DRAM_RTT_PARK(l_byte, START, LEN);
+
+ uint8_t l_field_bits = extract_spd_field(iv_target, DRAM_RTT_PARK, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VALUE = 7;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VALUE,
+ l_byte,
+ l_field_bits,
+ "Failed bounds check for DRAM RTT_PARK (package ranks 2,3)") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. DRAM RTT_PARK (package ranks 2,3): %d",
+ mss::c_str(iv_target),
+ o_output);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+}// lrdimm
+}//spd
+}// mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder_v1_1.C b/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder_v1_1.C
index cdaee5940..dfe54bbe3 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder_v1_1.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder_v1_1.C
@@ -32,3 +32,312 @@
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: HB:FSP
+
+// std lib
+#include <vector>
+
+// fapi2
+#include <fapi2.H>
+
+// mss lib
+#include <lib/spd/lrdimm/lrdimm_decoder.H>
+#include <lib/spd/common/spd_decoder.H>
+#include <lib/utils/checker.H>
+#include <lib/utils/c_str.H>
+#include <lib/utils/find.H>
+
+using fapi2::TARGET_TYPE_MCA;
+using fapi2::TARGET_TYPE_MCS;
+using fapi2::TARGET_TYPE_DIMM;
+
+namespace mss
+{
+namespace spd
+{
+namespace lrdimm
+{
+
+///
+/// @brief Decodes register and data buffer types
+/// @param[out] o_output encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 131 (Bits 7~4)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 3
+/// @note Page 4.1.2.12.3 - 63
+///
+fapi2::ReturnCode decoder_v1_1::register_and_buffer_type(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< REGISTER_TYPE >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t RESERVED = 2;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits < RESERVED, // extract sanity check
+ REGISTER_TYPE.iv_byte,
+ l_field_bits,
+ "Failed bounds check for Register and Data Buffer Types") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Register and Data Buffer Types: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief Decodes register output drive strength for CKE signal
+/// @param[out] o_output encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 137 (Bits 1~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 3
+/// @note Page 4.1.2.12.3 - 65
+///
+fapi2::ReturnCode decoder_v1_1::cke_signal_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< CKE_DRIVE_STRENGTH >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VAL = 3;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VAL, // extract sanity check
+ CKE_DRIVE_STRENGTH.iv_byte,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for CKE") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Register Output Driver for CKE: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes register output drive strength for ODT signal
+/// @param[out] o_output encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 137 (Bits 3~2)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 3
+/// @note Page 4.1.2.12.3 - 65
+///
+fapi2::ReturnCode decoder_v1_1::odt_signal_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< ODT_DRIVE_STRENGTH >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VAL = 3;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VAL, // extract sanity check
+ ODT_DRIVE_STRENGTH.iv_byte,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for ODT") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Register Output Driver for ODT: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes register output drive strength for chip select (CS) signal
+/// @param[out] o_output encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 137 (Bits 6~7)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 3
+/// @note Page 4.1.2.12.3 - 65
+///
+fapi2::ReturnCode decoder_v1_1::cs_signal_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< CS_DRIVE_STRENGTH >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VAL = 3;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VAL, // extract sanity check
+ CS_DRIVE_STRENGTH.iv_byte,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for CS") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Register Output Driver for CS: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes register output drive strength for clock (B side)
+/// @param[out] o_output drive strength encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 138 (Bits 1~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 3
+/// @note Page 4.1.2.12.3 - 66
+///
+fapi2::ReturnCode decoder_v1_1::b_side_clk_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< B_SIDE_DRIVE_STRENGTH >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VAL = 3;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VAL, // extract sanity check
+ B_SIDE_DRIVE_STRENGTH.iv_byte,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for clock (Y0,Y2)") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Register Output Driver for clock (Y0,Y2): %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes register output drive strength for clock (A side)
+/// @param[out] o_output drive strength encoding from SPD
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 138 (Bits 3~2)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 3
+/// @note Page 4.1.2.12.3 - 66
+///
+fapi2::ReturnCode decoder_v1_1::a_side_clk_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< A_SIDE_DRIVE_STRENGTH >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VAL = 3;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VAL,
+ A_SIDE_DRIVE_STRENGTH.iv_byte,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for clock (Y1,Y3)") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Register Output Driver for clock (Y1,Y3): %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes register output drive strength for data buffer control (BCOM, BODT, BKCE)
+/// @param[out] o_output encoded drive strength
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 138 (Bit 4)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 3
+/// @note Page 4.1.2.12.3 - 66
+///
+fapi2::ReturnCode decoder_v1_1::bcom_bcke_bodt_drive_strength(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< BCOM_BODT_BCKE_DRIVE_STRENGTH >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VAL = 3;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VAL,
+ BCOM_BODT_BCKE_DRIVE_STRENGTH.iv_byte,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for data buffer control (BCOM, BODT, BCKE)") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Register Output Driver for data buffer control (BCOM, BODT, BCKE): %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes register output drive strength for data buffer control (BCK)
+/// @param[out] o_output encoded drive strength
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 138 (Bit 5)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 3
+/// @note Page 4.1.2.12.3 - 66
+///
+fapi2::ReturnCode decoder_v1_1::bck_output_drive_strength(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< BCK_DRIVE_STRENGTH >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VAL = 3;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VAL,
+ BCK_DRIVE_STRENGTH.iv_byte,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for data buffer control (BCK)") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Register Output Driver for data buffer control (BCK): %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+}// lrdimm
+}// spd
+}// mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder_v1_2.C b/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder_v1_2.C
index 0682389dc..5bf7d02ed 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder_v1_2.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/spd/lrdimm/lrdimm_decoder_v1_2.C
@@ -32,3 +32,206 @@
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: HB:FSP
+
+// std lib
+#include <vector>
+
+// fapi2
+#include <fapi2.H>
+
+// mss lib
+#include <lib/spd/lrdimm/lrdimm_decoder.H>
+#include <lib/spd/common/spd_decoder.H>
+#include <lib/utils/checker.H>
+#include <lib/utils/c_str.H>
+#include <lib/utils/find.H>
+
+using fapi2::TARGET_TYPE_MCA;
+using fapi2::TARGET_TYPE_MCS;
+using fapi2::TARGET_TYPE_DIMM;
+
+namespace mss
+{
+namespace spd
+{
+namespace lrdimm
+{
+
+///
+/// @brief Decodes RCD output slew rate control
+/// @param[out] o_output encoded drive strength
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 138 (Bit 6)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 4
+/// @note Page 4.1.2.L-4 - 70
+///
+fapi2::ReturnCode decoder_v1_2::slew_rate_control(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< RCD_SLEW_CNTRL >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VAL = 0b1111;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VAL, // extract sanity check
+ RCD_SLEW_CNTRL.iv_byte,
+ l_field_bits,
+ "Failed bound check for RCD output slew rate control") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. RCD output slew rate control: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes VrefDQ range for DRAM interface range
+/// @param[out] o_output spd encoding
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 155 (Bits 3~0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 4
+/// @note Page 4.1.2.L-4 - 76
+///
+fapi2::ReturnCode decoder_v1_2::dram_vref_dq_range(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< DRAM_VREF_DQ_RANGE >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VAL = 0b1111;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VAL, // extract sanity check
+ DRAM_VREF_DQ_RANGE.iv_byte,
+ l_field_bits,
+ "Failed bound check for VrefDQ range for DRAM interface range ") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. VrefDQ range for DRAM interface range: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes data buffer VrefDQ range for DRAM interface range
+/// @param[out] o_output spd encoding
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 155 (Bit 4)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 4
+/// @note Page 4.1.2.L-4 - 76
+///
+fapi2::ReturnCode decoder_v1_2::data_buffer_vref_dq_range(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< DATA_BUFFER_VREF_DQ >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VAL = 1;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VAL, // extract sanity check
+ DATA_BUFFER_VREF_DQ.iv_byte,
+ l_field_bits,
+ "Failed bound check for data buffer VrefDQ range for DRAM interface range") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Data buffer VrefDQ range for DRAM interface range: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes data buffer gain adjustment
+/// @param[out] o_output spd encoding
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 156 (Bit 0)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 4
+/// @note Page 4.1.2.L-4 - 77
+///
+fapi2::ReturnCode decoder_v1_2::data_buffer_gain_adjustment(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< DATA_BUFFER_GAIN_ADJUST >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VAL = 1;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VAL, // extract sanity check
+ DATA_BUFFER_GAIN_ADJUST.iv_byte,
+ l_field_bits,
+ "Failed bound check for data buffer gain adjustment") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Data buffer gain adjustment: %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Decodes data buffer Decision Feedback Equalization (DFE)
+/// @param[out] o_output spd encoding
+/// @return FAPI2_RC_SUCCESS if okay
+/// @note SPD Byte 156 (Bit 1)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 4
+/// @note Page 4.1.2.L-4 - 77
+///
+fapi2::ReturnCode decoder_v1_2::data_buffer_dfe(uint8_t& o_output)
+{
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field< DATA_BUFFER_DFE >(iv_target, iv_spd_data);
+ FAPI_INF("Field Bits value: %d", l_field_bits);
+
+ // This checks my extracting params returns a value within bound
+ constexpr size_t MAX_VALID_VAL = 1;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VAL, // extract sanity check
+ DATA_BUFFER_DFE.iv_byte,
+ l_field_bits,
+ "Failed bound check for data buffer Decision Feedback Equalization (DFE)") );
+
+ // Update output only if check passes
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Data buffer Decision Feedback Equalization (DFE): %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+}// lrdimm
+}// spd
+}// mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/spd/rdimm/rdimm_decoder_v1_0.C b/src/import/chips/p9/procedures/hwp/memory/lib/spd/rdimm/rdimm_decoder_v1_0.C
index b841879f2..0e2643e8a 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/spd/rdimm/rdimm_decoder_v1_0.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/spd/rdimm/rdimm_decoder_v1_0.C
@@ -380,7 +380,7 @@ fapi2::ReturnCode rdimm_decoder_v1_0::manufacturer_id_code(uint8_t& o_output)
o_output = l_raw_byte;
- FAPI_INF("%s. Register revision number: %d",
+ FAPI_INF("%s. Manufacturer ID code: %d",
mss::c_str(iv_target),
o_output);
OpenPOWER on IntegriCloud