xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Vijay Kilari <vijay.kilari@gmail.com>
To: Ian Campbell <Ian.Campbell@citrix.com>,
	Julien Grall <julien.grall@linaro.org>,
	Stefano Stabellini <stefano.stabellini@eu.citrix.com>,
	Stefano Stabellini <stefano.stabellini@citrix.com>,
	Tim Deegan <tim@xen.org>, Jan Beulich <jbeulich@suse.com>,
	"xen-devel@lists.xen.org" <xen-devel@lists.xen.org>
Cc: Prasun Kapoor <Prasun.Kapoor@caviumnetworks.com>,
	Vijaya Kumar K <vijaya.kumar@caviumnetworks.com>,
	manish.jaggi@caviumnetworks.com,
	Vijay Kilari <vijay.kilari@gmail.com>
Subject: Re: [PATCH v8 4/7] xen/arm: Add virtual GICv3 support
Date: Wed, 23 Jul 2014 19:21:41 +0530	[thread overview]
Message-ID: <CALicx6v1T4n-86ECBqxtMH2RAvFHyrGEjjjAn-jR6T15zBrFnQ@mail.gmail.com> (raw)
In-Reply-To: <1406122913-8303-5-git-send-email-vijay.kilari@gmail.com>

Please ignore this patch.
There are some alignment issues reappearing

On Wed, Jul 23, 2014 at 7:11 PM,  <vijay.kilari@gmail.com> wrote:
> From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
>
> Add virtual GICv3 driver support.
> Also, with this patch vgic_irq_rank structure is modified to
> hold GICv2 GICD_TARGET and GICv3 GICD_ROUTER registers under
> union.
>
> This patch adds only basic GICv3 support.
> Does not support Interrupt Translation support (ITS)
>
> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
> ---
> v8: - Fixed printk coding styles
>     - Moved GICD_PIDRn and GICR_PIDRn macros to vgic-v3.c
>       from header file
>    - Check is made on return value of vgic_v3_init()
> v7: Fixed coding style.
> v6: Removed byte read access for IROUTERN register.
> ---
>  xen/arch/arm/Makefile      |    1 +
>  xen/arch/arm/vgic-v2.c     |    8 +-
>  xen/arch/arm/vgic-v3.c     |  919 ++++++++++++++++++++++++++++++++++++++++++++
>  xen/arch/arm/vgic.c        |    6 +
>  xen/include/asm-arm/vgic.h |   13 +-
>  5 files changed, 942 insertions(+), 5 deletions(-)
>
> diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
> index 1684c09..ba61e58 100644
> --- a/xen/arch/arm/Makefile
> +++ b/xen/arch/arm/Makefile
> @@ -28,6 +28,7 @@ obj-y += smp.o
>  obj-y += shutdown.o
>  obj-y += traps.o
>  obj-y += vgic.o vgic-v2.o
> +obj-$(CONFIG_ARM_64) += vgic-v3.o
>  obj-y += vtimer.o
>  obj-y += vuart.o
>  obj-y += hvm.o
> diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
> index 2102e43..d65146a 100644
> --- a/xen/arch/arm/vgic-v2.c
> +++ b/xen/arch/arm/vgic-v2.c
> @@ -133,7 +133,7 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info)
>          if ( rank == NULL) goto read_as_zero;
>
>          vgic_lock_rank(v, rank);
> -        *r = rank->itargets[REG_RANK_INDEX(8, gicd_reg - GICD_ITARGETSR,
> +        *r = rank->v2.itargets[REG_RANK_INDEX(8, gicd_reg - GICD_ITARGETSR,
>                                             DABT_WORD)];
>          if ( dabt.size == DABT_BYTE )
>              *r = vgic_byte_read(*r, dabt.sign, gicd_reg);
> @@ -361,10 +361,10 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info)
>          if ( rank == NULL) goto write_ignore;
>          vgic_lock_rank(v, rank);
>          if ( dabt.size == DABT_WORD )
> -            rank->itargets[REG_RANK_INDEX(8, gicd_reg - GICD_ITARGETSR,
> +            rank->v2.itargets[REG_RANK_INDEX(8, gicd_reg - GICD_ITARGETSR,
>                                            DABT_WORD)] = *r;
>          else
> -            vgic_byte_write(&rank->itargets[REG_RANK_INDEX(8,
> +            vgic_byte_write(&rank->v2.itargets[REG_RANK_INDEX(8,
>                         gicd_reg - GICD_ITARGETSR, DABT_WORD)], *r, gicd_reg);
>          vgic_unlock_rank(v, rank);
>          return 1;
> @@ -466,7 +466,7 @@ static int vgic_v2_vcpu_init(struct vcpu *v)
>
>      /* For SGI and PPI the target is always this CPU */
>      for ( i = 0 ; i < 8 ; i++ )
> -        v->arch.vgic.private_irqs->itargets[i] =
> +        v->arch.vgic.private_irqs->v2.itargets[i] =
>                (1<<(v->vcpu_id+0))
>              | (1<<(v->vcpu_id+8))
>              | (1<<(v->vcpu_id+16))
> diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
> new file mode 100644
> index 0000000..6abaac3
> --- /dev/null
> +++ b/xen/arch/arm/vgic-v3.c
> @@ -0,0 +1,919 @@
> +/*
> + * 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@caviumnetworks.com>
> + * 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 <xen/sizes.h>
> +#include <asm/current.h>
> +#include <asm/device.h>
> +#include <asm/mmio.h>
> +#include <asm/gic_v3_defs.h>
> +#include <asm/gic.h>
> +#include <asm/vgic.h>
> +
> +/* GICD_PIDRn register values for ARM implementations */
> +#define GICV3_GICD_PIDR0  0x92
> +#define GICV3_GICD_PIDR1  0xb4
> +#define GICV3_GICD_PIDR2  0x3b
> +#define GICV3_GICD_PIDR4  0x04
> +
> +/* GICR_PIDRn register values for ARM implementations */
> +#define GICV3_GICR_PIDR0  0x93
> +#define GICV3_GICR_PIDR1  GICV3_GICD_PIDR1
> +#define GICV3_GICR_PIDR2  GICV3_GICD_PIDR2
> +#define GICV3_GICR_PIDR4  GICV3_GICD_PIDR4
> +
> +static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info,
> +                                         uint32_t gicr_reg)
> +{
> +    struct hsr_dabt dabt = info->dabt;
> +    struct cpu_user_regs *regs = guest_cpu_user_regs();
> +    register_t *r = select_user_reg(regs, dabt.reg);
> +    uint64_t aff;
> +
> +    switch ( gicr_reg )
> +    {
> +    case GICR_CTLR:
> +        /* We have not implemented LPI's, read zero */
> +        goto read_as_zero;
> +    case GICR_IIDR:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        *r = GICV3_GICR_IIDR_VAL;
> +        return 1;
> +    case GICR_TYPER:
> +        if ( dabt.size != DABT_DOUBLE_WORD ) goto bad_width;
> +        /* TBD: Update processor id in [23:8] when ITS support is added */
> +        aff = (MPIDR_AFFINITY_LEVEL(v->arch.vmpidr, 3) << 56 |
> +               MPIDR_AFFINITY_LEVEL(v->arch.vmpidr, 2) << 48 |
> +               MPIDR_AFFINITY_LEVEL(v->arch.vmpidr, 1) << 40 |
> +               MPIDR_AFFINITY_LEVEL(v->arch.vmpidr, 0) << 32);
> +        *r = aff;
> +        return 1;
> +    case GICR_STATUSR:
> +        /* Not implemented */
> +        goto read_as_zero;
> +    case GICR_WAKER:
> +        /* Power management is not implemented */
> +        goto read_as_zero;
> +    case GICR_SETLPIR:
> +        /* WO. Read as zero */
> +        goto read_as_zero_64;
> +    case GICR_CLRLPIR:
> +        /* WO. Read as zero */
> +        goto read_as_zero_64;
> +    case GICR_PROPBASER:
> +        /* LPI's not implemented */
> +        goto read_as_zero_64;
> +    case GICR_PENDBASER:
> +        /* LPI's not implemented */
> +        goto read_as_zero_64;
> +    case GICR_INVLPIR:
> +        /* WO. Read as zero */
> +        goto read_as_zero_64;
> +    case GICR_INVALLR:
> +        /* WO. Read as zero */
> +        goto read_as_zero_64;
> +        return 0;
> +    case GICR_SYNCR:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        /* RO . But when read it always returns busy bito bit[0] */
> +        *r = GICR_SYNCR_NOT_BUSY;
> +        return 1;
> +    case GICR_MOVLPIR:
> +        /* WO Read as zero */
> +        goto read_as_zero_64;
> +    case GICR_MOVALLR:
> +        /* WO Read as zero */
> +        goto read_as_zero_64;
> +    case GICR_PIDR0:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        *r = GICV3_GICR_PIDR0;
> +         return 1;
> +    case GICR_PIDR1:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        *r = GICV3_GICR_PIDR1;
> +         return 1;
> +    case GICR_PIDR2:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        *r = GICV3_GICR_PIDR2;
> +         return 1;
> +    case GICR_PIDR3:
> +        /* Manufacture/customer defined */
> +        goto read_as_zero;
> +    case GICR_PIDR4:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        *r = GICV3_GICR_PIDR4;
> +         return 1;
> +    case GICR_PIDR5 ... GICR_PIDR7:
> +        /* Reserved0 */
> +        goto read_as_zero;
> +    default:
> +        printk("vGICv3: vGICR: read r%d offset %#08x\n not found",
> +               dabt.reg, gicr_reg);
> +        return 0;
> +    }
> +bad_width:
> +    printk("vGICv3: vGICR: bad read width %d r%d offset %#08x\n",
> +           dabt.size, dabt.reg, gicr_reg);
> +    domain_crash_synchronous();
> +    return 0;
> +
> +read_as_zero_64:
> +    if ( dabt.size != DABT_DOUBLE_WORD ) goto bad_width;
> +    *r = 0;
> +    return 1;
> +
> +read_as_zero:
> +    if ( dabt.size != DABT_WORD ) goto bad_width;
> +    *r = 0;
> +    return 1;
> +}
> +
> +static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
> +                                          uint32_t gicr_reg)
> +{
> +    struct hsr_dabt dabt = info->dabt;
> +    struct cpu_user_regs *regs = guest_cpu_user_regs();
> +    register_t *r = select_user_reg(regs, dabt.reg);
> +
> +    switch ( gicr_reg )
> +    {
> +    case GICR_CTLR:
> +        /* LPI's not implemented */
> +        goto write_ignore;
> +    case GICR_IIDR:
> +        /* RO */
> +        goto write_ignore;
> +    case GICR_TYPER:
> +        /* RO */
> +        goto write_ignore_64;
> +    case GICR_STATUSR:
> +        /* Not implemented */
> +        goto write_ignore;
> +    case GICR_WAKER:
> +        /* Power mgmt not implemented */
> +        goto write_ignore;
> +    case GICR_SETLPIR:
> +        /* LPI is not implemented */
> +        goto write_ignore_64;
> +    case GICR_CLRLPIR:
> +        /* LPI is not implemented */
> +        goto write_ignore_64;
> +    case GICR_PROPBASER:
> +        /* LPI is not implemented */
> +        goto write_ignore_64;
> +    case GICR_PENDBASER:
> +        /* LPI is not implemented */
> +        goto write_ignore_64;
> +    case GICR_INVLPIR:
> +        /* LPI is not implemented */
> +        goto write_ignore_64;
> +    case GICR_INVALLR:
> +        /* LPI is not implemented */
> +        goto write_ignore_64;
> +    case GICR_SYNCR:
> +        /* RO */
> +        goto write_ignore;
> +    case GICR_MOVLPIR:
> +        /* LPI is not implemented */
> +        goto write_ignore_64;
> +    case GICR_MOVALLR:
> +        /* LPI is not implemented */
> +        goto write_ignore_64;
> +    case GICR_PIDR7... GICR_PIDR0:
> +        /* RO */
> +        goto write_ignore;
> +    default:
> +        printk("vGICR: write r%d offset %#08x\n not found", dabt.reg, gicr_reg);
> +        return 0;
> +    }
> +bad_width:
> +    printk("vGICR: bad write width %d r%d=%"PRIregister" offset %#08x\n",
> +           dabt.size, dabt.reg, *r, gicr_reg);
> +    domain_crash_synchronous();
> +    return 0;
> +
> +write_ignore_64:
> +    if ( dabt.size != DABT_DOUBLE_WORD ) goto bad_width;
> +    return 1;
> +
> +write_ignore:
> +    if ( dabt.size != DABT_WORD ) goto bad_width;
> +    return 1;
> +}
> +
> +static int __vgic_v3_distr_common_mmio_read(struct vcpu *v, mmio_info_t *info,
> +                                            uint32_t reg)
> +{
> +    struct hsr_dabt dabt = info->dabt;
> +    struct cpu_user_regs *regs = guest_cpu_user_regs();
> +    register_t *r = select_user_reg(regs, dabt.reg);
> +    struct vgic_irq_rank *rank;
> +
> +    switch ( reg )
> +    {
> +    case GICD_IGROUPR ... GICD_IGROUPRN:
> +        /* We do not implement security extensions for guests, read zero */
> +        goto read_as_zero;
> +    case GICD_ISENABLER ... GICD_ISENABLERN:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, reg - GICD_ISENABLER, DABT_WORD);
> +        if ( rank == NULL ) goto read_as_zero;
> +        vgic_lock_rank(v, rank);
> +        *r = rank->ienable;
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICD_ICENABLER ... GICD_ICENABLERN:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, reg - GICD_ICENABLER, DABT_WORD);
> +        if ( rank == NULL) goto read_as_zero;
> +        vgic_lock_rank(v, rank);
> +        *r = rank->ienable;
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICD_ISPENDR ... GICD_ISPENDRN:
> +        if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, reg - GICD_ISPENDR, DABT_WORD);
> +        if ( rank == NULL ) goto read_as_zero;
> +        vgic_lock_rank(v, rank);
> +        *r = vgic_byte_read(rank->ipend, dabt.sign, reg);
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICD_ICPENDR ... GICD_ICPENDRN:
> +        if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, reg - GICD_ICPENDR, DABT_WORD);
> +        if ( rank == NULL) goto read_as_zero;
> +        vgic_lock_rank(v, rank);
> +        *r = vgic_byte_read(rank->ipend, dabt.sign, reg);
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICD_ISACTIVER ... GICD_ISACTIVERN:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, reg - GICD_ISACTIVER, DABT_WORD);
> +        if ( rank == NULL) goto read_as_zero;
> +        vgic_lock_rank(v, rank);
> +        *r = rank->iactive;
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICD_ICACTIVER ... GICD_ICACTIVERN:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, reg - GICD_ICACTIVER, DABT_WORD);
> +        if ( rank == NULL) goto read_as_zero;
> +        vgic_lock_rank(v, rank);
> +        *r = rank->iactive;
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
> +        if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 8, reg - GICD_IPRIORITYR, DABT_WORD);
> +        if ( rank == NULL) goto read_as_zero;
> +
> +        vgic_lock_rank(v, rank);
> +        *r = rank->ipriority[REG_RANK_INDEX(8, reg - GICD_IPRIORITYR,
> +                                            DABT_WORD)];
> +        if ( dabt.size == DABT_BYTE )
> +            *r = vgic_byte_read(*r, dabt.sign, reg);
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICD_ICFGR ... GICD_ICFGRN:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 2, reg - GICD_ICFGR, DABT_WORD);
> +        if ( rank == NULL) goto read_as_zero;
> +        vgic_lock_rank(v, rank);
> +        *r = rank->icfg[REG_RANK_INDEX(2, reg - GICD_ICFGR, DABT_WORD)];
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    default:
> +        printk("vGICv3: vGICD/vGICR: unhandled read r%d offset %#08x\n",
> +               dabt.reg, reg);
> +        return 0;
> +    }
> +
> +bad_width:
> +    dprintk(XENLOG_ERR,
> +            "vGICv3: vGICD/vGICR: bad read width %d r%d offset %#08x\n",
> +            dabt.size, dabt.reg, reg);
> +    domain_crash_synchronous();
> +    return 0;
> +
> +read_as_zero:
> +    if ( dabt.size != DABT_WORD ) goto bad_width;
> +    *r = 0;
> +    return 1;
> +}
> +
> +static int __vgic_v3_distr_common_mmio_write(struct vcpu *v, mmio_info_t *info,
> +                                             uint32_t reg)
> +{
> +    struct hsr_dabt dabt = info->dabt;
> +    struct cpu_user_regs *regs = guest_cpu_user_regs();
> +    register_t *r = select_user_reg(regs, dabt.reg);
> +    struct vgic_irq_rank *rank;
> +    uint32_t tr;
> +
> +    switch ( reg )
> +    {
> +    case GICD_IGROUPR ... GICD_IGROUPRN:
> +        /* We do not implement security extensions for guests, write ignore */
> +        goto write_ignore;
> +    case GICD_ISENABLER ... GICD_ISENABLERN:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, reg - GICD_ISENABLER, DABT_WORD);
> +        if ( rank == NULL) goto write_ignore;
> +        vgic_lock_rank(v, rank);
> +        tr = rank->ienable;
> +        rank->ienable |= *r;
> +        vgic_unlock_rank(v, rank);
> +        /* The irq number is extracted from offset. so shift by register size */
> +        vgic_enable_irqs(v, (*r) & (~tr), (reg - GICD_ISENABLER) >> DABT_WORD);
> +        return 1;
> +    case GICD_ICENABLER ... GICD_ICENABLERN:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, reg - GICD_ICENABLER, DABT_WORD);
> +        if ( rank == NULL) goto write_ignore;
> +        vgic_lock_rank(v, rank);
> +        tr = rank->ienable;
> +        rank->ienable &= ~*r;
> +        vgic_unlock_rank(v, rank);
> +        /* The irq number is extracted from offset. so shift by register size */
> +        vgic_disable_irqs(v, (*r) & tr, (reg - GICD_ICENABLER) >> DABT_WORD);
> +        return 1;
> +    case GICD_ISPENDR ... GICD_ISPENDRN:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, reg - GICD_ISPENDR, DABT_WORD);
> +        if ( rank == NULL ) goto write_ignore;
> +        vgic_lock_rank(v, rank);
> +        rank->ipend = *r;
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICD_ICPENDR ... GICD_ICPENDRN:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, reg - GICD_ICPENDR, DABT_WORD);
> +        if ( rank == NULL ) goto write_ignore;
> +        vgic_lock_rank(v, rank);
> +        rank->ipend &= ~*r;
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICD_ISACTIVER ... GICD_ISACTIVERN:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, reg - GICD_ISACTIVER, DABT_WORD);
> +        if ( rank == NULL) goto write_ignore;
> +        vgic_lock_rank(v, rank);
> +        rank->iactive &= ~*r;
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICD_ICACTIVER ... GICD_ICACTIVERN:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, reg - GICD_ICACTIVER, DABT_WORD);
> +        if ( rank == NULL) goto write_ignore;
> +        vgic_lock_rank(v, rank);
> +        rank->iactive &= ~*r;
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
> +        if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 8, reg - GICD_IPRIORITYR, DABT_WORD);
> +        if ( rank == NULL) goto write_ignore;
> +        vgic_lock_rank(v, rank);
> +        if ( dabt.size == DABT_WORD )
> +            rank->ipriority[REG_RANK_INDEX(8, reg - GICD_IPRIORITYR,
> +                                           DABT_WORD)] = *r;
> +        else
> +            vgic_byte_write(&rank->ipriority[REG_RANK_INDEX(8,
> +                       reg - GICD_IPRIORITYR, DABT_WORD)], *r, reg);
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICD_ICFGR: /* Restricted to configure SGIs */
> +        goto write_ignore;
> +    case GICD_ICFGR + 4 ... GICD_ICFGRN: /* PPI + SPIs */
> +        /* ICFGR1 for PPI's, which is implementation defined
> +           if ICFGR1 is programmable or not. We chose to program */
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 2, reg - GICD_ICFGR, DABT_WORD);
> +        if ( rank == NULL) goto write_ignore;
> +        vgic_lock_rank(v, rank);
> +        rank->icfg[REG_RANK_INDEX(2, reg - GICD_ICFGR, DABT_WORD)] = *r;
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    default:
> +        printk("vGICv3: vGICD/vGICR: unhandled write r%d "
> +               "=%"PRIregister" offset %#08x\n", dabt.reg, *r, reg);
> +        return 0;
> +    }
> +
> +bad_width:
> +    dprintk(XENLOG_ERR,
> +            "vGICv3: vGICD/vGICR: bad write width %d r%d=%"PRIregister" "
> +            "offset %#08x\n", dabt.size, dabt.reg, *r, reg);
> +    domain_crash_synchronous();
> +    return 0;
> +
> +write_ignore:
> +    if ( dabt.size != DABT_WORD ) goto bad_width;
> +    return 1;
> +}
> +
> +static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, mmio_info_t *info,
> +                                        uint32_t gicr_reg)
> +{
> +    struct hsr_dabt dabt = info->dabt;
> +    struct cpu_user_regs *regs = guest_cpu_user_regs();
> +    register_t *r = select_user_reg(regs, dabt.reg);
> +    struct vgic_irq_rank *rank;
> +
> +    switch ( gicr_reg )
> +    {
> +    case GICR_IGRPMODR0:
> +        /* We do not implement security extensions for guests, read zero */
> +        goto read_as_zero;
> +    case GICR_IGROUPR0:
> +    case GICR_ISENABLER0:
> +    case GICR_ICENABLER0:
> +    case GICR_ISACTIVER0:
> +    case GICR_ICACTIVER0:
> +    case GICR_IPRIORITYR0...GICR_IPRIORITYR7:
> +    case GICR_ICFGR0... GICR_ICFGR1:
> +         /*
> +          * Above registers offset are common with GICD.
> +          * So handle in common with GICD handling
> +          */
> +        return __vgic_v3_distr_common_mmio_read(v, info, gicr_reg);
> +    case GICR_ISPENDR0:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, gicr_reg - GICR_ISPENDR0, DABT_WORD);
> +        if ( rank == NULL ) goto read_as_zero;
> +        vgic_lock_rank(v, rank);
> +        *r = rank->pendsgi;
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICR_ICPENDR0:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, gicr_reg - GICR_ICPENDR0, DABT_WORD);
> +        if ( rank == NULL ) goto read_as_zero;
> +        vgic_lock_rank(v, rank);
> +        *r = rank->pendsgi;
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICR_NSACR:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        return 1;
> +    default:
> +        printk("vGICv3: vGICR: read r%d offset %#08x\n not found",
> +               dabt.reg, gicr_reg);
> +        return 0;
> +    }
> +bad_width:
> +    printk("vGICv3: vGICR: bad read width %d r%d offset %#08x\n",
> +           dabt.size, dabt.reg, gicr_reg);
> +    domain_crash_synchronous();
> +    return 0;
> +
> +read_as_zero:
> +    if ( dabt.size != DABT_WORD ) goto bad_width;
> +    *r = 0;
> +    return 1;
> +}
> +
> +static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, mmio_info_t *info,
> +                                         uint32_t gicr_reg)
> +{
> +    struct hsr_dabt dabt = info->dabt;
> +    struct cpu_user_regs *regs = guest_cpu_user_regs();
> +    register_t *r = select_user_reg(regs, dabt.reg);
> +    struct vgic_irq_rank *rank;
> +
> +    switch ( gicr_reg )
> +    {
> +    case GICR_IGRPMODR0:
> +        /* We do not implement security extensions for guests, write ignore */
> +        goto write_ignore;
> +    case GICR_IGROUPR0:
> +    case GICR_ISENABLER0:
> +    case GICR_ICENABLER0:
> +    case GICR_ISACTIVER0:
> +    case GICR_ICACTIVER0:
> +    case GICR_ICFGR1:
> +    case GICR_IPRIORITYR0...GICR_IPRIORITYR7:
> +         /*
> +          * Above registers offset are common with GICD.
> +          * So handle common with GICD handling
> +          */
> +        return __vgic_v3_distr_common_mmio_write(v, info, gicr_reg);
> +    case GICR_ISPENDR0:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, gicr_reg - GICR_ISACTIVER0, DABT_WORD);
> +        if ( rank == NULL ) goto write_ignore;
> +        vgic_lock_rank(v, rank);
> +        /* TODO: we just store the SGI pending status. Handle it properly */
> +        rank->pendsgi |= *r;
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICR_ICPENDR0:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 1, gicr_reg - GICR_ISACTIVER0, DABT_WORD);
> +        if ( rank == NULL ) goto write_ignore;
> +        vgic_lock_rank(v, rank);
> +        /* TODO: we just store the SGI pending status. Handle it properly */
> +        rank->pendsgi &= ~*r;
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICR_NSACR:
> +        /* We do not implement security extensions for guests, write ignore */
> +        goto write_ignore;
> +    default:
> +        printk("vGICv3: vGICR SGI: write r%d offset %#08x\n not found",
> +               dabt.reg, gicr_reg);
> +        return 0;
> +    }
> +
> +bad_width:
> +    printk("vGICR SGI: bad write width %d r%d=%"PRIregister" offset %#08x\n",
> +           dabt.size, dabt.reg, *r, gicr_reg);
> +    domain_crash_synchronous();
> +    return 0;
> +
> +write_ignore:
> +    if ( dabt.size != DABT_WORD ) goto bad_width;
> +    return 1;
> +}
> +
> +static int vgic_v3_rdistr_mmio_read(struct vcpu *v, mmio_info_t *info)
> +{
> +    uint32_t offset;
> +
> +    offset = info->gpa & (v->domain->arch.vgic.rdist_stride - 1);
> +
> +    if ( offset < SZ_64K )
> +        return __vgic_v3_rdistr_rd_mmio_read(v, info, offset);
> +    else  if ( (offset >= SZ_64K) && (offset < 2 * SZ_64K) )
> +        return vgic_v3_rdistr_sgi_mmio_read(v, info, (offset - SZ_64K));
> +    else
> +        gdprintk(XENLOG_WARNING,
> +                 "vGICv3: vGICR: unknown gpa read address %"PRIpaddr"\n",
> +                 info->gpa);
> +
> +    return 0;
> +}
> +
> +static int vgic_v3_rdistr_mmio_write(struct vcpu *v, mmio_info_t *info)
> +{
> +    uint32_t offset;
> +
> +    offset = info->gpa & (v->domain->arch.vgic.rdist_stride - 1);
> +    if ( offset < SZ_64K )
> +        return __vgic_v3_rdistr_rd_mmio_write(v, info, offset);
> +    else  if ( (offset >= SZ_64K) && (offset < 2 * SZ_64K) )
> +        return vgic_v3_rdistr_sgi_mmio_write(v, info, (offset - SZ_64K));
> +    else
> +        gdprintk(XENLOG_WARNING,
> +                 "vGICV3: vGICR: unknown gpa write address %"PRIpaddr"\n",
> +                 info->gpa);
> +
> +    return 0;
> +}
> +
> +static int vgic_v3_distr_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);
> +    struct vgic_irq_rank *rank;
> +    int gicd_reg = (int)(info->gpa - v->domain->arch.vgic.dbase);
> +
> +    switch ( gicd_reg )
> +    {
> +    case GICD_CTLR:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        vgic_lock(v);
> +        *r = v->domain->arch.vgic.ctlr;
> +        vgic_unlock(v);
> +        return 1;
> +    case GICD_TYPER:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        /* No secure world support for guests. */
> +        *r = (((v->domain->max_vcpus << 5) & GICD_TYPE_CPUS ) |
> +              ((v->domain->arch.vgic.nr_lines / 32) & GICD_TYPE_LINES));
> +        return 1;
> +    case GICD_STATUSR:
> +        /*
> +         *  Optional, Not implemented for now.
> +         *  Update to support guest debugging.
> +         */
> +        goto read_as_zero;
> +    case GICD_IIDR:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        *r = GICV3_GICD_IIDR_VAL;
> +        return 1;
> +    case 0x020 ... 0x03c:
> +    case 0xc000 ... 0xffcc:
> +        /* Implementation defined -- read as zero */
> +        goto read_as_zero;
> +    case GICD_IGROUPR ... GICD_IGROUPRN:
> +    case GICD_ISENABLER ... GICD_ISENABLERN:
> +    case GICD_ICENABLER ... GICD_ICENABLERN:
> +    case GICD_ISPENDR ... GICD_ISPENDRN:
> +    case GICD_ICPENDR ... GICD_ICPENDRN:
> +    case GICD_ISACTIVER ... GICD_ISACTIVERN:
> +    case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
> +    case GICD_ICFGR ... GICD_ICFGRN:
> +        /*
> +         * Above all register are common with GICR and GICD
> +         * Manage in common
> +         */
> +        return __vgic_v3_distr_common_mmio_read(v, info, gicd_reg);
> +    case GICD_IROUTER ... GICD_IROUTER31:
> +        /* SGI/PPI is RES0 */
> +        goto read_as_zero_64;
> +    case GICD_IROUTER32 ... GICD_IROUTERN:
> +        if ( dabt.size != DABT_DOUBLE_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 64, gicd_reg - GICD_IROUTER, DABT_DOUBLE_WORD);
> +        if ( rank == NULL) goto read_as_zero;
> +        vgic_lock_rank(v, rank);
> +        /* IROUTER is 64 bit so, to make it byte size right shift by 3.
> +           Here once. macro REG_RANK_INDEX will do it twice */
> +        *r = rank->v3.irouter[REG_RANK_INDEX(64,
> +                           (gicd_reg - GICD_IROUTER), DABT_DOUBLE_WORD)];
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICD_NSACR ... GICD_NSACRN:
> +        /* We do not implement security extensions for guests, read zero */
> +        goto read_as_zero;
> +    case GICD_SGIR:
> +        /* Read as ICH_SGIR system register with SRE set. So ignore */
> +        goto read_as_zero;
> +    case GICD_CPENDSGIR ... GICD_CPENDSGIRN:
> +        /* Replaced with GICR_ICPENDR0. So ignore write */
> +        goto read_as_zero;
> +    case GICD_SPENDSGIR ... GICD_SPENDSGIRN:
> +        /* Replaced with GICR_ISPENDR0. So ignore write */
> +        goto read_as_zero;
> +    case GICD_PIDR0:
> +        /* GICv3 identification value */
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        *r = GICV3_GICD_PIDR0;
> +        return 1;
> +    case GICD_PIDR1:
> +        /* GICv3 identification value */
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        *r = GICV3_GICD_PIDR1;
> +        return 1;
> +    case GICD_PIDR2:
> +        /* GICv3 identification value */
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        *r = GICV3_GICD_PIDR2;
> +        return 1;
> +    case GICD_PIDR3:
> +        /* GICv3 identification value. Manufacturer/Customer defined */
> +        goto read_as_zero;
> +    case GICD_PIDR4:
> +        /* GICv3 identification value */
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        *r = GICV3_GICD_PIDR4;
> +        return 1;
> +    case GICD_PIDR5 ... GICD_PIDR7:
> +        /* Reserved0 */
> +        goto read_as_zero;
> +    case 0x00c:
> +    case 0x044:
> +    case 0x04c:
> +    case 0x05c ... 0x07c:
> +    case 0xf30 ... 0x5fcc:
> +    case 0x8000 ... 0xbfcc:
> +        /* These are reserved register addresses */
> +        printk("vGICv3: vGICD: read unknown 0x00c .. 0xfcc r%d offset %#08x\n",
> +               dabt.reg, gicd_reg);
> +        goto read_as_zero;
> +    default:
> +        printk("vGICv3: vGICD: unhandled read r%d offset %#08x\n",
> +               dabt.reg, gicd_reg);
> +        return 0;
> +    }
> +
> +bad_width:
> +    dprintk(XENLOG_ERR, "vGICv3: vGICD: bad read width %d r%d offset %#08x\n",
> +            dabt.size, dabt.reg, gicd_reg);
> +    domain_crash_synchronous();
> +    return 0;
> +
> +read_as_zero_64:
> +    if ( dabt.size != DABT_DOUBLE_WORD ) goto bad_width;
> +    *r = 0;
> +    return 1;
> +
> +read_as_zero:
> +    if ( dabt.size != DABT_WORD ) goto bad_width;
> +    *r = 0;
> +    return 1;
> +}
> +
> +static int vgic_v3_distr_mmio_write(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);
> +    struct vgic_irq_rank *rank;
> +    int gicd_reg = (int)(info->gpa - v->domain->arch.vgic.dbase);
> +
> +    switch ( gicd_reg )
> +    {
> +    case GICD_CTLR:
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        /* Ignore all but the enable bit */
> +        v->domain->arch.vgic.ctlr = (*r) & GICD_CTL_ENABLE;
> +        return 1;
> +    case GICD_TYPER:
> +        /* RO -- write ignored */
> +        goto write_ignore;
> +    case GICD_IIDR:
> +        /* RO -- write ignored */
> +        goto write_ignore;
> +    case GICD_STATUSR:
> +        /* RO -- write ignored */
> +        goto write_ignore;
> +    case GICD_SETSPI_NSR:
> +        /* Message based SPI is not implemented */
> +        goto write_ignore;
> +    case GICD_CLRSPI_NSR:
> +        /* Message based SPI is not implemented */
> +        goto write_ignore;
> +    case GICD_SETSPI_SR:
> +        /* Message based SPI is not implemented */
> +        goto write_ignore;
> +    case GICD_CLRSPI_SR:
> +        /* Message based SPI is not implemented */
> +        goto write_ignore;
> +    case 0x020 ... 0x03c:
> +    case 0xc000 ... 0xffcc:
> +        /* Implementation defined -- write ignored */
> +        printk("vGICv3: vGICD: write unknown 0x020 - 0x03c r%d offset %#08x\n",
> +               dabt.reg, gicd_reg);
> +        goto write_ignore;
> +    case GICD_IGROUPR ... GICD_IGROUPRN:
> +    case GICD_ISENABLER ... GICD_ISENABLERN:
> +    case GICD_ICENABLER ... GICD_ICENABLERN:
> +    case GICD_ISPENDR ... GICD_ISPENDRN:
> +    case GICD_ICPENDR ... GICD_ICPENDRN:
> +    case GICD_ISACTIVER ... GICD_ISACTIVERN:
> +    case GICD_ICACTIVER ... GICD_ICACTIVERN:
> +    case GICD_IPRIORITYR ... GICD_IPRIORITYRN:
> +    case GICD_ICFGR ... GICD_ICFGRN:
> +        /* Above registers are common with GICR and GICD
> +         * Manage in common */
> +        return __vgic_v3_distr_common_mmio_write(v, info, gicd_reg);
> +    case GICD_IROUTER ... GICD_IROUTER31:
> +        /* SGI/PPI is RES0 */
> +        goto write_ignore_64;
> +    case GICD_IROUTER32 ... GICD_IROUTERN:
> +        if ( dabt.size != DABT_DOUBLE_WORD ) goto bad_width;
> +        rank = vgic_rank_offset(v, 64, gicd_reg - GICD_IROUTER, DABT_DOUBLE_WORD);
> +        if ( rank == NULL) goto write_ignore_64;
> +        if ( *r )
> +        {
> +            /* TODO: Ignored. We don't support irq delivery for vcpu != 0 */
> +            gdprintk(XENLOG_DEBUG,
> +                     "SPI delivery to secondary cpus not supported\n");
> +            goto write_ignore_64;
> +        }
> +        vgic_lock_rank(v, rank);
> +        rank->v3.irouter[REG_RANK_INDEX(64,
> +                      (gicd_reg - GICD_IROUTER), DABT_DOUBLE_WORD)] = *r;
> +        vgic_unlock_rank(v, rank);
> +        return 1;
> +    case GICD_NSACR ... GICD_NSACRN:
> +        /* We do not implement security extensions for guests, write ignore */
> +        goto write_ignore;
> +    case GICD_SGIR:
> +        /* it is accessed as system register in GICv3 */
> +        goto write_ignore;
> +    case GICD_CPENDSGIR ... GICD_CPENDSGIRN:
> +        /* Replaced with GICR_ICPENDR0. So ignore write */
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        return 0;
> +    case GICD_SPENDSGIR ... GICD_SPENDSGIRN:
> +        /* Replaced with GICR_ISPENDR0. So ignore write */
> +        if ( dabt.size != DABT_WORD ) goto bad_width;
> +        return 0;
> +    case GICD_PIDR7... GICD_PIDR0:
> +        /* RO -- write ignore */
> +        goto write_ignore;
> +    case 0x00c:
> +    case 0x044:
> +    case 0x04c:
> +    case 0x05c ... 0x07c:
> +    case 0xf30 ... 0x5fcc:
> +    case 0x8000 ... 0xbfcc:
> +        /* Reserved register addresses */
> +        printk("vGICv3: vGICD: write unknown 0x00c 0xfcc  r%d offset %#08x\n",
> +                dabt.reg, gicd_reg);
> +        goto write_ignore;
> +    default:
> +        printk("vGICv3: vGICD: unhandled write r%d=%"PRIregister" "
> +               "offset %#08x\n", dabt.reg, *r, gicd_reg);
> +        return 0;
> +    }
> +
> +bad_width:
> +    dprintk(XENLOG_ERR,
> +            "VGICv3: vGICD: bad write width %d r%d=%"PRIregister" "
> +            "offset %#08x\n", dabt.size, dabt.reg, *r, gicd_reg);
> +    domain_crash_synchronous();
> +    return 0;
> +
> +write_ignore:
> +    if ( dabt.size != DABT_WORD ) goto bad_width;
> +    return 1;
> +
> +write_ignore_64:
> +    if ( dabt.size != DABT_DOUBLE_WORD ) goto bad_width;
> +    return 1;
> +}
> +
> +static const struct mmio_handler_ops vgic_rdistr_mmio_handler = {
> +    .read_handler  = vgic_v3_rdistr_mmio_read,
> +    .write_handler = vgic_v3_rdistr_mmio_write,
> +};
> +
> +static const struct mmio_handler_ops vgic_distr_mmio_handler = {
> +    .read_handler  = vgic_v3_distr_mmio_read,
> +    .write_handler = vgic_v3_distr_mmio_write,
> +};
> +
> +static int vgicv3_vcpu_init(struct vcpu *v)
> +{
> +    int i;
> +    uint64_t affinity;
> +
> +    /* For SGI and PPI the target is always this CPU */
> +    affinity = (MPIDR_AFFINITY_LEVEL(v->arch.vmpidr, 3) << 32 |
> +                MPIDR_AFFINITY_LEVEL(v->arch.vmpidr, 2) << 16 |
> +                MPIDR_AFFINITY_LEVEL(v->arch.vmpidr, 1) << 8  |
> +                MPIDR_AFFINITY_LEVEL(v->arch.vmpidr, 0));
> +
> +    for ( i = 0 ; i < 32 ; i++ )
> +        v->arch.vgic.private_irqs->v3.irouter[i] = affinity;
> +
> +    return 0;
> +}
> +
> +static int vgicv3_domain_init(struct domain *d)
> +{
> +    int i;
> +
> +    /* We rely on gicv init to get dbase and size */
> +    register_mmio_handler(d, &vgic_distr_mmio_handler, d->arch.vgic.dbase,
> +                          d->arch.vgic.dbase_size);
> +
> +    /*
> +     * Register mmio handler per redistributor region but not for
> +     * every sgi rdist region which is per core.
> +     * The redistributor region encompasses per core sgi region.
> +     */
> +    for ( i = 0; i < d->arch.vgic.rdist_count; i++ )
> +        register_mmio_handler(d, &vgic_rdistr_mmio_handler,
> +            d->arch.vgic.rbase[i], d->arch.vgic.rbase_size[i]);
> +
> +    return 0;
> +}
> +
> +static const struct vgic_ops v3_ops = {
> +    .vcpu_init   = vgicv3_vcpu_init,
> +    .domain_init = vgicv3_domain_init,
> +};
> +
> +int vgic_v3_init(struct domain *d)
> +{
> +    register_vgic_ops(d, &v3_ops);
> +
> +    return 0;
> +}
> +
> +/*
> + * Local variables:
> + * mode: C
> + * c-file-style: "BSD"
> + * c-basic-offset: 4
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index d223db4..622219f 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -69,6 +69,12 @@ int domain_vgic_init(struct domain *d)
>
>      switch ( gic_hw_version() )
>      {
> +#ifdef CONFIG_ARM_64
> +    case GIC_V3:
> +        if ( vgic_v3_init(d) )
> +           return -ENODEV;
> +        break;
> +#endif
>      case GIC_V2:
>          if ( vgic_v2_init(d) )
>              return -ENODEV;
> diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
> index 19eed7e..f580b78 100644
> --- a/xen/include/asm-arm/vgic.h
> +++ b/xen/include/asm-arm/vgic.h
> @@ -83,7 +83,14 @@ struct vgic_irq_rank {
>      uint32_t ienable, iactive, ipend, pendsgi;
>      uint32_t icfg[2];
>      uint32_t ipriority[8];
> -    uint32_t itargets[8];
> +    union {
> +        struct {
> +            uint32_t itargets[8];
> +        }v2;
> +        struct {
> +            uint64_t irouter[32];
> +        }v3;
> +    };
>  };
>
>  struct vgic_ops {
> @@ -110,6 +117,9 @@ 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;
> @@ -159,6 +169,7 @@ extern void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n);
>  extern void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n);
>  extern void register_vgic_ops(struct domain *d, const struct vgic_ops *ops);
>  int vgic_v2_init(struct domain *d);
> +int vgic_v3_init(struct domain *d);
>
>  extern int vcpu_vgic_free(struct vcpu *v);
>  extern int vgic_to_sgi(struct vcpu *v, register_t sgir,
> --
> 1.7.9.5
>

  reply	other threads:[~2014-07-23 13:51 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-23 13:41 [PATCH v8 0/7] xen/arm: Add GICv3 support vijay.kilari
2014-07-23 13:41 ` [PATCH v8 1/7] xen/arm: Introduce sizes.h vijay.kilari
2014-07-28 13:55   ` Ian Campbell
2014-07-23 13:41 ` [PATCH v8 2/7] xen/arm: Stringify the register name in sysreg read write macros vijay.kilari
2014-07-23 17:20   ` Julien Grall
2014-07-28 13:56   ` Ian Campbell
2014-07-23 13:41 ` [PATCH v8 3/7] xen/arm: Add support for GIC v3 vijay.kilari
2014-07-23 17:28   ` Julien Grall
2014-07-24  9:03     ` Ian Campbell
2014-07-24 10:26       ` Julien Grall
2014-07-23 13:41 ` [PATCH v8 4/7] xen/arm: Add virtual GICv3 support vijay.kilari
2014-07-23 13:51   ` Vijay Kilari [this message]
2014-07-28 14:35     ` Ian Campbell
2014-07-28 14:55       ` Ian Campbell
2014-07-28 15:08         ` Julien Grall
2014-07-28 15:26           ` Ian Campbell
2014-07-28 15:29             ` Julien Grall
2014-07-28 15:35         ` Julien Grall
2014-07-28 16:02           ` Ian Campbell
2014-07-28 16:11             ` Julien Grall
2014-07-28 16:25               ` Ian Campbell
2014-07-28 16:30                 ` Julien Grall
2014-07-23 13:41 ` [PATCH v8 5/7] xen/arm: Update Dom0 GIC dt node with GICv3 information vijay.kilari
2014-07-23 13:41 ` [PATCH v8 6/7] xen/arm: add SGI handling for GICv3 vijay.kilari
2014-07-23 13:56   ` Stefano Stabellini
2014-07-24 14:37   ` Julien Grall
2014-07-28 14:04   ` Ian Campbell
2014-07-23 13:41 ` [PATCH v8 7/7] xen/arm: check for GICv3 platform support vijay.kilari
2014-07-24 14:45   ` Julien Grall
2014-08-03 21:24 ` [PATCH v8 0/7] xen/arm: Add GICv3 support Julien Grall
2014-08-04 10:06   ` Ian Campbell
2014-08-04 10:25     ` Julien Grall
2014-08-04 10:42       ` Ian Campbell
     [not found]         ` <CALicx6ucRFNP4A3a2uBPTmhYzKtNWNOvwmPLUfy4Z2DoYDVr3g@mail.gmail.com>
2014-08-04 15:48           ` Ian Campbell
2014-08-06 14:52             ` Vijay Kilari
2014-08-07 14:11               ` Julien Grall
2014-08-28 11:36                 ` Vijay Kilari
2014-09-02 23:18                   ` Stefano Stabellini
2014-09-03 12:15                     ` Ian Campbell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CALicx6v1T4n-86ECBqxtMH2RAvFHyrGEjjjAn-jR6T15zBrFnQ@mail.gmail.com \
    --to=vijay.kilari@gmail.com \
    --cc=Ian.Campbell@citrix.com \
    --cc=Prasun.Kapoor@caviumnetworks.com \
    --cc=jbeulich@suse.com \
    --cc=julien.grall@linaro.org \
    --cc=manish.jaggi@caviumnetworks.com \
    --cc=stefano.stabellini@citrix.com \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=tim@xen.org \
    --cc=vijaya.kumar@caviumnetworks.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).