From 8fb3f52276fd37466afb34b85a1dbda3c8ee3e9f Mon Sep 17 00:00:00 2001 From: Claus Michael Olsen Date: Thu, 30 Mar 2017 20:20:23 -0500 Subject: H-code ddLevel support - Front-end hooks for user and back-end codes. xip_image.c has been renamed to xip_image.C to take advantage of C++ ability to overload function call arg list to avoid having to introduce additional skinny "xip_dd_get_section" and "xip_dd_append" functions. p9_xip_get_section() and p9_xip_append() APIs have been updated with an additional DD support arg as their last parm. P9XipSection.iv_reserved8[0] converted to iv_ddSupport to enable XIP level knowledge about ddSupport capability of XIP sections. Introduced p9_xip_dd_section_support() that queries a section's iv_ddSupport flag to tell caller true/false about a sections ddLevel support status. Added support in xip_tool.C as follows: - Updated "append" command to accept an optional arg, ddSupport, if section has ddLevel support or not. - Updated "extract" command to accept an optional arg, ddLevel, specifying which ddLevel to extract. - Updated "report" command's listing to show ddLevel support status of sections. Change-Id: I17e1e09d63e894d4f26cb7b324cf10ab784d78a4 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/38666 Tested-by: PPE CI Tested-by: Hostboot CI Tested-by: Jenkins Server Reviewed-by: Jennifer A. Stofer Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/38667 Tested-by: FSP CI Jenkins Reviewed-by: Sachin Gupta --- src/import/chips/p9/xip/p9_xip_tool.C | 205 +++++++++++++++++++++++++++------- 1 file changed, 162 insertions(+), 43 deletions(-) (limited to 'src/import/chips/p9/xip/p9_xip_tool.C') diff --git a/src/import/chips/p9/xip/p9_xip_tool.C b/src/import/chips/p9/xip/p9_xip_tool.C index ab109c87..e6fe0793 100644 --- a/src/import/chips/p9/xip/p9_xip_tool.C +++ b/src/import/chips/p9/xip/p9_xip_tool.C @@ -40,6 +40,7 @@ #include #include #include +#include #undef P9_XIP_TOOL_VERBOSE @@ -72,10 +73,10 @@ enum LISTING_MODE_ID // p9_xip_tool [- ...] setv [ ... ] // p9_xip_tool [- ...] report [] // p9_xip_tool [- ...] attrdump -// p9_xip_tool [- ...] append
-// p9_xip_tool [- ...] extract
+// p9_xip_tool [- ...] append
[ ] +// p9_xip_tool [- ...] extract
[ ] // p9_xip_tool [- ...] delete
[ ... ] -// p9_xip_tool [- ...] dissect [table,short,normal(default),long,raw] +// p9_xip_tool [- ...] dissect [ table,short,normal(default),long,raw ] // p9_xip_tool [- ...] disasm // // This simple application uses the P9-XIP image APIs to normalize, search @@ -127,9 +128,18 @@ enum LISTING_MODE_ID // Currently the section must either be the final (highest address) section of // the image, or must be empty, in which case the append command creates the // section as the final section of the image. The 'append' command writes the -// relocatable image address where the input file was loaded to stdout. +// relocatable image address where the input file was loaded to stdout. The +// last argument, ddSupport, indicates if the section being added has ddLevel +// metadata support (=1) or not (=0). If this arg is omitted it's assumed +// to be false (=0). // -// The 'extract' command extracts a sections from the binary image. +// The 'extract' command extracts a section from the binary image. The last +// argument, ddLevel, indicates [in hex] the DD level to be extracted. If +// the section doesn't have DD level support, a message is returned stating +// that and to reissue the command w/o the ddLevel arg. If the section does +// have DD support but the specified ddLevel cannot be found, a message is +// returned stating that and no section is returned. If the arg is omitted, +// the entire XIP section is returned // // The 'delete' command deletes 0 or more sections, starting with . // Each section to be deleted must either be the final (highest address) @@ -165,11 +175,11 @@ const char* g_usage = " p9_xip_tool [-i ...] setv [ ... ]\n" " p9_xip_tool [-i ...] report []\n" " p9_xip_tool [-i ...] attrdump \n" - " p9_xip_tool [-i ...] append
\n" - " p9_xip_tool [-i ...] extract
\n" + " p9_xip_tool [-i ...] append
[ ]\n" + " p9_xip_tool [-i ...] extract
[ ]\n" " p9_xip_tool [-i ...] delete
[ ... ]\n" " p9_xip_tool [-i ...] dis
\n" - " p9_xip_tool [-i ...] dissect [table,short,normal(default),long,raw]\n" + " p9_xip_tool [-i ...] dissect [ table,short,normal(default),long,raw ]\n" " p9_xip_tool [-i ...] disasm \n" " p9_xip_tool [-i ...] check-sbe-ring-section
\n" "\n" @@ -222,9 +232,18 @@ const char* g_usage = "Currently the section must either be the final (highest address) section of\n" "the image, or must be empty, in which case the append command creates the\n" "section as the final section of the image. The 'append' command writes the\n" - "relocatable image address where the input file was loaded to stdout.\n" + "relocatable image address where the input file was loaded to stdout. The\n" + "last argument, ddSupport, indicates if the section being added has ddLevel\n" + "metadata support (=1) or not (=0). If this arg is omitted, it's assumed\n" + "to be false (=0).\n" "\n" - "The 'extract' command extracs a sections from a binary image.\n" + "The 'extract' command extracts a section from the binary image. The last\n" + "argument, ddLevel, indicates [in hex] the DD level to be extracted. If\n" + "the section doesn't have DD level support, a message is returned stating\n" + "that and to reissue the command w/o the ddLevel arg. If the section does\n" + "have DD support but the specified ddLevel cannot be found, a message is\n" + "returned stating that and no section is returned. If the arg is omitted,\n" + "the entire XIP section is returned." "\n" "The 'delete' command deletes 0 or more sections, starting with .\n" "Each section to be deleted must either be the final (highest address)\n" @@ -322,12 +341,12 @@ static inline const char* get_sectionName(uint64_t magic, int index) // Determine index of section given by its name in section table -static inline int get_sectionId(uint64_t i_magic, const char* i_section) +static inline int get_sectionId(uint64_t i_magic, const char* i_sectionName) { int i; for (i = 0; i < P9_XIP_SECTIONS; i++) - if (strcmp(i_section, get_sectionName(i_magic, i)) == 0) + if (strcmp(i_sectionName, get_sectionName(i_magic, i)) == 0) { return i; } @@ -566,15 +585,16 @@ dumpHeader(void* i_image) printf("\n"); printf("Section Table :\n\n"); - printf(" Name Alignment Start End Size\n"); + printf(" Name Align DD Start End Size\n"); printf("\n"); for (i = 0; i < P9_XIP_SECTIONS; i++) { section = &(header.iv_section[i]); - printf(" %-16s %d 0x%08x ", + printf(" %-16s %d %d 0x%08x ", get_sectionName(header.iv_magic, i), section->iv_alignment, + section->iv_ddSupport, section->iv_offset); if (section->iv_size == 0) @@ -1090,6 +1110,7 @@ static int append(const char* i_imageFile, const int i_imageFd, void* io_image, int i_argc, const char** i_argv) { + uint8_t i_ddSupport = 0; int fileFd, newImageFd, sectionId, rc; struct stat buf; const char* section; @@ -1105,7 +1126,7 @@ append(const char* i_imageFile, const int i_imageFd, void* io_image, // Basic syntax check:
- if (i_argc != 2) + if (i_argc != 2 && i_argc != 3) { fprintf(stderr, g_usage); exit(1); @@ -1114,6 +1135,23 @@ append(const char* i_imageFile, const int i_imageFd, void* io_image, section = i_argv[0]; file = i_argv[1]; + if (i_argc == 3) + { + if (strcmp(i_argv[2], "1") == 0) + { + i_ddSupport = 1; + } + else if (strcmp(i_argv[2], "0") == 0) + { + i_ddSupport = 0; + } + else + { + fprintf(stderr, g_usage); + exit(1); + } + } + p9_xip_translate_header(&header, (P9XipHeader*)io_image); // Translate the section name to a section Id @@ -1190,9 +1228,13 @@ append(const char* i_imageFile, const int i_imageFd, void* io_image, // We will not fail for unaligned addresses, as we have no knowledge // of whether or why the user wants the final image address. - rc = p9_xip_append(newImage, sectionId, - appendImage, buf.st_size, - newSize, §ionOffset); + rc = p9_xip_append(newImage, + sectionId, + appendImage, + buf.st_size, + newSize, + §ionOffset, + i_ddSupport); if (rc) { @@ -1248,63 +1290,140 @@ append(const char* i_imageFile, const int i_imageFd, void* io_image, return rc; } -// Extract section from a file +// Extract section from an image incl a DD-specific sub-section within an XIP section. static int extract(const char* i_imageFile, const int i_imageFd, void* io_image, int i_argc, const char** i_argv) { - int fileFd, sectionId, rc; + int rc = 0; + const char* i_sectionName; //Direct copy of input arg, thus i_ + const char* i_fileName; //Same + std::string i_ddLevelStr; //Same + uint8_t ddLevel = P9_XIP_UNDEFINED_DDLEVEL; + bool bDdSuppExpected = false; + int fileFd, sectionId; void* newImage; - const char* section; - const char* file; P9XipHeader header; - P9XipSection* xSection; - uint32_t size; - uint32_t offset; + P9XipSection* xSection; // XIP section of i_section + P9XipSection xDdSection; // Extracted XIP (self) or Dd section of i_section do { - if (i_argc != 2) + if (i_argc != 2 && i_argc != 3) { fprintf(stderr, g_usage); exit(1); } - section = i_argv[0]; - file = i_argv[1]; - - printf("%s %s\n", section , file); + i_sectionName = i_argv[0]; + i_fileName = i_argv[1]; p9_xip_translate_header(&header, (P9XipHeader*)io_image); - - sectionId = get_sectionId(header.iv_magic, section); + sectionId = get_sectionId(header.iv_magic, i_sectionName); if (sectionId < 0) { - fprintf(stderr, "Unrecognized section name : '%s;\n", section); + fprintf(stderr, "\nUnrecognized section name : '%s;\n", i_sectionName); exit(1); } xSection = &(header.iv_section[sectionId]); - size = xSection->iv_size; - offset = xSection->iv_offset; + printf("\nInput parms to the \"extract\" command:\n"\ + " Section: %s\n"\ + " Output file: %s\n", + i_sectionName, i_fileName); - printf("%-16s 0x%08x 0x%08x (%d)\n", - section, offset, size, size); + ddLevel = P9_XIP_UNDEFINED_DDLEVEL; + bDdSuppExpected = false; - newImage = malloc(size); + if (i_argc == 3) + { + i_ddLevelStr = i_argv[2]; + + bDdSuppExpected = true; + + printf(" DD level (input): %s\n", + i_ddLevelStr.c_str()); + } + + if (bDdSuppExpected) + { + if (xSection->iv_ddSupport) + { + if (i_ddLevelStr.size() != 2 && i_ddLevelStr.size() != 4) + { + fprintf(stderr, "\nThe specified ddLevel \"%s\" has an unsupported format.\n", + i_ddLevelStr.c_str()); + fprintf(stderr, "Specify ddLevel in hex format, e.g. \"0x10\" or \"10\"\n\n"); + exit(1); + } + + ddLevel = strtol(i_ddLevelStr.c_str(), NULL, 16); + + printf(" DD level (hex converted): 0x%x\n", + ddLevel); + } + else + { + fprintf(stderr, "\nThe section \"%s\" has no DD level support.\n", i_sectionName); + fprintf(stderr, "To extract the entire section, omit the \"ddLevel\" arg.\n\n"); + exit(1); + } + } + + printf("\nThe specified XIP section has the following attributes:\n"\ + " Offset: 0x%08x\n"\ + " Size (size): 0x%08x (%d)\n"\ + " DD support: %d\n", + xSection->iv_offset, xSection->iv_size, xSection->iv_size, xSection->iv_ddSupport); + + if (ddLevel == 0) + { + ddLevel = P9_XIP_UNDEFINED_DDLEVEL; + // Even though this may seem like we should just exit here, we'll leave it up + // to xip_get_section what to do in this case. Who knows, maybe it'll eventually + // return a list of supported DD levels. + } + +#ifdef __PPE__ + rc = p9_xip_get_section( io_image, sectionId, &xDdSection); +#else + rc = p9_xip_get_section( io_image, sectionId, &xDdSection, ddLevel); +#endif + + switch (rc) + { + case 0: + break; + + case P9_XIP_NO_DDLEVEL_SUPPORT: + fprintf(stderr, "\nThere is no support for DD level extraction yet.\n"); + fprintf(stderr, "To extract the entire section, omit the \"ddLevel\" arg.\n\n"); + exit(1); + + case P9_XIP_DDLEVEL_NOT_FOUND: + fprintf(stderr, "\nA sub-section w/the specified ddLevel (=0x%x) was not found.\n", ddLevel); + fprintf(stderr, "To extract the entire section, omit the \"ddLevel\" arg.\n\n"); + exit(1); + + default: + fprintf(stderr, "\np9_xip_get_section() failed w/rc = %d\n\n", rc); + exit(1); + } + + newImage = malloc(xSection->iv_size); if (newImage == 0) { - fprintf(stderr, "Can't malloc() a buffer for the new image\n"); + fprintf(stderr, "\nCan't malloc() a buffer for the new image\n"); exit(1); } - memcpy(newImage, (void*)((uint64_t)io_image + offset), size); + memcpy( newImage, (void*)((uint64_t)io_image + xDdSection.iv_offset), xDdSection.iv_size); - fileFd = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0755); + fileFd = open(i_fileName, O_CREAT | O_WRONLY | O_TRUNC, 0755); if (fileFd < 0) { @@ -1312,9 +1431,9 @@ extract(const char* i_imageFile, const int i_imageFd, void* io_image, exit(1); } - rc = write(fileFd, newImage, size); + rc = write(fileFd, newImage, xDdSection.iv_size); - if ((rc < 0) || ((uint32_t)rc != size)) + if ((rc < 0) || ((uint32_t)rc != xDdSection.iv_size)) { perror("write() of fixed section : "); exit(1); -- cgit v1.2.1