/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/usr/diag/attn/common/attnproc.C $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2014,2018 */ /* [+] International Business Machines Corp. */ /* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ /* You may obtain a copy of the License at */ /* */ /* http://www.apache.org/licenses/LICENSE-2.0 */ /* */ /* Unless required by applicable law or agreed to in writing, software */ /* distributed under the License is distributed on an "AS IS" BASIS, */ /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ /* implied. See the License for the specific language governing */ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ /** * @file attnproc.C * * @brief HBATTN Processor attention operations function definitions. */ #include #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; using namespace TARGETING; using namespace ERRORLOG; namespace ATTN { 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); GFIR::getCheckbits(i_attnToCheck.attnType, checkbits); err = getScom(i_attnToCheck.targetHndl, address, scomData); ATTN_TRACE("procOpsQuery:Addr:%016llx ChkBits:%016llx Data:%016llx", address, checkbits, scomData); if (!err) { 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(); 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.targetHndl ); // 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; } } return err; } errlHndl_t ProcOps::resolveIpoll( TargetHandle_t i_proc, AttentionList & o_attentions) { errlHndl_t err = NULL; uint64_t on = 0; uint64_t observed = 0; bool active = false; AttnData d; // very unlikely, but look for any // supported bits on in the // status register, in case the other // thread hasn't masked it yet err = getScom(i_proc, IPOLL_STATUS_REG, on); if(err) { errlCommit(err, ATTN_COMP_ID); } // also look for any supported bits on in the // mask register, indicating that the other thread // saw the error and masked it. err = getScom(i_proc, IPOLL::address, observed); if(err) { errlCommit(err, ATTN_COMP_ID); } ATTN_TRACE("resolveIpoll: Status:%016llx Mask:%016llx", on, observed); for(uint64_t type = INVALID_ATTENTION_TYPE; type != END_ATTENTION_TYPE; ++type) { uint64_t supported = 0; if(!IPOLL::getCheckbits(type, supported)) { // this object doesn't support // this attention type continue; } // analysis should be done if the bit for this // attention type is either on in the status reg // or masked in the mask reg if(!(supported & (on | observed))) { ATTN_TRACE("resolveIpoll: Skipping"); continue; } d.attnType = static_cast(type); d.targetHndl = i_proc; // to be sure, query corresponding GFIR ATTN_TRACE("rslvIpoll: Qry type :%016llx", d.attnType); err = query(d, active); if(err) { errlCommit(err, ATTN_COMP_ID); } else if(active) { o_attentions.add(Attention(d, this)); break; } } return err; } errlHndl_t ProcOps::resolve( TargetHandle_t i_proc, uint64_t i_typeMask, AttentionList & o_attentions) { errlHndl_t err = 0; bool active = false; AttnData d; d.targetHndl = i_proc; uint64_t ignored; ATTN_TRACE("procOps::resolve"); for(uint64_t type = INVALID_ATTENTION_TYPE; type != END_ATTENTION_TYPE; ++type) { if(!enabled()) { break; } ATTN_TRACE("procOps::Validate attn types"); if(!GFIR::getCheckbits(type, ignored)) { // this object doesn't support // this attention type continue; } uint64_t mask = 0; IPOLL::getCheckbits(type, mask); ATTN_TRACE("procOps::Chkbits type:%016llx mask:%016llx iMask:%016llx", type, mask, i_typeMask); if(!(mask & ~i_typeMask)) { // this attention type is masked continue; } d.attnType = static_cast(type); ATTN_TRACE("procOps::Query type :%016llx", d.attnType ); err = query(d, active); if(err) { errlCommit(err, ATTN_COMP_ID); } else if(active) { o_attentions.add(Attention(d, this)); break; } } return err; } }