summaryrefslogtreecommitdiffstats
path: root/src/usr/hwpf
diff options
context:
space:
mode:
authorBill Schwartz <whs@us.ibm.com>2015-04-21 05:17:09 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2015-09-16 11:04:39 -0500
commitdf5c383842ed36306c537b22f7ac23971ed04b1d (patch)
tree67bbf99bdf8fdbf02edf147917dc6017f5461a45 /src/usr/hwpf
parenta67ea7384ec6c326cfe553ee235b13eb434adee7 (diff)
downloadtalos-hostboot-df5c383842ed36306c537b22f7ac23971ed04b1d.tar.gz
talos-hostboot-df5c383842ed36306c537b22f7ac23971ed04b1d.zip
Supply WOF data
Create new attributes to make available WOF information to HTMGT and HWPs. Change-Id: I45689bc06e5a3808b9b9c3a356b70dd6e9cd2dd2 RTC: 125378 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/17367 Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Reviewed-by: William H. Schwartz <whs@us.ibm.com> Tested-by: Jenkins OP HW Tested-by: FSP CI Jenkins Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/hwpf')
-rw-r--r--src/usr/hwpf/hwp/chip_accessors/chip.mk5
-rw-r--r--src/usr/hwpf/hwp/chip_accessors/chip_errors.xml25
-rw-r--r--src/usr/hwpf/hwp/chip_accessors/getTdpRdpCurrentFactor.C142
-rw-r--r--src/usr/hwpf/hwp/chip_attributes.xml19
-rw-r--r--src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.C248
-rw-r--r--src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.H6
-rw-r--r--src/usr/hwpf/plat/fapiPlatAttributeService.C11
-rw-r--r--src/usr/hwpf/plat/fapiPlatMvpdAccess.C36
8 files changed, 461 insertions, 31 deletions
diff --git a/src/usr/hwpf/hwp/chip_accessors/chip.mk b/src/usr/hwpf/hwp/chip_accessors/chip.mk
index 8bca9427c..e98de05ec 100644
--- a/src/usr/hwpf/hwp/chip_accessors/chip.mk
+++ b/src/usr/hwpf/hwp/chip_accessors/chip.mk
@@ -5,7 +5,9 @@
#
# OpenPOWER HostBoot Project
#
-# COPYRIGHT International Business Machines Corp. 2012,2014
+# Contributors Listed Below - COPYRIGHT 2014,2015
+# [+] 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.
@@ -27,4 +29,5 @@ VPATH += ${HWPPATH}/chip_accessors
OBJS += getPciOscswitchConfig.o
OBJS += getOscswitchCtlAttr.o
+OBJS += getTdpRdpCurrentFactor.o
diff --git a/src/usr/hwpf/hwp/chip_accessors/chip_errors.xml b/src/usr/hwpf/hwp/chip_accessors/chip_errors.xml
index 388ab2721..c9abf520e 100644
--- a/src/usr/hwpf/hwp/chip_accessors/chip_errors.xml
+++ b/src/usr/hwpf/hwp/chip_accessors/chip_errors.xml
@@ -5,7 +5,9 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- COPYRIGHT International Business Machines Corp. 2014 -->
+<!-- Contributors Listed Below - COPYRIGHT 2014,2015 -->
+<!-- [+] 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. -->
@@ -20,7 +22,7 @@
<!-- permissions and limitations under the License. -->
<!-- -->
<!-- IBM_PROLOG_END_TAG -->
-<!-- $Id: chip_errors.xml,v 1.3 2014/05/23 01:07:27 whs Exp $ -->
+<!-- $Id: chip_errors.xml,v 1.5 2015/08/11 08:55:24 whs Exp $ -->
<hwpErrors>
<!-- ******************************************************************** -->
<hwpError>
@@ -97,4 +99,23 @@
<ffdc>FFDC_PASSED_SIZE</ffdc>
</hwpError>
<!-- ******************************************************************** -->
+ <hwpError>
+ <rc>RC_INSUFFICIENT_VPD_RETURNED</rc>
+ <description>
+ VPD keyword record returned is smaller than expected.
+ Probably a firmware bug, but could be bad VPD
+ </description>
+ <ffdc>KEYWORD</ffdc>
+ <ffdc>RETURNED_SIZE</ffdc>
+ <ffdc>EXPECTED_SIZE</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ <callout>
+ <target>CHIP_TARGET</target>
+ <priority>MEDIUM</priority>
+ </callout>
+ </hwpError>
+ <!-- ********************************************************************* -->
</hwpErrors>
diff --git a/src/usr/hwpf/hwp/chip_accessors/getTdpRdpCurrentFactor.C b/src/usr/hwpf/hwp/chip_accessors/getTdpRdpCurrentFactor.C
new file mode 100644
index 000000000..f7da05c85
--- /dev/null
+++ b/src/usr/hwpf/hwp/chip_accessors/getTdpRdpCurrentFactor.C
@@ -0,0 +1,142 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/chip_accessors/getTdpRdpCurrentFactor.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015 */
+/* [+] 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 */
+// $Id: getTdpRdpCurrentFactor.C,v 1.6 2015/09/15 20:31:49 whs Exp $
+/**
+ * @file getTdpRdpCurrentFactor.C
+ *
+ * @brief Accessor for providing the ATTR_TDP_RDP_CURRENT_FACTOR attribute
+ *
+ */
+
+#include <stdint.h>
+
+// fapi support
+#include <fapi.H>
+#include <fapiUtil.H>
+#include <getTdpRdpCurrentFactor.H>
+
+extern "C"
+{
+using namespace fapi;
+
+fapi::ReturnCode getTdpRdpCurrentFactor(
+ const fapi::Target &i_procTarget,
+ uint32_t & o_val)
+{
+
+ const uint32_t DEFAULT_TDP_RDP_CURRENT_FACTOR = 9180; // 91.90% = 0x9180
+ // IQ keyword layout
+ const uint8_t NUM_ENTRIES = 4; // The IQ keyword has 4 sub entries
+ const uint8_t TDP_RDP_ENTRY =0; // Array index for LRP9 Entry 1
+
+ struct iq_entry
+ {
+ uint8_t iv_MSB; // data in big endian format
+ uint8_t iv_LSB;
+ };
+ struct iq_keyword
+ {
+ uint8_t iv_version;
+ iq_entry entry[NUM_ENTRIES];
+ };
+
+ fapi::ReturnCode l_fapirc;
+ uint32_t l_tdpRdp = 0;
+
+ FAPI_DBG("getTdpRdpCurrentFactor: entry");
+
+ do
+ {
+ // On WOF enabled systems, mvpd record LRP9 keyword IQ has the
+ // TDP RDP current factor. LRP9 is not present for Murano processors
+ // and is present, but not defined as TDP RPD current factor on other
+ // Venice processors.
+ // Only look for TDP RPD current factor in vpd for WOF enabled systems.
+
+ // See if WOF enabled
+ uint8_t l_WofEnabled = ENUM_ATTR_WOF_ENABLED_DISABLED;
+ l_fapirc = FAPI_ATTR_GET(ATTR_WOF_ENABLED,NULL,l_WofEnabled);
+ if ( l_fapirc )
+ {
+ FAPI_IMP("getTdpRdpCurrentFactor: get ATTR_WOF_ENABLED failed, "
+ "rc=0x%08x",
+ static_cast<uint32_t>(l_fapirc));
+ break; // return with error. Unexpected.
+ }
+ else if (ENUM_ATTR_WOF_ENABLED_DISABLED == l_WofEnabled)
+ {
+ break; // not a WOF enabled system. Return with 0 value. No error.
+ }
+
+ // Read TDP RDP current factor from LRP9 IQ keyword.
+ // Expected to be present on WOF enabled system.
+ iq_keyword l_iqKeyword = {0,{{0}}};
+ uint32_t l_bufsize = sizeof(l_iqKeyword);
+
+ l_fapirc = fapiGetMvpdField(MVPD_RECORD_LRP9,
+ MVPD_KEYWORD_IQ,
+ i_procTarget,
+ (uint8_t*)(&l_iqKeyword),
+ l_bufsize );
+ if ( l_fapirc )
+ {
+ FAPI_IMP("getTdpRdpCurrentFactor: get LRP9 IQ failed, "
+ "rc=0x%08x",
+ static_cast<uint32_t>(l_fapirc));
+ break; // return with error
+ }
+ if (l_bufsize < sizeof(l_iqKeyword)) //ensure expected data retured
+ {
+ FAPI_ERR("getTdpRdpCurrentFacto:"
+ " less IQ keyword returned than expected %d < %d, "
+ " use default",
+ l_bufsize, sizeof(l_iqKeyword));
+ const uint32_t & KEYWORD = fapi::MVPD_KEYWORD_IQ;
+ const uint32_t & RETURNED_SIZE = l_bufsize;
+ const uint32_t & EXPECTED_SIZE = sizeof(l_iqKeyword);
+ const fapi::Target & CHIP_TARGET = i_procTarget;
+ FAPI_SET_HWP_ERROR(l_fapirc, RC_INSUFFICIENT_VPD_RETURNED );
+ break; // return with error. Unexpected.
+ }
+ // get TDP RDP current factor endian safe
+ l_tdpRdp = l_iqKeyword.entry[TDP_RDP_ENTRY].iv_LSB;
+ l_tdpRdp |= (l_iqKeyword.entry[TDP_RDP_ENTRY].iv_MSB<<8);
+ FAPI_DBG("getTdpRdpCurrentFactor: LRP9 IQ value=%d",l_tdpRdp);
+
+ // use default if value not filled in by mfg
+ if (!l_tdpRdp)
+ {
+ l_tdpRdp = DEFAULT_TDP_RDP_CURRENT_FACTOR;
+ FAPI_IMP("getTdpRdpCurrentFactor: use default value=%d",l_tdpRdp);
+ }
+ } while (0);
+
+ // return value
+ o_val = l_tdpRdp;
+
+ return l_fapirc;
+}
+
+} // extern "C"
diff --git a/src/usr/hwpf/hwp/chip_attributes.xml b/src/usr/hwpf/hwp/chip_attributes.xml
index ebecb8764..498e8aa70 100644
--- a/src/usr/hwpf/hwp/chip_attributes.xml
+++ b/src/usr/hwpf/hwp/chip_attributes.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
-<!-- Contributors Listed Below - COPYRIGHT 2012,2014 -->
+<!-- Contributors Listed Below - COPYRIGHT 2012,2015 -->
<!-- [+] International Business Machines Corp. -->
<!-- -->
<!-- -->
@@ -22,7 +22,7 @@
<!-- permissions and limitations under the License. -->
<!-- -->
<!-- IBM_PROLOG_END_TAG -->
-<!-- $Id: chip_attributes.xml,v 1.17 2014/11/20 17:58:41 jmcgill Exp $ -->
+<!-- $Id: chip_attributes.xml,v 1.18 2015/04/30 20:15:33 stillgs Exp $ -->
<!--
XML file specifying HWPF attributes.
These are platInit attributes associated with chips.
@@ -241,4 +241,19 @@
<writeable/>
<platInit/>
</attribute>
+ <!-- ********************************************************************* -->
+ <attribute>
+ <id>ATTR_TDP_RDP_CURRENT_FACTOR</id>
+ <targetType>TARGET_TYPE_PROC_CHIP</targetType>
+ <description>
+ Defines the scaling factor that converts the AC current (amperage) value from
+ the Thermal Design Point (TDP) to the Regulator Design Point (RDP) as input
+ to the Workload Optimization Frequency (WOF) OCC algorithm.
+
+ This is a percentage ratio value and has a granularity of 0.01 percent. Data
+ is held in hexidecimal. Example: 86.17% -> 8617 -> 0x21A9.
+ </description>
+ <valueType>uint32</valueType>
+ </attribute>
+ <!-- ********************************************************************* -->
</attributes>
diff --git a/src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.C b/src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.C
index 55cbb4a62..087e07844 100644
--- a/src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.C
+++ b/src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.C
@@ -58,6 +58,157 @@ using namespace TARGETING;
namespace FREQVOLTSVC
{
+ //**************************************************************************
+ // FREQVOLTSVC::setWofFrequencyUpliftSelected
+ //**************************************************************************
+ void setWofFrequencyUpliftSelected()
+ {
+
+ // get mrw data
+ TARGETING::Target* l_pTopLevel = NULL;
+ (void)TARGETING::targetService().getTopLevelTarget(l_pTopLevel);
+ ATTR_WOF_FREQUENCY_UPLIFT_type l_upliftTable = {{{0}}};
+ ATTR_WOF_PROC_SORT_type l_procSortTable = {{0}};
+ ATTR_NOMINAL_FREQ_MHZ_type l_sysNomFreqMhz =
+ l_pTopLevel->getAttr<ATTR_NOMINAL_FREQ_MHZ>();
+ ATTR_WOF_ENABLED_type l_wofEnabled = l_pTopLevel->getAttr
+ < TARGETING::ATTR_WOF_ENABLED > ();
+
+ // tryGetAttr used due to complex data type. Expected to always work.
+ if (!l_pTopLevel->tryGetAttr<ATTR_WOF_FREQUENCY_UPLIFT>(l_upliftTable))
+ {
+ // The zero initialized values will be used for the select array
+ TRACFCOMP(g_fapiTd, "Failed to get ATTR_WOF_FREQUENCY_UPLIFT");
+ }
+ // tryGetAttr used due to complex data type. Expected to always work.
+ if ( !l_pTopLevel->tryGetAttr<ATTR_WOF_PROC_SORT>(l_procSortTable))
+ {
+ // Not finding the sort table will result in not finding the index
+ // which will result in a log later
+ TRACFCOMP(g_fapiTd, "Failed to get ATTR_WOF_PROC_SORT");
+ }
+
+ // get the list of procs
+ TargetHandleList l_procTargetList;
+ getAllChips(l_procTargetList, TYPE_PROC, true);
+
+ // for each proc, fill in Wof Frequency Uplift Selected attribute
+ for (TargetHandleList::const_iterator
+ l_proc_iter = l_procTargetList.begin();
+ l_proc_iter != l_procTargetList.end();
+ ++l_proc_iter)
+ {
+ TARGETING::Target * l_pProcTarget = *l_proc_iter;
+
+ // find number of active cores
+ TARGETING::TargetHandleList l_presCoreList;
+ getChildAffinityTargetsByState( l_presCoreList,
+ const_cast<TARGETING::Target*>(l_pProcTarget),
+ TARGETING::CLASS_UNIT,
+ TARGETING::TYPE_CORE,
+ TARGETING::UTIL_FILTER_PRESENT);
+ uint8_t l_activeCores = l_presCoreList.size();
+ TRACDCOMP(g_fapiTd, "setWofFrequencyUpliftSelected:"
+ " number of active cores is %d ",
+ l_activeCores);
+
+ // find WOF index. For example:
+ // ATTR_WOF_PROC_SORT =
+ // Cores/Nom Freq/Index
+ // 8 3325 1
+ // 10 2926 2
+ // 12 2561 3
+ // 12 3093 4
+ // Use WOF index=3 for active cores=12 && nom freq=2561
+ uint8_t l_wofIndex = 0;
+ for (uint8_t i=0;i<4;i++)
+ {
+ if ( (l_activeCores == l_procSortTable[i][0]) &&
+ (l_sysNomFreqMhz == l_procSortTable[i][1]) )
+ {
+ l_wofIndex = l_procSortTable[i][2];
+ break;
+ }
+ }
+ TRACDCOMP(g_fapiTd, "setWofFrequencyUpliftSelected:"
+ " WOF index is %d ",
+ l_wofIndex);
+ // validate WOF index
+ ATTR_WOF_FREQUENCY_UPLIFT_SELECTED_type l_selectedTable = {{0}};
+ if ( (!l_wofIndex) || (l_wofIndex > 4))
+ {
+ if (l_wofEnabled) // log error if WOF enabled
+ {
+ TRACFCOMP(g_fapiTd, "setWofFrequencyUpliftSelected:"
+ " No WOF table index match found HUID:0x%08X"
+ " active cores=%d, nom freq=%d, index=%d",
+ l_pProcTarget->getAttr<TARGETING::ATTR_HUID>(),
+ l_activeCores,
+ l_sysNomFreqMhz,
+ l_wofIndex);
+
+ errlHndl_t l_err = NULL;
+ /*@
+ * @errortype
+ * @moduleid fapi::MOD_GET_WOF_FREQ_UPLIFT_SELECTED
+ * @reasoncode fapi::RC_INVALID_WOF_INDEX
+ * @userdata1[0:31] Proc HUID
+ * @userdata1[32:63] WOF Freq Uplift Index
+ * @userdata2[0:31] Number of active cores
+ * @userdata2[32:63] Nomimal Frequency
+ * @devdesc When WOF is enabled, the WOF Freq
+ * Uplift index should be 1,2,3, or 4
+ */
+ l_err =
+ new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ fapi::MOD_GET_WOF_FREQ_UPLIFT_SELECTED,
+ fapi::RC_INVALID_WOF_INDEX,
+ TWO_UINT32_TO_UINT64(
+ l_pProcTarget->getAttr<TARGETING::ATTR_HUID>(),
+ l_wofIndex),
+ TWO_UINT32_TO_UINT64(
+ l_activeCores,
+ l_sysNomFreqMhz));
+
+ // Callout HW as WOF mrw data is incorrect
+ l_err->addHwCallout(l_pProcTarget, HWAS::SRCI_PRIORITY_MED,
+ HWAS::NO_DECONFIG, HWAS::GARD_NULL);
+
+ // Include WOF processor sort table
+ TRACFBIN (g_fapiTd,
+ "WOF processor sort table",
+ l_procSortTable,
+ sizeof(l_procSortTable));
+ l_err->collectTrace(FAPI_TRACE_NAME);
+
+ // log error and keep going
+ errlCommit(l_err,HWPF_COMP_ID);
+ }
+ // make sure zeros are set in the selected table attribute
+ memset(l_selectedTable,
+ 0,
+ sizeof(l_selectedTable));
+ }
+ else
+ {
+ // use index to set Wof Frequency Uplift selected attribute
+ // note: mrw index is 1 based
+ memcpy(l_selectedTable,
+ &l_upliftTable[l_wofIndex-1][0][0],
+ sizeof(l_selectedTable));
+ }
+ if (!l_pProcTarget->trySetAttr<ATTR_WOF_FREQUENCY_UPLIFT_SELECTED>
+ (l_selectedTable))
+ {
+ //unlikely, crash
+ TRACFCOMP(g_fapiTd,
+ "Failed to set ATTR_WOF_FREQUENCY_UPLIFT_SELECTED");
+ assert(0);
+ }
+ }
+ return;
+ }
//**************************************************************************
// FREQVOLTSVC::setSysFreq
@@ -68,11 +219,14 @@ namespace FREQVOLTSVC
uint32_t l_sysHighestPowerSaveFreq = 0x0;
TARGETING::ATTR_NOMINAL_FREQ_MHZ_type l_sysNomFreq = 0x0;
TARGETING::ATTR_FREQ_CORE_MAX_type l_sysLowestTurboFreq = 0x0;
+ TARGETING::ATTR_ULTRA_TURBO_FREQ_MHZ_type
+ l_sysLowestUltraTurboFreq = 0x0;
// Get system frequency
l_err = getSysFreq(l_sysHighestPowerSaveFreq,
l_sysNomFreq,
- l_sysLowestTurboFreq);
+ l_sysLowestTurboFreq,
+ l_sysLowestUltraTurboFreq);
if (l_err != NULL)
{
TRACFCOMP( g_fapiTd,ERR_MRK"Error getting system frequency");
@@ -102,9 +256,16 @@ namespace FREQVOLTSVC
(void)l_pTopLevel->setAttr<TARGETING::ATTR_MIN_FREQ_MHZ>
(l_sysHighestPowerSaveFreq);
+ // Set min ultra turbo freq attribute
+ (void)l_pTopLevel->setAttr<TARGETING::ATTR_ULTRA_TURBO_FREQ_MHZ>
+ (l_sysLowestUltraTurboFreq);
+
verifyBootFreq(l_pTopLevel);
}
+ // set up the WOF Frequency Uplift Selected attribute
+ setWofFrequencyUpliftSelected();
+
return l_err;
}
@@ -128,12 +289,15 @@ namespace FREQVOLTSVC
// FREQVOLTSVC::getSysFreq
//**************************************************************************
errlHndl_t getSysFreq(
- uint32_t & o_sysVPDPowerSaveMinFreqMhz,
- TARGETING::ATTR_NOMINAL_FREQ_MHZ_type & o_sysNomFreqMhz,
- TARGETING::ATTR_FREQ_CORE_MAX_type & o_sysVPDTurboMaxFreqMhz)
+ uint32_t & o_sysVPDPowerSaveMinFreqMhz,
+ TARGETING::ATTR_NOMINAL_FREQ_MHZ_type & o_sysNomFreqMhz,
+ TARGETING::ATTR_FREQ_CORE_MAX_type & o_sysVPDTurboMaxFreqMhz,
+ TARGETING::ATTR_ULTRA_TURBO_FREQ_MHZ_type &
+ o_sysVPDUltraTurboMinFreqMhz)
{
uint32_t l_minsysVPDTurboMaxFreqMhz = 0;
uint32_t l_maxsysVPDPowerSaveMinFreqMhz = 0;
+ uint32_t l_minsysVPDUltraTurboFreqMhz = 0;
fapi::ReturnCode l_rc;
errlHndl_t l_err = NULL;
@@ -142,6 +306,19 @@ namespace FREQVOLTSVC
o_sysNomFreqMhz = 0;
o_sysVPDTurboMaxFreqMhz = 0;
o_sysVPDPowerSaveMinFreqMhz = 0;
+ o_sysVPDUltraTurboMinFreqMhz = 0;
+
+ //Get the top level (system) target handle
+ TARGETING::Target* l_pTopLevel = NULL;
+ (void)TARGETING::targetService().getTopLevelTarget(l_pTopLevel);
+
+ // Assert on failure getting system target
+ assert( l_pTopLevel != NULL );
+
+ // Retrun Fvmin as ultra turbo freq if WOF enabled.
+ ATTR_WOF_ENABLED_type l_wofEnabled = l_pTopLevel->getAttr
+ < TARGETING::ATTR_WOF_ENABLED > ();
+ TRACFCOMP(g_fapiTd,"getSysFreq: WOF_ENABLED is %d ",l_wofEnabled);
//Filter functional unit
TARGETING::PredicateIsFunctional l_isFunctional;
@@ -177,6 +354,8 @@ namespace FREQVOLTSVC
// Get Parent Chip target
const TARGETING::Target * l_pChipTarget =
getParentChip(l_pTarget);
+ fapi::Target l_pFapiChipTarget(fapi::TARGET_TYPE_PROC_CHIP,
+ (const_cast<TARGETING::Target*>(l_pChipTarget) ));
// Get core number for record number
TARGETING::ATTR_CHIP_UNIT_type l_coreNum =
@@ -185,7 +364,7 @@ namespace FREQVOLTSVC
uint32_t l_record = (uint32_t) MVPD::LRP0 + l_coreNum;
// Get #V bucket data
- l_rc = fapiGetPoundVBucketData(l_pChipTarget,
+ l_rc = fapiGetPoundVBucketData(l_pFapiChipTarget,
l_record,
l_poundVdata);
if(l_rc)
@@ -205,10 +384,15 @@ namespace FREQVOLTSVC
l_poundVdata.nomFreq;
TARGETING::ATTR_FREQ_CORE_MAX_type l_sysVPDTurboMaxFreqMhz =
l_poundVdata.turboFreq;
+ // WOF defines the reserved Fvmin value as ultra turbo
+ TARGETING::ATTR_ULTRA_TURBO_FREQ_MHZ_type
+ l_sysVPDUltraTurboFreqMhz = l_poundVdata.fvminFreq;
TRACFCOMP(g_fapiTd,INFO_MRK"Nominal freq is: [0x%08X]. Turbo "
- "freq is: [0x%08x]. PowerSave freq is: [0x%08X]",
+ "freq is: [0x%08x]. PowerSave freq is: [0x%08X]."
+ " Ultra Turbo is: [0x%08x]",
l_sysNomFreqMhz, l_sysVPDTurboMaxFreqMhz,
- l_sysVPDPowerSaveMinFreqMhz );
+ l_sysVPDPowerSaveMinFreqMhz,
+ l_sysVPDUltraTurboFreqMhz);
if( true == l_copyOnce)
{
@@ -216,6 +400,7 @@ namespace FREQVOLTSVC
l_minsysVPDTurboMaxFreqMhz = l_sysVPDTurboMaxFreqMhz;
l_maxsysVPDPowerSaveMinFreqMhz =
l_sysVPDPowerSaveMinFreqMhz;
+ l_minsysVPDUltraTurboFreqMhz = l_sysVPDUltraTurboFreqMhz;
l_copyOnce = false;
}
@@ -261,6 +446,39 @@ namespace FREQVOLTSVC
break;
}
+ // If WOF is enabled, Ultra Turbo frequency should not be zero.
+ // Return 0 for ultra turbo freq
+ if( (fapi::ENUM_ATTR_WOF_ENABLED_ENABLED == l_wofEnabled) &&
+ (l_sysVPDUltraTurboFreqMhz == 0) )
+ {
+ TRACFCOMP(g_fapiTd,
+ ERR_MRK"GetSysFreq: Ultra Turbo frequency is 0");
+
+ /*@
+ * @errortype
+ * @moduleid fapi::MOD_GET_SYS_FREQ
+ * @reasoncode fapi::RC_INVALID_ULTRA_TURBO_FREQ
+ * @userdata1 Proc HUID
+ * @userdata2 Invalid ultra turbo frequency
+ * @devdesc When WOF is enabled, ultra turbo freq
+ * should not be 0
+ */
+ l_err =
+ new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ fapi::MOD_GET_SYS_FREQ,
+ fapi::RC_INVALID_ULTRA_TURBO_FREQ,
+ l_pTarget->getAttr<TARGETING::ATTR_HUID>(),
+ l_sysVPDUltraTurboFreqMhz);
+
+ // Callout HW as VPD data is incorrect
+ l_err->addHwCallout(l_pTarget, HWAS::SRCI_PRIORITY_MED,
+ HWAS::NO_DECONFIG, HWAS::GARD_NULL);
+
+ // log error and keep going
+ errlCommit(l_err,HWPF_COMP_ID);
+ }
+
// Validate nominal frequency. If differs,
// create error and stop processing further.
if( o_sysNomFreqMhz != l_sysNomFreqMhz )
@@ -307,6 +525,13 @@ namespace FREQVOLTSVC
l_maxsysVPDPowerSaveMinFreqMhz =
l_sysVPDPowerSaveMinFreqMhz;
}
+ // Save the min ultra turbo freq
+ // If WOF is enabled, do not expect to see a zero value. But if
+ // there is a zero value, then return zero.
+ if (l_sysVPDUltraTurboFreqMhz < l_minsysVPDUltraTurboFreqMhz)
+ {
+ l_minsysVPDUltraTurboFreqMhz = l_sysVPDUltraTurboFreqMhz;
+ }
} // end for loop
if (l_err != NULL)
@@ -320,13 +545,18 @@ namespace FREQVOLTSVC
// Get max powersave freq
o_sysVPDPowerSaveMinFreqMhz = l_maxsysVPDPowerSaveMinFreqMhz;
+ // Get ultra turbo freq
+ o_sysVPDUltraTurboMinFreqMhz = l_minsysVPDUltraTurboFreqMhz;
+
} while (0);
TRACFCOMP(g_fapiTd,EXIT_MRK"o_sysNomFreqMhz: 0x%08X, "
"o_sysVPDTurboMaxFreqMhz: 0x%08X, "
- "o_sysVPDPowerSaveMinFreqMhz: 0x%08X",
+ "o_sysVPDPowerSaveMinFreqMhz: 0x%08X, "
+ "o_sysVPDUltraTurboFreqMhz: 0x%08x",
o_sysNomFreqMhz, o_sysVPDTurboMaxFreqMhz,
- o_sysVPDPowerSaveMinFreqMhz );
+ o_sysVPDPowerSaveMinFreqMhz,
+ o_sysVPDUltraTurboMinFreqMhz );
return l_err;
}
diff --git a/src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.H b/src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.H
index b8f047b29..1187076fc 100644
--- a/src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.H
+++ b/src/usr/hwpf/hwp/pstates/pstates/freqVoltageSvc.H
@@ -128,6 +128,9 @@ static const uint32_t PROC_BOOT_VOLT_VCS_MASK = 0x0000ff00;
* @param[out] o_sysVPDPowerSaveMinFreqMhz
* On success, holds highest powersave frequency
* On failure, set to zero.
+ * @param[out] o_sysVPDUltraTurboMinFreqMhz
+ * On success, holds lowest ultra turbo frequency
+ * On failure, set to zero.
*
* @return Error log handle indicating the status of the request
*
@@ -137,7 +140,8 @@ static const uint32_t PROC_BOOT_VOLT_VCS_MASK = 0x0000ff00;
errlHndl_t getSysFreq(
uint32_t & o_sysVPDPowerSaveMinFreqMhz,
TARGETING::ATTR_NOMINAL_FREQ_MHZ_type & o_sysNomFreqMhz,
- TARGETING::ATTR_FREQ_CORE_MAX_type & o_sysVPDTurboMaxFreqMhz);
+ TARGETING::ATTR_FREQ_CORE_MAX_type & o_sysVPDTurboMaxFreqMhz,
+ TARGETING::ATTR_ULTRA_TURBO_FREQ_MHZ_type & o_sysVPDUltraMinFreqMhz);
/**
* @brief Verify the system boot frequency attribute
diff --git a/src/usr/hwpf/plat/fapiPlatAttributeService.C b/src/usr/hwpf/plat/fapiPlatAttributeService.C
index 9f2e85714..651204ce8 100644
--- a/src/usr/hwpf/plat/fapiPlatAttributeService.C
+++ b/src/usr/hwpf/plat/fapiPlatAttributeService.C
@@ -51,6 +51,7 @@
#include <hwpf/hwp/mvpd_accessors/getMBvpdSensorMap.H>
#include <hwpf/hwp/mvpd_accessors/getMBvpdAttr.H>
#include <hwpf/hwp/mvpd_accessors/accessMBvpdL4BankDelete.H>
+#include <hwpf/hwp/chip_accessors/getTdpRdpCurrentFactor.H>
#include <hwpf/hwp/chip_accessors/getPciOscswitchConfig.H>
#include <hwpf/hwp/chip_accessors/getOscswitchCtlAttr.H>
#include <fapiPllRingAttr.H>
@@ -1587,6 +1588,16 @@ fapi::ReturnCode fapiPlatGetPciOscswitchConfig
}
//-----------------------------------------------------------------------------
+fapi::ReturnCode fapiPlatGetTdpRdpCurrentFactor
+ (const fapi::Target * i_pProcTarget,
+ uint32_t &o_val)
+{
+ fapi::ReturnCode l_rc;
+ FAPI_EXEC_HWP(l_rc, getTdpRdpCurrentFactor, *i_pProcTarget, o_val);
+ return l_rc;
+}
+
+//-----------------------------------------------------------------------------
fapi::ReturnCode fapiPlatGetSpdModspecComRefRawCard
(const fapi::Target * i_pDimmTarget,
uint8_t &o_val)
diff --git a/src/usr/hwpf/plat/fapiPlatMvpdAccess.C b/src/usr/hwpf/plat/fapiPlatMvpdAccess.C
index 051719ab6..274a63d47 100644
--- a/src/usr/hwpf/plat/fapiPlatMvpdAccess.C
+++ b/src/usr/hwpf/plat/fapiPlatMvpdAccess.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2014 */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -204,6 +204,7 @@ fapi::ReturnCode MvpdKeywordXlate(const fapi::MvpdKeyword i_fapiKeyword,
MVPD::MK,
MVPD::PB,
MVPD::CH,
+ MVPD::IQ,
};
const uint8_t NUM_MVPD_KEYWORDS =
sizeof(mvpdFapiKeywordToHbKeyword)/sizeof(mvpdFapiKeywordToHbKeyword[0]);
@@ -1290,9 +1291,6 @@ fapi::ReturnCode fapiGetMvpdField(const fapi::MvpdRecord i_record,
do
{
- TARGETING::Target * l_pChipTarget =
- reinterpret_cast<TARGETING::Target*>(i_procTarget.get());
-
// Translate the FAPI record to a Hostboot record
MVPD::mvpdRecord l_hbRecord = MVPD::MVPD_INVALID_RECORD;
@@ -1321,11 +1319,14 @@ fapi::ReturnCode fapiGetMvpdField(const fapi::MvpdRecord i_record,
fapi::voltageBucketData_t l_pVData;
// Get #V bucket data
- l_rc = fapiGetPoundVBucketData(l_pChipTarget,
+ l_rc = fapiGetPoundVBucketData(i_procTarget,
(uint32_t) l_hbRecord,
l_pVData);
if (l_rc)
{
+ TARGETING::Target * l_pChipTarget =
+ reinterpret_cast<TARGETING::Target*>(i_procTarget.get());
+
FAPI_ERR("fapiGetMvpdField: Error getting #V bucket data "
"HUID: 0x%08X",
l_pChipTarget->getAttr<TARGETING::ATTR_HUID>());
@@ -1506,7 +1507,7 @@ fapi::ReturnCode fapiSetMvpdField(const fapi::MvpdRecord i_record,
}
fapi::ReturnCode fapiGetPoundVBucketData(
- const TARGETING::Target * i_pChipTarget,
+ const fapi::Target &i_procTarget,
const uint32_t i_record,
fapi::voltageBucketData_t & o_data)
{
@@ -1518,8 +1519,11 @@ fapi::ReturnCode fapiGetPoundVBucketData(
do
{
+ TARGETING::Target * l_pChipTarget =
+ reinterpret_cast<TARGETING::Target*>(i_procTarget.get());
+
// Read PR keyword size
- l_err = deviceRead( (TARGETING::Target *)i_pChipTarget,
+ l_err = deviceRead( l_pChipTarget,
NULL,
l_vpdSize,
DEVICE_MVPD_ADDRESS( MVPD::VINI,
@@ -1528,7 +1532,7 @@ fapi::ReturnCode fapiGetPoundVBucketData(
{
FAPI_ERR("Error getting PR keyword size for HUID: "
"0x%08X, errorlog PLID=0x%x",
- i_pChipTarget->getAttr<TARGETING::ATTR_HUID>(),
+ l_pChipTarget->getAttr<TARGETING::ATTR_HUID>(),
l_err->plid());
// Add the error log pointer as data to the ReturnCode
@@ -1543,7 +1547,7 @@ fapi::ReturnCode fapiGetPoundVBucketData(
l_prDataPtr = new uint8_t [l_vpdSize];
// Read PR keyword data
- l_err = deviceRead( (TARGETING::Target *)i_pChipTarget,
+ l_err = deviceRead(l_pChipTarget,
l_prDataPtr,
l_vpdSize,
DEVICE_MVPD_ADDRESS( MVPD::VINI,
@@ -1552,7 +1556,7 @@ fapi::ReturnCode fapiGetPoundVBucketData(
{
FAPI_ERR("Error getting PR keyword data for HUID: "
"0x%08X, errorlog PLID=0x%x",
- i_pChipTarget->getAttr<TARGETING::ATTR_HUID>(),
+ l_pChipTarget->getAttr<TARGETING::ATTR_HUID>(),
l_err->plid());
// Add the error log pointer as data to the ReturnCode
@@ -1577,7 +1581,7 @@ fapi::ReturnCode fapiGetPoundVBucketData(
}
l_vpdSize = 0;
- l_err = deviceRead( (TARGETING::Target *)i_pChipTarget,
+ l_err = deviceRead( l_pChipTarget,
NULL,
l_vpdSize,
DEVICE_MVPD_ADDRESS( i_record,
@@ -1586,7 +1590,7 @@ fapi::ReturnCode fapiGetPoundVBucketData(
{
FAPI_ERR("Error getting #V keyword size for HUID: "
"0x%08X, errorlog PLID=0x%x",
- i_pChipTarget->getAttr<TARGETING::ATTR_HUID>(),
+ l_pChipTarget->getAttr<TARGETING::ATTR_HUID>(),
l_err->plid());
// Add the error log pointer as data to the ReturnCode
@@ -1600,7 +1604,7 @@ fapi::ReturnCode fapiGetPoundVBucketData(
l_vDataPtr = new uint8_t [l_vpdSize];
- l_err = deviceRead( (TARGETING::Target *)i_pChipTarget,
+ l_err = deviceRead( l_pChipTarget,
l_vDataPtr,
l_vpdSize,
DEVICE_MVPD_ADDRESS( i_record,
@@ -1609,7 +1613,7 @@ fapi::ReturnCode fapiGetPoundVBucketData(
{
FAPI_ERR("Error getting #V keyword data for HUID: "
"0x%08X, errorlog PLID=0x%x",
- i_pChipTarget->getAttr<TARGETING::ATTR_HUID>(),
+ l_pChipTarget->getAttr<TARGETING::ATTR_HUID>(),
l_err->plid());
// Add the error log pointer as data to the ReturnCode
@@ -1645,7 +1649,7 @@ fapi::ReturnCode fapiGetPoundVBucketData(
l_vpdSize);
// Callout HW as VPD data is incorrect
- l_err->addHwCallout(i_pChipTarget, HWAS::SRCI_PRIORITY_HIGH,
+ l_err->addHwCallout(l_pChipTarget, HWAS::SRCI_PRIORITY_HIGH,
HWAS::DECONFIG, HWAS::GARD_NULL);
// Code (SW) callout in case this is downlevel VPD version
@@ -1659,7 +1663,7 @@ fapi::ReturnCode fapiGetPoundVBucketData(
}
// Parse #V Version one data to get bucket data
- l_rc = fapiGetVerOneVoltageBucketData(i_pChipTarget,
+ l_rc = fapiGetVerOneVoltageBucketData(l_pChipTarget,
l_bucketId,
l_vpdSize,
l_vDataPtr,
OpenPOWER on IntegriCloud