registerOcc() { runtimeInterfaces_t * rt_intf = getRuntimeInterfaces(); rt_intf->get_lid_list = &UtilLidMgr::getLidList; rt_intf->occ_load = &executeLoadOCC; rt_intf->occ_start = &executeStartOCCs; rt_intf->occ_stop = &executeStopOCCs; rt_intf->process_occ_error = &process_occ_error; rt_intf->process_occ_reset = &process_occ_reset; rt_intf->enable_occ_actuation = &enable_occ_actuation; // If we already loaded OCC during the IPL we need to fix up // the virtual address because we're now not using virtual // memory // Note: We called our memory "ibm,slw-occ-image" but OPAL // created their own range that subsumed ours //@todo-RTC:124392-solve this naming issue... uint64_t l_base_homer = g_hostInterfaces->get_reserved_mem("ibm,homer-image"); TargetHandleList procChips; getAllChips(procChips, TYPE_PROC, true); for (TargetHandleList::iterator itr = procChips.begin(); itr != procChips.end(); ++itr) { uint64_t l_offset = (*itr)->getAttr<ATTR_POSITION>() * VMM_HOMER_INSTANCE_SIZE; (*itr)->setAttr<ATTR_HOMER_VIRT_ADDR> (l_base_homer+l_offset); } }
// // 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(); }
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(); }
//************************************************************************** // FREQVOLTSVC::setWofFrequencyUpliftSelected //************************************************************************** void setWofFrequencyUpliftSelected() { // get mrw data TARGETING::Target* l_pTopLevel = NULL; (void)TARGETING::targetService().getTopLevelTarget(l_pTopLevel); ATTR_WOF_FREQUENCY_UPLIFT_type l_upliftTable = {{{0}}}; ATTR_WOF_PROC_SORT_type l_procSortTable = {{0}}; ATTR_NOMINAL_FREQ_MHZ_type l_sysNomFreqMhz = l_pTopLevel->getAttr<ATTR_NOMINAL_FREQ_MHZ>(); ATTR_WOF_ENABLED_type l_wofEnabled = l_pTopLevel->getAttr < TARGETING::ATTR_WOF_ENABLED > (); // tryGetAttr used due to complex data type. Expected to always work. if (!l_pTopLevel->tryGetAttr<ATTR_WOF_FREQUENCY_UPLIFT>(l_upliftTable)) { // The zero initialized values will be used for the select array TRACFCOMP(g_fapiTd, "Failed to get ATTR_WOF_FREQUENCY_UPLIFT"); } // tryGetAttr used due to complex data type. Expected to always work. if ( !l_pTopLevel->tryGetAttr<ATTR_WOF_PROC_SORT>(l_procSortTable)) { // Not finding the sort table will result in not finding the index // which will result in a log later TRACFCOMP(g_fapiTd, "Failed to get ATTR_WOF_PROC_SORT"); } // get the list of procs TargetHandleList l_procTargetList; getAllChips(l_procTargetList, TYPE_PROC, true); // for each proc, fill in Wof Frequency Uplift Selected attribute for (TargetHandleList::const_iterator l_proc_iter = l_procTargetList.begin(); l_proc_iter != l_procTargetList.end(); ++l_proc_iter) { TARGETING::Target * l_pProcTarget = *l_proc_iter; // find number of active cores TARGETING::TargetHandleList l_presCoreList; getChildAffinityTargetsByState( l_presCoreList, const_cast<TARGETING::Target*>(l_pProcTarget), TARGETING::CLASS_UNIT, TARGETING::TYPE_CORE, TARGETING::UTIL_FILTER_PRESENT); uint8_t l_activeCores = l_presCoreList.size(); TRACDCOMP(g_fapiTd, "setWofFrequencyUpliftSelected:" " number of active cores is %d ", l_activeCores); // find WOF index. For example: // ATTR_WOF_PROC_SORT = // Cores/Nom Freq/Index // 8 3325 1 // 10 2926 2 // 12 2561 3 // 12 3093 4 // Use WOF index=3 for active cores=12 && nom freq=2561 uint8_t l_wofIndex = 0; for (uint8_t i=0;i<4;i++) { if ( (l_activeCores == l_procSortTable[i][0]) && (l_sysNomFreqMhz == l_procSortTable[i][1]) ) { l_wofIndex = l_procSortTable[i][2]; break; } } TRACDCOMP(g_fapiTd, "setWofFrequencyUpliftSelected:" " WOF index is %d ", l_wofIndex); // validate WOF index ATTR_WOF_FREQUENCY_UPLIFT_SELECTED_type l_selectedTable = {{0}}; if ( (!l_wofIndex) || (l_wofIndex > 4)) { if (l_wofEnabled) // log error if WOF enabled { TRACFCOMP(g_fapiTd, "setWofFrequencyUpliftSelected:" " No WOF table index match found HUID:0x%08X" " active cores=%d, nom freq=%d, index=%d", l_pProcTarget->getAttr<TARGETING::ATTR_HUID>(), l_activeCores, l_sysNomFreqMhz, l_wofIndex); errlHndl_t l_err = NULL; /*@ * @errortype * @moduleid fapi::MOD_GET_WOF_FREQ_UPLIFT_SELECTED * @reasoncode fapi::RC_INVALID_WOF_INDEX * @userdata1[0:31] Proc HUID * @userdata1[32:63] WOF Freq Uplift Index * @userdata2[0:31] Number of active cores * @userdata2[32:63] Nomimal Frequency * @devdesc When WOF is enabled, the WOF Freq * Uplift index should be 1,2,3, or 4 */ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, fapi::MOD_GET_WOF_FREQ_UPLIFT_SELECTED, fapi::RC_INVALID_WOF_INDEX, TWO_UINT32_TO_UINT64( l_pProcTarget->getAttr<TARGETING::ATTR_HUID>(), l_wofIndex), TWO_UINT32_TO_UINT64( l_activeCores, l_sysNomFreqMhz)); // Callout HW as WOF mrw data is incorrect l_err->addHwCallout(l_pProcTarget, HWAS::SRCI_PRIORITY_MED, HWAS::NO_DECONFIG, HWAS::GARD_NULL); // Include WOF processor sort table TRACFBIN (g_fapiTd, "WOF processor sort table", l_procSortTable, sizeof(l_procSortTable)); l_err->collectTrace(FAPI_TRACE_NAME); // log error and keep going errlCommit(l_err,HWPF_COMP_ID); } // make sure zeros are set in the selected table attribute memset(l_selectedTable, 0, sizeof(l_selectedTable)); } else { // use index to set Wof Frequency Uplift selected attribute // note: mrw index is 1 based memcpy(l_selectedTable, &l_upliftTable[l_wofIndex-1][0][0], sizeof(l_selectedTable)); } if (!l_pProcTarget->trySetAttr<ATTR_WOF_FREQUENCY_UPLIFT_SELECTED> (l_selectedTable)) { //unlikely, crash TRACFCOMP(g_fapiTd, "Failed to set ATTR_WOF_FREQUENCY_UPLIFT_SELECTED"); assert(0); } } return; }
/** * @brief Check flash image SHA512 hash value of each explorer chip * and update the flash if it does not match the SHA512 hash * of the image in PNOR. * * @param[out] o_stepError Error handle for logging istep failures * */ void updateAll(IStepError& o_stepError) { bool l_imageLoaded = false; errlHndl_t l_err = nullptr; bool l_rebootRequired = false; // Get a list of OCMB chips TARGETING::TargetHandleList l_ocmbTargetList; getAllChips(l_ocmbTargetList, TYPE_OCMB_CHIP); TRACFCOMP(g_trac_expupd, ENTER_MRK "updateAll: %d ocmb chips found", l_ocmbTargetList.size()); do { // If no OCMB chips exist, we're done. if(l_ocmbTargetList.size() == 0) { break; } // Read explorer fw image from pnor PNOR::SectionInfo_t l_pnorSectionInfo; rawImageInfo_t l_imageInfo; #ifdef CONFIG_SECUREBOOT l_err = PNOR::loadSecureSection(PNOR::OCMBFW); if(l_err) { TRACFCOMP(g_trac_expupd, ERR_MRK "updateAll: Failed to load OCMBFW section" " from PNOR!"); l_err->collectTrace(EXPUPD_COMP_NAME); // Create IStep error log and cross reference to error that occurred o_stepError.addErrorDetails( l_err ); // Commit Error errlCommit( l_err, EXPUPD_COMP_ID ); break; } #endif //CONFIG_SECUREBOOT l_imageLoaded = true; // get address and size of packaged image l_err = PNOR::getSectionInfo(PNOR::OCMBFW, l_pnorSectionInfo); if(l_err) { TRACFCOMP(g_trac_expupd, ERR_MRK "updateAll: Failure in getSectionInfo()"); l_err->collectTrace(EXPUPD_COMP_NAME); // Create IStep error log and cross reference to error that occurred o_stepError.addErrorDetails( l_err ); // Commit Error errlCommit( l_err, EXPUPD_COMP_ID ); break; } // Verify the header and retrieve address, size and // SHA512 hash of unpackaged image l_err = ocmbFwValidateImage( l_pnorSectionInfo.vaddr, l_pnorSectionInfo.secureProtectedPayloadSize, l_imageInfo); if(l_err) { TRACFCOMP(g_trac_expupd, ERR_MRK "updateAll: Failure in expupdValidateImage"); l_err->collectTrace(EXPUPD_COMP_NAME); // Create IStep error log and cross reference to error that occurred o_stepError.addErrorDetails( l_err ); // Commit Error errlCommit( l_err, EXPUPD_COMP_ID ); break; } // For each explorer chip, compare flash hash with PNOR hash and // create a list of explorer chips with differing hash values. TARGETING::TargetHandleList l_flashUpdateList; for(const auto & l_ocmbTarget : l_ocmbTargetList) { sha512regs_t l_regs; //skip all gemini ocmb chips (not updateable) if(l_ocmbTarget->getAttr<TARGETING::ATTR_CHIP_ID>() == POWER_CHIPID::GEMINI_16) { TRACFCOMP(g_trac_expupd, "updateAll: skipping update of gemini OCMB 0x%08x", TARGETING::get_huid(l_ocmbTarget)); continue; } //retrieve the SHA512 hash for the currently flashed image. l_err = getFlashedHash(l_ocmbTarget, l_regs); if(l_err) { TRACFCOMP(g_trac_expupd, ERR_MRK "updateAll: Failure in getFlashedHash(huid = 0x%08x)", TARGETING::get_huid(l_ocmbTarget)); l_err->collectTrace(EXPUPD_COMP_NAME); // Create IStep error log and cross reference to error // that occurred o_stepError.addErrorDetails(l_err); errlCommit(l_err, EXPUPD_COMP_ID); //Don't stop on error, go to next target. continue; } // Trace the hash and image ID values TRACFCOMP(g_trac_expupd, "updateAll: OCMB 0x%08x image ID=0x%08x", TARGETING::get_huid(l_ocmbTarget), l_regs.imageId); TRACFBIN(g_trac_expupd, "SHA512 HASH FROM EXPLORER", l_regs.sha512Hash, HEADER_SHA512_SIZE); //Compare hashes. If different, add to list for update. if(memcmp(l_regs.sha512Hash, l_imageInfo.imageSHA512HashPtr, HEADER_SHA512_SIZE)) { TRACFCOMP(g_trac_expupd, "updateAll: SHA512 hash mismatch on ocmb[0x%08x]", TARGETING::get_huid(l_ocmbTarget)); //add target to our list of targets needing an update l_flashUpdateList.push_back(l_ocmbTarget); } else { TRACFCOMP(g_trac_expupd, "updateAll: SHA512 hash for ocmb[0x%08x]" " matches SHA512 hash of PNOR image.", TARGETING::get_huid(l_ocmbTarget)); } } TRACFCOMP(g_trac_expupd, "updateAll: updating flash for %d OCMB chips", l_flashUpdateList.size()); // update each explorer in the list of chips needing updates for(const auto & l_ocmb : l_flashUpdateList) { TRACFCOMP(g_trac_expupd, "updateAll: updating OCMB 0x%08x", TARGETING::get_huid(l_ocmb)); fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>l_fapi2Target(l_ocmb); // reset watchdog for each ocmb as this function can be very slow INITSERVICE::sendProgressCode(); // Invoke procedure FAPI_INVOKE_HWP(l_err, exp_fw_update, l_fapi2Target, l_imageInfo.imagePtr, l_imageInfo.imageSize); if (l_err) { TRACFCOMP(g_trac_expupd, "Error from exp_fw_update for OCMB 0x%08x", TARGETING::get_huid(l_ocmb)); l_err->collectTrace(EXPUPD_COMP_NAME); // Create IStep error log and cross reference to error // that occurred o_stepError.addErrorDetails( l_err ); errlCommit(l_err, EXPUPD_COMP_ID); // Don't stop on error, go to next target. continue; } else { TRACFCOMP(g_trac_expupd, "updateAll: successfully updated OCMB 0x%08x", TARGETING::get_huid(l_ocmb)); // Request reboot for new firmware to be used l_rebootRequired = true; } } }while(0); // unload explorer fw image if(l_imageLoaded) { #ifdef CONFIG_SECUREBOOT l_err = PNOR::unloadSecureSection(PNOR::OCMBFW); if(l_err) { TRACFCOMP(g_trac_expupd, ERR_MRK "updateAll: Failed to unload OCMBFW"); l_err->collectTrace(EXPUPD_COMP_NAME); // Create IStep error log and cross reference to error that occurred o_stepError.addErrorDetails( l_err ); // Commit Error errlCommit( l_err, EXPUPD_COMP_ID ); } #endif //CONFIG_SECUREBOOT } // force reboot if any updates were successful if(l_rebootRequired) { TRACFCOMP(g_trac_expupd, "updateAll: OCMB chip(s) was updated. Requesting reboot..."); Target* l_pTopLevel = nullptr; targetService().getTopLevelTarget( l_pTopLevel ); assert(l_pTopLevel, "expupd::updateAll: no TopLevelTarget"); auto l_reconfigAttr = l_pTopLevel->getAttr<TARGETING::ATTR_RECONFIGURE_LOOP>(); l_reconfigAttr |= RECONFIGURE_LOOP_OCMB_FW_UPDATE; l_pTopLevel->setAttr<TARGETING::ATTR_RECONFIGURE_LOOP>(l_reconfigAttr); } else { TRACFCOMP(g_trac_expupd, "updateAll: No OCMB chips were updated"); } TRACFCOMP(g_trac_expupd, EXIT_MRK"updateAll()"); }
void cumulus_dccal_setup(IStepError & io_istepError) { errlHndl_t l_err = nullptr; TARGETING::TargetHandleList l_procTargetList; getAllChips(l_procTargetList, TYPE_PROC); for (const auto & l_proc_target : l_procTargetList) { // a. p9_io_dmi_dccal.C (DMI target) TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "p9_io_dmi_dccal HWP target HUID %.8x", TARGETING::get_huid(l_proc_target)); // call the HWP with each target fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_fapi_proc_target (l_proc_target); FAPI_INVOKE_HWP(l_err, p9_io_dmi_dccal, l_fapi_proc_target); // process return code. if ( l_err ) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "ERROR 0x%.8X: p9_io_dmi_dccal HWP on target HUID %.8x", l_err->reasonCode(), TARGETING::get_huid(l_proc_target) ); // capture the target data in the elog ErrlUserDetailsTarget(l_proc_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 : p9_io_dmi_dccal HWP on target HUID %.8x", TARGETING::get_huid(l_proc_target) ); } // b. p9_io_cen_dccal.C (Centaur target) TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "p9_io_cen_dccal HWP target HUID %.8x", TARGETING::get_huid(l_proc_target)); FAPI_INVOKE_HWP(l_err, p9_io_cen_dccal, l_fapi_proc_target); // process return code. if ( l_err ) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "ERROR 0x%.8X: p9_io_cen_dccal HWP on target HUID %.8x", l_err->reasonCode(), TARGETING::get_huid(l_proc_target) ); // capture the target data in the elog ErrlUserDetailsTarget(l_proc_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 : p9_io_cen_dccal HWP on target HUID %.8x", TARGETING::get_huid(l_proc_target) ); } } }
/** * @brief Stops OCCs on all Processors in the node */ errlHndl_t stopAllOCCs() { TRACFCOMP( g_fapiTd,ENTER_MRK"stopAllOCCs" ); errlHndl_t l_errl = NULL; bool winkle_loaded = false; do { #ifndef __HOSTBOOT_RUNTIME //OCC requires the build_winkle_images library if ( !VFS::module_is_loaded( "libbuild_winkle_images.so" ) ) { l_errl = VFS::module_load( "libbuild_winkle_images.so" ); if ( l_errl ) { // load module returned with errl set TRACFCOMP( g_fapiTd,ERR_MRK"loadnStartAllOccs: Could not load build_winkle module" ); // break from do loop if error occured break; } winkle_loaded = true; } #endif TargetHandleList procChips; getAllChips(procChips, TYPE_PROC, true); if(procChips.size() == 0) { TRACFCOMP( g_fapiTd,INFO_MRK"loadnStartAllOccs: No processors found" ); //We'll never get this far in the IPL without any processors, // so just exit. break; } TRACFCOMP( g_fapiTd, INFO_MRK"loadnStartAllOccs: %d procs found", procChips.size()); //The OCC Procedures require processors within a DCM be //setup together. If DCM installed is set, we work under //the assumption that each nodeID is a DCM. So sort the //list by NodeID then call OCC Procedures on NodeID pairs. std::sort(procChips.begin(), procChips.end(), orderByNodeAndPosition); //The OCC master for the node must be reset last. For all //OP systems there is only a single OCC that can be the //master so it is safe to look at the MASTER_CAPABLE flag. Target* masterProc0 = NULL; Target* masterProc1 = NULL; TargetHandleList::iterator itr1 = procChips.begin(); if(0 == (*itr1)->getAttr<ATTR_PROC_DCM_INSTALLED>()) { TRACUCOMP( g_fapiTd, INFO_MRK"stopAllOCCs: non-dcm path entered"); for (TargetHandleList::iterator itr = procChips.begin(); itr != procChips.end(); ++itr) { TargetHandleList pOccs; getChildChiplets(pOccs, *itr, TYPE_OCC); if (pOccs.size() > 0) { if( pOccs[0]->getAttr<ATTR_OCC_MASTER_CAPABLE>() ) { masterProc0 = *itr; continue; } } l_errl = HBOCC::stopOCC( *itr, NULL ); if (l_errl) { TRACFCOMP( g_fapiImpTd, ERR_MRK"stopAllOCCs: stop failed"); errlCommit (l_errl, HWPF_COMP_ID); // just commit and try the next chip } } if (l_errl) { break; } } else { TRACFCOMP( g_fapiTd, INFO_MRK"stopAllOCCs: Following DCM Path"); for (TargetHandleList::iterator itr = procChips.begin(); itr != procChips.end(); ++itr) { Target* targ0 = *itr; Target* targ1 = NULL; TRACFCOMP( g_fapiImpTd, INFO_MRK"stopAllOCCs: Cur target nodeID=%d", targ0->getAttr<ATTR_FABRIC_NODE_ID>()); //if the next target in the list is in the same node // they are on the same DCM, so bump itr forward // and update targ0 pointer if((itr+1) != procChips.end()) { TRACFCOMP( g_fapiImpTd, INFO_MRK"stopAllOCCs: n+1 target nodeID=%d", ((*(itr+1))->getAttr<ATTR_FABRIC_NODE_ID>())); if((targ0->getAttr<ATTR_FABRIC_NODE_ID>()) == ((*(itr+1))->getAttr<ATTR_FABRIC_NODE_ID>())) { //need to flip the numbers because we were reversed targ1 = targ0; itr++; targ0 = *itr; } } TargetHandleList pOccs; getChildChiplets(pOccs, targ0, TYPE_OCC); if (pOccs.size() > 0) { if( pOccs[0]->getAttr<ATTR_OCC_MASTER_CAPABLE>() ) { masterProc0 = targ0; masterProc1 = targ1; continue; } } l_errl = HBOCC::stopOCC( targ0, targ1 ); if (l_errl) { TRACFCOMP( g_fapiImpTd, ERR_MRK"stopAllOCCs: stop failed"); errlCommit (l_errl, HWPF_COMP_ID); // just commit and try the next module } } if (l_errl) { break; } } //now do the master OCC if( masterProc0 ) { l_errl = HBOCC::stopOCC( masterProc0, masterProc1 ); if (l_errl) { TRACFCOMP( g_fapiImpTd, ERR_MRK"stopAllOCCs: stop failed on master"); break; } } } while(0); //make sure we always unload the module if we loaded it if (winkle_loaded) { #ifndef __HOSTBOOT_RUNTIME errlHndl_t l_tmpErrl = VFS::module_unload( "libbuild_winkle_images.so" ); if ( l_tmpErrl ) { TRACFCOMP( g_fapiTd,ERR_MRK"stopAllOCCs: Error unloading build_winkle module" ); if(l_errl) { errlCommit( l_tmpErrl, HWPF_COMP_ID ); } else { l_errl = l_tmpErrl; } } #endif } TRACFCOMP( g_fapiTd,EXIT_MRK"stopAllOCCs" ); return l_errl; }
// // Used to update the sensor status for a specific set of target types // currently supported types are TYPE_DIMM, TYPE_CORE, TYPE_PROC. These // are virtual sensors where Hostboot updates the present and functional // states and the BMC maintains the sensor. // void updateBMCSensorStatus(TARGETING::TYPE i_type) { TARGETING::TargetHandleList l_tList; // get all targets of the passed in type, functional or not switch( i_type ) { case TARGETING::TYPE_PROC: getAllChips( l_tList, TARGETING::TYPE_PROC, false ); break; case TARGETING::TYPE_DIMM: getAllLogicalCards( l_tList, TARGETING::TYPE_DIMM, false ); break; case TARGETING::TYPE_CORE: getAllChiplets( l_tList, TARGETING::TYPE_CORE, false); break; default: assert(0, "invalid target type for BMC update"); } // have a list of targets now set the status sensor on the BMC for each // one. for(TARGETING::TargetHandleList::const_iterator pTargetIt = l_tList.begin(); pTargetIt != l_tList.end(); ++pTargetIt ) { StatusSensor::statusEnum l_status = StatusSensor::PRESENT_FUNCTIONAL; // create a status sensor for our needs StatusSensor l_sensor((*pTargetIt)); TARGETING::HwasState l_state = (*pTargetIt)->getAttr<TARGETING::ATTR_HWAS_STATE>(); if( l_state.present == true ) { if( l_state.functional == false ) { l_status = StatusSensor::PRESENT_NONFUNCTIONAL; } } else { l_status = StatusSensor::NOT_PRESENT; } // send the status to the BMC errlHndl_t l_err = l_sensor.setStatus( l_status ); // commit the error and move to the next target if( l_err ) { errlCommit( l_err, IPMI_COMP_ID ); } } }
/** * @brief Starts OCCs on all Processors in the node * This is intended to be used for AVP testing. * * @param[out] o_failedOccTarget: Pointer to the target failing * loadnStartAllOccs * @param[in] i_useSRAM: bool - use SRAM for OCC image, ie during IPL * true if during IPL, false if at end of IPL (default) * @return errlHndl_t Error log if OCC load failed */ errlHndl_t loadnStartAllOccs(TARGETING::Target *& o_failedOccTarget, bool i_useSRAM) { errlHndl_t l_errl = NULL; void* homerVirtAddrBase = NULL; uint64_t homerPhysAddrBase = VMM_HOMER_REGION_START_ADDR; bool winkle_loaded = false; TRACUCOMP( g_fapiTd, ENTER_MRK"loadnStartAllOccs(%d)", i_useSRAM); do { #ifndef __HOSTBOOT_RUNTIME //OCC requires the build_winkle_images library if ( !VFS::module_is_loaded( "libbuild_winkle_images.so" ) ) { l_errl = VFS::module_load( "libbuild_winkle_images.so" ); if ( l_errl ) { // load module returned with errl set TRACFCOMP( g_fapiTd,ERR_MRK"loadnStartAllOccs: Could not load build_winkle module" ); // break from do loop if error occured break; } winkle_loaded = true; } assert(VMM_HOMER_REGION_SIZE <= THIRTYTWO_GB, "loadnStartAllOccs: Unsupported HOMER Region size"); if (!i_useSRAM) { //If running Sapphire need to place this at the top of memory if(TARGETING::is_sapphire_load()) { homerPhysAddrBase = TARGETING::get_top_mem_addr(); assert (homerPhysAddrBase != 0, "loadnStartAllOccs: Top of memory was 0!"); homerPhysAddrBase -= VMM_ALL_HOMER_OCC_MEMORY_SIZE; } TRACFCOMP( g_fapiTd, "HOMER is at %.16X", homerPhysAddrBase ); //Map entire homer region into virtual memory homerVirtAddrBase = mm_block_map(reinterpret_cast<void*>(homerPhysAddrBase), VMM_HOMER_REGION_SIZE); TRACFCOMP( g_fapiTd, "HOMER virtaddrbase %.16X", homerVirtAddrBase ); } else { // malloc space big enough for all of OCC homerVirtAddrBase = (void *)malloc(1 * MEGABYTE); homerPhysAddrBase = mm_virt_to_phys(homerVirtAddrBase); } #endif if (i_useSRAM) { // OCC is going into L3 and SRAM so only need 1 prime and load // into the Master Proc TargetService & tS = targetService(); Target * sysTarget = NULL; tS.getTopLevelTarget( sysTarget ); assert( sysTarget != NULL ); Target* masterproc = NULL; tS.masterProcChipTargetHandle( masterproc ); /******* SETUP AND LOAD **************/ l_errl = primeAndLoadOcc (masterproc, homerVirtAddrBase, homerPhysAddrBase, i_useSRAM); if(l_errl) { o_failedOccTarget = masterproc; TRACFCOMP( g_fapiImpTd, ERR_MRK "loadnStartAllOccs:primeAndLoadOcc failed"); free(homerVirtAddrBase); break; } /********* START OCC *************/ l_errl = HBOCC::startOCC (masterproc, NULL, o_failedOccTarget); // it either started or errored; either way, free the memory free(homerVirtAddrBase); if (l_errl) { TRACFCOMP( g_fapiImpTd, ERR_MRK"loadnStartAllOccs: startOCC failed"); break; } } else { TargetHandleList procChips; getAllChips(procChips, TYPE_PROC, true); if(procChips.size() == 0) { TRACFCOMP( g_fapiTd,INFO_MRK"loadnStartAllOccs: No processors found" ); //We'll never get this far in the IPL without any processors, // so just exit. break; } TRACUCOMP( g_fapiTd, INFO_MRK"loadnStartAllOccs: %d procs found", procChips.size()); TargetHandleList::iterator itr1 = procChips.begin(); //The OCC Procedures require processors within a DCM be //setup together. So, first checking if any proc has //DCM installed attribute set. If not, we can iterate //over the list in any order. //If DCM installed is set, we work under the assumption //that each nodeID is a DCM. So sort the list by NodeID //then call OCC Procedures on NodeID pairs. if(0 == (*itr1)->getAttr<ATTR_PROC_DCM_INSTALLED>()) { TRACUCOMP( g_fapiTd, INFO_MRK"loadnStartAllOccs: non-dcm path entered"); for (TargetHandleList::iterator itr = procChips.begin(); itr != procChips.end(); ++itr) { /******* SETUP AND LOAD **************/ l_errl = primeAndLoadOcc (*itr, homerVirtAddrBase, homerPhysAddrBase, i_useSRAM); if(l_errl) { o_failedOccTarget = *itr; TRACFCOMP( g_fapiImpTd, ERR_MRK "loadnStartAllOccs:primeAndLoadOcc failed"); break; } /********* START OCC *************/ l_errl = HBOCC::startOCC (*itr, NULL, o_failedOccTarget); if (l_errl) { TRACFCOMP( g_fapiImpTd, ERR_MRK"loadnStartAllOccs: startOCC failed"); break; } } if (l_errl) { break; } } else { TRACUCOMP( g_fapiTd, INFO_MRK"loadnStartAllOccs: Following DCM Path"); std::sort(procChips.begin(), procChips.end(), orderByNodeAndPosition); TRACUCOMP( g_fapiTd, INFO_MRK"loadnStartAllOccs: procChips list sorted"); for (TargetHandleList::iterator itr = procChips.begin(); itr != procChips.end(); ++itr) { TRACUCOMP( g_fapiImpTd, INFO_MRK"loadnStartAllOccs: Insepcting first target" ); Target* targ0 = *itr; Target* targ1 = NULL; TRACUCOMP( g_fapiImpTd, INFO_MRK "loadnStartAllOccs: Cur target nodeID=%d", targ0->getAttr<ATTR_FABRIC_NODE_ID>()); //if the next target in the list is in the same node // they are on the same DCM, so bump itr forward // and update targ1 pointer if((itr+1) != procChips.end()) { TRACUCOMP( g_fapiImpTd, INFO_MRK "loadnStartAllOccs: n+1 target nodeID=%d", ((*(itr+1))->getAttr<ATTR_FABRIC_NODE_ID>()) ); if((targ0->getAttr<ATTR_FABRIC_NODE_ID>()) == ((*(itr+1))->getAttr<ATTR_FABRIC_NODE_ID>())) { itr++; targ1 = *itr; } } /********** Setup and load targ0 ***********/ l_errl = primeAndLoadOcc (targ0, homerVirtAddrBase, homerPhysAddrBase, i_useSRAM); if(l_errl) { o_failedOccTarget = targ0; TRACFCOMP( g_fapiImpTd, ERR_MRK "loadnStartAllOccs: " "primeAndLoadOcc failed on targ0"); break; } /*********** Setup and load targ1 **********/ l_errl = primeAndLoadOcc (targ1, homerVirtAddrBase, homerPhysAddrBase, i_useSRAM); if(l_errl) { o_failedOccTarget = targ1; TRACFCOMP( g_fapiImpTd, ERR_MRK "loadnStartAllOccs: " "primeAndLoadOcc failed on targ1"); break; } /*********** Start OCC *******************/ l_errl = HBOCC::startOCC (targ0, targ1, o_failedOccTarget); if (l_errl) { TRACFCOMP( g_fapiImpTd, ERR_MRK "loadnStartAllOccs: start failed"); break; } } if (l_errl) { break; } } } } while(0); errlHndl_t l_tmpErrl = NULL; //Unless HTMGT is in use, there are no further accesses to HOMER memory //required during the IPL #ifndef CONFIG_HTMGT if(homerVirtAddrBase) { int rc = 0; rc = mm_block_unmap(homerVirtAddrBase); if (rc != 0) { /*@ * @errortype * @moduleid fapi::MOD_OCC_LOAD_START_ALL_OCCS * @reasoncode fapi::RC_MM_UNMAP_ERR * @userdata1 Return Code * @userdata2 Unmap address * @devdesc mm_block_unmap() returns error * @custdesc A problem occurred during the IPL * of the system. */ l_tmpErrl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, fapi::MOD_OCC_LOAD_START_ALL_OCCS, fapi::RC_MM_UNMAP_ERR, rc, reinterpret_cast<uint64_t> (homerVirtAddrBase)); if(l_tmpErrl) { if(l_errl) { errlCommit( l_tmpErrl, HWPF_COMP_ID ); } else { l_errl = l_tmpErrl; } } } } #endif //make sure we always unload the module if (winkle_loaded) { l_tmpErrl = VFS::module_unload( "libbuild_winkle_images.so" ); if ( l_tmpErrl ) { TRACFCOMP ( g_fapiTd,ERR_MRK "loadnStartAllOccs: Error unloading build_winkle module" ); if(l_errl) { errlCommit( l_tmpErrl, HWPF_COMP_ID ); } else { l_errl = l_tmpErrl; } } } TRACUCOMP( g_fapiTd, EXIT_MRK"loadnStartAllOccs" ); return l_errl; }