|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 10/17] xen: arm: define guest virtual platform in API headers
On Tue, 12 Nov 2013, Ian Campbell wrote:
> The tools and the hypervisor need to agree on various aspects of the guest
> environment, such as interrupt numbers, memory layout, initial register values
> for registers which are implementation defined etc. Therefore move the
> associated defines into the public interface headers, or create them as
> necessary.
>
> This just exposes the current de-facto standard guest layout, which may be
> subject to change in the future. This deliberately does not make the guest
> layout dynamic since there is currently no need.
>
> These values should not be exposed to guests, they should find these things
> out via device tree or should not be relying on implementation defined
> defaults.
>
> Various bits of the hypervisor needed to change to configure dom0 with the
> real
> platform values while using the virtual platform configuration for guests.
> Arrange for this where appropriate and plumb through as needed.
>
> We also need to expose some 64-bit values (e.g. PSR_GUEST64_INIT) for the
> benefit of 32 bit toolstacks building 64 bit guests.
>
> Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Acked-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
> v4: dropped a spurious aarch64 ifdef
> improved some comments and expand the commit message to clarify that this
> is just implementing the current static de-facto setup.
> put back PSR_GUEST32_INIT which disapeared somewhere along the line
> ---
> tools/libxc/xc_dom_arm.c | 4 +--
> xen/arch/arm/domain.c | 8 ++++--
> xen/arch/arm/domain_build.c | 13 +++++----
> xen/arch/arm/gic.c | 21 +++++++++-----
> xen/arch/arm/psci.c | 2 +-
> xen/arch/arm/traps.c | 2 +-
> xen/arch/arm/vtimer.c | 13 ++++++---
> xen/include/asm-arm/domain.h | 1 +
> xen/include/asm-arm/event.h | 3 +-
> xen/include/asm-arm/gic.h | 3 --
> xen/include/asm-arm/processor.h | 7 -----
> xen/include/asm-arm/psci.h | 5 ----
> xen/include/public/arch-arm.h | 58
> +++++++++++++++++++++++++++++++--------
> 13 files changed, 90 insertions(+), 50 deletions(-)
>
> diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
> index df59ffb..9f3fdd3 100644
> --- a/tools/libxc/xc_dom_arm.c
> +++ b/tools/libxc/xc_dom_arm.c
> @@ -126,13 +126,13 @@ static int vcpu_arm(struct xc_dom_image *dom, void *ptr)
> */
> ctxt->user_regs.r2_usr = 0xffffffff;
>
> - ctxt->sctlr = /* #define SCTLR_BASE */0x00c50078;
> + ctxt->sctlr = SCTLR_GUEST_INIT;
>
> ctxt->ttbr0 = 0;
> ctxt->ttbr1 = 0;
> ctxt->ttbcr = 0; /* Defined Reset Value */
>
> - ctxt->user_regs.cpsr =
> PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC;
> + ctxt->user_regs.cpsr = PSR_GUEST32_INIT;
>
> ctxt->flags = VGCF_online;
>
> diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
> index 5ff7adf..2f57d01 100644
> --- a/xen/arch/arm/domain.c
> +++ b/xen/arch/arm/domain.c
> @@ -461,7 +461,8 @@ int vcpu_initialise(struct vcpu *v)
> if ( is_idle_vcpu(v) )
> return rc;
>
> - v->arch.sctlr = SCTLR_BASE;
> + v->arch.sctlr = SCTLR_GUEST_INIT;
> +
> /*
> * By default exposes an SMP system with AFF0 set to the VCPU ID
> * TODO: Handle multi-threading processor and cluster
> @@ -525,6 +526,9 @@ int arch_domain_create(struct domain *d, unsigned int
> domcr_flags)
> if ( (rc = vcpu_domain_init(d)) != 0 )
> goto fail;
>
> + /* XXX dom0 needs more intelligent selection of PPI */
> + d->arch.evtchn_irq = GUEST_EVTCHN_PPI;
> +
> /*
> * Virtual UART is only used by linux early printk and decompress code.
> * Only use it for dom0 because the linux kernel may not support
> @@ -740,7 +744,7 @@ void vcpu_mark_events_pending(struct vcpu *v)
> if ( already_pending )
> return;
>
> - vgic_vcpu_inject_irq(v, VGIC_IRQ_EVTCHN_CALLBACK, 1);
> + vgic_vcpu_inject_irq(v, v->domain->arch.evtchn_irq, 1);
> }
>
> /*
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index 5232d1f..3d04274 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -315,7 +315,8 @@ static int make_memory_node(struct domain *d,
> return res;
> }
>
> -static int make_hypervisor_node(void *fdt, const struct dt_device_node
> *parent)
> +static int make_hypervisor_node(struct domain *d,
> + void *fdt, const struct dt_device_node
> *parent)
> {
> const char compat[] =
> "xen,xen-"__stringify(XEN_VERSION)"."__stringify(XEN_SUBVERSION)"\0"
> @@ -363,8 +364,8 @@ static int make_hypervisor_node(void *fdt, const struct
> dt_device_node *parent)
> *
> * TODO: Handle correctly the cpumask
> */
> - DPRINT(" Event channel interrupt to %u\n", VGIC_IRQ_EVTCHN_CALLBACK);
> - set_interrupt_ppi(intr, VGIC_IRQ_EVTCHN_CALLBACK, 0xf,
> + DPRINT(" Event channel interrupt to %u\n", d->arch.evtchn_irq);
> + set_interrupt_ppi(intr, d->arch.evtchn_irq, 0xf,
> DT_IRQ_TYPE_LEVEL_LOW);
>
> res = fdt_property_interrupts(fdt, &intr, 1);
> @@ -395,11 +396,11 @@ static int make_psci_node(void *fdt, const struct
> dt_device_node *parent)
> if ( res )
> return res;
>
> - res = fdt_property_cell(fdt, "cpu_off", __PSCI_cpu_off);
> + res = fdt_property_cell(fdt, "cpu_off", PSCI_cpu_off);
> if ( res )
> return res;
>
> - res = fdt_property_cell(fdt, "cpu_on", __PSCI_cpu_on);
> + res = fdt_property_cell(fdt, "cpu_on", PSCI_cpu_on);
> if ( res )
> return res;
>
> @@ -804,7 +805,7 @@ static int handle_node(struct domain *d, struct
> kernel_info *kinfo,
> if ( res )
> return res;
>
> - res = make_hypervisor_node(kinfo->fdt, np);
> + res = make_hypervisor_node(d, kinfo->fdt, np);
> if ( res )
> return res;
>
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index 74575cd..33c6b8d 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -717,7 +717,7 @@ int gic_events_need_delivery(void)
> void gic_inject(void)
> {
> if ( vcpu_info(current, evtchn_upcall_pending) )
> - vgic_vcpu_inject_irq(current, VGIC_IRQ_EVTCHN_CALLBACK, 1);
> + vgic_vcpu_inject_irq(current, current->domain->arch.evtchn_irq, 1);
>
> gic_restore_pending_irqs(current);
> if (!gic_events_need_delivery())
> @@ -823,13 +823,20 @@ void gic_interrupt(struct cpu_user_regs *regs, int
> is_fiq)
>
> int gicv_setup(struct domain *d)
> {
> - /* TODO: Retrieve distributor and CPU guest base address from the
> - * guest DTS
> - * For the moment we use dom0 DTS
> + /*
> + * Domain 0 gets the hardware address.
> + * Guests get the virtual platform layout.
> */
> - d->arch.vgic.dbase = gic.dbase;
> - d->arch.vgic.cbase = gic.cbase;
> -
> + if ( d == dom0 )
> + {
> + d->arch.vgic.dbase = gic.dbase;
> + d->arch.vgic.cbase = gic.cbase;
> + }
> + else
> + {
> + d->arch.vgic.dbase = GUEST_GICD_BASE;
> + d->arch.vgic.cbase = GUEST_GICC_BASE;
> + }
>
> d->arch.vgic.nr_lines = 0;
>
> diff --git a/xen/arch/arm/psci.c b/xen/arch/arm/psci.c
> index 6c3be47..c82884f 100644
> --- a/xen/arch/arm/psci.c
> +++ b/xen/arch/arm/psci.c
> @@ -43,7 +43,7 @@ int do_psci_cpu_on(uint32_t vcpuid, register_t entry_point)
>
> memset(ctxt, 0, sizeof(*ctxt));
> ctxt->user_regs.pc64 = (u64) entry_point;
> - ctxt->sctlr = SCTLR_BASE;
> + ctxt->sctlr = SCTLR_GUEST_INIT;
> ctxt->ttbr0 = 0;
> ctxt->ttbr1 = 0;
> ctxt->ttbcr = 0; /* Defined Reset Value */
> diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
> index 287dd7b..f64b2b8 100644
> --- a/xen/arch/arm/traps.c
> +++ b/xen/arch/arm/traps.c
> @@ -870,7 +870,7 @@ typedef struct {
> } arm_psci_t;
>
> #define PSCI(_name, _nr_args) \
> - [ __PSCI_ ## _name ] = { \
> + [ PSCI_ ## _name ] = { \
> .fn = (arm_psci_fn_t) &do_psci_ ## _name, \
> .nr_args = _nr_args, \
> }
> diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c
> index d58a630..f323453 100644
> --- a/xen/arch/arm/vtimer.c
> +++ b/xen/arch/arm/vtimer.c
> @@ -54,21 +54,26 @@ int vcpu_domain_init(struct domain *d)
> int vcpu_vtimer_init(struct vcpu *v)
> {
> struct vtimer *t = &v->arch.phys_timer;
> + bool_t d0 = (v->domain == dom0);
>
> - /* TODO: Retrieve physical and virtual timer IRQ from the guest
> - * DT. For the moment we use dom0 DT
> + /*
> + * Domain 0 uses the hardware interrupts, guests get the virtual
> platform.
> */
>
> init_timer(&t->timer, phys_timer_expired, t, v->processor);
> t->ctl = 0;
> t->cval = NOW();
> - t->irq = timer_dt_irq(TIMER_PHYS_NONSECURE_PPI)->irq;
> + t->irq = d0
> + ? timer_dt_irq(TIMER_PHYS_NONSECURE_PPI)->irq
> + : GUEST_TIMER_PHYS_NS_PPI;
> t->v = v;
>
> t = &v->arch.virt_timer;
> init_timer(&t->timer, virt_timer_expired, t, v->processor);
> t->ctl = 0;
> - t->irq = timer_dt_irq(TIMER_VIRT_PPI)->irq;
> + t->irq = d0
> + ? timer_dt_irq(TIMER_VIRT_PPI)->irq
> + : GUEST_TIMER_VIRT_PPI;
> t->v = v;
>
> return 0;
> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
> index 67bfbbc..53847a9 100644
> --- a/xen/include/asm-arm/domain.h
> +++ b/xen/include/asm-arm/domain.h
> @@ -112,6 +112,7 @@ struct arch_domain
> spinlock_t lock;
> } vuart;
>
> + int evtchn_irq;
> } __cacheline_aligned;
>
> struct arch_vcpu
> diff --git a/xen/include/asm-arm/event.h b/xen/include/asm-arm/event.h
> index 04d854f..dd3ad13 100644
> --- a/xen/include/asm-arm/event.h
> +++ b/xen/include/asm-arm/event.h
> @@ -15,7 +15,8 @@ static inline int vcpu_event_delivery_is_enabled(struct
> vcpu *v)
>
> static inline int local_events_need_delivery_nomask(void)
> {
> - struct pending_irq *p = irq_to_pending(current,
> VGIC_IRQ_EVTCHN_CALLBACK);
> + struct pending_irq *p = irq_to_pending(current,
> + current->domain->arch.evtchn_irq);
>
> /* XXX: if the first interrupt has already been delivered, we should
> * check whether any other interrupts with priority higher than the
> diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
> index 0a890be..41f0b3b 100644
> --- a/xen/include/asm-arm/gic.h
> +++ b/xen/include/asm-arm/gic.h
> @@ -129,9 +129,6 @@
> #define GICH_LR_CPUID_SHIFT 9
> #define GICH_VTR_NRLRGS 0x3f
>
> -/* XXX: write this into the DT */
> -#define VGIC_IRQ_EVTCHN_CALLBACK 31
> -
> #ifndef __ASSEMBLY__
> #include <xen/device_tree.h>
>
> diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
> index 5294421..3da3a3d 100644
> --- a/xen/include/asm-arm/processor.h
> +++ b/xen/include/asm-arm/processor.h
> @@ -48,15 +48,8 @@
> #define SCTLR_A (1<<1)
> #define SCTLR_M (1<<0)
>
> -#define SCTLR_BASE 0x00c50078
> #define HSCTLR_BASE 0x30c51878
>
> -#define PSR_GUEST32_INIT
> (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC)
> -
> -#ifdef CONFIG_ARM_64
> -#define PSR_GUEST64_INIT
> (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_EL1h)
> -#endif
> -
> /* HCR Hyp Configuration Register */
> #define HCR_RW (1<<31) /* Register Width, ARM64 only */
> #define HCR_TGE (1<<27) /* Trap General Exceptions */
> diff --git a/xen/include/asm-arm/psci.h b/xen/include/asm-arm/psci.h
> index fdba636..67d4c35 100644
> --- a/xen/include/asm-arm/psci.h
> +++ b/xen/include/asm-arm/psci.h
> @@ -6,11 +6,6 @@
> #define PSCI_EINVAL -2
> #define PSCI_DENIED -3
>
> -#define __PSCI_cpu_suspend 0
> -#define __PSCI_cpu_off 1
> -#define __PSCI_cpu_on 2
> -#define __PSCI_migrate 3
> -
> int do_psci_cpu_on(uint32_t vcpuid, register_t entry_point);
> int do_psci_cpu_off(uint32_t power_state);
> int do_psci_cpu_suspend(uint32_t power_state, register_t entry_point);
> diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
> index 1e8aeda..cb41ddc 100644
> --- a/xen/include/public/arch-arm.h
> +++ b/xen/include/public/arch-arm.h
> @@ -302,8 +302,19 @@ typedef uint64_t xen_callback_t;
>
> #endif
>
> +#if defined(__XEN__) || defined(__XEN_TOOLS__)
> +
> /* PSR bits (CPSR, SPSR)*/
>
> +#define PSR_THUMB (1<<5) /* Thumb Mode enable */
> +#define PSR_FIQ_MASK (1<<6) /* Fast Interrupt mask */
> +#define PSR_IRQ_MASK (1<<7) /* Interrupt mask */
> +#define PSR_ABT_MASK (1<<8) /* Asynchronous Abort mask */
> +#define PSR_BIG_ENDIAN (1<<9) /* arm32: Big Endian Mode */
> +#define PSR_DBG_MASK (1<<9) /* arm64: Debug Exception mask */
> +#define PSR_IT_MASK (0x0600fc00) /* Thumb If-Then Mask */
> +#define PSR_JAZELLE (1<<24) /* Jazelle Mode */
> +
> /* 32 bit modes */
> #define PSR_MODE_USR 0x10
> #define PSR_MODE_FIQ 0x11
> @@ -316,7 +327,6 @@ typedef uint64_t xen_callback_t;
> #define PSR_MODE_SYS 0x1f
>
> /* 64 bit modes */
> -#ifdef __aarch64__
> #define PSR_MODE_BIT 0x10 /* Set iff AArch32 */
> #define PSR_MODE_EL3h 0x0d
> #define PSR_MODE_EL3t 0x0c
> @@ -325,18 +335,44 @@ typedef uint64_t xen_callback_t;
> #define PSR_MODE_EL1h 0x05
> #define PSR_MODE_EL1t 0x04
> #define PSR_MODE_EL0t 0x00
> -#endif
>
> -#define PSR_THUMB (1<<5) /* Thumb Mode enable */
> -#define PSR_FIQ_MASK (1<<6) /* Fast Interrupt mask */
> -#define PSR_IRQ_MASK (1<<7) /* Interrupt mask */
> -#define PSR_ABT_MASK (1<<8) /* Asynchronous Abort mask */
> -#define PSR_BIG_ENDIAN (1<<9) /* Big Endian Mode */
> -#ifdef __aarch64__ /* For Aarch64 bit 9 is repurposed. */
> -#define PSR_DBG_MASK (1<<9)
> +#define PSR_GUEST32_INIT
> (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC)
> +#define PSR_GUEST64_INIT
> (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_EL1h)
> +
> +#define SCTLR_GUEST_INIT 0x00c50078
> +
> +/*
> + * Virtual machine platform (memory layout, interrupts)
> + *
> + * These are defined for consistency between the tools and the
> + * hypervisor. Guests must not rely on these hardcoded values but
> + * should instead use the FDT.
> + */
> +
> +/* Physical Address Space */
> +#define GUEST_GICD_BASE 0x2c001000ULL
> +#define GUEST_GICD_SIZE 0x1000ULL
> +#define GUEST_GICC_BASE 0x2c002000ULL
> +#define GUEST_GICC_SIZE 0x100ULL
> +
> +#define GUEST_RAM_BASE 0x80000000ULL
> +
> +#define GUEST_GNTTAB_BASE 0xb0000000ULL
> +#define GUEST_GNTTAB_SIZE 0x00020000ULL
> +
> +/* Interrupts */
> +#define GUEST_TIMER_VIRT_PPI 27
> +#define GUEST_TIMER_PHYS_S_PPI 29
> +#define GUEST_TIMER_PHYS_NS_PPI 30
> +#define GUEST_EVTCHN_PPI 31
> +
> +/* PSCI functions */
> +#define PSCI_cpu_suspend 0
> +#define PSCI_cpu_off 1
> +#define PSCI_cpu_on 2
> +#define PSCI_migrate 3
> +
> #endif
> -#define PSR_IT_MASK (0x0600fc00) /* Thumb If-Then Mask */
> -#define PSR_JAZELLE (1<<24) /* Jazelle Mode */
>
> #endif /* __XEN_PUBLIC_ARCH_ARM_H__ */
>
> --
> 1.7.10.4
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |