summaryrefslogtreecommitdiffstats
path: root/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api.C')
-rw-r--r--src/usr/hwpf/hwp/build_winkle_images/p8_slw_build/p8_pore_table_gen_api.C251
1 files changed, 156 insertions, 95 deletions
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)
OpenPOWER on IntegriCloud