diff options
author | Mathias Kresin <dev@kresin.me> | 2021-11-05 10:41:26 +0100 |
---|---|---|
committer | Mathias Kresin <dev@kresin.me> | 2021-11-14 20:15:29 +0100 |
commit | 565b62cca2fc7d27f1f1584c44830a6e5c4f0f61 (patch) | |
tree | 453d81092d2e83b986e0e232e554e5478a24d3f6 /package/boot | |
parent | 9bd9e04b6fe7e427a5d90ccbb186c2727767a756 (diff) | |
download | upstream-565b62cca2fc7d27f1f1584c44830a6e5c4f0f61.tar.gz upstream-565b62cca2fc7d27f1f1584c44830a6e5c4f0f61.tar.bz2 upstream-565b62cca2fc7d27f1f1584c44830a6e5c4f0f61.zip |
uboot-lantiq: danube: fix hanging lzma kernel uncompression
At least since gcc 7.3.0 (OpenWrt 18.06) lwr/lwl are used in the
assembly of LzmaProps_Decode. While the decission made by the compiler
looks perfect fine, it triggers some obscure hang on lantiq danube-s
v1.5 with MX29LV640EB NOR flash chips.
Only if the offset 1 is used, the hang can be observed. Using any other
offset works fine:
lwl s0,0(a1) - s0 == 0x6d000080
lwl s0,1(a1) - hangs
lwl s0,2(a1) - s0 == 0x0080xxxx
lwl s0,3(a1) - s0 == 0x80xxxxxx
It isn't clear whether it is a limitation of the flash chip, the EBU or
something else.
Force 8bit reads to prevent gcc optimizing the read with lwr/lwl
instructions.
Signed-off-by: Mathias Kresin <dev@kresin.me>
Diffstat (limited to 'package/boot')
-rw-r--r-- | package/boot/uboot-lantiq/patches/0030-lzma-force-8bit-reads.patch | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/package/boot/uboot-lantiq/patches/0030-lzma-force-8bit-reads.patch b/package/boot/uboot-lantiq/patches/0030-lzma-force-8bit-reads.patch new file mode 100644 index 0000000000..dc7d9ed7ee --- /dev/null +++ b/package/boot/uboot-lantiq/patches/0030-lzma-force-8bit-reads.patch @@ -0,0 +1,48 @@ +From a40a6e16ed76e5e26a0f60226b64c311d4a62c9f Mon Sep 17 00:00:00 2001 +From: Mathias Kresin <dev@kresin.me> +Date: Sun, 31 Oct 2021 23:04:54 +0100 +Subject: [PATCH] lzma: force 8bit reads + +At least since gcc 7.3.0 (OpenWrt 18.06) lwr/lwl are used in the +assembly of LzmaProps_Decode. While the decission made by the compiler +looks perfect fine, it triggers some obscure hang on lantiq danube-s +v1.5 with MX29LV640EB NOR flash chips. + +Only if the offset 1 is used, the hang can be observed. Using any other +offset works fine: + + lwl s0,0(a1) - s0 == 0x6d000080 + lwl s0,1(a1) - hangs + lwl s0,2(a1) - s0 == 0x0080xxxx + lwl s0,3(a1) - s0 == 0x80xxxxxx + +It isn't clear whether it is a limitation of the flash chip, the EBU or +something else. + +Force 8bit reads to prevent gcc optimizing the read with lwr/lwl +instructions. + +Signed-off-by: Mathias Kresin <dev@kresin.me> +--- + lib/lzma/LzmaDec.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/lib/lzma/LzmaDec.c ++++ b/lib/lzma/LzmaDec.c +@@ -7,6 +7,7 @@ + #include "LzmaDec.h" + + #include <linux/string.h> ++#include <asm/io.h> + + #define kNumTopBits 24 + #define kTopValue ((UInt32)1 << kNumTopBits) +@@ -929,7 +930,7 @@ SRes LzmaProps_Decode(CLzmaProps *p, con + if (size < LZMA_PROPS_SIZE) + return SZ_ERROR_UNSUPPORTED; + else +- dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); ++ dicSize = readb(&data[1]) | ((UInt32)readb(&data[2]) << 8) | ((UInt32)readb(&data[3]) << 16) | ((UInt32)readb(&data[4]) << 24); + + if (dicSize < LZMA_DIC_MIN) + dicSize = LZMA_DIC_MIN; |