/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/usr/isteps/istep10/call_proc_build_smp.C $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2015,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ /* You may obtain a copy of the License at */ /* */ /* http://www.apache.org/licenses/LICENSE-2.0 */ /* */ /* Unless required by applicable law or agreed to in writing, software */ /* distributed under the License is distributed on an "AS IS" BASIS, */ /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ /* implied. See the License for the specific language governing */ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ #include #include #include #include #include #include // targeting support #include #include #include #include #include #include #include #include //@TODO RTC:150562 - Remove when BAR setting handled by INTRRP #include #include #include #include #include using namespace ISTEP_ERROR; using namespace ISTEP; using namespace TARGETING; using namespace ERRORLOG; namespace ISTEP_10 { void* call_proc_build_smp (void *io_pArgs) { IStepError l_StepError; do { errlHndl_t l_errl = nullptr; TARGETING::TargetHandleList l_cpuTargetList; getAllChips(l_cpuTargetList, TYPE_PROC); // // Identify the master processor // TARGETING::Target * l_masterProc = nullptr; TARGETING::Target * l_masterNode = nullptr; bool l_onlyFunctional = true; // Make sure masterproc is functional l_errl = TARGETING::targetService().queryMasterProcChipTargetHandle( l_masterProc, l_masterNode, l_onlyFunctional); if(l_errl) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "ERROR : call_proc_build_smp: " "queryMasterProcChipTargetHandle() returned PLID=0x%x", l_errl->plid() ); // Create IStep error log and cross reference error that occurred l_StepError.addErrorDetails(l_errl); // Commit error errlCommit( l_errl, HWPF_COMP_ID ); break; } std::vector> l_procList; // Loop through all proc chips and convert them to FAPI targets for (const auto & curproc: l_cpuTargetList) { const fapi2::Target l_fapi2_proc_target (curproc); l_procList.push_back(l_fapi2_proc_target); } TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_proc_build_smp entry" ); const fapi2::Target l_fapi2_master_proc (l_masterProc); FAPI_INVOKE_HWP( l_errl, p9_build_smp, l_procList, l_fapi2_master_proc, SMP_ACTIVATE_PHASE1 ); if(l_errl) { TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "ERROR : call p9_build_smp, PLID=0x%x", l_errl->plid() ); // Create IStep error log and cross reference error that occurred l_StepError.addErrorDetails(l_errl); // Commit error errlCommit( l_errl, HWPF_COMP_ID ); break; } // At the point where we can now change the proc chips to use // XSCOM rather than SBESCOM which is the default. TARGETING::TargetHandleList procChips; getAllChips(procChips, TYPE_PROC); TARGETING::TargetHandleList::iterator curproc = procChips.begin(); // Loop through all proc chips while(curproc != procChips.end()) { TARGETING::Target* l_proc_target = *curproc; // If the proc chip supports xscom.. if (l_proc_target->getAttr() .supportsXscom) { ScomSwitches l_switches = l_proc_target->getAttr(); // If Xscom is not already enabled. if ((l_switches.useXscom != 1) || (l_switches.useSbeScom != 0)) { l_switches.useSbeScom = 0; l_switches.useXscom = 1; // Turn off SBE scom and turn on Xscom. l_proc_target->setAttr(l_switches); // Reset the FSI2OPB logic on the new chips l_errl = FSI::resetPib2Opb(l_proc_target); if(l_errl) { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "ERROR : resetPib2Opb on %.8X", TARGETING::get_huid(l_proc_target)); // Create IStep error log and // cross reference error that occurred l_StepError.addErrorDetails(l_errl); // Commit error errlCommit( l_errl, HWPF_COMP_ID ); break; } } } if (l_proc_target != l_masterProc) { //Enable PSIHB Interrupts for slave proc -- moved from above l_errl = INTR::enablePsiIntr(l_proc_target); if(l_errl) { // capture the target data in the elog ErrlUserDetailsTarget(l_proc_target).addToLog( l_errl ); l_StepError.addErrorDetails(l_errl); errlCommit( l_errl, HWPF_COMP_ID ); break; } // Now that the SMP is connected, it's possible to establish // untrusted memory windows for non-master processor SBEs. Open // up the Hostboot read-only memory range for each one to allow // Hostboot dumps / attention handling via any processor chip. const auto hbHrmor = cpu_spr_value(CPU_SPR_HRMOR); l_errl = SBEIO::openUnsecureMemRegion( hbHrmor, VMM_MEMORY_SIZE, false, // False = read-only l_proc_target); if(l_errl) { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, ERR_MRK "Failed attempting to open Hostboot's " "VMM region in SBE of non-master processor chip " "with HUID=0x%08X. Requested address=0x%016llX, " "size=0x%08X", TARGETING::get_huid(l_proc_target), hbHrmor,VMM_MEMORY_SIZE); ErrlUserDetailsTarget(l_proc_target).addToLog(l_errl); l_StepError.addErrorDetails(l_errl); errlCommit(l_errl,HWPF_COMP_ID); break; } } // Clear XBUS FIR bits for bad lanes that existed prior to // link training TARGETING::TargetHandleList xbusTargets; getChildChiplets(xbusTargets, *curproc, TYPE_XBUS); for(auto pXbusTarget : xbusTargets) { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "Calling p9_io_xbus_erepair_cleanup HWP for XBUS with " "HUID of 0x%08X", TARGETING::get_huid(pXbusTarget)); const fapi2::Target fapi2_xbus(pXbusTarget); FAPI_INVOKE_HWP(l_errl, p9_io_xbus_erepair_cleanup, fapi2_xbus); if(l_errl) { TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, ERR_MRK "ERROR : Call to p9_io_xbus_erepair_cleanup HWP " "for XBUS with HUID of 0x%08X failed. " "PLID=0x%08X, EID=0x%08X, Reason=0x%04X", TARGETING::get_huid(pXbusTarget), l_errl->plid(), l_errl->eid(), l_errl->reasonCode()); ErrlUserDetailsTarget(pXbusTarget).addToLog(l_errl); l_StepError.addErrorDetails(l_errl); errlCommit(l_errl,HWPF_COMP_ID); } } ++curproc; } // Set a flag so that the ATTN code will check ALL processors // the next time it gets called versus just the master proc. uint8_t l_useAllProcs = 1; TARGETING::Target *l_sys = NULL; TARGETING::targetService().getTopLevelTarget( l_sys ); assert(l_sys != NULL); l_sys->setAttr(l_useAllProcs); } while (0); TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_proc_build_smp exit" ); // end task, returning any errorlogs to IStepDisp return l_StepError.getErrorHandle(); } };