summaryrefslogtreecommitdiffstats
path: root/src/usr/hwpf/hwp/mc_config
diff options
context:
space:
mode:
authorCamVan Nguyen <ctnguyen@us.ibm.com>2012-08-15 16:01:22 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-08-16 13:54:43 -0500
commit1681d8660846d58472bb717917ec383b49d69faf (patch)
tree9d5449b8aab65fc06bd7c4967db7953be12b8116 /src/usr/hwpf/hwp/mc_config
parent3afee991ccf79716b952706edfdf128b16154810 (diff)
downloadtalos-hostboot-1681d8660846d58472bb717917ec383b49d69faf.tar.gz
talos-hostboot-1681d8660846d58472bb717917ec383b49d69faf.zip
Updates to IPL flow v1.08
Change-Id: I496b5739f625dd5111a5cdd144e89dcd43ad1986 RTC: 45712 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1533 Tested-by: Jenkins Server Reviewed-by: Van H. Lee <vanlee@us.ibm.com> Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/hwpf/hwp/mc_config')
-rw-r--r--src/usr/hwpf/hwp/mc_config/makefile58
-rw-r--r--src/usr/hwpf/hwp/mc_config/mc_config.C306
-rw-r--r--src/usr/hwpf/hwp/mc_config/mc_config.H140
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config.C690
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config.H76
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_rank_group.C251
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_rank_group.H77
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.C193
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.H75
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.C315
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.H78
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.C436
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.H72
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt.C165
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt.H71
15 files changed, 3003 insertions, 0 deletions
diff --git a/src/usr/hwpf/hwp/mc_config/makefile b/src/usr/hwpf/hwp/mc_config/makefile
new file mode 100644
index 000000000..4256480d7
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/makefile
@@ -0,0 +1,58 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/hwpf/hwp/mc_config/makefile $
+#
+# IBM CONFIDENTIAL
+#
+# COPYRIGHT International Business Machines Corp. 2012
+#
+# p1
+#
+# Object Code Only (OCO) source materials
+# Licensed Internal Code Source Materials
+# IBM HostBoot Licensed Internal Code
+#
+# The source code for this program is not published or other-
+# wise divested of its trade secrets, irrespective of what has
+# been deposited with the U.S. Copyright Office.
+#
+# Origin: 30
+#
+# IBM_PROLOG_END_TAG
+ROOTPATH = ../../../../..
+
+MODULE = mc_config
+
+## support for Targeting and fapi
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/fapi
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/plat
+EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp
+
+## pointer to common HWP files
+EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/include
+
+## Include sub dirs
+## NOTE: add a new EXTRAINCDIR when you add a new HWP
+##@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/???
+EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_eff_config
+EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_volt
+EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_freq
+
+OBJS = mc_config.o \
+ mss_volt.o \
+ mss_freq.o \
+ mss_eff_config.o \
+ mss_eff_config_thermal.o \
+ mss_eff_config_termination.o \
+ mss_eff_config_rank_group.o
+
+## NOTE: add a new directory onto the vpaths when you add a new HWP
+##@ VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/???
+VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_eff_config
+VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_volt
+VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_freq
+
+
+include ${ROOTPATH}/config.mk
diff --git a/src/usr/hwpf/hwp/mc_config/mc_config.C b/src/usr/hwpf/hwp/mc_config/mc_config.C
new file mode 100644
index 000000000..04387718e
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mc_config.C
@@ -0,0 +1,306 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/mc_config/mc_config.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+/**
+ * @file mc_config.C
+ *
+ * Support file for IStep: mc_config
+ * Step 12 MC Config
+ *
+ * *****************************************************************
+ * THIS FILE WAS GENERATED ON 2012-03-01:1032
+ * *****************************************************************
+ *
+ */
+
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <stdint.h>
+
+#include <trace/interface.H>
+#include <initservice/taskargs.H>
+#include <errl/errlentry.H>
+
+#include <initservice/isteps_trace.H>
+
+// targeting support
+#include <targeting/common/commontargeting.H>
+#include <targeting/common/utilFilter.H>
+
+// fapi support
+#include <fapi.H>
+#include <fapiPlatHwpInvoker.H>
+
+
+// -- prototype includes --
+// Add any customized routines that you don't want overwritten into
+// "mc_config_custom.C" and include the prototypes here.
+// #include "mc_config_custom.H"
+
+#include "mc_config.H"
+
+// Uncomment these files as they become available:
+// #include "host_collect_dimm_spd/host_collect_dimm_spd.H"
+#include "mss_volt/mss_volt.H"
+#include "mss_freq/mss_freq.H"
+#include "mss_eff_config/mss_eff_config.H"
+
+namespace MC_CONFIG
+{
+
+using namespace TARGETING;
+using namespace fapi;
+
+
+
+//
+// Wrapper function to call 12.1 : host_collect_dimm_spd
+//
+void call_host_collect_dimm_spd( void *io_pArgs )
+{
+ errlHndl_t l_err = NULL;
+
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_collect_dimm_spd entry" );
+
+#if 0
+ // @@@@@ CUSTOM BLOCK: @@@@@
+ // figure out what targets we need
+ // customize any other inputs
+ // set up loops to go through all targets (if parallel, spin off a task)
+
+ // print call to hwp and dump physical path of the target(s)
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "===== host_collect_dimm_spd HWP(? ? ? )",
+ ?
+ ?
+ ? );
+ // dump physical path to targets
+ EntityPath l_path;
+ l_path = l_@targetN_target->getAttr<ATTR_PHYS_PATH>();
+ l_path.dump();
+
+ // cast OUR type of target to a FAPI type of target.
+ const fapi::Target l_fapi_@targetN_target(
+ TARGET_TYPE_MEMBUF_CHIP,
+ reinterpret_cast<void *>
+ (const_cast<TARGETING::Target*>(l_@targetN_target)) );
+
+ // call the HWP with each fapi::Target
+ l_fapirc = host_collect_dimm_spd( ? , ?, ? );
+
+ // process return code.
+ if ( l_fapirc== fapi::FAPI_RC_SUCCESS )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : host_collect_dimm_spd HWP(? ? ? )" );
+ }
+ else
+ {
+ /**
+ * @todo fapi error - just print out for now...
+ */
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: host_collect_dimm_spd HWP(? ? ?) ",
+ static_cast<uint32_t>(l_fapirc) );
+ }
+ // @@@@@ END CUSTOM BLOCK: @@@@@
+#endif
+
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_collect_dimm_spd exit" );
+
+ task_end2( l_err );
+}
+
+
+
+//
+// Wrapper function to call 12.2 : mss_volt
+//
+void call_mss_volt( void *io_pArgs )
+{
+ errlHndl_t l_err = NULL;
+
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_volt entry" );
+
+ TARGETING::TargetHandleList l_membufTargetList;
+ getAllChips(l_membufTargetList, TYPE_MEMBUF);
+
+ // declare a vector of fapi targets to pass to mss_volt
+ std::vector<fapi::Target> l_membufFapiTargets;
+
+ // fill in the vector
+ for ( size_t i = 0; i < l_membufTargetList.size(); i++ )
+ {
+ // make a local copy of the target for ease of use
+ const TARGETING::Target* l_membuf_target = l_membufTargetList[i];
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "===== add to fapi::Target vector..." );
+ EntityPath l_path;
+ l_path = l_membuf_target->getAttr<ATTR_PHYS_PATH>();
+ l_path.dump();
+
+ fapi::Target l_membuf_fapi_target(
+ TARGET_TYPE_MEMBUF_CHIP,
+ reinterpret_cast<void *>
+ (const_cast<TARGETING::Target*>(l_membuf_target)) );
+
+ l_membufFapiTargets.push_back( l_membuf_fapi_target );
+
+ } // endfor
+
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "===== mss_volt HWP( vector )" );
+ // call the HWP with each target ( if parallel, spin off a task )
+ FAPI_INVOKE_HWP(l_err, mss_volt, l_membufFapiTargets);
+
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: mss_volt HWP( ) ", l_err->reasonCode());
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : mss_volt HWP( )" );
+ }
+
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_volt exit" );
+
+ task_end2( l_err );
+}
+
+//
+// Wrapper function to call 12.3 : mss_freq
+//
+void call_mss_freq( void *io_pArgs )
+{
+ errlHndl_t l_err = NULL;
+
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_freq entry" );
+
+ TARGETING::TargetHandleList l_membufTargetList;
+ getAllChips(l_membufTargetList, TYPE_MEMBUF);
+
+ for ( size_t i = 0; i < l_membufTargetList.size(); i++ )
+ {
+ // make a local copy of the target for ease of use
+ const TARGETING::Target* l_membuf_target = l_membufTargetList[i];
+
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "===== mss_freq HWP( %d )", i );
+ EntityPath l_path;
+ l_path = l_membuf_target->getAttr<ATTR_PHYS_PATH>();
+ l_path.dump();
+
+ // call the HWP with each target ( if parallel, spin off a task )
+ // $$const fapi::Target l_fapi_membuf_target(
+ fapi::Target l_fapi_membuf_target(
+ TARGET_TYPE_MEMBUF_CHIP,
+ reinterpret_cast<void *>
+ (const_cast<TARGETING::Target*>(l_membuf_target)) );
+
+ FAPI_INVOKE_HWP(l_err, mss_freq, l_fapi_membuf_target);
+
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: mss_freq HWP( %d ) ",
+ l_err->reasonCode(),
+ i );
+ break; // break out memBuf loop
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : mss_freq HWP( %d )", i );
+ }
+ } // End memBuf loop
+
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_freq exit" );
+
+ task_end2( NULL );
+}
+
+//
+// Wrapper function to call 12.4 : mss_eff_config
+//
+void call_mss_eff_config( void *io_pArgs )
+{
+ errlHndl_t l_err = NULL;
+
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_eff_config entry" );
+
+ TARGETING::TargetHandleList l_mbaTargetList;
+ getAllChiplets(l_mbaTargetList, TYPE_MBA);
+
+ for ( size_t i = 0; i < l_mbaTargetList.size(); i++ )
+ {
+ // make a local copy of the target for ease of use
+ const TARGETING::Target* l_mba_target = l_mbaTargetList[i];
+
+ // print call to hwp and dump physical path of the target(s)
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "===== mss_eff_config HWP( mba %d )", i );
+ // dump physical path to targets
+ EntityPath l_path;
+ l_path = l_mba_target->getAttr<ATTR_PHYS_PATH>();
+ l_path.dump();
+
+
+ // cast OUR type of target to a FAPI type of target.
+ const fapi::Target l_fapi_mba_target(
+ TARGET_TYPE_MBA_CHIPLET,
+ reinterpret_cast<void *>
+ (const_cast<TARGETING::Target*>(l_mba_target)) );
+
+ // call the HWP with each fapi::Target
+ FAPI_INVOKE_HWP(l_err, mss_eff_config, l_fapi_mba_target);
+
+ // process return code.
+ if ( l_err )
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "ERROR 0x%.8X: mss_eff_config HWP( mba %d ) ",
+ l_err->reasonCode(), i );
+ break; // break out mba loop
+ }
+ else
+ {
+ TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
+ "SUCCESS : mss_eff_config HWP( mba %d )", i );
+ }
+ } // endfor
+
+
+ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_eff_config exit" );
+
+ task_end2( NULL );
+}
+
+
+}; // end namespace
diff --git a/src/usr/hwpf/hwp/mc_config/mc_config.H b/src/usr/hwpf/hwp/mc_config/mc_config.H
new file mode 100644
index 000000000..0f58a844f
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mc_config.H
@@ -0,0 +1,140 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/mc_config/mc_config.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+#ifndef __MC_CONFIG_MC_CONFIG_H
+#define __MC_CONFIG_MC_CONFIG_H
+
+/**
+ * @file mc_config.H
+ *
+ * Step 12 MC Config
+ *
+ * All of the following routines are "named isteps" - they are invoked as
+ * tasks by the @ref IStepDispatcher.
+ *
+ * *****************************************************************
+ * THIS FILE WAS GENERATED ON 2012-03-01:1032
+ * *****************************************************************
+ *
+ */
+
+/* @tag isteplist
+ * @docversion v1.08 (08/13/12)
+ * @istepname mc_config
+ * @istepnum 12
+ * @istepdesc Step 12 MC Config
+ *
+ * @{
+ * @substepnum 1
+ * @substepname host_collect_dimm_spd
+ * @substepdesc : Collect Master dimm SPD
+ * @target_sched serial
+ * @}
+ * @{
+ * @substepnum 2
+ * @substepname mss_volt
+ * @substepdesc : Calc dimm voltage
+ * @target_sched serial
+ * @}
+ * @{
+ * @substepnum 3
+ * @substepname mss_freq
+ * @substepdesc : Calc dimm frequency
+ * @target_sched serial
+ * @}
+ * @{
+ * @substepnum 4
+ * @substepname mss_eff_config
+ * @substepdesc : Determine effective config
+ * @target_sched serial
+ * @}
+ */
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <stdint.h>
+
+namespace MC_CONFIG
+{
+
+
+
+/**
+ * @brief host_collect_dimm_spd
+ *
+ * 12.1 : : Collect Master dimm SPD
+ *
+ * param[in,out] io_pArgs - (normally) a pointer to a TaskArgs struct,
+ * or NULL.
+ * return none
+ *
+ */
+void call_host_collect_dimm_spd( void * io_pArgs );
+
+
+
+/**
+ * @brief mss_volt
+ *
+ * 12.2 : : Calc dimm voltage
+ *
+ * param[in,out] io_pArgs - (normally) a pointer to a TaskArgs struct,
+ * or NULL.
+ * return none
+ *
+ */
+void call_mss_volt( void * io_pArgs );
+
+
+
+/**
+ * @brief mss_freq
+ *
+ * 12.3 : : Calc dimm frequency
+ *
+ * param[in,out] io_pArgs - (normally) a pointer to a TaskArgs struct,
+ * or NULL.
+ * return none
+ *
+ */
+void call_mss_freq( void * io_pArgs );
+
+
+
+/**
+ * @brief mss_eff_config
+ *
+ * 12.4 : : Determine effective config
+ *
+ * param[in,out] io_pArgs - (normally) a pointer to a TaskArgs struct,
+ * or NULL.
+ * return none
+ *
+ */
+void call_mss_eff_config( void * io_pArgs );
+
+
+}; // end namespace
+
+#endif
+
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config.C b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config.C
new file mode 100644
index 000000000..53f5723ce
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config.C
@@ -0,0 +1,690 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/mc_init/mss_eff_config/mss_eff_config.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: mss_eff_config.C,v 1.9 2012/06/07 01:16:03 asaetow Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_eff_config.C,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_eff_config
+// *! DESCRIPTION : see additional comments below
+// *! OWNER NAME : Anuwat Saetow Email: asaetow@us.ibm.com
+// *! BACKUP NAME : Mark Bellows Email: bellows@us.ibm.com
+// *! ADDITIONAL COMMENTS :
+//
+// The purpose of this procedure is to setup attributes used in other mss procedures.
+//
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.10 | | |
+// 1.9 | asaetow |29-MAY-12| Added divide by 0 check for mss_freq.
+// | | | Added 9 new attributes from memory_attributes.xml v1.23
+// | | | Changed plug_config to my_attr_eff_num_drops_per_port.
+// | | | NOTE: DO NOT pick-up without memory_attributes.xml v1.23 or newer.
+// | | | NOTE: Some hard code still in place awaiting SPD attributes bytes[76:68,33,8].
+// 1.8 | asaetow |04-MAY-12| Fixed my_attr_eff_dimm_size calcualtion and use new ATTR_EFF_DRAM_WIDTH enum from memory_attributes.xml v1.22
+// | | | NOTE: DO NOT pick-up without memory_attributes.xml v1.22 or newer.
+// 1.7 | asaetow |04-MAY-12| Removed calc_u8_timing_in_clk().
+// | | | Changed calc_u32_timing_in_clk() to calc_timing_in_clk() and changed params.
+// | | | Removed currently unused vars.
+// 1.6 | asaetow |03-MAY-12| Removed FAPI_ATTR_SET(ATTR_EFF_DRAM_CL), moved to mss_freq.C.
+// | | | Fixed "suggest parentheses around && within ||", per Mike Jones.
+// | | | Changed tCK_in_ps calc to reduce num of operations.
+// 1.5 | asaetow |02-MAY-12| Removed #include <*.C>, per FW.
+// | | | Added #include <mss_eff_config_thermal.H>
+// | | | Added call to sub-procedure mss_eff_config_thermal().
+// 1.4 | asaetow |30-APR-12| Changed procedure to use SPD attributes.
+// | | | Added calls to sub-procedures mss_eff_config_rank_group() and mss_eff_config_termination().
+// 1.3 | asaetow |18-APR-12| Changed procedure to print use mss_eff_config_sim.C until 30APR2012.
+// 1.2 | asaetow |03-NOV-11| Fixed to comply with mss_eff_config.H.
+// | | | Added calls to mss_eff_config_rank_group() and mss_eff_config_thermal().
+// 1.1 | asaetow |01-NOV-11| First Draft.
+
+
+
+//----------------------------------------------------------------------
+// My Includes
+//----------------------------------------------------------------------
+#include <mss_eff_config.H>
+#include <mss_eff_config_rank_group.H>
+#include <mss_eff_config_termination.H>
+#include <mss_eff_config_thermal.H>
+
+
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <fapi.H>
+
+
+
+//----------------------------------------------------------------------
+// ENUMs
+//----------------------------------------------------------------------
+enum {
+ EMPTY = 0,
+ VALID = 255,
+};
+
+
+
+extern "C" {
+
+
+
+//******************************************************************************
+//* name=calc_timing_in_clk, param=my_tCK_in_ps,my_mtb_in_ps,my_ftb_in_fs,my_unit,my_offset, return=my_timing_in_clk
+//******************************************************************************
+uint32_t calc_timing_in_clk(uint32_t my_tCK_in_ps, uint32_t my_mtb_in_ps, uint32_t my_ftb_in_fs, uint32_t my_unit, uint8_t my_offset) {
+
+ uint64_t my_timing = (my_unit * my_mtb_in_ps) + (my_offset * my_ftb_in_fs);
+ // ceiling()
+ uint32_t my_timing_in_clk = my_timing / my_tCK_in_ps;
+ if ((my_timing_in_clk * my_tCK_in_ps) < my_timing) {
+ my_timing_in_clk += 1;
+ }
+ // DEBUG HERE:
+ //FAPI_INF("calc_timing_in_clk: my_timing_in_clk = %d, my_tCK_in_ps = %d, my_mtb_in_ps = %d, my_ftb_in_fs = %d, my_unit = %d, my_offset = %d", my_timing_in_clk, my_tCK_in_ps, my_mtb_in_ps, my_ftb_in_fs, my_unit, my_offset );
+
+ return my_timing_in_clk;
+}
+
+
+
+//******************************************************************************
+//* name=mss_eff_config, param=i_target_mba, return=ReturnCode
+//******************************************************************************
+fapi::ReturnCode mss_eff_config(const fapi::Target i_target_mba) {
+ fapi::ReturnCode rc = fapi::FAPI_RC_SUCCESS;
+ const char * const PROCEDURE_NAME = "mss_eff_config";
+ FAPI_INF("*** Running %s on %s ... ***", PROCEDURE_NAME, i_target_mba.toEcmdString());
+
+ // Define attribute array size
+ const uint8_t PORT_SIZE = 2;
+ const uint8_t DIMM_SIZE = 2;
+
+ // Define spd attribute array size
+ // HERE const uint8_t SPD_ATTR_SIZE_18 = 18;
+ // HERE const uint8_t SPD_ATTR_SIZE_57 = 57;
+ // HERE const uint8_t SPD_ATTR_SIZE_80 = 80;
+
+ // Define local variables
+ uint8_t cur_dimm_spd_valid_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t cur_mba_port = 0;
+ uint8_t cur_mba_dimm = 0;
+ uint8_t cur_dram_density = 0;
+ uint32_t mss_freq = 0;
+ uint32_t mss_volt = 0;
+ uint32_t tCK_in_ps= 0;
+ uint32_t mtb_in_ps_u32array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint32_t ftb_in_fs_u32array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ //uint8_t my_dram_taa = 0;
+ uint32_t my_dram_tfaw = 0;
+ uint32_t my_dram_tras = 0;
+ uint32_t my_dram_trc = 0;
+ uint8_t my_dram_trcd = 0;
+ uint32_t my_dram_trfc = 0;
+ uint8_t my_dram_trp = 0;
+ uint8_t my_dram_trrd = 0;
+ uint8_t my_dram_trtp = 0;
+ uint8_t my_dram_twtr = 0;
+ uint8_t my_dram_wr = 0;
+
+ // Define local attribute variables
+ uint8_t my_attr_eff_dimm_ranks_configed[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint64_t my_attr_eff_dimm_rcd_cntl_word_0_15[PORT_SIZE][DIMM_SIZE] = {{0}}; // AST HERE: Needs SPD byte68:76
+ uint8_t my_attr_eff_dimm_size[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t my_attr_eff_dimm_type = 0;
+ uint8_t my_attr_eff_dram_al = 1;
+ uint8_t my_attr_eff_dram_asr = 0;
+ uint8_t my_attr_eff_dram_bl = 0;
+ uint8_t my_attr_eff_dram_banks = 0;
+ // See mss_freq.C
+ //uint8_t my_attr_eff_dram_cl = 0;
+ uint8_t my_attr_eff_dram_cols = 0;
+ uint8_t my_attr_eff_dram_cwl = 0;
+ uint8_t my_attr_eff_dram_density = 0;
+ uint8_t my_attr_eff_dram_dll_enable = 0;
+ uint8_t my_attr_eff_dram_dll_ppd = 0;
+ uint8_t my_attr_eff_dram_dll_reset = 1;
+ uint8_t my_attr_eff_dram_gen = 0;
+ uint8_t my_attr_eff_dram_output_buffer = 0;
+ uint8_t my_attr_eff_dram_pasr = 0;
+ uint8_t my_attr_eff_dram_rbt = 0;
+ uint8_t my_attr_eff_dram_rows = 0;
+ uint8_t my_attr_eff_dram_srt = 1;
+ uint8_t my_attr_eff_dram_tdqs = 0;
+ uint8_t my_attr_eff_dram_tfaw = 0;
+ uint32_t my_attr_eff_dram_tfaw_u32 = 0;
+ uint8_t my_attr_eff_dram_tm = 0;
+ uint8_t my_attr_eff_dram_tras = 0;
+ uint32_t my_attr_eff_dram_tras_u32 = 0;
+ uint8_t my_attr_eff_dram_trc = 0;
+ uint32_t my_attr_eff_dram_trc_u32 = 0;
+ uint8_t my_attr_eff_dram_trcd = 0;
+ uint32_t my_attr_eff_dram_trfc = 0;
+ uint32_t my_attr_eff_dram_trfi = 0;
+ uint8_t my_attr_eff_dram_trp = 0;
+ uint8_t my_attr_eff_dram_trrd = 0;
+ uint8_t my_attr_eff_dram_trtp = 0;
+ uint8_t my_attr_eff_dram_twtr = 0;
+ uint8_t my_attr_eff_dram_width = 0;
+ uint8_t my_attr_eff_dram_wr = 0;
+ uint8_t my_attr_eff_dram_wr_lvl_enable = 0;
+
+ // AST HERE: Needs SPD byte33[7,1:0], currently hard coded to TYPE_1B
+ uint8_t my_attr_eff_ibm_type[PORT_SIZE][DIMM_SIZE] = {{2,2},{2,2}};
+
+ uint32_t my_attr_eff_memcal_interval = 0;
+ uint8_t my_attr_eff_mpr_loc = 0x0;
+ uint8_t my_attr_eff_mpr_mode = 0;
+
+ // AST HERE: Needs SPD byte33[6:4], currently hard coded to 0
+ uint8_t my_attr_eff_num_dies_per_package[PORT_SIZE][DIMM_SIZE] = {{0}};
+
+ uint8_t my_attr_eff_num_drops_per_port = 0;
+ uint8_t my_attr_eff_num_master_ranks_per_dimm[PORT_SIZE][DIMM_SIZE] = {{0}};
+
+ // AST HERE: Needs source data, currently hard coded to 0
+ uint8_t my_attr_eff_num_packages_per_rank[PORT_SIZE][DIMM_SIZE] = {{0}};
+
+ uint8_t my_attr_eff_num_ranks_per_dimm[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t my_attr_eff_schmoo_mode = 0;
+ uint8_t my_attr_eff_schmoo_param_valid = 0x0;
+ uint8_t my_attr_eff_schmoo_test_valid = 0x0;
+
+ // AST HERE: Needs SPD byte33[7,1:0], currently hard coded to 1
+ uint8_t my_attr_eff_stack_type[PORT_SIZE][DIMM_SIZE] = {{1,1},{1,1}};
+
+ uint32_t my_attr_eff_zqcal_interval = 0;
+
+ // Define local spd attribute variables
+ uint8_t spd_dram_device_type_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_module_type_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_sdram_banks_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_sdram_density_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_sdram_rows_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_sdram_columns_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ //uint8_t spd_module_nominal_voltage_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_num_ranks_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_dram_width_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_module_memory_bus_width_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_ftb_dividend_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_ftb_divisor_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_mtb_dividend_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_mtb_divisor_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ //uint8_t spd_tckmin_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ //uint32_t spd_cas_latencies_supported_u32array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ //uint8_t spd_taamin_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_twrmin_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_trcdmin_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_trrdmin_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_trpmin_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint32_t spd_trasmin_u32array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint32_t spd_trcmin_u32array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint32_t spd_trfcmin_u32array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_twtrmin_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_trtpmin_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint32_t spd_tfawmin_u32array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ //uint8_t spd_sdram_optional_features_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ //uint8_t spd_sdram_thermal_and_refresh_options_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ //uint8_t spd_module_thermal_sensor_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_fine_offset_tckmin_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_fine_offset_taamin_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_fine_offset_trcdmin_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_fine_offset_trpmin_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t spd_fine_offset_trcmin_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ // HERE uint8_t spd_module_specific_section_u8array[PORT_SIZE][DIMM_SIZE][SPD_ATTR_SIZE_57] = {{{0}}};
+ //uint32_t spd_module_id_module_manufacturers_jedec_id_code_u32array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ //uint8_t spd_module_id_module_manufacturing_location_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ //uint32_t spd_module_id_module_manufacturing_date_u32array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ //uint32_t spd_module_id_module_serial_number_u32array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ //uint32_t spd_cyclical_redundancy_code_u32array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ // HERE uint8_t spd_module_part_number_u8array[PORT_SIZE][DIMM_SIZE][SPD_ATTR_SIZE_18] = {{{0}}};
+ //uint32_t spd_module_revision_code_u32array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ //uint32_t spd_dram_manufacturer_jedec_id_code_u32array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ // HERE uint8_t spd_bad_dq_data_u8array[PORT_SIZE][DIMM_SIZE][SPD_ATTR_SIZE_80] = {{{0}}};
+
+
+ // Grab freq/volt data.
+ fapi::Target l_target_centaur;
+ rc = fapiGetParentChip(i_target_mba, l_target_centaur); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MSS_FREQ, &l_target_centaur, mss_freq); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MSS_VOLT, &l_target_centaur, mss_volt); if(rc) return rc;
+ if (mss_freq <= 0) {
+ FAPI_ERR("Invalid ATTR_MSS_FREQ = %d on %s!", mss_freq, i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ tCK_in_ps = 2000000/mss_freq;
+ FAPI_INF("mss_freq = %d, tCK_in_ps= %d on %s.", mss_freq, tCK_in_ps, l_target_centaur.toEcmdString());
+ FAPI_INF("mss_volt = %d on %s.", mss_volt, l_target_centaur.toEcmdString());
+
+
+ // Grab all DIMM/SPD data.
+ std::vector<fapi::Target> l_target_dimm_array;
+ rc = fapiGetAssociatedDimms(i_target_mba, l_target_dimm_array); if(rc) return rc;
+ for (uint8_t dimm_index = 0; dimm_index < l_target_dimm_array.size(); dimm_index += 1) {
+
+ rc = FAPI_ATTR_GET(ATTR_MBA_PORT, &l_target_dimm_array[dimm_index], cur_mba_port); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MBA_DIMM, &l_target_dimm_array[dimm_index], cur_mba_dimm); if(rc) return rc;
+ cur_dimm_spd_valid_u8array[cur_mba_port][cur_mba_dimm] = VALID;
+
+ rc = FAPI_ATTR_GET(ATTR_SPD_DRAM_DEVICE_TYPE, &l_target_dimm_array[dimm_index], spd_dram_device_type_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_TYPE, &l_target_dimm_array[dimm_index], spd_module_type_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_SDRAM_BANKS, &l_target_dimm_array[dimm_index], spd_sdram_banks_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_SDRAM_DENSITY, &l_target_dimm_array[dimm_index], spd_sdram_density_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_SDRAM_ROWS, &l_target_dimm_array[dimm_index], spd_sdram_rows_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_SDRAM_COLUMNS, &l_target_dimm_array[dimm_index], spd_sdram_columns_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ //rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_NOMINAL_VOLTAGE, &l_target_dimm_array[dimm_index], spd_module_nominal_voltage_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_NUM_RANKS, &l_target_dimm_array[dimm_index], spd_num_ranks_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_DRAM_WIDTH, &l_target_dimm_array[dimm_index], spd_dram_width_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_MEMORY_BUS_WIDTH, &l_target_dimm_array[dimm_index], spd_module_memory_bus_width_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_FTB_DIVIDEND, &l_target_dimm_array[dimm_index], spd_ftb_dividend_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_FTB_DIVISOR, &l_target_dimm_array[dimm_index], spd_ftb_divisor_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_MTB_DIVIDEND, &l_target_dimm_array[dimm_index], spd_mtb_dividend_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_MTB_DIVISOR, &l_target_dimm_array[dimm_index], spd_mtb_divisor_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ //rc = FAPI_ATTR_GET(ATTR_SPD_TCKMIN, &l_target_dimm_array[dimm_index], spd_tckmin_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ //rc = FAPI_ATTR_GET(ATTR_SPD_CAS_LATENCIES_SUPPORTED, &l_target_dimm_array[dimm_index], spd_cas_latencies_supported_u32array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ //rc = FAPI_ATTR_GET(ATTR_SPD_TAAMIN, &l_target_dimm_array[dimm_index], spd_taamin_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_TWRMIN, &l_target_dimm_array[dimm_index], spd_twrmin_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_TRCDMIN, &l_target_dimm_array[dimm_index], spd_trcdmin_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_TRRDMIN, &l_target_dimm_array[dimm_index], spd_trrdmin_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_TRPMIN, &l_target_dimm_array[dimm_index], spd_trpmin_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_TRASMIN, &l_target_dimm_array[dimm_index], spd_trasmin_u32array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_TRCMIN, &l_target_dimm_array[dimm_index], spd_trcmin_u32array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_TRFCMIN, &l_target_dimm_array[dimm_index], spd_trfcmin_u32array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_TWTRMIN, &l_target_dimm_array[dimm_index], spd_twtrmin_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_TRTPMIN, &l_target_dimm_array[dimm_index], spd_trtpmin_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_TFAWMIN, &l_target_dimm_array[dimm_index], spd_tfawmin_u32array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ //rc = FAPI_ATTR_GET(ATTR_SPD_SDRAM_OPTIONAL_FEATURES, &l_target_dimm_array[dimm_index], spd_sdram_optional_features_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ //rc = FAPI_ATTR_GET(ATTR_SPD_SDRAM_THERMAL_AND_REFRESH_OPTIONS, &l_target_dimm_array[dimm_index], spd_sdram_thermal_and_refresh_options_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ //rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_THERMAL_SENSOR, &l_target_dimm_array[dimm_index], spd_module_thermal_sensor_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_FINE_OFFSET_TCKMIN, &l_target_dimm_array[dimm_index], spd_fine_offset_tckmin_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_FINE_OFFSET_TAAMIN, &l_target_dimm_array[dimm_index], spd_fine_offset_taamin_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_FINE_OFFSET_TRCDMIN, &l_target_dimm_array[dimm_index], spd_fine_offset_trcdmin_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_FINE_OFFSET_TRPMIN, &l_target_dimm_array[dimm_index], spd_fine_offset_trpmin_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_FINE_OFFSET_TRCMIN, &l_target_dimm_array[dimm_index], spd_fine_offset_trcmin_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ // HERE rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_SPECIFIC_SECTION, &l_target_dimm_array[dimm_index], spd_module_specific_section_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ //rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_ID_MODULE_MANUFACTURERS_JEDEC_ID_CODE, &l_target_dimm_array[dimm_index], spd_module_id_module_manufacturers_jedec_id_code_u32array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ //rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_ID_MODULE_MANUFACTURING_LOCATION, &l_target_dimm_array[dimm_index], spd_module_id_module_manufacturing_location_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ //rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_ID_MODULE_MANUFACTURING_DATE, &l_target_dimm_array[dimm_index], spd_module_id_module_manufacturing_date_u32array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ //rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_ID_MODULE_SERIAL_NUMBER, &l_target_dimm_array[dimm_index], spd_module_id_module_serial_number_u32array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ //rc = FAPI_ATTR_GET(ATTR_SPD_CYCLICAL_REDUNDANCY_CODE, &l_target_dimm_array[dimm_index], spd_cyclical_redundancy_code_u32array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ // HERE rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_PART_NUMBER, &l_target_dimm_array[dimm_index], spd_module_part_number_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ //rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_REVISION_CODE, &l_target_dimm_array[dimm_index], spd_module_revision_code_u32array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ //rc = FAPI_ATTR_GET(ATTR_SPD_DRAM_MANUFACTURER_JEDEC_ID_CODE, &l_target_dimm_array[dimm_index], spd_dram_manufacturer_jedec_id_code_u32array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ // HERE rc = FAPI_ATTR_GET(ATTR_SPD_BAD_DQ_DATA, &l_target_dimm_array[dimm_index], spd_bad_dq_data_u8array[cur_mba_port][cur_mba_dimm]); if(rc) return rc;
+ }
+
+
+ // Identify/Verify DIMM plug rule
+ if ((cur_dimm_spd_valid_u8array[0][0] == EMPTY) && ((cur_dimm_spd_valid_u8array[0][1] == VALID) || (cur_dimm_spd_valid_u8array[1][0] == VALID) || (cur_dimm_spd_valid_u8array[1][1] == VALID))) {
+ FAPI_ERR("Plug rule violation on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if (((cur_dimm_spd_valid_u8array[0][0] == VALID) && (cur_dimm_spd_valid_u8array[1][0] == EMPTY)) || ((cur_dimm_spd_valid_u8array[0][1] == VALID) && (cur_dimm_spd_valid_u8array[1][1] == EMPTY))) {
+ FAPI_ERR("Plug rule violation on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if ((cur_dimm_spd_valid_u8array[0][0] == VALID) && (cur_dimm_spd_valid_u8array[0][1] == VALID)) {
+ my_attr_eff_num_drops_per_port = fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL;
+ } else if ((cur_dimm_spd_valid_u8array[0][0] == VALID) && (cur_dimm_spd_valid_u8array[0][1] == EMPTY)) {
+ my_attr_eff_num_drops_per_port = fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_SINGLE;
+ } else {
+ my_attr_eff_num_drops_per_port = fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_EMPTY;
+ }
+
+
+ // Start Identify/Verify/Assigning values to attributes
+ if (my_attr_eff_num_drops_per_port != fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_EMPTY) {
+
+ // Identify/Verify DIMM compatability
+ if ((spd_dram_device_type_u8array[0][0] != spd_dram_device_type_u8array[1][0]) || ((my_attr_eff_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL) && ((spd_dram_device_type_u8array[0][1] != spd_dram_device_type_u8array[1][1]) || (spd_dram_device_type_u8array[0][0] != spd_dram_device_type_u8array[0][1])))) {
+ FAPI_ERR("Incompatable DRAM generation on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if ((spd_module_type_u8array[0][0] != spd_module_type_u8array[1][0]) || ((my_attr_eff_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL) && ((spd_module_type_u8array[0][1] != spd_module_type_u8array[1][1]) || (spd_module_type_u8array[0][0] != spd_module_type_u8array[0][1])))) {
+ FAPI_ERR("Incompatable DIMM type on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if ((spd_num_ranks_u8array[0][0] != spd_num_ranks_u8array[1][0]) || ((my_attr_eff_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL) && ((spd_num_ranks_u8array[0][1] != spd_num_ranks_u8array[1][1]) || (spd_num_ranks_u8array[0][0] != spd_num_ranks_u8array[0][1])))) {
+ FAPI_ERR("Incompatable DIMM ranks on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if ((spd_sdram_banks_u8array[0][0] != spd_sdram_banks_u8array[1][0]) || ((my_attr_eff_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL) && ((spd_sdram_banks_u8array[0][1] != spd_sdram_banks_u8array[1][1]) || (spd_sdram_banks_u8array[0][0] != spd_sdram_banks_u8array[0][1])))) {
+ FAPI_ERR("Incompatable DIMM banks on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if ((spd_sdram_rows_u8array[0][0] != spd_sdram_rows_u8array[1][0]) || ((my_attr_eff_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL) && ((spd_sdram_rows_u8array[0][1] != spd_sdram_rows_u8array[1][1]) || (spd_sdram_rows_u8array[0][0] != spd_sdram_rows_u8array[0][1])))) {
+ FAPI_ERR("Incompatable DIMM rows on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if ((spd_sdram_columns_u8array[0][0] != spd_sdram_columns_u8array[1][0]) || ((my_attr_eff_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL) && ((spd_sdram_columns_u8array[0][1] != spd_sdram_columns_u8array[1][1]) || (spd_sdram_columns_u8array[0][0] != spd_sdram_columns_u8array[0][1])))) {
+ FAPI_ERR("Incompatable DIMM cols on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if ((spd_module_memory_bus_width_u8array[0][0] != spd_module_memory_bus_width_u8array[1][0]) || ((my_attr_eff_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL) && ((spd_module_memory_bus_width_u8array[0][1] != spd_module_memory_bus_width_u8array[1][1]) || (spd_module_memory_bus_width_u8array[0][0] != spd_module_memory_bus_width_u8array[0][1])))) {
+ FAPI_ERR("Incompatable DRAM primary bus width on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ /* AST HERE: Needs SPD byte8[4:3]
+ if ((spd_module_memory_bus_width_extension_u8array[0][0] != spd_module_memory_bus_width_extension_u8array[1][0]) || ((my_attr_eff_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL) && ((spd_module_memory_bus_width_extension_u8array[0][1] != spd_module_memory_bus_width_extension_u8array[1][1])) || ((spd_module_memory_bus_width_extension_u8array[0][0] != spd_module_memory_bus_width_extension_u8array[0][1])))) {
+ FAPI_ERR("Incompatable DRAM bus width extension on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if ((spd_module_memory_bus_width_u8array[0][0] != fapi::ENUM_ATTR_SPD_MODULE_MEMORY_BUS_WIDTH_W64) || (spd_module_memory_bus_width_extension_u8array[0][0] != fapi::ENUM_ATTR_SPD_MODULE_MEMORY_BUS_WIDTH_EXTENSION_W8)) {
+ FAPI_ERR("Unsupported DRAM bus width on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ */
+ if ((spd_dram_width_u8array[0][0] != spd_dram_width_u8array[1][0]) || ((my_attr_eff_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL) && ((spd_dram_width_u8array[0][1] != spd_dram_width_u8array[1][1]) || (spd_dram_width_u8array[0][0] != spd_dram_width_u8array[0][1])))) {
+ FAPI_ERR("Incompatable DRAM width on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+
+ // Assigning values to attributes
+ if (spd_dram_device_type_u8array[0][0] == fapi::ENUM_ATTR_SPD_DRAM_DEVICE_TYPE_DDR3) {
+ my_attr_eff_dram_gen = fapi::ENUM_ATTR_EFF_DRAM_GEN_DDR3;
+ } else if (spd_dram_device_type_u8array[0][0] == fapi::ENUM_ATTR_SPD_DRAM_DEVICE_TYPE_DDR4) {
+ my_attr_eff_dram_gen = fapi::ENUM_ATTR_EFF_DRAM_GEN_DDR4;
+ } else {
+ FAPI_ERR("Unknown DRAM type on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if (spd_module_type_u8array[0][0] == fapi::ENUM_ATTR_SPD_MODULE_TYPE_CDIMM) {
+ my_attr_eff_dimm_type = fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM;
+ } else if (spd_module_type_u8array[0][0] == fapi::ENUM_ATTR_SPD_MODULE_TYPE_RDIMM) {
+ my_attr_eff_dimm_type = fapi::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM;
+ } else if (spd_module_type_u8array[0][0] == fapi::ENUM_ATTR_SPD_MODULE_TYPE_UDIMM) {
+ my_attr_eff_dimm_type = fapi::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM;
+ } else if (spd_module_type_u8array[0][0] == fapi::ENUM_ATTR_SPD_MODULE_TYPE_LRDIMM) {
+ my_attr_eff_dimm_type = fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM;
+ } else {
+ FAPI_ERR("Unknown DIMM type on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if (spd_sdram_banks_u8array[0][0] == fapi::ENUM_ATTR_SPD_SDRAM_BANKS_B8) {
+ my_attr_eff_dram_banks = 8;
+ } else if (spd_sdram_banks_u8array[0][0] == fapi::ENUM_ATTR_SPD_SDRAM_BANKS_B16) {
+ my_attr_eff_dram_banks = 16;
+ } else if (spd_sdram_banks_u8array[0][0] == fapi::ENUM_ATTR_SPD_SDRAM_BANKS_B32) {
+ my_attr_eff_dram_banks = 32;
+ } else if (spd_sdram_banks_u8array[0][0] == fapi::ENUM_ATTR_SPD_SDRAM_BANKS_B64) {
+ my_attr_eff_dram_banks = 64;
+ } else {
+ FAPI_ERR("Unknown DRAM banks on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if (spd_sdram_rows_u8array[0][0] == fapi::ENUM_ATTR_SPD_SDRAM_ROWS_R12) {
+ my_attr_eff_dram_rows = 12;
+ } else if (spd_sdram_rows_u8array[0][0] == fapi::ENUM_ATTR_SPD_SDRAM_ROWS_R13) {
+ my_attr_eff_dram_rows = 13;
+ } else if (spd_sdram_rows_u8array[0][0] == fapi::ENUM_ATTR_SPD_SDRAM_ROWS_R14) {
+ my_attr_eff_dram_rows = 14;
+ } else if (spd_sdram_rows_u8array[0][0] == fapi::ENUM_ATTR_SPD_SDRAM_ROWS_R15) {
+ my_attr_eff_dram_rows = 15;
+ } else if (spd_sdram_rows_u8array[0][0] == fapi::ENUM_ATTR_SPD_SDRAM_ROWS_R16) {
+ my_attr_eff_dram_rows = 16;
+ } else {
+ FAPI_ERR("Unknown DRAM rows on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if (spd_sdram_columns_u8array[0][0] == fapi::ENUM_ATTR_SPD_SDRAM_COLUMNS_C9) {
+ my_attr_eff_dram_cols = 9;
+ } else if (spd_sdram_columns_u8array[0][0] == fapi::ENUM_ATTR_SPD_SDRAM_COLUMNS_C10) {
+ my_attr_eff_dram_cols = 10;
+ } else if (spd_sdram_columns_u8array[0][0] == fapi::ENUM_ATTR_SPD_SDRAM_COLUMNS_C11) {
+ my_attr_eff_dram_cols = 11;
+ } else if (spd_sdram_columns_u8array[0][0] == fapi::ENUM_ATTR_SPD_SDRAM_COLUMNS_C12) {
+ my_attr_eff_dram_cols = 12;
+ } else {
+ FAPI_ERR("Unknown DRAM cols on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if (spd_dram_width_u8array[0][0] == fapi::ENUM_ATTR_SPD_DRAM_WIDTH_W4) {
+ my_attr_eff_dram_width = fapi::ENUM_ATTR_EFF_DRAM_WIDTH_X4;
+ } else if (spd_dram_width_u8array[0][0] == fapi::ENUM_ATTR_SPD_DRAM_WIDTH_W8) {
+ my_attr_eff_dram_width = fapi::ENUM_ATTR_EFF_DRAM_WIDTH_X8;
+ // NOTE: TDQS enable MR1(A11) is only avaliable for X8 in DDR3
+ my_attr_eff_dram_tdqs = 1;
+ } else if (spd_dram_width_u8array[0][0] == fapi::ENUM_ATTR_SPD_DRAM_WIDTH_W16) {
+ my_attr_eff_dram_width = fapi::ENUM_ATTR_EFF_DRAM_WIDTH_X16;
+ FAPI_ERR("Unsupported DRAM width x16 on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ } else if (spd_dram_width_u8array[0][0] == fapi::ENUM_ATTR_SPD_DRAM_WIDTH_W32) {
+ my_attr_eff_dram_width = fapi::ENUM_ATTR_EFF_DRAM_WIDTH_X32;
+ FAPI_ERR("Unsupported DRAM width x32 on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ } else {
+ FAPI_ERR("Unknown DRAM width on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ my_attr_eff_dram_density = 16;
+ for (cur_mba_port = 0; cur_mba_port < PORT_SIZE; cur_mba_port += 1) {
+ for (cur_mba_dimm = 0; cur_mba_dimm < my_attr_eff_num_drops_per_port; cur_mba_dimm += 1) {
+ if (spd_sdram_density_u8array[cur_mba_port][cur_mba_dimm] == fapi::ENUM_ATTR_SPD_SDRAM_DENSITY_D16GB) {
+ cur_dram_density = 16;
+ } else if (spd_sdram_density_u8array[cur_mba_port][cur_mba_dimm] == fapi::ENUM_ATTR_SPD_SDRAM_DENSITY_D8GB) {
+ cur_dram_density = 8;
+ } else if (spd_sdram_density_u8array[cur_mba_port][cur_mba_dimm] == fapi::ENUM_ATTR_SPD_SDRAM_DENSITY_D4GB) {
+ cur_dram_density = 4;
+ } else if (spd_sdram_density_u8array[cur_mba_port][cur_mba_dimm] == fapi::ENUM_ATTR_SPD_SDRAM_DENSITY_D2GB) {
+ cur_dram_density = 2;
+ } else if (spd_sdram_density_u8array[cur_mba_port][cur_mba_dimm] == fapi::ENUM_ATTR_SPD_SDRAM_DENSITY_D1GB) {
+ cur_dram_density = 1;
+ } else {
+ FAPI_ERR("Unsupported DRAM density on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if (my_attr_eff_dram_density > cur_dram_density) {
+ my_attr_eff_dram_density = cur_dram_density;
+ }
+
+ // Identify/Verify DIMM voltage compatability
+ // See mss_volt.C
+
+ // Identify/Assign minimum timing
+ mtb_in_ps_u32array[cur_mba_port][cur_mba_dimm] = (spd_mtb_dividend_u8array[cur_mba_port][cur_mba_dimm] * 1000) / spd_mtb_divisor_u8array[cur_mba_port][cur_mba_dimm];
+ ftb_in_fs_u32array[cur_mba_port][cur_mba_dimm] = (spd_ftb_dividend_u8array[cur_mba_port][cur_mba_dimm] * 1000) / spd_ftb_divisor_u8array[cur_mba_port][cur_mba_dimm];
+
+ // Calculate CL
+ // See mss_freq.C
+
+ my_dram_wr = calc_timing_in_clk(tCK_in_ps, mtb_in_ps_u32array[cur_mba_port][cur_mba_dimm], ftb_in_fs_u32array[cur_mba_port][cur_mba_dimm], spd_twrmin_u8array[cur_mba_port][cur_mba_dimm], 0);
+ if (my_dram_wr > my_attr_eff_dram_wr) {
+ my_attr_eff_dram_wr = my_dram_wr;
+ }
+ my_dram_trcd = calc_timing_in_clk(tCK_in_ps, mtb_in_ps_u32array[cur_mba_port][cur_mba_dimm], ftb_in_fs_u32array[cur_mba_port][cur_mba_dimm], spd_trcdmin_u8array[cur_mba_port][cur_mba_dimm], spd_fine_offset_trcdmin_u8array[cur_mba_port][cur_mba_dimm]);
+ if (my_dram_trcd > my_attr_eff_dram_trcd) {
+ my_attr_eff_dram_trcd = my_dram_trcd;
+ }
+ my_dram_trrd = calc_timing_in_clk(tCK_in_ps, mtb_in_ps_u32array[cur_mba_port][cur_mba_dimm], ftb_in_fs_u32array[cur_mba_port][cur_mba_dimm], spd_trrdmin_u8array[cur_mba_port][cur_mba_dimm], 0);
+ if (my_dram_trrd > my_attr_eff_dram_trrd) {
+ my_attr_eff_dram_trrd = my_dram_trrd;
+ }
+ my_dram_trp = calc_timing_in_clk(tCK_in_ps, mtb_in_ps_u32array[cur_mba_port][cur_mba_dimm], ftb_in_fs_u32array[cur_mba_port][cur_mba_dimm], spd_trpmin_u8array[cur_mba_port][cur_mba_dimm], spd_fine_offset_trpmin_u8array[cur_mba_port][cur_mba_dimm]);
+ if (my_dram_trp > my_attr_eff_dram_trp) {
+ my_attr_eff_dram_trp = my_dram_trp;
+ }
+ my_dram_twtr = calc_timing_in_clk(tCK_in_ps, mtb_in_ps_u32array[cur_mba_port][cur_mba_dimm], ftb_in_fs_u32array[cur_mba_port][cur_mba_dimm], spd_twtrmin_u8array[cur_mba_port][cur_mba_dimm], 0);
+ if (my_dram_twtr > my_attr_eff_dram_twtr) {
+ my_attr_eff_dram_twtr = my_dram_twtr;
+ }
+ my_dram_trtp = calc_timing_in_clk(tCK_in_ps, mtb_in_ps_u32array[cur_mba_port][cur_mba_dimm], ftb_in_fs_u32array[cur_mba_port][cur_mba_dimm], spd_trtpmin_u8array[cur_mba_port][cur_mba_dimm], 0);
+ if (my_dram_trtp > my_attr_eff_dram_trtp) {
+ my_attr_eff_dram_trtp = my_dram_trtp;
+ }
+ my_dram_tras = calc_timing_in_clk(tCK_in_ps, mtb_in_ps_u32array[cur_mba_port][cur_mba_dimm], ftb_in_fs_u32array[cur_mba_port][cur_mba_dimm], spd_trasmin_u32array[cur_mba_port][cur_mba_dimm], 0);
+ if (my_dram_tras > my_attr_eff_dram_tras_u32) {
+ my_attr_eff_dram_tras_u32 = my_dram_tras;
+ }
+ my_dram_trc = calc_timing_in_clk(tCK_in_ps, mtb_in_ps_u32array[cur_mba_port][cur_mba_dimm], ftb_in_fs_u32array[cur_mba_port][cur_mba_dimm], spd_trcmin_u32array[cur_mba_port][cur_mba_dimm], spd_fine_offset_trcmin_u8array[cur_mba_port][cur_mba_dimm]);
+ if (my_dram_trc > my_attr_eff_dram_trc_u32) {
+ my_attr_eff_dram_trc_u32 = my_dram_trc;
+ }
+ my_dram_trfc = calc_timing_in_clk(tCK_in_ps, mtb_in_ps_u32array[cur_mba_port][cur_mba_dimm], ftb_in_fs_u32array[cur_mba_port][cur_mba_dimm], spd_trfcmin_u32array[cur_mba_port][cur_mba_dimm], 0); if(rc) return rc;
+ if (my_dram_trfc > my_attr_eff_dram_trfc) {
+ my_attr_eff_dram_trfc = my_dram_trfc;
+ }
+ my_dram_tfaw = calc_timing_in_clk(tCK_in_ps, mtb_in_ps_u32array[cur_mba_port][cur_mba_dimm], ftb_in_fs_u32array[cur_mba_port][cur_mba_dimm], spd_tfawmin_u32array[cur_mba_port][cur_mba_dimm], 0); if(rc) return rc;
+ if (my_dram_tfaw > my_attr_eff_dram_tfaw_u32) {
+ my_attr_eff_dram_tfaw_u32 = my_dram_tfaw;
+ }
+ }
+ }
+
+ // Calculate CWL
+ if ((2000000/mss_freq) >= 2500) {
+ my_attr_eff_dram_cwl = 5;
+ } else if ((2000000/mss_freq) >= 1875) {
+ my_attr_eff_dram_cwl = 6;
+ } else if ((2000000/mss_freq) >= 1500) {
+ my_attr_eff_dram_cwl = 7;
+ } else if ((2000000/mss_freq) >= 1250) {
+ my_attr_eff_dram_cwl = 8;
+ } else if ((2000000/mss_freq) >= 1070) {
+ my_attr_eff_dram_cwl = 9;
+ } else if ((2000000/mss_freq) >= 935) {
+ my_attr_eff_dram_cwl = 10;
+ } else if ((2000000/mss_freq) >= 833) {
+ my_attr_eff_dram_cwl = 11;
+ } else if ((2000000/mss_freq) >= 750) {
+ my_attr_eff_dram_cwl = 12;
+ }
+
+ // Calculate tRFI
+ my_attr_eff_dram_trfi = (3900 * mss_freq) / 2000;
+
+ // Assigning dependent values to attributes
+ for (cur_mba_port = 0; cur_mba_port < PORT_SIZE; cur_mba_port += 1) {
+ for (cur_mba_dimm = 0; cur_mba_dimm < DIMM_SIZE; cur_mba_dimm += 1) {
+ if (spd_num_ranks_u8array[cur_mba_port][cur_mba_dimm] == fapi::ENUM_ATTR_SPD_NUM_RANKS_R4) {
+ my_attr_eff_num_ranks_per_dimm[cur_mba_port][cur_mba_dimm] = 4;
+ my_attr_eff_dimm_ranks_configed[cur_mba_port][cur_mba_dimm] = 0xF0;
+ } else if (spd_num_ranks_u8array[cur_mba_port][cur_mba_dimm] == fapi::ENUM_ATTR_SPD_NUM_RANKS_R2) {
+ my_attr_eff_num_ranks_per_dimm[cur_mba_port][cur_mba_dimm] = 2;
+ my_attr_eff_dimm_ranks_configed[cur_mba_port][cur_mba_dimm] = 0xC0;
+ } else if (spd_num_ranks_u8array[cur_mba_port][cur_mba_dimm] == fapi::ENUM_ATTR_SPD_NUM_RANKS_R1) {
+ my_attr_eff_num_ranks_per_dimm[cur_mba_port][cur_mba_dimm] = 1;
+ my_attr_eff_dimm_ranks_configed[cur_mba_port][cur_mba_dimm] = 0x80;
+ } else {
+ my_attr_eff_num_ranks_per_dimm[cur_mba_port][cur_mba_dimm] = 0;
+ my_attr_eff_dimm_ranks_configed[cur_mba_port][cur_mba_dimm] = 0x00;
+ }
+ if (my_attr_eff_num_ranks_per_dimm[cur_mba_port][cur_mba_dimm] != 0) {
+ // dimm_size = dram_density / 8 * primary_bus_width / dram_width * num_ranks_per_dimm
+ my_attr_eff_dimm_size[cur_mba_port][cur_mba_dimm] = (my_attr_eff_dram_density * my_attr_eff_num_ranks_per_dimm[cur_mba_port][cur_mba_dimm] * 64) / (8 * my_attr_eff_dram_width);
+ } else {
+ my_attr_eff_dimm_size[cur_mba_port][cur_mba_dimm] = 0;
+ }
+
+ // AST HERE: Needs SPD byte33[7,1:0], currently hard coded to no stacking
+ my_attr_eff_num_master_ranks_per_dimm[cur_mba_port][cur_mba_dimm] = my_attr_eff_num_ranks_per_dimm[cur_mba_port][cur_mba_dimm];
+
+ // DEBUG HERE:
+ //FAPI_INF("size=%d density=%d ranks=%d width=%d on %s", my_attr_eff_dimm_size[cur_mba_port][cur_mba_dimm], my_attr_eff_dram_density, my_attr_eff_num_ranks_per_dimm[cur_mba_port][cur_mba_dimm], my_attr_eff_dram_width, i_target_mba.toEcmdString());
+ }
+ }
+ }
+
+
+ my_attr_eff_dram_tras = uint8_t (my_attr_eff_dram_tras_u32);
+ my_attr_eff_dram_trc = uint8_t (my_attr_eff_dram_trc_u32);
+ my_attr_eff_dram_tfaw = uint8_t (my_attr_eff_dram_tfaw_u32);
+
+
+ // Set attributes
+ rc = FAPI_ATTR_SET(ATTR_EFF_DIMM_RANKS_CONFIGED, &i_target_mba, my_attr_eff_dimm_ranks_configed); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DIMM_RCD_CNTL_WORD_0_15, &i_target_mba, my_attr_eff_dimm_rcd_cntl_word_0_15); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DIMM_SIZE, &i_target_mba, my_attr_eff_dimm_size); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DIMM_TYPE, &i_target_mba, my_attr_eff_dimm_type); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_AL, &i_target_mba, my_attr_eff_dram_al); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_ASR, &i_target_mba, my_attr_eff_dram_asr); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_BANKS, &i_target_mba, my_attr_eff_dram_banks); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_BL, &i_target_mba, my_attr_eff_dram_bl); if(rc) return rc;
+ // See mss_freq.C
+ //rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_CL, &i_target_mba, my_attr_eff_dram_cl); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_COLS, &i_target_mba, my_attr_eff_dram_cols); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_CWL, &i_target_mba, my_attr_eff_dram_cwl); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_DENSITY, &i_target_mba, my_attr_eff_dram_density); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_DLL_ENABLE, &i_target_mba, my_attr_eff_dram_dll_enable); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_DLL_PPD, &i_target_mba, my_attr_eff_dram_dll_ppd); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_DLL_RESET, &i_target_mba, my_attr_eff_dram_dll_reset); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_GEN, &i_target_mba, my_attr_eff_dram_gen); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_OUTPUT_BUFFER, &i_target_mba, my_attr_eff_dram_output_buffer); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_PASR, &i_target_mba, my_attr_eff_dram_pasr); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_RBT, &i_target_mba, my_attr_eff_dram_rbt); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_ROWS, &i_target_mba, my_attr_eff_dram_rows); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_SRT, &i_target_mba, my_attr_eff_dram_srt); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_TDQS, &i_target_mba, my_attr_eff_dram_tdqs); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_TFAW, &i_target_mba, my_attr_eff_dram_tfaw); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_TM, &i_target_mba, my_attr_eff_dram_tm); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_TRAS, &i_target_mba, my_attr_eff_dram_tras); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_TRC, &i_target_mba, my_attr_eff_dram_trc); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_TRCD, &i_target_mba, my_attr_eff_dram_trcd); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_TRFC, &i_target_mba, my_attr_eff_dram_trfc); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_TRFI, &i_target_mba, my_attr_eff_dram_trfi); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_TRP, &i_target_mba, my_attr_eff_dram_trp); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_TRRD, &i_target_mba, my_attr_eff_dram_trrd); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_TRTP, &i_target_mba, my_attr_eff_dram_trtp); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_TWTR, &i_target_mba, my_attr_eff_dram_twtr); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_WIDTH, &i_target_mba, my_attr_eff_dram_width); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_WR, &i_target_mba, my_attr_eff_dram_wr); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_WR_LVL_ENABLE, &i_target_mba, my_attr_eff_dram_wr_lvl_enable); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_IBM_TYPE, &i_target_mba, my_attr_eff_ibm_type); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_MEMCAL_INTERVAL, &i_target_mba, my_attr_eff_memcal_interval); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_MPR_LOC, &i_target_mba, my_attr_eff_mpr_loc); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_MPR_MODE, &i_target_mba, my_attr_eff_mpr_mode); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_NUM_DIES_PER_PACKAGE, &i_target_mba, my_attr_eff_num_dies_per_package); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_NUM_DROPS_PER_PORT, &i_target_mba, my_attr_eff_num_drops_per_port); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM, &i_target_mba, my_attr_eff_num_master_ranks_per_dimm); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_NUM_PACKAGES_PER_RANK, &i_target_mba, my_attr_eff_num_packages_per_rank); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, my_attr_eff_num_ranks_per_dimm); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_SCHMOO_MODE, &i_target_mba, my_attr_eff_schmoo_mode); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_SCHMOO_PARAM_VALID, &i_target_mba, my_attr_eff_schmoo_param_valid); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_SCHMOO_TEST_VALID, &i_target_mba, my_attr_eff_schmoo_test_valid); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_STACK_TYPE, &i_target_mba, my_attr_eff_stack_type); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_ZQCAL_INTERVAL, &i_target_mba, my_attr_eff_zqcal_interval); if(rc) return rc;
+
+
+ // Calls to sub-procedures
+ rc = mss_eff_config_rank_group(i_target_mba); if(rc) return rc;
+ rc = mss_eff_config_termination(i_target_mba); if(rc) return rc;
+ rc = mss_eff_config_thermal(i_target_mba); if(rc) return rc;
+
+
+ FAPI_INF("%s on %s COMPLETE\n", PROCEDURE_NAME, i_target_mba.toEcmdString());
+ return rc;
+}
+
+
+
+} // extern "C"
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config.H b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config.H
new file mode 100644
index 000000000..3283fc09a
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config.H
@@ -0,0 +1,76 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: mss_eff_config.H,v 1.2 2012/02/15 01:34:45 asaetow Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_eff_config.H,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_eff_config.H
+// *! DESCRIPTION : Header file for mss_eff_config.
+// *! OWNER NAME : Anuwat Saetow Email: asaetow@us.ibm.com
+// *! BACKUP NAME : Mark Bellows Email: bellows@us.ibm.com
+// *! ADDITIONAL COMMENTS :
+//
+//
+//
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.3 | | |
+// 1.2 | asaetow |14-FEB-12| Fixed "fapi::" for hostboot, added "const", renamed "i_target_mba", and changed comments.
+// 1.1 | asaetow |03-NOV-11| First Draft.
+
+
+#ifndef MSS_EFF_CONFIG_H_
+#define MSS_EFF_CONFIG_H_
+
+//----------------------------------------------------------------------
+// My Includes
+//----------------------------------------------------------------------
+
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <fapi.H>
+
+
+typedef fapi::ReturnCode (*mss_eff_config_FP_t)(const fapi::Target i_target_mba);
+
+extern "C" {
+
+//******************************************************************************
+//* name=mss_eff_config, param=i_target_mba, return=ReturnCode
+//******************************************************************************
+fapi::ReturnCode mss_eff_config(const fapi::Target i_target_mba);
+
+} // extern "C"
+
+#endif // MSS_EFF_CONFIG_H_
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_rank_group.C b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_rank_group.C
new file mode 100644
index 000000000..399a91e09
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_rank_group.C
@@ -0,0 +1,251 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_rank_group.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: mss_eff_config_rank_group.C,v 1.6 2012/04/30 15:11:46 asaetow Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_eff_config_rank_group.C,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_eff_config_rank_group
+// *! DESCRIPTION : see additional comments below
+// *! OWNER NAME : Anuwat Saetow Email: asaetow@us.ibm.com
+// *! BACKUP NAME : Mark Bellows Email: bellows@us.ibm.com
+// *! ADDITIONAL COMMENTS :
+//
+// This procedure takes in attributes and determines proper rank groupings that will be apply to the system and used during draminit_training and draminit_training_adv. Each valid rank in the system will be assigned to one of twelve attributes below. Only the primary rank group will be calibrated and have values stored in the delay registers.
+// EFF_PRIMARY_RANK_GROUP0, EFF_PRIMARY_RANK_GROUP1, EFF_PRIMARY_RANK_GROUP2, EFF_PRIMARY_RANK_GROUP3
+// EFF_SECONDARY_RANK_GROUP0, EFF_SECONDARY_RANK_GROUP1, EFF_SECONDARY_RANK_GROUP2, EFF_SECONDARY_RANK_GROUP3
+// EFF_TERTIARY_RANK_GROUP0, EFF_TERTIARY_RANK_GROUP1, EFF_TERTIARY_RANK_GROUP2, EFF_TERTIARY_RANK_GROUP3
+// EFF_QUATERNARY_RANK_GROUP0, EFF_QUATERNARY_RANK_GROUP1, EFF_QUATERNARY_RANK_GROUP2, EFF_QUATERNARY_RANK_GROUP3
+//
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.7 | | |
+// 1.6 | asaetow |30-APR-12| Fixed "fapi::" for hostboot, added "const", renamed "i_target_mba", and changed comments.
+// | | | Changed message to standardized format.
+// | | | Changed BACKUP to Mark Bellows.
+// 1.5 | asaetow |20-MAR-12| Changed EFF_CONFIG_RANK_GROUP_RC_ERROR_001A to RC_MSS_PLACE_HOLDER_ERROR temporary until Cronus is ready to pick up error code xml.
+// 1.4 | asaetow |08-FEB-12| Added INVALID(255) into ranks that do not exist.
+// | | | Removed support for mix ATTR_EFF_NUM_RANKS_PER_DIMM within a port.
+// | | | Changed "rc =" to "FAPI_SET_HWP_ERROR(rc, EFF_CONFIG_RANK_GROUP_RC_ERROR_001A)".
+// 1.3 | asaetow |24-JAN-12| Removed all temp hard code work around and enabled FAPI_ATTR_GET().
+// | | | Added mem_attr write back support, enabled FAPI_ATTR_SET().
+// | | | Removed triple-drop support.
+// | | | Changed PORT_SIZE and DIMM_SIZE to const 2 to match mem_attr.
+// | | | Added extern "C" so that procedure can be run independently.
+// 1.2 | asaetow |03-NOV-11| Fixed to comply with mss_eff_config_rank_group.H
+// 1.1 | asaetow |01-NOV-11| First Draft.
+
+
+
+//----------------------------------------------------------------------
+// My Includes
+//----------------------------------------------------------------------
+
+
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <fapi.H>
+
+
+
+//----------------------------------------------------------------------
+// ENUMs
+//----------------------------------------------------------------------
+enum {
+ CDIMM = 0,
+ RDIMM = 1,
+ UDIMM = 2,
+ LRDIMM = 3,
+ INVALID = 255,
+};
+
+
+
+extern "C" {
+
+
+
+//******************************************************************************
+//* name=mss_eff_config_rank_group, param=i_target_mba, return=ReturnCode
+//******************************************************************************
+fapi::ReturnCode mss_eff_config_rank_group(const fapi::Target i_target_mba) {
+ fapi::ReturnCode rc = fapi::FAPI_RC_SUCCESS;
+ const char * const PROCEDURE_NAME = "mss_eff_config_rank_group";
+ FAPI_INF("*** Running %s on %s ... ***", PROCEDURE_NAME, i_target_mba.toEcmdString());
+
+ const uint8_t PORT_SIZE = 2;
+ const uint8_t DIMM_SIZE = 2;
+ // ATTR_EFF_DRAM_GEN: EMPTY = 0, DDR3 = 1, DDR4 = 2,
+ // ATTR_EFF_DIMM_TYPE: CDIMM = 0, RDIMM = 1, UDIMM = 2, LRDIMM = 3,
+ uint8_t num_ranks_per_dimm_u8array[PORT_SIZE][DIMM_SIZE];
+ uint8_t dram_gen_u8;
+ uint8_t dimm_type_u8;
+
+ rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, num_ranks_per_dimm_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_GEN, &i_target_mba, dram_gen_u8); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target_mba, dimm_type_u8); if(rc) return rc;
+
+ uint8_t primary_rank_group0_u8array[PORT_SIZE];
+ uint8_t primary_rank_group1_u8array[PORT_SIZE];
+ uint8_t primary_rank_group2_u8array[PORT_SIZE];
+ uint8_t primary_rank_group3_u8array[PORT_SIZE];
+ uint8_t secondary_rank_group0_u8array[PORT_SIZE];
+ uint8_t secondary_rank_group1_u8array[PORT_SIZE];
+ uint8_t secondary_rank_group2_u8array[PORT_SIZE];
+ uint8_t secondary_rank_group3_u8array[PORT_SIZE];
+ uint8_t tertiary_rank_group0_u8array[PORT_SIZE];
+ uint8_t tertiary_rank_group1_u8array[PORT_SIZE];
+ uint8_t tertiary_rank_group2_u8array[PORT_SIZE];
+ uint8_t tertiary_rank_group3_u8array[PORT_SIZE];
+ uint8_t quanternary_rank_group0_u8array[PORT_SIZE];
+ uint8_t quanternary_rank_group1_u8array[PORT_SIZE];
+ uint8_t quanternary_rank_group2_u8array[PORT_SIZE];
+ uint8_t quanternary_rank_group3_u8array[PORT_SIZE];
+
+ for (uint8_t cur_port = 0; cur_port < PORT_SIZE; cur_port += 1) {
+ if (dimm_type_u8 == LRDIMM) {
+ // HERE: NOT correct, need to account for ATTR_EFF_DIMM_RANKS_CONFIGED for LRDIMMs /w multi master ranks
+ primary_rank_group0_u8array[cur_port] = 0;
+ primary_rank_group1_u8array[cur_port] = 4;
+ primary_rank_group2_u8array[cur_port] = 8;
+ primary_rank_group3_u8array[cur_port] = 12;
+ secondary_rank_group0_u8array[cur_port] = 1;
+ secondary_rank_group1_u8array[cur_port] = 5;
+ secondary_rank_group2_u8array[cur_port] = 9;
+ secondary_rank_group3_u8array[cur_port] = 13;
+ tertiary_rank_group0_u8array[cur_port] = 2;
+ tertiary_rank_group1_u8array[cur_port] = 6;
+ tertiary_rank_group2_u8array[cur_port] = 10;
+ tertiary_rank_group3_u8array[cur_port] = 14;
+ quanternary_rank_group0_u8array[cur_port] = 3;
+ quanternary_rank_group1_u8array[cur_port] = 7;
+ quanternary_rank_group2_u8array[cur_port] = 11;
+ quanternary_rank_group3_u8array[cur_port] = 15;
+ } else { // RDIMM or CDIMM
+ if ((num_ranks_per_dimm_u8array[cur_port][0] > 0) && (num_ranks_per_dimm_u8array[cur_port][1] == 0)) {
+ primary_rank_group0_u8array[cur_port] = 0;
+ if (num_ranks_per_dimm_u8array[cur_port][0] > 1) {
+ primary_rank_group1_u8array[cur_port] = 1;
+ } else {
+ primary_rank_group1_u8array[cur_port] = INVALID;
+ }
+ if (num_ranks_per_dimm_u8array[cur_port][0] > 2) {
+ primary_rank_group2_u8array[cur_port] = 2;
+ primary_rank_group3_u8array[cur_port] = 3;
+ } else {
+ primary_rank_group2_u8array[cur_port] = INVALID;
+ primary_rank_group3_u8array[cur_port] = INVALID;
+ }
+ secondary_rank_group0_u8array[cur_port] = INVALID;
+ secondary_rank_group1_u8array[cur_port] = INVALID;
+ secondary_rank_group2_u8array[cur_port] = INVALID;
+ secondary_rank_group3_u8array[cur_port] = INVALID;
+ } else if ((num_ranks_per_dimm_u8array[cur_port][0] > 0) && (num_ranks_per_dimm_u8array[cur_port][1] > 0)) {
+ if (num_ranks_per_dimm_u8array[cur_port][0] != num_ranks_per_dimm_u8array[cur_port][1]) {
+ FAPI_ERR("%s: FAILED!", PROCEDURE_NAME);
+ FAPI_ERR("Plug rule violation, num_ranks_per_dimm=%d[0],%d[1] on %s PORT%d!", num_ranks_per_dimm_u8array[cur_port][0], num_ranks_per_dimm_u8array[cur_port][1], i_target_mba.toEcmdString(), cur_port);
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR);
+ return rc;
+ }
+ primary_rank_group0_u8array[cur_port] = 0;
+ primary_rank_group1_u8array[cur_port] = 4;
+ if (num_ranks_per_dimm_u8array[cur_port][0] == 2) {
+ primary_rank_group2_u8array[cur_port] = 1;
+ primary_rank_group3_u8array[cur_port] = 5;
+ secondary_rank_group0_u8array[cur_port] = INVALID;
+ secondary_rank_group1_u8array[cur_port] = INVALID;
+ secondary_rank_group2_u8array[cur_port] = INVALID;
+ secondary_rank_group3_u8array[cur_port] = INVALID;
+ } else if (num_ranks_per_dimm_u8array[cur_port][0] == 4) {
+ primary_rank_group2_u8array[cur_port] = 2;
+ primary_rank_group3_u8array[cur_port] = 6;
+ secondary_rank_group0_u8array[cur_port] = 1;
+ secondary_rank_group1_u8array[cur_port] = 5;
+ secondary_rank_group2_u8array[cur_port] = 3;
+ secondary_rank_group3_u8array[cur_port] = 7;
+ } else if (num_ranks_per_dimm_u8array[cur_port][0] != 1) {
+ FAPI_ERR("%s: FAILED!", PROCEDURE_NAME);
+ FAPI_ERR("Plug rule violation, num_ranks_per_dimm=%d[0],%d[1] on %s PORT%d!", num_ranks_per_dimm_u8array[cur_port][0], num_ranks_per_dimm_u8array[cur_port][1], i_target_mba.toEcmdString(), cur_port);
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR);
+ return rc;
+ }
+ } else if ((num_ranks_per_dimm_u8array[cur_port][0] == 0) && (num_ranks_per_dimm_u8array[cur_port][1] == 0)) {
+ primary_rank_group0_u8array[cur_port] = INVALID;
+ primary_rank_group1_u8array[cur_port] = INVALID;
+ primary_rank_group2_u8array[cur_port] = INVALID;
+ primary_rank_group3_u8array[cur_port] = INVALID;
+ secondary_rank_group0_u8array[cur_port] = INVALID;
+ secondary_rank_group1_u8array[cur_port] = INVALID;
+ secondary_rank_group2_u8array[cur_port] = INVALID;
+ secondary_rank_group3_u8array[cur_port] = INVALID;
+ } else {
+ FAPI_ERR("%s: FAILED!", PROCEDURE_NAME);
+ FAPI_ERR("Plug rule violation, num_ranks_per_dimm=%d[0],%d[1] on %s PORT%d!", num_ranks_per_dimm_u8array[cur_port][0], num_ranks_per_dimm_u8array[cur_port][1], i_target_mba.toEcmdString(), cur_port);
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR);
+ return rc;
+ }
+ tertiary_rank_group0_u8array[cur_port] = INVALID;
+ tertiary_rank_group1_u8array[cur_port] = INVALID;
+ tertiary_rank_group2_u8array[cur_port] = INVALID;
+ tertiary_rank_group3_u8array[cur_port] = INVALID;
+ quanternary_rank_group0_u8array[cur_port] = INVALID;
+ quanternary_rank_group1_u8array[cur_port] = INVALID;
+ quanternary_rank_group2_u8array[cur_port] = INVALID;
+ quanternary_rank_group3_u8array[cur_port] = INVALID;
+ }
+ FAPI_INF("P[%02d][%02d][%02d][%02d],S[%02d][%02d][%02d][%02d],T[%02d][%02d][%02d][%02d],Q[%02d][%02d][%02d][%02d] on %s PORT%d.", primary_rank_group0_u8array[cur_port], primary_rank_group1_u8array[cur_port], primary_rank_group2_u8array[cur_port], primary_rank_group3_u8array[cur_port], secondary_rank_group0_u8array[cur_port], secondary_rank_group1_u8array[cur_port], secondary_rank_group2_u8array[cur_port], secondary_rank_group3_u8array[cur_port], tertiary_rank_group0_u8array[cur_port], tertiary_rank_group1_u8array[cur_port], tertiary_rank_group2_u8array[cur_port], tertiary_rank_group3_u8array[cur_port], quanternary_rank_group0_u8array[cur_port], quanternary_rank_group1_u8array[cur_port], quanternary_rank_group2_u8array[cur_port], quanternary_rank_group3_u8array[cur_port], i_target_mba.toEcmdString(), cur_port);
+ }
+ rc = FAPI_ATTR_SET(ATTR_EFF_PRIMARY_RANK_GROUP0, &i_target_mba, primary_rank_group0_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_PRIMARY_RANK_GROUP1, &i_target_mba, primary_rank_group1_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_PRIMARY_RANK_GROUP2, &i_target_mba, primary_rank_group2_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_PRIMARY_RANK_GROUP3, &i_target_mba, primary_rank_group3_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_SECONDARY_RANK_GROUP0, &i_target_mba, secondary_rank_group0_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_SECONDARY_RANK_GROUP1, &i_target_mba, secondary_rank_group1_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_SECONDARY_RANK_GROUP2, &i_target_mba, secondary_rank_group2_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_SECONDARY_RANK_GROUP3, &i_target_mba, secondary_rank_group3_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_TERTIARY_RANK_GROUP0, &i_target_mba, tertiary_rank_group0_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_TERTIARY_RANK_GROUP1, &i_target_mba, tertiary_rank_group1_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_TERTIARY_RANK_GROUP2, &i_target_mba, tertiary_rank_group2_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_TERTIARY_RANK_GROUP3, &i_target_mba, tertiary_rank_group3_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_QUATERNARY_RANK_GROUP0, &i_target_mba, quanternary_rank_group0_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_QUATERNARY_RANK_GROUP1, &i_target_mba, quanternary_rank_group1_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_QUATERNARY_RANK_GROUP2, &i_target_mba, quanternary_rank_group2_u8array); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_QUATERNARY_RANK_GROUP3, &i_target_mba, quanternary_rank_group3_u8array); if(rc) return rc;
+
+ FAPI_INF("%s on %s COMPLETE", PROCEDURE_NAME, i_target_mba.toEcmdString());
+ return rc;
+}
+
+
+
+} // extern "C"
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_rank_group.H b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_rank_group.H
new file mode 100644
index 000000000..54c478d6b
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_rank_group.H
@@ -0,0 +1,77 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_rank_group.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: mss_eff_config_rank_group.H,v 1.3 2012/02/15 01:39:30 asaetow Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_eff_config_rank_group.H,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_eff_config_rank_group.H
+// *! DESCRIPTION : Header file for mss_eff_config_rank_group.
+// *! OWNER NAME : Anuwat Saetow Email: asaetow@us.ibm.com
+// *! BACKUP NAME : Mark Bellows Email: bellows@us.ibm.com
+// *! ADDITIONAL COMMENTS :
+//
+//
+//
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.4 | | |
+// 1.3 | asaetow |14-FEB-12| Fixed "fapi::" for hostboot, added "const", renamed "i_target_mba", and changed comments.
+// 1.2 | asaetow |24-JAN-12| Added typedef and extern "C".
+// 1.1 | asaetow |03-NOV-11| First Draft.
+
+
+#ifndef MSS_EFF_CONFIG_RANK_GROUP_H_
+#define MSS_EFF_CONFIG_RANK_GROUP_H_
+
+//----------------------------------------------------------------------
+// My Includes
+//----------------------------------------------------------------------
+
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <fapi.H>
+
+
+typedef fapi::ReturnCode (*mss_eff_config_rank_group_FP_t)(const fapi::Target i_target_mba);
+
+extern "C" {
+
+//******************************************************************************
+//* name=mss_eff_config_rank_group, param=i_target_mba, return=ReturnCode
+//******************************************************************************
+fapi::ReturnCode mss_eff_config_rank_group(const fapi::Target i_target_mba);
+
+} // extern "C"
+
+#endif // MSS_EFF_CONFIG_RANK_GROUP_H_
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.C b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.C
new file mode 100644
index 000000000..fa5746c00
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.C
@@ -0,0 +1,193 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: mss_eff_config_termination.C,v 1.1 2012/04/30 16:42:50 asaetow Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_eff_config_termination.C,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_eff_config_termination
+// *! DESCRIPTION : see additional comments below
+// *! OWNER NAME : Anuwat Saetow Email: asaetow@us.ibm.com
+// *! BACKUP NAME : Mark Bellows Email: bellows@us.ibm.com
+// *! ADDITIONAL COMMENTS :
+//
+// This procedure is a place holder for attributes set by the machine parsable workbook.
+//
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.2 | | |
+// 1.1 | asaetow |30-APR-12| First Draft.
+
+
+
+//----------------------------------------------------------------------
+// My Includes
+//----------------------------------------------------------------------
+
+
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <fapi.H>
+
+
+
+//----------------------------------------------------------------------
+// ENUMs
+//----------------------------------------------------------------------
+
+
+
+extern "C" {
+
+
+
+//******************************************************************************
+//* name=mss_eff_config_termination, param=i_target_mba, return=ReturnCode
+//******************************************************************************
+fapi::ReturnCode mss_eff_config_termination(const fapi::Target i_target_mba) {
+ fapi::ReturnCode rc = fapi::FAPI_RC_SUCCESS;
+ const char * const PROCEDURE_NAME = "mss_eff_config_termination";
+ FAPI_INF("*** Running %s on %s ... ***", PROCEDURE_NAME, i_target_mba.toEcmdString());
+
+ // Define attribute array size
+ const uint8_t PORT_SIZE = 2;
+ const uint8_t DIMM_SIZE = 2;
+ const uint8_t RANK_SIZE = 4;
+
+ // Define local attribute variables
+ uint8_t my_attr_eff_cen_drv_imp_cmd = 15;
+ uint8_t my_attr_eff_cen_drv_imp_cntl = 15;
+ uint8_t my_attr_eff_cen_drv_imp_dq_dqs = 24;
+ uint8_t my_attr_eff_cen_rcv_imp_dq_dqs = 15;
+ uint32_t my_attr_eff_cen_rd_vref = 50000;
+ uint8_t my_attr_eff_cen_slew_rate_cmd = 0x0;
+ uint8_t my_attr_eff_cen_slew_rate_cntl = 0x0;
+ uint8_t my_attr_eff_cen_slew_rate_dq_dqs = 0x0;
+ uint8_t my_attr_eff_dram_ron[PORT_SIZE][DIMM_SIZE];
+ my_attr_eff_dram_ron[0][0] = 34;
+ my_attr_eff_dram_ron[0][1] = 34;
+ my_attr_eff_dram_ron[1][0] = 34;
+ my_attr_eff_dram_ron[1][1] = 34;
+ uint8_t my_attr_eff_dram_rtt_nom[PORT_SIZE][DIMM_SIZE][RANK_SIZE];
+ my_attr_eff_dram_rtt_nom[0][0][0] = 20;
+ my_attr_eff_dram_rtt_nom[0][0][1] = 0;
+ my_attr_eff_dram_rtt_nom[0][0][2] = 0;
+ my_attr_eff_dram_rtt_nom[0][0][3] = 0;
+ my_attr_eff_dram_rtt_nom[0][1][0] = 20;
+ my_attr_eff_dram_rtt_nom[0][1][1] = 0;
+ my_attr_eff_dram_rtt_nom[0][1][2] = 0;
+ my_attr_eff_dram_rtt_nom[0][1][3] = 0;
+ my_attr_eff_dram_rtt_nom[1][0][0] = 20;
+ my_attr_eff_dram_rtt_nom[1][0][1] = 0;
+ my_attr_eff_dram_rtt_nom[1][0][2] = 0;
+ my_attr_eff_dram_rtt_nom[1][0][3] = 0;
+ my_attr_eff_dram_rtt_nom[1][1][0] = 20;
+ my_attr_eff_dram_rtt_nom[1][1][1] = 0;
+ my_attr_eff_dram_rtt_nom[1][1][2] = 0;
+ my_attr_eff_dram_rtt_nom[1][1][3] = 0;
+ uint8_t my_attr_eff_dram_rtt_wr[PORT_SIZE][DIMM_SIZE][RANK_SIZE];
+ my_attr_eff_dram_rtt_wr[0][0][0] = 60;
+ my_attr_eff_dram_rtt_wr[0][0][1] = 60;
+ my_attr_eff_dram_rtt_wr[0][0][2] = 0;
+ my_attr_eff_dram_rtt_wr[0][0][3] = 0;
+ my_attr_eff_dram_rtt_wr[0][1][0] = 60;
+ my_attr_eff_dram_rtt_wr[0][1][1] = 60;
+ my_attr_eff_dram_rtt_wr[0][1][2] = 0;
+ my_attr_eff_dram_rtt_wr[0][1][3] = 0;
+ my_attr_eff_dram_rtt_wr[1][0][0] = 60;
+ my_attr_eff_dram_rtt_wr[1][0][1] = 60;
+ my_attr_eff_dram_rtt_wr[1][0][2] = 0;
+ my_attr_eff_dram_rtt_wr[1][0][3] = 0;
+ my_attr_eff_dram_rtt_wr[1][1][0] = 60;
+ my_attr_eff_dram_rtt_wr[1][1][1] = 60;
+ my_attr_eff_dram_rtt_wr[1][1][2] = 0;
+ my_attr_eff_dram_rtt_wr[1][1][3] = 0;
+ uint32_t my_attr_eff_dram_wr_vref = 500;
+ uint8_t my_attr_eff_odt_rd[PORT_SIZE][DIMM_SIZE][RANK_SIZE];
+ my_attr_eff_odt_rd[0][0][0] = 0x0;
+ my_attr_eff_odt_rd[0][0][1] = 0x0;
+ my_attr_eff_odt_rd[0][0][2] = 0x0;
+ my_attr_eff_odt_rd[0][0][3] = 0x0;
+ my_attr_eff_odt_rd[0][1][0] = 0x0;
+ my_attr_eff_odt_rd[0][1][1] = 0x0;
+ my_attr_eff_odt_rd[0][1][2] = 0x0;
+ my_attr_eff_odt_rd[0][1][3] = 0x0;
+ my_attr_eff_odt_rd[1][0][0] = 0x0;
+ my_attr_eff_odt_rd[1][0][1] = 0x0;
+ my_attr_eff_odt_rd[1][0][2] = 0x0;
+ my_attr_eff_odt_rd[1][0][3] = 0x0;
+ my_attr_eff_odt_rd[1][1][0] = 0x0;
+ my_attr_eff_odt_rd[1][1][1] = 0x0;
+ my_attr_eff_odt_rd[1][1][2] = 0x0;
+ my_attr_eff_odt_rd[1][1][3] = 0x0;
+ uint8_t my_attr_eff_odt_wr[PORT_SIZE][DIMM_SIZE][RANK_SIZE];
+ my_attr_eff_odt_wr[0][0][0] = 0x0;
+ my_attr_eff_odt_wr[0][0][1] = 0x0;
+ my_attr_eff_odt_wr[0][0][2] = 0x0;
+ my_attr_eff_odt_wr[0][0][3] = 0x0;
+ my_attr_eff_odt_wr[0][1][0] = 0x0;
+ my_attr_eff_odt_wr[0][1][1] = 0x0;
+ my_attr_eff_odt_wr[0][1][2] = 0x0;
+ my_attr_eff_odt_wr[0][1][3] = 0x0;
+ my_attr_eff_odt_wr[1][0][0] = 0x0;
+ my_attr_eff_odt_wr[1][0][1] = 0x0;
+ my_attr_eff_odt_wr[1][0][2] = 0x0;
+ my_attr_eff_odt_wr[1][0][3] = 0x0;
+ my_attr_eff_odt_wr[1][1][0] = 0x0;
+ my_attr_eff_odt_wr[1][1][1] = 0x0;
+ my_attr_eff_odt_wr[1][1][2] = 0x0;
+ my_attr_eff_odt_wr[1][1][3] = 0x0;
+
+ // Set attributes
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_CMD, &i_target_mba, my_attr_eff_cen_drv_imp_cmd); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_CNTL, &i_target_mba, my_attr_eff_cen_drv_imp_cntl); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_DQ_DQS, &i_target_mba, my_attr_eff_cen_drv_imp_dq_dqs); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_RCV_IMP_DQ_DQS, &i_target_mba, my_attr_eff_cen_rcv_imp_dq_dqs); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_RD_VREF, &i_target_mba, my_attr_eff_cen_rd_vref); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_CMD, &i_target_mba, my_attr_eff_cen_slew_rate_cmd); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_CNTL, &i_target_mba, my_attr_eff_cen_slew_rate_cntl); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_DQ_DQS, &i_target_mba, my_attr_eff_cen_slew_rate_dq_dqs); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_RON, &i_target_mba, my_attr_eff_dram_ron); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_RTT_NOM, &i_target_mba, my_attr_eff_dram_rtt_nom); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_RTT_WR, &i_target_mba, my_attr_eff_dram_rtt_wr); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_WR_VREF, &i_target_mba, my_attr_eff_dram_wr_vref); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_ODT_RD, &i_target_mba, my_attr_eff_odt_rd); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_ODT_WR, &i_target_mba, my_attr_eff_odt_wr); if(rc) return rc;
+
+ FAPI_INF("%s on %s COMPLETE", PROCEDURE_NAME, i_target_mba.toEcmdString());
+ return rc;
+}
+
+
+
+} // extern "C"
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.H b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.H
new file mode 100644
index 000000000..79c3ad052
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.H
@@ -0,0 +1,75 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: mss_eff_config_termination.H,v 1.1 2012/04/26 00:08:52 asaetow Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_eff_config_termination.H,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_eff_config_termination.H
+// *! DESCRIPTION : Header file for mss_eff_config_termination.
+// *! OWNER NAME : Anuwat Saetow Email: asaetow@us.ibm.com
+// *! BACKUP NAME : Mark Bellows Email: bellows@us.ibm.com
+// *! ADDITIONAL COMMENTS :
+//
+//
+//
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.2 | | |
+// 1.1 | asaetow |25-APR-12| First Draft.
+
+
+#ifndef MSS_EFF_CONFIG_TERMINATION_H_
+#define MSS_EFF_CONFIG_TERMINATION_H_
+
+//----------------------------------------------------------------------
+// My Includes
+//----------------------------------------------------------------------
+
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <fapi.H>
+
+
+typedef fapi::ReturnCode (*mss_eff_config_termination_FP_t)(const fapi::Target i_target_mba);
+
+extern "C" {
+
+//******************************************************************************
+//* name=mss_eff_config_termination, param=i_target_mba, return=ReturnCode
+//******************************************************************************
+fapi::ReturnCode mss_eff_config_termination(const fapi::Target i_target_mba);
+
+} // extern "C"
+
+#endif // MSS_EFF_CONFIG_TERMINATION_H_
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.C b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.C
new file mode 100644
index 000000000..64809e94a
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.C
@@ -0,0 +1,315 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: mss_eff_config_thermal.C,v 1.7 2012/05/04 15:53:44 pardeik Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_eff_config_thermal.C,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_eff_config_thermal
+// *! DESCRIPTION : see additional comments below
+// *! OWNER NAME : Joab Henderson Email: joabhend@us.ibm.com
+// *! BACKUP NAME : Michael Pardeik Email: pardeik@us.ibm.com
+// *! ADDITIONAL COMMENTS :
+//
+// DESCRIPTION:
+// The purpose of this procedure is to set the default throttle and power attributes for dimms in a given system
+// -- The throttles here are intended to be the thermal runtime throttles for dimm/channel N/M
+// -- The power attributes are the slope/intercept values. Note that these values are in cW.
+// -- The values are determined by system based on power/thermal characterization
+// -- Thermal values are system dependent and will need to come from the machine readable workbook
+// -- Power values are going to be based on measurements and uplifted as needed based on voltage, frequency, termination, etc.
+//
+// TODO:
+// 1. Thermal attributes (IPL and Runtime Throttles) need to come from machine readable workbook
+// 2. Uplifts need to be done based on volt, freq, termination, etc.
+// 3. Power values need to be updated/added for the dimms that will be supported
+//
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.7 | pardeik |04-MAY-12| removed typedef from structures, use fapi to define dimm type enums
+// 1.6 | pardeik |10-APR-12| update cdimm power/int default, change power_thermal_values_t to use int32_t instead of uint32_t in order to identify a negative value correctly, added dimm config to the messages printed out
+// 1.5 | pardeik |03-APR-12| fix cdimm size/rank addition to cycle through both mba's
+// 1.4 | pardeik |26-MAR-12| Rewrite to iterate through the MBA's using fapi functions
+// | pardeik |01-DEC-11| Updated to align with procedure definition
+// 1.3 | asaetow |03-NOV-11| Fixed to comply with mss_eff_config_thermal.H
+// 1.2 | asaetow |03-NOV-11| Changed format of file and made function lower case.
+// 1.1 | pardeik |01-NOV-11| First Draft.
+
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <fapi.H>
+#include <mss_eff_config_thermal.H>
+
+extern "C" {
+
+ using namespace fapi;
+
+// Procedures in this file
+ fapi::ReturnCode mss_eff_config_thermal(const fapi::Target & i_target);
+
+//******************************************************************************
+//
+//******************************************************************************
+
+ fapi::ReturnCode mss_eff_config_thermal(const fapi::Target & i_target)
+ {
+
+ fapi::ReturnCode l_rc;
+
+ char procedure_name[32];
+ sprintf(procedure_name, "mss_eff_config_thermal");
+ FAPI_INF("*** Running %s ***", procedure_name);
+
+ enum
+ {
+ CDIMM = fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM,
+ RDIMM = fapi::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM,
+ UDIMM = fapi::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM,
+ LRDIMM = fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM,
+ };
+
+// number of dimms on channel/port
+ enum
+ {
+ SINGLEDROP = 0,
+ DOUBLEDROP = 1,
+ DIMM_CONFIG_TYPES = 2, // count of all possible various dimm configurations on port
+ };
+
+// Structure type for the table that holds dimm power slope and intercept values
+// use int32_t for slope and intercept in case values are entered wrong (ie. negative values will then be flagged)
+ struct power_thermal_values_t
+ {
+ int32_t power_slope;
+ int32_t power_int;
+ };
+ struct power_thermal_data_t
+ {
+ uint32_t dimm_type;
+ uint32_t dimm_size;
+ uint8_t dimm_ranks;
+ power_thermal_values_t data[DIMM_CONFIG_TYPES];
+ };
+// Default values defined here
+ const uint8_t l_num_ports = 2; // number of ports per MBA
+ const uint8_t l_num_dimms = 2; // number of dimms per MBA port
+ const uint32_t l_dimm_power_slope_default = 800; // default power slope for rdimm, udimm, lrdimm
+ const uint32_t l_dimm_power_int_default = 900; // default power intercept for rdimm, udimm, lrdimm
+ const uint32_t l_cdimm_power_slope_default = 2000; // default power slope for cdimm
+ const uint32_t l_cdimm_power_int_default = 700; // default power intercept for cdimm
+ const uint32_t l_dimm_throttle_n_default = 100; // default dimm throttle numerator
+ const uint32_t l_dimm_throttle_d_default = 100; // default dimm throttle denominator
+ const uint32_t l_channel_throttle_n_default = 100; // default channel throttle numerator
+ const uint32_t l_channel_throttle_d_default = 100; // default channel throttle denominator
+// other variables used in this procedure
+ uint8_t port;
+ uint8_t dimm;
+ uint8_t entry;
+ uint8_t l_dimm_type;
+ uint8_t l_dimm_size_array[l_num_ports][l_num_dimms];
+ uint8_t l_dimm_ranks_array[l_num_ports][l_num_dimms];
+ uint32_t l_half_cdimm_size = 0;
+ uint8_t l_half_cdimm_ranks = 0;
+ uint32_t l_list_sz;
+ uint32_t l_power_slope_array[l_num_ports][l_num_dimms];
+ uint32_t l_power_int_array[l_num_ports][l_num_dimms];
+ uint32_t l_power_int_uplift;
+ uint32_t l_dimm_throttle_n_array[l_num_ports][l_num_dimms];
+ uint32_t l_dimm_throttle_d_array[l_num_ports][l_num_dimms];
+ uint32_t l_channel_throttle_n_array[l_num_ports];
+ uint32_t l_channel_throttle_d_array[l_num_ports];
+ uint8_t l_found_entry_in_table;
+ uint8_t l_dimm_config[l_num_ports];
+
+// This sets up the power curve values for the DIMMs
+// NOTE: If a value of zero is in the slope or intercept fields, then the default settings will be used
+// NOTE: Power Slope and Intercept values are in cW
+// NOTE: For CDIMM, the power values need to be based on the dimm within the CDIMM (not based on power for whole CDIMM)
+// DIMM, Size, Ranks, Double drop config power slope and intercept, Single drop config power slope and intercept
+
+ power_thermal_data_t l_power_thermal_values[]=
+ {
+// SINGLE DOUBLE
+// DROP DROP
+// Type, Size, Ranks, slope,int, slope,int
+// RDIMMs - data from P7 based ISDIMMs (1066MHz and 1.35V)
+ { RDIMM, 2, 1, {{ 522, 154}, { 526, 153}}}, // example RDIMM 2GB 1Rx8 2Gb
+ { RDIMM, 4, 2, {{ 472, 187}, { 512, 182}}}, // example RDIMM 4GB 2Rx8 2Gb
+ { RDIMM, 4, 1, {{ 472, 187}, { 512, 182}}}, // example RDIMM 4GB 1Rx8 4Gb
+ { RDIMM, 8, 4, {{ 654, 274}, { 657, 262}}}, // example RDIMM 8GB 4Rx8 2Gb
+ { RDIMM, 8, 2, {{ 654, 274}, { 657, 262}}}, // example RDIMM 8GB 2Rx4 2Gb OR 8GB 2Rx8 4Gb
+ { RDIMM, 16, 4, {{ 770, 458}, { 738, 479}}}, // example RDIMM 16GB 4Rx4 2Gb
+ { RDIMM, 16, 2, {{ 770, 458}, { 738, 479}}}, // example RDIMM 16GB 2Rx4 4Gb
+ { RDIMM, 32, 4, {{ 770, 458}, { 738, 479}}}, // example RDIMM 32GB 4Rx4 4Gb
+// CDIMMs - projections based on Warren's dimm support table + 3% spread + 10% uplift
+// power values here are HALF of the cdimm power (since we handle one mba at a time) - need to divide this up and give each dimm an equal power amount
+// SingleDrop DoubleDrop
+// TYPE Size/X, Ranks/X, Slope,Int, Slope, Int
+// where X=number of MBA port pairs populated on CDIMM
+ { CDIMM, 16/2, 4/2, {{ 957, 153}, { 957, 153}}}, // example short CDIMM 16GB 4Rx8 4Gb OR 8GB 2Rx8 4Gb (Channel A/B populated)
+ { CDIMM, 32/2, 8/2, {{1130, 254}, {1130, 254}}}, // example short CDIMM 32GB 4Rx8 4Gb
+ { CDIMM, 64/2, 8/2, {{1763, 469}, {1763, 469}}}, // example short CDIMM 64GB 4Rx4 4Gb
+ { CDIMM, 128/2, 8/2, {{1763, 599}, {1763, 599}}}, // example tall CDIMM 128GB 4Rx4 4Gb (2H 3DS)
+// UDIMMs
+// LRDIMMs
+ };
+ l_list_sz = (sizeof(l_power_thermal_values))/(sizeof(power_thermal_data_t));
+
+// Get input attributes
+ l_rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target, l_dimm_type);
+ if(l_rc) return l_rc;
+ l_rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_SIZE, &i_target, l_dimm_size_array);
+ if(l_rc) return l_rc;
+ l_rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target, l_dimm_ranks_array);
+ if(l_rc) return l_rc;
+
+// Add up DIMM Size and Ranks if a CDIMM - this will be for half of the cdimm - and dimm config for each mba port (1 or 2 dimms per channel)
+ for (port=0; port < l_num_ports; port++)
+ {
+ l_dimm_config[port] = 0;
+ for (dimm=0; dimm < l_num_dimms; dimm++)
+ {
+ if ((l_dimm_type == CDIMM) && (l_dimm_ranks_array[port][dimm] > 0))
+ {
+ l_half_cdimm_size = l_half_cdimm_size + l_dimm_size_array[port][dimm];
+ l_half_cdimm_ranks = l_half_cdimm_ranks + l_dimm_ranks_array[port][dimm];
+ }
+ if (l_dimm_ranks_array[port][dimm] > 0)
+ {
+ l_dimm_config[port]++;
+ }
+ }
+ if (l_dimm_config[port] == 1)
+ {
+ l_dimm_config[port] = SINGLEDROP;
+ }
+ else if (l_dimm_config[port] == 2)
+ {
+ l_dimm_config[port] = DOUBLEDROP;
+ }
+ else
+ {
+ l_dimm_config[port] = DIMM_CONFIG_TYPES;
+ }
+ }
+
+
+// iterate through the MBA ports to define power and thermal attributes
+ for (port=0; port < l_num_ports; port++)
+ {
+// initialize entries to zero
+ l_channel_throttle_n_array[port] = 0;
+ l_channel_throttle_d_array[port] = 0;
+ for (dimm=0; dimm < l_num_dimms; dimm++)
+ {
+// initialize entries to zero
+ l_dimm_throttle_n_array[port][dimm] = 0;
+ l_dimm_throttle_d_array[port][dimm] = 0;
+ l_power_slope_array[port][dimm] = 0;
+ l_power_int_array[port][dimm] = 0;
+// only update values for dimms that are physically present (with default value or table entry value)
+ if (l_dimm_ranks_array[port][dimm] > 0)
+ {
+// TODO: Placeholder for thermal attributes from machine readable workbook (runtime throttles) - Hardcode these for now. IPL throttles will need to be added into an initfile once available.
+// Can remove this section once infrastructure is in place to get these from the MRW (probably done in a different firmware procedure)
+ l_dimm_throttle_n_array[port][dimm] = l_dimm_throttle_n_default;
+ l_dimm_throttle_d_array[port][dimm] = l_dimm_throttle_d_default;
+ l_channel_throttle_n_array[port] = l_channel_throttle_n_default;
+ l_channel_throttle_d_array[port] = l_channel_throttle_d_default;
+// Look up DIMM in Table, get size and ranks first, set slope/int to default values first in case entry is not found in table
+// If table entry is less than zero, then set value to default values
+ if (l_dimm_type == CDIMM)
+ {
+ l_dimm_size_array[port][dimm] = l_half_cdimm_size;
+ l_dimm_ranks_array[port][dimm] = l_half_cdimm_ranks;
+ l_power_slope_array[port][dimm] = l_cdimm_power_slope_default;
+ l_power_int_array[port][dimm] = l_cdimm_power_int_default;
+ }
+ else
+ {
+ l_power_slope_array[port][dimm] = l_dimm_power_slope_default;
+ l_power_int_array[port][dimm] = l_dimm_power_int_default;
+ }
+ l_found_entry_in_table = 0;
+ for (entry = 0; entry < l_list_sz; entry++) {
+ if ((l_power_thermal_values[entry].dimm_type == l_dimm_type) && (l_power_thermal_values[entry].dimm_size == l_dimm_size_array[port][dimm]) && (l_power_thermal_values[entry].dimm_ranks == l_dimm_ranks_array[port][dimm]))
+ {
+ if ((l_power_thermal_values[entry].data[l_dimm_config[port]].power_slope > 0) && (l_power_thermal_values[entry].data[l_dimm_config[port]].power_int > 0))
+ {
+ l_power_slope_array[port][dimm]=l_power_thermal_values[entry].data[l_dimm_config[port]].power_slope;
+ l_power_int_array[port][dimm]=l_power_thermal_values[entry].data[l_dimm_config[port]].power_int;
+ FAPI_INF("Found DIMM Entry in Power Table [%d:%d:%d:%d:%d:%d][%d:%d]", port, dimm, l_dimm_type, l_dimm_size_array[port][dimm], l_dimm_ranks_array[port][dimm], l_dimm_config[port], l_power_slope_array[port][dimm], l_power_int_array[port][dimm]);
+ }
+ else
+ {
+ FAPI_ERR( "DIMM Entry in Power Table not greater than zero, so default values will be used [%d:%d:%d:%d:%d:%d][%d:%d]", port, dimm, l_dimm_type, l_dimm_size_array[port][dimm], l_dimm_ranks_array[port][dimm], l_dimm_config[port], l_power_slope_array[port][dimm], l_power_int_array[port][dimm]);
+ }
+// break out since first match was found
+ l_found_entry_in_table = 1;
+ break;
+ }
+ }
+// Apply any uplifts to the Slope or intercept values based on various parameters if entry is found in table
+// TODO: What uplifts do we need to do (Frequency, Voltage, Termination, etc) - Use zero uplift for now.
+ if (l_found_entry_in_table == 1)
+ {
+ l_power_int_uplift = 0;
+ l_power_int_array[port][dimm] = l_power_int_array[port][dimm] + l_power_int_uplift;
+ }
+// post error if entry was not found
+ else
+ {
+ FAPI_ERR( "Failed to Find DIMM Entry in Power Table, so default values will be used [%d:%d:%d:%d:%d:%d][%d:%d]", port, dimm, l_dimm_type, l_dimm_size_array[port][dimm], l_dimm_ranks_array[port][dimm], l_dimm_config[port], l_power_slope_array[port][dimm], l_power_int_array[port][dimm] );
+ }
+ }
+ }
+ }
+// write output attributes
+ l_rc = FAPI_ATTR_SET(ATTR_MSS_POWER_SLOPE, &i_target, l_power_slope_array);
+ if(l_rc) return l_rc;
+ l_rc = FAPI_ATTR_SET(ATTR_MSS_POWER_INT, &i_target, l_power_int_array);
+ if(l_rc) return l_rc;
+ l_rc = FAPI_ATTR_SET(ATTR_MSS_THROTTLE_NUMERATOR, &i_target, l_dimm_throttle_n_array);
+ if(l_rc) return l_rc;
+ l_rc = FAPI_ATTR_SET(ATTR_MSS_THROTTLE_DENOMINATOR, &i_target, l_dimm_throttle_d_array);
+ if(l_rc) return l_rc;
+ l_rc = FAPI_ATTR_SET(ATTR_MSS_THROTTLE_CHANNEL_NUMERATOR, &i_target, l_channel_throttle_n_array);
+ if(l_rc) return l_rc;
+ l_rc = FAPI_ATTR_SET(ATTR_MSS_THROTTLE_CHANNEL_DENOMINATOR, &i_target, l_channel_throttle_d_array);
+ if(l_rc) return l_rc;
+
+ FAPI_INF("*** %s COMPLETE ***", procedure_name);
+ return l_rc;
+ }
+
+} //end extern C
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.H b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.H
new file mode 100644
index 000000000..a280cbf02
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.H
@@ -0,0 +1,78 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: mss_eff_config_thermal.H,v 1.3 2012/04/03 22:13:03 pardeik Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_eff_config_thermal.H,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_eff_config_thermal.H
+// *! DESCRIPTION : see additional comments below
+// *! OWNER NAME : Joab Henderson Email: joabhend@us.ibm.com
+// *! BACKUP NAME : Michael Pardeik Email: pardeik@us.ibm.com
+// *! ADDITIONAL COMMENTS :
+//
+// Header file for mss_eff_config_thermal.
+//
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.3 | pardeik |03-APR-12| use mba target instead of mbs
+// 1.2 | pardeik |26-MAR-12| Removed structure (going into .C file)
+// | pardeik |01-DEC-11| Added structures and defines
+// 1.1 | asaetow |03-NOV-11| First Draft.
+
+
+
+#ifndef MSS_EFF_CONFIG_THERMAL_H_
+#define MSS_EFF_CONFIG_THERMAL_H_
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <fapi.H>
+
+
+typedef fapi::ReturnCode (*mss_eff_config_thermal_FP_t)(const fapi::Target & i_target);
+
+
+extern "C" {
+/**
+ * @brief mss_eff_config_thermal procedure. Sets up dimm power curve attributes and dimm and channel throttle attributes
+ *
+ * @param[in] i_target Reference to centaur mba target
+ *
+ * @return ReturnCode
+ */
+
+ fapi::ReturnCode mss_eff_config_thermal(const fapi::Target & i_target);
+
+} //extern C
+
+#endif // MSS_EFF_CONFIG_THERMAL_H_
diff --git a/src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.C b/src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.C
new file mode 100644
index 000000000..63162d0d7
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.C
@@ -0,0 +1,436 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/mc_init/mss_freq/mss_freq.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: mss_freq.C,v 1.17 2012/07/17 13:24:13 bellows Exp $
+/* File mss_volt.C created by JEFF SABROWSKI on Fri 21 Oct 2011. */
+
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2007
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_freq.C
+// *! DESCRIPTION : Tools for centaur procedures
+// *! OWNER NAME : Jeff Sabrowski (jsabrow@us.ibm.com)
+// *! BACKUP NAME :
+// #! ADDITIONAL COMMENTS :
+//
+// General purpose funcs
+
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|----------|----------------------------------------------
+// 1.1 | jsabrow | 09/30/11 | Initial draft.
+// 1.2 | bellows | 12/21/11 | fixed function call to mss_freq
+// 1.4 | jsabrow |
+// 1.6 | jdsloat | 05/03/12 | Fixed per Firmware request, added CL calc
+// 1.7 | jdsloat | 05/03/12 | Uncommented Set Attributes
+// 1.8 | jdsloat | 05/07/12 | fixed per Firmware request
+// 1.9 | jdsloat | 05/07/12 | Unused Variables removed
+// 1.11 | jdsloat | 05/07/12 | Uncommented Set Attributes
+// 1.12 | jdsloat | 05/08/12 | Fixed per Firmware request, fixed CL attribute set, fixed MTB usage.
+// 1.13 | jdsloat | 05/09/12 | Fixed per Firmware request
+// 1.14 | jdsloat | 05/10/12 | Fixed per Firmware Request, RC checks, 0 checks
+// 1.15 | jdsloat | 06/04/12 | Added a Configuration check
+// 1.16 | jdsloat | 06/08/12 | Updates per Firware request
+// 1.17 | bellows | 07/16/12 | added in Id tag
+//
+// This procedure takes CENTAUR as argument. for each DIMM (under each MBA)
+// DIMM SPD attributes are read to determine optimal DRAM frequency
+// frequency bins: 800*, 1066*, 1333, 1600, 1866, 2133, 2400*, 2666*
+// (*=not supported in product as of feb'12)
+
+//----------------------------------------------------------------------
+// Includes - FAPI
+//----------------------------------------------------------------------
+#include <fapi.H>
+#include <mss_freq.H>
+
+//----------------------------------------------------------------------
+// ENUMs
+//----------------------------------------------------------------------
+enum {
+ MSS_FREQ_EMPTY = 0,
+ MSS_FREQ_SINGLE_DROP = 1,
+ MSS_FREQ_DUAL_DROP = 2,
+ MSS_FREQ_VALID = 255,
+};
+
+
+using namespace fapi;
+
+fapi::ReturnCode mss_freq(const fapi::Target &i_target_memb)
+{
+
+ // Define attribute array size
+ const uint8_t PORT_SIZE = 2;
+ const uint8_t DIMM_SIZE = 2;
+
+ fapi::ReturnCode l_rc;
+ std::vector<fapi::Target> l_mbaChiplets;
+ std::vector<fapi::Target> l_dimm_targets;
+ uint8_t l_spd_mtb_dividend=0;
+ uint8_t l_spd_mtb_divisor=0;
+ uint32_t l_dimm_freq_calc=0;
+ uint32_t l_dimm_freq_min=9999;
+ uint8_t l_spd_min_tck_MTB=0;
+ uint32_t l_spd_min_tck=0;
+ uint32_t l_spd_min_tck_max=0;
+ uint8_t l_spd_min_taa_MTB=0;
+ uint32_t l_spd_min_taa=0;
+ uint32_t l_spd_min_taa_max=0;
+ uint32_t l_selected_dimm_freq=0;
+ uint32_t l_spd_cas_lat_supported = 0xFFFFFFFF;
+ uint32_t l_spd_cas_lat_supported_all = 0xFFFFFFFF;
+ uint8_t l_cas_latency = 0;
+ uint32_t l_cl_mult_tck = 0;
+ uint8_t cur_mba_port = 0;
+ uint8_t cur_mba_dimm = 0;
+ uint8_t cur_dimm_spd_valid_u8array[PORT_SIZE][DIMM_SIZE] = {{0}};
+ uint8_t plug_config = 0;
+ uint8_t module_type = 0;
+ uint8_t module_type_all = 0;
+ uint8_t num_ranks = 0;
+ uint8_t num_ranks_total = 0;
+
+ // Get associated MBA's on this centaur
+ l_rc=fapiGetChildChiplets(i_target_memb, fapi::TARGET_TYPE_MBA_CHIPLET, l_mbaChiplets);
+ if (l_rc)
+ {
+ FAPI_ERR("Error Getting MBA targets.");
+ return l_rc;
+ }
+ // Loop through the 2 MBA's
+ for (uint32_t i=0; i < l_mbaChiplets.size(); i++)
+ {
+ // Get a vector of DIMM targets
+ l_rc = fapiGetAssociatedDimms(l_mbaChiplets[i], l_dimm_targets);
+ if (l_rc)
+ {
+ FAPI_ERR("Error Getting DIMM targets.");
+ return l_rc;
+ }
+ for (uint32_t j=0; j < l_dimm_targets.size(); j++)
+ {
+
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_MTB_DIVIDEND, &l_dimm_targets[j], l_spd_mtb_dividend);
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read SPD Medium Timebase Dividend.");
+ break;
+ }
+
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_MTB_DIVISOR, &l_dimm_targets[j], l_spd_mtb_divisor);
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read SPD Medium Timebase Divisor.");
+ break;
+ }
+
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_TCKMIN, &l_dimm_targets[j], l_spd_min_tck_MTB);
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read SPD Minimum TCK (Min Clock Cycle).");
+ break;
+ }
+
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_TAAMIN, &l_dimm_targets[j], l_spd_min_taa_MTB);
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read SPD Minimum TAA (Min CAS Latency Time).");
+ break;
+ }
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_CAS_LATENCIES_SUPPORTED, &l_dimm_targets[j], l_spd_cas_lat_supported);
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read SPD Supported CAS Latencies.");
+ break;
+ }
+
+ l_rc = FAPI_ATTR_GET(ATTR_MBA_PORT, &l_dimm_targets[j], cur_mba_port); if(l_rc) return l_rc;
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read the Port Info in order to determine configuration.");
+ break;
+ }
+ l_rc = FAPI_ATTR_GET(ATTR_MBA_DIMM, &l_dimm_targets[j], cur_mba_dimm); if(l_rc) return l_rc;
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read the DIMM Info in order to determine configuration.");
+ break;
+ }
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_TYPE, &l_dimm_targets[j], module_type); if(l_rc) return l_rc;
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read the SPD module type.");
+ break;
+ }
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_NUM_RANKS, &l_dimm_targets[j], num_ranks); if(l_rc) return l_rc;
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read the SPD number of ranks");
+ break;
+ }
+
+ cur_dimm_spd_valid_u8array[cur_mba_port][cur_mba_dimm] = MSS_FREQ_VALID;
+
+ if ((l_spd_min_tck_MTB == 0)||(l_spd_mtb_dividend == 0)||(l_spd_mtb_divisor == 0)||(l_spd_min_taa_MTB == 0))
+ {
+ //Invalid due to the fact that JEDEC dictates that these should be non-zero.
+ FAPI_ERR("Invalid data recieved from SPD within MTB Dividend, MTB Divisor, TCK Min, or TAA Min");
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_UNSUPPORTED_SPD_DATA);
+ break;
+ }
+
+ // Calc done on PS units (the multiplication of 1000) to avoid rounding errors.
+ // Frequency listed with multiplication of 2 as clocking data on both +- edges
+ l_spd_min_tck = ( 1000 * l_spd_min_tck_MTB * l_spd_mtb_dividend ) / l_spd_mtb_divisor;
+ l_spd_min_taa = ( 1000 * l_spd_min_taa_MTB * l_spd_mtb_dividend ) / l_spd_mtb_divisor;
+ if ((l_spd_min_tck == 0)||(l_spd_min_taa == 0))
+ {
+ //Invalid due to the fact that JEDEC dictates that these should be non-zero.
+ FAPI_ERR("Invalid data recieved from SPD causing TCK Min or TAA Min to be 0");
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_UNSUPPORTED_SPD_DATA);
+ break;
+ }
+ l_dimm_freq_calc = 2000000 / l_spd_min_tck;
+
+ //is this the slowest dimm?
+ if (l_dimm_freq_calc < l_dimm_freq_min)
+ {
+ l_dimm_freq_min = l_dimm_freq_calc;
+ }
+
+ if (l_spd_min_tck > l_spd_min_tck_max)
+ {
+ l_spd_min_tck_max = l_spd_min_tck;
+ }
+
+ if (l_spd_min_taa > l_spd_min_taa_max)
+ {
+ l_spd_min_taa_max = l_spd_min_taa;
+ }
+
+ l_spd_cas_lat_supported_all = l_spd_cas_lat_supported_all & l_spd_cas_lat_supported;
+ num_ranks_total = num_ranks_total + num_ranks;
+ if (module_type_all == 0)
+ {
+ module_type_all = module_type;
+ }
+ else if (module_type_all != module_type)
+ {
+ FAPI_ERR("Mixing of DIMM Module Types (%d, %d)", module_type_all, module_type);
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MODULE_TYPE_MIX);
+ }
+
+ }
+ if (l_rc)
+ {
+ break;
+ }
+ }
+
+ //Determining the cnfg for imposing any cnfg speed limitations
+ if ((cur_dimm_spd_valid_u8array[0][0] == MSS_FREQ_VALID) && (cur_dimm_spd_valid_u8array[0][1] == MSS_FREQ_VALID))
+ {
+ plug_config = MSS_FREQ_DUAL_DROP;
+ }
+ else if ((cur_dimm_spd_valid_u8array[0][0] == MSS_FREQ_VALID) && (cur_dimm_spd_valid_u8array[0][1] == MSS_FREQ_EMPTY))
+ {
+ plug_config = MSS_FREQ_SINGLE_DROP;
+ }
+ else
+ {
+ plug_config = MSS_FREQ_EMPTY;
+ }
+
+ // Impose configuration limitations
+ // Single Drop RDIMMs Cnfgs cannot run faster than 1333 unless it only has 1 rank
+ if ((module_type_all == ENUM_ATTR_SPD_MODULE_TYPE_RDIMM)&&(plug_config == MSS_FREQ_SINGLE_DROP)&&(num_ranks_total > 1)&&(l_dimm_freq_min > 1333))
+ {
+ l_dimm_freq_min = 1333;
+ l_spd_min_tck_max = 1500;
+ }
+ // Double Drop RDIMMs Cnfgs cannot run faster than 1333 with 4 ranks total
+ else if ((module_type_all == ENUM_ATTR_SPD_MODULE_TYPE_RDIMM)&&(plug_config == MSS_FREQ_DUAL_DROP)&&(num_ranks_total == 4)&&(l_dimm_freq_min > 1333))
+ {
+ l_dimm_freq_min = 1333;
+ l_spd_min_tck_max = 1500;
+ }
+ // Double Drop RDIMMs Cnfgs cannot run faster than 1066 with 8 ranks total
+ else if ((module_type_all == ENUM_ATTR_SPD_MODULE_TYPE_RDIMM)&&(plug_config == MSS_FREQ_DUAL_DROP)&&(num_ranks_total == 8)&&(l_dimm_freq_min > 1066))
+ {
+ l_dimm_freq_min = 1066;
+ l_spd_min_tck_max = 1875;
+ }
+ // Single Drop LRDIMMs Cnfgs cannot run faster than 1333 with greater than 2 ranks
+ else if ((module_type_all == ENUM_ATTR_SPD_MODULE_TYPE_LRDIMM)&&(plug_config == MSS_FREQ_SINGLE_DROP)&&(num_ranks_total > 2)&&(l_dimm_freq_min > 1333))
+ {
+ l_dimm_freq_min = 1333;
+ l_spd_min_tck_max = 1500;
+ }
+ // Dual Drop LRDIMMs Cnfgs cannot run faster than 1333
+ else if ((module_type_all == ENUM_ATTR_SPD_MODULE_TYPE_LRDIMM)&&(plug_config == MSS_FREQ_DUAL_DROP)&&(l_dimm_freq_min > 1333))
+ {
+ l_dimm_freq_min = 1333;
+ l_spd_min_tck_max = 1500;
+ }
+
+ FAPI_INF( "PLUG CONFIG: %d Type O' Dimm: 0x%02X Num Ranks: %d", plug_config, module_type, num_ranks);
+
+ if ((l_spd_cas_lat_supported_all == 0) && (!l_rc))
+ {
+ FAPI_ERR("No common supported CAS latencies between DIMMS.");
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_NO_COMMON_SUPPORTED_CL);
+ }
+
+ if (!l_rc)
+ {
+
+ //Determine a proposed CAS latency
+ l_cas_latency = l_spd_min_taa_max / l_spd_min_tck_max;
+ if ( l_spd_min_taa_max % l_spd_min_tck_max)
+ {
+ l_cas_latency++;
+ }
+ l_cl_mult_tck = l_cas_latency * l_spd_min_tck_max;
+
+ // If the CL proposed is not supported or the TAA exceeds TAA max
+ // Spec defines tAAmax as 20 ns for all DDR3 speed grades.
+ while ((!( l_spd_cas_lat_supported_all & (0x00000001<<(l_cas_latency-4)))) || (l_cl_mult_tck > 20000))
+ {
+ // If not supported, increment the CL up to 18 (highest supported CL) looking for Supported CL
+ while ((!( l_spd_cas_lat_supported_all & (0x00000001<<(l_cas_latency-4))))&&(l_cas_latency < 18))
+ {
+ l_cas_latency++;
+ }
+
+ // If still not supported CL or TAA is > 20 ns ... pick a slower TCK and start again
+ l_cl_mult_tck = l_cas_latency * l_spd_min_tck_max;
+
+ if ((!( l_spd_cas_lat_supported_all & (0x00000001<<(l_cas_latency-4)))) || (l_cl_mult_tck > 20000))
+ {
+ if (l_spd_min_tck_max < 1500)
+ {
+ //1600 to 1333
+ l_spd_min_tck_max = 1500;
+
+ }
+ else if (l_spd_min_tck_max < 1875)
+ {
+ //1333 to 1066
+ l_spd_min_tck_max = 1875;
+ }
+ else if (l_spd_min_tck_max < 2500)
+ {
+ //1066 to 800
+ l_spd_min_tck_max = 2500;
+ }
+ else
+ {
+ //This is minimum frequency and cannot be lowered
+ FAPI_ERR("Lowered Frequency to TCLK MIN finding no supported CL without exceeding TAA MAX.");
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_EXCEED_TAA_MAX_NO_CL );
+ break;
+ }
+
+ // Re-calculate with new tck
+ l_cas_latency = l_spd_min_taa_max / l_spd_min_tck_max;
+ if ( l_spd_min_taa_max % l_spd_min_tck_max)
+ {
+ l_cas_latency++;
+ }
+ l_cl_mult_tck = l_cas_latency * l_spd_min_tck_max;
+ l_dimm_freq_min = 2000000 / l_spd_min_tck_max;
+
+ }
+ }
+ }
+
+ //bucketize dimm freq.
+ if (!l_rc)
+ {
+ if (l_dimm_freq_min < 1013)
+ {
+ FAPI_ERR("Unsupported frequency: DIMM Freq calculated < 1013 MHz");
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_UNSUPPORTED_FREQ_CALCULATED);
+ }
+ else if (l_dimm_freq_min < 1266)
+ {
+ // 1066
+ l_selected_dimm_freq=1066;
+ }
+ else if (l_dimm_freq_min < 1520)
+ {
+ // 1333
+ l_selected_dimm_freq=1333;
+ }
+ else if (l_dimm_freq_min < 1773)
+ {
+ // 1600
+ l_selected_dimm_freq=1600;
+ }
+ else if (l_dimm_freq_min < 2026)
+ {
+ // 1866
+ l_selected_dimm_freq=1866;
+ }
+ else if (l_dimm_freq_min < 2280)
+ {
+ // 2133
+ l_selected_dimm_freq=2133;
+ }
+ else
+ {
+ FAPI_ERR("Unsupported frequency: DIMM Freq calculated > 2133 MHz: %d", l_dimm_freq_min);
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_UNSUPPORTED_FREQ_CALCULATED);
+ }
+ }
+
+ // set frequency in centaur attribute ATTR_MSS_FREQ
+ if (!l_rc)
+ {
+ l_rc = FAPI_ATTR_SET(ATTR_MSS_FREQ, &i_target_memb, l_selected_dimm_freq);
+ if (l_rc)
+ {
+ return l_rc;
+ }
+ FAPI_INF( "Successfully Calculated Frequency: %d ", l_selected_dimm_freq);
+ FAPI_INF( "Successfully Calculated CL: %d ", l_cas_latency);
+ for (uint32_t k=0; k < l_mbaChiplets.size(); k++)
+ {
+ l_rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_CL, &l_mbaChiplets[k], l_cas_latency);
+ if (l_rc)
+ {
+ return l_rc;
+ }
+ }
+ }
+
+ //all done.
+ return l_rc;
+}
diff --git a/src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.H b/src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.H
new file mode 100644
index 000000000..fbc52308f
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.H
@@ -0,0 +1,72 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: mss_freq.H,v 1.5 2012/07/17 13:22:54 bellows Exp $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_freq.H
+// *! DESCRIPTION : see additional comments below
+// *! OWNER NAME : Jeff Sabrowski Email: jsabrow@us.ibm.com
+// *! BACKUP NAME : Mark Bellows Email: bellows@us.ibm.com
+// *! ADDITIONAL COMMENTS :
+//
+// Header file for mss_freq.
+//
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|---------_|-----------------------------------------------
+// 1.0 | jsabrow | 11/30/11 | initial drop
+// 1.2 | jsabrow | 02/14/12 | Updates for initial code review
+// 1.3 | jdsloat | 04/26/12 | Code review updates
+// 1.5 | bellows | 07/16/12 | added in Id tag
+
+#ifndef MSS_FREQHWPB_H_
+#define MSS_FREQHWPB_H_
+
+#include <fapi.H>
+
+typedef fapi::ReturnCode (*mss_freq_FP_t)(const fapi::Target &);
+
+extern "C"
+{
+
+/**
+ * @brief mss_freq procedure. Determines operating frequency for dimms behind a centaur
+ *
+ * @param[in] fapi::Target &l_targets target type = centaur
+ *
+ * @return ReturnCode
+ */
+
+ fapi::ReturnCode mss_freq(const fapi::Target & i_target);
+
+} // extern "C"
+
+#endif // MSS_FREQHWPB_H_
diff --git a/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt.C b/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt.C
new file mode 100644
index 000000000..8aa152e37
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt.C
@@ -0,0 +1,165 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/mc_init/mss_volt/mss_volt.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: mss_volt.C,v 1.11 2012/07/17 13:24:49 bellows Exp $
+/* File mss_volt.C created by JEFF SABROWSKI on Fri 21 Oct 2011. */
+
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2007
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_volt.C
+// *! DESCRIPTION : Tools for centaur procedures
+// *! OWNER NAME : Jeff Sabrowski (jsabrow@us.ibm.com)
+// *! BACKUP NAME :
+// #! ADDITIONAL COMMENTS :
+//
+// General purpose funcs
+
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|----------|-----------------------------------------------
+// 1.0 | jsabrow | 09/30/11 | Initial draft.
+// 1.1 | jsabrow | 12/13/11 | This version compiles. Attributes dont work yet.
+// 1.3 | bellows | 12/21/11 | fapiGetAssociatedDimms funciton does not work, added quick exit
+// 1.4 | jsabrow | 02/13/12 | Updates for code review
+// 1.5 | jsabrow | 03/26/12 | Updates for code review
+// 1.8 | jdsloat | 04/26/12 | fixed 1.5V issue
+// 1.9 | jdsloat | 05/08/12 | Removed debug message
+// 1.10 | jdsloat | 05/09/12 | Fixed typo
+// 1.11 | bellows | 07/16/12 | added in Id tag
+
+// This procedure takes a vector of Centaurs behind a voltage domain,
+// reads in supported DIMM voltages from SPD and determines optimal
+// voltage bin for the DIMM voltage domain.
+// supported voltage bins: DDR3: 1.35 DDR4: 1.25V (expected)
+
+
+//----------------------------------------------------------------------
+// Includes - FAPI
+//----------------------------------------------------------------------
+#include <fapi.H>
+#include <mss_volt.H>
+
+fapi::ReturnCode mss_volt(std::vector<fapi::Target> & i_targets_memb)
+{
+
+ fapi::ReturnCode l_rc;
+ uint8_t l_spd_dramtype=0;
+ uint8_t l_spd_volts=0;
+ uint8_t l_spd_volts_all_dimms=0x06; //start assuming all voltages supported
+ uint8_t l_dram_ddr3_found_flag=0;
+ uint8_t l_dram_ddr4_found_flag=0;
+
+ uint32_t l_selected_dram_voltage=0; //this gets written into all centaurs when done.
+
+ // Iterate through the list of centaurs
+ for (uint32_t i=0; i < i_targets_memb.size(); i++)
+ {
+ std::vector<fapi::Target> l_mbaChiplets;
+ // Get associated MBA's on this centaur
+ l_rc=fapiGetChildChiplets(i_targets_memb[i], fapi::TARGET_TYPE_MBA_CHIPLET, l_mbaChiplets);
+ if (l_rc) return l_rc;
+ // Loop through the 2 MBA's
+ for (uint32_t j=0; j < l_mbaChiplets.size(); j++)
+ {
+ std::vector<fapi::Target> l_dimm_targets;
+ // Get a vector of DIMM targets
+ l_rc = fapiGetAssociatedDimms(l_mbaChiplets[j], l_dimm_targets);
+ if (l_rc) return l_rc;
+ for (uint32_t k=0; k < l_dimm_targets.size(); k++)
+ {
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_DRAM_DEVICE_TYPE, &l_dimm_targets[k], l_spd_dramtype);
+ if (l_rc) return l_rc;
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_NOMINAL_VOLTAGE, &l_dimm_targets[k], l_spd_volts);
+ if (l_rc) return l_rc;
+
+ // spd_volts: bit0= NOT 1.5V bit1=1.35V bit2=1.25V, assume a 1.20V in future for DDR4
+ // check for supported voltage/dram type combo DDR3=12, DDR4=13
+ if (l_spd_dramtype == fapi::ENUM_ATTR_SPD_DRAM_DEVICE_TYPE_DDR3)
+ {
+ l_dram_ddr3_found_flag=1;
+ }
+ else if (l_spd_dramtype == fapi::ENUM_ATTR_SPD_DRAM_DEVICE_TYPE_DDR4)
+ {
+ l_dram_ddr4_found_flag=1;
+ }
+ else
+ {
+ uint8_t &DEVICE_TYPE = l_spd_dramtype;
+ FAPI_ERR("Unknown DRAM Device Type 0x%x", l_spd_dramtype);
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_VOLT_UNRECOGNIZED_DRAM_DEVICE_TYPE);
+ return l_rc;
+ }
+ //AND dimm voltage capabilities together to find aggregate voltage support on all dimms
+ l_spd_volts_all_dimms = l_spd_volts_all_dimms & l_spd_volts;
+ }
+ }
+ }
+
+ // now we figure out if we have a supported ddr type and voltage
+ // note: only support DDR3=1.35V and DDR4=1.2xV
+
+ if (l_dram_ddr3_found_flag && l_dram_ddr4_found_flag)
+ {
+ FAPI_ERR("mss_volt: DDR3 and DDR4 mixing not allowed");
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_VOLT_DDR_TYPE_MIXING_UNSUPPORTED);
+ return l_rc;
+ }
+ if (l_dram_ddr3_found_flag && ((l_spd_volts_all_dimms & fapi::ENUM_ATTR_SPD_MODULE_NOMINAL_VOLTAGE_OP1_35) == fapi::ENUM_ATTR_SPD_MODULE_NOMINAL_VOLTAGE_OP1_35))
+ {
+ l_selected_dram_voltage=1350;
+ }
+ else if (l_dram_ddr4_found_flag && ((l_spd_volts_all_dimms & fapi::ENUM_ATTR_SPD_MODULE_NOMINAL_VOLTAGE_OP1_2X) == fapi::ENUM_ATTR_SPD_MODULE_NOMINAL_VOLTAGE_OP1_2X))
+ {
+ l_selected_dram_voltage=1200;
+ }
+ else if ((l_spd_volts_all_dimms & fapi::ENUM_ATTR_SPD_MODULE_NOMINAL_VOLTAGE_NOTOP1_5) != fapi::ENUM_ATTR_SPD_MODULE_NOMINAL_VOLTAGE_NOTOP1_5)
+ {
+ l_selected_dram_voltage=1500;
+ }
+ else
+ {
+ FAPI_ERR("One or more DIMMs do not support required voltage for DIMM type");
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_VOLT_DDR_TYPE_REQUIRED_VOLTAGE);
+ return l_rc;
+ }
+
+ // Iterate through the list of centaurs again, to update ATTR
+ for (uint32_t i=0; i < i_targets_memb.size(); i++)
+ {
+ l_rc = FAPI_ATTR_SET(ATTR_MSS_VOLT, &i_targets_memb[i], l_selected_dram_voltage);
+ FAPI_INF( "mss_volt calculation complete. MSS_VOLT: %d", l_selected_dram_voltage);
+ if (l_rc) return l_rc;
+ }
+ return l_rc;
+}
+
+
+
+
diff --git a/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt.H b/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt.H
new file mode 100644
index 000000000..31c0ab4b1
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt.H
@@ -0,0 +1,71 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
+// $Id: mss_volt.H,v 1.5 2012/07/17 13:23:39 bellows Exp $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_volt.H
+// *! DESCRIPTION : see additional comments below
+// *! OWNER NAME : Jeff Sabrowski Email: jsabrow@us.ibm.com
+// *! BACKUP NAME : Mark Bellows Email: bellows@us.ibm.com
+// *! ADDITIONAL COMMENTS :
+//
+// Header file for mss_volt.
+//
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|----------|-----------------------------------------------
+// 1.0 | jsabrow | 11/30/11 | initial drop
+// 1.2 | bellows | 12/21/11 | fixed missing ;
+// 1.4 | jsabrow | 02/14/12 | Updates for code review
+// 1.5 | bellows | 07/16/12 | added $Id tag
+#ifndef MSS_VOLTHWPB_H_
+#define MSS_VOLTHWPB_H_
+
+#include <fapi.H>
+
+typedef fapi::ReturnCode (*mss_volt_FP_t)(std::vector<fapi::Target> &);
+
+extern "C"
+{
+
+/**
+ * @brief mss_volt procedure. Determines operating voltage for dimms behind a voltage domain
+ *
+ * @param[in] std::vector<fapi::Target> l_targets Reference to vector of Centaur Targets in a particular power domain
+ *
+ * @return ReturnCode
+ */
+
+ fapi::ReturnCode mss_volt(std::vector<fapi::Target> & l_targets_memb);
+
+} // extern "C"
+
+#endif // MSS_VOLTHWPB_H_
OpenPOWER on IntegriCloud