diff options
author | Richard J. Knight <rjknight@us.ibm.com> | 2016-03-30 11:13:05 -0500 |
---|---|---|
committer | Sachin Gupta <sgupta2m@in.ibm.com> | 2016-09-26 01:47:27 -0400 |
commit | 2f21c8cdb1b36b58a1f0f392a03f8d9ff42e4dbb (patch) | |
tree | e505af2e3478a96b9066b79d081593bfb5468909 /src | |
parent | dc926fed0b3eb9dfa9dc8dfcb95273d3e81ea2df (diff) | |
download | talos-sbe-2f21c8cdb1b36b58a1f0f392a03f8d9ff42e4dbb.tar.gz talos-sbe-2f21c8cdb1b36b58a1f0f392a03f8d9ff42e4dbb.zip |
Implementation of p9_ipl_build tool
Change-Id: I778c3525e639cf1ce631ae327cf65b8bda14e1a4
RTC:150314
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/22745
Tested-by: Jenkins Server
Reviewed-by: Prachi Gupta <pragupta@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/30234
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/import/tools/imageProcs/p9_ipl_build.C | 679 | ||||
-rw-r--r-- | src/import/tools/imageProcs/p9_ipl_build.H | 42 |
2 files changed, 411 insertions, 310 deletions
diff --git a/src/import/tools/imageProcs/p9_ipl_build.C b/src/import/tools/imageProcs/p9_ipl_build.C index 45e4018d..31b86500 100644 --- a/src/import/tools/imageProcs/p9_ipl_build.C +++ b/src/import/tools/imageProcs/p9_ipl_build.C @@ -22,400 +22,459 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -/*------------------------------------------------------------------------------*/ -/* *! TITLE : p9_ipl_build.C */ -/* *! DESCRIPTION : Copies RS4 delta ring states from unsigned HW image to DD- */ -// specific PNOR SBE image. -/* *! OWNER NAME : Michael Olsen cmolsen@us.ibm.com */ -// -/* *! EXTENDED DESCRIPTION : */ -// -/* *! USAGE : To build - */ -// buildecmdprcd -C "p9_image_help_base.C" -c "p9_xip_image.c" p9_ipl_build.C -// -/* *! ASSUMPTIONS : */ -// - sysPhase=0 is assumed which puts the SBE image together for IPL. -// -/* *! COMMENTS : */ -// - .strings and .toc are removed as "a unit" before validating. -// -/*------------------------------------------------------------------------------*/ - -#include <p9_image_help.H> +/*----------------------------------------------------------------------------*/ +/* *! TITLE : p9_ipl_build.C */ +/* *! DESCRIPTION : Copies RS4 delta ring states from unsigned HW image to DD */ +/* specific PNOR SBE image. */ +/* *! OWNER NAME : Michael Olsen cmolsen@us.ibm.com */ +/* */ +/* *! EXTENDED DESCRIPTION : */ +/* */ +/* *! USAGE : p9_ipl_build <sbe image> <unsigend hw image> <dd level> */ +/* */ +/* *! ASSUMPTIONS : */ +/* - sysPhase=0 is assumed which puts the SBE image together for IPL. */ +/* */ +/* *! COMMENTS : */ +/*----------------------------------------------------------------------------*/ +#include <string> +#include <iomanip> +#include <sstream> +#include <fstream> +#include <errno.h> + +#include "p9_ipl_build.H" +#include <p9_xip_image.h> +#include <p9_tor.H> + +// prefix of our debug file name +const char* CHIP_TYPE = "p9_"; + +/// +/// @brief Create a filename containing the DD level and chip type +/// +/// @param[in] i_fn SBE image file name +/// @param[in] i_ddLevel - DD level of ring +/// +/// @retval std::string - holding the newly created file name. +/// +std::string getDDSpecificFileName(const char* i_fn, + uint32_t i_ddLevel + ) +{ + // create our dd specific file name + std::stringstream ss; + std::string fn = i_fn; + auto found = fn.find_last_of("/"); -#define THIS_HELP ("\nUSAGE:\n\tp9_ipl_build -help [anything]\n\t or\n" \ - "\tp9_ipl_build \n" \ - "\t\t<Input/output SBE image file>\n" \ - "\t\t<Input HW reference image file\n" \ - "\t\t<DD level [hex value]>\n" ) + ss << CHIP_TYPE << std::hex << i_ddLevel << "." << fn.substr(found + 1); + return ss.str(); +} -// main() input parms: -// arg1: Input/output SBE image file -// arg2: Input HW image file -// arg3: DD level [hex value] -int main( int argc, char* argv[]) + +/// +/// @brief retrieve a block of DD level rings from the unsigned hw image +/// +/// @param[in] i_hwImage - pointer to a an unsigned hw image. +/// @param[in] i_ddLevel - DD level of rings to append +/// @param[out] o_ringBlock - DD level block of rings from the hw image. +/// @param[out] o_blockSize - size of ring block returned +/// +/// @return IMGBUILD_SUCCESS, or failure value. +/// +int get_dd_level_rings_from_hw_image(char* i_hwImage, + uint32_t i_ddLevel, + void** o_ringBlock, + uint32_t& o_blockSize + ) { - int rc = 0; - char* fnImageSbe, *fnImageHw; - uint32_t ddLevel = 0; - uint32_t fdImageHw = 0; - struct stat stbuf; - uint32_t sizeImageHw; - void* imageHw; + int rc = IMGBUILD_SUCCESS; - P9_XIP_ERROR_STRINGS(g_errorStrings); + P9XipSection l_ringsSection; + *o_ringBlock = NULL; + o_blockSize = 0; + RingType_t l_ringType = ALLRING; + uint8_t unused_parm = 0; - // ========================================================================== - // Convert input parms from char to <type> - // ========================================================================== - MY_DBG("\n--> Processing Input Parameters...\n"); + // 1. use the tor api go get the block of rings from the hw image + rc = p9_xip_get_section(i_hwImage, P9_XIP_SECTION_HW_RINGS, &l_ringsSection); - if (argc < 4 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--h") == 0) + if(rc) { - MY_INF("%s\n", THIS_HELP); - return 1; + MY_ERR("call to p9_xip_get_section ID(%d) failed rc=%d\n", P9_XIP_SECTION_HW_RINGS, rc); + rc = IMGBUILD_ERR_GET_SECTION; } + else + { + // make a pointer to the start of the rings section + void* ringsSection = i_hwImage + l_ringsSection.iv_offset; - // Convert input parms from char to <type> - // - fnImageSbe = argv[1]; - fnImageHw = argv[2]; - ddLevel = strtol(argv[3], NULL, 16); - - MY_INF(" Input/output SBE image fn = %s\n", fnImageSbe); - MY_INF(" Input HW image fn = %s\n", fnImageHw); - MY_INF(" DD level = 0x%02x\n", ddLevel); - - // ========================================================================== - // Memory map HW reference image. - // ========================================================================== - MY_DBG("Memory map HW ref image.\n"); - fdImageHw = open(fnImageHw, O_RDONLY); + do + { - if (fstat(fdImageHw, &stbuf) != 0) - { - MY_ERR("Could not fstat the HW ref image file.\n"); - return 1; - } + // call the first time to get a size of the pending section + rc = tor_get_block_of_rings(ringsSection, i_ddLevel, + SBE, l_ringType, BASE, unused_parm, o_ringBlock, + o_blockSize); - sizeImageHw = stbuf.st_size; - imageHw = mmap(0, sizeImageHw, PROT_READ, MAP_SHARED, fdImageHw, 0); + if(rc) + { + MY_ERR("error calling tor API rc = %d\n", rc); + rc = IMGBUILD_ERR_SECTION_SIZING; + break; + } - if (imageHw == MAP_FAILED) - { - MY_ERR("mmap() of HW ref image failed.\n"); - return 1; - } + if( o_blockSize == 0 ) + { + rc = IMGBUILD_NO_RINGS_FOUND; + MY_INF("No rings for dd_level %#02x found\n", i_ddLevel); + break; + } - // ...validate image. - rc = p9_xip_validate(imageHw, sizeImageHw); + // *o_ringBlock is freed by caller + *o_ringBlock = malloc(o_blockSize); - if (rc) - { - MY_ERR("p9_xip_validate() of HW ref image failed: %s\n", P9_XIP_ERROR_STRING(g_errorStrings, rc)); - return 1; - } + if(o_ringBlock != NULL) + { + rc = tor_get_block_of_rings (ringsSection, i_ddLevel, + SBE, l_ringType, BASE, unused_parm, o_ringBlock, + o_blockSize); - // Update the SBE image. - // - MY_INF("Updating the SBE image... \n"); + if(rc) + { + MY_ERR("error calling tor API rc = %d\n", rc); + rc = IMGBUILD_ERR_RING_SEARCH; + } + } + else + { + MY_ERR("failed to allocate memory for ring block\n"); + rc = IMGBUILD_ERR_MEMORY; + } - rc = ipl_build( fnImageSbe, - imageHw, - ddLevel ); + MY_DBG("o_blockSize = %d\n", o_blockSize); + MY_DBG("o_ringBlock = %p\n", o_ringBlock); - if (rc == IMGBUILD_SUCCESS) - { - MY_INF("SBE image build was SUCCESSFUL.\n"); - } - else if (rc == IMGBUILD_RING_SEARCH_EOS_NO_MATCH) - { - MY_INF("SBE image build was SUCCESSFUL but no RS4 rings appended (rc=%i).\n", rc); + } + while(0); } - else + + return rc; +}; + + +/// +/// @brief appends a block of rings to the previously un-populated .rings +/// section of the P9 SBE image +/// +/// the passed in image pointer should point to an in memory sbe image +/// callers should ensure that the location is large enough for the existing +/// image and the new ring section. +/// +/// @param[in] io_sbeImage - pointer to an unsigned SBE image +/// @param[i/o] io_sbeImageSize - size of image after section has been appended +/// @param[i] i_ringBlock - pointer to a block of rings to be appended to +// the sbe image +/// @param[i] i_blockSize - size of the block of rings to append. +/// +/// @return 0 on success non-zero on failure +/// +int append_ring_block_to_image(char* io_sbeImage, + size_t& io_sbeImageSize, + char* i_ringBlock, + uint32_t i_blockSize + ) +{ + uint32_t unused_parm = 0; + int rc = IMGBUILD_SUCCESS; + + // Append block of rings to the sbe image in Memory + rc = p9_xip_append(io_sbeImage, + P9_XIP_SECTION_SBE_RINGS, + i_ringBlock, + i_blockSize, + io_sbeImageSize, + &unused_parm); + + if(rc) { - MY_ERR("SBE image build was UNSUCCESSFUL (rc=%i).\n", rc); - return 1; + MY_ERR("error appending ring section = %d\n", rc); + rc = IMGBUILD_ERR_APPEND; } - close(fdImageHw); + MY_DBG("i_ringBlock = %p\n", i_ringBlock); return rc; +}; + +/// +/// @brief Create an SBE image customized with DD level rings +/// +/// @param[in] i_fnSbeImage - File name of SBE image +/// @param[in] i_hwImage - pointer to a memory mapped Unsigned hardware image +/// @param[i] i_ddLevel - DD level of rings to append to the SBE image +/// +int ipl_build(char* i_fnSbeImage, + void* i_hwImage, + uint32_t i_ddLevel + ) +{ -} - + char* sbeImage = NULL; + void* l_ringBlock = NULL; + int rc = 0; -// Parameter list: -// char *io_fnImageSbe: Filename of SBE I/O image -// void *i_imageHw: Pointer to memory mapped HW Reference image -// uint32_t i_ddLevel: DD level -// -int ipl_build( char* io_fnImageSbe, - void* i_imageHw, - uint32_t i_ddLevel ) -{ - int rc = 0, rcLoc = 0, rcSearch = 0, countRings = 0; - void* ringBuffer = NULL; - uint32_t ringBlockSize = 0; - void* nextRing = NULL; - uint8_t iRingType = 0; - uint8_t xipSectionId = 0; - uint8_t bDone = 0; + std::string ddSpecificFileName = getDDSpecificFileName(i_fnSbeImage, i_ddLevel); -//CMO-When removing sections, mmap SBE image file here first. + std::ifstream sbeImageFile; + std::ofstream ddSpecificImage; -#if 0 //CMO-for now.. we probably need different impl for p9 - uint32_t sizeImage = 0; - P9XipSection xipSection; + sbeImageFile.open(i_fnSbeImage, std::ios::binary | std::ios::in | std::ios::out); - // ========================================================================== - // First, remove all unnecessary sections in the output image. - // ========================================================================== - // - rcLoc1 = sbe_xip_delete_section( i_imageOut, P9_XIP_SECTION_HBBL); - rcLoc2 = sbe_xip_image_size(i_imageOut, &sizeImage); - rcLoc = sbe_xip_validate(i_imageOut, sizeImage); - if (rcLoc1 || rcLoc2 || rcLoc) + if(!sbeImageFile) { - fprintf(stderr, "_delete_section(.hbbl) (rcLoc1=%i), _image_size() (rcLoc2=%i) and/or _validate() (rcLoc=%i) failed.\n", - rcLoc1, rcLoc2, rcLoc); - return IMGBUILD_ERR_SECTION_DELETE; + printf("failed to open %s\n", i_fnSbeImage); + rc = IMGBUILD_ERR_FILE_ACCESS; } + else + { + // open it in read mode, if it does not exist this will fail, which means + // its ok to create, otherwise we don't want to overwrite existing files. + ddSpecificImage.open(ddSpecificFileName.c_str(), std::ios::in); - fprintf(stdout, "Image size (after .hbbl delete): %i\n", sizeImage); - - rcLoc1 = sbe_xip_delete_section( i_imageOut, P9_XIP_SECTION_RINGS); - rcLoc2 = sbe_xip_image_size(i_imageOut, &sizeImage); - rcLoc = sbe_xip_validate(i_imageOut, sizeImage); + // did it open ok, if so tell the user + if(ddSpecificImage) + { + MY_ERR("%s already exists..\n", ddSpecificFileName.c_str()); + rc = IMGBUILD_ERR_FILE_ACCESS; + } + else + { + do + { + // get a filebuf pointer to make it easy to work with + std::filebuf* pbuf = sbeImageFile.rdbuf(); - if (rcLoc1 || rcLoc2 || rcLoc) - { - fprintf(stderr, - "_delete_section(.rings) (rcLoc1=%i), _image_size() (rcLoc2=%i) and/or _validate() (rcLoc=%i) failed.\n", rcLoc1, - rcLoc2, rcLoc); - return IMGBUILD_ERR_SECTION_DELETE; - } + // get the file size + std::size_t sbeImageSize = pbuf->pubseekoff(0, + sbeImageFile.end, sbeImageFile.in); - fprintf(stdout, "Image size (after .rings delete): %i\n", sizeImage); + pbuf->pubseekpos(0, sbeImageFile.in); - rcLoc1 = sbe_xip_delete_section( i_imageOut, P9_XIP_SECTION_OVERLAYS); - rcLoc2 = sbe_xip_image_size(i_imageOut, &sizeImage); - rcLoc = sbe_xip_validate(i_imageOut, sizeImage); + // allocate some space to hold the file data + sbeImage = (char*)malloc(sbeImageSize); - if (rcLoc1 || rcLoc2 || rcLoc) - { - fprintf(stderr, - "_delete_section(.overlays) (rcLoc1=%i), _image_size() (rcLoc2=%i) and/or _validate() (rcLoc=%i) failed.\n", rcLoc1, - rcLoc2, rcLoc); - return IMGBUILD_ERR_SECTION_DELETE; - } + if(sbeImage == NULL) + { + MY_ERR("Failed to allocate memory for the SBE image\n"); + rc = IMGBUILD_ERR_MEMORY; + break; + } - fprintf(stdout, "Image size (after .overlays delete): %i\n", sizeImage); + bzero(sbeImage, sbeImageSize); - rcLoc1 = sbe_xip_delete_section( i_imageOut, P9_XIP_SECTION_PIBMEM0); - rcLoc2 = sbe_xip_image_size(i_imageOut, &sizeImage); - rcLoc = sbe_xip_validate(i_imageOut, sizeImage); + // copy the SBE image into memory + pbuf->sgetn(sbeImage, sbeImageSize); - if (rcLoc1 || rcLoc2 || rcLoc) - { - fprintf(stderr, - "_delete_section(.pibmem0) (rcLoc1=%i), _image_size() (rcLoc2=%i) and/or _validate() (rcLoc=%i) failed.\n", rcLoc1, - rcLoc2, rcLoc); - return IMGBUILD_ERR_SECTION_DELETE; - } + // validate it + rc = p9_xip_validate(sbeImage, sbeImageSize); - fprintf(stdout, "Image size (after .pibmem0 delete): %i\n", sizeImage); + if(rc) + { + MY_ERR("The SBE image copied to memory" + "failed validation rc = %d", rc); - rcLoc1 = sbe_xip_delete_section( i_imageOut, P9_XIP_SECTION_HALT); - rcLoc2 = sbe_xip_image_size(i_imageOut, &sizeImage); - rcLoc = sbe_xip_validate(i_imageOut, sizeImage); + rc = IMGBUILD_INVALID_IMAGE; + break; + } - if (rcLoc1 || rcLoc2 || rcLoc) - { - fprintf(stderr, "_delete_section(.halt) (rcLoc1=%i), _image_size() (rcLoc2=%i) and/or _validate() (rcLoc=%i) failed.\n", - rcLoc1, rcLoc2, rcLoc); - return IMGBUILD_ERR_SECTION_DELETE; - } + MY_INF("SBE Image validated ok.. %p\n", sbeImage); - fprintf(stdout, "Image size (after .halt delete): %i\n", sizeImage); + uint32_t l_blockSize = 0; - rcLoc1 = sbe_xip_delete_section( i_imageOut, P9_XIP_SECTION_STRINGS); - rcLoc2 = sbe_xip_delete_section( i_imageOut, P9_XIP_SECTION_TOC); - sbe_xip_image_size(i_imageOut, &sizeImage); - rcLoc = sbe_xip_validate(i_imageOut, sizeImage); + char* hwImagePtr = static_cast<char*>(i_hwImage); - if (rcLoc1 || rcLoc2 || rcLoc) - { - fprintf(stderr, - "_delete_section(.strings) (rcLoc1=%i), _delete_section(.toc) (rcLoc2=%i) and/or _validate() (rcLoc=%i) failed.\n", - rcLoc1, rcLoc2, rcLoc); - return IMGBUILD_ERR_SECTION_DELETE; - } + rc = get_dd_level_rings_from_hw_image(hwImagePtr, + i_ddLevel, + &l_ringBlock, + l_blockSize); - fprintf(stdout, "Image size (after .strings and .toc delete): %i\n", sizeImage); + if(rc == IMGBUILD_SUCCESS) + { + // update our SBE image size to include the new block of rings + sbeImageSize += l_blockSize; + + // grow our workspace + void* tmp = realloc(sbeImage, sbeImageSize); + + if(tmp == NULL) + { + MY_ERR("error resizing workspace..giving up errno=%d", errno); + rc = IMGBUILD_ERR_MEMORY; + break; + } + + // use the new, larger space + sbeImage = static_cast<char*>(tmp); + + rc = append_ring_block_to_image(sbeImage, + sbeImageSize, + (char*)l_ringBlock, + l_blockSize); + + if(rc == IMGBUILD_SUCCESS) + { + // looks like it worked, create a debug file and write the + // customized image to it + ddSpecificImage.open(ddSpecificFileName.c_str(), std::ios::binary | std::ios::out); + + if(!ddSpecificImage) + { + MY_ERR("failed to open %s for writing\n", ddSpecificFileName.c_str()); + rc = IMGBUILD_ERR_FILE_ACCESS; + } + else + { + std::filebuf* outbuf = ddSpecificImage.rdbuf(); + + outbuf->sputn(sbeImage, sbeImageSize); + + MY_INF("DD specific file created as %s\n", ddSpecificFileName.c_str()); + + // rewind to the beginning of the original file and write this + // into it. + pbuf->pubseekpos(0, sbeImageFile.in); + + pbuf->sputn(sbeImage, sbeImageSize); + + } + } + else + { + MY_ERR("creating dd specific SBE image failed rc=%d\n", rc); + } + } + } + while(0); - rcLoc1 = sbe_xip_delete_section( i_imageOut, P9_XIP_SECTION_DATA); - rcLoc2 = sbe_xip_image_size(i_imageOut, &sizeImage); - rcLoc = sbe_xip_validate(i_imageOut, sizeImage); + free(sbeImage); + free(l_ringBlock); + } - if (rcLoc1 || rcLoc2 || rcLoc) - { - fprintf(stderr, "_delete_section(.data) (rcLoc1=%i), _image_size() (rcLoc2=%i) and/or _validate() (rcLoc=%i) failed.\n", - rcLoc1, rcLoc2, rcLoc); - return IMGBUILD_ERR_SECTION_DELETE; + ddSpecificImage.close(); + sbeImageFile.close(); } - fprintf(stdout, "Image size (after .data delete): %i\n", sizeImage); + return rc; +} - rcLoc1 = sbe_xip_delete_section( i_imageOut, P9_XIP_SECTION_TEXT); - rcLoc2 = sbe_xip_image_size(i_imageOut, &sizeImage); - rcLoc = sbe_xip_validate(i_imageOut, sizeImage); - if (rcLoc1 || rcLoc2 || rcLoc) - { - fprintf(stderr, "_delete_section(.text) (rcLoc1=%i), _image_size() (rcLoc2=%i) and/or _validate() (rcLoc=%i) failed.\n", - rcLoc1, rcLoc2, rcLoc); - return IMGBUILD_ERR_SECTION_DELETE; - } +#define THIS_HELP ("\nUSAGE:\n\tp9_ipl_build -help [anything]\n\t or\n" \ + "\tp9_ipl_build \n" \ + "\t\t<Input/output SBE image file>\n" \ + "\t\t<Input HW reference image file\n" \ + "\t\t<DD level [hex value]>\n" ) - fprintf(stdout, "Image size (after .text delete): %i\n", sizeImage); +// main() input parms: +// arg1: Input/output SBE image file +// arg2: Input HW image file +// arg3: DD level [hex value] +int main( int argc, char* argv[]) +{ + int rc = IMGBUILD_SUCCESS; + char* fnSbeImage, *fnHwImage; + uint32_t ddLevel = 0; + uint32_t fdHwImage = 0; + struct stat stbuf; + uint32_t sizeHwImage; + void* hwImage; + // ========================================================================== - // Re-append .pibmem0 + // Convert input parms from char to <type> // ========================================================================== - rc = sbe_xip_get_section( i_imageSbe, P9_XIP_SECTION_PIBMEM0, &xipSection); + MY_DBG("\n--> Processing Input Parameters...\n"); - if (rc) + if (argc < 4 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--h") == 0) { - MY_INF("ERROR : sbe_xip_get_section() failed: %s", P9_XIP_ERROR_STRING(g_errorStrings, rc)); - MY_INF("Probable cause:"); - MY_INF("\tThe section (=P9_XIP_SECTION_PIBMEM0=%i) was not found.", P9_XIP_SECTION_RINGS); - return IMGBUILD_ERR_KEYWORD_NOT_FOUND; + MY_INF("%s\n", THIS_HELP); + return 1; } - rc = sbe_xip_append( i_imageOut, - P9_XIP_SECTION_PIBMEM0, - (void*)((uintptr_t)i_imageSbe + xipSection.iv_offset), - xipSection.iv_size, - i_sizeImageOutMax, - 0); - - if (rc) - { - MY_INF("sbe_xip_append() failed: %s", P9_XIP_ERROR_STRING(g_errorStrings, rc)); - return IMGBUILD_ERR_APPEND; - } + // Convert input parms from char to <type> + // + fnSbeImage = argv[1]; + fnHwImage = argv[2]; + ddLevel = strtol(argv[3], NULL, 16); -#endif // #if 0 + MY_INF(" Input/output SBE image fn = %s\n", fnSbeImage); + MY_INF(" Input HW image fn = %s\n", fnHwImage); + MY_INF(" DD level = %#02x\n", ddLevel); + // ========================================================================== + // Memory map HW reference image. + // ========================================================================== + MY_DBG("Memory map HW image.\n"); + fdHwImage = open(fnHwImage, O_RDONLY); -//CMO-When removing sections, close the mmapped SBE image file here. - for (iRingType = 0; iRingType < RING_SECTION_ID_SIZE; iRingType++) + if (fstat(fdHwImage, &stbuf) != 0) { + MY_ERR("Could not fstat the HW image file.\n"); + return 1; + } - xipSectionId = RING_SECTION_ID[iRingType]; - nextRing = NULL; - bDone = 0; - - /**************************************************************************** - * SEARCH LOOP - Begin * - ****************************************************************************/ + sizeHwImage = stbuf.st_size; + hwImage = mmap(0, sizeHwImage, PROT_READ, MAP_SHARED, fdHwImage, 0); + if (hwImage == MAP_FAILED) + { + MY_ERR("mmap() of HW image failed.\n"); + rc = IMGBUILD_MEM_MAP_FAILED; + } + else + { do { + // ...validate image. + MY_INF("Validating the the HW image... \n"); + rc = p9_xip_validate(hwImage, sizeHwImage); - MY_DBG("nextRing (at top)=0x%016lx\n", (uint64_t)nextRing); - - ringBlockSize = FIXED_RING_BUF_SIZE; - ringBuffer = malloc(ringBlockSize); - - if (!ringBuffer) + if (rc) { - MY_ERR("malloc() for fixed ring buffer failed.\n"); - exit(1); + MY_ERR("p9_xip_validate() of HW image failed: rc=%d\n", rc); + rc = IMGBUILD_INVALID_IMAGE; + break; } - // ========================================================================== - // Get ring layout from HW ref image - // ========================================================================== - rcLoc = get_ring_from_image( i_imageHw, - i_ddLevel, - 0, // sysPhase = IPL-SBE image build - ringBuffer, // Contains copy of RS4 ring, incl layout - &ringBlockSize,// Contains ring block size on return - &nextRing, // Points to next ring (may not need for P9) - xipSectionId ); - rcSearch = rcLoc; - - if ( rcSearch != IMGBUILD_RING_SEARCH_MATCH && - rcSearch != IMGBUILD_RING_SEARCH_EOS_MATCH && - rcSearch != IMGBUILD_RING_SEARCH_EOS_NO_MATCH) - { - MY_ERR("ERROR : Error during retrieval of delta rings from the image (rcSearch=%i).\n", rcSearch); - MY_ERR("No further RS4 rings will be appended to the IPL image.\n"); - MY_ERR("The IPL image is incomplete.\n"); - return IMGBUILD_ERR_INCOMPLETE_IMG_BUILD; - } + // Update the SBE image. + // + MY_INF("Updating the SBE image... \n"); - if ( rcSearch == IMGBUILD_RING_SEARCH_MATCH || - rcSearch == IMGBUILD_RING_SEARCH_EOS_MATCH ) - { - MY_DBG("Retrieving ring was successful.\n"); - countRings++; - } + rc = ipl_build( fnSbeImage, hwImage, ddLevel); - // Check if we're done due to failure to find any more rings. - // - if ( rcSearch == IMGBUILD_RING_SEARCH_EOS_NO_MATCH ) + if (rc == IMGBUILD_SUCCESS) { - MY_INF("Number of RS4 rings appended to ring section (ID=%i): %i\n", xipSectionId, countRings); - rc = IMGBUILD_SUCCESS; - bDone = 1; + MY_INF("SBE image build was SUCCESSFUL.\n"); } - - if (!bDone) + else if (rc == IMGBUILD_NO_RINGS_FOUND) { - rc = append_ring_to_image( io_fnImageSbe, - ringBuffer, - ringBlockSize ); - free(ringBuffer); - - if (rc) - { - MY_ERR("ring_section_append() failed: rc=%i Stopping.\n", rc); - exit(1); - } - else - { - MY_DBG("Image update successful.\n"); - } - - } // End of if(!bDone) - - // Check if we're done due to having reached EOS of ring section and found a ring. - // - if ( rcSearch == IMGBUILD_RING_SEARCH_EOS_MATCH ) + MY_INF("SBE image build was UNSUCCESSFUL no rings found in the HW image" + "(rc=%i).\n", rc); + } + else { - MY_INF("Number of RS4 rings appended to ring section (ID=%i): %i\n", xipSectionId, countRings); - rc = IMGBUILD_SUCCESS; - bDone = 1; + MY_ERR("SBE image build was UNSUCCESSFUL (rc=%i).\n", rc); } - - } - while (!bDone); + while(0); - /*************************************************************************** - * SEARCH LOOP - End - ***************************************************************************/ - - MY_INF("Done adding rings to ring section ID = %i\n", xipSectionId); + munmap(hwImage, sizeHwImage); + } - } // End of for(iRingType=...) loop + close(fdHwImage); - exit(1); return rc; } diff --git a/src/import/tools/imageProcs/p9_ipl_build.H b/src/import/tools/imageProcs/p9_ipl_build.H new file mode 100644 index 00000000..a0726f76 --- /dev/null +++ b/src/import/tools/imageProcs/p9_ipl_build.H @@ -0,0 +1,42 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/import/tools/imageProcs/p9_ipl_build.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] 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 */ + +#ifndef __P9_IMAGE_BLD_H +#define __P9_IMAGE_BLD_H + +// $TODO - these are currently defined in p9_ring_apply.H - but I cant include +// that file due to other issues - added here till we sort it out. +#define IMGBUILD_SUCCESS 0 // Successful img build. +#define IMGBUILD_ERR_FILE_ACCESS 2 // Unable to access/open file. +#define IMGBUILD_MEM_MAP_FAILED 3 // Failed to map image to memory location +#define IMGBUILD_NO_RINGS_FOUND 5 // Successful img build but no rings found. +#define IMGBUILD_ERR_MEMORY 7 // Memory allocation error. +#define IMGBUILD_INVALID_IMAGE 10 // Invalid image. +#define IMGBUILD_ERR_RING_SEARCH 33 // Err assoc w/ring retrieval. +#define IMGBUILD_ERR_GET_SECTION 49 // Err assoc w/getting section ID. +#define IMGBUILD_ERR_APPEND 51 // Err assoc w/appending to ELF section. +#define IMGBUILD_ERR_SECTION_SIZING 48 // Err assoc w/section sizing. + +#endif |