summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJules Maselbas <jmaselbas@zdiv.net>2023-09-07 17:20:45 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2023-09-08 15:19:53 +0200
commitf73d9b66c0ea15f6181cd1de59a92ce29733a2cc (patch)
tree702ee96c6d82c2d6002f6247ce5e275d50598814 /lib
parent34b36519d7535d9de34ad09facd82ddc2140b3fc (diff)
downloadbarebox-f73d9b66c0ea15f6181cd1de59a92ce29733a2cc.tar.gz
barebox-f73d9b66c0ea15f6181cd1de59a92ce29733a2cc.tar.xz
decompressors: Update xz to include ARM64 BCJ decoder
Update lib/xz/xz_dec_bcj.c and lib/xz/xz_private.h files from xz-embedded [1], which include spelling fixes and the new ARM64 BCJ decoder which was recently introduced into .xz file format version 1.1.0 (2022-12-11) [2]. [1] https://git.tukaani.org/?p=xz-embedded.git [2] https://tukaani.org/xz/xz-file-format-1.1.0.txt Signed-off-by: Jules Maselbas <jmaselbas@zdiv.net> Link: https://lore.barebox.org/20230907152047.102747-1-jmaselbas@zdiv.net Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig4
-rw-r--r--lib/decompress_unxz.c6
-rw-r--r--lib/xz/xz_dec_bcj.c54
-rw-r--r--lib/xz/xz_private.h5
4 files changed, 64 insertions, 5 deletions
diff --git a/lib/Kconfig b/lib/Kconfig
index 758197b608..aaede68645 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -42,6 +42,7 @@ config XZ_DECOMPRESS
select XZ_DEC_ARM
select XZ_DEC_ARMTHUMB
select XZ_DEC_SPARC
+ select XZ_DEC_ARM64
config XZ_DEC_X86
bool
@@ -61,6 +62,9 @@ config XZ_DEC_ARMTHUMB
config XZ_DEC_SPARC
bool
+config XZ_DEC_ARM64
+ bool
+
config REED_SOLOMON
bool
diff --git a/lib/decompress_unxz.c b/lib/decompress_unxz.c
index a7e2d331ab..132ab4a239 100644
--- a/lib/decompress_unxz.c
+++ b/lib/decompress_unxz.c
@@ -131,7 +131,11 @@
# define XZ_DEC_POWERPC
#endif
#ifdef CONFIG_ARM
-# define XZ_DEC_ARM
+# ifdef CONFIG_CPU_64
+# define XZ_DEC_ARM64
+# else
+# define XZ_DEC_ARM
+# endif
#endif
#ifdef CONFIG_IA64
# define XZ_DEC_IA64
diff --git a/lib/xz/xz_dec_bcj.c b/lib/xz/xz_dec_bcj.c
index d268adbc65..d40fae3416 100644
--- a/lib/xz/xz_dec_bcj.c
+++ b/lib/xz/xz_dec_bcj.c
@@ -2,7 +2,7 @@
* Branch/Call/Jump (BCJ) filter decoders
*
* Authors: Lasse Collin <lasse.collin@tukaani.org>
- * Igor Pavlov <http://7-zip.org/>
+ * Igor Pavlov <https://7-zip.org/>
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
@@ -24,7 +24,8 @@ struct xz_dec_bcj {
BCJ_IA64 = 6, /* Big or little endian */
BCJ_ARM = 7, /* Little endian only */
BCJ_ARMTHUMB = 8, /* Little endian only */
- BCJ_SPARC = 9 /* Big or little endian */
+ BCJ_SPARC = 9, /* Big or little endian */
+ BCJ_ARM64 = 10 /* AArch64 */
} type;
/*
@@ -334,6 +335,45 @@ static size_t bcj_sparc(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
}
#endif
+#ifdef XZ_DEC_ARM64
+static size_t bcj_arm64(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
+{
+ size_t i;
+ uint32_t instr;
+ uint32_t addr;
+
+ for (i = 0; i + 4 <= size; i += 4) {
+ instr = get_unaligned_le32(buf + i);
+
+ if ((instr >> 26) == 0x25) {
+ /* BL instruction */
+ addr = instr - ((s->pos + (uint32_t)i) >> 2);
+ instr = 0x94000000 | (addr & 0x03FFFFFF);
+ put_unaligned_le32(instr, buf + i);
+
+ } else if ((instr & 0x9F000000) == 0x90000000) {
+ /* ADRP instruction */
+ addr = ((instr >> 29) & 3) | ((instr >> 3) & 0x1FFFFC);
+
+ /* Only convert values in the range +/-512 MiB. */
+ if ((addr + 0x020000) & 0x1C0000)
+ continue;
+
+ addr -= (s->pos + (uint32_t)i) >> 12;
+
+ instr &= 0x9000001F;
+ instr |= (addr & 3) << 29;
+ instr |= (addr & 0x03FFFC) << 3;
+ instr |= (0U - (addr & 0x020000)) & 0xE00000;
+
+ put_unaligned_le32(instr, buf + i);
+ }
+ }
+
+ return i;
+}
+#endif
+
/*
* Apply the selected BCJ filter. Update *pos and s->pos to match the amount
* of data that got filtered.
@@ -381,6 +421,11 @@ static void bcj_apply(struct xz_dec_bcj *s,
filtered = bcj_sparc(s, buf, size);
break;
#endif
+#ifdef XZ_DEC_ARM64
+ case BCJ_ARM64:
+ filtered = bcj_arm64(s, buf, size);
+ break;
+#endif
default:
/* Never reached but silence compiler warnings. */
filtered = 0;
@@ -422,7 +467,7 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s,
/*
* Flush pending already filtered data to the output buffer. Return
- * immediatelly if we couldn't flush everything, or if the next
+ * immediately if we couldn't flush everything, or if the next
* filter in the chain had already returned XZ_STREAM_END.
*/
if (s->temp.filtered > 0) {
@@ -554,6 +599,9 @@ XZ_EXTERN enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id)
#ifdef XZ_DEC_SPARC
case BCJ_SPARC:
#endif
+#ifdef XZ_DEC_ARM64
+ case BCJ_ARM64:
+#endif
break;
default:
diff --git a/lib/xz/xz_private.h b/lib/xz/xz_private.h
index 85f79635f0..b14a262c92 100644
--- a/lib/xz/xz_private.h
+++ b/lib/xz/xz_private.h
@@ -37,6 +37,9 @@
# ifdef CONFIG_XZ_DEC_SPARC
# define XZ_DEC_SPARC
# endif
+# ifdef CONFIG_XZ_DEC_ARM64
+# define XZ_DEC_ARM64
+# endif
# define memeq(a, b, size) (memcmp(a, b, size) == 0)
# define memzero(buf, size) memset(buf, 0, size)
# define FREE free
@@ -98,7 +101,7 @@
#ifndef XZ_DEC_BCJ
# if defined(XZ_DEC_X86) || defined(XZ_DEC_POWERPC) \
|| defined(XZ_DEC_IA64) || defined(XZ_DEC_ARM) \
- || defined(XZ_DEC_ARM) || defined(XZ_DEC_ARMTHUMB) \
+ || defined(XZ_DEC_ARM64) || defined(XZ_DEC_ARMTHUMB) \
|| defined(XZ_DEC_SPARC)
# define XZ_DEC_BCJ
# endif