// ------------------------------------------------------------------ // Fake writePNOR - image is in memory // ------------------------------------------------------------------ errlHndl_t writePNOR ( uint64_t i_byteAddr, size_t i_numBytes, void * i_data, TARGETING::Target * i_target, pnorInformation & i_pnorInfo, uint64_t &io_cachedAddr, mutex_t * i_mutex ) { errlHndl_t err = NULL; // Does VPD write ever need to be supported at runtime? TRACFCOMP(g_trac_vpd, ERR_MRK "RT writePNOR: VPD write not supported at runtime."); /*@ * @errortype * @reasoncode VPD::VPD_RT_WRITE_NOT_SUPPORTED * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid VPD::VPD_RT_WRITE_PNOR * @userdata1 target huid * @userdata2 VPD type * @devdesc VPD write not supported at runtime */ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, VPD::VPD_RT_WRITE_PNOR, VPD::VPD_RT_WRITE_NOT_SUPPORTED, get_huid(i_target), i_pnorInfo.pnorSection); err->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, HWAS::SRCI_PRIORITY_HIGH); err->collectTrace( "VPD", 256); return err; }
/** * @brief Callback function to check for a record override */ errlHndl_t DvpdFacade::checkForRecordOverride( const char* i_record, TARGETING::Target* i_target, uint8_t*& o_ptr ) { TRACFCOMP(g_trac_vpd,ENTER_MRK"DvpdFacade::checkForRecordOverride( %s, 0x%.8X )", i_record, get_huid(i_target)); errlHndl_t l_errl = nullptr; o_ptr = nullptr; assert( i_record != nullptr, "DvpdFacade::checkForRecordOverride() i_record is null" ); assert( i_target != nullptr, "DvpdFacade::checkForRecordOverride() i_target is null" ); VPD::RecordTargetPair_t l_recTarg = VPD::makeRecordTargetPair(i_record,i_target); do { // We only support overriding MEMD if( strcmp( i_record, "MEMD" ) ) { TRACFCOMP(g_trac_vpd,"Record %s has no override", i_record); mutex_lock(&iv_mutex); //iv_overridePtr is not threadsafe iv_overridePtr[l_recTarg] = nullptr; mutex_unlock(&iv_mutex); break; } // Compare the last nibble constexpr uint32_t l_vmMask = 0x0000000F; input_args_t l_args = { DVPD::MEMD, DVPD::VM, VPD::AUTOSELECT }; l_errl = getMEMDFromPNOR( l_args, i_target, l_vmMask ); if( l_errl ) { TRACFCOMP(g_trac_vpd,ERR_MRK"ERROR from getMEMDFromPNOR."); break; } } while(0); // For any error, we should reset the override map so that we'll // attempt everything again the next time we want VPD mutex_lock(&iv_mutex); //iv_overridePtr is not threadsafe if( l_errl ) { iv_overridePtr.erase(l_recTarg); } else { o_ptr = iv_overridePtr[l_recTarg]; } mutex_unlock(&iv_mutex); return l_errl; }
errlHndl_t FakeRegSvc::putScom( TargetHandle_t i_target, uint64_t i_address, uint64_t i_data) { ATTN_DBG("FakeRegSvc::putScom: huid: 0x%08X, add: %016x, data: %016x", get_huid(i_target), i_address, i_data); iv_regs[i_target][i_address] = i_data; return NULL; }
/** 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; }
errlHndl_t doScomOp(DeviceFW::OperationType i_opType, TARGETING::Target* i_target, void* io_buffer, size_t& io_buflen, int64_t i_accessType, uint64_t i_addr) { errlHndl_t l_err = NULL; do{ TARGETING::ScomSwitches scomSetting; scomSetting.useXscom = true; //Default to Xscom supported. if(TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL != i_target) { scomSetting = i_target->getAttr<TARGETING::ATTR_SCOM_SWITCHES>(); } //Always XSCOM the Master Sentinel if((TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL == i_target) || (scomSetting.useXscom)) { //do XSCOM l_err = deviceOp(i_opType, i_target, io_buffer, io_buflen, DEVICE_XSCOM_ADDRESS(i_addr)); break; } else if(scomSetting.useInbandScom) { //do IBSCOM l_err = deviceOp(i_opType, i_target, io_buffer, io_buflen, DEVICE_IBSCOM_ADDRESS(i_addr)); if( l_err ) { break; } } else if(scomSetting.useFsiScom) { //do FSISCOM l_err = deviceOp(i_opType, i_target, io_buffer, io_buflen, DEVICE_FSISCOM_ADDRESS(i_addr)); if( l_err ) { break; } } else { assert(0,"SCOM::scomPerformOp> ATTR_SCOM_SWITCHES does not indicate Xscom, Ibscom, or FSISCOM is supported. i_target=0x%.8x", get_huid(i_target)); break; } }while(0); //Look for special retry codes if( l_err && (0xFFFFFFFF != i_accessType) && (l_err->reasonCode() == IBSCOM::IBSCOM_RETRY_DUE_TO_ERROR) ) { delete l_err; TRACFCOMP(g_trac_scom, "Forcing retry of Scom to %.16X on %.8X", i_addr, TARGETING::get_huid(i_target)); // use the unused i_accessType parameter to avoid an infinite recursion int64_t accessType_flag = 0xFFFFFFFF; l_err = doScomOp( i_opType, i_target, io_buffer, io_buflen, accessType_flag, i_addr ); } //Add some additional FFDC based on the specific operation if( l_err ) { addScomFailFFDC( l_err, i_target, i_addr ); } return l_err; }
errlHndl_t initiateDrtm() { SB_ENTER("initiateDrtm"); errlHndl_t pError = nullptr; // For DRTM, the thread has to be pinned to a core (and therefore pinned to // a chip) task_affinity_pin(); void* drtmPayloadVirtAddr = nullptr; do { const std::vector<SECUREBOOT::ProcSecurity> LLP { SECUREBOOT::ProcSecurity::LLPBit, }; const std::vector<SECUREBOOT::ProcSecurity> LLS { SECUREBOOT::ProcSecurity::LLSBit, }; // Determine which fabric group and chip this task is executing on and // create a filter to find the matching chip target auto cpuId = task_getcpuid(); auto groupId = PIR_t::groupFromPir(cpuId); auto chipId = PIR_t::chipFromPir(cpuId); TARGETING::PredicateAttrVal<TARGETING::ATTR_FABRIC_GROUP_ID> matchesGroup(groupId); TARGETING::PredicateAttrVal<TARGETING::ATTR_FABRIC_CHIP_ID> matchesChip(chipId); TARGETING::PredicatePostfixExpr matchesGroupAndChip; matchesGroupAndChip.push(&matchesGroup).push(&matchesChip).And(); // Get all the functional proc chips and find the chip we're running on TARGETING::TargetHandleList funcProcChips; TARGETING::getAllChips(funcProcChips, TARGETING::TYPE_PROC); if(funcProcChips.empty()) { // TODO: RTC 167205: GA error handling assert(false,"initiateDrtm: BUG! Functional proc chips is empty, " "yet this code is running on a functional chip!"); break; } // NOTE: std::find_if requires predicates to be copy constructable, but // predicates are not; hence use a wrapper lambda function to bypass // that limitation auto pMatch = std::find_if(funcProcChips.begin(),funcProcChips.end(), [&matchesGroupAndChip] ( TARGETING::Target* pTarget ) { return matchesGroupAndChip(pTarget); } ); if(pMatch == funcProcChips.end()) { // TODO: RTC 167205: GA error handling assert(false, "initiateDrtm: BUG! No functional chip found " "to be running this code"); break; } // Move the matching target to the end of the list. // NOTE: If reverse iterators were supported, we could have verified the // last element of the container is not the match, and done a // std::iter_swap of the match and the last element TARGETING::Target* const pMatchTarget = *pMatch; funcProcChips.erase(pMatch); funcProcChips.push_back(pMatchTarget); // Map to the DRTM payload area in mainstore const uint32_t drtmPayloadPhysAddrMb = DRTM_RIT_PAYLOAD_PHYS_ADDR_MB; drtmPayloadVirtAddr = mm_block_map( reinterpret_cast<void*>(drtmPayloadPhysAddrMb*BYTES_PER_MEGABYTE), PAGESIZE); if(drtmPayloadVirtAddr == nullptr) { // TODO: RTC 167205: GA error handling assert(false, "initiateDrtm: BUG! Failed in call to mm_block_map " "to map the DRTM payload."); break; } // Copy the DRTM payload to the DRTM payload area memcpy( reinterpret_cast<uint32_t*>(drtmPayloadVirtAddr), DRTM_RIT_PAYLOAD, sizeof(DRTM_RIT_PAYLOAD)); // The required generic sequencing to initiate DRTM is as follows: // 1) Initiating task must pin itself to a core (to ensure it // will not be accidentally queisced by SBE) // 2) It must set the DRTM payload information in the master processor // mailbox scratch registers (registers 7 and 8) before it goes // offline // 3) It must determine the processor it's currently running on // 4) It must set the late launch bit (LL) on all other processors // 4a) If the given processor is an active master, it must set // late launch primary (LLP) bit // 4b) Otherwise it must set late launch secondary (LLS) bit // 5) Finally, it must its own processor's LL bit last, according to the // rules of step 4. for(auto &pFuncProc :funcProcChips) { const auto procMasterType = pFuncProc->getAttr< TARGETING::ATTR_PROC_MASTER_TYPE>(); // If master chip, set the DRTM payload address and validity if(procMasterType == TARGETING::PROC_MASTER_TYPE_ACTING_MASTER) { (void)setDrtmPayloadPhysAddrMb(drtmPayloadPhysAddrMb); } pError = SECUREBOOT::setSecuritySwitchBits(procMasterType == TARGETING::PROC_MASTER_TYPE_ACTING_MASTER ? LLP : LLS, pFuncProc); if(pError) { SB_ERR("initiateDrtm: setSecuritySwitchBits() failed for proc " "= 0x%08X. Tried to set LLP or LLS.", get_huid(pFuncProc)); break; } } if(pError) { break; } SB_INF("initiateDrtm: SBE should eventually quiesce all cores; until " "then, endlessly yield the task"); while(1) { task_yield(); } } while(0); // If we -do- come back from this function (on error path only), then we // should unpin task_affinity_unpin(); if(drtmPayloadVirtAddr) { auto rc = mm_block_unmap(const_cast<void*>(drtmPayloadVirtAddr)); if(rc != 0) { // TODO: RTC 167205: GA error handling assert(false,"initiateDrtm: BUG! mm_block_unmap failed for virtual " "address 0x%16llX.", drtmPayloadVirtAddr); } } if(pError) { SB_ERR("initiateDrtm: plid=0x%08X, eid=0x%08X, reason=0x%04X", ERRL_GETPLID_SAFE(pError), ERRL_GETEID_SAFE(pError), ERRL_GETRC_SAFE(pError)); } SB_EXIT("initiateDrtm"); return pError; }
errlHndl_t completeDrtm() { SB_ENTER("completeDrtm"); errlHndl_t pError = nullptr; do { bool drtmMpIpl = false; isDrtmMpipl(drtmMpIpl); if(drtmMpIpl) { SB_INF("completeDrtm: Clearing L4A and LQA on node's functional " "proc chips."); const std::vector<SECUREBOOT::ProcSecurity> bitsToClear { SECUREBOOT::ProcSecurity::L4ABit, SECUREBOOT::ProcSecurity::LQABit }; TARGETING::TargetHandleList funcProcChips; TARGETING::getAllChips(funcProcChips, TARGETING::TYPE_PROC); for(auto &pFuncProc :funcProcChips) { pError = SECUREBOOT::clearSecuritySwitchBits(bitsToClear, pFuncProc); if(pError) { // TODO: RTC 167205: GA error handling to attempt on every // processor SB_ERR("completeDrtm: clearSecuritySwitchBits() failed for " "proc = 0x%08X. Tried to clear LQA + L4A.", get_huid(pFuncProc)); break; } } if(pError) { break; } } else { SB_INF("completeDrtm: DRTM not active, not clearing LQA or L4A " "bits."); } } while(0); if(pError) { SB_ERR("completeDrtm: plid=0x%08X, eid=0x%08X, reason=0x%04X", ERRL_GETPLID_SAFE(pError), ERRL_GETEID_SAFE(pError), ERRL_GETRC_SAFE(pError)); } SB_EXIT("completeDrtm"); return pError; }
errlHndl_t validateDrtmHwSignature() { SB_ENTER("validateDrtmHwSignature"); errlHndl_t pError = nullptr; do { bool drtmMpIpl = false; isDrtmMpipl(drtmMpIpl); if(drtmMpIpl) { SB_DBG("validateDrtmHwSignature: DRTM active, checking L4A, LQA, " "SUL, LLS and LLP on node's functional proc chips."); TARGETING::TargetHandleList funcProcChips; TARGETING::getAllChips(funcProcChips, TARGETING::TYPE_PROC); for(auto &pFuncProc :funcProcChips) { uint64_t securitySwitches = 0; pError = SECUREBOOT::getSecuritySwitch(securitySwitches, pFuncProc); if(pError) { SB_ERR("validateDrtmHwSignature: getSecuritySwitch() " "failed for proc = 0x%08X.", get_huid(pFuncProc)); break; } const bool L4A = securitySwitches & static_cast<uint64_t>(SECUREBOOT::ProcSecurity::L4ABit); const bool LQA = securitySwitches & static_cast<uint64_t>(SECUREBOOT::ProcSecurity::LQABit); const bool SUL = securitySwitches & static_cast<uint64_t>(SECUREBOOT::ProcSecurity::SULBit); const bool LLP = securitySwitches & static_cast<uint64_t>(SECUREBOOT::ProcSecurity::LLPBit); const bool LLS = securitySwitches & static_cast<uint64_t>(SECUREBOOT::ProcSecurity::LLSBit); SB_INF("validateDrtmHwSignature: Proc 0x%08X has L4A = %d, " "LQA = %d, SUL = %d, LLP = %d, LLS = %d.", get_huid(pFuncProc),L4A,LQA,SUL,LLP,LLS); if(!L4A || !LQA || !SUL || LLP || LLS) { // TODO: RTC 167205: GA error handling, including whether // to attempt on every processor assert(false,"validateDrtmHwSignature: BUG! In DRTM flow, " "all functional proc chips should have L4A, LQA, and " "SUL set + LLP and LLS clear, however proc 0x%08X has " "L4A = %d, LQA = %d, SUL = %d, LLP = %d, LLS = %d.", get_huid(pFuncProc),L4A,LQA,SUL,LLP,LLS); break; } } if(pError) { break; } } else { SB_INF("validateDrtmHwSignature: DRTM not active, skipping check " "for L4A, LQA, SUL, LLP and LLS on node's functional procs"); } } while(0); if(pError) { SB_ERR("validateDrtmHwSignature: plid=0x%08X, eid=0x%08X, " "reason=0x%04X", ERRL_GETPLID_SAFE(pError), ERRL_GETEID_SAFE(pError), ERRL_GETRC_SAFE(pError)); } SB_EXIT("validateDrtmHwSignature"); return pError; }
void* call_mss_memdiag (void* io_pArgs) { errlHndl_t errl = nullptr; IStepError l_stepError; TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_memdiag entry"); TARGETING::Target* masterproc = nullptr; TARGETING::targetService().masterProcChipTargetHandle(masterproc); #ifdef CONFIG_IPLTIME_CHECKSTOP_ANALYSIS errl = HBOCC::loadHostDataToSRAM(masterproc, PRDF::ALL_PROC_MEM_MASTER_CORE); assert(nullptr == errl, "Error returned from call to HBOCC::loadHostDataToSRAM"); #endif do { // Actions vary by processor type. ATTR_MODEL_type procType = masterproc->getAttr<ATTR_MODEL>(); if ( MODEL_NIMBUS == procType ) { TargetHandleList trgtList; getAllChiplets( trgtList, TYPE_MCBIST ); // @todo RTC 179458 Intermittent SIMICs action file issues if ( Util::isSimicsRunning() == false ) { // Start Memory Diagnostics. errl = __runMemDiags( trgtList ); if ( nullptr != errl ) break; } for ( auto & tt : trgtList ) { fapi2::Target<fapi2::TARGET_TYPE_MCBIST> ft ( tt ); // Unmask mainline FIRs. FAPI_INVOKE_HWP( errl, mss::unmask::after_memdiags, ft ); if ( nullptr != errl ) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "mss::unmask::after_memdiags(0x%08x) failed", get_huid(tt) ); break; } // Turn off FIFO mode to improve performance. FAPI_INVOKE_HWP( errl, mss::reset_reorder_queue_settings, ft ); if ( nullptr != errl ) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "mss::reset_reorder_queue_settings(0x%08x) " "failed", get_huid(tt) ); break; } } if ( nullptr != errl ) break; } else if ( MODEL_CUMULUS == procType ) { TargetHandleList trgtList; getAllChiplets( trgtList, TYPE_MBA ); if ( Util::isSimicsRunning() == false ) { // Start Memory Diagnostics errl = __runMemDiags( trgtList ); if ( nullptr != errl ) break; } // No need to unmask or turn off FIFO. That is already contained // within the other Centaur HWPs. } } while (0); if ( nullptr != errl ) { // Create IStep error log and cross reference to error that occurred l_stepError.addErrorDetails(errl); // Commit Error errlCommit(errl, HWPF_COMP_ID); } TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_memdiag exit"); // end task, returning any errorlogs to IStepDisp return l_stepError.getErrorHandle(); }
void axone_dccal_setup(IStepError & io_istepError) { errlHndl_t l_err = nullptr; TargetHandleList l_omic_target_list; getAllChiplets(l_omic_target_list, TYPE_OMIC); for (const auto & l_omic_target : l_omic_target_list) { // call the HWP with each target fapi2::Target<fapi2::TARGET_TYPE_OMIC> l_fapi_omic_target (l_omic_target); TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "p9a_io_omi_scominit HWP target HUID %.8x", get_huid(l_omic_target)); FAPI_INVOKE_HWP(l_err, p9a_io_omi_scominit, l_fapi_omic_target); // process return code. if ( l_err ) { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "ERROR 0x%.8X: p9a_io_omi_scominit HWP on target HUID %.8x", l_err->reasonCode(), TARGETING::get_huid(l_omic_target) ); // capture the target data in the elog ErrlUserDetailsTarget(l_omic_target).addToLog( l_err ); // Create IStep error log and cross reference to error that occurred io_istepError.addErrorDetails( l_err ); // Commit Error errlCommit( l_err, ISTEP_COMP_ID ); } else { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "SUCCESS : p9a_io_omi_scominit HWP on target HUID %.8x", TARGETING::get_huid(l_omic_target) ); } TargetHandleList l_omi_target_list; getChildOmiTargetsByState(l_omi_target_list, l_omic_target, CLASS_UNIT, TYPE_OMI, UTIL_FILTER_FUNCTIONAL); uint32_t l_laneVector = 0x00000000; for(const auto & l_omi_target : l_omi_target_list) { // The OMI dc calibration HWP requires us to pass in the OMIC target // and then a bit mask representing which positon of OMI we are calibrating. // To get the position of the OMI relative to its parent OMIC, look up // ATTR_OMI_DL_GROUP_POS then shift the POS_0_VECTOR = 0x000000FF by 1 byte to the left // for every position away from 0 OMI_DL_GROUP_POS is. // Therefore // POS_0_VECTOR = 0x000000FF // POS_1_VECTOR = 0x0000FF00 // POS_2_VECTOR = 0x00FF0000 l_laneVector |= POS_0_VECTOR << (l_omi_target->getAttr<ATTR_OMI_DL_GROUP_POS>() * BITS_PER_BYTE); } TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "p9a_io_omi_dccal HWP target HUID %.8x with lane vector 0x%x", TARGETING::get_huid(l_omic_target), l_laneVector); FAPI_INVOKE_HWP(l_err, p9a_io_omi_dccal, l_fapi_omic_target, l_laneVector); // process return code. if ( l_err ) { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "ERROR 0x%.8X: p9a_io_omi_dccal HWP on target HUID %.8x with lane vector 0x%x", l_err->reasonCode(), TARGETING::get_huid(l_omic_target), l_laneVector); // capture the target data in the elog ErrlUserDetailsTarget(l_omic_target).addToLog( l_err ); l_err->collectTrace("ISTEPS_TRACE", 256); // Create IStep error log and cross reference to error that occurred io_istepError.addErrorDetails( l_err ); // Commit Error errlCommit( l_err, ISTEP_COMP_ID ); } else { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "SUCCESS : p9a_io_omi_dccal HWP on target HUID %.8x with lane vector 0x%x", TARGETING::get_huid(l_omic_target), l_laneVector ); } } }
/** * @brief Returns the runtime target type for a given targeting target * @param[in] i_pTarget Targeting target, must not be NULL * (asserts otherwise) * @param[out] o_rtType Runtime target type for given targeting target * @return Error log handle * @retval NULL Returned supported runtime target type for the given input * targeting target in the output parameter. * @retval !NULL Failed to determine runtime target type for the * given input targeting target, ignore output parameter. */ errlHndl_t getRtTypeForTarget( const TARGETING::Target* i_pTarget, RT_TARG::rtChipId_t& o_rtType) { assert(i_pTarget != NULL); errlHndl_t pError = NULL; if(i_pTarget == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) { TARGETING::Target* masterProcChip = NULL; TARGETING::targetService(). masterProcChipTargetHandle(masterProcChip); i_pTarget = masterProcChip; } auto found = true; auto rtType = RT_TYPE_UNKNOWN; auto targetingTargetType = i_pTarget->getAttr<TARGETING::ATTR_TYPE>(); switch(targetingTargetType) { case TARGETING::TYPE_PROC: rtType = HBRT_PROC_TYPE; break; case TARGETING::TYPE_MEMBUF: rtType = HBRT_MEMBUF_TYPE; break; case TARGETING::TYPE_CORE: rtType = HBRT_CORE_TYPE; break; default: found = false; break; } if(!found) { auto huid = get_huid(i_pTarget); TRACFCOMP(g_trac_runtime, ERR_MRK "Input targeting target's type of 0x%08X is not supported. " "HUID: 0x%08X", targetingTargetType, huid); /*@ * @errortype * @moduleid RUNTIME::MOD_CUST_CONF_HBRT_HYP_IDS * @reasoncode RUNTIME::RT_TARGET_TYPE_NOT_SUPPORTED * @userdata1 Target's HUID * @userdata2 Target's targeting type * @devdesc Targeting target's type not supported by runtime code */ pError = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_INFORMATIONAL, RUNTIME::MOD_CUST_CONF_HBRT_HYP_IDS, RUNTIME::RT_TARGET_TYPE_NOT_SUPPORTED, huid, targetingTargetType, true); ERRORLOG::ErrlUserDetailsTarget(i_pTarget,"Targeting Target"). addToLog(pError); } o_rtType = rtType; return pError; }
/** * @brief Returns the runtime target ID for a given targeting target for all * hypervisors other than PHyp * @param[in] i_pTarget Targeting target, must not be NULL (asserts * otherwise) * @param[out] o_rtTargetId Runtime target ID which maps to the given targeting * target * @return Error log handle * @retval NULL Computed a valid runtime target ID for the given input * targeting target and returned it in the output parameter. * @retval !NULL Failed to compute a runtime target ID for the given input * targeting target. Ignore output parameter. */ errlHndl_t computeNonPhypRtTarget( const TARGETING::Target* i_pTarget, RT_TARG::rtChipId_t& o_rtTargetId) { assert(i_pTarget != NULL); errlHndl_t pError = NULL; do { if(i_pTarget == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL) { TARGETING::Target* masterProcChip = NULL; TARGETING::targetService(). masterProcChipTargetHandle(masterProcChip); i_pTarget = masterProcChip; } auto targetingTargetType = i_pTarget->getAttr<TARGETING::ATTR_TYPE>(); if(targetingTargetType == TARGETING::TYPE_PROC) { uint32_t fabId = i_pTarget->getAttr<TARGETING::ATTR_FABRIC_GROUP_ID>(); uint32_t procPos = i_pTarget->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>(); o_rtTargetId = PIR_t::createChipId( fabId, procPos ); } else if( targetingTargetType == TARGETING::TYPE_MEMBUF) { //MEMBUF // 0b1000.0000.0000.0000.0000.0GGG.GCCC.MMMM // where GGGG is group, CCC is chip, MMMM is memory channel // TARGETING::TargetHandleList targetList; getParentAffinityTargets(targetList, i_pTarget, TARGETING::CLASS_UNIT, TARGETING::TYPE_DMI); if( targetList.empty() ) { auto huid = get_huid(i_pTarget); TRACFCOMP(g_trac_runtime, ERR_MRK "No associated DMI targeting target(s) found for MEMBUF " "targeting target with HUID of 0x%08X", huid); /*@ * @error * @moduleid RUNTIME::MOD_CUST_COMP_NON_PHYP_RT_TARGET * @reasoncode RUNTIME::RT_UNIT_TARGET_NOT_FOUND * @userdata1 MEMBUF targeting target's HUID * @devdesc No associated DMI targeting target(s) found for * given MEMBUF targeting target */ pError = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_INFORMATIONAL, RUNTIME::MOD_CUST_COMP_NON_PHYP_RT_TARGET, RUNTIME::RT_UNIT_TARGET_NOT_FOUND, huid, 0, true); ERRORLOG::ErrlUserDetailsTarget(i_pTarget,"Targeting Target"). addToLog(pError); break; } auto target = targetList[0]; auto pos = target->getAttr<TARGETING::ATTR_CHIP_UNIT>(); targetList.clear(); getParentAffinityTargets(targetList, target, TARGETING::CLASS_CHIP, TARGETING::TYPE_PROC); if(targetList.empty()) { pError = createProcNotFoundError(target); break; } auto procTarget = targetList[0]; pError = computeNonPhypRtTarget(procTarget, o_rtTargetId); if(pError) { break; } o_rtTargetId = (o_rtTargetId << RT_TARG::MEMBUF_ID_SHIFT); o_rtTargetId += pos; o_rtTargetId |= HBRT_MEMBUF_TYPE; } else if(targetingTargetType == TARGETING::TYPE_CORE) { // CORE // 0b0100.0000.0000.0000.0000.GGGG.CCCP.PPPP // GGGG is group, CCC is chip, PPPPP is core auto pos = i_pTarget->getAttr<TARGETING::ATTR_CHIP_UNIT>(); const TARGETING::Target* procTarget = getParentChip(i_pTarget); if(procTarget == NULL) { pError = createProcNotFoundError(i_pTarget); break; } pError = computeNonPhypRtTarget(procTarget, o_rtTargetId); if(pError) { break; } o_rtTargetId = PIR_t::createCoreId(o_rtTargetId,pos); o_rtTargetId |= HBRT_CORE_TYPE; } else { auto huid = get_huid(i_pTarget); TRACFCOMP(g_trac_runtime,ERR_MRK "Targeting target type 0x%08X not supported. Cannot " "convert targeting target with HUID of 0x%08X into a " "runtime target ID", targetingTargetType, huid); /*@ * @errortype * @moduleid RUNTIME::MOD_CUST_COMP_NON_PHYP_RT_TARGET * @reasoncode RUNTIME::RT_TARGET_TYPE_NOT_SUPPORTED * @userdata1 Targeting target's HUID * @userdata2 Targeting target's type * @devdesc The targeting type of the input targeting target is * not supported by runtime code */ pError = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_INFORMATIONAL, RUNTIME::MOD_CUST_COMP_NON_PHYP_RT_TARGET, RUNTIME::RT_TARGET_TYPE_NOT_SUPPORTED, huid, targetingTargetType, true); ERRORLOG::ErrlUserDetailsTarget(i_pTarget,"Targeting Target"). addToLog(pError); } } while(0); return pError; }
errlHndl_t FakePrd::callPrd(const AttentionList & i_attentions) { errlHndl_t l_elog = i_attentions.forEach(Clear(*iv_injectSink)).err; AttnList l_attnList; i_attentions.getAttnList(l_attnList); ATTN_TRACE("fakeCallPrd with Attn Count of %d", l_attnList.size()); // ----------------------------------------------------- // This is FAKE code only. // If you do the EC/MODEL check, it crashes in CXX testcase. // Kind of thinking some library missing that is needed when // adding these calls, For now, I will just leave them out // and we could probably scrap this test now that it runs // successfully (see attntestproc.H) // (Maybe add to 'fake target service' for these ATTRs) // ----------------------------------------------------- // For the initial NIMBUS chip, there is a HW issue // which requires us to clear the "Combined Global // interrupt register" on recoverable errors. // This also affects Checkstop/Special Attns, but // the FSP handles those and already clears the reg. // The issue does not apply to host/unit cs attns. // uint8_t l_ecLevel = 0; AttnList::iterator l_attnIter = l_attnList.begin(); // Shouldn't be mixing NIMBUS with CUMULUS,etc... // so probably don't need to repeat this call per chip. // bool l_isNimbus = ( (*l_attnIter).targetHndl-> // getAttr<ATTR_MODEL>() == MODEL_NIMBUS ); // Iterate thru all chips in case PRD handled // a chip other than the first one. while(l_attnIter != l_attnList.end()) { // l_ecLevel = (*l_attnIter).targetHndl->getAttr<ATTR_EC>(); if ( (RECOVERABLE == (*l_attnIter).attnType) // && (true == l_isNimbus) && (l_ecLevel < 0x11) ) { errlHndl_t l_scomErr = NULL; uint64_t l_clrAllBits = 0; l_scomErr = putScom( (*l_attnIter).targetHndl, PIB_INTR_TYPE_REG, l_clrAllBits ); if (NULL != l_scomErr) { ATTN_ERR("Clear PibIntrReg failed, HUID:0X%08X", get_huid( (*l_attnIter).targetHndl) ); errlCommit(l_scomErr, ATTN_COMP_ID); } // failed to clear PIB intr reg } // if recoverable attn ++l_attnIter; } // end while looping thru attn list return l_elog; }