/** Enable chip attentions * * @return 0 on success else return code */ int enableAttns(void) { // TODO RTC 134050 Post init setups are temporarily here because // Opal has not set up pnor or ipmi before calling rt_main. static bool onlyCallApplyTempOverridesOnce = false; if (!onlyCallApplyTempOverridesOnce) { ATTN_SLOW("ATTN_RT::enableAttns - call initialzation routines"); postInitCalls_t* rtPost = getPostInitCalls(); rtPost->callApplyTempOverrides(); onlyCallApplyTempOverridesOnce = true; } ATTN_SLOW(ENTER_MRK"ATTN_RT::enableAttns"); int rc = 0; errlHndl_t err = NULL; err = Singleton<Service>::instance().enableAttns(); if(err) { errlCommit(err, ATTN_COMP_ID); rc = -1; } ATTN_SLOW(EXIT_MRK"ATTN_RT::enableAttns rc: %d", rc); return rc; }
errlHndl_t Service::disableAttns() { ATTN_SLOW("Service::disableAttns() enter"); // During runtime do nothing. ATTN_SLOW("Service::disableAttns() exit"); return NULL; }
errlHndl_t Service::enableAttns() { ATTN_SLOW("Service::enableAttns() enter"); errlHndl_t err = configureInterrupts(UP); ATTN_SLOW("Service::enableAttns() exit"); return err; }
Service::~Service() { ATTN_SLOW("Service::~Service() enter"); errlHndl_t err = disableAttns(); if(err) { errlCommit(err, ATTN_COMP_ID); } ATTN_SLOW("Service::~Service() exit"); }
errlHndl_t Service::stop() { ATTN_SLOW("shutting down..."); mutex_lock(&iv_mutex); tid_t intrTask = iv_intrTask; tid_t prdTask = iv_prdTask; msg_q_t q = iv_intrTaskQ; iv_intrTask = 0; iv_prdTask = 0; mutex_unlock(&iv_mutex); if(intrTask) { errlHndl_t err = configureInterrupts(q, DOWN); if(err) { errlCommit(err, ATTN_COMP_ID); } msg_t * shutdownMsg = msg_allocate(); shutdownMsg->type = SHUTDOWN; msg_sendrecv(q, shutdownMsg); msg_free(shutdownMsg); task_wait_tid(intrTask, 0, 0); msg_q_destroy(q); } if(prdTask) { sync_cond_signal(&iv_cond); task_wait_tid(prdTask, 0, 0); } ATTN_SLOW("..shutdown complete"); return 0; }
/** Disable chip attentions * * @return 0 on success else return code */ int disableAttns(void) { ATTN_SLOW(ENTER_MRK"ATTN_RT::disableAttns"); int rc = 0; errlHndl_t err = NULL; err = Singleton<Service>::instance().disableAttns(); if(err) { errlCommit(err, ATTN_COMP_ID); rc = -1; } ATTN_SLOW(EXIT_MRK"ATTN_RT::disableAttns rc: %d", rc); return rc; }
errlHndl_t Service::start() { errlHndl_t err = NULL; bool cleanStartup = false; ATTN_SLOW("starting..."); mutex_lock(&iv_mutex); do { if(!iv_intrTaskQ) { // register msg q with interrupt // service for attention type interrupts msg_q_t q = msg_q_create(); err = configureInterrupts(q, UP); if(err) { msg_q_destroy(q); break; } iv_intrTaskQ = q; } if(!startIntrTask()) { break; } if(!startPrdTask()) { break; } cleanStartup = true; } while(0); tid_t prd = iv_prdTask, intr = iv_intrTask; mutex_unlock(&iv_mutex); if(!cleanStartup) { errlHndl_t err2 = stop(); if(err2) { errlCommit(err2, ATTN_COMP_ID); } } else { ATTN_SLOW("..startup complete, intr: %d, prd: %d", intr, prd); } return err; }
/** 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; }