diff options
author | Prem Shanker Jha <premjha2@in.ibm.com> | 2016-07-21 11:02:29 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-11-15 23:41:46 -0500 |
commit | 3c4936bcc01d3060aa5656cea03970bbb00f6371 (patch) | |
tree | 2f43813a0e2c2f92bad2fb8fa9d51e1779852af6 /src/import/chips/p9/procedures/hwp | |
parent | 65c1a0cb72f7daa85a7e5d37dce6c27cbf2042d7 (diff) | |
download | talos-hostboot-3c4936bcc01d3060aa5656cea03970bbb00f6371.tar.gz talos-hostboot-3c4936bcc01d3060aa5656cea03970bbb00f6371.zip |
PM: Customization of CME and SGPE rings in HOMER.
- Extracts rings from hardware image and VPD and stashes in to
a temp buffer using HWP p9_xip_customize. Subsequently, using
TOR API creates a fresh and leaner layout of scan rings in
HOMER.
- Implements a debug infrastructure to verify the scan ring layout
in HOMER.
- Implemented scan ring overrides for core common and cache common
rings.
- Introduces size check for various sections of HOMER.
Change-Id: I8d7785f632823c31077bd4f320c453129be4ef0c
RTC:157954
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/27697
Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Michael S. Floyd <mfloyd@us.ibm.com>
Dev-Ready: Michael S. Floyd <mfloyd@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/27699
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp')
7 files changed, 2466 insertions, 773 deletions
diff --git a/src/import/chips/p9/procedures/hwp/lib/p9_hcode_image_defines.H b/src/import/chips/p9/procedures/hwp/lib/p9_hcode_image_defines.H index e3e6567f9..e856471a4 100644 --- a/src/import/chips/p9/procedures/hwp/lib/p9_hcode_image_defines.H +++ b/src/import/chips/p9/procedures/hwp/lib/p9_hcode_image_defines.H @@ -94,12 +94,10 @@ HCD_HDR_UINT32( quadCmnRingOccOffset, 0); HCD_HDR_UINT32( quadSpecRingOccOffset, 0); HCD_HDR_UINT32( quadCmnScomOccOffset, 0); HCD_HDR_PAD(512); -//HCD_HDR_PAD(QPMR_HEADER_SIZE); #ifdef __ASSEMBLER__ .endm #else } __attribute__((packed, aligned(512))) QpmrHeaderLayout_t; -//} __attribute__((packed, aligned(QPMR_HEADER_SIZE))) QpmrHeaderLayout_t; #endif // @todo Get around the above hardcoding. @@ -138,12 +136,10 @@ HCD_HDR_UINT32( coreSpecRingLength, 0); HCD_HDR_UINT32( coreScomOffset, 0); HCD_HDR_UINT32( coreScomLength, 0); HCD_HDR_PAD(256); -//HCD_HDR_PAD(CPMR_HEADER_SIZE); #ifdef __ASSEMBLER__ .endm #else } __attribute__((packed, aligned(256))) cpmrHeader_t; -//} __attribute__((packed, aligned(CPMR_HEADER_SIZE))) cpmrHeader_t; #endif // @todo Get around the above hardcoding. @@ -180,9 +176,11 @@ HCD_HDR_UINT64(g_sgpe_reserve_flags, 0); HCD_HDR_UINT32(g_sgpe_cmn_ring_occ_offset, 0); HCD_HDR_UINT32(g_sgpe_cmn_ring_ovrd_occ_offset, 0); HCD_HDR_UINT32(g_sgpe_spec_ring_occ_offset, 0); -HCD_HDR_UINT32(g_sgpe_spec_ring_ovrd_occ_offset, 0); HCD_HDR_UINT32(g_sgpe_cmn_scom_offset, 0); -HCD_HDR_UINT32(g_sgpe_reserve3, 0); +HCD_HDR_UINT32(g_sgpe_cmn_scom_mem_offset, 0); +HCD_HDR_UINT32(g_sgpe_cmn_scom_length, 0); +HCD_HDR_UINT32(g_sgpe_24x7_offset, 0); +HCD_HDR_UINT32(g_sgpe_24x7_length, 0); HCD_HDR_PAD(IMG_HDR_ALIGN_SIZE); #ifdef __ASSEMBLER__ .endm @@ -299,6 +297,7 @@ enum MAX_CME_PER_CHIP = 12, MAX_CACHE_CHIPLETS = 6, CACH0_CHIPLET_ID = 0x10, + MAX_CORES_PER_EX = 2, CORE0_CHIPLET_ID = 0x20, PAD_OPCODE = 0x00000200, //ATTN Opcode PPE_RESERVE_AREA = 0x200, @@ -316,11 +315,9 @@ enum //** Hcode SGPE_INT_VECT = 384, - //SGPE_IMG_HEADER = 64, SGPE_IMG_HEADER = sizeof(sgpeHeader_t), SGPE_DBG_PTR_AREA_SIZE = 64, - //SGPE_HCODE_SIZE = 32 * ONE_KB, // FIXME RTC 155018 Revisit after Hcode optimization - SGPE_HCODE_SIZE = 45 * ONE_KB, // @todo RTC 158543 Reallocate space + SGPE_HCODE_SIZE = (45 * ONE_KB) + HALF_KB, // @todo RTC 158543 Reallocate space SGPE_EXE_SIZE = (SGPE_HCODE_SIZE - ( SGPE_INT_VECT + SGPE_IMG_HEADER + PK_DBG_PTR_AREA_SIZE )), @@ -328,17 +325,17 @@ enum SGPE_ALLOCATED_SIZE = SGPE_HCODE_SIZE, // @todo RTC 158543 Reallocate space (collapse??) //** Scan - //SGPE_COMMON_RING = 13 * ONE_KB, // Common rings (10KB) + Override rings(3KB) SGPE_COMMON_RING_SIZE = 13 * ONE_KB, // 400B * 9 rings * 3 types (base, RL, CC) SGPE_OVERRIDE_RING_SIZE = 3 * ONE_KB, // 300B * 9 rings CACHE_INST_SPECIFIC_SIZE = (3 * ONE_KB) + HALF_KB, // per cache, 1KB/ring x 5 rings/cache - CACHE_SPECIFIC_RING_SIZE = MAX_CACHE_CHIPLETS * CACHE_INST_SPECIFIC_SIZE, SGPE_INSTRUMENTATION_SIZE = 2 * ONE_KB, + MAX_CACHE_CHIPLET = 6, + MAX_QUAD_SPEC_RING_SIZE = 19 * ONE_KB, //** SCOM NUM_CACHE_SCOM_REGS = 47 + 1, // 16 L2 repr, 16 L3 repr, 15 non-repr, 1 NULL - CACHE_SCOM_RESTORE_SIZE = MAX_CACHE_CHIPLETS * NUM_CACHE_SCOM_REGS * SCOM_ENTRY_SIZE, + CACHE_SCOM_RESTORE_SIZE = 6 * ONE_KB, //4488B rounded to 6KB CACHE_SCOM_START = 128 * ONE_KB, // HOMER offset from QPMR @@ -363,35 +360,28 @@ enum //** SCOM CORE_SCOM_START = (256 * ONE_KB), CORE_SCOM_RESTORE_SIZE = SCOM_ENTRY_SIZE * 16, // (15 registers + 1 NULL) per core - CORE_SCOM_RES_SIZE = CORE_SCOM_RESTORE_SIZE * MAX_CORES_PER_CHIP, CME_SCOM_AREA = CORE_SCOM_RESTORE_SIZE * 2, // 2 cores SCOM_AREA_PER_CME = HALF_KB, // 256(ea ) * 2( CORES PER CME) (???) //** Hcode + CORE_SCOM_PER_CME = 512, + CORE_SCOM_RES_SIZE = MAX_CME_PER_CHIP * SCOM_AREA_PER_CME, CME_INT_VECTOR_SIZE = 384, CME_IMG_HEADER_SIZE = 64, CPMR_CME_HCODE_OFFSET = (CORE_SCOM_START + CORE_SCOM_RES_SIZE), - CME_HCODE_SIZE = (28 * ONE_KB) + HALF_KB, + CME_HCODE_SIZE = (30 * ONE_KB), //FIXME RTC 159737 Needs review before merge of P-State //** Scan - CORE_COMMON_RING_SIZE = 3 * ONE_KB, // common ring( 2KB) + common overrides (1KB) - CORE_SPECIFIC_RING = 2 * ONE_KB, // per core + CORE_COMMON_RING_SIZE = 1 * ONE_KB, // common ring( 2KB) + common overrides (1KB) + MAX_SIZE_CME_INST_RING = 1 * ONE_KB, CORE_OVERRIDE_RING = 1 * ONE_KB, // common for all cores QUAD_PSTATE_SIZE = HALF_KB, // common for all cores CME_INSTRUMENTATION_SIZE = HALF_KB, // per CME INSTRUMENTATION_COUNTERS = HALF_KB, // (???) - - CORE_RESERVE_SIZE = CORE_SCOM_START - - ( CORE_RESTORE_SIZE + - CME_HCODE_SIZE + - CORE_COMMON_RING_SIZE + - QUAD_PSTATE_SIZE ), - CME_SRAM_HCODE_OFFSET = 0x00, //(???) - CME_REGION_START = (CORE_SCOM_START + CORE_SCOM_RES_SIZE), CME_INST_SPEC_RING_START = 300 * ONE_KB, - RESERVE_CME_RING_AREA = ( CME_INST_SPEC_RING_START - - (CME_REGION_START + + CME_REGION_START = (CORE_SCOM_START + CORE_SCOM_RES_SIZE), + RESERVE_CME_RING_AREA = ( CME_INST_SPEC_RING_START - ( CME_REGION_START + CME_HCODE_SIZE + CORE_COMMON_RING_SIZE + QUAD_PSTATE_SIZE)), @@ -407,10 +397,13 @@ enum PGPE_HCODE_SIZE = 30 * ONE_KB, PGPE_PARAM_BLOCK_SIZE = 8 * ONE_KB, //Global and OCC PPB PSTATE_OUTPUT_TABLE = 8 * ONE_KB, - IGNORE_CHIPLET_INSTANCE = 0xFF, PGPE_MAX_AREA_SIZE = 48 * ONE_KB, // @todo RTC 158543 Reallocate space + IGNORE_CHIPLET_INSTANCE = 0xFF, + + //RING LAYOUT + RING_ALIGN_BOUNDARY = 0x08, }; /** @@ -446,9 +439,159 @@ enum ImgBldRetCode_t BUILD_FAIL_PGPE_BL2 = 25, BUILD_FAIL_PGPE_HCODE = 26, BUILD_FAIL_OVERRIDE = 27, + BUILD_SEC_SIZE_OVERFLOW = 28, + BUILD_FAIL_INVALID_SECTN = 29, + BUILD_FAIL_RING_EXTRACTN = 30, }; /** + * @brief models layout of core common rings in HOMER. + * @note Ring list below is primarily for debug. + */ +typedef struct +{ + uint16_t ecFuncRing; + uint16_t ecGptrRing; + uint16_t ecTimeRing; + uint16_t ecModeRing; +} CoreCmnRingsList_t; + +typedef struct +{ + CoreCmnRingsList_t cmnRings; + uint8_t cmnScanRingPayload[CORE_COMMON_RING_SIZE - sizeof(CoreCmnRingsList_t)]; +} CoreCmnRingsCme_t; + +typedef union +{ + CoreCmnRingsCme_t cmnRingIndex; + uint8_t cmnScanRings[CORE_COMMON_RING_SIZE]; +} CoreCmnRingLayout_t; + +/** + * @brief models layout of core instance specific ring in HOMER. + * @note Ring list below is primarily for debug. + */ +typedef struct +{ + uint16_t ecRepr0; + uint16_t ecRepr1; + uint8_t ecReserve[4]; +} CoreSpecRingList_t; +typedef struct +{ + CoreSpecRingList_t coreSpecRings; + uint8_t instanceRingPayLoad[ MAX_SIZE_CME_INST_RING - sizeof(CoreSpecRingList_t)]; +} CoreSpecRingCme_t; + +typedef union +{ + CoreSpecRingCme_t instRingIndex; + uint8_t instScanRings[ MAX_SIZE_CME_INST_RING ]; +} CoreSpecRingLayout_t; + +/** + * @brief models layout of quad common rings in HOMER. + * @note this layout resides in QPMR region and is consumed by SGPE. + * Ring list below is primarily for debug. + */ + +typedef struct +{ + uint16_t eqFureRing; + uint16_t eqGptrRing; + uint16_t eqTimeRing; + uint16_t eqModeRing; + uint16_t exL3FureRing; + uint16_t exL3GptrRing; + uint16_t exL3TimeRing; + uint16_t exL2ModeRing; + uint16_t exL2FureRing; + uint16_t exL2GptrRing; + uint16_t exL2TimeRing; + uint16_t exL3RefrFureRing; + uint16_t exL3RefrGptrRing; + uint16_t eqAnaFuncRing; + uint16_t eqAnaGptrRing; + uint16_t eqDpllFuncRing; + uint16_t eqDpllGptrRing; + uint16_t eqDpllModeRing; + uint16_t eqAnaBndyRingBucket0; + uint16_t eqAnaBndyRingBucket1; + uint16_t eqAnaBndyRingBucket2; + uint16_t eqAnaBndyRingBucket3; + uint16_t eqAnaBndyRingBucket4; + uint16_t eqAnaBndyRingBucket5; + uint16_t eqAnaBndyRingBucket6; + uint16_t eqAnaBndyRingBucket7; + uint16_t eqAnaBndyRingBucket8; + uint16_t eqAnaBndyRingBucket9; + uint16_t eqAnaBndyRingBucket10; + uint16_t eqAnaBndyRingBucket11; + uint16_t eqAnaBndyRingBucket12; + uint16_t eqAnaBndyRingBucket13; + uint16_t eqAnaBndyRingBucket14; + uint16_t eqAnaBndyRingBucket15; + uint16_t eqAnaBndyRingBucket16; + uint16_t eqAnaBndyRingBucket17; + uint16_t eqAnaBndyRingBucket18; + uint16_t eqAnaBndyRingBucket19; + uint16_t eqAnaBndyRingBucket20; + uint16_t eqAnaBndyRingBucket21; + uint16_t eqAnaBndyRingBucket22; + uint16_t eqAnaBndyRingBucket23; + uint16_t eqAnaBndyRingBucket24; + uint16_t eqAnaBndyRingBucket25; + uint16_t eqAnaBndyRingl3dccBucket26; + uint16_t eqAnaModeRing; + uint16_t ex_l2_fure_1; + uint16_t ex_l3_fure_1; +} QuadCmnRingsList_t; + +typedef struct +{ + QuadCmnRingsList_t quadCmnRingList; + uint8_t cmnRingPayLoad[SGPE_COMMON_RING_SIZE - sizeof(QuadCmnRingsList_t)]; +} QuadCmnRingsSgpe_t; + +typedef union +{ + QuadCmnRingsSgpe_t cmnRingIndex; + uint8_t cmnScanRings[SGPE_COMMON_RING_SIZE]; +} CmnRingLayoutSgpe_t; + +/** + * @brief models layout of quad/ex instance specific ring in HOMER. + * @note this layout resides in QPMR region and is consumed by SGPE. + * Ring list below is primarily for debug. + */ +typedef struct +{ + uint16_t eqRepr0Index; + uint16_t ex0L3ReprIndex; + uint16_t ex1L3ReprIndex; + uint16_t ex0L2ReprIndex; + uint16_t ex1L2ReprIndex; + uint16_t ex0L3RefrReprIndex; + uint16_t ex1L3RefrReprIndex; + uint16_t ex0L3RefrTimeIndex; + uint16_t ex1L3RefrTimeIndex; + uint8_t eqReserve[6]; +} QuadSpecRingsList_t; + +typedef struct +{ + QuadSpecRingsList_t quadSpecRings[MAX_CACHE_CHIPLET]; + uint8_t quadSpecRingPayLoad[ MAX_QUAD_SPEC_RING_SIZE - (MAX_CACHE_CHIPLET * sizeof(QuadSpecRingsList_t))]; +} QuadSpecRing_t; + +typedef union +{ + QuadSpecRing_t instRingIndex; + uint8_t instScanRings[ MAX_QUAD_SPEC_RING_SIZE ]; +} InstRingLayoutSgpe_t; + +/** * @brief models image section of SGPE in HOMER. */ typedef struct @@ -460,10 +603,8 @@ typedef struct uint8_t imgHeader[sizeof(sgpeHeader_t)]; uint8_t debugPtrs[PK_DBG_PTR_AREA_SIZE]; uint8_t hcode[SGPE_EXE_SIZE]; - uint8_t commonRings[SGPE_COMMON_RING_SIZE]; - uint8_t cacheSpecificRing[CACHE_SPECIFIC_RING_SIZE]; - uint8_t overrideRings[SGPE_OVERRIDE_RING_SIZE]; - uint8_t cacheScomRestore[CACHE_SCOM_RESTORE_SIZE]; + CmnRingLayoutSgpe_t quadCmnRingArea; + InstRingLayoutSgpe_t quadSpecRingArea; } SgpeLayout_t; typedef union CPMRSelfRestoreLayout @@ -501,12 +642,12 @@ typedef union CmeHcodeLayout typedef struct { - SelfRestoreLayout_t selfRestoreRegion; - CmeHcodeLayout_t cmeBin; - uint8_t commonRings[CORE_COMMON_RING_SIZE]; - uint8_t quadPstateArea[QUAD_PSTATE_SIZE]; - uint8_t resvRingArea[RESERVE_CME_RING_AREA]; - uint8_t instSpecificRing[MAX_CORES_PER_CHIP * CORE_SPECIFIC_RING]; + SelfRestoreLayout_t selfRestoreRegion; + CmeHcodeLayout_t cmeBin; + CoreCmnRingLayout_t coreCmnRingArea; + uint8_t quadPstateArea[QUAD_PSTATE_SIZE]; + uint8_t resvRingArea[RESERVE_CME_RING_AREA]; + CoreSpecRingLayout_t coreSpecRingArea[MAX_CME_PER_CHIP]; } CPMRLayout_t; /** diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.C b/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.C index 99bbaf5d7..4645df8f1 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.C +++ b/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.C @@ -36,29 +36,327 @@ //-------------------------------------------------------------------------- // Includes //-------------------------------------------------------------------------- +#include <map> #include <p9_hcode_image_build.H> #include "p9_xip_image.h" #include "p9_hcode_image_defines.H" #include "p9_stop_util.H" -#include "p9_ringId.H" +#include "p9_scan_ring_util.H" #include "p9_tor.H" #include "p9_misc_scom_addresses.H" +#include <p9_infrastruct_help.H> +#include <p9_xip_customize.H> +#include <p9_ringId.H> +#ifdef __CRONUS_VER + #include <string> +#endif using namespace stopImageSection; + extern "C" { + /** + * @brief aligns DATA_SIZE to 8B. + * @param TEMP_LEN temp storage + * @param DATA_SIZE size to be aligned. Aligned size is saved in same variable. + */ +#define ALIGN_DWORD(TEMP_LEN, DATA_SIZE) \ + {TEMP_LEN = (DATA_SIZE % RING_ALIGN_BOUNDARY); \ + if( TEMP_LEN ) \ + { \ + (DATA_SIZE = DATA_SIZE + (RING_ALIGN_BOUNDARY - TEMP_LEN));\ + } \ + } \ + + /** + * @brief aligns start of scan ring to 8B boundary. + * @param RING_REGION_BASE start location of scan ring region in HOMER. + * @param RING_LOC start of scan ring. + */ +#define ALGIN_RING_LOC(RING_REGION_BASE, RING_LOC) \ + { \ + uint8_t tempDiff = \ + (uint8_t *) RING_LOC - (uint8_t *) RING_REGION_BASE; \ + if(tempDiff) \ + { RING_LOC = RING_LOC + 8 - (tempDiff % 8) ; \ + } \ + } namespace p9_hcodeImageBuild { - enum E_PLAT_ID + /** + * @brief some misc local constants + */ + enum + { + ENABLE_ALL_CORE = 0x000FFFF, + RISK_LEVEL = 0x01, + QUAD_COMMON_RING_INDEX_SIZE = sizeof(QuadCmnRingsList_t), + QUAD_SPEC_RING_INDEX_SIZE = ((sizeof(QuadSpecRingsList_t)) / sizeof(uint16_t)), + QUAD_SPEC_RING_INDEX_LEN = (QUAD_SPEC_RING_INDEX_SIZE * 2 * MAX_CACHE_CHIPLET), + CORE_COMMON_RING_INDEX_SIZE = sizeof(CoreCmnRingsList_t), + CORE_SPEC_RING_INDEX_SIZE = sizeof(CoreSpecRingList_t), + RING_START_TO_RS4_OFFSET = 8, + }; + + /** + * @brief struct used to manipulate scan ring in HOMER. + */ + struct RingBufData + { + void* iv_pRingBuffer; + uint32_t iv_ringBufSize; + void* iv_pWorkBuf1; + uint32_t iv_sizeWorkBuf1; + void* iv_pWorkBuf2; + uint32_t iv_sizeWorkBuf2; + + RingBufData( void* i_pRingBuf1, const uint32_t i_ringSize, + void* i_pWorkBuf1, const uint32_t i_sizeWorkBuf1, + void* i_pWorkBuf2, const uint32_t i_sizeWorkBuf2 ) : + iv_pRingBuffer( i_pRingBuf1), + iv_ringBufSize(i_ringSize), + iv_pWorkBuf1( i_pWorkBuf1 ), + iv_sizeWorkBuf1( i_sizeWorkBuf1 ), + iv_pWorkBuf2( i_pWorkBuf2 ), + iv_sizeWorkBuf2( i_sizeWorkBuf2 ) + + {} + + RingBufData(): + iv_pRingBuffer( NULL ), + iv_ringBufSize( 0 ), + iv_pWorkBuf1( NULL ), + iv_sizeWorkBuf1( 0 ), + iv_pWorkBuf2( NULL ), + iv_sizeWorkBuf2( 0 ) + { } + }; + + /** + * @brief models an section in HOMER. + */ + struct ImgSec + { + PlatId iv_plat; + uint8_t iv_secId; + ImgSec( PlatId i_plat, uint8_t i_secId ): + iv_plat( i_plat ), + iv_secId( i_secId ) + { } + ImgSec(): iv_plat (PLAT_SELF), iv_secId (0 ) + { } + }; + + /** + * @brief operator < overloading for ImgSec. + */ + bool operator < ( const ImgSec& i_lhs, const ImgSec& i_rhs ) + { + if( i_lhs.iv_plat == i_rhs.iv_plat ) + { + return i_lhs.iv_secId < i_rhs.iv_secId; + } + else + { + return i_lhs.iv_plat < i_rhs.iv_plat; + } + } + + /** + * @brief operator == overloading for ImgSec. + */ + bool operator == ( const ImgSec& i_lhs, const ImgSec& i_rhs ) + { + bool equal = false; + + if( i_lhs.iv_plat == i_rhs.iv_plat ) + { + if( i_lhs.iv_secId == i_rhs.iv_secId ) + { + equal = true; + } + } + + return equal; + } + + /** + * @brief compares size of a given image's section with maximum allowed size. + */ + class ImgSizeBank + { + public: + ImgSizeBank(); + ~ImgSizeBank() {}; + uint32_t isSizeGood( PlatId i_plat, uint8_t i_sec, uint32_t i_size ); + + private: + std::map< ImgSec, uint32_t> iv_secSize; + + }; + + /** + * @brief constructor + */ + ImgSizeBank::ImgSizeBank() + { + iv_secSize[ImgSec(PLAT_SELF, P9_XIP_SECTION_RESTORE_SELF)] = SELF_REST_SIZE; + iv_secSize[ImgSec(PLAT_SELF, P9_XIP_SECTION_RESTORE_CPMR)] = CPMR_HEADER_SIZE; + iv_secSize[ImgSec(PLAT_SGPE, P9_XIP_SECTION_SGPE_QPMR)] = HALF_KB; + iv_secSize[ImgSec(PLAT_SGPE, P9_XIP_SECTION_SGPE_LVL1_BL)] = SGPE_LVL_1_BOOT_LOAD_SIZE; + iv_secSize[ImgSec(PLAT_SGPE, P9_XIP_SECTION_SGPE_LVL2_BL)] = SGPE_LVL_2_BOOT_LOAD_SIZE; + iv_secSize[ImgSec(PLAT_SGPE, P9_XIP_SECTION_SGPE_HCODE)] = SGPE_HCODE_SIZE; + + iv_secSize[ImgSec(PLAT_CME, P9_XIP_SECTION_CME_HCODE)] = CME_HCODE_SIZE; + + //iv_secSize[ImgSec(PLAT_PGPE, P9_XIP_SECTION_PGPE_PPPMR)] = HALF_KB; + iv_secSize[ImgSec(PLAT_PGPE, P9_XIP_SECTION_PGPE_LVL1_BL)] = PGPE_LVL_1_BOOT_LOAD_SIZE ; + iv_secSize[ImgSec(PLAT_PGPE, P9_XIP_SECTION_PGPE_LVL2_BL)] = PGPE_LVL_2_BOOT_LOAD_SIZE ; + iv_secSize[ImgSec(PLAT_PGPE, P9_XIP_SECTION_PGPE_HCODE)] = PGPE_HCODE_SIZE; + } + + /** + * @brief verifies actual section size against max size allowed. + * @param i_plat platform associated with image section. + * @param i_sec image section. + * @param i_size actual image section size. + * @return zero if size within limit else max size allowed. + */ + uint32_t ImgSizeBank::isSizeGood( PlatId i_plat, uint8_t i_sec, uint32_t i_size ) { - PLAT_SELF = 0, - PLAT_CME = 1, - PLAT_SGPE = 2, - PLAT_PGPE = 3, + uint32_t size = -1; + ImgSec key( i_plat, i_sec ); + std::map< ImgSec, uint32_t>::iterator it; + + for( it = iv_secSize.begin(); it != iv_secSize.end(); it++ ) + { + if( it->first == key ) + { + size = 0; + + if( it->second < i_size ) + { + size = it->second; + } + + break; + } + } + + FAPI_DBG(" Sec Size 0x%08x", size); + return size; + } + + /** + * @brief models an Ex pair. + */ + struct ExpairId + { + uint16_t iv_evenExId; + uint16_t iv_oddExId; + /** + * @brief constructor + */ + ExpairId( uint32_t i_evenExId, uint32_t i_oddExId ): + iv_evenExId( i_evenExId ), + iv_oddExId( i_oddExId ) + { } + + /** + * @brief constructor + */ + ExpairId() { }; + }; + + /** + * @brief a map to resolve Ex chiplet Id associated with all six quads in P9. + */ + class ExIdMap + { + public: + ExIdMap(); + ~ExIdMap() {}; + uint32_t getInstanceId( uint32_t i_eqId, uint32_t i_ringOrder ); + private: + std::map<uint32_t, ExpairId> iv_idMap; }; /** + * @brief constructor + */ + ExIdMap::ExIdMap() + { + ExpairId exPairIdMap[6] = { { 0x10, 0x11}, + { 0x12, 0x13 }, + { 0x14, 0x15 }, + { 0x16, 0x17 }, + { 0x18, 0x19 }, + { 0x20, 0x21 } + }; + + for( uint32_t eqCnt = 0; eqCnt < MAX_CACHE_CHIPLET; eqCnt++ ) + { + iv_idMap[CACH0_CHIPLET_ID + eqCnt] = exPairIdMap[eqCnt]; + } + } + + //------------------------------------------------------------------------- + + /** + * @brief returns ex chiplet ID associated with a scan ring and EQ id. + * @param i_eqId chiplet id for a given quad. + * @param i_ringOrder serial number associated with a scan ring in HOMER. + * @return chiplet Id associated with a scan ring. + */ + uint32_t ExIdMap::getInstanceId( uint32_t i_eqId, uint32_t i_ringOrder ) + { + uint32_t exChipletId = 0xFFFFFFFF; + std::map<uint32_t, ExpairId>::iterator itChipId = iv_idMap.find( i_eqId ); + + do + { + if ( itChipId == iv_idMap.end() ) + { + break; + } + else + { + switch( i_ringOrder ) + { + case 0: + exChipletId = i_eqId; + break; + + case 1: + case 3: + case 5: + case 7: + exChipletId = itChipId->second.iv_evenExId; + break; + + case 2: + case 4: + case 6: + case 8: + exChipletId = itChipId->second.iv_oddExId; + break; + + default: + break; + } + } + + } + while(0); + + FAPI_DBG("Resolved Ex Id 0x%02x", exChipletId ); + return exChipletId; + } + + //------------------------------------------------------------------------- + + /** * @brief validates arguments passed for hcode image build * @param refer to p9_hcode_image_build arguments * @return fapi2 return code @@ -66,7 +364,7 @@ extern "C" fapi2::ReturnCode validateInputArguments( void* const i_pImageIn, void* i_pImageOut, SysPhase_t i_phase, ImageType_t i_imgType, void* i_pBuf1, uint32_t i_bufSize1, void* i_pBuf2, - uint32_t i_bufSize2 ) + uint32_t i_bufSize2, void* i_pBuf3, uint32_t i_bufSize3 ) { uint32_t l_rc = IMG_BUILD_SUCCESS; uint32_t hwImagSize = 0; @@ -100,10 +398,11 @@ extern "C" .set_TEMP_BUF_PTR( i_pBuf1 ), "Invalid temp buffer1 passed for hcode image build" ); - FAPI_ASSERT( (( i_bufSize1 != 0 ) && ( i_bufSize2 != 0 )), + FAPI_ASSERT( (( i_bufSize1 != 0 ) && ( i_bufSize2 != 0 ) && ( i_bufSize3 != 0 )), fapi2::HCODE_TEMP_BUF_SIZE() .set_TEMP_BUF1_SIZE( i_bufSize1 ) - .set_TEMP_BUF2_SIZE( i_bufSize2 ), + .set_TEMP_BUF2_SIZE( i_bufSize2 ) + .set_TEMP_BUF3_SIZE( i_bufSize3 ), "Invalid work buffer size " ); FAPI_ASSERT( ( i_pBuf2 != NULL ), @@ -111,6 +410,11 @@ extern "C" .set_TEMP_BUF_PTR( i_pBuf2 ), "Invalid temp buffer2 passed for hcode image build" ); + FAPI_ASSERT( ( i_pBuf3 != NULL ), + fapi2::HCODE_INVALID_TEMP_BUF() + .set_TEMP_BUF_PTR( i_pBuf3 ), + "Invalid temp buffer3 passed for hcode image build" ); + FAPI_ASSERT( ( i_imgType.isBuildValid() ), fapi2::HCODE_INVALID_IMG_TYPE(), "Invalid temp buffer passed for hcode image build" ); @@ -120,7 +424,7 @@ extern "C" return fapi2::current_err; } -//------------------------------------------------------------------------------ + //------------------------------------------------------------------------------ /** * @brief Copies section of hardware image to HOMER * @param i_destPtr a location in HOMER @@ -130,11 +434,12 @@ extern "C" * @param o_ppeSection contains section details. * @return IMG_BUILD_SUCCESS if successful, error code otherwise. */ - uint32_t copySectionToHomer( uint8_t* i_destPtr, uint8_t* i_srcPtr, uint8_t i_secId, E_PLAT_ID i_platId , + uint32_t copySectionToHomer( uint8_t* i_destPtr, uint8_t* i_srcPtr, uint8_t i_secId, PlatId i_platId , P9XipSection& o_ppeSection ) { FAPI_INF("> copySectionToHomer"); uint32_t retCode = IMG_BUILD_SUCCESS; + ImgSizeBank sizebank; do { @@ -145,6 +450,7 @@ extern "C" if( rcTemp ) { FAPI_ERR("Failed to get section 0x%08x of Plat 0x%08x", i_secId, i_platId ); + retCode = BUILD_FAIL_INVALID_SECTN; break; } @@ -154,6 +460,18 @@ extern "C" o_ppeSection.iv_offset, o_ppeSection.iv_size, i_secId); + + rcTemp = sizebank.isSizeGood( i_platId, i_secId, o_ppeSection.iv_size ); + + if ( rcTemp ) + { + FAPI_ERR("??????????Size Exceeds the permissible limit???????" ); + FAPI_ERR("Max Allowed 0x%08x (%08d) Actual Size 0x%08x (%08d)", + rcTemp, rcTemp, o_ppeSection.iv_size, o_ppeSection.iv_size); + retCode = BUILD_SEC_SIZE_OVERFLOW; + break; + } + memcpy( i_destPtr, i_srcPtr + o_ppeSection.iv_offset, o_ppeSection.iv_size ); } while(0); @@ -189,15 +507,6 @@ extern "C" pCpmrHdr->coreScomOffset = SWIZZLE_4_BYTE((CORE_SCOM_START >> CME_BLK_SIZE_SHIFT)); pCpmrHdr->coreScomLength = SWIZZLE_4_BYTE((CORE_SCOM_RES_SIZE >> CME_BLK_SIZE_SHIFT)); - FAPI_INF("CPMR CME Hcode"); - FAPI_INF(" CME Offset = 0x%08X, Header value 0x%08X (Real offset / 32)", - SWIZZLE_4_BYTE(pCpmrHdr->cmeImgOffset) * 32, - SWIZZLE_4_BYTE(pCpmrHdr->cmeImgOffset)); - FAPI_INF(" CME Size = 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->cmeImgLength)); - FAPI_INF(" CME SCOM Offset = 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->coreScomOffset) ); - FAPI_INF(" CME SCOM Length = 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->coreScomLength) ); - - FAPI_INF("< updateCpmrHeaderCME"); } @@ -213,44 +522,46 @@ extern "C" (cpmrHeader_t*) & (i_pChipHomer->cpmrRegion.selfRestoreRegion.CPMR_SR.elements.CPMRHeader); cmeHeader_t* pCmeHdr = NULL; pCmeHdr = (cmeHeader_t*) & i_pChipHomer->cpmrRegion.cmeBin.elements.imgHeader; - pCpmrHdr->cmeCommonRingOffset = (uint8_t*) i_pChipHomer->cpmrRegion.commonRings - - (uint8_t*) &i_pChipHomer->cpmrRegion; - pCpmrHdr->cmeCommonRingOffset = SWIZZLE_4_BYTE(pCpmrHdr->cmeCommonRingOffset); - - pCpmrHdr->coreSpecRingOffset = SWIZZLE_4_BYTE(CME_INST_SPEC_RING_START); - pCpmrHdr->coreSpecRingLength = pCmeHdr->g_cme_max_spec_ring_length; // already swizzled - - //FIXME Populating headers fields with max possible values for now. This is to keep things in line with CME - //bootloader design. CME bootloader doesn't expect a hole within image layout how ever due to current design of - //hcode image build there are holes between various section of image say common and instance ring. - pCpmrHdr->cmeImgLength = SWIZZLE_4_BYTE( CME_HCODE_SIZE ); - pCpmrHdr->cmeCommonRingLength = SWIZZLE_4_BYTE( CORE_COMMON_RING_SIZE ); - pCmeHdr->g_cme_common_ring_length = pCpmrHdr->cmeCommonRingLength; - pCpmrHdr->cmePstateLength = 0; // This needs to be fixed later. - pCpmrHdr->cmePstateOffset = SWIZZLE_4_BYTE(i_pChipHomer->cpmrRegion.quadPstateArea - - (uint8_t*)&i_pChipHomer->cpmrRegion); - - FAPI_INF("CPMR CME Scan Rings"); - FAPI_INF(" CME Cmn Ring Offset = 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->cmeCommonRingOffset) ); - FAPI_INF(" CME Cmn Ring Length = 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->cmeCommonRingLength) ); - FAPI_INF(" CME Spc Ring Offset = 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->coreSpecRingOffset) ); - FAPI_INF(" CME Spc Ring Length = 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->coreSpecRingLength) ); - - FAPI_INF("CME Header Scan Rings"); + //FIXME Populating select fields with MAX possible size to assist booting. Will revisit it later + pCpmrHdr->cmeCommonRingOffset = (uint8_t*) &i_pChipHomer->cpmrRegion.coreCmnRingArea.cmnRingIndex - + (uint8_t*) &i_pChipHomer->cpmrRegion; + pCpmrHdr->cmeCommonRingOffset = SWIZZLE_4_BYTE(pCpmrHdr->cmeCommonRingOffset); + pCpmrHdr->cmeImgLength = SWIZZLE_4_BYTE( CME_HCODE_SIZE ); + pCpmrHdr->cmeCommonRingLength = pCmeHdr->g_cme_common_ring_length; + pCpmrHdr->coreSpecRingOffset = SWIZZLE_4_BYTE(CME_INST_SPEC_RING_START); + pCpmrHdr->coreSpecRingLength = pCmeHdr->g_cme_max_spec_ring_length; // already swizzled + pCmeHdr->g_cme_scom_offset = SWIZZLE_4_BYTE(SWIZZLE_4_BYTE(pCmeHdr->g_cme_core_spec_ring_offset) + + SWIZZLE_4_BYTE(pCmeHdr->g_cme_max_spec_ring_length)); + pCmeHdr->g_cme_scom_length = SWIZZLE_4_BYTE(CORE_SCOM_PER_CME); + + FAPI_INF("========================= CME Header Start =================================="); FAPI_INF(" Magic Num = 0x%16lX", SWIZZLE_8_BYTE(pCmeHdr->g_cme_magic_number)); FAPI_INF(" HC Offset = 0x%08X", SWIZZLE_4_BYTE(pCmeHdr->g_cme_hcode_offset)); FAPI_INF(" HC Size = 0x%08X", SWIZZLE_4_BYTE(pCmeHdr->g_cme_hcode_length)); FAPI_INF(" CR Offset = 0x%08X", SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_offset)); FAPI_INF(" CR Size = 0x%08X", SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_length)); - FAPI_INF(" CPMR Phy Add = 0x%016lX", SWIZZLE_8_BYTE(pCmeHdr->g_cme_cpmr_PhyAddr)); + FAPI_INF(" CR Ovrd Offset = 0x%08x", SWIZZLE_4_BYTE(pCmeHdr->g_cme_cmn_ring_ovrd_offset )); + FAPI_INF(" CSR Offset = 0x%08x (Real offset / 32) ", SWIZZLE_4_BYTE(pCmeHdr->g_cme_core_spec_ring_offset)); FAPI_INF(" PS Offset = 0x%08X", SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_region_offset)); FAPI_INF(" PS Size = 0x%08X", SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_region_length)); - FAPI_INF(" SR Offset = 0x%08X, Header value 0x%08X (Real offset / 32)", - SWIZZLE_4_BYTE(pCmeHdr->g_cme_core_spec_ring_offset) * 32, - SWIZZLE_4_BYTE(pCmeHdr->g_cme_core_spec_ring_offset)); - FAPI_INF(" SR Size = 0x%08X, Header value 0x%08X (Real offset / 32)", - SWIZZLE_4_BYTE(pCmeHdr->g_cme_max_spec_ring_length) * 32, - SWIZZLE_4_BYTE(pCmeHdr->g_cme_max_spec_ring_length) ); + FAPI_INF(" CSR Length = 0x%08x (Real length / 32)", SWIZZLE_4_BYTE(pCmeHdr->g_cme_max_spec_ring_length) ); + FAPI_INF(" CPMR Phy Add = 0x%016lX", SWIZZLE_8_BYTE(pCmeHdr->g_cme_cpmr_PhyAddr)); + FAPI_INF(" SCOM Offset = 0x%08X", SWIZZLE_4_BYTE(pCmeHdr->g_cme_scom_offset)); + FAPI_INF(" SCOM Area Len = 0x%08X", SWIZZLE_4_BYTE(pCmeHdr->g_cme_scom_length)); + FAPI_INF("========================= CME Header End =================================="); + + FAPI_INF("==========================CPMR Header==========================================="); + FAPI_INF(" CME HC Offset : 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->cmeImgOffset)); + FAPI_INF(" CME HC Length : 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->cmeImgLength)); + FAPI_INF(" CR Offset : 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->cmeCommonRingOffset)); + FAPI_INF(" CR Length : 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->cmeCommonRingLength)); + FAPI_INF(" PS Offset : 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->cmePstateOffset)); + FAPI_INF(" PS Length : 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->cmePstateLength)); + FAPI_INF(" CSR Offset : 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->coreSpecRingOffset)); + FAPI_INF(" CSR Length : 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->coreSpecRingLength)); + FAPI_INF(" Core SCOM Offset : 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->coreScomOffset)); + FAPI_INF(" Core SCOM Length : 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->coreScomLength )); + FAPI_INF("==================================CPMR Ends====================================="); } @@ -284,7 +595,6 @@ extern "C" FAPI_INF("< updateCpmrHeaderSR"); } - //------------------------------------------------------------------------------ /** * @brief updates various QPMR header region in HOMER. @@ -296,45 +606,48 @@ extern "C" uint32_t rc = IMG_BUILD_SUCCESS; QpmrHeaderLayout_t* pQpmrHdr = ( QpmrHeaderLayout_t*) & (i_pChipHomer->qpmrRegion.sgpeRegion.qpmrHeader); - - //FIXME Populating headers fields with max possible values for now. This is to keep things in line with SGPE - //bootloader design. SGPE bootloader doesn't expect a hole in image layout how ever due to current design of - //hcode image build there are holes between various section of image say common and instance ring. + sgpeHeader_t* pSgpeHdr = (sgpeHeader_t*)& i_pChipHomer->qpmrRegion.sgpeRegion.imgHeader; + memcpy( pQpmrHdr, &io_qpmrHdr, sizeof( QpmrHeaderLayout_t ) ); pQpmrHdr->sgpeImgLength = SWIZZLE_4_BYTE(SGPE_HCODE_SIZE); - pQpmrHdr->quadCommonRingOffset = SWIZZLE_4_BYTE(SGPE_COMMON_RING_SIZE); pQpmrHdr->quadSpecRingLength = SWIZZLE_4_BYTE(CACHE_INST_SPECIFIC_SIZE); - - memcpy( pQpmrHdr, &io_qpmrHdr, sizeof( QpmrHeaderLayout_t ) ); - pQpmrHdr->quadCommonRingOffset = (uint8_t*) i_pChipHomer->qpmrRegion.sgpeRegion.commonRings - - (uint8_t*) &i_pChipHomer->qpmrRegion.sgpeRegion; - - pQpmrHdr->quadCommonRingOffset = SWIZZLE_4_BYTE(pQpmrHdr->quadCommonRingOffset); - - FAPI_INF("QPMR"); - FAPI_INF(" Magic Num = 0x%16lX", SWIZZLE_8_BYTE(pQpmrHdr->magic_number)); - FAPI_INF(" Build Date = 0x%08X", SWIZZLE_4_BYTE(pQpmrHdr->buildDate)); - FAPI_INF(" Version = 0x%08X", SWIZZLE_4_BYTE(pQpmrHdr->buildVersion)); - FAPI_INF(" BC Offset = 0x%08X", SWIZZLE_4_BYTE(pQpmrHdr->bootCopierOffset)); - FAPI_INF(" BL Offset = 0x%08X", SWIZZLE_4_BYTE(pQpmrHdr->bootLoaderOffset)); - FAPI_INF(" BL Size = 0x%08X", SWIZZLE_4_BYTE(pQpmrHdr->bootLoaderLength)); - FAPI_INF(" HC Offset = 0x%08X", SWIZZLE_4_BYTE(pQpmrHdr->sgpeImgOffset)); - FAPI_INF(" HC Size = 0x%08X", SWIZZLE_4_BYTE(pQpmrHdr->sgpeImgLength)); - FAPI_INF(" Cmn Ring Offset = 0x%08x", SWIZZLE_4_BYTE(pQpmrHdr->quadCommonRingOffset) ); - FAPI_INF(" Cmn Ring Length = 0x%08x", SWIZZLE_4_BYTE(pQpmrHdr->quadCommonRingLength) ); - FAPI_INF(" Spc Ring Offset = 0x%08x", SWIZZLE_4_BYTE(pQpmrHdr->quadSpecRingOffset) ); - FAPI_INF(" Spc Ring Length = 0x%08x", SWIZZLE_4_BYTE(pQpmrHdr->quadSpecRingLength) ); - - sgpeHeader_t* pImgHdr = (sgpeHeader_t*)& i_pChipHomer->qpmrRegion.sgpeRegion.imgHeader; - FAPI_INF("SGPE Header"); - FAPI_INF(" Magic Num = 0x%16lX", SWIZZLE_8_BYTE(pImgHdr->g_sgpe_magic_number)); - FAPI_INF(" Reset Addr = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_sgpe_reset_address)); - FAPI_INF(" IVPR Addr = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_sgpe_ivpr_address)); - FAPI_INF(" Build Date = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_sgpe_build_date)); - FAPI_INF(" Version = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_sgpe_build_ver)); - FAPI_INF(" CR OCC Offset = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_sgpe_cmn_ring_occ_offset)); - FAPI_INF(" SR OCC Offset = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_sgpe_spec_ring_occ_offset)); - FAPI_INF(" SCOM Offset = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_sgpe_cmn_scom_offset)); + pQpmrHdr->quadCommonRingLength = SWIZZLE_4_BYTE(SGPE_COMMON_RING_SIZE); + pQpmrHdr->quadCommonRingOffset = (uint8_t*) + &i_pChipHomer->qpmrRegion.sgpeRegion.quadCmnRingArea.cmnRingIndex.quadCmnRingList - + (uint8_t*) &i_pChipHomer->qpmrRegion.sgpeRegion; + pQpmrHdr->quadCommonRingOffset = SWIZZLE_4_BYTE(pQpmrHdr->quadCommonRingOffset); + + //To take care of holes within sections, updating SGPE Image header with MAX section size. + pSgpeHdr->g_sgpe_cmn_ring_occ_offset = pQpmrHdr->sgpeImgLength; + pSgpeHdr->g_sgpe_spec_ring_occ_offset = SWIZZLE_4_BYTE(pSgpeHdr->g_sgpe_cmn_ring_occ_offset) + + SWIZZLE_4_BYTE(pQpmrHdr->quadCommonRingLength); + pSgpeHdr->g_sgpe_spec_ring_occ_offset = SWIZZLE_4_BYTE(pSgpeHdr->g_sgpe_spec_ring_occ_offset); + + FAPI_INF("==============================QPMR=================================="); + FAPI_INF(" Magic Num : 0x%16lX", SWIZZLE_8_BYTE(pQpmrHdr->magic_number)); + FAPI_INF(" Build Date : 0x%08X", SWIZZLE_4_BYTE(pQpmrHdr->buildDate)); + FAPI_INF(" Version : 0x%08X", SWIZZLE_4_BYTE(pQpmrHdr->buildVersion)); + FAPI_INF(" BC Offset : 0x%08X", SWIZZLE_4_BYTE(pQpmrHdr->bootCopierOffset)); + FAPI_INF(" BL Offset : 0x%08X", SWIZZLE_4_BYTE(pQpmrHdr->bootLoaderOffset)); + FAPI_INF(" BL Size : 0x%08X", SWIZZLE_4_BYTE(pQpmrHdr->bootLoaderLength)); + FAPI_INF(" HC Offset : 0x%08X", SWIZZLE_4_BYTE(pQpmrHdr->sgpeImgOffset)); + FAPI_INF(" HC Size : 0x%08X", SWIZZLE_4_BYTE(pQpmrHdr->sgpeImgLength)); + FAPI_DBG(" Cmn Ring Offset : 0x%08x", SWIZZLE_4_BYTE(pQpmrHdr->quadCommonRingOffset) ); + FAPI_DBG(" Cmn Ring Length : 0x%08x", SWIZZLE_4_BYTE(pQpmrHdr->quadCommonRingLength) ); + FAPI_DBG(" Quad Spec Ring Offset : 0x%08x", SWIZZLE_4_BYTE(pQpmrHdr->quadSpecRingOffset) ); + FAPI_DBG(" Quad Spec Ring Length : 0x%08x", SWIZZLE_4_BYTE(pQpmrHdr->quadSpecRingLength) ); + FAPI_INF("==============================QPMR Ends=============================="); + FAPI_INF("===========================SGPE Image Hdr============================="); + FAPI_INF(" Cmn Ring Offset : 0x%08x", SWIZZLE_4_BYTE(pSgpeHdr->g_sgpe_cmn_ring_occ_offset )); + FAPI_INF(" Override Offset : 0x%08x", SWIZZLE_4_BYTE(pSgpeHdr->g_sgpe_cmn_ring_ovrd_occ_offset )); + FAPI_INF(" Flags : 0x%08x", SWIZZLE_4_BYTE(pSgpeHdr->g_sgpe_reserve_flags )); + FAPI_INF(" Quad Spec Ring Offset : 0x%08x", SWIZZLE_4_BYTE(pSgpeHdr->g_sgpe_spec_ring_occ_offset )); + FAPI_INF(" Quad SCOM SRAM Offset : 0x%08x", SWIZZLE_4_BYTE(pSgpeHdr->g_sgpe_cmn_scom_offset)); + FAPI_INF(" Quad SCOM Mem Offset : 0x%08x", SWIZZLE_4_BYTE(pSgpeHdr->g_sgpe_cmn_scom_mem_offset)); + FAPI_INF(" Quad SCOM Mem Length : 0x%08x", SWIZZLE_4_BYTE(pSgpeHdr->g_sgpe_cmn_scom_length )); + FAPI_INF(" 24x7 Offset : 0x%08x", SWIZZLE_4_BYTE(pSgpeHdr->g_sgpe_24x7_offset )); + FAPI_INF(" 24x7 Length : 0x%08x", SWIZZLE_4_BYTE(pSgpeHdr->g_sgpe_cmn_scom_length )); + FAPI_INF("========================SGPE Image Hdr Ends==========================="); return rc; } @@ -357,10 +670,6 @@ extern "C" uint32_t rcTemp = 0; //Let us find XIP Header for SGPE P9XipSection ppeSection; - - FAPI_INF("Size of SGP Hdr 0x%08x", sizeof(sgpeHeader_t)); - FAPI_INF("Size of QPMR Hdr Hdr 0x%08x", sizeof(QpmrHeaderLayout_t)); - FAPI_INF("Size of CPMR Hdr 0x%08x", sizeof(cpmrHeader_t)); uint8_t* pSgpeImg = NULL; if(!i_imgType.sgpeHcodeBuild ) @@ -390,7 +699,7 @@ extern "C" if( rcTemp ) { FAPI_ERR("Failed to copy QPMR Header"); - rcTemp = BUILD_FAIL_SGPE_QPMR; + retCode = BUILD_FAIL_SGPE_QPMR; break; } @@ -407,7 +716,7 @@ extern "C" if( rcTemp ) { FAPI_ERR("Failed to copy Level1 bootloader"); - rcTemp = BUILD_FAIL_SGPE_BL1; + retCode = BUILD_FAIL_SGPE_BL1; break; } @@ -426,7 +735,7 @@ extern "C" if( rcTemp ) { FAPI_ERR("Failed to copy Level2 bootloader"); - rcTemp = BUILD_FAIL_SGPE_BL2; + retCode = BUILD_FAIL_SGPE_BL2; break; } @@ -448,23 +757,24 @@ extern "C" if( rcTemp ) { FAPI_ERR("Failed to copy SGPE hcode"); - rcTemp = BUILD_FAIL_SGPE_HCODE; + retCode = BUILD_FAIL_SGPE_HCODE; break; } o_qpmrHdr.sgpeImgOffset = o_qpmrHdr.bootLoaderOffset + SGPE_LVL_2_BOOT_LOAD_SIZE; - o_qpmrHdr.sgpeImgLength = SWIZZLE_4_BYTE(ppeSection.iv_size); // Endianess already accounted for FAPI_DBG("SGPE Hcode QPMR Offset = 0x%08X, Size = 0x%08X", SWIZZLE_4_BYTE(o_qpmrHdr.sgpeImgOffset), SWIZZLE_4_BYTE(o_qpmrHdr.sgpeImgLength)); - //let us take care of endianess now - o_qpmrHdr.bootCopierOffset = SWIZZLE_4_BYTE(o_qpmrHdr.bootCopierOffset); + o_qpmrHdr.sgpeImgOffset = o_qpmrHdr.bootLoaderOffset + SGPE_LVL_2_BOOT_LOAD_SIZE; + + o_qpmrHdr.sgpeImgLength = SWIZZLE_4_BYTE(SGPE_HCODE_SIZE); o_qpmrHdr.bootLoaderOffset = SWIZZLE_4_BYTE(o_qpmrHdr.bootLoaderOffset); + //let us take care of endianess now. + o_qpmrHdr.bootCopierOffset = SWIZZLE_4_BYTE(o_qpmrHdr.bootCopierOffset); o_qpmrHdr.bootLoaderLength = SWIZZLE_4_BYTE(o_qpmrHdr.bootLoaderLength); o_qpmrHdr.sgpeImgOffset = SWIZZLE_4_BYTE(o_qpmrHdr.sgpeImgOffset); - o_qpmrHdr.sgpeImgLength = SWIZZLE_4_BYTE(ppeSection.iv_size); //FIXME Need to confirm it @@ -480,21 +790,7 @@ extern "C" FAPI_INF(" Build Date = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_sgpe_build_date)); FAPI_INF(" Version = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_sgpe_build_ver)); FAPI_INF(" CR OCC Offset = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_sgpe_cmn_ring_occ_offset)); -// FAPI_INF(" SR OCC Offset = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_sgpe_spec_ring_occ_offset)); -// FAPI_INF(" SCOM Offset = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_sgpe_cmn_scom_offset)); - - //updating SGPE Image header in HOMER - // FIXME Need to handle fields related SCOM OCC offsets - -// uint32_t regionLimit = CACHE_SCOM_RESTORE_SIZE >> 2; -// -// FAPI_DBG("Padding SCOM region starting for 0x%08X bytes", CACHE_SCOM_RESTORE_SIZE); -// uint32_t l_fillPattern = PAD_OPCODE; -// -// for( uint32_t wordCnt = 0; wordCnt < regionLimit; wordCnt++ ) -// { -// memcpy( i_pChipHomer->qpmrRegion.cacheScomRegion, &l_fillPattern, sizeof(uint32_t) ); -// } + } while(0); @@ -648,20 +944,7 @@ extern "C" // Note: Only the *memory* addresses are updated cmeHeader_t* pImgHdr = (cmeHeader_t*) & i_pChipHomer->cpmrRegion.cmeBin.elements.imgHeader; pImgHdr->g_cme_hcode_offset = SWIZZLE_4_BYTE(CME_SRAM_HCODE_OFFSET); - - uint32_t cme_hcode_length = ppeSection.iv_size; - FAPI_INF(" CME Hcode Actual Size = 0x%08X", cme_hcode_length); - - if (cme_hcode_length > CME_HCODE_SIZE) - { - FAPI_ERR("CME Hcode greater than allocated space. Allocated = 0x%08X; Actual Size = 0x%08X", - CME_HCODE_SIZE, cme_hcode_length); - retCode = BUILD_FAIL_CME_HCODE; - break; - } - pImgHdr->g_cme_hcode_length = SWIZZLE_4_BYTE(CME_HCODE_SIZE); - FAPI_INF(" CME Hcode Allocated Size = 0x%08X", CME_HCODE_SIZE); //Populating common ring offset here. So, that other scan ring related field can be updated. pImgHdr->g_cme_common_ring_offset = SWIZZLE_4_BYTE(pImgHdr->g_cme_hcode_offset) + @@ -669,24 +952,13 @@ extern "C" pImgHdr->g_cme_common_ring_offset = SWIZZLE_4_BYTE(pImgHdr->g_cme_common_ring_offset); pImgHdr->g_cme_cpmr_PhyAddr = SWIZZLE_8_BYTE(i_cpmrPhyAdd | CPMR_OFFSET); pImgHdr->g_cme_scom_offset = 0; - pImgHdr->g_cme_scom_length = 0; + pImgHdr->g_cme_scom_length = SWIZZLE_4_BYTE(CORE_SCOM_PER_CME); pImgHdr->g_cme_common_ring_length = 0; pImgHdr->g_cme_pstate_region_offset = 0; pImgHdr->g_cme_pstate_region_length = 0; pImgHdr->g_cme_core_spec_ring_offset = 0; // multiple of 32B blocks pImgHdr->g_cme_max_spec_ring_length = 0; // multiple of 32B blocks - FAPI_INF("CME Header"); - FAPI_INF(" Magic Num = 0x%16lX", SWIZZLE_8_BYTE(pImgHdr->g_cme_magic_number)); - FAPI_INF(" HC Offset = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_cme_hcode_offset)); - FAPI_INF(" HC Size = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_cme_hcode_length)); - FAPI_INF(" CR Offset = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_cme_common_ring_offset)); - FAPI_INF(" CR Size = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_cme_common_ring_length)); - FAPI_INF(" CPMR Phy Add = 0x%016lX", SWIZZLE_8_BYTE(pImgHdr->g_cme_cpmr_PhyAddr)); - FAPI_INF(" PS Offset = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_cme_pstate_region_offset)); - FAPI_INF(" PS Size = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_cme_pstate_region_length)); - FAPI_INF(" SR Offset = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_cme_core_spec_ring_offset)); - FAPI_INF(" SR Size = 0x%08X", SWIZZLE_4_BYTE(pImgHdr->g_cme_max_spec_ring_length)); } } while(0); @@ -737,7 +1009,7 @@ extern "C" if( rcTemp ) { FAPI_ERR("Failed to copy PGPE Level1 bootloader"); - rcTemp = BUILD_FAIL_PGPE_BL1; + retCode = BUILD_FAIL_PGPE_BL1; break; } @@ -748,7 +1020,7 @@ extern "C" if( rcTemp ) { FAPI_ERR("Failed to copy PGPE Level2 bootloader"); - rcTemp = BUILD_FAIL_SGPE_BL2; + retCode = BUILD_FAIL_SGPE_BL2; break; } @@ -758,7 +1030,7 @@ extern "C" if( rcTemp ) { FAPI_ERR("Failed to copy PGPE hcode"); - rcTemp = BUILD_FAIL_PGPE_HCODE; + retCode = BUILD_FAIL_PGPE_HCODE; break; } @@ -771,670 +1043,730 @@ extern "C" return retCode; } -//------------------------------------------------------------------------------ + //------------------------------------------------------------------------------ /** - * @brief copies Base flavor of scan rings - * @param i_pImageIn points to start of hardware image. - * @param i_pChipHomerLoc points to HOMER image. - * @param i_ddLevel dd level of P9 chip. - * @param i_pBuf1 work buffer. - * @param io_copyLength buffer max length[in]/length copied[out]. - * @param i_platId platform associated with scan ring. - * @param i_instanceId chiplet id. - * @param i_ringQuery query for ring presence. - * @return IMG_BUILD_SUCCESS if function succeeds, error code otherwise. + * @brief get a blob of platform rings in a temp buffer. + * @param i_hwImage points to hardware image. + * @param i_procTgt processor target + * @param i_ringData temp data struct */ - uint32_t copyScanRings( - void* const i_pImageIn, - uint8_t* i_pChipHomerLoc, - uint8_t i_ddLevel, - void* i_pBuf1, - uint32_t& io_copyLength, - E_PLAT_ID i_platId, - uint8_t i_instanceId, - bool i_ringQuery = false ) + uint32_t getPpeScanRings( void* const i_pHwImage, + PlatId i_ppeType, + CONST_FAPI2_PROC& i_procTgt, + RingBufData& i_ringData, + ImageType_t i_imgType ) { - FAPI_INF("> copyScanRings") - uint32_t rc = IMG_BUILD_SUCCESS; - uint32_t tempBufLength = io_copyLength; - P9_TOR::RingType ringType = (i_instanceId == IGNORE_CHIPLET_INSTANCE ) ? P9_TOR::COMMON : P9_TOR::INSTANCE; - uint32_t torChipletId = 0; + FAPI_INF(">getPpeScanRings"); + uint32_t retCode = IMG_BUILD_SUCCESS; + uint32_t hwImageSize = 0; do { - //FIXME RTC 163264 Review chiplet id manipulation for common rings. - if( P9_TOR::COMMON == ringType ) - { - torChipletId = ( PLAT_CME == i_platId ) ? CORE0_CHIPLET_ID : CACH0_CHIPLET_ID; - } - else + if(( !i_imgType.cmeCommonRingBuild && !i_imgType.cmeCoreSpecificRingBuild ) || + ( i_imgType.sgpeCommonRingBuild && !i_imgType.sgpeCacheSpecificRingBuild )) { - torChipletId = i_instanceId; + break; } + p9_xip_image_size( i_pHwImage, &hwImageSize ); + P9XipSection ppeSection; - rc = p9_xip_get_section( i_pImageIn, P9_XIP_SECTION_HW_RINGS, &ppeSection ); + retCode = p9_xip_get_section( i_pHwImage, P9_XIP_SECTION_HW_RINGS, &ppeSection ); - if( rc ) + if( retCode ) { - FAPI_ERR("Failed to access common scan rings Plat 0x%08x", i_platId ); - rc = BUILD_FAIL_CMN_RINGS; + FAPI_ERR("Failed to access scan rings for %s", (i_ppeType == PLAT_CME ) ? "CME" : "SGPE" ); + retCode = BUILD_FAIL_RING_EXTRACTN; break; } - if( ppeSection.iv_size == 0 ) + if( 0 == ppeSection.iv_size ) { - FAPI_ERR("Empty .rings section not allowed: <.rings>.iv_size=%d", ppeSection.iv_size); - rc = BUILD_FAIL_CMN_RINGS; + retCode = BUILD_FAIL_RING_EXTRACTN; + FAPI_ERR("Empty .rings section not allowed: <.rings>.iv_size = %d Plat %s", + ppeSection.iv_size, (i_ppeType == PLAT_CME ) ? "CME" : "SGPE" ); break; } - uint8_t* pScanRing = ppeSection.iv_offset + (uint8_t*) (i_pImageIn ); - - if( ( PLAT_CME != i_platId ) && ( PLAT_SGPE != i_platId ) ) + FAPI_DBG("================== Input Buffer Specs ===================="); + FAPI_DBG("Ring section (buf,size)=(0x%016llx,0x%08x)", + (uintptr_t)(i_ringData.iv_pRingBuffer), i_ringData.iv_ringBufSize); + FAPI_DBG("Work buf1 (buf,size)=(0x%016llx,0x%08x)", + (uintptr_t)(i_ringData.iv_pWorkBuf1), i_ringData.iv_sizeWorkBuf1); + FAPI_DBG("Work buf2 (buf,size)=(0x%016llx,0x%08x)", + (uintptr_t)(i_ringData.iv_pWorkBuf2), i_ringData.iv_sizeWorkBuf2); + FAPI_DBG("================== Buffer Specs Ends ===================="); + + uint32_t l_bootMask = ENABLE_ALL_CORE; + fapi2::ReturnCode l_fapiRc = fapi2::FAPI2_RC_SUCCESS; + + FAPI_EXEC_HWP( l_fapiRc, + p9_xip_customize, + i_procTgt, + i_pHwImage, + hwImageSize, + i_ringData.iv_pRingBuffer, + i_ringData.iv_ringBufSize, + (i_ppeType == PLAT_CME) ? SYSPHASE_RT_CME : SYSPHASE_RT_SGPE, + MODEBUILD_IPL, + i_ringData.iv_pWorkBuf1, + i_ringData.iv_sizeWorkBuf1, + i_ringData.iv_pWorkBuf2, + i_ringData.iv_sizeWorkBuf2, + l_bootMask ); + + if( l_fapiRc ) { - FAPI_ERR(" scan ring not supported for platform 0x%d", i_platId ); + retCode = BUILD_FAIL_RING_EXTRACTN; + FAPI_ERR("p9_xip_customize failed to extract rings for %s", + (i_ppeType == PLAT_CME ) ? "CME" : "SGPE" ); break; } + } + while(0); - rc = tor_get_block_of_rings( pScanRing, - i_ddLevel, - ((PLAT_CME == i_platId) ? P9_TOR::CME : P9_TOR::SGPE), - ringType, - BASE, - torChipletId, - &i_pBuf1, - tempBufLength ); + FAPI_INF("<getPpeScanRings " ); + return retCode; + } - FAPI_INF("Ring type 0x%08x instance 0x%08x buf len 0x%08x", ringType, i_instanceId, tempBufLength ); + //------------------------------------------------------------------------------ - if( rc ) + uint32_t layoutCmeScanOverride( Homerlayout_t* i_pHomer, + void* i_pOverride, + const P9FuncModel& i_chipState, + RingBufData& i_ringData, + RingDebugMode_t i_debugMode, + uint32_t i_riskLevel, + ImageType_t i_imgType ) + { + FAPI_INF("> layoutCmeScanOverride" ); + uint32_t rc = IMG_BUILD_SUCCESS; + cmeHeader_t* pCmeHdr = (cmeHeader_t*) &i_pHomer->cpmrRegion.cmeBin.elements.imgHeader; + RingBucket cmeOvrdRings( PLAT_CME, + (uint8_t*)&i_pHomer->cpmrRegion, + i_debugMode ); + + do + { + if( !i_imgType.cmeCommonRingBuild ) { - FAPI_ERR(" common scan ring block not copied rc 0x%08x Length 0x%08x", rc, tempBufLength ); break; } - if( tempBufLength == io_copyLength ) + uint32_t tempRingLength = + SWIZZLE_4_BYTE(pCmeHdr->g_cme_cmn_ring_ovrd_offset) - SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_offset); + + //Start override ring from the actual end of base common rings. Remeber overrides reside within area + //earmarked for common rings + uint8_t* pOverrideStart = + &i_pHomer->cpmrRegion.coreCmnRingArea.cmnScanRings[tempRingLength]; + uint16_t* pScanRingIndex = (uint16_t*)pOverrideStart; + + //get core common rings + uint8_t* pOverrideRingPayload = pOverrideStart + CORE_COMMON_RING_INDEX_SIZE; + uint32_t tempBufSize = 0; + bool overrideNotFound = true; + + for( uint8_t ringIndex = 0; ringIndex < EC::g_ecData.iv_num_common_rings; + ringIndex++ ) { - FAPI_DBG(" Scan ring block size not updated"); - io_copyLength = 0; - rc = BUILD_FAIL_CMN_RINGS; - break; + tempBufSize = i_ringData.iv_sizeWorkBuf2; + + FAPI_DBG("Calling P9_TOR::tor_get_single_ring ring 0x%08x", ringIndex); + rc = tor_get_single_ring( i_pOverride, + P9_XIP_MAGIC_SEEPROM, + i_chipState.getChipLevel(), + cmeOvrdRings.getCommonRingId( ringIndex ), + P9_TOR::SBE, + OVERRIDE, + CORE0_CHIPLET_ID, + &i_ringData.iv_pWorkBuf2, + tempBufSize, + 2 ); + + if( (i_ringData.iv_sizeWorkBuf2 == tempBufSize) || (0 == tempBufSize ) || + ( 0 != rc ) ) + + { + tempBufSize = 0; + continue; + } + + overrideNotFound = false; + ALIGN_DWORD(tempRingLength, tempBufSize) + ALGIN_RING_LOC( pOverrideStart, pOverrideRingPayload ); + + memcpy( pOverrideRingPayload, i_ringData.iv_pWorkBuf2, tempBufSize); + *(pScanRingIndex + ringIndex) = SWIZZLE_2_BYTE((pOverrideRingPayload - pOverrideStart) + RING_START_TO_RS4_OFFSET); + + cmeOvrdRings.setRingOffset(pOverrideRingPayload, cmeOvrdRings.getCommonRingId( ringIndex )); + cmeOvrdRings.setRingSize( cmeOvrdRings.getCommonRingId( ringIndex ), tempBufSize ); + + pOverrideRingPayload = pOverrideRingPayload + tempBufSize; } - if( !i_ringQuery ) + if( overrideNotFound ) { - memcpy( i_pChipHomerLoc, (uint8_t*)i_pBuf1, tempBufLength ); + FAPI_INF("Overrides not found for CME"); + rc = BUILD_FAIL_OVERRIDE; // Not considered an error + break; } - io_copyLength = tempBufLength; + tempRingLength = (pOverrideRingPayload - pOverrideStart ); + + FAPI_DBG( "Override Ring Length 0x%08x", tempRingLength ); - FAPI_DBG("Copied Ring For: %s", (PLAT_CME == i_platId) ? "CME" : "SGPE" ); - FAPI_DBG("Ring Type: %s", - ( i_instanceId == IGNORE_CHIPLET_INSTANCE ) ? "Common" : "Instance"); - FAPI_DBG("Chiplet Id: %d", - ( i_instanceId == IGNORE_CHIPLET_INSTANCE ) ? IGNORE_CHIPLET_INSTANCE : i_instanceId ); - FAPI_DBG("Ring Length: 0x%08x", io_copyLength ); - FAPI_DBG("DD Level: 0x%08x", i_ddLevel ); - FAPI_DBG("Action: %s", i_ringQuery ? "Query" : "Copy", i_ddLevel ); } while(0); - FAPI_INF("< copyScanRings") + cmeOvrdRings.dumpOverrideRings(); + + FAPI_INF("< layoutCmeScanOverride" ); return rc; } - //--------------------------------------------------------------------------- + //------------------------------------------------------------------------------ - /** - * @brief copies override flavor of scan rings. - * @param i_pOverride points to override scanrings. - * @param i_pHomerLoc points to HOMER image. - * @param i_ddLevel dd level of P9 chip. - * @param i_ringType COMMON/INSTANCE - * @param i_pTempBuf Work buffer - * @param io_copyLength Work buffer max length[in]/length copied[out]. - * @param i_platId platform associated with scan ring. - * @param i_instanceId chiplet id. - * @param i_ringQuery query for ring presence. - * @return IMG_BUILD_SUCCESS if function succeeds, error code otherwise. - */ - uint32_t copyScanOverrideRing( void* const i_pOverride, - void* const i_pHomerLoc, - uint8_t const i_ddLevel, - P9_TOR::RingType_t i_ringType, - void* i_pTempBuf, - uint32_t& io_bufLength, - E_PLAT_ID i_platId, - uint8_t i_instanceId, - bool i_queryRing = false ) + uint32_t layoutSgpeScanOverride( Homerlayout_t* i_pHomer, + void* i_pOverride, + const P9FuncModel& i_chipState, + RingBufData& i_ringData, + RingDebugMode_t i_debugMode, + uint32_t i_riskLevel, + QpmrHeaderLayout_t& i_qpmrHdr, + ImageType_t i_imgType ) { + FAPI_INF("> layoutSgpeScanOverride "); uint32_t rc = IMG_BUILD_SUCCESS; + sgpeHeader_t* pSgpeImgHdr = (sgpeHeader_t*)& i_pHomer->qpmrRegion.sgpeRegion.imgHeader; + RingBucket sgpeOvrdRings( PLAT_SGPE, + (uint8_t*)&i_pHomer->qpmrRegion, + i_debugMode ); do { - if( ( PLAT_CME != i_platId ) && ( PLAT_SGPE != i_platId ) ) + if( !i_imgType.sgpeCommonRingBuild ) { - FAPI_ERR(" scan ring not supported for platform 0x%d", i_platId ); break; } - if( !i_pOverride ) - { - FAPI_DBG( "Override not defined"); - io_bufLength = 0; - break; - } + uint32_t commonRingLength = SWIZZLE_4_BYTE(i_qpmrHdr.quadCommonRingLength); - uint32_t tempBufLength = io_bufLength; - uint32_t torChipletId = 0; + //Start override ring from the actual end of base common rings. Remeber overrides reside within area + //earmarked for common rings + uint8_t* pOverrideStart = + &i_pHomer->qpmrRegion.sgpeRegion.quadCmnRingArea.cmnScanRings[commonRingLength]; + uint16_t* pScanRingIndex = (uint16_t*)pOverrideStart; - //FIXME RTC 163264 Review chiplet id manipulation for common rings. - if( P9_TOR::COMMON == i_ringType ) - { - torChipletId = ( PLAT_CME == i_platId ) ? CORE0_CHIPLET_ID : CACH0_CHIPLET_ID; - } - else + //get core common rings + uint8_t* pOvrdRingPayload = pOverrideStart + QUAD_COMMON_RING_INDEX_SIZE; + uint32_t tempRingLength = 0; + uint32_t tempBufSize = 0; + bool overrideNotFound = true; + + for( uint32_t ringIndex = 0; ringIndex < EQ::g_eqData.iv_num_common_rings; + ringIndex++ ) { - torChipletId = i_instanceId; - } + tempBufSize = i_ringData.iv_sizeWorkBuf1; + + FAPI_DBG("Calling P9_TOR::tor_get_single_ring ring 0x%08x", ringIndex); + rc = tor_get_single_ring( i_pOverride, + P9_XIP_MAGIC_SEEPROM, + i_chipState.getChipLevel(), + sgpeOvrdRings.getCommonRingId( ringIndex ), + P9_TOR::SBE, + OVERRIDE, + CACH0_CHIPLET_ID, + &i_ringData.iv_pWorkBuf2, + tempBufSize, + 2 ); + + if( (i_ringData.iv_sizeWorkBuf2 == tempBufSize) || (0 == tempBufSize ) || + ( 0 != rc ) ) + { + tempBufSize = 0; + continue; + } - rc = tor_get_block_of_rings( i_pOverride, - i_ddLevel, - ((PLAT_CME == i_platId) ? P9_TOR::CME : P9_TOR::SGPE), - i_ringType, - OVERRIDE, - torChipletId, - &i_pTempBuf, - io_bufLength ); + overrideNotFound = false; + ALIGN_DWORD(tempRingLength, tempBufSize) + ALGIN_RING_LOC( pOverrideStart, pOvrdRingPayload ); - if( TOR_AMBIGUOUS_API_PARMS == rc ) - { - FAPI_ERR("Invalid parameter, Overrides for %s ,rc 0x%08x", - ((PLAT_CME == i_platId) ? "CME" : "SGPE" ), rc ); - rc = BUILD_FAIL_CMN_RINGS; - io_bufLength = 0; - break; - } + memcpy( pOvrdRingPayload, i_ringData.iv_pWorkBuf2, tempBufSize); + *(pScanRingIndex + ringIndex) = SWIZZLE_2_BYTE((pOvrdRingPayload - pOverrideStart) + RING_START_TO_RS4_OFFSET ); - if( tempBufLength == io_bufLength ) - { - FAPI_DBG(" %s Overrides not found for %s", - ((i_instanceId == IGNORE_CHIPLET_INSTANCE ) ? "Common" : "Inst Specific"), - ((PLAT_CME == i_platId) ? "CME" : "SGPE" )); - - io_bufLength = 0; - //Not finding overrides cannot be regarded as error. - //Production Systems will not have scan overrides. So, let us continue. - rc = IMG_BUILD_SUCCESS; + sgpeOvrdRings.setRingOffset(pOvrdRingPayload, sgpeOvrdRings.getCommonRingId( ringIndex )); + sgpeOvrdRings.setRingSize( sgpeOvrdRings.getCommonRingId( ringIndex ), tempBufSize ); + + pOvrdRingPayload = pOvrdRingPayload + tempBufSize; } - if( !i_queryRing ) + if( overrideNotFound ) { - memcpy( i_pHomerLoc, (uint8_t*)i_pTempBuf, io_bufLength ); + FAPI_INF("Overrides not found for SGPE"); + rc = BUILD_FAIL_OVERRIDE; // Not considered an error + break; } - FAPI_DBG("Override Ring For: %s", (PLAT_CME == i_platId) ? "CME" : "SGPE" ); - FAPI_DBG("Ring Type: %s", - ( i_instanceId == IGNORE_CHIPLET_INSTANCE ) ? "Common" : "Instance"); - FAPI_DBG("Chiplet Id: %d", - ( i_instanceId == IGNORE_CHIPLET_INSTANCE ) ? IGNORE_CHIPLET_INSTANCE : i_instanceId ); - FAPI_DBG("Ring Length: 0x%08x", io_bufLength ); - FAPI_DBG("DD Level: 0x%08x", i_ddLevel ); - FAPI_DBG("Action: %s", i_queryRing ? "Query" : "Copy" ); + tempRingLength = (pOvrdRingPayload - pOverrideStart ); + pSgpeImgHdr->g_sgpe_cmn_ring_ovrd_occ_offset = + SWIZZLE_4_BYTE(pSgpeImgHdr->g_sgpe_cmn_ring_occ_offset) + commonRingLength; + i_qpmrHdr.quadCommonRingLength = SWIZZLE_4_BYTE(commonRingLength + tempRingLength); + pSgpeImgHdr->g_sgpe_cmn_ring_ovrd_occ_offset = SWIZZLE_4_BYTE(pSgpeImgHdr->g_sgpe_cmn_ring_ovrd_occ_offset); + } while(0); + sgpeOvrdRings.dumpOverrideRings(); + + FAPI_DBG("====================SGPE Override Rings================" ); + FAPI_DBG("====================SGPE Header ========================"); + FAPI_DBG("Override Ring Offset 0x%08x", SWIZZLE_4_BYTE(pSgpeImgHdr->g_sgpe_cmn_ring_ovrd_occ_offset)); + + FAPI_INF("< layoutSgpeScanOverride") return rc; } - //--------------------------------------------------------------------------- + //------------------------------------------------------------------------------ /** - * @brief copies override flavor of scan rings - * @param i_pImageIn points to start of hardware image. - * @param i_pOverride points to override rings. - * @param o_pImageOut points to HOMER image. - * @param i_ddLevel dd level associated with P9 chip. - * @param i_pBuf1 work buffer1 - * @param i_bufSize1 work buffer1 size. - * @param i_pBuf2 work buffer2 - * @param i_bufSize2 work buffer2 size. - * @param i_imgType image type to be built. - * @param o_qpmr temp instance of QpmrHeaderLayout_t - * @param i_platId platform associated with scan ring. - * @return IMG_BUILD_SUCCESS if successful else error code. + * @brief creates a lean scan ring layout for core rings in HOMER. + * @param i_pHOMER points to HOMER image. + * @param i_ringData processor target + * @param i_riskLevel IPL type */ - uint32_t copyRingsFromHwImage( - void* const i_pImageIn, - void* const i_pOverride, - void* const o_pImageOut, - uint8_t i_ddLevel, - void* const i_pBuf1, - const uint32_t i_bufSize1, - void* i_pBuf2, - const uint32_t i_bufSize2, - ImageType_t i_imgType, - QpmrHeaderLayout_t& o_qpmr, - E_PLAT_ID i_platId ) + uint32_t layoutRingsForCME( Homerlayout_t* i_pHomer, + const P9FuncModel& i_chipState, + RingBufData& i_ringData, + RingDebugMode_t i_debugMode, + uint32_t i_riskLevel, + ImageType_t i_imgType, + bool i_ovrdPresent ) { + FAPI_DBG( "> layoutRingsForCME"); uint32_t rc = IMG_BUILD_SUCCESS; - FAPI_INF( "> copyRingsFromHwImage"); + uint32_t tempBufSize = i_ringData.iv_sizeWorkBuf1; + uint32_t ringLength = 0; + RingVariant_t l_ringVariant = BASE; + uint8_t* pRingPayload = i_pHomer->cpmrRegion.coreCmnRingArea.cmnRingIndex.cmnScanRingPayload; + uint16_t* pScanRingIndex = (uint16_t*)&i_pHomer->cpmrRegion.coreCmnRingArea.cmnRingIndex.cmnRings; + uint8_t* pRingStart = (uint8_t*)&i_pHomer->cpmrRegion.coreCmnRingArea; + cmeHeader_t* pCmeHdr = (cmeHeader_t*) &i_pHomer->cpmrRegion.cmeBin.elements.imgHeader; + RingBucket cmeRings( PLAT_CME, + (uint8_t*)&i_pHomer->cpmrRegion, + i_debugMode ); do { - Homerlayout_t* i_pChipHomer = (Homerlayout_t*) o_pImageOut; - uint32_t tempLength = i_bufSize1; - uint32_t copyLength = 0; + if( !i_imgType.cmeCommonRingBuild ) + { + break; + } - if( PLAT_SGPE == i_platId ) + // get all the rings pertaining to CME in a work buffer first. + if( i_riskLevel ) { - // TOR structure arrange cache rings in terms of SGPE instance. Since there is only one - // instance of SGPE per P9 chip, entire cache instance specific rings need to be accessed - // as 1 block. It has not been arranged per instance of cache chiplet. Below - // is the representation: - //------------------------------------SGPE RING IN HW IMAGE ------------------------- - // Common Ring TOR | | - // -------------------------------------------------------------------- | Region A | - // | | - // Rings | | - //--------------------------------------------------------------------- |---------- | - // Cache Inst Spec Ring TOR | | - //--------------------------------------------------------------------- | | - // | | - // Cache 0 Rings | | - //----------------------------------------------------------------------| | - // | | - // Cache 1 Rings | | - //----------------------------------------------------------------------| Region B | - // | | - // Cache 2 Rings | | - //----------------------------------------------------------------------| | - // . | | - // . | | - // . | | - //----------------------------------------------------------------------|-----------| - - - //------------------------------OVERRDIDE RINGS ------------------------|-----------| - // Common Ring TOR | | - //----------------------------------------------------------------------|Region A | - // cache common override | | - // | | - //----------------------------------------------------------------------|-----------| - // Cache Inst. Spec Override Ring TOR | | - //----------------------------------------------------------------------| Region B | - // cache 0 override | | - //----------------------------------------------------------------------| | - // cache 1 override | | - //----------------------------------------------------------------------|------------ - // . - // . - //--------------------------------------------------------------------- - // - // Copying common quad rings of all flavors. In first go get base, CC,RL - // - // -------------------------------------------------------------------- - sgpeHeader_t* pSgpeImgHdr = ( sgpeHeader_t*) i_pChipHomer->qpmrRegion.sgpeRegion.imgHeader; - pSgpeImgHdr->g_sgpe_cmn_ring_ovrd_occ_offset = 0; - - - if( i_imgType.sgpeCommonRingBuild ) + l_ringVariant = RL; + } + + // Let us start with a clean slate in core common ring area. + memset( (uint8_t*)&i_pHomer->cpmrRegion.coreCmnRingArea, 0x00, CORE_COMMON_RING_SIZE ); + + for( uint32_t ringIndex = 0; ringIndex < EC::g_ecData.iv_num_common_rings; + ringIndex++ ) + { + tempBufSize = i_ringData.iv_sizeWorkBuf1; + rc = tor_get_single_ring( i_ringData.iv_pRingBuffer, + P9_XIP_MAGIC_CME, + i_chipState.getChipLevel(), + cmeRings.getCommonRingId( ringIndex ), + P9_TOR::CME, + l_ringVariant, + CORE0_CHIPLET_ID , + &i_ringData.iv_pWorkBuf1, + tempBufSize, + 2 ); + + if( (i_ringData.iv_sizeWorkBuf1 == tempBufSize) || (0 == tempBufSize ) || + ( 0 != rc ) ) { - rc = copyScanRings( i_pImageIn, - i_pChipHomer->qpmrRegion.sgpeRegion.commonRings, - i_ddLevel, - i_pBuf1, - tempLength, - PLAT_SGPE, - IGNORE_CHIPLET_INSTANCE ); + FAPI_INF( "Did not find core common ring Id %d ", ringIndex ); + rc = 0; + tempBufSize = 0; + continue; + } - if( rc ) - { - FAPI_ERR(" failed to copy the SGPE common ring rc: 0x%08x", rc ); - break; - } + ALIGN_DWORD(ringLength, tempBufSize) + ALGIN_RING_LOC( pRingStart, pRingPayload ); - FAPI_DBG(" Quad common scan ring copied offset 0x%08x, Length 0x%08x", - ((uint8_t*)i_pChipHomer->qpmrRegion.sgpeRegion.commonRings - (uint8_t*)i_pChipHomer), - tempLength ); + memcpy( pRingPayload, i_ringData.iv_pWorkBuf1, tempBufSize); + *(pScanRingIndex + ringIndex) = SWIZZLE_2_BYTE((pRingPayload - (uint8_t*) pScanRingIndex) + + RING_START_TO_RS4_OFFSET ); - copyLength = tempLength; - tempLength = i_bufSize1; + cmeRings.setRingOffset(pRingPayload, cmeRings.getCommonRingId( ringIndex )); + cmeRings.setRingSize( cmeRings.getCommonRingId( ringIndex ), tempBufSize ); - rc = copyScanOverrideRing( i_pOverride, - &i_pChipHomer->qpmrRegion.sgpeRegion.commonRings[copyLength], - i_ddLevel, - P9_TOR::COMMON, - i_pBuf1, - tempLength, - PLAT_SGPE, - IGNORE_CHIPLET_INSTANCE ); + pRingPayload = pRingPayload + tempBufSize; + } - if( rc ) - { - FAPI_INF(" No quad common override ring "); - tempLength = 0; - rc = IMG_BUILD_SUCCESS; - } + ringLength = (pRingPayload - pRingStart); - FAPI_DBG(" Quad common scan override ring offset 0x%08x, Length 0x%08x", - ((((uint8_t*)&i_pChipHomer->qpmrRegion.sgpeRegion.commonRings[copyLength] ) - - (uint8_t*)i_pChipHomer->qpmrRegion.sgpeRegion.commonRings)), tempLength ); + if( i_ovrdPresent ) + { + pCmeHdr->g_cme_common_ring_length = ringLength; //Save ring length in img header + } + else + { + pCmeHdr->g_cme_common_ring_length = CORE_COMMON_RING_SIZE; + } + + } + while(0); + + // Let us find out ring-pair which is biggest in list of 12 ring pairs + uint32_t maxCoreSpecRingLength = 0; + + do + { + if( !i_imgType.cmeCoreSpecificRingBuild ) + { + break; + } - o_qpmr.quadCommonRingLength = SWIZZLE_4_BYTE( tempLength + copyLength); - //putring running on SGPE needs to know the start of .overrides for quad common rings - //in SGPE Image. - pSgpeImgHdr->g_sgpe_cmn_ring_ovrd_occ_offset = SWIZZLE_4_BYTE(tempLength); // offset from start of .ring section + for( uint32_t exId = 0; exId < MAX_CME_PER_CHIP; exId++ ) + { + if( !i_chipState.isExFunctional( exId ) ) + { + FAPI_DBG( "ignoring ex %d for instance ring size consideration", exId); + continue; } - if( i_imgType.sgpeCacheSpecificRingBuild ) + ringLength = 0; + + for( uint32_t coreId = 0; coreId < MAX_CORES_PER_EX; coreId++ ) { - // for region B - tempLength = i_bufSize1; - rc = copyScanRings( i_pImageIn, - i_pChipHomer->qpmrRegion.sgpeRegion.cacheSpecificRing, - i_ddLevel, - i_pBuf1, - tempLength, - PLAT_SGPE, - CACH0_CHIPLET_ID ); + if( !i_chipState.isCoreFunctional( ((2 * exId ) + coreId)) ) + { + FAPI_DBG( "ignoring core %d for instance ring size consideration", (2 * exId ) + coreId ); + continue; + } - if( rc ) + tempBufSize = i_ringData.iv_sizeWorkBuf1; + rc = tor_get_single_ring( i_ringData.iv_pRingBuffer, + P9_XIP_MAGIC_CME, + i_chipState.getChipLevel(), + cmeRings.getInstRingId(0), + P9_TOR::CME, + l_ringVariant, + CORE0_CHIPLET_ID + ((2 * exId) + coreId), + &i_ringData.iv_pWorkBuf1, + tempBufSize, 2 ); + + if( (i_ringData.iv_sizeWorkBuf1 == tempBufSize) || (0 == tempBufSize ) || + ( 0 != rc ) ) { - FAPI_ERR(" failed to copy the Cache chiplet specific ring rc: 0x%08x", rc ); - break; + FAPI_DBG( "could not determine size of ring id %d of core %d", + cmeRings.getInstRingId(0), ((2 * exId) + coreId) ); + continue; } - FAPI_DBG(" Quad specific ring copied offset 0x%08x, Length 0x%08x", - ((uint8_t*)i_pChipHomer->qpmrRegion.sgpeRegion.cacheSpecificRing - (uint8_t*)i_pChipHomer), - tempLength ); + ringLength += tempBufSize; + } + + ALIGN_DWORD(tempBufSize, ringLength) + + maxCoreSpecRingLength = ringLength > maxCoreSpecRingLength ? ringLength : maxCoreSpecRingLength; + } + + maxCoreSpecRingLength += sizeof(CoreSpecRingList_t); + FAPI_DBG("Max Instance Spec Ring 0x%08x", maxCoreSpecRingLength); + // Let us copy the rings now. + + // Let us start with a clean slate in core specific ring area. + memset((uint8_t*) &i_pHomer->cpmrRegion.coreSpecRingArea[0], 0x00, (MAX_SIZE_CME_INST_RING * MAX_CME_PER_CHIP) ); - copyLength = tempLength; - tempLength = i_bufSize1; + for( uint32_t exId = 0; exId < MAX_CME_PER_CHIP; exId++ ) + { + pRingPayload = i_pHomer->cpmrRegion.coreSpecRingArea[exId].instRingIndex.instanceRingPayLoad; + pScanRingIndex = (uint16_t*)&i_pHomer->cpmrRegion.coreSpecRingArea[exId].instRingIndex.coreSpecRings; + pRingStart = (uint8_t*)&i_pHomer->cpmrRegion.coreSpecRingArea[exId]; - // for region B - rc = copyScanOverrideRing( i_pOverride, - &i_pChipHomer->qpmrRegion.sgpeRegion.cacheSpecificRing[copyLength], - i_ddLevel, - P9_TOR::INSTANCE, - i_pBuf1, - tempLength, - PLAT_SGPE, - CACH0_CHIPLET_ID ); + if( !i_chipState.isExFunctional( exId ) ) + { + FAPI_DBG("skipping copy of core specific rings of ex %d", exId); + pRingPayload = pRingStart + ( exId * maxCoreSpecRingLength ); + continue; + } - if( rc ) + for( uint32_t coreId = 0; coreId < MAX_CORES_PER_EX; coreId++ ) + { + if( !i_chipState.isCoreFunctional( ((2 * exId ) + coreId)) ) { - FAPI_INF(" No quad specific override ring "); - tempLength = 0; - rc = IMG_BUILD_SUCCESS; + FAPI_DBG( "ignoring core %d for instance ring size consideration", (2 * exId ) + coreId ); + continue; } - FAPI_DBG(" Quad specific scan override ring offset 0x%08x, Length 0x%08x", - ((((uint8_t*)&i_pChipHomer->qpmrRegion.sgpeRegion.cacheSpecificRing[copyLength] ) - - (uint8_t*)i_pChipHomer->qpmrRegion.sgpeRegion.cacheSpecificRing)), tempLength ); - //putring running on SGPE needs to know the start of .overrides for quad specific rings - //in SGPE Image. - pSgpeImgHdr->g_sgpe_spec_ring_ovrd_occ_offset = SWIZZLE_4_BYTE( tempLength + copyLength ); - pSgpeImgHdr->g_sgpe_spec_ring_occ_offset = - SWIZZLE_4_BYTE(SWIZZLE_4_BYTE(pSgpeImgHdr->g_sgpe_cmn_ring_occ_offset) + - SWIZZLE_4_BYTE(o_qpmr.quadCommonRingLength)); + tempBufSize = i_ringData.iv_sizeWorkBuf1; + rc = tor_get_single_ring( i_ringData.iv_pRingBuffer, + P9_XIP_MAGIC_CME, + i_chipState.getChipLevel(), + cmeRings.getInstRingId(0), + P9_TOR::CME, + l_ringVariant, + CORE0_CHIPLET_ID + ((2 * exId) + coreId), + &i_ringData.iv_pWorkBuf1, + tempBufSize ); + + if( (i_ringData.iv_sizeWorkBuf1 == tempBufSize) || (0 == tempBufSize ) || + ( 0 != rc ) ) + { + FAPI_INF("Instance ring Id %d not found for EX %d core %d", + cmeRings.getInstRingId(0), exId, coreId ); + rc = 0; + tempBufSize = 0; + continue; + } - FAPI_DBG(" SGPE Image Header - specific scan ring offset 0x%08x", - SWIZZLE_4_BYTE(pSgpeImgHdr->g_sgpe_spec_ring_occ_offset)); + ALGIN_RING_LOC( pRingStart, pRingPayload ); + memcpy( pRingPayload, i_ringData.iv_pWorkBuf1, tempBufSize); + cmeRings.setRingOffset( pRingPayload, + cmeRings.getInstRingId(0), + ( MAX_CORES_PER_EX * exId ) + coreId ); + *(pScanRingIndex + coreId) = SWIZZLE_2_BYTE((pRingPayload - pRingStart ) + RING_START_TO_RS4_OFFSET ); - //FIXME Assigning maximum size for now to facilitate bootloader. Eventually design shall be changed - //to eliminate max size allocation for each section say hcode or rings. Each section shall be - //packed next to each other. + pRingPayload = pRingPayload + tempBufSize; + cmeRings.setRingSize( cmeRings.getInstRingId(0), tempBufSize, ((MAX_CORES_PER_EX * exId) + coreId) ); + } + } - o_qpmr.quadSpecRingOffset = i_pChipHomer->qpmrRegion.sgpeRegion.cacheSpecificRing - - (uint8_t*)&i_pChipHomer->qpmrRegion; - o_qpmr.quadSpecRingLength = CACHE_INST_SPECIFIC_SIZE; + if( i_ovrdPresent ) + { + pCmeHdr->g_cme_cmn_ring_ovrd_offset = + SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_offset) + pCmeHdr->g_cme_common_ring_length; + } - o_qpmr.quadSpecRingOffset = SWIZZLE_4_BYTE(o_qpmr.quadSpecRingOffset); - o_qpmr.quadSpecRingLength = SWIZZLE_4_BYTE(o_qpmr.quadSpecRingLength); + pCmeHdr->g_cme_common_ring_length = CORE_COMMON_RING_SIZE; + pCmeHdr->g_cme_pstate_region_offset = SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_offset) + + pCmeHdr->g_cme_common_ring_length; + pCmeHdr->g_cme_core_spec_ring_offset = pCmeHdr->g_cme_pstate_region_offset + + SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_region_length); + pCmeHdr->g_cme_core_spec_ring_offset = (pCmeHdr->g_cme_core_spec_ring_offset + CME_BLOCK_READ_LEN - 1 ) >> + CME_BLK_SIZE_SHIFT; + pCmeHdr->g_cme_max_spec_ring_length = ( MAX_SIZE_CME_INST_RING + CME_BLOCK_READ_LEN - 1 ) >> CME_BLK_SIZE_SHIFT; + //Let us handle endianess now + pCmeHdr->g_cme_pstate_region_offset = SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_region_offset); + pCmeHdr->g_cme_core_spec_ring_offset = SWIZZLE_4_BYTE(pCmeHdr->g_cme_core_spec_ring_offset); + pCmeHdr->g_cme_max_spec_ring_length = SWIZZLE_4_BYTE(pCmeHdr->g_cme_max_spec_ring_length); + pCmeHdr->g_cme_common_ring_length = SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_length); + pCmeHdr->g_cme_cmn_ring_ovrd_offset = SWIZZLE_4_BYTE(pCmeHdr->g_cme_cmn_ring_ovrd_offset); + } + while(0); - } + cmeRings.dumpRings(); + FAPI_DBG("CME Header Ring Details "); + FAPI_DBG( "PS Offset %d (0x%08x)", SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_region_offset), + SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_region_offset)); + FAPI_DBG("PS Lengtrh %d (0x%08x)", SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_region_length), + SWIZZLE_4_BYTE(pCmeHdr->g_cme_pstate_region_length) ); + FAPI_DBG("Common Ring Offset %d (0x%08x) ", SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_offset), + SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_offset)); + FAPI_DBG("Common Ring Length %d (0x%08x) ", SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_length), + SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_length)); + FAPI_DBG("Instance Ring Offset / 32 %d (0x%08x) ", SWIZZLE_4_BYTE(pCmeHdr->g_cme_core_spec_ring_offset), + SWIZZLE_4_BYTE(pCmeHdr->g_cme_core_spec_ring_offset)); + FAPI_DBG("Instance Ring Length / 32 %d (0x%08x) ", SWIZZLE_4_BYTE(pCmeHdr->g_cme_max_spec_ring_length), + + SWIZZLE_4_BYTE(pCmeHdr->g_cme_max_spec_ring_length)); + + FAPI_DBG( "< layoutRingsForCME"); + + return rc; + } + + //------------------------------------------------------------------------------ + + /** + * @brief creates a lean scan ring layout for cache rings in HOMER. + * @param i_pHOMER points to HOMER image. + * @param i_ringData processor target + * @param i_riskLevel IPL type + * @return IMG_BUILD_SUCCESS if success , error code otherwise. + */ + uint32_t layoutRingsForSGPE( Homerlayout_t* i_pHomer, + const P9FuncModel& i_chipState, + RingBufData& i_ringData, + RingDebugMode_t i_debugMode, + uint32_t i_riskLevel, + QpmrHeaderLayout_t& i_qpmrHdr, + ImageType_t i_imgType ) + { + FAPI_DBG( "> layoutRingsForSGPE"); + uint32_t rc = IMG_BUILD_SUCCESS; + RingVariant_t l_ringVariant = BASE; + sgpeHeader_t* pSgpeImgHdr = (sgpeHeader_t*)& i_pHomer->qpmrRegion.sgpeRegion.imgHeader; + uint8_t* pRingPayload = i_pHomer->qpmrRegion.sgpeRegion.quadCmnRingArea.cmnRingIndex.cmnRingPayLoad; + uint16_t* pCmnRingIndex = (uint16_t*)&i_pHomer->qpmrRegion.sgpeRegion.quadCmnRingArea.cmnRingIndex.quadCmnRingList; + uint8_t* pRingStart = (uint8_t*)&i_pHomer->qpmrRegion.sgpeRegion.quadCmnRingArea; + uint32_t ringIndex = 0; + uint32_t tempLength = 0; + uint32_t tempBufSize = i_ringData.iv_sizeWorkBuf1; + + RingBucket sgpeRings( PLAT_SGPE, + (uint8_t*)&i_pHomer->qpmrRegion, + i_debugMode ); + + do + { + if( !i_imgType.sgpeCommonRingBuild ) + { + break; + } + + // get all the rings pertaining to CME in a work buffer first. + if( i_riskLevel ) + { + l_ringVariant = RL; } - else if( PLAT_CME == i_platId ) + + // Let us start with a clean slate in quad common ring area. + memset( (uint8_t*)&i_pHomer->qpmrRegion.sgpeRegion.quadCmnRingArea, 0x00, SGPE_COMMON_RING_SIZE ); + + tempLength = (tempBufSize % RING_ALIGN_BOUNDARY); + + //get core common rings + for( ; ringIndex < EQ::g_eqData.iv_num_common_rings; ringIndex++ ) { - //------------------------------------CME RING IN HW IMAGE ------------------------- - // | | - // Core Common Rings | Region A | - // | | - //----------------------------------------------------------------------------------- - // | | - // CME 0 Rings | Region 0 | - //----------------------------------------------------------------------|---------- | - // | | - // CME 1 Rings | Region 1 | - //----------------------------------------------------------------------|--------- | - // | | - // CME 2 Rings | Region 2 | - //----------------------------------------------------------------------|---------- | - // . | . | - // . | . | - // . | . | - //----------------------------------------------------------------------|-----------| - - - //------------------------------OVERRDIDE RINGS ------------------------------------------ - // cache common override - //---------------------------------------------------------------------------------- - // cache 0 override - //---------------------------------------------------------------------------------- - // cache 1 override - //---------------------------------------------------------------------------------- - // . - // . - //--------------------------------------------------------------------- - // - // Copying common quad rings of all flavors. In first go get base, CC,RL - // - // -------------------------------------------------------------------- - cmeHeader_t* pCmeImgHdr = &i_pChipHomer->cpmrRegion.cmeBin.elements.imgHeader; - pCmeImgHdr->g_cme_cmn_ring_ovrd_offset = 0; - pCmeImgHdr->g_cme_core_spec_ring_ovrd_offset = 0; - //--------------------------------------------------------------------- - // - // Copying common core rings of all flavors. In first go base, CC,RL - // and in second step copy override and overlay rings. - // - // -------------------------------------------------------------------- - - if( i_imgType.cmeCommonRingBuild ) + tempBufSize = i_ringData.iv_sizeWorkBuf1; + + rc = tor_get_single_ring( i_ringData.iv_pRingBuffer, + P9_XIP_MAGIC_SGPE, + i_chipState.getChipLevel(), + sgpeRings.getCommonRingId( ringIndex ), + P9_TOR::SGPE, + l_ringVariant, + CACH0_CHIPLET_ID, + &i_ringData.iv_pWorkBuf1, + tempBufSize ); + + if( (i_ringData.iv_sizeWorkBuf1 == tempBufSize) || (0 == tempBufSize ) || + ( 0 != rc ) ) { - tempLength = i_bufSize1; - rc = copyScanRings( i_pImageIn, - i_pChipHomer->cpmrRegion.commonRings, - i_ddLevel, - i_pBuf1, - tempLength, - PLAT_CME, - IGNORE_CHIPLET_INSTANCE ); + FAPI_INF( "did not find quad common ring %d", ringIndex ); + rc = 0; + tempBufSize = 0; + continue; + } - if( rc ) - { - FAPI_ERR(" failed to copy the CME common ring rc: 0x%08x", rc ); - break; - } + ALIGN_DWORD(tempLength, tempBufSize) + ALGIN_RING_LOC( pRingStart, pRingPayload ); - FAPI_INF(" Core Cmn Ring copied Offset 0x%08x Length 0x%08x", - ( (uint8_t*)i_pChipHomer->cpmrRegion.commonRings - (uint8_t*)i_pChipHomer ), - tempLength ); + memcpy( pRingPayload, i_ringData.iv_pWorkBuf1, tempBufSize); + sgpeRings.setRingOffset( pRingPayload, sgpeRings.getCommonRingId( ringIndex ) ); + *(pCmnRingIndex + ringIndex) = SWIZZLE_2_BYTE((pRingPayload - pRingStart ) + RING_START_TO_RS4_OFFSET ); + sgpeRings.setRingSize( sgpeRings.getCommonRingId( ringIndex ), tempBufSize ); + pRingPayload = pRingPayload + tempBufSize; - copyLength = tempLength; - tempLength = i_bufSize1; + }//for common rings - rc = copyScanOverrideRing( i_pOverride, - &i_pChipHomer->cpmrRegion.commonRings[copyLength], - i_ddLevel, - P9_TOR::COMMON, - i_pBuf1, - tempLength, - PLAT_CME, - IGNORE_CHIPLET_INSTANCE ); + tempLength = pRingPayload - pRingStart; + i_qpmrHdr.quadCommonRingLength = tempLength; + FAPI_DBG("Quad Cmn Ring Length 0x%08x", i_qpmrHdr.quadCommonRingLength ); - if( rc ) - { - FAPI_INF(" No common core override ring"); - tempLength = 0; - rc = IMG_BUILD_SUCCESS; - } + } + while(0); //building common rings - FAPI_DBG(" Core common ring override: length 0x%08x", tempLength ); - pCmeImgHdr->g_cme_common_ring_length = SWIZZLE_4_BYTE(tempLength + copyLength); - pCmeImgHdr->g_cme_cmn_ring_ovrd_offset = SWIZZLE_4_BYTE(tempLength); - } + do + { + if( !i_imgType.sgpeCacheSpecificRingBuild ) + { + break; + } - if( i_imgType.cmeCoreSpecificRingBuild ) - { - uint32_t cmeId = 0; - uint32_t maxRingLength = 0; - uint32_t maxOverrideLength = 0; - - //to facilitate seemless copy of CME's instance specific ring by CME BCE in to CME's SRAM, - //find out the max size for Core pair's Instance specific rings (odd and even core - //pair put together). Use this max size as standard size of instance specific ring block - //for all the core-pairs. - // - //Same logic is used for scan ring overrides too. - for( cmeId = 0; cmeId < MAX_CME_PER_CHIP; cmeId++ ) - { - tempLength = i_bufSize1; - - rc = copyScanRings( i_pImageIn, - &i_pChipHomer->cpmrRegion.instSpecificRing[0], //don't care here - i_ddLevel, - i_pBuf1, - tempLength, - PLAT_CME, - (CORE0_CHIPLET_ID + (2 * cmeId)), - true ); // querying size of the ring - - if( rc ) - { - FAPI_ERR(" failed to query CME instance specific ring rc: 0x%08x core id %d", - rc, cmeId ); - break; - } - - if( tempLength > maxRingLength ) - { - maxRingLength = tempLength; - } - - tempLength = i_bufSize1; - rc = copyScanOverrideRing( i_pOverride, - &i_pChipHomer->cpmrRegion.instSpecificRing[0], // don't care here - i_ddLevel, - P9_TOR::INSTANCE, - i_pBuf1, - tempLength, - PLAT_CME, - (CORE0_CHIPLET_ID + ( 2 * cmeId)), - true ); // querying size of the ring - - if( rc ) - { - FAPI_DBG(" didn't find core specific override ring core id %d", cmeId ); - rc = IMG_BUILD_SUCCESS; - continue; - } - - if( tempLength > maxOverrideLength ) - { - maxOverrideLength = tempLength; - } - } + pRingPayload = i_pHomer->qpmrRegion.sgpeRegion.quadSpecRingArea.instRingIndex.quadSpecRingPayLoad; + pCmnRingIndex = (uint16_t*)&i_pHomer->qpmrRegion.sgpeRegion.quadSpecRingArea.instRingIndex.quadSpecRings[0]; + pRingStart = (uint8_t*)&i_pHomer->qpmrRegion.sgpeRegion.quadSpecRingArea.instRingIndex; - if( rc ) - { - // failed to access core specific rings - break; - } + // Let us start with a clean slate in quad spec ring area. + memset( (uint8_t*)&i_pHomer->qpmrRegion.sgpeRegion.quadSpecRingArea, 0x00, MAX_QUAD_SPEC_RING_SIZE ); - copyLength = maxRingLength + maxOverrideLength; + for( uint32_t cacheInst = 0; cacheInst < MAX_CACHE_CHIPLET; cacheInst++ ) + { + if( !i_chipState.isQuadFunctional( cacheInst ) ) + { + pCmnRingIndex = pCmnRingIndex + QUAD_SPEC_RING_INDEX_SIZE; // Jump to next Quad Index + //Quad is not functional. Don't populate rings. Ring Index will be zero by design + FAPI_INF("Skipping copy of cache chiplet%d", cacheInst); + continue; + } - if( 0 != ( copyLength % CME_BLOCK_READ_LEN ) ) - { - FAPI_DBG("Core specific ring before rounding 0x%08x", copyLength ); - // rounding off size of ring to 32B boundary - copyLength = (( copyLength + (CME_BLOCK_READ_LEN - 1 ) ) >> CME_BLK_SIZE_SHIFT ); - copyLength = copyLength << CME_BLK_SIZE_SHIFT; - FAPI_DBG("Core specific ring after rounding 0x%08x", copyLength ); - } + ExIdMap ExChipletRingMap; + uint32_t chipletId = 0; - for( cmeId = 0; cmeId < MAX_CME_PER_CHIP; cmeId++ ) + for( ringIndex = 0; ringIndex < EQ::g_eqData.iv_num_instance_rings_scan_addrs; + ringIndex++ ) + { + tempBufSize = i_ringData.iv_sizeWorkBuf1; + chipletId = ExChipletRingMap.getInstanceId( CACH0_CHIPLET_ID + cacheInst , ringIndex ); + + rc = tor_get_single_ring( i_ringData.iv_pRingBuffer, + P9_XIP_MAGIC_SGPE, + i_chipState.getChipLevel(), + sgpeRings.getInstRingId( ringIndex ), + P9_TOR::SGPE, + l_ringVariant, + chipletId, + &i_ringData.iv_pWorkBuf1, + tempBufSize ); + + if( (i_ringData.iv_sizeWorkBuf1 == tempBufSize) || (0 == tempBufSize ) || + ( 0 != rc ) ) { - tempLength = i_bufSize1; - - // Copying base flavor of instance specific ring for core-pair. Pass chiplet id of even core - // e.g. for core0 and core1, pass chiplet id of core0 i.e. CORE0_CHIPLET_ID (0x20). - rc = copyScanRings( i_pImageIn, - &i_pChipHomer->cpmrRegion.instSpecificRing[( cmeId * copyLength )], - i_ddLevel, - i_pBuf1, - tempLength, - PLAT_CME, - (CORE0_CHIPLET_ID + ( 2 * cmeId)) ); - - if( rc ) - { - FAPI_ERR(" failed to copy the CME instance ring rc: 0x%08x core id %d", - rc, cmeId ); - break; - } - - // Copying override flavor of instance specific ring for core-pair. Pass chiplet id of - // even core e.g. for core0 and core1, pass chiplet id of core0 i.e. CORE0_CHIPLET_ID (0x20). - // copy ring override at the end of base rings - tempLength = i_bufSize1; - rc = copyScanOverrideRing( i_pOverride, - &i_pChipHomer->cpmrRegion.instSpecificRing[ ((cmeId * copyLength) + maxRingLength) ], - i_ddLevel, - P9_TOR::INSTANCE, - i_pBuf1, - tempLength, - PLAT_CME, - (CORE0_CHIPLET_ID + ( 2 * cmeId)) ); - - if( rc ) - { - FAPI_DBG(" didn't find core specific override ring core id %d", cmeId ); - rc = IMG_BUILD_SUCCESS; - continue; - } + FAPI_DBG( "did not find quad spec ring %d for cache Inst %d", ringIndex , cacheInst ); + rc = 0; + tempBufSize = 0; + continue; } - FAPI_DBG(" Core specific rings Offset 0x%08x max len per cme (base + ovrd) 0x%08x", - ( (uint8_t*)i_pChipHomer->cpmrRegion.instSpecificRing - (uint8_t*)i_pChipHomer ), - copyLength ); - - FAPI_DBG(" Core specific rings Override: Length 0x%08x", tempLength ); + ALIGN_DWORD(tempLength, tempBufSize) + ALGIN_RING_LOC( pRingStart, pRingPayload ); - pCmeImgHdr->g_cme_max_spec_ring_length = SWIZZLE_4_BYTE( copyLength >> CME_BLK_SIZE_SHIFT ); - //field below contains an offset wrt to common ring at which respective override area starts + memcpy( pRingPayload, i_ringData.iv_pWorkBuf1, tempBufSize); + sgpeRings.setRingOffset( pRingPayload, sgpeRings.getInstRingId( ringIndex ), chipletId ); + *(pCmnRingIndex + ringIndex) = SWIZZLE_2_BYTE((pRingPayload - pRingStart ) + RING_START_TO_RS4_OFFSET ); + sgpeRings.setRingSize( sgpeRings.getInstRingId( ringIndex ), tempBufSize, chipletId ); + pRingPayload = pRingPayload + tempBufSize; - pCmeImgHdr->g_cme_core_spec_ring_ovrd_offset = SWIZZLE_4_BYTE(maxOverrideLength); - tempLength = SWIZZLE_4_BYTE(pCmeImgHdr->g_cme_common_ring_offset) + //Unswizzle first to do math - SWIZZLE_4_BYTE(pCmeImgHdr->g_cme_common_ring_length); + }//for quad spec rings - //Swizzling again - tempLength = SWIZZLE_4_BYTE(( tempLength + CME_BLOCK_READ_LEN - 1 ) >> CME_BLK_SIZE_SHIFT ); - //Instance Specific ring needs to be copied at an offset which is a multiple of 32B. This offset - //will become an SBASE value of CME's BCE. Doing this math here to keep CME hcode simple. - pCmeImgHdr->g_cme_core_spec_ring_offset = tempLength; - pCmeImgHdr->g_cme_scom_offset = SWIZZLE_4_BYTE(SWIZZLE_4_BYTE(pCmeImgHdr->g_cme_core_spec_ring_offset) + - SWIZZLE_4_BYTE(pCmeImgHdr->g_cme_max_spec_ring_length)); - pCmeImgHdr->g_cme_scom_length = SWIZZLE_4_BYTE(CME_SCOM_AREA); - } + pCmnRingIndex = pCmnRingIndex + QUAD_SPEC_RING_INDEX_SIZE; // Jump to next Quad Index } + + i_qpmrHdr.quadSpecRingOffset = (uint8_t*)(&i_pHomer->qpmrRegion.sgpeRegion.quadSpecRingArea ) - + (uint8_t*)(&i_pHomer->qpmrRegion); + i_qpmrHdr.quadSpecRingLength = (pRingPayload - pRingStart); + + pSgpeImgHdr->g_sgpe_spec_ring_occ_offset = SWIZZLE_4_BYTE(pSgpeImgHdr->g_sgpe_cmn_ring_occ_offset) + + i_qpmrHdr.quadCommonRingLength; } - while(0); + while(0); //building instance rings + + //Let us handle endianes at last + i_qpmrHdr.quadCommonRingLength = SWIZZLE_4_BYTE(i_qpmrHdr.quadCommonRingLength); + i_qpmrHdr.quadSpecRingOffset = SWIZZLE_4_BYTE(i_qpmrHdr.quadSpecRingOffset); + i_qpmrHdr.quadSpecRingLength = SWIZZLE_4_BYTE(i_qpmrHdr.quadSpecRingLength); + pSgpeImgHdr->g_sgpe_spec_ring_occ_offset = SWIZZLE_4_BYTE(pSgpeImgHdr->g_sgpe_spec_ring_occ_offset); + sgpeRings.dumpRings(); + + FAPI_DBG("SGPE Header Ring Details "); + FAPI_DBG("Common Ring Offset %d (0x%08x) ", + SWIZZLE_4_BYTE(pSgpeImgHdr->g_sgpe_cmn_ring_occ_offset), + SWIZZLE_4_BYTE(pSgpeImgHdr->g_sgpe_cmn_ring_occ_offset)); + FAPI_DBG("Instance Ring Offset %d (0x%08x) ", + SWIZZLE_4_BYTE(pSgpeImgHdr->g_sgpe_spec_ring_occ_offset), + SWIZZLE_4_BYTE(pSgpeImgHdr->g_sgpe_spec_ring_occ_offset)); - FAPI_INF( "< copyRingsFromHwImage"); + FAPI_DBG( "< layoutRingsForSGPE"); return rc; } @@ -1480,7 +1812,11 @@ extern "C" void* const i_pBuf1, const uint32_t i_sizeBuf1, void* const i_pBuf2, - const uint32_t i_sizeBuf2 ) + const uint32_t i_sizeBuf2, + void* const i_pBuf3, + const uint32_t i_sizeBuf3 ) + + { FAPI_IMP("Entering p9_hcode_image_build "); fapi2::ReturnCode retCode; @@ -1488,9 +1824,15 @@ extern "C" do { FAPI_DBG("validating argument .."); + retCode = validateInputArguments( i_pImageIn, i_pHomerImage, i_phase, - i_imgType, i_pBuf1, i_sizeBuf1, i_pBuf2, - i_sizeBuf2 ); + i_imgType, + i_pBuf1, + i_sizeBuf1, + i_pBuf2, + i_sizeBuf2, + i_pBuf3, + i_sizeBuf3 ); if( retCode ) { @@ -1498,16 +1840,24 @@ extern "C" break; } + uint8_t ecLevel = 0; + FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_EC, + i_procTgt, + ecLevel), + "Error from for attribute ATTR_EC"); + + FAPI_INF("Creating chip functional model"); + + P9FuncModel l_chipFuncModel( i_procTgt, ecLevel ); Homerlayout_t* pChipHomer = ( Homerlayout_t*) i_pHomerImage; + const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; uint32_t ppeImgRc = IMG_BUILD_SUCCESS; - + QpmrHeaderLayout_t l_qpmrHdr; // HW Image is a nested XIP Image. Let us read global TOC of hardware image // and find out if XIP header of PPE image is contained therein. // Let us start with SGPE FAPI_INF("SGPE building"); - QpmrHeaderLayout_t qpmrHdr; - ppeImgRc = buildSgpeImage( i_pImageIn, pChipHomer, i_imgType, qpmrHdr ); - ppeImgRc = IMG_BUILD_SUCCESS; + ppeImgRc = buildSgpeImage( i_pImageIn, pChipHomer, i_imgType, l_qpmrHdr ); FAPI_ASSERT( ( IMG_BUILD_SUCCESS == ppeImgRc ), fapi2::SGPE_BUILD_FAIL() @@ -1520,9 +1870,7 @@ extern "C" //let us determine if system is configured in fuse mode. This needs to //be updated in a CPMR region. - const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; uint8_t fuseModeState = 0; - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_FUSED_CORE_MODE, FAPI_SYSTEM, fuseModeState), @@ -1559,61 +1907,127 @@ extern "C" fapi2::PGPE_BUILD_FAIL() .set_PGPE_FAIL_SECTN( ppeImgRc ), "Failed to copy PGPE section in HOMER" ); + FAPI_INF("PGPE built"); - //Update CPMR Header area in HOMER with CME Image related information. - updateCpmrHeaderCME( pChipHomer ); + uint8_t l_ringDebug = 0; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_SYSTEM_RING_DBG_MODE, + FAPI_SYSTEM, + l_ringDebug), + "Error from FAPI_ATTR_GET for attribute ATTR_SYSTEM_RING_DBG_MODE"); - uint8_t ecLevel = 0; - FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_EC, - i_procTgt, - ecLevel), - "Error from for attribute ATTR_EC"); + RingBufData l_ringData( i_pBuf1, + i_sizeBuf1, + i_pBuf2, + i_sizeBuf2, + i_pBuf3, + i_sizeBuf3 ); - FAPI_INF("CORE_RESERVE_SIZE 0x%08x ( %d )", CORE_RESERVE_SIZE ); -#if 1 - ppeImgRc = copyRingsFromHwImage( i_pImageIn, - i_pRingOverride, - i_pHomerImage, - ecLevel, - i_pBuf1, - i_sizeBuf1, - i_pBuf2, - i_sizeBuf2, - i_imgType, - qpmrHdr, - PLAT_SGPE ); + ppeImgRc = getPpeScanRings( i_pImageIn, + PLAT_CME, + i_procTgt, + l_ringData, + i_imgType ); - FAPI_ASSERT( ( IMG_BUILD_SUCCESS == ppeImgRc ), - fapi2::SCAN_RING_BUILD_FAIL() - .set_RING_FAIL_RC( ppeImgRc ), - "Failed to copy SGPE's scan ring in HOMER" ); - - FAPI_DBG("SGPE scan rings added "); - ppeImgRc = copyRingsFromHwImage( i_pImageIn, - i_pRingOverride, - i_pHomerImage, - ecLevel, - i_pBuf1, - i_sizeBuf1, - i_pBuf2, - i_sizeBuf2, - i_imgType, - qpmrHdr, - PLAT_CME ); + if( ppeImgRc ) + { + FAPI_ERR( "failed to extract core scan rings rc = 0x%08x", ppeImgRc ); + break; + } - FAPI_ASSERT( ( IMG_BUILD_SUCCESS == ppeImgRc ), - fapi2::SCAN_RING_BUILD_FAIL() - .set_RING_FAIL_RC( ppeImgRc ), - "Failed to copy CME's scan ring in HOMER" ); + uint8_t l_iplPhase = 0 ; + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_RISK_LEVEL, + FAPI_SYSTEM, + l_iplPhase), + "Error from FAPI_ATTR_GET for ATTR_RISK_LEVEL"); + // create a layout of rings in HOMER for consumption of CME + ppeImgRc = layoutRingsForCME( pChipHomer, + l_chipFuncModel, + l_ringData, + (RingDebugMode_t)l_ringDebug, + l_iplPhase, + i_imgType, + i_pRingOverride ? true : false ); + + if( ppeImgRc ) + { + FAPI_ERR("Failed to copy core Scan rings in HOMER rc 0x%08x", ppeImgRc ); + break; + } + + if( i_pRingOverride ) + { + FAPI_DBG("Extracting Override Rings for CME"); + l_ringData.iv_ringBufSize = i_sizeBuf1; + ppeImgRc = layoutCmeScanOverride( pChipHomer, + i_pRingOverride, + l_chipFuncModel, + l_ringData, + (RingDebugMode_t)l_ringDebug, + l_iplPhase, + i_imgType ); + + if( ppeImgRc ) + { + FAPI_INF("Did not find scan ring override for CME rc 0x%08x", ppeImgRc ); + } + } + + l_ringData.iv_ringBufSize = i_sizeBuf1; + ppeImgRc = getPpeScanRings( i_pImageIn, + PLAT_SGPE, + i_procTgt, + l_ringData, + i_imgType ); + + if( ppeImgRc ) + { + FAPI_ERR( "failed to extract quad/ex scan rings" ); + break; + } + + // create a layout of rings in HOMER for consumption of SGPE + ppeImgRc = layoutRingsForSGPE( pChipHomer, + l_chipFuncModel, + l_ringData, + (RingDebugMode_t)l_ringDebug, + l_iplPhase, + l_qpmrHdr, + i_imgType ); + + if( ppeImgRc ) + { + FAPI_ERR("Failed to copy quad/ex Scan rings in HOMER rc 0x%08x", ppeImgRc ); + break; + } + + if( i_pRingOverride ) + { + FAPI_DBG("Extracting Override Rings for CME"); + l_ringData.iv_ringBufSize = i_sizeBuf1; + ppeImgRc = layoutSgpeScanOverride( pChipHomer, + i_pRingOverride, + l_chipFuncModel, + l_ringData, + (RingDebugMode_t)l_ringDebug, + l_iplPhase, + l_qpmrHdr, + i_imgType ); + + if( ppeImgRc ) + { + FAPI_INF("Did not find scan ring override for CME rc 0x%08x", ppeImgRc ); + } + } + + //Update CPMR Header area in HOMER with CME Image related information. + updateCpmrHeaderCME( pChipHomer ); - FAPI_DBG("CME scan rings added "); -#endif //Update CPMR Header with Scan Ring details updateCpmrScanRing( pChipHomer ); //Update QPMR Header area in HOMER - updateQpmrHeader( pChipHomer, qpmrHdr ); + updateQpmrHeader( pChipHomer, l_qpmrHdr ); //Finally update the attributes storing PGPE and SGPE's boot copier offset. retCode = updateGpeAttributes( pChipHomer, i_procTgt ); diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.H b/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.H index 7b2e48046..076f33cf6 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.H +++ b/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.H @@ -42,6 +42,7 @@ // Includes //-------------------------------------------------------------------------- #include <fapi2.H> +#include <p9_infrastruct_help.H> extern "C" { @@ -63,7 +64,8 @@ extern "C" */ enum { - HW_IMG_RING_SIZE = 1024 * 1024, + HW_IMG_RING_SIZE = MAX_SEEPROM_IMAGE_SIZE, + WORK_BUF_SIZE = MAX_RING_BUF_SIZE, }; /** @@ -131,7 +133,9 @@ extern "C" void* const i_pBuf1, const uint32_t i_sizeBuf1, void* const i_pBuf2, - const uint32_t i_sizeBuf2 ); + const uint32_t i_sizeBuf2, + void* const i_pBuf3, + const uint32_t i_sizeBuf3 ); /** * @brief builds a STOP image using a refrence image as input. @@ -143,8 +147,10 @@ extern "C" * @param i_imgType image type to be built. * @param i_pBuf1 pointer to a work buffer1. * @param i_sizeBuf1 size of work buffer1. Minimum size expected HW_IMG_RING_SIZE. - * @param i_pBuf2 pointer to a work buffer2. Minimum size expected HW_IMG_RING_SIZE. + * @param i_pBuf2 pointer to a work buffer2. Minimum size expected WORK_BUF_SIZE. * @param i_sizeBuf2 size of work buffer2 + * @param i_pBuf3 pointer to a work buffer2. Minimum size expected WORK_BUF_SIZE. + * @param i_sizeBuf3 size of work buffer2 * @note needs attribute ATTR_EC */ fapi2::ReturnCode p9_hcode_image_build( CONST_FAPI2_PROC& i_procTgt, @@ -156,7 +162,8 @@ extern "C" void* const i_pBuf1, const uint32_t i_sizeBuf1, void* const i_pBuf2, - const uint32_t i_sizeBuf2 - ); + const uint32_t i_sizeBuf2, + void* const i_pBuf3, + const uint32_t i_sizeBuf3 ); } // extern C #endif //__HCODE_IMG_BUILD_H_ diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.mk b/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.mk index 2e3f9456b..2645c5e5f 100644 --- a/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.mk +++ b/src/import/chips/p9/procedures/hwp/pm/p9_hcode_image_build.mk @@ -27,6 +27,9 @@ HCODE_UTIL=$(ROOTPATH)/chips/p9/procedures/utils/stopreg/ HCODE_UTIL+=$(ROOTPATH)/chips/p9/xip/ HCODE_UTIL+=$(ROOTPATH)/chips/p9/procedures/hwp/lib/ HCODE_UTIL+=$(ROOTPATH)/chips/p9/utils/imageProcs/ +HCODE_UTIL+=$(ROOTPATH)/tools/imageProcs/ +HCODE_UTIL+=$(ROOTPATH)/chips/p9/procedures/hwp/customize/ +lib$(PROCEDURE)_DEPLIBS += p9_scan_ring_util lib$(PROCEDURE)_DEPLIBS += p9_xip_image lib$(PROCEDURE)_DEPLIBS += p9_tor lib$(PROCEDURE)_DEPLIBS += p9_ringId diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.C b/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.C new file mode 100644 index 000000000..7f6366f31 --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.C @@ -0,0 +1,774 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#include "p9_scan_ring_util.H" +#include "p9_hcode_image_defines.H" +#include <fapi2.H> +#include <stdio.h> +/// +/// @file p9_scan_ring_util.C +/// @brief utility classes and functions for scan ring debug. +/// +/// *HWP HWP Owner: Greg Still <stillgs@us.ibm.com> +/// *HWP FW Owner: Prem S Jha <premjha2@in.ibm.com> +/// *HWP Team: PM +/// *HWP Level: 2 +/// *HWP Consumed by: Hostboot:Phyp:Cro +// + +namespace p9_hcodeImageBuild +{ +/** + * @brief some local constants. + */ +enum +{ + TEMP_MAX_QUAD_CMN_RINGS = 0x50, + TEMP_MAX_QUAD_SPEC_RINGS = 0x10, + TEMP_MAX_CORE_CMN_RINGS = 0x08, + TEMP_MAX_CORE_SPEC_RINGS = 0x04, +}; + +bool operator < ( const RingProfile& i_lhsRing, const RingProfile& i_rhsRing ) +{ + bool l_state = false; + + if( i_lhsRing.iv_ringId < i_rhsRing.iv_ringId ) + { + l_state = true; + } + else if( i_lhsRing.iv_ringId == i_rhsRing.iv_ringId ) + { + if( i_lhsRing.iv_chipletPos < i_rhsRing.iv_chipletPos ) + { + l_state = true; + } + } + + return l_state; +} + +bool operator == ( const RingProfile& i_lhsRing, const RingProfile& i_rhsRing ) +{ + bool l_state = false; + + if( i_lhsRing.iv_ringId == i_rhsRing.iv_ringId ) + { + if( i_lhsRing.iv_chipletPos == i_rhsRing.iv_chipletPos ) + { + l_state = true; + } + } + + return l_state; +} + +RingName::RingName( char* i_char ) +{ + uint32_t strlength = strlen(i_char); + strlength = strlength > 40 ? 40 : strlength; + memset( iv_ringStr, 0, 40); + memcpy( iv_ringStr, i_char, strlength ); +} + +char* RingName::c_str() +{ + char* pStrName = &iv_ringStr[0]; + return pStrName ; +} + +void getScanRing( void* o_pRingBuffer, uint32_t& o_size, + uint32_t i_ringId, PlatId i_plat ) +{ + FAPI_DBG("> getScanRing Plat %s", (i_plat == PLAT_SGPE) ? "SGPE" : "CME"); +#ifdef __CRONUS_VER + + do + { + FILE* fpFakeRing = fopen( "../../output/gen/fake_ring.bin", "r" ); + + if( !fpFakeRing ) + { + FAPI_ERR("Failed to open fake ring file"); + break; + } + + fseek( fpFakeRing, ( sizeof( FakeRing ) * i_ringId ), SEEK_SET ); + fread( (uint8_t*)o_pRingBuffer, sizeof(char), sizeof(FakeRing), fpFakeRing ); + o_size = sizeof( FakeRing ); + + } + while(0); + +#endif + FAPI_DBG("< getScanRing"); +} +//------------------------------------------------------------------------- + +RingBucket::RingBucket( PlatId i_plat, uint8_t* i_pRingStart, RingDebugMode_t i_debugMode ) +{ + iv_pRingStart = i_pRingStart; + iv_plat = i_plat; + iv_debugMode = i_debugMode; + + uint32_t ringIndex = 0; + + if( PLAT_SGPE == i_plat ) + { + RingProfile l_quadCmnRings[TEMP_MAX_QUAD_CMN_RINGS] = + { + { eq_fure, 0, 0 }, + { eq_gptr, 0, 0 }, + { eq_time, 0, 0 }, + { eq_mode, 0, 0 }, + { ex_l3_fure, 0, 0 }, + { ex_l3_gptr, 0, 0 }, + { ex_l3_time, 0, 0 }, + { ex_l2_mode, 0, 0 }, + { ex_l2_fure, 0, 0 }, + { ex_l2_gptr, 0, 0 }, + { ex_l2_time, 0, 0 }, + { ex_l3_refr_fure, 0, 0 }, + { ex_l3_refr_gptr, 0, 0 }, + { eq_ana_func, 0, 0 }, + { eq_ana_gptr, 0, 0 }, + { eq_dpll_func, 0, 0 }, + { eq_dpll_gptr, 0, 0 }, + { eq_dpll_mode, 0, 0 }, + { eq_ana_bndy_bucket_0, 0, 0 }, + { eq_ana_bndy_bucket_1, 0, 0 }, + { eq_ana_bndy_bucket_2, 0, 0 }, + { eq_ana_bndy_bucket_3, 0, 0 }, + { eq_ana_bndy_bucket_4, 0, 0 }, + { eq_ana_bndy_bucket_5, 0, 0 }, + { eq_ana_bndy_bucket_6, 0, 0 }, + { eq_ana_bndy_bucket_7, 0, 0 }, + { eq_ana_bndy_bucket_8, 0, 0 }, + { eq_ana_bndy_bucket_9, 0, 0 }, + { eq_ana_bndy_bucket_10, 0, 0 }, + { eq_ana_bndy_bucket_11, 0, 0 }, + { eq_ana_bndy_bucket_12, 0, 0 }, + { eq_ana_bndy_bucket_13, 0, 0 }, + { eq_ana_bndy_bucket_14, 0, 0 }, + { eq_ana_bndy_bucket_15, 0, 0 }, + { eq_ana_bndy_bucket_16, 0, 0 }, + { eq_ana_bndy_bucket_17, 0, 0 }, + { eq_ana_bndy_bucket_18, 0, 0 }, + { eq_ana_bndy_bucket_19, 0, 0 }, + { eq_ana_bndy_bucket_20, 0, 0 }, + { eq_ana_bndy_bucket_21, 0, 0 }, + { eq_ana_bndy_bucket_22, 0, 0 }, + { eq_ana_bndy_bucket_23, 0, 0 }, + { eq_ana_bndy_bucket_24, 0, 0 }, + { eq_ana_bndy_bucket_25, 0, 0 }, + { eq_ana_bndy_l3dcc_bucket_26, 0, 0 }, + { eq_ana_mode, 0, 0 }, + }; + + RingProfile l_quadSpecRings[TEMP_MAX_QUAD_SPEC_RINGS * MAX_CACHE_CHIPLET] = + { + { eq_repr, 0x10 }, + { ex_l3_repr, 0x10 }, + { ex_l3_repr, 0x11 }, + { ex_l2_repr, 0x10 }, + { ex_l2_repr, 0x11 }, + { ex_l3_refr_repr, 0x10 }, + { ex_l3_refr_repr, 0x11 }, + { ex_l3_refr_time, 0x10 }, + { ex_l3_refr_time, 0x11 }, + + { eq_repr, 0x11 }, + { ex_l3_repr, 0x12 }, + { ex_l3_repr, 0x13 }, + { ex_l2_repr, 0x12 }, + { ex_l2_repr, 0x13 }, + { ex_l3_refr_repr, 0x12 }, + { ex_l3_refr_repr, 0x13 }, + { ex_l3_refr_time, 0x12 }, + { ex_l3_refr_time, 0x13 }, + + { eq_repr, 0x12 }, + { ex_l3_repr, 0x14 }, + { ex_l3_repr, 0x15 }, + { ex_l2_repr, 0x14 }, + { ex_l2_repr, 0x15 }, + { ex_l3_refr_repr, 0x14 }, + { ex_l3_refr_repr, 0x15 }, + { ex_l3_refr_time, 0x14 }, + { ex_l3_refr_time, 0x15 }, + + { eq_repr, 0x13 }, + { ex_l3_repr, 0x16 }, + { ex_l3_repr, 0x17 }, + { ex_l2_repr, 0x16 }, + { ex_l2_repr, 0x17 }, + { ex_l3_refr_repr, 0x16 }, + { ex_l3_refr_repr, 0x17 }, + { ex_l3_refr_time, 0x16 }, + { ex_l3_refr_time, 0x17 }, + + { eq_repr, 0x14 }, + { ex_l3_repr, 0x18 }, + { ex_l3_repr, 0x19 }, + { ex_l2_repr, 0x18 }, + { ex_l2_repr, 0x19 }, + { ex_l3_refr_repr, 0x18 }, + { ex_l3_refr_repr, 0x19 }, + { ex_l3_refr_time, 0x18 }, + { ex_l3_refr_time, 0x19 }, + + { eq_repr, 0x15 }, + { ex_l3_repr, 0x20 }, + { ex_l3_repr, 0x21 }, + { ex_l2_repr, 0x20 }, + { ex_l2_repr, 0x21 }, + { ex_l3_refr_repr, 0x20 }, + { ex_l3_refr_repr, 0x21 }, + { ex_l3_refr_time, 0x20 }, + { ex_l3_refr_time, 0x21 }, + + }; + + for( ringIndex = 0; ringIndex < EQ::g_eqData.iv_num_common_rings; ringIndex++ ) + { + iv_cmnRingMap[ringIndex] = l_quadCmnRings[ringIndex]; + } + + for( ringIndex = 0; ringIndex < ( EQ::g_eqData.iv_num_instance_rings_scan_addrs * MAX_CACHE_CHIPLET ); + ringIndex++ ) + { + iv_instRingMap[ringIndex] = l_quadSpecRings[ringIndex]; + } + + iv_ringName[ eq_fure ] = (char*)"eq_fure "; + iv_ringName[ eq_gptr ] = (char*)"eq_gptr "; + iv_ringName[ eq_time ] = (char*)"eq_time "; + iv_ringName[ eq_mode ] = (char*)"eq_mode "; + iv_ringName[ eq_fure ] = (char*)"eq_fure "; + iv_ringName[ eq_gptr ] = (char*)"eq_gptr "; + iv_ringName[ eq_time ] = (char*)"eq_time "; + iv_ringName[ ex_l3_fure ] = (char*)"ex_l3_fure "; + iv_ringName[ ex_l3_gptr ] = (char*)"ex_l3_gptr "; + iv_ringName[ ex_l3_time ] = (char*)"ex_l3_time "; + iv_ringName[ ex_l2_mode ] = (char*)"ex_l2_mode "; + iv_ringName[ ex_l2_fure ] = (char*)"ex_l2_fure "; + iv_ringName[ ex_l2_gptr ] = (char*)"ex_l2_gptr "; + iv_ringName[ ex_l2_time ] = (char*)"ex_l2_time "; + iv_ringName[ ex_l3_refr_fure ] = (char*)"ex_l3_refr_fure "; + iv_ringName[ ex_l3_refr_gptr ] = (char*)"ex_l3_refr_gptr "; + iv_ringName[ eq_ana_func ] = (char*)"eq_ana_func "; + iv_ringName[ eq_ana_gptr ] = (char*)"eq_ana_gptr "; + iv_ringName[ eq_dpll_func ] = (char*)"eq_dpll_func "; + iv_ringName[ eq_dpll_gptr ] = (char*)"eq_dpll_gptr "; + iv_ringName[ eq_dpll_mode ] = (char*)"eq_dpll_mode "; + iv_ringName[ eq_ana_bndy_bucket_0 ] = (char*)"eq_ana_bndy_bucket_0"; + iv_ringName[ eq_ana_bndy_bucket_1 ] = (char*)"eq_ana_bndy_bucket_1"; + iv_ringName[ eq_ana_bndy_bucket_2 ] = (char*)"eq_ana_bndy_bucket_2"; + iv_ringName[ eq_ana_bndy_bucket_3 ] = (char*)"eq_ana_bndy_bucket_3"; + iv_ringName[ eq_ana_bndy_bucket_4 ] = (char*)"eq_ana_bndy_bucket_4"; + iv_ringName[ eq_ana_bndy_bucket_5 ] = (char*)"eq_ana_bndy_bucket_5"; + iv_ringName[ eq_ana_bndy_bucket_6 ] = (char*)"eq_ana_bndy_bucket_6"; + iv_ringName[ eq_ana_bndy_bucket_7 ] = (char*)"eq_ana_bndy_bucket_7"; + iv_ringName[ eq_ana_bndy_bucket_8 ] = (char*)"eq_ana_bndy_bucket_8"; + iv_ringName[ eq_ana_bndy_bucket_9 ] = (char*)"eq_ana_bndy_bucket_9"; + iv_ringName[ eq_ana_bndy_bucket_10 ] = (char*)"eq_ana_bndy_bucket_10"; + iv_ringName[ eq_ana_bndy_bucket_11 ] = (char*)"eq_ana_bndy_bucket_11"; + iv_ringName[ eq_ana_bndy_bucket_12 ] = (char*)"eq_ana_bndy_bucket_12"; + iv_ringName[ eq_ana_bndy_bucket_13 ] = (char*)"eq_ana_bndy_bucket_13"; + iv_ringName[ eq_ana_bndy_bucket_14 ] = (char*)"eq_ana_bndy_bucket_14"; + iv_ringName[ eq_ana_bndy_bucket_15 ] = (char*)"eq_ana_bndy_bucket_15"; + iv_ringName[ eq_ana_bndy_bucket_16 ] = (char*)"eq_ana_bndy_bucket_16"; + iv_ringName[ eq_ana_bndy_bucket_17 ] = (char*)"eq_ana_bndy_bucket_17"; + iv_ringName[ eq_ana_bndy_bucket_18 ] = (char*)"eq_ana_bndy_bucket_18"; + iv_ringName[ eq_ana_bndy_bucket_19 ] = (char*)"eq_ana_bndy_bucket_19"; + iv_ringName[ eq_ana_bndy_bucket_20 ] = (char*)"eq_ana_bndy_bucket_20"; + iv_ringName[ eq_ana_bndy_bucket_21 ] = (char*)"eq_ana_bndy_bucket_21"; + iv_ringName[ eq_ana_bndy_bucket_22 ] = (char*)"eq_ana_bndy_bucket_22"; + iv_ringName[ eq_ana_bndy_bucket_23 ] = (char*)"eq_ana_bndy_bucket_23"; + iv_ringName[ eq_ana_bndy_bucket_24 ] = (char*)"eq_ana_bndy_bucket_24"; + iv_ringName[ eq_ana_bndy_bucket_25 ] = (char*)"eq_ana_bndy_bucket_25"; + iv_ringName[ eq_ana_bndy_l3dcc_bucket_26 ] = (char*)"eq_ana_bndy_l3dcc_bucket_26"; + iv_ringName[ eq_ana_mode ] = (char*)"eq_ana_mode "; + iv_ringName[ eq_repr ] = (char*)"eq_repr "; + iv_ringName[ ex_l3_repr ] = (char*)"ex_l3_repr "; + iv_ringName[ ex_l2_repr ] = (char*)"ex_l2_repr "; + iv_ringName[ ex_l3_refr_repr ] = (char*)"ex_l3_refr_repr "; + iv_ringName[ ex_l3_refr_time ] = (char*)"ex_l3_refr_time "; + } + else if( PLAT_CME == i_plat ) + { + RingProfile l_coreCmnRings[TEMP_MAX_CORE_CMN_RINGS] = + { + { ec_func, 0, 0 }, + { ec_gptr, 0, 0 }, + { ec_time, 0, 0 }, + { ec_mode, 0, 0 }, + }; + + RingProfile l_coreSpecRings[TEMP_MAX_CORE_SPEC_RINGS * MAX_CORES_PER_CHIP] = + { + { ec_repr, 0 }, + { ec_repr, 1 }, + { ec_repr, 2 }, + { ec_repr, 3 }, + { ec_repr, 4 }, + { ec_repr, 5 }, + { ec_repr, 6 }, + { ec_repr, 7 }, + { ec_repr, 8 }, + { ec_repr, 9 }, + { ec_repr, 10 }, + { ec_repr, 11}, + { ec_repr, 12 }, + { ec_repr, 13 }, + { ec_repr, 14 }, + { ec_repr, 15 }, + { ec_repr, 16 }, + { ec_repr, 17 }, + { ec_repr, 18 }, + { ec_repr, 19 }, + { ec_repr, 20 }, + { ec_repr, 21 }, + { ec_repr, 22 }, + { ec_repr, 23 }, + }; + + for( ringIndex = 0; ringIndex < EC::g_ecData.iv_num_common_rings; ringIndex++ ) + { + iv_cmnRingMap[ringIndex] = l_coreCmnRings[ringIndex]; + } + + for( ringIndex = 0; ringIndex < MAX_CORES_PER_CHIP; + ringIndex++ ) + { + iv_instRingMap[ringIndex] = l_coreSpecRings[ringIndex]; + } + + iv_ringName[ ec_func ] = (char*)"ec_func "; + iv_ringName[ ec_gptr ] = (char*)"ec_gptr "; + iv_ringName[ ec_time ] = (char*)"ec_time "; + iv_ringName[ ec_mode ] = (char*)"ec_mode "; + iv_ringName[ ec_repr ] = (char*)"ec_repr "; + } +} + +//------------------------------------------------------------------------- +RingBucket:: ~RingBucket() +{ +#ifdef __CRONUS_VER + iv_ringName.clear(); +#endif + iv_instRingMap.clear(); + iv_cmnRingMap.clear(); + +} +//------------------------------------------------------------------------- + +RingID RingBucket::getCommonRingId( uint16_t i_ringPos ) +{ + return iv_cmnRingMap[i_ringPos].iv_ringId; // for now not checking validity of pos +} + +//------------------------------------------------------------------------- + +RingID RingBucket::getInstRingId( uint16_t i_ringPos ) +{ + return iv_instRingMap[i_ringPos].iv_ringId; // for now not checking validity of pos +} + +//------------------------------------------------------------------------- + +uint16_t RingBucket::getRingOffset( RingID i_ringId, uint8_t i_chipletPos ) +{ + uint16_t l_ringOffset = 0; + std::map<uint16_t, RingProfile>::iterator it; + + do + { + for( it = iv_cmnRingMap.begin(); it != iv_cmnRingMap.end(); + it++ ) + { + RingProfile l_searchRing( i_ringId, i_chipletPos ); + + if( it->second == l_searchRing ) + { + l_ringOffset = it->second.iv_ringOffset; + break; + } + } + + for( it = iv_instRingMap.begin(); it != iv_instRingMap.end(); + it++ ) + { + RingProfile l_searchRing( i_ringId, i_chipletPos ); + + if( it->second == l_searchRing ) + { + l_ringOffset = it->second.iv_ringOffset; + break; + } + } + + } + while(0); + + return l_ringOffset; +} + +//------------------------------------------------------------------------- + + +void RingBucket::setRingOffset( uint8_t* i_pRingPtr, RingID i_ringId, uint8_t i_chipletPos ) +{ + do + { + std::map<uint16_t, RingProfile>::iterator it; + RingProfile l_searchRing( i_ringId, i_chipletPos ); + + for( it = iv_cmnRingMap.begin(); it != iv_cmnRingMap.end(); + it++ ) + { + if( it->second == l_searchRing ) + { + it->second.iv_ringOffset = i_pRingPtr - iv_pRingStart; + break; + } + } + + for( it = iv_instRingMap.begin(); it != iv_instRingMap.end(); + it++ ) + { + if( it->second == l_searchRing ) + { + it->second.iv_ringOffset = i_pRingPtr - iv_pRingStart; + break; + } + } + } + while(0); +} + +//------------------------------------------------------------------------- + +void RingBucket::initRingBase( uint8_t* i_pRingStart ) +{ + iv_pRingStart = i_pRingStart; +} + +//------------------------------------------------------------------------- +uint16_t RingBucket::getRingSize( RingID i_ringId, uint8_t i_chipletPos ) +{ + std::map<uint16_t, RingProfile>::iterator it = iv_cmnRingMap.begin(); + uint16_t l_ringSize = 0; + RingProfile l_searchRing( i_ringId, i_chipletPos ); + + do + { + for( it = iv_cmnRingMap.begin(); it != iv_cmnRingMap.end(); + it++ ) + { + if( it->second == l_searchRing ) + { + l_ringSize = it->second.iv_ringSize; + break; + } + } + + for( it = iv_instRingMap.begin(); it != iv_instRingMap.end(); + it++ ) + { + if ( it->second == l_searchRing ) + { + l_ringSize = it->second.iv_ringSize; + break; + } + } + + } + while(0); + + return l_ringSize; +} + +//------------------------------------------------------------------------- + +void RingBucket::setRingSize( RingID i_ringId, uint16_t i_ringSize, uint8_t i_chipletPos ) +{ + std::map<uint16_t, RingProfile>::iterator it = iv_cmnRingMap.begin(); + + do + { + RingProfile l_searchRing( i_ringId, i_chipletPos ); + + for( it = iv_cmnRingMap.begin(); it != iv_cmnRingMap.end(); + it++ ) + { + if( it->second == l_searchRing ) + { + it->second.iv_ringSize = i_ringSize; + break; + } + } + + for( it = iv_instRingMap.begin(); it != iv_instRingMap.end(); + it++ ) + { + if( it->second == l_searchRing ) + { + it->second.iv_ringSize = i_ringSize; + break; + } + } + + } + while(0); + +} + +//------------------------------------------------------------------------- + +const char* RingBucket::getRingName( RingID i_ringId ) +{ + const char* pRingName = NULL; + + if( iv_ringName.find(i_ringId) != iv_ringName.end() ) + { + pRingName = ((iv_ringName.find(i_ringId)->second).c_str()); + } + + return pRingName; +} + +//------------------------------------------------------------------------- + +void RingBucket::dumpRings( ) +{ + std::map<RingID, RingName>::iterator it = iv_ringName.begin(); + uint32_t chipletNo = 0; + + do + { + if( SCAN_RING_NO_DEBUG == iv_debugMode ) + { + break; + } + + FAPI_INF("==================================================================================="); + FAPI_INF("==================================================================================="); + + if( iv_plat == PLAT_CME ) + { + FAPI_INF("---------------------------------CME Rings---------------------------------------"); + chipletNo = EC::g_ecData.iv_num_instance_rings_scan_addrs; + } + else if( iv_plat == PLAT_SGPE ) + { + FAPI_INF("---------------------------------SGPE Rings--------------------------------------"); + chipletNo = EQ::g_eqData.iv_num_instance_rings_scan_addrs; + } + else + { + FAPI_INF("---------------------------------Unknown Platform--------------------------------"); + } + + FAPI_INF("-------------------------------------------------------------------------------------"); + FAPI_INF("-------------------------------------------------------------------------------------"); + FAPI_INF("-------------------------------Common Rings------------------------------------------"); + FAPI_INF("Ring Name----------------------Offset----------------------------Size----------------"); + FAPI_INF("====================================================================================="); + FAPI_INF("====================================================================================="); + + for( uint16_t ringIndex = 0; ringIndex < iv_cmnRingMap.size(); + ringIndex++ ) + { + it = iv_ringName.find( iv_cmnRingMap[ringIndex].iv_ringId ); + + if( iv_ringName.end() != it ) + { + FAPI_INF("%s\t\t %08d ( 0x%08x )\t\t%08d ( 0x%08x )", (it->second).c_str(), + iv_cmnRingMap[ringIndex].iv_ringOffset, + iv_cmnRingMap[ringIndex].iv_ringOffset, + iv_cmnRingMap[ringIndex].iv_ringSize, + iv_cmnRingMap[ringIndex].iv_ringSize ); + } + } + + FAPI_INF("====================================================================================="); + FAPI_INF("====================================================================================="); + FAPI_INF("-------------------------------Instance Ring-----------------------------------------"); + FAPI_INF("Ring Name----------------------Offset-------------------------Size-------------------"); + + for( uint16_t ringIndex = 0; ringIndex < iv_instRingMap.size(); + ringIndex++ ) + { + uint32_t chipletIndex = ringIndex % chipletNo; + + if(( 0 == ringIndex ) || ( 0 == chipletIndex )) + { + FAPI_INF("=============================================================================="); + FAPI_INF("=============================================================================="); + FAPI_INF("\t\t%s ( %d )", ( iv_plat == PLAT_CME ) ? "Core" : "Cache", (ringIndex / chipletNo) ); + FAPI_INF("=============================================================================="); + FAPI_INF("=============================================================================="); + } + + it = iv_ringName.find( iv_instRingMap[ringIndex].iv_ringId ); + + if( iv_ringName.end() != it ) + { + FAPI_INF("%s\t %08d ( 0x%08x )\t\t%08d ( 0x%08x )", (it->second).c_str(), + iv_instRingMap[ringIndex].iv_ringOffset, + iv_instRingMap[ringIndex].iv_ringOffset, + iv_instRingMap[ringIndex].iv_ringSize, + iv_instRingMap[ringIndex].iv_ringSize ); + } + } + + FAPI_INF("================================================================================="); + FAPI_INF("================================================================================="); + } + while(0); +} + +//------------------------------------------------------------------------- +void RingBucket::dumpOverrideRings( ) +{ + std::map<RingID, RingName>::iterator it = iv_ringName.begin(); + + do + { + if( SCAN_RING_NO_DEBUG == iv_debugMode ) + { + break; + } + + FAPI_INF("==================================================================================="); + FAPI_INF("==================================================================================="); + + if( iv_plat == PLAT_CME ) + { + FAPI_INF("----------------------------------CME Ring Overrides---------------------------"); + } + else if( iv_plat == PLAT_SGPE ) + { + FAPI_INF("----------------------------------SGPE Rings Overrides-------------------------"); + } + else + { + FAPI_INF("----------------------------------Unknown Platform-----------------------------"); + } + + FAPI_INF("-----------------------------------------------------------------------------------"); + FAPI_INF("-----------------------------------------------------------------------------------"); + FAPI_INF("Ring Name----------------------Offset----------------------------Size--------------"); + FAPI_INF("==================================================================================="); + FAPI_INF("==================================================================================="); + + for( uint16_t ringIndex = 0; ringIndex < iv_cmnRingMap.size(); + ringIndex++ ) + { + it = iv_ringName.find( iv_cmnRingMap[ringIndex].iv_ringId ); + + if( iv_ringName.end() != it ) + { + FAPI_INF("%s\t %08d ( 0x%08x )\t\t%08d ( 0x%08x )", (it->second).c_str(), + iv_cmnRingMap[ringIndex].iv_ringOffset, + iv_cmnRingMap[ringIndex].iv_ringOffset, + iv_cmnRingMap[ringIndex].iv_ringSize, + iv_cmnRingMap[ringIndex].iv_ringSize ); + } + } + + FAPI_INF("==============================================================================="); + FAPI_INF("==============================================================================="); + + } + while(0); +} +//------------------------------------------------------------------------- + +P9FuncModel::P9FuncModel( ): + iv_funcCores(0), + iv_funcExes(0), + iv_funcQuads(0), + iv_ddLevel(0) +{ } +//------------------------------------------------------------------------- + +P9FuncModel::P9FuncModel( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP >& i_procTgt , uint8_t i_ddLevel ) +{ + iv_funcCores = 0; + iv_funcExes = 0; + iv_funcQuads = 0; + iv_ddLevel = i_ddLevel; + + auto l_core_functional_vector = + i_procTgt.getChildren<fapi2::TARGET_TYPE_CORE>(fapi2::TARGET_STATE_FUNCTIONAL); + uint8_t l_corePos = 0; + + for( auto it : l_core_functional_vector ) + { + FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS, it, l_corePos ); + FAPI_DBG("functional cores id %d", l_corePos ); + iv_funcCores = iv_funcCores | (1 << l_corePos ); + iv_funcExes = iv_funcExes | (1 << (l_corePos >> 1) ); + iv_funcQuads = iv_funcQuads | (1 << (l_corePos >> 2) ); + } +} + +//--------------------------------------------------------------------------- + +P9FuncModel::~P9FuncModel() +{ + FAPI_DBG("Destroyed P9FuncModel"); +} + +//--------------------------------------------------------------------------- + +bool P9FuncModel::isCoreFunctional( uint32_t i_corePos ) const +{ + return ( (iv_funcCores & ( 1 << i_corePos )) != 0 ); +} + +//------------------------------------------------------------------------- + +bool P9FuncModel::isExFunctional( uint32_t i_exPos ) const +{ + return ( (iv_funcExes & ( 1 << i_exPos )) != 0 ); +} + +//------------------------------------------------------------------------- + +bool P9FuncModel::isQuadFunctional( uint32_t i_quadPos ) const +{ + return ( (iv_funcQuads & ( 1 << i_quadPos )) != 0 ); +} + +//------------------------------------------------------------------------- +uint8_t P9FuncModel::getChipLevel() const +{ + return iv_ddLevel; +} + +} diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.H b/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.H new file mode 100644 index 000000000..73a2b7578 --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.H @@ -0,0 +1,326 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __P9_SCAN_RING_UTIL_H +#define __P9_SCAN_RING_UTIL_H + +#include <fapi2.H> +#include "p9_ringId.H" +#include "p9_stop_util.H" +#include <map> + +//#define __CRONUS_VER +/// +/// @file p9_scan_ring_util.H +/// @brief utility classes and functions for scan ring debug. +/// +/// *HWP HWP Owner: Greg Still <stillgs@us.ibm.com> +/// *HWP FW Owner: Prem S Jha <premjha2@in.ibm.com> +/// *HWP Team: PM +/// *HWP Level: 2 +/// *HWP Consumed by: Hostboot:Phyp:Cro +// + +namespace p9_hcodeImageBuild +{ + +/** + * @brief enumerates all the platforms associated with hcode image build. + */ +enum PlatId +{ + PLAT_SELF = 0, + PLAT_SGPE = 1, + PLAT_CME = 2, + PLAT_PGPE = 3, +}; + +/** + * @brief constants associated with fake scan rings. + */ +enum FakeScanRing_t +{ + SCAN_RNG_START = 0x5363616e20526e67, + SCAN_RNG_END = 0x52696e6720456e64, + MAX_SCAN_RING_SIZE = 120, + MAX_FAKE_CMN_RING = 0x14, + MAX_FAKE_RING = 0x1E, +}; + +/** + * @brief debug modes supported for scan rings. + */ +enum RingDebugMode_t +{ + SCAN_RING_NO_DEBUG = 0x00, + SCAN_RING_TRACE_DEBUG = 0x01, +}; +/** + * @brief models a fake ring for debug. + */ +struct FakeRing +{ + uint64_t iv_ringHeader; + uint64_t iv_ringNumber; + uint8_t iv_ringPayload[MAX_SCAN_RING_SIZE]; + uint64_t iv_ringEnd; + +#ifdef __CRONUS_VER + FakeRing( uint8_t i_ringNumber ): + iv_ringHeader( SWIZZLE_8_BYTE(SCAN_RNG_START) ), + iv_ringEnd(SWIZZLE_8_BYTE(SCAN_RNG_END)) + { + memset( &iv_ringPayload, 0xAA, MAX_SCAN_RING_SIZE ); + uint8_t temp1 = i_ringNumber / 100; + temp1 = temp1 + 0x30; + iv_ringNumber = temp1 << 16; + temp1 = i_ringNumber % 100; + iv_ringNumber |= (( temp1 / 10) + 0x30 ) << 8; + iv_ringNumber |= ((temp1 % 10) + 0x30 ); + iv_ringNumber = SWIZZLE_8_BYTE(iv_ringNumber); + } +#else + FakeRing( uint8_t i_ringNumber ): + iv_ringHeader( 0 ), + iv_ringEnd( 0) + { + //dummy constructor to avoid compilation issue + memset( &iv_ringPayload, 0xAA, MAX_SCAN_RING_SIZE ); + } +#endif +}; + +class RingName +{ + public: + /** + * @brief constructor + * @param i_ringName name associated with the a scan ring. + * @param i_debugMode debug mode. + */ + RingName( char* i_ringName ); + + /** + * @brief constructor + */ + RingName() {}; + + /** + * @brief destructor + */ + ~RingName() {}; + + /** + * @brief returns string Name. + */ + char* c_str(); + private: + char iv_ringStr[40]; +}; + +/** + * @brief models the profile of a scan ring for debug. + */ +struct RingProfile +{ + RingID iv_ringId; + uint32_t iv_ringOffset; + uint32_t iv_ringSize; + uint32_t iv_chipletPos; + + RingProfile ( RingID i_ringId, uint16_t i_ringOffset, uint16_t i_ringSize ) : + iv_ringId( i_ringId ), + iv_ringOffset( i_ringOffset ), + iv_ringSize( i_ringSize ), + iv_chipletPos( 0 ) + { } + + RingProfile ( RingID i_ringId, uint8_t i_chipletPos ) : + iv_ringId( i_ringId ), + iv_ringOffset( 0 ), + iv_ringSize( 0 ), + iv_chipletPos( i_chipletPos ) + { } + + RingProfile(): + iv_ringId(eq_fure), + iv_ringOffset(0), + iv_ringSize(0) + {} +}; + +/** + * @brief populates an input buffer with a fake scan ring. + * @param o_pRingBuffer rings in which scan rings are copied. + * @param o_size size of scan ring. + * @param i_ringId scan ring id. + * @param i_plat platform associated with scan ring. + */ +void getScanRing( void* o_pRingBuffer, uint32_t& o_size, + uint32_t i_ringId, PlatId i_plat ); + +/** + * @brief class to suppport debug of scan ring layout in P9 HOMER + * @note Intended platform is cronus. + */ +class RingBucket +{ + public: + /** + * @brief constructor + */ + RingBucket( PlatId i_plat, uint8_t* i_pRingStart, RingDebugMode_t i_debugMode ); + + /** + * @brief destructor + */ + ~RingBucket(); + /** + * @brief returns the id of common ring from storage index. + * @param i_ringPos storage position of ring. + * @return scan ring id. + */ + RingID getCommonRingId( uint16_t i_ringPos ); + + /** + * @brief returns the id of chiplet instance specific ring from storage index. + * @param i_ringPos storage position of ring. + * @return scan ring id. + */ + RingID getInstRingId ( uint16_t i_ringPos ); + + /** + * @brief returns the offset associated with scan ring of given id. + * @param i_ringId Id associated with a scan ring. + * @param SUCCESS for successful operation erro code otherwise. + * @return offset associated with a given ring. + */ + uint16_t getRingOffset( RingID i_ringId, uint8_t i_chipletPos = 0 ); + + /** + * @brief sets the offset associated with scan ring of given id. + * @param i_pRingPtr points to start of scan ring. + * @param i_ringId Id associated with a scan ring. + * @param SUCCESS for successful operation, error code otherwise. + */ + void setRingOffset( uint8_t* i_pRingPtr, RingID i_ringId, uint8_t i_chipletPos = 0 ); + + /** + * @brief sets base of a ring associated with a given platform. + * @param i_ringPos points to start of ring index of CME/SGPE + */ + void initRingBase( uint8_t* i_pRingStart ); + + /** + * @brief sets size of a given scan ring. + * @param i_ringId Id associated with a given scan ring. + * @param i_ringSize size of scan ring. + */ + void setRingSize( RingID i_ringId, uint16_t i_ringSize, uint8_t i_chipletPos = 0 ); + + /** + * @brief returns size of a given scan ring. + * @param i_ringId Id associated with a given scan ring. + * @return size of a given scan ring. + */ + uint16_t getRingSize( RingID i_ringId, uint8_t i_chipletPos = 0 ); + + /** + * @brief returns name of scan ring associated with given id. + * @param i_ringId Id associated with a given scan ring. + * @return size of a given scan ring. + */ + const char* getRingName( RingID i_ringId ); + + /** + * @brief generates a report on layout of CME/SGPE scan rings in HOMER. + */ + void dumpRings( ); + + /** + * @brief generates a report on layout of CME/SGPE scan ring overrides in HOMER. + */ + void dumpOverrideRings(); + + private: + std::map<uint16_t, RingProfile> iv_cmnRingMap; + std::map<uint16_t, RingProfile> iv_instRingMap; + uint8_t* iv_pRingStart; + uint16_t iv_ringSize; + PlatId iv_plat; + RingDebugMode_t iv_debugMode; + + std::map<RingID, RingName> iv_ringName; +}; + +class P9FuncModel +{ + public: + /** + * @brief constructor + */ + P9FuncModel( const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP >& i_procTgt, + uint8_t i_ddLevel ); + /** + * brief destructor + */ + ~P9FuncModel( ); + + /** + * @brief returns functional state of a given core. + */ + bool isCoreFunctional( uint32_t i_corePos ) const; + + /** + * @brief returns functional state of a given ex. + */ + bool isExFunctional( uint32_t i_exPos ) const; + + /** + * @brief returns functional state of a given quad. + */ + bool isQuadFunctional( uint32_t i_quadPos ) const; + + /** + * @brief returns dd level associated with a processor. + */ + uint8_t getChipLevel() const; + + /** + * @brief constructor + */ + P9FuncModel( ); + + private: + P9FuncModel( const P9FuncModel& ); //Disallow copy constructor + P9FuncModel& operator = ( const P9FuncModel&); // Disallow assignment operator + uint32_t iv_funcCores; + uint16_t iv_funcExes; + uint8_t iv_funcQuads; + uint8_t iv_ddLevel; +}; + +}// namesapce p9_hcodeImageBuild ends + +#endif //__P9_SCAN_RING_UTIL_H diff --git a/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.mk b/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.mk new file mode 100644 index 000000000..a83829a86 --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.mk @@ -0,0 +1,28 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/import/chips/p9/procedures/hwp/pm/p9_scan_ring_util.mk $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2016 +# [+] International Business Machines Corp. +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. +# +# IBM_PROLOG_END_TAG +HCODE_UTIL+=$(ROOTPATH)/chips/p9/procedures/hwp/lib/ +PROCEDURE = p9_scan_ring_util +$(call ADD_MODULE_INCDIR,$(PROCEDURE),$(HCODE_UTIL)) +$(call BUILD_PROCEDURE) |