summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbe/sbefw/sbecmdiplcontrol.C286
-rw-r--r--sbe/sbefw/sbecmdiplcontrol.H22
-rw-r--r--sbe/sbefw/sbecmdparser.C2
-rw-r--r--sbe/sbefw/sbecmdprocessor.C4
-rw-r--r--sbe/sbefw/sbecmdreceiver.C21
-rw-r--r--sbe/sbefw/sbefifo.H152
6 files changed, 435 insertions, 52 deletions
diff --git a/sbe/sbefw/sbecmdiplcontrol.C b/sbe/sbefw/sbecmdiplcontrol.C
index 70f45805..a48e32aa 100644
--- a/sbe/sbefw/sbecmdiplcontrol.C
+++ b/sbe/sbefw/sbecmdiplcontrol.C
@@ -8,23 +8,297 @@
#include "sbecmdiplcontrol.H"
#include "sbefifo.H"
#include "sbetrace.H"
+#include "sbe_sp_intf.H"
+// Forward declaration
-uint32_t sbeExecuteIstep (uint8_t *i_pArg)
+uint32_t sbeExecuteIstep (const uint8_t i_major, const uint8_t i_minor);
+bool validateIstep (const uint8_t i_major, const uint8_t i_minor);
+
+// @TODO via RTC 129073.
+// Just a dummy code for HWP to test the flow.
+// Remove it once complete flow is ready
+uint32_t istep1SuccessHwp( ) { SBE_DEBUG("istep1SuccessHwp"); return 0; }
+uint32_t istep1FailHwp( ) { SBE_DEBUG("istep1FailHwp"); return 1; }
+
+
+//typedefs
+// @TODO via RTC 129073.
+// This is currently not defined as actual HWP signature as it
+// will break compilation. Once Greg FAPI codeis in master, we will
+// change it
+typedef uint32_t (*sbe_istep_hwp)();
+
+// Wrapper function for HWP IPl functions
+typedef uint32_t (*sbe_istep)( sbe_istep_hwp );
+
+// Wrapper function which will call HWP with Proc target.
+uint32_t istepWithProc( sbe_istep_hwp i_hwp );
+
+//structure for mapping SBE wrapper and HWP functions
+typedef struct
+{
+ sbe_istep istepWrapper;
+ sbe_istep_hwp istepHwp;
+}istepMap_t;
+
+// Major isteps which are supported
+typedef enum
+{
+ SBE_ISTEP2 = 2,
+ SBE_ISTEP4 = 4,
+ SBE_ISTEP5 = 5,
+}sbe_supported_steps_t;
+
+// constants
+// @TODO via RTC 129073.
+// These are random numbers now. Will fill up
+// once IPL flow document is in better shape.
+const uint32_t ISTEP2_MAX_SUBSTEPS = 15;
+const uint32_t ISTEP4_MAX_SUBSTEPS = 2;
+const uint32_t ISTEP5_MAX_SUBSTEPS = 4;
+
+// File static data
+// @TODO via RTC 129073.
+// Initialise pointer tables.
+
+static istepMap_t g_istep2PtrTbl[ ISTEP2_MAX_SUBSTEPS ] =
+ {
+ { NULL, NULL },
+ { &istepWithProc, &istep1FailHwp },
+ { &istepWithProc, &istep1SuccessHwp }
+
+ };
+static istepMap_t g_istep4PtrTbl[ ISTEP4_MAX_SUBSTEPS ];
+static istepMap_t g_istep5PtrTbl[ ISTEP5_MAX_SUBSTEPS ];
+
+// Functions
+//----------------------------------------------------------------------------
+uint32_t sbeHandleIstep (uint8_t *i_pArg)
+{
+ #define SBE_FUNC "sbeHandleIstep "
+ SBE_DEBUG(SBE_FUNC);
+ uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ //@TODO via RTC 129073.
+ //Use proper initialisation for fapi RC
+ uint32_t fapiRc = SBE_SEC_OPERATION_SUCCESSFUL;
+ uint8_t len = 0;
+ sbeIstepReqMsg_t req;
+ sbeResponseGenericHeader_t respHdr;
+ respHdr.init();
+ sbeResponseFfdc_t ffdc;
+
+ // NOTE: In this function we will have two loops
+ // First loop will deque data and prepare the response
+ // Second response will enque the data on DS FIFO
+ //loop 1
+ do
+ {
+ // @TODO via RTC : 130575
+ // Optimize both the RC handling and
+ // FIFO operation infrastructure.
+ len = sizeof( req )/sizeof(uint32_t);
+ rc = sbeUpFifoDeq_mult ( len, (uint32_t *)&req);
+ if (rc) //FIFO access issue
+ {
+ SBE_ERROR(SBE_FUNC"FIFO dequeue failed, rc[0x%X]", rc);
+ break;
+ }
+ len = 1;
+ rc = sbeUpFifoDeq_mult ( len, NULL, true );
+
+ // If we didn't receive EOT yet
+ if ( rc != SBE_FIFO_RC_EOT_ACKED )
+ {
+ SBE_ERROR(SBE_FUNC"FIFO dequeue failed, rc[0x%X]", rc);
+ break;
+ }
+ // override Rc as we do not want to treat SBE_FIFO_RC_EOT_ACKED as error
+ rc = SBE_SEC_OPERATION_SUCCESSFUL;
+
+ SBE_DEBUG(SBE_FUNC"Major number:0x%08x minor number:0x%08x",
+ req.major, req.minor );
+
+ if( false == validateIstep( req.major, req.minor ) )
+ {
+ SBE_ERROR(SBE_FUNC" Invalid Istep. major:0x%08x"
+ " minor:0x%08x", req.major, req.minor);
+ // @TODO via RTC 129073.
+ // Need to change code asper better error handling.
+ respHdr.setStatus( SBE_PRI_INVALID_DATA,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ break;
+ }
+ fapiRc = sbeExecuteIstep( req.major, req.minor );
+ if( fapiRc )
+ {
+ SBE_ERROR(SBE_FUNC" sbeExecuteIstep() Failed. major:0x%08x"
+ " minor:0x%08x", req.major, req.minor);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ ffdc.setRc(fapiRc);
+ }
+
+ }while(0);
+
+ //loop 2
+ do
+ {
+ // FIFO error
+ if ( rc )
+ {
+ break;
+ }
+
+ uint32_t distance = 1; //initialise by 1 for entry count itself.
+ len = sizeof(respHdr)/sizeof(uint32_t);
+ // sbeDownFifoEnq_mult.
+ rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &respHdr);
+ if (rc)
+ {
+ break;
+ }
+ distance += len;
+
+ // If no ffdc , exit;
+ if( ffdc.fapiRc )
+ {
+ len = sizeof(ffdc)/sizeof(uint32_t);
+ rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &ffdc);
+ if (rc)
+ {
+ break;
+ }
+ distance += len;
+ }
+ len = sizeof(distance)/sizeof(uint32_t);
+ //@TODO via 129076.
+ //Need to add FFDC data as well.
+ rc = sbeDownFifoEnq_mult ( len, &distance);
+ if (rc)
+ {
+ break;
+ }
+ }while(0);
+
+ if( rc )
+ {
+ SBE_ERROR( SBE_FUNC"Failed. rc[0x%X]", rc);
+ }
+ return rc;
+ #undef SBE_FUNC
+}
+
+//----------------------------------------------------------------------------
+// @TODO via RTC 129073.
+// Change return code as per design
+// @note This is the responsibilty of caller to verify major/minor
+// number before calling this function
+
+// @TODO via RTC 129077.
+// This function should check for system checkstop as well.
+uint32_t sbeExecuteIstep (const uint8_t i_major, const uint8_t i_minor)
{
- uint32_t l_rc = 0;
- SBE_TRACE("sbeExecuteIstep");
+ #define SBE_FUNC "sbeExecuteIstep "
+ SBE_DEBUG(SBE_FUNC"Major number:0x%x minor number:0x%x",
+ i_major, i_minor );
+ uint32_t rc = 0;
+ switch( i_major )
+ {
+ case SBE_ISTEP2:
+ rc = (g_istep2PtrTbl[i_minor-1].istepWrapper)(
+ g_istep2PtrTbl[i_minor-1].istepHwp);
+ break;
+
+ case SBE_ISTEP4:
+ rc = (g_istep4PtrTbl[i_minor-1].istepWrapper)(
+ g_istep4PtrTbl[i_minor-1].istepHwp);
+ break;
+
+ case SBE_ISTEP5:
+ rc = (g_istep5PtrTbl[i_minor-1].istepWrapper)(
+ g_istep5PtrTbl[i_minor-1].istepHwp);
+ break;
+
+ // We should never reach here as before calling this validation has
+ // been done.
+ // @TODO via RTC 129166.
+ // assert if we reach in default case.
+ default:
+ break;
+ }
+
+ return rc;
+ #undef SBE_FUNC
+}
- return l_rc;
+//----------------------------------------------------------------------------
+bool validateIstep (const uint8_t i_major, const uint8_t i_minor)
+{
+ bool valid = true;
+ do
+ {
+ if( 0 == i_minor )
+ {
+ valid = false;
+ break;
+ }
+
+ switch( i_major )
+ {
+ case SBE_ISTEP2:
+ // istep 2.1 loads image to PIBMEM
+ // So SBE control loop can not execute istep 2.1.
+ if(( i_minor > ISTEP2_MAX_SUBSTEPS ) || ( i_minor == 1) )
+ {
+ valid = false;
+ }
+ break;
+
+ case SBE_ISTEP4:
+ if( i_minor > ISTEP4_MAX_SUBSTEPS )
+ {
+ valid = false;
+ }
+ break;
+
+ case SBE_ISTEP5:
+ if( i_minor > ISTEP5_MAX_SUBSTEPS )
+ {
+ valid = false;
+ }
+ break;
+
+ default:
+ valid= false;
+ break;
+ }
+ } while(0);
+
+ return valid;
+}
+
+//----------------------------------------------------------------------------
+
+uint32_t istepWithProc( sbe_istep_hwp i_hwp)
+{
+ SBE_DEBUG("istepWithProc");
+ uint32_t rc = 0;
+ if( i_hwp )
+ {
+ rc = i_hwp();
+ }
+ return rc;
}
+//----------------------------------------------------------------------------
uint32_t sbeWaitForSbeIplDone (uint8_t *i_pArg)
{
- uint32_t l_rc = 0;
+ uint32_t rc = 0;
SBE_TRACE("sbeWaitForSbeIplDone");
- return l_rc;
+ return rc;
}
diff --git a/sbe/sbefw/sbecmdiplcontrol.H b/sbe/sbefw/sbecmdiplcontrol.H
index 286dea82..9440889c 100644
--- a/sbe/sbefw/sbecmdiplcontrol.H
+++ b/sbe/sbefw/sbecmdiplcontrol.H
@@ -3,12 +3,6 @@
*
* @brief This file contains the SBE command details
*
- * Change Log *****************************************************************
- * Flag Defect/Feature User Date Description
- * ---- -------------- ---- ---- -----------
- * basengup 2015/03/17 Created
- *
- * @endverbatim
*/
#ifndef __SBEFW_SBECMDIPLCONTROL_H
@@ -17,9 +11,23 @@
#include <stdint.h>
-uint32_t sbeExecuteIstep (uint8_t *i_pArg);
+/**
+ * @brief execute istep chipop (0xA101)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
+uint32_t sbeHandleIstep(uint8_t *i_pArg);
+/**
+ * @brief Handles wait for IPL done chipop (0xA102)
+ *
+ * @param[in] i_pArg Buffer to be passed to the function (not used as of now)
+ *
+ * @return Rc from the FIFO access utility
+ */
uint32_t sbeWaitForSbeIplDone (uint8_t *i_pArg);
diff --git a/sbe/sbefw/sbecmdparser.C b/sbe/sbefw/sbecmdparser.C
index 24b968eb..736f3221 100644
--- a/sbe/sbefw/sbecmdparser.C
+++ b/sbe/sbefw/sbecmdparser.C
@@ -34,7 +34,7 @@ static sbeCmdStruct_t g_sbeScomCmdArray [] =
////////////////////////////////////////////////////////////////
static sbeCmdStruct_t g_sbeIplControlCmdArray [] =
{
- {sbeExecuteIstep,
+ {sbeHandleIstep,
SBE_CMD_EXECUTE_ISTEP,
SBE_FENCE_AT_CONTINUOUS_IPL|SBE_FENCE_AT_RUNTIME|SBE_FENCE_AT_MPIPL,
},
diff --git a/sbe/sbefw/sbecmdprocessor.C b/sbe/sbefw/sbecmdprocessor.C
index b5d95bd3..b9a6e9b2 100644
--- a/sbe/sbefw/sbecmdprocessor.C
+++ b/sbe/sbefw/sbecmdprocessor.C
@@ -143,8 +143,8 @@ void sbeSyncCommandProcessor_routine(void *i_pArg)
// @TODO via RTC: 128658
// Review if Mutex protection is required
// for all the globals used between threads
- l_cmdClass = (uint8_t)(g_sbeCmdHdr.cmdReqHdr_cmdClass>>8) ;
- l_cmdOpCode = (uint8_t)(g_sbeCmdHdr.cmdReqHdr_cmdClass) ;
+ l_cmdClass = g_sbeCmdHdr.cmdClass;
+ l_cmdOpCode = g_sbeCmdHdr.command;
// Get the command function
l_pFuncP = sbeFindCmdFunc (l_cmdClass, l_cmdOpCode) ;
diff --git a/sbe/sbefw/sbecmdreceiver.C b/sbe/sbefw/sbecmdreceiver.C
index e15ecd1c..95061fdc 100644
--- a/sbe/sbefw/sbecmdreceiver.C
+++ b/sbe/sbefw/sbecmdreceiver.C
@@ -13,7 +13,7 @@
#include "sbetrace.H"
#include "sbe_sp_intf.H"
-sbeCmdHdr_t g_sbeCmdHdr ;
+sbeCmdReqBuf_t g_sbeCmdHdr;
sbeCmdRespHdr_t g_sbeCmdRespHdr;
//////////////////////////////////////////////////////
@@ -38,7 +38,7 @@ void sbeCommandReceiver_routine(void *i_pArg)
// for all the globals used between threads
g_sbeCmdRespHdr.prim_status = SBE_PRI_OPERATION_SUCCESSFUL;
g_sbeCmdRespHdr.sec_status = SBE_SEC_OPERATION_SUCCESSFUL;
- g_sbeCmdHdr.cmdReqHdr_cmdClass = SBE_CMD_CLASS_UNKNOWN;
+ g_sbeCmdHdr.cmdClass = SBE_CMD_CLASS_UNKNOWN;
// inner loop for command handling
do
@@ -59,9 +59,8 @@ void sbeCommandReceiver_routine(void *i_pArg)
// The responsibility of this thread is limited to dequeueing
// only the first two word entries from the protocol header.
- uint32_t l_ufifo_data[2] = {0};
- uint8_t l_len2dequeue = 2;
- l_rc = sbeUpFifoDeq_mult ( l_len2dequeue, &l_ufifo_data[0] );
+ uint8_t len = sizeof( g_sbeCmdHdr)/ sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult ( len, (uint32_t *)&g_sbeCmdHdr );
// If FIFO reset is requested,
if (l_rc == SBE_FIFO_RC_RESET)
@@ -97,18 +96,10 @@ void sbeCommandReceiver_routine(void *i_pArg)
break;
}
- // Successfully dequeued two mandatory entries;
- // First entry corresponds to command length parameter
- g_sbeCmdHdr.cmdReqHdr_cmdLen = l_ufifo_data[0];
-
- // Second entry contains the command class
- // and the opcode parameters
- g_sbeCmdHdr.cmdReqHdr_cmdClass = l_ufifo_data[1];
-
// validate the command class and sub-class opcodes
l_rc = sbeValidateCmdClass (
- (uint8_t)(g_sbeCmdHdr.cmdReqHdr_cmdClass>>8),
- (uint8_t)(g_sbeCmdHdr.cmdReqHdr_cmdClass) ) ;
+ g_sbeCmdHdr.cmdClass,
+ g_sbeCmdHdr.command ) ;
if (l_rc)
{
diff --git a/sbe/sbefw/sbefifo.H b/sbe/sbefw/sbefifo.H
index e9a815b0..bf1c3123 100644
--- a/sbe/sbefw/sbefifo.H
+++ b/sbe/sbefw/sbefifo.H
@@ -11,6 +11,7 @@
#include "sbeexeintf.H"
#include "sbetrace.H"
#include "ppe42_scom.h"
+#include "sbe_sp_intf.H"
/**
* @brief SBE FIFO Access addresses
@@ -61,6 +62,22 @@ typedef union
uint32_t upfifo_status_uint32;
} sbe_upfifo_status_t;
+/**
+ * @brief FIFO access return codes for internal purpose
+ *
+ */
+typedef enum
+{
+ SBE_FIFO_RC_ACCESS_SUCCESS = 0,
+ SBE_FIFO_RC_RESET = 0xE0,
+ SBE_FIFO_RC_FULL,
+ SBE_FIFO_RC_EMPTY,
+ SBE_FIFO_RC_DUMMY_DATA,
+ SBE_FIFO_RC_EOT_ACKED,
+ SBE_FIFO_RC_EOT_ACK_FAILED,
+ SBE_FIFO_RC_UNKNOWN,
+} sbe_fifo_access_rc_t;
+
/**
* @brief 64-bit DW structure for Upstream FIFO Read
@@ -101,17 +118,124 @@ typedef union
} sbe_downfifo_status_t;
+// @TODO via RTC 129073.
+// Put these structures in separate file as these are not FIFO specific.
+// Also make sure all FIFO structures are 32 bit alligned ( the largest
+// member should be atleast 4 byte). It is required as in sbe fifo
+// operation we are casting these structures to uint32_t pointer. It can
+// cause allignment issue if largest member of structure is not atleast
+// 32 bit. We can use bit fields to optimize memory requirements.
/**
* @brief Command Request Header
+ */
+typedef struct
+{
+ uint32_t len;
+ uint16_t reserved;
+ uint8_t cmdClass;
+ uint8_t command;
+}sbeCmdReqBuf_t;
+
+extern sbeCmdReqBuf_t g_sbeCmdHdr;
+
+/**
+ * @brief structure for generic header for fifo response.
*
*/
typedef struct
{
- uint32_t cmdReqHdr_cmdLen ;
- uint32_t cmdReqHdr_cmdClass ;
-} sbeCmdHdr_t;
+ uint16_t magicCode;
+ uint8_t cmdClass;
+ uint8_t command;
+ uint16_t primaryStatus;
+ uint16_t secondaryStatus;
+
+ /**
+ * @brief set the primary and secondary status
+ *
+ * @param[in] i_prim Primary status
+ * @param[in] i_sec Secondary status
+ *
+ * @return
+ */
+ void setStatus( const uint16_t i_prim, const uint16_t i_sec)
+ {
+ primaryStatus = i_prim;
+ secondaryStatus = i_sec;
+ }
+
+ /**
+ * @brief set initial values for response header
+ *
+ * @note We did not set this in constructor as based on use case
+ * it is possible that g_sbeCmdHdr does not have proper
+ * values at time of object creation.
+ *
+ */
+ void init()
+ {
+ magicCode = 0xC0DE;
+ cmdClass = g_sbeCmdHdr.cmdClass;
+ command = g_sbeCmdHdr.command;
+ primaryStatus = SBE_PRI_OPERATION_SUCCESSFUL;
+ secondaryStatus = SBE_SEC_OPERATION_SUCCESSFUL;
+ }
+
+}sbeResponseGenericHeader_t;
+
+/**
+ * @brief structure for ffdc header for fifo response.
+ *
+ */
+typedef struct sbeResponseFfdc
+{
+ uint16_t magicBytes;
+ uint16_t lenInWords; // length in word( 4 byte )
+ //@TODO via RTC 129073.
+ //make fapiRc 64 bit
+ uint32_t fapiRc;
+
+ /**
+ * @brief set rc
+ *
+ * @param[in] i_rc FAPI RC
+ *
+ * @return
+ */
+ void setRc(const uint32_t i_rc)
+ {
+ fapiRc = i_rc;
+ }
+
+ /**
+ * @brief constructor
+ *
+ * @param[in] i_rc FAPI RC
+ *
+ * @return
+ */
+ sbeResponseFfdc()
+ {
+ magicBytes = 0xFFDC;
+ //TODO via 129076.
+ //Need to change value for length once FFDC design is final.
+ lenInWords = ( sizeof(magicBytes) + sizeof(lenInWords)
+ + sizeof(fapiRc) )/ sizeof(uint32_t);
+ fapiRc = 0;
+ }
+}sbeResponseFfdc_t;
-extern sbeCmdHdr_t g_sbeCmdHdr;
+/**
+ * @brief structure for execute istep chipop (0xA101) contents.
+ *
+ */
+typedef struct
+{
+ uint8_t reserved1;
+ uint8_t major;
+ uint8_t reserved2;
+ uint8_t minor;
+}sbeIstepReqMsg_t;
/**
@@ -134,22 +258,6 @@ typedef struct
uint16_t len;
} sbeCmdResp_FFDC_t;
-/**
- * @brief FIFO access return codes for internal purpose
- *
- */
-typedef enum
-{
- SBE_FIFO_RC_ACCESS_SUCCESS = 0,
- SBE_FIFO_RC_RESET = 0xE0,
- SBE_FIFO_RC_FULL,
- SBE_FIFO_RC_EMPTY,
- SBE_FIFO_RC_DUMMY_DATA,
- SBE_FIFO_RC_EOT_ACKED,
- SBE_FIFO_RC_EOT_ACK_FAILED,
- SBE_FIFO_RC_UNKNOWN,
-} sbe_fifo_access_rc_t;
-
/*****************************************************************/
/** Upstream FIFO access utilities **/
@@ -296,7 +404,9 @@ extern uint32_t sbeDownFifoEnq_mult (uint8_t &io_len,
*/
extern inline uint32_t sbeBuildRespHeaderMagicCodeCmdClass (void)
{
- return ( 0xC0DE0000 | g_sbeCmdHdr.cmdReqHdr_cmdClass );
+ return ( (0xC0DE0000 ) |
+ (uint32_t)(g_sbeCmdHdr.cmdClass << 8) |
+ (uint32_t)(g_sbeCmdHdr.command ));
}
/**
OpenPOWER on IntegriCloud