aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/cbfs_core.c6
-rw-r--r--src/lib/lzmadecode.c11
2 files changed, 16 insertions, 1 deletions
diff --git a/src/lib/cbfs_core.c b/src/lib/cbfs_core.c
index 839b994cf3..50c037e573 100644
--- a/src/lib/cbfs_core.c
+++ b/src/lib/cbfs_core.c
@@ -202,6 +202,12 @@ int cbfs_decompress(int algo, void *src, void *dst, int len)
{
switch (algo) {
case CBFS_COMPRESS_NONE:
+ /* Reads need to be aligned at 4 bytes to avoid
+ poor flash performance. */
+ while (len && ((u32)src & 3)) {
+ *(u8*)dst++ = *(u8*)src++;
+ len--;
+ }
memmove(dst, src, len);
return len;
#ifdef CBFS_CORE_WITH_LZMA
diff --git a/src/lib/lzmadecode.c b/src/lib/lzmadecode.c
index 1cf647d27b..fb57f4fd4d 100644
--- a/src/lib/lzmadecode.c
+++ b/src/lib/lzmadecode.c
@@ -28,7 +28,10 @@
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5
-#define RC_READ_BYTE (*Buffer++)
+/* Use 32-bit reads whenever possible to avoid bad flash performance. */
+#define RC_READ_BYTE (look_ahead_ptr < 4 ? look_ahead.raw[look_ahead_ptr++] \
+ : ((((UInt32) Buffer & 3) || ((SizeT) (BufferLim - Buffer) < 4)) ? (*Buffer++) \
+ : ((look_ahead.dw = *(UInt32 *)Buffer), (Buffer += 4), (look_ahead_ptr = 1), look_ahead.raw[0])))
#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
{ int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
@@ -149,6 +152,12 @@ int LzmaDecode(CLzmaDecoderState *vs,
int len = 0;
const Byte *Buffer;
const Byte *BufferLim;
+ int look_ahead_ptr = 4;
+ union
+ {
+ Byte raw[4];
+ UInt32 dw;
+ } look_ahead;
UInt32 Range;
UInt32 Code;