diff options
author | Raja Das <rajadas2@in.ibm.com> | 2016-03-04 04:14:22 -0600 |
---|---|---|
committer | AMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com> | 2016-04-22 02:41:17 -0400 |
commit | 5af091aec6361f4d3dfb1ae3966a5f9cde7a29a2 (patch) | |
tree | dce5f55f347076fc3fd00597a584888ebc2d32aa /sbe/sbefw | |
parent | 37604a05d48d56d7120d0d178b575cbfd2346329 (diff) | |
download | talos-sbe-5af091aec6361f4d3dfb1ae3966a5f9cde7a29a2.tar.gz talos-sbe-5af091aec6361f4d3dfb1ae3966a5f9cde7a29a2.zip |
Support for Control Instruction
Change-Id: Ib6f1e15a199f08aeb48e2486f0be901832ff4127
RTC:128325
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/21787
Tested-by: Jenkins Server
Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Reviewed-by: Santosh S. Puranik <santosh.puranik@in.ibm.com>
Reviewed-by: AMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com>
Diffstat (limited to 'sbe/sbefw')
-rw-r--r-- | sbe/sbefw/sbeSpMsg.H | 68 | ||||
-rw-r--r-- | sbe/sbefw/sbe_sp_intf.H | 42 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdcntlinst.C | 200 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdcntlinst.H | 22 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdgeneric.C | 3 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdparser.C | 21 | ||||
-rw-r--r-- | sbe/sbefw/sbefwfiles.mk | 2 |
7 files changed, 356 insertions, 2 deletions
diff --git a/sbe/sbefw/sbeSpMsg.H b/sbe/sbefw/sbeSpMsg.H index ff49e2f2..7d8e3fb1 100644 --- a/sbe/sbefw/sbeSpMsg.H +++ b/sbe/sbefw/sbeSpMsg.H @@ -408,4 +408,72 @@ typedef struct extern sbeCmdRespHdr_t g_sbeCmdRespHdr; +/** + * @brief structure for Control Instruction Chipop (0xA701) contents. + * + */ +typedef struct +{ + uint32_t reserved:12; + sbeErrorMode mode:4; + sbeCoreChipletId coreChipletId:8; + sbeThreadNum threadNum:4; + sbeThreadOps threadOps:4; + + /** + * @brief Validate input arguments + * + * @return bool, true if the validation is success, else false for + * validation failure + */ + bool validateInputArgs() + { + bool l_validatePassFlag = true; + // Validate Thread Command / Thread Num / Error Mode + if((threadOps > THREAD_SRESET_INS) || + (mode > IGNORE_HW_ERRORS) || + !((threadNum <= SMT4_THREAD3) || (threadNum == SMT4_THREAD_ALL))) + { + SBE_ERROR(SBE_FUNC "Invalid Parameter by User, ThreadOps[%d] " + "mode[%d] ThreadNum[%d]", threadOps, mode, threadNum); + l_validatePassFlag = false; + } + return l_validatePassFlag; + } + + /** + * @brief Process the input to find out core/thread ids to iterate + * over HWP for the internal business logic + * + * @param[out] o_core, Core Id to start with in the iteration + * @param[out] o_coreCntMax, Core Max count to iterate, start from o_core + * @param[out] o_threadCnt, Thread Num to start with in the iteration + * @param[out] o_threadCntMax, Thread Max Num to iterate, start from + * o_threadCnt + * + * @return void + */ + void processInputDataToIterate(uint8_t & o_core, uint8_t & o_coreCntMax, + uint8_t & o_threadCnt, uint8_t & o_threadCntMax) + { + //Default Init + o_threadCnt = SMT4_THREAD0; + o_threadCntMax = SMT4_THREAD_MAX; + + o_core = SMT4_CORE0_ID; + o_coreCntMax = SMT4_CORE_ID_MAX; + + if( SMT4_ALL_CORES != coreChipletId ) + { + o_core = coreChipletId; + o_coreCntMax = coreChipletId; + } + if( SMT4_THREAD_ALL != threadNum ) + { + o_threadCnt = threadNum; + o_threadCntMax = threadNum; + } + } +}sbeCntlInstRegMsgHdr_t; + #endif // __SBEFW_SBESP_MSG_H diff --git a/sbe/sbefw/sbe_sp_intf.H b/sbe/sbefw/sbe_sp_intf.H index c2f5b546..7f5fac19 100644 --- a/sbe/sbefw/sbe_sp_intf.H +++ b/sbe/sbefw/sbe_sp_intf.H @@ -287,6 +287,48 @@ enum sbeSramAccessMode CIRCULAR_MODE = 0x3, }; +/** + * @brief Error Mode enum + */ +enum sbeErrorMode +{ + EXIT_ON_FIRST_ERROR = 0x0, // Bail out on first error + IGNORE_HW_ERRORS = 0x01, // Attempt best case +}; + +/** + * @brief Core Chiplet Id Enum + */ +enum sbeCoreChipletId +{ + SMT4_CORE0_ID = 0x20, + SMT4_CORE_ID_MAX = 0x38, + SMT4_ALL_CORES = 0xFF, +}; + +/** + * @brief Thread Num Enum + */ +enum sbeThreadNum +{ + SMT4_THREAD0 = 0x0, + SMT4_THREAD1 = 0x1, + SMT4_THREAD2 = 0x2, + SMT4_THREAD3 = 0x3, + SMT4_THREAD_MAX = 0x4, + SMT4_THREAD_ALL = 0xF, +}; + +/** + * @brief Thread Operation Enum + */ +enum sbeThreadOps +{ + THREAD_START_INS = 0x0, + THREAD_STOP_INS = 0x1, + THREAD_STEP_INS = 0x2, + THREAD_SRESET_INS = 0x3, +}; #ifdef __cplusplus } diff --git a/sbe/sbefw/sbecmdcntlinst.C b/sbe/sbefw/sbecmdcntlinst.C new file mode 100644 index 00000000..09eb8232 --- /dev/null +++ b/sbe/sbefw/sbecmdcntlinst.C @@ -0,0 +1,200 @@ +/* + * @file: ppe/sbe/sbefw/sbecmdcntlinst.C + * + * @brief This file contains the SBE Control Instruction chipOps + * + */ + +#include "sbecmdcntlinst.H" +#include "sbefifo.H" +#include "sbe_sp_intf.H" +#include "sbetrace.H" +#include "sbeFifoMsgUtils.H" + +#include "fapi2.H" +#include "p9_thread_control.H" + +using namespace fapi2; + +// This is used to find out the array index in g_control_reg_map in +// p9_thread_control.C +static const uint8_t SINGLE_THREAD_BIT_MASK = 0x08; + +/* @brief Map User Thread Command to Hwp ThreadCommands Enum */ +ThreadCommands getThreadCommand(const sbeCntlInstRegMsgHdr_t & i_req) +{ + ThreadCommands l_cmd = PTC_CMD_START; + switch(i_req.threadOps) + { + case THREAD_START_INS: l_cmd = PTC_CMD_START; break; + case THREAD_STOP_INS: l_cmd = PTC_CMD_STOP; break; + case THREAD_STEP_INS: l_cmd = PTC_CMD_STEP; break; + case THREAD_SRESET_INS: l_cmd = PTC_CMD_SRESET; break; + } + return l_cmd; +} + +/* @brief Map User Mode Command to Hwp Warn Check flag */ +inline bool getWarnCheckFlag(const sbeCntlInstRegMsgHdr_t & i_req) +{ + bool l_warnCheck = false; + if( EXIT_ON_FIRST_ERROR != i_req.mode ) + { + l_warnCheck = true; + } + return l_warnCheck; +} + +/////////////////////////////////////////////////////////////////////// +// @brief sbeCntlInst Sbe control instructions function +// +// @return RC from the underlying FIFO utility +/////////////////////////////////////////////////////////////////////// +uint32_t sbeCntlInst(uint8_t *i_pArg) +{ + #define SBE_FUNC " sbeCntlInst " + SBE_ENTER(SBE_FUNC); + + uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL; + ReturnCode l_fapiRc = FAPI2_RC_SUCCESS; + sbeRespGenHdr_t l_respHdr; + l_respHdr.init(); + sbeResponseFfdc_t l_ffdc; + + // Create the req struct for Control Instructions Chip-op + sbeCntlInstRegMsgHdr_t l_req = {0}; + + do + { + // Get the Req Struct Data sbeCntlInstRegMsgHdr_t from upstream Fifo + uint32_t l_len2dequeue = sizeof(l_req) / sizeof(uint32_t); + l_rc = sbeUpFifoDeq_mult (l_len2dequeue, (uint32_t *)&l_req, true); + + // If FIFO failure + if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc ) + { + // Let command processor routine to handle the RC. + break; + } + + SBE_DEBUG("mode[0x%04X] coreChipletId[0x%08X] threadNum[0x%04X] " + "threadOps[0x%04X] ", l_req.mode, l_req.coreChipletId, + l_req.threadNum, l_req.threadOps); + + // Validate Input Args + if( false == l_req.validateInputArgs()) + { + SBE_ERROR(SBE_FUNC "ValidateAndMapInputArgs failed"); + l_respHdr.setStatus( SBE_PRI_INVALID_DATA, + SBE_SEC_GENERIC_FAILURE_IN_EXECUTION ); + break; + } + + // Fetch HWP mapped values + bool l_warnCheck = getWarnCheckFlag(l_req); + ThreadCommands l_cmd = getThreadCommand(l_req); + + // Default assignment not required since it is assigned below + uint8_t l_core, l_coreCntMax; + uint8_t l_threadCnt, l_threadCntMax; + + l_req.processInputDataToIterate(l_core, l_coreCntMax, + l_threadCnt, l_threadCntMax); + fapi2::buffer<uint64_t> l_data64; + uint64_t l_state; + do + { + fapi2::Target<fapi2::TARGET_TYPE_CORE> l_coreTgt( + plat_getTargetHandleByChipletNumber(l_core)); + + uint8_t l_thread = l_threadCnt; + do + { + // Call the Procedure + l_fapiRc = p9_thread_control( + l_coreTgt, + (SINGLE_THREAD_BIT_MASK >> l_thread), + l_cmd, l_warnCheck, + l_data64, l_state); + + if(l_fapiRc != FAPI2_RC_SUCCESS) + { + SBE_ERROR(SBE_FUNC "Failed for Core[%d] Thread [%d] " + "Cmd[%d] Mode[%d]", l_core, l_thread, l_req.threadOps, + l_req.mode); + if(IGNORE_HW_ERRORS == l_req.mode) + { + // No need to delete the l_fapiRc handle,it will get + // over-written + SBE_DEBUG(SBE_FUNC "Continuing in case of HW Errors" + " As user has passed to ignore errors."); + continue; + } + else + { + SBE_ERROR(SBE_FUNC "Breaking out, since User has " + "Selected the mode to exit on first error."); + l_respHdr.setStatus(SBE_PRI_GENERIC_EXECUTION_FAILURE, + SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); + l_ffdc.setRc(l_fapiRc); + break; + } + } + }while(++l_thread < l_threadCntMax); + + // If FapiRc from the inner loop (thread loop), just break here + if ( l_fapiRc ) + { + break; // From core while loop + } + }while(++l_core < l_coreCntMax); + + }while(0); + + // Create the Response to caller + do + { + // If there was a FIFO error, will skip sending the response, + // instead give the control back to the command processor thread + if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc) + { + break; + } + + uint32_t l_dist2Hdr = 1; + // Now enqueue the minimum response header + uint32_t l_len = sizeof(l_respHdr) / sizeof(uint32_t); + l_rc = sbeDownFifoEnq_mult(l_len, (uint32_t *)(&l_respHdr) ); + if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc) + { + break; + } + + l_dist2Hdr += l_len; + + // Enqueue FFDC data if there is one + if( l_ffdc.getRc() ) + { + l_len = sizeof(l_ffdc) / sizeof(uint32_t); + l_rc = sbeDownFifoEnq_mult ( l_len, (uint32_t *)(&l_ffdc) ); + if ( SBE_SEC_OPERATION_SUCCESSFUL != l_rc) + { + break; + } + + l_dist2Hdr += l_len; + } + + l_len = sizeof(l_dist2Hdr) / sizeof(uint32_t); + l_rc = sbeDownFifoEnq_mult ( l_len, &l_dist2Hdr); + if ( l_rc ) + { + break; + } + }while(0); + + SBE_EXIT(SBE_FUNC); + return l_rc; + #undef SBE_FUNC +} + diff --git a/sbe/sbefw/sbecmdcntlinst.H b/sbe/sbefw/sbecmdcntlinst.H new file mode 100644 index 00000000..61323703 --- /dev/null +++ b/sbe/sbefw/sbecmdcntlinst.H @@ -0,0 +1,22 @@ +/* + * @file: ppe/sbe/sbefw/sbecmdcntlinst.H + * + * @brief This file contains the Interfaces for Control Instructions chip-ops + * + */ + +#ifndef __SBEFW_SBECMDCNTLINST_H +#define __SBEFW_SBECMDCNTLINST_H + +#include <stdint.h> + +/** + * @brief sbeCntlInst : Implements SBE Control instructions ChipOp + * + * @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 sbeCntlInst (uint8_t *i_pArg); + +#endif /* __SBEFW_SBECMDCNTLINST_H */ diff --git a/sbe/sbefw/sbecmdgeneric.C b/sbe/sbefw/sbecmdgeneric.C index eda09d88..8fe7b6a2 100644 --- a/sbe/sbefw/sbecmdgeneric.C +++ b/sbe/sbefw/sbecmdgeneric.C @@ -41,6 +41,9 @@ sbeCapabilityRespMsg::sbeCapabilityRespMsg() PUT_MEMORY_SUPPPORTED | GET_SRAM_OCC_SUPPPORTED | PUT_SRAM_OCC_SUPPPORTED; + + capability[INSTRUCTION_CTRL_CAPABILITY_START_IDX] = + CONTROL_INSTRUCTIONS_SUPPPORTED; } // Functions //---------------------------------------------------------------------------- diff --git a/sbe/sbefw/sbecmdparser.C b/sbe/sbefw/sbecmdparser.C index f71e5a96..6769be77 100644 --- a/sbe/sbefw/sbecmdparser.C +++ b/sbe/sbefw/sbecmdparser.C @@ -12,6 +12,7 @@ #include "sbecmdmemaccess.H" #include "sbecmdcntrldmt.H" #include "sbecmdsram.H" +#include "sbecmdcntlinst.H" #include "sbetrace.H" #include "sbe_sp_intf.H" #include "sbeHostMsg.H" @@ -103,6 +104,18 @@ static sbeCmdStruct_t g_sbeMemoryAccessCmdArray [] = }; ////////////////////////////////////////////////////////////// +// @brief g_sbeInstructionCntlCmdArray +// +////////////////////////////////////////////////////////////// +static sbeCmdStruct_t g_sbeInstructionCntlCmdArray[] = +{ + {sbeCntlInst, + SBE_CMD_CONTROL_INSTRUCTIONS, + SBE_FENCE_AT_CONTINUOUS_IPL, + }, +}; + +////////////////////////////////////////////////////////////// // @brief g_sbeCoreStateControlCmdArray // ////////////////////////////////////////////////////////////// @@ -120,7 +133,7 @@ uint8_t sbeGetCmdStructAttr (const uint8_t i_cmdClass, sbeCmdStruct_t **o_ppCmd) { #define SBE_FUNC " sbeGetCmdStructAttr " - SBE_DEBUG(SBE_FUNC); + SBE_DEBUG(SBE_FUNC "i_cmdClass [0x%08X]", i_cmdClass); uint8_t l_numCmds = 0; *o_ppCmd = NULL; @@ -151,6 +164,12 @@ uint8_t sbeGetCmdStructAttr (const uint8_t i_cmdClass, *o_ppCmd = (sbeCmdStruct_t*)g_sbeMemoryAccessCmdArray; break; + case SBE_CMD_CLASS_INSTRUCTION_CONTROL: + l_numCmds = sizeof(g_sbeInstructionCntlCmdArray) / + sizeof(sbeCmdStruct_t); + *o_ppCmd = (sbeCmdStruct_t*)g_sbeInstructionCntlCmdArray; + break; + // PSU Commands case SBE_PSU_CMD_CLASS_CORE_STATE: l_numCmds = sizeof(g_sbeCoreStateControlCmdArray) / diff --git a/sbe/sbefw/sbefwfiles.mk b/sbe/sbefw/sbefwfiles.mk index 95d4bdf9..32826a7d 100644 --- a/sbe/sbefw/sbefwfiles.mk +++ b/sbe/sbefw/sbefwfiles.mk @@ -14,7 +14,7 @@ SBEFW-CPP-SOURCES += sbeHostUtils.C SBEFW-CPP-SOURCES += sbecmdcntrldmt.C SBEFW-CPP-SOURCES += sbecmdsram.C SBEFW-CPP-SOURCES += sberegaccess.C - +SBEFW-CPP-SOURCES += sbecmdcntlinst.C SBEFW-C-SOURCES = SBEFW-S-SOURCES = |