summaryrefslogtreecommitdiffstats
path: root/src/import/chips
diff options
context:
space:
mode:
authorRichard J. Knight <rjknight@us.ibm.com>2017-06-27 12:16:16 -0500
committerSachin Gupta <sgupta2m@in.ibm.com>2017-11-23 07:48:54 -0500
commit7f62dd04344bba5ea02d8d1d19328a6cd33bcb8c (patch)
treed81bdbe647f7dca593165465747b9b618247ec81 /src/import/chips
parent0bc318357fc86b96424414d6e52b9326d15c279a (diff)
downloadtalos-sbe-7f62dd04344bba5ea02d8d1d19328a6cd33bcb8c.tar.gz
talos-sbe-7f62dd04344bba5ea02d8d1d19328a6cd33bcb8c.zip
p9_xip_tool support for DD level section parsing
- Currently supports only .overlays section. - Fixed an heap problem causing segmentation fault after repetitive use of malloc in rs4_decompress() and rs4_extract_cmsk(). Now allocating buffers locally and calling _rs4_decompress() and _rs4_extract_cmsk() instead so only have to use malloc once. - Fixed a bug in the usage of the ringBlockPtr which got moved away from pointing to its initially allocated buffer after the first CMSK ring is processed. - Even though malloc() can be used in a C++ context, we really should be using the new() operator. So, I replaced all malloc() and free() with new() and delete() instead in both p9_xip_tool.C and p9_scan_compression.C. Change-Id: I2da7509ed7aaa13345185dc07bce57f71c3740fd Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/42531 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Richard J. Knight <rjknight@us.ibm.com> Reviewed-by: Sumit Kumar <sumit_kumar@in.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/42802 Reviewed-by: Hostboot Team <hostboot@us.ibm.com> Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Diffstat (limited to 'src/import/chips')
-rw-r--r--src/import/chips/p9/utils/imageProcs/p9_infrastruct_help.H4
-rw-r--r--src/import/chips/p9/utils/imageProcs/p9_scan_compression.H63
-rw-r--r--src/import/chips/p9/xip/p9_xip_tool.C480
3 files changed, 389 insertions, 158 deletions
diff --git a/src/import/chips/p9/utils/imageProcs/p9_infrastruct_help.H b/src/import/chips/p9/utils/imageProcs/p9_infrastruct_help.H
index 7fe0d072..2e54efc8 100644
--- a/src/import/chips/p9/utils/imageProcs/p9_infrastruct_help.H
+++ b/src/import/chips/p9/utils/imageProcs/p9_infrastruct_help.H
@@ -43,6 +43,10 @@ const uint32_t MAX_SEEPROM_IMAGE_SIZE = 4 * ((64 * 1024) / 9 * 8) -
256; // Max Seeprom image size, excl ECC bits (4 banks).
const uint32_t MAX_RT_IMAGE_SIZE = 1024 * 1024; // Max Runtime size.
const uint32_t MAX_RING_BUF_SIZE = 60000; // Max ring buffer size.
+const uint32_t MAX_RING_BUF_SIZE_TOOL = 200000; // Max ring buf size for tools.
+// (i.e., n3_fure.bin.srd is some
+// 346,000B x 4b/B = 1,384,000b =
+// 173,000B binary w 8b/B)
const uint32_t MAX_OVERRIDES_SIZE = 2 * 1024; // Max overrides section size.
const uint32_t MAX_HBBL_SIZE = 20 * 1024; // Max hbbl section size.
diff --git a/src/import/chips/p9/utils/imageProcs/p9_scan_compression.H b/src/import/chips/p9/utils/imageProcs/p9_scan_compression.H
index ec5710e6..f04cdb7f 100644
--- a/src/import/chips/p9/utils/imageProcs/p9_scan_compression.H
+++ b/src/import/chips/p9/utils/imageProcs/p9_scan_compression.H
@@ -123,8 +123,9 @@ compressed_scan_data_translate(CompressedScanData* o_data,
/// <ChipType> ring ID header files for more info.)
///
/// This API is required for integration with PHYP which does not support
-/// malloc(). Applications in environments supporting malloc() can use
-/// rs4_compress() instead.
+/// local memory allocation, like malloc() and new(). Applications in
+/// environments supporting local memory allocation can use rs4_compress()
+/// instead.
///
/// We always require the worst-case amount of memory including the header and
/// any rounding required to guarantee that the data size is a multiple of 8
@@ -145,7 +146,7 @@ _rs4_compress(CompressedScanData* io_rs4,
/// Compress a scan string using the RS4 compression algorithm
///
-/// \param[out] o_rs4 This algorithm uses malloc() to allocate memory for the
+/// \param[out] o_rs4 This algorithm uses new() to allocate memory for the
/// compressed data, and returns a pointer to this memory in \a o_rs4. After
/// the call this memory is owned by the caller who is responsible for
/// free()-ing the data area once it is no longer required. Note that the
@@ -189,7 +190,9 @@ rs4_compress(CompressedScanData** o_rs4,
/// the decompressed care mask, which is the size of the original string in
/// bits rounded up to the nearest byte.
///
-/// \param[in] i_size The size in \e bytes of \a io_data_str and \a io_care_str.
+/// \param[in] i_size The size in \e bytes of \a o_data_str and \a o_care_str
+/// buffers and which represents the max number of raw ring bits x 8 that may
+/// fit into the two raw ring buffers.
///
/// \param[out] o_length The length of the decompressed string in \e bits.
///
@@ -197,13 +200,14 @@ rs4_compress(CompressedScanData** o_rs4,
/// decompressed.
///
/// This API is required for integration with PHYP which does not support
-/// malloc(). Applications in environments supporting malloc() can use
-/// rs4_decompress() instead.
+/// local memory allocation, such as malloc() and new(). Applications in
+/// environments supporting local memory allocation can use rs4_decompress()
+/// instead.
///
/// \returns See \ref scan_compression_codes
int
-_rs4_decompress(uint8_t* io_data_str,
- uint8_t* io_care_str,
+_rs4_decompress(uint8_t* o_data_str,
+ uint8_t* o_care_str,
uint32_t i_size,
uint32_t* o_length,
const CompressedScanData* i_rs4);
@@ -211,11 +215,11 @@ _rs4_decompress(uint8_t* io_data_str,
/// Decompress a scan string compressed using the RS4 compression algorithm
///
-/// \param[out] o_data_str The API malloc()-s this data area to contain the
+/// \param[out] o_data_str The API new() allocs this data area to contain the
/// decompressed string. After this call the caller owns \a o_data_str and is
/// responsible for free()-ing this data area once it is no longer required.
///
-/// \param[out] o_care_str The API malloc()-s this data area to contain the
+/// \param[out] o_care_str The API new() allocs this data area to contain the
/// decompressed care mask. After this call the caller owns \a o_care_str and
/// is responsible for free()-ing this data area once it is no longer required.
///
@@ -251,7 +255,7 @@ rs4_redundant(const CompressedScanData* i_data, int* o_redundant);
/// \param[in] i_rs4 A pointer to the RS4 CompressedScanData [header + data]
///
/// \returns 1 if CMSK ring found, 0 otherwise
-int rs4_is_cmsk(CompressedScanData* i_rs4);
+int rs4_is_cmsk(const CompressedScanData* i_rs4);
/// Embed CMSK ring into an RS4 ring
@@ -265,18 +269,41 @@ int rs4_embed_cmsk(CompressedScanData** io_rs4,
CompressedScanData* i_rs4_cmsk);
-/// Extract Stump & CMSK rings from an RS4 ring
+/// Extract Stump & CMSK rings from an RS4 ring (assumes pre-allocated ring buffers)
///
-/// \param[in] i_rs4 A pointer to the CompressedScanData [header + data]
+/// \param[in] i_rs4 A pointer to the input hybrid CMSK RS4 ring and which must contain
+/// boto CompressedScanData header + RS4 encoded data string.
///
-/// \param[inout] i_rs4_stump A pointer to the Stump CompressedScanData [header + data]
+/// \param[in] i_size Size of buffers to hold the output Stump and CMSK RS4 rings.
///
-/// \param[inout] i_rs4_cmsk A pointer to the Cmsk CompressedScanData [header + data]
+/// \param[out] o_rs4_stump A pointer to a pre-allocated buffer that must be big
+/// enough to hold the Stump CompressedScanData [header + data].
+///
+/// \param[out] o_rs4_cmsk A pointer to a pre-allocated buffer that must be big
+/// enough to hold the Cmsk CompressedScanData [header + data].
+///
+/// \returns See \ref scan_compression_codes
+int _rs4_extract_cmsk( const CompressedScanData* i_rs4,
+ size_t i_size,
+ CompressedScanData* o_rs4_stump,
+ CompressedScanData* o_rs4_cmsk );
+
+
+/// Extract Stump & CMSK rings from an RS4 ring (local allocation of ring buffers)
+///
+/// \param[in] i_rs4 A pointer to the input hybrid CMSK RS4 ring and which must contain
+/// boto CompressedScanData header + RS4 encoded data string.
+///
+/// \param[out] o_rs4_stump A pointer to a locally allocated buffer that holds the
+/// Stump CompressedScanData [header + data]. The calling code must free the buffer.
+///
+/// \param[out] o_rs4_cmsk A pointer to a locally allocated buffer that holds the
+/// Cmsk CompressedScanData [header + data]. The calling code must free the buffer.
///
/// \returns See \ref scan_compression_codes
-int rs4_extract_cmsk(CompressedScanData* i_rs4,
- CompressedScanData** io_rs4_stump,
- CompressedScanData** io_rs4_cmsk);
+int rs4_extract_cmsk( const CompressedScanData* i_rs4,
+ CompressedScanData** o_rs4_stump,
+ CompressedScanData** o_rs4_cmsk );
#endif // __ASSEMBLER__
diff --git a/src/import/chips/p9/xip/p9_xip_tool.C b/src/import/chips/p9/xip/p9_xip_tool.C
index 396a9aed..f5317915 100644
--- a/src/import/chips/p9/xip/p9_xip_tool.C
+++ b/src/import/chips/p9/xip/p9_xip_tool.C
@@ -43,9 +43,10 @@
#undef P9_XIP_TOOL_VERBOSE
#include "p9_xip_image.h"
-#ifndef __PPE__ // Needed on ppe side to avoid TOR API
+#ifndef __PPE__ // Needed on ppe side to avoid having to include various APIs
#include "p9_tor.H"
#include "p9_scan_compression.H"
+#include "p9_infrastruct_help.H"
namespace P9_RID
{
#include "p9_ringId.H"
@@ -54,12 +55,14 @@ namespace CEN_RID
{
#include "cen_ringId.H"
}
+#include <vector>
+#include <p9_dd_container.h>
+#include <endian.h>
#endif
#include "p9_infrastruct_help.H"
#include "p9_dd_container.h"
#define LINE_SIZE_MAX 1024 // Max size of a single snprintf dump.
-#define RING_BUF_SIZE_MAX 1000000
// Listing mode IDs:
//
@@ -595,7 +598,7 @@ dumpHeader(void* i_image, image_section_type_t i_imageSectionType)
default:
fprintf(stderr,
- "\nERROR: In dumpHeader(): Invalid image section type (=%d)\n",
+ "ERROR: In dumpHeader(): Invalid image section type (=%d)\n",
i_imageSectionType);
uint64_t l_magic = *((uint64_t*)i_image);
fprintf(stderr, "Here's the first 8 bytes of the image section (LE): 0x%016lx ",
@@ -610,7 +613,7 @@ dumpHeader(void* i_image, image_section_type_t i_imageSectionType)
*(((uint8_t*)&l_magic) + 6),
*(((uint8_t*)&l_magic) + 7));
fprintf(stderr,
- "If you're seeing \"TOR\" or \"DDCO\" in the first 8 bytes, you're probably using the PPE version of p9_xip_tool. Use the EKB version instead!\n");
+ "If you're seeing \"TOR\" or \"DDCO\" in the first 8 bytes, you're probably using the PPE version of p9_xip_tool. Use the EKB version instead!\n\n");
exit(EXIT_FAILURE);
}
@@ -664,6 +667,7 @@ report(void* io_image,
{
control.regex = 0;
+ printf("\n");
dumpHeader(io_image, IST_XIP);
printf("\nTOC Report\n\n");
}
@@ -680,6 +684,7 @@ report(void* io_image,
}
else
{
+ printf("\n");
dumpHeader(io_image, i_imageSectionType);
printf("\n");
}
@@ -1875,7 +1880,7 @@ TEST(void* io_image, const int i_argc, const char** i_argv)
/// until we get TOR magic (RTC157744).
///
static
-int dissectRingSectionTor( void* i_ringSection,
+int dissectRingSectionTor( uint8_t* i_ringSection,
uint8_t i_listingModeId )
{
int rc = 0;
@@ -1892,27 +1897,29 @@ int dissectRingSectionTor( void* i_ringSection,
uint8_t instanceId;
void* ringBlockPtr;
uint32_t ringBlockSize;
- char ringName[32];
+ char ringName[50];
uint32_t ringSeqNo = 0; // Ring sequence number
- CompressedScanData* rs4;
+ CompressedScanData* rs4 = NULL;
+ CompressedScanData* rs4ForDisplay = NULL;
+ uint32_t maxRingBufSize;
+ void* rs4StumpBuf;
+ void* rs4CmskBuf;
CompressedScanData* rs4Stump;
CompressedScanData* rs4Cmsk;
- CompressedScanData* rs4Print;
- uint8_t* data;
- uint8_t* care;
- uint32_t bits;
- int rs4rc;
- uint16_t ringSize;
- 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;
+ void* dataBuf;
+ void* careBuf;
+ uint8_t* data;
+ uint8_t* care;
+ uint32_t bits;
+ uint16_t ringSize;
+ double comprRate;
+ uint8_t cmskRingIteration = 0;
+ char ringSuffix = ' ';
+
+ TorHeader_t* torHeader = reinterpret_cast<TorHeader_t*>(i_ringSection);
//
- // Get TOR magic and DD level info from TOR header field
+ // Get TOR header fields
//
torMagic = be32toh(torHeader->magic);
chipType = torHeader->chipType;
@@ -1941,42 +1948,78 @@ int dissectRingSectionTor( void* i_ringSection,
exit(1);
}
- fprintf(stdout, "---------------------------------\n");
- fprintf(stdout, "* TOR header summary *\n");
- fprintf(stdout, "---------------------------------\n");
- dumpHeader(i_ringSection, IST_TOR);
- fprintf(stdout, "---------------------------------\n");
- fprintf(stdout, "\n\n");
+ //
+ // Allocate buffer to hold max length ring block
+ //
+ ringBlockSize = MAX_RING_BUF_SIZE_TOOL;
+ ringBlockPtr = operator new(ringBlockSize);
- if (i_listingModeId != LMID_TABLE)
+ if (!ringBlockPtr)
{
- fprintf( stdout, "-----------------------------\n"
- "* Ring summary *\n");
+ fprintf(stderr, "malloc of ringBlockPtr failed!\n");
+ exit(EXIT_FAILURE);
}
//
- // Allocate large buffer to hold max length ring block.
+ // Allocate buffers to hold decompressed raw rings for data and care as well
+ // as for buffers to hold extracted RS4 Stump and CMSK rings
//
- ringBlockSize = RING_BUF_SIZE_MAX;
- ringBlockPtr = malloc(ringBlockSize);
+ maxRingBufSize = MAX_RING_BUF_SIZE_TOOL;
+ dataBuf = operator new(maxRingBufSize);
+ careBuf = operator new(maxRingBufSize);
- if (i_listingModeId == LMID_TABLE)
+ if (!dataBuf || !careBuf)
+ {
+ fprintf(stderr, "malloc of dataBuf or careBuf failed!\n");
+ operator delete(ringBlockPtr);
+ operator delete(dataBuf);
+ operator delete(careBuf);
+ exit(EXIT_FAILURE);
+ }
+
+ data = (uint8_t*)dataBuf;
+ care = (uint8_t*)careBuf;
+
+ rs4StumpBuf = operator new(maxRingBufSize);
+ rs4CmskBuf = operator new(maxRingBufSize);
+
+ if (!rs4StumpBuf || !rs4CmskBuf)
{
- fprintf(stdout, "\n # DD PPE Var Inst Bits Compr Name\n");
+ fprintf(stderr, "malloc of rs4StumpBuf or rs4CmskBuf failed!\n");
+ operator delete(ringBlockPtr);
+ operator delete(dataBuf);
+ operator delete(careBuf);
+ operator delete(rs4StumpBuf);
+ operator delete(rs4CmskBuf);
+ exit(EXIT_FAILURE);
}
+ rs4Stump = (CompressedScanData*)rs4StumpBuf;
+ rs4Cmsk = (CompressedScanData*)rs4CmskBuf;
+
+ bool bRingsFound = true;
+ bool bPrintHeader = true;
+
+ // Needed if TOR_MAGIC_HW
+ TorDdBlock_t* torDdBlock = reinterpret_cast<TorDdBlock_t*>(i_ringSection + sizeof(TorHeader_t));
+
+
//----------------
// DD level loop.
for (iDdLevel = 0; iDdLevel < numDdLevels; iDdLevel++)
{
if (torMagic == TOR_MAGIC_HW)
{
- torDdBlock = (TorDdBlock_t*)&buf[offset];
- offset += sizeof(TorDdBlock_t);
ddLevel = torDdBlock->ddLevel;
+ //point to the next DD block
+ torDdBlock++;
}
+ // assume no rings will be found so on the next loop so we can print
+ // the info
+ bRingsFound = false;
+
//----------------
// PPE type loop.
// - SBE, CME, SGPE
@@ -1987,7 +2030,8 @@ int dissectRingSectionTor( void* i_ringSection,
(torMagic == TOR_MAGIC_CME && ppeType != PT_CME) ||
(torMagic == TOR_MAGIC_SBE && ppeType != PT_SBE) ||
(torMagic == TOR_MAGIC_OVRD && ppeType != PT_SBE) ||
- (torMagic == TOR_MAGIC_CEN && ppeType != PT_SBE))
+ (torMagic == TOR_MAGIC_CEN && ppeType != PT_SBE) ||
+ (torMagic == TOR_MAGIC_OVLY && ppeType != PT_SBE))
{
continue;
}
@@ -1995,11 +2039,11 @@ 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) ||
- (torMagic == TOR_MAGIC_CEN && ringVariant == CC))
+ if ( (torMagic == TOR_MAGIC_OVRD && ringVariant != BASE) ||
+ (torMagic == TOR_MAGIC_OVLY && ringVariant != BASE) ||
+ (torMagic == TOR_MAGIC_CEN && ringVariant == CC) )
{
continue;
}
@@ -2009,7 +2053,7 @@ int dissectRingSectionTor( void* i_ringSection,
for (ringId = 0; ringId < numRingIds; ringId++)
{
- ringType = -1;
+ ringType = 0xff;
//---------------------------
// Chiplet instance ID loop.
@@ -2026,7 +2070,7 @@ int dissectRingSectionTor( void* i_ringSection,
ddLevel, ppeTypeName[ppeType], ringVariantName[ringVariant], ringId, instanceId);
#endif
- ringBlockSize = RING_BUF_SIZE_MAX;
+ ringBlockSize = MAX_RING_BUF_SIZE_TOOL;
rc = tor_access_ring( i_ringSection,
ringId,
ddLevel,
@@ -2044,6 +2088,28 @@ int dissectRingSectionTor( void* i_ringSection,
//
if (rc == TOR_RING_FOUND)
{
+ if(bPrintHeader == true )
+ {
+ // print the table header info
+ if (i_listingModeId == LMID_TABLE)
+ {
+ fprintf(stdout, "------------------------------------------------------------------------------\n");
+ fprintf(stdout, "* Ring table *\n");
+ fprintf(stdout, "------------------------------------------------------------------------------\n");
+ fprintf(stdout, " # DD PPE Var Inst Bits Compr Name\n");
+ fprintf(stdout, "------------------------------------------------------------------------------\n");
+ }
+ else
+ {
+ fprintf( stdout, "-----------------------------\n"
+ "* Ring summary *\n");
+ }
+
+ bPrintHeader = false;
+ }
+
+ bRingsFound = true;
+
rs4 = (CompressedScanData*)ringBlockPtr;
// Sanity check RS4 container's ringId matches the requested.
@@ -2054,7 +2120,12 @@ int dissectRingSectionTor( void* i_ringSection,
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);
+ operator delete(ringBlockPtr);
+ operator delete(dataBuf);
+ operator delete(careBuf);
+ operator delete(rs4StumpBuf);
+ operator delete(rs4CmskBuf);
+ exit(EXIT_FAILURE);
}
@@ -2067,7 +2138,12 @@ int dissectRingSectionTor( void* i_ringSection,
"RS4 header's iv_size(=0x%04x) is either zero or doesn't match "
"size of ring buffer (ringBlockSize=0x%04x).\n",
ringSize, ringBlockSize);
- exit(1);
+ operator delete(ringBlockPtr);
+ operator delete(dataBuf);
+ operator delete(careBuf);
+ operator delete(rs4StumpBuf);
+ operator delete(rs4CmskBuf);
+ exit(EXIT_FAILURE);
}
ringSeqNo++;
@@ -2079,42 +2155,65 @@ int dissectRingSectionTor( void* i_ringSection,
do
{
+ data = (uint8_t*)dataBuf;
+ care = (uint8_t*)careBuf;
+
// decompress ring to obtain ring length and to verify compressed string
// check for cmsk ring
if (rs4_is_cmsk(rs4))
{
if (!cmskRingIteration)
{
- // Extract Stump & Cmsk rings from large rs4 ring
- // decompress each to get ring length and display
- // accordingly
- rc = rs4_extract_cmsk(rs4, &rs4Stump, &rs4Cmsk);
+ // Extract Stump & Cmsk rings from hybrid RS4 ring. Then
+ // decompress each to get ring length and trace out
+ rs4Stump = (CompressedScanData*)rs4StumpBuf;
+ rs4Cmsk = (CompressedScanData*)rs4CmskBuf;
+ rc = _rs4_extract_cmsk(rs4, maxRingBufSize, rs4Stump, rs4Cmsk);
if (rc)
{
- fprintf(stdout, "CMSK extract error %i)", rc);
+ fprintf(stderr, "CMSK extract error %d\n", rc);
+ exit(EXIT_FAILURE);
}
cmskRingIteration++;
ringSuffix = 's';
- rs4Print = rs4Stump; //For 'raw' & 'long' display
+ rs4ForDisplay = rs4Stump; //For 'raw' & 'long' display
ringBlockSize = be16toh(rs4Stump->iv_size);
- rs4rc = rs4_decompress(&data, &care, &bits, rs4Stump);
+ rc = _rs4_decompress(data, care, maxRingBufSize, &bits, rs4Stump);
+
+ if (rc)
+ {
+ fprintf(stderr, "rs4Stump decompress error %d\n", rc);
+ exit(EXIT_FAILURE);
+ }
}
else
{
cmskRingIteration--;
ringSuffix = 'c';
- rs4Print = rs4Cmsk; //For 'raw' & 'long' display
+ rs4ForDisplay = rs4Cmsk; //For 'raw' & 'long' display
ringBlockSize = be16toh(rs4Cmsk->iv_size);
- rs4rc = rs4_decompress(&data, &care, &bits, rs4Cmsk);
+ rc = _rs4_decompress(data, care, maxRingBufSize, &bits, rs4Cmsk);
+
+ if (rc)
+ {
+ fprintf(stderr, "rs4Cmsk decompress error %d\n", rc);
+ exit(EXIT_FAILURE);
+ }
}
}
else
{
ringSuffix = ' ';
- rs4Print = rs4;
- rs4rc = rs4_decompress(&data, &care, &bits, rs4);
+ rs4ForDisplay = rs4;
+ rc = _rs4_decompress(data, care, maxRingBufSize, &bits, rs4);
+
+ if (rc)
+ {
+ fprintf(stderr, "rs4 decompress error %d\n", rc);
+ exit(EXIT_FAILURE);
+ }
}
comprRate = (double)ringSize / (double)bits * 100.0;
@@ -2123,24 +2222,17 @@ int dissectRingSectionTor( void* i_ringSection,
if (i_listingModeId == LMID_TABLE)
{
fprintf(stdout,
- "%4i%c "
- "0x%02x "
- "%4s "
- "%4s "
- "0x%02x "
- "%7d "
- "%6.2f "
- "%s ",
+ "%4i%c "
+ "0x%02x "
+ "%4s "
+ "%4s "
+ "0x%02x "
+ "%7d "
+ "%6.2f "
+ "%s\n",
ringSeqNo, ringSuffix, ddLevel, ppeTypeName[ppeType],
ringVariantName[ringVariant], instanceId,
bits, comprRate, ringName);
-
- if (rs4rc != SCAN_COMPRESSION_OK)
- {
- fprintf(stdout, "Decompression error %i)", rs4rc);
- }
-
- fprintf(stdout, "\n");
}
// Summarize a few key characteristics of the ring block if "short".
@@ -2186,36 +2278,15 @@ int dissectRingSectionTor( void* i_ringSection,
{
fprintf(stdout, "Binary ring block dump (LE format):\n");
- // Below code is used to display the stumped and
- // cmsk raw|long ring block.
- // @FIXME: Tried to display the same by assigning
- // rs4Stump and rs4Cmsk to ringBlockPtr but having issue
- // with ringBlockPtr being void pointer.
- if (rs4_is_cmsk(rs4))
- {
- for (i = 0; i < ringBlockSize / 8; i++)
- {
- fprintf( stdout,
- "%04x: %04x %04x %04x %04x\n",
- i * 8,
- (uint16_t)( htobe64(*((uint64_t*)rs4Print + i)) >> 48),
- (uint16_t)( htobe64(*((uint64_t*)rs4Print + i)) >> 32),
- (uint16_t)( htobe64(*((uint64_t*)rs4Print + i)) >> 16),
- (uint16_t)( htobe64(*((uint64_t*)rs4Print + i))) );
- }
- }
- else
+ for (i = 0; i < ringBlockSize / 8; i++)
{
- for (i = 0; i < ringBlockSize / 8; i++)
- {
- fprintf( stdout,
- "%04x: %04x %04x %04x %04x\n",
- i * 8,
- (uint16_t)( htobe64(*((uint64_t*)ringBlockPtr + i)) >> 48),
- (uint16_t)( htobe64(*((uint64_t*)ringBlockPtr + i)) >> 32),
- (uint16_t)( htobe64(*((uint64_t*)ringBlockPtr + i)) >> 16),
- (uint16_t)( htobe64(*((uint64_t*)ringBlockPtr + i))) );
- }
+ fprintf( stdout,
+ "%04x: %04x %04x %04x %04x\n",
+ i * 8,
+ (uint16_t)( htobe64(*((uint64_t*)rs4ForDisplay + i)) >> 48),
+ (uint16_t)( htobe64(*((uint64_t*)rs4ForDisplay + i)) >> 32),
+ (uint16_t)( htobe64(*((uint64_t*)rs4ForDisplay + i)) >> 16),
+ (uint16_t)( htobe64(*((uint64_t*)rs4ForDisplay + i))) );
}
}
@@ -2233,11 +2304,9 @@ int dissectRingSectionTor( void* i_ringSection,
fprintf( stdout, "\n");
}
- free(data);
- free(care);
-
}
while (cmskRingIteration);
+
}
else if (rc == TOR_RING_NOT_FOUND ||
rc == TOR_INVALID_INSTANCE_ID ||
@@ -2249,33 +2318,60 @@ int dissectRingSectionTor( void* i_ringSection,
#ifdef P9_XIP_TOOL_VERBOSE
fprintf(stderr, "tor_access_ring() returned error code rc=%d\n", rc);
#endif
+ // All these errors are acceptable in the context of xip_tool dissect.
+ rc = INFRASTRUCT_RC_SUCCESS;
}
else
{
- fprintf(stderr, "tor_access_ring() returned error code rc=%d\n", rc);
- {
- exit(1);
- }
+ fprintf(stderr, "CODE BUG: tor_access_ring() returned invalid error code rc=%d\n", rc);
+ operator delete(ringBlockPtr);
+ operator delete(dataBuf);
+ operator delete(careBuf);
+ operator delete(rs4StumpBuf);
+ operator delete(rs4CmskBuf);
+ exit(EXIT_FAILURE);
+ }
+
+ if (rc && ringType == 255)
+ {
+ // So here we were unsuccessful in tor_access_ring and never even found a
+ // ring name match, or ring variant match, or chiplet match. So we can
+ // safely break the instanceId loop.
+ break;
}
} // End of for(instanceId)
- } // End of for(ringVariant)
+ } // End of for(ringId)
- } // End of for(iRingId)
+ } // End of for(ringVariant)
} // End of for(ppeType)
+ if( bRingsFound == false )
+ {
+ fprintf(stdout, "No rings for DD level: 0x%x\n", ddLevel);
+ }
+
} // End of for(iDdLevel)
- if (i_listingModeId != LMID_TABLE)
+ if (i_listingModeId == LMID_TABLE)
{
- fprintf(stdout, "-----------------------------\n");
+ fprintf(stdout, "------------------------------------------------------------------------------\n");
+ }
+ else
+ {
+ fprintf(stdout, "------------------------------------------\n");
}
- return 0;
-}
+ operator delete(ringBlockPtr);
+ operator delete(dataBuf);
+ operator delete(careBuf);
+ operator delete(rs4StumpBuf);
+ operator delete(rs4CmskBuf);
+ return rc;
+}
/// Function: dissectRingSection()
@@ -2306,9 +2402,10 @@ dissectRingSection(void* i_image,
uint8_t sectionId, listingModeId;
P9XipHeader hostHeader;
P9XipSection hostSection;
- void* ringSectionPtr;
image_section_type_t l_imageSectionType = IST_UNDEFINED;
-
+ bool bEcLvlSupported = false;
+ void* ringSection = NULL;
+ std::vector<void*>ringSectionPtrs;
//
// Treat input image section according to its type.
@@ -2322,6 +2419,7 @@ dissectRingSection(void* i_image,
if (i_argc == 1)
{
sectionName = i_argv[0];
+ // ..and default value for listingMode will be used.
}
else if (i_argc == 2)
{
@@ -2331,15 +2429,16 @@ dissectRingSection(void* i_image,
else
{
fprintf(stderr,
- "\nERROR: The number of sub arguments (=%d) is too few or too many for the 'dissect' command for an XIP image\n",
+ "\nERROR: The number of sub-arguments (=%d) is too few or too many for the 'dissect' command for an XIP image\n\n",
i_argc);
exit(EXIT_FAILURE);
}
p9_xip_translate_header(&hostHeader, (P9XipHeader*)i_image);
- // Determine P9-XIP ring section ID from the section name, e.g.
+ // Determine XIP ring section ID from the section name, e.g.
// .rings => P9_XIP_SECTION_HW_RINGS
+ //
if (strcmp(sectionName, ".rings") == 0)
{
if (hostHeader.iv_magic == P9_XIP_MAGIC_SEEPROM)
@@ -2375,9 +2474,9 @@ dissectRingSection(void* i_image,
}
else if (strcmp(sectionName, ".overlays") == 0)
{
- if (hostHeader.iv_magic == P9_XIP_MAGIC_SEEPROM)
+ if (hostHeader.iv_magic == P9_XIP_MAGIC_HW)
{
- sectionId = P9_XIP_SECTION_SBE_OVERLAYS;
+ sectionId = P9_XIP_SECTION_HW_OVERLAYS;
}
else
{
@@ -2399,25 +2498,92 @@ dissectRingSection(void* i_image,
exit(EXIT_FAILURE);
}
- // Get ring section.
+ // Determine if XIP section has DD support
//
- rc = p9_xip_get_section( i_image, sectionId, &hostSection);
+ rc = p9_xip_dd_section_support( i_image, sectionId, bEcLvlSupported );
- if (rc)
+ if( bEcLvlSupported )
{
- fprintf( stderr, "p9_xip_get_section() failed : %s\n", P9_XIP_ERROR_STRING(g_errorStrings, rc));
- return P9_XIP_DISASSEMBLER_ERROR;
- }
+ struct p9_dd_block* block;
+ struct p9_dd_block block_he;
- if (hostSection.iv_offset == 0)
- {
- fprintf( stdout, "Ring section (w/ID=%d) is empty. Nothing to do. Quitting.\n", sectionId);
- exit(EXIT_FAILURE);
+ rc = p9_xip_get_section( i_image, sectionId, &hostSection);
+
+ if (rc)
+ {
+ fprintf(stderr, "ERROR: error getting the multi-ec level %s section "
+ "(rc=%d)\n", sectionName, rc);
+ exit(EXIT_FAILURE);
+ }
+
+ struct p9_dd_iter iter = {NULL, 0};
+
+ // Initialize our iterator to the beginning of the container
+ iter.iv_cont = (struct p9_dd_cont*)(((uint8_t*)i_image) + hostSection.iv_offset);
+
+ fprintf(stdout, "\n");
+
+ fprintf(stdout, "----------------------------------------------\n");
+
+ fprintf(stdout, "* DD container summary *\n");
+
+ fprintf(stdout, "----------------------------------------------\n");
+
+ fprintf(stdout, "DD Container type: %s\n", sectionName);
+
+ fprintf(stdout, "Num DD levels: %d\n", iter.iv_cont->iv_num);
+
+ fprintf(stdout, "----------------------------------------------\n");
+
+ fprintf(stdout, "\n");
+
+ // For each DD specific block, grab the TOR ringSection
+ while ((block = p9_dd_next(&iter)))
+ {
+ p9_dd_betoh(block, &block_he);
+
+ rc = p9_xip_get_section(i_image, sectionId, &hostSection, block_he.iv_dd);
+
+ if (rc)
+ {
+ fprintf(stderr, "ERROR: Failed getting DD specific %s section for dd=%#x "
+ "(rc=%d)\n", sectionName, block_he.iv_dd, rc);
+ exit(EXIT_FAILURE);
+ }
+
+ ringSection = (void*)(hostSection.iv_offset + (uintptr_t)i_image);
+ ringSectionPtrs.push_back(ringSection);
+
+ if (block_he.iv_dd != ((TorHeader_t*)ringSection)->ddLevel)
+ {
+ //Error trace and exit.
+ fprintf(stderr, "ERROR: Incorrect DD level returned from container.\n\tExpected:%#x Got:%#x\n",
+ block_he.iv_dd, ((TorHeader_t*)ringSection)->ddLevel);
+ exit(EXIT_FAILURE);
+ }
+ }
}
+ else
+ {
+ 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));
+ exit(EXIT_FAILURE);
+ }
- ringSectionPtr = (void*)((uintptr_t)i_image + hostSection.iv_offset);
+ if (hostSection.iv_offset == 0)
+ {
+ fprintf( stdout, "Ring section (w/ID=%d) is empty. Nothing to do. Quitting.\n", sectionId);
+ exit(EXIT_FAILURE);
+ }
- resolve_image_section_type( ringSectionPtr, l_imageSectionType);
+ ringSection = (void*)((uintptr_t)i_image + hostSection.iv_offset);
+ ringSectionPtrs.push_back(ringSection);
+ }
+
+ resolve_image_section_type( ringSection, l_imageSectionType);
if (l_imageSectionType != IST_TOR)
{
@@ -2431,26 +2597,32 @@ dissectRingSection(void* i_image,
case IST_TOR:
- if (i_argc == 1)
+ if (i_argc == 0)
+ {
+ // Nothing TBD. It's legal to pass no sub-arguments to 'dissect' for standalone
+ // TOR ring section file. Default value for listingMode will be used.
+ }
+ else if (i_argc == 1)
{
listingModeName = i_argv[0];
}
else
{
fprintf(stderr,
- "\nERROR: The number of sub arguments (=%d) is too few or too many for the 'dissect' command for a TOR section\n",
+ "\nERROR: The number of sub-arguments (=%d) is too few or too many for the 'dissect' command for a TOR section\n\n",
i_argc);
exit(EXIT_FAILURE);
}
- ringSectionPtr = i_image;
+ ringSection = i_image;
+ ringSectionPtrs.push_back(ringSection);
break;
case IST_DDCO:
fprintf(stderr,
- "\nERROR: No support for DDCO image section type yet.\n");
+ "\nERROR: No support for standalone DDCO image section type yet.\n");
exit(EXIT_FAILURE);
default:
@@ -2516,10 +2688,31 @@ dissectRingSection(void* i_image,
exit(EXIT_FAILURE);
}
- rc = dissectRingSectionTor(ringSectionPtr, listingModeId);
+ for (size_t iPos = 0; iPos < ringSectionPtrs.size(); iPos++)
+ {
+ //
+ // Trace out TOR header info
+ //
+ fprintf(stdout, "\n");
+ fprintf(stdout, "----------------------------------------------\n");
+ fprintf(stdout, "* TOR header summary *\n");
+ fprintf(stdout, "----------------------------------------------\n");
+ dumpHeader(ringSectionPtrs.at(iPos), IST_TOR);
+ fprintf(stdout, "----------------------------------------------\n");
+ fprintf(stdout, "\n");
+
+ rc = dissectRingSectionTor(static_cast<uint8_t*>(ringSectionPtrs.at(iPos)), listingModeId);
- return rc;
+ if (rc)
+ {
+ fprintf(stderr, "ERROR: dissectRingSectionTor() failed w/rc=0x%08x\n", rc);
+ break;
+ }
+
+ fprintf(stdout, "\n");
+ }
+ return rc;
}
#endif
@@ -2554,8 +2747,8 @@ openAndMap(const char* i_fileName, int i_writable, int* o_fd, void** o_image, co
if (*o_fd < 0)
{
perror("open() of the image failed : ");
- fprintf(stderr, "ERROR: open() failed for filename=%s failed : ", i_fileName);
- exit(1);
+ fprintf(stderr, "ERROR: open() failed for filename=%s failed\n", i_fileName);
+ exit(EXIT_FAILURE);
}
rc = fstat(*o_fd, &buf);
@@ -2812,6 +3005,13 @@ command(const char* i_imageFile, const int i_argc, const char** i_argv, const ui
exit(EXIT_FAILURE);
#endif
+ if (rc)
+ {
+ fprintf(stderr, "ERROR: dissectRingSection() failed w/rc=0x%08x\n", rc);
+ exit(EXIT_FAILURE);
+ }
+
+
}
else if ( strcmp(i_argv[0], "check-sbe-ring-section") == 0 &&
l_imageSectionType == IST_XIP )
OpenPOWER on IntegriCloud