diff options
author | Julien Grall <julien.grall@linaro.org> | 2013-04-26 19:53:17 +0100 |
---|---|---|
committer | Ian Campbell <ian.campbell@citrix.com> | 2013-05-13 11:59:59 +0100 |
commit | 699f48cd134f6cf92375f0b00fcb67cffc8f40b4 (patch) | |
tree | 260a846362104c913ed0305ecd5a5a6f30d8a56d | |
parent | f5bde3da40ea79cbd4a1ab4de28e46e338bf7486 (diff) | |
download | xen-699f48cd134f6cf92375f0b00fcb67cffc8f40b4.tar.gz xen-699f48cd134f6cf92375f0b00fcb67cffc8f40b4.tar.bz2 xen-699f48cd134f6cf92375f0b00fcb67cffc8f40b4.zip |
xen/arm: Don't hardcode VGIC informations
- Define VGIC base address per domain. For the moment the base addresses
to dom0 base addresses.
- The number of interrupt lines (ie number of SPIs) is equal to:
* 0 for guests
* number of host SPIs for dom0
Signed-off-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
-rw-r--r-- | xen/arch/arm/gic.c | 21 | ||||
-rw-r--r-- | xen/arch/arm/vgic.c | 20 | ||||
-rw-r--r-- | xen/include/asm-arm/domain.h | 5 | ||||
-rw-r--r-- | xen/include/asm-arm/gic.h | 3 |
4 files changed, 39 insertions, 10 deletions
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index f69f86a69b..821f6836bf 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -56,6 +56,11 @@ static DEFINE_PER_CPU(uint64_t, lr_mask); static unsigned nr_lrs; +unsigned int gic_number_lines(void) +{ + return gic.lines; +} + irq_desc_t *__irq_to_desc(int irq) { if (irq < NR_LOCAL_IRQS) return &this_cpu(local_irq_desc)[irq]; @@ -775,11 +780,21 @@ 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 + */ + d->arch.vgic.dbase = gic.dbase; + d->arch.vgic.cbase = gic.cbase; + + + d->arch.vgic.nr_lines = 0; + /* map the gic virtual cpu interface in the gic cpu interface region of * the guest */ - return map_mmio_regions(d, gic.cbase, - gic.cbase + (2 * PAGE_SIZE) - 1, - gic.vbase); + return map_mmio_regions(d, d->arch.vgic.cbase, + d->arch.vgic.cbase + (2 * PAGE_SIZE) - 1, + gic.vbase); } static void gic_irq_eoi(void *info) diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c index f9c1a6b26e..7eaccb7eee 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -30,8 +30,6 @@ #include "io.h" #include <asm/gic.h> -#define VGIC_DISTR_BASE_ADDRESS 0x000000002c001000 - #define REG(n) (n/4) /* Number of ranks of interrupt registers for a domain */ @@ -80,7 +78,15 @@ int domain_vgic_init(struct domain *d) int i; d->arch.vgic.ctlr = 0; - d->arch.vgic.nr_lines = 32; + + /* Currently nr_lines in vgic and gic doesn't have the same meanings + * Here nr_lines = number of SPIs + */ + if ( d->domain_id == 0 ) + d->arch.vgic.nr_lines = gic_number_lines() - 32; + else + d->arch.vgic.nr_lines = 0; /* We don't need SPIs for the guest */ + d->arch.vgic.shared_irqs = xmalloc_array(struct vgic_irq_rank, DOMAIN_NR_RANKS(d)); d->arch.vgic.pending_irqs = @@ -163,7 +169,7 @@ static int vgic_distr_mmio_read(struct vcpu *v, mmio_info_t *info) struct cpu_user_regs *regs = guest_cpu_user_regs(); register_t *r = select_user_reg(regs, dabt.reg); struct vgic_irq_rank *rank; - int offset = (int)(info->gpa - VGIC_DISTR_BASE_ADDRESS); + int offset = (int)(info->gpa - v->domain->arch.vgic.dbase); int gicd_reg = REG(offset); switch ( gicd_reg ) @@ -440,7 +446,7 @@ static int vgic_distr_mmio_write(struct vcpu *v, mmio_info_t *info) struct cpu_user_regs *regs = guest_cpu_user_regs(); register_t *r = select_user_reg(regs, dabt.reg); struct vgic_irq_rank *rank; - int offset = (int)(info->gpa - VGIC_DISTR_BASE_ADDRESS); + int offset = (int)(info->gpa - v->domain->arch.vgic.dbase); int gicd_reg = REG(offset); uint32_t tr; @@ -620,7 +626,9 @@ write_ignore: static int vgic_distr_mmio_check(struct vcpu *v, paddr_t addr) { - return addr >= VGIC_DISTR_BASE_ADDRESS && addr < (VGIC_DISTR_BASE_ADDRESS+PAGE_SIZE); + struct domain *d = v->domain; + + return (addr >= (d->arch.vgic.dbase)) && (addr < (d->arch.vgic.dbase + PAGE_SIZE)); } const struct mmio_handler vgic_distr_mmio_handler = { diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h index cca7416f31..cb251cc250 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -88,13 +88,16 @@ struct arch_domain */ spinlock_t lock; int ctlr; - int nr_lines; + int nr_lines; /* Number of SPIs */ struct vgic_irq_rank *shared_irqs; /* * SPIs are domain global, SGIs and PPIs are per-VCPU and stored in * struct arch_vcpu. */ struct pending_irq *pending_irqs; + /* Base address for guest GIC */ + paddr_t dbase; /* Distributor base address */ + paddr_t cbase; /* CPU base address */ } vgic; struct vpl011 { diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 6ff217c231..e7608dc00b 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -189,6 +189,9 @@ extern void send_SGI_allbutself(enum gic_sgi sgi); /* print useful debug info */ extern void gic_dump_info(struct vcpu *v); +/* Number of interrupt lines */ +extern unsigned int gic_number_lines(void); + /* IRQ translation function for the device tree */ int gic_irq_xlate(const u32 *intspec, unsigned int intsize, unsigned int *out_hwirq, unsigned int *out_type); |