/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/usr/hwpf/hwp/core_activate/core_activate.C $ */ /* */ /* IBM CONFIDENTIAL */ /* */ /* COPYRIGHT International Business Machines Corp. 2012,2013 */ /* */ /* p1 */ /* */ /* Object Code Only (OCO) source materials */ /* Licensed Internal Code Source Materials */ /* IBM HostBoot Licensed Internal Code */ /* */ /* The source code for this program is not published or otherwise */ /* divested of its trade secrets, irrespective of what has been */ /* deposited with the U.S. Copyright Office. */ /* */ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ /** * @file core_activate.C * * Support file for IStep: core_activate * Core Activate * * HWP_IGNORE_VERSION_CHECK * */ /******************************************************************************/ // Includes /******************************************************************************/ #include #include #include #include #include #include #include #include #include // targeting support #include #include #include #include #include // fapi support #include #include #include #include "core_activate.H" #include #include // Uncomment these files as they become available: #include "proc_prep_master_winkle.H" #include "proc_stop_deadman_timer.H" #include "p8_set_pore_bar.H" #include "proc_switch_cfsim.H" #include "proc_switch_rec_attn.H" #include "cen_switch_rec_attn.H" #include "proc_post_winkle.H" namespace CORE_ACTIVATE { using namespace ERRORLOG; using namespace TARGETING; using namespace fapi; using namespace ISTEP; using namespace ISTEP_ERROR; // // Wrapper function to call host_activate_master // void* call_host_activate_master( void *io_pArgs ) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_activate_master entry" ); errlHndl_t l_errl = NULL; IStepError l_stepError; // @@@@@ CUSTOM BLOCK: @@@@@ do { // find the master core, i.e. the one we are running on TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_activate_master: Find master core: " ); const TARGETING::Target* l_masterCore = getMasterCore( ); assert( l_masterCore != NULL ); TARGETING::Target* l_cpu_target = const_cast ( getParentChip( l_masterCore ) ); // Cast OUR type of target to a FAPI type of target. const fapi::Target l_fapi_cpu_target( TARGET_TYPE_PROC_CHIP, (const_cast (l_cpu_target)) ); // Pass in Master EX target const TARGETING::Target* l_masterEx = getExChiplet(l_masterCore); assert(l_masterEx != NULL ); TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_activate_master: call proc_prep_master_winkle. " "Target HUID %.8X", TARGETING::get_huid(l_masterEx)); // cast OUR type of target to a FAPI type of target. const fapi::Target l_fapi_ex_target( TARGET_TYPE_EX_CHIPLET, (const_cast (l_masterEx)) ); // call the HWP with each fapi::Target FAPI_INVOKE_HWP( l_errl, proc_prep_master_winkle, l_fapi_ex_target, true ); if ( l_errl ) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "proc_prep_master_winkle ERROR : Returning errorlog, reason=0x%x", l_errl->reasonCode() ); // capture the target data in the elog ErrlUserDetailsTarget(l_masterEx).addToLog( l_errl ); break; } else { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "proc_prep_master_winkle SUCCESS" ); } // put the master into winkle. TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_activate_master: put master into winkle..." ); int l_rc = cpu_master_winkle( ); if ( l_rc ) { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "ERROR : failed to winkle master, rc=0x%x", l_rc ); /*@ * @errortype * @reasoncode ISTEP_FAIL_MASTER_WINKLE_RC * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid ISTEP_HOST_ACTIVATE_MASTER * @userdata1 return code from cpu_master_winkle * * @devdesc p8_pore_gen_cpureg returned an error when * attempting to change a reg value in the PORE image. */ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, ISTEP_HOST_ACTIVATE_MASTER, ISTEP_FAIL_MASTER_WINKLE_RC, l_rc ); break; } // -------------------------------------------------------- // should return from Winkle at this point // -------------------------------------------------------- TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "Returned from Winkle." ); TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "Call proc_stop_deadman_timer. Target %.8X", TARGETING::get_huid(l_cpu_target) ); // call the HWP with each fapi::Target FAPI_INVOKE_HWP( l_errl, proc_stop_deadman_timer, l_fapi_cpu_target ); if ( l_errl ) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "proc_stop_deadman_timer ERROR : " "Returning errorlog, reason=0x%x", l_errl->reasonCode() ); // capture the target data in the elog ErrlUserDetailsTarget(l_cpu_target).addToLog( l_errl ); break; } else { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "proc_prep_master_winkle SUCCESS" ); } } while ( 0 ); // @@@@@ END CUSTOM BLOCK: @@@@@ if( l_errl ) { /*@ * @errortype * @reasoncode ISTEP_CORE_ACTIVATE_FAILED * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid ISTEP_HOST_ACTIVATE_MASTER * @userdata1 bytes 0-1: plid identifying first error * bytes 2-3: reason code of first error * @userdata2 bytes 0-1: total number of elogs included * bytes 2-3: N/A * @devdesc call to host_activate_master failed see * error identified by the plid in user data * field. */ l_stepError.addErrorDetails(ISTEP_CORE_ACTIVATE_FAILED, ISTEP_HOST_ACTIVATE_MASTER, l_errl ); errlCommit( l_errl, HWPF_COMP_ID ); } TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_activate_master exit" ); // end task, returning any errorlogs to IStepDisp return l_stepError.getErrorHandle(); } // // Wrapper function to call host_activate_slave_cores // void* call_host_activate_slave_cores( void *io_pArgs ) { errlHndl_t l_errl = NULL; IStepError l_stepError; TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_activate_slave_cores entry" ); // @@@@@ CUSTOM BLOCK: @@@@@ uint64_t l_masterCoreID = task_getcpuid() & ~7; TargetHandleList l_cores; getAllChiplets(l_cores, TYPE_CORE); for(TargetHandleList::const_iterator l_core = l_cores.begin(); l_core != l_cores.end(); ++l_core) { ConstTargetHandle_t l_processor = getParentChip(*l_core); CHIP_UNIT_ATTR l_coreId = (*l_core)->getAttr(); FABRIC_NODE_ID_ATTR l_logicalNodeId = l_processor->getAttr(); FABRIC_CHIP_ID_ATTR l_chipId = l_processor->getAttr(); TARGETING::Target* sys = NULL; TARGETING::targetService().getTopLevelTarget(sys); assert( sys != NULL ); uint64_t en_threads = sys->getAttr(); uint64_t pir = INTR::PIR_t(l_logicalNodeId, l_chipId, l_coreId).word; if (pir != l_masterCoreID) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_activate_slave_cores: Waking %x", pir ); int rc = cpu_start_core(pir,en_threads); if (0 != rc) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_activate_slave_cores: " "Error from kernel %d on core %x", rc, pir); /*@ * @errortype * @reasoncode ISTEP_BAD_RC * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid ISTEP_HOST_ACTIVATE_SLAVE_CORES * @userdata1 PIR of failing core. * @userdata2 rc of cpu_start_core(). * * @devdesc Kernel returned error when trying to activate core. */ errlHndl_t l_tmperrl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, ISTEP_HOST_ACTIVATE_SLAVE_CORES, ISTEP_BAD_RC, pir, rc ); // Callout core that failed to wake up. l_tmperrl->addHwCallout(*l_core, HWAS::SRCI_PRIORITY_MED, HWAS::DECONFIG, HWAS::GARD_Predictive); if (NULL == l_errl) { l_errl = l_tmperrl; } else { errlCommit( l_tmperrl, HWPF_COMP_ID ); } } } } if (l_errl) { l_stepError.addErrorDetails(ISTEP_BAD_RC, ISTEP_HOST_ACTIVATE_SLAVE_CORES, l_errl); errlCommit(l_errl, HWPF_COMP_ID); } else { // Call proc_post_winkle TARGETING::TargetHandleList l_procTargetList; getAllChips(l_procTargetList, TYPE_PROC); // Done activate all master/slave cores. // Run post winkle check on all EX targets, one proc at a time. for (TargetHandleList::const_iterator l_procIter = l_procTargetList.begin(); l_procIter != l_procTargetList.end(); ++l_procIter) { const TARGETING::Target* l_pChipTarget = *l_procIter; TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "Running proc_post_winkle on chip HUID %.8X", TARGETING::get_huid(l_pChipTarget)); // Get EX list under this proc TARGETING::TargetHandleList l_exList; getChildChiplets( l_exList, l_pChipTarget, TYPE_EX ); for (TargetHandleList::const_iterator l_exIter = l_exList.begin(); l_exIter != l_exList.end(); ++l_exIter) { const TARGETING::Target * l_exTarget = *l_exIter; TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "Running proc_post_winkle on EX target HUID %.8X", TARGETING::get_huid(l_exTarget)); // cast OUR type of target to a FAPI type of target. fapi::Target l_fapi_ex_target( TARGET_TYPE_EX_CHIPLET, (const_cast(l_exTarget)) ); // call the HWP with each fapi::Target FAPI_INVOKE_HWP( l_errl, proc_post_winkle, l_fapi_ex_target); if ( l_errl ) { // capture the target data in the elog ErrlUserDetailsTarget(l_pChipTarget).addToLog( l_errl ); /*@ * @errortype * @reasoncode ISTEP_PROC_POST_WINKLE_FAILED * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid ISTEP_HOST_ACTIVATE_SLAVE_CORES * @userdata1 bytes 0-1: plid identifying first error * bytes 2-3: reason code of first error * @userdata2 bytes 0-1: total number of elogs included * bytes 2-3: N/A * @devdesc call to host_activate_master failed see * error identified by the plid in user data * field. */ l_stepError.addErrorDetails(ISTEP_PROC_POST_WINKLE_FAILED, ISTEP_HOST_ACTIVATE_SLAVE_CORES, l_errl ); errlCommit( l_errl, HWPF_COMP_ID ); TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "ERROR : proc_post_winkle, PLID=0x%x", l_errl->plid() ); } else { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "SUCCESS : proc_post_winkle" ); } } } // end for } // end if // @@@@@ END CUSTOM BLOCK: @@@@@ TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_activate_slave_cores exit" ); // end task, returning any errorlogs to IStepDisp return l_stepError.getErrorHandle(); } // // Wrapper function to call host_ipl_complete // void* call_host_ipl_complete( void *io_pArgs ) { errlHndl_t l_err = NULL; IStepError l_stepError; TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_ipl_complete entry" ); do { // We only need to run cfsim on the master Processor. TARGETING::Target * l_masterProc = NULL; (void)TARGETING::targetService(). masterProcChipTargetHandle( l_masterProc ); const fapi::Target l_fapi_proc_target( TARGET_TYPE_PROC_CHIP, ( const_cast(l_masterProc) ) ); TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "Running proc_switch_cfsim HWP on target HUID %.8X", TARGETING::get_huid(l_masterProc) ); // call proc_switch_cfsim // TODO - Comment out to work around Centaur FSI scom issue during BU // RTC 64136 is opened to undo this when in-band scoms are available. #if 0 FAPI_INVOKE_HWP(l_err, proc_switch_cfsim, l_fapi_proc_target, true, // RESET true, // RESET_OPB_SWITCH true, // FENCE_FSI0 true, // FENCE_PIB_NH true, // FENCE_PIB_H true, // FENCE_FSI1 true); // FENCE_PIB_SW1 #endif if (l_err) { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "ERROR 0x%.8X: proc_switch_cfsim HWP returned error", l_err->reasonCode()); // capture the target data in the elog ErrlUserDetailsTarget(l_masterProc).addToLog( l_err ); /*@ * @errortype * @reasoncode ISTEP_PROC_SWITCH_CFSIM_FAILED * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid ISTEP_HOST_IPL_COMPLETE * @userdata1 bytes 0-1: plid identifying first error * bytes 2-3: reason code of first error * @userdata2 bytes 0-1: total number of elogs included * bytes 2-3: N/A * @devdesc call to proc_switch_cfsim failed. * see error identified by the plid in user data * field. */ l_stepError.addErrorDetails( ISTEP_PROC_SWITCH_CFSIM_FAILED, ISTEP_HOST_IPL_COMPLETE, l_err ); // commit errorlog errlCommit( l_err, HWPF_COMP_ID ); // break to end break; } else { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "SUCCESS: proc_switch_cfsim HWP( )" ); } // Loop through all the centaurs in the system // and run cen_switch_rec_attn TARGETING::TargetHandleList l_memTargetList; getAllChips(l_memTargetList, TYPE_MEMBUF ); for ( TargetHandleList::iterator l_iter = l_memTargetList.begin(); l_iter != l_memTargetList.end(); ++l_iter ) { TARGETING::Target * l_memChip = (*l_iter) ; // dump physical path to target TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "Running cen_switch_rec_attn HWP on target HUID %.8X", TARGETING::get_huid(l_memChip) ); // cast OUR type of target to a FAPI type of target. fapi::Target l_fapi_centaur_target( TARGET_TYPE_MEMBUF_CHIP, l_memChip ); FAPI_INVOKE_HWP( l_err, cen_switch_rec_attn, l_fapi_centaur_target ); if (l_err) { // log error for this centaur and continue TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "ERROR 0x%.8X: cen_switch_rec_attn HWP( )", l_err->reasonCode() ); // Add all the details for this centaur ErrlUserDetailsTarget myDetails(l_memChip); // capture the target data in the elog myDetails.addToLog(l_err); /*@ * @errortype * @reasoncode ISTEP_CEN_REC_ATTN_FAILED * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid ISTEP_HOST_IPL_COMPLETE * @userdata1 bytes 0-1: plid identifying first error * bytes 2-3: reason code of first error * @userdata2 bytes 0-1: total number of elogs included * bytes 2-3: N/A * @devdesc call to cen_switch_attn failed. * see * error identified by the plid in user data * field. */ l_stepError.addErrorDetails( ISTEP_CEN_REC_ATTN_FAILED, ISTEP_HOST_IPL_COMPLETE, l_err ); errlCommit( l_err, HWPF_COMP_ID ); } else { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "SUCCESS: cen_switch_rec_attn HWP( )" ); } } // endfor // check if any errors were collected above. If so, drop out here. if ( !l_stepError.isNull() ) { break; } // Loop through all the mcs in the system // and run proc_switch_rec_attn TARGETING::TargetHandleList l_mcsTargetList; getAllChiplets(l_mcsTargetList, TYPE_MCS); for ( TargetHandleList::iterator l_iter = l_mcsTargetList.begin(); l_iter != l_mcsTargetList.end(); ++l_iter ) { TARGETING::Target * l_mcsChiplet = (*l_iter) ; // dump physical path to target TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "Running cen_switch_rec_attn HWP on target HUID %.8X", TARGETING::get_huid(l_mcsChiplet) ); // cast OUR type of target to a FAPI type of target. fapi::Target l_fapi_mcs_target( TARGET_TYPE_MCS_CHIPLET, l_mcsChiplet ); FAPI_INVOKE_HWP( l_err, proc_switch_rec_attn, l_fapi_mcs_target ); if (l_err) { // log error for this mcs and continue TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "ERROR 0x%.8X: proc_switch_rec_attn HWP( )", l_err->reasonCode() ); // Add all the details for this proc ErrlUserDetailsTarget myDetails(l_mcsChiplet); // capture the target data in the elog myDetails.addToLog(l_err); /*@ * @errortype * @reasoncode ISTEP_PROC_REC_ATTN_FAILED * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid ISTEP_HOST_IPL_COMPLETE * @userdata1 bytes 0-1: plid identifying first error * bytes 2-3: reason code of first error * @userdata2 bytes 0-1: total number of elogs included * bytes 2-3: N/A * @devdesc call to cen_switch_attn failed. * see * error identified by the plid in user data * field. */ l_stepError.addErrorDetails( ISTEP_PROC_REC_ATTN_FAILED, ISTEP_HOST_IPL_COMPLETE, l_err ); errlCommit( l_err, HWPF_COMP_ID ); } else { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "SUCCESS: proc_switch_rec_attn HWP( )" ); } } // endfor // check if any errors were collected above. If so, drop out here. if ( !l_stepError.isNull() ) { break; } //If Sapphire Payload need to set payload base to zero if (is_sapphire_load()) { TARGETING::Target* sys = NULL; TARGETING::targetService().getTopLevelTarget(sys); assert( sys != NULL ); sys->setAttr(0x0); } // Sync attributes to Fsp l_err = syncAllAttributesToFsp(); if( l_err ) { break; } // Send Sync Point to Fsp TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, INFO_MRK"Send SYNC_POINT_REACHED msg to Fsp" ); l_err = INITSERVICE::sendSyncPoint(); } while( 0 ); if( l_err ) { // collect and log any remaining errors /*@ * @errortype * @reasoncode ISTEP_CORE_ACTIVATE_FAILED * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE * @moduleid ISTEP_HOST_IPL_COMPLETE * @userdata1 bytes 0-1: plid identifying first error * bytes 2-3: reason code of first error * @userdata2 bytes 0-1: total number of elogs included * bytes 2-3: N/A * @devdesc call to host_ipl_complete failed see * error identified by the plid in user data * field. */ l_stepError.addErrorDetails(ISTEP_CORE_ACTIVATE_FAILED, ISTEP_HOST_IPL_COMPLETE, l_err ); errlCommit( l_err, HWPF_COMP_ID ); } TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_ipl_complete exit "); // end task, returning any errorlogs to IStepDisp return l_stepError.getErrorHandle(); } }; // end namespace