summaryrefslogtreecommitdiffstats
path: root/sbe
diff options
context:
space:
mode:
authorSantosh Puranik <santosh.puranik@in.ibm.com>2016-05-09 11:42:52 -0500
committerPrachi Gupta <pragupta@us.ibm.com>2016-06-08 11:45:52 -0500
commitd8e942c7bf09874cca9d0c55fe211370641b1808 (patch)
tree1615acad2a1d13a5afd2c52c4a7a13062e971347 /sbe
parent257861dcd4b5a7cce8b09c936ec26f8a9d36bc37 (diff)
downloadtalos-sbe-d8e942c7bf09874cca9d0c55fe211370641b1808.tar.gz
talos-sbe-d8e942c7bf09874cca9d0c55fe211370641b1808.zip
RTC: 126147
FIFO Reset support Change-Id: I1654d4a5a72bebd0764c2f560030057bf984cc31 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/23042 Tested-by: Jenkins Server Reviewed-by: RAJA DAS <rajadas2@in.ibm.com> Reviewed-by: AMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com>
Diffstat (limited to 'sbe')
-rw-r--r--sbe/sbefw/sbecmdprocessor.C13
-rw-r--r--sbe/sbefw/sbecmdreceiver.C48
-rw-r--r--sbe/sbefw/sbeexeintf.H9
-rw-r--r--sbe/sbefw/sbeirq.C8
-rw-r--r--sbe/sbefw/sbemain.C6
-rwxr-xr-xsbe/test/test.xml1
-rw-r--r--sbe/test/testFifoReset.py57
-rw-r--r--sbe/test/testFifoReset.xml12
-rw-r--r--sbe/test/testUtil.py41
9 files changed, 166 insertions, 29 deletions
diff --git a/sbe/sbefw/sbecmdprocessor.C b/sbe/sbefw/sbecmdprocessor.C
index f9be47b9..f5fb0f90 100644
--- a/sbe/sbefw/sbecmdprocessor.C
+++ b/sbe/sbefw/sbecmdprocessor.C
@@ -109,9 +109,6 @@ void sbeHandleFifoResponse (const uint32_t i_rc)
// Handle FIFO reset case
if (i_rc == SBE_FIFO_RESET_RECEIVED)
{
- // @TODO via RTC : 126147
- // Handle FIFO reset flow
- pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
break;
}
@@ -248,6 +245,14 @@ void sbeSyncCommandProcessor_routine(void *i_pArg)
l_primStatus = g_sbeCmdRespHdr.prim_status;
l_rc = g_sbeCmdRespHdr.sec_status;
}
+ else // SBE_INTERFACE_FIFO_RESET or SBE_INTERFACE_UNKNOWN
+ {
+ SBE_ERROR(SBE_FUNC"Unexpected interrupt communicated to the "
+ "processor thread. Interrupt source: 0x%02X",
+ g_sbeIntrSource.l_intrSource);
+ assert(false);
+ break;
+ }
SBE_DEBUG (SBE_FUNC"l_primStatus=[0x%04X], l_rc=[0x%04X]",
l_primStatus, l_rc);
@@ -325,8 +330,8 @@ void sbeSyncCommandProcessor_routine(void *i_pArg)
// Enable the new data available interrupt
g_sbeIntrSource.clearIntrSource(SBE_INTERFACE_FIFO);
pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
+ pk_irq_enable(SBE_IRQ_SBEFIFO_RESET);
}
-
} while(true); // Thread always exists
}
diff --git a/sbe/sbefw/sbecmdreceiver.C b/sbe/sbefw/sbecmdreceiver.C
index 415e23c6..94a44ce1 100644
--- a/sbe/sbefw/sbecmdreceiver.C
+++ b/sbe/sbefw/sbecmdreceiver.C
@@ -71,6 +71,14 @@ void sbeCommandReceiver_routine(void *i_pArg)
// the FIFO or PSU interfaces to be able to decode the command
// class and the command opcode parameters.
+ // Received FIFO Reset interrupt
+ if ( g_sbeIntrSource.isSet(SBE_INTERFACE_FIFO_RESET) )
+ {
+ SBE_ERROR(SBE_FUNC"FIFO reset received");
+ l_rc = SBE_FIFO_RESET_RECEIVED;
+ break;
+ }
+
// Received PSU interrupt
if ( g_sbeIntrSource.isSet(SBE_INTERFACE_PSU) )
{
@@ -91,7 +99,7 @@ void sbeCommandReceiver_routine(void *i_pArg)
l_command = g_sbePsu2SbeCmdReqHdr.command;
} // end if loop for PSU interface chipOp handling
- // Received FIFO interrupt
+ // Received FIFO New Data interrupt
else if ( g_sbeIntrSource.isSet(SBE_INTERFACE_FIFO) ) {
// This thread will attempt to unblock the command processor
@@ -115,14 +123,6 @@ void sbeCommandReceiver_routine(void *i_pArg)
if (l_rc == SBE_FIFO_RESET_RECEIVED)
{
SBE_ERROR(SBE_FUNC"FIFO reset received");
- g_sbeCmdRespHdr.prim_status =
- (uint16_t)l_rc;
- g_sbeCmdRespHdr.sec_status =
- (uint16_t)l_rc;
-
- // Reassign l_rc to Success to Unblock command processor
- // thread and let that take the necessary action.
- l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
break;
}
@@ -182,8 +182,36 @@ void sbeCommandReceiver_routine(void *i_pArg)
} while (false); // Inner do..while ends
+ // If there was a FIFO reset request,
+ if (l_rc == SBE_FIFO_RESET_RECEIVED)
+ {
+ // Perform FIFO Reset
+ uint32_t l_rc = sbeUpFifoPerformReset();
+ if (l_rc)
+ {
+ // Perform FIFO Reset failed
+ SBE_ERROR(SBE_FUNC"Perform FIFO Reset failed, "
+ "l_rc=[0x%08X]", l_rc);
+ // Collect FFDC?
+ }
+
+ if ( g_sbeIntrSource.isSet(SBE_INTERFACE_FIFO) )
+ {
+ g_sbeIntrSource.clearIntrSource(SBE_INTERFACE_FIFO);
+ }
+
+ if ( g_sbeIntrSource.isSet(SBE_INTERFACE_FIFO_RESET) )
+ {
+ g_sbeIntrSource.clearIntrSource(SBE_INTERFACE_FIFO_RESET);
+ }
+
+ pk_irq_enable(SBE_IRQ_SBEFIFO_DATA);
+ pk_irq_enable(SBE_IRQ_SBEFIFO_RESET);
+ continue;
+ } // FIFO reset handling ends
+
// Unblock the command processor thread
- // if we could dequeue the header successfully
+ // if we could dequeue the header successfully,
if ((l_rcPk == PK_OK) && (l_rc == SBE_SEC_OPERATION_SUCCESSFUL))
{
l_rcPk = pk_semaphore_post(&g_sbeSemCmdProcess);
diff --git a/sbe/sbefw/sbeexeintf.H b/sbe/sbefw/sbeexeintf.H
index e4eef8dd..6f43784d 100644
--- a/sbe/sbefw/sbeexeintf.H
+++ b/sbe/sbefw/sbeexeintf.H
@@ -76,14 +76,6 @@ extern PkSemaphore g_sbeSemCmdRecv;
*/
extern PkSemaphore g_sbeSemCmdProcess;
-/**
- * @brief Global semaphore : g_sbeSemFifoReset
- *
- * This is used to synchronize the graceful handling of FIFO reset
- * between command receiver and synchronous command processor threads.
- *
- */
-extern PkSemaphore g_sbeSemFifoReset;
/**
* @brief SBE Interface source
@@ -94,6 +86,7 @@ typedef enum
SBE_INTERFACE_UNKNOWN = 0x00,
SBE_INTERFACE_FIFO = 0x01,
SBE_INTERFACE_PSU = 0x02,
+ SBE_INTERFACE_FIFO_RESET = 0x04,
} sbeInterfaceSrc_t;
/**
diff --git a/sbe/sbefw/sbeirq.C b/sbe/sbefw/sbeirq.C
index c2f3b616..0f160509 100644
--- a/sbe/sbefw/sbeirq.C
+++ b/sbe/sbefw/sbeirq.C
@@ -36,8 +36,13 @@ void sbe_interrupt_handler (void *i_pArg, PkIrqId i_irq)
break;
case SBE_IRQ_SBEFIFO_DATA:
- case SBE_IRQ_SBEFIFO_RESET:
g_sbeIntrSource.setIntrSource(SBE_INTERFACE_FIFO);
+ pk_irq_disable(SBE_IRQ_SBEFIFO_RESET);
+ break;
+
+ case SBE_IRQ_SBEFIFO_RESET:
+ g_sbeIntrSource.setIntrSource(SBE_INTERFACE_FIFO_RESET);
+ pk_irq_disable(SBE_IRQ_SBEFIFO_DATA);
break;
default:
@@ -118,3 +123,4 @@ int sbeIRQSetup (void)
return l_rc;
#undef SBE_FUNC
}
+
diff --git a/sbe/sbefw/sbemain.C b/sbe/sbefw/sbemain.C
index 0502c2bf..0761d704 100644
--- a/sbe/sbefw/sbemain.C
+++ b/sbe/sbefw/sbemain.C
@@ -24,7 +24,6 @@
////////////////////////////////////////////////////////////////
PkSemaphore g_sbeSemCmdRecv;
PkSemaphore g_sbeSemCmdProcess;
-PkSemaphore g_sbeSemFifoReset;
////////////////////////////////////////////////////////////////
// @brief Stacks for Non-critical Interrupts and Threads
@@ -113,11 +112,6 @@ uint32_t sbeInitSems(void)
{
break;
}
- l_rc = pk_semaphore_create(&g_sbeSemFifoReset, 0, 1);
- if (l_rc)
- {
- break;
- }
} while (false);
if (l_rc)
diff --git a/sbe/test/test.xml b/sbe/test/test.xml
index 07d1f1a0..23f0d46f 100755
--- a/sbe/test/test.xml
+++ b/sbe/test/test.xml
@@ -11,6 +11,7 @@
<include>../simics/targets/p9_nimbus/sbeTest/testSram.xml</include>
<include>../simics/targets/p9_nimbus/sbeTest/testCntlInstruction.xml</include>
<include>../simics/targets/p9_nimbus/sbeTest/testRegAccess.xml</include>
+ <include>../simics/targets/p9_nimbus/sbeTest/testFifoReset.xml</include>
<testcase>
<simcmd>sbe-trace 0</simcmd>
</testcase>
diff --git a/sbe/test/testFifoReset.py b/sbe/test/testFifoReset.py
new file mode 100644
index 00000000..9660df2e
--- /dev/null
+++ b/sbe/test/testFifoReset.py
@@ -0,0 +1,57 @@
+import sys
+sys.path.append("targets/p9_nimbus/sbeTest")
+import testUtil
+
+err = False
+
+# Test data that only contains the command header
+TESTDATA = [0, 0, 0, 3,
+ 0, 0, 0xA1, 0x01]
+
+# Complete test data
+TESTDATA_FULL = [0, 0, 0, 3,
+ 0, 0, 0xA1, 0x01,
+ 0, 0x02, 0x00, 0x01]
+
+# Get capabilities command. This will ensure the DS FIFO gets full
+TESTDATA_2 = [0, 0, 0, 2,
+ 0, 0, 0xA8, 0x02]
+
+def main():
+ try:
+ testUtil.runCycles(10000000)
+ # Send a partial chip-op
+ testUtil.writeUsFifo(TESTDATA)
+ testUtil.resetFifo()
+ # Make sure both the upstream and downstrem FIFOs are clear after the reset
+ testUtil.waitTillUsFifoEmpty()
+ testUtil.waitTillDsFifoEmpty()
+ # Now send a complete chip-op on the upstream FIFO
+ testUtil.writeUsFifo(TESTDATA_FULL)
+ testUtil.writeEot()
+ testUtil.resetFifo()
+ # Make sure both the upstream and downstrem FIFOs are clear after the reset
+ testUtil.waitTillUsFifoEmpty()
+ testUtil.waitTillDsFifoEmpty()
+ # Now send a get capabilities chip-op, so that in response, the DS FIFO
+ # gets full before we do a reset
+ testUtil.writeUsFifo(TESTDATA_2)
+ testUtil.writeEot()
+ testUtil.resetFifo()
+ # Make sure both the upstream and downstrem FIFOs are clear after the reset
+ testUtil.waitTillUsFifoEmpty()
+ testUtil.waitTillDsFifoEmpty()
+ except:
+ print("\nTest completed with error(s), Raise error")
+ raise
+ print("\nTest completed with no errors")
+
+main()
+
+if err:
+ print ("\nTest Suite completed with error(s)")
+ #sys.exit(1)
+else:
+ print ("\nTest Suite completed with no errors")
+ #sys.exit(0);
+
diff --git a/sbe/test/testFifoReset.xml b/sbe/test/testFifoReset.xml
new file mode 100644
index 00000000..42c125d9
--- /dev/null
+++ b/sbe/test/testFifoReset.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+ <!-- SBE FIFO reset Test case -->
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testFifoReset.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
+ <!-- An istep chip-op should succeed post the FIFO reset -->
+ <testcase>
+ <simcmd>run-python-file targets/p9_nimbus/sbeTest/testIstepInvalid.py</simcmd>
+ <exitonerror>yes</exitonerror>
+ </testcase>
diff --git a/sbe/test/testUtil.py b/sbe/test/testUtil.py
index 3af06ffc..55802c0c 100644
--- a/sbe/test/testUtil.py
+++ b/sbe/test/testUtil.py
@@ -32,6 +32,47 @@ def readEot():
checkEqual( (status[3] & 0x80), 0x80 );
read(lbus, 0x2440, 4)
+def resetFifo():
+ write(lbus, 0x240C, (0, 0, 0, 1))
+ return
+
+def readUsFifoStatus():
+ status = read(lbus, 0x2404, 4)
+ return status
+
+def readDsFifoStatus():
+ status = read(lbus, 0x2444, 4)
+ return status
+
+def waitTillFifoEmpty(func):
+ count = 0
+ loop = True
+ while(loop is True):
+ status = func()
+ if(status[1] == 0x10):
+ loop = False
+ break
+ else:
+ count = count + 1
+ runCycles(200000)
+ if(count > 10):
+ raise Exception('Timed out waiting for FIFO to get flushed')
+
+
+def waitTillUsFifoEmpty():
+ try:
+ waitTillFifoEmpty(readUsFifoStatus)
+ except:
+ raise Exception('US FIFO did not get empty')
+
+
+def waitTillDsFifoEmpty():
+ try:
+ waitTillFifoEmpty(readDsFifoStatus)
+ except:
+ raise Exception('DS FIFO did not get empty')
+
+
# This function will only read the entry but will not compare it
# with anything. This can be used to flush out enteries.
def readDsEntry(entryCount):
OpenPOWER on IntegriCloud