All of lore.kernel.org
 help / color / mirror / Atom feed
* [repost] ARM big-endian support
@ 2013-07-24 10:27 Ben Dooks
  2013-07-24 10:27 ` [PATCH 01/14] ARM: fix ARCH_IXP4xx usage of ARCH_SUPPORTS_BIG_ENDIAN Ben Dooks
                   ` (14 more replies)
  0 siblings, 15 replies; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

A repost (as requested) of the current big-endian core work for review.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 01/14] ARM: fix ARCH_IXP4xx usage of ARCH_SUPPORTS_BIG_ENDIAN
  2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
@ 2013-07-24 10:27 ` Ben Dooks
  2013-07-24 10:27 ` [PATCH 02/14] ARM: asm: Add ARM_BE8() assembly helper Ben Dooks
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

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)

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 arch/arm/Kconfig             |    1 +
 arch/arm/mach-ixp4xx/Kconfig |    4 ----
 arch/arm/mm/Kconfig          |    6 ++++++
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 136f263..0e60b0e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -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
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 73a2d90..72de05f 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -1,9 +1,5 @@
 if ARCH_IXP4XX
 
-config ARCH_SUPPORTS_BIG_ENDIAN
-	bool
-	default y
-
 menu "Intel IXP4xx Implementation Options"
 
 comment "IXP4xx Platforms"
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 35955b5..b83782e 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -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.
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 02/14] ARM: asm: Add ARM_BE8() assembly helper
  2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
  2013-07-24 10:27 ` [PATCH 01/14] ARM: fix ARCH_IXP4xx usage of ARCH_SUPPORTS_BIG_ENDIAN Ben Dooks
@ 2013-07-24 10:27 ` Ben Dooks
  2013-07-24 14:28   ` Will Deacon
  2013-07-24 10:27 ` [PATCH 03/14] ARM: fixup_pv_table bug when CPU_ENDIAN_BE8 Ben Dooks
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Acked-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 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(-)

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 032a8d9..4eb8364 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -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
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 05ee9ee..e780afb 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -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
  */
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 582b405..09130e2 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -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
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index bc5bc0a..8c79344 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -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)
 
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S
index 8074199..3815a82 100644
--- a/arch/arm/mm/abort-ev6.S
+++ b/arch/arm/mm/abort-ev6.S
@@ -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.
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 919405e..f2e43e8 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -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
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index e35fec3..8338ba4 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -351,9 +351,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"
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 03/14] ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
  2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
  2013-07-24 10:27 ` [PATCH 01/14] ARM: fix ARCH_IXP4xx usage of ARCH_SUPPORTS_BIG_ENDIAN Ben Dooks
  2013-07-24 10:27 ` [PATCH 02/14] ARM: asm: Add ARM_BE8() assembly helper Ben Dooks
@ 2013-07-24 10:27 ` Ben Dooks
  2013-07-24 14:33   ` Will Deacon
  2013-07-24 10:27 ` [PATCH 04/14] ARM: set BE8 if LE in head code Ben Dooks
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

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 (in the
case where the code is not thumb2).

For thumb2, we add the necessary rev16 instructions to ensure that
the instructions are processed in the correct format, as it was
easier than re-writing the code to contain a mask and shift.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 arch/arm/kernel/head.S |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 8bac553..e40c0b3b 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -584,8 +584,10 @@ __fixup_a_pv_table:
 	b	2f
 1:	add     r7, r3
 	ldrh	ip, [r7, #2]
+ARM_BE8(rev16	ip, ip)
 	and	ip, 0x8f00
 	orr	ip, r6	@ mask in offset bits 31-24
+ARM_BE8(rev16	ip, ip)
 	strh	ip, [r7, #2]
 2:	cmp	r4, r5
 	ldrcc	r7, [r4], #4	@ use branch for delay slot
@@ -594,8 +596,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
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 04/14] ARM: set BE8 if LE in head code
  2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
                   ` (2 preceding siblings ...)
  2013-07-24 10:27 ` [PATCH 03/14] ARM: fixup_pv_table bug when CPU_ENDIAN_BE8 Ben Dooks
@ 2013-07-24 10:27 ` Ben Dooks
  2013-07-24 14:41   ` Will Deacon
  2013-07-24 10:27 ` [PATCH 05/14] ARM: pl01x debug code endian fix Ben Dooks
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 arch/arm/boot/compressed/head.S |    1 +
 arch/arm/kernel/head.S          |    4 ++++
 arch/arm/kernel/sleep.S         |    1 +
 3 files changed, 6 insertions(+)

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 4eb8364..4d83bfd 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -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
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index e40c0b3b..706c441 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -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
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index 987dcf3..954c28a 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -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)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 05/14] ARM: pl01x debug code endian fix
  2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
                   ` (3 preceding siblings ...)
  2013-07-24 10:27 ` [PATCH 04/14] ARM: set BE8 if LE in head code Ben Dooks
@ 2013-07-24 10:27 ` Ben Dooks
  2013-07-24 14:44   ` Will Deacon
  2013-07-24 10:27 ` [PATCH 06/14] ARM: twd: data " Ben Dooks
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 arch/arm/include/asm/hardware/debug-pl01x.S |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/include/asm/hardware/debug-pl01x.S b/arch/arm/include/asm/hardware/debug-pl01x.S
index f9fd083..6489d1f 100644
--- a/arch/arm/include/asm/hardware/debug-pl01x.S
+++ b/arch/arm/include/asm/hardware/debug-pl01x.S
@@ -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
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 06/14] ARM: twd: data endian fix
  2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
                   ` (4 preceding siblings ...)
  2013-07-24 10:27 ` [PATCH 05/14] ARM: pl01x debug code endian fix Ben Dooks
@ 2013-07-24 10:27 ` Ben Dooks
  2013-07-24 14:49   ` Will Deacon
  2013-07-24 10:27 ` [PATCH 07/14] ARM: smp_scu: data endian fixes Ben Dooks
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 arch/arm/kernel/smp_twd.c |   24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 90525d9..804d3f8 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -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 |
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 07/14] ARM: smp_scu: data endian fixes
  2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
                   ` (5 preceding siblings ...)
  2013-07-24 10:27 ` [PATCH 06/14] ARM: twd: data " Ben Dooks
@ 2013-07-24 10:27 ` Ben Dooks
  2013-07-24 15:05   ` Will Deacon
  2013-07-24 10:27 ` [PATCH 08/14] highbank: enable big-endian Ben Dooks
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 arch/arm/kernel/smp_scu.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
index 5bc1a63..1aafa0d 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -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;
 }
 
@@ -42,19 +42,19 @@ 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);
+		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;
 }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 08/14] highbank: enable big-endian
  2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
                   ` (6 preceding siblings ...)
  2013-07-24 10:27 ` [PATCH 07/14] ARM: smp_scu: data endian fixes Ben Dooks
@ 2013-07-24 10:27 ` Ben Dooks
  2013-07-24 10:27 ` [PATCH 09/14] mvebu: support running big-endian Ben Dooks
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 arch/arm/mach-highbank/Kconfig |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-highbank/Kconfig b/arch/arm/mach-highbank/Kconfig
index cd9fcb1..4f57554 100644
--- a/arch/arm/mach-highbank/Kconfig
+++ b/arch/arm/mach-highbank/Kconfig
@@ -18,3 +18,4 @@ config ARCH_HIGHBANK
 	select PL320_MBOX
 	select SPARSE_IRQ
 	select USE_OF
+	select ARCH_SUPPORTS_BIG_ENDIAN
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 09/14] mvebu: support running big-endian
  2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
                   ` (7 preceding siblings ...)
  2013-07-24 10:27 ` [PATCH 08/14] highbank: enable big-endian Ben Dooks
@ 2013-07-24 10:27 ` Ben Dooks
  2013-07-24 10:27 ` [PATCH 10/14] vexpress: add big endian support Ben Dooks
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

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.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 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(+)

diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 80a8bca..317cdb8 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -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
diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S
index 5476669..ee7598f 100644
--- a/arch/arm/mach-mvebu/coherency_ll.S
+++ b/arch/arm/mach-mvebu/coherency_ll.S
@@ -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
diff --git a/arch/arm/mach-mvebu/headsmp.S b/arch/arm/mach-mvebu/headsmp.S
index a06e0ed..a4f995d 100644
--- a/arch/arm/mach-mvebu/headsmp.S
+++ b/arch/arm/mach-mvebu/headsmp.S
@@ -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
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 10/14] vexpress: add big endian support
  2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
                   ` (8 preceding siblings ...)
  2013-07-24 10:27 ` [PATCH 09/14] mvebu: support running big-endian Ben Dooks
@ 2013-07-24 10:27 ` Ben Dooks
  2013-07-24 10:27 ` [PATCH 11/14] ARM: alignment: correctly decode instructions in BE8 mode Ben Dooks
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

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

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 arch/arm/mach-vexpress/Kconfig    |    1 +
 arch/arm/plat-versatile/headsmp.S |    2 ++
 2 files changed, 3 insertions(+)

diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index 5907e10..fa69d4e 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -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
diff --git a/arch/arm/plat-versatile/headsmp.S b/arch/arm/plat-versatile/headsmp.S
index b178d44..4c5c8ca 100644
--- a/arch/arm/plat-versatile/headsmp.S
+++ b/arch/arm/plat-versatile/headsmp.S
@@ -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
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 11/14] ARM: alignment: correctly decode instructions in BE8 mode.
  2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
                   ` (9 preceding siblings ...)
  2013-07-24 10:27 ` [PATCH 10/14] vexpress: add big endian support Ben Dooks
@ 2013-07-24 10:27 ` Ben Dooks
  2013-07-24 15:28   ` Will Deacon
  2013-07-25  9:44   ` Will Deacon
  2013-07-24 10:28 ` [PATCH 12/14] ARM: traps: use <asm/opcodes.h> to get correct instruction order Ben Dooks
                   ` (3 subsequent siblings)
  14 siblings, 2 replies; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 10:27 UTC (permalink / raw)
  To: linux-arm-kernel

If we are in BE8 mode, we must deal with the instruction stream being
in LE order when data is being loaded in BE order. Ensure the data is
swapped before processing to avoid thre following:

Change to using <asm/opcodes.h> to provide the necessary conversion
functions to change the byte ordering.

Alignment trap: not handling instruction 030091e8 at [<80333e8c>]
Unhandled fault: alignment exception (0x001) at 0xbfa09567

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 arch/arm/mm/alignment.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 6f4585b..f38145a 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -25,6 +25,7 @@
 #include <asm/cp15.h>
 #include <asm/system_info.h>
 #include <asm/unaligned.h>
+#include <asm/opcodes.h>
 
 #include "fault.h"
 
@@ -762,21 +763,24 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 	if (thumb_mode(regs)) {
 		u16 *ptr = (u16 *)(instrptr & ~1);
 		fault = probe_kernel_address(ptr, tinstr);
+		tinstr = __mem_to_opcode_thumb16(tinstr);
 		if (!fault) {
 			if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
 			    IS_T32(tinstr)) {
 				/* Thumb-2 32-bit */
 				u16 tinst2 = 0;
 				fault = probe_kernel_address(ptr + 1, tinst2);
+				tinst2 = __mem_to_opcode_thumb16(tinst2);
 				instr = (tinstr << 16) | tinst2;
 				thumb2_32b = 1;
 			} else {
 				isize = 2;
-				instr = thumb2arm(tinstr);
 			}
 		}
-	} else
+	} else {
 		fault = probe_kernel_address(instrptr, instr);
+		instr = __mem_to_opcode_arm(instr);
+	}
 
 	if (fault) {
 		type = TYPE_FAULT;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 12/14] ARM: traps: use <asm/opcodes.h> to get correct instruction order
  2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
                   ` (10 preceding siblings ...)
  2013-07-24 10:27 ` [PATCH 11/14] ARM: alignment: correctly decode instructions in BE8 mode Ben Dooks
@ 2013-07-24 10:28 ` Ben Dooks
  2013-07-24 16:20   ` Will Deacon
  2013-07-24 10:28 ` [PATCH 13/14] ARM: module: correctly relocate instructions in BE8 Ben Dooks
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 10:28 UTC (permalink / raw)
  To: linux-arm-kernel

The trap handler needs to take into account the endian configuration of
the system when loading instructions. Use <asm/opcodes.h> to provide the
necessary conversion functions.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 arch/arm/kernel/traps.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 18b32e8..c300e51 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -34,6 +34,7 @@
 #include <asm/unwind.h>
 #include <asm/tls.h>
 #include <asm/system_misc.h>
+#include <asm/opcodes.h>
 
 #include "signal.h"
 
@@ -404,23 +405,24 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
 	if (processor_mode(regs) == SVC_MODE) {
 #ifdef CONFIG_THUMB2_KERNEL
 		if (thumb_mode(regs)) {
-			instr = ((u16 *)pc)[0];
+			instr = __mem_to_opcode_thumb16(((u16 *)pc)[0]);
 			if (is_wide_instruction(instr)) {
 				instr <<= 16;
-				instr |= ((u16 *)pc)[1];
+				instr |= __mem_to_opcode_thumb16(((u16 *)pc)[1]);
 			}
 		} else
 #endif
-			instr = *(u32 *) pc;
+			instr = __mem_to_opcode_arm(*(u32 *) pc);
 	} else if (thumb_mode(regs)) {
 		if (get_user(instr, (u16 __user *)pc))
 			goto die_sig;
+		instr = __mem_to_opcode_thumb16(instr);
 		if (is_wide_instruction(instr)) {
 			unsigned int instr2;
 			if (get_user(instr2, (u16 __user *)pc+1))
 				goto die_sig;
 			instr <<= 16;
-			instr |= instr2;
+			instr |= __mem_to_opcode_thumb16(instr2);
 		}
 	} else if (get_user(instr, (u32 __user *)pc)) {
 		goto die_sig;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 13/14] ARM: module: correctly relocate instructions in BE8
  2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
                   ` (11 preceding siblings ...)
  2013-07-24 10:28 ` [PATCH 12/14] ARM: traps: use <asm/opcodes.h> to get correct instruction order Ben Dooks
@ 2013-07-24 10:28 ` Ben Dooks
  2013-07-25  9:54   ` Will Deacon
  2013-07-24 10:28 ` [PATCH 14/14] ARM: set --be8 when linking modules Ben Dooks
  2013-07-24 16:05 ` [repost] ARM big-endian support Ben Dooks
  14 siblings, 1 reply; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 10:28 UTC (permalink / raw)
  To: linux-arm-kernel

When in BE8 mode, our instructions are not in the same ordering as the
data, so use <asm/opcodes.h> to take this into account.

Note, also requires modules to be built --be8

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 arch/arm/kernel/module.c |   57 +++++++++++++++++++++++++++-------------------
 1 file changed, 34 insertions(+), 23 deletions(-)

diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 1e9be5d..7e13787 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -24,6 +24,7 @@
 #include <asm/sections.h>
 #include <asm/smp_plat.h>
 #include <asm/unwind.h>
+#include <asm/opcodes.h>
 
 #ifdef CONFIG_XIP_KERNEL
 /*
@@ -60,6 +61,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 		Elf32_Sym *sym;
 		const char *symname;
 		s32 offset;
+		u32 tmp;
 #ifdef CONFIG_THUMB2_KERNEL
 		u32 upper, lower, sign, j1, j2;
 #endif
@@ -95,7 +97,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 		case R_ARM_PC24:
 		case R_ARM_CALL:
 		case R_ARM_JUMP24:
-			offset = (*(u32 *)loc & 0x00ffffff) << 2;
+			offset = __mem_to_opcode_arm(*(u32 *)loc);
+			offset = (offset & 0x00ffffff) << 2;
 			if (offset & 0x02000000)
 				offset -= 0x04000000;
 
@@ -111,9 +114,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 			}
 
 			offset >>= 2;
+			offset &= 0x00ffffff;
 
-			*(u32 *)loc &= 0xff000000;
-			*(u32 *)loc |= offset & 0x00ffffff;
+			*(u32 *)loc &= __opcode_to_mem_arm(0xff000000);
+			*(u32 *)loc |= __opcode_to_mem_arm(offset);
 			break;
 
 	       case R_ARM_V4BX:
@@ -121,8 +125,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 			* other bits to re-code instruction as
 			* MOV PC,Rm.
 			*/
-		       *(u32 *)loc &= 0xf000000f;
-		       *(u32 *)loc |= 0x01a0f000;
+		       *(u32 *)loc &= __opcode_to_mem_arm(0xf000000f);
+		       *(u32 *)loc |= __opcode_to_mem_arm(0x01a0f000);
 		       break;
 
 		case R_ARM_PREL31:
@@ -132,7 +136,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 
 		case R_ARM_MOVW_ABS_NC:
 		case R_ARM_MOVT_ABS:
-			offset = *(u32 *)loc;
+			offset = tmp = __mem_to_opcode_arm(*(u32 *)loc);
 			offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff);
 			offset = (offset ^ 0x8000) - 0x8000;
 
@@ -140,16 +144,18 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 			if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS)
 				offset >>= 16;
 
-			*(u32 *)loc &= 0xfff0f000;
-			*(u32 *)loc |= ((offset & 0xf000) << 4) |
-					(offset & 0x0fff);
+			tmp &= 0xfff0f000;
+			tmp |= ((offset & 0xf000) << 4) |
+				(offset & 0x0fff);
+
+			*(u32 *)loc = __opcode_to_mem_arm(tmp);
 			break;
 
 #ifdef CONFIG_THUMB2_KERNEL
 		case R_ARM_THM_CALL:
 		case R_ARM_THM_JUMP24:
-			upper = *(u16 *)loc;
-			lower = *(u16 *)(loc + 2);
+			upper = __mem_to_opcode_thumb16(*(u16 *)loc);
+			lower = __mem_to_opcode_thumb16(*(u16 *)(loc + 2));
 
 			/*
 			 * 25 bit signed address range (Thumb-2 BL and B.W
@@ -198,17 +204,20 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 			sign = (offset >> 24) & 1;
 			j1 = sign ^ (~(offset >> 23) & 1);
 			j2 = sign ^ (~(offset >> 22) & 1);
-			*(u16 *)loc = (u16)((upper & 0xf800) | (sign << 10) |
+			upper = (u16)((upper & 0xf800) | (sign << 10) |
 					    ((offset >> 12) & 0x03ff));
-			*(u16 *)(loc + 2) = (u16)((lower & 0xd000) |
-						  (j1 << 13) | (j2 << 11) |
-						  ((offset >> 1) & 0x07ff));
+			lower = (u16)((lower & 0xd000) |
+				      (j1 << 13) | (j2 << 11) |
+				      ((offset >> 1) & 0x07ff));
+
+			*(u16 *)loc = __opcode_to_mem_thumb16(upper);
+			*(u16 *)(loc + 2) = __opcode_to_mem_thumb16(lower);
 			break;
 
 		case R_ARM_THM_MOVW_ABS_NC:
 		case R_ARM_THM_MOVT_ABS:
-			upper = *(u16 *)loc;
-			lower = *(u16 *)(loc + 2);
+			upper = __mem_to_opcode_thumb16(*(u16 *)loc);
+			lower = __mem_to_opcode_thumb16(*(u16 *)(loc + 2));
 
 			/*
 			 * MOVT/MOVW instructions encoding in Thumb-2:
@@ -229,12 +238,14 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 			if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS)
 				offset >>= 16;
 
-			*(u16 *)loc = (u16)((upper & 0xfbf0) |
-					    ((offset & 0xf000) >> 12) |
-					    ((offset & 0x0800) >> 1));
-			*(u16 *)(loc + 2) = (u16)((lower & 0x8f00) |
-						  ((offset & 0x0700) << 4) |
-						  (offset & 0x00ff));
+			upper = (u16)((upper & 0xfbf0) |
+				      ((offset & 0xf000) >> 12) |
+				      ((offset & 0x0800) >> 1));
+			lower = (u16)((lower & 0x8f00) |
+				      ((offset & 0x0700) << 4) |
+				      (offset & 0x00ff));
+			*(u16 *)loc = __opcode_to_mem_thumb16(upper);
+			*(u16 *)(loc + 2) = __opcode_to_mem_thumb16(lower);
 			break;
 #endif
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 14/14] ARM: set --be8 when linking modules
  2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
                   ` (12 preceding siblings ...)
  2013-07-24 10:28 ` [PATCH 13/14] ARM: module: correctly relocate instructions in BE8 Ben Dooks
@ 2013-07-24 10:28 ` Ben Dooks
  2013-07-24 16:25   ` Will Deacon
  2013-07-24 23:41   ` Nicolas Pitre
  2013-07-24 16:05 ` [repost] ARM big-endian support Ben Dooks
  14 siblings, 2 replies; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 10:28 UTC (permalink / raw)
  To: linux-arm-kernel

To avoid having to make every text section swap the instruction order
of all instructions, make sure modules are built also built with --be8
(as is the current kernel final link).

If we do not do this, we would end up having to swap all instructions
when loading a module, instead of just the instructions that we are
applying ELF relocations to.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 arch/arm/Makefile |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 1ba358b..70bc19e 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -16,6 +16,7 @@ LDFLAGS		:=
 LDFLAGS_vmlinux	:=-p --no-undefined -X
 ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
 LDFLAGS_vmlinux	+= --be8
+LDFLAGS_MODULE	+= --be8
 endif
 
 OBJCOPYFLAGS	:=-O binary -R .comment -S
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 02/14] ARM: asm: Add ARM_BE8() assembly helper
  2013-07-24 10:27 ` [PATCH 02/14] ARM: asm: Add ARM_BE8() assembly helper Ben Dooks
@ 2013-07-24 14:28   ` Will Deacon
  2013-07-24 14:38     ` Ben Dooks
  2013-07-24 14:48     ` Ben Dooks
  0 siblings, 2 replies; 46+ messages in thread
From: Will Deacon @ 2013-07-24 14:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 24, 2013 at 11:27:50AM +0100, Ben Dooks wrote:
> 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.
> 
> Acked-by: Nicolas Pitre <nico@linaro.org>
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>

Reviewed-by: Will Deacon <will.deacon@arm.com>

We could probably add a similar ARM_LE helper to clean up the
__LITTLE_ENDIAN definitions in arch/arm/net/bpf_jit_32.c too.

Will

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 03/14] ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
  2013-07-24 10:27 ` [PATCH 03/14] ARM: fixup_pv_table bug when CPU_ENDIAN_BE8 Ben Dooks
@ 2013-07-24 14:33   ` Will Deacon
  2013-07-24 15:24     ` Ben Dooks
  0 siblings, 1 reply; 46+ messages in thread
From: Will Deacon @ 2013-07-24 14:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 24, 2013 at 11:27:51AM +0100, Ben Dooks wrote:
> 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 (in the
> case where the code is not thumb2).
> 
> For thumb2, we add the necessary rev16 instructions to ensure that
> the instructions are processed in the correct format, as it was
> easier than re-writing the code to contain a mask and shift.
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
>  arch/arm/kernel/head.S |    8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
> index 8bac553..e40c0b3b 100644
> --- a/arch/arm/kernel/head.S
> +++ b/arch/arm/kernel/head.S
> @@ -584,8 +584,10 @@ __fixup_a_pv_table:
>  	b	2f
>  1:	add     r7, r3
>  	ldrh	ip, [r7, #2]
> +ARM_BE8(rev16	ip, ip)
>  	and	ip, 0x8f00
>  	orr	ip, r6	@ mask in offset bits 31-24
> +ARM_BE8(rev16	ip, ip)

I'm not sure I follow you when you say this is easier than a mask and a
shift? As far as I can tell, it's two extra instructions and makes the LE
and BE cases look different.

>  	strh	ip, [r7, #2]
>  2:	cmp	r4, r5
>  	ldrcc	r7, [r4], #4	@ use branch for delay slot
> @@ -594,8 +596,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

Pedantry: you could add a space between lsl and #24.

Will

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 02/14] ARM: asm: Add ARM_BE8() assembly helper
  2013-07-24 14:28   ` Will Deacon
@ 2013-07-24 14:38     ` Ben Dooks
  2013-07-24 14:48     ` Ben Dooks
  1 sibling, 0 replies; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 14:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 24/07/13 15:28, Will Deacon wrote:
> On Wed, Jul 24, 2013 at 11:27:50AM +0100, Ben Dooks wrote:
>> 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.
>>
>> Acked-by: Nicolas Pitre<nico@linaro.org>
>> Signed-off-by: Ben Dooks<ben.dooks@codethink.co.uk>
>
> Reviewed-by: Will Deacon<will.deacon@arm.com>
>
> We could probably add a similar ARM_LE helper to clean up the
> __LITTLE_ENDIAN definitions in arch/arm/net/bpf_jit_32.c too.

Ok, but I would like to get to the point where this series is
just fixes now. I would like to try and get it merged and then
go back and look at these issues.

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 04/14] ARM: set BE8 if LE in head code
  2013-07-24 10:27 ` [PATCH 04/14] ARM: set BE8 if LE in head code Ben Dooks
@ 2013-07-24 14:41   ` Will Deacon
  2013-07-24 15:55     ` Ben Dooks
  0 siblings, 1 reply; 46+ messages in thread
From: Will Deacon @ 2013-07-24 14:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 24, 2013 at 11:27:52AM +0100, Ben Dooks wrote:
> 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.
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
>  arch/arm/boot/compressed/head.S |    1 +
>  arch/arm/kernel/head.S          |    4 ++++
>  arch/arm/kernel/sleep.S         |    1 +
>  3 files changed, 6 insertions(+)
> 
> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
> index 4eb8364..4d83bfd 100644
> --- a/arch/arm/boot/compressed/head.S
> +++ b/arch/arm/boot/compressed/head.S
> @@ -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

I find the comment here slightly confusing as it makes it sound like the
macro expands to nothing if we're BE8 (which is clearly not the case).

>  		mrs	r9, cpsr
>  #ifdef CONFIG_ARM_VIRT_EXT
>  		bl	__hyp_stub_install	@ get into SVC mode, reversibly
> diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
> index e40c0b3b..706c441 100644
> --- a/arch/arm/kernel/head.S
> +++ b/arch/arm/kernel/head.S
> @@ -77,6 +77,7 @@
>  
>  	__HEAD
>  ENTRY(stext)
> + ARM_BE8(setend	be )			@ ensure we are in BE8 mode

Alignment issue here -- please try to align the instruction with the
instructions below (it's awkward to read with all the brackets).

>  
>   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
> diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> index 987dcf3..954c28a 100644
> --- a/arch/arm/kernel/sleep.S
> +++ b/arch/arm/kernel/sleep.S
> @@ -81,6 +81,7 @@ ENDPROC(cpu_resume_after_mmu)
>  	.data
>  	.align
>  ENTRY(cpu_resume)
> +ARM_BE8(setend be)			@ ensure we are in BE mode

Any reason to have three different comments for the same thing? I think you
probably just need to comment the one in head.S.

Will

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 05/14] ARM: pl01x debug code endian fix
  2013-07-24 10:27 ` [PATCH 05/14] ARM: pl01x debug code endian fix Ben Dooks
@ 2013-07-24 14:44   ` Will Deacon
  0 siblings, 0 replies; 46+ messages in thread
From: Will Deacon @ 2013-07-24 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 24, 2013 at 11:27:53AM +0100, Ben Dooks wrote:
> 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.
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---

Reviewed-by: Will Deacon <will.deacon@arm.com>

Will

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 02/14] ARM: asm: Add ARM_BE8() assembly helper
  2013-07-24 14:28   ` Will Deacon
  2013-07-24 14:38     ` Ben Dooks
@ 2013-07-24 14:48     ` Ben Dooks
  1 sibling, 0 replies; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 14:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 24/07/13 15:28, Will Deacon wrote:
> On Wed, Jul 24, 2013 at 11:27:50AM +0100, Ben Dooks wrote:
>> 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.
>>
>> Acked-by: Nicolas Pitre<nico@linaro.org>
>> Signed-off-by: Ben Dooks<ben.dooks@codethink.co.uk>
>
> Reviewed-by: Will Deacon<will.deacon@arm.com>
>
> We could probably add a similar ARM_LE helper to clean up the
> __LITTLE_ENDIAN definitions in arch/arm/net/bpf_jit_32.c too.
>
> Will

I did however realise we need to fix the instruction storage
so changed _emit to fix this as follows:

     ARM: net: fix arm instruction endian-ness in bpf_jit_32.c

     Use <asm/opcodes.h> to correctly transform instruction byte ordering
     into in-memory ordering.

     Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>

diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
index 1a643ee..95b43b6 100644
--- a/arch/arm/net/bpf_jit_32.c
+++ b/arch/arm/net/bpf_jit_32.c
@@ -19,6 +19,7 @@
  #include <linux/if_vlan.h>
  #include <asm/cacheflush.h>
  #include <asm/hwcap.h>
+#include <asm/opcodes.h>

  #include "bpf_jit_32.h"

@@ -113,8 +114,11 @@ static u32 jit_udiv(u32 dividend, u32 divisor)

  static inline void _emit(int cond, u32 inst, struct jit_ctx *ctx)
  {
+       inst |= (cond << 28);
+       inst = __opcode_to_mem_arm(inst);
+
         if (ctx->target != NULL)
-               ctx->target[ctx->idx] = inst | (cond << 28);
+               ctx->target[ctx->idx] = inst;

         ctx->idx++;
  }

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

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 06/14] ARM: twd: data endian fix
  2013-07-24 10:27 ` [PATCH 06/14] ARM: twd: data " Ben Dooks
@ 2013-07-24 14:49   ` Will Deacon
  2013-07-24 15:00     ` Ben Dooks
  2013-07-24 15:06     ` Ben Dooks
  0 siblings, 2 replies; 46+ messages in thread
From: Will Deacon @ 2013-07-24 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 24, 2013 at 11:27:54AM +0100, Ben Dooks wrote:
> 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.
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>

Reviewed-by: Will Deacon <will.deacon@arm.com>

There are a bunch of other __raw_* users under arch/arm/, but I suppose we
can let other people move those over as they see fit. It wouldn't hurt to
fix arch/arm/include/asm/{cti,hardware/coresight.h} though.

Will

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 06/14] ARM: twd: data endian fix
  2013-07-24 14:49   ` Will Deacon
@ 2013-07-24 15:00     ` Ben Dooks
  2013-07-24 15:06     ` Ben Dooks
  1 sibling, 0 replies; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 15:00 UTC (permalink / raw)
  To: linux-arm-kernel

On 24/07/13 15:49, Will Deacon wrote:
> On Wed, Jul 24, 2013 at 11:27:54AM +0100, Ben Dooks wrote:
>> 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.
>>
>> Signed-off-by: Ben Dooks<ben.dooks@codethink.co.uk>
>
> Reviewed-by: Will Deacon<will.deacon@arm.com>
>
> There are a bunch of other __raw_* users under arch/arm/, but I suppose we
> can let other people move those over as they see fit. It wouldn't hurt to
> fix arch/arm/include/asm/{cti,hardware/coresight.h} though.

I will have a look at these.

Quite a lot of the machine specific stuff I decided to leave alone as
fixing everything was out of my remit, and is best left to a later
effort.

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 07/14] ARM: smp_scu: data endian fixes
  2013-07-24 10:27 ` [PATCH 07/14] ARM: smp_scu: data endian fixes Ben Dooks
@ 2013-07-24 15:05   ` Will Deacon
  0 siblings, 0 replies; 46+ messages in thread
From: Will Deacon @ 2013-07-24 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 24, 2013 at 11:27:55AM +0100, Ben Dooks wrote:
> 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.
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---

Reviewed-by: Will Deacon <will.deacon@arm.com>

Will

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 06/14] ARM: twd: data endian fix
  2013-07-24 14:49   ` Will Deacon
  2013-07-24 15:00     ` Ben Dooks
@ 2013-07-24 15:06     ` Ben Dooks
  2013-07-24 16:29       ` Will Deacon
  1 sibling, 1 reply; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 15:06 UTC (permalink / raw)
  To: linux-arm-kernel

On 24/07/13 15:49, Will Deacon wrote:
> On Wed, Jul 24, 2013 at 11:27:54AM +0100, Ben Dooks wrote:
>> 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.
>>
>> Signed-off-by: Ben Dooks<ben.dooks@codethink.co.uk>
>
> Reviewed-by: Will Deacon<will.deacon@arm.com>
>
> There are a bunch of other __raw_* users under arch/arm/, but I suppose we
> can let other people move those over as they see fit. It wouldn't hurt to
> fix arch/arm/include/asm/{cti,hardware/coresight.h} though.

I didn't think to look for things under there.

Do people think it would be worth just changing __raw_read/__raw_write
functions to also take into account endian-ness?

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 03/14] ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
  2013-07-24 14:33   ` Will Deacon
@ 2013-07-24 15:24     ` Ben Dooks
  2013-07-25 10:14       ` Will Deacon
  0 siblings, 1 reply; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 15:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 24/07/13 15:33, Will Deacon wrote:
> On Wed, Jul 24, 2013 at 11:27:51AM +0100, Ben Dooks wrote:
>> 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 (in the
>> case where the code is not thumb2).
>>
>> For thumb2, we add the necessary rev16 instructions to ensure that
>> the instructions are processed in the correct format, as it was
>> easier than re-writing the code to contain a mask and shift.
>>
>> Signed-off-by: Ben Dooks<ben.dooks@codethink.co.uk>
>> ---
>>   arch/arm/kernel/head.S |    8 ++++++++
>>   1 file changed, 8 insertions(+)
>>
>> diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
>> index 8bac553..e40c0b3b 100644
>> --- a/arch/arm/kernel/head.S
>> +++ b/arch/arm/kernel/head.S
>> @@ -584,8 +584,10 @@ __fixup_a_pv_table:
>>   	b	2f
>>   1:	add     r7, r3
>>   	ldrh	ip, [r7, #2]
>> +ARM_BE8(rev16	ip, ip)
>>   	and	ip, 0x8f00
>>   	orr	ip, r6	@ mask in offset bits 31-24
>> +ARM_BE8(rev16	ip, ip)
>
> I'm not sure I follow you when you say this is easier than a mask and a
> shift? As far as I can tell, it's two extra instructions and makes the LE
> and BE cases look different.

I am not as familiar with THUMB2 as the ARM, so it was easier
to do this than see if there where any spare registers to hold the
mask and shift values, and use them.

>>   	strh	ip, [r7, #2]
>>   2:	cmp	r4, r5
>>   	ldrcc	r7, [r4], #4	@ use branch for delay slot
>> @@ -594,8 +596,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
>
> Pedantry: you could add a space between lsl and #24.
>
> Will


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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 11/14] ARM: alignment: correctly decode instructions in BE8 mode.
  2013-07-24 10:27 ` [PATCH 11/14] ARM: alignment: correctly decode instructions in BE8 mode Ben Dooks
@ 2013-07-24 15:28   ` Will Deacon
  2013-07-25  9:44   ` Will Deacon
  1 sibling, 0 replies; 46+ messages in thread
From: Will Deacon @ 2013-07-24 15:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 24, 2013 at 11:27:59AM +0100, Ben Dooks wrote:
> If we are in BE8 mode, we must deal with the instruction stream being
> in LE order when data is being loaded in BE order. Ensure the data is
> swapped before processing to avoid thre following:
> 
> Change to using <asm/opcodes.h> to provide the necessary conversion
> functions to change the byte ordering.
> 
> Alignment trap: not handling instruction 030091e8 at [<80333e8c>]
> Unhandled fault: alignment exception (0x001) at 0xbfa09567
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
>  arch/arm/mm/alignment.c |    8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
> index 6f4585b..f38145a 100644
> --- a/arch/arm/mm/alignment.c
> +++ b/arch/arm/mm/alignment.c
> @@ -25,6 +25,7 @@
>  #include <asm/cp15.h>
>  #include <asm/system_info.h>
>  #include <asm/unaligned.h>
> +#include <asm/opcodes.h>
>  
>  #include "fault.h"
>  
> @@ -762,21 +763,24 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
>  	if (thumb_mode(regs)) {
>  		u16 *ptr = (u16 *)(instrptr & ~1);
>  		fault = probe_kernel_address(ptr, tinstr);
> +		tinstr = __mem_to_opcode_thumb16(tinstr);
>  		if (!fault) {
>  			if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
>  			    IS_T32(tinstr)) {
>  				/* Thumb-2 32-bit */
>  				u16 tinst2 = 0;
>  				fault = probe_kernel_address(ptr + 1, tinst2);
> +				tinst2 = __mem_to_opcode_thumb16(tinst2);
>  				instr = (tinstr << 16) | tinst2;

Took me a while to convince myself, but looks right to me:

Reviewed-by: Will Deacon <will.deacon@arm.com>

Will

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 04/14] ARM: set BE8 if LE in head code
  2013-07-24 14:41   ` Will Deacon
@ 2013-07-24 15:55     ` Ben Dooks
  0 siblings, 0 replies; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 15:55 UTC (permalink / raw)
  To: linux-arm-kernel

On 24/07/13 15:41, Will Deacon wrote:
> On Wed, Jul 24, 2013 at 11:27:52AM +0100, Ben Dooks wrote:
>> 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.
>>
>> Signed-off-by: Ben Dooks<ben.dooks@codethink.co.uk>
>> ---
>>   arch/arm/boot/compressed/head.S |    1 +
>>   arch/arm/kernel/head.S          |    4 ++++
>>   arch/arm/kernel/sleep.S         |    1 +
>>   3 files changed, 6 insertions(+)
>>
>> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
>> index 4eb8364..4d83bfd 100644
>> --- a/arch/arm/boot/compressed/head.S
>> +++ b/arch/arm/boot/compressed/head.S
>> @@ -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
 >
> I find the comment here slightly confusing as it makes it sound like the
> macro expands to nothing if we're BE8 (which is clearly not the case).

I've changed it to "go BE8 if compiled for BE8"

>>   		mrs	r9, cpsr
>>   #ifdef CONFIG_ARM_VIRT_EXT
>>   		bl	__hyp_stub_install	@ get into SVC mode, reversibly
>> diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
>> index e40c0b3b..706c441 100644
>> --- a/arch/arm/kernel/head.S
>> +++ b/arch/arm/kernel/head.S
>> @@ -77,6 +77,7 @@
>>
>>   	__HEAD
>>   ENTRY(stext)
>> + ARM_BE8(setend	be )			@ ensure we are in BE8 mode
>
> Alignment issue here -- please try to align the instruction with the
> instructions below (it's awkward to read with all the brackets).

If I move it one to the left, then it gets coloured blue by
my editor, as it is the first thing on the line like the
ENTRY() macro.

>>
>>    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
>> diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
>> index 987dcf3..954c28a 100644
>> --- a/arch/arm/kernel/sleep.S
>> +++ b/arch/arm/kernel/sleep.S
>> @@ -81,6 +81,7 @@ ENDPROC(cpu_resume_after_mmu)
>>   	.data
>>   	.align
>>   ENTRY(cpu_resume)
>> +ARM_BE8(setend be)			@ ensure we are in BE mode
>
> Any reason to have three different comments for the same thing? I think you
> probably just need to comment the one in head.S.

I've changed the comments to match in.

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [repost] ARM big-endian support
  2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
                   ` (13 preceding siblings ...)
  2013-07-24 10:28 ` [PATCH 14/14] ARM: set --be8 when linking modules Ben Dooks
@ 2013-07-24 16:05 ` Ben Dooks
  2013-07-29 13:26   ` Thomas Petazzoni
  14 siblings, 1 reply; 46+ messages in thread
From: Ben Dooks @ 2013-07-24 16:05 UTC (permalink / raw)
  To: linux-arm-kernel

On 24/07/13 11:27, Ben Dooks wrote:
> A repost (as requested) of the current big-endian core work for review.

New branches at git.baserock.org/delta/linux.git
	311/be/atags-v4
  	311/be/core-v4

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 12/14] ARM: traps: use <asm/opcodes.h> to get correct instruction order
  2013-07-24 10:28 ` [PATCH 12/14] ARM: traps: use <asm/opcodes.h> to get correct instruction order Ben Dooks
@ 2013-07-24 16:20   ` Will Deacon
  0 siblings, 0 replies; 46+ messages in thread
From: Will Deacon @ 2013-07-24 16:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 24, 2013 at 11:28:00AM +0100, Ben Dooks wrote:
> The trap handler needs to take into account the endian configuration of
> the system when loading instructions. Use <asm/opcodes.h> to provide the
> necessary conversion functions.
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
>  arch/arm/kernel/traps.c |   10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
> index 18b32e8..c300e51 100644
> --- a/arch/arm/kernel/traps.c
> +++ b/arch/arm/kernel/traps.c
> @@ -34,6 +34,7 @@
>  #include <asm/unwind.h>
>  #include <asm/tls.h>
>  #include <asm/system_misc.h>
> +#include <asm/opcodes.h>
>  
>  #include "signal.h"
>  
> @@ -404,23 +405,24 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
>  	if (processor_mode(regs) == SVC_MODE) {
>  #ifdef CONFIG_THUMB2_KERNEL
>  		if (thumb_mode(regs)) {
> -			instr = ((u16 *)pc)[0];
> +			instr = __mem_to_opcode_thumb16(((u16 *)pc)[0]);
>  			if (is_wide_instruction(instr)) {
>  				instr <<= 16;
> -				instr |= ((u16 *)pc)[1];
> +				instr |= __mem_to_opcode_thumb16(((u16 *)pc)[1]);
>  			}
>  		} else
>  #endif
> -			instr = *(u32 *) pc;
> +			instr = __mem_to_opcode_arm(*(u32 *) pc);
>  	} else if (thumb_mode(regs)) {
>  		if (get_user(instr, (u16 __user *)pc))
>  			goto die_sig;
> +		instr = __mem_to_opcode_thumb16(instr);
>  		if (is_wide_instruction(instr)) {
>  			unsigned int instr2;
>  			if (get_user(instr2, (u16 __user *)pc+1))
>  				goto die_sig;
>  			instr <<= 16;
> -			instr |= instr2;
> +			instr |= __mem_to_opcode_thumb16(instr2);
>  		}
>  	} else if (get_user(instr, (u32 __user *)pc)) {
>  		goto die_sig;

Maybe it's also worth updating dump_instr, so that we don't confuse people
by printing the faulting instruction in the wrong endianness.

Will

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 14/14] ARM: set --be8 when linking modules
  2013-07-24 10:28 ` [PATCH 14/14] ARM: set --be8 when linking modules Ben Dooks
@ 2013-07-24 16:25   ` Will Deacon
  2013-07-24 23:41   ` Nicolas Pitre
  1 sibling, 0 replies; 46+ messages in thread
From: Will Deacon @ 2013-07-24 16:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 24, 2013 at 11:28:02AM +0100, Ben Dooks wrote:
> To avoid having to make every text section swap the instruction order
> of all instructions, make sure modules are built also built with --be8
> (as is the current kernel final link).
> 
> If we do not do this, we would end up having to swap all instructions
> when loading a module, instead of just the instructions that we are
> applying ELF relocations to.
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>

Reviewed-by: Will Deacon <will.deacon@arm.com>

Will

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 06/14] ARM: twd: data endian fix
  2013-07-24 15:06     ` Ben Dooks
@ 2013-07-24 16:29       ` Will Deacon
  0 siblings, 0 replies; 46+ messages in thread
From: Will Deacon @ 2013-07-24 16:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 24, 2013 at 04:06:58PM +0100, Ben Dooks wrote:
> On 24/07/13 15:49, Will Deacon wrote:
> > On Wed, Jul 24, 2013 at 11:27:54AM +0100, Ben Dooks wrote:
> >> 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.
> >>
> >> Signed-off-by: Ben Dooks<ben.dooks@codethink.co.uk>
> >
> > Reviewed-by: Will Deacon<will.deacon@arm.com>
> >
> > There are a bunch of other __raw_* users under arch/arm/, but I suppose we
> > can let other people move those over as they see fit. It wouldn't hurt to
> > fix arch/arm/include/asm/{cti,hardware/coresight.h} though.
> 
> I didn't think to look for things under there.
> 
> Do people think it would be worth just changing __raw_read/__raw_write
> functions to also take into account endian-ness?

That's probably a bit too far and will likely break some of the many drivers
which use these accessors. It also puts us at odds with other architectures
offering these accessors, so we're better off just fixing the callsites as
appropriate.

Will

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 14/14] ARM: set --be8 when linking modules
  2013-07-24 10:28 ` [PATCH 14/14] ARM: set --be8 when linking modules Ben Dooks
  2013-07-24 16:25   ` Will Deacon
@ 2013-07-24 23:41   ` Nicolas Pitre
  1 sibling, 0 replies; 46+ messages in thread
From: Nicolas Pitre @ 2013-07-24 23:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 24 Jul 2013, Ben Dooks wrote:

> To avoid having to make every text section swap the instruction order
> of all instructions, make sure modules are built also built with --be8
> (as is the current kernel final link).
> 
> If we do not do this, we would end up having to swap all instructions
> when loading a module, instead of just the instructions that we are
> applying ELF relocations to.

That wouldn't work anyway as you'd also swap constants embedded in the 
instruction stream such as literal pools which are most certainly in BE 
mode already.

> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>

Please make sure the kernel will reject modules if they're not compiled 
appropriately.  Either by looking at the ELF record or by altering 
MODULE_ARCH_VERMAGIC.


Nicolas

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 11/14] ARM: alignment: correctly decode instructions in BE8 mode.
  2013-07-24 10:27 ` [PATCH 11/14] ARM: alignment: correctly decode instructions in BE8 mode Ben Dooks
  2013-07-24 15:28   ` Will Deacon
@ 2013-07-25  9:44   ` Will Deacon
  1 sibling, 0 replies; 46+ messages in thread
From: Will Deacon @ 2013-07-25  9:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 24, 2013 at 11:27:59AM +0100, Ben Dooks wrote:
> If we are in BE8 mode, we must deal with the instruction stream being
> in LE order when data is being loaded in BE order. Ensure the data is
> swapped before processing to avoid thre following:
> 
> Change to using <asm/opcodes.h> to provide the necessary conversion
> functions to change the byte ordering.
> 
> Alignment trap: not handling instruction 030091e8 at [<80333e8c>]
> Unhandled fault: alignment exception (0x001) at 0xbfa09567
> 
> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
>  arch/arm/mm/alignment.c |    8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
> index 6f4585b..f38145a 100644
> --- a/arch/arm/mm/alignment.c
> +++ b/arch/arm/mm/alignment.c
> @@ -25,6 +25,7 @@
>  #include <asm/cp15.h>
>  #include <asm/system_info.h>
>  #include <asm/unaligned.h>
> +#include <asm/opcodes.h>
>  
>  #include "fault.h"
>  
> @@ -762,21 +763,24 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
>  	if (thumb_mode(regs)) {
>  		u16 *ptr = (u16 *)(instrptr & ~1);
>  		fault = probe_kernel_address(ptr, tinstr);
> +		tinstr = __mem_to_opcode_thumb16(tinstr);
>  		if (!fault) {
>  			if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
>  			    IS_T32(tinstr)) {
>  				/* Thumb-2 32-bit */
>  				u16 tinst2 = 0;
>  				fault = probe_kernel_address(ptr + 1, tinst2);
> +				tinst2 = __mem_to_opcode_thumb16(tinst2);
>  				instr = (tinstr << 16) | tinst2;
>  				thumb2_32b = 1;
>  			} else {
>  				isize = 2;
> -				instr = thumb2arm(tinstr);

As Dave pointed out in the other thread, this looks like an erroneous
deletion.

Will

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 13/14] ARM: module: correctly relocate instructions in BE8
  2013-07-24 10:28 ` [PATCH 13/14] ARM: module: correctly relocate instructions in BE8 Ben Dooks
@ 2013-07-25  9:54   ` Will Deacon
  0 siblings, 0 replies; 46+ messages in thread
From: Will Deacon @ 2013-07-25  9:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 24, 2013 at 11:28:01AM +0100, Ben Dooks wrote:
> When in BE8 mode, our instructions are not in the same ordering as the
> data, so use <asm/opcodes.h> to take this into account.
> 
> Note, also requires modules to be built --be8

This seems fairly methodical to me.

> @@ -132,7 +136,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
>  
>  		case R_ARM_MOVW_ABS_NC:
>  		case R_ARM_MOVT_ABS:
> -			offset = *(u32 *)loc;
> +			offset = tmp = __mem_to_opcode_arm(*(u32 *)loc);
>  			offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff);
>  			offset = (offset ^ 0x8000) - 0x8000;

I find the double assignment a bit gratuitous, but that's just a cosmetic
issue.

  Reviewed-by: Will Deacon <will.deacon@arm.com>

Will

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 03/14] ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
  2013-07-24 15:24     ` Ben Dooks
@ 2013-07-25 10:14       ` Will Deacon
  2013-07-25 10:21         ` Ben Dooks
  2013-07-25 10:25         ` Russell King - ARM Linux
  0 siblings, 2 replies; 46+ messages in thread
From: Will Deacon @ 2013-07-25 10:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 24, 2013 at 04:24:34PM +0100, Ben Dooks wrote:
> On 24/07/13 15:33, Will Deacon wrote:
> > On Wed, Jul 24, 2013 at 11:27:51AM +0100, Ben Dooks wrote:
> >> 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 (in the
> >> case where the code is not thumb2).
> >>
> >> For thumb2, we add the necessary rev16 instructions to ensure that
> >> the instructions are processed in the correct format, as it was
> >> easier than re-writing the code to contain a mask and shift.
> >>
> >> Signed-off-by: Ben Dooks<ben.dooks@codethink.co.uk>
> >> ---
> >>   arch/arm/kernel/head.S |    8 ++++++++
> >>   1 file changed, 8 insertions(+)
> >>
> >> diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
> >> index 8bac553..e40c0b3b 100644
> >> --- a/arch/arm/kernel/head.S
> >> +++ b/arch/arm/kernel/head.S
> >> @@ -584,8 +584,10 @@ __fixup_a_pv_table:
> >>   	b	2f
> >>   1:	add     r7, r3
> >>   	ldrh	ip, [r7, #2]
> >> +ARM_BE8(rev16	ip, ip)
> >>   	and	ip, 0x8f00
> >>   	orr	ip, r6	@ mask in offset bits 31-24
> >> +ARM_BE8(rev16	ip, ip)
> >
> > I'm not sure I follow you when you say this is easier than a mask and a
> > shift? As far as I can tell, it's two extra instructions and makes the LE
> > and BE cases look different.
> 
> I am not as familiar with THUMB2 as the ARM, so it was easier
> to do this than see if there where any spare registers to hold the
> mask and shift values, and use them.

What's wrong with the following?

Will

--->8

diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 9cf6063..ee660c2 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -581,8 +581,13 @@ __fixup_a_pv_table:
        b       2f
 1:     add     r7, r3
        ldrh    ip, [r7, #2]
+#ifdef CONFIG_CPU_ENDIAN_BE8
+       and     ip, 0x008f
+       orr     ip, ip, r6, lsl #24
+#else
        and     ip, 0x8f00
        orr     ip, r6  @ mask in offset bits 31-24
+#endif
        strh    ip, [r7, #2]
 2:     cmp     r4, r5
        ldrcc   r7, [r4], #4    @ use branch for delay slot

^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH 03/14] ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
  2013-07-25 10:14       ` Will Deacon
@ 2013-07-25 10:21         ` Ben Dooks
  2013-07-25 10:30           ` Will Deacon
  2013-07-25 10:25         ` Russell King - ARM Linux
  1 sibling, 1 reply; 46+ messages in thread
From: Ben Dooks @ 2013-07-25 10:21 UTC (permalink / raw)
  To: linux-arm-kernel

On 25/07/13 11:14, Will Deacon wrote:
> On Wed, Jul 24, 2013 at 04:24:34PM +0100, Ben Dooks wrote:
>> On 24/07/13 15:33, Will Deacon wrote:
>>> On Wed, Jul 24, 2013 at 11:27:51AM +0100, Ben Dooks wrote:
>>>> 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 (in the
>>>> case where the code is not thumb2).
>>>>
>>>> For thumb2, we add the necessary rev16 instructions to ensure that
>>>> the instructions are processed in the correct format, as it was
>>>> easier than re-writing the code to contain a mask and shift.
>>>>
>>>> Signed-off-by: Ben Dooks<ben.dooks@codethink.co.uk>
>>>> ---
>>>>    arch/arm/kernel/head.S |    8 ++++++++
>>>>    1 file changed, 8 insertions(+)
>>>>
>>>> diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
>>>> index 8bac553..e40c0b3b 100644
>>>> --- a/arch/arm/kernel/head.S
>>>> +++ b/arch/arm/kernel/head.S
>>>> @@ -584,8 +584,10 @@ __fixup_a_pv_table:
>>>>    	b	2f
>>>>    1:	add     r7, r3
>>>>    	ldrh	ip, [r7, #2]
>>>> +ARM_BE8(rev16	ip, ip)
>>>>    	and	ip, 0x8f00
>>>>    	orr	ip, r6	@ mask in offset bits 31-24
>>>> +ARM_BE8(rev16	ip, ip)
>>>
>>> I'm not sure I follow you when you say this is easier than a mask and a
>>> shift? As far as I can tell, it's two extra instructions and makes the LE
>>> and BE cases look different.
>>
>> I am not as familiar with THUMB2 as the ARM, so it was easier
>> to do this than see if there where any spare registers to hold the
>> mask and shift values, and use them.
>
> What's wrong with the following?
>
> Will
>
> --->8
>
> diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
> index 9cf6063..ee660c2 100644
> --- a/arch/arm/kernel/head.S
> +++ b/arch/arm/kernel/head.S
> @@ -581,8 +581,13 @@ __fixup_a_pv_table:
>          b       2f
>   1:     add     r7, r3
>          ldrh    ip, [r7, #2]
> +#ifdef CONFIG_CPU_ENDIAN_BE8
> +       and     ip, 0x008f
> +       orr     ip, ip, r6, lsl #24
> +#else
>          and     ip, 0x8f00
>          orr     ip, r6  @ mask in offset bits 31-24
> +#endif
>          strh    ip, [r7, #2]
>   2:     cmp     r4, r5
>          ldrcc   r7, [r4], #4    @ use branch for delay slot

If the offset bits are 8bits, then that would
be fine (apart from the lsl #8).

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 03/14] ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
  2013-07-25 10:14       ` Will Deacon
  2013-07-25 10:21         ` Ben Dooks
@ 2013-07-25 10:25         ` Russell King - ARM Linux
  2013-07-25 10:34           ` Ben Dooks
  2013-07-25 10:40           ` Will Deacon
  1 sibling, 2 replies; 46+ messages in thread
From: Russell King - ARM Linux @ 2013-07-25 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jul 25, 2013 at 11:14:42AM +0100, Will Deacon wrote:
> What's wrong with the following?

Is this like a challenge to find the silly mistake?

> @@ -581,8 +581,13 @@ __fixup_a_pv_table:
>         b       2f
>  1:     add     r7, r3
>         ldrh    ip, [r7, #2]
> +#ifdef CONFIG_CPU_ENDIAN_BE8
> +       and     ip, 0x008f
> +       orr     ip, ip, r6, lsl #24
> +#else
>         and     ip, 0x8f00
>         orr     ip, r6  @ mask in offset bits 31-24
> +#endif
>         strh    ip, [r7, #2]

Well, ip is being loaded/stored as 16bit, but you're putting r6 in to
ip's bits 31-24, which are going to be ignored by the following strh.

The comment "@ mask in offset bits 31-24" refers to the physical address
bits here, which are already pre-shifted to bits 7-0 in r6.

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 03/14] ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
  2013-07-25 10:21         ` Ben Dooks
@ 2013-07-25 10:30           ` Will Deacon
  0 siblings, 0 replies; 46+ messages in thread
From: Will Deacon @ 2013-07-25 10:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jul 25, 2013 at 11:21:21AM +0100, Ben Dooks wrote:
> On 25/07/13 11:14, Will Deacon wrote:
> > What's wrong with the following?
> >
> > --->8
> >
> > diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
> > index 9cf6063..ee660c2 100644
> > --- a/arch/arm/kernel/head.S
> > +++ b/arch/arm/kernel/head.S
> > @@ -581,8 +581,13 @@ __fixup_a_pv_table:
> >          b       2f
> >   1:     add     r7, r3
> >          ldrh    ip, [r7, #2]
> > +#ifdef CONFIG_CPU_ENDIAN_BE8
> > +       and     ip, 0x008f
> > +       orr     ip, ip, r6, lsl #24
> > +#else
> >          and     ip, 0x8f00
> >          orr     ip, r6  @ mask in offset bits 31-24
> > +#endif
> >          strh    ip, [r7, #2]
> >   2:     cmp     r4, r5
> >          ldrcc   r7, [r4], #4    @ use branch for delay slot
> 
> If the offset bits are 8bits, then that would
> be fine (apart from the lsl #8).

Ah yes, I see the problem now. Maybe it's easier to rev r6 for the
big-endian case and leave the orr alone.

Will

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 03/14] ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
  2013-07-25 10:25         ` Russell King - ARM Linux
@ 2013-07-25 10:34           ` Ben Dooks
  2013-07-25 10:40           ` Will Deacon
  1 sibling, 0 replies; 46+ messages in thread
From: Ben Dooks @ 2013-07-25 10:34 UTC (permalink / raw)
  To: linux-arm-kernel

On 25/07/13 11:25, Russell King - ARM Linux wrote:
> On Thu, Jul 25, 2013 at 11:14:42AM +0100, Will Deacon wrote:
>> What's wrong with the following?
>
> Is this like a challenge to find the silly mistake?
>
>> @@ -581,8 +581,13 @@ __fixup_a_pv_table:
>>          b       2f
>>   1:     add     r7, r3
>>          ldrh    ip, [r7, #2]
>> +#ifdef CONFIG_CPU_ENDIAN_BE8
>> +       and     ip, 0x008f
>> +       orr     ip, ip, r6, lsl #24
>> +#else
>>          and     ip, 0x8f00
>>          orr     ip, r6  @ mask in offset bits 31-24
>> +#endif
>>          strh    ip, [r7, #2]
>
> Well, ip is being loaded/stored as 16bit, but you're putting r6 in to
> ip's bits 31-24, which are going to be ignored by the following strh.
>
> The comment "@ mask in offset bits 31-24" refers to the physical address
> bits here, which are already pre-shifted to bits 7-0 in r6.

I looked into this, and the code before this loop does:

	clz	r7, r6
	lsr	r6, #24
	lsl	r6, r7
	bic	r6, #0x0080
	lsrs	r7, #1
	orrcs	r6, #0x0080
	orr	r6, r6, r7, lsl #12
	orr	r6, #0x4000
	b	2f

Note that r6 has bits that are not in the 0..7 range, which makes life
difficult when dealing with the loop. If we are going to change the
loop then we will have to pre rev16 r6 before going in to it.

IE:

	lsls	r6, #24
	beq	2f
	clz	r7, r6
	lsr	r6, #24
	lsl	r6, r7
	bic	r6, #0x0080
	lsrs	r7, #1
	orrcs	r6, #0x0080
	orr	r6, r6, r7, lsl #12
	orr	r6, #0x4000
  ARM_BE8(rev16	r6, r6)
	b	2f
1:	add     r7, r3
	ldrh	ip, [r7, #2]
#ifdef CONFIG_CPU_ENDIAN_BE8
	and	ip, 0x008f
#else
	and	ip, 0x8f00
#endif
	orr	ip, r6	@ mask in offset bits 31-24
	strh	ip, [r7, #2]
2:	cmp	r4, r5
	ldrcc	r7, [r4], #4	@ use branch for delay slot
	bcc	1b
	bx	lr




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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH 03/14] ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
  2013-07-25 10:25         ` Russell King - ARM Linux
  2013-07-25 10:34           ` Ben Dooks
@ 2013-07-25 10:40           ` Will Deacon
  1 sibling, 0 replies; 46+ messages in thread
From: Will Deacon @ 2013-07-25 10:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jul 25, 2013 at 11:25:41AM +0100, Russell King - ARM Linux wrote:
> On Thu, Jul 25, 2013 at 11:14:42AM +0100, Will Deacon wrote:
> > What's wrong with the following?
> 
> Is this like a challenge to find the silly mistake?

Unfortunately, yes. I'm half asleep this morning...

> > @@ -581,8 +581,13 @@ __fixup_a_pv_table:
> >         b       2f
> >  1:     add     r7, r3
> >         ldrh    ip, [r7, #2]
> > +#ifdef CONFIG_CPU_ENDIAN_BE8
> > +       and     ip, 0x008f
> > +       orr     ip, ip, r6, lsl #24

That was supposed to be lsl #8 (I blindly copied from Ben's correct ARM
hunk), but I think that it's still broken with that change.

> > +#else
> >         and     ip, 0x8f00
> >         orr     ip, r6  @ mask in offset bits 31-24
> > +#endif
> >         strh    ip, [r7, #2]
> 
> Well, ip is being loaded/stored as 16bit, but you're putting r6 in to
> ip's bits 31-24, which are going to be ignored by the following strh.
> 
> The comment "@ mask in offset bits 31-24" refers to the physical address
> bits here, which are already pre-shifted to bits 7-0 in r6.

Yup. It's bits 15-8 that make life slightly fiddly.

Will

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [repost] ARM big-endian support
  2013-07-24 16:05 ` [repost] ARM big-endian support Ben Dooks
@ 2013-07-29 13:26   ` Thomas Petazzoni
  2013-07-31 20:05     ` Ben Dooks
  0 siblings, 1 reply; 46+ messages in thread
From: Thomas Petazzoni @ 2013-07-29 13:26 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Ben Dooks,

On Wed, 24 Jul 2013 17:05:39 +0100, Ben Dooks wrote:
> On 24/07/13 11:27, Ben Dooks wrote:
> > A repost (as requested) of the current big-endian core work for review.
> 
> New branches at git.baserock.org/delta/linux.git
> 	311/be/atags-v4
>   	311/be/core-v4

Thanks. Can you post a patch set based on top of 3.11-rc, so that it
can hopefully be merged? Posting something based on 3.10 has no chance
of being merged. Again, if you need any help on this, do not hesitate
to ask.

Also, would it be possible to get cover letters that include a proper
changelog, as well as version number for each posting of the patch
series?

Thanks a lot!

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [repost] ARM big-endian support
  2013-07-29 13:26   ` Thomas Petazzoni
@ 2013-07-31 20:05     ` Ben Dooks
  2013-08-01  6:21       ` Thomas Petazzoni
  0 siblings, 1 reply; 46+ messages in thread
From: Ben Dooks @ 2013-07-31 20:05 UTC (permalink / raw)
  To: linux-arm-kernel

On 29/07/13 14:26, Thomas Petazzoni wrote:
> Dear Ben Dooks,
>
> On Wed, 24 Jul 2013 17:05:39 +0100, Ben Dooks wrote:
>> On 24/07/13 11:27, Ben Dooks wrote:
>>> A repost (as requested) of the current big-endian core work for review.
>>
>> New branches at git.baserock.org/delta/linux.git
>> 	311/be/atags-v4
>>    	311/be/core-v4
>
> Thanks. Can you post a patch set based on top of 3.11-rc, so that it
> can hopefully be merged? Posting something based on 3.10 has no chance
> of being merged. Again, if you need any help on this, do not hesitate
> to ask.
>
> Also, would it be possible to get cover letters that include a proper
> changelog, as well as version number for each posting of the patch
> series?

I've lost quite a bit of the change information, so sorry about that.

The 3.11-rc series I will try and get done as soon as I've gone through
and sorted out the last round of review comments. Unfortunately I am
not in the office for the next three weeks.


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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [repost] ARM big-endian support
  2013-07-31 20:05     ` Ben Dooks
@ 2013-08-01  6:21       ` Thomas Petazzoni
  2013-08-03 16:49         ` Ben Dooks
  0 siblings, 1 reply; 46+ messages in thread
From: Thomas Petazzoni @ 2013-08-01  6:21 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Ben Dooks,

On Wed, 31 Jul 2013 21:05:16 +0100, Ben Dooks wrote:

> > Also, would it be possible to get cover letters that include a proper
> > changelog, as well as version number for each posting of the patch
> > series?
> 
> I've lost quite a bit of the change information, so sorry about that.

Ok. I guess for the next version, it'd be great to have the list of
changes compared to the current one.

> The 3.11-rc series I will try and get done as soon as I've gone through
> and sorted out the last round of review comments. Unfortunately I am
> not in the office for the next three weeks.

Is there anything I can do to help? I'd really like to see this in
3.12, and I think your patch set is pretty close.

Thanks,

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [repost] ARM big-endian support
  2013-08-01  6:21       ` Thomas Petazzoni
@ 2013-08-03 16:49         ` Ben Dooks
  2013-08-05  8:01           ` Thomas Petazzoni
  0 siblings, 1 reply; 46+ messages in thread
From: Ben Dooks @ 2013-08-03 16:49 UTC (permalink / raw)
  To: linux-arm-kernel

On 01/08/13 07:21, Thomas Petazzoni wrote:
> Dear Ben Dooks,
>
> On Wed, 31 Jul 2013 21:05:16 +0100, Ben Dooks wrote:
>
>>> Also, would it be possible to get cover letters that include a proper
>>> changelog, as well as version number for each posting of the patch
>>> series?
>>
>> I've lost quite a bit of the change information, so sorry about that.
>
> Ok. I guess for the next version, it'd be great to have the list of
> changes compared to the current one.
>
>> The 3.11-rc series I will try and get done as soon as I've gone through
>> and sorted out the last round of review comments. Unfortunately I am
>> not in the office for the next three weeks.
>
> Is there anything I can do to help? I'd really like to see this in
> 3.12, and I think your patch set is pretty close.

At the moment testing is the important bit as I will not be back in my
office until late August now.

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

^ permalink raw reply	[flat|nested] 46+ messages in thread

* [repost] ARM big-endian support
  2013-08-03 16:49         ` Ben Dooks
@ 2013-08-05  8:01           ` Thomas Petazzoni
  0 siblings, 0 replies; 46+ messages in thread
From: Thomas Petazzoni @ 2013-08-05  8:01 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Ben Dooks,

On Sat, 03 Aug 2013 17:49:36 +0100, Ben Dooks wrote:

> > Ok. I guess for the next version, it'd be great to have the list of
> > changes compared to the current one.
> >
> >> The 3.11-rc series I will try and get done as soon as I've gone through
> >> and sorted out the last round of review comments. Unfortunately I am
> >> not in the office for the next three weeks.
> >
> > Is there anything I can do to help? I'd really like to see this in
> > 3.12, and I think your patch set is pretty close.
> 
> At the moment testing is the important bit as I will not be back in my
> office until late August now.

In this case, do you mind if I pick up your patches and send updated
series of them to address comments and feedback? Of course, if they
don't get merged by the end of August, you can take back the lead when
you get back to your office. What do you think?

Thanks!

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2013-08-05  8:01 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-24 10:27 [repost] ARM big-endian support Ben Dooks
2013-07-24 10:27 ` [PATCH 01/14] ARM: fix ARCH_IXP4xx usage of ARCH_SUPPORTS_BIG_ENDIAN Ben Dooks
2013-07-24 10:27 ` [PATCH 02/14] ARM: asm: Add ARM_BE8() assembly helper Ben Dooks
2013-07-24 14:28   ` Will Deacon
2013-07-24 14:38     ` Ben Dooks
2013-07-24 14:48     ` Ben Dooks
2013-07-24 10:27 ` [PATCH 03/14] ARM: fixup_pv_table bug when CPU_ENDIAN_BE8 Ben Dooks
2013-07-24 14:33   ` Will Deacon
2013-07-24 15:24     ` Ben Dooks
2013-07-25 10:14       ` Will Deacon
2013-07-25 10:21         ` Ben Dooks
2013-07-25 10:30           ` Will Deacon
2013-07-25 10:25         ` Russell King - ARM Linux
2013-07-25 10:34           ` Ben Dooks
2013-07-25 10:40           ` Will Deacon
2013-07-24 10:27 ` [PATCH 04/14] ARM: set BE8 if LE in head code Ben Dooks
2013-07-24 14:41   ` Will Deacon
2013-07-24 15:55     ` Ben Dooks
2013-07-24 10:27 ` [PATCH 05/14] ARM: pl01x debug code endian fix Ben Dooks
2013-07-24 14:44   ` Will Deacon
2013-07-24 10:27 ` [PATCH 06/14] ARM: twd: data " Ben Dooks
2013-07-24 14:49   ` Will Deacon
2013-07-24 15:00     ` Ben Dooks
2013-07-24 15:06     ` Ben Dooks
2013-07-24 16:29       ` Will Deacon
2013-07-24 10:27 ` [PATCH 07/14] ARM: smp_scu: data endian fixes Ben Dooks
2013-07-24 15:05   ` Will Deacon
2013-07-24 10:27 ` [PATCH 08/14] highbank: enable big-endian Ben Dooks
2013-07-24 10:27 ` [PATCH 09/14] mvebu: support running big-endian Ben Dooks
2013-07-24 10:27 ` [PATCH 10/14] vexpress: add big endian support Ben Dooks
2013-07-24 10:27 ` [PATCH 11/14] ARM: alignment: correctly decode instructions in BE8 mode Ben Dooks
2013-07-24 15:28   ` Will Deacon
2013-07-25  9:44   ` Will Deacon
2013-07-24 10:28 ` [PATCH 12/14] ARM: traps: use <asm/opcodes.h> to get correct instruction order Ben Dooks
2013-07-24 16:20   ` Will Deacon
2013-07-24 10:28 ` [PATCH 13/14] ARM: module: correctly relocate instructions in BE8 Ben Dooks
2013-07-25  9:54   ` Will Deacon
2013-07-24 10:28 ` [PATCH 14/14] ARM: set --be8 when linking modules Ben Dooks
2013-07-24 16:25   ` Will Deacon
2013-07-24 23:41   ` Nicolas Pitre
2013-07-24 16:05 ` [repost] ARM big-endian support Ben Dooks
2013-07-29 13:26   ` Thomas Petazzoni
2013-07-31 20:05     ` Ben Dooks
2013-08-01  6:21       ` Thomas Petazzoni
2013-08-03 16:49         ` Ben Dooks
2013-08-05  8:01           ` Thomas Petazzoni

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.