diff --git a/src/include/usr/isteps/istep21list.H b/src/include/usr/isteps/istep21list.H index 61b0d49e4a2..c58ced1a0b5 100644 --- a/src/include/usr/isteps/istep21list.H +++ b/src/include/usr/isteps/istep21list.H @@ -125,6 +125,7 @@ const DepModInfo g_istep21Dependancies = { DEP_LIB(libpm.so), #ifdef CONFIG_HTMGT DEP_LIB(libhtmgt.so), + DEP_LIB(libisteps_mss.so), #endif NULL } diff --git a/src/usr/htmgt/htmgt.C b/src/usr/htmgt/htmgt.C index 56759c39f79..7107d3e4421 100644 --- a/src/usr/htmgt/htmgt.C +++ b/src/usr/htmgt/htmgt.C @@ -77,7 +77,11 @@ namespace HTMGT { #ifndef __HOSTBOOT_RUNTIME // Calc memory throttles (once per IPL) - calcMemThrottles(); + l_err = calcMemThrottles(); + if( l_err ) + { + break; + } #endif // Make sure OCCs are ready for communication diff --git a/src/usr/htmgt/htmgt_cfgdata.C b/src/usr/htmgt/htmgt_cfgdata.C index 144eacb560d..eb4136d199c 100644 --- a/src/usr/htmgt/htmgt_cfgdata.C +++ b/src/usr/htmgt/htmgt_cfgdata.C @@ -31,6 +31,7 @@ #include "ipmi/ipmisensor.H" #include #include +#include "htmgt_memthrottles.H" using namespace TARGETING; @@ -159,10 +160,10 @@ namespace HTMGT break; case OCC_CFGDATA_MEM_THROTTLE: - if (int_flags_set(FLAG_SEND_MEM_CONFIG)) + if (!int_flags_set(FLAG_DISABLE_MEM_CONFIG)) { getMemThrottleMessageData(occ->getTarget(), - cmdData, cmdDataLen); + occInstance, cmdData, cmdDataLen); } break; @@ -238,10 +239,8 @@ enum occCfgDataVersion { OCC_CFGDATA_FREQ_POINT_VERSION = 0x20, OCC_CFGDATA_APSS_VERSION = 0x20, - OCC_CFGDATA_MEM_CONFIG_VERSION = 0x21, OCC_CFGDATA_PCAP_CONFIG_VERSION = 0x20, OCC_CFGDATA_SYS_CONFIG_VERSION = 0x20, - OCC_CFGDATA_MEM_THROTTLE_VERSION = 0x20, OCC_CFGDATA_TCT_CONFIG_VERSION = 0x20, OCC_CFGDATA_AVSBUS_CONFIG_VERSION = 0X01, }; @@ -289,7 +288,6 @@ void writeMemConfigData( uint8_t *& o_data, //Byte 11 Nimbus DIMM Temp i2c address // Cumulus Reserved for Cumulus o_data[io_index++] = i_i2cDevAddr; - } @@ -301,7 +299,7 @@ void getMemConfigMessageData(const TargetHandle_t i_occ, assert(o_data != nullptr); o_data[index++] = OCC_CFGDATA_MEM_CONFIG; - o_data[index++] = OCC_CFGDATA_MEM_CONFIG_VERSION; + o_data[index++] = 0x21; // version //System reference needed for these ATTR. Target* sys = nullptr; @@ -328,7 +326,7 @@ void getMemConfigMessageData(const TargetHandle_t i_occ, //Byte 5: Number of data sets. size_t numSetsOffset = index++; //Will fill in numSets at the end - if (int_flags_set(FLAG_SEND_MEM_CONFIG)) + if (!int_flags_set(FLAG_DISABLE_MEM_CONFIG)) { TargetHandleList centaurs; TargetHandleList mbas; @@ -458,6 +456,7 @@ void getMemConfigMessageData(const TargetHandle_t i_occ, void getMemThrottleMessageData(const TargetHandle_t i_occ, + const uint8_t i_occ_instance, uint8_t* o_data, uint64_t & o_size) { uint8_t numSets = 0; @@ -467,17 +466,17 @@ void getMemThrottleMessageData(const TargetHandle_t i_occ, assert(proc != nullptr); assert(o_data != nullptr); - TargetHandleList centaurs; + //Get all functional MCSs + TargetHandleList mcs_list; + getAllChiplets(mcs_list, TYPE_MCS, true); + TMGT_INF("calcMemThrottles: found %d MCSs", mcs_list.size()); o_data[index++] = OCC_CFGDATA_MEM_THROTTLE; - o_data[index++] = OCC_CFGDATA_MEM_THROTTLE_VERSION; + o_data[index++] = 0x20; // version; //Byte 3: Number of memory throttling data sets. size_t numSetsOffset = index++; //Will fill in numSets at the end - - getChildAffinityTargets(centaurs, proc, CLASS_CHIP, TYPE_MEMBUF); - //Next, the following format repeats per set/MBA: //Byte 0: Cumulus: Centaur position 0-7 // Nimbus : Memory Controller @@ -489,49 +488,112 @@ void getMemThrottleMessageData(const TargetHandle_t i_occ, //Bytes 8-9: Turbo N_PER_CHIP //Bytes 10-11: Max mem power with throttle @Turbo //Bytes 12-13: Power Capping N_PER_MBA - //Bytes 14-15: Power Capping N_PER_MBA + //Bytes 14-15: Power Capping N_PER_CHIP //Bytes 16-17: Max mem power with throttle @PowerCapping //Bytes 18-19: Nominal Power N_PER_MBA //Bytes 20-21: Nominal Power N_PER_CHIP //Bytes 22-23: Max mem power with throttle @Nominal //Bytes 24-29: Reserved - // Hard coding until we can get mem throttle cfg data - for (uint8_t entry = 0; entry < 2; ++entry) + for(const auto & mcs_target : mcs_list) { - o_data[index++] = 0x00; //MC01 - o_data[index++] = entry; // Port - o_data[index++] = 0x44; // Min N Per MBA - o_data[index++] = 0x44; - o_data[index++] = 0x01; // Max mem pwr at min throttle - o_data[index++] = 0x00; - o_data[index++] = 0x45; // Turbo N per MBA - o_data[index++] = 0x56; - o_data[index++] = 0x55; // Turbo N per chip - o_data[index++] = 0x5F; - o_data[index++] = 0x01; // Max mem pwr at turbo - o_data[index++] = 0x10; - o_data[index++] = 0x45; // Power capping N per MBA - o_data[index++] = 0x56; - o_data[index++] = 0x55; // Power capping N per chip - o_data[index++] = 0x5F; - o_data[index++] = 0x01; // Max mem pwr at power capping - o_data[index++] = 0x20; - o_data[index++] = 0x45; // Nominal N per MBA - o_data[index++] = 0x56; - o_data[index++] = 0x55; // Nominal N per chip - o_data[index++] = 0x5F; - o_data[index++] = 0x01; // Max mem pwr at Nominal - o_data[index++] = 0x30; - o_data[index++] = 0x00; // reserved - o_data[index++] = 0x00; - o_data[index++] = 0x00; - o_data[index++] = 0x00; - o_data[index++] = 0x00; - o_data[index++] = 0x00; - ++numSets ; - } + uint8_t mcs_unit = 0xFF; + if (!mcs_target->tryGetAttr(mcs_unit)) + { + uint32_t mcs_huid = 0xFFFFFFFF; + mcs_target->tryGetAttr(mcs_huid); + TMGT_ERR("calcMemThrottles: Unable to determine MCS unit for HUID" + " 0x%04X", mcs_huid); + continue; + } + ConstTargetHandle_t proc_target = getParentChip(mcs_target); + assert(proc_target != nullptr); + // Make sure this MCS is for the current OCC/Proc + if (i_occ_instance == proc_target->getAttr()) + { + // Read the throttle and power values for this MCS + ATTR_OT_MIN_N_PER_MBA_type npm_min; + ATTR_OT_MEM_POWER_type power_min; + mcs_target->tryGetAttr(npm_min); + mcs_target->tryGetAttr(power_min); + ATTR_N_PLUS_ONE_N_PER_MBA_type npm_redun; + ATTR_N_PLUS_ONE_N_PER_CHIP_type npc_redun; + ATTR_N_PLUS_ONE_MEM_POWER_type power_redun; + mcs_target->tryGetAttr(npm_redun); + mcs_target->tryGetAttr(npc_redun); + mcs_target->tryGetAttr(power_redun); + ATTR_POWERCAP_N_PER_MBA_type npm_pcap; + ATTR_POWERCAP_N_PER_CHIP_type npc_pcap; + ATTR_POWERCAP_MEM_POWER_type power_pcap; + mcs_target->tryGetAttr(npm_pcap); + mcs_target->tryGetAttr(npc_pcap); + mcs_target->tryGetAttr(power_pcap); + + // Query the functional MCAs for this MCS + TARGETING::TargetHandleList mca_list; + getChildAffinityTargetsByState(mca_list, mcs_target, CLASS_UNIT, + TYPE_MCA, UTIL_FILTER_FUNCTIONAL); + for(const auto & mca_target : mca_list) + { + // unit identifies unique MCA under a processor + uint8_t mca_unit = 0xFF; + mca_target->tryGetAttr(mca_unit); + const uint8_t mca_rel_pos = mca_unit % 2; + if ((npm_min[mca_rel_pos] == 0) || + (npm_redun[mca_rel_pos] == 0) || + (npm_pcap[mca_rel_pos] == 0)) + { + TMGT_ERR("calcMemThrottles: MCS%d/MCA%d [%d]" + " - Ignored due to null throttle", + mcs_unit, mca_unit, mca_rel_pos); + TMGT_ERR("N/slot: Min=%d, Turbo=%d, Pcap=%d", + npm_min[mca_rel_pos], npm_redun[mca_rel_pos], + npm_pcap[mca_rel_pos]); + continue; + } + if (mca_rel_pos >= TMGT_MAX_MCA_PER_MCS) + { + TMGT_ERR("calcMemThrottles: OCC%d / MCS%d / MCA%d" + " - Ignored due invalid MCA position: %d", + i_occ_instance, mcs_unit, mca_unit, mca_rel_pos); + continue; + } + TMGT_INF("calcMemThrottles: OCC%d / MCS%d / MCA%d [%d]", + i_occ_instance, mcs_unit, mca_unit, mca_rel_pos); + // OCC expects phyMC=0 for (MCS0-1) and 1 for (MCS2-3) + // MCS MCA MCA OCC OCC + // unit unit relPos phyMC phyPort + // 0 0 0 0 0 + // 0 1 1 0 1 + // 1 2 0 0 2 + // 1 3 1 0 3 + // 2 4 0 1 0 + // 2 5 1 1 1 + // 3 6 0 1 2 + // 3 7 1 1 3 + o_data[index] = mcs_unit >> 1; // MC (0-1) + o_data[index+1] = mca_unit % 4; // Phy Port (0-3) + // Minimum + UINT16_PUT(&o_data[index+ 2], npm_min[mca_rel_pos]); + UINT16_PUT(&o_data[index+ 4], power_min[mca_rel_pos]); + // Turbo + UINT16_PUT(&o_data[index+ 6], npm_redun[mca_rel_pos]); + UINT16_PUT(&o_data[index+ 8], npc_redun[mca_rel_pos]); + UINT16_PUT(&o_data[index+10], power_redun[mca_rel_pos]); + // Power Capping + UINT16_PUT(&o_data[index+12], npm_pcap[mca_rel_pos]); + UINT16_PUT(&o_data[index+14], npc_pcap[mca_rel_pos]); + UINT16_PUT(&o_data[index+16], power_pcap[mca_rel_pos]); + // Nominal (same as Turbo) + UINT16_PUT(&o_data[index+18], npm_redun[mca_rel_pos]); + UINT16_PUT(&o_data[index+20], npc_redun[mca_rel_pos]); + UINT16_PUT(&o_data[index+22], power_redun[mca_rel_pos]); + index += 30; + ++numSets ; + } + } + } TMGT_INF("getMemThrottleMessageData: returning %d" " sets of data for OCC 0x%X", @@ -669,8 +731,13 @@ void getPowerCapMessageData(uint8_t* o_data, uint64_t & o_size) index += 2; // Quick Power Drop Power Cap - ATTR_OPEN_POWER_N_BULK_POWER_LIMIT_WATTS_type qpd_pcap = - sys->getAttr(); + ATTR_OPEN_POWER_N_BULK_POWER_LIMIT_WATTS_type qpd_pcap; + if ( ! sys->tryGetAttr + (qpd_pcap)) + { + // attr does not exist, so disable by sending 0 + qpd_pcap = 0; + } UINT16_PUT(&o_data[index], qpd_pcap); index += 2; @@ -846,7 +913,7 @@ void getThermalControlMessageData(uint8_t* o_data, l_numSets++; } - // Dimm + // DIMM o_data[index++] = CFGDATA_FRU_TYPE_DIMM; l_DVFS_temp =l_sys->getAttr(); l_ERR_temp =l_sys->getAttr(); @@ -864,6 +931,19 @@ void getThermalControlMessageData(uint8_t* o_data, o_data[index++] = l_timeout; l_numSets++; + // VRM + l_timeout = l_sys->getAttr(); + if (l_timeout != 0) + { + o_data[index++] = CFGDATA_FRU_TYPE_VRM; + o_data[index++] = 0xFF; + o_data[index++] = 0xFF; + o_data[index++] = 0xFF; + o_data[index++] = 0xFF; + o_data[index++] = l_timeout; + l_numSets++; + } + o_data[l_numSetsOffset] = l_numSets; o_size = index; diff --git a/src/usr/htmgt/htmgt_cfgdata.H b/src/usr/htmgt/htmgt_cfgdata.H index 2e0fde5bb78..126b5f4c774 100644 --- a/src/usr/htmgt/htmgt_cfgdata.H +++ b/src/usr/htmgt/htmgt_cfgdata.H @@ -71,6 +71,7 @@ namespace HTMGT CFGDATA_FRU_TYPE_PROC = 0x00, CFGDATA_FRU_TYPE_MEMBUF = 0x01, CFGDATA_FRU_TYPE_DIMM = 0x02, + CFGDATA_FRU_TYPE_VRM = 0x03, CFDATA_DVFS_NOT_DEFINED = 0xFF, }; @@ -146,11 +147,13 @@ namespace HTMGT * including the format and version numbers. * * @param[in] i_occ - the OCC to gather data for + * @param[in] i_occ_instance - OCC instance number * @param[in] o_data - preallocated buffer to fill in * @param[out] o_size - set to the message size * @pre o_data is large enough. */ void getMemThrottleMessageData(const TARGETING::TargetHandle_t i_occ, + const uint8_t i_occ_instance, uint8_t* o_data, uint64_t & o_size); diff --git a/src/usr/htmgt/htmgt_memthrottles.C b/src/usr/htmgt/htmgt_memthrottles.C index b87addd14e2..a919d3928da 100644 --- a/src/usr/htmgt/htmgt_memthrottles.C +++ b/src/usr/htmgt/htmgt_memthrottles.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014,2016 */ +/* Contributors Listed Below - COPYRIGHT 2014,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -31,8 +31,13 @@ #include #include #include +#include +// Hardware Procedures: +#include +#include +// See src/include/usr/targeting/common/utilFilter.H for handy target utilities using namespace TARGETING; @@ -46,297 +51,184 @@ namespace HTMGT { /** - * Helper function to run the hardware procedure to calculate the - * throttle attributes for the Over Temp condition. - * flow = htmgtCalcMemThrottle_OT + * Run hardware procedure to determine throttle/numerator/number of commands + * based on the specified utilization * - * @param[in] i_mbas - list of functional MBAs * @param[in] i_utilization - Minimum utilization value required - * @param[in] i_nSafeModeMBA - the safe mode MBA throttle numerator + * @param[in] i_watt_target - power target required for bulk_pwr_throttles */ -void memPowerThrottleOT(TargetHandleList & i_mbas, - const uint32_t i_nSafeModeMBA, - const uint8_t i_utilization) +errlHndl_t call_utils_to_throttle( + std::vector > i_fapi_target_list, + const uint32_t i_util, + const uint32_t i_watt_target = 0) { - bool useSafeMode = false; - bool throttleError = false; - uint32_t nUtilBased = 0; - uint32_t mbaHuid = 0; - Target* sys = NULL; - - TMGT_INF(ENTER_MRK" memPowerThrottleOT"); + errlHndl_t err = NULL; + uint32_t utilization[TMGT_MAX_MCA_PER_MCS] = { i_util, i_util }; + uint32_t l_watt_targets[TMGT_MAX_MCA_PER_MCS][TMGT_MAX_DIMM_PER_MCA] = + {i_watt_target, i_watt_target, i_watt_target, i_watt_target}; + TMGT_INF("call_utils_to_throttle: utilization: 0x%04X, watt_target: " + "0x%04X", i_util, i_watt_target); + + // Update input attributes for specified targets + for(const auto & l_fapi_target : i_fapi_target_list) + { + FAPI_ATTR_SET(fapi2::ATTR_MSS_DATABUS_UTIL, l_fapi_target, utilization); + if (i_watt_target) + { + FAPI_ATTR_SET(fapi2::ATTR_MSS_MEM_WATT_TARGET, + l_fapi_target, l_watt_targets); + } + } - targetService().getTopLevelTarget(sys); - assert(sys != NULL); + // p9_mss_utils_to_throttle() - Sets number commands allowed within a + // given port databus utilization + // inputs: ATTR_MSS_DATABUS_UTIL + // outputs: ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, + // ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, and + // ATTR_MSS_PORT_MAXPOWER + TMGT_INF("call_utils_to_throttle: Calling HWP:p9_mss_utils_to_throttle" + "(POWER) for %d MCS Targets", i_fapi_target_list.size()); + { + FAPI_INVOKE_HWP(err, p9_mss_utils_to_throttle, i_fapi_target_list); + } - for( const auto & mba : i_mbas ) + if (NULL != err) { - mbaHuid = mba->getAttr(); - useSafeMode = true; - nUtilBased = 0; + TMGT_ERR("call_utils_to_throttle: HWP:p9_mss_utils_to_throttle failed" + " with rc=0x%04X", err->reasonCode()); + } - if (i_utilization != 0) - { - //Run a hardware procedure to calculate the lowest - //possible throttle setting based on the minimum - //utilization percentage. - errlHndl_t err = NULL; - const fapi2::Target fapiTarget(mba); - - //Set this so the procedure can use it - mba->setAttr(i_utilization); - -/* TODO: RTC 155033 - Memory Throttle Settings - FAPI_INVOKE_HWP(err, mss_util_to_throttle, fapiTarget); -*/ - if (err) - { - //Ignore the error and just use safe - //mode as the lowest throttle - TMGT_ERR("memPowerThrottleOT: Failed call to " - "mss_util_to_throttle on MBA 0x%X", - mbaHuid); - - delete err; - err = NULL; - } - else - { - //get the procedure output - nUtilBased = mba->getAttr(); + return err; - if (0 != nUtilBased) - { - useSafeMode = false; - } - else - { - TMGT_ERR("memPowerThrottleOT: mss_util_to_throttle" - " calculated a numerator of 0, MBA 0x%X", - mbaHuid); - - if (!throttleError) - { - throttleError = true; - - /*@ - * @errortype - * @reasoncode HTMGT_RC_OT_THROTTLE_INVALID_N - * @severity ERRL_SEV_UNRECOVERABLE - * @moduleid HTMGT_MOD_MEMTHROTTLE - * @userdata1 MBA HUID - * @devdesc Overtemp Throttle HW procedure - * calculated an invalid numerator - * value. - */ - err = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - HTMGT_MOD_MEMTHROTTLE, - HTMGT_RC_OT_THROTTLE_INVALID_N, - mbaHuid, 0, true); - err->collectTrace(HTMGT_COMP_NAME); - errlCommit(err, HTMGT_COMP_ID); - } - } - } - } +} // end call_utils_to_throttle() - if (useSafeMode) - { - nUtilBased = i_nSafeModeMBA; - TMGT_INF("memPowerThrottleOT: MBA 0x%X must use safemode" - " numerator", mbaHuid); - } +/** + * Calculate throttles for over-temperture + * + * @param[in] i_fapi_target_list - list of FAPI MCS targets + * @param[in] i_utilization - Minimum utilization value required + */ +errlHndl_t memPowerThrottleOT( + std::vector < fapi2::Target< fapi2::TARGET_TYPE_MCS>> i_fapi_target_list, + const uint8_t i_utilization) +{ + errlHndl_t err = NULL; - TMGT_INF("memPowerThrottleOT: MBA 0x%X: N Util OT = 0x%X", - mbaHuid, nUtilBased); + TMGT_INF("memPowerThrottleOT: Calculating throttles for util: %d", + i_utilization); - mba->setAttr(nUtilBased); + err = call_utils_to_throttle(i_fapi_target_list, i_utilization); + if (NULL == err) + { + uint32_t ot_mem_power = 0; + for(const auto & mcs_fapi_target : i_fapi_target_list) + { + // Read HWP outputs: + ATTR_OT_MIN_N_PER_MBA_type l_slot = {0}; + ATTR_OT_MEM_POWER_type l_power = {0}; + FAPI_ATTR_GET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, + mcs_fapi_target, l_slot); + FAPI_ATTR_GET(fapi2::ATTR_MSS_PORT_MAXPOWER, + mcs_fapi_target, l_power); + ot_mem_power += l_power[0] + l_power[1]; + + // Update MCS data (to be sent to OCC) + TARGETING::Target * mcs_target = + reinterpret_cast(mcs_fapi_target.get()); + ConstTargetHandle_t proc_target = getParentChip(mcs_target); + assert(proc_target != nullptr); + const uint8_t occ_instance = + proc_target->getAttr(); + uint8_t mcs_unit = 0xFF; + mcs_target->tryGetAttr(mcs_unit); + mcs_target->setAttr(l_slot); + mcs_target->setAttr(l_power); + TMGT_INF("memPowerThrottleOT: MIN: OCC%d/MCS%d - " + "N/slot: %d/%d, Power: %d/%dcW", + occ_instance, mcs_unit, l_slot[0], l_slot[1], + l_power[0], l_power[1]); + } + TMGT_INF("memPowerThrottleOT: Total Minimum Memory" + " Power: %dW", ot_mem_power/100); + } + else + { + TMGT_ERR("memPowerThrottleOT: Failed to calculate over-temp" + " memory throttles, rc=0x%04X", + err->reasonCode()); } + return err; -} - - +} // end memPowerThrottleOT() /** - * Helper function to run the mss_bulk_pwr_throttles and - * mss_util_to_throttle to calculate memory throttling - * numerator values. + * Run the p9_mss_bulk_pwr_throttles hardware procedure + * to calculate memory throttling numerator values. * - * @param[in] i_mba - the MBA - * @param[in] i_wattTarget - the power target for the MBA + * @param[in] i_fapi_target_list - list of FAPI MCS targets + * @param[in] i_wattTarget - the power target for the MCS * @param[in] i_utilization - the utilization desired - * @param[out] o_useSafeMode - will be set to true if safe mode - * values should be used - * @param[out] o_nMBA - set to the N_PER_MBA numerator value - * (don't use if safemode=true) - * @param[out] o_nChip - set to the N_PER_CHIP numerator value - * (don't use if safemode=true) */ -void doMBAThrottleCalc(TARGETING::Target * i_mba, +errlHndl_t call_bulk_pwr_throttles( + std::vector < fapi2::Target< fapi2::TARGET_TYPE_MCS>> i_fapi_target_list, const uint32_t i_wattTarget, - const uint8_t i_utilization, - bool & o_useSafeMode, - uint32_t & o_nMBA, - uint32_t & o_nChip) + const uint8_t i_utilization) { errlHndl_t err = NULL; - o_useSafeMode = false; - o_nMBA = 0; - o_nChip = 0; - - TARGETING::ATTR_MSS_MEM_WATT_TARGET_type l_wattArray = {{i_wattTarget, - i_wattTarget}, - {i_wattTarget, - i_wattTarget}}; //Set the values the procedures need - i_mba->setAttr(l_wattArray); - i_mba->setAttr(i_utilization); - - const fapi2::Target fapiTarget(i_mba); - -/* TODO This hwp is changing for p9 - FAPI_INVOKE_HWP(err, mss_bulk_pwr_throttles, fapiTarget); -*/ - if (err) - { - TMGT_ERR("doMBAThrottleCalc: Failed call to mss_bulk_pwr_throttles" - " on MBA 0x%X", - i_mba->getAttr()); - } - else + err = call_utils_to_throttle(i_fapi_target_list, + i_utilization, i_wattTarget); + if (NULL == err) { - //Get the procedure outputs - o_nMBA = i_mba->getAttr(); - o_nChip = i_mba->getAttr(); - - //Make sure neither are 0 - if ((0 == o_nMBA) || (0 == o_nChip)) + TMGT_INF("call_bulk_pwr_throttles: Calling HWP:p9_mss_bulk_pwr_" + "throttles(POWER) for MCS Targets"); + FAPI_INVOKE_HWP(err, p9_mss_bulk_pwr_throttles, i_fapi_target_list, + mss::throttle_type::POWER); + if (NULL != err) { - TMGT_ERR("doMBAThrottleCalc: mss_bulk_pwr_throttles calculated a" - " numerator value of 0: nMBA = %d, nChip = %d, MBA 0x%X", - o_nMBA, o_nChip, i_mba->getAttr()); - - /*@ - * @errortype - * @reasoncode HTMGT_RC_THROTTLE_INVALID_N - * @severity ERRL_SEV_UNRECOVERABLE - * @moduleid HTMGT_MOD_MEMTHROTTLE - * @userdata1 MBA HUID - * @userdata2[0:31] MBA numerator - * @userdata2[32:63] Chip numerator - * @devdesc Throttle HW procedure calculated - * an invalid numerator value. - */ - uint64_t data = ((uint64_t)o_nMBA << 32) | o_nChip; - err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, - HTMGT_MOD_MEMTHROTTLE, - HTMGT_RC_THROTTLE_INVALID_N, - i_mba->getAttr(), - data, true); - } - else if (i_utilization != 0) - { - //Make sure the calculated throttles meet the min - //utilization, if provided. - -/* TODO this hwp is changing for p9 - FAPI_INVOKE_HWP(err, mss_util_to_throttle, fapiTarget); -*/ - if (err) - { - TMGT_ERR("doMBAThrottleCalc: Failed call to " - "mss_util_to_throttle on MBA 0x%X", - i_mba->getAttr()); - } - else - { - //Get the value the procedure wrote - uint32_t nUtilMBA = i_mba->getAttr(); - - TRACUCOMP("doMBAThrottleCalc: mss_util_to_throttle" - " calculated N = %d", - nUtilMBA); - - //If mss_bulk_pwr_throttles calculated a value - //that doesn't meet the minimum requested utilization, - //then we have a problem. - if (nUtilMBA > o_nMBA) - { - TMGT_ERR("doMBAThrottleCalc: MSS_UTIL_N_PER_MBA 0x%X " - "> MSS_MEM_THROTTLE_N_PER_MBA 0x%X on MBA 0x%X", - nUtilMBA, o_nMBA, - i_mba->getAttr()); - - /*@ - * @errortype - * @reasoncode HTMGT_RC_THROTTLE_UTIL_ERROR - * @severity ERRL_SEV_UNRECOVERABLE - * @moduleid HTMGT_MOD_MEMTHROTTLE - * @userdata1 MBA HUID - * @userdata2[0:31] util based N - * @userdata2[32:63] calculated N - * @devdesc Throttle numerator calculated - * doesn't meet min utilization - */ - uint64_t data = ((uint64_t)nUtilMBA << 32) | o_nMBA; - err = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - HTMGT_MOD_MEMTHROTTLE, - HTMGT_RC_THROTTLE_UTIL_ERROR, - i_mba->getAttr(), - data, true); - } - } + TMGT_ERR("call_bulk_pwr_throttles: p9_mss_bulk_pwr_throttles " + "failed with rc=0x%04X", err->reasonCode()); } } - - if (err) + else { - err->collectTrace(HTMGT_COMP_NAME); - errlCommit(err, HTMGT_COMP_ID); - o_useSafeMode = true; + TMGT_ERR("call_bulk_pwr_throttles: call_utils_to_throttle failed with" + " rc=0x%04X", err->reasonCode()); } -} + return err; + +} // end call_bulk_pwr_throttles() /** - * Helper function to run the hardware procedures to calculate the - * throttle attributes used for redundant power. - * flow = htmgtCalcMemThrottle_redundantPwr + * Calculate throttles for when system has redundant power (N+1 mode) * - * @param[in] i_mbas - the list of functional MBAs - * @param[in] i_nSafeModeMBA - the safe mode MBA throttle numerator - * @param[in] i_nSafeModeChip - the safe mode MBA throttle numerator + * @param[in] i_fapi_target_list - list of FAPI MCS targets * @param[in] i_utilization - Minimum utilization value required * @param[in] i_efficiency - the regulator efficiency */ -void memPowerThrottleRedPower(TargetHandleList & i_mbas, - const uint32_t i_nSafeModeMBA, - const uint32_t i_nSafeModeChip, +errlHndl_t memPowerThrottleRedPower( + std::vector > i_fapi_target_list, const uint8_t i_utilization, const uint8_t i_efficiency) { + errlHndl_t err = NULL; Target* sys = NULL; uint32_t power = 0; uint32_t wattTarget = 0; - uint32_t nChip = 0; - uint32_t nMBA = 0; - bool useSafeMode = false; - targetService().getTopLevelTarget(sys); assert(sys != NULL); - //Get the max N+1 power allocated to memory + //Get the max redundant (N+1) power allocated to memory power = sys->getAttr(); - power *= 100; //centiWatts + power *= 100; // convert to centiWatts //Account for the regulator efficiency (percentage), if supplied if (i_efficiency != 0) @@ -344,72 +236,86 @@ void memPowerThrottleRedPower(TargetHandleList & i_mbas, power = (power * i_efficiency) / 100; } - //Find the Watt target for each MBA - if (i_mbas.size()) + //Find the Watt target for each MCS + if (i_fapi_target_list.size()) { - wattTarget = power / i_mbas.size(); + wattTarget = power / i_fapi_target_list.size(); } - TMGT_INF("memPowerThrottleRedPower: power = %d, wattTarget = %d", - power, wattTarget); + TMGT_INF("memPowerThrottleRedPower: N+1 power: %dW / %dcW per MCS", + power/100, wattTarget); - for( const auto & mba : i_mbas ) + //Calculate the throttles + err = call_bulk_pwr_throttles(i_fapi_target_list, + wattTarget, + i_utilization); + if (NULL == err) { - useSafeMode = false; - nMBA = nChip = 0; - - //Run the calculations - doMBAThrottleCalc(mba, wattTarget, i_utilization, - useSafeMode, nMBA, nChip); - - if (useSafeMode) + uint32_t nominal_mem_power = 0; + for(auto & mcs_fapi_target : i_fapi_target_list) { - nMBA = i_nSafeModeMBA; - nChip = i_nSafeModeChip; - TMGT_INF("memPowerThrottleRedPower: MBA 0x%X using safemode " - "numerator", - mba->getAttr()); + // Read HWP output parms: + ATTR_N_PLUS_ONE_N_PER_MBA_type l_slot = {0}; + ATTR_N_PLUS_ONE_N_PER_CHIP_type l_port = {0}; + ATTR_N_PLUS_ONE_MEM_POWER_type l_power = {0}; + FAPI_ATTR_GET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, + mcs_fapi_target, l_slot); + FAPI_ATTR_GET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, + mcs_fapi_target, l_port); + FAPI_ATTR_GET(fapi2::ATTR_MSS_PORT_MAXPOWER, + mcs_fapi_target, l_power); + nominal_mem_power += l_power[0] + l_power[1]; + + // Update MCS data (to be sent to OCC) + TARGETING::Target * mcs_target = + reinterpret_cast(mcs_fapi_target.get()); + ConstTargetHandle_t proc_target = getParentChip(mcs_target); + assert(proc_target != nullptr); + const uint8_t occ_instance = + proc_target->getAttr(); + uint8_t mcs_unit = 0xFF; + mcs_target->tryGetAttr(mcs_unit); + mcs_target->setAttr(l_slot); + mcs_target->setAttr(l_port); + mcs_target->setAttr(l_power); + + TMGT_INF("memPowerThrottleRedPower: NOMINAL: OCC%d/MCS%d - " + "N/slot: %d/%d, N/port: %d/%d, Power: %d/%dcW", + occ_instance, mcs_unit, l_slot[0], l_slot[1], + l_port[0], l_port[1], l_power[0], l_power[1]); } - - //Set the attributes we'll send to OCC later - TMGT_INF("memPowerThrottleRedPower: MBA 0x%X: N_PER_MBA = 0x%X, " - "N_PER_CHIP = 0x%X", - mba->getAttr(), nMBA, nChip); - - mba->setAttr(nMBA); - mba->setAttr(nChip); - + TMGT_INF("memPowerThrottleRedPower: Total Redundant Memory Power: %dW", + nominal_mem_power/100); + } + else + { + TMGT_ERR("memPowerThrottleRedPower: Failed to calculate redundant " + "power memory throttles, rc=0x%04X", + err->reasonCode()); } + return err; -} +} // end memPowerThrottleRedPower() /** - * Helper function to run the hardware procedures to calculate the - * throttle attributes used for oversubscription. - * flow = htmgtCalcMemThrottle_oversub + * Calculate throttles for when system is oversubscribed (N mode) * - * @param[in] i_mbas - the list of functional MBAs - * @param[in] i_nSafeModeMBA - the safe mode MBA throttle numerator - * @param[in] i_nSafeModeChip - the safe mode MBA throttle numerator + * @param[in] i_fapi_target_list - list of FAPI MCS targets * @param[in] i_utilization - Minimum utilization value required * @param[in] i_efficiency - the regulator efficiency */ -void memPowerThrottleOverSub(TargetHandleList & i_mbas, - const uint32_t i_nSafeModeMBA, - const uint32_t i_nSafeModeChip, - const uint8_t i_utilization, - const uint8_t i_efficiency) +errlHndl_t memPowerThrottleOverSub( + std::vector > i_fapi_target_list, + const uint8_t i_utilization, + const uint8_t i_efficiency) { + errlHndl_t err = NULL; Target* sys = NULL; uint32_t power = 0; uint32_t wattTarget = 0; - uint32_t nChip = 0; - uint32_t nMBA = 0; - bool useSafeMode = false; - targetService().getTopLevelTarget(sys); assert(sys != NULL); @@ -423,87 +329,278 @@ void memPowerThrottleOverSub(TargetHandleList & i_mbas, power = (power * i_efficiency) / 100; } - //Find the Watt target for each MBA - if (i_mbas.size()) + //Find the Watt target for each MCS + if (i_fapi_target_list.size()) { - wattTarget = power / i_mbas.size(); + wattTarget = power / i_fapi_target_list.size(); } - TMGT_INF("memPowerThrottleOverSub: power = %d, wattTarget = %d", - power, wattTarget); + TMGT_INF("memPowerThrottleOverSub: N power: %dW / %dcW per MCS", + power/100, wattTarget); - for ( const auto & mba : i_mbas ) + //Calculate the throttles + err = call_bulk_pwr_throttles(i_fapi_target_list, + wattTarget, + i_utilization); + if (NULL == err) { - useSafeMode = false; - nMBA = nChip = 0; - - //Run the calculations - doMBAThrottleCalc(mba, wattTarget, i_utilization, - useSafeMode, nMBA, nChip); - - if (useSafeMode) + uint32_t oversub_mem_power = 0; + for(auto & mcs_fapi_target : i_fapi_target_list) { - nMBA = i_nSafeModeMBA; - nChip = i_nSafeModeChip; - TMGT_INF("memPowerThrottleOverSub: MBA 0x%X using safemode " - "numerator", - mba->getAttr()); + // Read HWP output parms: + ATTR_OVERSUB_N_PER_MBA_type l_slot = {0}; + ATTR_OVERSUB_N_PER_CHIP_type l_port = {0}; + ATTR_OVERSUB_MEM_POWER_type l_power = {0}; + FAPI_ATTR_GET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, + mcs_fapi_target, l_slot); + FAPI_ATTR_GET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, + mcs_fapi_target, l_port); + FAPI_ATTR_GET(fapi2::ATTR_MSS_PORT_MAXPOWER, + mcs_fapi_target, l_power); + oversub_mem_power += l_power[0] + l_power[1]; + + // Update MCS data (to be sent to OCC) + TARGETING::Target * mcs_target = + reinterpret_cast(mcs_fapi_target.get()); + ConstTargetHandle_t proc_target = getParentChip(mcs_target); + assert(proc_target != nullptr); + const uint8_t occ_instance = + proc_target->getAttr(); + uint8_t mcs_unit = 0xFF; + mcs_target->tryGetAttr(mcs_unit); + mcs_target->setAttr(l_slot); + mcs_target->setAttr(l_port); + mcs_target->setAttr(l_power); + + TMGT_INF("memPowerThrottleOverSub: OVERSUB: OCC%d/MCS%d - " + "N/slot: %d/%d, N/port: %d/%d, Power: %d/%dcW", + occ_instance, mcs_unit, l_slot[0], l_slot[1], + l_port[0], l_port[1], l_power[0], l_power[1]); } + TMGT_INF("memPowerThrottleOverSub: Total Oversubscription Memory" + " Power: %dW", oversub_mem_power/100); + } + else + { + TMGT_ERR("memPowerThrottleOverSub: Failed to calculate redundant " + "power memory throttles, rc=0x%04X", + err->reasonCode()); + } + + return err; + +} // end memPowerThrottleOverSub() + - //Set the attributes we'll send to OCC later - TMGT_INF("memPowerThrottleOverSub: MBA 0x%X: N_PER_MBA = 0x%X, " - "N_PER_CHIP = 0x%X", - mba->getAttr(), nMBA, nChip); - mba->setAttr(nMBA); - mba->setAttr(nChip); +/** + * Run hardware procedures to calculate the throttles for power capping + * + * @param[in] i_fapi_target_list - list of FAPI MCS targets + * @param[in] i_utilization - Minimum utilization value required + */ +errlHndl_t memPowerThrottlePowercap( + std::vector < fapi2::Target< fapi2::TARGET_TYPE_MCS>> i_fapi_target_list, + const uint8_t i_utilization) +{ + errlHndl_t err = NULL; + + TMGT_INF("memPowerThrottlePowercap: Calculating throttles for util: %d", + i_utilization); + if (i_utilization != 0) + { + //Calculate the throttles + err = call_utils_to_throttle(i_fapi_target_list, i_utilization); } + if (NULL == err) + { + uint32_t pcap_mem_power = 0; + for(auto & mcs_fapi_target : i_fapi_target_list) + { + TARGETING::Target * mcs_target = + reinterpret_cast(mcs_fapi_target.get()); + ConstTargetHandle_t proc_target = getParentChip(mcs_target); + assert(proc_target != nullptr); + const uint8_t occ_instance = + proc_target->getAttr(); + uint8_t mcs_unit = 0xFF; + mcs_target->tryGetAttr(mcs_unit); + + // Read HWP output parms (if the procedure was run): + ATTR_POWERCAP_N_PER_MBA_type l_slot = {0xFF, 0xFF}; + ATTR_POWERCAP_N_PER_CHIP_type l_port = {0xFF, 0xFF}; + ATTR_POWERCAP_MEM_POWER_type l_power = {0}; + if (i_utilization != 0) + { + FAPI_ATTR_GET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, + mcs_fapi_target, l_slot); + FAPI_ATTR_GET(fapi2::ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, + mcs_fapi_target, l_port); + FAPI_ATTR_GET(fapi2::ATTR_MSS_PORT_MAXPOWER, + mcs_fapi_target, l_power); + } + // else N values will be 0xFF and will be overwritten below + + // Validate pcap throttles are the lowest throttles + ATTR_N_PLUS_ONE_N_PER_MBA_type l_slot_redun = {0}; + ATTR_N_PLUS_ONE_N_PER_CHIP_type l_port_redun = {0}; + ATTR_N_PLUS_ONE_MEM_POWER_type l_power_redun = {0}; + mcs_target->tryGetAttr(l_slot_redun); + mcs_target->tryGetAttr(l_port_redun); + mcs_target->tryGetAttr(l_power_redun); + ATTR_OVERSUB_N_PER_MBA_type l_slot_oversub = {0}; + ATTR_OVERSUB_N_PER_CHIP_type l_port_oversub = {0}; + ATTR_OVERSUB_MEM_POWER_type l_power_oversub = {0}; + mcs_target->tryGetAttr(l_slot_oversub); + mcs_target->tryGetAttr(l_port_oversub); + mcs_target->tryGetAttr(l_power_oversub); + unsigned int mca_index; + for (mca_index = 0; mca_index < TMGT_MAX_MCA_PER_MCS; ++mca_index) + { + if (l_slot[mca_index] > l_slot_oversub[mca_index]) + { + TMGT_INF("memPowerThrottlePowercap: MCS%d/MCA%d" + " oversub throttle (%d) < pcap throttle (%d)", + mcs_unit, mca_index, + l_slot_oversub[mca_index], l_slot[mca_index]); + l_slot[mca_index] = l_slot_oversub[mca_index]; + l_port[mca_index] = l_port_oversub[mca_index]; + l_power[mca_index] = l_power_oversub[mca_index]; + } + if (l_slot[mca_index] > l_slot_redun[mca_index]) + { + TMGT_INF("memPowerThrottlePowercap: MCS%d/MCA%d - " + " redun throttle (%d) < pcap throttle (%d)", + mcs_unit, mca_index, + l_slot_redun[mca_index], l_slot[mca_index]); + l_slot[mca_index] = l_slot_redun[mca_index]; + l_port[mca_index] = l_port_redun[mca_index]; + l_power[mca_index] = l_power_redun[mca_index]; + } + } -} + // Update MCS data (to be sent to OCC) + mcs_target->setAttr(l_slot); + mcs_target->setAttr(l_port); + mcs_target->setAttr(l_power); + pcap_mem_power += l_power[0] + l_power[1]; + + // Trace Results + TMGT_INF("memPowerThrottlePowercap: PCAP: OCC%d/MCS%d - " + "N/slot: %d/%d, N/port: %d/%d, Power: %d/%dcW", + occ_instance, mcs_unit, l_slot[0], l_slot[1], + l_port[0], l_port[1], l_power[0], l_power[1]); + } + TMGT_INF("memPowerThrottlePowercap: Total PowerCap Memory" + " Power: %dW", pcap_mem_power/100); + } + else + { + TMGT_ERR("memPowerThrottlePowercap: Failed to calculate powercap " + "memory throttles, rc=0x%04X", + err->reasonCode()); + } + return err; +} // end memPowerThrottlePowercap() -void calcMemThrottles() + + +errlHndl_t calcMemThrottles() { Target* sys = NULL; - TargetHandleList mbas; targetService().getTopLevelTarget(sys); assert(sys != NULL); - uint32_t nSafeModeMBA = - sys->getAttr(); - - uint32_t nSafeModeChip = - sys->getAttr(); - - uint8_t utilization = + uint8_t min_utilization = sys->getAttr(); - - uint8_t efficiency = + if (min_utilization == 0) + { + uint32_t l_safe_n_per_mba = + sys->getAttr(); + TMGT_INF("MIN_MEM_UTILIZATION_THROTTLING is 0, so reading " + "ATTR_MSS_MRW_SAFEMODE_MEM_THROTTLED_N_COMMANDS_PER_PORT:" + " %d", l_safe_n_per_mba); + if (l_safe_n_per_mba == 0) + { + l_safe_n_per_mba = 10; + TMGT_ERR("ATTR_MSS_MRW_SAFEMODE_MEM_THROTTLED_N_COMMANDS_PER_PORT" + " is 0! Using %d", l_safe_n_per_mba); + } + } + const uint8_t efficiency = sys->getAttr(); + TMGT_INF("calcMemThrottles: Using min utilization=%d, efficiency=%d" + " percent", min_utilization, efficiency); - TMGT_INF("calcMemThrottles: Using nSafeModeMBA=0x%X, nSafeModeChip=0x%X", - nSafeModeMBA, nSafeModeChip); - - TMGT_INF("calcMemThrottles: Using utilization=%d, efficiency=%d percent", - utilization, efficiency); + //Get all functional MCSs + TargetHandleList mcs_list; + getAllChiplets(mcs_list, TYPE_MCS, true); + TMGT_INF("calcMemThrottles: found %d MCSs", mcs_list.size()); + // Create a FAPI Target list for HWP + std::vector < fapi2::Target< fapi2::TARGET_TYPE_MCS>> l_fapi_target_list; + for(const auto & mcs_target : mcs_list) + { + uint32_t mcs_huid = 0xFFFFFFFF; + uint8_t mcs_unit = 0xFF; + mcs_target->tryGetAttr(mcs_huid); + mcs_target->tryGetAttr(mcs_unit); + + // Query the functional MCAs for this MCS + TARGETING::TargetHandleList mca_list; + getChildAffinityTargetsByState(mca_list, mcs_target, CLASS_UNIT, + TYPE_MCA, UTIL_FILTER_FUNCTIONAL); + uint8_t occ_instance = 0xFF; + ConstTargetHandle_t proc_target = getParentChip(mcs_target); + assert(proc_target != nullptr); + occ_instance = proc_target->getAttr(); + TMGT_INF("calcMemThrottles: OCC%d, MCS%d HUID:0x%08X has %d" + " functional MCSs", + occ_instance, mcs_unit, mcs_huid, mca_list.size()); + + // Convert to FAPI target and add to list + fapi2::Target l_fapiTarget(mcs_target); + l_fapi_target_list.push_back(l_fapiTarget); + } - //Get all functional MBAs - getAllChiplets(mbas, TYPE_MBA, true); + errlHndl_t err = NULL; + do + { + //Calculate Throttle settings for Over Temperature + err = memPowerThrottleOT(l_fapi_target_list, min_utilization); + if (NULL != err) break; + + //Calculate Throttle settings for Nominal/Turbo + err = memPowerThrottleRedPower(l_fapi_target_list, + min_utilization, efficiency); + if (NULL != err) break; + + //Calculate Throttle settings for Oversubscription + err = memPowerThrottleOverSub(l_fapi_target_list, + min_utilization, efficiency); + if (NULL != err) break; + + //Calculate Throttle settings for Power Capping + uint8_t pcap_min_utilization; + if (!sys->tryGetAttr + (pcap_min_utilization)) + { + pcap_min_utilization = 0; + } + err = memPowerThrottlePowercap(l_fapi_target_list,pcap_min_utilization); - //Calculate Throttle settings for Over Temperature - memPowerThrottleOT(mbas, nSafeModeMBA, utilization); + } while(0); - //Calculate Throttle settings for Redundant Power - memPowerThrottleRedPower(mbas, nSafeModeMBA, nSafeModeChip, - utilization, efficiency); + if (err) + { + err->collectTrace(HTMGT_COMP_NAME); + } - //Calculate Throttle settings for Oversubscription - memPowerThrottleOverSub(mbas, nSafeModeMBA, nSafeModeChip, - utilization, efficiency); + return err; } } // End namespace diff --git a/src/usr/htmgt/htmgt_memthrottles.H b/src/usr/htmgt/htmgt_memthrottles.H index 7816da98f9a..37b79bf54c3 100644 --- a/src/usr/htmgt/htmgt_memthrottles.H +++ b/src/usr/htmgt/htmgt_memthrottles.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014 */ +/* Contributors Listed Below - COPYRIGHT 2014,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -25,18 +25,23 @@ #ifndef HTMGT_MEMTHROTTLES_H #define HTMGT_MEMTHROTTLES_H +#include namespace HTMGT { + // NIMBUS: + const uint8_t TMGT_MAX_MCS_PER_MCBIST = 2; + const uint8_t TMGT_MAX_MCA_PER_MCS = 2; + const uint8_t TMGT_MAX_DIMM_PER_MCA = 2; + const uint8_t TMGT_MAX_DIMM_PER_MCS = + TMGT_MAX_DIMM_PER_MCA * TMGT_MAX_MCA_PER_MCS; /** * Calculates the memory throttling numerator values for the OT, * oversubscription, and redundant power cases. The results are * stored in attributes under the corresponding MBAs. */ - void calcMemThrottles(); - - + errlHndl_t calcMemThrottles(); }; #endif diff --git a/src/usr/htmgt/htmgt_utility.H b/src/usr/htmgt/htmgt_utility.H index 7872a1f788d..5ef5d745733 100644 --- a/src/usr/htmgt/htmgt_utility.H +++ b/src/usr/htmgt/htmgt_utility.H @@ -117,7 +117,7 @@ namespace HTMGT enum internalFlagTypes { FLAG_HALT_ON_OCC_SRC = 0x00800000, // Prevent resets after SRC - FLAG_SEND_MEM_CONFIG = 0x00000800, // Enables sending mem config + FLAG_DISABLE_MEM_CONFIG = 0x00000800, // Disable sending mem config FLAG_HALT_ON_RESET_FAIL = 0x00000100, // Stop additional resets FLAG_EXT_RESET_DISABLED = 0x00000080, // Ignore opal-prd/BMC resets FLAG_DISABLE_MEM_THROTTLE = 0x00000040, diff --git a/src/usr/htmgt/makefile b/src/usr/htmgt/makefile index e73d02705cd..8ddea9b092e 100644 --- a/src/usr/htmgt/makefile +++ b/src/usr/htmgt/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2014,2016 +# Contributors Listed Below - COPYRIGHT 2014,2017 # [+] International Business Machines Corp. # # @@ -28,6 +28,15 @@ MODULE = htmgt # objects common to hostboot and hbrt include htmgt_common.mk +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/memory +EXTRAINCDIR += ${ROOTPATH}/src/import + +PROCEDURES_PATH = ${ROOTPATH}/src/import/chips/p9/procedures +EXTRAINCDIR += $(PROCEDURES_PATH)/hwp/memory +include ${ROOTPATH}/procedure.rules.mk +OBJS += $(PROCEDURES_PATH)/hwp/memory/p9_mss_utils_to_throttle.o +OBJS += $(PROCEDURES_PATH)/hwp/memory/p9_mss_bulk_pwr_throttles.o + # objects unique to hostboot OBJS += htmgt_memthrottles.o diff --git a/src/usr/htmgt/test/htmgtcfgtest.H b/src/usr/htmgt/test/htmgtcfgtest.H index 776d24e2a12..ab71ec03487 100644 --- a/src/usr/htmgt/test/htmgtcfgtest.H +++ b/src/usr/htmgt/test/htmgtcfgtest.H @@ -127,31 +127,37 @@ public: //Make sure all of the numerators are set for (mba=mbas.begin();mba!=mbas.end();++mba) { - if (0 == (*mba)->getAttr()) + ATTR_OT_MIN_N_PER_MBA_type n; + (*mba)->tryGetAttr(n); + if ((0 == n[0]) && (0 == n[1])) { TS_FAIL("MBA 0x%X has value of zero for OT_MIN_N_PER_MBA", (*mba)->getAttr()); } - if (0 == (*mba)->getAttr()) + (*mba)->tryGetAttr(n); + if ((0 == n[0]) && (0 == n[1])) { TS_FAIL("MBA 0x%X has value of zero for N_PLUS_ONE_N_PER_MBA", (*mba)->getAttr()); } - if (0 == (*mba)->getAttr()) + (*mba)->tryGetAttr(n); + if ((0 == n[0]) && (0 == n[1])) { TS_FAIL("MBA 0x%X has value of zero for N_PLUS_ONE_N_PER_CHIP", (*mba)->getAttr()); } - if (0 == (*mba)->getAttr()) + (*mba)->tryGetAttr(n); + if ((0 == n[0]) && (0 == n[1])) { TS_FAIL("MBA 0x%X has value of zero for OVERSUB_N_PER_MBA", (*mba)->getAttr()); } - if (0 == (*mba)->getAttr()) + (*mba)->tryGetAttr(n); + if ((0 == n[0]) && (0 == n[1])) { TS_FAIL("MBA 0x%X has value of zero for OVERSUB_N_PER_CHIP", (*mba)->getAttr()); @@ -179,7 +185,7 @@ public: { memset(data, 0, 4*KILOBYTE); - getMemThrottleMessageData(*occ, data, size); + getMemThrottleMessageData(*occ, 0, data, size); if (data[0] != OCC_CFGDATA_MEM_THROTTLE) { diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml index e762f042684..8a91bdbf471 100644 --- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml @@ -618,139 +618,6 @@ - - PSTATE_TABLE - HTMGT PSTATE data - - - 3656 - - volatile-zeroed - - - - - - PSTATE_TABLE_MFG - HTMGT PSTATE data for mfg - - - 3656 - - volatile-zeroed - - - - - - OCC_CONTROL_DATA - OCC operational data - - - - 256 - - volatile-zeroed - - - - - - HTMGT_INTERNAL_FLAGS - HTMGT internal flags - - - - 0 - - - volatile-zeroed - - - - - - OT_MIN_N_PER_MBA - - Lowest per MBA numerator ever allowed when OCC is - throttling due to OT. - - - - 0 - - - volatile-zeroed - - - - - - N_PLUS_ONE_N_PER_MBA - - Static per MBA numerator setting when not in - oversubscription. Calculated based on MRW memory - power with redundant power. Lowest per MBA numerator - ever allowed when OCC is throttling due to OT. - - - - 0 - - - volatile-zeroed - - - - - - N_PLUS_ONE_N_PER_CHIP - - Static per chip numerator setting when not in oversubscription. - - - - 0 - - - volatile-zeroed - - - - - - OVERSUB_N_PER_MBA - - Static per MBA numerator setting when in oversubscription. - Calculated based on MRW oversubscription memory power. - - - - 0 - - - volatile-zeroed - - - - - - OVERSUB_N_PER_CHIP - - Static per chip numerator setting when in oversubscription. - - - - 0 - - - volatile-zeroed - - - - - - VPD_SWITCHES @@ -796,19 +663,6 @@ - - HTMGT_SAFEMODE - 1 = in safemode. 0 = in normal mode. - - - - - volatile-zeroed - - - - - SPCWKUP_COUNT diff --git a/src/usr/targeting/common/xmltohb/attribute_types_openpower.xml b/src/usr/targeting/common/xmltohb/attribute_types_openpower.xml index 3a7f00f296f..2635b8ea4bb 100644 --- a/src/usr/targeting/common/xmltohb/attribute_types_openpower.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types_openpower.xml @@ -497,10 +497,39 @@ OPEN_POWER_MIN_MEM_UTILIZATION_THROTTLING - Minimum memory utilization for memory throttling + Minimum memory utilization percent (from 0-100) + for memory throttling - + + + non-volatile + + + + + OPEN_POWER_MIN_MEM_UTILIZATION_POWER_CAP + + Minimum memory utilization percent (from 0-100) + for power capping + + + + + non-volatile + + + + + OPEN_POWER_VRM_READ_TIMEOUT_SEC + + VRM read timeout in seconds (from 0-255) + Use 0 to disable VRM OT monitoring + + + + 0 + non-volatile @@ -821,4 +850,257 @@ ID for the sensor number returned with the elog. --> + + + + HTMGT_SAFEMODE + 1 = in safemode. 0 = in normal mode. + + + + + volatile-zeroed + + + + + + + PSTATE_TABLE + HTMGT PSTATE data + + + 3656 + + volatile-zeroed + + + + + + PSTATE_TABLE_MFG + HTMGT PSTATE data for mfg + + + 3656 + + volatile-zeroed + + + + + + OCC_CONTROL_DATA + OCC operational data + + + + 256 + + volatile-zeroed + + + + + + HTMGT_INTERNAL_FLAGS + HTMGT internal flags + + + + 0 + + + volatile-zeroed + + + + + + OT_MIN_N_PER_MBA + + Lowest per MBA numerator ever allowed when OCC is + throttling due to OT. + + + + 0,0 + + 2 + + volatile-zeroed + + + + + + OT_MEM_POWER + + Maximum memory power in centiWatts with throttle + set to minimum. + + + + 0,0 + + 2 + + volatile-zeroed + + + + + + N_PLUS_ONE_N_PER_MBA + + Static per MBA numerator setting when not in + oversubscription. Calculated based on MRW memory + power with redundant power. Lowest per MBA numerator + ever allowed when OCC is throttling due to OT. + + + + 0,0 + + 2 + + volatile-zeroed + + + + + + N_PLUS_ONE_N_PER_CHIP + + Static per chip numerator setting when not in oversubscription. + + + + 0,0 + + 2 + + volatile-zeroed + + + + + + N_PLUS_ONE_MEM_POWER + + Maximum memory power in centiWatts with throttle + set to nominal/turbo + + + + 0,0 + + 2 + + volatile-zeroed + + + + + + OVERSUB_N_PER_MBA + + Static per MBA numerator setting when in oversubscription. + Calculated based on MRW oversubscription memory power. + + + + 0,0 + + 2 + + volatile-zeroed + + + + + + OVERSUB_N_PER_CHIP + + Static per chip numerator setting when in oversubscription. + + + + 0,0 + + 2 + + volatile-zeroed + + + + + + OVERSUB_MEM_POWER + + Maximum memory power in centiWatts with throttle + set to oversubscription. + + + + 0,0 + + 2 + + volatile-zeroed + + + + + + + POWERCAP_N_PER_MBA + + Static per slot numerator setting when power is being capped. + + + + 0,0 + + 2 + + volatile-zeroed + + + + + + POWERCAP_N_PER_CHIP + + Static per chip numerator setting when power is being capped. + + + + 0,0 + + 2 + + volatile-zeroed + + + + + + POWERCAP_MEM_POWER + + Maximum memory power in centiWatts with when power is being capped. + + + + 0,0 + + 2 + + volatile-zeroed + + + + + + diff --git a/src/usr/targeting/common/xmltohb/target_types_hb.xml b/src/usr/targeting/common/xmltohb/target_types_hb.xml index 39bc79fff03..2626f004d24 100755 --- a/src/usr/targeting/common/xmltohb/target_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/target_types_hb.xml @@ -37,9 +37,6 @@ IBSCOM_ENABLE_OVERRIDE HB_MUTEX_TEST_LOCK HB_EXISTING_IMAGE - OCC_CONTROL_DATA - HTMGT_INTERNAL_FLAGS - HTMGT_SAFEMODE CLEAR_DIMM_SPD_ENABLE OCC_COMMON_AREA_PHYS_ADDR ATTN_CHK_ALL_PROCS @@ -233,16 +230,6 @@ HB_TARGET_SCOMABLE - - occ - - PSTATE_TABLE - - - PSTATE_TABLE_MFG - - - chip-tpm-cectpm diff --git a/src/usr/targeting/common/xmltohb/target_types_openpower.xml b/src/usr/targeting/common/xmltohb/target_types_openpower.xml index 278f100706c..83abac45743 100644 --- a/src/usr/targeting/common/xmltohb/target_types_openpower.xml +++ b/src/usr/targeting/common/xmltohb/target_types_openpower.xml @@ -49,6 +49,9 @@ sys-sys-power9 + OCC_CONTROL_DATA + HTMGT_INTERNAL_FLAGS + HTMGT_SAFEMODE ADC_CHANNEL_FUNC_IDS ADC_CHANNEL_SENSOR_NUMBERS ADC_CHANNEL_GNDS @@ -72,6 +75,8 @@ OPEN_POWER_DIMM_READ_TIMEOUT_SEC OPEN_POWER_PROC_ERROR_TEMP_DEG_C OPEN_POWER_MIN_MEM_UTILIZATION_THROTTLING + OPEN_POWER_MIN_MEM_UTILIZATION_POWER_CAP + OPEN_POWER_VRM_READ_TIMEOUT_SEC OPEN_POWER_PROC_READ_TIMEOUT_SEC OPEN_POWER_REGULATOR_EFFICIENCY_FACTOR OPEN_POWER_MIN_POWER_CAP_WATTS @@ -124,4 +129,29 @@ BMC_SW_TYPE + + occ + + PSTATE_TABLE + + + PSTATE_TABLE_MFG + + + + + unit-mcs-power9 + OT_MIN_N_PER_MBA + OT_MEM_POWER + N_PLUS_ONE_N_PER_MBA + N_PLUS_ONE_N_PER_CHIP + N_PLUS_ONE_MEM_POWER + OVERSUB_N_PER_MBA + OVERSUB_N_PER_CHIP + OVERSUB_MEM_POWER + POWERCAP_N_PER_MBA + POWERCAP_N_PER_CHIP + POWERCAP_MEM_POWER + +