diff options
author | Brian Stegmiller <bjs@us.ibm.com> | 2017-09-27 16:09:22 -0500 |
---|---|---|
committer | Zane C. Shelley <zshelle@us.ibm.com> | 2017-10-11 17:16:46 -0400 |
commit | 6be06fc2818d424dc2de77592700e31e71d00bff (patch) | |
tree | 31bfa1397966c8788f5b8cbc9c7ed059180e9430 /src/usr/diag/attn | |
parent | 207b8e472e59158c37235f10e0aa0db230972691 (diff) | |
download | talos-hostboot-6be06fc2818d424dc2de77592700e31e71d00bff.tar.gz talos-hostboot-6be06fc2818d424dc2de77592700e31e71d00bff.zip |
ATTN: Support memory attentions for Cumulus
Change-Id: I98391edb0f0e223cf8f4d217199217433e86033a
RTC: 150944
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/46864
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com>
Diffstat (limited to 'src/usr/diag/attn')
-rw-r--r-- | src/usr/diag/attn/common/attnbits.C | 22 | ||||
-rw-r--r-- | src/usr/diag/attn/common/attnbits.H | 24 | ||||
-rw-r--r-- | src/usr/diag/attn/common/attnmem.C | 320 | ||||
-rw-r--r-- | src/usr/diag/attn/common/attnmem.H | 16 | ||||
-rw-r--r-- | src/usr/diag/attn/common/attnproc.C | 45 | ||||
-rw-r--r-- | src/usr/diag/attn/common/attnproc.H | 4 | ||||
-rw-r--r-- | src/usr/diag/attn/common/attnsvc_common.C | 27 | ||||
-rw-r--r-- | src/usr/diag/attn/ipl/attnsvc.C | 12 |
8 files changed, 341 insertions, 129 deletions
diff --git a/src/usr/diag/attn/common/attnbits.C b/src/usr/diag/attn/common/attnbits.C index b2514ad11..8e6f13440 100644 --- a/src/usr/diag/attn/common/attnbits.C +++ b/src/usr/diag/attn/common/attnbits.C @@ -185,6 +185,18 @@ bool getCheckbits( } } +namespace MC +{ +// First MC chiplet in broadcast read +const uint64_t firstChiplet = 0x0100000000000000ull; + +// Number of MC chiplets +const uint64_t numChiplets = 2; +} + + +// @TODO RTC: 180469 +// Remove MCI address space and then update all the CXX testing namespace MCI { // Not valid / used for now on P9 @@ -229,8 +241,12 @@ void forEach( forEach(first, last, i_scomData, i_data, i_func); } -} +} // end MCI space + + +// @TODO RTC: 180469 +// Remove MCI address space and then update all the CXX testing namespace GP1 { // Not valid / used for now on P9 @@ -280,5 +296,7 @@ void forEach( forEach(first, last, i_scomData, i_data, i_func); } -} +} // end GP1 space + + } diff --git a/src/usr/diag/attn/common/attnbits.H b/src/usr/diag/attn/common/attnbits.H index 5bee569e8..de37e3466 100644 --- a/src/usr/diag/attn/common/attnbits.H +++ b/src/usr/diag/attn/common/attnbits.H @@ -100,6 +100,23 @@ bool getCheckbits( uint64_t & o_bits); } +namespace MC +{ +/** + * @brief First MC chiplet bits in broadcast read + */ +extern const uint64_t firstChiplet; + +/** + * @brief Total Number of MC chiplets + */ +extern const uint64_t numChiplets; +} + + + +// @TODO RTC: 180469 +// Remove MCI address space and then update all the CXX testing namespace MCI { @@ -135,6 +152,9 @@ void forEach( void (*i_func)(uint64_t, void *)); } + +// @TODO RTC: 180469 +// Remove GP1 address space and then update all the CXX testing namespace GP1 { @@ -171,14 +191,12 @@ bool getCheckbits( uint64_t & o_bits); } + /** * @brief Interrupt config related constants */ enum { - // This was for MCS usage, but not needed right now - GP2_REG = 0x02000002, - // PIB interrupt register (spec/recov/chkstop) PIB_INTR_TYPE_REG = 0x000F001A, diff --git a/src/usr/diag/attn/common/attnmem.C b/src/usr/diag/attn/common/attnmem.C index 8eb89088a..18ce8e53b 100644 --- a/src/usr/diag/attn/common/attnmem.C +++ b/src/usr/diag/attn/common/attnmem.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014,2016 */ +/* Contributors Listed Below - COPYRIGHT 2014,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -34,6 +34,7 @@ #include "common/attnlist.H" #include "common/attntarget.H" #include "attntrace.H" +#include <targeting/common/utilFilter.H> using namespace std; using namespace PRDF; @@ -43,107 +44,286 @@ using namespace ERRORLOG; namespace ATTN { -struct ResolveMcsArgs +typedef struct { - TargetHandle_t proc; - AttentionList * list; - MemOps * ops; -}; + uint32_t chipletFir; + uint32_t chipletFirMask; + ATTENTION_VALUE_TYPE attnType; + + // First of four bits to check + // (2 bits apart) + uint64_t intrBitToChk; +} attnMemoryFirs_t; -void resolveMcs(uint64_t i_mcs, void * i_data) + +const attnMemoryFirs_t ATTN_MEM_CHIPLET_FIRS[] = { - ResolveMcsArgs * args = static_cast<ResolveMcsArgs *>(i_data); + { 0x07040009, 0x0704001A, + HOST_ATTN, 0x4000000000000000ull }, // Host 1,3,5,7 + { 0x07040018, 0x07040019, + UNIT_CS, 0x4000000000000000ull }, // unit CS 1,3,5,7 + { 0x07040001, 0x07040002, + RECOVERABLE, 0x0800000000000000ull }, // Recov 4,6,8,10 + { 0x07040000, 0x07040002, + CHECK_STOP, 0x0800000000000000ull } // chkstop 4,6,8,10 +}; - uint64_t mciFirScomData; +// 4 DMI units per MC +const uint32_t ATTN_MAX_DMI_INTRS = 4; - TargetHandle_t mcs = getTargetService().getMcs(args->proc, i_mcs); +// Processor FIR set when MemBuffer raises attention +const uint32_t ATTN_ADDR_CHIFIR_DATA = 0x07010900; +const uint32_t ATTN_ADDR_CHIFIR_MASK = 0x07010903; - // read the MCI fir to determine what type of attention - // centaur reporting +// Attention bit positions in CHIFIR 16, 19,20,21 +const uint64_t ATTN_CEN_CHECKSTOP = 0x0000800000000000ull ; +const uint64_t ATTN_CEN_RECOV = 0x0000100000000000ull ; +const uint64_t ATTN_CEN_SPECIAL = 0x0000080000000000ull ; +const uint64_t ATTN_CEN_MAINT_CMD = 0x0000040000000000ull ; - errlHndl_t err = getScom(mcs, MCI::address, mciFirScomData); - if(err) - { - errlCommit(err, ATTN_COMP_ID); - } - else + +// @TODO RTC: 180469 +// Move to target services part and then update all the CXX testing +TargetHandle_t attnGetMembuf( const TargetHandle_t &i_mc, + const uint32_t i_dmi, + const ATTENTION_VALUE_TYPE i_attnType ) +{ + // where i_dmi is 0:7 value + TargetHandle_t membuf = NULL; + TargetHandleList l_dmiList; + errlHndl_t l_err = NULL; + uint64_t l_chifirData = 0; + uint64_t l_chifirMask = 0; + uint64_t l_chifirIntr = 0; + + + // Get the list of DMI units for MC unit passed in + getChildChiplets(l_dmiList, i_mc, TYPE_DMI); + + for ( auto l_dmiTarg : l_dmiList ) { - // pick the highest priority attention + ATTN_TRACE(" MemRes(%d) - DMI:%d chiplet from MC", + i_dmi, l_dmiTarg->getAttr<ATTR_CHIP_UNIT>() ); - for(uint64_t type = INVALID_ATTENTION_TYPE; - type != END_ATTENTION_TYPE; - ++type) + if ( i_dmi == l_dmiTarg->getAttr<ATTR_CHIP_UNIT>() ) { - uint64_t mask; + ATTN_SLOW(" MemOps::resolve - DMI Match:%d", + i_dmi ); - if(!MCI::getCheckbits(type, mask)) - { - // this object doesn't support - // this attention type + // Get mem buffer associated with the DMI chiplet + TargetHandleList l_memBufList; + getChildAffinityTargets( l_memBufList, l_dmiTarg, + CLASS_CHIP, TYPE_MEMBUF ); - continue; - } - - if(mask & mciFirScomData) + if (l_memBufList.size() == 1) { - AttnData d; - d.targetHndl = getTargetService().getMembuf(mcs); + // Validate Centaur actually raised attention + l_err = getScom( l_dmiTarg, + ATTN_ADDR_CHIFIR_DATA, + l_chifirData ); - if(!d.targetHndl) + if (NULL == l_err) { - // this membuf not functional - // or nothing is attached to this MCS + l_err = getScom( l_dmiTarg, + ATTN_ADDR_CHIFIR_MASK, + l_chifirMask ); + } // end if no error on getscom CHIFIR - break; - } + if (NULL == l_err) + { + // Check for active attention + l_chifirIntr = l_chifirData & ~l_chifirMask; + + ATTN_SLOW(" MemOps::res - CenAttn:%016llx ::%X", + l_chifirIntr, i_attnType ); + + // Is it attn we are looking for ? + if ( ( (i_attnType == HOST_ATTN) && + ((l_chifirIntr & ATTN_CEN_SPECIAL) || + (l_chifirIntr & ATTN_CEN_MAINT_CMD) + ) + ) || + + ( (i_attnType == RECOVERABLE) && + (l_chifirIntr & ATTN_CEN_RECOV) + ) || + ( (i_attnType == CHECK_STOP) && + (l_chifirIntr & ATTN_CEN_CHECKSTOP) + ) || + + ( (i_attnType == UNIT_CS) && + (l_chifirIntr & ATTN_CEN_CHECKSTOP) + ) + ) + { + membuf = l_memBufList[0]; + // Found right DMI and memory buffer + // so stop loooping + break; + } // end if matching attention in membuf + + } // end if no error on getscom CHIFIR Mask + + + // Handle any elog + if (NULL != l_err) + { + errlCommit(l_err, ATTN_COMP_ID); + } // if elog - d.attnType = static_cast<ATTENTION_VALUE_TYPE>(type); + } // end one membuf found - args->list->add(Attention(d, args->ops)); - break; - } - } - } -} + } // end if correct DMI target + + } // end for on DMI targets -errlHndl_t MemOps::resolve( - TargetHandle_t i_proc, - AttentionList & o_attentions) -{ - errlHndl_t err = 0; - //@TODO: RTC:150944 - // Don't need this for now as this is Centaur Chip related - ATTN_TRACE("MemOps::resolve - P9 Noop"); + return(membuf); -#if 0 - uint64_t gp1ScomData = 0; +} // end attnGetMembuf + + +bool MemOps::resolve( + PRDF::AttnData & i_AttnData, + const uint32_t i_mcNumber ) +{ + errlHndl_t l_err = 0; + bool l_attnFound = false; + uint64_t l_firData = 0; + uint64_t l_maskData = 0; + uint64_t l_intData = 0; + uint32_t l_mcNum = 0; + uint32_t l_dmi_0to7 = 0; - do { - // get the nest gp1 register content and decode - // (get a list of membufs reporting attentions) + TargetHandleList l_mcTargetList; + getAllChiplets(l_mcTargetList, TYPE_MC, true ); - err = getScom(i_proc, GP1::address, gp1ScomData); + // Find correct MC chiplet + for ( auto l_mc : l_mcTargetList ) + { + ATTN_TRACE("MemOps::resolve - MC chiplet:%d", i_mcNumber); + l_mcNum = l_mc->getAttr<ATTR_CHIP_UNIT>(); - if(err) + if (l_mcNum == i_mcNumber) { - break; - } + // Check for attention using chiplet summary registers + uint32_t l_numFirs = sizeof(ATTN_MEM_CHIPLET_FIRS) / + sizeof(attnMemoryFirs_t); - ResolveMcsArgs args; + for ( uint32_t l_cFir=0; (l_cFir < l_numFirs); l_cFir++ ) + { + // Verify the attention type + if (i_AttnData.attnType == + ATTN_MEM_CHIPLET_FIRS[l_cFir].attnType) + { + // get chiplet FIR data + l_err = getScom(l_mc, + ATTN_MEM_CHIPLET_FIRS[l_cFir].chipletFir, + l_firData); + + if (NULL == l_err) + { + // Get chiplet MASK + l_err = getScom(l_mc, + ATTN_MEM_CHIPLET_FIRS[l_cFir].chipletFirMask, + l_maskData); + + ATTN_SLOW( + "...MemRes:cAddr:%016llx cFir:%016llx cMask:%016llx", + ATTN_MEM_CHIPLET_FIRS[l_cFir].chipletFir, + l_firData, l_maskData ); + + if (NULL == l_err) + { + // Recoverable FIR & MASK are 2 bits off + // so need to handle this here + if (RECOVERABLE == i_AttnData.attnType) + { + l_firData = l_firData >> 2; + } // end if recoverable + + // Check for active attention + l_intData = l_firData & ~l_maskData; + + ATTN_TRACE("...resolve - IntrActive::%016llx ", + l_intData ); + + // Interrupts are in various bit positions, + // so will shift a mask 2 bit positions for each DMI + for ( uint32_t l_intNum=0; + (l_intNum < ATTN_MAX_DMI_INTRS); l_intNum++) + { + // Check for active DMI interrupt + if ( l_intData & + (ATTN_MEM_CHIPLET_FIRS[l_cFir].intrBitToChk + >> (l_intNum*2)) ) + { + // Heirarchy: MC -> MI -> DMI -> Centaur + // Valid active interrupt on DMI Bus + // Need membuf targ for passing to PRD + + // Determine DMI chiplet - 0 thru 7 value + l_dmi_0to7 = (l_mcNum * ATTN_MAX_DMI_INTRS) + + l_intNum; + + AttnData d; + // add membuf target if found + d.targetHndl = attnGetMembuf(l_mc, + l_dmi_0to7, + i_AttnData.attnType); + + if (NULL != d.targetHndl) + { + ATTN_TRACE( + " MemOpsRes -Got membuf Attn:%d", + ATTN_MEM_CHIPLET_FIRS[l_cFir].attnType); + + i_AttnData.targetHndl = d.targetHndl; + l_attnFound = true; + // handle the one attention + break; + } // end if valid memory buffer target + + } // end if active DMI Interrupt + + } // end for loop thru all potential DMI interrupts + + } // if ok reading mask data + else + { + ATTN_ERR("Mem:Resolve FirMask Fail Addr:%08X", + ATTN_MEM_CHIPLET_FIRS[l_cFir].chipletFirMask); + } // end else failed reading mask + + } // if ok reading FIR data + else + { + ATTN_ERR("Mem:Resolve Fir Fail Addr:%08X", + ATTN_MEM_CHIPLET_FIRS[l_cFir].chipletFir); + } // end else failed reading FIR + + // Handle any elog + if (NULL != l_err) + { + errlCommit(l_err, ATTN_COMP_ID); + } // if elog + + // Found attn match so get out + break; + } // end if attention matches + + } // end for thru chiplet FIRs - args.proc = i_proc; - args.list = &o_attentions; - args.ops = this; + // We handle attns one at a time + break; + } // end if found MC chiplet - GP1::forEach(gp1ScomData, &args, &resolveMcs); + } // end for on MC chiplets - } while(0); -#endif - return err; + return l_attnFound; } MemOps::MemOps() diff --git a/src/usr/diag/attn/common/attnmem.H b/src/usr/diag/attn/common/attnmem.H index 80799cee6..faf26e66a 100644 --- a/src/usr/diag/attn/common/attnmem.H +++ b/src/usr/diag/attn/common/attnmem.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014 */ +/* Contributors Listed Below - COPYRIGHT 2014,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -47,15 +47,15 @@ class MemOps : public AttentionOps /** * @brief resolve Find membuf attentions behind the supplied proc. * - * @param[in] i_proc The proc on which to look for attentions. - * @param[out] o_attentions Where to put attentions when found. + * @param[in] i_AttnData Where to put membuf target and attn type + * @param[out] i_mcNumber MC unit to examine (0 or 1) * - * @retval[0] No error. - * @retval[!0] Unexpected error occurred. + * @retval true if i_AttnData was set to valid values + * @retval false if i_AttnData is invalid (no memory attns) */ - errlHndl_t resolve( - TARGETING::TargetHandle_t i_proc, - AttentionList & o_attentions); + bool resolve( + PRDF::AttnData & i_AttnData, + const uint32_t i_mcNumber ); /** * @brief dtor diff --git a/src/usr/diag/attn/common/attnproc.C b/src/usr/diag/attn/common/attnproc.C index 9697b5897..cdd124c0b 100644 --- a/src/usr/diag/attn/common/attnproc.C +++ b/src/usr/diag/attn/common/attnproc.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014,2016 */ +/* Contributors Listed Below - COPYRIGHT 2014,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -32,6 +32,8 @@ #include "common/attnproc.H" #include "common/attnlist.H" #include "common/attntrace.H" +#include "common/attntarget.H" +#include "common/attnmem.H" using namespace std; using namespace PRDF; @@ -41,11 +43,13 @@ using namespace ERRORLOG; namespace ATTN { -errlHndl_t ProcOps::query(const AttnData & i_attnToCheck, bool & o_active) +errlHndl_t ProcOps::query(AttnData & i_attnToCheck, bool & o_active) { errlHndl_t err = 0; - uint64_t address = 0, checkbits = 0, scomData = 0; + AttnData l_cenAttnData; + bool l_cenAttnFound = false; + MemOps & memOps = getMemOps(); GFIR::getAddress(i_attnToCheck.attnType, address); @@ -56,12 +60,41 @@ errlHndl_t ProcOps::query(const AttnData & i_attnToCheck, bool & o_active) ATTN_TRACE("procOpsQuery:Addr:%016llx ChkBits:%016llx Data:%016llx", address, checkbits, scomData); - if(!err) + if (!err) { - if(scomData & checkbits) + if (scomData & checkbits) { o_active = true; - } + + // NIMBUS has no memory buffers to look at + TARGETING::Target *l_MasterProcTarget = NULL; + getTargetService().masterProcChipTargetHandle( + l_MasterProcTarget); + + ATTR_MODEL_type l_model = l_MasterProcTarget->getAttr<ATTR_MODEL>(); + if ( MODEL_CUMULUS == l_model ) + { + // Attempt resolving to Centaur + // If we do, the attention target/type gets set. + // Else we will leave as proc attention + for ( uint32_t l_mc=0; + ((l_mc < MC::numChiplets) && (false == l_cenAttnFound)); + l_mc++) + { + if ( scomData & ((MC::firstChiplet) >> l_mc) ) + { + // Will handle the first attention + l_cenAttnFound = memOps.resolve( i_attnToCheck, l_mc); + // i_attnToCheck gets altered to membuf + // if we found valid attention there + + } // end if this MC chiplet is active + + } // end for on MC chiplets + + } // end if CUMULUS + + } // end if active attention else { o_active = false; diff --git a/src/usr/diag/attn/common/attnproc.H b/src/usr/diag/attn/common/attnproc.H index c5ad171a3..ac77337a1 100644 --- a/src/usr/diag/attn/common/attnproc.H +++ b/src/usr/diag/attn/common/attnproc.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2014 */ +/* Contributors Listed Below - COPYRIGHT 2014,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -79,7 +79,7 @@ class ProcOps : public AttentionOps * @retval[0] No error. * @retval[!0] Unexpected error occurred. */ - errlHndl_t query(const PRDF::AttnData & i_data, bool & o_active); + errlHndl_t query(PRDF::AttnData & i_data, bool & o_active); /** * @brief resolveIpoll Find attentions of the supplied type on the diff --git a/src/usr/diag/attn/common/attnsvc_common.C b/src/usr/diag/attn/common/attnsvc_common.C index be3ab3f96..b9d5ef2fa 100644 --- a/src/usr/diag/attn/common/attnsvc_common.C +++ b/src/usr/diag/attn/common/attnsvc_common.C @@ -107,11 +107,6 @@ errlHndl_t ServiceCommon::configureInterrupts( while(it != procs.end()) { - // enable/disable MCSes - //@TODO: RTC:150944 Do we need to enable/disable MCS ? Doubt it - // Seems to be related strictly to that GPIO P8 workaround - - #ifndef __HOSTBOOT_RUNTIME uint64_t mask = 0; // enable attentions in ipoll mask @@ -181,7 +176,6 @@ void ServiceCommon::processAttentions(const TargetHandleList & i_procs) // this should be the opposite of what we used for masking in preAck uint64_t restoreMask = ~(HostMask::host() | HostMask::nonHost()); - MemOps & memOps = getMemOps(); ProcOps & procOps = getProcOps(); do { @@ -202,15 +196,6 @@ void ServiceCommon::processAttentions(const TargetHandleList & i_procs) { errlCommit(err, ATTN_COMP_ID); } - - // enumerate host attentions and convert - // to centaur targets (NOOP for now on P9) - err = memOps.resolve(*pit, attentions); - - if(err) - { - errlCommit(err, ATTN_COMP_ID); - } } err = getPrdWrapper().callPrd(attentions); @@ -276,7 +261,6 @@ errlHndl_t ServiceCommon::handleAttentions(const TargetHandle_t i_proc) errlHndl_t err = NULL; AttentionList attentions; - MemOps & memOps = getMemOps(); ProcOps & procOps = getProcOps(); do { @@ -293,17 +277,6 @@ errlHndl_t ServiceCommon::handleAttentions(const TargetHandle_t i_proc) break; } - // query the mem resolver for active attentions - - err = memOps.resolve(i_proc, attentions); - - if(err) - { - ATTN_ERR("memOps.resolve() returned error.HUID:0X%08X ", - get_huid( i_proc )); - break; - } - ATTN_TRACE("handleAttns %d active( PRD)", attentions.size() ); if(!attentions.empty()) { diff --git a/src/usr/diag/attn/ipl/attnsvc.C b/src/usr/diag/attn/ipl/attnsvc.C index 37ec9a9f4..156153a04 100644 --- a/src/usr/diag/attn/ipl/attnsvc.C +++ b/src/usr/diag/attn/ipl/attnsvc.C @@ -249,7 +249,7 @@ errlHndl_t Service::processCheckstop() while(tit != list.end()) { // query the proc resolver for active attentions - + // (we also handle mem bufs in this routine) err = procOps.resolve( *tit, 0, attentions); if(err) @@ -259,16 +259,6 @@ errlHndl_t Service::processCheckstop() break; } - // query the mem resolver for active attentions - - err = memOps.resolve(*tit, attentions); - - if(err) - { - ATTN_ERR("memOps.resolve() returned error.HUID:0X%08X ", - get_huid( *tit )); - break; - } ++tit; } |