summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorElizabeth Liner <eliner@us.ibm.com>2016-03-09 10:32:37 -0600
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2016-03-21 17:49:03 -0400
commit265ac2d6c7eee92deb434808c72af19b9ff4c9d5 (patch)
treeacd16f2f6ad54f9d009370d2c777658b677e9ef5 /src/usr
parent9ecc804688e872b8204addd52c6bea658b19afaa (diff)
downloadtalos-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.C2
-rw-r--r--src/usr/isteps/istep21/call_host_start_payload.C118
-rw-r--r--src/usr/pnor/common/ffs_hb.H20
-rw-r--r--src/usr/pnor/pnor_utils.C3
-rw-r--r--src/usr/pnor/pnor_utils.H4
-rw-r--r--src/usr/pnor/pnorrp.C4
-rw-r--r--src/usr/pnor/runtime/rt_pnor.C5
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");
OpenPOWER on IntegriCloud