From 27c01047205d6c64b89f1df0dc5952a202bee792 Mon Sep 17 00:00:00 2001 From: Matt Derksen Date: Tue, 17 Jul 2018 13:46:00 -0500 Subject: Use hostservice to do special wakeup at runtime for open-power systems Currently HB uses FSP register at runtime to do special wakeup in open-power systems. It prevents pdbg or sbe from using that register. HB should shift to hostservices to do special wakeup. Change-Id: I79db6583550f69e4f19e6f4101237f6140ccb07c CQ:SW437887 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/62677 Tested-by: Jenkins Server Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Tested-by: FSP CI Jenkins Reviewed-by: Christian R. Geddes Reviewed-by: Richard Ward Reviewed-by: Daniel M. Crowell --- src/usr/scom/handleSpecialWakeup.C | 426 ++++++++++++++++++------------------- 1 file changed, 211 insertions(+), 215 deletions(-) (limited to 'src/usr/scom') diff --git a/src/usr/scom/handleSpecialWakeup.C b/src/usr/scom/handleSpecialWakeup.C index 9d4e9f233..fac362c5b 100644 --- a/src/usr/scom/handleSpecialWakeup.C +++ b/src/usr/scom/handleSpecialWakeup.C @@ -68,261 +68,257 @@ errlHndl_t handleSpecialWakeup(TARGETING::Target* i_target, bool i_enable) TARGETING::TYPE l_type = i_target->getAttr(); #ifdef __HOSTBOOT_RUNTIME - // FSP - if(INITSERVICE::spBaseServicesEnabled()) + // FSP and BMC runtime use hostservice for wakeup + + // Check for valid interface function + if( g_hostInterfaces == NULL || + g_hostInterfaces->wakeup == NULL ) { - // Check for valid interface function - if( g_hostInterfaces == NULL || - g_hostInterfaces->wakeup == NULL ) - { - TRACFCOMP( g_trac_scom, - ERR_MRK"Hypervisor wakeup interface not linked"); + 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; + } - /*@ - * @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); + TargetHandleList pCoreList; - l_errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, - HWAS::SRCI_PRIORITY_HIGH); + // 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 ); + } - return l_errl; + // 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; } - TargetHandleList pCoreList; - - // If the target is already a core just push it on the list - if(l_type == TARGETING::TYPE_CORE) + uint32_t mode; + if(i_enable) { - pCoreList.clear(); - pCoreList.push_back(i_target); + mode = HBRT_WKUP_FORCE_AWAKE; } else { - getChildChiplets( pCoreList, i_target, TARGETING::TYPE_CORE ); + 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; + } + } + +#else + // IPL time so use HWP for wakeup + + if(l_type == TARGETING::TYPE_PROC) + { // Call wakeup on all core targets - // Wakeup may be called twice for fused cores + TargetHandleList pCoreList; + getChildChiplets( pCoreList, i_target, TARGETING::TYPE_CORE ); + 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); + // To simplify, just call recursively with the core target + l_errl = handleSpecialWakeup(*pCore_it, i_enable); if(l_errl) { break; } + } + return l_errl; + } - 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); + // 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_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; - } - } + 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_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_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 ); } - // BMC - else + // Only call the HWP if 0-->1 or 1-->0 + if( ((l_count==0) && i_enable) || + ((l_count==1) && !i_enable) ) { -#endif // __HOSTBOOT_RUNTIME - if(l_type == TARGETING::TYPE_PROC) + // 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; + p9specialWakeup::PROC_SPCWKUP_ENTITY l_spcwkupSrc; + if(! INITSERVICE::spBaseServicesEnabled()) { - // Call wakeup on all core targets - TargetHandleList pCoreList; - getChildChiplets( pCoreList, i_target, TARGETING::TYPE_CORE ); - - 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; + l_spcwkupSrc = p9specialWakeup::FSP; } - - // 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) + else { - TRACFCOMP( g_trac_scom,ERR_MRK - "Disabling special wakeup on target with SPCWKUP_COUNT=0"); - - /*@ - * @errortype - * @moduleid SCOM_HANDLE_SPECIAL_WAKEUP - * @reasoncode SCOM_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_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 ); + l_spcwkupSrc = p9specialWakeup::HOST; } - // Only call the HWP if 0-->1 or 1-->0 - if( ((l_count==0) && i_enable) || - ((l_count==1) && !i_enable) ) + if(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; - p9specialWakeup::PROC_SPCWKUP_ENTITY l_spcwkupSrc; - if(! INITSERVICE::spBaseServicesEnabled()) - { - l_spcwkupSrc = p9specialWakeup::FSP; - } - else - { - l_spcwkupSrc = p9specialWakeup::HOST; - } - - if(i_enable) - { - l_spcwkupType = p9specialWakeup::SPCWKUP_ENABLE; - } - else - { - l_spcwkupType = p9specialWakeup::SPCWKUP_DISABLE; - } + l_spcwkupType = p9specialWakeup::SPCWKUP_ENABLE; + } + else + { + l_spcwkupType = p9specialWakeup::SPCWKUP_DISABLE; + } - if(l_type == TARGETING::TYPE_EQ) - { - fapi2::Target - l_fapi_target(const_cast(i_target)); - - FAPI_EXEC_HWP(l_rc, - p9_cpu_special_wakeup_eq, - l_fapi_target, - l_spcwkupType, - l_spcwkupSrc ); - l_errl = rcToErrl(l_rc, ERRORLOG::ERRL_SEV_UNRECOVERABLE); - } - else if(l_type == TARGETING::TYPE_EX) - { - fapi2::Target - l_fapi_target(const_cast(i_target)); - - FAPI_EXEC_HWP(l_rc, - p9_cpu_special_wakeup_ex, - l_fapi_target, - l_spcwkupType, - l_spcwkupSrc ); - l_errl = rcToErrl(l_rc, ERRORLOG::ERRL_SEV_UNRECOVERABLE); - } - else if(l_type == TARGETING::TYPE_CORE) - { - fapi2::Target - l_fapi_target(const_cast(i_target)); - - FAPI_EXEC_HWP(l_rc, - p9_cpu_special_wakeup_core, - l_fapi_target, - l_spcwkupType, - l_spcwkupSrc ); - l_errl = rcToErrl(l_rc, ERRORLOG::ERRL_SEV_UNRECOVERABLE); - } + if(l_type == TARGETING::TYPE_EQ) + { + fapi2::Target + l_fapi_target(const_cast(i_target)); + + FAPI_EXEC_HWP(l_rc, + p9_cpu_special_wakeup_eq, + l_fapi_target, + l_spcwkupType, + l_spcwkupSrc ); + l_errl = rcToErrl(l_rc, ERRORLOG::ERRL_SEV_UNRECOVERABLE); + } + else if(l_type == TARGETING::TYPE_EX) + { + fapi2::Target + l_fapi_target(const_cast(i_target)); + + FAPI_EXEC_HWP(l_rc, + p9_cpu_special_wakeup_ex, + l_fapi_target, + l_spcwkupType, + l_spcwkupSrc ); + l_errl = rcToErrl(l_rc, ERRORLOG::ERRL_SEV_UNRECOVERABLE); + } + else if(l_type == TARGETING::TYPE_CORE) + { + fapi2::Target + l_fapi_target(const_cast(i_target)); + + FAPI_EXEC_HWP(l_rc, + p9_cpu_special_wakeup_core, + l_fapi_target, + l_spcwkupType, + l_spcwkupSrc ); + l_errl = rcToErrl(l_rc, ERRORLOG::ERRL_SEV_UNRECOVERABLE); + } - if(l_errl) - { - TRACFCOMP( g_trac_scom, - "p9_cpu_special_wakeup ERROR :" - " Returning errorlog, reason=0x%x", - l_errl->reasonCode() ); + 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 ); - } + // Capture the target data in the elog + ERRORLOG::ErrlUserDetailsTarget(i_target).addToLog( l_errl ); } + } - // Update the counter - if(!l_errl) + // Update the counter + if(!l_errl) + { + if(i_enable) { - if(i_enable) - { - l_count++; - } - else - { - l_count--; - } - i_target->setAttr(l_count); + l_count++; } -#ifdef __HOSTBOOT_RUNTIME + else + { + l_count--; + } + i_target->setAttr(l_count); } -#endif + +#endif // __HOSTBOOT_RUNTIME return l_errl; } -- cgit v1.2.1