summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/image/sbe_xip_tool.c876
-rwxr-xr-xtools/scripts/parseErrorInfo.pl1511
2 files changed, 1948 insertions, 439 deletions
diff --git a/tools/image/sbe_xip_tool.c b/tools/image/sbe_xip_tool.c
index 195a29ef..75448a25 100644
--- a/tools/image/sbe_xip_tool.c
+++ b/tools/image/sbe_xip_tool.c
@@ -77,13 +77,9 @@
//
// The 'report' command prints a report including a dump of the header and
// section table, a listing of the types and values of all items that appear
-// in the TOC, and a dump of the .halt section. The TOC listing includes the
+// in the TOC. The TOC listing includes the
// sequence number of the entry in the TOC, the item name, the item type and
-// the item value. The .halt listing displays a map of HALT PC values to the
-// string form of the halt code associated with the HALT address. The optional
-// <regex> expression, if present, is a POSIX Basic Regular Expression. If
-// <regex> is specified, then no header, section table or .halt dumps are
-// provided, and only the TOC entries matching <regex> will be listed.
+// the item value.
//
// The 'append' command either creates or extends the section named by the
// section argument, by appending the contents of the named file verbatim.
@@ -158,13 +154,9 @@ const char* g_usage =
"\n"
"The 'report' command prints a report including a dump of the header and\n"
"section table, a listing of the types and values of all items that appear\n"
-"in the TOC, and a dump of the .halt section. The TOC listing includes the\n"
+"in the TOC. The TOC listing includes the\n"
"sequence number of the entry in the TOC, the item name, the item type and\n"
-"the item value. The .halt listing displays a map of HALT PC values to the\n"
-"string form of the halt code associated with the HALT address. The optional\n"
-"<regex> expression, if present, is a POSIX Basic Regular Expression. If\n"
-"<regex> is specified, then no header, section table or .halt dumps are\n"
-"provided, and only the TOC entries matching <regex> will be listed.\n"
+"the item value.\n"
"\n"
"The 'append' command either creates or extends the section named by the\n"
"section argument, by appending the contents of the named file verbatim.\n"
@@ -332,16 +324,41 @@ tocListing(void* io_image,
if (rc) break;
printf("0x%02x", (uint8_t)data);
break;
+ case SBE_XIP_INT8:
+ rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
+ if (rc) break;
+ printf("%d", (int8_t)data);
+ break;
+ case SBE_XIP_UINT16:
+ rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
+ if (rc) break;
+ printf("0x%08x", (uint16_t)data);
+ break;
+ case SBE_XIP_INT16:
+ rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
+ if (rc) break;
+ printf("%d", (int16_t)data);
+ break;
case SBE_XIP_UINT32:
rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
if (rc) break;
printf("0x%08x", (uint32_t)data);
break;
+ case SBE_XIP_INT32:
+ rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
+ if (rc) break;
+ printf("%d", (int32_t)data);
+ break;
case SBE_XIP_UINT64:
rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
if (rc) break;
printf("0x%016llx", data);
break;
+ case SBE_XIP_INT64:
+ rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data);
+ if (rc) break;
+ printf("%d", (int64_t)data);
+ break;
case SBE_XIP_STRING:
rc = sbe_xip_get_string(io_image, i_item->iv_id, &s);
if (rc) break;
@@ -355,6 +372,7 @@ tocListing(void* io_image,
(uint32_t)(data & 0xffffffff));
break;
default:
+ printf("unknown type\n");
rc = SBE_XIP_BUG;
break;
}
@@ -421,19 +439,6 @@ dumpHeader(void* i_image)
}
-// Dump an entry from .halt
-
-int
-haltListing(void* io_image,
- const uint64_t i_homerAddress,
- const char* i_rcString,
- void* io_arg)
-{
- printf("%016llx : %s\n", i_homerAddress, i_rcString);
- return 0;
-}
-
-
// Print a report
int
@@ -475,17 +480,6 @@ report(void* io_image, const int i_argc, const char** i_argv)
rc = sbe_xip_map_toc(io_image, tocListing, (void*)(&control));
if (rc) break;
- // Dump the .halt section
-
- if (i_argc == 0) {
- printf("\nHALT report\n\n");
- rc = sbe_xip_map_halt(io_image, haltListing, 0);
- if (rc == SBE_XIP_ITEM_NOT_FOUND) {
- rc = 0;
- }
- if (rc) break;
- }
-
} while (0);
return rc;
@@ -550,6 +544,7 @@ set(void* io_image, const int i_argc, const char** i_argv, int i_setv)
switch (item.iv_type) {
case SBE_XIP_UINT8:
+ case SBE_XIP_UINT16:
case SBE_XIP_UINT32:
case SBE_XIP_UINT64:
@@ -586,6 +581,15 @@ set(void* io_image, const int i_argc, const char** i_argv, int i_setv)
}
break;
+ case SBE_XIP_UINT16:
+ if ((uint16_t)newValue != newValue) {
+ fprintf(stderr,
+ "Value 0x%016llx too large for 16-bit type\n",
+ newValue);
+ exit(1);
+ }
+ break;
+
case SBE_XIP_UINT32:
if ((uint32_t)newValue != newValue) {
fprintf(stderr,
@@ -616,7 +620,18 @@ set(void* io_image, const int i_argc, const char** i_argv, int i_setv)
rc = sbe_xip_set_string(io_image, key, (char*)value);
if (rc) rc = SBE_XIP_BUG;
break;
-
+ case SBE_XIP_INT8:
+ case SBE_XIP_INT16:
+ case SBE_XIP_INT32:
+ case SBE_XIP_INT64:
+ fprintf(stderr,
+ "Item %s has int type %s, "
+ "which is not supported for '%s'.\n",
+ i_argv[arg],
+ SBE_XIP_TYPE_STRING(g_typeStrings, item.iv_type),
+ (i_setv ? "setv" : "set"));
+ exit(1);
+ break;
default:
fprintf(stderr,
"Item %s has type %s, "
@@ -713,6 +728,7 @@ get(void* i_image, const int i_argc, const char** i_argv, int i_getv)
switch (item.iv_type) {
case SBE_XIP_UINT8:
+ case SBE_XIP_UINT16:
case SBE_XIP_UINT32:
case SBE_XIP_UINT64:
rc = sbe_xip_get_element(i_image, key, index_val, &data);
@@ -724,6 +740,9 @@ get(void* i_image, const int i_argc, const char** i_argv, int i_getv)
case SBE_XIP_UINT8:
printf("0x%02x\n", (uint8_t)data);
break;
+ case SBE_XIP_UINT16:
+ printf("0x%04x\n", (uint16_t)data);
+ break;
case SBE_XIP_UINT32:
printf("0x%08x\n", (uint32_t)data);
break;
@@ -762,7 +781,14 @@ get(void* i_image, const int i_argc, const char** i_argv, int i_getv)
}
printf("%s\n", s);
break;
-
+ case SBE_XIP_INT8:
+ case SBE_XIP_INT16:
+ case SBE_XIP_INT32:
+ case SBE_XIP_INT64:
+ fprintf(stderr, "%s%d : Bug, int types not implemented %d\n",
+ __FILE__, __LINE__, item.iv_type);
+ exit(1);
+ break;
default:
fprintf(stderr, "%s%d : Bug, unexpected type %d\n",
__FILE__, __LINE__, item.iv_type);
@@ -1332,18 +1358,6 @@ TEST(void* io_image, const int i_argc, const char** i_argv)
BOMB_IF(sbe_xip_find(io_image, "proc_sbe_ex_dpll_initf", 0) != 0);
}
- // Run the embedded delete and append tests. This assumes that the
- // test image does not contain the .fit and .ffdc sections. We just
- // append zeros here, we're mostly interested in whether we can handle
- // errors and return the image back to its original state.
-
- BOMB_IF((deleteAppendImage = malloc(imageSize + 2000)) == 0);
- memcpy(deleteAppendImage, io_image, imageSize);
-
- BOMB_IF(sbe_xip_append(deleteAppendImage, SBE_XIP_SECTION_FIT,
- 0, 973, imageSize + 2000, 0) != 0);
- BOMB_IF(sbe_xip_append(deleteAppendImage, SBE_XIP_SECTION_FFDC,
- 0, 973, imageSize + 2000, 0) != 0);
#ifdef DEBUG_SBE_XIP_IMAGE
printf("\nYou will see an expected warning below "
@@ -1351,14 +1365,6 @@ TEST(void* io_image, const int i_argc, const char** i_argv)
"It means the TEST is working (not failing)\n\n");
#endif
- BOMB_IF(sbe_xip_append(deleteAppendImage, SBE_XIP_SECTION_FFDC,
- 0, 973, imageSize + 2000, 0) == 0);
-
- BOMB_IF(sbe_xip_delete_section(deleteAppendImage, SBE_XIP_SECTION_FFDC) != 0);
- BOMB_IF(sbe_xip_delete_section(deleteAppendImage, SBE_XIP_SECTION_FIT) != 0);
-
- memcpy(io_image, deleteAppendImage, imageSize);
-
// Finally compare against the original
BOMB_IF(memcmp(io_image, originalImage, imageSize));
@@ -1473,440 +1479,432 @@ int disassembleSection(void *i_image,
int i_argc,
const char **i_argv)
{
- int rc=0, rcSet=0;
- uint32_t rcCount=0;
- char *disList=NULL;
- uint32_t sizeSection=0, nextLinkOffsetBlock=0;
- uint32_t sizeBlock=0, sizeData=0, sizeCode=0, sizeData2=0;
- uint32_t sizeDisLine=0, sizeList=0, sizeListMax=0;
- uint32_t offsetCode=0;
- uint8_t typeRingsSection=0; // 0: RS4 1: Wiggle-Flip
- uint8_t bSummary=0, bFoundInToc=0;
- uint32_t sectionId;
- uint64_t backPtr=0, fwdPtr=0;
- PairingInfo pairingInfo;
- const char *sectionName;
+ int rc=0, rcSet=0;
+ uint32_t rcCount=0;
+ char *disList=NULL;
+ uint32_t sizeSection=0, nextLinkOffsetBlock=0;
+ uint32_t sizeBlock=0, sizeData=0, sizeCode=0, sizeData2=0;
+ uint32_t sizeDisLine=0, sizeList=0, sizeListMax=0;
+ uint32_t offsetCode=0;
+ uint8_t typeRingsSection=0; // 0: RS4 1: Wiggle-Flip
+ uint8_t bSummary=0, bFoundInToc=0;
+ uint32_t sectionId;
+ uint64_t backPtr=0, fwdPtr=0;
+ PairingInfo pairingInfo;
+ const char *sectionName;
char *ringName;
uint32_t ringSeqNo=0; // Ring sequence location counter.
uint8_t vectorPos,overRidable;
- void *nextBlock, *nextSection;
- SbeXipHeader hostHeader;
- SbeXipSection hostSection;
- ImageInlineContext ctx;
- ImageInlineDisassembly dis;
- char lineDis[LISTING_STRING_SIZE];
- void *hostRs4Container;
- uint32_t compressedBits=0, ringLength=0;
- double compressionPct=0;
-
- if (i_argc != 1) {
- fprintf(stderr, g_usage);
- exit(1);
- }
- sectionName = i_argv[0];
-
- // Determine SBE-XIP section ID from the section name, e.g.
- // .ipl_text => SBE_XIP_SECTION_IPL_TEXT
- // .text => SBE_XIP_SECTION_TEXT
- // .rings => SBE_XIP_SECTION_RINGS
- if (strcmp(sectionName, ".header")==0)
- sectionId = SBE_XIP_SECTION_HEADER;
- else
- if (strcmp(sectionName, ".fixed")==0)
- sectionId = SBE_XIP_SECTION_FIXED;
- else
- if (strcmp(sectionName, ".fixed_toc")==0)
- sectionId = SBE_XIP_SECTION_FIXED_TOC;
- else
- if (strcmp(sectionName, ".ipl_text")==0)
- sectionId = SBE_XIP_SECTION_IPL_TEXT;
- else
- if (strcmp(sectionName, ".ipl_data")==0)
- sectionId = SBE_XIP_SECTION_IPL_DATA;
- else
- if (strcmp(sectionName, ".text")==0)
- sectionId = SBE_XIP_SECTION_TEXT;
- else
- if (strcmp(sectionName, ".data")==0)
- sectionId = SBE_XIP_SECTION_DATA;
- else
- if (strcmp(sectionName, ".toc")==0)
- sectionId = SBE_XIP_SECTION_TOC;
- else
- if (strcmp(sectionName, ".strings")==0)
- sectionId = SBE_XIP_SECTION_STRINGS;
- else
- if (strcmp(sectionName, ".pibmem0")==0)
- sectionId = SBE_XIP_SECTION_PIBMEM0;
- else
- if (strcmp(sectionName, ".rings")==0)
- sectionId = SBE_XIP_SECTION_RINGS;
- else
- if (strcmp(sectionName, ".rings_summary")==0) {
- sectionId = SBE_XIP_SECTION_RINGS;
- bSummary = 1;
- }
- else
- if (strcmp(sectionName, ".dcrings")==0)
- sectionId = SBE_XIP_SECTION_DCRINGS;
- else
- if (strcmp(sectionName, ".halt")==0)
- sectionId = SBE_XIP_SECTION_HALT;
- else
- if (strcmp(sectionName, ".slw")==0)
- sectionId = SBE_XIP_SECTION_SLW;
- else
- if (strcmp(sectionName, ".ffdc")==0)
- sectionId = SBE_XIP_SECTION_FFDC;
- else {
- fprintf(stderr,"ERROR : %s is an invalid section name.\n",sectionName);
- fprintf(stderr,"Valid <section> names for the 'dis' function are:\n");
- fprintf(stderr,"\t.header\n");
- fprintf(stderr,"\t.fixed\n");
- fprintf(stderr,"\t.fixed_toc\n");
- fprintf(stderr,"\t.ipl_text\n");
- fprintf(stderr,"\t.ipl_data\n");
- fprintf(stderr,"\t.text\n");
- fprintf(stderr,"\t.data\n");
- fprintf(stderr,"\t.toc\n");
- fprintf(stderr,"\t.strings\n");
- fprintf(stderr,"\t.pibmem0\n");
- fprintf(stderr,"\t.rings\n");
- fprintf(stderr,"\t.rings_summary\n");
- fprintf(stderr,"\t.dcrings\n");
- fprintf(stderr,"\t.halt\n");
- fprintf(stderr,"\t.slw\n");
- fprintf(stderr,"\t.ffdc\n");
- exit(1);
- }
-
- // Get host header and section pointer.
- //
- sbe_xip_translate_header( &hostHeader, (SbeXipHeader*)i_image);
- rc = sbe_xip_get_section( i_image, sectionId, &hostSection);
- if (rc) {
- fprintf( stderr, "sbe_xip_get_section() failed : %s\n", SBE_XIP_ERROR_STRING(g_errorStrings, rc));
- return SBE_XIP_DISASSEMBLER_ERROR;
- }
- sizeSection = hostSection.iv_size;
- nextBlock = (void*)(hostSection.iv_offset + (uintptr_t)i_image);
- nextSection = (void*)((uint64_t)nextBlock + (uint64_t)sizeSection);
+ void *nextBlock, *nextSection;
+ SbeXipHeader hostHeader;
+ SbeXipSection hostSection;
+ ImageInlineContext ctx;
+ ImageInlineDisassembly dis;
+ char lineDis[LISTING_STRING_SIZE];
+ void *hostRs4Container;
+ uint32_t compressedBits=0, ringLength=0;
+ double compressionPct=0;
+
+ if (i_argc != 1) {
+ fprintf(stderr, g_usage);
+ exit(1);
+ }
+ sectionName = i_argv[0];
+
+ // Determine SBE-XIP section ID from the section name, e.g.
+ // .loader_text => SBE_XIP_SECTION_LOADER_TEXT
+ // .text => SBE_XIP_SECTION_TEXT
+ // .rings => SBE_XIP_SECTION_RINGS
+ if (strcmp(sectionName, ".header")==0)
+ sectionId = SBE_XIP_SECTION_HEADER;
+ else
+ if (strcmp(sectionName, ".fixed")==0)
+ sectionId = SBE_XIP_SECTION_FIXED;
+ else
+ if (strcmp(sectionName, ".fixed_toc")==0)
+ sectionId = SBE_XIP_SECTION_FIXED_TOC;
+ else
+ if (strcmp(sectionName, ".loader_text")==0)
+ sectionId = SBE_XIP_SECTION_LOADER_TEXT;
+ else
+ if (strcmp(sectionName, ".loader_data")==0)
+ sectionId = SBE_XIP_SECTION_LOADER_DATA;
+ else
+ if (strcmp(sectionName, ".text")==0)
+ sectionId = SBE_XIP_SECTION_TEXT;
+ else
+ if (strcmp(sectionName, ".data")==0)
+ sectionId = SBE_XIP_SECTION_DATA;
+ else
+ if (strcmp(sectionName, ".toc")==0)
+ sectionId = SBE_XIP_SECTION_TOC;
+ else
+ if (strcmp(sectionName, ".strings")==0)
+ sectionId = SBE_XIP_SECTION_STRINGS;
+ else
+ if (strcmp(sectionName, ".base")==0)
+ sectionId = SBE_XIP_SECTION_BASE;
+ else
+ if (strcmp(sectionName, ".baseloader")==0)
+ sectionId = SBE_XIP_SECTION_BASELOADER;
+ else
+ if (strcmp(sectionName, ".rings")==0)
+ sectionId = SBE_XIP_SECTION_RINGS;
+ else
+ if (strcmp(sectionName, ".rings_summary")==0) {
+ sectionId = SBE_XIP_SECTION_RINGS;
+ bSummary = 1;
+ }
+ else
+ if (strcmp(sectionName, ".overlays")==0)
+ sectionId = SBE_XIP_SECTION_OVERLAYS;
+ else {
+ fprintf(stderr,"ERROR : %s is an invalid section name.\n",sectionName);
+ fprintf(stderr,"Valid <section> names for the 'dis' function are:\n");
+ fprintf(stderr,"\t.header\n");
+ fprintf(stderr,"\t.fixed\n");
+ fprintf(stderr,"\t.fixed_toc\n");
+ fprintf(stderr,"\t.loader_text\n");
+ fprintf(stderr,"\t.loader_data\n");
+ fprintf(stderr,"\t.text\n");
+ fprintf(stderr,"\t.data\n");
+ fprintf(stderr,"\t.toc\n");
+ fprintf(stderr,"\t.strings\n");
+ fprintf(stderr,"\t.base\n");
+ fprintf(stderr,"\t.baseloader\n");
+ fprintf(stderr,"\t.overlays\n");
+ fprintf(stderr,"\t.rings\n");
+ fprintf(stderr,"\t.rings_summary\n");
+ exit(1);
+ }
+
+ // Get host header and section pointer.
+ //
+ sbe_xip_translate_header( &hostHeader, (SbeXipHeader*)i_image);
+ rc = sbe_xip_get_section( i_image, sectionId, &hostSection);
+ if (rc) {
+ fprintf( stderr, "sbe_xip_get_section() failed : %s\n", SBE_XIP_ERROR_STRING(g_errorStrings, rc));
+ return SBE_XIP_DISASSEMBLER_ERROR;
+ }
+ sizeSection = hostSection.iv_size;
+ nextBlock = (void*)(hostSection.iv_offset + (uintptr_t)i_image);
+ nextSection = (void*)((uint64_t)nextBlock + (uint64_t)sizeSection);
- // Relocatable offset of section at hand.
- nextLinkOffsetBlock = (uint32_t)hostHeader.iv_linkAddress + hostSection.iv_offset;
-
- // Allocate buffer to hold disassembled listing. (Start out with minimum 10k buffer size.)
- //
- if (sizeSection>10000)
- sizeListMax = sizeSection; // Just to use something as an initial guess.
- else
- sizeListMax = 10000;
- disList = (char*)malloc(sizeListMax);
- if (disList==NULL) {
- fprintf( stderr, "ERROR : malloc() failed.\n");
- fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_MEMORY_ERROR));
- return SBE_XIP_DISASSEMBLER_ERROR;
- }
- *disList = '\0'; // Make sure the buffer is NULL terminated (though probably not needed.)
- sizeList = 0;
-
- // Create context and point it to image section.
- //
- rc = image_inline_context_create( &ctx,
- nextBlock,
- sizeSection,
- nextLinkOffsetBlock,
- 0);
- if (rc) {
- fprintf( stderr, "ERROR : %s (rc=%i)\n",image_inline_error_strings[rc],rc);
- fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_DISASM_ERROR));
- return SBE_XIP_DISASSEMBLER_ERROR;
- }
+ // Relocatable offset of section at hand.
+ nextLinkOffsetBlock = (uint32_t)hostHeader.iv_linkAddress + hostSection.iv_offset;
- while ((uint64_t)nextBlock<(uint64_t)nextSection) {
+ // Allocate buffer to hold disassembled listing. (Start out with minimum 10k buffer size.)
+ //
+ if (sizeSection>10000)
+ sizeListMax = sizeSection; // Just to use something as an initial guess.
+ else
+ sizeListMax = 10000;
+ disList = (char*)malloc(sizeListMax);
+ if (disList==NULL) {
+ fprintf( stderr, "ERROR : malloc() failed.\n");
+ fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_MEMORY_ERROR));
+ return SBE_XIP_DISASSEMBLER_ERROR;
+ }
+ *disList = '\0'; // Make sure the buffer is NULL terminated (though probably not needed.)
+ sizeList = 0;
- // Disassemble sections based on their types and intents.
+ // Create context and point it to image section.
//
- if (sectionId==SBE_XIP_SECTION_RINGS || sectionId==SBE_XIP_SECTION_DCRINGS) {
- // Ring section (with a mix of data and code.)
- // ...use BaseRingLayout structure to decode each ring block.
- offsetCode = (uint32_t)myRev64(((BaseRingLayout*)nextBlock)->entryOffset);
- sizeBlock = myRev32(((BaseRingLayout*)nextBlock)->sizeOfThis);
- // ...determine ring type, either RS4 or Wiggle-flip.
- if (offsetCode-(myRev32(((BaseRingLayout*)nextBlock)->sizeOfMeta)+3)/4*4>28) {
- typeRingsSection = 0; // RS4 w/32-byte header.
- sizeData2 = sizeBlock - offsetCode - ASM_RS4_LAUNCH_BUF_SIZE;
- }
- else
- typeRingsSection = 1; // Wiggle-flip w/24-byte header.
- // ...get the backPtr and fwdPtr and put at top of disasm listing.
- backPtr = myRev64(((BaseRingLayout*)nextBlock)->backItemPtr);
- sbe_xip_read_uint64(i_image,
- backPtr,
- &fwdPtr);
+ rc = image_inline_context_create( &ctx,
+ nextBlock,
+ sizeSection,
+ nextLinkOffsetBlock,
+ 0);
+ if (rc) {
+ fprintf( stderr, "ERROR : %s (rc=%i)\n",image_inline_error_strings[rc],rc);
+ fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_DISASM_ERROR));
+ return SBE_XIP_DISASSEMBLER_ERROR;
+ }
+
+ while ((uint64_t)nextBlock<(uint64_t)nextSection) {
+
+ // Disassemble sections based on their types and intents.
+ //
+ if (sectionId==SBE_XIP_SECTION_RINGS || sectionId==SBE_XIP_SECTION_OVERLAYS) {
+ // Ring section (with a mix of data and code.)
+ // ...use BaseRingLayout structure to decode each ring block.
+ offsetCode = (uint32_t)myRev64(((BaseRingLayout*)nextBlock)->entryOffset);
+ sizeBlock = myRev32(((BaseRingLayout*)nextBlock)->sizeOfThis);
+ // ...determine ring type, either RS4 or Wiggle-flip.
+ if (offsetCode-(myRev32(((BaseRingLayout*)nextBlock)->sizeOfMeta)+3)/4*4>28) {
+ typeRingsSection = 0; // RS4 w/32-byte header.
+ sizeData2 = sizeBlock - offsetCode - ASM_RS4_LAUNCH_BUF_SIZE;
+ }
+ else
+ typeRingsSection = 1; // Wiggle-flip w/24-byte header.
+ // ...get the backPtr and fwdPtr and put at top of disasm listing.
+ backPtr = myRev64(((BaseRingLayout*)nextBlock)->backItemPtr);
+ sbe_xip_read_uint64(i_image,
+ backPtr,
+ &fwdPtr);
- // Calculate RS4 compression efficiency if RS4 rings.
- if (typeRingsSection==0) {
- hostRs4Container = (void*)( (uintptr_t)nextBlock +
- offsetCode + ASM_RS4_LAUNCH_BUF_SIZE );
- compressedBits = myRev32(((CompressedScanData*)hostRs4Container)->iv_algorithmReserved) * 4;
- ringLength = myRev32(((CompressedScanData*)hostRs4Container)->iv_length);
- compressionPct = (double)compressedBits / (double)ringLength * 100.0;
+ // Calculate RS4 compression efficiency if RS4 rings.
+ if (typeRingsSection==0) {
+ hostRs4Container = (void*)( (uintptr_t)nextBlock +
+ offsetCode + ASM_RS4_LAUNCH_BUF_SIZE );
+ compressedBits = myRev32(((CompressedScanData*)hostRs4Container)->iv_algorithmReserved) * 4;
+ ringLength = myRev32(((CompressedScanData*)hostRs4Container)->iv_length);
+ compressionPct = (double)compressedBits / (double)ringLength * 100.0;
}
- //
+ //
// Map over TOC or do a targeted search of FIXED_TOC to pair backPtr addr
// with ring name and override and/or vector position (i.e. multi-chiplet).
//
- sbe_xip_get_section( i_image, SBE_XIP_SECTION_TOC, &hostSection);
+ sbe_xip_get_section( i_image, SBE_XIP_SECTION_TOC, &hostSection);
if (hostSection.iv_offset) {
- // TOC exists.
- pairingInfo.address = backPtr;
+ // TOC exists.
+ pairingInfo.address = backPtr;
// Search for pairing. First exhaust base position (pos=0), then next, then next, ...
for (pairingInfo.vectorpos=0;pairingInfo.vectorpos<32;pairingInfo.vectorpos++) {
- rc = sbe_xip_map_toc( i_image, pairRingNameAndAddr, (void*)(&pairingInfo));
+ rc = sbe_xip_map_toc( i_image, pairRingNameAndAddr, (void*)(&pairingInfo));
if (rc)
break;
}
- if (rc==DIS_RING_NAME_ADDR_MATCH_FAILURE) {
- fprintf( stderr,"ERROR : Error associated with sbe_xip_map_toc().\n");
- fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_RING_NAME_ADDR_MATCH_FAILURE));
- return SBE_XIP_DISASSEMBLER_ERROR;
- }
- ringSeqNo++;
+ if (rc==DIS_RING_NAME_ADDR_MATCH_FAILURE) {
+ fprintf( stderr,"ERROR : Error associated with sbe_xip_map_toc().\n");
+ fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_RING_NAME_ADDR_MATCH_FAILURE));
+ return SBE_XIP_DISASSEMBLER_ERROR;
+ }
+ ringSeqNo++;
if (rc==DIS_RING_NAME_ADDR_MATCH_SUCCESS) {
bFoundInToc = 1;
- ringName = pairingInfo.name; // The ring name matched in pairRingNameAndAddr()
+ ringName = pairingInfo.name; // The ring name matched in pairRingNameAndAddr()
vectorPos = pairingInfo.vectorpos; // The vector position matched in pairRingNameAndAddr()
overRidable = pairingInfo.overridable; // Whether the ring supports on override ring.
- if (pairingInfo.override) {
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
- "# ------------------------------\n# %i.\n# ringName = %s (override)\n# vectorPos = %i\n# overRidable = %i\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n",
- ringSeqNo, ringName,vectorPos,overRidable,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct);
- }
- else {
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
- "# ------------------------------\n# %i.\n# ringName = %s (base)\n# vectorPos = %i\n# overRidable = %i\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n",
- ringSeqNo,ringName,vectorPos,overRidable,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct);
- }
+ if (pairingInfo.override) {
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# ------------------------------\n# %i.\n# ringName = %s (override)\n# vectorPos = %i\n# overRidable = %i\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n",
+ ringSeqNo, ringName,vectorPos,overRidable,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct);
+ }
+ else {
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# ------------------------------\n# %i.\n# ringName = %s (base)\n# vectorPos = %i\n# overRidable = %i\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n",
+ ringSeqNo,ringName,vectorPos,overRidable,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct);
+ }
}
- else {
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
- "# ------------------------------\n# %i.\n# ringName = Not found (but TOC's available)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n",
- ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr);
+ else {
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# ------------------------------\n# %i.\n# ringName = Not found (but TOC's available)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n",
+ ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr);
}
- }
+ }
else {
- // TOC doesn't exist. First try targeted search of MVPD ring names in FIXED_TOC.
- bFoundInToc = 0; // If we find in fixed_toc, then change to 1.
+ // TOC doesn't exist. First try targeted search of MVPD ring names in FIXED_TOC.
+ bFoundInToc = 0; // If we find in fixed_toc, then change to 1.
// 2012-11-13: CMO TBD. Try using pairRingNameAndAddr by enabling a sequential
- // traversing of each of the MVPD lists inside that function. You'll
- // need to call pairRing manually from right here (or from a
- // sbe_xip_search_fixed_toc()-like function). Maybe you can add a
+ // traversing of each of the MVPD lists inside that function. You'll
+ // need to call pairRing manually from right here (or from a
+ // sbe_xip_search_fixed_toc()-like function). Maybe you can add a
// 4th arg to pairRing that is zero by default, meaning it is to be
// used by xip_map_toc(). But if non-zero, it is to be used in a
// traversing manner. Or you could add another member to the
- // PairingInfo struct to indirectly pass this info to the function.
+ // PairingInfo struct to indirectly pass this info to the function.
// You'd also need to pass two more arguments to get_vpd_ring_list_
- // entry() to indicate sequence number and the MVPD keyword.
- // rc = pairRingNameAndAddr();
+ // entry() to indicate sequence number and the MVPD keyword.
+ // rc = pairRingNameAndAddr();
// if (rc==DIS_RING_NAME_ADDR_MATCH_SUCCESS) {
- // bFoundInToc = 1;
- // // Do same as in TOC section above.
- // break;
- // }
- // // OK, so ring name wasn't in TOC nor in FIXED_TOC. That happens if the ring
- // // is a non-Mvpd ring and the TOC has been removed, such as in an IPL or
- // // Seeprom image.
- ringSeqNo++;
- if (typeRingsSection==0) {
- // RS4 header, which has override info
- if (((Rs4RingLayout*)nextBlock)->override==0) {
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
- "# ------------------------------\n# %i.\n# ringName = Not available (base)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n",
- ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct);
- }
+ // bFoundInToc = 1;
+ // // Do same as in TOC section above.
+ // break;
+ // }
+ // // OK, so ring name wasn't in TOC nor in FIXED_TOC. That happens if the ring
+ // // is a non-Mvpd ring and the TOC has been removed, such as in an IPL or
+ // // Seeprom image.
+ ringSeqNo++;
+ if (typeRingsSection==0) {
+ // RS4 header, which has override info
+ if (((Rs4RingLayout*)nextBlock)->override==0) {
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# ------------------------------\n# %i.\n# ringName = Not available (base)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n",
+ ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct);
+ }
else {
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
- "# ------------------------------\n# %i.\n# ringName = Not available (override)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n",
- ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct);
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# ------------------------------\n# %i.\n# ringName = Not available (override)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n",
+ ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct);
}
- }
+ }
else {
- // WF header, which doesn't have override info
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
- "# ------------------------------\n# %i.\n# ringName and override = Not available\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n",
- ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr);
+ // WF header, which doesn't have override info
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# ------------------------------\n# %i.\n# ringName and override = Not available\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n",
+ ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr);
}
- }
- sizeList = sizeList + sizeDisLine;
- disList = strcat(disList,lineDis);
+ }
+ sizeList = sizeList + sizeDisLine;
+ disList = strcat(disList,lineDis);
}
- else if ( sectionId==SBE_XIP_SECTION_IPL_TEXT ||
- sectionId==SBE_XIP_SECTION_TEXT) {
- // Sections that have only code.
- offsetCode = 0;
- sizeBlock = sizeSection;
- }
- else {
- // Sections that have only data.
- offsetCode = sizeSection;
- sizeBlock = sizeSection;
- }
- sizeData = offsetCode;
- sizeCode = sizeBlock - offsetCode - sizeData2;
-
- if (sectionId==SBE_XIP_SECTION_RINGS && bSummary) {
- //
- // Summarize rings section.
-
- if (typeRingsSection==0) { // RS4 header.
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
- "# ddLevel = 0x%02x\n# override= %i\n# sysPhase= %i\n# Block size= %i\n",
- myRev32(((Rs4RingLayout*)nextBlock)->ddLevel),
- ((Rs4RingLayout*)nextBlock)->override,
- ((Rs4RingLayout*)nextBlock)->sysPhase,
- sizeBlock);
- }
- else { // WF header.
+ else if ( sectionId==SBE_XIP_SECTION_LOADER_TEXT ||
+ sectionId==SBE_XIP_SECTION_TEXT) {
+ // Sections that have only code.
+ offsetCode = 0;
+ sizeBlock = sizeSection;
+ }
+ else {
+ // Sections that have only data.
+ offsetCode = sizeSection;
+ sizeBlock = sizeSection;
+ }
+ sizeData = offsetCode;
+ sizeCode = sizeBlock - offsetCode - sizeData2;
+
+ if (sectionId==SBE_XIP_SECTION_RINGS && bSummary) {
+ //
+ // Summarize rings section.
+
+ if (typeRingsSection==0) { // RS4 header.
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# ddLevel = 0x%02x\n# override= %i\n# sysPhase= %i\n# Block size= %i\n",
+ myRev32(((Rs4RingLayout*)nextBlock)->ddLevel),
+ ((Rs4RingLayout*)nextBlock)->override,
+ ((Rs4RingLayout*)nextBlock)->sysPhase,
+ sizeBlock);
+ }
+ else { // WF header.
if (bFoundInToc) {
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
- "# override= %i\n# Block size= %i\n",
- pairingInfo.override, sizeBlock);
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# override= %i\n# Block size= %i\n",
+ pairingInfo.override, sizeBlock);
}
else {
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
- "# override= Not available\n# Block size= %i\n",
- sizeBlock);
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "# override= Not available\n# Block size= %i\n",
+ sizeBlock);
}
- }
- sizeList = sizeList + sizeDisLine;
- disList = strcat(disList,lineDis);
- // Readjust list buffer size, if needed.
- if (sizeList > sizeListMax-1000) {
- sizeListMax = 2*sizeListMax;
- disList = (char*)realloc( (void*)(disList), sizeListMax);
- }
-
- }
- else {
- //
- // Do disassembly.
-
- // ...data disassembly
- if (sizeData>0) {
- ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA;
- do {
- rc = image_inline_disassemble( &ctx, &dis);
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s);
- sizeList = sizeList + sizeDisLine;
- disList = strcat(disList,lineDis);
- if (rc) {
- rcSet = rcSet | 0x1;
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
- "WARNING: %s (rc=%i) -> Stopping disasm. Check code and sectionID=%i.\n",
- image_inline_error_strings[rc],rc,sectionId);
+ }
sizeList = sizeList + sizeDisLine;
disList = strcat(disList,lineDis);
- }
- // Readjust list buffer size, if needed.
- if (sizeList > sizeListMax-1000) {
- sizeListMax = 2*sizeListMax;
- disList = (char*)realloc( (void*)(disList), sizeListMax);
- }
- } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeData);
- }
- if (rcSet)
- rc = 0;
-
- // ...code disassembly
- if (sizeCode>0) {
- ctx.options = IMAGE_INLINE_LISTING_MODE;
- do {
- rc = image_inline_disassemble( &ctx, &dis);
- ctx.options = IMAGE_INLINE_LISTING_MODE;
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s);
- sizeList = sizeList + sizeDisLine;
- disList = strcat(disList,lineDis);
- if (rc && rcCount<100) {
- rcSet = rcSet | 0x2;
- rcCount++;
- if (sectionId==SBE_XIP_SECTION_RINGS) {
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
- "WARNING: %s (rc=%i) -> Trying data disasm mode. Check code, xyzRingLayout structures and image section.\n",
- image_inline_error_strings[rc],rc);
+ // Readjust list buffer size, if needed.
+ if (sizeList > sizeListMax-1000) {
+ sizeListMax = 2*sizeListMax;
+ disList = (char*)realloc( (void*)(disList), sizeListMax);
}
- else {
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
- "WARNING: %s (rc=%i) -> Trying data disasm mode.\n",
- image_inline_error_strings[rc],rc);
+
+ }
+ else {
+ //
+ // Do disassembly.
+
+ // ...data disassembly
+ if (sizeData>0) {
+ ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA;
+ do {
+ rc = image_inline_disassemble( &ctx, &dis);
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s);
+ sizeList = sizeList + sizeDisLine;
+ disList = strcat(disList,lineDis);
+ if (rc) {
+ rcSet = rcSet | 0x1;
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "WARNING: %s (rc=%i) -> Stopping disasm. Check code and sectionID=%i.\n",
+ image_inline_error_strings[rc],rc,sectionId);
+ sizeList = sizeList + sizeDisLine;
+ disList = strcat(disList,lineDis);
+ }
+ // Readjust list buffer size, if needed.
+ if (sizeList > sizeListMax-1000) {
+ sizeListMax = 2*sizeListMax;
+ disList = (char*)realloc( (void*)(disList), sizeListMax);
+ }
+ } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeData);
}
- sizeList = sizeList + sizeDisLine;
- disList = strcat(disList,lineDis);
- ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA;
- rc = 0;
- }
- else {
- if (rc && rcCount>=1000) {
- fprintf(stderr, "Too many disasm warnings. Check output listing.\n");
- fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_TOO_MANY_DISASM_WARNINGS));
- return SBE_XIP_DISASSEMBLER_ERROR;
+ if (rcSet)
+ rc = 0;
+
+ // ...code disassembly
+ if (sizeCode>0) {
+ ctx.options = IMAGE_INLINE_LISTING_MODE;
+ do {
+ rc = image_inline_disassemble( &ctx, &dis);
+ ctx.options = IMAGE_INLINE_LISTING_MODE;
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s);
+ sizeList = sizeList + sizeDisLine;
+ disList = strcat(disList,lineDis);
+ if (rc && rcCount<100) {
+ rcSet = rcSet | 0x2;
+ rcCount++;
+ if (sectionId==SBE_XIP_SECTION_RINGS) {
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "WARNING: %s (rc=%i) -> Trying data disasm mode. Check code, xyzRingLayout structures and image section.\n",
+ image_inline_error_strings[rc],rc);
+ }
+ else {
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "WARNING: %s (rc=%i) -> Trying data disasm mode.\n",
+ image_inline_error_strings[rc],rc);
+ }
+ sizeList = sizeList + sizeDisLine;
+ disList = strcat(disList,lineDis);
+ ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA;
+ rc = 0;
+ }
+ else {
+ if (rc && rcCount>=1000) {
+ fprintf(stderr, "Too many disasm warnings. Check output listing.\n");
+ fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_TOO_MANY_DISASM_WARNINGS));
+ return SBE_XIP_DISASSEMBLER_ERROR;
+ }
+ }
+ // Readjust list buffer size, if needed.
+ if (sizeList > sizeListMax-1000) {
+ sizeListMax = 2*sizeListMax;
+ disList = (char*)realloc( (void*)(disList), sizeListMax);
+ }
+ } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeData+sizeCode);
}
- }
- // Readjust list buffer size, if needed.
- if (sizeList > sizeListMax-1000) {
- sizeListMax = 2*sizeListMax;
- disList = (char*)realloc( (void*)(disList), sizeListMax);
- }
- } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeData+sizeCode);
- }
- if (rcSet)
- rc = 0;
+ if (rcSet)
+ rc = 0;
- // ...data2 disassembly (only done for rings section if RS4 type.)
- if (sizeData2>0) {
- ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA;
- do {
- rc = image_inline_disassemble( &ctx, &dis);
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s);
- sizeList = sizeList + sizeDisLine;
- disList = strcat(disList,lineDis);
- if (rc) {
- rcSet = rcSet | 0x4;
- sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
- "WARNING: %s (rc=%i) -> Stopping disasm. Check code and sectionID=%i.\n",
- image_inline_error_strings[rc],rc,sectionId);
- sizeList = sizeList + sizeDisLine;
- disList = strcat(disList,lineDis);
- }
- // Readjust list buffer size, if needed.
- if (sizeList > sizeListMax-1000) {
- sizeListMax = 2*sizeListMax;
- disList = (char*)realloc( (void*)(disList), sizeListMax);
- }
- } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeBlock);
- }
- if (rcSet)
- rc = 0;
+ // ...data2 disassembly (only done for rings section if RS4 type.)
+ if (sizeData2>0) {
+ ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA;
+ do {
+ rc = image_inline_disassemble( &ctx, &dis);
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s);
+ sizeList = sizeList + sizeDisLine;
+ disList = strcat(disList,lineDis);
+ if (rc) {
+ rcSet = rcSet | 0x4;
+ sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,
+ "WARNING: %s (rc=%i) -> Stopping disasm. Check code and sectionID=%i.\n",
+ image_inline_error_strings[rc],rc,sectionId);
+ sizeList = sizeList + sizeDisLine;
+ disList = strcat(disList,lineDis);
+ }
+ // Readjust list buffer size, if needed.
+ if (sizeList > sizeListMax-1000) {
+ sizeListMax = 2*sizeListMax;
+ disList = (char*)realloc( (void*)(disList), sizeListMax);
+ }
+ } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeBlock);
+ }
+ if (rcSet)
+ rc = 0;
- } // End of if (bSummary) condition.
+ } // End of if (bSummary) condition.
- nextBlock = (void*)((uint64_t)nextBlock + (uint64_t)sizeBlock);
- nextLinkOffsetBlock = nextLinkOffsetBlock + sizeBlock;
+ nextBlock = (void*)((uint64_t)nextBlock + (uint64_t)sizeBlock);
+ nextLinkOffsetBlock = nextLinkOffsetBlock + sizeBlock;
- } // End of while(nextBlock...) loop.
+ } // End of while(nextBlock...) loop.
- // Adjust final buffer size, add 1 for NULL char and print it.
- if (disList) {
- disList = (char*)realloc( (void*)(disList), sizeList+1);
- fprintf(stdout,"%s\n",disList);
- free(disList);
- }
+ // Adjust final buffer size, add 1 for NULL char and print it.
+ if (disList) {
+ disList = (char*)realloc( (void*)(disList), sizeList+1);
+ fprintf(stdout,"%s\n",disList);
+ free(disList);
+ }
- if (rcSet)
- fprintf( stderr, "INFO : There were some hickups: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_DISASM_TROUBLES));
+ if (rcSet)
+ fprintf( stderr, "INFO : There were some hickups: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_DISASM_TROUBLES));
- return 0;
+ return 0;
}
#endif
diff --git a/tools/scripts/parseErrorInfo.pl b/tools/scripts/parseErrorInfo.pl
new file mode 100755
index 00000000..61b6c96d
--- /dev/null
+++ b/tools/scripts/parseErrorInfo.pl
@@ -0,0 +1,1511 @@
+#!/usr/bin/perl
+# IBM_PROLOG_BEGIN_TAG
+# This is an automatically generated prolog.
+#
+# $Source: src/usr/hwpf/fapi/fapiParseErrorInfo.pl $
+#
+# OpenPOWER HostBoot Project
+#
+# Contributors Listed Below - COPYRIGHT 2011,2014
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+# IBM_PROLOG_END_TAG
+# $Id: fapiParseErrorInfo.pl,v 1.30 2014/07/25 00:36:41 jmcgill Exp $
+# Purpose: This perl script will parse HWP Error XML files and create required
+# FAPI code.
+#
+# Author: CamVan Nguyen and Mike Jones
+# Reworked for fapi2/P9
+#
+# Usage:
+# fapiParseErrorInfo.pl <output dir> <filename1> <filename2> ...
+
+use strict;
+
+#------------------------------------------------------------------------------
+# Set PREFERRED_PARSER to XML::Parser. Otherwise it uses XML::SAX which contains
+# bugs that result in XML parse errors that can be fixed by adjusting white-
+# space (i.e. parse errors that do not make sense).
+#------------------------------------------------------------------------------
+$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
+
+#------------------------------------------------------------------------------
+# Specify perl modules to use
+#------------------------------------------------------------------------------
+use Digest::MD5 qw(md5_hex);
+use XML::Simple;
+my $xml = new XML::Simple (KeyAttr=>[]);
+
+# Uncomment to enable debug output
+use Data::Dumper;
+use Getopt::Long;
+
+my $target_ffdc_type = "fapi2::Target<T>";
+my $buffer_ffdc_type = "fapi2::buffer";
+my $variable_buffer_ffdc_type = "fapi2::variable_buffer";
+my $ffdc_type = "fapi2::ffdc_t";
+
+# We want to keep the signatures for the ffdc gathering hwp so that
+# we can create members of the proper types for the ffdc classes.
+my %signatures = ("proc_extract_pore_halt_ffdc" => ["por_base_state",
+ "por_halt_type_t",
+ "por_ffdc_offset_t"],
+ "hwpTestFfdc1" => [$target_ffdc_type],
+ "proc_extract_pore_base_ffdc" => ["por_base_state", "por_sbe_base_state"],
+ "proc_tp_collect_dbg_data" => [$target_ffdc_type],
+ );
+
+# There are some names used in the XML files which exist in either
+# c++ keywords (case, for example) or macros (DOMAIN). The one's which
+# cause problems and need to be changed are here.
+#
+# DOMAIN is defined to 1 in math.h
+my %mangle_names = ("DOMAIN" => "FAPI2_DOMAIN");
+
+# A list of deprecated elements. These will report messages to the
+# user, and not define anything. They have not been found to be used,
+# but that doesn't mean they're not ...
+my %deprecated = ("RC_PROCPM_PMCINIT_TIMEOUT" => "CHIP_IN_ERROR is defined as a callout procedure");
+
+#------------------------------------------------------------------------------
+# Print Command Line Help
+#------------------------------------------------------------------------------
+my $arg_empty_ffdc = undef;
+my $arg_output_dir = undef;
+my $arg_use_variable_buffers = undef;
+
+# Get the options from the command line - the rest of @ARGV will
+# be filenames
+GetOptions("empty-ffdc-classes" => \$arg_empty_ffdc,
+ "output-dir=s" => \$arg_output_dir,
+ "use-variable-buffers" => \$arg_use_variable_buffers);
+
+my $numArgs = $#ARGV + 1;
+if (($numArgs < 1) || ($arg_output_dir eq undef))
+{
+ print ("Usage: parseErrorInfo.pl [--empty-ffdc-classes] [--use-variable-buffers] --output-dir=<output dir> <filename1> <filename2> ...\n");
+ print (" This perl script will parse HWP Error XML files and creates\n");
+ print (" the following files:\n");
+ print (" - hwp_return_codes.H. HwpReturnCode enumeration (HWP generated errors)\n");
+ print (" - hwp_error_info.H. Error information (used by FAPI_SET_HWP_ERROR\n");
+ print (" when a HWP generates an error)\n");
+ print (" - collect_reg_ffdc.C. Function to collect register FFDC\n");
+ print (" - set_sbe_error.H. Macro to create an SBE error\n");
+ print (" The --empty-ffdc-classes option is for platforms which don't collect ffdc.\n");
+ exit(1);
+}
+
+#------------------------------------------------------------------------------
+# Hashes containing error names/enum-values
+#------------------------------------------------------------------------------
+my %errNameToValueHash;
+my %errValuePresentHash;
+
+#------------------------------------------------------------------------------
+# Hashes containing ffdc names/enum-values
+#------------------------------------------------------------------------------
+my %ffdcNameToValueHash;
+my %ffdcValuePresentHash;
+
+#------------------------------------------------------------------------------
+# Subroutine that checks if an entry exists in an array. If it doesn't exist
+# then it is added. The index of the entry within the array is returned
+#------------------------------------------------------------------------------
+sub addEntryToArray
+{
+ my ($arrayref, $entry ) = @_;
+
+ my $match = 0;
+ my $index = 0;
+
+ foreach my $element (@$arrayref)
+ {
+ if ($element eq $entry)
+ {
+ $match = 1;
+ last;
+ }
+ else
+ {
+ $index++;
+ }
+ }
+
+ if (!($match))
+ {
+ push(@$arrayref, $entry);
+ }
+
+ return $index;
+}
+
+#------------------------------------------------------------------------------
+# Subroutine that figures out an error enum value from an error name and stores
+# it in global hashes
+#------------------------------------------------------------------------------
+sub setErrorEnumValue
+{
+ my $name = $_[0];
+
+ #--------------------------------------------------------------------------
+ # Check that the error name is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($errNameToValueHash{$name}))
+ {
+ # Two different errors with the same name!
+ print ("fapiParseErrorInfo.pl ERROR. Duplicate error name ", $name, "\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Figure out the error enum-value. This is a hash value generated from
+ # the error name. A hash is used for Cronus so that if a HWP is not
+ # recompiled against a new eCMD/Cronus version where the errors have
+ # changed then there will not be a mismatch in error values.
+ # This is a 24bit hash value because FAPI has a requirement that the
+ # top byte of the 32 bit error value be zero to store flags indicating
+ # the creator of the error
+ #--------------------------------------------------------------------------
+ my $errHash128Bit = md5_hex($name);
+ my $errHash24Bit = substr($errHash128Bit, 0, 6);
+
+ #--------------------------------------------------------------------------
+ # Check that the error enum-value is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($errValuePresentHash{$errHash24Bit}))
+ {
+ # Two different errors generate the same hash-value!
+ print ("fapiParseAttributeInfo.pl ERROR. Duplicate error hash value\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Update the hashes with the error name and ID
+ #--------------------------------------------------------------------------
+ $errValuePresentHash{$errHash24Bit} = 1;
+ $errNameToValueHash{$name} = $errHash24Bit;
+}
+
+#------------------------------------------------------------------------------
+# Subroutine that figures out an FFDC ID value from an FFDC name and stores it
+# in global hashes for use when creating the enumeration of FFDC IDs
+#------------------------------------------------------------------------------
+sub setFfdcIdValue
+{
+ my $name = $_[0];
+
+ #--------------------------------------------------------------------------
+ # Check that the FFDC name is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($ffdcNameToValueHash{$name}))
+ {
+ # Two different FFDCs with the same name!
+ print ("fapiParseErrorInfo.pl ERROR. Duplicate FFDC name ", $name, "\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Figure out the FFDC enum-value. This is a hash value generated from
+ # the FFDC name.
+ #--------------------------------------------------------------------------
+ my $ffdcHash128Bit = md5_hex($name);
+ my $ffdcHash32Bit = substr($ffdcHash128Bit, 0, 8);
+
+ #--------------------------------------------------------------------------
+ # Check that the error enum-value is not a duplicate
+ #--------------------------------------------------------------------------
+ if (exists($ffdcValuePresentHash{$ffdcHash32Bit}))
+ {
+ # Two different FFDCs generate the same hash-value!
+ print ("fapiParseAttributeInfo.pl ERROR. Duplicate FFDC hash value\n");
+ exit(1);
+ }
+
+ #--------------------------------------------------------------------------
+ # Update the hashes with the error name and ID
+ #--------------------------------------------------------------------------
+ $ffdcValuePresentHash{$ffdcHash32Bit} = 1;
+ $ffdcNameToValueHash{$name} = $ffdcHash32Bit;
+}
+
+#------------------------------------------------------------------------------
+# Subroutine to create ffdc methods
+#------------------------------------------------------------------------------
+sub addFfdcMethod
+{
+ my $methods = shift;
+ my $ffdc_uc = shift;
+ my $class_name = shift;
+ my $type = shift;
+
+ # Remove the leading *_
+ $class_name = (split (/_/, $class_name, 2))[1];
+
+ # If we didn't get a type passed in, this element will get an ffdc_t pair.
+ $type = $ffdc_type if ($type eq undef);
+
+ # Mangle the uppercase name if needed
+ $ffdc_uc = $mangle_names{$ffdc_uc} if ($mangle_names{$ffdc_uc} ne undef);
+
+ my $key = $ffdc_uc.$type;
+ my $key_target = $ffdc_uc.$target_ffdc_type;
+ my $key_ffdc = $ffdc_uc.$ffdc_type;
+
+ # Check to see if this element already has been recorded with this
+ # type or a target type. Note the effect we're shooting for here is
+ # to define the member if it's not been defined before *or* it's
+ # changing from an ffdc_t to a target due to other information in the xml
+ return if ($methods->{$key}{type} eq $type);
+ return if ($methods->{$key_target}{type} eq $target_ffdc_type);
+
+ # Just leave if this is a variable_buffer ans we're not supporting that.
+ return if (($type eq $variable_buffer_ffdc_type) && ($arg_use_variable_buffers eq undef));
+
+ # Set the proper type, and clear out any previous members/methods if
+ # we're going from an ffdc_t to a target.
+ $methods->{$key}{type} = $type;
+ delete $methods->{$key_ffdc} if ($type eq $target_ffdc_type);
+
+ my $method = "";
+ my $method_body = "";
+
+ # If we're generating empty classes, not using an argument name will avoid the unused parameter warnings
+ my $param = ($arg_empty_ffdc eq undef) ? "i_value" : "";
+
+ if ($type eq $ffdc_type)
+ {
+ $method = "\n template< typename T >\n";
+ $method .= " inline $class_name& set_$ffdc_uc(const T& $param)\n";
+ $method_body = " {$ffdc_uc.ptr() = &i_value; $ffdc_uc.size() = fapi2::getErrorInfoFfdcSize(i_value); return *this;}\n\n";
+
+ $methods->{$key}{member} = "$ffdc_type $ffdc_uc;\n ";
+ }
+
+ elsif ($type eq $buffer_ffdc_type)
+ {
+ # Two methods - one for integral buffers and one for variable_buffers
+ $method = "\n template< typename T >\n";
+ $method .= " inline $class_name& set_$ffdc_uc(const fapi2::buffer<T>& $param)\n";
+ $method_body = " {$ffdc_uc.ptr() = &i_value(); $ffdc_uc.size() = i_value.template getLength<uint8_t>(); return *this;}\n\n";
+
+ $methods->{$key}{member} = "$ffdc_type $ffdc_uc;\n ";
+ }
+
+ elsif ($type eq $variable_buffer_ffdc_type)
+ {
+ $method = "\n inline $class_name& set_$ffdc_uc(const fapi2::variable_buffer& $param)\n";
+ $method_body = " {$ffdc_uc.ptr() = &i_value(); $ffdc_uc.size() = i_value.template getLength<uint8_t>(); return *this;}\n\n";
+
+ # No need to add the member here, it was added with fapi2::buffer. And we can't have variable
+ # buffer support with out integral buffer support (can we?)
+ }
+
+ elsif ($type eq $target_ffdc_type)
+ {
+ $method = "\n template< TargetType T >\n";
+ $method .= " inline $class_name& set_$ffdc_uc(const $type& $param)\n";
+ $method_body .= " {$ffdc_uc.ptr() = &i_value; $ffdc_uc.size() = fapi2::getErrorInfoFfdcSize(i_value); return *this;}\n\n";
+
+ $methods->{$key}{member} = "$ffdc_type $ffdc_uc;\n ";
+ }
+
+ else
+ {
+ print ("ffdc type $type is unknown");
+ exit(1);
+ }
+
+ $method .= ($arg_empty_ffdc eq undef) ? $method_body : " {return *this;}\n\n";
+ $methods->{$key}{method} = $method;
+}
+
+#------------------------------------------------------------------------------
+# Open output files for writing
+#------------------------------------------------------------------------------
+my $rcFile = $arg_output_dir;
+$rcFile .= "/";
+$rcFile .= "hwp_return_codes.H";
+open(RCFILE, ">", $rcFile);
+
+my $eiFile = $arg_output_dir;
+$eiFile .= "/";
+$eiFile .= "hwp_error_info.H";
+open(EIFILE, ">", $eiFile);
+
+my $ecFile = $arg_output_dir;
+$ecFile .= "/";
+$ecFile .= "hwp_ffdc_classes.H";
+open(ECFILE, ">", $ecFile);
+
+my $crFile = $arg_output_dir;
+$crFile .= "/";
+$crFile .= "collect_reg_ffdc.C";
+open(CRFILE, ">", $crFile);
+
+my $sbFile = $arg_output_dir;
+$sbFile .= "/";
+$sbFile .= "set_sbe_error.H";
+open(SBFILE, ">", $sbFile);
+
+#------------------------------------------------------------------------------
+# Print start of file information to hwp_error_info.H
+#------------------------------------------------------------------------------
+print EIFILE "// hwp_error_info.H\n";
+print EIFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print EIFILE "#ifndef FAPI2_HWPERRORINFO_H_\n";
+print EIFILE "#define FAPI2_HWPERRORINFO_H_\n\n";
+print EIFILE "#include <target.H>\n";
+print EIFILE "#include <plat_trace.H>\n";
+print EIFILE "#include <hwp_return_codes.H>\n";
+print EIFILE "#include <set_sbe_error.H>\n";
+print EIFILE "/**\n";
+print EIFILE " * \@brief Error Information macros and HwpFfdcId enumeration\n";
+print EIFILE " *\/\n";
+
+#------------------------------------------------------------------------------
+# Print start of file information to hwp_ffdc_classes.H
+#------------------------------------------------------------------------------
+print ECFILE "// hwp_ffdc_classes.H\n";
+print ECFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print ECFILE "#ifndef FAPI2_HWP_FFDC_CLASSES_H_\n";
+print ECFILE "#define FAPI2_HWP_FFDC_CLASSES_H_\n\n";
+print ECFILE "#include <ffdc.H>\n";
+print ECFILE "#include <buffer.H>\n";
+print ECFILE "#include <variable_buffer.H>\n" if ($arg_use_variable_buffers ne undef);
+print ECFILE "#include <error_info.H>\n";
+print ECFILE "#include <utils.H>\n";
+print ECFILE "#include <hwp_error_info.H>\n";
+print ECFILE "#include <collect_reg_ffdc.H>\n";
+#print ECFILE "#include <proc_extract_sbe_rc.H>\n\n";
+print ECFILE "/**\n";
+print ECFILE " * \@brief FFDC gathering classes\n";
+print ECFILE " *\/\n";
+print ECFILE "namespace fapi2\n{\n";
+
+#------------------------------------------------------------------------------
+# Print start of file information to collectRegFfdc.C
+#------------------------------------------------------------------------------
+print CRFILE "// collect_reg_ffdc.C\n";
+print CRFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print CRFILE "#include <stdint.h>\n";
+print CRFILE "#include <vector>\n";
+
+print CRFILE "#include <buffer.H>\n";
+print CRFILE "#include <collect_reg_ffdc.H>\n";
+print CRFILE "#include <target.H>\n";
+print CRFILE "#include <return_code.H>\n";
+print CRFILE "#include <hw_access.H>\n";
+print CRFILE "#include <plat_trace.H>\n\n";
+
+print CRFILE "namespace fapi2\n";
+print CRFILE "{\n";
+print CRFILE "void collectRegFfdc(const fapi2::ffdc_t& i_target,\n";
+print CRFILE " const fapi2::HwpFfdcId i_ffdcId,\n";
+print CRFILE " fapi2::ReturnCode & o_rc,\n";
+print CRFILE " const TargetType i_child,\n";
+print CRFILE " const TargetType i_presChild,\n";
+print CRFILE " uint32_t i_childOffsetMult)\n";
+print CRFILE "{\n";
+print CRFILE " FAPI_INF(\"collectRegFfdc. FFDC ID: 0x%x\", i_ffdcId);\n";
+print CRFILE " fapi2::ReturnCode l_rc;\n";
+print CRFILE " fapi2::buffer<uint64_t> l_buf;\n";
+print CRFILE " uint32_t l_cfamData = 0;\n";
+print CRFILE " uint64_t l_scomData = 0;\n";
+print CRFILE " std::vector<uint32_t> l_cfamAddresses;\n";
+print CRFILE " std::vector<uint64_t> l_scomAddresses;\n";
+print CRFILE " uint32_t l_ffdcSize = 0;\n\n";
+print CRFILE " switch (i_ffdcId)\n";
+print CRFILE " {\n";
+print CRFILE " // void statments for the unused variables\n";
+print CRFILE " static_cast<void>(l_cfamData);\n";
+print CRFILE " static_cast<void>(l_scomData);\n";
+print CRFILE " static_cast<void>(l_ffdcSize);\n";
+print CRFILE " static_cast<const void>(i_target);\n";
+print CRFILE " static_cast<void>(o_rc);\n";
+print CRFILE " static_cast<void>(i_child);\n";
+print CRFILE " static_cast<void>(i_presChild);\n";
+print CRFILE " static_cast<void>(i_childOffsetMult);\n";
+#------------------------------------------------------------------------------
+# Print start of file information to setSbeError.H
+#------------------------------------------------------------------------------
+print SBFILE "// setSbeError.H\n";
+print SBFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n";
+print SBFILE "// When SBE code creates an error, it produces an error value\n";
+print SBFILE "// that matches a value in the HwpReturnCode enum in\n";
+print SBFILE "// fapiHwpReturnCodes.H. The SBE uses the __ASSEMBLER__\n";
+print SBFILE "// primitives in hwpReturnCodes.H to do this. The function\n";
+print SBFILE "// that extracts the error value from the SBE needs to call\n";
+print SBFILE "// FAPI_SET_HWP_ERROR to create the error and get all the\n";
+print SBFILE "// actions in the error XML file performed, but that macro can\n";
+print SBFILE "// only be called with the enumerator, not the value. This\n";
+print SBFILE "// FAPI_SET_SBE_ERROR macro can be called instead, it calls\n";
+print SBFILE "// FAPI_SET_HWP_ERROR with the correct error enumerator.\n";
+print SBFILE "// Errors containing <sbeError/> in their XML are supported\n";
+print SBFILE "// in this macro.\n\n";
+print SBFILE "// Note that it is expected that this macro will be called\n";
+print SBFILE "// in one place (the function that extracts the error from\n";
+print SBFILE "// the SBE), if this changes and it is called in multiple\n";
+print SBFILE "// places then the macro could be turned into a function to\n";
+print SBFILE "// avoid the code size increase of expanding the macro in\n";
+print SBFILE "// multiple places. The function approach is slightly more\n";
+print SBFILE "// complicated, there is an extra C file and the function\n";
+print SBFILE "// must take a parameter for the generic chip ID in the error\n";
+print SBFILE "// XML.\n\n";
+print SBFILE "#ifndef FAPI2_SETSBEERROR_H_\n";
+print SBFILE "#define FAPI2_SETSBEERROR_H_\n\n";
+print SBFILE "#define FAPI_SET_SBE_ERROR(RC, ERRVAL)\\\n";
+print SBFILE "{\\\n";
+print SBFILE "switch (ERRVAL)\\\n";
+print SBFILE "{\\\n";
+
+#------------------------------------------------------------------------------
+# For each XML file
+#------------------------------------------------------------------------------
+foreach my $argnum (0 .. $#ARGV)
+{
+ my $infile = $ARGV[$argnum];
+ my $count = 0;
+
+ #--------------------------------------------------------------------------
+ # Read XML file. The ForceArray option ensures that there is an array of
+ # elements even if there is only one element
+ #--------------------------------------------------------------------------
+ my $errors = $xml->XMLin($infile, ForceArray =>
+ ['hwpError', 'collectFfdc', 'ffdc', 'callout', 'deconfigure', 'gard',
+ 'registerFfdc', 'collectRegisterFfdc', 'cfamRegister', 'scomRegister',
+ 'id','collectTrace', 'buffer']);
+
+ # Uncomment to get debug output of all errors
+ #print "\nFile: ", $infile, "\n", Dumper($errors), "\n";
+
+ #--------------------------------------------------------------------------
+ # For each Error
+ #--------------------------------------------------------------------------
+ foreach my $err (@{$errors->{hwpError}})
+ {
+ # Hash of methods for the ffdc-gathering class
+ my %methods;
+
+ #----------------------------------------------------------------------
+ # Check that expected fields are present
+ #----------------------------------------------------------------------
+ if (! exists $err->{rc})
+ {
+ print ("parseErrorInfo.pl ERROR. rc missing\n");
+ exit(1);
+ }
+
+ if (! exists $err->{description})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. description missing\n");
+ exit(1);
+ }
+
+ #----------------------------------------------------------------------
+ # Check that this rc hasn't been deprecated
+ #----------------------------------------------------------------------
+ if ($deprecated{$err->{rc}} ne undef)
+ {
+ print "WARNING: $err->{rc} has been deprecated because $deprecated{$err->{rc}}\n";
+ next;
+ }
+
+ #----------------------------------------------------------------------
+ # Set the error enum value in a global hash
+ #---------------------------------------------------------------------
+ setErrorEnumValue($err->{rc});
+
+ #----------------------------------------------------------------------
+ # If this is an SBE error, add it to set_sbe_error.H
+ #----------------------------------------------------------------------
+ if (exists $err->{sbeError})
+ {
+ print SBFILE " case fapi2::$err->{rc}:\\\n";
+ print SBFILE " FAPI_SET_HWP_ERROR(RC, $err->{rc});\\\n";
+ print SBFILE " break;\\\n";
+ }
+
+ #----------------------------------------------------------------------
+ # Print the CALL_FUNCS_TO_COLLECT_FFDC macro to hwp_error_info.H
+ #----------------------------------------------------------------------
+ print EIFILE "#define $err->{rc}_CALL_FUNCS_TO_COLLECT_FFDC(RC) ";
+
+ # For now, this code is removed. It appears to work just fine but
+ # will require more of the fapi2 infrastructure to be in place.
+ # Because the ffdc collection classes create members with real types,
+ # the declarations of the types need to be visible - and they're not
+ # right now. When we get further along, we can enable this code.
+=begin NO_FFDC_COLLECT_HWP
+ $count = 0;
+
+ foreach my $collectFfdc (@{$err->{collectFfdc}})
+ {
+ if ($count == 0)
+ {
+ print EIFILE "{ fapi2::ReturnCode l_tempRc; ";
+ }
+ $count++;
+
+ print EIFILE "FAPI_EXEC_HWP(l_tempRc, $collectFfdc, RC); ";
+
+ # collectFfdc is a string we're going to stuff into FAPI_EXEC_HWP
+ # but we need to create the arguments in the ffdc class. The first
+ # element inthe collectFfdc string is the function to call.
+ my @elements = split /,/, $collectFfdc;
+ my @signature = @{$signatures{@elements[0]}};
+ for (my $i = 1; $i <= $#elements; $i++)
+ {
+ @elements[$i] =~ s/^\s+|\s+$//g;
+ addFfdcMethod(\%methods, @elements[$i], $err->{rc}, @signature[$i-1]);
+ }
+ }
+
+ if ($count > 0)
+ {
+ print EIFILE "}";
+ }
+=cut NO_FFDC_COLLECT_HWP
+ print EIFILE "\n";
+
+ #----------------------------------------------------------------------
+ # Print the CALL_FUNCS_TO_COLLECT_REG_FFDC macro to hwp_error_info.H
+ #----------------------------------------------------------------------
+ print EIFILE "#define $err->{rc}_CALL_FUNCS_TO_COLLECT_REG_FFDC(RC) ";
+
+ foreach my $collectRegisterFfdc (@{$err->{collectRegisterFfdc}})
+ {
+ #------------------------------------------------------------------
+ # Check that expected fields are present
+ #------------------------------------------------------------------
+ if (! exists $collectRegisterFfdc->{id}[0])
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. id(s) missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ foreach my $id (@{$collectRegisterFfdc->{id}})
+ {
+ #---------------------------------------------------------------------------------
+ # Check FFDC register collection type: target, child, or based on present children
+ #---------------------------------------------------------------------------------
+ if (exists $collectRegisterFfdc->{target})
+ {
+ print EIFILE "fapi2::collectRegFfdc($collectRegisterFfdc->{target}, ";
+ print EIFILE "fapi2::$id, RC, fapi2::TARGET_TYPE_NONE, fapi2::TARGET_TYPE_NONE); ";
+ addFfdcMethod(\%methods, $collectRegisterFfdc->{target},
+ $err->{rc}, $target_ffdc_type);
+ }
+ elsif (exists $collectRegisterFfdc->{childTargets})
+ {
+ if (! exists $collectRegisterFfdc->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR: parent missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ if (! exists $collectRegisterFfdc->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR: childType missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ print EIFILE "fapi2::collectRegFfdc($collectRegisterFfdc->{childTargets}->{parent}, fapi2::$id, ";
+ print EIFILE "RC, fapi2::$collectRegisterFfdc->{childTargets}->{childType}, fapi2::TARGET_TYPE_NONE); ";
+ addFfdcMethod(\%methods, $collectRegisterFfdc->{childTargets}->{parent},
+ $err->{rc}, $target_ffdc_type);
+ }
+ elsif (exists $collectRegisterFfdc->{basedOnPresentChildren})
+ {
+ if (! exists $collectRegisterFfdc->{basedOnPresentChildren}->{target})
+ {
+ print ("parseErrorInfo.pl ERROR: target missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ if (! exists $collectRegisterFfdc->{basedOnPresentChildren}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR: childType missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ if (! exists $collectRegisterFfdc->{basedOnPresentChildren}->{childPosOffsetMultiplier})
+ {
+ print ("parseErrorInfo.pl ERROR: childPosOffsetMultiplier missing from collectRegisterFfdc\n");
+ exit(1);
+ }
+ print EIFILE "fapi2::collectRegFfdc($collectRegisterFfdc->{basedOnPresentChildren}->{target}, fapi2::$id, RC, ";
+ print EIFILE "fapi2::TARGET_TYPE_NONE, fapi2::$collectRegisterFfdc->{basedOnPresentChildren}->{childType}, ";
+ print EIFILE "$collectRegisterFfdc->{basedOnPresentChildren}->{childPosOffsetMultiplier}); ";
+ addFfdcMethod(\%methods, $collectRegisterFfdc->{basedOnPresentChildren}->{target},
+ $err->{rc}, $target_ffdc_type);
+ }
+ else
+ {
+ print ("parseErrorInfo.pl ERROR: Invalid collectRegisterFfdc configuration\n");
+ exit(1);
+ }
+ }
+ }
+
+ print EIFILE "\n";
+
+ #----------------------------------------------------------------------
+ # Print the ADD_ERROR_INFO macro to hwp_error_info.H
+ #----------------------------------------------------------------------
+ print EIFILE "#define $err->{rc}_ADD_ERROR_INFO(RC) ";
+
+ # Array of EI Objects
+ my @eiObjects;
+
+ my $eiObjectStr = "const void * l_objects[] = {";
+ my $eiEntryStr = "";
+ my $eiEntryCount = 0;
+ my %cdgTargetHash; # Records the callout/deconfigure/gards for Targets
+ my %cdgChildHash; # Records the callout/deconfigure/gards for Children
+
+ # collect firmware trace
+ foreach my $collectTrace (@{$err->{collectTrace}})
+ {
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_COLLECT_TRACE; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].collect_trace.iv_eieTraceId = fapi2::CollectTraces::$collectTrace; \\\n";
+ $eiEntryCount++;
+ }
+
+ # Local FFDC
+ foreach my $ffdc (@{$err->{ffdc}})
+ {
+ # Set the FFDC ID value in a global hash. The name is <rc>_<ffdc>
+ my $ffdcName = $err->{rc} . "_";
+ $ffdcName = $ffdcName . $ffdc;
+ setFfdcIdValue($ffdcName);
+
+ # Add the FFDC data to the EI Object array if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $ffdc);
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $ffdc, $err->{rc});
+
+ $ffdc = $mangle_names{$ffdc} if ($mangle_names{$ffdc} ne undef);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_FFDC; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcObjIndex = $objNum; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcId = fapi2::$ffdcName; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcSize = $ffdc.size(); \\\n";
+ $eiEntryCount++;
+ }
+
+ # Buffers, looks a lot like local ffdc
+ foreach my $buffer (@{$err->{buffer}})
+ {
+ # Set the FFDC ID value in a global hash. The name is <rc>_<ffdc>
+ my $bufferName = $err->{rc} . "_";
+ $bufferName = $bufferName . $buffer;
+ setFfdcIdValue($bufferName);
+
+ # Add the FFDC data to the EI Object array if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $buffer);
+
+ # Add a method to the ffdc-gathering class - one for each buffer type
+ addFfdcMethod(\%methods, $buffer, $err->{rc}, $buffer_ffdc_type);
+ addFfdcMethod(\%methods, $buffer, $err->{rc}, $variable_buffer_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_FFDC; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcObjIndex = $objNum; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcId = fapi2::$bufferName; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcSize = fapi2::getErrorInfoFfdcSize($buffer); \\\n";
+ $eiEntryCount++;
+ }
+
+ # Procedure/Target/Bus/Child callouts
+ foreach my $callout (@{$err->{callout}})
+ {
+ if (! exists $callout->{priority})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout priority missing\n");
+ exit(1);
+ }
+
+ my $elementsFound = 0;
+ if (exists $callout->{hw})
+ {
+ # HW Callout
+ if (! exists $callout->{hw}->{hwid})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. HW Callout hwid missing\n");
+ exit(1);
+ }
+
+ # Check that those HW callouts that need reference targets have them
+ if (($callout->{hw}->{hwid} eq "TOD_CLOCK") ||
+ ($callout->{hw}->{hwid} eq "MEM_REF_CLOCK") ||
+ ($callout->{hw}->{hwid} eq "PROC_REF_CLOCK") ||
+ ($callout->{hw}->{hwid} eq "PCI_REF_CLOCK"))
+ {
+ if (! exists $callout->{hw}->{refTarget})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout missing refTarget\n");
+ exit(1);
+ }
+ }
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_HW_CALLOUT; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_hw = fapi2::HwCallouts::$callout->{hw}->{hwid}; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_calloutPriority = fapi2::CalloutPriorities::$callout->{priority}; \\\n";
+ if (exists $callout->{hw}->{refTarget})
+ {
+ # Add the Targets to the objectlist if they don't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $callout->{hw}->{refTarget});
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_refObjIndex = $objNum; \\\n";
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $callout->{hw}->{refTarget}, $err->{rc});
+ }
+ else
+ {
+ $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_refObjIndex = 0xff; \\\n";
+ }
+ $eiEntryCount++;
+ $elementsFound++;
+ }
+ if (exists $callout->{procedure})
+ {
+ # Procedure Callout
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_PROCEDURE_CALLOUT; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].proc_callout.iv_procedure = fapi2::ProcedureCallouts::$callout->{procedure}; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].proc_callout.iv_calloutPriority = fapi2::CalloutPriorities::$callout->{priority}; \\\n";
+ $eiEntryCount++;
+ $elementsFound++;
+ }
+ if (exists $callout->{bus})
+ {
+ # A Bus Callout consists of two targets separated by
+ # commas/spaces
+ my @targets = split(/\s*,\s*|\s+/, $callout->{bus});
+
+ if (scalar @targets != 2)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. did not find two targets in bus callout\n");
+ exit(1);
+ }
+
+ # Add the Targets to the objectlist if they don't already exist
+ my $objNum1 = addEntryToArray(\@eiObjects, $targets[0]);
+
+ my $objNum2 = addEntryToArray(\@eiObjects, $targets[1]);
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $targets[0], $err->{rc}, $target_ffdc_type);
+ addFfdcMethod(\%methods, $targets[1], $err->{rc}, $target_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_BUS_CALLOUT; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].bus_callout.iv_endpoint1ObjIndex = $objNum1; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].bus_callout.iv_endpoint2ObjIndex = $objNum2; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].bus_callout.iv_calloutPriority = fapi2::CalloutPriorities::$callout->{priority}; \\\n";
+ $eiEntryCount++;
+ $elementsFound++;
+ }
+ if (exists $callout->{target})
+ {
+ # Add the Target to cdgTargetHash to be processed with any
+ # deconfigure and GARD requests
+ $cdgTargetHash{$callout->{target}}{callout} = 1;
+ $cdgTargetHash{$callout->{target}}{priority} =
+ $callout->{priority};
+
+ $elementsFound++;
+ }
+ if (exists $callout->{childTargets})
+ {
+ # Check that the parent and childType subelements exist
+ if (! exists $callout->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Callout parent missing\n");
+ exit(1);
+ }
+
+ if (! exists $callout->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Callout childType missing\n");
+ exit(1);
+ }
+
+ # Add the child info to cdgChildHash to be processed with
+ # any deconfigure and GARD requests
+ my $parent = $callout->{childTargets}->{parent};
+ my $childType = $callout->{childTargets}->{childType};
+ $cdgChildHash{$parent}{$childType}{callout} = 1;
+ $cdgChildHash{$parent}{$childType}{priority} =
+ $callout->{priority};
+
+ $elementsFound++;
+
+ if (exists $callout->{childTargets}->{childPort})
+ {
+ my $childPort = $callout->{childTargets}->{childPort};
+
+ $cdgChildHash{$parent}{$childType}{childPort} = $childPort;
+ }
+
+ if (exists $callout->{childTargets}->{childNumber})
+ {
+ my $childNum = $callout->{childTargets}->{childNumber};
+ $cdgChildHash{$parent}{$childType}{childNumber} = $childNum;
+ }
+
+ }
+ if ($elementsFound == 0)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout incomplete\n");
+ exit(1);
+ }
+ elsif ($elementsFound > 1)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout has multiple elements\n");
+ exit(1);
+ }
+ } # callout
+
+ # Target/Child deconfigures
+ foreach my $deconfigure (@{$err->{deconfigure}})
+ {
+ my $elementsFound = 0;
+ if (exists $deconfigure->{target})
+ {
+ # Add the Target to cdgTargetHash to be processed with any
+ # callout and GARD requests
+ $cdgTargetHash{$deconfigure->{target}}{deconf} = 1;
+ $elementsFound++;
+ }
+ if (exists $deconfigure->{childTargets})
+ {
+ # Check that the parent and childType subelements exist
+ if (! exists $deconfigure->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Deconfigure parent missing\n");
+ exit(1);
+ }
+ if (! exists $deconfigure->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Deconfigure childType missing\n");
+ exit(1);
+ }
+
+ # Add the child info to cdgChildHash to be processed with
+ # any callout and GARD requests
+ my $parent = $deconfigure->{childTargets}->{parent};
+ my $childType = $deconfigure->{childTargets}->{childType};
+ $cdgChildHash{$parent}{$childType}{deconf} = 1;
+
+ $elementsFound++;
+
+ if ( exists $deconfigure->{childTargets}->{childPort})
+ {
+ my $childPort = $deconfigure->{childTargets}->{childPort};
+
+ $cdgChildHash{$parent}{$childType}{childPort} = $childPort;
+ }
+
+ if ( exists $deconfigure->{childTargets}->{childNumber})
+ {
+ my $childNum = $deconfigure->{childTargets}->{childNumber};
+ $cdgChildHash{$parent}{$childType}{childNumber} = $childNum;
+
+ }
+ }
+ if ($elementsFound == 0)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Deconfigure incomplete\n");
+ exit(1);
+ }
+ elsif ($elementsFound > 1)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Deconfigure has multiple elements\n");
+ exit(1);
+ }
+ } # deconfigure
+
+ # Target/Child Gards
+ foreach my $gard (@{$err->{gard}})
+ {
+ my $elementsFound = 0;
+ if (exists $gard->{target})
+ {
+ # Add the Target to cdgTargetHash to be processed with any
+ # callout and deconfigure requests
+ $cdgTargetHash{$gard->{target}}{gard} = 1;
+ $elementsFound++;
+ }
+ if (exists $gard->{childTargets})
+ {
+ # Check that the parent and childType subelements exist
+ if (! exists $gard->{childTargets}->{parent})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child GARD parent missing\n");
+ exit(1);
+ }
+ if (! exists $gard->{childTargets}->{childType})
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. Child GARD childType missing\n");
+ exit(1);
+ }
+
+ # Add the child info to cdgChildHash to be processed with
+ # any callout and deconfigure requests
+ my $parent = $gard->{childTargets}->{parent};
+ my $childType = $gard->{childTargets}->{childType};
+ $cdgChildHash{$parent}{$childType}{gard} = 1;
+
+ $elementsFound++;
+
+ if ( exists $gard->{childTargets}->{childPort})
+ {
+ my $childPort = $gard->{childTargets}->{childPort};
+
+ $cdgChildHash{$parent}{$childType}{childPort} = $childPort;
+
+ }
+
+ if ( exists $gard->{childTargets}->{childNumber})
+ {
+ my $childNum = $gard->{childTargets}->{childNumber};
+ $cdgChildHash{$parent}{$childType}{childNumber} = $childNum;
+ }
+ }
+ if ($elementsFound == 0)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. GARD incomplete\n");
+ exit(1);
+ }
+ elsif ($elementsFound > 1)
+ {
+ print ("parseErrorInfo.pl ERROR in $err->{rc}. GARD has multiple elements\n");
+ exit(1);
+ }
+ } # gard
+
+ # Process the callout, deconfigures and GARDs for each Target
+ foreach my $cdg (keys %cdgTargetHash)
+ {
+ my $callout = 0;
+ my $priority = 'LOW';
+ my $deconf = 0;
+ my $gard = 0;
+
+ if (exists $cdgTargetHash{$cdg}->{callout})
+ {
+ $callout = 1;
+ }
+ if (exists $cdgTargetHash{$cdg}->{priority})
+ {
+ $priority = $cdgTargetHash{$cdg}->{priority};
+ }
+ if (exists $cdgTargetHash{$cdg}->{deconf})
+ {
+ $deconf = 1;
+ }
+ if (exists $cdgTargetHash{$cdg}->{gard})
+ {
+ $gard = 1;
+ }
+
+ # Add the Target to the objectlist if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $cdg);
+
+ # Add a method to the ffdc-gathering class
+ addFfdcMethod(\%methods, $cdg, $err->{rc}, $target_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_CDG; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_targetObjIndex = $objNum; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_callout = $callout; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_deconfigure = $deconf; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_gard = $gard; \\\n";
+ $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_calloutPriority = fapi2::CalloutPriorities::$priority; \\\n";
+ $eiEntryCount++;
+ }
+
+ # Process the callout, deconfigures and GARDs for Child Targets
+ foreach my $parent (keys %cdgChildHash)
+ {
+ foreach my $childType (keys %{$cdgChildHash{$parent}})
+ {
+ my $callout = 0;
+ my $priority = 'LOW';
+ my $deconf = 0;
+ my $gard = 0;
+ my $childPort = 0xFF;
+ my $childNumber = 0xFF;
+
+ if (exists $cdgChildHash{$parent}{$childType}->{callout})
+ {
+ $callout = 1;
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{priority})
+ {
+ $priority =
+ $cdgChildHash{$parent}->{$childType}->{priority};
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{deconf})
+ {
+ $deconf = 1;
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{childPort})
+ {
+ $childPort =
+ $cdgChildHash{$parent}->{$childType}->{childPort} ;
+ addFfdcMethod(\%methods, $childPort, $err->{rc});
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{childNumber})
+ {
+ $childNumber =
+ $cdgChildHash{$parent}->{$childType}->{childNumber} ;
+ addFfdcMethod(\%methods, $childNumber, $err->{rc});
+ }
+ if (exists $cdgChildHash{$parent}->{$childType}->{gard})
+ {
+ $gard = 1;
+ }
+
+
+ # Add the Target to the objectlist if it doesn't already exist
+ my $objNum = addEntryToArray(\@eiObjects, $parent);
+ addFfdcMethod(\%methods, $parent, $err->{rc}, $target_ffdc_type);
+
+ # Add an EI entry to eiEntryStr
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_CHILDREN_CDG; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_parentObjIndex = $objNum; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_callout = $callout; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_deconfigure = $deconf; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_childType = fapi2::$childType; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_childPort = $childPort; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_childNumber = $childNumber; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_gard = $gard; \\\n";
+ $eiEntryStr .=
+ " l_entries[$eiEntryCount].children_cdg.iv_calloutPriority = fapi2::CalloutPriorities::$priority; \\\n";
+ $eiEntryCount++;
+ }
+ }
+
+ # Add all objects to $eiObjectStr
+ my $objCount = 0;
+
+ foreach my $eiObject (@eiObjects)
+ {
+ if ($objCount > 0)
+ {
+ $eiObjectStr .= ", ";
+ }
+
+ if ($mangle_names{$eiObject} eq undef)
+ {
+ $eiObjectStr .= "$eiObject"
+ }
+ else
+ {
+ $eiObjectStr .= $mangle_names{$eiObject};
+ }
+
+ $objCount++;
+ }
+ $eiObjectStr .= "};";
+
+ # Print info to file
+ if ($eiEntryCount > 0)
+ {
+ print EIFILE "\\\n{ \\\n $eiObjectStr \\\n";
+ print EIFILE " fapi2::ErrorInfoEntry l_entries[$eiEntryCount]; \\\n";
+ print EIFILE "$eiEntryStr";
+ print EIFILE " RC.addErrorInfo(l_objects, l_entries, $eiEntryCount); \\\n}";
+ }
+
+ print EIFILE "\n";
+
+ #----------------------------------------------------------------------
+ # Print the return code class to hwp_error_info.H
+ #----------------------------------------------------------------------
+ # Remove the repeated whitespace and newlines other characters from the description
+ $err->{description} =~ s/^\s+|\s+$|"//g;
+ $err->{description} =~ tr{\n}{ };
+ $err->{description} =~ s/\h+/ /g;
+
+ #----------------------------------------------------------------------
+ # Print the return code class to hwp_error_info.H
+ #----------------------------------------------------------------------
+ my $class_name = $err->{rc};
+ # Remove everything upto and including the first _. This makes the ffdc class
+ # names different from the error code value enum names.
+ $class_name = (split (/_/, $class_name, 2))[1];
+
+ # Class declaration
+ print ECFILE "\nclass $class_name\n{\n public:\n";
+
+ # Constructor. This traces the description. If this is too much, we can
+ # remove it.
+ if ($arg_empty_ffdc eq undef)
+ {
+ print ECFILE " $class_name(fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE, fapi2::ReturnCode& i_rc = fapi2::current_err):\n";
+ print ECFILE " iv_rc(i_rc),\n";
+ print ECFILE " iv_sev(i_sev)\n";
+ print ECFILE " { FAPI_ERR(\"$err->{description}\"); }\n";
+ }
+ else
+ {
+ # Void expression keeps the compiler from complaining about the unused arguments.
+ # We want to set the i_rc to the RC if we're empty. This otherwise gets done in _setHwpError()
+ print ECFILE " $class_name(fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE, fapi2::ReturnCode& i_rc = fapi2::current_err)\n";
+ print ECFILE " {\n";
+ print ECFILE " static_cast<void>(i_sev);\n";
+ print ECFILE " i_rc = $err->{rc};\n";
+ print ECFILE " }\n\n";
+ }
+
+ # Methods
+ foreach my $key (keys %methods)
+ {
+ print ECFILE $methods{$key}{method};
+ }
+
+ # Stick the execute method at the end of the other methods. We allow
+ # passing in of the severity so that macros which call execute() can over-ride
+ # the default severity.
+ print ECFILE " void execute(fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNDEFINED)\n";
+ if ($arg_empty_ffdc eq undef)
+ {
+ print ECFILE " {\n";
+ print ECFILE " FAPI_SET_HWP_ERROR(iv_rc, $err->{rc});\n";
+ print ECFILE " fapi2::logError(iv_rc, (i_sev == fapi2::FAPI2_ERRL_SEV_UNDEFINED) ? iv_sev : i_sev);\n";
+ print ECFILE " }\n\n";
+ }
+ else
+ {
+ print ECFILE " {\n";
+ print ECFILE " static_cast<void>(i_sev);\n";
+ print ECFILE " }\n\n";
+ }
+
+ # Instance variables
+ if ($arg_empty_ffdc eq undef)
+ {
+ print ECFILE " private:\n ";
+ foreach my $key (keys %methods)
+ {
+ print ECFILE $methods{$key}{member};
+ }
+
+ print ECFILE "fapi2::ReturnCode& iv_rc;\n";
+ print ECFILE " fapi2::errlSeverity_t iv_sev;\n";
+ }
+
+ print ECFILE "};\n\n\n\n";
+ }
+
+ #--------------------------------------------------------------------------
+ # For each registerFfdc.
+ #--------------------------------------------------------------------------
+ foreach my $registerFfdc (@{$errors->{registerFfdc}})
+ {
+ #----------------------------------------------------------------------
+ # Check that expected fields are present
+ #----------------------------------------------------------------------
+ if (! exists $registerFfdc->{id}[0])
+ {
+ print ("parseErrorInfo.pl ERROR. id missing from registerFfdc\n");
+ exit(1);
+ }
+
+ if (scalar @{$registerFfdc->{id}} > 1)
+ {
+ print ("parseErrorInfo.pl ERROR. multiple ids in registerFfdc\n");
+ exit(1);
+ }
+
+ #----------------------------------------------------------------------
+ # Set the FFDC ID value in a global hash
+ #----------------------------------------------------------------------
+ setFfdcIdValue($registerFfdc->{id}[0]);
+
+ #----------------------------------------------------------------------
+ # Generate code to capture the registers in collect_reg_ffdc.C
+ #----------------------------------------------------------------------
+ print CRFILE " case $registerFfdc->{id}[0]:\n";
+
+=begin NEED_P9_REGISTERS
+ # Look for CFAM Register addresses
+ foreach my $cfamRegister (@{$registerFfdc->{cfamRegister}})
+ {
+ print CRFILE " l_cfamAddresses.push_back($cfamRegister);\n";
+ print CRFILE " l_ffdcSize += sizeof(l_cfamData);\n";
+ }
+
+ # Look for SCOM Register addresses
+ foreach my $scomRegister (@{$registerFfdc->{scomRegister}})
+ {
+ print CRFILE " l_scomAddresses.push_back($scomRegister);\n";
+ print CRFILE " l_ffdcSize += sizeof(l_scomData);\n";
+ }
+=cut NEED_P9_REGISTERS
+
+ print CRFILE " break;\n";
+ }
+
+}
+
+#------------------------------------------------------------------------------
+# Print end of file information to collect_reg_ffdc.C
+#------------------------------------------------------------------------------
+print CRFILE " default:\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Invalid FFDC ID 0x%x\", ";
+print CRFILE "i_ffdcId);\n";
+print CRFILE " return;\n";
+print CRFILE " }\n\n";
+
+=begin NEED_P9_REGISTERS
+
+print CRFILE " uint8_t * l_pBuf = NULL;\n";
+print CRFILE " uint8_t * l_pData = NULL;\n";
+print CRFILE " std::vector<fapi::Target> l_targets;\n";
+print CRFILE " uint32_t l_chipletPos32 = 0;\n";
+#---------------------------------------------------------------------------------------------------------
+# Populate chiplet vectors (if required by register collection method) and adjust buffer sizes accordingly
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " if (fapi2::TARGET_TYPE_NONE != i_child)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetChildChiplets(i_target, i_child, l_targets, TARGET_STATE_FUNCTIONAL);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error: fapiGetChildChiplets: failed to get chiplets.\");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " if (l_targets.empty())\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_INF(\"collect_reg_ffdc.C: Error: No functional chiplets found. \");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " l_ffdcSize += sizeof(l_chipletPos32);\n";
+print CRFILE " l_ffdcSize *= l_targets.size();\n";
+print CRFILE " l_pBuf = new uint8_t[l_ffdcSize];\n";
+print CRFILE " l_pData = l_pBuf;\n";
+print CRFILE " }\n";
+print CRFILE " else if (fapi2::TARGET_TYPE_NONE != i_presChild)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetChildChiplets(i_target, i_presChild, l_targets, TARGET_STATE_PRESENT);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error: fapiGetChildChiplets: failed to get chiplets.\");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " if (l_targets.empty())\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_INF(\"collect_reg_ffdc.C: Error: No functional chiplets found. \");\n";
+print CRFILE " return;\n";
+print CRFILE " }\n";
+print CRFILE " l_ffdcSize += sizeof(l_chipletPos32);\n";
+print CRFILE " l_ffdcSize *= l_targets.size();\n";
+print CRFILE " l_pBuf = new uint8_t[l_ffdcSize];\n";
+print CRFILE " l_pData = l_pBuf;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_ffdcSize += sizeof(l_chipletPos32);\n";
+print CRFILE " l_pBuf = new uint8_t[l_ffdcSize];\n";
+print CRFILE " l_pData = l_pBuf;\n";
+print CRFILE " l_targets.push_back(i_target);\n";
+print CRFILE " }\n\n";
+#---------------------------------------------------------------------------------------------------------
+# Obtain target position and insert as the first word in the buffer
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " bool l_targIsChiplet = i_target.isChiplet();\n\n";
+print CRFILE " for (std::vector<fapi::Target>::const_iterator targetIter = l_targets.begin();\n";
+print CRFILE " targetIter != l_targets.end(); ++targetIter)\n";
+print CRFILE " {\n";
+print CRFILE " if ((fapi2::TARGET_TYPE_NONE != i_child) ||\n";
+print CRFILE " (fapi2::TARGET_TYPE_NONE != i_presChild) ||\n";
+print CRFILE " (true == l_targIsChiplet))\n";
+print CRFILE " {\n";
+print CRFILE " uint8_t l_chipletPos = 0;\n";
+print CRFILE " l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &(*targetIter), l_chipletPos);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error getting chiplet position\");\n";
+print CRFILE " l_chipletPos = 0xFF;\n";
+print CRFILE " }\n";
+ #-------------------------------------------------------------------------
+ # We print the target's position in the error log whether the target is a
+ # chip or chiplet, so we need to store the chiplet position in a uint32_t
+ # to have consitency in the buffer as ATTR_POS below returns a uint32_t
+ #-------------------------------------------------------------------------
+print CRFILE " l_chipletPos32 = l_chipletPos;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = FAPI_ATTR_GET(ATTR_POS, &(*targetIter), l_chipletPos32);\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error getting chip position\");\n";
+print CRFILE " l_chipletPos32 = 0xFFFFFFFF;\n";
+print CRFILE " }\n";
+print CRFILE " }\n";
+print CRFILE " *(reinterpret_cast<uint32_t *>(l_pData)) = l_chipletPos32;\n";
+print CRFILE " l_pData += sizeof(l_chipletPos32);\n";
+#---------------------------------------------------------------------------------------------------------
+# Instert cfam data (if any) related to this chip / chiplet into the buffer
+# If collecting FFDC based on present children, adjust the register address by the appropriate offset
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " for (std::vector<uint32_t>::const_iterator cfamIter = l_cfamAddresses.begin();\n";
+print CRFILE " cfamIter != l_cfamAddresses.end(); ++cfamIter)\n";
+print CRFILE " {\n";
+print CRFILE " if (fapi2::TARGET_TYPE_NONE != i_presChild)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetCfamRegister(i_target, (*cfamIter + (l_chipletPos32 * i_childOffsetMult)), l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetCfamRegister(*targetIter, *cfamIter, l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: CFAM error for 0x%x\",";
+print CRFILE "*cfamIter);\n";
+print CRFILE " l_cfamData = 0xbaddbadd;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_cfamData = l_buf.getWord(0);\n";
+print CRFILE " }\n";
+print CRFILE " *(reinterpret_cast<uint32_t *>(l_pData)) = l_cfamData;\n";
+print CRFILE " l_pData += sizeof(l_cfamData);\n";
+print CRFILE " }\n\n";
+#---------------------------------------------------------------------------------------------------------
+# Instert any scom data (if any) related to this chip / chiplet into the buffer
+# If collecting FFDC based on present children, adjust the register address by the appropriate offset
+#---------------------------------------------------------------------------------------------------------
+print CRFILE " for (std::vector<uint64_t>::const_iterator scomIter = l_scomAddresses.begin();\n";
+print CRFILE " scomIter != l_scomAddresses.end(); ++scomIter)\n";
+print CRFILE " {\n";
+print CRFILE " if (fapi2::TARGET_TYPE_NONE != i_presChild)\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetScom(i_target, (*scomIter + (l_chipletPos32 * i_childOffsetMult)), l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_rc = fapiGetScom(*targetIter, *scomIter, l_buf);\n";
+print CRFILE " }\n";
+print CRFILE " if (l_rc)\n";
+print CRFILE " {\n";
+print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: SCOM error for 0x%llx\",";
+print CRFILE "*scomIter);\n";
+print CRFILE " l_scomData = 0xbaddbaddbaddbaddULL;\n";
+print CRFILE " }\n";
+print CRFILE " else\n";
+print CRFILE " {\n";
+print CRFILE " l_scomData = l_buf.getDoubleWord(0);\n";
+print CRFILE " }\n";
+print CRFILE " *(reinterpret_cast<uint64_t *>(l_pData)) = l_scomData;\n";
+print CRFILE " l_pData += sizeof(l_scomData);\n";
+print CRFILE " }\n";
+print CRFILE " }\n\n";
+print CRFILE " o_rc.addEIFfdc(i_ffdcId, l_pBuf, l_ffdcSize);\n";
+print CRFILE " delete [] l_pBuf;\n";
+=cut NEED_P9_REGISTERS
+
+print CRFILE "}\n";
+print CRFILE "}\n";
+
+
+#------------------------------------------------------------------------------
+# Print the fapiHwpReturnCodes.H file
+#------------------------------------------------------------------------------
+print RCFILE "// fapiHwpReturnCodes.H\n";
+print RCFILE "// This file is generated by perl script parseErrorInfo.pl\n\n";
+print RCFILE "#ifndef FAPI2_HWPRETURNCODES_H_\n";
+print RCFILE "#define FAPI2_HWPRETURNCODES_H_\n\n";
+print RCFILE "#ifndef __ASSEMBLER__\n";
+print RCFILE "namespace fapi2\n";
+print RCFILE "{\n\n";
+print RCFILE "/**\n";
+print RCFILE " * \@brief Enumeration of HWP return codes\n";
+print RCFILE " *\/\n";
+print RCFILE "enum HwpReturnCode\n";
+print RCFILE "{\n";
+foreach my $key (keys %errNameToValueHash)
+{
+ print RCFILE " $key = 0x$errNameToValueHash{$key},\n";
+}
+print RCFILE "};\n\n";
+print RCFILE "}\n\n";
+print RCFILE "#else\n";
+foreach my $key (keys %errNameToValueHash)
+{
+ print RCFILE " .set $key, 0x$errNameToValueHash{$key}\n";
+}
+print RCFILE "#endif\n";
+print RCFILE "#endif\n";
+
+#------------------------------------------------------------------------------
+# Print the HwpFfdcId enumeration to hwp_error_info.H
+#------------------------------------------------------------------------------
+print EIFILE "namespace fapi2\n";
+print EIFILE "{\n\n";
+print EIFILE "/**\n";
+print EIFILE " * \@brief Enumeration of FFDC identifiers\n";
+print EIFILE " *\/\n";
+print EIFILE "enum HwpFfdcId\n";
+print EIFILE "{\n";
+foreach my $key (keys %ffdcNameToValueHash)
+{
+ print EIFILE " $key = 0x$ffdcNameToValueHash{$key},\n";
+}
+print EIFILE "};\n\n";
+print EIFILE "}\n\n";
+
+#------------------------------------------------------------------------------
+# Print end of file information to hwp_error_info.H
+#------------------------------------------------------------------------------
+print EIFILE "\n\n#endif\n";
+
+#------------------------------------------------------------------------------
+# Print end of file information to hwp_ffdc_classes.H
+#------------------------------------------------------------------------------
+print ECFILE "\n};\n"; # close the namespace
+print ECFILE "\n\n#endif\n";
+
+#------------------------------------------------------------------------------
+# Print end of file information to set_sbe_error.H
+#------------------------------------------------------------------------------
+print SBFILE " default:\\\n";
+print SBFILE " FAPI_SET_HWP_ERROR(RC, RC_SBE_UNKNOWN_ERROR);\\\n";
+print SBFILE " break;\\\n";
+print SBFILE "}\\\n";
+print SBFILE "}\n\n";
+print SBFILE "#endif\n";
+
+#------------------------------------------------------------------------------
+# Close output files
+#------------------------------------------------------------------------------
+close(RCFILE);
+close(EIFILE);
+close(ECFILE);
+close(CRFILE);
+close(SBFILE);
OpenPOWER on IntegriCloud