/** * @brief This function updates the NVDIMM firmware code */ void call_nvdimm_update() { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,ENTER_MRK"call_nvdimm_update()"); TARGETING::TargetHandleList l_nvdimmTargetList; TARGETING::TargetHandleList l_procList; TARGETING::getAllChips(l_procList, TARGETING::TYPE_PROC, false); // grab the NVDIMMs under each processor and add to overall list for (auto l_proc : l_procList) { TARGETING::TargetHandleList tmpList = TARGETING::getProcNVDIMMs(l_proc); l_nvdimmTargetList.insert(l_nvdimmTargetList.end(), tmpList.begin(), tmpList.end()); } // Run the nvdimm update function if the list is not empty if ( !l_nvdimmTargetList.empty() ) { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_nvdimm_update(): found %d nvdimms to check for update", l_nvdimmTargetList.size()); bool updateWorked = NVDIMM::nvdimm_update(l_nvdimmTargetList); if (!updateWorked) { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_nvdimm_update(): nvdimm update failed"); } } TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,EXIT_MRK"call_nvdimm_update()"); }
/////////////////////////////////////////////////////////////////////////////// // ErrlManager::ackErrLogInPnor() /////////////////////////////////////////////////////////////////////////////// bool ErrlManager::ackErrLogInPnor( uint32_t i_errEid ) { TRACFCOMP( g_trac_errl, ENTER_MRK"ackErrLogInPnor(%.8x)", i_errEid); bool rc = true; // look for an un-ACKed log that matches this eid uint32_t i; for (i = 0; i < iv_maxErrlInPnor; i++) { if (!isSlotEmpty(i) && !isSlotACKed(i)) { uint32_t l_eid = readEidFromFlattened(i); if (l_eid == i_errEid) { TRACDCOMP( g_trac_errl, INFO_MRK"ackErrLogInPnor: match in slot %d", i); setACKInFlattened(i); break; } } } // for // if we made it through the loop w/out breaking early if (i == iv_maxErrlInPnor) { //could not find the errorlog to mark for acknowledgment TRACDCOMP( g_trac_errl, ERR_MRK"ackErrLogInPnor failed to find the error log" ); rc = false; } TRACFCOMP( g_trac_errl, EXIT_MRK"ackErrLogInPnor returning %s", rc ? "true" : "false"); return rc; } // ackErrLogInPnor
ErrlManager::ErrlManager() : iv_currLogId(0), iv_pStorage(NULL), iv_hwasProcessCalloutFn(NULL), iv_msgQ(NULL) { TRACFCOMP( g_trac_errl, ENTER_MRK "ErrlManager::ErrlManager constructor" ); iv_hwasProcessCalloutFn = rt_processCallout; TARGETING::Target * sys = NULL; TARGETING::targetService().getTopLevelTarget( sys ); if(sys) { iv_currLogId = sys->getAttr<TARGETING::ATTR_HOSTSVC_PLID>(); } else { iv_currLogId = 0x9fbad000; TRACFCOMP( g_trac_errl, ERR_MRK"HOSTSVC_PLID not available" ); } TRACFCOMP( g_trac_errl, EXIT_MRK "ErrlManager::ErrlManager constructor." ); }
/////////////////////////////////////////////////////////////////////////////// // Handling commit error log. /////////////////////////////////////////////////////////////////////////////// void ErrlManager::commitErrLog(errlHndl_t& io_err, compId_t i_committerComp ) { TRACDCOMP( g_trac_errl, ENTER_MRK"ErrlManager::commitErrLog" ); do { if (io_err == NULL) { // put out warning trace TRACFCOMP(g_trac_errl, ERR_MRK "commitErrLog() - NULL pointer"); break; } TRACFCOMP(g_trac_errl, "commitErrLog() called by %.4X for plid=0x%X," "Reasoncode=%.4X", i_committerComp, io_err->plid(), io_err->reasonCode() ); // Deferred callouts not allowed at runtime - this call will check, // flag and change any that are found. io_err->deferredDeconfigure(); TRACFCOMP( g_trac_errl, INFO_MRK "Send an error log to hypervisor to commit. plid=0x%X", io_err->plid() ); io_err->commit(i_committerComp); sendMboxMsg(io_err); io_err = NULL; } while( 0 ); TRACDCOMP( g_trac_errl, EXIT_MRK"ErrlManager::commitErrLog" ); return; }
// Helper function to run Memory Diagnostics on a list of targets. errlHndl_t __runMemDiags( TargetHandleList i_trgtList ) { errlHndl_t errl = nullptr; do { errl = ATTN::startService(); if ( nullptr != errl ) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "ATTN::startService() failed" ); break; } errl = MDIA::runStep( i_trgtList ); if ( nullptr != errl ) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "MDIA::runStep() failed" ); break; } errl = ATTN::stopService(); if ( nullptr != errl ) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "ATTN::stopService() failed" ); break; } } while (0); return errl; }
/** * @brief Reset the Scom engine regs * * @param[in] i_target Target of the CPU that the xscom is for * @param[in] i_virtAddr virtual address of the CPU that the xscom is * targeted for * * @return none */ void resetScomEngine(TARGETING::Target* i_target, uint64_t* i_virtAddr) { errlHndl_t l_err = NULL; HMER l_hmer; uint64_t io_buffer = 0; size_t io_buflen = XSCOM_BUFFER_SIZE; uint64_t* l_virtAddr = 0; // xscom registers that need to be set. XscomAddrType_t XscomAddr[] = { {0x0202000F, CurThreadCpu}, {0x02020007, TargetCpu}, {0x02020009, TargetCpu},}; TRACFCOMP(g_trac_xscom,"resetScomEngine: XSCOM RESET INTIATED"); // Loop through the registers you want to write to 0 for (int i = 0; i<3; i++) { // First address we need to read is for the Cpu that this thread is // running on. Need to find the virtAddr for that CPU. if (XscomAddr[i].target_type == CurThreadCpu) { l_virtAddr = getCpuIdVirtualAddress(); } // The rest are xscoms are to the target cpu. else { l_virtAddr = i_virtAddr; } //********************************************************* // Write SCOM ADDR To reset the XSCOM ENGINE //********************************************************* l_err = xScomDoOp(DeviceFW::WRITE, l_virtAddr, XscomAddr[i].addr, &io_buffer, io_buflen, l_hmer); // If not successful if (l_err) { // Delete thie errorlog as this is in the errorpath already. delete l_err; TRACFCOMP(g_trac_xscom,ERR_MRK "XSCOM RESET FAILED: XscomAddr = %.16llx, VAddr=%llx",XscomAddr[i], l_virtAddr ); } // unmap the device now that we are done with the scom to that area. if (XscomAddr[i].target_type == CurThreadCpu) { mmio_dev_unmap(reinterpret_cast<void*>(l_virtAddr)); } } return; }
/////////////////////////////////////////////////////////////////////////////// // Handling commit error log. /////////////////////////////////////////////////////////////////////////////// void ErrlManager::commitErrLog(errlHndl_t& io_err, compId_t i_committerComp ) { TRACDCOMP( g_trac_errl, ENTER_MRK"ErrlManager::commitErrLog" ); do { if (io_err == NULL) { // put out warning trace TRACFCOMP(g_trac_errl, ERR_MRK "commitErrLog() - NULL pointer"); break; } TRACFCOMP(g_trac_errl, "commitErrLog() called by %.4X for eid=%.8x, Reasoncode=%.4X", i_committerComp, io_err->eid(), io_err->reasonCode() ); if (io_err->sev() != ERRORLOG::ERRL_SEV_INFORMATIONAL) { iv_nonInfoCommitted = true; lwsync(); } //Ask ErrlEntry to check for any special deferred deconfigure callouts io_err->deferredDeconfigure(); //Offload the error log to the errlog message queue sendErrlogToMessageQueue ( io_err, i_committerComp ); io_err = NULL; } while( 0 ); TRACDCOMP( g_trac_errl, EXIT_MRK"ErrlManager::commitErrLog" ); return; }
void* call_dmi_io_dccal (void *io_pArgs) { IStepError l_StepError; TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_dmi_io_dccal entry" ); do { auto l_procModel = TARGETING::targetService().getProcessorModel(); switch (l_procModel) { case TARGETING::MODEL_CUMULUS: cumulus_dccal_setup(l_StepError); break; case TARGETING::MODEL_AXONE: axone_dccal_setup(l_StepError); break; case TARGETING::MODEL_NIMBUS: default: TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "skipping p9_io_dmi_dccal because not required for current processor model 0x%x", l_procModel); break; } }while(0); TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_dmi_io_dccal exit" ); // end task, returning any errorlogs to IStepDisp return l_StepError.getErrorHandle(); }
// // Wrapper function to call proc_fbc_eff_config_aggregate // void* call_host_fbc_eff_config_aggregate( void *io_pArgs ) { errlHndl_t l_errl = NULL; ISTEP_ERROR::IStepError l_stepError; TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_fbc_eff_config_aggregate entry" ); TARGETING::TargetHandleList l_procChips; getAllChips( l_procChips, TARGETING::TYPE_PROC); for (const auto & l_procChip: l_procChips) { fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>l_fapi2CpuTarget(l_procChip); FAPI_INVOKE_HWP(l_errl,p9_fbc_eff_config_aggregate,l_fapi2CpuTarget); if(l_errl) { l_stepError.addErrorDetails(l_errl); TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "ERROR : call_proc_fbc_eff_config_aggregate, PLID=0x%x", l_errl->plid() ); errlCommit(l_errl, HWPF_COMP_ID); } } TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_fbc_eff_config_aggregate exit" ); return l_stepError.getErrorHandle(); }
int enable_occ_actuation (int i_occ_activation) { int rc = 0; #ifdef CONFIG_HTMGT errlHndl_t err = HTMGT::enableOccActuation(0 != i_occ_activation); if (err) { rc = err->reasonCode(); if (0 == rc) { // If there was a failure, be sure to return non-zero status rc = -1; } TRACFCOMP (g_fapiTd,ERR_MRK"enable_occ_actuation: OCC state change" " failed with rc=0x%04X (actuate=%d)", err->reasonCode(), i_occ_activation); errlCommit (err, HWPF_COMP_ID); } #else rc = -1; TRACFCOMP(g_fapiTd,ERR_MRK"Unexpected call to enable_occ_actuation(%d)" " when HTMGT is not enabled", i_occ_activation); #endif return rc; }
ErrlManager::ErrlManager() : iv_currLogId(0), iv_pStorage(NULL), iv_hwasProcessCalloutFn(NULL), iv_msgQ(NULL) { TRACFCOMP( g_trac_errl, ENTER_MRK "ErrlManager::ErrlManager constructor" ); iv_hwasProcessCalloutFn = rt_processCallout; TARGETING::Target * sys = NULL; TARGETING::targetService().getTopLevelTarget( sys ); if(sys) { iv_currLogId = sys->getAttr<TARGETING::ATTR_HOSTSVC_PLID>(); // set whether we want to skip certain error logs or not. iv_hiddenErrLogsEnable = sys->getAttr<TARGETING::ATTR_HIDDEN_ERRLOGS_ENABLE>(); TRACFCOMP( g_trac_errl,"iv_hiddenErrorLogsEnable = 0x%x", iv_hiddenErrLogsEnable ); } else { iv_currLogId = 0x9fbad000; TRACFCOMP( g_trac_errl, ERR_MRK"HOSTSVC_PLID not available" ); } TRACFCOMP( g_trac_errl, EXIT_MRK "ErrlManager::ErrlManager constructor." ); }
/** * @brief Write 1 page of data to the PNOR device */ errlHndl_t PnorRP::writeToDevice( uint64_t i_offset, uint64_t i_chip, bool i_ecc, void* i_src ) { TRACUCOMP(g_trac_pnor, "PnorRP::writeToDevice> i_offset=%X, i_chip=%d", i_offset, i_chip ); errlHndl_t l_errhdl = NULL; uint8_t* ecc_buffer = NULL; do { #ifdef CONFIG_SFC_IS_AST2400 //@todo RTC:106881 -- Add full write/erase support TRACFCOMP(g_trac_pnor, "PnorRP::writeToDevice> Skipping all writes in BMC for now" ); break; #endif TARGETING::Target* pnor_target = TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL; // assume a single page to write void* data_to_write = i_src; size_t write_size = PAGESIZE; // apply ECC to data if needed if( i_ecc ) { ecc_buffer = new uint8_t[PAGESIZE_PLUS_ECC]; PNOR::ECC::injectECC( reinterpret_cast<uint8_t*>(i_src), PAGESIZE, reinterpret_cast<uint8_t*>(ecc_buffer) ); data_to_write = reinterpret_cast<void*>(ecc_buffer); write_size = PAGESIZE_PLUS_ECC; } //no need for mutex since only ever a singleton object iv_stats[i_offset/PAGESIZE].numWrites++; // write the data out to the PNOR DD errlHndl_t l_errhdl = DeviceFW::deviceWrite( pnor_target, data_to_write, write_size, DEVICE_PNOR_ADDRESS(i_chip,i_offset) ); if( l_errhdl ) { TRACFCOMP(g_trac_pnor, "PnorRP::writeToDevice> Error from device : RC=%X", l_errhdl->reasonCode() ); break; } } while(0); if( ecc_buffer ) { delete[] ecc_buffer; } TRACUCOMP(g_trac_pnor, "< PnorRP::writeToDevice" ); return l_errhdl; }
/** * @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; }
/////////////////////////////////////////////////////////////////////////////// // ErrlManager::startup() /////////////////////////////////////////////////////////////////////////////// void * ErrlManager::startup ( void* i_self ) { TRACFCOMP( g_trac_errl, ENTER_MRK "ErrlManager::startup..." ); //Start a thread and let error log message handler running. reinterpret_cast<ErrlManager *>(i_self)->errlogMsgHndlr(); TRACFCOMP( g_trac_errl, EXIT_MRK "ErrlManager::startup" ); return NULL; }
void* call_cen_arrayinit (void *io_pArgs) { IStepError l_StepError; errlHndl_t l_err = NULL; TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_cen_arrayinit entry" ); TARGETING::TargetHandleList l_membufTargetList; getAllChips(l_membufTargetList, TYPE_MEMBUF); TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "call_cen_arrayinit: %d membufs found", l_membufTargetList.size()); for (const auto & l_membuf_target : l_membufTargetList) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "cen_arrayinit HWP target HUID %.8x", TARGETING::get_huid(l_membuf_target)); // call the HWP with each target fapi2::Target <fapi2::TARGET_TYPE_MEMBUF_CHIP> l_fapi_membuf_target (l_membuf_target); FAPI_INVOKE_HWP(l_err, cen_arrayinit, l_fapi_membuf_target); // process return code. if ( l_err ) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "ERROR 0x%.8X: cen_arrayinit HWP on target HUID %.8x", l_err->reasonCode(), TARGETING::get_huid(l_membuf_target) ); // capture the target data in the elog ErrlUserDetailsTarget(l_membuf_target).addToLog( l_err ); // Create IStep error log and cross reference to error that occurred l_StepError.addErrorDetails( l_err ); // Commit Error errlCommit( l_err, ISTEP_COMP_ID ); } else { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "SUCCESS : cen_arrayinit HWP"); } } TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_cen_arrayinit exit" ); return l_StepError.getErrorHandle(); }
/** * @brief Constructor */ PnorRP::PnorRP() : iv_TOC_used(0) ,iv_msgQ(NULL) ,iv_startupRC(0) { TRACFCOMP(g_trac_pnor, "PnorRP::PnorRP> " ); // setup everything in a separate function initDaemon(); TRACFCOMP(g_trac_pnor, "< PnorRP::PnorRP : Startup Errors=%X ", iv_startupRC ); }
// Runtime processCallout bool rt_processCallout(errlHndl_t &io_errl, uint8_t * i_pData, uint64_t i_Size, bool i_DeferredOnly) { HWAS::callout_ud_t *pCalloutUD = (HWAS::callout_ud_t *)i_pData; if(i_DeferredOnly) { if ((pCalloutUD->type == HWAS::HW_CALLOUT) && ((pCalloutUD->deconfigState == HWAS::DELAYED_DECONFIG) || (pCalloutUD->deconfigState == HWAS::DECONFIG))) { pCalloutUD->deconfigState = HWAS::NO_DECONFIG; TRACFCOMP( g_trac_errl, ERR_MRK "Runtime errorlog callout with DELAYED_DECONFIG or " "DECONFIG not allowed! Changed to NO_DECONFIG. " " plid: 0x%X. Deconfig State: 0x%x", io_errl->plid(), pCalloutUD->deconfigState); } } // Gard callouts are handled by the HWSV if there is an FSP // if we attempt to create a gard record it requires us to read // PNOR which we cannot do on FSP based machines if(!INITSERVICE::spBaseServicesEnabled()) { if ((pCalloutUD->type == HWAS::HW_CALLOUT) && (pCalloutUD->gardErrorType != HWAS::GARD_NULL)) { TARGETING::Target *pTarget = NULL; uint8_t * l_uData = (uint8_t *)(pCalloutUD + 1); bool l_err = HWAS::retrieveTarget(l_uData, pTarget, io_errl); if (!l_err) { errlHndl_t errl = HWAS::theDeconfigGard().platCreateGardRecord (pTarget, io_errl->eid(), pCalloutUD->gardErrorType); if (errl) { TRACFCOMP( g_trac_errl, ERR_MRK "rt_processCallout: error from platCreateGardRecord"); errlCommit(errl, HWAS_COMP_ID); } } } } return true; }
/////////////////////////////////////////////////////////////////////////////// // ErrlManager::sendMboxMsg() /////////////////////////////////////////////////////////////////////////////// void ErrlManager::sendMboxMsg ( errlHndl_t& io_err ) { TRACFCOMP( g_trac_errl, ENTER_MRK"ErrlManager::sendToHypervisor" ); do { #ifdef CONFIG_BMC_IPMI TRACFCOMP(g_trac_errl,INFO_MRK"Send msg to BMC for errlogId [0x%08x]", io_err->plid() ); // convert to SEL/eSEL and send to BMC over IPMI sendErrLogToBmc(io_err); #else TRACDCOMP(g_trac_errl, INFO_MRK"Send msg to FSP for errlogId [0x%08x]", io_err->plid() ); uint32_t l_msgSize = io_err->flattenedSize(); uint8_t * temp_buff = new uint8_t [l_msgSize ]; io_err->flatten ( temp_buff, l_msgSize ); if(g_hostInterfaces && g_hostInterfaces->sendErrorLog) { int rc = g_hostInterfaces->sendErrorLog(io_err->plid(), l_msgSize, temp_buff); if(rc) { TRACFCOMP(g_trac_errl, ERR_MRK "Failed sending error log to FSP. rc: %d. " "plid: 0x%08x", rc, io_err->plid() ); } } else { TRACFCOMP(g_trac_errl, ERR_MRK "Host interfaces not initialized, error log not sent. " "plid: 0x%08x", io_err->plid() ); } delete [] temp_buff; #endif delete io_err; io_err = NULL; } while (0); TRACFCOMP( g_trac_errl, EXIT_MRK"sendToHypervisor()" ); return; }
errlHndl_t RtPnor::readTOC () { TRACFCOMP(g_trac_pnor, ENTER_MRK"RtPnor::readTOC" ); errlHndl_t l_err = NULL; uint8_t* l_toc0Buffer = new uint8_t[PNOR::TOC_SIZE]; do { if (g_hostInterfaces && g_hostInterfaces->pnor_read) { //find proc id uint64_t l_procId; TARGETING::Target* l_masterProc = NULL; TARGETING::targetService().masterProcChipTargetHandle(l_masterProc); l_err = RT_TARG::getRtTarget (l_masterProc, l_procId); if (l_err) { TRACFCOMP(g_trac_pnor, "RtPnor::readTOC: getRtTarget failed"); break; } // offset = 0 means read the entire PNOR::TOC partition // This offset is offset into the partition, not offset from the // beginning of the flash l_err = readFromDevice (l_procId, PNOR::TOC, 0, PNOR::TOC_SIZE, false, l_toc0Buffer); if (l_err) { TRACFCOMP(g_trac_pnor,"RtPnor::readTOC:readFromDevice failed" " for TOC0"); break; } // When we ask for TOC partition, Opal returns a valid TOC. // So, we don't need to verify the second TOC in parseTOC // Therefore, sending invalid value for second toc PNOR::TOCS l_tocUsed; l_err = PNOR::parseTOC(l_toc0Buffer, 0, l_tocUsed, iv_TOC, 0); if (l_err) { TRACFCOMP(g_trac_pnor, "RtPnor::readTOC: parseTOC failed"); break; } } } while (0); if(l_toc0Buffer != NULL) { delete[] l_toc0Buffer; } TRACFCOMP(g_trac_pnor, EXIT_MRK"RtPnor::readTOC" ); return l_err; }
// send the sync complete message errlHndl_t AttributeSync::sendSyncCompleteMessage( ) { TRACFCOMP(g_trac_targeting, "sending sync complete message"); errlHndl_t l_err = NULL; msg_t * msg = msg_allocate(); // initialize msg buffer memset( msg, 0, sizeof(msg_t) ); msg->type = ATTR_SYNC_COMPLETE_TO_FSP; ATTR_SYNC_ADD_PAGE_COUNT( iv_total_pages, msg->data[0] ); l_err = sendMboxMessage( SYNCHRONOUS, msg ); if( l_err == NULL ) { // see if there was an error on the other end ATTR_SYNC_RC return_code = ATTR_SYNC_GET_RC( msg->data[0] ); if ( return_code ) { TRACFCOMP(g_trac_targeting, "return code: 0x%x", return_code ); /*@ * @errortype * @moduleid TARG_MOD_ATTR_SYNC * @reasoncode TARG_RC_ATTR_SYNC_TO_FSP_FAIL * @userdata1 return code from FSP attribute sync * @userdata2 section ID of for section being sync'd * * @devdesc The Attribute synchronization code on the * FSP side was unable to complete the sync * operation successfully. */ l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, TARG_MOD_ATTR_SYNC, TARG_RC_ATTR_SYNC_TO_FSP_FAIL, return_code, (uint64_t)iv_section_to_sync); } } // for a syncronous message we need to free the message msg_free( msg ); return l_err; }
/** * @brief Destructor */ PnorRP::~PnorRP() { TRACFCOMP(g_trac_pnor, "PnorRP::~PnorRP> " ); // delete the message queue we created if( iv_msgQ ) { msg_q_destroy( iv_msgQ ); } // should kill the task we spawned, but that isn't needed right now TRACFCOMP(g_trac_pnor, "< PnorRP::~PnorRP" ); }
/////////////////////////////////////////////////////////////////////////////// // ErrlManager::errlogShutdown() /////////////////////////////////////////////////////////////////////////////// void ErrlManager::errlogShutdown() { // if there are errorlogs that didn't get fully processed, trace them // and clean up while (!iv_errlList.empty()) { // Get errl and its flags ErrlFlagPair_t l_pair = iv_errlList.front(); // If still true that means it was not processed TRACFCOMP(g_trac_errl, INFO_MRK "Failed to fully process Errl(eid %.8x) - Errl Flags Bitfield = 0x%X", l_pair.first->eid(), l_pair.second); delete l_pair.first; l_pair.first = NULL; // delete from the list iv_errlList.pop_front(); } // while items on iv_errlList list // Ensure that all the error logs are pushed out to PNOR // prior to the PNOR resource provider shutting down. int l_rc = mm_remove_pages(FLUSH, (void *) iv_pnorAddr, iv_maxErrlInPnor * PNOR_ERROR_LENGTH); if( l_rc ) { //If mm_remove_pages returns none zero for error then //log an error trace in this case. TRACFCOMP(g_trac_errl, ERR_MRK "Fail to flush the page %p size %d", iv_pnorAddr, iv_maxErrlInPnor * PNOR_ERROR_LENGTH); } // Un-register error log message queue from the shutdown INITSERVICE::unregisterShutdownEvent( iv_msgQ); if (iv_isMboxEnabled) { // Un-register error log message queue from the mailbox service MBOX::msgq_unregister( MBOX::HB_ERROR_MSGQ ); } // Do not destroy the queue... there are paths where the daemon thread // still has references to the queue or the unregisterShutdownEvent did // not take effect because we were already in the middle of a system // shutdown. // Leaving this message queue around really isn't a leak because we are // shutting down. // msg_q_destroy(iv_msgQ); return; }
// ---------------------------------------------------------------------------- // configureBootMode() // ---------------------------------------------------------------------------- void AST2400BootConfig::configureBootMode(uint8_t i_bootMode ) { // assume boot mode is exclusive.. switch( i_bootMode ) { case NORMAL: { TRACFCOMP(g_bc_trace, "configureBootMode() - Boot Mode = NORMAL"); break; } // RTC:123376 - Need to investigate if any additional flags need to be // set or if terminate on error is sufficient case TERMINATE_ON_ERROR: { TARGETING::Target* l_pTopLevel = NULL; TARGETING::targetService().getTopLevelTarget(l_pTopLevel); TRACFCOMP(g_bc_trace, "configureBootMode() - Boot Mode = TERMINATE_ON_ERROR"); l_pTopLevel->setAttr<TARGETING::ATTR_MNFG_FLAGS> (TARGETING::MNFG_FLAG_SRC_TERM ); break; } case ISTEP_MODE: { TRACFCOMP(g_bc_trace, "configureBootMode() - Boot Mode = ISTEP MODE"); TARGETING::Target* l_pTopLevel = NULL; TARGETING::targetService().getTopLevelTarget(l_pTopLevel); l_pTopLevel->setAttr<TARGETING::ATTR_ISTEP_MODE>(1); break; } default: TRACFCOMP(g_bc_trace, "WRN>>configureBootMode() - Boot mode = " "INVALID[0x%x] default to normal", i_bootMode ); break; break; } }
/////////////////////////////////////////////////////////////////////////////// // ErrlManager::sendErrLogToFSP() /////////////////////////////////////////////////////////////////////////////// void ErrlManager::sendErrLogToFSP ( errlHndl_t& io_err ) { msg_t *msg = NULL; TRACFCOMP( g_trac_errl, ENTER_MRK"ErrlManager::sendErrLogToFSP" ); do { //Create a mailbox message to send to FSP msg = msg_allocate(); msg->type = ERRLOG_SEND_TO_FSP_TYPE; uint32_t l_msgSize = io_err->flattenedSize(); //Data[0] will be hostboot error log ID so Hostboot can //keep track of the error log when FSP responses back. msg->data[0] = io_err->eid(); msg->data[1] = l_msgSize; void * temp_buff = MBOX::allocate( l_msgSize ); io_err->flatten ( temp_buff, l_msgSize ); msg->extra_data = temp_buff; TRACDCOMP( g_trac_errl, INFO_MRK"Send msg to FSP for errlogId %.8x", io_err->eid() ); errlHndl_t l_err = MBOX::send( MBOX::FSP_ERROR_MSGQ, msg ); if( !l_err ) { // clear this - we're done with the message; // the receiver will free the storage when it's done msg = NULL; } else { TRACFCOMP(g_trac_errl, ERR_MRK"Failed sending error log to FSP"); //Free the extra data due to the error MBOX::deallocate( msg->extra_data ); msg_free( msg ); msg = NULL; delete l_err; l_err = NULL; } } while (0); TRACFCOMP( g_trac_errl, EXIT_MRK"ErrlManager::sendErrLogToFSP" ); } // sendErrLogToFSP
uint64_t ErrlSctnHdr::flatten( void * o_pBuffer, const uint64_t i_cbBuffer ) { uint64_t l_rc = 0; // Compile-time assertions CPPASSERT( 8 == sizeof( pelSectionHeader_t )); CPPASSERT( 2 == sizeof( iv_sid )); CPPASSERT( 2 == sizeof( iv_slen )); CPPASSERT( 1 == sizeof( iv_ver )); CPPASSERT( 1 == sizeof( iv_sst )); CPPASSERT( 2 == sizeof( iv_compId )); if( i_cbBuffer >= sizeof( pelSectionHeader_t )) { // See errltypes.H for pelSectionHeader_t pelSectionHeader_t * p = static_cast<pelSectionHeader_t *>(o_pBuffer); p->sid = iv_sid; p->len = iv_slen; p->ver = iv_ver; p->sst = iv_sst; p->compId = iv_compId; l_rc = sizeof( pelSectionHeader_t ); } else { TRACFCOMP( g_trac_errl, "ErrlSctnHdr::flatten: buffer too small"); } return l_rc; };
// ------------------------------------------------------------------ // 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; }
//************************************************************************** // FREQVOLTSVC::runP8BuildPstateDataBlock //************************************************************************** errlHndl_t runP8BuildPstateDataBlock( const TARGETING::Target * i_procChip, PstateSuperStructure * o_data) { errlHndl_t l_err = NULL; // Assert on NULL input target assert(i_procChip != NULL); // convert to fapi target fapi::Target l_fapiProcChip(fapi::TARGET_TYPE_PROC_CHIP, reinterpret_cast<void *> (const_cast<TARGETING::Target*>(i_procChip)) ); FAPI_INVOKE_HWP(l_err, p8_build_pstate_datablock,l_fapiProcChip,o_data); if( l_err != NULL) { TRACFCOMP( g_fapiTd,ERR_MRK"Error from HWP: " "p8_build_pstate_datablock for target HUID: 0x%08X", i_procChip->getAttr<TARGETING::ATTR_HUID>()); } return l_err; }
/** * @brief Convert a virtual address into the PNOR device address */ errlHndl_t PnorRP::computeDeviceAddr( void* i_vaddr, uint64_t& o_offset, uint64_t& o_chip, bool& o_ecc ) { errlHndl_t l_errhdl = NULL; o_offset = 0; o_chip = 99; uint64_t l_vaddr = (uint64_t)i_vaddr; // make sure this is one of our addresses if( !((l_vaddr >= BASE_VADDR) && (l_vaddr < LAST_VADDR)) ) { TRACFCOMP( g_trac_pnor, "PnorRP::computeDeviceAddr> Virtual Address outside known PNOR range : i_vaddr=%p", i_vaddr ); /*@ * @errortype * @moduleid PNOR::MOD_PNORRP_WAITFORMESSAGE * @reasoncode PNOR::RC_INVALID_ADDRESS * @userdata1 Virtual Address * @userdata2 Base PNOR Address * @devdesc PnorRP::computeDeviceAddr> Virtual Address outside * known PNOR range * @custdesc A problem occurred while accessing the boot flash. */ l_errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, PNOR::MOD_PNORRP_COMPUTEDEVICEADDR, PNOR::RC_INVALID_ADDRESS, l_vaddr, BASE_VADDR, true /*Add HB SW Callout*/); l_errhdl->collectTrace(PNOR_COMP_NAME); return l_errhdl; } // find the matching section PNOR::SectionId id = PNOR::INVALID_SECTION; l_errhdl = computeSection( l_vaddr, id ); if( l_errhdl ) { return l_errhdl; } // pull out the information we need to return from our global copy o_chip = iv_TOC[id].chip; o_ecc = (bool)(iv_TOC[id].integrity & FFS_INTEG_ECC_PROTECT); o_offset = l_vaddr - iv_TOC[id].virtAddr; //offset into section // for ECC we need to figure out where the ECC-enhanced offset is // before tacking on the offset to the section if( o_ecc ) { o_offset = (o_offset * 9) / 8; } // add on the offset of the section itself o_offset += iv_TOC[id].flashAddr; TRACUCOMP( g_trac_pnor, "< PnorRP::computeDeviceAddr: i_vaddr=%X, o_offset=0x%X, o_chip=%d", l_vaddr, o_offset, o_chip ); return l_errhdl; }
const uint8_t* TPMS_CAPABILITY_DATA_unmarshal(TPMS_CAPABILITY_DATA* val, const uint8_t* i_tpmBuf, size_t * io_tpmBufSize) { i_tpmBuf = unmarshalChunk(i_tpmBuf, io_tpmBufSize, &(val->capability), sizeof(val->capability)); switch (val->capability) { case TPM_CAP_HANDLES: { return TPML_HANDLE_unmarshal( &(val->data.tpmHandles), i_tpmBuf, io_tpmBufSize); } break; case TPM_CAP_TPM_PROPERTIES: { return TPML_TAGGED_TPM_PROPERTY_unmarshal( &(val->data.tpmProperties), i_tpmBuf, io_tpmBufSize); } break; default: { TRACFCOMP( g_trac_trustedboot, "TPMS_CAPABILITY_DATA::unmarshal Unknown capability"); return NULL; } break; } return NULL; }
/** * @brief Send a user-defined SPI command */ errlHndl_t SfcFake::sendSpiCmd( uint8_t i_opCode, uint32_t i_address, size_t i_writeCnt, const uint8_t* i_writeData, size_t i_readCnt, uint8_t* o_readData ) { TRACFCOMP( g_trac_pnor, "SfcFake::sendSpiCmd> Nothing to do here : opcode=%.2X", i_opCode ); /*@ * @errortype * @moduleid PNOR::MOD_SFCFAKE_SENDSPICMD * @reasoncode PNOR::RC_UNSUPPORTED_OPERATION * @userdata1[0:31] Op Code * @userdata1[32:63] Address * @userdata2 <unused> * @devdesc SfcFake::sendSpiCmd> Function is not supported * @custdesc Firmware error accessing flash during IPL */ return new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, PNOR::MOD_SFCFAKE_SENDSPICMD, PNOR::RC_UNSUPPORTED_OPERATION, TWO_UINT32_TO_UINT64(i_opCode, i_address), 0, true /*Software error*/); }