| From c2b2d20fdf36bff21577ca6ed6703395ebad8971 Mon Sep 17 00:00:00 2001 |
| From: Olsen <cmolsen@us.ibm.com> |
| Date: Wed, 9 Oct 2019 08:53:07 -0400 |
| Subject: [PATCH] TOR API : Refactoring, traversal and buffer check |
| improvements |
| |
| Changes made: |
| - Introduced two new internal functions: _tor_access_ring() |
| and _tor_header_check(). |
| - Updated tor_append_ring() to pass a max ringSectionSize arg to be |
| checked for overflow in the new _tor_access_ring() function. |
| - Moved the actual appending/updating of RS4 rings out of |
| tor_append_ring() into _tor_access_ring(). |
| - Removed tor_access_ring(). |
| - All TOR chiplet and ring offsets are now referenced wrt to the |
| ringSection origin (ie, where the TOR header starts). |
| - Updated TOR_VERSION to v2. |
| - Refactoring of various TOR APIs to use the above changes. |
| - Updates to ring_apply, ipl_customize and qme_customize to support |
| the new tor_append_ring() API. |
| - Updates to Sbe and Qme TOR traversal codes and extract HOMER. |
| - Various cleanups in buffer handling in p10_ipl_customize.C. |
| - Removed p9_ring_apply.* files (though not at all relevant to this |
| commit) |
| |
| Key_Cronus_Test=XIP_REGRESS_SBE_QME |
| |
| Change-Id: I7bb3a76ae2454a34c7c0619e928c67706cc571e4 |
| Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/85899 |
| Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> |
| Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com> |
| Tested-by: Cronus HW CI <cronushw-ci+hostboot@us.ibm.com> |
| Reviewed-by: Prem Shanker Jha <premjha2@in.ibm.com> |
| Reviewed-by: Jennifer A Stofer <stofer@us.ibm.com> |
| --- |
| .../chips/common/utils/imageProcs/common_ringId.H | 25 +- |
| .../procedures/hwp/customize/p10_ipl_customize.C | 196 ++++++-- |
| .../procedures/hwp/customize/p10_qme_customize.C | 152 ++---- |
| .../xml/error_info/p10_ipl_customize_errors.xml | 3 +- |
| .../p10/utils/imageProcs/p10_infrastruct_help.H | 1 - |
| .../p10/utils/imageProcs/p10_scan_compression.H | 5 +- |
| src/import/chips/p10/utils/imageProcs/p10_tor.C | 526 ++++++++++----------- |
| src/import/chips/p10/utils/imageProcs/p10_tor.H | 97 ++-- |
| 8 files changed, 483 insertions(+), 522 deletions(-) |
| |
| diff --git a/src/import/chips/common/utils/imageProcs/common_ringId.H b/src/import/chips/common/utils/imageProcs/common_ringId.H |
| index 1fc819a..053af8c 100644 |
| --- a/src/import/chips/common/utils/imageProcs/common_ringId.H |
| +++ b/src/import/chips/common/utils/imageProcs/common_ringId.H |
| @@ -48,7 +48,7 @@ typedef uint8_t ChipletType_t; // Type for Chiplets enum |
| typedef uint8_t ChipId_t; // Type for ChipId enum |
| typedef uint8_t RingType_t; // Type for RingType enum |
| typedef uint8_t RingRequest_t; // Type for RingRequest enum, e.g. GET_SINGLE_RING |
| -typedef uint32_t TorCpltOffset_t; // Type for offset value to chiplet's CMN or INST section |
| +typedef uint16_t TorOffset_t; // Type for offset value to various TOR objects (chiplet,ring) |
| typedef uint8_t MyBool_t; // false:0, true:1, undefined:UNDEFINED_BOOLEAN |
| |
| #define UNDEFINED_RING_ID (RingId_t)0xffff |
| @@ -61,10 +61,14 @@ typedef uint8_t MyBool_t; // false:0, true:1, undefined:UNDEFINED_BOOL |
| |
| #define UNDEFINED_DD_LEVEL (uint8_t)0xff |
| |
| -#define MAX_TOR_RING_OFFSET (uint16_t)(256*256-1) // Max val of uint16 |
| - |
| #define MAX_RING_NAME_LENGTH (uint8_t)50 |
| |
| +// Ring section defines |
| +#define MAX_TOR_RING_OFFSET (uint16_t)(256*256-1) // Max val of uint16 |
| +#define MAX_TOR_RING_SECTION_SIZE (uint32_t)(256*256) |
| +#define MAX_DYN_RING_SECTION_SIZE (uint32_t)(1024*1024) |
| + |
| +// Chiplet ID defines |
| #define CHIPLET_ID_MASK (uint32_t)0xFF000000 |
| #define MIN_INSTANCE_ID (uint8_t)0x01 |
| #define MAX_INSTANCE_ID (uint8_t)0x3F |
| @@ -93,12 +97,10 @@ typedef struct |
| |
| typedef struct |
| { |
| - TorCpltOffset_t cmnOffset; |
| - TorCpltOffset_t instOffset; |
| + TorOffset_t cmnOffset; |
| + TorOffset_t instOffset; |
| } TorCpltBlock_t; |
| |
| -typedef uint16_t TorRingOffset_t; // Offset value to actual ring |
| - |
| // // |
| // TOR layout definitions - End // |
| /////////////////////////////////////////////////////////////////////////////// |
| @@ -118,7 +120,8 @@ typedef uint16_t TorRingOffset_t; // Offset value to actual ring |
| //#define TOR_VERSION 7 // Added three more runtime risk levels (RL3/4/5) |
| |
| // P10 TOR versions |
| -#define TOR_VERSION 1 // Removed all ring variant support. Only BASE rings supported now. |
| +//#define TOR_VERSION 1 // Removed all ring variant support. Only BASE rings supported now. |
| +#define TOR_VERSION 2 // TOR ringSection offsets now wrt origin of ringSection at TOR header. |
| |
| |
| // TOR Magic values for top-level TOR ringSection and sub-ringSections |
| @@ -263,8 +266,8 @@ enum RingType |
| |
| enum RingRequest |
| { |
| - GET_SINGLE_RING = 0x00, |
| - PUT_SINGLE_RING = 0x01 |
| + GET_SINGLE_RING = 0, |
| + PUT_SINGLE_RING = 1, |
| }; |
| |
| // |
| @@ -327,7 +330,7 @@ typedef struct |
| #define TOR_INVALID_CHIP_ID INFRASTRUCT_NOOF_RCS + 3 |
| #define TOR_INVALID_CHIPLET_TYPE INFRASTRUCT_NOOF_RCS + 4 |
| #define TOR_INVALID_RING_ID INFRASTRUCT_NOOF_RCS + 5 |
| -#define TOR_INVALID_INSTANCE_ID INFRASTRUCT_NOOF_RCS + 6 |
| +#define TOR_INVALID_CHIPLET_ID INFRASTRUCT_NOOF_RCS + 6 |
| #define TOR_INVALID_RING_REQUEST INFRASTRUCT_NOOF_RCS + 7 |
| #define TOR_UNSUPPORTED_RING_SECTION INFRASTRUCT_NOOF_RCS + 8 |
| #define TOR_RING_FILE_NOT_FOUND INFRASTRUCT_NOOF_RCS + 9 |
| diff --git a/src/import/chips/p10/procedures/hwp/customize/p10_ipl_customize.C b/src/import/chips/p10/procedures/hwp/customize/p10_ipl_customize.C |
| index 3a114f0..b36ef65 100644 |
| --- a/src/import/chips/p10/procedures/hwp/customize/p10_ipl_customize.C |
| +++ b/src/import/chips/p10/procedures/hwp/customize/p10_ipl_customize.C |
| @@ -882,10 +882,10 @@ fapi2::ReturnCode _fetch_and_insert_vpd_rings( |
| |
| l_rc = tor_append_ring( |
| i_ringSection, |
| - io_ringSectionSize, // In: Exact size. Out: Updated size. |
| + i_maxRingSectionSize, |
| i_ringId, |
| - l_chipletId, // Chiplet ID |
| - i_vpdRing ); // The VPD RS4 ring container |
| + l_chipletId, |
| + i_vpdRing ); |
| |
| FAPI_ASSERT( l_rc == INFRASTRUCT_RC_SUCCESS, |
| fapi2::XIPC_TOR_APPEND_RING_FAILED(). |
| @@ -896,7 +896,10 @@ fapi2::ReturnCode _fetch_and_insert_vpd_rings( |
| "tor_append_ring() failed in sysPhase=%d w/rc=%d for ringId=0x%x", |
| i_sysPhase, l_rc, i_ringId ); |
| |
| - FAPI_IMP("Successfully appended VPD ring, (ringId,chipletId)=(0x%x,0x%02x), and now ringSectionSize=%u", |
| + io_ringSectionSize = be32toh(((TorHeader_t*)i_ringSection)->size); |
| + |
| + FAPI_IMP("Successfully appended VPD ring, (ringId,chipletId)=(0x%x,0x%02x), and" |
| + " now ringSectionSize=%u", |
| i_ringId, l_chipletId, io_ringSectionSize); |
| } |
| else if ((uint32_t)l_fapiRc == RC_MVPD_RING_NOT_FOUND) |
| @@ -907,7 +910,7 @@ fapi2::ReturnCode _fetch_and_insert_vpd_rings( |
| // No match, do nothing. But since rare, trace out as warning since all |
| // rings we're looking for in Mvpd really should be represented there. |
| FAPI_DBG("WARNING!: _fetch_and_insert_vpd_rings(): The ring w/" |
| - "(ringId,chipletId)=(0x%02x,0x%02x) was not found. (This is not a bug)", |
| + "(ringId,chipletId)=(0x%x,0x%02x) was not found. (This is not a bug)", |
| i_ringId, l_chipletId); |
| |
| fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; |
| @@ -977,7 +980,7 @@ fapi2::ReturnCode resolve_gptr_overlays( |
| FAPI_TRY( FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_EC, |
| i_procTarget, |
| o_ddLevel), |
| - "Error: Attribute ATTR_EC failed w/rc=0x%08x", |
| + "ERROR: Attribute ATTR_EC failed w/rc=0x%08x", |
| (uint64_t)current_err ); |
| |
| l_rc = p9_xip_get_section(i_hwImage, P9_XIP_SECTION_HW_OVERLAYS, &l_xipSection, o_ddLevel); |
| @@ -1848,7 +1851,7 @@ fapi2::ReturnCode process_base_and_dynamic_rings( |
| set_RING_ID(i_ringId). |
| set_DD_LEVEL(i_ddlevel). |
| set_LOCAL_RC(l_rc), |
| - "tor_get_single_ring() for Base ring: Failed w/rc=%i for " |
| + "ERROR: tor_get_single_ring() for Base ring: Failed w/rc=%i for " |
| "ringId=0x%x, chipletId=0xff and ddLevel=0x%x", |
| l_rc, i_ringId, i_ddlevel ); |
| |
| @@ -1862,14 +1865,9 @@ fapi2::ReturnCode process_base_and_dynamic_rings( |
| baseTypeField = ((CompressedScanData*)baseRs4)->iv_type; |
| } |
| |
| -//CMO-20190902: At this point we could probably sanity check that baseTypeField == |
| -// dynTypeField. However, it's a hit-and-miss check since we can only |
| -// make this check if both a Base AND a Dynamic ring is found. It's |
| -// better than nothing, but we postpone for now. |
| - |
| if(bBaseRingFound && bDynRingFound) |
| { |
| - FAPI_DBG("Base and Dynamic rings found.");// Will delete later |
| + FAPI_DBG("ringId=0x%x: Base ring found. Dynamic ring found.", i_ringId); |
| |
| // Use baseTypeField as ref input value for iv_type, but dynTypeField would be just as good |
| finalTypeField = (baseTypeField & ~RS4_IV_TYPE_SEL_MASK) | |
| @@ -1891,7 +1889,7 @@ fapi2::ReturnCode process_base_and_dynamic_rings( |
| } |
| else if(!bBaseRingFound && bDynRingFound) |
| { |
| - FAPI_DBG("No Base ring found. Dynamic ring found.");//Will delete later |
| + FAPI_DBG("ringId=0x%x: No Base ring found. Dynamic ring found.", i_ringId); |
| |
| // We'll need these temp vars below |
| RingId_t ringIdTmp = be16toh(((CompressedScanData*)finalRs4)->iv_ringId); |
| @@ -1927,7 +1925,7 @@ fapi2::ReturnCode process_base_and_dynamic_rings( |
| else if(bBaseRingFound && !bDynRingFound) |
| { |
| //In this case finalRs4 = baseRs4 = io_ringBuf1 already has the final ring |
| - FAPI_DBG("Base ring found. No Dynamic ring found.");//Will delete this later |
| + FAPI_DBG("ringId=0x%x: Base ring found. No Dynamic ring found.", i_ringId); |
| |
| finalTypeField = (baseTypeField & ~RS4_IV_TYPE_SEL_MASK) | |
| RS4_IV_TYPE_SEL_BASE | RS4_IV_TYPE_SEL_FINAL; |
| @@ -1939,11 +1937,11 @@ fapi2::ReturnCode process_base_and_dynamic_rings( |
| } |
| else |
| { |
| - FAPI_DBG("No Base or Dynamic rings found."); // Delete later |
| + FAPI_DBG("ringId=0x%x: No Base ring found. No Dynamic ring found.", i_ringId); |
| fapi2::current_err = RC_XIPC_NO_RING_FOUND; |
| } |
| |
| - //io_ringBuf1 has the final ring at this point. |
| + // Note that the final ring is already in io_ringBuf1 at this point. |
| |
| fapi_try_exit: |
| FAPI_DBG("Exiting process_base_and_dynamic_rings"); |
| @@ -1990,8 +1988,9 @@ ReturnCode p10_ipl_customize ( |
| uint32_t l_inputImageSize; |
| uint32_t l_imageSizeWithoutRings; |
| uint32_t l_currentImageSize; |
| - uint32_t l_maxImageSize = 0; // Attrib adjusted local value of MAX_SEEPROM_IMAGE_SIZE |
| - uint32_t l_maxRingSectionSize; |
| + uint32_t l_maxImageSize = 0; // Attrib adjusted local value of MAX_SEEPROM_IMAGE_SIZE |
| + uint32_t l_maxRingSectionSize; // Max size of ringSection |
| + uint32_t l_ringSectionBufSize; // Size of ringSection buffer |
| uint32_t l_sectionOffset = 1; |
| uint32_t attrMaxSbeSeepromSize = 0; |
| uint32_t l_requestedBootCoreMask = (i_sysPhase == SYSPHASE_HB_SBE) ? io_bootCoreMask : 0xFFFFFFFF; |
| @@ -2016,14 +2015,13 @@ ReturnCode p10_ipl_customize ( |
| void* baseRingSection = NULL; |
| void* dynamicRingSection = NULL; |
| TorHeader_t* torHeaderBase; |
| - uint32_t customRingSectionSize = 0; |
| uint8_t* partialKwdData = NULL; |
| uint32_t sizeofPartialKwdData = 0; |
| uint8_t mvpdRtvFromCode = 0xff; |
| uint8_t mvpdRtvFromMvpd = 0xff; |
| MvpdKeyword mvpdKeyword; |
| |
| - FAPI_IMP ("Entering p10_ipl_customize w/sysPhase=%d...", i_sysPhase); |
| + FAPI_IMP("Entering p10_ipl_customize w/sysPhase=%d...", i_sysPhase); |
| |
| |
| // Make copy of the requested bootCoreMask |
| @@ -2122,6 +2120,9 @@ ReturnCode p10_ipl_customize ( |
| (uintptr_t)i_ringBufSize2, |
| (uintptr_t)i_ringBufSize3 ); |
| |
| + // Make local copy of the [max] io_ringSectionBufSize before we start changing it |
| + l_ringSectionBufSize = io_ringSectionBufSize; |
| + |
| |
| //------------------------------------------- |
| // Verify that platform and Mvpd agree on: |
| @@ -2590,17 +2591,17 @@ ReturnCode p10_ipl_customize ( |
| set_CHIP_TARGET(i_procTarget). |
| set_INPUT_IMAGE_SIZE(l_inputImageSize). |
| set_IMAGE_BUF_SIZE(io_imageSize). |
| - set_RING_SECTION_BUF_SIZE(io_ringSectionBufSize). |
| + set_RING_SECTION_BUF_SIZE(l_ringSectionBufSize). |
| set_RING_BUF_SIZE1(i_ringBufSize1). |
| set_RING_BUF_SIZE2(i_ringBufSize2). |
| set_OCCURRENCE(2), |
| "One or more invalid input buffer sizes for HB_SBE phase:\n" |
| " l_maxImageSize=0x%016llx\n" |
| " io_imageSize=0x%016llx\n" |
| - " io_ringSectionBufSize=0x%016llx\n", |
| + " l_ringSectionBufSize=0x%016llx\n", |
| (uintptr_t)l_maxImageSize, |
| (uintptr_t)io_imageSize, |
| - (uintptr_t)io_ringSectionBufSize ); |
| + (uintptr_t)l_ringSectionBufSize ); |
| |
| } |
| |
| @@ -2691,7 +2692,8 @@ ReturnCode p10_ipl_customize ( |
| set_CHIP_TARGET(i_procTarget). |
| set_SYSPHASE(i_sysPhase). |
| set_OCCURRENCE(1), |
| - "Caller bug: Caller supplied unsupported value of sysPhase=%u (Occurrence 1)", |
| + "Caller bug: Caller supplied unsupported value of sysPhase=%u" |
| + " (Occurrence 1)", |
| i_sysPhase ); |
| |
| break; |
| @@ -2715,6 +2717,7 @@ ReturnCode p10_ipl_customize ( |
| |
| |
| |
| + |
| ////////////////////////////////////////////////////////////////////////// |
| // CUSTOMIZE item: Build up a new ring section in io_ringSectionBuf |
| // based on the TOR header info in baseRingSection. |
| @@ -2734,7 +2737,64 @@ ReturnCode p10_ipl_customize ( |
| set_CHIP_TARGET(i_procTarget), |
| "tor_skeleton_generation failed w/rc=0x%08X", (uint32_t)l_rc ); |
| |
| - customRingSectionSize = be32toh(((TorHeader_t*)io_ringSectionBuf)->size); |
| + // Now, start tracking the instantaneous actual custom ring section size. |
| + // (Note that we already took a copy of the [max] value of io_ringSectionBufSize |
| + // earlier on into l_ringSectionBufSize, so safe to update this now.) |
| + io_ringSectionBufSize = be32toh(((TorHeader_t*)io_ringSectionBuf)->size); |
| + |
| + |
| + |
| + |
| + ////////////////////////////////////////////////////////////////////////// |
| + // CUSTOMIZE item: Determine the max allowed ringSection size |
| + // Systemp phase: All phases |
| + ////////////////////////////////////////////////////////////////////////// |
| + |
| + switch (i_sysPhase) |
| + { |
| + |
| + case SYSPHASE_HB_SBE: |
| + |
| + // Calc the max ring section size for SBE. |
| + l_maxRingSectionSize = l_maxImageSize - l_imageSizeWithoutRings; |
| + |
| + break; |
| + |
| + case SYSPHASE_RT_QME: |
| + |
| + // Max ring section size for QME. |
| + l_maxRingSectionSize = l_ringSectionBufSize; // l_ringSectionBufSize is actual max buf size |
| + |
| + break; |
| + |
| + default: |
| + |
| + FAPI_ASSERT( false, |
| + fapi2::XIPC_INVALID_SYSPHASE_PARM(). |
| + set_CHIP_TARGET(i_procTarget). |
| + set_SYSPHASE(i_sysPhase). |
| + set_OCCURRENCE(2), |
| + "Caller bug: Caller supplied unsupported value of sysPhase=%u" |
| + " (Occurrence 2)", |
| + i_sysPhase ); |
| + |
| + break; |
| + } |
| + |
| + // maxRingSectionSize should never exceed ringSectionBufSize which should always be allocated |
| + // to be so large that we should be able to fill out the image to its maximum capacity. |
| + FAPI_ASSERT( l_maxRingSectionSize <= l_ringSectionBufSize, |
| + fapi2::XIPC_RING_SECTION_SIZING(). |
| + set_CHIP_TARGET(i_procTarget). |
| + set_RING_SECTION_SIZE(io_ringSectionBufSize). |
| + set_RING_SECTION_BUF_SIZE(l_ringSectionBufSize). |
| + set_MAX_RING_SECTION_SIZE(l_maxRingSectionSize). |
| + set_OCCURRENCE(1), |
| + "CODE BUG : maxRingSectionSize(=%u) > ringSectionBufSize(=%u) should" |
| + " never happen. Fix your assumptions/settings about ringSection" |
| + " buffer size or max image size (=%u) (Occurrence 1)", |
| + l_maxRingSectionSize, l_ringSectionBufSize, l_maxImageSize ); |
| + |
| |
| |
| |
| @@ -2767,7 +2827,9 @@ ReturnCode p10_ipl_customize ( |
| set_CHIP_TARGET(i_procTarget). |
| set_OCCURRENCE(5), |
| "FAPI_ATTR_GET(ATTR_DYNAMIC_INIT_FEATURE_VEC) failed." |
| - " Unable to determine featureVector." ); |
| + " Unable to determine featureVec." ); |
| + |
| + FAPI_IMP("Dynamic inits featureVec = 0x%016llx (GET from plat attribute)", featureVec); |
| |
| l_fapiRc2 = FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_IPL_PHASE, |
| FAPI_SYSTEM, |
| @@ -2822,6 +2884,8 @@ ReturnCode p10_ipl_customize ( |
| set_OCCURRENCE(8), |
| "Failed to set the dynamic init feature vector attribute" ); |
| |
| + FAPI_IMP("Dynamic inits featureVec = 0x%016llx (SET to plat attribute)", featureVec); |
| + |
| l_rc = p9_xip_get_section(i_hwImage, P9_XIP_SECTION_HW_DYNAMIC, &iplImgSection, attrDdLevel); |
| |
| FAPI_ASSERT( l_rc == INFRASTRUCT_RC_SUCCESS, |
| @@ -2848,7 +2912,7 @@ ReturnCode p10_ipl_customize ( |
| |
| //CMO-20190825: For the RT_QME phase we will get TOR_INVALID_CHIPLET_TYPE a lot |
| // here because we cycle through all the chiplets, when we really only |
| -// shold consider the EQ chiplet for RT_QME. For now, we will be |
| +// should consider the EQ chiplet for RT_QME. For now, we will be |
| // mindless, but this should probably be changed. |
| for(ringId = 0; ringId < NUM_RING_IDS; ringId++) |
| { |
| @@ -2880,16 +2944,16 @@ ReturnCode p10_ipl_customize ( |
| "ringId=0x%0x w/rc=0x%08x", |
| ringId, (uint32_t)l_fapiRc); |
| |
| - if(l_fapiRc == FAPI2_RC_SUCCESS) |
| + if (l_fapiRc == FAPI2_RC_SUCCESS) |
| { |
| l_rc = tor_append_ring( |
| io_ringSectionBuf, |
| - customRingSectionSize, |
| + l_maxRingSectionSize, |
| ringId, |
| 0xff, |
| i_ringBuf1 ); |
| |
| - FAPI_ASSERT( l_rc == INFRASTRUCT_RC_SUCCESS || |
| + FAPI_ASSERT( l_rc == TOR_SUCCESS || |
| l_rc == TOR_INVALID_CHIPLET_TYPE || |
| l_rc == TOR_RING_HAS_DERIVS, |
| fapi2::XIPC_TOR_APPEND_RING_FAILED(). |
| @@ -2902,12 +2966,45 @@ ReturnCode p10_ipl_customize ( |
| "for ringId=0x%x", |
| l_rc, ringId ); |
| |
| - FAPI_DBG("A Base or Dynamic ring w/ringId=0x%x was either appended or skipped (if" |
| - " deriv ring or invalid chiplet) and now ringSectionSize=%u", |
| - ringId, be32toh(((TorHeader_t*)io_ringSectionBuf)->size)); |
| + io_ringSectionBufSize = be32toh(((TorHeader_t*)io_ringSectionBuf)->size); |
| + |
| + switch (l_rc) |
| + { |
| + case TOR_SUCCESS: |
| + FAPI_IMP("A Base or Dynamic ring w/ringId=0x%x was appended" |
| + " and now ringSection->size=%u", |
| + ringId, io_ringSectionBufSize); |
| + break; |
| + |
| + case TOR_INVALID_CHIPLET_TYPE: |
| + FAPI_IMP("A Base or Dynamic ring w/ringId=0x%x was skipped" |
| + " because its an invalid chiplet for this sysPhase=%u", |
| + ringId, i_sysPhase); |
| + break; |
| + |
| + case TOR_RING_HAS_DERIVS: |
| + FAPI_IMP("A Base or Dynamic ring w/ringId=0x%x was skipped" |
| + " because its a [root] ring w/derivatives", |
| + ringId); |
| + break; |
| + |
| + default: |
| + FAPI_ASSERT( false, |
| + fapi2::XIPC_CODE_BUG(). |
| + set_CHIP_TARGET(i_procTarget). |
| + set_OCCURRENCE(2), |
| + "Code bug(2): Messed up RC handling in assoc code. Fix code!" ); |
| + break; |
| + } |
| + |
| } |
| } |
| |
| + // Now create the "anticipatory" dynamic init debug ring list. |
| + // - This list lists all the ringIds that have received dynamic init overlays. |
| + // - For each ringId, the complete final feature vector is included so it can be seen |
| + // which specific features were applied to a given ringId. |
| + // - The list may come in handy in case of scanning issues with the final dynamic rings. |
| ringIdFeatListSize = ringIdFeatureVecMap.size() * (sizeof(uint64_t) + sizeof(RingId_t)); |
| ringIdFeatList = new uint8_t[ringIdFeatListSize]; |
| |
| @@ -2938,11 +3035,6 @@ ReturnCode p10_ipl_customize ( |
| 0 ); |
| |
| |
| - // Make a copy of the supplied max ring section buffer size before over writing it |
| - l_maxRingSectionSize = io_ringSectionBufSize; |
| - |
| - // Now, start tracking the instantaneous actual custom ring section size |
| - io_ringSectionBufSize = customRingSectionSize; |
| |
| ////////////////////////////////////////////////////////////////////////// |
| // CUSTOMIZE item: Append VPD rings to io_ringSectionBuf |
| @@ -3019,12 +3111,8 @@ ReturnCode p10_ipl_customize ( |
| |
| case SYSPHASE_HB_SBE: |
| |
| - FAPI_DBG("Size of SBE .rings section before VPD update: %d", io_ringSectionBufSize); |
| - |
| - // Adjust the max ring section size |
| - l_maxRingSectionSize = l_maxImageSize - l_imageSizeWithoutRings; |
| - |
| - FAPI_DBG("Max allowable size of .rings section: %d", l_maxRingSectionSize); |
| + FAPI_DBG("Size of SBE .rings section before VPD update: %u (max size allowed: %u)", |
| + io_ringSectionBufSize, l_maxRingSectionSize); |
| |
| //---------------------------------------- |
| // Append VPD Rings to the .rings section |
| @@ -3107,12 +3195,13 @@ ReturnCode p10_ipl_customize ( |
| |
| // More size code sanity checks of section and image sizes. |
| FAPI_ASSERT( io_ringSectionBufSize <= l_maxRingSectionSize, |
| - fapi2::XIPC_SECTION_SIZING(). |
| + fapi2::XIPC_RING_SECTION_SIZING(). |
| set_CHIP_TARGET(i_procTarget). |
| set_RING_SECTION_SIZE(io_ringSectionBufSize). |
| + set_RING_SECTION_BUF_SIZE(l_ringSectionBufSize). |
| set_MAX_RING_SECTION_SIZE(l_maxRingSectionSize). |
| - set_OCCURRENCE(1), |
| - "Code bug: ringSectionBufSize(=%d) > maxRingSectionSize(=%d) in HB_SBE(1)", |
| + set_OCCURRENCE(2), |
| + "Code bug: ringSectionBufSize(=%d) > maxRingSectionSize(=%d) in HB_SBE (Occurrence 2)", |
| io_ringSectionBufSize, l_maxRingSectionSize ); |
| |
| FAPI_ASSERT( (l_imageSizeWithoutRings + io_ringSectionBufSize) <= l_maxImageSize, |
| @@ -3219,12 +3308,14 @@ ReturnCode p10_ipl_customize ( |
| |
| // More size code sanity checks of section and image sizes. |
| FAPI_ASSERT( io_ringSectionBufSize <= l_maxRingSectionSize, |
| - fapi2::XIPC_SECTION_SIZING(). |
| + fapi2::XIPC_RING_SECTION_SIZING(). |
| set_CHIP_TARGET(i_procTarget). |
| set_RING_SECTION_SIZE(io_ringSectionBufSize). |
| + set_RING_SECTION_BUF_SIZE(l_ringSectionBufSize). |
| set_MAX_RING_SECTION_SIZE(l_maxRingSectionSize). |
| set_OCCURRENCE(3), |
| - "Code bug: QME ring section size(=%d) > maxRingSectionSize(=%d) in RT_QME(3)", |
| + "Code bug: QME ring section size(=%d) > maxRingSectionSize(=%d)" |
| + " in RT_QME (Occurrence 3)", |
| io_ringSectionBufSize, l_maxRingSectionSize ); |
| |
| break; |
| @@ -3234,8 +3325,9 @@ ReturnCode p10_ipl_customize ( |
| fapi2::XIPC_INVALID_SYSPHASE_PARM(). |
| set_CHIP_TARGET(i_procTarget). |
| set_SYSPHASE(i_sysPhase). |
| - set_OCCURRENCE(2), |
| - "Caller bug: Caller supplied unsupported value of sysPhase=%u (Occurrence 2)", |
| + set_OCCURRENCE(3), |
| + "Caller bug: Caller supplied unsupported value of sysPhase=%u" |
| + " (Occurrence 3)", |
| i_sysPhase ); |
| |
| break; |
| diff --git a/src/import/chips/p10/procedures/hwp/customize/p10_qme_customize.C b/src/import/chips/p10/procedures/hwp/customize/p10_qme_customize.C |
| index a87bc2b..fc645d6 100644 |
| --- a/src/import/chips/p10/procedures/hwp/customize/p10_qme_customize.C |
| +++ b/src/import/chips/p10/procedures/hwp/customize/p10_qme_customize.C |
| @@ -5,7 +5,7 @@ |
| /* */ |
| /* OpenPOWER HostBoot Project */ |
| /* */ |
| -/* Contributors Listed Below - COPYRIGHT 2016,2019 */ |
| +/* Contributors Listed Below - COPYRIGHT 2016,2020 */ |
| /* [+] International Business Machines Corp. */ |
| /* */ |
| /* */ |
| @@ -49,11 +49,10 @@ fapi2::ReturnCode p10_qme_customize( |
| uint32_t& io_bufCustRingsSize, |
| uint32_t i_dbgl) |
| { |
| - FAPI_IMP(">> p10_qme_customize "); |
| - |
| int rc = INFRASTRUCT_RC_SUCCESS; |
| |
| - TorHeader_t* torHeader = (TorHeader_t*) i_bufQmeRings; |
| + TorHeader_t* torHeaderQme = (TorHeader_t*) i_bufQmeRings; |
| + TorHeader_t* torHeaderCust = (TorHeader_t*) io_bufCustRings; |
| |
| uint8_t ddLevel; |
| uint8_t torVersion; |
| @@ -63,11 +62,13 @@ fapi2::ReturnCode p10_qme_customize( |
| ChipId_t chipId = UNDEFINED_CHIP_ID; |
| ChipletData_t* chipletData; |
| |
| - ddLevel = torHeader->ddLevel; |
| - torVersion = torHeader->version; |
| - torMagic = be32toh(torHeader->magic); |
| - chipId = torHeader->chipId; |
| - inputQmeRingsSize = be32toh(torHeader->size); |
| + FAPI_IMP(">> p10_qme_customize "); |
| + |
| + ddLevel = torHeaderQme->ddLevel; |
| + torVersion = torHeaderQme->version; |
| + torMagic = be32toh(torHeaderQme->magic); |
| + chipId = torHeaderQme->chipId; |
| + inputQmeRingsSize = be32toh(torHeaderQme->size); |
| |
| RingId_t numRings = UNDEFINED_RING_ID; // Number of chiplet common or instance rings |
| MyBool_t bInstCase = UNDEFINED_BOOLEAN; // 0:COMMON, 1:INSTANCE rings |
| @@ -78,8 +79,11 @@ fapi2::ReturnCode p10_qme_customize( |
| |
| uint8_t iRing; |
| void* nextRing = NULL; |
| - uint32_t nextRingSize; |
| + uint32_t remBufSize; |
| |
| + // |
| + // Step 0: Test input parameters |
| + // |
| FAPI_ASSERT(i_custOp < NUM_CUSTOMIZE_QME_ENTRIES |
| && i_bufQmeRings != NULL |
| && io_bufCustRings != NULL, |
| @@ -127,6 +131,7 @@ fapi2::ReturnCode p10_qme_customize( |
| // Step 1: Create TOR skeleton ringSection |
| // Create the complete ring skeleton, but with empty TOR ring slots (ie, no ring content). |
| // |
| + |
| rc = tor_skeleton_generation(io_bufCustRings, |
| torMagic, |
| torVersion, |
| @@ -135,13 +140,9 @@ fapi2::ReturnCode p10_qme_customize( |
| i_dbgl); |
| |
| FAPI_DBG("tor_skeleton_generation() completed w/rc=0x%08x,\n" |
| - " torMagic=0x%08x and torVersion=0x%08x,\n" |
| - " ddLevel=0x%08x and chipId=0x%08x.\n", |
| - rc, |
| - torMagic, |
| - torVersion, |
| - ddLevel, |
| - chipId); |
| + " torMagic=0x%08x, torVersion=%u,\n" |
| + " ddLevel=0x%02x and chipId=0x%02x.\n", |
| + rc, torMagic, torVersion, ddLevel, chipId); |
| |
| FAPI_ASSERT(rc == INFRASTRUCT_RC_SUCCESS, |
| fapi2::QMEC_TOR_SKELETON_GEN_ERROR() |
| @@ -151,20 +152,13 @@ fapi2::ReturnCode p10_qme_customize( |
| .set_TOR_VER(torVersion) |
| .set_DD_LEVEL(ddLevel) |
| .set_CHIP_ID(chipId), |
| - "Error: tor_skeleton_generation() failed w/rc=0x%08x,\n" |
| - " torMagic=0x%08x and torVersion=0x%08x,\n" |
| - " ddLevel=0x%08x and chipId=0x%08x.\n", |
| - rc, |
| - torMagic, |
| - torVersion, |
| - ddLevel, |
| - chipId); |
| + "Error: tor_skeleton_generation() failed w/rc=0x%08x," |
| + " torMagic=0x%08x, torVersion=%u, ddLevel=0x%02x and chipId=0x%02x\n", |
| + rc, torMagic, torVersion, ddLevel, chipId); |
| |
| // |
| // Step 2: Add ring content |
| - // Main TOR ringSection create loop |
| - // - Generate RS4 container for each ring, attaching it to end of ringSection and update |
| - // the ring's TOR offset slot |
| + // Append rings to the end of the [skeleton] TOR ring section and update TOR offset slot |
| // |
| |
| // Get all the meta data for this chiplet and its rings |
| @@ -174,13 +168,6 @@ fapi2::ReturnCode p10_qme_customize( |
| EQ_TYPE, |
| &chipletData); |
| |
| - FAPI_DBG("ringid_get_chipletProps() completed w/rc=0x%08x,\n" |
| - " chipId=0x%08x, torMagic=0x%08x, torVersion=0x%08x.\n", |
| - rc, |
| - chipId, |
| - torMagic, |
| - torVersion); |
| - |
| FAPI_ASSERT(rc == INFRASTRUCT_RC_SUCCESS, |
| fapi2::QMEC_RINGID_GET_CHIPLETPROPS_ERROR() |
| .set_TARGET(i_procTarget) |
| @@ -188,10 +175,8 @@ fapi2::ReturnCode p10_qme_customize( |
| .set_TOR_MAGIC(torMagic) |
| .set_TOR_VER(torVersion), |
| "Error: ringid_get_chipletProps() failed w/rc=0x%08x,\n" |
| - " ddLevel=0x%08x and torVersion=0x%08x.\n", |
| - rc, |
| - torMagic, |
| - torVersion); |
| + " torMagic=0x%08x and torVersion=%u.\n", |
| + rc, torMagic, torVersion); |
| |
| chipletInstId = chipletData->chipletBaseId + i_custOp; |
| |
| @@ -199,13 +184,6 @@ fapi2::ReturnCode p10_qme_customize( |
| chipletData->numInstanceRings : |
| chipletData->numCommonRings; |
| |
| - FAPI_DBG("p10_qme_customize(): chipletInstId = 0x%08x, numRings = 0x%08x,\n" |
| - " numInstanceRings = 0x%08x, numCommonRings = 0x%08x.\n", |
| - chipletInstId, |
| - numRings, |
| - chipletData->numInstanceRings, |
| - chipletData->numCommonRings); |
| - |
| // Loop through all rings, get ring data for each ring and |
| // append it to cust ring section. |
| for (iRing = 0; iRing < numRings; iRing++) |
| @@ -219,15 +197,6 @@ fapi2::ReturnCode p10_qme_customize( |
| ringId, |
| false); |
| |
| - FAPI_DBG("ringidGetRingId2() completed w/rc=0x%08x,\n" |
| - " torMagic=0x%08x,iRing=0x%08x,\n" |
| - " bInstCase=%d, ringId=0x%08x.\n", |
| - rc, |
| - torMagic, |
| - iRing, |
| - bInstCase, |
| - ringId); |
| - |
| FAPI_ASSERT(rc == INFRASTRUCT_RC_SUCCESS, |
| fapi2::QMEC_RINGID_GET_RINGID2_ERROR() |
| .set_TARGET(i_procTarget) |
| @@ -237,30 +206,26 @@ fapi2::ReturnCode p10_qme_customize( |
| .set_INST_CASE(bInstCase) |
| .set_RING_ID(ringId), |
| "Error: ringidGetRingId2() failed w/rc=0x%08x,\n" |
| - " torMagic=0x%08x,iRing=0x%08x,\n" |
| - " bInstCase=%d, ringId=0x%08x.\n", |
| - rc, |
| - torMagic, |
| - iRing, |
| - bInstCase, |
| - ringId); |
| - |
| - io_bufCustRingsSize = be32toh(((TorHeader_t*) io_bufCustRings)->size); |
| + " torMagic=0x%08x, iRing=%u,\n" |
| + " bInstCase=%u and ringId=0x%x.\n", |
| + rc, torMagic, iRing, bInstCase, ringId); |
| + |
| + io_bufCustRingsSize = be32toh(torHeaderCust->size); |
| nextRing = (void*) (io_bufCustRings + io_bufCustRingsSize); |
| - nextRingSize = maxCustRingsSize - io_bufCustRingsSize; |
| |
| - // nextRing is portion of io_bufCustRings buffer, which is used as |
| - // temporary memory to pass the ring in i_bufQmeRings from the |
| + // nextRing is portion of io_bufCustRings buffer which is used as |
| + // temporary buffer to pass the ring in i_bufQmeRings from the |
| // tor_get_single_ring() function. |
| - // The size of nextRing is the size of temporary memory. |
| + // The size of this temporary buffer is captured by remBufSize. |
| FAPI_ASSERT(maxCustRingsSize > io_bufCustRingsSize, |
| fapi2::QMEC_RINGS_OUTPUT_BUFFER_TOO_SMALL() |
| .set_MAX_CUST_RINGS_BUF_SIZE(maxCustRingsSize) |
| .set_CUST_QME_RINGS_BUF_SIZE(io_bufCustRingsSize), |
| "Error: QME rings output buffer is not large enough to use part of it for rs4Ring,\n" |
| " maxCustRingsSize=0x%08x, io_bufCustRingsSize=0x%08x.\n", |
| - maxCustRingsSize, |
| - io_bufCustRingsSize); |
| + maxCustRingsSize, io_bufCustRingsSize); |
| + |
| + remBufSize = maxCustRingsSize - io_bufCustRingsSize; |
| |
| // Extract ring data using the ringId. |
| rc = tor_get_single_ring(i_bufQmeRings, |
| @@ -268,18 +233,9 @@ fapi2::ReturnCode p10_qme_customize( |
| ringId, |
| chipletInstId, //This argument ignored for Common rings. |
| nextRing, |
| - nextRingSize, |
| + remBufSize, |
| i_dbgl); |
| |
| - FAPI_DBG("tor_get_single_ring() completed w/rc=0x%08x,\n" |
| - " ddLevel=0x%08x, ringId=0x%08x,\n" |
| - " chipletInstId=0x%08x, nextRs4RingSize=%d.\n", |
| - rc, |
| - ddLevel, |
| - ringId, |
| - chipletInstId, |
| - nextRingSize); |
| - |
| FAPI_ASSERT(rc == INFRASTRUCT_RC_SUCCESS || |
| rc == TOR_RING_IS_EMPTY, |
| fapi2::QMEC_TOR_GET_SINGLE_RING_ERROR() |
| @@ -288,17 +244,12 @@ fapi2::ReturnCode p10_qme_customize( |
| .set_DD_LEVEL(ddLevel) |
| .set_RING_ID(ringId) |
| .set_CHIPLET_INST_ID(chipletInstId) |
| - .set_NEXT_RS4RING_BUF_SIZE(nextRingSize), |
| - "Error: tor_get_single_ring() failed w/rc=0x%08x,\n" |
| - " ddLevel=0x%08x, ringId=0x%08x,\n" |
| - " chipletInstId=0x%08x, nextRs4RingSize=%d.\n", |
| - rc, |
| - ddLevel, |
| - ringId, |
| - chipletInstId, |
| - nextRingSize); |
| - |
| - // if ring is empty, loop through and check next ring. |
| + .set_NEXT_RS4RING_BUF_SIZE(remBufSize), |
| + "Error: tor_get_single_ring() failed w/rc=0x%08x, ddLevel=0x%02x," |
| + " ringId=0x%x, chipletInstId=0x%02x, remBufSize=%u.\n", |
| + rc, ddLevel, ringId, chipletInstId, remBufSize); |
| + |
| + // If ring is empty, skip and check next ring. |
| if(rc == TOR_RING_IS_EMPTY) |
| { |
| rc = INFRASTRUCT_RC_SUCCESS; |
| @@ -308,17 +259,13 @@ fapi2::ReturnCode p10_qme_customize( |
| // Append ring to ring section. |
| // Note that this API also updates the header's ring size |
| rc = tor_append_ring(io_bufCustRings, |
| - io_bufCustRingsSize, |
| + maxCustRingsSize, |
| ringId, |
| chipletInstId, |
| - (void*) nextRing, |
| + (void*)nextRing, |
| i_dbgl); |
| |
| - FAPI_DBG("tor_append_ring() completed w/rc=0x%08x,\n" |
| - " io_bufCustRingsSize=0x%08x, ringId=0x%x.\n", |
| - rc, |
| - io_bufCustRingsSize, |
| - ringId); |
| + io_bufCustRingsSize = be32toh(torHeaderCust->size); |
| |
| FAPI_ASSERT(rc == INFRASTRUCT_RC_SUCCESS, |
| fapi2::QMEC_TOR_APPEND_RING_ERROR() |
| @@ -328,16 +275,13 @@ fapi2::ReturnCode p10_qme_customize( |
| .set_RING_ID(ringId), |
| "Error: tor_append_ring() failed w/rc=0x%08x,\n" |
| " io_bufCustRingsSize=0x%08x, ringId=0x%x.\n", |
| - rc, |
| - io_bufCustRingsSize, |
| - ringId); |
| + rc, io_bufCustRingsSize, ringId); |
| + |
| } |
| |
| - FAPI_DBG("p10_qme_customize(): io_bufCustRingsSize = 0x%08x\n", |
| - io_bufCustRingsSize); |
| +fapi_try_exit: |
| |
| FAPI_IMP("<< p10_qme_customize "); |
| |
| -fapi_try_exit: |
| return fapi2::current_err; |
| } |
| diff --git a/src/import/chips/p10/procedures/xml/error_info/p10_ipl_customize_errors.xml b/src/import/chips/p10/procedures/xml/error_info/p10_ipl_customize_errors.xml |
| index eeb7016..838c3e6 100644 |
| --- a/src/import/chips/p10/procedures/xml/error_info/p10_ipl_customize_errors.xml |
| +++ b/src/import/chips/p10/procedures/xml/error_info/p10_ipl_customize_errors.xml |
| @@ -353,10 +353,11 @@ |
| </hwpError> |
| <!-- ********************************************************************* --> |
| <hwpError> |
| - <rc>RC_XIPC_SECTION_SIZING</rc> |
| + <rc>RC_XIPC_RING_SECTION_SIZING</rc> |
| <description>Code bug: Ring section size would exceed max ring section size</description> |
| <ffdc>CHIP_TARGET</ffdc> |
| <ffdc>RING_SECTION_SIZE</ffdc> |
| + <ffdc>RING_SECTION_BUF_SIZE</ffdc> |
| <ffdc>MAX_RING_SECTION_SIZE</ffdc> |
| <ffdc>OCCURRENCE</ffdc> |
| <callout> |
| diff --git a/src/import/chips/p10/utils/imageProcs/p10_infrastruct_help.H b/src/import/chips/p10/utils/imageProcs/p10_infrastruct_help.H |
| index 81df056..feffee2 100644 |
| --- a/src/import/chips/p10/utils/imageProcs/p10_infrastruct_help.H |
| +++ b/src/import/chips/p10/utils/imageProcs/p10_infrastruct_help.H |
| @@ -49,7 +49,6 @@ const uint32_t MAX_RT_IMAGE_SIZE = 1024 * 1024; // Max Runtime size. |
| const uint32_t MAX_RING_BUF_SIZE = 650000; // Max ring buffer size (agreed w/HB). |
| const uint32_t MAX_RING_BUF_SIZE_TOOL = 450000; // Max ring buf size for tools. |
| |
| -const uint32_t MAX_DYN_RING_SECTION_SIZE = 1024 * 1024; // Max dynamic ring section size. |
| const uint32_t MAX_OVERRIDES_SIZE = 2 * 1024; // Max overrides ring section size. |
| const uint32_t MAX_HBBL_SIZE = 20 * 1024; // Max hbbl bin section size. |
| |
| diff --git a/src/import/chips/p10/utils/imageProcs/p10_scan_compression.H b/src/import/chips/p10/utils/imageProcs/p10_scan_compression.H |
| index 8485543..ba38835 100644 |
| --- a/src/import/chips/p10/utils/imageProcs/p10_scan_compression.H |
| +++ b/src/import/chips/p10/utils/imageProcs/p10_scan_compression.H |
| @@ -5,7 +5,7 @@ |
| /* */ |
| /* OpenPOWER HostBoot Project */ |
| /* */ |
| -/* Contributors Listed Below - COPYRIGHT 2019 */ |
| +/* Contributors Listed Below - COPYRIGHT 2019,2020 */ |
| /* [+] International Business Machines Corp. */ |
| /* */ |
| /* */ |
| @@ -86,7 +86,8 @@ typedef struct |
| uint16_t iv_undefined; // Must be last (temp assumption in Mvpd accessor) |
| } CompressedScanData; |
| |
| -#define RS4_V3TOV4_SIZE_INC 4 // Header increase from V3 to V4 (needed by Mvpd accessor) |
| +#define RS4_V3TOV4_SIZE_INC 4 // Header increase from V3 to V4 (needed by Mvpd accessor) |
| +#define RS4_MIN_RING_SIZE 20 // Min value of iv_size, e.g. flush size of short ring. |
| |
| /// Endian-translate a CompressedScanData structure |
| /// |
| diff --git a/src/import/chips/p10/utils/imageProcs/p10_tor.C b/src/import/chips/p10/utils/imageProcs/p10_tor.C |
| index 62f9462..c3f0e86 100644 |
| --- a/src/import/chips/p10/utils/imageProcs/p10_tor.C |
| +++ b/src/import/chips/p10/utils/imageProcs/p10_tor.C |
| @@ -36,37 +36,40 @@ |
| |
| |
| /////////////////////////////////////////////////////////////////////////////////// |
| -// Get Ring From Ring Section function |
| +// [internal] TOR Access Ring function |
| ////////////////////////////////////////////////////////////////////////////////// |
| static |
| -int get_ring_from_ring_section( void* i_ringSection, // Ring section ptr |
| - RingId_t i_ringId, // Ring ID |
| - uint8_t& io_instanceId, // IO instance ID |
| - RingRequest_t i_ringRequest, // {GET,PUT}_SINGLE_RING |
| - void* io_rs4Ring, // IO RS4 ring buffer (caller mgd) |
| - uint32_t& io_ringBufSize, // Query, rs4Size, or max buf size |
| - uint32_t i_dbgl ) |
| +int _tor_access_ring( void* io_ringSection, // Ring section ptr |
| + uint32_t i_maxRingSectionSize, // Max ringSection size |
| + RingId_t i_ringId, // Ring ID to extract or append |
| + uint8_t i_chipletId, // Chiplet ID (ignored for Common rings) |
| + RingRequest_t i_ringRequest, // {GET,PUT}_SINGLE_RING |
| + void* io_rs4Ring, // RS4 ring buffer (caller mgd) |
| + uint32_t& io_ringBufSize, // Query, rs4Size, or max buf size |
| + uint32_t i_dbgl ) |
| { |
| int rc = TOR_SUCCESS; |
| TorHeader_t* torHeader; |
| uint32_t torMagic; |
| ChipId_t chipId; |
| TorCpltBlock_t* cpltBlock; |
| - TorCpltOffset_t cpltOffset; // Offset from ringSection to chiplet section |
| - TorRingOffset_t ringOffset; // Offset to actual ring container |
| + TorOffset_t cpltOffsetSlot; // Offset to TOR chiplet offset slot |
| + TorOffset_t cpltOffset; // Offset from ringSection to chiplet section |
| + TorOffset_t ringOffsetSlot; // Offset to TOR ring offset slot |
| + TorOffset_t ringOffset; // Offset to actual ring container (for GET operation) |
| + TorOffset_t ringOffset16; // Offset to actual ring container (for PUT operation) |
| uint32_t torSlotNum; // TOR slot number (within a chiplet section) |
| uint32_t rs4Size; // Size of RS4 ring container/block. |
| RingId_t numRings; |
| ChipletType_t chipletType = UNDEFINED_CHIPLET_TYPE; |
| ChipletType_t chipletIndex = UNDEFINED_CHIPLET_TYPE; // Effective chiplet index |
| MyBool_t bInstCase = UNDEFINED_BOOLEAN; |
| - ChipletData_t* chipletData; |
| - uint8_t numInstances; |
| RingProperties_t* ringProps = NULL; |
| + ChipletData_t* chipletData = NULL; |
| uint8_t idxRingEff; // Effective chiplet ring index |
| - uint8_t iInst, iRing; // Index counters for instance, chiplet rings |
| + uint32_t ringSectionSize; |
| |
| - torHeader = (TorHeader_t*)i_ringSection; |
| + torHeader = (TorHeader_t*)io_ringSection; |
| torMagic = be32toh(torHeader->magic); |
| chipId = torHeader->chipId; |
| |
| @@ -100,7 +103,7 @@ int get_ring_from_ring_section( void* i_ringSection, // Ring section |
| } |
| |
| // |
| - // Check the scope of chipletType and Get the effective chipletType's index |
| + // Check the scope of chipletType and get the effective chipletType's index |
| // |
| rc = ringid_get_chipletIndex( chipId, |
| torMagic, |
| @@ -133,20 +136,30 @@ int get_ring_from_ring_section( void* i_ringSection, // Ring section |
| bInstCase = 0; |
| } |
| |
| - // |
| - // Calculate various loop upper limits |
| - // |
| - numInstances = bInstCase ? |
| - chipletData->numChipletInstances : |
| - 1; |
| - |
| numRings = bInstCase ? |
| chipletData->numInstanceRings : |
| chipletData->numCommonRings; |
| |
| idxRingEff = ringProps[i_ringId].idxRing & INSTANCE_RING_MASK; // Always safe |
| |
| + // |
| + // Check that chipletId is within chiplet's range (Note that we care only about Instance |
| + // rings here so we can identify to proper slot. For Common rings, we can ignore the |
| + // chipletId since there's only one instance slot, namely the 0'th.) |
| + // |
| + if ( bInstCase && |
| + ( i_chipletId < chipletData->chipletBaseId || |
| + i_chipletId > (chipletData->chipletBaseId + chipletData->numChipletInstances - 1) ) ) |
| + { |
| + // TOR_INVALID_CHIPLET_ID: This is not necessarily an error. User codes may differ |
| + // in their knowledge what is an acceptable value for the chipletId. So we can't |
| + // trace out here in confidence. It's up to the caller to investigate the rc. |
| + return TOR_INVALID_CHIPLET_ID; |
| + } |
| + |
| + // |
| // Unless we find a ring, then the following rc will be returned |
| + // |
| rc = TOR_RING_HAS_NO_TOR_SLOT; |
| |
| // |
| @@ -154,137 +167,138 @@ int get_ring_from_ring_section( void* i_ringSection, // Ring section |
| // |
| if (numRings) // Only proceed if chiplet has [Common/Instance] rings. |
| { |
| - // Calc offset to chiplet's CMN or INST section, cpltOffset (steps 1-3) |
| + // Calc offset to chiplet's CMN or INST section, cpltOffset |
| + // - Note that the TOR cpltOffset is assumed to be wrt to ringSection origin |
| + // |
| + // 1. Calc offset to TOR chiplet offset slot pointing to chiplet's COM or INST section |
| + cpltOffsetSlot = sizeof(TorHeader_t) + |
| + chipletIndex * sizeof(TorCpltBlock_t) + |
| + bInstCase * sizeof(cpltBlock->cmnOffset); |
| + // 2. Retrive chiplet offset and endian convert |
| + cpltOffset = *(TorOffset_t*)( (uint8_t*)io_ringSection + cpltOffsetSlot ); |
| + cpltOffset = be16toh(cpltOffset); // <- This is the final TOR chiplet offset |
| + |
| + // |
| + // Calc the effective TOR offset slot index number (within the chiplet's Common |
| + // or Instance ring section) |
| // |
| - // 1. Calc offset to TOR slot pointing to chiplet's COM or INST section |
| - cpltOffset = sizeof(TorHeader_t) + |
| - chipletIndex * sizeof(TorCpltBlock_t) + |
| - bInstCase * sizeof(cpltBlock->cmnOffset); |
| - // 2. Retrive offset, endian convert and make it relative to ring section origin |
| - cpltOffset = *(uint32_t*)( (uint8_t*)i_ringSection + cpltOffset ); |
| - cpltOffset = be32toh(cpltOffset); |
| - // 3. Make offset relative to ring section origin |
| - cpltOffset = sizeof(TorHeader_t) + cpltOffset; |
| - |
| - torSlotNum = 0; |
| - |
| - for ( iInst = 0; iInst < numInstances; iInst++ ) |
| + torSlotNum = bInstCase * (i_chipletId - chipletData->chipletBaseId) * numRings + idxRingEff; |
| + |
| + // Calc offset to actual ring, ringOffset |
| + // - Note that ringOffset is assumed to be wrt to ringSection origin |
| + // |
| + // 1. Calc offset to the TOR ring offset slot (which points to the actual ring) |
| + ringOffsetSlot = cpltOffset + torSlotNum * sizeof(ringOffset); |
| + // 2. Retrieve ring offset and endian convert |
| + ringOffset = *(TorOffset_t*)( (uint8_t*)io_ringSection + ringOffsetSlot ); |
| + ringOffset = be16toh(ringOffset); // <- This is the final TOR ring offset |
| + |
| + if (i_ringRequest == GET_SINGLE_RING) |
| { |
| - for ( iRing = 0; iRing < numRings; iRing++ ) |
| + rs4Size = 0; |
| + |
| + if (ringOffset) |
| { |
| - // Remember in the following "busy" if that we're already in the correct |
| - // chiplet ring section and that we're merely trying to determine if we have |
| - // hit the proper combination of (iRing,iInst). |
| - if ( idxRingEff == iRing && |
| - ( !bInstCase || |
| - ( bInstCase && |
| - ( iInst == (io_instanceId - chipletData->chipletBaseId) ) ) ) ) |
| - { |
| - // Calc offset to actual ring, ringOffset (steps 1-3) |
| - // |
| - // 1. Calc offset to TOR slot pointing to actual ring |
| - ringOffset = cpltOffset + torSlotNum * sizeof(ringOffset); |
| - // 2. Retrieve offset and endian convert |
| - ringOffset = *(TorRingOffset_t*)( (uint8_t*)i_ringSection + ringOffset ); |
| - ringOffset = be16toh(ringOffset); |
| - |
| - if (i_ringRequest == GET_SINGLE_RING) |
| - { |
| - rs4Size = 0; |
| - |
| - if (ringOffset) |
| - { |
| - // 3. Make offset relative to ring section origin |
| - ringOffset = cpltOffset + ringOffset; |
| - |
| - rs4Size = be16toh( ((CompressedScanData*) |
| - ((uint8_t*)i_ringSection + ringOffset))->iv_size ); |
| - |
| - if (io_ringBufSize < rs4Size) |
| - { |
| - if (i_dbgl > 0) |
| - { |
| - MY_DBG("io_ringBufSize(=%u) is less than rs4Size(=%u).\n", |
| - io_ringBufSize, rs4Size); |
| - } |
| - |
| - io_ringBufSize = rs4Size; |
| - return TOR_BUFFER_TOO_SMALL; |
| - } |
| - |
| - // Produce return parms |
| - memcpy( io_rs4Ring, |
| - (void*)((uint8_t*)i_ringSection + ringOffset), |
| - rs4Size ); |
| - io_ringBufSize = rs4Size; |
| - io_instanceId = bInstCase ? |
| - io_instanceId : |
| - chipletData->chipletBaseId; |
| - |
| - if (i_dbgl > 0) |
| - { |
| - MY_DBG("Found a ring:\n" \ |
| - " ringId: 0x%x\n" \ |
| - " rs4Size: %d\n", |
| - i_ringId, rs4Size); |
| - } |
| - |
| - rc = TOR_SUCCESS; |
| - } |
| - else |
| - { |
| - if (i_dbgl > 0) |
| - { |
| - MY_DBG("ringId=0x%x was found but is empty\n", |
| - i_ringId); |
| - } |
| - |
| - rc = TOR_RING_IS_EMPTY; |
| - } |
| - |
| - if (i_dbgl > 0) |
| - { |
| - MY_DBG("Details for chiplet ring index=%d: \n" |
| - " Full offset to chiplet section = 0x%08x \n" |
| - " Full offset to RS4 header = 0x%08x \n" |
| - " RS4 ring size = 0x%08x \n", |
| - iRing, cpltOffset, ringOffset, rs4Size); |
| - } |
| - |
| - return rc; |
| + rs4Size = be16toh( ((CompressedScanData*) |
| + ((uint8_t*)io_ringSection + ringOffset))->iv_size ); |
| |
| - } |
| - else if (i_ringRequest == PUT_SINGLE_RING) |
| - { |
| - if (ringOffset) |
| - { |
| - MY_ERR("Ring container is already present in image\n"); |
| - MY_ERR(" Ring section addr: 0x%016lx (First 8B: 0x%016lx)\n", |
| - (uintptr_t)i_ringSection, |
| - be64toh(*((uint64_t*)i_ringSection))); |
| - MY_ERR(" cpltOffset=0x%08x, torSlotNum=0x%x, TOR offset=0x%04x\n", |
| - cpltOffset, torSlotNum, ringOffset); |
| - return TOR_RING_IS_POPULATED; |
| - } |
| - |
| - // Special [mis]use of io_rs4Ring and io_ringBufSize: |
| - // Put location of chiplet's CMN or INST section into rs4Ring |
| - memcpy(io_rs4Ring, &cpltOffset, sizeof(cpltOffset)); |
| - // Put location of ringOffset slot into ringBufSize |
| - io_ringBufSize = cpltOffset + (torSlotNum * sizeof(ringOffset)); |
| - |
| - return TOR_SUCCESS; |
| - } |
| - else |
| + if (io_ringBufSize < rs4Size) |
| + { |
| + if (i_dbgl > 0) |
| { |
| - MY_ERR("Ring request (i_ringRequest=%d) is not supported\n", i_ringRequest); |
| - return TOR_INVALID_RING_REQUEST; |
| + MY_DBG("io_ringBufSize(=%u) is less than rs4Size(=%u).\n", |
| + io_ringBufSize, rs4Size); |
| } |
| + |
| + io_ringBufSize = rs4Size; |
| + return TOR_BUFFER_TOO_SMALL; |
| + } |
| + |
| + // Produce return parms |
| + memcpy( io_rs4Ring, |
| + (void*)((uint8_t*)io_ringSection + ringOffset), |
| + rs4Size ); |
| + io_ringBufSize = rs4Size; |
| + |
| + if (i_dbgl > 0) |
| + { |
| + MY_DBG("Found a ring: ringId=0x%x and rs4Size=%u\n", |
| + i_ringId, rs4Size); |
| } |
| |
| - torSlotNum++; // Next TOR ring slot |
| + rc = TOR_SUCCESS; |
| + } |
| + else |
| + { |
| + rc = TOR_RING_IS_EMPTY; |
| } |
| + |
| + return rc; |
| + |
| + } |
| + else if (i_ringRequest == PUT_SINGLE_RING) |
| + { |
| + // We can not overwrite an existing ring |
| + if (ringOffset) |
| + { |
| + MY_ERR("Ring container is already present in image\n"); |
| + MY_ERR(" Ring section addr: 0x%016lx (First 8B: 0x%016lx)\n", |
| + (uintptr_t)io_ringSection, |
| + be64toh(*((uint64_t*)io_ringSection))); |
| + MY_ERR(" cpltOffset=0x%08x, torSlotNum=0x%x, ringOffset=0x%04x\n", |
| + cpltOffset, torSlotNum, ringOffset); |
| + return TOR_RING_IS_POPULATED; |
| + } |
| + |
| + // Check we can fit the ring |
| + ringSectionSize = be32toh(torHeader->size); |
| + rs4Size = be16toh( ((CompressedScanData*)io_rs4Ring)->iv_size ); |
| + |
| + if ( (ringSectionSize + rs4Size) > i_maxRingSectionSize ) |
| + { |
| + MY_ERR("ERROR: _tor_access_ring() : Appending the ring would overflow" |
| + " the max ring section size:\n" |
| + " Current ringSectionSize: %d\n" |
| + " Size of ring to be added: %d\n" |
| + " Max ringSection Size: %d\n", |
| + ringSectionSize, rs4Size, i_maxRingSectionSize); |
| + return TOR_BUFFER_TOO_SMALL; |
| + } |
| + |
| + // Then calculate the TOR ring offset value and put it into the TOR ring |
| + // slot. But first, check that the offset value can be contained within |
| + // the 2B of the TOR ring slot. |
| + // - Note that TOR offset value to the ring is wrt to ringSection origin |
| + if ( ringSectionSize <= MAX_TOR_RING_OFFSET ) |
| + { |
| + ringOffset16 = htobe16(ringSectionSize); |
| + memcpy( (uint8_t*)io_ringSection + ringOffsetSlot, |
| + &ringOffset16, |
| + sizeof(ringOffset16) ); |
| + } |
| + else |
| + { |
| + MY_ERR("Code bug: Ring offset (=0x%x) exceeds MAX_TOR_RING_OFFSET (=0x%x)\n", |
| + ringSectionSize, MAX_TOR_RING_OFFSET); |
| + return TOR_OFFSET_TOO_BIG; |
| + } |
| + |
| + // Finally, append the ring to the end of ringSection. |
| + memcpy( (uint8_t*)io_ringSection + ringSectionSize, |
| + (uint8_t*)io_rs4Ring, |
| + rs4Size ); |
| + |
| + // Update the ring section size in the TOR header |
| + torHeader->size = htobe32(ringSectionSize + rs4Size); |
| + |
| + return TOR_SUCCESS; |
| + } |
| + else |
| + { |
| + MY_ERR("Ring request (i_ringRequest=%d) is not supported\n", i_ringRequest); |
| + return TOR_INVALID_RING_REQUEST; |
| } |
| + |
| } |
| else |
| { |
| @@ -296,31 +310,22 @@ int get_ring_from_ring_section( void* i_ringSection, // Ring section |
| |
| return rc; |
| |
| -} // End of get_ring_from_ring_section() |
| +} // End of _tor_access_ring() |
| |
| |
| |
| ////////////////////////////////////////////////////////////////////////////////////////// |
| -/// TOR ACCESS RING API |
| +/// [internal] TOR Header Check function |
| ////////////////////////////////////////////////////////////////////////////////////////// |
| -int tor_access_ring( void* i_ringSection, // Ring section ptr |
| - RingId_t i_ringId, // Ring ID |
| - uint8_t i_ddLevel, // DD level |
| - uint8_t& io_instanceId, // Instance ID |
| - RingRequest_t i_ringRequest, // {GET,PUT}_SINGLE_RING |
| - void* io_rs4Ring, // IO RS4 ring buffer (caller mgd) |
| - uint32_t& io_ringBufSize, // Query, rs4Size, or max buf size |
| - uint32_t i_dbgl ) |
| +int _tor_header_check( void* i_ringSection, // Ring section ptr |
| + RingId_t i_ringId, // Ring ID |
| + uint8_t i_ddLevel, // DD level |
| + uint32_t i_dbgl ) |
| { |
| int rc = TOR_SUCCESS; |
| uint32_t torMagic; |
| TorHeader_t* torHeader; |
| |
| - if (i_dbgl > 1) |
| - { |
| - MY_DBG("Entering tor_access_ring()...\n"); |
| - } |
| - |
| torHeader = (TorHeader_t*)i_ringSection; |
| torMagic = be32toh(torHeader->magic); |
| |
| @@ -384,10 +389,10 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr |
| torHeader->version != TOR_VERSION || |
| torHeader->rtVersion > RING_TABLE_VERSION_HWIMG ) |
| { |
| - MY_ERR("TOR header check failure:\n" |
| - " magic: 0x%08x (!= TOR_MAGIC: 0x%08x)\n" |
| - " version: %u (!= TOR_VERSION: %u)\n" |
| - " rtVersion: %u (> RING_TABLE_VERSION_HWIMG: %u)\n" |
| + MY_ERR("ERROR: TOR header check failure:\n" |
| + " magic: 0x%08x (TOR_MAGIC: 0x%08x)\n" |
| + " version: %u (TOR_VERSION: %u)\n" |
| + " rtVersion: %u (RING_TABLE_VERSION_HWIMG: %u)\n" |
| " size: %d\n", |
| torMagic, TOR_MAGIC, |
| torHeader->version, TOR_VERSION, |
| @@ -400,75 +405,58 @@ int tor_access_ring( void* i_ringSection, // Ring section ptr |
| if ( i_ddLevel != torHeader->ddLevel && |
| i_ddLevel != UNDEFINED_DD_LEVEL ) |
| { |
| - MY_ERR("Requested DD level (=0x%x) doesn't match TOR header DD level (=0x%x) nor" |
| - " UNDEFINED_DD_LEVEL (=0x%x)\n", |
| + MY_ERR("ERROR: Requested DD level (=0x%x) doesn't match TOR header DD level (=0x%x)" |
| + " nor UNDEFINED_DD_LEVEL (=0x%x)\n", |
| i_ddLevel, torHeader->ddLevel, UNDEFINED_DD_LEVEL); |
| return TOR_DD_LEVEL_NOT_FOUND; |
| } |
| |
| - rc = get_ring_from_ring_section( i_ringSection, |
| - i_ringId, |
| - io_instanceId, |
| - i_ringRequest, |
| - io_rs4Ring, |
| - io_ringBufSize, |
| - i_dbgl ); |
| - |
| - // Explanation to the "list" of RCs that we exclude from tracing out: |
| - // TOR_RING_IS_EMPTY: Normal scenario (will occur frequently). |
| - // TOR_RING_HAS_NO_TOR_SLOT: Will be caused a lot by ipl_image_tool, but is an error if |
| - // called by any other user. |
| - // TOR_INVALID_CHIPLET_TYPE: Also somewhat normal scenario since the caller should, |
| - // in princple, be able to mindlessly request a ringId without |
| - // having to figure out first if that ringId belongs to a chiplet |
| - // that is valid for the context. But really this is a gray area. |
| - // For now, we omit to trace out as we will hit this rc condition |
| - // in both ipl_image_tool and ipl_customize (RT_QME phase). |
| - if (rc) |
| - { |
| - if ( rc != TOR_RING_IS_EMPTY && |
| - rc != TOR_RING_HAS_NO_TOR_SLOT && |
| - rc != TOR_INVALID_CHIPLET_TYPE ) |
| - { |
| - MY_ERR("ERROR : tor_access_ring() : get_ring_from_ring_section() failed w/rc=" |
| - "0x%08x\n", rc); |
| - } |
| - |
| - return rc; |
| - } |
| - |
| return rc; |
| -} // End of tor_access_ring() |
| +} // End of _tor_header_check() |
| |
| |
| |
| ///////////////////////////////////////////////////////////////////////////////////// |
| -// TOR GET SINGLE RING API |
| +// TOR Get Single Ring API |
| ///////////////////////////////////////////////////////////////////////////////////// |
| int tor_get_single_ring ( void* i_ringSection, // Ring section ptr |
| uint8_t i_ddLevel, // DD level |
| RingId_t i_ringId, // Ring ID |
| - uint8_t i_instanceId, // Instance ID |
| + uint8_t i_chipletId, // Chiplet ID (ignored for Common rings) |
| void* io_rs4Ring, // IO RS4 ring buffer (caller mgd) |
| uint32_t& io_ringBufSize, // Query, rs4Size, or max buf size |
| uint32_t i_dbgl ) |
| { |
| + int rc = TOR_SUCCESS; |
| |
| - int rc = TOR_SUCCESS; |
| + rc = _tor_header_check( i_ringSection, |
| + i_ringId, |
| + i_ddLevel, |
| + i_dbgl ); |
| |
| - rc = tor_access_ring( i_ringSection, |
| - i_ringId, |
| - i_ddLevel, |
| - i_instanceId, |
| - GET_SINGLE_RING, |
| - io_rs4Ring, |
| - io_ringBufSize, |
| - i_dbgl ); |
| + if (rc) |
| + { |
| + MY_ERR("ERROR: tor_get_single_ring() : _tor_header_check() failed w/rc=0x%08x\n", rc); |
| + return rc; |
| + } |
| + |
| + rc = _tor_access_ring( i_ringSection, |
| + 0, // Not used. Only used when appending a ring. |
| + i_ringId, |
| + i_chipletId, |
| + GET_SINGLE_RING, |
| + io_rs4Ring, |
| + io_ringBufSize, |
| + i_dbgl ); |
| |
| // Explanation to the "list" of RCs that we exclude from tracing out: |
| // TOR_RING_IS_EMPTY: Normal scenario (will occur frequently). |
| // TOR_HOLE_RING_ID: Normal scenario when rings are removed from the ring list |
| // and leaves behind a "hole". |
| + // TOR_RING_HAS_NO_TOR_SLOT: Will be caused a lot by ipl_image_tool, but is an error if |
| + // called by any other user. |
| + // TOR_INVALID_CHIPLET_ID: Not necessarily an error as a user may be sweeping through a |
| + // worst case range to "get all I can get". |
| // TOR_INVALID_CHIPLET_TYPE: Also somewhat normal scenario since the caller should, |
| // in princple, be able to mindlessly request a ringId without |
| // having to figure out first if that ringId belongs to a chiplet |
| @@ -479,104 +467,82 @@ int tor_get_single_ring ( void* i_ringSection, // Ring section ptr |
| { |
| if ( rc != TOR_RING_IS_EMPTY && |
| rc != TOR_HOLE_RING_ID && |
| + rc != TOR_RING_HAS_NO_TOR_SLOT && |
| + rc != TOR_INVALID_CHIPLET_ID && |
| rc != TOR_INVALID_CHIPLET_TYPE ) |
| { |
| - MY_ERR("ERROR : tor_get_single_ring() : tor_access_ring() failed w/rc=0x%08x\n", rc); |
| + MY_ERR("ERROR: tor_get_single_ring() : _tor_access_ring() failed w/rc=0x%08x\n", rc); |
| } |
| |
| return rc; |
| } |
| |
| return rc; |
| -} |
| +} // End of tor_get_single_ring() |
| |
| |
| |
| //////////////////////////////////////////////////////////////////////////////////////// |
| -// TOR APPEND RING API |
| +// TOR Append Ring API |
| /////////////////////////////////////////////////////////////////////////////////////// |
| -int tor_append_ring( void* i_ringSection, // Ring section ptr |
| - uint32_t& io_ringSectionSize, // In: Exact size of ring section. |
| - // Out: Updated size of ring section. |
| - RingId_t i_ringId, // Ring ID |
| - uint8_t i_instanceId, // Instance ID |
| - void* i_rs4Ring, // RS4 ring |
| - uint32_t i_dbgl ) // Debug option |
| +int tor_append_ring( void* io_ringSection, // Ring section ptr |
| + uint32_t i_maxRingSectionSize, // Max ringSection size |
| + RingId_t i_ringId, // Ring ID to append |
| + uint8_t i_chipletId, // Chiplet ID (ignored for Common rings) |
| + void* i_rs4Ring, // RS4 ring container |
| + uint32_t i_dbgl ) // Debug option |
| { |
| - int rc = TOR_SUCCESS; |
| - uint32_t buf = 0; |
| - uint32_t* cpltSection = &buf; |
| - uint32_t rs4Size = 0; |
| - TorRingOffset_t ringOffset16; |
| - uint32_t torOffsetSlot; |
| + int rc = TOR_SUCCESS; |
| + uint32_t ringBufSize; |
| |
| - if ( ringid_has_derivs( ((TorHeader_t*)i_ringSection)->chipId, i_ringId) ) |
| + rc = _tor_header_check( io_ringSection, |
| + i_ringId, |
| + UNDEFINED_DD_LEVEL, |
| + i_dbgl ); |
| + |
| + if (rc) |
| { |
| - MY_DBG("Can't append ringId=0x%x since it has derivatives\n", |
| + MY_ERR("ERROR: tor_append_ring() : _tor_header_check() failed w/rc=0x%08x\n", rc); |
| + return rc; |
| + } |
| + |
| + if ( ringid_has_derivs( ((TorHeader_t*)io_ringSection)->chipId, i_ringId) ) |
| + { |
| + MY_DBG("Can't append ringId=0x%x since it has derivatives. Only the" |
| + " derivative rings, e.g. *_bucket, can be appended.\n", |
| i_ringId); |
| return TOR_RING_HAS_DERIVS; |
| } |
| |
| - rc = tor_access_ring( i_ringSection, |
| - i_ringId, |
| - UNDEFINED_DD_LEVEL, |
| - i_instanceId, |
| - PUT_SINGLE_RING, |
| - (void*)cpltSection, // On return, contains offset (wrt ringSection) of |
| - // chiplet section's common or instance section |
| - torOffsetSlot, // On return, contains offset (wrt ringSection) of |
| - // TOR offset slot |
| - i_dbgl ); |
| + rc = _tor_access_ring( io_ringSection, |
| + i_maxRingSectionSize, |
| + i_ringId, |
| + i_chipletId, |
| + PUT_SINGLE_RING, |
| + i_rs4Ring, |
| + ringBufSize, // Not used here |
| + i_dbgl ); |
| |
| // Explanation to the "list" of RCs that we exclude from tracing out: |
| - // TOR_INVALID_CHIPLET_TYPE: Not really a normal scenario though it's not unreasonable that |
| - // the caller should be able to mindlessly request a ringId without |
| - // having to figure out first if that ringId belongs to a chiplet |
| - // that is valid for the context. But really this is a gray area. |
| + // TOR_INVALID_CHIPLET_TYPE: Not really a normal scenario though it's possible a |
| + // caller will mindlessly request a ringId to be appended without |
| + // knowing ahead of the call if the ringId belongs to the chiplet |
| + // indicated in ringSection's torMagic. But this is a gray area. |
| // For now, we omit to trace out as we will hit this rc condition |
| // in ipl_customize (RT_QME phase). |
| if (rc) |
| { |
| if (rc != TOR_INVALID_CHIPLET_TYPE) |
| { |
| - MY_ERR("ERROR : tor_append_ring() : tor_access_ring() failed w/rc=0x%08x\n", rc); |
| + MY_ERR("ERROR: tor_append_ring() : _tor_access_ring() failed w/rc=0x%08x for" |
| + " ringId=0x%x\n", |
| + rc, i_ringId); |
| } |
| |
| return rc; |
| } |
| |
| - // Explanation to the following: |
| - // tor_append_ring() appends a ring to the end of the ringSection. The offset value to |
| - // that ring is wrt the beginning of the chiplet's Common/Instance TOR ring offset slot |
| - // section. Below we calculate the offset value and put it into the TOR slot. But first, |
| - // check that the offset value can be contained within the 2B of the TOR slot. |
| - if ( (io_ringSectionSize - *cpltSection) <= MAX_TOR_RING_OFFSET ) |
| - { |
| - ringOffset16 = htobe16(io_ringSectionSize - *cpltSection); |
| - memcpy( (uint8_t*)i_ringSection + torOffsetSlot, |
| - &ringOffset16, sizeof(ringOffset16) ); |
| - } |
| - else |
| - { |
| - MY_ERR("Code bug: TOR ring offset (=0x%x) exceeds MAX_TOR_RING_OFFSET (=0x%x)\n", |
| - io_ringSectionSize - *cpltSection, MAX_TOR_RING_OFFSET); |
| - return TOR_OFFSET_TOO_BIG; |
| - } |
| - |
| - // Now append the ring to the end of ringSection. |
| - rs4Size = be16toh( ((CompressedScanData*)i_rs4Ring)->iv_size ); |
| - memcpy( (uint8_t*)i_ringSection + io_ringSectionSize, |
| - (uint8_t*)i_rs4Ring, |
| - rs4Size ); |
| - |
| - // Update the ringSectionSize |
| - io_ringSectionSize += rs4Size; |
| - |
| - // Update the size in the TOR header |
| - TorHeader_t* torHeader = (TorHeader_t*)i_ringSection; |
| - torHeader->size = htobe32(be32toh(torHeader->size) + rs4Size); |
| - |
| - return TOR_SUCCESS; |
| + return rc; |
| } |
| |
| |
| @@ -601,7 +567,6 @@ int tor_skeleton_generation( void* io_ringSection, |
| uint32_t chipletBlockStart; // Offset from ringSection to start of chiplet offset block |
| uint32_t sizeChipletBlock; // Size of the chiplet offset block |
| uint32_t sizeRingSlots; // Size of ring offset block |
| - uint32_t chipletRingsStart; // Offset from ringSection to start of chiplet's ring slots |
| RingId_t numRings = UNDEFINED_RING_ID; // Number of a chiplet common or instance rings |
| uint8_t numInstances = 0; // Number of chiplet instances (=1 for COMMON case) |
| uint32_t numRingSlots = 0; // Number of ring slots in chiplet's Cmn/Inst ring section |
| @@ -687,18 +652,15 @@ int tor_skeleton_generation( void* io_ringSection, |
| continue; |
| } |
| |
| - // Save start position of current chiplet's Common or Instance ring section |
| - // (relative to start of ringSection) |
| - chipletRingsStart = ringSectionSize; |
| - |
| // Update the current chiplet block's offset to the Common or Instance ring section |
| + // - Note that the TOR chiplet offsets are assumed to be wrt to ringSection origin |
| if (bInstCase) |
| { |
| - torChipletBlock->instOffset = htobe32(chipletRingsStart - chipletBlockStart); |
| + torChipletBlock->instOffset = htobe16(ringSectionSize); |
| } |
| else |
| { |
| - torChipletBlock->cmnOffset = htobe32(chipletRingsStart - chipletBlockStart); |
| + torChipletBlock->cmnOffset = htobe16(ringSectionSize); |
| } |
| |
| // Determine total number of Instance or Common rings (TOR slots) which involves: |
| @@ -716,8 +678,8 @@ int tor_skeleton_generation( void* io_ringSection, |
| |
| // Allocate and init offset slots for chiplet Cmn/Inst rings |
| // Use 4B alignment of the TOR ring slots for debugging visualization. |
| - sizeRingSlots = myByteAlign(4, numRingSlots * sizeof(TorRingOffset_t)); |
| - memset( (uint8_t*)io_ringSection + chipletRingsStart, |
| + sizeRingSlots = myByteAlign(4, numRingSlots * sizeof(TorOffset_t)); |
| + memset( (uint8_t*)io_ringSection + ringSectionSize, |
| 0, |
| sizeRingSlots ); |
| |
| @@ -769,7 +731,7 @@ int dyn_append_ring( void* io_ringSection, // Ring section ptr |
| } |
| else |
| { |
| - MY_ERR("ERROR in dyn_append_ring: ringSectionSize(=%d) + rs4Size(=%d)" |
| + MY_ERR("ERROR in dyn_append_ring: ringSectionSize(=%u) + rs4Size(=%u)" |
| " would exceed maxRingSectionSize(=%d)\n", |
| ringSectionSize, rs4Size, i_maxRingSectionSize); |
| return TOR_BUFFER_TOO_SMALL; |
| diff --git a/src/import/chips/p10/utils/imageProcs/p10_tor.H b/src/import/chips/p10/utils/imageProcs/p10_tor.H |
| index 929945e..093b39a 100644 |
| --- a/src/import/chips/p10/utils/imageProcs/p10_tor.H |
| +++ b/src/import/chips/p10/utils/imageProcs/p10_tor.H |
| @@ -5,7 +5,7 @@ |
| /* */ |
| /* OpenPOWER HostBoot Project */ |
| /* */ |
| -/* Contributors Listed Below - COPYRIGHT 2016,2019 */ |
| +/* Contributors Listed Below - COPYRIGHT 2016,2020 */ |
| /* [+] International Business Machines Corp. */ |
| /* */ |
| /* */ |
| @@ -56,66 +56,25 @@ int tor_skeleton_generation( void* io_ringSection, |
| uint32_t dbgl = 0 ); |
| |
| |
| -/// Access and perform various functions on a TOR ring section. |
| -/// |
| -/// \param[in] i_ringSection A pointer to the TOR ring section. |
| -/// |
| -/// \param[in] i_ringId A enum to indicate unique ID for the ring |
| -/// |
| -/// \param[in] i_ddLevel A variable to indicate chip DD level. TOR API |
| -/// uses DD level to extract single ring or block of rings from hw_image |
| -/// |
| -/// \param[in/out] io_instanceId A variable to indicate chiplet instance ID. |
| -/// It returns Chiplet instance ID while doing get single ring operation |
| -/// |
| -/// \param[in] i_ringRequest A enum to indicate type of operation performed |
| -/// by TOR API Option: |
| -/// GET_SINGLE_RING indicates to extract single ring container. |
| -/// PUT_SINGLE_RING indicates to extract ring absolute memory addres for |
| -/// ringTorSlot location |
| -/// |
| -/// \param[in/out] io_rs4Ring A void pointer to pointer. Returns data |
| -/// which copied during extract ring operation and returns tor absolute address |
| -/// where offset slot is located while PUT_SINGLE_RING call. |
| -/// Note:- Caller's responsibility for free() to avoid memory leak |
| -/// |
| -/// \param[in/out] io_ringBufSize A variable. Returns size of data copied |
| -/// into io_rs4Ring and returns absolute offset where ring RS4 starts in |
| -/// TOR during PUT_SINGLE_RING call |
| -/// |
| -/// \param[in] i_debug Debug level [0:3]. |
| -/// |
| -/// \retval 0 Success |
| -/// |
| -/// \retval non-0 See \ref TOR API RETURN errors |
| -int tor_access_ring( void* i_ringSection, |
| - RingId_t i_ringId, |
| - uint8_t i_ddLevel, |
| - uint8_t& io_instanceId, // Chiplet instance ID |
| - RingRequest_t i_ringRequest, // {GET,PUT}_SINGLE_RING |
| - void* io_rs4Ring, |
| - uint32_t& io_ringBufSize, // Query, rs4Size, or max buf size |
| - uint32_t i_dbgl = 0 ); |
| - |
| - |
| /// Retrieve a single RS4 ring from a TOR ring section |
| /// |
| -/// \param[in] i_ringSection A pointer to the ring section. |
| +/// \param[in] i_ringSection A pointer to the ring section. |
| /// |
| -/// \param[in] i_ringId A enum to indicate unique ID for the ring |
| +/// \param[in] i_ringId A enum to indicate unique ID for the ring |
| /// |
| -/// \param[in] i_ddLevel A variable to indicate chip DD level. TOR API |
| -/// uses DD level to verify validity of ring section. |
| +/// \param[in] i_ddLevel A variable to indicate chip DD level. TOR API uses |
| +/// DD level to verify validity of ring section. |
| /// |
| -/// \param[in] io_instanceId A variable to indicate chiplet instance ID |
| +/// \param[in] i_chipletId A variable to indicate chiplet instance ID. Only |
| +/// used for Instance rings. Ignored for Common rings. |
| /// |
| -/// \param[in/out] io_rs4Ring A void pointer. Contains copied ring. |
| -/// Note that it's caller's responsibility to manage buffer. |
| +/// \param[in/out] io_rs4Ring A void pointer. Contains copied ring. Note that |
| +/// it's caller's responsibility to manage buffer. |
| /// |
| -/// \param[in/out] io_ringBufSize A variable that returns size of ring |
| -/// copied into io_rs4Ring |
| +/// \param[in/out] io_ringBufSize A variable that returns size of ring |
| +/// copied into io_rs4Ring |
| /// |
| -/// \param[in] i_debug Debug level [0:3]. |
| +/// \param[in] i_debug Debug level [0:3]. |
| /// |
| /// \retval 0 Success |
| /// |
| @@ -123,37 +82,36 @@ int tor_access_ring( void* i_ringSection, |
| int tor_get_single_ring ( void* i_ringSection, |
| uint8_t i_ddLevel, |
| RingId_t i_ringId, |
| - uint8_t i_instanceId, |
| + uint8_t i_chipletId, |
| void* io_rs4Ring, |
| uint32_t& io_ringBufSize, // Query, rs4Size, or max buf size |
| uint32_t i_dbgl = 0 ); |
| |
| |
| -/// Append a single RS4 ring to the end of a TOR ring section. |
| +/// Append an RS4 ring to the end of a TOR ring section. |
| /// |
| -/// \param[in] i_ringSection A pointer to a TOR ring section. |
| -/// Note that caller manages this buffer. |
| +/// \param[in/out] io_ringSection A pointer to a TOR ring section. |
| +/// Note that caller manages this buffer. |
| /// |
| -/// \param[in/out] io_ringSectionSize In: Exact size of i_ringSection. |
| -/// Out: Updated size of i_ringSection. |
| +/// \param[in] i_maxRingSectionSize Max ring section size |
| /// |
| -/// \param[in] i_ringId The unique enum ID for the ring |
| +/// \param[in] i_ringId The enum ID for the ring in rs4Ring to be appended |
| /// |
| -/// \param[in] i_instanceId The chiplet instance ID. Only needed for |
| -/// Instance rings. Ignored for Common rings. |
| +/// \param[in] i_chipletId The chiplet instance ID. Only needed for Instance rings. |
| +/// Ignored for Common rings. |
| /// |
| -/// \param[in] i_rs4Ring Pointer to the RS4 compressed ring container. |
| +/// \param[in] i_rs4Ring Pointer to the RS4 compressed ring container. |
| /// |
| -/// \param[in] i_debug Debug level [0:3]. |
| +/// \param[in] i_debug Debug level [0:3]. |
| /// |
| /// \retval 0 Success |
| /// |
| -/// \retval non-0 See \ref TOR API RETURN errors |
| +/// \retval non-0 See \ref TOR API RETURN errors |
| /// |
| -int tor_append_ring( void* i_ringSection, |
| - uint32_t& io_ringSectionSize, |
| +int tor_append_ring( void* io_ringSection, |
| + uint32_t i_maxRingSectionSize, |
| RingId_t i_ringId, |
| - uint8_t i_instanceId, |
| + uint8_t i_chipletId, |
| void* i_rs4Ring, // Ptr to the RS4 ring container |
| uint32_t i_dbgl = 0 ); |
| |
| @@ -201,7 +159,8 @@ int dyn_get_ring( void* i_ringSection, |
| |
| /// Append a single RS4 ring to the end of a Dynamic ring section (non-TOR layout). |
| /// |
| -/// \param[in] i_ringSection A pointer to the Dynamic ring section. |
| +/// \param[in] io_ringSection A pointer to the Dynamic ring section. |
| +/// Note that caller manages buffer. |
| /// |
| /// \param[in] i_maxRingSectionSize Max size of i_ringSection. |
| /// |
| -- |
| 1.8.2.2 |
| |