Skip to contentSkip to conversation

Initial big-endian support series

PATCH New Ben Dooks 2 participants 18 messages Jun 19, 2013 – Jun 27, 2013

Subsystems (6)
lore
Share & tools
lore

Ben Dooks

author
#0 lore raw

This updates the kernel support for building big-endian kernels and updating the core drivers to deal with the endian swap as needed.

This series does not include the fixups for ATAGs so it will require being booted with fdt. As a note, we do not currently disable the ATAGs options for the system (although we could) as there will be a set of patches following on to deal with booting BE kernel on LE systems.

I have not had time to test it on THUMB2 kernels. There is still fixup work to be done for these which will require more time.

It is on git://git.baserock.org:/delta/linux on branch baserock/311/be/core

author
#1 lore raw

PATCH 1/10 ARM: fix ARCH_IXP4xx usage of ARCH_SUPPORTS_BIG_ENDIAN

The Kconfig for arch/arm/mach-ixp4xx has a local definition of ARCH_SUPPORTS_BIG_ENDIAN which could be used elsewhere. This means that if IXP4xx is selected and this symbol is selected eleswhere then an warning is produced.

Clean the following error up by making the symbol be selected by the main ARCH_IXP4XX definition and have a common definition in arch/arm/mm/Kconfig

warning: (ARCH_xxx) selects ARCH_SUPPORTS_BIG_ENDIAN which has unmet direct dependencies (ARCH_IXP4XX)
warning: (ARCH_xxx) selects ARCH_SUPPORTS_BIG_ENDIAN which has unmet direct dependencies (ARCH_IXP4XX)

---
 arch/arm/Kconfig             |    1 +
 arch/arm/mach-ixp4xx/Kconfig |    4 ----
 arch/arm/mm/Kconfig          |    6 ++++++
 3 files changed, 7 insertions(+), 4 deletions(-)
arch/arm/Kconfig +1 -0
index 49d993c..2ad5df1 100644
@@ -474,6 +474,7 @@ config ARCH_IXP4XX
 	bool "IXP4xx-based"
 	depends on MMU
 	select ARCH_HAS_DMA_SET_COHERENT_MASK
+	select ARCH_SUPPORTS_BIG_ENDIAN
 	select ARCH_REQUIRE_GPIOLIB
 	select CLKSRC_MMIO
 	select CPU_XSCALE
arch/arm/mach-ixp4xx/Kconfig +0 -4
index 73a2d90..72de05f 100644
@@ -1,9 +1,5 @@
 if ARCH_IXP4XX
 
-config ARCH_SUPPORTS_BIG_ENDIAN
-	bool
-	default y
-
 menu "Intel IXP4xx Implementation Options"
 
 comment "IXP4xx Platforms"
arch/arm/mm/Kconfig +6 -0
index 35955b5..b83782e 100644
@@ -895,3 +895,9 @@ config ARCH_HAS_BARRIERS
 	help
 	  This option allows the use of custom mandatory barriers
 	  included via the mach/barriers.h file.
+
+config ARCH_SUPPORTS_BIG_ENDIAN
+	bool
+	help
+	  This option specifies the architecture can support big endian
+	  operation.
Signature · 1 line
1.7.10.4
#2 lore raw

PATCH 1/10 ARM: fix ARCH_IXP4xx usage of ARCH_SUPPORTS_BIG_ENDIAN

Dear Ben Dooks,

Quoted 9 lines · Ben Dooks

The Kconfig for arch/arm/mach-ixp4xx has a local definition of ARCH_SUPPORTS_BIG_ENDIAN which could be used elsewhere. This means that if IXP4xx is selected and this symbol is selected eleswhere then an warning is produced.

Clean the following error up by making the symbol be selected by the main ARCH_IXP4XX definition and have a common definition in arch/arm/mm/Kconfig

Quoted 7 lines

warning: (ARCH_xxx) selects ARCH_SUPPORTS_BIG_ENDIAN which has unmet direct dependencies (ARCH_IXP4XX)
warning: (ARCH_xxx) selects ARCH_SUPPORTS_BIG_ENDIAN which has unmet direct dependencies (ARCH_IXP4XX)

---
 arch/arm/Kconfig             |    1 +
 arch/arm/mach-ixp4xx/Kconfig |    4 ----
 arch/arm/mm/Kconfig          |    6 ++++++
 3 files changed, 7 insertions(+), 4 deletions(-)

Patch lacks SoB.

Best regards,

Thomas

Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
author
#3 lore raw

PATCH 1/10 ARM: fix ARCH_IXP4xx usage of ARCH_SUPPORTS_BIG_ENDIAN

Quoted 20 lines · Thomas Petazzoni

Dear Ben Dooks,

Quoted 9 lines · Ben Dooks

The Kconfig for arch/arm/mach-ixp4xx has a local definition of ARCH_SUPPORTS_BIG_ENDIAN which could be used elsewhere. This means that if IXP4xx is selected and this symbol is selected eleswhere then an warning is produced.

Clean the following error up by making the symbol be selected by the main ARCH_IXP4XX definition and have a common definition in arch/arm/mm/Kconfig

Quoted 7 lines

warning: (ARCH_xxx) selects ARCH_SUPPORTS_BIG_ENDIAN which has unmet direct dependencies (ARCH_IXP4XX)
warning: (ARCH_xxx) selects ARCH_SUPPORTS_BIG_ENDIAN which has unmet direct dependencies (ARCH_IXP4XX)

---
  arch/arm/Kconfig             |    1 +
  arch/arm/mach-ixp4xx/Kconfig |    4 ----
  arch/arm/mm/Kconfig          |    6 ++++++
  3 files changed, 7 insertions(+), 4 deletions(-)
Quoted 1 line

Patch lacks SoB.

Thanks, must have missed it.

Signature · 2 lines
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius
author
#4 lore raw

PATCH 2/10 ARM: fixup_pv_table bug when CPU_ENDIAN_BE8

In reply to Ben Dooks

The fixup_pv_table assumes that the instructions are in the same endian configuration as the data, but when the CPU is running in BE8 the instructions stay in little-endian format.

Make sure if CONFIG_CPU_ENDIAN_BE8 is set that we do all the alterations to the instructions taking in to account the LDR/STR will be swapping the data endian-ness.

Since the code is only modifying a byte, we avoid dual-swapping the data, and just change the bits we clear and ORR in.

Note, not tested against an actual bug, it looked wrong.

---
 arch/arm/kernel/head.S |    6 ++++++
 1 file changed, 6 insertions(+)
arch/arm/kernel/head.S +6 -0
index 8bac553..56ddd47 100644
@@ -594,8 +594,14 @@ __fixup_a_pv_table:
 #else
 	b	2f
 1:	ldr	ip, [r7, r3]
+#ifdef CONFIG_CPU_ENDIAN_BE8
+	@ in BE8, we load data in BE, but instructions still in LE
+	bic	ip, ip, #0xff000000
+	orr	ip, ip, r6, lsl#24
+#else
 	bic	ip, ip, #0x000000ff
 	orr	ip, ip, r6	@ mask in offset bits 31-24
+#endif
 	str	ip, [r7, r3]
 2:	cmp	r4, r5
 	ldrcc	r7, [r4], #4	@ use branch for delay slot
Signature · 1 line
1.7.10.4
#5 lore raw

PATCH 2/10 ARM: fixup_pv_table bug when CPU_ENDIAN_BE8

Dear Ben Dooks,

arch/arm/kernel/head.S __fixup_a_pv_table: · line 607

Quoted 11 lines · Ben Dooks
arch/arm/kernel/head.S +6 -0
+#ifdef CONFIG_CPU_ENDIAN_BE8
+	@ in BE8, we load data in BE, but instructions still in LE
+	bic	ip, ip, #0xff000000
+	orr	ip, ip, r6, lsl#24
+#else
 	bic	ip, ip, #0x000000ff
 	orr	ip, ip, r6	@ mask in offset bits 31-24
+#endif
 	str	ip, [r7, r3]
 2:	cmp	r4, r5
 	ldrcc	r7, [r4], #4	@ use branch for delay slot

As was suggested in
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/150782.html,
you could put this patch later in the series and use the ARM_BE8() macro you introduce in the next patch.

Also in
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/150784.html,
the same reviewer suggested to name the macro BE8() to make it fit like ARM() and THUMB() in the margin left by the indentation of assembly code. And also to add LE() to make the above code look like:

BE8( bic ip, ip, #0xff000000)
BE8( orr ip, ip, r6, lsl#24)
LE( bic ip, ip, #0x000000ff)
LE( orr ip, ip, r6)

Thomas

Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
author
#6 lore raw

PATCH 2/10 ARM: fixup_pv_table bug when CPU_ENDIAN_BE8

Quoted 27 lines · Thomas Petazzoni

Dear Ben Dooks,

arch/arm/kernel/head.S __fixup_a_pv_table: · line 607

Quoted 11 lines · Ben Dooks
arch/arm/kernel/head.S +6 -0
+#ifdef CONFIG_CPU_ENDIAN_BE8
+	@ in BE8, we load data in BE, but instructions still in LE
+	bic	ip, ip, #0xff000000
+	orr	ip, ip, r6, lsl#24
+#else
  	bic	ip, ip, #0x000000ff
  	orr	ip, ip, r6	@ mask in offset bits 31-24
+#endif
  	str	ip, [r7, r3]
  2:	cmp	r4, r5
  	ldrcc	r7, [r4], #4	@ use branch for delay slot

As was suggested in
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/150782.html,
you could put this patch later in the series and use the ARM_BE8() macro you introduce in the next patch.

Also in
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/150784.html,
the same reviewer suggested to name the macro BE8() to make it fit like ARM() and THUMB() in the margin left by the indentation of assembly code. And also to add LE() to make the above code look like:

Quoted 4 lines

BE8( bic ip, ip, #0xff000000)
BE8( orr ip, ip, r6, lsl#24)
LE( bic ip, ip, #0x000000ff)
LE( orr ip, ip, r6)

Actually, that doesn't work as LE is not the inverse of BE8 as it could also be when the kernel is being compiled in BE32.

Signature · 2 lines
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius
#7 lore raw

PATCH 2/10 ARM: fixup_pv_table bug when CPU_ENDIAN_BE8

Dear Ben Dooks,

Quoted 6 lines · Ben Dooks
Quoted 6 lines

Also in
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/150784.html,
the same reviewer suggested to name the macro BE8() to make it fit like ARM() and THUMB() in the margin left by the indentation of assembly code. And also to add LE() to make the above code look like:

Quoted 7 lines
Quoted 4 lines

BE8( bic ip, ip, #0xff000000)
BE8( orr ip, ip, r6, lsl#24)
LE( bic ip, ip, #0x000000ff)
LE( orr ip, ip, r6)

Actually, that doesn't work as LE is not the inverse of BE8 as it could also be when the kernel is being compiled in BE32.

Aah, correct. In BE32, data and instructions have the same endianness.

Thanks,

Thomas

Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
author
#8 lore raw

PATCH 3/10 ARM: asm: Add ARM_BE8() assembly helper

In reply to Ben Dooks

Add ARM_BE8() helper to wrap any code conditional on being compile when CONFIG_ARM_ENDIAN_BE8 is selected and convert existing places where this is to use it.

---
 arch/arm/boot/compressed/head.S  |    8 ++------
 arch/arm/include/asm/assembler.h |    7 +++++++
 arch/arm/kernel/entry-armv.S     |    5 ++---
 arch/arm/kernel/entry-common.S   |    4 +---
 arch/arm/mm/abort-ev6.S          |    5 ++---
 arch/arm/mm/proc-v6.S            |    4 +---
 arch/arm/mm/proc-v7.S            |    4 +---
 7 files changed, 16 insertions(+), 21 deletions(-)
arch/arm/boot/compressed/head.S +2 -6
index 032a8d9..4eb8364 100644
@@ -679,9 +679,7 @@ __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
+ ARM_BE8(	orr	r0, r0, #1 << 25 )	@ big-endian page tables
 		bl	__common_mmu_cache_on
 		mov	r0, #0
 		mcr	p15, 0, r0, c8, c7, 0	@ flush I,D TLBs
@@ -708,9 +706,7 @@ __armv7_mmu_cache_on:
 		orr	r0, r0, #1 << 22	@ U (v6 unaligned access model)
 						@ (needed for ARM1176)
 #ifdef CONFIG_MMU
-#ifdef CONFIG_CPU_ENDIAN_BE8
-		orr	r0, r0, #1 << 25	@ big-endian page tables
-#endif
+ ARM_BE8(	orr	r0, r0, #1 << 25 )	@ big-endian page tables
 		mrcne   p15, 0, r6, c2, c0, 2   @ read ttb control reg
 		orrne	r0, r0, #1		@ MMU enabled
 		movne	r1, #0xfffffffd		@ domain 0 = client
arch/arm/include/asm/assembler.h +7 -0
index 05ee9ee..e780afb 100644
@@ -53,6 +53,13 @@
 #define put_byte_3      lsl #0
 #endif
 
+/* Select code for any configuration running in BE8 mode */
+#ifdef CONFIG_CPU_ENDIAN_BE8
+#define ARM_BE8(code...) code
+#else
+#define ARM_BE8(code...)
+#endif
+
 /*
  * Data preload for architectures that support it
  */
arch/arm/kernel/entry-armv.S +2 -3
index 582b405..09130e2 100644
@@ -415,9 +415,8 @@ __und_usr:
 	bne	__und_usr_thumb
 	sub	r4, r2, #4			@ ARM instr@LR - 4
 1:	ldrt	r0, [r4]
-#ifdef CONFIG_CPU_ENDIAN_BE8
-	rev	r0, r0				@ little endian instruction
-#endif
+ ARM_BE8(rev	r0, r0)				@ little endian instruction
+
 	@ r0 = 32-bit ARM instruction which caused the exception
 	@ r2 = PC value for the following instruction (:= regs->ARM_pc)
 	@ r4 = PC value for the faulting instruction
arch/arm/kernel/entry-common.S +1 -3
index bc5bc0a..8c79344 100644
@@ -379,9 +379,7 @@ ENTRY(vector_swi)
 #else
 	ldr	r10, [lr, #-4]			@ get SWI instruction
 #endif
-#ifdef CONFIG_CPU_ENDIAN_BE8
-	rev	r10, r10			@ little endian instruction
-#endif
+ ARM_BE8(rev	r10, r10)			@ little endian instruction
 
 #elif defined(CONFIG_AEABI)
 
arch/arm/mm/abort-ev6.S +2 -3
index 8074199..3815a82 100644
@@ -38,9 +38,8 @@ ENTRY(v6_early_abort)
 	bne	do_DataAbort
 	bic	r1, r1, #1 << 11		@ clear bit 11 of FSR
 	ldr	r3, [r4]			@ read aborted ARM instruction
-#ifdef CONFIG_CPU_ENDIAN_BE8
-	rev	r3, r3
-#endif
+ ARM_BE8(rev	r3, r3)
+
 	do_ldrd_abort tmp=ip, insn=r3
 	tst	r3, #1 << 20			@ L = 0 -> write
 	orreq	r1, r1, #1 << 11		@ yes.
arch/arm/mm/proc-v6.S +1 -3
index 919405e..f2e43e8 100644
@@ -218,9 +218,7 @@ __v6_setup:
 #endif /* CONFIG_MMU */
 	adr	r5, v6_crval
 	ldmia	r5, {r5, r6}
-#ifdef CONFIG_CPU_ENDIAN_BE8
-	orr	r6, r6, #1 << 25		@ big-endian page tables
-#endif
+ ARM_BE8(orr	r6, r6, #1 << 25)		@ big-endian page tables
 	mrc	p15, 0, r0, c1, c0, 0		@ read control register
 	bic	r0, r0, r5			@ clear bits them
 	orr	r0, r0, r6			@ set them
arch/arm/mm/proc-v7.S +1 -3
index 2c73a73..8b0e815 100644
@@ -328,9 +328,7 @@ __v7_setup:
 #endif
 	adr	r5, v7_crval
 	ldmia	r5, {r5, r6}
-#ifdef CONFIG_CPU_ENDIAN_BE8
-	orr	r6, r6, #1 << 25		@ big-endian page tables
-#endif
+ ARM_BE8(orr	r6, r6, #1 << 25)		@ big-endian page tables
 #ifdef CONFIG_SWP_EMULATE
 	orr     r5, r5, #(1 << 10)              @ set SW bit in "clear"
 	bic     r6, r6, #(1 << 10)              @ clear it in "mmuset"
Signature · 1 line
1.7.10.4
author
#9 lore raw

PATCH 4/10 ARM: set BE8 if LE in head code

In reply to Ben Dooks

If we are booting in LE and compiled for BE8, then add code to set the state to bE8. Since the instruction stream is always LE, we do not need to do anything special to the instruction.

Also ensure that the secondary processors are started in the same mode.

Note, we do add about 20 bytes to the kernel image, but it seems easier to do this than adding another configuration to change.

---
 arch/arm/boot/compressed/head.S |    1 +
 arch/arm/kernel/head.S          |    4 ++++
 arch/arm/kernel/sleep.S         |    1 +
 3 files changed, 6 insertions(+)
arch/arm/boot/compressed/head.S +1 -0
index 4eb8364..4d83bfd 100644
@@ -135,6 +135,7 @@ start:
 		.word	_edata			@ zImage end address
  THUMB(		.thumb			)
 1:
+ ARM_BE8(	setend	be )			@ go BE8 if LE, no-op if BE8
 		mrs	r9, cpsr
 #ifdef CONFIG_ARM_VIRT_EXT
 		bl	__hyp_stub_install	@ get into SVC mode, reversibly
arch/arm/kernel/head.S +4 -0
index 56ddd47..da09dc0 100644
@@ -77,6 +77,7 @@
 
 	__HEAD
 ENTRY(stext)
+ ARM_BE8(setend	be )			@ ensure we are in BE8 mode
 
  THUMB(	adr	r9, BSYM(1f)	)	@ Kernel is always entered in ARM.
  THUMB(	bx	r9		)	@ If this is a Thumb-2 kernel,
@@ -351,6 +352,9 @@ ENTRY(secondary_startup)
 	 * the processor type - there is no need to check the machine type
 	 * as it has already been validated by the primary processor.
 	 */
+
+ ARM_BE8(setend	be)				@ if system starts LE, go BE8
+
 #ifdef CONFIG_ARM_VIRT_EXT
 	bl	__hyp_stub_install_secondary
 #endif
arch/arm/kernel/sleep.S +1 -0
index 987dcf3..954c28a 100644
@@ -81,6 +81,7 @@ ENDPROC(cpu_resume_after_mmu)
 	.data
 	.align
 ENTRY(cpu_resume)
+ARM_BE8(setend be)			@ ensure we are in BE mode
 #ifdef CONFIG_SMP
 	adr	r0, sleep_save_sp
 	ALT_SMP(mrc p15, 0, r1, c0, c0, 5)
Signature · 1 line
1.7.10.4
author
#10 lore raw

PATCH 5/10 ARM: pl01x debug code endian fix

In reply to Ben Dooks

The PL01X debug code needs to take into account which endian mode the processor is running in. If it is big-endian, ensure the data is swapped appropriately.

Note, we could do this slightly more efficiently if we have an macro to do the necessary swap for the bits used by test.

---
 arch/arm/include/asm/hardware/debug-pl01x.S |    2 ++
 1 file changed, 2 insertions(+)
arch/arm/include/asm/hardware/debug-pl01x.S +2 -0
index f9fd083..6489d1f 100644
@@ -18,12 +18,14 @@
 
 		.macro	waituart,rd,rx
 1001:		ldr	\rd, [\rx, #UART01x_FR]
+ ARM_BE8(	rev	\rd, \rd )
 		tst	\rd, #UART01x_FR_TXFF
 		bne	1001b
 		.endm
 
 		.macro	busyuart,rd,rx
 1001:		ldr	\rd, [\rx, #UART01x_FR]
+ ARM_BE8(	rev	\rd, \rd )
 		tst	\rd, #UART01x_FR_BUSY
 		bne	1001b
 		.endm
Signature · 1 line
1.7.10.4
author
#11 lore raw

PATCH 6/10 ARM: twd: data endian fix

In reply to Ben Dooks

Ensure the twd driver uses the correct calls to access the hardware to ensure that we do not end up with data in the wrong endian format.

---
 arch/arm/kernel/smp_twd.c |   24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)
arch/arm/kernel/smp_twd.c +12 -12
index 90525d9..804d3f8 100644
@@ -45,7 +45,7 @@ static void twd_set_mode(enum clock_event_mode mode,
 	case CLOCK_EVT_MODE_PERIODIC:
 		ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE
 			| TWD_TIMER_CONTROL_PERIODIC;
-		__raw_writel(DIV_ROUND_CLOSEST(twd_timer_rate, HZ),
+		writel_relaxed(DIV_ROUND_CLOSEST(twd_timer_rate, HZ),
 			twd_base + TWD_TIMER_LOAD);
 		break;
 	case CLOCK_EVT_MODE_ONESHOT:
@@ -58,18 +58,18 @@ static void twd_set_mode(enum clock_event_mode mode,
 		ctrl = 0;
 	}
 
-	__raw_writel(ctrl, twd_base + TWD_TIMER_CONTROL);
+	writel_relaxed(ctrl, twd_base + TWD_TIMER_CONTROL);
 }
 
 static int twd_set_next_event(unsigned long evt,
 			struct clock_event_device *unused)
 {
-	unsigned long ctrl = __raw_readl(twd_base + TWD_TIMER_CONTROL);
+	unsigned long ctrl = readl_relaxed(twd_base + TWD_TIMER_CONTROL);
 
 	ctrl |= TWD_TIMER_CONTROL_ENABLE;
 
-	__raw_writel(evt, twd_base + TWD_TIMER_COUNTER);
-	__raw_writel(ctrl, twd_base + TWD_TIMER_CONTROL);
+	writel_relaxed(evt, twd_base + TWD_TIMER_COUNTER);
+	writel_relaxed(ctrl, twd_base + TWD_TIMER_CONTROL);
 
 	return 0;
 }
@@ -82,8 +82,8 @@ static int twd_set_next_event(unsigned long evt,
  */
 static int twd_timer_ack(void)
 {
-	if (__raw_readl(twd_base + TWD_TIMER_INTSTAT)) {
-		__raw_writel(1, twd_base + TWD_TIMER_INTSTAT);
+	if (readl_relaxed(twd_base + TWD_TIMER_INTSTAT)) {
+		writel_relaxed(1, twd_base + TWD_TIMER_INTSTAT);
 		return 1;
 	}
 
@@ -209,15 +209,15 @@ static void __cpuinit twd_calibrate_rate(void)
 		waitjiffies += 5;
 
 				 /* enable, no interrupt or reload */
-		__raw_writel(0x1, twd_base + TWD_TIMER_CONTROL);
+		writel_relaxed(0x1, twd_base + TWD_TIMER_CONTROL);
 
 				 /* maximum value */
-		__raw_writel(0xFFFFFFFFU, twd_base + TWD_TIMER_COUNTER);
+		writel_relaxed(0xFFFFFFFFU, twd_base + TWD_TIMER_COUNTER);
 
 		while (get_jiffies_64() < waitjiffies)
 			udelay(10);
 
-		count = __raw_readl(twd_base + TWD_TIMER_COUNTER);
+		count = readl_relaxed(twd_base + TWD_TIMER_COUNTER);
 
 		twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
 
@@ -275,7 +275,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
 	 * bother with the below.
 	 */
 	if (per_cpu(percpu_setup_called, cpu)) {
-		__raw_writel(0, twd_base + TWD_TIMER_CONTROL);
+		writel_relaxed(0, twd_base + TWD_TIMER_CONTROL);
 		clockevents_register_device(*__this_cpu_ptr(twd_evt));
 		enable_percpu_irq(clk->irq, 0);
 		return 0;
@@ -288,7 +288,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
 	 * The following is done once per CPU the first time .setup() is
 	 * called.
 	 */
-	__raw_writel(0, twd_base + TWD_TIMER_CONTROL);
+	writel_relaxed(0, twd_base + TWD_TIMER_CONTROL);
 
 	clk->name = "local_timer";
 	clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
Signature · 1 line
1.7.10.4
author
#12 lore raw

PATCH 7/10 ARM: smp_scu: data endian fixes

In reply to Ben Dooks

The smp_scu driver needs to use the relaxed readl/write accessors to avoid any issues with the endian mode the processor core is in.

---
 arch/arm/kernel/smp_scu.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
arch/arm/kernel/smp_scu.c +8 -8
index 5bc1a63..0fcd0ce 100644
@@ -28,7 +28,7 @@
  */
 unsigned int __init scu_get_core_count(void __iomem *scu_base)
 {
-	unsigned int ncores = __raw_readl(scu_base + SCU_CONFIG);
+	unsigned int ncores = readl_relaxed(scu_base + SCU_CONFIG);
 	return (ncores & 0x03) + 1;
 }
 
@@ -41,20 +41,20 @@ void scu_enable(void __iomem *scu_base)
 
 #ifdef CONFIG_ARM_ERRATA_764369
 	/* Cortex-A9 only */
-	if ((read_cpuid_id() & 0xff0ffff0) == 0x410fc090) {
-		scu_ctrl = __raw_readl(scu_base + 0x30);
+	if ((read_cpuid(CPUID_ID) & 0xff0ffff0) == 0x410fc090) {
+		scu_ctrl = readl_relaxed(scu_base + 0x30);
 		if (!(scu_ctrl & 1))
-			__raw_writel(scu_ctrl | 0x1, scu_base + 0x30);
+			writel_relaxed(scu_ctrl | 0x1, scu_base + 0x30);
 	}
 #endif
 
-	scu_ctrl = __raw_readl(scu_base + SCU_CTRL);
+	scu_ctrl = readl_relaxed(scu_base + SCU_CTRL);
 	/* already enabled? */
 	if (scu_ctrl & 1)
 		return;
 
 	scu_ctrl |= 1;
-	__raw_writel(scu_ctrl, scu_base + SCU_CTRL);
+	writel_relaxed(scu_ctrl, scu_base + SCU_CTRL);
 
 	/*
 	 * Ensure that the data accessed by CPU0 before the SCU was
@@ -80,9 +80,9 @@ int scu_power_mode(void __iomem *scu_base, unsigned int mode)
 	if (mode > 3 || mode == 1 || cpu > 3)
 		return -EINVAL;
 
-	val = __raw_readb(scu_base + SCU_CPU_STATUS + cpu) & ~0x03;
+	val = readb_relaxed(scu_base + SCU_CPU_STATUS + cpu) & ~0x03;
 	val |= mode;
-	__raw_writeb(val, scu_base + SCU_CPU_STATUS + cpu);
+	writeb_relaxed(val, scu_base + SCU_CPU_STATUS + cpu);
 
 	return 0;
 }
Signature · 1 line
1.7.10.4
author
#13 lore raw

PATCH 8/10 highbank: enable big-endian

In reply to Ben Dooks

Apart from a xgmac driver issue, the highbank seems to work correctly in big-endian mode. Allow the selection of big-endian in the system.

---
 arch/arm/mach-highbank/Kconfig |    1 +
 1 file changed, 1 insertion(+)
arch/arm/mach-highbank/Kconfig +1 -0
index cd9fcb1..4f57554 100644
@@ -18,3 +18,4 @@ config ARCH_HIGHBANK
 	select PL320_MBOX
 	select SPARSE_IRQ
 	select USE_OF
+	select ARCH_SUPPORTS_BIG_ENDIAN
Signature · 1 line
1.7.10.4
author
#14 lore raw

PATCH 9/10 mvebu: support running big-endian

In reply to Ben Dooks

Add indication we can run these cores in BE mode, and ensure that the secondary CPU is set to big-endian mode in the initialisation code as the initial code runs little-endian.

---
 arch/arm/mach-mvebu/Kconfig        |    1 +
 arch/arm/mach-mvebu/coherency_ll.S |    3 +++
 arch/arm/mach-mvebu/headsmp.S      |    4 ++++
 3 files changed, 8 insertions(+)
arch/arm/mach-mvebu/Kconfig +1 -0
index 80a8bca..317cdb8 100644
@@ -1,5 +1,6 @@
 config ARCH_MVEBU
 	bool "Marvell SOCs with Device Tree support" if ARCH_MULTI_V7
+	select ARCH_SUPPORTS_BIG_ENDIAN
 	select CLKSRC_MMIO
 	select COMMON_CLK
 	select GENERIC_CLOCKEVENTS
arch/arm/mach-mvebu/coherency_ll.S +3 -0
index 5476669..ee7598f 100644
@@ -20,6 +20,8 @@
 #define ARMADA_XP_CFB_CTL_REG_OFFSET 0x0
 #define ARMADA_XP_CFB_CFG_REG_OFFSET 0x4
 
+#include <asm/assembler.h>
+
 	.text
 /*
  * r0: Coherency fabric base register address
@@ -29,6 +31,7 @@ ENTRY(ll_set_cpu_coherent)
 	/* Create bit by cpu index */
 	mov	r3, #(1 << 24)
 	lsl	r1, r3, r1
+ARM_BE8(rev	r1, r1)
 
 	/* Add CPU to SMP group - Atomic */
 	add	r3, r0, #ARMADA_XP_CFB_CTL_REG_OFFSET
arch/arm/mach-mvebu/headsmp.S +4 -0
index a06e0ed..a4f995d 100644
@@ -21,6 +21,8 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
+#include <asm/assembler.h>
+
 /*
  * At this stage the secondary CPUs don't have acces yet to the MMU, so
  * we have to provide physical addresses
@@ -36,6 +38,8 @@
  */
 ENTRY(armada_xp_secondary_startup)
 
+ ARM_BE8(setend	be )			@ go BE8 if booted LE
+
 	/* Read CPU id */
 	mrc     p15, 0, r1, c0, c0, 5
 	and     r1, r1, #0xF
Signature · 1 line
1.7.10.4
author
#15 lore raw

PATCH 10/10 vexpress: add big endian support

In reply to Ben Dooks

Add support for the versatile express systems to boot big-endian.

---
 arch/arm/mach-vexpress/Kconfig    |    1 +
 arch/arm/plat-versatile/headsmp.S |    2 ++
 2 files changed, 3 insertions(+)
arch/arm/mach-vexpress/Kconfig +1 -0
index 5907e10..fa69d4e 100644
@@ -1,6 +1,7 @@
 config ARCH_VEXPRESS
 	bool "ARM Ltd. Versatile Express family" if ARCH_MULTI_V7
 	select ARCH_REQUIRE_GPIOLIB
+	select ARCH_SUPPORTS_BIG_ENDIAN
 	select ARM_AMBA
 	select ARM_GIC
 	select ARM_TIMER_SP804
arch/arm/plat-versatile/headsmp.S +2 -0
index b178d44..4c5c8ca 100644
@@ -10,6 +10,7 @@
  */
 #include <linux/linkage.h>
 #include <linux/init.h>
+#include <asm/assembler.h>
 
 	__INIT
 
@@ -19,6 +20,7 @@
  * until we're ready for them to initialise.
  */
 ENTRY(versatile_secondary_startup)
+ ARM_BE8(setend	be)
 	mrc	p15, 0, r0, c0, c0, 5
 	bic	r0, #0xff000000
 	adr	r4, 1f
Signature · 1 line
1.7.10.4
#16 lore raw
In reply to Ben Dooks

Dear Ben Dooks,

Quoted 9 lines · Ben Dooks

This updates the kernel support for building big-endian kernels and updating the core drivers to deal with the endian swap as needed.

This series does not include the fixups for ATAGs so it will require being booted with fdt. As a note, we do not currently disable the ATAGs options for the system (although we could) as there will be a set of patches following on to deal with booting BE kernel on LE systems.

I have tested both series on an Armada XP based platform and I confirm that I'm able to boot successfully with a BE8 kernel and into a BE8 userspace. Nice!

Would it be possible to get this merged?

Quoted 2 lines

I have not had time to test it on THUMB2 kernels. There is still fixup work to be done for these which will require more time.

I might have some time in the near future to look at that, if you don't do it in the mean time, of course.

Thanks!

Thomas

Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
author
#17 lore raw
In reply to Ben Dooks
Quoted 10 lines · Ben Dooks

This updates the kernel support for building big-endian kernels and updating the core drivers to deal with the endian swap as needed.

This series does not include the fixups for ATAGs so it will require being booted with fdt. As a note, we do not currently disable the ATAGs options for the system (although we could) as there will be a set of patches following on to deal with booting BE kernel on LE systems.

Quoted 4 lines

I have not had time to test it on THUMB2 kernels. There is still fixup work to be done for these which will require more time.

It is on git://git.baserock.org:/delta/linux on branch baserock/311/be/core

Russell, any objections to taking this patch series?

Signature · 2 lines
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius