From: vijay.kilari@gmail.com
To: Ian.Campbell@citrix.com, julien.grall@linaro.org,
stefano.stabellini@eu.citrix.com, stefano.stabellini@citrix.com,
xen-devel@lists.xen.org
Cc: Prasun.Kapoor@caviumnetworks.com,
Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>,
vijay.kilari@gmail.com
Subject: [PATCH v4 14/16] xen/arm: Add virtual GICv3 support
Date: Mon, 26 May 2014 15:56:47 +0530 [thread overview]
Message-ID: <1401100009-7326-15-git-send-email-vijay.kilari@gmail.com> (raw)
In-Reply-To: <1401100009-7326-1-git-send-email-vijay.kilari@gmail.com>
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Add virtual GICv3 driver support
This patch adds only basic v3 support.
Does not support Interrupt Translation support (ITS)
Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
---
xen/arch/arm/Makefile | 1 +
xen/arch/arm/vgic-v2.c | 8 +-
xen/arch/arm/vgic-v3.c | 895 ++++++++++++++++++++++++++++++++++++++++++++
xen/arch/arm/vgic.c | 13 +-
xen/include/asm-arm/vgic.h | 13 +-
5 files changed, 923 insertions(+), 7 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 b146efe..e05d821 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 = byte_read(*r, dabt.sign, gicd_reg);
@@ -344,10 +344,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
- byte_write(&rank->itargets[REG_RANK_INDEX(8,
+ 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;
@@ -449,7 +449,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..d80683d
--- /dev/null
+++ b/xen/arch/arm/vgic-v3.c
@@ -0,0 +1,895 @@
+/*
+ * 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 <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>
+
+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 mpidr;
+ 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 */
+ mpidr = cpu_logical_map(v->vcpu_id);
+ aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 56 |
+ MPIDR_AFFINITY_LEVEL(mpidr, 2) << 48 |
+ MPIDR_AFFINITY_LEVEL(mpidr, 1) << 40 |
+ MPIDR_AFFINITY_LEVEL(mpidr, 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_irq_rank(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_irq_rank(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_irq_rank(v, 1, reg - GICD_ISPENDR, DABT_WORD);
+ if ( rank == NULL ) goto read_as_zero;
+ vgic_lock_rank(v, rank);
+ *r = 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_irq_rank(v, 1, reg - GICD_ICPENDR, DABT_WORD);
+ if ( rank == NULL) goto read_as_zero;
+ vgic_lock_rank(v, rank);
+ *r = 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_irq_rank(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_irq_rank(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_irq_rank(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 = 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_irq_rank(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("GICv3: 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_irq_rank(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_irq_rank(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_irq_rank(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_irq_rank(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_irq_rank(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_irq_rank(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_irq_rank(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
+ 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_irq_rank(v, 2, reg - GICD_ICFGR, DABT_WORD);
+ vgic_lock_rank(v, rank);
+ if ( rank == NULL) goto write_ignore;
+ 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_irq_rank(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_irq_rank(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_irq_rank(v, 1, gicr_reg - GICR_ISACTIVER0, DABT_WORD);
+ if ( rank == NULL ) goto write_ignore;
+ vgic_lock_rank(v, rank);
+ rank->pendsgi |= *r;
+ vgic_unlock_rank(v, rank);
+ return 1;
+ case GICR_ICPENDR0:
+ if ( dabt.size != DABT_WORD ) goto bad_width;
+ rank = vgic_irq_rank(v, 1, gicr_reg - GICR_ISACTIVER0, DABT_WORD);
+ if ( rank == NULL ) goto write_ignore;
+ vgic_lock_rank(v, rank);
+ 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. */
+ vgic_lock(v);
+ *r = (((v->domain->max_vcpus << 5) & GICD_TYPE_CPUS ) |
+ ((v->domain->arch.vgic.nr_lines / 32) & GICD_TYPE_LINES));
+ vgic_unlock(v);
+ 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_BYTE && dabt.size != DABT_DOUBLE_WORD )
+ goto bad_width;
+ rank = vgic_irq_rank(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)];
+ if ( dabt.size == DABT_BYTE )
+ *r = byte_read(*r, dabt.sign, gicd_reg);
+ 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("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_irq_rank(v, 64, gicd_reg - GICD_IROUTER, DABT_DOUBLE_WORD);
+ if ( rank == NULL) goto write_ignore;
+ 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;
+}
+
+const static struct mmio_handler_ops vgic_rdistr_mmio_handler = {
+ .read_handler = vgic_v3_rdistr_mmio_read,
+ .write_handler = vgic_v3_rdistr_mmio_write,
+};
+
+const static 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 = cpu_logical_map(smp_processor_id());
+ 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;
+
+ 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;
+}
+
+const static 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 3fa0857..787c547 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -264,10 +264,19 @@ int domain_vgic_init(struct domain *d)
else
d->arch.vgic.nr_lines = 0; /* We don't need SPIs for the guest */
- if ( gic_hw_version() == GIC_V2 )
+ switch ( gic_hw_version() )
+ {
+#ifdef CONFIG_ARM_64
+ case GIC_V3:
+ vgic_v3_init(d);
+ break;
+#endif
+ case GIC_V2:
vgic_v2_init(d);
- else
+ break;
+ default:
panic("No VGIC found\n");
+ }
d->arch.vgic.shared_irqs =
xzalloc_array(struct vgic_irq_rank, DOMAIN_NR_RANKS(d));
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index aa4e94d..754d521 100644
--- a/xen/include/asm-arm/vgic.h
+++ b/xen/include/asm-arm/vgic.h
@@ -26,7 +26,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 {
@@ -53,6 +60,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;
@@ -120,6 +130,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);
#endif
--
1.7.9.5
next prev parent reply other threads:[~2014-05-26 10:26 UTC|newest]
Thread overview: 78+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-26 10:26 [PATCH v4 00/16] xen/arm: Add GICv3 support vijay.kilari
2014-05-26 10:26 ` [PATCH v4 01/16] xen/arm: move io.h as mmio.h to include folder vijay.kilari
2014-05-26 11:28 ` Julien Grall
2014-05-28 13:55 ` Stefano Stabellini
2014-05-26 10:26 ` [PATCH v4 02/16] xen/arm: make mmio handlers domain specific vijay.kilari
2014-05-26 12:33 ` Julien Grall
2014-05-28 14:05 ` Stefano Stabellini
2014-05-28 14:11 ` Julien Grall
2014-05-26 10:26 ` [PATCH v4 03/16] xen/arm: make sgi handling generic vijay.kilari
2014-05-26 12:41 ` Julien Grall
2014-05-26 12:45 ` Julien Grall
2014-05-28 14:10 ` Stefano Stabellini
2014-06-09 9:58 ` Vijay Kilari
2014-05-26 10:26 ` [PATCH v4 04/16] xen/arm: remove unused parameter in do_sgi call vijay.kilari
2014-05-26 12:48 ` Julien Grall
2014-05-26 10:26 ` [PATCH v4 05/16] xen/arm: use ioremap to map gic-v2 registers vijay.kilari
2014-05-26 13:10 ` Julien Grall
2014-05-30 12:54 ` Vijay Kilari
2014-05-28 14:26 ` Stefano Stabellini
2014-06-09 10:29 ` Vijay Kilari
2014-05-26 10:26 ` [PATCH v4 06/16] xen/arm: segregate and split GIC low level functionality vijay.kilari
2014-05-26 14:09 ` Julien Grall
2014-05-27 19:13 ` Julien Grall
2014-05-28 14:43 ` Stefano Stabellini
2014-05-26 10:26 ` [PATCH v4 07/16] arm/xen: move GIC context data structure to gic driver vijay.kilari
2014-05-26 14:32 ` Julien Grall
2014-05-28 14:49 ` Stefano Stabellini
2014-05-26 10:26 ` [PATCH v4 08/16] xen/arm: use device api to detect GIC version vijay.kilari
2014-05-26 14:39 ` Julien Grall
2014-05-28 14:52 ` Stefano Stabellini
2014-05-26 10:26 ` [PATCH v4 09/16] xen/arm: move vgic rank data to gic header file vijay.kilari
2014-05-27 11:32 ` Julien Grall
2014-05-28 14:54 ` Stefano Stabellini
2014-05-26 10:26 ` [PATCH v4 10/16] xen/arm: move vgic defines to vgic " vijay.kilari
2014-05-27 11:49 ` Julien Grall
2014-06-10 8:30 ` Vijay Kilari
2014-05-26 10:26 ` [PATCH v4 11/16] xen/arm: calculate vgic irq rank based on register size vijay.kilari
2014-05-27 11:56 ` Julien Grall
2014-05-30 8:59 ` Vijay Kilari
2014-05-30 9:58 ` Julien Grall
2014-05-30 10:24 ` Vijay Kilari
2014-05-30 10:36 ` Julien Grall
2014-05-30 10:51 ` Vijay Kilari
2014-05-30 10:54 ` Julien Grall
2014-05-26 10:26 ` [PATCH v4 12/16] xen/arm: split vgic driver into generic and vgic-v2 driver vijay.kilari
2014-05-27 16:50 ` Julien Grall
2014-05-26 10:26 ` [PATCH v4 13/16] xen/arm: Add support for GIC v3 vijay.kilari
2014-05-27 19:47 ` Julien Grall
2014-06-02 17:33 ` Stefano Stabellini
2014-06-03 8:54 ` Ian Campbell
2014-06-03 9:05 ` Julien Grall
2014-06-03 9:07 ` Ian Campbell
2014-06-03 10:43 ` Stefano Stabellini
2014-06-03 10:46 ` Stefano Stabellini
2014-05-26 10:26 ` vijay.kilari [this message]
2014-06-02 15:50 ` [PATCH v4 14/16] xen/arm: Add virtual GICv3 support Stefano Stabellini
2014-06-11 11:36 ` Vijay Kilari
2014-06-11 12:44 ` Stefano Stabellini
2014-06-02 16:10 ` Julien Grall
2014-06-02 16:15 ` Ian Campbell
2014-06-02 16:18 ` Julien Grall
2014-06-02 16:38 ` Ian Campbell
2014-06-02 16:46 ` Julien Grall
2014-05-26 10:26 ` [PATCH v4 15/16] xen/arm: Update Dom0 GIC dt node with GICv3 information vijay.kilari
2014-05-26 10:26 ` [PATCH v4 16/16] xen/arm: add SGI handling for GICv3 vijay.kilari
2014-06-02 16:05 ` Stefano Stabellini
2014-06-02 16:13 ` Ian Campbell
2014-06-11 12:34 ` Vijay Kilari
2014-06-02 16:17 ` Julien Grall
2014-06-11 12:35 ` Vijay Kilari
2014-06-11 12:38 ` Julien Grall
2014-06-12 6:53 ` Vijay Kilari
2014-06-12 21:56 ` Julien Grall
2014-06-13 8:34 ` Ian Campbell
2014-06-15 18:44 ` Julien Grall
2014-06-20 8:48 ` Vijay Kilari
2014-05-28 10:26 ` [PATCH v4 00/16] xen/arm: Add GICv3 support Ian Campbell
2014-05-28 12:34 ` 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=1401100009-7326-15-git-send-email-vijay.kilari@gmail.com \
--to=vijay.kilari@gmail.com \
--cc=Ian.Campbell@citrix.com \
--cc=Prasun.Kapoor@caviumnetworks.com \
--cc=Vijaya.Kumar@caviumnetworks.com \
--cc=julien.grall@linaro.org \
--cc=stefano.stabellini@citrix.com \
--cc=stefano.stabellini@eu.citrix.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).