summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory
diff options
context:
space:
mode:
authorJoe McGill <jmcgill@us.ibm.com>2016-12-15 00:12:48 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-01-04 16:34:47 -0500
commit102eab796fbfb6b72d90bcfc4496088066a78575 (patch)
treebc050a4fba8b3f403891cabfa5efb78c37a25689 /src/import/chips/p9/procedures/hwp/memory
parent1265dcb0cdcad11de8849bd9c78334b2d3864b07 (diff)
downloadtalos-hostboot-102eab796fbfb6b72d90bcfc4496088066a78575.tar.gz
talos-hostboot-102eab796fbfb6b72d90bcfc4496088066a78575.zip
Add MSS customization support from CRP0 Lx MVPD
Keyword V0 offsets are the same as V1 Move bad-bits error processing to 1.03 Change-Id: I01e44c83f775b77e4ecc7afd7a5d92db524dfc98 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/34073 Dev-Ready: Joseph J. McGill <jmcgill@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com> Reviewed-by: Martin Gloff <mgloff@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Matt K. Light <mklight@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/34135 Reviewed-by: Hostboot Team <hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C5
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H31
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H154
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H52
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C16
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H53
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_attr_update.C506
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_attr_update.H22
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_attr_update.mk5
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_mc.C6
12 files changed, 720 insertions, 138 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.C b/src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.C
index f03e65e37..7ba8663c1 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/fir/unmask.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -173,7 +173,7 @@ fapi2::ReturnCode after_scominit( const fapi2::Target<TARGET_TYPE_MCBIST>& i_tar
// to Nimbus. If they can be generic,this whole thing can go back in the H file and the specifics
// of the registers and bits can be handled generically.
- for (const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target))
+ for (const auto& p : mss::find_targets_with_magic<TARGET_TYPE_MCA>(i_target))
{
fir::reg<MCA_IOM_PHY0_DDRPHY_FIR_REG> l_mca_fir_reg(p, l_rc);
FAPI_TRY(l_rc, "unable to create fir::reg for %d", MCA_IOM_PHY0_DDRPHY_FIR_REG);
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C
index 1ee2353bb..907655022 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -93,11 +93,14 @@ fapi2::ReturnCode enable_periodic_cal( const fapi2::Target<fapi2::TARGET_TYPE_MC
FAPI_TRY( mss::eff_memcal_interval(i_target, l_memcal_interval) );
FAPI_TRY( mss::eff_zqcal_interval(i_target, l_zqcal_interval) );
+ // TODO RTC: 166433 Leave periodics off (0's) by default for the time being
+#ifdef TODO_166433_PERIODICS
FAPI_TRY( mss::mrw_periodic_memcal_mode_options(l_per_memcal_mode_options) );
FAPI_INF("mrw_periodic_memcal_mode_options: 0x%02x", l_per_memcal_mode_options);
FAPI_TRY( mss::mrw_periodic_zqcal_mode_options(l_per_zqcal_mode_options) );
FAPI_INF("mrw_periodic_zqcal_mode_options: 0x%02x", l_per_memcal_mode_options);
+#endif
// TODO RTC:155854 We haven't done the work for calculating init cal periods
// in effective config yet, and the MC setup below is hard wired for sim
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H
index c5edddf9f..48a75d431 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H
@@ -40,6 +40,7 @@
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>
+#include <lib/mss_attribute_accessors.H>
#include <lib/shared/mss_const.H>
#include <lib/utils/scom.H>
@@ -507,5 +508,35 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief Apply mark store bits from module VPD
+/// @tparam T, the fapi2 target type of the target
+/// @tparam TT, the class traits for the port
+/// @param[in] i_target A target representing a port
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+template< fapi2::TargetType T, typename TT = portTraits<T> >
+fapi2::ReturnCode apply_mark_store( const fapi2::Target<T>& i_target )
+{
+ FAPI_INF("Enable marks from MVPD");
+
+ uint32_t l_fwms[MARK_STORE_COUNT];
+
+ FAPI_TRY( mss::mvpd_fwms(i_target, &(l_fwms[0])) );
+
+ for (size_t l_mark = 0; l_mark < MARK_STORE_COUNT; ++l_mark)
+ {
+ if (l_fwms[l_mark] != 0)
+ {
+ fapi2::buffer<uint64_t> l_fwms_data;
+ l_fwms_data.insertFromRight < MCA_FWMS0_MARK, MCA_FWMS0_EXIT_1 - MCA_FWMS0_MARK + 1 > (l_fwms[l_mark]);
+ FAPI_TRY( mss::putScom(i_target, MCA_FWMS0 + l_mark, l_fwms_data) );
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
}
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H
index 10908f668..73ae873ae 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H
@@ -10380,21 +10380,77 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_VREF_DAC_NIBBLE getter
-/// @param[out] uint8_t& reference to store the value
-/// @note Generated by gen_accessors.pl generateParameters (SYSTEM)
+/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
+/// @param[out] ref to the value uint8_t
+/// @note Generated by gen_accessors.pl generateParameters (D)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Value for VREF DAC
-/// nibbles
+/// nibble
///
-inline fapi2::ReturnCode vref_dac_nibble(uint8_t& o_value)
+inline fapi2::ReturnCode vref_dac_nibble(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, uint8_t& o_value)
{
+ uint8_t l_value[2];
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_VREF_DAC_NIBBLE, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), o_value) );
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_VREF_DAC_NIBBLE, i_target.getParent<fapi2::TARGET_TYPE_MCS>(), l_value) );
+ o_value = l_value[mss::index(i_target)];
return fapi2::current_err;
fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_MSS_VREF_DAC_NIBBLE: 0x%lx (system target)",
- uint64_t(fapi2::current_err));
+ FAPI_ERR("failed accessing ATTR_MSS_VREF_DAC_NIBBLE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_VREF_DAC_NIBBLE getter
+/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[out] ref to the value uint8_t
+/// @note Generated by gen_accessors.pl generateParameters (D.1)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Value for VREF DAC
+/// nibble
+///
+inline fapi2::ReturnCode vref_dac_nibble(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint8_t& o_value)
+{
+ uint8_t l_value[2];
+ auto l_mca = i_target.getParent<fapi2::TARGET_TYPE_MCA>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_VREF_DAC_NIBBLE, l_mca.getParent<fapi2::TARGET_TYPE_MCS>(), l_value) );
+ o_value = l_value[mss::index(l_mca)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_VREF_DAC_NIBBLE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_VREF_DAC_NIBBLE getter
+/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCS>
+/// @param[out] uint8_t* memory to store the value
+/// @note Generated by gen_accessors.pl generateParameters (E)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Value for VREF DAC
+/// nibble
+///
+inline fapi2::ReturnCode vref_dac_nibble(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, uint8_t* o_array)
+{
+ if (o_array == nullptr)
+ {
+ FAPI_ERR("nullptr passed to attribute accessor %s", __func__);
+ return fapi2::FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ uint8_t l_value[2];
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_VREF_DAC_NIBBLE, i_target, l_value) );
+ memcpy(o_array, &l_value, 2);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_VREF_DAC_NIBBLE: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
return fapi2::current_err;
}
@@ -16813,6 +16869,90 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief ATTR_MSS_MVPD_FWMS getter
+/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
+/// @param[out] ref to the value uint32_t
+/// @note Generated by gen_accessors.pl generateParameters (F)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Mark store records from MPVD Lx
+/// keyword
+///
+inline fapi2::ReturnCode mvpd_fwms(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint32_t& o_value)
+{
+ uint32_t l_value[2][8];
+ auto l_mca = i_target.getParent<fapi2::TARGET_TYPE_MCA>();
+ auto l_mcs = l_mca.getParent<fapi2::TARGET_TYPE_MCS>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MVPD_FWMS, l_mcs, l_value) );
+ o_value = l_value[mss::index(l_mca)][mss::index(i_target)];
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_MVPD_FWMS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_MVPD_FWMS getter
+/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
+/// @param[out] uint32_t* memory to store the value
+/// @note Generated by gen_accessors.pl generateParameters (G)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Mark store records from MPVD Lx
+/// keyword
+///
+inline fapi2::ReturnCode mvpd_fwms(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, uint32_t* o_array)
+{
+ if (o_array == nullptr)
+ {
+ FAPI_ERR("nullptr passed to attribute accessor %s", __func__);
+ return fapi2::FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ uint32_t l_value[2][8];
+ auto l_mcs = i_target.getParent<fapi2::TARGET_TYPE_MCS>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MVPD_FWMS, l_mcs, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 32);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_MVPD_FWMS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_MVPD_FWMS getter
+/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCS>
+/// @param[out] uint32_t* memory to store the value
+/// @note Generated by gen_accessors.pl generateParameters (H)
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Mark store records from MPVD Lx
+/// keyword
+///
+inline fapi2::ReturnCode mvpd_fwms(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, uint32_t* o_array)
+{
+ if (o_array == nullptr)
+ {
+ FAPI_ERR("nullptr passed to attribute accessor %s", __func__);
+ return fapi2::FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ uint32_t l_value[2][8];
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MVPD_FWMS, i_target, l_value) );
+ memcpy(o_array, &l_value, 64);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_MVPD_FWMS: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
///
/// @brief ATTR_EFF_DRAM_GEN getter
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H
index d3521a28c..7b77aa04d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -174,31 +174,6 @@ fapi_try_exit:
}
///
-/// @brief ATTR_CHIP_EC_FEATURE_MSS_VCCD_OVERRIDE getter
-/// @tparam T the fapi2 target type of the target
-/// @param[in] const ref to the target
-/// @return bool true iff feature is enabled
-///
-template< fapi2::TargetType T >
-inline bool chip_ec_feature_mss_vccd_override(const fapi2::Target<T>& i_target)
-{
- const auto l_chip = mss::find_target<fapi2::TARGET_TYPE_PROC_CHIP>(i_target);
- uint8_t l_value = 0;
- uint8_t l_do_value = 0;
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_MSS_VCCD_OVERRIDE, l_chip, l_value) );
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_DO_MSS_VCCD_OVERRIDE, l_chip, l_do_value) );
-
- return (l_value != 0) && (l_do_value == fapi2::ENUM_ATTR_DO_MSS_VCCD_OVERRIDE_YES);
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_CHIP_EC_FEATURE_MSS_VCCD_OVERRIDE or ATTR_DO_MSS_VCCD_OVERRIDE: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- fapi2::Assert(false);
- return false;
-}
-
-///
/// @brief ATTR_CHIP_EC_FEATURE_MSS_VREF_DAC getter
/// @tparam T the fapi2 target type of the target
/// @param[in] const ref to the target
@@ -224,31 +199,6 @@ fapi_try_exit:
}
///
-/// @brief ATTR_CHIP_EC_FEATURE_MSS_VREG_COARSE getter
-/// @tparam T the fapi2 target type of the target
-/// @param[in] const ref to the target
-/// @return bool true iff feature is enabled
-///
-template< fapi2::TargetType T >
-inline bool chip_ec_feature_mss_vreg_coarse(const fapi2::Target<T>& i_target)
-{
- const auto l_chip = mss::find_target<fapi2::TARGET_TYPE_PROC_CHIP>(i_target);
- uint8_t l_value = 0;
- uint8_t l_do_value = 0;
-
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_MSS_VREG_COARSE, l_chip, l_value) );
- FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_DO_MSS_VREG_COARSE, l_chip, l_do_value) );
-
- return (l_value != 0) && (l_do_value == fapi2::ENUM_ATTR_DO_MSS_VREG_COARSE_YES);
-
-fapi_try_exit:
- FAPI_ERR("failed accessing ATTR_CHIP_EC_FEATURE_MSS_VREG_COARSE or ATTR_DO_MSS_VREG_COARSE: 0x%lx (target: %s)",
- uint64_t(fapi2::current_err), mss::c_str(i_target));
- fapi2::Assert(false);
- return false;
-}
-
-///
/// @brief ATTR_CHIP_EC_FEATURE_MSS_WAT_DEBUG_ATTN getter
/// @tparam T the fapi2 target type of the target
/// @param[in] const ref to the target
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
index d21083e85..908687495 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -63,6 +63,8 @@ enum sizes
MAX_NUM_CAL_SLEW_RATES = 4, ///< 3V/ns, 4V/ns, 5V/ns, 6V/n
MAX_DQ_BITS = 72, /// TODO RTC:157753 This is Nimbus specific. Should be attribute/trait of processor.
+ MARK_STORE_COUNT = 8, ///< Elements in a VPD mark/store array
+
BYTES_PER_GB = 1000000000, ///< Multiplier to go from GB to B
T_PER_MT = 1000000, ///< Multiplier to go from MT/s to T/s
CYCLES_PER_CMD = 4, ///< Best case cycles per MCBIST command
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C
index de792ba17..90a17d239 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -171,20 +171,6 @@ fapi2::ReturnCode after_phy_reset( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST
std::vector< std::pair<fapi2::buffer<uint64_t>, fapi2::buffer<uint64_t>> > l_vreg_coarse;
std::vector< std::pair<fapi2::buffer<uint64_t>, fapi2::buffer<uint64_t>> > l_vref_cntl;
- // Fix up VREG Coarse
- {
- // Read, modify, write
- FAPI_TRY( mss::scom_suckah(p, TT::DLL_VREG_COARSE_REG, l_vreg_coarse) );
- std::for_each(l_vreg_coarse.begin(), l_vreg_coarse.end(),
- [&p](std::pair<fapi2::buffer<uint64_t>, fapi2::buffer<uint64_t> >& v)
- {
- // Checks for EC level
- v.first = mss::workarounds::dp16::vreg_coarse(p, v.first);
- v.second = mss::workarounds::dp16::vreg_coarse(p, v.second);
- });
- FAPI_TRY( mss::scom_blastah(p, TT::DLL_VREG_COARSE_REG, l_vreg_coarse) );
- }
-
// Fix up vref dac
if (!is_sim)
{
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H
index cb3be6cfa..c7fc99d96 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -150,7 +150,7 @@ inline uint64_t vref_dac( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
// We have an attribute for VREF DAC nibble, if it's 0 then we'll not do anything
uint8_t l_vref_dac_nibble = 0;
- FAPI_TRY( mss::vref_dac_nibble(l_vref_dac_nibble) );
+ FAPI_TRY( mss::vref_dac_nibble(i_target, l_vref_dac_nibble) );
// We want to set the EN_FORCE on no matter what.
l_value.setBit<MCA_DDRPHY_DP16_RD_VREF_BYTE0_DAC_P0_0_01_NIB0_EN_FORCE>()
@@ -178,55 +178,6 @@ fapi_try_exit:
}
///
-/// @brief DP16 VREG Coarse override
-/// In DD1.0 Nimbus VREG Coarse work arounds are needed
-/// @param[in] i_target the port target for this override
-/// @param[in] i_original_value a value to which we add the workaround bits
-/// @return uint64_t the original value with the bits added
-///
-inline uint64_t vreg_coarse( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_original_value )
-{
-
-// Anuwat has asked that we don't enforce this right now.
-#ifdef ANUWAT_SAYS_DONT_DO_THIS_NOW
-
- fapi2::buffer<uint64_t> l_value(i_original_value);
- uint8_t l_vccd_override = 0;
-
- // Check for whether we apply this workaround or not
- if (! mss::chip_ec_feature_mss_vreg_coarse(i_target) )
- {
- return i_original_value;
- }
-
- FAPI_TRY( mss::vccd_override(l_vccd_override) );
-
- if (fapi2::ENUM_ATTR_MSS_VCCD_OVERRIDE_YES == l_vccd_override)
- {
- l_value.insertFromRight<MCA_DDRPHY_ADR_DLL_VREG_COARSE_P0_ADR32S0_ADR0_REGS_RXDLL_DAC,
- MCA_DDRPHY_ADR_DLL_VREG_COARSE_P0_ADR32S0_ADR0_REGS_RXDLL_DAC_LEN>(0b0000100);
- }
-
- FAPI_INF("vref_coarse 0x%016lx, 0x%016lx", i_original_value, uint64_t(l_value));
- return l_value;
-
-fapi_try_exit:
- // Probably bigger problems ...
- FAPI_ERR("Unable to get vccd_override attribute");
- fapi2::Assert(false);
-
- // Not reached
- return 0;
-
-#else
-
- return i_original_value;
-
-#endif
-
-}
-
-///
/// @brief DP16 workarounds to be run after PHY reset
/// In DD1.0 Nimbus various work arounds are needed
/// @param[in] i_target the fapi2 target of the controller
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_attr_update.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_attr_update.C
index b1109e481..283cf49e1 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_attr_update.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_attr_update.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -27,26 +27,518 @@
/// @file p9_mss_attr_update.C
/// @brief Programatic over-rides related to effective config
///
-// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Owner: Joe McGill <jmcgill@us.ibm.com>
// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
#include <fapi2.H>
+#include <mss.H>
+#include <lib/utils/count_dimm.H>
+#include <lib/shared/mss_const.H>
#include <p9_mss_attr_update.H>
using fapi2::TARGET_TYPE_MCS;
+using fapi2::TARGET_TYPE_MCA;
+using fapi2::TARGET_TYPE_PROC_CHIP;
+using fapi2::TARGET_TYPE_MCBIST;
using fapi2::FAPI2_RC_SUCCESS;
+//------------------------------------------------------------------------------
+// Constant definitions
+//------------------------------------------------------------------------------
+
+// expected field size 255B
+constexpr uint32_t CRP0_Lx_RECORD_SIZE_EXP = 255;
+
+// offset of keyword version information
+constexpr uint8_t Lx_VERSION_OFFSET = 0;
+constexpr uint8_t Lx_V1_VALUE = 1;
+constexpr uint8_t Lx_V0_VALUE = 0;
+
+// Lx version 1 parsing/extraction constants
+// group offsets within section
+constexpr uint8_t Lx_V1_S_OFFSET_TO_G0 = 2;
+constexpr uint8_t Lx_V1_S_OFFSET_TO_G1 = 34;
+// data offsets within group (0)
+constexpr uint8_t Lx_V1_G0_OFFSET_TO_VALID = 0;
+constexpr uint8_t Lx_V1_G0_OFFSET_TO_FWMS[mss::MARK_STORE_COUNT] = { 1, 4, 7, 10, 13, 16, 19, 22 };
+constexpr uint8_t Lx_V1_G0_OFFSET_TO_VREF_DAC = 25;
+constexpr uint8_t Lx_V1_G0_OFFSET_TO_VDDR_BIAS = 26;
+// data offsets within group (1)
+constexpr uint8_t Lx_V1_G1_OFFSET_TO_VALID = 0;
+constexpr uint8_t Lx_V1_G1_OFFSET_TO_DPHY_RLO = 1;
+constexpr uint8_t Lx_V1_G1_OFFSET_TO_TSYS_ADR = 2;
+constexpr uint8_t Lx_V1_G1_OFFSET_TO_TSYS_DATA = 3;
+
+//------------------------------------------------------------------------------
+// Function definitions
+//------------------------------------------------------------------------------
+
///
-/// @brief Programatic over-rides related to effective config
+/// @brief Given target and memory frequency, return MVPD Lx keyword and
+/// offset to first byte in frequency-specific customization section
+/// @param[in] i_target the port target (e.g., MCA)
+/// @param[out] o_keyword Lx keyword ID for this port
+/// @param[out] o_s_offset frequency-specific section byte offset
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode
+p9_mss_attr_update_get_lx_offsets(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
+ fapi2::MvpdKeyword& o_keyword,
+ uint8_t& o_s_offset)
+{
+ FAPI_DBG("Start");
+
+ switch( mss::pos(i_target) )
+ {
+ case 0:
+ o_keyword = fapi2::MVPD_KEYWORD_L1;
+ break;
+
+ case 1:
+ o_keyword = fapi2::MVPD_KEYWORD_L2;
+ break;
+
+ case 2:
+ o_keyword = fapi2::MVPD_KEYWORD_L3;
+ break;
+
+ case 3:
+ o_keyword = fapi2::MVPD_KEYWORD_L4;
+ break;
+
+ case 4:
+ o_keyword = fapi2::MVPD_KEYWORD_L5;
+ break;
+
+ case 5:
+ o_keyword = fapi2::MVPD_KEYWORD_L6;
+ break;
+
+ case 6:
+ o_keyword = fapi2::MVPD_KEYWORD_L7;
+ break;
+
+ case 7:
+ o_keyword = fapi2::MVPD_KEYWORD_L8;
+ break;
+
+ default:
+ // Can't actually happen and if it did it's a huge programming error elsewhere.
+ // We test for this in the CI tests, too, to make sure this assertion is a good one.
+ FAPI_ERR("Unknown port position %d in p9_mss_attr_update_get_lx_offsets", mss::pos(i_target));
+ fapi2::Assert(false);
+ break;
+ };
+
+ uint64_t l_freq = 0;
+
+ FAPI_TRY( mss::freq(mss::find_target<TARGET_TYPE_MCBIST>(i_target), l_freq) );
+
+ switch (l_freq)
+ {
+ case (fapi2::ENUM_ATTR_MSS_FREQ_MT2666):
+ o_s_offset = Lx_V1_R_OFFSET_TO_F3S;
+ break;
+
+ case (fapi2::ENUM_ATTR_MSS_FREQ_MT2400):
+ o_s_offset = Lx_V1_R_OFFSET_TO_F2S;
+ break;
+
+ case (fapi2::ENUM_ATTR_MSS_FREQ_MT2133):
+ o_s_offset = Lx_V1_R_OFFSET_TO_F1S;
+ break;
+
+ case (fapi2::ENUM_ATTR_MSS_FREQ_MT1866):
+ o_s_offset = Lx_V1_R_OFFSET_TO_F0S;
+ break;
+
+ default:
+ // Can't actually happen and if it did it's a huge programming error elsewhere.
+ FAPI_ERR("Invalid MSS frequency in p9_mss_attr_update_get_lx_offsets");
+ fapi2::Assert(false);
+ break;
+ }
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Set ATTR_MSS_MVPD_FWMS from MVPD Lx keyword
+/// @param[in] i_target, the port target (e.g., MCA)
+/// @param[in] i_record_data, pointer to VPD keyword data
+/// @parmm[in] i_f_s_offset, byte offset to frequency-specific section
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode
+p9_mss_attr_update_fwms(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
+ const uint8_t* i_record_data,
+ const uint8_t i_f_s_offset)
+{
+ FAPI_DBG("Start");
+
+ // if group is valid, update attribute value associated with this port
+ if (i_record_data[i_f_s_offset +
+ Lx_V1_S_OFFSET_TO_G0 +
+ Lx_V1_G0_OFFSET_TO_VALID])
+ {
+ fapi2::ATTR_MSS_MVPD_FWMS_Type l_fwms;
+ const auto& l_mcs_target = mss::find_target<TARGET_TYPE_MCS>(i_target);
+ const auto l_index = mss::index(i_target);
+
+ // read current attribute value
+ FAPI_TRY( mss::mvpd_fwms(l_mcs_target, &(l_fwms[0][0])) );
+
+ // update attribute value for this port
+ for (size_t l_ms = 0; l_ms < mss::MARK_STORE_COUNT; l_ms++)
+ {
+ uint8_t l_offset_to_fwms =
+ i_f_s_offset + // offset to section
+ Lx_V1_S_OFFSET_TO_G0 + // offset to group
+ Lx_V1_G0_OFFSET_TO_FWMS[l_ms]; // offset to mark
+
+ // clear value, build final value for this index
+ l_fwms[l_index][l_ms] = 0;
+ l_fwms[l_index][l_ms] |= (i_record_data[l_offset_to_fwms++] << 16);
+ l_fwms[l_index][l_ms] |= (i_record_data[l_offset_to_fwms++] << 8);
+ l_fwms[l_index][l_ms] |= (i_record_data[l_offset_to_fwms]);
+ }
+
+ // update attribute value
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_MSS_MVPD_FWMS, l_mcs_target, l_fwms),
+ "Error from FAPI_ATTR_SET (ATTR_MSS_MVPD_FWMS) on target: %s",
+ mss::c_str(l_mcs_target));
+ }
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Set ATTR_MSS_VREF_DAC_NIBBLE from MVPD Lx keyword
+/// @param[in] i_target, the port target (e.g., MCA)
+/// @param[in] i_record_data, pointer to VPD keyword data
+/// @parmm[in] i_f_s_offset, byte offset to frequency-specific section
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode
+p9_mss_attr_update_dac_nibble(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
+ const uint8_t* i_record_data,
+ const uint8_t i_f_s_offset)
+{
+ FAPI_DBG("Start");
+
+ // if group is valid, update attribute value associated with this port
+ if (i_record_data[i_f_s_offset +
+ Lx_V1_S_OFFSET_TO_G0 +
+ Lx_V1_G0_OFFSET_TO_VALID])
+ {
+ fapi2::ATTR_MSS_VREF_DAC_NIBBLE_Type l_vref_dac_nibble;
+ const auto& l_mcs_target = mss::find_target<TARGET_TYPE_MCS>(i_target);
+
+ // read current attribute value
+ FAPI_TRY( mss::vref_dac_nibble(l_mcs_target, l_vref_dac_nibble) );
+
+ // update attribute value for this port
+ l_vref_dac_nibble[mss::index(i_target)] =
+ i_record_data[i_f_s_offset + // offset to section
+ Lx_V1_S_OFFSET_TO_G0 + // offset to group
+ Lx_V1_G0_OFFSET_TO_VREF_DAC]; // offset to data
+
+ // update attribute value
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_MSS_VREF_DAC_NIBBLE, l_mcs_target, l_vref_dac_nibble),
+ "Error from FAPI_ATTR_SET (ATTR_MSS_VREF_DAC_NIBBLE) on target: %s",
+ mss::c_str(l_mcs_target));
+ }
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Set ATTR_MSS_VOLT_VDDR from MVPD Lx keyword
+/// @param[in] i_target, the port target (e.g., MCA)
+/// @param[in] i_record_data, pointer to VPD keyword data
+/// @parmm[in] i_f_s_offset, byte offset to frequency-specific section
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode
+p9_mss_attr_update_vddr(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
+ const uint8_t* i_record_data,
+ const uint8_t i_f_s_offset)
+{
+ FAPI_DBG("Start");
+
+ // if group is valid, update attribute value associated with this port
+ if (i_record_data[i_f_s_offset +
+ Lx_V1_S_OFFSET_TO_G0 +
+ Lx_V1_G0_OFFSET_TO_VALID])
+ {
+ fapi2::ATTR_MSS_VOLT_VDDR_Type l_mss_volt_vddr;
+ const auto& l_mcbist_target = mss::find_target<TARGET_TYPE_MCBIST>(i_target);
+
+ // update attribute value for this port
+ l_mss_volt_vddr =
+ i_record_data[i_f_s_offset + // offset to section
+ Lx_V1_S_OFFSET_TO_G0 + // offset to group
+ Lx_V1_G0_OFFSET_TO_VDDR_BIAS]; // offset to data (byte 0)
+ l_mss_volt_vddr = l_mss_volt_vddr << 8;
+
+ l_mss_volt_vddr |=
+ i_record_data[i_f_s_offset + // offset to section
+ Lx_V1_S_OFFSET_TO_G0 + // offset to group
+ Lx_V1_G0_OFFSET_TO_VDDR_BIAS + 1]; // offset to data (byte 1)
+
+ // update attribute value
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_MSS_VOLT_VDDR, l_mcbist_target, l_mss_volt_vddr),
+ "Error from FAPI_ATTR_SET (ATTR_MSS_VOLT_VDDR) on target: %s",
+ mss::c_str(l_mcbist_target));
+ }
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
+
+
+
+///
+/// @brief Set ATTR_MSS_VPD_MR_DPHY_RLO from MVPD Lx keyword
+/// @param[in] i_target, the port target (e.g., MCA)
+/// @param[in] i_record_data, pointer to VPD keyword data
+/// @parmm[in] i_f_s_offset, byte offset to frequency-specific section
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode
+p9_mss_attr_update_dphy_rlo(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
+ const uint8_t* i_record_data,
+ const uint8_t i_f_s_offset)
+{
+ FAPI_DBG("Start");
+
+ // if group is valid, update attribute value associated with this port
+ if (i_record_data[i_f_s_offset +
+ Lx_V1_S_OFFSET_TO_G0 +
+ Lx_V1_G1_OFFSET_TO_VALID])
+ {
+ fapi2::ATTR_MSS_VPD_MR_DPHY_RLO_Type l_vpd_mr_dphy_rlo;
+ const auto& l_mcs_target = mss::find_target<TARGET_TYPE_MCS>(i_target);
+
+ // read current attribute value
+ FAPI_TRY( mss::vpd_mr_dphy_rlo(l_mcs_target, l_vpd_mr_dphy_rlo) );
+
+ // update attribute value for this port
+ l_vpd_mr_dphy_rlo[mss::index(i_target)] =
+ i_record_data[i_f_s_offset + // offset to section
+ Lx_V1_S_OFFSET_TO_G1 + // offset to group
+ Lx_V1_G1_OFFSET_TO_DPHY_RLO]; // offset to data
+
+ // update attribute value
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MR_DPHY_RLO, l_mcs_target, l_vpd_mr_dphy_rlo),
+ "Error from FAPI_ATTR_SET (ATTR_MSS_VPD_MR_DPHY_RLO) on target: %s",
+ mss::c_str(l_mcs_target));
+ }
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Set ATTR_MSS_VPD_MR_TSYS_ADR from MVPD Lx keyword
+/// @param[in] i_target, the port target (e.g., MCA)
+/// @param[in] i_record_data, pointer to VPD keyword data
+/// @parmm[in] i_f_s_offset, byte offset to frequency-specific section
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode
+p9_mss_attr_update_tsys_adr(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
+ const uint8_t* i_record_data,
+ const uint8_t i_f_s_offset)
+{
+ FAPI_DBG("Start");
+
+ // if group is valid, update attribute value associated with this port
+ if (i_record_data[i_f_s_offset +
+ Lx_V1_S_OFFSET_TO_G0 +
+ Lx_V1_G1_OFFSET_TO_VALID])
+ {
+ fapi2::ATTR_MSS_VPD_MR_TSYS_ADR_Type l_vpd_mr_tsys_adr;
+ const auto& l_mcs_target = mss::find_target<TARGET_TYPE_MCS>(i_target);
+
+ // update attribute value for this port
+ l_vpd_mr_tsys_adr =
+ i_record_data[i_f_s_offset + // offset to section
+ Lx_V1_S_OFFSET_TO_G1 + // offset to group
+ Lx_V1_G1_OFFSET_TO_TSYS_ADR]; // offset to data
+
+ // update attribute value
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MR_TSYS_ADR, l_mcs_target, l_vpd_mr_tsys_adr),
+ "Error from FAPI_ATTR_SET (ATTR_MSS_VPD_MR_TSYS_ADR) on target: %s",
+ mss::c_str(l_mcs_target));
+ }
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Set ATTR_MSS_VPD_MR_TSYS_DATA from MVPD Lx keyword
+/// @param[in] i_target, the port target (e.g., MCA)
+/// @param[in] i_record_data, pointer to VPD keyword data
+/// @parmm[in] i_f_s_offset, byte offset to frequency-specific section
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode
+p9_mss_attr_update_tsys_data(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
+ const uint8_t* i_record_data,
+ const uint8_t i_f_s_offset)
+{
+ FAPI_DBG("Start");
+
+ // if group is valid, update attribute value associated with this port
+ if (i_record_data[i_f_s_offset +
+ Lx_V1_S_OFFSET_TO_G0 +
+ Lx_V1_G1_OFFSET_TO_VALID])
+ {
+ fapi2::ATTR_MSS_VPD_MR_TSYS_DATA_Type l_vpd_mr_tsys_data;
+ const auto& l_mcs_target = mss::find_target<TARGET_TYPE_MCS>(i_target);
+
+ // update attribute value for this port
+ l_vpd_mr_tsys_data =
+ i_record_data[i_f_s_offset + // offset to section
+ Lx_V1_S_OFFSET_TO_G1 + // offset to group
+ Lx_V1_G1_OFFSET_TO_TSYS_DATA]; // offset to data
+
+ // update attribute value
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_MSS_VPD_MR_TSYS_DATA, l_mcs_target, l_vpd_mr_tsys_data),
+ "Error from FAPI_ATTR_SET (ATTR_MSS_VPD_MR_TSYS_DATA) on target: %s",
+ mss::c_str(l_mcs_target));
+ }
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Apply chip specific overrides from module VPD
+/// @param[in] i_target, the port target (e.g., MCA)
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode
+p9_mss_attr_update_lx_mvpd(const fapi2::Target<TARGET_TYPE_MCA>& i_target)
+{
+ FAPI_INF("Start");
+
+ uint32_t l_keyword_size;
+ uint8_t l_keyword_data[CRP0_Lx_RECORD_SIZE_EXP];
+ fapi2::MvpdKeyword l_keyword;
+ uint8_t l_section_offset;
+ const auto& l_chip_target = mss::find_target<TARGET_TYPE_PROC_CHIP>(i_target);
+
+ // determine keyword/section offset for lookup
+ FAPI_TRY(p9_mss_attr_update_get_lx_offsets(i_target, l_keyword, l_section_offset),
+ "Error from p9_mss_attr_update_lx_mvpd_offsets");
+
+ // check VPD field size
+ FAPI_TRY(fapi2::getMvpdField(fapi2::MVPD_RECORD_CRP0,
+ l_keyword,
+ l_chip_target,
+ NULL,
+ l_keyword_size),
+ "Error from getMvpdField (CRP0, keyword:%d, size check) on target: %s",
+ l_keyword, mss::c_str(l_chip_target));
+
+ FAPI_ASSERT(l_keyword_size == CRP0_Lx_RECORD_SIZE_EXP,
+ fapi2::P9_MSS_ATTR_UPDATE_MVPD_READ_ERR()
+ .set_TARGET(l_chip_target)
+ .set_KEYWORD_SIZE(l_keyword_size),
+ "Invalid CRP0 keyword:%d record size (%s)",
+ l_keyword, mss::c_str(l_chip_target));
+
+ // retrieve data
+ FAPI_TRY(fapi2::getMvpdField(fapi2::MVPD_RECORD_CRP0,
+ l_keyword,
+ l_chip_target,
+ l_keyword_data,
+ l_keyword_size),
+ "Error from getMvpdField (CRP0, keyword:%d, retrieval) on target: %s",
+ l_keyword, mss::c_str(l_chip_target));
+
+ // check version number. currently v0 == v1, so we check for either and make sure we
+ // use the V1 offsets.
+ FAPI_ASSERT(((l_keyword_data[Lx_VERSION_OFFSET] == Lx_V0_VALUE) ||
+ (l_keyword_data[Lx_VERSION_OFFSET] == Lx_V1_VALUE)),
+ fapi2::P9_MSS_ATTR_UPDATE_MVPD_VERSION_ERR().
+ set_TARGET(l_chip_target).
+ set_VERSION(l_keyword_data[Lx_VERSION_OFFSET]),
+ "Invalid CRP0 keyword:%d record version: %02X (%s)",
+ l_keyword, l_keyword_data[Lx_VERSION_OFFSET], mss::c_str(l_chip_target));
+
+ // update from frequency specific areas
+ FAPI_TRY(p9_mss_attr_update_fwms(i_target, l_keyword_data, l_section_offset),
+ "Error from p9_mss_attr_update_fwms");
+ FAPI_TRY(p9_mss_attr_update_dac_nibble(i_target, l_keyword_data, l_section_offset),
+ "Error from p9_mss_attr_update_dac_nibble");
+ FAPI_TRY(p9_mss_attr_update_vddr(i_target, l_keyword_data, l_section_offset),
+ "Error from p9_mss_attr_update_vddr");
+ FAPI_TRY(p9_mss_attr_update_dphy_rlo(i_target, l_keyword_data, l_section_offset),
+ "Error from p9_mss_attr_update_dphy_rlo");
+ FAPI_TRY(p9_mss_attr_update_tsys_adr(i_target, l_keyword_data, l_section_offset),
+ "Error from p9_mss_attr_update_tsys_adr");
+ FAPI_TRY(p9_mss_attr_update_tsys_data(i_target, l_keyword_data, l_section_offset),
+ "Error from p9_mss_attr_update_tsys_data");
+
+fapi_try_exit:
+ FAPI_INF("End");
+ return fapi2::current_err;
+}
+
+
+///
+/// @brief Programatic over-rides related to effective config, including data
+/// from module VPD
/// @param[in] i_target, the controller (e.g., MCS)
/// @return FAPI2_RC_SUCCESS iff ok
///
-fapi2::ReturnCode p9_mss_attr_update( const fapi2::Target<TARGET_TYPE_MCS>& i_target )
+fapi2::ReturnCode
+p9_mss_attr_update(const fapi2::Target<TARGET_TYPE_MCS>& i_target)
{
- FAPI_INF("Start attr update");
- FAPI_INF("End attr update");
- return FAPI2_RC_SUCCESS;
+ FAPI_INF("Start");
+
+ // if there are no DIMM, exit
+ if (mss::count_dimm(i_target) == 0)
+ {
+ FAPI_INF("Seeing no DIMM on %s, no attribute overrides to set", mss::c_str(i_target));
+ return FAPI2_RC_SUCCESS;
+ }
+
+ // apply MPVD overrides per MCA port
+ for (const auto& p : mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target))
+ {
+ FAPI_TRY(p9_mss_attr_update_lx_mvpd(p),
+ "Error from p9_mss_attr_update_lx_mvpd (target: %s)", mss::c_str(p));
+ }
+
+fapi_try_exit:
+ FAPI_INF("End");
+ return fapi2::current_err;
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_attr_update.H b/src/import/chips/p9/procedures/hwp/memory/p9_mss_attr_update.H
index 58eea1ba0..cd4c698c2 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_attr_update.H
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_attr_update.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,8 +38,28 @@
#include <fapi2.H>
+// Lx version 1 parsing/extraction constants
+// section offsets
+constexpr uint8_t Lx_V1_R_OFFSET_TO_F0S = 24;
+constexpr uint8_t Lx_V1_R_OFFSET_TO_F1S = 82;
+constexpr uint8_t Lx_V1_R_OFFSET_TO_F2S = 140;
+constexpr uint8_t Lx_V1_R_OFFSET_TO_F3S = 198;
+
typedef fapi2::ReturnCode (*p9_mss_attr_update_FP_t) (const fapi2::Target<fapi2::TARGET_TYPE_MCS>&);
+// Define some of the helper API so we can test them in CI
+///
+/// @brief Given target and memory frequency, return MVPD Lx keyword and
+/// offset to first byte in frequency-specific customization section
+/// @param[in] i_target the port target (e.g., MCA)
+/// @param[out] o_keyword Lx keyword ID for this port
+/// @param[out] o_s_offset frequency-specific section byte offset
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode p9_mss_attr_update_get_lx_offsets( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ fapi2::MvpdKeyword& o_keyword,
+ uint8_t& o_s_offset);
+
extern "C"
{
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_attr_update.mk b/src/import/chips/p9/procedures/hwp/memory/p9_mss_attr_update.mk
index ed66a0546..b7f29d6a9 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_attr_update.mk
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_attr_update.mk
@@ -5,7 +5,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2015,2016
+# Contributors Listed Below - COPYRIGHT 2015,2017
# [+] International Business Machines Corp.
#
#
@@ -22,5 +22,8 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
+-include 00common.mk
+
PROCEDURE=p9_mss_attr_update
+$(eval $(call ADD_MEMORY_INCDIRS,$(PROCEDURE)))
$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_mc.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_mc.C
index c0995bed0..a3aa5d35d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_mc.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_mc.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -36,6 +36,7 @@
#include <fapi2.H>
#include <mss.H>
+#include <p9_mc_scom_addresses_fld.H>
#include <p9_mss_draminit_mc.H>
#include <lib/fir/unmask.H>
#include <lib/utils/find.H>
@@ -138,6 +139,9 @@ extern "C"
// Step Six: Setup Control Bit ECC
FAPI_TRY( mss::enable_read_ecc(p) );
+
+ // apply marks from MVPD
+ FAPI_TRY( mss::apply_mark_store(p) );
}
// At this point the DDR interface must be monitored for memory errors. Memory related FIRs should be unmasked.
OpenPOWER on IntegriCloud