summaryrefslogtreecommitdiffstats
path: root/sbe/sbefw/sbecmdringaccess.C
diff options
context:
space:
mode:
Diffstat (limited to 'sbe/sbefw/sbecmdringaccess.C')
-rw-r--r--sbe/sbefw/sbecmdringaccess.C143
1 files changed, 141 insertions, 2 deletions
diff --git a/sbe/sbefw/sbecmdringaccess.C b/sbe/sbefw/sbecmdringaccess.C
index 79939139..a3844034 100644
--- a/sbe/sbefw/sbecmdringaccess.C
+++ b/sbe/sbefw/sbecmdringaccess.C
@@ -23,19 +23,29 @@
/* */
/* IBM_PROLOG_END_TAG */
/*
- * @file: ppe/sbe/sbefw/sbecmdcntrldmt.C
+ * @file: ppe/sbe/sbefw/sbecmdringaccess.C
*
- * @brief This file contains Put Ring From Image Command handler
+ * @brief This file contains the SBE Ring Access chipOps
*
*/
+
#include "sbecmdringaccess.H"
+#include "sbefifo.H"
+#include "sbe_sp_intf.H"
#include "sbetrace.H"
#include "sbeHostMsg.H"
#include "sbeHostUtils.H"
+#include "sbeFifoMsgUtils.H"
#include "sbeutil.H"
#include "fapi2.H"
+#include "plat_hw_access.H"
using namespace fapi2;
+
+static const uint32_t SIZE_OF_LENGTH_INWORDS = 1;
+static const uint32_t NUM_WORDS_PER_GRANULE = 2;
+static const uint32_t GETRING_GRANULE_SIZE_IN_BITS = 64;
+
/*@brief - Map sbe ring access modes to fapi ring access modes
*
* @param[in] - i_ringMode - sbe ring access mode
@@ -167,3 +177,132 @@ uint32_t sbePutRingFromImagePSU (uint8_t *i_pArg)
return l_rc;
#undef SBE_FUNC
}
+
+//////////////////////////////////////////////////////
+//////////////////////////////////////////////////////
+uint32_t sbeGetRing(uint8_t *i_pArg)
+{
+ #define SBE_FUNC " sbeGetRing "
+ SBE_ENTER(SBE_FUNC);
+
+ uint32_t l_rc = SBE_SEC_OPERATION_SUCCESSFUL;
+ sbeGetRingAccessMsgHdr_t l_reqMsg;
+ sbeRespGenHdr_t respHdr;
+ respHdr.init();
+ sbeResponseFfdc_t l_ffdc;
+ ReturnCode l_fapiRc;
+ uint32_t l_len = 0;
+ uint32_t l_bitSentCnt = 0;
+
+ do
+ {
+ // Get the ring access header
+ l_len = sizeof(sbeGetRingAccessMsgHdr_t)/sizeof(uint32_t);
+ l_rc = sbeUpFifoDeq_mult (l_len, (uint32_t *)&l_reqMsg); // EOT fetch
+
+ // If FIFO access failure
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+
+ SBE_DEBUG(SBE_FUNC "Ring Address 0x%08X User Ring Mode 0x%04X "
+ "Length in Bits 0x%08X",
+ l_reqMsg.ringAddr, l_reqMsg.ringMode, l_reqMsg.ringLenInBits);
+
+ uint16_t l_ringMode = sbeToFapiRingMode(l_reqMsg.ringMode);
+
+ // Call getRing_setup - loads the scan region data for the given ring
+ // address and updates the check word data
+ l_fapiRc = fapi2::getRing_setup(l_reqMsg.ringAddr,
+ (fapi2::RingMode)l_ringMode);
+ if( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" getRing_setup failed. RingAddress:0x%08X "
+ "RingMode:0x%04x", l_reqMsg.ringAddr, l_ringMode);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+ // Calculate the iteration length
+ uint32_t l_loopCnt =
+ (l_reqMsg.ringLenInBits / GETRING_GRANULE_SIZE_IN_BITS);
+ // Check for modulus - remainder
+ uint8_t l_mod = (l_reqMsg.ringLenInBits % GETRING_GRANULE_SIZE_IN_BITS);
+ if(l_mod)
+ {
+ ++l_loopCnt;
+ }
+
+ // fix for the alignment issue
+ uint32_t l_buf[NUM_WORDS_PER_GRANULE]__attribute__ ((aligned (8))) ={0};
+ uint32_t l_bitShift = 0;
+ l_len = NUM_WORDS_PER_GRANULE;
+
+ // Fetch the ring data in bits, each iteration will give you 64bits
+ for(uint32_t l_cnt=0; l_cnt < l_loopCnt; l_cnt++)
+ {
+ if((l_cnt == (l_loopCnt-1)) && (l_mod))
+ {
+ l_bitShift = l_mod;
+ }
+ else
+ {
+ l_bitShift = GETRING_GRANULE_SIZE_IN_BITS;
+ }
+ // Call getRing_granule_data - read the 64 bit data from the HW
+ l_fapiRc = getRing_granule_data((uint32_t)(l_reqMsg.ringAddr),
+ (uint64_t*)&l_buf,
+ l_bitShift);
+ if( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" getRing_granule_data failed. "
+ "RingAddress:0x%08X RingMode:0x%04x",
+ l_reqMsg.ringAddr, l_ringMode);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ break;
+ }
+
+ // Send it to DS Fifo
+ // If this is the last iteration in the loop, let the full 64bit
+ // go, even for 1bit of remaining length. The length passed to
+ // the user will take care of actual number of bits.
+ l_rc = sbeDownFifoEnq_mult (l_len, (uint32_t *)&l_buf);
+ CHECK_SBE_RC_AND_BREAK_IF_NOT_SUCCESS(l_rc);
+ l_bitSentCnt = l_bitSentCnt + l_bitShift;
+ }
+ if ( (l_fapiRc == FAPI2_RC_SUCCESS) &&
+ (l_rc == SBE_SEC_OPERATION_SUCCESSFUL) )
+ {
+ // Call getRing_verifyAndcleanup - verify the check word data is
+ // matching or not and will clean up the scan region data
+ l_fapiRc = getRing_verifyAndcleanup((uint32_t)(l_reqMsg.ringAddr),
+ (fapi2::RingMode)l_ringMode);
+ if( l_fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" getRing_verifyAndcleanup failed. "
+ "RingAddress:0x%08X RingMode:0x%04x",
+ l_reqMsg.ringAddr, l_ringMode);
+ respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE,
+ SBE_SEC_GENERIC_FAILURE_IN_EXECUTION);
+ l_ffdc.setRc(l_fapiRc);
+ }
+ }
+ }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 == l_rc )
+ {
+ l_len = SIZE_OF_LENGTH_INWORDS;
+ l_rc = sbeDownFifoEnq_mult (l_len, &(l_bitSentCnt));
+ if(SBE_SEC_OPERATION_SUCCESSFUL == l_rc)
+ {
+ l_rc = sbeDsSendRespHdr( respHdr, l_ffdc);
+ }
+ }
+ return l_rc;
+#undef SBE_FUNC
+}
+
OpenPOWER on IntegriCloud