Skip to content

Commit

Permalink
uboot-lantiq: danube: fix hanging lzma kernel uncompression
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
mkresin committed Nov 14, 2021
1 parent 4b0f877 commit c744798
Showing 1 changed file with 48 additions and 0 deletions.
48 changes: 48 additions & 0 deletions package/boot/uboot-lantiq/patches/0030-lzma-force-8bit-reads.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
From a40a6e16ed76e5e26a0f60226b64c311d4a62c9f Mon Sep 17 00:00:00 2001
From: Mathias Kresin <[email protected]>
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 <[email protected]>
---
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;

0 comments on commit c744798

Please sign in to comment.