summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2014-10-22 10:32:01 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-12-13 10:16:26 -0600
commit61c9acc8fd01eab34b942a284ac851bbd990d9f7 (patch)
tree92c86f3f8e1ad6b3b5f5cf016ae8d8cfb61c88e2
parent5cdd71606bc1577f9cfe87b326190b84b9137dee (diff)
downloadtalos-hostboot-61c9acc8fd01eab34b942a284ac851bbd990d9f7.tar.gz
talos-hostboot-61c9acc8fd01eab34b942a284ac851bbd990d9f7.zip
HTMGT code to build several of the OCC config message payloads.
Includes an interface to run the hardware procedures related to memory throttling, which will write attributes needed for an OCC config message. Change-Id: I302e5c2f0e354dd57d6f6f9c8ad81095277a3d8c RTC: 114286 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/14131 Reviewed-by: Christopher Cain <cjcain@us.ibm.com> Tested-by: Jenkins Server Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--src/include/usr/htmgt/htmgt_reasoncodes.H4
-rw-r--r--src/usr/htmgt/htmgt.C2
-rw-r--r--src/usr/htmgt/htmgt_activate.C2
-rw-r--r--src/usr/htmgt/htmgt_activate.H5
-rw-r--r--src/usr/htmgt/htmgt_cfgdata.C578
-rw-r--r--src/usr/htmgt/htmgt_cfgdata.H174
-rw-r--r--src/usr/htmgt/htmgt_common.mk1
-rw-r--r--src/usr/htmgt/htmgt_memthrottles.C509
-rw-r--r--src/usr/htmgt/htmgt_memthrottles.H (renamed from src/usr/htmgt/htmgt_config.H)48
-rw-r--r--src/usr/htmgt/htmgt_occ.C2
-rw-r--r--src/usr/htmgt/htmgt_occ.H8
-rw-r--r--src/usr/htmgt/htmgt_occcmd.C2
-rw-r--r--src/usr/htmgt/htmgt_poll.C2
-rw-r--r--src/usr/htmgt/htmgt_utility.C27
-rw-r--r--src/usr/htmgt/htmgt_utility.H12
-rw-r--r--src/usr/htmgt/makefile9
-rw-r--r--src/usr/htmgt/test/htmgtcfgtest.H492
-rw-r--r--src/usr/htmgt/test/pstatetest.H12
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types_hb.xml94
-rw-r--r--src/usr/targeting/common/xmltohb/simics_MURANO.system.xml16
-rw-r--r--src/usr/targeting/common/xmltohb/simics_VENICE.system.xml16
-rw-r--r--src/usr/targeting/common/xmltohb/target_types_hb.xml16
22 files changed, 1983 insertions, 48 deletions
diff --git a/src/include/usr/htmgt/htmgt_reasoncodes.H b/src/include/usr/htmgt/htmgt_reasoncodes.H
index c830df27d..f675a0a23 100644
--- a/src/include/usr/htmgt/htmgt_reasoncodes.H
+++ b/src/include/usr/htmgt/htmgt_reasoncodes.H
@@ -34,6 +34,7 @@ namespace HTMGT
HTMGT_MOD_LOAD_START_STATUS = 0x00,
HTMGT_MOD_WAIT_FOR_OCC_ACTIVE = 0x01,
HTMGT_MOD_WAIT_FOR_OCC_READY = 0x02,
+ HTMGT_MOD_MEMTHROTTLE = 0x03,
HTMGT_MOD_OCC_POLL = 0x76,
HTMGT_MOD_READ_OCC_SRAM = 0x85,
HTMGT_MOD_SEND_OCC_CMD = 0x90,
@@ -46,6 +47,9 @@ namespace HTMGT
enum htmgtReasonCode
{
HTMGT_RC_INTERNAL_ERROR = HTMGT_COMP_ID | 0x01,
+ HTMGT_RC_THROTTLE_UTIL_ERROR = HTMGT_COMP_ID | 0x02,
+ HTMGT_RC_THROTTLE_INVALID_N = HTMGT_COMP_ID | 0x03,
+ HTMGT_RC_OT_THROTTLE_INVALID_N = HTMGT_COMP_ID | 0x04,
HTMGT_RC_NO_SUPPORT = HTMGT_COMP_ID | 0x0F,
HTMGT_RC_OCC_RESET = HTMGT_COMP_ID | 0x15,
HTMGT_RC_OCC_CRIT_FAILURE = HTMGT_COMP_ID | 0x16,
diff --git a/src/usr/htmgt/htmgt.C b/src/usr/htmgt/htmgt.C
index e4625b0af..d693a52b0 100644
--- a/src/usr/htmgt/htmgt.C
+++ b/src/usr/htmgt/htmgt.C
@@ -26,7 +26,7 @@
#include <htmgt/htmgt.H>
#include <htmgt/htmgt_reasoncodes.H>
#include "htmgt_activate.H"
-#include "htmgt_config.H"
+#include "htmgt_cfgdata.H"
#include "htmgt_utility.H"
// Targeting support
diff --git a/src/usr/htmgt/htmgt_activate.C b/src/usr/htmgt/htmgt_activate.C
index e094b491f..ec9a7035c 100644
--- a/src/usr/htmgt/htmgt_activate.C
+++ b/src/usr/htmgt/htmgt_activate.C
@@ -28,7 +28,7 @@
#include "htmgt_utility.H"
#include "htmgt_activate.H"
#include "htmgt_occcmd.H"
-#include "htmgt_config.H"
+#include "htmgt_cfgdata.H"
#include "htmgt_poll.H"
// Targeting support
diff --git a/src/usr/htmgt/htmgt_activate.H b/src/usr/htmgt/htmgt_activate.H
index 83cc79cec..4c0bf9fd0 100644
--- a/src/usr/htmgt/htmgt_activate.H
+++ b/src/usr/htmgt/htmgt_activate.H
@@ -75,5 +75,10 @@ namespace HTMGT
*/
errlHndl_t setOccActiveSensors();
+ /**
+ * @brief send all occ configuration messages to the OCCs
+ */
+ void sendOccConfigData();
+
} // end namespace
#endif
diff --git a/src/usr/htmgt/htmgt_cfgdata.C b/src/usr/htmgt/htmgt_cfgdata.C
new file mode 100644
index 000000000..d0a1151c0
--- /dev/null
+++ b/src/usr/htmgt/htmgt_cfgdata.C
@@ -0,0 +1,578 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/htmgt/htmgt_cfgdata.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/attributes.H>
+#include <targeting/common/utilFilter.H>
+#include "htmgt_cfgdata.H"
+#include "htmgt_utility.H"
+
+
+using namespace TARGETING;
+
+
+//for unit testing
+//#define TRACUCOMP(args...) TMGT_INF(args)
+#define TRACUCOMP(args...)
+
+namespace HTMGT
+{
+
+/** OCC configuration data message versions */
+enum occCfgDataVersion
+{
+ OCC_CFGDATA_PSTATE_VERSION = 0x10,
+ OCC_CFGDATA_FREQ_POINT_VERSION = 0x10,
+ OCC_CFGDATA_APSS_VERSION = 0x10,
+ OCC_CFGDATA_MEM_CONFIG_VERSION = 0x10,
+ OCC_CFGDATA_PCAP_CONFIG_VERSION = 0x10,
+ OCC_CFGDATA_SYS_CONFIG_VERSION = 0x10,
+ OCC_CFGDATA_MEM_THROTTLE_VERSION = 0x10,
+ OCC_CFGDATA_TCT_CONFIG_VERSION = 0x10
+};
+
+void getMemConfigMessageData(const TargetHandle_t i_occ,
+ bool i_monitoringEnabled,
+ uint8_t* o_data, uint64_t & o_size)
+{
+ uint64_t index = 0;
+
+ assert(o_data != NULL);
+
+ o_data[index++] = OCC_CFGDATA_MEM_CONFIG;
+ o_data[index++] = OCC_CFGDATA_MEM_CONFIG_VERSION;
+ size_t numSetsOffset = index++; //Will fill in numSets at the end
+
+ //Next, the following format repeats per set of data
+ //Bytes 0-3: Reserved
+ //Bytes 4-5 hardware sensor ID
+ //Bytes 6-7: temperature sensor ID
+ //Byte 8: Centaur position 0-7
+ //Byte 9: DIMM position 0-7
+ //Bytes 10-11: Reserved
+
+ if (i_monitoringEnabled)
+ {
+ TargetHandleList centaurs;
+ TargetHandleList mbas;
+ TargetHandleList dimms;
+ TargetHandleList::const_iterator centaur;
+ TargetHandleList::const_iterator mba;
+ TargetHandleList::const_iterator dimm;
+ uint8_t centPos = 0;
+ uint8_t dimmPos = 0;
+ uint8_t numSets = 0;
+ uint16_t sensor = 0;
+
+
+ ConstTargetHandle_t proc = getParentChip(i_occ);
+ assert(proc != NULL);
+
+ getChildAffinityTargets(centaurs, proc, CLASS_CHIP, TYPE_MEMBUF);
+
+ TRACUCOMP("Proc 0x%X has %d centaurs",
+ proc->getAttr<ATTR_HUID>(),
+ centaurs.size());
+
+ for (centaur=centaurs.begin(); centaur!=centaurs.end(); ++centaur)
+ {
+ numSets++;
+
+ centPos = (*centaur)->getAttr<ATTR_POSITION>();
+
+ //Do the entry for the Centaur itself
+
+ //Reserved
+ memset(&o_data[index], 0, 4);
+ index += 4;
+
+ //Hardware Sensor ID
+ sensor = 0; //TODO RTC 115294
+ memcpy(&o_data[index], &sensor, 2);
+ index += 2;
+
+ //Temperature Sensor ID
+ sensor = 0; //TODO RTC 115294
+ memcpy(&o_data[index], &sensor, 2);
+ index += 2;
+
+ //Centaur #
+ o_data[index++] = centPos;
+
+ //Dimm # (0xFF since a centaur)
+ o_data[index++] = 0xFF;
+
+ //Reserved
+ memset(&o_data[index], 0, 2);
+ index += 2;
+
+
+ mbas.clear();
+ getChildAffinityTargets(mbas, *centaur,
+ CLASS_UNIT, TYPE_MBA);
+
+ for (mba=mbas.begin(); mba!=mbas.end(); ++mba)
+ {
+ dimms.clear();
+ getChildAffinityTargets(dimms, *mba,
+ CLASS_LOGICAL_CARD, TYPE_DIMM);
+
+ TRACUCOMP("MBA 0x%X has %d DIMMs",
+ (*mba)->getAttr<ATTR_HUID>(), dimms.size());
+
+ for (dimm=dimms.begin(); dimm!=dimms.end(); ++dimm)
+ {
+ //Fill in the DIMM entry
+ numSets++;
+
+ dimmPos = getOCCDIMMPos(*mba, *dimm);
+
+ //Reserved
+ memset(&o_data[index], 0, 4);
+ index += 4;
+
+ //Hardware Sensor ID
+ sensor = 0; //TODO RTC 115294
+ memcpy(&o_data[index], &sensor, 2);
+ index += 2;
+
+ //Temperature Sensor ID
+ sensor = 0; //TODO RTC 115294
+ memcpy(&o_data[index], &sensor, 2);
+ index += 2;
+
+ //Centaur #
+ o_data[index++] = centPos;
+
+ //DIMM #
+ o_data[index++] = dimmPos;
+
+ //Reserved
+ memset(&o_data[index], 0, 2);
+ index += 2;
+
+ }
+ }
+ }
+
+ TMGT_INF("getMemConfigMessageData: returning %d"
+ " sets of data for OCC 0x%X",
+ numSets, i_occ->getAttr<ATTR_HUID>());
+
+ o_data[numSetsOffset] = numSets;
+ }
+ else
+ {
+ TMGT_INF("getMemConfigMessageData: Mem monitoring is disabled");
+
+ //A zero in byte 2 (numSets) means monitoring is disabled
+ o_data[2] = 0;
+ }
+
+ o_size = index;
+
+}
+
+
+
+
+void getMemThrottleMessageData(const TargetHandle_t i_occ,
+ uint8_t* o_data, uint64_t & o_size)
+{
+ uint8_t centPos = 0;
+ uint8_t mbaPos = 0;
+ uint8_t numSets = 0;
+ uint64_t index = 0;
+ uint16_t numerator = 0;
+
+ ConstTargetHandle_t proc = getParentChip(i_occ);
+ assert(proc != NULL);
+ assert(o_data != NULL);
+
+ o_data[index++] = OCC_CFGDATA_MEM_THROTTLE;
+ o_data[index++] = OCC_CFGDATA_MEM_THROTTLE_VERSION;
+ index++; //Will fill in numSets at the end
+
+
+ TargetHandleList centaurs;
+ TargetHandleList mbas;
+ TargetHandleList::const_iterator centaur;
+ TargetHandleList::const_iterator mba;
+
+ getChildAffinityTargets(centaurs, proc, CLASS_CHIP, TYPE_MEMBUF);
+
+ //Next, the following format repeats per set/MBA:
+ //Byte 0: Centaur position 0-7
+ //Byte 1: MBA Position 0-1
+ //Bytes 2-3: min OT N_PER_MBA
+ //bytes 4-5: redundant power N_PER_MBA
+ //bytes 6-7: redundant power N_PER_CHIP
+ //bytes 8-9: oversubscription N_PER_MBA
+ //bytes 10-11: oversubscription N_PER_CHIP
+
+
+ for (centaur=centaurs.begin(); centaur!=centaurs.end(); ++centaur)
+ {
+ centPos = (*centaur)->getAttr<ATTR_POSITION>();
+
+ mbas.clear();
+ getChildAffinityTargets(mbas, *centaur,
+ CLASS_UNIT, TYPE_MBA);
+
+ for (mba=mbas.begin(); mba!=mbas.end(); ++mba)
+ {
+ numSets++;
+ mbaPos = (*mba)->getAttr<ATTR_CHIP_UNIT>();
+
+ TRACUCOMP("centPos = %d, mbaPos = %d",
+ centPos, mbaPos);
+
+ o_data[index++] = centPos;
+ o_data[index++] = mbaPos;
+
+ numerator = (*mba)->getAttr<ATTR_OT_MIN_N_PER_MBA>();
+ memcpy(&o_data[index], &numerator, 2);
+ index += 2;
+
+ numerator = (*mba)->getAttr<ATTR_N_PLUS_ONE_N_PER_MBA>();
+ memcpy(&o_data[index], &numerator, 2);
+ index += 2;
+
+ numerator = (*mba)->getAttr<ATTR_N_PLUS_ONE_N_PER_CHIP>();
+ memcpy(&o_data[index], &numerator, 2);
+ index += 2;
+
+ numerator = (*mba)->getAttr<ATTR_OVERSUB_N_PER_MBA>();
+ memcpy(&o_data[index], &numerator, 2);
+ index += 2;
+
+ numerator = (*mba)->getAttr<ATTR_OVERSUB_N_PER_CHIP>();
+ memcpy(&o_data[index], &numerator, 2);
+ index += 2;
+ }
+
+ }
+
+
+ TMGT_INF("getMemThrottleMessageData: returning %d"
+ " sets of data for OCC 0x%X",
+ numSets, i_occ->getAttr<ATTR_HUID>());
+
+ o_data[2] = numSets;
+
+ o_size = index;
+
+}
+
+
+
+void getOCCRoleMessageData(bool i_master, bool i_firMaster,
+ uint8_t* o_data, uint64_t & o_size)
+{
+ assert(o_data != NULL);
+
+ o_data[0] = OCC_CFGDATA_OCC_ROLE;
+
+ o_data[1] = OCC_ROLE_SLAVE;
+
+ if (i_master)
+ {
+ o_data[1] = OCC_ROLE_MASTER;
+ }
+
+ if (i_firMaster)
+ {
+ o_data[1] |= OCC_ROLE_FIR_MASTER;
+ }
+
+ o_size = 2;
+}
+
+
+void getPowerCapMessageData(uint8_t* o_data, uint64_t & o_size)
+{
+ uint64_t index = 0;
+ uint16_t pcap = 0;
+ Target* sys = NULL;
+ targetService().getTopLevelTarget(sys);
+
+ assert(sys != NULL);
+ assert(o_data != NULL);
+
+ o_data[index++] = OCC_CFGDATA_PCAP_CONFIG;
+ o_data[index++] = OCC_CFGDATA_PCAP_CONFIG_VERSION;
+
+ //Minimum Power Cap
+ pcap = sys->getAttr<ATTR_OPEN_POWER_MIN_POWER_CAP_WATTS>();
+ memcpy(&o_data[index], &pcap, 2);
+ index += 2;
+
+ //System Maximum Power Cap
+ pcap = sys->getAttr<ATTR_OPEN_POWER_N_PLUS_ONE_BULK_POWER_LIMIT_WATTS>();
+ memcpy(&o_data[index], &pcap, 2);
+ index += 2;
+
+ //Oversubscription Power Cap
+ pcap = sys->getAttr<ATTR_OPEN_POWER_N_BULK_POWER_LIMIT_WATTS>();
+ memcpy(&o_data[index], &pcap, 2);
+ index += 2;
+
+ o_size = index;
+}
+
+
+void getSystemConfigMessageData(uint8_t* o_data, uint64_t & o_size)
+{
+ uint64_t index = 0;
+ uint16_t sensor = 0;
+ assert(o_data != NULL);
+
+ o_data[index++] = OCC_CFGDATA_SYS_CONFIG;
+ o_data[index++] = OCC_CFGDATA_SYS_CONFIG_VERSION;
+
+ //System Type
+ o_data[index++] = OCC_CFGDATA_OPENPOWER_SYSTEMTYPE;
+
+ //processor sensor ID
+ sensor = 0; //TODO all sensors - RTC 115294
+ memcpy(&o_data[index], &sensor, 2);
+ index += 2;
+
+ //Next 12*4 bytes are for core sensors
+ for (uint64_t core=0; core<CFGDATA_CORES; core++)
+ {
+ //Core Temp Sensor ID
+ sensor = 0;
+ memcpy(&o_data[index], &sensor, 2);
+ index += 2;
+
+ //Core Frequency Sensor ID
+ sensor = 0;
+ memcpy(&o_data[index], &sensor, 2);
+ index += 2;
+ }
+
+ //Backplane sensor ID
+ sensor = 0;
+ memcpy(&o_data[index], &sensor, 2);
+ index += 2;
+
+ //APSS sensor ID
+ sensor = 0;
+ memcpy(&o_data[index], &sensor, 2);
+ index += 2;
+
+ o_size = index;
+}
+
+
+void getThermalControlMessageData(uint8_t* o_data,
+ uint64_t & o_size)
+{
+ uint64_t index = 0;
+ Target* sys = NULL;
+ targetService().getTopLevelTarget(sys);
+
+ assert(sys != NULL);
+ assert(o_data != NULL);
+
+ o_data[index++] = OCC_CFGDATA_TCT_CONFIG;
+ o_data[index++] = OCC_CFGDATA_TCT_CONFIG_VERSION;
+
+ //3 data sets following (proc, Centaur, DIMM), and
+ //each will get a FRU type, DVS temp, error temp,
+ //and max read timeout
+ o_data[index++] = 3;
+
+ o_data[index++] = CFGDATA_FRU_TYPE_PROC;
+ o_data[index++] = sys->getAttr<ATTR_OPEN_POWER_PROC_DVFS_TEMP_DEG_C>();
+ o_data[index++] = sys->getAttr<ATTR_OPEN_POWER_PROC_ERROR_TEMP_DEG_C>();
+ o_data[index++] = sys->getAttr<ATTR_OPEN_POWER_PROC_READ_TIMEOUT_SEC>();
+
+ o_data[index++] = CFGDATA_FRU_TYPE_MEMBUF;
+ o_data[index++] = CFDATA_DVFS_NOT_DEFINED;
+ o_data[index++] = sys->getAttr<ATTR_OPEN_POWER_MEMCTRL_ERROR_TEMP_DEG_C>();
+ o_data[index++] = sys->getAttr<ATTR_OPEN_POWER_MEMCTRL_READ_TIMEOUT_SEC>();
+
+ o_data[index++] = CFGDATA_FRU_TYPE_DIMM;
+ o_data[index++] = CFDATA_DVFS_NOT_DEFINED;
+ o_data[index++] = sys->getAttr<ATTR_OPEN_POWER_DIMM_ERROR_TEMP_DEG_C>();
+ o_data[index++] = sys->getAttr<ATTR_OPEN_POWER_DIMM_READ_TIMEOUT_SEC>();
+
+ o_size = index;
+
+}
+
+
+void getFrequencyPointMessageData(uint8_t* o_data,
+ uint64_t & o_size)
+{
+ uint64_t index = 0;
+ uint16_t min = 0;
+ uint16_t max = 0;
+ uint16_t nominal = 0;
+ Target* sys = NULL;
+
+ targetService().getTopLevelTarget(sys);
+ assert(sys != NULL);
+ assert(o_data != NULL);
+
+ o_data[index++] = OCC_CFGDATA_FREQ_POINT;
+ o_data[index++] = OCC_CFGDATA_FREQ_POINT_VERSION;
+
+
+ //Nominal Frequency in MHz
+ nominal = sys->getAttr<ATTR_NOMINAL_FREQ_MHZ>();
+ memcpy(&o_data[index], &nominal, 2);
+ index += 2;
+
+
+ //Maximum Frequency in MHz
+ uint8_t turboAllowed =
+ sys->getAttr<ATTR_OPEN_POWER_TURBO_MODE_SUPPORTED>();
+
+ //If Turbo isn't allowed, then we send up the
+ //nominal frequency for this value.
+ if (turboAllowed)
+ {
+ max = sys->getAttr<ATTR_FREQ_CORE_MAX>();
+ }
+ else
+ {
+ max = nominal;
+ }
+
+ memcpy(&o_data[index], &max, 2);
+ index += 2;
+
+
+ //Minimum Frequency in MHz
+ min = sys->getAttr<ATTR_MIN_FREQ_MHZ>();
+ memcpy(&o_data[index], &min, 2);
+ index += 2;
+
+ TMGT_INF("Frequency Points: Nominal %d, Max %d, Min %d",
+ (uint32_t)nominal, (uint32_t)max, (uint32_t)min);
+
+ o_size = index;
+}
+
+
+void getPstateTableMessageData(const TargetHandle_t i_occTarget,
+ uint8_t* o_data,
+ uint64_t & io_size)
+{
+ uint64_t msg_size = sizeof(ATTR_PSTATE_TABLE_type) + 4;
+ assert(io_size >= msg_size);
+
+ if(io_size > msg_size)
+ {
+ io_size = msg_size;
+ }
+
+ o_data[0] = OCC_CFGDATA_PSTATE_SSTRUCT;
+ o_data[1] = 0; // reserved
+ o_data[2] = 0; // reserved
+ o_data[3] = 0; // reserved
+
+ // Read data from attribute for specified occ
+ ATTR_PSTATE_TABLE_type * pstateDataPtr =
+ reinterpret_cast<ATTR_PSTATE_TABLE_type*>(o_data + 4);
+
+ i_occTarget->tryGetAttr<ATTR_PSTATE_TABLE>(*pstateDataPtr);
+}
+
+
+
+void getApssMessageData(uint8_t* o_data,
+ uint64_t & o_size)
+{
+ Target* sys = NULL;
+ targetService().getTopLevelTarget(sys);
+
+ ATTR_ADC_CHANNEL_FUNC_IDS_type function;
+ sys->tryGetAttr<ATTR_ADC_CHANNEL_FUNC_IDS>(function);
+
+ ATTR_ADC_CHANNEL_GNDS_type ground;
+ sys->tryGetAttr<ATTR_ADC_CHANNEL_GNDS>(ground);
+
+ ATTR_ADC_CHANNEL_GAINS_type gain;
+ sys->tryGetAttr<ATTR_ADC_CHANNEL_GAINS>(gain);
+
+ ATTR_ADC_CHANNEL_OFFSETS_type offset;
+ sys->tryGetAttr<ATTR_ADC_CHANNEL_OFFSETS>(offset);
+
+ CPPASSERT(sizeof(function) == sizeof(ground));
+ CPPASSERT(sizeof(function) == sizeof(gain));
+ CPPASSERT(sizeof(function) == sizeof(offset));
+
+ o_data[0] = OCC_CFGDATA_APSS_CONFIG;
+ o_data[1] = OCC_CFGDATA_APSS_VERSION;
+ o_data[2] = 0;
+ o_data[3] = 0;
+ uint64_t idx = 4;
+
+ for(uint64_t channel = 0; channel < sizeof(function); ++channel)
+ {
+ o_data[idx] = function[channel]; // ADC Channel assignement
+ idx += sizeof(uint8_t);
+
+ uint16_t sensorId = 0;
+ memcpy(o_data+idx,&sensorId,sizeof(uint16_t)); // Sensor ID
+ idx += sizeof(uint16_t);
+
+ o_data[idx] = ground[channel]; // Ground Select
+ idx += sizeof(uint8_t);
+
+ memcpy(o_data+idx, &gain[channel], sizeof(uint32_t)); // Gain
+ idx += sizeof(uint32_t);
+
+ memcpy(o_data+idx, &offset[channel], sizeof(uint32_t)); // offset
+ idx += sizeof(uint32_t);
+ }
+
+ ATTR_APSS_GPIO_PORT_MODES_type gpioMode;
+ sys->tryGetAttr<ATTR_APSS_GPIO_PORT_MODES>(gpioMode);
+
+ ATTR_APSS_GPIO_PORT_PINS_type gpioPin;
+ sys->tryGetAttr<ATTR_APSS_GPIO_PORT_PINS>(gpioPin);
+
+ uint64_t pinsPerPort = sizeof(ATTR_APSS_GPIO_PORT_PINS_type) /
+ sizeof(ATTR_APSS_GPIO_PORT_MODES_type);
+ uint64_t pinIdx = 0;
+
+ for(uint64_t port = 0; port < sizeof(gpioMode); ++port)
+ {
+ o_data[idx] = gpioMode[port];
+ idx += sizeof(uint8_t);
+ o_data[idx] = 0;
+ idx += sizeof(uint8_t);
+ memcpy(o_data + idx, gpioPin+pinIdx, pinsPerPort);
+ idx += pinsPerPort;
+ pinIdx += pinsPerPort;
+ }
+
+ o_size = idx;
+}
+}
diff --git a/src/usr/htmgt/htmgt_cfgdata.H b/src/usr/htmgt/htmgt_cfgdata.H
new file mode 100644
index 000000000..5b6d30f5a
--- /dev/null
+++ b/src/usr/htmgt/htmgt_cfgdata.H
@@ -0,0 +1,174 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/htmgt/htmgt_cfgdata.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef HTMGT_CFGDATA_H
+#define HTMGT_CFGDATA_H
+
+#include <targeting/common/target.H>
+#include "htmgt_occ.H"
+
+
+namespace HTMGT
+{
+
+ /** OCC configuration data message formats */
+ enum occCfgDataFormat
+ {
+ OCC_CFGDATA_NO_REQUEST = 0x00, // no request for config data
+ OCC_CFGDATA_PSTATE_SSTRUCT = 0x01, // Psate Super Structure
+ OCC_CFGDATA_FREQ_POINT = 0x02, // Frequency Operating Points
+ OCC_CFGDATA_OCC_ROLE = 0x03, // OCC Role
+ OCC_CFGDATA_APSS_CONFIG = 0x04, // APSS Config
+ OCC_CFGDATA_MEM_CONFIG = 0x05, // Memory Configuration
+ OCC_CFGDATA_FIR_SCOMS = 0x06, // FIR Scoms Table
+ OCC_CFGDATA_PCAP_CONFIG = 0x07, // PCAP Config
+ OCC_CFGDATA_SYS_CONFIG = 0x0F, // System Configuration
+ OCC_CFGDATA_MEM_THROTTLE = 0x12, // Memory Throttle Settings
+ OCC_CFGDATA_TCT_CONFIG = 0x13, // Thermal Control Treshold
+
+ OCC_CFGDATA_FORMAT_END, // Marker to indicate last entry
+ OCC_CFGDATA_CLEAR_ALL = 0xFF, // Clear All Active Config Data
+ };
+
+
+ enum // constants
+ {
+ //KVM mode + single node
+ OCC_CFGDATA_OPENPOWER_SYSTEMTYPE = 0x81,
+
+ CFGDATA_CORES = 12,
+
+ CFGDATA_FRU_TYPE_PROC = 0x00,
+ CFGDATA_FRU_TYPE_MEMBUF = 0x01,
+ CFGDATA_FRU_TYPE_DIMM = 0x02,
+
+ CFDATA_DVFS_NOT_DEFINED = 0xFF,
+ };
+
+
+ /**
+ * Fills in the Memory Config Configuration Data message buffer,
+ * including the format and version numbers.
+ *
+ * @param[in] i_occ - the OCC to gather data for
+ * @param[in] i_monitoringEnabled - set it to true if mem monitoring on
+ * @param[out] o_data - preallocated buffer to fill in
+ * @param[out] o_size - set to the message size
+ * @pre o_data is large enough.
+ */
+ void getMemConfigMessageData(const TARGETING::TargetHandle_t i_occ,
+ bool i_monitoringEnabled,
+ uint8_t* o_data, uint64_t & o_size);
+
+
+ /**
+ * Fills in the Memory Throttle Configuration Data message buffer,
+ * including the format and version numbers.
+ *
+ * @param[in] i_occ - the OCC to gather data for
+ * @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,
+ uint8_t* o_data, uint64_t & o_size);
+
+
+ /**
+ * Fills in the OCC Role Configuration Data message buffer.
+ *
+ * @param[in] i_master - if this is for the OCC master
+ * @param[in] i_firMaster - if this is for the OCC FIR master
+ * @param[out] o_data - preallocated buffer to fill in
+ * @param[out] o_size - set to the message size
+ * @pre o_data is large enough.
+ */
+ void getOCCRoleMessageData(bool i_master, bool i_firMaster,
+ uint8_t* o_data, uint64_t & o_size);
+
+
+ /**
+ * Fills in the Power Cap Configuration Data message buffer.
+ *
+ * @param[out] o_data - preallocated buffer to fill in
+ * @param[out] o_size - set to the message size
+ * @pre o_data is large enough.
+ */
+ void getPowerCapMessageData(uint8_t* o_data, uint64_t & o_size);
+
+
+ /**
+ * Fills in the System Config Configuration Data message buffer.
+ *
+ * @param[out] o_data - preallocated buffer to fill in
+ * @param[out] o_size - set to the message size
+ * @pre o_data is large enough.
+ */
+ void getSystemConfigMessageData(uint8_t* o_data, uint64_t & o_size);
+
+
+ /**
+ * Fills in the Thermal Control Thresholds Configuration
+ * Data message buffer.
+ *
+ * @param[out] o_data - preallocated buffer to fill in
+ * @param[out] o_size - set to the message size
+ * @pre o_data is large enough.
+ */
+ void getThermalControlMessageData(uint8_t* o_data, uint64_t & o_size);
+
+
+ /**
+ * Fill in the Frequency Point Configuration Data
+ * message buffer.
+ *
+ * @param[out] o_data - preallocated buffer to fill in
+ * @param[out] o_size - set to the message size
+ * @pre o_data is large enough.
+ */
+ void getFrequencyPointMessageData(uint8_t* o_data,
+ uint64_t & o_size);
+
+ /**
+ * Read pstate data from attribute and build occcmd message
+ * @param[in] The OCC TARGETING::Target
+ * @param[out] The occ cmd message
+ * @param[in/out] In: Byte size of the o_data area. Out: Byte size of
+ * the occ cmd message.
+ */
+ void getPstateTableMessageData(const TARGETING::TargetHandle_t i_occTarget,
+ uint8_t* o_data,
+ uint64_t & io_size);
+
+ /**
+ * Generate the APSS configuration message
+ * @param[out] The APSS cfg message
+ * @param[in/out] In: Byte size of the o_data area. Out: Byte size of
+ * the occ cmd message
+ */
+ void getApssMessageData(uint8_t* o_data,
+ uint64_t & o_size);
+
+};
+#endif
diff --git a/src/usr/htmgt/htmgt_common.mk b/src/usr/htmgt/htmgt_common.mk
index 589cedd1b..38ad4db39 100644
--- a/src/usr/htmgt/htmgt_common.mk
+++ b/src/usr/htmgt/htmgt_common.mk
@@ -29,6 +29,7 @@ OBJS += htmgt_activate.o
OBJS += htmgt_occcmd.o
OBJS += htmgt_poll.o
OBJS += htmgt_utility.o
+OBJS += htmgt_cfgdata.o
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer
EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi
diff --git a/src/usr/htmgt/htmgt_memthrottles.C b/src/usr/htmgt/htmgt_memthrottles.C
new file mode 100644
index 000000000..3684c71d7
--- /dev/null
+++ b/src/usr/htmgt/htmgt_memthrottles.C
@@ -0,0 +1,509 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/htmgt/htmgt_memthrottles.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#include "htmgt_memthrottles.H"
+#include "htmgt_utility.H"
+#include <htmgt/htmgt_reasoncodes.H>
+#include <errl/errlmanager.H>
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/utilFilter.H>
+#include <targeting/common/attributes.H>
+#include <targeting/common/targetservice.H>
+#include <fapi.H>
+#include <fapiPlatHwpInvoker.H>
+#include <mss_bulk_pwr_throttles.H>
+#include <mss_util_to_throttle.H>
+
+
+using namespace TARGETING;
+
+
+
+//for unit testing
+//#define TRACUCOMP(args...) TMGT_INF(args)
+#define TRACUCOMP(args...)
+
+namespace HTMGT
+{
+
+/**
+ * Helper function to run the hardware procedure to calculate the
+ * throttle attributes for the Over Temp condition.
+ * flow = htmgtCalcMemThrottle_OT
+ *
+ * @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
+ */
+void memPowerThrottleOT(TargetHandleList & i_mbas,
+ const uint32_t i_nSafeModeMBA,
+ const uint8_t i_utilization)
+{
+ TargetHandleList::iterator mba;
+ bool useSafeMode = false;
+ bool throttleError = false;
+ uint32_t nUtilBased = 0;
+ uint32_t mbaHuid = 0;
+ Target* sys = NULL;
+
+ TMGT_INF(ENTER_MRK" memPowerThrottleOT");
+
+ targetService().getTopLevelTarget(sys);
+ assert(sys != NULL);
+
+ for (mba=i_mbas.begin(); mba!=i_mbas.end(); ++mba)
+ {
+ mbaHuid = (*mba)->getAttr<ATTR_HUID>();
+ useSafeMode = true;
+ nUtilBased = 0;
+
+ 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 fapi::Target fapiTarget(fapi::TARGET_TYPE_MBA_CHIPLET,
+ const_cast<Target*>(*mba));
+
+ //Set this so the procedure can use it
+ (*mba)->setAttr<ATTR_MSS_DATABUS_UTIL_PER_MBA>(i_utilization);
+
+ 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<ATTR_MSS_UTIL_N_PER_MBA>();
+
+ 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);
+ }
+ }
+ }
+ }
+
+
+ if (useSafeMode)
+ {
+ nUtilBased = i_nSafeModeMBA;
+
+ TMGT_INF("memPowerThrottleOT: MBA 0x%X must use safemode"
+ " numerator", mbaHuid);
+ }
+
+ TMGT_INF("memPowerThrottleOT: MBA 0x%X: N Util OT = 0x%X",
+ mbaHuid, nUtilBased);
+
+ (*mba)->setAttr<ATTR_OT_MIN_N_PER_MBA>(nUtilBased);
+ }
+
+
+}
+
+
+
+
+
+/**
+ * Helper function to run the mss_bulk_pwr_throttles and
+ * mss_util_to_throttle 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_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(TargetHandle_t i_mba,
+ const uint32_t i_wattTarget,
+ const uint8_t i_utilization,
+ bool & o_useSafeMode,
+ uint32_t & o_nMBA,
+ uint32_t & o_nChip)
+{
+ errlHndl_t err = NULL;
+
+ o_useSafeMode = false;
+ o_nMBA = 0;
+ o_nChip = 0;
+
+ //Set the values the procedures need
+ i_mba->setAttr<ATTR_MSS_MEM_WATT_TARGET>(i_wattTarget);
+ i_mba->setAttr<ATTR_MSS_DATABUS_UTIL_PER_MBA>(i_utilization);
+
+ const fapi::Target fapiTarget(fapi::TARGET_TYPE_MBA_CHIPLET,
+ i_mba);
+
+ 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<ATTR_HUID>());
+ }
+ else
+ {
+ //Get the procedure outputs
+ o_nMBA = i_mba->getAttr<ATTR_MSS_MEM_THROTTLE_NUMERATOR_PER_MBA>();
+ o_nChip = i_mba->getAttr<ATTR_MSS_MEM_THROTTLE_NUMERATOR_PER_CHIP>();
+
+ //Make sure neither are 0
+ if ((0 == o_nMBA) || (0 == o_nChip))
+ {
+ 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<ATTR_HUID>());
+
+ /*@
+ * @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<ATTR_HUID>(),
+ data, true);
+ }
+ else if (i_utilization != 0)
+ {
+ //Make sure the calculated throttles meet the min
+ //utilization, if provided.
+
+ 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<ATTR_HUID>());
+ }
+ else
+ {
+ //Get the value the procedure wrote
+ uint32_t nUtilMBA = i_mba->getAttr<ATTR_MSS_UTIL_N_PER_MBA>();
+
+ 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<ATTR_HUID>());
+
+ /*@
+ * @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<ATTR_HUID>(),
+ data, true);
+ }
+ }
+ }
+ }
+
+ if (err)
+ {
+ err->collectTrace(HTMGT_COMP_NAME);
+ errlCommit(err, HTMGT_COMP_ID);
+ o_useSafeMode = true;
+ }
+
+}
+
+
+/**
+ * Helper function to run the hardware procedures to calculate the
+ * throttle attributes used for redundant power.
+ * flow = htmgtCalcMemThrottle_redundantPwr
+ *
+ * @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_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,
+ const uint8_t i_utilization,
+ const uint8_t i_efficiency)
+{
+ Target* sys = NULL;
+ TargetHandleList::iterator mba;
+ uint16_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
+ power = sys->getAttr<ATTR_OPEN_POWER_N_PLUS_ONE_MAX_MEM_POWER_WATTS>();
+ power *= 100; //centiWatts
+
+ //Account for the regulator efficiency, if supplied
+ if (i_efficiency != 0)
+ {
+ power *= i_efficiency;
+ }
+
+ //Find the Watt target for each MBA
+ if (i_mbas.size())
+ {
+ wattTarget = power / i_mbas.size();
+ }
+
+ TMGT_INF("memPowerThrottleRedPower: power = %d, wattTarget = %d",
+ power, wattTarget);
+
+ for (mba=i_mbas.begin(); mba!=i_mbas.end(); ++mba)
+ {
+ useSafeMode = false;
+ nMBA = nChip = 0;
+
+ //Run the calculations
+ doMBAThrottleCalc(*mba, wattTarget, i_utilization,
+ useSafeMode, nMBA, nChip);
+
+ if (useSafeMode)
+ {
+ nMBA = i_nSafeModeMBA;
+ nChip = i_nSafeModeChip;
+ TMGT_INF("memPowerThrottleRedPower: MBA 0x%X using safemode "
+ "numerator",
+ (*mba)->getAttr<ATTR_HUID>());
+ }
+
+ //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<ATTR_HUID>(), nMBA, nChip);
+
+ (*mba)->setAttr<ATTR_N_PLUS_ONE_N_PER_MBA>(nMBA);
+ (*mba)->setAttr<ATTR_N_PLUS_ONE_N_PER_CHIP>(nChip);
+
+ }
+
+
+}
+
+
+
+/**
+ * Helper function to run the hardware procedures to calculate the
+ * throttle attributes used for oversubscription.
+ * flow = htmgtCalcMemThrottle_oversub
+ *
+ * @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_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)
+{
+ Target* sys = NULL;
+ TargetHandleList::iterator mba;
+ uint16_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 power allocated to memory
+ power = sys->getAttr<ATTR_OPEN_POWER_N_MAX_MEM_POWER_WATTS>();
+ power *= 100; //centiWatts
+
+ //Account for the regulator efficiency, if supplied
+ if (i_efficiency != 0)
+ {
+ power *= i_efficiency;
+ }
+
+ //Find the Watt target for each MBA
+ if (i_mbas.size())
+ {
+ wattTarget = power / i_mbas.size();
+ }
+
+ TMGT_INF("memPowerThrottleOverSub: power = %d, wattTarget = %d",
+ power, wattTarget);
+
+ for (mba=i_mbas.begin(); mba!=i_mbas.end(); ++mba)
+ {
+ useSafeMode = false;
+ nMBA = nChip = 0;
+
+ //Run the calculations
+ doMBAThrottleCalc(*mba, wattTarget, i_utilization,
+ useSafeMode, nMBA, nChip);
+
+ if (useSafeMode)
+ {
+ nMBA = i_nSafeModeMBA;
+ nChip = i_nSafeModeChip;
+ TMGT_INF("memPowerThrottleOverSub: MBA 0x%X using safemode "
+ "numerator",
+ (*mba)->getAttr<ATTR_HUID>());
+ }
+
+ //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<ATTR_HUID>(), nMBA, nChip);
+
+ (*mba)->setAttr<ATTR_OVERSUB_N_PER_MBA>(nMBA);
+ (*mba)->setAttr<ATTR_OVERSUB_N_PER_CHIP>(nChip);
+
+ }
+
+}
+
+
+
+void calcMemThrottles()
+{
+ Target* sys = NULL;
+ TargetHandleList mbas;
+
+ targetService().getTopLevelTarget(sys);
+ assert(sys != NULL);
+
+ uint32_t nSafeModeMBA =
+ sys->getAttr<ATTR_MRW_SAFEMODE_MEM_THROTTLE_NUMERATOR_PER_MBA>();
+
+ uint32_t nSafeModeChip =
+ sys->getAttr<ATTR_MRW_SAFEMODE_MEM_THROTTLE_NUMERATOR_PER_CHIP>();
+
+ uint8_t utilization =
+ sys->getAttr<ATTR_OPEN_POWER_MIN_MEM_UTILIZATION_THROTTLING>();
+
+ uint8_t efficiency =
+ sys->getAttr<ATTR_OPEN_POWER_REGULATOR_EFFICIENCY_FACTOR>();
+
+ TMGT_INF("calcMemThrottles: Using nSafeModeMBA=0x%X, nSafeModeChip=0x%X",
+ nSafeModeMBA, nSafeModeChip);
+
+ TMGT_INF("calcMemThrottles: Using utilization=0x%X, efficiency=0x%X",
+ utilization, efficiency);
+
+
+ //Get all functional MBAs
+ getAllChiplets(mbas, TYPE_MBA, true);
+
+ //Calculate Throttle settings for Over Temperature
+ memPowerThrottleOT(mbas, nSafeModeMBA, utilization);
+
+ //Calculate Throttle settings for Redundant Power
+ memPowerThrottleRedPower(mbas, nSafeModeMBA, nSafeModeChip,
+ utilization, efficiency);
+
+ //Calculate Throttle settings for Oversubscription
+ memPowerThrottleOverSub(mbas, nSafeModeMBA, nSafeModeChip,
+ utilization, efficiency);
+
+}
+} // End namespace
diff --git a/src/usr/htmgt/htmgt_config.H b/src/usr/htmgt/htmgt_memthrottles.H
index e87c5f381..7816da98f 100644
--- a/src/usr/htmgt/htmgt_config.H
+++ b/src/usr/htmgt/htmgt_memthrottles.H
@@ -1,7 +1,7 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
-/* $Source: src/usr/htmgt/tmgtutility.H $ */
+/* $Source: src/usr/htmgt/htmgt_memthrottles.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
@@ -22,49 +22,21 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
-#ifndef HTMGT_CONFIG_H
-#define HTMGT_CONFIG_H
+#ifndef HTMGT_MEMTHROTTLES_H
+#define HTMGT_MEMTHROTTLES_H
-#include <stdint.h>
namespace HTMGT
{
- extern const uint8_t NUM_CFG_FORMATS;
+ /**
+ * 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();
- enum occCfgDataFormat
- {
- OCC_CFGDATA_NO_REQUEST = 0x00, // no request for config data
- OCC_CFGDATA_PSTATE_SSTRUCT = 0x01, // Psate Super Structure
- OCC_CFGDATA_FREQ_POINT = 0x02, // Frequency Operating Points
- OCC_CFGDATA_OCC_ROLE = 0x03, // OCC Role
- OCC_CFGDATA_APSS_CONFIG = 0x04, // APSS Config
- OCC_CFGDATA_MEM_CONFIG = 0x05, // Memory Configuration
- OCC_CFGDATA_FIR_SCOMS = 0x06, // FIR Scoms Table
- OCC_CFGDATA_PCAP_CONFIG = 0x07, // PCAP Config
- OCC_CFGDATA_SYS_CONFIG = 0x0F, // System Configuration
- OCC_CFGDATA_MEM_THROTTLE = 0x12, // Memory Throttle Settings
- OCC_CFGDATA_TCT_CONFIG = 0x13, // Thermal Contorl Treshold
- OCC_CFGDATA_FORMAT_END, // Marker to indicate last entry
- OCC_CFGDATA_CLEAR_ALL = 0xFF, // Clear All Active Config Data
- };
-
-
- enum occDataState
- {
- OCC_DATA_NOT_AVAILABLE = 0x00,
- OCC_DATA_AVAILABLE = 0x01,
- OCC_DATA_NEEDS_TO_BE_SENT = 0x02,
- };
-
-
-
- // Send all config data to the OCCs
- void sendOccConfigData();
-
-
-
-} // end namespace
+};
#endif
diff --git a/src/usr/htmgt/htmgt_occ.C b/src/usr/htmgt/htmgt_occ.C
index 2d0aaca11..7722563ea 100644
--- a/src/usr/htmgt/htmgt_occ.C
+++ b/src/usr/htmgt/htmgt_occ.C
@@ -27,7 +27,7 @@
#include <htmgt/htmgt_reasoncodes.H>
#include "htmgt_utility.H"
#include "htmgt_occcmd.H"
-#include "htmgt_config.H"
+#include "htmgt_cfgdata.H"
#include "htmgt_occ.H"
// Targeting support
diff --git a/src/usr/htmgt/htmgt_occ.H b/src/usr/htmgt/htmgt_occ.H
index 64daf73c9..9ac7b350e 100644
--- a/src/usr/htmgt/htmgt_occ.H
+++ b/src/usr/htmgt/htmgt_occ.H
@@ -53,10 +53,10 @@ namespace HTMGT
enum occRole
{
- OCC_ROLE_SLAVE = 0,
- OCC_ROLE_MASTER = 1,
- OCC_ROLE_BACKUP_MASTER = 2,
- OCC_ROLE_FIR_MASTER = 3
+ OCC_ROLE_SLAVE = 0x00,
+ OCC_ROLE_MASTER = 0x01,
+ OCC_ROLE_BACKUP_MASTER = 0x02,
+ OCC_ROLE_FIR_MASTER = 0x80
};
diff --git a/src/usr/htmgt/htmgt_occcmd.C b/src/usr/htmgt/htmgt_occcmd.C
index 7a238b5d5..97ae2564e 100644
--- a/src/usr/htmgt/htmgt_occcmd.C
+++ b/src/usr/htmgt/htmgt_occcmd.C
@@ -26,7 +26,7 @@
#include <htmgt/htmgt.H>
#include <htmgt/htmgt_reasoncodes.H>
#include "htmgt_occcmd.H"
-#include "htmgt_config.H"
+#include "htmgt_cfgdata.H"
#include "htmgt_poll.H"
// Targeting support
diff --git a/src/usr/htmgt/htmgt_poll.C b/src/usr/htmgt/htmgt_poll.C
index 402c7ce74..bd9780a95 100644
--- a/src/usr/htmgt/htmgt_poll.C
+++ b/src/usr/htmgt/htmgt_poll.C
@@ -29,7 +29,7 @@
#include "htmgt_activate.H"
#include "htmgt_poll.H"
#include "htmgt_occcmd.H"
-#include "htmgt_config.H"
+#include "htmgt_cfgdata.H"
// Targeting support
#include <targeting/common/commontargeting.H>
diff --git a/src/usr/htmgt/htmgt_utility.C b/src/usr/htmgt/htmgt_utility.C
index 733887de3..ef086c592 100644
--- a/src/usr/htmgt/htmgt_utility.C
+++ b/src/usr/htmgt/htmgt_utility.C
@@ -23,7 +23,10 @@
/* */
/* IBM_PROLOG_END_TAG */
#include "htmgt_utility.H"
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/attributes.H>
+using namespace TARGETING;
namespace HTMGT
{
@@ -117,4 +120,28 @@ namespace HTMGT
+ uint8_t getOCCDIMMPos(const TargetHandle_t i_mba,
+ const TargetHandle_t i_dimm)
+ {
+ //To make the OCC DIMM # 0 - 7: 0bABC
+ // A: MBA ATTR_CHIP_UNIT: 0 or 1
+ // B: DIMM ATTR_MBA_PORT: 0 or 1
+ // C: DIMM ATTR_MBA_DIMM: 0 or 1
+
+ //Note: No CDIMM systems in plan. May need to revisit
+ //this if there are any as OCC may not care about logical DIMMs.
+
+ const uint8_t mbaUnit = i_mba->getAttr<ATTR_CHIP_UNIT>();
+ const uint8_t mbaPort = i_dimm->getAttr<ATTR_MBA_PORT>();
+ const uint8_t mbaDIMM = i_dimm->getAttr<ATTR_MBA_DIMM>();
+
+ TMGT_DBG("DIMM 0x%X unit %d port %d pos %d = %d",
+ i_dimm->getAttr<ATTR_HUID>(),
+ mbaUnit, mbaPort, mbaDIMM,
+ ((mbaUnit << 2) | (mbaPort << 1) | mbaDIMM));
+
+ return ((mbaUnit << 2) | (mbaPort << 1) | mbaDIMM);
+ }
+
+
} // end namespace
diff --git a/src/usr/htmgt/htmgt_utility.H b/src/usr/htmgt/htmgt_utility.H
index cbc5b1fb9..025ab49e7 100644
--- a/src/usr/htmgt/htmgt_utility.H
+++ b/src/usr/htmgt/htmgt_utility.H
@@ -149,5 +149,17 @@ namespace HTMGT
const char *command_string(const uint8_t i_cmd);
+ /**
+ * Helper function to return the DIMM number as the OCC sees it.
+ * There can be 8 DIMMs per Centaur.
+ *
+ * @param i_mba - the MBA the DIMM is on
+ * @param i_dimm - the DIMM
+ * @return - a number 0-7
+ */
+ uint8_t getOCCDIMMPos(const TARGETING::TargetHandle_t i_mba,
+ const TARGETING::TargetHandle_t i_dimm);
+
+
} // end namespace
#endif
diff --git a/src/usr/htmgt/makefile b/src/usr/htmgt/makefile
index c04d7e4b0..f49953fcb 100644
--- a/src/usr/htmgt/makefile
+++ b/src/usr/htmgt/makefile
@@ -25,11 +25,18 @@
ROOTPATH = ../../..
MODULE = htmgt
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp
+EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/include
+EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_eff_config
+
# objects common to hostboot and hbrt
include htmgt_common.mk
# objects unique to hostboot (none yet)
-#OBJS +=
+OBJS += htmgt_memthrottles.o
SUBDIRS += test.d
SUBDIRS += runtime.d
diff --git a/src/usr/htmgt/test/htmgtcfgtest.H b/src/usr/htmgt/test/htmgtcfgtest.H
new file mode 100644
index 000000000..c23cd2ff3
--- /dev/null
+++ b/src/usr/htmgt/test/htmgtcfgtest.H
@@ -0,0 +1,492 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/htmgt/test/htmgtcfgtest.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+#ifndef __HTMGTMEMTEST_H
+#define __HTMGTMEMTEST_H
+
+#include <vfs/vfs.H>
+#include <cxxtest/TestSuite.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <targeting/common/targetservice.H>
+#include <targeting/common/attributes.H>
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/utilFilter.H>
+#include <targeting/common/util.H>
+#include "../htmgt_memthrottles.H"
+#include "../htmgt_cfgdata.H"
+#include "../htmgt_utility.H"
+
+using namespace TARGETING;
+using namespace HTMGT;
+
+
+class htmgtMemTest : public CxxTest::TestSuite
+{
+
+private:
+ bool iv_mcConfigLoaded;
+ bool iv_htmgtLoaded;
+
+public:
+
+ htmgtMemTest()
+ {
+ if (!VFS::module_is_loaded("libmc_config.so"))
+ {
+ errlHndl_t err = VFS::module_load("libmc_config.so");
+ if (err)
+ {
+ TS_FAIL("Could not load mc_config module");
+ errlCommit(err, HTMGT_COMP_ID);
+ }
+
+ iv_mcConfigLoaded = true;
+ }
+ else
+ {
+ iv_mcConfigLoaded = false;
+ }
+
+ if (!VFS::module_is_loaded("libhtmgt.so"))
+ {
+ errlHndl_t err = VFS::module_load("libhtmgt.so");
+ if (err)
+ {
+ TS_FAIL("Could not load libhtmgt module");
+ errlCommit(err, HTMGT_COMP_ID);
+ }
+
+ iv_htmgtLoaded = true;
+ }
+ else
+ {
+ iv_htmgtLoaded = false;
+ }
+ }
+
+
+ ~htmgtMemTest()
+ {
+ if (iv_mcConfigLoaded)
+ {
+ errlHndl_t err = VFS::module_unload("libmc_config.so");
+ if (err)
+ {
+ TS_FAIL("Could not unload mc_config module");
+ errlCommit(err, HTMGT_COMP_ID);
+ }
+ }
+
+ if (iv_htmgtLoaded)
+ {
+ errlHndl_t err = VFS::module_unload("libhtmgt.so");
+ if (err)
+ {
+ TS_FAIL("Could not unload libhtmgt module");
+ errlCommit(err, HTMGT_COMP_ID);
+ }
+ }
+
+ }
+
+
+ void testThrottles()
+ {
+ TS_TRACE(ENTER_MRK"HTMGT: testThrottles");
+
+ calcMemThrottles();
+
+
+ TargetHandleList mbas;
+ TargetHandleList::iterator mba;
+
+ getAllChiplets(mbas, TYPE_MBA, true);
+
+ //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>())
+ {
+ TS_FAIL("MBA 0x%X has value of zero for OT_MIN_N_PER_MBA",
+ (*mba)->getAttr<ATTR_HUID>());
+ }
+
+ if (0 == (*mba)->getAttr<ATTR_N_PLUS_ONE_N_PER_MBA>())
+ {
+ TS_FAIL("MBA 0x%X has value of zero for N_PLUS_ONE_N_PER_MBA",
+ (*mba)->getAttr<ATTR_HUID>());
+ }
+
+ if (0 == (*mba)->getAttr<ATTR_N_PLUS_ONE_N_PER_CHIP>())
+ {
+ TS_FAIL("MBA 0x%X has value of zero for N_PLUS_ONE_N_PER_CHIP",
+ (*mba)->getAttr<ATTR_HUID>());
+ }
+
+ if (0 == (*mba)->getAttr<ATTR_OVERSUB_N_PER_MBA>())
+ {
+ TS_FAIL("MBA 0x%X has value of zero for OVERSUB_N_PER_MBA",
+ (*mba)->getAttr<ATTR_HUID>());
+ }
+
+ if (0 == (*mba)->getAttr<ATTR_OVERSUB_N_PER_CHIP>())
+ {
+ TS_FAIL("MBA 0x%X has value of zero for OVERSUB_N_PER_CHIP",
+ (*mba)->getAttr<ATTR_HUID>());
+ }
+ }
+
+ }
+
+
+ void testThrottleConfigData()
+ {
+ TargetHandleList occs;
+ TargetHandleList::iterator occ;
+ uint8_t numSets = 0;
+ uint8_t data[4*KILOBYTE];
+ uint64_t size = 0;
+ uint64_t expectedSize = 0;
+ const size_t THROTTLE_DATA_SET_SIZE = 12;
+
+ TS_TRACE(ENTER_MRK"HTMGT: testThrottleConfigData");
+
+ getAllChiplets(occs, TYPE_OCC, true);
+
+ for (occ=occs.begin();occ!=occs.end();++occ)
+ {
+ memset(data, 0, 4*KILOBYTE);
+
+ getMemThrottleMessageData(*occ, data, size);
+
+ if (data[0] != OCC_CFGDATA_MEM_THROTTLE)
+ {
+ TS_FAIL("Wrong format 0x%X for throttle config data command",
+ data[0]);
+ }
+
+ //Note: Yes, the version number is hardcoded, but if the version
+ //changes then these testcases would have to change anyway.
+ if (data[1] != 0x10)
+ {
+ TS_FAIL("Wrong version 0x%X for throttle config data command",
+ data[1]);
+ }
+
+ numSets = data[2];
+
+ TS_TRACE("HTMGT: testThrottleConfigData: OCC 0x%X returned message"
+ " size %d num sets %d",
+ (*occ)->getAttr<ATTR_HUID>(), size, numSets);
+
+ //3B header + 12B / set
+ expectedSize = 3 + (THROTTLE_DATA_SET_SIZE * numSets);
+ if (size != expectedSize)
+ {
+ TS_FAIL("Throttle data size %d did not match expected size %d"
+ " for OCC 0x%X",
+ size, expectedSize, (*occ)->getAttr<ATTR_HUID>());
+ }
+ }
+
+ }
+
+
+ void testMemConfigData()
+ {
+ TargetHandleList occs;
+ TargetHandleList::iterator occ;
+ uint8_t numSets = 0;
+ uint8_t data[4*KILOBYTE];
+ uint64_t size = 0;
+ uint64_t expectedSize = 0;
+ const size_t MEMCONFIG_DATA_SET_SIZE = 12;
+
+ TS_TRACE(ENTER_MRK"HTMGT: testMemConfigData");
+
+ getAllChiplets(occs, TYPE_OCC, true);
+
+ for (occ=occs.begin();occ!=occs.end();++occ)
+ {
+ memset(data, 0, 4*KILOBYTE);
+
+ getMemConfigMessageData(*occ, true, data, size);
+
+ if (data[0] != OCC_CFGDATA_MEM_CONFIG)
+ {
+ TS_FAIL("Wrong format 0x%X for mem config data command",
+ data[0]);
+ }
+
+ if (data[1] != 0x10)
+ {
+ TS_FAIL("Wrong version 0x%X for mem config data command",
+ data[1]);
+ }
+
+ numSets = data[2];
+
+ TS_TRACE("HTMGT: testMemConfigData: OCC 0x%X returned message "
+ "size %d num sets %d",
+ (*occ)->getAttr<ATTR_HUID>(), size, numSets);
+
+ expectedSize = 3 + (MEMCONFIG_DATA_SET_SIZE * numSets);
+ if (size != expectedSize)
+ {
+ TS_FAIL("MemConfig data size %d did notmatch expected "
+ "size %d for OCC 0x%X",
+ size, expectedSize, (*occ)->getAttr<ATTR_HUID>());
+ }
+ }
+
+ }
+
+ void testOCCRoleConfigData()
+ {
+ uint8_t data[4*KILOBYTE];
+ uint64_t size = 0;
+
+ TS_TRACE(ENTER_MRK"HTMGT: testOCCRoleConfigData");
+
+ getOCCRoleMessageData(true, true, data, size);
+
+ if (data[0] != OCC_CFGDATA_OCC_ROLE)
+ {
+ TS_FAIL("Wrong format 0x%X for occ role config data command",
+ data[0]);
+ }
+
+ if (data[1] != (OCC_ROLE_MASTER | OCC_ROLE_FIR_MASTER))
+ {
+ TS_FAIL("Wrong OCC role data 0x%X for occ"
+ " role config data command",
+ data[1]);
+ }
+
+ if (size != 2)
+ {
+ TS_FAIL("Wrong message length %d for occ role config data command",
+ size);
+ }
+
+
+ //Now do fir master = false
+ getOCCRoleMessageData(true, false, data, size);
+
+ if (data[1] != OCC_ROLE_MASTER)
+ {
+ TS_FAIL("Wrong OCC role data 0x%X for occ"
+ " role config data command",
+ data[1]);
+ }
+
+ //now master role = false
+ getOCCRoleMessageData(false, true, data, size);
+
+ if (data[1] != OCC_ROLE_FIR_MASTER)
+ {
+ TS_FAIL("Wrong OCC role data 0x%X for occ role config data command",
+ data[1]);
+ }
+
+ }
+
+
+
+ void testPowerCapConfigData()
+ {
+ uint8_t data[4*KILOBYTE];
+ uint64_t size = 0;
+
+ TS_TRACE(ENTER_MRK"HTMGT: testPowerCapConfigData");
+
+ getPowerCapMessageData(data, size);
+
+ if (data[0] != OCC_CFGDATA_PCAP_CONFIG)
+ {
+ TS_FAIL("Wrong format 0x%X for power cap config data command",
+ data[0]);
+ }
+
+ if (data[1] != 0x10)
+ {
+ TS_FAIL("Wrong version 0x%X for power cap config data command",
+ data[1]);
+ }
+
+ if (size != 8)
+ {
+ TS_FAIL("Wrong size %d for power cap config data command",
+ size);
+ }
+
+ }
+
+
+ void testSystemConfigData()
+ {
+ uint8_t data[4*KILOBYTE];
+ uint64_t size = 0;
+
+ TS_TRACE(ENTER_MRK"HTMGT: testSystemConfigData");
+
+ getSystemConfigMessageData(data, size);
+
+ if (data[0] != OCC_CFGDATA_SYS_CONFIG)
+ {
+ TS_FAIL("Wrong format 0x%X for system config data command",
+ data[0]);
+ }
+
+ if (data[1] != 0x10)
+ {
+ TS_FAIL("Wrong version 0x%X for system config data command",
+ data[1]);
+ }
+
+
+ if (data[2] != OCC_CFGDATA_OPENPOWER_SYSTEMTYPE)
+ {
+ TS_FAIL("wrong system type 0x%X for system config data command",
+ data[2]);
+ }
+
+ if (size != 57)
+ {
+ TS_FAIL("wrong size %d for system config data command",
+ size);
+ }
+
+ }
+
+
+ void testThermalControlConfigData()
+ {
+ uint8_t data[4*KILOBYTE];
+ uint64_t size = 0;
+
+ TS_TRACE(ENTER_MRK"HTMGT: testThermalControlConfigData");
+
+ getThermalControlMessageData(data, size);
+
+
+ if (data[0] != OCC_CFGDATA_TCT_CONFIG)
+ {
+ TS_FAIL("Wrong format 0x%X for thermal config data command",
+ data[0]);
+ }
+
+ if (data[1] != 0x10)
+ {
+ TS_FAIL("Wrong version 0x%X for thermal config data command",
+ data[1]);
+ }
+
+ if (size != 15)
+ {
+ TS_FAIL("wrong size %d for thermal control config data command",
+ size);
+ }
+
+ }
+
+
+ void testFreqPointConfigData()
+ {
+ uint8_t data[4*KILOBYTE];
+ uint64_t size = 0;
+
+ TS_TRACE(ENTER_MRK"HTMGT: testThermalControlConfigData");
+ memset(data, 0, 4*KILOBYTE);
+
+ getFrequencyPointMessageData(data, size);
+
+ if (data[0] != OCC_CFGDATA_FREQ_POINT)
+ {
+ TS_FAIL("Wrong format 0x%X for frequency point data command",
+ data[0]);
+ }
+
+ if (data[1] != 0x10)
+ {
+ TS_FAIL("Wrong version 0x%X for frequency point data command",
+ data[1]);
+ }
+
+ if (size != 8)
+ {
+ TS_FAIL("wrong size %d for frequency point config data command",
+ size);
+ }
+
+ }
+
+ void testReadPstateTable( void )
+ {
+ TS_TRACE(ENTER_MRK"HTMGT::testReadPstateTable");
+
+ TargetHandleList occs;
+ TargetHandleList::iterator occ;
+ size_t size = sizeof(ATTR_PSTATE_TABLE_type) + 4;
+ uint8_t data[size];
+
+ getAllChiplets(occs, TYPE_OCC, true);
+
+ for(occ=occs.begin(); occ !=occs.end(); ++occ)
+ {
+ size = sizeof(ATTR_PSTATE_TABLE_type) + 4;
+ memset(data, 0, size);
+ getPstateTableMessageData(*occ, data, size);
+
+ if(size != sizeof(ATTR_PSTATE_TABLE_type) + 4)
+ {
+ TS_FAIL("Wrong pstate table size. %d",
+ size);
+ }
+ }
+ }
+
+ void testApssConfigData()
+ {
+ uint64_t size = 256;
+ uint8_t data[size];
+
+ TMGT_INF(ENTER_MRK"HTMGT::testApccConfigData");
+ memset(data,0,size);
+ size = 0;
+
+ getApssMessageData(data, size);
+
+ TMGT_INF("APSS message size = %d bytes", size);
+
+ if(size != 216 || data[0] != HTMGT::OCC_CFGDATA_APSS_CONFIG)
+ {
+ TS_FAIL("Invalid APSS config size (%d) or format.",size);
+ }
+ }
+};
+
+
+#endif
diff --git a/src/usr/htmgt/test/pstatetest.H b/src/usr/htmgt/test/pstatetest.H
index e5d274695..7e6d8a595 100644
--- a/src/usr/htmgt/test/pstatetest.H
+++ b/src/usr/htmgt/test/pstatetest.H
@@ -44,6 +44,7 @@
#include <mss_bulk_pwr_throttles.H>
#include <mss_util_to_throttle.H>
#include <mss_throttle_to_power.H>
+#include <mss_eff_config_thermal.H>
using namespace TARGETING;
@@ -147,6 +148,17 @@ class pstateTest: public CxxTest::TestSuite
(fapi::TARGET_TYPE_MBA_CHIPLET,
(const_cast<TARGETING::Target*>(l_mba_target)));
+ // mss_eff_config_thermal sets up the attributes needed by
+ // the hw procedures that follow it.
+ FAPI_INVOKE_HWP( l_errl,
+ mss_eff_config_thermal,
+ l_fapi_mba_target);
+ if( l_errl )
+ {
+ errlCommit(l_errl, HTMGT_COMP_ID);
+ TS_FAIL("Call to mss_eff_config_thermal failed");
+ }
+
FAPI_INVOKE_HWP( l_errl,
mss_bulk_pwr_throttles,
l_fapi_mba_target);
diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
index d519a9253..c912b455e 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml
@@ -622,6 +622,18 @@
</attribute>
<attribute>
+ <id>PSTATE_TABLE</id>
+ <description>HTMGT PSTATE data</description>
+ <simpleType>
+ <uint8_t></uint8_t>
+ <array>1904</array>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+</attribute>
+
+<attribute>
<id>OCC_CONTROL_DATA</id>
<description>OCC operational data
</description>
@@ -633,6 +645,88 @@
<readable/>
<writeable/>
</attribute>
+
+<attribute>
+ <id>OT_MIN_N_PER_MBA</id>
+ <description>
+ Lowest per MBA numerator ever allowed when OCC is
+ throttling due to OT.
+ </description>
+ <simpleType>
+ <uint16_t>
+ <default>0</default>
+ </uint16_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+</attribute>
+
+<attribute>
+ <id>N_PLUS_ONE_N_PER_MBA</id>
+ <description>
+ 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.
+ </description>
+ <simpleType>
+ <uint16_t>
+ <default>0</default>
+ </uint16_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+</attribute>
+
+<attribute>
+ <id>N_PLUS_ONE_N_PER_CHIP</id>
+ <description>
+ Static per chip numerator setting when not in oversubscription.
+ </description>
+ <simpleType>
+ <uint16_t>
+ <default>0</default>
+ </uint16_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+</attribute>
+
+<attribute>
+ <id>OVERSUB_N_PER_MBA</id>
+ <description>
+ Static per MBA numerator setting when in oversubscription.
+ Calculated based on MRW oversubscription memory power.
+ </description>
+ <simpleType>
+ <uint16_t>
+ <default>0</default>
+ </uint16_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+</attribute>
+
+<attribute>
+ <id>OVERSUB_N_PER_CHIP</id>
+ <description>
+ Static per chip numerator setting when in oversubscription.
+ </description>
+ <simpleType>
+ <uint16_t>
+ <default>0</default>
+ </uint16_t>
+ </simpleType>
+ <persistency>volatile-zeroed</persistency>
+ <readable/>
+ <writeable/>
+</attribute>
+
+
<!-- end HTMGT attributes -->
<attribute>
diff --git a/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml b/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml
index d1f832c4a..c17e7dcb5 100644
--- a/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml
+++ b/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml
@@ -166,6 +166,22 @@
<default>5000</default>
</attribute>
<attribute>
+ <id>OPEN_POWER_REGULATOR_EFFICIENCY_FACTOR</id>
+ <default>85</default>
+ </attribute>
+ <attribute>
+ <id>OPEN_POWER_MIN_MEM_UTILIZATION_THROTTLING</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>OPEN_POWER_N_PLUS_ONE_MAX_MEM_POWER_WATTS</id>
+ <default>500</default>
+ </attribute>
+ <attribute>
+ <id>OPEN_POWER_N_MAX_MEM_POWER_WATTS</id>
+ <default>500</default>
+ </attribute>
+ <attribute>
<id>PM_EXTERNAL_VRM_STEPSIZE</id>
<default>0xc4</default>
</attribute>
diff --git a/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml b/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml
index ab81014c2..9b81815fa 100644
--- a/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml
+++ b/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml
@@ -169,6 +169,22 @@
<id>MRW_THERMAL_MEMORY_POWER_LIMIT</id>
<default>5000</default>
</attribute>
+ <attribute>
+ <id>OPEN_POWER_REGULATOR_EFFICIENCY_FACTOR</id>
+ <default>85</default>
+ </attribute>
+ <attribute>
+ <id>OPEN_POWER_MIN_MEM_UTILIZATION_THROTTLING</id>
+ <default>5</default>
+ </attribute>
+ <attribute>
+ <id>OPEN_POWER_N_PLUS_ONE_MAX_MEM_POWER_WATTS</id>
+ <default>500</default>
+ </attribute>
+ <attribute>
+ <id>OPEN_POWER_N_MAX_MEM_POWER_WATTS</id>
+ <default>500</default>
+ </attribute>
<attribute>
<id>PM_EXTERNAL_VRM_STEPSIZE</id>
<default>0xc4</default>
diff --git a/src/usr/targeting/common/xmltohb/target_types_hb.xml b/src/usr/targeting/common/xmltohb/target_types_hb.xml
index dbbf1a167..cdab85f84 100644
--- a/src/usr/targeting/common/xmltohb/target_types_hb.xml
+++ b/src/usr/targeting/common/xmltohb/target_types_hb.xml
@@ -153,4 +153,20 @@
<attribute><id>VPD_SWITCHES</id></attribute>
</targetTypeExtension>
+<targetTypeExtension>
+ <id>occ</id>
+ <attribute>
+ <id>PSTATE_TABLE</id>
+ </attribute>
+</targetTypeExtension>
+
+<targetTypeExtension>
+ <id>unit-mba-power8</id>
+ <attribute><id>OT_MIN_N_PER_MBA</id></attribute>
+ <attribute><id>N_PLUS_ONE_N_PER_MBA</id></attribute>
+ <attribute><id>N_PLUS_ONE_N_PER_CHIP</id></attribute>
+ <attribute><id>OVERSUB_N_PER_MBA</id></attribute>
+ <attribute><id>OVERSUB_N_PER_CHIP</id></attribute>
+</targetTypeExtension>
+
</attributes>
OpenPOWER on IntegriCloud