summaryrefslogtreecommitdiffstats
path: root/src/import/generic/memory/lib/spd/rdimm
diff options
context:
space:
mode:
authorAndre Marin <aamarin@us.ibm.com>2017-03-22 23:04:12 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-03-27 12:29:28 -0400
commitaae922c1132fa71bd4ffb711296420755c7c0098 (patch)
treeea757503109d8918cb54105405a81438439797ff /src/import/generic/memory/lib/spd/rdimm
parenta8edc5a1152e91170728d19ae5d0839223803bef (diff)
downloadtalos-hostboot-aae922c1132fa71bd4ffb711296420755c7c0098.tar.gz
talos-hostboot-aae922c1132fa71bd4ffb711296420755c7c0098.zip
Add base spd decoder to share among controllers
Reorganized files and names to make room for DDR3 SPD decoder to be used for Cumulus. Change-Id: Id3e7a8f4bb60fd0ae0cdf36b8298a1d00257205a Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/36319 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: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/36326 Reviewed-by: Hostboot Team <hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/generic/memory/lib/spd/rdimm')
-rw-r--r--src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H431
-rw-r--r--src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_0.C672
-rw-r--r--src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_1.C273
-rw-r--r--src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.C216
-rw-r--r--src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.H86
5 files changed, 1678 insertions, 0 deletions
diff --git a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H
new file mode 100644
index 000000000..effc7f983
--- /dev/null
+++ b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H
@@ -0,0 +1,431 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file rdimm_decoder.H
+/// @brief RDIMM module SPD decoder declarations
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_RDIMM_DECODER_H_
+#define _MSS_RDIMM_DECODER_H_
+
+#include <fapi2.H>
+#include <generic/memory/lib/spd/common/dimm_module_decoder.H>
+
+namespace mss
+{
+namespace spd
+{
+
+///
+/// @class decoder
+/// @brief RDIMM module SPD DRAM decoder for rev 1.0
+///
+class rdimm_decoder_v1_0 : public dimm_module_decoder
+{
+ protected:
+ enum
+ {
+ // Byte 128
+ MODULE_NOM_HEIGHT_START = 3,
+ MODULE_NOM_HEIGHT_LEN = 5,
+ RAW_CARD_EXT_START = 0,
+ RAW_CARD_EXT_LEN = 3,
+
+ // Byte 129
+ FRONT_MODULE_THICKNESS_START = 4,
+ FRONT_MODULE_THICKNESS_LEN = 4,
+ BACK_MODULE_THICKNESS_START = 0,
+ BACK_MODULE_THICKNESS_LEN = 4,
+
+ // Byte 130
+ REF_RAW_CARD_START = 3,
+ REF_RAW_CARD_LEN = 5,
+ REF_RAW_CARD_REV_START = 1,
+ REF_RAW_CARD_REV_LEN = 2,
+ REF_RAW_CARD_EXT_START = 0,
+ REF_RAW_CARD_EXT_LEN = 1,
+
+ // Byte 131
+ REGS_USED_START = 6,
+ REGS_USED_LEN = 2,
+ ROWS_OF_DRAMS_START = 4,
+ ROWS_OF_DRAMS_LEN = 2,
+ REGISTER_TYPE_START = 0,
+ REGISTER_TYPE_LEN = 4,
+
+ // Byte 132
+ HEAT_SPREADER_CHAR_START = 1,
+ HEAT_SPREADER_CHAR_LEN = 7,
+ HEAT_SPREADER_SOL_START = 0,
+ HEAT_SPREADER_SOL_LEN = 1,
+
+ // Byte 133
+ CONTINUATION_CODES_START = 1,
+ CONTINUATION_CODES_LEN = 7,
+
+ // Byte 134 - whole byte taken
+ // Byte 135 - whole byte taken
+
+ // Byte 136
+ ADDR_MAPPING_START = 7,
+ ADDR_MAPPING_LEN = 1,
+
+ // Byte 137
+ CKE_DRIVER_START = 6,
+ CKE_DRIVER_LEN = 2,
+ ODT_DRIVER_START = 4,
+ ODT_DRIVER_LEN = 2,
+ CA_DRIVER_START = 2,
+ CA_DRIVER_LEN = 2,
+ CS_DRIVER_START = 0,
+ CS_DRIVER_LEN = 2,
+
+ // Byte 138
+ YO_Y2_DRIVER_START = 6,
+ YO_Y2_DRIVER_LEN = 2,
+ Y1_Y3_DRIVER_START = 4,
+ Y1_Y3_DRIVER_LEN = 2,
+ };
+
+ enum addr_mapping
+ {
+ STANDARD = 0,
+ MIRRORED = 1,
+ };
+
+ public:
+ // deleted default ctor
+ rdimm_decoder_v1_0() = delete;
+
+ ///
+ /// @brief ctor
+ /// @param[in] i_target dimm target
+ /// @param[in] i_spd_data vector DIMM SPD data
+ ///
+ rdimm_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 ~rdimm_decoder_v1_0() = default;
+
+ ///
+ /// @brief Decodes module nominal height max, in mm
+ /// @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) override;
+
+ ///
+ /// @brief Decodes front module maximum thickness max, in mm
+ /// @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) override;
+
+ ///
+ /// @brief Decodes back module maximum thickness max, in mm
+ /// @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) override;
+
+ ///
+ /// @brief Decodes number of registers used on RDIMM
+ /// @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 - 50
+ ///
+ virtual fapi2::ReturnCode num_registers_used(uint8_t& o_output) override;
+
+ ///
+ /// @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 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) override;
+
+ ///
+ /// @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) 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 - 51
+ ///
+ 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 (bit 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) override;
+
+ ///
+ /// @brief Decodes register 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 Item JEDEC Standard No. 21-C
+ /// @note DDR4 SPD Document Release 2
+ /// @note Page 4.1.2.12 - 51
+ ///
+ virtual fapi2::ReturnCode reg_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 136 (bit 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) 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 - 52
+ ///
+ 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 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 - 53
+ ///
+ 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 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 - 53
+ ///
+ 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 (bit 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) override;
+
+ ///
+ /// @brief Decodes register output drive strength for control signal (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 - 53
+ ///
+ 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 (bit 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) 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 (bit 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) override;
+
+ protected:
+ const fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
+ const std::vector<uint8_t> iv_spd_data;
+
+};// rdimm_decoder_v1_0
+
+///
+/// @class decoder
+/// @brief RDIMM module SPD DRAM decoder for rev 1.1
+///
+class rdimm_decoder_v1_1 : public rdimm_decoder_v1_0
+{
+ public:
+
+ // deleted default ctor
+ rdimm_decoder_v1_1() = delete;
+
+ ///
+ /// @brief ctor
+ /// @param[in] i_target dimm target
+ /// @param[in] i_spd_data vector DIMM SPD data
+ ///
+ rdimm_decoder_v1_1(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const std::vector<uint8_t>& i_spd_data): rdimm_decoder_v1_0(i_target, i_spd_data)
+ {}
+
+ ///
+ /// @brief default dtor
+ ///
+ virtual ~rdimm_decoder_v1_1() = default;
+
+ ///
+ /// @brief Decodes register 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 drive strength 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
+ ///
+ 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 drive strength 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
+ ///
+ virtual fapi2::ReturnCode odt_signal_output_driver(uint8_t& o_output) override;
+
+ ///
+ /// @brief Decodes register output drive strength for control signal (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 JC-45-2220.01x
+ /// @note Page 76
+ /// @note DDR4 SPD Document Release 4
+ ///
+ 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 (bit 1~0)
+ /// @note Item JC-45-2220.01x
+ /// @note Page 76
+ /// @note DDR4 SPD Document Release 4
+ ///
+ 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 (bit 3~2)
+ /// @note Item JC-45-2220.01x
+ /// @note Page 76
+ /// @note DDR4 SPD Document Release 4
+ ///
+ virtual fapi2::ReturnCode a_side_clk_output_driver(uint8_t& o_output) override;
+
+};//rdimm_decoder_v1_1
+
+}// spd
+}// mss
+
+#endif //_MSS_RDIMM_DECODER_H_
diff --git a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_0.C b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_0.C
new file mode 100644
index 000000000..43eb08c51
--- /dev/null
+++ b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_0.C
@@ -0,0 +1,672 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_0.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file rdimm_decoder.C
+/// @brief RDIMM module specific SPD decoder definitions
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB:FSP
+
+// std lib
+#include <vector>
+
+// fapi2
+#include <fapi2.H>
+
+// mss lib
+#include <generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H>
+#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
+#include <generic/memory/lib/spd/spd_checker.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <generic/memory/lib/utils/find.H>
+
+using fapi2::TARGET_TYPE_MCBIST;
+using fapi2::TARGET_TYPE_MCA;
+using fapi2::TARGET_TYPE_MCS;
+using fapi2::TARGET_TYPE_DIMM;
+
+
+namespace mss
+{
+namespace spd
+{
+
+/////////////////////////
+// Member Method implementation
+// For RDIMM module rev 1.0
+/////////////////////////
+
+///
+/// @brief Decodes module nominal height max, in mm
+/// @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
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::max_module_nominal_height(uint8_t& o_output)
+{
+ constexpr size_t BYTE_INDEX = 128;
+ uint8_t l_field_bits = extract_spd_field<BYTE_INDEX, MODULE_NOM_HEIGHT_START, MODULE_NOM_HEIGHT_LEN>(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,
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bound check for module nominal height max") );
+
+ 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 front module maximum thickness max, in mm
+/// @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
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::front_module_max_thickness(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE_INDEX = 129;
+ uint8_t l_field_bits = extract_spd_field<BYTE_INDEX, FRONT_MODULE_THICKNESS_START, FRONT_MODULE_THICKNESS_LEN>
+ (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,
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bound check for front module max thickness") );
+
+ 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, in mm
+/// @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
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::back_module_max_thickness(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE_INDEX = 129;
+ uint8_t l_field_bits = extract_spd_field<BYTE_INDEX, BACK_MODULE_THICKNESS_START, BACK_MODULE_THICKNESS_LEN>(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,
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bound check for back module max thickness") );
+
+ 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 RDIMM
+/// @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 - 50
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::num_registers_used(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE_INDEX = 131;
+ uint8_t l_field_bits = extract_spd_field<BYTE_INDEX, REGS_USED_START, REGS_USED_LEN>(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 = 0b11;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VALUE,
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bound check for number of registers used on RDIMM ") );
+
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Number of registers used on RDIMM : %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+///
+/// @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 3~2)
+/// @note Item JEDEC Standard No. 21-C
+/// @note DDR4 SPD Document Release 2
+/// @note Page 4.1.2.12 - 50
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::num_rows_of_drams(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE_INDEX = 131;
+ uint8_t l_field_bits = extract_spd_field<BYTE_INDEX, ROWS_OF_DRAMS_START, ROWS_OF_DRAMS_LEN>(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 = 0b11;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VALUE,
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bound check for number of rows of DRAMs on RDIMM ") );
+
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Number of rows of DRAMs on RDIMM : %d",
+ mss::c_str(iv_target),
+ o_output);
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+///
+/// @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
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::heat_spreader_thermal_char(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE_INDEX = 132;
+ uint8_t l_field_bits = extract_spd_field<BYTE_INDEX, HEAT_SPREADER_CHAR_START, HEAT_SPREADER_CHAR_LEN>(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,
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bound check for heat spreader thermal characteristics") );
+
+ o_output = l_field_bits;
+
+ FAPI_INF("%s. Heat spreader thermal characteristics: %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 - 51
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::heat_spreader_solution(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE_INDEX = 132;
+ uint8_t l_field_bits = extract_spd_field<BYTE_INDEX, HEAT_SPREADER_SOL_START, HEAT_SPREADER_SOL_LEN>(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,
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bound check for heat spreader solution") );
+
+ 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 - 51
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::num_continuation_codes(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE_INDEX = 133;
+ uint8_t l_field_bits = extract_spd_field<BYTE_INDEX, CONTINUATION_CODES_START, CONTINUATION_CODES_LEN>(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
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits <= MAX_VALID_VALUE,
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bound check for number of continuation codes") );
+
+ 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 register 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 - 51
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::reg_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);
+
+ o_output = l_raw_byte;
+
+ FAPI_INF("%s. Manufacturer ID code: %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 - 51
+///
+fapi2::ReturnCode rdimm_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);
+
+ 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 - 52
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::register_to_dram_addr_mapping(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE_INDEX = 136;
+ uint8_t l_field_bits = extract_spd_field<BYTE_INDEX, ADDR_MAPPING_START, ADDR_MAPPING_LEN>(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, // extract sanity check
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bound check for to register to dram addr mapping") );
+
+ 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 - 53
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::cke_signal_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE_INDEX = 137;
+ uint8_t l_field_bits = extract_spd_field<BYTE_INDEX, CKE_DRIVER_START, CKE_DRIVER_LEN>(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
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for CKE") );
+
+ 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 - 53
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::odt_signal_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE_INDEX = 137;
+ uint8_t l_field_bits = extract_spd_field<BYTE_INDEX, ODT_DRIVER_START, ODT_DRIVER_LEN>(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
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for ODT") );
+
+ 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 - 53
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::ca_signal_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE_INDEX = 137;
+ uint8_t l_field_bits = extract_spd_field<BYTE_INDEX, CA_DRIVER_START, CA_DRIVER_LEN>(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 = 3;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ l_field_bits < INVALID_VAL, // extract sanity check
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for CA") );
+
+ 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 control signal (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 - 53
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::cs_signal_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE_INDEX = 137;
+ uint8_t l_field_bits = extract_spd_field<BYTE_INDEX, CS_DRIVER_START, CS_DRIVER_LEN>(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
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for CS") );
+
+ 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 - 53
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::b_side_clk_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE_INDEX = 138;
+ uint8_t l_field_bits = extract_spd_field<BYTE_INDEX, YO_Y2_DRIVER_START, YO_Y2_DRIVER_LEN>(iv_target, iv_spd_data);
+
+ // 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
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for clock (Y0,Y2)") );
+
+ 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 - 53
+///
+fapi2::ReturnCode rdimm_decoder_v1_0::a_side_clk_output_driver(uint8_t& o_output)
+{
+ // Trace in the front assists w/ debug
+ constexpr size_t BYTE_INDEX = 138;
+
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field<BYTE_INDEX, Y1_Y3_DRIVER_START, Y1_Y3_DRIVER_LEN>(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,
+ BYTE_INDEX,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for clock (Y1,Y3)") );
+
+ 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;
+}
+
+}//spd namespace
+}// mss namespace
diff --git a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_1.C b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_1.C
new file mode 100644
index 000000000..4517de0a7
--- /dev/null
+++ b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_1.C
@@ -0,0 +1,273 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4_v1_1.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+// std lib
+#include <vector>
+
+// fapi2
+#include <fapi2.H>
+
+// mss lib
+#include <generic/memory/lib/spd/rdimm/ddr4/rdimm_decoder_ddr4.H>
+#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
+#include <generic/memory/lib/spd/spd_checker.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <generic/memory/lib/utils/find.H>
+
+using fapi2::TARGET_TYPE_MCBIST;
+using fapi2::TARGET_TYPE_MCA;
+using fapi2::TARGET_TYPE_MCS;
+using fapi2::TARGET_TYPE_DIMM;
+
+
+namespace mss
+{
+namespace spd
+{
+
+/////////////////////////
+// Member Method implementation
+// For RDIMM module rev 1.1
+/////////////////////////
+
+///
+/// @brief Decodes register type
+/// @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 rdimm_decoder_v1_1::register_and_buffer_type(uint8_t& o_output)
+{
+ constexpr size_t BYTE = 131;
+ // Extracting desired bits
+ uint8_t l_field_bits = extract_spd_field<BYTE, REGISTER_TYPE_START, REGISTER_TYPE_LEN>(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
+ 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 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 drive strength 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
+///
+fapi2::ReturnCode rdimm_decoder_v1_1::cke_signal_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE = 137;
+ uint8_t l_field_bits = extract_spd_field<BYTE, CKE_DRIVER_START, CKE_DRIVER_LEN>(iv_target, iv_spd_data);
+
+ FAPI_INF("Field_Bits value: %d", l_field_bits);
+
+ // This really just checks my extract gives me a valid value
+ constexpr size_t MAX_VALID_VALUE = 0b11;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ (l_field_bits <= MAX_VALID_VALUE), // extract sanity check
+ BYTE,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for CKE") );
+
+ 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 JC-45-2220.01x
+/// @note Page 76
+/// @note DDR4 SPD Document Release 4
+///
+fapi2::ReturnCode rdimm_decoder_v1_1::odt_signal_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE = 137;
+ uint8_t l_field_bits = extract_spd_field<BYTE, ODT_DRIVER_START, ODT_DRIVER_LEN>(iv_target, iv_spd_data);
+
+ FAPI_INF("Field_Bits value: %d", l_field_bits);
+
+ // This really just checks my extract gives me a valid value
+ constexpr size_t MAX_VALID_VALUE = 0b11;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ (l_field_bits <= MAX_VALID_VALUE), // extract sanity check
+ BYTE,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for ODT") );
+
+ 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 control signal (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 JC-45-2220.01x
+/// @note Page 76
+/// @note DDR4 SPD Document Release 4
+///
+fapi2::ReturnCode rdimm_decoder_v1_1::cs_signal_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE = 137;
+ uint8_t l_field_bits = extract_spd_field<BYTE, CS_DRIVER_START, CS_DRIVER_LEN>(iv_target, iv_spd_data);
+
+ FAPI_INF("Field_Bits value: %d", l_field_bits);
+
+ // This really just checks my extract gives me a valid value
+ constexpr size_t MAX_VALID_VALUE = 0b11;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ (l_field_bits <= MAX_VALID_VALUE), // extract sanity check
+ BYTE,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for chip select") );
+
+ 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 JC-45-2220.01x
+/// @note Page 76
+/// @note DDR4 SPD Document Release 4
+///
+fapi2::ReturnCode rdimm_decoder_v1_1::b_side_clk_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE = 138;
+ uint8_t l_field_bits = extract_spd_field<BYTE, YO_Y2_DRIVER_START, YO_Y2_DRIVER_LEN>(iv_target, iv_spd_data);
+
+ FAPI_INF("Field_Bits value: %d", l_field_bits);
+
+ // This really just checks my extract gives me a valid value
+ constexpr size_t MAX_VALID_VAL = 2;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ (l_field_bits <= MAX_VALID_VAL), // extract sanity check
+ BYTE,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for clock (Y0,Y2)") );
+
+ 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 JC-45-2220.01x
+/// @note Page 76
+/// @note DDR4 SPD Document Release 4
+///
+fapi2::ReturnCode rdimm_decoder_v1_1::a_side_clk_output_driver(uint8_t& o_output)
+{
+ // Extracting desired bits
+ constexpr size_t BYTE = 138;
+ uint8_t l_field_bits = extract_spd_field<BYTE, Y1_Y3_DRIVER_START, Y1_Y3_DRIVER_LEN>(iv_target, iv_spd_data);
+
+ FAPI_INF("Field_Bits value: %d", l_field_bits);
+
+ // This really just checks my extract gives me a valid value
+ constexpr size_t MAX_VALID_VAL = 2;
+
+ FAPI_TRY( mss::check::spd::fail_for_invalid_value(iv_target,
+ (l_field_bits <= MAX_VALID_VAL), // extract sanity check
+ BYTE,
+ l_field_bits,
+ "Failed bounds check for Register Output Driver for clock (Y1,Y3)") );
+
+ 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;
+}
+
+}//spd
+}// mss
diff --git a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.C b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.C
new file mode 100644
index 000000000..0b4e50f02
--- /dev/null
+++ b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.C
@@ -0,0 +1,216 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file raw_cards.C
+/// @brief RDIMM raw card data structure
+/// Contains RCW settings per raw card rev
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: FSP:HB
+
+// std lib
+#include <vector>
+
+// fapi2
+#include <fapi2.H>
+
+// mss lib
+#include <generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.H>
+
+namespace mss
+{
+
+///
+/// @brief raw card C1 settings
+///
+rcw_settings rdimm_rc_c1( 0x00, // RC00
+ 0x00, // RC01 (C might be the right answer?)
+ 0x00, // RC02
+ 0x0F, // RC06_07
+ 0x00, // RC09
+ 0x0E, // RC0B
+ 0x00, // RC0C
+ 0x00, // RC0F
+ 0x00, // RC1X
+ 0x00, // RC2X
+ 0x00, // RC4X
+ 0x00, // RC5X
+ 0x00, // RC6X
+ 0x00, // RC8X
+ 0x00, // RC9X
+ 0x00, // RCAX
+ 0x07);// RCBX
+
+///
+/// @brief raw card C2 settings
+/// @note same settings as C1
+///
+rcw_settings rdimm_rc_c2( 0x00, // RC00
+ 0x00, // RC01 (C might be the right answer?)
+ 0x00, // RC02
+ 0x0F, // RC06_07
+ 0x00, // RC09
+ 0x0E, // RC0B
+ 0x00, // RC0C
+ 0x00, // RC0F
+ 0x00, // RC1X
+ 0x00, // RC2X
+ 0x00, // RC4X
+ 0x00, // RC5X
+ 0x00, // RC6X
+ 0x00, // RC8X
+ 0x00, // RC9X
+ 0x00, // RCAX
+ 0x07);// RCBX
+
+///
+/// @brief raw card A1 settings
+///
+rcw_settings rdimm_rc_a1( 0x00, // RC00
+ 0x00, // RC01 (C might be the right answer?)
+ 0x00, // RC02
+ 0x0F, // RC06_07
+ 0x00, // RC09
+ 0x0E, // RC0B
+ 0x00, // RC0C
+ 0x00, // RC0F
+ 0x00, // RC1X
+ 0x00, // RC2X
+ 0x00, // RC4X
+ 0x00, // RC5X
+ 0x00, // RC6X
+ 0x00, // RC8X
+ 0x00, // RC9X
+ 0x00, // RCAX
+ 0x07);// RCBX
+
+///
+/// @brief raw card B1 settings
+/// @note need to verify, copy from b2, need to verify with b1 annex
+///
+rcw_settings rdimm_rc_b1( 0x00, // RC00
+ 0x00, // RC01 (C might be the right answer?)
+ 0x00, // RC02
+ 0x0F, // RC06_07
+ 0x00, // RC09 //Should be set in eff_config for CKE power DOWN modep:q
+ 0x0E, // RC0B
+ 0x00, // RC0C
+ 0x00, // RC0F
+ 0x00, // RC1X
+ 0x00, // RC2X
+ 0x00, // RC4X
+ 0x00, // RC5X
+ 0x00, // RC6X
+ 0x00, // RC8X
+ 0x00, // RC9X
+ 0x00, // RCAX
+ 0x07);// RCBX
+
+///
+/// @brief raw card B2 settings
+///
+rcw_settings rdimm_rc_b2( 0x00, // RC00
+ 0x00, // RC01 (C might be the right answer?)
+ 0x00, // RC02
+ 0x0F, // RC06_07
+ 0x00, // RC09
+ 0x0E, // RC0B
+ 0x00, // RC0C
+ 0x00, // RC0F
+ 0x00, // RC1X
+ 0x00, // RC2X
+ 0x00, // RC4X
+ 0x00, // RC5X
+ 0x00, // RC6X
+ 0x00, // RC8X
+ 0x00, // RC9X
+ 0x00, // RCAX
+ 0x07);// RCBX
+
+////
+/// @brief raw card for custom dimms
+///
+rcw_settings rdimm_rc_custom ( 0x00, // RC00
+ 0x00, // RC01 (C might be the right answer?)
+ 0x00, // RC02
+ 0x0F, // RC06_07
+ 0x00, // RC09
+ 0x0E, // RC0B
+ 0x00, // RC0C
+ 0x00, // RC0F
+ 0x00, // RC1X
+ 0x00, // RC2X
+ 0x00, // RC4X
+ 0x00, // RC5X
+ 0x00, // RC6X
+ 0x00, // RC8X
+ 0x00, // RC9X
+ 0x00, // RCAX
+ 0x07);// RCBX
+
+//
+/// @brief raw card VBU settings
+///
+rcw_settings rdimm_rc_vbu( 0x00, // RC00
+ 0x00, // RC01
+ 0x00, // RC02
+ 0x0F, // RC06_07
+ 0x00, // RC09
+ 0x0E, // RC0B
+ 0x00, // RC0C
+ 0x00, // RC0F
+ 0x00, // RC1X
+ 0x00, // RC2X
+ 0x00, // RC4X
+ 0x00, // RC5X
+ 0x00, // RC6X
+ 0x00, // RC8X
+ 0x00, // RC9X
+ 0x00, // RCAX
+ 0x07);// RCBX
+
+namespace rdimm
+{
+
+const std::vector< std::pair< uint8_t , rcw_settings> > RAW_CARDS =
+{
+ // I expect this to grow as Warren M. expects us to have
+ // settings for every raw card that JEDEC puts out. Openpower
+ // can't break due to a missing raw card...
+ {raw_card_rev::A1, rdimm_rc_a1},
+ {raw_card_rev::B1, rdimm_rc_b1},
+ {raw_card_rev::C1, rdimm_rc_c1},
+ {raw_card_rev::VBU, rdimm_rc_vbu},
+ {raw_card_rev::B2, rdimm_rc_b2},
+ {raw_card_rev::C2, rdimm_rc_c2},
+ {raw_card_rev::CUSTOM, rdimm_rc_custom},
+};
+
+}// rdimm
+}// mss
diff --git a/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.H b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.H
new file mode 100644
index 000000000..02c30ba79
--- /dev/null
+++ b/src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.H
@@ -0,0 +1,86 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+///
+/// @file raw_cards.H
+/// @brief Raw card data structure
+///
+// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 2
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_RDIMM_RAW_CARDS_H_
+#define _MSS_RDIMM_RAW_CARDS_H_
+
+#include <fapi2.H>
+#include <cstdint>
+#include <vector>
+#include <generic/memory/lib/spd/common/rcw_settings.H>
+
+namespace mss
+{
+namespace rdimm
+{
+
+// In the order of the vector below which needs to be sorted by enum value
+enum raw_card_rev : uint8_t
+{
+ A1 = 0x20,
+ B1 = 0x21,
+
+ // RDIMM power-on
+ C1 = 0x22,
+
+ // TK - Change VBU value to a no-op value or a value that will never be reached -JLH
+ VBU = 0x23,
+
+ B2 = 0x41,
+ C2 = 0x42,
+
+ // Default settings used for DIMMs that do not use a JEDEC raw card reference
+ CUSTOM = 0xFF,
+};
+
+// Raw cards can share the same raw card # between RDIMM and LRDIMMs so
+// we track them independently. Since all of these don't come from SPD for DDR4,
+// we have to set some RCWs (we want limit these and derive as many as possible)
+extern const std::vector< std::pair< uint8_t, rcw_settings> > RAW_CARDS;
+
+}// rdimm
+
+// Exposed so we can test them.
+extern rcw_settings rdimm_rc_c1;
+extern rcw_settings rdimm_rc_c2;
+extern rcw_settings rdimm_rc_a1;
+extern rcw_settings rdimm_rc_b1;
+extern rcw_settings rdimm_rc_b2;
+extern rcw_settings rdimm_rc_custom;
+extern rcw_settings rdimm_rc_vbu;
+
+}// mss
+
+#endif //_MSS_RDIMM_RAW_CARDS_H_
OpenPOWER on IntegriCloud