diff options
Diffstat (limited to 'src')
15 files changed, 6579 insertions, 124 deletions
diff --git a/src/include/usr/hwpf/istepreasoncodes.H b/src/include/usr/hwpf/istepreasoncodes.H index 0639e713b..3309a8b74 100644 --- a/src/include/usr/hwpf/istepreasoncodes.H +++ b/src/include/usr/hwpf/istepreasoncodes.H @@ -105,6 +105,7 @@ enum istepModuleId ISTEP_PROC_CEN_SET_INBAND_ADDR = 0x38, ISTEP_MSS_THERMAL_INIT = 0x39, ISTEP_MSS_VOLT = 0x3A, + ISTEP_MSS_DRAMINIT_TRAINADV = 0x3C, }; /** diff --git a/src/usr/hwpf/hwp/dram_training/dram_training.C b/src/usr/hwpf/hwp/dram_training/dram_training.C index 95a1a7327..ca6c709d8 100644 --- a/src/usr/hwpf/hwp/dram_training/dram_training.C +++ b/src/usr/hwpf/hwp/dram_training/dram_training.C @@ -81,7 +81,7 @@ const uint8_t VPO_NUM_OF_MEMBUF_TO_RUN = UNLIMITED_RUN; #include "mss_ddr_phy_reset/mss_ddr_phy_reset.H" #include "mss_draminit/mss_draminit.H" #include "mss_draminit_training/mss_draminit_training.H" -// #include "mss_draminit_trainadv/mss_draminit_trainadv.H" +#include "mss_draminit_trainadv/mss_draminit_training_advanced.H" #include "mss_draminit_mc/mss_draminit_mc.H" namespace DRAM_TRAINING @@ -763,57 +763,83 @@ void* call_mss_draminit_training( void *io_pArgs ) void* call_mss_draminit_trainadv( void *io_pArgs ) { errlHndl_t l_err = NULL; + IStepError l_stepError; + uint8_t l_pattern = 0; + uint8_t l_test_type = 0; TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_draminit_trainadv entry" ); -#if 0 - // @@@@@ CUSTOM BLOCK: @@@@@ - // figure out what targets we need - // customize any other inputs - // set up loops to go through all targets (if parallel, spin off a task) - - // print call to hwp and dump physical path of the target(s) - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "===== mss_draminit_trainadv HWP(? ? ? )", - ? - ? - ? ); - // dump physical path to targets - EntityPath l_path; - l_path = l_@targetN_target->getAttr<ATTR_PHYS_PATH>(); - l_path.dump(); - TRACFCOMP( g_trac_mc_init, "===== " ); - - // cast OUR type of target to a FAPI type of target. - const fapi::Target l_fapi_@targetN_target( - TARGET_TYPE_MEMBUF_CHIP, - reinterpret_cast<void *> - (const_cast<TARGETING::Target*>(l_@targetN_target)) ); - - // call the HWP with each fapi::Target - l_fapirc = mss_draminit_trainadv( ? , ?, ? ); + // Get all MBA targets + TARGETING::TargetHandleList l_mbaTargetList; + getAllChiplets(l_mbaTargetList, TYPE_MBA); - // process return code. - if ( l_fapirc== fapi::FAPI_RC_SUCCESS ) + // Limit the number of MBAs to run in VPO environment to save time. + uint8_t l_mbaLimit = UNLIMITED_RUN; + if (TARGETING::is_vpo() ) { - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "SUCCESS : mss_draminit_trainadv HWP(? ? ? )" ); + l_mbaLimit = VPO_NUM_OF_MBAS_TO_RUN; } - else + + uint8_t l_mbaNum = 0; + for (TargetHandleList::iterator l_mba_iter = l_mbaTargetList.begin(); + (l_mbaNum < l_mbaLimit) && (l_mba_iter != l_mbaTargetList.end()); + ++l_mba_iter, ++l_mbaNum) { - /** - * @todo fapi error - just print out for now... - */ - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "ERROR 0x%.8X: mss_draminit_trainadv HWP(? ? ?) ", - static_cast<uint32_t>(l_fapirc) ); + // make a local copy of the target for ease of use + const TARGETING::Target* l_mba_target = *l_mba_iter; + + // Dump current run on target + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "Running mss_draminit_training_advanced HWP on..." ); + EntityPath l_path; + l_path = l_mba_target->getAttr<ATTR_PHYS_PATH>(); + l_path.dump(); + + // Cast to a FAPI type of target. + const fapi::Target l_fapi_mba_target( + TARGET_TYPE_MBA_CHIPLET, + reinterpret_cast<void *> + (const_cast<TARGETING::Target*>(l_mba_target)) ); + + // call the HWP with each fapi::Target + FAPI_INVOKE_HWP(l_err, mss_draminit_training_advanced, l_fapi_mba_target, + l_pattern, l_test_type); + + if (l_err) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "ERROR 0x%.8X : mss_draminit_training_advanced HWP returns error", + l_err->reasonCode()); + + ErrlUserDetailsTarget myDetails(l_mba_target); + + // capture the target data in the elog + myDetails.addToLog(l_err ); + + /*@ + * + * @errortype + * @reasoncode ISTEP_DRAM_TRAINING_FAILED + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid ISTEP_MSS_DRAMINIT_TRAINADV + * @userdata1 bytes 0-1: plid identifying first error + * bytes 2-3: reason code of first error + * @userdata2 bytes 0-1: total number of elogs included + * bytes 2-3: N/A + * @devdesc call to mss_dram_init_training_advanced has failed + */ + l_stepError.addErrorDetails( ISTEP_DRAM_TRAINING_FAILED, + ISTEP_MSS_DRAMINIT_TRAINADV, + l_err ); + + errlCommit( l_err, HWPF_COMP_ID ); + } + + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "SUCCESS : mss_draminit_training_advanced HWP( )" ); } - // @@@@@ END CUSTOM BLOCK: @@@@@ -#endif TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_draminit_trainadv exit" ); - return l_err; + return l_stepError.getErrorHandle(); } // diff --git a/src/usr/hwpf/hwp/dram_training/makefile b/src/usr/hwpf/hwp/dram_training/makefile index 121e8677b..b5712de65 100644 --- a/src/usr/hwpf/hwp/dram_training/makefile +++ b/src/usr/hwpf/hwp/dram_training/makefile @@ -35,7 +35,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/include ## NOTE: add the base istep dir here. ##@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/@istepname -EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training ## Include sub dirs ## NOTE: add a new EXTRAINCDIR when you add a new HWP @@ -47,6 +47,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mem_startclocks EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_scominit EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mem_pll_setup +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv ## NOTE: add new object files when you add a new HWP OBJS = dram_training.o \ @@ -58,11 +59,15 @@ OBJS = dram_training.o \ mss_ddr_phy_reset.o \ mss_termination_control.o \ cen_mem_startclocks.o \ - mss_scominit.o \ + mss_scominit.o \ cen_mem_pll_initf.o \ - cen_mem_pll_setup.o + cen_mem_pll_setup.o \ + mss_draminit_training_advanced.o \ + mss_access_delay_reg.o \ + mss_generic_shmoo.o \ + mss_mcbist.o \ + mss_mcbist_common.o - ## NOTE: add a new directory onto the vpaths when you add a new HWP ##@ VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/??? VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_draminit_training @@ -72,5 +77,6 @@ VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mem_startclocks VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_scominit VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mem_pll_setup +VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv include ${ROOTPATH}/config.mk diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_access_delay_reg.C b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_access_delay_reg.C new file mode 100644 index 000000000..1fad03077 --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_access_delay_reg.C @@ -0,0 +1,1823 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_access_delay_reg.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: mss_access_delay_reg.C,v 1.10 2012/12/14 11:13:03 sasethur Exp $ +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2011 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//------------------------------------------------------------------------------ +// *! TITLE : mss_access_delay_reg +// *! OWNER NAME : Saurabh Chadha Email: sauchadh@in.ibm.com +// *! ADDITIONAL COMMENTS : +// +// The purpose of this procedure is to give different phase rototor values like RD_DQ, RD_DQS, WR_DQ, WR_DQS +//------------------------------------------------------------------------------ +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:| Author: | Date: | Comment: +//---------|----------|---------|----------------------------------------------- +// 1.1 | sauchadh |15-Oct-12| First Draft. +// 1.2 | sauchadh |29-Oct-12| Fixed Firmware comments +// 1.3 | sauchadh |29-Oct-12| Fixed error due to rc_num +// 1.4 | sauchadh |29-Oct-12| Fixed error due to rc +// 1.5 | sauchadh |6-Nov-12 | Added RAW modes +// 1.6 | sauchadh |20-Nov-12| Made index to follow ISDIMM net for DQS and added glacier 2 suppport +// 1.7 | sauchadh |30-Nov-12| Glacier 1 and 2 selected based on init file settings +// 1.8 | sauchadh |5-Dec-12 | Fixed firmware comments and added DQS align DQS gate +// 1.9 | sauchadh |14-Dec-12| Fixed Firmware comments + + +//---------------------------------------------------------------------- +// My Includes +//---------------------------------------------------------------------- +#include <mss_access_delay_reg.H> + + + +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include <fapi.H> + + + + + +extern "C" { + + + +//****************************************************************************** +//Function name: mss_access_delay_reg() +//Description:This function Read and Write delay values for RD_DQ, WR_DQ, RD_DQS, WR_DQS +//RD_DQ - Read Delay (DQ) registers +//WR_DQ - Write delay (DQ) registers +//RD_DQS - DQS_CLK_ALIGN +//WR_DQS - Write delay (DQS)registers +//Input : Target MBA=i_target_mba, i_access_type_e = READ or WRITE, i_port_u8=0 or 1, i_rank_u8=valid ranks,i_input_type_e=RD_DQ or RD_DQS or WR_DQ or WR_DQS or RAW_modes, i_input_index_u8=follow ISDIMMnet/C4 for non raw modes and supports raw modes +//Output : delay value=io_value_u32 if i_access_type_e = READ else if i_access_type_e = WRITE no return value +//****************************************************************************** + +fapi::ReturnCode mss_access_delay_reg(const fapi::Target & i_target_mba, access_type_t i_access_type_e, uint8_t i_port_u8, uint8_t i_rank_u8, input_type_t i_input_type_e, uint8_t i_input_index_u8, uint32_t &io_value_u32) +{ + fapi::ReturnCode rc; + + const uint8_t max_rp=8; + uint8_t l_val=0; + uint8_t l_dram_width=0; + scom_location l_out; + uint64_t l_scom_add=0x0ull; + uint32_t l_sbit=0; + uint32_t l_len=0; + uint32_t rc_num=0; + ecmdDataBufferBase data_buffer_64(64); + ecmdDataBufferBase out(16); + uint32_t l_output=0; + uint32_t l_start=0; + uint8_t l_rank_pair=9; + uint8_t l_rankpair_table[max_rp]={255}; + uint8_t l_dimmtype=0; + uint8_t l_block=0; + uint8_t l_lane=0; + uint8_t l_start_bit=0; + uint8_t l_len8=0; + input_type l_type; + uint8_t l_mbapos=0; + const uint8_t l_ISDIMM_dqmax=71; + const uint8_t l_CDIMM_dqmax=79; + + + rc = mss_getrankpair(i_target_mba,i_port_u8,i_rank_u8,&l_rank_pair,l_rankpair_table); if(rc) return rc; + + rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target_mba, l_dimmtype); if(rc) return rc; + + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &i_target_mba, l_dram_width); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_target_mba, l_mbapos); if(rc) return rc; + + FAPI_INF("dimm type=%d",l_dimmtype); + + FAPI_INF("rank pair=%d",l_rank_pair); + + if((i_port_u8 >1) || (l_mbapos>1)) + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong target or port specified rc = 0x%08X", uint32_t(rc)); + return rc; + } + + if((l_dram_width ==fapi::ENUM_ATTR_EFF_DRAM_WIDTH_X4) || (l_dram_width ==fapi::ENUM_ATTR_EFF_DRAM_WIDTH_X8)) // Checking for dram width here so that checking can be skipped in called function + { + FAPI_INF("dram width=%d",l_dram_width); + + } + + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong dram width specified rc = 0x%08X", uint32_t(rc)); + return rc; + } + + if(i_input_type_e==RD_DQ || i_input_type_e==WR_DQ) + { + + if(l_dimmtype==fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM) + { + l_type=CDIMM_DQ; + + if(i_input_index_u8>l_CDIMM_dqmax) + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input index specified rc = 0x%08X" ,uint32_t(rc)); + return rc; + } + + } + else if((l_dimmtype==fapi::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM) || (l_dimmtype==fapi::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM) || (l_dimmtype==fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM)) + { + l_type=ISDIMM_DQ; + if(i_input_index_u8>l_ISDIMM_dqmax) + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input index specified rc = 0x%08X", uint32_t(rc)); + return rc; + } + } + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong dimm type specified rc = 0x%08X", uint32_t(rc)); + return rc; + } + + + rc=rosetta_map(i_target_mba,i_port_u8,l_type,i_input_index_u8,l_val); if(rc) return rc; + + FAPI_INF("C4 value is=%d",l_val); + rc=cross_coupled(i_target_mba,i_port_u8,l_rank_pair,i_input_type_e,l_val,l_out); if(rc) return rc; + FAPI_INF("scom_address=%llX",l_out.scom_addr); + FAPI_INF("start bit=%d",l_out.start_bit); + FAPI_INF("length=%d",l_out.bit_length); + l_scom_add=l_out.scom_addr; + l_sbit=l_out.start_bit; + l_len=l_out.bit_length; + + } + + else if (i_input_type_e==RD_DQS || i_input_type_e==WR_DQS || i_input_type_e==DQS_ALIGN || i_input_type_e==DQS_GATE) + { + + if(l_dimmtype==fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM) + { + l_type=CDIMM_DQS; + } + else if((l_dimmtype==fapi::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM) || (l_dimmtype==fapi::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM) || (l_dimmtype==fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM)) + { + l_type=ISDIMM_DQS; + } + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong dimm type specified rc = 0x%08X", uint32_t(rc)); + return rc; + } + + + rc=rosetta_map(i_target_mba,i_port_u8,l_type,i_input_index_u8,l_val); if(rc) return rc; + FAPI_INF("C4 value is=%d",l_val); + rc=cross_coupled(i_target_mba,i_port_u8,l_rank_pair,i_input_type_e,l_val,l_out); if(rc) return rc; + FAPI_INF("scom_address=%llX",l_out.scom_addr); + FAPI_INF("start bit=%d",l_out.start_bit); + FAPI_INF("length=%d",l_out.bit_length); + l_scom_add=l_out.scom_addr; + l_sbit=l_out.start_bit; + l_len=l_out.bit_length; + + } + + + else if(i_input_type_e==RAW_WR_DQ_0 || i_input_type_e==RAW_WR_DQ_1 || i_input_type_e==RAW_WR_DQ_2 || i_input_type_e==RAW_WR_DQ_3 || i_input_type_e==RAW_WR_DQ_4) + { + if(i_input_type_e==RAW_WR_DQ_0) + { + l_block=0; + } + else if(i_input_type_e==RAW_WR_DQ_1) + { + l_block=1; + } + else if(i_input_type_e==RAW_WR_DQ_2) + { + l_block=2; + } + else if(i_input_type_e==RAW_WR_DQ_3) + { + l_block=3; + } + else + { + l_block=4; + } + if(i_input_index_u8<=15) // 16 Write delay values for DQ bits + { + l_lane=i_input_index_u8; + } + + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input index specified rc = 0x%08X ", uint32_t(rc)); + return rc; + } + + ip_type_t l_input=RAW_WR_DQ; + FAPI_INF("block=%d",l_block); + FAPI_INF("lane=%d",l_lane); + rc=get_address(i_target_mba,i_port_u8,l_rank_pair,l_input,l_block,l_lane,l_scom_add,l_start_bit,l_len8); if(rc) return rc; + l_sbit=l_start_bit; + l_len=l_len8; + FAPI_INF("scom_address=%llX",l_scom_add); + FAPI_INF("start bit=%d",l_start_bit); + FAPI_INF("length=%d",l_len8); + + } + + else if(i_input_type_e==RAW_RD_DQ_0 || i_input_type_e==RAW_RD_DQ_1 || i_input_type_e==RAW_RD_DQ_2 || i_input_type_e==RAW_RD_DQ_3 || i_input_type_e==RAW_RD_DQ_4) + { + if(i_input_type_e==RAW_RD_DQ_0) + { + l_block=0; + } + else if(i_input_type_e==RAW_RD_DQ_1) + { + l_block=1; + } + else if(i_input_type_e==RAW_RD_DQ_2) + { + l_block=2; + } + else if(i_input_type_e==RAW_RD_DQ_3) + { + l_block=3; + } + else + { + l_block=4; + } + if(i_input_index_u8<=15) // 16 read delay values for DQ bits + { + l_lane=i_input_index_u8; + } + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input index specified rc = 0x%08X ", uint32_t(rc)); + return rc; + } + ip_type_t l_input=RAW_RD_DQ; + FAPI_INF("block=%d",l_block); + FAPI_INF("lane=%d",l_lane); + rc=get_address(i_target_mba,i_port_u8,l_rank_pair,l_input,l_block,l_lane,l_scom_add,l_start_bit,l_len8); if(rc) return rc; + l_sbit=l_start_bit; + l_len=l_len8; + FAPI_INF("scom_address=%llX",l_scom_add); + FAPI_INF("start bit=%d",l_start_bit); + FAPI_INF("length=%d",l_len8); + + } + + else if(i_input_type_e==RAW_RD_DQS_0 || i_input_type_e==RAW_RD_DQS_1 || i_input_type_e==RAW_RD_DQS_2 || i_input_type_e==RAW_RD_DQS_3 || i_input_type_e==RAW_RD_DQS_4) + { + if(i_input_type_e==RAW_RD_DQS_0) + { + l_block=0; + } + else if(i_input_type_e==RAW_RD_DQS_1) + { + l_block=1; + } + else if(i_input_type_e==RAW_RD_DQS_2) + { + l_block=2; + } + else if(i_input_type_e==RAW_RD_DQS_3) + { + l_block=3; + } + else + { + l_block=4; + } + if(i_input_index_u8<=3) // 4 Read DQS delay values + { + l_lane=i_input_index_u8; + } + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input index specified rc = 0x%08X ", uint32_t(rc)); + return rc; + } + + ip_type_t l_input=RAW_RD_DQS; + FAPI_INF("block=%d",l_block); + FAPI_INF("lane=%d",l_lane); + rc=get_address(i_target_mba,i_port_u8,l_rank_pair,l_input,l_block,l_lane,l_scom_add,l_start_bit,l_len8); if(rc) return rc; + l_sbit=l_start_bit; + l_len=l_len8; + FAPI_INF("scom_address=%llX",l_scom_add); + FAPI_INF("start bit=%d",l_start_bit); + FAPI_INF("length=%d",l_len8); + + } + + else if(i_input_type_e==RAW_DQS_ALIGN_0 || i_input_type_e==RAW_DQS_ALIGN_1 || i_input_type_e==RAW_DQS_ALIGN_2 || i_input_type_e==RAW_DQS_ALIGN_3 || i_input_type_e==RAW_DQS_ALIGN_4) + { + if(i_input_type_e==RAW_DQS_ALIGN_0) + { + l_block=0; + } + else if(i_input_type_e==RAW_DQS_ALIGN_1) + { + l_block=1; + } + else if(i_input_type_e==RAW_DQS_ALIGN_2) + { + l_block=2; + } + else if(i_input_type_e==RAW_DQS_ALIGN_3) + { + l_block=3; + } + else + { + l_block=4; + } + if(i_input_index_u8<=3) // 4 DQS alignment delay values + { + l_lane=i_input_index_u8; + } + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input index specified rc = 0x%08X ", uint32_t(rc)); + return rc; + } + ip_type_t l_input=RAW_DQS_ALIGN; + FAPI_INF("block=%d",l_block); + FAPI_INF("lane=%d",l_lane); + rc=get_address(i_target_mba,i_port_u8,l_rank_pair,l_input,l_block,l_lane,l_scom_add,l_start_bit,l_len8); if(rc) return rc; + l_sbit=l_start_bit; + l_len=l_len8; + FAPI_INF("scom_address=%llX",l_scom_add); + FAPI_INF("start bit=%d",l_start_bit); + FAPI_INF("length=%d",l_len8); + + } + + + else if(i_input_type_e==RAW_WR_DQS_0 || i_input_type_e==RAW_WR_DQS_1 || i_input_type_e==RAW_WR_DQS_2 || i_input_type_e==RAW_WR_DQS_3 || i_input_type_e==RAW_WR_DQS_4) + { + if(i_input_type_e==RAW_WR_DQS_0) + { + l_block=0; + } + else if(i_input_type_e==RAW_WR_DQS_1) + { + l_block=1; + } + else if(i_input_type_e==RAW_WR_DQS_2) + { + l_block=2; + } + else if(i_input_type_e==RAW_WR_DQS_3) + { + l_block=3; + } + else + { + l_block=4; + } + if(i_input_index_u8<=3) // 4 Write DQS delay values + { + l_lane=i_input_index_u8; + } + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input index specified rc = 0x%08X ", uint32_t(rc)); + return rc; + } + ip_type_t l_input=RAW_WR_DQS; + FAPI_INF("block=%d",l_block); + FAPI_INF("lane=%d",l_lane); + rc=get_address(i_target_mba,i_port_u8,l_rank_pair,l_input,l_block,l_lane,l_scom_add,l_start_bit,l_len8); if(rc) return rc; + l_sbit=l_start_bit; + l_len=l_len8; + FAPI_INF("scom_address=%llX",l_scom_add); + FAPI_INF("start bit=%d",l_start_bit); + FAPI_INF("length=%d",l_len8); + + } + else if(i_input_type_e==RAW_SYS_CLK_0 || i_input_type_e==RAW_SYS_CLK_1 || i_input_type_e==RAW_SYS_CLK_2 || i_input_type_e==RAW_SYS_CLK_3 || i_input_type_e==RAW_SYS_CLK_4) + { + if(i_input_type_e==RAW_SYS_CLK_0) + { + l_block=0; + } + else if(i_input_type_e==RAW_SYS_CLK_1) + { + l_block=1; + } + else if(i_input_type_e==RAW_SYS_CLK_2) + { + l_block=2; + } + else if(i_input_type_e==RAW_SYS_CLK_3) + { + l_block=3; + } + else + { + l_block=4; + } + if(i_input_index_u8==0) // 1 system clock delay value + { + l_lane=i_input_index_u8; + } + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input index specified rc = 0x%08X ", uint32_t(rc)); + return rc; + } + ip_type_t l_input=RAW_SYS_CLK; + FAPI_INF("block=%d",l_block); + FAPI_INF("lane=%d",l_lane); + rc=get_address(i_target_mba,i_port_u8,l_rank_pair,l_input,l_block,l_lane,l_scom_add,l_start_bit,l_len8); if(rc) return rc; + l_sbit=l_start_bit; + l_len=l_len8; + FAPI_INF("scom_address=%llX",l_scom_add); + FAPI_INF("start bit=%d",l_start_bit); + FAPI_INF("length=%d",l_len8); + + } + + else if(i_input_type_e==RAW_SYS_ADDR_CLK) + { + if(i_input_index_u8<=1) // 1 system address clock delay value + { + l_lane=i_input_index_u8; + } + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input index specified rc = 0x%08X ", uint32_t(rc)); + return rc; + } + ip_type_t l_input=RAW_SYS_ADDR_CLKS0S1; + FAPI_INF("lane=%d",l_lane); + rc=get_address(i_target_mba,i_port_u8,l_rank_pair,l_input,l_block,l_lane,l_scom_add,l_start_bit,l_len8); if(rc) return rc; + l_sbit=l_start_bit; + l_len=l_len8; + FAPI_INF("scom_address=%llX",l_scom_add); + FAPI_INF("start bit=%d",l_start_bit); + FAPI_INF("length=%d",l_len8); + + } + + + else if(i_input_type_e==RAW_WR_CLK_0 || i_input_type_e==RAW_WR_CLK_1 || i_input_type_e==RAW_WR_CLK_2 || i_input_type_e==RAW_WR_CLK_3 || i_input_type_e==RAW_WR_CLK_4) + { + if(i_input_type_e==RAW_WR_CLK_0) + { + l_block=0; + } + else if(i_input_type_e==RAW_WR_CLK_1) + { + l_block=1; + } + else if(i_input_type_e==RAW_WR_CLK_2) + { + l_block=2; + } + else if(i_input_type_e==RAW_WR_CLK_3) + { + l_block=3; + } + else + { + l_block=4; + } + if(i_input_index_u8==0) // 1 Write clock delay value + { + l_lane=i_input_index_u8; + } + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input index specified rc = 0x%08X ", uint32_t(rc)); + return rc; + } + ip_type_t l_input=RAW_WR_CLK; + FAPI_INF("block=%d",l_block); + FAPI_INF("lane=%d",l_lane); + rc=get_address(i_target_mba,i_port_u8,l_rank_pair,l_input,l_block,l_lane,l_scom_add,l_start_bit,l_len8); if(rc) return rc; + l_sbit=l_start_bit; + l_len=l_len8; + FAPI_INF("scom_address=%llX",l_scom_add); + FAPI_INF("start bit=%d",l_start_bit); + FAPI_INF("length=%d",l_len8); + + } + + else if(i_input_type_e==RAW_ADDR_0 || i_input_type_e==RAW_ADDR_1 || i_input_type_e==RAW_ADDR_2 || i_input_type_e==RAW_ADDR_3) + { + if(i_input_type_e==RAW_ADDR_0) + { + l_block=0; + } + else if(i_input_type_e==RAW_ADDR_1) + { + l_block=1; + } + else if(i_input_type_e==RAW_ADDR_2) + { + l_block=2; + } + else + { + l_block=3; + } + if(i_input_index_u8<=15) // 16 Addr delay values + { + l_lane=i_input_index_u8; + } + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input index specified rc = 0x%08X ", uint32_t(rc)); + return rc; + } + ip_type_t l_input=RAW_ADDR; + FAPI_INF("block=%d",l_block); + FAPI_INF("lane=%d",l_lane); + rc=get_address(i_target_mba,i_port_u8,l_rank_pair,l_input,l_block,l_lane,l_scom_add,l_start_bit,l_len8); if(rc) return rc; + l_sbit=l_start_bit; + l_len=l_len8; + FAPI_INF("scom_address=%llX",l_scom_add); + FAPI_INF("start bit=%d",l_start_bit); + FAPI_INF("length=%d",l_len8); + + } + + else if(i_input_type_e==RAW_DQS_GATE_0 || i_input_type_e==RAW_DQS_GATE_1 || i_input_type_e==RAW_DQS_GATE_2 || i_input_type_e==RAW_DQS_GATE_3 || i_input_type_e==RAW_DQS_GATE_4) + { + if(i_input_type_e==RAW_DQS_GATE_0) + { + l_block=0; + } + else if(i_input_type_e==RAW_DQS_GATE_1) + { + l_block=1; + } + else if(i_input_type_e==RAW_DQS_GATE_2) + { + l_block=2; + } + else if(i_input_type_e==RAW_DQS_GATE_3) + { + l_block=3; + } + else + { + l_block=4; + } + + if(i_input_index_u8<=3) // 4 Gate Delay values + { + l_lane=i_input_index_u8; + } + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input index specified rc = 0x%08X ", uint32_t(rc)); + return rc; + } + ip_type_t l_input=RAW_DQS_GATE; + FAPI_INF("block=%d",l_block); + FAPI_INF("lane=%d",l_lane); + rc=get_address(i_target_mba,i_port_u8,l_rank_pair,l_input,l_block,l_lane,l_scom_add,l_start_bit,l_len8); if(rc) return rc; + l_sbit=l_start_bit; + l_len=l_len8; + FAPI_INF("scom_address=%llX",l_scom_add); + FAPI_INF("start bit=%d",l_start_bit); + FAPI_INF("length=%d",l_len8); + + } + + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input type specified rc = 0x%08X ", uint32_t(rc)); + return rc; + } + + if(i_access_type_e==READ) + { + rc=fapiGetScom(i_target_mba,l_scom_add,data_buffer_64);if(rc) return rc; + rc_num= rc_num | data_buffer_64.extractToRight(&l_output,l_sbit,l_len); + if(rc_num) + { + FAPI_ERR( "ecmd error on l_scom_add extract"); + rc.setEcmdError(rc_num); + return rc; + } + io_value_u32=l_output; + } + + else if(i_access_type_e==WRITE) + { + + if(i_input_type_e==RD_DQ || i_input_type_e==RD_DQS || i_input_type_e==RAW_RD_DQ_0 || i_input_type_e==RAW_RD_DQ_1 || i_input_type_e==RAW_RD_DQ_2 || i_input_type_e==RAW_RD_DQ_3 || i_input_type_e==RAW_RD_DQ_4 || i_input_type_e==RAW_RD_DQS_0 || i_input_type_e==RAW_RD_DQS_1 || i_input_type_e==RAW_RD_DQS_2 || i_input_type_e==RAW_RD_DQS_3 || i_input_type_e==RAW_RD_DQS_4 + || i_input_type_e==RAW_SYS_ADDR_CLK || i_input_type_e==RAW_SYS_CLK_0 || i_input_type_e==RAW_SYS_CLK_1 || i_input_type_e==RAW_SYS_CLK_2 || i_input_type_e==RAW_SYS_CLK_3 || i_input_type_e==RAW_SYS_CLK_4 || i_input_type_e==RAW_WR_CLK_0 || i_input_type_e==RAW_WR_CLK_1 || i_input_type_e==RAW_WR_CLK_2 || i_input_type_e==RAW_WR_CLK_3 || i_input_type_e==RAW_WR_CLK_4 + || i_input_type_e==RAW_ADDR_0 || i_input_type_e==RAW_ADDR_1 || i_input_type_e==RAW_ADDR_2 || i_input_type_e==RAW_ADDR_3 || i_input_type_e==RAW_DQS_ALIGN_0 || i_input_type_e==RAW_DQS_ALIGN_1 || i_input_type_e==RAW_DQS_ALIGN_2 || i_input_type_e==RAW_DQS_ALIGN_3 || i_input_type_e==RAW_DQS_ALIGN_4 + || i_input_type_e==DQS_ALIGN ) + { + l_start=25; // l_start is starting bit of delay value in the register. There are different registers and each register has a different field for delay + } + else if(i_input_type_e==WR_DQ || i_input_type_e==WR_DQS || i_input_type_e==RAW_WR_DQ_0 || i_input_type_e==RAW_WR_DQ_1 || i_input_type_e==RAW_WR_DQ_2 || i_input_type_e==RAW_WR_DQ_3 || i_input_type_e==RAW_WR_DQ_4 || i_input_type_e==RAW_WR_DQS_0 || i_input_type_e==RAW_WR_DQS_1 || i_input_type_e==RAW_WR_DQS_2 || i_input_type_e==RAW_WR_DQS_3 || i_input_type_e==RAW_WR_DQS_4 ) + { + l_start=22; + } + + else if(i_input_type_e==RAW_DQS_GATE_0 || i_input_type_e==RAW_DQS_GATE_1 || i_input_type_e==RAW_DQS_GATE_2 || i_input_type_e==RAW_DQS_GATE_3 || i_input_type_e==RAW_DQS_GATE_4 || i_input_type_e==DQS_GATE) + { + l_start=29; + } + else + { + FAPI_ERR("Wrong input value specified rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + return rc; + } + rc=fapiGetScom(i_target_mba,l_scom_add,data_buffer_64);if(rc) return rc; + rc_num=data_buffer_64.insert(io_value_u32,l_sbit,l_len,l_start); + if(rc_num) + { + FAPI_ERR( "ecmd error on l_scom_add extract"); + rc.setEcmdError(rc_num); + return rc; + } + rc=fapiPutScom(i_target_mba,l_scom_add,data_buffer_64); if(rc) return rc; + } + return rc; +} + + + + +//****************************************************************************** +//Function name: cross_coupled() +//Description:This function returns address,start bit and bit length for RD_DQ, WR_DQ, RD_DQS, WR_DQS +//Input : Target MBA=i_target_mba, i_port_u8=0 or 1, i_rank_pair=0 or 1 or 2 or 3, i_input_type_e=RD_DQ or RD_DQS or WR_DQ or WR_DQS,i_input_index_u8=0-79/0-71/0-8/0-19 +//Output : out (address,start bit and bit length) +//****************************************************************************** + +fapi::ReturnCode cross_coupled(const fapi::Target & i_target_mba,uint8_t i_port, uint8_t i_rank_pair,input_type_t i_input_type_e,uint8_t i_input_index,scom_location& out) +{ + fapi::ReturnCode rc; + const uint8_t l_dqmax=80; + const uint8_t l_dqsmax=20; + const uint8_t lane_dq_p0[l_dqmax]={4,6,5,7,2,1,3,0,13,15,12,14,8,9,11,10,13,15,12,14,9,8,11,10,13,15,12,14,11,9,10,8,11,8,9,10,12,13,14,15,7,6,5,4,1,3,2,0,5,6,4,7,3,1,2,0,7,4,5,6,2,0,3,1,3,0,1,2,6,5,4,7,11,8,9,10,15,13,12,14}; + const uint8_t lane_dq_p1[l_dqmax]={9,11,8,10,13,14,15,12,10,8,11,9,12,13,14,15,1,0,2,3,4,5,6,7,9,11,10,8,15,12,13,14,5,7,6,4,1,0,2,3,0,2,1,3,5,4,6,7,0,2,3,1,4,5,6,7,12,15,13,14,11,8,10,9,5,7,4,6,3,2,0,1,14,12,15,13,9,8,11,10}; + const uint8_t lane_dq_p2[l_dqmax]={13,15,12,14,11,9,10,8,13,12,14,15,10,9,11,8,5,6,7,4,2,3,0,1,10,9,8,11,13,12,15,14,15,12,13,14,11,10,9,8,7,6,4,5,1,0,3,2,0,2,1,3,5,6,4,7,5,7,6,4,1,0,2,3,1,2,3,0,7,6,5,4,9,10,8,11,12,15,14,13}; + const uint8_t lane_dq_p3[l_dqmax]={4,5,6,7,0,1,3,2,12,13,15,14,8,9,10,11,10,8,11,9,12,13,15,14,3,0,1,2,4,6,7,5,9,10,11,8,14,13,15,12,7,5,6,4,3,1,2,0,5,6,7,4,1,2,3,0,14,12,15,13,8,10,9,11,0,3,2,1,6,5,7,4,10,11,9,8,12,13,15,14}; + const uint8_t dqs_dq_lane_p0[l_dqsmax]={4,0,12,8,12,8,12,8,8,12,4,0,4,0,4,0,0,4,8,12}; + const uint8_t dqs_dq_lane_p1[l_dqsmax]={8,12,8,12,0,4,8,12,4,0,0,4,0,4,12,8,4,0,12,8}; + const uint8_t dqs_dq_lane_p2[l_dqsmax]={12,8,12,8,4,0,8,12,12,8,4,0,0,4,4,0,0,4,8,12}; + const uint8_t dqs_dq_lane_p3[l_dqsmax]={4,0,12,8,8,12,0,4,8,12,4,0,4,0,12,8,0,4,8,12}; + const uint8_t block_p1[l_dqmax]={0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2}; + const uint8_t block_p0[l_dqmax]={2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1}; + const uint8_t block_p2[l_dqmax]={1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4}; + const uint8_t block_p3[l_dqmax]={2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; + const uint8_t block_dqs_p0[l_dqsmax]={2,2,2,2,0,0,3,3,4,4,3,3,4,4,1,1,0,0,1,1}; + const uint8_t block_dqs_p1[l_dqsmax]={0,0,3,3,0,0,1,1,2,2,3,3,4,4,4,4,1,1,2,2}; + const uint8_t block_dqs_p2[l_dqsmax]={1,1,3,3,0,0,0,0,2,2,2,2,3,3,4,4,1,1,4,4}; + const uint8_t block_dqs_p3[l_dqsmax]={2,2,2,2,0,0,0,0,3,3,3,3,4,4,4,4,1,1,1,1}; + uint8_t l_mbapos = 0; + uint8_t l_dram_width=0; + uint8_t l_lane=0; + uint8_t l_block=0; + uint8_t lane_dqs[4]; + uint8_t l_index=0; + uint8_t l_dq=0; + uint64_t l_scom_address_64=0x0ull; + uint8_t l_start_bit=0; + uint8_t l_len=0; + ip_type_t l_input_type; + ecmdDataBufferBase data_buffer_64(64); + + rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_target_mba, l_mbapos); if(rc) return rc; + + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &i_target_mba, l_dram_width); if(rc) return rc; + + + if(i_input_type_e==RD_DQ || i_input_type_e==WR_DQ) + { + if(i_port==0 && l_mbapos==0) + { + l_lane=lane_dq_p0[i_input_index]; + l_block=block_p0[i_input_index]; + } + else if(i_port==1 && l_mbapos==0) + { + l_lane=lane_dq_p1[i_input_index]; + l_block=block_p1[i_input_index]; + } + else if(i_port==0 && l_mbapos==1) + { + l_lane=lane_dq_p2[i_input_index]; + l_block=block_p2[i_input_index]; + } + else + { + l_lane=lane_dq_p3[i_input_index]; + l_block=block_p3[i_input_index]; + } + + FAPI_INF("block=%d",l_block); + FAPI_INF("lane=%d",l_lane); + + if(i_input_type_e==RD_DQ) + { + l_input_type=RD_DQ_t; + } + else + { + l_input_type=WR_DQ_t; + } + + + rc=get_address(i_target_mba,i_port,i_rank_pair,l_input_type,l_block,l_lane,l_scom_address_64,l_start_bit,l_len); if(rc) return rc; + out.scom_addr=l_scom_address_64; + out.start_bit=l_start_bit; + out.bit_length=l_len; + } + + else if (i_input_type_e==RD_DQS || i_input_type_e==WR_DQS || i_input_type_e==DQS_ALIGN) + { + + if(i_port==0 && l_mbapos==0) + { + l_dq=dqs_dq_lane_p0[i_input_index]; + l_block=block_dqs_p0[i_input_index]; + } + + else if(i_port==1 && l_mbapos==0) + { + l_dq=dqs_dq_lane_p1[i_input_index]; + l_block=block_dqs_p1[i_input_index]; + } + else if(i_port==0 && l_mbapos==1) + { + l_dq=dqs_dq_lane_p2[i_input_index]; + l_block=block_dqs_p2[i_input_index]; + } + else + { + l_dq=dqs_dq_lane_p3[i_input_index]; + l_block=block_dqs_p3[i_input_index]; + } + + FAPI_INF("block=%d",l_block); + FAPI_INF("dqs_dq_lane=%d",l_dq); + l_input_type=RD_CLK_t; + rc=get_address(i_target_mba,i_port,i_rank_pair, l_input_type,l_block,l_lane,l_scom_address_64,l_start_bit,l_len); if(rc) return rc; + FAPI_INF("read clock address=%llx",l_scom_address_64); + rc=fapiGetScom(i_target_mba,l_scom_address_64,data_buffer_64);if(rc) return rc; + + if(l_dram_width==fapi::ENUM_ATTR_EFF_DRAM_WIDTH_X4) + { + + if (data_buffer_64.isBitSet(48)) + { + lane_dqs[l_index]=16; + l_index++; + } + else if(data_buffer_64.isBitSet(52)) + { + lane_dqs[l_index]=18; + l_index++; + } + + if (data_buffer_64.isBitSet(49)) + { + lane_dqs[l_index]=16; + l_index++; + } + + else if (data_buffer_64.isBitSet(53)) + { + lane_dqs[l_index]=18; + l_index++; + } + + if (data_buffer_64.isBitSet(54)) + { + lane_dqs[l_index]=20; + l_index++; + } + else if (data_buffer_64.isBitSet(56)) + { + lane_dqs[l_index]=22; + l_index++; + } + + if (data_buffer_64.isBitSet(55)) + { + lane_dqs[l_index]=20; + l_index++; + } + else if (data_buffer_64.isBitSet(57)) // else is not possible as one of them will definitely get set + { + lane_dqs[l_index]=22; + l_index++; + } + FAPI_INF("array is=%d and %d and %d and %d",lane_dqs[0],lane_dqs[1],lane_dqs[2],lane_dqs[3]); + if(l_dq==0) + { + l_lane=lane_dqs[0]; + } + else if(l_dq==4) + { + l_lane=lane_dqs[1]; + } + else if(l_dq==8) + { + l_lane=lane_dqs[2]; + } + else + { + l_lane=lane_dqs[3]; + } + + FAPI_INF("lane is=%d",l_lane); + + } + + + else + { + if (data_buffer_64.isBitSet(48)&& data_buffer_64.isBitSet(49)) + { + lane_dqs[l_index]=16; + l_index++; + } + else if (data_buffer_64.isBitSet(52)&& data_buffer_64.isBitSet(53)) + { + lane_dqs[l_index]=18; + l_index++; + } + if (data_buffer_64.isBitSet(54)&& data_buffer_64.isBitSet(55)) + { + lane_dqs[l_index]=20; + l_index++; + } + else if (data_buffer_64.isBitSet(56)&& data_buffer_64.isBitSet(57)) // else is not possible as one of them will definitely get set + { + lane_dqs[l_index]=22; + l_index++; + } + FAPI_INF("array is=%d and %d",lane_dqs[0],lane_dqs[1]); + + if((l_dq==0) || (l_dq==4)) + { + l_lane=lane_dqs[0]; + } + else + { + l_lane=lane_dqs[1]; + } + + FAPI_INF("lane is=%d",l_lane); + } + + if (i_input_type_e==RD_DQS) + { + l_input_type=RD_DQS_t; + } + else if(i_input_type_e==WR_DQS) + { + l_input_type=WR_DQS_t; + } + else + { + l_input_type=DQS_ALIGN_t; + } + + rc=get_address(i_target_mba,i_port,i_rank_pair,l_input_type,l_block,l_lane,l_scom_address_64,l_start_bit,l_len); if(rc) return rc; + out.scom_addr=l_scom_address_64; + out.start_bit=l_start_bit; + out.bit_length=l_len; + } + + + else if (i_input_type_e==DQS_GATE) + { + + if(i_port==0 && l_mbapos==0) + { + l_dq=dqs_dq_lane_p0[i_input_index]; + l_block=block_dqs_p0[i_input_index]; + } + + else if(i_port==1 && l_mbapos==0) + { + l_dq=dqs_dq_lane_p1[i_input_index]; + l_block=block_dqs_p1[i_input_index]; + } + else if(i_port==0 && l_mbapos==1) + { + l_dq=dqs_dq_lane_p2[i_input_index]; + l_block=block_dqs_p2[i_input_index]; + } + else + { + l_dq=dqs_dq_lane_p3[i_input_index]; + l_block=block_dqs_p3[i_input_index]; + } + + FAPI_INF("block=%d",l_block); + FAPI_INF("dqs_dq_lane=%d",l_dq); + + if(l_dq==0) + { + l_lane=16; + } + + else if(l_dq==4) + { + l_lane=18; + } + + else if (l_dq==8) + { + l_lane=20; + } + + else + { + l_lane=22; + } + + l_input_type=DQS_GATE_t; + + FAPI_INF("lane is=%d",l_lane); + + rc=get_address(i_target_mba,i_port,i_rank_pair,l_input_type,l_block,l_lane,l_scom_address_64,l_start_bit,l_len); if(rc) return rc; + out.scom_addr=l_scom_address_64; + out.start_bit=l_start_bit; + out.bit_length=l_len; + } + + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input type specified rc = 0x%08X ", uint32_t(rc)); + return rc; + } + + + return rc; +} + + +//****************************************************************************** +//Function name: rosetta_map() +//Description:This function returns C4 bit for the corresponding ISDIMM bit +//Input : Target MBA=i_target_mba, i_port_u8=0 or 1,i_input_type_e=RD_DQ or RD_DQS or WR_DQ or WR_DQS, i_input_index_u8=0-79/0-71/0-8/0-19 +//Output : C4 bit=o_value +//****************************************************************************** + +fapi::ReturnCode rosetta_map(const fapi::Target & i_target_mba,uint8_t i_port,input_type i_input_type_e,uint8_t i_input_index,uint8_t &o_value) //This function is used by some other procedures +{ // Boundary check is done again + fapi::ReturnCode rc; + + const uint8_t l_ISDIMM_dqmax=71; + const uint8_t l_CDIMM_dqmax=79; + uint8_t l_mbapos = 0; + uint8_t l_dimmtype=0; + const uint8_t l_maxdq=72; + const uint8_t l_maxdqs=18; + uint8_t l_swizzle=0; + const uint8_t GL_DQ_p0_g1[l_maxdq]={10,9,11,8,12,13,14,15,3,1,2,0,7,5,4,6,20,21,22,23,16,17,18,19,64,65,66,67,71,70,69,68,32,33,34,35,36,37,38,39,42,40,43,41,44,46,45,47,48,51,50,49,52,53,54,55,58,56,57,59,60,61,62,63,31,28,29,30,25,27,26,24}; + const uint8_t GL_DQ_p0_g2[l_maxdq]={10,9,11,8,12,13,14,15,3,1,2,0,7,5,4,6,16,17,18,19,20,21,22,23,64,65,66,67,71,70,69,68,32,33,34,35,36,37,38,39,42,40,43,41,44,46,45,47,48,51,50,49,52,53,54,55,58,56,57,59,60,61,62,63,25,27,26,24,28,31,29,30}; + const uint8_t GL_DQ_p1_g1[l_maxdq]={15,13,12,14,9,8,10,11,5,7,4,6,3,2,1,0,20,22,21,23,16,17,18,19,70,71,69,68,67,66,65,64,32,35,34,33,38,37,39,36,40,41,42,43,44,45,46,47,49,50,48,51,52,53,54,55,59,57,56,58,60,62,61,63,27,26,25,24,31,30,28,29}; + const uint8_t GL_DQ_p1_g2[l_maxdq]={8,9,10,11,12,13,14,15,3,2,1,0,4,5,6,7,16,17,18,19,20,21,22,23,67,66,64,65,70,71,69,68,32,35,34,33,38,37,39,36,40,41,42,43,44,45,46,47,49,50,48,51,52,53,54,55,59,57,56,58,60,62,61,63,27,26,25,24,31,30,28,29}; + const uint8_t GL_DQ_p2[l_maxdq]={9,11,10,8,12,15,13,14,0,1,3,2,5,4,7,6,19,17,16,18,20,22,21,23,66,67,65,64,71,70,69,68,32,33,34,35,36,37,38,39,41,40,43,42,45,44,47,46,48,49,50,51,52,53,54,55,58,56,57,59,60,61,62,63,25,27,24,26,28,31,29,30}; + const uint8_t GL_DQ_p3[l_maxdq]={3,2,0,1,4,5,6,7,11,10,8,9,15,14,12,13,16,17,18,19,20,21,22,23,64,65,66,67,68,69,70,71,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,24,25,26,27,28,29,30,31}; + + const uint8_t GL_DQS_p0_g1[l_maxdqs]={2,0,5,16,8,10,12,14,7,3,1,4,17,9,11,13,15,6}; + const uint8_t GL_DQS_p0_g2[l_maxdqs]={2,0,4,16,8,10,12,14,6,3,1,5,17,9,11,13,15,7}; + const uint8_t GL_DQS_p1_g1[l_maxdqs]={3,1,5,16,8,10,12,14,6,2,0,4,17,9,11,13,15,7}; + const uint8_t GL_DQS_p1_g2[l_maxdqs]={2,0,4,16,8,10,12,14,6,3,1,5,17,9,11,13,15,7}; + const uint8_t GL_DQS_p2[l_maxdqs]={2,0,4,16,8,10,12,14,6,3,1,5,17,9,11,13,15,7}; + const uint8_t GL_DQS_p3[l_maxdqs]={0,2,4,16,8,10,12,14,6,1,3,5,17,9,11,13,15,7}; + + rc = FAPI_ATTR_GET(ATTR_MSS_DQS_SWIZZLE_TYPE, &i_target_mba, l_swizzle); if(rc) return rc; + + + if(l_swizzle ==0 || l_swizzle ==1) + { + FAPI_INF("swizzle type=%d",l_swizzle); + } + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong swizzle value rc = 0x%08X ", uint32_t(rc)); + return rc; + } + + rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_target_mba, l_mbapos); if(rc) return rc; + + if((i_port >1) || (l_mbapos>1)) // Checking it again since this function will be called by some other procedures + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong target or port specified rc = 0x%08X ", uint32_t(rc)); + return rc; + } + + rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target_mba, l_dimmtype); if(rc) return rc; + + if(l_dimmtype==fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM) + { + if(i_input_index>l_CDIMM_dqmax) + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input index specified rc = 0x%08X" ,uint32_t(rc)); + return rc; + } + } + + else if((l_dimmtype==fapi::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM) || (l_dimmtype==fapi::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM) || (l_dimmtype==fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM)) + { + if(i_input_index>l_ISDIMM_dqmax) + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input index specified rc = 0x%08X", uint32_t(rc)); + return rc; + } + } + + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong dimm type specified rc = 0x%08X", uint32_t(rc)); + return rc; + } + + + + if(i_input_type_e ==ISDIMM_DQ) + { + if(i_port==0 && l_mbapos==0) + { + if(l_swizzle==1) + { + o_value=GL_DQ_p0_g1[i_input_index]; + } + else + { + o_value=GL_DQ_p0_g2[i_input_index]; + } + + } + + else if(i_port==1 && l_mbapos==0) + { + if(l_swizzle==1) + { + o_value=GL_DQ_p1_g1[i_input_index]; + } + else + { + o_value=GL_DQ_p1_g2[i_input_index]; + } + } + + else if(i_port==0 && l_mbapos==1) + { + o_value=GL_DQ_p2[i_input_index]; + } + else + { + o_value=GL_DQ_p3[i_input_index]; + } + + } + + + else if(i_input_type_e ==ISDIMM_DQS) + { + + if(i_port==0 && l_mbapos==0) + { + if(l_swizzle==1) + { + o_value=GL_DQS_p0_g1[i_input_index]; + } + else + { + o_value=GL_DQS_p0_g2[i_input_index]; + } + + } + else if(i_port==1 && l_mbapos==0) + { + if(l_swizzle==1) + { + o_value=GL_DQS_p1_g1[i_input_index]; + } + else + { + o_value=GL_DQS_p1_g2[i_input_index]; + } + + } + else if(i_port==0 && l_mbapos==1) + { + o_value=GL_DQS_p2[i_input_index]; + } + else + { + o_value=GL_DQS_p3[i_input_index]; + } + + } + else if(i_input_type_e==CDIMM_DQS) + { + o_value=i_input_index; + } + + else if(i_input_type_e==CDIMM_DQ) + { + o_value=i_input_index; + } + + else + { + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Wrong input type specified rc = 0x%08X ", uint32_t(rc)); + return rc; + } + + + + return rc; +} + + +//****************************************************************************** +//Function name: get address() +//Description:This function returns address,start bit and bit length for RD_DQ, WR_DQ, RD_DQS, WR_DQS +//Input : Target MBA=i_target_mba, i_port_u8=0 or 1, i_rank_pair=0 or 1 or 2 or 3, i_input_type_e=RD_DQ or RD_DQS or WR_DQ or WR_DQS, i_block=0 or 1 or 2 or 3 or 4, i_lane=0-15 +//Output : scom address=o_scom_address_64, start bit=o_start_bit, bit length=o_len +//****************************************************************************** + +fapi::ReturnCode get_address(const fapi::Target & i_target_mba,uint8_t i_port, uint8_t i_rank_pair,ip_type_t i_input_type_e,uint8_t i_block,uint8_t i_lane, uint64_t &o_scom_address_64,uint8_t &o_start_bit,uint8_t &o_len) +{ + fapi::ReturnCode rc; + + uint64_t l_scom_address_64 = 0x0ull; + uint64_t l_temp=0x0ull; + uint8_t l_mbapos; + uint8_t l_lane=0; + const uint64_t l_port01_st=0x8000000000000000ull; + const uint64_t l_port23_st=0x8001000000000000ull; + const uint32_t l_port01_en=0x0301143f; + const uint64_t l_rd_port01_en=0x040301143full; + const uint64_t l_sys_clk_en=0x730301143full; + const uint64_t l_wr_clk_en =0x740301143full; + const uint64_t l_adr02_st=0x8000400000000000ull; + const uint64_t l_adr13_st=0x8001400000000000ull; + const uint64_t l_dqs_gate_en=0x130301143full; + rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_target_mba, l_mbapos); if(rc) return rc; + + if(i_input_type_e==WR_DQ_t || i_input_type_e==RAW_WR_DQ) + { + if(i_lane > 7) + { + l_scom_address_64 = 0x00000040; + l_scom_address_64=l_scom_address_64<<32; + l_temp|=(i_lane-8); + } + + else + { + l_scom_address_64|=0x00000038; + l_scom_address_64=l_scom_address_64<<32; + l_temp|=i_lane; + } + l_temp|=(i_block*4)<<8; + l_temp|=i_rank_pair<<8; + l_temp=l_temp<<32; + if((i_port==0 && l_mbapos==0) || (i_port==0 && l_mbapos==1)) + { + l_scom_address_64|= l_port01_st | l_temp | l_port01_en; + } + else + { + l_scom_address_64|= l_port23_st | l_temp | l_port01_en; + } + + o_scom_address_64=l_scom_address_64; + o_start_bit=48; + o_len=10; + + } + + else if(i_input_type_e==RD_DQ_t || i_input_type_e==RAW_RD_DQ) + { + l_scom_address_64|=0x00000050; + l_scom_address_64=l_scom_address_64<<32; + l_lane=i_lane/2; + l_temp|=l_lane; + l_temp|=(i_block*4)<<8; + l_temp|=i_rank_pair<<8; + l_temp=l_temp<<32; + if((i_port==0 && l_mbapos==0) || (i_port==0 && l_mbapos==1)) + { + l_scom_address_64|= l_port01_st | l_temp | l_port01_en; + } + else + { + l_scom_address_64|= l_port23_st | l_temp | l_port01_en; + } + + if((i_lane % 2) == 0) + { + o_start_bit=48; + o_len=7; + } + else + { + o_start_bit=56; + o_len=7; + } + + + o_scom_address_64=l_scom_address_64; + + } + + + else if(i_input_type_e==WR_DQS_t || i_input_type_e==RAW_WR_DQS) + { + + if(i_input_type_e==RAW_WR_DQS) + { + if(i_lane==0) + { + i_lane=16; + } + else if(i_lane==1) + { + i_lane=18; + } + else if(i_lane==2) + { + i_lane=20; + } + else + { + i_lane=22; + } + } + if(i_lane==16) + { + l_scom_address_64|=0x00000048; + } + else if(i_lane==18) + { + l_scom_address_64|=0x0000004a; + } + else if(i_lane==20) + { + l_scom_address_64|=0x0000004c; + } + else + { + l_scom_address_64|=0x0000004e; + } + + l_scom_address_64=l_scom_address_64<<32; + l_temp|=(i_block*4)<<8; + l_temp|=i_rank_pair<<8; + l_temp=l_temp<<32; + if((i_port==0 && l_mbapos==0) || (i_port==0 && l_mbapos==1)) + { + l_scom_address_64|= l_port01_st | l_temp | l_port01_en; + } + else + { + l_scom_address_64|= l_port23_st | l_temp | l_port01_en; + } + + o_start_bit=48; + o_len=10; + o_scom_address_64=l_scom_address_64; + + } + + else if(i_input_type_e==RD_CLK_t) + { + l_temp|=(i_block*4)<<8; + l_temp|=i_rank_pair<<8; + l_temp=l_temp<<32; + if((i_port==0 && l_mbapos==0) || (i_port==0 && l_mbapos==1)) + { + l_scom_address_64|= l_port01_st | l_temp| l_rd_port01_en; + } + else + { + l_scom_address_64|= l_port23_st | l_temp| l_rd_port01_en; + } + + + o_start_bit=0; + o_len=0; + o_scom_address_64=l_scom_address_64; + + } + + else if(i_input_type_e==RD_DQS_t || i_input_type_e==RAW_RD_DQS) + { + + if(i_input_type_e==RAW_RD_DQS) + { + if(i_lane==0) + { + i_lane=16; + } + else if(i_lane==1) + { + i_lane=18; + } + else if(i_lane==2) + { + i_lane=20; + } + else + { + i_lane=22; + } + } + if(i_lane==16) + { + l_scom_address_64|=0x00000030; + o_start_bit=49; + } + else if(i_lane==18) + { + l_scom_address_64|=0x00000030; + o_start_bit=57; + } + else if(i_lane==20) + { + l_scom_address_64|=0x00000031; + o_start_bit=49; + } + else + { + l_scom_address_64|=0x00000031; + o_start_bit=57; + } + + l_scom_address_64=l_scom_address_64<<32; + l_temp|=(i_block*4)<<8; + l_temp|=i_rank_pair<<8; + l_temp=l_temp<<32; + + if((i_port==0 && l_mbapos==0) || (i_port==0 && l_mbapos==1)) + { + l_scom_address_64|= l_port01_st | l_temp | l_port01_en; + } + else + { + l_scom_address_64|= l_port23_st | l_temp | l_port01_en; + } + + + o_len=7; + o_scom_address_64=l_scom_address_64; + + } + + else if(i_input_type_e==DQS_ALIGN_t || i_input_type_e==RAW_DQS_ALIGN) + { + + if(i_input_type_e==RAW_DQS_ALIGN) + { + if(i_lane==0) + { + i_lane=16; + } + else if(i_lane==1) + { + i_lane=18; + } + else if(i_lane==2) + { + i_lane=20; + } + else + { + i_lane=22; + } + } + if(i_lane==16) + { + l_scom_address_64|=0x0000005c; + o_start_bit=49; + } + else if(i_lane==18) + { + l_scom_address_64|=0x0000005c; + o_start_bit=57; + } + else if(i_lane==20) + { + l_scom_address_64|=0x0000005d; + o_start_bit=49; + } + else + { + l_scom_address_64|=0x0000005d; + o_start_bit=57; + } + + l_scom_address_64=l_scom_address_64<<32; + l_temp|=(i_block*4)<<8; + l_temp|=i_rank_pair<<8; + l_temp=l_temp<<32; + if((i_port==0 && l_mbapos==0) || (i_port==0 && l_mbapos==1)) + { + l_scom_address_64|= l_port01_st | l_temp | l_port01_en; + } + else + { + l_scom_address_64|= l_port23_st | l_temp | l_port01_en; + } + + + o_len=7; + o_scom_address_64=l_scom_address_64; + + } + + + + else if(i_input_type_e==RAW_SYS_ADDR_CLKS0S1) + { + + if((i_port==0 && l_mbapos==0) || (i_port==0 && l_mbapos==1)) + { + if(i_lane==0) + { + l_scom_address_64=0x800080340301143full; + } + else + { + l_scom_address_64=0x800084340301143full; + } + } + + else + { + if(i_lane==0) + { + l_scom_address_64=0x800180340301143full; + } + else + { + l_scom_address_64=0x800184340301143full; + } + } + + o_start_bit=49; + o_len=7; + o_scom_address_64=l_scom_address_64; + + } + + else if(i_input_type_e==RAW_SYS_CLK) + { + l_temp|=(i_block*4)<<8; + l_temp=l_temp<<32; + if((i_port==0 && l_mbapos==0) || (i_port==0 && l_mbapos==1)) + { + l_scom_address_64|= l_port01_st | l_temp| l_sys_clk_en; + } + else + { + l_scom_address_64|= l_port23_st | l_temp| l_sys_clk_en; + } + + o_start_bit=49; + o_len=7; + o_scom_address_64=l_scom_address_64; + + } + + else if(i_input_type_e==RAW_WR_CLK) + { + l_temp|=(i_block*4)<<8; + l_temp=l_temp<<32; + if((i_port==0 && l_mbapos==0) || (i_port==0 && l_mbapos==1)) + { + l_scom_address_64|= l_port01_st | l_temp| l_wr_clk_en; + } + else + { + l_scom_address_64|= l_port23_st | l_temp| l_wr_clk_en; + } + + o_start_bit=49; + o_len=7; + o_scom_address_64=l_scom_address_64; + + } + + else if(i_input_type_e==RAW_ADDR) + { + l_scom_address_64|=0x00000004; + l_lane=i_lane; + if(i_lane<=7) + { + i_lane=i_lane/2; + } + else if(i_lane==8 || i_lane==9) + { + l_scom_address_64=0x00000008; + i_lane=0; + } + else if(i_lane==10 || i_lane==11) + { + l_scom_address_64=0x00000009; + i_lane=0; + } + else if(i_lane==12 || i_lane==13) + { + l_scom_address_64=0x0000000a; + i_lane=0; + } + else + { + l_scom_address_64=0x0000000b; + i_lane=0; + } + l_scom_address_64=l_scom_address_64<<32; + l_temp|=i_lane; + l_temp|=(i_block*4)<<8; + l_temp=l_temp<<32; + if((i_port==0 && l_mbapos==0) || (i_port==0 && l_mbapos==1)) + { + l_scom_address_64|= l_adr02_st | l_temp | l_port01_en; + } + else + { + l_scom_address_64|= l_adr13_st | l_temp | l_port01_en; + } + + if((l_lane % 2) == 0) + { + o_start_bit=49; + o_len=7; + } + else + { + o_start_bit=57; + o_len=7; + } + + + o_scom_address_64=l_scom_address_64; + + } + + else if(i_input_type_e==RAW_DQS_GATE || i_input_type_e==DQS_GATE_t) + { + //l_lane=i_lane; + l_lane=i_lane/4; + l_temp|=l_lane; + l_temp|=(i_block*4)<<8; + l_temp|=i_rank_pair<<8; + l_temp=l_temp<<32; + + if((i_port==0 && l_mbapos==0) || (i_port==0 && l_mbapos==1)) + { + l_scom_address_64|= l_port01_st | l_temp | l_dqs_gate_en; + } + else + { + l_scom_address_64|= l_port23_st | l_temp | l_dqs_gate_en; + } + + if(i_input_type_e==RAW_DQS_GATE) + { + if((i_lane % 4) == 0) + { + o_start_bit=49; + o_len=3; + } + else if((i_lane % 4) == 1) + { + o_start_bit=53; + o_len=3; + } + + else if((i_lane % 4) == 2) + { + o_start_bit=57; + o_len=3; + } + + else + { + o_start_bit=61; + o_len=3; + } + } + + else + { + if(l_lane == 16) + { + o_start_bit=49; + o_len=3; + } + else if(l_lane ==18) + { + o_start_bit=53; + o_len=3; + } + + else if(l_lane ==20) + { + o_start_bit=57; + o_len=3; + } + + else + { + o_start_bit=61; + o_len=3; + } + + } + + o_scom_address_64=l_scom_address_64; + + } + + return rc; +} + +//****************************************************************************** +//Function name: mss_getrankpair() +//Description:This function returns rank pair and valid ranks from a given rank +//Input : Target MBA=i_target_mba, i_port_u8=0 or 1, i_rank=valid ranks +//Output : rank pair=o_rank_pair, valid ranks=o_rankpair_table[] +//****************************************************************************** + +fapi::ReturnCode mss_getrankpair(const fapi::Target & i_target_mba,uint8_t i_port,uint8_t i_rank,uint8_t *o_rank_pair,uint8_t o_rankpair_table[]) +{ + fapi::ReturnCode rc; + uint8_t l_temp_rank[2]={0}; + uint8_t l_temp_rankpair_table[16]={0}; + uint8_t l_i= 0; + uint8_t l_rank_pair = 0; + uint8_t l_j= 0; + uint8_t l_temp_swap = 0; + + + for(l_i=0; l_i<8; l_i++) //populate Rank Pair Table as FF - invalid + { + //l_temp_rankpair_table[l_i]=255; + o_rankpair_table[l_i]=255; + } + + if(i_port==0 || i_port ==1) + { + + rc = FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP0, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[0]=l_temp_rank[i_port]; + + rc = FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP1, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[1]=l_temp_rank[i_port]; + + rc = FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP2, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[2]=l_temp_rank[i_port]; + rc = FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP3, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[3]=l_temp_rank[i_port]; + + rc = FAPI_ATTR_GET(ATTR_EFF_SECONDARY_RANK_GROUP0, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[4]=l_temp_rank[i_port]; + + rc = FAPI_ATTR_GET(ATTR_EFF_SECONDARY_RANK_GROUP1, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[5]=l_temp_rank[i_port]; + rc = FAPI_ATTR_GET(ATTR_EFF_SECONDARY_RANK_GROUP2, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[6]=l_temp_rank[i_port]; + + rc = FAPI_ATTR_GET(ATTR_EFF_SECONDARY_RANK_GROUP3, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[7]=l_temp_rank[i_port]; + + rc = FAPI_ATTR_GET(ATTR_EFF_TERTIARY_RANK_GROUP0, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[8]=l_temp_rank[i_port]; + + rc = FAPI_ATTR_GET(ATTR_EFF_TERTIARY_RANK_GROUP1, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[9]=l_temp_rank[i_port]; + + rc = FAPI_ATTR_GET(ATTR_EFF_TERTIARY_RANK_GROUP2, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[10]=l_temp_rank[i_port]; + + rc = FAPI_ATTR_GET(ATTR_EFF_TERTIARY_RANK_GROUP3, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[11]=l_temp_rank[i_port]; + + rc = FAPI_ATTR_GET(ATTR_EFF_QUATERNARY_RANK_GROUP0, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[12]=l_temp_rank[i_port]; + + rc = FAPI_ATTR_GET(ATTR_EFF_QUATERNARY_RANK_GROUP1, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[13]=l_temp_rank[i_port]; + + rc = FAPI_ATTR_GET(ATTR_EFF_QUATERNARY_RANK_GROUP2, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[14]=l_temp_rank[i_port]; + + rc = FAPI_ATTR_GET(ATTR_EFF_QUATERNARY_RANK_GROUP3, &i_target_mba, l_temp_rank);if(rc) return rc; + l_temp_rankpair_table[15]=l_temp_rank[i_port]; + + + } + + for(l_i=0; l_i<16; l_i++) + { + if(l_temp_rankpair_table[l_i]==i_rank) + { + l_rank_pair=l_i;break; + } + } + + l_rank_pair = l_rank_pair%4; // if index l_i is greater than 4,8,12 Secondary, Tertiary, Quaternary. + + + for(l_i=0; l_i<15; l_i++) + { + for(l_j=l_i+1;l_j<16;l_j++) + { + if(l_temp_rankpair_table[l_i]>l_temp_rankpair_table[l_j]) + { + l_temp_swap = l_temp_rankpair_table[l_j]; + l_temp_rankpair_table[l_j]=l_temp_rankpair_table[l_i]; + l_temp_rankpair_table[l_i]=l_temp_swap; + } + } + } + + for(l_i=0; l_i<8; l_i++) + { + if(l_temp_rankpair_table[l_i]!=255) + o_rankpair_table[l_i]=l_temp_rankpair_table[l_i]; + } + *o_rank_pair = l_rank_pair; + + + return rc; +} //end of mss_getrankpair + + + + + + +} // extern "C" diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_access_delay_reg.H b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_access_delay_reg.H new file mode 100644 index 000000000..bebaef857 --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_access_delay_reg.H @@ -0,0 +1,180 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_access_delay_reg.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +//$Id: mss_access_delay_reg.H,v 1.5 2012/12/05 16:50:29 sasethur Exp $ +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2011 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//------------------------------------------------------------------------------ +// *! TITLE : mss_demo_access_delay_reg.H +// *! DESCRIPTION : Header file for mss_access_delay_reg. +// *! OWNER NAME : Saurabh Chadha Email: sauchadh@in.ibm.com +// *! BACKUP NAME : Jacob Sloat Email: jdsloat@us.ibm.com +// *! ADDITIONAL COMMENTS : +// +// +// +//------------------------------------------------------------------------------ +// Don't forget to create CVS comments when you check in your changes! +//------------------------------------------------------------------------------ +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:| Author: | Date: | Comment: +//---------|----------|---------|----------------------------------------------- +// 1.1 | sauchadh |15-Oct-12| First Draft. +//------------------------------------------------------------------------------ + + +#ifndef MSS_ACCESS_DELAY_REG_H_ +#define MSS_ACCESS_DELAY_REG_H_ + +//------------------------------------------------------------------------------ +// My Includes +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Includes +//------------------------------------------------------------------------------ +#include <fapi.H> + + + +//---------------------------------------------------------------------- +// ENUMs +//---------------------------------------------------------------------- +enum access_type_t { + READ = 0, + WRITE = 1 +}; + +enum input_type_t { + WR_DQ, + RAW_WR_DQ_0, + RAW_WR_DQ_1, + RAW_WR_DQ_2, + RAW_WR_DQ_3, + RAW_WR_DQ_4, + RD_DQ, + RAW_RD_DQ_0, + RAW_RD_DQ_1, + RAW_RD_DQ_2, + RAW_RD_DQ_3, + RAW_RD_DQ_4, + WR_DQS, + RAW_WR_DQS_0, + RAW_WR_DQS_1, + RAW_WR_DQS_2, + RAW_WR_DQS_3, + RAW_WR_DQS_4, + RD_DQS, + RAW_RD_DQS_0, + RAW_RD_DQS_1, + RAW_RD_DQS_2, + RAW_RD_DQS_3, + RAW_RD_DQS_4, + RAW_SYS_ADDR_CLK, + RAW_SYS_CLK_0, + RAW_SYS_CLK_1, + RAW_SYS_CLK_2, + RAW_SYS_CLK_3, + RAW_SYS_CLK_4, + RAW_WR_CLK_0, + RAW_WR_CLK_1, + RAW_WR_CLK_2, + RAW_WR_CLK_3, + RAW_WR_CLK_4, + RAW_ADDR_0, + RAW_ADDR_1, + RAW_ADDR_2, + RAW_ADDR_3, + DQS_GATE, + RAW_DQS_GATE_0, + RAW_DQS_GATE_1, + RAW_DQS_GATE_2, + RAW_DQS_GATE_3, + RAW_DQS_GATE_4, + DQS_ALIGN, + RAW_DQS_ALIGN_0, + RAW_DQS_ALIGN_1, + RAW_DQS_ALIGN_2, + RAW_DQS_ALIGN_3, + RAW_DQS_ALIGN_4, + }; + +enum ip_type_t { + WR_DQ_t, + RAW_WR_DQ, + RD_DQ_t, + RAW_RD_DQ, + WR_DQS_t, + RAW_WR_DQS, + RD_DQS_t, + RAW_RD_DQS, + RD_CLK_t, + RAW_SYS_ADDR_CLKS0S1, + RAW_SYS_CLK, + RAW_WR_CLK, + RAW_ADDR, + DQS_GATE_t, + RAW_DQS_GATE, + DQS_ALIGN_t, + RAW_DQS_ALIGN, +}; + + +enum input_type { + ISDIMM_DQ, + ISDIMM_DQS, + CDIMM_DQS, + CDIMM_DQ, + GL_NET_DQ, + GL_NET_DQS +}; + +struct scom_location { + uint64_t scom_addr; + uint8_t start_bit; + uint8_t bit_length; +}; + + +typedef fapi::ReturnCode (*mss_access_delay_reg_FP_t)(const fapi::Target & i_target_mba, access_type_t i_access_type_e, uint8_t i_port_u8, uint8_t i_rank_u8, input_type_t i_input_type_e, uint8_t i_input_index_u8, uint32_t &io_value_u32); + + + +extern "C" { + +//------------------------------------------------------------------------------ +fapi::ReturnCode mss_access_delay_reg(const fapi::Target & i_target_mba, access_type_t i_access_type_e, uint8_t i_port_u8, uint8_t i_rank_u8, input_type_t i_input_type_e, uint8_t i_input_index_u8, uint32_t &io_value_u32); + +fapi::ReturnCode cross_coupled(const fapi::Target & i_target_mba,uint8_t i_port, uint8_t i_rank_pair,input_type_t i_input_type_e,uint8_t i_input_index,scom_location& out); + +fapi::ReturnCode get_address(const fapi::Target & i_target_mba,uint8_t i_port, uint8_t i_rank_pair,ip_type_t i_input_type_e,uint8_t i_block,uint8_t i_lane,uint64_t &o_scom_address_64,uint8_t &o_start_bit,uint8_t &o_len); + +fapi::ReturnCode rosetta_map(const fapi::Target & i_target_mba,uint8_t i_port, input_type i_input_type_e ,uint8_t i_input_index,uint8_t &o_value); + +fapi::ReturnCode mss_getrankpair(const fapi::Target & i_target_mba,uint8_t i_port,uint8_t i_rank,uint8_t *o_rank_pair,uint8_t o_rankpair_table[8]); +} // extern "C" + +#endif // MSS_ACCESS_DELAY_REG_H + diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_draminit_training_advanced.C b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_draminit_training_advanced.C new file mode 100644 index 000000000..fe54dab0c --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_draminit_training_advanced.C @@ -0,0 +1,1079 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_draminit_training_advanced.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: mss_draminit_training_advanced.C,v 1.23 2012/12/14 16:27:23 sasethur Exp $ +/* File is created by SARAVANAN SETHURAMAN on Thur 29 Sept 2011. */ + +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2007 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//------------------------------------------------------------------------------ +// *! TITLE :mss_draminit_training_advanced.C +// *! DESCRIPTION : Tools for centaur procedures +// *! OWNER NAME : Saravanan Sethuraman email ID:saravanans@in.ibm.com +// *! BACKUP NAME: Mark D Bellows email ID:bellows@us.ibm.com +// #! ADDITIONAL COMMENTS : +// +// General purpose funcs + +//------------------------------------------------------------------------------ +// Don't forget to create CVS comments when you check in your changes! +//------------------------------------------------------------------------------ +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:| Author: | Date: | Comment: +//---------|----------|---------|----------------------------------------------- +// 1.1 | sasethur |30-Sep-11| Initial draft. +// 1.2 | sasethur |18-Nov-11| Changed function names +// 1.3 | sasethur |01-Dec-11| Added details on Vref shmoo, reg addresses +// 1.4 | sasethur |29-Jan-12| Updated wr&rd vref, removed ecmd workarounds +// 1.5 | sasethur |13-Feb-12| Updated register naming conventions +// 1.6 | sasethur |08-Mar-12| Changed rc_num, multiple changes to drv_imp, Vref funcs +// 1.7 | sasethur |23-Mar-12| Added Receiver Impedance shmoo & changes to mcbist call +// 1.8 | sasethur |30-Mar-12| Removed port from start_mcb, added 15,20,48 receiver imp settings +// 1.9 | sasethur |03-Apr-12| Fixed warning messages +// 1.13 | bellows |16-Jul-12| Added in Id tag +// 1.14 | bellows |18-Jul-12| Disabled some checking code +// 1.15 | gollub |05-Sep-12| Calling mss_unmask_draminit_training_advanced_errors after mss_draminit_training_advanced_cloned +// 1.16 | sasethur |15-Oct-12| Fixed FW review comments and modified function based on new attributes, added slew function +// 1.17 | sasethur |17-Oct-12| Updated index bound checks +// 1.18 | sasethur |17-Oct-12| Removed Hardcoding of Shmoo parameter value +// 1.19 | sasethur |26-Oct-12| Updated fapi::ReturnCode, const Target& and removed fapi::RC_SUCCSESS as per FW comments +// 1.20 | bellows |13-Nov-12| Updated for new SI attributes +// 1.21 | sasethur |11-Nov-12| Updated for new SI attribute change, fw review comments +// 1.22 | sasethur |07-Dec-12| Updated for FW review comments - multiple changes +// 1.23 | sasethur |14-Dec-12| Updated for FW review comments + +// This procedure Schmoo's DRV_IMP, SLEW, VREF (DDR, CEN), RCV_IMP based on attribute from effective config procedure +// DQ & DQS Driver impedance, Slew rate, WR_Vref shmoo would call only write_eye shmoo for margin calculation +// DQ & DQS VREF (rd_vref), RCV_IMP shmoo would call rd_eye for margin calculation +// Internal Vref controlled by this function & external vref platform to provide function we return value + +// Not supported +// DDR4, DIMM Types +//---------------------------------------------------------------------- +// Includes - FAPI +//---------------------------------------------------------------------- + +#include <fapi.H> + +//---------------------------------------------------------------------- +//Centaur functions +//---------------------------------------------------------------------- +#include <mss_termination_control.H> +#include <mss_mcbist.H> +#include <mss_shmoo_common.H> +#include <mss_generic_shmoo.H> +#include <mss_draminit_training_advanced.H> +#include <mss_unmask_errors.H> + + +const uint32_t MASK = 1; +const uint32_t MAX_DIMM =2; + +enum shmoo_param +{ + PARAM_NONE = 0x00, + DELAY_REG = 0x01, + DRV_IMP = 0x02, + SLEW_RATE = 0x04, + WR_VREF = 0x08, + RD_VREF = 0x10, + RCV_IMP = 0x20 +}; + + +extern "C" +{ + +using namespace fapi; + +fapi::ReturnCode mss_draminit_training_advanced_cloned(const fapi::Target & i_target_mba, + uint8_t i_pattern, uint8_t i_test_type); + +fapi::ReturnCode drv_imped_shmoo(const fapi::Target & i_target_mba, uint8_t i_port, + shmoo_type_t i_shmoo_type_valid, + uint8_t i_pattern, uint8_t i_test_type); + +fapi::ReturnCode slew_rate_shmoo(const fapi::Target & i_target_mba, uint8_t i_port, + shmoo_type_t i_shmoo_type_valid, + uint8_t i_pattern, uint8_t i_test_type); + +fapi::ReturnCode wr_vref_shmoo(const fapi::Target & i_target_mba, uint8_t i_port, + shmoo_type_t i_shmoo_type_valid, + uint8_t i_pattern, uint8_t i_test_type); + +fapi::ReturnCode rd_vref_shmoo(const fapi::Target & i_target_mba, uint8_t i_port, + shmoo_type_t i_shmoo_type_valid, + uint8_t i_pattern, uint8_t i_test_type); + +fapi::ReturnCode rcv_imp_shmoo(const fapi::Target & i_target_mba, uint8_t i_port, + shmoo_type_t i_shmoo_type_valid, + uint8_t i_pattern, uint8_t i_test_type); + +fapi::ReturnCode delay_shmoo(const fapi::Target & i_target_mba, uint8_t i_port, + shmoo_type_t i_shmoo_type_valid, + uint32_t *o_left_margin, uint32_t *o_right_margin, + uint8_t i_pattern, uint8_t i_test_type); + +void find_best_margin(shmoo_param i_shmoo_param_valid,uint32_t i_left[], + uint32_t i_right[], const uint8_t i_max, + uint32_t i_param_nom, uint8_t& o_index); + +//----------------------------------------------------------------------------------- +//Function name: mss_draminit_training_advanced() +//Description: This function varies driver impedance, receiver impedance, slew, wr & rd vref +//based on attribute definition and runs either mcbist/delay shmoo based on attribute +//Also calls unmask function mss_unmask_draminit_training_advanced_errors() +//Input : const fapi::Target MBA, i_pattern = pattern selection during mcbist @ lab, +// l_test type = test type selection during mcbist @ lab +// Default vlaues are Zero +//----------------------------------------------------------------------------------- + +fapi::ReturnCode mss_draminit_training_advanced(const fapi::Target & i_target_mba, + uint8_t i_pattern, + uint8_t i_test_type) +{ + // const fapi::Target is centaur.mba + + fapi::ReturnCode rc; + FAPI_INF(" pattern bit is %d and test_type_bit is %d",i_pattern,i_test_type); + + rc = mss_draminit_training_advanced_cloned(i_target_mba,i_pattern,i_test_type); + if (rc) + { + FAPI_ERR("Advanced DRAM Init training procedure is Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + } + + // If mss_unmask_draminit_training_advanced_errors gets it's own bad rc, + // it will commit the passed in rc (if non-zero), and return it's own bad rc. + // Else if mss_unmask_draminit_training_advanced_errors runs clean, + // it will just return the passed in rc. + + rc = mss_unmask_draminit_training_advanced_errors(i_target_mba, rc); + if (rc) + { + FAPI_ERR("Unmask Function is Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + return rc; + } + +} +//end of extern C + +//----------------------------------------------------------------------------------- +// Function name: mss_draminit_training_advanced_cloned() +// Description: This function varies driver impedance, receiver impedance, slew, wr & rd vref +// based on attribute definition and runs either mcbist/delay shmoo based on attribute +// Input : const fapi::Target MBA +// i_pattern, i_test_type : Default = 0, mcbist lab function would use this arg +//----------------------------------------------------------------------------------- +fapi::ReturnCode mss_draminit_training_advanced_cloned(const fapi::Target & i_target_mba, + uint8_t i_pattern, + uint8_t i_test_type) +{ + //const fapi::Target is centaur.mba + fapi::ReturnCode rc; + char procedure_name[32]; + sprintf(procedure_name, "mss_draminit_training_advanced"); + FAPI_INF("+++++++ Executing %s +++++++", procedure_name); + + // Define attribute variables + uint32_t l_attr_mss_freq_u32 = 0; + uint32_t l_attr_mss_volt_u32 = 0; + uint8_t l_num_drops_per_port_u8 = 2; + uint8_t l_num_ranks_per_dimm_u8array[MAX_PORT][MAX_DIMM] = {{0}}; + uint8_t l_actual_dimm_size_u8 = 0; + uint8_t l_port = 0; + uint8_t l_dimm_type_u8 = 0; //default is set to CDIMM + uint32_t l_left_margin=0; + uint32_t l_right_margin=0; + + // Define local variables + uint8_t l_shmoo_type_valid_t=0; + uint8_t l_shmoo_param_valid_t=0; + + //const fapi::Target is centaur + fapi::Target l_target_centaur; + rc = fapiGetParentChip(i_target_mba, l_target_centaur); + if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_MSS_FREQ, &l_target_centaur, l_attr_mss_freq_u32); + if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_MSS_VOLT, &l_target_centaur, l_attr_mss_volt_u32); + if(rc) return rc; + + //const fapi::Target is centaur.mba + rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target_mba, l_dimm_type_u8); + if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_DROPS_PER_PORT, &i_target_mba, l_num_drops_per_port_u8); + if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, l_num_ranks_per_dimm_u8array); + if(rc) return rc; + + FAPI_INF("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + FAPI_INF("freq = %d on %s.", l_attr_mss_freq_u32, l_target_centaur.toEcmdString()); + FAPI_INF("volt = %d on %s.", l_attr_mss_volt_u32, l_target_centaur.toEcmdString()); + FAPI_INF("dimm_type = %d on %s.", l_dimm_type_u8, i_target_mba.toEcmdString()); + FAPI_INF("num_drops_per_port = %d on %s.", l_num_drops_per_port_u8, i_target_mba.toEcmdString()); + FAPI_INF("num_ranks_per_dimm = [%02d][%02d][%02d][%02d] on %s.", l_num_ranks_per_dimm_u8array[0][0],l_num_ranks_per_dimm_u8array[0][1], l_num_ranks_per_dimm_u8array[1][0],l_num_ranks_per_dimm_u8array[1][1], i_target_mba.toEcmdString()); + FAPI_INF("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + + if ( l_num_drops_per_port_u8 == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL ) + { + l_actual_dimm_size_u8 = 2; + } + else + { + l_actual_dimm_size_u8 = 1; + } + + rc = FAPI_ATTR_GET(ATTR_EFF_SCHMOO_TEST_VALID, &i_target_mba, l_shmoo_type_valid_t); + if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_SCHMOO_PARAM_VALID, &i_target_mba, l_shmoo_param_valid_t); + if(rc) return rc; + + shmoo_type_t l_shmoo_type_valid; + shmoo_param l_shmoo_param_valid; + + l_shmoo_type_valid=(shmoo_type_t)l_shmoo_type_valid_t; + l_shmoo_param_valid=(shmoo_param)l_shmoo_param_valid_t; + + FAPI_INF("+++++++++++++++++++++++++ Read Schmoo Attributes ++++++++++++++++++++++++++"); + FAPI_INF("Schmoo param valid = 0x%x on %s", l_shmoo_param_valid, i_target_mba.toEcmdString()); + FAPI_INF("Schmoo test valid = 0x%x on %s", l_shmoo_type_valid, i_target_mba.toEcmdString()); + FAPI_INF("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + + //Check for Shmoo Parameter, if anyof them is enabled then go into the loop else the procedure exit + + for ( l_port = 0; l_port < MAX_PORT; l_port += 1 ) + { + if (( l_num_ranks_per_dimm_u8array[l_port][0] > 0 ) || (l_num_ranks_per_dimm_u8array[l_port][1] > 0)) + { + if(l_shmoo_param_valid != PARAM_NONE) + { + if((l_shmoo_param_valid & DRV_IMP) != 0) + { + rc = drv_imped_shmoo(i_target_mba, l_port, l_shmoo_type_valid, i_pattern,i_test_type); + if (rc) + { + FAPI_ERR("Driver Impedance Schmoo function is Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + } + if((l_shmoo_param_valid & SLEW_RATE) !=0) + { + rc = slew_rate_shmoo(i_target_mba, l_port, l_shmoo_type_valid, i_pattern,i_test_type); + if (rc) + { + FAPI_ERR("Slew Rate Schmoo Function is Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + } + if((l_shmoo_param_valid & WR_VREF) != 0) + { + rc = wr_vref_shmoo(i_target_mba, l_port, l_shmoo_type_valid, i_pattern,i_test_type); + if (rc) + { + FAPI_ERR("Write Vref Schmoo Function is Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + } + if((l_shmoo_param_valid & RD_VREF) !=0) + { + rc = rd_vref_shmoo(i_target_mba, l_port, l_shmoo_type_valid, i_pattern,i_test_type); + if (rc) + { + FAPI_ERR("Read Vref Schmoo Function is Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + } + if ((l_shmoo_param_valid & RCV_IMP) !=0) + { + rc = rcv_imp_shmoo(i_target_mba, l_port, l_shmoo_type_valid, i_pattern,i_test_type); + if (rc) + { + FAPI_ERR("Receiver Impedance Schmoo Function is Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + } + if ((l_shmoo_param_valid & DELAY_REG) != 0) + { + rc = delay_shmoo(i_target_mba, l_port, l_shmoo_type_valid, &l_left_margin, &l_right_margin,i_pattern,i_test_type); + if (rc) + { + FAPI_ERR("Delay Schmoo Function is Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + } + } + } + } +return rc; +} + + + +//------------------------------------------------------------------------------- +// Function name: drv_imped_shmoo() +// This function varies the driver impedance in the nominal mode +// for both dq/dqs & adr/cmd signals - DQ_DQS<24,30,34,40>,CMD_CNTL<15,20,30,40> +// if there is any mcbist failure, that will be reported to put_bad_bits function +// Input param: const fapi::Target MBA, port = 0,1 +// Shmoo type: MCBIST, WR_EYE, RD_EYE, WR_DQS, RD_DQS +// Shmoo param: PARAM_NONE, DRV_IMP, SLEW_RATE, WR_VREF, RD_VREF, RCV_IMP +// Shmoo Mode: FEW_ADDR, QUARTER_ADDR, HALF_ADDR, FULL_ADDR +// i_pattern, i_test_type : Default = 0, mcbist lab function would use this arg +//------------------------------------------------------------------------------- + +fapi::ReturnCode drv_imped_shmoo(const fapi::Target & i_target_mba, + uint8_t i_port, + shmoo_type_t i_shmoo_type_valid, + uint8_t i_pattern, + uint8_t i_test_type) +{ + fapi::ReturnCode rc; + uint8_t l_drv_imp_dq_dqs[MAX_PORT] = {0}; + uint8_t l_drv_imp_dq_dqs_nom[MAX_PORT] = {0}; + uint8_t l_drv_imp_dq_dqs_new[MAX_PORT] = {0}; + uint8_t index=0; + uint8_t l_slew_rate_dq_dqs[MAX_PORT] = {0}; + uint8_t l_slew_rate_dq_dqs_schmoo[MAX_PORT] = {0}; + uint32_t l_drv_imp_dq_dqs_schmoo[MAX_PORT] = {0}; + uint8_t l_drv_imp_dq_dqs_nom_fc = 0; + //Temporary + i_shmoo_type_valid = WR_EYE; //Hard coded, since no other schmoo is applicable for this parameter + uint32_t l_left_margin_drv_imp_array[MAX_DRV_IMP] = {0}; + uint32_t l_right_margin_drv_imp_array[MAX_DRV_IMP] = {0}; + uint32_t l_left_margin = 0; + uint32_t l_right_margin = 0; + uint8_t count = 0; + uint8_t l_slew_type = 0; // Hard coded since this procedure will touch only DQ_DQS and not address + + rc = FAPI_ATTR_GET(ATTR_EFF_CEN_DRV_IMP_DQ_DQS, &i_target_mba, l_drv_imp_dq_dqs_nom); + if (rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_CEN_SLEW_RATE_DQ_DQS, &i_target_mba, l_slew_rate_dq_dqs); + if (rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_CEN_DRV_IMP_DQ_DQS_SCHMOO, &i_target_mba, l_drv_imp_dq_dqs_schmoo); + if (rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_CEN_SLEW_RATE_DQ_DQS_SCHMOO, &i_target_mba, l_slew_rate_dq_dqs_schmoo); + if (rc) return rc; + + FAPI_INF("+++++++++++++++++Read DRIVER IMP Attributes values++++++++++++++++"); + FAPI_INF("CEN_DRV_IMP_DQ_DQS[%d] = [%02d] Ohms, on %s", i_port, l_drv_imp_dq_dqs_nom[i_port], i_target_mba.toEcmdString()); + FAPI_INF("CEN_DRV_IMP_DQ_DQS_SCHMOO[0] = [0x%x], CEN_DRV_IMP_DQ_DQS_SCHMOO[1] = [0x%x] on %s", l_drv_imp_dq_dqs_schmoo[0],l_drv_imp_dq_dqs_schmoo[1], i_target_mba.toEcmdString()); + FAPI_INF("CEN_SLEW_RATE_DQ_DQS[0] = [%02d]V/ns , CEN_SLEW_RATE_DQ_DQS[1] = [%02d]V/ns on %s", l_slew_rate_dq_dqs[0],l_slew_rate_dq_dqs[1], i_target_mba.toEcmdString()); + FAPI_INF("CEN_SLEW_RATE_DQ_DQS_SCHMOO[0] = [0x%x], CEN_SLEW_RATE_DQ_DQS_SCHMOO[1] = [0x%x] on %s", l_slew_rate_dq_dqs_schmoo[0],l_slew_rate_dq_dqs_schmoo[1], i_target_mba.toEcmdString()); + FAPI_INF("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + + if(l_drv_imp_dq_dqs_schmoo[i_port] == 0) //Check for any of the bits enabled in the shmoo + { + FAPI_INF("DRIVER IMP Shmoo set to FAST Mode and won't do anything"); + } + else + { + for(index = 0; index< MAX_DRV_IMP; index+=1) + { + if (l_drv_imp_dq_dqs_schmoo[i_port] & MASK) + { + l_drv_imp_dq_dqs[i_port] = drv_imp_array[index]; + FAPI_INF("Current Driver Impedance Value = %d Ohms", drv_imp_array[index]); + FAPI_INF("Configuring Driver Impedance Registers:"); + rc = config_drv_imp(i_target_mba, i_port, l_drv_imp_dq_dqs[i_port]); + if (rc) return rc; + FAPI_INF("Configuring Slew Rate Registers:"); + rc = config_slew_rate(i_target_mba, i_port, l_slew_type, l_drv_imp_dq_dqs[i_port], l_slew_rate_dq_dqs[i_port]); + if (rc) return rc; + FAPI_INF("Calling Shmoo for finding Timing Margin:"); + rc = delay_shmoo(i_target_mba, i_port, i_shmoo_type_valid, + &l_left_margin, &l_right_margin, i_pattern, i_test_type); + if (rc) return rc; + l_left_margin_drv_imp_array[index]= l_left_margin; + l_right_margin_drv_imp_array[index]= l_right_margin; + } + else + { + l_left_margin_drv_imp_array[index]= 0; + l_right_margin_drv_imp_array[index]= 0; + } + l_drv_imp_dq_dqs_schmoo[i_port] = (l_drv_imp_dq_dqs_schmoo[i_port] >> 1); + } + l_drv_imp_dq_dqs_nom_fc = l_drv_imp_dq_dqs_nom[i_port]; + find_best_margin(DRV_IMP, l_left_margin_drv_imp_array, + l_right_margin_drv_imp_array, MAX_DRV_IMP, l_drv_imp_dq_dqs_nom_fc, count); + + if (count >= MAX_DRV_IMP) + { + FAPI_ERR("Driver Imp new input(%d) out of bounds, (>= %d)", + count, MAX_DRV_IMP); + FAPI_SET_HWP_ERROR(rc, RC_MSS_INVALID_FN_INPUT_ERROR); + return rc; + } + else + { + + if(i_port == 0) + { + l_drv_imp_dq_dqs_new[0] = drv_imp_array[count]; + l_drv_imp_dq_dqs_new[1] = l_drv_imp_dq_dqs_nom[1]; // This can be removed once the get/set attribute takes care of this + } + else + { + l_drv_imp_dq_dqs_new[1] = drv_imp_array[count]; + l_drv_imp_dq_dqs_new[0] = l_drv_imp_dq_dqs_nom[0]; + } + + if (l_drv_imp_dq_dqs_new[i_port] != l_drv_imp_dq_dqs_nom[i_port]) + { + FAPI_INF("Better Margin found on %d Ohms on %s", l_drv_imp_dq_dqs_new[i_port], i_target_mba.toEcmdString()); + rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_DQ_DQS, &i_target_mba, l_drv_imp_dq_dqs_new); + if (rc) return rc; + FAPI_INF("Configuring New Driver Impedance Value to Registers:"); + rc = config_drv_imp(i_target_mba, i_port, l_drv_imp_dq_dqs_new[i_port]); + if (rc) return rc; + rc = config_slew_rate(i_target_mba, i_port, l_slew_type, l_drv_imp_dq_dqs_new[i_port], l_slew_rate_dq_dqs[i_port]); + if (rc) return rc; + } + else + { + FAPI_INF("Nominal value will not be changed - Restoring the original values!"); + rc = config_drv_imp(i_target_mba, i_port, l_drv_imp_dq_dqs_nom[i_port]); + if (rc) return rc; + rc = config_slew_rate(i_target_mba, i_port, l_slew_type, l_drv_imp_dq_dqs_nom[i_port], l_slew_rate_dq_dqs[i_port]); + if (rc) return rc; + } + } + + FAPI_INF("++++ Driver impedance shmoo function executed successfully ++++"); + } +return rc; +} + +//----------------------------------------------------------------------------------------- +// Function name: slew_rate_shmoo() +// This function varies the slew rate of the data & adr signals (fast/slow) +// calls the write eye shmoo which internally calls mcbist function to see for failure +// if there is any mcbist failure, this function will report to baddqpins function +// Input param: const fapi::Target MBA, port = 0,1 +// Shmoo type: MCBIST, WR_EYE, RD_EYE, WR_DQS, RD_DQS +// Shmoo param: PARAM_NONE, DRV_IMP, SLEW_RATE, WR_VREF, RD_VREF, RCV_IMP +// Shmoo Mode: FEW_ADDR, QUARTER_ADDR, HALF_ADDR, FULL_ADDR +// i_pattern, i_test_type : Default = 0, mcbist lab function would use this arg +//----------------------------------------------------------------------------------------- + +fapi::ReturnCode slew_rate_shmoo(const fapi::Target & i_target_mba, + uint8_t i_port, + shmoo_type_t i_shmoo_type_valid, + uint8_t i_pattern, + uint8_t i_test_type) +{ + fapi::ReturnCode rc; + uint8_t l_slew_rate_dq_dqs[MAX_PORT] = {0}; + uint8_t l_slew_rate_dq_dqs_nom[MAX_PORT] = {0}; + uint8_t l_slew_rate_dq_dqs_nom_fc = 0; + uint8_t l_slew_rate_dq_dqs_new[MAX_PORT] = {0}; + uint32_t l_slew_rate_dq_dqs_schmoo[MAX_PORT] = {0}; + uint8_t l_drv_imp_dq_dqs_nom[MAX_PORT] = {0}; + i_shmoo_type_valid = WR_EYE; // Hard coded - Other shmoo type is not valid - Temporary + + uint8_t index = 0; + uint8_t count = 0; + uint32_t l_left_margin_slew_array[MAX_NUM_SLEW_RATES] = {0}; + uint32_t l_right_margin_slew_array[MAX_NUM_SLEW_RATES] = {0}; + uint32_t l_left_margin = 0; + uint32_t l_right_margin = 0; + uint8_t l_slew_type = 0; // Hard coded since this procedure will touch only DQ_DQS and not address + + //Read Attributes - DRV IMP, SLEW, SLEW RATES values to be Schmoo'ed + rc = FAPI_ATTR_GET(ATTR_EFF_CEN_DRV_IMP_DQ_DQS, &i_target_mba, l_drv_imp_dq_dqs_nom); + if (rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_CEN_SLEW_RATE_DQ_DQS, &i_target_mba, l_slew_rate_dq_dqs_nom); + if (rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_CEN_DRV_IMP_DQ_DQS_SCHMOO, &i_target_mba, l_slew_rate_dq_dqs_schmoo); + if (rc) return rc; + + FAPI_INF("+++++++++++++++++Read Slew Shmoo Attributes values+++++++++++++++"); + FAPI_INF("CEN_DRV_IMP_DQ_DQS[0] = [%02d] Ohms, CEN_DRV_IMP_DQ_DQS[1] = [%02d] Ohms on %s", l_drv_imp_dq_dqs_nom[0],l_drv_imp_dq_dqs_nom[1], i_target_mba.toEcmdString()); + FAPI_INF("CEN_SLEW_RATE_DQ_DQS[0] = [%02d]V/ns , CEN_SLEW_RATE_DQ_DQS[1] = [%02d]V/ns on %s", l_slew_rate_dq_dqs_nom[0],l_slew_rate_dq_dqs_nom[1], i_target_mba.toEcmdString()); + FAPI_INF("CEN_SLEW_RATE_DQ_DQS_SCHMOO[0] = [0x%x], CEN_SLEW_RATE_DQ_DQS_SCHMOO[1] = [0x%x] on %s", l_slew_rate_dq_dqs_schmoo[0],l_slew_rate_dq_dqs_schmoo[1], i_target_mba.toEcmdString()); + FAPI_INF("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + + if(l_slew_rate_dq_dqs_schmoo == 0) //Check for any of the bits enabled in the shmoo + { + FAPI_INF("Slew Rate Shmoo set to FAST Mode and won't do anything"); + } + else + { + for(index = 0; index < MAX_NUM_SLEW_RATES; index+=1) + { + if (l_slew_rate_dq_dqs_schmoo[i_port] & MASK ) + { + l_slew_rate_dq_dqs[i_port] = slew_rate_array[index]; + FAPI_INF("Current Slew rate value is %d V/ns", slew_rate_array[index]); + FAPI_INF("Configuring Slew registers:"); + rc = config_slew_rate(i_target_mba, i_port, l_slew_type, l_drv_imp_dq_dqs_nom[i_port], l_slew_rate_dq_dqs[i_port]); + if (rc) return rc; + FAPI_INF("Calling Shmoo for finding Timing Margin:"); + rc = delay_shmoo(i_target_mba, i_port, i_shmoo_type_valid, + &l_left_margin, &l_right_margin, i_pattern, i_test_type); + if (rc) return rc; + l_left_margin_slew_array[index]= l_left_margin; + l_right_margin_slew_array[index]= l_right_margin; + } + else + { + l_left_margin_slew_array[index]= 0; + l_right_margin_slew_array[index]= 0; + } + l_slew_rate_dq_dqs_schmoo[i_port] = (l_slew_rate_dq_dqs_schmoo[i_port] >> 1); + } + l_slew_rate_dq_dqs_nom_fc = l_slew_rate_dq_dqs_nom[i_port]; + find_best_margin(SLEW_RATE, l_left_margin_slew_array, + l_right_margin_slew_array, MAX_NUM_SLEW_RATES, l_slew_rate_dq_dqs_nom_fc, count); + if (count >= MAX_NUM_SLEW_RATES) + { + FAPI_ERR("Driver Imp new input(%d) out of bounds, (>= %d)", + count, MAX_NUM_SLEW_RATES); + FAPI_SET_HWP_ERROR(rc, RC_MSS_INVALID_FN_INPUT_ERROR); + return rc; + } + else + { + + if(i_port == 0) + { + l_slew_rate_dq_dqs_new[0] = slew_rate_array[count]; + l_slew_rate_dq_dqs_new[1] = l_slew_rate_dq_dqs_nom[1]; + } + else + { + l_slew_rate_dq_dqs_new[1] = slew_rate_array[count]; + l_slew_rate_dq_dqs_new[0] = l_slew_rate_dq_dqs_nom[0]; + } + + + + if (l_slew_rate_dq_dqs_new[i_port] != l_slew_rate_dq_dqs_nom[i_port]) + { + FAPI_INF("Better Margin found on Slew Rate: %d V/ns on %s", l_slew_rate_dq_dqs_new[i_port], i_target_mba.toEcmdString()); + rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_DQ_DQS, &i_target_mba, l_slew_rate_dq_dqs_new); + if (rc) return rc; + FAPI_INF("Configuring New Slew Rate Value to Registers:"); + rc = config_slew_rate(i_target_mba, i_port, l_slew_type, l_drv_imp_dq_dqs_nom[i_port], l_slew_rate_dq_dqs_new[i_port]); + if (rc) return rc; + } + else + { + FAPI_INF("Nominal value will not be changed!"); + FAPI_INF("Slew Rate: %d V/ns on %s", l_slew_rate_dq_dqs_nom[i_port], i_target_mba.toEcmdString()); + } + } + FAPI_INF("++++ Slew Rate shmoo function executed successfully ++++"); + } +return rc; +} + +//---------------------------------------------------------------------------------------------- +// Function name: wr_vref_shmoo() +// This function varies the DIMM vref using PC_VREF_DRV_CNTL register in 32 steps with vref sign +// Calls mcbist/write eye shmoo function and look for failure, incase of failure +// this function reports bad DQ pins matrix to put bad bits function +// Input param: const fapi::Target MBA, port = 0,1 +// Shmoo type: MCBIST, WR_EYE, RD_EYE, WR_DQS, RD_DQS +// Shmoo param: PARAM_NONE, DRV_IMP, SLEW_RATE, WR_VREF, RD_VREF, RCV_IMP +// Shmoo Mode: FEW_ADDR, QUARTER_ADDR, HALF_ADDR, FULL_ADDR +// i_pattern, i_test_type : Default = 0, mcbist lab function would use this arg +//---------------------------------------------------------------------------------------------- + +fapi::ReturnCode wr_vref_shmoo(const fapi::Target & i_target_mba, + uint8_t i_port, + shmoo_type_t i_shmoo_type_valid, + uint8_t i_pattern, + uint8_t i_test_type) +{ + fapi::ReturnCode rc; + uint32_t l_wr_dram_vref[MAX_PORT] = {0}; + uint32_t l_wr_dram_vref_nom[MAX_PORT] = {0}; + uint32_t l_wr_dram_vref_new[MAX_PORT] = {0}; + uint32_t l_wr_dram_vref_schmoo[MAX_PORT] = {0}; + uint32_t l_wr_dram_vref_nom_fc = 0; + i_shmoo_type_valid = WR_EYE; // Hard coded - Temporary + + uint8_t index = 0; + uint8_t count = 0; + uint32_t l_left_margin = 0; + uint32_t l_right_margin = 0; + uint32_t l_left_margin_wr_vref_array[MAX_WR_VREF]= {0}; + uint32_t l_right_margin_wr_vref_array[MAX_WR_VREF]= {0}; + + //Read the write vref attributes + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WR_VREF, &i_target_mba, l_wr_dram_vref_nom); + if (rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WR_VREF_SCHMOO, &i_target_mba, l_wr_dram_vref_schmoo); + if (rc) return rc; + FAPI_INF("+++++++++++++++++DRAM VREF Read Shmoo Attributes values+++++++++++++++"); + FAPI_INF("DRAM_WR_VREF[0] = %d , DRAM_WR_VREF[0] = %d on %s", l_wr_dram_vref_nom[0], l_wr_dram_vref_nom[1],i_target_mba.toEcmdString()); + FAPI_INF("DRAM_WR_VREF_SCHMOO[0] = [%x],DRAM_WR_VREF_SCHMOO[0] = [%x] on %s", l_wr_dram_vref_schmoo[0], l_wr_dram_vref_schmoo[1],i_target_mba.toEcmdString()); + FAPI_INF("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + + + if(l_wr_dram_vref_schmoo[i_port] == 0) + { + FAPI_INF("FAST Shmoo Mode: This function will not change any Write DRAM VREF settings"); + } + else + { + for(index = 0; index < MAX_WR_VREF; index+=1) + { + if (l_wr_dram_vref_schmoo[i_port] & MASK) + { + FAPI_INF("Current Vref value is %dmV", wr_vref_array[index]); + l_wr_dram_vref[i_port] = wr_vref_array[index]; + rc = config_wr_dram_vref(i_target_mba, i_port, l_wr_dram_vref[i_port]); + if (rc) return rc; + FAPI_INF(" Calling Shmoo for finding Timing Margin:"); + rc = delay_shmoo(i_target_mba, i_port, i_shmoo_type_valid, + &l_left_margin, &l_right_margin, i_pattern, i_test_type); + if (rc) return rc; + l_left_margin_wr_vref_array[index]= l_left_margin; + l_right_margin_wr_vref_array[index]= l_right_margin; + } + else + { + l_left_margin_wr_vref_array[index]= 0; + l_right_margin_wr_vref_array[index]= 0; + } + l_wr_dram_vref_schmoo[i_port] = (l_wr_dram_vref_schmoo[i_port] >> 1); + FAPI_INF("Configuring Vref registers_2:, index %d , max value %d, schmoo %x mask %d ", index, MAX_WR_VREF, l_wr_dram_vref_schmoo[i_port], MASK); + } + l_wr_dram_vref_nom_fc = l_wr_dram_vref_nom[i_port]; + find_best_margin(WR_VREF, l_left_margin_wr_vref_array, + l_right_margin_wr_vref_array, MAX_WR_VREF, l_wr_dram_vref_nom_fc, count); + if (count >= MAX_WR_VREF) + { + FAPI_ERR("Driver Imp new input(%d) out of bounds, (>= %d)", + count, MAX_WR_VREF); + FAPI_SET_HWP_ERROR(rc, RC_MSS_INVALID_FN_INPUT_ERROR); + return rc; + } + else + { + + if(i_port == 0) + { + l_wr_dram_vref_new[0] = wr_vref_array_fitness[count]; + l_wr_dram_vref_new[1] = l_wr_dram_vref_nom[1]; + } + else + { + l_wr_dram_vref_new[1] = wr_vref_array_fitness[count]; + l_wr_dram_vref_new[0] = l_wr_dram_vref_nom[0]; + } + + if(l_wr_dram_vref_new[i_port] != l_wr_dram_vref_nom[i_port]) + { + FAPI_INF("Best Margin Found on Vref : %d , %d mV on %s", count, wr_vref_array_fitness[count], i_target_mba.toEcmdString()); + rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_WR_VREF, &i_target_mba, l_wr_dram_vref_new); + if (rc) return rc; + FAPI_INF("Configuring New Vref Value to registers:"); + rc = config_wr_dram_vref(i_target_mba, i_port, l_wr_dram_vref_new[i_port]); + if (rc) return rc; + } + else + { + FAPI_INF("Nominal value will not be changed!- Restoring the original values!"); + rc = config_wr_dram_vref(i_target_mba, i_port, l_wr_dram_vref_nom[i_port]); + if (rc) return rc; + } + } + FAPI_INF("++++ Write Vref Shmoo function executed successfully ++++"); + } + return rc; +} + + + +//---------------------------------------------------------------------------------------------- +// Function name: rd_vref_shmoo() +// Description: This function varies the Centaur IO vref in 16 steps +// Calls write eye shmoo function +// Input param: const fapi::Target MBA, port = 0,1 +// Shmoo type: MCBIST, WR_EYE, RD_EYE, WR_DQS, RD_DQS +// Shmoo param: PARAM_NONE, DRV_IMP, SLEW_RATE, WR_VREF, RD_VREF, RCV_IMP +// Shmoo Mode: FEW_ADDR, QUARTER_ADDR, HALF_ADDR, FULL_ADDR +// i_pattern, i_test_type : Default = 0, mcbist lab function would use this arg +//---------------------------------------------------------------------------------------------- + +fapi::ReturnCode rd_vref_shmoo(const fapi::Target & i_target_mba, + uint8_t i_port, + shmoo_type_t i_shmoo_type_valid, + uint8_t i_pattern, + uint8_t i_test_type) +{ + fapi::ReturnCode rc; + uint32_t l_rd_cen_vref[MAX_PORT] = {0}; + uint32_t l_rd_cen_vref_nom[MAX_PORT] = {0}; + uint32_t l_rd_cen_vref_nom_fc = 0; + uint32_t l_rd_cen_vref_new[MAX_PORT] ={0}; + uint32_t l_rd_cen_vref_schmoo[MAX_PORT] = {0}; + uint8_t index = 0; + uint8_t count = 0; + i_shmoo_type_valid = RD_EYE; // Hard coded - Temporary + + uint32_t l_left_margin = 0; + uint32_t l_right_margin = 0; + uint32_t l_left_margin_rd_vref_array[MAX_RD_VREF] = {0}; + uint32_t l_right_margin_rd_vref_array[MAX_RD_VREF] = {0}; + + + rc = FAPI_ATTR_GET(ATTR_EFF_CEN_RD_VREF, &i_target_mba, l_rd_cen_vref_nom); + if (rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_CEN_RD_VREF_SCHMOO, &i_target_mba, l_rd_cen_vref_schmoo); + if (rc) return rc; + + FAPI_INF("+++++++++++++++++CENTAUR VREF Read Shmoo Attributes values+++++++++++++++"); + FAPI_INF("CEN_RD_VREF[0] = %d CEN_RD_VREF[1] = %d on %s", l_rd_cen_vref_nom[0],l_rd_cen_vref_nom[1], i_target_mba.toEcmdString()); + FAPI_INF("CEN_RD_VREF_SCHMOO[0] = [%d], CEN_RD_VREF_SCHMOO[1] = [%d] on %s", l_rd_cen_vref_schmoo[0], l_rd_cen_vref_schmoo[1],i_target_mba.toEcmdString()); + FAPI_INF("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + + if(l_rd_cen_vref_schmoo[i_port] == 0) + { + FAPI_INF("FAST Shmoo Mode: This function will not change any Write DRAM VREF settings"); + } + else + { + for(index = 0; index< MAX_RD_VREF; index+=1) + { + if ((l_rd_cen_vref_schmoo[i_port] & MASK) == 1) + { + l_rd_cen_vref[i_port] = rd_cen_vref_array[index]; + FAPI_INF("Current Vref value is %dmV", rd_cen_vref_array[index]); + FAPI_INF("Configuring Read Vref Registers:"); + rc = config_rd_cen_vref(i_target_mba, i_port, l_rd_cen_vref[i_port]); if (rc) return rc; + FAPI_INF(" Calling Shmoo function to find out Timing Margin:"); + rc = delay_shmoo(i_target_mba, i_port, i_shmoo_type_valid, &l_left_margin, &l_right_margin,i_pattern,i_test_type); + if (rc) return rc; + l_left_margin_rd_vref_array[index]= l_left_margin; + l_right_margin_rd_vref_array[index]= l_right_margin; + } + else + { + l_left_margin_rd_vref_array[index]= 0; + l_right_margin_rd_vref_array[index]= 0; + } + l_rd_cen_vref_schmoo[i_port] = (l_rd_cen_vref_schmoo[i_port] >> 1); + } + l_rd_cen_vref_nom_fc = l_rd_cen_vref_nom[i_port]; + find_best_margin(RD_VREF, l_left_margin_rd_vref_array, + l_right_margin_rd_vref_array, MAX_RD_VREF, l_rd_cen_vref_nom_fc, count); + if (count >= MAX_RD_VREF) + { + FAPI_ERR("Driver Imp new input(%d) out of bounds, (>= %d)", + count, MAX_RD_VREF); + FAPI_SET_HWP_ERROR(rc, RC_MSS_INVALID_FN_INPUT_ERROR); + return rc; + } + else + { + + if(i_port == 0) + { + l_rd_cen_vref_new[0] = rd_cen_vref_array_fitness[count]; + l_rd_cen_vref_new[1] = l_rd_cen_vref_nom[1]; + } + else + { + l_rd_cen_vref_new[1] = rd_cen_vref_array_fitness[count]; + l_rd_cen_vref_new[0] = l_rd_cen_vref_nom[0]; + } + + if(l_rd_cen_vref_new[i_port] != l_rd_cen_vref_nom[i_port]) + { + FAPI_INF("Best Margin Found on Vref : %dmv , %dmV on %s", l_rd_cen_vref_new[i_port], rd_cen_vref_array_fitness[count], i_target_mba.toEcmdString()); + rc = FAPI_ATTR_SET(ATTR_EFF_CEN_RD_VREF, &i_target_mba, l_rd_cen_vref_new); + if (rc) return rc; + FAPI_INF("Configuring New Read Vref Value to Registers:"); + rc = config_rd_cen_vref(i_target_mba, i_port, l_rd_cen_vref_new[i_port]); + if (rc) return rc; + } + else + { + FAPI_INF("Nominal value will not be changed!- Restoring the original values!"); + rc = config_rd_cen_vref(i_target_mba, i_port, l_rd_cen_vref_nom[i_port]); + if (rc) return rc; + } + } + FAPI_INF("++++ Read Vref Shmoo function executed successfully ++++"); + } +return rc; +} + +//------------------------------------------------------------------------------ +// Function name: rcv_imp_shmoo() +// Receiver impedance shmoo function varies 9 values +// Input param: const fapi::Target MBA, port = 0,1 +// Shmoo type: MCBIST, WR_EYE, RD_EYE, WR_DQS, RD_DQS +// Shmoo param: PARAM_NONE, DRV_IMP, SLEW_RATE, WR_VREF, RD_VREF, RCV_IMP +// Shmoo Mode: FEW_ADDR, QUARTER_ADDR, HALF_ADDR, FULL_ADDR +// i_pattern, i_test_type : Default = 0, mcbist lab function would use this arg +//------------------------------------------------------------------------------ +fapi::ReturnCode rcv_imp_shmoo(const fapi::Target & i_target_mba, + uint8_t i_port, + shmoo_type_t i_shmoo_type_valid, + uint8_t i_pattern, + uint8_t i_test_type) +{ + fapi::ReturnCode rc; + uint8_t l_rcv_imp_dq_dqs[MAX_PORT] = {0}; + uint8_t l_rcv_imp_dq_dqs_nom[MAX_PORT] = {0}; + uint8_t l_rcv_imp_dq_dqs_nom_fc = 0; + uint8_t l_rcv_imp_dq_dqs_new[MAX_PORT] = {0}; + uint32_t l_rcv_imp_dq_dqs_schmoo[MAX_PORT] = {0}; + uint8_t index = 0; + uint8_t count = 0; + i_shmoo_type_valid = RD_EYE; //Hard coded since no other shmoo is applicable - Temporary + + uint32_t l_left_margin = 0; + uint32_t l_right_margin = 0; + uint32_t l_left_margin_rcv_imp_array[MAX_RCV_IMP] = {0}; + uint32_t l_right_margin_rcv_imp_array[MAX_RCV_IMP] = {0}; + + + rc = FAPI_ATTR_GET(ATTR_EFF_CEN_RCV_IMP_DQ_DQS, &i_target_mba, l_rcv_imp_dq_dqs_nom); + if (rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_CEN_RCV_IMP_DQ_DQS_SCHMOO, &i_target_mba, l_rcv_imp_dq_dqs_schmoo); + if (rc) return rc; + + FAPI_INF("+++++++++++++++++RECIVER IMP Read Shmoo Attributes values+++++++++++++++"); + FAPI_INF("CEN_RCV_IMP_DQ_DQS[0] = %d , CEN_RCV_IMP_DQ_DQS[1] = %d on %s", l_rcv_imp_dq_dqs_nom[0],l_rcv_imp_dq_dqs_nom[1], i_target_mba.toEcmdString()); + FAPI_INF("CEN_RCV_IMP_DQ_DQS_SCHMOO[0] = [%d], CEN_RCV_IMP_DQ_DQS_SCHMOO[1] = [%d], on %s", l_rcv_imp_dq_dqs_schmoo[0],l_rcv_imp_dq_dqs_schmoo[1], i_target_mba.toEcmdString()); + FAPI_INF("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + + if(l_rcv_imp_dq_dqs_schmoo[i_port] == 0) + { + FAPI_INF("FAST Shmoo Mode: This function will not change any Write DRAM VREF settings"); + } + else + { + for(index = 0; index< MAX_RCV_IMP; index+=1) + { + if ((l_rcv_imp_dq_dqs_schmoo[i_port] & MASK) == 1) + { + l_rcv_imp_dq_dqs[i_port] = rcv_imp_array[index]; + FAPI_INF("Current Receiver Impedance: %d Ohms ", rcv_imp_array[index]); + FAPI_INF("Configuring Receiver impedance registers:"); + rc = config_rcv_imp(i_target_mba, i_port, l_rcv_imp_dq_dqs[i_port]); if (rc) return rc; + FAPI_INF("Calling Shmoo function to find out timing margin:"); + rc = delay_shmoo(i_target_mba, i_port, i_shmoo_type_valid, + &l_left_margin, &l_right_margin, i_pattern, i_test_type); + if (rc) return rc; + l_left_margin_rcv_imp_array[index]= l_left_margin; + l_right_margin_rcv_imp_array[index]= l_right_margin; + } + else + { + l_left_margin_rcv_imp_array[index]= 0; + l_right_margin_rcv_imp_array[index]= 0; + } + l_rcv_imp_dq_dqs_schmoo[i_port] = (l_rcv_imp_dq_dqs_schmoo[i_port] >> 1); + } + l_rcv_imp_dq_dqs_nom_fc = l_rcv_imp_dq_dqs_nom[i_port]; + find_best_margin(RCV_IMP, l_left_margin_rcv_imp_array, + l_right_margin_rcv_imp_array, MAX_RCV_IMP, l_rcv_imp_dq_dqs_nom_fc, count); + if (count >= MAX_RCV_IMP) + { + FAPI_ERR("Driver Imp new input(%d) out of bounds, (>= %d)", + count, MAX_RCV_IMP); + FAPI_SET_HWP_ERROR(rc, RC_MSS_INVALID_FN_INPUT_ERROR); + return rc; + } + else + { + + if(i_port == 0) + { + l_rcv_imp_dq_dqs_new[0] = rcv_imp_array[count]; + l_rcv_imp_dq_dqs_new[1] = l_rcv_imp_dq_dqs_nom[1]; // This can be removed once the get/set attribute takes care of this + } + else + { + l_rcv_imp_dq_dqs_new[1] = rcv_imp_array[count]; + l_rcv_imp_dq_dqs_new[0] = l_rcv_imp_dq_dqs_nom[0]; + } + + if (l_rcv_imp_dq_dqs_new[i_port] != l_rcv_imp_dq_dqs_nom[i_port]) + { + FAPI_INF("Better Margin found on %d on %s", l_rcv_imp_dq_dqs_new[i_port], i_target_mba.toEcmdString()); + rc = FAPI_ATTR_SET(ATTR_EFF_CEN_RCV_IMP_DQ_DQS, &i_target_mba, l_rcv_imp_dq_dqs_new); + if (rc) return rc; + rc = config_rcv_imp(i_target_mba, i_port, l_rcv_imp_dq_dqs_new[i_port]); + if (rc) return rc; + } + else + { + FAPI_INF("Nominal value will not be changed!- Restoring the original values!"); + rc = config_rcv_imp(i_target_mba, i_port, l_rcv_imp_dq_dqs_nom[i_port]); + if (rc) return rc; + } + } + FAPI_INF("++++ Receiver Impdeance Shmoo function executed successfully ++++"); + } +return rc; +} + +//------------------------------------------------------------------------------ +// Function name:delay_shmoo() +// Calls Delay shmoo function varies delay values of each dq and returns timing margin +// Input param: const fapi::Target MBA, port = 0,1 +// Shmoo type: MCBIST, WR_EYE, RD_EYE, WR_DQS, RD_DQS +// Shmoo Mode: FEW_ADDR, QUARTER_ADDR, HALF_ADDR, FULL_ADDR +// i_pattern, i_test_type : Default = 0, mcbist lab function would use this arg +// Output param: l_left_margin = Left Margin(Setup time), +// l_right_margin = Right Margin (Hold time) in ps +//------------------------------------------------------------------------------ + +fapi::ReturnCode delay_shmoo(const fapi::Target & i_target_mba, uint8_t i_port, + shmoo_type_t i_shmoo_type_valid, + uint32_t *o_left_margin, + uint32_t *o_right_margin, + uint8_t i_pattern, + uint8_t i_test_type) +{ + fapi::ReturnCode rc; + FAPI_INF(" Inside the delay shmoo "); + //Constructor CALL: generic_shmoo::generic_shmoo(uint8_t i_port, uint32_t shmoo_mask,shmoo_algorithm_t shmoo_algorithm) + generic_shmoo mss_shmoo=generic_shmoo(i_port,i_shmoo_type_valid,SEQ_LIN); + rc = mss_shmoo.run(i_target_mba, o_left_margin, o_right_margin,i_pattern,i_test_type); + if(rc) + { + FAPI_ERR("Delay Schmoo Function is Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } +return rc; +} + +//------------------------------------------------------------------------------ +// Function name:find_best_margin() +// Finds better timing margin and returns the index +// Input param: const fapi::Target MBA, port = 0,1 +// Shmoo param: PARAM_NONE, DRV_IMP, SLEW_RATE, WR_VREF, RD_VREF, RCV_IMP +// i_left[], i_right[] - timing margin arrays, i_max = Max enum value of schmoo param +// i_param_nom = selected shmoo parameter (DRV_IMP, SLEW_RATE, WR_VREF, RD_VREF, RCV_IMP +// Output param: o_index (returns index) +//------------------------------------------------------------------------------ + + +void find_best_margin(shmoo_param i_shmoo_param_valid, + uint32_t i_left[], + uint32_t i_right[], + const uint8_t i_max, + uint32_t i_param_nom, + uint8_t& o_index) +{ + uint32_t left_margin = 0; + uint32_t right_margin = 0; + uint32_t left_margin_nom = 0; + uint32_t right_margin_nom = 0; + uint32_t diff_margin_nom = 0; + uint32_t total_margin = 0; + uint32_t diff_margin = 0; + uint8_t index = 0; + uint8_t index2 = 0; + + + for(index = 0; index < i_max; index+=1) //send max from top function + { + if(i_shmoo_param_valid & DRV_IMP) + { + if (drv_imp_array[index] == i_param_nom) + { + left_margin_nom = i_left[index]; + right_margin_nom = i_right[index]; + diff_margin_nom = (i_left[index] >= i_right[index]) ? (i_left[index] - i_right[index]) : (i_right[index] - i_left[index]); + FAPI_INF("Driver impedance value (NOM): %d Ohms Setup Margin: %d Hold Margin: %d", i_param_nom, i_left[index], i_right[index]); + break; + } + } + else if(i_shmoo_param_valid & SLEW_RATE) + { + if (slew_rate_array[index] == i_param_nom) + { + left_margin_nom = i_left[index]; + right_margin_nom = i_right[index]; + diff_margin_nom = (i_left[index] >= i_right[index]) ? (i_left[index] - i_right[index]) : (i_right[index] - i_left[index]); + FAPI_INF("Slew rate value (NOM): %d V/ns Setup Margin: %d Hold Margin: %d", i_param_nom, i_left[index], i_right[index]); + break; + } + } + else if(i_shmoo_param_valid & WR_VREF) + { + if (wr_vref_array_fitness[index] == i_param_nom) + { + left_margin_nom = i_left[index]; + right_margin_nom = i_right[index]; + diff_margin_nom = (i_left[index] >= i_right[index]) ? (i_left[index] - i_right[index]) : (i_right[index] - i_left[index]); + FAPI_INF("Write DRAM Vref value (NOM): %d mV Setup Margin: %d Hold Margin: %d", i_param_nom, i_left[index], i_right[index]); + break; + } + } + else if(i_shmoo_param_valid & RD_VREF) + { + if (rd_cen_vref_array_fitness[index] == i_param_nom) + { + left_margin_nom = i_left[index]; + right_margin_nom = i_right[index]; + diff_margin_nom = (i_left[index] >= i_right[index]) ? (i_left[index] - i_right[index]) : (i_right[index] - i_left[index]); + FAPI_INF("Centaur Read Vref value (NOM): %d mV Setup Margin: %d Hold Margin: %d", i_param_nom, i_left[index], i_right[index]); + break; + } + } + else if(i_shmoo_param_valid & RCV_IMP) + { + if (rcv_imp_array[index] == i_param_nom) + { + left_margin_nom = i_left[index]; + right_margin_nom = i_right[index]; + diff_margin_nom = (i_left[index] >= i_right[index]) ? (i_left[index] - i_right[index]) : (i_right[index] - i_left[index]); + FAPI_INF("Receiver Impedance value (NOM): %d Ohms Setup Margin: %d Hold Margin: %d", i_param_nom, i_left[index], i_right[index]); + break; + } + } + + } + for(index2 = 0; index2 < i_max; index2+=1) + { + left_margin = i_left[index2]; + right_margin = i_right[index2]; + total_margin = i_left[index2] + i_right[index2]; + diff_margin = (i_left[index2] >= i_right[index2]) ? (i_left[index2] - i_right[index2]) : (i_right[index2] - i_left[index2]); + if ((left_margin > 0 && right_margin > 0)) + { + if((left_margin >= left_margin_nom) && (right_margin >= right_margin_nom) && (diff_margin <= diff_margin_nom)) + { + o_index = index2; + //wont break this loop, since the purpose is to find the best parameter value & best timing margin The enum is constructed to do that + FAPI_INF("Best Value found on index %d, Setup Margin: %d, Hold Margin: %d", o_index, i_left[index2], i_right[index2]); + } + } + } +} diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_draminit_training_advanced.H b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_draminit_training_advanced.H new file mode 100755 index 000000000..706672cbd --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_draminit_training_advanced.H @@ -0,0 +1,82 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_draminit_training_advanced.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: mss_draminit_training_advanced.H,v 1.13 2012/12/06 11:13:42 lapietra Exp $ +/* File is created by SARAVANAN SETHURAMAN on Thur Sept 28 2011. */ + +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2007 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//------------------------------------------------------------------------------ +// *! TITLE :mss_draminit_training_advanced.H +// *! DESCRIPTION : Tools for centaur procedures +// *! OWNER NAME : SARAVANAN SETHURAMAN email id: saravanans@in.ibm.com +// *! BACKUP NAME :MARK D BELLOWS email id: bellows@us.ibm.com +// #! ADDITIONAL COMMENTS : +// +// General purpose funcs + +//------------------------------------------------------------------------------ +// Don't forget to create CVS comments when you check in your changes! +//------------------------------------------------------------------------------ +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:| Author: | Date: | Comment: +//---------|---------- |--------- |----------------------------------------------- +// 1.0 | 28-Sep-11 | sasethur | First drop of Centaur +// 1.1 | 18-Nov-11 | sasethur | Added typedef and comment update +// 1.2 | 13-Feb-12 | sasethur | Updated scom address naming convention +// 1.9 | 16-Jul-12 | bellows | Added in Id tag +// 1.10 | 15-Oct-12 | sasethur | Updated user option +// 1.11 | 26-Oct-12 | sasethur | Updated fapi:: and const Target & for HB environment +// 1.12 | 15-Nov-12 | sasethur | Updated fw review comments +// 1.13 | 07-Dec-12 | sasethur | Updated for fw review in comment section + + +#ifndef _MSS_DRAMINIT_TRAINING_ADVANCED_H +#define _MSS_DRAMINIT_TRAINING_ADVANCED_H + +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include <fapi.H> + +typedef fapi::ReturnCode (*mss_draminit_training_advanced_FP_t)(const fapi::Target &,uint8_t i_pattern,uint8_t i_test_type); + + +extern "C" +{ +/** +* @brief Draminit training advanced procedure shmoo's drv_impedance, slew, vref and receiver impedance and get the optimum value +* +* @param[in] i_target Reference to target +* i_pattern To enable patterns for mcbist used in lab/debug mode - user option +* i_test_type To enable test types for mcbist used in lab/debug mode - user option +* @return ReturnCode +*/ + +fapi::ReturnCode mss_draminit_training_advanced(const fapi::Target & i_target_mba,uint8_t i_pattern,uint8_t i_test_type); + +} // extern C + +#endif// _MSS_DRAMINIT_TRAINING_ADVANCED_H 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 new file mode 100644 index 000000000..16a5b259d --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_generic_shmoo.C @@ -0,0 +1,1141 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_generic_shmoo.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: mss_generic_shmoo.C,v 1.16 2012/12/14 16:09:53 sasethur Exp $ +// *!*************************************************************************** +// *! (C) Copyright International Business Machines Corp. 1997, 1998 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +// *!*************************************************************************** +// *! FILENAME : mss_generic_shmoo.C +// *! TITLE : MSS Generic Shmoo Implementation +// *! DESCRIPTION : Memory Subsystem Generic Shmoo -- abstraction for HB +// *! CONTEXT : To make all shmoos share a common abstraction layer +// *! +// *! OWNER NAME : Abhijit Saurabh Email: abhijit.saurabh@in.ibm.com +// *! BACKUP NAME : preetham Email: preeragh@in.ibm.com +// *! +// *!*************************************************************************** +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:|Author: | Date: | Comment: +// --------|--------|---------|-------------------------------------------------- +// 1.16 |sasethur|14-DEC-12| Updated for Warning +// 1.15 |abhijit |13-DEC-12| Updated for FW review comments +// 1.14 |abhijit |06-DEC-12| Fixed more FW review comments +// 1.12 |abhijit |15-Nov-12| Fixed FW review comments +// 1.11 |abhijit |29-Oct-12| added change for ISDIMM checker DQS. +// 1.9 |abhijit |22-Oct-12| added Write and read DQS. +// 1.8 |abhijit |15-Oct-12|Updated multiple changes +// 1.0 |varkeykv|27-Sep-11|Initial check in +//------------------------------------------------------------------------------ +#include <fapi.H> +#include "mss_generic_shmoo.H" +#include "mss_mcbist.H" +#include <dimmBadDqBitmapFuncs.H> +#include <mss_access_delay_reg.H> + + + +extern "C" +{ +using namespace fapi; + +// START IMPLEMENTATION OF generic_shmoo CLASS METHODS +//! shmoo_mask - What shmoos do you want to run ... encoded as Hex 0x2,0x4,0x8,0x16 +/*------------------------------------------------------------------------------ + * constructor: generic_shmoo + * Description :Constructor used to initialize variables and do the initial settings + * + * Parameters: i_target: mba; iv_port: 0, 1 + * ---------------------------------------------------------------------------*/ +generic_shmoo:: generic_shmoo(uint8_t prt,uint32_t shmoo_mask,shmoo_algorithm_t shmoo_algorithm) +{ + this->shmoo_mask=shmoo_mask; //! Sets what Shmoos the caller wants to run + this->algorithm=shmoo_algorithm ; + this->iv_port=prt ; + + + iv_MAX_RANKS=8; + iv_MAX_BYTES=10; + iv_DQS_ON=0; + iv_pattern=0; + iv_test_type=0; + iv_dmm_type=0; + + for(int i=0;i<iv_MAX_RANKS;++i) + { + valid_rank[i]=0; + } + + FAPI_DBG("mss_generic_shmoo : constructor running for shmoo type %d",shmoo_mask); + + + + if(shmoo_mask & WR_EYE) + { + FAPI_DBG("mss_generic_shmoo : WR_EYE selected %d",shmoo_mask); + iv_shmoo_type = 0; + SHMOO[0].static_knob.min_val=0; + SHMOO[0].static_knob.max_val=512; + } + if(shmoo_mask & RD_EYE) + { + FAPI_DBG("mss_generic_shmoo : RD_EYE selected %d",shmoo_mask); + iv_shmoo_type = 2; + SHMOO[2].static_knob.min_val=0; + SHMOO[2].static_knob.max_val=128; + } + + if(shmoo_mask & WRT_DQS) //preet + { + FAPI_DBG("mss_generic_shmoo : WRT_DQS selected %d",shmoo_mask); + iv_shmoo_type = 1; + iv_DQS_ON = 1; + SHMOO[1].static_knob.min_val=0; + SHMOO[1].static_knob.max_val=512; + } + + if(shmoo_mask & RD_GATE) //preet + { + FAPI_DBG("mss_generic_shmoo : RD_EYE selected %d",shmoo_mask); + + iv_shmoo_type = 3; + iv_DQS_ON = 1; + SHMOO[3].static_knob.min_val=0; + SHMOO[3].static_knob.max_val=128; + } + + for(int j=0;j<iv_MAX_RANKS;++j) + { + init_multi_array(SHMOO[iv_shmoo_type].MBA.P[iv_port].S[j].K.nom_val,0); + init_multi_array(SHMOO[iv_shmoo_type].MBA.P[iv_port].S[j].K.lb_regval,SHMOO[iv_shmoo_type].static_knob.min_val); + init_multi_array(SHMOO[iv_shmoo_type].MBA.P[iv_port].S[j].K.rb_regval,SHMOO[iv_shmoo_type].static_knob.max_val); + init_multi_array(SHMOO[iv_shmoo_type].MBA.P[iv_port].S[j].K.total_margin,0); + init_multi_array(SHMOO[iv_shmoo_type].MBA.P[iv_port].S[j].K.right_margin_val,0); + init_multi_array(SHMOO[iv_shmoo_type].MBA.P[iv_port].S[j].K.left_margin_val,0); + } + + if(iv_DQS_ON == 1) + { + for(int j=0;j<iv_MAX_RANKS;++j) //initialize values for DQS + { + init_multi_array_dqs(SHMOO[iv_shmoo_type].MBA.P[iv_port].S[j].K.nom_val,0); + init_multi_array_dqs(SHMOO[iv_shmoo_type].MBA.P[iv_port].S[j].K.lb_regval,SHMOO[iv_shmoo_type].static_knob.min_val); + init_multi_array_dqs(SHMOO[iv_shmoo_type].MBA.P[iv_port].S[j].K.rb_regval,SHMOO[iv_shmoo_type].static_knob.max_val); + init_multi_array_dqs(SHMOO[iv_shmoo_type].MBA.P[iv_port].S[j].K.total_margin,0); + init_multi_array_dqs(SHMOO[iv_shmoo_type].MBA.P[iv_port].S[j].K.right_margin_val,0); + init_multi_array_dqs(SHMOO[iv_shmoo_type].MBA.P[iv_port].S[j].K.left_margin_val,0); + } + } +} + +/*------------------------------------------------------------------------------ + * Function: run + * Description : ! Delegator function that runs shmoo using other functions + * + * Parameters: i_target: mba; iv_port: 0, 1 + * ---------------------------------------------------------------------------*/ +fapi::ReturnCode generic_shmoo::run(const fapi::Target & i_target,uint32_t *o_right_min_margin,uint32_t *o_left_min_margin,uint8_t i_pattern,uint8_t i_test_type){ + fapi::ReturnCode rc; + uint8_t num_ranks_per_dimm[2][2]; + uint8_t l_attr_eff_dimm_type_u8=0; + uint8_t rank_pair=0; + uint16_t l_sp_mask=0x00ff; + ecmdDataBufferBase l_data_buffer1_64(64); + uint32_t rc_num = 0; + + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target, num_ranks_per_dimm); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target, l_attr_eff_dimm_type_u8); if(rc) return rc; + iv_MAX_RANKS=num_ranks_per_dimm[iv_port][0]+num_ranks_per_dimm[iv_port][1]; + iv_pattern=i_pattern; + iv_test_type=i_test_type; + + if ( l_attr_eff_dimm_type_u8 == 0 ) + { + iv_MAX_BYTES=10; + + } + else + { + if(iv_port==0) + { + rc_num = rc_num | l_data_buffer1_64.insertFromRight(l_sp_mask,0,16); + if(rc_num) + { + FAPI_ERR( "mss_generic_shmoo: Error in run !"); + rc.setEcmdError(rc_num); + return rc; + } + } + else + { + rc_num = rc_num | l_data_buffer1_64.insertFromRight(l_sp_mask,16,16); + if(rc_num) + { + FAPI_ERR( "mss_generic_shmoo:"); + rc.setEcmdError(rc_num); + return rc; + } + } + rc = fapiPutScom(i_target,MBS_MCBIST01_MCBCMABQ_0x02011674,l_data_buffer1_64); if(rc) return rc; + iv_dmm_type=1; + iv_MAX_BYTES=9; + } + rc = mss_getrankpair(i_target,iv_port,0,&rank_pair,valid_rank);if(rc) return rc; + FAPI_DBG("mss_generic_shmoo : run() for shmoo type %d",shmoo_mask); + // Check if all bytes/bits are in a pass condition initially .Otherwise quit + rc=sanity_check(i_target); // Run MCBIST on default state to make sure everything is fine + if(!rc.ok()) + { + FAPI_ERR("generic_shmoo::run MSS Generic Shmoo failed initial Sanity Check. Memory not in an all pass Condition"); + return rc; + } + // If memory is OK then we continue to gather nominals and config values + // Now Read nominal values for all knobs configured + // FAPI_DBG("mss_generic_shmoo : run() :read nominal values "); + //rc=get_all_noms(i_target);if(rc) return rc; + //Find RIGHT BOUND OR SETUP BOUND + //rc=find_bound(i_target,RIGHT);if(rc) return rc; + //Find LEFT BOUND OR HOLD BOUND + //rc=find_bound(i_target,LEFT);if(rc) return rc; + //Find the margins in Ps i.e setup margin ,hold margin,Eye width + rc=get_margin(i_target);if(rc) return rc; + //It is used to find the lowest of setup and hold margin + //rc=get_min_margin(i_target,o_right_min_margin,o_left_min_margin);if(rc) return rc; + // It is used to print the schmoo report + #ifdef char + //rc=print_report(i_target);if(rc) return rc; + #endif + return rc; +} +/*------------------------------------------------------------------------------ + * Function: sanity_check + * Description : do intial mcbist check in nominal and report spd if any bad bit found + * + * Parameters: i_target: mba; + * ---------------------------------------------------------------------------*/ +fapi::ReturnCode generic_shmoo::sanity_check(const fapi::Target & i_target){ + fapi:: ReturnCode rc; + mcbist_mode=QUARTER_SLOW; + uint8_t l_mcb_status=0; + uint8_t l_rank = 0; + uint8_t l_rank_valid = 0; + uint8_t l_byte = 0; + uint8_t l_nibble = 0; + uint8_t l_socket =0; + uint32_t rc_num = 0; + uint8_t l_dqBitmap[DIMM_DQ_RANK_BITMAP_SIZE]; + uint64_t l_original_start_address1 = 0x0000000000000000; + uint64_t l_original_end_address1 = 0x0000000000000000; + uint64_t l_original_start_address2 = 0x0000000000000000; + uint64_t l_original_end_address2 = 0x0000000000000000; + ecmdDataBufferBase l_data_bufferx1_64(64); + ecmdDataBufferBase l_data_bufferx2_64(64); + ecmdDataBufferBase l_data_bufferx3_64(64); + ecmdDataBufferBase l_data_bufferx4_64(64); + + rc = fapiGetScom(i_target,MBA01_MCBIST_MCBSSARA0Q_0x030106d0,l_data_bufferx1_64); if(rc) return rc; + rc = fapiGetScom(i_target,MBA01_MCBIST_MCBSEARA0Q_0x030106d2,l_data_bufferx2_64); if(rc) return rc; + rc = fapiGetScom(i_target,MBA01_MCBIST_MCBSSARA1Q_0x030106d1,l_data_bufferx3_64); if(rc) return rc; + rc = fapiGetScom(i_target,MBA01_MCBIST_MCBSEARA1Q_0x030106d3,l_data_bufferx4_64); if(rc) return rc; + l_original_start_address1 = l_data_bufferx1_64.getDoubleWord (0); + l_original_end_address1 = l_data_bufferx2_64.getDoubleWord (0); + l_original_start_address2 = l_data_bufferx3_64.getDoubleWord (0); + l_original_end_address2 = l_data_bufferx4_64.getDoubleWord (0); + for(l_rank = 0; l_rank < iv_MAX_RANKS; l_rank++) + { + l_rank_valid=valid_rank[l_rank]; + + if(l_rank_valid<MAX_RANK_DIMM) + { + l_socket=0; + } + else + { + l_socket=1; + } + FAPI_INF(" entering set_up mcbist now and rank %d",l_rank_valid); + + rc = setup_mcbist(i_target, iv_port, MCBIST_2D_CUP_PAT8, MEMWRITE, UNMASK_ALL, 0,iv_pattern,iv_test_type,l_rank_valid);if(rc) return rc; //send shmoo mode to vary the address range + + FAPI_INF(" starting mcbist now"); + rc=start_mcb(i_target);if(rc) return rc; + FAPI_INF(" polling mcbist now"); + rc=poll_mcb(i_target,false,&l_mcb_status);if(rc) return rc; + FAPI_INF(" checking error map "); + rc=mcb_error_map(i_target,mcbist_error_map,iv_port,l_rank_valid);if(rc) return rc; + for(l_byte = 0; l_byte < iv_MAX_BYTES; l_byte++) + { + for(l_nibble = 0; l_nibble < MAX_NIBBLES; l_nibble++) + { + if(mcbist_error_map[iv_port][l_rank_valid][l_byte][l_nibble] == 1) + { + if(l_nibble == 0) + { + l_dqBitmap[l_byte] = 0xf0; + } + else + { + l_dqBitmap[l_byte] = 0x0f; + } + rc = dimmSetBadDqBitmap(i_target,iv_port,l_socket, l_rank_valid, l_dqBitmap);if(rc) return rc; + } + } + } + rc_num = l_data_bufferx1_64.setDoubleWord(0,l_original_start_address1);if (rc_num){FAPI_ERR( "Error in function sanity_check:");rc.setEcmdError(rc_num);return rc;} + rc_num = l_data_bufferx2_64.setDoubleWord(0,l_original_end_address1);if (rc_num){FAPI_ERR( "Error in function sanity_check:");rc.setEcmdError(rc_num);return rc;} + rc_num = l_data_bufferx3_64.setDoubleWord(0,l_original_start_address2);if (rc_num){FAPI_ERR( "Error in function sanity_check:");rc.setEcmdError(rc_num);return rc;} + rc_num = l_data_bufferx4_64.setDoubleWord(0,l_original_end_address2);if (rc_num){FAPI_ERR( "Error in function sanity_check:");rc.setEcmdError(rc_num);return rc;} + rc = fapiPutScom(i_target,MBA01_MCBIST_MCBSSARA0Q_0x030106d0,l_data_bufferx1_64); if(rc) return rc; + rc = fapiPutScom(i_target,MBA01_MCBIST_MCBSEARA0Q_0x030106d2,l_data_bufferx2_64); if(rc) return rc; + rc = fapiPutScom(i_target,MBA01_MCBIST_MCBSSARA1Q_0x030106d1,l_data_bufferx3_64); if(rc) return rc; + rc = fapiPutScom(i_target,MBA01_MCBIST_MCBSEARA1Q_0x030106d3,l_data_bufferx4_64); if(rc) return rc; + + } + + if(l_mcb_status) + { + FAPI_ERR("generic_shmoo:sanity_check failed !! MCBIST failed on intial run , memory is not in good state aborting shmoo"); + FAPI_SET_HWP_ERROR(rc,RC_MSS_MCBIST_ERROR); + return rc; + } + + return rc; +} +/*------------------------------------------------------------------------------ + * Function: do_mcbist_test + * Description : do mcbist check for error on particular nibble + * + * Parameters: i_target: mba,iv_port 0/1 , rank 0-7 , byte 0-7, nibble 0/1, pass; + * ---------------------------------------------------------------------------*/ +fapi::ReturnCode generic_shmoo::do_mcbist_test(const fapi::Target & i_target,uint8_t i_rank,uint8_t i_byte,uint8_t i_nibble,uint8_t &pass) +{ + mcbist_mode=QUARTER_SLOW; + uint8_t l_socket=0; + uint8_t l_mcb_status=0; + input_type l_input_type_e = ISDIMM_DQ; + uint8_t i_input_index_u8=0; + uint8_t l_val =0; + uint32_t rc_num =0; + fapi::ReturnCode rc; + uint64_t l_original_start_address1 = 0x0000000000000000; + uint64_t l_original_end_address1 = 0x0000000000000000; + uint64_t l_original_start_address2 = 0x0000000000000000; + uint64_t l_original_end_address2 = 0x0000000000000000; + ecmdDataBufferBase l_data_bufferx1_64(64); + ecmdDataBufferBase l_data_bufferx2_64(64); + ecmdDataBufferBase l_data_bufferx3_64(64); + ecmdDataBufferBase l_data_bufferx4_64(64); + + rc = fapiGetScom(i_target,MBA01_MCBIST_MCBSSARA0Q_0x030106d0,l_data_bufferx1_64); if(rc) return rc; + rc = fapiGetScom(i_target,MBA01_MCBIST_MCBSEARA0Q_0x030106d2,l_data_bufferx2_64); if(rc) return rc; + rc = fapiGetScom(i_target,MBA01_MCBIST_MCBSSARA1Q_0x030106d1,l_data_bufferx3_64); if(rc) return rc; + rc = fapiGetScom(i_target,MBA01_MCBIST_MCBSEARA1Q_0x030106d3,l_data_bufferx4_64); if(rc) return rc; + l_original_start_address1 = l_data_bufferx1_64.getDoubleWord (0); + l_original_end_address1 = l_data_bufferx2_64.getDoubleWord (0); + l_original_start_address2 = l_data_bufferx3_64.getDoubleWord (0); + l_original_end_address2 = l_data_bufferx4_64.getDoubleWord (0); + + if(i_rank<4) + { + l_socket=0; + } + else + { + l_socket=1; + } + + + + rc = setup_mcbist(i_target, iv_port, MCBIST_2D_CUP_PAT8, MEMWRITE, UNMASK_ALL, 0, iv_pattern,iv_test_type,i_rank); if(rc) return rc; + + rc = start_mcb(i_target); + if(rc) + { + FAPI_ERR("generic_shmoo::do_mcbist_test: Start MCBIST failed !!"); + + return rc; + } + rc=poll_mcb(i_target,false,&l_mcb_status); + if(rc) + { + FAPI_ERR("generic_shmoo::do_mcbist_test: POLL MCBIST failed !!"); + + return rc; + } + rc=mcb_error_map(i_target,mcbist_error_map,iv_port,i_rank); + if(rc) + { + FAPI_ERR("generic_shmoo::do_mcbist_test: mcb_error_map failed!!"); + + return rc; + } + rc_num = l_data_bufferx1_64.setDoubleWord(0,l_original_start_address1);if (rc_num){FAPI_ERR( "Error in function do_mcbist_test:");rc.setEcmdError(rc_num);return rc;} + rc_num = l_data_bufferx2_64.setDoubleWord(0,l_original_end_address1);if (rc_num){FAPI_ERR( "Error in function do_mcbist_test:");rc.setEcmdError(rc_num);return rc;} + rc_num = l_data_bufferx3_64.setDoubleWord(0,l_original_start_address2);if (rc_num){FAPI_ERR( "Error in function do_mcbist_test:");rc.setEcmdError(rc_num);return rc;} + rc_num = l_data_bufferx4_64.setDoubleWord(0,l_original_end_address2);if (rc_num){FAPI_ERR( "Error in function do_mcbist_test:");rc.setEcmdError(rc_num);return rc;} + rc = fapiPutScom(i_target,MBA01_MCBIST_MCBSSARA0Q_0x030106d0,l_data_bufferx1_64); if(rc) return rc; + rc = fapiPutScom(i_target,MBA01_MCBIST_MCBSEARA0Q_0x030106d2,l_data_bufferx2_64); if(rc) return rc; + rc = fapiPutScom(i_target,MBA01_MCBIST_MCBSSARA1Q_0x030106d1,l_data_bufferx3_64); if(rc) return rc; + rc = fapiPutScom(i_target,MBA01_MCBIST_MCBSEARA1Q_0x030106d3,l_data_bufferx4_64); if(rc) return rc; + + if(iv_dmm_type==1) + { + i_input_index_u8=8*i_byte+4*i_nibble; + rc=rosetta_map(i_target,iv_port,l_input_type_e,i_input_index_u8,l_val);if(rc) return rc; + i_byte=l_val/8; + i_nibble=l_val%4; + check_error_map(i_rank,i_byte,i_nibble,pass); + + } + else + { + check_error_map(i_rank,i_byte,i_nibble,pass); + + } + return rc; +} +/*------------------------------------------------------------------------------ + * Function: check_error_map + * Description : used by do_mcbist_test to check the error map for particular nibble + * + * Parameters: iv_port 0/1 , rank 0-7 , byte 0-7, nibble 0/1, pass; + * ---------------------------------------------------------------------------*/ +void generic_shmoo::check_error_map(uint8_t i_rank,uint8_t i_byte,uint8_t i_nibble,uint8_t &pass) +{ + + if( mcbist_error_map [iv_port][i_rank][i_byte][i_nibble] == 1){ + pass=0; + FAPI_INF("We are in error1"); + } + else + { + pass=1; + FAPI_INF("We are in error2"); + } + +} +/*------------------------------------------------------------------------------ + * Function: init_multi_array + * Description : This function do the initialization of various schmoo parameters + * + * Parameters: the array address and the initial value + * ---------------------------------------------------------------------------*/ +void generic_shmoo::init_multi_array(uint32_t (&array)[MAX_DQ][MAX_RPS],uint32_t init_val) +{ + + uint8_t l_byte,l_nibble,l_bit,l_rp; + uint8_t l_dq=0; + for (l_rp=0;l_rp<MAX_RPS;++l_rp) + {// Byte loop + + for(l_byte=0;l_byte<iv_MAX_BYTES;++l_byte) + { //Nibble loop + for(l_nibble=0;l_nibble< MAX_NIBBLES;++l_nibble) + { + //Bit loop + for(l_bit=0;l_bit<MAX_BITS;++l_bit) + { + l_dq=8*l_byte+4*l_nibble+l_bit; + array[l_dq][l_rp]=init_val; + } + } + } + } + +} +/*------------------------------------------------------------------------------ + * Function: init_multi_array_dqs + * Description : This function do the initialization of various schmoo parameters + * + * Parameters: the array address and the initial value + * ---------------------------------------------------------------------------*/ +fapi::ReturnCode generic_shmoo::init_multi_array_dqs(uint32_t (&array)[MAX_DQ][MAX_RPS],uint32_t init_val) +{ + fapi::ReturnCode rc; + uint8_t l_byte,l_nibble,l_bit,l_rp; + uint8_t l_dq=0; + for (l_rp=0;l_rp<MAX_RPS;++l_rp) + {// Byte loop + + for(l_byte=0;l_byte<iv_MAX_BYTES;++l_byte) + { //Nibble loop + for(l_nibble=0;l_nibble< MAX_NIBBLES;++l_nibble) + { + //Bit loop + for(l_bit=0;l_bit<MAX_BITS;++l_bit) + { + l_dq=8*l_byte+4*l_nibble+l_bit; + array[l_dq][l_rp]=init_val; + } + } + } + } +return rc; +} +/*------------------------------------------------------------------------------ + * Function: get_all_noms + * Description : This function gets the nominal values for each DQ + * + * Parameters: Target:MBA + * ---------------------------------------------------------------------------*/ +fapi::ReturnCode generic_shmoo::get_all_noms(const fapi::Target & i_target) +{ + fapi::ReturnCode rc; + + uint8_t l_rnk,l_byte,l_nibble,l_bit; + uint8_t i_rnk=0; + uint8_t i_rp=0; + uint32_t val=0; + uint8_t l_dq=0; + + input_type_t l_input_type_e = WR_DQ; + access_type_t l_access_type_e = READ ; + FAPI_DBG("mss_generic_shmoo : get_all_noms : Reading in all nominal values"); + + + if(iv_shmoo_type == 1) + { + l_input_type_e = WR_DQS; + + } + else if(iv_shmoo_type == 2) + { + + l_input_type_e = RD_DQ; + + } + else if(iv_shmoo_type == 3) + { + + l_input_type_e = RD_DQS; + + } + + + for (l_rnk=0;l_rnk<iv_MAX_RANKS;++l_rnk) + {// Byte loop + i_rnk=valid_rank[l_rnk]; + rc = mss_getrankpair(i_target,iv_port,i_rnk,&i_rp,valid_rank);if(rc) return rc; + for(l_byte=0;l_byte<iv_MAX_BYTES;++l_byte) + { //Nibble loop + for(l_nibble=0;l_nibble< MAX_NIBBLES;++l_nibble) + { + //Bit loop + for(l_bit=0;l_bit<MAX_BITS;++l_bit) + { + l_dq=8*l_byte+4*l_nibble+l_bit; + + rc=mss_access_delay_reg(i_target,l_access_type_e,iv_port,i_rnk,l_input_type_e,l_dq,val);if(rc) return rc; + SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rnk].K.nom_val[l_dq][i_rp]=val; + FAPI_INF("Nominal Value for rank=%d and rank pair=%d and dq=%d is %d",i_rnk,i_rp,l_dq,val); + + } + } + } + } + return rc; +} + +/*------------------------------------------------------------------------------ + * Function: knob_update + * Description : This is a key function is used to find right and left bound using new algorithm -- there is an option u can chose not to use it by setting a flag + * + * Parameters: Target:MBA,bound:RIGHT/LEFT,scenario:type of schmoo,iv_port:0/1,rank:0-7,byte:0-7,nibble:0/1,bit:0-3,pass, + * ---------------------------------------------------------------------------*/ +fapi::ReturnCode generic_shmoo::knob_update(const fapi::Target & i_target,bound_t bound,uint8_t scenario,uint8_t rank,uint8_t byte,uint8_t nibble,uint8_t bit,uint8_t pass,bool &flag) +{ + fapi::ReturnCode rc; + ecmdDataBufferBase data_buffer_64(64); + ecmdDataBufferBase data_buffer_64_1(64); + uint32_t l_current_val=0; + uint32_t l_left_del=20; + uint32_t l_right_del=400; + uint32_t l_max_value=0; + uint32_t l_min_value=0; + uint16_t l_nibb_err_chk=2*byte+nibble; + uint32_t l_rd_cnt_A=0; + uint32_t l_rd_cnt_B=0; + uint32_t l_err_cnt_C=0; + uint32_t l_start_bit=0; + uint32_t rc_ecmd; + uint32_t l_length_buffer=7; + uint32_t l_delta=0; + uint32_t l_err_prblty=0; + uint8_t l_rp=0; + input_type_t l_input_type_e = WR_DQ; + uint8_t l_dq=0; + access_type_t l_access_type_e = WRITE; + + + + l_dq=8*byte+4*nibble+bit; + + rc = mss_getrankpair(i_target,iv_port,rank,&l_rp,valid_rank);if(rc) return rc; + + + if(scenario == 2) { + l_input_type_e = RD_DQ; + } + + + if(bound==LEFT) + { + + if(algorithm==SEQ_LIN) + { + l_min_value=SHMOO[scenario].static_knob.min_val; + for(l_current_val=SHMOO[scenario].MBA.P[iv_port].S[rank].K.nom_val[l_dq][l_rp];((l_current_val >= l_left_del)&&(pass==1));l_current_val-=l_left_del) + { + FAPI_DBG(" The current value inside left bound for dq=%d and rp=%d is %d ",l_dq,l_rp,l_current_val); + rc=mss_access_delay_reg(i_target,l_access_type_e,iv_port,rank,l_input_type_e,l_dq,l_current_val);if(rc) return rc; + rc=do_mcbist_test(i_target,rank,byte,nibble,pass); + if(rc) + { + FAPI_ERR("generic_shmoo::find_bound do_mcbist_test failed"); + return rc; + } + } + if(flag) + { + pass=1; + for(l_current_val=l_current_val+10;((l_current_val>l_min_value)&&(pass==1));l_current_val--) + { + rc=mss_access_delay_reg(i_target,l_access_type_e,iv_port,rank,l_input_type_e,l_dq,l_current_val);if(rc) return rc; + rc = fapiGetScom(i_target,MBA01_MBA_PMU0Q_0x03010437,data_buffer_64); if(rc) return rc; + l_rd_cnt_A = data_buffer_64.getDoubleWord(0); + do + { + rc = fapiGetScom(i_target,MBA01_MBA_PMU0Q_0x03010437,data_buffer_64); if(rc) return rc; + l_rd_cnt_B = data_buffer_64.getDoubleWord(0); + if(iv_port==0) + { + if(l_nibb_err_chk<9) + { + rc = fapiGetScom(i_target,MBS_MCBIST01_MCB_ERRCNTA1Q_0x02011664,data_buffer_64_1); if(rc) return rc; + l_start_bit=l_nibb_err_chk*7; + rc_ecmd=data_buffer_64.extractToRight(&l_err_cnt_C,l_start_bit,l_length_buffer);if (rc_ecmd){ rc.setEcmdError(rc_ecmd); return rc;} + } + else + { + rc = fapiGetScom(i_target,MBS_MCBIST01_MCB_ERRCNTA2Q_0x02011665,data_buffer_64_1); if(rc) return rc; + l_nibb_err_chk=l_nibb_err_chk-9; + l_start_bit=l_nibb_err_chk*7; + rc_ecmd=data_buffer_64.extractToRight(&l_err_cnt_C,l_start_bit,l_length_buffer);if (rc_ecmd){ rc.setEcmdError(rc_ecmd); return rc;} + } + } + else + { + if(l_nibb_err_chk<9) + { + rc = fapiGetScom(i_target,MBS_MCBIST01_MCB_ERRCNTB1Q_0x02011667,data_buffer_64_1); if(rc) return rc; + l_start_bit=l_nibb_err_chk*7; + rc_ecmd=data_buffer_64.extractToRight(&l_err_cnt_C,l_start_bit,l_length_buffer);if (rc_ecmd){ rc.setEcmdError(rc_ecmd); return rc;} + } + else + { + rc = fapiGetScom(i_target,MBS_MCBIST01_MCB_ERRCNTB2Q_0x02011668,data_buffer_64_1); if(rc) return rc; + l_nibb_err_chk=l_nibb_err_chk-9; + l_start_bit=l_nibb_err_chk*7; + rc_ecmd=data_buffer_64.extractToRight(&l_err_cnt_C,l_start_bit,l_length_buffer);if (rc_ecmd){ rc.setEcmdError(rc_ecmd); return rc;} + } + } + if(l_rd_cnt_A>l_rd_cnt_B) + { + l_delta=l_rd_cnt_A-l_rd_cnt_B; + } + else + { + l_delta=l_rd_cnt_B-l_rd_cnt_A; + } + if(l_delta>read_counter_threshold) + { + l_err_prblty=l_err_cnt_C*read_counter_threshold; + l_err_prblty=l_err_prblty/l_delta; + if(l_err_prblty>error_threshold_count) + { + pass=0; + } + else + { + pass=1; + } + } + }while(l_delta<read_counter_threshold); + if(!pass) + { + SHMOO[scenario].MBA.P[iv_port].S[rank].K.lb_regval[l_dq][l_rp]=l_current_val; + } + } + } + if(!pass) + { + SHMOO[scenario].MBA.P[iv_port].S[rank].K.lb_regval[l_dq][l_rp]=l_current_val; + } + else + { + SHMOO[scenario].MBA.P[iv_port].S[rank].K.lb_regval[l_dq][l_rp]=l_current_val+l_left_del; + } + l_current_val=SHMOO[scenario].MBA.P[iv_port].S[rank].K.nom_val[l_dq][l_rp]; + FAPI_INF(" the restoring nominal value for rank=%d dq=%d and rp=%d is %d",rank,l_dq,l_rp,l_current_val); + rc=mss_access_delay_reg(i_target,l_access_type_e,iv_port,rank,l_input_type_e,l_dq,l_current_val);if(rc) return rc; + } + } + if(bound==RIGHT) + { + if(algorithm==SEQ_LIN) + { + l_max_value=SHMOO[scenario].static_knob.max_val; + for(l_current_val=SHMOO[scenario].MBA.P[iv_port].S[rank].K.nom_val[l_dq][l_rp];((l_current_val<l_max_value)&&(pass==1));l_current_val+=l_right_del) + { + FAPI_DBG(" The current value inside right bound dq=%d and rp=%d is %d ",l_dq,l_rp,l_current_val); + rc=mss_access_delay_reg(i_target,l_access_type_e,iv_port,rank,l_input_type_e,l_dq,l_current_val);if(rc) return rc; + rc=do_mcbist_test(i_target,rank,byte,nibble,pass); + if(rc) + { + FAPI_ERR("generic_shmoo::find_bound do_mcbist_test failed"); + return rc; + } + } + + if(flag) + { + pass=1; + for(l_current_val=l_current_val-20;((l_current_val<l_max_value)&&(pass==1));l_current_val++) + { + rc=mss_access_delay_reg(i_target,l_access_type_e,iv_port,rank,l_input_type_e,l_dq,l_current_val);if(rc) return rc; + rc = fapiGetScom(i_target,MBA01_MBA_PMU0Q_0x03010437,data_buffer_64); if(rc) return rc; + l_rd_cnt_A = data_buffer_64.getDoubleWord(0); + do + { + rc = fapiGetScom(i_target,MBA01_MBA_PMU0Q_0x03010437,data_buffer_64); if(rc) return rc; + l_rd_cnt_B = data_buffer_64.getDoubleWord(0); + if(iv_port==0) + { + if(l_nibb_err_chk<9) + { + rc = fapiGetScom(i_target,MBS_MCBIST01_MCB_ERRCNTA1Q_0x02011664,data_buffer_64_1); if(rc) return rc; + l_start_bit=l_nibb_err_chk*7; + rc_ecmd=data_buffer_64.extractToRight(&l_err_cnt_C,l_start_bit,l_length_buffer);if (rc_ecmd){ rc.setEcmdError(rc_ecmd); return rc;} + } + else + { + rc = fapiGetScom(i_target,MBS_MCBIST01_MCB_ERRCNTA2Q_0x02011665,data_buffer_64_1); if(rc) return rc; + l_nibb_err_chk=l_nibb_err_chk-9; + l_start_bit=l_nibb_err_chk*7; + rc_ecmd=data_buffer_64.extractToRight(&l_err_cnt_C,l_start_bit,l_length_buffer);if (rc_ecmd){ rc.setEcmdError(rc_ecmd); return rc;} + } + } + else + { + if(l_nibb_err_chk<9) + { + rc = fapiGetScom(i_target,MBS_MCBIST01_MCB_ERRCNTB1Q_0x02011667,data_buffer_64_1); if(rc) return rc; + l_start_bit=l_nibb_err_chk*7; + rc_ecmd=data_buffer_64.extractToRight(&l_err_cnt_C,l_start_bit,l_length_buffer);if (rc_ecmd){ rc.setEcmdError(rc_ecmd); return rc;} + } + else + { + rc = fapiGetScom(i_target,MBS_MCBIST01_MCB_ERRCNTB2Q_0x02011668,data_buffer_64_1); if(rc) return rc; + l_nibb_err_chk=l_nibb_err_chk-9; + l_start_bit=l_nibb_err_chk*7; + rc_ecmd=data_buffer_64.extractToRight(&l_err_cnt_C,l_start_bit,l_length_buffer);if (rc_ecmd){ rc.setEcmdError(rc_ecmd); return rc;} + } + } + if(l_rd_cnt_A>l_rd_cnt_B) + { + l_delta=l_rd_cnt_A-l_rd_cnt_B; + } + else + { + l_delta=l_rd_cnt_B-l_rd_cnt_A; + } + if(l_delta>read_counter_threshold) + { + l_err_prblty=l_err_cnt_C*read_counter_threshold; + l_err_prblty=l_err_prblty/l_delta; + if(l_err_prblty>error_threshold_count) + { + pass=0; + } + else + { + pass=1; + } + } + }while(l_delta<read_counter_threshold); + if(!pass) + { + SHMOO[scenario].MBA.P[iv_port].S[rank].K.rb_regval[l_dq][l_rp]=l_current_val; + } + else + { + SHMOO[scenario].MBA.P[iv_port].S[rank].K.rb_regval[l_dq][l_rp]=l_current_val-l_right_del; + } + } + } + if(!pass) + { + SHMOO[scenario].MBA.P[iv_port].S[rank].K.rb_regval[l_dq][l_rp]=l_current_val; + } + else + { + SHMOO[scenario].MBA.P[iv_port].S[rank].K.rb_regval[l_dq][l_rp]=l_current_val-l_right_del; + } + FAPI_INF(" the right bound %d ",SHMOO[scenario].MBA.P[iv_port].S[rank].K.rb_regval[l_dq][l_rp]); + l_current_val=SHMOO[scenario].MBA.P[iv_port].S[rank].K.nom_val[l_dq][l_rp]; + FAPI_INF(" the restoring nominal value for rank=%d dq=%d and rp=%d is %d",rank,l_dq,l_rp,l_current_val); + rc=mss_access_delay_reg(i_target,l_access_type_e,iv_port,rank,l_input_type_e,l_dq,l_current_val);if(rc) return rc; + + } + } + return rc; +} +/*------------------------------------------------------------------------------ + * Function: knob_update_dqs + * Description : This is a key function is used to find right and left bound using new algorithm -- there is an option u can chose not to use it by setting a flag + * + * Parameters: Target:MBA,bound:RIGHT/LEFT,scenario:type of schmoo,iv_port:0/1,rank:0-7,byte:0-7,nibble:0/1,bit:0-3,pass, + * ---------------------------------------------------------------------------*/ +fapi::ReturnCode generic_shmoo::knob_update_dqs(const fapi::Target & i_target,bound_t bound,uint8_t scenario,uint8_t rank,uint8_t byte,uint8_t nibble,uint8_t bit,uint8_t pass) +{ + fapi::ReturnCode rc; + ecmdDataBufferBase data_buffer_64(64); + ecmdDataBufferBase data_buffer_64_1(64); + data_buffer_64.flushTo0(); + data_buffer_64_1.flushTo0(); + uint32_t l_current_val=0; + uint32_t l_max_value=0; + uint32_t l_min_value=0; + + uint8_t l_rp=0; + input_type_t l_input_type_e = WR_DQS; + uint8_t l_dq=0; + access_type_t l_access_type_e = WRITE; + + if(scenario == 1) + { + l_input_type_e = WR_DQS; + } + else if(scenario == 3) + { + l_input_type_e = RD_DQS; + } + + if(bound==LEFT) + { + + if(algorithm==SEQ_LIN) + { + l_min_value=SHMOO[scenario].static_knob.min_val; + FAPI_INF(" curr val in left above = %d and pass=%d ",l_current_val,pass); + for(l_current_val=SHMOO[scenario].MBA.P[iv_port].S[rank].K.nom_val[l_dq][l_rp];((l_current_val >= 20)&&(pass==1));l_current_val-=20) + { + //use saurabh function for writing here + FAPI_INF(" curr val in left = %d and pass=%d ",l_current_val,pass); + rc=mss_access_delay_reg(i_target,l_access_type_e,iv_port,0,l_input_type_e,l_dq,l_current_val);if(rc) return rc; + + rc=do_mcbist_test(i_target,rank,byte,nibble,pass); + if(rc) + { + FAPI_ERR("generic_shmoo::find_bound do_mcbist_test failed"); + return rc; + } + } + if(!pass) + { + SHMOO[scenario].MBA.P[iv_port].S[rank].K.lb_regval[l_dq][l_rp]=l_current_val; + } + FAPI_INF(" left bound = %d ",SHMOO[scenario].MBA.P[iv_port].S[rank].K.rb_regval[l_dq][l_rp]); + l_current_val=SHMOO[scenario].MBA.P[iv_port].S[rank].K.nom_val[l_dq][l_rp]; + rc=mss_access_delay_reg(i_target,l_access_type_e,iv_port,0,l_input_type_e,l_dq,l_current_val);if(rc) return rc; + + } + } + + else if(bound==RIGHT) + { + + if(algorithm==SEQ_LIN) + { + l_max_value=SHMOO[scenario].static_knob.max_val; + for(l_current_val=SHMOO[scenario].MBA.P[iv_port].S[rank].K.nom_val[l_dq][l_rp];((l_current_val<l_max_value)&&(pass==1));l_current_val+=100) + { + //use saurabh function for writing here + FAPI_INF(" curr val = %d ",l_current_val); + rc=mss_access_delay_reg(i_target,l_access_type_e,iv_port,0,l_input_type_e,l_dq,l_current_val);if(rc) return rc; + + rc=do_mcbist_test(i_target,rank,byte,nibble,pass); + if(rc) + { + FAPI_ERR("generic_shmoo::find_bound do_mcbist_test failed"); + return rc; + } + } + if(!pass) + { + SHMOO[scenario].MBA.P[iv_port].S[rank].K.rb_regval[l_dq][l_rp]=l_current_val; + } + l_current_val=SHMOO[scenario].MBA.P[iv_port].S[rank].K.nom_val[l_dq][l_rp]; + + rc=mss_access_delay_reg(i_target,l_access_type_e,iv_port,0,l_input_type_e,l_dq,l_current_val);if(rc) return rc; + FAPI_INF(" right bound = %d ",SHMOO[scenario].MBA.P[iv_port].S[rank].K.rb_regval[l_dq][l_rp]); + } + + } + return rc; +} + +/*------------------------------------------------------------------------------ + * Function: find_bound + * Description : This function calls the knob_update for each DQ which is used to find bound that is left/right according to schmoo type + * + * Parameters: Target:MBA,bound:RIGHT/LEFT, + * ---------------------------------------------------------------------------*/ +fapi::ReturnCode generic_shmoo::find_bound(const fapi::Target & i_target,bound_t bound){ + uint8_t l_rnk,l_byte,l_nibble,l_bit; + fapi::ReturnCode rc; + + uint8_t i_scenario = 0; + uint8_t i_rank=0; + bool flag=false; + + + + FAPI_INF("generic_shmoo::find_bound running find_bound function "); + for(i_scenario=0;i_scenario<MAX_SHMOO;++i_scenario) + { + + for (l_rnk=0;l_rnk<iv_MAX_RANKS;++l_rnk) + {// Byte loop + i_rank=valid_rank[l_rnk]; + for(l_byte=0;l_byte<iv_MAX_BYTES;++l_byte) + { //Nibble loop + + for(l_nibble=0;l_nibble< MAX_NIBBLES;++l_nibble) + { + + //Bit loop + for(l_bit=0;l_bit< MAX_BITS;++l_bit) + { + // preetham function here + + + if(iv_DQS_ON==1) + rc=knob_update_dqs(i_target,bound,i_scenario,i_rank,l_byte,l_nibble,l_bit,1);if(rc) return rc; + else + rc=knob_update(i_target,bound,i_scenario,i_rank,l_byte,l_nibble,l_bit,1,flag); if(rc) return rc; + } + } + } + } + } + return rc; +} +#ifdef char +/*------------------------------------------------------------------------------ + * Function: print_report + * Description : This function is used to print the information needed such as freq,voltage etc, and also the right,left and total margin + * + * Parameters: Target:MBA + * ---------------------------------------------------------------------------*/ +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_rp=0; + uint8_t i_rank=0; + uint8_t l_mbapos = 0; + uint32_t l_attr_mss_freq_u32 = 0; + uint32_t l_attr_mss_volt_u32 = 0; + uint8_t l_attr_eff_dimm_type_u8 = 0; + uint8_t l_attr_eff_num_drops_per_port_u8 = 0; + uint8_t l_attr_eff_dram_width_u8 = 0; + fapi::Target l_target_centaur; + + + rc = fapiGetParentChip(i_target, l_target_centaur); if(rc) return rc; + + rc = FAPI_ATTR_GET(ATTR_MSS_FREQ, &l_target_centaur, l_attr_mss_freq_u32); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_MSS_VOLT, &l_target_centaur, l_attr_mss_volt_u32); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target, l_attr_eff_dimm_type_u8); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_DROPS_PER_PORT, &i_target, l_attr_eff_num_drops_per_port_u8); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &i_target, l_attr_eff_dram_width_u8); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_target, l_mbapos);if(rc) return rc; + + FAPI_INF(" freq = %d on %s.", l_attr_mss_freq_u32, l_target_centaur.toEcmdString()); + FAPI_INF("volt = %d on %s.", l_attr_mss_volt_u32, l_target_centaur.toEcmdString()); + FAPI_INF("dimm_type = %d on %s.", l_attr_eff_dimm_type_u8, i_target.toEcmdString()); + if ( l_attr_eff_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM ) + { + FAPI_INF("It is a CDIMM"); + } + else + { + FAPI_INF("It is an ISDIMM"); + } + FAPI_INF("num_drops_per_port = %d on %s.", l_attr_eff_num_drops_per_port_u8, i_target.toEcmdString()); + FAPI_INF("num_ranks = %d on %s.", iv_MAX_RANKS,i_target.toEcmdString()); + FAPI_INF("dram_width = %d on %s. \n\n", l_attr_eff_dram_width_u8, i_target.toEcmdString()); + FAPI_INF("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + FAPI_INF("Schmoo\tPOS\tPort\tRank\tByte\tnibble\tbit\tNominal\t\tSetup_Limit\tHold_Limit\tWrD_Setup(ps)\tWrD_Hold(ps)\tEye_Width(ps)\tBitRate "); + + + + for (l_rnk=0;l_rnk<iv_MAX_RANKS;++l_rnk) + {// Byte loop + i_rank=valid_rank[l_rnk]; + rc = mss_getrankpair(i_target,iv_port,i_rank,&l_rp,valid_rank);if(rc) return rc; + for(l_byte=0;l_byte<iv_MAX_BYTES;++l_byte) + { + + //Nibble loop + for(l_nibble=0;l_nibble< MAX_NIBBLES;++l_nibble) + { + for(l_bit=0;l_bit< MAX_BITS;++l_bit) + { + l_dq=8*l_byte+4*l_nibble+l_bit; + + if(iv_shmoo_type==0) + { + FAPI_INF("WR_EYE\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\n ",iv_port,l_mbapos,i_rank,l_byte,l_nibble,l_bit,SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.nom_val[l_dq][l_rp],SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.rb_regval[l_dq][l_rp],SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.lb_regval[l_dq][l_rp],SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.right_margin_val[l_dq][l_rp],SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.left_margin_val[l_dq][l_rp],SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.total_margin[l_dq][l_rp],l_attr_mss_freq_u32); + } + if(iv_shmoo_type==2) + { + FAPI_INF("RD_EYE\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n ",iv_port,l_mbapos,i_rank,l_byte,l_nibble,l_bit,SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.nom_val[l_dq][l_rp],SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.rb_regval[l_dq][l_rp],SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.lb_regval[l_dq][l_rp],SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.right_margin_val[l_dq][l_rp],SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.left_margin_val[l_dq][l_rp],SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.total_margin[l_dq][l_rp],l_attr_mss_freq_u32); + } + + } + } + } + } + + + return rc; + } +#endif +/*------------------------------------------------------------------------------ + * Function: get_margin + * Description : This function is used to get margin for setup,hold and total eye width in Ps by using frequency + * + * Parameters: Target:MBA + * ---------------------------------------------------------------------------*/ +fapi::ReturnCode generic_shmoo::get_margin(const fapi::Target & i_target) +{ + fapi::ReturnCode rc; + uint8_t l_rnk,l_byte,l_nibble,l_bit; + uint32_t l_attr_mss_freq_margin_u32 = 0; + uint32_t l_freq=0; + uint8_t l_dq=0; + uint8_t l_rp=0; + uint8_t i_rank=0; + uint32_t l_factor=0; + + + fapi::Target l_target_centaur; + rc = fapiGetParentChip(i_target, l_target_centaur); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_MSS_FREQ, &l_target_centaur, l_attr_mss_freq_margin_u32); if(rc) return rc; + l_freq=l_attr_mss_freq_margin_u32/2; + l_freq=1000000/l_freq; + l_factor=l_freq/128; + FAPI_INF(" the factor is %d ",l_factor); + + + for (l_rnk=0;l_rnk<iv_MAX_RANKS;++l_rnk) + {// Byte loop + i_rank=valid_rank[l_rnk]; + rc = mss_getrankpair(i_target,iv_port,i_rank,&l_rp,valid_rank);if(rc) return rc; + for(l_byte=0;l_byte<iv_MAX_BYTES;++l_byte) + { + + //Nibble loop + for(l_nibble=0;l_nibble< MAX_NIBBLES;++l_nibble) + { + for(l_bit=0;l_bit< MAX_BITS;++l_bit) + { + l_dq=8*l_byte+4*l_nibble+l_bit; + FAPI_INF(" the right bound = %d and nominal = %d",SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.rb_regval[l_dq][l_rp],SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.nom_val[l_dq][l_rp]); + SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.right_margin_val[l_dq][l_rp]=(SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.rb_regval[l_dq][l_rp]-SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.nom_val[l_dq][l_rp])*l_factor; + SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.left_margin_val[l_dq][l_rp]= (SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.nom_val[l_dq][l_rp]-SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.lb_regval[l_dq][l_rp])*l_factor;//((1/uint32_t_freq*1000000)/128); + SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.total_margin[l_dq][l_rp]=SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.right_margin_val[l_dq][l_rp]+SHMOO[iv_shmoo_type].MBA.P[iv_port].S[i_rank].K.left_margin_val[l_dq][l_rp]; + } + } + } + } + + + return rc; + } + +/*------------------------------------------------------------------------------ + * Function: get_min_margin + * Description : This function is used to get the minimum margin of all the schmoo margins + * + * Parameters: Target:MBA,right minimum margin , left minimum margin, pass fail + * ---------------------------------------------------------------------------*/ +fapi::ReturnCode generic_shmoo::get_min_margin(const fapi::Target & i_target,uint32_t *o_right_min_margin,uint32_t *o_left_min_margin) +{ + fapi::ReturnCode rc; + uint8_t l_rnk,l_byte,l_nibble,l_bit; + uint16_t l_temp_right=4800; + uint16_t l_temp_left=4800; + uint8_t l_dq=0; + uint8_t l_rp=0; + + + + + for (l_rnk=0;l_rnk<iv_MAX_RANKS;++l_rnk) + {// Byte loop + for(l_byte=0;l_byte<iv_MAX_BYTES;++l_byte) + { + + //Nibble loop + for(l_nibble=0;l_nibble< MAX_NIBBLES;++l_nibble) + { + for(l_bit=0;l_bit< MAX_BITS;++l_bit) + { + l_dq=8*l_byte+4*l_nibble+l_bit; + if(SHMOO[iv_shmoo_type].MBA.P[iv_port].S[l_rnk].K.right_margin_val[l_dq][l_rp]<l_temp_right) + { + l_temp_right=SHMOO[iv_shmoo_type].MBA.P[iv_port].S[l_rnk].K.right_margin_val[l_dq][l_rp]; + } + if(SHMOO[iv_shmoo_type].MBA.P[iv_port].S[l_rnk].K.left_margin_val[l_dq][l_rp]<l_temp_left) + { + l_temp_left=SHMOO[iv_shmoo_type].MBA.P[iv_port].S[l_rnk].K.left_margin_val[l_dq][l_rp]; + } + } + } + } + } + + + // hacked for now till schmoo is running + *o_right_min_margin=l_temp_right; + *o_left_min_margin=l_temp_left; + return rc; + } + +}//Extern C diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_generic_shmoo.H b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_generic_shmoo.H new file mode 100644 index 000000000..d21302df8 --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_generic_shmoo.H @@ -0,0 +1,123 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_generic_shmoo.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: mss_generic_shmoo.H,v 1.10 2012/12/14 08:48:13 lapietra Exp $ +// *!*************************************************************************** +// *! (C) Copyright International Business Machines Corp. 1997, 1998 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +// *!*************************************************************************** +// *! FILENAME : mss_generic_shmoo.H +// *! TITLE : MSS Generic Shmoo +// *! DESCRIPTION : Memory Subsystem Generic Shmoo -- abstraction for HB +// *! CONTEXT : To make all shmoos share a common abstraction layer +// *! +// *! OWNER NAME : Varkey Varghese Email: varkey.kv@in.ibm.com +// *! BACKUP NAME : Abhijit Saurabh Email: abhijit.saurabh@in.ibm.com +// *! +// *!*************************************************************************** +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:|Author: | Date: | Comment: +// --------|--------|--------|-------------------------------------------------- +// 1.9 |abhijit |06/12/12|fixed fw review comments +// 1.4 |abhijit |09/27/11|made changes according to new design +// 1.5 |abhijit |10/29/12|made changes after target and returncode +// 1.6 |abhijit |10/29/12|made changes +// 1.7 |abhijit |11/15/12|made changes for fw review comments +//------------------------------------------------------------------------------ +#include <fapi.H> + +#ifndef generic_shmoo_H +#define generic_shmoo_H + +using namespace fapi; +//! Globals +#define SHMOO_DEBUG 0 +#define SHMOO_DEBUG2 0 +#include "mss_shmoo_common.H" +#include "mss_mcbist.H" + + + +//! MSS Generic Shmoo Class.. Inherits from PHY access class and the knob abstraction +class generic_shmoo +{ + private: + + + //! MBS Config : Port + Socket + Knobs + struct SHMOO_SCENARIO{ + struct MBS_CONFIG{ + struct PORT{ + struct RANK{ + shmoo_knob_data_t K; // Set of knobs used by this shmoo + }S[MAX_RANK]; + } P[MAX_PORT]; + }MBA; + shmoo_knob_config_t static_knob; // Static info regarding the knob + }SHMOO[MAX_SHMOO]; // Denote max shmoo scenarios we have + + //! Result Data + + uint8_t convergence_gap; + shmoo_algorithm_t algorithm; + shmoo_mode mcbist_mode; + uint8_t mcbist_error_map[MAX_PORT][MAX_RANK][MAX_BYTE][MAX_NIBBLES]; + uint32_t shmoo_mask; + uint8_t iv_port; + uint8_t iv_MAX_RANKS; + uint8_t iv_MAX_BYTES; + uint8_t iv_pattern; + uint8_t iv_test_type; + uint8_t iv_dmm_type; + uint8_t iv_DQS_ON; + uint8_t iv_shmoo_type; + uint8_t valid_rank[MAX_RANK]; + + + public: + + + + + enum bound_t { LEFT , RIGHT}; + + generic_shmoo(uint8_t iv_port,uint32_t shmoo_mask,shmoo_algorithm_t shmoo_algorithm);// Constructor + generic_shmoo(){}; + ~generic_shmoo(){}; // Destructor + void init_multi_array(uint32_t (&array)[MAX_DQ][MAX_RPS],uint32_t init_val); //initialize multi dim arrays to known value + fapi::ReturnCode init_multi_array_dqs(uint32_t (&array)[MAX_DQ][MAX_RPS],uint32_t init_val); + fapi::ReturnCode get_all_noms(const fapi::Target & i_target); //! Read in all the Nominal values of the relevant knobs + fapi::ReturnCode find_bound(const fapi::Target & i_target,bound_t); // generic Right bound + fapi::ReturnCode knob_update(const fapi::Target & i_target,bound_t bound,uint8_t scenario,uint8_t rank,uint8_t byte,uint8_t nibble,uint8_t bit,uint8_t pass,bool &flag); // Increment or decrement the knob + fapi::ReturnCode knob_update_dqs(const fapi::Target & i_target,bound_t bound,uint8_t scenario,uint8_t rank,uint8_t byte,uint8_t nibble,uint8_t bit,uint8_t pass); + fapi::ReturnCode print_report(const fapi::Target & i_target); // Print Shmoo report to file or STDOUT + fapi::ReturnCode print_shmoo_parms(); + fapi::ReturnCode get_margin(const fapi::Target & i_target); + fapi::ReturnCode get_min_margin(const fapi::Target & i_target,uint32_t *o_right_min_margin,uint32_t *o_left_min_margin); + fapi::ReturnCode do_mcbist_test(const fapi::Target & i_target,uint8_t rank,uint8_t byte,uint8_t nibble,uint8_t &pass); + void check_error_map(uint8_t i_rank,uint8_t i_byte,uint8_t i_nibble,uint8_t &pass); + fapi::ReturnCode sanity_check(const fapi::Target & i_target); + fapi::ReturnCode run(const fapi::Target & i_target,uint32_t *right_min_margin,uint32_t *left_min_margin,uint8_t i_pattern,uint8_t i_test_type); +}; +#endif diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_mcbist.C b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_mcbist.C new file mode 100755 index 000000000..31b462f70 --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_mcbist.C @@ -0,0 +1,547 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_mcbist.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: mss_mcbist.C,v 1.23 2012/12/14 06:30:44 sasethur Exp $ +// *!*************************************************************************** +// *! (C) Copyright International Business Machines Corp. 1997, 1998 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +// *!*************************************************************************** +// *! FILENAME : mss_mcbist.C +// *! TITLE : +// *! DESCRIPTION : MCBIST Procedures +// *! CONTEXT : +// *! +// *! OWNER NAME : Devashikamani, Aditya Email: adityamd@in.ibm.com +// *! BACKUP : Sethuraman, Saravanan Email: saravanans@in.ibm.com +// *!*************************************************************************** +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:|Author: | Date: | Comment: +// --------|--------|--------|-------------------------------------------------- +// 1.22 |aditya |12/14/12|Updated FW review comments +// 1.22 |aditya |12/6/12 | Updated Review Comments +// 1.21 |aditya |11/15/12| Updated for FIRMWARE REVIEW COMMENTS +// 1.20 |aditya |10/29/12| updated fw review comments +// 1.18 |aditya |10/29/12| Updated from ReturnCode to fapi::ReturnCode and Target to const fapi::Target & +// 1.17 |aditya |10/18/12| Replaced insertFromHexRight by SetDoubleWord +// 1.16 |aditya |10/17/12| updated code to be compatible with ecmd 13 release +// 1.15 |aditya |10/01/12| updated fw review comments, datapattern, testtype, addressing +// 1.14 |mwuu |07/17/12| updated dram_width tests to new definition +// 1.13 |bellows |07/16/12| added in Id tag +// 1.10 |gaushard|04/26/12| Added ONE_SHMOO parameter +// 1.9 |gaushard|03/26/12| Updated start_mcbist +// 1.8 |gaushard|03/26/12| Removed Extra Comments/Codes +// 1.7 |gaushard|03/26/12| Added new shmoo modes +// 1.6 |sasethur|03/23/12| Corrected Warning Messages +// 1.5 |sasethur|03/23/12| Corrected Warning messages +// 1.4 |gaushard|03/22/12| Added Address generation +// 1.3 |gaushard|02/29/12| Added rc_num for Buffer operation +// 1.2 |gaushard|02/14/12| Added rc_buff for buffer access +// 1.1 |gaushard|02/13/12| Updated scom addresses +// 1.0 |gaushard|01/19/12| Initial Version +//------------------------------------------------------------------------------ + +//#include "mss_mcbist_common.C" +#include "mss_mcbist.H" +extern "C" +{ +using namespace fapi; + + +//*****************************************************************/ +// Funtion name : cfg_mcb_test_mem +// Description : This function executes different MCBIST subtests +// Input Parameters : +// const fapi::Target & i_target_mba Centaur.mba +// mcbist_test_mem i_test_type Subtest Type +//****************************************************************/ + +fapi::ReturnCode cfg_mcb_test_mem(const fapi::Target & i_target_mba,mcbist_test_mem i_test_type) +{ + fapi::ReturnCode rc; + FAPI_INF("Function - cfg_mcb_test_mem"); + + + + if(i_test_type == CENSHMOO) + { + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,W,0,SF,FIX,0,DEFAULT,PORTA0_SEQ,0); if(rc) return rc; + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,R,0,SF,FIX,1,DEFAULT,PORTA0_SEQ,1); if(rc) return rc; + } + + else if(i_test_type == MEMWRITE) + { + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,W,0,SF,FIX,1,DEFAULT,FIX_ADDR,0); if(rc) return rc; + } + else if(i_test_type == MEMREAD) + { + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,R,0,SF,FIX,1,DEFAULT,FIX_ADDR,0); if(rc) return rc; + } + + else if (i_test_type == SIMPLE_FIX) + { + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,W, 0,SF,FIX, 0,DEFAULT,FIX_ADDR,0); if(rc) return rc; + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,R, 0,SF,FIX, 1,DEFAULT,FIX_ADDR,1); if(rc) return rc; + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,R, 0,SF,FIX, 1,DEFAULT,FIX_ADDR,2); if(rc) return rc; + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,OPER_RAND,0,RF,FIX, 1,DEFAULT,FIX_ADDR,3); if(rc) return rc; + + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR1Q_0x030106a9,RW, 0,RF,RAND,0,DEFAULT,FIX_ADDR,0); if(rc) return rc; + } + else if (i_test_type == SIMPLE_RAND) + { + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,W, 0,SF,RAND,0,DEFAULT,FIX_ADDR,0); if(rc) return rc; + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,R, 0,SF,RAND,1,DEFAULT,FIX_ADDR,1); if(rc) return rc; + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,W, 0,RF,RAND,1,DEFAULT,FIX_ADDR,2); if(rc) return rc; + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,R, 0,RF,RAND,1,DEFAULT,FIX_ADDR,3); if(rc) return rc; + + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR1Q_0x030106a9,RW, 4,RF,RAND,0,DEFAULT,FIX_ADDR,0); if(rc) return rc; + } + + else if (i_test_type == WR_ONLY) + { + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,W, 0,SF,RAND,0,DEFAULT,FIX_ADDR,0); if(rc) return rc; + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,R, 0,SF,RAND,1,DEFAULT,FIX_ADDR,1); if(rc) return rc; + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,W, 0,RF,FIX,0,DEFAULT,FIX_ADDR,2); if(rc) return rc; + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,OPER_RAND,0,RF,FIX,1,DEFAULT,FIX_ADDR,3); if(rc) return rc; + + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR1Q_0x030106a9,RW, 4,RF,RAND,0,DEFAULT,FIX_ADDR,0); if(rc) return rc; + } + else if (i_test_type == W_ONLY) + { + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,W, 0,SF,RAND,1,DEFAULT,FIX_ADDR,0); if(rc) return rc; + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,R, 0,SF,FIX, 1,DEFAULT,FIX_ADDR,1); if(rc) return rc; + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,W, 0,RF,FIX, 0,DEFAULT,FIX_ADDR,2); if(rc) return rc; + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,OPER_RAND,0,RF,FIX, 1,DEFAULT,FIX_ADDR,3); if(rc) return rc; + + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR1Q_0x030106a9,RW, 4,RF,RAND,0,DEFAULT,FIX_ADDR,0); if(rc) return rc; + } + else if (i_test_type == R_ONLY) + { + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,R, 0,SF,RAND,1,DEFAULT,FIX_ADDR,0); if(rc) return rc; + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,W, 0,RF,FIX, 0,DEFAULT,FIX_ADDR,2); if(rc) return rc; + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR0Q_0x030106a8,OPER_RAND,0,RF,FIX, 1,DEFAULT,FIX_ADDR,3); if(rc) return rc; + + rc = mcb_write_test_mem(i_target_mba,MBA01_MCBIST_MCBMR1Q_0x030106a9,RW, 4,RF,RAND,0,DEFAULT,FIX_ADDR,0); if(rc) return rc; + } + + else + { + + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + FAPI_ERR("Invalid MCBIST test type! cfg_mcb_test_mem Function "); + return rc; + } + + return rc; +} + + + + + +//*****************************************************************/ +// Funtion name : cfg_mcb_dgen +// Description : This function writes data patterns based on i_datamode passed +// Input Parameters : +// const fapi::Target & i_target_mba Centaur.mba +// mcbist_data_gen i_datamode MCBIST Data mode +// uint8_t i_mcbrotate Provides the number of bit to shift per burst +//****************************************************************/ +fapi::ReturnCode cfg_mcb_dgen(const fapi::Target & i_target_mba,mcbist_data_gen i_datamode,uint8_t i_mcbrotate) +{ + ecmdDataBufferBase l_data_buffer_64(64); + ecmdDataBufferBase l_var_data_buffer_64(64); + ecmdDataBufferBase l_var1_data_buffer_64(64); + ecmdDataBufferBase l_spare_data_buffer_64(64); + ecmdDataBufferBase l_data_buffer_32(32); + ecmdDataBufferBase l_data_buffer_16(16); + ecmdDataBufferBase l_data_buffer_4(4); + ecmdDataBufferBase l_data_buffer1_4(4); + uint64_t l_var = 0x0000000000000000ull; + uint64_t l_var1 = 0x0000000000000000ull; + uint64_t l_spare = 0x0000000000000000ull; + //uint64_t l_data = 0x0000000000000000ull; + uint8_t l_rotnum = 0; + uint32_t l_mba01_mcb_pseudo_random[NINE] = { MBA01_MCBIST_MCBFD0Q_0x030106be,MBA01_MCBIST_MCBFD1Q_0x030106bf,MBA01_MCBIST_MCBFD2Q_0x030106c0,MBA01_MCBIST_MCBFD3Q_0x030106c1,MBA01_MCBIST_MCBFD4Q_0x030106c2, MBA01_MCBIST_MCBFD5Q_0x030106c3,MBA01_MCBIST_MCBFD6Q_0x030106c4,MBA01_MCBIST_MCBFD7Q_0x030106c5,MBA01_MCBIST_MCBFDQ_0x030106c6}; + uint32_t l_mba01_mcb_random[MAX_BYTE] = {MBA01_MCBIST_MCBRDS0Q_0x030106b2,MBA01_MCBIST_MCBRDS1Q_0x030106b3,MBA01_MCBIST_MCBRDS2Q_0x030106b4,MBA01_MCBIST_MCBRDS3Q_0x030106b5,MBA01_MCBIST_MCBRDS4Q_0x030106b6,MBA01_MCBIST_MCBRDS5Q_0x030106b7,MBA01_MCBIST_MCBRDS6Q_0x030106b8,MBA01_MCBIST_MCBRDS7Q_0x030106b9,MBA01_MCBIST_MCBRDS8Q_0x030106ba,MBA01_MCBIST_MCBDRSRQ_0x030106bc}; + uint8_t l_index,l_index1 = 0; + uint32_t l_rand_32 = 0; + + uint32_t l_rand_8 = 0; + + fapi::ReturnCode rc; + uint32_t rc_num = 0; + FAPI_INF(" Data mode is %d ",i_datamode); + uint8_t l_mbaPosition =0; + + FAPI_INF("Function cfg_mcb_dgen"); + //Read MBA position attribute 0 - MBA01 1 - MBA23 + rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_target_mba, l_mbaPosition); + if(rc) + { + FAPI_ERR("Error getting MBA position"); return rc; + } + + + /*if ((l_mbaPosition != 0)||(l_mbaPosition != 1)) + { + return rc; + } */ + + + + if(i_datamode == MCBIST_2D_CUP_PAT5) + { + l_var = 0xFFFF0000FFFF0000ull; + l_var1 =0x0000FFFF0000FFFFull; + l_spare = 0xFF00FF00FF00FF00ull; + + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var);if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;} rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD0Q_0x030106be, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD1Q_0x030106bf, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD2Q_0x030106c0, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD3Q_0x030106c1, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD4Q_0x030106c2, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD5Q_0x030106c3, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD6Q_0x030106c4, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD7Q_0x030106c5, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFDQ_0x030106c6 , l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFDSPQ_0x030106c7 , l_data_buffer_64); if(rc) return rc; + + + + + + + + + } + + + + else if(i_datamode == MCBIST_2D_CUP_PAT8) + { + l_var = 0xFFFFFFFFFFFFFFFFull; + l_var1 =0x0000000000000000ull; + l_spare = 0xFFFF0000FFFF0000ull; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD0Q_0x030106be, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD1Q_0x030106bf, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD2Q_0x030106c0, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD3Q_0x030106c1, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD4Q_0x030106c2, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD5Q_0x030106c3, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD6Q_0x030106c4, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD7Q_0x030106c5, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFDQ_0x030106c6 , l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFDSPQ_0x030106c7 , l_data_buffer_64); if(rc) return rc; + + + } + else if(i_datamode == ABLE_FIVE) + { + + l_var = 0xA5A5A5A5A5A5A5A5ull; + l_var1 =0x5A5A5A5A5A5A5A5Aull; + l_spare = 0xA55AA55AA55AA55Aull; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD0Q_0x030106be, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD1Q_0x030106bf, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD2Q_0x030106c0, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD3Q_0x030106c1, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD4Q_0x030106c2, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD5Q_0x030106c3, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD6Q_0x030106c4, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD7Q_0x030106c5, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFDQ_0x030106c6 , l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFDSPQ_0x030106c7 , l_data_buffer_64); if(rc) return rc; + + } + else if((i_datamode == DATA_GEN_DELTA_I) || (i_datamode == MCBIST_2D_CUP_PAT0)) + { + + + l_var = 0xFFFFFFFFFFFFFFFFull; + l_var1 =0x0000000000000000ull; + l_spare = 0xFF00FF00FF00FF00ull; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD0Q_0x030106be, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD1Q_0x030106bf, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD2Q_0x030106c0, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD3Q_0x030106c1, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD4Q_0x030106c2, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD5Q_0x030106c3, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD6Q_0x030106c4, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFD7Q_0x030106c5, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFDQ_0x030106c6 , l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBFDSPQ_0x030106c7 , l_data_buffer_64); if(rc) return rc; + + } + + else if(i_datamode == PSEUDORANDOM) + { + // srand(2); + FAPI_INF("Need to check the value of RAND_MAX for this compiler -- assuming 32bit of data is returned"); + for (l_index = 0; l_index< (MAX_BYTE-1) ; l_index++) + { + //l_rand_32 = rand(); + l_rand_32 = 0xFFFFFFFF;//Hard Coded Temporary Fix till random function is fixed + rc_num = l_data_buffer_32.insertFromRight(l_rand_32,0,32); + rc_num = l_data_buffer_64.insert(l_data_buffer_32,0,32,0); + //l_rand_32 = rand(); + l_rand_32 = 0xFFFFFFFF; + rc_num = l_data_buffer_32.insertFromRight(l_rand_32,0,32); + rc_num = l_data_buffer_64.insert(l_data_buffer_32,32,32,0); + if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, l_mba01_mcb_pseudo_random[l_index] , l_data_buffer_64); if(rc) return rc; + } + } + else + { + FAPI_ERR("Data generation configuration mcbist_data_gen enum : %d does not exist for centaur printPosData(i_target_mba)",(int)i_datamode); + + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + return rc; + } + + fapi::Target i_target_centaur ; + rc = fapiGetParentChip(i_target_mba, i_target_centaur); + if (rc) + { + FAPI_INF("Error in getting parent chip!"); return rc; + } + + if(i_datamode == MCBIST_2D_CUP_PAT5) + { + l_var = 0xFFFF0000FFFF0000ull; + l_var1 =0x0000FFFF0000FFFFull; + l_spare = 0xFF00FF00FF00FF00ull; + if (l_mbaPosition == 0) + { + //Writing MBS 01 pattern registers for comparison mode + + + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD0Q_0x02011681, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD1Q_0x02011682, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD2Q_0x02011683, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD3Q_0x02011684, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD4Q_0x02011685, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD5Q_0x02011686, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD6Q_0x02011687, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD7Q_0x02011688, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare);if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFDQ_0x02011689, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare);if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFDSPQ_0x0201168A,l_data_buffer_64); if(rc) return rc; + + } + else if (l_mbaPosition == 1) + { + //Writing MBS 23 pattern registers for comparison mode + + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD0Q_0x02011781, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD1Q_0x02011782, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD2Q_0x02011783, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD3Q_0x02011784, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD4Q_0x02011785, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD5Q_0x02011786, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD6Q_0x02011787, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD7Q_0x02011788, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare);if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFDQ_0x02011789, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFDSPQ_0x0201178A,l_data_buffer_64); if(rc) return rc; + + } + } + else if(i_datamode == MCBIST_2D_CUP_PAT8) + { + l_var = 0xFFFFFFFFFFFFFFFFull; + l_var1 =0x0000000000000000ull; + l_spare = 0xFFFF0000FFFF0000ull; + if (l_mbaPosition == 0) + { + //Writing MBS 01 pattern registers for comparison mod + + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD0Q_0x02011681, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD1Q_0x02011682, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD2Q_0x02011683, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD3Q_0x02011684, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD4Q_0x02011685, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD5Q_0x02011686, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD6Q_0x02011687, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD7Q_0x02011688, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFDQ_0x02011689, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFDSPQ_0x0201168A,l_data_buffer_64); if(rc) return rc; + } + else if (l_mbaPosition == 1) + { + //Writing MBS 23 pattern registers for comparison mod + + + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD0Q_0x02011781, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD1Q_0x02011782, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD2Q_0x02011783, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD3Q_0x02011784, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD4Q_0x02011785, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD5Q_0x02011786, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD6Q_0x02011787, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD7Q_0x02011788, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFDQ_0x02011789, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFDSPQ_0x0201178A,l_data_buffer_64); if(rc) return rc; + + + } + } + else if(i_datamode == ABLE_FIVE) + { + l_var = 0xA5A5A5A5A5A5A5A5ull; + l_var1 =0x5A5A5A5A5A5A5A5Aull; + l_spare = 0xA55AA55AA55AA55Aull; + + if (l_mbaPosition == 0) + { + //Writing MBS 01 pattern registers for comparison mod + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST01_MBS_MCBFD0Q_0x02011681, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST01_MBS_MCBFD1Q_0x02011682, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST01_MBS_MCBFD2Q_0x02011683, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST01_MBS_MCBFD3Q_0x02011684, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST01_MBS_MCBFD4Q_0x02011685, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST01_MBS_MCBFD5Q_0x02011686, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST01_MBS_MCBFD6Q_0x02011687, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST01_MBS_MCBFD7Q_0x02011688, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare);if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST01_MBS_MCBFDQ_0x02011689, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba,MBS_MCBIST01_MBS_MCBFDSPQ_0x0201168A, l_data_buffer_64); if(rc) return rc; + } + else if (l_mbaPosition == 1) + { + //Writing MBS 23 pattern registers for comparison mod + + + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST23_MBS_MCBFD0Q_0x02011781, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST23_MBS_MCBFD1Q_0x02011782, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST23_MBS_MCBFD2Q_0x02011783, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST23_MBS_MCBFD3Q_0x02011784, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST23_MBS_MCBFD4Q_0x02011785, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST23_MBS_MCBFD5Q_0x02011786, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST23_MBS_MCBFD6Q_0x02011787, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST23_MBS_MCBFD7Q_0x02011788, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare);if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST23_MBS_MCBFDQ_0x02011789, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_mba, MBS_MCBIST23_MBS_MCBFDSPQ_0x0201178A,l_data_buffer_64); if(rc) return rc; + + } + } + else if((i_datamode == DATA_GEN_DELTA_I) || (i_datamode == MCBIST_2D_CUP_PAT0)) + { + + l_var = 0xFFFFFFFFFFFFFFFFull; + l_var1 =0x0000000000000000ull; + l_spare = 0xFF00FF00FF00FF00ull; + if (l_mbaPosition == 0) + { + //Writing MBS 01 pattern registers for comparison mod + + + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD0Q_0x02011681, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD1Q_0x02011682, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD2Q_0x02011683, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD3Q_0x02011684, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD4Q_0x02011685, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD5Q_0x02011686, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD6Q_0x02011687, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFD7Q_0x02011688, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFDQ_0x02011689, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST01_MBS_MCBFDSPQ_0x0201168A,l_data_buffer_64); if(rc) return rc; + + + } + else if (l_mbaPosition == 1) + { + //Writing MBS 23 pattern registers for comparison mod + + + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD0Q_0x02011781, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD1Q_0x02011782, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD2Q_0x02011783, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD3Q_0x02011784, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD4Q_0x02011785, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD5Q_0x02011786, l_data_buffer_64); if(rc) return rc; + rc_num = l_var_data_buffer_64.setDoubleWord(0,l_var); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD6Q_0x02011787, l_data_buffer_64); if(rc) return rc; + rc_num = l_var1_data_buffer_64.setDoubleWord(0,l_var1); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFD7Q_0x02011788, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFDQ_0x02011789, l_data_buffer_64); if(rc) return rc; + rc_num = l_spare_data_buffer_64.setDoubleWord(0,l_spare); if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;}rc = fapiPutScom(i_target_centaur, MBS_MCBIST23_MBS_MCBFDSPQ_0x0201178A,l_data_buffer_64); if(rc) return rc; + + } + } + + + else + { + FAPI_ERR("Data generation configuration mcbist_data_gen enum : %d does not exist for centaur printPosData(i_target_mba)",(int)i_datamode); + + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + return rc; + } + for(l_index = 0; l_index<MAX_BYTE ;l_index ++) + { + + for(l_index1 = 0; l_index1 < 8; l_index1++) + { + //l_rand_8 = rand(); + l_rand_8 = 0xFF; + rc_num = l_data_buffer_64.insert(l_rand_8,8*l_index1,8,24);if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;} // Source start in sn is given as 24 -- need to ask + } + rc = fapiPutScom(i_target_mba, l_mba01_mcb_random[l_index] , l_data_buffer_64); if(rc) return rc; + } + + // rc = print_pattern(i_target_mba);if(rc)return rc; + + + + + + + if(i_mcbrotate == 0) + { + FAPI_INF("i_mcbrotate == 0 , the l_rotnum is set to 13"); + l_rotnum = 13; // for random data generation - basic setup + } + else + { + l_rotnum = i_mcbrotate; + } + + rc_num = rc_num| l_data_buffer_4.insert(l_rotnum,0,4,0); + rc_num = rc_num| l_data_buffer_64.insert(l_data_buffer_4,0,4,0); + if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;} + // rc_num = l_data_buffer_4.insert(l_rotnum,0,4,0);if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;} + + rc_num = rc_num| l_data_buffer_16.insert(l_data_buffer1_4,0,4); + rc_num = rc_num| l_data_buffer_16.insert(l_data_buffer1_4,4,4); + rc_num = rc_num| l_data_buffer_16.insert(l_data_buffer1_4,8,4); + rc_num = rc_num|l_data_buffer_16.insert(l_data_buffer1_4,12,4); + + + + rc_num = rc_num| l_data_buffer_64.insert(l_data_buffer_16,4,16,0); + + FAPI_INF("Clearing bit 20 of MBA01_MCBIST_MCBDRCRQ_0x030106bd to avoid inversion of data to the write data flow"); + rc_num = rc_num|l_data_buffer_64.clearBit(20); + + if (rc_num){ FAPI_ERR( "cfg_mcb_dgen:");rc.setEcmdError(rc_num);return rc;} + rc = fapiPutScom(i_target_mba,MBA01_MCBIST_MCBDRCRQ_0x030106bd,l_data_buffer_64); if(rc) return rc; + + return rc; + } +} diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_mcbist.H b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_mcbist.H new file mode 100755 index 000000000..85d8d4824 --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_mcbist.H @@ -0,0 +1,262 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_mcbist.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: mss_mcbist.H,v 1.17 2012/12/14 06:31:11 sasethur Exp $ +// *!*************************************************************************** +// *! (C) Copyright International Business Machines Corp. 1997, 1998 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +// *!*************************************************************************** +// *! FILENAME : mss_mcbist.H +// *! TITLE : +// *! DESCRIPTION : MCBIST procedures +// *! CONTEXT : +// *! +// *! OWNER NAME : Devashikamani, Aditya Email: adityamd@in.ibm.com +// *! BACKUP : Sethuraman, Saravanan Email: saravanans@in.ibm.com +// *!*************************************************************************** +// CHANGE HISTORY: +//------------------------------------------------------------------------------- +// Version:|Author: | Date: | Comment: +// --------|--------|---------|-------------------------------------------------- +// 1.17 |aditya |12/14/12 |Updated FW review comments +// 1.16 |aditya |12/6/12 | Updated Review Comments +// 1.15 |aditya |11/15/12 | Updated for FW REVIEW COMMENTS +// 1.13 |aditya |10/29/12 | Updated from ReturnCode to fapi::ReturnCode and Target to const fapi::Target & +// 1.12 |aditya |10/18/12 | Changed Parameters for Function mcb_write_test_mem +// 1.11 |aditya |10/17/12 | updated code to be compatible with ecmd 13 release +// 1.10 |aditya |15-Oct-12| Moved scom address to cen_scom_addresses.H, added user option +// 1.9 |bellows |16-Jul-12| Added in Id tag +// 1.6 |gaushard|26/03/12 | Removed Extra Comments/Codes +// 1.5 |gaushard|26/03/12 | Updated Function Declaration +// 1.4 |sasethur|23/03/12 | Added enum for shmoo mode +// 1.3 |gaushard|22/03/12 | Added address generation function +// 1.2 |sasethur|24/02/12 | Updated Typo +// 1.1 |gaushard|14/02/12 | Shifted register address from .C file to .H file +// 1.0 |gaushard|12/01/12 | Initial version +//------------------------------------------------------------------------------ +#ifndef MSS_MCBIST_H +#define MSS_MCBIST_H +/****************************************************************************************/ +/* mss_mcbist.H */ +/****************************************************************************************/ +#include <fapi.H> +#include <cen_scom_addresses.H> +#include <mss_access_delay_reg.H> +#include <mss_shmoo_common.H> +extern "C" +{ +using namespace fapi; + +//############### Global variables ################ +/*const uint8_t MAX_PORT = 2; +const uint8_t MAX_BYTE = 10; +const uint8_t MAX_RANK = 8; +const uint8_t MAX_NIBBLE = 1;*/ + +enum mcbist_test_mem +{ + USER_MODE, + CENSHMOO, + SUREFAIL, + MEMWRITE, + MEMREAD, + CBR_REFRESH, + MCBIST_SHORT, + SHORT_SEQ, + DELTA_I, + DELTA_I_LOOP, + SHORT_RAND, + LONG1, + BUS_TAT, + SIMPLE_FIX, + SIMPLE_RAND, + SIMPLE_RAND_2W, + SIMPLE_RAND_FIXD, + SIMPLE_RA_RD_WR, + SIMPLE_RA_RD_R, + SIMPLE_RA_FD_R, + SIMPLE_RA_FD_R_INF, + SIMPLE_SA_FD_R, + SIMPLE_RA_FD_W, + INFINITE, + WR_ONLY, + W_ONLY, + R_ONLY, + W_ONLY_RAND, + R_ONLY_RAND, + R_ONLY_MULTI +}; + +enum mcbist_data_gen +{ + ABLE_FIVE, + USR_MODE, + ONEHOT, + DQ0_00011111_RESTALLONE, + DQ0_11100000_RESTALLZERO, + ALLZERO, + ALLONE, + BYTE_BURST_SIGNATURE, + BYTE_BURST_SIGNATURE_V1, + BYTE_BURST_SIGNATURE_V2, + BYTE_BURST_SIGNATURE_V3, + DATA_GEN_DELTA_I, + MCBIST_2D_CUP_PAT0, + MPR, + MPR03, + MPR25, + MPR47, + DELTA_I1, + MCBIST_2D_CUP_PAT1, + MHC_55, + MHC_DQ_SIM, + MCBIST_2D_CUP_PAT2, + MCBIST_2D_CUP_PAT3, + MCBIST_2D_CUP_PAT4, + MCBIST_2D_CUP_PAT5, + MCBIST_2D_CUP_PAT6, + MCBIST_2D_CUP_PAT7, + MCBIST_2D_CUP_PAT8, + MCBIST_2D_CUP_PAT9, + CWLPATTERN, + GREY1, + DC_ONECHANGE, + DC_ONECHANGEDIAG, + GREY2, + FIRST_XFER, + MCBIST_222_XFER, + MCBIST_333_XFER, + MCBIST_444_XFER, + MCBIST_555_XFER, + MCBIST_666_XFER, + MCBIST_777_XFER, + MCBIST_888_XFER, + FIRST_XFER_X4MODE, + MCBIST_LONG, + PSEUDORANDOM +}; + +enum mcbist_oper_type +{ + W, + R, + RW, + WR, + RWR, + RWW, + OPER_RAND, + GOTO +}; + +enum mcbist_data_mode +{ + FIX, + DATA_RF, + DATA_RR, + RECCF, + RECCB, + DEA, + DRL, + DRR, + RAND +}; + +enum mcbist_addr_mode +{ + SF, + SR, + RF, + RR +}; + +enum mcbist_add_select_mode +{ + FIX_ADDR, + PORTA0_RANDOM, + PORTA1_RANDOM, + PORTA0_SEQ +}; + +enum mcbist_data_select_mode +{ + DEFAULT, + BURST0, + BURST1, + BURST2 +}; + +enum mcbist_byte_mask +{ + BYTE0, + BYTE1, + BYTE2, + BYTE3, + BYTE4, + BYTE5, + BYTE6, + BYTE7, + BYTE8, + BYTE9, + UNMASK_ALL, + NONE +}; + +enum shmoo_mode +{ + FAST = 0, + ONE_SLOW = 1, + QUARTER_SLOW = 2, + HALF_SLOW = 3, + FULL_SLOW = 4, + ONE_CHAR = 5, + QUARTER_CHAR = 6, + HALF_CHAR = 7, + FULL_CHAR = 8 +}; + +enum shmoo_addr_mode +{ + FEW_ADDR= 0, + QUARTER_ADDR = 1, + HALF_ADDR = 2, + FULL_ADDR = 3 +}; + + + + + +fapi::ReturnCode addr_gen_func(const fapi::Target & i_target_mba, mcbist_addr_mode i_addr_mode, uint8_t i_attr_eff_schmoo_addr_mode, uint64_t &io_end_address, uint64_t &io_start_address,uint8_t i_rank,uint8_t i_port); +fapi::ReturnCode poll_mcb(const fapi::Target & i_target_mba,bool i_mcb_stop_on_fail,uint8_t *o_mcb_status); +fapi::ReturnCode mcb_error_map(const fapi::Target & i_target_mba,uint8_t o_error_map[][8][10][2],uint8_t i_port,uint8_t i_rank); +fapi::ReturnCode mcb_write_test_mem(const fapi::Target & i_target_mba,const uint64_t i_reg_addr,mcbist_oper_type i_operation_type,uint8_t i_cfg_test_123_cmd,mcbist_addr_mode i_addr_mode,mcbist_data_mode i_data_mode,uint8_t i_done,mcbist_data_select_mode i_data_select_mode, mcbist_add_select_mode i_addr_select_mode,uint8_t i_testnumber); +fapi::ReturnCode cfg_mcb_test_mem(const fapi::Target & i_target_mba,mcbist_test_mem i_test_type); +fapi::ReturnCode mcb_reset_trap(const fapi::Target & i_target_mba); +fapi::ReturnCode cfg_mcb_dgen(const fapi::Target & i_target_mba,mcbist_data_gen i_datamode,uint8_t i_mcbrotate); +fapi::ReturnCode cfg_byte_mask(const fapi::Target & i_target_mba,uint8_t i_rank,uint8_t i_port); +fapi::ReturnCode start_mcb(const fapi::Target & i_target_mba); +fapi::ReturnCode setup_mcbist(const fapi::Target & i_target_mba, uint8_t i_port,mcbist_data_gen i_mcbpatt,mcbist_test_mem i_mcbtest,mcbist_byte_mask i_mcbbytemask,uint8_t i_mcbrotate,uint8_t i_pattern,uint8_t i_test_type,uint8_t i_rank); +fapi::ReturnCode cfg_mcb_addr(const fapi::Target & i_target_mba,uint8_t i_rank,uint8_t i_port); +fapi::ReturnCode mcb_error_map_print(const fapi::Target & i_target_mba,uint8_t i_port,uint8_t i_rank,ecmdDataBufferBase & l_mcb_fail_320); +} +#endif diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_mcbist_common.C b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_mcbist_common.C new file mode 100644 index 000000000..c472c1111 --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_mcbist_common.C @@ -0,0 +1,1115 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_mcbist_common.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: mss_mcbist_common.C,v 1.10 2012/12/14 16:09:38 sasethur Exp $ +// *!*************************************************************************** +// *! (C) Copyright International Business Machines Corp. 1997, 1998 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +// *!*************************************************************************** +// *! FILENAME : mss_mcbist_common.C +// *! TITLE : +// *! DESCRIPTION : MCBIST Procedures +// *! CONTEXT : +// *! +// *! OWNER NAME : Devashikamani, Aditya Email: adityamd@in.ibm.com +// *! BACKUP : Sethuraman, Saravanan Email: saravanans@in.ibm.com +// *!*************************************************************************** +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:|Author: | Date: | Comment: +// --------|--------|--------|-------------------------------------------------- +// 1.10 |sasethur|12/14/12| Updated for warnings +// 1.9 |aditya |12/14/12| Updated FW review comments +// 1.8 |aditya |12/6/12 | Updated Review Comments +// 1.7 |aditya |11/15/12| Updated for FW REVIEW COMMENTS +// 1.6 |aditya |10/31/12| Fixed issue in mcb_error_map function +// 1.5 |abhijit |10/29/12| fixed issue in byte mask function +// 1.4 |aditya |10/29/12| Updated from ReturnCode to fapi::ReturnCode and Target to const fapi::Target & +// 1.3 |aditya |10/18/12| Replaced insertFromBin by InsertFromRight +// 1.2 |aditya |10/17/12| updated code to be compatible with ecmd 13 release +// 1.1 |aditya |10/01/12| updated fw review comments, datapattern, testtype, addressing +// +// +//This File mss_mcbist_common.C contains the definition of common procedures for the files mss_mcbist.C and mss_mcbist_lab.C +//------------------------------------------------------------------------------ +#include "mss_mcbist.H" +#include <mss_access_delay_reg.H> +#include <fapiTestHwpDq.H> +#include <dimmBadDqBitmapFuncs.H> + +extern "C" +{ +using namespace fapi; + +#define MCB_DEBUG +#define MCB_DEBUG1 +#define MCB_DEBUG2 + + +//const uint8_t MAX_PORT = 2; +const uint8_t MAX_DRAM = 20; + +//const uint8_t MAX_BYTE = 10; +//const uint8_t MAX_RANK = 8; +//const uint8_t MAX_NIBBLE = 1; +const uint8_t MCB_TEST_NUM = 16; +const uint8_t MCB_MAX_TIMEOUT = 100; +const uint64_t DELAY_100US = 100000; // general purpose 100 usec delay for HW mode (2000000 sim cycles if simclk = 20ghz) +const uint64_t DELAY_2000SIMCYCLES = 2000; // general purpose 2000 sim cycle delay for sim mode (100 ns if simclk = 20Ghz) +//const uint64_t END_ADDRESS = 0x0000000004; //Will be fixed later, once the address generation function is ready +// const uint64_t START_ADDRESS = 0x0000000001; +//const uint64_t FEW_INTERVAL = 0x0000000003; + +const uint64_t END_ADDRESS = 0x0000000010000000ull; //Will be fixed later, once the address generation function is ready + const uint64_t START_ADDRESS = 0x0000000004000000ull; +const uint64_t FEW_INTERVAL = 0x000000000C000000ull; +const uint64_t FOUR = 0x0000000000000004ull; + + +//*****************************************************************/ +// Funtion name : setup_mcbist +// Description : Will setup the required MCBIST configuration register +// Input Parameters : +// const fapi::Target & Centaur.mba +// uint8_t i_port Port on which we are operating. + +// mcbist_data_gen i_mcbpatt Data pattern +// mcbist_test_mem i_mcbtest subtest Type +// mcbist_byte_mask i_mcbbytemask It is used to mask bad bits read from SPD +// uint8_t i_mcbrotate Provides the number of bit to shift per burst + +// uint8_t i_pattern Data Pattern +// uint8_t i_test_type Subtest Type +// uint8_t i_rank Current Rank +//****************************************************************/ + + +fapi::ReturnCode setup_mcbist(const fapi::Target & i_target_mba, uint8_t i_port,mcbist_data_gen i_mcbpatt,mcbist_test_mem i_mcbtest,mcbist_byte_mask i_mcbbytemask,uint8_t i_mcbrotate,uint8_t i_pattern,uint8_t i_test_type,uint8_t i_rank) +{ + + fapi::ReturnCode rc; + uint32_t rc_num = 0; + FAPI_INF("Function Setup_MCBIST"); + ecmdDataBufferBase l_data_buffer_64(64); + ecmdDataBufferBase l_data_bufferx1_64(64); + ecmdDataBufferBase l_data_bufferx2_64(64); + ecmdDataBufferBase l_data_bufferx3_64(64); + ecmdDataBufferBase l_data_bufferx4_64(64); + //ecmdDataBufferBase l_data_buffer_64_1(64); + + + rc = mcb_reset_trap(i_target_mba); + if(rc) return rc; +/* + rc = fapiGetScom(i_target_mba, MBA01_MCBIST_MCBMR0Q_0x030106a8,l_data_buffer_64); if(rc) return rc; + rc_num = rc_num | l_data_buffer_64.flushTo0(); + rc_num = rc_num | l_data_buffer_64.setBit(18); + rc_num = rc_num | l_data_buffer_64.setBit(27); + rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBMR0Q_0x030106a8, l_data_buffer_64); if(rc) return rc; + + rc = fapiGetScom(i_target_mba, MBA01_MCBIST_MCBSEARA0Q_0x030106d2,l_data_buffer_64);if(rc) return rc; + rc_num = rc_num | l_data_buffer_64.setBit(36); + rc_num = rc_num | l_data_buffer_64.setBit(37); + rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBSEARA0Q_0x030106d2,l_data_buffer_64); if(rc) return rc; + + rc = fapiGetScom(i_target_mba, MBA01_MCBIST_MCBSSARA0Q_0x030106d0,l_data_buffer_64); if(rc) return rc; + rc_num = rc_num | l_data_buffer_64.flushTo0(); + rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBSSARA0Q_0x030106d0,l_data_buffer_64); if(rc) return rc; + + rc = fapiGetScom(i_target_mba, MBA01_MCBIST_MCBAGRAQ_0x030106d6,l_data_buffer_64); if(rc) return rc; + rc_num = rc_num | l_data_buffer_64.setBit(24); + rc_num = rc_num | l_data_buffer_64.clearBit(25); + rc = fapiPutScom(i_target_mba, MBA01_MCBIST_MCBAGRAQ_0x030106d6, l_data_buffer_64); if(rc) return rc; + */ + rc = fapiGetScom(i_target_mba,MBA01_CCS_MODEQ_0x030106a7, l_data_buffer_64); if(rc) return rc; + rc_num = l_data_buffer_64.clearBit(29); if (rc_num){FAPI_ERR( "Error in function setup_mcb:");rc.setEcmdError(rc_num);return rc;} + + rc = fapiPutScom(i_target_mba,MBA01_CCS_MODEQ_0x030106a7, l_data_buffer_64); if(rc) return rc; + //rc = print_pattern(i_target_mba);if(rc)return rc; + if((i_test_type == 1) && (i_pattern == 1)) + { + FAPI_INF("User pattern and User test_type modes enabled"); + rc = cfg_mcb_dgen(i_target_mba,USR_MODE,i_mcbrotate); if(rc) return rc; + FAPI_INF("Inside setup mcbist Entering cfg_mcb_addr"); + //rc = cfg_mcb_addr(i_target_mba,i_rank,i_port);if(rc) return rc; + rc = cfg_mcb_test_mem(i_target_mba,USER_MODE); if(rc) return rc; + } + else if(i_pattern == 1) + { + FAPI_INF("User pattern mode enabled"); + rc = cfg_mcb_dgen(i_target_mba,USR_MODE,i_mcbrotate); if(rc) return rc; + FAPI_INF("Inside setup mcbist Entering cfg_mcb_addr"); + //rc = cfg_mcb_addr(i_target_mba,i_rank,i_port);if(rc) return rc; + rc = cfg_mcb_test_mem(i_target_mba,i_mcbtest); if(rc) return rc; + } + else if(i_test_type == 1) + { + FAPI_INF(" User test_type mode enabled"); + rc = cfg_mcb_dgen(i_target_mba,i_mcbpatt,i_mcbrotate); if(rc) return rc; + FAPI_INF("Inside setup mcbist Entering cfg_mcb_addr"); + //rc = cfg_mcb_addr(i_target_mba,i_rank,i_port);if(rc) return rc; + rc = cfg_mcb_test_mem(i_target_mba,USER_MODE); if(rc) return rc; + } + else + { + rc = cfg_mcb_dgen(i_target_mba,i_mcbpatt,i_mcbrotate); if(rc) return rc; + FAPI_INF("Inside setup mcbist Entering cfg_mcb_addr"); + //rc = cfg_mcb_addr(i_target_mba,i_rank,i_port);if(rc) return rc; + rc = cfg_mcb_test_mem(i_target_mba,i_mcbtest); if(rc) return rc; + } + + if(i_mcbbytemask != NONE) + { + rc = cfg_byte_mask(i_target_mba,i_rank,i_port); if(rc) return rc; + + } + + + return rc; +} + +//*****************************************************************/ +// Funtion name : mcb_reset_trap +// Description: Clears all the trap registers in MCBIST engine +//Input Parameters : +// const fapi::Target & centaur.mba +//*****************************************************************/ + +fapi::ReturnCode mcb_reset_trap(const fapi::Target & i_target_mba) +{ + ecmdDataBufferBase l_data_buffer_64(64); + fapi::ReturnCode rc; + uint32_t rc_num = 0; + + + FAPI_INF("Function - mcb_reset_trap"); + FAPI_INF("Using MCB Reset Trap Function -- This automatically resets error log RA, error counters, Status Reg and error map"); + + rc = fapiGetScom(i_target_mba,MBA01_MCBIST_MCBCFGQ_0x030106e0,l_data_buffer_64);if(rc) return rc; + rc_num = l_data_buffer_64.clearBit(60);if (rc_num){FAPI_ERR( "Error in function mcb_reset_trap:");rc.setEcmdError(rc_num);return rc;} + rc = fapiPutScom(i_target_mba,MBA01_MCBIST_MCBCFGQ_0x030106e0,l_data_buffer_64);if(rc) return rc; + rc_num = l_data_buffer_64.setBit(60);if (rc_num){FAPI_ERR( "Error in function mcb_reset_trap:");rc.setEcmdError(rc_num);return rc;} + rc = fapiPutScom(i_target_mba,MBA01_MCBIST_MCBCFGQ_0x030106e0,l_data_buffer_64);if(rc) return rc; + rc_num = l_data_buffer_64.clearBit(60);if (rc_num){FAPI_ERR( "Error in function mcb_reset_trap:");rc.setEcmdError(rc_num);return rc;} + rc = fapiPutScom(i_target_mba,MBA01_MCBIST_MCBCFGQ_0x030106e0,l_data_buffer_64);if(rc) return rc; + //Reset MCB Maintanence register + FAPI_INF("Clearing the MCBIST Maintenance "); + rc_num = l_data_buffer_64.flushTo0();if (rc_num){FAPI_ERR( "Error in function mcb_reset_trap:");rc.setEcmdError(rc_num);return rc;} + rc = fapiGetScom(i_target_mba,MBA01_MCBIST_MCB_CNTLSTATQ_0x030106dc,l_data_buffer_64);if(rc) return rc; + rc_num = l_data_buffer_64.clearBit(0,3);if (rc_num){FAPI_ERR( "Error in function mcb_reset_trap:");rc.setEcmdError(rc_num);return rc;} + rc = fapiPutScom(i_target_mba,MBA01_MCBIST_MCB_CNTLSTATQ_0x030106dc,l_data_buffer_64);if(rc) return rc; + + //Reset the MCBIST runtime counter + FAPI_INF("Clearing the MCBIST Runtime Counter "); + rc_num = l_data_buffer_64.flushTo0();if (rc_num){FAPI_ERR( "Error in function mcb_reset_trap:");rc.setEcmdError(rc_num);return rc;} + rc = fapiGetScom(i_target_mba,MBA01_MCBIST_RUNTIMECTRQ_0x030106b0,l_data_buffer_64);if(rc) return rc; + rc_num = l_data_buffer_64.clearBit(0,37);if (rc_num){FAPI_ERR( "Error in function mcb_reset_trap:");rc.setEcmdError(rc_num);return rc;} + rc = fapiPutScom(i_target_mba,MBA01_MCBIST_RUNTIMECTRQ_0x030106b0,l_data_buffer_64);if(rc) return rc; + + FAPI_INF("To clear Port error map registers of both port A and B"); + rc_num = l_data_buffer_64.flushTo0();if (rc_num){FAPI_ERR( "Error in function mcb_reset_trap:");rc.setEcmdError(rc_num);return rc;} + //PORT - A + rc = fapiPutScom(i_target_mba,MBS_MCBIST01_MCBEMA1Q_0x0201166a,l_data_buffer_64); if(rc) return(rc); + rc = fapiPutScom(i_target_mba,MBS_MCBIST01_MCBEMA2Q_0x0201166b,l_data_buffer_64); if(rc) return(rc); + rc = fapiPutScom(i_target_mba,MBS_MCBIST01_MCBEMA3Q_0x0201166c,l_data_buffer_64); if(rc) return(rc); + + //PORT - B + rc = fapiPutScom(i_target_mba,MBS_MCBIST01_MCBEMB1Q_0x0201166d,l_data_buffer_64); if(rc) return(rc); + rc = fapiPutScom(i_target_mba,MBS_MCBIST01_MCBEMB2Q_0x0201166e,l_data_buffer_64); if(rc) return(rc); + rc = fapiPutScom(i_target_mba,MBS_MCBIST01_MCBEMB3Q_0x0201166f,l_data_buffer_64); if(rc) return(rc); + + + + return rc; +} + + +//*****************************************************************/ +// Funtion name : start_mcb +// Description: Checks for dimms drop in the particular port & starts MCBIST +//Input Parameters : +// const fapi::Target & Centaur.mba +//*****************************************************************/ + +fapi::ReturnCode start_mcb(const fapi::Target & i_target_mba) +{ + ecmdDataBufferBase l_data_buffer_64(64); + uint8_t l_num_ranks_per_dimm[2][2]; + fapi::ReturnCode rc; + uint32_t rc_num = 0; + FAPI_INF("Function - start_mcb"); + + + rc = fapiGetScom(i_target_mba,MBA01_MCBIST_MCBAGRAQ_0x030106d6,l_data_buffer_64); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, l_num_ranks_per_dimm); if(rc) return rc; + + + if(l_num_ranks_per_dimm[0][0] > 0) + { + FAPI_INF("Port AB configured, Socket 0 Configured"); + rc_num = l_data_buffer_64.setBit(24);if (rc_num){FAPI_ERR( "Error in function start_mcb:");rc.setEcmdError(rc_num);return rc;} + rc_num = l_data_buffer_64.clearBit(25);if (rc_num){FAPI_ERR( "Error in function start_mcb:");rc.setEcmdError(rc_num);return rc;} + } + else if(l_num_ranks_per_dimm[0][1] > 0) + { + FAPI_INF("Port AB configured, Socket 1 Configured"); + rc_num = l_data_buffer_64.clearBit(24);if (rc_num){FAPI_ERR( "Error in function start_mcb:");rc.setEcmdError(rc_num);return rc;} + rc_num = l_data_buffer_64.setBit(25);if (rc_num){FAPI_ERR( "Error in function start_mcb:");rc.setEcmdError(rc_num);return rc;} + } + else if((l_num_ranks_per_dimm[0][0] > 0) && (l_num_ranks_per_dimm[0][1] > 0)) + { + FAPI_INF("Port AB configured, Socket 0, 1 Configured"); + rc_num = l_data_buffer_64.setBit(24);if (rc_num){FAPI_ERR( "Error in function start_mcb:");rc.setEcmdError(rc_num);return rc;} + rc_num = l_data_buffer_64.setBit(25);if (rc_num){FAPI_ERR( "Error in function start_mcb:");rc.setEcmdError(rc_num);return rc;} + } + else + { + FAPI_INF("No Socket found"); + + } + + + //rc = fapiDelay(DELAY_100US, DELAY_2000SIMCYCLES);if(rc) return rc; // wait 2000 simcycles (in sim mode) OR 100 uS (in hw mode) + + rc = fapiPutScom(i_target_mba,MBA01_MCBIST_MCBAGRAQ_0x030106d6,l_data_buffer_64); if(rc) return rc; + FAPI_INF("STARTING MCBIST for Centaur Target"); + rc = fapiGetScom(i_target_mba,MBA01_MCBIST_MCB_CNTLSTATQ_0x030106dc,l_data_buffer_64); if(rc) return rc; + + if(l_data_buffer_64.isBitSet(0)) + { + FAPI_INF("MCBIST already in progess, wait till MCBIST completes"); + + return rc; + + } + rc_num = l_data_buffer_64.flushTo0();if (rc_num){FAPI_ERR( "Error in function start_mcb:");rc.setEcmdError(rc_num);return rc;} + rc_num = l_data_buffer_64.setBit(0);if (rc_num){FAPI_ERR( "Error in function start_mcb:");rc.setEcmdError(rc_num);return rc;} + rc = fapiPutScom(i_target_mba,MBA01_MCBIST_MCB_CNTLQ_0x030106db,l_data_buffer_64); if(rc) return rc; + + //rc = fapiDelay(DELAY_100US, DELAY_2000SIMCYCLES);if(rc) return rc; // wait 2000 simcycles (in sim mode) OR 100 uS (in hw mode) + + + + return rc; +} + + + +//*****************************************************************/ +// Funtion name : poll_mcb +// Description : Will check the MCBIST Configuration Register for mcb fail, in progress +// fail. It will print the corresponding centaur on which MCBIST has +// been completed, in progress or failed. +// Input Parameters : +// const fapi::Target & Centaur.mba +// bool i_mcb_stop_on_fail Whether MCBIST should stop on fail or not +// Output Parameter : +// uint32 status = 1 MCBIST done with fail or MCBIST not complete (default value) +// = 0 MCBIST Done without fail +//****************************************************************/ +fapi::ReturnCode poll_mcb(const fapi::Target & i_target_mba,bool i_mcb_stop_on_fail,uint8_t *o_mcb_status) +{ + fapi::ReturnCode rc; // return value after each SCOM access/buffer modification + uint32_t rc_num = 0; + ecmdDataBufferBase l_data_buffer_64(64); + ecmdDataBufferBase l_stop_on_fail_buffer_64(64); + //Current status of the MCB (done, fail, in progress) + uint8_t l_mcb_done = 0; + uint8_t l_mcb_fail = 0; + uint8_t l_mcb_ip = 0; + //Time out variables + uint32_t l_mcb_timeout = 0; + uint32_t l_count = 0; + + // Clear to register to zero; + + FAPI_INF("Function Poll_MCBIST"); + + while ((l_mcb_done == 0) && (l_mcb_timeout <= MCB_MAX_TIMEOUT)) + { + rc = fapiGetScom(i_target_mba,MBA01_MCBIST_MCB_CNTLSTATQ_0x030106dc,l_data_buffer_64); if(rc) return rc; + if(l_data_buffer_64.isBitSet(0)) + { + FAPI_INF("MCBIST is in progress_inside poll_mcb"); + l_mcb_ip = 1; + } + if(l_data_buffer_64.isBitSet(1)) + { + FAPI_INF("MCBIST is done"); + l_mcb_ip = 0; + l_mcb_done = 1; + } + if(l_data_buffer_64.isBitSet(2)) + { + l_mcb_fail = 1; + if(i_mcb_stop_on_fail == true) //if stop on error is 1, break after the current subtest completes + { + rc = fapiGetScom(i_target_mba,MBA01_MCBIST_MCBCFGQ_0x030106e0,l_stop_on_fail_buffer_64); if(rc) return rc; + rc_num = l_stop_on_fail_buffer_64.setBit(62);if (rc_num){FAPI_ERR( "Error in function poll_mcb:");rc.setEcmdError(rc_num);return rc;} // Set bit 61 to break after current subtest + rc = fapiPutScom(i_target_mba,MBA01_MCBIST_MCBCFGQ_0x030106e0,l_stop_on_fail_buffer_64); if(rc) return rc; + FAPI_INF("MCBIST will break after Current Subtest"); + + while(l_mcb_done == 0) // Poll till MCBIST is done + { + rc = fapiGetScom(i_target_mba,MBA01_MCBIST_MCB_CNTLSTATQ_0x030106dc,l_data_buffer_64); if(rc) return rc; + if(l_data_buffer_64.isBitSet(1)) + { + l_mcb_ip = 0; + l_mcb_done = 1; + FAPI_INF("MCBIST Done"); + rc_num = l_stop_on_fail_buffer_64.clearBit(62);if (rc_num){FAPI_ERR( "Error in function poll_mcb:");rc.setEcmdError(rc_num);return rc;} // Clearing bit 61 to avoid breaking after current subtest + rc = fapiPutScom(i_target_mba,MBA01_MCBIST_MCBCFGQ_0x030106e0,l_stop_on_fail_buffer_64); if(rc) return rc; + } + } + } + } + l_mcb_timeout++; + if (l_mcb_timeout >= MCB_MAX_TIMEOUT) + { + FAPI_ERR( "poll_mcb:Maximun time out"); + FAPI_SET_HWP_ERROR(rc,RC_MSS_MCBIST_TIMEOUT_ERROR); + return rc; + } + +#ifdef MCB_DEBUG_1 + if(l_count%100 == 0)//Can be changed later + { + FAPI_INF("MCB done bit : l_mcb_done"); + FAPI_INF("MCB fail bit : l_mcb_fail"); + FAPI_INF("MCB IP bit : l_mcb_ip"); + } +#endif + l_count++; + } + + if((l_mcb_done == 1) && (l_mcb_fail == 1) && (i_mcb_stop_on_fail == true)) + { + *o_mcb_status = 1; /// MCB fail + #ifdef MCB_DEBUG_2 + FAPI_INF("*************************************************"); + FAPI_INF("MCB done bit : %d",l_mcb_done); + FAPI_INF("MCB fail bit : %d",l_mcb_fail); + FAPI_INF("MCB IP bit : %d",l_mcb_ip); + FAPI_INF("*************************************************"); + #endif + } + else if((l_mcb_done == 1) && (l_mcb_fail == 0)) + { + *o_mcb_status = 0;//pass; + #ifdef MCB_DEBUG2 + FAPI_INF("*************************************************"); + FAPI_INF("MCB done bit : %d",l_mcb_done); + FAPI_INF("MCB fail bit : %d",l_mcb_fail); + FAPI_INF("MCB IP bit : %d",l_mcb_ip); + FAPI_INF("*************************************************"); + #endif + } + else if((l_mcb_done == 0) && (l_mcb_ip == 1) && (l_mcb_timeout == MCB_MAX_TIMEOUT)) + { + *o_mcb_status = 1;//fail; + #ifdef MCB_DEBUG2 + FAPI_INF("****************************************"); + FAPI_INF("MCB done bit : %d",l_mcb_done); + FAPI_INF("MCB fail bit : %d",l_mcb_fail); + FAPI_INF("MCB IP bit : %d",l_mcb_ip); + FAPI_INF("****************************************"); + + #endif + } + + + if (*o_mcb_status == 1) + { + FAPI_ERR( "poll_mcb:MCBIST failed"); + FAPI_SET_HWP_ERROR(rc,RC_MSS_MCBIST_ERROR); + return rc; + } + + + + return rc; +} + + + +/****************************************************************/ +// Funtion name : mcb_error_map_print +// Description : Prints the error Map of a Rank +// Input Parameters : +// const fapi::Target & Centaur.mba +// uint8_t i_port Port in use +// uint8_t i_rank Rank in use +// ecmdDataBufferBase & l_mcb_fail_320 Ecmd Buffer +// Output Parameter : +// uint8_t o_error_map[][8][10][2] Contains the error map +//****************************************************************/ + +fapi::ReturnCode mcb_error_map_print(const fapi::Target & i_target_mba,uint8_t i_port,uint8_t i_rank,ecmdDataBufferBase & l_mcb_fail_320) +{ + ReturnCode rc; + uint8_t l_num_ranks_per_dimm[MAX_PORT][MAX_PORT]; + uint8_t l_rankpair_table[MAX_RANK] = {0}; + uint8_t l_cur_rank =0; + uint8_t l_cur_dram =0; + uint8_t l_max_rank = 0; + uint8_t l_rank_pair = 0; + char l_str1[200] = ""; + uint8_t l_index = 0; + + if(i_port == 0) + { + FAPI_INF("################# PortA Error MAP #################"); + } + if(i_port == 1) + { + FAPI_INF("################# PortB Error MAP #################"); + } + + FAPI_INF("Byte 00112233445566778899"); + FAPI_INF(" --------------------"); + FAPI_INF("Nibble 00000000001111111111"); + FAPI_INF("Nibble 01234567890123456789"); + + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, l_num_ranks_per_dimm); if(rc) return rc; + l_max_rank=l_num_ranks_per_dimm[i_port][0]+l_num_ranks_per_dimm[i_port][1]; + rc = mss_getrankpair(i_target_mba,i_port,0,&l_rank_pair,l_rankpair_table); if(rc) return rc; + + if(l_max_rank > MAX_RANK) + { + FAPI_ERR(" Maximum ranks available exceeded 8"); + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + + return rc; + } + for(l_cur_rank = 0;l_cur_rank < l_max_rank;l_cur_rank++) + { + if(i_rank == l_rankpair_table[l_cur_rank]) + { + sprintf(l_str1,"%-4s%d%5s","RANK",l_rankpair_table[l_cur_rank],""); + for(l_cur_dram = 0; l_cur_dram < MAX_DRAM; l_cur_dram++) + { + + if(i_port == 1) + { + l_index = (l_rankpair_table[l_cur_rank])*(MAX_DRAM) + l_cur_dram + 160; + } + + if(i_port == 0) + { + l_index = (l_rankpair_table[l_cur_rank])*(MAX_DRAM) + l_cur_dram ; + } + + + + + if(l_mcb_fail_320.isBitSet(l_index)) + { + + strcat(l_str1,"X"); + } + else + { + + strcat(l_str1,"."); + } + } + + + FAPI_INF("%s",l_str1); + break; + } + } +return rc; +} + + + + + + + +/*****************************************************************/ +// Funtion name : mcb_error_map +// Description : Reads the nibblewise Error map registers into o_error_map +// Input Parameters : +// const fapi::Target & Centaur.mba +// +// Output Parameter : +// uint8_t o_error_map[][8][10][2] Contains the error map +//****************************************************************/ +fapi::ReturnCode mcb_error_map(const fapi::Target & i_target_mba, uint8_t o_error_map[][8][10][2],uint8_t i_port,uint8_t i_rank) +{ + ecmdDataBufferBase l_mcbem1ab(64); + ecmdDataBufferBase l_mcbem2ab(64); + ecmdDataBufferBase l_mcbem3ab(64); + ecmdDataBufferBase l_data_buffer_64(64); + ecmdDataBufferBase l_mcb_fail_320(320); + + + + + //#################### + fapi::Target i_target_centaur ; + //#################### + fapi::ReturnCode rc; + uint32_t rc_num = 0; + //uint8_t l_cur_rank =0; + //uint8_t l_cur_dram =0; + uint8_t l_index0 = 0; + uint8_t l_index1 = 0; + uint8_t l_port = 0; + uint8_t l_rank = 0; + uint8_t l_byte = 0; + uint8_t l_nibble = 0; + uint8_t l_num_ranks_per_dimm[MAX_PORT][MAX_PORT]; + // uint8_t l_max_rank = 0; + // uint8_t l_rankpair_table[MAX_RANK] = {0}; + //uint8_t l_rank_pair = 0; + uint8_t l_mbaPosition = 0; + FAPI_INF("Function MCB_ERROR_MAP"); + rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_target_mba, l_mbaPosition); + if(rc) + { + FAPI_ERR("Error getting MBA position"); return rc; + } + + + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, l_num_ranks_per_dimm); if(rc) return rc; + rc = fapiGetParentChip(i_target_mba, i_target_centaur); + if (rc) + { + FAPI_ERR("Error in getting Parent Chiplet"); + return rc; + } + + + rc = fapiGetScom(i_target_centaur,MBS_MCBIST01_MCBEMA1Q_0x0201166a,l_mcbem1ab); if(rc) return rc; + rc_num = l_mcb_fail_320.insert(l_mcbem1ab,0,60,0);if (rc_num){FAPI_ERR( "Error in function mcb_error_map:");rc.setEcmdError(rc_num);return rc;} + rc = fapiGetScom(i_target_centaur,MBS_MCBIST01_MCBEMA2Q_0x0201166b,l_mcbem2ab); if(rc) return rc; + rc_num = l_mcb_fail_320.insert(l_mcbem2ab,60,60,0);if (rc_num){FAPI_ERR( "Error in function mcb_error_map:");rc.setEcmdError(rc_num);return rc;} + rc = fapiGetScom(i_target_centaur,MBS_MCBIST01_MCBEMA3Q_0x0201166c,l_mcbem3ab); if(rc) return rc; + rc_num = l_mcb_fail_320.insert(l_mcbem3ab,120,40,0);if (rc_num){FAPI_ERR( "Error in function mcb_error_map:");rc.setEcmdError(rc_num);return rc;} + + + //rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, l_num_ranks_per_dimm); if(rc) return rc; + //l_max_rank=l_num_ranks_per_dimm[0][0]+l_num_ranks_per_dimm[0][1]; + // rc = mss_getrankpair(i_target_mba,i_port,0,&l_rank_pair,l_rankpair_table); if(rc) return rc; + + /*if(l_max_rank > MAX_RANK) + { + FAPI_ERR(" Maximum ranks available exceeded 8"); + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + return rc; + }*/ + if(i_port == 0) + { + + mcb_error_map_print( i_target_mba ,i_port, i_rank, l_mcb_fail_320); + + } + rc = fapiGetScom(i_target_centaur,MBS_MCBIST01_MCBEMB1Q_0x0201166d,l_mcbem1ab); if(rc) return rc; + rc_num = l_mcb_fail_320.insert(l_mcbem1ab,160,60,0);if (rc_num){FAPI_ERR( "Error in function mcb_error_map:");rc.setEcmdError(rc_num);return rc;} + rc = fapiGetScom(i_target_centaur,MBS_MCBIST01_MCBEMB2Q_0x0201166e,l_mcbem2ab); if(rc) return rc; + rc_num = l_mcb_fail_320.insert(l_mcbem2ab,220,60,0);if (rc_num){FAPI_ERR( "Error in function mcb_error_map:");rc.setEcmdError(rc_num);return rc;} + rc = fapiGetScom(i_target_centaur,MBS_MCBIST01_MCBEMB3Q_0x0201166f,l_mcbem3ab); if(rc) return rc; + rc_num = l_mcb_fail_320.insert(l_mcbem3ab,280,40,0);if (rc_num){FAPI_ERR( "Error in function mcb_error_map:");rc.setEcmdError(rc_num);return rc;} + //Restore values + + if(i_port == 1) + { + mcb_error_map_print(i_target_mba, i_port, i_rank, l_mcb_fail_320); + } + + //Need to check the DIMM plugged in and decide the rank? - Implement that. + + for (l_port = 0; l_port < MAX_PORT ; l_port++) + { + for(l_rank = 0; l_rank < MAX_RANK; l_rank++) + { + for(l_byte = 0; l_byte < MAX_BYTE; l_byte++) + { + for(l_nibble = 0; l_nibble < MAX_NIBBLES; l_nibble++) + { + l_index0 = (l_rank*20) + (l_byte*2) + l_nibble; + l_index1 = l_index0 + 160*(l_port); + if((l_mcb_fail_320.isBitSet(l_index1))) + { + o_error_map[l_port][l_rank][l_byte][l_nibble] = 1; + } + else + { + o_error_map[l_port][l_rank][l_byte][l_nibble] = 0; + } + + } + } + } + } + + + + return rc; +} +/*****************************************************************/ +// Funtion name : mcb_write_test_mem +// Description : : Based on parameters passed we write data into Register being passed +// Input Parameters : +// const fapi::Target & Centaur.mba +// const uint64_t i_reg_addr Register address +// mcbist_oper_type i_operation_type Operation Type +// mcbist_addr_mode i_addr_mode Sequential or Random address modes +// mcbist_data_mode i_data_mode Data Mode +// uint8_t i_done Done Bit +// mcbist_data_select_mode i_data_select_mode Different BURST modes or DEFAULT +// mcbist_add_select_mode i_addr_select_mode Address Select mode +// uint8_t i_testnumber Subtest number +// uint8_t i_cfg_test_123_cmd Integer value + +//****************************************************************/ +fapi::ReturnCode mcb_write_test_mem(const fapi::Target & i_target_mba,const uint64_t i_reg_addr,mcbist_oper_type i_operation_type,uint8_t i_cfg_test_123_cmd,mcbist_addr_mode i_addr_mode,mcbist_data_mode i_data_mode,uint8_t i_done,mcbist_data_select_mode i_data_select_mode, mcbist_add_select_mode i_addr_select_mode,uint8_t i_testnumber) +{ + fapi::ReturnCode rc; + uint32_t rc_num = 0; + uint8_t l_index = 0; + uint8_t l_operation_type = i_operation_type; + uint8_t l_cfg_test_123_cmd = i_cfg_test_123_cmd; + uint8_t l_addr_mode = i_addr_mode; + uint8_t l_data_mode = i_data_mode; + uint8_t l_data_select_mode = i_data_select_mode; + uint8_t l_addr_select_mode = i_addr_select_mode; + + ecmdDataBufferBase l_data_buffer_64(64); + + + FAPI_INF("Function mcb_write_test_mem"); + rc = fapiGetScom(i_target_mba,i_reg_addr,l_data_buffer_64);if(rc) return rc; + l_index = i_testnumber * (MCB_TEST_NUM) ; + + // Operation type + + + rc_num = rc_num| l_data_buffer_64.insertFromRight(l_operation_type,l_index ,3); + + + rc_num = rc_num| l_data_buffer_64.insertFromRight(l_cfg_test_123_cmd,l_index + 3,3); + + // ADDR MODE + + rc_num = rc_num| l_data_buffer_64.insertFromRight(l_addr_mode,l_index + 6,2); + // DATA MODE + + rc_num = rc_num| l_data_buffer_64.insertFromRight(l_data_mode,l_index + 8,3); + // Done bit + + rc_num = rc_num| l_data_buffer_64.insertFromRight(i_done,l_index + 11,1); + // Data Select Mode + + rc_num = rc_num| l_data_buffer_64.insertFromRight(l_data_select_mode,l_index + 12,2); + + // Address Select mode + + rc_num = rc_num| l_data_buffer_64.insertFromRight(l_addr_select_mode,l_index + 14,2); + + + if (rc_num){FAPI_ERR( "Error in function mcb_write_test_mem:");rc.setEcmdError(rc_num);return rc;} + + rc = fapiPutScom(i_target_mba,i_reg_addr,l_data_buffer_64); if(rc) return rc; + rc = fapiGetScom(i_target_mba,i_reg_addr,l_data_buffer_64); if(rc) return rc; + + + return rc; +} +/*****************************************************************/ +// Funtion name : cfg_byte_mask +// Description : +// Input Parameters : It is used to mask bad bits read from SPD +// const fapi::Target & Centaur.mba +// uint8_t i_rank Current Rank +// uint8_t i_port Current Port +//****************************************************************/ +fapi::ReturnCode cfg_byte_mask(const fapi::Target & i_target_mba,uint8_t i_rank,uint8_t i_port) +{ + + uint8_t l_dimm=0; + ecmdDataBufferBase l_data_buffer1_64(64); + ecmdDataBufferBase l_data_buffer2_64(64); + ecmdDataBufferBase l_data_buffer3_64(64); + + + fapi::ReturnCode rc; + uint32_t rc_num = 0; + + rc_num = l_data_buffer3_64.flushTo1();if (rc_num){FAPI_ERR( "Error in function cfg_byte_mask:");rc.setEcmdError(rc_num);return rc;} + + + uint8_t l_dqBitmap[DIMM_DQ_RANK_BITMAP_SIZE]; + uint8_t l_dq[8]={0}; + uint8_t l_sp[2]={0}; + uint8_t l_index0=0; + uint8_t l_index_sp=0; + uint16_t l_sp_mask=0xffff; + + FAPI_INF("Function cfg_byte_mask"); + if(i_rank>3) + { + l_dimm=1; + i_rank=4-i_rank; + } + else + { + l_dimm=0; + } + rc = dimmGetBadDqBitmap(i_target_mba, i_port, l_dimm, i_rank,l_dqBitmap);if(rc) return rc; + + for ( l_index0 = 0; l_index0 < DIMM_DQ_RANK_BITMAP_SIZE; l_index0++) + { + if(l_index0<8) + { + l_dq[l_index0]=l_dqBitmap[l_index0]; + FAPI_INF("\n the bad dq=%x ",l_dqBitmap[l_index0]); + + } + else + { + l_sp[l_index_sp]=l_dqBitmap[l_index0]; + l_index_sp++; + } + } + + + rc_num = l_data_buffer1_64.insertFromRight(l_dq,0,64);if (rc_num){FAPI_ERR( "Error in function cfg_byte_mask:");rc.setEcmdError(rc_num);return rc;} + // rc_num = l_data_buffer2_64.insertFromRight(l_sp,0,16);if (rc_num){FAPI_ERR( "Error in function cfg_byte_mask:");rc.setEcmdError(rc_num);return rc;} + + if(i_port == 0) + { + rc_num = l_data_buffer2_64.insertFromRight(l_sp,0,16);if (rc_num){FAPI_ERR( "Error in function cfg_byte_mask:");rc.setEcmdError(rc_num);return rc;} + rc_num = l_data_buffer2_64.insertFromRight(l_sp_mask,16,16);if (rc_num){FAPI_ERR( "Error in function cfg_byte_mask:");rc.setEcmdError(rc_num);return rc;} + rc = fapiPutScom(i_target_mba,MBS_MCBIST01_MCBCMA1Q_0x02011672,l_data_buffer1_64); if(rc) return rc; + rc = fapiPutScom(i_target_mba,MBS_MCBIST01_MCBCMABQ_0x02011674,l_data_buffer2_64); if(rc) return rc; + rc = fapiPutScom(i_target_mba,MBS_MCBIST01_MCBCMB1Q_0x02011673,l_data_buffer3_64); if(rc) return rc; + } + else + { + rc_num = l_data_buffer2_64.insertFromRight(l_sp,16,16);if (rc_num){FAPI_ERR( "Error in function cfg_byte_mask:");rc.setEcmdError(rc_num);return rc;} + rc_num = l_data_buffer2_64.insertFromRight(l_sp_mask,0,16);if (rc_num){FAPI_ERR( "Error in function cfg_byte_mask:");rc.setEcmdError(rc_num);return rc;} + rc = fapiPutScom(i_target_mba,MBS_MCBIST01_MCBCMB1Q_0x02011673,l_data_buffer1_64); if(rc) return rc; + rc = fapiPutScom(i_target_mba,MBS_MCBIST01_MCBCMABQ_0x02011674,l_data_buffer2_64); if(rc) return rc; + rc = fapiPutScom(i_target_mba,MBS_MCBIST01_MCBCMA1Q_0x02011672,l_data_buffer3_64); if(rc) return rc; + } + + + return rc; +} +/*****************************************************************/ +// Funtion name : addr_gen_func +// Description : Based on the Schmoo Address Mode this function decides the address range on which MCBIST must operate +// Input Parameters : +// const fapi::Target & Centaur.mba +// mcbist_addr_mode i_addr_mode MCBIST address mode +// uint8_t i_attr_eff_schmoo_addr_mode Schmoo address mode +// Output Parameters : +// uint64_t &io_end_address End address of MCBIST +// uint64_t &io_start_address Start address of MCBIST +// uint8_t i_rank Current Rank +//****************************************************************/ + +fapi::ReturnCode addr_gen_func(const fapi::Target & i_target_mba, mcbist_addr_mode i_addr_mode, uint8_t i_attr_eff_schmoo_addr_mode ,uint64_t &io_end_address,uint64_t &io_start_address,uint8_t i_rank,uint8_t i_port) +{ + fapi::ReturnCode rc; + uint8_t l_rank = 0; + uint8_t l_cur_rank = 0; + uint8_t l_rankpair_table[8]; + FAPI_INF("Function mss_address_gen"); + uint64_t l_end_address = io_end_address; + uint64_t l_start_address = io_start_address; + uint64_t l_diff_address = 0; + uint64_t l_diff_address1 = 0; + uint64_t l_addr1 = 0; + uint64_t l_addr2 = 0; + uint8_t l_num_ranks_per_dimm[MAX_PORT][MAX_PORT]; + uint8_t l_max_rank = 0; + //uint8_t i_port = 0; + uint8_t l_rank_pair = 0; + //uint8_t i = 0; + uint8_t l_compare = 0; + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, l_num_ranks_per_dimm); if(rc) return rc; + l_max_rank=l_num_ranks_per_dimm[i_port][0]+l_num_ranks_per_dimm[i_port][1]; + rc = mss_getrankpair(i_target_mba,i_port,0,&l_rank_pair,l_rankpair_table); if(rc) return rc; + + if(l_max_rank > MAX_RANK) + { + FAPI_ERR(" Maximum ranks available exceeded 8"); + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + return rc; + } + + + for(l_cur_rank = 0;l_cur_rank < l_max_rank;l_cur_rank++) + { + if(i_rank == l_rankpair_table[l_cur_rank]) + { + l_rank = l_cur_rank; + break; + } + } + //FAPI_INF(" Addressing mode is %d ",i_attr_eff_schmoo_addr_mode); + //l_cur_rank = 0; + + if(i_addr_mode == SF) + { + l_addr1 = l_start_address; + l_addr2 = l_end_address; + } + else if(i_addr_mode == SR) + { + l_addr1 = l_end_address; + l_addr2 = l_start_address; + } + else + { + FAPI_INF("Wrong Shmoo address mode"); + FAPI_SET_HWP_ERROR(rc, RC_MSS_INPUT_ERROR); + return rc; + } + + if(i_attr_eff_schmoo_addr_mode == FEW_ADDR) + { + // FAPI_INF("Value 0 of Start is %016llX and Diff %016llX",l_addr1,l_addr2); + + l_diff_address = l_addr2 - l_addr1; + + /*for(i=0;i<l_rank;i++) + { + l_addr1 = l_addr1 + START_ADDRESS + l_diff_address; + }*/ + + //FAPI_INF("Value 1 of Start is %016llX and Diff %016llX",l_addr1,l_addr2); + + //l_addr1 += (END_ADDRESS * l_rank); + l_addr1 += ((START_ADDRESS + l_diff_address) * l_rank); + + l_addr2 = l_addr1 + FEW_INTERVAL; + //FAPI_INF("Value 2 of Start is %016llX and Diff %016llX",l_addr1,l_addr2); + + + } + + else if(i_attr_eff_schmoo_addr_mode == QUARTER_ADDR) + { + + + + l_diff_address = l_addr2 - l_addr1; + + if (l_diff_address >= (FOUR)) + { + l_diff_address1 = l_diff_address>>2; + + + + /*for(i=0;i<l_rank;i++) + { + l_addr1 = l_addr1 + START_ADDRESS + l_diff_address; + }*/ + //FAPI_INF("Value 3 of Start is %016llX and Diff %016llX",l_addr1,l_addr2); + + //l_addr1 += ((START_ADDRESS+l_diff_address) * l_rank); + l_addr1 += ((START_ADDRESS + l_diff_address) * l_rank); + l_addr2 = l_addr1 + l_diff_address1; + + + //FAPI_INF("Value 4 of Start is %016llX and Diff %016llX",l_addr1,l_addr2); + } + + + } + else if(i_attr_eff_schmoo_addr_mode == HALF_ADDR) + { + + + + l_diff_address = l_addr2 - l_addr1; + l_compare = (FOUR)>>1; + + if (l_diff_address >= l_compare) + { + l_diff_address1 = l_diff_address>>1; + + //FAPI_INF("Value 5.1 of diff is %016llX and FOUR %016llX",l_diff_address,l_compare); + + /*for(i=0;i<l_rank;i++) + { + l_addr1 = l_addr1 + l_diff_address + START_ADDRESS; + } */ + //FAPI_INF("Value 5 of Start is %016llX and Diff %016llX",l_addr1,l_addr2); + //l_addr1 += ((START_ADDRESS+l_diff_address) * l_rank); + l_addr1 += ((START_ADDRESS + l_diff_address) * l_rank); + l_addr2 = l_addr1 + l_diff_address1; + //FAPI_INF("Value 6 of Start is %016llX and Diff %016llX",l_addr1,l_addr2); + } + } + + else if(i_attr_eff_schmoo_addr_mode == FULL_ADDR) + { + + l_diff_address = l_addr2 - l_addr1; + + /*for(i=0;i<l_rank;i++) + { + l_addr1 = l_addr1 + l_diff_address + START_ADDRESS; + + }*/ + + // l_addr1 += ((START_ADDRESS+l_diff_address) * l_rank); + l_addr1 += ((START_ADDRESS + l_diff_address) * l_rank); + l_addr2 = l_addr1 + l_diff_address; + + } + + if(i_addr_mode == SF) + { + l_start_address = l_addr1 ; + l_end_address = l_addr2 ; + } + else if(i_addr_mode == SR) + { + l_end_address = l_addr1; + l_start_address = l_addr2; + } + + + + io_start_address = l_start_address; + io_end_address = l_end_address; + //FAPI_INF("Value of end_address is %016llX and start address %016llX",io_end_address,io_start_address); + return rc; +} + + +//************************************************************************/ +// Funtion name : cfg_mcb_addr +// Description : Configures the address range of MCBIST +// Input Parameters : +// const fapi::Target & Centaur.mba +// uint8_t i_rank Current Rank Being Passed +//************************************************************************/ +fapi::ReturnCode cfg_mcb_addr(const fapi::Target & i_target_mba,uint8_t rank,uint8_t i_port) +{ + fapi::ReturnCode rc; // return value after each SCOM access/buffer modification + uint32_t rc_num = 0; + + ecmdDataBufferBase l_data_buffer_64(64); + ecmdDataBufferBase l_data_buffer2_64(64); + + uint32_t io_value_u32 = 0x00000000; + uint32_t l_sbit = 38; + uint32_t l_len = 26; + uint32_t l_start = 0; + uint8_t l_attr_eff_schmoo_addr_mode = 0; + uint8_t l_num_ranks_per_dimm[MAX_PORT][MAX_PORT]; + uint64_t start_address = 0; + uint64_t end_address = 0; + + + rc = FAPI_ATTR_GET(ATTR_EFF_SCHMOO_ADDR_MODE, &i_target_mba, l_attr_eff_schmoo_addr_mode); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, l_num_ranks_per_dimm); if(rc) return rc; + FAPI_INF("Function cfg_mcb_addr"); + + + FAPI_INF("Num ranks per dimm :%d ", l_num_ranks_per_dimm[0][0]); + FAPI_INF("Num ranks per dimm :%d ", l_num_ranks_per_dimm[0][1]); + FAPI_INF("Num ranks per dimm :%d ", l_num_ranks_per_dimm[1][0]); + FAPI_INF("Num ranks per dimm :%d ", l_num_ranks_per_dimm[1][1]); + + + + if( ( l_attr_eff_schmoo_addr_mode == FEW_ADDR) || ( l_attr_eff_schmoo_addr_mode == QUARTER_ADDR) ||( l_attr_eff_schmoo_addr_mode == HALF_ADDR) ||( l_attr_eff_schmoo_addr_mode == FULL_ADDR)) + { + + + + if(((l_num_ranks_per_dimm[0][0] != 0) || (l_num_ranks_per_dimm[1][0] != 0)) && (rank <=3)) + { + FAPI_INF("Slot 0 is configured\n"); + + rc = fapiGetScom(i_target_mba,MBA01_MCBIST_MCBSSARA0Q_0x030106d0,l_data_buffer_64); if(rc) return rc; + rc = fapiGetScom(i_target_mba,MBA01_MCBIST_MCBSEARA0Q_0x030106d2,l_data_buffer2_64); if(rc) return rc; + start_address = l_data_buffer_64.getDoubleWord (0); + end_address = l_data_buffer2_64.getDoubleWord (0); + + + + + FAPI_INF(" value of start and end addr is %016llX and %016llX",start_address,end_address); + rc=addr_gen_func(i_target_mba,SF, l_attr_eff_schmoo_addr_mode,end_address,start_address,rank,i_port);if(rc)return rc; + + + //rc_num=rc_num|l_data_buffer_64.insert(io_value_u32,l_sbit,l_len,l_start); + //rc_num=rc_num|l_data_buffer2_64.insert(io_value_u32,l_sbit,l_len,l_start); + rc_num = rc_num|l_data_buffer_64.setDoubleWord(0,start_address); + rc_num = rc_num| l_data_buffer2_64.setDoubleWord(0,end_address); + if (rc_num){FAPI_ERR( "Error in function cfg_mcb_addr:");rc.setEcmdError(rc_num);return rc;} + + + rc_num=l_data_buffer_64.insert(io_value_u32,l_sbit,l_len,l_start);if (rc_num){FAPI_ERR( "Error in function cfg_mcb_addr:");rc.setEcmdError(rc_num);return rc;} + rc_num=l_data_buffer2_64.insert(io_value_u32,l_sbit,l_len,l_start); if (rc_num){FAPI_ERR( "Error in function cfg_mcb_addr:");rc.setEcmdError(rc_num);return rc;} + + + FAPI_INF(" value of start and end addr is %016llX and %016llX",start_address,end_address); + rc = fapiPutScom(i_target_mba,MBA01_MCBIST_MCBSSARA0Q_0x030106d0,l_data_buffer_64); if(rc) return rc; + rc = fapiPutScom(i_target_mba,MBA01_MCBIST_MCBSEARA0Q_0x030106d2,l_data_buffer2_64); if(rc) return rc; + } + + if(((l_num_ranks_per_dimm[0][1] != 0) || (l_num_ranks_per_dimm[1][1] != 0)) && (rank >=4)) + { + FAPI_INF("Slot 1 is configured\n"); + + rc = fapiGetScom(i_target_mba,MBA01_MCBIST_MCBSSARA0Q_0x030106d0,l_data_buffer_64); if(rc) return rc; + rc = fapiGetScom(i_target_mba,MBA01_MCBIST_MCBSEARA0Q_0x030106d2,l_data_buffer2_64); if(rc) return rc; + start_address = l_data_buffer_64.getDoubleWord (0); + end_address = l_data_buffer2_64.getDoubleWord (0); + FAPI_INF(" value of start and end addr is %016llX and %016llX",start_address,end_address); + rc=addr_gen_func(i_target_mba,SF, l_attr_eff_schmoo_addr_mode,end_address,start_address,rank,i_port); if(rc)return rc; + rc_num = rc_num| l_data_buffer_64.setDoubleWord(0,start_address); + rc_num = rc_num|l_data_buffer2_64.setDoubleWord(0,end_address); + if (rc_num){FAPI_ERR( "Error in function cfg_mcb_addr:");rc.setEcmdError(rc_num);return rc;} + + rc_num=rc_num|l_data_buffer_64.insert(io_value_u32,l_sbit,l_len,l_start); + rc_num=rc_num|l_data_buffer2_64.insert(io_value_u32,l_sbit,l_len,l_start); + if (rc_num){FAPI_ERR( "Error in function cfg_mcb_addr:");rc.setEcmdError(rc_num);return rc;} + FAPI_INF(" value of start and end addr is %016llX and %016llX",start_address,end_address); + rc = fapiPutScom(i_target_mba,MBA01_MCBIST_MCBSSARA1Q_0x030106d1,l_data_buffer_64); if(rc) return rc; + rc = fapiPutScom(i_target_mba,MBA01_MCBIST_MCBSEARA1Q_0x030106d3,l_data_buffer2_64); if(rc) return rc; + } + + } + + + return rc; + +} + + + +} + diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_shmoo_common.H b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_shmoo_common.H new file mode 100644 index 000000000..af6b2eac4 --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_shmoo_common.H @@ -0,0 +1,90 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv/mss_shmoo_common.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: mss_shmoo_common.H,v 1.10 2012/12/06 11:46:58 sasethur Exp $ +// *!*************************************************************************** +// *! (C) Copyright International Business Machines Corp. 1997, 1998 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +// *!*************************************************************************** +// *! FILENAME : mss_shmoo_common.H +// *! TITLE : MSS Shmoo common defines +// *! DESCRIPTION : Memory Subsystem Shmoo common defines +// *! CONTEXT : To make all shmoos share a common defines +// *! +// *! OWNER NAME : Varkey Varghese Email: varkey.kv@in.ibm.com +// *! BACKUP NAME : Gaurav Sharda Email: +// *! +// *!*************************************************************************** +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:|Author: | Date: | Comment: +// 1.9 |aditya |12/6/12 | Updated Review Comments +// 1.8 | abhijit| 15/11/12| made changes fw review comments +// 1.7 | abhijit| 22/10/12| made changes to variables +// 1.6 | abhijit| 22/10/12| made changes according to the new design +// --------|--------|-------- |-------------------------------------------------- +#ifndef MSS_SHMOO_COMMON_H +#define MSS_SHMOO_COMMON_H + +enum shmoo_type_t { TEST_NONE=0,MCBIST=1,WR_EYE=2, WRT_DQS=4,RD_EYE=8,RD_GATE=16 }; + + +enum shmoo_algorithm_t { SEQ_LIN}; // Parallel bytes/ranks here .. no parallel targets in HB +const uint8_t NINE = 9; +const uint8_t MAX_RPS=4;// 4 Rank pairs in this design +const uint8_t MAX_SHMOO=4; +const uint8_t MAX_RANK_DIMM=4; +const uint8_t MAX_NIBBLES=2; +const uint8_t MAX_BITS=4; +const uint8_t MAX_DQ=80; +const uint8_t MAX_DQS=20; +const uint16_t read_counter_threshold=1000; +const uint16_t error_threshold_count=400; +const uint8_t MAX_PORT = 2; +const uint8_t MAX_BYTE = 10; +const uint8_t MAX_RANK = 8; +//const uint8_t MAX_NIBBLE = 1; + +//! Defines the structure of a knob ..Holds static info regarding a knob +struct shmoo_knob_config_t{ + //! These are const values that define a knob , will not change during + //! shmoo runtime + uint16_t min_val; //Minimum value that can be taken by the knob + uint16_t max_val; //Maximum value that can be taken by the knob + +}; + +//! Defines the structure of a knob ..Holds dynamic runtime info of a knob +struct shmoo_knob_data_t{ + // placeholder for the datastructure that will hold all the shmoo + // config data and results + //uint32_t curr_val[MAX_BLOCK][MAX_INSTANCE][MAX_RPS]; + bool done; + uint32_t lb_regval[MAX_DQ][MAX_RPS]; // Left Bound register/Hex value + uint32_t rb_regval[MAX_DQ][MAX_RPS];// Right Bound register/Hex value + uint32_t total_margin[MAX_DQ][MAX_RPS]; //Left bound+ right bound value + uint32_t nom_val[MAX_DQ][MAX_RPS]; // nominal value of this instance of the knob + uint32_t right_margin_val[MAX_DQ][MAX_RPS]; + uint32_t left_margin_val[MAX_DQ][MAX_RPS]; +}; +#endif diff --git a/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.C b/src/usr/hwpf/hwp/dram_training/mss_termination_control.C index 940fb703b..52edce90c 100644 --- a/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.C +++ b/src/usr/hwpf/hwp/dram_training/mss_termination_control.C @@ -1,7 +1,7 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.C $ */ +/* $Source: src/usr/hwpf/hwp/dram_training/mss_termination_control.C $ */ /* */ /* IBM CONFIDENTIAL */ /* */ @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_termination_control.C,v 1.11 2012/12/06 19:16:38 sasethur Exp $ +// $Id: mss_termination_control.C,v 1.12 2012/12/14 21:46:04 mwuu Exp $ /* File is created by SARAVANAN SETHURAMAN on Thur 29 Sept 2011. */ //------------------------------------------------------------------------------ @@ -43,6 +43,7 @@ //------------------------------------------------------------------------------ // Version:| Author: | Date: | Comment: //---------|----------|---------|----------------------------------------------- +// 1.12 | mwuu |14-Dec-12| Updated additional fw review comments // 1.11 | sasethur |07-Dec-12| Updated for fw review comments // 1.10 | mwuu |28-Nov-12| Added changes suggested from FW team. // 1.9 | mwuu |20-Nov-12| Changed warning status to not cause error. @@ -73,7 +74,7 @@ //---------------------------------------------------------------------- #include <mss_termination_control.H> #include <cen_scom_addresses.H> -//#include <mss_draminit_training_advanced.H> +#include <mss_draminit_training_advanced.H> /*------------------------------------------------------------------------------ * Function: config_drv_imp() @@ -88,7 +89,6 @@ fapi::ReturnCode config_drv_imp(const fapi::Target & i_target_mba, uint8_t i_por ecmdDataBufferBase data_buffer(64); fapi::ReturnCode rc; - fapi::ReturnCode rc_buff; uint32_t rc_num = 0; uint8_t enslice_drv = 0xFF; uint8_t enslice_ffedrv = 0xF; @@ -139,8 +139,8 @@ fapi::ReturnCode config_drv_imp(const fapi::Target & i_target_mba, uint8_t i_por if (rc_num) { FAPI_ERR( "config_rd_vref: Error in setting up buffer "); - rc_buff.setEcmdError(rc_num); - return rc_buff; + rc.setEcmdError(rc_num); + return rc; } rc = fapiPutScom(i_target_mba, DPHY01_DDRPHY_DP18_IO_TX_NFET_SLICE_P0_0_0x800000780301143F, @@ -183,8 +183,8 @@ fapi::ReturnCode config_drv_imp(const fapi::Target & i_target_mba, uint8_t i_por if (rc_num) { FAPI_ERR( "config_rd_vref: Error in setting up buffer "); - rc_buff.setEcmdError(rc_num); - return rc_buff; + rc.setEcmdError(rc_num); + return rc; } rc = fapiPutScom(i_target_mba, DPHY01_DDRPHY_DP18_IO_TX_NFET_SLICE_P1_0_0x800100780301143F, @@ -235,7 +235,6 @@ fapi::ReturnCode config_rcv_imp(const fapi::Target & i_target_mba, uint8_t i_por ecmdDataBufferBase data_buffer(64); fapi::ReturnCode rc; - fapi::ReturnCode rc_buff; uint32_t rc_num = 0; uint8_t enslicepterm = 0xFF; uint8_t enslicepffeterm = 0; @@ -307,8 +306,8 @@ fapi::ReturnCode config_rcv_imp(const fapi::Target & i_target_mba, uint8_t i_por if (rc_num) { FAPI_ERR( "config_drv_imp: Error in setting up buffer "); - rc_buff.setEcmdError(rc_num); - return rc_buff; + rc.setEcmdError(rc_num); + return rc; } rc = fapiPutScom(i_target_mba, DPHY01_DDRPHY_DP18_IO_TX_NFET_TERM_P0_0_0x8000007A0301143F, @@ -351,8 +350,8 @@ fapi::ReturnCode config_rcv_imp(const fapi::Target & i_target_mba, uint8_t i_por if (rc_num) { FAPI_ERR( "config_drv_imp: Error in setting up buffer "); - rc_buff.setEcmdError(rc_num); - return rc_buff; + rc.setEcmdError(rc_num); + return rc; } rc = fapiPutScom(i_target_mba, DPHY01_DDRPHY_DP18_IO_TX_NFET_TERM_P1_0_0x8001007A0301143F, @@ -404,7 +403,6 @@ fapi::ReturnCode config_slew_rate(const fapi::Target & i_target_mba, const uint8_t i_slew_rate) { fapi::ReturnCode rc; - fapi::ReturnCode rc_buff; ecmdDataBufferBase data_buffer(64); uint32_t rc_num = 0; uint8_t slew_cal_value = 0; @@ -507,8 +505,8 @@ fapi::ReturnCode config_slew_rate(const fapi::Target & i_target_mba, if (rc_num) { FAPI_ERR("Error in setting up DATA slew buffer"); - rc_buff.setEcmdError(rc_num); - return rc_buff; + rc.setEcmdError(rc_num); + return rc; } rc = fapiPutScom(i_target_mba, @@ -537,8 +535,8 @@ fapi::ReturnCode config_slew_rate(const fapi::Target & i_target_mba, if (rc_num) { FAPI_ERR( "Error in setting up DATA slew buffer"); - rc_buff.setEcmdError(rc_num); - return rc_buff; + rc.setEcmdError(rc_num); + return rc; } rc = fapiPutScom(i_target_mba, @@ -633,8 +631,8 @@ fapi::ReturnCode config_slew_rate(const fapi::Target & i_target_mba, if (rc_num) { FAPI_ERR( "Error in setting up ADR slew buffer"); - rc_buff.setEcmdError(rc_num); - return rc_buff; + rc.setEcmdError(rc_num); + return rc; } rc = fapiPutScom(i_target_mba, @@ -660,8 +658,8 @@ fapi::ReturnCode config_slew_rate(const fapi::Target & i_target_mba, if (rc_num) { FAPI_ERR( "Error in setting up ADR slew buffer"); - rc_buff.setEcmdError(rc_num); - return rc_buff; + rc.setEcmdError(rc_num); + return rc; } rc = fapiPutScom(i_target_mba, DPHY01_DDRPHY_ADR_IO_SLEW_CTL_VALUE_P1_ADR0_0x8001401A0301143F, @@ -697,7 +695,7 @@ fapi::ReturnCode config_wr_dram_vref(const fapi::Target & i_target_mba, uint8_t { ecmdDataBufferBase data_buffer(64); - fapi::ReturnCode rc, rc_buff; + fapi::ReturnCode rc; uint32_t rc_num = 0; uint32_t pcvref = 0; uint32_t i = 0; @@ -727,8 +725,8 @@ fapi::ReturnCode config_wr_dram_vref(const fapi::Target & i_target_mba, uint8_t if (rc_num) { FAPI_ERR( "config_wr_vref: Error in setting up buffer "); - rc_buff.setEcmdError(rc_num); - return rc_buff; + rc.setEcmdError(rc_num); + return rc; } rc = fapiPutScom(i_target_mba, DPHY01_DDRPHY_PC_VREF_DRV_CONTROL_P0_0x8000C0150301143F, data_buffer); if(rc) return rc; } @@ -740,8 +738,8 @@ fapi::ReturnCode config_wr_dram_vref(const fapi::Target & i_target_mba, uint8_t if (rc_num) { FAPI_ERR( "config_wr_vref: Error in setting up buffer "); - rc_buff.setEcmdError(rc_num); - return rc_buff; + rc.setEcmdError(rc_num); + return rc; } rc = fapiPutScom(i_target_mba, DPHY01_DDRPHY_PC_VREF_DRV_CONTROL_P1_0x8001C0150301143F, data_buffer); if(rc) return rc; } @@ -766,7 +764,7 @@ fapi::ReturnCode config_rd_cen_vref (const fapi::Target & i_target_mba, uint8_t { ecmdDataBufferBase data_buffer(64); - fapi::ReturnCode rc, rc_buff; + fapi::ReturnCode rc; uint32_t rc_num = 0; uint32_t rd_vref = 0; @@ -794,8 +792,8 @@ fapi::ReturnCode config_rd_cen_vref (const fapi::Target & i_target_mba, uint8_t if (rc_num) { FAPI_ERR( "config_rd_vref: Error in setting up buffer "); - rc_buff.setEcmdError(rc_num); - return rc_buff; + rc.setEcmdError(rc_num); + return rc; } rc = fapiPutScom(i_target_mba, DPHY01_DDRPHY_DP18_RX_PEAK_AMP_P0_0_0x800000060301143F, @@ -822,8 +820,8 @@ fapi::ReturnCode config_rd_cen_vref (const fapi::Target & i_target_mba, uint8_t if (rc_num) { FAPI_ERR( "config_rd_vref: Error in setting up buffer "); - rc_buff.setEcmdError(rc_num); - return rc_buff; + rc.setEcmdError(rc_num); + return rc; } rc = fapiPutScom(i_target_mba, DPHY01_DDRPHY_DP18_RX_PEAK_AMP_P1_0_0x800100060301143F, @@ -855,7 +853,7 @@ fapi::ReturnCode mss_slew_cal(const fapi::Target &i_target) { fapi::ReturnCode rc; uint32_t rc_ecmd = 0; - std::vector<fapi::ReturnCode> vector_rcs; // to capture rc's on port loop + fapi::ReturnCode array_rcs[MAX_NUM_PORTS]={fapi::FAPI_RC_SUCCESS}; // capture rc per port loop uint32_t poll_count = 0; uint8_t ports_valid = 0; uint8_t is_sim = 0; @@ -1008,15 +1006,15 @@ fapi::ReturnCode mss_slew_cal(const fapi::Target &i_target) FAPI_INF("Enabling slew calibration engine... dram=DDR%i(%u), freq=%u(%u)", (ddr_type+2), ddr_idx, ddr_freq, freq_idx); - vector_rcs.clear(); // clear rc vector for (uint8_t l_port=0; l_port < MAX_NUM_PORTS; l_port++) { uint8_t port_val = (ports_valid & (0xF0 >> (4 * l_port))); if (port_val == 0) { FAPI_INF("WARNING: Port %u is invalid from " - "ATTR_MSS_EFF_DIMM_FUNCTIONAL_VECTOR, 0x%02x", + "ATTR_MSS_EFF_DIMM_FUNCTIONAL_VECTOR (0x%02x), skipping.", l_port, ports_valid); + continue; } // Step A: Configure ADR registers and MCLK detect (done in ddr_phy_reset) // DPHY01_DDRPHY_ADR_SLEW_CAL_CNTL_P0_ADR32S0_0x800080390301143F + port @@ -1024,9 +1022,7 @@ fapi::ReturnCode mss_slew_cal(const fapi::Target &i_target) if (rc) { FAPI_ERR("Error reading DDRPHY_ADR_SLEW_CAL_CNTL register."); - //return rc; - vector_rcs.push_back(rc); - continue; + return rc; } rc_ecmd = ctl_reg.flushTo0(); @@ -1036,9 +1032,7 @@ fapi::ReturnCode mss_slew_cal(const fapi::Target &i_target) FAPI_ERR("Error setting enable bit in ADR Slew calibration " "control register."); rc.setEcmdError(rc_ecmd); - //return rc; - vector_rcs.push_back(rc); - continue; + return rc; } // DPHY01_DDRPHY_ADR_SLEW_CAL_CNTL_P0_ADR32S0_0x800080390301143F + port @@ -1047,9 +1041,7 @@ fapi::ReturnCode mss_slew_cal(const fapi::Target &i_target) { FAPI_ERR("Error enabling slew calibration engine in " "DDRPHY_ADR_SLEW_CAL_CNTL register."); - //return rc; - vector_rcs.push_back(rc); - continue; + return rc; } //---------------------------------------------------------------------/ @@ -1060,9 +1052,7 @@ fapi::ReturnCode mss_slew_cal(const fapi::Target &i_target) rc = fapiDelay(DELAY_100NS, DELAY_SIMCYCLES); if (rc) { FAPI_ERR("Error executing fapiDelay of 100ns or 2000simcycles"); - //return rc; - vector_rcs.push_back(rc); - continue; + return rc; } // DPHY01_DDRPHY_ADR_SYSCLK_PR_VALUE_RO_P0_ADR32S0_0x800080340301143F + port rc = fapiGetScom(i_target, slew_cal_stat[l_port], stat_reg); @@ -1070,9 +1060,7 @@ fapi::ReturnCode mss_slew_cal(const fapi::Target &i_target) { FAPI_ERR("Error reading DDRPHY_ADR_SYSCLK_PR_VALUE_RO register " "for BB_Lock."); - //return rc; - vector_rcs.push_back(rc); - continue; + return rc; } FAPI_DBG("stat_reg = 0x%04x, count=%i",stat_reg.getHalfWord(3), poll_count); @@ -1112,9 +1100,7 @@ fapi::ReturnCode mss_slew_cal(const fapi::Target &i_target) { FAPI_ERR("Error setting start bit or cal input value."); rc.setEcmdError(rc_ecmd); - //return rc; - vector_rcs.push_back(rc); - continue; + return rc; } // DPHY01_DDRPHY_ADR_SLEW_CAL_CNTL_P0_ADR32S0_0x800080390301143F + port @@ -1125,9 +1111,7 @@ fapi::ReturnCode mss_slew_cal(const fapi::Target &i_target) if (rc) { FAPI_ERR("Error starting slew calibration."); - //return rc; - vector_rcs.push_back(rc); - continue; + return rc; } // poll for calibration status done or timeout... @@ -1144,18 +1128,14 @@ fapi::ReturnCode mss_slew_cal(const fapi::Target &i_target) FAPI_ERR("Error reading " "DDRPHY_ADR_SYSCLK_PR_VALUE_RO " "register for calibration status."); - //return rc; - vector_rcs.push_back(rc); - continue; + return rc; } rc_ecmd = stat_reg.extractToRight(&cal_status, 58, 2); if (rc_ecmd) { FAPI_ERR("Error getting calibration status bits"); rc.setEcmdError(rc_ecmd); - //return rc; - vector_rcs.push_back(rc); - continue; + return rc; } FAPI_DBG("cal_status = %i",cal_status); if (cal_status != 0) @@ -1164,9 +1144,7 @@ fapi::ReturnCode mss_slew_cal(const fapi::Target &i_target) rc = fapiDelay(DELAY_100NS, DELAY_SIMCYCLES); if(rc) { - //return rc; - vector_rcs.push_back(rc); - continue; + return rc; } } @@ -1181,22 +1159,20 @@ fapi::ReturnCode mss_slew_cal(const fapi::Target &i_target) FAPI_ERR("Error getting calibration output " "slew value"); rc.setEcmdError(rc_ecmd); - //return rc; - vector_rcs.push_back(rc); - continue; + return rc; } calibrated_slew[data_adr][l_port][imp][slew] = cal_slew; } else if (cal_status == 2) { - FAPI_ERR("warning occurred during slew " + FAPI_INF("WARNING: occurred during slew " "calibration, continuing..."); } else { if (cal_status == 1) { - FAPI_ERR("error occurred during slew calibration"); + FAPI_ERR("Error occurred during slew calibration"); } else { @@ -1221,7 +1197,7 @@ fapi::ReturnCode mss_slew_cal(const fapi::Target &i_target) { FAPI_SET_HWP_ERROR(rc, RC_MSS_SLEW_CAL_ERROR); //return rc; - vector_rcs.push_back(rc); + array_rcs[l_port]=rc; continue; } } // end error check @@ -1236,14 +1212,17 @@ fapi::ReturnCode mss_slew_cal(const fapi::Target &i_target) { FAPI_ERR("Error disabling slew calibration engine in " "DDRPHY_ADR_SLEW_CAL_CNTL register."); - //return rc; - vector_rcs.push_back(rc); + return rc; } } // end port loop - if (vector_rcs.size() != 0) + for (uint8_t rn=0; rn < MAX_NUM_PORTS; rn++) { - return vector_rcs.front(); // return first RC encountered + if (array_rcs[rn] != fapi::FAPI_RC_SUCCESS) + { + FAPI_ERR("Returning ERROR RC for port %u",rn); + return array_rcs[rn]; + } } FAPI_INF("Setting output slew tables ATTR_MSS_SLEW_RATE_DATA/ADR"); // ATTR_MSS_SLEW_RATE_DATA [2][4][4] port, imped, slew_rate diff --git a/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.H b/src/usr/hwpf/hwp/dram_training/mss_termination_control.H index 68e2b8fea..7e6402d72 100644 --- a/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.H +++ b/src/usr/hwpf/hwp/dram_training/mss_termination_control.H @@ -1,7 +1,7 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.H $ */ +/* $Source: src/usr/hwpf/hwp/dram_training/mss_termination_control.H $ */ /* */ /* IBM CONFIDENTIAL */ /* */ @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_termination_control.H,v 1.9 2012/12/06 19:17:47 sasethur Exp $
+// $Id: mss_termination_control.H,v 1.10 2012/12/14 16:17:07 sasethur Exp $
/* File is created by SARAVANAN SETHURAMAN on Thur Sept 28 2011. */
//------------------------------------------------------------------------------
@@ -43,6 +43,7 @@ //------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|---------- |--------- |---------------------------------------------
+// 1.10 | 14-Dec-12 | sasethur | Updated for fw review comments
// 1.9 | 07-Dec-12 | sasethur | Updated for fw review comments
// 1.8 | 16-Nov-12 | mwuu | Added typedef for external call of
// mss_slew_cal F
@@ -262,8 +263,8 @@ fapi::ReturnCode config_rd_cen_vref(const fapi::Target & i_target_mba, uint8_t i fapi::ReturnCode config_drv_imp(const fapi::Target & i_target_mba, uint8_t i_port, uint8_t l_drv_imp_dq_dqs);
fapi::ReturnCode config_rcv_imp(const fapi::Target & i_target_mba, uint8_t i_port, uint8_t l_rcv_imp_dq_dqs);
fapi::ReturnCode config_slew_rate(const fapi::Target & i_target_mba,
- const uint8_t i_port, const uint8_t l_slew_type, const uint8_t l_slew_imp,
- const uint8_t l_slew_rate);
+ const uint8_t i_port, const uint8_t i_slew_type, const uint8_t i_slew_imp,
+ const uint8_t i_slew_rate);
fapi::ReturnCode mss_slew_cal(const fapi::Target & i_target_mba);
} // extern C
#endif
|