From d8e942c7bf09874cca9d0c55fe211370641b1808 Mon Sep 17 00:00:00 2001 From: Santosh Puranik Date: Mon, 9 May 2016 11:42:52 -0500 Subject: 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 Reviewed-by: AMIT J. TENDOLKAR --- sbe/sbefw/sbecmdprocessor.C | 13 +++++++---- sbe/sbefw/sbecmdreceiver.C | 48 ++++++++++++++++++++++++++++++-------- sbe/sbefw/sbeexeintf.H | 9 +------ sbe/sbefw/sbeirq.C | 8 ++++++- sbe/sbefw/sbemain.C | 6 ----- sbe/test/test.xml | 1 + sbe/test/testFifoReset.py | 57 +++++++++++++++++++++++++++++++++++++++++++++ sbe/test/testFifoReset.xml | 12 ++++++++++ sbe/test/testUtil.py | 41 ++++++++++++++++++++++++++++++++ 9 files changed, 166 insertions(+), 29 deletions(-) create mode 100644 sbe/test/testFifoReset.py create mode 100644 sbe/test/testFifoReset.xml (limited to 'sbe') 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 @@ ../simics/targets/p9_nimbus/sbeTest/testSram.xml ../simics/targets/p9_nimbus/sbeTest/testCntlInstruction.xml ../simics/targets/p9_nimbus/sbeTest/testRegAccess.xml + ../simics/targets/p9_nimbus/sbeTest/testFifoReset.xml sbe-trace 0 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 @@ + + + + + run-python-file targets/p9_nimbus/sbeTest/testFifoReset.py + yes + + + + run-python-file targets/p9_nimbus/sbeTest/testIstepInvalid.py + yes + 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): -- cgit v1.2.1