[PATCH 00/13] Arm64 big endian enablement

Hi all,
This series enabled big endian support for arm64, enabled qemu-arm board for arm64be and slightly adjusted our Kconfig handling on endianness.
In practical I think most Arm SoCs do support little endian only, for those SoCs with big endian support they are usually bi-endian and expected bootloader in little endian. The only big-endian only Arm SoC I know is a network processor from ZTE ZXIC, I doubt if upstream U-Boot will ever support it.
However enabling arm64be can enable us to take more care on big endian targets, given that arm64 is the most feature rich arch in U-Boot, we can run more test on big endian systems.
Boot tested on qemu.
Please review.
Thanks
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- Jiaxun Yang (13): tools/relocate-rela: Fix Big Endian elf64 handling arm: Don't select ARM_ASM_UNIFIED on arm64 arm: Fix assembler.h for arm64 arm: Introduce CPU_LE/CPU_BE macros arm: Define endian related bits in system.h armv8: Big Endian enablement for compiler and linker arm: Perform byte swap for read and write in io.h armv8: Allow endianness to be setted at reset entry armv8: spin_table: Perform byte swap for jump address lib/crc32: Don't perform byte swap for arm64 crc32b Kconfig: Unify endian support option config: Use CONFIG_SYS_BIG_ENDIAN in code whenever possible qemu-arm: Big endian enablement for arm64
Makefile | 2 +- arch/Kconfig | 34 ++++++++--- arch/arc/include/asm/arc-bcr.h | 10 +-- arch/arm/Kconfig | 3 +- arch/arm/config.mk | 14 +++++ arch/arm/cpu/armv8/Kconfig | 9 +++ .../arm/cpu/armv8/linux-kernel-image-header-vars.h | 4 +- arch/arm/cpu/armv8/spin_table_v8.S | 2 + arch/arm/cpu/armv8/start.S | 26 ++++++++ arch/arm/cpu/armv8/u-boot-spl.lds | 6 ++ arch/arm/cpu/armv8/u-boot.lds | 4 ++ arch/arm/include/asm/assembler.h | 25 ++++++++ arch/arm/include/asm/io.h | 12 ++-- arch/arm/include/asm/system.h | 3 + arch/arm/lib/elf_aarch64_efi.lds | 7 +++ arch/mips/Kconfig | 20 +++--- arch/mips/mach-ath79/Kconfig | 8 +-- arch/mips/mach-bmips/Kconfig | 20 +++--- arch/mips/mach-jz47xx/Kconfig | 2 +- arch/mips/mach-mscc/Kconfig | 4 +- arch/mips/mach-pic32/Kconfig | 2 +- board/emulation/qemu-arm/Kconfig | 2 + board/emulation/qemu-arm/MAINTAINERS | 1 + configs/qemu_arm64be_defconfig | 71 ++++++++++++++++++++++ doc/board/emulation/qemu-arm.rst | 7 ++- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 2 +- lib/crc32.c | 3 +- scripts/Makefile.build | 2 +- scripts/Makefile.lib | 3 +- tools/relocate-rela.c | 40 +++++++----- 30 files changed, 271 insertions(+), 77 deletions(-) --- base-commit: 3be9f399e911cfc437a37ac826441f1d96da1c9b change-id: 20240518-aarch64-be-1ec99cf7f28b
Best regards,

Implement elf64_to_cpu and use it when necessary.
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- tools/relocate-rela.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-)
diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c index 613abd25ef46..cbdd2552ec6e 100644 --- a/tools/relocate-rela.c +++ b/tools/relocate-rela.c @@ -111,6 +111,14 @@ static uint32_t cpu_to_elf32(uint32_t data) return cpu_to_be32(data); }
+static uint64_t elf64_to_cpu(uint64_t data) +{ + if (ei_data == ELFDATA2LSB) + return le64_to_cpu(data); + + return be64_to_cpu(data); +} + static bool supported_rela(Elf64_Rela *rela) { uint64_t mask = 0xffffffffULL; /* would be different on 32-bit */ @@ -150,7 +158,7 @@ static int decode_elf64(FILE *felf, char **argv) return 25; }
- machine = le16_to_cpu(header.e_machine); + machine = elf16_to_cpu(header.e_machine); debug("Machine\t%d\n", machine);
if (machine != EM_AARCH64) { @@ -158,10 +166,10 @@ static int decode_elf64(FILE *felf, char **argv) return 30; }
- text_base = le64_to_cpu(header.e_entry); - section_header_base = le64_to_cpu(header.e_shoff); - section_header_size = le16_to_cpu(header.e_shentsize) * - le16_to_cpu(header.e_shnum); + text_base = elf64_to_cpu(header.e_entry); + section_header_base = elf64_to_cpu(header.e_shoff); + section_header_size = elf16_to_cpu(header.e_shentsize) * + elf16_to_cpu(header.e_shnum);
sh_table = malloc(section_header_size); if (!sh_table) { @@ -189,8 +197,8 @@ static int decode_elf64(FILE *felf, char **argv) return 27; }
- sh_index = le16_to_cpu(header.e_shstrndx); - sh_size = le64_to_cpu(sh_table[sh_index].sh_size); + sh_index = elf16_to_cpu(header.e_shstrndx); + sh_size = elf64_to_cpu(sh_table[sh_index].sh_size); debug("e_shstrndx %x, sh_size %lx\n", sh_index, sh_size);
sh_str = malloc(sh_size); @@ -205,8 +213,8 @@ static int decode_elf64(FILE *felf, char **argv) * Specifies the byte offset from the beginning of the file * to the first byte in the section. */ - sh_offset = le64_to_cpu(sh_table[sh_index].sh_offset); - sh_num = le16_to_cpu(header.e_shnum); + sh_offset = elf64_to_cpu(sh_table[sh_index].sh_offset); + sh_num = elf16_to_cpu(header.e_shnum);
ret = fseek(felf, sh_offset, SEEK_SET); if (ret) { @@ -228,13 +236,13 @@ static int decode_elf64(FILE *felf, char **argv) }
for (i = 0; i < sh_num; i++) { - char *sh_name = sh_str + le32_to_cpu(sh_table[i].sh_name); + char *sh_name = sh_str + elf32_to_cpu(sh_table[i].sh_name);
debug("%s\n", sh_name);
- sh_addr = le64_to_cpu(sh_table[i].sh_addr); - sh_offset = le64_to_cpu(sh_table[i].sh_offset); - sh_size = le64_to_cpu(sh_table[i].sh_size); + sh_addr = elf64_to_cpu(sh_table[i].sh_addr); + sh_offset = elf64_to_cpu(sh_table[i].sh_offset); + sh_size = elf64_to_cpu(sh_table[i].sh_size);
if (!strcmp(".rela.dyn", sh_name)) { debug("Found section\t".rela_dyn"\n"); @@ -480,9 +488,9 @@ static int rela_elf64(char **argv, FILE *f) return 4; }
- swrela.r_offset = le64_to_cpu(rela.r_offset); - swrela.r_info = le64_to_cpu(rela.r_info); - swrela.r_addend = le64_to_cpu(rela.r_addend); + swrela.r_offset = elf64_to_cpu(rela.r_offset); + swrela.r_info = elf64_to_cpu(rela.r_info); + swrela.r_addend = elf64_to_cpu(rela.r_addend);
if (!supported_rela(&swrela)) continue;

We don't have thumb on arm64, so that's pointless and causing problems on some headers.
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- arch/arm/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 39ad03acd2e4..46c0d33b3c6e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -152,8 +152,7 @@ config GPIO_EXTRA_HEADER
# Used for compatibility with asm files copied from the kernel config ARM_ASM_UNIFIED - bool - default y + def_bool !ARM64
# Used for compatibility with asm files copied from the kernel config THUMB2_KERNEL

Header guard is missing, and ret macro is not relevant for arm64.
Both fixed.
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- arch/arm/include/asm/assembler.h | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 4fda483b8d8d..c3b8f34dd0af 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -14,6 +14,9 @@ * assembler source. */
+#ifndef __ASM_ARM_ASSEMBLER_H +#define __ASM_ARM_ASSEMBLER_H + #include <asm/unified.h>
/* @@ -56,6 +59,7 @@ #define PLD(code...) #endif
+#if !defined(__aarch64__) /* * Use 'bx lr' everywhere except ARMv4 (without 'T') where only 'mov pc, lr' * works @@ -75,6 +79,7 @@ #endif .endm .endr +#endif
/* * Cache aligned, used for optimized memcpy/memset @@ -87,3 +92,5 @@ #else #define CALGN(code...) code #endif + +#endif

They come from the same header in Linux. They are used to conditional select code on different endianness.
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- arch/arm/include/asm/assembler.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index c3b8f34dd0af..2a3858d15d4e 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -93,4 +93,22 @@ #define CALGN(code...) code #endif
+/* + * Select code when configured for BE. + */ +#if CONFIG_IS_ENABLED(SYS_BIG_ENDIAN) +#define CPU_BE(code...) code +#else +#define CPU_BE(code...) +#endif + +/* + * Select code when configured for LE. + */ +#if CONFIG_IS_ENABLED(SYS_BIG_ENDIAN) +#define CPU_LE(code...) +#else +#define CPU_LE(code...) code +#endif + #endif

So they can be used at a later point.
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- arch/arm/include/asm/system.h | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 43f7503571d7..886a9ffbee35 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -15,6 +15,7 @@ #define CR_SA (1 << 3) /* Stack Alignment Check Enable */ #define CR_I (1 << 12) /* Icache enable */ #define CR_WXN (1 << 19) /* Write Permision Imply XN */ +#define CR_E0E (1 << 24) /* Endianness of EL0 */ #define CR_EE (1 << 25) /* Exception (Big) Endian */
#define ES_TO_AARCH64 1 @@ -58,6 +59,7 @@ */ #define SCTLR_EL2_RES1 (3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 |\ 1 << 11 | 3 << 4) /* Reserved, RES1 */ +#define SCTLR_EL2_EE_BE (1 << 25) /* Exception Little-endian */ #define SCTLR_EL2_EE_LE (0 << 25) /* Exception Little-endian */ #define SCTLR_EL2_WXN_DIS (0 << 19) /* Write permission is not XN */ #define SCTLR_EL2_ICACHE_DIS (0 << 12) /* Instruction cache disabled */ @@ -114,6 +116,7 @@ 1 << 11) /* Reserved, RES1 */ #define SCTLR_EL1_UCI_DIS (0 << 26) /* Cache instruction disabled */ #define SCTLR_EL1_EE_LE (0 << 25) /* Exception Little-endian */ +#define SCTLR_EL1_EE_BE (1 << 25) /* Exception Little-endian */ #define SCTLR_EL1_WXN_DIS (0 << 19) /* Write permission is not XN */ #define SCTLR_EL1_NTWE_DIS (0 << 18) /* WFE instruction disabled */ #define SCTLR_EL1_NTWI_DIS (0 << 16) /* WFI instruction disabled */

Pass flags to compilers and linkers, also modify linker scripts to set correct output format.
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- arch/arm/config.mk | 14 ++++++++++++++ arch/arm/cpu/armv8/u-boot-spl.lds | 6 ++++++ arch/arm/cpu/armv8/u-boot.lds | 4 ++++ arch/arm/lib/elf_aarch64_efi.lds | 7 +++++++ scripts/Makefile.lib | 3 ++- 5 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/arch/arm/config.mk b/arch/arm/config.mk index 5530d02b66c4..b3f70c1fe9db 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -34,11 +34,25 @@ PLATFORM_RELFLAGS += $(LLVM_RELFLAGS) PLATFORM_CPPFLAGS += -D__ARM__
ifdef CONFIG_ARM64 +ifdef CONFIG_SYS_BIG_ENDIAN +PLATFORM_ELFFLAGS += -B aarch64 -O elf64-bigaarch64 +else PLATFORM_ELFFLAGS += -B aarch64 -O elf64-littleaarch64 +endif else PLATFORM_ELFFLAGS += -B arm -O elf32-littlearm endif
+ifdef CONFIG_SYS_LITTLE_ENDIAN +KBUILD_LDFLAGS += -EL +PLATFORM_CPPFLAGS += -mlittle-endian +endif + +ifdef CONFIG_SYS_BIG_ENDIAN +KBUILD_LDFLAGS += -EB +PLATFORM_CPPFLAGS += -mbig-endian +endif + # Choose between ARM/Thumb instruction sets ifeq ($(CONFIG_$(SPL_)SYS_THUMB_BUILD),y) AFLAGS_IMPLICIT_IT := $(call as-option,-Wa$(comma)-mimplicit-it=always) diff --git a/arch/arm/cpu/armv8/u-boot-spl.lds b/arch/arm/cpu/armv8/u-boot-spl.lds index ef8af67e11c3..1848c501c234 100644 --- a/arch/arm/cpu/armv8/u-boot-spl.lds +++ b/arch/arm/cpu/armv8/u-boot-spl.lds @@ -11,12 +11,18 @@ * Aneesh V aneesh@ti.com */
+#include <config.h> + MEMORY { .sram : ORIGIN = IMAGE_TEXT_BASE, LENGTH = IMAGE_MAX_SIZE } MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+#if CONFIG_IS_ENABLED(SYS_BIG_ENDIAN) +OUTPUT_FORMAT("elf64-bigaarch64", "elf64-bigaarch64", "elf64-bigaarch64") +#else OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") +#endif OUTPUT_ARCH(aarch64) ENTRY(_start) SECTIONS diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds index 857f44412e07..f357e5468e27 100644 --- a/arch/arm/cpu/armv8/u-boot.lds +++ b/arch/arm/cpu/armv8/u-boot.lds @@ -10,7 +10,11 @@ #include <config.h> #include <asm/psci.h>
+#if CONFIG_IS_ENABLED(SYS_BIG_ENDIAN) +OUTPUT_FORMAT("elf64-bigaarch64", "elf64-bigaarch64", "elf64-bigaarch64") +#else OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") +#endif OUTPUT_ARCH(aarch64) ENTRY(_start) SECTIONS diff --git a/arch/arm/lib/elf_aarch64_efi.lds b/arch/arm/lib/elf_aarch64_efi.lds index 5dd98091698c..4bba305bab35 100644 --- a/arch/arm/lib/elf_aarch64_efi.lds +++ b/arch/arm/lib/elf_aarch64_efi.lds @@ -5,7 +5,14 @@ * Modified from elf_aarch64_efi.lds in gnu-efi */
+#include <config.h> + +#if CONFIG_IS_ENABLED(SYS_BIG_ENDIAN) +OUTPUT_FORMAT("elf64-bigaarch64", "elf64-bigaarch64", "elf64-bigaarch64") +#else OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") +#endif + OUTPUT_ARCH(aarch64)
PHDRS diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 62f87517c09c..ff88cc3e55cd 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -475,7 +475,8 @@ cmd_efi_objcopy = $(OBJCOPY) -j .header -j .text -j .sdata -j .data -j \ $(obj)/%.efi: $(obj)/%_efi.so $(call cmd,efi_objcopy)
-KBUILD_EFILDFLAGS = -nostdlib -zexecstack -znocombreloc -znorelro +KBUILD_EFILDFLAGS += $(if $(CONFIG_SYS_BIG_ENDIAN),-EB,-EL) +KBUILD_EFILDFLAGS += -nostdlib -zexecstack -znocombreloc -znorelro KBUILD_EFILDFLAGS += $(call ld-option,--no-warn-rwx-segments) quiet_cmd_efi_ld = LD $@ cmd_efi_ld = $(LD) $(KBUILD_EFILDFLAGS) -T $(EFI_LDS_PATH) \

I/O is always assumed little endian, so perform byte swap if necessary, as what Linux did.
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- arch/arm/include/asm/io.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 89b1015bc4d3..864ad5ae5c61 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -99,14 +99,14 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen) #define smp_processor_id() 0
#define writeb(v,c) ({ u8 __v = v; __iowmb(); __arch_putb(__v,c); __v; }) -#define writew(v,c) ({ u16 __v = v; __iowmb(); __arch_putw(__v,c); __v; }) -#define writel(v,c) ({ u32 __v = v; __iowmb(); __arch_putl(__v,c); __v; }) -#define writeq(v,c) ({ u64 __v = v; __iowmb(); __arch_putq(__v,c); __v; }) +#define writew(v,c) ({ u16 __v = v; __iowmb(); __arch_putw((__force u16)cpu_to_le16(__v), c); __v; }) +#define writel(v,c) ({ u32 __v = v; __iowmb(); __arch_putl((__force u32)cpu_to_le32(__v), c); __v; }) +#define writeq(v,c) ({ u64 __v = v; __iowmb(); __arch_putq((__force u64)cpu_to_le64(__v), c); __v; })
#define readb(c) ({ u8 __v = __arch_getb(c); __iormb(); __v; }) -#define readw(c) ({ u16 __v = __arch_getw(c); __iormb(); __v; }) -#define readl(c) ({ u32 __v = __arch_getl(c); __iormb(); __v; }) -#define readq(c) ({ u64 __v = __arch_getq(c); __iormb(); __v; }) +#define readw(c) ({ u16 __v = le16_to_cpu((__force __le16)__arch_getw(c)); __iormb(); __v; }) +#define readl(c) ({ u32 __v = le32_to_cpu((__force __le32)__arch_getl(c)); __iormb(); __v; }) +#define readq(c) ({ u64 __v = le64_to_cpu((__force __le64)__arch_getq(c)); __iormb(); __v; })
/* * Relaxed I/O memory access primitives. These follow the Device memory

Provide a option to allow Endian at U-Boot's EL to be setted at reset entry.
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- arch/arm/cpu/armv8/Kconfig | 9 +++++++++ arch/arm/cpu/armv8/start.S | 26 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+)
diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig index 9f0fb369f773..4b38ee12de58 100644 --- a/arch/arm/cpu/armv8/Kconfig +++ b/arch/arm/cpu/armv8/Kconfig @@ -14,6 +14,15 @@ config ARMV8_SPL_EXCEPTION_VECTORS Say N here if you are running out of code space in the image and want to save some space at the cost of less debugging info.
+config ARMV8_RESET_SET_ENDIAN + bool "Set CPU endianness at reset entry" + help + Perform endianness setting with SCTLR_ELx registers at U-Boot's + reset entry. + + Say Y here if your CPU may comes out of reset in a different + endianness. + config ARMV8_MULTIENTRY bool "Enable multiple CPUs to enter into U-Boot"
diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S index 746128026172..2e6ae2f6f3ca 100644 --- a/arch/arm/cpu/armv8/start.S +++ b/arch/arm/cpu/armv8/start.S @@ -9,6 +9,7 @@ #include <linux/linkage.h> #include <asm/macro.h> #include <asm/armv8/mmu.h> +#include <asm/assembler.h>
/************************************************************************* * @@ -53,6 +54,31 @@ _bss_end_ofs: .quad __bss_end - _start
reset: +#if CONFIG_IS_ENABLED(ARMV8_RESET_SET_ENDIAN) + switch_el x16, 3f, 2f, 1f +3: mrs x16, sctlr_el3 +CPU_BE( mov x17, #(CR_EE)) +CPU_BE( orr x16, x17, x16) +CPU_LE( mov x17, #~(CR_EE)) +CPU_LE( and x16, x17, x16) + msr sctlr_el3, x16 + isb +2: mrs x16, sctlr_el2 +CPU_BE( mov x17, #(CR_EE | CR_E0E)) +CPU_BE( orr x16, x17, x16) +CPU_LE( mov x17, #~(CR_EE | CR_E0E)) +CPU_LE( and x16, x17, x16) + msr sctlr_el2, x16 + isb +1: mrs x16, sctlr_el1 +CPU_BE( mov x17, #(CR_EE | CR_E0E)) +CPU_BE( orr x16, x17, x16) +CPU_LE( mov x17, #~(CR_EE | CR_E0E)) +CPU_LE( and x16, x17, x16) + msr sctlr_el1, x16 +0: isb +#endif + /* Allow the board to save important registers */ b save_boot_params .globl save_boot_params_ret

Address comes from spin table is always little endian.
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- arch/arm/cpu/armv8/spin_table_v8.S | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/cpu/armv8/spin_table_v8.S b/arch/arm/cpu/armv8/spin_table_v8.S index 6d268432702f..023c82261ca6 100644 --- a/arch/arm/cpu/armv8/spin_table_v8.S +++ b/arch/arm/cpu/armv8/spin_table_v8.S @@ -12,6 +12,8 @@ spin_table_reserve_begin: 0: wfe ldr x0, spin_table_cpu_release_addr cbz x0, 0b + /* spin-table is always little endian */ +CPU_BE( rev x0, x0) br x0 .globl spin_table_cpu_release_addr .align 3

crc32b always calculate results in CPU's native endian, so there is no need to perform any endian swap.
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- lib/crc32.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/lib/crc32.c b/lib/crc32.c index f36f1763064f..b991e477b31d 100644 --- a/lib/crc32.c +++ b/lib/crc32.c @@ -183,10 +183,9 @@ const uint32_t * ZEXPORT get_crc_table() uint32_t __efi_runtime crc32_no_comp(uint32_t crc, const Bytef *buf, uInt len) { #ifdef CONFIG_ARM64_CRC32 - crc = cpu_to_le32(crc); while (len--) crc = __builtin_aarch64_crc32b(crc, *buf++); - return le32_to_cpu(crc); + return crc; #else const uint32_t *tab = crc_table; const uint32_t *b =(const uint32_t *)buf;

Move SUPPORT_BIG_ENDIAN, SUPPORT_LITTLE_ENDIAN to top-level arch Kconfig and let architectures select them as necessary.
Remove if guard for Endianness selection choice so we can have one of SYS_BIG_ENDIAN, SYS_LITTLE_ENDIAN config symbol defined even on single endian system.
Default endian to SYS_BIG_ENDIAN for MIPS || MICROBLAZE and LITTLE_ENDIAN for the rest to retain old config behaviour.
Note: PPC, SH, Xtensa are technically bi-endian, but I checked compiled u-boot image with readelf, U-Boot currently only support little endian for SH and Xtensa, Big Endian for PPC.
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- arch/Kconfig | 34 ++++++++++++++++++++++++++-------- arch/mips/Kconfig | 20 +++++++------------- arch/mips/mach-ath79/Kconfig | 8 ++++---- arch/mips/mach-bmips/Kconfig | 20 ++++++++++---------- arch/mips/mach-jz47xx/Kconfig | 2 +- arch/mips/mach-mscc/Kconfig | 4 ++-- arch/mips/mach-pic32/Kconfig | 2 +- 7 files changed, 51 insertions(+), 39 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig index abd406d48841..8f1f46670128 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -8,6 +8,13 @@ config CREATE_ARCH_SYMLINK config HAVE_ARCH_IOREMAP bool
+config SUPPORT_BIG_ENDIAN + bool + +config SUPPORT_LITTLE_ENDIAN + bool + default y if !SUPPORT_BIG_ENDIAN + config SYS_CACHE_SHIFT_4 bool
@@ -59,6 +66,8 @@ config ARC select SUPPORT_OF_CONTROL select SYS_CACHE_SHIFT_7 select TIMER + select SUPPORT_BIG_ENDIAN + select SUPPORT_LITTLE_ENDIAN select SYS_BIG_ENDIAN if CPU_BIG_ENDIAN select SYS_LITTLE_ENDIAN if !CPU_BIG_ENDIAN
@@ -68,6 +77,7 @@ config ARM select CREATE_ARCH_SYMLINK select HAVE_PRIVATE_LIBGCC if !ARM64 select SUPPORT_ACPI + select SUPPORT_LITTLE_ENDIAN select SUPPORT_OF_CONTROL
config M68K @@ -77,10 +87,13 @@ config M68K select SYS_BOOT_GET_CMDLINE select SYS_BOOT_GET_KBD select SYS_CACHE_SHIFT_4 + select SUPPORT_BIG_ENDIAN select SUPPORT_OF_CONTROL
config MICROBLAZE bool "MicroBlaze architecture" + select SUPPORT_BIG_ENDIAN + select SUPPORT_LITTLE_ENDIAN select SUPPORT_OF_CONTROL imply CMD_TIMER imply SPL_REGMAP if SPL @@ -101,12 +114,14 @@ config NIOS2 select DM select DM_EVENT select OF_CONTROL + select SUPPORT_LITTLE_ENDIAN select SUPPORT_OF_CONTROL imply CMD_DM
config PPC bool "PowerPC architecture" select HAVE_PRIVATE_LIBGCC + select SUPPORT_BIG_ENDIAN select SUPPORT_OF_CONTROL select SYS_BOOT_GET_CMDLINE select SYS_BOOT_GET_KBD @@ -115,6 +130,7 @@ config RISCV bool "RISC-V architecture" select CREATE_ARCH_SYMLINK select SUPPORT_ACPI + select SUPPORT_LITTLE_ENDIAN select SUPPORT_OF_CONTROL select OF_CONTROL select DM @@ -160,6 +176,8 @@ config SANDBOX select PCI_ENDPOINT select SPI select SUPPORT_OF_CONTROL + select SUPPORT_BIG_ENDIAN + select SUPPORT_LITTLE_ENDIAN select SYSRESET_CMD_POWEROFF if CMD_POWEROFF select SYS_CACHE_SHIFT_4 select IRQ @@ -224,6 +242,7 @@ config SANDBOX
config SH bool "SuperH architecture" + select SUPPORT_LITTLE_ENDIAN select HAVE_PRIVATE_LIBGCC select SUPPORT_OF_CONTROL
@@ -231,6 +250,7 @@ config X86 bool "x86 architecture" select SUPPORT_SPL select SUPPORT_TPL + select SUPPORT_LITTLE_ENDIAN select CREATE_ARCH_SYMLINK select DM select HAVE_ARCH_IOMAP @@ -312,6 +332,7 @@ config X86 config XTENSA bool "Xtensa architecture" select CREATE_ARCH_SYMLINK + select SUPPORT_LITTLE_ENDIAN select SUPPORT_OF_CONTROL
endchoice @@ -515,24 +536,21 @@ endif
source "board/keymile/Kconfig"
-if MIPS || MICROBLAZE - choice prompt "Endianness selection" + default SYS_BIG_ENDIAN if MIPS || MICROBLAZE + default SYS_LITTLE_ENDIAN help - Some MIPS boards can be configured for either little or big endian + Some boards can be configured for either little or big endian byte order. These modes require different U-Boot images. In general there is one preferred byteorder for a particular system but some systems are just as commonly used in the one or the other endianness.
config SYS_BIG_ENDIAN bool "Big endian" - depends on (SUPPORTS_BIG_ENDIAN && MIPS) || MICROBLAZE + depends on SUPPORT_BIG_ENDIAN
config SYS_LITTLE_ENDIAN bool "Little endian" - depends on (SUPPORTS_LITTLE_ENDIAN && MIPS) || MICROBLAZE - + depends on SUPPORT_LITTLE_ENDIAN endchoice - -endif diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index eb7f3ad23762..38577af43d03 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -28,14 +28,14 @@ config TARGET_MALTA select OF_ISA_BUS select PCI_MAP_SYSTEM_MEMORY select ROM_EXCEPTION_VECTORS - select SUPPORTS_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 select SUPPORTS_CPU_MIPS32_R6 select SUPPORTS_CPU_MIPS64_R1 select SUPPORTS_CPU_MIPS64_R2 select SUPPORTS_CPU_MIPS64_R6 - select SUPPORTS_LITTLE_ENDIAN + select SUPPORT_BIG_ENDIAN + select SUPPORT_LITTLE_ENDIAN select SWAP_IO_SPACE imply CMD_DM
@@ -86,7 +86,7 @@ config ARCH_MTMIPS select ROM_EXCEPTION_VECTORS select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 - select SUPPORTS_LITTLE_ENDIAN + select SUPPORT_LITTLE_ENDIAN select SUPPORT_SPL
config ARCH_JZ47XX @@ -112,7 +112,7 @@ config ARCH_OCTEON select MIPS_TUNE_OCTEON3 select MTD select ROM_EXCEPTION_VECTORS - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS64_OCTEON select PHYS_64BIT select OF_CONTROL @@ -138,14 +138,14 @@ config TARGET_BOSTON select OF_BOARD_SETUP select OF_CONTROL select ROM_EXCEPTION_VECTORS - select SUPPORTS_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 select SUPPORTS_CPU_MIPS32_R6 select SUPPORTS_CPU_MIPS64_R1 select SUPPORTS_CPU_MIPS64_R2 select SUPPORTS_CPU_MIPS64_R6 - select SUPPORTS_LITTLE_ENDIAN + select SUPPORT_BIG_ENDIAN + select SUPPORT_LITTLE_ENDIAN imply CMD_DM
config TARGET_XILFPGA @@ -159,7 +159,7 @@ config TARGET_XILFPGA select ROM_EXCEPTION_VECTORS select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 - select SUPPORTS_LITTLE_ENDIAN + select SUPPORT_LITTLE_ENDIAN imply CMD_DM help This supports IMGTEC MIPSfpga platform @@ -413,12 +413,6 @@ config MIPS_BOOT_FDT
endmenu
-config SUPPORTS_BIG_ENDIAN - bool - -config SUPPORTS_LITTLE_ENDIAN - bool - config SUPPORTS_CPU_MIPS32_R1 bool
diff --git a/arch/mips/mach-ath79/Kconfig b/arch/mips/mach-ath79/Kconfig index cd85d1b6c31b..2fa628568aa0 100644 --- a/arch/mips/mach-ath79/Kconfig +++ b/arch/mips/mach-ath79/Kconfig @@ -8,7 +8,7 @@ config SOC_AR933X bool select MIPS_TUNE_24KC select ROM_EXCEPTION_VECTORS - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 help @@ -17,7 +17,7 @@ config SOC_AR933X config SOC_AR934X bool select MIPS_TUNE_74KC - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 select USB_EHCI_IS_TDI if USB_EHCI_HCD @@ -28,7 +28,7 @@ config SOC_QCA953X bool select MIPS_TUNE_24KC select ROM_EXCEPTION_VECTORS - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 help @@ -37,7 +37,7 @@ config SOC_QCA953X config SOC_QCA956X bool select MIPS_TUNE_74KC - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 help diff --git a/arch/mips/mach-bmips/Kconfig b/arch/mips/mach-bmips/Kconfig index eb9ea34c52fe..b140552657ff 100644 --- a/arch/mips/mach-bmips/Kconfig +++ b/arch/mips/mach-bmips/Kconfig @@ -23,7 +23,7 @@ config SOC_BMIPS_BCM3380 bool "BMIPS BCM3380 family" select SYS_CACHE_SHIFT_4 select MIPS_TUNE_4KC - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SYSRESET_WATCHDOG help @@ -33,7 +33,7 @@ config SOC_BMIPS_BCM6318 bool "BMIPS BCM6318 family" select SYS_CACHE_SHIFT_4 select MIPS_TUNE_4KC - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SYSRESET_SYSCON help @@ -43,7 +43,7 @@ config SOC_BMIPS_BCM6328 bool "BMIPS BCM6328 family" select SYS_CACHE_SHIFT_4 select MIPS_TUNE_4KC - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SYSRESET_SYSCON help @@ -53,7 +53,7 @@ config SOC_BMIPS_BCM6338 bool "BMIPS BCM6338 family" select SYS_CACHE_SHIFT_4 select MIPS_TUNE_4KC - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SYSRESET_SYSCON help @@ -63,7 +63,7 @@ config SOC_BMIPS_BCM6348 bool "BMIPS BCM6348 family" select SYS_CACHE_SHIFT_4 select MIPS_TUNE_4KC - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SYSRESET_WATCHDOG help @@ -73,7 +73,7 @@ config SOC_BMIPS_BCM6358 bool "BMIPS BCM6358 family" select SYS_CACHE_SHIFT_4 select MIPS_TUNE_4KC - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SYSRESET_SYSCON help @@ -83,7 +83,7 @@ config SOC_BMIPS_BCM6368 bool "BMIPS BCM6368 family" select SYS_CACHE_SHIFT_4 select MIPS_TUNE_4KC - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SYSRESET_SYSCON help @@ -93,7 +93,7 @@ config SOC_BMIPS_BCM6362 bool "BMIPS BCM6362 family" select SYS_CACHE_SHIFT_4 select MIPS_TUNE_4KC - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SYSRESET_SYSCON help @@ -103,7 +103,7 @@ config SOC_BMIPS_BCM63268 bool "BMIPS BCM63268 family" select SYS_CACHE_SHIFT_4 select MIPS_TUNE_4KC - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SYSRESET_SYSCON help @@ -114,7 +114,7 @@ config SOC_BMIPS_BCM6838 bool "BMIPS BCM6838 family" select SYS_CACHE_SHIFT_4 select MIPS_TUNE_4KC - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SYSRESET_SYSCON help diff --git a/arch/mips/mach-jz47xx/Kconfig b/arch/mips/mach-jz47xx/Kconfig index dcaac0162866..858173e75b40 100644 --- a/arch/mips/mach-jz47xx/Kconfig +++ b/arch/mips/mach-jz47xx/Kconfig @@ -6,7 +6,7 @@ config SYS_SOC
config SOC_JZ4780 bool - select SUPPORTS_LITTLE_ENDIAN + select SUPPORT_LITTLE_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 help diff --git a/arch/mips/mach-mscc/Kconfig b/arch/mips/mach-mscc/Kconfig index affc4721f82e..367d5248a1cc 100644 --- a/arch/mips/mach-mscc/Kconfig +++ b/arch/mips/mach-mscc/Kconfig @@ -6,10 +6,10 @@ menu "MSCC VCore-III platforms" config SOC_VCOREIII select MIPS_TUNE_24KC select ROM_EXCEPTION_VECTORS - select SUPPORTS_BIG_ENDIAN + select SUPPORT_BIG_ENDIAN select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 - select SUPPORTS_LITTLE_ENDIAN + select SUPPORT_LITTLE_ENDIAN bool
config SYS_SOC diff --git a/arch/mips/mach-pic32/Kconfig b/arch/mips/mach-pic32/Kconfig index 2afa972074c1..52d2eec0a766 100644 --- a/arch/mips/mach-pic32/Kconfig +++ b/arch/mips/mach-pic32/Kconfig @@ -13,7 +13,7 @@ config SOC_PIC32MZDA select ROM_EXCEPTION_VECTORS select SUPPORTS_CPU_MIPS32_R1 select SUPPORTS_CPU_MIPS32_R2 - select SUPPORTS_LITTLE_ENDIAN + select SUPPORT_LITTLE_ENDIAN select SYS_MIPS_CACHE_INIT_RAM_LOAD help This supports Microchip PIC32MZ[DA] family of microcontrollers.

So CONFIG_SYS_BIG_ENDIAN is our cross architecture option for selecting machine endian, while the old CONFIG_CPU_BIG_ENDIAN is defined by Arc only.
Use it whenever possible to ensure big endian code path is enabled for all possible big endian machines.
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- Makefile | 2 +- arch/arc/include/asm/arc-bcr.h | 10 +++++----- arch/arm/cpu/armv8/linux-kernel-image-header-vars.h | 4 ++-- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 2 +- scripts/Makefile.build | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/Makefile b/Makefile index 44deb339af19..49959ecf3100 100644 --- a/Makefile +++ b/Makefile @@ -1048,7 +1048,7 @@ endif CHECKFLAGS += --arch=$(ARCH)
# insure the checker run with the right endianness -CHECKFLAGS += $(if $(CONFIG_CPU_BIG_ENDIAN),-mbig-endian,-mlittle-endian) +CHECKFLAGS += $(if $(CONFIG_SYS_BIG_ENDIAN),-mbig-endian,-mlittle-endian)
# the checker needs the correct machine size CHECKFLAGS += $(if $(CONFIG_64BIT),-m64,-m32) diff --git a/arch/arc/include/asm/arc-bcr.h b/arch/arc/include/asm/arc-bcr.h index a6c972bf1e31..d4de9b818c1a 100644 --- a/arch/arc/include/asm/arc-bcr.h +++ b/arch/arc/include/asm/arc-bcr.h @@ -15,7 +15,7 @@
union bcr_di_cache { struct { -#ifdef CONFIG_CPU_BIG_ENDIAN +#ifdef CONFIG_SYS_BIG_ENDIAN unsigned int pad:12, line_len:4, sz:4, config:4, ver:8; #else unsigned int ver:8, config:4, sz:4, line_len:4, pad:12; @@ -26,7 +26,7 @@ union bcr_di_cache {
union bcr_slc_cfg { struct { -#ifdef CONFIG_CPU_BIG_ENDIAN +#ifdef CONFIG_SYS_BIG_ENDIAN unsigned int pad:24, way:2, lsz:2, sz:4; #else unsigned int sz:4, lsz:2, way:2, pad:24; @@ -37,7 +37,7 @@ union bcr_slc_cfg {
union bcr_generic { struct { -#ifdef CONFIG_CPU_BIG_ENDIAN +#ifdef CONFIG_SYS_BIG_ENDIAN unsigned int pad:24, ver:8; #else unsigned int ver:8, pad:24; @@ -48,7 +48,7 @@ union bcr_generic {
union bcr_clust_cfg { struct { -#ifdef CONFIG_CPU_BIG_ENDIAN +#ifdef CONFIG_SYS_BIG_ENDIAN unsigned int pad:7, c:1, num_entries:8, num_cores:8, ver:8; #else unsigned int ver:8, num_cores:8, num_entries:8, c:1, pad:7; @@ -59,7 +59,7 @@ union bcr_clust_cfg {
union bcr_mmu_4 { struct { -#ifdef CONFIG_CPU_BIG_ENDIAN +#ifdef CONFIG_SYS_BIG_ENDIAN unsigned int ver:8, sasid:1, sz1:4, sz0:4, res:2, pae:1, n_ways:2, n_entry:2, n_super:2, u_itlb:3, u_dtlb:3; #else diff --git a/arch/arm/cpu/armv8/linux-kernel-image-header-vars.h b/arch/arm/cpu/armv8/linux-kernel-image-header-vars.h index b6394aee1657..c6af825dbc7b 100644 --- a/arch/arm/cpu/armv8/linux-kernel-image-header-vars.h +++ b/arch/arm/cpu/armv8/linux-kernel-image-header-vars.h @@ -31,7 +31,7 @@ * when PIE is in effect. So we need to split them up in 32-bit high and low * words. */ -#ifdef CONFIG_CPU_BIG_ENDIAN +#ifdef CONFIG_SYS_BIG_ENDIAN #define DATA_LE32(data) \ ((((data) & 0x000000ff) << 24) | \ (((data) & 0x0000ff00) << 8) | \ @@ -55,7 +55,7 @@ #endif #define __MEM_USAGE (__CODE_DATA_SIZE + __MAX_EXTRA_RAM_USAGE)
-#ifdef CONFIG_CPU_BIG_ENDIAN +#ifdef CONFIG_SYS_BIG_ENDIAN #define __HEAD_FLAG_BE 1 #else #define __HEAD_FLAG_BE 0 diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index b7bf7cc0893d..b1af3f717d43 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -1698,7 +1698,7 @@ static int brcmnand_fill_dma_desc(struct brcmnand_host *host, desc->cmd_irq = (dma_cmd << 24) | (end ? (0x03 << 8) : 0) | /* IRQ | STOP */ (!!begin) | ((!!end) << 1); /* head, tail */ -#ifdef CONFIG_CPU_BIG_ENDIAN +#ifdef CONFIG_SYS_BIG_ENDIAN desc->cmd_irq |= 0x01 << 12; #endif desc->dram_addr = lower_32_bits(buf); diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 97dd4a64f6ef..99cc29595b4a 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -224,7 +224,7 @@ recordmcount_source := $(srctree)/scripts/recordmcount.c \ $(srctree)/scripts/recordmcount.h else sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ - "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \ + "$(if $(CONFIG_SYS_BIG_ENDIAN),big,little)" \ "$(if $(CONFIG_64BIT),64,32)" \ "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)" \ "$(LD) $(KBUILD_LDFLAGS)" "$(NM)" "$(RM)" "$(MV)" \

Select a few config option and generate a new defconfig for big endian arm64.
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com --- board/emulation/qemu-arm/Kconfig | 2 + board/emulation/qemu-arm/MAINTAINERS | 1 + configs/qemu_arm64be_defconfig | 71 ++++++++++++++++++++++++++++++++++++ doc/board/emulation/qemu-arm.rst | 7 +++- 4 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/board/emulation/qemu-arm/Kconfig b/board/emulation/qemu-arm/Kconfig index e21c135e86fa..4c98340a62f4 100644 --- a/board/emulation/qemu-arm/Kconfig +++ b/board/emulation/qemu-arm/Kconfig @@ -5,8 +5,10 @@ config TEXT_BASE
config BOARD_SPECIFIC_OPTIONS # dummy def_bool y + select ARMV8_RESET_SET_ENDIAN if ARM64 select QFW if ACPI select QFW_MMIO if CMD_QFW + select SUPPORT_BIG_ENDIAN if ARM64 imply VIRTIO_MMIO imply VIRTIO_PCI imply VIRTIO_NET diff --git a/board/emulation/qemu-arm/MAINTAINERS b/board/emulation/qemu-arm/MAINTAINERS index 5154262f29ea..9384b1003d2c 100644 --- a/board/emulation/qemu-arm/MAINTAINERS +++ b/board/emulation/qemu-arm/MAINTAINERS @@ -6,3 +6,4 @@ F: board/emulation/common/ F: include/configs/qemu-arm.h F: configs/qemu_arm_defconfig F: configs/qemu_arm64_defconfig +F: configs/qemu_arm64be_defconfig diff --git a/configs/qemu_arm64be_defconfig b/configs/qemu_arm64be_defconfig new file mode 100644 index 000000000000..af05f484036d --- /dev/null +++ b/configs/qemu_arm64be_defconfig @@ -0,0 +1,71 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_ARCH_QEMU=y +CONFIG_SYS_MALLOC_LEN=0x1000000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x40200000 +CONFIG_ENV_SIZE=0x40000 +CONFIG_ENV_SECT_SIZE=0x40000 +CONFIG_DEFAULT_DEVICE_TREE="qemu-arm64" +CONFIG_DEBUG_UART_BASE=0x9000000 +CONFIG_DEBUG_UART_CLOCK=0 +CONFIG_ARMV8_CRYPTO=y +CONFIG_SYS_LOAD_ADDR=0x40200000 +CONFIG_ENV_ADDR=0x4000000 +CONFIG_PCI=y +CONFIG_DEBUG_UART=y +CONFIG_AHCI=y +CONFIG_SYS_BIG_ENDIAN=y +CONFIG_FIT=y +CONFIG_FIT_SIGNATURE=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_BEST_MATCH=y +CONFIG_BOOTSTD_FULL=y +CONFIG_LEGACY_IMAGE_FORMAT=y +CONFIG_USE_PREBOOT=y +# CONFIG_DISPLAY_CPUINFO is not set +# CONFIG_DISPLAY_BOARDINFO is not set +CONFIG_PCI_INIT_R=y +CONFIG_CMD_SMBIOS=y +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_BOOTEFI_SELFTEST=y +CONFIG_CMD_NVEDIT_EFI=y +CONFIG_CMD_DFU=y +CONFIG_CMD_MTD=y +CONFIG_CMD_PCI=y +CONFIG_CMD_TPM=y +CONFIG_CMD_MTDPARTS=y +CONFIG_ENV_IS_IN_FLASH=y +CONFIG_SCSI_AHCI=y +CONFIG_AHCI_PCI=y +CONFIG_DFU_TFTP=y +CONFIG_DFU_MTD=y +CONFIG_DFU_RAM=y +# CONFIG_MMC is not set +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_NOR_FLASH=y +CONFIG_FLASH_SHOW_PROGRESS=0 +CONFIG_CFI_FLASH=y +CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_FLASH_CFI_MTD=y +CONFIG_SYS_FLASH_CFI=y +CONFIG_SYS_MAX_FLASH_SECT=256 +CONFIG_SYS_MAX_FLASH_BANKS=2 +CONFIG_SYS_MAX_FLASH_BANKS_DETECT=y +CONFIG_E1000=y +CONFIG_NVME_PCI=y +CONFIG_PCIE_ECAM_GENERIC=y +CONFIG_SCSI=y +CONFIG_DEBUG_UART_PL011=y +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYSRESET=y +CONFIG_SYSRESET_CMD_POWEROFF=y +CONFIG_SYSRESET_PSCI=y +CONFIG_TPM2_MMIO=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_PCI=y +CONFIG_SEMIHOSTING=y +CONFIG_TPM=y diff --git a/doc/board/emulation/qemu-arm.rst b/doc/board/emulation/qemu-arm.rst index 1c91c7f3ac67..70108f98c759 100644 --- a/doc/board/emulation/qemu-arm.rst +++ b/doc/board/emulation/qemu-arm.rst @@ -38,6 +38,11 @@ Set the CROSS_COMPILE environment variable as usual, and run: make qemu_arm64_defconfig make
+- For AArch64 Big Endian:: + + make qemu_arm64be_defconfig + make + Running U-Boot -------------- The minimal QEMU command line to get U-Boot up and running is: @@ -46,7 +51,7 @@ The minimal QEMU command line to get U-Boot up and running is:
qemu-system-arm -machine virt -nographic -bios u-boot.bin
-- For AArch64:: +- For AArch64 (both endian)::
qemu-system-aarch64 -machine virt -nographic -cpu cortex-a57 -bios u-boot.bin

Hi Jiaxun,
On Sun, 19 May 2024 at 15:56, Jiaxun Yang jiaxun.yang@flygoat.com wrote:
Hi all,
Apologies for taking time to review, got a lot in my backlog
This series enabled big endian support for arm64, enabled qemu-arm board for arm64be and slightly adjusted our Kconfig handling on endianness.
In practical I think most Arm SoCs do support little endian only, for those SoCs with big endian support they are usually bi-endian and expected bootloader in little endian. The only big-endian only Arm SoC I know is a network processor from ZTE ZXIC, I doubt if upstream U-Boot will ever support it.
However enabling arm64be can enable us to take more care on big endian targets, given that arm64 is the most feature rich arch in U-Boot, we can run more test on big endian systems.
Boot tested on qemu.
This is not a nak, but I dont see why we should have the extra maintenace burden if people don't use it.
I'd like more feedback from the community on whether this is useful or not
Cheers /Ilias
Please review.
Thanks
Signed-off-by: Jiaxun Yang jiaxun.yang@flygoat.com
Jiaxun Yang (13): tools/relocate-rela: Fix Big Endian elf64 handling arm: Don't select ARM_ASM_UNIFIED on arm64 arm: Fix assembler.h for arm64 arm: Introduce CPU_LE/CPU_BE macros arm: Define endian related bits in system.h armv8: Big Endian enablement for compiler and linker arm: Perform byte swap for read and write in io.h armv8: Allow endianness to be setted at reset entry armv8: spin_table: Perform byte swap for jump address lib/crc32: Don't perform byte swap for arm64 crc32b Kconfig: Unify endian support option config: Use CONFIG_SYS_BIG_ENDIAN in code whenever possible qemu-arm: Big endian enablement for arm64
Makefile | 2 +- arch/Kconfig | 34 ++++++++--- arch/arc/include/asm/arc-bcr.h | 10 +-- arch/arm/Kconfig | 3 +- arch/arm/config.mk | 14 +++++ arch/arm/cpu/armv8/Kconfig | 9 +++ .../arm/cpu/armv8/linux-kernel-image-header-vars.h | 4 +- arch/arm/cpu/armv8/spin_table_v8.S | 2 + arch/arm/cpu/armv8/start.S | 26 ++++++++ arch/arm/cpu/armv8/u-boot-spl.lds | 6 ++ arch/arm/cpu/armv8/u-boot.lds | 4 ++ arch/arm/include/asm/assembler.h | 25 ++++++++ arch/arm/include/asm/io.h | 12 ++-- arch/arm/include/asm/system.h | 3 + arch/arm/lib/elf_aarch64_efi.lds | 7 +++ arch/mips/Kconfig | 20 +++--- arch/mips/mach-ath79/Kconfig | 8 +-- arch/mips/mach-bmips/Kconfig | 20 +++--- arch/mips/mach-jz47xx/Kconfig | 2 +- arch/mips/mach-mscc/Kconfig | 4 +- arch/mips/mach-pic32/Kconfig | 2 +- board/emulation/qemu-arm/Kconfig | 2 + board/emulation/qemu-arm/MAINTAINERS | 1 + configs/qemu_arm64be_defconfig | 71 ++++++++++++++++++++++ doc/board/emulation/qemu-arm.rst | 7 ++- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 2 +- lib/crc32.c | 3 +- scripts/Makefile.build | 2 +- scripts/Makefile.lib | 3 +- tools/relocate-rela.c | 40 +++++++----- 30 files changed, 271 insertions(+), 77 deletions(-)
base-commit: 3be9f399e911cfc437a37ac826441f1d96da1c9b change-id: 20240518-aarch64-be-1ec99cf7f28b
Best regards,
Jiaxun Yang jiaxun.yang@flygoat.com
participants (2)
-
Ilias Apalodimas
-
Jiaxun Yang