blob: d64991af5ccc78449a0d54ffea44c9b57a7d0273 [file] [log] [blame]
From 8afc07837b303e5621ba28fed8a070eba633475d Mon Sep 17 00:00:00 2001
From: aalugore <aalugore@us.ibm.com>
Date: Mon, 24 Aug 2015 13:42:24 -0500
Subject: [PATCH] Function to set Nest Frequency based off DIMM memory
capability
-Needed for 32x32GB DIMM support
-Finds max capable frequency of system and all present DIMMs
and deconfigures any DIMM that cannot run at desired frequency
-If necessary, Sets Nest Freq and triggers SBE update
Change-Id: I9bba92f55f1b67ff4a15d79113f19d39272ec72d
RTC:122884
Depends-on:I1dca7196cd02a2704a238665b73b522c9e103936
---
src/include/usr/hwpf/hwpf_reasoncodes.H | 4 +-
src/include/usr/isteps/istep12list.H | 4 +-
src/include/usr/sbe/sbeif.H | 16 +
src/include/usr/targeting/common/target.H | 11 +
src/include/util/algorithm.H | 18 +-
src/include/util/align.H | 17 +-
src/usr/hwpf/hwp/mc_config/mc_config.C | 437 ++++++++++++++++++++-
src/usr/hwpf/hwp/memory_attributes.xml | 12 +-
src/usr/hwpf/plat/fapiPlatUtil.C | 2 +-
src/usr/sbe/sbe_update.C | 62 +++
src/usr/targeting/common/target.C | 47 +++
.../targeting/common/xmltohb/attribute_types.xml | 10 +-
12 files changed, 608 insertions(+), 32 deletions(-)
diff --git a/src/include/usr/hwpf/hwpf_reasoncodes.H b/src/include/usr/hwpf/hwpf_reasoncodes.H
index e1a00da..ea326c1 100644
--- a/src/include/usr/hwpf/hwpf_reasoncodes.H
+++ b/src/include/usr/hwpf/hwpf_reasoncodes.H
@@ -80,7 +80,9 @@ namespace fapi
MOD_PLAT_MVPD_GET_VLTG_BUCKET_ATTR = 0x26,
MOD_PLAT_ATTR_SVC_CEN_DQ_TO_DIMM_CONN_DQ = 0x27,
MOD_PLAT_ATTR_SVC_GET_MEM_ATTR_DATA = 0x28,
-
+ MOD_GET_WOF_FREQ_UPLIFT_SELECTED = 0x29,
+ MOD_SET_NEST_FREQ = 0x2A,
+ MOD_FIND_MAX_DMI_SPD = 0x2B,
};
/**
diff --git a/src/include/usr/isteps/istep12list.H b/src/include/usr/isteps/istep12list.H
index 2e724f2..f668733 100644
--- a/src/include/usr/isteps/istep12list.H
+++ b/src/include/usr/isteps/istep12list.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2014 */
+/* Contributors Listed Below - COPYRIGHT 2012,2015 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -105,6 +105,8 @@ const DepModInfo g_istep12Dependancies = {
#ifndef CONFIG_VPO_COMPILE
DEP_LIB(libmc_config.so),
#endif
+ DEP_LIB(libsbe.so),
+ DEP_LIB(libbuild_winkle_images.so),
NULL
}
};
diff --git a/src/include/usr/sbe/sbeif.H b/src/include/usr/sbe/sbeif.H
index b00e01f..ff397ca 100644
--- a/src/include/usr/sbe/sbeif.H
+++ b/src/include/usr/sbe/sbeif.H
@@ -94,6 +94,22 @@ namespace SBE
*/
errlHndl_t resolveProcessorSbeSeeproms();
+ /**
+ * @brief Determines whether we are on the Golden side or not
+ *
+ * @param[out] o_isGolden boolean, True if we are on Golden side, False
+ * otherwise.
+ *
+ * @return errlHndl_t Error log handle on failure.
+ *
+ * NOTE: -Golden Side means we booted from the Golden Seeprom pointing
+ * at the Golden side of PNOR.
+ * -Using master processor to make this determination.
+ */
+
+ errlHndl_t isGoldenSide( bool & o_isGolden );
+
+
} //end namespace SBE
diff --git a/src/include/usr/targeting/common/target.H b/src/include/usr/targeting/common/target.H
index 25e7be6..bf5b7da 100644
--- a/src/include/usr/targeting/common/target.H
+++ b/src/include/usr/targeting/common/target.H
@@ -672,6 +672,17 @@ const char* Target::getAttrAsString() const
return attrToString<A>(l_attrValue);
}
+// Function to set various frequency related attributes
+/**
+ * @brief - sets various attributes directly related to the nest frequency.
+ *
+ * @param[in] i_sys - top level system target to set attributes for
+ * @param[in] i_newNestFreq - the new nest frequency to base all the attributes
+ * off of.
+ */
+void setFrequencyAttributes(Target * i_sys, uint32_t i_newNestFreq);
+
+
// WARNING: The following #include imports any platform specific template
// specializations for getAttr and tryGetAttr
#include <targeting/adapters/targetadapter.H>
diff --git a/src/include/util/algorithm.H b/src/include/util/algorithm.H
index 54baa02..dac0f47 100644
--- a/src/include/util/algorithm.H
+++ b/src/include/util/algorithm.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2014 */
+/* Contributors Listed Below - COPYRIGHT 2012,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. */
@@ -52,6 +54,20 @@ namespace Util
static const T value = (a > b) ? a : b;
};
+ /**
+ * @brief - utility function that determines if a given number is
+ * power of 2.
+ *
+ * @param[in] i_num - given number.
+ *
+ * @return bool - True if the number is a power of 2, False otherwise.
+ */
+ template <typename T>
+ bool isPow2(T i_num)
+ {
+ return (!(i_num & (i_num-1)));
+ }
+
};
};
#endif
diff --git a/src/include/util/align.H b/src/include/util/align.H
index e0132b2..10a8369 100644
--- a/src/include/util/align.H
+++ b/src/include/util/align.H
@@ -51,18 +51,7 @@
#define ALIGN_MEGABYTE(u) (ALIGN_X(u,MEGABYTE))
#define ALIGN_MEGABYTE_DOWN(u) (ALIGN_DOWN_X(u,MEGABYTE))
-// Returns a number that is aligned to the next highest power of 2 number of
-// pages for the given buffer.
-#define ALIGN_TO_NEXT_POWER_OF_TWO_PAGES(b) ({\
- unsigned int v = ALIGN_PAGE(b)/PAGE_SIZE;\
- v--;\
- v |= v >> 1;\
- v |= v >> 2;\
- v |= v >> 4;\
- v |= v >> 8;\
- v |= v >> 16;\
- v++;\
- v * PAGE_SIZE;\
- })
-
+// Return a number rounded to the next power of two.
+#define ALIGN_POW2(u) ((u&(u-1)) ? 1 << (64 - __builtin_clzl(u)) : u)
+#define ALIGN_POW2_DOWN(u) (u ? 1 << (63 - __builtin_clzl(u)) : 0)
#endif
diff --git a/src/usr/hwpf/hwp/mc_config/mc_config.C b/src/usr/hwpf/hwp/mc_config/mc_config.C
index b2bc2f1..f29ee7c 100644
--- a/src/usr/hwpf/hwp/mc_config/mc_config.C
+++ b/src/usr/hwpf/hwp/mc_config/mc_config.C
@@ -44,16 +44,19 @@
#include <trace/interface.H>
#include <initservice/taskargs.H>
+#include <initservice/initserviceif.H>
#include <errl/errlentry.H>
#include <hwpisteperror.H>
+#include <hwpf/hwpf_reasoncodes.H>
#include <errl/errludtarget.H>
#include <initservice/isteps_trace.H>
-
+#include <sbe/sbeif.H>
// targeting support
#include <targeting/common/commontargeting.H>
#include <targeting/common/utilFilter.H>
+#include <attributetraits.H>
// fapi support
#include <fapi.H>
@@ -79,6 +82,8 @@
#include "mss_volt/mss_volt_dimm_count.H"
#include <config.h>
+#include <util/align.H>
+#include <util/algorithm.H>
namespace MC_CONFIG
{
@@ -129,7 +134,8 @@ void set_eff_config_attrs_helper( const EFF_CONFIG_ATTRIBUTES_BASE i_base,
// Get Node Target
TARGETING::Target* sysTgt = NULL;
TARGETING::targetService().getTopLevelTarget(sysTgt);
- assert(sysTgt != NULL,"System target was NULL.");
+ assert(sysTgt != NULL,"set_eff_config_attrs_helper: "
+ "System target was NULL.");
TARGETING::TargetHandleList l_nodeList;
@@ -467,7 +473,8 @@ errlHndl_t setMemoryVoltageDomainOffsetVoltage()
TARGETING::Target* pSysTarget = NULL;
TARGETING::targetService().getTopLevelTarget(pSysTarget);
- assert(pSysTarget != NULL,"System target was NULL.");
+ assert(pSysTarget != NULL,"setMemoryVoltageDomainOffsetVoltage: "
+ "System target was NULL.");
typename AttributeTraits< OFFSET_DISABLEMENT_ATTR >::Type
disableOffsetVoltage =
@@ -717,13 +724,16 @@ void call_mss_volt_hwp (std::vector<TARGETING::ATTR_VMEM_ID_type>& i_VmemList,
l_membufFapiTargets.push_back( l_membuf_fapi_target );
}
}
+
+ TRACDCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "Calling mss_volt_hwp...");
FAPI_INVOKE_HWP(l_err, mss_volt_hwp, l_membufFapiTargets);
// process return code.
if ( l_err )
{
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
- "ERROR 0x%.8X: mss_volt_dimm_count HWP( ) ",
+ "ERROR 0x%.8X: mss_volt HWP( ) ",
l_err->reasonCode());
// Create IStep error log and cross reference to error that occurred
@@ -872,7 +882,411 @@ void* call_mss_volt( void *io_pArgs )
return l_StepError.getErrorHandle();
}
+/**
+ * @brief - this utility function takes in the frequency in
+ * ATTR_MRW_NEST_CAPABLE_FREQUENCIES_SYS and returns the corresponding
+ * dmi bus speed from ATTR_MSS_NEST_CAPABLE_FREQUENCIES
+ *
+ * @param[in] i_freq - the input frequency
+ * @param[in/out] io_speed - the corresponding dmi bus speed
+ */
+void sysFreq_to_dmiSpeed(ATTR_MRW_NEST_CAPABLE_FREQUENCIES_SYS_type i_freq,
+ ATTR_MSS_NEST_CAPABLE_FREQUENCIES_type & io_speed)
+{
+ switch(i_freq)
+ {
+ case TARGETING::MRW_NEST_CAPABLE_FREQUENCIES_SYS_UNSUPPORTED_FREQ:
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,"Unsupported nest freq!");
+ io_speed = 0;
+ break;
+ case TARGETING::MRW_NEST_CAPABLE_FREQUENCIES_SYS_2000_MHZ:
+ io_speed=fapi::ENUM_ATTR_MSS_NEST_CAPABLE_FREQUENCIES_8_0G;
+ break;
+ case TARGETING::MRW_NEST_CAPABLE_FREQUENCIES_SYS_2400_MHZ:
+ io_speed=fapi::ENUM_ATTR_MSS_NEST_CAPABLE_FREQUENCIES_9_6G;
+ break;
+ case TARGETING::MRW_NEST_CAPABLE_FREQUENCIES_SYS_2000_MHZ_OR_2400_MHZ:
+ io_speed=fapi::ENUM_ATTR_MSS_NEST_CAPABLE_FREQUENCIES_8_0G_OR_9_6G;
+ break;
+ default:
+ io_speed = 0;
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,"Invalid nest freq!");
+ }
+}
+/**
+ * @brief - this utility function takes in the dmi bus speed enumeration
+ * value as described in MSS_NEST_CAPABLE_FREQUENCIES and outputs
+ * the actual corresponding nest frequency in MHz supported by the
+ * given dmi bus speed.
+ *
+ * @param[in] i_speed - the input dmi bus speed
+ * @param[in/out] io_freq - the corresponding frequency in MHz
+ *
+ */
+void dmiSpeed_to_sysFreq(ATTR_MSS_NEST_CAPABLE_FREQUENCIES_type i_speed,
+ ATTR_NEST_FREQ_MHZ_type & io_freq)
+{
+ switch(i_speed)
+ {
+ case fapi::ENUM_ATTR_MSS_NEST_CAPABLE_FREQUENCIES_8_0G:
+ io_freq = 2000;
+ break;
+ case fapi::ENUM_ATTR_MSS_NEST_CAPABLE_FREQUENCIES_9_6G:
+ io_freq = 2400;
+ break;
+ default:
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "Invalid dmi speed!");
+ io_freq = 0;
+ }
+}
+
+
+
+//
+// calloutChildDimms
+//
+void calloutChildDimms(errlHndl_t & io_errl, const TARGETING::Target * i_membuf)
+{
+ TargetHandleList l_dimmList;
+
+ // Get child dimms
+ getChildAffinityTargets( l_dimmList,
+ i_membuf,
+ CLASS_NA,
+ TYPE_DIMM );
+
+ if( !l_dimmList.empty())
+ {
+ // iterate over the DIMMs and call them out
+ TargetHandleList::iterator l_iter = l_dimmList.begin();
+
+ for(;l_iter != l_dimmList.end(); ++l_iter)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "Calling out DIMM Target huid = %x",
+ get_huid(*l_iter));
+
+ io_errl->addHwCallout( *l_iter,
+ HWAS::SRCI_PRIORITY_MED,
+ HWAS::DELAYED_DECONFIG,
+ HWAS::GARD_NULL );
+ }
+ }
+ else
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "No child DIMMs found!");
+ }
+}
+
+
+// TODO RTC 135720 - Support for mixed DIMM configuration with 32GB DIMMs.
+
+/**
+ * @brief - Recursive utility function for finding the max dmi
+ * bus speed to run at based on the nest dmi bus speed
+ * and the membuf's dmi bus speed
+ *
+ * @param[in] i_iter - Iterator over the list of membufs.
+ * @param[in] i_membufs - Pointer to the list of membufs.
+ * @param[in/out] io_currentMaxSpeed - The speed to run at will be returned here
+ * @param[in] i_capableNestDmiBusSpeed - The nest capable dmi bus speed.
+ */
+void findMaxSpdAndDeconfigIncompatible(TargetHandleList::iterator i_iter,
+ TargetHandleList * i_membufs,
+ ATTR_MSS_NEST_CAPABLE_FREQUENCIES_type & io_currentMaxSpeed,
+ ATTR_MSS_NEST_CAPABLE_FREQUENCIES_type i_capableNestDmiBusSpeed )
+{
+ do
+ {
+ // Base Case: If we are at the end of the membuf list return
+ if(i_iter == i_membufs->end())
+ {
+ // find the left most bit of the max speed found. This bit
+ // represents the highest dmi bus speed setting we can support
+ // across the nest and all membufs and the speed we will boot with.
+ io_currentMaxSpeed = ALIGN_POW2_DOWN(io_currentMaxSpeed);
+ break;
+ }
+
+ // Get the current membuf's dmi bus speed
+ ATTR_MSS_NEST_CAPABLE_FREQUENCIES_type l_currentMembufSpd =
+ (*i_iter)->getAttr<TARGETING::ATTR_MSS_NEST_CAPABLE_FREQUENCIES>();
+
+ // update current max speed.
+ // Max is restricted by nest capable dmi bus speed
+ if(((l_currentMembufSpd & i_capableNestDmiBusSpeed) != 0) &&
+ (l_currentMembufSpd > io_currentMaxSpeed))
+ {
+ io_currentMaxSpeed = l_currentMembufSpd;
+ }
+
+ //Save the current membuf for when we come back from recursive call.
+ TARGETING::Target * l_currentMembuf = (*i_iter);
+
+ // Recursive call to go down the list of membufs and find the max
+ // capable dmi speed across the nest and membufs.
+ findMaxSpdAndDeconfigIncompatible(++i_iter,
+ i_membufs,
+ io_currentMaxSpeed,
+ i_capableNestDmiBusSpeed );
+
+ // deconfigure any membufs with incompatible
+ // speeds on the way up the stack
+ if((l_currentMembufSpd & io_currentMaxSpeed) == 0)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "Deconfiguring Membuf Huid: %X, membuf speed: %d",
+ TARGETING::get_huid(l_currentMembuf),
+ l_currentMembufSpd);
+ // Membuf has incompatible frequency. Deconfigure it.
+ /*@
+ * @errortype
+ * @moduleid MOD_FIND_MAX_DMI_SPD
+ * @reasoncode RC_INVALID_FREQ
+ * @userdata1 HUID of membuf
+ * @userdata2 [0:7] membuf frequency enumeration value
+ * @userdata2 [8:15] dmi bus speed enumeration value
+ * @devdesc Invalid nest frequency found for given membuf
+ * @custdesc Invalid memory configuration
+ */
+ errlHndl_t l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ fapi::MOD_FIND_MAX_DMI_SPD,
+ fapi::RC_INVALID_FREQ,
+ TARGETING::get_huid(l_currentMembuf),
+ TO_UINT64(TWO_UINT8_TO_UINT16
+ (l_currentMembufSpd,
+ i_capableNestDmiBusSpeed)));
+
+ l_err->addHwCallout(l_currentMembuf, HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DELAYED_DECONFIG,
+ HWAS::GARD_NULL );
+ l_err->addProcedureCallout(
+ HWAS::EPUB_PRC_MEMORY_PLUGGING_ERROR,
+ HWAS::SRCI_PRIORITY_HIGH );
+
+
+ // add hw callouts for current membuf child DIMMs
+ calloutChildDimms( l_err, l_currentMembuf );
+
+ errlCommit( l_err, HWPF_COMP_ID );
+ l_err = NULL;
+ }
+ }while( 0 );
+}
+
+
+//
+// setNestBasedOffDimms
+//
+errlHndl_t setNestBasedOffDimms()
+{
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, ENTER_MRK"mc_config::setNestBasedOffDimms()");
+ errlHndl_t l_err = NULL;
+ bool l_isGoldenSide = false;
+ ATTR_MRW_NEST_CAPABLE_FREQUENCIES_SYS_type l_capableNestFreq =
+ MRW_NEST_CAPABLE_FREQUENCIES_SYS_UNSUPPORTED_FREQ;
+
+ ATTR_MSS_NEST_CAPABLE_FREQUENCIES_type l_selectedBootSpeed =
+ fapi::ENUM_ATTR_MSS_NEST_CAPABLE_FREQUENCIES_NONE;
+
+ ATTR_MSS_NEST_CAPABLE_FREQUENCIES_type l_capableNestDmiBusSpeed =
+ fapi::ENUM_ATTR_MSS_NEST_CAPABLE_FREQUENCIES_NONE;
+
+ ATTR_MSS_NEST_CAPABLE_FREQUENCIES_type l_compatibleSpeed =
+ fapi::ENUM_ATTR_MSS_NEST_CAPABLE_FREQUENCIES_NONE;
+
+ ATTR_NEST_FREQ_MHZ_type l_maxFreqMhz = 0;
+
+ l_isGoldenSide = false;
+
+ do
+ {
+ // First, get the systems capable nest frequency. If 0, then stick with
+ // already set nest frequency
+ TARGETING::Target * l_sys = NULL;
+ targetService().getTopLevelTarget(l_sys);
+
+ uint32_t l_currentSysNestFreq =
+ l_sys->getAttr<TARGETING::ATTR_NEST_FREQ_MHZ>();
+
+ // Check to see if we booted from the Golden side
+ l_err = SBE::isGoldenSide(l_isGoldenSide);
+
+ if(l_err)
+ {
+ // Error getting Golden side. Proceeding as if booting from safe Golden side
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ ERR_MRK"setNestBasedOffDimms::isGoldenSide returned an error");
+ errlCommit( l_err, HWPF_COMP_ID );
+ l_isGoldenSide = true;
+ }
+
+ if(!l_isGoldenSide)
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ INFO_MRK"Booting from normal side. use "
+ "MRW_NEST_CAPABLE_FREQUENCIES_SYS to calculate best freq "
+ "across membufs");
+ l_capableNestFreq = l_sys->getAttr
+ <ATTR_MRW_NEST_CAPABLE_FREQUENCIES_SYS>();
+ }
+ else
+ {
+ // We booted using the Golden Side. Use NEST_FREQ_MHZ
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ INFO_MRK"Booting from Golden Side. Use default NEST_FREQ"
+ "to calculate best freq across membufs");
+ if(l_currentSysNestFreq == 2000)
+ {
+ l_capableNestFreq =
+ TARGETING::MRW_NEST_CAPABLE_FREQUENCIES_SYS_2000_MHZ;
+ }
+ else if( l_currentSysNestFreq == 2400 )
+ {
+ l_capableNestFreq =
+ TARGETING::MRW_NEST_CAPABLE_FREQUENCIES_SYS_2400_MHZ;
+ }
+ else
+ {
+ l_capableNestFreq =
+ TARGETING::MRW_NEST_CAPABLE_FREQUENCIES_SYS_UNSUPPORTED_FREQ;
+ }
+
+ }
+
+ // convert the frequency to its corresponding dmi bus speed
+ sysFreq_to_dmiSpeed( l_capableNestFreq, l_capableNestDmiBusSpeed );
+
+ if(!l_capableNestDmiBusSpeed)
+ {
+ // Unknown frequency was given to sysFreq_to_dmiSpeed
+ // break out of function and proceed with value already in
+ // ATTR_NEST_FREQ_MHZ
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,"Invalid dmi speed. Proceeding with default value in NEST_FREQ_MHZ.");
+ break;
+ }
+
+ // Get a list of all the membufs
+ TargetHandleList l_membufs;
+ TARGETING::getAllChips(l_membufs, TYPE_MEMBUF);
+ TargetHandleList::iterator l_iter = l_membufs.begin();
+
+
+ // If the nest capable dmi bus speed can only support one setting,
+ // that speed is the speed we want to boot with.
+ // Deconfigure all membufs with incompatible speeds
+ if(Util::Algorithm::isPow2(l_capableNestDmiBusSpeed))
+ {
+ // We are forced to boot with the nest freq.
+ // Save boot freq for later.
+ l_selectedBootSpeed = l_capableNestDmiBusSpeed;
+
+
+ ATTR_MSS_NEST_CAPABLE_FREQUENCIES_type l_membufDmiBusSpeed = 0;
+ for(;l_iter != l_membufs.end(); ++l_iter )
+ {
+ l_membufDmiBusSpeed = (*l_iter)->getAttr
+ <TARGETING::ATTR_MSS_NEST_CAPABLE_FREQUENCIES>();
+
+ // if the intersection of the membuf's and nest's dmi speed
+ // is zero, the membuf is incompatible with the nest and must be
+ // deconfigured.
+ l_compatibleSpeed = l_membufDmiBusSpeed &
+ l_capableNestDmiBusSpeed;
+
+ if(l_compatibleSpeed ==
+ fapi::ENUM_ATTR_MSS_NEST_CAPABLE_FREQUENCIES_NONE )
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "Deconfiguring Membuf Huid: %X, membuf speed: %d",
+ TARGETING::get_huid(*l_iter),
+ l_membufDmiBusSpeed);
+ // Membuf has incompatible frequency. Deconfigure it.
+ /*@
+ * @errortype
+ * @moduleid MOD_SET_NEST_FREQ
+ * @reasoncode RC_INVALID_FREQ
+ * @userdata1 HUID of membuf
+ * @userdata2 [0:7] membuf frequency enumeration value
+ * @userdata2 [8:15] dmi bus speed enumeration value
+ * @devdesc Invalid nest found for given membuf
+ * @custdesc Invalid memory configuration
+ */
+ l_err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ fapi::MOD_SET_NEST_FREQ,
+ fapi::RC_INVALID_FREQ,
+ TARGETING::get_huid(*l_iter),
+ TO_UINT64(TWO_UINT8_TO_UINT16
+ (l_membufDmiBusSpeed,
+ l_capableNestDmiBusSpeed)));
+
+ l_err->addHwCallout(*l_iter, HWAS::SRCI_PRIORITY_HIGH,
+ HWAS::DELAYED_DECONFIG,
+ HWAS::GARD_NULL );
+
+
+ // add hw callouts for current membufs child DIMMs
+ calloutChildDimms( l_err, *l_iter);
+
+ errlCommit( l_err, HWPF_COMP_ID );
+ l_err = NULL;
+ continue;
+ }
+
+ } // end for-loop
+
+ }
+ else
+ {
+ // The nest supports multiple frequencies. Find the max dmi bus
+ // speed shared by the nest and at least 1 membuf and boot with that
+ // speed.
+ findMaxSpdAndDeconfigIncompatible(l_iter,
+ &l_membufs,
+ l_selectedBootSpeed,
+ l_capableNestDmiBusSpeed);
+
+ }
+
+ //Convert the selected boot speed to frequency
+ dmiSpeed_to_sysFreq(l_selectedBootSpeed, l_maxFreqMhz);
+
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "The max supported frequency across the processor and all dimms "
+ "is %d", l_maxFreqMhz );
+
+ if( l_maxFreqMhz == l_currentSysNestFreq)
+ {
+ //do nothing. go with current Nest freq, break.
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "Nest did not need to change. Proceeding with default NEST_FREQ");
+ break;
+ }
+ else
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "DIMM config determined NEST_FREQ needs to be changed to %d",
+ l_maxFreqMhz );
+ //set all the attributes and trigger an sbe update
+ TARGETING::setFrequencyAttributes(l_sys, l_maxFreqMhz);
+ //trigger sbe update so we can update all the frequency attributes
+ l_err = SBE::updateProcessorSbeSeeproms(
+ SBE::SBE_UPDATE_ONLY_CHECK_NEST_FREQ);
+
+ if( l_err )
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ "Error triggering sbe update.");
+ }
+ }
+ }while( 0 );
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "setNestBasedOffDimms exit" );
+ return l_err;
+}
//
// Wrapper function to call mss_freq
//
@@ -931,6 +1345,21 @@ void* call_mss_freq( void *io_pArgs )
}
} // End memBuf loop
+ if(! INITSERVICE::spBaseServicesEnabled() )
+ {
+ //set nest frequency based off present membufs
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ INFO_MRK"Setting Nest Frequency based off Membuf capability.");
+ l_err = setNestBasedOffDimms();
+
+ if( l_err )
+ {
+ TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
+ ERR_MRK"Error: call_mss_freq()::setNestBasedOffDimms()");
+ l_StepError.addErrorDetails(l_err);
+ }
+ }
+
TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_freq exit" );
return l_StepError.getErrorHandle();
diff --git a/src/usr/hwpf/hwp/memory_attributes.xml b/src/usr/hwpf/hwp/memory_attributes.xml
index b4059a2..df3a2ef 100644
--- a/src/usr/hwpf/hwp/memory_attributes.xml
+++ b/src/usr/hwpf/hwp/memory_attributes.xml
@@ -1,7 +1,7 @@
<!-- IBM_PROLOG_BEGIN_TAG -->
<!-- This is an automatically generated prolog. -->
<!-- -->
-<!-- $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/xml/attribute_info/memory_attributes.xml,v $ -->
+<!-- $Source: src/usr/hwpf/hwp/memory_attributes.xml $ -->
<!-- -->
<!-- OpenPOWER HostBoot Project -->
<!-- -->
@@ -23,7 +23,7 @@
<!-- -->
<!-- IBM_PROLOG_END_TAG -->
<attributes>
-<!-- $Id: memory_attributes.xml,v 1.159 2015/09/09 18:10:53 thi Exp $ -->
+<!-- $Id: memory_attributes.xml,v 1.159AL_custom 2014/11/18 17:35:29 aalugore Exp $ -->
<!-- DO NOT EDIT THIS FILE DIRECTLY PLEASE UPDATE THE ODS FILE AND FOLLOW THE INSTRUCTION TAB -->
<!-- PLEASE SEE MARK BELLOWS (BELLOWS.IBM.COM) OR OTHERS ON MEMORY TEAM FOR HELP -->
<!-- *********************************************************************** -->
@@ -108,7 +108,7 @@ Set by: PLL settings written by Dave Cadigan</description>
<odmChangeable/>
<persistRuntime/>
</attribute>
-
+
<attribute>
<id>ATTR_MSS_DIMM_MFG_ID_CODE</id>
<targetType>TARGET_TYPE_MBA_CHIPLET</targetType>
@@ -3051,8 +3051,8 @@ Will be set at an MBA level with one policy to be used</description>
<writeable/>
<odmVisable/>
<odmChangeable/>
- <enum>8_0G = 1, 9_6G = 2</enum>
-</attribute>
+ <enum>NONE = 0, 8_0G = 1, 9_6G = 2, 8_0G_OR_9_6G = 3</enum>
+</attribute>
<attribute>
<id>ATTR_MRW_STRICT_MBA_PLUG_RULE_CHECKING</id>
@@ -3425,7 +3425,7 @@ Will be set at an MBA level with one policy to be used</description>
<valueType>uint32</valueType>
<platInit/>
<odmVisable/>
-</attribute>
+</attribute>
<attribute>
<id>ATTR_MRW_MEM_SENSOR_CACHE_ADDR_MAP</id>
diff --git a/src/usr/hwpf/plat/fapiPlatUtil.C b/src/usr/hwpf/plat/fapiPlatUtil.C
index d03b670..269c36f 100644
--- a/src/usr/hwpf/plat/fapiPlatUtil.C
+++ b/src/usr/hwpf/plat/fapiPlatUtil.C
@@ -334,7 +334,7 @@ void* fapiPlatMalloc(size_t s)
{
if (s > PAGE_SIZE)
{
- s = ALIGN_TO_NEXT_POWER_OF_TWO_PAGES(s);
+ s = PAGE_SIZE * ALIGN_POW2(ALIGN_PAGE(s) / PAGE_SIZE);
}
return malloc(s);
}
diff --git a/src/usr/sbe/sbe_update.C b/src/usr/sbe/sbe_update.C
index 1faad63..237838f 100644
--- a/src/usr/sbe/sbe_update.C
+++ b/src/usr/sbe/sbe_update.C
@@ -3976,6 +3976,68 @@ namespace SBE
}
+/////////////////////////////////////////////////////////////////////
+ errlHndl_t isGoldenSide( bool & o_isGolden )
+ {
+ errlHndl_t l_errl = NULL;
+ o_isGolden = false;
+
+#ifndef CONFIG_SBE_UPDATE_SEQUENTIAL
+ do
+ {
+ // Get the master processor
+ TARGETING::Target * l_masterProc = NULL;
+ TARGETING::targetService().masterProcChipTargetHandle(l_masterProc);
+ assert( l_masterProc != NULL );
+
+ sbeSeepromSide_t l_currentSide = SBE_SEEPROM_INVALID;
+
+ // Get Seeprom side
+ l_errl = getSbeBootSeeprom(l_masterProc, l_currentSide);
+
+ if( l_errl )
+ {
+ TRACFCOMP( g_trac_sbe, ERR_MRK
+ "isGoldenSide() - Error returned "
+ "from getSbeBootSeeprom() "
+ "rc=0x%.4X, Target UID=0x%X",
+ l_errl->reasonCode(),
+ TARGETING::get_huid(l_masterProc));
+ break;
+ }
+
+ //Get PNOR Side
+ PNOR::SideId l_pnorSide = PNOR::WORKING;
+ PNOR::SideInfo_t l_sideInfo;
+
+ l_errl = PNOR::getSideInfo( l_pnorSide, l_sideInfo );
+
+ if( l_errl )
+ {
+ TRACFCOMP(g_trac_sbe, ERR_MRK
+ "isGoldenSide() - Error returned "
+ "from PNOR::getSideInfo() "
+ "rc=0x%.4X, Target UID=0x%X",
+ l_errl->reasonCode(),
+ TARGETING::get_huid( l_masterProc ));
+ break;
+ }
+
+ // SBE_SEEPROM1 by itself does not imply golden side.
+ // cross reference sbe side with pnor side to make sure.
+ if(( l_currentSide == SBE_SEEPROM1 ) &&
+ (( l_sideInfo.isGolden ) || (l_sideInfo.hasOtherSide == false )))
+ {
+ TRACUCOMP(g_trac_sbe, INFO_MRK
+ "sbe_update.C::isGoldenSide() - "
+ "Booted from Golden side!");
+ o_isGolden = true;
+ }
+
+ }while( 0 );
+#endif
+ return l_errl;
+ }
/////////////////////////////////////////////////////////////////////
diff --git a/src/usr/targeting/common/target.C b/src/usr/targeting/common/target.C
index 2248283..559fd4e 100644
--- a/src/usr/targeting/common/target.C
+++ b/src/usr/targeting/common/target.C
@@ -645,6 +645,53 @@ bool Target::uninstallWriteAttributeCallback()
#undef TARG_FN
}
+
+//******************************************************************************
+// setFrequencyAttributes
+//******************************************************************************
+void setFrequencyAttributes(Target * i_sys, uint32_t i_newNestFreq)
+{
+
+ // Calculate the new value for PIB_I2C_NEST_PLL using old freq attributes.
+ uint32_t l_oldPll = i_sys->getAttr<TARGETING::ATTR_PIB_I2C_NEST_PLL>();
+ uint32_t l_oldNestFreq = i_sys->getAttr<TARGETING::ATTR_NEST_FREQ_MHZ>();
+ uint32_t l_newPll = (i_newNestFreq * l_oldPll)/l_oldNestFreq;
+
+ //NEST_FREQ
+ i_sys->setAttr<TARGETING::ATTR_NEST_FREQ_MHZ>(i_newNestFreq);
+ TRACFCOMP(g_trac_targeting,
+ "ATTR_NEST_FREQ_MHZ getting set from %d to %d",
+ l_oldNestFreq,
+ i_newNestFreq );
+
+ //FREQ_X
+ uint32_t l_freqX = i_newNestFreq * 2;
+ i_sys->setAttr<TARGETING::ATTR_FREQ_X>(l_freqX);
+ TRACFCOMP(g_trac_targeting,
+ "ATTR_FREQ_X getting set to from %d to %d",
+ l_oldNestFreq*2,
+ l_freqX );
+
+ //FREQ_PB
+ uint32_t l_freqPb = i_newNestFreq;
+ i_sys->setAttr<TARGETING::ATTR_FREQ_PB>(l_freqPb);
+ TRACFCOMP(g_trac_targeting,
+ "ATTR_FREQ_PB getting set from %d to %d",
+ l_oldNestFreq,
+ l_freqPb );
+
+ //PIB_I2C_NEST_PLL
+ i_sys->setAttr<TARGETING::ATTR_PIB_I2C_NEST_PLL>(l_newPll);
+ TRACFCOMP(g_trac_targeting,
+ "ATTR_PIB_I2C_NEST_PLL getting set from %x to %x",
+ l_oldPll,
+ l_newPll);
+
+ return;
+}
+
+
+
//******************************************************************************
// Attribute Tanks
//******************************************************************************
diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml
index 05497fd..88041b4 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types.xml
@@ -2049,6 +2049,7 @@
<simpleType><uint32_t></uint32_t></simpleType>
<persistency>non-volatile</persistency>
<readable/>
+ <writeable/>
<hwpfToHbAttrMap>
<id>ATTR_FREQ_PB</id>
<macro>DIRECT</macro>
@@ -2083,6 +2084,7 @@
<simpleType><uint32_t></uint32_t></simpleType>
<persistency>non-volatile</persistency>
<readable/>
+ <writeable/>
<hwpfToHbAttrMap>
<id>ATTR_FREQ_X</id>
<macro>DIRECT</macro>
@@ -6103,7 +6105,7 @@ firmware notes: Used as override attribute for pstate procedure
<default>2000</default>
</uint32_t>
</simpleType>
- <persistency>volatile</persistency>
+ <persistency>non-volatile</persistency>
<readable/>
<writeable/>
<hwpfToHbAttrMap>
@@ -15666,7 +15668,7 @@ firmware notes: Platforms should initialize this attribute to AUTO (0)</descript
<attribute>
<id>MRW_VMEM_REGULATOR_POWER_LIMIT_PER_DIMM_ADJ_ENABLE</id>
- <description>Machine Readable Workbook enablement of the HWP code to adjust
+ <description>Machine Readable Workbook enablement of the HWP code to adjust
the VMEM regulator power limit based on number of installed DIMMs.
</description>
<simpleType>
@@ -15702,7 +15704,7 @@ firmware notes: Platforms should initialize this attribute to AUTO (0)</descript
<attribute>
<id>MRW_VMEM_REGULATOR_MEMORY_POWER_LIMIT_PER_DIMM</id>
- <description>Machine Readable Workbook VMEM regulator power limit per CDIMM
+ <description>Machine Readable Workbook VMEM regulator power limit per CDIMM
assuming a full configuration. Units in cW.
</description>
<simpleType>
@@ -15741,7 +15743,7 @@ firmware notes: Platforms should initialize this attribute to AUTO (0)</descript
<attribute>
<id>MRW_NEST_CAPABLE_FREQUENCIES_SYS</id>
- <description>The NEST frequencies that the system can support. This is a bit-wise value that represents which of the possible nest frequencies are supported : 2.0GHz, 2.4GHz, or both.
+ <description>The NEST frequencies that the system can support. This is a bit-wise value that represents which of the possible nest frequencies are supported. : 2.0GHz, 2.4GHz, or both. New frequencies should be added in ascending order.
</description>
<simpleType>
<enumeration>
--
1.8.2.2