/////////////////////////////////////////////////////////////////////////////// // 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; }
/////////////////////////////////////////////////////////////////////////////// // 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
void* host_init_fsi( void *io_pArgs ) { errlHndl_t l_err = NULL; ISTEP_ERROR::IStepError l_stepError; TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_init_fsi entry" ); do { l_err = FSI::initializeHardware( ); if (l_err) { // This error should get returned l_stepError.addErrorDetails(l_err); errlCommit( l_err, ISTEP_COMP_ID ); break; } // Only reset the I2C Masters if FSP is not running if ( !INITSERVICE::spBaseServicesEnabled() ) { l_err = I2C::i2cResetActiveMasters(I2C::I2C_ALL, false); if (l_err) { // Commit this error errlCommit( l_err, ISTEP_COMP_ID ); } } } while (0); TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_init_fsi exit" ); return l_stepError.getErrorHandle(); }
//------------------------------------------------------------------------------ // Part callout ErrlUserDetailsCallout::ErrlUserDetailsCallout( const void *i_pTargetData, uint32_t i_targetDataLength, const HWAS::partTypeEnum i_partType, const HWAS::callOutPriority i_priority, const HWAS::DeconfigEnum i_deconfigState, const HWAS::GARD_ErrorType i_gardErrorType) { TRACDCOMP(g_trac_errl, "PartCallout entry"); // Set up ErrlUserDetails instance variables iv_CompId = ERRL_COMP_ID; iv_Version = 1; iv_SubSection = ERRL_UDT_CALLOUT; uint32_t pDataLength = sizeof(HWAS::callout_ud_t) + i_targetDataLength; HWAS::callout_ud_t *pData; pData = reinterpret_cast<HWAS::callout_ud_t *> (reallocUsrBuf(pDataLength)); pData->type = HWAS::PART_CALLOUT; pData->partType = i_partType; pData->priority = i_priority; pData->partDeconfigState = i_deconfigState; pData->partGardErrorType = i_gardErrorType; memcpy(pData + 1, i_pTargetData, i_targetDataLength); TRACDCOMP(g_trac_errl, "PartCallout exit; pDataLength %d", pDataLength); } // Part callout
/////////////////////////////////////////////////////////////////////////////// // 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; }
//------------------------------------------------------------------------------ // Bus callout ErrlUserDetailsCallout::ErrlUserDetailsCallout( const void *i_pTarget1Data, uint32_t i_target1DataLength, const void *i_pTarget2Data, uint32_t i_target2DataLength, const HWAS::busTypeEnum i_busType, const HWAS::callOutPriority i_priority) { TRACDCOMP(g_trac_errl, "BusCallout entry"); // Set up ErrlUserDetails instance variables iv_CompId = ERRL_COMP_ID; iv_Version = 1; iv_SubSection = ERRL_UDT_CALLOUT; uint32_t pDataLength = sizeof(HWAS::callout_ud_t) + i_target1DataLength + i_target2DataLength; HWAS::callout_ud_t *pData; pData = reinterpret_cast<HWAS::callout_ud_t *> (reallocUsrBuf(pDataLength)); pData->type = HWAS::BUS_CALLOUT; pData->busType = i_busType; pData->priority = i_priority; char * l_ptr = (char *)(++pData); memcpy(l_ptr, i_pTarget1Data, i_target1DataLength); memcpy(l_ptr + i_target1DataLength, i_pTarget2Data, i_target2DataLength); TRACDCOMP(g_trac_errl, "BusCallout exit; pDataLength %d", pDataLength); } // Bus callout
//------------------------------------------------------------------------------ // Hardware callout ErrlUserDetailsCallout::ErrlUserDetailsCallout( const void *i_pTargetData, uint32_t i_targetDataLength, const HWAS::callOutPriority i_priority, const HWAS::DeconfigEnum i_deconfigState, const HWAS::GARD_ErrorType i_gardErrorType) { TRACDCOMP(g_trac_errl, "HWCallout entry"); // Set up ErrlUserDetails instance variables iv_CompId = ERRL_COMP_ID; iv_Version = 1; iv_SubSection = ERRL_UDT_CALLOUT; //iv_merge = false; // use the default of false uint32_t pDataLength = sizeof(HWAS::callout_ud_t) + i_targetDataLength; HWAS::callout_ud_t *pData; pData = reinterpret_cast<HWAS::callout_ud_t *> (reallocUsrBuf(pDataLength)); pData->type = HWAS::HW_CALLOUT; pData->priority = i_priority; #ifndef __HOSTBOOT_RUNTIME pData->cpuid = task_getcpuid(); #else pData->cpuid = (uint32_t)(-1); #endif pData->deconfigState = i_deconfigState; pData->gardErrorType = i_gardErrorType; memcpy(pData + 1, i_pTargetData, i_targetDataLength); TRACDCOMP(g_trac_errl, "HWCallout exit; pDataLength %d", pDataLength); } // Hardware callout
// ------------------------------------------------------------------ // i2cEnableSensorCache // ------------------------------------------------------------------ errlHndl_t i2cEnableSensorCache ( TARGETING::Target * i_target ) { errlHndl_t err = NULL; TRACDCOMP( g_trac_i2c, ENTER_MRK"i2cEnableSensorCache()" ); // There must be a 2ms window where the cache is disabled to avoid // some thrashing in the Centaur logic. TRACDCOMP( g_trac_i2c, "Delaying 2ms before enable" ); nanosleep(0,2 * NS_PER_MSEC); uint64_t scacData = SCAC_ENABLE_MSK; size_t dataSize = sizeof(scacData); // Write the scac set reg to enable the sensor cache err = DeviceFW::deviceOp( DeviceFW::WRITE, i_target, &scacData, dataSize, DEVICE_SCOM_ADDRESS(SCAC_CONFIG_SET) ); TRACDCOMP( g_trac_i2c, EXIT_MRK"i2cEnableSensorCache()" ); return err; } // end i2cEnableSensorCache
/// @brief returns a ChipletID for a give target /// @param[in] i_hbTarget includes the HB target type /// @return: ChipletID for i_hbTarget target uint8_t getChipletIDForSBE(TARGETING::Target * i_hbTarget) { uint8_t l_chipletID = 0; TRACDCOMP( g_trac_sbeio, ENTER_MRK "entering getChipletIDForSBE()"); //based on the Host to SBE Interface specification ver 0.70+ switch( i_hbTarget->getAttr<TARGETING::ATTR_TYPE>()) { case(TARGETING::TYPE_PROC): { //not all targets will have CHIPLET_IDs l_chipletID = 0; break; } //MCS has a virtual Chiplet ID case (TARGETING::TYPE_MCS): { l_chipletID = VIRTUAL_CHIPLET_ID_BASE_MCS_TARGET_TYPE + static_cast<uint8_t>(i_hbTarget-> getAttr<TARGETING::ATTR_CHIP_UNIT>()); break; } default: { l_chipletID = static_cast<uint8_t>(i_hbTarget-> getAttr<TARGETING::ATTR_CHIPLET_ID>()); break; } } TRACDCOMP( g_trac_sbeio, EXIT_MRK "exiting getChipletIDForSBE()"); return l_chipletID; }
//************************************************************************** // FREQVOLTSVC::runProcGetVoltage //************************************************************************** errlHndl_t runProcGetVoltage( TARGETING::Target * io_procChip, const uint32_t i_bootFreqMhz) { TRACDCOMP(g_fapiTd,INFO_MRK"Enter runProcGetVoltage"); uint8_t l_vdd_vid = 0; uint8_t l_vcs_vid = 0; errlHndl_t l_err = NULL; TARGETING::ATTR_BOOT_VOLTAGE_type l_boot_voltage_info = PROC_BOOT_VOLT_PORT0_ENABLE; TRACDCOMP(g_fapiTd,INFO_MRK"i_bootFreqMhz: 0x%08X",i_bootFreqMhz); // Assert on NULL input target // If the target is NULL, we have NO functional PROCS. // Terminate IPL assert(io_procChip != NULL); // convert to fapi target fapi::Target l_fapiProcChip(fapi::TARGET_TYPE_PROC_CHIP, reinterpret_cast<void *> (const_cast<TARGETING::Target*>(io_procChip))); // Invoke HW procedure FAPI_INVOKE_HWP(l_err, proc_get_voltage,l_fapiProcChip,i_bootFreqMhz, l_vdd_vid,l_vcs_vid); if( l_err != NULL) { TRACFCOMP( g_fapiTd,ERR_MRK"Error from HWP: proc_get_voltage: " "i_bootFreq: 0x%08X, " "HUID: 0x%08X", i_bootFreqMhz, io_procChip->getAttr<TARGETING::ATTR_HUID>()); } TRACDCOMP(g_fapiTd,INFO_MRK"Vdd: 0x%02x, vcs: 0x%02x", l_vdd_vid, l_vcs_vid); // create boot voltage value l_boot_voltage_info |= ( ( static_cast<uint32_t>(l_vdd_vid) << PROC_BOOT_VOLT_VDD_SHIFT) & ( PROC_BOOT_VOLT_VDD_MASK ) ); l_boot_voltage_info |= ( ( static_cast<uint32_t>(l_vcs_vid) << PROC_BOOT_VOLT_VCS_SHIFT) & ( PROC_BOOT_VOLT_VDD_MASK ) ); // set ATTR_PROC_BOOT_VOLTAGE_VID io_procChip->setAttr< TARGETING::ATTR_PROC_BOOT_VOLTAGE_VID>( l_boot_voltage_info ); return l_err; }
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(); }
/// @brief translates HB target types to SBE target type groups /// @param[in] i_hbTarget includes the HB target type /// @return SBE_TARGET_TYPES returns SBE_TARGET_TYPE_UNKNOWN in error SBE_TARGET_TYPES translateToSBETargetType(TARGETING::Target *i_hbTarget) { TRACDCOMP( g_trac_sbeio, ENTER_MRK "entering translateToSBETargetType()"); SBE_TARGET_TYPES sbeType; sbeType = SBE_TARGET_TYPE_UNKNOWN; switch( i_hbTarget->getAttr<TARGETING::ATTR_TYPE>()) { case(TARGETING::TYPE_PROC): { sbeType = SBE_TARGET_TYPE_PROC; break; } case(TARGETING::TYPE_EX): { sbeType = SBE_TARGET_TYPE_EX; break; } case(TARGETING::TYPE_PERV): case(TARGETING::TYPE_XBUS): case(TARGETING::TYPE_MCBIST): case(TARGETING::TYPE_OBUS): case(TARGETING::TYPE_PCI): case(TARGETING::TYPE_L2): case(TARGETING::TYPE_L3): case(TARGETING::TYPE_L4): case(TARGETING::TYPE_CORE): { sbeType = SBE_TARGET_TYPE_PERV; break; } case(TARGETING::TYPE_MCS): { sbeType = SBE_TARGET_TYPE_MCS; break; } default: TRACFCOMP( g_trac_sbeio, ERR_MRK "translateToSBETargetType:>" " Not supported Target type =%.8X ", i_hbTarget->getAttr<TARGETING::ATTR_TYPE>() ); break; } TRACDCOMP( g_trac_sbeio, EXIT_MRK "exiting translateToSBETargetType()"); return sbeType; }
// readPlidFromFlattened() // i_position MUST be valid errlog (not EMPTY_ERRLOG_IN_PNOR) uint32_t ErrlManager::readPlidFromFlattened(uint32_t i_position) { const char * l_pnorAddr = iv_pnorAddr + (PNOR_ERROR_LENGTH * i_position); const pelPrivateHeaderSection_t *pPH = reinterpret_cast<const pelPrivateHeaderSection_t *>(l_pnorAddr); TRACDCOMP(g_trac_errl, "readEid(%d): plid %.8x", i_position, pPH->plid); return pPH->plid; }
/////////////////////////////////////////////////////////////////////////////// // 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; } // Increment our persistent counter so we don't reuse EIDs // after reboots or mpipl TARGETING::Target * sys = NULL; if( TARGETING::targetService().isInitialized() ) { TARGETING::targetService().getTopLevelTarget( sys ); sys->setAttr<TARGETING::ATTR_HOSTSVC_PLID>(io_err->eid()+1); } 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; }
/////////////////////////////////////////////////////////////////////////////// // ErrlManager::saveErrLogEntry() /////////////////////////////////////////////////////////////////////////////// void ErrlManager::saveErrLogEntry( errlHndl_t& io_err ) { TRACDCOMP( g_trac_errl, ENTER_MRK"ErrlManager::saveErrLogEntry eid %.8x", io_err->eid()); do { // Get flattened count of bytes. uint32_t l_cbActualFlat = io_err->flattenedSize(); // Round this copy up to next nearest word (32-bit) boundary. uint32_t l_cbflat = ((l_cbActualFlat+3) & ~3); // Save/flatten the error log to the storage buffer. uint32_t l_extent = iv_pStorage->offsetMarker + CB2MARKERS + l_cbflat; if( l_extent < ERRL_STORAGE_SIZE) { // New data and its surrounding markers can fit between // the insertion point and the end of the storage buffer. // Flatten the data at the insertion point. marker_t * l_pMarker = OFFSET2MARKER( iv_pStorage->offsetMarker ); io_err->flatten( l_pMarker+1, l_cbflat ); l_pMarker->length = l_cbActualFlat; // Assign offset to next marker to this marker. l_pMarker->offsetNext=iv_pStorage->offsetMarker+CBMARKER+l_cbflat; // Save new insertion point in header. iv_pStorage->offsetMarker = l_pMarker->offsetNext; // Initialize the marker at the new insertion point. marker_t * pNew = OFFSET2MARKER( iv_pStorage->offsetMarker ); pNew->offsetNext = 0; pNew->length = 0; } // Count of error logs called to commit, regardless if there was // room to commit them or not. iv_pStorage->cInserted++; } while( 0 ); TRACDCOMP( g_trac_errl, EXIT_MRK"ErrlManager::saveErrLogEntry" ); return; }
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(); }
bool ErrlManager::isSlotEmpty(uint32_t i_position) { // checks the first word of the flattened errlog, which should be a // pelsectionheader - which will NEVER be 0xFFFFFFFF if it's valid. char * l_pnorAddr = iv_pnorAddr + (PNOR_ERROR_LENGTH * i_position); bool rc = (memcmp(l_pnorAddr, &EMPTY_ERRLOG_IN_PNOR, sizeof(uint32_t)) == 0); TRACDCOMP( g_trac_errl, "isSlotEmpty: slot %d @ %p is %s", i_position, l_pnorAddr, rc ? "empty" : "not empty"); return rc; }
/////////////////////////////////////////////////////////////////////////////// // 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; }
void* call_host_revert_sbe_mcs_setup( void *io_pArgs ) { errlHndl_t l_err = NULL; ISTEP_ERROR::IStepError l_stepError; TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_revert_sbe_mcs_setup entry" ); TARGETING::Target * l_masterProc; TARGETING::targetService().masterProcChipTargetHandle( l_masterProc ); TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "Running p9_revert_sbe_mcs_setup on " "target HUID %.8X", TARGETING::get_huid(l_masterProc)); // cast the target to a fapi2 target fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_fapi_master_proc( l_masterProc ); //Invode p9_revert_sbe_mcs_setup FAPI_INVOKE_HWP( l_err, p9_revert_sbe_mcs_setup, l_fapi_master_proc ); if (l_err) { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "ERROR 0x%.8X: p9_revert_sbe_mcs_setup", l_err->reasonCode()); // Create IStep error log and cross reference error l_stepError.addErrorDetails(l_err); // Commit error errlCommit(l_err,SBE_COMP_ID); } TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_revert_sbe_mcs_setup exit" ); return l_stepError.getErrorHandle(); }
//------------------------------------------------------------------------------ // Sensor callout ErrlUserDetailsCallout::ErrlUserDetailsCallout(const uint32_t i_sensorID, const HWAS::sensorTypeEnum i_sensorType, const HWAS::callOutPriority i_priority) { TRACDCOMP(g_trac_errl, "Sensor Callout"); // Set up ErrlUserDetails instance variables iv_CompId = ERRL_COMP_ID; iv_Version = 1; iv_SubSection = ERRL_UDT_CALLOUT; HWAS::callout_ud_t *pData; pData = reinterpret_cast<HWAS::callout_ud_t *> (reallocUsrBuf(sizeof(HWAS::callout_ud_t))); pData->type = HWAS::SENSOR_CALLOUT; pData->priority = i_priority; pData->sensorId = i_sensorID; pData->sensorType = i_sensorType; TRACDCOMP(g_trac_errl, "Sensor Callout exit"); } // Sensor callout
// isSlotACKed() // i_position MUST be valid errlog (not EMPTY_ERRLOG_IN_PNOR) bool ErrlManager::isSlotACKed(uint32_t i_position) { const char * l_pnorAddr = iv_pnorAddr + (PNOR_ERROR_LENGTH * i_position); l_pnorAddr += sizeof(pelPrivateHeaderSection_t); l_pnorAddr += sizeof(pelUserHeaderSection_t); const pelSRCSection_t *pSRC = reinterpret_cast<const pelSRCSection_t *>(l_pnorAddr); TRACDCOMP(g_trac_errl, "isSlotACKed(%d): word5 %08x - %s", i_position, pSRC->word5, (pSRC->word5 & ErrlSrc::ACK_BIT) ? "not ACKed" : "ACKed"); return (pSRC->word5 & ErrlSrc::ACK_BIT) ? false : true; }
/////////////////////////////////////////////////////////////////////////////// // 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
//------------------------------------------------------------------------------ // Procedure callout ErrlUserDetailsCallout::ErrlUserDetailsCallout( const HWAS::epubProcedureID i_procedure, const HWAS::callOutPriority i_priority) { TRACDCOMP(g_trac_errl, "Procedure Callout"); // Set up ErrlUserDetails instance variables iv_CompId = ERRL_COMP_ID; iv_Version = 1; iv_SubSection = ERRL_UDT_CALLOUT; //iv_merge = false; // use the default of false HWAS::callout_ud_t *pData; pData = reinterpret_cast<HWAS::callout_ud_t *> (reallocUsrBuf(sizeof(HWAS::callout_ud_t))); pData->type = HWAS::PROCEDURE_CALLOUT; pData->procedure = i_procedure; pData->priority = i_priority; TRACDCOMP(g_trac_errl, "Procedure Callout exit"); } // Procedure callout
// setACKInFlattened() void ErrlManager::setACKInFlattened(uint32_t i_position) { char * l_pnorErrlAddr = iv_pnorAddr + (PNOR_ERROR_LENGTH * i_position); char * l_pnorAddr = l_pnorErrlAddr + sizeof(pelPrivateHeaderSection_t); l_pnorAddr += sizeof(pelUserHeaderSection_t); pelSRCSection_t *pSRC = reinterpret_cast<pelSRCSection_t *>(l_pnorAddr); pSRC->word5 &= ~(ErrlSrc::ACK_BIT); TRACDCOMP(g_trac_errl, "setACKInFlattened(%d): word5 %08x - %s", i_position, pSRC->word5, (pSRC->word5 & ErrlSrc::ACK_BIT) ? "not ACKed" : "ACKed"); return; }
void AttributeSync::getSectionData() { // make sure we have a clean slate iv_total_pages = 0; iv_current_page = 0; iv_pages.clear(); // call the targeting function here to get context. TargetService& l_targetService = targetService(); // read the section data info into the iv_pages structure l_targetService.readSectionData( iv_pages, iv_section_to_sync ); iv_total_pages = iv_pages.size(); TRACDCOMP(g_trac_targeting, "total pages %d", iv_total_pages ); }
/** * @brief Get the Virtual Address of the XSCOM space for the processor * associated with this thread (the source chip) * * @param[out] o_mmioAddr Physical mmio address that was mapped in * @return uint64_t* virtualAddress */ uint64_t* getCpuIdVirtualAddress( XSComBase_t& o_mmioAddr ) { uint64_t* o_virtAddr = 0; // Read the MMIO setup by the SBE o_mmioAddr = g_BlToHbDataManager.getXscomBAR(); // Target's virtual address o_virtAddr = static_cast<uint64_t*> (mmio_dev_map(reinterpret_cast<void*>(o_mmioAddr), THIRTYTWO_GB)); TRACDCOMP(g_trac_xscom, "getCpuIdVirtualAddress: o_Virtual Address = 0x%llX\n",o_virtAddr); return o_virtAddr; }
/** * @brief Read data from the flash */ errlHndl_t SfcFake::readFlash( uint32_t i_addr, size_t i_size, void* o_data ) { TRACDCOMP( g_trac_pnor, "SfcFake::readFlash> i_addr=0x%.8x, i_size=0x%.8x", i_addr, i_size ); errlHndl_t errhdl = NULL; //create a pointer to the offset start. uint8_t* srcPtr = reinterpret_cast<uint8_t*>(iv_fakePnor+i_addr); if( (srcPtr+i_size) > (iv_fakePnor+iv_sizeBytes) ) { TRACFCOMP(g_trac_pnor, "SfcFake::readFlash> Read goes past end of fake-PNOR : i_addr=0x%X, i_size=0x%X", i_addr, i_size ); /*@ * @errortype * @moduleid PNOR::MOD_SFCFAKE_READFLASH * @reasoncode PNOR::RC_INVALID_ADDRESS * @userdata1[0:31] PNOR Address * @userdata1[32:63] Bytes to read * @userdata2[0:31] <unused> * @userdata2[32:63] Size of allocated PNOR space * @devdesc SfcFake::readFlash> Requested access exceeded the * bounds of the allocated PNOR space * @custdesc Firmware error accessing flash during IPL */ errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, PNOR::MOD_SFCFAKE_READFLASH, PNOR::RC_INVALID_ADDRESS, TWO_UINT32_TO_UINT64(i_addr, i_size), TWO_UINT32_TO_UINT64(0, iv_sizeBytes), true /*Software error*/); } else { //Read directly from memory memcpy( o_data, srcPtr, i_size ); } return errhdl; }
/** * @brief Erase a block of flash */ errlHndl_t SfcFake::eraseFlash( uint32_t i_addr ) { TRACDCOMP( g_trac_pnor, "SfcFake::eraseFlash> i_addr=0x%.8x, i_size=0x%.8x", i_addr ); errlHndl_t errhdl = NULL; //create a pointer to the offset start. uint8_t* destPtr = reinterpret_cast<uint8_t*>(iv_fakePnor+i_addr); if( (destPtr+iv_eraseSizeBytes) > (iv_fakePnor+iv_sizeBytes) ) { TRACFCOMP(g_trac_pnor, "SfcFake::writeFlash> Write goes past end of fake-PNOR : i_addr=0x%X, i_size=0x%X", i_addr ); /*@ * @errortype * @moduleid PNOR::MOD_SFCFAKE_ERASEFLASH * @reasoncode PNOR::RC_INVALID_ADDRESS * @userdata1[0:31] PNOR Address * @userdata1[32:63] <unused> * @userdata2[0:31] Bytes in erase block * @userdata2[32:63] Size of allocated PNOR space * @devdesc SfcFake::writeFlash> Requested access exceeded the * bounds of the allocated PNOR space * @custdesc Firmware error accessing flash during IPL */ errhdl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, PNOR::MOD_SFCFAKE_ERASEFLASH, PNOR::RC_INVALID_ADDRESS, TWO_UINT32_TO_UINT64(i_addr, 0), TWO_UINT32_TO_UINT64(iv_eraseSizeBytes, iv_sizeBytes), true /*Software error*/); } else { //A real erase sets every bit so emulate that with a memset memset( destPtr, 0xFF, iv_eraseSizeBytes ); } return errhdl; }
void* AttrRP::translateAddr(void* i_pAddress, const Target* i_pUnused) { void* l_address = NULL; for (size_t i = 0; i < iv_sectionCount; ++i) { if ((iv_sections[i].vmmAddress + iv_sections[i].size) >= reinterpret_cast<uint64_t>(i_pAddress)) { l_address = reinterpret_cast<void*>( iv_sections[i].pnorAddress + reinterpret_cast<uint64_t>(i_pAddress) - iv_sections[i].vmmAddress); break; } } TRACDCOMP(g_trac_targeting, "Translated 0x%p to 0x%p", i_pAddress, l_address); return l_address; }
/** * @brief Get the Virtual Address of the XSCOM space for the processor * associated with this thread (the source chip) * * @return uint64_t* virtualAddress */ uint64_t* getCpuIdVirtualAddress() { uint64_t* o_virtAddr = 0; // Get the CPU core this thread is running on uint32_t cpuid = task_getcpuid(); //NNNCCCPPPPTTT format fot the cpuid.. // N = node, C = chip, P = proc, T = thread uint32_t chipId = (cpuid & 0x0380)>>7; uint32_t nodeId = (cpuid & 0x1C00)>>10; // Can change the above hardcoded values to either a macro or use // the info below to do the masking and shifting. // uint64_t max_threads = cpu_thread_count(); // for the number of Chips - use g_xscomMaxChipsPerNode instead.. // For the number of Procs.. MAX_PROCS_RSV = P8_MAX_PROCS*2 // P8_MAX_PROCS = 8 -- space left for 2* that. XSComBase_t l_systemBaseAddr = MASTER_PROC_XSCOM_BASE_ADDR; // Target's XSCOM Base address XSComBase_t l_XSComBaseAddr = l_systemBaseAddr + ( ( (g_xscomMaxChipsPerNode * nodeId) + chipId ) * THIRTYTWO_GB); // Target's virtual address o_virtAddr = static_cast<uint64_t*> (mmio_dev_map(reinterpret_cast<void*>(l_XSComBaseAddr), THIRTYTWO_GB)); TRACDCOMP(g_trac_xscom, "getCpuIdVirtualAddress: o_Virtual Address = 0x%llX\n",o_virtAddr); return o_virtAddr; }