summaryrefslogtreecommitdiffstats
path: root/src/import
diff options
context:
space:
mode:
authorJacob Harvey <jlharvey@us.ibm.com>2016-08-31 13:55:41 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2016-11-01 11:04:23 -0400
commit6c22f61fc163823ec0ef677c2fce851fe704c466 (patch)
treeec1a6faec8729704de2998b4c5f6c86cf5166b29 /src/import
parente6bca1c97afaea818b8f41a3e39d0eb25910219d (diff)
downloadtalos-hostboot-6c22f61fc163823ec0ef677c2fce851fe704c466.tar.gz
talos-hostboot-6c22f61fc163823ec0ef677c2fce851fe704c466.zip
Implement L2 eff_config_thermal, bulk_pwr_throttle
Implemented p9_mss_bulk_pwr_throttles p9_mss_utils_to_throttles p9_mss_eff_config_thermal Updated throttle xml Change-Id: I0492f9fe8a5bd027ff5875f236711bcf55af88f5 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/31804 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: Brian R. Silver <bsilver@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/31813 Reviewed-by: Hostboot Team <hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Diffstat (limited to 'src/import')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors.H164
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.C73
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H11
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C389
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H164
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/find.H3
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C90
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C12
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C87
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.H8
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_throttle_mem.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C43
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml23
-rwxr-xr-xsrc/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml4
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml2
18 files changed, 760 insertions, 323 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C
index 2feba70b5..15df95deb 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C
@@ -184,7 +184,7 @@ fapi_try_exit:
}// dimm_type
///
-/// @brief Determines & sets effective config for dram_mfg_id type from SPD
+/// @brief Determines & sets effective config for eff_dram_mfg_id type from SPD
/// @param[in] i_target FAPI2 target
/// @return fapi2::FAPI2_RC_SUCCESS if okay
///
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.H
index a85ed96d3..e6f780d88 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.H
@@ -129,7 +129,7 @@ class eff_config
const std::vector<uint8_t>& i_spd_data);
///
- /// @brief Determines & sets effective config for dram_mfg_id type from SPD
+ /// @brief Determines & sets effective config for eff_dram_mfg_id type from SPD
/// @param[in] i_target FAPI2 target
/// @return fapi2::FAPI2_RC_SUCCESS if okay
///
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 e1cb7e4ac..bdf5c4979 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
@@ -5642,16 +5642,16 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
-/// @param[out] ref to the value uint32_t
+/// @param[out] ref to the value uint16_t
/// @note Generated by gen_accessors.pl generateParameters (D)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note This is the throttled N commands per window of M DRAM clocks setting for
/// cfg_nm_n_per_port.
///
inline fapi2::ReturnCode mem_throttled_n_commands_per_port(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- uint32_t& o_value)
+ uint16_t& o_value)
{
- uint32_t l_value[2];
+ uint16_t l_value[2];
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, i_target.getParent<fapi2::TARGET_TYPE_MCS>(),
l_value) );
@@ -5667,16 +5667,16 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
-/// @param[out] ref to the value uint32_t
+/// @param[out] ref to the value uint16_t
/// @note Generated by gen_accessors.pl generateParameters (D.1)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note This is the throttled N commands per window of M DRAM clocks setting for
/// cfg_nm_n_per_port.
///
inline fapi2::ReturnCode mem_throttled_n_commands_per_port(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- uint32_t& o_value)
+ uint16_t& o_value)
{
- uint32_t l_value[2];
+ uint16_t l_value[2];
auto l_mca = i_target.getParent<fapi2::TARGET_TYPE_MCA>();
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, l_mca.getParent<fapi2::TARGET_TYPE_MCS>(),
@@ -5693,14 +5693,14 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCS>
-/// @param[out] uint32_t* memory to store the value
+/// @param[out] uint16_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 This is the throttled N commands per window of M DRAM clocks setting for
/// cfg_nm_n_per_port.
///
inline fapi2::ReturnCode mem_throttled_n_commands_per_port(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,
- uint32_t* o_array)
+ uint16_t* o_array)
{
if (o_array == nullptr)
{
@@ -5708,10 +5708,10 @@ inline fapi2::ReturnCode mem_throttled_n_commands_per_port(const fapi2::Target<f
return fapi2::FAPI2_RC_INVALID_PARAMETER;
}
- uint32_t l_value[2];
+ uint16_t l_value[2];
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, i_target, l_value) );
- memcpy(o_array, &l_value, 8);
+ memcpy(o_array, &l_value, 4);
return fapi2::current_err;
fapi_try_exit:
@@ -5802,16 +5802,16 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
-/// @param[out] ref to the value uint32_t
+/// @param[out] ref to the value uint16_t
/// @note Generated by gen_accessors.pl generateParameters (D)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note This is the throttle numerator setting for
/// cfg_nm_n_per_slot
///
inline fapi2::ReturnCode mem_throttled_n_commands_per_slot(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
- uint32_t& o_value)
+ uint16_t& o_value)
{
- uint32_t l_value[2];
+ uint16_t l_value[2];
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, i_target.getParent<fapi2::TARGET_TYPE_MCS>(),
l_value) );
@@ -5827,16 +5827,16 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
-/// @param[out] ref to the value uint32_t
+/// @param[out] ref to the value uint16_t
/// @note Generated by gen_accessors.pl generateParameters (D.1)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note This is the throttle numerator setting for
/// cfg_nm_n_per_slot
///
inline fapi2::ReturnCode mem_throttled_n_commands_per_slot(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- uint32_t& o_value)
+ uint16_t& o_value)
{
- uint32_t l_value[2];
+ uint16_t l_value[2];
auto l_mca = i_target.getParent<fapi2::TARGET_TYPE_MCA>();
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, l_mca.getParent<fapi2::TARGET_TYPE_MCS>(),
@@ -5853,14 +5853,14 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCS>
-/// @param[out] uint32_t* memory to store the value
+/// @param[out] uint16_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 This is the throttle numerator setting for
/// cfg_nm_n_per_slot
///
inline fapi2::ReturnCode mem_throttled_n_commands_per_slot(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,
- uint32_t* o_array)
+ uint16_t* o_array)
{
if (o_array == nullptr)
{
@@ -5868,10 +5868,10 @@ inline fapi2::ReturnCode mem_throttled_n_commands_per_slot(const fapi2::Target<f
return fapi2::FAPI2_RC_INVALID_PARAMETER;
}
- uint32_t l_value[2];
+ uint16_t l_value[2];
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, i_target, l_value) );
- memcpy(o_array, &l_value, 8);
+ memcpy(o_array, &l_value, 4);
return fapi2::current_err;
fapi_try_exit:
@@ -6710,18 +6710,102 @@ fapi_try_exit:
}
///
+/// @brief ATTR_MSS_DIMM_THERMAL_LIMIT 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 DIMM Max Power based on a thermal limit Decoded from
+/// ATTR_MSS_MRW_THERMAL_POWER_LIMIT
+///
+inline fapi2::ReturnCode dimm_thermal_limit(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, uint32_t& o_value)
+{
+ uint32_t l_value[2][2];
+ 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_DIMM_THERMAL_LIMIT, 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_DIMM_THERMAL_LIMIT: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_DIMM_THERMAL_LIMIT 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 DIMM Max Power based on a thermal limit Decoded from
+/// ATTR_MSS_MRW_THERMAL_POWER_LIMIT
+///
+inline fapi2::ReturnCode dimm_thermal_limit(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][2];
+ auto l_mcs = i_target.getParent<fapi2::TARGET_TYPE_MCS>();
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_DIMM_THERMAL_LIMIT, l_mcs, l_value) );
+ memcpy(o_array, &(l_value[mss::index(i_target)][0]), 8);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_DIMM_THERMAL_LIMIT: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
+/// @brief ATTR_MSS_DIMM_THERMAL_LIMIT 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 DIMM Max Power based on a thermal limit Decoded from
+/// ATTR_MSS_MRW_THERMAL_POWER_LIMIT
+///
+inline fapi2::ReturnCode dimm_thermal_limit(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][2];
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_DIMM_THERMAL_LIMIT, i_target, l_value) );
+ memcpy(o_array, &l_value, 16);
+ return fapi2::current_err;
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_MSS_DIMM_THERMAL_LIMIT: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ return fapi2::current_err;
+}
+
+///
/// @brief ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
-/// @param[out] ref to the value uint32_t
+/// @param[out] ref to the value uint16_t
/// @note Generated by gen_accessors.pl generateParameters (D)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Runtime throttled N commands per M DRAM clocks setting for
/// cfg_nm_n_per_port.
///
inline fapi2::ReturnCode runtime_mem_throttled_n_commands_per_port(const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
- i_target, uint32_t& o_value)
+ i_target, uint16_t& o_value)
{
- uint32_t l_value[2];
+ uint16_t l_value[2];
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT,
i_target.getParent<fapi2::TARGET_TYPE_MCS>(), l_value) );
@@ -6737,16 +6821,16 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
-/// @param[out] ref to the value uint32_t
+/// @param[out] ref to the value uint16_t
/// @note Generated by gen_accessors.pl generateParameters (D.1)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Runtime throttled N commands per M DRAM clocks setting for
/// cfg_nm_n_per_port.
///
inline fapi2::ReturnCode runtime_mem_throttled_n_commands_per_port(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&
- i_target, uint32_t& o_value)
+ i_target, uint16_t& o_value)
{
- uint32_t l_value[2];
+ uint16_t l_value[2];
auto l_mca = i_target.getParent<fapi2::TARGET_TYPE_MCA>();
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT,
@@ -6763,14 +6847,14 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCS>
-/// @param[out] uint32_t* memory to store the value
+/// @param[out] uint16_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 Runtime throttled N commands per M DRAM clocks setting for
/// cfg_nm_n_per_port.
///
inline fapi2::ReturnCode runtime_mem_throttled_n_commands_per_port(const fapi2::Target<fapi2::TARGET_TYPE_MCS>&
- i_target, uint32_t* o_array)
+ i_target, uint16_t* o_array)
{
if (o_array == nullptr)
{
@@ -6778,10 +6862,10 @@ inline fapi2::ReturnCode runtime_mem_throttled_n_commands_per_port(const fapi2::
return fapi2::FAPI2_RC_INVALID_PARAMETER;
}
- uint32_t l_value[2];
+ uint16_t l_value[2];
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT, i_target, l_value) );
- memcpy(o_array, &l_value, 8);
+ memcpy(o_array, &l_value, 4);
return fapi2::current_err;
fapi_try_exit:
@@ -6874,16 +6958,16 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCA>
-/// @param[out] ref to the value uint32_t
+/// @param[out] ref to the value uint16_t
/// @note Generated by gen_accessors.pl generateParameters (D)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Runtime throttle numerator setting for
/// cfg_nm_n_per_slot
///
inline fapi2::ReturnCode runtime_mem_throttled_n_commands_per_slot(const fapi2::Target<fapi2::TARGET_TYPE_MCA>&
- i_target, uint32_t& o_value)
+ i_target, uint16_t& o_value)
{
- uint32_t l_value[2];
+ uint16_t l_value[2];
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
i_target.getParent<fapi2::TARGET_TYPE_MCS>(), l_value) );
@@ -6899,16 +6983,16 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
-/// @param[out] ref to the value uint32_t
+/// @param[out] ref to the value uint16_t
/// @note Generated by gen_accessors.pl generateParameters (D.1)
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Runtime throttle numerator setting for
/// cfg_nm_n_per_slot
///
inline fapi2::ReturnCode runtime_mem_throttled_n_commands_per_slot(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&
- i_target, uint32_t& o_value)
+ i_target, uint16_t& o_value)
{
- uint32_t l_value[2];
+ uint16_t l_value[2];
auto l_mca = i_target.getParent<fapi2::TARGET_TYPE_MCA>();
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
@@ -6925,14 +7009,14 @@ fapi_try_exit:
///
/// @brief ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT getter
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_MCS>
-/// @param[out] uint32_t* memory to store the value
+/// @param[out] uint16_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 Runtime throttle numerator setting for
/// cfg_nm_n_per_slot
///
inline fapi2::ReturnCode runtime_mem_throttled_n_commands_per_slot(const fapi2::Target<fapi2::TARGET_TYPE_MCS>&
- i_target, uint32_t* o_array)
+ i_target, uint16_t* o_array)
{
if (o_array == nullptr)
{
@@ -6940,10 +7024,10 @@ inline fapi2::ReturnCode runtime_mem_throttled_n_commands_per_slot(const fapi2::
return fapi2::FAPI2_RC_INVALID_PARAMETER;
}
- uint32_t l_value[2];
+ uint16_t l_value[2];
FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT, i_target, l_value) );
- memcpy(o_array, &l_value, 8);
+ memcpy(o_array, &l_value, 4);
return fapi2::current_err;
fapi_try_exit:
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.C b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.C
index a6129774a..11da9b2dd 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.C
@@ -115,6 +115,30 @@ fapi2::ReturnCode decoder::generate_encoding()
fapi_try_exit:
return fapi2::current_err;
}
+///
+///@brief a compare functor for the decoder::find_attr functions below
+///@note AND's the input hash with the generated hash from the DIMM to see if they match
+///@note Using an AND instead of == because not all DIMM configs have power slopes, so defaults are needed
+///
+struct is_match
+{
+ ///
+ ///@brief functor constructor
+ ///@param[in] i_gen_key the class object's constructed hash for the installed dimm, to be compared with the attr array
+ ///
+ is_match(const fapi2::buffer<uint32_t> i_gen_key) : iv_gen_key(i_gen_key) {}
+ const fapi2::buffer<uint32_t> iv_gen_key;
+
+ ///
+ ///@brief Boolean compare used for find_if function
+ ///
+ bool operator()(const fapi2::buffer<uint64_t> i_hash)
+ {
+ uint32_t l_temp = 0;
+ i_hash.extractToRight<ENCODING_START, ENCODING_LENGTH>(l_temp);
+ return ((l_temp & iv_gen_key) == iv_gen_key);
+ }
+};
///
/// @brief Finds a value for the power curve slope attributes by matching the generated hashes
@@ -124,27 +148,18 @@ fapi_try_exit:
///
fapi2::ReturnCode decoder::find_slope (const std::vector<fapi2::buffer<uint64_t>>& i_slope)
{
-
- // Comparator lambda expression
- const auto compare = [this](const fapi2::buffer<uint64_t>& i_hash)
- {
- uint32_t l_temp = 0;
- i_hash.extractToRight<ENCODING_START, ENCODING_LENGTH>(l_temp);
- return ((l_temp & iv_gen_key) == iv_gen_key);
- };
-
// Find iterator to matching key (if it exists)
const auto l_value_iterator = std::find_if(i_slope.begin(),
i_slope.end(),
- compare);
+ is_match(iv_gen_key));
- //Should have matched with the all default ATTR at least
+ //Should have matched with the default ATTR value at least
//The last value should always be the default value
FAPI_ASSERT(l_value_iterator != i_slope.end(),
fapi2::MSS_NO_POWER_THERMAL_ATTR_FOUND()
.set_GENERATED_KEY(iv_gen_key)
.set_DIMM_TARGET(iv_kind.iv_target),
- "Couldn't find %s value for generated key:%016lx, for target %s. "
+ "Couldn't find %s value for generated key:%08lx, for target %s. "
"DIMM values for generated key are "
"size is %d, gen is %d, type is %d, width is %d, density %d, stack %d, mfgid %d, dimms %d",
"ATTR_MSS_MRW_POWER_CURVE_SLOPE",
@@ -159,8 +174,8 @@ fapi2::ReturnCode decoder::find_slope (const std::vector<fapi2::buffer<uint64_t>
iv_kind.iv_mfgid,
iv_dimms_per_port);
- (*l_value_iterator).extractToRight<VDDR_START, VDDR_LENGTH>( iv_vddr_slope);
- (*l_value_iterator).extractToRight<TOTAL_START, TOTAL_LENGTH>(iv_total_slope);
+ l_value_iterator->extractToRight<VDDR_START, VDDR_LENGTH>( iv_vddr_slope);
+ l_value_iterator->extractToRight<TOTAL_START, TOTAL_LENGTH>(iv_total_slope);
fapi_try_exit:
return fapi2::current_err;
@@ -174,18 +189,10 @@ fapi_try_exit:
///
fapi2::ReturnCode decoder::find_intercept (const std::vector<fapi2::buffer<uint64_t>>& i_intercept)
{
- // Comparator lambda expression
- const auto compare = [this](const fapi2::buffer<uint64_t>& i_hash)
- {
- uint32_t l_temp = 0;
- i_hash.extractToRight<ENCODING_START, ENCODING_LENGTH>(l_temp);
- return ((l_temp & iv_gen_key) == iv_gen_key);
- };
-
// Find iterator to matching key (if it exists)
const auto l_value_iterator = std::find_if(i_intercept.begin(),
i_intercept.end(),
- compare);
+ is_match(iv_gen_key));
//Should have matched with the all default ATTR at least
//The last value should always be the default value
@@ -193,7 +200,7 @@ fapi2::ReturnCode decoder::find_intercept (const std::vector<fapi2::buffer<uint6
fapi2::MSS_NO_POWER_THERMAL_ATTR_FOUND()
.set_GENERATED_KEY(iv_gen_key)
.set_DIMM_TARGET(iv_kind.iv_target),
- "Couldn't find %s value for generated key:%016lx, for target %s. "
+ "Couldn't find %s value for generated key:%08lx, for target %s. "
"DIMM values for generated key are "
"size is %d, gen is %d, type is %d, width is %d, density %d, stack %d, mfgid %d, dimms %d",
"ATTR_MSS_MRW_POWER_CURVE_INTERCEPT",
@@ -208,8 +215,8 @@ fapi2::ReturnCode decoder::find_intercept (const std::vector<fapi2::buffer<uint6
iv_kind.iv_mfgid,
iv_dimms_per_port);
- (*l_value_iterator).extractToRight<VDDR_START, VDDR_LENGTH>( iv_vddr_intercept);
- (*l_value_iterator).extractToRight<TOTAL_START, TOTAL_LENGTH>(iv_total_intercept);
+ l_value_iterator->extractToRight<VDDR_START, VDDR_LENGTH>( iv_vddr_intercept);
+ l_value_iterator->extractToRight<TOTAL_START, TOTAL_LENGTH>(iv_total_intercept);
fapi_try_exit:
return fapi2::current_err;
@@ -223,18 +230,10 @@ fapi_try_exit:
///
fapi2::ReturnCode decoder::find_thermal_power_limit (const std::vector<fapi2::buffer<uint64_t>>& i_thermal_limits)
{
- // Comparator lambda expression
- const auto compare = [this](const fapi2::buffer<uint64_t>& i_hash)
- {
- uint32_t l_temp = 0;
- i_hash.extractToRight<ENCODING_START, ENCODING_LENGTH>(l_temp);
- return ((l_temp & iv_gen_key) == iv_gen_key);
- };
-
// Find iterator to matching key (if it exists)
const auto l_value_iterator = std::find_if(i_thermal_limits.begin(),
i_thermal_limits.end(),
- compare);
+ is_match(iv_gen_key));
//Should have matched with the all default ATTR at least
//The last value should always be the default value
@@ -242,7 +241,7 @@ fapi2::ReturnCode decoder::find_thermal_power_limit (const std::vector<fapi2::bu
fapi2::MSS_NO_POWER_THERMAL_ATTR_FOUND()
.set_GENERATED_KEY(iv_gen_key)
.set_DIMM_TARGET(iv_kind.iv_target),
- "Couldn't find %s value for generated key:%016lx, for target %s. "
+ "Couldn't find %s value for generated key:%8lx, for target %s. "
"DIMM values for generated key are "
"size is %d, gen is %d, type is %d, width is %d, density %d, stack %d, mfgid %d, dimms %d",
"ATTR_MSS_MRW_THERMAL_POWER_LIMIT",
@@ -257,7 +256,7 @@ fapi2::ReturnCode decoder::find_thermal_power_limit (const std::vector<fapi2::bu
iv_kind.iv_mfgid,
iv_dimms_per_port);
- (*l_value_iterator).extractToRight<THERMAL_POWER_START, THERMAL_POWER_LENGTH>( iv_thermal_power_limit);
+ l_value_iterator->extractToRight<THERMAL_POWER_START, THERMAL_POWER_LENGTH>( iv_thermal_power_limit);
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H
index d7ca5bf71..aa339fd93 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/decoder.H
@@ -41,17 +41,17 @@
#include <lib/utils/count_dimm.H>
namespace mss
{
+
+namespace power_thermal
+{
+
enum size_of_attrs : size_t
{
SIZE_OF_POWER_CURVES_ATTRS = 100,
SIZE_OF_THERMAL_ATTR = 10,
};
-
-namespace power_thermal
-{
//Currently needs to be in sorted order for lookup to work
-
static const std::vector< std::pair<uint32_t , uint8_t> > DIMM_SIZE_MAP =
{
{4, 0b0000},
@@ -162,8 +162,8 @@ enum ATTR_DECODE_INFO
///
class decoder
{
- private:
public:
+
//IVs for all of the attributes per MCS
const mss::dimm::kind iv_kind;
@@ -252,7 +252,6 @@ fapi2::ReturnCode get_power_attrs (const fapi2::Target<fapi2::TARGET_TYPE_MCS>&
uint16_t o_total_slope [PORTS_PER_MCS][MAX_DIMM_PER_PORT],
uint16_t o_total_int [PORTS_PER_MCS][MAX_DIMM_PER_PORT],
uint32_t o_thermal_power [PORTS_PER_MCS][MAX_DIMM_PER_PORT]);
-
///
/// @brief Encode the attribute into a bit encoding
/// @tparam[in] S *ATTR*_SIZE enum used for fapi2::buffer position
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C
index f468ec708..031c846b1 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.C
@@ -23,15 +23,16 @@
/* */
/* IBM_PROLOG_END_TAG */
///
-/// @file eff_config.C
-/// @brief Determine effective config for mss settings
+/// @file throttle.C
+/// @brief Determine throttle settings for memory
///
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB
-
+//std lib
+#include<algorithm>
// fapi2
#include <fapi2.H>
@@ -48,8 +49,6 @@ namespace mss
{
namespace power_thermal
{
-
-
///
/// @brief Constructor
/// @param[in] i_target MCS target to call power thermal stuff on
@@ -63,23 +62,20 @@ throttle::throttle( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_mca, fapi2::R
iv_n_slot(0),
iv_n_port(0),
iv_port_power_limit(0),
- iv_port_maxpower(0),
iv_calc_port_maxpower(0)
{
+ //holder for watt_target to add up for port
uint32_t l_dimm_power_limits [MAX_DIMM_PER_PORT] = {};
-
- FAPI_TRY( mem_throttled_n_commands_per_slot( iv_target, iv_n_slot) );
- FAPI_TRY( mem_throttled_n_commands_per_port( iv_target, iv_n_port) );
- FAPI_TRY( port_maxpower ( iv_target, iv_port_maxpower) );
FAPI_TRY( mrw_max_dram_databus_util(iv_databus_port_max) );
- FAPI_TRY( mrw_dimm_power_curve_percent_uplift( iv_power_uplift) );
- FAPI_TRY( mrw_dimm_power_curve_percent_uplift_idle( iv_power_uplift_idle) );
- //FAPI_TRY( mrw_thermal_memory_power_limit( iv_dimm_thermal_limit) );
-
+ FAPI_TRY( mrw_dimm_power_curve_percent_uplift(iv_power_uplift) );
+ FAPI_TRY( mrw_dimm_power_curve_percent_uplift_idle(iv_power_uplift_idle) );
+ FAPI_TRY( dimm_thermal_limit( iv_target, iv_dimm_thermal_limit) );
+ FAPI_TRY( total_pwr_intercept( iv_target, iv_pwr_int));
+ FAPI_TRY( total_pwr_slope( iv_target, iv_pwr_slope));
FAPI_TRY( runtime_mem_throttled_n_commands_per_slot(iv_target, iv_runtime_n_slot ) );
FAPI_TRY( runtime_mem_throttled_n_commands_per_port(iv_target, iv_runtime_n_port ) );
- FAPI_TRY( mem_watt_target( iv_target, &(l_dimm_power_limits[0])) );
+ FAPI_TRY( mem_watt_target( iv_target, l_dimm_power_limits) );
FAPI_TRY( mrw_mem_m_dram_clocks(iv_m_clocks) );
//Port power limit = sum of dimm power limits
@@ -88,15 +84,35 @@ throttle::throttle( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_mca, fapi2::R
iv_port_power_limit += l_dimm_power_limits[mss::index(l_dimm)];
}
+ FAPI_INF("Setting up throttle for target %s, Values are: max databus is %d, uplifts are %d %d, runtime throttles are %d %d",
+ mss::c_str(iv_target),
+ iv_databus_port_max,
+ iv_power_uplift,
+ iv_power_uplift_idle,
+ iv_runtime_n_slot,
+ iv_runtime_n_port);
+
+ FAPI_INF("The dimm power limit is %d, port power limit is %d, dram clocks are %d, dimm power curve slopes are %d %d,",
+ l_dimm_power_limits[0],
+ iv_port_power_limit,
+ iv_m_clocks,
+ iv_pwr_slope[0],
+ iv_pwr_slope[1]);
+
+ FAPI_INF("DIMM power curve intercepts are %d %d, DIMM power thermal limits are %d %d",
+ iv_pwr_int[0],
+ iv_pwr_int[1],
+ iv_dimm_thermal_limit[0],
+ iv_dimm_thermal_limit[1]);
+
+ o_rc = fapi2::FAPI2_RC_SUCCESS;
FAPI_ASSERT ( (iv_databus_port_max != 0),
fapi2::MSS_NO_DATABUS_UTILIZATION()
.set_PORT_DATABUS_UTIL(iv_databus_port_max)
.set_MCA_TARGET(iv_target),
"Failed to get max databus utilization for target %s",
mss::c_str(iv_target));
- o_rc = fapi2::FAPI2_RC_SUCCESS;
return;
-
fapi_try_exit:
o_rc = fapi2::current_err;
FAPI_ERR("Error getting attributes for mss::power_thermal::throttle ctor");
@@ -113,6 +129,54 @@ fapi_try_exit:
///
fapi2::ReturnCode throttle::power_regulator_throttles ()
{
+ double l_port_power_calc_idle = 0;
+ double l_port_power_calc_max = 0;
+ uint32_t l_port_power_slope = 0;
+ uint32_t l_port_power_int = 0;
+ double l_calc_util_port = 0;
+ double l_databus_dimm_max[MAX_DIMM_PER_PORT] = {};
+ double l_calc_databus_port_idle[MAX_DIMM_PER_PORT] = {IDLE_UTIL, IDLE_UTIL};
+
+ FAPI_INF("Starting power regulator throttles");
+
+ //Decide utilization for each dimm based off of dimm count and power slopes
+ FAPI_TRY( calc_databus(iv_databus_port_max, l_databus_dimm_max));
+
+ //Use the dimm utilizations and dimm power slopes to calculate port min and max power
+ calc_port_power(l_calc_databus_port_idle,
+ l_databus_dimm_max,
+ l_port_power_calc_idle,
+ l_port_power_calc_max);
+ FAPI_INF("POWER calculated port power is %f", l_port_power_calc_max);
+
+ //Calculate the power curve slope and intercept using the port's min and max power values
+ FAPI_TRY(calc_power_curve(l_port_power_calc_idle,
+ l_port_power_calc_max,
+ l_port_power_slope,
+ l_port_power_int));
+
+ FAPI_INF("POWER Port power limit is %d", iv_port_power_limit);
+ //Calculate the port's utilization to get under watt target using the port's calculated slopes
+ calc_util_usage(l_port_power_slope,
+ l_port_power_int,
+ iv_port_power_limit,
+ l_calc_util_port);
+
+ FAPI_INF("POWER calc util port is %f", l_calc_util_port);
+
+ //Calculate the N throttles
+ iv_n_port = power_thermal::throttled_cmds(l_calc_util_port, iv_m_clocks);
+
+ //Set iv_n_slot to the lower value between the slot runtime and iv_n_port
+ iv_n_slot = (iv_runtime_n_slot != 0) ? std::min (iv_n_port, iv_runtime_n_slot) : iv_n_port;
+
+ //Choose the lowest value of the runtime and the calculated
+ iv_n_port = (iv_runtime_n_port != 0) ? std::min (iv_n_port, iv_runtime_n_port) : iv_n_port;
+
+ //Use the throttle value to calculate the power that gets to exactly that value
+ iv_calc_port_maxpower = calc_power_from_n(iv_n_port);
+
+fapi_try_exit:
return fapi2::current_err;
}
@@ -125,12 +189,70 @@ fapi2::ReturnCode throttle::power_regulator_throttles ()
///
fapi2::ReturnCode throttle::thermal_throttles ()
{
+ double l_dimm_power_idle [MAX_DIMM_PER_PORT] = {};
+ double l_dimm_power_max [MAX_DIMM_PER_PORT] = {};
+ uint32_t l_dimm_power_slope [MAX_DIMM_PER_PORT] = {};
+ uint32_t l_dimm_power_int [MAX_DIMM_PER_PORT] = {};
+ double l_calc_util [MAX_DIMM_PER_PORT] = {};
+ uint16_t l_n_slots [MAX_DIMM_PER_PORT] = {};
+ const auto l_count = count_dimm (iv_target);
+
+ //Calculate the dimm power range for each dimm at max utilization for each
+ calc_dimm_power(power_thermal::IDLE_UTIL,
+ iv_databus_port_max,
+ l_dimm_power_idle,
+ l_dimm_power_max);
+
+ //Let's calculate the N throttle for each DIMM
+ for ( const auto& l_dimm : find_targets<TARGET_TYPE_DIMM>(iv_target) )
+ {
+ uint8_t l_pos = mss::index(l_dimm);
+ //Calculate the power curve taking the thermal limit into account
+ FAPI_TRY( calc_power_curve(l_dimm_power_idle[l_pos],
+ l_dimm_power_max[l_pos],
+ l_dimm_power_slope[l_pos],
+ l_dimm_power_int[l_pos]));
+
+ //Calculate the databus utilization at the calculated power curve
+ calc_util_usage(l_dimm_power_slope[l_pos],
+ l_dimm_power_int[l_pos],
+ iv_dimm_thermal_limit[l_pos],
+ l_calc_util[l_pos]);
+
+ FAPI_INF("THERMAL Dimm at pos %d's util is %f", l_pos, l_calc_util[l_pos]);
+
+ l_n_slots[l_pos] = power_thermal::throttled_cmds (l_calc_util[l_pos], iv_m_clocks);
+
+ //Set to the min between the two value
+ //If iv_n_slot == 0 (so uninitialized), set it to the calculated slot value
+ //The l_n_slot value can't be equal to 0 because there's a dimm installed
+ if ((l_n_slots[l_pos] < iv_n_slot) || (iv_n_slot == 0))
+ {
+ iv_n_slot = l_n_slots[l_pos];
+ }
+ }
+
+ //Set to lowest value between calculated and runtime
+ FAPI_INF("THERMAL runtime slot is %d, calc n slot is %d", iv_runtime_n_slot, iv_n_slot);
+ //Taking the min of the SLOT * (# of dimms on the port) and that maximum allowed port throttle (iv_runtime_port)
+ //So it's the min of either to actually utilized to the maximum allowed utilization
+ iv_n_port = std::min(iv_runtime_n_port, uint16_t(iv_n_slot * l_count));
+
+ iv_n_slot = std::min(iv_n_slot, iv_runtime_n_slot);
+
+ //Now time to get and set iv_calc_port_max from the calculated N throttle
+ iv_calc_port_maxpower = calc_power_from_n(iv_n_port);
return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ FAPI_ERR("Error calculating mss::power_thermal::thermal_throttles()");
+ return fapi2::current_err;
}
+
+
///
-/// @brief Calculates the min and max power usage for a port based off of power curves and utilizati
+/// @brief Calculates the min and max power usage for a port based off of power curves and utilizations
/// @param[in] i_idle_util the utilization of the databus in idle mode
/// @param[in] i_max_util the utilization of the port at maximum possible (mrw or calculated)
/// @param[out] o_port_power_idle max value of port power in cW
@@ -138,108 +260,147 @@ fapi2::ReturnCode throttle::thermal_throttles ()
/// @note Called twice in p9_mss_bulk_pwr_throttles
/// @note uses dimm power curves from class variables
///
-void throttle::calc_port_power( const double i_idle_util [MAX_DIMM_PER_PORT],
- const double i_max_util [MAX_DIMM_PER_PORT],
- double& o_port_power_idle,
- double& o_port_power_max)
+void throttle::calc_port_power(const double i_idle_util [MAX_DIMM_PER_PORT],
+ const double i_max_util [MAX_DIMM_PER_PORT],
+ double& o_port_power_idle,
+ double& o_port_power_max)
{
//Playing it safe
o_port_power_idle = 0;
o_port_power_max = 0;
+ FAPI_INF("max util is %f, %f", i_max_util[0], i_max_util[1]);
//Calculate the port power curve info by summing the dimms on the port
for ( const auto& l_dimm : mss::find_targets<TARGET_TYPE_DIMM>(iv_target) )
{
uint32_t l_pos = mss::index(l_dimm);
//Sum up the dim's power to calculate the port power curve
- o_port_power_idle +=
- ( i_idle_util[l_pos] / UTIL_CONVERSION * iv_pwr_slope[l_pos]) + iv_pwr_int[l_pos];
-
- o_port_power_max +=
- ( i_max_util[l_pos] / UTIL_CONVERSION * iv_pwr_slope[l_pos]) + iv_pwr_int[l_pos];
+ o_port_power_idle += calc_power(i_idle_util[l_pos], l_pos);
+ o_port_power_max += calc_power(i_max_util[l_pos], l_pos);
}
//Raise the powers by the uplift percent
- o_port_power_idle *= (1 + (double(iv_power_uplift_idle) / PERCENT_CONVERSION));
- o_port_power_max *= (1 + (double(iv_power_uplift) / PERCENT_CONVERSION));
+ calc_power_uplift(iv_power_uplift_idle, o_port_power_idle);
+ calc_power_uplift(iv_power_uplift, o_port_power_max);
}
///
-/// @brief Calculate the port power curve in order to calculate the port utilization
-/// @paramp[in] i_port_power_calc_idle double of the port's power consumption at idle
-/// @paramp[in] i_port_power_calc_max double of the port's power consumption at max utilization
-/// @paramp[out] o_port_power_slope
-/// @paramp[out] o_port_power_int
+/// @brief Calculates max and min power usages based off of DIMM power curves
+/// @param[in] i_databus_idle idle databus utilization (either calculated or mrw)
+/// @param[in] i_databus_max max databus utilization (either calculated or mrw)
+/// @param[out] o_dimm_power_idle array of dimm power in cW
+/// @param[out] o_dimm_power_max array of dimm power in cW
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
/// @note Called in p9_mss_bulk_pwr_throttles
-/// @note Port power curve needed to calculate the port utilization
+/// @note used for the thermal throttles
///
-fapi2::ReturnCode throttle::calc_port_power_curve (const double& i_port_power_calc_idle,
- const double& i_port_power_calc_max,
- uint32_t& o_port_power_slope,
- uint32_t& o_port_power_int)
+void throttle::calc_dimm_power(const double i_databus_idle,
+ const double i_databus_max,
+ double o_dimm_power_idle [MAX_DIMM_PER_PORT],
+ double o_dimm_power_max [MAX_DIMM_PER_PORT])
{
- double l_denominator = ((double(iv_databus_port_max) / UTIL_CONVERSION) - IDLE_UTIL);
+ for ( const auto& l_dimm : mss::find_targets<TARGET_TYPE_DIMM>(iv_target) )
+ {
+ const uint8_t l_pos = mss::index(l_dimm);
+ o_dimm_power_idle[l_pos] = calc_power(i_databus_idle, l_pos);
+ o_dimm_power_max[l_pos] = calc_power(i_databus_max, l_pos);
- FAPI_ASSERT(l_denominator != 0,
- fapi2::MSS_CALC_PORT_POWER_CURVE_DIVIDE_BY_ZERO().
- set_PORT_DATABUS_UTIL(iv_databus_port_max).
- set_UTIL_CONVERSION(UTIL_CONVERSION).
- set_IDLE_UTIL(IDLE_UTIL),
- "Denominator = (databus(%d) / UTIL_CONVERSION (%d)) - IDLE_UTIL(%d)",
- iv_databus_port_max,
- UTIL_CONVERSION,
- IDLE_UTIL);
+ //Raise the powers by the uplift percent
- o_port_power_slope = (i_port_power_calc_max - i_port_power_calc_idle) / l_denominator;
- o_port_power_int = i_port_power_calc_idle - (o_port_power_slope * IDLE_UTIL);
+ calc_power_uplift(iv_power_uplift_idle, o_dimm_power_idle[l_pos]);
+ calc_power_uplift(iv_power_uplift, o_dimm_power_max[l_pos]);
+ FAPI_INF("Calc_dimm_power: dimm (%d) power max is %f, %f for dimm slope of %d, intercept of %d",
+ l_pos,
+ o_dimm_power_max[l_pos],
+ o_dimm_power_max[l_pos],
+ iv_pwr_slope[l_pos],
+ iv_pwr_int[l_pos]);
+ }
+}
+
+///
+/// @brief Calculate the port power curve in order to calculate the port utilization
+/// @param[in] i_power_idle double of the port's power consumption at idle
+/// @param[in] i_power_max double of the port's power consumption at max utilization
+/// @param[out] o_slope
+/// @param[out] o_int
+/// @note Called in p9_mss_bulk_pwr_throttles
+/// @note Port power curve needed to calculate the port utilization
+///
+fapi2::ReturnCode throttle::calc_power_curve(const double i_power_idle,
+ const double i_power_max,
+ uint32_t& o_slope,
+ uint32_t& o_int)
+{
+ double l_divisor = ((double(iv_databus_port_max) / UTIL_CONVERSION) - IDLE_UTIL);
+ FAPI_ASSERT ((l_divisor != 0),
+ fapi2::MSS_CALC_POWER_CURVE_DIVIDE_BY_ZERO()
+ .set_PORT_DATABUS_UTIL(iv_databus_port_max)
+ .set_UTIL_CONVERSION(UTIL_CONVERSION)
+ .set_IDLE_UTIL(IDLE_UTIL),
+ "Calculated zero for the divisor in calc_power_curve on target %s, the equation is %s",
+ mss::c_str(iv_target),
+ "(double(iv_databus_port_max) / UTIL_CONVERSION) - IDLE_UTIL");
+
+ o_slope = (i_power_max - i_power_idle) / l_divisor;
+ o_int = i_power_idle - (o_slope * IDLE_UTIL);
+ FAPI_INF("Calc_power_curve: power idle is %f, max is %f, slope is %d, int is %d",
+ i_power_idle,
+ i_power_max,
+ o_slope,
+ o_int);
return fapi2::FAPI2_RC_SUCCESS;
fapi_try_exit:
+ FAPI_INF("Error calculating mss::power_thermal::calc_power_curve");
return fapi2::current_err;
+
}
///
-/// @brief Calculate the port's databus utilization given the port's power curve
-/// @paramp[in] i_port_power_slope
-/// @paramp[in] i_port_power_int
-/// @paramp[out] o_port_util the port's databus utilization
+/// @brief Calculate the databus utilization given the power curve
+/// @param[in] i_slope
+/// @param[in] i_int
+/// @param[in] i_power_limit either the port_power_limit or the dimm thermal power limit
+/// @param[out] o_port_util the port's databus utilization
/// @note Called in p9_mss_bulk_pwr_throttles
/// @note Chooses worst case between the maximum allowed databus utilization and the calculated value
-/// @notes makes sure that the utilization isn't 0
///
-void throttle::calc_port_util_usage (const uint32_t& i_port_power_slope,
- const uint32_t& i_port_power_int,
- double& o_port_util)
+void throttle::calc_util_usage(const uint32_t i_slope,
+ const uint32_t i_int,
+ const uint32_t i_power_limit,
+ double& o_util)
{
- o_port_util = (double(iv_port_power_limit) - i_port_power_int) / i_port_power_slope * UTIL_CONVERSION;
- o_port_util = (uint32_t(o_port_util) < iv_databus_port_max) ? o_port_util : iv_databus_port_max;
- o_port_util = (o_port_util == 0) ? 1 : o_port_util;
+ o_util = (double(i_power_limit) - i_int) / i_slope * UTIL_CONVERSION;
+ o_util = (uint32_t(o_util) < iv_databus_port_max) ? o_util : iv_databus_port_max;
+ o_util = (o_util == 0) ? MIN_UTIL : o_util;
}
///
-/// @brief Calculates the power max and idle for each dimm using power curves and databus utilization
-/// @param[out] o_dimm_power_idle double type for precision, the DIMM power limit in idle state (0 utilization)
-/// @param[out] o_dimm_power_max double type for precision, the DIMM power limit at max utilization
-/// @note Called in p9_mss_bulk_pwr_throttle for thermal_throttles, eff_config_thermal
-/// @note power values are as if dimm is alone on port, using port_databus_util_max
+///@brief calculated the output power estimate from the calculated N throttle
+///@param[in] i_n_throttle is the throtte N (address operations) that the power (cW) should be calculated fro
+///@return the power calculated from the uint
///
-void throttle::calc_dimm_power( double o_dimm_power_idle [MAX_DIMM_PER_PORT],
- double o_dimm_power_max [MAX_DIMM_PER_PORT])
+uint32_t throttle::calc_power_from_n (const uint16_t i_n_throttle)
{
- for ( const auto& l_dimm : mss::find_targets<TARGET_TYPE_DIMM>(iv_target) )
- {
- const auto l_pos = mss::index(l_dimm);
+ double l_calc_util;
+ double l_calc_databus_port_max[MAX_DIMM_PER_PORT] = {};
+ double l_calc_databus_port_idle[MAX_DIMM_PER_PORT] = {};
+ double l_port_power_max = 0;
+ double l_port_power_idle = 0;
- o_dimm_power_idle[l_pos] = iv_pwr_int[l_pos];
- o_dimm_power_max[l_pos] = (double(iv_databus_port_max) / UTIL_CONVERSION) * iv_pwr_slope[l_pos] +
- iv_pwr_int[l_pos];
+ l_calc_util = calc_util_from_throttles(i_n_throttle, iv_m_clocks);
+ //Now do everything as port stuff
+ calc_databus(l_calc_util, l_calc_databus_port_max);
- //Raise the powers by the uplift percent
- o_dimm_power_idle[l_pos] *= (1 + (iv_power_uplift_idle / PERCENT_CONVERSION));
- o_dimm_power_max[l_pos] *= (1 + (iv_power_uplift / PERCENT_CONVERSION));
- }
+ calc_port_power(l_calc_databus_port_idle,
+ l_calc_databus_port_max,
+ l_port_power_idle,
+ l_port_power_max);
+
+ return uint32_t(power_thermal::round_up (l_port_power_max));
}
///
@@ -250,7 +411,7 @@ void throttle::calc_dimm_power( double o_dimm_power_idle [MAX_DIMM_PER_PORT],
/// @note Called in p9_mss_bulk_pwr_throttles
/// @used to calculate the port power based off of DIMM power curves
///
-fapi2::ReturnCode throttle::calc_databus( const double& i_databus_port_max,
+fapi2::ReturnCode throttle::calc_databus( const double i_databus_port_max,
double o_databus_dimm_max [MAX_DIMM_PER_PORT])
{
uint8_t l_count_dimms = count_dimm (iv_target);
@@ -267,22 +428,21 @@ fapi2::ReturnCode throttle::calc_databus( const double& i_databus_port_max,
o_databus_dimm_max[mss::index(l_dimm)] = i_databus_port_max / l_count_dimms;
}
- //If not equal power slopes, set the dimm with the highest power slope
- //Should be correct even if only one DIMM installed
+ //If the power slopes aren't equal, set the dimm with the highest power slope
+ //Should be correct even if only one DIMM is installed
if (iv_pwr_slope[0] != iv_pwr_slope[1])
{
o_databus_dimm_max[0] = (iv_pwr_slope[0] > iv_pwr_slope[1]) ? i_databus_port_max : 0;
o_databus_dimm_max[1] = (iv_pwr_slope[1] > iv_pwr_slope[0]) ? i_databus_port_max : 0;
}
- //make sure both aren't equal to 0
+ //make sure both are not 0
FAPI_ASSERT ( (o_databus_dimm_max[0] != 0) || (o_databus_dimm_max[1] != 0),
fapi2::MSS_NO_DATABUS_UTILIZATION()
- .set_PORT_DATABUS_UTIL(iv_databus_port_max)
+ .set_PORT_DATABUS_UTIL(i_databus_port_max)
.set_MCA_TARGET(iv_target),
"Failed to calculated databus utilization for target %s",
mss::c_str(iv_target));
-
fapi_try_exit:
return fapi2::current_err;
}
@@ -291,28 +451,71 @@ fapi_try_exit:
/// @brief Perform thermal calculations as part of the effective configuration
/// @param[in] i_target the MCS target in which the runtime throttles will be reset
/// @return FAPI2_RC_SUCCESS iff ok
-/// TK implement/ will be overun?
///
fapi2::ReturnCode restore_runtime_throttles( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target )
{
- uint32_t l_run_throttles [PORTS_PER_MCS] = {};
+ uint16_t l_run_throttles [MAX_DIMM_PER_PORT] = {};
uint32_t l_max_databus = 0;
- uint32_t l_throttle_m_clocks [PORTS_PER_MCS] = {};
+ uint32_t l_throttle_m_clocks = {};
- FAPI_TRY( runtime_mem_m_dram_clocks(i_target, l_throttle_m_clocks) );
+ FAPI_TRY( mrw_mem_m_dram_clocks(l_throttle_m_clocks) );
FAPI_TRY( mrw_max_dram_databus_util(l_max_databus) );
- for (const auto& l_mca : find_targets<TARGET_TYPE_MCA> (i_target))
+ //set runtime throttles to unthrottled value, using max dram utilization and M throttle
+ //Do I need to check to see if any DIMMS configured on the port?
+ for (const auto& l_mca : find_targets<TARGET_TYPE_MCA>(i_target))
{
- const uint8_t l_pos = mss::index(l_mca);
- l_run_throttles[l_pos] = mss::power_thermal::throttled_cmds(l_max_databus, l_throttle_m_clocks[0]);
+ const auto l_pos = mss::index(l_mca);
+
+ if (mss::count_dimm (l_mca) != 0)
+ {
+ l_run_throttles[l_pos] = mss::power_thermal::throttled_cmds (l_max_databus, l_throttle_m_clocks);
+ }
}
FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT, i_target, l_run_throttles) );
+ FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT, i_target, l_run_throttles) );
fapi_try_exit:
return fapi2::current_err;
}
-}//namespace power_thermal
+///
+/// @brief Update the runtime throttles to the worst case of the general throttle values and the runtime values
+/// @param[in] i_target the MCS target in which the runtime throttles will be set
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode update_runtime_throttles( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >& i_targets )
+{
+ for (const auto& l_mcs : i_targets)
+ {
+ uint16_t l_run_slot [PORTS_PER_MCS] = {};
+ uint16_t l_run_port [PORTS_PER_MCS] = {};
+ uint16_t l_calc_slot [PORTS_PER_MCS] = {};
+ uint16_t l_calc_port [PORTS_PER_MCS] = {};
+
+ FAPI_TRY(runtime_mem_throttled_n_commands_per_slot(l_mcs, l_run_slot));
+ FAPI_TRY(runtime_mem_throttled_n_commands_per_port(l_mcs, l_run_port));
+ FAPI_TRY(mem_throttled_n_commands_per_slot(l_mcs, l_calc_slot));
+ FAPI_TRY(mem_throttled_n_commands_per_port(l_mcs, l_calc_port));
+
+ for (const auto& l_mca : find_targets<TARGET_TYPE_MCA>(l_mcs))
+ {
+ const auto l_pos = mss::index(l_mca);
+ //Choose the worst case between runtime and calculated throttles
+ //Have to make sure the calc_slot isn't equal to 0 though
+ l_run_slot[l_pos] = (l_calc_slot[l_pos] != 0) ? std::min(l_run_slot[l_pos], l_calc_slot[l_pos]) : l_run_slot[l_pos];
+ l_run_port[l_pos] = (l_calc_port[l_pos] != 0) ? std::min(l_run_port[l_pos], l_calc_port[l_pos]) : l_run_port[l_pos];
+ FAPI_INF("New runtime throttles dimm %d for slot are %d, port are %d", l_pos, l_run_slot[l_pos], l_run_port[l_pos]);
+ }
+
+ FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT, l_mcs, l_run_port) );
+ FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT, l_mcs, l_run_slot) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+}//namespace power_thermal
}//namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H
index 3259608ce..876e277a3 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/power_thermal/throttle.H
@@ -46,9 +46,12 @@ enum throttle_const : size_t
{
// Dram data bus utilization is bus utilization / 4
DRAM_BUS_UTILS = 4,
+ //10000 to convert to and from c%
UTIL_CONVERSION = 10000,
PERCENT_CONVERSION = 100,
- MIN_UTIL = 1,
+
+ //MIN_UTIL and IDLE_UTIL are in c%
+ MIN_UTIL = 100,
IDLE_UTIL = 0,
};
///
@@ -58,25 +61,47 @@ enum throttle_const : size_t
class throttle
{
private:
+ ///
+ /// @brief Calculate the power (cW) of inputs and the power curve
+ /// @tparam T
+ /// @param[in] i_util the databus utilization that the power will be based on
+ /// @param[in] l_pos the dimm position for the power value being calculated.
+ /// @return Integral type T
+ ///
+ template<typename T>
+ inline T calc_power (const T i_util, const size_t i_pos)
+ {
+ return ((i_util / UTIL_CONVERSION) * iv_pwr_slope[i_pos]) + iv_pwr_int[i_pos];
+ }
+
+ ///
+ /// @brief Raise the o_value by the percent passed in
+ /// @param[in] i_uplift the percent the o_Value should be raised by
+ /// @param[out] o_value the value that will be modified
+ ///
+ inline void calc_power_uplift (const uint8_t i_uplift, double& o_value)
+ {
+ o_value *= (1 + (double(i_uplift) / PERCENT_CONVERSION));
+ }
public:
const fapi2::Target<fapi2::TARGET_TYPE_MCA>& iv_target;
//dimm level
uint32_t iv_databus_port_max;
+ //TK change thermal limit as well as power curves
uint8_t iv_power_uplift_idle;
uint8_t iv_power_uplift;
- uint32_t iv_runtime_n_slot;
- uint32_t iv_runtime_n_port;
+ uint16_t iv_runtime_n_slot;
+ uint16_t iv_runtime_n_port;
uint32_t iv_m_clocks;
uint32_t iv_dimm_thermal_limit[MAX_DIMM_PER_PORT] = {};
uint16_t iv_pwr_slope[MAX_DIMM_PER_PORT] = {};
uint16_t iv_pwr_int[MAX_DIMM_PER_PORT] = {};
- uint32_t iv_n_slot;
- uint32_t iv_n_port;
+ uint16_t iv_n_slot;
+ uint16_t iv_n_port;
uint32_t iv_port_power_limit;
- uint32_t iv_port_maxpower;
uint32_t iv_calc_port_maxpower;
//default ctor deleted
@@ -95,71 +120,82 @@ class throttle
~throttle() = default;
///
- /// @brief Calculates the min and max power usage for a port based off of power curves and utilizati
+ /// @brief Calculates the min and max power usage for a port
/// @param[in] i_idle_util the utilization of the databus in idle mode
/// @param[in] i_max_util the utilization of the port at maximum possible (mrw or calculated)
/// @param[out] o_port_power_idle max value of port power in cW
/// @param[out] o_port_power_max max value of port power in cW
/// @note Called twice in p9_mss_bulk_pwr_throttles
- /// @note uses dimm power curves from class variables
- ///
- void calc_port_power(const double i_idle_util [MAX_DIMM_PER_PORT],
- const double i_max_util [MAX_DIMM_PER_PORT],
- double& o_port_power_idle,
- double& o_port_power_max);
- ///
- /// @brief Calculate the port power curve in order to calculate the port utilization
- /// @paramp[in] i_port_power_calc_idle double of the port's power consumption at idle
- /// @paramp[in] i_port_power_calc_max double of the port's power consumption at max utilization
- /// @paramp[out] o_port_power_slope
- /// @paramp[out] o_port_power_int
- /// @return FAPI2_RC_SUCCESS iff success
+ ///
+ void calc_port_power( const double i_idle_util [MAX_DIMM_PER_PORT],
+ const double i_max_util [MAX_DIMM_PER_PORT],
+ double& o_port_power_idle,
+ double& o_port_power_max);
+ ///
+ /// @brief Calculates max and min power usages based off of DIMM power curves
+ /// @param[in] i_databus_port_max max databus utilization for the port (either calculated or mrw)
+ /// @param[in] i_port_power_calc_idle double of the port's power consumption at idle
+ /// @param[out] o_dimm_power_idle array of dimm power in cW
+ /// @param[out] o_dimm_power_max array of dimm power in cW
/// @note Called in p9_mss_bulk_pwr_throttles
- /// @note Port power curve needed to calculate the port utilization
+ /// @note used for the thermal throttles
///
- fapi2::ReturnCode calc_port_power_curve(const double& i_port_power_calc_idle,
- const double& i_port_power_calc_max,
- uint32_t& o_port_power_slope,
- uint32_t& o_port_power_int);
+ void calc_dimm_power(const double i_databus_idle,
+ const double i_databus_max,
+ double o_dimm_power_idle [MAX_DIMM_PER_PORT],
+ double o_dimm_power_max [MAX_DIMM_PER_PORT]);
+
///
- /// @brief Calculate the port's databus utilization given the port's power curve
- /// @paramp[in] i_port_power_slope
- /// @paramp[in] i_port_power_int
- /// @paramp[out] o_port_util the port's databus utilization
+ /// @brief Calculate the power curve in order to calculate databus utilization
+ /// @param[in] i_power_idle double of the port's power consumption at idle
+ /// @param[in] i_power_max double of the port's power consumption at max utilization
+ /// @param[out] o_power_slope
+ /// @param[out] o_power_int
+ /// @note Called in p9_mss_bulk_pwr_throttles
+ /// @note Power curve needed to calculate the utilization
+ ///
+ fapi2::ReturnCode calc_power_curve(const double i_power_idle,
+ const double i_power_max,
+ uint32_t& o_power_slope,
+ uint32_t& o_power_int);
+ ///
+ /// @brief Calculate the databus utilization given the power curve
+ /// @param[in] i_slope
+ /// @param[in] i_int
+ /// @param[in] i_power_limit either iv_port_power_limit or thermal_power_limit depending on throttle type
+ /// @param[out] o_port_util the port's databus utilization
/// @note Called in p9_mss_bulk_pwr_throttles
/// @note Chooses worst case between the maximum allowed databus utilization and the calculated value
- /// @notes makes sure that the utilization isn't 0
///
- void calc_port_util_usage(const uint32_t& i_port_power_slope,
- const uint32_t& i_port_power_int,
- double& o_port_util);
-
+ void calc_util_usage(const uint32_t i_slope,
+ const uint32_t i_int,
+ const uint32_t i_power_limit,
+ double& o_util);
///
- /// @brief Calculates the power max and idle for each dimm using power curves and databus utilization
- /// @param[out] o_dimm_power_idle double type for precision, the DIMM power limit in idle state (0 utilization)
- /// @param[out] o_dimm_power_max double type for precision, the DIMM power limit at max utilization
- /// @note Called in p9_mss_bulk_pwr_throttle for thermal_throttles, eff_config_thermal
- /// @note power values are as if dimm is alone on port, using port_databus_util_max
+ ///@brief calculated the output power estimate from the calculated N throttle
+ ///@param[in] i_n_port is the throtte N (address operations) that the power (cW) is be calculated from
+ ///@return the power calculated from the uint
///
- void calc_dimm_power(double o_dimm_power_idle [MAX_DIMM_PER_PORT],
- double o_dimm_power_max [MAX_DIMM_PER_PORT]);
+ uint32_t calc_power_from_n (const uint16_t i_n_port);
+
///
- /// @brief Converts the port maximum databus to a dimm level based on powerslopes and dimms installed
+ /// @brief Converts the port maximum databus util to a dimm level based on powerslopes and dimms installed
/// @param[in] i_databus_port_max max databus utilization for the port (either calculated or mrw)
/// @param[out] o_databus_dimm_max array of dimm utilization values
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff the split is OK
/// @note Called in p9_mss_bulk_pwr_throttles
/// @used to calculate the port power based off of DIMM power curves
///
- fapi2::ReturnCode calc_databus(const double& i_databus_port_max,
- double o_databus_dimm_max [MAX_DIMM_PER_PORT]);
+ fapi2::ReturnCode calc_databus( const double i_databus_port_max,
+ double o_databus_dimm_max [MAX_DIMM_PER_PORT]);
///
- /// @brief Set ATTR_MSS_CHANNEL_PAIR_MAXPOWER and ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
+ /// @brief Calculate ATTR_MSS_CHANNEL_PAIR_MAXPOWER and ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
/// @note Called in p9_mss_bulk_pwr_throttles
- /// @note determines the throttle levels based off of the port's power curve,
- /// sets the slot throttles to the same
+ /// @note determines the throttle levels based off of the port's power curve, max databus utilization,
+ /// and memwat target.
+ /// @note currently sets the slot and port throttles to the same value
///
fapi2::ReturnCode power_regulator_throttles ();
@@ -179,15 +215,16 @@ class throttle
/// @param[in] i_num_dram_clocks window of M DRAM clocks
/// @return number of throttled commands allowed
/// @note Uses N/M Throttling.
-/// Equation: (DRAM data bus utilization Percent / 10000 ) = ((N * M) / 4 )
-/// Equation: N = (DRAM data bus utilization Percent * M) / (4 * 10000)
+/// Equation: N = (DRAM data bus utilization * M) / (4 * 10000)
+///
inline uint32_t throttled_cmds(const uint32_t i_databus_util, const uint32_t i_num_dram_clocks)
{
constexpr uint64_t l_divisor = DRAM_BUS_UTILS * UTIL_CONVERSION;
const uint64_t l_dividend = i_databus_util * i_num_dram_clocks;
const uint64_t l_result = l_dividend / l_divisor;
- return l_result;
+ //Make sure N is not equal to 0, or we brick the dram until reboot
+ return ((l_result == 0) ? 1 : l_result);
}
///
@@ -196,7 +233,7 @@ inline uint32_t throttled_cmds(const uint32_t i_databus_util, const uint32_t i_n
/// @param[in] i_num_dram_clocks window of M DRAM clocks
/// @return number of throttled commands allowed
/// @note Uses N/M Throttling.
-/// Equation: databus utilization = (N * 4 * 100000) / M
+/// @note DRAM databus utilization = N * 4 * 10000 / M
///
inline double calc_util_from_throttles(const uint16_t i_n_throttles, const uint32_t i_num_dram_clocks)
{
@@ -206,12 +243,37 @@ inline double calc_util_from_throttles(const uint16_t i_n_throttles, const uint3
}
///
+/// @brief Determines if the double has decimal digits and adds 1 and rounds if true
+/// @param[in] io_val the double to be rounded up if trialing digits
+/// @return the input value rounded up to the next whole digit
+/// @note Called in p9_mss_bulk_pwr_throttles
+///
+inline uint32_t round_up(double i_val)
+{
+ //convert to uint to truncate decimals and convert back to double for comparison
+ uint32_t temp = uint32_t (i_val);
+
+ //if not equal, lost something from truncating, so add 1
+ temp += (temp == i_val) ? 0 : 1;
+
+ //Truncate final value
+ return temp;
+}
+
+///
/// @brief Perform thermal calculations as part of the effective configuration
/// @param[in] i_target the MCS target in which the runtime throttles will be reset
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode restore_runtime_throttles( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target );
+///
+/// @brief Update the runtime throttles to the worst case of the general throttle values and the runtime values
+/// @param[in] i_target the MCS target in which the runtime throttles will be set
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+fapi2::ReturnCode update_runtime_throttles(const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >& i_targets);
+
}//power_thermal
}// mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/find.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/find.H
index c00bbac72..ffc2b59ff 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/find.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/find.H
@@ -127,7 +127,6 @@ inline fapi2::Target<fapi2::TARGET_TYPE_MCBIST> find_target( const fapi2::Target
return i_target.getParent<fapi2::TARGET_TYPE_MCBIST>();
}
-
///
/// @brief find all the dimm connected to an MCS
/// @param[in] i_target a fapi2::Target MCS
@@ -453,8 +452,6 @@ fapi2::ReturnCode find_key_from_value(const std::vector<std::pair<T, OT> >& i_ve
}// find_value_from_key
-
-
///
/// @brief find a key value from a C-style array of STL pairs
/// @tparam T input type
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C
index 77cbacf5d..2b7d43395 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.C
@@ -30,7 +30,7 @@
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
-// *HWP Level: 1
+// *HWP Level: 2
// *HWP Consumed by: FSP:HB
#include <vector>
@@ -38,6 +38,7 @@
#include <fapi2.H>
#include <p9_mss_bulk_pwr_throttles.H>
#include <lib/utils/find.H>
+#include <lib/utils/count_dimm.H>
#include <lib/power_thermal/throttle.H>
using fapi2::TARGET_TYPE_MCS;
@@ -46,35 +47,58 @@ using fapi2::TARGET_TYPE_DIMM;
extern "C"
{
- ///
- /// @brief Set ATTR_MSS_PORT_MAXPOWER, ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT
- /// @param[in] i_targets vector of MCS's on the same VDDR domain
- /// @param[in] thermal boolean to determine whether to calculate throttles based on the power regulator or thermal limits
- /// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
- /// @note Called in p9_mss_bulk_pwr_throttles
- /// @note determines the throttle levels based off of the port's power curve,
- /// sets the slot throttles to the same
- /// @note Enums are POWER for power egulator throttles and THERMAL for thermal throttles
- /// @note equalizes the throttles to the lowest of runtime and the lowest slot-throttle value
- ///
+///
+/// @brief Set ATTR_MSS_PORT_MAXPOWER, ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT
+/// @param[in] i_targets vector of MCS's on the same VDDR domain
+/// @param[in] thermal boolean to determine whether to calculate throttles based on the power regulator or thermal limits
+/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
+/// @note Called in p9_mss_bulk_pwr_throttles
+/// @note determines the throttle levels based off of the port's power curve,
+/// sets the slot throttles to the same
+/// @note Enums are POWER for power egulator throttles and THERMAL for thermal throttles
+/// @note equalizes the throttles to the lowest of runtime and the lowest slot-throttle value
+///
fapi2::ReturnCode p9_mss_bulk_pwr_throttles( const std::vector< fapi2::Target<TARGET_TYPE_MCS> >& i_targets,
throttle_type t)
{
FAPI_INF("Start bulk_pwr_throttles");
-//To be implemented in next commit
-#if 0
//Check for THERMAL
if (t == THERMAL)
{
for ( const auto& l_mcs : i_targets)
{
+ uint16_t l_slot [mss::PORTS_PER_MCS] = {};
+ uint16_t l_port [mss::PORTS_PER_MCS] = {};
+ uint32_t l_power [mss::PORTS_PER_MCS] = {};
+
for (const auto& l_mca : mss::find_targets<TARGET_TYPE_MCA>(l_mcs))
{
- //mss::power_thermal::throttle l_pwr_struct(l_mca);
- //FAPI_TRY (l_pwr_struct.thermal_throttles() );
+ //Don't run if there are no dimms on the port
+ if (mss::count_dimm(l_mca) == 0)
+ {
+ continue;
+ }
+
+ const uint8_t l_pos = mss::index(l_mca);
+ fapi2::ReturnCode l_rc;
+ mss::power_thermal::throttle l_pwr_struct(l_mca, l_rc);
+ FAPI_TRY(l_rc, "Error constructing mss:power_thermal::throttle object for target %s",
+ mss::c_str(l_mca));
+ FAPI_TRY (l_pwr_struct.thermal_throttles());
+
+ l_slot[l_pos] = l_pwr_struct.iv_n_slot;
+ l_port[l_pos] = l_pwr_struct.iv_n_port;
+ l_power[l_pos] = l_pwr_struct.iv_calc_port_maxpower;
}
+
+ FAPI_INF("Port maxpower is %d, %d slot is %d, %d, port is %d %d",
+ l_power[0], l_power[1], l_slot[0], l_slot[1], l_port[0], l_port[1]);
+
+ FAPI_TRY(FAPI_ATTR_SET( fapi2::ATTR_MSS_PORT_MAXPOWER, l_mcs, l_power));
+ FAPI_TRY(FAPI_ATTR_SET( fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, l_mcs, l_slot));
+ FAPI_TRY(FAPI_ATTR_SET( fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, l_mcs, l_port));
}
//Equalize throttles
@@ -84,20 +108,46 @@ extern "C"
{
for ( const auto& l_mcs : i_targets)
{
+ uint16_t l_slot [mss::PORTS_PER_MCS] = {};
+ uint16_t l_port [mss::PORTS_PER_MCS] = {};
+ uint32_t l_power [mss::PORTS_PER_MCS] = {};
+
for (const auto& l_mca : mss::find_targets<TARGET_TYPE_MCA>(l_mcs))
{
- //mss::power_thermal::throttle l_pwr_struct(l_mca);
- //FAPI_TRY (l_pwr_struct.power_regulator_throttles() );
+ //Don't run if there are no dimms on the port
+ if (mss::count_dimm(l_mca) == 0)
+ {
+ continue;
+ }
+
+ uint8_t l_pos = mss::index(l_mca);
+ fapi2::ReturnCode l_rc;
+ mss::power_thermal::throttle l_pwr_struct(l_mca, l_rc);
+ FAPI_TRY(l_rc, "Error constructing mss:power_thermal::throttle object for target %s",
+ mss::c_str(l_mca));
+
+ FAPI_TRY (l_pwr_struct.power_regulator_throttles());
+
+ l_slot[l_pos] = l_pwr_struct.iv_n_slot;
+ l_port[l_pos] = l_pwr_struct.iv_n_port;
+ l_power[l_pos] = l_pwr_struct.iv_calc_port_maxpower;
}
+
+ FAPI_INF("Port maxpower is %d, %d slot is %d, %d, port is %d %d",
+ l_power[0], l_power[1], l_slot[0], l_slot[1], l_port[0], l_port[1]);
+ FAPI_TRY(FAPI_ATTR_SET( fapi2::ATTR_MSS_PORT_MAXPOWER, l_mcs, l_power));
+ FAPI_TRY(FAPI_ATTR_SET( fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, l_mcs, l_slot));
+ FAPI_TRY(FAPI_ATTR_SET( fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, l_mcs, l_port));
}
//Equalize throttles
}
-
FAPI_INF("End bulk_pwr_throttles");
+ return fapi2::FAPI2_RC_SUCCESS;
+
fapi_try_exit:
-#endif
+ FAPI_ERR("Error calculating bulk_pwr_throttles");
return fapi2::current_err;
}
} //extern C
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.H b/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.H
index 25215dbc4..f0acad89b 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.H
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_bulk_pwr_throttles.H
@@ -30,7 +30,7 @@
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
-// *HWP Level: 1
+// *HWP Level: 2
// *HWP Consumed by: FSP:HB
#ifndef __P9_MSS_BULK_PWR_THROTTLES__
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C
index 8306dc750..2e755c647 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config.C
@@ -196,18 +196,6 @@ fapi2::ReturnCode p9_mss_eff_config( const fapi2::Target<fapi2::TARGET_TYPE_MCS>
FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_MEM_WATT_TARGET, i_target,
l_mem_watt_target ) );
}
- //Values taken from Mike Pardeik. Calculated to reach 90% util, will be removed once eff_config_thermal is implemented
- {
- uint32_t l_throttled_n_commands[mss::PORTS_PER_MCS] = {0x73, 0x73};
- FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT, i_target,
- l_throttled_n_commands ) );
- }
-
- {
- uint32_t l_throttled_n_commands[mss::PORTS_PER_MCS] = {0x73, 0x73};
- FAPI_TRY( FAPI_ATTR_SET( fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT, i_target,
- l_throttled_n_commands ) );
- }
{
uint16_t l_cal_step[mss::PORTS_PER_MCS] = {0xFAC0, 0xFAC0};
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C
index 361c3dbe6..3935ef805 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C
@@ -30,7 +30,7 @@
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
-// *HWP Level: 1
+// *HWP Level: 2
// *HWP Consumed by: FSP:HB
#include <fapi2.H>
@@ -40,14 +40,15 @@
#include <lib/power_thermal/throttle.H>
#include <lib/power_thermal/decoder.H>
#include <lib/dimm/kind.H>
+#include <lib/utils/count_dimm.H>
#include <mss.H>
extern "C"
{
-///
-/// @brief Perform thermal calculations as part of the effective configuration
-/// @param[in] i_targets an array of MCS targets all on the same VDDR domain
-/// @return FAPI2_RC_SUCCESS iff ok
-///
+ ///
+ /// @brief Perform thermal calculations as part of the effective configuration
+ /// @param[in] i_targets an array of MCS targets all on the same VDDR domain
+ /// @return FAPI2_RC_SUCCESS iff ok
+ ///
fapi2::ReturnCode p9_mss_eff_config_thermal( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >& i_targets )
{
@@ -61,17 +62,18 @@ extern "C"
//Gotta convert into fapi2::buffers. Not very elegant
//Do it here or in the encode and decode functions
- std::vector< uint64_t > l_tslope (mss::SIZE_OF_POWER_CURVES_ATTRS, 0);
- std::vector< uint64_t > l_tintercept (mss::SIZE_OF_POWER_CURVES_ATTRS, 0);
- std::vector< uint64_t > l_tthermal_power_limit (mss::SIZE_OF_THERMAL_ATTR, 0);
+ //Not that pretty :(
+ std::vector< uint64_t > l_tslope (mss::power_thermal::SIZE_OF_POWER_CURVES_ATTRS, 0);
+ std::vector< uint64_t > l_tintercept (mss::power_thermal::SIZE_OF_POWER_CURVES_ATTRS, 0);
+ std::vector< uint64_t > l_tthermal_power_limit (mss::power_thermal::SIZE_OF_THERMAL_ATTR, 0);
- std::vector< fapi2::buffer< uint64_t > > l_slope (mss::SIZE_OF_POWER_CURVES_ATTRS);
- std::vector< fapi2::buffer< uint64_t > > l_intercept (mss::SIZE_OF_POWER_CURVES_ATTRS);
- std::vector< fapi2::buffer< uint64_t > > l_thermal_power_limit (mss::SIZE_OF_THERMAL_ATTR);
+ std::vector<fapi2::buffer< uint64_t>> l_slope (mss::power_thermal::SIZE_OF_POWER_CURVES_ATTRS);
+ std::vector<fapi2::buffer< uint64_t>> l_intercept (mss::power_thermal::SIZE_OF_POWER_CURVES_ATTRS);
+ std::vector<fapi2::buffer< uint64_t>> l_thermal_power_limit (mss::power_thermal::SIZE_OF_THERMAL_ATTR);
- FAPI_TRY ( mss::mrw_pwr_slope (l_tslope.data() ));
- FAPI_TRY ( mss::mrw_pwr_intercept (l_tintercept.data()) );
- FAPI_TRY ( mss::mrw_thermal_memory_power_limit (l_tthermal_power_limit.data()) );
+ FAPI_TRY( mss::mrw_pwr_slope (l_tslope.data() ));
+ FAPI_TRY( mss::mrw_pwr_intercept (l_tintercept.data()) );
+ FAPI_TRY( mss::mrw_thermal_memory_power_limit (l_tthermal_power_limit.data()) );
for (size_t i = 0; i < l_slope.size(); ++i)
{
@@ -79,9 +81,22 @@ extern "C"
l_intercept[i] = fapi2::buffer<uint64_t>(l_tintercept[i]);
}
- for ( const auto& l_mcs : i_targets )
+ for (size_t i = 0; i < l_thermal_power_limit.size(); ++i)
+ {
+ l_thermal_power_limit[i] = fapi2::buffer<uint64_t> (l_tthermal_power_limit[i]);
+ }
+
+ //Restore runtime_throttles from safemode setting
+ //Decode and set power curve attributes at the same time
+ for (const auto& l_mcs : i_targets )
{
- FAPI_TRY (mss::power_thermal::get_power_attrs(l_mcs,
+ //Not doing any work if there are no dimms installed
+ if (mss::count_dimm(l_mcs) == 0)
+ {
+ continue;
+ }
+
+ FAPI_TRY( mss::power_thermal::get_power_attrs(l_mcs,
l_slope,
l_intercept,
l_thermal_power_limit,
@@ -90,13 +105,11 @@ extern "C"
l_total_slope,
l_total_int,
l_thermal_power));
-
+ //Sets throttles to max_databus_util value
+ FAPI_INF("Restoring throttles");
FAPI_TRY( mss::power_thermal::restore_runtime_throttles(l_mcs));
- //Set the power attribute (TOTAL_PWR) to just VDDR for IPL, restoreto vddr+vpp later for OCC
- //Set here because bulk_pwr_throttles takes input as attributes, and I can't change which attribute it takes
- //So we have to use TOTAL_PWR_SLOPE
- //Setting here and not in set_power_attrs because get_power_attrs decodes the attributes and stores them
+ //Set the power attribute (TOTAL_PWR) to just VDDR for the POWER bulk_pwr_throttles, restore to vddr+vpp later for OCC
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_TOTAL_PWR_SLOPE,
l_mcs,
l_vddr_slope));
@@ -104,15 +117,27 @@ extern "C"
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_TOTAL_PWR_INTERCEPT,
l_mcs,
l_vddr_int));
+
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_DIMM_THERMAL_LIMIT,
+ l_mcs,
+ l_thermal_power));
}
+ FAPI_INF("Starting bulk_pwr");
//get the thermal limits, done per dimm and set to worst case for the slot and port throttles
- FAPI_TRY (p9_mss_bulk_pwr_throttles(i_targets, THERMAL));
+ //Bulk_pwr sets the general, all purpose ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, _PER_PORT, and MAXPOWER ATTRs
+ FAPI_TRY( p9_mss_bulk_pwr_throttles(i_targets, POWER));
+
+ //Set runtime throttles to worst case between ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT
+ //and ATTR_MSS_MEM_RUNTIME_THROTTLED_N_COMMANDS_PER_SLOT and the _PORT equivalents also
+ FAPI_INF("Starting update");
+ FAPI_TRY( mss::power_thermal::update_runtime_throttles (i_targets));
+ FAPI_INF("finished update");
- //Set VDDR+VPP
+ //Set VDDR+VPP power curve values
for ( const auto& l_mcs : i_targets )
{
- FAPI_TRY (mss::power_thermal::get_power_attrs(l_mcs,
+ FAPI_TRY( mss::power_thermal::get_power_attrs(l_mcs,
l_slope,
l_intercept,
l_thermal_power_limit,
@@ -122,9 +147,10 @@ extern "C"
l_total_int,
l_thermal_power));
- FAPI_TRY( mss::power_thermal::restore_runtime_throttles(l_mcs));
+ FAPI_INF( "VDDR+VPP power curve slope is %d, int is %d, thermal_power is %d", l_total_slope[0][0], l_total_int[0][0],
+ l_thermal_power[0][0]);
- //Set the power attribute (TOTAL_PWR) to just VDDR for IPL, restoreto vddr+vpp later for OCC
+ //Set the power attribute (TOTAL_PWR) to vpp+vdd power slope
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_TOTAL_PWR_SLOPE,
l_mcs,
l_total_slope));
@@ -134,8 +160,13 @@ extern "C"
l_total_int));
}
+ //Run thermal throttles with the VDDR+VPP power curves
+ FAPI_TRY( p9_mss_bulk_pwr_throttles(i_targets, THERMAL));
+ //Update everything to worst case
+ FAPI_TRY( mss::power_thermal::update_runtime_throttles (i_targets));
- FAPI_INF("End effective config thermal");
+ //Done
+ FAPI_INF( "End effective config thermal");
fapi_try_exit:
return fapi2::FAPI2_RC_SUCCESS;
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.H b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.H
index 9071f5a1c..0822da50c 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.H
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.H
@@ -27,10 +27,10 @@
/// @file p9_mss_eff_config_thermal.H
/// @brief Perform thermal calculations as part of the effective configuration
///
-// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
+// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
-// *HWP Level: 1
+// *HWP Level: 2
// *HWP Consumed by: FSP:HB
#ifndef __P9_MSS_EFF_CONFIG_THERMAL__
@@ -39,7 +39,8 @@
#include <fapi2.H>
#include <vector>
-typedef fapi2::ReturnCode (*p9_mss_eff_config_thermal_FP_t) (const std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCS>>&);
+typedef fapi2::ReturnCode (*p9_mss_eff_config_thermal_FP_t) (const
+ std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >&);
extern "C"
{
@@ -50,7 +51,6 @@ extern "C"
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode p9_mss_eff_config_thermal( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >& i_targets );
-
}
#endif
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_throttle_mem.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_throttle_mem.C
index e1c27e4b3..15783f487 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_throttle_mem.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_throttle_mem.C
@@ -53,8 +53,8 @@ extern "C"
for (const auto& l_mca : mss::find_targets<fapi2::TARGET_TYPE_MCA> (i_target))
{
- uint32_t l_runtime_port = 0;
- uint32_t l_runtime_slot = 0;
+ uint16_t l_runtime_port = 0;
+ uint16_t l_runtime_slot = 0;
uint32_t l_throttle_denominator = 0;
FAPI_TRY( mss::mem_m_dram_clocks( l_mca, l_throttle_denominator) );
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C
index 8809ad0f4..cbf1fe988 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C
@@ -33,7 +33,7 @@
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Brian Silver <bsilver@us.ibm.com>
// *HWP Team: Memory
-// *HWP Level: 1
+// *HWP Level: 2
// *HWP Consumed by: FSP:HB
#include <p9_mss_utils_to_throttle.H>
@@ -46,6 +46,7 @@
#include <lib/utils/index.H>
#include <lib/utils/find.H>
#include <lib/utils/conversions.H>
+#include <lib/power_thermal/throttle.H>
#include <lib/mss_attribute_accessors.H>
using fapi2::TARGET_TYPE_MCS;
@@ -65,43 +66,49 @@ extern "C"
{
for( const auto& l_mcs : i_targets )
{
- //TODO RTC 160048 Complete implementing (calculating power and per slot throttles) - JLH
uint32_t l_databus_util [mss::PORTS_PER_MCS];
- uint32_t l_throttled_cmds_port[mss::PORTS_PER_MCS];
- uint32_t l_throttled_cmds_slot[mss::PORTS_PER_MCS];
+ uint32_t l_dram_clocks = 0;
+
+ uint16_t l_throttled_cmds_port[mss::PORTS_PER_MCS];
+ uint16_t l_throttled_cmds_slot[mss::PORTS_PER_MCS];
uint32_t l_max_power[mss::PORTS_PER_MCS];
- uint32_t l_dram_clocks = 0;
FAPI_TRY( mss::mrw_mem_m_dram_clocks(l_dram_clocks) );
-
+ //Util attribute set by OCC
FAPI_TRY( mss::databus_util(l_mcs, l_databus_util) );
for( const auto& l_mca : mss::find_targets<TARGET_TYPE_MCA>(l_mcs) )
{
const auto l_port_num = mss::index( l_mca );
+ //Make a throttle object in order to calculate the port power
+ fapi2::ReturnCode l_rc;
+ mss::power_thermal::throttle l_throttle (l_mca, l_rc);
+ FAPI_TRY(l_rc, "Error calculating mss::power_thermal::throttle constructor in p9_mss_utils_to_throttles");
FAPI_INF( "MRW dram clock window: %d, databus utilization: %d",
l_dram_clocks,
- l_databus_util );
-
- // Calculate programmable N address operations within M dram clock window
- l_throttled_cmds_port[l_port_num] = mss::power_thermal::throttled_cmds( l_databus_util[l_port_num], l_dram_clocks );
- l_throttled_cmds_slot[l_port_num] = mss::power_thermal::throttled_cmds( l_databus_util[l_port_num], l_dram_clocks );
- //TK - actually implement function - JLH
- //Quick hard code for API purposes
- l_max_power[l_port_num] = 2088;
- FAPI_INF( "Calculated N commands per port [%d] = %d",
+ l_databus_util);
+
+ //Calculate programmable N address operations within M dram clock window
+ l_throttled_cmds_port[l_port_num] = mss::power_thermal::throttled_cmds(l_databus_util[l_port_num],
+ l_dram_clocks );
+ l_throttled_cmds_slot[l_port_num] = l_throttled_cmds_port[l_port_num];
+ //Calculate the port power needed to reach the calculated N value
+ l_max_power[l_port_num] = l_throttle.calc_power_from_n(l_throttled_cmds_slot[l_port_num]);
+
+ FAPI_INF( "Calculated N commands per port [%d] = %d commands, maxpower is %d",
l_port_num,
- l_throttled_cmds_port[l_port_num]);
+ l_throttled_cmds_port[l_port_num],
+ l_max_power[l_port_num]);
}// end for
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_PORT_MAXPOWER,
l_mcs,
l_max_power) );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
l_mcs,
l_throttled_cmds_slot) );
- FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT,
+ FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT,
l_mcs,
l_throttled_cmds_port) );
}
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml
index b0353804e..7762d231b 100644
--- a/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/memory_mcs_attributes.xml
@@ -1182,7 +1182,7 @@
of M DRAM clocks setting for cfg_nm_n_per_port.
</description>
<initToZero></initToZero>
- <valueType>uint32</valueType>
+ <valueType>uint16</valueType>
<writeable/>
<array>2</array>
<mssAccessorName>mem_throttled_n_commands_per_port</mssAccessorName>
@@ -1209,7 +1209,7 @@
<targetType>TARGET_TYPE_MCS</targetType>
<description>This is the throttle numerator setting for cfg_nm_n_per_slot</description>
<initToZero></initToZero>
- <valueType>uint32</valueType>
+ <valueType>uint16</valueType>
<writeable/>
<array>2</array>
<mssAccessorName>mem_throttled_n_commands_per_slot</mssAccessorName>
@@ -1346,6 +1346,21 @@
</attribute>
<attribute>
+ <id>ATTR_MSS_DIMM_THERMAL_LIMIT</id>
+ <targetType>TARGET_TYPE_MCS</targetType>
+ <description>
+ DIMM Max Power based on a thermal limit
+ Decoded from ATTR_MSS_MRW_THERMAL_POWER_LIMIT
+ </description>
+ <initToZero></initToZero>
+ <valueType>uint32</valueType>
+ <writeable/>
+ <mssUnit>cW</mssUnit>
+ <array> 2 2</array>
+ <mssAccessorName>dimm_thermal_limit</mssAccessorName>
+ </attribute>
+
+ <attribute>
<id>ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT</id>
<targetType>TARGET_TYPE_MCS</targetType>
<description>
@@ -1353,7 +1368,7 @@
M DRAM clocks setting for cfg_nm_n_per_port.
</description>
<initToZero></initToZero>
- <valueType>uint32</valueType>
+ <valueType>uint16</valueType>
<writeable/>
<array>2</array>
<mssAccessorName>runtime_mem_throttled_n_commands_per_port</mssAccessorName>
@@ -1375,7 +1390,7 @@
<targetType>TARGET_TYPE_MCS</targetType>
<description>Runtime throttle numerator setting for cfg_nm_n_per_slot</description>
<initToZero></initToZero>
- <valueType>uint32</valueType>
+ <valueType>uint16</valueType>
<writeable/>
<array>2</array>
<mssAccessorName>runtime_mem_throttled_n_commands_per_slot</mssAccessorName>
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml
index f4737af85..8c59ba71f 100755
--- a/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/memory_mrw_attributes.xml
@@ -102,6 +102,7 @@
<platInit/>
<initToZero/>
<array>100</array>
+ <default>0xffffe00002CC03AE</default>
<mssAccessorName>mrw_pwr_intercept</mssAccessorName>
</attribute>
@@ -132,6 +133,7 @@
<platInit/>
<initToZero/>
<array>100</array>
+ <default>0xffffe00003FD0546</default>
<mssAccessorName>mrw_pwr_slope</mssAccessorName>
</attribute>
@@ -246,7 +248,7 @@
<id>ATTR_MSS_MRW_POWER_CONTROL_REQUESTED</id>
<targetType>TARGET_TYPE_SYSTEM</targetType>
<description>
- Memory power control settings programmed during IPL
+ Memory power control settings programmed during IPL
Used by OCC when exiting idle power-save mode
</description>
<valueType>uint8</valueType>
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml
index 12336a55b..7007f8c39 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_eff_config.xml
@@ -161,7 +161,7 @@
</hwpError>
<hwpError>
- <rc>RC_MSS_CALC_PORT_POWER_CURVE_DIVIDE_BY_ZERO</rc>
+ <rc>RC_MSS_CALC_POWER_CURVE_DIVIDE_BY_ZERO</rc>
<description>
Denominator equals 0
</description>
OpenPOWER on IntegriCloud