|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [RFC 28/29] xen/arm: Support secondary cpus boot and switch to hypervisor for the exynos5
On Mon, 2013-04-29 at 00:02 +0100, Julien Grall wrote:
> Use machine ID to know what is the current board. This value is only given
> to the first CPU by the bootloader.
>
> When the exynos 5 starts, there is only one CPU up. Xen needs to start the
> secondary cpu. The latter boots in secure mode.
Please can you put a big note here about the temporary nature of these
hacks and the eventual move to a boot-wrapper like setup?
>
> Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>
> ---
> xen/arch/arm/arm32/head.S | 19 +++++++-
> xen/arch/arm/arm32/mode_switch.S | 74
> ++++++++++++++++++++++--------
> xen/include/asm-arm/platforms/vexpress.h | 11 +++++
> 3 files changed, 85 insertions(+), 19 deletions(-)
>
> diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S
> index 55781cd..f701bc0 100644
> --- a/xen/arch/arm/arm32/head.S
> +++ b/xen/arch/arm/arm32/head.S
> @@ -72,7 +72,7 @@ past_zImage:
> cpsid aif /* Disable all interrupts */
>
> /* Save the bootloader arguments in less-clobberable registers */
> - /* No need to save r1 == Unused ARM-linux machine type */
> + mov r5, r1 /* r5: ARM-linux machine type */
:=
> mov r8, r2 /* r8 := DTB base address */
>
> /* Find out where we are */
> @@ -122,6 +122,20 @@ boot_cpu:
> teq r12, #0
> bleq kick_cpus
>
> + /* Secondary CPUs doesn't have machine ID
> + * - Store machine on boot CPU
> + * - Load machine ID on secondary CPUs */
> + ldr r0, =machine_id /* VA of machine_id */
> + add r0, r0, r10 /* PA of machine_id */
> + teq r12, #0
> + streq r5, [r0] /* On boot CPU save machine ID */
You never read this. Keeping it solely in r5 in head.S will help avoid
these hacks leaking further into Xen.
> + ldrne r5, [r0] /* If non boot cpu r5 := machine ID
> */
> +
> + PRINT("- Machine ID ")
> + mov r0, r5
> + bl putn
> + PRINT(" -\r\n")
This is after the call to kick_cpus, which appears to want to use the
result?
Since this is a hack to workaround insufficient firmware I'd prefer to
keep the body of this outside of head.S, can we follow a pattern like
how we deal with cortex_a15_init?
> +
> /* Check that this CPU has Hyp mode */
> mrc CP32(r0, ID_PFR1)
> and r0, r0, #0xf000 /* Bits 12-15 define virt extensions */
> @@ -402,6 +416,9 @@ putn: mov pc, lr
>
> #endif /* !EARLY_PRINTK */
>
> +/* Place holder for machine ID */
> +machine_id: .word 0x0
> +
> /*
> * Local variables:
> * mode: ASM
> diff --git a/xen/arch/arm/arm32/mode_switch.S
> b/xen/arch/arm/arm32/mode_switch.S
> index d6741d0..ab40f18 100644
> --- a/xen/arch/arm/arm32/mode_switch.S
> +++ b/xen/arch/arm/arm32/mode_switch.S
> @@ -20,14 +20,20 @@
> #include <asm/config.h>
> #include <asm/page.h>
> #include <asm/platforms/vexpress.h>
> +#include <asm/platforms/exynos5.h>
> #include <asm/asm_defns.h>
> #include <asm/gic.h>
>
> -
> -/* XXX: Versatile Express specific code */
> -/* wake up secondary cpus */
> +/* Wake up secondary cpus
> + * This code relies on Machine ID and only works for Vexpress and the Arndale
> + * TODO: Move this code either later (via platform specific desc) or in a
> bootwrapper
> + * r5: Machine ID
> + * Clobber r0 r2 */
> .globl kick_cpus
> kick_cpus:
> + ldr r0, =MACH_TYPE_SMDK5250
> + teq r5, r0 /* Are we running on the
> arndale? */
> + beq kick_cpus_arndale
Can you add:
/* Otherwise vexpress */
where we fall through here. Or even better if we are going to have this
hack lets just check for the vexpress machid too.
> /* write start paddr to v2m sysreg FLAGSSET register */
> ldr r0, =(V2M_SYS_MMIO_BASE) /* base V2M sysreg MMIO
> address */
> dsb
> @@ -38,8 +44,20 @@ kick_cpus:
> add r2, r2, r10
> str r2, [r0, #(V2M_SYS_FLAGSSET)]
> dsb
> + ldr r2, =V2M_GIC_BASE_ADDRESS /* r2 := VE gic base address */
> + b kick_cpus_sgi
> +kick_cpus_arndale:
> + /* write start paddr to CPU 1 sysreg register */
> + ldr r0, =(S5P_PA_SYSRAM)
> + ldr r2, =start
> + add r2, r2, r10
> + str r2, [r0]
> + dsb
> + ldr r2, =EXYNOS5_GIC_BASE_ADDRESS /* r2 := Exynos5 gic base
> address */
> +kick_cpus_sgi:
> /* send an interrupt */
> - ldr r0, =(GIC_BASE_ADDRESS + GIC_DR_OFFSET) /* base GICD MMIO
> address */
> + ldr r0, =GIC_DR_OFFSET /* GIC distributor offset */
> + add r0, r2 /* r0 := r0 + gic base address
> */
> mov r2, #0x1
> str r2, [r0, #(GICD_CTLR * 4)] /* enable distributor */
> mov r2, #0xfe0000
> @@ -51,13 +69,15 @@ kick_cpus:
>
> /* Get up a CPU into Hyp mode. Clobbers r0-r3.
> *
> - * Expects r12 == CPU number
> + * r5: Machine ID
> + * r12: CPU number
> *
> - * This code is specific to the VE model, and not intended to be used
> + * This code is specific to the VE model/Arndale, and not intended to be used
> * on production systems. As such it's a bit hackier than the main
> * boot code in head.S. In future it will be replaced by better
> * integration with the bootloader/firmware so that Xen always starts
> - * in Hyp mode. */
> + * in Hyp mode.
> + * Clobber r0 - r4 */
>
> .globl enter_hyp_mode
> enter_hyp_mode:
> @@ -68,33 +88,51 @@ enter_hyp_mode:
> orr r0, r0, #0xb1 /* Set SCD, AW, FW and NS */
> bic r0, r0, #0xe /* Clear EA, FIQ and IRQ */
> mcr CP32(r0, SCR)
> +
> + ldr r2, =MACH_TYPE_SMDK5250 /* r4 := Arndale machine ID */
> + /* By default load Arndale defaults values */
> + ldr r0, =EXYNOS5_TIMER_FREQUENCY /* r0 := timer's frequency */
> + ldr r1, =EXYNOS5_GIC_BASE_ADDRESS /* r1 := GIC base address */
> + /* If it's not the Arndale machine ID, load VE values */
> + teq r5, r2
> + ldrne r0, =V2M_TIMER_FREQUENCY
> + ldrne r1, =V2M_GIC_BASE_ADDRESS
Are these processor or platform specific? If processor can they be
handled like how proc-ca15.S:cortex_a15_init does things?
> +
> /* Ugly: the system timer's frequency register is only
> * programmable in Secure state. Since we don't know where its
> * memory-mapped control registers live, we can't find out the
> - * right frequency. Use the VE model's default frequency here. */
> - ldr r0, =0x5f5e100 /* 100 MHz */
> + * right frequency. */
> mcr CP32(r0, CNTFRQ)
> ldr r0, =0x40c00 /* SMP, c11, c10 in non-secure mode */
> mcr CP32(r0, NSACR)
> - mov r0, #GIC_BASE_ADDRESS
> - add r0, r0, #GIC_DR_OFFSET
> +
> + add r0, r1, #GIC_DR_OFFSET
> /* Disable the GIC distributor, on the boot CPU only */
> - mov r1, #0
> + mov r4, #0
> teq r12, #0 /* Is this the boot CPU? */
> - streq r1, [r0]
> + streq r4, [r0]
> /* Continuing ugliness: Set up the GIC so NS state owns interrupts,
> * The first 32 interrupts (SGIs & PPIs) must be configured on all
> * CPUs while the remainder are SPIs and only need to be done one, on
> * the boot CPU. */
> add r0, r0, #0x80 /* GICD_IGROUP0 */
> mov r2, #0xffffffff /* All interrupts to group 1 */
> - teq r12, #0 /* Boot CPU? */
> str r2, [r0] /* Interrupts 0-31 (SGI & PPI) */
> - streq r2, [r0, #4] /* Interrupts 32-63 (SPI) */
> - streq r2, [r0, #8] /* Interrupts 64-95 (SPI) */
> + teq r12, #0 /* Boot CPU? */
> + bne skip_spis /* Don't route SPIs on secondary CPUs */
> +
> + add r4, r1, #GIC_DR_OFFSET
> + ldr r4, [r4, #4] /* r4 := Interrupt Controller Type Reg
> */
> + and r4, r4, #GICD_TYPE_LINES /* r4 := number of SPIs */
> + /* Assume we have minimum 32 SPIs */
It'd be relatively easy to turn this do {} while construct into a
while() {} one and avoid this assumption?
> +1:
> + add r0, r0, #4 /* Go to the new group */
> + str r2, [r0] /* Update the group */
> + subs r4, r4, #1
> + bne 1b
> +skip_spis:
> /* Disable the GIC CPU interface on all processors */
> - mov r0, #GIC_BASE_ADDRESS
> - add r0, r0, #GIC_CR_OFFSET
> + add r0, r1, #GIC_CR_OFFSET
> mov r1, #0
> str r1, [r0]
> /* Must drop priority mask below 0x80 before entering NS state */
> diff --git a/xen/include/asm-arm/platforms/vexpress.h
> b/xen/include/asm-arm/platforms/vexpress.h
> index 5cf3aba..982a293 100644
> --- a/xen/include/asm-arm/platforms/vexpress.h
> +++ b/xen/include/asm-arm/platforms/vexpress.h
> @@ -32,6 +32,17 @@
> int vexpress_syscfg(int write, int function, int device, uint32_t *data);
> #endif
>
> +/* Constants below is only used in assembly because the DTS is not yet
> parsed */
> +#ifdef __ASSEMBLY__
> +
> +/* GIC base address */
> +#define V2M_GIC_BASE_ADDRESS 0x2c000000
> +
> +/* Timer's frequency */
> +#define V2M_TIMER_FREQUENCY 0x5f5e100 /* 100 Mhz */
> +
> +#endif /* __ASSEMBLY__ */
> +
> #endif /* __ASM_ARM_PLATFORMS_VEXPRESS_H */
> /*
> * Local variables:
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |