summaryrefslogtreecommitdiffstats
path: root/sbe/sbefw/sbeFifoMsgUtils.C
diff options
context:
space:
mode:
Diffstat (limited to 'sbe/sbefw/sbeFifoMsgUtils.C')
-rw-r--r--sbe/sbefw/sbeFifoMsgUtils.C245
1 files changed, 245 insertions, 0 deletions
diff --git a/sbe/sbefw/sbeFifoMsgUtils.C b/sbe/sbefw/sbeFifoMsgUtils.C
new file mode 100644
index 00000000..d86208ad
--- /dev/null
+++ b/sbe/sbefw/sbeFifoMsgUtils.C
@@ -0,0 +1,245 @@
+/*
+ * @file: ppe/sbe/sbefw/sbeFifoMsgUtils.C
+ *
+ * @brief This file contains the SBE FIFO Access Common Utility Functions
+ *
+ */
+
+#include "sbefifo.H"
+#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+#include "sbeFifoMsgUtils.H"
+#include "sbeerrorcodes.H"
+#include "assert.h"
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeUpFifoDeq_mult (uint32_t &io_len,
+ uint32_t *o_pData,
+ const bool i_isEotExpected,
+ const bool i_flush)
+{
+ #define SBE_FUNC " sbeUpFifoDeq_mult "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t l_len = 0;
+
+ // If Caller didn't request flush operation
+ // and passed a non-zero valid length, we
+ // would expect a valid buffer
+ if ((!i_flush) && (io_len > 0))
+ {
+ assert ( NULL != o_pData)
+ }
+
+ do
+ {
+ sbeFifoEntry_t l_data = {0};
+
+ // Read Double word from the Upstream FIFO;
+ // The DW data represents the first 32 bits of data word entry
+ // followed by the status bits.
+
+ // Bit 0-31 : Data
+ // Bit 32 : Data valid flag
+ // Bit 33 : EOT flag
+ // Bit 34-63 : Status (2-31)
+ // Valid : EOT
+ // 1 : 0 -> data=message
+ // 0 : 1 -> data=dummy_data of EOT operation
+ // 0 : 0 -> data=dummy_data
+ // 1 : 1 -> Not used
+
+ l_rc = sbeUpFifoDeq ( reinterpret_cast<uint64_t*>(&l_data) );
+
+ if (l_rc)
+ {
+ // Error while dequeueing from upstream FIFO
+ SBE_ERROR(SBE_FUNC"sbeUpFifoDeq failed,"
+ "l_rc=[0x%08X]", l_rc);
+ // @TODO RTC via : 132295
+ // RC refactoring - reserve 3 bits in SBE RC for PCBPIB
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ SBE_DEBUG(SBE_FUNC"sbeUpFifoDeq, "
+ "l_data.fifo_data=[0x%08X],",
+ l_data.fifo_data);
+
+ // If FIFO reset is requested
+ if(l_data.statusOrReserved.req_upfifo_reset)
+ {
+ // @TODO via RTC : 126147
+ // Review reset loop flow in here.
+ // Received a FIFO reset request
+ l_rc = SBE_FIFO_RESET_RECEIVED;
+ break;
+ }
+
+ // if EOT flag is set, clear EOT and
+ // set the RC accordingly
+ if (l_data.statusOrReserved.eot_flag)
+ {
+ l_rc = sbeUpFifoAckEot();
+ if (l_rc)
+ {
+ // Error while ack'ing EOT in upstream FIFO
+ SBE_ERROR(SBE_FUNC"sbeUpFifoAckEot failed,"
+ "l_rc=[0x%08X]", l_rc);
+
+ // Collect FFDC and save off the l_rc
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ // Successfully Ack'ed the EOT in upstream FIFO
+ if ( ((!i_isEotExpected) || (l_len != io_len))
+ && (!i_flush) )
+ {
+ if (l_len < io_len)
+ {
+ // Unexpected EOT, got insufficient data
+ l_rc = SBE_SEC_UNEXPECTED_EOT_INSUFFICIENT_DATA ;
+ }
+ else
+ {
+ // Unexpected EOT, got excess data
+ l_rc = SBE_SEC_UNEXPECTED_EOT_EXCESS_DATA ;
+ }
+ }
+ break;
+ }
+
+ // if Upstream FIFO is empty,
+ if (l_data.statusOrReserved.fifo_empty)
+ {
+ continue;
+ }
+
+ if ((!i_flush) && (l_len < io_len))
+ {
+ o_pData[l_len] = l_data.fifo_data;
+ }
+
+ ++l_len;
+
+ } while(i_flush || i_isEotExpected || (l_len < io_len));
+
+ // Return the length of entries dequeued.
+ io_len = l_len;
+ return l_rc;
+
+ #undef SBE_FUNC
+}
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeDownFifoEnq_mult (uint32_t &io_len,
+ const uint32_t *i_pData)
+{
+ #define SBE_FUNC " sbeDownFifoEnq_mult "
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint32_t l_len = 0;
+
+ do
+ {
+ sbeDownFifoStatusReg_t l_status = {0};
+
+ // Read the down stream FIFO status
+ l_rc = sbeDownFifoGetStatus (reinterpret_cast<uint64_t *>(&l_status));
+ if (l_rc)
+ {
+ // Error while reading downstream FIFO status
+ SBE_ERROR(SBE_FUNC"sbeDownFifoGetStatus failed, "
+ "l_rc=[0x%08X]", l_rc);
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ // Check if there was a FIFO reset request from SP
+ if (l_status.downfifo_status.req_upfifo_reset)
+ {
+ // @TODO via RTC : 126147
+ // Review reset loop flow in here.
+ // Received an upstream FIFO reset request
+ SBE_ERROR(SBE_FUNC"Received reset request");
+ l_rc = SBE_FIFO_RESET_RECEIVED;
+ break;
+ }
+
+ // Check if downstream FIFO is full
+ if (l_status.downfifo_status.fifo_full)
+ {
+ // Downstream FIFO is full
+ SBE_INFO(SBE_FUNC"Downstream FIFO is full");
+ continue;
+ }
+
+ // PIB write data format:
+ // Bit 0 - 31 : Data
+ // Bit 32 - 63 : Unused
+
+ sbeFifoEntry_t l_data = {0};
+
+ l_data.fifo_data = *(i_pData+l_len);
+
+ SBE_DEBUG(SBE_FUNC"Downstream fifo data entry[0x%08X]",
+ l_data.fifo_data);
+
+ // Write the data into the downstream FIFO
+ l_rc = sbeDownFifoEnq ( *(reinterpret_cast<uint64_t*>(&l_data)) );
+ if (l_rc)
+ {
+ SBE_ERROR(SBE_FUNC"sbeDownFifoEnq failed, "
+ "l_rc[0x%08X]", l_rc);
+ // @TODO RTC via : 132295
+ // RC refactoring - reserve 3 bits in SBE RC for PCBPIB
+ l_rc = SBE_SEC_FIFO_ACCESS_FAILURE;
+ break;
+ }
+
+ ++l_len;
+
+ } while(l_len<io_len);
+
+ io_len = l_len;
+ return l_rc;
+ #undef SBE_FUNC
+}
+
+////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////
+void sbeBuildMinRespHdr ( uint32_t *io_pBuf,
+ uint32_t &io_curIndex,
+ const uint16_t i_primStatus,
+ const uint16_t i_secStatus,
+ const uint32_t i_pcbpibStatus,
+ const uint32_t i_startIndex )
+{
+ do
+ {
+ if (!io_pBuf)
+ {
+ break;
+ }
+
+ io_pBuf[io_curIndex] = sbeBuildRespHeaderMagicCodeCmdClass();
+ io_pBuf[++io_curIndex] = sbeBuildRespHeaderStatusWordLocal(
+ i_primStatus, i_secStatus);
+
+ // Pcb-Pib error is optional,
+ // not needed for success case
+ if ( (i_primStatus != SBE_PRI_OPERATION_SUCCESSFUL) ||
+ (i_pcbpibStatus != SBE_PCB_PIB_ERROR_NONE) )
+ {
+ io_pBuf[++io_curIndex] = i_pcbpibStatus;
+ }
+
+ // Somehow this compiler isn't allowing the
+ // index pre-increment for the last array entry
+ // directly embedded into the assignment
+ ++io_curIndex;
+ io_pBuf[io_curIndex] = io_curIndex - i_startIndex + 1;
+
+ } while(false);
+}
OpenPOWER on IntegriCloud