summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSachin Gupta <sgupta2m@in.ibm.com>2018-03-20 02:33:56 -0500
committerSachin Gupta <sgupta2m@in.ibm.com>2018-03-20 08:28:05 -0400
commit5c0363924c7d710146155b3354b236012372dd24 (patch)
tree478a3bfcaf52ce94235e51624222ce2e3ea81ec2
parent26fbcbed7c360f0c7b5b7e342d1fe149bf175dac (diff)
downloadtalos-sbe-5c0363924c7d710146155b3354b236012372dd24.tar.gz
talos-sbe-5c0363924c7d710146155b3354b236012372dd24.zip
Handle race condition between PSU/FIFO interface.
It fixes these two problems 1. Protect global interrupt flags by putting them in critical section 2. Disable inteerupts before sending the ACK for timer chipop. Otherwise other high priority thread can interrupt it if there is a interrupt on FIFO. On slow soft-fsi based systems, taking initial data from FIFO may take time in command receiver thread. Change-Id: I6e33eb9b9a3fa698c38ca228ed1e645bebeb8234 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/56052 Reviewed-by: Shakeeb A. Pasha B K <shakeebbk@in.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: RAJA DAS <rajadas2@in.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
-rw-r--r--src/sbefw/app/common/sbecmdCntrlTimer.C69
-rw-r--r--src/sbefw/core/sbeexeintf.H10
-rw-r--r--src/sbefw/core/sbeirq.C2
3 files changed, 49 insertions, 32 deletions
diff --git a/src/sbefw/app/common/sbecmdCntrlTimer.C b/src/sbefw/app/common/sbecmdCntrlTimer.C
index ff650eac..2a030403 100644
--- a/src/sbefw/app/common/sbecmdCntrlTimer.C
+++ b/src/sbefw/app/common/sbecmdCntrlTimer.C
@@ -6,6 +6,7 @@
/* OpenPOWER sbe Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* [+] International Business Machines Corp. */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -42,7 +43,6 @@ using namespace fapi2;
// Global instance to track PK timer
static timerService g_hostTimerSvc;
-
// Callback
void sbeTimerExpiryCallback(void *)
{
@@ -80,38 +80,49 @@ uint32_t sbeCntrlTimer( uint8_t *i_pArg )
{
if(SBE_GLOBAL->sbePsu2SbeCmdReqHdr.flags & SBE_PSU_FLAGS_START_TIMER)
{
- uint64_t time = 0;
- l_rc = sbeReadPsu2SbeMbxReg(SBE_HOST_PSU_MBOX_REG1,
+ // Disable interrupts before sending the ACK for timer chipop.
+ // Otherwise other high priority thread can interrupt it if
+ // there is a interrupt on slow soft-fsi based systems,
+ // taking initial data from FIFO may take time in command receiver
+ // thread.
+ PkMachineContext ctx;
+ pk_critical_section_enter(&ctx);
+ do
+ {
+ uint64_t time = 0;
+ l_rc = sbeReadPsu2SbeMbxReg(SBE_HOST_PSU_MBOX_REG1,
(sizeof(time)/sizeof(uint64_t)),
&time, true);
- if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
- {
- SBE_ERROR(SBE_FUNC" Failed to extract SBE_HOST_PSU_MBOX_REG1");
- break;
- }
-
- SBE_INFO(SBE_FUNC "Start Timer. Time: [%08X]us",
- SBE::lower32BWord(time));
-
- l_rc = g_hostTimerSvc.stopTimer( );
- if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
- {
- SBE_GLOBAL->sbeSbe2PsuRespHdr.setStatus(SBE_PRI_INTERNAL_ERROR, l_rc);
- SBE_ERROR(SBE_FUNC" g_hostTimerSvc.stopTimer failed");
- l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
- break;
- }
-
- l_rc = g_hostTimerSvc.startTimer( (uint32_t )time,
+ if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ SBE_ERROR(SBE_FUNC" Failed to extract "
+ "SBE_HOST_PSU_MBOX_REG1");
+ break;
+ }
+
+ l_rc = g_hostTimerSvc.stopTimer( );
+ if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ SBE_GLOBAL->sbeSbe2PsuRespHdr.setStatus(
+ SBE_PRI_INTERNAL_ERROR, l_rc);
+ SBE_ERROR(SBE_FUNC" g_hostTimerSvc.stopTimer failed");
+ l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ break;
+ }
+
+ l_rc = g_hostTimerSvc.startTimer( (uint32_t )time,
(PkTimerCallback)&sbeTimerExpiryCallback);
- if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
- {
- SBE_GLOBAL->sbeSbe2PsuRespHdr.setStatus(SBE_PRI_INTERNAL_ERROR, l_rc);
- SBE_ERROR(SBE_FUNC" g_hostTimerSvc.startTimer failed");
- l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
- break;
- }
+ if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc)
+ {
+ SBE_GLOBAL->sbeSbe2PsuRespHdr.setStatus(
+ SBE_PRI_INTERNAL_ERROR, l_rc);
+ SBE_ERROR(SBE_FUNC" g_hostTimerSvc.startTimer failed");
+ l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ break;
+ }
+ }while(0);
+ pk_critical_section_exit(&ctx);
break;
}
// Acknowledge host
diff --git a/src/sbefw/core/sbeexeintf.H b/src/sbefw/core/sbeexeintf.H
index 80d89586..eaeab51c 100644
--- a/src/sbefw/core/sbeexeintf.H
+++ b/src/sbefw/core/sbeexeintf.H
@@ -5,7 +5,8 @@
/* */
/* OpenPOWER sbe Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2017 */
+/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* [+] International Business Machines Corp. */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -44,7 +45,6 @@ extern "C" {
#ifdef __cplusplus
}
#endif
-
/**
* @brief enums for priorities for thread creation
*
@@ -118,6 +118,8 @@ typedef struct
void setIntrSource(const sbeHandler_t i_handler,
const sbeInterfaceSrc_t i_val)
{
+ PkMachineContext ctx;
+ pk_critical_section_enter(&ctx);
switch(i_handler)
{
case SBE_INTERRUPT_ROUTINE: intrSource |= i_val; break;
@@ -125,11 +127,14 @@ typedef struct
case SBE_PROC_ROUTINE: procThrIntrSource |= i_val; break;
case SBE_ALL_HANDLER: break;
}
+ pk_critical_section_exit(&ctx);
}
void clearIntrSource(const sbeHandler_t i_handler,
const sbeInterfaceSrc_t i_val)
{
+ PkMachineContext ctx;
+ pk_critical_section_enter(&ctx);
switch(i_handler)
{
case SBE_INTERRUPT_ROUTINE: intrSource &= ~i_val; break;
@@ -143,6 +148,7 @@ typedef struct
break;
}
}
+ pk_critical_section_exit(&ctx);
}
bool isSet (const sbeHandler_t i_handler, const sbeInterfaceSrc_t i_val)
diff --git a/src/sbefw/core/sbeirq.C b/src/sbefw/core/sbeirq.C
index 48021f3c..a1d5b72b 100644
--- a/src/sbefw/core/sbeirq.C
+++ b/src/sbefw/core/sbeirq.C
@@ -51,7 +51,7 @@
void sbe_interrupt_handler (void *i_pArg, PkIrqId i_irq)
{
#define SBE_FUNC " sbe_interrupt_handler "
- SBE_ENTER(SBE_FUNC"i_irq=[0x%02X]",i_irq);
+ SBE_INFO(SBE_FUNC"i_irq=[0x%02X]",i_irq);
int l_rc = 0;
OpenPOWER on IntegriCloud