From c1119f46316546d97d3b9de5f88f88c5df3cca6b Mon Sep 17 00:00:00 2001 From: Corey Swenson Date: Fri, 12 Aug 2016 10:27:46 -0500 Subject: Special wakeup updates for P9 Change-Id: Id60773a1a84ee856265e451925b7f7c8c15a8af1 RTC:132413 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29665 Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Reviewed-by: Christian R. Geddes Reviewed-by: Daniel M. Crowell --- src/usr/scom/runtime/handleSpecialWakeup.C | 282 +++++++++++++++++++++++++---- src/usr/scom/runtime/handleSpecialWakeup.H | 14 +- src/usr/scom/runtime/makefile | 5 + src/usr/scom/scomtrans.C | 10 +- 4 files changed, 268 insertions(+), 43 deletions(-) (limited to 'src/usr/scom') diff --git a/src/usr/scom/runtime/handleSpecialWakeup.C b/src/usr/scom/runtime/handleSpecialWakeup.C index c41e922d5..0827c7054 100644 --- a/src/usr/scom/runtime/handleSpecialWakeup.C +++ b/src/usr/scom/runtime/handleSpecialWakeup.C @@ -24,8 +24,8 @@ /* IBM_PROLOG_END_TAG */ #include #include +#include #include - #include #include @@ -33,6 +33,13 @@ #include #include +#include +#include +#include +#include + +#include +#include extern "C" { @@ -41,49 +48,262 @@ extern "C" extern trace_desc_t* g_trac_scom; using namespace TARGETING; +using namespace SCOM; -errlHndl_t handleSpecialWakeup(TARGETING::Target* i_exTarget, - bool i_enableDisable) +/** + * @brief Enable and disable special wakeup for SCOM operations + * FSP: Call the Host interface wakeup function for all core + * targets under the specified target, HOST wakeup bit is used + * BMC: Call the wakeup HWP for the target type specified (EQ/EX/CORE), + * Proc type calls the HWP for all cores, FSP wakeup bit is used + */ +errlHndl_t handleSpecialWakeup(TARGETING::Target* i_target, bool i_enable) { errlHndl_t l_errl = NULL; - //@TODO RTC:132413 Add it back once we have fapi2 support -#if 0 - fapi::Target l_fapi_ex_target(TARGET_TYPE_EX_CHIPLET, - (const_cast(i_exTarget)) ); + TARGETING::TYPE l_type = i_target->getAttr(); - PROC_SPCWKUP_OPS l_spcwkupType; - if(i_enableDisable) + // FSP + if(INITSERVICE::spBaseServicesEnabled()) { - l_spcwkupType = SPCWKUP_ENABLE; + // Check for valid interface function + if( g_hostInterfaces == NULL || + g_hostInterfaces->wakeup == NULL ) + { + TRACFCOMP( g_trac_scom, + ERR_MRK"Hypervisor wakeup interface not linked"); + + /*@ + * @errortype + * @moduleid SCOM_HANDLE_SPECIAL_WAKEUP + * @reasoncode SCOM_RUNTIME_INTERFACE_ERR + * @userdata1 Target HUID + * @userdata2 Wakeup Enable + * @devdesc Wakeup runtime interface not linked. + */ + l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL, + SCOM_HANDLE_SPECIAL_WAKEUP, + SCOM_RUNTIME_INTERFACE_ERR, + get_huid(i_target), + i_enable); + + l_errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_HIGH); + + return l_errl; + } + + TargetHandleList pCoreList; + + // If the target is already a core just push it on the list + if(l_type == TARGETING::TYPE_CORE) + { + pCoreList.clear(); + pCoreList.push_back(i_target); + } + else + { + getChildChiplets( pCoreList, i_target, TARGETING::TYPE_CORE ); + } + + // Call wakeup on all core targets + // Wakeup may be called twice for fused cores + for ( auto pCore_it = pCoreList.begin(); + pCore_it != pCoreList.end(); + ++pCore_it ) + { + // Runtime target id + RT_TARG::rtChipId_t rtTargetId = 0; + l_errl = RT_TARG::getRtTarget(*pCore_it, rtTargetId); + if(l_errl) + { + break; + } + + uint32_t mode; + if(i_enable) + { + mode = HBRT_WKUP_FORCE_AWAKE; + } + else + { + mode = HBRT_WKUP_CLEAR_FORCE; + } + + // Do the special wakeup + int l_rc = g_hostInterfaces->wakeup(rtTargetId,mode); + + if(l_rc) + { + TRACFCOMP( g_trac_scom,ERR_MRK + "Hypervisor wakeup failed. " + "rc 0x%X target_huid 0x%llX rt_target_id 0x%llX mode %d", + l_rc, get_huid(*pCore_it), rtTargetId, mode ); + + // convert rc to error log + /*@ + * @errortype + * @moduleid SCOM_HANDLE_SPECIAL_WAKEUP + * @reasoncode SCOM_RUNTIME_WAKEUP_ERR + * @userdata1 Hypervisor return code + * @userdata2[0:31] Runtime Target ID + * @userdata2[32:63] Wakeup Mode + * @devdesc Hypervisor wakeup failed. + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + SCOM_HANDLE_SPECIAL_WAKEUP, + SCOM_RUNTIME_WAKEUP_ERR, + l_rc, + TWO_UINT32_TO_UINT64( + rtTargetId, mode)); + + l_errl->addHwCallout(i_target, + HWAS::SRCI_PRIORITY_LOW, + HWAS::NO_DECONFIG, + HWAS::GARD_NULL); + + break; + } + } } + + // BMC else { - l_spcwkupType = SPCWKUP_DISABLE; - } + if(l_type == TARGETING::TYPE_PROC) + { + // Call wakeup on all core targets + TargetHandleList pCoreList; + getChildChiplets( pCoreList, i_target, TARGETING::TYPE_CORE ); - //Using the FSP bit so it doesn't collide with Sapphire. - //There are 3 independent registers used to trigger a special wakeup - //(FSP,HOST,OCC). Since this is in HBRT, Opal already owns the HOST - //register, so we're using the FSP bit here. - FAPI_INVOKE_HWP(l_errl, - p8_cpu_special_wakeup, - l_fapi_ex_target, - l_spcwkupType, - FSP); - - if(l_errl) - { - TRACFCOMP( g_trac_scom, - "Disable p8_cpu_special_wakeup ERROR :" - " Returning errorlog, reason=0x%x", - l_errl->reasonCode() ); + for ( auto pCore_it = pCoreList.begin(); + pCore_it != pCoreList.end(); + ++pCore_it ) + { + // To simplify, just call recursively with the core target + l_errl = handleSpecialWakeup(*pCore_it, i_enable); + if(l_errl) + { + break; + } + } + return l_errl; + } + + // Need to handle multiple calls to enable special wakeup + // Count attribute will keep track and disable when zero + // Assume HBRT is single-threaded, so no issues with concurrency + uint32_t l_count = (i_target)->getAttr(); + + if((l_count==0) && !i_enable) + { + TRACFCOMP( g_trac_scom,ERR_MRK + "Disabling special wakeup on target with SPCWKUP_COUNT=0"); + + /*@ + * @errortype + * @moduleid SCOM_HANDLE_SPECIAL_WAKEUP + * @reasoncode SCOM_RUNTIME_SPCWKUP_COUNT_ERR + * @userdata1 Target HUID + * @userdata2[0:31] Wakeup Enable + * @userdata2[32:63] Wakeup Count + * @devdesc Disabling special wakeup when not enabled. + */ + l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL, + SCOM_HANDLE_SPECIAL_WAKEUP, + SCOM_RUNTIME_SPCWKUP_COUNT_ERR, + get_huid(i_target), + TWO_UINT32_TO_UINT64( + i_enable, l_count)); + + l_errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_LOW); + + errlCommit( l_errl, RUNTIME_COMP_ID ); + } + + // Only call the HWP if 0-->1 or 1-->0 + if( ((l_count==0) && i_enable) || + ((l_count==1) && !i_enable) ) + { + // NOTE Regarding the entity type passed to the HWP: + // There are 3 independent registers used to trigger a + // special wakeup (FSP,HOST,OCC), we are using the FSP + // bit because HOST/OCC are already in use. + + p9specialWakeup::PROC_SPCWKUP_OPS l_spcwkupType; + if(i_enable) + { + l_spcwkupType = p9specialWakeup::SPCWKUP_ENABLE; + } + else + { + l_spcwkupType = p9specialWakeup::SPCWKUP_DISABLE; + } - // capture the target data in the elog - ERRORLOG::ErrlUserDetailsTarget(i_exTarget).addToLog( l_errl ); + if(l_type == TARGETING::TYPE_EQ) + { + fapi2::Target + l_fapi_target(const_cast(i_target)); + + FAPI_INVOKE_HWP( l_errl, + p9_cpu_special_wakeup_eq, + l_fapi_target, + l_spcwkupType, + p9specialWakeup::FSP ); + } + else if(l_type == TARGETING::TYPE_EX) + { + fapi2::Target + l_fapi_target(const_cast(i_target)); + + FAPI_INVOKE_HWP( l_errl, + p9_cpu_special_wakeup_ex, + l_fapi_target, + l_spcwkupType, + p9specialWakeup::FSP ); + } + else if(l_type == TARGETING::TYPE_CORE) + { + fapi2::Target + l_fapi_target(const_cast(i_target)); + + FAPI_INVOKE_HWP( l_errl, + p9_cpu_special_wakeup_core, + l_fapi_target, + l_spcwkupType, + p9specialWakeup::FSP ); + } + + if(l_errl) + { + TRACFCOMP( g_trac_scom, + "p9_cpu_special_wakeup ERROR :" + " Returning errorlog, reason=0x%x", + l_errl->reasonCode() ); + + // Capture the target data in the elog + ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog( l_errl ); + } + } + + // Update the counter + if(!l_errl) + { + if(i_enable) + { + l_count++; + } + else + { + l_count--; + } + i_target->setAttr(l_count); + } } -#endif return l_errl; } + } diff --git a/src/usr/scom/runtime/handleSpecialWakeup.H b/src/usr/scom/runtime/handleSpecialWakeup.H index 3090fa4d1..43d05f246 100644 --- a/src/usr/scom/runtime/handleSpecialWakeup.H +++ b/src/usr/scom/runtime/handleSpecialWakeup.H @@ -1,11 +1,11 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/usr/scom/disableSW.H $ */ +/* $Source: src/usr/scom/runtime/handleSpecialWakeup.H $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2015 */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -33,13 +33,13 @@ extern "C" * @brief This function handles the enable and disable of the special * wakeup that allows scom operations on idle cores. * - * @param[in] i_exTarget - EX Target core - * @param[in] i_enableDisable - enable (true), disable (false) + * @param[in] i_target - EQ/EX/Core target + * @param[in] i_enable - enable (true), disable (false) * - * @return errlHndl_t - error handle + * @return errlHndl_t - error handle */ -errlHndl_t handleSpecialWakeup(TARGETING::Target* i_exTarget, - bool i_enableDisable); +errlHndl_t handleSpecialWakeup(TARGETING::Target* i_target, bool i_enable); + } #endif diff --git a/src/usr/scom/runtime/makefile b/src/usr/scom/runtime/makefile index 3397a82d8..d58066ec1 100644 --- a/src/usr/scom/runtime/makefile +++ b/src/usr/scom/runtime/makefile @@ -29,6 +29,11 @@ MODULE = scom_rt #include common ojects between hostboot and runtime hostboot include ../scom.mk +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/pm/ +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/imageProcs/ +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/ffdc/ +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2/ + #include unique object modules - currently none OBJS += handleSpecialWakeup.o diff --git a/src/usr/scom/scomtrans.C b/src/usr/scom/scomtrans.C index 48ceb5724..9fab4d1ec 100644 --- a/src/usr/scom/scomtrans.C +++ b/src/usr/scom/scomtrans.C @@ -310,11 +310,11 @@ errlHndl_t p9_translation (TARGETING::Target * &i_target, #if __HOSTBOOT_RUNTIME - //true => FSP present, false =>OP HBRT - bool isFSP_HBRT = INITSERVICE::spBaseServicesEnabled(); - - if(((i_type == TARGETING::TYPE_EX) || (i_type == TARGETING::TYPE_CORE)) && - (!g_wakeupInProgress) && (!isFSP_HBRT) && !(i_opMode & fapi2::DO_NOT_DO_WAKEUP) ) + if(((i_type == TARGETING::TYPE_EQ) || + (i_type == TARGETING::TYPE_EX) || + (i_type == TARGETING::TYPE_CORE)) && + (!g_wakeupInProgress) && + !(i_opMode & fapi2::DO_NOT_DO_WAKEUP) ) { TRACFCOMP(g_trac_scom,"Determining if Special Wakeup is needed.."); bool l_needsWakeup = true; -- cgit v1.2.1