diff options
author | Elizabeth Liner <eliner@us.ibm.com> | 2016-03-09 10:32:37 -0600 |
---|---|---|
committer | William G. Hoffa <wghoffa@us.ibm.com> | 2016-03-21 17:49:03 -0400 |
commit | 265ac2d6c7eee92deb434808c72af19b9ff4c9d5 (patch) | |
tree | acd16f2f6ad54f9d009370d2c777658b677e9ef5 /src/usr | |
parent | 9ecc804688e872b8204addd52c6bea658b19afaa (diff) | |
download | talos-hostboot-265ac2d6c7eee92deb434808c72af19b9ff4c9d5.tar.gz talos-hostboot-265ac2d6c7eee92deb434808c72af19b9ff4c9d5.zip |
Adding xz decompression functionality for the skiboot image
Change-Id: I50d1eaa8bc76a030b42f982e2a967773e113f123
RTC:125550
depends-on: I2a104ec955966a6fcb9ed94dde54ab763c30210a
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/21854
Tested-by: Jenkins Server
Tested-by: FSP CI Jenkins
Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/hwpf/hwp/start_payload/start_payload.C | 2 | ||||
-rw-r--r-- | src/usr/isteps/istep21/call_host_start_payload.C | 118 | ||||
-rw-r--r-- | src/usr/pnor/common/ffs_hb.H | 20 | ||||
-rw-r--r-- | src/usr/pnor/pnor_utils.C | 3 | ||||
-rw-r--r-- | src/usr/pnor/pnor_utils.H | 4 | ||||
-rw-r--r-- | src/usr/pnor/pnorrp.C | 4 | ||||
-rw-r--r-- | src/usr/pnor/runtime/rt_pnor.C | 5 |
7 files changed, 126 insertions, 30 deletions
diff --git a/src/usr/hwpf/hwp/start_payload/start_payload.C b/src/usr/hwpf/hwp/start_payload/start_payload.C index 4e785d3bb..e51f5428e 100644 --- a/src/usr/hwpf/hwp/start_payload/start_payload.C +++ b/src/usr/hwpf/hwp/start_payload/start_payload.C @@ -89,8 +89,6 @@ #include <ipmi/ipmiwatchdog.H> #include <vpd/vpd_if.H> -#include <xz/xz.h> - // Uncomment these files as they become available: // #include "host_start_payload/host_start_payload.H" diff --git a/src/usr/isteps/istep21/call_host_start_payload.C b/src/usr/isteps/istep21/call_host_start_payload.C index 07eb58363..2ac6d4fda 100644 --- a/src/usr/isteps/istep21/call_host_start_payload.C +++ b/src/usr/isteps/istep21/call_host_start_payload.C @@ -44,8 +44,8 @@ #include <mbox/ipc_msg_types.H> #include <devicefw/userif.H> #include <arch/pirformat.H> - - +#include <xz/xz.h> +#include <isteps/hwpf_reasoncodes.H> #include <errl/errludtarget.H> @@ -127,26 +127,36 @@ static errlHndl_t load_pnor_section(PNOR::SectionId i_section, { return err; } - const uint32_t payloadSize = pnorSectionInfo.size; + uint32_t uncompressedPayloadSize = pnorSectionInfo.xzCompressed ? + pnorSectionInfo.xzSize : pnorSectionInfo.size; + + const uint32_t originalPayloadSize = pnorSectionInfo.size; printk( "Loading PNOR section %d (%s) %d bytes @0x%lx\n", i_section, pnorSectionInfo.name, - payloadSize, + originalPayloadSize, i_physAddr ); + uint64_t loadAddr = NULL; // Use simics optimization if we are running under simics which has very // slow PNOR access. if ( Util::isSimicsRunning() ) { + //TODO RTC:143500 + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "If you are running simics, and have a xz compressed ", + "payload image, you are going to fail. RTC 143500"); simics_load_payload( i_physAddr ); } else { // Map in the physical memory we are loading into. + // If we are not xz compressed, the uncompressedSize is + // equal to the original size. uint64_t loadAddr = reinterpret_cast<uint64_t>( mm_block_map( reinterpret_cast<void*>( i_physAddr ), - payloadSize ) ); + uncompressedPayloadSize ) ); // Print out inital progress bar. #ifdef CONFIG_CONSOLE @@ -159,24 +169,96 @@ static errlHndl_t load_pnor_section(PNOR::SectionId i_section, printk( "\r" ); #endif - // Load the data block by block and update the progress bar. - const uint32_t BLOCK_SIZE = 4096; - for ( uint32_t i = 0; i < payloadSize; i += BLOCK_SIZE ) + if(!pnorSectionInfo.xzCompressed) { - memcpy( reinterpret_cast<void*>( loadAddr + i ), - reinterpret_cast<void*>( pnorSectionInfo.vaddr + i ), - std::min( payloadSize - i, BLOCK_SIZE ) ); -#ifdef CONFIG_CONSOLE - for ( int new_progress = (i * progressSteps) / payloadSize; - progress <= new_progress; progress++ ) + // Load the data block by block and update the progress bar. + const uint32_t BLOCK_SIZE = 4096; + for ( uint32_t i = 0; i < originalPayloadSize; i += BLOCK_SIZE ) { - printk( "=" ); - } + memcpy( reinterpret_cast<void*>( loadAddr + i ), + reinterpret_cast<void*>( pnorSectionInfo.vaddr + i ), + std::min( originalPayloadSize - i, BLOCK_SIZE ) ); +#ifdef CONFIG_CONSOLE + for ( int new_progress = (i * progressSteps) / + originalPayloadSize; + progress <= new_progress; progress++ ) + { + printk( "=" ); + } #endif - } + } #ifdef CONFIG_CONSOLE - printk( "\n" ); + printk( "\n" ); #endif + } + } + + if(pnorSectionInfo.xzCompressed) + { + struct xz_buf b; + struct xz_dec *s; + enum xz_ret ret; + + xz_crc32_init(); + + s = xz_dec_init(XZ_SINGLE, 0); + if(s == NULL) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,ERR_MRK + "load_pnor_section: XZ Embedded Initialization failed"); + return err; + } + + static const uint64_t compressed_SIZE = originalPayloadSize; + static const uint64_t decompressed_SIZE = uncompressedPayloadSize; + + b.in = reinterpret_cast<uint8_t *>( pnorSectionInfo.vaddr); + b.in_pos = 0; + b.in_size = compressed_SIZE; + b.out = reinterpret_cast<uint8_t *>(loadAddr); + b.out_pos = 0; + b.out_size = decompressed_SIZE; + + ret = xz_dec_run(s, &b); + + if(ret == XZ_STREAM_END) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "load_pnor_section: The %s section was decompressed.", + pnorSectionInfo.name); + }else + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,ERR_MRK + "load_pnor_section: xz-embedded returned an error, ", + "the ret is %d",ret); + + //Clean up memory + xz_dec_end(s); + + /*@ + * @errortype + * @reasoncode fapi::RC_INVALID_RETURN_XZ_CODE + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid fapi::MOD_START_XZ_PAYLOAD + * @devdesc xz-embedded has returned an error. + * the return code can be found in xz.h + * @custdesc Error uncompressing payload image from + * boot flash + * @userdata1 Return code from xz-embedded + * @userdata2[0:31] Original Payload Size + * @userdata2[32:63] Uncompressed Payload Size + */ + err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi::MOD_START_XZ_PAYLOAD, + fapi::RC_INVALID_RETURN_XZ_CODE, + ret,TWO_UINT32_TO_UINT64( + originalPayloadSize, + uncompressedPayloadSize)); + err->addProcedureCallout(HWAS::EPUB_PRC_PHYP_CODE, + HWAS::SRCI_PRIORITY_HIGH); + return err; + } + xz_dec_end(s); } return NULL; diff --git a/src/usr/pnor/common/ffs_hb.H b/src/usr/pnor/common/ffs_hb.H index 23070a2e3..a7f579129 100644 --- a/src/usr/pnor/common/ffs_hb.H +++ b/src/usr/pnor/common/ffs_hb.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2015 */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -52,7 +52,8 @@ enum FFS_CHIPSEL_UNUSED = 0xFF, /**< Chip select not used */ /* Compression : 1 byte */ - FFS_COMPRESS_UNUSED = 0xFF, /**< Compression not used */ + FFS_COMPRESS_XZ = 0x80, /**< Section is XZ compressed */ + FFS_COMPRESS_UNUSED = 0x7F, /**< Compression not used */ /* Data Integrity : 2 bytes */ FFS_INTEG_ECC_PROTECT = 0x8000, /**< Data Integrity: ECC protected */ @@ -76,13 +77,14 @@ enum * This matches the PNOR binary layout of the data[] in an ffs_entry. */ struct ffs_hb_user_t{ - uint8_t chip; /**< Chip Select (0,1) */ - uint8_t compressType; /**< Compression Indication/alg (0=not compressed) */ - uint16_t dataInteg; /**< Indicates Data Integrity mechanism */ - uint8_t verCheck; /**< Indicates Version check type */ - uint8_t miscFlags; /**< Misc Partition related Flags */ - uint8_t freeMisc[2]; /**< Unused Miscellaneious Info */ - uint32_t freeUser[13]; /**< Unused User Data */ + uint8_t chip; /**< Chip Select (0,1) */ + uint8_t compressType; /**< Compression Indication/alg (0=not compressed) */ + uint16_t dataInteg; /**< Indicates Data Integrity mechanism */ + uint8_t verCheck; /**< Indicates Version check type */ + uint8_t miscFlags; /**< Misc Partition related Flags */ + uint8_t freeMisc[2]; /**< Unused Miscellaneious Info */ + uint32_t decompressSize; /**< Size after data is uncompressed in bytes */ + uint32_t freeUser[12]; /**< Unused User Data */ } PACKED; diff --git a/src/usr/pnor/pnor_utils.C b/src/usr/pnor/pnor_utils.C index ead1be810..a78b5cdc1 100644 --- a/src/usr/pnor/pnor_utils.C +++ b/src/usr/pnor/pnor_utils.C @@ -314,6 +314,9 @@ void PNOR::parseEntries (ffs_hdr* i_ffs_hdr, io_TOC[secId].integrity = ffsUserData->dataInteg; io_TOC[secId].version = ffsUserData->verCheck; io_TOC[secId].misc = ffsUserData->miscFlags; + io_TOC[secId].compress = ffsUserData->compressType; + io_TOC[secId].xzDecompressSize = + (ffsUserData->decompressSize); if((io_TOC[secId].flashAddr + io_TOC[secId].size) > (i_ffs_hdr->block_count*PAGESIZE)) { diff --git a/src/usr/pnor/pnor_utils.H b/src/usr/pnor/pnor_utils.H index e0027d349..1ceada403 100644 --- a/src/usr/pnor/pnor_utils.H +++ b/src/usr/pnor/pnor_utils.H @@ -116,6 +116,8 @@ struct SectionData_t { uint8_t version; /**< Version Checking */ uint16_t integrity; /**< Data Integrity */ uint8_t misc; /**< Misc Flags */ + uint8_t compress; /**< Compression Flags */ + uint32_t xzDecompressSize; /**< Size of uncompressed image */ } PACKED; /** @@ -221,4 +223,4 @@ void parseEntries (ffs_hdr* i_ffs_hdr, } // End namespace PNOR -#endif
\ No newline at end of file +#endif diff --git a/src/usr/pnor/pnorrp.C b/src/usr/pnor/pnorrp.C index b2b67a86d..725fa88e9 100644 --- a/src/usr/pnor/pnorrp.C +++ b/src/usr/pnor/pnorrp.C @@ -441,6 +441,10 @@ errlHndl_t PnorRP::getSectionInfo( PNOR::SectionId i_section, != 0) ? true : false; o_info.readOnly = ((iv_TOC[id].misc & FFS_MISC_READ_ONLY) != 0) ? true : false; + o_info.xzCompressed = ((iv_TOC[id].compress & FFS_COMPRESS_XZ) + != 0) ? true : false; + o_info.xzSize = ((iv_TOC[id].compress & FFS_COMPRESS_XZ) != 0) ? + iv_TOC[id].xzDecompressSize : 0; } return l_errhdl; diff --git a/src/usr/pnor/runtime/rt_pnor.C b/src/usr/pnor/runtime/rt_pnor.C index 33c1a2439..776fb1167 100644 --- a/src/usr/pnor/runtime/rt_pnor.C +++ b/src/usr/pnor/runtime/rt_pnor.C @@ -195,6 +195,11 @@ errlHndl_t RtPnor::getSectionInfo(PNOR::SectionId i_section, (iv_TOC[i_section].version & FFS_VERS_SHA512) ? true : false; o_info.sha512perEC = (iv_TOC[i_section].version & FFS_VERS_SHA512_PER_EC) ? true : false; + o_info.xzCompressed = + ((iv_TOC[i_section].compress & FFS_COMPRESS_XZ) != 0) ? true : false; + o_info.xzSize = + ((iv_TOC[i_section].compress & FFS_COMPRESS_XZ) != 0) ? + iv_TOC[i_section].xzDecompressSize : 0; } while (0); TRACFCOMP(g_trac_pnor, EXIT_MRK"RtPnor::getSectionInfo"); |