From c5e8f81acb726ade1061d501880d882d4a59ba71 Mon Sep 17 00:00:00 2001 From: Sachin Gupta Date: Tue, 13 Sep 2016 05:42:09 -0500 Subject: Support for putring chipop Change-Id: I5bd0ffb5f508922f8b298be6b2d5315e5c8a1114 RTC: 128977 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29559 Tested-by: Jenkins Server Tested-by: FSP CI Jenkins Reviewed-by: Shakeeb A. Pasha B K Reviewed-by: AMIT J. TENDOLKAR --- src/sbefw/sbeSpMsg.H | 26 +++++++++++ src/sbefw/sbe_sp_intf.H | 4 ++ src/sbefw/sbecmdgeneric.C | 3 +- src/sbefw/sbecmdparser.C | 7 ++- src/sbefw/sbecmdringaccess.C | 75 +++++++++++++++++++++++++++++++ src/sbefw/sbecmdringaccess.H | 8 ++++ src/test/testcases/testGetCapabilities.py | 2 +- 7 files changed, 122 insertions(+), 3 deletions(-) diff --git a/src/sbefw/sbeSpMsg.H b/src/sbefw/sbeSpMsg.H index b0bb0a09..97e3ddf2 100644 --- a/src/sbefw/sbeSpMsg.H +++ b/src/sbefw/sbeSpMsg.H @@ -644,6 +644,32 @@ typedef struct uint32_t ringMode:16; }sbeGetRingAccessMsgHdr_t; +/** + * @brief maximum double words for putring RS4 payload for chipop operation + */ +static const uint32_t SBE_PUT_RING_RS4_MAX_DOUBLE_WORDS = + SBE_PUT_RING_RS4_MAX_PAYLOAD_BYTES/sizeof(uint64_t); + +/** + * @brief Put Ring message header + */ +typedef struct +{ + uint32_t reserved:16; + uint32_t ringMode:16; +}sbePutRingMsgHdr_t; + +/** + * @brief Put Ring message + * @note This structure should have uint64_t as type as underlying + * platrform cast it to uint64 pointer. If we declare this as + * uint32, we can get allignment errors. + */ +typedef struct +{ + uint64_t rs4Payload[SBE_PUT_RING_RS4_MAX_DOUBLE_WORDS]; +}sbePutRingMsg_t; + /** * @brief Reg access message header */ diff --git a/src/sbefw/sbe_sp_intf.H b/src/sbefw/sbe_sp_intf.H index 6c6bb8b5..8573825a 100644 --- a/src/sbefw/sbe_sp_intf.H +++ b/src/sbefw/sbe_sp_intf.H @@ -392,6 +392,10 @@ enum sbeCacheChipletId EQ_ALL_CHIPLETS = 0xFF, }; +/* + * @brief maximum length for putring RS4 payload for chipop operation +*/ +static const uint32_t SBE_PUT_RING_RS4_MAX_PAYLOAD_BYTES = 512; /* * @brief enums for access modes used in ring access chip op */ diff --git a/src/sbefw/sbecmdgeneric.C b/src/sbefw/sbecmdgeneric.C index 7ec6d2db..1c7fe1ea 100644 --- a/src/sbefw/sbecmdgeneric.C +++ b/src/sbefw/sbecmdgeneric.C @@ -84,7 +84,8 @@ sbeCapabilityRespMsg::sbeCapabilityRespMsg() PUT_REGISTER_SUPPPORTED ; capability[RING_CAPABILITY_START_IDX] = - GET_RING_SUPPPORTED; + GET_RING_SUPPPORTED | + PUT_RING_SUPPPORTED; } // Functions //---------------------------------------------------------------------------- diff --git a/src/sbefw/sbecmdparser.C b/src/sbefw/sbecmdparser.C index 9722fe4a..a1b7a2ca 100644 --- a/src/sbefw/sbecmdparser.C +++ b/src/sbefw/sbecmdparser.C @@ -211,6 +211,11 @@ static sbeCmdStruct_t g_sbeRingAccessCmdArray [] = SBE_CMD_GETRING, SBE_FENCE_AT_CONTINUOUS_IPL|SBE_FENCE_AT_QUIESCE, }, + + {sbePutRing, + SBE_CMD_PUTRING, + PUT_HARDWARE_FENCED_STATE|SBE_FENCE_AT_QUIESCE, + }, }; ////////////////////////////////////////////////////////////// @@ -235,7 +240,7 @@ static sbeCmdStruct_t g_sbePutRingFromImageCmdArray [] = { {sbePutRingFromImagePSU, SBE_PSU_MSG_PUT_RING_FROM_IMAGE, - SBE_FENCE_AT_CONTINUOUS_IPL|SBE_FENCE_AT_QUIESCE, + PUT_HARDWARE_FENCED_STATE|SBE_FENCE_AT_QUIESCE, }, }; diff --git a/src/sbefw/sbecmdringaccess.C b/src/sbefw/sbecmdringaccess.C index 73466900..e837b8a1 100644 --- a/src/sbefw/sbecmdringaccess.C +++ b/src/sbefw/sbecmdringaccess.C @@ -238,3 +238,78 @@ uint32_t sbeGetRing(uint8_t *i_pArg) #undef SBE_FUNC } +////////////////////////////////////////////////////// +////////////////////////////////////////////////////// +uint32_t sbePutRing(uint8_t *i_pArg) +{ +#define SBE_FUNC " sbePutRing " + SBE_ENTER(SBE_FUNC); + + uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL; + sbePutRingMsg_t reqMsg; + sbeRespGenHdr_t respHdr; + respHdr.init(); + sbeResponseFfdc_t ffdc; + ReturnCode fapiRc; + sbePutRingMsgHdr_t hdr; + uint32_t len = 0; + + do + { + // Get the length of payload + // Length is not part of chipop. So take length from total length + len = g_sbeFifoCmdHdr.len - + sizeof(g_sbeFifoCmdHdr)/sizeof(uint32_t); + uint32_t rs4FifoEntries = len - + sizeof(sbePutRingMsgHdr_t)/sizeof(uint32_t); + + if( rs4FifoEntries > (SBE_PUT_RING_RS4_MAX_DOUBLE_WORDS * 2) ) + { + SBE_ERROR(SBE_FUNC" RS4 palyload size is wrong." + "size(entries):0x%08x", rs4FifoEntries); + respHdr.setStatus( SBE_PRI_INVALID_DATA, + SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); + // flush the fifo + rc = sbeUpFifoDeq_mult(len, NULL,true, true); + break; + } + + len = sizeof(sbePutRingMsgHdr_t)/sizeof(uint32_t); + rc = sbeUpFifoDeq_mult (len, (uint32_t *)&hdr, false); + // If FIFO access failure + CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(rc); + + len = rs4FifoEntries; + rc = sbeUpFifoDeq_mult (len, (uint32_t *)&reqMsg); + // If FIFO access failure + CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(rc); + + uint16_t ringMode = sbeToFapiRingMode(hdr.ringMode); + + Target proc = plat_getChipTarget(); + // No need to pass length as platform api takes length from payload. + fapiRc = rs4DecompressionSvc(proc, (uint8_t *)reqMsg.rs4Payload, + false, (fapi2::RingMode)ringMode); + if( fapiRc != FAPI2_RC_SUCCESS ) + { + SBE_ERROR(SBE_FUNC" rs4DecompressionSvc failed." + "RingMode:0x%04x", ringMode); + respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, + SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); + ffdc.setRc(fapiRc); + break; + } + }while(false); + + // Now build and enqueue response into downstream FIFO + // 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 == rc ) + { + rc = sbeDsSendRespHdr( respHdr, &ffdc); + } + SBE_EXIT(SBE_FUNC); + return rc; +#undef SBE_FUNC +} + diff --git a/src/sbefw/sbecmdringaccess.H b/src/sbefw/sbecmdringaccess.H index 578aa264..6df11f20 100644 --- a/src/sbefw/sbecmdringaccess.H +++ b/src/sbefw/sbecmdringaccess.H @@ -60,5 +60,13 @@ uint32_t sbePutRingFromImagePSU(uint8_t *i_pArg); */ uint32_t sbeGetRing(uint8_t *i_pArg); +/** + * @brief Put Ring Command + * + * @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 sbePutRing(uint8_t *i_pArg); #endif /* __SBEFW_SBECMDRINGACCESS_H */ diff --git a/src/test/testcases/testGetCapabilities.py b/src/test/testcases/testGetCapabilities.py index 33971638..b8760eea 100755 --- a/src/test/testcases/testGetCapabilities.py +++ b/src/test/testcases/testGetCapabilities.py @@ -36,7 +36,7 @@ EXPDATA1 = [0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0, 0xa2,0x0,0x0,0x0f, #getscom/putscom/modifyscom/putscomundermask 0x0,0x0,0x0,0x0, - 0xa3,0x0,0x0,0x1, #getring + 0xa3,0x0,0x0,0x3, #getring/putring 0x00,0x0,0x0,0x0]; EXPDATA2 = [0xa4,0x0,0x0,0x0f, #GetMemPba/PutMemPba/GetSramOcc/PutSramOcc -- cgit v1.2.1