summaryrefslogtreecommitdiffstats
path: root/src/usr/hwpf/hwp/dram_training
diff options
context:
space:
mode:
authorThi Tran <thi@us.ibm.com>2014-02-20 08:55:11 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-02-27 14:08:26 -0600
commitcfb19f068394a358ce21fa3976d0aca834bb3030 (patch)
tree4c4991c0704ba668fba38cc1863fd7dc13e63ab6 /src/usr/hwpf/hwp/dram_training
parent495036dd7a20f04e645de933b795d5e66cf52a2b (diff)
downloadtalos-hostboot-cfb19f068394a358ce21fa3976d0aca834bb3030.tar.gz
talos-hostboot-cfb19f068394a358ce21fa3976d0aca834bb3030.zip
INITPROC: Hostboot SW245013 Centaur DMI & training update
Change-Id: I09a9d02c7070a09378220030f16c5ce2b040c38c CQ:SW245013 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/9040 Tested-by: Jenkins Server Reviewed-by: Thi N. Tran <thi@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/hwpf/hwp/dram_training')
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_draminit_mc/mss_draminit_mc.C99
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/memory_mss_generic_shmoo.xml21
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_generic_shmoo.C222
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_draminit_training/mss_draminit_training.C773
4 files changed, 742 insertions, 373 deletions
diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit_mc/mss_draminit_mc.C b/src/usr/hwpf/hwp/dram_training/mss_draminit_mc/mss_draminit_mc.C
index 356b3dc70..7159a0736 100644
--- a/src/usr/hwpf/hwp/dram_training/mss_draminit_mc/mss_draminit_mc.C
+++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_mc/mss_draminit_mc.C
@@ -5,7 +5,7 @@
/* */
/* IBM CONFIDENTIAL */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2013 */
+/* COPYRIGHT International Business Machines Corp. 2012,2014 */
/* */
/* p1 */
/* */
@@ -20,7 +20,7 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
-// $Id: mss_draminit_mc.C,v 1.43 2013/10/28 15:10:24 dcadiga Exp $
+// $Id: mss_draminit_mc.C,v 1.45 2014/02/17 15:16:14 lapietra Exp $
//------------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2011
// *! All Rights Reserved -- Property of IBM
@@ -44,6 +44,8 @@
//------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|----------|---------|-----------------------------------------------
+// 1.45 | dcadiga |14-FEB-14| Periodic Cal Fix for DD2
+// 1.44 | bellows |12-FEB-14| Workaround for ENABLE_RCE_WITH_OTHER_ERRORS_HW246685
// 1.43 | dcadiga |28-OCT-13| Fixed code review comments for parent chip and typos
// 1.42 | dcadiga |16-OCT-13| Fixed Code Review Comments, added DD2.X EC check for parity on 32GB
// 1.41 | dcadiga |16-OCT-13| repeating Brent's test
@@ -353,36 +355,76 @@ ReturnCode mss_enable_periodic_cal (Target& i_target)
if (memcal_iterval != 0)
{
- //Phase Select Fix for DD1.1
+
+
+
+ uint8_t attr_centaur_ec_rdclk_pr_update_hw236658_fixed;
+ rc = FAPI_ATTR_GET(ATTR_CENTAUR_EC_RDCLK_PR_UPDATE_HW236658_FIXED, &i_target, attr_centaur_ec_rdclk_pr_update_hw236658_fixed);
+ if(rc) return rc;
+
+ if(!attr_centaur_ec_rdclk_pr_update_hw236658_fixed){
+
+ //Check EC, Disable Phase Select Update for DD2 HW
+ //Phase Select Fix for DD1.1
+ rc_num = rc_num | data_buffer_64.flushTo0();
+ rc_num = rc_num | data_buffer_64.setBit(52);
+ if(rc_num)
+ {
+ rc.setEcmdError(rc_num);
+ return rc;
+ }
+
+
+ rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P0_0_0x800000120301143F,data_buffer_64);
+ if(rc) return rc;
+ rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P0_1_0x800004120301143F,data_buffer_64);
+ if(rc) return rc;
+ rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P0_2_0x800008120301143F,data_buffer_64);
+ if(rc) return rc;
+ rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P0_3_0x80000C120301143F,data_buffer_64);
+ if(rc) return rc;
+ rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P0_4_0x800010120301143F,data_buffer_64);
+ if(rc) return rc;
+
+ rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P1_0_0x800100120301143F,data_buffer_64);
+ if(rc) return rc;
+ rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P1_1_0x800104120301143F,data_buffer_64);
+ if(rc) return rc;
+ rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P1_2_0x800108120301143F,data_buffer_64);
+ if(rc) return rc;
+ rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P1_3_0x80010C120301143F,data_buffer_64);
+ if(rc) return rc;
+ rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P1_4_0x800110120301143F,data_buffer_64);
+
+
+ }
+
+ //Disable Periodic Read Centering for ALL HW
rc_num = rc_num | data_buffer_64.flushTo0();
- rc_num = rc_num | data_buffer_64.setBit(52);
- if(rc_num)
+ if(rc_num)
{
rc.setEcmdError(rc_num);
return rc;
}
- rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P0_0_0x800000120301143F,data_buffer_64);
- if(rc) return rc;
- rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P0_1_0x800004120301143F,data_buffer_64);
- if(rc) return rc;
- rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P0_2_0x800008120301143F,data_buffer_64);
- if(rc) return rc;
- rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P0_3_0x80000C120301143F,data_buffer_64);
- if(rc) return rc;
- rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P0_4_0x800010120301143F,data_buffer_64);
- if(rc) return rc;
+ rc = fapiGetScom(i_target,DPHY01_DDRPHY_PC_PER_CAL_CONFIG_P0_0x8000C00B0301143F,data_buffer_64);
+ rc_num = rc_num | data_buffer_64.clearBit(54);
+ rc = fapiPutScom(i_target,DPHY01_DDRPHY_PC_PER_CAL_CONFIG_P0_0x8000C00B0301143F,data_buffer_64);
+
+
+
+ rc_num = rc_num | data_buffer_64.flushTo0();
+ if(rc_num)
+ {
+ rc.setEcmdError(rc_num);
+ return rc;
+ }
+ rc = fapiGetScom(i_target,DPHY01_DDRPHY_PC_PER_CAL_CONFIG_P1_0x8001C00B0301143F,data_buffer_64);
+ rc_num = rc_num | data_buffer_64.clearBit(54);
+ rc = fapiPutScom(i_target,DPHY01_DDRPHY_PC_PER_CAL_CONFIG_P1_0x8001C00B0301143F,data_buffer_64);
- rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P1_0_0x800100120301143F,data_buffer_64);
- if(rc) return rc;
- rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P1_1_0x800104120301143F,data_buffer_64);
- if(rc) return rc;
- rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P1_2_0x800108120301143F,data_buffer_64);
- if(rc) return rc;
- rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P1_3_0x80010C120301143F,data_buffer_64);
- if(rc) return rc;
- rc = fapiPutScom(i_target,DPHY01_DDRPHY_DP18_RD_DIA_CONFIG5_P1_4_0x800110120301143F,data_buffer_64);
if(rc) return rc;
+
//Mem Cal Enabled
rc_num = rc_num | data_buffer_64.flushTo0();
if(rc_num)
@@ -484,6 +526,15 @@ ReturnCode mss_enable_control_bit_ecc (Target& i_target)
rc_num = rc_num | ecc1_data_buffer_64.clearBit(1);
rc_num = rc_num | ecc1_data_buffer_64.setBit(3);
+ uint8_t attr_centaur_ec_enable_rce_with_other_errors_hw246685;
+ rc = FAPI_ATTR_GET(ATTR_CENTAUR_EC_ENABLE_RCE_WITH_OTHER_ERRORS_HW246685, &i_target, attr_centaur_ec_enable_rce_with_other_errors_hw246685);
+ if(rc) return rc;
+
+ if(attr_centaur_ec_enable_rce_with_other_errors_hw246685) {
+ rc_num = rc_num | ecc0_data_buffer_64.setBit(16);
+ rc_num = rc_num | ecc1_data_buffer_64.setBit(16);
+ }
+
if (rc_num)
{
FAPI_ERR( "mss_enable_control_bit_ecc: Error setting up buffers");
diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/memory_mss_generic_shmoo.xml b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/memory_mss_generic_shmoo.xml
index ef57ff96a..6e6af1b6e 100644
--- a/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/memory_mss_generic_shmoo.xml
+++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/memory_mss_generic_shmoo.xml
@@ -21,7 +21,7 @@
<!-- -->
<!-- IBM_PROLOG_END_TAG -->
<hwpErrors>
-<!-- $Id: memory_mss_generic_shmoo.xml,v 1.2 2014/01/23 20:10:51 sasethur Exp $ -->
+<!-- $Id: memory_mss_generic_shmoo.xml,v 1.3 2014/02/07 16:56:32 sasethur Exp $ -->
<!-- For file ../../ipl/fapi/mss_generic_shmoo.C -->
<!-- // *! OWNER NAME : Abhijit Saurabh Email: abhijit.saurabh@in.ibm.com -->
<!-- // *! BACKUP NAME : Sidhartha Vijay Email: sidvijay@in.ibm.com -->
@@ -31,11 +31,22 @@
<description>
The mss_generic_shmoo file found an MCBIST Failure
</description>
- <ffdc>MCB_STATUS</ffdc>
<callout>
- <target>MBA_CHIPLET</target>
+ <childTargets>
+ <parent>MBA_CHIPLET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ <childPort>MBA_PORT_NUMBER</childPort>
+ <childNumber>MBA_DIMM_NUMBER</childNumber>
+ </childTargets>
<priority>HIGH</priority>
</callout>
+ <deconfigure>
+ <childTargets>
+ <parent>MBA_CHIPLET</parent>
+ <childType>TARGET_TYPE_DIMM</childType>
+ <childPort>MBA_PORT_NUMBER</childPort>
+ <childNumber>MBA_DIMM_NUMBER</childNumber>
+ </childTargets>
+ </deconfigure>
</hwpError>
-
-</hwpErrors>
+</hwpErrors> \ No newline at end of file
diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_generic_shmoo.C b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_generic_shmoo.C
index a634456ab..88a56df88 100644
--- a/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_generic_shmoo.C
+++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_generic_shmoo.C
@@ -21,7 +21,7 @@
/* */
/* IBM_PROLOG_END_TAG */
-// $Id: mss_generic_shmoo.C,v 1.86 2014/01/24 17:18:50 sasethur Exp $
+// $Id: mss_generic_shmoo.C,v 1.87 2014/02/07 16:54:14 sasethur Exp $
// *!***************************************************************************
// *! (C) Copyright International Business Machines Corp. 1997, 1998
// *! All Rights Reserved -- Property of IBM
@@ -40,6 +40,7 @@
//------------------------------------------------------------------------------
// Version:|Author: | Date: | Comment:
// --------|--------|---------|--------------------------------------------------
+// 1.87 |abhijsau|7-Feb-14| added sanity check and error call out for schmoo's , removed printing of disconnected DQS.
// 1.86 |abhijsau|24-Jan-14| Fixed code as per changes in access delay error check
// 1.85 |mjjones |24-Jan-14| Fixed layout and error handling for RAS Review
// 1.84 |abhijit |16-JAN-14| Changed EFF_DIMM_TYPE attribute to ATTR_EFF_CUSTOM_DIMM
@@ -336,6 +337,11 @@ fapi::ReturnCode generic_shmoo::run(const fapi::Target & i_target,
if (rc) return rc;
rc = schmoo_setup_mcb(i_target);
if (rc) return rc;
+
+ //sanity check
+ //rc = sanity_check(i_target);
+ //if (rc) return rc;
+
//Find RIGHT BOUND OR SETUP BOUND
rc = find_bound(i_target, RIGHT);
if (rc) return rc;
@@ -379,6 +385,10 @@ fapi::ReturnCode generic_shmoo::run(const fapi::Target & i_target,
{
rc = schmoo_setup_mcb(i_target);
if (rc) return rc;
+
+ rc = sanity_check(i_target);
+ if (rc) return rc;
+
}
rc = set_all_binary(i_target, RIGHT);
if (rc) return rc;
@@ -482,6 +492,19 @@ fapi::ReturnCode generic_shmoo::sanity_check(const fapi::Target & i_target)
uint8_t l_mcb_status = 0;
uint8_t l_CDarray0[80] = { 0 };
uint8_t l_CDarray1[80] = { 0 };
+
+ uint8_t l_byte, l_rnk;
+ uint8_t l_nibble;
+ uint8_t l_n = 0;
+ uint8_t l_p = 0;
+ uint8_t i_rp = 0;
+ uint8_t rank = 0;
+ uint8_t l_faulted_rank = 255;
+ uint8_t l_faulted_port = 255;
+ uint8_t l_faulted_dimm = 255;
+ uint8_t l_memory_health = 0;
+ uint8_t l_max_byte = 10;
+ //uint8_t l_max_nibble = 20;
struct Subtest_info l_sub_info[30];
@@ -501,12 +524,50 @@ fapi::ReturnCode generic_shmoo::sanity_check(const fapi::Target & i_target)
rc = mcb_error_map(i_target, mcbist_error_map, l_CDarray0, l_CDarray1,
count_bad_dq);
if (rc) return rc;
+
+ for (l_p = 0; l_p < MAX_PORT; l_p++)
+ {
+ for (l_rnk = 0; l_rnk < iv_MAX_RANKS[l_p]; ++l_rnk)
+ {// Byte loop
+ rc = mss_getrankpair(i_target, l_p, 0, &i_rp, valid_rank);
+ if (rc) return rc;
+ rank = valid_rank[l_rnk];
- if (l_mcb_status)
+ l_n = 0;
+ for (l_byte = 0; l_byte < l_max_byte; ++l_byte)
+ {
+ //Nibble loop
+ for (l_nibble = 0; l_nibble < MAX_NIBBLES; ++l_nibble)
+ {
+ if (mcbist_error_map[l_p][l_rnk][l_byte][l_nibble] == 1)
+ {
+ l_memory_health = 1;
+ l_faulted_rank = rank;
+ l_faulted_port = l_p;
+ if(rank>3){
+ l_faulted_dimm = 1;
+ }else{
+ l_faulted_dimm = 0;
+ }
+ break;
+ }
+
+ l_n++;
+
+ }
+ }
+ }
+ }
+
+
+ //////////////// changed the check condition ... The error call out need to gard the dimm=l_faulted_dimm(0 or 1) //// port=l_faulted_port(0 or 1) target=i_target ...
+ if (l_memory_health)
{
- FAPI_ERR("generic_shmoo:sanity_check failed !! MCBIST failed on intial run , memory is not in good state aborting shmoo");
- const uint8_t & MCB_STATUS = l_mcb_status;
+ FAPI_INF("generic_shmoo:sanity_check failed !! MCBIST failed on intial run , memory is not in good state needs investigation port=%d rank=%d dimm=%d",
+ l_faulted_port, l_faulted_rank, l_faulted_dimm);
const fapi::Target & MBA_CHIPLET = i_target;
+ const uint8_t & MBA_PORT_NUMBER = l_faulted_port;
+ const uint8_t & MBA_DIMM_NUMBER = l_faulted_dimm;
FAPI_SET_HWP_ERROR(rc, RC_MSS_GENERIC_SHMOO_MCBIST_FAILED);
return rc;
}
@@ -615,8 +676,7 @@ fapi::ReturnCode generic_shmoo::check_error_map(const fapi::Target & i_target,
uint8_t l_byte_is;
uint8_t l_nibble_is;
uint8_t l_n = 0;
- uint8_t l_i = 0;
- uint8_t l_dq = 0;
+
pass = 1;
uint8_t l_p = 0;
input_type l_input_type_e = ISDIMM_DQ;
@@ -626,6 +686,8 @@ fapi::ReturnCode generic_shmoo::check_error_map(const fapi::Target & i_target,
uint8_t rank = 0;
uint8_t l_max_byte = 10;
uint8_t l_max_nibble = 20;
+ uint8_t l_i = 0;
+ uint8_t l_dq = 0;
uint8_t l_CDarray0[80] = { 0 };
uint8_t l_CDarray1[80] = { 0 };
@@ -3428,7 +3490,7 @@ fapi::ReturnCode generic_shmoo::print_report(const fapi::Target & i_target)
fapi::ReturnCode rc;
uint8_t l_rnk, l_byte, l_nibble, l_bit;
- uint8_t l_dq = 0;
+ //uint8_t l_dq = 0;
uint8_t l_rp = 0;
uint8_t l_p = 0;
uint8_t i_rank = 0;
@@ -3439,9 +3501,23 @@ fapi::ReturnCode generic_shmoo::print_report(const fapi::Target & i_target)
uint8_t l_attr_eff_num_drops_per_port_u8 = 0;
uint8_t l_attr_eff_dram_width_u8 = 0;
uint16_t l_total_margin = 0;
+ uint8_t l_i = 0;
+ uint8_t l_dq = 0;
+ uint8_t l_flag = 0;
+ uint8_t l_CDarray0[80] = { 0 };
+ uint8_t l_CDarray1[80] = { 0 };
+
char * l_pMike = new char[128];
char * l_str = new char[128];
+
+ rc = mcb_error_map(i_target, mcbist_error_map, l_CDarray0, l_CDarray1,
+ count_bad_dq);
+ if (rc)
+ {
+ FAPI_ERR("generic_shmoo::print report: mcb_error_map failed!!");
+ return rc;
+ }
fapi::Target l_target_centaur;
@@ -3484,7 +3560,7 @@ fapi::ReturnCode generic_shmoo::print_report(const fapi::Target & i_target)
//FAPI_INF("%s:num_drops_per_port = %d on %s.", l_attr_eff_num_drops_per_port_u8, i_target.toEcmdString());
//FAPI_INF("%s:num_ranks = %d on %s.", iv_MAX_RANKS,i_target.toEcmdString());
- //FAPI_INF("%s:dram_width = %d on %s. \n\n", l_attr_eff_dram_width_u8, i_target.toEcmdString());
+ FAPI_INF("dram_width = %d \n\n", l_attr_eff_dram_width_u8);
FAPI_INF("%s:+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++",
i_target.toEcmdString());
//// Based on schmoo param the print will change eventually
@@ -3514,7 +3590,37 @@ fapi::ReturnCode generic_shmoo::print_report(const fapi::Target & i_target)
{
//Nibble loop
for (l_nibble = 0; l_nibble < MAX_NIBBLES; ++l_nibble)
- {
+ {
+
+ l_dq=8 * l_byte + 4 * l_nibble;
+ l_flag=0;
+ if (l_p == 0)
+ {
+ for (l_i = 0; l_i < count_bad_dq[0]; l_i++)
+ {
+ if (l_CDarray0[l_i] == l_dq)
+ {
+ l_flag=1;
+
+ }
+ }
+ }
+ else
+ {
+ for (l_i = 0; l_i < count_bad_dq[1]; l_i++)
+ {
+ if (l_CDarray1[l_i] == l_dq)
+ {
+ l_flag=1;
+
+ }
+ }
+ }
+
+ if(l_flag==1)
+ {
+ continue;
+ }
for (l_bit = 0; l_bit < MAX_BITS; ++l_bit)
{
l_dq = 8 * l_byte + 4 * l_nibble + l_bit;
@@ -3569,6 +3675,20 @@ fapi::ReturnCode generic_shmoo::print_report_dqs(const fapi::Target & i_target)
uint8_t l_by8_dqs = 0;
char * l_pMike = new char[128];
char * l_str = new char[128];
+
+ uint8_t l_i = 0;
+ uint8_t l_dq = 0;
+ uint8_t l_flag = 0;
+ uint8_t l_CDarray0[80] = { 0 };
+ uint8_t l_CDarray1[80] = { 0 };
+
+ rc = mcb_error_map(i_target, mcbist_error_map, l_CDarray0, l_CDarray1,
+ count_bad_dq);
+ if (rc)
+ {
+ FAPI_ERR("generic_shmoo::print report: mcb_error_map failed!!");
+ return rc;
+ }
if (iv_dmm_type == 1)
{
@@ -3658,7 +3778,36 @@ fapi::ReturnCode generic_shmoo::print_report_dqs(const fapi::Target & i_target)
l_nibble = l_nibble * 2;
}
}
-
+ l_dq=4* l_nibble;
+ l_flag=0;
+ if (l_p == 0)
+ {
+ for (l_i = 0; l_i < count_bad_dq[0]; l_i++)
+ {
+ if (l_CDarray0[l_i] == l_dq)
+ {
+ l_flag=1;
+
+ }
+ }
+ }
+ else
+ {
+ for (l_i = 0; l_i < count_bad_dq[1]; l_i++)
+ {
+ if (l_CDarray1[l_i] == l_dq)
+ {
+ l_flag=1;
+
+ }
+ }
+ }
+
+ if(l_flag==1)
+ {
+ continue;
+ }
+
l_total_margin
= SHMOO[iv_SHMOO_ON].MBA.P[l_p].S[l_rnk].K.left_margin_val[l_nibble]
+ SHMOO[iv_SHMOO_ON].MBA.P[l_p].S[l_rnk].K.right_margin_val[l_nibble];
@@ -3942,11 +4091,7 @@ fapi::ReturnCode generic_shmoo::get_margin_dqs_by8(const fapi::Target & i_target
SHMOO[iv_SHMOO_ON].MBA.P[l_p].S[l_rnk].K.left_margin_val[l_nibble]
= ((SHMOO[iv_SHMOO_ON].MBA.P[l_p].S[l_rnk].K.curr_val[l_nibble]
- SHMOO[iv_SHMOO_ON].MBA.P[l_p].S[l_rnk].K.lb_regval[l_nibble])
- * l_factor) / l_factor_ps;//((1/uint32_t_freq*1000000)/128);
- //SHMOO[iv_SHMOO_ON].MBA.P[l_p].S[l_rnk].K.total_margin[l_nibble]=SHMOO[iv_SHMOO_ON].MBA.P[l_p].S[l_rnk].K.right_margin_val[l_nibble]+SHMOO[iv_SHMOO_ON].MBA.P[l_p].S[l_rnk].K.left_margin_val[l_nibble];
- // SHMOO[iv_shmoo_type].MBA.P[l_p].S[l_rnk].K.total_margin[l_nibble]=SHMOO[iv_shmoo_type].MBA.P[l_p].S[l_rnk].K.right_margin_val[l_nibble]+SHMOO[iv_shmoo_type].MBA.P[l_p].S[l_rnk].K.left_margin_val[l_nibble];
- //FAPI_INF("\n Abhijit is here after %d and port=%d \n",l_nibble,l_p);
- //FAPI_INF("\n Abhijit is here after 2 %d \n",l_rnk);
+ * l_factor) / l_factor_ps;
}
}
}
@@ -3968,9 +4113,22 @@ fapi::ReturnCode generic_shmoo::get_min_margin(const fapi::Target & i_target,
uint8_t l_rnk, l_byte, l_nibble, l_bit, i_rank;
uint16_t l_temp_right = 4800;
uint16_t l_temp_left = 4800;
- uint8_t l_dq = 0;
+ //uint8_t l_dq = 0;
uint8_t l_rp = 0;
uint8_t l_p = 0;
+ uint8_t l_i = 0;
+ uint8_t l_dq = 0;
+ uint8_t l_flag = 0;
+ uint8_t l_CDarray0[80] = { 0 };
+ uint8_t l_CDarray1[80] = { 0 };
+
+ rc = mcb_error_map(i_target, mcbist_error_map, l_CDarray0, l_CDarray1,
+ count_bad_dq);
+ if (rc)
+ {
+ FAPI_ERR("generic_shmoo::print report: mcb_error_map failed!!");
+ return rc;
+ }
for (l_p = 0; l_p < MAX_PORT; l_p++)
{
@@ -3985,7 +4143,37 @@ fapi::ReturnCode generic_shmoo::get_min_margin(const fapi::Target & i_target,
{
//Nibble loop
for (l_nibble = 0; l_nibble < MAX_NIBBLES; ++l_nibble)
- {
+ {
+ l_dq=8 * l_byte + 4 * l_nibble;
+ l_flag=0;
+ if (l_p == 0)
+ {
+ for (l_i = 0; l_i < count_bad_dq[0]; l_i++)
+ {
+ if (l_CDarray0[l_i] == l_dq)
+ {
+ l_flag=1;
+
+ }
+ }
+ }
+ else
+ {
+ for (l_i = 0; l_i < count_bad_dq[1]; l_i++)
+ {
+ if (l_CDarray1[l_i] == l_dq)
+ {
+ l_flag=1;
+
+ }
+ }
+ }
+
+ if(l_flag==1)
+ {
+ continue;
+ }
+
for (l_bit = 0; l_bit < MAX_BITS; ++l_bit)
{
l_dq = 8 * l_byte + 4 * l_nibble + l_bit;
diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit_training/mss_draminit_training.C b/src/usr/hwpf/hwp/dram_training/mss_draminit_training/mss_draminit_training.C
index f5b739867..b83472316 100644
--- a/src/usr/hwpf/hwp/dram_training/mss_draminit_training/mss_draminit_training.C
+++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_training/mss_draminit_training.C
@@ -5,7 +5,7 @@
/* */
/* IBM CONFIDENTIAL */
/* */
-/* COPYRIGHT International Business Machines Corp. 2012,2013 */
+/* COPYRIGHT International Business Machines Corp. 2012,2014 */
/* */
/* p1 */
/* */
@@ -20,7 +20,7 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
-// $Id: mss_draminit_training.C,v 1.70 2013/11/11 20:51:15 jdsloat Exp $
+// $Id: mss_draminit_training.C,v 1.72 2014/02/15 00:25:56 mwuu Exp $
//------------------------------------------------------------------------------
// Don't forget to create CVS comments when you check in your changes!
//------------------------------------------------------------------------------
@@ -28,11 +28,16 @@
//------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|----------|---------|------------------------------------------------
+// 1.72 | mwuu |14-FEB-14| Fixed x4 spare case when mss_c4_phy returns bad
+// | | | data with workaround
+// 1.71 | mwuu |13-FEB-14| Updated get/setC4dq2reg, mss_set/get_bbm_regs FNs
+// | | | to use access_delay_regs for dq/dqs pin mapping.
+// | | | Added mss_get_dqs_lane helper FN.
// 1.70 | jdsloat | 11/11/13| Changed EFF attributes to VPD named attributes
// 1.69 | jdsloat |06-OCT-13| Removed Control Switch Attribute
// 1.68 | bellows |16-SEP-13| Hostboot compile update
// 1.67 | kcook |13-SEP-13| Updated define FAPI_LRDIMM token.
-// 1.66 | kcook |27-AUG-13| Moved main LRDIMM sections into separate file.
+// 1.66 | kcook |27-AUG-13| Moved main LRDIMM sections into separate file.
// | | | Removed reference to ATTR_LAB_USE_JTAG_MODE.
// | mwuu | | Added ATTR_MSS_DISABLE1_REG_FIXED for bbm FN for DD2.
// 1.65 | kcook |16-AUG-13| Added LRDIMM support. Use with mss_funcs.C v1.32.
@@ -131,6 +136,7 @@
// 1.2 | jdsloat |14-Jul-11| Proper call name fix
// 1.1 | jdsloat |22-Apr-11| Initial draft
+
//----------------------------------------------------------------------
// FAPI function Includes
//----------------------------------------------------------------------
@@ -145,8 +151,7 @@
#include <dimmBadDqBitmapFuncs.H>
#include <mss_unmask_errors.H>
#include <mss_lrdimm_funcs.H>
-
-
+#include "mss_access_delay_reg.H"
#ifndef FAPI_LRDIMM
@@ -172,6 +177,7 @@ const uint8_t MRS1_BA = 1;
const uint8_t MRS2_BA = 2;
#define MAX_PORTS 2
+#define MAX_DIMMS 2
#define MAX_PRI_RANKS 4
#define TOTAL_BYTES 10
#define BITS_PER_REG 16
@@ -204,10 +210,11 @@ ReturnCode mss_read_center_workaround(Target& i_target, uint8_t i_mbaPosition, u
ReturnCode mss_read_center_second_workaround(Target& i_target);
ReturnCode mss_reset_delay_values(Target& i_target);
-ReturnCode getC4dq2reg(const Target &i_mba, const uint8_t i_port, const uint8_t i_dimm, const uint8_t i_rank, ecmdDataBufferBase &o_reg);
-ReturnCode setC4dq2reg(const Target &i_mba, const uint8_t i_port, const uint8_t i_dimm, const uint8_t i_rank, ecmdDataBufferBase &o_reg);
+ReturnCode getC4dq2reg(const Target &i_mba, const uint8_t i_port, const uint8_t i_dimm, const uint8_t i_rank, ecmdDataBufferBase &o_reg, uint8_t &is_clean);
+ReturnCode setC4dq2reg(const Target &i_mba, const uint8_t i_port, const uint8_t i_dimm, const uint8_t i_rank, const ecmdDataBufferBase &i_reg);
ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target);
ReturnCode mss_get_bbm_regs (const fapi::Target & mba_target);
+ReturnCode mss_get_dqs_lane (const fapi::Target & i_mba, const uint8_t i_port, const uint8_t i_block, const uint8_t i_quad, uint8_t &lane);
ReturnCode mss_draminit_training(Target& i_target)
@@ -328,7 +335,7 @@ ReturnCode mss_draminit_training_cloned(Target& i_target)
if(rc) return rc;
uint8_t dimm_type;
- rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target, dimm_type);
+ rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target, dimm_type);
if(rc) return rc;
@@ -3085,7 +3092,7 @@ ReturnCode mss_rtt_nom_rtt_wr_swap(
fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target)
{
// Flash to registers.
- // disable0=dq bits, disable1=dqs (need to use swizzle),
+ // disable0=dq bits, disable1=dqs(+,-)
// wrclk_en=dqs follows quad, same as disable0
const uint64_t disable_reg[MAX_PORTS][MAX_PRI_RANKS][DP18_INSTANCES] = {
@@ -3149,65 +3156,30 @@ fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target)
ENUM_ATTR_EFF_PRIMARY_RANK_GROUP3_INVALID,
};
- const uint8_t disable1_mask_lookup[4][DP18_INSTANCES][4] = { // for swizzle map
- // port 0
- // q0 q1 q2 q3
- { {0xC0,0x30,0x03,0x0C}, // DP18 block 0 instance
- {0xC0,0x30,0x03,0x0C}, // ... block 1
- {0xC0,0x30,0x0C,0x03}, // ... block 2
- {0xC0,0x30,0x0C,0x03}, // ... block 3
- {0xC0,0x30,0x0C,0x03} // ... block 4
- },
- // port 1
- { {0x30,0xC0,0x0C,0x03}, // 0xC0 = disable lanes 16,17
- {0x30,0xC0,0x0C,0x03}, // 0x30 = disable lanes 18,19
- {0xC0,0x30,0x0C,0x03}, // 0x0C = disable lanes 20,21
- {0xC0,0x30,0x0C,0x03}, // 0x03 = disable lanes 22,23
- {0xC0,0x30,0x03,0x0C}
- },
- // port 2
- { {0xC0,0x30,0x0C,0x03},
- {0xC0,0x30,0x03,0x0C},
- {0xC0,0x30,0x0C,0x03},
- {0xC0,0x30,0x0C,0x03},
- {0xC0,0x30,0x0C,0x03}
- },
- // port 3
- { {0xC0,0x30,0x0C,0x03},
- {0xC0,0x30,0x0C,0x03},
- {0xC0,0x30,0x03,0x0C},
- {0x30,0xC0,0x0C,0x03},
- {0xC0,0x30,0x0C,0x03}
- }
- };
-
const uint16_t wrclk_disable_mask[] = { // by quads
0x8800, 0x4400, 0x2280, 0x1140
};
- uint8_t l_dram_width, l_mbaPos, l_disable1_fixed;
+ uint8_t l_dram_width, l_disable1_fixed;
uint64_t l_addr;
- // 0x8000007d0301143f
- const uint64_t l_disable1_addr_offset = 0x0000000100000000ull; // from disable0 register
- // 0x800000050301143f
- const uint64_t l_wrclk_en_addr_mask = 0xFFFFFF07FFFFFFFFull; // from disable1 register
+ // 0x8000007d0301143f from disable0 register
+ const uint64_t l_disable1_addr_offset = 0x0000000100000000ull;
+ // 0x800000050301143f from disable1 register
+ const uint64_t l_wrclk_en_addr_mask = 0xFFFFFF07FFFFFFFFull;
ReturnCode rc;
ecmdDataBufferBase data_buffer(64);
ecmdDataBufferBase db_reg(BITS_PER_PORT);
uint32_t l_ecmdRc = ECMD_DBUF_SUCCESS;
- uint8_t prg[MAX_PRI_RANKS][MAX_PORTS]; // primary rank group values
+ uint8_t prg[MAX_PRI_RANKS][MAX_PORTS]; // primary rank group values
- FAPI_INF("Running set bad bits FN:mss_set_bbm_regs,"
- " input Target: %s", mba_target.toEcmdString());
+ FAPI_INF("Running flash->registers(set)");
std::vector<Target> mba_dimms;
fapiGetAssociatedDimms(mba_target, mba_dimms); // functional dimms
- FAPI_INF("***-------- Found %i functional DIMMS --------***",
- mba_dimms.size());
-
- // ATTR_EFF_PRIMARY_RANK_GROUP0[port], GROUP1[port], GROUP2[port], GROUP3[port]
+ // ATTR_EFF_PRIMARY_RANK_GROUP0[port], GROUP1[port],
+ // GROUP2[port], GROUP3[port]
rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP0, &mba_target, prg[0]);
if(rc) return rc;
rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP1, &mba_target, prg[1]);
@@ -3217,9 +3189,6 @@ fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target)
rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP3, &mba_target, prg[3]);
if(rc) return rc;
- rc=FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &mba_target, l_mbaPos);
- if(rc) return rc;
-
rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &mba_target, l_dram_width);
if(rc) return rc;
@@ -3228,7 +3197,7 @@ fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target)
if(rc) return rc;
rc = FAPI_ATTR_GET(ATTR_MSS_DISABLE1_REG_FIXED, &l_target_centaur, l_disable1_fixed);
- if(rc) return rc;
+ if(rc) return rc;
switch (l_dram_width)
{
@@ -3261,23 +3230,22 @@ fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target)
}
for (uint8_t port = 0; port < MAX_PORTS; port++ ) // [0:1]
{
- uint8_t aport = (l_mbaPos*2) + port;
-
// loop through primary ranks [0:3]
for (uint8_t prank = 0; prank < MAX_PRI_RANKS; prank++ )
{
uint8_t dimm = prg[prank][port] >> 2;
uint8_t rank = prg[prank][port] & 0x03;
uint16_t l_data = 0;
+ uint8_t is_clean = 1;
if (prg[prank][port] == rg_invalid[prank]) // invalid rank
{
- FAPI_INF("Primary rank group %i is INVALID, continuing...",
+ FAPI_DBG("Primary rank group %i: INVALID, continuing...",
prank);
continue;
}
- rc = getC4dq2reg(mba_target, port, dimm, rank, db_reg);
+ rc = getC4dq2reg(mba_target, port, dimm, rank, db_reg, is_clean);
if (rc)
{
FAPI_ERR("Error from getting register bitmap port=%i: "
@@ -3286,23 +3254,23 @@ fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target)
return rc;
}
// quick test to move on to next rank if no bits need to be set
- if (db_reg.getNumBitsSet(0, BITS_PER_PORT) == 0)
+ if (is_clean == 1) // Note ignores spares that match attribute
{
- FAPI_INF("No bad bits found for p%i:d%i:r%i(rg%i):cs%i",
- port, dimm, rank, prank, prg[prank][port]);
+ FAPI_INF("Primary rank group %i: No bad bits found for "
+ "p%i:d%i:r%i:cs%i", prank, port, dimm, rank,
+ prg[prank][port]);
continue;
}
-
for ( uint8_t i=0; i < DP18_INSTANCES; i++ ) // dp18 [0:4]
{
- uint16_t disable1_data = 0;
+ uint8_t disable1_data = 0;
uint16_t wrclk_mask = 0;
// check or not to check(always set register)?
l_data = db_reg.getHalfWord(i);
if (l_data == 0)
{
- FAPI_INF("DP18_%i has no bad bits set, continuing...", i);
+ FAPI_DBG("\tDP18_%i has no bad bits set, continuing...", i);
continue;
}
// clear bits 48:63
@@ -3315,18 +3283,47 @@ fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target)
rc.setEcmdError(l_ecmdRc);
return rc;
}
-
- if (l_dram_width == 4) { // disable entire nibble if bad bit found
- uint16_t mask = 0xF000;
- for (uint8_t n=0; n < 4; n++) { // check each nibble
- uint16_t nmask = mask >> (4*n);
- if ((nmask & l_data) > 0) {
- l_data = l_data | nmask;
- FAPI_INF("Disabling nibble %i",n);
+
+ for (uint8_t n=0; n < 4; n++) // check each nibble
+ {
+ uint16_t nmask = 0xF000 >> (4*n);
+ if (l_dram_width == 4)
+ {
+ if ((nmask & l_data) > 0) // bad bit(s) in nibble
+ {
+ // For Marc Gollub, since repair for x4 DRAM is in nibble
+ // granularity. Also due to higher chance of hitting dq0 of
+ // Micron causing write leveling to fail for entire x4 DRAM.
+ // Will also save a re-training loop. Complement in get_bbm_regs.
+
+ l_data = l_data | nmask; // set entire nibble
+ FAPI_INF("Disabling entire nibble %i",n);
+ rc = mss_get_dqs_lane(mba_target, port, i, n,
+ disable1_data);
+ if (rc) return rc;
+ wrclk_mask |= wrclk_disable_mask[n];
+ }
+ } // end x4
+ else // width == 8+?
+ {
+ if ((n % 2) == 0)
+ {
+ nmask = 0xFF00 >> (4*n);
+ if ((nmask & l_data) == nmask) // entire byte bad
+ {
+ disable1_data |= (0xF0 >> (n*2));
+ }
+ }
+ if (((nmask & l_data)>>(4*(3-n))) == 0x0F)
+ {
+ wrclk_mask |= wrclk_disable_mask[n];
}
}
}
+ FAPI_DBG("\t\tdisable1_data=0x%04X", disable1_data);
+
+ // set disable0(dq) reg
l_ecmdRc = data_buffer.setHalfWord(3, l_data);
if (l_ecmdRc != ECMD_DBUF_SUCCESS)
{
@@ -3343,48 +3340,53 @@ fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target)
"Rank%i \tdp18_%i addr=0x%llx, data=0x%04X", port,
dimm, prank, prg[prank][port], i, l_addr , l_data);
-// rc = fapiPutScom(mba_target, l_addr, data_buffer);
- rc = fapiPutScomUnderMask(mba_target, l_addr, data_buffer, data_buffer);
+ rc = fapiPutScomUnderMask(mba_target, l_addr, data_buffer,
+ data_buffer);
if (rc)
{
FAPI_ERR("Error from fapiPutScom writing disable0 reg");
return rc;
}
+
+ // set address for disable1(dqs) register
+ l_addr += l_disable1_addr_offset;
+ if (disable1_data != 0)
+ {
+ l_ecmdRc = data_buffer.flushTo0(); // clear buffer
+ if (l_ecmdRc != ECMD_DBUF_SUCCESS)
+ {
+ FAPI_ERR("Error from ecmdDataBuffer flushTo0() "
+ "- rc 0x%.8X", l_ecmdRc);
- if (l_dram_width == 4) {
- uint16_t bn_mask = 0xF000;
- uint16_t mask;
- for (uint8_t q=0; q < 4; q++) {
- mask = bn_mask >> (4*q);
- if ((l_data & mask) == mask) {
- disable1_data |= disable1_mask_lookup[aport][i][q];
- if ( !l_disable1_fixed ) {
- wrclk_mask |= wrclk_disable_mask[q];
- }
- FAPI_DBG("x4 disable1_data=0x%04X, wrclk_mask=0x%04X",disable1_data,wrclk_mask);
- }
+ rc.setEcmdError(l_ecmdRc);
+ return rc;
}
- } else {
- uint16_t bn_mask = 0xFF00;
- uint16_t mask;
- for (uint8_t q=0; q < 4; q=q+2) {
- mask = bn_mask >> (4*q);
- if ((l_data & mask) == mask) {
- disable1_data |= disable1_mask_lookup[aport][i][q] |
- disable1_mask_lookup[aport][i][q+1];
- if ( !l_disable1_fixed ) {
- wrclk_mask |= wrclk_disable_mask[q] | wrclk_disable_mask[q+1];
- }
- FAPI_DBG("x8 disable1_data=0x%04X, wrclk_mask=0x%04X",disable1_data,wrclk_mask);
- }
+
+ l_ecmdRc = data_buffer.setByte(6, disable1_data);
+ if (l_ecmdRc != ECMD_DBUF_SUCCESS)
+ {
+ FAPI_ERR("Error from ecmdDataBuffer setByte() "
+ "- rc 0x%.8X", l_ecmdRc);
+
+ rc.setEcmdError(l_ecmdRc);
+ return rc;
}
- }
- if (disable1_data != 0) {
- // shift over 8 bits since disable1_lookup is 8 bits, and reg is 16
- disable1_data = disable1_data << 8;
- l_addr += l_disable1_addr_offset; // set address for disable1 reg
+ // write disable1(dqs) register
+ rc = fapiPutScomUnderMask(mba_target, l_addr,
+ data_buffer, data_buffer);
+ if (rc)
+ {
+ FAPI_ERR("Error from PutScom writing disable1 reg");
+ return rc;
+ }
+ } // end disable1_data != 0
+ // set address for wrclk_en register
+ l_addr &= l_wrclk_en_addr_mask;
+
+ if (wrclk_mask != 0)
+ {
l_ecmdRc = data_buffer.flushTo0(); // clear buffer
if (l_ecmdRc != ECMD_DBUF_SUCCESS)
{
@@ -3394,60 +3396,47 @@ fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target)
rc.setEcmdError(l_ecmdRc);
return rc;
}
-
- l_ecmdRc = data_buffer.setHalfWord(3, disable1_data);
+ ecmdDataBufferBase put_mask(64);
+ l_ecmdRc = put_mask.setHalfWord(3, wrclk_mask);
if (l_ecmdRc != ECMD_DBUF_SUCCESS)
{
- FAPI_ERR("Error from ecmdDataBuffer setHalfWord() "
- "- rc 0x%.8X", l_ecmdRc);
+ FAPI_ERR("Error from ecmdDataBuffer setHalfWord()"
+ " for wrclk_mask - rc 0x%.8X", l_ecmdRc);
rc.setEcmdError(l_ecmdRc);
return rc;
}
- // write disable1 register
-// rc = fapiPutScom(mba_target, l_addr, data_buffer);
- rc = fapiPutScomUnderMask(mba_target, l_addr, data_buffer, data_buffer);
- if (rc)
+ if (!l_disable1_fixed)
{
- FAPI_ERR("Error from fapiPutScom writing disable1 reg");
- return rc;
- }
-
-// for DD1.X chips since disable1 register not fully working... can take out wrclk stuff for DD2+
- if ( !l_disable1_fixed )
- {
- l_addr &= l_wrclk_en_addr_mask; // set address for wrclk_en register
-
- l_ecmdRc = data_buffer.flushTo0(); // clear buffer
- if (l_ecmdRc != ECMD_DBUF_SUCCESS)
- {
- FAPI_ERR("Error from ecmdDataBuffer flushTo0() "
- "- rc 0x%.8X", l_ecmdRc);
-
- rc.setEcmdError(l_ecmdRc);
- return rc;
- }
-
- ecmdDataBufferBase put_mask(64);
- l_ecmdRc = put_mask.setHalfWord(3, wrclk_mask);
- if (l_ecmdRc != ECMD_DBUF_SUCCESS)
+ // clear(0) out the unused quads for wrclk
+ rc = fapiPutScomUnderMask(mba_target, l_addr,
+ data_buffer, put_mask);
+ if (rc)
{
- FAPI_ERR("Error from ecmdDataBuffer setHalfWord() for wrclk_mask"
- "- rc 0x%.8X", l_ecmdRc);
-
- rc.setEcmdError(l_ecmdRc);
- return rc;
+ FAPI_ERR("Error from fapiPutScomUnderMask writing "
+ "wrclk_en reg");
+ return rc;
}
- // clear(0) out the unused quads
- rc = fapiPutScomUnderMask(mba_target, l_addr, data_buffer, put_mask);
+ }
+ else
+ {
+ uint64_t rdclk_addr =
+ disable_reg[port][prank][i] & 0xFFFFFF040FFFFFFFull;
+ // clear(0) out the unused quads for rdclk
+ rc = fapiPutScomUnderMask(mba_target, rdclk_addr,
+ data_buffer, put_mask);
if (rc)
{
- FAPI_ERR("Error from fapiPutScomUnderMask writing wrclk_en reg");
+ FAPI_ERR("Error from fapiPutScomUnderMask writing "
+ "rdclk_en reg");
return rc;
}
- } // if not disable1_fixed
- } // if disable1 data != 0
+
+ FAPI_DBG("rdclk_addr=0x%llx, wrclk_addr=0x%llx, "
+ "wrclk_mask=0x%04X", rdclk_addr, l_addr, wrclk_mask);
+ }
+ } // end wrclk_mask != 0
} // end DP18 instance loop
} // end primary rank loop
} // end port loop
@@ -3455,6 +3444,56 @@ fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target)
} // end mss_set_bbm_regs
+fapi::ReturnCode mss_get_dqs_lane (const fapi::Target & i_mba,
+ const uint8_t i_port, const uint8_t i_block, const uint8_t i_quad,
+ uint8_t &o_lane)
+{
+// input = mba, port, dp18 block, quad
+// output = OR'd in lane of the dqs for the specified input
+
+ ReturnCode rc;
+ uint8_t dq, dqs;
+ uint8_t phy_lane = i_quad * 4;
+ uint8_t l_block = i_block;
+ // returns dq
+ rc=mss_c4_phy(i_mba,i_port,0,RD_DQ,dq,0,phy_lane,l_block,1);
+ if (rc) return rc;
+ dqs = dq / 4;
+ // returns phy_lane
+ rc=mss_c4_phy(i_mba,i_port,0,WR_DQS,dqs,0,phy_lane,l_block,0);
+ if (rc) return rc;
+ if (l_block != i_block)
+ {
+ FAPI_ERR("\t !!! blocks don't match from c4 to phy i_block=%i,"
+ " o_block=%i", i_block, l_block);
+ }
+
+ switch (phy_lane)
+ {
+ case 16:
+ case 17:
+ o_lane |= 0xC0;
+ break;
+ case 18:
+ case 19:
+ o_lane |= 0x30;
+ break;
+ case 20:
+ case 21:
+ o_lane |= 0x0C;
+ break;
+ case 22:
+ case 23:
+ o_lane |= 0x03;
+ break;
+ default:
+ FAPI_ERR("\t!!! (Port%i, dp18_%i, q=%i) phy_lane(%i)"
+ "returned from mss_c4_phy is invalid",
+ i_port, i_block, i_quad, phy_lane);
+// FAPI_SET_HWP_ERROR(rc, RC_MSS_IMP_INPUT_ERROR);
+ }
+ return rc;
+} //end mss_get_dqs_lane
fapi::ReturnCode mss_get_bbm_regs (const fapi::Target & mba_target)
{
@@ -3527,21 +3566,17 @@ fapi::ReturnCode mss_get_bbm_regs (const fapi::Target & mba_target)
ecmdDataBufferBase data_buffer(64);
ecmdDataBufferBase db_reg(BITS_PER_PORT);
uint32_t l_ecmdRc = ECMD_DBUF_SUCCESS;
- uint8_t prg[MAX_PRI_RANKS][MAX_PORTS]; // primary rank group values
+ uint8_t prg[MAX_PRI_RANKS][MAX_PORTS]; // primary rank group values
uint8_t l_dram_width;
- FAPI_INF("Running set bad bits FN:mss_set_bbm_regs \n"
- " input Target: %s", mba_target.toEcmdString());
+ FAPI_INF("Running (get)registers->flash");
std::vector<Target> mba_dimms;
fapiGetAssociatedDimms(mba_target, mba_dimms); // functional dimms
- FAPI_INF("***-------- Found %i functional DIMMS --------***",
- mba_dimms.size());
-
// 4 dimms per MBA, 2 per port
-
- // ATTR_EFF_PRIMARY_RANK_GROUP0[port], GROUP1[port], GROUP2[port], GROUP3[port]
+ // ATTR_EFF_PRIMARY_RANK_GROUP0[port], GROUP1[port],
+ // GROUP2[port], GROUP3[port]
rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP0, &mba_target, prg[0]);
if(rc) return rc;
rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP1, &mba_target, prg[1]);
@@ -3591,17 +3626,29 @@ fapi::ReturnCode mss_get_bbm_regs (const fapi::Target & mba_target)
uint8_t dimm = prg[prank][port] >> 2;
uint8_t rank = prg[prank][port] & 0x03;
uint16_t l_data = 0;
+ uint8_t l_has_bad_bits = 0;
if (prg[prank][port] == rg_invalid[prank]) // invalid rank
{
- FAPI_INF("Primary rank group %i is INVALID, continuing...",
+ FAPI_DBG("Primary rank group %i is INVALID, continuing...",
prank);
continue;
}
- for ( uint8_t i=0; i < DP18_INSTANCES; i++ ) // dp18 [0:4]
+ // create the db_reg (all the failed bits of the port)
+ l_ecmdRc = db_reg.flushTo0();
+ if (l_ecmdRc != ECMD_DBUF_SUCCESS)
{
+ FAPI_ERR("Error from ecmdDataBuffer flushTo0() "
+ "- rc 0x%.8X", l_ecmdRc);
+
+ rc.setEcmdError(l_ecmdRc);
+ return rc;
+ }
+ FAPI_DBG("Port%i, dimm=%i, prg%i rank=%i", port, dimm, prank, rank);
+ for ( uint8_t i=0; i < DP18_INSTANCES; i++ ) // dp18 [0:4]
+ {
// clear bits 48:63
l_ecmdRc = data_buffer.clearBit(48, BITS_PER_REG);
if (l_ecmdRc != ECMD_DBUF_SUCCESS)
@@ -3622,238 +3669,310 @@ fapi::ReturnCode mss_get_bbm_regs (const fapi::Target & mba_target)
}
l_data = data_buffer.getHalfWord(3);
- if (l_ecmdRc != ECMD_DBUF_SUCCESS)
- {
- FAPI_ERR("Error from ecmdDataBuffer setHalfWord() "
- "- rc 0x%.8X", l_ecmdRc);
- rc.setEcmdError(l_ecmdRc);
- return rc;
- }
+ FAPI_DBG("dp18_%i 0x%llx = 0x%x", i,
+ disable_reg[port][prank][i], l_data);
- if (l_dram_width == 4) { // disable entire nibble if bad bit found
- uint16_t mask = 0xF000;
- for (uint8_t n=0; n < 4; n++) { // check each nibble
- uint16_t nmask = mask >> (4*n);
- if ((nmask & l_data) > 0) {
- l_data = l_data | nmask;
- FAPI_INF("Disabling nibble %i",n);
+ if (l_data != 0)
+ {
+ l_has_bad_bits = 1;
+ // to complement Marc Gollub's request in mss_set_bbm_regs
+ // and stay consistent for procedures following this one
+ // if x4 and any bit in a nibble is bad, mask entire nibble
+ if (l_dram_width == 4) {
+ uint16_t mask = 0xF000;
+ for (uint8_t n=0; n < 4; n++) { // check each nibble
+ uint16_t nmask = mask >> (4*n);
+ if ((nmask & l_data) > 0) {
+ l_data = l_data | nmask;
+ FAPI_INF("Disabling entire nibble %i",n);
+ }
}
}
- }
- l_ecmdRc |= db_reg.setHalfWord(i, l_data);
- if (l_ecmdRc != ECMD_DBUF_SUCCESS)
- {
- FAPI_ERR("Error from ecmdDataBuffer setHalfWord() "
+ l_ecmdRc = db_reg.setHalfWord(i, l_data);
+ if (l_ecmdRc != ECMD_DBUF_SUCCESS)
+ {
+ FAPI_ERR("Error from ecmdDataBuffer setHalfWord() "
"- rc 0x%.8X", l_ecmdRc);
- rc.setEcmdError(l_ecmdRc);
- return rc;
- }
-
- FAPI_INF("+++ Setting Bad Bit Mask p%i: DIMM%i PRG%i "
- "Rank%i \tdp18_%i addr=0x%llx, data=0x%04X", port,
- dimm, prank, prg[prank][port], i,
- disable_reg[port][prank][i], l_data);
+ rc.setEcmdError(l_ecmdRc);
+ return rc;
+ }
+ FAPI_INF("+++ Setting Bad Bit Mask p%i: DIMM%i PRG%i "
+ "Rank%i \tdp18_%i addr=0x%llx, data=0x%04X", port,
+ dimm, prank, prg[prank][port], i,
+ disable_reg[port][prank][i], l_data);
+ }
} // end DP18 instance loop
- rc = setC4dq2reg(mba_target, port, dimm, rank, db_reg);
- if (rc)
+ if (l_has_bad_bits)
{
- FAPI_ERR("Error from setting register bitmap p%i: "
+ rc = setC4dq2reg(mba_target, port, dimm, rank, db_reg);
+ if (rc)
+ {
+ FAPI_ERR("Error from setting register bitmap p%i: "
"dimm=%i, rank=%i rc=%i", port, dimm, rank,
static_cast<uint32_t>(rc));
- return rc;
+ return rc;
+ }
}
-
} // end primary rank loop
} // end port loop
return rc;
} // end mss_get_bbm_regs
-// output reg = in phy based order
-ReturnCode getC4dq2reg(const Target & i_mba, const uint8_t i_port, const uint8_t i_dimm, const uint8_t i_rank, ecmdDataBufferBase &o_reg)
+ReturnCode getC4dq2reg(const Target & i_mba, const uint8_t i_port,
+ const uint8_t i_dimm, const uint8_t i_rank, ecmdDataBufferBase &o_reg, uint8_t &is_clean)
{
- // [port][bits per port]
- const uint8_t lookup[4][BITS_PER_PORT] = {
- // port 0
- {65,66,67,64, 70,69,68,71, 21,20,23,22, 18,16,19,17, // DP18 block 0
- 61,63,60,62, 57,58,59,56, 73,74,75,72, 78,77,79,76, // ... block 1
- 7, 5, 4, 6, 0, 2, 1, 3, 12,13,15,14, 10, 8,11, 9, // ... block 2
- 47,44,46,45, 43,42,41,40, 31,29,30,28, 26,24,27,25, // ... block 3
- 55,53,54,52, 50,48,49,51, 33,34,35,32, 36,37,38,39}, // ... block 4
- // port 1
- {17,16,18,19, 20,21,22,23, 2, 0, 3, 1, 7, 4, 5, 6,
- 70,71,69,68, 66,64,67,65, 27,24,26,25, 29,30,31,28,
- 37,36,38,39, 35,32,34,33, 77,76,79,78, 73,75,72,74,
- 40,42,41,43, 45,44,46,47, 9,11, 8,10, 12,13,14,15,
- 48,51,49,50, 52,53,54,55, 61,63,62,60, 56,58,59,57},
- // port 2
- {22,23,20,21, 19,16,17,18, 26,25,24,27, 29,28,31,30,
- 67,64,65,66, 71,70,69,68, 7, 5, 6, 4, 2, 0, 3, 1,
- 45,44,47,46, 42,43,41,40, 39,38,37,36, 33,34,35,32,
- 48,50,49,51, 54,52,53,55, 15,13,12,14, 9, 8,10,11,
- 61,60,62,63, 59,56,58,57, 74,72,73,75, 76,79,78,77},
- // port 3
- {25,26,27,24, 28,31,29,30, 17,19,16,18, 20,21,23,22,
- 64,67,66,65, 71,69,68,70, 75,74,72,73, 76,77,79,78,
- 4, 5, 7, 6, 0, 1, 2, 3, 12,13,14,15, 8, 9,11,10,
- 47,45,46,44, 43,41,42,40, 35,32,33,34, 39,37,36,38,
- 55,52,53,54, 51,48,49,50, 60,62,61,63, 57,59,56,58}
- };
+// used by set_bbm(flash to registers)
+// calls dimmGetBadDqBitmap and converts the data to phy order in a databuffer
+// output reg = in phy based order(lanes)
uint8_t l_bbm[TOTAL_BYTES] = {0}; // bad bitmap from dimmGetBadDqBitmap
- ecmdDataBufferBase c4dqbmp(BITS_PER_PORT); // databuffer of C4 dq bitmap
ReturnCode rc;
- uint8_t l_port = i_port; // port # relative to Centaur
- uint8_t mba_pos = 0;
uint32_t ecmdrc = ECMD_DBUF_SUCCESS;
+ uint8_t dq;
+ uint8_t phy_lane, phy_block;
ecmdrc = o_reg.flushTo0(); // clear output databuffer
if (ecmdrc != ECMD_DBUF_SUCCESS)
{
- FAPI_ERR("Error from ecmdDataBuffer flushTo0() "
- "- rc 0x%.8X", ecmdrc);
+ FAPI_ERR("Error from ecmdDataBuffer flushTo0() "
+ "- rc 0x%.8X", ecmdrc);
- rc.setEcmdError(ecmdrc);
- return rc;
- }
- rc=FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_mba, mba_pos);
- if (rc)
- {
- FAPI_ERR("Error getting ATTR_CHIP_UNIT_POS for MBA");
- return (rc);
+ rc.setEcmdError(ecmdrc);
+ return rc;
}
// get Centaur dq bitmap (C4 signal) order=[0:79], array of bytes
rc = dimmGetBadDqBitmap(i_mba, i_port, i_dimm, i_rank, l_bbm);
if (rc)
{
- FAPI_ERR("Error from dimmGetBadDqBitmap on MBA%ip%i: "
- "dimm=%i, rank=%i rc=%i", mba_pos, i_port, i_dimm, i_rank,
- static_cast<uint32_t>(rc));
- return rc;
+ FAPI_ERR("Error from dimmGetBadDqBitmap on port %i: "
+ "dimm=%i, rank=%i rc=%i", i_port, i_dimm, i_rank,
+ static_cast<uint32_t>(rc));
+ return rc;
}
- // create databuffer from C4 dq bitmap array
- ecmdrc = c4dqbmp.insertFromRight(l_bbm, 0, BITS_PER_PORT);
- if (ecmdrc != ECMD_DBUF_SUCCESS)
- {
- FAPI_ERR("Error from ecmdDataBuffer insertFromRight() "
- "- rc 0x%.8X", ecmdrc);
+ uint8_t dimm_spare[MAX_PORTS][MAX_DIMMS][MAX_PRI_RANKS];
+ rc = FAPI_ATTR_GET(ATTR_VPD_DIMM_SPARE, &i_mba, dimm_spare);
+ if(rc) return rc;
- rc.setEcmdError(ecmdrc);
- return rc;
- }
+ for (uint8_t byte=0; byte < TOTAL_BYTES; byte++)
+ {
+ if (l_bbm[byte] != 0)
+ {
+ if (byte == (TOTAL_BYTES-1)) // spare byte
+ {
+ uint8_t spare_bitmap = 0;
+
+ switch (dimm_spare[i_port][i_dimm][i_rank])
+ {
+ case ENUM_ATTR_VPD_DIMM_SPARE_NO_SPARE:
+ spare_bitmap = 0;
+ break;
+ case ENUM_ATTR_VPD_DIMM_SPARE_LOW_NIBBLE:
+ spare_bitmap = 0x0F;
+ break;
+ case ENUM_ATTR_VPD_DIMM_SPARE_HIGH_NIBBLE:
+ spare_bitmap = 0xF0;
+ break;
+ case ENUM_ATTR_VPD_DIMM_SPARE_FULL_BYTE:
+ spare_bitmap = 0xFF;
+ break;
+ default:
+ FAPI_ERR("ATTR_VPD_DIMM_SPARE is invalid %u",
+ dimm_spare[i_port][i_dimm][i_rank]);
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_IMP_INPUT_ERROR);
+ return rc;
+ }
- // quick check if there no bits on, we're done
- if (c4dqbmp.getNumBitsSet(0, BITS_PER_PORT) == 0)
- {
- return rc;
- }
- l_port = i_port + (mba_pos * MAX_PORTS); // relative to Centaur
+ if (l_bbm[byte] == spare_bitmap) // spare already set via initfile
+ continue;
+ }
- for (uint8_t i=0; i < BITS_PER_PORT; i++)
- {
- if (c4dqbmp.isBitSet(lookup[l_port][i]))
- {
- o_reg.setBit(i);
- FAPI_DBG("set bad bit C4_dq=%i,\t dp18_%i_lane%i\t (bit %i)",
- lookup[l_port][i], (i / 16), (i % 16), i);
- }
- }
+ uint8_t bs=0;
+ uint8_t be=8;
+ uint8_t loc=0;
+ is_clean = 0;
- return rc;
-}
+ if ((l_bbm[byte] & 0xF0) == 0xF0) // 0xF?
+ {
+ dq = (byte * 8); // for first lane
+ // input=cen_c4_dq, output=phy block, lane
+ rc = mss_c4_phy(i_mba, i_port, 0, RD_DQ,dq,
+ 0, phy_lane,phy_block, 0);
+ if (rc) return rc;
+
+ if (l_bbm[byte] == 0xFF)
+ { // block lanes + 1st lane{0,8}
+ loc = (phy_block * 16) + (phy_lane & 0x08);
+ o_reg.setBit(loc, 8); // set dq byte
+ FAPI_DBG("0xFF byte=%i, lbbm=0x%02x dp%i_%i dq=%i o=%i",
+ byte, l_bbm[byte], phy_block, phy_lane, dq, loc);
+ continue;
+ }
+ // block lanes + 1st lane{0,4,8,12}
+ loc = (phy_block * 16) + (phy_lane & 0x0C);
+ o_reg.setBit(loc, 4); // set dq nibble0
+ FAPI_DBG("0xF0 byte=%i, lbbm=0x%02x dp%i_%i dq=%i o=%i",
+ byte, l_bbm[byte], phy_block, phy_lane, dq, loc);
-ReturnCode setC4dq2reg(const Target &i_mba, const uint8_t i_port, const uint8_t i_dimm, const uint8_t i_rank, ecmdDataBufferBase &o_reg)
+ if (l_bbm[byte] == 0xF0) // done with byte
+ continue;
+ bs=4; // processed the first 4 bits already
+ }
+ else if ((l_bbm[byte] & 0x0F) == 0x0F) // 0x?F
+ {
+ dq = (byte * 8) + 4; // for first lane of dq
+ rc = mss_c4_phy(i_mba, i_port, 0, RD_DQ,dq,
+ 0, phy_lane, phy_block, 0);
+ if (rc) return rc;
+ // block lanes + 1st lane{0,4,8,12}
+ loc = (phy_block * 16) + (phy_lane & 0x0C);
+ FAPI_DBG("0x0F byte=%i, lbbm=0x%02x dp%i_%i dq=%i o=%i",
+ byte, l_bbm[byte], phy_block, phy_lane, dq, loc);
+ o_reg.setBit(loc, 4); // set dq nibble1
+ if (l_bbm[byte] == 0x0F) // done with byte
+ continue;
+ be=4; // processed the last 4 bits already
+ }
+ else if ((l_bbm[byte] >> 4) == 0) // 0x0?
+ bs=4;
+ else if ((l_bbm[byte] & 0x0F) == 0) // 0x?0
+ be=4;
+
+ for (uint8_t b=bs; b < be; b++) // test each bit
+ {
+ if ((l_bbm[byte] & (0x80 >> b)) > 0) // bit is set,
+ {
+ dq = (byte * 8) + b;
+ rc=mss_c4_phy(i_mba, i_port, 0, RD_DQ,dq,
+ 0, phy_lane, phy_block, 0);
+ if (rc) return rc;
+ loc = (phy_block * 16) + phy_lane;
+ o_reg.setBit(loc);
+ FAPI_DBG("b=%i byte=%i, lbbm=0x%02x dp%i_%i dq=%i "
+ "loc=%i bs=%i be=%i", b, byte, l_bbm[byte],
+ phy_block, phy_lane, dq, loc, bs, be);
+ }
+ }
+ } // end if not clean
+ } // end byte
+ return rc;
+} // end getC4dq2reg
+
+
+ReturnCode setC4dq2reg(const Target &i_mba, const uint8_t i_port,
+ const uint8_t i_dimm, const uint8_t i_rank, const ecmdDataBufferBase &i_reg)
{
+// used by get_bbm(registers to flash)
+// Converts the data from phy order (i_reg) to cen_c4_dq array
+// for dimmSetBadDqBitmap to write flash with
- const uint8_t lookup[4][BITS_PER_PORT] = {
- // port 0
- {65,66,67,64,70,69,68,71,21,20,23,22,18,16,19,17, // DP18 block 0
- 61,63,60,62,57,58,59,56,73,74,75,72,78,77,79,76, // ... block 1
- 7, 5, 4, 6, 0, 2, 1, 3,12,13,15,14,10, 8,11, 9, // ... block 2
- 47,44,46,45,43,42,41,40,31,29,30,28,26,24,27,25, // ... block 3
- 55,53,54,52,50,48,49,51,33,34,35,32,36,37,38,39}, // ... block 4
- // port 1
- {17,16,18,19,20,21,22,23, 2, 0, 3, 1, 7, 4, 5, 6,
- 70,71,69,68,66,64,67,65,27,24,26,25,29,30,31,28,
- 37,36,38,39,35,32,34,33,77,76,79,78,73,75,72,74,
- 40,42,41,43,45,44,46,47, 9,11, 8,10,12,13,14,15,
- 48,51,49,50,52,53,54,55,61,63,62,60,56,58,59,57},
- // port 2
- {22,23,20,21,19,16,17,18,26,25,24,27,29,28,31,30,
- 67,64,65,66,71,70,69,68, 7, 5, 6, 4, 2, 0, 3, 1,
- 45,44,47,46,42,43,41,40,39,38,37,36,33,34,35,32,
- 48,50,49,51,54,52,53,55,15,13,12,14, 9, 8,10,11,
- 61,60,62,63,59,56,58,57,74,72,73,75,76,79,78,77},
- // port 3
- {25,26,27,24,28,31,29,30,17,19,16,18,20,21,23,22,
- 64,67,66,65,71,69,68,70,75,74,72,73,76,77,79,78,
- 4, 5, 7, 6, 0, 1, 2, 3,12,13,14,15, 8, 9,11,10,
- 47,45,46,44,43,41,42,40,35,32,33,34,39,37,36,38,
- 55,52,53,54,51,48,49,50,60,62,61,63,57,59,56,58}
- };
- uint8_t l_bbm [TOTAL_BYTES] = {0};
- ecmdDataBufferBase c4dqbmp(BITS_PER_PORT);
ReturnCode rc;
- uint8_t l_port = i_port;
- uint8_t mba_pos = 0;
- uint32_t ecmdrc = ECMD_DBUF_SUCCESS;
+ uint8_t l_bbm [TOTAL_BYTES] = {0};
+ uint8_t dq=0;
+ uint8_t phy_lane;
+ uint8_t phy_block;
+ uint8_t data;
+
+ // get Centaur dq bitmap (C4 signal) order=[0:79], array of bytes
+ rc = dimmGetBadDqBitmap(i_mba, i_port, i_dimm, i_rank, l_bbm);
+ if (rc)
+ {
+ FAPI_ERR("Error from dimmGetBadDqBitmap on port %i: "
+ "dimm=%i, rank=%i rc=%i", i_port, i_dimm, i_rank,
+ static_cast<uint32_t>(rc));
+ return rc;
+ }
- // clear output databuffer
- ecmdrc = c4dqbmp.flushTo0();
- if (ecmdrc != ECMD_DBUF_SUCCESS)
+ for (uint8_t byte=0; byte < TOTAL_BYTES; byte++)
{
- FAPI_ERR("Error from ecmdDataBuffer flushTo0() "
- "- rc 0x%.8X", ecmdrc);
+ data = i_reg.getByte(byte);
+ if (data != 0) // need to check bits
+ {
+ uint8_t bs=0;
+ uint8_t be=8;
- rc.setEcmdError(ecmdrc);
- return rc;
- }
+ phy_block = (byte / 2); // byte=[0..9], block=[0..4]
+ FAPI_DBG("\n\t\t\t\t\t\tbyte=%i, data=0x%02x phy_block=%i ",
+ byte, data, phy_block);
+ if ((data & 0xF0) == 0xF0) // 0xF?
+ {
+ phy_lane = 8 * (byte % 2); // lane=[0,8]
+ // input=block, lane output=cen_dq
+ rc = mss_c4_phy(i_mba, i_port, 0, RD_DQ,dq,
+ 0, phy_lane, phy_block, 1);
+ if (rc) return rc;
+
+ if (data == 0xFF)
+ { // set 8 consecutive bits of the cen_c4_dq
+ l_bbm[(dq/8)] = 0xFF;
+ FAPI_DBG("0xFF dp%i_%i dq=%i, lbbm=0x%02x",
+ phy_block, phy_lane, dq, l_bbm[dq/8]);
+ continue;
+ }
- // Set Port info
- rc=FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_mba, mba_pos);
- if (rc)
- {
- FAPI_ERR("Error getting ATTR_CHIP_UNIT_POS for MBA");
- return (rc);
- }
+ l_bbm[(dq/8)] |= ((dq % 8) < 4) ? 0xF0 : 0x0F;
+ FAPI_DBG("0xF0 dp%i_%i dq=%i, lbbm=0x%02x",
+ phy_block, phy_lane, dq, l_bbm[dq/8]);
- l_port = i_port + (mba_pos * MAX_PORTS);
+ if (data == 0xF0) // done with byte
+ continue;
+ bs=4; // need to work on other bits
+ }
+ else if ((data & 0x0F) == 0x0F) // 0x?F
+ {
+ phy_lane = (8 * (byte % 2)) + 4; // lane=[4,12]
+ rc = mss_c4_phy(i_mba, i_port, 0, RD_DQ, dq,
+ 0, phy_lane, phy_block, 1);
+ if (rc) return rc;
- // translate c4 from input
- for (uint8_t i=0; i < BITS_PER_PORT; i++)
- {
- if (o_reg.isBitSet(i))
- {
- c4dqbmp.setBit(lookup[l_port][i]);
- }
- }
+ l_bbm[(dq/8)] |= ((dq % 8) < 4) ? 0xF0 : 0x0F;
+ FAPI_DBG("0x0F dp%i_%i dq=%i, lbbm=0x%02x",
+ phy_block, phy_lane, dq, l_bbm[dq/8]);
- // create array from databuffer
- for (uint8_t b=0; b < TOTAL_BYTES; b++)
- {
- l_bbm[b] = c4dqbmp.getByte(b);
- }
+ if (data == 0x0F) // done with byte
+ continue;
+ be=4; // need to work on other bits
+ }
+ else if ((data >> 4) == 0) // 0x0?
+ bs=4;
+ else if ((data & 0x0F) == 0) // 0x?0
+ be=4;
+
+ for (uint8_t b=bs; b < be; b++) // test each bit
+ {
+ if ((data & (0x80 >> b)) > 0) // bit is set,
+ {
+ phy_lane = (8 * (byte % 2)) + b;
+ rc = mss_c4_phy(i_mba, i_port, 0, RD_DQ, dq,
+ 0, phy_lane, phy_block, 1);
+ if (rc) return rc;
+ l_bbm[(dq/8)] |= (0x80 >> (dq % 8));
+ FAPI_DBG("b=%i dp%i_%i dq=%i, lbbm=0x%02x",
+ b, phy_block, phy_lane, dq, l_bbm[dq/8]);
+ }
+ }
+ } //end if not clean
+ } //end byte
// set Centaur dq bitmap (C4 signal) order=[0:79], array of bytes
rc = dimmSetBadDqBitmap(i_mba, i_port, i_dimm, i_rank, l_bbm);
if (rc)
{
- FAPI_ERR("Error from dimmSetBadDqBitmap on MBA%ip%i: "
- "dimm=%i, rank=%i rc=%i", mba_pos, i_port, i_dimm, i_rank,
- static_cast<uint32_t>(rc));
+ FAPI_ERR("Error from dimmSetBadDqBitmap on port %i: "
+ "dimm=%i, rank=%i rc=%i", i_port, i_dimm, i_rank,
+ static_cast<uint32_t>(rc));
return rc;
}
return rc;
-}
+} //end setC4dq2reg
} //end extern C
-
OpenPOWER on IntegriCloud