diff options
-rw-r--r-- | src/include/usr/hwpf/hwp/dram_initialization/mss_memdiag/mss_maint_cmds.H (renamed from src/usr/hwpf/hwp/dram_initialization/mss_memdiag/mss_maint_cmds.H) | 136 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/dram_initialization/makefile | 2 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/dram_initialization/mss_memdiag/mss_maint_cmds.C | 2354 |
3 files changed, 1799 insertions, 693 deletions
diff --git a/src/usr/hwpf/hwp/dram_initialization/mss_memdiag/mss_maint_cmds.H b/src/include/usr/hwpf/hwp/dram_initialization/mss_memdiag/mss_maint_cmds.H index 642dc341b..c45791c18 100644 --- a/src/usr/hwpf/hwp/dram_initialization/mss_memdiag/mss_maint_cmds.H +++ b/src/include/usr/hwpf/hwp/dram_initialization/mss_memdiag/mss_maint_cmds.H @@ -1,7 +1,7 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/usr/hwpf/hwp/dram_initialization/mss_memdiag/mss_maint_cmds.H $ */ +/* $Source: src/include/usr/hwpf/hwp/dram_initialization/mss_memdiag/mss_maint_cmds.H $ */ /* */ /* IBM CONFIDENTIAL */ /* */ @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_maint_cmds.H,v 1.10 2012/09/07 21:32:14 gollub Exp $ +// $Id: mss_maint_cmds.H,v 1.14 2012/11/21 21:21:42 gollub Exp $ //------------------------------------------------------------------------------ // Don't forget to create CVS comments when you check in your changes! //------------------------------------------------------------------------------ @@ -44,6 +44,10 @@ // | | | save/restore of setting for super fast read // 1.10 | 09/07/12 | gollub | Updates from review. // | | | Support for more patterns. +// 1.11 | 09/28/12 | gollub | Added mss_restore_DRAM_repairs +// 1.12 | 11/02/12 | gollub | Updates from review. +// 1.13 | 11/08/12 | gollub | Added timebase steer cleanup +// 1.14 | 11/21/12 | gollub | Updates from review. #ifndef _MSS_MAINT_CMDS_H @@ -73,6 +77,14 @@ */ const uint8_t MSS_ALL_RANKS = 0xff; + +/** + * @brief Used to indicate invalid symbol + */ +const uint8_t MSS_INVALID_SYMBOL = 0xff; + + + namespace mss_SteerMux { @@ -97,6 +109,7 @@ namespace mss_SteerMux }; + //------------------------------------------------------------------------------ // Parent class for all maintenance command types //------------------------------------------------------------------------------ @@ -725,6 +738,64 @@ class mss_TimeBaseScrub : public mss_MaintCmd }; +//------------------------------------------------------------------------------ +// mss_TimeBaseSteerCleanup +//------------------------------------------------------------------------------ +class mss_TimeBaseSteerCleanup : public mss_MaintCmd +{ + public: // Constructor(s) + + mss_TimeBaseSteerCleanup( const fapi::Target & i_target, // MBA target + const ecmdDataBufferBase & i_startAddr, // Address cmd will start at + const ecmdDataBufferBase & i_endAddr, // Address cmd will stop at + TimeBaseSpeed i_speed, // TODO: fast for runtime, faster for ipl? + uint32_t i_stopCondition, // Mask of error conditions cmd should stop on + bool i_poll ); // Set to true if you wait for command to complete + + public: + + fapi::ReturnCode setupAndExecuteCmd(); + fapi::ReturnCode stopCmd(); + CmdType getCmdType() const { return cv_cmdType; } + + // This class's implementation of parent class functions that can be + // overridden. + fapi::ReturnCode cleanupCmd(); + + + + void setStartAddr(ecmdDataBufferBase i_startAddr) + { iv_startAddr = i_startAddr; } + + void setEndAddr( ecmdDataBufferBase i_endAddr ) + { iv_endAddr = i_endAddr; } + + ecmdDataBufferBase getStartAddr() const { return iv_startAddr; } + ecmdDataBufferBase getEndAddr() const { return iv_endAddr; } + + private: + + fapi::ReturnCode setSavedData( uint32_t i_savedData ) + {fapi::ReturnCode l_rc; iv_savedData = i_savedData; return l_rc; } + + uint32_t getSavedData() { return iv_savedData; } + + private: // Class variable(s) + + static const CmdType cv_cmdType; + + private: // Instance variable(s) + + // list of things to save may be specific to each cmd, so keep it + // here for now + uint32_t iv_savedData; + + // TODO: Want as fast as possible, but IPL may be able to go faster than + // runtime since no fetch traffic to worry about. + TimeBaseSpeed iv_speed; +}; + + //------------------------------------------------------------------------------ // Utility funcitons @@ -798,6 +869,8 @@ fapi::ReturnCode mss_put_mark_store( const fapi::Target & i_target, * * @param i_target MBA target * @param i_rank Rank we want to read steer mux for. + * @param i_muxType Select either the read mux or the write mux + * to get. * @param o_dramSparePort0Symbol First symbol index of the DRAM fixed by the * spare on port0 (if no steer, return 0xff) * @param o_dramSparePort1Symbol First symbol index of the DRAM fixed by the @@ -823,9 +896,9 @@ fapi::ReturnCode mss_get_steer_mux( const fapi::Target & i_target, * @param i_rank Rank we want to write steer mux for. * @param i_muxType Select either the read mux or the write mux * to update. - * @param i_steerType DRAM_SPARE_PORT0, Spare DRAM on port0 - * DRAM_SPARE_PORT1, Spare DRAM on port1 - * ECC_SPARE, ECC spare (used in x4 mode only) + * @param i_steerType 0 = DRAM_SPARE_PORT0, Spare DRAM on port0 + * 1 = DRAM_SPARE_PORT1, Spare DRAM on port1 + * 2 = ECC_SPARE, ECC spare (used in x4 mode only) * @param i_symbol First symbol index of the DRAM to steer * around. * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. @@ -833,10 +906,61 @@ fapi::ReturnCode mss_get_steer_mux( const fapi::Target & i_target, fapi::ReturnCode mss_put_steer_mux( const fapi::Target & i_target, uint8_t i_rank, mss_SteerMux::muxType i_muxType, - mss_SteerMux::steerType i_steerType, + uint8_t i_steerType, uint8_t i_symbol ); +/** + * @brief This procedure applies the maximum possible DRAM repairs + * (chip/symbol marks, DRAM steers) to known bad bits recorded in + * DIMM VPD. This operation is done on both valid logical DIMM pairs + * behind the given MBA. + * + * @param i_target MBA target + * @param o_repairs_applied 8-bit mask, where a bit set means the + * specified rank had any repairs applied. + * + * rank0 = 0x80 (maps to port0_dimm0, port1_dimm0) + * rank1 = 0x40 (maps to port0_dimm0, port1_dimm0) + * rank2 = 0x20 (maps to port0_dimm0, port1_dimm0) + * rank3 = 0x10 (maps to port0_dimm0, port1_dimm0) + * rank4 = 0x08 (maps to port0_dimm1, port1_dimm1) + * rank5 = 0x04 (maps to port0_dimm1, port1_dimm1) + * rank6 = 0x02 (maps to port0_dimm1, port1_dimm1) + * rank7 = 0x01 (maps to port0_dimm1, port1_dimm1) + * + * @param o_repairs_exceeded 4-bit mask, where a bit set means the + * specified DIMM-select on the specified port + * had more bad bits than could be repaired. + * + * port0_dimm0 = 0x8 + * port0_dimm1 = 0x4 + * port1_dimm0 = 0x2 + * port1_dimm1 = 0x1 + * + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + */ +fapi::ReturnCode mss_restore_DRAM_repairs( const fapi::Target & i_target, + uint8_t & o_repairs_applied, + uint8_t & o_repairs_exceeded); + + + +/** + * @brief This function takes converts from a Centaur DQ on a given port + * to a corresponding symbol index. + * + * @param i_dq Centaur DQ from 0-71 + * + * @param i_port port 0 or 1 + * + * @return Symbol index + */ + +uint8_t mss_centaurDQ_to_symbol( uint8_t i_dq, uint8_t i_port ); + + + #endif /* _MSS_MAINT_CMDS_H */ diff --git a/src/usr/hwpf/hwp/dram_initialization/makefile b/src/usr/hwpf/hwp/dram_initialization/makefile index 9e1f6e2f3..cc1c2a5c0 100644 --- a/src/usr/hwpf/hwp/dram_initialization/makefile +++ b/src/usr/hwpf/hwp/dram_initialization/makefile @@ -48,7 +48,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_initialization/mss_memdiag EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_initialization/proc_pcie_config EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_initialization/host_mpipl_service EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_initialization/mss_thermal_init - +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/hwpf/hwp/dram_initialization/mss_memdiag ## NOTE: add new object files when you add a new HWP OBJS = dram_initialization.o \ diff --git a/src/usr/hwpf/hwp/dram_initialization/mss_memdiag/mss_maint_cmds.C b/src/usr/hwpf/hwp/dram_initialization/mss_memdiag/mss_maint_cmds.C index 8a6ccdc37..038ac5864 100644 --- a/src/usr/hwpf/hwp/dram_initialization/mss_memdiag/mss_maint_cmds.C +++ b/src/usr/hwpf/hwp/dram_initialization/mss_memdiag/mss_maint_cmds.C @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_maint_cmds.C,v 1.11 2012/09/07 22:35:07 gollub Exp $ +// $Id: mss_maint_cmds.C,v 1.16 2012/11/21 21:21:08 gollub Exp $ //------------------------------------------------------------------------------ // Don't forget to create CVS comments when you check in your changes! //------------------------------------------------------------------------------ @@ -48,13 +48,21 @@ // | | | to disable rrq fifo mode when done. // 1.11 | 09/07/12 | gollub | Updates from review. // | | | Support for more patterns. +// 1.12 | 09/29/12 | gollub | Added mss_restore_DRAM_repairs +// 1.13 | 10/08/12 | gollub | Updated with 12h scrub rate calculation +// 1.14 | 11/02/12 | gollub | Updates from review. +// 1.15 | 11/08/12 | gollub | Added timebase steer cleanup +// | | | Updates to traces. +// 1.16 | 11/21/12 | gollub | Updates from review. //------------------------------------------------------------------------------ -// Includes +// Includes //------------------------------------------------------------------------------ #include <mss_maint_cmds.H> #include <cen_scom_addresses.H> +#include <dimmBadDqBitmapFuncs.H> + using namespace fapi; @@ -91,10 +99,10 @@ const uint8_t MSS_X4_STEER_OPTIONS_PER_PORT1 = 18; /** * @brief 18 on port0, 17 on port1, plus one no steer option - * NOTE: Can's use ECC spare to fix bad spare DRAMs - */ -const uint8_t MSS_X4_ECC_STEER_OPTIONS = 36; - + * NOTE: Can's use ECC spare to fix bad spare DRAMs + */ +const uint8_t MSS_X4_ECC_STEER_OPTIONS = 36; + /** * @brief Max 8 patterns */ @@ -118,23 +126,35 @@ namespace mss_MemConfig */ enum DramWidth { - X8 = 0, - X4 = 1, + X4 = fapi::ENUM_ATTR_EFF_DRAM_WIDTH_X4, + X8 = fapi::ENUM_ATTR_EFF_DRAM_WIDTH_X8, }; /** - * @brief DRAM row, column, and bank bits, used to determine address range + * @brief DRAM row, column, and bank bits, used to determine address range * for maint cmds */ enum MemOrg { ROW_15 = 0x00007FFF, ROW_16 = 0x0000FFFF, - COL_10 = 0x000003F8, // c2, c1, c0 always 0 - COL_11 = 0x000007F8, // c2, c1, c0 always 0 - COL_12 = 0x00000FF8, // c2, c1, c0 always 0 + COL_10 = 0x000003F8, // c2, c1, c0 always 0 + COL_11 = 0x000007F8, // c2, c1, c0 always 0 + COL_12 = 0x00000FF8, // c2, c1, c0 always 0 BANK_3 = 0x00000007, }; + +/** + * @brief Spare DRAM config, used to identify what spares exist + */ + enum SpareDramConfig + { + NO_SPARE = 0, + LOW_NIBBLE = 1, // x4 spare (low nibble: default) + HIGH_NIBBLE = 2, // x4 spare (high nibble: no plan to use) + FULL_BYTE = 3 // x8 dpare + }; + }; @@ -162,19 +182,19 @@ static const uint32_t mss_markStoreRegs[8][2]={ {MBS_ECC0_MBMS5_0x02011450, MBS_ECC1_MBMS5_0x02011490}, {MBS_ECC0_MBMS6_0x02011451, MBS_ECC1_MBMS6_0x02011491}, {MBS_ECC0_MBMS7_0x02011452, MBS_ECC1_MBMS7_0x02011492}}; - + static const uint32_t mss_readMuxRegs[8][2]={ // port0/1 port2/3 {MBS_ECC0_MBSBS0_0x0201145E, MBS_ECC1_MBSBS0_0x0201149E}, {MBS_ECC0_MBSBS1_0x0201145F, MBS_ECC1_MBSBS1_0x0201149F}, - {MBS_ECC0_MBSBS2_0x02011460, MBS_ECC1_MBSBS2_0x020114A0}, + {MBS_ECC0_MBSBS2_0x02011460, MBS_ECC1_MBSBS2_0x020114A0}, {MBS_ECC0_MBSBS3_0x02011461, MBS_ECC1_MBSBS3_0x020114A1}, {MBS_ECC0_MBSBS4_0x02011462, MBS_ECC1_MBSBS4_0x020114A2}, {MBS_ECC0_MBSBS5_0x02011463, MBS_ECC1_MBSBS5_0x020114A3}, {MBS_ECC0_MBSBS6_0x02011464, MBS_ECC1_MBSBS6_0x020114A4}, - {MBS_ECC0_MBSBS7_0x02011465, MBS_ECC1_MBSBS7_0x020114A5}}; + {MBS_ECC0_MBSBS7_0x02011465, MBS_ECC1_MBSBS7_0x020114A5}}; -static const uint32_t mss_writeMuxRegs[8]={ +static const uint32_t mss_writeMuxRegs[8]={ MBA01_MBABS0_0x03010440, MBA01_MBABS1_0x03010441, @@ -200,10 +220,12 @@ static const uint8_t mss_symbol2Galois[MSS_SYMBOLS_PER_RANK] = 0x5e, 0x21, 0xa5, 0x3d, 0x5b, 0x23, 0xaf, 0x3e, // symbols 56-63 0xfe, 0x61, 0x75, 0x5d, 0x51, 0x27, 0xa2, 0x38, // symbols 64-71 }; - + + + static const uint8_t mss_x8dramSparePort0Index_to_symbol[MSS_X8_STEER_OPTIONS_PER_PORT]={ // symbol - 0xff, // Port0 DRAM spare not used + MSS_INVALID_SYMBOL, // Port0 DRAM spare not used 68, // DRAM 17 (x8) 64, // DRAM 16 (x8) 60, // DRAM 15 (x8) @@ -216,7 +238,7 @@ static const uint8_t mss_x8dramSparePort0Index_to_symbol[MSS_X8_STEER_OPTIONS_PE static const uint8_t mss_x4dramSparePort0Index_to_symbol[MSS_X4_STEER_OPTIONS_PER_PORT0]={ // symbol - 0xff, // Port0 DRAM spare not used + MSS_INVALID_SYMBOL, // Port0 DRAM spare not used 70, // DRAM 35 (x4) 68, // DRAM 34 (x4) 66, // DRAM 33 (x4) @@ -225,7 +247,7 @@ static const uint8_t mss_x4dramSparePort0Index_to_symbol[MSS_X4_STEER_OPTIONS_PE 60, // DRAM 30 (x4) 58, // DRAM 29 (x4) 56, // DRAM 28 (x4) - 54, // DRAM 27 (x4) + 54, // DRAM 27 (x4) 52, // DRAM 26 (x4) 50, // DRAM 25 (x4) 48, // DRAM 24 (x4) @@ -240,7 +262,7 @@ static const uint8_t mss_x4dramSparePort0Index_to_symbol[MSS_X4_STEER_OPTIONS_PE static const uint8_t mss_x8dramSparePort1Index_to_symbol[MSS_X8_STEER_OPTIONS_PER_PORT]={ // symbol - 0xff, // Port1 DRAM spare not used + MSS_INVALID_SYMBOL, // Port1 DRAM spare not used 36, // DRAM 9 (x8) 32, // DRAM 8 (x8) 28, // DRAM 7 (x8) @@ -255,7 +277,7 @@ static const uint8_t mss_x8dramSparePort1Index_to_symbol[MSS_X8_STEER_OPTIONS_PE static const uint8_t mss_x4dramSparePort1Index_to_symbol[MSS_X4_STEER_OPTIONS_PER_PORT1]={ // symbol - 0xff, // Port1 DRAM spare not used + MSS_INVALID_SYMBOL, // Port1 DRAM spare not used 38, // DRAM 19 (x4) 36, // DRAM 18 (x4) 34, // DRAM 17 (x4) @@ -264,7 +286,7 @@ static const uint8_t mss_x4dramSparePort1Index_to_symbol[MSS_X4_STEER_OPTIONS_PE 28, // DRAM 14 (x4) 26, // DRAM 13 (x4) 24, // DRAM 12 (x4) - 22, // DRAM 11 (x4) + 22, // DRAM 11 (x4) 20, // DRAM 10 (x4) 18, // DRAM 9 (x4) 16, // DRAM 8 (x4) @@ -273,14 +295,14 @@ static const uint8_t mss_x4dramSparePort1Index_to_symbol[MSS_X4_STEER_OPTIONS_PE 10, // DRAM 5 (x4) 8, // DRAM 4 (x4) 2}; // DRAM 1 (x4) - // NOTE: DRAM 0 (x4) (symbols 0,1) on Port1 is used for the ECC spare, + // NOTE: DRAM 0 (x4) (symbols 0,1) on Port1 is used for the ECC spare, // so can't use DRAM spare to fix DRAM 0. static const uint8_t mss_eccSpareIndex_to_symbol[MSS_X4_ECC_STEER_OPTIONS]={ // symbol - 0xff, // ECC spare not used + MSS_INVALID_SYMBOL, // ECC spare not used 70, // DRAM 35 (x4) 68, // DRAM 34 (x4) 66, // DRAM 33 (x4) @@ -323,39 +345,39 @@ static const uint8_t mss_eccSpareIndex_to_symbol[MSS_X4_ECC_STEER_OPTIONS]={ static const uint32_t mss_maintBufferData[MSS_MAX_PATTERNS][16][2]={ // PATTERN_0 - {{0x00000000, 0x00000000}, - {0x00000000, 0x00000000}, - {0x00000000, 0x00000000}, - {0x00000000, 0x00000000}, - {0x00000000, 0x00000000}, - {0x00000000, 0x00000000}, - {0x00000000, 0x00000000}, - {0x00000000, 0x00000000}, - {0x00000000, 0x00000000}, - {0x00000000, 0x00000000}, - {0x00000000, 0x00000000}, - {0x00000000, 0x00000000}, - {0x00000000, 0x00000000}, - {0x00000000, 0x00000000}, - {0x00000000, 0x00000000}, - {0x00000000, 0x00000000}}, + {{0x00000000, 0x00000000}, + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000}, + {0x00000000, 0x00000000}}, // PATTERN_1 - {{0xffffffff, 0xffffffff}, - {0xffffffff, 0xffffffff}, - {0xffffffff, 0xffffffff}, - {0xffffffff, 0xffffffff}, - {0xffffffff, 0xffffffff}, - {0xffffffff, 0xffffffff}, - {0xffffffff, 0xffffffff}, - {0xffffffff, 0xffffffff}, - {0xffffffff, 0xffffffff}, - {0xffffffff, 0xffffffff}, - {0xffffffff, 0xffffffff}, - {0xffffffff, 0xffffffff}, - {0xffffffff, 0xffffffff}, - {0xffffffff, 0xffffffff}, - {0xffffffff, 0xffffffff}, + {{0xffffffff, 0xffffffff}, + {0xffffffff, 0xffffffff}, + {0xffffffff, 0xffffffff}, + {0xffffffff, 0xffffffff}, + {0xffffffff, 0xffffffff}, + {0xffffffff, 0xffffffff}, + {0xffffffff, 0xffffffff}, + {0xffffffff, 0xffffffff}, + {0xffffffff, 0xffffffff}, + {0xffffffff, 0xffffffff}, + {0xffffffff, 0xffffffff}, + {0xffffffff, 0xffffffff}, + {0xffffffff, 0xffffffff}, + {0xffffffff, 0xffffffff}, + {0xffffffff, 0xffffffff}, {0xffffffff, 0xffffffff}}, // PATTERN_2 @@ -374,10 +396,10 @@ static const uint32_t mss_maintBufferData[MSS_MAX_PATTERNS][16][2]={ {0xf0f0f0f0, 0xf0f0f0f0}, {0xf0f0f0f0, 0xf0f0f0f0}, {0xf0f0f0f0, 0xf0f0f0f0}, - {0xf0f0f0f0, 0xf0f0f0f0}}, - + {0xf0f0f0f0, 0xf0f0f0f0}}, + // PATTERN_3 - {{0x0f0f0f0f, 0x0f0f0f0f}, + {{0x0f0f0f0f, 0x0f0f0f0f}, {0x0f0f0f0f, 0x0f0f0f0f}, {0x0f0f0f0f, 0x0f0f0f0f}, {0x0f0f0f0f, 0x0f0f0f0f}, @@ -395,7 +417,7 @@ static const uint32_t mss_maintBufferData[MSS_MAX_PATTERNS][16][2]={ {0x0f0f0f0f, 0x0f0f0f0f}}, // PATTERN_4 - {{0xaaaaaaaa, 0xaaaaaaaa}, + {{0xaaaaaaaa, 0xaaaaaaaa}, {0xaaaaaaaa, 0xaaaaaaaa}, {0xaaaaaaaa, 0xaaaaaaaa}, {0xaaaaaaaa, 0xaaaaaaaa}, @@ -413,7 +435,7 @@ static const uint32_t mss_maintBufferData[MSS_MAX_PATTERNS][16][2]={ {0xaaaaaaaa, 0xaaaaaaaa}}, // PATTERN_5 - {{0x55555555, 0x55555555}, + {{0x55555555, 0x55555555}, {0x55555555, 0x55555555}, {0x55555555, 0x55555555}, {0x55555555, 0x55555555}, @@ -428,7 +450,7 @@ static const uint32_t mss_maintBufferData[MSS_MAX_PATTERNS][16][2]={ {0x55555555, 0x55555555}, {0x55555555, 0x55555555}, {0x55555555, 0x55555555}, - {0x55555555, 0x55555555}}, + {0x55555555, 0x55555555}}, // PATTERN_6 {{0xcccccccc, 0xcccccccc}, @@ -572,9 +594,9 @@ fapi::ReturnCode mss_MaintCmd::preConditionCheck() ecmdDataBufferBase l_mbaxcr(64); ecmdDataBufferBase l_ccs_modeq(64); ecmdDataBufferBase l_mbsecc(64); - + FAPI_INF("ENTER mss_MaintCmd::preConditionCheck()"); - + // Get Centaur target for the given MBA l_rc = fapiGetParentChip(iv_target, iv_targetCentaur); if(l_rc) @@ -582,34 +604,33 @@ fapi::ReturnCode mss_MaintCmd::preConditionCheck() FAPI_ERR("Error getting Centaur parent target for the given MBA"); return l_rc; } - - + // Get MBA position: 0 = mba01, 1 = mba23 l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &iv_target, iv_mbaPosition); if(l_rc) { FAPI_ERR("Error getting MBA position"); return l_rc; - } + } - // Read MBMCCQ - l_rc = fapiGetScom(iv_target, MBA01_MBMCCQ_0x0301060B, l_mbmccq); + // Read MBMCCQ + l_rc = fapiGetScom(iv_target, MBA01_MBMCCQ_0x0301060B, l_mbmccq); if(l_rc) return l_rc; // Read MBMSRQ - l_rc = fapiGetScom(iv_target, MBA01_MBMSRQ_0x0301060C, l_mbmsrq); + l_rc = fapiGetScom(iv_target, MBA01_MBMSRQ_0x0301060C, l_mbmsrq); if(l_rc) return l_rc; - + // Read MBAXCRn - l_rc = fapiGetScom(iv_targetCentaur, mss_mbaxcr[iv_mbaPosition], l_mbaxcr); + l_rc = fapiGetScom(iv_targetCentaur, mss_mbaxcr[iv_mbaPosition], l_mbaxcr); if(l_rc) return l_rc; - + // Read CCS_MODEQ l_rc = fapiGetScom(iv_target, MEM_MBA01_CCS_MODEQ_0x030106A7, l_ccs_modeq); if(l_rc) return l_rc; - + // Read MBSECC - l_rc = fapiGetScom(iv_targetCentaur, mss_mbsecc[iv_mbaPosition], l_mbsecc); + l_rc = fapiGetScom(iv_targetCentaur, mss_mbsecc[iv_mbaPosition], l_mbsecc); if(l_rc) return l_rc; @@ -617,7 +638,7 @@ fapi::ReturnCode mss_MaintCmd::preConditionCheck() if (l_mbmccq.isBitSet(0)) { // Create new log - FAPI_ERR("MCMCCQ[0]: maint_cmd_start not reset by hw."); + FAPI_ERR("MCMCCQ[0]: maint_cmd_start not reset by hw."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_START_NOT_RESET); } @@ -626,18 +647,18 @@ fapi::ReturnCode mss_MaintCmd::preConditionCheck() { // Log previous error before creating new log if (l_rc) fapiLogError(l_rc); - + // Create new log - FAPI_ERR("MCMCCQ[1]: maint_cmd_stop not reset by hw."); + FAPI_ERR("MCMCCQ[1]: maint_cmd_stop not reset by hw."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_STOP_NOT_RESET); } // Check for MBMSRQ[0], maint_cmd_in_progress, to be reset. if (l_mbmsrq.isBitSet(0)) - { + { // Log previous error before creating new log if (l_rc) fapiLogError(l_rc); - + // Create new log FAPI_ERR("MBMSRQ[0]: Can't start new cmd if previous cmd still in progress."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_CMD_IN_PROGRESS); @@ -648,18 +669,18 @@ fapi::ReturnCode mss_MaintCmd::preConditionCheck() { // Log previous error before creating new log if (l_rc) fapiLogError(l_rc); - + // Create new log FAPI_ERR("MBAXCRn[0:3] = 0, meaning no memory configured behind this MBA."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_NO_MEM_CNFG); } - + // Check CCS_MODEQ[29] to make sure mux switched from CCS to mainline if (l_ccs_modeq.isBitSet(29)) { // Log previous error before creating new log if (l_rc) fapiLogError(l_rc); - + // Create new log FAPI_ERR("CCS_MODEQ[29] = 1, meaning mux set for CCS instead of mainline."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_CCS_MUX_NOT_MAINLINE); @@ -670,13 +691,13 @@ fapi::ReturnCode mss_MaintCmd::preConditionCheck() { // Log previous error before creating new log if (l_rc) fapiLogError(l_rc); - + // Create new log FAPI_ERR("MBSECC[0] = 1, meaning ECC check/correct disabled."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_ECC_DISABLED); } - + FAPI_INF("EXIT mss_MaintCmd::preConditionCheck()"); return l_rc; } @@ -688,17 +709,17 @@ fapi::ReturnCode mss_MaintCmd::preConditionCheck() fapi::ReturnCode mss_MaintCmd::loadCmdType() { fapi::ReturnCode l_rc; - uint32_t l_ecmd_rc = 0; + uint32_t l_ecmd_rc = 0; ecmdDataBufferBase l_data(64); FAPI_INF("ENTER mss_MaintCmd::loadCmdType()"); - - l_rc = fapiGetScom(iv_target, MBA01_MBMCTQ_0x0301060A, l_data); + + l_rc = fapiGetScom(iv_target, MBA01_MBMCTQ_0x0301060A, l_data); if(l_rc) return l_rc; l_ecmd_rc |= l_data.insert( (uint32_t)iv_cmdType, 0, 5, 32-5 ); - + // NOTE: Setting super fast address increment mode, where COL bits are LSB. - // Valid for all cmds. + // Valid for all cmds. l_ecmd_rc |= l_data.setBit(5); if(l_ecmd_rc) { @@ -707,7 +728,7 @@ fapi::ReturnCode mss_MaintCmd::loadCmdType() } l_rc = fapiPutScom(iv_target, MBA01_MBMCTQ_0x0301060A, l_data); if(l_rc) return l_rc; - + FAPI_INF("EXIT mss_MaintCmd::loadCmdType()"); return l_rc; } @@ -720,17 +741,17 @@ fapi::ReturnCode mss_MaintCmd::loadCmdType() fapi::ReturnCode mss_MaintCmd::loadStartAddress() { fapi::ReturnCode l_rc; - uint32_t l_ecmd_rc = 0; + uint32_t l_ecmd_rc = 0; ecmdDataBufferBase l_data(64); FAPI_INF("ENTER mss_MaintCmd::loadStartAddress()"); - + l_rc = fapiGetScom(iv_target, MBA01_MBMACAQ_0x0301060D, l_data); if(l_rc) return l_rc; - + // Load address bits 0:39 - l_ecmd_rc |= l_data.insert( iv_startAddr, 0, 40, 0 ); - + l_ecmd_rc |= l_data.insert( iv_startAddr, 0, 40, 0 ); + // Clear error status bits 40:46 l_ecmd_rc |= l_data.clearBit(40,7); @@ -741,7 +762,7 @@ fapi::ReturnCode mss_MaintCmd::loadStartAddress() } l_rc = fapiPutScom(iv_target, MBA01_MBMACAQ_0x0301060D, l_data); if(l_rc) return l_rc; - + FAPI_INF("EXIT mss_MaintCmd::loadStartAddress()"); return l_rc; } @@ -753,23 +774,23 @@ fapi::ReturnCode mss_MaintCmd::loadStartAddress() fapi::ReturnCode mss_MaintCmd::loadEndAddress() { fapi::ReturnCode l_rc; - uint32_t l_ecmd_rc = 0; + uint32_t l_ecmd_rc = 0; ecmdDataBufferBase l_data(64); FAPI_INF("ENTER mss_MaintCmd::loadEndAddress()"); l_rc = fapiGetScom(iv_target, MBA01_MBMEAQ_0x0301060E, l_data); if(l_rc) return l_rc; - - l_ecmd_rc |= l_data.insert( iv_endAddr, 0, 40, 0 ); + + l_ecmd_rc |= l_data.insert( iv_endAddr, 0, 40, 0 ); if(l_ecmd_rc) { l_rc.setEcmdError(l_ecmd_rc); return l_rc; } - l_rc = fapiPutScom(iv_target, MBA01_MBMEAQ_0x0301060E, l_data); + l_rc = fapiPutScom(iv_target, MBA01_MBMEAQ_0x0301060E, l_data); if(l_rc) return l_rc; - + FAPI_INF("EXIT mss_MaintCmd::loadEndAddress()"); return l_rc; } @@ -781,65 +802,65 @@ fapi::ReturnCode mss_MaintCmd::loadEndAddress() fapi::ReturnCode mss_MaintCmd::loadStopCondMask() { fapi::ReturnCode l_rc; - uint32_t l_ecmd_rc = 0; + uint32_t l_ecmd_rc = 0; ecmdDataBufferBase l_mbasctlq(64); - FAPI_INF("ENTER mss_MaintCmd::loadStopCondMask()"); + FAPI_INF("ENTER mss_MaintCmd::loadStopCondMask()"); // Get stop conditions from MBASCTLQ - l_rc = fapiGetScom(iv_target, MBA01_MBASCTLQ_0x0301060F, l_mbasctlq); + l_rc = fapiGetScom(iv_target, MBA01_MBASCTLQ_0x0301060F, l_mbasctlq); if(l_rc) return l_rc; - + // Start by clearing all bits 0:12 and bit 16 l_ecmd_rc |= l_mbasctlq.clearBit(0,13); l_ecmd_rc |= l_mbasctlq.clearBit(16); // Enable stop immediate - if ( 0 != (iv_stopCondition & STOP_IMMEDIATE) ) + if ( 0 != (iv_stopCondition & STOP_IMMEDIATE) ) l_ecmd_rc |= l_mbasctlq.setBit(0); // Enable stop end of rank - if ( 0 != (iv_stopCondition & STOP_END_OF_RANK) ) + if ( 0 != (iv_stopCondition & STOP_END_OF_RANK) ) l_ecmd_rc |= l_mbasctlq.setBit(1); - + // Stop on hard NCE ETE - if ( 0 != (iv_stopCondition & STOP_ON_HARD_NCE_ETE) ) + if ( 0 != (iv_stopCondition & STOP_ON_HARD_NCE_ETE) ) l_ecmd_rc |= l_mbasctlq.setBit(2); // Stop on intermittent NCE ETE - if ( 0 != (iv_stopCondition & STOP_ON_INT_NCE_ETE) ) + if ( 0 != (iv_stopCondition & STOP_ON_INT_NCE_ETE) ) l_ecmd_rc |= l_mbasctlq.setBit(3); // Stop on soft NCE ETE - if ( 0 != (iv_stopCondition & STOP_ON_SOFT_NCE_ETE) ) + if ( 0 != (iv_stopCondition & STOP_ON_SOFT_NCE_ETE) ) l_ecmd_rc |= l_mbasctlq.setBit(4); // Stop on SCE - if ( 0 != (iv_stopCondition & STOP_ON_SCE) ) + if ( 0 != (iv_stopCondition & STOP_ON_SCE) ) l_ecmd_rc |= l_mbasctlq.setBit(5); // Stop on MCE - if ( 0 != (iv_stopCondition & STOP_ON_MCE) ) + if ( 0 != (iv_stopCondition & STOP_ON_MCE) ) l_ecmd_rc |= l_mbasctlq.setBit(6); // Stop on retry CE ETE - if ( 0 != (iv_stopCondition & STOP_ON_RETRY_CE) ) + if ( 0 != (iv_stopCondition & STOP_ON_RETRY_CE) ) l_ecmd_rc |= l_mbasctlq.setBit(7); // Stop on MPE - if ( 0 != (iv_stopCondition & STOP_ON_MPE) ) + if ( 0 != (iv_stopCondition & STOP_ON_MPE) ) l_ecmd_rc |= l_mbasctlq.setBit(8); // Stop on UE - if ( 0 != (iv_stopCondition & STOP_ON_UE) ) + if ( 0 != (iv_stopCondition & STOP_ON_UE) ) l_ecmd_rc |= l_mbasctlq.setBit(9); // Stop on end address - if ( 0 != (iv_stopCondition & STOP_ON_END_ADDRESS) ) + if ( 0 != (iv_stopCondition & STOP_ON_END_ADDRESS) ) l_ecmd_rc |= l_mbasctlq.setBit(10); // Enable command complete attention - if ( 0 != (iv_stopCondition & ENABLE_CMD_COMPLETE_ATTENTION) ) + if ( 0 != (iv_stopCondition & ENABLE_CMD_COMPLETE_ATTENTION) ) l_ecmd_rc |= l_mbasctlq.setBit(11); // Stop on SUE @@ -847,20 +868,20 @@ fapi::ReturnCode mss_MaintCmd::loadStopCondMask() l_ecmd_rc |= l_mbasctlq.setBit(12); // Enable command complete attention on clean and error - if ( 0 != (iv_stopCondition & ENABLE_CMD_COMPLETE_ATTENTION_ON_CLEAN_AND_ERROR) ) + if ( 0 != (iv_stopCondition & ENABLE_CMD_COMPLETE_ATTENTION_ON_CLEAN_AND_ERROR) ) l_ecmd_rc |= l_mbasctlq.setBit(16); if(l_ecmd_rc) { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } + } // Write stop conditions to MBASCTLQ - l_rc = fapiPutScom(iv_target, MBA01_MBASCTLQ_0x0301060F, l_mbasctlq); + l_rc = fapiPutScom(iv_target, MBA01_MBASCTLQ_0x0301060F, l_mbasctlq); if(l_rc) return l_rc; - FAPI_INF("EXIT mss_MaintCmd::loadStopCondMask()"); + FAPI_INF("EXIT mss_MaintCmd::loadStopCondMask()"); return l_rc; } @@ -872,18 +893,18 @@ fapi::ReturnCode mss_MaintCmd::loadStopCondMask() fapi::ReturnCode mss_MaintCmd::startMaintCmd() { fapi::ReturnCode l_rc; - uint32_t l_ecmd_rc = 0; + uint32_t l_ecmd_rc = 0; ecmdDataBufferBase l_data(64); FAPI_INF("ENTER mss_MaintCmd::startMaintCmd()"); - + // DEBUG - should be no special attentions before we start cmd - l_rc = fapiGetScom(iv_target, MBA01_MBSPAQ_0x03010611, l_data); + l_rc = fapiGetScom(iv_target, MBA01_MBSPAQ_0x03010611, l_data); if(l_rc) return l_rc; - - l_rc = fapiGetScom(iv_target, MBA01_MBMCCQ_0x0301060B, l_data); + + l_rc = fapiGetScom(iv_target, MBA01_MBMCCQ_0x0301060B, l_data); if(l_rc) return l_rc; - + l_ecmd_rc |= l_data.setBit(0); if(l_ecmd_rc) { @@ -893,7 +914,7 @@ fapi::ReturnCode mss_MaintCmd::startMaintCmd() l_rc = fapiPutScom(iv_target, MBA01_MBMCCQ_0x0301060B, l_data); if(l_rc) return l_rc; - FAPI_INF("EXIT mss_MaintCmd::startMaintCmd()"); + FAPI_INF("EXIT mss_MaintCmd::startMaintCmd()"); return l_rc; } @@ -906,21 +927,21 @@ fapi::ReturnCode mss_MaintCmd::postConditionCheck() ecmdDataBufferBase l_mbmccq(64); ecmdDataBufferBase l_mbafirq(64); - FAPI_INF("ENTER mss_MaintCmd::postConditionCheck()"); - - // Read MBMCCQ - l_rc = fapiGetScom(iv_target, MBA01_MBMCCQ_0x0301060B, l_mbmccq); + FAPI_INF("ENTER mss_MaintCmd::postConditionCheck()"); + + // Read MBMCCQ + l_rc = fapiGetScom(iv_target, MBA01_MBMCCQ_0x0301060B, l_mbmccq); if(l_rc) return l_rc; // Read MBAFIRQ - l_rc = fapiGetScom(iv_target, MBA01_MBAFIRQ_0x03010600, l_mbafirq); + l_rc = fapiGetScom(iv_target, MBA01_MBAFIRQ_0x03010600, l_mbafirq); if(l_rc) return l_rc; // Check for MBMCCQ[0], maint_cmd_start, to be reset by hw. if (l_mbmccq.isBitSet(0)) { // Create new log - FAPI_ERR("MCMCCQ[0]: maint_cmd_start not reset by hw."); + FAPI_ERR("MCMCCQ[0]: maint_cmd_start not reset by hw."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_START_NOT_RESET); } @@ -929,9 +950,9 @@ fapi::ReturnCode mss_MaintCmd::postConditionCheck() { // Log previous error before creating new log if (l_rc) fapiLogError(l_rc); - + // Create new log - FAPI_ERR("MBAFIRQ[0], invalid_maint_cmd."); + FAPI_ERR("MBAFIRQ[0], invalid_maint_cmd."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_INVALID_CMD); } @@ -940,14 +961,13 @@ fapi::ReturnCode mss_MaintCmd::postConditionCheck() { // Log previous error before creating new log if (l_rc) fapiLogError(l_rc); - + // Create new log - FAPI_ERR("MBAFIRQ[1], cmd started with invalid_maint_address."); + FAPI_ERR("MBAFIRQ[1], cmd started with invalid_maint_address."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_INVALID_ADDR); } - - FAPI_INF("EXIT mss_MaintCmd::postConditionCheck()"); + FAPI_INF("EXIT mss_MaintCmd::postConditionCheck()"); return l_rc; } @@ -956,49 +976,51 @@ fapi::ReturnCode mss_MaintCmd::postConditionCheck() //--------------------------------------------------------- fapi::ReturnCode mss_MaintCmd::pollForMaintCmdComplete() { - + fapi::ReturnCode l_rc; ecmdDataBufferBase l_data(64); - FAPI_INF("ENTER mss_MaintCmd::pollForMaintCmdComplete()"); - + FAPI_INF("ENTER mss_MaintCmd::pollForMaintCmdComplete()"); + uint32_t count = 0; - + // 1 ms delay for HW mode const uint64_t HW_MODE_DELAY = 1000000; - - // 200000 sim cycle delay for SIM mode - const uint64_t SIM_MODE_DELAY = 200000; - + + // 200000 sim cycle delay for SIM mode + const uint64_t SIM_MODE_DELAY = 200000; + uint32_t loop_limit = 500; - + do { - fapiDelay(HW_MODE_DELAY, SIM_MODE_DELAY); - - // DEBUG - want to see attention only when cmd done - FAPI_INF("MBSPAQ"); - l_rc = fapiGetScom(iv_target, MBA01_MBSPAQ_0x03010611, l_data); + fapiDelay(HW_MODE_DELAY, SIM_MODE_DELAY); + + // Want to see cmd complete attention + l_rc = fapiGetScom(iv_target, MBA01_MBSPAQ_0x03010611, l_data); if(l_rc) return l_rc; + FAPI_DBG("MBSPAQ = 0x%.8X 0x%.8X",l_data.getWord(0), l_data.getWord(1)); - FAPI_INF("Read MBMACAQ just to see if it's incrementing"); + // Read MBMACAQ just to see if it's incrementing l_rc = fapiGetScom(iv_target, MBA01_MBMACAQ_0x0301060D, l_data); if(l_rc) return l_rc; + FAPI_DBG("MBMACAQ = 0x%.8X 0x%.8X",l_data.getWord(0), l_data.getWord(1)); - FAPI_INF("Waiting for MBMSRQ[0] maint cmd in progress bit to turn off"); + // Waiting for MBMSRQ[0] maint cmd in progress bit to turn off l_rc = fapiGetScom(iv_target, MBA01_MBMSRQ_0x0301060C, l_data); if(l_rc) return l_rc; + FAPI_DBG("MBMSRQ = 0x%.8X 0x%.8X",l_data.getWord(0), l_data.getWord(1)); count++; } - // Poll until cmd in progress bit goes off - while (l_data.isBitSet(0) && (count < loop_limit)); + // Poll until cmd in progress bit goes off + while (l_data.isBitSet(0) && (count < loop_limit)); if (count == loop_limit) { // Create new log - FAPI_ERR("Maint cmd timeout."); + FAPI_ERR("Maint cmd timeout."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_CMD_TIMEOUT); } else @@ -1006,7 +1028,7 @@ fapi::ReturnCode mss_MaintCmd::pollForMaintCmdComplete() FAPI_INF("Maint cmd complete. "); } - FAPI_INF("EXIT mss_MaintCmd::pollForMaintCmdComplete()"); + FAPI_INF("EXIT mss_MaintCmd::pollForMaintCmdComplete()"); return l_rc; } @@ -1017,76 +1039,110 @@ fapi::ReturnCode mss_MaintCmd::collectFFDC() { fapi::ReturnCode l_rc; ecmdDataBufferBase l_data(64); + uint8_t l_dramSparePort0Symbol = MSS_INVALID_SYMBOL; + uint8_t l_dramSparePort1Symbol = MSS_INVALID_SYMBOL; + uint8_t l_eccSpareSymbol = MSS_INVALID_SYMBOL; + uint8_t l_symbol_mark = MSS_INVALID_SYMBOL; + uint8_t l_chip_mark = MSS_INVALID_SYMBOL; + + FAPI_INF("ENTER mss_MaintCmd::collectFFDC()"); - FAPI_INF("ENTER mss_MaintCmd::collectFFDC()"); - - FAPI_INF("MBMCTQ"); l_rc = fapiGetScom(iv_target, MBA01_MBMCTQ_0x0301060A, l_data); if(l_rc) return l_rc; - - FAPI_INF("MBMACAQ"); + FAPI_DBG("MBMCTQ = 0x%.8X 0x%.8X", l_data.getWord(0), l_data.getWord(1)); + l_rc = fapiGetScom(iv_target, MBA01_MBMACAQ_0x0301060D, l_data); if(l_rc) return l_rc; + FAPI_DBG("MBMACAQ = 0x%.8X 0x%.8X", l_data.getWord(0), l_data.getWord(1)); // Print out error status bits from MBMACAQ - if (l_data.isBitSet(40)) FAPI_ERR("40:NCE"); - if (l_data.isBitSet(41)) FAPI_ERR("41:SCE"); - if (l_data.isBitSet(42)) FAPI_ERR("42:MCE"); - if (l_data.isBitSet(43)) FAPI_ERR("43:RCE"); - if (l_data.isBitSet(44)) FAPI_ERR("44:MPE"); - if (l_data.isBitSet(45)) FAPI_ERR("45:UE"); - if (l_data.isBitSet(46)) FAPI_ERR("46:SUE"); - - FAPI_INF("MBMEAQ"); + if (l_data.isBitSet(40)) FAPI_ERR("MBMACAQ error status: 40:NCE"); + if (l_data.isBitSet(41)) FAPI_ERR("MBMACAQ error status: 41:SCE"); + if (l_data.isBitSet(42)) FAPI_ERR("MBMACAQ error status: 42:MCE"); + if (l_data.isBitSet(43)) FAPI_ERR("MBMACAQ error status: 43:RCE"); + if (l_data.isBitSet(44)) FAPI_ERR("MBMACAQ error status: 44:MPE"); + if (l_data.isBitSet(45)) FAPI_ERR("MBMACAQ error status: 45:UE"); + if (l_data.isBitSet(46)) FAPI_ERR("MBMACAQ error status: 46:SUE"); + l_rc = fapiGetScom(iv_target, MBA01_MBMEAQ_0x0301060E, l_data); if(l_rc) return l_rc; - - FAPI_INF("MBASCTLQ"); + FAPI_DBG("MBMEAQ = 0x%.8X 0x%.8X", l_data.getWord(0), l_data.getWord(1)); + l_rc = fapiGetScom(iv_target, MBA01_MBASCTLQ_0x0301060F, l_data); if(l_rc) return l_rc; - FAPI_INF("MBASCTLQ = 0x%.8X 0x%.8X", l_data.getWord(0), l_data.getWord(1)); - - FAPI_INF("MBMCCQ"); + FAPI_DBG("MBASCTLQ = 0x%.8X 0x%.8X", l_data.getWord(0), l_data.getWord(1)); + l_rc = fapiGetScom(iv_target, MBA01_MBMCCQ_0x0301060B, l_data); if(l_rc) return l_rc; - - FAPI_INF("MBMSRQ"); + FAPI_DBG("MBMCCQ = 0x%.8X 0x%.8X", l_data.getWord(0), l_data.getWord(1)); + l_rc = fapiGetScom(iv_target, MBA01_MBMSRQ_0x0301060C, l_data); if(l_rc) return l_rc; - - FAPI_INF("MBAFIRQ"); + FAPI_DBG("MBMSRQ = 0x%.8X 0x%.8X", l_data.getWord(0), l_data.getWord(1)); + l_rc = fapiGetScom(iv_target, MBA01_MBAFIRQ_0x03010600, l_data); if(l_rc) return l_rc; - - FAPI_INF("MBSPAQ"); + FAPI_DBG("MBAFIRQ = 0x%.8X 0x%.8X", l_data.getWord(0), l_data.getWord(1)); + l_rc = fapiGetScom(iv_target, MBA01_MBSPAQ_0x03010611, l_data); if(l_rc) return l_rc; - - FAPI_INF("MBACALFIR"); - l_rc = fapiGetScom(iv_target, MBA01_MBACALFIR_0x03010400, l_data); + FAPI_DBG("MBSPAQ = 0x%.8X 0x%.8X", l_data.getWord(0), l_data.getWord(1)); + + l_rc = fapiGetScom(iv_target, MBA01_MBACALFIR_0x03010400, l_data); if(l_rc) return l_rc; - - FAPI_INF("MBECCFIR"); - l_rc = fapiGetScom(iv_targetCentaur, mss_mbeccfir[iv_mbaPosition], l_data); + FAPI_DBG("MBACALFIR = 0x%.8X 0x%.8X", l_data.getWord(0), l_data.getWord(1)); + + l_rc = fapiGetScom(iv_targetCentaur, mss_mbeccfir[iv_mbaPosition], l_data); if(l_rc) return l_rc; - + FAPI_DBG("MBECCFIR = 0x%.8X 0x%.8X", l_data.getWord(0), l_data.getWord(1)); + // Print out maint ECC FIR bits from MBECCFIR - if (l_data.isBitSet(20,8)) FAPI_ERR("20-27:Maint MPE"); + if (l_data.isBitSet(20)) FAPI_ERR("20:Maint MPE, rank0"); + if (l_data.isBitSet(21)) FAPI_ERR("21:Maint MPE, rank1"); + if (l_data.isBitSet(22)) FAPI_ERR("22:Maint MPE, rank2"); + if (l_data.isBitSet(23)) FAPI_ERR("23:Maint MPE, rank3"); + if (l_data.isBitSet(24)) FAPI_ERR("24:Maint MPE, rank4"); + if (l_data.isBitSet(25)) FAPI_ERR("25:Maint MPE, rank5"); + if (l_data.isBitSet(26)) FAPI_ERR("26:Maint MPE, rank6"); + if (l_data.isBitSet(27)) FAPI_ERR("27:Maint MPE, rank7"); if (l_data.isBitSet(36)) FAPI_ERR("36: Maint NCE"); - if (l_data.isBitSet(37)) FAPI_ERR("37: Maint SCE"); - if (l_data.isBitSet(38)) FAPI_ERR("38: Maint MCE"); - if (l_data.isBitSet(39)) FAPI_ERR("39: Maint RCE"); - if (l_data.isBitSet(40)) FAPI_ERR("40: Maint SUE"); - if (l_data.isBitSet(41)) FAPI_ERR("41: Maint UE"); + if (l_data.isBitSet(37)) FAPI_ERR("37: Maint SCE"); + if (l_data.isBitSet(38)) FAPI_ERR("38: Maint MCE"); + if (l_data.isBitSet(39)) FAPI_ERR("39: Maint RCE"); + if (l_data.isBitSet(40)) FAPI_ERR("40: Maint SUE"); + if (l_data.isBitSet(41)) FAPI_ERR("41: Maint UE"); - FAPI_INF("Markstore: MBMS0-7"); + FAPI_DBG("Markstore"); for ( uint8_t i = 0; i < MSS_MAX_RANKS; i++ ) { l_rc = fapiGetScom(iv_targetCentaur, mss_markStoreRegs[i][iv_mbaPosition], l_data); if(l_rc) return l_rc; + FAPI_DBG("MBMS%d = 0x%.8X 0x%.8X",i, l_data.getWord(0), l_data.getWord(1)); } - - FAPI_INF("EXIT mss_MaintCmd::collectFFDC()"); + + for ( uint8_t i = 0; i < MSS_MAX_RANKS; i++ ) + { + l_rc = mss_get_mark_store(iv_target, i, l_symbol_mark, l_chip_mark ); + if (l_rc) + { + FAPI_ERR("Error reading markstore"); + return l_rc; + } + } + + FAPI_DBG("Steer MUXES"); + for ( uint8_t i = 0; i < MSS_MAX_RANKS; i++ ) + { + l_rc = mss_get_steer_mux(iv_target, + i, + mss_SteerMux::READ_MUX, + l_dramSparePort0Symbol, + l_dramSparePort1Symbol, + l_eccSpareSymbol); + if(l_rc) return l_rc; + } + + FAPI_INF("EXIT mss_MaintCmd::collectFFDC()"); return l_rc; } @@ -1097,10 +1153,10 @@ fapi::ReturnCode mss_MaintCmd::collectFFDC() fapi::ReturnCode mss_MaintCmd::loadPattern(PatternIndex i_initPattern) { - FAPI_INF("ENTER mss_MaintCmd::loadPattern()"); - + FAPI_INF("ENTER mss_MaintCmd::loadPattern()"); + static const uint32_t maintBufferDataRegs[2][16][2]={ - // port0/1 + // port0/1 {{MAINT0_MBS_MAINT_BUFF0_DATA0_0x0201160A, MAINT0_MBS_MAINT_BUFF0_DATA_ECC0_0x02011612}, {MAINT0_MBS_MAINT_BUFF0_DATA1_0x0201160B, MAINT0_MBS_MAINT_BUFF0_DATA_ECC1_0x02011613}, {MAINT0_MBS_MAINT_BUFF0_DATA2_0x0201160C, MAINT0_MBS_MAINT_BUFF0_DATA_ECC2_0x02011614}, @@ -1117,7 +1173,7 @@ fapi::ReturnCode mss_MaintCmd::loadPattern(PatternIndex i_initPattern) {MAINT0_MBS_MAINT_BUFF3_DATA1_0x0201163B, MAINT0_MBS_MAINT_BUFF3_DATA_ECC1_0x02011643}, {MAINT0_MBS_MAINT_BUFF3_DATA2_0x0201163C, MAINT0_MBS_MAINT_BUFF3_DATA_ECC2_0x02011644}, {MAINT0_MBS_MAINT_BUFF3_DATA3_0x0201163D, MAINT0_MBS_MAINT_BUFF3_DATA_ECC3_0x02011645}}, - // port2/3 + // port2/3 {{MAINT1_MBS_MAINT_BUFF0_DATA0_0x0201170A, MAINT1_MBS_MAINT_BUFF0_DATA_ECC0_0x02011712}, {MAINT1_MBS_MAINT_BUFF0_DATA1_0x0201170B, MAINT1_MBS_MAINT_BUFF0_DATA_ECC1_0x02011713}, {MAINT1_MBS_MAINT_BUFF0_DATA2_0x0201170C, MAINT1_MBS_MAINT_BUFF0_DATA_ECC2_0x02011714}, @@ -1135,35 +1191,38 @@ fapi::ReturnCode mss_MaintCmd::loadPattern(PatternIndex i_initPattern) {MAINT1_MBS_MAINT_BUFF3_DATA2_0x0201173C, MAINT1_MBS_MAINT_BUFF3_DATA_ECC2_0x02011744}, {MAINT1_MBS_MAINT_BUFF3_DATA3_0x0201173D, MAINT1_MBS_MAINT_BUFF3_DATA_ECC3_0x02011745}}}; - + static const uint32_t maintBuffer65thRegs[4][2]={ {MAINT0_MBS_MAINT_BUFF_65TH_BYTE_64B_ECC0_0x0201164A, MAINT1_MBS_MAINT_BUFF_65TH_BYTE_64B_ECC0_0x0201174A}, {MAINT0_MBS_MAINT_BUFF_65TH_BYTE_64B_ECC1_0x0201164B, MAINT1_MBS_MAINT_BUFF_65TH_BYTE_64B_ECC1_0x0201174B}, {MAINT0_MBS_MAINT_BUFF_65TH_BYTE_64B_ECC2_0x0201164C, MAINT1_MBS_MAINT_BUFF_65TH_BYTE_64B_ECC2_0x0201174C}, {MAINT0_MBS_MAINT_BUFF_65TH_BYTE_64B_ECC3_0x0201164D, MAINT1_MBS_MAINT_BUFF_65TH_BYTE_64B_ECC3_0x0201174D}}; - - fapi::ReturnCode l_rc; - uint32_t l_ecmd_rc = 0; + + fapi::ReturnCode l_rc; + uint32_t l_ecmd_rc = 0; ecmdDataBufferBase l_data(64); ecmdDataBufferBase l_ecc(64); ecmdDataBufferBase l_65th(64); uint32_t loop = 0; + FAPI_INF("pattern = 0x%.8X 0x%.8X", + mss_maintBufferData[i_initPattern][0][0], + mss_maintBufferData[i_initPattern][0][1]); + //---------------------------------------------------- // Load the data: 16 loops x 64bits = 128B cacheline //---------------------------------------------------- - FAPI_INF("Load the data: 16 loops x 64bits = 128B cacheline"); - + // Set bit 9 so that hw will generate the fabric ECC. - // This is an 8B ECC protecting the data moving on internal buses in + // This is an 8B ECC protecting the data moving on internal buses in // the Centaur. - l_ecmd_rc |= l_ecc.flushTo0(); + l_ecmd_rc |= l_ecc.flushTo0(); l_ecmd_rc |= l_ecc.setBit(9); - + for(loop=0; loop<16; loop++ ) { - // A write to MAINT_BUFFx_DATAy will not update until the corresponding + // A write to MAINT_BUFFx_DATAy will not update until the corresponding // MAINT_BUFFx_DATA_ECCy is written to. l_ecmd_rc |= l_data.insert(mss_maintBufferData[i_initPattern][loop][0], 0, 32, 0); l_ecmd_rc |= l_data.insert(mss_maintBufferData[i_initPattern][loop][1], 32, 32, 0); @@ -1171,21 +1230,20 @@ fapi::ReturnCode mss_MaintCmd::loadPattern(PatternIndex i_initPattern) { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } - l_rc = fapiPutScom(iv_targetCentaur, maintBufferDataRegs[iv_mbaPosition][loop][0], l_data); - if(l_rc) return l_rc; - - l_rc = fapiPutScom(iv_targetCentaur, maintBufferDataRegs[iv_mbaPosition][loop][1], l_ecc); - if(l_rc) return l_rc; + } + l_rc = fapiPutScom(iv_targetCentaur, maintBufferDataRegs[iv_mbaPosition][loop][0], l_data); + if(l_rc) return l_rc; + + l_rc = fapiPutScom(iv_targetCentaur, maintBufferDataRegs[iv_mbaPosition][loop][1], l_ecc); + if(l_rc) return l_rc; } - + //---------------------------------------------------- - // Load the 65th byte: 4 loops to fill in the two 65th bytes in cacheline + // Load the 65th byte: 4 loops to fill in the two 65th bytes in cacheline //---------------------------------------------------- - FAPI_INF("Load the 65th byte: 4 loops to fill in the two 65th bytes in the cacheline"); - - l_ecmd_rc |= l_65th.flushTo0(); - + + l_ecmd_rc |= l_65th.flushTo0(); + // Set bit 56 so that hw will generate the fabric ECC. // This is an 8B ECC protecting the data moving on internal buses in Centaur. l_ecmd_rc |= l_65th.setBit(56); @@ -1193,8 +1251,8 @@ fapi::ReturnCode mss_MaintCmd::loadPattern(PatternIndex i_initPattern) { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } - + } + for(loop=0; loop<4; loop++ ) { l_ecmd_rc |= l_65th.insert(mss_65thByte[i_initPattern][loop], 1, 3, 1); @@ -1202,13 +1260,13 @@ fapi::ReturnCode mss_MaintCmd::loadPattern(PatternIndex i_initPattern) { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } + } - l_rc = fapiPutScom(iv_targetCentaur, maintBuffer65thRegs[loop][iv_mbaPosition], l_65th); - if(l_rc) return l_rc; - } - - FAPI_INF("EXIT mss_MaintCmd::loadPattern()"); + l_rc = fapiPutScom(iv_targetCentaur, maintBuffer65thRegs[loop][iv_mbaPosition], l_65th); + if(l_rc) return l_rc; + } + + FAPI_INF("EXIT mss_MaintCmd::loadPattern()"); return l_rc; } @@ -1219,33 +1277,41 @@ fapi::ReturnCode mss_MaintCmd::loadPattern(PatternIndex i_initPattern) fapi::ReturnCode mss_MaintCmd::loadSpeed(TimeBaseSpeed i_speed) { - FAPI_INF("ENTER mss_MaintCmd::loadSpeed()"); + FAPI_INF("ENTER mss_MaintCmd::loadSpeed()"); fapi::ReturnCode l_rc; - uint32_t l_ecmd_rc = 0; + uint32_t l_ecmd_rc = 0; ecmdDataBufferBase l_data(64); - + uint32_t l_ddr_freq = 0; + uint64_t l_step_size = 0; + uint64_t l_num_address_bits = 0; + uint64_t l_num_addresses = 0; + uint64_t l_address_bit = 0; + ecmdDataBufferBase l_start_address(64); + ecmdDataBufferBase l_end_address(64); + uint64_t l_cmd_interval = 0; + // burst_window_sel // MBMCTQ[6]: 0 = 512 Maint Clks // 1 = 536870912 Maint Clks uint8_t l_burst_window_sel = 0; - + // timebase_sel // MBMCTQ[9:10]: 00 = 1 Maint Clk // 01 = 8192 Maint clks uint8_t l_timebase_sel = 0; - + // timebase_burst_sel // MBMCTQ[11]: 0 = disable burst mode // 1 = enable burst mode uint8_t l_timebase_burst_sel = 0; - + // timebase_interval // MBMCTQ[12:23]: The operation interval for timebase operations // equals the timebase_sel x MBMCTQ[12:23]. // NOTE: Should never be 0, or will hang mainline traffic. uint32_t l_timebase_interval = 1; - + // burst_window // MBMCTQ[24:31]: The burst window for timebase operations with burst mode // enabled equals burst_window_sel x MBMCTQ[24:31] @@ -1257,9 +1323,9 @@ fapi::ReturnCode mss_MaintCmd::loadSpeed(TimeBaseSpeed i_speed) // no operations occurring in them. uint8_t l_burst_interval = 0; - l_rc = fapiGetScom(iv_target, MBA01_MBMCTQ_0x0301060A, l_data); + l_rc = fapiGetScom(iv_target, MBA01_MBMCTQ_0x0301060A, l_data); if(l_rc) return l_rc; - + // FAST_AS_POSSIBLE if (i_speed == FAST_AS_POSSIBLE) @@ -1275,39 +1341,132 @@ fapi::ReturnCode mss_MaintCmd::loadSpeed(TimeBaseSpeed i_speed) // SLOW_12H else { - // TODO: Need to figure out setting are for 12H cycle. - l_burst_window_sel = 0; - l_timebase_sel = 0; - l_timebase_burst_sel = 0; - l_timebase_interval = 512; - l_burst_window = 0; - l_burst_interval = 0; + // Get l_ddr_freq from ATTR_MSS_FREQ + // Possible frequencies are 800, 1066, 1333, 1600, 1866, and 2133 MHz + // NOTE: Max 32 address bits using 800 and 1066 result in scrub + // taking longer than 12h, but these is no plan to actually use + // those frequencies. + l_rc = FAPI_ATTR_GET( ATTR_MSS_FREQ, &iv_targetCentaur, l_ddr_freq); + if (l_rc) + { + FAPI_ERR("Failed to get attribute: ATTR_MSS_FREQ."); + return l_rc; + } + + // Make sure it's non-zero, to avoid divide by 0 + if (l_ddr_freq == 0) + { + FAPI_SET_HWP_ERROR(l_rc, RC_MSS_UNSUPPORTED_FREQ_CALCULATED); + return l_rc; + } + + // l_timebase_sel + // MBMCTQ[9:10]: 00 = 1 * Maint Clk + // 01 = 8192 * Maint Clk + // Where Maint Clk = 2/1_ddr_freq + l_timebase_sel = 1; + + // Get l_step_size in nSec + l_step_size = 8192*2*1000/l_ddr_freq; + + FAPI_DBG("l_ddr_freq = %d MHz, l_step_size = %d nSec", + (uint32_t)l_ddr_freq, (uint32_t)l_step_size); + + // Get l_end_address + l_rc = mss_get_address_range( iv_target, + MSS_ALL_RANKS, + l_start_address, + l_end_address ); + if (l_rc) + { + FAPI_ERR("mss_get_address_range failed. "); + return l_rc; + } + + // Get l_num_address_bits by counting bits set to 1 in l_end_address. + for(l_address_bit=0; l_address_bit<37; l_address_bit++ ) + { + if(l_end_address.isBitSet(l_address_bit)) + { + l_num_address_bits++; + } + } + + // NOTE: Assumption is max 32 address bits, which can be done + // in 12h (+/- 2h). More than 32 address bits would + // double scrub time for every extra address bit. + if (l_num_address_bits > 32) + { + FAPI_INF("WARNING: l_num_address_bits: %d, is greater than 32, so scrub will take longer than 12h.",(uint32_t)l_num_address_bits); + } + + // NOTE: Smallest number of address bits is supposed to be 25. + // So if for some reason it's less (like in VBU), + // use 25 anyway so the scrub rate calculation still works. + if (l_num_address_bits < 25) + { + FAPI_INF("WARNING: l_num_address_bits: %d, is less than 25, but using 25 in calculation anyway.",(uint32_t)l_num_address_bits); + l_num_address_bits = 25; + } + + // Get l_num_addresses + l_num_addresses = 1; + for(uint32_t i=0; i<l_num_address_bits; i++ ) + { + l_num_addresses *=2; + } + // Convert to M addresses + l_num_addresses /=1000000; + + // Get interval between cmds in order to through l_num_addresses in 12h + l_cmd_interval = (12 * 60 * 60 * 1000)/l_num_addresses; + + // How many times to multiply l_step_size to get l_cmd_interval? + l_timebase_interval = l_cmd_interval/l_step_size; + + // Round up to nearest integer for more accurate number + l_timebase_interval += (l_cmd_interval % l_step_size >= l_step_size/2) ? 1:0; + + // Make sure smallest is 1 + if (l_timebase_interval == 0) l_timebase_interval = 1; + + FAPI_DBG("l_num_address_bits = %d, l_num_addresses = %d (M), l_cmd_interval = %d nSec, l_timebase_interval = %d", + (uint32_t)l_num_address_bits, (uint32_t)l_num_addresses, (uint32_t)l_cmd_interval, (uint32_t)l_timebase_interval); + + // Disable burst mode + l_timebase_burst_sel = 0; // Disable burst mode + l_burst_window_sel = 0; // Don't care since burst mode disabled + l_burst_window = 0; // Don't care since burst mode disabled + l_burst_interval = 0; // Don't care since burst mode disabled + + return l_rc; + } - - + + // burst_window_sel // MBMCTQ[6] l_ecmd_rc |= l_data.insert( l_burst_window_sel, 6, 1, 8-1 ); - + // timebase_sel // MBMCTQ[9:10] l_ecmd_rc |= l_data.insert( l_timebase_sel, 9, 2, 8-2 ); - + // timebase_burst_sel // MBMCTQ[11] l_ecmd_rc |= l_data.insert( l_timebase_burst_sel, 11, 1, 8-1 ); // timebase_interval // MBMCTQ[12:23] - l_ecmd_rc |= l_data.insert( l_timebase_interval, 12, 12, 32-12 ); - + l_ecmd_rc |= l_data.insert( l_timebase_interval, 12, 12, 32-12 ); + // burst_window // MBMCTQ[24:31] - l_ecmd_rc |= l_data.insert( l_burst_window, 24, 8, 8-8 ); + l_ecmd_rc |= l_data.insert( l_burst_window, 24, 8, 8-8 ); // burst_interval // MBMCTQ[32:39] - l_ecmd_rc |= l_data.insert( l_burst_interval, 32, 8, 8-8 ); + l_ecmd_rc |= l_data.insert( l_burst_interval, 32, 8, 8-8 ); if(l_ecmd_rc) { @@ -1318,7 +1477,7 @@ fapi::ReturnCode mss_MaintCmd::loadSpeed(TimeBaseSpeed i_speed) l_rc = fapiPutScom(iv_target, MBA01_MBMCTQ_0x0301060A, l_data); if(l_rc) return l_rc; - FAPI_INF("EXIT mss_MaintCmd::loadSpeed()"); + FAPI_INF("EXIT mss_MaintCmd::loadSpeed()"); return l_rc; } @@ -1330,9 +1489,9 @@ fapi::ReturnCode mss_MaintCmd::loadSpeed(TimeBaseSpeed i_speed) fapi::ReturnCode mss_MaintCmd::setupAndExecuteCmd() { - FAPI_INF("ENTER mss_MaintCmd::setupAndExecuteCmd()"); + FAPI_INF("ENTER mss_MaintCmd::setupAndExecuteCmd()"); fapi::ReturnCode l_rc; - FAPI_INF("EXIT mss_MaintCmd::setupAndExecuteCmd()"); + FAPI_INF("EXIT mss_MaintCmd::setupAndExecuteCmd()"); return l_rc; } @@ -1386,19 +1545,19 @@ mss_SuperFastInit::mss_SuperFastInit( const fapi::Target & i_target, //--------------------------------------------------------- fapi::ReturnCode mss_SuperFastInit::setupAndExecuteCmd() { - - FAPI_INF("ENTER mss_SuperFastInit::setupAndExecuteCmd()"); - + FAPI_INF("ENTER mss_SuperFastInit::setupAndExecuteCmd()"); + + fapi::ReturnCode l_rc; ecmdDataBufferBase l_data(64); - // Gather data that needs to be stored. For testing purposes we will just + // Gather data that needs to be stored. For testing purposes we will just // set an abitrary number. //l_rc = setSavedData( 0xdeadbeef ); if(l_rc) return l_rc; //printf( "Saved data: 0x%08x\n", getSavedData() ); - + // Make sure maint logic in valid state to run new cmd l_rc = preConditionCheck(); if(l_rc) return l_rc; @@ -1407,25 +1566,25 @@ fapi::ReturnCode mss_SuperFastInit::setupAndExecuteCmd() l_rc = loadPattern(iv_initPattern); if(l_rc) return l_rc; // Load cmd type: MBMCTQ - l_rc = loadCmdType(); if(l_rc) return l_rc; - + l_rc = loadCmdType(); if(l_rc) return l_rc; + // Load start address: MBMACAQ - l_rc = loadStartAddress(); if(l_rc) return l_rc; + l_rc = loadStartAddress(); if(l_rc) return l_rc; // Load end address: MBMEAQ - l_rc = loadEndAddress(); if(l_rc) return l_rc; - + l_rc = loadEndAddress(); if(l_rc) return l_rc; + // Load stop conditions: MBASCTLQ l_rc = loadStopCondMask(); if(l_rc) return l_rc; // Start the command: MBMCCQ l_rc = startMaintCmd(); if(l_rc) return l_rc; - - // Check for early problems with maint cmd instead of waiting for + + // Check for early problems with maint cmd instead of waiting for // cmd timeout l_rc = postConditionCheck(); if(l_rc) return l_rc; - + if(iv_poll == false) { FAPI_INF("Cmd has started. Use attentions to detect cmd complete."); @@ -1434,11 +1593,11 @@ fapi::ReturnCode mss_SuperFastInit::setupAndExecuteCmd() // Poll for command complete: MBMSRQ l_rc = pollForMaintCmdComplete(); if(l_rc) return l_rc; - + // Collect FFDC l_rc = collectFFDC(); if(l_rc) return l_rc; - FAPI_INF("EXIT mss_SuperFastInit::setupAndExecuteCmd()"); + FAPI_INF("EXIT mss_SuperFastInit::setupAndExecuteCmd()"); return l_rc; } @@ -1449,8 +1608,8 @@ fapi::ReturnCode mss_SuperFastInit::setupAndExecuteCmd() fapi::ReturnCode mss_SuperFastInit::stopCmd() { - FAPI_INF("ENTER mss_SuperFastInit::stopCmd()"); - + FAPI_INF("ENTER mss_SuperFastInit::stopCmd()"); + fapi::ReturnCode l_rc; // Stop the maintenace command if it is running. @@ -1460,24 +1619,24 @@ fapi::ReturnCode mss_SuperFastInit::stopCmd() //iv_startAddr = 0x0000dead0000beefll; //printf( "addr stopped on: 0x%016llx\n", iv_startAddr ); - FAPI_INF("EXIT mss_SuperFastInit::stopCmd()"); - + FAPI_INF("EXIT mss_SuperFastInit::stopCmd()"); + return l_rc; } fapi::ReturnCode mss_SuperFastInit::cleanupCmd() { - FAPI_INF("ENTER mss_SuperFastInit::cleanupCmd()"); - + FAPI_INF("ENTER mss_SuperFastInit::cleanupCmd()"); + fapi::ReturnCode l_rc; // Clear maintenance command complete attention, scrub stats, etc... // Restore the saved data. - FAPI_INF("EXIT mss_SuperFastInit::cleanupCmd()"); - + FAPI_INF("EXIT mss_SuperFastInit::cleanupCmd()"); + return l_rc; } @@ -1504,7 +1663,7 @@ mss_SuperFastRandomInit::mss_SuperFastRandomInit( const fapi::Target & i_target, i_stopCondition, i_poll, cv_cmdType), - iv_initPattern( i_initPattern ) + iv_initPattern( i_initPattern ) {} @@ -1518,33 +1677,33 @@ fapi::ReturnCode mss_SuperFastRandomInit::setupAndExecuteCmd() { - FAPI_INF("ENTER mss_SuperFastRandomInit::setupAndExecuteCmd()"); + FAPI_INF("ENTER mss_SuperFastRandomInit::setupAndExecuteCmd()"); + - fapi::ReturnCode l_rc; uint32_t l_ecmd_rc = 0; - // Gather data that needs to be stored. For testing purposes we will just + // Gather data that needs to be stored. For testing purposes we will just // set an abitrary number. //l_rc = setSavedData( 0xdeadbeef ); if(l_rc) return l_rc; //printf( "Saved data: 0x%08x\n", getSavedData() ); - + // Make sure maint logic in valid state to run new cmd - l_rc = preConditionCheck(); if(l_rc) return l_rc; + l_rc = preConditionCheck(); if(l_rc) return l_rc; // Load pattern l_rc = loadPattern(iv_initPattern); if(l_rc) return l_rc; // Load cmd type: MBMCTQ - l_rc = loadCmdType(); if(l_rc) return l_rc; + l_rc = loadCmdType(); if(l_rc) return l_rc; // Load start address: MBMACAQ - l_rc = loadStartAddress(); if(l_rc) return l_rc; + l_rc = loadStartAddress(); if(l_rc) return l_rc; // Load end address: MBMEAQ - l_rc = loadEndAddress(); if(l_rc) return l_rc; - + l_rc = loadEndAddress(); if(l_rc) return l_rc; + // Load stop conditions: MBASCTLQ l_rc = loadStopCondMask(); if(l_rc) return l_rc; @@ -1552,7 +1711,7 @@ fapi::ReturnCode mss_SuperFastRandomInit::setupAndExecuteCmd() // before a SuperFastRandomInit command is issued l_rc = fapiGetScom(iv_target, MBA01_MBA_WRD_MODE_0x03010449, iv_saved_MBA_WRD_MODE); if(l_rc) return l_rc; - + ecmdDataBufferBase l_data(64); l_ecmd_rc |= l_data.insert(iv_saved_MBA_WRD_MODE, 0, 64, 0); l_ecmd_rc |= l_data.setBit(0); @@ -1561,17 +1720,17 @@ fapi::ReturnCode mss_SuperFastRandomInit::setupAndExecuteCmd() { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } + } l_rc = fapiPutScom(iv_target, MBA01_MBA_WRD_MODE_0x03010449, l_data); if(l_rc) return l_rc; // Start the command: MBMCCQ l_rc = startMaintCmd(); if(l_rc) return l_rc; - - // Check for early problems with maint cmd instead of waiting for + + // Check for early problems with maint cmd instead of waiting for //cmd timeout l_rc = postConditionCheck(); if(l_rc) return l_rc; - + if(iv_poll == false) { FAPI_INF("Cmd has started. Use attentions to detect cmd complete."); @@ -1580,11 +1739,11 @@ fapi::ReturnCode mss_SuperFastRandomInit::setupAndExecuteCmd() // Poll for command complete: MBMSRQ l_rc = pollForMaintCmdComplete(); if(l_rc) return l_rc; - + // Collect FFDC l_rc = collectFFDC(); if(l_rc) return l_rc; - - FAPI_INF("EXIT mss_SuperFastRandomInit::setupAndExecuteCmd()"); + + FAPI_INF("EXIT mss_SuperFastRandomInit::setupAndExecuteCmd()"); return l_rc; } @@ -1595,7 +1754,7 @@ fapi::ReturnCode mss_SuperFastRandomInit::setupAndExecuteCmd() fapi::ReturnCode mss_SuperFastRandomInit::stopCmd() { - FAPI_INF("ENTER mss_SuperFastRandomInit::stopCmd()"); + FAPI_INF("ENTER mss_SuperFastRandomInit::stopCmd()"); fapi::ReturnCode l_rc; @@ -1606,16 +1765,16 @@ fapi::ReturnCode mss_SuperFastRandomInit::stopCmd() //iv_startAddr = 0x0000dead0000beefll; //printf( "addr stopped on: 0x%016llx\n", iv_startAddr ); - FAPI_INF("EXIT mss_SuperFastRandomInit::stopCmd()"); - + FAPI_INF("EXIT mss_SuperFastRandomInit::stopCmd()"); + return l_rc; } fapi::ReturnCode mss_SuperFastRandomInit::cleanupCmd() { - FAPI_INF("ENTER mss_SuperFastRandomInit::cleanupCmd()"); - + FAPI_INF("ENTER mss_SuperFastRandomInit::cleanupCmd()"); + fapi::ReturnCode l_rc; // Clear maintenance command complete attention, scrub stats, etc... @@ -1624,8 +1783,8 @@ fapi::ReturnCode mss_SuperFastRandomInit::cleanupCmd() l_rc = fapiPutScom(iv_target, MBA01_MBA_WRD_MODE_0x03010449, iv_saved_MBA_WRD_MODE); if(l_rc) return l_rc; - FAPI_INF("EXIT mss_SuperFastRandomInit::cleanupCmd()"); - + FAPI_INF("EXIT mss_SuperFastRandomInit::cleanupCmd()"); + return l_rc; } @@ -1659,31 +1818,31 @@ mss_SuperFastRead::mss_SuperFastRead( const fapi::Target & i_target, fapi::ReturnCode mss_SuperFastRead::setupAndExecuteCmd() { - FAPI_INF("ENTER mss_SuperFastRead::setupAndExecuteCmd()"); - + FAPI_INF("ENTER mss_SuperFastRead::setupAndExecuteCmd()"); + fapi::ReturnCode l_rc; uint32_t l_ecmd_rc = 0; - - // Gather data that needs to be stored. For testing purposes we will just + + // Gather data that needs to be stored. For testing purposes we will just // set an abitrary number. //l_rc = setSavedData( 0xdeadbeef ); if(l_rc) return l_rc; //printf( "Saved data: 0x%08x\n", getSavedData() ); // Make sure maint logic in valid state to run new cmd l_rc = preConditionCheck(); if(l_rc) return l_rc; - + // Load cmd type: MBMCTQ - l_rc = loadCmdType(); if(l_rc) return l_rc; - + l_rc = loadCmdType(); if(l_rc) return l_rc; + // Load start address: MBMACAQ - l_rc = loadStartAddress(); if(l_rc) return l_rc; + l_rc = loadStartAddress(); if(l_rc) return l_rc; // Load end address: MBMEAQ - l_rc = loadEndAddress(); if(l_rc) return l_rc; - + l_rc = loadEndAddress(); if(l_rc) return l_rc; + // Load stop conditions: MBASCTLQ l_rc = loadStopCondMask(); if(l_rc) return l_rc; - + // Need to set RRQ to fifo mode to ensure super fast read commands // are done on order. Otherwise, if cmds get out of order we can't be sure // the trapped address in MBMACA will be correct when we stop @@ -1692,7 +1851,7 @@ fapi::ReturnCode mss_SuperFastRead::setupAndExecuteCmd() // NOTE: Cleanup needs to be done to restore settings done. l_rc = fapiGetScom(iv_target, MBA01_MBA_RRQ0Q_0x0301040E, iv_saved_MBA_RRQ0); if(l_rc) return l_rc; - + ecmdDataBufferBase l_data(64); l_ecmd_rc |= l_data.insert(iv_saved_MBA_RRQ0, 0, 64, 0); l_ecmd_rc |= l_data.clearBit(6,5); // Set 6:10 = 00000 (fifo mode) @@ -1701,7 +1860,7 @@ fapi::ReturnCode mss_SuperFastRead::setupAndExecuteCmd() { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } + } l_rc = fapiPutScom(iv_target, MBA01_MBA_RRQ0Q_0x0301040E, l_data); if(l_rc) return l_rc; @@ -1724,7 +1883,7 @@ fapi::ReturnCode mss_SuperFastRead::setupAndExecuteCmd() // Start the command: MBMCCQ l_rc = startMaintCmd(); if(l_rc) return l_rc; - // Check for early problems with maint cmd instead of waiting for + // Check for early problems with maint cmd instead of waiting for // cmd timeout l_rc = postConditionCheck(); if(l_rc) return l_rc; @@ -1736,12 +1895,12 @@ fapi::ReturnCode mss_SuperFastRead::setupAndExecuteCmd() // Poll for command complete: MBMSRQ l_rc = pollForMaintCmdComplete(); if(l_rc) return l_rc; - + // Collect FFDC - l_rc = collectFFDC(); if(l_rc) return l_rc; + l_rc = collectFFDC(); if(l_rc) return l_rc; + + FAPI_INF("EXIT mss_SuperFastRead::setupAndExecuteCmd()"); - FAPI_INF("EXIT mss_SuperFastRead::setupAndExecuteCmd()"); - return l_rc; } @@ -1749,8 +1908,8 @@ fapi::ReturnCode mss_SuperFastRead::setupAndExecuteCmd() fapi::ReturnCode mss_SuperFastRead::stopCmd() { - FAPI_INF("ENTER mss_SuperFastRead::stopCmd()"); - + FAPI_INF("ENTER mss_SuperFastRead::stopCmd()"); + fapi::ReturnCode l_rc; // Stop the maintenace command if it is running. @@ -1760,18 +1919,18 @@ fapi::ReturnCode mss_SuperFastRead::stopCmd() //iv_startAddr = 0x0000dead0000beefll; //printf( "addr stopped on: 0x%016llx\n", iv_startAddr ); - FAPI_INF("EXIT mss_SuperFastRead::stopCmd()"); - + FAPI_INF("EXIT mss_SuperFastRead::stopCmd()"); + return l_rc; } fapi::ReturnCode mss_SuperFastRead::cleanupCmd() { - FAPI_INF("ENTER mss_SuperFastRead::cleanupCmd()"); - + FAPI_INF("ENTER mss_SuperFastRead::cleanupCmd()"); + fapi::ReturnCode l_rc; - + // Clear maintenance command complete attention, scrub stats, etc... // Restore the saved data. @@ -1780,9 +1939,9 @@ fapi::ReturnCode mss_SuperFastRead::cleanupCmd() // Undo rrq fifo mode l_rc = fapiPutScom(iv_target, MBA01_MBA_RRQ0Q_0x0301040E, iv_saved_MBA_RRQ0); if(l_rc) return l_rc; - - FAPI_INF("EXIT mss_SuperFastRead::cleanupCmd()"); - + + FAPI_INF("EXIT mss_SuperFastRead::cleanupCmd()"); + return l_rc; } @@ -1807,7 +1966,7 @@ mss_AtomicInject::mss_AtomicInject( const fapi::Target & i_target, NO_STOP_CONDITIONS, // i_stopCondition not used for this cmd true, // i_poll always true for this cmd cv_cmdType), - + iv_injectType( i_injectType ) // NOTE: iv_injectType is instance variable // of AtomicInject, since not needed // in parent class @@ -1820,25 +1979,25 @@ mss_AtomicInject::mss_AtomicInject( const fapi::Target & i_target, fapi::ReturnCode mss_AtomicInject::setupAndExecuteCmd() { - FAPI_INF("ENTER mss_AtomicInject::setupAndExecuteCmd()"); - + FAPI_INF("ENTER mss_AtomicInject::setupAndExecuteCmd()"); + fapi::ReturnCode l_rc; uint32_t l_ecmd_rc = 0; - - // Gather data that needs to be stored. For testing purposes we will just + + // Gather data that needs to be stored. For testing purposes we will just // set an abitrary number. //l_rc = setSavedData( 0xdeadbeef ); if(l_rc) return l_rc; //printf( "Saved data: 0x%08x\n", getSavedData() ); // Make sure maint logic in valid state to run new cmd l_rc = preConditionCheck(); if(l_rc) return l_rc; - + // Load cmd type: MBMCTQ - l_rc = loadCmdType(); if(l_rc) return l_rc; - + l_rc = loadCmdType(); if(l_rc) return l_rc; + // Load start address: MBMACAQ - l_rc = loadStartAddress(); if(l_rc) return l_rc; - + l_rc = loadStartAddress(); if(l_rc) return l_rc; + // Load stop conditions: MBASCTLQ l_rc = loadStopCondMask(); if(l_rc) return l_rc; @@ -1852,23 +2011,23 @@ fapi::ReturnCode mss_AtomicInject::setupAndExecuteCmd() { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } + } l_rc = fapiPutScom(iv_target, MBA01_MBECTLQ_0x03010610, l_injectType); if(l_rc) return l_rc; // Start the command: MBMCCQ l_rc = startMaintCmd(); if(l_rc) return l_rc; - + // Check for early problems with maint cmd instead of waiting for // cmd timeout l_rc = postConditionCheck(); if(l_rc) return l_rc; // Poll for command complete: MBMSRQ l_rc = pollForMaintCmdComplete(); if(l_rc) return l_rc; - + // Collect FFDC l_rc = collectFFDC(); if(l_rc) return l_rc; - + // Clear MBECCFIR ecmdDataBufferBase l_data(64); l_ecmd_rc |= l_data.flushTo0(); @@ -1876,14 +2035,14 @@ fapi::ReturnCode mss_AtomicInject::setupAndExecuteCmd() { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } - + } + l_rc = fapiPutScom(iv_targetCentaur, mss_mbeccfir[iv_mbaPosition], l_data); if(l_rc) return l_rc; - FAPI_INF("EXIT mss_AtomicInject::setupAndExecuteCmd()"); + FAPI_INF("EXIT mss_AtomicInject::setupAndExecuteCmd()"); + - return l_rc; } @@ -1891,10 +2050,10 @@ fapi::ReturnCode mss_AtomicInject::setupAndExecuteCmd() fapi::ReturnCode mss_AtomicInject::stopCmd() { - FAPI_INF("ENTER mss_AtomicInject::stopCmd()"); + FAPI_INF("ENTER mss_AtomicInject::stopCmd()"); fapi::ReturnCode l_rc; - FAPI_INF("EXIT mss_AtomicInject::stopCmd()"); - + FAPI_INF("EXIT mss_AtomicInject::stopCmd()"); + return l_rc; } @@ -1919,7 +2078,7 @@ mss_Display::mss_Display( const fapi::Target & i_target, NO_STOP_CONDITIONS, // i_stopCondition not used for this cmd true, // i_poll always true for this cmd cv_cmdType){} - + //--------------------------------------------------------- // mss_Display setupAndExecuteCmd @@ -1927,30 +2086,30 @@ mss_Display::mss_Display( const fapi::Target & i_target, fapi::ReturnCode mss_Display::setupAndExecuteCmd() { - FAPI_INF("ENTER mss_Display::setupAndExecuteCmd()"); - + FAPI_INF("ENTER mss_Display::setupAndExecuteCmd()"); + fapi::ReturnCode l_rc; - - // Gather data that needs to be stored. For testing purposes we will just + + // Gather data that needs to be stored. For testing purposes we will just // set an abitrary number. //l_rc = setSavedData( 0xdeadbeef ); if(l_rc) return l_rc; //printf( "Saved data: 0x%08x\n", getSavedData() ); // Make sure maint logic in valid state to run new cmd l_rc = preConditionCheck(); if(l_rc) return l_rc; - + // Load cmd type: MBMCTQ - l_rc = loadCmdType(); if(l_rc) return l_rc; - + l_rc = loadCmdType(); if(l_rc) return l_rc; + // Load start address: MBMACAQ - l_rc = loadStartAddress(); if(l_rc) return l_rc; + l_rc = loadStartAddress(); if(l_rc) return l_rc; // Load stop conditions: MBASCTLQ l_rc = loadStopCondMask(); if(l_rc) return l_rc; - + // Start the command: MBMCCQ l_rc = startMaintCmd(); if(l_rc) return l_rc; - + // Check for early problems with maint cmd instead of waiting for // cmd timeout l_rc = postConditionCheck(); if(l_rc) return l_rc; @@ -1963,30 +2122,30 @@ fapi::ReturnCode mss_Display::setupAndExecuteCmd() // Poll for command complete: MBMSRQ l_rc = pollForMaintCmdComplete(); if(l_rc) return l_rc; - + // Read the data from the display cmd: MBMSRQ - + static const uint32_t maintBufferReadDataRegs[16]={ MAINT0_MBA_MAINT_BUFF0_DATA0_0x03010655, MAINT0_MBA_MAINT_BUFF0_DATA1_0x03010656, MAINT0_MBA_MAINT_BUFF0_DATA2_0x03010657, MAINT0_MBA_MAINT_BUFF0_DATA3_0x03010658, - + MAINT0_MBA_MAINT_BUFF1_DATA0_0x03010665, MAINT0_MBA_MAINT_BUFF1_DATA1_0x03010666, MAINT0_MBA_MAINT_BUFF1_DATA2_0x03010667, MAINT0_MBA_MAINT_BUFF1_DATA3_0x03010668, - + MAINT0_MBA_MAINT_BUFF2_DATA0_0x03010675, MAINT0_MBA_MAINT_BUFF2_DATA1_0x03010676, MAINT0_MBA_MAINT_BUFF2_DATA2_0x03010677, MAINT0_MBA_MAINT_BUFF2_DATA3_0x03010678, - + MAINT0_MBA_MAINT_BUFF3_DATA0_0x03010685, MAINT0_MBA_MAINT_BUFF3_DATA1_0x03010686, MAINT0_MBA_MAINT_BUFF3_DATA2_0x03010687, MAINT0_MBA_MAINT_BUFF3_DATA3_0x03010688}; - + static const uint32_t maintBufferRead65thByteRegs[4]={ MAINT0_MBA_MAINT_BUFF_65TH_BYTE_64B_ECC0_0x03010695, MAINT0_MBA_MAINT_BUFF_65TH_BYTE_64B_ECC1_0x03010696, @@ -1996,23 +2155,23 @@ fapi::ReturnCode mss_Display::setupAndExecuteCmd() uint32_t loop = 0; ecmdDataBufferBase l_data(64); - + //---------------------------------------------------- // Read the data: 16 loops x 64bits = 128B cacheline //---------------------------------------------------- FAPI_INF("Read the data: 16 loops x 64bits = 128B cacheline"); - + for(loop=0; loop<16; loop++ ) { l_rc = fapiGetScom(iv_target, maintBufferReadDataRegs[loop], l_data); if(l_rc) return l_rc; } - + //---------------------------------------------------- // Read the 65th byte: 4 loops //---------------------------------------------------- FAPI_INF("Read the 65th byte: 4 loops"); - + for(loop=0; loop<4; loop++ ) { l_rc = fapiGetScom(iv_target, maintBufferRead65thByteRegs[loop], l_data); @@ -2021,9 +2180,9 @@ fapi::ReturnCode mss_Display::setupAndExecuteCmd() // Collect FFDC l_rc = collectFFDC(); if(l_rc) return l_rc; - - FAPI_INF("EXIT Display::setupAndExecuteCmd()"); - + + FAPI_INF("EXIT Display::setupAndExecuteCmd()"); + return l_rc; } @@ -2031,10 +2190,10 @@ fapi::ReturnCode mss_Display::setupAndExecuteCmd() fapi::ReturnCode mss_Display::stopCmd() { - FAPI_INF("ENTER mss_Display::stopCmd()"); + FAPI_INF("ENTER mss_Display::stopCmd()"); fapi::ReturnCode l_rc; - FAPI_INF("EXIT mss_Display::stopCmd()"); - + FAPI_INF("EXIT mss_Display::stopCmd()"); + return l_rc; } @@ -2051,7 +2210,7 @@ const mss_MaintCmd::CmdType mss_IncrementAddress::cv_cmdType = INCREMENT_MBMACA_ //--------------------------------------------------------- mss_IncrementAddress::mss_IncrementAddress( const fapi::Target & i_target ): - + mss_MaintCmd( i_target, ecmdDataBufferBase(64), // i_startAddr not used for this cmd ecmdDataBufferBase(64), // i_endAddr not used for this cmd @@ -2067,33 +2226,33 @@ fapi::ReturnCode mss_IncrementAddress::setupAndExecuteCmd() { - FAPI_INF("ENTER mss_IncrementAddress::setupAndExecuteCmd()"); + FAPI_INF("ENTER mss_IncrementAddress::setupAndExecuteCmd()"); + - fapi::ReturnCode l_rc; - + // Make sure maint logic in valid state to run new cmd l_rc = preConditionCheck(); if(l_rc) return l_rc; - + // Load cmd type: MBMCTQ - l_rc = loadCmdType(); if(l_rc) return l_rc; - + l_rc = loadCmdType(); if(l_rc) return l_rc; + // Read start address: MBMACAQ ecmdDataBufferBase l_mbmacaq(64); - l_rc = fapiGetScom(iv_target, MBA01_MBMACAQ_0x0301060D, l_mbmacaq); + l_rc = fapiGetScom(iv_target, MBA01_MBMACAQ_0x0301060D, l_mbmacaq); if(l_rc) return l_rc; FAPI_INF("MBMACAQ = 0x%.8X 0x%.8X", l_mbmacaq.getWord(0), l_mbmacaq.getWord(1)); - + // Start the command: MBMCCQ l_rc = startMaintCmd(); if(l_rc) return l_rc; - - // Check for early problems with maint cmd instead of waiting for + + // Check for early problems with maint cmd instead of waiting for // cmd timeout l_rc = postConditionCheck(); if(l_rc) return l_rc; // Poll for command complete: MBMSRQ l_rc = pollForMaintCmdComplete(); if(l_rc) return l_rc; - + // Read incremented start address: MBMACAQ l_rc = fapiGetScom(iv_target, MBA01_MBMACAQ_0x0301060D, l_mbmacaq); if(l_rc) return l_rc; @@ -2101,8 +2260,8 @@ fapi::ReturnCode mss_IncrementAddress::setupAndExecuteCmd() // Collect FFDC l_rc = collectFFDC(); if(l_rc) return l_rc; - FAPI_INF("EXIT mss_IncrementAddress::setupAndExecuteCmd()"); - + FAPI_INF("EXIT mss_IncrementAddress::setupAndExecuteCmd()"); + return l_rc; } @@ -2110,10 +2269,10 @@ fapi::ReturnCode mss_IncrementAddress::setupAndExecuteCmd() fapi::ReturnCode mss_IncrementAddress::stopCmd() { - FAPI_INF("ENTER mss_IncrementAddress::stopCmd()"); + FAPI_INF("ENTER mss_IncrementAddress::stopCmd()"); fapi::ReturnCode l_rc; - FAPI_INF("EXIT mss_IncrementAddress::stopCmd()"); - + FAPI_INF("EXIT mss_IncrementAddress::stopCmd()"); + return l_rc; } @@ -2131,7 +2290,7 @@ const mss_MaintCmd::CmdType mss_TimeBaseScrub::cv_cmdType = TIMEBASE_SCRUB; mss_TimeBaseScrub::mss_TimeBaseScrub( const fapi::Target & i_target, const ecmdDataBufferBase & i_startAddr, const ecmdDataBufferBase & i_endAddr, - TimeBaseSpeed i_speed, + TimeBaseSpeed i_speed, uint32_t i_stopCondition, bool i_poll ) : mss_MaintCmd( i_target, @@ -2141,9 +2300,9 @@ mss_TimeBaseScrub::mss_TimeBaseScrub( const fapi::Target & i_target, i_poll, cv_cmdType), - // NOTE: iv_speed is instance variable of TimeBaseScrub, since not + // NOTE: iv_speed is instance variable of TimeBaseScrub, since not // needed in parent class - iv_speed( i_speed ) + iv_speed( i_speed ) {} @@ -2154,33 +2313,33 @@ mss_TimeBaseScrub::mss_TimeBaseScrub( const fapi::Target & i_target, fapi::ReturnCode mss_TimeBaseScrub::setupAndExecuteCmd() { - FAPI_INF("ENTER mss_TimeBaseScrub::setupAndExecuteCmd()"); - + FAPI_INF("ENTER mss_TimeBaseScrub::setupAndExecuteCmd()"); + fapi::ReturnCode l_rc; - - // Gather data that needs to be stored. For testing purposes we will just + + // Gather data that needs to be stored. For testing purposes we will just // set an abitrary number. //l_rc = setSavedData( 0xdeadbeef ); if(l_rc) return l_rc; //printf( "Saved data: 0x%08x\n", getSavedData() ); // Make sure maint logic in valid state to run new cmd l_rc = preConditionCheck(); if(l_rc) return l_rc; - + // Load cmd type: MBMCTQ - l_rc = loadCmdType(); if(l_rc) return l_rc; - + l_rc = loadCmdType(); if(l_rc) return l_rc; + // Load start address: MBMACAQ - l_rc = loadStartAddress(); if(l_rc) return l_rc; + l_rc = loadStartAddress(); if(l_rc) return l_rc; // Load end address: MBMEAQ - l_rc = loadEndAddress(); if(l_rc) return l_rc; - + l_rc = loadEndAddress(); if(l_rc) return l_rc; + // Load speed: MBMCTQ - l_rc = loadSpeed(iv_speed); if(l_rc) return l_rc; - + l_rc = loadSpeed(iv_speed); if(l_rc) return l_rc; + // Load stop conditions: MBASCTLQ l_rc = loadStopCondMask(); if(l_rc) return l_rc; - + /* // DEBUG. Set hard CE threshold to 1: MBSTRQ FAPI_INF("\nDEBUG. Set hard CE threshold to 1: MBSTRQ"); @@ -2197,8 +2356,8 @@ fapi::ReturnCode mss_TimeBaseScrub::setupAndExecuteCmd() // Start the command: MBMCCQ l_rc = startMaintCmd(); if(l_rc) return l_rc; - - // Check for early problems with maint cmd instead of waiting for + + // Check for early problems with maint cmd instead of waiting for // cmd timeout l_rc = postConditionCheck(); if(l_rc) return l_rc; @@ -2212,10 +2371,10 @@ fapi::ReturnCode mss_TimeBaseScrub::setupAndExecuteCmd() l_rc = pollForMaintCmdComplete(); if(l_rc) return l_rc; // Collect FFDC - l_rc = collectFFDC(); if(l_rc) return l_rc; + l_rc = collectFFDC(); if(l_rc) return l_rc; + + FAPI_INF("EXIT mss_TimeBaseScrub::setupAndExecuteCmd()"); - FAPI_INF("EXIT mss_TimeBaseScrub::setupAndExecuteCmd()"); - return l_rc; } @@ -2223,8 +2382,8 @@ fapi::ReturnCode mss_TimeBaseScrub::setupAndExecuteCmd() fapi::ReturnCode mss_TimeBaseScrub::stopCmd() { - FAPI_INF("ENTER mss_TimeBaseScrub::stopCmd()"); - + FAPI_INF("ENTER mss_TimeBaseScrub::stopCmd()"); + fapi::ReturnCode l_rc; // Stop the maintenace command if it is running. @@ -2234,25 +2393,152 @@ fapi::ReturnCode mss_TimeBaseScrub::stopCmd() //iv_startAddr = 0x0000dead0000beefll; //printf( "addr stopped on: 0x%016llx\n", iv_startAddr ); - FAPI_INF("EXIT mss_TimeBaseScrub::stopCmd()"); - + FAPI_INF("EXIT mss_TimeBaseScrub::stopCmd()"); + return l_rc; } fapi::ReturnCode mss_TimeBaseScrub::cleanupCmd() { - FAPI_INF("ENTER mss_TimeBaseScrub::cleanupCmd()"); - + FAPI_INF("ENTER mss_TimeBaseScrub::cleanupCmd()"); + fapi::ReturnCode l_rc; - + // Clear maintenance command complete attention, scrub stats, etc... // Restore the saved data. //printf( "Saved data: 0x%08x\n", getSavedData() ); - FAPI_INF("EXIT mss_TimeBaseScrub::cleanupCmd()"); + FAPI_INF("EXIT mss_TimeBaseScrub::cleanupCmd()"); + + return l_rc; +} + + +//------------------------------------------------------------------------------ +// mss_TimeBaseSteerCleanup +//------------------------------------------------------------------------------ + +const mss_MaintCmd::CmdType mss_TimeBaseSteerCleanup::cv_cmdType = TIMEBASE_STEER_CLEANUP; + +//--------------------------------------------------------- +// mss_TimeBaseSteerCleanup Constructor +//--------------------------------------------------------- + +mss_TimeBaseSteerCleanup::mss_TimeBaseSteerCleanup( const fapi::Target & i_target, + const ecmdDataBufferBase & i_startAddr, + const ecmdDataBufferBase & i_endAddr, + TimeBaseSpeed i_speed, + uint32_t i_stopCondition, + bool i_poll ) : + mss_MaintCmd( i_target, + i_startAddr, + i_endAddr, + i_stopCondition, + i_poll, + cv_cmdType), + + // NOTE: iv_speed is instance variable of TimeBaseSteerCleanup, since not + // needed in parent class + iv_speed( i_speed ) + {} + + + +//--------------------------------------------------------- +// mss_TimeBaseSteerCleanup setupAndExecuteCmd +//--------------------------------------------------------- + +fapi::ReturnCode mss_TimeBaseSteerCleanup::setupAndExecuteCmd() +{ + FAPI_INF("ENTER mss_TimeBaseSteerCleanup::setupAndExecuteCmd()"); + + fapi::ReturnCode l_rc; + // Gather data that needs to be stored. For testing purposes we will just + // set an abitrary number. + //l_rc = setSavedData( 0xdeadbeef ); if(l_rc) return l_rc; + //printf( "Saved data: 0x%08x\n", getSavedData() ); + + // Make sure maint logic in valid state to run new cmd + l_rc = preConditionCheck(); if(l_rc) return l_rc; + + // Load cmd type: MBMCTQ + l_rc = loadCmdType(); if(l_rc) return l_rc; + + // Load start address: MBMACAQ + l_rc = loadStartAddress(); if(l_rc) return l_rc; + + // Load end address: MBMEAQ + l_rc = loadEndAddress(); if(l_rc) return l_rc; + + // Load speed: MBMCTQ + // TODO: May be able to go faster during IPL than runtime, since don't + // have to worry about hanging fetch traffic during IPL. + l_rc = loadSpeed(iv_speed); if(l_rc) return l_rc; + + // Load stop conditions: MBASCTLQ + l_rc = loadStopCondMask(); if(l_rc) return l_rc; + + // Start the command: MBMCCQ + l_rc = startMaintCmd(); if(l_rc) return l_rc; + + // Check for early problems with maint cmd instead of waiting for + // cmd timeout + l_rc = postConditionCheck(); if(l_rc) return l_rc; + + if(iv_poll == false) + { + FAPI_INF("Cmd has started. Use attentions to detect cmd complete."); + return l_rc; + } + + // Poll for command complete: MBMSRQ + l_rc = pollForMaintCmdComplete(); if(l_rc) return l_rc; + + // Collect FFDC + l_rc = collectFFDC(); if(l_rc) return l_rc; + + FAPI_INF("EXIT mss_TimeBaseSteerCleanup::setupAndExecuteCmd()"); + + return l_rc; + +} + +fapi::ReturnCode mss_TimeBaseSteerCleanup::stopCmd() +{ + + FAPI_INF("ENTER mss_TimeBaseSteerCleanup::stopCmd()"); + + fapi::ReturnCode l_rc; + + // Stop the maintenace command if it is running. + + // Update the iv_startAddr to the addr the maintenenance command + // stopped on. For testing purposes we will just set an abitrary number. + //iv_startAddr = 0x0000dead0000beefll; + //printf( "addr stopped on: 0x%016llx\n", iv_startAddr ); + + FAPI_INF("EXIT mss_TimeBaseSteerCleanup::stopCmd()"); + + return l_rc; +} + +fapi::ReturnCode mss_TimeBaseSteerCleanup::cleanupCmd() +{ + + FAPI_INF("ENTER mss_TimeBaseSteerCleanup::cleanupCmd()"); + + fapi::ReturnCode l_rc; + + // Clear maintenance command complete attention, scrub stats, etc... + + // Restore the saved data. + //printf( "Saved data: 0x%08x\n", getSavedData() ); + + FAPI_INF("EXIT mss_TimeBaseSteerCleanup::cleanupCmd()"); + return l_rc; } @@ -2272,57 +2558,63 @@ fapi::ReturnCode mss_get_address_range( const fapi::Target & i_target, { - FAPI_INF("ENTER mss_get_address_range()"); + FAPI_INF("ENTER mss_get_address_range()"); - static const uint8_t memConfigType[9][4][2]={ - - // SUBTYPE_A SUBTYPE_B SUBTYPE_C SUBTYPE_D - //SLOT_0_ONLY SLOT_0_AND_1 SLOT_0_ONLY SLOT_0_AND_1 SLOT_0_ONLY SLOT_0_AND_1 SLOT_0_ONLY SLOT_0_AND_1 - {{0xff, 0xff}, {0xff, 0xff}, {0xff, 0xff}, {0xff, 0xff}}, // TYPE_0 - {{0x00, 0x04}, {0x01, 0x05}, {0x03, 0x07}, {0xff, 0xff}}, // TYPE_1 - {{0xff, 0xff}, {0xff, 0xff}, {0xff, 0xff}, {0xff, 0xff}}, // TYPE_2 - {{0x01, 0x05}, {0x01, 0x05}, {0x01, 0x05}, {0xff, 0xff}}, // TYPE_3 - {{0x03, 0x07}, {0x03, 0x07}, {0x03, 0x07}, {0xff, 0xff}}, // TYPE_4 - {{0x00, 0x04}, {0x01, 0x05}, {0x03, 0x07}, {0x07, 0xff}}, // TYPE_5 - {{0xff, 0xff}, {0xff, 0xff}, {0xff, 0xff}, {0xff, 0xff}}, // TYPE_6 - {{0x01, 0x05}, {0x01, 0x05}, {0x01, 0x05}, {0xff, 0xff}}, // TYPE_7 - {{0x03, 0x07}, {0x03, 0x07}, {0x03, 0x07}, {0xff, 0xff}}};// TYPE_8 - + // Refer to Centaur Workbook: 5.2 Master and Slave Rank Usage + // + // SUBTYPE_A SUBTYPE_B SUBTYPE_C SUBTYPE_D + // + //SLOT_0_ONLY SLOT_0_AND_1 SLOT_0_ONLY SLOT_0_AND_1 SLOT_0_ONLY SLOT_0_AND_1 SLOT_0_ONLY SLOT_0_AND_1 + // + //master slave master slave master slave master slave master slave master slave master slave master slave + // + {{0xff, 0xff}, {0xff, 0xff}, {0xff, 0xff}, {0xff, 0xff}}, // TYPE_0 + {{0x00, 0x40}, {0x10, 0x50}, {0x30, 0x70}, {0xff, 0xff}}, // TYPE_1 + {{0x01, 0x41}, {0x03, 0x43}, {0x07, 0x47}, {0xff, 0xff}}, // TYPE_2 + {{0x11, 0x51}, {0x13, 0x53}, {0x17, 0x57}, {0xff, 0xff}}, // TYPE_3 + {{0x31, 0x71}, {0x33, 0x73}, {0x37, 0x77}, {0xff, 0xff}}, // TYPE_4 + {{0x00, 0x40}, {0x10, 0x50}, {0x30, 0x70}, {0xff, 0xff}}, // TYPE_5 + {{0x01, 0x41}, {0x03, 0x43}, {0x07, 0x47}, {0xff, 0xff}}, // TYPE_6 + {{0x11, 0x51}, {0x13, 0x53}, {0x17, 0x57}, {0xff, 0xff}}, // TYPE_7 + {{0x31, 0x71}, {0x33, 0x73}, {0x37, 0x77}, {0xff, 0xff}}}; // TYPE_8 + // TODO: Need to update when 5D config confirmed. + fapi::ReturnCode l_rc; - uint32_t l_ecmd_rc = 0; + uint32_t l_ecmd_rc = 0; ecmdDataBufferBase l_data(64); mss_MemConfig::MemOrg l_row; mss_MemConfig::MemOrg l_col; mss_MemConfig::MemOrg l_bank; uint32_t l_dramSize = 0; - uint32_t l_dramWidth = 0; + uint8_t l_dramWidth = 0; fapi::Target l_targetCentaur; uint8_t l_mbaPosition = 0; uint8_t l_isSIM = 1; - + uint8_t l_slotConfig = 0; uint8_t l_configType = 0; uint8_t l_configSubType = 0; - uint8_t l_end_rank = 0; - + uint8_t l_end_master_rank = 0; + uint8_t l_end_slave_rank = 0; + // Get Centaur target for the given MBA - l_rc = fapiGetParentChip(i_target, l_targetCentaur); + l_rc = fapiGetParentChip(i_target, l_targetCentaur); if(l_rc) { FAPI_ERR("Error getting Centaur parent target for the given MBA"); return l_rc; } - - // Get MBA position: 0 = mba01, 1 = mba23 + + // Get MBA position: 0 = mba01, 1 = mba23 l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_target, l_mbaPosition); if(l_rc) { FAPI_ERR("Error getting MBA position"); return l_rc; } - + // Check system attribute if sim: 1 = Awan/HWSimulator. 0 = Simics/RealHW. l_rc = FAPI_ATTR_GET(ATTR_IS_SIMULATION, NULL, l_isSIM); if(l_rc) @@ -2330,32 +2622,39 @@ fapi::ReturnCode mss_get_address_range( const fapi::Target & i_target, FAPI_ERR("Error getting ATTR_IS_SIMULATION"); return l_rc; } - + + // Get l_dramWidth + l_rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &i_target, l_dramWidth); + if(l_rc) + { + FAPI_ERR("Error getting DRAM width"); + return l_rc; + } + // Check MBAXCRn, to show memory configured behind this MBA l_rc = fapiGetScom(l_targetCentaur, mss_mbaxcr[l_mbaPosition], l_data); if(l_rc) return l_rc; if (l_data.isBitClear(0,4)) { - // Create new log. + // Create new log. FAPI_ERR("MBAXCRn[0:3] = 0, meaning no memory configured behind this MBA."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_NO_MEM_CNFG); return l_rc; } - + //******************************************************************** // Find max row/col/bank, based on l_dramSize and l_dramWidth //******************************************************************** - // Get l_dramSize and l_dramWidth + // Get l_dramSize l_ecmd_rc |= l_data.extractPreserve(&l_dramSize, 6, 2, 32-2); // (6:7) - l_ecmd_rc |= l_data.extractPreserve(&l_dramWidth, 9, 1, 32-1); // (9) if(l_ecmd_rc) { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } + } - if((l_dramWidth == mss_MemConfig::X8) && (l_dramSize == mss_MemConfig::GBIT_2)) + if((l_dramWidth == mss_MemConfig::X8) && (l_dramSize == mss_MemConfig::GBIT_2)) { // For memory part Size = 256Mbx8 (2Gb), row/col/bank = 15/10/3 FAPI_INF("For memory part Size = 256Mbx8 (2Gb), row/col/bank = 15/10/3"); @@ -2363,7 +2662,7 @@ fapi::ReturnCode mss_get_address_range( const fapi::Target & i_target, l_col = mss_MemConfig::COL_10; l_bank = mss_MemConfig::BANK_3; } - else if((l_dramWidth == mss_MemConfig::X4) && (l_dramSize == mss_MemConfig::GBIT_2)) + else if((l_dramWidth == mss_MemConfig::X4) && (l_dramSize == mss_MemConfig::GBIT_2)) { // For memory part Size = 512Mbx4 (2Gb), row/col/bank = 15/11/3 FAPI_INF("For memory part Size = 512Mbx4 (2Gb), row/col/bank = 15/11/3"); @@ -2374,15 +2673,15 @@ fapi::ReturnCode mss_get_address_range( const fapi::Target & i_target, else if((l_dramWidth == mss_MemConfig::X8) && (l_dramSize == mss_MemConfig::GBIT_4)) { // For memory part Size = 512Mbx8 (4Gb), row/col/bank = 16/10/3 - FAPI_INF("For memory part Size = 512Mbx8 (4Gb), row/col/bank = 16/10/3"); + FAPI_INF("For memory part Size = 512Mbx8 (4Gb), row/col/bank = 16/10/3"); l_row = mss_MemConfig::ROW_16; l_col = mss_MemConfig::COL_10; l_bank = mss_MemConfig::BANK_3; } - else if((l_dramWidth == mss_MemConfig::X4) && (l_dramSize == mss_MemConfig::GBIT_4)) + else if((l_dramWidth == mss_MemConfig::X4) && (l_dramSize == mss_MemConfig::GBIT_4)) { // For memory part Size = 1Gbx4 (4Gb), row/col/bank = 16/11/3 - FAPI_INF("For memory part Size = 1Gbx4 (4Gb), row/col/bank = 16/11/3"); + FAPI_INF("For memory part Size = 1Gbx4 (4Gb), row/col/bank = 16/11/3"); l_row = mss_MemConfig::ROW_16; l_col = mss_MemConfig::COL_11; l_bank = mss_MemConfig::BANK_3; @@ -2390,7 +2689,7 @@ fapi::ReturnCode mss_get_address_range( const fapi::Target & i_target, else if((l_dramWidth == mss_MemConfig::X8) && (l_dramSize == mss_MemConfig::GBIT_8)) { // For memory part Size = 1Gbx8 (8Gb), row/col/bank = 16/11/3 - FAPI_INF("For memory part Size = 1Gbx8 (8Gb), row/col/bank = 16/11/3"); + FAPI_INF("For memory part Size = 1Gbx8 (8Gb), row/col/bank = 16/11/3"); l_row = mss_MemConfig::ROW_16; l_col = mss_MemConfig::COL_11; l_bank = mss_MemConfig::BANK_3; @@ -2398,7 +2697,7 @@ fapi::ReturnCode mss_get_address_range( const fapi::Target & i_target, else if((l_dramWidth == mss_MemConfig::X4) && (l_dramSize == mss_MemConfig::GBIT_8)) { // For memory part Size = 2Gbx4 (8Gb), row/col/bank = 16/12/3 - FAPI_INF("For memory part Size = 2Gbx4 (8Gb), row/col/bank = 16/12/3"); + FAPI_INF("For memory part Size = 2Gbx4 (8Gb), row/col/bank = 16/12/3"); l_row = mss_MemConfig::ROW_16; l_col = mss_MemConfig::COL_12; l_bank = mss_MemConfig::BANK_3; @@ -2413,100 +2712,115 @@ fapi::ReturnCode mss_get_address_range( const fapi::Target & i_target, //******************************************************************** - // Find l_end_rank based on DIMM configuration - //******************************************************************** + // Find l_end_master_rank and l_end_slave_rank based on DIMM configuration + //******************************************************************** // (0:3) Configuration type (1-8) - l_ecmd_rc |= l_data.extractPreserve(&l_configType, 0, 4, 8-4); - + l_ecmd_rc |= l_data.extractPreserve(&l_configType, 0, 4, 8-4); + // (4:5) Configuration subtype (A, B, C, D) l_ecmd_rc |= l_data.extractPreserve(&l_configSubType, 4, 2, 8-2); - + // (8) Slot Configuration - // 0 = Centaur DIMM or IS DIMM, slot0 only, 1 = IS DIMM slots 0 and 1 - l_ecmd_rc |= l_data.extractPreserve(&l_slotConfig, 8, 1, 8-1); + // 0 = Centaur DIMM or IS DIMM, slot0 only, 1 = IS DIMM slots 0 and 1 + l_ecmd_rc |= l_data.extractPreserve(&l_slotConfig, 8, 1, 8-1); if(l_ecmd_rc) { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } + } - l_end_rank = memConfigType[l_configType][l_configSubType][l_slotConfig]; - - if (l_end_rank == 0xff) + FAPI_INF("memConfigType[%d][%d][%d] = 0x%02x", + l_configType,l_configSubType,l_slotConfig, + memConfigType[l_configType][l_configSubType][l_slotConfig]); + + l_end_master_rank = (memConfigType[l_configType][l_configSubType][l_slotConfig] & 0xf0) >> 4; + l_end_slave_rank = memConfigType[l_configType][l_configSubType][l_slotConfig] & 0x0f; + + FAPI_INF("end master rank = %d, end slave rank = %d", l_end_master_rank, l_end_slave_rank); + + if ((l_end_master_rank == 0x0f) || (l_end_slave_rank == 0x0f)) { - // Create new log. - FAPI_ERR("MBAXCRn configured with invalid combination of l_configType, l_configSubType, l_slotConfig"); + // Create new log. + FAPI_ERR("MBAXCRn configured with unsupported combination of l_configType, l_configSubType, l_slotConfig"); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_INVALID_DIMM_CNFG); return l_rc; } - - //******************************************************************** + + //******************************************************************** // Get address range for all ranks configured behind this MBA - //******************************************************************** + //******************************************************************** if (i_rank == MSS_ALL_RANKS) { FAPI_INF("Get address range for rank = ALL_RANKS"); - + // Start address is just rank 0 with row/col/bank all 0's - o_startAddr.flushTo0(); - + o_startAddr.flushTo0(); + // If Awan/HWSimulator, end address is just start address +3 if (l_isSIM) { FAPI_INF("ATTR_IS_SIMULATION = 1, Awan/HWSimulator, so use smaller address range."); - + // Do only rank0, row0, all banks all cols - l_end_rank = 0; + l_end_master_rank = 0; + l_end_slave_rank = 0; + uint32_t l_row_zero = 0; l_ecmd_rc |= o_endAddr.flushTo0(); - // RANK = 0:3 - l_ecmd_rc |= o_endAddr.insert( l_end_rank, 0, 4, 8-4 ); - - // BANK = 7:10 + // MASTER RANK = 0:3 + l_ecmd_rc |= o_endAddr.insert( l_end_master_rank, 0, 4, 8-4 ); + + // SLAVE RANK = 4:6 + l_ecmd_rc |= o_endAddr.insert( l_end_slave_rank, 4, 3, 8-3 ); + + // BANK = 7:10 l_ecmd_rc |= o_endAddr.insert( (uint32_t)l_bank, 7, 4, 32-4 ); - - // ROW = 11:27 + + // ROW = 11:27 l_ecmd_rc |= o_endAddr.insert( (uint32_t)l_row_zero, 11, 17, 32-17 ); - + // COL = 28:39, note: c2, c1, c0 always 0 - l_ecmd_rc |= o_endAddr.insert( (uint32_t)l_col, 28, 12, 32-12 ); - + l_ecmd_rc |= o_endAddr.insert( (uint32_t)l_col, 28, 12, 32-12 ); + } - // Else, set end address to be last address of l_end_rank + // Else, set end address to be last address of l_end_master_rank else { l_ecmd_rc |= o_endAddr.flushTo0(); - - // RANK = 0:3 - l_ecmd_rc |= o_endAddr.insert( l_end_rank, 0, 4, 8-4 ); - + + // MASTER RANK = 0:3 + l_ecmd_rc |= o_endAddr.insert( l_end_master_rank, 0, 4, 8-4 ); + + // SLAVE RANK = 4:6 + l_ecmd_rc |= o_endAddr.insert( l_end_slave_rank, 4, 3, 8-3 ); + // BANK = 7:10 l_ecmd_rc |= o_endAddr.insert( (uint32_t)l_bank, 7, 4, 32-4 ); - - // ROW = 11:27 + + // ROW = 11:27 l_ecmd_rc |= o_endAddr.insert( (uint32_t)l_row, 11, 17, 32-17 ); - - // COL = 28:39, note: c2, c1, c0 always 0 - l_ecmd_rc |= o_endAddr.insert( (uint32_t)l_col, 28, 12, 32-12 ); - } + + // COL = 28:39, note: c2, c1, c0 always 0 + l_ecmd_rc |= o_endAddr.insert( (uint32_t)l_col, 28, 12, 32-12 ); + } } - - //******************************************************************** + + //******************************************************************** // Get address range for single rank configured behind this MBA - //******************************************************************** + //******************************************************************** else { - FAPI_INF("Get address range for rank = %d\n", i_rank ); - - // NOTE: If this rank is not valid, we should see MBAFIR[1]: invalid + FAPI_INF("Get address range for master rank = %d\n", i_rank ); + + // NOTE: If this rank is not valid, we should see MBAFIR[1]: invalid // maint address, when cmd started - + // DEBUG - run on last few address of the rank /* // Set end address to end of rank @@ -2519,33 +2833,40 @@ fapi::ReturnCode mss_get_address_range( const fapi::Target & i_target, // Set start address so we do all banks/cols in last row of the rank uint32_t l_bank_zero = 0; - uint32_t l_col_zero = 0; - l_ecmd_rc |= o_startAddr.flushTo0(); - l_ecmd_rc |= o_startAddr.insert( i_rank, 0, 4, 8-4 ); - l_ecmd_rc |= o_startAddr.insert( (uint32_t)l_bank_zero, 7, 4, 32-4 ); - l_ecmd_rc |= o_startAddr.insert( (uint32_t)l_row, 11, 17, 32-17 ); - l_ecmd_rc |= o_startAddr.insert( (uint32_t)l_col_zero, 28, 12, 32-12 ); + uint32_t l_col_zero = 0; + l_ecmd_rc |= o_startAddr.flushTo0(); + l_ecmd_rc |= o_startAddr.insert( i_rank, 0, 4, 8-4 ); + l_ecmd_rc |= o_startAddr.insert( (uint32_t)l_bank_zero, 7, 4, 32-4 ); + l_ecmd_rc |= o_startAddr.insert( (uint32_t)l_row, 11, 17, 32-17 ); + l_ecmd_rc |= o_startAddr.insert( (uint32_t)l_col_zero, 28, 12, 32-12 ); */ // DEBUG - run on last few address of the rank - + // Start address is just i_rank with row/col/bank all 0's l_ecmd_rc |= o_startAddr.flushTo0(); - // RANK = 0:3 - l_ecmd_rc |= o_startAddr.insert( i_rank, 0, 4, 8-4 ); - + // MASTER RANK = 0:3 + l_ecmd_rc |= o_startAddr.insert( i_rank, 0, 4, 8-4 ); + // If Awan/HWSimulator, end address is just start address +3 if (l_isSIM) { FAPI_INF("ATTR_IS_SIMULATION = 1, Awan/HWSimulator, so use smaller address range."); + + l_end_slave_rank = 0; + uint32_t l_row_zero = 0; l_ecmd_rc |= o_endAddr.flushTo0(); - // RANK = 0:3 + // MASTER RANK = 0:3 l_ecmd_rc |= o_endAddr.insert( i_rank, 0, 4, 8-4 ); + + // SLAVE RANK = 4:6 + l_ecmd_rc |= o_endAddr.insert( l_end_slave_rank, 4, 3, 8-3 ); + // BANK = 7:10 l_ecmd_rc |= o_endAddr.insert( (uint32_t)l_bank, 7, 4, 32-4 ); - // ROW = 11:27 + // ROW = 11:27 l_ecmd_rc |= o_endAddr.insert( (uint32_t)l_row_zero, 11, 17, 32-17 ); // COL = 28:39, note: c2, c1, c0 always 0 l_ecmd_rc |= o_endAddr.insert( (uint32_t)l_col, 28, 12, 32-12 ); @@ -2555,27 +2876,31 @@ fapi::ReturnCode mss_get_address_range( const fapi::Target & i_target, else { l_ecmd_rc |= o_endAddr.flushTo0(); - // RANK = 0:3 + // MASTER RANK = 0:3 l_ecmd_rc |= o_endAddr.insert( i_rank, 0, 4, 8-4 ); + + // SLAVE RANK = 4:6 + l_ecmd_rc |= o_endAddr.insert( l_end_slave_rank, 4, 3, 8-3 ); + // BANK = 7:10 l_ecmd_rc |= o_endAddr.insert( (uint32_t)l_bank, 7, 4, 32-4 ); - // ROW = 11:27 + // ROW = 11:27 l_ecmd_rc |= o_endAddr.insert( (uint32_t)l_row, 11, 17, 32-17 ); // COL = 28:36 l_ecmd_rc |= o_endAddr.insert( (uint32_t)l_col, 28, 12, 32-12 ); } - + } - + if(l_ecmd_rc) { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } + } - - FAPI_INF("EXIT mss_get_address_range()"); + + FAPI_INF("EXIT mss_get_address_range()"); return l_rc; } @@ -2593,22 +2918,21 @@ fapi::ReturnCode mss_get_mark_store( const fapi::Target & i_target, uint8_t & o_chipMark ) { - - FAPI_INF("ENTER mss_get_mark_store()"); - - fapi::ReturnCode l_rc; uint32_t l_ecmd_rc = 0; ecmdDataBufferBase l_markstore(64); ecmdDataBufferBase l_mbeccfir(64); ecmdDataBufferBase l_data(64); - uint32_t l_dramWidth = 0; + uint8_t l_dramWidth = 0; uint8_t l_symbolMarkGalois = 0; uint8_t l_chipMarkGalois = 0; uint8_t l_symbolsPerChip = 4; fapi::Target l_targetCentaur; uint8_t l_mbaPosition = 0; + o_symbolMark = MSS_INVALID_SYMBOL; + o_chipMark = MSS_INVALID_SYMBOL; + // Get Centaur target for the given MBA l_rc = fapiGetParentChip(i_target, l_targetCentaur); if(l_rc) @@ -2617,31 +2941,34 @@ fapi::ReturnCode mss_get_mark_store( const fapi::Target & i_target, return l_rc; } - + // Get MBA position: 0 = mba01, 1 = mba23 l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_target, l_mbaPosition); if(l_rc) { FAPI_ERR("Error getting MBA position"); return l_rc; - } + } + + // Get l_dramWidth + l_rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &i_target, l_dramWidth); + if(l_rc) + { + FAPI_ERR("Error getting DRAM width"); + return l_rc; + } - // Get l_dramWidth - l_rc = fapiGetScom(l_targetCentaur, mss_mbaxcr[l_mbaPosition], l_data); - if(l_rc) return l_rc; - l_ecmd_rc |= l_data.extractPreserve(&l_dramWidth, 9, 1, 32-1); - // Read markstore register for the given rank - l_rc = fapiGetScom(l_targetCentaur, mss_markStoreRegs[i_rank][l_mbaPosition], l_markstore); + l_rc = fapiGetScom(l_targetCentaur, mss_markStoreRegs[i_rank][l_mbaPosition], l_markstore); if(l_rc) return l_rc; - + // If MPE FIR for the given rank (scrub or fetch) is on after the read, // we will read one more time just to make sure we get latest. - l_rc = fapiGetScom(l_targetCentaur, mss_mbeccfir[l_mbaPosition], l_mbeccfir); + l_rc = fapiGetScom(l_targetCentaur, mss_mbeccfir[l_mbaPosition], l_mbeccfir); if(l_rc) return l_rc; if (l_mbeccfir.isBitSet(i_rank) || l_mbeccfir.isBitSet(20 + i_rank)) { - l_rc = fapiGetScom(l_targetCentaur, mss_markStoreRegs[i_rank][l_mbaPosition], l_markstore); + l_rc = fapiGetScom(l_targetCentaur, mss_markStoreRegs[i_rank][l_mbaPosition], l_markstore); if(l_rc) return l_rc; } @@ -2651,11 +2978,11 @@ fapi::ReturnCode mss_get_mark_store( const fapi::Target & i_target, { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } - + } + if (l_symbolMarkGalois == 0x00) // No symbol mark { - o_symbolMark = 0xff; + o_symbolMark = MSS_INVALID_SYMBOL; } else if (l_dramWidth == mss_MemConfig::X4) { @@ -2681,22 +3008,22 @@ fapi::ReturnCode mss_get_mark_store( const fapi::Target & i_target, // Create new log. FAPI_ERR("Invalid galois field in markstore."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_INVALID_MARKSTORE); - return l_rc; + return l_rc; } } - + // Get l_chipMarkGalois l_ecmd_rc |= l_markstore.extractPreserve(&l_chipMarkGalois, 8, 8, 8-8); if(l_ecmd_rc) { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } + } + - if (l_chipMarkGalois == 0x00) // No chip mark { - o_chipMark = 0xff; + o_chipMark = MSS_INVALID_SYMBOL; } else // Converted from galois field to chip index { @@ -2709,7 +3036,7 @@ fapi::ReturnCode mss_get_mark_store( const fapi::Target & i_target, { l_symbolsPerChip = 4; } - + o_chipMark = MSS_SYMBOLS_PER_RANK; for ( uint32_t i = 0; i < MSS_SYMBOLS_PER_RANK; i=i+l_symbolsPerChip) { @@ -2725,13 +3052,13 @@ fapi::ReturnCode mss_get_mark_store( const fapi::Target & i_target, // Create new log. FAPI_ERR("Invalid galois field in markstore."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_INVALID_MARKSTORE); - return l_rc; + return l_rc; } } - - FAPI_INF("EXIT mss_get_mark_store()"); - + FAPI_INF("mss_get_mark_store(): rank%d, chip mark = %d, symbol mark = %d", + i_rank, o_chipMark, o_symbolMark ); + return l_rc; } @@ -2746,15 +3073,15 @@ fapi::ReturnCode mss_put_mark_store( const fapi::Target & i_target, uint8_t i_chipMark ) { - FAPI_INF("ENTER mss_put_mark_store()"); + FAPI_INF("ENTER mss_put_mark_store()"); + - fapi::ReturnCode l_rc; - uint32_t l_ecmd_rc = 0; + uint32_t l_ecmd_rc = 0; ecmdDataBufferBase l_markstore(64); ecmdDataBufferBase l_mbeccfir(64); ecmdDataBufferBase l_data(64); - uint32_t l_dramWidth = 0; + uint8_t l_dramWidth = 0; uint8_t l_symbolMarkGalois = 0; uint8_t l_chipMarkGalois = 0; fapi::Target l_targetCentaur; @@ -2767,108 +3094,107 @@ fapi::ReturnCode mss_put_mark_store( const fapi::Target & i_target, FAPI_ERR("Error getting Centaur parent target for the given MBA"); return l_rc; } - - + + // Get MBA position: 0 = mba01, 1 = mba23 l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_target, l_mbaPosition); if(l_rc) { FAPI_ERR("Error getting MBA position"); return l_rc; - } + } - // Get l_dramWidth - l_rc = fapiGetScom(l_targetCentaur, mss_mbaxcr[l_mbaPosition], l_data); - if(l_rc) return l_rc; - l_ecmd_rc |= l_data.extractPreserve(&l_dramWidth, 9, 1, 32-1); - if(l_ecmd_rc) + + // Get l_dramWidth + l_rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &i_target, l_dramWidth); + if(l_rc) { - l_rc.setEcmdError(l_ecmd_rc); + FAPI_ERR("Error getting DRAM width"); return l_rc; - } + } // Get l_symbolMarkGalois - if (i_symbolMark == 0xff) // No symbol mark + if (i_symbolMark == MSS_INVALID_SYMBOL) // No symbol mark { l_symbolMarkGalois = 0x00; } - else if ( l_dramWidth == mss_MemConfig::X4 ) + else if ( l_dramWidth == mss_MemConfig::X4 ) { - // Create new log. + // Create new log. FAPI_ERR("i_symbolMark invalid: symbol mark not allowed in x4 mode."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_NO_X4_SYMBOL); - return l_rc; + return l_rc; } - else if ( MSS_SYMBOLS_PER_RANK <= i_symbolMark ) + else if ( MSS_SYMBOLS_PER_RANK <= i_symbolMark ) { - // Create new log. + // Create new log. FAPI_ERR("i_symbolMark invalid: symbol index out of range."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_INVALID_SYMBOL_INDEX); - return l_rc; + return l_rc; } else // Convert from symbol index to galois field { l_symbolMarkGalois = mss_symbol2Galois[i_symbolMark]; } l_ecmd_rc |= l_markstore.insert( l_symbolMarkGalois, 0, 8, 0 ); - + // Get l_chipMarkGalois - if (i_chipMark == 0xff) // No chip mark + if (i_chipMark == MSS_INVALID_SYMBOL) // No chip mark { l_chipMarkGalois = 0x00; } - else if ( MSS_SYMBOLS_PER_RANK <= i_chipMark ) + else if ( MSS_SYMBOLS_PER_RANK <= i_chipMark ) { // Create new log. FAPI_ERR("i_chipMark invalid: symbol index out of range."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_INVALID_SYMBOL_INDEX); - return l_rc; + return l_rc; } - else if ((l_dramWidth == mss_MemConfig::X8) && (i_chipMark % 4) ) + else if ((l_dramWidth == mss_MemConfig::X8) && (i_chipMark % 4) ) { - // Create new log. + // Create new log. FAPI_ERR("i_chipMark invalid: not first symbol index of a x8 chip."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_INVALID_CHIP_INDEX); - return l_rc; - + return l_rc; + } - else if ((l_dramWidth == mss_MemConfig::X4) && (i_chipMark % 2) ) + else if ((l_dramWidth == mss_MemConfig::X4) && (i_chipMark % 2) ) { - // Create new log. + // Create new log. FAPI_ERR("i_chipMark invalid: not first symbol index of a x4 chip."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_INVALID_CHIP_INDEX); - return l_rc; + return l_rc; } else // Convert from symbol index to galois field { l_chipMarkGalois = mss_symbol2Galois[i_chipMark]; } - l_ecmd_rc |= l_markstore.insert( l_chipMarkGalois, 8, 8, 0 ); + l_ecmd_rc |= l_markstore.insert( l_chipMarkGalois, 8, 8, 0 ); if(l_ecmd_rc) { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } - + } + // Write markstore register for the given rank - l_rc = fapiPutScom(l_targetCentaur, mss_markStoreRegs[i_rank][l_mbaPosition], l_markstore); + l_rc = fapiPutScom(l_targetCentaur, mss_markStoreRegs[i_rank][l_mbaPosition], l_markstore); if(l_rc) return l_rc; - + // If MPE FIR for the given rank (scrub or fetch) is on after the read, // we will return TBD fapi::ReturnCode to indicate write may not have worked. // Up to caller to read again if they want to see what new chip mark is. - l_rc = fapiGetScom(l_targetCentaur, mss_mbeccfir[l_mbaPosition], l_mbeccfir); + l_rc = fapiGetScom(l_targetCentaur, mss_mbeccfir[l_mbaPosition], l_mbeccfir); if(l_rc) return l_rc; if (l_mbeccfir.isBitSet(i_rank) || l_mbeccfir.isBitSet(20 + i_rank)) { - // Create new log. + // Create new log. FAPI_ERR("Markstore write may have been blocked due to MPE FIR set."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_MARKSTORE_WRITE_BLOCKED); - return l_rc; + return l_rc; } - - FAPI_INF("EXIT mss_put_mark_store()"); + + FAPI_INF("EXIT mss_put_mark_store()"); return l_rc; } @@ -2886,20 +3212,21 @@ fapi::ReturnCode mss_get_steer_mux( const fapi::Target & i_target, uint8_t & o_eccSpareSymbol ) { - FAPI_INF("ENTER mss_get_steer_mux()"); - - fapi::ReturnCode l_rc; - uint32_t l_ecmd_rc = 0; + uint32_t l_ecmd_rc = 0; ecmdDataBufferBase l_steerMux(64); ecmdDataBufferBase l_data(64); - uint32_t l_dramWidth = 0; + uint8_t l_dramWidth = 0; uint8_t l_dramSparePort0Index = 0; uint8_t l_dramSparePort1Index = 0; uint8_t l_eccSpareIndex = 0; fapi::Target l_targetCentaur; uint8_t l_mbaPosition = 0; + o_dramSparePort0Symbol = MSS_INVALID_SYMBOL; + o_dramSparePort1Symbol = MSS_INVALID_SYMBOL; + o_eccSpareSymbol = MSS_INVALID_SYMBOL; + // Get Centaur target for the given MBA l_rc = fapiGetParentChip(i_target, l_targetCentaur); if(l_rc) @@ -2917,25 +3244,28 @@ fapi::ReturnCode mss_get_steer_mux( const fapi::Target & i_target, return l_rc; } - // Get l_dramWidth - l_rc = fapiGetScom(l_targetCentaur, mss_mbaxcr[l_mbaPosition], l_data); - if(l_rc) return l_rc; - l_ecmd_rc |= l_data.extractPreserve(&l_dramWidth, 9, 1, 32-1); - + // Get l_dramWidth + l_rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &i_target, l_dramWidth); + if(l_rc) + { + FAPI_ERR("Error getting DRAM width"); + return l_rc; + } + // Read steer mux register for the given rank and mux type (read or write). if (i_muxType == mss_SteerMux::READ_MUX) - { + { // Read muxes are in the MBS - l_rc = fapiGetScom(l_targetCentaur, mss_readMuxRegs[i_rank][l_mbaPosition], l_steerMux); + l_rc = fapiGetScom(l_targetCentaur, mss_readMuxRegs[i_rank][l_mbaPosition], l_steerMux); if(l_rc) return l_rc; } - else - { + else + { // Write muxes are in the MBA - l_rc = fapiGetScom(i_target, mss_writeMuxRegs[i_rank], l_steerMux); + l_rc = fapiGetScom(i_target, mss_writeMuxRegs[i_rank], l_steerMux); if(l_rc) return l_rc; } - + //*************************************** // Get l_dramSparePort0Index l_ecmd_rc |= l_steerMux.extractPreserve(&l_dramSparePort0Index, 0, 5, 8-5); @@ -2943,8 +3273,8 @@ fapi::ReturnCode mss_get_steer_mux( const fapi::Target & i_target, { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } - + } + // Get o_dramSparePort0Symbol if index in valid range if ((l_dramWidth == mss_MemConfig::X8) && (l_dramSparePort0Index < MSS_X8_STEER_OPTIONS_PER_PORT)) { @@ -2957,20 +3287,20 @@ fapi::ReturnCode mss_get_steer_mux( const fapi::Target & i_target, else { FAPI_ERR("l_dramSparePort0Index out of range."); - // Caller needs to recognize a symbol value of 0xfe as invalid. - o_dramSparePort0Symbol = 0xfe; + // Caller needs to recognize a symbol value of 0xfe as invalid. + o_dramSparePort0Symbol = 0xfe; } - - - //*************************************** + + + //*************************************** // Get l_dramSparePort1Index l_ecmd_rc |= l_steerMux.extractPreserve(&l_dramSparePort1Index, 5, 5, 8-5); if(l_ecmd_rc) { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } - + } + // Get o_dramSparePort1Symbol if index in valid range if ((l_dramWidth == mss_MemConfig::X8) && (l_dramSparePort1Index < MSS_X8_STEER_OPTIONS_PER_PORT)) { @@ -2983,11 +3313,11 @@ fapi::ReturnCode mss_get_steer_mux( const fapi::Target & i_target, else { FAPI_ERR("l_dramSparePort1Index out of range."); - // Caller needs to recognize a symbol value of 0xfe as invalid. - o_dramSparePort1Symbol = 0xfe; + // Caller needs to recognize a symbol value of 0xfe as invalid. + o_dramSparePort1Symbol = 0xfe; } - + //*************************************** // Get l_eccSpareIndex l_ecmd_rc |= l_steerMux.extractPreserve(&l_eccSpareIndex, 10, 5, 8-5); @@ -2995,7 +3325,7 @@ fapi::ReturnCode mss_get_steer_mux( const fapi::Target & i_target, { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } + } // Get o_eccSpareSymbol if index in valid range if (l_eccSpareIndex < MSS_X4_ECC_STEER_OPTIONS) @@ -3005,15 +3335,15 @@ fapi::ReturnCode mss_get_steer_mux( const fapi::Target & i_target, else { FAPI_ERR("o_eccSpareSymbol out of range."); - // Caller needs to recognize a symbol value of 0xfe as invalid. - o_eccSpareSymbol = 0xfe; + // Caller needs to recognize a symbol value of 0xfe as invalid. + o_eccSpareSymbol = 0xfe; } - - FAPI_INF("EXIT mss_get_steer_mux()"); + FAPI_INF("mss_get_steer_mux(): rank%d, port0 steer = %d, port1 steer = %d, ecc steer = %d", + i_rank, o_dramSparePort0Symbol, o_dramSparePort1Symbol, o_eccSpareSymbol ); return l_rc; - + } @@ -3026,29 +3356,29 @@ fapi::ReturnCode mss_get_steer_mux( const fapi::Target & i_target, fapi::ReturnCode mss_put_steer_mux( const fapi::Target & i_target, uint8_t i_rank, mss_SteerMux::muxType i_muxType, - mss_SteerMux::steerType i_steerType, + uint8_t i_steerType, uint8_t i_symbol ) { - // TODO: i_symbol = 0xff will result 0's entered in steer mux, which + // TODO: i_symbol = MSS_INVALID_SYMBOL will result 0's entered in steer mux, which // means no steer. // Do I want to allow writing of no steer? - - // TODO: i_symbol has to be first symbol in the chip for us to accept it. + + // TODO: i_symbol has to be first symbol in the chip for us to accept it. // Do I want to allow any symbol as the input? - FAPI_INF("ENTER mss_put_steer_mux()"); + FAPI_INF("ENTER mss_put_steer_mux()"); + - fapi::ReturnCode l_rc; - uint32_t l_ecmd_rc = 0; + uint32_t l_ecmd_rc = 0; ecmdDataBufferBase l_steerMux(64); ecmdDataBufferBase l_data(64); - uint32_t l_dramWidth = 0; + uint8_t l_dramWidth = 0; uint8_t l_dramSparePort0Index = 0; uint8_t l_dramSparePort1Index = 0; uint8_t l_eccSpareIndex = 0; @@ -3062,7 +3392,7 @@ fapi::ReturnCode mss_put_steer_mux( const fapi::Target & i_target, FAPI_ERR("Error getting Centaur parent target for the given MBA"); return l_rc; } - + // Get MBA position: 0 = mba01, 1 = mba23 l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_target, l_mbaPosition); @@ -3070,33 +3400,32 @@ fapi::ReturnCode mss_put_steer_mux( const fapi::Target & i_target, { FAPI_ERR("Error getting MBA position"); return l_rc; - } - - // Get l_dramWidth - l_rc = fapiGetScom(l_targetCentaur, mss_mbaxcr[l_mbaPosition], l_data); - if(l_rc) return l_rc; - l_ecmd_rc |= l_data.extractPreserve(&l_dramWidth, 9, 1, 31-1); - if(l_ecmd_rc) + } + + // Get l_dramWidth + l_rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &i_target, l_dramWidth); + if(l_rc) { - l_rc.setEcmdError(l_ecmd_rc); + FAPI_ERR("Error getting DRAM width"); return l_rc; - } - + } + + // Read steer mux register for the given rank and mux type (read or write). if (i_muxType == mss_SteerMux::READ_MUX) - { + { // Read muxes are in the MBS l_rc = fapiGetScom(l_targetCentaur, mss_readMuxRegs[i_rank][l_mbaPosition], l_steerMux); if(l_rc) return l_rc; } - else + else { // Write muxes are in the MBA l_rc = fapiGetScom(i_target, mss_writeMuxRegs[i_rank], l_steerMux); if(l_rc) return l_rc; } - + // Convert from i_symbol to l_dramSparePort0Index if (i_steerType == mss_SteerMux::DRAM_SPARE_PORT0) { @@ -3115,7 +3444,7 @@ fapi::ReturnCode mss_put_steer_mux( const fapi::Target & i_target, if ( MSS_X8_STEER_OPTIONS_PER_PORT <= l_dramSparePort0Index ) { // Create new log. - FAPI_ERR("No match for i_symbol in mss_x8dramSparePort0Index_to_symbol[]."); + FAPI_ERR("No match for i_symbol = %d in mss_x8dramSparePort0Index_to_symbol[].", i_symbol); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_INVALID_SYMBOL_TO_STEER); return l_rc; } @@ -3142,10 +3471,10 @@ fapi::ReturnCode mss_put_steer_mux( const fapi::Target & i_target, } } - l_ecmd_rc |= l_steerMux.insert( l_dramSparePort0Index, 0, 5, 8-5 ); - } - - + l_ecmd_rc |= l_steerMux.insert( l_dramSparePort0Index, 0, 5, 8-5 ); + } + + // Convert from i_symbol to l_dramSparePort1Index if (i_steerType == mss_SteerMux::DRAM_SPARE_PORT1) { @@ -3169,7 +3498,7 @@ fapi::ReturnCode mss_put_steer_mux( const fapi::Target & i_target, return l_rc; } } - + else if (l_dramWidth == mss_MemConfig::X4) { l_dramSparePort1Index = MSS_X4_STEER_OPTIONS_PER_PORT1; @@ -3191,11 +3520,11 @@ fapi::ReturnCode mss_put_steer_mux( const fapi::Target & i_target, } } - l_ecmd_rc |= l_steerMux.insert( l_dramSparePort1Index, 5, 5, 8-5 ); + l_ecmd_rc |= l_steerMux.insert( l_dramSparePort1Index, 5, 5, 8-5 ); } - - + + // Convert from i_symbol to l_eccSpareIndex if (i_steerType == mss_SteerMux::ECC_SPARE) { @@ -3221,40 +3550,693 @@ fapi::ReturnCode mss_put_steer_mux( const fapi::Target & i_target, } else if (l_dramWidth == mss_MemConfig::X8) { - + // Create new log. FAPI_ERR("ECC_SPARE not valid with x8 mode."); FAPI_SET_HWP_ERROR(l_rc, RC_MSS_MAINT_NO_X8_ECC_SPARE); return l_rc; } - - l_ecmd_rc |= l_steerMux.insert( l_eccSpareIndex, 10, 5, 8-5 ); + + l_ecmd_rc |= l_steerMux.insert( l_eccSpareIndex, 10, 5, 8-5 ); } - + if(l_ecmd_rc) { l_rc.setEcmdError(l_ecmd_rc); return l_rc; - } + } - // Write the steer mux register for the given rank and mux + // Write the steer mux register for the given rank and mux // type (read or write). if (i_muxType == mss_SteerMux::READ_MUX) - { + { // Read muxes are in the MBS - l_rc = fapiPutScom(l_targetCentaur, mss_readMuxRegs[i_rank][l_mbaPosition], l_steerMux); + l_rc = fapiPutScom(l_targetCentaur, mss_readMuxRegs[i_rank][l_mbaPosition], l_steerMux); if(l_rc) return l_rc; } - else + else { // Write muxes are in the MBA - l_rc = fapiPutScom(i_target, mss_writeMuxRegs[i_rank], l_steerMux); + l_rc = fapiPutScom(i_target, mss_writeMuxRegs[i_rank], l_steerMux); if(l_rc) return l_rc; } - FAPI_INF("EXIT mss_put_steer_mux()"); + FAPI_INF("EXIT mss_put_steer_mux()"); return l_rc; - + +} + + + +//------------------------------------------------------------------------------ +// mss_restore_DRAM_repairs +//------------------------------------------------------------------------------ + + +fapi::ReturnCode mss_restore_DRAM_repairs( const fapi::Target & i_target, + uint8_t & o_repairs_applied, + uint8_t & o_repairs_exceeded) + +{ + + FAPI_INF("ENTER mss_restore_DRAM_repairs()"); + + + fapi::ReturnCode l_rc; + uint8_t l_dramWidth = 0; + uint8_t l_dqBitmap[DIMM_DQ_RANK_BITMAP_SIZE]; // 10 byte array of bad bits + ecmdDataBufferBase l_data(64); + uint8_t l_port=0; + uint8_t l_dimm=0; + uint8_t l_rank=0; + uint8_t l_byte=0; + uint8_t l_dq_pair_index = 0; + uint8_t l_bad_dq_pair_index = 0; + uint8_t l_bad_dq_pair_count=0; + uint8_t l_bad_dq_pair = 0xff; + uint8_t l_dq_pair_mask = 0xC0; + uint8_t l_byte_being_steered = 0xff; + uint8_t l_bad_symbol = MSS_INVALID_SYMBOL; + uint8_t l_symbol_mark = MSS_INVALID_SYMBOL; + uint8_t l_chip_mark = MSS_INVALID_SYMBOL; + bool l_spare_exists = false; + bool l_spare_used = false; + bool l_chip_mark_used = false; + bool l_symbol_mark_used = false; + + + // TODO: Fake this to show spares exist until attribute ready + // NO_SPARE = 0, LOW_NIBBLE = 1, HIGH_NIBBLE = 2, FULL_BYTE = 3 + uint8_t l_spare_dram[2][2][4]= { // Array defining if spare dram exits + {{3,3,3,3} , {3,3,3,3}}, + {{3,3,3,3} , {3,3,3,3}}}; + + + enum + { + MSS_REPAIRS_APPLIED = 1, + MSS_REPAIRS_EXCEEDED = 2, + }; + + uint8_t l_repair_status[2][2][4]={ + {{0,0,0,0} , {0,0,0,0}}, + {{0,0,0,0} , {0,0,0,0}}}; + + static const uint8_t l_repairs_applied_translation[8]={ + 0x80, //rank0 (maps to port0_dimm0, port1_dimm0) + 0x40, //rank1 (maps to port0_dimm0, port1_dimm0) + 0x20, //rank2 (maps to port0_dimm0, port1_dimm0) + 0x10, //rank3 (maps to port0_dimm0, port1_dimm0) + 0x08, //rank4 (maps to port0_dimm1, port1_dimm1) + 0x04, //rank5 (maps to port0_dimm1, port1_dimm1) + 0x02, //rank6 (maps to port0_dimm1, port1_dimm1) + 0x01}; //rank7 (maps to port0_dimm1, port1_dimm1) + + static const uint8_t l_repairs_exceeded_translation[2][2]={ + // dimm0 dimm1 + { 0x8, 0x4 }, // port0 + { 0x2, 0x1 }}; // port1 + + + + + // Start with no repairs applies and no repairs exceeded + o_repairs_applied = 0; + o_repairs_exceeded = 0; + + + // TODO: Fake this out for now since Anuwat is changing it. + // Get array attribute that defines if spare dram exits + // l_spare_dram[port][dimm][rank] + // NO_SPARE = 0, LOW_NIBBLE = 1, HIGH_NIBBLE = 2, FULL_BYTE = 3 + // NOTE: Typically will same value for whole Centaur. + //l_rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_SPARE, &i_target, l_spare_dram); + //if(l_rc) + //{ + // FAPI_ERR("Error reading attribute to see if spare exists"); + // return l_rc; + //} + + // Get l_dramWidth + l_rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &i_target, l_dramWidth); + if(l_rc) + { + FAPI_ERR("Error getting DRAM width"); + return l_rc; + } + + // For each port in the given MBA:0,1 + for(l_port=0; l_port<DIMM_DQ_MAX_MBA_PORTS; l_port++ ) + { + // For each DIMM select on the given port:0,1 + for(l_dimm=0; l_dimm<DIMM_DQ_MAX_MBAPORT_DIMMS; l_dimm++ ) + { + // For each rank select on the given DIMM select:0,1,2,3 + for(l_rank=0; l_rank<DIMM_DQ_MAX_DIMM_RANKS; l_rank++ ) + { + + + // Get the bad DQ Bitmap for l_port, l_dimm, l_rank + l_rc = dimmGetBadDqBitmap(i_target, + l_port, + l_dimm, + l_rank, + l_dqBitmap); + if (l_rc) + { + FAPI_ERR("Error from dimmGetBadDqBitmap"); + return l_rc; + } + + // x8 ECC + // x8 bit chip mark, x2 bit symbol mark, spare x8 DRAM if CDIMM + if (l_dramWidth == mss_MemConfig::X8) + { + + // Determine if spare x8 DRAM exists + l_spare_exists = l_spare_dram[l_port][l_dimm][l_rank] == mss_MemConfig::FULL_BYTE; + + // Start with spare not used + l_spare_used = false; + l_byte_being_steered = MSS_INVALID_SYMBOL; + + // Read mark store + l_rc = mss_get_mark_store( + + i_target, // MBA + 4*l_dimm + l_rank, // Master rank: 0-7 + l_symbol_mark, // MSS_INVALID_SYMBOL if no symbol mark + l_chip_mark ); // MSS_INVALID_SYMBOL if no chip mark + + if (l_rc) + { + FAPI_ERR("Error reading markstore"); + return l_rc; + } + + // Check if chip mark used (may have been used on other port) + l_chip_mark_used = l_chip_mark != MSS_INVALID_SYMBOL; + + // Check if symbol mark used (may have been used on other port) + l_symbol_mark_used = l_symbol_mark != MSS_INVALID_SYMBOL; + + // Initialize to no bad dq pair found yet + l_bad_dq_pair = 0xff; + + // For each byte 0-9, where 9 is the spare + for(l_byte=0; l_byte<DIMM_DQ_RANK_BITMAP_SIZE; l_byte++ ) + { + if ((l_byte == 9) && !l_spare_exists) + { + // Don't look at byte 9 if spare doesn't exist + break; + } + + if (l_dqBitmap[l_byte] == 0) + { + // Don't bother analyzing if byte is clean + continue; + } + + // Mask initialized to look at first dq pair in byte + l_dq_pair_mask = 0xC0; + + // Start with no bad dq pairs counted for this byte + l_bad_dq_pair_count = 0; + + // For each of the 4 dq pairs in the byte + for(l_dq_pair_index=0; l_dq_pair_index<4; l_dq_pair_index++ ) + { + + // If any bad bits in this dq pair + if (l_dqBitmap[l_byte] & l_dq_pair_mask) + { + // Increment bad symbol count + l_bad_dq_pair_count++; + + // Record bad dq pair - just most recent if multiple bad + l_bad_dq_pair_index = l_dq_pair_index; + l_bad_dq_pair = 8*l_byte + 2*l_bad_dq_pair_index; + } + + // Shift mask to next symbol + l_dq_pair_mask = l_dq_pair_mask >> 2; + } + + // If spare is bad but not used, not valid to try repair + if ( l_spare_exists && (l_byte==9) && (l_bad_dq_pair_count > 0) && !l_spare_used) + { + FAPI_INF("port=%d, dimm=%d, rank=%d, l_dqBitmap[%d] = %02x, Bad unused spare - no valid repair", + l_port, l_dimm, l_rank, l_byte, l_dqBitmap[l_byte]); + + break; + } + + // If more than one dq pair is bad + if(l_bad_dq_pair_count > 1) + { + + // If spare x8 DRAM exists and not used yet, + if (l_spare_exists && !l_spare_used) + { + l_bad_symbol = mss_centaurDQ_to_symbol(8*l_byte,l_port) - 3; + + // Update read mux + l_rc = mss_put_steer_mux( + + i_target, // MBA + 4*l_dimm + l_rank, // Master rank: 0-7 + mss_SteerMux::READ_MUX, // read mux + l_port, // l_port: 0,1 + l_bad_symbol); // First symbol index of byte to steer + + if (l_rc) + { + FAPI_ERR("Error updating read mux"); + return l_rc; + + } + + // Update write mux + l_rc = mss_put_steer_mux( + + i_target, // MBA + 4*l_dimm + l_rank, // Master rank: 0-7 + mss_SteerMux::WRITE_MUX,// write mux + l_port, // l_port: 0,1 + l_bad_symbol); // First symbol index of byte to steer + + if (l_rc) + { + FAPI_ERR("Error updating write mux"); + return l_rc; + } + + // Spare now used on this port,dimm,rank + l_spare_used = true; + + // Remember which byte is being steered + // so we know where to apply chip or symbol mark + // if spare turns out to be bad + l_byte_being_steered = l_byte; + + // Update which rank 0-7 has had repairs applied + o_repairs_applied |= l_repairs_applied_translation[4*l_dimm + l_rank]; + + l_repair_status[l_port][l_dimm][l_rank]=MSS_REPAIRS_APPLIED; + + // If port1 repairs applied and port0 had repairs exceeded, say port1 repairs exceeded too + if ((l_repair_status[1][l_dimm][l_rank] == MSS_REPAIRS_APPLIED) && (l_repair_status[0][l_dimm][l_rank] == MSS_REPAIRS_EXCEEDED)) + { + o_repairs_exceeded |= l_repairs_exceeded_translation[1][l_dimm]; + } + + FAPI_INF("port=%d, dimm=%d, rank=%d, l_dqBitmap[%d] = %02x, dq %d-%d, symbols %d-%d, FIXED CHIP WITH X8 STEER", + l_port, l_dimm, l_rank, l_byte, l_dqBitmap[l_byte], 8*l_byte, 8*l_byte+7,l_bad_symbol, l_bad_symbol+3 ); + + + } + + // Else if chip mark not used yet, update mark store with chip mark + else if (!l_chip_mark_used) + { + // NOTE: Have to do a read/modify/write so we + // only update chip mark, and don't overwrite + // symbol mark. + + // Read mark store + l_rc = mss_get_mark_store( + + i_target, // MBA + 4*l_dimm + l_rank, // Master rank: 0-7 + l_symbol_mark, // Reading this just to write it back + l_chip_mark ); // Expecting MSS_INVALID_SYMBOL since no chip mark + + if (l_rc) + { + FAPI_ERR("Error reading markstore"); + return l_rc; + } + + + // Special case: + // If this is a bad spare byte we are analying + // the chip mark goes on the byte being steered + if (l_byte==9) + { + l_chip_mark = mss_centaurDQ_to_symbol(8*l_byte_being_steered,l_port) - 3; + FAPI_INF("Bad spare so chip mark goes on l_byte_being_steered = %d", l_byte_being_steered); + } + + else + { + l_chip_mark = mss_centaurDQ_to_symbol(8*l_byte,l_port) - 3; + } + + // Write mark store + l_rc = mss_put_mark_store( + + i_target, // MBA + 4*l_dimm + l_rank, // Master rank: 0-7 + l_symbol_mark, // Writting back exactly what we read + l_chip_mark ); // First symbol index of byte getting chip mark + + if (l_rc) + { + FAPI_ERR("Error updating markstore"); + return l_rc; + } + + // Chip mark now used on this rank + l_chip_mark_used = true; + + // Update which rank 0-7 has had repairs applied + o_repairs_applied |= l_repairs_applied_translation[4*l_dimm + l_rank]; + + l_repair_status[l_port][l_dimm][l_rank]=MSS_REPAIRS_APPLIED; + + // If port1 repairs applied and port0 had repairs exceeded, say port1 repairs exceeded too + if ((l_repair_status[1][l_dimm][l_rank] == MSS_REPAIRS_APPLIED) && (l_repair_status[0][l_dimm][l_rank] == MSS_REPAIRS_EXCEEDED)) + { + o_repairs_exceeded |= l_repairs_exceeded_translation[1][l_dimm]; + } + + FAPI_INF("port=%d, dimm=%d, rank=%d, l_dqBitmap[%d] = %02x, dq %d-%d, symbols %d-%d, FIXED CHIP WITH X8 CHIP MARK", + l_port, l_dimm, l_rank, l_byte, l_dqBitmap[l_byte], 8*l_byte, 8*l_byte+7,l_chip_mark, l_chip_mark+3 ); + + } + + // Else, more bad bits than we can repair so update o_repairs_exceeded + else + { + o_repairs_exceeded |= l_repairs_exceeded_translation[l_port][l_dimm]; + + l_repair_status[l_port][l_dimm][l_rank]=MSS_REPAIRS_EXCEEDED; + + // If port1 repairs exceeded and port0 had a repair, say port0 repairs exceeded too + if ((l_repair_status[1][l_dimm][l_rank] == MSS_REPAIRS_EXCEEDED) && (l_repair_status[0][l_dimm][l_rank] == MSS_REPAIRS_APPLIED)) + { + o_repairs_exceeded |= l_repairs_exceeded_translation[0][l_dimm]; + } + + FAPI_INF("port=%d, dimm=%d, rank=%d, l_dqBitmap[%d] = %02x, dq %d-%d, REPAIRS EXCEEDED", + l_port, l_dimm, l_rank, l_byte, l_dqBitmap[l_byte], 8*l_byte, 8*l_byte+7); + + + // Break out of loop on bytes + break; + } + } // End If bad symbol count > 1 + + + //Else if bad symbol count = 1 + else if(l_bad_dq_pair_count == 1) + { + // If symbol mark not used yet, update mark store with symbol mark + if (!l_symbol_mark_used) + { + + // NOTE: Have to do a read/modify/write so we + // only update symbol mark, and don't overwrite + // chip mark. + + // Read mark store + l_rc = mss_get_mark_store( + + i_target, // MBA + 4*l_dimm + l_rank, // Master rank: 0-7 + l_symbol_mark, // Expecting MSS_INVALID_SYMBOL since no symbol mark + l_chip_mark ); // Reading this just to write it back + + if (l_rc) + { + FAPI_ERR("Error reading markstore"); + return l_rc; + } + + // Special case: + // If this is a bad spare byte we are analying + // the symbol mark goes on the byte being steered + if (l_byte==9) + { + l_symbol_mark = mss_centaurDQ_to_symbol(8*l_byte_being_steered + 2*l_bad_dq_pair_index,l_port); + FAPI_INF("Bad spare so symbol mark goes on l_byte_being_steered = %d", l_byte_being_steered); + } + + else + { + l_symbol_mark = mss_centaurDQ_to_symbol(8*l_byte + 2*l_bad_dq_pair_index,l_port); + } + + + // Update mark store + l_rc = mss_put_mark_store( + + i_target, // MBA + 4*l_dimm + l_rank, // Master rank: 0-7 + l_symbol_mark, // Single bad symbol found on this byte + l_chip_mark ); // Writting back exactly what we read + + if (l_rc) + { + FAPI_ERR("Error updating markstore"); + return l_rc; + } + + // Symbol mark now used on this rank + l_symbol_mark_used = true; + + // Update which rank 0-7 has had repairs applied + o_repairs_applied |= l_repairs_applied_translation[4*l_dimm + l_rank]; + + l_repair_status[l_port][l_dimm][l_rank]=MSS_REPAIRS_APPLIED; + + // If port1 repairs applied and port0 had repairs exceeded, say port1 repairs exceeded too + if ((l_repair_status[1][l_dimm][l_rank] == MSS_REPAIRS_APPLIED) && (l_repair_status[0][l_dimm][l_rank] == MSS_REPAIRS_EXCEEDED)) + { + o_repairs_exceeded |= l_repairs_exceeded_translation[1][l_dimm]; + } + + FAPI_INF("port=%d, dimm=%d, rank=%d, l_dqBitmap[%d] = %02x, dq %d-%d, symbol %d, FIXED SYMBOL WITH X2 SYMBOL MARK", + l_port, l_dimm, l_rank, l_byte, l_dqBitmap[l_byte], + 8*l_byte + 2*l_bad_dq_pair_index, 8*l_byte + 2*l_bad_dq_pair_index + 1, + l_symbol_mark ); + + } + + + // Else if spare x8 DRAM exists and not used yet, update steer mux + else if (l_spare_exists && !l_spare_used) + { + + l_bad_symbol = mss_centaurDQ_to_symbol(8*l_byte,l_port) - 3; + + // Update read mux + l_rc = mss_put_steer_mux( + + i_target, // MBA + 4*l_dimm + l_rank, // Master rank: 0-7 + mss_SteerMux::READ_MUX, // read mux + l_port, // l_port: 0,1 + l_bad_symbol ); // First symbol index of byte to steer + + if (l_rc) + { + FAPI_ERR("Error updating read mux"); + return l_rc; + + } + + // Update write mux + l_rc = mss_put_steer_mux( + + i_target, // MBA + 4*l_dimm + l_rank, // Master rank: 0-7 + mss_SteerMux::WRITE_MUX,// write mux + l_port, // l_port: 0,1 + l_bad_symbol ); // First symbol index of byte to steer + + if (l_rc) + { + FAPI_ERR("Error updating write mux"); + return l_rc; + } + + // Spare now used on this port,dimm,rank + l_spare_used = true; + + // Remember which byte is being steered + // so we where to apply chip or symbol mark + // if spare turns out to be bad + l_byte_being_steered = l_byte; + + // Update which rank 0-7 has had repairs applied + o_repairs_applied |= l_repairs_applied_translation[4*l_dimm + l_rank]; + + l_repair_status[l_port][l_dimm][l_rank]=MSS_REPAIRS_APPLIED; + + // If port1 repairs applied and port0 had repairs exceeded, say port1 repairs exceeded too + if ((l_repair_status[1][l_dimm][l_rank] == MSS_REPAIRS_APPLIED) && (l_repair_status[0][l_dimm][l_rank] == MSS_REPAIRS_EXCEEDED)) + { + o_repairs_exceeded |= l_repairs_exceeded_translation[1][l_dimm]; + } + + FAPI_INF("port=%d, dimm=%d, rank=%d, l_dqBitmap[%d] = %02x, dq %d-%d, symbols %d-%d, FIXED SYMBOL WITH X8 STEER", + l_port, l_dimm, l_rank, l_byte, l_dqBitmap[l_byte], + 8*l_byte + 2*l_bad_dq_pair_index, 8*l_byte + 2*l_bad_dq_pair_index + 1, + l_bad_symbol, + l_bad_symbol + 3); + + } + + // Else if chip mark not used yet, update mark store with chip mark + else if (!l_chip_mark_used) + { + + // NOTE: Have to do a read/modify/write so we + // only update chip mark, and don't overwrite + // symbol mark. + + // Read mark store + l_rc = mss_get_mark_store( + + i_target, // MBA + 4*l_dimm + l_rank, // Master rank: 0-7 + l_symbol_mark, // Reading this just to write it back + l_chip_mark ); // Expecting MSS_INVALID_SYMBOL since no chip mark + + if (l_rc) + { + FAPI_ERR("Error reading markstore"); + return l_rc; + } + + + // Special case: + // If this is a bad spare byte we are analying + // the chip mark goes on the byte being steered + if (l_byte==9) + { + l_chip_mark = mss_centaurDQ_to_symbol(8*l_byte_being_steered,l_port) - 3; + FAPI_INF("Bad spare so chip mark goes on l_byte_being_steered = %d", l_byte_being_steered); + } + + else + { + l_chip_mark = mss_centaurDQ_to_symbol(8*l_byte,l_port) - 3; + } + + // Update mark store + l_rc = mss_put_mark_store( + + i_target, // MBA + 4*l_dimm + l_rank, // Master rank: 0-7 + l_symbol_mark, // Writting back exactly what we read + l_chip_mark ); // First symbol index of byte getting chip mark + + if (l_rc) + { + FAPI_ERR("Error updating markstore"); + return l_rc; + } + + // Chip mark now used on this rank + l_chip_mark_used = true; + + // Update which rank 0-7 has had repairs applied + o_repairs_applied |= l_repairs_applied_translation[4*l_dimm + l_rank]; + + l_repair_status[l_port][l_dimm][l_rank]=MSS_REPAIRS_APPLIED; + + // If port1 repairs applied and port0 had repairs exceeded, say port1 repairs exceeded too + if ((l_repair_status[1][l_dimm][l_rank] == MSS_REPAIRS_APPLIED) && (l_repair_status[0][l_dimm][l_rank] == MSS_REPAIRS_EXCEEDED)) + { + o_repairs_exceeded |= l_repairs_exceeded_translation[1][l_dimm]; + } + + FAPI_INF("port=%d, dimm=%d, rank=%d, l_dqBitmap[%d] = %02x, dq %d-%d, symbols %d-%d, FIXED SYMBOL WITH X8 CHIP MARK", + l_port, l_dimm, l_rank, l_byte, l_dqBitmap[l_byte], + 8*l_byte + 2*l_bad_dq_pair_index, 8*l_byte + 2*l_bad_dq_pair_index + 1, + l_chip_mark, + l_chip_mark + 3); + + } + + + // Else, more bad bits than we can repair so update o_repairs_exceeded + else + { + + o_repairs_exceeded |= l_repairs_exceeded_translation[l_port][l_dimm]; + + l_repair_status[l_port][l_dimm][l_rank]=MSS_REPAIRS_EXCEEDED; + + // If port1 repairs exceeded and port0 had a repair, say port0 repairs exceeded too + if ((l_repair_status[1][l_dimm][l_rank] == MSS_REPAIRS_EXCEEDED) && (l_repair_status[0][l_dimm][l_rank] == MSS_REPAIRS_APPLIED)) + { + o_repairs_exceeded |= l_repairs_exceeded_translation[0][l_dimm]; + } + + FAPI_INF("port=%d, dimm=%d, rank=%d, l_dqBitmap[%d] = %02x, dq %d-%d, REPAIRS EXCEEDED", + l_port, l_dimm, l_rank, l_byte, l_dqBitmap[l_byte], + 8*l_byte + 2*l_bad_dq_pair_index, 8*l_byte + 2*l_bad_dq_pair_index + 1); + + // Break out of loop on bytes + break; + } + + } // End If bad symbol count = 1 + + } // End For each byte 0-9, where 9 is the spare + + } // End x8 ECC + + // x4 ECC + // x4 chip mark, x4 ECC steer, spare x4 DRAM if CDIMM + else if (l_dramWidth == mss_MemConfig::X4) + { + } // End x4 ECC + + } // End loop on rank + } // End loop on dimm + } // End loop on port + + + + + + + FAPI_INF("o_repairs_applied = %02x\n", o_repairs_applied); + FAPI_INF("o_repairs_exceeded = %02x\n", o_repairs_exceeded); + + FAPI_INF("EXIT mss_restore_DRAM_repairs()"); + + return l_rc; + +} + + +//------------------------------------------------------------------------------ +// mss_centaurDQ_to_symbol +//------------------------------------------------------------------------------ + +uint8_t mss_centaurDQ_to_symbol( uint8_t i_dq, uint8_t i_port ) +{ + + uint8_t o_symbol = MSS_INVALID_SYMBOL; + + if ( 64 <= i_dq ) // DQs 64 - 71 + { + o_symbol = (71 - i_dq) / 2; // symbols 0 - 3 + if ( 0 == i_port ) o_symbol += 4; // symbols 4 - 7 + } + else // DQs 0 - 63 + { + o_symbol = (71 - i_dq + 8) / 2; // symbols 8 - 39 + if ( 0 == i_port ) o_symbol += 32; // symbols 40 - 71 + } + + return o_symbol; } |