diff options
author | Brian Stegmiller <bjs@us.ibm.com> | 2016-08-24 14:58:53 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-09-18 13:15:12 -0400 |
commit | b5b931c182a5432759f74ad0e6847dfc0ef9e159 (patch) | |
tree | 7e90cf775f8d23bec010f2305ff6b4779821d791 /src | |
parent | 83efa306d8460f901459b936c341781633c7b507 (diff) | |
download | talos-hostboot-b5b931c182a5432759f74ad0e6847dfc0ef9e159.tar.gz talos-hostboot-b5b931c182a5432759f74ad0e6847dfc0ef9e159.zip |
ATTN: Clear Intr Reg on RECOV errors from Host Side
Change-Id: I6427f18fc6d50fc60a9de9d1a06ebc0850fa906b
RTC: 159844
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/28753
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com>
Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com>
Reviewed-by: Caleb N. Palmer <cnpalmer@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/usr/diag/attn/common/attnbits.H | 15 | ||||
-rw-r--r-- | src/usr/diag/attn/common/attnprd.C | 54 | ||||
-rw-r--r-- | src/usr/diag/attn/ipl/test/attnfakeprd.C | 68 | ||||
-rw-r--r-- | src/usr/diag/attn/ipl/test/attnrandsource.C | 15 | ||||
-rw-r--r-- | src/usr/diag/attn/ipl/test/attnrandsource.H | 12 | ||||
-rw-r--r-- | src/usr/diag/attn/ipl/test/attntestproc.H | 221 | ||||
-rw-r--r-- | src/usr/diag/attn/ipl/test/makefile | 2 |
7 files changed, 359 insertions, 28 deletions
diff --git a/src/usr/diag/attn/common/attnbits.H b/src/usr/diag/attn/common/attnbits.H index af34cb5b4..763f0c987 100644 --- a/src/usr/diag/attn/common/attnbits.H +++ b/src/usr/diag/attn/common/attnbits.H @@ -176,26 +176,17 @@ bool getCheckbits( */ enum { - // Interrupt Type Mask Register - INTR_TYPE_MASK_OR_REG = 0x000F002D, - INTR_TYPE_MASK_AND_REG = 0x000F002E, - - // Interrupt Type Config Register - // (contains MUX'ing bits now) - INTR_TYPE_CONFIG_AND_REG = 0x000F0031, - // This was for MCS usage, but not needed right now GP2_REG = 0x02000002, + // PIB interrupt register (spec/recov/chkstop) + PIB_INTR_TYPE_REG = 0x000F001A, + // IPOLL MASK register IPOLL_MASK_REG = 0x000F0033, // (IPOLL) Error status reg IPOLL_STATUS_REG = 0x000F0034, - // Interrupt Presentation Reg (IPR) - INTR_TYPE_LCL_ERR_STATUS_REG = 0x000F0020, - INTR_TYPE_LCL_ERR_STATUS_OR_REG = 0x000F0021, - INTR_TYPE_LCL_ERR_STATUS_AND_REG = 0x000F0022, }; diff --git a/src/usr/diag/attn/common/attnprd.C b/src/usr/diag/attn/common/attnprd.C index 1111c14ed..cf0019b03 100644 --- a/src/usr/diag/attn/common/attnprd.C +++ b/src/usr/diag/attn/common/attnprd.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014,2015 */ +/* Contributors Listed Below - COPYRIGHT 2014,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -96,8 +96,56 @@ errlHndl_t PrdImpl::callPrd(const AttentionList & i_attentions) #endif { err = PRDF::main(attnList.front().attnType, attnList); - } - } + + // For the initial NIMBUS chip, there is a HW issue + // which requires us to clear the "Combined Global + // interrupt register" on recoverable errors. + // This also affects Checkstop/Special Attns, but + // the FSP handles those and already clears the reg. + // The issue does not apply to host/unit cs attns. + uint8_t l_ecLevel = 0; + AttnList::iterator l_attnIter = attnList.begin(); + + // Shouldn't be mixing NIMBUS with CUMULUS,etc... + // so probably don't need to repeat this call per chip. + bool l_isNimbus = ( (*l_attnIter).targetHndl-> + getAttr<ATTR_MODEL>() == MODEL_NIMBUS ); + + // Iterate thru all chips in case PRD handled + // a chip other than the first one. + while(l_attnIter != attnList.end()) + { + l_ecLevel = (*l_attnIter).targetHndl->getAttr<ATTR_EC>(); + + + if ( (RECOVERABLE == (*l_attnIter).attnType) && + (true == l_isNimbus) && (l_ecLevel < 0x11) + ) + { + errlHndl_t l_scomErr = NULL; + uint64_t l_clrAllBits = 0; + + l_scomErr = putScom( (*l_attnIter).targetHndl, + PIB_INTR_TYPE_REG, + l_clrAllBits + ); + + if (NULL != l_scomErr) + { + ATTN_ERR("Clear PibIntrReg failed, HUID:0X%08X", + get_huid( (*l_attnIter).targetHndl) ); + errlCommit(l_scomErr, ATTN_COMP_ID); + } // failed to clear PIB intr reg + + } // if recoverable attn + + ++l_attnIter; + + } // end while looping thru attn list + + } // end else NOT checkstop + + } // if attn list is not empty return err; } diff --git a/src/usr/diag/attn/ipl/test/attnfakeprd.C b/src/usr/diag/attn/ipl/test/attnfakeprd.C index 0f4bd9a3d..5c9bd6340 100644 --- a/src/usr/diag/attn/ipl/test/attnfakeprd.C +++ b/src/usr/diag/attn/ipl/test/attnfakeprd.C @@ -1,11 +1,11 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/usr/diag/attn/hostboot/test/attnfakeprd.C $ */ +/* $Source: src/usr/diag/attn/ipl/test/attnfakeprd.C $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014 */ +/* Contributors Listed Below - COPYRIGHT 2014,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -32,6 +32,7 @@ #include "attninject.H" #include "../../common/attnops.H" #include "../../common/attnlist.H" +#include "../../common/attntrace.H" #include <sys/time.h> using namespace PRDF; @@ -73,7 +74,68 @@ struct Clear errlHndl_t FakePrd::callPrd(const AttentionList & i_attentions) { - return i_attentions.forEach(Clear(*iv_injectSink)).err; + errlHndl_t l_elog = i_attentions.forEach(Clear(*iv_injectSink)).err; + + AttnList l_attnList; + i_attentions.getAttnList(l_attnList); + + // ----------------------------------------------------- + // asdf bjs @TODO: RTC:151004 (this is FAKE code only) + // If you do the EC/MODEL check, it crashes in CXX testcase. + // Kind of thinking some library missing that is needed when + // adding these calls, For now, I will just leave them out + // and we could probably scrap this test now that it runs + // successfully (see attntestproc.H) + // (Maybe add to 'fake target service' for these ATTRs) + // ----------------------------------------------------- + // For the initial NIMBUS chip, there is a HW issue + // which requires us to clear the "Combined Global + // interrupt register" on recoverable errors. + // This also affects Checkstop/Special Attns, but + // the FSP handles those and already clears the reg. + // The issue does not apply to host/unit cs attns. +// uint8_t l_ecLevel = 0; + AttnList::iterator l_attnIter = l_attnList.begin(); + + // Shouldn't be mixing NIMBUS with CUMULUS,etc... + // so probably don't need to repeat this call per chip. +// bool l_isNimbus = ( (*l_attnIter).targetHndl-> +// getAttr<ATTR_MODEL>() == MODEL_NIMBUS ); + + // Iterate thru all chips in case PRD handled + // a chip other than the first one. + while(l_attnIter != l_attnList.end()) + { +// l_ecLevel = (*l_attnIter).targetHndl->getAttr<ATTR_EC>(); + + + if ( (RECOVERABLE == (*l_attnIter).attnType) +// && (true == l_isNimbus) && (l_ecLevel < 0x11) + ) + { + errlHndl_t l_scomErr = NULL; + uint64_t l_clrAllBits = 0; + + l_scomErr = putScom( (*l_attnIter).targetHndl, + PIB_INTR_TYPE_REG, + l_clrAllBits + ); + + if (NULL != l_scomErr) + { + ATTN_ERR("Clear PibIntrReg failed, HUID:0X%08X", + get_huid( (*l_attnIter).targetHndl) ); + errlCommit(l_scomErr, ATTN_COMP_ID); + } // failed to clear PIB intr reg + + } // if recoverable attn + + ++l_attnIter; + + } // end while looping thru attn list + + + return l_elog; } FakePrd::FakePrd(InjectSink & i_injectSink) : diff --git a/src/usr/diag/attn/ipl/test/attnrandsource.C b/src/usr/diag/attn/ipl/test/attnrandsource.C index 3e9654fe5..9cbd229ba 100644 --- a/src/usr/diag/attn/ipl/test/attnrandsource.C +++ b/src/usr/diag/attn/ipl/test/attnrandsource.C @@ -85,7 +85,7 @@ void* RandSource::main(void * i_source) return NULL; } -void RandSource::run() +void RandSource::run(PRDF::ATTENTION_VALUE_TYPE i_attnType) { mutex_lock(&iv_mutex); @@ -108,9 +108,18 @@ void RandSource::run() // select a random target // generate a random attention - d.targetHndl = *(iv_first + randint(0, distance(iv_first, iv_last) -1)); - d.attnType = getRandomAttentionType(); + + // Input value determines if we use random type + // or what was passed in + if (PRDF::END_ATTENTION_TYPE == i_attnType) + { + d.attnType = getRandomAttentionType(); + } + else + { + d.attnType = i_attnType; + } l.push_back(d); ATTN_TRACE("RandSource:run, Type:%d, Count:%d Iterations:%d", diff --git a/src/usr/diag/attn/ipl/test/attnrandsource.H b/src/usr/diag/attn/ipl/test/attnrandsource.H index a3deedfda..fa6803649 100644 --- a/src/usr/diag/attn/ipl/test/attnrandsource.H +++ b/src/usr/diag/attn/ipl/test/attnrandsource.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014,2015 */ +/* Contributors Listed Below - COPYRIGHT 2014,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -85,8 +85,16 @@ class RandSource /** * @brief run Execute the testcase. + * + * @param[in] i_attnType - Optional parameter + * If you pass this in, then only that + * attention type will be generated. + * Else a random attn type from the valid + * values will get used. */ - void run(); + void run( PRDF::ATTENTION_VALUE_TYPE i_attnType = + PRDF::END_ATTENTION_TYPE + ); /** * @brief dtor diff --git a/src/usr/diag/attn/ipl/test/attntestproc.H b/src/usr/diag/attn/ipl/test/attntestproc.H index 06e1d4f1a..873140050 100644 --- a/src/usr/diag/attn/ipl/test/attntestproc.H +++ b/src/usr/diag/attn/ipl/test/attntestproc.H @@ -1,11 +1,11 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/usr/diag/attn/hostboot/test/attntestproc.H $ */ +/* $Source: src/usr/diag/attn/ipl/test/attntestproc.H $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014 */ +/* Contributors Listed Below - COPYRIGHT 2014,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -45,6 +45,7 @@ #include <cxxtest/TestSuite.H> #include <sys/time.h> #include "../../common/attntrace.H" +#include <targeting/common/targetservice.H> using namespace ATTN; using namespace PRDF; @@ -56,7 +57,6 @@ using namespace std; class AttnProcTest: public CxxTest::TestSuite { public: - /** * @brief testQuery Unit test for the * query method. @@ -64,6 +64,7 @@ class AttnProcTest: public CxxTest::TestSuite void testQuery(void) { ATTN_SLOW(ENTER_MRK "AttnProcTest::testQuery"); +#if 0 // asdf bjs @TODO: RTC:151004 static const uint64_t iterations = 100; static const uint64_t targetPoolSize = 8; @@ -144,6 +145,7 @@ class AttnProcTest: public CxxTest::TestSuite break; } } +#endif ATTN_SLOW(EXIT_MRK "AttnProcTest::testQuery"); } @@ -155,7 +157,7 @@ class AttnProcTest: public CxxTest::TestSuite void testFakeAttentions() { ATTN_SLOW(ENTER_MRK "AttnProcTest::testFakeAttentions"); - +#if 0 // asdf bjs @TODO: RTC:151004 static const uint64_t targetPoolSize = 8; static const uint64_t iterations = 5; static const uint64_t maxAttnsPerIteration = 5; @@ -269,8 +271,219 @@ class AttnProcTest: public CxxTest::TestSuite v.dump(); } +#endif ATTN_SLOW(EXIT_MRK "AttnProcTest::testFakeAttentions"); } + + + // Want to verify the HW workaround on NIMBUS + // for clearing F001A reg on RECOV errors. + void testRecovAttnWorkaround() + { + static const uint64_t targetPoolSize = 1; + static const uint64_t iterations = 1; + static const uint64_t maxAttnsPerIteration = 1; + uint64_t l_intrAddrReg = 0x00000000000F001Aull; + uint64_t l_intrAddrData = 0xE000000000000000ull; + uint64_t l_intrDataRead = l_intrAddrData; + + + + ATTN_SLOW("AttnProcTest::testRecovAttnWorkaround"); + + errlHndl_t err = 0; + + // Verify RECOV error goes thru the workaround + ATTN_SLOW("AttnProcTest::RECOV TEST"); + + FakeSystem system; + + FakeGfir recGfir(RECOVERABLE); + recGfir.install(system); + + Validator v; + v.install(system); + system.installScomImpl(); + + FakeProcTargetService targetSvc(targetPoolSize); + TargetHandleList procs; + targetSvc.getAllChips(procs, TYPE_PROC); + + RandSource source( + iterations, + maxAttnsPerIteration, + system, + &procs[0], + &procs[0] + procs.size()); + + targetSvc.installTargetService(); + + FakePrd prd(system); + prd.installPrd(); + + getProcOps().enable(); + + ATTN_SLOW("AttnProcTest::testRecovAttnWorkaround ready to go"); + + do + { + // --------------------------------------- + // Alter the combined global interrupt reg + // so we can verify it later + err = putScom( procs[0], + l_intrAddrReg, + l_intrAddrData + ); + + if (NULL != err) + { + TS_FAIL("Error1 setting Reg %016llx Data:%016llx", + l_intrAddrReg, l_intrAddrData ); + break; + } + // --------------------------------------- + + source.run(RECOVERABLE); + + err = checkForIplAttentions(); + + if(err) + { + TS_FAIL("unexpected error checking for ipl attentions."); + break; + } + + uint64_t count = system.count(); + if(count) + { + TS_FAIL("%d unexpected attentions present after check for " + "ipl attentions.", count); + + system.dump(); + break; + } + + // --------------------------------------- + // The combined global interrupt reg should get + // reset (at least on certain level of hardware) + err = getScom( procs[0], + l_intrAddrReg, + l_intrDataRead + ); + + if (NULL != err) + { + TS_FAIL("Error1 getting Reg %016llx Data:%016llx", + l_intrAddrReg, l_intrAddrData ); + break; + } + + // Verify REG is MODIFIED this time + if (0 != l_intrDataRead) + { + TS_FAIL("Int Reg1 Not cleared: Orig:%016llx Read:%016llx", + l_intrAddrData, l_intrDataRead ); + break; + } + // --------------------------------------- + + + } while(0); + + + // Verify HOST_ATTN skips the workaround + FakeSystem systemHA; + + FakeGfir haGfir(HOST_ATTN); + haGfir.install(systemHA); + + Validator vHA; + vHA.install(systemHA); + systemHA.installScomImpl(); + + RandSource sourceHA( + iterations, + maxAttnsPerIteration, + systemHA, + &procs[0], + &procs[0] + procs.size()); + + FakePrd prdHA(systemHA); + prdHA.installPrd(); + + getProcOps().enable(); + + ATTN_SLOW("AttnProcTest::testRecovAttnWorkaround2 ready to go"); + + do + { + // --------------------------------------- + // Alter the combined global interrupt reg + // so we can verify it later + err = putScom( procs[0], + l_intrAddrReg, + l_intrAddrData + ); + + if (NULL != err) + { + TS_FAIL("Error2 setting Reg %016llx Data:%016llx", + l_intrAddrReg, l_intrAddrData ); + break; + } + // --------------------------------------- + + sourceHA.run(HOST_ATTN); + + err = checkForIplAttentions(); + + if(err) + { + TS_FAIL("unexpected error checking for ipl attentions2."); + break; + } + + uint64_t count = systemHA.count(); + if(count) + { + TS_FAIL("%d unexpected attentions present after check for " + "ipl attentions2.", count); + + systemHA.dump(); + break; + } + + // --------------------------------------- + // The combined global interrupt reg should not + // change + err = getScom( procs[0], + l_intrAddrReg, + l_intrDataRead + ); + + if (NULL != err) + { + TS_FAIL("Error2 getting Reg %016llx Data:%016llx", + l_intrAddrReg, l_intrAddrData ); + break; + } + + // Verify REG is MODIFIED this time + if (l_intrAddrData != l_intrDataRead) + { + TS_FAIL("Int Reg2 altered rig:%016llx Read:%016llx", + l_intrAddrData, l_intrDataRead ); + break; + } + // --------------------------------------- + + } while(0); + + + ATTN_SLOW("AttnProcTest::testRecovAttnWorkaround ending"); + + } // end testRecovAttnWorkaround + }; #endif diff --git a/src/usr/diag/attn/ipl/test/makefile b/src/usr/diag/attn/ipl/test/makefile index faaef1e16..3826af801 100644 --- a/src/usr/diag/attn/ipl/test/makefile +++ b/src/usr/diag/attn/ipl/test/makefile @@ -45,6 +45,6 @@ MODULE = testattn # asdf bjs @TODO: RTC:151004 #TESTS = *.H -TESTS = attntestipl.H +TESTS = attntestipl.H attntestproc.H include ${ROOTPATH}/config.mk |