summaryrefslogtreecommitdiffstats
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
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>
-rwxr-xr-xsrc/build/buildpnor/buildpnor.pl28
-rw-r--r--src/include/usr/isteps/hwpf_reasoncodes.H5
-rw-r--r--src/include/usr/pnor/pnor_const.H4
-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
10 files changed, 160 insertions, 33 deletions
diff --git a/src/build/buildpnor/buildpnor.pl b/src/build/buildpnor/buildpnor.pl
index 116c77912..7284c22e5 100755
--- a/src/build/buildpnor/buildpnor.pl
+++ b/src/build/buildpnor/buildpnor.pl
@@ -6,7 +6,7 @@
#
# OpenPOWER HostBoot Project
#
-# Contributors Listed Below - COPYRIGHT 2012,2015
+# Contributors Listed Below - COPYRIGHT 2012,2016
# [+] International Business Machines Corp.
#
#
@@ -216,6 +216,14 @@ sub loadPnorLayout
my $sha512perEC = (exists $sectionEl->{sha512perEC} ? "yes" : "no");
my $preserved = (exists $sectionEl->{preserved} ? "yes" : "no");
my $readOnly = (exists $sectionEl->{readOnly} ? "yes" : "no");
+ my $xz = "";
+ my $xzSize = 0;
+ if ((exists $sectionEl->{compressed}) &&
+ ($sectionEl->{compressed}[0]->{algorithm}[0] eq "xz"))
+ {
+ $xz = "xz";
+ $xzSize = $sectionEl->{compressed}[0]->{uncompressedSize}[0];
+ }
if (($testRun == 0) && ($sectionEl->{testonly}[0] eq "yes"))
{
next;
@@ -236,6 +244,8 @@ sub loadPnorLayout
$$i_pnorLayoutRef{sections}{$physicalOffset}{sha512perEC} = $sha512perEC;
$$i_pnorLayoutRef{sections}{$physicalOffset}{preserved} = $preserved;
$$i_pnorLayoutRef{sections}{$physicalOffset}{readOnly} = $readOnly;
+ $$i_pnorLayoutRef{sections}{$physicalOffset}{compressed}{algorithm} = $xz;
+ $$i_pnorLayoutRef{sections}{$physicalOffset}{compressed}{uncompressedSize} = $xzSize;
#store the physical offsets of each section in a hash, so, it is easy
#to search physicalOffsets based on the name of the section (eyecatch)
@@ -370,6 +380,7 @@ sub addUserData
# User data Flags based on FFS entry user data (ffs_hb_user_t)
my $chip = 0;
my $compressType = 0;
+ my $compressSize = 0;
my $dataInteg = 0;
my $verCheck = 0;
my $miscFlags = 0;
@@ -390,6 +401,13 @@ sub addUserData
$verCheck = 0x40;
}
+ # Compression Flag
+ if( ($i_sectionHash{$i_key}{compressed}{algorithm} eq "xz") )
+ {
+ $compressType = 0x80;
+ $compressSize = $i_sectionHash{$i_key}{compressed}{uncompressedSize};
+ }
+
# Misc Flags
if( ($i_sectionHash{$i_key}{preserved} eq "yes") )
{
@@ -411,6 +429,10 @@ sub addUserData
my $userflags1 = ($verCheck << 24)
| ($miscFlags << 16);
+ #Third User Data Word
+ #[1,2:compressSize]
+ my $userflags2 = hex($compressSize);
+
trace(2, "$g_fpartCmd --target $i_pnorBinName --partition-offset $i_offset --user 0 --name $eyeCatch --value userflags0=$userflags0");
system("$g_fpartCmd --target $i_pnorBinName --partition-offset $i_offset --user 0 --name $eyeCatch --value $userflags0");
die "ERROR: $this_func: Call to add userdata to $eyeCatch failed. Aborting!" if($?);
@@ -418,6 +440,10 @@ sub addUserData
trace(2, "$g_fpartCmd --target $i_pnorBinName --partition-offset $i_offset --user 1 --name $eyeCatch --value userflags1=$userflags1");
system("$g_fpartCmd --target $i_pnorBinName --partition-offset $i_offset --user 1 --name $eyeCatch --value $userflags1");
die "ERROR: $this_func: Call to add userdata to $eyeCatch failed. Aborting!" if($?);
+
+ trace(2, "$g_fpartCmd --target $i_pnorBinName --partition-offset $i_offset --user 2 --name $eyeCatch --value userflags2=$userflags2");
+ system("$g_fpartCmd --target $i_pnorBinName --partition-offset $i_offset --user 2 --name $eyeCatch --value $userflags2");
+ die "ERROR: $this_func: Call to add userdata to $eyeCatch failed. Aborting!" if($?);
}
################################################################################
diff --git a/src/include/usr/isteps/hwpf_reasoncodes.H b/src/include/usr/isteps/hwpf_reasoncodes.H
index 9737f9cdd..23bf0501e 100644
--- a/src/include/usr/isteps/hwpf_reasoncodes.H
+++ b/src/include/usr/isteps/hwpf_reasoncodes.H
@@ -5,7 +5,8 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2015 */
+/* Contributors Listed Below - COPYRIGHT 2013,2016 */
+/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -83,6 +84,7 @@ namespace fapi
MOD_SET_NEST_FREQ = 0x2A,
MOD_FIND_MIN_DMI_SPD = 0x2B,
MOD_OCC_LOAD_HOST_DATA_TO_SRAM = 0x2C,
+ MOD_START_XZ_PAYLOAD = 0x2D,
};
/**
@@ -144,6 +146,7 @@ namespace fapi
RC_INVALID_ULTRA_TURBO_FREQ = HWPF_COMP_ID | 0x3B,
RC_INVALID_WOF_INDEX = HWPF_COMP_ID | 0x3C,
RC_ECMD_INSERT_FAILED = HWPF_COMP_ID | 0x3D,
+ RC_INVALID_RETURN_XZ_CODE = HWPF_COMP_ID | 0x3E,
};
/**
diff --git a/src/include/usr/pnor/pnor_const.H b/src/include/usr/pnor/pnor_const.H
index 1f0b08574..88f0b8ab4 100644
--- a/src/include/usr/pnor/pnor_const.H
+++ b/src/include/usr/pnor/pnor_const.H
@@ -85,6 +85,8 @@ struct SectionInfo_t
bool sha512Version; /**< Version Checking */
bool sha512perEC; /**< Version Checking perEC */
bool readOnly; /**< Section is read only */
+ bool xzCompressed; /**< Section is XZ compressed */
+ uint32_t xzSize; /**< Size of uncompressed partition in bytes */
};
/**
@@ -119,4 +121,4 @@ enum TestSectionOffset{
}
-#endif \ No newline at end of file
+#endif
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