errlHndl_t ServiceCommon::handleAttentions(const TargetHandle_t i_proc) { errlHndl_t err = NULL; AttentionList attentions; MemOps & memOps = getMemOps(); ProcOps & procOps = getProcOps(); do { attentions.clear(); // query the proc resolver for active attentions err = procOps.resolve(i_proc, 0, attentions); if(err) { break; } // query the mem resolver for active attentions err = memOps.resolve(i_proc, attentions); if(err) { break; } if(!attentions.empty()) { err = getPrdWrapper().callPrd(attentions); } if(err) { break; } #ifdef __HOSTBOOT_RUNTIME // During runtime, we will only handle one attention at a time //and give control back to OPAL. break; #endif //__HOSTBOOT_RUNTIME } while(!attentions.empty()); return err; }
void Service::processAttentions(const TargetHandleList & i_procs) { errlHndl_t err = NULL; AttentionList attentions; MemOps & memOps = getMemOps(); ProcOps & procOps = getProcOps(); do { attentions.clear(); // enumerate the highest priority pending attention // on every chip and then give the entire set to PRD TargetHandleList::const_iterator pit = i_procs.end(); while(pit-- != i_procs.begin()) { // enumerate proc local attentions (xstp,spcl,rec). err = procOps.resolveIpoll(*pit, attentions); if(err) { errlCommit(err, ATTN_COMP_ID); } // enumerate host attentions and convert // to centaur targets err = memOps.resolve(*pit, attentions); if(err) { errlCommit(err, ATTN_COMP_ID); } } err = getPrdWrapper().callPrd(attentions); if(err) { errlCommit(err, ATTN_COMP_ID); } // unmask proc local attentions // (xstp,rec,special) in ipoll mask // any pending attentions will be found // on the next pass pit = i_procs.end(); while(pit-- != i_procs.begin()) { mutex_lock(&iv_mutex); // the other thread might be trying to mask // on the same target. The mutex ensures // neither thread corrupts the register. err = modifyScom( *pit, IPOLL::address, ~HostMask::nonHost(), SCOM_AND); mutex_unlock(&iv_mutex); if(err) { errlCommit(err, ATTN_COMP_ID); } } // if on a given Centaur with a pending attention // on an MBA, an attention comes on in the other MBA // we don't get an interrupt for that. So make another // pass and check for that. } while(!attentions.empty()); }
/** brief handle chip attentions * * @param[in] i_proc - processor chip id at attention * XSCOM chip id based on devtree defn * @param[in] i_ipollStatus - processor chip Ipoll status * @param[in] i_ipollMask - processor chip Ipoll mask * @return 0 on success else return code */ int handleAttns(uint64_t i_proc, uint64_t i_ipollStatus, uint64_t i_ipollMask) { ATTN_SLOW(ENTER_MRK"ATTN_RT::handleAttns RtProc: %llx" ", ipollMask: %llx, ipollStatus: %llx", i_proc, i_ipollMask, i_ipollStatus); int rc = 0; errlHndl_t err = NULL; AttentionList attentions; MemOps & memOps = getMemOps(); uint64_t l_iprScomData = 0; do { // Convert chipIds to HB targets TargetHandle_t proc = NULL; err = RT_TARG::getHbTarget(i_proc, proc); if(err) { ATTN_ERR("ATTN_RT::handleAttns getHbTarget " "returned error for RtProc: %llx", i_proc); rc = EINVAL; break; } err = Singleton<Service>::instance().handleAttentions(proc); if(err) { ATTN_ERR("ATTN_RT::handleAttns service::handleAttentions " "returned error for RtProc: %llx", i_proc); break; } // For host attentions, clear gpio interrupt type register. // If we do not clear gpio register, ipoll status will again // get set and we will end up in infinite loop. uint64_t hostMask = 0; IPOLL::getCheckbits(HOST, hostMask); if( i_ipollMask & hostMask) { // After handling attn, check GP1 for more attns // as there could be additional memory units with attns. attentions.clear(); err = memOps.resolve(proc, attentions); if(err) { ATTN_ERR("RT GP1 Chk:memOps returned error.HUID:0X%08X ", get_huid( proc )); break; } // Save the IPR if any attns still active on Centaurs if (!attentions.empty()) { err = getScom(proc, INTR_TYPE_LCL_ERR_STATUS_REG, l_iprScomData); if(err) { ATTN_ERR("RT SaveIPR returned error.HUID:0X%08X ", get_huid( proc )); break; } } // end if any attentions // Clear the IPR (interrupt presentation register) err = putScom(proc, INTR_TYPE_LCL_ERR_STATUS_AND_REG, 0); if(err) { ATTN_ERR("ATTN_RT::handleAttns putscom failed for " "RtProc: %llx address:0x%08X", i_proc, INTR_TYPE_LCL_ERR_STATUS_AND_REG); break; } // Restore the IPR if any attns still active in Centaurs if (!attentions.empty()) { err = putScom(proc, INTR_TYPE_LCL_ERR_STATUS_OR_REG, l_iprScomData); if(err) { ATTN_ERR("RT RestoreIPR returned error.HUID:0X%08X ", get_huid( proc )); break; } } // end if any attentions } // end if i_ipollMask & hostMask) } while(0); if(err) { errlCommit( err, ATTN_COMP_ID ); if(0 == rc) { rc = -1; } } attentions.clear(); ATTN_SLOW(EXIT_MRK"ATTN_RT::handleAttns rc: %d", rc); return rc; }