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/sbecmdcntlinst.C | |
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/sbecmdcntlinst.C')
-rw-r--r-- | sbe/sbefw/sbecmdcntlinst.C | 200 |
1 files changed, 200 insertions, 0 deletions
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 +} + |