3.11-rc7 big-endian support
Subsystems (9)
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
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
@@ -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
@@ -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
@@ -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
PATCH 2/19 ARM: asm: Add ARM_BE8() assembly helper
In reply to Ben DooksAdd 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 3/19 ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
In reply to Ben DooksThe 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
@@ -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
PATCH 3/19 ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
Quoted 8 lines · Ben Dooks
The
fixup_pv_tableassumes 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_BE8is 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
Signed-off-by Ben Dooks <[email protected]>--- arch/arm/kernel/head.S | 8 ++++++++ 1 file changed, 8 insertions(+)arch/arm/kernel/head.S +8
-0@@ -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 slotSignature · 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
PATCH 4/19 ARM: set BE8 if LE in head code
In reply to Ben DooksIf 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
@@ -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
@@ -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
@@ -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
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.
Signed-off-by Ben Dooks <[email protected]>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
PATCH 4/19 ARM: set BE8 if LE in head code
In reply to Ben DooksQuoted 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.
Signed-off-by Ben Dooks <[email protected]>
(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@@ -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, reversiblyarch/arm/kernel/head.S +4
-0@@ -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 #endifarch/arm/kernel/sleep.S +1
-0@@ -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
PATCH 5/19 ARM: pl01x debug code endian fix
In reply to Ben DooksThe 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
@@ -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
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
Reviewed-by Will Deacon <[email protected]>Signed-off-by Ben Dooks <[email protected]>--- arch/arm/include/asm/hardware/debug-pl01x.S | 2 ++ 1 file changed, 2 insertions(+)arch/arm/include/asm/hardware/debug-pl01x.S +2
-0@@ -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 .endmSignature · 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
PATCH 6/19 ARM: twd: data endian fix
In reply to Ben DooksEnsure 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
@@ -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
PATCH 7/19 ARM: smp_scu: data endian fixes
In reply to Ben DooksThe 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
@@ -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
PATCH 8/19 highbank: enable big-endian
In reply to Ben DooksApart 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
@@ -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
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.
Signed-off-by Ben Dooks <[email protected]>--- arch/arm/mach-highbank/Kconfig | 1 + 1 file changed, 1 insertion(+)arch/arm/mach-highbank/Kconfig +0
-0
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
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.
Signed-off-by Ben Dooks<[email protected]>--- arch/arm/mach-highbank/Kconfig | 1 + 1 file changed, 1 insertion(+)arch/arm/mach-highbank/Kconfig +0
-0arch/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_ENDIANThe 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
PATCH 9/19 mvebu: support running big-endian
In reply to Ben DooksAdd 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
@@ -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
@@ -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
@@ -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
PATCH 10/19 vexpress: add big endian support
In reply to Ben DooksAdd 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
@@ -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
@@ -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
PATCH 11/19 ARM: alignment: correctly decode instructions in BE8 mode.
In reply to Ben DooksIf 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
@@ -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
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
030091e8at [<80333e8c>] Unhandled fault: alignment exception (0x001) at0xbfa09567
Quoted 54 lines
Signed-off-by Ben Dooks <[email protected]>--- arch/arm/mm/alignment.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)arch/arm/mm/alignment.c +7
-2@@ -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
PATCH 12/19 ARM: traps: use <asm/opcodes.h> to get correct instruction order
In reply to Ben DooksThe 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
@@ -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
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.Signed-off-by Ben Dooks <[email protected]>--- arch/arm/kernel/traps.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)arch/arm/kernel/traps.c +1
-0@@ -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
PATCH 13/19 ARM: module: correctly relocate instructions in BE8
In reply to Ben DooksWhen 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
@@ -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
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
Signed-off-by Ben Dooks <[email protected]>
Quoted 147 lines
--- arch/arm/kernel/module.c | 57 +++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 23 deletions(-)arch/arm/kernel/module.c +34
-23@@ -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
PATCH 14/19 ARM: set --be8 when linking modules
In reply to Ben DooksTo 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
@@ -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
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
Signed-off-by Ben Dooks <[email protected]>--- arch/arm/Makefile | 1 + 1 file changed, 1 insertion(+)arch/arm/Makefile +1
-0@@ -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 -SSignature · 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
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:
Reviewed-by Dave Martin<[email protected]>Cheers
---DaveQuoted 25 lines
Signed-off-by Ben Dooks<[email protected]>--- arch/arm/Makefile | 1 + 1 file changed, 1 insertion(+)arch/arm/Makefile +1
-1@@ -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
PATCH 15/19 ARM: hardware: fix endian-ness in <hardware/coresight.h>
In reply to Ben DooksThe <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
@@ -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
PATCH 16/19 ARM: net: fix arm instruction endian-ness in bpf_jit_32.c
In reply to Ben DooksUse <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
@@ -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
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
Signed-off-by Ben Dooks <[email protected]>--- arch/arm/net/bpf_jit_32.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)arch/arm/net/bpf_jit_32.c +5
-1@@ -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
PATCH 17/19 ARM: Correct BUG() assembly to ensure it is endian-agnostic
In reply to Ben DooksCurrently 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
@@ -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
@@ -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
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 theBUG()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.instinstructions which where added to try and resolve this issue (reported by Dave Martin <[email protected]>).
Quoted 84 lines
Signed-off-by Ben Dooks <[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@@ -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@@ -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
PATCH 18/19 ARM: kdgb: use <asm/opcodes.h> for data to be assembled as intruction
In reply to Ben DooksThe 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
@@ -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
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
Signed-off-by Ben Dooks <[email protected]>--- arch/arm/include/asm/kgdb.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)arch/arm/include/asm/kgdb.h +2
-1@@ -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
PATCH 19/19 ARM: atomic64: fix endian-ness in atomic.h
In reply to Ben DooksFrom: 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
@@ -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
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
- FixedBUG()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
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-v1Since the previous version:
- Added Victor's atomic64 patch
- FixedBUG()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
@@ -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
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-v1Since the previous version:
- Added Victor's atomic64 patch
- FixedBUG()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_tablebug whenCPU_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 inbpf_jit_32.c
(after adding Dave Martin Reviewed-by)
[PATCH 17/19] ARM: CorrectBUG()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 inatomic.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:
Tested-by Thomas Petazzoni<[email protected]>
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@@ -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, #0xFThanks,
Thomas
Signature · 2 lines
Ben Dooks http://www.codethink.co.uk/ Senior Engineer Codethink - Providing Genius
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:
Tested-by Thomas Petazzoni<[email protected]>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
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:
Tested-by Thomas Petazzoni<[email protected]>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
Quoted 11 lines · Victor Kamensky
Hi Ben,
I wonder is it possible for you to review,
pick up, and include into your series this patchhttp://lists.infradead.org/pipermail/linux-arm-kernel/2013-August/195176.html
([PATCH v3 0/1] ARM: signal:sigreturn_codesshould 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
re-send patch series due to mta issues
In reply to Ben Dooksre-send of the previous due to MTA dropping part of the series.
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
@@ -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
@@ -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
@@ -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
PATCH 2/19 ARM: asm: Add ARM_BE8() assembly helper
In reply to Ben DooksAdd 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 3/19 ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
In reply to Ben DooksThe 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
@@ -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
PATCH 4/19 ARM: set BE8 if LE in head code
In reply to Ben DooksIf 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
@@ -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
@@ -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
@@ -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
PATCH 5/19 ARM: pl01x debug code endian fix
In reply to Ben DooksThe 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
@@ -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
PATCH 6/19 ARM: twd: data endian fix
In reply to Ben DooksEnsure 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
@@ -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
PATCH 7/19 ARM: smp_scu: data endian fixes
In reply to Ben DooksThe 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
@@ -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
PATCH 8/19 highbank: enable big-endian
In reply to Ben DooksApart 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
@@ -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
PATCH 9/19 mvebu: support running big-endian
In reply to Ben DooksAdd 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
@@ -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
@@ -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
@@ -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
PATCH 10/19 vexpress: add big endian support
In reply to Ben DooksAdd 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
@@ -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
@@ -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
PATCH 11/19 ARM: alignment: correctly decode instructions in BE8 mode.
In reply to Ben DooksIf 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
@@ -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
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
030091e8at [<80333e8c>] Unhandled fault: alignment exception (0x001) at0xbfa09567
I guess the above 2 paragraphs are swapped.
Quoted 1 line
Signed-off-by Ben Dooks <[email protected]>
WBR, Sergei
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
030091e8at [<80333e8c>] Unhandled fault: alignment exception (0x001) at0xbfa09567I guess the above 2 paragraphs are swapped.
Quoted 1 line
Signed-off-by Ben Dooks <[email protected]>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
PATCH 12/19 ARM: traps: use <asm/opcodes.h> to get correct instruction order
In reply to Ben DooksThe 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
@@ -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
PATCH 13/19 ARM: module: correctly relocate instructions in BE8
In reply to Ben DooksWhen 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
@@ -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
PATCH 14/19 ARM: set --be8 when linking modules
In reply to Ben DooksTo 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
@@ -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
PATCH 15/19 ARM: hardware: fix endian-ness in <hardware/coresight.h>
In reply to Ben DooksThe <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
@@ -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
PATCH 16/19 ARM: net: fix arm instruction endian-ness in bpf_jit_32.c
In reply to Ben DooksUse <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
@@ -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
PATCH 17/19 ARM: Correct BUG() assembly to ensure it is endian-agnostic
In reply to Ben DooksCurrently 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
@@ -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
@@ -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
PATCH 18/19 ARM: kdgb: use <asm/opcodes.h> for data to be assembled as intruction
In reply to Ben DooksThe 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
@@ -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
PATCH 19/19 ARM: atomic64: fix endian-ness in atomic.h
In reply to Ben DooksFrom: 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
@@ -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