From cba07dd682f0142474f0aa235e97b6fcbc34d760 Mon Sep 17 00:00:00 2001 From: Carl-Daniel Hailfinger Date: Thu, 14 Sep 2006 15:12:36 +0000 Subject: [PATCH] additions and mods for lzma. Signed-off-by: Carl-Daniel Hailfinger Signed-off-by: Ronald G. Minnich git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2413 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/arch/i386/Config.lb | 9 +- src/config/Options.lb | 12 +- src/lib/lzma.c | 39 ++ src/lib/lzmadecode.c | 398 ++++++++++++++++++++ src/lib/lzmadecode.h | 67 ++++ src/lib/nrv2b.c | 2 +- src/mainboard/amd/rumba/Options.lb | 2 +- src/mainboard/artecgroup/dbe61/Options.lb | 2 +- src/mainboard/olpc/rev_a/Options.lb | 3 +- src/mainboard/technologic/ts5300/Options.lb | 2 +- src/mainboard/via/epia-m/Options.lb | 2 +- src/stream/rom_stream.c | 47 ++- targets/artecgroup/dbe61/Config.lb | 2 +- targets/olpc/rev_a/Config.1M.lb | 2 +- targets/olpc/rev_a/Config.SPI.lb | 5 +- targets/olpc/rev_a/Config.lb | 2 +- 16 files changed, 578 insertions(+), 18 deletions(-) create mode 100644 src/lib/lzma.c create mode 100644 src/lib/lzmadecode.c create mode 100644 src/lib/lzmadecode.h diff --git a/src/arch/i386/Config.lb b/src/arch/i386/Config.lb index 6f614caf0..1b0dbf795 100644 --- a/src/arch/i386/Config.lb +++ b/src/arch/i386/Config.lb @@ -28,8 +28,15 @@ makerule payload.nrv2b action "./nrv2b e $(PAYLOAD) $@" end +# unlike nrv2b, lzma is a huge build mess. If they want lzma, they have to have built it +makerule payload.lzma + depends "$(PAYLOAD) " + action "lzma e $(PAYLOAD) $@" +end + makedefine PAYLOAD-1:=payload -makedefine PAYLOAD-$(CONFIG_COMPRESSED_ROM_STREAM):=payload.nrv2b +makedefine PAYLOAD-$(CONFIG_COMPRESSED_ROM_STREAM_NRV2B):=payload.nrv2b +makedefine PAYLOAD-$(CONFIG_COMPRESSED_ROM_STREAM_LZMA):=payload.lzma makerule linuxbios.rom depends "linuxbios.strip buildrom $(PAYLOAD-1)" diff --git a/src/config/Options.lb b/src/config/Options.lb index b4b971bc2..00042b8cf 100644 --- a/src/config/Options.lb +++ b/src/config/Options.lb @@ -572,7 +572,17 @@ end define CONFIG_COMPRESSED_ROM_STREAM default 0 export always - comment "compressed boot image is located in ROM" + comment "compressed boot image is located in ROM and is assumed to be NRV2B (deprecated)" +end +define CONFIG_COMPRESSED_ROM_STREAM_NRV2B + default 0 + export always + comment "NRV2B compressed boot image is located in ROM" +end +define CONFIG_COMPRESSED_ROM_STREAM_LZMA + default 0 + export always + comment "LZMA compressed boot image is located in ROM" end define CONFIG_PRECOMPRESSED_ROM_STREAM default 0 diff --git a/src/lib/lzma.c b/src/lib/lzma.c new file mode 100644 index 000000000..42746e102 --- /dev/null +++ b/src/lib/lzma.c @@ -0,0 +1,39 @@ +/* + +LinuxBIOS interface to memory-saving variant of LZMA decoder +(C)opyright 2006 Carl-Daniel Hailfinger +Released under the GNU GPL + +*/ + +#include "lzmadecode.c" + + +static unsigned long ulzma(unsigned char * src, unsigned char * dst) +{ + unsigned char properties[LZMA_PROPERTIES_SIZE]; + UInt32 outSize; + SizeT inProcessed; + SizeT outProcessed; + int res; + CLzmaDecoderState state; + SizeT mallocneeds; + unsigned char scratchpad[15980]; + + memcpy(properties, src, LZMA_PROPERTIES_SIZE); + outSize = *(UInt32 *)(src + LZMA_PROPERTIES_SIZE); + if (LzmaDecodeProperties(&state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK) { + printk_warning("Incorrect stream properties\n"); + } + mallocneeds = (LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); + if (mallocneeds > 15980) { + printk_warning("Decoder scratchpad too small!\n"); + } + state.Probs = (CProb *)scratchpad; + res = LzmaDecode(&state, src + LZMA_PROPERTIES_SIZE + 8, (SizeT)0xffffffff, &inProcessed, + dst, outSize, &outProcessed); + if (res != 0) { + printk_warning("Decoding error = %d\n", res); + } + return outSize; +} diff --git a/src/lib/lzmadecode.c b/src/lib/lzmadecode.c new file mode 100644 index 000000000..1c96283fb --- /dev/null +++ b/src/lib/lzmadecode.c @@ -0,0 +1,398 @@ +/* + LzmaDecode.c + LZMA Decoder (optimized for Speed version) + + LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this Code, expressly permits you to + statically or dynamically link your Code (or bind by name) to the + interfaces of this file without subjecting your linked Code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#include "lzmadecode.h" + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_READ_BYTE (*Buffer++) + +#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ + { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} + + +#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } + +#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 + + +#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } + +#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) +#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; +#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; + +#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ + { UpdateBit0(p); mi <<= 1; A0; } else \ + { UpdateBit1(p); mi = (mi + mi) + 1; A1; } + +#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;) + +#define RangeDecoderBitTreeDecode(probs, numLevels, res) \ + { int i = numLevels; res = 1; \ + do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \ + res -= (1 << numLevels); } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) +{ + unsigned char prop0; + if (size < LZMA_PROPERTIES_SIZE) + return LZMA_RESULT_DATA_ERROR; + prop0 = propsData[0]; + if (prop0 >= (9 * 5 * 5)) + return LZMA_RESULT_DATA_ERROR; + { + for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); + for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); + propsRes->lc = prop0; + /* + unsigned char remainder = (unsigned char)(prop0 / 9); + propsRes->lc = prop0 % 9; + propsRes->pb = remainder / 5; + propsRes->lp = remainder % 5; + */ + } + + return LZMA_RESULT_OK; +} + +#define kLzmaStreamWasFinishedId (-1) + +int LzmaDecode(CLzmaDecoderState *vs, + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) +{ + CProb *p = vs->Probs; + SizeT nowPos = 0; + Byte previousByte = 0; + UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; + UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; + int lc = vs->Properties.lc; + + + int state = 0; + UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; + int len = 0; + const Byte *Buffer; + const Byte *BufferLim; + UInt32 Range; + UInt32 Code; + + *inSizeProcessed = 0; + *outSizeProcessed = 0; + + { + UInt32 i; + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + } + + RC_INIT(inStream, inSize); + + + while(nowPos < outSize) + { + CProb *prob; + UInt32 bound; + int posState = (int)( + (nowPos + ) + & posStateMask); + + prob = p + IsMatch + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + int symbol = 1; + UpdateBit0(prob) + prob = p + Literal + (LZMA_LIT_SIZE * + ((( + (nowPos + ) + & literalPosMask) << lc) + (previousByte >> (8 - lc)))); + + if (state >= kNumLitStates) + { + int matchByte; + matchByte = outStream[nowPos - rep0]; + do + { + int bit; + CProb *probLit; + matchByte <<= 1; + bit = (matchByte & 0x100); + probLit = prob + 0x100 + bit + symbol; + RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) + } + while (symbol < 0x100); + } + while (symbol < 0x100) + { + CProb *probLit = prob + symbol; + RC_GET_BIT(probLit, symbol) + } + previousByte = (Byte)symbol; + + outStream[nowPos++] = previousByte; + if (state < 4) state = 0; + else if (state < 10) state -= 3; + else state -= 6; + } + else + { + UpdateBit1(prob); + prob = p + IsRep + state; + IfBit0(prob) + { + UpdateBit0(prob); + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + state = state < kNumLitStates ? 0 : 3; + prob = p + LenCoder; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG0 + state; + IfBit0(prob) + { + UpdateBit0(prob); + prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + UpdateBit0(prob); + + if (nowPos == 0) + return LZMA_RESULT_DATA_ERROR; + + state = state < kNumLitStates ? 9 : 11; + previousByte = outStream[nowPos - rep0]; + outStream[nowPos++] = previousByte; + + continue; + } + else + { + UpdateBit1(prob); + } + } + else + { + UInt32 distance; + UpdateBit1(prob); + prob = p + IsRepG1 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep1; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG2 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep2; + } + else + { + UpdateBit1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = p + RepLenCoder; + } + { + int numBits, offset; + CProb *probLen = prob + LenChoice; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + numBits = kLenNumLowBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenChoice2; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + numBits = kLenNumMidBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + numBits = kLenNumHighBits; + } + } + RangeDecoderBitTreeDecode(probLen, numBits, len); + len += offset; + } + + if (state < 4) + { + int posSlot; + state += kNumLitStates; + prob = p + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + rep0 = (2 | ((UInt32)posSlot & 1)); + if (posSlot < kEndPosModelIndex) + { + rep0 <<= numDirectBits; + prob = p + SpecPos + rep0 - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + RC_NORMALIZE + Range >>= 1; + rep0 <<= 1; + if (Code >= Range) + { + Code -= Range; + rep0 |= 1; + } + } + while (--numDirectBits != 0); + prob = p + Align; + rep0 <<= kNumAlignBits; + numDirectBits = kNumAlignBits; + } + { + int i = 1; + int mi = 1; + do + { + CProb *prob3 = prob + mi; + RC_GET_BIT2(prob3, mi, ; , rep0 |= i); + i <<= 1; + } + while(--numDirectBits != 0); + } + } + else + rep0 = posSlot; + if (++rep0 == (UInt32)(0)) + { + /* it's for stream version */ + len = kLzmaStreamWasFinishedId; + break; + } + } + + len += kMatchMinLen; + if (rep0 > nowPos) + return LZMA_RESULT_DATA_ERROR; + + + do + { + previousByte = outStream[nowPos - rep0]; + len--; + outStream[nowPos++] = previousByte; + } + while(len != 0 && nowPos < outSize); + } + } + RC_NORMALIZE; + + + *inSizeProcessed = (SizeT)(Buffer - inStream); + *outSizeProcessed = nowPos; + return LZMA_RESULT_OK; +} diff --git a/src/lib/lzmadecode.h b/src/lib/lzmadecode.h new file mode 100644 index 000000000..dedde0de6 --- /dev/null +++ b/src/lib/lzmadecode.h @@ -0,0 +1,67 @@ +/* + LzmaDecode.h + LZMA Decoder interface + + LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this code, expressly permits you to + statically or dynamically link your code (or bind by name) to the + interfaces of this file without subjecting your linked code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#ifndef __LZMADECODE_H +#define __LZMADECODE_H + +typedef unsigned char Byte; +typedef unsigned short UInt16; +typedef unsigned int UInt32; +typedef UInt32 SizeT; + +#define CProb UInt16 + +#define LZMA_RESULT_OK 0 +#define LZMA_RESULT_DATA_ERROR 1 + + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +#define LZMA_PROPERTIES_SIZE 5 + +typedef struct _CLzmaProperties +{ + int lc; + int lp; + int pb; +}CLzmaProperties; + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size); + +#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) + +#define kLzmaNeedInitId (-2) + +typedef struct _CLzmaDecoderState +{ + CLzmaProperties Properties; + CProb *Probs; + + +} CLzmaDecoderState; + + +int LzmaDecode(CLzmaDecoderState *vs, + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed); + +#endif diff --git a/src/lib/nrv2b.c b/src/lib/nrv2b.c index 4dd71e52a..db92ceb15 100644 --- a/src/lib/nrv2b.c +++ b/src/lib/nrv2b.c @@ -35,7 +35,7 @@ static unsigned long unrv2b(uint8_t * src, uint8_t * dst) uint32_t bb = 0; unsigned bc = 0; const uint8_t *m_pos; - unsigned long file_len = *(unsigned long *) src; +// unsigned long file_len = *(unsigned long *) src; // we only have printk_debug in copy_and_run.c if CONFIG_USE_INIT is // not set, so comment it out. diff --git a/src/mainboard/amd/rumba/Options.lb b/src/mainboard/amd/rumba/Options.lb index d55d8ce92..4c1030a31 100644 --- a/src/mainboard/amd/rumba/Options.lb +++ b/src/mainboard/amd/rumba/Options.lb @@ -21,7 +21,7 @@ uses ROM_IMAGE_SIZE uses ROM_SECTION_SIZE uses ROM_SECTION_OFFSET uses CONFIG_ROM_STREAM_START -uses CONFIG_COMPRESSED_ROM_STREAM +uses CONFIG_COMPRESSED_ROM_STREAM_NRV2B uses PAYLOAD_SIZE uses _ROMBASE uses _RAMBASE diff --git a/src/mainboard/artecgroup/dbe61/Options.lb b/src/mainboard/artecgroup/dbe61/Options.lb index 1112fcee2..ec4c78c33 100644 --- a/src/mainboard/artecgroup/dbe61/Options.lb +++ b/src/mainboard/artecgroup/dbe61/Options.lb @@ -21,7 +21,7 @@ uses ROM_IMAGE_SIZE uses ROM_SECTION_SIZE uses ROM_SECTION_OFFSET uses CONFIG_ROM_STREAM_START -uses CONFIG_COMPRESSED_ROM_STREAM +uses CONFIG_COMPRESSED_ROM_STREAM_NRV2B uses PAYLOAD_SIZE uses _ROMBASE uses _RAMBASE diff --git a/src/mainboard/olpc/rev_a/Options.lb b/src/mainboard/olpc/rev_a/Options.lb index e7a96ba15..36b0ab956 100644 --- a/src/mainboard/olpc/rev_a/Options.lb +++ b/src/mainboard/olpc/rev_a/Options.lb @@ -21,7 +21,8 @@ uses ROM_IMAGE_SIZE uses ROM_SECTION_SIZE uses ROM_SECTION_OFFSET uses CONFIG_ROM_STREAM_START -uses CONFIG_COMPRESSED_ROM_STREAM +uses CONFIG_COMPRESSED_ROM_STREAM_NRV2B +uses CONFIG_COMPRESSED_ROM_STREAM_LZMA uses CONFIG_PRECOMPRESSED_ROM_STREAM uses PAYLOAD_SIZE uses _ROMBASE diff --git a/src/mainboard/technologic/ts5300/Options.lb b/src/mainboard/technologic/ts5300/Options.lb index 079086c1a..d457d027e 100644 --- a/src/mainboard/technologic/ts5300/Options.lb +++ b/src/mainboard/technologic/ts5300/Options.lb @@ -6,7 +6,7 @@ uses HAVE_HARD_RESET uses HAVE_OPTION_TABLE uses USE_OPTION_TABLE uses CONFIG_COMPRESS -uses CONFIG_COMPRESSED_ROM_STREAM +uses CONFIG_COMPRESSED_ROM_STREAM_NRV2B uses CONFIG_ROM_STREAM uses CONFIG_USE_INIT uses IRQ_SLOT_COUNT diff --git a/src/mainboard/via/epia-m/Options.lb b/src/mainboard/via/epia-m/Options.lb index cd8fcf111..7342a5e07 100644 --- a/src/mainboard/via/epia-m/Options.lb +++ b/src/mainboard/via/epia-m/Options.lb @@ -21,7 +21,7 @@ uses ROM_IMAGE_SIZE uses ROM_SECTION_SIZE uses ROM_SECTION_OFFSET uses CONFIG_ROM_STREAM_START -uses CONFIG_COMPRESSED_ROM_STREAM +uses CONFIG_COMPRESSED_ROM_STREAM_NRV2B uses PAYLOAD_SIZE uses _ROMBASE uses _RAMBASE diff --git a/src/stream/rom_stream.c b/src/stream/rom_stream.c index ef8df9f39..711aa1f58 100644 --- a/src/stream/rom_stream.c +++ b/src/stream/rom_stream.c @@ -4,10 +4,30 @@ #include #include -#if CONFIG_COMPRESSED_ROM_STREAM || CONFIG_PRECOMPRESSED_ROM_STREAM +/* if they set the precompressed rom stream, they better have set a type */ +#if CONFIG_PRECOMPRESSED_ROM_STREAM && ((!CONFIG_COMPRESSED_ROM_STREAM) && (!CONFIG_COMPRESSED_ROM_STREAM_NRV2B) && (!CONFIG_COMPRESSED_ROM_STREAM_LZMA)) +#error "You set CONFIG_PRECOMPRESSED_ROM_STREAM but need to set CONFIG_COMPRESSED_ROM_STREAM (implies NRV2B, deprecated) or CONFIG_COMPRESSED_ROM_STREAM_NRV2B or CONFIG_COMPRESSED_ROM_STREAM_LZMA +#endif + +/* If they set ANY of these, then we're compressed */ +#if ((CONFIG_COMPRESSED_ROM_STREAM) || (CONFIG_COMPRESSED_ROM_STREAM_NRV2B) || (CONFIG_COMPRESSED_ROM_STREAM_LZMA)) +#define UNCOMPRESSER 1 +extern unsigned char _heap, _eheap; +#endif + +#if (CONFIG_COMPRESSED_ROM_STREAM) || (CONFIG_COMPRESSED_ROM_STREAM_NRV2B) +#define HAVE_UNCOMPRESSER 1 // include generic nrv2b #include "../lib/nrv2b.c" -extern unsigned char _heap, _eheap; +#endif + +#if (CONFIG_COMPRESSED_ROM_STREAM_LZMA) +#if HAVE_UNCOMPRESSER +#error "You're defining more than one compression type, which is not allowed (of course)" +#endif +#define HAVE_UNCOMPRESSER 1 +// include generic nrv2b +#include "../lib/lzma.c" #endif #ifndef CONFIG_ROM_STREAM_START @@ -29,9 +49,21 @@ extern unsigned char _heap, _eheap; static const unsigned char *rom; +#if UNCOMPRESSER +unsigned long +uncompress(uint8_t * rom_start, uint8_t *dest ) +{ +#if (CONFIG_COMPRESSED_ROM_STREAM) || (CONFIG_COMPRESSED_ROM_STREAM_NRV2B) + return unrv2b(rom_start, dest); +#endif +#if (CONFIG_COMPRESSED_ROM_STREAM_LZMA) + return ulzma(rom_start, dest); +#endif +} +#endif int stream_init(void) { -#if CONFIG_COMPRESSED_ROM_STREAM || CONFIG_PRECOMPRESSED_ROM_STREAM +#if (UNCOMPRESSER) unsigned char *dest; unsigned long olen; #endif @@ -40,7 +72,7 @@ int stream_init(void) (unsigned long)rom_start, (unsigned long)rom_end); -#if CONFIG_COMPRESSED_ROM_STREAM || CONFIG_PRECOMPRESSED_ROM_STREAM +#if (UNCOMPRESSER) dest = &_eheap; /* need a good address on RAM */ @@ -56,8 +88,13 @@ int stream_init(void) } #endif + /* ALL of those settings are too smart and also unsafe. Set the dest to 16 MB: + * known to be safe for LB for now, and mostly safe for all elf images we have tried. + * long term, this has got to be fixed. + */ + dest = (unsigned char *) (16 * 1024 * 1024); printk_debug("Uncompressing to RAM 0x%08lx ", dest); - olen = unrv2b((uint8_t *) rom_start, (uint8_t *)dest ); + olen = uncompress((uint8_t *) rom_start, (uint8_t *)dest ); printk_debug(" olen = 0x%08lx done.\n", olen); rom_end = dest + olen - 1; rom = dest; diff --git a/targets/artecgroup/dbe61/Config.lb b/targets/artecgroup/dbe61/Config.lb index b36693a3d..ae43f2ce9 100644 --- a/targets/artecgroup/dbe61/Config.lb +++ b/targets/artecgroup/dbe61/Config.lb @@ -3,7 +3,7 @@ target dbe61 mainboard artecgroup/dbe61 -option CONFIG_COMPRESSED_ROM_STREAM=0 +option CONFIG_COMPRESSED_ROM_STREAM_NRV2B=0 ## ROM_SIZE is the total number of bytes allocated for LinuxBIOS use ## (normal AND fallback images and payloads). diff --git a/targets/olpc/rev_a/Config.1M.lb b/targets/olpc/rev_a/Config.1M.lb index bd5c21442..d3c748ded 100644 --- a/targets/olpc/rev_a/Config.1M.lb +++ b/targets/olpc/rev_a/Config.1M.lb @@ -4,7 +4,7 @@ target rev_a_1M mainboard olpc/rev_a # Don't let LinuxBIOS compress the payload -# option CONFIG_COMPRESSED_ROM_STREAM=0 +# option CONFIG_COMPRESSED_ROM_STREAM_NRV2B=0 #option CONFIG_PRECOMPRESSED_ROM_STREAM=1 # leave 64k for vsa diff --git a/targets/olpc/rev_a/Config.SPI.lb b/targets/olpc/rev_a/Config.SPI.lb index ecea6f4e8..b7d0199a3 100644 --- a/targets/olpc/rev_a/Config.SPI.lb +++ b/targets/olpc/rev_a/Config.SPI.lb @@ -4,8 +4,9 @@ target rev_a_1M mainboard olpc/rev_a # Don't let LinuxBIOS compress the payload -# option CONFIG_COMPRESSED_ROM_STREAM=0 -#option CONFIG_PRECOMPRESSED_ROM_STREAM=1 +#option CONFIG_COMPRESSED_ROM_STREAM_NRV2B=0 +#option CONFIG_COMPRESSED_ROM_STREAM_LZMA=1 +#option CONFIG_PRECOMPRESSED_ROM_STREAM=0 # leave 64k for vsa and 64k for EC code option ROM_SIZE=(1024*1024)-(64*1024)-(64*1024) diff --git a/targets/olpc/rev_a/Config.lb b/targets/olpc/rev_a/Config.lb index fa6441d86..da46f84a4 100644 --- a/targets/olpc/rev_a/Config.lb +++ b/targets/olpc/rev_a/Config.lb @@ -4,7 +4,7 @@ target rev_a mainboard olpc/rev_a # leave 64k for vsa -option CONFIG_COMPRESSED_ROM_STREAM=0 +option CONFIG_COMPRESSED_ROM_STREAM_NRV2B=0 option ROM_SIZE=512*1024-64*1024 option FALLBACK_SIZE=ROM_SIZE -- 2.25.1