summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9
diff options
context:
space:
mode:
authorBrian Silver <bsilver@us.ibm.com>2016-07-20 15:19:15 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-08-07 21:42:52 -0400
commit2e757391b9e08b278833c1171714ebad70cd3d9b (patch)
tree5de009dee2b0c241a7dcdbbdfabd633775e72d39 /src/import/chips/p9
parent0840cd326dd311b6dec20b32779d98697d3a1251 (diff)
downloadtalos-hostboot-2e757391b9e08b278833c1171714ebad70cd3d9b.tar.gz
talos-hostboot-2e757391b9e08b278833c1171714ebad70cd3d9b.zip
Create MRS data structures
Change-Id: Ib7298205cd7e9da2e3f2e08c32ce1bdb53dd21fd Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/27291 Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@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/27295 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs00.C211
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs01.C182
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs02.C182
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs03.C169
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs04.C177
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs05.C196
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs06.C146
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C125
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H579
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.C24
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.H39
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load_ddr4.C850
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load_ddr4.H163
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/swizzle.H2
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_draminit.xml24
15 files changed, 2031 insertions, 1038 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs00.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs00.C
index c1f3622e9..f41505858 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs00.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs00.C
@@ -22,3 +22,214 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mrs00.C
+/// @brief Run and manage the DDR4 MRS00 loading
+///
+// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+
+#include <mss.H>
+#include <lib/dimm/ddr4/mrs_load_ddr4.H>
+
+using fapi2::TARGET_TYPE_MCBIST;
+using fapi2::TARGET_TYPE_DIMM;
+
+using fapi2::FAPI2_RC_SUCCESS;
+
+namespace mss
+{
+
+namespace ddr4
+{
+
+///
+/// @brief mrs0_data ctor
+/// @param[in] a fapi2::TARGET_TYPE_DIMM target
+/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+mrs00_data::mrs00_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ):
+ iv_burst_length(0),
+ iv_read_burst_type(0),
+ iv_dll_reset(0),
+ iv_test_mode(0),
+ iv_write_recovery(0),
+ iv_cas_latency(0)
+{
+ FAPI_TRY( mss::eff_dram_bl(i_target, iv_burst_length) );
+ FAPI_TRY( mss::eff_dram_rbt(i_target, iv_read_burst_type) );
+ FAPI_TRY( mss::eff_dram_cl(i_target, iv_cas_latency) );
+ FAPI_TRY( mss::eff_dram_dll_reset(i_target, iv_dll_reset) );
+ FAPI_TRY( mss::eff_dram_tm(i_target, iv_test_mode) );
+ FAPI_TRY( mss::eff_dram_twr(i_target, iv_write_recovery) );
+
+ FAPI_INF("MR0 Attributes: BL: 0x%x, RBT: 0x%x, CL: 0x%x, TM: 0x%x, DLL_RESET: 0x%x, WR: 0x%x",
+ iv_burst_length, iv_read_burst_type, iv_cas_latency, iv_test_mode, iv_dll_reset, iv_write_recovery);
+
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+ return;
+
+fapi_try_exit:
+ o_rc = fapi2::current_err;
+ FAPI_ERR("unable to get attributes for mrs0");
+ return;
+}
+
+///
+/// @brief Configure the ARR0 of the CCS instruction for mrs00
+/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank the rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs00(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank)
+{
+ // Check to make sure our ctor worked ok
+ mrs00_data l_data( i_target, fapi2::current_err );
+ FAPI_TRY( fapi2::current_err, "Unable to construct MRS00 data from attributes");
+ FAPI_TRY( mrs00(i_target, l_data, io_inst, i_rank) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Configure the ARR0 of the CCS instruction for mrs00, data object as input
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] i_data an mrs00_data object, filled in
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank the rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs00(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mrs00_data& i_data,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank)
+{
+ // Map from Write Recovery attribute value to bits in the MRS.
+ // Bit 4 is A13, bits 5:7 are A11:A9
+ constexpr uint64_t LOWEST_WR = 10;
+ constexpr uint64_t WR_COUNT = 17;
+ constexpr uint8_t wr_map[WR_COUNT] =
+ {
+ // 10 12 14 16 18 20 22 24 26
+ 0b0000, 0, 0b0001, 0, 0b0001, 0, 0b0011, 0, 0b0100, 0, 0b0101, 0, 0b0111, 0, 0b0110, 0, 0b1000
+ };
+
+ // Map from the CAS Latency attribute to the bits in the MRS
+ constexpr uint64_t LOWEST_CL = 9;
+ constexpr uint64_t CL_COUNT = 25;
+ constexpr uint8_t cl_map[CL_COUNT] =
+ {
+ // 9 10 11 12 13 14 15 16
+ 0b00000, 0b00001, 0b00010, 0b00011, 0b00100, 0b00101, 0b00110, 0b00111,
+ // 17, 18 19 20 21 22 23 24
+ 0b01101, 0b01000, 0b01110, 0b01001, 0b01111, 0b01010, 0b01100, 0b01011,
+ // 25 26 27 28 29 30 31 32 33
+ 0b10000, 0b10001, 0b10010, 0b10011, 0b10100, 0b10101, 0b10110, 0b10111, 0b11000
+ };
+
+ fapi2::buffer<uint8_t> l_cl;
+ fapi2::buffer<uint8_t> l_wr;
+
+ FAPI_ASSERT((i_data.iv_write_recovery >= LOWEST_WR) && (i_data.iv_write_recovery < (LOWEST_WR + WR_COUNT)),
+ fapi2::MSS_BAD_MR_PARAMETER()
+ .set_MR_NUMBER(0)
+ .set_PARAMETER(WRITE_RECOVERY)
+ .set_PARAMETER_VALUE(i_data.iv_write_recovery)
+ .set_DIMM_IN_ERROR(i_target),
+ "Bad value for Write Recovery: %d (%s)", i_data.iv_write_recovery, mss::c_str(i_target));
+
+ FAPI_ASSERT((i_data.iv_cas_latency >= LOWEST_CL) && (i_data.iv_cas_latency < (LOWEST_CL + CL_COUNT)),
+ fapi2::MSS_BAD_MR_PARAMETER()
+ .set_MR_NUMBER(0)
+ .set_PARAMETER(CAS_LATENCY)
+ .set_PARAMETER_VALUE(i_data.iv_cas_latency)
+ .set_DIMM_IN_ERROR(i_target),
+ "Bad value for CAS Latency: %d (%s)", i_data.iv_cas_latency, mss::c_str(i_target));
+
+ io_inst.arr0.insertFromRight<A0, 2>(i_data.iv_burst_length);
+ io_inst.arr0.writeBit<A3>(i_data.iv_read_burst_type);
+ io_inst.arr0.writeBit<A7>(i_data.iv_test_mode);
+ io_inst.arr0.writeBit<A8>(i_data.iv_dll_reset);
+
+ // CAS Latency takes a little effort - the bits aren't contiguous
+ l_cl = cl_map[i_data.iv_cas_latency - LOWEST_CL];
+ io_inst.arr0.writeBit<A12>(l_cl.getBit<3>());
+ io_inst.arr0.writeBit<A6>(l_cl.getBit<4>());
+ io_inst.arr0.writeBit<A5>(l_cl.getBit<5>());
+ io_inst.arr0.writeBit<A4>(l_cl.getBit<6>());
+ io_inst.arr0.writeBit<A2>(l_cl.getBit<7>());
+
+ // Write Recovery/Read to Precharge is not contiguous either.
+ l_wr = wr_map[i_data.iv_write_recovery - LOWEST_WR];
+ io_inst.arr0.writeBit<A13>(l_wr.getBit<4>());
+ io_inst.arr0.writeBit<A11>(l_wr.getBit<5>());
+ io_inst.arr0.writeBit<A10>(l_wr.getBit<6>());
+ io_inst.arr0.writeBit<A9>(l_wr.getBit<7>());
+
+ FAPI_INF("MR0: 0x%016llx", uint64_t(io_inst.arr0));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Given a CCS instruction which contains address bits with an encoded MRS0,
+/// decode and trace the contents
+/// @param[in] i_inst the CCS instruction
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode mrs00_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+ const uint64_t i_rank)
+{
+ static const uint8_t wr_map[9] = { 10, 12, 14, 16, 18, 20, 24, 22, 26 };
+
+ uint8_t l_burst_length = 0;
+ uint8_t l_read_burst_type = 0;
+ uint8_t l_dll_reset = 0;
+ uint8_t l_test_mode = 0;
+
+ fapi2::buffer<uint8_t> l_wr_index;
+ fapi2::buffer<uint8_t> l_cas_latency;
+
+ i_inst.arr0.extractToRight<A0, 2>(l_burst_length);
+ l_read_burst_type = i_inst.arr0.getBit<A3>();
+ l_test_mode = i_inst.arr0.getBit<A7>();
+ l_dll_reset = i_inst.arr0.getBit<A8>();
+
+ // CAS Latency takes a little effort - the bits aren't contiguous
+ l_cas_latency.writeBit<3>(i_inst.arr0.getBit<A12>());
+ l_cas_latency.writeBit<4>(i_inst.arr0.getBit<A6>());
+ l_cas_latency.writeBit<5>(i_inst.arr0.getBit<A5>());
+ l_cas_latency.writeBit<6>(i_inst.arr0.getBit<A4>());
+ l_cas_latency.writeBit<7>(i_inst.arr0.getBit<A2>());
+
+ // Write Recovery/Read to Precharge is not contiguous either.
+ l_wr_index.writeBit<4>(i_inst.arr0.getBit<A13>());
+ l_wr_index.writeBit<5>(i_inst.arr0.getBit<A11>());
+ l_wr_index.writeBit<6>(i_inst.arr0.getBit<A10>());
+ l_wr_index.writeBit<7>(i_inst.arr0.getBit<A9>());
+
+ FAPI_INF("MR0 Decode BL: 0x%x, RBT: 0x%x, CL: 0x%x, TM: 0x%x, DLL_RESET: 0x%x, WR: (0x%x)0x%x",
+ l_burst_length, l_read_burst_type, uint8_t(l_cas_latency), l_test_mode, l_dll_reset,
+ wr_map[uint8_t(l_wr_index)], uint8_t(l_wr_index));
+
+ return FAPI2_RC_SUCCESS;
+}
+
+} // ns ddr4
+
+} // ns mss
+
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs01.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs01.C
index 5f83649f1..8e58fddb7 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs01.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs01.C
@@ -22,3 +22,185 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mrs01.C
+/// @brief Run and manage the DDR4 MRS01 loading
+///
+// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+
+#include <mss.H>
+#include <lib/dimm/ddr4/mrs_load_ddr4.H>
+
+using fapi2::TARGET_TYPE_MCBIST;
+using fapi2::TARGET_TYPE_DIMM;
+
+using fapi2::FAPI2_RC_SUCCESS;
+
+namespace mss
+{
+
+namespace ddr4
+{
+
+///
+/// @brief mrs01_data ctor
+/// @param[in] a fapi2::TARGET_TYPE_DIMM target
+/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+mrs01_data::mrs01_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ):
+ iv_dll_enable(0),
+ iv_odic(0),
+ iv_additive_latency(0),
+ iv_wl_enable(0),
+ iv_tdqs(0),
+ iv_qoff(0)
+{
+ FAPI_TRY( mss::eff_dram_dll_enable(i_target, iv_dll_enable) );
+ FAPI_TRY( mss::eff_dram_ron(i_target, iv_odic) );
+ FAPI_TRY( mss::eff_dram_al(i_target, iv_additive_latency) );
+ FAPI_TRY( mss::eff_dram_wr_lvl_enable(i_target, iv_wl_enable) );
+ FAPI_TRY( mss::eff_dram_rtt_nom(i_target, &(iv_rtt_nom[0])) );
+ FAPI_TRY( mss::eff_dram_tdqs(i_target, iv_tdqs) );
+ FAPI_TRY( mss::eff_dram_output_buffer(i_target, iv_qoff) );
+
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+ return;
+
+fapi_try_exit:
+ o_rc = fapi2::current_err;
+ FAPI_ERR("unable to get attributes for mrs0");
+ return;
+}
+
+///
+/// @brief Configure the ARR0 of the CCS instruction for mrs01
+/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank the rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs01(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank)
+{
+ // Check to make sure our ctor worked ok
+ mrs01_data l_data( i_target, fapi2::current_err );
+ FAPI_TRY( fapi2::current_err, "Unable to construct MRS01 data from attributes");
+ FAPI_TRY( mrs01(i_target, l_data, io_inst, i_rank) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Configure the ARR0 of the CCS instruction for mrs01, data object as input
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] i_data an mrs01_data object, filled in
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank the rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs01(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mrs01_data& i_data,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank)
+{
+ // Little table to map Output Driver Imepdance Control. 34Ohm is index 0,
+ // 48Ohm is index 1
+ // Left bit is A2, right bit is A1
+ constexpr uint8_t odic_map[2] = { 0b00, 0b01 };
+
+ // Indexed by denominator. So, if RQZ is 240, and you have OHM240, then you're looking
+ // for index 1. So this doesn't correspond directly with the table in the JEDEC spec,
+ // as that's not in "denominator order."
+ // 0 RQZ/1 RQZ/2 RQZ/3 RQZ/4 RQZ/5 RQZ/6 RQZ/7
+ constexpr uint8_t rtt_nom_map[8] = { 0, 0b100, 0b010, 0b110, 0b001, 0b101, 0b011, 0b111 };
+
+ size_t l_rtt_nom_index = 0;
+
+ fapi2::buffer<uint8_t> l_additive_latency;
+ fapi2::buffer<uint8_t> l_odic_buffer;
+ fapi2::buffer<uint8_t> l_rtt_nom_buffer;
+
+ FAPI_ASSERT( ((i_data.iv_odic == fapi2::ENUM_ATTR_EFF_DRAM_RON_OHM34) ||
+ (i_data.iv_odic == fapi2::ENUM_ATTR_EFF_DRAM_RON_OHM48)),
+ fapi2::MSS_BAD_MR_PARAMETER()
+ .set_MR_NUMBER(1)
+ .set_PARAMETER(OUTPUT_IMPEDANCE)
+ .set_PARAMETER_VALUE(i_data.iv_odic)
+ .set_DIMM_IN_ERROR(i_target),
+ "Bad value for output driver impedance: %d (%s)", i_data.iv_odic, mss::c_str(i_target));
+
+ // Map from impedance to bits in MRS1
+ l_odic_buffer = (i_data.iv_odic == fapi2::ENUM_ATTR_EFF_DRAM_RON_OHM34) ? odic_map[0] : odic_map[1];
+
+ // We have to be careful about 0
+ l_rtt_nom_index = (i_data.iv_rtt_nom[mss::index(i_rank)] == 0) ?
+ 0 : fapi2::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM240 / i_data.iv_rtt_nom[mss::index(i_rank)];
+
+ // Map from RTT_NOM array to the value in the map
+ l_rtt_nom_buffer = rtt_nom_map[l_rtt_nom_index];
+
+ // Print this here as opposed to the MRS01 ctor as we want to see the specific rtt now information
+ FAPI_INF("MR1 rank %d attributes: DLL_ENABLE: 0x%x, ODIC: 0x%x(0x%x), AL: 0x%x, WLE: 0x%x, "
+ "RTT_NOM: 0x%x(0x%x), TDQS: 0x%x, QOFF: 0x%x", i_rank,
+ i_data.iv_dll_enable, i_data.iv_odic, uint8_t(l_odic_buffer), uint8_t(l_additive_latency), i_data.iv_wl_enable,
+ i_data.iv_rtt_nom[mss::index(i_rank)], uint8_t(l_rtt_nom_buffer), i_data.iv_tdqs, i_data.iv_qoff);
+
+ io_inst.arr0.writeBit<A0>(i_data.iv_dll_enable);
+ mss::swizzle<A1, 2, 7>(l_odic_buffer, io_inst.arr0);
+ mss::swizzle<A3, 2, 7>(fapi2::buffer<uint8_t>(i_data.iv_additive_latency), io_inst.arr0);
+ io_inst.arr0.writeBit<A7>(i_data.iv_wl_enable);
+ mss::swizzle<A8, 3, 7>(l_rtt_nom_buffer, io_inst.arr0);
+ io_inst.arr0.writeBit<A11>(i_data.iv_tdqs);
+ io_inst.arr0.writeBit<A12>(i_data.iv_qoff);
+
+ FAPI_INF("MR1: 0x%016llx", uint64_t(io_inst.arr0));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Given a CCS instruction which contains address bits with an encoded MRS1,
+/// decode and trace the contents
+/// @param[in] i_inst the CCS instruction
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode mrs01_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+ const uint64_t i_rank)
+{
+ fapi2::buffer<uint8_t> l_odic;
+ fapi2::buffer<uint8_t> l_additive_latency;
+ fapi2::buffer<uint8_t> l_rtt_nom;
+
+ uint8_t l_dll_enable = i_inst.arr0.getBit<A0>();
+ uint8_t l_wrl_enable = i_inst.arr0.getBit<A7>();
+ uint8_t l_tdqs = i_inst.arr0.getBit<A11>();
+ uint8_t l_qoff = i_inst.arr0.getBit<A12>();
+
+ mss::swizzle<6, 2, A2>(i_inst.arr0, l_odic);
+ mss::swizzle<6, 2, A4>(i_inst.arr0, l_additive_latency);
+ mss::swizzle<5, 3, A10>(i_inst.arr0, l_rtt_nom);
+
+ FAPI_INF("MR1 rank %d decode: DLL_ENABLE: 0x%x, ODIC: 0x%x, AL: 0x%x, WLE: 0x%x, "
+ "RTT_NOM: 0x%x, TDQS: 0x%x, QOFF: 0x%x", i_rank,
+ l_dll_enable, uint8_t(l_odic), uint8_t(l_additive_latency), l_wrl_enable, uint8_t(l_rtt_nom),
+ l_tdqs, l_qoff);
+
+ return FAPI2_RC_SUCCESS;
+}
+
+} // ns ddr4
+
+} // ns mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs02.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs02.C
index fafcd9780..1d6ecbf44 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs02.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs02.C
@@ -22,3 +22,185 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mrs02.C
+/// @brief Run and manage the DDR4 MRS02 loading
+///
+// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+
+#include <mss.H>
+#include <lib/dimm/ddr4/mrs_load_ddr4.H>
+
+using fapi2::TARGET_TYPE_MCBIST;
+using fapi2::TARGET_TYPE_DIMM;
+
+using fapi2::FAPI2_RC_SUCCESS;
+
+namespace mss
+{
+
+namespace ddr4
+{
+
+///
+/// @brief mrs02_data ctor
+/// @param[in] a fapi2::TARGET_TYPE_DIMM target
+/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+mrs02_data::mrs02_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ):
+ iv_lpasr(0),
+ iv_cwl(0),
+ iv_write_crc(0)
+{
+ FAPI_TRY( mss::eff_dram_lpasr(i_target, iv_lpasr) );
+ FAPI_TRY( mss::eff_dram_cwl(i_target, iv_cwl) );
+ FAPI_TRY( mss::eff_dram_rtt_wr(i_target, &(iv_dram_rtt_wr[0])) );
+ FAPI_TRY( mss::eff_write_crc(i_target, iv_write_crc) );
+
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+ return;
+
+fapi_try_exit:
+ o_rc = fapi2::current_err;
+ FAPI_ERR("unable to get attributes for mrs0");
+ return;
+}
+
+///
+/// @brief Configure the ARR0 of the CCS instruction for mrs02
+/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank the rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs02(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank)
+{
+ // Check to make sure our ctor worked ok
+ mrs02_data l_data( i_target, fapi2::current_err );
+ FAPI_TRY( fapi2::current_err, "Unable to construct MRS02 data from attributes");
+ FAPI_TRY( mrs02(i_target, l_data, io_inst, i_rank) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Configure the ARR0 of the CCS instruction for mrs02, data object as input
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] i_data an mrs02_data object, filled in
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank the rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs02(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mrs02_data& i_data,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank)
+{
+ // Index this by subtracting 9 from the CWL attribute value. The table maps CWL attribute value
+ // (in clks) to the bit setting in MR2. See the table in the JEDEC spec for the mapping.
+ constexpr uint64_t LOWEST_CWL = 9;
+ constexpr uint64_t CWL_COUNT = 12;
+ // 9 10 11 12 14 16 18 20
+ constexpr uint8_t cwl_map[CWL_COUNT] = { 0b000, 0b001, 0b010, 0b011, 0, 0b100, 0, 0b101, 0, 0b110, 0, 0b111 };
+
+ fapi2::buffer<uint8_t> l_cwl_buffer;
+ fapi2::buffer<uint8_t> l_rtt_wr_buffer;
+
+ FAPI_ASSERT((i_data.iv_cwl >= LOWEST_CWL) && (i_data.iv_cwl < (LOWEST_CWL + CWL_COUNT)),
+ fapi2::MSS_BAD_MR_PARAMETER()
+ .set_MR_NUMBER(0)
+ .set_PARAMETER(CAS_WRITE_LATENCY)
+ .set_PARAMETER_VALUE(i_data.iv_cwl)
+ .set_DIMM_IN_ERROR(i_target),
+ "Bad value for CWL: %d (%s)", i_data.iv_cwl, mss::c_str(i_target));
+
+ l_cwl_buffer = cwl_map[i_data.iv_cwl - LOWEST_CWL];
+
+ switch (i_data.iv_dram_rtt_wr[i_rank])
+ {
+ case fapi2::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE:
+ l_rtt_wr_buffer = 0b000;
+ break;
+
+ case fapi2::ENUM_ATTR_EFF_DRAM_RTT_WR_HIGHZ:
+ l_rtt_wr_buffer = 0b011;
+ break;
+
+ case fapi2::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM240:
+ l_rtt_wr_buffer = 0b010;
+ break;
+
+ case fapi2::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120:
+ l_rtt_wr_buffer = 0b001;
+ break;
+
+ case fapi2::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM60:
+ l_rtt_wr_buffer = 0b100;
+ break;
+
+ default:
+ FAPI_ERR("unknown RTT_WR 0x%x (%s rank %d), dynamic odt off",
+ i_data.iv_dram_rtt_wr[i_rank], mss::c_str(i_target), i_rank);
+ l_rtt_wr_buffer = 0b000;
+ break;
+ };
+
+ // Printed here as opposed to the ctor as it uses the rank information
+ FAPI_INF("MR2 rank %d attributes: LPASR: 0x%x, CWL: 0x%x(0x%x), RTT_WR: 0x%x(0x%x), WRITE_CRC: 0x%x", i_rank,
+ uint8_t(i_data.iv_lpasr), i_data.iv_cwl, uint8_t(l_cwl_buffer),
+ i_data.iv_dram_rtt_wr[i_rank], uint8_t(l_rtt_wr_buffer), i_data.iv_write_crc);
+
+ mss::swizzle<A3, 3, 7>(l_cwl_buffer, io_inst.arr0);
+
+ mss::swizzle<A6, 2, 7>(fapi2::buffer<uint8_t>(i_data.iv_lpasr), io_inst.arr0);
+
+ mss::swizzle<A9, 3, 7>(l_rtt_wr_buffer, io_inst.arr0);
+
+ io_inst.arr0.writeBit<A12>(i_data.iv_write_crc);
+
+ FAPI_INF("MR2: 0x%016llx", uint64_t(io_inst.arr0));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Given a CCS instruction which contains address bits with an encoded MRS2,
+/// decode and trace the contents
+/// @param[in] i_inst the CCS instruction
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode mrs02_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+ const uint64_t i_rank)
+{
+ fapi2::buffer<uint8_t> l_lpasr;
+ fapi2::buffer<uint8_t> l_cwl;
+ fapi2::buffer<uint8_t> l_rtt_wr;
+
+ uint8_t l_write_crc = i_inst.arr0.getBit<A12>();
+ mss::swizzle<5, 3, A5>(i_inst.arr0, l_cwl);
+ mss::swizzle<6, 2, A7>(i_inst.arr0, l_lpasr);
+ mss::swizzle<5, 3, A11>(i_inst.arr0, l_rtt_wr);
+
+ FAPI_INF("MR2 rank %d deocode: LPASR: 0x%x, CWL: 0x%x, RTT_WR: 0x%x, WRITE_CRC: 0x%x", i_rank,
+ uint8_t(l_lpasr), uint8_t(l_cwl), uint8_t(l_rtt_wr), l_write_crc);
+
+ return FAPI2_RC_SUCCESS;
+}
+
+} // ns ddr4
+
+} // ns mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs03.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs03.C
index 52bf96fb3..31a1e323a 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs03.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs03.C
@@ -22,3 +22,172 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mrs03.C
+/// @brief Run and manage the DDR4 DDR4 loading
+///
+// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+
+#include <mss.H>
+#include <lib/dimm/ddr4/mrs_load_ddr4.H>
+
+using fapi2::TARGET_TYPE_MCBIST;
+using fapi2::TARGET_TYPE_DIMM;
+
+using fapi2::FAPI2_RC_SUCCESS;
+
+namespace mss
+{
+
+namespace ddr4
+{
+
+///
+/// @brief mrs03_data ctor
+/// @param[in] a fapi2::TARGET_TYPE_DIMM target
+/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+mrs03_data::mrs03_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ):
+ iv_mpr_mode(0),
+ iv_mpr_page(0),
+ iv_geardown(0),
+ iv_pda(0),
+ iv_crc_wr_latency(0),
+ iv_temp_readout(0),
+ iv_fine_refresh(0),
+ iv_read_format(0)
+{
+ FAPI_TRY( mss::eff_mpr_mode(i_target, iv_mpr_mode) );
+ FAPI_TRY( mss::eff_mpr_page(i_target, iv_mpr_page) );
+ FAPI_TRY( mss::eff_geardown_mode(i_target, iv_geardown) );
+ FAPI_TRY( mss::eff_per_dram_access(i_target, iv_pda) );
+ FAPI_TRY( mss::eff_temp_readout(i_target, iv_temp_readout) );
+ FAPI_TRY( mss::mrw_fine_refresh_mode(iv_fine_refresh) );
+ FAPI_TRY( mss::eff_crc_wr_latency(i_target, iv_crc_wr_latency) );
+ FAPI_TRY( mss::eff_mpr_rd_format(i_target, iv_read_format) );
+
+ FAPI_INF("MR3 attributes: MPR_MODE: 0x%x, MPR_PAGE: 0x%x, GD: 0x%x, PDA: 0x%x, "
+ "TEMP: 0x%x FR: 0x%x, CRC_WL: 0x%x, RF: 0x%x",
+ iv_mpr_mode, iv_mpr_page, iv_geardown, iv_pda, iv_temp_readout,
+ iv_fine_refresh, iv_crc_wr_latency, iv_read_format);
+
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+ return;
+
+fapi_try_exit:
+ o_rc = fapi2::current_err;
+ FAPI_ERR("unable to get attributes for mrs0");
+ return;
+}
+
+///
+/// @brief Configure the ARR0 of the CCS instruction for mrs03
+/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank the rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs03(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank)
+{
+ // Check to make sure our ctor worked ok
+ mrs03_data l_data( i_target, fapi2::current_err );
+ FAPI_TRY( fapi2::current_err, "Unable to construct MRS03 data from attributes");
+ FAPI_TRY( mrs03(i_target, l_data, io_inst, i_rank) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Configure the ARR0 of the CCS instruction for mrs03, data object as input
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] i_data an mrs00_data object, filled in
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank the rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs03(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mrs03_data& i_data,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank)
+{
+ constexpr uint64_t LOWEST_WL = 4;
+ constexpr uint64_t WL_COUNT = 3;
+ // 4 5 6
+ constexpr uint8_t crc_wr_latency_map[WL_COUNT] = { 1, 2, 3 };
+
+ fapi2::buffer<uint8_t> l_crc_wr_latency_buffer;
+
+ FAPI_ASSERT((i_data.iv_crc_wr_latency >= LOWEST_WL) && (i_data.iv_crc_wr_latency < (LOWEST_WL + WL_COUNT)),
+ fapi2::MSS_BAD_MR_PARAMETER()
+ .set_MR_NUMBER(3)
+ .set_PARAMETER(WRITE_CMD_LATENCY)
+ .set_PARAMETER_VALUE(i_data.iv_crc_wr_latency)
+ .set_DIMM_IN_ERROR(i_target),
+ "Bad value for Write CMD Latency: %d (%s)", i_data.iv_crc_wr_latency, mss::c_str(i_target));
+
+ l_crc_wr_latency_buffer = crc_wr_latency_map[i_data.iv_crc_wr_latency - LOWEST_WL];
+
+ mss::swizzle<A0, 2, 7>(fapi2::buffer<uint8_t>(i_data.iv_mpr_mode), io_inst.arr0);
+ io_inst.arr0.writeBit<A2>(i_data.iv_mpr_page);
+ io_inst.arr0.writeBit<A3>(i_data.iv_geardown);
+ io_inst.arr0.writeBit<A4>(i_data.iv_pda);
+ io_inst.arr0.writeBit<A5>(i_data.iv_temp_readout);
+
+ mss::swizzle<A6 , 3, 7>(fapi2::buffer<uint8_t>(i_data.iv_fine_refresh), io_inst.arr0);
+ mss::swizzle<A9 , 2, 7>(l_crc_wr_latency_buffer, io_inst.arr0);
+ mss::swizzle<A11, 2, 7>(fapi2::buffer<uint8_t>(i_data.iv_read_format), io_inst.arr0);
+
+ FAPI_INF("MR3: 0x%016llx", uint64_t(io_inst.arr0));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Given a CCS instruction which contains address bits with an encoded MRS3,
+/// decode and trace the contents
+/// @param[in] i_inst the CCS instruction
+/// @param[in] i_rank ths rank in question
+/// @return void
+///
+fapi2::ReturnCode mrs03_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+ const uint64_t i_rank)
+{
+ fapi2::buffer<uint8_t> l_mpr_mode;
+
+ fapi2::buffer<uint8_t> l_fine_refresh;
+ fapi2::buffer<uint8_t> l_crc_wr_latency_buffer;
+ fapi2::buffer<uint8_t> l_read_format;
+
+ uint8_t l_mpr_page = i_inst.arr0.getBit<A2>();
+ uint8_t l_geardown = i_inst.arr0.getBit<A3>();
+ uint8_t l_pda = i_inst.arr0.getBit<A4>();
+ uint8_t l_temp_readout = i_inst.arr0.getBit<A5>();
+
+ mss::swizzle<6, 2, A1>(i_inst.arr0, l_mpr_mode);
+ mss::swizzle<5, 3, A7>(i_inst.arr0, l_fine_refresh);
+ mss::swizzle<6, 2, A10>(i_inst.arr0, l_crc_wr_latency_buffer);
+ mss::swizzle<6, 2, A12>(i_inst.arr0, l_read_format);
+
+ FAPI_INF("MR3 rank %d decode: MPR_MODE: 0x%x, MPR_PAGE: 0x%x, GD: 0x%x, PDA: 0x%x, "
+ "TEMP: 0x%x FR: 0x%x, CRC_WL: 0x%x, RF: 0x%x", i_rank,
+ uint8_t(l_mpr_mode), l_mpr_page, l_geardown, l_pda, uint8_t(l_temp_readout),
+ uint8_t(l_fine_refresh), uint8_t(l_crc_wr_latency_buffer), uint8_t(l_read_format));
+
+ return FAPI2_RC_SUCCESS;
+}
+
+} // ns ddr4
+} // ns mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs04.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs04.C
index da3efde0b..aeb0b8c9e 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs04.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs04.C
@@ -22,3 +22,180 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mrs04.C
+/// @brief Run and manage the DDR4 MRS04 loading
+///
+// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+
+#include <mss.H>
+#include <lib/dimm/ddr4/mrs_load_ddr4.H>
+
+using fapi2::TARGET_TYPE_MCBIST;
+using fapi2::TARGET_TYPE_DIMM;
+
+using fapi2::FAPI2_RC_SUCCESS;
+
+namespace mss
+{
+
+namespace ddr4
+{
+
+///
+/// @brief mrs04_data ctor
+/// @param[in] a fapi2::TARGET_TYPE_DIMM target
+/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+mrs04_data::mrs04_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ):
+ iv_max_pd_mode(0),
+ iv_temp_refresh_range(0),
+ iv_temp_ref_mode(0),
+ iv_vref_mon(0),
+ iv_cs_cmd_latency(0),
+ iv_ref_abort(0),
+ iv_rd_pre_train_mode(0),
+ iv_rd_preamble(0),
+ iv_wr_preamble(0),
+ iv_ppr(0)
+{
+ FAPI_TRY( mss::eff_max_powerdown_mode(i_target, iv_max_pd_mode) );
+ FAPI_TRY( mss::mrw_temp_refresh_range(iv_temp_refresh_range) );
+ FAPI_TRY( mss::eff_temp_refresh_mode(i_target, iv_temp_ref_mode) );
+ FAPI_TRY( mss::eff_internal_vref_monitor(i_target, iv_vref_mon) );
+ FAPI_TRY( mss::eff_cs_cmd_latency(i_target, iv_cs_cmd_latency) );
+ FAPI_TRY( mss::eff_self_ref_abort(i_target, iv_ref_abort) );
+ FAPI_TRY( mss::eff_rd_preamble_train(i_target, iv_rd_pre_train_mode) );
+ FAPI_TRY( mss::eff_rd_preamble(i_target, iv_rd_preamble) );
+ FAPI_TRY( mss::eff_wr_preamble(i_target, iv_wr_preamble) );
+ FAPI_TRY( mss::eff_dram_ppr(i_target, iv_ppr) );
+
+ FAPI_INF("MR4 attributes: MAX_PD: 0x%x, TEMP_REFRESH_RANGE: 0x%x, TEMP_REF_MODE: 0x%x "
+ "VREF_MON: 0x%x, CSL: 0x%x, REF_ABORT: 0x%x, RD_PTM: 0x%x, RD_PRE: 0x%x, "
+ "WR_PRE: 0x%x, PPR: 0x%x",
+ iv_max_pd_mode, iv_temp_refresh_range, iv_temp_ref_mode, iv_vref_mon,
+ iv_cs_cmd_latency, iv_ref_abort,
+ iv_rd_pre_train_mode, iv_rd_preamble, iv_wr_preamble, iv_ppr);
+
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+ return;
+
+fapi_try_exit:
+ o_rc = fapi2::current_err;
+ FAPI_ERR("unable to get attributes for mrs0");
+ return;
+}
+
+///
+/// @brief Configure the ARR0 of the CCS instruction for mrs04
+/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank thes rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs04(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank)
+{
+ // Check to make sure our ctor worked ok
+ mrs04_data l_data( i_target, fapi2::current_err );
+ FAPI_TRY( fapi2::current_err, "Unable to construct MRS04 data from attributes");
+ FAPI_TRY( mrs04(i_target, l_data, io_inst, i_rank) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Configure the ARR0 of the CCS instruction for mrs04, data object as input
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] i_data an mrs04_data object, filled in
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank the rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs04(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mrs04_data& i_data,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank)
+{
+ constexpr uint64_t CS_CMD_COUNT = 9;
+ // 0 3 4 5 6 8
+ constexpr uint8_t cs_cmd_latency_map[CS_CMD_COUNT] = { 0b000, 0, 0, 0b001, 0b010, 0b011, 0b100, 0, 0b101 };
+
+ fapi2::buffer<uint8_t> l_cs_cmd_latency_buffer;
+
+ FAPI_ASSERT( (i_data.iv_cs_cmd_latency < CS_CMD_COUNT),
+ fapi2::MSS_BAD_MR_PARAMETER()
+ .set_MR_NUMBER(4)
+ .set_PARAMETER(CS_CMD_LATENCY)
+ .set_PARAMETER_VALUE(i_data.iv_cs_cmd_latency)
+ .set_DIMM_IN_ERROR(i_target),
+ "Bad value for CS to CMD/ADDR Latency: %d (%s)", i_data.iv_cs_cmd_latency, mss::c_str(i_target));
+
+ l_cs_cmd_latency_buffer = cs_cmd_latency_map[i_data.iv_cs_cmd_latency];
+
+ io_inst.arr0.writeBit<A1>(i_data.iv_max_pd_mode);
+ io_inst.arr0.writeBit<A2>(i_data.iv_temp_refresh_range);
+ io_inst.arr0.writeBit<A3>(i_data.iv_temp_ref_mode);
+ io_inst.arr0.writeBit<A4>(i_data.iv_vref_mon);
+
+ mss::swizzle<A6, 3, 7>(l_cs_cmd_latency_buffer, io_inst.arr0);
+ io_inst.arr0.writeBit<A9>(i_data.iv_ref_abort);
+ io_inst.arr0.writeBit<A10>(i_data.iv_rd_pre_train_mode);
+ io_inst.arr0.writeBit<A11>(i_data.iv_rd_preamble);
+ io_inst.arr0.writeBit<A12>(i_data.iv_wr_preamble);
+ io_inst.arr0.writeBit<A13>(i_data.iv_ppr);
+
+ FAPI_INF("MR4: 0x%016llx", uint64_t(io_inst.arr0));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Given a CCS instruction which contains address bits with an encoded MRS4,
+/// decode and trace the contents
+/// @param[in] i_inst the CCS instruction
+/// @param[in] i_rank ths rank in question
+/// @return void
+///
+fapi2::ReturnCode mrs04_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+ const uint64_t i_rank)
+{
+ uint8_t l_max_pd_mode = i_inst.arr0.getBit<A1>();
+ uint8_t l_temp_refresh_range = i_inst.arr0.getBit<A2>();
+ uint8_t l_temp_ref_mode = i_inst.arr0.getBit<A3>();
+ uint8_t l_vref_mon = i_inst.arr0.getBit<A4>();
+
+ fapi2::buffer<uint8_t> l_cs_cmd_latency_buffer;
+ mss::swizzle<5, 3, A8>(i_inst.arr0, l_cs_cmd_latency_buffer);
+
+ uint8_t l_ref_abort = i_inst.arr0.getBit<A9>();
+ uint8_t l_rd_pre_train_mode = i_inst.arr0.getBit<A10>();
+ uint8_t l_rd_preamble = i_inst.arr0.getBit<A11>();
+ uint8_t l_wr_preamble = i_inst.arr0.getBit<A12>();
+ uint8_t l_ppr = i_inst.arr0.getBit<A13>();
+
+ FAPI_INF("MR4 rank %d decode: MAX_PD: 0x%x, TEMP_REFRESH_RANGE: 0x%x, TEMP_REF_MODE: 0x%x "
+ "VREF_MON: 0x%x, CSL: 0x%x, REF_ABORT: 0x%x, RD_PTM: 0x%x, RD_PRE: 0x%x, "
+ "WR_PRE: 0x%x, PPR: 0x%x", i_rank,
+ l_max_pd_mode, l_temp_refresh_range, l_temp_ref_mode, l_vref_mon,
+ uint8_t(l_cs_cmd_latency_buffer), l_ref_abort,
+ l_rd_pre_train_mode, l_rd_preamble, l_wr_preamble, l_ppr);
+
+ return FAPI2_RC_SUCCESS;
+}
+
+
+} // ns ddr4
+} // ns mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs05.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs05.C
index 966e225fa..5f647d1c1 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs05.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs05.C
@@ -22,3 +22,199 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mrs05.C
+/// @brief Run and manage the DDR4 MRS05 loading
+///
+// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+
+#include <mss.H>
+#include <lib/dimm/ddr4/mrs_load_ddr4.H>
+
+using fapi2::TARGET_TYPE_MCBIST;
+using fapi2::TARGET_TYPE_DIMM;
+
+using fapi2::FAPI2_RC_SUCCESS;
+
+namespace mss
+{
+
+namespace ddr4
+{
+
+///
+/// @brief mrs05_data ctor
+/// @param[in] a fapi2::TARGET_TYPE_DIMM target
+/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+mrs05_data::mrs05_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ):
+ iv_ca_parity_latency(0),
+ iv_crc_error_clear(0),
+ iv_ca_parity_error_status(0),
+ iv_odt_input_buffer(0),
+ iv_ca_parity(0),
+ iv_data_mask(0),
+ iv_write_dbi(0),
+ iv_read_dbi(0)
+{
+ FAPI_TRY( mss::eff_ca_parity_latency(i_target, iv_ca_parity_latency) );
+ FAPI_TRY( mss::eff_crc_error_clear(i_target, iv_crc_error_clear) );
+ FAPI_TRY( mss::eff_ca_parity_error_status(i_target, iv_ca_parity_error_status) );
+ FAPI_TRY( mss::eff_odt_input_buff(i_target, iv_odt_input_buffer) );
+ FAPI_TRY( mss::eff_rtt_park(i_target, &(iv_rtt_park[0])) );
+ FAPI_TRY( mss::eff_ca_parity(i_target, iv_ca_parity) );
+ FAPI_TRY( mss::eff_data_mask(i_target, iv_data_mask) );
+ FAPI_TRY( mss::eff_write_dbi(i_target, iv_write_dbi) );
+ FAPI_TRY( mss::eff_read_dbi(i_target, iv_read_dbi) );
+
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+ return;
+
+fapi_try_exit:
+ o_rc = fapi2::current_err;
+ FAPI_ERR("unable to get attributes for mrs0");
+ return;
+}
+
+///
+/// @brief Configure the ARR0 of the CCS instruction for mrs05
+/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank the rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs05(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank)
+{
+ // Check to make sure our ctor worked ok
+ mrs05_data l_data( i_target, fapi2::current_err );
+ FAPI_TRY( fapi2::current_err, "Unable to construct MRS05 data from attributes");
+ FAPI_TRY( mrs05(i_target, l_data, io_inst, i_rank) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Configure the ARR0 of the CCS instruction for mrs05, data object as input
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] i_data an mrs05_data object, filled in
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank the rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs05(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mrs05_data& i_data,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank)
+{
+ constexpr uint64_t CA_PARITY_COUNT = 9;
+ // 0 4 5 6 8
+ constexpr uint8_t ca_parity_latency_map[CA_PARITY_COUNT] = { 0b000, 0, 0, 0, 0b001, 0b010, 0b011, 0, 0b100 };
+
+ // Indexed by denominator. So, if RQZ is 240, and you have OHM240, then you're looking
+ // for index 1. So this doesn't correspond directly with the table in the JEDEC spec,
+ // as that's not in "denominator order."
+ constexpr uint64_t RTT_PARK_COUNT = 8;
+ // 0 RQZ/1 RQZ/2 RQZ/3 RQZ/4 RQZ/5 RQZ/6 RQZ/7
+ constexpr uint8_t rtt_park_map[RTT_PARK_COUNT] = { 0, 0b100, 0b010, 0b110, 0b001, 0b101, 0b011, 0b111 };
+
+ uint8_t l_rtt_park_index = 0;
+
+ fapi2::buffer<uint8_t> l_ca_parity_latency_buffer;
+ fapi2::buffer<uint8_t> l_rtt_park_buffer;
+
+ FAPI_ASSERT( (i_data.iv_ca_parity_latency < CA_PARITY_COUNT),
+ fapi2::MSS_BAD_MR_PARAMETER()
+ .set_MR_NUMBER(5)
+ .set_PARAMETER(CA_PARITY_LATENCY)
+ .set_PARAMETER_VALUE(i_data.iv_ca_parity_latency)
+ .set_DIMM_IN_ERROR(i_target),
+ "Bad value for CA parity latency: %d (%s)", i_data.iv_ca_parity_latency, mss::c_str(i_target));
+
+ FAPI_ASSERT( (i_rank < RTT_PARK_COUNT),
+ fapi2::MSS_BAD_MR_PARAMETER()
+ .set_MR_NUMBER(5)
+ .set_PARAMETER(RTT_PARK)
+ .set_PARAMETER_VALUE(i_rank)
+ .set_DIMM_IN_ERROR(i_target),
+ "Bad value for RTT park: %d (%s)", i_rank, mss::c_str(i_target));
+
+ l_ca_parity_latency_buffer = ca_parity_latency_map[i_data.iv_ca_parity_latency];
+
+ // We have to be careful about 0
+ l_rtt_park_index = (i_data.iv_rtt_park[mss::index(i_rank)] == 0) ?
+ 0 : fapi2::ENUM_ATTR_EFF_RTT_PARK_240OHM / i_data.iv_rtt_park[mss::index(i_rank)];
+
+ // Map from RTT_NOM array to the value in the map
+ l_rtt_park_buffer = rtt_park_map[l_rtt_park_index];
+
+ FAPI_INF("MR5 rank %d attributes: CAPL: 0x%x(0x%x), CRC_EC: 0x%x, CA_PES: 0x%x, ODT_IB: 0x%x "
+ "RTT_PARK: 0x%x(0x%x), CAP: 0x%x, DM: 0x%x, WDBI: 0x%x, RDBI: 0x%x", i_rank,
+ i_data.iv_ca_parity_latency, uint8_t(l_ca_parity_latency_buffer), i_data.iv_crc_error_clear,
+ i_data.iv_ca_parity_error_status, i_data.iv_odt_input_buffer,
+ i_data.iv_rtt_park[mss::index(i_rank)], uint8_t(l_rtt_park_buffer), i_data.iv_ca_parity,
+ i_data.iv_data_mask, i_data.iv_write_dbi, i_data.iv_read_dbi);
+
+ mss::swizzle<A0, 3, 7>(l_ca_parity_latency_buffer, io_inst.arr0);
+ io_inst.arr0.writeBit<A3>(i_data.iv_crc_error_clear);
+ io_inst.arr0.writeBit<A4>(i_data.iv_ca_parity_error_status);
+ io_inst.arr0.writeBit<A5>(i_data.iv_odt_input_buffer);
+ mss::swizzle<A6, 3, 7>(l_rtt_park_buffer, io_inst.arr0);
+ io_inst.arr0.writeBit<A9>(i_data.iv_ca_parity);
+ io_inst.arr0.writeBit<A10>(i_data.iv_data_mask);
+ io_inst.arr0.writeBit<A11>(i_data.iv_write_dbi);
+ io_inst.arr0.writeBit<A12>(i_data.iv_read_dbi);
+
+ FAPI_INF("MR5: 0x%016llx", uint64_t(io_inst.arr0));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Given a CCS instruction which contains address bits with an encoded MRS5,
+/// decode and trace the contents
+/// @param[in] i_inst the CCS instruction
+/// @param[in] i_rank ths rank in question
+/// @return void
+///
+fapi2::ReturnCode mrs05_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+ const uint64_t i_rank)
+{
+ fapi2::buffer<uint8_t> l_ca_parity_latency_buffer;
+ fapi2::buffer<uint8_t> l_rtt_park_buffer;
+
+ mss::swizzle<5, 3, A2>(i_inst.arr0, l_ca_parity_latency_buffer);
+ mss::swizzle<5, 3, A8>(i_inst.arr0, l_rtt_park_buffer);
+
+ uint8_t l_crc_error_clear = i_inst.arr0.getBit<A3>();
+ uint8_t l_ca_parity_error_status = i_inst.arr0.getBit<A4>();
+ uint8_t l_odt_input_buffer = i_inst.arr0.getBit<A5>();
+
+ uint8_t l_ca_parity = i_inst.arr0.getBit<A9>();
+ uint8_t l_data_mask = i_inst.arr0.getBit<A10>();
+ uint8_t l_write_dbi = i_inst.arr0.getBit<A11>();
+ uint8_t l_read_dbi = i_inst.arr0.getBit<A12>();
+
+ FAPI_INF("MR5 rank %d decode: CAPL: 0x%x, CRC_EC: 0x%x, CA_PES: 0x%x, ODT_IB: 0x%x "
+ "RTT_PARK: 0x%x, CAP: 0x%x, DM: 0x%x, WDBI: 0x%x, RDBI: 0x%x", i_rank,
+ uint8_t(l_ca_parity_latency_buffer), l_crc_error_clear, l_ca_parity_error_status,
+ l_odt_input_buffer, uint8_t(l_rtt_park_buffer), l_ca_parity, l_data_mask,
+ l_write_dbi, l_read_dbi);
+
+ return FAPI2_RC_SUCCESS;
+}
+
+} // ns ddr4
+} // ns mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs06.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs06.C
index d8a285d91..3829d2ef0 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs06.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs06.C
@@ -22,3 +22,149 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+
+///
+/// @file mrs06.C
+/// @brief Run and manage the DDR4 MRS06 loading
+///
+// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+
+#include <mss.H>
+#include <lib/dimm/ddr4/mrs_load_ddr4.H>
+
+using fapi2::TARGET_TYPE_MCBIST;
+using fapi2::TARGET_TYPE_DIMM;
+
+using fapi2::FAPI2_RC_SUCCESS;
+
+namespace mss
+{
+
+namespace ddr4
+{
+
+///
+/// @brief mrs06_data ctor
+/// @param[in] a fapi2::TARGET_TYPE_DIMM target
+/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+mrs06_data::mrs06_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ):
+ iv_tccd_l(0)
+{
+ FAPI_TRY( mss::eff_vref_dq_train_value(i_target, &(iv_vrefdq_train_value[0])) );
+ FAPI_TRY( mss::eff_vref_dq_train_range(i_target, &(iv_vrefdq_train_range[0])) );
+ FAPI_TRY( mss::eff_vref_dq_train_enable(i_target, &(iv_vrefdq_train_enable[0])) );
+ FAPI_TRY( mss::eff_dram_tccd_l(i_target, iv_tccd_l) );
+
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
+ return;
+
+fapi_try_exit:
+ o_rc = fapi2::current_err;
+ FAPI_ERR("unable to get attributes for mrs0");
+ return;
+}
+
+///
+/// @brief Configure the ARR0 of the CCS instruction for mrs06
+/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank the rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs06(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank)
+{
+ // Check to make sure our ctor worked ok
+ mrs06_data l_data( i_target, fapi2::current_err );
+ FAPI_TRY( fapi2::current_err, "Unable to construct MRS06 data from attributes");
+ FAPI_TRY( mrs06(i_target, l_data, io_inst, i_rank) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Configure the ARR0 of the CCS instruction for mrs06, data object as input
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] i_data an mrs06_data object, filled in
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank the rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs06(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mrs06_data& i_data,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank)
+{
+ constexpr uint64_t LOWEST_TCCD = 4;
+ constexpr uint64_t TCCD_COUNT = 5;
+ // 4 5 6 7 8
+ constexpr uint8_t tccd_l_map[TCCD_COUNT] = { 0b000, 0b001, 0b010, 0b011, 0b100 };
+
+ fapi2::buffer<uint8_t> l_tccd_l_buffer;
+ fapi2::buffer<uint8_t> l_vrefdq_train_value_buffer;
+
+ FAPI_ASSERT((i_data.iv_tccd_l >= LOWEST_TCCD) && (i_data.iv_tccd_l < (LOWEST_TCCD + TCCD_COUNT)),
+ fapi2::MSS_BAD_MR_PARAMETER()
+ .set_MR_NUMBER(6)
+ .set_PARAMETER(TCCD)
+ .set_PARAMETER_VALUE(i_data.iv_tccd_l)
+ .set_DIMM_IN_ERROR(i_target),
+ "Bad value for TCCD: %d (%s)", i_data.iv_tccd_l, mss::c_str(i_target));
+
+ l_tccd_l_buffer = tccd_l_map[i_data.iv_tccd_l - LOWEST_TCCD];
+ l_vrefdq_train_value_buffer = i_data.iv_vrefdq_train_value[mss::index(i_rank)];
+
+ FAPI_INF("MR6 rank %d attributes: TRAIN_V: 0x%x(0x%x), TRAIN_R: 0x%x, TRAIN_E: 0x%x, TCCD_L: 0x%x(0x%x)", i_rank,
+ i_data.iv_vrefdq_train_value[mss::index(i_rank)], uint8_t(l_vrefdq_train_value_buffer),
+ i_data.iv_vrefdq_train_range[mss::index(i_rank)],
+ i_data.iv_vrefdq_train_enable[mss::index(i_rank)], i_data.iv_tccd_l, uint8_t(l_tccd_l_buffer));
+
+ mss::swizzle<A0, 6, 7>(l_vrefdq_train_value_buffer, io_inst.arr0);
+ io_inst.arr0.writeBit<A6>(i_data.iv_vrefdq_train_range[mss::index(i_rank)]);
+ io_inst.arr0.writeBit<A7>(i_data.iv_vrefdq_train_enable[mss::index(i_rank)]);
+ mss::swizzle<A10, 3, 7>(l_tccd_l_buffer, io_inst.arr0);
+
+ FAPI_INF("MR6: 0x%016llx", uint64_t(io_inst.arr0));
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Given a CCS instruction which contains address bits with an encoded MRS6,
+/// decode and trace the contents
+/// @param[in] i_inst the CCS instruction
+/// @param[in] i_rank ths rank in question
+/// @return void
+///
+fapi2::ReturnCode mrs06_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
+ const uint64_t i_rank)
+{
+ fapi2::buffer<uint8_t> l_tccd_l_buffer;
+ fapi2::buffer<uint8_t> l_vrefdq_train_value_buffer;
+
+ mss::swizzle<2, 6, A5>(i_inst.arr0, l_vrefdq_train_value_buffer);
+ uint8_t l_vrefdq_train_range = i_inst.arr0.getBit<A6>();
+ uint8_t l_vrefdq_train_enable = i_inst.arr0.getBit<A7>();
+ mss::swizzle<5, 3, A12>(i_inst.arr0, l_tccd_l_buffer);
+
+ FAPI_INF("MR6 rank %d decode: TRAIN_V: 0x%x, TRAIN_R: 0x%x, TRAIN_E: 0x%x, TCCD_L: 0x%x", i_rank,
+ uint8_t(l_vrefdq_train_value_buffer), l_vrefdq_train_range,
+ l_vrefdq_train_enable, uint8_t(l_tccd_l_buffer));
+
+ return FAPI2_RC_SUCCESS;
+}
+
+} // ns ddr4
+} // ns mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C
new file mode 100644
index 000000000..166246dde
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C
@@ -0,0 +1,125 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* [+] 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 mrs_load_ddr4.C
+/// @brief Run and manage the DDR4 mrs loading
+///
+// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: FSP:HB
+
+#include <fapi2.H>
+
+#include <mss.H>
+#include <lib/dimm/ddr4/mrs_load_ddr4.H>
+
+using fapi2::TARGET_TYPE_MCBIST;
+using fapi2::TARGET_TYPE_DIMM;
+
+using fapi2::FAPI2_RC_SUCCESS;
+
+namespace mss
+{
+
+namespace ddr4
+{
+
+///
+/// @brief Perform the mrs_load DDR4 operations - TARGET_TYPE_DIMM specialization
+/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
+/// @param[in] io_inst a vector of CCS instructions we should add to
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+fapi2::ReturnCode mrs_load( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
+ std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
+{
+ FAPI_INF("ddr4::mrs_load %s", mss::c_str(i_target));
+
+ // Per DDR4MRS02 table 104 - timing requirements
+ static const uint64_t tMRD = 8;
+
+ static std::vector< mrs_data<TARGET_TYPE_MCBIST> > l_mrs_data =
+ {
+ // JEDEC ordering of MRS per DDR4 power on sequence
+ { 3, mrs03, mrs03_decode, tMRD }, { 6, mrs06, mrs06_decode, tMRD },
+ { 5, mrs05, mrs05_decode, tMRD }, { 4, mrs04, mrs04_decode, tMRD },
+ { 2, mrs02, mrs02_decode, tMRD }, { 1, mrs01, mrs01_decode, tMRD },
+ { 0, mrs00, mrs00_decode, tMRD },
+ };
+
+ std::vector< uint64_t > l_ranks;
+ FAPI_TRY( mss::ranks(i_target, l_ranks) );
+
+ for (const auto& d : l_mrs_data)
+ {
+ for (const auto& r : l_ranks)
+ {
+ // Note: this isn't general - assumes Nimbus via MCBIST instruction here BRS
+ ccs::instruction_t<TARGET_TYPE_MCBIST> l_inst_a_side =
+ ccs::mrs_command<TARGET_TYPE_MCBIST>(i_target, r, d.iv_mrs);
+ ccs::instruction_t<TARGET_TYPE_MCBIST> l_inst_b_side;
+
+ // Thou shalt send 2 MRS, one for the a-side and the other inverted for the b-side.
+ // If we're on an odd-rank then we need to mirror
+ // So configure the A-side, mirror if necessary and invert for the B-side
+ FAPI_TRY( d.iv_func(i_target, l_inst_a_side, r) );
+
+ FAPI_TRY( mss::address_mirror(i_target, r, l_inst_a_side) );
+ l_inst_b_side = mss::address_invert(l_inst_a_side);
+
+ // Not sure if we can get tricky here and only delay after the b-side MR. The question is whether the delay
+ // is needed/assumed by the register or is purely a DRAM mandated delay. We know we can't go wrong having
+ // both delays but if we can ever confirm that we only need one we can fix this. BRS
+ l_inst_a_side.arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES,
+ MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(d.iv_delay);
+ l_inst_b_side.arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES,
+ MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(d.iv_delay);
+
+ // Dump out the 'decoded' MRS and trace the CCS instructions.
+ if (d.iv_dumper != nullptr)
+ {
+ FAPI_TRY( d.iv_dumper(l_inst_a_side, r) );
+ }
+
+ FAPI_INF("MRS%02d (%d) 0x%016llx:0x%016llx %s:rank %d a-side", uint8_t(d.iv_mrs), d.iv_delay,
+ l_inst_a_side.arr0, l_inst_a_side.arr1, mss::c_str(i_target), r);
+ FAPI_INF("MRS%02d (%d) 0x%016llx:0x%016llx %s:rank %d b-side", uint8_t(d.iv_mrs), d.iv_delay,
+ l_inst_b_side.arr0, l_inst_b_side.arr1, mss::c_str(i_target), r);
+
+ // Add both to the CCS program
+ io_inst.push_back(l_inst_a_side);
+ io_inst.push_back(l_inst_b_side);
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+} // ns ddr4
+} // ns mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H
new file mode 100644
index 000000000..cfbe96e5a
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H
@@ -0,0 +1,579 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016 */
+/* [+] 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 mrs_load_ddr4.H
+/// @brief Code to support mrs_load_ddr4
+///
+// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
+// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
+// *HWP Team: Memory
+// *HWP Level: 1
+// *HWP Consumed by: HB:FSP
+
+#ifndef _MSS_MRS_LOAD_DDR4_H_
+#define _MSS_MRS_LOAD_DDR4_H_
+
+#include <vector>
+#include <fapi2.H>
+#include <lib/utils/c_str.H>
+#include <lib/dimm/mrs_load.H>
+
+namespace mss
+{
+
+namespace ddr4
+{
+
+//
+// Each MRS has it's attributes encapsulated in it's little struct.
+//
+
+///
+/// @brief Data structure for MRS0 data
+///
+struct mrs00_data
+{
+ ///
+ /// @brief mrs00_data ctor
+ /// @param[in] a fapi2::TARGET_TYPE_DIMM target
+ /// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+ ///
+ mrs00_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc );
+
+ uint8_t iv_burst_length;
+ uint8_t iv_read_burst_type;
+ uint8_t iv_dll_reset;
+ uint8_t iv_test_mode;
+ uint8_t iv_write_recovery;
+ uint8_t iv_cas_latency;
+};
+
+///
+/// @brief Data structure for MRS1 data
+///
+struct mrs01_data
+{
+ ///
+ /// @brief mrs01_data ctor
+ /// @param[in] a fapi2::TARGET_TYPE_DIMM target
+ /// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+ ///
+ mrs01_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc );
+
+ uint8_t iv_dll_enable;
+ uint8_t iv_odic;
+ uint8_t iv_additive_latency;
+ uint8_t iv_wl_enable;
+ uint8_t iv_tdqs;
+ uint8_t iv_qoff;
+ uint8_t iv_rtt_nom[MAX_RANK_PER_DIMM];
+};
+
+///
+/// @brief Data structure for MRS2 data
+///
+struct mrs02_data
+{
+ ///
+ /// @brief mrs03_data ctor
+ /// @param[in] a fapi2::TARGET_TYPE_DIMM target
+ /// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+ ///
+ mrs02_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc );
+
+ uint8_t iv_lpasr;
+ uint8_t iv_cwl;
+ uint8_t iv_write_crc;
+ uint8_t iv_dram_rtt_wr[MAX_RANK_PER_DIMM];
+};
+
+
+///
+/// @brief Data structure for MRS3 data
+///
+struct mrs03_data
+{
+ ///
+ /// @brief mrs03_data ctor
+ /// @param[in] a fapi2::TARGET_TYPE_DIMM target
+ /// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+ ///
+ mrs03_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc );
+
+ uint8_t iv_mpr_mode;
+ uint8_t iv_mpr_page;
+ uint8_t iv_geardown;
+ uint8_t iv_pda;
+ uint8_t iv_crc_wr_latency;
+ uint8_t iv_temp_readout;
+ uint8_t iv_fine_refresh;
+ uint8_t iv_read_format;
+};
+
+///
+/// @brief Data structure for MRS4 data
+///
+struct mrs04_data
+{
+ ///
+ /// @brief mrs04_data ctor
+ /// @param[in] a fapi2::TARGET_TYPE_DIMM target
+ /// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+ ///
+ mrs04_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc );
+
+ uint8_t iv_max_pd_mode;
+ uint8_t iv_temp_refresh_range;
+ uint8_t iv_temp_ref_mode;
+ uint8_t iv_vref_mon;
+ uint8_t iv_cs_cmd_latency;
+ uint8_t iv_ref_abort;
+ uint8_t iv_rd_pre_train_mode;
+ uint8_t iv_rd_preamble;
+ uint8_t iv_wr_preamble;
+ uint8_t iv_ppr;
+};
+
+///
+/// @brief Data structure for MRS5 data
+///
+struct mrs05_data
+{
+ ///
+ /// @brief mrs05_data ctor
+ /// @param[in] a fapi2::TARGET_TYPE_DIMM target
+ /// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+ ///
+ mrs05_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc );
+
+ uint8_t iv_ca_parity_latency;
+ uint8_t iv_crc_error_clear;
+ uint8_t iv_ca_parity_error_status;
+ uint8_t iv_odt_input_buffer;
+ uint8_t iv_ca_parity;
+ uint8_t iv_data_mask;
+ uint8_t iv_write_dbi;
+ uint8_t iv_read_dbi;
+ uint8_t iv_rtt_park[MAX_RANK_PER_DIMM];
+};
+
+///
+/// @brief Data structure for MRS6 data
+///
+struct mrs06_data
+{
+ ///
+ /// @brief mrs06_data ctor
+ /// @param[in] a fapi2::TARGET_TYPE_DIMM target
+ /// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+ ///
+ mrs06_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc );
+
+ uint8_t iv_vrefdq_train_value[MAX_RANK_PER_DIMM];
+ uint8_t iv_vrefdq_train_range[MAX_RANK_PER_DIMM];
+ uint8_t iv_vrefdq_train_enable[MAX_RANK_PER_DIMM];
+ uint8_t iv_tccd_l;
+};
+
+///
+/// @defgroup setup-ccs
+/// @addtogroyp setup-ccs
+/// API which setup CCS instructions.
+/// @{
+
+///
+/// @brief Configure the ARR0 of the CCS isntruction for mrs00
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs00(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank);
+
+///
+/// @brief Configure the ARR0 of the CCS isntruction for mrs01
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs01(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank);
+
+///
+/// @brief Configure the ARR0 of the CCS isntruction for mrs02
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs02(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank);
+///
+/// @brief Configure the ARR0 of the CCS isntruction for mrs03
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs03(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank);
+///
+/// @brief Configure the ARR0 of the CCS isntruction for mrs04
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs04(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank);
+///
+/// @brief Configure the ARR0 of the CCS isntruction for mrs05
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs05(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank);
+///
+/// @brief Configure the ARR0 of the CCS isntruction for mrs06
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs06(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank);
+
+/// }@
+
+///
+/// @defgroup setup-ccs-overloads
+/// @addtogroyp setup-ccs-overloads
+/// API which setup CCS instructions, but take an MRS data object as input
+/// @{
+
+///
+/// @brief Configure the ARR0 of the CCS isntruction for mrs00, data object as input
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] i_data an mrs00_data object, filled in
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs00(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mrs00_data& i_data,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank);
+
+///
+/// @brief Configure the ARR0 of the CCS isntruction for mrs01, data object as input
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] i_data an mrs01_data object, filled in
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs01(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mrs01_data& i_data,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank);
+
+///
+/// @brief Configure the ARR0 of the CCS isntruction for mrs02, data object as input
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] i_data an mrs02_data object, filled in
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs02(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mrs02_data& i_data,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank);
+
+///
+/// @brief Configure the ARR0 of the CCS isntruction for mrs03, data object as input
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] i_data an mrs00_data object, filled in
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs03(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mrs03_data& i_data,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank);
+
+///
+/// @brief Configure the ARR0 of the CCS isntruction for mrs04, data object as input
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] i_data an mrs04_data object, filled in
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs04(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mrs04_data& i_data,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank);
+
+///
+/// @brief Configure the ARR0 of the CCS isntruction for mrs05, data object as input
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] i_data an mrs05_data object, filled in
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs05(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mrs05_data& i_data,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank);
+
+///
+/// @brief Configure the ARR0 of the CCS isntruction for mrs06, data object as input
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] i_data an mrs06_data object, filled in
+/// @param[in,out] io_inst the instruction to fixup
+/// @param[in] i_rank ths rank in question
+/// @return FAPI2_RC_SUCCESS iff OK
+///
+fapi2::ReturnCode mrs06(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mrs06_data& i_data,
+ ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
+ const uint64_t i_rank);
+
+/// }@
+
+///
+/// @defgroup ccs-decode
+/// @addtogroyccs-decode
+/// API which decode CCS instructions.
+/// @{
+
+///
+/// @brief Given a CCS instruction which contains address bits with an encoded MRS00,
+/// decode and trace the contents
+/// @param[in] i_inst the CCS instruction
+/// @param[in] i_rank ths rank in question
+/// @return void
+///
+fapi2::ReturnCode mrs00_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+ const uint64_t i_rank);
+
+///
+/// @brief Given a CCS instruction which contains address bits with an encoded MRS01,
+/// decode and trace the contents
+/// @param[in] i_inst the CCS instruction
+/// @param[in] i_rank ths rank in question
+/// @return void
+///
+fapi2::ReturnCode mrs01_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+ const uint64_t i_rank);
+
+///
+/// @brief Given a CCS instruction which contains address bits with an encoded MRS02,
+/// decode and trace the contents
+/// @param[in] i_inst the CCS instruction
+/// @param[in] i_rank ths rank in question
+/// @return void
+///
+fapi2::ReturnCode mrs02_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+ const uint64_t i_rank);
+
+///
+/// @brief Given a CCS instruction which contains address bits with an encoded MRS03,
+/// decode and trace the contents
+/// @param[in] i_inst the CCS instruction
+/// @param[in] i_rank ths rank in question
+/// @return void
+///
+fapi2::ReturnCode mrs03_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+ const uint64_t i_rank);
+
+///
+/// @brief Given a CCS instruction which contains address bits with an encoded MRS04,
+/// decode and trace the contents
+/// @param[in] i_inst the CCS instruction
+/// @param[in] i_rank ths rank in question
+/// @return void
+///
+fapi2::ReturnCode mrs04_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+ const uint64_t i_rank);
+
+///
+/// @brief Given a CCS instruction which contains address bits with an encoded MRS05,
+/// decode and trace the contents
+/// @param[in] i_inst the CCS instruction
+/// @param[in] i_rank ths rank in question
+/// @return void
+///
+fapi2::ReturnCode mrs05_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+ const uint64_t i_rank);
+
+///
+/// @brief Given a CCS instruction which contains address bits with an encoded MRS06,
+/// decode and trace the contents
+/// @param[in] i_inst the CCS instruction
+/// @param[in] i_rank ths rank in question
+/// @return void
+///
+fapi2::ReturnCode mrs06_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
+ const uint64_t i_rank);
+
+
+///
+/// @brief Perform the mrs_load DDR4 operations - TARGET_TYPE_DIMM specialization
+/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[in] io_inst a vector of CCS instructions we should add to
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+fapi2::ReturnCode mrs_load( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
+
+/// @}
+
+} // ns ddr4
+
+// Map bits in the ARR0 register(s) to MRS address bits. Should be traits related to ARR0. BRS
+enum address_bits
+{
+ A0 = 0,
+ A1 = 1,
+ A2 = 2,
+ A3 = 3,
+ A4 = 4,
+ A5 = 5,
+ A6 = 6,
+ A7 = 7,
+ A8 = 8,
+ A9 = 9,
+ A10 = 10,
+ A11 = 11,
+ A12 = 12,
+ A13 = 13,
+ A14 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_14,
+ A15 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_15,
+ A16 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_16,
+ A17 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_17,
+
+ // Only kind of address bits ... <shrug>
+ BA0 = 17,
+ BA1 = 18,
+ BG0 = 19,
+ BG1 = 15,
+};
+
+///
+/// @brief Mirror (front to back) the ADR bits of a CCS instruction - implementation
+/// @tparam T typename of the ccs::instruction_t
+/// @param[in, out] io_inst reference to a CCS instruction to be mirrored
+/// @return FAPI2_RC_SUCESS iff ok
+/// @note written this way so this is easier to test
+///
+template<fapi2::TargetType T>
+void address_mirror_impl(ccs::instruction_t<T>& io_inst)
+{
+ // Nothing fancy here, just mirror the bits we're told to mirror in Table 14 — Address Mirroring and Inversion
+ mss::template swap<A3, A4>(io_inst.arr0);
+ mss::template swap<A5, A6>(io_inst.arr0);
+ mss::template swap<A7, A8>(io_inst.arr0);
+ mss::template swap<A11, A13>(io_inst.arr0);
+ mss::template swap<BA0, BA1>(io_inst.arr0);
+ mss::template swap<BG0, BG1>(io_inst.arr0);
+}
+
+///
+/// @brief Mirror (front to back) the ADR bits of a CCS instruction
+/// @tparam T typename of the ccs::instruction_t
+/// @param[in] i_target target to use to get mirroring attribute
+/// @param[in] i_rank the rank in question
+/// @param[in, out] io_inst reference to a CCS instruction to be mirrored
+/// @return FAPI2_RC_SUCESS iff ok
+/// @note assumes the input is from an even number rank
+///
+template<fapi2::TargetType T>
+fapi2::ReturnCode address_mirror(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const uint64_t i_rank, ccs::instruction_t<T>& io_inst)
+{
+ // We only mirror if the mirroring attribute is set.
+ uint8_t l_mirror = 0;
+ FAPI_TRY( eff_dimm_rcd_mirror_mode(i_target, l_mirror) );
+
+ // We only mirror odd ranks.
+ if ((l_mirror == fapi2::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_ON) && (i_rank & 0x1))
+ {
+ address_mirror_impl(io_inst);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Invert (side to side) the ADR bits of a CCS instruction
+/// @param[in] i_inst const reference to a CCS instruction.
+/// @return[out] ccs instruction with the ADR bits inverted (side-to-side)
+///
+template<fapi2::TargetType T>
+ccs::instruction_t<T> address_invert(const ccs::instruction_t<T>& i_inst)
+{
+ // Copy the input as the output doesn't all change.
+ ccs::instruction_t<T> i_out(i_inst);
+
+ // Nothing fancy here, just negate the bits we're told to negate in Table 14 — Address Mirroring and Inversion
+ mss::template negate<A3>(i_out.arr0);
+ mss::template negate<A4>(i_out.arr0);
+ mss::template negate<A5>(i_out.arr0);
+ mss::template negate<A6>(i_out.arr0);
+ mss::template negate<A7>(i_out.arr0);
+ mss::template negate<A8>(i_out.arr0);
+ mss::template negate<A9>(i_out.arr0);
+
+ mss::template negate<A11>(i_out.arr0);
+ mss::template negate<A13>(i_out.arr0);
+ mss::template negate<A17>(i_out.arr0);
+
+ mss::template negate<BA0>(i_out.arr0);
+ mss::template negate<BA1>(i_out.arr0);
+ mss::template negate<BG0>(i_out.arr0);
+ mss::template negate<BG1>(i_out.arr0);
+
+ return i_out;
+}
+
+} // namespace
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.C
index 9ea3415a8..1ece04fd4 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.C
@@ -38,7 +38,7 @@
#include <mss.H>
#include <lib/dimm/mrs_load.H>
-#include <lib/dimm/mrs_load_ddr4.H>
+#include <lib/dimm/ddr4/mrs_load_ddr4.H>
using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_DIMM;
@@ -84,12 +84,12 @@ fapi_try_exit:
///
/// @brief Perform the mrs_load operations - unknown DIMM case
/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
-/// @param[in] i_inst a vector of CCS instructions we should add to (unused)
+/// @param[in] io_inst a vector of CCS instructions we should add to (unused)
/// @return FAPI2_RC_SUCCESS if and only if ok
///
template<>
fapi2::ReturnCode perform_mrs_load<DEFAULT_KIND>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& i_inst)
+ std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
{
uint8_t l_type = 0;
uint8_t l_gen = 0;
@@ -114,15 +114,15 @@ fapi_try_exit:
///
/// @brief Perform the mrs_load operations - RDIMM DDR4
/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
-/// @param[in] i_inst a vector of CCS instructions we should add to
+/// @param[in] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
template<>
fapi2::ReturnCode perform_mrs_load<KIND_RDIMM_DDR4>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& i_inst)
+ std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
{
FAPI_DBG("perform mrs_load for %s [expecting rdimm (ddr4)]", mss::c_str(i_target));
- FAPI_TRY( mrs_load_ddr4(i_target, i_inst) );
+ FAPI_TRY( ddr4::mrs_load(i_target, io_inst) );
fapi_try_exit:
return fapi2::current_err;
@@ -131,15 +131,15 @@ fapi_try_exit:
///
/// @brief Perform the mrs_load operations - LRDIMM DDR4
/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
-/// @param[in] i_inst a vector of CCS instructions we should add to
+/// @param[in] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
template<>
fapi2::ReturnCode perform_mrs_load<KIND_LRDIMM_DDR4>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& i_inst)
+ std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
{
FAPI_DBG("perform mrs_load for %s [expecting lrdimm (ddr4)]", mss::c_str(i_target));
- FAPI_TRY( mrs_load_ddr4(i_target, i_inst) );
+ FAPI_TRY( ddr4::mrs_load(i_target, io_inst) );
fapi_try_exit:
return fapi2::current_err;
@@ -149,12 +149,12 @@ fapi_try_exit:
///
/// @brief Perform the mrs_load operations - start the dispatcher
/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
-/// @param[in] i_inst a vector of CCS instructions we should add to
+/// @param[in] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS if and only if ok
///
template<>
fapi2::ReturnCode perform_mrs_load<FORCE_DISPATCH>( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& i_inst)
+ std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst)
{
uint8_t l_type = 0;
uint8_t l_gen = 0;
@@ -162,7 +162,7 @@ fapi2::ReturnCode perform_mrs_load<FORCE_DISPATCH>( const fapi2::Target<TARGET_T
FAPI_TRY( mss::eff_dimm_type(i_target, l_type) );
FAPI_TRY( mss::eff_dram_gen(i_target, l_gen) );
- return perform_mrs_load_dispatch<FORCE_DISPATCH>(dimm_kind( l_type, l_gen ), i_target, i_inst);
+ return perform_mrs_load_dispatch<FORCE_DISPATCH>(dimm_kind( l_type, l_gen ), i_target, io_inst);
fapi_try_exit:
FAPI_ERR("couldn't get dimm type, dram gen: %s", mss::c_str(i_target));
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.H
index 076b57c86..d7108dad3 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load.H
@@ -46,6 +46,25 @@ namespace mss
{
///
+/// @brief MR Parameter Error Values
+/// A set of enumerations allowing one error xml/code to represent all bad parameters
+/// for MR encoding. The error info will take which MR has bad encoding, one of these
+/// enumerations to indicate which field was incorrect, and then the incorrect value.
+///
+enum mrs_bad_field
+{
+ WRITE_CMD_LATENCY = 0,
+ WRITE_RECOVERY = 1,
+ CAS_LATENCY = 2,
+ OUTPUT_IMPEDANCE = 3,
+ CAS_WRITE_LATENCY = 4,
+ CS_CMD_LATENCY = 5,
+ CA_PARITY_LATENCY = 6,
+ RTT_PARK = 7,
+ TCCD = 8,
+};
+
+///
/// @brief A structure to represent an MRS operation
/// @tparam T, the target type of the CCS engine chiplet
///
@@ -64,10 +83,10 @@ struct mrs_data
// The delay needed after this MRS word is written
uint64_t iv_delay;
- mrs_data( uint64_t i_mrs,
+ mrs_data( const uint64_t i_mrs,
fapi2::ReturnCode (*i_func)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&, ccs::instruction_t<T>&, const uint64_t),
fapi2::ReturnCode (*i_dumper)(const ccs::instruction_t<T>&, const uint64_t),
- uint64_t i_delay ):
+ const uint64_t i_delay ):
iv_mrs(i_mrs),
iv_func(i_func),
iv_dumper(i_dumper),
@@ -142,7 +161,7 @@ struct perform_mrs_load_overload< KIND_LRDIMM_DDR4 >
template< mss::kind_t K = FORCE_DISPATCH >
typename std::enable_if< perform_mrs_load_overload<DEFAULT_KIND>::available, fapi2::ReturnCode>::type
perform_mrs_load( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& i_inst);
+ std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
//
// We know we registered overloads for perform_mrs_load, so we need the entry point to
@@ -151,11 +170,11 @@ perform_mrs_load( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
//
template<>
fapi2::ReturnCode perform_mrs_load<FORCE_DISPATCH>( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& i_inst);
+ std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
template<>
fapi2::ReturnCode perform_mrs_load<DEFAULT_KIND>( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& i_inst);
+ std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst);
//
// Boilerplate dispatcher
@@ -163,27 +182,27 @@ fapi2::ReturnCode perform_mrs_load<DEFAULT_KIND>( const fapi2::Target<fapi2::TAR
template< kind_t K, bool B = perform_mrs_load_overload<K>::available >
inline fapi2::ReturnCode perform_mrs_load_dispatch( const kind_t& i_kind,
const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& i_inst)
+ std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
{
// We dispatch to another kind if:
// We don't have an overload defined (B == false)
// Or, if we do have an overload (B == true) and this is not out kind.
if ((B == false) || ((B == true) && (K != i_kind)))
{
- return perform_mrs_load_dispatch < (kind_t)(K - 1) > (i_kind, i_target, i_inst);
+ return perform_mrs_load_dispatch < (kind_t)(K - 1) > (i_kind, i_target, io_inst);
}
// Otherwise, we call the overload.
- return perform_mrs_load<K>(i_target, i_inst);
+ return perform_mrs_load<K>(i_target, io_inst);
}
// DEFAULT_KIND is 0 so this is the end of the recursion
template<>
inline fapi2::ReturnCode perform_mrs_load_dispatch<DEFAULT_KIND>(const kind_t&,
const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& i_inst)
+ std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
{
- return perform_mrs_load<DEFAULT_KIND>(i_target, i_inst);
+ return perform_mrs_load<DEFAULT_KIND>(i_target, io_inst);
}
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load_ddr4.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load_ddr4.C
deleted file mode 100644
index 5632c05dd..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load_ddr4.C
+++ /dev/null
@@ -1,850 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load_ddr4.C $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
-/* [+] 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 mrs_load_ddr4.C
-/// @brief Run and manage the DDR4 mrs loading
-///
-// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
-// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
-// *HWP FW Owner: Bill Hoffa <wghoffa@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 1
-// *HWP Consumed by: FSP:HB
-
-#include <fapi2.H>
-
-#include <mss.H>
-#include <lib/dimm/mrs_load_ddr4.H>
-
-using fapi2::TARGET_TYPE_MCBIST;
-using fapi2::TARGET_TYPE_DIMM;
-
-using fapi2::FAPI2_RC_SUCCESS;
-
-namespace mss
-{
-
-//
-// Each MRS has it's attributes encapsulated in it's little setter function.
-//
-
-///
-/// @brief Configure the ARR0 of the CCS isntruction for mrs00
-/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
-/// @param[in,out] io_inst the instruction to fixup
-/// @param[in] i_rank ths rank in question
-/// @return FAPI2_RC_SUCCESS iff OK
-///
-static fapi2::ReturnCode ddr4_mrs00(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
- const uint64_t i_rank)
-{
- // Map from Write Recovery attribute value to bits in the MRS.
- // Bit 4 is A13, bits 5:7 are A11:A9
- static const uint8_t wr_map[27] =
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0b0000, 0, 0b0001, 0, 0b0001, 0, 0b0011,
- 0, 0b0100, 0, 0b0101, 0, 0b0111, 0, 0b0110, 0, 0b1000
- };
-
- // Map from the CAS Latency attribute to the bits in the MRS
- static const uint8_t cl_map[34] =
- {
- // 0 1 2 3 4 5 6 7 8
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- // 9 10 11 12 13 14 15 16
- 0b00000, 0b00001, 0b00010, 0b00011, 0b00100, 0b00101, 0b00110, 0b00111,
- // 17, 18 19 20 21 22 23 24
- 0b01101, 0b01000, 0b01110, 0b01001, 0b01111, 0b01010, 0b01100, 0b01011,
- // 25 26 27 28 29 30 31 32 33
- 0b10000, 0b10001, 0b10010, 0b10011, 0b10100, 0b10101, 0b10110, 0b10111, 0b11000
- };
-
- uint8_t l_burst_length = 0;
- uint8_t l_read_burst_type = 0;
- uint8_t l_dll_reset = 0;
- uint8_t l_test_mode = 0;
- uint8_t l_write_recovery = 0;
- uint8_t l_cas_latency = 0;
-
- fapi2::buffer<uint8_t> l_cl;
- fapi2::buffer<uint8_t> l_wr;
-
- FAPI_TRY( mss::eff_dram_bl(i_target, l_burst_length) );
- FAPI_TRY( mss::eff_dram_rbt(i_target, l_read_burst_type) );
- FAPI_TRY( mss::eff_dram_cl(i_target, l_cas_latency) );
- FAPI_TRY( mss::eff_dram_dll_reset(i_target, l_dll_reset) );
- FAPI_TRY( mss::eff_dram_tm(i_target, l_test_mode) );
- FAPI_TRY( mss::eff_dram_twr(i_target, l_write_recovery) );
-
- FAPI_DBG("MR0 Attributes: BL: 0x%x, RBT: 0x%x, CL: 0x%x(0x%x), TM: 0x%x, DLL_RESET: 0x%x, WR: 0x%x(0x%x)",
- l_burst_length, l_read_burst_type, l_cas_latency, cl_map[l_cas_latency],
- l_test_mode, l_dll_reset, l_write_recovery, wr_map[l_write_recovery]);
-
- io_inst.arr0.insertFromRight<A0, 2>(l_burst_length);
- io_inst.arr0.writeBit<A3>(l_read_burst_type);
- io_inst.arr0.writeBit<A7>(l_test_mode);
- io_inst.arr0.writeBit<A8>(l_dll_reset);
-
- // CAS Latency takes a little effort - the bits aren't contiguous
- l_cl = cl_map[l_cas_latency];
- io_inst.arr0.writeBit<A12>(l_cl.getBit<3>());
- io_inst.arr0.writeBit<A6>(l_cl.getBit<4>());
- io_inst.arr0.writeBit<A5>(l_cl.getBit<5>());
- io_inst.arr0.writeBit<A4>(l_cl.getBit<6>());
- io_inst.arr0.writeBit<A2>(l_cl.getBit<7>());
-
- // Write Recovery/Read to Precharge is not contiguous either.
- l_wr = wr_map[l_write_recovery];
- io_inst.arr0.writeBit<A13>(l_wr.getBit<4>());
- io_inst.arr0.writeBit<A11>(l_wr.getBit<5>());
- io_inst.arr0.writeBit<A10>(l_wr.getBit<6>());
- io_inst.arr0.writeBit<A9>(l_wr.getBit<7>());
-
- FAPI_DBG("MR0: 0x%016llx", uint64_t(io_inst.arr0));
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Given a CCS instruction which contains address bits with an encoded MRS0,
-/// decode and trace the contents
-/// @param[in] i_inst the CCS instruction
-/// @param[in] i_rank ths rank in question
-/// @return void
-///
-static fapi2::ReturnCode ddr4_mrs00_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
- const uint64_t i_rank)
-{
- static const uint8_t wr_map[9] = { 10, 12, 14, 16, 18, 20, 24, 22, 26 };
-
- uint8_t l_burst_length = 0;
- uint8_t l_read_burst_type = 0;
- uint8_t l_dll_reset = 0;
- uint8_t l_test_mode = 0;
-
- fapi2::buffer<uint8_t> l_wr_index;
- fapi2::buffer<uint8_t> l_cas_latency;
-
- i_inst.arr0.extractToRight<A0, 2>(l_burst_length);
- l_read_burst_type = i_inst.arr0.getBit<A3>();
- l_test_mode = i_inst.arr0.getBit<A7>();
- l_dll_reset = i_inst.arr0.getBit<A8>();
-
- // CAS Latency takes a little effort - the bits aren't contiguous
- l_cas_latency.writeBit<3>(i_inst.arr0.getBit<A12>());
- l_cas_latency.writeBit<4>(i_inst.arr0.getBit<A6>());
- l_cas_latency.writeBit<5>(i_inst.arr0.getBit<A5>());
- l_cas_latency.writeBit<6>(i_inst.arr0.getBit<A4>());
- l_cas_latency.writeBit<7>(i_inst.arr0.getBit<A2>());
-
- // Write Recovery/Read to Precharge is not contiguous either.
- l_wr_index.writeBit<4>(i_inst.arr0.getBit<A13>());
- l_wr_index.writeBit<5>(i_inst.arr0.getBit<A11>());
- l_wr_index.writeBit<6>(i_inst.arr0.getBit<A10>());
- l_wr_index.writeBit<7>(i_inst.arr0.getBit<A9>());
-
- FAPI_DBG("MR0 Decode BL: 0x%x, RBT: 0x%x, CL: 0x%x, TM: 0x%x, DLL_RESET: 0x%x, WR: (0x%x)0x%x",
- l_burst_length, l_read_burst_type, uint8_t(l_cas_latency), l_test_mode, l_dll_reset,
- wr_map[uint8_t(l_wr_index)], uint8_t(l_wr_index));
-
- return FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Configure the ARR0 of the CCS isntruction for mrs01
-/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
-/// @param[in,out] io_inst the instruction to fixup
-/// @param[in] i_rank ths rank in question
-/// @return FAPI2_RC_SUCCESS iff OK
-///
-static fapi2::ReturnCode ddr4_mrs01(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
- const uint64_t i_rank)
-{
- // Little table to map Output Driver Imepdance Control. 34Ohm is index 0,
- // 48Ohm is index 1 and we expect eff_config to make sure there's nothing
- // else used here.
- // Left bit is A2, right bit is A1
- static const uint8_t odic_map[2] = { 0b00, 0b01 };
-
- // Indexed by denominator. So, if RQZ is 240, and you have OHM240, then you're looking
- // for index 1. So this doesn't correspond directly with the table in the JEDEC spec,
- // as that's not in "denominator order."
- // 0 RQZ/1 RQZ/2 RQZ/3 RQZ/4 RQZ/5 RQZ/6 RQZ/7
- static const uint8_t rtt_nom_map[8] = { 0, 0b100, 0b010, 0b110, 0b001, 0b101, 0b011, 0b111 };
-
- uint8_t l_dll_enable = 0;
- uint8_t l_odic = 0;
- uint8_t l_wl_enable = 0;
- uint8_t l_tdqs = 0;
- uint8_t l_qoff = 0;
- uint8_t l_rtt_nom[MAX_RANK_PER_DIMM] = {0};
-
- size_t l_rtt_nom_index = 0;
-
- fapi2::buffer<uint8_t> l_additive_latency;
- fapi2::buffer<uint8_t> l_odic_buffer;
- fapi2::buffer<uint8_t> l_rtt_nom_buffer;
-
- FAPI_TRY( mss::eff_dram_dll_enable(i_target, l_dll_enable) );
- FAPI_TRY( mss::eff_dram_ron(i_target, l_odic) );
- FAPI_TRY( mss::eff_dram_al(i_target, l_additive_latency) );
- FAPI_TRY( mss::eff_dram_wr_lvl_enable(i_target, l_wl_enable) );
- FAPI_TRY( mss::eff_dram_rtt_nom(i_target, &(l_rtt_nom[0])) );
- FAPI_TRY( mss::eff_dram_tdqs(i_target, l_tdqs) );
- FAPI_TRY( mss::eff_dram_output_buffer(i_target, l_qoff) );
-
- // Map from impedance to bits in MRS1
- l_odic_buffer = (l_odic == fapi2::ENUM_ATTR_EFF_DRAM_RON_OHM34) ? odic_map[0] : odic_map[1];
-
- // We have to be careful about 0
- l_rtt_nom_index = (l_rtt_nom[mss::index(i_rank)] == 0) ?
- 0 : fapi2::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM240 / l_rtt_nom[mss::index(i_rank)];
-
- // Map from RTT_NOM array to the value in the map
- l_rtt_nom_buffer = rtt_nom_map[l_rtt_nom_index];
-
- FAPI_INF("MR1 rank %d attributes: DLL_ENABLE: 0x%x, ODIC: 0x%x(0x%x), AL: 0x%x, WLE: 0x%x, "
- "RTT_NOM: 0x%x(0x%x), TDQS: 0x%x, QOFF: 0x%x", i_rank,
- l_dll_enable, l_odic, uint8_t(l_odic_buffer), uint8_t(l_additive_latency), l_wl_enable,
- l_rtt_nom[mss::index(i_rank)], uint8_t(l_rtt_nom_buffer), l_tdqs, l_qoff);
-
- io_inst.arr0.writeBit<A0>(l_dll_enable);
- mss::swizzle<A1, 2, 7>(l_odic_buffer, io_inst.arr0);
- mss::swizzle<A3, 2, 7>(l_additive_latency, io_inst.arr0);
- io_inst.arr0.writeBit<A7>(l_wl_enable);
- mss::swizzle<A8, 3, 7>(l_rtt_nom_buffer, io_inst.arr0);
- io_inst.arr0.writeBit<A11>(l_tdqs);
- io_inst.arr0.writeBit<A12>(l_qoff);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Given a CCS instruction which contains address bits with an encoded MRS1,
-/// decode and trace the contents
-/// @param[in] i_inst the CCS instruction
-/// @param[in] i_rank ths rank in question
-/// @return void
-///
-static fapi2::ReturnCode ddr4_mrs01_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
- const uint64_t i_rank)
-{
- fapi2::buffer<uint8_t> l_odic;
- fapi2::buffer<uint8_t> l_additive_latency;
- fapi2::buffer<uint8_t> l_rtt_nom;
-
- uint8_t l_dll_enable = i_inst.arr0.getBit<A0>();
- uint8_t l_wrl_enable = i_inst.arr0.getBit<A7>();
- uint8_t l_tdqs = i_inst.arr0.getBit<A11>();
- uint8_t l_qoff = i_inst.arr0.getBit<A12>();
-
- mss::swizzle<6, 2, A2>(i_inst.arr0, l_odic);
- mss::swizzle<6, 2, A4>(i_inst.arr0, l_additive_latency);
- mss::swizzle<5, 3, A10>(i_inst.arr0, l_rtt_nom);
-
- FAPI_INF("MR1 rank %d decode: DLL_ENABLE: 0x%x, ODIC: 0x%x, AL: 0x%x, WLE: 0x%x, "
- "RTT_NOM: 0x%x, TDQS: 0x%x, QOFF: 0x%x", i_rank,
- l_dll_enable, uint8_t(l_odic), uint8_t(l_additive_latency), l_wrl_enable, uint8_t(l_rtt_nom),
- l_tdqs, l_qoff);
-
- return FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Given a uint32_t, which contains address bits with an encoded MRS1,
-/// decode and trace the contents
-/// @param[in] i_value ADR 17:0
-/// @return void
-///
-fapi2::ReturnCode ddr4_mrs01_decode(const uint32_t i_value)
-{
- fapi2::buffer<uint32_t> l_data(i_value);
- // Flip l_data so bit 0 is bit 0, bit 17 is bit 17 ...
- reverse(l_data);
-
- fapi2::buffer<uint8_t> l_odic;
- fapi2::buffer<uint8_t> l_additive_latency;
- fapi2::buffer<uint8_t> l_rtt_nom;
-
- uint8_t l_dll_enable = l_data.getBit<A0>();
- uint8_t l_wrl_enable = l_data.getBit<A7>();
- uint8_t l_tdqs = l_data.getBit<A11>();
- uint8_t l_qoff = l_data.getBit<A12>();
-
- mss::swizzle<6, 2, A2>(l_data, l_odic);
- mss::swizzle<6, 2, A4>(l_data, l_additive_latency);
- mss::swizzle<5, 3, A10>(l_data, l_rtt_nom);
-
- FAPI_INF("MR1 buffer decode: DLL_ENABLE: 0x%x, ODIC: 0x%x, AL: 0x%x, WLE: 0x%x, "
- "RTT_NOM: 0x%x, TDQS: 0x%x, QOFF: 0x%x",
- l_dll_enable, uint8_t(l_odic), uint8_t(l_additive_latency), l_wrl_enable, uint8_t(l_rtt_nom),
- l_tdqs, l_qoff);
-
- return FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Configure the ARR0 of the CCS isntruction for mrs02
-/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
-/// @param[in,out] io_inst the instruction to fixup
-/// @param[in] i_rank ths rank in question
-/// @return FAPI2_RC_SUCCESS iff OK
-///
-static fapi2::ReturnCode ddr4_mrs02(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
- const uint64_t i_rank)
-{
- // Index this by subtracting 9 from the CWL attribute value.
- static const uint64_t LOWEST_CWL = 9;
- // 9 10 11 12 14 16 18 20
- static const uint8_t cwl_map[12] = { 0b000, 0b001, 0b010, 0b011, 0, 0b100, 0, 0b101, 0, 0b110, 0, 0b111 };
-
- fapi2::buffer<uint8_t> l_lpasr;
- uint8_t l_cwl = 0;
- uint8_t l_dram_rtt_wr[MAX_RANK_PER_DIMM] = {0};
- uint8_t l_write_crc = 0;
-
- fapi2::buffer<uint8_t> l_cwl_buffer;
- fapi2::buffer<uint8_t> l_rtt_wr_buffer;
-
- FAPI_TRY( mss::eff_dram_lpasr(i_target, l_lpasr) );
- FAPI_TRY( mss::eff_dram_cwl(i_target, l_cwl) );
- FAPI_TRY( mss::eff_dram_rtt_wr(i_target, &(l_dram_rtt_wr[0])) );
- FAPI_TRY( mss::eff_write_crc(i_target, l_write_crc) );
-
- l_cwl_buffer = cwl_map[l_cwl - LOWEST_CWL];
-
- // Arg. Change this. BRS
- switch (l_dram_rtt_wr[i_rank])
- {
- case fapi2::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE:
- l_rtt_wr_buffer = 0b000;
- break;
-
- case fapi2::ENUM_ATTR_EFF_DRAM_RTT_WR_HIGHZ:
- l_rtt_wr_buffer = 0b011;
- break;
-
- case fapi2::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM240:
- l_rtt_wr_buffer = 0b010;
- break;
-
- case fapi2::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120:
- l_rtt_wr_buffer = 0b001;
- break;
-
- case fapi2::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM60:
- l_rtt_wr_buffer = 0b100;
- break;
-
- default:
- FAPI_ERR("unknown RTT_WR 0x%x (%s rank %d), dynamic odt off",
- l_dram_rtt_wr[i_rank], mss::c_str(i_target), i_rank);
- l_rtt_wr_buffer = 0b000;
- break;
- };
-
- FAPI_INF("MR2 rank %d attributes: LPASR: 0x%x, CWL: 0x%x(0x%x), RTT_WR: 0x%x(0x%x), WRITE_CRC: 0x%x", i_rank,
- uint8_t(l_lpasr), l_cwl, uint8_t(l_cwl_buffer),
- l_dram_rtt_wr[i_rank], uint8_t(l_rtt_wr_buffer), l_write_crc);
-
- mss::swizzle<A3, 3, 7>(l_cwl_buffer, io_inst.arr0);
-
- mss::swizzle<A6, 2, 7>(l_lpasr, io_inst.arr0);
-
- mss::swizzle<A9, 3, 7>(l_rtt_wr_buffer, io_inst.arr0);
-
- io_inst.arr0.writeBit<A12>(l_write_crc);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Given a CCS instruction which contains address bits with an encoded MRS2,
-/// decode and trace the contents
-/// @param[in] i_inst the CCS instruction
-/// @param[in] i_rank ths rank in question
-/// @return void
-///
-static fapi2::ReturnCode ddr4_mrs02_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
- const uint64_t i_rank)
-{
- fapi2::buffer<uint8_t> l_lpasr;
- fapi2::buffer<uint8_t> l_cwl;
- fapi2::buffer<uint8_t> l_rtt_wr;
-
- uint8_t l_write_crc = i_inst.arr0.getBit<A12>();
- mss::swizzle<5, 3, A5>(i_inst.arr0, l_cwl);
- mss::swizzle<6, 2, A7>(i_inst.arr0, l_lpasr);
- mss::swizzle<5, 3, A11>(i_inst.arr0, l_rtt_wr);
-
- FAPI_INF("MR2 rank %d deocode: LPASR: 0x%x, CWL: 0x%x, RTT_WR: 0x%x, WRITE_CRC: 0x%x", i_rank,
- uint8_t(l_lpasr), uint8_t(l_cwl), uint8_t(l_rtt_wr), l_write_crc);
-
- return FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Configure the ARR0 of the CCS isntruction for mrs03
-/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
-/// @param[in,out] io_inst the instruction to fixup
-/// @param[in] i_rank ths rank in question
-/// @return FAPI2_RC_SUCCESS iff OK
-///
-static fapi2::ReturnCode ddr4_mrs03(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
- const uint64_t i_rank)
-{
- // 4 5 6 R
- static const uint8_t crc_wr_latency_map[8] = { 0, 0, 0, 0, 0, 1, 2, 3 };
-
- uint8_t l_mpr_page = 0;
- uint8_t l_geardown = 0;
- uint8_t l_pda = 0;
- uint8_t l_crc_wr_latency = 0;
- uint8_t l_temp_readout = 0;
- uint8_t l_fine_refresh;
-
- fapi2::buffer<uint8_t> l_mpr_mode;
- fapi2::buffer<uint8_t> l_crc_wr_latency_buffer;
- fapi2::buffer<uint8_t> l_read_format;
-
- FAPI_TRY( mss::eff_mpr_mode(i_target, l_mpr_mode) );
- FAPI_TRY( mss::eff_mpr_page(i_target, l_mpr_page) );
- FAPI_TRY( mss::eff_geardown_mode(i_target, l_geardown) );
- FAPI_TRY( mss::eff_per_dram_access(i_target, l_pda) );
- FAPI_TRY( mss::eff_temp_readout(i_target, l_temp_readout) );
- FAPI_TRY( mss::mrw_fine_refresh_mode(l_fine_refresh) );
- FAPI_TRY( mss::eff_crc_wr_latency(i_target, l_crc_wr_latency) );
- FAPI_TRY( mss::eff_mpr_rd_format(i_target, l_read_format) );
-
- l_crc_wr_latency_buffer = crc_wr_latency_map[l_crc_wr_latency];
-
- FAPI_INF("MR3 rank %d attributes: MPR_MODE: 0x%x, MPR_PAGE: 0x%x, GD: 0x%x, PDA: 0x%x, "
- "TEMP: 0x%x FR: 0x%x, CRC_WL: 0x%x(0x%x), RF: 0x%x", i_rank,
- uint8_t(l_mpr_mode), l_mpr_page, l_geardown, l_pda, l_temp_readout,
- uint8_t(l_fine_refresh), l_crc_wr_latency, uint8_t(l_crc_wr_latency_buffer),
- uint8_t(l_read_format));
-
- mss::swizzle<A0, 2, 7>(l_mpr_mode, io_inst.arr0);
- io_inst.arr0.writeBit<A2>(l_mpr_page);
- io_inst.arr0.writeBit<A3>(l_geardown);
- io_inst.arr0.writeBit<A4>(l_pda);
- io_inst.arr0.writeBit<A5>(l_temp_readout);
-
- mss::swizzle<A6 , 3, 7>(fapi2::buffer<uint8_t>(l_fine_refresh), io_inst.arr0);
- mss::swizzle<A9 , 2, 7>(l_crc_wr_latency_buffer, io_inst.arr0);
- mss::swizzle<A11, 2, 7>(l_read_format, io_inst.arr0);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Given a CCS instruction which contains address bits with an encoded MRS3,
-/// decode and trace the contents
-/// @param[in] i_inst the CCS instruction
-/// @param[in] i_rank ths rank in question
-/// @return void
-///
-static fapi2::ReturnCode ddr4_mrs03_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
- const uint64_t i_rank)
-{
- fapi2::buffer<uint8_t> l_mpr_mode;
-
- fapi2::buffer<uint8_t> l_fine_refresh;
- fapi2::buffer<uint8_t> l_crc_wr_latency_buffer;
- fapi2::buffer<uint8_t> l_read_format;
-
- uint8_t l_mpr_page = i_inst.arr0.getBit<A2>();
- uint8_t l_geardown = i_inst.arr0.getBit<A3>();
- uint8_t l_pda = i_inst.arr0.getBit<A4>();
- uint8_t l_temp_readout = i_inst.arr0.getBit<A5>();
-
- mss::swizzle<6, 2, A1>(i_inst.arr0, l_mpr_mode);
- mss::swizzle<5, 3, A7>(i_inst.arr0, l_fine_refresh);
- mss::swizzle<6, 2, A10>(i_inst.arr0, l_crc_wr_latency_buffer);
- mss::swizzle<6, 2, A12>(i_inst.arr0, l_read_format);
-
- FAPI_INF("MR3 rank %d decode: MPR_MODE: 0x%x, MPR_PAGE: 0x%x, GD: 0x%x, PDA: 0x%x, "
- "TEMP: 0x%x FR: 0x%x, CRC_WL: 0x%x, RF: 0x%x", i_rank,
- uint8_t(l_mpr_mode), l_mpr_page, l_geardown, l_pda, uint8_t(l_temp_readout),
- uint8_t(l_fine_refresh), uint8_t(l_crc_wr_latency_buffer), uint8_t(l_read_format));
-
- return FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Configure the ARR0 of the CCS isntruction for mrs04
-/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
-/// @param[in,out] io_inst the instruction to fixup
-/// @param[in] i_rank ths rank in question
-/// @return FAPI2_RC_SUCCESS iff OK
-///
-static fapi2::ReturnCode ddr4_mrs04(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
- const uint64_t i_rank)
-{
- // 0 3 4 5 6 8
- static const uint8_t cs_cmd_latency_map[9] = { 0b000, 0, 0, 0b001, 0b010, 0b011, 0b100, 0, 0b101 };
-
- uint8_t l_max_pd_mode = 0;
- uint8_t l_temp_refresh_range = 0;
- uint8_t l_temp_ref_mode = 0;
- uint8_t l_vref_mon = 0;
- uint8_t l_cs_cmd_latency = 0;
- uint8_t l_ref_abort = 0;
- uint8_t l_rd_pre_train_mode = 0;
- uint8_t l_rd_preamble = 0;
- uint8_t l_wr_preamble = 0;
- uint8_t l_ppr = 0;
-
- fapi2::buffer<uint8_t> l_cs_cmd_latency_buffer;
-
- FAPI_TRY( mss::eff_max_powerdown_mode(i_target, l_max_pd_mode) );
- FAPI_TRY( mss::mrw_temp_refresh_range(l_temp_refresh_range) );
- FAPI_TRY( mss::eff_temp_refresh_mode(i_target, l_temp_ref_mode) );
- FAPI_TRY( mss::eff_internal_vref_monitor(i_target, l_vref_mon) );
- FAPI_TRY( mss::eff_cs_cmd_latency(i_target, l_cs_cmd_latency) );
- FAPI_TRY( mss::eff_self_ref_abort(i_target, l_ref_abort) );
- FAPI_TRY( mss::eff_rd_preamble_train(i_target, l_rd_pre_train_mode) );
- FAPI_TRY( mss::eff_rd_preamble(i_target, l_rd_preamble) );
- FAPI_TRY( mss::eff_wr_preamble(i_target, l_wr_preamble) );
- FAPI_TRY( mss::eff_dram_ppr(i_target, l_ppr) );
-
- l_cs_cmd_latency_buffer = cs_cmd_latency_map[l_cs_cmd_latency];
-
- FAPI_INF("MR4 rank %d attributes: MAX_PD: 0x%x, TEMP_REFRESH_RANGE: 0x%x, TEMP_REF_MODE: 0x%x "
- "VREF_MON: 0x%x, CSL: 0x%x(0x%x), REF_ABORT: 0x%x, RD_PTM: 0x%x, RD_PRE: 0x%x, "
- "WR_PRE: 0x%x, PPR: 0x%x", i_rank,
- l_max_pd_mode, l_temp_refresh_range, l_temp_ref_mode, l_vref_mon,
- l_cs_cmd_latency, uint8_t(l_cs_cmd_latency_buffer), l_ref_abort,
- l_rd_pre_train_mode, l_rd_preamble, l_wr_preamble, l_ppr);
-
- io_inst.arr0.writeBit<A1>(l_max_pd_mode);
- io_inst.arr0.writeBit<A2>(l_temp_refresh_range);
- io_inst.arr0.writeBit<A3>(l_temp_ref_mode);
- io_inst.arr0.writeBit<A4>(l_vref_mon);
-
- mss::swizzle<A6, 3, 7>(l_cs_cmd_latency_buffer, io_inst.arr0);
- io_inst.arr0.writeBit<A9>(l_ref_abort);
- io_inst.arr0.writeBit<A10>(l_rd_pre_train_mode);
- io_inst.arr0.writeBit<A11>(l_rd_preamble);
- io_inst.arr0.writeBit<A12>(l_wr_preamble);
- io_inst.arr0.writeBit<A13>(l_ppr);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Given a CCS instruction which contains address bits with an encoded MRS4,
-/// decode and trace the contents
-/// @param[in] i_inst the CCS instruction
-/// @param[in] i_rank ths rank in question
-/// @return void
-///
-static fapi2::ReturnCode ddr4_mrs04_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
- const uint64_t i_rank)
-{
- uint8_t l_max_pd_mode = i_inst.arr0.getBit<A1>();
- uint8_t l_temp_refresh_range = i_inst.arr0.getBit<A2>();
- uint8_t l_temp_ref_mode = i_inst.arr0.getBit<A3>();
- uint8_t l_vref_mon = i_inst.arr0.getBit<A4>();
-
- fapi2::buffer<uint8_t> l_cs_cmd_latency_buffer;
- mss::swizzle<5, 3, A8>(i_inst.arr0, l_cs_cmd_latency_buffer);
-
- uint8_t l_ref_abort = i_inst.arr0.getBit<A9>();
- uint8_t l_rd_pre_train_mode = i_inst.arr0.getBit<A10>();
- uint8_t l_rd_preamble = i_inst.arr0.getBit<A11>();
- uint8_t l_wr_preamble = i_inst.arr0.getBit<A12>();
- uint8_t l_ppr = i_inst.arr0.getBit<A13>();
-
- FAPI_INF("MR4 rank %d decode: MAX_PD: 0x%x, TEMP_REFRESH_RANGE: 0x%x, TEMP_REF_MODE: 0x%x "
- "VREF_MON: 0x%x, CSL: 0x%x, REF_ABORT: 0x%x, RD_PTM: 0x%x, RD_PRE: 0x%x, "
- "WR_PRE: 0x%x, PPR: 0x%x", i_rank,
- l_max_pd_mode, l_temp_refresh_range, l_temp_ref_mode, l_vref_mon,
- uint8_t(l_cs_cmd_latency_buffer), l_ref_abort,
- l_rd_pre_train_mode, l_rd_preamble, l_wr_preamble, l_ppr);
-
- return FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Configure the ARR0 of the CCS isntruction for mrs05
-/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
-/// @param[in,out] io_inst the instruction to fixup
-/// @param[in] i_rank ths rank in question
-/// @return FAPI2_RC_SUCCESS iff OK
-///
-static fapi2::ReturnCode ddr4_mrs05(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
- const uint64_t i_rank)
-{
- // 0 4 5 6 8
- static const uint8_t ca_parity_latency_map[9] = { 0b000, 0, 0, 0, 0b001, 0b010, 0b011, 0, 0b100 };
-
- // Indexed by denominator. So, if RQZ is 240, and you have OHM240, then you're looking
- // for index 1. So this doesn't correspond directly with the table in the JEDEC spec,
- // as that's not in "denominator order."
- // 0 RQZ/1 RQZ/2 RQZ/3 RQZ/4 RQZ/5 RQZ/6 RQZ/7
- static const uint8_t rtt_park_map[8] = { 0, 0b100, 0b010, 0b110, 0b001, 0b101, 0b011, 0b111 };
-
- uint8_t l_ca_parity_latency = 0;
- uint8_t l_crc_error_clear = 0;
- uint8_t l_ca_parity_error_status = 0;
- uint8_t l_odt_input_buffer = 0;
- uint8_t l_rtt_park[MAX_RANK_PER_DIMM] = {0};
- uint8_t l_ca_parity = 0;
- uint8_t l_data_mask = 0;
- uint8_t l_write_dbi = 0;
- uint8_t l_read_dbi = 0;
-
- uint8_t l_rtt_park_index = 0;
-
- fapi2::buffer<uint8_t> l_ca_parity_latency_buffer;
- fapi2::buffer<uint8_t> l_rtt_park_buffer;
-
- FAPI_TRY( mss::eff_ca_parity_latency(i_target, l_ca_parity_latency) );
- FAPI_TRY( mss::eff_crc_error_clear(i_target, l_crc_error_clear) );
- FAPI_TRY( mss::eff_ca_parity_error_status(i_target, l_ca_parity_error_status) );
- FAPI_TRY( mss::eff_odt_input_buff(i_target, l_odt_input_buffer) );
-
- FAPI_TRY( mss::eff_rtt_park(i_target, &(l_rtt_park[0])) );
-
- FAPI_TRY( mss::eff_ca_parity(i_target, l_ca_parity) );
- FAPI_TRY( mss::eff_data_mask(i_target, l_data_mask) );
- FAPI_TRY( mss::eff_write_dbi(i_target, l_write_dbi) );
- FAPI_TRY( mss::eff_read_dbi(i_target, l_read_dbi) );
-
- l_ca_parity_latency_buffer = ca_parity_latency_map[l_ca_parity_latency];
-
- // We have to be careful about 0
- l_rtt_park_index = (l_rtt_park[mss::index(i_rank)] == 0) ?
- 0 : fapi2::ENUM_ATTR_EFF_RTT_PARK_240OHM / l_rtt_park[mss::index(i_rank)];
-
- // Map from RTT_NOM array to the value in the map
- l_rtt_park_buffer = rtt_park_map[l_rtt_park_index];
-
- FAPI_INF("MR5 rank %d attributes: CAPL: 0x%x(0x%x), CRC_EC: 0x%x, CA_PES: 0x%x, ODT_IB: 0x%x "
- "RTT_PARK: 0x%x(0x%x), CAP: 0x%x, DM: 0x%x, WDBI: 0x%x, RDBI: 0x%x", i_rank,
- l_ca_parity_latency, uint8_t(l_ca_parity_latency_buffer), l_crc_error_clear,
- l_ca_parity_error_status, l_odt_input_buffer,
- l_rtt_park[mss::index(i_rank)], uint8_t(l_rtt_park_buffer), l_ca_parity,
- l_data_mask, l_write_dbi, l_read_dbi);
-
- mss::swizzle<A0, 3, 7>(l_ca_parity_latency_buffer, io_inst.arr0);
- io_inst.arr0.writeBit<A3>(l_crc_error_clear);
- io_inst.arr0.writeBit<A4>(l_ca_parity_error_status);
- io_inst.arr0.writeBit<A5>(l_odt_input_buffer);
- mss::swizzle<A6, 3, 7>(l_rtt_park_buffer, io_inst.arr0);
- io_inst.arr0.writeBit<A9>(l_ca_parity);
- io_inst.arr0.writeBit<A10>(l_data_mask);
- io_inst.arr0.writeBit<A11>(l_write_dbi);
- io_inst.arr0.writeBit<A12>(l_read_dbi);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Given a CCS instruction which contains address bits with an encoded MRS5,
-/// decode and trace the contents
-/// @param[in] i_inst the CCS instruction
-/// @param[in] i_rank ths rank in question
-/// @return void
-///
-static fapi2::ReturnCode ddr4_mrs05_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
- const uint64_t i_rank)
-{
- fapi2::buffer<uint8_t> l_ca_parity_latency_buffer;
- fapi2::buffer<uint8_t> l_rtt_park_buffer;
-
- mss::swizzle<5, 3, A2>(i_inst.arr0, l_ca_parity_latency_buffer);
- mss::swizzle<5, 3, A8>(i_inst.arr0, l_rtt_park_buffer);
-
- uint8_t l_crc_error_clear = i_inst.arr0.getBit<A3>();
- uint8_t l_ca_parity_error_status = i_inst.arr0.getBit<A4>();
- uint8_t l_odt_input_buffer = i_inst.arr0.getBit<A5>();
-
- uint8_t l_ca_parity = i_inst.arr0.getBit<A9>();
- uint8_t l_data_mask = i_inst.arr0.getBit<A10>();
- uint8_t l_write_dbi = i_inst.arr0.getBit<A11>();
- uint8_t l_read_dbi = i_inst.arr0.getBit<A12>();
-
- FAPI_INF("MR5 rank %d decode: CAPL: 0x%x, CRC_EC: 0x%x, CA_PES: 0x%x, ODT_IB: 0x%x "
- "RTT_PARK: 0x%x, CAP: 0x%x, DM: 0x%x, WDBI: 0x%x, RDBI: 0x%x", i_rank,
- uint8_t(l_ca_parity_latency_buffer), l_crc_error_clear, l_ca_parity_error_status,
- l_odt_input_buffer, uint8_t(l_rtt_park_buffer), l_ca_parity, l_data_mask,
- l_write_dbi, l_read_dbi);
-
- return FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Configure the ARR0 of the CCS isntruction for mrs06
-/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
-/// @param[in,out] io_inst the instruction to fixup
-/// @param[in] i_rank ths rank in question
-/// @return FAPI2_RC_SUCCESS iff OK
-///
-static fapi2::ReturnCode ddr4_mrs06(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
- const uint64_t i_rank)
-{
- // 4 5 6 7 8
- static const uint8_t tccd_l_map[9] = { 0, 0, 0, 0, 0b000, 0b001, 0b010, 0b011, 0b100 };
-
- uint8_t l_vrefdq_train_value[MAX_RANK_PER_DIMM] = {0};
- uint8_t l_vrefdq_train_range[MAX_RANK_PER_DIMM] = {0};
- uint8_t l_vrefdq_train_enable[MAX_RANK_PER_DIMM] = {0};
- uint8_t l_tccd_l = 0;
-
- fapi2::buffer<uint8_t> l_tccd_l_buffer;
- fapi2::buffer<uint8_t> l_vrefdq_train_value_buffer;
-
- FAPI_TRY( mss::eff_vref_dq_train_value(i_target, l_vrefdq_train_value) );
- FAPI_TRY( mss::eff_vref_dq_train_range(i_target, l_vrefdq_train_range) );
- FAPI_TRY( mss::eff_vref_dq_train_enable(i_target, l_vrefdq_train_enable) );
- FAPI_TRY( mss::eff_dram_tccd_l(i_target, l_tccd_l) );
-
- l_tccd_l_buffer = tccd_l_map[l_tccd_l];
- l_vrefdq_train_value_buffer = l_vrefdq_train_value[mss::index(i_rank)];
-
- FAPI_INF("MR6 rank %d attributes: TRAIN_V: 0x%x(0x%x), TRAIN_R: 0x%x, TRAIN_E: 0x%x, TCCD_L: 0x%x(0x%x)", i_rank,
- l_vrefdq_train_value[mss::index(i_rank)], uint8_t(l_vrefdq_train_value_buffer),
- l_vrefdq_train_range[mss::index(i_rank)],
- l_vrefdq_train_enable[mss::index(i_rank)], l_tccd_l, uint8_t(l_tccd_l_buffer));
-
- mss::swizzle<A0, 6, 7>(l_vrefdq_train_value_buffer, io_inst.arr0);
- io_inst.arr0.writeBit<A6>(l_vrefdq_train_range[mss::index(i_rank)]);
- io_inst.arr0.writeBit<A7>(l_vrefdq_train_enable[mss::index(i_rank)]);
- mss::swizzle<A10, 3, 7>(l_tccd_l_buffer, io_inst.arr0);
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Given a CCS instruction which contains address bits with an encoded MRS6,
-/// decode and trace the contents
-/// @param[in] i_inst the CCS instruction
-/// @param[in] i_rank ths rank in question
-/// @return void
-///
-static fapi2::ReturnCode ddr4_mrs06_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
- const uint64_t i_rank)
-{
- fapi2::buffer<uint8_t> l_tccd_l_buffer;
- fapi2::buffer<uint8_t> l_vrefdq_train_value_buffer;
-
- mss::swizzle<2, 6, A5>(i_inst.arr0, l_vrefdq_train_value_buffer);
- uint8_t l_vrefdq_train_range = i_inst.arr0.getBit<A6>();
- uint8_t l_vrefdq_train_enable = i_inst.arr0.getBit<A7>();
- mss::swizzle<5, 3, A12>(i_inst.arr0, l_tccd_l_buffer);
-
- FAPI_INF("MR6 rank %d decode: TRAIN_V: 0x%x, TRAIN_R: 0x%x, TRAIN_E: 0x%x, TCCD_L: 0x%x", i_rank,
- uint8_t(l_vrefdq_train_value_buffer), l_vrefdq_train_range,
- l_vrefdq_train_enable, uint8_t(l_tccd_l_buffer));
-
- return FAPI2_RC_SUCCESS;
-}
-
-///
-/// @brief Perform the mrs_load_ddr4 operations - TARGET_TYPE_DIMM specialization
-/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
-/// @param[in] i_inst a vector of CCS instructions we should add to
-/// @return FAPI2_RC_SUCCESS if and only if ok
-///
-fapi2::ReturnCode mrs_load_ddr4( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& i_inst)
-{
- FAPI_INF("mrs_load_ddr4 %s", mss::c_str(i_target));
-
- // Per DDR4MRS02 table 104 - timing requirements
- static const uint64_t tMRD = 8;
-
- static std::vector< mrs_data<TARGET_TYPE_MCBIST> > l_mrs_data =
- {
- { 0, ddr4_mrs00, ddr4_mrs00_decode, tMRD }, { 1, ddr4_mrs01, ddr4_mrs01_decode, tMRD },
- { 2, ddr4_mrs02, ddr4_mrs02_decode, tMRD }, { 3, ddr4_mrs03, ddr4_mrs03_decode, tMRD },
- { 4, ddr4_mrs04, ddr4_mrs04_decode, tMRD }, { 5, ddr4_mrs05, ddr4_mrs05_decode, tMRD },
- { 6, ddr4_mrs06, ddr4_mrs06_decode, tMRD },
- };
-
- std::vector< uint64_t > l_ranks;
- FAPI_TRY( mss::ranks(i_target, l_ranks) );
-
- for (auto d : l_mrs_data)
- {
- for (auto r : l_ranks)
- {
- // Note: this isn't general - assumes Nimbus via MCBIST instruction here BRS
- ccs::instruction_t<TARGET_TYPE_MCBIST> l_inst_a_side = ccs::mrs_command<TARGET_TYPE_MCBIST>(i_target, r, d.iv_mrs);
- ccs::instruction_t<TARGET_TYPE_MCBIST> l_inst_b_side;
-
- // Thou shalt send 2 MRS, one for the a-side and the other inverted for the b-side.
- // If we're on an odd-rank then we need to mirror
- // So configure the A-side, mirror if necessary and invert for the B-side
- FAPI_TRY( d.iv_func(i_target, l_inst_a_side, r) );
-
- FAPI_TRY( mss::address_mirror(i_target, r, l_inst_a_side) );
- l_inst_b_side = mss::address_invert(l_inst_a_side);
-
- // Not sure if we can get tricky here and only delay after the b-side MR. The question is whether the delay
- // is needed/assumed by the register or is purely a DRAM mandated delay. We know we can't go wrong having
- // both delays but if we can ever confirm that we only need one we can fix this. BRS
- l_inst_a_side.arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES, MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(d.iv_delay);
- l_inst_b_side.arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES, MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(d.iv_delay);
-
- // Dump out the 'decoded' MRS and trace the CCS instructions.
- if (d.iv_dumper != NULL)
- {
- FAPI_TRY( d.iv_dumper(l_inst_a_side, r) );
- }
-
- FAPI_INF("MRS%02d (%d) 0x%016llx:0x%016llx %s:rank %d a-side", uint8_t(d.iv_mrs), d.iv_delay,
- l_inst_a_side.arr0, l_inst_a_side.arr1, mss::c_str(i_target), r);
- FAPI_INF("MRS%02d (%d) 0x%016llx:0x%016llx %s:rank %d b-side", uint8_t(d.iv_mrs), d.iv_delay,
- l_inst_b_side.arr0, l_inst_b_side.arr1, mss::c_str(i_target), r);
-
- // Add both to the CCS program
- i_inst.push_back(l_inst_a_side);
- i_inst.push_back(l_inst_b_side);
- }
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-} // namespace
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load_ddr4.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load_ddr4.H
deleted file mode 100644
index 1878864c4..000000000
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load_ddr4.H
+++ /dev/null
@@ -1,163 +0,0 @@
-/* IBM_PROLOG_BEGIN_TAG */
-/* This is an automatically generated prolog. */
-/* */
-/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/dimm/mrs_load_ddr4.H $ */
-/* */
-/* OpenPOWER HostBoot Project */
-/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
-/* [+] 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 mrs_load_ddr4.H
-/// @brief Code to support mrs_load_ddr4
-///
-// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
-// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
-// *HWP FW Owner: Bill Hoffa <wghoffa@us.ibm.com>
-// *HWP Team: Memory
-// *HWP Level: 1
-// *HWP Consumed by: HB:FSP
-
-#ifndef _MSS_MRS_LOAD_DDR4_H_
-#define _MSS_MRS_LOAD_DDR4_H_
-
-#include <fapi2.H>
-#include <mss.H>
-
-namespace mss
-{
-
-// Map bits in the ARR0 register(s) to MRS address bits. Should be traits related to ARR0. BRS
-enum address_bits
-{
- A0 = 0,
- A1 = 1,
- A2 = 2,
- A3 = 3,
- A4 = 4,
- A5 = 5,
- A6 = 6,
- A7 = 7,
- A8 = 8,
- A9 = 9,
- A10 = 10,
- A11 = 11,
- A12 = 12,
- A13 = 13,
- A14 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_14,
- A15 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_15,
- A16 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_16,
- A17 = MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_17,
-
- // Only kind of address bits ... <shrug>
- BA0 = 17,
- BA1 = 18,
- BG0 = 19,
- BG1 = 15,
-};
-
-///
-/// @brief Perform the mrs_load_ddr4 operations - TARGET_TYPE_DIMM specialization
-/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
-/// @param[in] i_inst a vector of CCS instructions we should add to
-/// @return FAPI2_RC_SUCCESS if and only if ok
-///
-fapi2::ReturnCode mrs_load_ddr4( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& i_inst);
-
-///
-/// @brief Mirror (front to back) the ADR bits of a CCS instruction - implementation
-/// @tparam T typename of the ccs::instruction_t
-/// @param[in, out] io_inst reference to a CCS instruction to be mirrored
-/// @return FAPI2_RC_SUCESS iff ok
-/// @note written this way so this is easier to test
-///
-template<fapi2::TargetType T>
-void address_mirror_impl(ccs::instruction_t<T>& io_inst)
-{
- // Nothing fancy here, just mirror the bits we're told to mirror in Table 14 — Address Mirroring and Inversion
- mss::template swap<A3, A4>(io_inst.arr0);
- mss::template swap<A5, A6>(io_inst.arr0);
- mss::template swap<A7, A8>(io_inst.arr0);
- mss::template swap<A11, A13>(io_inst.arr0);
- mss::template swap<BA0, BA1>(io_inst.arr0);
- mss::template swap<BG0, BG1>(io_inst.arr0);
-}
-
-///
-/// @brief Mirror (front to back) the ADR bits of a CCS instruction
-/// @tparam T typename of the ccs::instruction_t
-/// @param[in] i_target target to use to get mirroring attribute
-/// @param[in] i_rank the rank in question
-/// @param[in, out] io_inst reference to a CCS instruction to be mirrored
-/// @return FAPI2_RC_SUCESS iff ok
-/// @note assumes the input is from an even number rank
-///
-template<fapi2::TargetType T>
-fapi2::ReturnCode address_mirror(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_rank, ccs::instruction_t<T>& io_inst)
-{
- // We only mirror if the mirroring attribute is set.
- uint8_t l_mirror = 0;
- FAPI_TRY( eff_dimm_rcd_mirror_mode(i_target, l_mirror) );
-
- // We only mirror odd ranks.
- if ((l_mirror == fapi2::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_ON) && (i_rank & 0x1))
- {
- address_mirror_impl(io_inst);
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
-/// @brief Invert (side to side) the ADR bits of a CCS instruction
-/// @param[in] i_inst const reference to a CCS instruction.
-/// @return[out] ccs instruction with the ADR bits inverted (side-to-side)
-///
-template<fapi2::TargetType T>
-ccs::instruction_t<T> address_invert(const ccs::instruction_t<T>& i_inst)
-{
- // Copy the input as the output doesn't all change.
- ccs::instruction_t<T> i_out(i_inst);
-
- // Nothing fancy here, just negate the bits we're told to negate in Table 14 — Address Mirroring and Inversion
- mss::template negate<A3>(i_out.arr0);
- mss::template negate<A4>(i_out.arr0);
- mss::template negate<A5>(i_out.arr0);
- mss::template negate<A6>(i_out.arr0);
- mss::template negate<A7>(i_out.arr0);
- mss::template negate<A8>(i_out.arr0);
- mss::template negate<A9>(i_out.arr0);
-
- mss::template negate<A11>(i_out.arr0);
- mss::template negate<A13>(i_out.arr0);
- mss::template negate<A17>(i_out.arr0);
-
- mss::template negate<BA0>(i_out.arr0);
- mss::template negate<BA1>(i_out.arr0);
- mss::template negate<BG0>(i_out.arr0);
- mss::template negate<BG1>(i_out.arr0);
-
- return i_out;
-}
-
-} // namespace
-#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/swizzle.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/swizzle.H
index 2db5dc40c..126b20c27 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/swizzle.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/swizzle.H
@@ -118,7 +118,7 @@ inline fapi2::buffer<DB>& swizzle( fapi2::buffer<SB> i_source, fapi2::buffer<DB>
reverse(i_source);
#ifdef SWIZZLE_TRACE
- FAPI_DBG("swizzle o: 0x%0X s: 0x%X d: 0x%llX ds: %d l: %d ss: %d",
+ FAPI_DBG("swizzle o: 0x%016lx s: 0x%016lx d: 0x%016lx ds: %d l: %d ss: %d",
l_tmp, i_source, o_destination, DS, L, (sizeof(SB) * 8) - (SS + 1));
#endif
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_draminit.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_draminit.xml
index 84cfb1e67..cb76ed4cf 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_draminit.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_draminit.xml
@@ -29,9 +29,8 @@
<!-- -->
<!-- *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com> -->
<!-- *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com> -->
-<!-- *HWP FW Owner: Bill Hoffa <wghoffa@us.ibm.com> -->
<!-- *HWP Team: Memory -->
-<!-- *HWP Level: 1 -->
+<!-- *HWP Level: 2 -->
<!-- *HWP Consumed by: HB:FSP -->
<!-- -->
@@ -57,4 +56,25 @@
</hwpError>
+<hwpError>
+ <rc>RC_MSS_BAD_MR_PARAMETER</rc>
+ <description>
+ A bad parameter was passed to MR processing
+ </description>
+ <ffdc>MR_NUMBER</ffdc>
+ <ffdc>PARAMETER</ffdc>
+ <ffdc>PARAMETER_VALUE</ffdc>
+ <callout>
+ <target>DIMM_IN_ERROR</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_IN_ERROR</target>
+ </deconfigure>
+ <gard>
+ <target>DIMM_IN_ERROR</target>
+ </gard>
+</hwpError>
+
+
</hwpErrors>
OpenPOWER on IntegriCloud