uboot-lantiq: danube: fix hanging lzma kernel uncompression
[openwrt/openwrt.git] / package / boot / uboot-lantiq / patches / 0030-lzma-force-8bit-reads.patch
1 From a40a6e16ed76e5e26a0f60226b64c311d4a62c9f Mon Sep 17 00:00:00 2001
2 From: Mathias Kresin <dev@kresin.me>
3 Date: Sun, 31 Oct 2021 23:04:54 +0100
4 Subject: [PATCH] lzma: force 8bit reads
5
6 At least since gcc 7.3.0 (OpenWrt 18.06) lwr/lwl are used in the
7 assembly of LzmaProps_Decode. While the decission made by the compiler
8 looks perfect fine, it triggers some obscure hang on lantiq danube-s
9 v1.5 with MX29LV640EB NOR flash chips.
10
11 Only if the offset 1 is used, the hang can be observed. Using any other
12 offset works fine:
13
14 lwl s0,0(a1) - s0 == 0x6d000080
15 lwl s0,1(a1) - hangs
16 lwl s0,2(a1) - s0 == 0x0080xxxx
17 lwl s0,3(a1) - s0 == 0x80xxxxxx
18
19 It isn't clear whether it is a limitation of the flash chip, the EBU or
20 something else.
21
22 Force 8bit reads to prevent gcc optimizing the read with lwr/lwl
23 instructions.
24
25 Signed-off-by: Mathias Kresin <dev@kresin.me>
26 ---
27 lib/lzma/LzmaDec.c | 3 ++-
28 1 file changed, 2 insertions(+), 1 deletion(-)
29
30 --- a/lib/lzma/LzmaDec.c
31 +++ b/lib/lzma/LzmaDec.c
32 @@ -7,6 +7,7 @@
33 #include "LzmaDec.h"
34
35 #include <linux/string.h>
36 +#include <asm/io.h>
37
38 #define kNumTopBits 24
39 #define kTopValue ((UInt32)1 << kNumTopBits)
40 @@ -929,7 +930,7 @@ SRes LzmaProps_Decode(CLzmaProps *p, con
41 if (size < LZMA_PROPS_SIZE)
42 return SZ_ERROR_UNSUPPORTED;
43 else
44 - dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
45 + dicSize = readb(&data[1]) | ((UInt32)readb(&data[2]) << 8) | ((UInt32)readb(&data[3]) << 16) | ((UInt32)readb(&data[4]) << 24);
46
47 if (dicSize < LZMA_DIC_MIN)
48 dicSize = LZMA_DIC_MIN;