diff options
author | Raja Das <rajadas2@in.ibm.com> | 2016-02-18 03:36:27 -0600 |
---|---|---|
committer | AMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com> | 2016-03-23 04:40:35 -0400 |
commit | 19139d2eb05f1211bd21e5ee3689ae9a215cf0fc (patch) | |
tree | 959c0a2015f7c4094567491d6db37d91cde6a3f1 /sbe | |
parent | 911cc624014689c649651764ba784237c58c815a (diff) | |
download | talos-sbe-19139d2eb05f1211bd21e5ee3689ae9a215cf0fc.tar.gz talos-sbe-19139d2eb05f1211bd21e5ee3689ae9a215cf0fc.zip |
Control DeadMan Loop Support
Change-Id: Icee15457cd7abb8779e1134fc88063b2437e3281
RTC:134270
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/21038
Tested-by: Jenkins Server
Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Reviewed-by: AMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com>
Diffstat (limited to 'sbe')
-rw-r--r-- | sbe/sbefw/sbeHostMsg.H | 1 | ||||
-rw-r--r-- | sbe/sbefw/sbeHostUtils.C | 65 | ||||
-rw-r--r-- | sbe/sbefw/sbeHostUtils.H | 18 | ||||
-rw-r--r-- | sbe/sbefw/sbe_host_intf.H | 6 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdcntrldmt.C | 239 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdcntrldmt.H | 13 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdparser.C | 9 | ||||
-rw-r--r-- | sbe/sbefw/sbecmdprocessor.C | 19 |
8 files changed, 312 insertions, 58 deletions
diff --git a/sbe/sbefw/sbeHostMsg.H b/sbe/sbefw/sbeHostMsg.H index a3632908..12ab1502 100644 --- a/sbe/sbefw/sbeHostMsg.H +++ b/sbe/sbefw/sbeHostMsg.H @@ -11,6 +11,7 @@ #include <stdint.h> #include "sbe_host_intf.H" +#include "sbe_sp_intf.H" /*****************************************************************/ /* SBE->PSU request structures */ diff --git a/sbe/sbefw/sbeHostUtils.C b/sbe/sbefw/sbeHostUtils.C index f8622566..028245c1 100644 --- a/sbe/sbefw/sbeHostUtils.C +++ b/sbe/sbefw/sbeHostUtils.C @@ -22,20 +22,20 @@ /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// uint32_t sbeReadPsu2SbeMbxReg (uint32_t i_addr, - uint8_t &io_count, + const uint8_t i_count, uint64_t *o_pData) { #define SBE_FUNC " sbeReadPsu2SbeMbxReg " - SBE_DEBUG(SBE_FUNC"io_count[0x%02X], i_addr=[0x%08X]", io_count, i_addr); + SBE_DEBUG(SBE_FUNC"i_count[0x%02X], i_addr=[0x%08X]", i_count, i_addr); uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL; uint8_t l_count = 0; - assert((io_count >0 ) && (NULL != o_pData)) + assert((i_count >0 ) && (NULL != o_pData)) assert( (SBE_HOST_PSU_MBOX_REG0 <= i_addr) && - (SBE_HOST_PSU_MBOX_REG3 >= (i_addr + io_count - 1)) ) + (SBE_HOST_PSU_MBOX_REG3 >= (i_addr + i_count - 1)) ) - while (l_count < io_count) + while (l_count < i_count) { l_rc = getscom_abs ( i_addr, reinterpret_cast<uint64_t*>(&o_pData[l_count]) ); @@ -53,9 +53,6 @@ uint32_t sbeReadPsu2SbeMbxReg (uint32_t i_addr, ++l_count; ++i_addr; } - - // Indicate the number of Mbx registers read off - io_count = l_count; return l_rc; #undef SBE_FUNC @@ -99,39 +96,49 @@ uint32_t sbeAcknowledgeHost () /////////////////////////////////////////////////////////////////// uint32_t sbeWriteSbe2PsuMbxReg (uint32_t i_addr, const uint64_t *i_pData, - uint8_t &io_count) + const uint8_t i_count, + bool i_setBit0ToIntrHB) { #define SBE_FUNC " sbeWriteSbe2PsuMbxReg " - SBE_DEBUG(SBE_FUNC"io_count[0x%02X], i_addr=[0x%08X]", io_count, i_addr); + SBE_DEBUG(SBE_FUNC"i_count[0x%02X], i_addr=[0x%08X]", i_count, i_addr); uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL; uint8_t l_count = 0; - assert( ((io_count >0 ) && (NULL != i_pData)) || (io_count = 0) ) + assert( (i_count >0 ) && (NULL != i_pData) ) assert( (SBE_HOST_PSU_MBOX_REG4 <= i_addr) && - (SBE_HOST_PSU_MBOX_REG7 >= (i_addr + io_count - 1)) ) + (SBE_HOST_PSU_MBOX_REG7 >= (i_addr + i_count - 1)) ) - while ( (g_sbePsu2SbeCmdReqHdr.flags & SBE_PSU_FLAGS_RESP_REQUIRED) && - (l_count < io_count) ) + if( g_sbePsu2SbeCmdReqHdr.flags & SBE_PSU_FLAGS_RESP_REQUIRED ) { - SBE_DEBUG(SBE_FUNC"l_data=[0x%016X]", *(i_pData+l_count)); - - l_rc = putscom_abs ( i_addr, *(i_pData+l_count) ); - - if (l_rc) + while (l_count < i_count) { - // Error while reading from PSU->SBE mbx register - SBE_ERROR(SBE_FUNC"putscom_abs failed," - "l_rc=[0x%08X], i_addr=[0x%08X]", - l_rc, i_addr); - break; + SBE_DEBUG(SBE_FUNC"l_data=[0x%016X]", *(i_pData+l_count)); + + l_rc = putscom_abs ( i_addr, *(i_pData+l_count) ); + if (l_rc) + { + // Error while reading from PSU->SBE mbx register + SBE_ERROR(SBE_FUNC"putscom_abs failed," + "l_rc=[0x%08X], i_addr=[0x%08X]", + l_rc, i_addr); + break; + } + + ++l_count; + ++i_addr; } - ++l_count; - ++i_addr; + if( (i_setBit0ToIntrHB) && (SBE_SEC_OPERATION_SUCCESSFUL == l_rc) ) + { + // indicate the Host via Bit SBE_SBE2PSU_DOORBELL_SET_BIT0 + l_rc = sbeSetSbe2PsuDbBitX(SBE_SBE2PSU_DOORBELL_SET_BIT0); + if(l_rc) + { + SBE_ERROR(SBE_FUNC " Failed to Sent Ack to Host over " + "SBE_SBE2PSU_DOORBELL_SET_BIT0"); + } + } } - - // Indicate the number of Mbx registers written into - io_count = l_count; return l_rc; #undef SBE_FUNC diff --git a/sbe/sbefw/sbeHostUtils.H b/sbe/sbefw/sbeHostUtils.H index e4e6e211..d8324233 100644 --- a/sbe/sbefw/sbeHostUtils.H +++ b/sbe/sbefw/sbeHostUtils.H @@ -107,16 +107,15 @@ inline uint32_t sbeReadPsu2SbeDbReg (uint64_t *o_data) * * @param[in] i_addr * Starting Mbx Register Address - * @param[in/out] io_count - * On input: Number of Mbx registers to be read. - * On output: Number of Mbx registers read. + * @param[in] i_count + * Number of Mbx registers to be read. * @param[out] o_pData * Contents of the Mbx registers read into the buffer * @return Return Code * SUCCESS or TBD */ uint32_t sbeReadPsu2SbeMbxReg (uint32_t i_addr, - uint8_t &io_count, + const uint8_t i_count, uint64_t *o_pData); /*****************************************************************/ @@ -189,14 +188,17 @@ uint32_t sbeIntrHostUponRespWaiting(); * Starting Mbx Register Address * @param[in] i_pData * Contains the data to be written into given Mbx registers - * @param[in/out] io_count - * On input: Number of Mbx registers to be written. - * On output: Number of Mbx registers written. + * @param[in] i_count + * Number of Mbx registers to be written. + * @param[in] i_setBit0ToIntrHB + * Indicates whether to write Bit0 to interrupt the Host, + * By default it is false. * @return Return Code * SUCCESS or TBD */ uint32_t sbeWriteSbe2PsuMbxReg (uint32_t i_addr, const uint64_t *i_pData, - uint8_t &io_count); + const uint8_t i_count, + bool i_setBit0ToIntrHB = false); #endif // __SBEFW_SBEHOSTUTILS_H diff --git a/sbe/sbefw/sbe_host_intf.H b/sbe/sbefw/sbe_host_intf.H index d6263645..e31813e9 100644 --- a/sbe/sbefw/sbe_host_intf.H +++ b/sbe/sbefw/sbe_host_intf.H @@ -47,4 +47,10 @@ enum sbePsuControlFlags SBE_PSU_FLAGS_ACK_REQUIRED = 0x0200, }; +enum sbePsuDmtCmdFlags +{ + SBE_PSU_FLAGS_START_DMT = 0x0001, + SBE_PSU_FLAGS_STOP_DMT = 0x0002, +}; + #endif // __SBEFW_SBE_HOST_INTF_H diff --git a/sbe/sbefw/sbecmdcntrldmt.C b/sbe/sbefw/sbecmdcntrldmt.C index 8c6178d6..ed4ea95b 100644 --- a/sbe/sbefw/sbecmdcntrldmt.C +++ b/sbe/sbefw/sbecmdcntrldmt.C @@ -6,21 +6,248 @@ */ #include "sbecmdcntrldmt.H" -#include "sbefifo.H" #include "sbetrace.H" -#include "sbe_sp_intf.H" #include "sbe_build_info.H" -#include "sbeFifoMsgUtils.H" #include "sbeHostMsg.H" +#include "sbeHostUtils.H" +#include "sbe_sp_intf.H" +#include "fapi2.H" +#include "p9_sbe_check_master_stop15.H" +#include "p9_perv_scom_addresses.H" + +using namespace fapi2; + +//////////////////////////////////////////////////////////////////// +//Static initialization of the Dmt Pk timer +PkTimer g_sbe_pk_dmt_timer; +// Global Flag to indicate Dmt Timer Expiry +bool g_SbeDmtTimerExpired = false; + +///////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////// +void sbeDmtPkExpiryCallback(void *) +{ + #define SBE_FUNC "sbeDmtPkExpiryCallback" + SBE_INFO(SBE_FUNC" DMT Callback Timer has expired..Checkstop the system "); + g_SbeDmtTimerExpired = true; + + // check stop the system + uint32_t l_status = SBE_PCB_PIB_ERROR_NONE; + l_status = putscom_abs (PERV_N3_LOCAL_FIR_OR, N3_FIR_CORE_CHECKSTOP_BIT); + if(SBE_PCB_PIB_ERROR_NONE != l_status) + { + // Scom failed + SBE_ERROR(SBE_FUNC "PutScom failed for REG PERV_N3_LOCAL_FIR"); + // TODO - Store the response in Async Response + // RTC:149074 + } + #undef SBE_FUNC +} + +///////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////// +uint32_t sbeStartCntlDmt() +{ + #define SBE_FUNC "sbeStartCntlDmt" + uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL; + int l_pkRc = 0; + ReturnCode l_fapiRc = FAPI2_RC_SUCCESS; + g_SbeDmtTimerExpired = false; + + do + { + // Fetch the Timer Value and Start a Pk Timer + uint64_t l_timerVal = 0; + l_rc = sbeReadPsu2SbeMbxReg(SBE_HOST_PSU_MBOX_REG1, + (sizeof(l_timerVal)/sizeof(uint64_t)), + &l_timerVal); + if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc) + { + SBE_ERROR(SBE_FUNC" Failed to extract SBE_HOST_PSU_MBOX_REG1"); + break; + } + + // Attach Callback + PkTimerCallback l_callback = &sbeDmtPkExpiryCallback; + + // Create Timer with the above value + l_pkRc = pk_timer_create(&g_sbe_pk_dmt_timer, l_callback, NULL); + if(l_pkRc) + { + SBE_ERROR(SBE_FUNC" Pk Timer Create failed, RC=[%d]", l_pkRc); + l_rc = SBE_SEC_OS_FAILURE; + break; + } + + // Schedule the timer + l_pkRc = pk_timer_schedule(&g_sbe_pk_dmt_timer, + PK_MILLISECONDS((uint32_t)l_timerVal)); + if(l_pkRc) + { + SBE_ERROR(SBE_FUNC" Pk Timer Schedule failed, RC=[%d]", l_pkRc); + l_rc = SBE_SEC_OS_FAILURE; + break; + } + + l_rc = sbeWriteSbe2PsuMbxReg(SBE_HOST_PSU_MBOX_REG4, + (uint64_t*)(&g_sbeSbe2PsuRespHdr), + (sizeof(g_sbeSbe2PsuRespHdr)/sizeof(uint64_t)), + true); + if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc) + { + SBE_ERROR(SBE_FUNC" Failed to write to " + "SBE_HOST_PSU_MBOX_REG4"); + break; + } + + // Fetch the master core + Target<TARGET_TYPE_PROC_CHIP > l_procTgt = plat_getChipTarget(); + + // Fetch the MASTER_CORE attribute + uint8_t l_coreId = 0; + FAPI_ATTR_GET(fapi2::ATTR_MASTER_CORE,l_procTgt,l_coreId); + + // Construct the Master Core Target + fapi2::Target<fapi2::TARGET_TYPE_CORE > l_coreTgt( + (uint64_t)l_coreId); + + // Call Hwp p9_sbe_check_master_stop15 and loop + // Go around a loop till you get FAPI2_RC_SUCCESS + do + { + l_fapiRc = p9_sbe_check_master_stop15(l_coreTgt); + //Conversion is required here, since ReturnCode doesn't support + //comparision '!=' or '==' + //TODO RTC:149021 + uint32_t l_rcFapi = l_fapiRc; + if( (l_rcFapi != fapi2::RC_CHECK_MASTER_STOP15_PENDING) && + (l_rcFapi != FAPI2_RC_SUCCESS)) + { + SBE_ERROR(SBE_FUNC" p9_sbe_check_master_stop15 " + "returned failure"); + // Async Response to be stored + // RTC:149074 + break; + } + + // Only for Pending and Success case + if(RC_CHECK_MASTER_STOP15_PENDING != l_rcFapi) // Success + { + // indicate the Host via Bit SBE_SBE2PSU_DOORBELL_SET_BIT2 + // that Stop15 exit + l_rc = sbeSetSbe2PsuDbBitX(SBE_SBE2PSU_DOORBELL_SET_BIT2); + if(l_rc) + { + SBE_ERROR(SBE_FUNC " Failed to Write " + "SBE_SBE2PSU_DOORBELL_SET_BIT2"); + } + break; // Breakout from do..while() + } + // Stop 15 Pending Case + pk_sleep(PK_MILLISECONDS(SBE_DMT_SLEEP_INTERVAL)); + + }while(false == g_SbeDmtTimerExpired); // Inner Loop + + }while(0); // Outer loop + + return l_rc; + #undef SBE_FUNC +} + +///////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////// +uint32_t sbeStopCntlDmt() +{ + #define SBE_FUNC "sbeStopCntlDmt" + uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL; + int l_pkRc = 0; + + do + { + // Stop the Pk Timer - There is no call to check if the timer is + // still alive, if i call cancel on already expired timer, it + // returns error code. + if(false == g_SbeDmtTimerExpired) + { + SBE_DEBUG(SBE_FUNC " DmTimer hasn't expired yet.. stop it"); + l_pkRc = pk_timer_cancel(&g_sbe_pk_dmt_timer); + if(l_pkRc) + { + // Check again if the failure is because of the timer already + // expired, in that case don't need to send any error response + // to hostboot + if(false == g_SbeDmtTimerExpired) + { + SBE_ERROR(SBE_FUNC " Pk Timer Cancel failed, RC=[%d]", + l_pkRc); + l_rc = SBE_SEC_OS_FAILURE; + } + break; + } + } + + l_rc = sbeWriteSbe2PsuMbxReg(SBE_HOST_PSU_MBOX_REG4, + (uint64_t*)(&g_sbeSbe2PsuRespHdr), + (sizeof(g_sbeSbe2PsuRespHdr)/sizeof(uint64_t)), + true); + if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc) + { + SBE_ERROR(SBE_FUNC" Failed to write to SBE_HOST_PSU_MBOX_REG4"); + break; + } + }while(0); + + return l_rc; + #undef SBE_FUNC +} ///////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// uint32_t sbeControlDeadmanTimer (uint8_t *i_pArg) { #define SBE_FUNC "sbeControlDeadmanTimer" - SBE_DEBUG(SBE_FUNC); - uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL; + SBE_ENTER(SBE_FUNC); + uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL; + + do + { + // Send Ack to Host via SBE_SBE2PSU_DOORBELL_SET_BIT1 + // This util method will check internally on the mbox0 register if ACK + // is requested. + l_rc = sbeAcknowledgeHost(); + if(l_rc) + { + SBE_ERROR(SBE_FUNC " Failed to Sent Ack to Host over " + "SBE_SBE2PSU_DOORBELL_SET_BIT1"); + break; + } + + if(g_sbePsu2SbeCmdReqHdr.flags & SBE_PSU_FLAGS_START_DMT) + { + l_rc = sbeStartCntlDmt(); + if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc) + { + SBE_ERROR(SBE_FUNC " Failed sbeStartCntlDmt"); + break; + } + } + else if(g_sbePsu2SbeCmdReqHdr.flags & SBE_PSU_FLAGS_STOP_DMT) + { + l_rc = sbeStopCntlDmt(); + if(SBE_SEC_OPERATION_SUCCESSFUL != l_rc) + { + SBE_ERROR(SBE_FUNC " Failed sbeStopCntlDmt"); + break; + } + } + else + { + SBE_DEBUG(SBE_DEBUG" Not a valid command "); + l_rc = SBE_SEC_COMMAND_NOT_SUPPORTED; + } + }while(0); // End of do-while - return rc; + SBE_EXIT(SBE_FUNC); + return l_rc; #undef SBE_FUNC } diff --git a/sbe/sbefw/sbecmdcntrldmt.H b/sbe/sbefw/sbecmdcntrldmt.H index be017f13..5d3d4caf 100644 --- a/sbe/sbefw/sbecmdcntrldmt.H +++ b/sbe/sbefw/sbecmdcntrldmt.H @@ -10,6 +10,19 @@ #include <stdint.h> +// Define for the Sleep interval between continuous HWP calls +// for DMT functionality in Millisecond +static const uint8_t SBE_DMT_SLEEP_INTERVAL = 1; + +// Bit-32 used to checkstop the system +static const uint64_t N3_FIR_CORE_CHECKSTOP_BIT = 32; + +/** + * @brief Callback for Timer Expiry for DMT + * + * @return void + */ +void sbeDmtPkExpiryCallback(void *arg); /** * @brief Control Deadman Timer command (0xD101) diff --git a/sbe/sbefw/sbecmdparser.C b/sbe/sbefw/sbecmdparser.C index 873d0986..6adbb1ca 100644 --- a/sbe/sbefw/sbecmdparser.C +++ b/sbe/sbefw/sbecmdparser.C @@ -90,15 +90,6 @@ static sbeCmdStruct_t g_sbeMemoryAccessCmdArray [] = SBE_FENCE_AT_CONTINUOUS_IPL, }, - {sbeGetSram, - SBE_CMD_GETSRAM, - SBE_FENCE_AT_CONTINUOUS_IPL, - }, - - {sbePutSram, - SBE_CMD_PUTSRAM, - SBE_FENCE_AT_CONTINUOUS_IPL, - }, }; ////////////////////////////////////////////////////////////// diff --git a/sbe/sbefw/sbecmdprocessor.C b/sbe/sbefw/sbecmdprocessor.C index cf42865b..72796579 100644 --- a/sbe/sbefw/sbecmdprocessor.C +++ b/sbe/sbefw/sbecmdprocessor.C @@ -35,7 +35,6 @@ void sbeHandlePsuResponse (const uint32_t i_rc) case SBE_SEC_COMMAND_CLASS_NOT_SUPPORTED: case SBE_SEC_COMMAND_NOT_SUPPORTED: // Caller sent an invalid Command class/opcode - // Set the Ack bit in SBE->PSU DB register l_rc = sbeAcknowledgeHost(); if (SBE_SEC_OPERATION_SUCCESSFUL != l_rc) @@ -50,21 +49,29 @@ void sbeHandlePsuResponse (const uint32_t i_rc) sizeof(uint64_t); l_rc = sbeWriteSbe2PsuMbxReg(SBE_HOST_PSU_MBOX_REG4, reinterpret_cast<const uint64_t *>( - &g_sbeSbe2PsuRespHdr), l_count); + &g_sbeSbe2PsuRespHdr), l_count, true); if (SBE_SEC_OPERATION_SUCCESSFUL != l_rc) { break; } + break; + + case SBE_SEC_OS_FAILURE: + // Set primary and secondary status + g_sbeSbe2PsuRespHdr.setStatus(SBE_PRI_GENERIC_EXECUTION_FAILURE, i_rc); - // Interrupt the host indicating about the response - // message in SBE->PSU mbx register - l_rc = sbeIntrHostUponRespWaiting(); + // Now Update SBE->PSU Mbx Reg4 with response + l_count = sizeof(g_sbeSbe2PsuRespHdr)/ + sizeof(uint64_t); + l_rc = sbeWriteSbe2PsuMbxReg(SBE_HOST_PSU_MBOX_REG4, + reinterpret_cast<const uint64_t *>( + &g_sbeSbe2PsuRespHdr), l_count, true); if (SBE_SEC_OPERATION_SUCCESSFUL != l_rc) { break; } break; - + case SBE_SEC_OPERATION_SUCCESSFUL: // Services code successfully executed the chipOp. SBE_INFO(SBE_FUNC"PSU ChipOp Done"); |