From 7f62dd04344bba5ea02d8d1d19328a6cd33bcb8c Mon Sep 17 00:00:00 2001 From: "Richard J. Knight" Date: Tue, 27 Jun 2017 12:16:16 -0500 Subject: 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 Tested-by: Jenkins Server Tested-by: HWSV CI Tested-by: PPE CI Tested-by: Hostboot CI Reviewed-by: Richard J. Knight Reviewed-by: Sumit Kumar Reviewed-by: Jennifer A. Stofer Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/42802 Reviewed-by: Hostboot Team Reviewed-by: Sachin Gupta --- .../p9/utils/imageProcs/p9_infrastruct_help.H | 4 + .../p9/utils/imageProcs/p9_scan_compression.H | 63 ++- src/import/chips/p9/xip/p9_xip_tool.C | 480 +++++++++++++++------ 3 files changed, 389 insertions(+), 158 deletions(-) (limited to 'src/import/chips') 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, /// 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 +#include +#include #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(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(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::vectorringSectionPtrs; // // 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(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 ) -- cgit v1.2.1