]> xenbits.xensource.com Git - people/julieng/xen-unstable.git/commitdiff
xen/arm: vgic: Introduce a new field to store the rank index and use it
authorJulien Grall <julien.grall@citrix.com>
Wed, 7 Oct 2015 14:41:08 +0000 (15:41 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Thu, 8 Oct 2015 11:22:46 +0000 (12:22 +0100)
Having in hand the index for the rank is very handy to avoid computing
it every time.

For now, use it when enabling/disabling the vIRQs rather than a formula
which is not obvious to understand.

Also drop the comments which were wrong because a shift by DABT_WORD
will not give the IRQ number but the index of the register.

Signed-off-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
xen/arch/arm/vgic-v2.c
xen/arch/arm/vgic-v3.c
xen/arch/arm/vgic.c
xen/include/asm-arm/vgic.h

index ad1bb15eb898b93c43490f491ba7efa386cec043..2d63e12f5ce108b2915a8ee6197fed495f1e0415 100644 (file)
@@ -288,11 +288,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         vgic_lock_rank(v, rank, flags);
         tr = rank->ienable;
         rank->ienable |= r;
-        /* The virtual irq is derived from register offset.
-         * The register difference is word difference. So divide by 2(DABT_WORD)
-         * to get Virtual irq number */
-        vgic_enable_irqs(v, r & (~tr),
-                         (gicd_reg - GICD_ISENABLER) >> DABT_WORD);
+        vgic_enable_irqs(v, r & (~tr), rank->index);
         vgic_unlock_rank(v, rank, flags);
         return 1;
 
@@ -303,11 +299,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
         vgic_lock_rank(v, rank, flags);
         tr = rank->ienable;
         rank->ienable &= ~r;
-        /* The virtual irq is derived from register offset.
-         * The register difference is word difference. So divide by 2(DABT_WORD)
-         * to get  Virtual irq number */
-        vgic_disable_irqs(v, r & tr,
-                         (gicd_reg - GICD_ICENABLER) >> DABT_WORD);
+        vgic_disable_irqs(v, r & tr, rank->index);
         vgic_unlock_rank(v, rank, flags);
         return 1;
 
index 92a3ccfb9492974616f65fa990deb54cda6243d4..b5249ff1cd5f4ec3ca0d39b044d1a5540b25f56d 100644 (file)
@@ -386,8 +386,7 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v,
         vgic_lock_rank(v, rank, flags);
         tr = rank->ienable;
         rank->ienable |= r;
-        /* The irq number is extracted from offset. so shift by register size */
-        vgic_enable_irqs(v, r & (~tr), (reg - GICD_ISENABLER) >> DABT_WORD);
+        vgic_enable_irqs(v, r & (~tr), rank->index);
         vgic_unlock_rank(v, rank, flags);
         return 1;
     case GICD_ICENABLER ... GICD_ICENABLERN:
@@ -397,8 +396,7 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v,
         vgic_lock_rank(v, rank, flags);
         tr = rank->ienable;
         rank->ienable &= ~r;
-        /* The irq number is extracted from offset. so shift by register size */
-        vgic_disable_irqs(v, r & tr, (reg - GICD_ICENABLER) >> DABT_WORD);
+        vgic_disable_irqs(v, r & tr, rank->index);
         vgic_unlock_rank(v, rank, flags);
         return 1;
     case GICD_ISPENDR ... GICD_ISPENDRN:
index 2128d2934e28b0804b8ec6ba36c32225f2784045..7bb457075bb7a4ffd17cfc5c49bc669ea53dcb5b 100644 (file)
@@ -68,6 +68,13 @@ static void vgic_init_pending_irq(struct pending_irq *p, unsigned int virq)
     p->irq = virq;
 }
 
+static void vgic_rank_init(struct vgic_irq_rank *rank, uint8_t index)
+{
+    spin_lock_init(&rank->lock);
+
+    rank->index = index;
+}
+
 int domain_vgic_init(struct domain *d, unsigned int nr_spis)
 {
     int i;
@@ -114,8 +121,8 @@ int domain_vgic_init(struct domain *d, unsigned int nr_spis)
     for (i=0; i<d->arch.vgic.nr_spis; i++)
         vgic_init_pending_irq(&d->arch.vgic.pending_irqs[i], i + 32);
 
-    for (i=0; i<DOMAIN_NR_RANKS(d); i++)
-        spin_lock_init(&d->arch.vgic.shared_irqs[i].lock);
+    for ( i = 0; i < DOMAIN_NR_RANKS(d); i++ )
+        vgic_rank_init(&d->arch.vgic.shared_irqs[i], i + 1);
 
     ret = d->arch.vgic.handler->domain_init(d);
     if ( ret )
@@ -169,7 +176,7 @@ int vcpu_vgic_init(struct vcpu *v)
     if ( v->arch.vgic.private_irqs == NULL )
       return -ENOMEM;
 
-    spin_lock_init(&v->arch.vgic.private_irqs->lock);
+    vgic_rank_init(v->arch.vgic.private_irqs, 0);
 
     v->domain->arch.vgic.handler->vcpu_init(v);
 
index ff989139477b8c6b628db2bf1c4911122ef001e9..ba74d0f5946136fb1cf5851b79608f11ea6f2852 100644 (file)
@@ -88,6 +88,9 @@ struct pending_irq
 /* Represents state corresponding to a block of 32 interrupts */
 struct vgic_irq_rank {
     spinlock_t lock; /* Covers access to all other members of this struct */
+
+    uint8_t index;
+
     uint32_t ienable;
     uint32_t icfg[2];