summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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