diff options
author | Marty Gloff <mgloff@us.ibm.com> | 2016-05-19 09:30:00 -0500 |
---|---|---|
committer | Stephen Cprek <smcprek@us.ibm.com> | 2016-07-18 15:32:26 -0500 |
commit | 1b968d7a2f1860e1704c77d7bf126486c46dd11f (patch) | |
tree | 61404e412c0a5c4285be6a9102f74a849190f15c | |
parent | 302ba45da68d13348596149b26c4934bc31171c7 (diff) | |
download | talos-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>
5 files changed, 1058 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" diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_mvpd_ring_funcs_errors.xml b/src/import/chips/p9/procedures/xml/error_info/p9_mvpd_ring_funcs_errors.xml new file mode 100644 index 000000000..b95fd3f65 --- /dev/null +++ b/src/import/chips/p9/procedures/xml/error_info/p9_mvpd_ring_funcs_errors.xml @@ -0,0 +1,70 @@ +<!-- IBM_PROLOG_BEGIN_TAG --> +<!-- This is an automatically generated prolog. --> +<!-- --> +<!-- $Source: chips/p9/procedures/xml/error_info/p9_mvpd_ring_funcs_errors.xml $ --> +<!-- --> +<!-- 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 --> +<!-- Error definitions for p9_mvpd_ring_funcs procedure --> +<hwpErrors> + <!-- ********************************************************************* --> + <hwpError> + <rc>RC_MVPD_RING_FUNC_INVALID_PARAMETER</rc> + <description>MVPD ring function parameter is not valid</description> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- ********************************************************************* --> + <hwpError> + <rc>RC_REPAIR_RING_NOT_FOUND</rc> + <description>Specified MVPD ring for this target was not found</description> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + <ffdc>RING_MODIFIER</ffdc> + <ffdc>CHIPLET_ID</ffdc> + <ffdc>CHIP_TARGET</ffdc> + </hwpError> + <!-- ********************************************************************* --> + <hwpError> + <rc>RC_REPAIR_RING_INVALID_SIZE</rc> + <description>Data does not fit into record</description> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- ********************************************************************* --> + <hwpError> + <rc>RC_MVPD_RING_FUNC_INSUFFICIENT_RECORD_SPACE</rc> + <description>Data does not fit into output buffer</description> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- ********************************************************************* --> + <hwpError> + <rc>RC_MVPD_RING_FUNC_INVALID_RECORD</rc> + <description>MVPD ring function record is not valid</description> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- ********************************************************************* --> +</hwpErrors> |