Skip to contentSkip to conversation

ARM: various boot-time tidying

PATCH In review Tim Deegan 3 participants 15 messages May 31, 2012 – Jun 1, 2012

lore
Share & tools
lore

Tim Deegan

author
#0 lore raw

PATCH 1/1 ARM: various boot-time tidying

These patches tinker with the ARM boot a little bit. They shouldn't clash with any of the other ARM work going on, since they only touch very early code.

Cheers,

Tim.

author
#1 lore raw

PATCH 1/1 arm: More interrupt setup at start-of-day for secondary CPUs

# HG changeset patch
# User Tim Deegan <[email protected]>
# Date 1338482127 -3600
# Node ID 25d389d891c5a2a3009258ef7261379a9ad97746 # Parent d7318231cfe3498947bf75f09d6675407d7b4e76
arm: More interrupt setup at start-of-day for secondary CPUs.

xen/arch/arm/smpboot.c +2 -0
diff -r d7318231cfe3 -r 25d389d891c5 xen/arch/arm/smpboot.c
@@ -107,6 +107,8 @@ void __cpuinit start_secondary(unsigned 
 
     mmu_init_secondary_cpu();
     gic_init_secondary_cpu();
+    init_timer_interrupt();
+    gic_route_irqs();
 
     set_current(idle_vcpu[cpuid]);
author
#2 lore raw

PATCH 1/1 arm: Move hyp-mode entry code out of line

In reply to Tim Deegan

# HG changeset patch
# User Tim Deegan <[email protected]>
# Date 1338482127 -3600
# Node ID 05447f395c91029fb732142e36788cfa92374045 # Parent 25d389d891c5a2a3009258ef7261379a9ad97746
arm: Move hyp-mode entry code out of line.

This code is grottier than the rest of the start-of-day code and very specific to the software model we're developing on. Segregate it accordingly, by putting it in its own file.

xen/arch/arm/Makefile +1 -0
diff -r 25d389d891c5 -r 05447f395c91 xen/arch/arm/Makefile
@@ -12,6 +12,7 @@ obj-y += io.o
 obj-y += irq.o
 obj-y += kernel.o
 obj-y += mm.o
+obj-y += mode_switch.o
 obj-y += p2m.o
 obj-y += percpu.o
 obj-y += guestcopy.o
xen/arch/arm/head.S +3 -44

53 lines not on this page · raw message

xen/arch/arm/mode_switch.S new file +76 -0

76 lines not on this page · raw message

#3 lore raw

Re: [PATCH 2 of 6] arm: Move hyp-mode entry code out of line

Quoted 10 lines · Tim Deegan

# HG changeset patch
# User Tim Deegan <[email protected]>
# Date 1338482127 -3600
# Node ID 05447f395c91029fb732142e36788cfa92374045 # Parent 25d389d891c5a2a3009258ef7261379a9ad97746
arm: Move hyp-mode entry code out of line.

This code is grottier than the rest of the start-of-day code and very specific to the software model we're developing on. Segregate it accordingly, by putting it in its own file.

I've been vaguely thinking about writing a stub-bootloader to do this and provide the DTB (instead of having to link it with Xen). Is this something that would be useful?

David

#4 lore raw

Re: [PATCH 2 of 6] arm: Move hyp-mode entry code out of line

Quoted 8 lines · David Vrabel
Quoted 7 lines · Tim Deegan

# HG changeset patch
# User Tim Deegan <[email protected]>
# Date 1338482127 -3600
# Node ID 05447f395c91029fb732142e36788cfa92374045 # Parent 25d389d891c5a2a3009258ef7261379a9ad97746
arm: Move hyp-mode entry code out of line.

Quoted 7 lines
Quoted 3 lines

This code is grottier than the rest of the start-of-day code and very specific to the software model we're developing on. Segregate it accordingly, by putting it in its own file.

I've been vaguely thinking about writing a stub-bootloader to do this and provide the DTB (instead of having to link it with Xen). Is this something that would be useful?

Rather than a new stub-bootloader we should switch over to using the same boot-wrapper.git as Linaro and KVM are using[0], and perhaps enhancing it to meet our needs.

One benefit of that is that when they come to do stuff on real hardware we will already be somewhat aligned with something which looks a bit like a bootloader so it should be easier for us to transition too.

It also has other benefits like enabling us to use semi-hosting to pull the files off the host filesystem.

Ian.

[0] http://git.linaro.org/gitweb?p=arm/models/boot-wrapper.git;a=summary

author
#5 lore raw

PATCH 1/1 arm: avoid memory write in switch to Hyp mode

In reply to Tim Deegan

# HG changeset patch
# User Tim Deegan <[email protected]>
# Date 1338482127 -3600
# Node ID 8656509f24ea8b17d1c2dabd67c710662f66d17f # Parent 05447f395c91029fb732142e36788cfa92374045
arm: avoid memory write in switch to Hyp mode.

Assemble the new CPSR in registers instead. It's slightly cleaner, And makes it possible to have a read-only text section.

xen/arch/arm/mode_switch.S +4 -8
diff -r 05447f395c91 -r 8656509f24ea xen/arch/arm/mode_switch.S
@@ -66,11 +66,7 @@ enter_hyp_mode:
 	mcr   CP32(r0, FCSEIDR)
 	mcr   CP32(r0, CONTEXTIDR)
 	/* FIXME: ought to reset some other NS control regs here */
-	adr   r1, 1f                 /* Store return address */
-	str   r3, [r1]               /* where we can use it for RFE */
-	isb                          /* Ensure we see the stored address */
-	rfeia r1                     /* Enter Hyp mode */
-
-1:	.word 0                      /* PC to enter Hyp mode at */
-	.word 0x000001da             /* CPSR: LE, Abort/IRQ/FIQ off, Hyp */
-
+	mrs   r0, cpsr               /* Copy the CPSR */
+	add   r0, r0, #0x4           /* 0x16 (Monitor) -> 0x1a (Hyp) */
+	msr   spsr_cxsf, r0          /* into the SPSR */
+	movs  pc, r3                 /* Exception-return into Hyp mode */
#6 lore raw

Re: [PATCH 3 of 6] arm: avoid memory write in switch to Hyp mode

Quoted 20 lines · Tim Deegan

# HG changeset patch
# User Tim Deegan <[email protected]>
# Date 1338482127 -3600
# Node ID 8656509f24ea8b17d1c2dabd67c710662f66d17f # Parent 05447f395c91029fb732142e36788cfa92374045
arm: avoid memory write in switch to Hyp mode.

Assemble the new CPSR in registers instead. It's slightly cleaner, And makes it possible to have a read-only text section.

diff -r 05447f395c91 -r 8656509f24ea xen/arch/arm/mode_switch.S

xen/arch/arm/mode_switch.S +0 -1
@@ -66,11 +66,7 @@ enter_hyp_mode:
 	mcr   CP32(r0, FCSEIDR)
 	mcr   CP32(r0, CONTEXTIDR)
 	/* FIXME: ought to reset some other NS control regs here */
-	adr   r1, 1f                 /* Store return address */

xen/arch/arm/mode_switch.S enter_hyp_mode: · line 71

Quoted 10 lines
xen/arch/arm/mode_switch.S +3 -7
-	str   r3, [r1]               /* where we can use it for RFE */
-	isb                          /* Ensure we see the stored address */
-	rfeia r1                     /* Enter Hyp mode */
-
-1:	.word 0                      /* PC to enter Hyp mode at */
-	.word 0x000001da             /* CPSR: LE, Abort/IRQ/FIQ off, Hyp */
-
+	mrs   r0, cpsr               /* Copy the CPSR */
+	add   r0, r0, #0x4           /* 0x16 (Monitor) -> 0x1a (Hyp) */
+	msr   spsr_cxsf, r0          /* into the SPSR */

Not that it matters much but I think this could have been sprs_c to just update spsr[0:7] (which is all you wanted to touch). In fact I reckon you could have just done:

	mov r0, #0x1a|SPSR_I|SPSR_F
	msr spsr_c, r0

Anyway, I'm going to apply regardless because I'm just nitpicking...

Quoted 1 line
xen/arch/arm/mode_switch.S +1 -0
+	movs  pc, r3                 /* Exception-return into Hyp mode */
author
#7 lore raw

Re: [PATCH 3 of 6] arm: avoid memory write in switch to Hyp mode

Quoted 9 lines · Ian Campbell

xen/arch/arm/mode_switch.S enter_hyp_mode: · line 71

Quoted 3 lines
xen/arch/arm/mode_switch.S +3 -0
+	mrs   r0, cpsr               /* Copy the CPSR */
+	add   r0, r0, #0x4           /* 0x16 (Monitor) -> 0x1a (Hyp) */
+	msr   spsr_cxsf, r0          /* into the SPSR */

Not that it matters much but I think this could have been sprs_c to just update spsr[0:7] (which is all you wanted to touch). In fact I reckon you could have just done:

	mov r0, #0x1a|SPSR_I|SPSR_F
	msr spsr_c, r0

I considered that, but I don't think that anything in the path so far will have initialised this mode's SPSR to a sensible value, and I didn't want to accidentally turn on big-endian mode or some such.

Cheers,

Tim.

author
#8 lore raw

PATCH 1/1 arm: missing __init annotation

In reply to Tim Deegan

# HG changeset patch
# User Tim Deegan <[email protected]>
# Date 1338482127 -3600
# Node ID 89f363564aa68dcb78d3aedd6a0b24f9bb1ffc13 # Parent 8656509f24ea8b17d1c2dabd67c710662f66d17f
arm: missing __init annotation

xen/arch/arm/setup.c +1 -1
diff -r 8656509f24ea -r 89f363564aa6 xen/arch/arm/setup.c
@@ -51,7 +51,7 @@ static void __init init_idle_domain(void
         /* TODO: setup_idle_pagetable(); */
 }
 
-static void processor_id(void)
+static void __init processor_id(void)
 {
     printk("Processor Features: %08x %08x\n",
            READ_CP32(ID_PFR0), READ_CP32(ID_PFR0));
author
#9 lore raw

PATCH 1/1 arm: allow ourselves access to all coprocessors in non-secure mode

In reply to Tim Deegan

# HG changeset patch
# User Tim Deegan <[email protected]>
# Date 1338482127 -3600
# Node ID 9570c43c07f397d8d4a8e725698c17c10c034d80
# Parent 89f363564aa68dcb78d3aedd6a0b24f9bb1ffc13
arm: allow ourselves access to all coprocessors in non-secure mode

We'll need it to be able top use the VFP extensions, for example.

xen/arch/arm/mode_switch.S +4 -1
diff -r 89f363564aa6 -r 9570c43c07f3 xen/arch/arm/mode_switch.S
@@ -65,7 +65,10 @@ enter_hyp_mode:
 	mov   r0, #0
 	mcr   CP32(r0, FCSEIDR)
 	mcr   CP32(r0, CONTEXTIDR)
-	/* FIXME: ought to reset some other NS control regs here */
+	/* Allow non-secure access to coprocessors, FIQs, VFP and NEON */
+	ldr   r1, =0x3fff            /* 14 CP bits set, all others clear */
+	mcr   CP32(r1, NSACR)
+
 	mrs   r0, cpsr               /* Copy the CPSR */
 	add   r0, r0, #0x4           /* 0x16 (Monitor) -> 0x1a (Hyp) */
 	msr   spsr_cxsf, r0          /* into the SPSR */
author
#10 lore raw

PATCH 1/1 arm: Enable VFP at boot

In reply to Tim Deegan

# HG changeset patch
# User Tim Deegan <[email protected]>
# Date 1338482127 -3600
# Node ID d12d5fcf152bffda41de51f9919b3211d69f955b # Parent 9570c43c07f397d8d4a8e725698c17c10c034d80
arm: Enable VFP at boot.

xen/arch/arm/Rules.mk +1 -1
diff -r 9570c43c07f3 -r d12d5fcf152b xen/arch/arm/Rules.mk
@@ -24,7 +24,7 @@ ifneq ($(call cc-option,$(CC),-fvisibili
 CFLAGS += -DGCC_HAS_VISIBILITY_ATTRIBUTE
 endif
 
-CFLAGS += -march=armv7-a -mcpu=cortex-a15
+CFLAGS += -march=armv7-a -mcpu=cortex-a15 -mfpu=vfpv3 -mfloat-abi=softfp
 
 # Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers)
 check-$(gcc) = $(call cc-ver-check,CC,0x030400,"Xen requires at least gcc-3.4")
xen/arch/arm/setup.c +3 -0
diff -r 9570c43c07f3 -r d12d5fcf152b xen/arch/arm/setup.c
@@ -36,6 +36,7 @@
 #include <asm/page.h>
 #include <asm/current.h>
 #include <asm/setup.h>
+#include <asm/vfp.h>
 #include "gic.h"
 
 static __attribute_used__ void init_done(void)
@@ -192,6 +193,8 @@ void __init start_xen(unsigned long boot
 
     processor_id();
 
+    enable_vfp();
+
     softirq_init();
 
     tasklet_subsys_init();
xen/arch/arm/smpboot.c +3 -0
diff -r 9570c43c07f3 -r d12d5fcf152b xen/arch/arm/smpboot.c
@@ -26,6 +26,7 @@
 #include <xen/sched.h>
 #include <xen/smp.h>
 #include <xen/softirq.h>
+#include <asm/vfp.h>
 #include "gic.h"
 
 cpumask_t cpu_online_map;
@@ -106,6 +107,8 @@ void __cpuinit start_secondary(unsigned 
     WRITE_CP32((uint32_t) hyp_traps_vector, HVBAR);
 
     mmu_init_secondary_cpu();
+    enable_vfp();
+
     gic_init_secondary_cpu();
     init_timer_interrupt();
     gic_route_irqs();
xen/include/asm-arm/vfp.h new file +35 -0
diff -r 9570c43c07f3 -r d12d5fcf152b xen/include/asm-arm/vfp.h
@@ -0,0 +1,35 @@
+#ifndef __ARM_VFP_H_
+#define __ARM_VFP_H_
+
+#include <xen/types.h>
+
+#define FPEXC_EN (1u << 30)
+
+/* Save and restore FP state.
+ * Ought to be using the new vmrs/vmsr names, but older binutils has a
+ * bug where it only allows them to target fpscr (and not, say, fpexc). */
+#define READ_FP(reg) ({                                 \
+    uint32_t val;                                       \
+    asm volatile ("fmrx %0, fp" #reg : "=r" (val));     \
+    val; })
+
+#define WRITE_FP(reg, val) do {                         \
+    asm volatile ("fmxr fp" #reg ", %0" : : "r" (val)); \
+} while (0)
+
+
+/* Start-of-day: Turn on VFP */
+static inline void enable_vfp(void)
+{
+    WRITE_FP(exc, READ_FP(exc) | FPEXC_EN);
+}
+
+#endif
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
#11 lore raw

Re: [PATCH 6 of 6] arm: Enable VFP at boot

Quoted 6 lines · Tim Deegan

# HG changeset patch
# User Tim Deegan <[email protected]>
# Date 1338482127 -3600
# Node ID d12d5fcf152bffda41de51f9919b3211d69f955b # Parent 9570c43c07f397d8d4a8e725698c17c10c034d80
arm: Enable VFP at boot.

Thanks, this should mean I can remove "cluster.cpu0.vfp-enable_at_reset=1" from my fast model cfg file!

... tries it... yes it works, sweeet!

xen/arch/arm/Rules.mk ifneq ($(call cc-option,$(CC),-fvisibili · line 27

Quoted 12 lines

diff -r 9570c43c07f3 -r d12d5fcf152b xen/arch/arm/Rules.mk

xen/arch/arm/Rules.mk +1 -1
@@ -24,7 +24,7 @@ ifneq ($(call cc-option,$(CC),-fvisibili
 CFLAGS += -DGCC_HAS_VISIBILITY_ATTRIBUTE
 endif
 
-CFLAGS += -march=armv7-a -mcpu=cortex-a15
+CFLAGS += -march=armv7-a -mcpu=cortex-a15 -mfpu=vfpv3 -mfloat-abi=softfp

This might have been worthy of a comment...

http://wiki.debian.org/ArmHardFloatPort has some discussion, including:
* soft: Full software floating point.
* softfp: Use the FPU, but remain compatible with soft-float code.
* hard: Full hardware floating point.

and "The combination of -mfpu=vfp and -mfloat-abi=hard is not available in FSF GCC 4.4". (there's a reference to a TODO section which seems to not exist anymore...). I think Debian's armhf does actually use hard (the page seems to imply it)

Anyway softfp does seem like the right option, at least until -mfloat-abi=hard. Since this is all internal to the hypervisor (guests can do whatever they want, I'm happily running armhf binaries) I don't think this is a big deal to change as and when the compiler will let us.

Quoted 82 lines
xen/arch/arm/Rules.mk +0 -0
 # Require GCC v3.4+ (to avoid issues with alignment constraints in Xen headers)
 check-$(gcc) = $(call cc-ver-check,CC,0x030400,"Xen requires at least gcc-3.4")

diff -r 9570c43c07f3 -r d12d5fcf152b xen/arch/arm/setup.c

xen/arch/arm/setup.c +3 -0
@@ -36,6 +36,7 @@
 #include <asm/page.h>
 #include <asm/current.h>
 #include <asm/setup.h>
+#include <asm/vfp.h>
 #include "gic.h"
 
 static __attribute_used__ void init_done(void)
@@ -192,6 +193,8 @@ void __init start_xen(unsigned long boot
 
     processor_id();
 
+    enable_vfp();
+
     softirq_init();
 
     tasklet_subsys_init();

diff -r 9570c43c07f3 -r d12d5fcf152b xen/arch/arm/smpboot.c

xen/arch/arm/smpboot.c +3 -0
@@ -26,6 +26,7 @@
 #include <xen/sched.h>
 #include <xen/smp.h>
 #include <xen/softirq.h>
+#include <asm/vfp.h>
 #include "gic.h"
 
 cpumask_t cpu_online_map;
@@ -106,6 +107,8 @@ void __cpuinit start_secondary(unsigned 
     WRITE_CP32((uint32_t) hyp_traps_vector, HVBAR);
 
     mmu_init_secondary_cpu();
+    enable_vfp();
+
     gic_init_secondary_cpu();
     init_timer_interrupt();
     gic_route_irqs();

diff -r 9570c43c07f3 -r d12d5fcf152b xen/include/asm-arm/vfp.h

xen/include/asm-arm/vfp.h new file +35 -0
@@ -0,0 +1,35 @@
+#ifndef __ARM_VFP_H_
+#define __ARM_VFP_H_
+
+#include <xen/types.h>
+
+#define FPEXC_EN (1u << 30)
+
+/* Save and restore FP state.
+ * Ought to be using the new vmrs/vmsr names, but older binutils has a
+ * bug where it only allows them to target fpscr (and not, say, fpexc). */
+#define READ_FP(reg) ({                                 \
+    uint32_t val;                                       \
+    asm volatile ("fmrx %0, fp" #reg : "=r" (val));     \
+    val; })
+
+#define WRITE_FP(reg, val) do {                         \
+    asm volatile ("fmxr fp" #reg ", %0" : : "r" (val)); \
+} while (0)
+
+
+/* Start-of-day: Turn on VFP */
+static inline void enable_vfp(void)
+{
+    WRITE_FP(exc, READ_FP(exc) | FPEXC_EN);
+}
+
+#endif
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
author
#12 lore raw

Re: [PATCH 6 of 6] arm: Enable VFP at boot

Quoted 4 lines · Ian Campbell

xen/arch/arm/Rules.mk ifneq ($(call cc-option,$(CC),-fvisibili · line 27

Quoted 2 lines
xen/arch/arm/Rules.mk +1 -1
-CFLAGS += -march=armv7-a -mcpu=cortex-a15
+CFLAGS += -march=armv7-a -mcpu=cortex-a15 -mfpu=vfpv3 -mfloat-abi=softfp

This might have been worthy of a comment...

Ah, yes it might. Would you like me to add one and resubmit?

If I get time next week I'm going to look at VFP context switching; at that point I might move all the VFP code into its own .c or .S file and enable the fpu instructions just there, to be sure that gcc doesn't start using the VFP registers in normal Xen code -- it will do that for integer arithmetic with -mfpu=neon, for example. OTOH it might be OK to do that as long as there are no caller-save VFP registers; I'll have a look at the calling conventions and see what can be done.

Tim.

Quoted 16 lines

http://wiki.debian.org/ArmHardFloatPort has some discussion, including:
* soft: Full software floating point.
* softfp: Use the FPU, but remain compatible with soft-float code.
* hard: Full hardware floating point.

and "The combination of -mfpu=vfp and -mfloat-abi=hard is not available in FSF GCC 4.4". (there's a reference to a TODO section which seems to not exist anymore...). I think Debian's armhf does actually use hard (the page seems to imply it)

Anyway softfp does seem like the right option, at least until -mfloat-abi=hard. Since this is all internal to the hypervisor (guests can do whatever they want, I'm happily running armhf binaries) I don't think this is a big deal to change as and when the compiler will let us.

#13 lore raw

Re: [PATCH 6 of 6] arm: Enable VFP at boot

Quoted 7 lines · Tim Deegan
Quoted 4 lines · Ian Campbell

xen/arch/arm/Rules.mk ifneq ($(call cc-option,$(CC),-fvisibili · line 27

Quoted 2 lines
xen/arch/arm/Rules.mk +1 -1
-CFLAGS += -march=armv7-a -mcpu=cortex-a15
+CFLAGS += -march=armv7-a -mcpu=cortex-a15 -mfpu=vfpv3 -mfloat-abi=softfp

This might have been worthy of a comment...

Ah, yes it might. Would you like me to add one and resubmit?

I've already committed. If you feel like it then an incremental patch might be nice...

Quoted 7 lines

If I get time next week I'm going to look at VFP context switching; at that point I might move all the VFP code into its own .c or .S file and enable the fpu instructions just there, to be sure that gcc doesn't start using the VFP registers in normal Xen code -- it will do that for integer arithmetic with -mfpu=neon, for example. OTOH it might be OK to do that as long as there are no caller-save VFP registers; I'll have a look at the calling conventions and see what can be done.

OK!

#14 lore raw
In reply to Tim Deegan
Quoted 3 lines · Tim Deegan

These patches tinker with the ARM boot a little bit. They shouldn't clash with any of the other ARM work going on, since they only touch very early code.

All applied, thanks!