summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/xip
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/chips/p9/xip')
-rw-r--r--src/import/chips/p9/xip/p9_xip_tool.C245
1 files changed, 155 insertions, 90 deletions
diff --git a/src/import/chips/p9/xip/p9_xip_tool.C b/src/import/chips/p9/xip/p9_xip_tool.C
index 04555105..069cb426 100644
--- a/src/import/chips/p9/xip/p9_xip_tool.C
+++ b/src/import/chips/p9/xip/p9_xip_tool.C
@@ -149,9 +149,16 @@ const char* g_usage =
"section of the image at the time it is deleted, or must be empty. The\n"
"'delete' command writes the size of the final modified image to stdout.\n"
"\n"
- "The 'dissect' command dissects the ring section named by the section argument\n"
- "and summarizes the content of the ring section. The second argument to\n"
- "'dissect', i.e. [table,short,normal(default),long,raw], specifies how much information\n"
+ "The 'dissect' command dissects a ring section. It accepts two different\n"
+ "types of images, namely the regular XIP image and now also stand-alone\n"
+ "ring section images (that have the TOR header). Wrt an XIP image, the\n"
+ "'dissect' command dissects the ring section named by the section argument.\n"
+ "Wrt a stand-alone ring section image, the 'dissect' command dissects\n"
+ "the ring section based on the TOR magic word embedded in the top of the\n"
+ "image. It does so regardless of what the section argument is (so for now\n"
+ "pass it .rings in this argument). In both cases, 'dissect' summarizes\n"
+ "the content of the ring section. The second argument to 'dissect', i.e.\n"
+ "[table,short,normal(default),long,raw], specifies how much information\n"
"is included in the listing:\n"
" table: Tabular overview.\n"
" short: The bare necessities.\n"
@@ -1751,9 +1758,7 @@ TEST(void* io_image, const int i_argc, const char** i_argv)
///
/// \param[in] i_ringSection A pointer to a TOR compliant ring section.
///
-/// \param[in] i_imageMagicNo The image's MAGIC number.
-///
-/// \param[in] i_listingModeId The listing mode: {table, short, normal(default), long, raw}.
+/// \param[in] i_listingModeId The listing mode: {table, short, normal(default), long}.
///
/// Assumptions:
/// - Dissection only works with .rings section. It does not work with .overrides
@@ -1761,13 +1766,14 @@ TEST(void* io_image, const int i_argc, const char** i_argv)
///
static
int dissectRingSectionTor( void* i_ringSection,
- uint64_t i_imageMagicNo,
uint8_t i_listingModeId )
{
int rc = 0;
uint32_t i;
- uint32_t numDdLevels;
- uint8_t iDdLevel, ddLevel;
+ uint32_t torMagic = 0xffffffff; // Undefined value
+ uint8_t chipType = 0xff; // Undefined value
+ uint32_t numDdLevels = 0; // Undefined value
+ uint8_t iDdLevel, ddLevel = 0xff; // Undefined value
uint8_t ppeType;
uint8_t ringId;
RingType_t ringType;
@@ -1789,6 +1795,33 @@ int dissectRingSectionTor( void* i_ringSection,
double comprRate;
uint8_t cmskRingIteration = 0;
char ringSuffix = ' ';
+ uint8_t* buf = (uint8_t*)i_ringSection;
+ TorHeader_t* torHeader = (TorHeader_t*)i_ringSection;
+ int offset = sizeof(TorHeader_t);
+ TorDdBlock_t* torDdBlock;
+
+ //
+ // Get TOR magic, chip type and DD level info from TOR header field
+ //
+ torMagic = be32toh(torHeader->magic);
+ chipType = torHeader->chipType;
+ ddLevel = torHeader->ddLevel;
+ numDdLevels = torHeader->numDdLevels;
+
+ fprintf(stdout, "---------------------------------\n");
+ fprintf(stdout, "* TOR header summary *\n");
+ fprintf(stdout, "---------------------------------\n");
+ fprintf(stdout, "TOR magic: 0x%4x=>%c%c%c%c\n", torMagic,
+ (uint8_t)(torMagic >> 24),
+ (uint8_t)(torMagic >> 16),
+ (uint8_t)(torMagic >> 8),
+ (uint8_t)(torMagic));
+ fprintf(stdout, "TOR version: %d\n", torHeader->version);
+ fprintf(stdout, "Chip type: %d=>%s\n", chipType, CHIP_TYPE_LIST[chipType].name);
+ fprintf(stdout, "DD level: 0x%x\n", ddLevel);
+ fprintf(stdout, "Num DD levels: %d\n", numDdLevels);
+ fprintf(stdout, "---------------------------------\n");
+ fprintf(stdout, "\n\n");
if (i_listingModeId != LMID_TABLE)
{
@@ -1802,20 +1835,6 @@ int dissectRingSectionTor( void* i_ringSection,
ringBlockSize = RING_BUF_SIZE_MAX;
ringBlockPtr = malloc(ringBlockSize);
- //
- // Get number of DD levels from TOR structure in ring section
- //
- if (i_imageMagicNo == P9_XIP_MAGIC_HW)
- {
- numDdLevels = htobe32( ( (TorNumDdLevels_t*)i_ringSection )->TorNumDdLevels );
- fprintf( stderr, "numDdLevels (=%d) read from top of ring section.\n", numDdLevels);
- }
- else
- {
- numDdLevels = 1;
- ddLevel = 0xff; // This means it's unknown.
- fprintf( stderr, "Image contains only one DD level set of rings.\n");
- }
if (i_listingModeId == LMID_TABLE)
{
@@ -1826,11 +1845,11 @@ int dissectRingSectionTor( void* i_ringSection,
// DD level loop.
for (iDdLevel = 0; iDdLevel < numDdLevels; iDdLevel++)
{
-
- if (i_imageMagicNo == P9_XIP_MAGIC_HW)
+ if (torMagic == TOR_MAGIC_HW)
{
- ddLevel = ( ( htobe32( ( ( (TorDdLevelBlock_t*)((uintptr_t)i_ringSection + sizeof(TorNumDdLevels_t)) ) +
- iDdLevel )->TorDdLevelAndOffset ) & 0xff000000 ) >> 24 );
+ torDdBlock = (TorDdBlock_t*)&buf[offset];
+ offset += sizeof(TorDdBlock_t);
+ ddLevel = torDdBlock->ddLevel;
}
//----------------
@@ -1839,9 +1858,10 @@ int dissectRingSectionTor( void* i_ringSection,
for (ppeType = 0; ppeType < NUM_PPE_TYPES; ppeType++)
{
- if ((i_imageMagicNo == P9_XIP_MAGIC_SGPE && ppeType != SGPE) ||
- (i_imageMagicNo == P9_XIP_MAGIC_CME && ppeType != CME) ||
- (i_imageMagicNo == P9_XIP_MAGIC_SEEPROM && ppeType != SBE))
+ if ((torMagic == TOR_MAGIC_SGPE && ppeType != SGPE) ||
+ (torMagic == TOR_MAGIC_CME && ppeType != CME) ||
+ (torMagic == TOR_MAGIC_SBE && ppeType != SBE) ||
+ (torMagic == TOR_MAGIC_OVRD && ppeType != SBE))
{
continue;
}
@@ -1849,8 +1869,13 @@ int dissectRingSectionTor( void* i_ringSection,
//--------------------
// Ring variant loop.
// - Base, cache, risk, override, overlay
- for (ringVariant = 0; ringVariant < OVERRIDE; ringVariant++)
+ for (ringVariant = 0; ringVariant <= OVERRIDE; ringVariant++)
{
+ if ((torMagic != TOR_MAGIC_OVRD && ringVariant == OVERRIDE) ||
+ (torMagic == TOR_MAGIC_OVRD && ringVariant != OVERRIDE))
+ {
+ continue;
+ }
//----------------------
// Unique ring ID loop.
@@ -1876,7 +1901,6 @@ int dissectRingSectionTor( void* i_ringSection,
ringBlockSize = RING_BUF_SIZE_MAX;
rc = tor_access_ring( i_ringSection,
- i_imageMagicNo,
(RingID)ringId,
ddLevel,
(PpeType_t)ppeType,
@@ -1894,12 +1918,25 @@ int dissectRingSectionTor( void* i_ringSection,
if (rc == TOR_RING_FOUND)
{
rs4 = (CompressedScanData*)ringBlockPtr;
- ringSize = be16toh(rs4->iv_size);
+
+ // Sanity check RS4 container's ringId matches the requested.
+ uint16_t l_ringId = be16toh(rs4->iv_ringId);
+
+ if ( l_ringId != ringId )
+ {
+ fprintf(stderr, "tor_access_ring() was successful and found a ring. But "
+ "RS4 header's iv_ringId(=0x%x) differs from requested ringId(=0x%x).\n",
+ l_ringId, ringId);
+ exit(1);
+ }
+
// Check ring block size.
+ ringSize = be16toh(rs4->iv_size);
+
if ( ringSize != ringBlockSize || ringSize == 0 )
{
- fprintf(stderr, "tor_access_ring() was successful and found a ring but "
+ fprintf(stderr, "tor_access_ring() was successful and found a ring. But "
"RS4 header's iv_size(=0x%04x) is either zero or doesn't match "
"size of ring buffer (ringBlockSize=0x%04x).\n",
ringSize, ringBlockSize);
@@ -2077,6 +2114,8 @@ int dissectRingSectionTor( void* i_ringSection,
}
else if (rc == TOR_RING_NOT_FOUND ||
rc == TOR_INVALID_INSTANCE_ID ||
+ rc == TOR_INVALID_CHIPLET ||
+ rc == TOR_INVALID_VARIANT ||
rc == TOR_AMBIGUOUS_API_PARMS ||
rc == TOR_INVALID_RING_ID)
{
@@ -2087,7 +2126,9 @@ int dissectRingSectionTor( void* i_ringSection,
else
{
fprintf(stderr, "tor_access_ring() returned error code rc=%d\n", rc);
- exit(1);
+ {
+ exit(1);
+ }
}
} // End of for(instanceId)
@@ -2154,60 +2195,101 @@ int dissectRingSection(void* i_image,
listingModeName = i_argv[1];
}
- p9_xip_translate_header(&hostHeader, (P9XipHeader*)i_image);
-
- // Determine P9-XIP ring section ID from the section name, e.g.
- // .rings => P9_XIP_SECTION_HW_RINGS
- if (strcmp(sectionName, ".rings") == 0)
+ // Determine whether i_image is an XIP image or an isolated TOR ring section image.
+ //
+ if (be64toh(((P9XipHeader*)i_image)->iv_magic) >> 32 == P9_XIP_MAGIC)
{
- if (hostHeader.iv_magic == P9_XIP_MAGIC_SEEPROM)
- {
- sectionId = P9_XIP_SECTION_SBE_RINGS;
- }
- else if (hostHeader.iv_magic == P9_XIP_MAGIC_HW)
+
+ p9_xip_translate_header(&hostHeader, (P9XipHeader*)i_image);
+
+ // Determine P9-XIP ring section ID from the section name, e.g.
+ // .rings => P9_XIP_SECTION_HW_RINGS
+ if (strcmp(sectionName, ".rings") == 0)
{
- sectionId = P9_XIP_SECTION_HW_RINGS;
+ if (hostHeader.iv_magic == P9_XIP_MAGIC_SEEPROM)
+ {
+ sectionId = P9_XIP_SECTION_SBE_RINGS;
+ }
+ else if (hostHeader.iv_magic == P9_XIP_MAGIC_HW)
+ {
+ sectionId = P9_XIP_SECTION_HW_RINGS;
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: .rings is not a valid section for image w/magic=0x%016lx\n",
+ hostHeader.iv_magic);
+ exit(1);
+ }
}
- else
+ else if (strcmp(sectionName, ".overrides") == 0)
{
- fprintf(stderr, "ERROR: .rings is not a valid section for image w/magic=0x%016lx\n",
- hostHeader.iv_magic);
- exit(1);
+ if (hostHeader.iv_magic == P9_XIP_MAGIC_SEEPROM)
+ {
+ sectionId = P9_XIP_SECTION_SBE_OVERRIDES;
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: .overrides is not a valid section for image w/magic=0x%016lx\n",
+ hostHeader.iv_magic);
+ exit(1);
+ }
}
- }
- else if (strcmp(sectionName, ".overrides") == 0)
- {
- if (hostHeader.iv_magic == P9_XIP_MAGIC_SEEPROM)
+ else if (strcmp(sectionName, ".overlays") == 0)
{
- sectionId = P9_XIP_SECTION_SBE_OVERRIDES;
+ if (hostHeader.iv_magic == P9_XIP_MAGIC_SEEPROM)
+ {
+ sectionId = P9_XIP_SECTION_SBE_OVERLAYS;
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: .overlays is not a valid section for image w/magic=0x%016lx\n",
+ hostHeader.iv_magic);
+ exit(1);
+ }
}
else
{
- fprintf(stderr, "ERROR: .overrides is not a valid section for image w/magic=0x%016lx\n",
- hostHeader.iv_magic);
+ fprintf(stderr, "ERROR : %s is an invalid ring section name.\n", sectionName);
+ fprintf(stderr, "Valid ring <section> names for the 'dissect' function are:\n");
+ fprintf(stderr, "\t.rings\n");
+ fprintf(stderr, "\t.overrides\n");
+ fprintf(stderr, "\t.overlays\n");
exit(1);
}
- }
- else if (strcmp(sectionName, ".overlays") == 0)
- {
- if (hostHeader.iv_magic == P9_XIP_MAGIC_SEEPROM)
+
+ // Get ring section.
+ //
+ rc = p9_xip_get_section( i_image, sectionId, &hostSection);
+
+ if (rc)
{
- sectionId = P9_XIP_SECTION_SBE_OVERLAYS;
+ fprintf( stderr, "p9_xip_get_section() failed : %s\n", P9_XIP_ERROR_STRING(g_errorStrings, rc));
+ return P9_XIP_DISASSEMBLER_ERROR;
}
- else
+
+ if (hostSection.iv_offset == 0)
{
- fprintf(stderr, "ERROR: .overlays is not a valid section for image w/magic=0x%016lx\n",
- hostHeader.iv_magic);
+ fprintf( stdout, "Ring section (w/ID=%d) is empty. Nothing to do. Quitting.\n", sectionId);
exit(1);
}
+
+ if (be32toh(((TorHeader_t*)i_image)->magic) >> 8 != TOR_MAGIC)
+ {
+ fprintf( stderr,
+ "ERROR: The XIP section is not a TOR compatible ring section. Possibly, the image is outdated and has the old TOR-headerless layout which is no longer supported. Try dissecting with an older version of p9_xip_tool.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ ringSectionPtr = (void*)(hostSection.iv_offset + (uintptr_t)i_image);
+
+ }
+ else if (be32toh(((TorHeader_t*)i_image)->magic) >> 8 == TOR_MAGIC)
+ {
+ ringSectionPtr = i_image;
}
else
{
- fprintf(stderr, "ERROR : %s is an invalid ring section name.\n", sectionName);
- fprintf(stderr, "Valid ring <section> names for the 'dissect' function are:\n");
- fprintf(stderr, "\t.rings\n");
- fprintf(stderr, "\t.overrides\n");
- fprintf(stderr, "\t.overlays\n");
+ fprintf(stderr, "ERROR : Input image is neither an XIP image nor an TOR ringSection image.\n");
exit(1);
}
@@ -2249,25 +2331,7 @@ int dissectRingSection(void* i_image,
exit(1);
}
- // Get ring section.
- //
- rc = p9_xip_get_section( i_image, sectionId, &hostSection);
-
- if (rc)
- {
- fprintf( stderr, "p9_xip_get_section() failed : %s\n", P9_XIP_ERROR_STRING(g_errorStrings, rc));
- return P9_XIP_DISASSEMBLER_ERROR;
- }
-
- if (hostSection.iv_offset == 0)
- {
- fprintf( stdout, "Ring section (w/ID=%d) is empty. Nothing to do. Quitting.\n", sectionId);
- exit(1);
- }
-
- ringSectionPtr = (void*)(hostSection.iv_offset + (uintptr_t)i_image);
-
- rc = dissectRingSectionTor(ringSectionPtr, hostHeader.iv_magic, listingModeId);
+ rc = dissectRingSectionTor(ringSectionPtr, listingModeId);
return rc;
@@ -2326,7 +2390,8 @@ openAndMap(const char* i_fileName, int i_writable, int* o_fd, void** o_image, co
exit(1);
}
- if ( !(i_maskIgnores & P9_XIP_IGNORE_ALL) )
+ if ( !(i_maskIgnores & P9_XIP_IGNORE_ALL) &&
+ (be64toh(((P9XipHeader*)o_image)->iv_magic) >> 32 == P9_XIP_MAGIC) )
{
rc = p9_xip_validate2(*o_image, g_imageSize, i_maskIgnores);
OpenPOWER on IntegriCloud