From 7b0dcb2cc3a80cb09aa2af5d4cd2f2673c7146a6 Mon Sep 17 00:00:00 2001 From: Chris Phan Date: Wed, 24 Jul 2013 10:44:25 -0500 Subject: MDIA: add hcdb/HWAS_CHANGED_BIT_MEMDIAG support Also add check for the new ATTR_RUN_MAX_MEM_PATTERNS Change-Id: I343f1054cf657e06cea688f0a87340bdd32f01f2 RTC: 38367 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/5548 Tested-by: Jenkins Server Reviewed-by: Zane Shelley Reviewed-by: A. Patrick Williams III --- src/usr/diag/mdia/mdia.C | 11 ++ src/usr/diag/mdia/mdiafwd.H | 20 ++++ src/usr/diag/mdia/mdiamba.C | 194 +++++++++++++++++++++++++++++++++++ src/usr/diag/mdia/mdiasm.C | 16 ++- src/usr/diag/mdia/mdiasm.H | 1 + src/usr/diag/mdia/test/mdiatestmba.H | 59 +++++++---- src/usr/diag/mdia/test/mdiatestsm.H | 3 +- 7 files changed, 280 insertions(+), 24 deletions(-) (limited to 'src/usr') diff --git a/src/usr/diag/mdia/mdia.C b/src/usr/diag/mdia/mdia.C index c14bec331..cafc276fb 100644 --- a/src/usr/diag/mdia/mdia.C +++ b/src/usr/diag/mdia/mdia.C @@ -56,6 +56,17 @@ errlHndl_t runStep(const TargetHandleList & i_targetList) if(top) { globals.mfgPolicy = top->getAttr(); + + uint8_t maxMemPatterns = + top->getAttr(); + + // This registry / attr is the same as the + // exhaustive mnfg one + if(maxMemPatterns) + { + globals.mfgPolicy |= + MNFG_FLAG_BIT_MNFG_ENABLE_EXHAUSTIVE_PATTERN_TEST; + } } // get the workflow for each target mba passed in. diff --git a/src/usr/diag/mdia/mdiafwd.H b/src/usr/diag/mdia/mdiafwd.H index 83186f23e..6737cb29b 100644 --- a/src/usr/diag/mdia/mdiafwd.H +++ b/src/usr/diag/mdia/mdiafwd.H @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -184,5 +185,24 @@ errlHndl_t getMbaWorkFlow( */ void doStepCleanup(const Globals & i_globals); +/** + * @brief check if hw state has been changed for an mba's + * associated targets + * + * @param[in] i_mba input mba target + * + * @retval true if hw state has been changed or else + */ +bool isHWStateChanged(TARGETING::TargetHandle_t i_mba); + +/** + * @brief clear hw changed state for an mba's + * associated targets + * + * @param[in] i_mba input mba target + * + */ +void clearHWStateChanged(TARGETING::TargetHandle_t i_mba); + } #endif diff --git a/src/usr/diag/mdia/mdiamba.C b/src/usr/diag/mdia/mdiamba.C index fdac9f11d..35abedbf6 100644 --- a/src/usr/diag/mdia/mdiamba.C +++ b/src/usr/diag/mdia/mdiamba.C @@ -28,6 +28,8 @@ #include "mdiafwd.H" #include "mdiaglobals.H" #include "mdiasm.H" +#include "mdiatrace.H" +#include "targeting/common/utilFilter.H" using namespace TARGETING; @@ -59,6 +61,20 @@ errlHndl_t getMbaDiagnosticMode( o_mode = ONE_PATTERN; } + // Only need to check hw changed state attributes + // when not already set to standard or exhaustive + if((FOUR_PATTERNS != o_mode) || + (NINE_PATTERNS != o_mode)) + { + if(isHWStateChanged(i_mba)) + { + o_mode = FOUR_PATTERNS; + } + } + + MDIA_FAST("getMbaDiagnosticMode: mba: %x, o_mode: 0x%x", + get_huid(i_mba), o_mode); + return 0; } @@ -119,6 +135,184 @@ errlHndl_t getMbaWorkFlow(DiagMode i_mode, WorkFlow & o_wf) break; } + // clear HW changed state attribute + o_wf.push_back(CLEAR_HW_CHANGED_STATE); + return 0; } + +/* + * Local helper function to return a list of Centaur + * DIMMs, and MCS associated with the input MBA target + * + * If i_queryOnly = true (Query) + * - Return a list of DIMMs, Centaur, and + * MCS connected to this MBA + * + * Else (Clear) + * - Return a list of DIMMs and + * (Centaur + MCS) if all the DIMMs behind this + * Centaur have hwchangedState flags cleared + * or about to be cleared by this MBA + */ +TargetHandleList getMemTargetsForQueryOrClear( + TargetHandle_t i_mba, bool i_queryOnly) +{ + #define FUNC "getMemTargetsForQueryOrClear: " + TargetHandleList o_list; + + do + { + // add associated DIMMs + TargetHandleList dimmList; + getChildAffinityTargets(dimmList, + i_mba, + CLASS_NA, + TYPE_DIMM); + + if( ! dimmList.empty() ) + { + o_list.insert(o_list.begin(), dimmList.begin(), + dimmList.end()); + } + + // add associated Centaur + TargetHandleList targetList; + getParentAffinityTargets(targetList, + i_mba, + CLASS_CHIP, + TYPE_MEMBUF); + + if( targetList.empty() ) + { + MDIA_FAST(FUNC"no connected centaur " + "for mba: %x", get_huid(i_mba)); + break; + } + + TargetHandle_t centaur = targetList[0]; + + // if query flag is not set, check to make sure + // all of the dimms connected to this centaur + // have cleared hw chagned state attributes + // before adding this centaur/mcs to the list. + // This is needed because we only clear + // the centaur/mcs attribute when all of the + // dimms' attributes from both mbas have cleared. + if(false == i_queryOnly) + { + targetList.clear(); + getChildAffinityTargets(targetList, + centaur, + CLASS_NA, + TYPE_DIMM); + + if( ! targetList.empty() ) + { + TargetHandleList::iterator target; + + for(target = targetList.begin(); + target != targetList.end(); ++target) + { + // exclude dimms belong to the current mba + // because their attributes will be cleared + if(dimmList.end() != + std::find(dimmList.begin(), + dimmList.end(), *target)) + { + continue; + } + + ATTR_HWAS_STATE_CHANGED_FLAG_type hwChangeFlag; + hwChangeFlag = + (*target)->getAttr(); + + if(HWAS_CHANGED_BIT_MEMDIAG & hwChangeFlag) + { + MDIA_FAST(FUNC"hwChangedState is not cleared " + "for dimm: %x", get_huid(*target)); + centaur = NULL; // don't add centaur and mcs + break; + } + } + } + } + + if(NULL == centaur) + { + break; + } + + o_list.push_back(centaur); + + // get connected mcs target + targetList.clear(); + + getParentAffinityTargets(targetList, + centaur, + CLASS_UNIT, + TYPE_MCS); + + if( ! targetList.empty() ) + { + o_list.push_back(targetList[0]); + } + + } while(0); + + MDIA_DBG(FUNC"mba: %x, size: %d", + get_huid(i_mba), o_list.size()); + + return o_list; + + #undef FUNC +} + + +bool isHWStateChanged(TargetHandle_t i_mba) +{ + bool hwChanged = false; + ATTR_HWAS_STATE_CHANGED_FLAG_type hwChangeFlag; + + // Get a list of associated targets for attribute query + TargetHandleList targetList = + getMemTargetsForQueryOrClear(i_mba, true); + + for(TargetHandleList::iterator target = targetList.begin(); + target != targetList.end(); ++target ) + { + hwChangeFlag = + (*target)->getAttr(); + + if(HWAS_CHANGED_BIT_MEMDIAG & hwChangeFlag) + { + MDIA_DBG("isHWStateChanged: set for target: %x", + get_huid(*target)); + hwChanged = true; + break; + } + } + + return hwChanged; +} + +void clearHWStateChanged(TargetHandle_t i_mba) +{ + TargetHandleList targetList; + + // Get a list of associated targets for attribute clearing + targetList = getMemTargetsForQueryOrClear(i_mba, false); + + for(TargetHandleList::iterator target = targetList.begin(); + target != targetList.end(); ++target) + { + MDIA_DBG("clearHWStateChanged: mba: %x, target: %x", + get_huid(i_mba), get_huid(*target)); + + clear_hwas_changed_bit( *target, + HWAS_CHANGED_BIT_MEMDIAG); + } +} + + } diff --git a/src/usr/diag/mdia/mdiasm.C b/src/usr/diag/mdia/mdiasm.C index 7a6c542ff..ec2892ba8 100644 --- a/src/usr/diag/mdia/mdiasm.C +++ b/src/usr/diag/mdia/mdiasm.C @@ -480,6 +480,7 @@ bool StateMachine::workItemIsAsync(WorkFlowProperties & i_wfp) { case RESTORE_DRAM_REPAIRS: case DUMMY_SYNC_PHASE: + case CLEAR_HW_CHANGED_STATE: // no attention associated with these so // schedule the next work item now @@ -545,6 +546,16 @@ bool StateMachine::executeWorkItem(WorkFlowProperties * i_wfp) break; + case CLEAR_HW_CHANGED_STATE: + + mutex_lock(&iv_mutex); + + clearHWStateChanged(getTarget(*i_wfp)); + + mutex_unlock(&iv_mutex); + + break; + default: break; } @@ -822,6 +833,7 @@ CommandMonitor & StateMachine::getMonitor() bool StateMachine::processMaintCommandEvent(const MaintCommandEvent & i_event) { + enum { CLEANUP_CMD = 0x8, @@ -870,8 +882,8 @@ bool StateMachine::processMaintCommandEvent(const MaintCommandEvent & i_event) cmd = static_cast(wfp.data); - MDIA_FAST("sm: processing event for: %x: cmd: %p", - get_huid(getTarget(wfp))); + MDIA_FAST("sm: processing event for: %x, cmd: %p, type: %x", + get_huid(getTarget(wfp)), cmd, i_event.type); switch(i_event.type) { diff --git a/src/usr/diag/mdia/mdiasm.H b/src/usr/diag/mdia/mdiasm.H index 6dccaa86c..f4c93b699 100644 --- a/src/usr/diag/mdia/mdiasm.H +++ b/src/usr/diag/mdia/mdiasm.H @@ -55,6 +55,7 @@ enum WorkFlowPhase DUMMY_ASYNC_PHASE, RESTORE_DRAM_REPAIRS, START_SCRUB, + CLEAR_HW_CHANGED_STATE, }; /** diff --git a/src/usr/diag/mdia/test/mdiatestmba.H b/src/usr/diag/mdia/test/mdiatestmba.H index b855c66a2..3dd2d8bd9 100644 --- a/src/usr/diag/mdia/test/mdiatestmba.H +++ b/src/usr/diag/mdia/test/mdiatestmba.H @@ -31,6 +31,7 @@ #include #include #include +#include #include "../mdiafwd.H" #include "../mdiaglobals.H" #include "../mdiasm.H" @@ -46,21 +47,28 @@ class MdiaMbaTest : public CxxTest::TestSuite TS_TRACE(ENTER_MRK "testGetMbaDiagnosticMode"); - DiagMode mode; - Globals globals = {}; - TargetHandle_t mba = 0; + TargetHandleList mbaList; + getAllChiplets(mbaList, TYPE_MBA); - errlHndl_t err = getMbaDiagnosticMode( - globals, mba, mode); - - if(err) + if( !mbaList.empty() ) { - TS_FAIL("getMbaDiagnosticMode failed unexpectedly"); - } + DiagMode mode; + Globals globals = {}; + TargetHandle_t mba = mbaList[0]; - if(mode != INIT_ONLY) - { - TS_FAIL("mode != INIT_ONLY"); + errlHndl_t err = getMbaDiagnosticMode( + globals, mba, mode); + + if(err) + { + TS_FAIL("getMbaDiagnosticMode failed " + "unexpectedly"); + } + + if(mode != INIT_ONLY) + { + TS_FAIL("mode != INIT_ONLY"); + } } TS_TRACE(EXIT_MRK "testGetMbaDiagnosticMode"); @@ -76,24 +84,33 @@ class MdiaMbaTest : public CxxTest::TestSuite Globals globals = {}; TargetHandle_t mba = 0; DiagMode mode; + errlHndl_t err = NULL; + TargetHandleList mbaList; + getAllChiplets(mbaList, TYPE_MBA); - errlHndl_t err = getMbaDiagnosticMode( - globals, mba, mode); - - if(err) + if( !mbaList.empty() ) { - TS_FAIL("getMbaDiagnosticMode failed unexpectedly"); - } + mba = mbaList[0]; + err = getMbaDiagnosticMode( + globals, mba, mode); - if(mode != INIT_ONLY) - { - TS_FAIL("mode != INIT_ONLY"); + if(err) + { + TS_FAIL("getMbaDiagnosticMode " + "failed unexpectedly"); + } + + if(mode != INIT_ONLY) + { + TS_FAIL("mode != INIT_ONLY"); + } } WorkFlow wf, expected; expected.push_back(RESTORE_DRAM_REPAIRS); expected.push_back(START_PATTERN_0); + expected.push_back(CLEAR_HW_CHANGED_STATE); err = getMbaWorkFlow(mode, wf); diff --git a/src/usr/diag/mdia/test/mdiatestsm.H b/src/usr/diag/mdia/test/mdiatestsm.H index 11e675029..fd905f9f0 100644 --- a/src/usr/diag/mdia/test/mdiatestsm.H +++ b/src/usr/diag/mdia/test/mdiatestsm.H @@ -311,7 +311,8 @@ class MdiaSmTest : public CxxTest::TestSuite Checks(START_PATTERN_5, true), Checks(START_PATTERN_6, true), Checks(START_PATTERN_7, true), - Checks(START_SCRUB, true) + Checks(START_SCRUB, true), + Checks(CLEAR_HW_CHANGED_STATE, false) }; StateMachine sm; -- cgit v1.2.1