Initial big-endian support series
Subsystems (6)
This updates the kernel support for building big-endian kernels and updating the core drivers to deal with the endian swap as needed.
This series does not include the fixups for ATAGs so it will require being booted with fdt. As a note, we do not currently disable the ATAGs options for the system (although we could) as there will be a set of patches following on to deal with booting BE kernel on LE systems.
I have not had time to test it on THUMB2 kernels. There is still fixup work to be done for these which will require more time.
It is on git://git.baserock.org:/delta/linux on branch baserock/311/be/core
PATCH 1/10 ARM: fix ARCH_IXP4xx usage of ARCH_SUPPORTS_BIG_ENDIAN
The Kconfig for arch/arm/mach-ixp4xx has a local definition of ARCH_SUPPORTS_BIG_ENDIAN which could be used elsewhere. This means that if IXP4xx is selected and this symbol is selected eleswhere then an warning is produced.
Clean the following error up by making the symbol be selected by the main ARCH_IXP4XX definition and have a common definition in arch/arm/mm/Kconfig
warning: (ARCH_xxx) selects ARCH_SUPPORTS_BIG_ENDIAN which has unmet direct dependencies (ARCH_IXP4XX)
warning: (ARCH_xxx) selects ARCH_SUPPORTS_BIG_ENDIAN which has unmet direct dependencies (ARCH_IXP4XX)
--- arch/arm/Kconfig | 1 + arch/arm/mach-ixp4xx/Kconfig | 4 ---- arch/arm/mm/Kconfig | 6 ++++++ 3 files changed, 7 insertions(+), 4 deletions(-)
arch/arm/Kconfig +1 -0
@@ -474,6 +474,7 @@ config ARCH_IXP4XX bool "IXP4xx-based" depends on MMU select ARCH_HAS_DMA_SET_COHERENT_MASK + select ARCH_SUPPORTS_BIG_ENDIAN select ARCH_REQUIRE_GPIOLIB select CLKSRC_MMIO select CPU_XSCALE
arch/arm/mach-ixp4xx/Kconfig +0 -4
@@ -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
@@ -895,3 +895,9 @@ config ARCH_HAS_BARRIERS help This option allows the use of custom mandatory barriers included via the mach/barriers.h file. + +config ARCH_SUPPORTS_BIG_ENDIAN + bool + help + This option specifies the architecture can support big endian + operation.
Signature · 1 line
1.7.10.4
PATCH 1/10 ARM: fix ARCH_IXP4xx usage of ARCH_SUPPORTS_BIG_ENDIAN
Dear Ben Dooks,
Quoted 9 lines · Ben Dooks
The
Kconfigforarch/arm/mach-ixp4xxhas a local definition ofARCH_SUPPORTS_BIG_ENDIANwhich 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_IXP4XXdefinition and have a common definition inarch/arm/mm/Kconfig
Quoted 7 lines
warning: (
ARCH_xxx) selectsARCH_SUPPORTS_BIG_ENDIANwhich has unmet direct dependencies (ARCH_IXP4XX)
warning: (ARCH_xxx) selectsARCH_SUPPORTS_BIG_ENDIANwhich has unmet direct dependencies (ARCH_IXP4XX)--- arch/arm/Kconfig | 1 + arch/arm/mach-ixp4xx/Kconfig | 4 ---- arch/arm/mm/Kconfig | 6 ++++++ 3 files changed, 7 insertions(+), 4 deletions(-)
Patch lacks SoB.
Best regards,
Thomas
Signature · 4 lines
Thomas Petazzoni, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 1/10 ARM: fix ARCH_IXP4xx usage of ARCH_SUPPORTS_BIG_ENDIAN
Quoted 20 lines · Thomas Petazzoni
Dear Ben Dooks,
Quoted 9 lines · Ben Dooks
The
Kconfigforarch/arm/mach-ixp4xxhas a local definition ofARCH_SUPPORTS_BIG_ENDIANwhich 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_IXP4XXdefinition and have a common definition inarch/arm/mm/KconfigQuoted 7 lines
warning: (
ARCH_xxx) selectsARCH_SUPPORTS_BIG_ENDIANwhich has unmet direct dependencies (ARCH_IXP4XX)
warning: (ARCH_xxx) selectsARCH_SUPPORTS_BIG_ENDIANwhich has unmet direct dependencies (ARCH_IXP4XX)--- arch/arm/Kconfig | 1 + arch/arm/mach-ixp4xx/Kconfig | 4 ---- arch/arm/mm/Kconfig | 6 ++++++ 3 files changed, 7 insertions(+), 4 deletions(-)
Quoted 1 line
Patch lacks SoB.
Thanks, must have missed it.
Signature · 2 lines
Ben Dooks http://www.codethink.co.uk/ Senior Engineer Codethink - Providing Genius
PATCH 2/10 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.
Note, not tested against an actual bug, it looked wrong.
--- arch/arm/kernel/head.S | 6 ++++++ 1 file changed, 6 insertions(+)
arch/arm/kernel/head.S +6 -0
@@ -594,8 +594,14 @@ __fixup_a_pv_table: #else b 2f 1: ldr ip, [r7, r3] +#ifdef CONFIG_CPU_ENDIAN_BE8 + @ in BE8, we load data in BE, but instructions still in LE + bic ip, ip, #0xff000000 + orr ip, ip, r6, lsl#24 +#else bic ip, ip, #0x000000ff orr ip, ip, r6 @ mask in offset bits 31-24 +#endif str ip, [r7, r3] 2: cmp r4, r5 ldrcc r7, [r4], #4 @ use branch for delay slot
Signature · 1 line
1.7.10.4
PATCH 2/10 ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
Dear Ben Dooks,
arch/arm/kernel/head.S __fixup_a_pv_table: · line 607
Quoted 11 lines · Ben Dooks
arch/arm/kernel/head.S +6
-0+#ifdef CONFIG_CPU_ENDIAN_BE8 + @ in BE8, we load data in BE, but instructions still in LE + bic ip, ip, #0xff000000 + orr ip, ip, r6, lsl#24 +#else bic ip, ip, #0x000000ff orr ip, ip, r6 @ mask in offset bits 31-24 +#endif str ip, [r7, r3] 2: cmp r4, r5 ldrcc r7, [r4], #4 @ use branch for delay slot
As was suggested in
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/150782.html,
you could put this patch later in the series and use the ARM_BE8() macro you introduce in the next patch.
Also in
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/150784.html,
the same reviewer suggested to name the macro BE8() to make it fit like ARM() and THUMB() in the margin left by the indentation of assembly code. And also to add LE() to make the above code look like:
BE8( bic ip, ip, #0xff000000)BE8( orr ip, ip, r6, lsl#24)LE( bic ip, ip, #0x000000ff)LE( orr ip, ip, r6)
Thomas
Signature · 4 lines
Thomas Petazzoni, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 2/10 ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
Quoted 27 lines · Thomas Petazzoni
Dear Ben Dooks,
arch/arm/kernel/head.S __fixup_a_pv_table: · line 607
Quoted 11 lines · Ben Dooks
arch/arm/kernel/head.S +6
-0+#ifdef CONFIG_CPU_ENDIAN_BE8 + @ in BE8, we load data in BE, but instructions still in LE + bic ip, ip, #0xff000000 + orr ip, ip, r6, lsl#24 +#else bic ip, ip, #0x000000ff orr ip, ip, r6 @ mask in offset bits 31-24 +#endif str ip, [r7, r3] 2: cmp r4, r5 ldrcc r7, [r4], #4 @ use branch for delay slotAs was suggested in
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/150782.html,
you could put this patch later in the series and use theARM_BE8()macro you introduce in the next patch.Also in
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/150784.html,
the same reviewer suggested to name the macroBE8()to make it fit likeARM()andTHUMB()in the margin left by the indentation of assembly code. And also to addLE()to make the above code look like:
Quoted 4 lines
BE8( bic ip, ip, #0xff000000)BE8( orr ip, ip, r6, lsl#24)LE( bic ip, ip, #0x000000ff)LE( orr ip, ip, r6)
Actually, that doesn't work as LE is not the inverse of BE8 as it could also be when the kernel is being compiled in BE32.
Signature · 2 lines
Ben Dooks http://www.codethink.co.uk/ Senior Engineer Codethink - Providing Genius
PATCH 2/10 ARM: fixup_pv_table bug when CPU_ENDIAN_BE8
Dear Ben Dooks,
Quoted 6 lines · Ben Dooks
Quoted 6 lines
Also in
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/150784.html,
the same reviewer suggested to name the macroBE8()to make it fit likeARM()andTHUMB()in the margin left by the indentation of assembly code. And also to addLE()to make the above code look like:
Quoted 7 lines
Quoted 4 lines
BE8( bic ip, ip, #0xff000000)BE8( orr ip, ip, r6, lsl#24)LE( bic ip, ip, #0x000000ff)LE( orr ip, ip, r6)Actually, that doesn't work as LE is not the inverse of BE8 as it could also be when the kernel is being compiled in BE32.
Aah, correct. In BE32, data and instructions have the same endianness.
Thanks,
Thomas
Signature · 4 lines
Thomas Petazzoni, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
PATCH 3/10 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
@@ -679,9 +679,7 @@ __armv4_mmu_cache_on: mrc p15, 0, r0, c1, c0, 0 @ read control reg orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement orr r0, r0, #0x0030 -#ifdef CONFIG_CPU_ENDIAN_BE8 - orr r0, r0, #1 << 25 @ big-endian page tables -#endif + ARM_BE8( orr r0, r0, #1 << 25 ) @ big-endian page tables bl __common_mmu_cache_on mov r0, #0 mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
@@ -708,9 +706,7 @@ __armv7_mmu_cache_on: orr r0, r0, #1 << 22 @ U (v6 unaligned access model) @ (needed for ARM1176) #ifdef CONFIG_MMU -#ifdef CONFIG_CPU_ENDIAN_BE8 - orr r0, r0, #1 << 25 @ big-endian page tables -#endif + ARM_BE8( orr r0, r0, #1 << 25 ) @ big-endian page tables mrcne p15, 0, r6, c2, c0, 2 @ read ttb control reg orrne r0, r0, #1 @ MMU enabled movne r1, #0xfffffffd @ domain 0 = client
arch/arm/include/asm/assembler.h +7 -0
@@ -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
@@ -415,9 +415,8 @@ __und_usr: bne __und_usr_thumb sub r4, r2, #4 @ ARM instr@LR - 4 1: ldrt r0, [r4] -#ifdef CONFIG_CPU_ENDIAN_BE8 - rev r0, r0 @ little endian instruction -#endif + ARM_BE8(rev r0, r0) @ little endian instruction + @ r0 = 32-bit ARM instruction which caused the exception @ r2 = PC value for the following instruction (:= regs->ARM_pc) @ r4 = PC value for the faulting instruction
arch/arm/kernel/entry-common.S +1 -3
@@ -379,9 +379,7 @@ ENTRY(vector_swi) #else ldr r10, [lr, #-4] @ get SWI instruction #endif -#ifdef CONFIG_CPU_ENDIAN_BE8 - rev r10, r10 @ little endian instruction -#endif + ARM_BE8(rev r10, r10) @ little endian instruction #elif defined(CONFIG_AEABI)
arch/arm/mm/abort-ev6.S +2 -3
@@ -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
@@ -218,9 +218,7 @@ __v6_setup: #endif /* CONFIG_MMU */ adr r5, v6_crval ldmia r5, {r5, r6} -#ifdef CONFIG_CPU_ENDIAN_BE8 - orr r6, r6, #1 << 25 @ big-endian page tables -#endif + ARM_BE8(orr r6, r6, #1 << 25) @ big-endian page tables mrc p15, 0, r0, c1, c0, 0 @ read control register bic r0, r0, r5 @ clear bits them orr r0, r0, r6 @ set them
arch/arm/mm/proc-v7.S +1 -3
@@ -328,9 +328,7 @@ __v7_setup: #endif adr r5, v7_crval ldmia r5, {r5, r6} -#ifdef CONFIG_CPU_ENDIAN_BE8 - orr r6, r6, #1 << 25 @ big-endian page tables -#endif + ARM_BE8(orr r6, r6, #1 << 25) @ big-endian page tables #ifdef CONFIG_SWP_EMULATE orr r5, r5, #(1 << 10) @ set SW bit in "clear" bic r6, r6, #(1 << 10) @ clear it in "mmuset"
Signature · 1 line
1.7.10.4
PATCH 4/10 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.
--- 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 LE, no-op if BE8 mrs r9, cpsr #ifdef CONFIG_ARM_VIRT_EXT bl __hyp_stub_install @ get into SVC mode, reversibly
arch/arm/kernel/head.S +4 -0
@@ -77,6 +77,7 @@ __HEAD ENTRY(stext) + ARM_BE8(setend be ) @ ensure we are in BE8 mode THUMB( adr r9, BSYM(1f) ) @ Kernel is always entered in ARM. THUMB( bx r9 ) @ If this is a Thumb-2 kernel,
@@ -351,6 +352,9 @@ ENTRY(secondary_startup) * the processor type - there is no need to check the machine type * as it has already been validated by the primary processor. */ + + ARM_BE8(setend be) @ if system starts LE, go BE8 + #ifdef CONFIG_ARM_VIRT_EXT bl __hyp_stub_install_secondary #endif
arch/arm/kernel/sleep.S +1 -0
@@ -81,6 +81,7 @@ ENDPROC(cpu_resume_after_mmu) .data .align ENTRY(cpu_resume) +ARM_BE8(setend be) @ ensure we are in BE mode #ifdef CONFIG_SMP adr r0, sleep_save_sp ALT_SMP(mrc p15, 0, r1, c0, c0, 5)
Signature · 1 line
1.7.10.4
PATCH 5/10 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/10 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 __cpuinit twd_calibrate_rate(void) waitjiffies +=5 ;/* enable, no interrupt or reload */ -__raw_writel (0x1 , twd_base +TWD_TIMER_CONTROL ); +writel_relaxed (0x1 , twd_base +TWD_TIMER_CONTROL );/* maximum value */ -__raw_writel (0xFFFFFFFFU , twd_base +TWD_TIMER_COUNTER ); +writel_relaxed (0xFFFFFFFFU , twd_base +TWD_TIMER_COUNTER );while (get_jiffies_64 () < waitjiffies)udelay (10 ); - count =__raw_readl (twd_base +TWD_TIMER_COUNTER ); + count =readl_relaxed (twd_base +TWD_TIMER_COUNTER ); twd_timer_rate = (0xFFFFFFFFU - count) * (HZ /5 );
@@ -275,7 +275,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)* bother with the below. */ if (per_cpu (percpu_setup_called, cpu)) { -__raw_writel (0 , twd_base +TWD_TIMER_CONTROL ); +writel_relaxed (0 , twd_base +TWD_TIMER_CONTROL );clockevents_register_device (*__this_cpu_ptr (twd_evt));enable_percpu_irq (clk->irq,0 );return 0 ;
@@ -288,7 +288,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)* The following is done once per CPU the first time .setup() is * called. */ -__raw_writel (0 , twd_base +TWD_TIMER_CONTROL ); +writel_relaxed (0 , twd_base +TWD_TIMER_CONTROL ); clk->name ="local_timer" ; clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
Signature · 1 line
1.7.10.4
PATCH 7/10 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 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
arch/arm/kernel/smp_scu.c +8 -8
@@ -28,7 +28,7 @@*/ unsigned int __init scu_get_core_count (void __iomem *scu_base) { -unsigned int ncores =__raw_readl (scu_base +SCU_CONFIG ); +unsigned int ncores =readl_relaxed (scu_base +SCU_CONFIG );return (ncores &0x03 ) +1 ; }
@@ -41,20 +41,20 @@ void scu_enable(void __iomem *scu_base)#ifdef CONFIG_ARM_ERRATA_764369 /* Cortex-A9 only */ -if ((read_cpuid_id () &0xff0ffff0 ) ==0x410fc090 ) { - scu_ctrl =__raw_readl (scu_base +0x30 ); +if ((read_cpuid (CPUID_ID ) &0xff0ffff0 ) ==0x410fc090 ) { + scu_ctrl =readl_relaxed (scu_base +0x30 );if (!(scu_ctrl &1 )) -__raw_writel (scu_ctrl |0x1 , scu_base +0x30 ); +writel_relaxed (scu_ctrl |0x1 , scu_base +0x30 ); }#endif - scu_ctrl =__raw_readl (scu_base +SCU_CTRL ); + scu_ctrl =readl_relaxed (scu_base +SCU_CTRL );/* already enabled? */ if (scu_ctrl &1 )return ; scu_ctrl |=1 ; -__raw_writel (scu_ctrl, scu_base +SCU_CTRL ); +writel_relaxed (scu_ctrl, scu_base +SCU_CTRL );/* * Ensure that the data accessed by CPU0 before the SCU was
@@ -80,9 +80,9 @@ int scu_power_mode(void __iomem *scu_base, unsigned int mode)if (mode >3 || mode ==1 || cpu >3 )return -EINVAL ; - val =__raw_readb (scu_base +SCU_CPU_STATUS + cpu) & ~0x03 ; + val =readb_relaxed (scu_base +SCU_CPU_STATUS + cpu) & ~0x03 ; val |= mode; -__raw_writeb (val, scu_base +SCU_CPU_STATUS + cpu); +writeb_relaxed (val, scu_base +SCU_CPU_STATUS + cpu);return 0 ; }
Signature · 1 line
1.7.10.4
PATCH 8/10 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/10 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> + /* * At this stage the secondary CPUs don't have acces yet to the MMU, so * we have to provide physical addresses
@@ -36,6 +38,8 @@ */ ENTRY(armada_xp_secondary_startup) + ARM_BE8(setend be ) @ go BE8 if booted LE + /* Read CPU id */ mrc p15, 0, r1, c0, c0, 5 and r1, r1, #0xF
Signature · 1 line
1.7.10.4
PATCH 10/10 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> __INIT
@@ -19,6 +20,7 @@ * until we're ready for them to initialise. */ ENTRY(versatile_secondary_startup) + ARM_BE8(setend be) mrc p15, 0, r0, c0, c0, 5 bic r0, #0xff000000 adr r4, 1f
Signature · 1 line
1.7.10.4
Dear Ben Dooks,
Quoted 9 lines · Ben Dooks
This updates the kernel support for building big-endian kernels and updating the core drivers to deal with the endian swap as needed.
This series does not include the fixups for ATAGs so it will require being booted with fdt. As a note, we do not currently disable the ATAGs options for the system (although we could) as there will be a set of patches following on to deal with booting BE kernel on LE systems.
I have tested both series on an Armada XP based platform and I confirm that I'm able to boot successfully with a BE8 kernel and into a BE8 userspace. Nice!
Would it be possible to get this merged?
Quoted 2 lines
I have not had time to test it on THUMB2 kernels. There is still fixup work to be done for these which will require more time.
I might have some time in the near future to look at that, if you don't do it in the mean time, of course.
Thanks!
Thomas
Signature · 4 lines
Thomas Petazzoni, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. http://free-electrons.com
Quoted 10 lines · Ben Dooks
This updates the kernel support for building big-endian kernels and updating the core drivers to deal with the endian swap as needed.
This series does not include the fixups for ATAGs so it will require being booted with fdt. As a note, we do not currently disable the ATAGs options for the system (although we could) as there will be a set of patches following on to deal with booting BE kernel on LE systems.
Quoted 4 lines
I have not had time to test it on THUMB2 kernels. There is still fixup work to be done for these which will require more time.
It is on
git://git.baserock.org:/delta/linuxon branch baserock/311/be/core
Russell, any objections to taking this patch series?
Signature · 2 lines
Ben Dooks http://www.codethink.co.uk/ Senior Engineer Codethink - Providing Genius