Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 26584853 authored by Catalin Marinas's avatar Catalin Marinas
Browse files

Add core support for ARMv6/v7 big-endian



Starting with ARMv6, the CPUs support the BE-8 variant of big-endian
(byte-invariant). This patch adds the core support:

- setting of the BE-8 mode via the CPSR.E register for both kernel and
  user threads
- big-endian page table walking
- REV used to rotate instructions read from memory during fault
  processing as they are still little-endian format
- Kconfig and Makefile support for BE-8. The --be8 option must be passed
  to the final linking stage to convert the instructions to
  little-endian

Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent ee8c9571
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -11,6 +11,9 @@
# Copyright (C) 1995-2001 by Russell King

LDFLAGS_vmlinux	:=-p --no-undefined -X
ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
LDFLAGS_vmlinux	+= --be8
endif
CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
OBJCOPYFLAGS	:=-O binary -R .note -R .note.gnu.build-id -R .comment -S
GZFLAGS		:=-9
+4 −1
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ ifeq ($(CONFIG_PXA_SHARPSL),y)
OBJS		+= head-sharpsl.o
endif

ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
ifeq ($(CONFIG_CPU_ENDIAN_BE32),y)
ifeq ($(CONFIG_CPU_CP15),y)
OBJS		+= big-endian.o
else
@@ -78,6 +78,9 @@ EXTRA_AFLAGS := -Wa,-march=all
# linker symbols.  We only define initrd_phys and params_phys if the
# machine class defined the corresponding makefile variable.
LDFLAGS_vmlinux := --defsym zreladdr=$(ZRELADDR)
ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
LDFLAGS_vmlinux += --be8
endif
ifneq ($(INITRD_PHYS),)
LDFLAGS_vmlinux += --defsym initrd_phys=$(INITRD_PHYS)
endif
+6 −0
Original line number Diff line number Diff line
@@ -438,6 +438,9 @@ __armv4_mmu_cache_on:
		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
		orr	r0, r0, #0x5000		@ I-cache enable, RR cache replacement
		orr	r0, r0, #0x0030
#ifdef CONFIG_CPU_ENDIAN_BE8
		orr	r0, r0, #1 << 25	@ big-endian page tables
#endif
		bl	__common_mmu_cache_on
		mov	r0, #0
		mcr	p15, 0, r0, c8, c7, 0	@ flush I,D TLBs
@@ -455,6 +458,9 @@ __armv7_mmu_cache_on:
		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
		orr	r0, r0, #0x5000		@ I-cache enable, RR cache replacement
		orr	r0, r0, #0x003c		@ write buffer
#ifdef CONFIG_CPU_ENDIAN_BE8
		orr	r0, r0, #1 << 25	@ big-endian page tables
#endif
		orrne	r0, r0, #1		@ MMU enabled
		movne	r1, #-1
		mcrne	p15, 0, r3, c2, c0, 0	@ load page table pointer
+1 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ struct thread_struct {
		regs->ARM_cpsr = USR26_MODE;				\
	if (elf_hwcap & HWCAP_THUMB && pc & 1)				\
		regs->ARM_cpsr |= PSR_T_BIT;				\
	regs->ARM_cpsr |= PSR_ENDSTATE;					\
	regs->ARM_pc = pc & ~1;		/* pc */			\
	regs->ARM_sp = sp;		/* sp */			\
	regs->ARM_r2 = stack[2];	/* r2 (envp) */			\
+10 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@
#define PSR_F_BIT	0x00000040
#define PSR_I_BIT	0x00000080
#define PSR_A_BIT	0x00000100
#define PSR_E_BIT	0x00000200
#define PSR_J_BIT	0x01000000
#define PSR_Q_BIT	0x08000000
#define PSR_V_BIT	0x10000000
@@ -72,6 +73,15 @@
#define PSR_IT_MASK	0x0600fc00	/* If-Then execution state mask */
#define PSR_ENDIAN_MASK	0x00000200	/* Endianness state mask */

/*
 * Default endianness state
 */
#ifdef CONFIG_CPU_ENDIAN_BE8
#define PSR_ENDSTATE	PSR_E_BIT
#else
#define PSR_ENDSTATE	0
#endif

#ifndef __ASSEMBLY__

/*
Loading