diff options
author | Zane Shelley <zshelle@us.ibm.com> | 2013-04-27 22:12:56 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-06-11 09:11:25 -0500 |
commit | 25a05966a93786736212b4f35aa84929423a48e4 (patch) | |
tree | 3be7d985ec3938b43671ff01e93ff8db5eae9de1 /src/usr/diag/prdf/common/plat | |
parent | bb2e9e1adac63e8b12c881b546b757f8d8de5697 (diff) | |
download | talos-hostboot-25a05966a93786736212b4f35aa84929423a48e4.tar.gz talos-hostboot-25a05966a93786736212b4f35aa84929423a48e4.zip |
PRD: TD controller for MDIA
Change-Id: I6453a1fef37cbd7f9d3c105af8349688ad62c0c2
RTC: 22866
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/4248
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Reviewed-by: Zane Shelley <zshelle@us.ibm.com>
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/4935
Diffstat (limited to 'src/usr/diag/prdf/common/plat')
16 files changed, 570 insertions, 88 deletions
diff --git a/src/usr/diag/prdf/common/plat/pegasus/Mba.rule b/src/usr/diag/prdf/common/plat/pegasus/Mba.rule index d09d63997..438f483be 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/Mba.rule +++ b/src/usr/diag/prdf/common/plat/pegasus/Mba.rule @@ -44,6 +44,8 @@ chip Mba dump DUMP_CONTENT_HWSUPERNOVA; scomlen 64; +.include "prdfCenMbaExtraSig.H"; + ############################################################################# # # # ###### # @@ -120,6 +122,13 @@ chip Mba capture group FirRegs; }; + register MBADDRPHYFIR_AND + { + name "DPHY01.PHY01_DDRPHY_FIR_REG_AND"; + scomaddr 0x800200910301143F; + capture group never; + }; + register MBADDRPHYFIR_MASK { name "DPHY01.PHY01_DDRPHY_FIR_MASK_REG"; @@ -190,11 +199,17 @@ chip Mba name "MBU.MBA01.MBA_MCBIST.SCOMFIR.MBSPAQ"; scomaddr 0x03010611; reset (&, 0x03010612); - #FIXME : There is no OR register for mask. Is it right to use mask register value mask (|, 0x03010614); capture group FirRegs; }; + register MBASPA_AND + { + name "MBU.MBA01.MBA_MCBIST.SCOMFIR.MBSPAQ_AND"; + scomaddr 0x03010612; + capture group never; + }; + register MBASPA_MASK { name "MBU.MBA01.MBA_MCBIST.SCOMFIR.MBSPAMSKQ"; @@ -221,7 +236,6 @@ chip Mba capture group CerrRegs; }; - register DDRPHY_APB_FIR_ERR0_P0 { name "DPHY01.DDRPHY_APB_FIR_ERR0_P0"; @@ -796,5 +810,9 @@ group gMbaSpa attntype SPECIAL filter singlebit ################################################################################ /** Analyze maintenance command complete */ -actionclass analyzeMaintCmdComplete { funccall("MaintCmdComplete"); }; +actionclass analyzeMaintCmdComplete +{ + funccall("MaintCmdComplete"); # Must be called last so return code can be + # passed on to rule code. +}; diff --git a/src/usr/diag/prdf/common/plat/pegasus/Membuf_regs_NEST.rule b/src/usr/diag/prdf/common/plat/pegasus/Membuf_regs_NEST.rule index 668f49be3..7bf027415 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/Membuf_regs_NEST.rule +++ b/src/usr/diag/prdf/common/plat/pegasus/Membuf_regs_NEST.rule @@ -228,6 +228,13 @@ capture group FirRegs; }; + register MBSECC01FIR_AND + { + name "MBU.MBS.ECC01.MBECCFIR_AND"; + scomaddr 0x02011441; + capture group never; + }; + register MBSECC01FIR_MASK { name "MBU.MBS.ECC01.MBECCFIR_MASK"; @@ -269,6 +276,13 @@ capture group FirRegs; }; + register MBSECC23FIR_AND + { + name "MBU.MBS.ECC23.MBECCFIR_AND"; + scomaddr 0x02011481; + capture group never; + }; + register MBSECC23FIR_MASK { name "MBU.MBS.ECC23.MBECCFIR_MASK"; @@ -599,3 +613,21 @@ capture group default; }; + ############################################################################ + # NEST Chiplet memory scrub/read threshold register + ############################################################################ + + register MBSTR_0 + { + name "MBU.MBS.MCBISTS01.SCOMFIR.MBSTRQ"; + scomaddr 0x02011655; + capture group default; + }; + + register MBSTR_1 + { + name "MBU.MBS.MCBISTS23.SCOMFIR.MBSTRQ"; + scomaddr 0x02011755; + capture group default; + }; + diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.C index 39917a826..a7ca03cb7 100644 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.C +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.C @@ -27,6 +27,7 @@ #include <iipServiceDataCollector.h> #include <prdfCenAddress.H> +#include <prdfCenMarkstore.H> #include <prdfPlatServices.H> #include <prdfTrace.H> @@ -49,6 +50,25 @@ void defaultError( STEP_CODE_DATA_STRUCT & i_sc ) //------------------------------------------------------------------------------ +void calloutMark( TargetHandle_t i_mba, const CenRank & i_rank, + const CenMark & i_mark, STEP_CODE_DATA_STRUCT & io_sc, + PRDpriority i_priority ) +{ + if ( i_mark.getCM().isValid() ) + { + MemoryMru memmru ( i_mba, i_rank, i_mark.getCM() ); + io_sc.service_data->SetCallout( memmru, i_priority ); + } + + if ( i_mark.getSM().isValid() ) + { + MemoryMru memmru ( i_mba, i_rank, i_mark.getSM() ); + io_sc.service_data->SetCallout( memmru, i_priority ); + } +} + +//------------------------------------------------------------------------------ + TargetHandleList getConnectedDimms( TargetHandle_t i_mba, const CenRank & i_rank ) { diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.H index ff4f97baf..0bf1a6863 100644 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.H +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCalloutUtil.H @@ -24,15 +24,18 @@ #ifndef prdfCalloutUtil_H #define prdfCalloutUtil_H -#include <prdfPlatServices.H> - /** @file prdfCalloutUtil.H * @brief Utility functions for common, non-trivial callouts. */ +#include <prdfPlatServices.H> + +#include <prdfCallouts.H> + namespace PRDF { +class CenMark; class CenRank; struct STEP_CODE_DATA_STRUCT; @@ -48,6 +51,19 @@ namespace CalloutUtil void defaultError( STEP_CODE_DATA_STRUCT & i_sc ); /** + * @brief Will add a MemoryMru to the callout list for the chip mark and symbol + * mark, if they exist. + * @param i_mba Target MBA. + * @param i_rank Target rank. + * @param i_mark Target mark. + * @param io_sc The step code data struct. + * @param i_priority Callout priority (default MRU_MED). + */ +void calloutMark( TARGETING::TargetHandle_t i_mba, const CenRank & i_rank, + const CenMark & i_mark, STEP_CODE_DATA_STRUCT & io_sc, + PRDpriority i_priority = MRU_MED ); + +/** * @param i_mba The target MBA. * @param i_rank The target rank. * @return A list of DIMMs connected to the MBA and rank. diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenConst.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenConst.H index 8d31d928b..4360da5b2 100644 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenConst.H +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenConst.H @@ -48,6 +48,12 @@ enum SYMBOLS_PER_BYTE = 4, DQS_PER_SYMBOL = 2, DQS_PER_BYTE = SYMBOLS_PER_BYTE * DQS_PER_SYMBOL, + + SYMBOLS_PER_X8DRAM = 4, + SYMBOLS_PER_X4DRAM = 2, + + X8DRAMS_PER_RANK = SYMBOLS_PER_RANK / SYMBOLS_PER_X8DRAM, + X4DRAMS_PER_RANK = SYMBOLS_PER_RANK / SYMBOLS_PER_X4DRAM, }; } // end namespace PRDF diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C index 8b0e920d8..48ea97c00 100644 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.C @@ -228,6 +228,42 @@ int32_t CenDqBitmap::setEccSpare( uint8_t i_pins ) //------------------------------------------------------------------------------ +int32_t CenDqBitmap::isDramSpareAvailable( uint8_t i_portSlct, + bool & o_available ) +{ + #define PRDF_FUNC "[CenDqBitmap::isDramSpareAvailable] " + + int32_t o_rc = SUCCESS; + + o_available = false; + + do + { + if ( PORT_SLCT_PER_MBA <= i_portSlct ) + { + PRDF_ERR( PRDF_FUNC"Invalid parameter: i_portSlct=%d", i_portSlct ); + o_rc = FAIL; break; + } + + if ( isDramWidthX4(iv_mba) ) + { + // TODO: RTC 68096 Need to add x4 ECC support. + } + else + { + o_available = + ( 0 == iv_data[i_portSlct][DIMM_DQ_RANK_BITMAP_SIZE-1] ); + } + + } while (0); + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + void CenDqBitmap::getCaptureData( CaptureData & o_cd ) const { uint8_t rank = iv_rank.flatten(); diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H index 834c3bb01..4762caecd 100644 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenDqBitmap.H @@ -114,6 +114,14 @@ class CenDqBitmap int32_t setEccSpare( uint8_t i_pins ); /** + * @brief Queries for DRAM spare status. + * @param i_portSlct The target port. + * @param o_available TRUE if the spare is available, FALSE if it is used. + * @return Non-SUCCESS if an internal function failed, SUCCESS otherwise. + */ + int32_t isDramSpareAvailable( uint8_t i_portSlct, bool & o_available ); + + /** * @brief Adds the bitmaps for both ports to the capture data. * @param o_cd Capture data struct. */ diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMba.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMba.C index 0d03876ab..c73efc43f 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMba.C +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMba.C @@ -22,19 +22,22 @@ /* IBM_PROLOG_END_TAG */ /** @file prdfCenMba.C - * @brief Contains all the plugin code for the PRD Centaur MBA + * @brief Contains all common plugin code for the Centaur MBA */ +// Framework includes #include <iipServiceDataCollector.h> -#include <prdfCalloutUtil.H> #include <prdfExtensibleChip.H> #include <prdfPlatServices.H> #include <prdfPluginMap.H> -#include <prdfCenAddress.H> +// Pegasus includes +#include <prdfCalloutUtil.H> #include <prdfCenMbaCaptureData.H> #include <prdfCenMbaDataBundle.H> +using namespace TARGETING; + namespace PRDF { @@ -78,71 +81,32 @@ int32_t MaintCmdComplete( ExtensibleChip * i_mbaChip, { #define PRDF_FUNC "[Mba::MaintCmdComplete] " - using namespace TARGETING; - int32_t l_rc = SUCCESS; - TargetHandle_t mbaTarget = i_mbaChip->GetChipHandle(); - - do - { - #ifdef __HOSTBOOT_MODULE - - if ( isInMdiaMode() ) - { - // Immediately inform mdia that the command - // has finished. - - l_rc = mdiaSendEventMsg( mbaTarget, MDIA::RESET_TIMER ); - - if(l_rc) - { - PRDF_ERR( PRDF_FUNC"PlatServices::mdiaSendEventMsg() failed" ); - // keep going - } - - // Determine for mdia whether or not the command - // finished at the end of the last rank or if - // the command will need to be restarted. - // Tuck this away until PostAnalysis. - - CenAddr startAddr, endAddr; - l_rc = getCenMaintStartAddr( i_mbaChip, startAddr ); - l_rc |= getCenMaintEndAddr( i_mbaChip, endAddr ); - if ( SUCCESS != l_rc ) - { - PRDF_ERR( PRDF_FUNC"cenGetMbaAddr() failed" ); - break; - } - - CenMbaDataBundle * mbadb = getMbaDataBundle( i_mbaChip ); - mbadb->iv_sendCmdCompleteMsg = true; - mbadb->iv_cmdCompleteMsgData = - startAddr == endAddr ? MDIA::COMMAND_COMPLETE - : MDIA::COMMAND_STOPPED; - - // Do not commit error log for a successful command complete. - if ( MDIA::COMMAND_COMPLETE == mbadb->iv_cmdCompleteMsgData ) - i_sc.service_data->DontCommitErrorLog(); - } - - #endif // __HOSTBOOT_MODULE - - // Get DRAM repairs capture data - CenMbaCaptureData::addDramRepairsData( mbaTarget, i_sc ); - } while (0); + TargetHandle_t mbaTarget = i_mbaChip->GetChipHandle(); + CenMbaDataBundle * mbadb = getMbaDataBundle( i_mbaChip ); + // Tell the TD controller that a maintenance command complete occurred. + l_rc = mbadb->iv_tdCtlr.handleCmdCompleteEvent( i_sc ); if ( SUCCESS != l_rc ) { - PRDF_ERR( PRDF_FUNC"failed on MBA 0x%08x", getHuid(mbaTarget) ); + PRDF_ERR( PRDF_FUNC"Failed: i_mbaChip=0x%08x", getHuid(mbaTarget) ); CalloutUtil::defaultError( i_sc ); } - return l_rc; + // Gather capture data even if something failed above. + // NOTE: There is no need to capture if the maintenance command complete was + // successful with no errors because the error log will not be + // committed. + if ( !i_sc.service_data->IsDontCommitErrl() ) + CenMbaCaptureData::addDramRepairsData( mbaTarget, i_sc ); + + return PRD_NO_CLEAR_FIR_BITS; // FIR bits are cleared by this plugin #undef PRDF_FUNC } PRDF_PLUGIN_DEFINE( Mba, MaintCmdComplete ); } // end namespace Mba + } // end namespace PRDF diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaDataBundle_common.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaDataBundle_common.H index a239ad48d..fe2eb5c4c 100644 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaDataBundle_common.H +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaDataBundle_common.H @@ -28,11 +28,15 @@ * @brief Contains the common data bundle for a Centaur MBA object. */ +// Framework includes #include <iipSystem.h> #include <prdfExtensibleChip.H> #include <prdfGlobal.H> #include <prdfPlatServices.H> +// Pegasus includes +#include <prdfCenMbaTdCtlr.H> + namespace PRDF { @@ -48,7 +52,7 @@ class CenMbaDataBundleCommon : public DataBundle * @param i_mbaChip The MBA chip. */ explicit CenMbaDataBundleCommon( ExtensibleChip * i_mbaChip ) : - iv_mbaChip(i_mbaChip), iv_membChip(NULL) + iv_mbaChip(i_mbaChip), iv_membChip(NULL), iv_tdCtlr(i_mbaChip) {} /** @@ -83,6 +87,11 @@ class CenMbaDataBundleCommon : public DataBundle ExtensibleChip * iv_mbaChip; ///< This MBA chip ExtensibleChip * iv_membChip; ///< The connected MEMBUF chip + + public: // instance variables + + CenMbaTdCtlr iv_tdCtlr; ///< Targeted Diagnostics Controller + }; } // end namespace PRDF diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaExtraSig.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaExtraSig.H new file mode 100644 index 000000000..3fa49f259 --- /dev/null +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaExtraSig.H @@ -0,0 +1,48 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaExtraSig.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __prdfCenMbaExtraSig_H +#define __prdfCenMbaExtraSig_H + +#include <prdrSignatures.H> + +PRDR_ERROR_SIGNATURE(MaintCmdComplete_ERROR, 0xeeee0000, "", + "ERROR: maint cmd complete analysis failed" ); + +PRDR_ERROR_SIGNATURE(StartVcmPhase1, 0xffff0000, "", "Starting VCM phase 1"); +PRDR_ERROR_SIGNATURE(StartVcmPhase2, 0xffff0001, "", "Starting VCM phase 2"); +PRDR_ERROR_SIGNATURE(StartDsdPhase1, 0xffff0002, "", "Starting DSD phase 1"); +PRDR_ERROR_SIGNATURE(StartDsdPhase2, 0xffff0003, "", "Starting DSD phase 2"); + +PRDR_ERROR_SIGNATURE(MaintUE, 0xffff0010, "", "Maintenance UE"); + +PRDR_ERROR_SIGNATURE(VcmVerified, 0xffff0020, "", "VCM: verified"); +PRDR_ERROR_SIGNATURE(VcmFalseAlarm, 0xffff0021, "", "VCM: false alarm"); +PRDR_ERROR_SIGNATURE(VcmBadSpare, 0xffff0022, "", "VCM: bad DRAM spare"); +PRDR_ERROR_SIGNATURE(VcmMarksUnavail, 0xffff0023, "", + "VCM: No more marks available"); + +PRDR_ERROR_SIGNATURE(DsdDramSpared, 0xffff0030, "", "DSD: DRAM spared"); +PRDR_ERROR_SIGNATURE(DsdBadSpare, 0xffff0031, "", "DSD: DRAM spare is bad"); + +#endif // __prdfCenMbaExtraSig_H diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C new file mode 100644 index 000000000..1e7a0ed7c --- /dev/null +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C @@ -0,0 +1,104 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#include <prdfCenMbaTdCtlr_common.H> + +using namespace TARGETING; + +namespace PRDF +{ + +using namespace PlatServices; + +//------------------------------------------------------------------------------ + +int32_t CenMbaTdCtlrCommon::cleanupPrevCmd() +{ + #define PRDF_FUNC "[CenMbaTdCtlrCommon::cleanupPrevCmd] " + + int32_t o_rc = SUCCESS; + + // Clean up the current maintenance command. This must be done whenever + // maintenance command will no longer be executed. + if ( NULL != iv_mssCmd ) + { + o_rc = iv_mssCmd->cleanupCmd(); + if ( SUCCESS != o_rc ) + PRDF_ERR( PRDF_FUNC"cleanupCmd() failed" ); + + delete iv_mssCmd; iv_mssCmd = NULL; + } + + // Clear the command complete attention. This must be done before starting + // the next maintenance command. + SCAN_COMM_REGISTER_CLASS * firand = iv_mbaChip->getRegister("MBASPA_AND"); + firand->setAllBits(); + + firand->ClearBit(0); // Maintenance command complete + firand->ClearBit(8); // Maintenance command complete (DD1.0 workaround) + + int32_t l_rc = firand->Write(); + if ( SUCCESS != l_rc ) + { + PRDF_ERR( PRDF_FUNC"Write() failed on MBASPA_AND" ); + o_rc = FAIL; + } + + return o_rc; + + #undef PRDF_FUNC +} + +//------------------------------------------------------------------------------ + +int32_t CenMbaTdCtlrCommon::chipMarkCleanup() +{ + #define PRDF_FUNC "[CenMbaTdCtlrCommon::chipMarkCleanup] " + + int32_t o_rc = SUCCESS; + + do + { + SCAN_COMM_REGISTER_CLASS * ddrPhyAndFir = + iv_mbaChip->getRegister( "MBADDRPHYFIR_AND" ); + ddrPhyAndFir->setAllBits(); + + ddrPhyAndFir->ClearBit(50); // Calibration Error RE 0 + ddrPhyAndFir->ClearBit(58); // Calibration Error RE 1 + + o_rc = ddrPhyAndFir->Write(); + if ( SUCCESS != o_rc ) + { + PRDF_ERR( PRDF_FUNC"Write() failed on MBADDRPHYFIR_AND" ); + break; + } + + } while(0); + + return o_rc; + + #undef PRDF_FUNC +} + +} // end namespace PRDF + diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.H new file mode 100644 index 000000000..5107dc7f5 --- /dev/null +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.H @@ -0,0 +1,212 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/diag/prdf/common/plat/pegasus/prdfCenMbaTdCtlr_common.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/** @file prdfCenMbaTdCtlr_common.H + * @brief The common implementation of the MBA TD Controller. + */ + +#ifndef __prdfCenMbaTdCtlr_common_H +#define __prdfCenMbaTdCtlr_common_H + +// Framework includes +#include <iipServiceDataCollector.h> +#include <prdf_types.h> +#include <prdfPlatServices.H> + +// Pegasus includes +#include <prdfCenAddress.H> +#include <prdfCenConst.H> +#include <prdfCenMarkstore.H> +#include <prdfCenMbaExtraSig.H> + +namespace PRDF +{ + +class ExtensibleChip; + +/** + * @brief A state machine for memory targeted diagnostics. + */ +class CenMbaTdCtlrCommon +{ + public: // functions + + /** + * @brief Constructor + * + * This constructor will be called in the MBA data bundle code. Therefore, + * no register reads/writes can be done in this constructor. Anything needed + * to initialize the instance variables that requires register reads/writes + * or is non-trivial should be done in initialize(). + * + * @param i_mbaChip An MBA chip. + */ + explicit CenMbaTdCtlrCommon( ExtensibleChip * i_mbaChip ) : + iv_mbaChip(i_mbaChip), iv_initialized(false), iv_rank(), iv_mark(), + iv_mssCmd(NULL) + {} + + /** @brief Destructor */ + ~CenMbaTdCtlrCommon() + { + delete iv_mssCmd; iv_mssCmd = NULL; + } + + /** + * @brief Determines and executes the next course of action after a + * maintenance command complete attention. + * @note Initializes the TD controller, if needed. + * @param io_sc The step code data struct. + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + */ + virtual int32_t handleCmdCompleteEvent( STEP_CODE_DATA_STRUCT & io_sc ) = 0; + + protected: // functions + + /** + * @brief Initializes the TD controller and sets appropriate information + * in the hardware, if needed. + * + * Since the TD controller constructor will only be called in the MBA data + * bundle, register reads/writes can NOT be done in the constructor. + * Instead, anything needed to initialize the instance variables that + * requires register reads/writes or is non-trivial should be done in + * this function. + * + * @note Should be called at the beginning of every public function to + * ensure the TD controller is initialized. + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + */ + virtual int32_t initialize() = 0; + + /** + * @brief Analyzes a non-TD command complete event. + * + * A maintenance command has completed but no TD are in progress. This + * function will check for any ECC errors, unverified chip marks from a + * reset/reload, etc. and starts any TD procedures, if necessary. + * + * @param io_sc The step code data struct. + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + */ + virtual int32_t analyzeCmdComplete( STEP_CODE_DATA_STRUCT & io_sc ) = 0; + + /** + * @brief Analyzes VCM Phase 1 results and moves state machine. + * @param io_sc The step code data struct. + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + */ + virtual int32_t analyzeVcmPhase1( STEP_CODE_DATA_STRUCT & io_sc ) = 0; + + /** + * @brief Analyzes VCM Phase 2 results and moves state machine. + * @param io_sc The step code data struct. + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + */ + virtual int32_t analyzeVcmPhase2( STEP_CODE_DATA_STRUCT & io_sc ) = 0; + + /** + * @brief Analyzes DSD Phase 1 results and moves state machine. + * @param io_sc The step code data struct. + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + */ + virtual int32_t analyzeDsdPhase1( STEP_CODE_DATA_STRUCT & io_sc ) = 0; + + /** + * @brief Analyzes DSD Phase 2 results and moves state machine. + * @param io_sc The step code data struct. + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + */ + virtual int32_t analyzeDsdPhase2( STEP_CODE_DATA_STRUCT & io_sc ) = 0; + + /** + * @brief Starts VCM Phase 1. + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + */ + virtual int32_t startVcmPhase1() = 0; + + /** + * @brief Starts VCM Phase 2. + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + */ + virtual int32_t startVcmPhase2() = 0; + + /** + * @brief Starts DSD Phase 1. + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + */ + virtual int32_t startDsdPhase1() = 0; + + /** + * @brief Starts DSD Phase 2. + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + */ + virtual int32_t startDsdPhase2() = 0; + + /** + * @return TRUE if currently running a targeted diagnositics procedure, + * FALSE otherwise. + */ + virtual bool isInTdMode() = 0; + + /** + * @brief Calls the cleanupCmd() function of the command that had just + * completed. + * @note This function will clear the maintenance command complete + * attention. So for FSP attentions, the SDC needs to be synched + * before calling this function just in case there is a + * reset/reload. + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + */ + virtual int32_t cleanupPrevCmd(); + + /** + * @brief Clears FIR bits that may have been a side-effect of a chip mark + * placed by hardware. + * @return Non-SUCCESS if an internal function fails, SUCCESS otherwise. + */ + virtual int32_t chipMarkCleanup(); + + protected: // instance variables + + /** The memory controller chip that this TD controller acts on. */ + ExtensibleChip * iv_mbaChip; + + /** Indicates if TD controller is initialized. */ + bool iv_initialized; + + /** The current rank that is being targeted for diagnostics. */ + CenRank iv_rank; + + /** The current mark that is being targeted for diagnostics. */ + CenMark iv_mark; + + /** Current maintenance command */ + PlatServices::mss_MaintCmdWrapper * iv_mssCmd; + +}; // CenMbaTdCtlrCommon + +} // end namespace PRDF + +#endif // __prdfCenMbaTdCtlr_common_H + diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C b/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C index 38edaea21..57eaf1322 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.C @@ -60,29 +60,17 @@ CenSymbol CenSymbol::fromSymbol( TargetHandle_t i_mba, const CenRank & i_rank, break; } - if ( SYMBOLS_PER_RANK <= i_symbol ) - { - PRDF_ERR( PRDF_FUNC"i_symbol is invalid" ); - break; - } - if ( BOTH_SYMBOL_DQS < i_pins ) { PRDF_ERR( PRDF_FUNC"i_pins is invalid" ); break; } - o_symbol = CenSymbol ( i_mba, i_rank, wiringType, i_symbol, i_pins ); + o_symbol = CenSymbol ( i_mba, i_rank, wiringType, i_symbol, i_pins, + isDramWidthX4(i_mba) ); } while (0); - if ( !o_symbol.isValid() ) - { - PRDF_ERR( PRDF_FUNC"Failed: i_mba=0x%08x i_rank=%d i_symbol=%d " - "i_pins=%d", getHuid(i_mba), i_rank.flatten(), i_symbol, - i_pins ); - } - return o_symbol; #undef PRDF_FUNC @@ -124,17 +112,11 @@ CenSymbol CenSymbol::fromDimmDq( TargetHandle_t i_mba, const CenRank & i_rank, uint8_t pins = (0 == (i_dimmDq & ODD_SYMBOL_DQ)) ? EVEN_SYMBOL_DQ : ODD_SYMBOL_DQ; - o_symbol = CenSymbol ( i_mba, i_rank, wiringType, symbol, pins ); + o_symbol = CenSymbol ( i_mba, i_rank, wiringType, symbol, pins, + isDramWidthX4(i_mba) ); } while (0); - if ( !o_symbol.isValid() ) - { - PRDF_ERR( PRDF_FUNC"Failed: i_mba=0x%08x i_rank=%d i_dimmDq=%d " - "i_portSlct=%d", getHuid(i_mba), i_rank.flatten(), i_dimmDq, - i_portSlct ); - } - return o_symbol; #undef PRDF_FUNC @@ -205,6 +187,20 @@ uint8_t CenSymbol::symbol2PortSlct( uint8_t i_symbol ) //------------------------------------------------------------------------------ +uint8_t CenSymbol::symbol2Dram( uint8_t i_symbol, bool isX4Dram ) +{ + uint8_t dram = isX4Dram ? X4DRAMS_PER_RANK : X8DRAMS_PER_RANK; + + if ( SYMBOLS_PER_RANK > i_symbol ) + { + dram = i_symbol / (isX4Dram ? SYMBOLS_PER_X4DRAM : SYMBOLS_PER_X8DRAM); + } + + return dram; +} + +//------------------------------------------------------------------------------ + int32_t CenSymbol::getSymbol( const CenRank & i_rank, WiringType i_wiringType, uint8_t i_dimmDq, uint8_t i_portSlct, uint8_t & o_symbol ) diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H b/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H index 0bfc86dfd..a43700e87 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfCenSymbol.H @@ -81,9 +81,10 @@ class CenSymbol * @brief Constructor from components */ CenSymbol( TARGETING::TargetHandle_t i_mba, CenRank i_rank, - WiringType i_wiringType, uint8_t i_symbol, uint8_t i_pins ) : + WiringType i_wiringType, uint8_t i_symbol, uint8_t i_pins, + bool i_x4Dram ) : iv_mbaTarget(i_mba), iv_rank(i_rank), iv_wiringType(i_wiringType), - iv_symbol(i_symbol), iv_pins(i_pins) + iv_symbol(i_symbol), iv_pins(i_pins), iv_x4Dram(i_x4Dram) {} public: // functions @@ -148,6 +149,12 @@ class CenSymbol /** @return The port select for this symbol. */ uint8_t getPortSlct() const { return symbol2PortSlct( iv_symbol ); } + /** @return The DRAM index for this symbol. */ + uint8_t getDram() const { return symbol2Dram( iv_symbol, iv_x4Dram ); } + + /** @return TRUE this symbol is on a x4 DRAM, FALSE otherwise. */ + bool isX4Dram() const { return iv_x4Dram; } + /** @return The symbol of the given Centaur DQ and port select. */ static uint8_t cenDq2Symbol( uint8_t i_CenDq, uint8_t i_ps ); @@ -157,6 +164,9 @@ class CenSymbol /** @return The port select for given symbol. */ static uint8_t symbol2PortSlct( uint8_t i_symbol ); + /** @return The DRAM index for the given symbol. */ + static uint8_t symbol2Dram( uint8_t i_symbol, bool isX4Dram ); + /** * @brief Overrides the '<' operator. * @param i_symbol The symbol to compare with. @@ -199,6 +209,7 @@ class CenSymbol WiringType iv_wiringType; ///< This symbol's wiring type. uint8_t iv_symbol; ///< This symbol's numerical value. uint8_t iv_pins; ///< See enum DqMask. + bool iv_x4Dram; ///< TRUE x4 DRAM, FALSE x8 DRAM. }; } // end namespace PRDF diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.C b/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.C index 177a64d91..6c4e7a736 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.C +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.C @@ -203,8 +203,7 @@ MemoryMru::MemoryMru( TARGETING::TargetHandle_t i_mbaTarget, iv_memMruMeld.s.rank = iv_rank.flatten(); iv_memMruMeld.s.symbol = iv_symbol.getSymbol(); iv_memMruMeld.s.pins = iv_symbol.getPins(); - //TODO: RTC 68096 Add support for DRAM spare - iv_memMruMeld.s.dramSpared = 0; + iv_memMruMeld.s.dramSpared = 0; // manually set by setDramSpared() iv_memMruMeld.s.wiringType = iv_symbol.getWiringType(); // If the code gets to this point the MemoryMru is valid. diff --git a/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.H b/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.H index a1cb63ab0..448649385 100755 --- a/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.H +++ b/src/usr/diag/prdf/common/plat/pegasus/prdfMemoryMru.H @@ -71,6 +71,9 @@ class MemoryMru MemoryMru( TARGETING::TargetHandle_t i_mbaTarget, const CenRank & i_rank, MemoryMruData::Callout i_specialCallout ); + /** @brief Indicates that the symbol actually resides on the DRAM spare. */ + void setDramSpared() { iv_memMruMeld.s.dramSpared = 1; } + public: // functions /** @return The 32-bit representation of this MemoryMru. */ |