summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/accessors
diff options
context:
space:
mode:
authorMarty Gloff <mgloff@us.ibm.com>2016-05-19 09:30:00 -0500
committerStephen Cprek <smcprek@us.ibm.com>2016-07-18 15:32:26 -0500
commit1b968d7a2f1860e1704c77d7bf126486c46dd11f (patch)
tree61404e412c0a5c4285be6a9102f74a849190f15c /src/import/chips/p9/procedures/hwp/accessors
parent302ba45da68d13348596149b26c4934bc31171c7 (diff)
downloadtalos-hostboot-1b968d7a2f1860e1704c77d7bf126486c46dd11f.tar.gz
talos-hostboot-1b968d7a2f1860e1704c77d7bf126486c46dd11f.zip
Platform support for FAPI2 winkle/stop ring accessors
Add getMvpdRing function and supporting utility functions by porting P8 code and replacing FAPI interfaces with FAPI2 interfaces. Change-Id: Ied4895f560177a8c68e57ac47db9d9769a04dbdd RTC:142622 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/24800 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: Claus M. Olsen <cmolsen@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/26925 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/accessors')
-rw-r--r--src/import/chips/p9/procedures/hwp/accessors/p9_get_mvpd_ring.C73
-rw-r--r--src/import/chips/p9/procedures/hwp/accessors/p9_get_mvpd_ring.H92
-rw-r--r--src/import/chips/p9/procedures/hwp/accessors/p9_get_mvpd_ring.mk22
-rw-r--r--src/import/chips/p9/procedures/hwp/accessors/p9_mvpd_ring_funcs.C801
4 files changed, 988 insertions, 0 deletions
diff --git a/src/import/chips/p9/procedures/hwp/accessors/p9_get_mvpd_ring.C b/src/import/chips/p9/procedures/hwp/accessors/p9_get_mvpd_ring.C
new file mode 100644
index 000000000..5ac93ec89
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/accessors/p9_get_mvpd_ring.C
@@ -0,0 +1,73 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/procedures/hwp/accessors/p9_get_mvpd_ring.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2012,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: p9_get_mvpd_ring.C,v 1.1 2012/07/19 22:00:40 mjjones Exp $
+/**
+ * @file p9_get_mvpd_ring.C
+ *
+ * @brief fetch repair rings from MVPD records
+ *
+ */
+
+#include <stdint.h>
+
+// fapi2 support
+#include <fapi2.H>
+
+#include <p9_get_mvpd_ring.H>
+#include <p9_mvpd_ring_funcs.H>
+
+extern "C"
+{
+ using namespace fapi2;
+
+// getMvpdRing: Wrapper to call common function mvpdRingFunc
+ fapi2::ReturnCode getMvpdRing( fapi2::MvpdRecord i_record,
+ fapi2::MvpdKeyword i_keyword,
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
+ & i_fapiTarget,
+ const uint8_t i_chipletId,
+ const uint8_t i_ringId,
+ uint8_t* i_pRingBuf,
+ uint32_t& io_rRingBufsize)
+ {
+ fapi2::ReturnCode l_fapirc;
+
+ FAPI_DBG("getMvpdRing: entry ringId=0x%x, chipletId=0x%x, size=0x%x ",
+ i_ringId,
+ i_chipletId,
+ io_rRingBufsize );
+
+ // common get and set processing
+ l_fapirc = mvpdRingFunc(MVPD_RING_GET,
+ i_record,
+ i_keyword,
+ i_fapiTarget,
+ i_chipletId,
+ i_ringId,
+ i_pRingBuf,
+ io_rRingBufsize);
+
+
+ FAPI_DBG("getMvpdRing: exit rc=0x%x",
+ static_cast<uint32_t>(l_fapirc) );
+
+ return l_fapirc;
+ }
+
+} // extern "C"
diff --git a/src/import/chips/p9/procedures/hwp/accessors/p9_get_mvpd_ring.H b/src/import/chips/p9/procedures/hwp/accessors/p9_get_mvpd_ring.H
new file mode 100644
index 000000000..0b24c0adf
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/accessors/p9_get_mvpd_ring.H
@@ -0,0 +1,92 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/procedures/hwp/accessors/p9_get_mvpd_ring.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2012,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: p9_get_mvpd_ring.H,v 1.1 2012/07/19 22:00:38 mjjones Exp $
+/**
+ * @file p9_get_mvpd_ring.H
+ *
+ * @brief Prototype for getMvpdRing() -
+ * get a repair ring from a MVPD record
+ */
+
+#ifndef _HWP_GETMVPDRING_
+#define _HWP_GETMVPDRING_
+
+#include <fapi2.H>
+
+// function pointer typedef definition for HWP call support
+typedef fapi2::ReturnCode (*getMvpdRing_FP_t)
+(fapi2::MvpdRecord, fapi2::MvpdKeyword,
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&,
+ const uint8_t, const uint8_t, uint8_t*, uint32_t&);
+
+
+extern "C"
+{
+ /**
+ * @brief get specified ring from MVPD for the specified target CPU.
+ *
+ * A Ring Id Chiplet Id should be unique in the mvpd Record.
+ * The code does not validate. No assumption should be made on which would
+ * be returned if there are multiple.
+ *
+ * @param i_record - Record enumerator
+ * @param i_keyword - Keyword enumerator
+ * Supported Rings are:
+ * MVPD_RECORD_CP00 - MVPD_KEYWORD_PDR
+ * MVPD_RECORD_CP00 - MVPD_KEYWORD_PDG
+ * @param i_fapiTarget - cpu target
+ * @param i_chipletId - Chiplet ID
+ * @param i_ringId - Ring ID
+ * @param i_pRingBuf - pointer to a buffer allocated by the caller
+ * to receive the ring header and data.
+ * if NULL, the size of the min buffer required
+ * buffer will be returned in io_rRingBufsize
+ * with rc FAPI_RC_SUCCESS.
+ * @param io_rRingBufsize - in: size of ring buffer that caller has
+ * allocated
+ * out: number of BYTES that were copied to the
+ * output buffer.
+ * If the ring was not found, an error
+ * will be returned and this will be 0.
+ * If the output buffer is not big enough,
+ * an error will be returned and this will
+ * be the minimum size required.
+ * The buffer contains the CompressedScanData
+ * structure followed by compressed data. The
+ * caller does compression and decompression.
+ * Buffer: io_rRingBufsize returns xNN.
+ * byte x0 CompressedScanData structure (rs4 header)
+ * byte x18 compressed data (sizeof CompressedScanData is 0x18)
+ * byte xNN last byte of compressed data
+ *
+ * @return fapi2::ReturnCode - FAPI_RC_SUCCESS if success,
+ * relevant error code for failure.
+ */
+ fapi2::ReturnCode getMvpdRing( fapi2::MvpdRecord i_record,
+ fapi2::MvpdKeyword i_keyword,
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
+ & i_fapiTarget,
+ const uint8_t i_chipletId,
+ const uint8_t i_ringId,
+ uint8_t* io_pRingBuf,
+ uint32_t& io_rRingBufsize );
+
+}
+
+#endif
diff --git a/src/import/chips/p9/procedures/hwp/accessors/p9_get_mvpd_ring.mk b/src/import/chips/p9/procedures/hwp/accessors/p9_get_mvpd_ring.mk
new file mode 100644
index 000000000..cce39470c
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/accessors/p9_get_mvpd_ring.mk
@@ -0,0 +1,22 @@
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: chips/p9/procedures/hwp/accessors/p9_get_mvpd_ring.mk $
+#
+# IBM CONFIDENTIAL
+#
+# EKB Project
+#
+# COPYRIGHT 2016
+# [+] International Business Machines Corp.
+#
+#
+# The source code for this program is not published or otherwise
+# divested of its trade secrets, irrespective of what has been
+# deposited with the U.S. Copyright Office.
+#
+# IBM_PROLOG_END_TAG
+
+# Include the macros and things for MVPD ring procedures
+PROCEDURE=p9_get_mvpd_ring
+$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9/procedures/hwp/accessors/p9_mvpd_ring_funcs.C b/src/import/chips/p9/procedures/hwp/accessors/p9_mvpd_ring_funcs.C
new file mode 100644
index 000000000..afbb267af
--- /dev/null
+++ b/src/import/chips/p9/procedures/hwp/accessors/p9_mvpd_ring_funcs.C
@@ -0,0 +1,801 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: chips/p9/procedures/hwp/accessors/p9_mvpd_ring_funcs.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* EKB Project */
+/* */
+/* COPYRIGHT 2012,2016 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: p9_mvpd_ring_funcs.C,v 1.12 2014/07/16 19:06:49 cswenson Exp $
+/**
+ * @file p9_mvpd_ring_funcs.C
+ *
+ * @brief common routines
+ *
+ */
+
+#include <stdint.h>
+
+// fapi2 support
+#include <fapi2.H>
+#include <utils.H>
+#include <mvpd_access.H>
+#include <p9_mvpd_ring_funcs.H>
+
+// pull in CompressedScanData def from proc_slw_build HWP
+#include <p9_scan_compression.H>
+
+
+extern "C"
+{
+ using namespace fapi2;
+
+// functions internal to this file
+// these functions are common for both mvpdRingFunc and mbvpdRingFunc
+ fapi2::ReturnCode mvpdValidateRingHeader( CompressedScanData* i_pRing,
+ uint8_t i_chipletId,
+ uint8_t i_ringId,
+ uint32_t i_ringBufsize);
+
+ fapi2::ReturnCode mvpdRingFuncFind( const uint8_t i_chipletId,
+ const uint8_t i_ringId,
+ uint8_t* i_pRecordBuf,
+ uint32_t i_recordBufLenfapi,
+ uint8_t*& o_rRingBuf,
+ uint32_t& o_rRingBufsize);
+
+ fapi2::ReturnCode mvpdRingFuncGet( uint8_t* i_pRing,
+ uint32_t i_ringLen,
+ uint8_t* i_pCallerRingBuf,
+ uint32_t& io_rCallerRingBufLen);
+
+ fapi2::ReturnCode mvpdRingFuncSet( uint8_t* i_pRecordBuf,
+ uint32_t i_recordLen,
+ uint8_t* i_pRing,
+ uint32_t i_ringLen,
+ uint8_t* i_pCallerRingBuf,
+ uint32_t i_callerRingBufLen);
+
+ // add record/keywords with rings with RS4 header here.
+ struct _supportedRecordKeywords
+ {
+ fapi2::MvpdRecord record;
+ fapi2::MvpdKeyword keyword;
+ } supportedRecordKeywords [] =
+ {
+ { MVPD_RECORD_CP00, MVPD_KEYWORD_PDR },
+ { MVPD_RECORD_CP00, MVPD_KEYWORD_PDG },
+ };
+
+ /**
+ * @brief Validate Record and Keyword Combination
+ *
+ * @par Detailed Description:
+ * Check for supported combinations of Record and Keyword.
+ * The record needs to contain rings of RS4 header
+ * (CompressedScanData) format.
+ *
+ * @param[in] i_record
+ * Record to validate
+ *
+ * @param[in] i_keyword
+ * Keyword to validate
+ *
+ * @note: "Getting" data not in RS4 header format would likely just
+ * fail to find the ring harmlessly. "Setting" data could
+ * make a mess looking for the end to append a new ring. The
+ * result could be invalid vpd.
+ *
+ * @return fapi2::ReturnCode
+ */
+ fapi2::ReturnCode mvpdValidateRecordKeyword( fapi2::MvpdRecord i_record,
+ fapi2::MvpdKeyword i_keyword)
+ {
+ fapi2::ReturnCode l_fapirc;
+ bool l_validPair = false;
+ const uint32_t numPairs =
+ sizeof(supportedRecordKeywords) / sizeof(supportedRecordKeywords[0]);
+
+ for (uint32_t curPair = 0; curPair < numPairs; curPair++ )
+ {
+ if (supportedRecordKeywords[curPair].record == i_record &&
+ supportedRecordKeywords[curPair].keyword == i_keyword)
+ {
+ l_validPair = true;
+ break;
+ }
+ }
+
+ if ( !l_validPair )
+ {
+ FAPI_SET_HWP_ERROR(l_fapirc, RC_MVPD_RING_FUNC_INVALID_PARAMETER );
+ }
+
+ return l_fapirc;
+
+ };
+
+
+ /**
+ * @brief MVPD Ring Function
+ *
+ * @par Detailed Description:
+ * The getMvpdRing and setMvpdRing wrappers call this function
+ * to do all the processing.
+ *
+ * @param[in] i_mvpdRingFuncOp
+ * MVPD ring function op to process
+ *
+ * @param[in] i_record
+ * Record in the MVPD
+ *
+ * @param[in] i_keyword
+ * Keyword for the MVPD record
+ *
+ * @param[in] i_fapiTarget
+ * FAPI target for the op
+ *
+ * @param[in] i_chipletId
+ * Chiplet ID for the op
+ *
+ * @param[in] i_ringId
+ * Ring ID for the op
+ *
+ * @param[in] i_pRingBuf
+ * Pointer to ring buffer with set data
+ *
+ * @param[in/out] io_rRingBufsize
+ * Size of ring buffer
+ *
+ * @note: io_rRingBufsize is only an 'output' for get function.
+ *
+ * @return fapi2::ReturnCode
+ */
+ fapi2::ReturnCode mvpdRingFunc(const mvpdRingFuncOp i_mvpdRingFuncOp,
+ fapi2::MvpdRecord i_record,
+ fapi2::MvpdKeyword i_keyword,
+ const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
+ & i_fapiTarget,
+ const uint8_t i_chipletId,
+ const uint8_t i_ringId,
+ uint8_t* i_pRingBuf,
+ uint32_t& io_rRingBufsize)
+ {
+ fapi2::ReturnCode l_fapirc;
+ uint32_t l_recordLen = 0;
+ uint8_t* l_recordBuf = NULL;
+ uint8_t* l_pRing = NULL;
+ uint32_t l_ringLen = 0;
+
+ FAPI_DBG("mvpdRingFunc:entry op=0x%x ringId=0x%x chipletId=0x%x "
+ "size=0x%x",
+ i_mvpdRingFuncOp,
+ i_ringId,
+ i_chipletId,
+ io_rRingBufsize );
+
+ // do common get and set input parameter error checks
+ // check for supported combination of Record and Keyword
+ FAPI_TRY(mvpdValidateRecordKeyword(i_record,
+ i_keyword),
+ "mvpdRingFunc: unsupported record keyword pair "
+ "record=0x%x, keyword=0x%x",
+ i_record,
+ i_keyword);
+
+ // do set specific input parameter checks
+ if (i_mvpdRingFuncOp == MVPD_RING_SET )
+ {
+ // passing NULL pointer to receive needed size is only for get.
+ FAPI_ASSERT(i_pRingBuf != NULL,
+ fapi2::MVPD_RING_FUNC_INVALID_PARAMETER(),
+ "mvpdRingFunc: NULL ring buffer pointer passed "
+ "to set function chipletId=0x%x, ringId=0x%x",
+ i_chipletId,
+ i_ringId);
+
+ // Validate ring header to protect vpd
+ FAPI_TRY(mvpdValidateRingHeader(
+ reinterpret_cast<CompressedScanData*>(i_pRingBuf),
+ i_chipletId,
+ i_ringId,
+ io_rRingBufsize),
+ "mvpdRingFunc: invalid ring header "
+ "chipletId=0x%x, ringId=0x%x",
+ i_chipletId,
+ i_ringId);
+ }
+
+ // call getMvpdField once with a NULL pointer to get the buffer
+ // size no error should be returned.
+ FAPI_TRY(getMvpdField(i_record,
+ i_keyword,
+ i_fapiTarget,
+ NULL,
+ l_recordLen ),
+ "mvpdRingFunc: getMvpdField failed to get buffer size "
+ "chipletId=0x%x, ringId=0x%x",
+ i_chipletId,
+ i_ringId);
+
+ FAPI_DBG( "mvpdRingFunc: getMvpdField returned record len=0x%x",
+ l_recordLen );
+
+ // allocate buffer for the record. Always works
+ l_recordBuf = static_cast<uint8_t*>(malloc((size_t)l_recordLen));
+
+ // load ring from MVPD for this target
+ FAPI_TRY(getMvpdField(i_record,
+ i_keyword,
+ i_fapiTarget,
+ l_recordBuf,
+ l_recordLen ),
+ "mvpdRingFunc: getMvpdField failed "
+ "chipletId=0x%x, ringId=0x%x",
+ i_chipletId,
+ i_ringId);
+
+ // find ring in the record. It is an error if not there for a "get".
+ // Its ok if not there for a "set". The ring will be added.
+ // l_ringLen set to 0 if not there with l_pRing at the start of padding.
+ FAPI_TRY(mvpdRingFuncFind(i_chipletId,
+ i_ringId,
+ l_recordBuf,
+ l_recordLen,
+ l_pRing,
+ l_ringLen),
+ "mvpdRingFunc: mvpdRingFuncFind failed "
+ "chipletId=0x%x, ringId=0x%x",
+ i_chipletId,
+ i_ringId);
+
+ // do the get or set specific operations
+ if (i_mvpdRingFuncOp == MVPD_RING_GET ) // do the get operation
+ {
+ // ensure ring was found. Must be there for "get"
+ FAPI_ASSERT(l_ringLen != 0,
+ fapi2::REPAIR_RING_NOT_FOUND().
+ set_RING_MODIFIER(i_ringId).
+ set_CHIP_TARGET(i_fapiTarget).
+ set_CHIPLET_ID(i_chipletId),
+ "mvpdRingFunc: mvpdRingFuncFind did not find ring");
+
+ // copy ring back to caller's buffer
+ FAPI_TRY(mvpdRingFuncGet(l_pRing,
+ l_ringLen,
+ i_pRingBuf,
+ io_rRingBufsize),
+ "mvpdRingFunc: mvpdRingFuncGet failed "
+ "chipletId=0x%x, ringId=0x%x",
+ i_chipletId,
+ i_ringId);
+ }
+ else // set operation
+ {
+ // update record with caller's ring
+ FAPI_TRY(mvpdRingFuncSet(l_recordBuf,
+ l_recordLen,
+ l_pRing,
+ l_ringLen,
+ i_pRingBuf,
+ io_rRingBufsize),
+ "mvpdRingFunc: mvpdRingFuncSet failed "
+ "chipletId=0x%x, ringId=0x%x",
+ i_chipletId,
+ i_ringId);
+
+ // update record back to the mvpd
+ FAPI_TRY(setMvpdField(i_record,
+ i_keyword,
+ i_fapiTarget,
+ l_recordBuf,
+ l_recordLen),
+ "mvpdRingFunc: setMvpdField failed "
+ "chipletId=0x%x, ringId=0x%x",
+ i_chipletId,
+ i_ringId);
+ }
+
+ fapi_try_exit:
+ // get current error
+ l_fapirc = fapi2::current_err;
+
+ // unload the repair ring if allocated
+ if(l_recordBuf)
+ {
+ free(static_cast<void*>(l_recordBuf));
+ l_recordBuf = NULL;
+ }
+
+ if((i_mvpdRingFuncOp != MVPD_RING_GET) && l_fapirc)
+ {
+ io_rRingBufsize = 0;
+ }
+
+ FAPI_DBG( "mvpdRingFunc: exit bufsize= 0x%x rc= 0x%x",
+ io_rRingBufsize,
+ static_cast<uint32_t>(l_fapirc) );
+ return l_fapirc;
+ }
+
+
+ /**
+ * @brief MVPD Ring Function Find
+ *
+ * @par Detailed Description:
+ * Step through the record looking at rings for a match.
+ *
+ * @param[in] i_chipletId
+ * Chiplet ID for the op
+ *
+ * @param[in] i_ringId
+ * Ring ID for the op
+ *
+ * @param[in] i_pRecordBuf
+ * Pointer to record buffer
+ *
+ * @param[in] i_recordBufLen
+ * Length of record buffer
+ *
+ * @param[out] o_rpRing
+ * Pointer to the ring in the record, if it is there
+ * Pointer to the start of the padding after the last
+ * ring, if it is not there
+ *
+ * @param[out] o_rRingLen
+ * Number of bytes in the ring (header and data)
+ * Will be 0 if ring not found
+ *
+ * @return fapi2::ReturnCode
+ */
+ fapi2::ReturnCode mvpdRingFuncFind( const uint8_t i_chipletId,
+ const uint8_t i_ringId,
+ uint8_t* i_pRecordBuf,
+ uint32_t i_recordBufLen,
+ uint8_t*& o_rpRing,
+ uint32_t& o_rRingLen)
+ {
+ fapi2::ReturnCode l_fapirc;
+ uint8_t* l_pRing = NULL;
+ uint32_t l_offset = 0;
+ CompressedScanData* l_pScanData = NULL;
+ bool l_foundflag = false;
+
+ // initialize return fields in case of an error.
+ o_rpRing = NULL;
+ o_rRingLen = 0;
+
+ FAPI_DBG("mvpdRingFuncFind: entry chipletId=0x%x, ringId=0x%x ",
+ i_chipletId,
+ i_ringId );
+
+ do
+ {
+ // point to #R record
+ l_pRing = i_pRecordBuf;
+
+ // Find first RSA data block in ring (fixed offset defined by
+ // MVPD spec)
+ //
+ // First byte in record should be the version number, skip
+ // over this.
+ //
+ FAPI_DBG( "mvpdRingFuncFind: record version = 0x%x", *l_pRing );
+ l_pRing++;
+ l_offset = 0;
+
+ l_foundflag = false;
+
+ // be sure that data we will look at is within the passed buffer
+ while ( l_offset + sizeof(CompressedScanData) < i_recordBufLen )
+ {
+ // point to header
+ l_pScanData =
+ reinterpret_cast<CompressedScanData*>( l_pRing + l_offset );
+
+ // Check magic key to make sure this is a valid record.
+ FAPI_ASSERT(be32toh(l_pScanData->iv_magic) == RS4_MAGIC,
+ fapi2::MVPD_RING_FUNC_INVALID_RECORD(),
+ "mvpdRingFuncFind: Header 0x%x offset 0x%x, "
+ "end of list chipletId=0x%x, ringId=0x%x",
+ be32toh(l_pScanData->iv_magic),
+ l_offset,
+ i_chipletId,
+ i_ringId);
+
+ // dump record info for debug
+ FAPI_DBG("mvpdRingFuncFind:%d ringId=0x%x chipletId=0x%x"
+ " ringlen=0x%x size=0x%x",
+ l_offset,
+ l_pScanData->iv_ringId,
+ l_pScanData->iv_chipletId,
+ be32toh(l_pScanData->iv_length),
+ be32toh(l_pScanData->iv_size) );
+
+
+ if ( (l_pScanData->iv_ringId == i_ringId)
+ && (l_pScanData->iv_chipletId == i_chipletId) )
+ {
+ FAPI_DBG( "mvpdRingFuncFind: Found it: ring=0x%x, "
+ "chiplet=0x%x, ringlen=0x%x",
+ i_ringId,
+ i_chipletId,
+ be32toh(l_pScanData->iv_length) );
+
+ // shouldn't happen, but does not all fit
+ FAPI_ASSERT(l_offset + be32toh(l_pScanData->iv_size) <=
+ i_recordBufLen,
+ fapi2::REPAIR_RING_INVALID_SIZE(),
+ "mvpdRingFuncFind: data does not fit "
+ "chipletId=0x%x, ringId=0x%x",
+ i_chipletId,
+ i_ringId);
+
+ l_foundflag = true;
+ o_rpRing = l_pRing + l_offset;
+ o_rRingLen = be32toh(l_pScanData->iv_size);
+ // got it, break out of scan loop
+ break;
+ }
+
+ // being defensive.
+ if ( be32toh(l_pScanData->iv_size) == 0)
+ {
+ // size of 0 is invalid, would loop forever.
+ break;
+ }
+
+ // bump to next ring
+ l_offset += be32toh(l_pScanData->iv_size) ;
+
+ } // end while scan loop
+
+ // if no other error and not found, indicate with 0 size.
+ if ( !l_fapirc && ! l_foundflag )
+ {
+ o_rpRing = l_pRing + l_offset; //return pointer to end of list
+ //incase needed for appending
+ o_rRingLen = 0; //indicate not found
+ }
+
+ }
+ while ( 0 );
+
+ fapi_try_exit:
+ // get current error
+ l_fapirc = fapi2::current_err;
+
+ FAPI_DBG("mvpdRingFuncFind: exit *ring= 0x%p", o_rpRing);
+ FAPI_IMP("mvpdRingFuncFind: exit chipletId=0x%x, ringId=0x%x size=0x%x"
+ " rc=0x%x",
+ i_chipletId,
+ i_ringId,
+ o_rRingLen,
+ static_cast<uint32_t>(l_fapirc) );
+
+ return l_fapirc;
+ }
+
+
+ /**
+ * @brief MVPD Validate Ring Header
+ *
+ * @param[in] i_pRingBuf
+ * Pointer to the ring in the record
+ *
+ * @param[in] i_chipletId
+ * Chiplet ID for the op
+ *
+ * @param[in] i_ringId
+ * Ring ID for the op
+ *
+ * @param[in] i_ringBufsize
+ * Number of bytes in the ring (header and data)
+ *
+ * @return fapi2::ReturnCode
+ */
+ fapi2::ReturnCode mvpdValidateRingHeader( CompressedScanData* i_pRingBuf,
+ uint8_t i_chipletId,
+ uint8_t i_ringId,
+ uint32_t i_ringBufsize)
+ {
+ FAPI_ASSERT(i_ringBufsize > sizeof(CompressedScanData),
+ fapi2::MVPD_RING_FUNC_INVALID_PARAMETER(),
+ "mvpdValidateRingHeader: i_ringBufsize failed "
+ "chipletId=0x%x, ringId=0x%x",
+ i_chipletId,
+ i_ringId);
+ FAPI_ASSERT(be32toh(i_pRingBuf->iv_magic) == RS4_MAGIC,
+ fapi2::MVPD_RING_FUNC_INVALID_PARAMETER(),
+ "mvpdValidateRingHeader: i_pRingBuf->iv_magic failed "
+ "chipletId=0x%x, ringId=0x%x",
+ i_chipletId,
+ i_ringId);
+ FAPI_ASSERT(i_pRingBuf->iv_ringId == i_ringId,
+ fapi2::MVPD_RING_FUNC_INVALID_PARAMETER(),
+ "mvpdValidateRingHeader: i_pRingBuf->iv_ringId failed "
+ "chipletId=0x%x, ringId=0x%x",
+ i_chipletId,
+ i_ringId);
+ FAPI_ASSERT(i_pRingBuf->iv_chipletId == i_chipletId,
+ fapi2::MVPD_RING_FUNC_INVALID_PARAMETER(),
+ "mvpdValidateRingHeader: i_pRingBuf->iv_chipletId failed "
+ "chipletId=0x%x, ringId=0x%x",
+ i_chipletId,
+ i_ringId);
+ FAPI_ASSERT(be32toh(i_pRingBuf->iv_size) == i_ringBufsize,
+ fapi2::MVPD_RING_FUNC_INVALID_PARAMETER(),
+ "mvpdValidateRingHeader: i_pRingBuf->iv_size failed "
+ "chipletId=0x%x, ringId=0x%x",
+ i_chipletId,
+ i_ringId);
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+
+ /**
+ * @brief MVPD Get Ring Function
+ *
+ * @par Detailed Description:
+ * Copy the ring back to the caller.
+ *
+ * @param[in] i_pRing
+ * Pointer to the ring in the record
+ *
+ * @param[in] i_ringLen
+ * Number of bytes in the ring (header and data)
+ *
+ *
+ * @param[in] i_pCallerRingBuf
+ * Pointer to the caller's ring in the record
+ *
+ * @param[in/out] io_rCallerRingBufLen
+ * Number of bytes in the caller's ring
+ *
+ * @return fapi2::ReturnCode
+ */
+ fapi2::ReturnCode mvpdRingFuncGet( uint8_t* i_pRing,
+ uint32_t i_ringLen,
+ uint8_t* i_pCallerRingBuf,
+ uint32_t& io_rCallerRingBufLen)
+ {
+ fapi2::ReturnCode l_fapirc;
+
+ do
+ {
+ // return buffer pointer is NULL if just looking for the size
+ if ( i_pCallerRingBuf == NULL )
+ {
+ io_rCallerRingBufLen = i_ringLen;
+ // break out of do block with success rc
+ break;
+ }
+
+ // check if we have enough space
+ FAPI_ASSERT(io_rCallerRingBufLen >= i_ringLen,
+ fapi2::REPAIR_RING_INVALID_SIZE(),
+ "mvpdRingFuncGet: output buffer too small: "
+ "0x%x < 0x%x",
+ io_rCallerRingBufLen,
+ i_ringLen);
+
+ // we're good, copy data into the passed-in buffer
+ FAPI_DBG( "mvpdRingFuncGet: memcpy 0x%p 0x%p 0x%x",
+ i_pCallerRingBuf,
+ i_pRing,
+ i_ringLen );
+ memcpy( i_pCallerRingBuf, i_pRing, i_ringLen );
+ io_rCallerRingBufLen = i_ringLen;
+
+ }
+ while (0);
+
+ fapi_try_exit:
+ // get current error
+ l_fapirc = fapi2::current_err;
+
+ if (l_fapirc.isRC(RC_REPAIR_RING_INVALID_SIZE))
+ {
+ // return actual size of data, so caller can re-try with
+ // the correct value
+ io_rCallerRingBufLen = i_ringLen;
+ }
+
+ FAPI_DBG( "mvpdRingFuncGet: exit bufsize= 0x%x rc= 0x%x",
+ io_rCallerRingBufLen,
+ static_cast<uint32_t>(l_fapirc) );
+
+ return l_fapirc;
+ }
+
+
+ /**
+ * @brief MVPD Set Ring Function
+ *
+ * @par Detailed Description:
+ * Update the record with the caller's ring.
+ *
+ * @param[in] i_pRecordBuf
+ * Pointer to record buffer
+ *
+ * @param[in] i_recordLen
+ * Length of record buffer
+ *
+ * @param[in] i_pRing
+ * Pointer to the ring in the record
+ *
+ * @param[in] i_ringLen
+ * Number of bytes in the ring (header and data)
+ *
+ * @param[in] i_pCallerRingBuf
+ * Pointer to the caller's ring in the record
+ *
+ * @param[in] i_callerRingBufLen
+ * Number of bytes in the caller's ring
+ *
+ * @return fapi2::ReturnCode
+ */
+ fapi2::ReturnCode mvpdRingFuncSet( uint8_t* i_pRecordBuf,
+ uint32_t i_recordLen,
+ uint8_t* i_pRing,
+ uint32_t i_ringLen,
+ uint8_t* i_pCallerRingBuf,
+ uint32_t i_callerRingBufLen)
+ {
+ fapi2::ReturnCode l_fapirc;
+ uint8_t* l_to = NULL;
+ uint8_t* l_fr = NULL;
+ uint32_t l_len = 0;
+ uint8_t* l_pRingEnd; // pointer into record to start of pad at end
+
+ FAPI_DBG( "mvpdRingFuncSet: pRing=0x%p rLen=0x%x pCaller=0x%p cLen=0x%x",
+ i_pRing,
+ i_ringLen,
+ i_pCallerRingBuf,
+ i_callerRingBufLen);
+
+ do
+ {
+ // if exact fit, update in place
+ if (i_callerRingBufLen == i_ringLen)
+ {
+ l_to = i_pRing;
+ l_fr = i_pCallerRingBuf;
+ l_len = i_callerRingBufLen;
+ FAPI_DBG( "mvpdRingFuncSet: update in place-memcpy 0x%p 0x%p 0x%x",
+ l_to,
+ l_fr,
+ l_len);
+ memcpy (l_to, l_fr, l_len);
+
+ // break out successful
+ break;
+ }
+
+ // will need the end for shifting... look for something invalid
+ FAPI_TRY(mvpdRingFuncFind(0x00,
+ 0x00,
+ i_pRecordBuf,
+ i_recordLen,
+ l_pRingEnd, // find start of padding
+ l_len),
+ "mvpdRingFuncSet: mvpdRingFuncFind failed");
+
+ FAPI_DBG( "mvpdRingFuncSet: end= 0x%p",
+ l_pRingEnd);
+
+ // if not there, then append if it fits
+ if (i_ringLen == 0 ) //is not currently in record (0 len from find)
+ {
+ FAPI_ASSERT(l_pRingEnd + i_callerRingBufLen <=
+ i_pRecordBuf + i_recordLen,
+ fapi2::MVPD_RING_FUNC_INSUFFICIENT_RECORD_SPACE(),
+ "mvpdRingFuncSet: not enough room to append");
+
+ l_to = i_pRing;
+ l_fr = i_pCallerRingBuf;
+ l_len = i_callerRingBufLen;
+ FAPI_DBG( "mvpdRingFuncSet: append-memcpy 0x%p 0x%p 0x%x",
+ l_to,
+ l_fr,
+ l_len);
+ memcpy (l_to, l_fr, l_len);
+
+ // break out successful
+ break;
+ }
+
+ // if smaller, then shift left and zero fill
+ if (i_callerRingBufLen < i_ringLen)
+ {
+ l_to = i_pRing;
+ l_fr = i_pCallerRingBuf;
+ l_len = i_callerRingBufLen;
+ FAPI_DBG( "mvpdRingFuncSet: shrink-memcpy 0x%p 0x%p 0x%x",
+ l_to,
+ l_fr,
+ l_len);
+ memcpy (l_to, l_fr, l_len);
+
+ l_to = i_pRing + i_callerRingBufLen;
+ l_fr = i_pRing + i_ringLen;
+ l_len = (l_pRingEnd) - (i_pRing + i_ringLen);
+ FAPI_DBG( "mvpdRingFuncSet: shrink-memmove 0x%p 0x%p 0x%x",
+ l_to,
+ l_fr,
+ l_len);
+ memmove (l_to, l_fr, l_len); //use memmove, always overlaps.
+
+ l_to = (l_pRingEnd) - (i_ringLen - i_callerRingBufLen);
+ l_len = i_ringLen - i_callerRingBufLen;
+ FAPI_DBG( "mvpdRingFuncSet: shrink-memset 0x%p 0x%x 0x%x",
+ l_to,
+ 0x00,
+ l_len);
+ memset (l_to, 0x00, l_len);
+
+ // break out successful
+ break;
+
+ }
+
+ // if larger, then shift right, if it fits
+ if (i_callerRingBufLen > i_ringLen)
+ {
+ // ensure the padding can contain the growth
+ FAPI_ASSERT((l_pRingEnd + (i_callerRingBufLen - i_ringLen)) <=
+ (i_pRecordBuf + i_recordLen),
+ fapi2::MVPD_RING_FUNC_INSUFFICIENT_RECORD_SPACE(),
+ "mvpdRingFuncSet: not enough room to insert");
+
+ l_to = i_pRing + i_callerRingBufLen;
+ l_fr = i_pRing + i_ringLen;
+ l_len = l_pRingEnd - (i_pRing + i_ringLen);
+ FAPI_DBG( "mvpdRingFuncSet: insert-memmove 0x%p 0x%p 0x%x",
+ l_to,
+ l_fr,
+ l_len);
+ memmove (l_to, l_fr, l_len);
+
+ l_to = i_pRing;
+ l_fr = i_pCallerRingBuf;
+ l_len = i_callerRingBufLen;
+ FAPI_DBG( "mvpdRingFuncSet: insert-memcpy 0x%p 0x%p 0x%x",
+ l_to,
+ l_fr,
+ l_len);
+ memcpy (l_to, l_fr, l_len);
+
+ // break out successful
+ break;
+ }
+
+ FAPI_ERR( "mvpdRingFuncSet: shouldn't get to here" );
+
+ }
+ while (0);
+
+ fapi_try_exit:
+ // get current error
+ l_fapirc = fapi2::current_err;
+
+ FAPI_DBG( "mvpdRingFuncSet: exit rc= 0x%x",
+ static_cast<uint32_t>(l_fapirc) );
+
+ return l_fapirc;
+ }
+
+
+} // extern "C"
OpenPOWER on IntegriCloud