diff options
author | Prem Shanker Jha <premjha2@in.ibm.com> | 2016-05-27 02:21:29 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-06-21 11:47:23 -0400 |
commit | f5136b83799b518042f73ff56424fa1fe809e0df (patch) | |
tree | 9e1e5b1d5fb0ec7bebd49d5a5eb69c51ceb3efe7 /src/import/chips | |
parent | 312020362421d107c3e2886168f30ebf6b91ade2 (diff) | |
download | talos-hostboot-f5136b83799b518042f73ff56424fa1fe809e0df.tar.gz talos-hostboot-f5136b83799b518042f73ff56424fa1fe809e0df.zip |
PM:Revised hcode image build.
- Extracts PGPE Hcode from hw image.
- Extracts base and override scan rings using TOR API.
- Endianess correction for cronus use case.
- Generates of standalone binaries associated with various regions of HOMER.
- Generates hardware image binary.
- Additional debug traces to aid veririfcation.
- Code refactoring
Change-Id: I86a707d90c2d0eb56f2637e8c5caff79ff3fff75
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/25109
Tested-by: Jenkins Server
Reviewed-by: Gregory S. Still <stillgs@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Tested-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/25119
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips')
8 files changed, 1675 insertions, 344 deletions
diff --git a/src/import/chips/p9/procedures/hwp/lib/p9_hcd_header_defs.H b/src/import/chips/p9/procedures/hwp/lib/p9_hcd_header_defs.H new file mode 100644 index 000000000..3932883c7 --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/lib/p9_hcd_header_defs.H @@ -0,0 +1,150 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: chips/p9/procedures/hwp/lib/p9_hcd_header_defs.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* EKB Project */ +/* */ +/* COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// +/// @file p9_occ_sram_defs.H +/// @brief Constants defining the layout of the OCC SRAM +/// +/// This header contains those cpp manifest constants required for processing +/// the linker scripts used to generate OCC code images. As these are used +/// by linker scripts as well as by C++ code, these cannot be solely be put +/// into a namespace. Prefixing these with the region name is the attempt +/// to make these globally unique when this header is included in C++ code. +/// +// *HWP HWP Owner: Greg Still <stillgs@us.ibm.com> +// *HWP FW Owner: Prem Jha <premjha2@in.ibm.com> +// *HWP Team: PM +// *HWP Level: 2 +// *HWP Consumed by: PM +// + +#ifndef __HCD_HEADER_DEFS_H__ +#define __HCD_HEADER_DEFS_H__ + +/// Macros for generating an Hcode header section +/// +/// The CPP macros HCD_HDR_UINTxx generate equivalent code depending on +/// whether they are being called from assembler (where they actually +/// create the header section data) or from C (where they specifiy a +/// C-structure form of the contents of the header section. +/// +/// In assembler each invocation also creates space in the header section + +#ifdef __ASSEMBLER__ + +// *INDENT-OFF* + .macro hcd_header_uint64, symbol:req, value = 0 + .global \symbol +\symbol\(): + .quad (\value) + .endm + + .macro hcd_header_uint32, symbol:req, value = 0 + .global \symbol + \symbol\(): + .long (\value) + .endm + + .macro hcd_header_uint16, symbol:req, value = 0 + .global \symbol +\symbol\(): + .short (\value) + .endm + + .macro hcd_header_uint8, symbol:req, value = 0 + .global \symbol +\symbol\(): + .byte (\value) + .endm + + .macro hcd_header_uint8_vec, symbol:req, number:req, value = 0 + .global \symbol +\symbol\(): + .rept (\number) + .byte (\value) + .endr + .endm + + .macro hcd_header_attn, symbol:req, number = 1 + .global \symbol +\symbol\(): + .rept (\number) + .long 0x00000200 + .endr + .endm + + .macro hcd_header_attn_pad, align:req + .balignl (\align), 0x00000200 + .endm + + .macro hcd_header_pad, align:req + .balignl (\align), 0 + .endm +// *INDENT-ON* + +#undef CONST_UINT8_T +#undef CONST_UINT32_T +#undef CONST_UINT64_T + +#define CONST_UINT8_T(name, expr) .set name, expr +#define CONST_UINT16_T(name, expr) .set name, expr +#define CONST_UINT32_T(name, expr) .set name, expr +#define CONST_UINT64_T(name, expr) .set name, expr + +#define ULL(x) x + +#define HCD_HDR_UINT64(symbol, value) hcd_header_uint64 symbol value +#define HCD_HDR_UINT32(symbol, value) hcd_header_uint32 symbol value +#define HCD_HDR_UINT16(symbol, value) hcd_header_uint16 symbol value +#define HCD_HDR_UINT8(symbol, value) hcd_header_uint8 symbol value +#define HCD_HDR_UINT8_VEC(symbol, number, value) hcd_header_uint8_vec symbol number value + +#define HCD_HDR_ATTN(symbol, number) hcd_header_attn symbol number +#define HCD_HDR_ATTN_PAD(align) hcd_header_attn_pad align +#define HCD_HDR_PAD(align) hcd_header_pad align +#define HCD_MAGIC_NUMBER(symbol, value) .set symbol, value + +#else // __ASSEMBLER__ + +#undef CONST_UINT8_T +#undef CONST_UINT32_T +#undef CONST_UINT64_T + +#define CONST_UINT8_T(name, expr) static const uint8_t name = expr; +#define CONST_UINT16_T(name, expr) static const uint16_t name = expr; +#define CONST_UINT32_T(name, expr) static const uint32_t name = expr; +#define CONST_UINT64_T(name, expr) static const uint64_t name = expr; + +#define ULL(x) x##ull + +#define HCD_HDR_UINT64(symbol, value) uint64_t symbol +#define HCD_HDR_UINT32(symbol, value) uint32_t symbol +#define HCD_HDR_UINT16(symbol, value) uint16_t symbol +#define HCD_HDR_UINT8(symbol, value) uint8_t symbol +#define HCD_HDR_UINT8_VEC(symbol, number, value) uint8_t symbol[number] +#define HCD_HDR_ATTN(symbol, number) uint32_t symbol[number] +#define HCD_HDR_ATTN_PAD(align) +#define HCD_HDR_PAD(align) +#define HCD_MAGIC_NUMBER(symbol, value) static const uint64_t symbol = value + +#endif // __ASSEMBLER__ + +#define STR_HELPER(x) #x +#define STR(x) STR_HELPER(x) + +#endif // __HCD_HEADER_DEFS_H__ 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 5cd3daf6a..3a8bdeb3d 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 @@ -16,9 +16,6 @@ /* deposited with the U.S. Copyright Office. */ /* */ /* IBM_PROLOG_END_TAG */ -#ifndef __HW_IMG_DEFINE -#define __HW_IMG_DEFINE - /// /// @file p9_hcode_image_defines.H /// @brief defines constants associated with hcode image build. @@ -28,6 +25,12 @@ // *HWP Team: PM // *HWP Level: 2 // *HWP Consumed by: Hostboot: Phyp + +#ifndef __HW_IMG_DEFINE +#define __HW_IMG_DEFINE + + +#include <p9_hcd_header_defs.H> //-------------------------------------------------------------------------- // local structs and constants // ------------------------------------------------------------------------- @@ -47,64 +50,74 @@ enum ONE_MB = 1024 * 1024, HARDWARE_IMG_SIZE = ONE_MB, OCC_HOST_AREA_SIZE = ONE_MB, + HOMER_OCC_REGION_NUM = 0, + HOMER_QPMR_REGION_NUM = 1, + HOMER_CMPR_REGION_NUM = 2, + HOMER_PPMR_REGION_NUM = 3, MAX_CORES_PER_CHIP = 24, + MAX_CME_PER_CHIP = 12, + CORE0_CHIPLET_ID = 0x20, PAD_OPCODE = 0x00000200, //ATTN Opcode PPE_RESERVE_AREA = 0x200, - QPMR_HEADER_SIZE = 0x00000200, + FUSE_STATE = 0xAA, + UNFUSE_STATE = 0xBB, + + // QPMR + QPMR_OFFSET = HOMER_QPMR_REGION_NUM * ONE_MB, SGPE_LVL_1_BOOT_LOAD_SIZE = ONE_KB, SGPE_LVL_2_BOOT_LOAD_SIZE = ONE_KB, SGPE_INT_VECT = 384, SGPE_IMG_HEADER = 64, - SGPE_DBG_PTR_AREA_SIZE = 64, - CME_HCODE_REL_OFFSET = (SGPE_INT_VECT + - SGPE_IMG_HEADER + - SGPE_DBG_PTR_AREA_SIZE), - SGPE_HCODE_SIZE = 30 * ONE_KB, + SGPE_DBG_PTR_AREA_SIZE = 36, + SGPE_HCODE_SIZE = 40 * ONE_KB, // FIXME RTC 155018 Revisit after Hcode optimization SGPE_COMMON_RING = 2 * ONE_KB, CACHE_SCOM_RESTORE_SIZE = 6 * ONE_KB, CACHE_INST_SPECIFIC_SIZE = 4 * ONE_KB, MAX_CACHE_CHIPLET = 6, + CACH0_CHIPLET_ID = 0x10, + SGPE_MAX_AREA_SIZE = 64 * ONE_KB, - CPMR_HEADER_SIZE = 256, + SGPE_RESV_CMN_RING = 8, + + // CPMR + CPMR_OFFSET = HOMER_CMPR_REGION_NUM * ONE_MB, THREAD_LAUNCHER_SIZE = 256, CORE_INT_AREA = 8 * ONE_KB, SELF_REST_SIZE = CORE_INT_AREA + THREAD_LAUNCHER_SIZE, CORE_RESTORE_SIZE = 192 * ONE_KB, + CORE_SCOM_START = (256 * ONE_KB), CORE_SCOM_RES_SIZE = 6 * ONE_KB, - CME_INT_VECTOR = 384, - CME_IMG_HEADER = 64, - CME_DBG_PTR_AREA_SIZE = 64, - CME_HCODE_SIZE = 20 * ONE_KB, + CME_INT_VECTOR_SIZE = 384, + CME_IMG_HEADER_SIZE = 64, + CPMR_CME_HCODE_OFFSET = (CORE_SCOM_START + CORE_SCOM_RES_SIZE), + CME_HCODE_SIZE = 32 * ONE_KB, ////FIXME RTC 155018 Revisit after Hcode size optimization CORE_COMMON_RING_SIZE = 6 * ONE_KB, - QUAD_PSTATE_SIZE = 2 * ONE_KB, CORE_SPECIFIC_RING = 2 * ONE_KB, - CORE_SCOM_START = 256 * ONE_KB, + CME_SRAM_HCODE_OFFSET = 0x00, + QUAD_PSTATE_SIZE = 2 * ONE_KB, CORE_RESERVE_SIZE = - CORE_SCOM_START - ( CORE_RESTORE_SIZE + CORE_INT_AREA + - CME_HCODE_SIZE + CORE_COMMON_RING_SIZE + - QUAD_PSTATE_SIZE + CME_IMG_HEADER ), + CORE_SCOM_START - ( CORE_RESTORE_SIZE + CME_HCODE_SIZE + CORE_COMMON_RING_SIZE + QUAD_PSTATE_SIZE ), - CME_REGION_START = CORE_SCOM_START + CORE_SCOM_RES_SIZE, - CME_INST_SPEC_RING_START = (300 * ONE_KB ) , // offset from CPMR + CME_REGION_START = (CORE_SCOM_START + CORE_SCOM_RES_SIZE), + CME_INST_SPEC_RING_START = (360 * ONE_KB ) , //FIXME RTC 155018 Revisit after Hcode size optimization RESERVE_CME_RING_AREA = ( CME_INST_SPEC_RING_START - ( CME_REGION_START + - PPE_RESERVE_AREA + CME_HCODE_SIZE + CORE_COMMON_RING_SIZE + QUAD_PSTATE_SIZE)), + CME_BLOCK_READ_LEN = 32, + CME_BLK_SIZE_SHIFT = 0x05, + CACHE_SCOM_START = 128 * ONE_KB, + // PPMR + PPMR_OFFSET = HOMER_PPMR_REGION_NUM * ONE_MB, PGPE_LVL_1_BOOT_LOAD_SIZE = ONE_KB, PGPE_LVL_2_BOOT_LOAD_SIZE = ONE_KB, PGPE_IMG_HEADER = 64, // need to get confirmation on this - PGPE_HCODE_INT_VECT = 384, + PGPE_INT_VECTOR = 384, PGPE_HCODE_SIZE = 16 * ONE_KB, PGPE_PARAM_BLOCK_SIZE = 8 * ONE_KB, PSTATE_OUTPUT_TABLE = 8 * ONE_KB, - FUSE_STATE = 0xAA, - UNFUSE_STATE = 0xBB, - CME_BLOCK_READ_LEN = 32, - CACHE_SCOM_START = 128 * ONE_KB, - CPMR_MAGIC_WORD = 0x484F4D4552312E30ll, - CME_BLK_SIZE_SHIFT = 0x05, + IGNORE_CHIPLET_INSTANCE = 0xFF, }; /** @@ -125,196 +138,361 @@ enum ImgBldRetCode_t BUILD_FAIL_SGPE_HCODE = 10, BUILD_FAIL_SGPE_CMN_RINGS = 11, BUILD_FAIL_SGPE_SPEC_RINGS = 12, - BUILD_FAIL_P9_CPMR_HDR = 13, - BUILD_FAIL_P9_SRESET_HNDLR = 14, - BUILD_FAIL_P9_THRD_LAUNCHER = 15, - BUILD_FAIL_P9_SPR_RESTORE = 16, - BUILD_FAIL_P9_SCOM_RESTORE = 17, + BUILD_FAIL_CPMR_HDR = 13, + BUILD_FAIL_SRESET_HNDLR = 14, + BUILD_FAIL_THRD_LAUNCHER = 15, + BUILD_FAIL_SPR_RESTORE = 16, + BUILD_FAIL_SCOM_RESTORE = 17, BUILD_FAIL_CME_IMG_HDR = 18, BUILD_FAIL_CME_HCODE = 19, - BUILD_FAIL_CME_CMN_RINGS = 20, + BUILD_FAIL_CMN_RINGS = 20, BUILD_FAIL_CME_QUAD_PSTATE = 21, - BUILD_FAIL_CME_SPEC_RINGS = 22, - BUILD_FAIL_CME_INT_VECT = 23, + BUILD_FAIL_SPEC_RINGS = 22, + BUILD_FAIL_INT_VECT = 23, + BUILD_FAIL_PGPE_BL1 = 24, + BUILD_FAIL_PGPE_BL2 = 25, + BUILD_FAIL_PGPE_HCODE = 26, + BUILD_FAIL_OVERRIDE = 27, }; +#endif // __ASSEMBLER__ + +// Constants used in both C++ and Assembler/Linker code +CONST_UINT32_T(CPMR_HEADER_SIZE, 256); +CONST_UINT32_T(QPMR_HEADER_SIZE, 512); + +//#pragma message (STR(CPMR_HEADER_SIZE)) + +// Define the Magic Numbers for the various images +HCD_MAGIC_NUMBER(CPMR_MAGIC_NUMBER, ULL(0x43504d525f312e30)); // CPMR_1.0 +HCD_MAGIC_NUMBER(QPMR_MAGIC_NUMBER, ULL(0x51504d525f312e30)); // QPMR_1.0 +HCD_MAGIC_NUMBER(CME_MAGIC_NUMBER , ULL(0x434d455f5f312e30)); // CME__1.0 +HCD_MAGIC_NUMBER(PGPE_MAGIC_NUMBER , ULL(0x504750455F312E30)); // PGPE_1.0 + + +/** + * @brief models QPMR header in HOMER + */ + +#ifdef __ASSEMBLER__ +.macro .qpmr_header +.section ".qpmr" , "aw" +.balign 8 +#else +typedef struct +{ +#endif // __ASSEMBLER__ + +HCD_HDR_UINT64( magic_number, QPMR_MAGIC_NUMBER); // QPMR_1.0 +HCD_HDR_UINT32( bootCopierOffset, 0); // level 1 boot loader +HCD_HDR_UINT32( reserve1, 0); +HCD_HDR_UINT32( bootLoaderOffset, 0); // level 2 boot loader +HCD_HDR_UINT32( bootLoaderLength, 0); +HCD_HDR_UINT32( buildDate, 0); +HCD_HDR_UINT32( buildVersion, 0); +HCD_HDR_UINT64( reservedFlags, 0); +HCD_HDR_UINT32( sgpeImgOffset, 0); +HCD_HDR_UINT32( sgpeImgLength, 0); +HCD_HDR_UINT32( quadCommonRingOffset, 0); +HCD_HDR_UINT32( quadCommonRingLength, 0); +HCD_HDR_UINT32( quadSpecRingOffset, 0); +HCD_HDR_UINT32( quadSpecRingLength, 0); +HCD_HDR_UINT32( quadSpecScomOffset, 0); +HCD_HDR_UINT32( quadSpecScomLength, 0); +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. + + +/** + * CPMR Header + * + * This header is only consumed by Hcode Image Build and + * lab tools, not by PPE code. It is generated with assembler + * primitives during CME build and placed in HOMER by + * Hcode Image Build. + */ + +#ifdef __ASSEMBLER__ +.macro .cpmr_header +.section ".cpmr" , "aw" +.balign 8 +#else +typedef struct +{ +#endif +HCD_HDR_ATTN ( attnOpcodes, 2); +HCD_HDR_UINT64( magic_number, CPMR_MAGIC_NUMBER); // CPMR_1.0 +HCD_HDR_UINT32( cpmrbuildDate, 0); +HCD_HDR_UINT32( cpmrVersion, 0); +HCD_HDR_UINT8_VEC (cpmrReserveFlags, 7, 0); +HCD_HDR_UINT8 ( fuseModeStatus, 0); +HCD_HDR_UINT32( cmeImgOffset, 0); +HCD_HDR_UINT32( cmeImgLength, 0); +HCD_HDR_UINT32( cmeCommonRingOffset, 0); +HCD_HDR_UINT32( cmeCommonRingLength, 0); +HCD_HDR_UINT32( cmePstateOffset, 0); +HCD_HDR_UINT32( cmePstateLength, 0); +HCD_HDR_UINT32( coreSpecRingOffset, 0); +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. + +/** + * SGPE Header + * + * The SGPE header is loaded in the OCC SRAM. Structure member names are + * preceded with "g_" as these becoming global variables in the SGPE Hcode. + * + * The Linker script maps this header to an SRAM address range after interrupt + * vector area. Some fields will be populated during Hcode image build activity. + * Build date, version, Hcode offset and position are populated during SGPE + * Image build process. + */ + +#ifdef __ASSEMBLER__ +.macro .sgpe_header +.section ".sgpe_image_header" , "aw" +.balign 8 +#else +typedef struct +{ +#endif +HCD_HDR_UINT64(g_sgpe_magic_number, P9_XIP_MAGIC_SGPE); //XIP SGPE +HCD_HDR_UINT32(g_sgpe_reset_address, 0); +HCD_HDR_UINT32(g_sgpe_reserve1, 0); +HCD_HDR_UINT32(g_sgpe_ivpr_address, 0); +HCD_HDR_UINT32(g_sgpe_reserve2, 0); +HCD_HDR_UINT32(g_sgpe_build_date, 0); +HCD_HDR_UINT32(g_sgpe_build_ver, 0); +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_reserve3, 0); +HCD_HDR_UINT32(g_sgpe_cmn_scom_offset, 0); +HCD_HDR_PAD(64); +#ifdef __ASSEMBLER__ +.endm +#else +//FIXME RTC 155018 +//Eventually SGPE Img header has been defined to be of size 96B. Next 36B would be for +//debug pointer.Aligning SGPE image header to 64B boundary. +} __attribute__((packed, aligned(64))) sgpeHeader_t; +#endif + + +/** + * CME Header + * + * The CME header is loaded in the CME SRAM so it is "tight" (little extra space) + * Thus, this "structure" is NOT padded to a specific size and is limited to + * 64B. Also, structure member names are preceded with "g_" as these becoming + * global variables in the CME Hcode. + */ +#ifdef __ASSEMBLER__ +.macro .cme_header +.section ".cme_image_header" , "aw" +.balign 8 +#else +typedef struct +{ +#endif +HCD_HDR_UINT64(g_cme_magic_number, CME_MAGIC_NUMBER); // CME__1.0 +HCD_HDR_UINT32(g_cme_build_date, 0); +HCD_HDR_UINT32(g_cme_build_ver, 0); +HCD_HDR_UINT32(g_cme_hcode_offset, 0); +HCD_HDR_UINT32(g_cme_hcode_length, 0); +HCD_HDR_UINT32(g_cme_common_ring_offset, 0); +HCD_HDR_UINT32(g_cme_cmn_ring_ovrd_offset, 0); +HCD_HDR_UINT32(g_cme_common_ring_length, 0); +HCD_HDR_UINT32(g_cme_pstate_region_offset, 0); +HCD_HDR_UINT32(g_cme_pstate_region_length, 0); +HCD_HDR_UINT32(g_cme_core_spec_ring_offset, 0); +HCD_HDR_UINT32(g_cme_core_spec_ring_ovrd_offset, 0); +HCD_HDR_UINT32(g_cme_max_spec_ring_length, 0); +HCD_HDR_UINT32(g_cme_mode_flags, 0); +HCD_HDR_UINT32(g_cme_reserved1, 0); +HCD_HDR_UINT64(g_cme_reserved2, 0); +HCD_HDR_PAD(64); +#ifdef __ASSEMBLER__ +.endm +#else +//FIXME RTC 155018 +//Eventually CME Img header might be of size 96B. Next 36B would be for +//debug pointer.Aligning CME image header to 64B boundary. +} __attribute__((packed, aligned(64))) cmeHeader_t; +#endif + +#ifndef __ASSEMBLER__ + +typedef struct CMEImageFlags +{ + uint32_t fused_mode : 1; + uint32_t reserved0 : 31; +} CMEImageFlags_t; + +/** + * PGPE Header + * + * The PGPE header is loaded in the OCC SRAM so it is "tight" (little extra space) + * Thus, this "structure" is NOT padded to a specific size and is limited to + * 64B. Also, structure member names are preceded with "g_" as these becoming + * global variables in the CME Hcode. + */ +#ifdef __ASSEMBLER__ +.macro .pgpe_header +.section ".pgpe_header" , "aw" +.balign 8 +#else +typedef struct +{ +#endif +HCD_HDR_UINT64(g_pgpe_magic_number, PGPE_MAGIC_NUMBER); // PGPE_1.0 +HCD_HDR_UINT32(g_pgpe_build_date, 0); +HCD_HDR_UINT32(g_pgpe_build_ver, 0); +HCD_HDR_UINT32(g_pgpe_hcode_offset, 0); +HCD_HDR_UINT32(g_pgpe_hcode_length, 0); +HCD_HDR_PAD(64); +//FIXME Need to get info on other fields +#ifdef __ASSEMBLER__ +.endm +#else +//FIXME RTC 155018 +//Eventually PGPE Img header has been defined to be of size 96B. Next 36B would be for +//debug pointer.Aligning PGPE image header to 64B boundary. +} __attribute__((packed, aligned(64))) PgpeHeader_t; +#endif + /** * @brief models image section of SGPE in HOMER. */ typedef struct { - uint8_t qpmrHeader[QPMR_HEADER_SIZE]; + uint8_t qpmrHeader[sizeof(QpmrHeaderLayout_t)]; uint8_t l1BootLoader[SGPE_LVL_1_BOOT_LOAD_SIZE]; uint8_t l2BootLoader[SGPE_LVL_2_BOOT_LOAD_SIZE]; uint8_t hcodeIntVect[SGPE_INT_VECT]; - uint8_t imgHeader[SGPE_IMG_HEADER]; - uint8_t debugPtrArea[SGPE_DBG_PTR_AREA_SIZE]; + uint8_t imgHeader[sizeof(sgpeHeader_t)]; uint8_t hcode[SGPE_HCODE_SIZE]; uint8_t commonRings[SGPE_COMMON_RING]; - uint8_t cacheSpecificRing[MAX_CACHE_CHIPLET][CACHE_INST_SPECIFIC_SIZE]; + uint8_t cacheSpecificRing[MAX_CACHE_CHIPLET * CACHE_INST_SPECIFIC_SIZE]; } SgpeLayout_t; +typedef union CPMRSelfRestoreLayout +{ + uint8_t region[SELF_REST_SIZE]; + struct + { + cpmrHeader_t CPMRHeader; + uint8_t exe[SELF_REST_SIZE - sizeof(cpmrHeader_t)]; + } elements; +} CPMRSelfRestoreLayout_t; + /** * @brief models image section associated with core self restore in HOMER. */ typedef struct { - uint8_t selfRestoreArea[SELF_REST_SIZE]; - uint8_t coreSelfRestore[CORE_RESTORE_SIZE]; - uint8_t reserve[CORE_SCOM_START - (SELF_REST_SIZE + CORE_RESTORE_SIZE)]; - uint8_t coreScom[CORE_SCOM_RES_SIZE]; + CPMRSelfRestoreLayout_t CPMR_SR; + uint8_t coreSelfRestore[CORE_RESTORE_SIZE]; + uint8_t reserve[CORE_SCOM_START - (SELF_REST_SIZE + CORE_RESTORE_SIZE)]; + uint8_t coreScom[CORE_SCOM_RES_SIZE]; } SelfRestoreLayout_t; +typedef union CmeHcodeLayout +{ + uint8_t hcode[CME_HCODE_SIZE]; + struct + { + uint8_t cmeIntVector[CME_INT_VECTOR_SIZE]; + cmeHeader_t imgHeader; + uint8_t exe[CME_HCODE_SIZE - CME_INT_VECTOR_SIZE - sizeof(cmeHeader_t)]; + } elements; +} CmeHcodeLayout_t; + + typedef struct { - uint8_t cmeIntVector[CME_INT_VECTOR]; - uint8_t imgHeader[CME_IMG_HEADER]; - uint8_t debugPtrArea[CME_DBG_PTR_AREA_SIZE]; - uint8_t hcode[CME_HCODE_SIZE]; - 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]; // 300KB offset from CPMR -} CmeRegionLayout_t; + 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]; +} CPMRLayout_t; /** - * @brief models image section associated with core self restore in HOMER. + * @brief models image section associated with PGPE in HOMER. */ +typedef union PgpeHcodeLayout +{ + uint8_t hcode[PGPE_HCODE_SIZE]; + struct + { + uint8_t pgpeIntVector[PGPE_INT_VECTOR]; + PgpeHeader_t imgHeader; + uint8_t exe[PGPE_HCODE_SIZE - PGPE_INT_VECTOR - sizeof(PgpeHeader_t)]; + } elements; +} PgpeHcodeLayout_t; + typedef struct { uint8_t l1BootLoader[PGPE_LVL_1_BOOT_LOAD_SIZE]; uint8_t l2BootLoader[PGPE_LVL_2_BOOT_LOAD_SIZE]; - uint8_t pgpeIntVector[PGPE_HCODE_INT_VECT]; - uint8_t imgHeader[PGPE_IMG_HEADER]; - uint8_t hcode[PGPE_HCODE_SIZE]; + PgpeHcodeLayout_t pgpeBin; uint8_t paramBlock[PGPE_PARAM_BLOCK_SIZE]; uint8_t pstateOutputTable[PSTATE_OUTPUT_TABLE]; -} PgpeLayout_t; +} PPMRLayout_t; /** - * @brief models CME image header in HOMER. + * @brief models QPMR in HOMER. */ typedef struct { - uint64_t magicNumber; - uint32_t buildDate; - uint32_t buildVer; - uint32_t hcodeOffset; - uint32_t hcodeLength; - uint32_t commonRingOffset; - uint32_t commonRingLength; - uint32_t pStateOffset; - uint32_t pStateLength; - uint32_t coreSpecificRingOffset;; - uint32_t coreSpecificRingLength; - uint32_t cmeMode; - uint8_t reserve[12]; -} CmeImageHeader_t; - -/** - * @brief models SGPE image header in HOMER. - */ -struct SgpeImageHeader_t -{ - uint64_t magicNumber; - uint32_t sysResetAddr; - uint32_t reserve1; - uint32_t ivprAddress; - uint32_t reserve2; - uint32_t buildDate; - uint32_t buildVer; - uint64_t reserveFlag; - uint32_t quadCmnRingOccOffset; - uint32_t quadSpecRingOccOffset; - uint32_t quadCommonScomOccOffset; - uint8_t reserve3[12]; -}; + SgpeLayout_t sgpeRegion; + uint8_t qpmrReserve1[CACHE_SCOM_START - sizeof(SgpeLayout_t)]; + uint8_t cacheScomRegion[CACHE_SCOM_RESTORE_SIZE]; +} QPMRLayout_t; /** * @brief models layout of HOMER. */ -struct Homerlayout_t +typedef struct { uint8_t occHostArea[OCC_HOST_AREA_SIZE]; - SgpeLayout_t sgpeRegion; - uint8_t sgpeReserve1[CACHE_SCOM_START - sizeof(SgpeLayout_t)]; - uint8_t cacheScomRegion[CACHE_SCOM_RESTORE_SIZE]; - uint8_t sgpeReserve2[ONE_MB - (CACHE_SCOM_START + CACHE_SCOM_RESTORE_SIZE )]; - SelfRestoreLayout_t selfRestoreRegion; - CmeRegionLayout_t cmeRegion; - uint8_t cmeReserve[ONE_MB - (sizeof( CmeRegionLayout_t ) + sizeof( SelfRestoreLayout_t ))]; - PgpeLayout_t pgpeRegion; - uint8_t pgpeReserve[ONE_MB - sizeof( PgpeLayout_t )]; -}; + QPMRLayout_t qpmrRegion; + uint8_t qpmrReserve[ONE_MB - sizeof( QPMRLayout_t )]; + CPMRLayout_t cpmrRegion; + uint8_t cppmReserve[ONE_MB - sizeof( CPMRLayout_t )]; + PPMRLayout_t ppmrRegion; + uint8_t pgpeReserve[ONE_MB - sizeof( PPMRLayout_t )]; +} Homerlayout_t; #ifndef __PPE_PLAT }// namespace p9_hcodeImageBuild ends #endif //__PPE_PLAT #endif //__ASSEMBLER__ - -/** - * @brief models QPMR header in HOMER - */ - -#ifdef __ASSEMBLER__ -#define DEF_MEM_QPMR_UINT64( member )\ - member: \ - .quad 0 -#else -#define DEF_MEM_QPMR_UINT64( member ) uint64_t member; -#endif - -#ifdef __ASSEMBLER__ -#define DEF_MEM_QPMR_UINT32( member )\ - member: \ - .long 0 -#else -#define DEF_MEM_QPMR_UINT32( member ) uint32_t member; -#endif - - -#ifdef __ASSEMBLER__ -.section ".qpmr" , "aw" -.balign 8 -#else - -#ifndef __PPE_PLAT -namespace p9_hcodeImageBuild -{ -#endif //__PPE_PLAT - -struct QpmrHeaderLayout_t -{ -#endif -DEF_MEM_QPMR_UINT64( magicNumber ) -DEF_MEM_QPMR_UINT32( bootCopierOffset ) // level 1 boot loader -DEF_MEM_QPMR_UINT32( reserve1 ) -DEF_MEM_QPMR_UINT32( bootLoaderOffset ) // level 2 boot loader -DEF_MEM_QPMR_UINT32( bootLoaderLength ) -DEF_MEM_QPMR_UINT32( buildDate ) -DEF_MEM_QPMR_UINT32( buildVersion ) -DEF_MEM_QPMR_UINT64( reservedFlags ) -DEF_MEM_QPMR_UINT32( sgpeImgOffset ) -DEF_MEM_QPMR_UINT32( sgpeImgLength ) -DEF_MEM_QPMR_UINT32( quadCmnRingOffset ) -DEF_MEM_QPMR_UINT32( quadCmnRingLength ) -DEF_MEM_QPMR_UINT32( quadSpecRingOffset ) -DEF_MEM_QPMR_UINT32( quadSpecRingLength ) -DEF_MEM_QPMR_UINT32( quadSpecScomOffset ) -DEF_MEM_QPMR_UINT32( quadSpecScomLength ) -DEF_MEM_QPMR_UINT32( quadCmnRingOccOffset ) -DEF_MEM_QPMR_UINT32( quadSpecRingOccOffset ) -DEF_MEM_QPMR_UINT32( quadCmnScomOccOffset ) -#ifndef __ASSEMBLER__ -}; - -#ifndef __PPE_PLAT -} // p9_hcodeImageBuild ends -#endif //__PPE_PLAT - -#endif - - -#endif +#endif //__HW_IMG_DEFINE 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 967392517..85d5a682b 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 @@ -34,11 +34,9 @@ #include "p9_xip_image.h" #include "p9_hcode_image_defines.H" #include "p9_stop_util.H" +#include "p9_tor.H" - -using namespace fapi2; using namespace stopImageSection; - extern "C" { namespace p9_hcodeImageBuild @@ -57,10 +55,10 @@ extern "C" * @param refer to p9_hcode_image_build arguments * @return fapi2 return code */ - fapi2::ReturnCode validateInputArguments( void* const i_pImageIn, - void* i_pImageOut, - SysPhase_t i_phase, - ImageType_t i_imgType, void* i_pBuf ) + 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 l_rc = IMG_BUILD_SUCCESS; uint32_t hwImagSize = 0; @@ -69,34 +67,46 @@ extern "C" FAPI_ASSERT( (( i_pImageIn != NULL ) && ( i_pImageOut != NULL ) && ( i_pImageIn != i_pImageOut )), - fapi2::P9_IMG_PTR_ERROR() + fapi2::IMG_PTR_ERROR() .set_HW_IMG_BUF_PTR( i_pImageIn ) .set_HOMER_IMG_BUF_PTR( i_pImageOut ), "Bad pointer to HW Image or HOMER Image" ); l_rc = p9_xip_image_size( i_pImageIn, &hwImagSize ); - FAPI_DBG("size is 0x%08x", hwImagSize); + FAPI_DBG("size is 0x%08x; xip_image_size RC is 0x%02x HARDWARE_IMG_SIZE 0x%08x Sz 0x%08x", + hwImagSize, l_rc, HARDWARE_IMG_SIZE, hwImagSize ); FAPI_ASSERT( (( IMG_BUILD_SUCCESS == l_rc ) && ( hwImagSize > 0 ) && ( HARDWARE_IMG_SIZE >= hwImagSize )), - fapi2::P9_HW_IMAGE_INVALID_SIZE() + fapi2::HW_IMAGE_INVALID_SIZE() .set_HW_IMG_SIZE( hwImagSize ) .set_MAX_HW_IMG_SIZE( HARDWARE_IMG_SIZE ), "Hardware image size found out of range" ); FAPI_ASSERT( (( i_phase > PHASE_NA ) && ( i_phase < PHASE_END )), - fapi2::P9_HCODE_INVALID_PHASE() + fapi2::HCODE_INVALID_PHASE() .set_SYS_PHASE( i_phase ), "Invalid value passed as build phase" ); - FAPI_ASSERT( ( i_pBuf != NULL ), - fapi2::P9_HCODE_INVALID_TEMP_BUF() - .set_TEMP_BUF_PTR( i_pBuf ), - "Invalid temp buffer passed for hcode image build" ); + FAPI_ASSERT( ( i_pBuf1 != NULL ), + fapi2::HCODE_INVALID_TEMP_BUF() + .set_TEMP_BUF_PTR( i_pBuf1 ), + "Invalid temp buffer1 passed for hcode image build" ); + + FAPI_ASSERT( (( i_bufSize1 != 0 ) && ( i_bufSize2 != 0 )), + fapi2::HCODE_TEMP_BUF_SIZE() + .set_TEMP_BUF1_SIZE( i_bufSize1 ) + .set_TEMP_BUF2_SIZE( i_bufSize2 ), + "Invalid work buffer size " ); + + FAPI_ASSERT( ( i_pBuf2 != NULL ), + fapi2::HCODE_INVALID_TEMP_BUF() + .set_TEMP_BUF_PTR( i_pBuf2 ), + "Invalid temp buffer2 passed for hcode image build" ); FAPI_ASSERT( ( i_imgType.isBuildValid() ), - fapi2::P9_HCODE_INVALID_IMG_TYPE(), + fapi2::HCODE_INVALID_IMG_TYPE(), "Invalid temp buffer passed for hcode image build" ); FAPI_DBG("Exiting validateInputArguments ..."); @@ -105,9 +115,19 @@ extern "C" } //------------------------------------------------------------------------------ + /** + * @brief Copies section of hardware image to HOMER + * @param i_destPtr a location in HOMER + * @param i_srcPtr a location in HW Image. + * @param i_secId XIP Section id to be copied. + * @param i_platId platform associated with the given section. + * @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 , P9XipSection& o_ppeSection ) { + FAPI_INF("> copySectionToHomer"); uint32_t retCode = IMG_BUILD_SUCCESS; do @@ -122,53 +142,151 @@ extern "C" break; } + FAPI_DBG("o_ppeSection.iv_offset = %X, " + "o_ppeSection.iv_size = %X, " + "i_secId %d", + o_ppeSection.iv_offset, + o_ppeSection.iv_size, + i_secId); memcpy( i_destPtr, i_srcPtr + o_ppeSection.iv_offset, o_ppeSection.iv_size ); } while(0); + FAPI_INF("< copySectionToHomer"); return retCode; } + //------------------------------------------------------------------------------ - uint32_t updateCpmrHeader( Homerlayout_t* i_pChipHomer, uint8_t i_fuseState ) + + /** + * @brief updates various CPMR fields which are not associated with scan rings. + * @param i_pChipHomer points to start of P9 HOMER. + */ + void updateCpmrHeaderCME( Homerlayout_t* i_pChipHomer) { - uint32_t rc = IMG_BUILD_SUCCESS; + FAPI_INF("> updateCpmrHeaderCME"); - do - { - HomerImgDesc_t* pCpmrHdr = (HomerImgDesc_t*) & (i_pChipHomer->selfRestoreRegion); - - CmeImageHeader_t* pCmeHdr = NULL; - pCmeHdr = (CmeImageHeader_t*) i_pChipHomer->cmeRegion.imgHeader; - pCpmrHdr->homerMagicNumber = SWIZZLE_8_BYTE(CPMR_MAGIC_WORD); - //populate CPMR header - pCpmrHdr->fuseModeStatus = i_fuseState ? FUSE_STATE : UNFUSE_STATE; - //offset is multiple of 32B for quick setting of MBASE of CME's BCE - pCpmrHdr->cmeImgOffset = (CME_REGION_START >> CME_BLK_SIZE_SHIFT); - - // populate the CME binary's size - pCpmrHdr->cmeImgLength = pCmeHdr->hcodeLength + CME_INT_VECTOR + CME_IMG_HEADER; - //FIXME to be handled while adding scan ring part. - pCpmrHdr->cmeCommonRingOffset = 0; - pCpmrHdr->cmeCommonRingLength = 0; - pCpmrHdr->cmePstateOffset = 0; - pCpmrHdr->cmePstateLength = 0; - pCpmrHdr->coreSpecRingOffset = 0; - pCpmrHdr->coreSpecRingLen = 0; - pCpmrHdr->coreScomOffset = (CORE_SCOM_START >> CME_BLK_SIZE_SHIFT); - pCpmrHdr->coreScomLength = (CORE_SCOM_RES_SIZE >> CME_BLK_SIZE_SHIFT); - } - while(0); + cpmrHeader_t* pCpmrHdr = + (cpmrHeader_t*) & (i_pChipHomer->cpmrRegion.selfRestoreRegion.CPMR_SR.elements.CPMRHeader); - return rc; + cmeHeader_t* pCmeHdr = NULL; + pCmeHdr = (cmeHeader_t*) & i_pChipHomer->cpmrRegion.cmeBin.elements.imgHeader; + + + //offset is multiple of 32B for quick setting of MBASE of CME's BCE + pCpmrHdr->cmeImgOffset = SWIZZLE_4_BYTE((CPMR_CME_HCODE_OFFSET >> CME_BLK_SIZE_SHIFT)); + // populate the CME binary's size + pCpmrHdr->cmeImgLength = pCmeHdr->g_cme_hcode_length; + + pCpmrHdr->cmePstateOffset = 0; + pCpmrHdr->cmePstateLength = 0; + 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 (Real offset / 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"); + } + +//------------------------------------------------------------------------------ + + /** + * @brief updates various CPMR fields which are associated with scan rings. + * @param i_pChipHomer points to start of P9 HOMER. + */ + void updateCpmrScanRing( Homerlayout_t* i_pChipHomer ) + { + cpmrHeader_t* pCpmrHdr = + (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->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 + + 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 Spec Ring Length = 0x%08x", SWIZZLE_4_BYTE(pCpmrHdr->coreSpecRingLength) ); + + FAPI_INF("CME Header Scan Rings"); + FAPI_INF(" CME Cmn Ring Offset = 0x%08x", SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_offset)); + FAPI_INF(" CME Cmn Ring Length = 0x%08x", SWIZZLE_4_BYTE(pCmeHdr->g_cme_common_ring_length) ); + FAPI_INF(" Core Instance Ring Offset = 0x%08x (Real offset / 32) ", + SWIZZLE_4_BYTE(pCmeHdr->g_cme_core_spec_ring_offset)); + FAPI_INF(" Core Instance Ring Length = 0x%08x (Real length / 32)", + SWIZZLE_4_BYTE(pCmeHdr->g_cme_max_spec_ring_length) ); + FAPI_INF(" Core Spec Ovrd Ring Offset = 0x%08x", SWIZZLE_4_BYTE(pCmeHdr->g_cme_core_spec_ring_ovrd_offset )); + + } + +//------------------------------------------------------------------------------ + /** + * @brief updates various CPMR fields which are associated with self restore code. + * @param i_pChipHomer points to start of P9 HOMER. + * @param i_fuseState core fuse status + */ + void updateCpmrHeaderSR( Homerlayout_t* i_pChipHomer, uint8_t i_fuseState ) + { + FAPI_INF("> updateCpmrHeaderSR"); + cpmrHeader_t* pCpmrHdr = + (cpmrHeader_t*) & (i_pChipHomer->cpmrRegion.selfRestoreRegion.CPMR_SR.elements.CPMRHeader); + + cmeHeader_t* pCmeHdr = NULL; + pCmeHdr = (cmeHeader_t*) & i_pChipHomer->cpmrRegion.cmeBin.elements.imgHeader; + //populate CPMR header + pCpmrHdr->fuseModeStatus = SWIZZLE_4_BYTE(i_fuseState ? FUSE_STATE : UNFUSE_STATE); + + pCmeHdr->g_cme_mode_flags = SWIZZLE_4_BYTE(i_fuseState ? 1 : 0); + + FAPI_INF("CPMR SR"); + FAPI_INF(" Fuse Mode = 0x%08X CME Image Flag = 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->fuseModeStatus), + SWIZZLE_4_BYTE(pCmeHdr->g_cme_mode_flags)); + FAPI_DBG(" Offset = 0x%08X (Real offset / 32)", SWIZZLE_4_BYTE(pCpmrHdr->cmeImgOffset)); + FAPI_DBG(" Size = 0x%08X", SWIZZLE_4_BYTE(pCpmrHdr->cmeImgLength)); + + FAPI_INF("< updateCpmrHeaderSR"); } + //------------------------------------------------------------------------------ + /** + * @brief updates various QPMR header region in HOMER. + * @param i_pChipHomer points to start of P9 HOMER. + * @param io_qpmrHdr temp instance of QpmrHeaderLayout_t used for data collection. + */ uint32_t updateQpmrHeader( Homerlayout_t* i_pChipHomer, QpmrHeaderLayout_t& io_qpmrHdr ) { uint32_t rc = IMG_BUILD_SUCCESS; - QpmrHeaderLayout_t* pQpmrHdr = ( QpmrHeaderLayout_t*)i_pChipHomer->sgpeRegion.qpmrHeader; + QpmrHeaderLayout_t* pQpmrHdr = ( QpmrHeaderLayout_t*) & (i_pChipHomer->qpmrRegion.sgpeRegion.qpmrHeader); 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_DBG(" Cmn Ring Offset = 0x%08x", SWIZZLE_4_BYTE(pQpmrHdr->quadCommonRingOffset) ); + FAPI_DBG(" Cmn Ring Length = 0x%08x", SWIZZLE_4_BYTE(pQpmrHdr->quadCommonRingLength) ); + return rc; } @@ -176,12 +294,13 @@ extern "C" /** * @brief copies image section associated with SGPE from HW Image to HOMER * @param[in] i_pImageIn points to start of hardware image. - * @param[in] i_pChipHomer points to HOMER image in main memory. + * @param[in] i_pChipHomer points to HOMER image. * @param[in] i_imgType image sections to be built */ - uint32_t buildSgpeImage( void* const i_pImageIn, Homerlayout_t* i_pChipHomer, - ImageType_t i_imgType ) + uint32_t buildSgpeImage( void* const i_pImageIn, Homerlayout_t* i_pChipHomer, ImageType_t i_imgType, + QpmrHeaderLayout_t& o_qpmrHdr ) { + FAPI_INF("> buildSgpeImage"); uint32_t retCode = IMG_BUILD_SUCCESS; do @@ -190,7 +309,6 @@ extern "C" //Let us find XIP Header for SGPE P9XipSection ppeSection; uint8_t* pSgpeImg = NULL; - QpmrHeaderLayout_t qpmrHdr; if(!i_imgType.sgpeHcodeBuild ) { @@ -207,9 +325,14 @@ extern "C" } pSgpeImg = ppeSection.iv_offset + (uint8_t*) (i_pImageIn ); + FAPI_DBG("HW image SGPE Offset = 0x%08X", ppeSection.iv_offset); - rcTemp = copySectionToHomer( i_pChipHomer->sgpeRegion.qpmrHeader, pSgpeImg, - P9_XIP_SECTION_SGPE_QPMR, PLAT_SGPE, ppeSection ); + FAPI_INF("QPMR Header"); + rcTemp = copySectionToHomer( i_pChipHomer->qpmrRegion.sgpeRegion.qpmrHeader, + pSgpeImg, + P9_XIP_SECTION_SGPE_QPMR, + PLAT_SGPE, + ppeSection ); if( rcTemp ) { @@ -219,11 +342,14 @@ extern "C" } //updating local instance of QPMR header - memcpy( &qpmrHdr, i_pChipHomer->sgpeRegion.qpmrHeader, sizeof(QpmrHeaderLayout_t)); + memcpy( &o_qpmrHdr, i_pChipHomer->qpmrRegion.sgpeRegion.qpmrHeader, sizeof(QpmrHeaderLayout_t)); - rcTemp = copySectionToHomer( i_pChipHomer->sgpeRegion.l1BootLoader, pSgpeImg, - P9_XIP_SECTION_SGPE_LVL1_BL, PLAT_SGPE, ppeSection ); - qpmrHdr.bootCopierOffset = QPMR_HEADER_SIZE; + FAPI_DBG("SGPE Boot Copier"); + rcTemp = copySectionToHomer( i_pChipHomer->qpmrRegion.sgpeRegion.l1BootLoader, + pSgpeImg, + P9_XIP_SECTION_SGPE_LVL1_BL, + PLAT_SGPE, + ppeSection ); if( rcTemp ) { @@ -232,10 +358,17 @@ extern "C" break; } - rcTemp = copySectionToHomer( i_pChipHomer->sgpeRegion.l2BootLoader, pSgpeImg, - P9_XIP_SECTION_SGPE_LVL2_BL, PLAT_SGPE, ppeSection ); - qpmrHdr.bootLoaderOffset = qpmrHdr.bootCopierOffset + SGPE_LVL_1_BOOT_LOAD_SIZE; - qpmrHdr.bootLoaderLength = ppeSection.iv_size; + o_qpmrHdr.bootCopierOffset = QPMR_HEADER_SIZE; + FAPI_DBG("SGPE Boot Copier Size = 0x%08X", + o_qpmrHdr.bootCopierOffset); + + FAPI_DBG(" SGPE Boot Loader"); + + rcTemp = copySectionToHomer( i_pChipHomer->qpmrRegion.sgpeRegion.l2BootLoader, + pSgpeImg, + P9_XIP_SECTION_SGPE_LVL2_BL, + PLAT_SGPE, + ppeSection ); if( rcTemp ) { @@ -244,58 +377,73 @@ extern "C" break; } - rcTemp = copySectionToHomer( i_pChipHomer->sgpeRegion.hcodeIntVect, pSgpeImg, - P9_XIP_SECTION_SGPE_INT_VECT, PLAT_SGPE, ppeSection ); + o_qpmrHdr.bootLoaderOffset = o_qpmrHdr.bootCopierOffset + SGPE_LVL_1_BOOT_LOAD_SIZE; + o_qpmrHdr.bootLoaderLength = ppeSection.iv_size; - if( rcTemp ) - { - FAPI_ERR("Failed to copy SGPE Int. vectors "); - rcTemp = BUILD_FAIL_CME_INT_VECT; - break; - } + FAPI_INF("SGPE Boot Loader QPMR Offset = 0x%08X, Size = 0x%08X", + o_qpmrHdr.bootLoaderOffset, o_qpmrHdr.bootLoaderLength); - rcTemp = copySectionToHomer( i_pChipHomer->sgpeRegion.imgHeader, pSgpeImg, - P9_XIP_SECTION_SGPE_IMG_HDR, PLAT_SGPE, ppeSection ); + // The image in the HW Image has the Interrupt Vectors, SGPE Header and Debug + // Pointer already included. Thus, load the "Hcode Image" starting at the + // sgpeRegion.hcodeIntVect location. + rcTemp = copySectionToHomer( i_pChipHomer->qpmrRegion.sgpeRegion.hcodeIntVect, + pSgpeImg, + P9_XIP_SECTION_SGPE_HCODE, + PLAT_SGPE, + ppeSection ); if( rcTemp ) { - FAPI_ERR("Failed to copy SGPE header"); - rcTemp = BUILD_FAIL_SGPE_HDR; + FAPI_ERR("Failed to copy SGPE hcode"); + rcTemp = BUILD_FAIL_SGPE_HCODE; break; } - rcTemp = copySectionToHomer( i_pChipHomer->sgpeRegion.hcode, pSgpeImg, - P9_XIP_SECTION_SGPE_HCODE, PLAT_SGPE, ppeSection ); + FAPI_DBG("SGPE Hcode QPMR Offset = 0x%08X, Size = 0x%08X", + SWIZZLE_4_BYTE(o_qpmrHdr.sgpeImgOffset), + SWIZZLE_4_BYTE(o_qpmrHdr.sgpeImgLength)); - // FIXME Need to handle Scan Ring part here + o_qpmrHdr.sgpeImgOffset = o_qpmrHdr.bootLoaderOffset + SGPE_LVL_2_BOOT_LOAD_SIZE; - if( rcTemp ) - { - FAPI_ERR("Failed to copy SGPE hcode"); - rcTemp = BUILD_FAIL_SGPE_HCODE; - break; - } + //let us take care of endianess now. + o_qpmrHdr.sgpeImgLength = SWIZZLE_4_BYTE(ppeSection.iv_size); + o_qpmrHdr.bootLoaderOffset = SWIZZLE_4_BYTE(o_qpmrHdr.bootLoaderOffset); + o_qpmrHdr.bootCopierOffset = SWIZZLE_4_BYTE(o_qpmrHdr.bootCopierOffset); + o_qpmrHdr.sgpeImgOffset = SWIZZLE_4_BYTE(o_qpmrHdr.sgpeImgOffset); + o_qpmrHdr.bootLoaderLength = SWIZZLE_4_BYTE(o_qpmrHdr.bootLoaderLength); + + //FIXME Need to confirm it + o_qpmrHdr.quadSpecScomOffset = SWIZZLE_4_BYTE(CACHE_SCOM_START); + + sgpeHeader_t* pImgHdr = (sgpeHeader_t*)& i_pChipHomer->qpmrRegion.sgpeRegion.imgHeader; + pImgHdr->g_sgpe_cmn_ring_occ_offset = o_qpmrHdr.sgpeImgLength; - qpmrHdr.sgpeImgOffset = i_pChipHomer->sgpeRegion.hcodeIntVect - - (uint8_t*)&i_pChipHomer->sgpeRegion; - qpmrHdr.sgpeImgLength = ppeSection.iv_size + PPE_RESERVE_AREA; - qpmrHdr.quadSpecScomOffset = CACHE_SCOM_START; + 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)); //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++ ) { - uint32_t l_fillPattern = PAD_OPCODE; - memcpy( i_pChipHomer->cacheScomRegion, &l_fillPattern, sizeof(uint32_t) ); + memcpy( i_pChipHomer->qpmrRegion.cacheScomRegion, &l_fillPattern, sizeof(uint32_t) ); } - - updateQpmrHeader( i_pChipHomer, qpmrHdr ); } while(0); + FAPI_INF("< buildSgpeImag") return retCode; } @@ -304,8 +452,10 @@ extern "C" /** * @brief copies core self restore section from hardware image to HOMER. * @param[in] i_pImageIn points to start of hardware image. - * @param[in] i_pChipHomer points to HOMER image in main memory. + * @param[in] i_pChipHomer points to HOMER image. * @param[in] i_imgType image sections to be built + * @param[in] i_fuseState fuse state of core. + * @return IMG_BUILD_SUCCESS if function succeeds, error code otherwise. */ uint32_t buildCoreRestoreImage( void* const i_pImageIn, Homerlayout_t* i_pChipHomer, ImageType_t i_imgType, @@ -334,42 +484,54 @@ extern "C" { // first 256 bytes is expected to be zero here. It is by purpose. Just after this step, // we will add CPMR header in that area. - rcTemp = copySectionToHomer( i_pChipHomer->selfRestoreRegion.selfRestoreArea, pSelfRestImg, - P9_XIP_SECTION_RESTORE_SELF, PLAT_SELF, ppeSection ); + FAPI_INF("Self Restore Image install"); + FAPI_INF(" Offset = 0x%08X, Size = 0x%08X", + ppeSection.iv_offset, ppeSection.iv_size); + rcTemp = copySectionToHomer( i_pChipHomer->cpmrRegion.selfRestoreRegion.CPMR_SR.region, + pSelfRestImg, + P9_XIP_SECTION_RESTORE_SELF, + PLAT_SELF, + ppeSection ); if( rcTemp ) { FAPI_ERR("Failed to copy SRESET Handler"); - retCode = BUILD_FAIL_P9_SRESET_HNDLR; + retCode = BUILD_FAIL_SRESET_HNDLR; break; } } - // adding CPMR header in first 256 bytes of HOMER + 2 MB. - rcTemp = copySectionToHomer( i_pChipHomer->selfRestoreRegion.selfRestoreArea, pSelfRestImg, - P9_XIP_SECTION_RESTORE_CPMR, PLAT_SELF, ppeSection ); + // adding CPMR header in first 256 bytes of the CPMR. + FAPI_INF("Overlay CPMR Header at the beginning of CPMR"); + rcTemp = copySectionToHomer( i_pChipHomer->cpmrRegion.selfRestoreRegion.CPMR_SR.region, + pSelfRestImg, + P9_XIP_SECTION_RESTORE_CPMR, + PLAT_SELF, + ppeSection ); if( rcTemp ) { FAPI_ERR("Failed to copy CPMR header"); - retCode = BUILD_FAIL_P9_CPMR_HDR; + retCode = BUILD_FAIL_CPMR_HDR; break; } //Pad undefined or runtime section with ATTN Opcode //Padding SPR restore area with ATTN Opcode - + FAPI_INF("Padding CPMR Core Restore portion with Attn opcodes"); uint32_t wordCnt = 0; + uint32_t l_fillPattern = SWIZZLE_4_BYTE(PAD_OPCODE); while( wordCnt < CORE_RESTORE_SIZE ) { - uint32_t l_fillPattern = SWIZZLE_4_BYTE(PAD_OPCODE); - memcpy( (uint32_t*)&i_pChipHomer->selfRestoreRegion.coreSelfRestore[wordCnt], &l_fillPattern, sizeof( uint32_t )); + memcpy( (uint32_t*)&i_pChipHomer->cpmrRegion.selfRestoreRegion.coreSelfRestore[wordCnt], + &l_fillPattern, + sizeof( uint32_t )); wordCnt += 4; } - updateCpmrHeader( i_pChipHomer, i_fuseState ); + updateCpmrHeaderSR( i_pChipHomer, i_fuseState ); } while(0); @@ -381,8 +543,9 @@ extern "C" /** * @brief copies cme section from hardware image to HOMER. * @param[in] i_pImageIn points to start of hardware image. - * @param[in] i_pChipHomer points to HOMER image in main memory. + * @param[in] i_pChipHomer points to HOMER image. * @param[in] i_imgType image sections to be built + * @return IMG_BUILD_SUCCESS if function succeeds, error code otherwise. */ uint32_t buildCmeImage( void* const i_pImageIn, Homerlayout_t* i_pChipHomer, ImageType_t i_imgType ) @@ -406,72 +569,768 @@ extern "C" } pCmeImg = ppeSection.iv_offset + (uint8_t*) (i_pImageIn ); - rcTemp = copySectionToHomer( i_pChipHomer->cmeRegion.cmeIntVector, pCmeImg, - P9_XIP_SECTION_CME_INT_VECT, PLAT_CME, ppeSection ); + FAPI_DBG("ppeSection.iv_offset = 0x%08X, ppeSection.iv_size = 0x%08X", + ppeSection.iv_offset, ppeSection.iv_size); + + if( i_imgType.cmeHcodeBuild ) + { + // The image in the HW Image has the Interrupt Vectors, CME Header and Debug + // Pointers already included. + rcTemp = copySectionToHomer( i_pChipHomer->cpmrRegion.cmeBin.hcode, pCmeImg, + P9_XIP_SECTION_CME_HCODE, + PLAT_CME, + ppeSection ); + + if( rcTemp ) + { + FAPI_ERR("Failed to append CME Hcode"); + retCode = BUILD_FAIL_CME_HCODE; + break; + } + + // Initializing CME Image header + // Names have g_ prefix as these global variables for CME Hcode + // 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); + pImgHdr->g_cme_hcode_length = SWIZZLE_4_BYTE(ppeSection.iv_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) + + SWIZZLE_4_BYTE(pImgHdr->g_cme_hcode_length); + pImgHdr->g_cme_common_ring_offset = SWIZZLE_4_BYTE(pImgHdr->g_cme_common_ring_offset); + 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(" 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); + + return retCode; + } + +//------------------------------------------------------------------------------ + /** + * @brief copies PGPE section from hardware image to HOMER. + * @param[in] i_pImageIn points to start of hardware image. + * @param[in] i_pChipHomer points to HOMER image in main memory. + * @param[in] i_imgType image sections to be built + * @return IMG_BUILD_SUCCESS if function succeeds, error code otherwise. + */ + uint32_t buildPgpeImage( void* const i_pImageIn, Homerlayout_t* i_pChipHomer, + ImageType_t i_imgType ) + { + uint32_t retCode = IMG_BUILD_SUCCESS; + FAPI_INF("> PGPE Img build") + + do + { + uint32_t rcTemp = 0; + //Let us find XIP Header for SGPE + P9XipSection ppeSection; + uint8_t* pPgpeImg = NULL; + + if(!i_imgType.pgpeImageBuild ) + { + break; + } + + rcTemp = p9_xip_get_section( i_pImageIn, P9_XIP_SECTION_HW_PGPE, &ppeSection ); if( rcTemp ) { - FAPI_ERR("Failed to copy SGPE Int. vectors "); - rcTemp = BUILD_FAIL_CME_INT_VECT; + FAPI_ERR("Failed to get PGPE XIP Image Header" ); + retCode = BUILD_FAIL_PGPE_IMAGE; break; } - rcTemp = copySectionToHomer( i_pChipHomer->cmeRegion.imgHeader, pCmeImg, - P9_XIP_SECTION_CME_IMG_HDR, PLAT_CME, ppeSection ); + pPgpeImg = ppeSection.iv_offset + (uint8_t*) (i_pImageIn ); + + rcTemp = copySectionToHomer( i_pChipHomer->ppmrRegion.l1BootLoader, pPgpeImg, + P9_XIP_SECTION_PGPE_LVL1_BL, PLAT_SGPE, ppeSection ); if( rcTemp ) { - FAPI_ERR("Failed to append CME Image Header"); - retCode = BUILD_FAIL_CME_IMG_HDR; + FAPI_ERR("Failed to copy PGPE Level1 bootloader"); + rcTemp = BUILD_FAIL_PGPE_BL1; break; } - rcTemp = copySectionToHomer( i_pChipHomer->cmeRegion.imgHeader, pCmeImg, - P9_XIP_SECTION_CME_IMG_HDR, PLAT_CME, ppeSection ); + + rcTemp = copySectionToHomer( i_pChipHomer->ppmrRegion.l2BootLoader, pPgpeImg, + P9_XIP_SECTION_PGPE_LVL2_BL, PLAT_PGPE, ppeSection ); if( rcTemp ) { - FAPI_ERR("Failed to append CME Image Header"); - retCode = BUILD_FAIL_CME_IMG_HDR; + FAPI_ERR("Failed to copy PGPE Level2 bootloader"); + rcTemp = BUILD_FAIL_SGPE_BL2; break; } - if( i_imgType.cmeHcodeBuild ) + rcTemp = copySectionToHomer( i_pChipHomer->ppmrRegion.pgpeBin.hcode, pPgpeImg, + P9_XIP_SECTION_PGPE_HCODE, PLAT_PGPE, ppeSection ); + + if( rcTemp ) { - rcTemp = copySectionToHomer( i_pChipHomer->cmeRegion.hcode, pCmeImg, - P9_XIP_SECTION_CME_HCODE, PLAT_CME, ppeSection ); + FAPI_ERR("Failed to copy PGPE hcode"); + rcTemp = BUILD_FAIL_PGPE_HCODE; + break; + } - if( rcTemp ) + //FIXME PGPE image header shall be populated after its definition is published. + + } + while(0); + + FAPI_INF("< PGPE Img build") + 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. + */ + 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 ) + { + 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; + + do + { + P9XipSection ppeSection; + rc = p9_xip_get_section( i_pImageIn, P9_XIP_SECTION_HW_RINGS, &ppeSection ); + + if( rc ) + { + FAPI_ERR("Failed to access common scan rings Plat 0x%08x", i_platId ); + rc = BUILD_FAIL_CMN_RINGS; + break; + } + + uint8_t* pScanRing = ppeSection.iv_offset + (uint8_t*) (i_pImageIn ); + + if( ( PLAT_CME != i_platId ) && ( PLAT_SGPE != i_platId ) ) + { + FAPI_ERR(" scan ring not supported for platform 0x%d", i_platId ); + break; + } + + rc = tor_get_block_of_rings( pScanRing, + i_ddLevel, + ((PLAT_CME == i_platId) ? P9_TOR::CME : P9_TOR::SGPE), + ringType, + P9_TOR::BASE, + i_instanceId, + &i_pBuf1, + tempBufLength ); + FAPI_INF("Ring type 0x%08x instance 0x%08x buf len 0x%08x", ringType, i_instanceId, tempBufLength ); + + if( rc ) + { + FAPI_ERR(" common scan ring block not copied rc 0x%08x Length 0x%08x", rc, tempBufLength ); + break; + } + + if( tempBufLength == io_copyLength ) + { + FAPI_DBG(" Scan ring block size not updated"); + io_copyLength = 0; + rc = BUILD_FAIL_CMN_RINGS; + break; + } + + if( !i_ringQuery ) + { + memcpy( i_pChipHomerLoc, (uint8_t*)i_pBuf1, tempBufLength ); + } + + io_copyLength = tempBufLength; + + 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") + 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 rc = IMG_BUILD_SUCCESS; + + do + { + if( ( PLAT_CME != i_platId ) && ( PLAT_SGPE != i_platId ) ) + { + 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 tempBufLength = io_bufLength; + + rc = tor_get_block_of_rings( i_pOverride, + i_ddLevel, + ((PLAT_CME == i_platId) ? P9_TOR::CME : P9_TOR::SGPE), + i_ringType, + P9_TOR::OVERRIDE, + i_instanceId, + &i_pTempBuf, + io_bufLength ); + + if( IMGBUILD_TGR_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; + } + + if( tempBufLength == io_bufLength ) + { + FAPI_DBG(" %s Overrides not found for %s", + ((i_instanceId == IGNORE_CHIPLET_INSTANCE ) ? "Common" : "Inst Speccific"), + ((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; + } + + if( !i_queryRing ) + { + memcpy( i_pHomerLoc, (uint8_t*)i_pTempBuf, io_bufLength ); + } + + 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" ); + } + while(0); + + 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. + */ + 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 rc = IMG_BUILD_SUCCESS; + FAPI_INF( "> copyRingsFromHwImage"); + + do + { + Homerlayout_t* i_pChipHomer = (Homerlayout_t*) o_pImageOut; + uint32_t tempLength = i_bufSize1; + uint32_t copyLength = 0; + + if( PLAT_SGPE == i_platId ) + { + // 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 ) { - FAPI_ERR("Failed to append CME Hcode"); - retCode = BUILD_FAIL_CME_HCODE; - break; + rc = copyScanRings( i_pImageIn, + i_pChipHomer->qpmrRegion.sgpeRegion.commonRings, + i_ddLevel, + i_pBuf1, + tempLength, + PLAT_SGPE, + IGNORE_CHIPLET_INSTANCE ); + + if( rc ) + { + FAPI_ERR(" failed to copy the SGPE common ring rc: 0x%08x", rc ); + break; + } + + 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 ); + + copyLength = tempLength; + tempLength = i_bufSize1; + + rc = copyScanOverrideRing( i_pOverride, + &i_pChipHomer->qpmrRegion.sgpeRegion.commonRings[copyLength], + i_ddLevel, + P9_TOR::COMMON, + i_pBuf1, + tempLength, + PLAT_SGPE, + IGNORE_CHIPLET_INSTANCE ); + + if( rc ) + { + FAPI_INF(" No quad common override ring "); + tempLength = 0; + rc = IMG_BUILD_SUCCESS; + } + + 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 ); + + 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 } - // Initializing CME Image header - CmeImageHeader_t* pImgHdr = ( CmeImageHeader_t*)i_pChipHomer->cmeRegion.imgHeader; - pImgHdr->hcodeOffset = CME_HCODE_REL_OFFSET; - pImgHdr->hcodeLength = ppeSection.iv_size; - pImgHdr->commonRingOffset = 0; - pImgHdr->commonRingLength = 0; - pImgHdr->pStateOffset = 0; - pImgHdr->pStateLength = 0; - pImgHdr->coreSpecificRingOffset = 0; // multiple of 32B blocks - pImgHdr->coreSpecificRingLength = 0; // multiple of 32B blocks + if( i_imgType.sgpeCacheSpecificRingBuild ) + { + // 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( rc ) + { + FAPI_ERR(" failed to copy the Cache chiplet specific ring rc: 0x%08x", rc ); + break; + } + + FAPI_DBG(" Quad specific ring copied offset 0x%08x, Length 0x%08x", + ((uint8_t*)i_pChipHomer->qpmrRegion.sgpeRegion.cacheSpecificRing - (uint8_t*)i_pChipHomer), + tempLength ); + + copyLength = tempLength; + tempLength = i_bufSize1; + + // 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( rc ) + { + FAPI_INF(" No quad specific override ring "); + tempLength = 0; + rc = IMG_BUILD_SUCCESS; + } + + 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)); + } + } + else if( PLAT_CME == i_platId ) + { + //------------------------------------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 ) + { + tempLength = i_bufSize1; + rc = copyScanRings( i_pImageIn, + i_pChipHomer->cpmrRegion.commonRings, + i_ddLevel, + i_pBuf1, + tempLength, + PLAT_CME, + IGNORE_CHIPLET_INSTANCE); + + if( rc ) + { + FAPI_ERR(" failed to copy the CME common ring rc: 0x%08x", rc ); + break; + } + + FAPI_INF(" Core Cmn Ring copied Offset 0x%08x Length 0x%08x", + ( (uint8_t*)i_pChipHomer->cpmrRegion.commonRings - (uint8_t*)i_pChipHomer ), + tempLength ); + + copyLength = tempLength; + tempLength = i_bufSize1; + + rc = copyScanOverrideRing( i_pOverride, + &i_pChipHomer->cpmrRegion.commonRings[copyLength], + i_ddLevel, + P9_TOR::COMMON, + i_pBuf1, + tempLength, + PLAT_CME, + IGNORE_CHIPLET_INSTANCE ); + + if( rc ) + { + FAPI_INF(" No common core override ring"); + tempLength = 0; + rc = IMG_BUILD_SUCCESS; + } + + 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); + } + + 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; + } + } + + if( rc ) + { + // failed to access core specific rings + break; + } + + copyLength = maxRingLength + maxOverrideLength; + + 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 ); + } + + for( cmeId = 0; cmeId < MAX_CME_PER_CHIP; cmeId++ ) + { + 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(" 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 ); + + 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 + + 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); + + //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; + } } } while(0); - return retCode; + FAPI_INF( "< copyRingsFromHwImage"); + + return rc; } -//------------------------------------------------------------------------------ + + //--------------------------------------------------------------------------- fapi2::ReturnCode p9_hcode_image_build( CONST_FAPI2_PROC& i_procTgt, - void* const i_pImageIn, - void* o_pImageOut, + void* const i_pImageIn, + void* i_pHomerImage, + void* const i_pRingOverride, SysPhase_t i_phase, ImageType_t i_imgType, - void* i_pBuf ) + void* const i_pBuf1, + const uint32_t i_sizeBuf1, + void* const i_pBuf2, + const uint32_t i_sizeBuf2 ) { FAPI_IMP("Entering p9_hcode_image_build "); fapi2::ReturnCode retCode; @@ -479,8 +1338,9 @@ extern "C" do { FAPI_DBG("validating argument .."); - retCode = validateInputArguments( i_pImageIn, o_pImageOut, i_phase, - i_imgType, i_pBuf ); + retCode = validateInputArguments( i_pImageIn, i_pHomerImage, i_phase, + i_imgType, i_pBuf1, i_sizeBuf1, i_pBuf2, + i_sizeBuf2 ); if( retCode ) { @@ -488,45 +1348,139 @@ extern "C" break; } - Homerlayout_t* pChipHomer = ( Homerlayout_t*) o_pImageOut; + Homerlayout_t* pChipHomer = ( Homerlayout_t*) i_pHomerImage; uint32_t ppeImgRc = IMG_BUILD_SUCCESS; // 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 - ppeImgRc = buildSgpeImage( i_pImageIn, pChipHomer, i_imgType ); + FAPI_INF("SGPE building"); + QpmrHeaderLayout_t qpmrHdr; + ppeImgRc = buildSgpeImage( i_pImageIn, pChipHomer, i_imgType, qpmrHdr ); + ppeImgRc = IMG_BUILD_SUCCESS; FAPI_ASSERT( ( IMG_BUILD_SUCCESS == ppeImgRc ), - fapi2::P9_SGPE_BUILD_FAIL() + fapi2::SGPE_BUILD_FAIL() .set_SGPE_FAIL_SECTN( ppeImgRc ), "Failed to copy SGPE section in HOMER" ); - FAPI_DBG("SGPE built"); + FAPI_INF("SGPE built"); - // copy sections pertaining to CME - ppeImgRc = buildCmeImage( i_pImageIn, pChipHomer, i_imgType ); + // copy sections pertaining to self restore + // Note: this creates the CPMR header portion - FAPI_ASSERT( ( IMG_BUILD_SUCCESS == ppeImgRc ), - fapi2::P9_CME_BUILD_FAIL() - .set_CME_FAIL_SECTN( ppeImgRc ), - "Failed to copy CME section in HOMER" ); - FAPI_DBG("cme built"); //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), "Error from FAPI_ATTR_GET for attribute ATTR_FUSED_CORE_MODE"); - // copy sections pertaining to self restore + + FAPI_INF("CPMR / Self Restore building"); ppeImgRc = buildCoreRestoreImage( i_pImageIn, pChipHomer, i_imgType, fuseModeState ); FAPI_ASSERT( ( IMG_BUILD_SUCCESS == ppeImgRc ), - fapi2::P9_SELF_RESTORE_BUILD_FAIL() + fapi2::SELF_RESTORE_BUILD_FAIL() .set_SELF_RESTORE_FAIL_SECTN( ppeImgRc ), "Failed to copy core self restore section in HOMER" ); - FAPI_DBG("self restore built "); + FAPI_INF("Self Restore built "); + + // copy sections pertaining to CME + FAPI_INF("CPMR / CME building"); + ppeImgRc = buildCmeImage( i_pImageIn, pChipHomer, i_imgType ); + ppeImgRc = IMG_BUILD_SUCCESS; + + FAPI_ASSERT( ( IMG_BUILD_SUCCESS == ppeImgRc ), + fapi2::CME_BUILD_FAIL() + .set_CME_FAIL_SECTN( ppeImgRc ), + "Failed to copy CME section in HOMER" ); + FAPI_INF("CME built"); + + FAPI_INF("PGPE building"); + //FIXME RTC 148009 PGPE Header needs to be defined. + ppeImgRc = buildPgpeImage( i_pImageIn, pChipHomer, i_imgType ); + + FAPI_ASSERT( ( IMG_BUILD_SUCCESS == ppeImgRc ), + fapi2::PGPE_BUILD_FAIL() + .set_PGPE_FAIL_SECTN( ppeImgRc ), + "Failed to copy PGPE section in HOMER" ); + FAPI_INF("PGPE built"); + + //Update CPMR Header area n HOMER with CME Image related information. + updateCpmrHeaderCME( pChipHomer ); + + uint8_t ecLevel = 0; + FAPI_TRY(FAPI_ATTR_GET_PRIVILEGED(fapi2::ATTR_EC, + i_procTgt, + ecLevel), + "Error from for attribute ATTR_EC"); +#if 0 + ppeImgRc = copyRingsFromHwImage( i_pImageIn, + i_pRingOverride, + i_pHomerImage, + ecLevel, + i_pBuf1, + i_sizeBuf1, + i_pBuf2, + i_sizeBuf2, + i_imgType, + qpmrHdr, + PLAT_SGPE ); + + 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 ); + + 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" ); + + 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 ); + + //Finally update the attributes storing PGPE and SGPE's boot copier offset. + QpmrHeaderLayout_t* pQpmrHdr = (QpmrHeaderLayout_t*)pChipHomer->qpmrRegion.sgpeRegion.qpmrHeader; + + uint32_t attrVal = SWIZZLE_4_BYTE(pQpmrHdr->bootCopierOffset); + attrVal |= (0x80000000 | ONE_MB); + + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_STOPGPE_BOOT_COPIER_IVPR_OFFSET, + i_procTgt, + attrVal ), + "Error from FAPI_ATTR_SET for attribute ATTR_STOPGPE_BOOT_COPIER_IVPR_OFFSET"); + + FAPI_DBG("Set ATTR_STOPGPE_BOOT_COPIER_IVPR_OFFSET to 0x%08x", attrVal ); + + attrVal = (uint8_t*)(pChipHomer->ppmrRegion.l1BootLoader) - (uint8_t*)(pChipHomer); + attrVal |= 0x80000000; + FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_PSTATEGPE_BOOT_COPIER_IVPR_OFFSET, + i_procTgt, + attrVal ), + "Error from FAPI_ATTR_SET for attribute ATTR_PSTATEGPE_BOOT_COPIER_IVPR_OFFSET"); + FAPI_DBG("Set ATTR_PSTATEGPE_BOOT_COPIER_IVPR_OFFSET to 0x%08x", attrVal ); } while(0); 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 dda135247..8bfca112e 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 @@ -117,26 +117,40 @@ extern "C" typedef fapi2::ReturnCode( *p9_hcode_image_build_FP_t ) ( CONST_FAPI2_PROC& i_procTgt, - void* const i_pImageIn, - void* o_pImageOut, - SysPhase_t i_phase, + void* const i_pImageIn, + void* i_pHomerImage, + void* const i_pRingOverride, + SysPhase_t i_phase, ImageType_t i_imgType, - void* i_pBuf ); + void* const i_pBuf1, + const uint32_t i_sizeBuf1, + void* const i_pBuf2, + const uint32_t i_sizeBuf2 ); /** * @brief builds a STOP image using a refrence image as input. - * @param i_procTgt fapi2 target for processor chip. - * @param i_pImageIn points to memory mapped refrence image in PNOR. - * @param o_pImageOut pointer to the beginning of the HOMER image buffer. - * @param i_phase phase of the system i.e. IPL or Hypervisor/rebuild mode. - * @param i_pBuf buffer of size >= HW_IMG_RING_SIZE for handling ring. + * @param i_procTgt fapi2 target for processor chip. + * @param i_pImageIn points to memory mapped refrence image in PNOR. + * @param i_pHomerImage pointer to the beginning of the HOMER image buffer. + * @param i_pRingOverride pointer to the location of override ring. NULL means override not available. + * @param i_phase phase of the system i.e. IPL or Hypervisor/rebuild mode. + * @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_sizeBuf2 size of work buffer2 * @note needs attribute ATTR_EC */ fapi2::ReturnCode p9_hcode_image_build( CONST_FAPI2_PROC& i_procTgt, - void* const i_pImageIn, - void* o_pImageOut, - SysPhase_t i_phase, - ImageType_t i_imgType, - void* i_pBuf ); + void* const i_pImageIn, + void* i_pHomerImage, + void* const i_pRingOverride, + SysPhase_t i_phase, + ImageType_t i_imgType, + void* const i_pBuf1, + const uint32_t i_sizeBuf1, + void* const i_pBuf2, + const uint32_t i_sizeBuf2 + ); } // 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 aca48706d..e9a6ca4d1 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 @@ -16,9 +16,10 @@ # deposited with the U.S. Copyright Office. # # IBM_PROLOG_END_TAG -PROCEDURE=p9_hcode_image_build +PROCEDURE = p9_hcode_image_build HCODE_UTIL=$(ROOTPATH)/chips/p9/procedures/utils/stopreg/ HCODE_UTIL+=$(ROOTPATH)/chips/p9/xip/ +HCODE_UTIL+=$(ROOTPATH)/chips/p9/utils/imageProcs/ HCODE_UTIL+=$(ROOTPATH)/chips/p9/procedures/hwp/lib/ HCODE_UTIL+=$(ROOTPATH)/tools/imageProcs/ $(PROCEDURE)_DEPLIBS+=p9_xip_image diff --git a/src/import/chips/p9/procedures/xml/attribute_info/p9_hcode_image_build_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/p9_hcode_image_build_attributes.xml index 782facfff..656822b97 100644 --- a/src/import/chips/p9/procedures/xml/attribute_info/p9_hcode_image_build_attributes.xml +++ b/src/import/chips/p9/procedures/xml/attribute_info/p9_hcode_image_build_attributes.xml @@ -28,6 +28,7 @@ else zero. It needs to be populated during ipl but before istep 15. </description> <valueType>uint8</valueType> + <enum> CORE_UNFUSED = 0x0, CORE_FUSED = 0x1 </enum> <platInit/> </attribute> </attributes> diff --git a/src/import/chips/p9/procedures/xml/attribute_info/pm_hwp_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/pm_hwp_attributes.xml index 3ef71f073..235a5866f 100644 --- a/src/import/chips/p9/procedures/xml/attribute_info/pm_hwp_attributes.xml +++ b/src/import/chips/p9/procedures/xml/attribute_info/pm_hwp_attributes.xml @@ -32,6 +32,7 @@ will be Sreset after this value is established. </description> <valueType>uint32</valueType> + <writeable/> </attribute> <!-- ********************************************************************* --> <attribute> @@ -44,6 +45,7 @@ will be Sreset after this value is established </description> <valueType>uint32</valueType> + <writeable/> </attribute> <!-- ********************************************************************* --> <attribute> diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_hcode_image_build_errors.xml b/src/import/chips/p9/procedures/xml/error_info/p9_hcode_image_build_errors.xml index 9205b1307..289959b9e 100755 --- a/src/import/chips/p9/procedures/xml/error_info/p9_hcode_image_build_errors.xml +++ b/src/import/chips/p9/procedures/xml/error_info/p9_hcode_image_build_errors.xml @@ -21,7 +21,7 @@ <hwpErrors> <!-- *********************************************************************** --> <hwpError> - <rc>RC_P9_IMG_PTR_ERROR</rc> + <rc>RC_IMG_PTR_ERROR</rc> <description>Image pointers passed are either bad or point to same location.</description> <ffdc>HW_IMG_BUF_PTR</ffdc> <ffdc>HOMER_IMG_BUF_PTR</ffdc> @@ -32,7 +32,7 @@ </hwpError> <!-- *********************************************************************** --> <hwpError> - <rc>RC_P9_HW_IMAGE_INVALID_SIZE</rc> + <rc>RC_HW_IMAGE_INVALID_SIZE</rc> <description>Hardware Image size is not in expected range </description> <ffdc>HW_IMG_SIZE</ffdc> <ffdc>MAX_HW_IMG_SIZE</ffdc> @@ -43,7 +43,7 @@ </hwpError> <!-- *********************************************************************** --> <hwpError> - <rc>RC_P9_HCODE_INVALID_PHASE</rc> + <rc>RC_HCODE_INVALID_PHASE</rc> <description>System phase is neither IPL nor Hypervisor</description> <ffdc>SYS_PHASE</ffdc> <callout> @@ -53,7 +53,7 @@ </hwpError> <!-- *********************************************************************** --> <hwpError> - <rc>RC_P9_HCODE_INVALID_TEMP_BUF</rc> + <rc>RC_HCODE_INVALID_TEMP_BUF</rc> <description>Temporary buffer is invalid.</description> <ffdc>TEMP_BUF_PTR</ffdc> <ffdc>TEMP_BUF_SIZE</ffdc> @@ -64,7 +64,18 @@ </hwpError> <!-- *********************************************************************** --> <hwpError> - <rc>RC_P9_HCODE_INVALID_IMG_TYPE</rc> + <rc>RC_HCODE_TEMP_BUF_SIZE</rc> + <description>Temporary buffer size invalid</description> + <ffdc>TEMP_BUF1_SIZE</ffdc> + <ffdc>TEMP_BUF2_SIZE</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_HCODE_INVALID_IMG_TYPE</rc> <description>Invalid image type passed for hcode image build.</description> <callout> <procedure>CODE</procedure> @@ -73,8 +84,8 @@ </hwpError> <!-- *********************************************************************** --> <hwpError> - <rc>RC_P9_SGPE_BUILD_FAIL</rc> - <description>hcode image build procedure failed to add sgpe image</description> + <rc>RC_SGPE_BUILD_FAIL</rc> + <description>hcode image build procedure failed to add SGPE image</description> <ffdc>SGPE_FAIL_SECTN</ffdc> <callout> <procedure>CODE</procedure> @@ -83,7 +94,7 @@ </hwpError> <!-- *********************************************************************** --> <hwpError> - <rc>RC_P9_SELF_RESTORE_BUILD_FAIL</rc> + <rc>RC_SELF_RESTORE_BUILD_FAIL</rc> <description>hcode image build procedure failed to add core self restore image</description> <ffdc>SELF_RESTORE_FAIL_SECTN</ffdc> <callout> @@ -93,7 +104,7 @@ </hwpError> <!-- *********************************************************************** --> <hwpError> - <rc>RC_P9_CME_BUILD_FAIL</rc> + <rc>RC_CME_BUILD_FAIL</rc> <description>hcode image build procedure failed to add CME image</description> <ffdc>CME_FAIL_SECTN</ffdc> <callout> @@ -102,4 +113,24 @@ </callout> </hwpError> <!-- *********************************************************************** --> + <hwpError> + <rc>RC_PGPE_BUILD_FAIL</rc> + <description>hcode image build procedure failed to add PGPE image</description> + <ffdc>PGPE_FAIL_SECTN</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_SCAN_RING_BUILD_FAIL</rc> + <description>hcode image build procedure failed to add PGPE image</description> + <ffdc>RING_FAIL_RC</ffdc> + <callout> + <procedure>CODE</procedure> + <priority>HIGH</priority> + </callout> + </hwpError> + <!-- *********************************************************************** --> </hwpErrors> |