Patches to resolve circular dependency preventing 32x32gb dimm func
diff --git a/openpower/package/hostboot/hostboot-0005-Function-to-set-nest-freq-based-off-dimms.patch b/openpower/package/hostboot/hostboot-0005-Function-to-set-nest-freq-based-off-dimms.patch
new file mode 100644
index 0000000..d64991a
--- /dev/null
+++ b/openpower/package/hostboot/hostboot-0005-Function-to-set-nest-freq-based-off-dimms.patch
@@ -0,0 +1,937 @@
+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
+