Skip to contentSkip to conversation

3.11-rc7 big-endian support

PATCH New Ben Dooks 6 participants 62 messages Aug 27, 2013 – Aug 30, 2013

Subsystems (9)
lore
Share & tools
lore

Ben Dooks

author
#0 lore raw

This is a new series of the core work for getting big-endian working nicely on ARM. This is mainly a rebase on 3.11-rc7 and has not had a lot of testing on it.

It is available on:

	git://git.baserock.org/delta/linux.git baserock/311-rc7/be/core-v1

Since the previous version:

- Added Victor's atomic64 patch
- Fixed BUG() patch to use <asm/opcodes.h>

I would like to get as much of this merged as possible, so would it be possible

author
#1 lore raw

PATCH 1/19 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 43594d5..0628529 100644
@@ -480,6 +480,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 30e1ebe..c342dc4 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 cd2c88e..1f8fed9 100644
@@ -952,3 +952,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
author
#2 lore raw

PATCH 2/19 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 75189f1..c912c2a 100644
@@ -699,9 +699,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
@@ -728,9 +726,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 a5fef71..5350f83 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 9cbe70c..55090fb 100644
@@ -416,9 +416,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 94104bf..cc318cd 100644
@@ -393,9 +393,7 @@ ENTRY(vector_swi)
 #else
  USER(	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 1128064..45dc29f 100644
@@ -220,9 +220,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 73398bc..03978e3 100644
@@ -355,9 +355,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
#3 lore raw

PATCH 3/19 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 (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.

---
 arch/arm/kernel/head.S |    8 ++++++++
 1 file changed, 8 insertions(+)
arch/arm/kernel/head.S +8 -0
index 2c7cc1e..9e5906c 100644
@@ -582,8 +582,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
@@ -592,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
#4 lore raw

PATCH 3/19 ARM: fixup_pv_table bug when CPU_ENDIAN_BE8

Quoted 8 lines · 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.

Quoted 7 lines

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.

Shame about the ifdef, but ARM_LE_OR_BE32(...) or ARM_NOT_BE8(...) seems too contrived to be practical...

We could probably do bitfield clobber more neatly with BFI, but unfortunately v6 plain doesn't have that. Only v6T2 or v7 and later have it.

Cheers
---Dave

Quoted 44 lines
---
 arch/arm/kernel/head.S |    8 ++++++++
 1 file changed, 8 insertions(+)
arch/arm/kernel/head.S +8 -0
index 2c7cc1e..9e5906c 100644
@@ -582,8 +582,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
@@ -592,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 · 7 lines
1.7.10.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
author
#5 lore raw

PATCH 4/19 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.

Conflicts:
arch/arm/kernel/sleep.S

---
 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 c912c2a..066b034 100644
@@ -135,6 +135,7 @@ start:
 		.word	_edata			@ zImage end address
  THUMB(		.thumb			)
 1:
+ ARM_BE8(	setend	be )			@ go BE8 if compiled for 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 9e5906c..a047acf 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,
@@ -352,6 +353,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)				@ ensure we are in BE8 mode
+
 #ifdef CONFIG_ARM_VIRT_EXT
 	bl	__hyp_stub_install_secondary
 #endif
arch/arm/kernel/sleep.S +1 -0
index db1536b..716343c 100644
@@ -130,6 +130,7 @@ ENDPROC(cpu_resume_after_mmu)
 	.data
 	.align
 ENTRY(cpu_resume)
+ARM_BE8(setend be)			@ ensure we are in BE mode
 	mov	r1, #0
 	ALT_SMP(mrc p15, 0, r0, c0, c0, 5)
 	ALT_UP_B(1f)
Signature · 1 line
1.7.10.4
#6 lore raw

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

Dear Ben Dooks,

Quoted 6 lines · 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.

Quoted 7 lines

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

Conflicts:
arch/arm/kernel/sleep.S

Those two lines probably shouldn't be there.

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
#7 lore raw

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

In reply to Ben Dooks
Quoted 10 lines · 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.

(Lose the merge conflicts lines, though)

Quoted 63 lines

Conflicts:
arch/arm/kernel/sleep.S

---
 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 c912c2a..066b034 100644
@@ -135,6 +135,7 @@ start:
 		.word	_edata			@ zImage end address
  THUMB(		.thumb			)
 1:
+ ARM_BE8(	setend	be )			@ go BE8 if compiled for 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 9e5906c..a047acf 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,
@@ -352,6 +353,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)				@ ensure we are in BE8 mode
+
 #ifdef CONFIG_ARM_VIRT_EXT
 	bl	__hyp_stub_install_secondary
 #endif
arch/arm/kernel/sleep.S +1 -0
index db1536b..716343c 100644
@@ -130,6 +130,7 @@ ENDPROC(cpu_resume_after_mmu)
 	.data
 	.align
 ENTRY(cpu_resume)
+ARM_BE8(setend be)			@ ensure we are in BE mode
 	mov	r1, #0
 	ALT_SMP(mrc p15, 0, r0, c0, c0, 5)
 	ALT_UP_B(1f)
Signature · 7 lines
1.7.10.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
author
#8 lore raw

PATCH 5/19 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
#9 lore raw

PATCH 5/19 ARM: pl01x debug code endian fix

Quoted 6 lines · 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.

Hmm, opcodes.h already has the asm-compatible byteswappers, but the interface it provides is not correct to allow them to be used cleanly for data swabbing.

Maybe that would be worth factoring out sometime, but this patch should work as-is.

Cheers
---Dave

Quoted 34 lines
---
 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 · 7 lines
1.7.10.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
author
#10 lore raw

PATCH 6/19 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 2595620..0804013 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 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 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 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
#11 lore raw

PATCH 7/19 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 |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
arch/arm/kernel/smp_scu.c +7 -7
index 5bc1a63..1aafa0d 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;
 }
 
@@ -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;
 }
Signature · 1 line
1.7.10.4
author
#12 lore raw

PATCH 8/19 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
#13 lore raw

PATCH 8/19 highbank: enable big-endian

Quoted 13 lines · 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 +0 -0
index cd9fcb1..4f57554 100644

arch/arm/mach-highbank/Kconfig config ARCH_HIGHBANK · line 21

Quoted 4 lines
arch/arm/mach-highbank/Kconfig +1 -0
@@ -18,3 +18,4 @@ config ARCH_HIGHBANK
        select PL320_MBOX
        select SPARSE_IRQ
        select USE_OF
+       select ARCH_SUPPORTS_BIG_ENDIAN

The select entries should be sorted.

Rob

author
#14 lore raw

PATCH 8/19 highbank: enable big-endian

Quoted 21 lines · Rob Herring
Quoted 13 lines · 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 +0 -0
index cd9fcb1..4f57554 100644

arch/arm/mach-highbank/Kconfig config ARCH_HIGHBANK · line 21

Quoted 4 lines
arch/arm/mach-highbank/Kconfig +1 -0
@@ -18,3 +18,4 @@ config ARCH_HIGHBANK
         select PL320_MBOX
         select SPARSE_IRQ
         select USE_OF
+       select ARCH_SUPPORTS_BIG_ENDIAN

The select entries should be sorted.

Quoted 1 line

Rob

Ok, will sort this out.

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

PATCH 9/19 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 9eb63d7..5e269d7 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 8a1b0c9..3109df0 100644
@@ -21,6 +21,8 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
+#include <asm/assembler.h>
+
 /*
  * Armada XP specific entry point for secondary CPUs.
  * We add the CPU to the coherency fabric and then jump to secondary
@@ -32,6 +34,8 @@ ENTRY(armada_xp_secondary_startup)
 	ldr	r1, [r0]
 	ldr	r0, [r0, r1]
 
+ 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
#16 lore raw

PATCH 10/19 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 b8bbabe..d9dc5d2a 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 2677bc3..40f27e5 100644
@@ -10,6 +10,7 @@
  */
 #include <linux/linkage.h>
 #include <linux/init.h>
+#include <asm/assembler.h>
 
 /*
  * Realview/Versatile Express specific entry point for secondary CPUs.
@@ -17,6 +18,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
author
#17 lore raw

PATCH 11/19 ARM: alignment: correctly decode instructions in BE8 mode.

In reply to Ben Dooks

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

---
 arch/arm/mm/alignment.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
arch/arm/mm/alignment.c +7 -2
index 6f4585b..9240364 100644
@@ -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,25 @@ 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);
-				instr = (tinstr << 16) | tinst2;
+				tinst2 = __mem_to_opcode_thumb16(tinst2);
+				instr = __opcode_thumb32_compose(tinstr, 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;
Signature · 1 line
1.7.10.4
#18 lore raw

PATCH 11/19 ARM: alignment: correctly decode instructions in BE8 mode.

Quoted 9 lines · Ben Dooks

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

Quoted 54 lines
---
 arch/arm/mm/alignment.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
arch/arm/mm/alignment.c +7 -2
index 6f4585b..9240364 100644
@@ -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,25 @@ 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);
-				instr = (tinstr << 16) | tinst2;
+				tinst2 = __mem_to_opcode_thumb16(tinst2);
+				instr = __opcode_thumb32_compose(tinstr, 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;
Signature · 7 lines
1.7.10.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
author
#19 lore raw

PATCH 12/19 ARM: traps: use <asm/opcodes.h> to get correct instruction order

In reply to Ben Dooks

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.

---
 arch/arm/kernel/traps.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
arch/arm/kernel/traps.c +10 -6
index ab517fc..99bcd0e3 100644
@@ -34,6 +34,7 @@
 #include <asm/unwind.h>
 #include <asm/tls.h>
 #include <asm/system_misc.h>
+#include <asm/opcodes.h>
 
 static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
 
@@ -402,25 +403,28 @@ 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];
+				u16 inst2;
+				instr2 = __mem_to_opcode_thumb16(((u16 *)pc)[1]);
+				instr = __opcode_thumb32_compose(instr, instr2);
 			}
 		} 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;
+			instr2 = __mem_to_opcode_thumb16(instr2);
+			instr = __opcode_thumb32_compose(instr, instr2);
 		}
 	} else if (get_user(instr, (u32 __user *)pc)) {
+		instr = __mem_to_opcode_arm(instr);
 		goto die_sig;
 	}
 
Signature · 1 line
1.7.10.4
#20 lore raw

PATCH 12/19 ARM: traps: use <asm/opcodes.h> to get correct instruction order

Quoted 22 lines · Ben Dooks

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.

---
 arch/arm/kernel/traps.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
arch/arm/kernel/traps.c +1 -0
index ab517fc..99bcd0e3 100644
@@ -34,6 +34,7 @@
 #include <asm/unwind.h>
 #include <asm/tls.h>
 #include <asm/system_misc.h>
+#include <asm/opcodes.h>
 
 static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
 

arch/arm/kernel/traps.c asmlinkage void __exception do_undefinstr(struct pt_regs *regs) · line 409

Quoted 10 lines
arch/arm/kernel/traps.c +3 -3
@@ -402,25 +403,28 @@ 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];
+				u16 inst2;
+				instr2 = __mem_to_opcode_thumb16(((u16 *)pc)[1]);

Typo?

inst2 versus instr2.

Cheers
---Dave

Quoted 32 lines
arch/arm/kernel/traps.c +6 -3
+				instr = __opcode_thumb32_compose(instr, instr2);
 			}
 		} 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;
+			instr2 = __mem_to_opcode_thumb16(instr2);
+			instr = __opcode_thumb32_compose(instr, instr2);
 		}
 	} else if (get_user(instr, (u32 __user *)pc)) {
+		instr = __mem_to_opcode_arm(instr);
 		goto die_sig;
 	}
 
Signature · 7 lines
1.7.10.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
author
#21 lore raw

PATCH 13/19 ARM: module: correctly relocate instructions in BE8

In reply to Ben Dooks

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

---
 arch/arm/kernel/module.c |   57 +++++++++++++++++++++++++++-------------------
 1 file changed, 34 insertions(+), 23 deletions(-)
arch/arm/kernel/module.c +34 -23
index 85c3fb6..a1045a7 100644
@@ -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
 
Signature · 1 line
1.7.10.4
#22 lore raw

PATCH 13/19 ARM: module: correctly relocate instructions in BE8

Quoted 6 lines · Ben Dooks

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

Quoted 147 lines
---
 arch/arm/kernel/module.c |   57 +++++++++++++++++++++++++++-------------------
 1 file changed, 34 insertions(+), 23 deletions(-)
arch/arm/kernel/module.c +34 -23
index 85c3fb6..a1045a7 100644
@@ -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
 
Signature · 7 lines
1.7.10.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
author
#23 lore raw

PATCH 14/19 ARM: set --be8 when linking modules

In reply to Ben Dooks

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.

---
 arch/arm/Makefile |    1 +
 1 file changed, 1 insertion(+)
arch/arm/Makefile +1 -0
index 6fd2cea..2c659f9 100644
@@ -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
Signature · 1 line
1.7.10.4
#24 lore raw

PATCH 14/19 ARM: set --be8 when linking modules

Quoted 7 lines · Ben Dooks

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.

Someone on one of the previous threads asked about whether we need module vermagic for BE8.

I'm a bit hazy on whether this is needed. The interesting scenario would be if someone tried to load a BE32 module into a BE8 kernel or vice versa.

Currently the kernel does not seem to check ELF endianness at all either for modules or userspace binaries -- they load get loaded/ fixed up/executed just is if they were native endianness.

So BE8 doesn't add any new brokenness here. Fixing all that stuff falls outside the scope of this series.

Any thoughts?

For this patch though:

Cheers
---Dave

Quoted 25 lines
---
 arch/arm/Makefile |    1 +
 1 file changed, 1 insertion(+)
arch/arm/Makefile +1 -0
index 6fd2cea..2c659f9 100644
@@ -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
Signature · 7 lines
1.7.10.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
author
#25 lore raw

PATCH 14/19 ARM: set --be8 when linking modules

Quoted 11 lines · Dave Martin
Quoted 7 lines · Ben Dooks

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.

Someone on one of the previous threads asked about whether we need module vermagic for BE8.

Don't think so, although we could do this if needed. I would like to get this series merged and then think about updates.

Quoted 7 lines

I'm a bit hazy on whether this is needed. The interesting scenario would be if someone tried to load a BE32 module into a BE8 kernel or vice versa.

Currently the kernel does not seem to check ELF endianness at all either for modules or userspace binaries -- they load get loaded/ fixed up/executed just is if they were native endianness.

I've not tried BE32 binaries on BE8 kernels, although it would probably produce an undefined instruction quite quickly.

Quoted 2 lines

So BE8 doesn't add any new brokenness here. Fixing all that stuff falls outside the scope of this series.

think so.

Quoted 35 lines

Any thoughts?

For this patch though:

Cheers
---Dave

Quoted 25 lines
---
  arch/arm/Makefile |    1 +
  1 file changed, 1 insertion(+)
arch/arm/Makefile +1 -1
index 6fd2cea..2c659f9 100644
@@ -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

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

PATCH 15/19 ARM: hardware: fix endian-ness in <hardware/coresight.h>

In reply to Ben Dooks

The <hardware/coresight.h> needs to take into account the endian-ness of the processor when reading and writing data, so change to using the readl/writel relaxed variants from the raw ones.

---
 arch/arm/include/asm/hardware/coresight.h |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm/include/asm/hardware/coresight.h +4 -4
index 0cf7a6b..ad774f3 100644
@@ -24,8 +24,8 @@
 #define TRACER_TIMEOUT 10000
 
 #define etm_writel(t, v, x) \
-	(__raw_writel((v), (t)->etm_regs + (x)))
-#define etm_readl(t, x) (__raw_readl((t)->etm_regs + (x)))
+	(writel_relaxed((v), (t)->etm_regs + (x)))
+#define etm_readl(t, x) (readl_relaxed((t)->etm_regs + (x)))
 
 /* CoreSight Management Registers */
 #define CSMR_LOCKACCESS 0xfb0
@@ -142,8 +142,8 @@
 #define ETBFF_TRIGFL		BIT(10)
 
 #define etb_writel(t, v, x) \
-	(__raw_writel((v), (t)->etb_regs + (x)))
-#define etb_readl(t, x) (__raw_readl((t)->etb_regs + (x)))
+	(writel_relaxed((v), (t)->etb_regs + (x)))
+#define etb_readl(t, x) (readl_relaxed((t)->etb_regs + (x)))
 
 #define etm_lock(t) do { etm_writel((t), 0, CSMR_LOCKACCESS); } while (0)
 #define etm_unlock(t) \
Signature · 1 line
1.7.10.4
author
#27 lore raw

PATCH 16/19 ARM: net: fix arm instruction endian-ness in bpf_jit_32.c

In reply to Ben Dooks

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

---
 arch/arm/net/bpf_jit_32.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm/net/bpf_jit_32.c +5 -1
index f50d223..510d923 100644
@@ -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++;
 }
Signature · 1 line
1.7.10.4
#28 lore raw

PATCH 16/19 ARM: net: fix arm instruction endian-ness in bpf_jit_32.c

Quoted 2 lines · Ben Dooks

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

Quoted 39 lines
---
 arch/arm/net/bpf_jit_32.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm/net/bpf_jit_32.c +5 -1
index f50d223..510d923 100644
@@ -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++;
 }
Signature · 7 lines
1.7.10.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
author
#29 lore raw

PATCH 17/19 ARM: Correct BUG() assembly to ensure it is endian-agnostic

In reply to Ben Dooks

Currently BUG() uses .word or .hword to create the necessary illegal instructions. However if we are building BE8 then these get swapped by the linker into different illegal instructions in the text. This means that the BUG() macro does not get trapped properly.

Change to using <asm/opcodes.h> to provide the necessary ARM instruction building as we cannot rely on gcc/gas having the .inst instructions which where added to try and resolve this issue (reported by Dave Martin <[email protected]>).

---
 arch/arm/include/asm/bug.h |   10 ++++++----
 arch/arm/kernel/traps.c    |    8 +++++---
 2 files changed, 11 insertions(+), 7 deletions(-)
arch/arm/include/asm/bug.h +6 -4
index 7af5c6c..b274bde 100644
@@ -2,6 +2,8 @@
 #define _ASMARM_BUG_H
 
 #include <linux/linkage.h>
+#include <linux/types.h>
+#include <asm/opcodes.h>
 
 #ifdef CONFIG_BUG
 
@@ -12,10 +14,10 @@
  */
 #ifdef CONFIG_THUMB2_KERNEL
 #define BUG_INSTR_VALUE 0xde02
-#define BUG_INSTR_TYPE ".hword "
+#define BUG_INSTR(__value) __inst_thumb16(__value)
 #else
 #define BUG_INSTR_VALUE 0xe7f001f2
-#define BUG_INSTR_TYPE ".word "
+#define BUG_INSTR(__value) __inst_arm(__value)
 #endif
 
 
@@ -33,7 +35,7 @@
 
 #define __BUG(__file, __line, __value)				\
 do {								\
-	asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n"	\
+	asm volatile("1:\t" BUG_INSTR(__value) "\n"  \
 		".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
 		"2:\t.asciz " #__file "\n" 			\
 		".popsection\n" 				\
@@ -48,7 +50,7 @@ do {								\
 
 #define __BUG(__file, __line, __value)				\
 do {								\
-	asm volatile(BUG_INSTR_TYPE #__value);			\
+	asm volatile(BUG_INSTR(__value) "\n");			\
 	unreachable();						\
 } while (0)
 #endif  /* CONFIG_DEBUG_BUGVERBOSE */
arch/arm/kernel/traps.c +5 -3
index 99bcd0e3..da070db 100644
@@ -342,15 +342,17 @@ void arm_notify_die(const char *str, struct pt_regs *regs,
 int is_valid_bugaddr(unsigned long pc)
 {
 #ifdef CONFIG_THUMB2_KERNEL
-	unsigned short bkpt;
+	u16 bkpt;
+	u16 insn = __opcode_to_mem_thumb16(BUG_INSTR_VALUE);
 #else
-	unsigned long bkpt;
+	u32 bkpt;
+	u32 insn = __opcode_to_mem_arm(BUG_INSTR_VALUE);
 #endif
 
 	if (probe_kernel_address((unsigned *)pc, bkpt))
 		return 0;
 
-	return bkpt == BUG_INSTR_VALUE;
+	return bkpt == insn;
 }
 
 #endif
Signature · 1 line
1.7.10.4
#30 lore raw

PATCH 17/19 ARM: Correct BUG() assembly to ensure it is endian-agnostic

Quoted 9 lines · Ben Dooks

Currently BUG() uses .word or .hword to create the necessary illegal instructions. However if we are building BE8 then these get swapped by the linker into different illegal instructions in the text. This means that the BUG() macro does not get trapped properly.

Change to using <asm/opcodes.h> to provide the necessary ARM instruction building as we cannot rely on gcc/gas having the .inst instructions which where added to try and resolve this issue (reported by Dave Martin <[email protected]>).

Quoted 84 lines
---
 arch/arm/include/asm/bug.h |   10 ++++++----
 arch/arm/kernel/traps.c    |    8 +++++---
 2 files changed, 11 insertions(+), 7 deletions(-)
arch/arm/include/asm/bug.h +6 -4
index 7af5c6c..b274bde 100644
@@ -2,6 +2,8 @@
 #define _ASMARM_BUG_H
 
 #include <linux/linkage.h>
+#include <linux/types.h>
+#include <asm/opcodes.h>
 
 #ifdef CONFIG_BUG
 
@@ -12,10 +14,10 @@
  */
 #ifdef CONFIG_THUMB2_KERNEL
 #define BUG_INSTR_VALUE 0xde02
-#define BUG_INSTR_TYPE ".hword "
+#define BUG_INSTR(__value) __inst_thumb16(__value)
 #else
 #define BUG_INSTR_VALUE 0xe7f001f2
-#define BUG_INSTR_TYPE ".word "
+#define BUG_INSTR(__value) __inst_arm(__value)
 #endif
 
 
@@ -33,7 +35,7 @@
 
 #define __BUG(__file, __line, __value)				\
 do {								\
-	asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n"	\
+	asm volatile("1:\t" BUG_INSTR(__value) "\n"  \
 		".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
 		"2:\t.asciz " #__file "\n" 			\
 		".popsection\n" 				\
@@ -48,7 +50,7 @@ do {								\
 
 #define __BUG(__file, __line, __value)				\
 do {								\
-	asm volatile(BUG_INSTR_TYPE #__value);			\
+	asm volatile(BUG_INSTR(__value) "\n");			\
 	unreachable();						\
 } while (0)
 #endif  /* CONFIG_DEBUG_BUGVERBOSE */
arch/arm/kernel/traps.c +5 -3
index 99bcd0e3..da070db 100644
@@ -342,15 +342,17 @@ void arm_notify_die(const char *str, struct pt_regs *regs,
 int is_valid_bugaddr(unsigned long pc)
 {
 #ifdef CONFIG_THUMB2_KERNEL
-	unsigned short bkpt;
+	u16 bkpt;
+	u16 insn = __opcode_to_mem_thumb16(BUG_INSTR_VALUE);
 #else
-	unsigned long bkpt;
+	u32 bkpt;
+	u32 insn = __opcode_to_mem_arm(BUG_INSTR_VALUE);
 #endif
 
 	if (probe_kernel_address((unsigned *)pc, bkpt))
 		return 0;
 
-	return bkpt == BUG_INSTR_VALUE;
+	return bkpt == insn;
 }
 
 #endif
Signature · 7 lines
1.7.10.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
author
#31 lore raw

PATCH 18/19 ARM: kdgb: use <asm/opcodes.h> for data to be assembled as intruction

In reply to Ben Dooks

The arch_kgdb_breakpoint() function uses an inline assembly directive to assemble a specific instruction using .word. This means the linker will not treat is as an instruction, and therefore incorrectly swap the endian-ness if running BE8.

---
 arch/arm/include/asm/kgdb.h |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/include/asm/kgdb.h +2 -1
index 48066ce..0a9d5dd 100644
@@ -11,6 +11,7 @@
 #define __ARM_KGDB_H__
 
 #include <linux/ptrace.h>
+#include <asm/opcodes.h>
 
 /*
  * GDB assumes that we're a user process being debugged, so
@@ -41,7 +42,7 @@
 
 static inline void arch_kgdb_breakpoint(void)
 {
-	asm(".word 0xe7ffdeff");
+	asm(__inst_arm(0xe7ffdeff));
 }
 
 extern void kgdb_handle_bus_error(void);
Signature · 1 line
1.7.10.4
#32 lore raw

PATCH 18/19 ARM: kdgb: use <asm/opcodes.h> for data to be assembled as intruction

Quoted 4 lines · Ben Dooks

The arch_kgdb_breakpoint() function uses an inline assembly directive to assemble a specific instruction using .word. This means the linker will not treat is as an instruction, and therefore incorrectly swap the endian-ness if running BE8.

I wonder whether KGDB works with Thumb-2 kernels... but this patch shouldn't make things any worse, anyway.

Cheers
---Dave

Quoted 35 lines
---
 arch/arm/include/asm/kgdb.h |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/include/asm/kgdb.h +2 -1
index 48066ce..0a9d5dd 100644
@@ -11,6 +11,7 @@
 #define __ARM_KGDB_H__
 
 #include <linux/ptrace.h>
+#include <asm/opcodes.h>
 
 /*
  * GDB assumes that we're a user process being debugged, so
@@ -41,7 +42,7 @@
 
 static inline void arch_kgdb_breakpoint(void)
 {
-	asm(".word 0xe7ffdeff");
+	asm(__inst_arm(0xe7ffdeff));
 }
 
 extern void kgdb_handle_bus_error(void);
Signature · 7 lines
1.7.10.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
author
#33 lore raw

PATCH 19/19 ARM: atomic64: fix endian-ness in atomic.h

In reply to Ben Dooks

From: Victor Kamensky <[email protected]>

Fix inline asm for atomic64_xxx functions in arm atomic.h. Instead of %H operand specifiers code should use %Q for least significant part of the value, and %R for the most significant part of the value. %H always returns the higher of the two register numbers, and therefore it is not endian neutral. %H should be used with ldrexd and strexd instructions.

---
 arch/arm/include/asm/atomic.h |   26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)
arch/arm/include/asm/atomic.h +13 -13
index da1c77d..6447a0b 100644
@@ -301,8 +301,8 @@ static inline void atomic64_add(u64 i, atomic64_t *v)
 
 	__asm__ __volatile__("@ atomic64_add\n"
 "1:	ldrexd	%0, %H0, [%3]\n"
-"	adds	%0, %0, %4\n"
-"	adc	%H0, %H0, %H4\n"
+"	adds	%Q0, %Q0, %Q4\n"
+"	adc	%R0, %R0, %R4\n"
 "	strexd	%1, %0, %H0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
@@ -320,8 +320,8 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
 
 	__asm__ __volatile__("@ atomic64_add_return\n"
 "1:	ldrexd	%0, %H0, [%3]\n"
-"	adds	%0, %0, %4\n"
-"	adc	%H0, %H0, %H4\n"
+"	adds	%Q0, %Q0, %Q4\n"
+"	adc	%R0, %R0, %R4\n"
 "	strexd	%1, %0, %H0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
@@ -341,8 +341,8 @@ static inline void atomic64_sub(u64 i, atomic64_t *v)
 
 	__asm__ __volatile__("@ atomic64_sub\n"
 "1:	ldrexd	%0, %H0, [%3]\n"
-"	subs	%0, %0, %4\n"
-"	sbc	%H0, %H0, %H4\n"
+"	subs	%Q0, %Q0, %Q4\n"
+"	sbc	%R0, %R0, %R4\n"
 "	strexd	%1, %0, %H0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
@@ -360,8 +360,8 @@ static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
 
 	__asm__ __volatile__("@ atomic64_sub_return\n"
 "1:	ldrexd	%0, %H0, [%3]\n"
-"	subs	%0, %0, %4\n"
-"	sbc	%H0, %H0, %H4\n"
+"	subs	%Q0, %Q0, %Q4\n"
+"	sbc	%R0, %R0, %R4\n"
 "	strexd	%1, %0, %H0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
@@ -428,9 +428,9 @@ static inline u64 atomic64_dec_if_positive(atomic64_t *v)
 
 	__asm__ __volatile__("@ atomic64_dec_if_positive\n"
 "1:	ldrexd	%0, %H0, [%3]\n"
-"	subs	%0, %0, #1\n"
-"	sbc	%H0, %H0, #0\n"
-"	teq	%H0, #0\n"
+"	subs	%Q0, %Q0, #1\n"
+"	sbc	%R0, %R0, #0\n"
+"	teq	%R0, #0\n"
 "	bmi	2f\n"
 "	strexd	%1, %0, %H0, [%3]\n"
 "	teq	%1, #0\n"
@@ -459,8 +459,8 @@ static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
 "	teqeq	%H0, %H5\n"
 "	moveq	%1, #0\n"
 "	beq	2f\n"
-"	adds	%0, %0, %6\n"
-"	adc	%H0, %H0, %H6\n"
+"	adds	%Q0, %Q0, %Q6\n"
+"	adc	%R0, %R0, %R6\n"
 "	strexd	%2, %0, %H0, [%4]\n"
 "	teq	%2, #0\n"
 "	bne	1b\n"
Signature · 1 line
1.7.10.4
author
#34 lore raw
In reply to Ben Dooks
Quoted 8 lines · Ben Dooks

This is a new series of the core work for getting big-endian working nicely on ARM. This is mainly a rebase on 3.11-rc7 and has not had a lot of testing on it.

It is available on:

	git://git.baserock.org/delta/linux.git baserock/311-rc7/be/core-v1
Quoted 7 lines

Since the previous version:

- Added Victor's atomic64 patch
- Fixed BUG() patch to use<asm/opcodes.h>

I would like to get as much of this merged as possible, so would it be possible

Is it possible to get all or some of this series pulled before the next merge window? Do I need to remove the machine specific parts of the series?

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

Dear Ben Dooks,

Quoted 14 lines · Ben Dooks
Quoted 13 lines · Ben Dooks

This is a new series of the core work for getting big-endian working nicely on ARM. This is mainly a rebase on 3.11-rc7 and has not had a lot of testing on it.

It is available on:

	git://git.baserock.org/delta/linux.git baserock/311-rc7/be/core-v1

Since the previous version:

- Added Victor's atomic64 patch
- Fixed BUG() patch to use<asm/opcodes.h>

Quoted 6 lines
Quoted 2 lines

I would like to get as much of this merged as possible, so would it be possible

Is it possible to get all or some of this series pulled before the next merge window? Do I need to remove the machine specific parts of the series?

I believe your patch series would get more attention if the cover letter was a bit better. It lacks a version number and a changelog. The new posting you made as "re-send patch series due to mta issues" does not even have a cover letter.

Also, none of the patches are Cc'ed to the relevant maintainers, so I'm not sure how you expect those maintainers to look at your patches?

Would it be possible to Cc me on future postings of this patch set?

Considering the Acked-by and Reviewed-by you had, I would suggest that you push the following patches in Russell King's patch system:

[PATCH 02/19] ARM: asm: Add ARM_BE8() assembly helper
[PATCH 03/19] ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
(after adding Dave Martin Reviewed-by)
[PATCH 04/19] ARM: set BE8 if LE in head code
(after adding Dave Martin Reviewed-by and removing the merge line conflict)
[PATCH 05/19] ARM: pl01x debug code endian fix
[PATCH 06/19] ARM: twd: data endian fix
[PATCH 07/19] ARM: smp_scu: data endian fixes
[PATCH 11/19] ARM: alignment: correctly decode instructions in BE8 mode.
(after adding Dave Martin Reviewed-by)
[PATCH 12/19] ARM: traps: use <asm/opcodes.h> to get correct instruction order
(after fixing the typo pointed by Dave Martin)
[PATCH 13/19] ARM: module: correctly relocate instructions in BE8
(after adding Dave Martin Reviewed-by)
[PATCH 14/19] ARM: set --be8 when linking modules
(after adding Dave Martin Reviewed-by)
[PATCH 15/19] ARM: hardware: fix endian-ness in <hardware/coresight.h> [PATCH 16/19] ARM: net: fix arm instruction endian-ness in bpf_jit_32.c
(after adding Dave Martin Reviewed-by)
[PATCH 17/19] ARM: Correct BUG() assembly to ensure it is endian-agnostic
(after adding Dave Martin Reviewed-by)
[PATCH 18/19] ARM: kdgb: use <asm/opcodes.h> for data to be assembled as intruction
(after adding Dave Martin Reviewed-by)
[PATCH 19/19] ARM: atomic64: fix endian-ness in atomic.h

Considering the release timing, you should really submit those either today or tomorrow into Russell's patch system if you want them to be merged for 3.12.

Regarding mvebu, the below patch is needed to get the secondary CPUs to boot. Other than that, on Armada XP:

It doesn't work yet on Armada 370, but I'm not sure it's due to your patches and anyway isn't a regression since LE continues to work fine on Armada 370.

arch/arm/mach-mvebu/headsmp.S +2 -2
index 3109df0..be067b7 100644
@@ -29,13 +29,13 @@
  * startup
  */
 ENTRY(armada_xp_secondary_startup)
+ARM_BE8(setend be )                    @ go BE8 if booted LE
+
        /* Get coherency fabric base physical address */
        adr     r0, 1f
        ldr     r1, [r0]
        ldr     r0, [r0, r1]
 
- ARM_BE8(setend        be )                    @ go BE8 if booted LE
-
        /* Read CPU id */
        mrc     p15, 0, r1, c0, c0, 5
        and     r1, r1, #0xF

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
#36 lore raw
Quoted 20 lines · Thomas Petazzoni

Dear Ben Dooks,

Quoted 17 lines · Ben Dooks
Quoted 15 lines · Ben Dooks

This is a new series of the core work for getting big-endian working nicely on ARM. This is mainly a rebase on 3.11-rc7 and has not had a lot of testing on it.

It is available on:

	git://git.baserock.org/delta/linux.git baserock/311-rc7/be/core-v1

Since the previous version:

- Added Victor's atomic64 patch
- Fixed BUG() patch to use<asm/opcodes.h>

I would like to get as much of this merged as possible, so would it be possible

Quoted 8 lines
Quoted 3 lines

Is it possible to get all or some of this series pulled before the next merge window? Do I need to remove the machine specific parts of the series?

I believe your patch series would get more attention if the cover letter was a bit better. It lacks a version number and a changelog. The new posting you made as "re-send patch series due to mta issues" does not even have a cover letter.

That was in-reply to as it seems that some of the messages never made it back to me due to a mta issue at my end that needed fixing.

Quoted 2 lines

Also, none of the patches are Cc'ed to the relevant maintainers, so I'm not sure how you expect those maintainers to look at your patches?

I actually left the machine specific ones in this series as a convenient place to keep them before producing a tree for submission.

Quoted 31 lines

Would it be possible to Cc me on future postings of this patch set?

Considering the Acked-by and Reviewed-by you had, I would suggest that you push the following patches in Russell King's patch system:

[PATCH 02/19] ARM: asm: Add ARM_BE8() assembly helper
[PATCH 03/19] ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
(after adding Dave Martin Reviewed-by)
[PATCH 04/19] ARM: set BE8 if LE in head code
(after adding Dave Martin Reviewed-by and removing the merge line conflict)
[PATCH 05/19] ARM: pl01x debug code endian fix
[PATCH 06/19] ARM: twd: data endian fix
[PATCH 07/19] ARM: smp_scu: data endian fixes
[PATCH 11/19] ARM: alignment: correctly decode instructions in BE8 mode.
(after adding Dave Martin Reviewed-by)
[PATCH 12/19] ARM: traps: use<asm/opcodes.h> to get correct instruction order
(after fixing the typo pointed by Dave Martin)
[PATCH 13/19] ARM: module: correctly relocate instructions in BE8
(after adding Dave Martin Reviewed-by)
[PATCH 14/19] ARM: set --be8 when linking modules
(after adding Dave Martin Reviewed-by)
[PATCH 15/19] ARM: hardware: fix endian-ness in<hardware/coresight.h> [PATCH 16/19] ARM: net: fix arm instruction endian-ness in bpf_jit_32.c
(after adding Dave Martin Reviewed-by)
[PATCH 17/19] ARM: Correct BUG() assembly to ensure it is endian-agnostic
(after adding Dave Martin Reviewed-by)
[PATCH 18/19] ARM: kdgb: use<asm/opcodes.h> for data to be assembled as intruction
(after adding Dave Martin Reviewed-by)
[PATCH 19/19] ARM: atomic64: fix endian-ness in atomic.h

Quoted 8 lines

Considering the release timing, you should really submit those either today or tomorrow into Russell's patch system if you want them to be merged for 3.12.

Regarding mvebu, the below patch is needed to get the secondary CPUs to boot. Other than that, on Armada XP:

I will fix up the original patch, as it seems to have gotten out of sync with the change to add the coherency fabric code.

Quoted 3 lines

It doesn't work yet on Armada 370, but I'm not sure it's due to your patches and anyway isn't a regression since LE continues to work fine on Armada 370.

I wonder if it is due to a bootloader issue. I will push out the atags branch later today and you can try that.

Quoted 24 lines
arch/arm/mach-mvebu/headsmp.S +2 -2
index 3109df0..be067b7 100644
@@ -29,13 +29,13 @@
   * startup
   */
  ENTRY(armada_xp_secondary_startup)
+ARM_BE8(setend be )                    @ go BE8 if booted LE
+
         /* Get coherency fabric base physical address */
         adr     r0, 1f
         ldr     r1, [r0]
         ldr     r0, [r0, r1]
 
- ARM_BE8(setend        be )                    @ go BE8 if booted LE
-
         /* Read CPU id */
         mrc     p15, 0, r1, c0, c0, 5
         and     r1, r1, #0xF

Thanks,

Thomas

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

Dear Ben Dooks,

Quoted 7 lines · Ben Dooks
Quoted 4 lines

I believe your patch series would get more attention if the cover letter was a bit better. It lacks a version number and a changelog. The new posting you made as "re-send patch series due to mta issues" does not even have a cover letter.

That was in-reply to as it seems that some of the messages never made it back to me due to a mta issue at my end that needed fixing.

Agreed, but even your original cover letter "3.11-rc7 big-endian support" is far from containing the needed information: a title that contains a version number, and proper changelog with all the changes between all the different versions. You've been in the kernel community for a much longer time than me, I'm sure you know perfectly how to do this properly.

Quoted 5 lines
Quoted 2 lines

Also, none of the patches are Cc'ed to the relevant maintainers, so I'm not sure how you expect those maintainers to look at your patches?

I actually left the machine specific ones in this series as a convenient place to keep them before producing a tree for submission.

Still, I believe the relevant maintainers should be Cc'ed so that you can start collecting their Acked-by/Tested-by.

Quoted 7 lines
Quoted 4 lines

Regarding mvebu, the below patch is needed to get the secondary CPUs to boot. Other than that, on Armada XP:

I will fix up the original patch, as it seems to have gotten out of sync with the change to add the coherency fabric code.

Yeah, the automatic merge with the coherency fabric changes did the wrong choice. Anyway, not a big issue.

Quoted 6 lines
Quoted 3 lines

It doesn't work yet on Armada 370, but I'm not sure it's due to your patches and anyway isn't a regression since LE continues to work fine on Armada 370.

I wonder if it is due to a bootloader issue. I will push out the atags branch later today and you can try that.

I might try some of your earlier branches that are based on 3.10 and have the ATAGS thing, just to see how it behaves on Armada 370. But I'm not using ATAG_DTB_COMPAT, so normally ATAGS endianness should not be a problem.

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
#38 lore raw

Hi Ben,

I wonder is it possible for you to review,
pick up, and include into your series this patch

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-August/195176.html
([PATCH v3 0/1] ARM: signal: sigreturn_codes should be endian neutral to work in BE8)

I think it is very much relevant to the effort.

It was tested on top of your series. And as far as I know it is single patch outside of your series needed so BE Linux LTP testing result will match LE results on the same kernel h/w.

Thanks,
Victor

Quoted 64 lines · Thomas Petazzoni

Dear Ben Dooks,

Quoted 7 lines · Ben Dooks
Quoted 4 lines

I believe your patch series would get more attention if the cover letter was a bit better. It lacks a version number and a changelog. The new posting you made as "re-send patch series due to mta issues" does not even have a cover letter.

That was in-reply to as it seems that some of the messages never made it back to me due to a mta issue at my end that needed fixing.

Agreed, but even your original cover letter "3.11-rc7 big-endian support" is far from containing the needed information: a title that contains a version number, and proper changelog with all the changes between all the different versions. You've been in the kernel community for a much longer time than me, I'm sure you know perfectly how to do this properly.

Quoted 5 lines
Quoted 2 lines

Also, none of the patches are Cc'ed to the relevant maintainers, so I'm not sure how you expect those maintainers to look at your patches?

I actually left the machine specific ones in this series as a convenient place to keep them before producing a tree for submission.

Still, I believe the relevant maintainers should be Cc'ed so that you can start collecting their Acked-by/Tested-by.

Quoted 7 lines
Quoted 4 lines

Regarding mvebu, the below patch is needed to get the secondary CPUs to boot. Other than that, on Armada XP:

I will fix up the original patch, as it seems to have gotten out of sync with the change to add the coherency fabric code.

Yeah, the automatic merge with the coherency fabric changes did the wrong choice. Anyway, not a big issue.

Quoted 6 lines
Quoted 3 lines

It doesn't work yet on Armada 370, but I'm not sure it's due to your patches and anyway isn't a regression since LE continues to work fine on Armada 370.

I wonder if it is due to a bootloader issue. I will push out the atags branch later today and you can try that.

I might try some of your earlier branches that are based on 3.10 and have the ATAGS thing, just to see how it behaves on Armada 370. But I'm not using ATAG_DTB_COMPAT, so normally ATAGS endianness should not be a problem.

Thanks,

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

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

author
#39 lore raw
Quoted 11 lines · Victor Kamensky

Hi Ben,

I wonder is it possible for you to review,
pick up, and include into your series this patch

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-August/195176.html
([PATCH v3 0/1] ARM: signal: sigreturn_codes should be endian neutral to work in BE8)

I think it is very much relevant to the effort.

Quoted 7 lines

It was tested on top of your series. And as far as I know it is single patch outside of your series needed so BE Linux LTP testing result will match LE results on the same kernel h/w.

Thanks,
Victor

I have added it to my latest tree, and will re-post once the reviews are in tomorrow.

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

PATCH 1/19 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 43594d5..0628529 100644
@@ -480,6 +480,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 30e1ebe..c342dc4 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 cd2c88e..1f8fed9 100644
@@ -952,3 +952,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
author
#42 lore raw

PATCH 2/19 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 75189f1..c912c2a 100644
@@ -699,9 +699,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
@@ -728,9 +726,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 a5fef71..5350f83 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 9cbe70c..55090fb 100644
@@ -416,9 +416,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 94104bf..cc318cd 100644
@@ -393,9 +393,7 @@ ENTRY(vector_swi)
 #else
  USER(	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 1128064..45dc29f 100644
@@ -220,9 +220,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 73398bc..03978e3 100644
@@ -355,9 +355,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
#43 lore raw

PATCH 3/19 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 (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.

---
 arch/arm/kernel/head.S |    8 ++++++++
 1 file changed, 8 insertions(+)
arch/arm/kernel/head.S +8 -0
index 2c7cc1e..9e5906c 100644
@@ -582,8 +582,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
@@ -592,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
author
#44 lore raw

PATCH 4/19 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.

Conflicts:
arch/arm/kernel/sleep.S

---
 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 c912c2a..066b034 100644
@@ -135,6 +135,7 @@ start:
 		.word	_edata			@ zImage end address
  THUMB(		.thumb			)
 1:
+ ARM_BE8(	setend	be )			@ go BE8 if compiled for 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 9e5906c..a047acf 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,
@@ -352,6 +353,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)				@ ensure we are in BE8 mode
+
 #ifdef CONFIG_ARM_VIRT_EXT
 	bl	__hyp_stub_install_secondary
 #endif
arch/arm/kernel/sleep.S +1 -0
index db1536b..716343c 100644
@@ -130,6 +130,7 @@ ENDPROC(cpu_resume_after_mmu)
 	.data
 	.align
 ENTRY(cpu_resume)
+ARM_BE8(setend be)			@ ensure we are in BE mode
 	mov	r1, #0
 	ALT_SMP(mrc p15, 0, r0, c0, c0, 5)
 	ALT_UP_B(1f)
Signature · 1 line
1.7.10.4
author
#45 lore raw

PATCH 5/19 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
#46 lore raw

PATCH 6/19 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 2595620..0804013 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 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 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 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
#47 lore raw

PATCH 7/19 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 |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
arch/arm/kernel/smp_scu.c +7 -7
index 5bc1a63..1aafa0d 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;
 }
 
@@ -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;
 }
Signature · 1 line
1.7.10.4
author
#48 lore raw

PATCH 8/19 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
#49 lore raw

PATCH 9/19 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 9eb63d7..5e269d7 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 8a1b0c9..3109df0 100644
@@ -21,6 +21,8 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
+#include <asm/assembler.h>
+
 /*
  * Armada XP specific entry point for secondary CPUs.
  * We add the CPU to the coherency fabric and then jump to secondary
@@ -32,6 +34,8 @@ ENTRY(armada_xp_secondary_startup)
 	ldr	r1, [r0]
 	ldr	r0, [r0, r1]
 
+ 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
#50 lore raw

PATCH 10/19 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 b8bbabe..d9dc5d2a 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 2677bc3..40f27e5 100644
@@ -10,6 +10,7 @@
  */
 #include <linux/linkage.h>
 #include <linux/init.h>
+#include <asm/assembler.h>
 
 /*
  * Realview/Versatile Express specific entry point for secondary CPUs.
@@ -17,6 +18,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
author
#51 lore raw

PATCH 11/19 ARM: alignment: correctly decode instructions in BE8 mode.

In reply to Ben Dooks

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

---
 arch/arm/mm/alignment.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
arch/arm/mm/alignment.c +7 -2
index 6f4585b..9240364 100644
@@ -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,25 @@ 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);
-				instr = (tinstr << 16) | tinst2;
+				tinst2 = __mem_to_opcode_thumb16(tinst2);
+				instr = __opcode_thumb32_compose(tinstr, 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;
Signature · 1 line
1.7.10.4
#52 lore raw

PATCH 11/19 ARM: alignment: correctly decode instructions in BE8 mode.

Hello.

Quoted 9 lines · Ben Dooks

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

I guess the above 2 paragraphs are swapped.

Quoted 1 line

WBR, Sergei

author
#53 lore raw

PATCH 11/19 ARM: alignment: correctly decode instructions in BE8 mode.

Quoted 11 lines · Sergei Shtylyov

Hello.

Quoted 6 lines · Ben Dooks

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.

Quoted 8 lines
Quoted 2 lines

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

I guess the above 2 paragraphs are swapped.

Quoted 1 line

WBR, Sergei

thanks, I also forgot to put a sentence to say that these where kernel messages.

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

PATCH 12/19 ARM: traps: use <asm/opcodes.h> to get correct instruction order

In reply to Ben Dooks

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.

---
 arch/arm/kernel/traps.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
arch/arm/kernel/traps.c +10 -6
index ab517fc..99bcd0e3 100644
@@ -34,6 +34,7 @@
 #include <asm/unwind.h>
 #include <asm/tls.h>
 #include <asm/system_misc.h>
+#include <asm/opcodes.h>
 
 static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
 
@@ -402,25 +403,28 @@ 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];
+				u16 inst2;
+				instr2 = __mem_to_opcode_thumb16(((u16 *)pc)[1]);
+				instr = __opcode_thumb32_compose(instr, instr2);
 			}
 		} 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;
+			instr2 = __mem_to_opcode_thumb16(instr2);
+			instr = __opcode_thumb32_compose(instr, instr2);
 		}
 	} else if (get_user(instr, (u32 __user *)pc)) {
+		instr = __mem_to_opcode_arm(instr);
 		goto die_sig;
 	}
 
Signature · 1 line
1.7.10.4
author
#55 lore raw

PATCH 13/19 ARM: module: correctly relocate instructions in BE8

In reply to Ben Dooks

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

---
 arch/arm/kernel/module.c |   57 +++++++++++++++++++++++++++-------------------
 1 file changed, 34 insertions(+), 23 deletions(-)
arch/arm/kernel/module.c +34 -23
index 85c3fb6..a1045a7 100644
@@ -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
 
Signature · 1 line
1.7.10.4
author
#56 lore raw

PATCH 14/19 ARM: set --be8 when linking modules

In reply to Ben Dooks

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.

---
 arch/arm/Makefile |    1 +
 1 file changed, 1 insertion(+)
arch/arm/Makefile +1 -0
index 6fd2cea..2c659f9 100644
@@ -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
Signature · 1 line
1.7.10.4
author
#57 lore raw

PATCH 15/19 ARM: hardware: fix endian-ness in <hardware/coresight.h>

In reply to Ben Dooks

The <hardware/coresight.h> needs to take into account the endian-ness of the processor when reading and writing data, so change to using the readl/writel relaxed variants from the raw ones.

---
 arch/arm/include/asm/hardware/coresight.h |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm/include/asm/hardware/coresight.h +4 -4
index 0cf7a6b..ad774f3 100644
@@ -24,8 +24,8 @@
 #define TRACER_TIMEOUT 10000
 
 #define etm_writel(t, v, x) \
-	(__raw_writel((v), (t)->etm_regs + (x)))
-#define etm_readl(t, x) (__raw_readl((t)->etm_regs + (x)))
+	(writel_relaxed((v), (t)->etm_regs + (x)))
+#define etm_readl(t, x) (readl_relaxed((t)->etm_regs + (x)))
 
 /* CoreSight Management Registers */
 #define CSMR_LOCKACCESS 0xfb0
@@ -142,8 +142,8 @@
 #define ETBFF_TRIGFL		BIT(10)
 
 #define etb_writel(t, v, x) \
-	(__raw_writel((v), (t)->etb_regs + (x)))
-#define etb_readl(t, x) (__raw_readl((t)->etb_regs + (x)))
+	(writel_relaxed((v), (t)->etb_regs + (x)))
+#define etb_readl(t, x) (readl_relaxed((t)->etb_regs + (x)))
 
 #define etm_lock(t) do { etm_writel((t), 0, CSMR_LOCKACCESS); } while (0)
 #define etm_unlock(t) \
Signature · 1 line
1.7.10.4
author
#58 lore raw

PATCH 16/19 ARM: net: fix arm instruction endian-ness in bpf_jit_32.c

In reply to Ben Dooks

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

---
 arch/arm/net/bpf_jit_32.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm/net/bpf_jit_32.c +5 -1
index f50d223..510d923 100644
@@ -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++;
 }
Signature · 1 line
1.7.10.4
author
#59 lore raw

PATCH 17/19 ARM: Correct BUG() assembly to ensure it is endian-agnostic

In reply to Ben Dooks

Currently BUG() uses .word or .hword to create the necessary illegal instructions. However if we are building BE8 then these get swapped by the linker into different illegal instructions in the text. This means that the BUG() macro does not get trapped properly.

Change to using <asm/opcodes.h> to provide the necessary ARM instruction building as we cannot rely on gcc/gas having the .inst instructions which where added to try and resolve this issue (reported by Dave Martin <[email protected]>).

---
 arch/arm/include/asm/bug.h |   10 ++++++----
 arch/arm/kernel/traps.c    |    8 +++++---
 2 files changed, 11 insertions(+), 7 deletions(-)
arch/arm/include/asm/bug.h +6 -4
index 7af5c6c..b274bde 100644
@@ -2,6 +2,8 @@
 #define _ASMARM_BUG_H
 
 #include <linux/linkage.h>
+#include <linux/types.h>
+#include <asm/opcodes.h>
 
 #ifdef CONFIG_BUG
 
@@ -12,10 +14,10 @@
  */
 #ifdef CONFIG_THUMB2_KERNEL
 #define BUG_INSTR_VALUE 0xde02
-#define BUG_INSTR_TYPE ".hword "
+#define BUG_INSTR(__value) __inst_thumb16(__value)
 #else
 #define BUG_INSTR_VALUE 0xe7f001f2
-#define BUG_INSTR_TYPE ".word "
+#define BUG_INSTR(__value) __inst_arm(__value)
 #endif
 
 
@@ -33,7 +35,7 @@
 
 #define __BUG(__file, __line, __value)				\
 do {								\
-	asm volatile("1:\t" BUG_INSTR_TYPE #__value "\n"	\
+	asm volatile("1:\t" BUG_INSTR(__value) "\n"  \
 		".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
 		"2:\t.asciz " #__file "\n" 			\
 		".popsection\n" 				\
@@ -48,7 +50,7 @@ do {								\
 
 #define __BUG(__file, __line, __value)				\
 do {								\
-	asm volatile(BUG_INSTR_TYPE #__value);			\
+	asm volatile(BUG_INSTR(__value) "\n");			\
 	unreachable();						\
 } while (0)
 #endif  /* CONFIG_DEBUG_BUGVERBOSE */
arch/arm/kernel/traps.c +5 -3
index 99bcd0e3..da070db 100644
@@ -342,15 +342,17 @@ void arm_notify_die(const char *str, struct pt_regs *regs,
 int is_valid_bugaddr(unsigned long pc)
 {
 #ifdef CONFIG_THUMB2_KERNEL
-	unsigned short bkpt;
+	u16 bkpt;
+	u16 insn = __opcode_to_mem_thumb16(BUG_INSTR_VALUE);
 #else
-	unsigned long bkpt;
+	u32 bkpt;
+	u32 insn = __opcode_to_mem_arm(BUG_INSTR_VALUE);
 #endif
 
 	if (probe_kernel_address((unsigned *)pc, bkpt))
 		return 0;
 
-	return bkpt == BUG_INSTR_VALUE;
+	return bkpt == insn;
 }
 
 #endif
Signature · 1 line
1.7.10.4
author
#60 lore raw

PATCH 18/19 ARM: kdgb: use <asm/opcodes.h> for data to be assembled as intruction

In reply to Ben Dooks

The arch_kgdb_breakpoint() function uses an inline assembly directive to assemble a specific instruction using .word. This means the linker will not treat is as an instruction, and therefore incorrectly swap the endian-ness if running BE8.

---
 arch/arm/include/asm/kgdb.h |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm/include/asm/kgdb.h +2 -1
index 48066ce..0a9d5dd 100644
@@ -11,6 +11,7 @@
 #define __ARM_KGDB_H__
 
 #include <linux/ptrace.h>
+#include <asm/opcodes.h>
 
 /*
  * GDB assumes that we're a user process being debugged, so
@@ -41,7 +42,7 @@
 
 static inline void arch_kgdb_breakpoint(void)
 {
-	asm(".word 0xe7ffdeff");
+	asm(__inst_arm(0xe7ffdeff));
 }
 
 extern void kgdb_handle_bus_error(void);
Signature · 1 line
1.7.10.4
author
#61 lore raw

PATCH 19/19 ARM: atomic64: fix endian-ness in atomic.h

In reply to Ben Dooks

From: Victor Kamensky <[email protected]>

Fix inline asm for atomic64_xxx functions in arm atomic.h. Instead of %H operand specifiers code should use %Q for least significant part of the value, and %R for the most significant part of the value. %H always returns the higher of the two register numbers, and therefore it is not endian neutral. %H should be used with ldrexd and strexd instructions.

---
 arch/arm/include/asm/atomic.h |   26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)
arch/arm/include/asm/atomic.h +13 -13
index da1c77d..6447a0b 100644
@@ -301,8 +301,8 @@ static inline void atomic64_add(u64 i, atomic64_t *v)
 
 	__asm__ __volatile__("@ atomic64_add\n"
 "1:	ldrexd	%0, %H0, [%3]\n"
-"	adds	%0, %0, %4\n"
-"	adc	%H0, %H0, %H4\n"
+"	adds	%Q0, %Q0, %Q4\n"
+"	adc	%R0, %R0, %R4\n"
 "	strexd	%1, %0, %H0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
@@ -320,8 +320,8 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
 
 	__asm__ __volatile__("@ atomic64_add_return\n"
 "1:	ldrexd	%0, %H0, [%3]\n"
-"	adds	%0, %0, %4\n"
-"	adc	%H0, %H0, %H4\n"
+"	adds	%Q0, %Q0, %Q4\n"
+"	adc	%R0, %R0, %R4\n"
 "	strexd	%1, %0, %H0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
@@ -341,8 +341,8 @@ static inline void atomic64_sub(u64 i, atomic64_t *v)
 
 	__asm__ __volatile__("@ atomic64_sub\n"
 "1:	ldrexd	%0, %H0, [%3]\n"
-"	subs	%0, %0, %4\n"
-"	sbc	%H0, %H0, %H4\n"
+"	subs	%Q0, %Q0, %Q4\n"
+"	sbc	%R0, %R0, %R4\n"
 "	strexd	%1, %0, %H0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
@@ -360,8 +360,8 @@ static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
 
 	__asm__ __volatile__("@ atomic64_sub_return\n"
 "1:	ldrexd	%0, %H0, [%3]\n"
-"	subs	%0, %0, %4\n"
-"	sbc	%H0, %H0, %H4\n"
+"	subs	%Q0, %Q0, %Q4\n"
+"	sbc	%R0, %R0, %R4\n"
 "	strexd	%1, %0, %H0, [%3]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
@@ -428,9 +428,9 @@ static inline u64 atomic64_dec_if_positive(atomic64_t *v)
 
 	__asm__ __volatile__("@ atomic64_dec_if_positive\n"
 "1:	ldrexd	%0, %H0, [%3]\n"
-"	subs	%0, %0, #1\n"
-"	sbc	%H0, %H0, #0\n"
-"	teq	%H0, #0\n"
+"	subs	%Q0, %Q0, #1\n"
+"	sbc	%R0, %R0, #0\n"
+"	teq	%R0, #0\n"
 "	bmi	2f\n"
 "	strexd	%1, %0, %H0, [%3]\n"
 "	teq	%1, #0\n"
@@ -459,8 +459,8 @@ static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
 "	teqeq	%H0, %H5\n"
 "	moveq	%1, #0\n"
 "	beq	2f\n"
-"	adds	%0, %0, %6\n"
-"	adc	%H0, %H0, %H6\n"
+"	adds	%Q0, %Q0, %Q6\n"
+"	adc	%R0, %R0, %R6\n"
 "	strexd	%2, %0, %H0, [%4]\n"
 "	teq	%2, #0\n"
 "	bne	1b\n"
Signature · 1 line
1.7.10.4