[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [RFC PATCH v1 09/10] xen/arm: Add vgic support for GIC v3
On Wed, 19 Mar 2014, vijay.kilari@xxxxxxxxx wrote: > From: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx> > > Add vgic driver support for GIC v3 version. > > Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx> > --- > xen/arch/arm/Makefile | 2 +- > xen/arch/arm/vgic-v3.c | 927 > +++++++++++++++++++++++++++++++++++++++++++++ > xen/arch/arm/vgic.c | 12 + > xen/include/asm-arm/gic.h | 1 + > 4 files changed, 941 insertions(+), 1 deletion(-) > > diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile > index a11c699..5a6cb07 100644 > --- a/xen/arch/arm/Makefile > +++ b/xen/arch/arm/Makefile > @@ -26,7 +26,7 @@ obj-y += smpboot.o > obj-y += smp.o > obj-y += shutdown.o > obj-y += traps.o > -obj-y += vgic.o vgic-v2.o > +obj-y += vgic.o vgic-v2.o vgic-v3.o > obj-y += vtimer.o > obj-y += vuart.o > obj-y += hvm.o > diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c > new file mode 100644 > index 0000000..b5c1d1e > --- /dev/null > +++ b/xen/arch/arm/vgic-v3.c > @@ -0,0 +1,927 @@ > +/* > + * xen/arch/arm/vgic-v3.c > + * > + * ARM Virtual Generic Interrupt Controller v3 support > + * based on xen/arch/arm/vgic.c > + * > + * Vijaya Kumar K <vijaya.kumar@xxxxxxxxxxxxxxxxxx> > + * Copyright (c) 2014 Cavium Inc. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include <xen/bitops.h> > +#include <xen/config.h> > +#include <xen/lib.h> > +#include <xen/init.h> > +#include <xen/softirq.h> > +#include <xen/irq.h> > +#include <xen/sched.h> > + > +#include <asm/current.h> > + > +#include "io.h" > +#include <asm/gic-v3.h> > +#include <asm/gic.h> > + > +struct vgic_irq_rank { > + spinlock_t lock; /* Covers access to all other members of this struct */ > + uint32_t ienable, iactive, ipend, pendsgi; > + uint32_t icfg[2]; > + uint32_t ipriority[8]; > + uint64_t irouter[32]; > +}; > + > +#define REG(n) (n) > + > +/* Number of ranks of interrupt registers for a domain */ > +#define DOMAIN_NR_RANKS(d) (((d)->arch.vgic.nr_lines+31)/32) > + > +/* > + * Rank containing GICD_<FOO><n> for GICD_<FOO> with > + * <b>-bits-per-interrupt > + */ > +static inline int REG_RANK_NR(int b, uint32_t n) > +{ > + switch ( b ) > + { > + case 64: return n >> 6; > + case 32: return n >> 5; > + case 16: return n >> 4; > + case 8: return n >> 3; > + case 4: return n >> 2; > + case 2: return n >> 1; > + case 1: return n; > + default: BUG(); > + } > +} > + > +/* > + * Offset of GICD_<FOO><n> with its rank, for GICD_<FOO> with > + * <b>-bits-per-interrupt. > + */ > +/* Shift n >> 2 to make it byte register diff */ > +#define REG_RANK_INDEX(b, n) (((n) >> 2) & ((b)-1)) > + > +/* > + * Returns rank corresponding to a GICD_<FOO><n> register for > + * GICD_<FOO> with <b>-bits-per-interrupt. > + */ > +static struct vgic_irq_rank *vgic_irq_rank(struct vcpu *v, int b, int n) > +{ > + int rank; > + > + n = n >> 2; > + rank = REG_RANK_NR(b, n); > + > + if ( rank == 0 ) /* Rank 0 is nothing but GICR registers in GICv3 */ > + return (struct vgic_irq_rank *)v->arch.vgic.private_irqs; > + else if ( rank <= DOMAIN_NR_RANKS(v->domain) ) > + return (struct vgic_irq_rank *)((unsigned char > *)(v->domain->arch.vgic.shared_irqs) > + + (sizeof(struct vgic_irq_rank) *(rank - 1))); > + else > + return NULL; code style > +} > + > +#define vgic_lock(v) spin_lock_irq(&(v)->domain->arch.vgic.lock) > +#define vgic_unlock(v) spin_unlock_irq(&(v)->domain->arch.vgic.lock) > + > +#define vgic_lock_rank(v, r) spin_lock(&(r)->lock) > +#define vgic_unlock_rank(v, r) spin_unlock(&(r)->lock) > + > +static uint32_t byte_read(uint32_t val, int sign, int offset) > +{ > + int byte = offset & 0x3; > + > + val = val >> (8*byte); > + if ( sign && (val & 0x80) ) > + val |= 0xffffff00; > + else > + val &= 0x000000ff; > + return val; > +} > + > +static void byte_write(uint32_t *reg, uint32_t var, int offset) > +{ > + int byte = offset & 0x3; > + > + var &= (0xff << (8*byte)); > + > + *reg &= ~(0xff << (8*byte)); > + *reg |= var; > +} > + > +static int vgic_read_priority(struct vcpu *v, int irq) > +{ > + struct vgic_irq_rank *rank = vgic_irq_rank(v, 8, irq); > + return byte_read(rank->ipriority[REG_RANK_INDEX(8, irq)], 0, irq & 0x3); > +} > + > +static int __vgic_rdistr_mmio_read(struct vcpu *v, mmio_info_t *info) > +{ > + struct hsr_dabt dabt = info->dabt; > + struct cpu_user_regs *regs = guest_cpu_user_regs(); > + register_t *r = select_user_reg(regs, dabt.reg); > + int offset = (int)(info->gpa - gic_data_rdist_rd_base()); > + int gicr_reg = REG(offset); > + u64 mpidr; > + u64 aff; > + > + switch ( gicr_reg ) > + { > + case GICR_CTLR: > + /* We have implemented LPI's, read zero */ > + goto read_as_zero; > + case GICR_IIDR: > + *r = 0x34; > + return 1; > + case GICR_TYPER: > + if(((info->gpa) & (~((SZ_64K * 2 * smp_processor_id()) - 1))) == > + (gic_data_rdist_rd_base() & (~((SZ_64K * 2 * smp_processor_id()) > - 1))) ) Please add a comment to explain what you are doing here _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |