summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZane Shelley <zshelle@us.ibm.com>2014-03-14 14:16:52 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-03-20 15:47:37 -0500
commit8df400cb723a3a2d1ded42f8611e9d6065e759fc (patch)
tree3a915cf09f884670659e5ba7b162bd0600ccc587
parent7d87c86e14ad803bb295bc4e3e97e42cce20fd08 (diff)
downloadtalos-hostboot-8df400cb723a3a2d1ded42f8611e9d6065e759fc.tar.gz
talos-hostboot-8df400cb723a3a2d1ded42f8611e9d6065e759fc.zip
HWP update for mss_maint_cmds
Change-Id: Ib036c6cb11126a55a3598cd02628621a2141feb8 CQ: SW252112 Backport: release-fips810 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/9653 Reviewed-by: Zane Shelley <zshelle@us.ibm.com> Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--src/include/usr/hwpf/hwp/utility_procedures/mss_maint_cmds.H33
-rwxr-xr-xsrc/usr/diag/prdf/common/framework/service/prdfPlatServices_common.C4
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_error_support.C221
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_freq/memory_mss_freq.xml77
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.C1468
-rw-r--r--src/usr/hwpf/hwp/utility_procedures/mss_maint_cmds.C16
6 files changed, 1106 insertions, 713 deletions
diff --git a/src/include/usr/hwpf/hwp/utility_procedures/mss_maint_cmds.H b/src/include/usr/hwpf/hwp/utility_procedures/mss_maint_cmds.H
index 9c1031189..59afc8e5e 100644
--- a/src/include/usr/hwpf/hwp/utility_procedures/mss_maint_cmds.H
+++ b/src/include/usr/hwpf/hwp/utility_procedures/mss_maint_cmds.H
@@ -20,7 +20,7 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
-// $Id: mss_maint_cmds.H,v 1.21 2014/03/08 04:03:27 gollub Exp $
+// $Id: mss_maint_cmds.H,v 1.22 2014/03/11 19:04:46 gollub Exp $
//------------------------------------------------------------------------------
// Don't forget to create CVS comments when you check in your changes!
//------------------------------------------------------------------------------
@@ -59,6 +59,8 @@
// 1.19 | 02/07/14 |adityamd | Added support to mss_restore_DRAM_repairs to be accessed at Standby
// 1.20 | 02/20/14 |bellows | RAS update from repairs at standby
// 1.21 | 03/07/14 | gollub | mss_restore_DRAM_repairs_asm: changed i_standby_flag to bool
+// 1.22 | 03/11/14 | gollub | SW250519: More options for enum TimeBaseSpeed
+
#ifndef _MSS_MAINT_CMDS_H
#define _MSS_MAINT_CMDS_H
@@ -296,9 +298,21 @@ static const uint8_t mss_x8_chip_mark_to_centaurDQ[18][2]={
* @brief speed options for time base commands.
*/
enum TimeBaseSpeed
- {
- FAST_AS_POSSIBLE = 0,
- SLOW_12H = 1,
+ {
+ /** Background scrubbing (field). */
+ BG_SCRUB,
+
+ /** Runtime DRAM repairs procedures (field) and the initial fast scrub
+ * of memory (field). */
+ FAST_MIN_BW_IMPACT,
+
+ /** Background scrubbing (mnfg) and the initial fast scrub of memory
+ * (mnfg). */
+ FAST_MED_BW_IMPACT,
+
+ /** IPL time DRAM repairs procedures (field/mnfg) and runtime DRAM
+ * repairs procedures (mnfg). */
+ FAST_MAX_BW_IMPACT,
};
@@ -460,7 +474,7 @@ static const uint8_t mss_x8_chip_mark_to_centaurDQ[18][2]={
/**
* @brief Loads timebase speed into hw.
- * @param i_speed FAST_AS_POSSIBLE or SLOW_12H
+ * @param i_speed See enum TimeBaseSpeed
* @return Non-SUCCESS if an internal function fails, SUCCESS otherwise.
*/
virtual fapi::ReturnCode loadSpeed(TimeBaseSpeed i_speed);
@@ -775,7 +789,7 @@ static const uint8_t mss_x8_chip_mark_to_centaurDQ[18][2]={
mss_TimeBaseScrub( const fapi::Target & i_target, // MBA target
const ecmdDataBufferBase & i_startAddr, // Address cmd will start at
const ecmdDataBufferBase & i_endAddr, // Address cmd will stop at
- TimeBaseSpeed i_speed, // Fast as possible, or slow (all memory on the MBA in 12h)
+ TimeBaseSpeed i_speed, // See enum TimeBaseSpeed
uint32_t i_stopCondition, // Mask of error conditions cmd should stop on
bool i_poll ); // Set to true if you wait for command to complete
@@ -813,7 +827,7 @@ static const uint8_t mss_x8_chip_mark_to_centaurDQ[18][2]={
// here for now
uint32_t iv_savedData;
-// Fast as possible, or slow (all memory on the MBA in 12h)
+// See enum TimeBaseSpeed
TimeBaseSpeed iv_speed;
};
@@ -828,7 +842,7 @@ static const uint8_t mss_x8_chip_mark_to_centaurDQ[18][2]={
mss_TimeBaseSteerCleanup( const fapi::Target & i_target, // MBA target
const ecmdDataBufferBase & i_startAddr, // Address cmd will start at
const ecmdDataBufferBase & i_endAddr, // Address cmd will stop at
- TimeBaseSpeed i_speed, // TODO: fast for runtime, faster for ipl?
+ TimeBaseSpeed i_speed, // See enum TimeBaseSpeed
uint32_t i_stopCondition, // Mask of error conditions cmd should stop on
bool i_poll ); // Set to true if you wait for command to complete
@@ -866,8 +880,7 @@ static const uint8_t mss_x8_chip_mark_to_centaurDQ[18][2]={
// here for now
uint32_t iv_savedData;
-// TODO: Want as fast as possible, but IPL may be able to go faster than
-// runtime since no fetch traffic to worry about.
+// See enum TimeBaseSpeed
TimeBaseSpeed iv_speed;
};
diff --git a/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.C b/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.C
index 4489bb0d7..53aeb0593 100755
--- a/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.C
+++ b/src/usr/diag/prdf/common/framework/service/prdfPlatServices_common.C
@@ -722,9 +722,9 @@ mss_MaintCmdWrapper * createMssCmd( mss_MaintCmdWrapper::CmdType i_cmdType,
mss_MaintCmdWrapper * o_cmd = NULL;
- mss_MaintCmd::TimeBaseSpeed cmdSpeed = mss_MaintCmd::SLOW_12H;
+ mss_MaintCmd::TimeBaseSpeed cmdSpeed = mss_MaintCmd::BG_SCRUB;
if ( i_isFastSpeed )
- cmdSpeed = mss_MaintCmd::FAST_AS_POSSIBLE;
+ cmdSpeed = mss_MaintCmd::FAST_MAX_BW_IMPACT;
mss_MaintCmd * cmd = NULL;
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_error_support.C b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_error_support.C
index 4e11554e7..5819eadfb 100644
--- a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_error_support.C
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_error_support.C
@@ -5,7 +5,7 @@
/* */
/* IBM CONFIDENTIAL */
/* */
-/* COPYRIGHT International Business Machines Corp. 2013 */
+/* COPYRIGHT International Business Machines Corp. 2013,2014 */
/* */
/* p1 */
/* */
@@ -20,7 +20,7 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
-// $Id: mss_error_support.C,v 1.1 2013/03/21 19:04:19 bellows Exp $
+// $Id: mss_error_support.C,v 1.3 2014/02/19 13:41:28 bellows Exp $
//------------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2013
@@ -41,7 +41,9 @@
//------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|----------|---------|-----------------------------------------------
-// 1.1 | 03/08/13 | bellows | Initial Version
+// 1.3 | bellows |19-FEB-14| RAS Review Updates
+// 1.2 | bellows | 05/08/13| Fixed error return code checking
+// 1.1 | bellows | 03/08/13| Initial Version
//----------------------------------------------------------------------
// Includes
@@ -55,7 +57,7 @@ using namespace fapi;
// This is the FFDC HWP specially written to collect the data specified by RC_ERROR_MEM_GROUPING
fapi::ReturnCode hwpCollectMemGrouping(const fapi::Target & i_target,fapi::ReturnCode & o_rc)
{
- fapi::ReturnCode l_rc;
+ fapi::ReturnCode l_rc = fapi::FAPI_RC_SUCCESS;
uint32_t _ATTR_PROC_POS;
uint32_t _ATTR_CEN_POS;
@@ -79,139 +81,143 @@ fapi::ReturnCode hwpCollectMemGrouping(const fapi::Target & i_target,fapi::Retur
unsigned i;
- l_rc = FAPI_ATTR_GET(ATTR_POS, &i_target, _ATTR_PROC_POS);
-
- if (l_rc)
+ do
{
- FAPI_ERR("Error reading ATTR_POS (Proc), ignoring");
- }
-
- l_rc = fapiGetChildChiplets(i_target, fapi::TARGET_TYPE_MEMBUF_CHIP, l_memb);
-
- if (l_rc)
- {
- FAPI_ERR("Error fapiGetChildChiplets, ignoring");
- }
-
- for(i=0;i<l_memb.size();i++) {
- l_rc = FAPI_ATTR_GET(ATTR_POS, &l_memb[i], _ATTR_CEN_POS);
-
+ l_rc = FAPI_ATTR_GET(ATTR_POS, &i_target, _ATTR_PROC_POS);
if (l_rc)
{
- FAPI_ERR("Error reading ATTR_POS (cen), ignoring");
+ FAPI_ERR("Error reading ATTR_POS (Proc)");
+ break;
}
- l_rc = fapiGetChildChiplets(l_memb[i], fapi::TARGET_TYPE_MBA_CHIPLET, l_mba_chiplets);
-
+ l_rc = fapiGetChildChiplets(i_target, fapi::TARGET_TYPE_MEMBUF_CHIP, l_memb);
if (l_rc)
{
- FAPI_ERR("Error fapiGetChildChiplets, ignoring");
+ FAPI_ERR("Error fapiGetChildChiplets");
+ break;
}
+ for(i=0;i<l_memb.size();i++)
+ {
+ l_rc = FAPI_ATTR_GET(ATTR_POS, &l_memb[i], _ATTR_CEN_POS);
+ if (l_rc)
+ {
+ FAPI_ERR("Error reading ATTR_POS (cen)");
+ break;
+ }
+
+ l_rc = fapiGetChildChiplets(l_memb[i], fapi::TARGET_TYPE_MBA_CHIPLET, l_mba_chiplets);
+ if (l_rc)
+ {
+ FAPI_ERR("Error fapiGetChildChiplets");
+ break;
+ }
+
+
+ l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &l_mba_chiplets[0], _ATTR_CHIP_UNIT_POS_MBA0);
+ if (l_rc)
+ {
+ FAPI_ERR("Error reading ATTR_CHIP_UNIT_POS (0)");
+ break;
+ }
+
+ l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &l_mba_chiplets[1], _ATTR_CHIP_UNIT_POS_MBA1);
+ if (l_rc)
+ {
+ FAPI_ERR("Error reading ATTR_CHIP_UNIT_POS (1)");
+ break;
+ }
+
+ l_rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_SIZE, &l_mba_chiplets[0], _ATTR_EFF_DIMM_SIZE0);
+ if (l_rc)
+ {
+ FAPI_ERR("Error reading ATTR_EFF_DIMM_SIZE (0)");
+ break;
+ }
+
+ l_rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_SIZE, &l_mba_chiplets[1], _ATTR_EFF_DIMM_SIZE1);
+ if (l_rc)
+ {
+ FAPI_ERR("Error reading ATTR_EFF_DIMM_SIZE (1)");
+ break;
+ }
+ }
- l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &l_mba_chiplets[0], _ATTR_CHIP_UNIT_POS_MBA0);
-
+ l_rc = FAPI_ATTR_GET(ATTR_MSS_INTERLEAVE_ENABLE,&i_target, _ATTR_MSS_INTERLEAVE_ENABLE);
if (l_rc)
{
- FAPI_ERR("Error reading ATTR_CHIP_UNIT_POS (0), ignoring");
+ FAPI_ERR("Error reading ATTR_MSS_INTERLEAVE_ENABLE");
+ break;
}
- l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &l_mba_chiplets[1], _ATTR_CHIP_UNIT_POS_MBA1);
-
+ l_rc = FAPI_ATTR_GET(ATTR_ALL_MCS_IN_INTERLEAVING_GROUP, NULL,_ATTR_ALL_MCS_IN_INTERLEAVING_GROUP); // system level attribute
if (l_rc)
{
- FAPI_ERR("Error reading ATTR_CHIP_UNIT_POS (1), ignoring");
+ FAPI_ERR("Error reading ATTR_ALL_MCS_IN_INTERLEAVING_GROUP");
+ break;
}
- l_rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_SIZE, &l_mba_chiplets[0], _ATTR_EFF_DIMM_SIZE0);
-
+ l_rc = FAPI_ATTR_GET(ATTR_PROC_MEM_BASE,&i_target,_ATTR_PROC_MEM_BASE);
if (l_rc)
{
- FAPI_ERR("Error reading ATTR_EFF_DIMM_SIZE (0), ignoring");
+ FAPI_ERR("Error reading ATTR_PROC_MEM_BASE");
+ break;
}
- l_rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_SIZE, &l_mba_chiplets[1], _ATTR_EFF_DIMM_SIZE1);
-
+ l_rc = FAPI_ATTR_GET(ATTR_PROC_MIRROR_BASE,&i_target,_ATTR_PROC_MIRROR_BASE);
if (l_rc)
{
- FAPI_ERR("Error reading ATTR_EFF_DIMM_SIZE (1), ignoring");
+ FAPI_ERR("Error reading ATTR_PROC_MIRROR_BASE");
+ break;
}
- }
-
- l_rc = FAPI_ATTR_GET(ATTR_MSS_INTERLEAVE_ENABLE,&i_target, _ATTR_MSS_INTERLEAVE_ENABLE);
-
- if (l_rc)
- {
- FAPI_ERR("Error reading ATTR_MSS_INTERLEAVE_ENABLE, ignoring");
- }
-
- l_rc = FAPI_ATTR_GET(ATTR_ALL_MCS_IN_INTERLEAVING_GROUP, NULL,_ATTR_ALL_MCS_IN_INTERLEAVING_GROUP); // system level attribute
-
- if (l_rc)
- {
- FAPI_ERR("Error reading ATTR_ALL_MCS_IN_INTERLEAVING_GROUP, ignoring");
- }
-
- l_rc = FAPI_ATTR_GET(ATTR_PROC_MEM_BASE,&i_target,_ATTR_PROC_MEM_BASE);
-
- if (l_rc)
- {
- FAPI_ERR("Error reading ATTR_PROC_MEM_BASE, ignoring");
- }
-
- l_rc = FAPI_ATTR_GET(ATTR_PROC_MIRROR_BASE,&i_target,_ATTR_PROC_MIRROR_BASE);
-
- if (l_rc)
- {
- FAPI_ERR("Error reading ATTR_PROC_MIRROR_BASE, ignoring");
- }
-
- l_rc = FAPI_ATTR_GET(ATTR_MSS_MEM_MC_IN_GROUP, &i_target, _ATTR_MSS_MEM_MC_IN_GROUP);
-
- if (l_rc)
- {
- FAPI_ERR("Error reading ATTR_MSS_MEM_MC_IN_GROUP, ignoring");
- }
-
- l_rc = FAPI_ATTR_GET(ATTR_PROC_MEM_BASES, &i_target, _ATTR_PROC_MEM_BASES);
-
- if (l_rc)
- {
- FAPI_ERR("Error reading ATTR_PROC_MEM_BASES, ignoring");
- }
-
- l_rc = FAPI_ATTR_GET(ATTR_PROC_MEM_SIZES, &i_target, _ATTR_PROC_MEM_SIZES);
-
- if (l_rc)
- {
- FAPI_ERR("Error reading ATTR_PROC_MEM_SIZES, ignoring");
- }
- l_rc = FAPI_ATTR_GET(ATTR_MSS_MCS_GROUP_32,&i_target, _ATTR_MSS_MCS_GROUP_32);
+ l_rc = FAPI_ATTR_GET(ATTR_MSS_MEM_MC_IN_GROUP, &i_target, _ATTR_MSS_MEM_MC_IN_GROUP);
+ if (l_rc)
+ {
+ FAPI_ERR("Error reading ATTR_MSS_MEM_MC_IN_GROUP");
+ break;
+ }
- if (l_rc)
- {
- FAPI_ERR("Error reading ATTR_MSS_MCS_GROUP_32, ignoring");
- }
+ l_rc = FAPI_ATTR_GET(ATTR_PROC_MEM_BASES, &i_target, _ATTR_PROC_MEM_BASES);
+ if (l_rc)
+ {
+ FAPI_ERR("Error reading ATTR_PROC_MEM_BASES");
+ break;
+ }
- l_rc = FAPI_ATTR_GET(ATTR_PROC_MIRROR_BASES, &i_target, _ATTR_PROC_MIRROR_BASES);
+ l_rc = FAPI_ATTR_GET(ATTR_PROC_MEM_SIZES, &i_target, _ATTR_PROC_MEM_SIZES);
+ if (l_rc)
+ {
+ FAPI_ERR("Error reading ATTR_PROC_MEM_SIZES");
+ break;
+ }
- if (l_rc)
- {
- FAPI_ERR("Error reading ATTR_PROC_MIRROR_BASES, ignoring");
- }
+ l_rc = FAPI_ATTR_GET(ATTR_MSS_MCS_GROUP_32,&i_target, _ATTR_MSS_MCS_GROUP_32);
+ if (l_rc)
+ {
+ FAPI_ERR("Error reading ATTR_MSS_MCS_GROUP_32");
+ break;
+ }
- l_rc = FAPI_ATTR_GET(ATTR_PROC_MIRROR_SIZES, &i_target, _ATTR_PROC_MIRROR_SIZES);
+ l_rc = FAPI_ATTR_GET(ATTR_PROC_MIRROR_BASES, &i_target, _ATTR_PROC_MIRROR_BASES);
+ if (l_rc)
+ {
+ FAPI_ERR("Error reading ATTR_PROC_MIRROR_BASES");
+ break;
+ }
- if (l_rc)
- {
- FAPI_ERR("Error reading ATTR_PROC_MIRROR_SIZES, ignoring");
- }
+ l_rc = FAPI_ATTR_GET(ATTR_PROC_MIRROR_SIZES, &i_target, _ATTR_PROC_MIRROR_SIZES);
+ if (l_rc)
+ {
+ FAPI_ERR("Error reading ATTR_PROC_MIRROR_SIZES");
+ break;
+ }
+ FAPI_ADD_INFO_TO_HWP_ERROR(o_rc, RC_ERROR_MSS_GROUPING_ATTRS);
- FAPI_ADD_INFO_TO_HWP_ERROR(o_rc, RC_ERROR_MSS_GROUPING_ATTRS);
+ }while(0);
- return fapi::FAPI_RC_SUCCESS;
+ return l_rc;
}
fapi::ReturnCode hwpCollectMemFIRs(const fapi::Target & i_target,fapi::ReturnCode & o_rc)
@@ -228,16 +234,15 @@ fapi::ReturnCode hwpCollectMemFIRs(const fapi::Target & i_target,fapi::ReturnCod
l_rc = fapiGetChildChiplets(i_target, fapi::TARGET_TYPE_MBA_CHIPLET, l_mba_chiplets);
if (l_rc)
{
- FAPI_ERR("Error fapiGetChildChiplets, ignoring");
+ FAPI_ERR("Error fapiGetChildChiplets");
+ return l_rc;
}
- for(i=0;i<l_mba_chiplets.size(); i++) {
+ for(i=0;i<l_mba_chiplets.size(); i++)
+ {
const fapi::Target & CENCHIP_MBA = l_mba_chiplets[i];
FAPI_ADD_INFO_TO_HWP_ERROR(o_rc, RC_ERROR_MBA_FIRS);
}
-
-
-
return fapi::FAPI_RC_SUCCESS;
}
diff --git a/src/usr/hwpf/hwp/mc_config/mss_freq/memory_mss_freq.xml b/src/usr/hwpf/hwp/mc_config/mss_freq/memory_mss_freq.xml
index 69e9f3cd3..f210d65f2 100644
--- a/src/usr/hwpf/hwp/mc_config/mss_freq/memory_mss_freq.xml
+++ b/src/usr/hwpf/hwp/mc_config/mss_freq/memory_mss_freq.xml
@@ -5,7 +5,7 @@
<!-- -->
<!-- IBM CONFIDENTIAL -->
<!-- -->
-<!-- COPYRIGHT International Business Machines Corp. 2013 -->
+<!-- COPYRIGHT International Business Machines Corp. 2013,2014 -->
<!-- -->
<!-- p1 -->
<!-- -->
@@ -21,39 +21,106 @@
<!-- -->
<!-- IBM_PROLOG_END_TAG -->
<hwpErrors>
-<!-- $Id: memory_mss_freq.xml,v 1.1 2013/06/19 18:28:07 bellows Exp $ -->
+
+<!-- $Id: memory_mss_freq.xml,v 1.2 2014/03/06 00:11:49 jdsloat Exp $ -->
<!-- For file ../../ipl/fapi/mss_freq.C -->
-<!-- // *! OWNER NAME : Jeff Sabrowski (jsabrow@us.ibm.com) -->
+<!-- // *! OWNER NAME : Jacob Sloat (jdsloat@us.ibm.com) -->
<!-- // *! BACKUP NAME : -->
-<!-- Original Source for RC_MSS_UNSUPPORTED_SPD_DATA memory_errors.xml -->
+<!-- Original Source for RC_MSS_UNSUPPORTED_SPD_DATA_DDR4 memory_errors.xml -->
+ <hwpError>
+ <rc>RC_MSS_UNSUPPORTED_SPD_DATA_DDR4</rc>
+ <description>Invalid SPD data returned.</description>
+ <ffdc>MTB_DDR4</ffdc>
+ <ffdc>FTB_DDR4</ffdc>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+</hwpError>
+
+<!-- Original Source for RC_MSS_UNSUPPORTED_SPD_DATA_DDR3 memory_errors.xml -->
+ <hwpError>
+ <rc>RC_MSS_UNSUPPORTED_SPD_DATA_DDR3</rc>
+ <description>Invalid SPD data returned.</description>
+ <ffdc>MTB_DIVIDEND</ffdc>
+ <ffdc>MTB_DIVISOR</ffdc>
+ <ffdc>FTB_DIVIDEND</ffdc>
+ <ffdc>FTB_DIVISOR</ffdc>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
+</hwpError>
+
+<!-- Original Source for RC_MSS_UNSUPPORTED_SPD_DATA_COMMON memory_errors.xml -->
<hwpError>
- <rc>RC_MSS_UNSUPPORTED_SPD_DATA</rc>
+ <rc>RC_MSS_UNSUPPORTED_SPD_DATA_COMMON</rc>
<description>Invalid SPD data returned.</description>
+ <ffdc>MIN_TCK</ffdc>
+ <ffdc>MIN_TAA</ffdc>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
</hwpError>
<!-- Original Source for RC_MSS_MODULE_TYPE_MIX memory_errors.xml -->
<hwpError>
<rc>RC_MSS_MODULE_TYPE_MIX</rc>
<description>Differing DIMM types in the same configuration.</description>
+ <ffdc>MODULE_TYPE</ffdc>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
</hwpError>
<!-- Original Source for RC_MSS_NO_COMMON_SUPPORTED_CL memory_errors.xml -->
<hwpError>
<rc>RC_MSS_NO_COMMON_SUPPORTED_CL</rc>
<description>Current Configuration has no common supported CL Values.</description>
+ <ffdc>CL_SUPPORTED</ffdc>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
</hwpError>
<!-- Original Source for RC_MSS_EXCEED_TAA_MAX_NO_CL memory_errors.xml -->
<hwpError>
<rc>RC_MSS_EXCEED_TAA_MAX_NO_CL</rc>
<description>Exceeded TAA MAX with Lowest frequency. No compatable CL.</description>
+ <ffdc>CL_SUPPORTED</ffdc>
+ <callout>
+ <target>DIMM_TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>DIMM_TARGET</target>
+ </deconfigure>
</hwpError>
<!-- Original Source for RC_MSS_UNSUPPORTED_FREQ_CALCULATED memory_errors.xml -->
<hwpError>
<rc>RC_MSS_UNSUPPORTED_FREQ_CALCULATED</rc>
<description>The frequency calculated with spd data is not supported by the jedec standards.</description>
+ <ffdc>DIMM_MIN_FREQ</ffdc>
</hwpError>
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
index ea2bb996d..a7e02f6ee 100644
--- a/src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.C
+++ b/src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.C
@@ -20,7 +20,7 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
-// $Id: mss_freq.C,v 1.24 2014/02/18 19:53:48 jdsloat Exp $
+// $Id: mss_freq.C,v 1.27 2014/03/12 21:40:16 jdsloat Exp $
/* File mss_volt.C created by JEFF SABROWSKI on Fri 21 Oct 2011. */
//------------------------------------------------------------------------------
@@ -30,7 +30,7 @@
//------------------------------------------------------------------------------
// *! TITLE : mss_freq.C
// *! DESCRIPTION : Tools for centaur procedures
-// *! OWNER NAME : Jeff Sabrowski (jsabrow@us.ibm.com)
+// *! OWNER NAME : Jacob Sloat (jdsloat@us.ibm.com)
// *! BACKUP NAME :
// #! ADDITIONAL COMMENTS :
//
@@ -64,6 +64,9 @@
// 1.22 | jdsloat | 06/27/13 | Fixed overridng RC error that results in coredump on no centaur SPD info.
// 1.23 | jdsloat | 02/05/14 | Added support for DMI capable frequecies via ATTR_MSS_NEST_CAPABLE_FREQUENCIES
// 1.24 | jdsloat | 02/18/14 | Added support for DDR4
+// 1.25 | jdsloat | 03/05/14 | RAS review Edits -- Error HW callouts
+// 1.26 | jdsloat | 03/12/14 | Fixed an assignment within a boolean expression.
+// 1.27 | jdsloat | 03/12/14 | Fixed inf loop bug associated with edit 1.26
//
// This procedure takes CENTAUR as argument. for each DIMM (under each MBA)
// DIMM SPD attributes are read to determine optimal DRAM frequency
@@ -80,10 +83,10 @@
// ENUMs
//----------------------------------------------------------------------
enum {
- MSS_FREQ_EMPTY = 0,
- MSS_FREQ_SINGLE_DROP = 1,
- MSS_FREQ_DUAL_DROP = 2,
- MSS_FREQ_VALID = 255,
+ MSS_FREQ_EMPTY = 0,
+ MSS_FREQ_SINGLE_DROP = 1,
+ MSS_FREQ_DUAL_DROP = 2,
+ MSS_FREQ_VALID = 255,
};
//----------------------------------------------------------------------
@@ -101,583 +104,888 @@ using namespace fapi;
fapi::ReturnCode mss_freq(const fapi::Target &i_target_memb)
{
- // Define attribute array size
+ // 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;
- uint8_t l_spd_ftb_dividend=0;
- uint8_t l_spd_ftb_divisor=0;
- uint32_t l_dimm_freq_calc=0;
- uint32_t l_dimm_freq_min=9999;
- uint8_t l_spd_min_tck_MTB=0;
- uint8_t l_spd_tck_offset_FTB=0;
- uint8_t l_spd_tck_offset=0;
- uint32_t l_spd_min_tck=0;
- uint32_t l_spd_min_tck_max=0;
- uint8_t l_spd_min_taa_MTB=0;
- uint8_t l_spd_taa_offset_FTB=0;
- uint8_t l_spd_taa_offset=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;
- uint32_t l_freq_override = 0;
- uint8_t l_override_path = 0;
- uint8_t l_nest_capable_frequencies = 0;
- uint8_t l_spd_dram_dev_type;
- uint8_t l_spd_tb_mtb_ddr4=0;
- uint8_t l_spd_tb_ftb_ddr4=0;
- uint8_t l_spd_tckmax_ddr4=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++)
+ fapi::ReturnCode l_rc;
+ std::vector<fapi::Target> l_mbaChiplets;
+ std::vector<fapi::Target> l_dimm_targets;
+ std::vector<fapi::Target> l_dimm_targets_deconfig;
+ uint8_t l_spd_mtb_dividend=0;
+ uint8_t l_spd_mtb_divisor=0;
+ uint8_t l_spd_ftb_dividend=0;
+ uint8_t l_spd_ftb_divisor=0;
+ uint32_t l_dimm_freq_calc=0;
+ uint32_t l_dimm_freq_min=9999;
+ uint8_t l_spd_min_tck_MTB=0;
+ uint8_t l_spd_tck_offset_FTB=0;
+ uint8_t l_spd_tck_offset=0;
+ uint32_t l_spd_min_tck=0;
+ uint32_t l_spd_min_tck_max=0;
+ uint8_t l_spd_min_taa_MTB=0;
+ uint8_t l_spd_taa_offset_FTB=0;
+ uint8_t l_spd_taa_offset=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_deconfig = 0;
+ uint8_t module_type_group_1 = 0;
+ uint8_t module_type_group_2 = 0;
+ uint8_t module_type_group_1_total = 0;
+ uint8_t module_type_group_2_total = 0;
+ uint8_t num_ranks = 0;
+ uint8_t num_ranks_total = 0;
+ uint32_t l_freq_override = 0;
+ uint8_t l_override_path = 0;
+ uint8_t l_nest_capable_frequencies = 0;
+ uint8_t l_spd_dram_dev_type;
+ uint8_t l_spd_tb_mtb_ddr4=0;
+ uint8_t l_spd_tb_ftb_ddr4=0;
+ uint8_t l_spd_tckmax_ddr4=0;
+ uint8_t cl_count_array[20];
+ uint8_t highest_common_cl = 0;
+ uint8_t highest_cl_count = 0;
+ uint8_t lowest_common_cl = 0;
+ uint32_t lowest_cl_count = 0xFFFFFFFF;
+
+ for(uint8_t i=0;i<20;i++)
+ {
+ cl_count_array[i] = 0; // Initializing each element separately
+ }
+ do
{
- // 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_DRAM_DEVICE_TYPE, &l_dimm_targets[j], l_spd_dram_dev_type);
- if (l_rc)
- {
- FAPI_ERR("Unable to read SPD Dram Device Type.");
- break;
- }
- if (l_spd_dram_dev_type == fapi::ENUM_ATTR_SPD_DRAM_DEVICE_TYPE_DDR4)
- {
- // DDR4 ONLY
- FAPI_DBG("DDR4 detected");
-
- l_rc = FAPI_ATTR_GET(ATTR_SPD_TIMEBASE_MTB_DDR4, &l_dimm_targets[j], l_spd_tb_mtb_ddr4);
- if (l_rc)
- {
- FAPI_ERR("Unable to read SPD DDR4 Medium Timebase");
- break;
- }
-
- l_rc = FAPI_ATTR_GET(ATTR_SPD_TIMEBASE_FTB_DDR4, &l_dimm_targets[j], l_spd_tb_ftb_ddr4);
- if (l_rc)
- {
- FAPI_ERR("Unable to read SPD DDR4 Fine Timebase");
- break;
- }
-
- l_rc = FAPI_ATTR_GET(ATTR_SPD_TCKMAX_DDR4, &l_dimm_targets[j], l_spd_tckmax_ddr4);
- if (l_rc)
- {
- FAPI_ERR("Unable to read SPD DDR4 TCK Max");
- break;
- }
-
- if ( (l_spd_tb_mtb_ddr4 == 0)&&(l_spd_tb_ftb_ddr4 == 0))
- {
- // These are now considered constant within DDR4
- // If DDR4 spec changes to include other values, these const's need to be updated
- l_spd_mtb_dividend = DDR4_MTB_DIVIDEND;
- l_spd_mtb_divisor = DDR4_MTB_DIVISOR;
- l_spd_ftb_dividend = DDR4_FTB_DIVIDEND;
- l_spd_ftb_divisor = DDR4_FTB_DIVISOR;
- }
- else
- {
- //Invalid due to the fact that JEDEC dictates that these should be zero.
- FAPI_ERR("Invalid data received from SPD DDR4 MTB/FTB Timebase");
- FAPI_SET_HWP_ERROR(l_rc, RC_MSS_UNSUPPORTED_SPD_DATA);
- break;
- }
-
- }
- else
- {
- // DDR3 ONLY
- FAPI_DBG("DDR3 detected");
-
- 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_FTB_DIVIDEND, &l_dimm_targets[j], l_spd_ftb_dividend);
- if (l_rc)
- {
- FAPI_ERR("Unable to read the SPD FTB dividend");
- break;
- }
- l_rc = FAPI_ATTR_GET(ATTR_SPD_FTB_DIVISOR, &l_dimm_targets[j], l_spd_ftb_divisor);
- if (l_rc)
- {
- FAPI_ERR("Unable to read the SPD FTB divisor");
- break;
- }
- if ( (l_spd_mtb_dividend == 0)||(l_spd_mtb_divisor == 0)||(l_spd_ftb_dividend == 0)||(l_spd_ftb_divisor == 0))
- {
- //Invalid due to the fact that JEDEC dictates that these should be non-zero.
- FAPI_ERR("Invalid data received from SPD within MTB/FTB Dividend, MTB/FTB Divisor");
- FAPI_SET_HWP_ERROR(l_rc, RC_MSS_UNSUPPORTED_SPD_DATA);
- break;
- }
- }
- // common to both DDR3 & DDR4
- 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)
- {
- 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)
- {
- 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)
- {
- FAPI_ERR("Unable to read the SPD module type.");
- break;
- }
- // from dimm_spd_attributes.xml, R1 = 0x00, R2 = 0x01, R3 = 0x02, R4 = 0x03
- l_rc = FAPI_ATTR_GET(ATTR_SPD_NUM_RANKS, &l_dimm_targets[j], num_ranks);
- if (l_rc)
- {
- FAPI_ERR("Unable to read the SPD number of ranks");
- break;
- }
- l_rc = FAPI_ATTR_GET(ATTR_SPD_FINE_OFFSET_TAAMIN, &l_dimm_targets[j], l_spd_taa_offset_FTB);
- if (l_rc)
- {
- FAPI_ERR("Unable to read the SPD TAA offset (FTB)");
- break;
- }
- l_rc = FAPI_ATTR_GET(ATTR_SPD_FINE_OFFSET_TCKMIN, &l_dimm_targets[j], l_spd_tck_offset_FTB);
- if (l_rc)
- {
- FAPI_ERR("Unable to read the SPD TCK offset (FTB)");
- break;
- }
-
- cur_dimm_spd_valid_u8array[cur_mba_port][cur_mba_dimm] = MSS_FREQ_VALID;
-
- if ((l_spd_min_tck_MTB == 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 received from SPD within 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;
-
- FAPI_INF("min tck = %i, taa = %i", l_spd_min_tck, l_spd_min_taa);
- FAPI_INF("FTB tck 0x%x, taa 0x%x",l_spd_tck_offset_FTB,l_spd_taa_offset_FTB);
- // Adjusting by tck offset -- tck offset represented in 2's compliment as it could be positive or negative adjustment
- // No multiplication of 1000 as it is already in picoseconds.
- if (l_spd_tck_offset_FTB & 0x80)
- {
- l_spd_tck_offset_FTB = ~( l_spd_tck_offset_FTB ) + 1;
- l_spd_tck_offset = (l_spd_tck_offset_FTB * l_spd_ftb_dividend ) / l_spd_ftb_divisor;
- l_spd_min_tck = l_spd_min_tck - l_spd_tck_offset;
- FAPI_INF("FTB minus offset %i, min tck %i",l_spd_tck_offset,l_spd_min_tck);
- }
- else
- {
- l_spd_tck_offset = (l_spd_tck_offset_FTB * l_spd_ftb_dividend ) / l_spd_ftb_divisor;
- l_spd_min_tck = l_spd_min_tck + l_spd_tck_offset;
- FAPI_INF("FTB plus offset %i, min tck %i",l_spd_tck_offset,l_spd_min_tck);
- }
-
- // Adjusting by taa offset -- taa offset represented in 2's compliment as it could be positive or negative adjustment
- if (l_spd_taa_offset_FTB & 0x80)
- {
- l_spd_taa_offset_FTB = ~( l_spd_taa_offset_FTB) + 1;
- l_spd_taa_offset = (l_spd_taa_offset_FTB * l_spd_ftb_dividend ) / l_spd_ftb_divisor;
- l_spd_min_taa = l_spd_min_taa - l_spd_taa_offset;
- }
- else
- {
- l_spd_taa_offset = (l_spd_taa_offset_FTB * l_spd_ftb_dividend ) / l_spd_ftb_divisor;
- l_spd_min_taa = l_spd_min_taa + l_spd_taa_offset;
- }
-
- 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 received 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;
-
- FAPI_INF( "TAA(ps): %d TCK(ps): %d Calc'ed Freq for this dimm: %d", l_spd_min_taa, l_spd_min_tck, l_dimm_freq_calc);
-
- //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 + 1;
- 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);
- }
-
- } // end dimm target loop
- if (l_rc)
- {
- break;
- }
- } // end mba target loop
-
- FAPI_INF( "Highest Supported Frequency amongst DIMMs: %d", l_dimm_freq_min);
- FAPI_INF( "Minimum TAA(ps) amongst DIMMs: %d Minimum TCK(ps) amongst DIMMs: %d", l_spd_min_taa_max, l_spd_min_tck_max);
-
- //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;
- }
-
-
- FAPI_INF( "PLUG CONFIG(from SPD): %d, Type of Dimm(from SPD): 0x%02X, Num Ranks(from SPD): %d", plug_config, module_type, num_ranks);
-
- // 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;
- FAPI_INF( "Single Drop RDIMM with more than 1 Rank Cnfg limitation. New Freq: %d", l_dimm_freq_min);
- }
- // 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;
- FAPI_INF( "Dual Drop RDIMM with more than 4 Rank Cnfg limitation. New Freq: %d", l_dimm_freq_min);
- }
- // 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;
- FAPI_INF( "Dual Drop RDIMM with more than 8 Rank Cnfg limitation. New Freq: %d", l_dimm_freq_min);
- }
- // 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;
- FAPI_INF( "Single Drop LRDIMM with more than 2 Rank Cnfg limitation. New Freq: %d", l_dimm_freq_min);
- }
- // 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( "Dual Drop LRDIMM Cnfg limitation. New Freq: %d", l_dimm_freq_min);
- }
-
- if ( l_spd_min_tck_max == 0)
- {
- FAPI_ERR("l_spd_min_tck_max = 0 unable to calculate freq or cl. Possibly no centaurs configured. ");
- FAPI_SET_HWP_ERROR(l_rc, RC_MSS_UNSUPPORTED_SPD_DATA);
- }
-
- if (!l_rc)
- {
- l_rc = FAPI_ATTR_GET(ATTR_MSS_FREQ_OVERRIDE, &i_target_memb, l_freq_override);
- if ( l_freq_override != 0)
- {
- // The relationship is as such
- // l_dimm_freq_min = 2000000 / l_spd_min_tck_max
-
- if (l_freq_override == 1866)
- {
- l_dimm_freq_min = 1866;
- l_spd_min_tck_max = 1072;
- }
-
- if (l_freq_override == 1600)
- {
- l_dimm_freq_min = 1600;
- l_spd_min_tck_max = 1250;
- }
-
- if (l_freq_override == 1333)
- {
- l_dimm_freq_min = 1333;
- l_spd_min_tck_max = 1500;
- }
-
- if (l_freq_override == 1066)
- {
- l_dimm_freq_min = 1066;
- l_spd_min_tck_max = 1875;
- }
-
- FAPI_INF( "Override Frequency Detected: %d", l_dimm_freq_min);
- }
- }
-
- 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;
-
- FAPI_INF( "CL = TAA / TCK ... TAA(ps): %d TCK(ps): %d", l_spd_min_taa_max, l_spd_min_tck_max);
- FAPI_INF( "Calculated CL: %d", l_cas_latency);
-
- if ( l_spd_min_taa_max % l_spd_min_tck_max)
- {
- l_cas_latency++;
- FAPI_INF( "After rounding up ... CL: %d", 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.
- // Break loop if we have an override condition without a solution.
-
- while ( ( (!( l_spd_cas_lat_supported_all & (0x00000001<<(l_cas_latency-4)))) || (l_cl_mult_tck > 20000) )
- && ( l_override_path = 0 ) )
- {
-
- FAPI_INF( "Warning calculated CL is not supported in VPD. Searching for a new CL.");
-
- // 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;
-
- // Do not move freq if using an override freq. Just continue. Hence the overide in this if statement
- if ( ( (!( l_spd_cas_lat_supported_all & (0x00000001<<(l_cas_latency-4)))) || (l_cl_mult_tck > 20000) )
- && ( l_freq_override == 0) )
- {
- FAPI_INF( "No Supported CL works for calculating frequency. Lowering frequency and trying CL Algorithm again.");
-
- 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;
-
- }
- // Need to break the loop in case we reach this condition because no longer modify freq and CL
- // With an overrride
- if ( ( (!( l_spd_cas_lat_supported_all & (0x00000001<<(l_cas_latency-4)))) || (l_cl_mult_tck > 20000) )
- && ( l_freq_override == 1) )
- {
-
- FAPI_INF( "No Supported CL works for override frequency. Using override frequency with an unsupported CL.");
- l_override_path = 1;
- }
- }
- }
-
- //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);
- }
- }
-
- if (!l_rc)
- {
- // 0x03 = capable of both 8.0G/9.6G, 0x01 = capable of 8.0G, 0x02 = capable 9.6G
- if ( l_selected_dimm_freq == 1066)
- {
- l_nest_capable_frequencies = 0x01;
- l_rc = FAPI_ATTR_SET(ATTR_MSS_NEST_CAPABLE_FREQUENCIES, &i_target_memb, l_nest_capable_frequencies);
- }
- else
- {
- l_nest_capable_frequencies = 0x02;
- l_rc = FAPI_ATTR_SET(ATTR_MSS_NEST_CAPABLE_FREQUENCIES, &i_target_memb, l_nest_capable_frequencies);
- }
-
- }
-
- // 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( "Final Chosen Frequency: %d ", l_selected_dimm_freq);
- FAPI_INF( "Final Chosen 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;
+ // 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.");
+ break;
+ }
+ // 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.");
+ break;
+ }
+ for (uint32_t j=0; j < l_dimm_targets.size(); j++)
+ {
+
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_DRAM_DEVICE_TYPE, &l_dimm_targets[j], l_spd_dram_dev_type);
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read SPD Dram Device Type.");
+ break;
+ }
+ if (l_spd_dram_dev_type == fapi::ENUM_ATTR_SPD_DRAM_DEVICE_TYPE_DDR4)
+ {
+ // DDR4 ONLY
+ FAPI_DBG("DDR4 detected");
+
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_TIMEBASE_MTB_DDR4, &l_dimm_targets[j], l_spd_tb_mtb_ddr4);
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read SPD DDR4 Medium Timebase");
+ break;
+ }
+
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_TIMEBASE_FTB_DDR4, &l_dimm_targets[j], l_spd_tb_ftb_ddr4);
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read SPD DDR4 Fine Timebase");
+ break;
+ }
+
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_TCKMAX_DDR4, &l_dimm_targets[j], l_spd_tckmax_ddr4);
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read SPD DDR4 TCK Max");
+ break;
+ }
+
+ if ( (l_spd_tb_mtb_ddr4 == 0)&&(l_spd_tb_ftb_ddr4 == 0))
+ {
+ // These are now considered constant within DDR4
+ // If DDR4 spec changes to include other values, these const's need to be updated
+ l_spd_mtb_dividend = DDR4_MTB_DIVIDEND;
+ l_spd_mtb_divisor = DDR4_MTB_DIVISOR;
+ l_spd_ftb_dividend = DDR4_FTB_DIVIDEND;
+ l_spd_ftb_divisor = DDR4_FTB_DIVISOR;
+ }
+ else
+ {
+
+ //Invalid due to the fact that JEDEC dictates that these should be zero.
+ FAPI_ERR("Invalid data received from SPD DDR4 MTB/FTB Timebase");
+ const uint8_t &MTB_DDR4 = l_spd_tb_mtb_ddr4;
+ const uint8_t &FTB_DDR4 = l_spd_tb_ftb_ddr4;
+ const fapi::Target &DIMM_TARGET = l_dimm_targets[j];
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_UNSUPPORTED_SPD_DATA_DDR4);
+ fapiLogError(l_rc);
+ }
+
+ }
+ else
+ {
+ // DDR3 ONLY
+ FAPI_DBG("DDR3 detected");
+
+ 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_FTB_DIVIDEND, &l_dimm_targets[j], l_spd_ftb_dividend);
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read the SPD FTB dividend");
+ break;
+ }
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_FTB_DIVISOR, &l_dimm_targets[j], l_spd_ftb_divisor);
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read the SPD FTB divisor");
+ break;
+ }
+ if ( (l_spd_mtb_dividend == 0)||(l_spd_mtb_divisor == 0)||(l_spd_ftb_dividend == 0)||(l_spd_ftb_divisor == 0))
+ {
+ //Invalid due to the fact that JEDEC dictates that these should be non-zero.
+ FAPI_ERR("Invalid data received from SPD within MTB/FTB Dividend, MTB/FTB Divisor");
+ const uint8_t &MTB_DIVIDEND = l_spd_mtb_dividend;
+ const uint8_t &MTB_DIVISOR = l_spd_mtb_divisor;
+ const uint8_t &FTB_DIVIDEND = l_spd_ftb_dividend;
+ const uint8_t &FTB_DIVISOR = l_spd_ftb_divisor;
+ const fapi::Target &DIMM_TARGET = l_dimm_targets[j];
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_UNSUPPORTED_SPD_DATA_DDR3);
+ fapiLogError(l_rc);
+ }
+ }
+ // common to both DDR3 & DDR4
+ 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)
+ {
+ 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)
+ {
+ 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)
+ {
+ FAPI_ERR("Unable to read the SPD module type.");
+ break;
+ }
+ // from dimm_spd_attributes.xml, R1 = 0x00, R2 = 0x01, R3 = 0x02, R4 = 0x03
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_NUM_RANKS, &l_dimm_targets[j], num_ranks);
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read the SPD number of ranks");
+ break;
+ }
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_FINE_OFFSET_TAAMIN, &l_dimm_targets[j], l_spd_taa_offset_FTB);
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read the SPD TAA offset (FTB)");
+ break;
+ }
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_FINE_OFFSET_TCKMIN, &l_dimm_targets[j], l_spd_tck_offset_FTB);
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read the SPD TCK offset (FTB)");
+ break;
+ }
+
+ cur_dimm_spd_valid_u8array[cur_mba_port][cur_mba_dimm] = MSS_FREQ_VALID;
+
+ if ((l_spd_min_tck_MTB == 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 received from SPD within TCK Min, or TAA Min");
+ const uint8_t &MIN_TCK = l_spd_min_tck_MTB;
+ const uint8_t &MIN_TAA = l_spd_min_taa_MTB;
+ const fapi::Target &DIMM_TARGET = l_dimm_targets[j];
+ const fapi::Target &TARGET = i_target_memb;
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_UNSUPPORTED_SPD_DATA_COMMON);
+ fapiLogError(l_rc);
+ }
+
+ // 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;
+
+ FAPI_INF("min tck = %i, taa = %i", l_spd_min_tck, l_spd_min_taa);
+ FAPI_INF("FTB tck 0x%x, taa 0x%x",l_spd_tck_offset_FTB,l_spd_taa_offset_FTB);
+ // Adjusting by tck offset -- tck offset represented in 2's compliment as it could be positive or negative adjustment
+ // No multiplication of 1000 as it is already in picoseconds.
+ if (l_spd_tck_offset_FTB & 0x80)
+ {
+ l_spd_tck_offset_FTB = ~( l_spd_tck_offset_FTB ) + 1;
+ l_spd_tck_offset = (l_spd_tck_offset_FTB * l_spd_ftb_dividend ) / l_spd_ftb_divisor;
+ l_spd_min_tck = l_spd_min_tck - l_spd_tck_offset;
+ FAPI_INF("FTB minus offset %i, min tck %i",l_spd_tck_offset,l_spd_min_tck);
+ }
+ else
+ {
+ l_spd_tck_offset = (l_spd_tck_offset_FTB * l_spd_ftb_dividend ) / l_spd_ftb_divisor;
+ l_spd_min_tck = l_spd_min_tck + l_spd_tck_offset;
+ FAPI_INF("FTB plus offset %i, min tck %i",l_spd_tck_offset,l_spd_min_tck);
+ }
+
+ // Adjusting by taa offset -- taa offset represented in 2's compliment as it could be positive or negative adjustment
+ if (l_spd_taa_offset_FTB & 0x80)
+ {
+ l_spd_taa_offset_FTB = ~( l_spd_taa_offset_FTB) + 1;
+ l_spd_taa_offset = (l_spd_taa_offset_FTB * l_spd_ftb_dividend ) / l_spd_ftb_divisor;
+ l_spd_min_taa = l_spd_min_taa - l_spd_taa_offset;
+ }
+ else
+ {
+ l_spd_taa_offset = (l_spd_taa_offset_FTB * l_spd_ftb_dividend ) / l_spd_ftb_divisor;
+ l_spd_min_taa = l_spd_min_taa + l_spd_taa_offset;
+ }
+
+ 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 received from SPD causing TCK Min or TAA Min to be 0");
+ const uint8_t &MIN_TCK = l_spd_min_tck_MTB;
+ const uint8_t &MIN_TAA = l_spd_min_taa_MTB;
+ const fapi::Target &DIMM_TARGET = l_dimm_targets[j];
+ const fapi::Target &TARGET = i_target_memb;
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_UNSUPPORTED_SPD_DATA_COMMON);
+ fapiLogError(l_rc);
+ }
+ l_dimm_freq_calc = 2000000 / l_spd_min_tck;
+
+ FAPI_INF( "TAA(ps): %d TCK(ps): %d Calc'ed Freq for this dimm: %d", l_spd_min_taa, l_spd_min_tck, l_dimm_freq_calc);
+
+ //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;
+ }
+
+ if ( l_spd_cas_lat_supported & 0x00000001 )
+ {
+ cl_count_array[0]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00000002 )
+ {
+ cl_count_array[1]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00000004 )
+ {
+ cl_count_array[2]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00000008 )
+ {
+ cl_count_array[3]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00000010 )
+ {
+ cl_count_array[4]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00000020 )
+ {
+ cl_count_array[5]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00000040 )
+ {
+ cl_count_array[6]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00000080 )
+ {
+ cl_count_array[7]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00000100 )
+ {
+ cl_count_array[8]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00000200 )
+ {
+ cl_count_array[9]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00000400)
+ {
+ cl_count_array[10]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00000800 )
+ {
+ cl_count_array[11]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00001000 )
+ {
+ cl_count_array[12]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00002000 )
+ {
+ cl_count_array[13]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00004000)
+ {
+ cl_count_array[14]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00008000 )
+ {
+ cl_count_array[15]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00010000 )
+ {
+ cl_count_array[16]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00020000 )
+ {
+ cl_count_array[17]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00040000)
+ {
+ cl_count_array[18]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00080000 )
+ {
+ cl_count_array[19]++;
+ }
+ else if ( l_spd_cas_lat_supported & 0x00100000 )
+ {
+ cl_count_array[20]++;
+ }
+
+
+ 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 + 1;
+
+ if ( (module_type_group_1 == module_type) || (module_type_group_1 == 0) )
+ {
+ module_type_group_1 = module_type;
+ module_type_group_1_total++;
+ }
+ else if ( (module_type_group_2 == module_type) || (module_type_group_2 == 0) )
+ {
+ module_type_group_2 = module_type;
+ module_type_group_2_total++;
+ }
+
+ } // end dimm target loop
+ if (l_rc)
+ {
+ break;
+ }
+ } // end mba target loop
+ if (l_rc)
+ {
+ // Break out of do...while(0)
+ break;
+ }
+ // Check for DIMM Module Type Mixing
+ if (module_type_group_2 != 0)
+ {
+ if (module_type_group_1_total > module_type_group_2_total)
+ {
+ module_type_deconfig = module_type_group_1;
+ }
+ else
+ {
+ module_type_deconfig = module_type_group_2;
+ }
+
+ // 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.");
+ break;
+ }
+ for (uint32_t j=0; j < l_dimm_targets.size(); j++)
+ {
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_TYPE, &l_dimm_targets[j], module_type);
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read the SPD module type.");
+ break;
+ }
+ if (module_type == module_type_deconfig)
+ {
+ const fapi::Target &DIMM_TARGET = l_dimm_targets[j];
+ const uint8_t &MODULE_TYPE = module_type;
+ FAPI_ERR("Mixing of DIMM Module Types (%d, %d) deconfiguring minority type: %d", module_type_group_1, module_type_group_2, module_type_deconfig);
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MODULE_TYPE_MIX);
+ fapiLogError(l_rc);
+ }
+ }
+ if (l_rc)
+ {
+ break;
+ }
+ }
+ }
+ if (l_rc)
+ {
+ // Break out of do...while(0)
+ break;
+ }
+ FAPI_INF( "Highest Supported Frequency amongst DIMMs: %d", l_dimm_freq_min);
+ FAPI_INF( "Minimum TAA(ps) amongst DIMMs: %d Minimum TCK(ps) amongst DIMMs: %d", l_spd_min_taa_max, l_spd_min_tck_max);
+
+ //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;
+ }
+
+
+ FAPI_INF( "PLUG CONFIG(from SPD): %d, Type of Dimm(from SPD): 0x%02X, Num Ranks(from SPD): %d", plug_config, module_type, num_ranks);
+
+ // Impose configuration limitations
+ // Single Drop RDIMMs Cnfgs cannot run faster than 1333 unless it only has 1 rank
+ if ((module_type_group_1 == 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;
+ FAPI_INF( "Single Drop RDIMM with more than 1 Rank Cnfg limitation. New Freq: %d", l_dimm_freq_min);
+ }
+ // Double Drop RDIMMs Cnfgs cannot run faster than 1333 with 4 ranks total
+ else if ((module_type_group_1 == 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;
+ FAPI_INF( "Dual Drop RDIMM with more than 4 Rank Cnfg limitation. New Freq: %d", l_dimm_freq_min);
+ }
+ // Double Drop RDIMMs Cnfgs cannot run faster than 1066 with 8 ranks total
+ else if ((module_type_group_1 == 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;
+ FAPI_INF( "Dual Drop RDIMM with more than 8 Rank Cnfg limitation. New Freq: %d", l_dimm_freq_min);
+ }
+ // Single Drop LRDIMMs Cnfgs cannot run faster than 1333 with greater than 2 ranks
+ else if ((module_type_group_1 == 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;
+ FAPI_INF( "Single Drop LRDIMM with more than 2 Rank Cnfg limitation. New Freq: %d", l_dimm_freq_min);
+ }
+ // Dual Drop LRDIMMs Cnfgs cannot run faster than 1333
+ else if ((module_type_group_1 == 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( "Dual Drop LRDIMM Cnfg limitation. New Freq: %d", l_dimm_freq_min);
+ }
+
+ if ( l_spd_min_tck_max == 0)
+ {
+
+ // 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.");
+ break;
+ }
+ for (uint32_t j=0; j < l_dimm_targets.size(); j++)
+ {
+ 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;
+ }
+
+ if ( l_spd_min_tck_MTB == 0 )
+ {
+ FAPI_ERR("l_spd_min_tck_max = 0 unable to calculate freq or cl. Possibly no centaurs configured. ");
+ const uint32_t &MIN_TCK = l_spd_min_tck_max;
+ const uint32_t &MIN_TAA = l_spd_min_taa_max;
+ const fapi::Target &DIMM_TARGET = l_dimm_targets[j];
+ const fapi::Target &TARGET = i_target_memb;
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_UNSUPPORTED_SPD_DATA_COMMON);
+ break;
+ }
+ }
+ if (l_rc)
+ {
+ break;
+ }
+ }
+ }
+
+ if (!l_rc)
+ {
+ l_rc = FAPI_ATTR_GET(ATTR_MSS_FREQ_OVERRIDE, &i_target_memb, l_freq_override);
+ if ( l_freq_override != 0)
+ {
+ // The relationship is as such
+ // l_dimm_freq_min = 2000000 / l_spd_min_tck_max
+
+ if (l_freq_override == 1866)
+ {
+ l_dimm_freq_min = 1866;
+ l_spd_min_tck_max = 1072;
+ }
+
+ if (l_freq_override == 1600)
+ {
+ l_dimm_freq_min = 1600;
+ l_spd_min_tck_max = 1250;
+ }
+
+ if (l_freq_override == 1333)
+ {
+ l_dimm_freq_min = 1333;
+ l_spd_min_tck_max = 1500;
+ }
+
+ if (l_freq_override == 1066)
+ {
+ l_dimm_freq_min = 1066;
+ l_spd_min_tck_max = 1875;
+ }
+
+ FAPI_INF( "Override Frequency Detected: %d", l_dimm_freq_min);
+ }
+ }
+
+
+
+ //If no common supported CL get rid of the minority DIMMs
+ if ((l_spd_cas_lat_supported_all == 0) && (!l_rc))
+ {
+ for(uint8_t i=0;i<20;i++)
+ {
+ if (cl_count_array[i] > highest_cl_count)
+ {
+ highest_common_cl = i;
+ }
+ }
+
+
+ // 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.");
+ break;
+ }
+ for (uint32_t j=0; j < l_dimm_targets.size(); j++)
+ {
+ 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;
+ }
+ if ( !(l_spd_cas_lat_supported & 0x0000001 << highest_common_cl) )
+ {
+ const fapi::Target &DIMM_TARGET = l_dimm_targets[j];
+ const uint32_t &CL_SUPPORTED = l_spd_cas_lat_supported;
+ FAPI_ERR("No common supported CAS latencies between DIMMS.");
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_NO_COMMON_SUPPORTED_CL);
+ fapiLogError(l_rc);
+ }
+ }
+ if (l_rc)
+ {
+ break;
+ }
+ }
+ }
+ if (l_rc)
+ {
+ // Break out of do...while(0)
+ break;
+ }
+ if (!l_rc)
+ {
+
+ //Determine a proposed CAS latency
+ l_cas_latency = l_spd_min_taa_max / l_spd_min_tck_max;
+
+ FAPI_INF( "CL = TAA / TCK ... TAA(ps): %d TCK(ps): %d", l_spd_min_taa_max, l_spd_min_tck_max);
+ FAPI_INF( "Calculated CL: %d", l_cas_latency);
+
+ if ( l_spd_min_taa_max % l_spd_min_tck_max)
+ {
+ l_cas_latency++;
+ FAPI_INF( "After rounding up ... CL: %d", 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.
+ // Break loop if we have an override condition without a solution.
+
+ while ( ( (!( l_spd_cas_lat_supported_all & (0x00000001<<(l_cas_latency-4)))) || (l_cl_mult_tck > 20000) )
+ && ( l_override_path == 0 ) )
+ {
+
+ FAPI_INF( "Warning calculated CL is not supported in VPD. Searching for a new CL.");
+
+ // 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;
+
+ // Do not move freq if using an override freq. Just continue. Hence the overide in this if statement
+ if ( ( (!( l_spd_cas_lat_supported_all & (0x00000001<<(l_cas_latency-4)))) || (l_cl_mult_tck > 20000) )
+ && ( l_freq_override == 0) )
+ {
+ FAPI_INF( "No Supported CL works for calculating frequency. Lowering frequency and trying CL Algorithm again.");
+
+ 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
+ //Therefore we will deconfig the minority dimms.
+ for(uint8_t i=0;i<20;i++)
+ {
+ if (cl_count_array[i] > lowest_cl_count)
+ {
+ lowest_common_cl = i;
+ }
+ }
+
+
+ // 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_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;
+ }
+ if (l_spd_cas_lat_supported & 0x0000001 << lowest_common_cl)
+ {
+ const fapi::Target &DIMM_TARGET = l_dimm_targets[j];
+ const uint32_t &CL_SUPPORTED = l_spd_cas_lat_supported;
+ 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 );
+ fapiLogError(l_rc);
+ }
+ }
+ if (l_rc)
+ {
+ break;
+ }
+ }
+ }
+ if (l_rc)
+ {
+ // Break out of while loop
+ 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;
+
+ }
+ // Need to break the loop in case we reach this condition because no longer modify freq and CL
+ // With an overrride
+ if ( ( (!( l_spd_cas_lat_supported_all & (0x00000001<<(l_cas_latency-4)))) || (l_cl_mult_tck > 20000) )
+ && ( l_freq_override != 0) )
+ {
+
+ FAPI_INF( "No Supported CL works for override frequency. Using override frequency with an unsupported CL.");
+ l_override_path = 1;
+ }
+ }
+ }
+ if (l_rc)
+ {
+ // Break out of do...while(0)
+ break;
+ }
+ //bucketize dimm freq.
+ if (!l_rc)
+ {
+ if (l_dimm_freq_min < 1013)
+ {
+ FAPI_ERR("Unsupported frequency: DIMM Freq calculated < 1013 MHz");
+ const uint32_t &DIMM_MIN_FREQ = l_dimm_freq_min;
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_UNSUPPORTED_FREQ_CALCULATED);
+ break;
+ }
+ 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);
+ const uint32_t &DIMM_MIN_FREQ = l_dimm_freq_min;
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_UNSUPPORTED_FREQ_CALCULATED);
+ break;
+ }
+ }
+
+ if (!l_rc)
+ {
+ // 0x03 = capable of both 8.0G/9.6G, 0x01 = capable of 8.0G, 0x02 = capable 9.6G
+ if ( l_selected_dimm_freq == 1066)
+ {
+ l_nest_capable_frequencies = 0x01;
+ l_rc = FAPI_ATTR_SET(ATTR_MSS_NEST_CAPABLE_FREQUENCIES, &i_target_memb, l_nest_capable_frequencies);
+ }
+ else
+ {
+ l_nest_capable_frequencies = 0x02;
+ l_rc = FAPI_ATTR_SET(ATTR_MSS_NEST_CAPABLE_FREQUENCIES, &i_target_memb, l_nest_capable_frequencies);
+ }
+
+ }
+
+ // 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( "Final Chosen Frequency: %d ", l_selected_dimm_freq);
+ FAPI_INF( "Final Chosen 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;
+ }
+ }
+ }
+ }while(0);
+ //all done.
+ return l_rc;
}
-
-
-
diff --git a/src/usr/hwpf/hwp/utility_procedures/mss_maint_cmds.C b/src/usr/hwpf/hwp/utility_procedures/mss_maint_cmds.C
index a6387be9d..52eb11230 100644
--- a/src/usr/hwpf/hwp/utility_procedures/mss_maint_cmds.C
+++ b/src/usr/hwpf/hwp/utility_procedures/mss_maint_cmds.C
@@ -20,7 +20,7 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
-// $Id: mss_maint_cmds.C,v 1.33 2014/03/08 04:04:21 gollub Exp $
+// $Id: mss_maint_cmds.C,v 1.34 2014/03/11 19:04:19 gollub Exp $
//------------------------------------------------------------------------------
// Don't forget to create CVS comments when you check in your changes!
//------------------------------------------------------------------------------
@@ -94,7 +94,7 @@
// | | | mss_get_dummy_steer_mux
// | | | mss_put_dummy_steer_mux
// | | | SW249600: Adding 1ms delay to allow cmd to stop properly in mss_stopCmd()
-
+// 1.34 |11-MAR-14 | gollub | SW250519: More options for enum TimeBaseSpeed
//------------------------------------------------------------------------------
// Includes
@@ -1878,20 +1878,20 @@ static const uint32_t maintBuffer65thRegs[4][2]={
if(l_rc) return l_rc;
-// FAST_AS_POSSIBLE
- if (i_speed == FAST_AS_POSSIBLE)
+
+ if ( (FAST_MIN_BW_IMPACT == i_speed) ||
+ (FAST_MED_BW_IMPACT == i_speed) ||
+ (FAST_MAX_BW_IMPACT == i_speed) )
{
-// TODO: Need to figure out what fastest possible setting is.
l_burst_window_sel = 0;
l_timebase_sel = 0;
l_timebase_burst_sel = 0;
l_timebase_interval = 512;
-//l_timebase_interval = 32; // DEBUG: speeds up testing
l_burst_window = 0;
l_burst_interval = 0;
}
-// SLOW_12H
- else
+
+ else // BG_SCRUB
{
// Get l_ddr_freq from ATTR_MSS_FREQ
// Possible frequencies are 800, 1066, 1333, 1600, 1866, and 2133 MHz
OpenPOWER on IntegriCloud