[PATCH 1/3] ARM: decompressor: always set endianess on xscale

From: Linus Walleij

Date: Wed Jul 08 2026 - 18:25:29 EST


From: Arnd Bergmann <arnd@xxxxxxxx>

In BE32 configurations, endianess is always set to BE in Control
Register C1, originally to allow booting BE kernels from a LE bootloader
on IXP12xx.

To also allow the opposite and allow booting LE kernels from a BE
IXP4xx bootloader, moving this code into head-xscale.S along with the
recommended serialization sequence and flip the B bit into the correct
position regardless of its original state.

Note that both the endianess switch sequence and the cp15wait I add
here should be harmless on all supported ARMv4/v4t/v5 CPUs, but the
existing cache flush code is not actually defined on ARM720 and may
cause problems in multiplatform kernels that include both Xscale
and CLPS711x.

Signed-off-by: Arnd Bergmann <arnd@xxxxxxxx>
Signed-off-by: Linus Walleij <linusw@xxxxxxxxxx>
---
arch/arm/boot/compressed/Makefile | 8 --------
arch/arm/boot/compressed/big-endian.S | 14 --------------
arch/arm/boot/compressed/head-xscale.S | 12 ++++++++++++
3 files changed, 12 insertions(+), 22 deletions(-)

diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index e3f550d62857..5993dd1d0ee9 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -41,14 +41,6 @@ ifeq ($(CONFIG_PXA_SHARPSL_DETECT_MACH_ID),y)
OBJS += head-sharpsl.o
endif

-ifeq ($(CONFIG_CPU_ENDIAN_BE32),y)
-ifeq ($(CONFIG_CPU_CP15),y)
-OBJS += big-endian.o
-else
-# The endian should be set by h/w design.
-endif
-endif
-
#
# We now have a PIC decompressor implementation. Decompressors running
# from RAM should not define ZTEXTADDR. Decompressors running directly
diff --git a/arch/arm/boot/compressed/big-endian.S b/arch/arm/boot/compressed/big-endian.S
deleted file mode 100644
index 0e092c36da2f..000000000000
--- a/arch/arm/boot/compressed/big-endian.S
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * linux/arch/arm/boot/compressed/big-endian.S
- *
- * Switch CPU into big endian mode.
- * Author: Nicolas Pitre
- */
-
- .section ".start", "ax"
-
- mrc p15, 0, r0, c1, c0, 0 @ read control reg
- orr r0, r0, #(1 << 7) @ enable big endian mode
- mcr p15, 0, r0, c1, c0, 0 @ write control reg
-
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S
index 20fa44d59f82..86705c865be6 100644
--- a/arch/arm/boot/compressed/head-xscale.S
+++ b/arch/arm/boot/compressed/head-xscale.S
@@ -14,6 +14,18 @@ __XScale_start:

@ Preserve r8/r7 i.e. kernel entry values

+ @ set correct endianness for ixp4xx regardless of bootloader
+ mrc p15, 0, r0, c1, c0, 0
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ orr r0, r0, #(1 << 7) @ enable big endian mode
+#else
+ bic r0, r0, #0x80
+#endif
+ mcr p15, 0, r0, c1, c0, 0
+ mrc p15, 0, r0, c2, c0, 0
+ mov r0, r0
+ sub pc, pc, #4 @ flush instruction pipeline
+
@ Data cache might be active.
@ Be sure to flush kernel binary out of the cache,
@ whatever state it is, before it is turned off.

--
2.55.0