diff options
-rw-r--r-- | sbe/sbefw/sbecmdiplcontrol.C | 286 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdiplcontrol.H | 22 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdparser.C | 2 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdprocessor.C | 4 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdreceiver.C | 21 | ||||
-rw-r--r-- | sbe/sbefw/sbefifo.H | 152 |
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 )); } /** |