summaryrefslogtreecommitdiffstats
path: root/src/usr/scom
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/scom')
-rw-r--r--src/usr/scom/handleSpecialWakeup.C113
-rw-r--r--src/usr/scom/scomtrans.C6
2 files changed, 93 insertions, 26 deletions
diff --git a/src/usr/scom/handleSpecialWakeup.C b/src/usr/scom/handleSpecialWakeup.C
index 65be26b03..11fbb94b1 100644
--- a/src/usr/scom/handleSpecialWakeup.C
+++ b/src/usr/scom/handleSpecialWakeup.C
@@ -43,9 +43,7 @@
#include <fapi2/plat_hwp_invoker.H>
#include <p9_cpu_special_wakeup.H>
-
-extern "C"
-{
+#include <scom/wakeup.H>
// Trace definition
extern trace_desc_t* g_trac_scom;
@@ -53,6 +51,9 @@ extern trace_desc_t* g_trac_scom;
using namespace TARGETING;
using namespace SCOM;
+namespace WAKEUP
+{
+
/**
* @brief Check to see which type of wakeup we need to use
* @return true: Use Host wakeup interface;
@@ -98,9 +99,10 @@ bool useHypWakeup( void )
/**
* @brief Use the Host/Hyp interface to control special wakeup
* @param i_target Input target core/ex/eq/etc
- * @param i_enable Turn wakeup on or off
+ * @param[in] i_enable - set or clear or clear all of the wakeups
*/
-errlHndl_t callWakeupHyp(TARGETING::Target* i_target, bool i_enable)
+errlHndl_t callWakeupHyp(TARGETING::Target* i_target,
+ HandleOptions_t i_enable)
{
errlHndl_t l_errl = NULL;
@@ -162,14 +164,48 @@ errlHndl_t callWakeupHyp(TARGETING::Target* i_target, bool i_enable)
}
uint32_t mode;
- if(i_enable)
+ if(i_enable == ENABLE)
{
mode = HBRT_WKUP_FORCE_AWAKE;
}
- else
+ else if(i_enable == DISABLE)
{
mode = HBRT_WKUP_CLEAR_FORCE;
}
+ else if(i_enable == FORCE_DISABLE)
+ {
+ mode = HBRT_WKUP_CLEAR_FORCE_COMPLETELY;
+ }
+ else
+ {
+ /*@
+ * @errortype
+ * @moduleid SCOM_HANDLE_SPECIAL_WAKEUP
+ * @reasoncode SCOM_INVALID_WAKEUP_PARM
+ * @userdata1 Wakeup Argument
+ * @userdata2 Input Target
+ * @devdesc Invalid mode parm for wakeup operation.
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ SCOM_HANDLE_SPECIAL_WAKEUP,
+ SCOM_INVALID_WAKEUP_PARM,
+ i_enable,
+ TARGETING::get_huid(i_target),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT );
+ break;
+ }
+
+ // PHYP supports the complete clear but OPAL might not yet
+ if( (mode == HBRT_WKUP_CLEAR_FORCE_COMPLETELY)
+ && !TARGETING::is_phyp_load()
+ && !(g_hostInterfaces->
+ get_interface_capabilities(HBRT_CAPS_SET1_OPAL)
+ & HBRT_CAPS_OPAL_HAS_WAKEUP_CLEAR) )
+ {
+ TRACFCOMP( g_trac_scom, "No support for forced clear, skipping" );
+ break;
+ }
// Do the special wakeup
int l_rc = g_hostInterfaces->wakeup(rtTargetId,mode);
@@ -221,9 +257,10 @@ errlHndl_t callWakeupHyp(TARGETING::Target* i_target, bool i_enable)
/**
* @brief Call the wakeup HWP to control special wakeup
* @param i_target Input target core/ex/eq/etc
- * @param i_enable Turn wakeup on or off
+ * @param[in] i_enable - set or clear or clear all of the wakeups
*/
-errlHndl_t callWakeupHwp(TARGETING::Target* i_target, bool i_enable)
+errlHndl_t callWakeupHwp(TARGETING::Target* i_target,
+ HandleOptions_t i_enable)
{
errlHndl_t l_errl = NULL;
fapi2::ReturnCode l_rc;
@@ -255,7 +292,7 @@ errlHndl_t callWakeupHwp(TARGETING::Target* i_target, bool i_enable)
// Assume HBRT is single-threaded, so no issues with concurrency
uint32_t l_count = (i_target)->getAttr<ATTR_SPCWKUP_COUNT>();
- if((l_count==0) && !i_enable)
+ if((l_count==0) && (i_enable==WAKEUP::DISABLE))
{
TRACFCOMP( g_trac_scom,ERR_MRK
"Disabling special wakeup on target with SPCWKUP_COUNT=0");
@@ -266,7 +303,7 @@ errlHndl_t callWakeupHwp(TARGETING::Target* i_target, bool i_enable)
* @reasoncode SCOM_SPCWKUP_COUNT_ERR
* @userdata1 Target HUID
* @userdata2[0:31] Wakeup Enable
- * @userdata2[32:63] Wakeup Count
+ * @userdata2[32:63] Wakeup Count (ATTR_SPCWKUP_COUNT)
* @devdesc Disabling special wakeup when not enabled.
*/
l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
@@ -274,17 +311,42 @@ errlHndl_t callWakeupHwp(TARGETING::Target* i_target, bool i_enable)
SCOM_SPCWKUP_COUNT_ERR,
get_huid(i_target),
TWO_UINT32_TO_UINT64(
- i_enable, l_count));
+ i_enable, l_count),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
- l_errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
- HWAS::SRCI_PRIORITY_LOW);
+ errlCommit( l_errl, RUNTIME_COMP_ID );
+ }
+
+ if( (l_count>0) && (i_enable==WAKEUP::FORCE_DISABLE) )
+ {
+ TRACFCOMP( g_trac_scom,ERR_MRK
+ "Attempting to force disable special wakeup on %.8X with SPCWKUP_COUNT=%d",
+ TARGETING::get_huid(i_target), l_count);
+ /*@
+ * @errortype
+ * @moduleid SCOM_CALL_WAKEUP_HWP
+ * @reasoncode SCOM_UNEXPECTED_FORCE_WAKEUP
+ * @userdata1 Target HUID
+ * @userdata2[0:31] Wakeup Enable
+ * @userdata2[32:63] Wakeup Count (ATTR_SPCWKUP_COUNT)
+ * @devdesc Unexpectedly forcing wakeup off when the counter
+ * is non-zero, implies a bug in the code flow.
+ */
+ l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ SCOM_CALL_WAKEUP_HWP,
+ SCOM_UNEXPECTED_FORCE_WAKEUP,
+ get_huid(i_target),
+ TWO_UINT32_TO_UINT64(
+ i_enable, l_count),
+ ERRORLOG::ErrlEntry::ADD_SW_CALLOUT );
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) )
+ // Only call the HWP if 0-->1 or 1-->0 or if it is a force
+ if( ((l_count==0) && (i_enable==WAKEUP::ENABLE)) ||
+ ((l_count==1) && (i_enable==WAKEUP::DISABLE)) ||
+ ((l_count>1) && (i_enable==WAKEUP::FORCE_DISABLE)) )
{
// NOTE Regarding the entity type passed to the HWP:
// There are 3 independent registers used to trigger a
@@ -302,13 +364,13 @@ errlHndl_t callWakeupHwp(TARGETING::Target* i_target, bool i_enable)
l_spcwkupSrc = p9specialWakeup::HOST;
}
- if(i_enable)
+ if(i_enable==WAKEUP::DISABLE)
{
- l_spcwkupType = p9specialWakeup::SPCWKUP_ENABLE;
+ l_spcwkupType = p9specialWakeup::SPCWKUP_DISABLE;
}
else
{
- l_spcwkupType = p9specialWakeup::SPCWKUP_DISABLE;
+ l_spcwkupType = p9specialWakeup::SPCWKUP_ENABLE;
}
if(l_type == TARGETING::TYPE_EQ)
@@ -363,14 +425,18 @@ errlHndl_t callWakeupHwp(TARGETING::Target* i_target, bool i_enable)
// Update the counter
if(!l_errl)
{
- if(i_enable)
+ if(i_enable == ENABLE)
{
l_count++;
}
- else
+ else if(i_enable == DISABLE)
{
l_count--;
}
+ else if(i_enable == FORCE_DISABLE)
+ {
+ l_count = 0;
+ }
i_target->setAttr<ATTR_SPCWKUP_COUNT>(l_count);
}
@@ -381,7 +447,8 @@ errlHndl_t callWakeupHwp(TARGETING::Target* i_target, bool i_enable)
/**
* @brief Enable and disable special wakeup for SCOM operations
*/
-errlHndl_t handleSpecialWakeup(TARGETING::Target* i_target, bool i_enable)
+errlHndl_t handleSpecialWakeup(TARGETING::Target* i_target,
+ HandleOptions_t i_enable)
{
errlHndl_t l_errl = NULL;
diff --git a/src/usr/scom/scomtrans.C b/src/usr/scom/scomtrans.C
index 06cf404fc..f100a5e3c 100644
--- a/src/usr/scom/scomtrans.C
+++ b/src/usr/scom/scomtrans.C
@@ -56,7 +56,7 @@
#include <hw_access_def.H>
#if __HOSTBOOT_RUNTIME
- #include "handleSpecialWakeup.H"
+ #include <scom/wakeup.H>
#endif
// Trace definition
@@ -208,7 +208,7 @@ errlHndl_t startScomProcess(DeviceFW::OperationType i_opType,
TRACDCOMP(g_trac_scom,"Special wakeup required, starting now..");
g_wakeupInProgress = true;
- l_err = handleSpecialWakeup(i_target,true);
+ l_err = WAKEUP::handleSpecialWakeup(i_target,WAKEUP::ENABLE);
if(l_err)
{
TRACFCOMP(g_trac_scom, "startScomProcess: "
@@ -242,7 +242,7 @@ errlHndl_t startScomProcess(DeviceFW::OperationType i_opType,
g_wakeupInProgress = true;
errlHndl_t l_errSW = NULL;
- l_errSW = handleSpecialWakeup(i_target,false);
+ l_errSW = WAKEUP::handleSpecialWakeup(i_target,WAKEUP::DISABLE);
if(l_err != NULL && l_errSW)
{
OpenPOWER on IntegriCloud