void resolveMcs(uint64_t i_mcs, void * i_data) { ResolveMcsArgs * args = static_cast<ResolveMcsArgs *>(i_data); uint64_t mciFirScomData; TargetHandle_t mcs = getTargetService().getMcs(args->proc, i_mcs); // read the MCI fir to determine what type of attention // centaur reporting errlHndl_t err = getScom(mcs, MCI::address, mciFirScomData); if(err) { errlCommit(err, ATTN_COMP_ID); } else { // pick the highest priority attention for(uint64_t type = INVALID_ATTENTION_TYPE; type != END_ATTENTION_TYPE; ++type) { uint64_t mask; if(!MCI::getCheckbits(type, mask)) { // this object doesn't support // this attention type continue; } if(mask & mciFirScomData) { AttnData d; d.targetHndl = getTargetService().getMembuf(mcs); if(!d.targetHndl) { // this membuf not functional // or nothing is attached to this MCS break; } d.attnType = static_cast<ATTENTION_VALUE_TYPE>(type); args->list->add(Attention(d, args->ops)); break; } } } }
errlHndl_t MemInjectSink::putAttention(const AttnData & i_attn) { return putScom( getTargetService().getMcs(i_attn.targetHndl), MCI::address, ~0); }
void* Service::prdTask(void * i_svc) { // prd task loop Service & svc = *static_cast<Service *>(i_svc); bool shutdown = false; TargetHandleList procs; getTargetService().getAllChips(procs, TYPE_PROC); // wait for a wakeup while(true) { shutdown = svc.prdTaskWait(); if(shutdown) { // this was a shutdown wakeup. // tell the prd task loop to exit break; } // new attentions for prd to handle svc.processAttentions(procs); } return NULL; }
errlHndl_t checkForIplAttentions() { errlHndl_t err = NULL; assert(!Singleton<Service>::instance().running()); TargetHandleList list; getTargetService().getAllChips(list, TYPE_PROC); TargetHandleList::iterator tit = list.begin(); while(tit != list.end()) { err = Singleton<Service>::instance().handleAttentions(*tit); if(err) { errlCommit(err, ATTN_COMP_ID); } tit = list.erase(tit); } return 0; }
TargetServiceImpl::~TargetServiceImpl() { // restore the default getTargetService().setImpl(Singleton<TargetServiceImpl>::instance()); TargetService & wrapper = getTargetService(); TargetServiceImpl * defaultImpl = &Singleton<TargetServiceImpl>::instance(); if(wrapper.iv_impl == this) { if(this != defaultImpl) { wrapper.setImpl(*defaultImpl); } } }
void initGSSAPIContext( const char * inServiceName, gss_ctx_id_t * outContext, gss_buffer_desc * outToken, PAPIStatus * outStatus ) { gss_name_t theServiceName; getTargetService( inServiceName, &theServiceName, outStatus ); if ( *outStatus == PAPISuccess ) { OM_uint32 theMajorStatus; OM_uint32 theMinorStatus; gss_buffer_desc theServiceNameBuf; OM_uint32 theReqFlags = GSS_C_DELEG_FLAG; OM_uint32 theRetFlags; gss_OID theMech; #ifdef SOLARIS gss_OID_desc theMechArr = { 9, "\052\206\110\206\367\022\001\002\002"}; theMech = &theMechArr; #else theMech = GSS_KRB5_MECHANISM; #endif outToken->length = 0; theMajorStatus = gss_init_sec_context( &theMinorStatus, GSS_C_NO_CREDENTIAL, outContext, theServiceName, GSS_C_NO_OID, 0, 0, NULL, GSS_C_NO_BUFFER, 0, outToken, &theRetFlags, 0 ); if ( theMajorStatus == GSS_S_COMPLETE ) { *outStatus = PAPISuccess; } else { *outStatus = PAPIAuthenticationFailure; } } }
errlHndl_t FakeGp1::processPutReg( FakeSystem & i_sys, TargetHandle_t i_target, uint64_t i_address, uint64_t i_new, uint64_t i_old) { errlHndl_t err = 0; uint64_t mcsPos; TargetHandle_t membuf = getTargetService().getMembuf(i_target); TargetHandle_t proc = getTargetService().getProc(membuf); getTargetService().getMcsPos(i_target, mcsPos); uint64_t gp1Content = i_sys.getReg(proc, GP1::address); bool set = false, cleared = false, on = false; // these mci bits turned on MCI::forEach(i_new & ~i_old, &set, &setFlag); // these mci bits turned off MCI::forEach(~i_new & i_old, &cleared, &setFlag); // these mci bits are on MCI::forEach(i_new, &on, &setFlag); // whether or not the mcs is reporting FindMcsArgs args; args.reporting = false; args.pos = mcsPos; GP1::forEach(gp1Content, &args, &findMcs); uint64_t writebits; GP1::getCheckbits(mcsPos, writebits); if(args.reporting && cleared && !on) { // this mcs is reporting, but all the bits in the MCI FIR // have turned off. err = i_sys.modifyReg( proc, GP1::address, ~writebits, SCOM_AND); } else if(!args.reporting && set) { // this mcs wasn't reporting before, but now a bit is on err = i_sys.modifyReg( proc, GP1::address, writebits, SCOM_OR); } return err; }
void Service::processIntrQMsgPreAck(const msg_t & i_msg) { // this function should do as little as possible // since the hw can't generate additional interrupts // until the msg is acknowledged TargetHandle_t proc = NULL; INTR::XISR_t xisr; xisr.u32 = i_msg.data[0]; TargetHandleList procs; getTargetService().getAllChips(procs, TYPE_PROC); TargetHandleList::iterator it = procs.begin(); // resolve the xisr to a proc target while(it != procs.end()) { uint64_t node = 0, chip = 0; getTargetService().getAttribute(ATTR_FABRIC_NODE_ID, *it, node); getTargetService().getAttribute(ATTR_FABRIC_CHIP_ID, *it, chip); if(node == xisr.node && chip == xisr.chip) { proc = *it; break; } ++it; } uint64_t hostMask = HostMask::host(); uint64_t nonHostMask = HostMask::nonHost(); uint64_t data = 0; // do the minimum that is required // for sending EOI without getting // another interrupt. for host attentions // this is clearing the gpio interrupt // type status register // and for xstp,rec,spcl this is // masking the appropriate bit in // ipoll mask // read the ipoll status register // to determine the interrupt was // caused by host attn or something // else (xstp,rec,spcl) errlHndl_t err = getScom(proc, IPOLL_STATUS_REG, data); if(err) { errlCommit(err, ATTN_COMP_ID); // assume everything is on data = hostMask | nonHostMask; } if(data & hostMask) { // if host attention, clear the ITR macro gpio interrupt // type status register. err = putScom(proc, INTR_TYPE_LCL_ERR_STATUS_AND_REG, 0); if(err) { errlCommit(err, ATTN_COMP_ID); } } if(data & nonHostMask) { // mask local proc xstp,rec and/or special attns if on. // the other thread might be trying to unmask // on the same target. The mutex ensures // neither thread corrupts the register. mutex_lock(&iv_mutex); err = modifyScom(proc, IPOLL::address, data & nonHostMask, SCOM_OR); mutex_unlock(&iv_mutex); if(err) { errlCommit(err, ATTN_COMP_ID); } } }
errlHndl_t Service::configureInterrupts( msg_q_t i_q, ConfigureMode i_mode) { errlHndl_t err = NULL; // First register for Q // This will set up the psi host bridge logic for // lcl_err interrupt on all chips if(i_mode == UP) { err = INTR::registerMsgQ(i_q, ATTENTION, INTR::ISN_LCL_ERR); } // setup the ITR macro for GPIO type host attentions, // on all procs if(!err) { TargetHandleList procs; getTargetService().getAllChips(procs, TYPE_PROC); TargetHandleList::iterator it = procs.begin(); while(it != procs.end()) { uint64_t mask = 0; // clear GPIO interrupt type status register if(i_mode == UP) { err = putScom(*it, INTR_TYPE_LCL_ERR_STATUS_AND_REG, 0); } if(err) { break; } // unmask GPIO interrupt type mask = 0x8000000000000000ull; err = putScom( *it, (i_mode == UP ? INTR_TYPE_MASK_AND_REG : INTR_TYPE_MASK_OR_REG), i_mode == UP ? ~mask : mask); if(err) { break; } // set GPIO interrupt type mode - or if(i_mode == UP) { err = putScom(*it, INTR_TYPE_CONFIG_AND_REG, ~mask); } if(err) { break; } // enable/disable MCSes mask = 0; GP1::forEach(~0, &mask, &getPbGp2Mask); err = modifyScom( *it, GP2_REG, i_mode == UP ? mask : ~mask, i_mode == UP ? SCOM_OR : SCOM_AND); if(err) { break; } // enable attentions in ipoll mask mask = HostMask::nonHost(); mask |= HostMask::host(); // this doesn't have an and/or reg for some reason... err = modifyScom( *it, IPOLL::address, i_mode == UP ? ~mask : mask, i_mode == UP ? SCOM_AND : SCOM_OR); if(err) { break; } ++it; } if(!err && i_mode == DOWN) { if(NULL == INTR::unRegisterMsgQ(INTR::ISN_LCL_ERR)) { ATTN_ERR("INTR did not find isn: 0x%07x", INTR::ISN_LCL_ERR); } } } return err; }
errlHndl_t ServiceCommon::configureInterrupts( ConfigureMode i_mode) { errlHndl_t err = NULL; TargetHandleList procs; getTargetService().getAllChips(procs, TYPE_PROC); TargetHandleList::iterator it = procs.begin(); while(it != procs.end()) { uint64_t mask = 0; // clear GPIO interrupt type status register if(i_mode == UP) { err = putScom(*it, INTR_TYPE_LCL_ERR_STATUS_AND_REG, 0); } if(err) { break; } // unmask GPIO interrupt type mask = 0x8000000000000000ull; err = putScom(*it, (i_mode == UP ? INTR_TYPE_MASK_AND_REG : INTR_TYPE_MASK_OR_REG), i_mode == UP ? ~mask : mask); if(err) { break; } // set GPIO interrupt type mode - or if(i_mode == UP) { err = putScom(*it, INTR_TYPE_CONFIG_AND_REG, ~mask); } if(err) { break; } // enable/disable MCSes mask = 0; GP1::forEach(~0, &mask, &getPbGp2Mask); err = modifyScom(*it, GP2_REG, i_mode == UP ? mask : ~mask, i_mode == UP ? SCOM_OR : SCOM_AND); if(err) { break; } // enable attentions in ipoll mask mask = HostMask::nonHost(); mask |= HostMask::host(); // this doesn't have an and/or reg for some reason... err = modifyScom(*it, IPOLL::address, i_mode == UP ? ~mask : mask, i_mode == UP ? SCOM_AND : SCOM_OR); if(err) { break; } ++it; } return err; }