diff options
| author | Corey Swenson <cswenson@us.ibm.com> | 2017-04-25 09:47:34 -0500 |
|---|---|---|
| committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-04-28 14:14:12 -0400 |
| commit | 2a1c0da1e1766caab280528cfa4c74433718c081 (patch) | |
| tree | 1ee0b5a137d9a53e8d75678ebfc316d92467b913 | |
| parent | 38bb2df0d99cbd6235f43ef44ebbe205e6b5f900 (diff) | |
| download | blackbird-hostboot-2a1c0da1e1766caab280528cfa4c74433718c081.tar.gz blackbird-hostboot-2a1c0da1e1766caab280528cfa4c74433718c081.zip | |
Handle SMT4/SMT8 fuse bits
Change-Id: I8fc108877714ff76103510b7801af72a94e5aae3
RTC:160720
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/39778
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Martin Gloff <mgloff@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
| -rw-r--r-- | src/include/arch/pvrformat.H | 2 | ||||
| -rw-r--r-- | src/include/usr/isteps/istep_reasoncodes.H | 1 | ||||
| -rw-r--r-- | src/usr/isteps/istep06/thread_activate/thread_activate.C | 260 | ||||
| -rw-r--r-- | src/usr/targeting/common/util.C | 57 |
4 files changed, 273 insertions, 47 deletions
diff --git a/src/include/arch/pvrformat.H b/src/include/arch/pvrformat.H index 7915891fe..0e1c462b8 100644 --- a/src/include/arch/pvrformat.H +++ b/src/include/arch/pvrformat.H @@ -123,6 +123,8 @@ struct PVR_t // Field: smt SMT8_MODE = 0, SMT4_MODE = 1, + SMT_MASK = 0x00001000, + SMT_SHIFT = 12, // Field: chipFamily P8_MURANO = 0x4B, diff --git a/src/include/usr/isteps/istep_reasoncodes.H b/src/include/usr/isteps/istep_reasoncodes.H index a3e019c3a..8b588ba14 100644 --- a/src/include/usr/isteps/istep_reasoncodes.H +++ b/src/include/usr/isteps/istep_reasoncodes.H @@ -93,6 +93,7 @@ namespace ISTEP RC_PM_OCC_CHKPT_TIMEOUT = ISTEP_COMP_ID | 0x1C, RC_UPDATE_SECURITY_CTRL_HWP_FAIL = ISTEP_COMP_ID | 0x1D, RC_NO_FUNCTIONAL_MEMORY = ISTEP_COMP_ID | 0x1E, + RC_NO_FUSED_CORE_TARGET = ISTEP_COMP_ID | 0x1F, }; }; diff --git a/src/usr/isteps/istep06/thread_activate/thread_activate.C b/src/usr/isteps/istep06/thread_activate/thread_activate.C index e94a73063..26d374ef7 100644 --- a/src/usr/isteps/istep06/thread_activate/thread_activate.C +++ b/src/usr/isteps/istep06/thread_activate/thread_activate.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -42,13 +42,16 @@ #include <devicefw/userif.H> #include <sys/misc.h> #include <sys/mm.h> +#include <sys/mmio.h> #include <p9_thread_control.H> #include <arch/pirformat.H> +#include <arch/pvrformat.H> // targeting support #include <targeting/common/target.H> #include <targeting/common/commontargeting.H> #include <targeting/common/utilFilter.H> +#include <targeting/common/util.H> // fapi support #include <fapi2.H> @@ -65,6 +68,8 @@ namespace THREAD_ACTIVATE { +const uint64_t SMT8_ENABLE_THREADS_MASK = 0xC000000000000000; + /** * @brief This function will query MVPD and figure out if the master * core has a fully configured cache or not.. @@ -239,6 +244,11 @@ void activate_threads( errlHndl_t& io_rtaskRetErrl ) TRACFCOMP( g_fapiTd, "activate_threads entry" ); + // get the sys target + TARGETING::Target* sys = NULL; + TARGETING::targetService().getTopLevelTarget(sys); + assert( sys != NULL ); + // get the master processor target TARGETING::Target* l_masterProc = NULL; TARGETING::targetService().masterProcChipTargetHandle( l_masterProc ); @@ -256,32 +266,61 @@ void activate_threads( errlHndl_t& io_rtaskRetErrl ) TARGETING::TYPE_CORE, false); - // find the core/thread we're running on - task_affinity_pin(); - task_affinity_migrate_to_master(); //just in case... - uint64_t cpuid = task_getcpuid(); - task_affinity_unpin(); - - uint64_t l_masterCoreID = PIR_t::coreFromPir(cpuid); - uint64_t l_masterThreadID = PIR_t::threadFromPir(cpuid); - - const TARGETING::Target* l_masterCore = NULL; - for( TARGETING::TargetHandleList::const_iterator - core_it = l_coreTargetList.begin(); - core_it != l_coreTargetList.end(); - ++core_it ) + // set the fused core mode attribute + bool l_smt8 = false; + uint32_t l_pvr = mmio_pvr_read() & 0xFFFFFFFF; + if( (l_pvr & PVR_t::CHIP_DD_MASK) == PVR_t::IS_NIMBUS_DD1 ) { - TARGETING::ATTR_CHIP_UNIT_type l_coreId = - (*core_it)->getAttr<TARGETING::ATTR_CHIP_UNIT>(); - if( l_coreId == l_masterCoreID ) + sys->setAttr<TARGETING::ATTR_FUSED_CORE_MODE> + (TARGETING::FUSED_CORE_MODE_SMT4_DEFAULT); + } + else + { + uint32_t l_smt = (l_pvr & PVR_t::SMT_MASK) >> PVR_t::SMT_SHIFT; + if( l_smt == PVR_t::SMT4_MODE ) { - l_masterCore = (*core_it); - break; + sys->setAttr<TARGETING::ATTR_FUSED_CORE_MODE> + (TARGETING::FUSED_CORE_MODE_SMT4_ONLY); + } + else // SMT8_MODE + { + sys->setAttr<TARGETING::ATTR_FUSED_CORE_MODE> + (TARGETING::FUSED_CORE_MODE_SMT8_ONLY); + l_smt8 = true; } } do { + // ----------------------------------- + // Activate threads on the master core + // ----------------------------------- + + // find the core/thread we're running on + task_affinity_pin(); + task_affinity_migrate_to_master(); //just in case... + uint64_t cpuid = task_getcpuid(); + task_affinity_unpin(); + + uint64_t l_masterCoreID = PIR_t::coreFromPir(cpuid); + uint64_t l_masterThreadID = PIR_t::threadFromPir(cpuid); + + // find the master core + const TARGETING::Target* l_masterCore = NULL; + for( TARGETING::TargetHandleList::const_iterator + core_it = l_coreTargetList.begin(); + core_it != l_coreTargetList.end(); + ++core_it ) + { + TARGETING::ATTR_CHIP_UNIT_type l_coreId = + (*core_it)->getAttr<TARGETING::ATTR_CHIP_UNIT>(); + if( l_coreId == l_masterCoreID ) + { + l_masterCore = (*core_it); + break; + } + } + if( l_masterCore == NULL ) { TRACFCOMP( g_fapiImpTd, @@ -316,16 +355,22 @@ void activate_threads( errlHndl_t& io_rtaskRetErrl ) TARGETING::get_huid(l_masterCore) ); // cast OUR type of target to a FAPI type of target. - const fapi2::Target<fapi2::TARGET_TYPE_CORE>& l_fapiCore = + const fapi2::Target<fapi2::TARGET_TYPE_CORE>& l_fapiCore0 = (const_cast<TARGETING::Target*>(l_masterCore)); // AVPs might enable a subset of the available threads uint64_t max_threads = cpu_thread_count(); - TARGETING::Target* sys = NULL; - TARGETING::targetService().getTopLevelTarget(sys); - assert( sys != NULL ); - uint64_t en_threads = sys->getAttr<TARGETING::ATTR_ENABLED_THREADS>(); - + uint64_t en_threads_master = + sys->getAttr<TARGETING::ATTR_ENABLED_THREADS>(); + + // Core0_thread: 0 1 2 3 Core1_thread: 0 1 2 3 + // NORMAL - E E E - - - - + // FUSED - E - - E E - - + // * E=enable, Core0_t0=master already enabled + if( l_smt8 ) + { + en_threads_master &= SMT8_ENABLE_THREADS_MASK; + } // -------------------------------------------------------------------- //Enable the special wake-up on master core @@ -346,10 +391,9 @@ void activate_threads( errlHndl_t& io_rtaskRetErrl ) } FAPI_INVOKE_HWP(l_errl, p9_cpu_special_wakeup_core, - l_fapiCore, + l_fapiCore0, p9specialWakeup::SPCWKUP_ENABLE, p9specialWakeup::HOST); - if(l_errl) { TRACFCOMP( g_fapiImpTd, @@ -359,9 +403,9 @@ void activate_threads( errlHndl_t& io_rtaskRetErrl ) break; } - TRACDCOMP( g_fapiTd, - "activate_threads max_threads=%d, en_threads=0x%016X", - max_threads, en_threads ); + TRACFCOMP( g_fapiTd, + "activate_threads max_threads=%d, en_threads_master=0x%016X", + max_threads, en_threads_master ); uint8_t thread_bitset = 0; for( uint64_t thread = 0; thread < max_threads; thread++ ) @@ -376,7 +420,7 @@ void activate_threads( errlHndl_t& io_rtaskRetErrl ) } // Skip threads that we shouldn't be starting - if(!(en_threads & (0x8000000000000000>>thread))) + if(!(en_threads_master & (0x8000000000000000>>thread))) { TRACDCOMP( g_fapiTd, "activate_threads skipping thread=%d", thread ); @@ -414,7 +458,7 @@ void activate_threads( errlHndl_t& io_rtaskRetErrl ) fapi2::buffer<uint64_t> l_rasStatus = 0; uint64_t l_threadState = 0; FAPI_INVOKE_HWP( l_errl, p9_thread_control, - l_fapiCore, //i_target + l_fapiCore0, //i_target thread_bitset, //i_threads PTC_CMD_SRESET, //i_command false, //i_warncheck @@ -446,6 +490,154 @@ void activate_threads( errlHndl_t& io_rtaskRetErrl ) break; } + // ----------------------------------------- + // Activate threads on the master-fused core + // ----------------------------------------- + + if( l_smt8 ) + { + uint64_t l_fusedCoreID = l_masterCoreID + 1; + + // find the master-fused core + const TARGETING::Target* l_fusedCore = NULL; + for( TARGETING::TargetHandleList::const_iterator + core_it = l_coreTargetList.begin(); + core_it != l_coreTargetList.end(); + ++core_it ) + { + TARGETING::ATTR_CHIP_UNIT_type l_coreId = + (*core_it)->getAttr<TARGETING::ATTR_CHIP_UNIT>(); + if( l_coreId == l_fusedCoreID ) + { + l_fusedCore = (*core_it); + break; + } + } + + if( l_fusedCore == NULL ) + { + TRACFCOMP( g_fapiImpTd, + "Could not find a target for core %d", + l_fusedCoreID ); + /*@ + * @errortype + * @moduleid ISTEP::MOD_THREAD_ACTIVATE + * @reasoncode ISTEP::RC_NO_FUSED_CORE_TARGET + * @userdata1 Master-fused core id + * @userdata2 Master-fused processor chip huid + * @devdesc activate_threads> Could not find a target + * for the master-fused core + * @custdesc A problem occurred during the IPL + * of the system. + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + ISTEP::MOD_THREAD_ACTIVATE, + ISTEP::RC_NO_FUSED_CORE_TARGET, + l_fusedCoreID, + TARGETING::get_huid(l_masterProc)); + l_errl->collectTrace("TARG",256); + l_errl->collectTrace(FAPI_TRACE_NAME,256); + l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256); + + break; + } + + TRACFCOMP( g_fapiTd, + "Master-Fused CPU : c%d (HUID=%.8X)", + l_fusedCoreID, TARGETING::get_huid(l_fusedCore) ); + + // cast OUR type of target to a FAPI type of target. + const fapi2::Target<fapi2::TARGET_TYPE_CORE>& l_fapiCore1 = + (const_cast<TARGETING::Target*>(l_fusedCore)); + + uint64_t en_threads_c1 = SMT8_ENABLE_THREADS_MASK; + + // ------------------------------------------------------------- + //Enable the special wake-up on master-fused core + FAPI_INF("Enable special wake-up on master-fused core"); + + FAPI_INVOKE_HWP(l_errl, p9_cpu_special_wakeup_core, + l_fapiCore1, + p9specialWakeup::SPCWKUP_ENABLE, + p9specialWakeup::HOST); + if(l_errl) + { + TRACFCOMP( g_fapiImpTd, + "ERROR: 0x%.8X : " + "p9_cpu_special_wakeup_core set HWP(cpu %d)", + l_errl->reasonCode(), + l_masterCoreID); + break; + } + + TRACFCOMP( g_fapiTd, + "activate_threads max_threads=%d, en_threads_c1=0x%016X", + max_threads, en_threads_c1 ); + + thread_bitset = 0; + for( uint64_t thread = 0; thread < max_threads; thread++ ) + { + // Skip threads that we shouldn't be starting + if(!(en_threads_c1 & (0x8000000000000000>>thread))) + { + TRACDCOMP( g_fapiTd, + "activate_threads skipping thread=%d", thread ); + + continue; + } + else + { + TRACFCOMP( g_fapiTd, + "activate_threads enabling thread=%d", thread ); + + thread_bitset |= fapi2::thread_id2bitset(thread); + + } + } + + // send a magic instruction for PHYP Simics to work... + MAGIC_INSTRUCTION(MAGIC_SIMICS_CORESTATESAVE); + + // see HWP call above for parameter definitions + l_rasStatus = 0; + l_threadState = 0; + FAPI_INVOKE_HWP( l_errl, p9_thread_control, + l_fapiCore1, //i_target + thread_bitset, //i_threads + PTC_CMD_SRESET, //i_command + false, //i_warncheck + l_rasStatus, //o_rasStatusReg + l_threadState); //o_state + + if ( l_errl != NULL ) + { + TRACFCOMP( g_fapiImpTd, + "ERROR: 0x%.8X : proc_thread_control HWP" + "( cpu %d, thread_bitset 0x%02X, " + "l_rasStatus 0x%lx )", + l_errl->reasonCode(), + l_masterCoreID, + thread_bitset, + l_rasStatus ); + } + else + { + TRACFCOMP(g_fapiTd, + "SUCCESS: p9_thread_control HWP" + "( cpu %d, thread_bitset 0x%02X )", + l_masterCoreID, + thread_bitset ); + } + + if(l_errl) + { + break; + } + + } // end if( l_smt8 ) + + //Check if we are in MPIPL uint8_t is_mpipl = 0; sys->tryGetAttr<TARGETING::ATTR_IS_MPIPL_HB>(is_mpipl); @@ -454,7 +646,7 @@ void activate_threads( errlHndl_t& io_rtaskRetErrl ) { TRACFCOMP( g_fapiTd, "activate_threads: We are in MPIPL, extending cache to be real memory" ); - mm_extend(MM_EXTEND_REAL_MEMORY); + mm_extend(MM_EXTEND_REAL_MEMORY); } // Reclaim remainder of L3 cache if available. else if ((!PNOR::usingL3Cache()) && diff --git a/src/usr/targeting/common/util.C b/src/usr/targeting/common/util.C index 80e4147b8..92fec0365 100644 --- a/src/usr/targeting/common/util.C +++ b/src/usr/targeting/common/util.C @@ -306,32 +306,63 @@ uint8_t is_fused_mode( ) TARGETING::Target * sys = NULL; TARGETING::targetService().getTopLevelTarget( sys ); assert(sys != NULL); - TARGETING::PAYLOAD_KIND l_payload = sys->getAttr<ATTR_PAYLOAD_KIND>(); - uint8_t l_attrValue = sys->getAttr<ATTR_FUSED_CORE_OPTION>(); + /* + Fused Mode - if (FUSED_CORE_OPTION_USING_DEFAULT_CORES == l_attrValue) + ATTR_FUSED_CORE_MODE / ATTR_FUSED_CORE_OPTION / ATTR_PAYLOAD_KIND + + smt4_default / default_cores / phyp --> fused + smt4_default / default_cores / opal --> notfused + smt4_default / normal_cores / * --> notfused + smt4_default / fused_cores / * --> fused + + smt4_only / default_cores / * --> notfused + smt4_only / normal_cores / * --> notfused + smt4_only / fused_cores / * --> fused + + smt8_only / default_cores / * --> fused + smt8_only / normal_cores / * --> notfused + smt8_only / fused_cores / * --> fused + */ + + uint8_t l_mode = sys->getAttr<ATTR_FUSED_CORE_MODE>();; + uint8_t l_option = sys->getAttr<ATTR_FUSED_CORE_OPTION>();; + PAYLOAD_KIND l_payload = sys->getAttr<ATTR_PAYLOAD_KIND>(); + + if (FUSED_CORE_OPTION_USING_DEFAULT_CORES == l_option) { - // if payload is PHYP, use FUSED mode - // Anything else, use NORMAL mode - if (PAYLOAD_KIND_PHYP == l_payload) + if (FUSED_CORE_MODE_SMT4_DEFAULT == l_mode) { - l_fused = true; + if (PAYLOAD_KIND_PHYP == l_payload) + { + l_fused = true; + } + else + { + l_fused = false; + } } - else + else if (FUSED_CORE_MODE_SMT4_ONLY == l_mode) { l_fused = false; } + else // SMT8_ONLY + { + l_fused = true; + } } - else + else if (FUSED_CORE_OPTION_USING_NORMAL_CORES == l_option) { - l_fused = (l_attrValue == FUSED_CORE_OPTION_USING_NORMAL_CORES) ? - false : true; + l_fused = false; + } + else // USING_FUSED_CORES + { + l_fused = true; } - return(l_fused); } // end is_fused_mode -} +} // end namespace TARGETING |

