diff options
author | Van Lee <vanlee@us.ibm.com> | 2012-12-13 15:02:51 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-12-18 16:59:49 -0600 |
commit | d00706a9f8869af321b4ddb3dea0106d19cea312 (patch) | |
tree | c7cd59a618bc7604ccb6f786eccd6fedd4f0bdbd /src/usr/hwpf/hwp/build_winkle_images | |
parent | c945c66c24a6fc8195081c7ecd44aede10df90a1 (diff) | |
download | talos-hostboot-d00706a9f8869af321b4ddb3dea0106d19cea312.tar.gz talos-hostboot-d00706a9f8869af321b4ddb3dea0106d19cea312.zip |
HWP: integrate p8_xip_customize into hostboot
Change-Id: Idfe342adb19a8cc1c1eb5ec59dbaba1c858da0c1
RTC: 42182
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/2686
Reviewed-by: Thi N. Tran <thi@us.ibm.com>
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/hwpf/hwp/build_winkle_images')
18 files changed, 2393 insertions, 457 deletions
diff --git a/src/usr/hwpf/hwp/build_winkle_images/makefile b/src/usr/hwpf/hwp/build_winkle_images/makefile index c91201bd0..6f94ad7cf 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/makefile +++ b/src/usr/hwpf/hwp/build_winkle_images/makefile @@ -35,6 +35,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/include ## NOTE: add the base istep dir here. EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/mvpd_accessors ## Include sub dirs ## NOTE: add a new EXTRAINCDIR when you add a new HWP @@ -58,7 +59,9 @@ OBJS = build_winkle_images.o \ p8_pmc_deconfig_setup.o \ p8_poreslw_init.o \ p8_set_pore_bar.o \ - p8_slw_build.o + p8_slw_build.o \ + p8_xip_customize.o \ + p8_ring_identification.o ## NOTE: add a new directory onto the vpaths when you add a new HWP ## EXAMPLE: @@ -67,7 +70,8 @@ VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/p8_set_pore_bar ## Point to the PORE image in PNOR -BINARY_FILES = $(IMGDIR)/procpore.dat:d177d9a2a28f80fc282f09b145d790fa56719ba2 +#BINARY_FILES = $(IMGDIR)/procpore.dat:d177d9a2a28f80fc282f09b145d790fa56719ba2 +BINARY_FILES = $(IMGDIR)/procpore.dat:8886974065a94f3ea83d98be88716e063bcba57e include ${ROOTPATH}/config.mk diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_delta_scan_rw.h b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_delta_scan_rw.h index 46f50e297..5a75f0290 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_delta_scan_rw.h +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_delta_scan_rw.h @@ -20,10 +20,10 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_delta_scan_rw.h,v 1.23 2012/09/21 15:08:02 cmolsen Exp $ +// $Id: p8_delta_scan_rw.h,v 1.27 2012/12/14 19:44:53 cmolsen Exp $ #define OVERRIDE_OFFSET 8 // Byte offset of forward pointer's addr relative // to base forward pointer's addr. -#define SIZE_IMAGE_BUF_MAX 50000000 // Max ~50MB image buffer size. +#define SIZE_IMAGE_BUF_MAX 5000000 // Max ~50MB image buffer size. #define SIZE_IMAGE_CENTAUR_MAX 5000000 // Max ~5MB image buffer size. #define SIZE_REPR_RING_MAX 50000 // Max ~50kB repr ring buffer size. #define SCOM_REG_MASK 0x00ffffff // Scom register mask (within a chiplet) @@ -31,6 +31,10 @@ #define CID_EX_LOW 0x10 // Lowest EX chiplet addr #define CID_EX_HIGH 0x1f // Highest EX chiplet addr +/***** Xip customize support ****/ +#define COMBINED_GOOD_VECTORS_TOC_NAME "combined_good_vectors" +#define PERV_PIB_REPR_VECTOR_TOC_NAME "proc_sbe_pibmem_repair_vector" +#define NEST_SKEWADJUST_VECTOR_TOC_NAME "proc_sbe_nest_skewadjust_vector" /***** Scan setting *****/ #define OPCG_SCAN_RATIO 4 @@ -65,10 +69,14 @@ #define DSLWB_SLWB_IMAGE_ERROR 44 #define DSLWB_SLWB_UNKNOWN_ERROR 45 #define IMGBUILD_SUCCESS 0 // Successful img build. -#define IMGBUILD_NO_RINGS_FOUND 1 // Successful img build but no rings found. -#define IMGBUILD_BAD_ARGS 2 // Bad function arguments. -#define IMGBUILD_ERR_MEMORY 4 // Memory allocation error. -#define IMGBUILD_ERR_CHECK_CODE 6 // Coding or image data problem. +#define IMGBUILD_ERR_GENERIC 1 // Non-specific error code. +#define IMGBUILD_ERR_FILE_ACCESS 2 // Unable to access/open file. +#define IMGBUILD_ERR_CHIPLET_ID_MESS 4 // Chiplet ID mess(mostly for VPD rings). +#define IMGBUILD_NO_RINGS_FOUND 5 // Successful img build but no rings found. +#define IMGBUILD_BAD_ARGS 6 // Bad function arguments. +#define IMGBUILD_ERR_MEMORY 7 // Memory allocation error. +#define IMGBUILD_ERR_RING_TOO_LARGE 8 // Ring size exceeds HB/PHYP's buffer. +#define IMGBUILD_ERR_CHECK_CODE 9 // Coding or image data problem. #define IMGBUILD_INVALID_IMAGE 10 // Invalid image. #define IMGBUILD_IMAGE_SIZE_MISMATCH 11 // Mismatch between image sizes. #define IMGBUILD_ERR_PORE_INLINE 20 // Pore inline error. @@ -85,7 +93,7 @@ #define IMGBUILD_ERR_XIP_UNKNOWN 58 // Unknown XIP image error. #define IMGBUILD_ERR_RS4_DECOMPRESS 59 // Error during RS4 decompression. #define IMGBUILD_ERR_RAM_HDRS_NOT_SYNCED 61 // Ram headers not synchronized. -#define IMGBUILD_ERR_RAM_TABLE_OVERFLOW 63 // Ram table entry overflow. +#define IMGBUILD_ERR_RAM_TABLE_FULL 63 // Ram table is full. #define IMGBUILD_ERR_RAM_CODE 64 // Code error in Ram API code. #define IMGBUILD_ERR_RAM_INVALID_PARM 65 // Invalid Ramming parameter. #define IMGBUILD_WARN_RAM_TABLE_CONTAMINATION 66 // Ram table contamination @@ -95,6 +103,7 @@ #define IMGBUILD_ERR_SCOM_HDRS_NOT_SYNCD 72 // Scom headers out of sync. #define IMGBUILD_ERR_SCOM_ENTRY_NOT_FOUND 74 // Scom entry not found (OR/AND oper.) #define IMGBUILD_ERR_SCOM_REPEAT_ENTRIES 76 // Repeat entries not allow. +#define IMGBUILD_ERR_SCOM_INVALID_SUBSECTION 77 // Invalid subsection value. #define IMGBUILD_ERR_SCOM_TABLE_FAIL 79 // Unsuccessful SCOM table build. #if defined SLW_COMMAND_LINE_RAM || defined XIPC_COMMAND_LINE @@ -235,30 +244,54 @@ int write_ring_block_to_image( void *io_image, DeltaRingLayout *i_ringBlock, uint32_t i_sizeImageMax); -int gen_ring_delta_state( +int gen_ring_delta_state( uint32_t bitLen, uint32_t *i_init, uint32_t *i_alter, uint32_t *o_delta, uint32_t verbose); -int write_delta_ring_to_image( +//int write_delta_ring_to_image( +// char *i_fnImage, +// CompressedScanData *i_RS4, +// uint32_t i_ddLevel, +// uint8_t i_sysPhase, +// uint8_t i_override, +// char *i_varName, +// char *i_fnMetaData, +// uint32_t verbose); +int write_rs4_ring_to_ref_image( char *i_fnImage, CompressedScanData *i_RS4, uint32_t i_ddLevel, uint8_t i_sysPhase, uint8_t i_override, + uint8_t i_ringType, char *i_varName, char *i_fnMetaData, + void *i_bufTmp, + uint32_t i_sizeBufTmp, uint32_t verbose); -int write_repr_ring_to_image( +int write_vpd_ring_to_ipl_image( void *io_image, - uint32_t *io_sizeImageOut, + uint32_t &io_sizeImageOut, CompressedScanData *i_bufRs4Ring, - uint8_t i_chipletId, + uint32_t i_ddLevel, uint8_t i_sysPhase, - char *i_ringName); + char *i_ringName, + void *i_bufTmp, + uint32_t i_sizeBufTmp); + +int write_vpd_ring_to_slw_image( + void *io_image, + uint32_t &io_sizeImageOut, + CompressedScanData *i_bufRs4Ring, + uint32_t i_ddLevel, + uint8_t i_sysPhase, + char *i_ringName, + void *i_bufTmp, + uint32_t i_sizeBufTmp); int get_delta_ring_from_image( char *i_fnImage, diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help.C b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help.C index 2d5814632..555dfc3cb 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help.C +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help.C @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_image_help.C,v 1.28 2012/09/27 20:59:51 cmolsen Exp $ +// $Id: p8_image_help.C,v 1.32 2012/11/14 12:33:45 cmolsen Exp $ // /*------------------------------------------------------------------------------*/ /* *! TITLE : p8_image_help.C */ @@ -58,11 +58,11 @@ int get_ring_layout_from_image( const void *i_imageIn, { uint32_t rc=0, rcLoc=0; uint8_t bRingFound=0, bRingEOS=0; - DeltaRingLayout *thisRingLayout=NULL, *nextRingLayout=NULL; //Pointers into memory mapped image. DO NOT CHANGE MEMBERS! + DeltaRingLayout *thisRingLayout, *nextRingLayout; //Pointers into memory mapped image. DO NOT CHANGE MEMBERS! uint32_t sizeInitf; SbeXipSection hostSection; void *initfHostAddress0; - + SBE_XIP_ERROR_STRINGS(errorStrings); // Always first get the .initf stats from the TOC: @@ -71,7 +71,7 @@ int get_ring_layout_from_image( const void *i_imageIn, // rc = sbe_xip_get_section( i_imageIn, SBE_XIP_SECTION_RINGS, &hostSection); if (rc) { - MY_ERR("ERROR : sbe_xip_get_section() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("sbe_xip_get_section() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); MY_ERR("Probable cause:"); MY_ERR("\tThe section (=SBE_XIP_SECTION_RINGS=%i) was not found.",SBE_XIP_SECTION_RINGS); return IMGBUILD_ERR_KEYWORD_NOT_FOUND; @@ -80,7 +80,7 @@ int get_ring_layout_from_image( const void *i_imageIn, MY_INF("INFO : No ring data exists for the section ID = SBE_XIP_SECTION_RINGS (ID=%i).",SBE_XIP_SECTION_RINGS); return DSLWB_RING_SEARCH_NO_MATCH; // Implies exhaust search as well. } - initfHostAddress0 = (void*)((uintptr_t)i_imageIn + hostSection.iv_offset); + initfHostAddress0 = (void*)((uintptr_t)i_imageIn + hostSection.iv_offset); sizeInitf = hostSection.iv_size; // On first call, get the base offset to the .initf section. @@ -91,16 +91,16 @@ int get_ring_layout_from_image( const void *i_imageIn, else nextRingLayout = (DeltaRingLayout*)*nextRing; - MY_DBG("initfHostAddress0 = 0x%016llx",(uint64_t)initfHostAddress0); + MY_DBG("initfHostAddress0 = 0x%016llx",(uint64_t)initfHostAddress0); MY_DBG("sizeInitf = %i", sizeInitf); MY_DBG("nextRingLayout = 0x%016llx",(uint64_t)nextRingLayout); - + // Populate the output RS4 ring BE layout structure as well as local structure in host LE format where needed. // Note! Entire memory content is in BE format. So we do LE conversions where needed. // bRingFound = 0; bRingEOS = 0; - + // SEARCH loop: Parse ring blocks successively until we find a ring that matches: // ddLevel == i_ddLevel // sysPhase == i_sysPhase @@ -113,7 +113,7 @@ int get_ring_layout_from_image( const void *i_imageIn, MY_DBG("Next override = %i",thisRingLayout->override); MY_DBG("Next reserved1 = %i",thisRingLayout->reserved1); MY_DBG("Next reserved2 = %i",thisRingLayout->reserved2); - + if (myRev32(thisRingLayout->ddLevel)==i_ddLevel) { // Is there a non-specific DD level, like for sys phase? if ((thisRingLayout->sysPhase==0 && i_sysPhase==0) || (thisRingLayout->sysPhase==1 && i_sysPhase==1) || @@ -129,7 +129,7 @@ int get_ring_layout_from_image( const void *i_imageIn, *nextRing = NULL; MY_DBG("\tRing search exhausted!"); } - + } // End of SEARCH. if (bRingFound) { @@ -137,7 +137,7 @@ int get_ring_layout_from_image( const void *i_imageIn, rcLoc = DSLWB_RING_SEARCH_EXHAUST_MATCH; else rcLoc = DSLWB_RING_SEARCH_MATCH; - } + } else { *nextRing = NULL; if (bRingEOS) @@ -157,31 +157,31 @@ int get_ring_layout_from_image( const void *i_imageIn, o_rs4RingLayout->override = thisRingLayout->override; o_rs4RingLayout->reserved1 = thisRingLayout->reserved1; o_rs4RingLayout->reserved2 = thisRingLayout->reserved2; - o_rs4RingLayout->metaData = (char*)(&thisRingLayout->reserved2 + + o_rs4RingLayout->metaData = (char*)(&thisRingLayout->reserved2 + sizeof(thisRingLayout->reserved2)); - o_rs4RingLayout->rs4Launch = (uint32_t*)((uintptr_t)thisRingLayout + + o_rs4RingLayout->rs4Launch = (uint32_t*)((uintptr_t)thisRingLayout + myRev64(thisRingLayout->entryOffset)); // entryOffset, rs4Launch and ASM_RS4_LAUNCH_BUF_SIZE should already be 8-byte aligned. - o_rs4RingLayout->rs4Delta = (uint32_t*)( (uintptr_t)thisRingLayout + + o_rs4RingLayout->rs4Delta = (uint32_t*)( (uintptr_t)thisRingLayout + myRev64(thisRingLayout->entryOffset) + ASM_RS4_LAUNCH_BUF_SIZE ); - // Check that the ring layout structure in the memory is 8-byte aligned. This must + // Check that the ring layout structure in the memory is 8-byte aligned. This must // be so because: - // - The entryOffset address must be on an 8-byte boundary because the start of the - // .rings section must be 8-byte aligned AND because the rs4Delta member is the + // - The entryOffset address must be on an 8-byte boundary because the start of the + // .rings section must be 8-byte aligned AND because the rs4Delta member is the // last member and which must itself be 8-byte aligned. - // - These two things together means that both the beginning and end of the delta - // ring layout must be 8-byte aligned, and thus the whole block, i.e. sizeOfThis, + // - These two things together means that both the beginning and end of the delta + // ring layout must be 8-byte aligned, and thus the whole block, i.e. sizeOfThis, // must therefore automatically be 8-byte aligned. // Also check that the RS4 delta ring is 8-byte aligned. // Also check that the RS4 launcher is 8-byte aligned. // - if (((uintptr_t)thisRingLayout-(uintptr_t)i_imageIn)%8 || - myRev32(o_rs4RingLayout->sizeOfThis)%8 || - myRev64(o_rs4RingLayout->entryOffset)%8 || + if (((uintptr_t)thisRingLayout-(uintptr_t)i_imageIn)%8 || + myRev32(o_rs4RingLayout->sizeOfThis)%8 || + myRev64(o_rs4RingLayout->entryOffset)%8 || ASM_RS4_LAUNCH_BUF_SIZE%8) { - MY_ERR("ERROR : Ring block or layout structure is not 8-byte aligned:"); + MY_ERR("Ring block or layout structure is not 8-byte aligned:"); MY_ERR(" thisRingLayout-imageIn = %i",(uintptr_t)thisRingLayout-(uintptr_t)i_imageIn); MY_ERR(" o_rs4RingLayout->sizeOfThis = %i",myRev32(o_rs4RingLayout->sizeOfThis)); MY_ERR(" o_rs4RingLayout->entryOffset = %i",(uint32_t)myRev64(o_rs4RingLayout->entryOffset)); @@ -223,13 +223,20 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s uint32_t count=0; uint32_t rotateLen=0, remainder=0, remainingBits=0; uint64_t pore_imm64b=0; - uint32_t maxWfInlineLenInWords = 3*MAX_RING_SIZE/32; + //uint32_t maxWfInlineLenInWords = 3*MAX_RING_SIZE/32; + uint32_t maxWfInlineLenInWords; PoreInlineContext ctx; - *o_wfInline = (uint32_t*)malloc(maxWfInlineLenInWords); + maxWfInlineLenInWords = *o_wfInlineLenInWords; + +/* 2012-11-13: CMO- Commented out since both slw_build and centaur_build now pass + preallocated buffers. + if (*o_wfInline==NULL) + *o_wfInline = (uint32_t*)malloc(maxWfInlineLenInWords); +*/ pore_inline_context_create(&ctx, *o_wfInline, maxWfInlineLenInWords * 4, 0, 0); - + // Get chiplet and Ring Addr info. // -------------------------------------------------------------------------- @@ -241,8 +248,8 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s // Descr: SCOM reg for scan ring shifting. scanRing_poreAddr=scanRing_baseAddr; // Init scan ring rotate addr scanRingCheckWord=P8_SCAN_CHECK_WORD; // Header check word for checking ring write was successful - - // This fix is a direct copy of the setp1_mcreadand macro in ./ipl/sbe/p8_slw.H + + // This fix is a direct copy of the setp1_mcreadand macro in ./ipl/sbe/p8_slw.H uint64_t CLEAR_MC_TYPE_MASK=0x47; PoreInlineLocation src1=0, src2=0, tgt1=0, tgt2=0; pore_MR( &ctx, D1, P0); @@ -272,12 +279,12 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s MY_ERR("***inline_branch_fixup error (2) rc = %d", ctx.error); return ctx.error; } - + // We can assume that atomic lock is already in effect prior to WF calls. // It can probably also be assumed that functional clocks are stopped, but // let's do it and check for it anyway. /* CMO: 20120927 - Not working - Being debugged by EPM - PoreInlineLocation src0=0,tgt0=0; + PoreInlineLocation src0=0,tgt0=0; pore_imm64b = uint64_t(0x8C200E00)<<32; pore_STI(&ctx, P8_PORE_CLOCK_REGION_0x00030006, P0, pore_imm64b); pore_LD(&ctx, D1, P8_PORE_CLOCK_STATUS_0x00030008, P1); @@ -344,7 +351,7 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s MY_ERR("***STD D0 rc = %d", ctx.error); return ctx.error; } - + // Check how many 32-bit shift ops are needed and if we need final shift of remaining bit. count = i_ringBitLen/32; remainder = i_ringBitLen%32; @@ -357,7 +364,7 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s // CMO: I changed the following to not skip the first 32-bit. //remainingBits = i_ringBitLen-32; //Yong impl. remainingBits = i_ringBitLen; //Mike impl. - + MY_DBG("count=%i rem=%i remBits=%i",count,remainder,remainingBits); // Compare 32 bit data at a time then shift ring (p7+ reqmt) @@ -365,10 +372,10 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s // Read and compare init and flush values 32 bits at a time. Store delta in o_delta buffer. //for (i=1; i<count; i++) { //Yong impl for (i=0; i<count; i++) { //Mike impl - + //==================================================================================== // If flush & init values are identical, increase the read count, no code needed. - // When the discrepancy is found, read (rotate the ring) up to current address + // When the discrepancy is found, read (rotate the ring) up to current address // then scan/write in the last 32 bits //==================================================================================== // Note: For PORE scan instruction, set Port to 3. Bit 16 Must be set to 1. @@ -429,14 +436,14 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s if (ctx.error > 0) { MY_ERR("***WORST CASE PIB(1) rc = %d", ctx.error); return ctx.error; - } + } #else scanRing_poreAddr=scanRing_baseAddr | rotateLen; pore_LD(&ctx, D0, scanRing_poreAddr, P1); if (ctx.error > 0) { MY_ERR("***LD D0 rc = %d", ctx.error); return ctx.error; - } + } #endif #endif @@ -467,13 +474,13 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s else { // i_deltaRing[i]==0 (i.e., init and alter states are identical). // Increase rotate length by remaining scan bits (32 by default). - + // Increase rotate length by remaining scan bits (default 32 bits) if (remainingBits>32) rotateLen = rotateLen + 32; else rotateLen = rotateLen + remainingBits; - + #ifdef IMGBUILD_PPD_WF_POLLING_PROT uint32_t nwait2=0; PoreInlineLocation srcp2=0,tgtp2=0; @@ -528,7 +535,7 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s remainingBits = 0; } // End of for loop - + // If the scan ring has not been rotated to the original position // shift the ring by remaining shift bit length. (No need to do polling here.) if (rotateLen>0) { @@ -620,8 +627,8 @@ int create_wiggle_flip_prg( uint32_t *i_deltaRing, // scan ring delta s pore_MR( &ctx, D1, P0); pore_ANDI( &ctx, D1, D1, CLEAR_MC_TYPE_MASK); pore_ORI( &ctx, D1, D1, BIT(60)); - pore_MR( &ctx, P1, D1); - if (ctx.error > 0) { + pore_MR( &ctx, P1, D1); + if (ctx.error > 0) { MY_ERR("***setp1_mcreadand rc = %d", ctx.error); return ctx.error; } @@ -747,55 +754,55 @@ int write_wiggle_flip_to_image( void *io_imageOut, void *ringsBuffer=NULL; uint32_t ringRingsOffset=0; uint64_t ringPoreAddress=0,backPtr=0,fwdPtr=0,fwdPtrCheck; - + SBE_XIP_ERROR_STRINGS(errorStrings); - MY_DBG("wfInlineLenInWords=%i", i_wfInlineLenInWords); - + MY_DBG("wfInlineLenInWords=%i", i_wfInlineLenInWords); + // Modify the input ring layout content - // - Remove the qualifier section: ddLevel, sysPhase, override and reserved1+2. + // - Remove the qualifier section: ddLevel, sysPhase, override and reserved1+2. // This means reducing the entryOffset by the size of these qualifiers. - // - The new WF ring block and start of WF code must both be 8-byte aligned. + // - The new WF ring block and start of WF code must both be 8-byte aligned. // - RS4 entryOffset is already 8-byte aligned. // - The WF code section, i.e. wfInlineLenInWords, is already 8-byte aligned. // - i_ringLayout->entryOffset = + i_ringLayout->entryOffset = myRev64( myByteAlign(8, myRev64(i_ringLayout->entryOffset) - sizeof(i_ringLayout->ddLevel) - sizeof(i_ringLayout->sysPhase) - sizeof(i_ringLayout->override) - sizeof(i_ringLayout->reserved1) - sizeof(i_ringLayout->reserved2) ) ); - i_ringLayout->sizeOfThis = + i_ringLayout->sizeOfThis = myRev32( myRev64(i_ringLayout->entryOffset) + i_wfInlineLenInWords*4 ); - + // Not really any need for this. Just being consistent. Once we have transitioned completely to new - // headers, then ditch i_wfInline from parm list and assign wfInline to layout in main program. + // headers, then ditch i_wfInline from parm list and assign wfInline to layout in main program. i_ringLayout->wfInline = i_wfInline; - + if (myRev64(i_ringLayout->entryOffset)%8 || myRev32(i_ringLayout->sizeOfThis)%8) { - MY_ERR("ERROR : Ring block or WF code origin not 8-byte aligned."); + MY_ERR("Ring block or WF code origin not 8-byte aligned."); return IMGBUILD_ERR_MISALIGNED_RING_LAYOUT; } - + // Calc the size of the data section we're adding and the resulting output image. // rc = sbe_xip_image_size( io_imageOut, &sizeImageIn); if (rc) { - MY_ERR("ERROR : sbe_xip_image_size() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("sbe_xip_image_size() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); return IMGBUILD_ERR_XIP_MISC; } sizeNewDataBlock = myRev32(i_ringLayout->sizeOfThis); // ...estimate max size of new image - sizeImageOutThisEst = sizeImageIn + sizeNewDataBlock + SBE_XIP_MAX_SECTION_ALIGNMENT; // + sizeImageOutThisEst = sizeImageIn + sizeNewDataBlock + SBE_XIP_MAX_SECTION_ALIGNMENT; // if (sizeImageOutThisEst>*i_sizeImageMaxNew) { - MY_ERR("ERROR : Estimated new image size (=%i) would exceed max allowed size (=%i).", + MY_ERR("Estimated new image size (=%i) would exceed max allowed size (=%i).", sizeImageOutThisEst, *i_sizeImageMaxNew); *i_sizeImageMaxNew = sizeImageOutThisEst; return IMGBUILD_ERR_IMAGE_TOO_LARGE; } - + MY_DBG("Input image size\t\t= %6i\n\tNew rings data block size\t= %6i\n\tOutput image size (max)\t\t<=%6i", sizeImageIn, sizeNewDataBlock, sizeImageOutThisEst); MY_DBG("entryOffset = %i\n\tsizeOfThis = %i\n\tMeta data size = %i", @@ -808,7 +815,7 @@ int write_wiggle_flip_to_image( void *io_imageOut, // ringsBuffer = malloc((size_t)sizeNewDataBlock); if (ringsBuffer == NULL) { - MY_ERR("ERROR : malloc() of initf buffer failed."); + MY_ERR("malloc() of initf buffer failed."); return IMGBUILD_ERR_MEMORY; } // ... First, copy WF ring layout header into ringsBuffer in BIG-ENDIAN format. @@ -823,7 +830,7 @@ int write_wiggle_flip_to_image( void *io_imageOut, bufLC = bufLC + deltaLC; deltaLC = (uint32_t)myRev64(i_ringLayout->entryOffset) - bufLC; if (deltaLC<0 || deltaLC>=8) { - MY_ERR("ERROR : Ring layout mess. Check code or delta_scan(). deltaLC=%i",deltaLC); + MY_ERR("Ring layout mess. Check code or delta_scan(). deltaLC=%i",deltaLC); return IMGBUILD_ERR_CHECK_CODE; } if (deltaLC>0) { @@ -834,24 +841,24 @@ int write_wiggle_flip_to_image( void *io_imageOut, // ... now do the WF buffer bufLC = bufLC + deltaLC; if (bufLC!=(uint32_t)myRev64(i_ringLayout->entryOffset)) { - MY_ERR("ERROR : Ring layout messup. Check code or delta_scan()."); + MY_ERR("Ring layout messup. Check code or delta_scan()."); return IMGBUILD_ERR_CHECK_CODE; } deltaLC = i_wfInlineLenInWords*4; memcpy( (uint8_t*)ringsBuffer+bufLC, i_wfInline, deltaLC); - + // Append WF ring layout to .rings section of in-memory input image. // Note! All layout members should already be 8-byte aligned. // - rc = sbe_xip_append( io_imageOut, - SBE_XIP_SECTION_RINGS, + rc = sbe_xip_append( io_imageOut, + SBE_XIP_SECTION_RINGS, (void*)ringsBuffer, sizeNewDataBlock, sizeImageOutThisEst, &ringRingsOffset); MY_DBG("ringRingsOffset=0x%08x",ringRingsOffset); if (rc) { - MY_ERR("ERROR : sbe_xip_append() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("sbe_xip_append() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); if (ringsBuffer) free(ringsBuffer); return IMGBUILD_ERR_XIP_MISC; } @@ -861,12 +868,12 @@ int write_wiggle_flip_to_image( void *io_imageOut, *i_sizeImageMaxNew = sizeImageOutThis; rc = sbe_xip_validate( io_imageOut, sizeImageOutThis); if (rc) { - MY_ERR("ERROR : sbe_xip_validate() of output image failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("sbe_xip_validate() of output image failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); if (ringsBuffer) free(ringsBuffer); return IMGBUILD_ERR_XIP_MISC; } MY_DBG("Successful append of RS4 ring to .rings. Next, update forward ptr..."); - + // Update forward pointer associated with the ring/var name + any override offset. // // Convert the ring offset (wrt .rings address) to an PORE address @@ -874,29 +881,29 @@ int write_wiggle_flip_to_image( void *io_imageOut, fwdPtr = ringPoreAddress; MY_DBG("fwdPtr=0x%016llx", fwdPtr); if (rc) { - MY_ERR("ERROR : sbe_xip_section2pore() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("sbe_xip_section2pore() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); if (ringsBuffer) free(ringsBuffer); return IMGBUILD_ERR_XIP_MISC; } // ...then update the forward pointer, i.e. the old "variable/ring name's" pointer. - // DO NOT add any 8-byte offset if override ring. The backItemPtr already has this + // DO NOT add any 8-byte offset if override ring. The backItemPtr already has this // from p8_delta_scan. // backPtr = myRev64(i_ringLayout->backItemPtr); MY_DBG("backPtr = 0x%016llx", backPtr); - rc = sbe_xip_write_uint64( io_imageOut, + rc = sbe_xip_write_uint64( io_imageOut, backPtr, fwdPtr); rc = rc+sbe_xip_read_uint64(io_imageOut, backPtr, &fwdPtrCheck); if (rc) { - MY_ERR("ERROR : sbe_xip_[write,read]_uint64() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("sbe_xip_[write,read]_uint64() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); if (ringsBuffer) free(ringsBuffer); return IMGBUILD_ERR_XIP_MISC; } if (fwdPtrCheck!=ringPoreAddress || backPtr!=myRev64(i_ringLayout->backItemPtr)) { - MY_ERR("ERROR : Forward or backward pointer mess. Check code."); + MY_ERR("Forward or backward pointer mess. Check code."); MY_ERR("fwdPtr =0x%016llx",fwdPtr); MY_ERR("fwdPtrCheck =0x%016llx",fwdPtrCheck); MY_ERR("layout bckPtr=0x%016llx",myRev64(i_ringLayout->backItemPtr)); @@ -907,16 +914,16 @@ int write_wiggle_flip_to_image( void *io_imageOut, // ...test if successful update. rc = sbe_xip_validate( io_imageOut, sizeImageOutThis); if (rc) { - MY_ERR("ERROR : sbe_xip_validate() of output image failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("sbe_xip_validate() of output image failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); MY_ERR("Probable cause:"); MY_ERR("\tsbe_xip_write_uint64() updated at the wrong address (=0x%016llx)", myRev64(i_ringLayout->backItemPtr)); if (ringsBuffer) free(ringsBuffer); return IMGBUILD_ERR_XIP_MISC; } - + if (ringsBuffer) free(ringsBuffer); - + return rc; } @@ -936,35 +943,35 @@ int append_empty_section( void *io_image, SBE_XIP_ERROR_STRINGS(errorStrings); rc = 0; - + if (i_sizeSection==0) { MY_INF("INFO : Requested append size = 0. Nothing to do."); return rc; } - + // Check if there is enough room in the new image to add section. // sbe_xip_image_size( io_image, &sizeImageIn); // ...estimate max size of new image sizeImageOutThisEst = sizeImageIn + i_sizeSection + SBE_XIP_MAX_SECTION_ALIGNMENT; if (sizeImageOutThisEst>*i_sizeImageMaxNew) { - MY_ERR("ERROR : Estimated new image size (=%i) would exceed max allowed size (=%i).", + MY_ERR("Estimated new image size (=%i) would exceed max allowed size (=%i).", sizeImageOutThisEst, *i_sizeImageMaxNew); *i_sizeImageMaxNew = sizeImageOutThisEst; return IMGBUILD_ERR_IMAGE_TOO_LARGE; } - + // Add the 0-initialized buffer as a section append. // bufEmpty = calloc( i_sizeSection, 1); - rc = sbe_xip_append( io_image, - i_sectionId, + rc = sbe_xip_append( io_image, + i_sectionId, bufEmpty, i_sizeSection, sizeImageOutThisEst, &offsetCheck); if (rc) { - MY_ERR("ERROR : xip_append() failed: %s\n",SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("xip_append() failed: %s\n",SBE_XIP_ERROR_STRING(errorStrings, rc)); if (bufEmpty) free(bufEmpty); return DSLWB_SLWB_IMAGE_ERROR; @@ -977,11 +984,11 @@ int append_empty_section( void *io_image, *i_sizeImageMaxNew = sizeImageOutThis; rc = sbe_xip_validate( io_image, sizeImageOutThis); if (rc) { - MY_ERR("ERROR : xip_validate() of output image failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("xip_validate() of output image failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); if (bufEmpty) free(bufEmpty); return IMGBUILD_ERR_XIP_MISC; } - + if (bufEmpty) free(bufEmpty); @@ -1001,9 +1008,10 @@ int initialize_slw_section( void *io_image, PoreInlineContext ctx; SbeXipSection xipSection; SbeXipItem xipTocItem; - void *hostScomTableFirst, *hostScomTableNext, *hostScomVectorFirst, *hostScomVectorNext; - uint64_t xipScomTableFirst; - ////void *bufRNNN=NULL; + void *hostScomTableNext, *hostScomVectorNext; + void *hostScomVectorFirstNC, *hostScomVectorFirstL2, *hostScomVectorFirstL3; + void *hostScomTableNC, *hostScomTableL2, *hostScomTableL3; + uint64_t xipScomTableNC, xipScomTableL2, xipScomTableL3; uint8_t bufRNNN[XIPSIZE_SCOM_ENTRY]; SBE_XIP_ERROR_STRINGS(errorStrings); @@ -1033,39 +1041,80 @@ int initialize_slw_section( void *io_image, MY_ERR("***_RET or _NOP generated rc = %d", ctx.error); return IMGBUILD_ERR_PORE_INLINE_ASM; } - + // ... get host and pore location of Scom table in .slw section. + // Note that we will assume, further down, that the NC section goes first, + // then the L2 section and then the L3 section. rc = sbe_xip_get_section( io_image, SBE_XIP_SECTION_SLW, &xipSection); if (rc) { - MY_ERR("ERROR : sbe_xip_get_section() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("sbe_xip_get_section() failed: %s", SBE_XIP_ERROR_STRING(errorStrings, rc)); MY_ERR("Probable cause:"); MY_ERR("\tThe section (=SBE_XIP_SECTION_SLW=%i) was not found.",SBE_XIP_SECTION_SLW); return IMGBUILD_ERR_KEYWORD_NOT_FOUND; } - hostScomTableFirst = (void*)((uintptr_t)io_image + xipSection.iv_offset + SLW_RAM_TABLE_SIZE); - sbe_xip_host2pore( io_image, hostScomTableFirst, &xipScomTableFirst); + hostScomTableNC = (void*)((uintptr_t)io_image + xipSection.iv_offset + SLW_RAM_TABLE_SIZE); + + // ... populate entire Scom table with RNNN IIS, incl NC, L2 and L3 sections. + for (i_iis=0; i_iis<SLW_SCOM_TABLE_SIZE_ALL; i_iis=i_iis+XIPSIZE_SCOM_ENTRY) { + hostScomTableNext = (void*)( (uintptr_t)hostScomTableNC + i_iis); + memcpy( hostScomTableNext, (void*)bufRNNN, XIPSIZE_SCOM_ENTRY); + } - // ... get location of Scom vector from TOC. - rc = sbe_xip_find( io_image, SLW_HOST_SCOM_VECTOR_TOC_NAME, &xipTocItem); + hostScomTableL2 = (void*)((uintptr_t)hostScomTableNC + SLW_SCOM_TABLE_SIZE_NC); + hostScomTableL3 = (void*)((uintptr_t)hostScomTableL2 + SLW_SCOM_TABLE_SIZE_L2); + + // ... get location of ----> Scom NC <---- vector from TOC. + rc = sbe_xip_find( io_image, SLW_HOST_SCOM_NC_VECTOR_TOC_NAME, &xipTocItem); if (rc) { - MY_ERR("ERROR : sbe_xip_find() failed w/rc=%i and %s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("sbe_xip_find() failed w/rc=%i and %s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); MY_ERR("Probable cause:"); - MY_ERR("\tThe keyword (=%s) was not found.",SLW_HOST_SCOM_VECTOR_TOC_NAME); + MY_ERR("\tThe keyword (=%s) was not found.",SLW_HOST_SCOM_NC_VECTOR_TOC_NAME); return IMGBUILD_ERR_KEYWORD_NOT_FOUND; } - sbe_xip_pore2host( io_image, xipTocItem.iv_address, &hostScomVectorFirst); + sbe_xip_pore2host( io_image, xipTocItem.iv_address, &hostScomVectorFirstNC); - // ... populate entire Scom table with RNNN IIS. - for (i_iis=0; i_iis<SLW_SCOM_TABLE_SIZE_ALL; i_iis=i_iis+XIPSIZE_SCOM_ENTRY) { - hostScomTableNext = (void*)( (uintptr_t)hostScomTableFirst + i_iis); - memcpy( hostScomTableNext, (void*)bufRNNN, XIPSIZE_SCOM_ENTRY); + // ... update Scom NC vector. + sbe_xip_host2pore( io_image, hostScomTableNC, &xipScomTableNC); + for (i_coreId=0; i_coreId<SLW_MAX_CORES; i_coreId++) { + hostScomVectorNext = (void*)( (uint64_t*)hostScomVectorFirstNC + i_coreId); + *(uint64_t*)hostScomVectorNext = myRev64( xipScomTableNC + + SLW_SCOM_TABLE_SPACE_PER_CORE_NC*i_coreId); } - // ... update Non-cache Scom vector. + // ... get location of ----> Scom L2 <---- vector from TOC. + rc = sbe_xip_find( io_image, SLW_HOST_SCOM_L2_VECTOR_TOC_NAME, &xipTocItem); + if (rc) { + MY_ERR("sbe_xip_find() failed w/rc=%i and %s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("Probable cause:"); + MY_ERR("\tThe keyword (=%s) was not found.",SLW_HOST_SCOM_L2_VECTOR_TOC_NAME); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + sbe_xip_pore2host( io_image, xipTocItem.iv_address, &hostScomVectorFirstL2); + + // ... update Scom L2 vector. + sbe_xip_host2pore( io_image, hostScomTableL2, &xipScomTableL2); for (i_coreId=0; i_coreId<SLW_MAX_CORES; i_coreId++) { - hostScomVectorNext = (void*)( (uint64_t*)hostScomVectorFirst + i_coreId); - *(uint64_t*)hostScomVectorNext = myRev64( xipScomTableFirst + - SLW_SCOM_TABLE_SPACE_PER_CORE_NC*i_coreId); + hostScomVectorNext = (void*)( (uint64_t*)hostScomVectorFirstL2 + i_coreId); + *(uint64_t*)hostScomVectorNext = myRev64( xipScomTableL2 + + SLW_SCOM_TABLE_SPACE_PER_CORE_L2*i_coreId); + } + + // ... get location of ----> Scom L3 <---- vector from TOC. + rc = sbe_xip_find( io_image, SLW_HOST_SCOM_L3_VECTOR_TOC_NAME, &xipTocItem); + if (rc) { + MY_ERR("sbe_xip_find() failed w/rc=%i and %s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("Probable cause:"); + MY_ERR("\tThe keyword (=%s) was not found.",SLW_HOST_SCOM_L3_VECTOR_TOC_NAME); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + sbe_xip_pore2host( io_image, xipTocItem.iv_address, &hostScomVectorFirstL3); + + // ... update Scom L3 vector. + sbe_xip_host2pore( io_image, hostScomTableL3, &xipScomTableL3); + for (i_coreId=0; i_coreId<SLW_MAX_CORES; i_coreId++) { + hostScomVectorNext = (void*)( (uint64_t*)hostScomVectorFirstL3 + i_coreId); + *(uint64_t*)hostScomVectorNext = myRev64( xipScomTableL3 + + SLW_SCOM_TABLE_SPACE_PER_CORE_L3*i_coreId); } return rc; @@ -1088,17 +1137,17 @@ int update_runtime_scom_pointer( void *io_image) // rc = sbe_xip_get_scalar( io_image, SLW_RUNTIME_SCOM_TOC_NAME, &xipSlwRuntimeAddr); if (rc) { - MY_ERR("ERROR : sbe_xip_set_scalar() failed w/rc=%i and %s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("sbe_xip_set_scalar() failed w/rc=%i and %s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); MY_ERR("Probable cause:"); MY_ERR("\tThe keyword (=%s) was not found.",SLW_RUNTIME_SCOM_TOC_NAME); return IMGBUILD_ERR_KEYWORD_NOT_FOUND; } - + // Update host_runtime_scom with sub_slw_runtime_scom's address. // rc = sbe_xip_set_scalar( io_image, HOST_RUNTIME_SCOM_TOC_NAME, xipSlwRuntimeAddr); if (rc) { - MY_ERR("ERROR : sbe_xip_set_scalar() failed w/rc=%i and %s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("sbe_xip_set_scalar() failed w/rc=%i and %s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); MY_ERR("Probable cause:"); MY_ERR("\tThe keyword (=%s) was not found.",HOST_RUNTIME_SCOM_TOC_NAME); return IMGBUILD_ERR_KEYWORD_NOT_FOUND; @@ -1108,29 +1157,341 @@ int update_runtime_scom_pointer( void *io_image) // rc = sbe_xip_get_scalar( io_image, SLW_EX_ENABLE_RUNTIME_SCOM_TOC_NAME, &xipSlwExEnableRuntimeAddr); if (rc) { - MY_ERR("ERROR : sbe_xip_set_scalar() failed w/rc=%i and %s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); - MY_ERR("Probable cause:"); - MY_ERR("\tThe keyword (=%s) was not found.",SLW_EX_ENABLE_RUNTIME_SCOM_TOC_NAME); - return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + MY_INF("WARNING : sbe_xip_get_scalar() failed w/rc=%i and msg=%s, but it's probably OK.", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_INF("Will skip trying to update ex_enable_runtime_scom.\n"); + MY_INF("Probable cause:"); + MY_INF("\tThe keyword (=%s) was not found.",SLW_EX_ENABLE_RUNTIME_SCOM_TOC_NAME); + } + else { + // Next, update ex_enable_runtime_scom with sub_slw_ex_enable_runtime_scom's address. + // (Assumption is that if sub_slw_ex_enable... exists then ex_enable... exists too.) + rc = sbe_xip_set_scalar( io_image, EX_ENABLE_RUNTIME_SCOM_TOC_NAME, xipSlwExEnableRuntimeAddr); + if (rc) { + MY_ERR("sbe_xip_set_scalar() failed w/rc=%i and msg=%s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); + MY_ERR("This is an odd error, indicating messed up or old image.\n"); + MY_ERR("Probable cause:"); + MY_ERR("\tThe keyword (=%s) was not found.",EX_ENABLE_RUNTIME_SCOM_TOC_NAME); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + } + + return 0; +} + + + +// write_vpd_ring_to_ipl_image() +// - For VPD rings, there is no notion of a base and override ring. There can only be +// one ring. Thus, for core ID specific rings, their vector locations are updated only +// by 8-bytes, unlike 16-bytes for non-VPD rings which have base+override. +// - Any ring, including ex_ rings, that have a chipletId==0xFF will get stored at its +// "top" or base position, i.e. as if it was coreId=0, or chipletId=0x10. +// - For IPL images, #R/G must be accessible through .fixed_toc since .toc is removed. +// and same is true for proc_sbe_decompress_scan_chiplet_address (for RS4 launch.) +// Notes: +// - This code has great similarity to write_delta_ring_to_image() in p8_delta_scan_w.C. +// Consider merging the two codes. +int write_vpd_ring_to_ipl_image(void *io_image, + uint32_t &io_sizeImageOut, + CompressedScanData *i_bufRs4Ring, + uint32_t i_ddLevel, + uint8_t i_sysPhase, + char *i_ringName, + void *i_bufTmp, + uint32_t i_sizeBufTmp) +{ + uint32_t rc=0, bufLC; + uint8_t chipletId, coreId; + uint32_t sizeRs4Launch, sizeRs4Ring; + uint32_t sizeImageIn, sizeImageOut, sizeImageOutEst, sizeNewDataBlock; + PoreInlineContext ctx; + uint32_t asmInitLC=0; + uint32_t asmBuffer[ASM_RS4_LAUNCH_BUF_SIZE/4]; + void *ringsBuffer=NULL; + uint64_t scanChipletAddress=0; + Rs4RingLayout rs4RingLayout, rs4RingLayoutBE; + uint32_t ringsDataBlockOffset=0; + uint64_t ringsDataBlockPoreAddr=0, addrOfFwdPtr=0; + SbeXipItem tocItem; + + SBE_XIP_ERROR_STRINGS(errorStrings); + + MY_INF("i_ringName=%s", i_ringName); + + if (i_bufTmp == NULL) { + MY_ERR("\tTemporary ring buffer passed by caller points to NULL and is invalid.\n"); + return IMGBUILD_ERR_MEMORY; } - // Update host_runtime_scom with sub_slw_ex_enable_runtime_scom's address. + sbe_xip_image_size( io_image, &sizeImageIn); + + // Create RS4 launcher and store in asmBuffer. // - rc = sbe_xip_set_scalar( io_image, EX_ENABLE_RUNTIME_SCOM_TOC_NAME, xipSlwExEnableRuntimeAddr); - if (rc) { - MY_ERR("ERROR : sbe_xip_set_scalar() failed w/rc=%i and %s", rc, SBE_XIP_ERROR_STRING(errorStrings, rc)); - MY_ERR("Probable cause:"); - MY_ERR("\tThe keyword (=%s) was not found.",EX_ENABLE_RUNTIME_SCOM_TOC_NAME); - return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + rc = sbe_xip_get_scalar( io_image, "proc_sbe_decompress_scan_chiplet_address", &scanChipletAddress); + if (rc) { + MY_INF("\tWARNING: sbe_xip_get_scalar() failed: %s\n", SBE_XIP_ERROR_STRING(errorStrings, rc)); + if (rc==SBE_XIP_ITEM_NOT_FOUND) { + MY_ERR("\tProbable cause:\n"); + MY_ERR("\t\tThe key word (=proc_sbe_decompress_scan_chiplet_address) does not exist in the image. (No TOC record.)\n"); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + else + if (rc==SBE_XIP_BUG) { + MY_ERR("\tProbable cause:\n"); + MY_ERR("\t\tIllegal keyword, maybe?\n"); + return IMGBUILD_ERR_XIP_MISC; + } + else { + MY_ERR("\tUnknown cause.\n"); + return IMGBUILD_ERR_XIP_UNKNOWN; + } } + if (scanChipletAddress==0) { + MY_ERR("\tValue of key word (proc_sbe_decompress_scan_chiplet_address=0) is not permitted. Exiting.\n"); + return IMGBUILD_ERR_CHECK_CODE; + } + // Now, create the inline assembler code. + rc = pore_inline_context_create( &ctx, asmBuffer, ASM_RS4_LAUNCH_BUF_SIZE, asmInitLC, 0); + if (rc) { + MY_ERR("\tpore_inline_context_create() failed w/rc=%i =%s\n", rc, pore_inline_error_strings[rc]); + return IMGBUILD_ERR_PORE_INLINE; + } + pore_MR(&ctx, A0, PC); + pore_ADDS(&ctx, A0, A0, ASM_RS4_LAUNCH_BUF_SIZE); + pore_LI(&ctx, D0, scanChipletAddress); + pore_BRAD(&ctx, D0); + if (ctx.error) { + MY_ERR("\tpore_MR/ADDS/LI/BRAD() failed w/rc=%i =%s\n", ctx.error, pore_inline_error_strings[ctx.error]); + return IMGBUILD_ERR_PORE_INLINE_ASM; + } - return 0; -} + // Check sizeRs4Launch and that sizeRs4Launch and sizeRs4Ring both are 8-byte aligned. + sizeRs4Launch = ctx.lc - asmInitLC; + sizeRs4Ring = myRev32(i_bufRs4Ring->iv_size); + if (sizeRs4Launch!=ASM_RS4_LAUNCH_BUF_SIZE) { + MY_ERR("\tSize of RS4 launch code differs from assumed size.\n\tsizeRs4Launch=%i\n\tASM_RS4_LAUNCH_BUF_SIZE=%i\n", + sizeRs4Launch,ASM_RS4_LAUNCH_BUF_SIZE); + return IMGBUILD_ERR_CHECK_CODE; + } + if (sizeRs4Launch%8 || sizeRs4Ring%8) { + MY_ERR("\tRS4 launch code or data not 8-byte aligned.\n\tsizeRs4Launch=%i\n\tASM_RS4_LAUNCH_BUF_SIZE=%i\n\tsizeRs4Ring=%i\n", + sizeRs4Launch,ASM_RS4_LAUNCH_BUF_SIZE,sizeRs4Ring); + return IMGBUILD_ERR_CHECK_CODE; + } + + // Obtain the back pointer to the .data item, i.e. the location of the ptr associated + // with the ring name in the -> .fixed_toc <- (since .toc is removed in IPL images.) + // + rc = sbe_xip_find( io_image, i_ringName, &tocItem); + if (rc) { + MY_ERR("\tWARNING: sbe_xip_find() failed: %s\n", SBE_XIP_ERROR_STRING(errorStrings, rc)); + if (rc==SBE_XIP_ITEM_NOT_FOUND) { + MY_ERR("\tProbable cause:\n"); + MY_ERR("\t\tThe variable name supplied (=%s) is not a valid key word in the image. (No .fixed_toc record.)\n", + i_ringName); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + else { + MY_ERR("\tUnknown cause.\n"); + return IMGBUILD_ERR_XIP_UNKNOWN; + } + } + + // Store the forward pointer at the ring's vector: + // - For VPD rings, there is no notion of a base and override ring. There can only be + // one ring. Thus, for core ID specific rings, their vector locations are updated in + // 8-byte increments, unlike 16-bytes for non-VPD rings which have base+override. + // 2012-11-12: According to Jeshua, #G might have overrides! + // - Any ring, including ex_ rings, that have a chipletId==0xFF will get stored at its + // zero-offset position. + chipletId = i_bufRs4Ring->iv_chipletId; + if (chipletId>=0x10 && chipletId<0x20) { + coreId = chipletId - 0x10; + addrOfFwdPtr = tocItem.iv_address + 8*coreId; + } + else + addrOfFwdPtr = tocItem.iv_address; + MY_INF("Addr of forward ptr = 0x%016llx\n", addrOfFwdPtr); + + // Populate the local ring layout structure + // + rs4RingLayout.entryOffset = (uint64_t)( + sizeof(rs4RingLayout.entryOffset) + + sizeof(rs4RingLayout.backItemPtr) + + sizeof(rs4RingLayout.sizeOfThis) + + sizeof(rs4RingLayout.sizeOfMeta) + + sizeof(rs4RingLayout.ddLevel) + + sizeof(rs4RingLayout.sysPhase) + + sizeof(rs4RingLayout.override) + + sizeof(rs4RingLayout.reserved1) + + sizeof(rs4RingLayout.reserved2) + + 0 ); // No meta data => automatic 8-byte align of RS4 launch. + rs4RingLayout.backItemPtr = addrOfFwdPtr; + rs4RingLayout.sizeOfThis = rs4RingLayout.entryOffset + // Must be 8-byte aligned. + sizeRs4Launch + // Must be 8-byte aligned. + sizeRs4Ring; // Must be 8-byte aligned. + rs4RingLayout.sizeOfMeta = 0; + rs4RingLayout.ddLevel = i_ddLevel; + rs4RingLayout.sysPhase = i_sysPhase; + rs4RingLayout.override = 0; // Doesn't apply for VPD ring. Always "base". + rs4RingLayout.reserved1 = 0; + rs4RingLayout.reserved2 = 0; + + if (rs4RingLayout.entryOffset%8) { + MY_ERR("\tRS4 launch code entry not 8-byte aligned.\n\trs4RingLayout.entryOffset=%i", + (uint32_t)rs4RingLayout.entryOffset); + return IMGBUILD_ERR_CHECK_CODE; + } + if (rs4RingLayout.sizeOfThis%8) { + MY_ERR("\tRS4 ring layout not 8-byte aligned.\n\trs4RingLayout.sizeOfThis=%i\n", + rs4RingLayout.sizeOfThis); + return IMGBUILD_ERR_CHECK_CODE; + } + + // Calc the size of the data section we're adding and the resulting output image's + // max size (needed for sbe_xip_append() ).. + // + sizeNewDataBlock = rs4RingLayout.sizeOfThis; + sizeImageOutEst = sizeImageIn + sizeNewDataBlock + SBE_XIP_MAX_SECTION_ALIGNMENT; + if (sizeImageOutEst>io_sizeImageOut) { + MY_ERR("Estimated new image size (=%i) would exceed max allowed image size (=%i).", + sizeImageOutEst, io_sizeImageOut); + io_sizeImageOut = sizeImageOutEst; + return IMGBUILD_ERR_IMAGE_TOO_LARGE; + } + + MY_INF("\tInput image size\t\t= %6i\n\tNew initf data block size\t= %6i\n\tOutput image size (max)\t\t= %6i\n", + sizeImageIn, sizeNewDataBlock, sizeImageOutEst); + MY_INF("\tentryOffset = %i\n\tsizeOfThis = %i\n", + (uint32_t)rs4RingLayout.entryOffset, rs4RingLayout.sizeOfThis); + MY_INF("\tRS4 launch size = %i\n\tRS4 delta size = %i\n", sizeRs4Launch, sizeRs4Ring); + MY_INF("\tBack item ptr = 0x%016llx\n", rs4RingLayout.backItemPtr); + MY_INF("\tDD level = %i\n\tSys phase = %i\n\tOverride = %i\n", + rs4RingLayout.ddLevel, rs4RingLayout.sysPhase, rs4RingLayout.override); + + // Combine rs4RingLayout members into a unified buffer (ringsBuffer). + // + if (sizeNewDataBlock>i_sizeBufTmp) { + MY_ERR("New ring data block size (=%i) would exceed max allowed size (=%i).", + sizeNewDataBlock, i_sizeBufTmp); + return IMGBUILD_ERR_RING_TOO_LARGE; + } + ringsBuffer = i_bufTmp; + // ... and copy the rs4 ring layout data into ringsBuffer in BIG-ENDIAN format. + bufLC = 0; + rs4RingLayoutBE.entryOffset = myRev64(rs4RingLayout.entryOffset); + memcpy( (uint8_t*)ringsBuffer+bufLC, &rs4RingLayoutBE.entryOffset, sizeof(rs4RingLayoutBE.entryOffset)); + + bufLC = bufLC + sizeof(rs4RingLayoutBE.entryOffset); + rs4RingLayoutBE.backItemPtr = myRev64(rs4RingLayout.backItemPtr); + memcpy( (uint8_t*)ringsBuffer+bufLC, &rs4RingLayoutBE.backItemPtr, sizeof(rs4RingLayoutBE.backItemPtr)); + + bufLC = bufLC + sizeof(rs4RingLayoutBE.backItemPtr); + rs4RingLayoutBE.sizeOfThis = myRev32(rs4RingLayout.sizeOfThis); + memcpy( (uint8_t*)ringsBuffer+bufLC, &rs4RingLayoutBE.sizeOfThis, sizeof(rs4RingLayoutBE.sizeOfThis)); + + bufLC = bufLC + sizeof(rs4RingLayoutBE.sizeOfThis); + rs4RingLayoutBE.sizeOfMeta = myRev32(rs4RingLayout.sizeOfMeta); + memcpy( (uint8_t*)ringsBuffer+bufLC, &rs4RingLayoutBE.sizeOfMeta, sizeof(rs4RingLayoutBE.sizeOfMeta)); + + bufLC = bufLC + sizeof(rs4RingLayoutBE.sizeOfMeta); + rs4RingLayoutBE.ddLevel = myRev32(rs4RingLayout.ddLevel); + memcpy( (uint8_t*)ringsBuffer+bufLC, &rs4RingLayoutBE.ddLevel, sizeof(rs4RingLayoutBE.ddLevel)); + + bufLC = bufLC + sizeof(rs4RingLayoutBE.ddLevel); + rs4RingLayoutBE.sysPhase = myRev32(rs4RingLayout.sysPhase); + memcpy( (uint8_t*)ringsBuffer+bufLC, &rs4RingLayout.sysPhase, sizeof(rs4RingLayoutBE.sysPhase)); + + bufLC = bufLC + sizeof(rs4RingLayoutBE.sysPhase); + rs4RingLayoutBE.override = myRev32(rs4RingLayout.override); + memcpy( (uint8_t*)ringsBuffer+bufLC, &rs4RingLayout.override, sizeof(rs4RingLayoutBE.override)); + + bufLC = bufLC + sizeof(rs4RingLayoutBE.override); + rs4RingLayoutBE.reserved1 = myRev32(rs4RingLayout.reserved1); + memcpy( (uint8_t*)ringsBuffer+bufLC, &rs4RingLayout.reserved1, sizeof(rs4RingLayoutBE.reserved1)); + + bufLC = bufLC + sizeof(rs4RingLayoutBE.reserved1); + rs4RingLayoutBE.reserved2 = myRev32(rs4RingLayout.reserved2); + memcpy( (uint8_t*)ringsBuffer+bufLC, &rs4RingLayout.reserved2, sizeof(rs4RingLayoutBE.reserved2)); + + bufLC = bufLC + sizeof(rs4RingLayoutBE.reserved2); + + if (bufLC!=(uint32_t)rs4RingLayout.entryOffset) { + MY_ERR("Inconsistent calculations of entryOffset to RS4 launch code.\n"); + return IMGBUILD_ERR_CHECK_CODE; + } + + // RS4 launch buffer alread BE formatted. + memcpy( (uint8_t*)ringsBuffer+bufLC, (uint8_t*)asmBuffer, (size_t)sizeRs4Launch); + bufLC = bufLC + sizeRs4Launch; // This is [already] 8-byte aligned. + if (bufLC%8) { + MY_ERR("\tRS4 ring layout (during buffer copy) is not 8-byte aligned.\n\tbufLC=%i\n", + bufLC); + return IMGBUILD_ERR_CHECK_CODE; + } + + // RS4 delta ring already BE formatted. + memcpy( (uint8_t*)ringsBuffer+bufLC, (uint8_t*)i_bufRs4Ring, (size_t)sizeRs4Ring); + + // Append rs4DeltaLayout to .rings section of in-memory input image. + // Note! All rs4DeltaLayout members should already be 8-byte aligned. + // + ringsDataBlockOffset = 0; + rc = sbe_xip_append( io_image, + SBE_XIP_SECTION_RINGS, + (void*)ringsBuffer, + sizeNewDataBlock, + sizeImageOutEst, + &ringsDataBlockOffset); + MY_INF("\tringsDataBlockOffset=0x%08x\n",ringsDataBlockOffset); + if (rc) { + MY_ERR("\tsbe_xip_append() failed: %s\n", SBE_XIP_ERROR_STRING(errorStrings, rc)); + return IMGBUILD_ERR_XIP_MISC; + } + // ...test if successful update. + sbe_xip_image_size(io_image, &sizeImageOut); + io_sizeImageOut = sizeImageOut; + rc = sbe_xip_validate(io_image, sizeImageOut); + if (rc) { + MY_ERR("\tsbe_xip_validate() of output image copy failed: %s\n", SBE_XIP_ERROR_STRING(errorStrings, rc)); + return IMGBUILD_ERR_XIP_MISC; + } + MY_INF("\tSuccessful append of RS4 ring to .rings... Next, update variable name ptr...\n"); + // ...convert rings section offset to a PORE address + rc = sbe_xip_section2pore( io_image, SBE_XIP_SECTION_RINGS, ringsDataBlockOffset, &ringsDataBlockPoreAddr); + MY_INF("\tringsDataBlockPoreAddr=0x%016llx\n", ringsDataBlockPoreAddr); + if (rc) { + MY_ERR("\tsbe_xip_section2pore() failed: %s\n", SBE_XIP_ERROR_STRING(errorStrings, rc)); + return IMGBUILD_ERR_XIP_MISC; + } + // ...and lastly, associate PORE addr with ringName. + rc = sbe_xip_set_scalar( io_image, i_ringName, ringsDataBlockPoreAddr); + if (rc) { + MY_ERR("\tsbe_xip_set_scalar() failed: %s\n", SBE_XIP_ERROR_STRING(errorStrings, rc)); + if (rc==SBE_XIP_ITEM_NOT_FOUND) { + MY_ERR("\tProbable cause:\n"); + MY_ERR("\t\tThe variable name supplied (=%s) is not a valid key word in the image. (No TOC record.)\n", + i_ringName); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + if (rc==SBE_XIP_BUG) { + MY_ERR("\tProbable cause:\n"); + MY_ERR("\t\tThe variable name supplied (=%s) is a valid key word but cannot be updated with a scalar value.\n", + i_ringName); + return IMGBUILD_ERR_XIP_MISC; + } + return IMGBUILD_ERR_XIP_UNKNOWN; + } + + MY_INF("\tSuccessful in-memory image update...\n"); + + return rc; +} -void cleanup( void *buf1, - void *buf2, +void cleanup( void *buf1, + void *buf2, void *buf3, void *buf4, void *buf5) diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help_base.H b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help_base.H index 1067d3f9c..8dcffd76f 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help_base.H +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_image_help_base.H @@ -20,14 +20,21 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_image_help_base.H,v 1.4 2012/09/01 16:49:28 cmolsen Exp $ +// $Id: p8_image_help_base.H,v 1.8 2012/11/13 16:40:53 cmolsen Exp $ //------------------------------------------------------------------------------ // Title: p8_image_help_base.H // Description: Contains the most basic structures and defines needed for // image building and interpretation. //------------------------------------------------------------------------------ -#define ASM_RS4_LAUNCH_BUF_SIZE 24 // Byte size of RS4 launch buffer. +const uint32_t MAX_REF_IMAGE_SIZE = 5000000; // Max reference image size. +const uint32_t FIXED_SLW_IMAGE_SIZE = 1000000; // Fixed SLW image size assumed by HB, PHYP and slw_build(). +const uint32_t FIXED_RING_BUF_SIZE = 60000; // Fixed ring buffer size assumed by HB, PHYP and slw_build(). Only use when emulating FAPI calls and for command-line utilities. +const uint8_t MAX_VPD_TYPES = 2; // #G and #R, so far. +const uint8_t CHIPLET_ID_MIN = 0x00; +const uint8_t CHIPLET_ID_MAX = 0x1F; +const uint8_t MAX_CHIPLETS = CHIPLET_ID_MAX-CHIPLET_ID_MIN+1; +const uint32_t ASM_RS4_LAUNCH_BUF_SIZE = 24; // Byte size of RS4 launch buffer. #define LISTING_STRING_SIZE (2*PORE_INLINE_DISASSEMBLER_STRING_SIZE) // Base (shared) ring layout for both RS4 and Wiggle-flip layouts. @@ -54,7 +61,15 @@ typedef struct { // PairingInfo is used for pairing, or matching, a back pointer address of a // ring block with its corresponding TOC name. typedef struct { - uint64_t address; // 64-bit PORE address - char *name; // TOC name - uint8_t override; // 0: base 1: override + uint64_t address; // (in) Holds PORE backPtr addr of the ring + uint8_t vectorpos; // (in) Vector position of fwdPtr [0;31] + // max=0 for most VPD rings + // max=1 for all non-VPD rings + // max=1 for perv_ VPD rings + // max=15 for most VPD ex_ rings + // max=31 for 16 ex_ chiplets with override + char *name; // (out) TOC name + uint8_t isvpd; // (out) 0: Non-VPD ring 1: VPD ring + uint8_t overridable; // (out) 0: No (most VPD rings) 1: Yes (all non-VPD rings) + uint8_t override; // (out) 0: base 1: override } PairingInfo; diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api.C b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api.C index 979ad4bef..9ab2c8b8c 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api.C +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api.C @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_pore_table_gen_api.C,v 1.10 2012/09/24 21:25:55 cmolsen Exp $ +// $Id: p8_pore_table_gen_api.C,v 1.11 2012/10/04 02:39:07 cmolsen Exp $ // /*------------------------------------------------------------------------------*/ /* *! (C) Copyright International Business Machines Corp. 2012 */ @@ -45,8 +45,8 @@ /*------------------------------------------------------------------------------*/ #define __P8_PORE_TABLE_GEN_API_C -#include <p8_pore_api_custom.h> #include <HvPlicModule.H> +#include <p8_pore_api_custom.h> #include <p8_pore_table_gen_api.H> #include <p8_delta_scan_rw.h> @@ -115,7 +115,7 @@ uint32_t p8_pore_gen_cpureg( void *io_image, } // ...check thread ID if (i_threadId>=SLW_CORE_THREADS) { - MY_ERR("Thread ID = %i is not within valid range of [0;%i]\n",i_coreId,SLW_CORE_THREADS-1); + MY_ERR("Thread ID = %i is not within valid range of [0;%i]\n",i_threadId,SLW_CORE_THREADS-1); rcLoc = 1; } if (rcLoc) @@ -221,8 +221,8 @@ uint32_t p8_pore_gen_cpureg( void *io_image, // Check hostRamTableThis for sizeTableThis>SLW_MAX_CPUREGS_OPS if ((uint64_t)hostRamTableNext==(uint64_t)hostRamTableThis) { if ((sizeTableThis/XIPSIZE_RAM_ENTRY+1)>SLW_MAX_CPUREGS_OPS) { - MY_ERR("Table entry overflow. (SLW_MAX_CPUREGS_OPS=%i). Exiting.\n",SLW_MAX_CPUREGS_OPS); - return IMGBUILD_ERR_RAM_TABLE_OVERFLOW; + MY_ERR("RAM table is full. Max %i entries allowed.\n",SLW_MAX_CPUREGS_OPS); + return IMGBUILD_ERR_RAM_TABLE_FULL; } } // Update total table size. @@ -271,26 +271,32 @@ uint32_t p8_pore_gen_cpureg( void *io_image, // Insert at end of existing table. hostRamEntryNext = hostRamTableThis; ramEntryNext = (RamTableEntry*)hostRamEntryNext; - iCount = 0; + iCount = 1; while ((myRev32(ramEntryNext->header) & RAM_HEADER_END_MASK_C)==0) { + if (iCount>=SLW_MAX_CPUREGS_OPS) { + MY_ERR("Bad table! Header end bit not found and RAM table full (=%i entries).\n",SLW_MAX_CPUREGS_OPS); + return IMGBUILD_ERR_RAM_TABLE_END_NOT_FOUND; + } hostRamEntryNext = (void*)((uint8_t*)hostRamEntryNext + XIPSIZE_RAM_ENTRY); ramEntryNext = (RamTableEntry*)hostRamEntryNext; iCount++; - if ((iCount+1)>SLW_MAX_CPUREGS_OPS) { - MY_ERR("Table end bit, in header, wasn't found within max OPs allowed per table.\n"); - return IMGBUILD_ERR_RAM_TABLE_END_NOT_FOUND; - } - } - // ...zero out previous END bit in header - if ((myRev32(ramEntryNext->header) & RAM_HEADER_END_MASK_C)) { - ramEntryNext->header = ramEntryNext->header & myRev32(~RAM_HEADER_END_MASK_C); - } - else { - MY_ERR("ERROR : We should never get here. Check code. Dumping data:\n"); - MY_ERR("myRev32(ramEntryNext->header) = 0x%08x\n",myRev32(ramEntryNext->header)); - MY_ERR("RAM_HEADER_END_MASK_C = 0x%08x\n",RAM_HEADER_END_MASK_C); - return IMGBUILD_ERR_RAM_CODE; } + if (iCount<SLW_MAX_CPUREGS_OPS) { + // ...zero out previous END bit in header + if ((myRev32(ramEntryNext->header) & RAM_HEADER_END_MASK_C)) { + ramEntryNext->header = ramEntryNext->header & myRev32(~RAM_HEADER_END_MASK_C); + } + else { + MY_ERR("We should never get here. Check code. Dumping data:\n"); + MY_ERR("myRev32(ramEntryNext->header) = 0x%08x\n",myRev32(ramEntryNext->header)); + MY_ERR("RAM_HEADER_END_MASK_C = 0x%08x\n",RAM_HEADER_END_MASK_C); + return IMGBUILD_ERR_RAM_CODE; + } + } + else { + MY_ERR("RAM table is full. Max %i entries allowed.\n",SLW_MAX_CPUREGS_OPS); + return IMGBUILD_ERR_RAM_TABLE_FULL; + } // ...this is the spot for the new entry hostRamEntryThis = (void*)((uint8_t*)hostRamEntryNext + XIPSIZE_RAM_ENTRY); bEntryEnd = 1; @@ -307,7 +313,7 @@ uint32_t p8_pore_gen_cpureg( void *io_image, ramEntryNext-- ) { *(ramEntryNext+1) = *ramEntryNext; if ((ramEntryNext+1)->instr!=ramEntryNext->instr) { - MY_ERR("ERROR : Incorrect shifting of table entries. Check code.\n"); + MY_ERR("Incorrect shifting of table entries. Check code.\n"); return IMGBUILD_ERR_RAM_CODE; } } @@ -334,7 +340,7 @@ uint32_t p8_pore_gen_cpureg( void *io_image, // ...do the SPR instr sprSwiz = i_regName>>5 | (i_regName & 0x0000001f)<<5; if (sprSwiz!=SLW_SPR_REGS[iReg].swizzled) { - MY_ERR("ERROR : Inconsistent swizzle rules implemented. Check code. Dumping data.\n"); + MY_ERR("Inconsistent swizzle rules implemented. Check code. Dumping data.\n"); MY_ERR("\tsprSwiz (on-the-fly-calc)=%i\n",sprSwiz); MY_ERR("\tSLW_SPR_REGS[%i].swizzled=%i\n",iReg,SLW_SPR_REGS[iReg].swizzled); return IMGBUILD_ERR_RAM_CODE; @@ -383,21 +389,21 @@ uint32_t p8_pore_gen_cpureg( void *io_image, uint32_t p8_pore_gen_scom( void *io_image, uint32_t i_sizeImage, uint32_t i_scomAddr, - uint32_t i_coreId, - uint64_t i_scomData, // [1:4] - uint32_t i_operation) // [0:15] + uint32_t i_coreId, // [0:15] + uint64_t i_scomData, + uint32_t i_operation, // [0:5] + uint32_t i_section) // [0,2,3] { uint32_t rc=0, rcLoc=0, iEntry=0; - int pgas_rc=0; uint32_t chipletId=0; uint32_t operation=0; - uint32_t entriesCount=0, entriesMatch=0; + uint32_t entriesCount=0, entriesMatch=0, entriesNOP=0; uint32_t sizeImageIn=0; void *hostSlwSection; uint64_t xipScomTableThis; void *hostScomVector, *hostScomTableThis; void *hostScomEntryNext; // running entry pointer - void *hostScomEntryFound=NULL; // pointer to entry that matches scomAddr + void *hostScomEntryMatch=NULL; // pointer to entry that matches scomAddr void *hostScomEntryRET=NULL; // pointer to first return instr after table void *hostScomEntryNOP=NULL; // pointer to first nop IIS uint8_t bufIIS[XIPSIZE_SCOM_ENTRY], bufNOP[4], bufRET[4]; @@ -464,19 +470,43 @@ uint32_t p8_pore_gen_scom( void *io_image, MY_INF("Input parameter checks - OK\n"); MY_INF("\tRegister = 0x%08x\n",i_scomAddr); MY_INF("\tOperation = %i\n",i_operation); + MY_INF("\tSection = %i\n",i_section); MY_INF("\tCore ID = %i\n",i_coreId); MY_INF("Image validation and size checks - OK\n"); MY_INF("\tImage size = %i\n",i_sizeImage); MY_INF("\tSLW section size= %i\n",xipSection.iv_size); // ------------------------------------------------------------------------- - // Locate Scom vector and locate Scom table associated with "This" core ID. + // Locate Scom vector according to i_section and then locate Scom table + // associated with "This" core ID. // - rc = sbe_xip_find( io_image, SLW_HOST_SCOM_VECTOR_TOC_NAME, &xipTocItem); - if (rc) { - MY_ERR("Probably invalid key word for SLW_HOST_SCOM_VECTOR_TOC_NAME.\n"); - return IMGBUILD_ERR_KEYWORD_NOT_FOUND; - } + switch (i_section) { + case 0: + rc = sbe_xip_find( io_image, SLW_HOST_SCOM_NC_VECTOR_TOC_NAME, &xipTocItem); + if (rc) { + MY_ERR("Probably invalid key word for SLW_HOST_SCOM_NC_VECTOR_TOC_NAME.\n"); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + break; + case 2: + rc = sbe_xip_find( io_image, SLW_HOST_SCOM_L2_VECTOR_TOC_NAME, &xipTocItem); + if (rc) { + MY_ERR("Probably invalid key word for SLW_HOST_SCOM_L2_VECTOR_TOC_NAME.\n"); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + break; + case 3: + rc = sbe_xip_find( io_image, SLW_HOST_SCOM_L3_VECTOR_TOC_NAME, &xipTocItem); + if (rc) { + MY_ERR("Probably invalid key word for SLW_HOST_SCOM_L3_VECTOR_TOC_NAME.\n"); + return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + } + break; + default: + MY_ERR("Invalid value for i_section (=%i).\n",i_section); + MY_ERR("Valid values for i_section = [0,2,3].\n"); + return IMGBUILD_ERR_SCOM_INVALID_SUBSECTION; + } MY_INF("xipTocItem.iv_address = 0x%016llx\n",xipTocItem.iv_address); sbe_xip_pore2host( io_image, xipTocItem.iv_address, &hostScomVector); MY_INF("hostScomVector = 0x%016llx\n",(uint64_t)hostScomVector); @@ -485,7 +515,7 @@ uint32_t p8_pore_gen_scom( void *io_image, if (xipScomTableThis) { sbe_xip_pore2host( io_image, xipScomTableThis, &hostScomTableThis); } - else { // We should never get here. + else { // Should never be here. MY_ERR("Code or image bug. Scom vector table entries should never be null.\n"); return IMGBUILD_ERR_CHECK_CODE; } @@ -499,62 +529,87 @@ uint32_t p8_pore_gen_scom( void *io_image, // - If no NOP found, insert at first RET. // - // First, create search string - // Note, this IIS will also be used in case of operation==replace. + // First, create search strings for addr, nop and ret. + // Note, the following IIS will also be used in case of + // - i_operation==append + // - i_operation==replace pore_inline_context_create( &ctx, (void*)bufIIS, XIPSIZE_SCOM_ENTRY, 0, 0); - pgas_rc = pore_LS( &ctx, P1, chipletId); - pgas_rc = pgas_rc + pore_STI( &ctx, i_scomAddr, P1, i_scomData); - if (pgas_rc>0) { - MY_ERR("pore_LS or _STI generated rc = %d", pgas_rc); + pore_LS( &ctx, P1, chipletId); + pore_STI( &ctx, i_scomAddr, P1, i_scomData); + if (ctx.error > 0) { + MY_ERR("pore_LS or _STI generated rc = %d", ctx.error); return IMGBUILD_ERR_PORE_INLINE_ASM; } pore_inline_context_create( &ctx, (void*)bufRET, 4, 0, 0); - pgas_rc = pore_RET( &ctx); - if (pgas_rc>0) { - MY_ERR("pore_RET generated rc = %d", pgas_rc); + pore_RET( &ctx); + if (ctx.error > 0) { + MY_ERR("pore_RET generated rc = %d", ctx.error); return IMGBUILD_ERR_PORE_INLINE_ASM; } pore_inline_context_create( &ctx, (void*)bufNOP, 4, 0, 0); - pgas_rc = pore_NOP( &ctx); - if (pgas_rc>0) { - MY_ERR("pore_NOP generated rc = %d", pgas_rc); + pore_NOP( &ctx); + if (ctx.error > 0) { + MY_ERR("pore_NOP generated rc = %d", ctx.error); return IMGBUILD_ERR_PORE_INLINE_ASM; } - // Second, search for scomAddr in relevant coreId table until first RET. + // Second, search for addr and nop in relevant coreId table until first RET. // Note: - // - We go through ALL entries until first RET instr. - // - Count number of entries and check for overrun. - // - Check for repeat entries, which are not allowed. - // - The STI opcode is in the 2nd word of the Scom entry. - // - Last NOP is picked, if any, for append (if no entry found for a replace) + // - We go through ALL entries until first RET instr. We MUST find a RET instr, + // though we don't check for overrun until later. (Should be improved.) + // - Count number of entries and check for overrun, though we'll continue + // searching until we find an RET. (Should be improved.) + // - The STI(+SCOM_addr) opcode is in the 2nd word of the Scom entry. + // - For an append operation, if a NOP is found (before a RET obviously), the + // SCOM is replacing that NNNN sequence. hostScomEntryNext = hostScomTableThis; while (*(uint32_t*)hostScomEntryNext!=*(uint32_t*)bufRET) { entriesCount++; - if (*((uint32_t*)bufIIS+1)==*((uint32_t*)hostScomEntryNext+1)) {// +1 skips 1st word in Scom entry - hostScomEntryFound = hostScomEntryNext; + if (*((uint32_t*)bufIIS+1)==*((uint32_t*)hostScomEntryNext+1) && entriesMatch==0) {// +1 skips 1st word in Scom entry (which loads the PC in an LS operation.) + hostScomEntryMatch = hostScomEntryNext; entriesMatch++; } - if (*(uint32_t*)hostScomEntryNext==*(uint32_t*)bufNOP ) - hostScomEntryNOP = hostScomEntryNext; // If >1 NOP, then pick last NOP. + if (*(uint32_t*)hostScomEntryNext==*(uint32_t*)bufNOP && entriesNOP==0) { + hostScomEntryNOP = hostScomEntryNext; + entriesNOP++; + } hostScomEntryNext = (void*)((uintptr_t)hostScomEntryNext + XIPSIZE_SCOM_ENTRY); } hostScomEntryRET = hostScomEntryNext; // The last EntryNext will always be the first RET. - if (entriesMatch>1) { - MY_ERR("Repeat Scom entries not allowed. (entriesMatch=%i)\n",entriesMatch); - return IMGBUILD_ERR_SCOM_REPEAT_ENTRIES; - } - if (entriesCount>SLW_MAX_SCOMS_NC) { - MY_ERR("Too many Scoms in table. Max %i is allowed.\n",SLW_MAX_SCOMS_NC); - MY_ERR("Check code.\n"); - return IMGBUILD_ERR_CHECK_CODE; + + switch (i_section) { + case 0: + if (entriesCount>=SLW_MAX_SCOMS_NC) { + MY_ERR("SCOM table NC is full. Max %i entries allowed.\n",SLW_MAX_SCOMS_NC); + return IMGBUILD_ERR_CHECK_CODE; + } + break; + case 2: + if (entriesCount>=SLW_MAX_SCOMS_L2) { + MY_ERR("SCOM table L2 is full. Max %i entries allowed.\n",SLW_MAX_SCOMS_L2); + return IMGBUILD_ERR_CHECK_CODE; + } + break; + case 3: + if (entriesCount>=SLW_MAX_SCOMS_L3) { + MY_ERR("SCOM table L3 is full. Max %i entries allowed.\n",SLW_MAX_SCOMS_L3); + return IMGBUILD_ERR_CHECK_CODE; + } + break; + default: + MY_ERR("Invalid value for i_section (=%i).\n",i_section); + MY_ERR("Valid values for i_section = [0,2,3].\n"); + return IMGBUILD_ERR_SCOM_INVALID_SUBSECTION; } // // Further qualify (translate) operation and IIS. // - if (i_operation==P8_PORE_SCOM_REPLACE) { - if (hostScomEntryFound) + if (i_operation==P8_PORE_SCOM_APPEND) { + operation = i_operation; + } + else if (i_operation==P8_PORE_SCOM_REPLACE) { + if (hostScomEntryMatch) // ... do a replace operation = i_operation; else @@ -564,12 +619,12 @@ uint32_t p8_pore_gen_scom( void *io_image, else if (i_operation==P8_PORE_SCOM_NOOP) { // ...overwrite earlier bufIIS from the search step pore_inline_context_create( &ctx, (void*)bufIIS, XIPSIZE_SCOM_ENTRY, 0, 0); - pgas_rc = pore_NOP( &ctx); - pgas_rc = pgas_rc + pore_NOP( &ctx); - pgas_rc = pgas_rc + pore_NOP( &ctx); - pgas_rc = pgas_rc + pore_NOP( &ctx); - if (pgas_rc>0) { - MY_ERR("*** _NOP generated rc = %d", pgas_rc); + pore_NOP( &ctx); + pore_NOP( &ctx); + pore_NOP( &ctx); + pore_NOP( &ctx); + if (ctx.error > 0) { + MY_ERR("*** _NOP generated rc = %d", ctx.error); return IMGBUILD_ERR_PORE_INLINE_ASM; } operation = i_operation; @@ -581,12 +636,12 @@ uint32_t p8_pore_gen_scom( void *io_image, else if (i_operation==P8_PORE_SCOM_RESET) { // ... create RNNN instruction sequence. pore_inline_context_create( &ctx, (void*)bufIIS, XIPSIZE_SCOM_ENTRY, 0, 0); - pgas_rc = pore_RET( &ctx); - pgas_rc = pgas_rc + pore_NOP( &ctx); - pgas_rc = pgas_rc + pore_NOP( &ctx); - pgas_rc = pgas_rc + pore_NOP( &ctx); - if (pgas_rc>0) { - MY_ERR("***_RET or _NOP generated rc = %d", pgas_rc); + pore_RET( &ctx); + pore_NOP( &ctx); + pore_NOP( &ctx); + pore_NOP( &ctx); + if (ctx.error > 0) { + MY_ERR("***_RET or _NOP generated rc = %d", ctx.error); return IMGBUILD_ERR_PORE_INLINE_ASM; } operation = i_operation; @@ -605,46 +660,51 @@ uint32_t p8_pore_gen_scom( void *io_image, // - Remember to check for more than SLW_MAX_SCOMS_NC entries! switch (operation) { - case P8_PORE_SCOM_APPEND: // Append a Scom at a NOP or at RET + case P8_PORE_SCOM_APPEND: // Append a Scom at first occurring NNNN or RNNN, if (hostScomEntryNOP) { - // ... do an append at a NOP + // ... replace the NNNN MY_INF("Append at NOP\n"); memcpy(hostScomEntryNOP,(void*)bufIIS,XIPSIZE_SCOM_ENTRY); } - else { - // ... do an append at the RET + else if (hostScomEntryRET) { + // ... replace the RNNN MY_INF("Append at RET\n"); memcpy(hostScomEntryRET,(void*)bufIIS,XIPSIZE_SCOM_ENTRY); } + else { + // We should never be here. + MY_ERR("In case=_SCOM_APPEND: EntryRET=NULL is impossible. Check code.\n"); + return IMGBUILD_ERR_CHECK_CODE; + } break; case P8_PORE_SCOM_REPLACE: // Replace existing Scom with new data - if (hostScomEntryFound) { + if (hostScomEntryMatch) { // ... do a vanilla replace MY_INF("Replace existing Scom\n"); - memcpy(hostScomEntryFound,(void*)bufIIS,XIPSIZE_SCOM_ENTRY); + memcpy(hostScomEntryMatch,(void*)bufIIS,XIPSIZE_SCOM_ENTRY); } else { // We should never be here. - MY_ERR("In case=_SCOM_REPLACE: EntryFound=NULL is impossible. Check code.\n"); + MY_ERR("In case=_SCOM_REPLACE: EntryMatch=NULL is impossible. Check code.\n"); return IMGBUILD_ERR_CHECK_CODE; } break; case P8_PORE_SCOM_NOOP: - if (hostScomEntryFound) { + if (hostScomEntryMatch) { // ... do a vanilla replace MY_INF("Replace existing Scom w/NOPs\n"); - memcpy(hostScomEntryFound,(void*)bufIIS,XIPSIZE_SCOM_ENTRY); + memcpy(hostScomEntryMatch,(void*)bufIIS,XIPSIZE_SCOM_ENTRY); } else { // do nothing, and assume everything is fine, since we did no damage. } break; case P8_PORE_SCOM_OR: // Overlay Scom data onto existing data by bitwise OR - if (hostScomEntryFound) { + if (hostScomEntryMatch) { // ... do an OR on the data (which is the 2nd DWord in the entry) MY_INF("Overlay existing Scom - OR case\n"); - *((uint64_t*)hostScomEntryFound+1) = - *((uint64_t*)hostScomEntryFound+1) | myRev64(i_scomData); + *((uint64_t*)hostScomEntryMatch+1) = + *((uint64_t*)hostScomEntryMatch+1) | myRev64(i_scomData); } else { MY_ERR("No Scom entry found to do OR operation with.\n"); @@ -652,11 +712,11 @@ uint32_t p8_pore_gen_scom( void *io_image, } break; case P8_PORE_SCOM_AND: // Overlay Scom data onto existing data by bitwise AND - if (hostScomEntryFound) { + if (hostScomEntryMatch) { // ... do an AND on the data (which is the 2nd DWord in the entry) MY_INF("Overlay existing Scom - AND case\n"); - *((uint64_t*)hostScomEntryFound+1) = - *((uint64_t*)hostScomEntryFound+1) & myRev64(i_scomData); + *((uint64_t*)hostScomEntryMatch+1) = + *((uint64_t*)hostScomEntryMatch+1) & myRev64(i_scomData); } else { MY_ERR("No Scom entry found to do AND operation with.\n"); @@ -672,7 +732,8 @@ uint32_t p8_pore_gen_scom( void *io_image, } break; default: - break; + MY_ERR("Impossible value of operation (=%i). Check code.\n",operation); + return IMGBUILD_ERR_CHECK_CODE; } // End of switch(operation) diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api.H b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api.H index 60c765f95..a777529db 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api.H +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api.H @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_pore_table_gen_api.H,v 1.13 2012/09/24 15:02:48 cmolsen Exp $ +// $Id: p8_pore_table_gen_api.H,v 1.15 2012/10/17 19:06:54 cmolsen Exp $ /*------------------------------------------------------------------------------*/ /* *! (C) Copyright International Business Machines Corp. 2012 */ /* *! All Rights Reserved -- Property of IBM */ @@ -61,7 +61,7 @@ // 1 - Reserved // 2:3 - Type // 00: MTSPR -// 01: MTGPR +// 01: MTMSRD // 10: Reserved // 11: Reserved // 4:13 - SPR number in non-swizzled form (0:9) @@ -122,7 +122,6 @@ CONST_UINT64_T( EX_PERV_SCRATCH7 , ULL(0x1001328A) ); // RAM Status reg settings. CONST_UINT64_T( RAM_STATUS_REG_AFTER_RAM, 0x5000000000000000); -CONST_UINT32_T( SLW_MAX_RAM_POLLS ,ULL(0x04) ); // mfspr gpr0, scratch0 opcode left-shifted 29 bits, ready for ramming. CONST_UINT64_T( MTSPR_SCRATCH0_GPR0_RAM_READY, (0x000000007C1543A6<<29)); @@ -189,16 +188,17 @@ CONST_UINT64_T( SCRATCH0_RESET_VALUE, (0xABBA99EBBA33DADA) ); /* Other defs needed for ramming and scomming */ // TOC names #define SLW_HOST_REG_VECTOR_TOC_NAME "slw_host_reg_vector" -#define SLW_HOST_SCOM_VECTOR_TOC_NAME "slw_host_scom_vector" +#define SLW_HOST_SCOM_NC_VECTOR_TOC_NAME "slw_host_scom_nc_vector" #define SLW_HOST_SCOM_L2_VECTOR_TOC_NAME "slw_host_scom_l2_vector" #define SLW_HOST_SCOM_L3_VECTOR_TOC_NAME "slw_host_scom_l3_vector" -//#define SLW_HOST_REG_TABLE_TOC_NAME "slw_core_reg_table" // Defines for slw_build() to update "runtime_scom" pointers w/pointer to // "sub_slw_runtime_scom" subroutines at SLW image build time. #define HOST_RUNTIME_SCOM_TOC_NAME "host_runtime_scom" // Null 1st, then fill w/addr of SLW_RUNTIME_SCOM_TOC_NAME #define SLW_RUNTIME_SCOM_TOC_NAME "sub_slw_runtime_scom" -#define EX_ENABLE_RUNTIME_SCOM_TOC_NAME "ex_enable_runtime_scom" // Null 1st, then fill w/addr of SLW_EX_ENABLE_RUNTIME_SCOM_TOC_NAME + +// The following two provide TRANSITIONAL SUPPORT only. TO BE REMOVED ASAP. +#define EX_ENABLE_RUNTIME_SCOM_TOC_NAME "ex_enable_runtime_scom" #define SLW_EX_ENABLE_RUNTIME_SCOM_TOC_NAME "sub_slw_ex_enable_runtime_scom" #define SCAN_MAX_ROTATE_38XXX_NAME "scan_max_rotate_38xxx" @@ -211,9 +211,10 @@ CONST_UINT64_T( SCRATCH0_RESET_VALUE, (0xABBA99EBBA33DADA) ); #define SLW_MAX_CPUREGS_CORE 9 #define SLW_MAX_CPUREGS_THREADS 2 #define SLW_CORE_THREADS 8 -#define SLW_MAX_CPUREGS_OPS ( SLW_MAX_CPUREGS_CORE + \ - SLW_CORE_THREADS*SLW_MAX_CPUREGS_THREADS ) -#define SLW_RAM_TABLE_SIZE ( SLW_MAX_CORES * SLW_MAX_CPUREGS_OPS * XIPSIZE_RAM_ENTRY ) +#define SLW_MAX_CPUREGS_OPS ( SLW_MAX_CPUREGS_CORE + \ + SLW_CORE_THREADS*SLW_MAX_CPUREGS_THREADS ) +#define SLW_RAM_TABLE_SPACE_PER_CORE ( SLW_MAX_CPUREGS_OPS * XIPSIZE_RAM_ENTRY ) +#define SLW_RAM_TABLE_SIZE ( SLW_MAX_CORES * SLW_RAM_TABLE_SPACE_PER_CORE ) // SPR and MSR values for i_regName enum { @@ -233,31 +234,41 @@ enum { // SCOM table defines - Common #define XIPSIZE_SCOM_ENTRY 16 -// SCOM table defines - Non-cache +// SCOM table defines - Non-cache section #define SLW_MAX_SCOMS_NC 32 #define SLW_SCOM_TABLE_SPACE_PER_CORE_NC ( (SLW_MAX_SCOMS_NC+1)*XIPSIZE_SCOM_ENTRY ) // Add 1 for RNNN IIS #define SLW_SCOM_TABLE_SIZE_NC ( SLW_MAX_CORES * SLW_SCOM_TABLE_SPACE_PER_CORE_NC ) -// SCOM table defines - L2 +// SCOM table defines - L2 section #define SLW_MAX_SCOMS_L2 16 #define SLW_SCOM_TABLE_SPACE_PER_CORE_L2 ( (SLW_MAX_SCOMS_L2+1)*XIPSIZE_SCOM_ENTRY ) // Add 1 for RNNN IIS #define SLW_SCOM_TABLE_SIZE_L2 ( SLW_MAX_CORES * SLW_SCOM_TABLE_SPACE_PER_CORE_L2 ) -// SCOM table defines - L3 +// SCOM table defines - L3 section #define SLW_MAX_SCOMS_L3 16 #define SLW_SCOM_TABLE_SPACE_PER_CORE_L3 ( (SLW_MAX_SCOMS_L3+1)*XIPSIZE_SCOM_ENTRY ) // Add 1 for RNNN IIS #define SLW_SCOM_TABLE_SIZE_L3 ( SLW_MAX_CORES * SLW_SCOM_TABLE_SPACE_PER_CORE_L3 ) #define SLW_SCOM_TABLE_SIZE_ALL ( SLW_SCOM_TABLE_SIZE_NC + SLW_SCOM_TABLE_SIZE_L2 + SLW_SCOM_TABLE_SIZE_L3) - + +// RAM and SCOM sub-section offsets from beginning of .slw section. +#define SLW_RAM_TABLE_OFFSET 0 +#define SLW_SCOM_TABLE_OFFSET_NC (SLW_RAM_TABLE_OFFSET + SLW_RAM_TABLE_SIZE) +#define SLW_SCOM_TABLE_OFFSET_L2 (SLW_SCOM_TABLE_OFFSET_NC + SLW_SCOM_TABLE_SIZE_NC) +#define SLW_SCOM_TABLE_OFFSET_L3 (SLW_SCOM_TABLE_OFFSET_L2 + SLW_SCOM_TABLE_SIZE_L2) +#define SLW_TABLE_SIZE_ALL (SLW_RAM_TABLE_SIZE + SLW_SCOM_TABLE_SIZE_ALL) + +// FFDC section +#define FFDC_SECTION_SIZE 256 + // SCOM/CID masks and ranges #define P8_CID_EX_LOW 0x10 // Lowest EX chiplet addr #define P8_CID_EX_HIGH 0x1f // Highest EX chiplet addr // SCOM Operators -#define P8_PORE_SCOM_FIRST_OP 1 // First supported INPUT Scom operation. -#define P8_PORE_SCOM_APPEND 0 // Add Scom to the end of table (only used internally) -#define P8_PORE_SCOM_REPLACE 1 // Replace existing Scom, or append to end of table +#define P8_PORE_SCOM_FIRST_OP 0 // First supported INPUT Scom operation. +#define P8_PORE_SCOM_APPEND 0 // Add Scom to end of table +#define P8_PORE_SCOM_REPLACE 1 // Repl 1st matching Scom addr or add to end of table #define P8_PORE_SCOM_OR 2 // Overlay data onto existing Scom by bitwise OR #define P8_PORE_SCOM_AND 3 // Overlay data onto existing Scom by bitwise AND #define P8_PORE_SCOM_NOOP 4 // Replace existing Scom PORE NOP instruction @@ -323,16 +334,18 @@ uint32_t p8_pore_gen_cpureg(void *io_image, * Parameter list: i_image - pointer to SLW mainstore image * i_sizeImage - size of SLW mainstore image * i_scomAddr - scom register address - * i_scomData - 64-bit data to put in scom register - * i_operation - what to do with the scom data * i_coreId - the core ID [0:15] + * i_scomData - 64-bit data to put in scom register + * i_operation - what to do with the scom data [0:5] + * i_section - SCOM section [0,2,3] */ uint32_t p8_pore_gen_scom(void *io_image, uint32_t i_sizeImage, uint32_t i_scomAddr, uint32_t i_coreId, uint64_t i_scomData, - uint32_t i_operation); + uint32_t i_operation, + uint32_t i_section); #ifdef __cplusplus } diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_ring_identification.H b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_ring_identification.H new file mode 100644 index 000000000..e516afed8 --- /dev/null +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_ring_identification.H @@ -0,0 +1,68 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_ring_identification.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* 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. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: p8_ring_identification.H,v 1.6 2012/11/13 16:39:12 cmolsen Exp $ +/*------------------------------------------------------------------------------*/ +/* *! (C) Copyright International Business Machines Corp. 2012 */ +/* *! All Rights Reserved -- Property of IBM */ +/* *! *** IBM Confidential *** */ +/*------------------------------------------------------------------------------*/ +/* *! TITLE : p8_ring_identification */ +/* *! DESCRIPTION : Include file for global static #G & #R ringID vs ringName. */ +/* *! OWNER NAME : Michael Olsen Email: cmolsen@us.ibm.com */ +// +/*------------------------------------------------------------------------------*/ +#include <p8_pore_api_custom.h> +#include <string.h> // Why isn't this included in p8_pore_api_custom.h? PHYP + // said back in Aug that strcmp() is allowed. But it is + // not in p8_pore_api_custom.h. + +// Ring ID list structure. +typedef struct { + const char *ringName; + uint8_t ringId; + uint8_t chipIdMin; + uint8_t chipIdMax; + const char *ringNameImg; // Ring name in image: ringName + "_ring" + uint8_t vpdKeyword; +} RingIdList; + +extern const RingIdList RING_ID_LIST_PG[], RING_ID_LIST_PR[]; +extern const uint32_t RING_ID_LIST_PG_SIZE, RING_ID_LIST_PR_SIZE; +extern const RingIdList RING_ID_LIST[]; +extern const uint32_t RING_ID_LIST_SIZE; + +// Enumerated VPD keyword values. +// Note! This is DIFFERENT from the MvpdKeyword list in fapiMvpdAccess.H which +// can't be used in this file since it's not, per se, a fapi file. So +// these values need to be translated in xip_customize when passing the +// mvpdKeyword to getMvpdRing(); +enum VpdKeyword { + VPD_KEYWORD_PDG, + VPD_KEYWORD_PDR, + NUM_OF_VPD_TYPES +}; + +int get_vpd_ring_list_entry(const char *i_ringName, + const uint8_t i_ringId, + RingIdList **i_ringIdList); + diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_ring_identification.c b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_ring_identification.c new file mode 100644 index 000000000..05eeddc2e --- /dev/null +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_ring_identification.c @@ -0,0 +1,158 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_ring_identification.c $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* 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. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: p8_ring_identification.c,v 1.12 2012/12/16 02:06:13 cmolsen Exp $ +/*------------------------------------------------------------------------------*/ +/* *! (C) Copyright International Business Machines Corp. 2012 */ +/* *! All Rights Reserved -- Property of IBM */ +/* *! *** IBM Confidential *** */ +/*------------------------------------------------------------------------------*/ +/* *! TITLE : p8_ring_identification */ +/* *! DESCRIPTION : Global static #G & #R ringID vs ringName. */ +/* *! OWNER NAME : Michael Olsen Email: cmolsen@us.ibm.com */ +// +/*------------------------------------------------------------------------------*/ +#include <p8_ring_identification.H> + +const RingIdList RING_ID_LIST_PG[] = { + /* ringName ringId chipIdMin chipIdMax ringNameImg mvpdKeyword */ + { "ab_gptr_ab", 0xA0, 0x08, 0x08, "ab_gptr_ab_ring", VPD_KEYWORD_PDG }, + { "ab_gptr_ioa", 0xA1, 0x08, 0x08, "ab_gptr_ioa_ring", VPD_KEYWORD_PDG }, + { "ab_gptr_perv", 0xA2, 0x08, 0x08, "ab_gptr_perv_ring", VPD_KEYWORD_PDG }, + { "ab_gptr_pll", 0xA3, 0x08, 0x08, "ab_gptr_pll_ring", VPD_KEYWORD_PDG }, + { "ab_time", 0xA4, 0x08, 0x08, "ab_time_ring", VPD_KEYWORD_PDG }, + { "ex_gptr_core", 0xA5, 0xFF, 0xFF, "ex_gptr_core_ring", VPD_KEYWORD_PDG }, //Chip specific + { "ex_gptr_dpll", 0xA6, 0xFF, 0xFF, "ex_gptr_dpll_ring", VPD_KEYWORD_PDG }, //Chip specific + { "ex_gptr_l2", 0xA7, 0xFF, 0xFF, "ex_gptr_l2_ring", VPD_KEYWORD_PDG }, //Chip specific + { "ex_gptr_l3", 0xA8, 0xFF, 0xFF, "ex_gptr_l3_ring", VPD_KEYWORD_PDG }, //Chip specific + { "ex_gptr_l3refr", 0xA9, 0xFF, 0xFF, "ex_gptr_l3refr_ring", VPD_KEYWORD_PDG }, //Chip specific + { "ex_gptr_perv", 0xAA, 0xFF, 0xFF, "ex_gptr_perv_ring", VPD_KEYWORD_PDG }, //Chip specific + { "ex_time_core", 0xAB, 0x10, 0x1F, "ex_time_core_ring", VPD_KEYWORD_PDG }, //Chiplet specfc + { "ex_time_eco", 0xAC, 0x10, 0x1F, "ex_time_eco_ring", VPD_KEYWORD_PDG }, //Chiplet specfc + { "pb_gptr_dmipll", 0xAD, 0x02, 0x02, "pb_gptr_dmipll_ring", VPD_KEYWORD_PDG }, + { "pb_gptr_mcl", 0xAE, 0x02, 0x02, "pb_gptr_mcl_ring", VPD_KEYWORD_PDG }, + { "pb_gptr_mcr", 0xAF, 0x02, 0x02, "pb_gptr_mcr_ring", VPD_KEYWORD_PDG }, + { "pb_gptr_nest", 0xB0, 0x02, 0x02, "pb_gptr_nest_ring", VPD_KEYWORD_PDG }, + { "pb_gptr_nx", 0xB1, 0x02, 0x02, "pb_gptr_nx_ring", VPD_KEYWORD_PDG }, + { "pb_gptr_pcis", 0xB2, 0x02, 0x02, "pb_gptr_pcis_ring", VPD_KEYWORD_PDG }, + { "pb_gptr_perv", 0xB3, 0x02, 0x02, "pb_gptr_perv_ring", VPD_KEYWORD_PDG }, + { "pb_time", 0xB4, 0x02, 0x02, "pb_time_ring", VPD_KEYWORD_PDG }, + { "pb_time_mcl", 0xB5, 0x02, 0x02, "pb_time_mcl_ring", VPD_KEYWORD_PDG }, + { "pb_time_mcr", 0xB5, 0x02, 0x02, "pb_time_mcr_ring", VPD_KEYWORD_PDG }, + { "pb_time_nx", 0xB6, 0x02, 0x02, "pb_time_nx_ring", VPD_KEYWORD_PDG }, + { "pci_gptr_iopci", 0xB7, 0x09, 0x09, "pci_gptr_iopci_ring", VPD_KEYWORD_PDG }, + { "pci_gptr_pbf", 0xB8, 0x09, 0x09, "pci_gptr_pbf_ring", VPD_KEYWORD_PDG }, + { "pci_gptr_pci0", 0xB9, 0x09, 0x09, "pci_gptr_pci0_ring", VPD_KEYWORD_PDG }, + { "pci_gptr_pci1", 0xBA, 0x09, 0x09, "pci_gptr_pci1_ring", VPD_KEYWORD_PDG }, + { "pci_gptr_pci2", 0xBB, 0x09, 0x09, "pci_gptr_pci2_ring", VPD_KEYWORD_PDG }, + { "pci_gptr_perv", 0xBC, 0x09, 0x09, "pci_gptr_perv_ring", VPD_KEYWORD_PDG }, + { "pci_gptr_pll", 0xBD, 0x09, 0x09, "pci_gptr_pll_ring", VPD_KEYWORD_PDG }, + { "pci_time", 0xBE, 0x09, 0x09, "pci_time_ring", VPD_KEYWORD_PDG }, + { "perv_gptr_net", 0xBF, 0x00, 0x00, "perv_gptr_net_ring", VPD_KEYWORD_PDG }, + { "perv_gptr_occ", 0xC0, 0x00, 0x00, "perv_gptr_occ_ring", VPD_KEYWORD_PDG }, + { "perv_gptr_perv", 0xC1, 0x00, 0x00, "perv_gptr_perv_ring", VPD_KEYWORD_PDG }, + { "perv_gptr_pib", 0xC2, 0x00, 0x00, "perv_gptr_pib_ring", VPD_KEYWORD_PDG }, + { "perv_gptr_pll", 0xC3, 0x00, 0x00, "perv_gptr_pll_ring", VPD_KEYWORD_PDG }, + { "perv_time", 0xC4, 0x00, 0x00, "perv_time_ring", VPD_KEYWORD_PDG }, + { "xb_gptr_iox", 0xC5, 0x04, 0x04, "xb_gptr_iox_ring", VPD_KEYWORD_PDG }, + { "xb_gptr_iopci", 0xC6, 0x04, 0x04, "xb_gptr_iopci_ring", VPD_KEYWORD_PDG }, + { "xb_gptr_pben", 0xC7, 0x04, 0x04, "xb_gptr_pben_ring", VPD_KEYWORD_PDG }, + { "xb_gptr_perv", 0xC8, 0x04, 0x04, "xb_gptr_perv_ring", VPD_KEYWORD_PDG }, + { "xb_time", 0xC9, 0x04, 0x04, "xb_time_ring", VPD_KEYWORD_PDG }, +}; + +const RingIdList RING_ID_LIST_PR[] = { + /* ringName ringId chipIdMin chipIdMax ringNameImg mvpdKeyword */ + { "ab_repr", 0xE0, 0x08, 0x08, "ab_repr_ring", VPD_KEYWORD_PDR }, + { "ex_repr_core", 0xE1, 0x10, 0x1F, "ex_repr_core_ring", VPD_KEYWORD_PDR }, + { "ex_repr_eco", 0xE2, 0x10, 0x1F, "ex_repr_eco_ring", VPD_KEYWORD_PDR }, + { "pb_repr", 0xE3, 0x02, 0x02, "pb_repr_ring", VPD_KEYWORD_PDR }, + { "pb_repr_mcl", 0xE4, 0x02, 0x02, "pb_repr_mcl_ring", VPD_KEYWORD_PDR }, + { "pb_repr_mcr", 0xE5, 0x02, 0x02, "pb_repr_mcr_ring", VPD_KEYWORD_PDR }, + { "pb_repr_nx", 0xE6, 0x02, 0x02, "pb_repr_nx_ring", VPD_KEYWORD_PDR }, + { "pci_repr", 0xE7, 0x09, 0x09, "pci_repr_ring", VPD_KEYWORD_PDR }, + { "perv_repr", 0xE8, 0x00, 0x00, "perv_repr_ring", VPD_KEYWORD_PDR }, + { "perv_repr_net", 0xE9, 0x00, 0x00, "perv_repr_net_ring", VPD_KEYWORD_PDR }, + { "perv_repr_pib", 0xEA, 0x00, 0x00, "perv_repr_pib_ring", VPD_KEYWORD_PDR }, + { "xb_repr", 0xEB, 0x04, 0x04, "xb_repr_ring", VPD_KEYWORD_PDR }, +}; + +const uint32_t RING_ID_LIST_PG_SIZE = sizeof(RING_ID_LIST_PG)/sizeof(RING_ID_LIST_PG[0]); +const uint32_t RING_ID_LIST_PR_SIZE = sizeof(RING_ID_LIST_PR)/sizeof(RING_ID_LIST_PR[0]); + +// The following defines are probably safe to decommision at this point. +const RingIdList RING_ID_LIST[] = { + /* ringName ringId chipIdMin chipIdMax ringNameImg mvpdKeyword */ + { "ab_repr", 0xE0, 0x08, 0x08, "ab_repr_ring", VPD_KEYWORD_PDR }, + { "ex_repr_core", 0xE1, 0x10, 0x1F, "ex_repr_core_ring", VPD_KEYWORD_PDR }, + { "ex_repr_eco", 0xE2, 0x10, 0x1F, "ex_repr_eco_ring", VPD_KEYWORD_PDR }, + { "pb_repr", 0xE3, 0x02, 0x02, "pb_repr_ring", VPD_KEYWORD_PDR }, + { "pb_repr_mcl", 0xE4, 0x02, 0x02, "pb_repr_mcl_ring", VPD_KEYWORD_PDR }, + { "pb_repr_mcr", 0xE5, 0x02, 0x02, "pb_repr_mcr_ring", VPD_KEYWORD_PDR }, + { "pb_repr_nx", 0xE6, 0x02, 0x02, "pb_repr_nx_ring", VPD_KEYWORD_PDR }, + { "pci_repr", 0xE7, 0x09, 0x09, "pci_repr_ring", VPD_KEYWORD_PDR }, + { "perv_repr", 0xE8, 0x00, 0x00, "perv_repr_ring", VPD_KEYWORD_PDR }, + { "perv_repr_net", 0xE9, 0x00, 0x00, "perv_repr_net_ring", VPD_KEYWORD_PDR }, + { "perv_repr_pib", 0xEA, 0x00, 0x00, "perv_repr_pib_ring", VPD_KEYWORD_PDR }, + { "xb_repr", 0xEB, 0x04, 0x04, "xb_repr_ring", VPD_KEYWORD_PDR }, +}; +const uint32_t RING_ID_LIST_SIZE = sizeof(RING_ID_LIST)/sizeof(RING_ID_LIST[0]); + +// get_vpd_ring_list_entry() retrieves the MVPD list entry based on either a ringName +// or a ringId. If both are supplied, only the ringName is used. If ringName==NULL, +// then the ringId is used. A pointer to the RingIdList is returned. +int get_vpd_ring_list_entry(const char *i_ringName, + const uint8_t i_ringId, + RingIdList **i_ringIdList) +{ + int rc=0, NOT_FOUND=0, FOUND=1; + uint8_t iVpdType; + uint8_t iRing; + RingIdList *ring_id_list=NULL; + uint8_t ring_id_list_size; + + rc = NOT_FOUND; + for (iVpdType=0; iVpdType<NUM_OF_VPD_TYPES; iVpdType++) { + if (iVpdType==0) { + ring_id_list = (RingIdList*)RING_ID_LIST_PG; + ring_id_list_size = (uint32_t)RING_ID_LIST_PG_SIZE; + } + else { + ring_id_list = (RingIdList*)RING_ID_LIST_PR; + ring_id_list_size = (uint32_t)RING_ID_LIST_PR_SIZE; + } + // Search the MVPD reference lists. + if (i_ringName) { + for (iRing=0; iRing<ring_id_list_size; iRing++) { + if (strcmp((ring_id_list+iRing)->ringNameImg,i_ringName)==0) { + *i_ringIdList = ring_id_list+iRing; + return FOUND; + } + } + } + // Since ringName was not supplied, search for ringId. + // 2012-11-12: TBD. + + } + return rc; +} + diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_scan_compression.C b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_scan_compression.C index 73e2189af..d221b0aab 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_scan_compression.C +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_scan_compression.C @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_scan_compression.C,v 1.5 2012/09/20 20:25:29 bcbrock Exp $ +// $Id: p8_scan_compression.C,v 1.6 2012/10/22 22:13:38 bcbrock Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/utils/p8_scan_compression.C,v $ //------------------------------------------------------------------------------ // *! (C) Copyright International Business Machines Corp. 2011 @@ -134,6 +134,7 @@ #include <stdlib.h> +#include <string.h> #include "p8_scan_compression.H" // Diagnostic aids for debugging @@ -173,6 +174,10 @@ #endif // DEBUG_P8_SCAN_COMPRESSION +// Note: PHYP requires that all subroutines, _even static subroutines_, have +// unique names to support concurrent update. Most routines defined here have +// some variant of 'rs4' in their names; others should be inherently unique. + // Note: For maximum flexibility we provide private versions of // endian-conversion routines rather than counting on a system-specific header // to provide these. @@ -180,7 +185,7 @@ // Byte-reverse a 32-bit integer if on a little-endian machine static uint32_t -revle32(const uint32_t i_x) +rs4_revle32(const uint32_t i_x) { uint32_t rx; @@ -207,11 +212,11 @@ void compressed_scan_data_translate(CompressedScanData* o_data, CompressedScanData* i_data) { - o_data->iv_magic = revle32(i_data->iv_magic); - o_data->iv_size = revle32(i_data->iv_size); - o_data->iv_algorithmReserved = revle32(i_data->iv_algorithmReserved); - o_data->iv_length = revle32(i_data->iv_length); - o_data->iv_scanSelect = revle32(i_data->iv_scanSelect); + o_data->iv_magic = rs4_revle32(i_data->iv_magic); + o_data->iv_size = rs4_revle32(i_data->iv_size); + o_data->iv_algorithmReserved = rs4_revle32(i_data->iv_algorithmReserved); + o_data->iv_length = rs4_revle32(i_data->iv_length); + o_data->iv_scanSelect = rs4_revle32(i_data->iv_scanSelect); o_data->iv_headerVersion = i_data->iv_headerVersion; o_data->iv_flushOptimization = i_data->iv_flushOptimization; o_data->iv_ringId = i_data->iv_ringId; @@ -222,7 +227,7 @@ compressed_scan_data_translate(CompressedScanData* o_data, // Return a big-endian-indexed nibble from a byte string static int -get_nibble(const uint8_t* i_string, const uint32_t i_i) +rs4_get_nibble(const uint8_t* i_string, const uint32_t i_i) { uint8_t byte; int nibble; @@ -240,7 +245,7 @@ get_nibble(const uint8_t* i_string, const uint32_t i_i) // Set a big-endian-indexed nibble in a byte string static int -set_nibble(uint8_t* io_string, const uint32_t i_i, const int i_nibble) +rs4_set_nibble(uint8_t* io_string, const uint32_t i_i, const int i_nibble) { uint8_t* byte; @@ -259,7 +264,7 @@ set_nibble(uint8_t* io_string, const uint32_t i_i, const int i_nibble) // resulting code. static int -stop_encode(const uint32_t i_count, uint8_t* io_string, const uint32_t i_i) +rs4_stop_encode(const uint32_t i_count, uint8_t* io_string, const uint32_t i_i) { uint32_t count; int digits, offset; @@ -276,14 +281,14 @@ stop_encode(const uint32_t i_count, uint8_t* io_string, const uint32_t i_i) // First insert the stop (low-order) digit offset = digits - 1; - set_nibble(io_string, i_i + offset, (i_count & 0x7) | 0x8); + rs4_set_nibble(io_string, i_i + offset, (i_count & 0x7) | 0x8); // Now insert the high-order digits count = i_count >> 3; offset--; while (count) { - set_nibble(io_string, i_i + offset, count & 0x7); + rs4_set_nibble(io_string, i_i + offset, count & 0x7); offset--; count >>= 3; } @@ -306,7 +311,7 @@ stop_decode(uint32_t* o_count, const uint8_t* i_string, const uint32_t i_i) i = i_i; do { - nibble = get_nibble(i_string, i); + nibble = rs4_get_nibble(i_string, i); count = (count * 8) + (nibble & 0x7); i++; digits++; @@ -334,9 +339,9 @@ stop_decode(uint32_t* o_count, const uint8_t* i_string, const uint32_t i_i) // Returns the number of nibbles in the compressed string. static uint32_t -_rs4_compress(CompressedScanData* o_data, - const uint8_t* i_string, - const uint32_t i_length) +__rs4_compress(CompressedScanData* o_data, + const uint8_t* i_string, + const uint32_t i_length) { int state; /* 0 : Rotate, 1 : Scan */ uint32_t n; /* Number of whole nibbles in i_data */ @@ -361,36 +366,36 @@ _rs4_compress(CompressedScanData* o_data, while (i < n) { if (state == 0) { - if (get_nibble(i_string, i) == 0) { + if (rs4_get_nibble(i_string, i) == 0) { count++; i++; } else { - j += stop_encode(count, data, j); + j += rs4_stop_encode(count, data, j); count = 0; k = j; j++; state = 1; } } else { - if (get_nibble(i_string, i) == 0) { - if (((i + 1) < n) && (get_nibble(i_string, i + 1) == 0)) { - set_nibble(data, k, count); + if (rs4_get_nibble(i_string, i) == 0) { + if (((i + 1) < n) && (rs4_get_nibble(i_string, i + 1) == 0)) { + rs4_set_nibble(data, k, count); count = 0; state = 0; } else { - set_nibble(data, j, 0); + rs4_set_nibble(data, j, 0); count++; i++; j++; } } else { - set_nibble(data, j, get_nibble(i_string, i)); + rs4_set_nibble(data, j, rs4_get_nibble(i_string, i)); count++; i++; j++; } if ((state == 1) && (count == 15)) { - set_nibble(data, k, 15); + rs4_set_nibble(data, k, 15); state = 0; count = 0; } @@ -401,21 +406,21 @@ _rs4_compress(CompressedScanData* o_data, // finish on a scan we must insert a null rotate first. if (state == 0) { - j += stop_encode(count, data, j); + j += rs4_stop_encode(count, data, j); } else { - set_nibble(data, k, count); - j += stop_encode(0, data, j); + rs4_set_nibble(data, k, count); + j += rs4_stop_encode(0, data, j); } - set_nibble(data, j, 0); + rs4_set_nibble(data, j, 0); j++; // Insert the remainder count nibble, and if non-0, the remainder data // nibble. - set_nibble(data, j, r); + rs4_set_nibble(data, j, r); j++; if (r != 0) { - set_nibble(data, j, get_nibble(i_string, n)); + rs4_set_nibble(data, j, rs4_get_nibble(i_string, n)); j++; } @@ -427,6 +432,64 @@ _rs4_compress(CompressedScanData* o_data, // The worst-case compression for RS4 requires 2 nibbles of control overhead // per 15 nibbles of data (17/15), plus a maximum of 2 nibbles of termination. +// We always require this worst-case amount of memory including the header and +// any rounding required to guarantee that the data size is a multiple of 8 +// bytes. The final image size is also rounded up to a multiple of 8 bytes. + +int +_rs4_compress(CompressedScanData* io_data, + uint32_t i_dataSize, + uint32_t* o_imageSize, + const uint8_t* i_string, + const uint32_t i_length, + const uint64_t i_scanSelect, + const uint8_t i_ringId, + const uint8_t i_chipletId, + const uint8_t i_flushOptimization) +{ + int rc; + uint32_t nibbles, bytes; + + nibbles = (((((i_length + 3) / 4) + 14) / 15) * 17) + 2; + bytes = ((nibbles + 1) / 2) + sizeof(CompressedScanData); + bytes = ((bytes + 7) / 8) * 8; + + do { + + if (i_dataSize < bytes) { + rc = BUG(SCAN_COMPRESSION_BUFFER_OVERFLOW); + break; + } + + memset(io_data, 0, bytes); + + nibbles = __rs4_compress(io_data, i_string, i_length); + bytes = ((nibbles + 1) / 2) + sizeof(CompressedScanData); + bytes = ((bytes + 7) / 8) * 8; + + io_data->iv_magic = rs4_revle32(RS4_MAGIC); + io_data->iv_size = rs4_revle32(bytes); + io_data->iv_algorithmReserved = rs4_revle32(nibbles); + io_data->iv_length = rs4_revle32(i_length); + io_data->iv_scanSelect = rs4_revle32((uint32_t)(i_scanSelect >> + 32)); + io_data->iv_headerVersion = COMPRESSED_SCAN_DATA_VERSION; + io_data->iv_flushOptimization = i_flushOptimization; + io_data->iv_ringId = i_ringId; + io_data->iv_chipletId = i_chipletId; + + *o_imageSize = bytes; + + rc = SCAN_COMPRESSION_OK; + + } while (0); + + return rc; +} + + +// The worst-case compression for RS4 requires 2 nibbles of control overhead +// per 15 nibbles of data (17/15), plus a maximum of 2 nibbles of termination. // We always allocate this worst-case amount of memory including the header // and any rounding required to guarantee that the allocated length is a // multiple of 8 bytes. The final size is also rounded up to a multiple of 8 @@ -438,7 +501,7 @@ rs4_compress(CompressedScanData** o_data, const uint8_t* i_string, const uint32_t i_length, const uint64_t i_scanSelect, - const uint8_t i_ringId, + const uint8_t i_ringId, const uint8_t i_chipletId, const uint8_t i_flushOptimization) { @@ -449,28 +512,14 @@ rs4_compress(CompressedScanData** o_data, bytes = ((nibbles + 1) / 2) + sizeof(CompressedScanData); bytes = ((bytes + 7) / 8) * 8; - *o_data = (CompressedScanData*)calloc(bytes, 1); + *o_data = (CompressedScanData*)malloc(bytes); if (*o_data == 0) { rc = BUG(SCAN_COMPRESSION_NO_MEMORY); } else { - nibbles = _rs4_compress(*o_data, i_string, i_length); - bytes = ((nibbles + 1) / 2) + sizeof(CompressedScanData); - bytes = ((bytes + 7) / 8) * 8; - - (*o_data)->iv_magic = revle32(RS4_MAGIC); - (*o_data)->iv_size = revle32(bytes); - (*o_data)->iv_algorithmReserved = revle32(nibbles); - (*o_data)->iv_length = revle32(i_length); - (*o_data)->iv_scanSelect = revle32((uint32_t)(i_scanSelect >> 32)); - (*o_data)->iv_headerVersion = COMPRESSED_SCAN_DATA_VERSION; - (*o_data)->iv_flushOptimization = i_flushOptimization; - (*o_data)->iv_ringId = i_ringId; - (*o_data)->iv_chipletId = i_chipletId; - - *o_size = bytes; - - rc = SCAN_COMPRESSION_OK; + rc = _rs4_compress(*o_data, bytes, o_size, i_string, i_length, + i_scanSelect, i_ringId, i_chipletId, + i_flushOptimization); } return rc; @@ -483,9 +532,9 @@ rs4_compress(CompressedScanData** o_data, // Returns a scan compression return code. static int -_rs4_decompress(uint8_t* o_string, - const uint8_t* i_string, - const uint32_t i_length) +__rs4_decompress(uint8_t* o_string, + const uint8_t* i_string, + const uint32_t i_length) { int rc; int state; /* 0 : Rotate, 1 : Scan */ @@ -515,12 +564,12 @@ _rs4_decompress(uint8_t* o_string, i += nibbles; bits += (4 * count); for (k = 0; k < count; k++) { - set_nibble(o_string, j, 0); + rs4_set_nibble(o_string, j, 0); j++; } state = 1; } else { - nibbles = get_nibble(i_string, i); + nibbles = rs4_get_nibble(i_string, i); i++; if (nibbles == 0) { break; @@ -531,7 +580,7 @@ _rs4_decompress(uint8_t* o_string, } bits += (4 * nibbles); for (k = 0; k < nibbles; k++) { - set_nibble(o_string, j, get_nibble(i_string, i)); + rs4_set_nibble(o_string, j, rs4_get_nibble(i_string, i)); i++; j++; } @@ -542,14 +591,14 @@ _rs4_decompress(uint8_t* o_string, // Now handle string termination if (!rc) { - r = get_nibble(i_string, i); + r = rs4_get_nibble(i_string, i); i++; if (r != 0) { if ((bits + r) > i_length) { rc = BUG(SCAN_DECOMPRESSION_SIZE_ERROR); } else { bits += r; - set_nibble(o_string, j, get_nibble(i_string, i)); + rs4_set_nibble(o_string, j, rs4_get_nibble(i_string, i)); } } } @@ -569,30 +618,64 @@ _rs4_decompress(uint8_t* o_string, int +_rs4_decompress(uint8_t* io_string, + uint32_t i_stringSize, + uint32_t* o_length, + const CompressedScanData* i_data) +{ + int rc; + uint32_t bytes; + + do { + if (rs4_revle32(i_data->iv_magic) != RS4_MAGIC) { + rc = BUG(SCAN_DECOMPRESSION_MAGIC_ERROR); + break; + } + + *o_length = rs4_revle32(i_data->iv_length); + bytes = (*o_length + 7) / 8; + + if (i_stringSize < bytes) { + rc = BUG(SCAN_COMPRESSION_BUFFER_OVERFLOW); + break; + } + + memset(io_string, 0, bytes); + + rc = __rs4_decompress(io_string, + (uint8_t*)i_data + sizeof(CompressedScanData), + *o_length); + } while (0); + + return rc; +} + + +int rs4_decompress(uint8_t** o_string, uint32_t* o_length, const CompressedScanData* i_data) { int rc; - uint32_t bytes; + uint32_t length, bytes; do { - if (revle32(i_data->iv_magic) != RS4_MAGIC) { + if (rs4_revle32(i_data->iv_magic) != RS4_MAGIC) { rc = BUG(SCAN_DECOMPRESSION_MAGIC_ERROR); break; } - *o_length = revle32(i_data->iv_length); - bytes = (*o_length + 7) / 8; - *o_string = (uint8_t*)calloc(bytes, 1); + length = rs4_revle32(i_data->iv_length); + bytes = (length + 7) / 8; + *o_string = (uint8_t*)malloc(bytes); + if (*o_string == 0) { rc = BUG(SCAN_COMPRESSION_NO_MEMORY); break; } - rc = _rs4_decompress(*o_string, - (uint8_t*)i_data + sizeof(CompressedScanData), - *o_length); + rc = _rs4_decompress(*o_string, bytes, o_length, i_data); + } while (0); return rc; diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_scan_compression.H b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_scan_compression.H index 8e4d38364..72089f478 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_scan_compression.H +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_scan_compression.H @@ -23,7 +23,7 @@ #ifndef __P8_SCAN_COMPRESSION_H__ #define __P8_SCAN_COMPRESSION_H__ -// $Id: p8_scan_compression.H,v 1.3 2012/09/20 20:25:37 bcbrock Exp $ +// $Id: p8_scan_compression.H,v 1.4 2012/10/22 22:13:39 bcbrock Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/utils/p8_scan_compression.H,v $ //------------------------------------------------------------------------------ // *! (C) Copyright International Business Machines Corp. 2011 @@ -163,7 +163,68 @@ compressed_scan_data_translate(CompressedScanData* o_data, /// Compress a scan string using the RS4 compression algorithm /// -/// \param o_data This algorithm uses malloc() to allocate memory for the +/// \param[in,out] io_data This is a pointer to a memory area which must be +/// large enough to hold the worst-case result of compressing \a i_string (see +/// below). Note that the CompressedScanData is always created in big-endian +/// format, however the caller can use compresed_scan_data_translate() to +/// create a copy of the header in host format. +/// +/// \param[in] i_dataSize The size of \a io_data in bytes. +/// +/// \param[out] o_imageSize The effective size of the entire compressed scan +/// data structure (header + compressed data) created in \a io_data, in bytes. +/// This value will always be a multiple of 8. +/// +/// \param[in] i_string The string to compress. Scan data to compress is +/// left-justified in this input string. +/// +/// \param[in] i_length The length of the input string in \e bits. It is +/// assumed the \a i_string contains at least (\a i_length + 7) / 8 bytes. +/// +/// \param[in] i_scanSelect The 64-bit value written to the Scan Select +/// register to set up for the scan. Only the 32 high-order bits are actually +/// stored. +/// +/// \param[in] i_ringId The ring ID that uniquely identifies the ring name of +/// a repair ring. (See p8_ring_identification.c for more info.) +/// +/// \param[in] i_chipletId The 7-bit value for the iv_chipletId field of the +/// CompressedScanData. +/// +/// \param[in] i_flushOptimization This input parameter should be set to a +/// non-0 value if it is known that this ring difference will be applied to a +/// scan-0 flush state. This will improve the performance of the +/// decompress-scan routine. If the initial state of the ring is unknown, set +/// this parameter to 0. +/// +/// This API is required for integration with PHYP which does not support +/// malloc(). Applications in environments supporting malloc() can use +/// rs4_compress() instead. +/// +/// The worst-case compression for RS4 requires 2 nibbles of control overhead +/// per 15 nibbles of data (17/15), plus a maximum of 2 nibbles of termination. +/// We always require this worst-case amount of memory including the header and +/// any rounding required to guarantee that the data size is a multiple of 8 +/// bytes. The final image size is also rounded up to a multiple of 8 bytes. +/// If the \a i_dataSize is less than this amount (based on \a i_length) the +/// call will fail. +/// +/// \returns See \ref scan_compression_codes +int +_rs4_compress(CompressedScanData* io_data, + uint32_t i_dataSize, + uint32_t* o_imageSize, + const uint8_t* i_string, + const uint32_t i_length, + const uint64_t i_scanSelect, + const uint8_t i_ringId, + const uint8_t i_chipletId, + const uint8_t i_flushOptimization); + + +/// Compress a scan string using the RS4 compression algorithm +/// +/// \param[out] o_data This algorithm uses malloc() to allocate memory for the /// compresed data, and returns a pointer to this memory in \a o_data. After /// the call this memory is owned by the caller who is responsible for /// free()-ing the data area once it is no longer required. Note that the @@ -171,30 +232,31 @@ compressed_scan_data_translate(CompressedScanData* o_data, /// caller can use compresed_scan_data_translate() to create a copy of the /// header in host format. /// -/// \param o_size The effective size of the entire compressed scan data +/// \param[out] o_size The effective size of the entire compressed scan data /// structure (header + compressed data) pointed to by \a o_data, in bytes. /// This value will always be a multiple of 8. /// -/// \param i_string The string to compress. Scan data to compress is +/// \param[in] i_string The string to compress. Scan data to compress is /// left-justified in this input string. /// -/// \param i_length The length of the input string in \e bits. It is assumed -/// the \a i_string contains at least (\a i_length + 7) / 8 bytes. +/// \param[in] i_length The length of the input string in \e bits. It is +/// assumed the \a i_string contains at least (\a i_length + 7) / 8 bytes. /// -/// \param i_scanSelect The 64-bit value written to the Scan Select register -/// to set up for the scan. Only the 32 high-order bits are actually stored. +/// \param[in] i_scanSelect The 64-bit value written to the Scan Select +/// register to set up for the scan. Only the 32 high-order bits are actually +/// stored. /// -/// \param i_ringId The ring ID that uniquely identifies the ring name of +/// \param[in] i_ringId The ring ID that uniquely identifies the ring name of /// a repair ring. (See p8_ring_identification.c for more info.) /// -/// \param i_chipletId The 7-bit value for the iv_chipletId field of the -/// CompressedScanData. +/// \param[in] i_chipletId The 7-bit value for the iv_chipletId field of the +/// CompressedScanData. /// -/// \param i_flushOptimization This input parameter should be set to a non-0 -/// value if it is known that this ring difference will be applied to a scan-0 -/// flush state. This will improve the performance of the decompress-scan -/// routine. If the initial state of the ring is unknown, set this parameter -/// to 0. +/// \param[in] i_flushOptimization This input parameter should be set to a +/// non-0 value if it is known that this ring difference will be applied to a +/// scan-0 flush state. This will improve the performance of the +/// decompress-scan routine. If the initial state of the ring is unknown, set +/// this parameter to 0. /// /// \returns See \ref scan_compression_codes int @@ -210,21 +272,50 @@ rs4_compress(CompressedScanData** o_data, /// Decompress a scan string compressed using the RS4 compression algorithm /// -/// \param o_string The API malloc()-s this data area to contain the +/// \param[in,out] io_string A caller-supplied data area to contain the +/// decompressed string. The \a i_stringSize must be large enough to contain +/// the decompressed string, which is the size of the original string in bits +/// rounded up to the nearest byte. +/// +/// \param[in] i_stringSize The size (in bytes) of \a i_string. +/// +/// \param[out] o_length The length of the decompressed string in \e bits. +/// +/// \param[in] i_data A pointer to the CompressedScanData header + data to be +/// decompressed. +/// +/// This API is required for integration with PHYP which does not support +/// malloc(). Applications in environments supporting malloc() can use +/// rs4_decompress() instead. +/// +/// \returns See \ref scan_compression_codes +int +_rs4_decompress(uint8_t* i_string, + uint32_t i_stringSize, + uint32_t* o_length, + const CompressedScanData* i_data); + + +/// Decompress a scan string compressed using the RS4 compression algorithm +/// +/// \param[out] o_string The API malloc()-s this data area to contain the /// decompressed string. After this call the caller owns \a o_string and is /// responsible for free()-ing this data area once it is no longer required. /// -/// \param o_length The length of the decompressed string in \e bits. The -/// caller may assume that \a o_string contains at least (\a o_length + 7) / 8 -/// bytes. +/// \param[out] o_length The length of the decompressed string in \e bits. +/// The caller may assume that \a o_string contains at least (\a o_length + 7) +/// / 8 \e bytes. +/// +/// \param[in] i_data A pointer to the CompressedScanData header + data to be +/// decompressed. /// -/// \param i_data A pointer to the CompressedScanData header + data to be -/// decompressed. +/// \returns See \ref scan_compression_codes int rs4_decompress(uint8_t** o_string, uint32_t* o_length, const CompressedScanData* i_data); + #endif // __ASSEMBLER__ @@ -270,6 +361,14 @@ CONST_UINT8_T(SCAN_DECOMPRESSION_MAGIC_ERROR, 2); /// may not be discovered until after the decompression buffer is overrun. CONST_UINT8_T(SCAN_DECOMPRESSION_SIZE_ERROR, 3); +/// A buffer would overflow +/// +/// Either the caller-supplied memory buffer to _rs4_decompress() was too +/// small to contain the decompressed string, or a caller-supplied buffer to +/// _rs4_compress() was not large enough to hold the worst-case compressed +/// string. +CONST_UINT8_T(SCAN_COMPRESSION_BUFFER_OVERFLOW, 4); + /// @} #endif // __P8_SCAN_COMPRESSION_H__ diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_slw_build.C b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_slw_build.C index 79800a66f..f74280b55 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_slw_build.C +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_slw_build.C @@ -20,13 +20,13 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: p8_slw_build.C,v 1.3 2012/09/19 14:07:17 cmolsen Exp $ +// $Id: p8_slw_build.C,v 1.7 2012/11/27 18:44:03 cmolsen Exp $ /*------------------------------------------------------------------------------*/ /* *! TITLE : p8_slw_build */ /* *! DESCRIPTION : Extracts and decompresses delta ring states from EPROM */ // image. Utilizes the linked list approach (LLA) to extract -// and position wiggle-flip programs in .rings according to -// back pointer, DD level, phase and override settings. +// and position wiggle-flip programs in .rings according to +// back pointer, DD level, phase and override settings. /* *! OWNER NAME : Michael Olsen cmolsen@us.ibm.com */ // /* *! EXTENDED DESCRIPTION : */ @@ -34,8 +34,8 @@ /* *! USAGE : To build (for Hostboot) - */ // buildfapiprcd -C "p8_image_help.C,p8_scan_compression.C" -c "sbe_xip_image.c,pore_inline_assembler.c" -e "../../xml/error_info/p8_slw_build_errors.xml" p8_slw_build.C // To build (for command-line) - -// buildfapiprcd -C "p8_image_help.C,p8_scan_compression.C" -c "sbe_xip_image.c,pore_inline_assembler.c" -e "../../xml/error_info/p8_slw_build_errors.xml" -u "SLW_COMMAND_LINE" p8_slw_build.C -// Other Pre-Processor Directive (PPD) options - +// buildfapiprcd -r ver-13-0 -C "p8_image_help.C,p8_scan_compression.C" -c "sbe_xip_image.c,pore_inline_assembler.c" -e "../../xml/error_info/p8_slw_build_errors.xml" -u "SLW_COMMAND_LINE,IMGBUILD_PPD_IGNORE_XIPC" p8_slw_build.C +// Other Pre-Processor Directive (PPD) options - // To debug WF programs: // -u "IMGBUILD_PPD_DEBUG_WF" // To add worst-case PIB access to wf programs: @@ -44,10 +44,10 @@ // -u "IMGBUILD_PPD_WF_POLLING_PROT" // (NB! This will eventually be changed to IMGBUILD_PPD_WF_NO POLLING_PROT // because we want the polling protocol to be default.) -// To add repair rings to the .rings section: -// -u "IMGBUILD_PPD_ADD_REPR_RINGS" -// (NB! This will eventually be changed to IMGBUILD_PPD_OMIT_REPR_RINGS -// because we want the adding of repair rings to be default.) +// To NOT run xip_customize: +// -u "IMGBUILD_PPD_IGNORE_XIPC" +// (NB! Thus, by defaul for HB and PHYP, since they don't used PPDs, +// xip_customize() will always be called.) // /* *! ASSUMPTIONS : */ // - For Hostboot environment: @@ -61,14 +61,19 @@ /* *! COMMENTS : */ // - All image content, incl .initf content and ring layout, is handled // in BE format. No matter which platform. -// - A ring may only be requested with the sysPhase=0 or 1. Any other +// - A ring may only be requested with the sysPhase=0 or 1. Any other // sysPhase value, incl sysPhase=2, will cause no rings to be found. // /*------------------------------------------------------------------------------*/ +// The IMGBUILD_PPD_IGNORE_XIPC is defined to temporarily disable the call of +// p8_xip_customize HWP. +// @Todo: RTC 60670 will remove the macro to re-enable the HWP. +#define IMGBUILD_PPD_IGNORE_XIPC #include <p8_pore_api_custom.h> #include <HvPlicModule.H> #include <p8_slw_build.H> +#include <p8_xip_customize.H> #include <p8_delta_scan_rw.h> #include <p8_pore_table_gen_api.H> @@ -90,22 +95,55 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, uint32_t *io_sizeImageOut) { ReturnCode rc; - uint8_t l_uint8 = 0; + uint8_t l_uint8 = 0; uint32_t ddLevel=0; - uint8_t sysPhase=1; // To build SLW image for Hostboot. - + uint8_t sysPhase=1; // Build an SLW image. + uint32_t rcLoc=0, rcSearch=0, i, countWF=0; uint32_t sizeImage=0, sizeImageOutMax, sizeImageTmp, sizeImageOld; - uint8_t *deltaRingDxed=NULL; + //uint8_t *deltaRingDxed=NULL; CompressedScanData *deltaRingRS4=NULL; DeltaRingLayout rs4RingLayout; void *nextRing=NULL; - uint32_t ringBitLen=0; //ringByteLen=0, ringTrailBits=0; - uint32_t *wfInline=NULL; - uint32_t wfInlineLenInWords; - uint64_t scanMaxRotate=SCAN_ROTATE_DEFAULT; + uint32_t ringBitLen=0; //ringByteLen=0, ringTrailBits=0; + uint32_t *wfInline=NULL; + uint32_t wfInlineLenInWords; + uint64_t scanMaxRotate=SCAN_ROTATE_DEFAULT; sizeImageOutMax = *io_sizeImageOut; + + + // 2012-11-13: CMO- Temporary defines of ring buffers. This will be changed by + // Dec 03 where we'll switch over to a fixed size image for ffdc + // support and will schedule the enhancement to slw_build's + // interface to accept these buffers as well as to ditch + // io_sizeImageOut. We also should drop i_sizeImageIn. It really + // serves no purpose to require caller to pass this when we can + // immediately retrieve through xip_image_size(). + // CMO- Very important. Stop freeing buffers, incl wfInline, once + // these buffers are being passed as parms by slw_build(). + void *buf1=NULL, *buf2=NULL; + uint32_t sizeBuf1=0, sizeBuf2=0; + uint32_t rcTmp=1; + sizeBuf1 = FIXED_RING_BUF_SIZE; + buf1 = malloc(sizeBuf1); + if (!buf1) { + FAPI_ERR("malloc() for ring buffer 1 failed."); + uint32_t & RC_LOCAL = rcTmp; + FAPI_SET_HWP_ERROR(rc, RC_PROC_SLWB_MEMORY_ERROR); + return rc; + } + sizeBuf2 = FIXED_RING_BUF_SIZE; + buf2 = malloc(sizeBuf2); + if (!buf2) { + FAPI_ERR("malloc() for ring buffer 1 failed."); + uint32_t & RC_LOCAL = rcTmp; + FAPI_SET_HWP_ERROR(rc, RC_PROC_SLWB_MEMORY_ERROR); + free(buf1); + return rc; + } + + // Sanity check. if (sizeImageOutMax<i_sizeImageIn) { FAPI_ERR("Inp image size (from caller): %i",i_sizeImageIn); FAPI_ERR("Max image size (from caller): %i",*io_sizeImageOut); @@ -114,8 +152,7 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, FAPI_SET_HWP_ERROR(rc, RC_PROC_SLWB_INPUT_IMAGE_SIZE_MESS); return rc; } - - + // ========================================================================== // Check and copy image to mainstore and clean it up. // ========================================================================== @@ -142,7 +179,7 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, return rc; } FAPI_DBG("Image size (in EPROM): %i",i_sizeImageIn); - + // Second, copy input image to supplied mainstore location. // memcpy( i_imageOut, i_imageIn, i_sizeImageIn); @@ -216,7 +253,7 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, do { FAPI_DBG("nextRing (at top)=0x%016llx",(uint64_t)nextRing); - + // ========================================================================== // Get ring layout from image @@ -228,37 +265,55 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, &rs4RingLayout, &nextRing); rcSearch = rcLoc; - if (rcSearch!=DSLWB_RING_SEARCH_MATCH && - rcSearch!=DSLWB_RING_SEARCH_EXHAUST_MATCH && + if (rcSearch!=DSLWB_RING_SEARCH_MATCH && + rcSearch!=DSLWB_RING_SEARCH_EXHAUST_MATCH && rcSearch!=DSLWB_RING_SEARCH_NO_MATCH) { - FAPI_ERR("\tERROR : Getting delta ring from image was unsuccessful (rcSearch=%i).",rcSearch); + FAPI_ERR("\tGetting delta ring from image was unsuccessful (rcSearch=%i).",rcSearch); FAPI_ERR("\tNo wiggle-flip programs will be stored in .rings section."); FAPI_ERR("\tThe following ELF sections have been emptied: .rings, .pibmem0, .ipl_text."); uint32_t & RC_LOCAL=rcLoc; FAPI_SET_HWP_ERROR(rc, RC_PROC_SLWB_RING_RETRIEVAL_ERROR); return rc; } - if (rcSearch==DSLWB_RING_SEARCH_MATCH || + if (rcSearch==DSLWB_RING_SEARCH_MATCH || rcSearch==DSLWB_RING_SEARCH_EXHAUST_MATCH) FAPI_DBG("\tRetrieving RS4 delta ring was successful."); // Check if we're done at this point. - // + // if (rcSearch==DSLWB_RING_SEARCH_NO_MATCH) { -#ifdef IMGBUILD_PPD_ADD_REPR_RINGS - // Add repair rings. - rc = p8_xip_customize( i_target, - i_imageOut, - sizeImageOld, - sysPhase, - NULL, - sizeImageoutMax); - // TBD. Need to check RC. -#endif FAPI_INF("Wiggle-flip programming done."); FAPI_INF("Number of wf programs appended: %i", countWF); if (countWF==0) FAPI_INF("ZERO WF programs appended to .rings section."); +#ifndef IMGBUILD_PPD_IGNORE_XIPC + // Do various customizations to image. + if (!buf1 || !buf2) { + FAPI_ERR("The [assumed] pre-allocated ring buffers, buf1/2, do not exist.\n"); + uint32_t & RC_LOCAL = rcTmp; + FAPI_SET_HWP_ERROR(rc, RC_PROC_SLWB_MEMORY_ERROR); + return rc; + } + sizeImageTmp = sizeImageOutMax; + FAPI_INF("Calling xip_customize().\n"); + FAPI_EXEC_HWP(rc, p8_xip_customize, + i_target, + i_imageOut, // This is both in and out image for xip_customize. + NULL, // No need to pass a separate out image + sizeImageTmp, + sysPhase, + buf1, + sizeBuf1, + buf2, + sizeBuf2); + free(buf1); + free(buf2); + if (rc!=FAPI_RC_SUCCESS) { + FAPI_ERR("Xip customization failed."); + return rc; + } + FAPI_INF("Xip customization done."); +#endif sizeImageTmp = sizeImageOutMax; // Initialize .slw section with PORE table. rcLoc = initialize_slw_section( i_imageOut, @@ -287,11 +342,13 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, // Report final size. sbe_xip_image_size( i_imageOut, io_sizeImageOut); FAPI_INF("Final SLW image size: %i", *io_sizeImageOut); + if (buf1) free(buf1); + if (buf2) free(buf2); return FAPI_RC_SUCCESS; } - + deltaRingRS4 = (CompressedScanData*)rs4RingLayout.rs4Delta; - + FAPI_DBG("Dumping ring layout:"); FAPI_DBG("\tentryOffset = %i",(uint32_t)myRev64(rs4RingLayout.entryOffset)); FAPI_DBG("\tbackItemPtr = 0x%016llx",myRev64(rs4RingLayout.backItemPtr)); @@ -301,7 +358,7 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, FAPI_DBG("\tsysPhase = %i",rs4RingLayout.sysPhase); FAPI_DBG("\toverride = %i",rs4RingLayout.override); FAPI_DBG("\treserved1+2 = %i",rs4RingLayout.reserved1|rs4RingLayout.reserved2); - FAPI_DBG("\tRS4 magic # = 0x%08x",myRev32(deltaRingRS4->iv_magic)); + FAPI_DBG("\tRS4 magic # = 0x%08x",myRev32(deltaRingRS4->iv_magic)); FAPI_DBG("\tRS4 total size = %i",myRev32(deltaRingRS4->iv_size)); FAPI_DBG("\tUnXed data size = %i",myRev32(deltaRingRS4->iv_length)); FAPI_DBG("\tScan select = 0x%08x",myRev32(deltaRingRS4->iv_scanSelect)); @@ -322,23 +379,25 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, // ========================================================================== FAPI_DBG("--> Decompressing RS4 delta ring."); // Note: deltaRingDxed is left-aligned. If converting to uint32_t, do BE->LE flip. - deltaRingDxed = NULL; - rcLoc = rs4_decompress( &deltaRingDxed, - &ringBitLen, + //deltaRingDxed = NULL; + //rcLoc = rs4_decompress( &deltaRingDxed, + // &ringBitLen, + // deltaRingRS4); + rcLoc = _rs4_decompress((uint8_t*)buf2, + sizeBuf2, + &ringBitLen, deltaRingRS4); - FAPI_DBG("rs4_decompress %d.\n", rcLoc ); if (rcLoc) { - FAPI_ERR("\tERROR : rs4_decompress() failed: rc=%i",rcLoc); - if (deltaRingDxed) free(deltaRingDxed); + //FAPI_ERR("\trs4_decompress() failed: rc=%i",rcLoc); + //if (deltaRingDxed) free(deltaRingDxed); + FAPI_ERR("\t_rs4_decompress() failed: rc=%i",rcLoc); + if (buf2) free(buf2); uint32_t & RC_LOCAL=rcLoc; FAPI_SET_HWP_ERROR(rc, RC_PROC_SLWB_RS4_DECOMPRESSION_ERROR); return rc; } FAPI_DBG("\tDecompression successful.\n"); - -// ringByteLen = (ringBitLen-1)/8+1; -// ringTrailBits = ringBitLen - 8*(ringByteLen-1); - + // ========================================================================== // Create Wiggle-Flip Programs (but first resolve max rotate status.) @@ -356,7 +415,8 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, } else { FAPI_ERR("ERROR: Nope, couldn't wing it."); - if (deltaRingDxed) free(deltaRingDxed); + //if (deltaRingDxed) free(deltaRingDxed); + if (buf2) free(buf2); uint32_t & RC_LOCAL=rcLoc; FAPI_SET_HWP_ERROR(rc, RC_PROC_SLWB_UNKNOWN_XIP_ERROR); return rc; @@ -369,23 +429,27 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, FAPI_INF("Continuing...\n"); } - rcLoc = create_wiggle_flip_prg( (uint32_t*)deltaRingDxed, + wfInline = (uint32_t*)buf1; + wfInlineLenInWords = sizeBuf1/4; + //rcLoc = create_wiggle_flip_prg( (uint32_t*)deltaRingDxed, + rcLoc = create_wiggle_flip_prg( (uint32_t*)buf2, ringBitLen, myRev32(deltaRingRS4->iv_scanSelect), (uint32_t)deltaRingRS4->iv_chipletId, - &wfInline, + &wfInline, &wfInlineLenInWords, (uint32_t)scanMaxRotate); if (rcLoc) { - FAPI_ERR("ERROR : create_wiggle_flip_prg() failed w/rcLoc=%i",rcLoc); - if (deltaRingDxed) free(deltaRingDxed); + FAPI_ERR("create_wiggle_flip_prg() failed w/rcLoc=%i",rcLoc); + //if (deltaRingDxed) free(deltaRingDxed); + if (buf2) free(buf2); if (wfInline) free(wfInline); uint32_t & RC_LOCAL=rcLoc; FAPI_SET_HWP_ERROR(rc, RC_PROC_SLWB_WF_CREATION_ERROR); return rc; } FAPI_DBG("\tWiggle-flip programming successful."); - + // ========================================================================== // Append Wiggle-Flip programs to .rings section. @@ -398,8 +462,9 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, wfInline, wfInlineLenInWords); if (rcLoc) { - FAPI_ERR("ERROR : write_wiggle_flip_to_image() failed w/rcLoc=%i",rcLoc); - if (deltaRingDxed) free(deltaRingDxed); + FAPI_ERR("write_wiggle_flip_to_image() failed w/rcLoc=%i",rcLoc); + //if (deltaRingDxed) free(deltaRingDxed); + if (buf2) free(buf2); if (wfInline) free(wfInline); if (rcLoc==IMGBUILD_ERR_IMAGE_TOO_LARGE) { uint32_t & DATA_IMG_SIZE_OLD=sizeImageOld; @@ -414,7 +479,7 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, return rc; } FAPI_DBG("\tUpdating image w/wiggle-flip program + header was successful."); - + // Update some variables for debugging and error reporting. sizeImageOld = sizeImageTmp; countWF++; @@ -423,28 +488,47 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, // ========================================================================== // Clean up // ========================================================================== - if (deltaRingDxed) free(deltaRingDxed); - if (wfInline) free(wfInline); - - + //if (deltaRingDxed) free(deltaRingDxed); + // 2012-11-14: CMO- Do NOT free buf1 or buf2 here! They are used in xip_customize(). + // And once these buffers are actually passed as parms to slw_build, + // stop freeing them inside slw_build!!!!!!!! + // ========================================================================== // Are we done? // ========================================================================== if (rcSearch==DSLWB_RING_SEARCH_EXHAUST_MATCH) { -#ifdef IMGBUILD_PPD_ADD_REPR_RINGS - // Add repair rings. - rc = p8_xip_customize( i_target, - i_imageOut, - sizeImageOld, - sysPhase, - NULL, - sizeImageoutMax); - // TBD. Need to check RC. -#endif FAPI_INF("Wiggle-flip programming done."); FAPI_INF("Number of wf programs appended: %i", countWF); if (countWF==0) FAPI_INF("ZERO WF programs appended to .rings section."); +#ifndef IMGBUILD_PPD_IGNORE_XIPC + // Do various customizations to image. + if (!buf1 || !buf2) { + FAPI_ERR("The [assumed] pre-allocated ring buffers, buf1/2, do not exist.\n"); + uint32_t & RC_LOCAL = rcTmp; + FAPI_SET_HWP_ERROR(rc, RC_PROC_SLWB_MEMORY_ERROR); + return rc; + } + sizeImageTmp = sizeImageOutMax; + FAPI_INF("Calling xip_customize().\n"); + FAPI_EXEC_HWP(rc, p8_xip_customize, + i_target, + i_imageOut, // This is both in and out image for xip_customize. + NULL, // No need to pass a separate out image + sizeImageTmp, + sysPhase, + buf1, + sizeBuf1, + buf2, + sizeBuf2); + free(buf1); + free(buf2); + if (rc!=FAPI_RC_SUCCESS) { + FAPI_ERR("Xip customization failed."); + return rc; + } + FAPI_INF("Xip customization done."); +#endif sizeImageTmp = sizeImageOutMax; // Initialize .slw section with PORE table. rcLoc = initialize_slw_section( i_imageOut, @@ -473,17 +557,19 @@ ReturnCode p8_slw_build( const fapi::Target &i_target, // Report final size. sbe_xip_image_size( i_imageOut, io_sizeImageOut); FAPI_INF("Final SLW image size: %i", *io_sizeImageOut); + if (buf1) free(buf1); + if (buf2) free(buf2); return FAPI_RC_SUCCESS; } FAPI_DBG("nextRing (at bottom)=0x%016llx",(uint64_t)nextRing); - + } while (nextRing!=NULL); /*************************************************************************** * SEARCH LOOP - End * ***************************************************************************/ - FAPI_ERR("ERROR : Shouldn't be in this code section. Check code."); + FAPI_ERR("Shouldn't be in this code section. Check code."); rcLoc = IMGBUILD_ERR_CHECK_CODE; uint32_t & RC_LOCAL=rcLoc; FAPI_SET_HWP_ERROR(rc, RC_PROC_SLWB_UNKNOWN_ERROR); diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_slw_build_errors.xml b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_slw_build_errors.xml index 0931f22bd..df9487970 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_slw_build_errors.xml +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_slw_build_errors.xml @@ -117,4 +117,10 @@ <description>Unknown error. (Shouldn't be in this code section.)</description> <ffdc>RC_LOCAL</ffdc> </hwpError> + <!-- *********************************************************************** --> + <hwpError> + <rc>RC_PROC_SLWB_MEMORY_ERROR</rc> + <description>Memory allocation error.</description> + <ffdc>RC_LOCAL</ffdc> + </hwpError> </hwpErrors> diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize.C b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize.C new file mode 100644 index 000000000..7187efe45 --- /dev/null +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize.C @@ -0,0 +1,478 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* 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. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: p8_xip_customize.C,v 1.12 2012/12/07 18:22:32 cmolsen Exp $ +/*------------------------------------------------------------------------------*/ +/* *! TITLE : p8_xip_customize */ +/* *! DESCRIPTION : Obtains repair rings from VPD and adds them to either */ +// IPL or SLW mainstore images. +/* *! OWNER NAME : Michael Olsen cmolsen@us.ibm.com */ +// +/* *! EXTENDED DESCRIPTION : */ +// +/* *! USAGE : To build (for Hostboot) - */ +// buildfapiprcd -c "sbe_xip_image.c,pore_inline_assembler.c,p8_ring_identification.c" -C "p8_image_help.C" -e "$PROC_PATH/../../xml/error_info/p8_xip_customize_errors.xml,../../../../../../hwpf/hwp/xml/attribute_info/chip_attributes.xml,../../../../../../hwpf/hwp/xml/error_info/mvpd_errors.xml" p8_xip_customize.C +// To build (for VBU/command-line) - assuming getMvpdRing_x86.so already exist. +// buildfapiprcd -r ver-13-0 -c "sbe_xip_image.c,pore_inline_assembler.c,p8_ring_identification.c" -C "p8_image_help.C" -e "../../xml/error_info/p8_xip_customize_errors.xml,../../../../../../hwpf/hwp/xml/attribute_info/chip_attributes.xml,../../../../../../hwpf/hwp/xml/error_info/mvpd_errors.xml" -u "XIPC_COMMAND_LINE" p8_xip_customize.C +// To build (for VBU/command-line) - incorporating getMvpdRing etc into build: +// (NB! Not recommended - it's a mess - the following is incoomplete) +// buildfapiprcd -r ver-13-0 -c "sbe_xip_image.c,pore_inline_assembler.c,p8_ring_identification.c" -C "p8_image_help.C,getMvpdRing.C" -e "../../xml/error_info/p8_xip_customize_errors.xml,../../../../../../hwpf/hwp/xml/error_info/mvpd_errors.xml,../../../../../../hwpf/hwp/xml/attribute_info/chip_attributes.xml,../../../../../../hwpf/hwp/xml/error_info/mvpd_errors.xml" -u "XIPC_COMMAND_LINE" p8_xip_customize.C +// Other usages - +// using "IMGBUILD_PPD_IGNORE_VPD" will ignore adding MVPD rings. +// using "IMGBUILD_PPD_IGNORE_VPD_FIELD" will ignore using fapiGetMvpdField. +// using "IMGBUILD_PPD_IGNORE_PLL_UPDATE" will ignore PLL attribute ring. +// +/* *! ASSUMPTIONS : */ +// +/* *! COMMENTS : */ +// +/*------------------------------------------------------------------------------*/ +// The IMGBUILD_PPD_IGNORE_PLL_UPDATE macro is defined to temporarily disable +// the call usage of attributes which are not yet supported. +// @Todo: RTC 60670 will remove the macro when the attributes are supported. +#define IMGBUILD_PPD_IGNORE_PLL_UPDATE + +#include <p8_pore_api_custom.h> +#include <HvPlicModule.H> +#include <getMvpdRing.H> +#include <fapiMvpdAccess.H> +#include <p8_xip_customize.H> +#include <p8_delta_scan_rw.h> +#include <p8_ring_identification.H> + +extern "C" { + +using namespace fapi; + +// Parameter list: +// const fapi::Target &i_target: Processor chip target. +// void *i_imageIn: Ptr to input IPL or input/output SLW image. +// void *i_imageOut: Ptr to output IPL img. (Ignored for SLW/RAM imgs.) +// uint32_t io_sizeImageOut: In: Max size of IPL/SRAM img. Out: Final size. +// uint8_t i_sysPhase: 0: IPL 1: SLW +// void *i_buf1: Temp buffer 1 for dexed RS4 ring. Caller allocs/frees. +// uint32_t i_sizeBuf1: Size of buf1. +// void *i_buf2: Temp buffer 2 for WF ring. Caller allocs/frees. +// uint32_t i_sizeBuf22 Size of buf2. +// +ReturnCode p8_xip_customize( const fapi::Target &i_target, + void *i_imageIn, + void *i_imageOut, + uint32_t &io_sizeImageOut, + const uint8_t i_sysPhase, + void *i_buf1, + const uint32_t i_sizeBuf1, + void *i_buf2, + const uint32_t i_sizeBuf2 ) +{ + fapi::ReturnCode rcFapi, rc=FAPI_RC_SUCCESS; + uint32_t rcLoc=0; + void *imageOut; + uint32_t sizeImage, sizeImageIn, sizeImageOut, sizeImageOutMax; + + SBE_XIP_ERROR_STRINGS(errorStrings); + + sizeImageOutMax = io_sizeImageOut; + + // ========================================================================== + // Check and copy (if IPL phase) image to mainstore and clean it up. + // ========================================================================== + // + // First, check supplied size and validation of input EPROM image. + // + sbe_xip_image_size((void*)i_imageIn, &sizeImageIn); + rcLoc = sbe_xip_validate((void*)i_imageIn, sizeImageIn); + if (rcLoc) { + FAPI_ERR("xip_validate() failed w/rcLoc=%i",rcLoc); + uint32_t & RC_LOCAL = rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_INTERNAL_IMAGE_ERR); + return rc; + } + + // Second, if IPL phase, copy input image to supplied mainstore location. + // + if (i_sysPhase==0) { + imageOut = (void*)i_imageOut; + memcpy( imageOut, i_imageIn, sizeImageIn); + sbe_xip_image_size(imageOut, &sizeImage); + rcLoc = sbe_xip_validate(imageOut, sizeImage); + if (rcLoc) { + FAPI_ERR("xip_validate() failed w/rcLoc=%i",rcLoc); + uint32_t & RC_LOCAL=rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_MS_INTERNAL_IMAGE_ERR); + return rc; + } + if (sizeImage!=sizeImageIn) { + FAPI_ERR("Size obtained from image's header (=%i) differs from supplied size (=%i).", + sizeImage,sizeImageIn); + uint32_t & DATA_IMG_SIZE_INP = sizeImageIn; + uint32_t & DATA_IMG_SIZE = sizeImage; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_MS_IMAGE_SIZE_MISMATCH); + return rc; + } + } + else // Output image is same as input image in SLW case (even for an SRAM build). + imageOut = (void*)i_imageIn; + + // Customization defines. + // + uint32_t iVec=0; + uint64_t attrCombGoodVec[MAX_CHIPLETS]={ (uint64_t(0xfedcba98)<<32)+0x76543210 }; + void *hostCombGoodVec; + SbeXipItem xipTocItem; + + // -------------------------------------------------------------------------- + // CUSTOMIZE item: Combined good vectors update. + // Retrieval method: Attribute. + // System phase: IPL and SLW sysPhase. + // Note: The 32 vectors are listed in order from chiplet 0x00 to 0x1f. + // Note: We will use the content of these vectors to determine if each + // chiplet is functional. This is to avoid the messy "walking the + // chiplets approach" using fapiGetChildChiplets(). + // -------------------------------------------------------------------------- + + rc = FAPI_ATTR_GET(ATTR_CHIP_REGIONS_TO_ENABLE, &i_target, attrCombGoodVec); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_CHIP_REGIONS_TO_ENABLE) returned error.\n"); + return rc; + } + rcLoc = sbe_xip_find( imageOut, COMBINED_GOOD_VECTORS_TOC_NAME, &xipTocItem); + if (rcLoc) { + FAPI_ERR("sbe_xip_find() failed w/rc=%i and %s", rcLoc, SBE_XIP_ERROR_STRING(errorStrings, rcLoc)); + FAPI_ERR("Probable cause:"); + FAPI_ERR("\tThe keyword (=%s) was not found.",COMBINED_GOOD_VECTORS_TOC_NAME); + uint32_t & RC_LOCAL = rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_KEYWORD_NOT_FOUND_ERROR); + return rc; + } + sbe_xip_pore2host( imageOut, xipTocItem.iv_address, &hostCombGoodVec); + FAPI_DBG("Dumping [initial] global variable content of combined_good_vectors, then the updated value:\n"); + for (iVec=0; iVec<MAX_CHIPLETS; iVec++) { + FAPI_INF("combined_good_vectors[%2i]: Before=0x%16llX",iVec,*((uint64_t*)hostCombGoodVec+iVec)); + *((uint64_t*)hostCombGoodVec+iVec) = myRev64(attrCombGoodVec[iVec]); + FAPI_INF(" After=0x%16llX\n",*((uint64_t*)hostCombGoodVec+iVec)); + } + +#ifndef IMGBUILD_PPD_IGNORE_VPD_FIELD + void *hostPibmemRepairVec, *hostNestSkewAdjVec; + uint8_t *bufVpdField; + uint32_t sizeVpdField=0; + // -------------------------------------------------------------------------- + // CUSTOMIZE item: Update 20 swizzled bits for PIB repair vector. + // Retrieval method: MVPD field. + // System phase: IPL sysPhase. + // -------------------------------------------------------------------------- + if (i_sysPhase==0) { + bufVpdField = (uint8_t*)i_buf1; + sizeVpdField = i_sizeBuf1; // We have to use fixed and max size buffer. + FAPI_EXEC_HWP(rcFapi, fapiGetMvpdField, + MVPD_RECORD_CP00, + MVPD_KEYWORD_PB, // Use _PR temporarily. Should be _PB. + i_target, + bufVpdField, + sizeVpdField); + if (rcFapi) { + FAPI_ERR("fapiGetMvpdField() w/keyword=PB returned error."); + return rcFapi; + } + rcLoc = sbe_xip_find( imageOut, PERV_PIB_REPR_VECTOR_TOC_NAME, &xipTocItem); + if (rcLoc) { + FAPI_ERR("sbe_xip_find() failed w/rc=%i and %s", rcLoc, SBE_XIP_ERROR_STRING(errorStrings, rcLoc)); + FAPI_ERR("Probable cause:"); + FAPI_ERR("\tThe keyword (=%s) was not found.",PERV_PIB_REPR_VECTOR_TOC_NAME); + uint32_t & RC_LOCAL = rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_KEYWORD_NOT_FOUND_ERROR); + return rc; + } + if (sizeVpdField!=4) { + FAPI_ERR("fapiGetMvpdField() w/keyword=PB returned sizeVpdField=%i but expected size=4.",sizeVpdField); + uint32_t & DATA_SIZE_VPD_FIELD = sizeVpdField; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_UNEXPECTED_FIELD_SIZE); + return rc; + } + FAPI_DBG("Dumping global variable content of pibmem_repair_vector:\n"); + sbe_xip_pore2host( imageOut, xipTocItem.iv_address, &hostPibmemRepairVec); + FAPI_INF("pibmem_repair_vector:Before=0x%16llX\n",*((uint64_t*)hostPibmemRepairVec)); + *(uint64_t*)hostPibmemRepairVec = myRev64(((uint64_t)(*(uint32_t*)bufVpdField))<<32); + FAPI_INF(" After=0x%16llX\n",*((uint64_t*)hostPibmemRepairVec)); + } + + // -------------------------------------------------------------------------- + // CUSTOMIZE item: Update nest skewadjust vector. + // Retrieval method: MVPD field. + // System phase: IPL sysPhase. + // -------------------------------------------------------------------------- + if (i_sysPhase==0) { + bufVpdField = (uint8_t*)i_buf1; + sizeVpdField = i_sizeBuf1; // We have to use fixed and max size buffer. + FAPI_EXEC_HWP(rcFapi, fapiGetMvpdField, + MVPD_RECORD_CP00, + MVPD_KEYWORD_MK, // Use _PR temporarily. Should be _MK. + i_target, + bufVpdField, + sizeVpdField); + if (rcFapi) { + FAPI_ERR("fapiGetMvpdField() w/keyword=MK returned error."); + return rcFapi; + } + rcLoc = sbe_xip_find( imageOut, NEST_SKEWADJUST_VECTOR_TOC_NAME, &xipTocItem); + if (rcLoc) { + FAPI_ERR("sbe_xip_find() failed w/rc=%i and %s", rcLoc, SBE_XIP_ERROR_STRING(errorStrings, rcLoc)); + FAPI_ERR("Probable cause:"); + FAPI_ERR("\tThe keyword (=%s) was not found.",NEST_SKEWADJUST_VECTOR_TOC_NAME); + uint32_t & RC_LOCAL = rcLoc; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_KEYWORD_NOT_FOUND_ERROR); + return rc; + } + if (sizeVpdField!=4) { + FAPI_ERR("fapiGetMvpdField() w/keyword=MK returned sizeVpdField=%i but expected size=4.",sizeVpdField); + uint32_t & DATA_SIZE_VPD_FIELD = sizeVpdField; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_UNEXPECTED_FIELD_SIZE); + return rc; + } + FAPI_DBG("Dumping global variable content of nest_skewadjust_vector:\n"); + sbe_xip_pore2host( imageOut, xipTocItem.iv_address, &hostNestSkewAdjVec); + FAPI_INF("nest_skewadjust_vector: Before=0x%16llX\n",*((uint64_t*)hostNestSkewAdjVec)); + *(uint64_t*)hostNestSkewAdjVec = myRev64(((uint64_t)(*(uint32_t*)bufVpdField))<<32); + FAPI_INF(" After=0x%16llX\n",*((uint64_t*)hostNestSkewAdjVec)); + } +#endif + + // -------------------------------------------------------------------------- + // CUSTOMIZE item: Update PLL ring (perv_bndy_pll_ring). + // Retrieval method: Attribute. + // System phase: IPL sysPhase. + // -------------------------------------------------------------------------- +#ifndef IMGBUILD_PPD_IGNORE_PLL_UPDATE +#define MAX_PLL_RING_SIZE 256 + uint8_t attrRingData[MAX_PLL_RING_SIZE] = { 0 }; + uint32_t attrRingDataSize=0; + if (i_sysPhase==0) { + rc = FAPI_ATTR_GET(ATTR_RING_DATA_SIZE, $i_target, attrRingDataSize); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_RING_DATA_SIZE) returned error.\n"); + return rc; + } + if (attrRingDataSize>MAX_PLL_RING_SIZE) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_RING_DATA_SIZE) returned ring size=%i > max pll ring size=%i bytes.\n", + attrRingDataSize,MAX_PLL_RING_SIZE); + return rc; + } + rc = FAPI_ATTR_GET(ATTR_RING_DATA, &i_target, attrRingData); + if (rc) { + FAPI_ERR("FAPI_ATTR_GET(ATTR_RING_DATA) returned error.\n"); + return rc; + } + } + // Check that this is final "xor'ed" ring state, so I can proceed directly to RS4 compression. +#endif + + // -------------------------------------------------------------------------- + // CUSTOMIZE item: Add #G and #R rings. + // Applies to both sysPhase modes: IPL and SLW. + // For SLW, only update ex_ chiplet rings. + // -------------------------------------------------------------------------- + + /*************************************************************************** + * CHIPLET WALK LOOP - Begin * + ***************************************************************************/ + // + // Walk through #G rings first, then #R rings. + // iVpdType=0 : #G Repair rings + // iVpdType=1 : #R Repair rings + // Notes about VPD rings: + // - Only space for the base ring is allocated in the TOC. No override space! + // - Some ex_ rings are non-core-ID-specific and will have chipletID=0xFF. + // Add these rings only once!! + // Notes about #G rings: + // - Some ex_ rings are core ID specific. Add the fwd ptr based on the core ID. + // Notes about $R rings: + // - The ex_ rings are core ID specific. Add the fwd ptr based on the core ID. + // + uint8_t iVpdType; + RingIdList *ring_id_list=NULL; + uint32_t ring_id_list_size; + + for (iVpdType=0; iVpdType<NUM_OF_VPD_TYPES; iVpdType++) { + if (iVpdType==0) { + ring_id_list = (RingIdList*)RING_ID_LIST_PG; + ring_id_list_size = (uint32_t)RING_ID_LIST_PG_SIZE; + } + else { + ring_id_list = (RingIdList*)RING_ID_LIST_PR; + ring_id_list_size = (uint32_t)RING_ID_LIST_PR_SIZE; + } +#ifndef IMGBUILD_PPD_IGNORE_VPD + uint32_t iRing; + uint32_t sizeVpdRing=0; + uint8_t chipletId, ringId; + uint8_t *bufVpdRing; + uint32_t ddLevel=0xFFFFFFFF; + uint8_t bValidChipletId=0,bRingAlreadyAdded=0; + uint8_t chipletIdVpd; + + for (iRing=0; iRing<ring_id_list_size; iRing++) { + ringId = (ring_id_list+iRing)->ringId; + bRingAlreadyAdded = 0; + for ( chipletId=(ring_id_list+iRing)->chipIdMin; + (chipletId>=(ring_id_list+iRing)->chipIdMin && chipletId<=(ring_id_list+iRing)->chipIdMax); + chipletId++) { + FAPI_INF("(iRing,chipletId) = (%2i,0x%02x)",iRing,chipletId); + bValidChipletId = 0; + if (chipletId>=CHIPLET_ID_MIN && chipletId<=CHIPLET_ID_MAX) { + // Using known_good_vectors data to determine of a chiplet is functional. + if (attrCombGoodVec[chipletId]) + bValidChipletId = 1; + else + bValidChipletId = 0; + } + else { + if (chipletId==0xFF) + bValidChipletId = 1; + else { + bValidChipletId = 0; + FAPI_INF("chipletId=0x%02x is not a valid chiplet ID. Check chiplet ID range in p8_ring_identification.c.",chipletId); + } + } + if (bValidChipletId) { + bufVpdRing = (uint8_t*)i_buf1; + sizeVpdRing = i_sizeBuf1; // We always supply max buffer space for ring. + // 2012-11-14: CMO- A thought: Once getMvpdRing() becomes available, add + // get_mvpd_keyword() func at bottom in this file. Then + // put prototype in *.H file. The func should map the + // vpd keyword (0,1,2,...) to mvpd keyword in the include + // file, fapiMvpdAccess.H. + //rcFapi = get_mvpd_keyword((ring_id_list+iRing)->vpdKeyword, mvpdKeyword); + //if (rcFapi) { + // FAPI_ERR("get_mvpd_keyword() returned error."); + // return rcFapi; + //} + fapi::MvpdKeyword mvpd_keyword; + if ((ring_id_list+iRing)->vpdKeyword==VPD_KEYWORD_PDG) + mvpd_keyword = MVPD_KEYWORD_PDG; + else + if ((ring_id_list+iRing)->vpdKeyword==VPD_KEYWORD_PDR) + mvpd_keyword = MVPD_KEYWORD_PDR; + else { + FAPI_ERR("Unable to resolve VPD keyword from ring list table."); + uint8_t & DATA_RING_LIST_VPD_KEYWORD = (ring_id_list+iRing)->vpdKeyword; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_VPD_KEYWORD_RESOLVE_ERROR); + return rc; + } + FAPI_EXEC_HWP(rcFapi, getMvpdRing, + MVPD_RECORD_CP00, + mvpd_keyword, + i_target, + chipletId, + ringId, + bufVpdRing, + sizeVpdRing); + if (rcFapi!=FAPI_RC_SUCCESS && rcFapi!=RC_REPAIR_RING_NOT_FOUND) { + FAPI_ERR("getMvpdRing() returned error."); + return rcFapi; + } + chipletIdVpd = ((CompressedScanData*)bufVpdRing)->iv_chipletId; + if (chipletIdVpd!=chipletId && chipletIdVpd!=0xFF) { + FAPI_ERR("VPD ring's chipletId in scan container (=0x%02X) is not equal to 0xFF nor does it match the requested chipletId (=0x%02X).\n",chipletIdVpd,chipletId); + uint8_t & DATA_CHIPLET_ID_VPD = chipletIdVpd; + uint8_t & DATA_CHIPLET_ID_REQ = chipletId; + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_CHIPLET_ID_MESS); + return rc; + } + //if (sizeVpdRing==0) { + if (rcFapi==RC_REPAIR_RING_NOT_FOUND) { + // No match, do nothing. Next (chipletId,ringId)-pair. + } + else { + if (sizeVpdRing>i_sizeBuf1) { + // Supplied buffer from HB/PHYP is too small. Error out. Is this right + // decision or should we ignore and proceed to next ring. + uint32_t sizeBuf1=(uint32_t)i_sizeBuf1; + uint32_t & DATA_RING_SIZE_REQ = sizeVpdRing; + uint32_t & DATA_RING_SIZE_MAX = sizeBuf1; + switch (iVpdType) { + case 0: + FAPI_ERR("#G ring too large."); + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PG_RING_TOO_LARGE); + break; + case 1: + FAPI_ERR("#R ring too large."); + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_PR_RING_TOO_LARGE); + break; + default: + uint8_t & DATA_VPD_TYPE = iVpdType; + FAPI_ERR("#Invalid VPD type."); + FAPI_SET_HWP_ERROR(rc, RC_PROC_XIPC_INVALID_VPD_TYPE); + break; + } + return rc; + } + else { + // Add VPD ring to image. + if (!bRingAlreadyAdded) { + sizeImageOut = sizeImageOutMax; + if (i_sysPhase==0) { + // Add VPD ring to --->>> IPL <<<--- image + rcLoc = write_vpd_ring_to_ipl_image( + imageOut, + sizeImageOut, + (CompressedScanData*)bufVpdRing, //i_buf1 + ddLevel, + i_sysPhase, + (char*)((ring_id_list+iRing)->ringNameImg), + (void*)i_buf2, + i_sizeBuf2); + //CMO: How do we return a more informative rc, say one that indicates + // successful img build but no rings found? + } + else { + // Add VPD ring to --->>> SLW <<<--- image + rcLoc = write_vpd_ring_to_ipl_image( + imageOut, + sizeImageOut, + (CompressedScanData*)bufVpdRing, //i_buf1 + ddLevel, + i_sysPhase, + (char*)(ring_id_list+iRing)->ringNameImg, + (void*)i_buf2, + i_sizeBuf2); + } + if (chipletIdVpd==0xFF) + bRingAlreadyAdded = 1; + } + } + } + } + } + } +#endif + } + + i_imageOut = imageOut; + io_sizeImageOut = sizeImageOut; + + return FAPI_RC_SUCCESS; + +} + + +} // End of extern C diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize.H b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize.H new file mode 100644 index 000000000..780513b27 --- /dev/null +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize.H @@ -0,0 +1,74 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* 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. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +// $Id: p8_xip_customize.H,v 1.5 2012/12/07 18:23:01 cmolsen Exp $ + +#include <fapi.H> + +typedef fapi::ReturnCode (*fapiGetMvpdField_FP_t) ( const fapi::MvpdRecord i_record, + const fapi::MvpdKeyword i_keyword, + const fapi::Target &i_procTarget, + uint8_t * const i_pBuffer, + uint32_t &io_fieldSize); + +typedef fapi::ReturnCode (*p8_xip_customize_FP_t) ( const fapi::Target&, + void*, + void*, + uint32_t&, + const uint8_t, + void*, + const uint32_t, + void*, + const uint32_t ); + +extern "C" +{ + +// +// Function declares. +// + + // Description: + // FAPI HWP entry point for p8_xip_customize(). + // proc_xip_customize() adds VPD rings to the IPL and SLW images and updates + // various vectors in the images. + // + // Parameters: + // fapi::Target &i_target: Processor chip target. + // void *i_imageIn: Ptr to input IPL or SLW image. + // void *i_imageOut: Ptr to output IPL img. (Ignored for SLW/RAM imgs.) + // uint32_t &io_sizeImageOut: In: Max size of IPL/SRAM img. Out: Final size. + // uint8_t i_sysPhase: 0: IPL 1: SLW + // void *i_buf1: Temp buffer1 for dexed RS4 ring. Caller allocs/frees. + // uint32_t i_sizeBuf1: Size of buf1. + // void *i_buf2: Temp buffer2 for WF ring. Caller allocs/frees. + // uint32_t i_sizeBuf22 Size of buf2. + fapi::ReturnCode p8_xip_customize( const fapi::Target &i_target, + void *i_imageIn, + void *i_imageOut, + uint32_t &io_sizeImageOut, + const uint8_t i_sysPhase, + void *i_buf1, + const uint32_t i_sizeBuf1, + void *i_buf2, + const uint32_t i_sizeBuf2 ); +} diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize_attributes.xml b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize_attributes.xml new file mode 100644 index 000000000..a8d1c13ec --- /dev/null +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize_attributes.xml @@ -0,0 +1,245 @@ +<!-- IBM_PROLOG_BEGIN_TAG --> +<!-- This is an automatically generated prolog. --> +<!-- --> +<!-- $Source: src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize_attributes.xml $ --> +<!-- --> +<!-- IBM CONFIDENTIAL --> +<!-- --> +<!-- COPYRIGHT International Business Machines Corp. 2012 --> +<!-- --> +<!-- p1 --> +<!-- --> +<!-- Object Code Only (OCO) source materials --> +<!-- Licensed Internal Code Source Materials --> +<!-- IBM HostBoot Licensed Internal Code --> +<!-- --> +<!-- 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. --> +<!-- --> +<!-- Origin: 30 --> +<!-- --> +<!-- IBM_PROLOG_END_TAG --> +<!-- p8_xip_customize_attributes.xml --> +<attributes> + <!-- ********************************************************************* --> + <attribute> + <id>ATTR_PROC_NX_ENABLE</id> + <targetType>TARGET_TYPE_PROC_CHIP</targetType> + <description>NX partial good control + creator: platform + firmware notes: + must track ATTR_CHIP_REGIONS_TO_ENABLE + </description> + <valueType>uint8</valueType> + <enum>DISABLE = 0x0, ENABLE = 0x1</enum> + <platInit/> + <persistRuntime/> + </attribute> + <!-- ********************************************************************* --> + <attribute> + <id>ATTR_PROC_PCIE_ENABLE</id> + <targetType>TARGET_TYPE_PROC_CHIP</targetType> + <description>PCIE partial good control + creator: platform + firmware notes: + must track ATTR_CHIP_REGIONS_TO_ENABLE + </description> + <valueType>uint8</valueType> + <enum>DISABLE = 0x0, ENABLE = 0x1</enum> + <platInit/> + <persistRuntime/> + </attribute> + <!-- ********************************************************************* --> + <attribute> + <id>ATTR_PROC_L3_ENABLE</id> + <targetType>TARGET_TYPE_EX_CHIPLET</targetType> + <description>L3 partial good control + creator: platform + firmware notes: + must track ATTR_CHIP_REGIONS_TO_ENABLE + </description> + <valueType>uint8</valueType> + <enum>DISABLE = 0x0, ENABLE = 0x1</enum> + <platInit/> + <persistRuntime/> + </attribute> + <!-- ********************************************************************* --> + <attribute> + <id>ATTR_PROC_ADU_UNTRUSTED_BAR_BASE_ADDR</id> + <targetType>TARGET_TYPE_PROC_CHIP</targetType> + <description>ADU Untrusted BAR base address (secure mode) + creator: platform + firmware notes: + 64-bit address representing BAR RA + </description> + <valueType>uint64</valueType> + <platInit/> + <persistRuntime/> + </attribute> + <!-- ********************************************************************* --> + <attribute> + <id>ATTR_PROC_ADU_UNTRUSTED_BAR_SIZE</id> + <targetType>TARGET_TYPE_PROC_CHIP</targetType> + <description>ADU Untrusted BAR size (secure mode) + creator: platform + firmware notes: + mask applied to RA 14:43 + </description> + <valueType>uint64</valueType> + <enum> + 1_PB = 0x0000000000000000, + 512_TB = 0x0002000000000000, + 256_TB = 0x0003000000000000, + 128_TB = 0x0003800000000000, + 64_TB = 0x0003C00000000000, + 32_TB = 0x0003E00000000000, + 16_TB = 0x0003F00000000000, + 8_TB = 0x0003F80000000000, + 4_TB = 0x0003FC0000000000, + 2_TB = 0x0003FE0000000000, + 1_TB = 0x0003FF0000000000, + 512_GB = 0x0003FF8000000000, + 256_GB = 0x0003FFC000000000, + 128_GB = 0x0003FFE000000000, + 64_GB = 0x0003FFF000000000, + 32_GB = 0x0003FFF800000000, + 16_GB = 0x0003FFFC00000000, + 8_GB = 0x0003FFFE00000000, + 4_GB = 0x0003FFFF00000000, + 2_GB = 0x0003FFFF80000000, + 1_GB = 0x0003FFFFC0000000, + 512_MB = 0x0003FFFFE0000000, + 256_MB = 0x0003FFFFF0000000, + 128_MB = 0x0003FFFFF8000000, + 64_MB = 0x0003FFFFFC000000, + 32_MB = 0x0003FFFFFE000000, + 16_MB = 0x0003FFFFFF000000, + 8_MB = 0x0003FFFFFF800000, + 4_MB = 0x0003FFFFFFC00000, + 2_MB = 0x0003FFFFFFE00000, + 1_MB = 0x0003FFFFFFF00000 + </enum> + <platInit/> + <persistRuntime/> + </attribute> + <!-- ********************************************************************* --> + <attribute> + <id>ATTR_PROC_PSI_UNTRUSTED_BAR0_BASE_ADDR</id> + <targetType>TARGET_TYPE_PROC_CHIP</targetType> + <description>PSI Untrusted BAR0 base address (secure mode) + creator: platform + firmware notes: + 64-bit address representing BAR RA + </description> + <valueType>uint64</valueType> + <platInit/> + <persistRuntime/> + </attribute> + <!-- ********************************************************************* --> + <attribute> + <id>ATTR_PROC_PSI_UNTRUSTED_BAR0_SIZE</id> + <targetType>TARGET_TYPE_PROC_CHIP</targetType> + <description>PSI Untrusted BAR0 size (secure mode) + creator: platform + firmware notes: + mask applied to RA 14:43 + </description> + <valueType>uint64</valueType> + <enum> + 1_PB = 0x0000000000000000, + 512_TB = 0x0002000000000000, + 256_TB = 0x0003000000000000, + 128_TB = 0x0003800000000000, + 64_TB = 0x0003C00000000000, + 32_TB = 0x0003E00000000000, + 16_TB = 0x0003F00000000000, + 8_TB = 0x0003F80000000000, + 4_TB = 0x0003FC0000000000, + 2_TB = 0x0003FE0000000000, + 1_TB = 0x0003FF0000000000, + 512_GB = 0x0003FF8000000000, + 256_GB = 0x0003FFC000000000, + 128_GB = 0x0003FFE000000000, + 64_GB = 0x0003FFF000000000, + 32_GB = 0x0003FFF800000000, + 16_GB = 0x0003FFFC00000000, + 8_GB = 0x0003FFFE00000000, + 4_GB = 0x0003FFFF00000000, + 2_GB = 0x0003FFFF80000000, + 1_GB = 0x0003FFFFC0000000, + 512_MB = 0x0003FFFFE0000000, + 256_MB = 0x0003FFFFF0000000, + 128_MB = 0x0003FFFFF8000000, + 64_MB = 0x0003FFFFFC000000, + 32_MB = 0x0003FFFFFE000000, + 16_MB = 0x0003FFFFFF000000, + 8_MB = 0x0003FFFFFF800000, + 4_MB = 0x0003FFFFFFC00000, + 2_MB = 0x0003FFFFFFE00000, + 1_MB = 0x0003FFFFFFF00000 + </enum> + <platInit/> + <persistRuntime/> + </attribute> + <!-- ********************************************************************* --> + <attribute> + <id>ATTR_PROC_PSI_UNTRUSTED_BAR1_BASE_ADDR</id> + <targetType>TARGET_TYPE_PROC_CHIP</targetType> + <description>PSI Untrusted BAR1 base address (secure mode) + creator: platform + firmware notes: + 64-bit address representing BAR RA + </description> + <valueType>uint64</valueType> + <platInit/> + <persistRuntime/> + </attribute> + <!-- ********************************************************************* --> + <attribute> + <id>ATTR_PROC_PSI_UNTRUSTED_BAR1_SIZE</id> + <targetType>TARGET_TYPE_PROC_CHIP</targetType> + <description>PSI Untrusted BAR1 size (secure mode) + creator: platform + firmware notes: + mask applied to RA 14:43 + </description> + <valueType>uint64</valueType> + <enum> + 1_PB = 0x0000000000000000, + 512_TB = 0x0002000000000000, + 256_TB = 0x0003000000000000, + 128_TB = 0x0003800000000000, + 64_TB = 0x0003C00000000000, + 32_TB = 0x0003E00000000000, + 16_TB = 0x0003F00000000000, + 8_TB = 0x0003F80000000000, + 4_TB = 0x0003FC0000000000, + 2_TB = 0x0003FE0000000000, + 1_TB = 0x0003FF0000000000, + 512_GB = 0x0003FF8000000000, + 256_GB = 0x0003FFC000000000, + 128_GB = 0x0003FFE000000000, + 64_GB = 0x0003FFF000000000, + 32_GB = 0x0003FFF800000000, + 16_GB = 0x0003FFFC00000000, + 8_GB = 0x0003FFFE00000000, + 4_GB = 0x0003FFFF00000000, + 2_GB = 0x0003FFFF80000000, + 1_GB = 0x0003FFFFC0000000, + 512_MB = 0x0003FFFFE0000000, + 256_MB = 0x0003FFFFF0000000, + 128_MB = 0x0003FFFFF8000000, + 64_MB = 0x0003FFFFFC000000, + 32_MB = 0x0003FFFFFE000000, + 16_MB = 0x0003FFFFFF000000, + 8_MB = 0x0003FFFFFF800000, + 4_MB = 0x0003FFFFFFC00000, + 2_MB = 0x0003FFFFFFE00000, + 1_MB = 0x0003FFFFFFF00000 + </enum> + <platInit/> + <persistRuntime/> + </attribute> + <!-- ********************************************************************* --> +</attributes> diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize_errors.xml b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize_errors.xml new file mode 100644 index 000000000..6db8a9925 --- /dev/null +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize_errors.xml @@ -0,0 +1,134 @@ +<!-- IBM_PROLOG_BEGIN_TAG --> +<!-- This is an automatically generated prolog. --> +<!-- --> +<!-- $Source: src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_xip_customize_errors.xml $ --> +<!-- --> +<!-- IBM CONFIDENTIAL --> +<!-- --> +<!-- COPYRIGHT International Business Machines Corp. 2012 --> +<!-- --> +<!-- p1 --> +<!-- --> +<!-- Object Code Only (OCO) source materials --> +<!-- Licensed Internal Code Source Materials --> +<!-- IBM HostBoot Licensed Internal Code --> +<!-- --> +<!-- 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. --> +<!-- --> +<!-- Origin: 30 --> +<!-- --> +<!-- IBM_PROLOG_END_TAG --> +<!-- Error definitions for proc_slw_build procedure --> +<hwpErrors> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_INPUT_IMAGE_SIZE_MESS</rc> + <description>Supplied max image size is too small or image too large.</description> + <ffdc>DATA_IMG_SIZE_INP</ffdc> + <ffdc>DATA_IMG_SIZE_MAX</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_INTERNAL_IMAGE_ERR</rc> + <description>Unable to obtain either image size or to validate image.</description> + <ffdc>RC_LOCAL</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_IMAGE_SIZE_MISMATCH</rc> + <description>Supplied image size differs from size in image header.</description> + <ffdc>DATA_IMG_SIZE_INP</ffdc> + <ffdc>DATA_IMG_SIZE</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_MS_INTERNAL_IMAGE_ERR</rc> + <description>Unable to obtain either image size or to validate image in MS.</description> + <ffdc>RC_LOCAL</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_MS_IMAGE_SIZE_MISMATCH</rc> + <description>Supplied image size differs from size in image header in MS.</description> + <ffdc>DATA_IMG_SIZE_INP</ffdc> + <ffdc>DATA_IMG_SIZE</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_IMAGE_UPDATE_ERROR</rc> + <description>Error associated with updating mainstore image.</description> + <ffdc>RC_LOCAL</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_UNEXPECTED_FIELD_SIZE</rc> + <description>Expected field size of 4 bytes. Got something else from fapiGetMvpdField().</description> + <ffdc>DATA_SIZE_VPD_FIELD</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_XIP_FIND_ERROR</rc> + <description>sbe_xip_find() failed w/local rc.</description> + <ffdc>RC_LOCAL</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_RS4_COMPRESS_ERROR</rc> + <description>_rs4_compress() failed w/local rc.</description> + <ffdc>RC_LOCAL</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_RS4_COMPRESS_SIZE_MESS</rc> + <description>Problem with RS4 ring sizes from _rs4_compress().</description> + <ffdc>DATA_SIZE_RS4_COMPRESS_RETURN</ffdc> + <ffdc>DATA_SIZE_RS4_COMPRESS_CONTAINERN</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_CHIPLET_ID_MESS</rc> + <description>VPD ring's chipletId differs from 0xFF and doesn't match requested value either.</description> + <ffdc>DATA_CHIPLET_ID_VPD</ffdc> + <ffdc>DATA_CHIPLET_ID_REQ</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_PG_RING_TOO_LARGE</rc> + <description>Requested #G ring size exceeds max value.</description> + <ffdc>DATA_RING_SIZE_REQ</ffdc> + <ffdc>DATA_RING_SIZE_MAX</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_PR_RING_TOO_LARGE</rc> + <description>Requested #R ring size exceeds max value.</description> + <ffdc>DATA_RING_SIZE_REQ</ffdc> + <ffdc>DATA_RING_SIZE_MAX</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_INVALID_VPD_TYPE</rc> + <description>Invalid VPD type.</description> + <ffdc>DATA_VPD_TYPE</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_KEYWORD_NOT_FOUND_ERROR</rc> + <description>A keyword in the XIP image was not found.</description> + <ffdc>RC_LOCAL</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_VPD_KEYWORD_RESOLVE_ERROR</rc> + <description>Unable to resolve local vpd keyword to fapi-level mvpd keyword.</description> + <ffdc>DATA_RING_LIST_VPD_KEYWORD</ffdc> +</hwpError> +<!-- *********************************************************************** --> +<hwpError> + <rc>RC_PROC_XIPC_UNKNOWN_ERROR</rc> + <description>Unknown error. (Shouldn't be in this code section.)</description> + <ffdc>RC_LOCAL</ffdc> +</hwpError> +</hwpErrors> diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/pore_inline.h b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/pore_inline.h index a8436d69f..50dd6b7f9 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/pore_inline.h +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/pore_inline.h @@ -1,30 +1,29 @@ -/* IBM_PROLOG_BEGIN_TAG - * This is an automatically generated prolog. - * - * $Source: src/usr/hwpf/hwp/build_winkle_images/proc_slw_build/pore_inline.h $ - * - * IBM CONFIDENTIAL - * - * COPYRIGHT International Business Machines Corp. 2012 - * - * p1 - * - * Object Code Only (OCO) source materials - * Licensed Internal Code Source Materials - * IBM HostBoot Licensed Internal Code - * - * The source code for this program is not published or other- - * wise divested of its trade secrets, irrespective of what has - * been deposited with the U.S. Copyright Office. - * - * Origin: 30 - * - * IBM_PROLOG_END_TAG - */ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/pore_inline.h $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* 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. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #ifndef __PORE_INLINE_H__ #define __PORE_INLINE_H__ -// $Id: pore_inline.h,v 1.15 2012/05/23 19:03:42 bcbrock Exp $ +// $Id: pore_inline.h,v 1.16 2012/11/12 19:54:15 bcbrock Exp $ // ** WARNING : This file is maintained as part of the OCC firmware. Do ** // ** not edit this file in the PMX area or the hardware procedure area ** @@ -248,6 +247,18 @@ enum { /// the PoreInlineContext between calls of pore_inline_disassemble(). #define PORE_INLINE_8_BYTE_DATA 0x10 +/// Disassemble unrecognized opcodes as 4-byte data +/// +/// This flag is an option to pore_inline_context_create(). If set, then +/// any putative instruction with an unrecognized opcode will be silently +/// diassembled as 4-byte data. +/// +/// This option was added to allow error-free disassembly of +/// non-parity-protected PORE text sections that contain 0x00000000 alignment +/// padding, and is not guaranteed to produce correct or consistent results in +/// any other case. +#define PORE_INLINE_DISASSEMBLE_UNKNOWN 0x20 + #ifndef __ASSEMBLER__ @@ -409,12 +420,15 @@ typedef struct { /// The data (for data disassembly) /// - /// This is either 1 or 8 bytes in host byte order. + /// This is either 1, 4 or 8 bytes in host byte order. uint64_t data; /// The size of the disassembled \a data field (for data disassembly) size_t data_size; + /// Was this location disassembled as an instruction (0) or as data (1) + int is_data; + } PoreInlineDisassembly; diff --git a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/pore_inline_assembler.c b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/pore_inline_assembler.c index b576f8281..096595a78 100644 --- a/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/pore_inline_assembler.c +++ b/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/pore_inline_assembler.c @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: pore_inline_assembler.c,v 1.14 2012/05/23 19:03:42 bcbrock Exp $ +// $Id: pore_inline_assembler.c,v 1.15 2012/11/12 19:54:15 bcbrock Exp $ // ** WARNING : This file is maintained as part of the OCC firmware. Do ** // ** not edit this file in the PMX area or the hardware procedure area ** @@ -94,8 +94,8 @@ /// \section Assembler /// /// The inline assembler implements each PORE/PGAS instruction as individual -/// function calls. The APIs are consistently named \c pore_<OPCODE>, where -/// \c <OPCODE> is a PGAS mnemonic in upper case. The arguments to each +/// function calls. The APIs are consistently named \c pore_\<OPCODE\>, where +/// \c \<OPCODE\> is a PGAS mnemonic in upper case. The arguments to each /// opcode appear in the same order that they appear in the source-level /// assembler, with appropriate C-language types. The supported opcode APIs /// are defined in pore_inline.h @@ -159,7 +159,7 @@ /// \subsection Assembling Branches /// /// Opcodes that implement relative branches require that the branch target be -/// specified as a <em> location counter <\em>. Once initialized, the current +/// specified as a <em> location counter </em>. Once initialized, the current /// location counter is available as the \a lc field of the PoreInlineContext /// object controlling the assembly. The \a lc field is the only field /// (besides the error code held in the \a error field) that application code @@ -247,7 +247,7 @@ /// branch-to-self - the recommended idiom for forward branch source /// instructions. Once the entire sequence has been assembled, /// pore_inline_branch_fixup() reassembles the \c source instruction as a -/// branch to the \target instruction. The above instruction sequence is +/// branch to the \c target instruction. The above instruction sequence is /// equivalent to the PGAS code below: /// /// \code @@ -362,9 +362,11 @@ /// \subsection Data Disassembly /// /// If the PoreInlineContext is created with the flag -/// PORE_INLINE_DISASSEMBLE_DATA, then the context is disassembled as -/// data. For complete information see the documentation for -/// pore_inline_disassemble(). +/// PORE_INLINE_DISASSEMBLE_DATA, then the context is disassembled as data. If +/// the PoreInlineContext is created with the flag +/// PORE_INLINE_DISASSEMBLE_UNKNOWN then putative data embedded in a text +/// section will be disassembled as data. For complete information see the +/// documentation for pore_inline_disassemble(). #define __PORE_INLINE_ASSEMBLER_C__ @@ -704,8 +706,8 @@ pore_inline_context_reset_excursion(PoreInlineContext *ctx) /// conjunction with PORE_INLINE_LISTING_MODE. /// /// - PORE_INLINE_8_BYTE_DATA : generate data disassembly using 8-byte values -/// rather than the default 4-byte values. text. Normally data is -/// disassembled as .quad directives, however if the context is unaligned or +/// rather than the default 4-byte values. Normally data is disassembled as +/// .quad directives under this option, however if the context is unaligned or /// of an odd length then .long and .byte directives may be used as well. /// This option can be used in conjunction with PORE_INLINE_LISTING_MODE. /// @@ -733,10 +735,12 @@ pore_inline_context_create(PoreInlineContext *ctx, int rc; int valid_options = - PORE_INLINE_GENERATE_PARITY | - PORE_INLINE_CHECK_PARITY | - PORE_INLINE_LISTING_MODE | - PORE_INLINE_DISASSEMBLE_DATA; + PORE_INLINE_GENERATE_PARITY | + PORE_INLINE_CHECK_PARITY | + PORE_INLINE_LISTING_MODE | + PORE_INLINE_DISASSEMBLE_DATA | + PORE_INLINE_8_BYTE_DATA | + PORE_INLINE_DISASSEMBLE_UNKNOWN; if ((ctx == 0) || ((memory == 0) && (size != 0)) || ((options & ~valid_options) != 0)) { @@ -765,7 +769,7 @@ pore_inline_context_create(PoreInlineContext *ctx, /// source of the copy. /// /// This API copies one PoreInlineContext structure to another. An example -/// use appears in \ref pore_inline_assembly in the section discussing +/// use appears in \ref pore_inline_assembler in the section discussing /// disassembly. void |