[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 5/9] xen/arm: vgic: Re-order the register emulations to match the memory map



It helps to find quickly whether we forgot to emulate a register or not.

At the same time add the missing reserved/implementation defined
registers. All other missing registers will be added in a follow-up if
necessary.

Note that only the distributor register map explicitely say the
size of a register (see 8.8 in ARM IHI 0069A). When the size is not
known, the implementation defined/reserved may not be emulated
correctly.

Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>

---

Note that the reserved range after IROUTER<n> is overlapping in the
spec. It has been fixup in the code to avoid a build error.
---
 xen/arch/arm/vgic-v2.c | 177 ++++++++++++++++++-----------
 xen/arch/arm/vgic-v3.c | 298 +++++++++++++++++++++++++++++++++++--------------
 2 files changed, 328 insertions(+), 147 deletions(-)

diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
index d1860a9..2c73133 100644
--- a/xen/arch/arm/vgic-v2.c
+++ b/xen/arch/arm/vgic-v2.c
@@ -210,9 +210,14 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, 
mmio_info_t *info,
         *r = vgic_reg32_extract(0x0000043b, info);
         return 1;
 
-    /* Implementation defined -- read as zero */
-    case 0x020 ... 0x03c:
-        goto read_as_zero;
+    case VRANGE32(0x00C, 0x01C):
+        goto read_reserved;
+
+    case VRANGE32(0x020, 0x03C):
+        goto read_impl_defined;
+
+    case VRANGE32(0x040, 0x07C):
+        goto read_reserved;
 
     case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
         /* We do not implement security extensions for guests, read zero */
@@ -246,21 +251,6 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, 
mmio_info_t *info,
     case VRANGE32(GICD_ICACTIVER, GICD_ICACTIVERN):
         goto read_as_zero;
 
-    case VRANGE32(GICD_ITARGETSR, GICD_ITARGETSRN):
-    {
-        uint32_t itargetsr;
-
-        if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
-        rank = vgic_rank_offset(v, 8, gicd_reg - GICD_ITARGETSR, DABT_WORD);
-        if ( rank == NULL) goto read_as_zero;
-        vgic_lock_rank(v, rank, flags);
-        itargetsr = vgic_fetch_itargetsr(rank, gicd_reg - GICD_ITARGETSR);
-        vgic_unlock_rank(v, rank, flags);
-        *r = vgic_reg32_extract(itargetsr, info);
-
-        return 1;
-    }
-
     case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
     {
         uint32_t ipriorityr;
@@ -279,6 +269,27 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, 
mmio_info_t *info,
         return 1;
     }
 
+    case VREG32(0x7FC):
+        goto read_reserved;
+
+    case VRANGE32(GICD_ITARGETSR, GICD_ITARGETSRN):
+    {
+        uint32_t itargetsr;
+
+        if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
+        rank = vgic_rank_offset(v, 8, gicd_reg - GICD_ITARGETSR, DABT_WORD);
+        if ( rank == NULL) goto read_as_zero;
+        vgic_lock_rank(v, rank, flags);
+        itargetsr = vgic_fetch_itargetsr(rank, gicd_reg - GICD_ITARGETSR);
+        vgic_unlock_rank(v, rank, flags);
+        *r = vgic_reg32_extract(itargetsr, info);
+
+        return 1;
+    }
+
+    case VREG32(0xBFC):
+        goto read_reserved;
+
     case VRANGE32(GICD_ICFGR, GICD_ICFGRN):
     {
         uint32_t icfgr;
@@ -295,6 +306,9 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, 
mmio_info_t *info,
         return 1;
     }
 
+    case VRANGE32(0xD00, 0xDFC):
+        goto read_impl_defined;
+
     case VRANGE32(GICD_NSACR, GICD_NSACRN):
         /* We do not implement security extensions for guests, read zero */
         goto read_as_zero_32;
@@ -305,32 +319,27 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, 
mmio_info_t *info,
         *r = 0xdeadbeef;
         return 1;
 
+    case VRANGE32(0xF04, 0xF0C):
+        goto read_reserved;
+
     /* Setting/Clearing the SGI pending bit via GICD is not supported */
     case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
     case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
         goto read_as_zero;
 
-    /* Implementation defined -- read as zero */
-    case 0xfd0 ... 0xfe4:
-        goto read_as_zero;
+    case VRANGE32(0xF30, 0xFCC):
+        goto read_reserved;
+
+    case VRANGE32(0xFD0, 0xFE4):
+        goto read_impl_defined;
 
     case VREG32(GICD_ICPIDR2):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR "%pv: vGICD: unhandled read from ICPIDR2\n", v);
         return 0;
 
-    /* Implementation defined -- read as zero */
-    case 0xfec ... 0xffc:
-        goto read_as_zero;
-
-    /* Reserved -- read as zero */
-    case 0x00c ... 0x01c:
-    case 0x040 ... 0x07c:
-    case 0x7fc:
-    case 0xbfc:
-    case 0xf04 ... 0xf0c:
-    case 0xf30 ... 0xfcc:
-        goto read_as_zero;
+    case VRANGE32(0xFEC, 0xFFC):
+        goto read_impl_defined;
 
     default:
         printk(XENLOG_G_ERR "%pv: vGICD: unhandled read r%d offset %#08x\n",
@@ -349,6 +358,20 @@ read_as_zero_32:
 read_as_zero:
     *r = 0;
     return 1;
+
+read_impl_defined:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICD: RAZ on implemention defined register offset %#08x\n",
+           v, gicd_reg);
+    *r = 0;
+    return 1;
+
+read_reserved:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICD: RAZ on reserved register offset %#08x\n",
+           v, gicd_reg);
+    *r = 0;
+    return 1;
 }
 
 static int vgic_v2_to_sgi(struct vcpu *v, register_t sgir)
@@ -414,9 +437,14 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, 
mmio_info_t *info,
     case VREG32(GICD_IIDR):
         goto write_ignore_32;
 
-    /* Implementation defined -- write ignored */
-    case 0x020 ... 0x03c:
-        goto write_ignore;
+    case VRANGE32(0x00C, 0x01C):
+        goto write_reserved;
+
+    case VRANGE32(0x020, 0x03C):
+        goto write_impl_defined;
+
+    case VRANGE32(0x040, 0x07C):
+        goto write_reserved;
 
     case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
         /* We do not implement security extensions for guests, write ignore */
@@ -472,6 +500,25 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, 
mmio_info_t *info,
                v, r, gicd_reg - GICD_ICACTIVER);
         return 0;
 
+    case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
+    {
+        uint32_t *ipriorityr;
+
+        if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
+        rank = vgic_rank_offset(v, 8, gicd_reg - GICD_IPRIORITYR, DABT_WORD);
+        if ( rank == NULL) goto write_ignore;
+        vgic_lock_rank(v, rank, flags);
+        ipriorityr = &rank->ipriorityr[REG_RANK_INDEX(8,
+                                                      gicd_reg - 
GICD_IPRIORITYR,
+                                                      DABT_WORD)];
+        vgic_reg32_update(ipriorityr, r, info);
+        vgic_unlock_rank(v, rank, flags);
+        return 1;
+    }
+
+    case VREG32(0x7FC):
+        goto write_reserved;
+
     case VRANGE32(GICD_ITARGETSR, GICD_ITARGETSR7):
         /* SGI/PPI target is read only */
         goto write_ignore_32;
@@ -492,21 +539,8 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, 
mmio_info_t *info,
         return 1;
     }
 
-    case VRANGE32(GICD_IPRIORITYR, GICD_IPRIORITYRN):
-    {
-        uint32_t *ipriorityr;
-
-        if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
-        rank = vgic_rank_offset(v, 8, gicd_reg - GICD_IPRIORITYR, DABT_WORD);
-        if ( rank == NULL) goto write_ignore;
-        vgic_lock_rank(v, rank, flags);
-        ipriorityr = &rank->ipriorityr[REG_RANK_INDEX(8,
-                                                      gicd_reg - 
GICD_IPRIORITYR,
-                                                      DABT_WORD)];
-        vgic_reg32_update(ipriorityr, r, info);
-        vgic_unlock_rank(v, rank, flags);
-        return 1;
-    }
+    case VREG32(0xBFC):
+        goto write_reserved;
 
     case VREG32(GICD_ICFGR): /* SGIs */
         goto write_ignore_32;
@@ -526,6 +560,9 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, 
mmio_info_t *info,
         vgic_unlock_rank(v, rank, flags);
         return 1;
 
+    case VRANGE32(0xD00, 0xDFC):
+        goto write_impl_defined;
+
     case VRANGE32(GICD_NSACR, GICD_NSACRN):
         /* We do not implement security extensions for guests, write ignore */
         goto write_ignore_32;
@@ -534,6 +571,9 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, 
mmio_info_t *info,
         if ( dabt.size != DABT_WORD ) goto bad_width;
         return vgic_v2_to_sgi(v, r);
 
+    case VRANGE32(0xF04, 0xF0C):
+        goto write_reserved;
+
     case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
         if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width;
         printk(XENLOG_G_ERR
@@ -548,26 +588,19 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, 
mmio_info_t *info,
                v, dabt.size ? "word" : "byte", r, gicd_reg - GICD_SPENDSGIR);
         return 0;
 
-    /* Implementation defined -- write ignored */
-    case 0xfd0 ... 0xfe4:
-        goto write_ignore;
+    case VRANGE32(0xF30, 0xFCC):
+        goto write_reserved;
+
+    case VRANGE32(0xFD0, 0xFE4):
+        /* Implementation defined identification registers */
+        goto write_impl_defined;
 
     /* R/O -- write ignore */
     case VREG32(GICD_ICPIDR2):
         goto write_ignore_32;
 
-    /* Implementation defined -- write ignored */
-    case 0xfec ... 0xffc:
-        goto write_ignore;
-
-    /* Reserved -- write ignored */
-    case 0x00c ... 0x01c:
-    case 0x040 ... 0x07c:
-    case 0x7fc:
-    case 0xbfc:
-    case 0xf04 ... 0xf0c:
-    case 0xf30 ... 0xfcc:
-        goto write_ignore;
+    case VRANGE32(0xFEC, 0xFFC):
+        /* Implementation defined identification registers */
 
     default:
         printk(XENLOG_G_ERR
@@ -587,6 +620,18 @@ write_ignore_32:
     if ( dabt.size != DABT_WORD ) goto bad_width;
 write_ignore:
     return 1;
+
+write_impl_defined:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICD: WI on implementation defined register offset %#08x\n",
+           v, gicd_reg);
+    return 1;
+
+write_reserved:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICD: WI on implementation defined register offset %#08x\n",
+           v, gicd_reg);
+    return 1;
 }
 
 static const struct mmio_handler_ops vgic_v2_distr_mmio_handler = {
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index 28f075a..f9d8ecb 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -210,6 +210,12 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, 
mmio_info_t *info,
         /* Power management is not implemented */
         goto read_as_zero_32;
 
+    case 0x0018:
+        goto read_reserved;
+
+    case 0x0020:
+        goto read_impl_defined;
+
     case VREG64(GICR_SETLPIR):
         /* WO. Read as zero */
         goto read_as_zero_64;
@@ -218,6 +224,9 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, 
mmio_info_t *info,
         /* WO. Read as zero */
         goto read_as_zero_64;
 
+    case 0x0050:
+        goto read_reserved;
+
     case VREG64(GICR_PROPBASER):
         /* LPI's not implemented */
         goto read_as_zero_64;
@@ -226,27 +235,48 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, 
mmio_info_t *info,
         /* LPI's not implemented */
         goto read_as_zero_64;
 
+    case 0x0080:
+        goto read_reserved;
+
     case VREG64(GICR_INVLPIR):
         /* WO. Read as zero */
         goto read_as_zero_64;
 
+    case 0x00A8:
+        goto read_reserved;
+
     case VREG64(GICR_INVALLR):
         /* WO. Read as zero */
         goto read_as_zero_64;
         return 0;
 
+    case 0x00B8:
+        goto read_reserved;
+
     case VREG32(GICR_SYNCR):
         if ( dabt.size != DABT_WORD ) goto bad_width;
         /* RO . But when read it always returns busy bito bit[0] */
         *r = vgic_reg32_extract(GICR_SYNCR_NOT_BUSY, info);
         return 1;
 
+    case 0x00C8:
+        goto read_reserved;
+
     case VREG64(0x0100):
         goto read_impl_defined;
 
+    case 0x0108:
+        goto read_reserved;
+
     case VREG64(0x0110):
         goto read_impl_defined;
 
+    case 0x0118 ... 0xBFFC:
+        goto read_reserved;
+
+    case 0xC000 ... 0xFFCC:
+        goto read_impl_defined;
+
     case 0xFFD0 ... 0xFFE4:
         /* Implementation defined identification registers */
        goto read_impl_defined;
@@ -284,7 +314,14 @@ read_as_zero_32:
 
 read_impl_defined:
     printk(XENLOG_G_DEBUG
-           "%pv: vGICR: RAZ on implemention defined register offset %#08x\n",
+           "%pv: vGICR: RAZ on implementation defined register offset %#08x\n",
+           v, gicr_reg);
+    *r = 0;
+    return 1;
+
+read_reserved:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICR: RAZ on reserved register offset %#08x\n",
            v, gicr_reg);
     *r = 0;
     return 1;
@@ -318,6 +355,12 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, 
mmio_info_t *info,
         /* Power mgmt not implemented */
         goto write_ignore_32;
 
+    case 0x0018:
+        goto write_reserved;
+
+    case 0x0020:
+        goto write_impl_defined;
+
     case VREG64(GICR_SETLPIR):
         /* LPI is not implemented */
         goto write_ignore_64;
@@ -326,6 +369,9 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, 
mmio_info_t *info,
         /* LPI is not implemented */
         goto write_ignore_64;
 
+    case 0x0050:
+        goto write_reserved;
+
     case VREG64(GICR_PROPBASER):
         /* LPI is not implemented */
         goto write_ignore_64;
@@ -334,24 +380,45 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, 
mmio_info_t *info,
         /* LPI is not implemented */
         goto write_ignore_64;
 
+    case 0x0080:
+        goto write_reserved;
+
     case VREG64(GICR_INVLPIR):
         /* LPI is not implemented */
         goto write_ignore_64;
 
+    case 0x00A8:
+        goto write_reserved;
+
     case VREG64(GICR_INVALLR):
         /* LPI is not implemented */
         goto write_ignore_64;
 
+    case 0x00B8:
+        goto write_reserved;
+
     case VREG32(GICR_SYNCR):
         /* RO */
         goto write_ignore_32;
 
+    case 0x00C8:
+        goto write_reserved;
+
     case VREG64(0x0100):
         goto write_impl_defined;
 
+    case 0x0108:
+        goto write_reserved;
+
     case VREG64(0x0110):
         goto write_impl_defined;
 
+    case 0x0118 ... 0xBFFC:
+        goto write_reserved;
+
+    case 0xC000 ... 0xFFCC:
+        goto write_impl_defined;
+
     case 0xFFD0 ... 0xFFE4:
         /* Implementation defined identification registers */
        goto write_impl_defined;
@@ -389,6 +456,12 @@ write_impl_defined:
            "%pv: vGICR: WI on implementation defined register offset %#08x\n",
            v, gicr_reg);
     return 1;
+
+write_reserved:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICR: WI on reserved register offset %#08x\n",
+           v, gicr_reg);
+    return 1;
 }
 
 static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
@@ -609,10 +682,6 @@ static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, 
mmio_info_t *info,
 
     switch ( gicr_reg )
     {
-    case VREG32(GICR_IGRPMODR0):
-        /* We do not implement security extensions for guests, read zero */
-        goto read_as_zero_32;
-
     case VREG32(GICR_IGROUPR0):
     case VREG32(GICR_ISENABLER0):
     case VREG32(GICR_ICENABLER0):
@@ -632,10 +701,23 @@ static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, 
mmio_info_t *info,
     case VREG32(GICR_ICPENDR0):
         goto read_as_zero;
 
+    case VREG32(GICR_IGRPMODR0):
+        /* We do not implement security extensions for guests, read zero */
+        goto read_as_zero_32;
+
     case VREG32(GICR_NSACR):
         /* We do not implement security extensions for guests, read zero */
         goto read_as_zero_32;
 
+    case 0x0E04 ... 0xBFFC:
+        goto read_reserved;
+
+    case 0xC000 ... 0xFFCC:
+        goto read_impl_defined;
+
+    case 0xFFD0 ... 0xFFFC:
+        goto read_reserved;
+
     default:
         printk(XENLOG_G_ERR
                "%pv: vGICR: SGI: unhandled read r%d offset %#08x\n",
@@ -653,6 +735,21 @@ read_as_zero_32:
 read_as_zero:
     *r = 0;
     return 1;
+
+read_impl_defined:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICR: SGI: RAZ on implementation defined register offset 
%#08x\n",
+           v, gicr_reg);
+    *r = 0;
+    return 1;
+
+read_reserved:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICR: SGI: RAZ on reserved register offset %#08x\n",
+           v, gicr_reg);
+    *r = 0;
+    return 1;
+
 }
 
 static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, mmio_info_t *info,
@@ -662,10 +759,6 @@ static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, 
mmio_info_t *info,
 
     switch ( gicr_reg )
     {
-    case VREG32(GICR_IGRPMODR0):
-        /* We do not implement security extensions for guests, write ignore */
-        goto write_ignore_32;
-
     case VREG32(GICR_IGROUPR0):
     case VREG32(GICR_ISENABLER0):
     case VREG32(GICR_ICENABLER0):
@@ -694,6 +787,11 @@ static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, 
mmio_info_t *info,
                v, r);
         return 0;
 
+    case VREG32(GICR_IGRPMODR0):
+        /* We do not implement security extensions for guests, write ignore */
+        goto write_ignore_32;
+
+
     case VREG32(GICR_NSACR):
         /* We do not implement security extensions for guests, write ignore */
         goto write_ignore_32;
@@ -829,6 +927,14 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, 
mmio_info_t *info,
         return 1;
     }
 
+    case VREG32(GICD_IIDR):
+        if ( dabt.size != DABT_WORD ) goto bad_width;
+        *r = vgic_reg32_extract(GICV3_GICD_IIDR_VAL, info);
+        return 1;
+
+    case VREG32(0x000C):
+        goto read_reserved;
+
     case VREG32(GICD_STATUSR):
         /*
          *  Optional, Not implemented for now.
@@ -836,15 +942,23 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, 
mmio_info_t *info,
          */
         goto read_as_zero_32;
 
-    case VREG32(GICD_IIDR):
-        if ( dabt.size != DABT_WORD ) goto bad_width;
-        *r = vgic_reg32_extract(GICV3_GICD_IIDR_VAL, info);
-        return 1;
+    case VRANGE32(0x0014, 0x001C):
+        goto read_reserved;
 
-    case 0x020 ... 0x03c:
-    case 0xc000 ... 0xffcc:
-        /* Implementation defined -- read as zero */
-        goto read_as_zero_32;
+    case VRANGE32(0x0020, 0x003C):
+        goto read_impl_defined;
+
+    case VREG32(0x0044):
+        goto read_reserved;
+
+    case VREG32(0x004C):
+        goto read_reserved;
+
+    case VREG32(0x0054):
+        goto read_reserved;
+
+    case VRANGE32(0x005C, 0x007C):
+        goto read_reserved;
 
     case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
     case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
@@ -860,6 +974,25 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, 
mmio_info_t *info,
          */
         return __vgic_v3_distr_common_mmio_read("vGICD", v, info, gicd_reg, r);
 
+    case VRANGE32(GICD_NSACR, GICD_NSACRN):
+        /* We do not implement security extensions for guests, read zero */
+        goto read_as_zero_32;
+
+    case VREG32(GICD_SGIR):
+        /* Read as ICH_SGIR system register with SRE set. So ignore */
+        goto read_as_zero_32;
+
+    case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
+        /* Replaced with GICR_ICPENDR0. So ignore write */
+        goto read_as_zero_32;
+
+    case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
+        /* Replaced with GICR_ISPENDR0. So ignore write */
+        goto read_as_zero_32;
+
+    case VRANGE32(0x0F30, 0x60FC):
+        goto read_reserved;
+
     case VRANGE64(GICD_IROUTER32, GICD_IROUTER1019):
     {
         uint64_t irouter;
@@ -877,23 +1010,13 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, 
mmio_info_t *info,
         return 1;
     }
 
-    case VRANGE32(GICD_NSACR, GICD_NSACRN):
-        /* We do not implement security extensions for guests, read zero */
-        goto read_as_zero_32;
+    case VRANGE32(0x7FE0, 0xBFFC):
+        goto read_reserved;
 
-    case VREG32(GICD_SGIR):
-        /* Read as ICH_SGIR system register with SRE set. So ignore */
-        goto read_as_zero_32;
-
-    case VRANGE32(GICD_CPENDSGIR, GICD_CPENDSGIRN):
-        /* Replaced with GICR_ICPENDR0. So ignore write */
-        goto read_as_zero_32;
-
-    case VRANGE32(GICD_SPENDSGIR, GICD_SPENDSGIRN):
-        /* Replaced with GICR_ISPENDR0. So ignore write */
-        goto read_as_zero_32;
+    case VRANGE32(0xC000, 0xFFCC):
+        goto read_impl_defined;
 
-    case 0xFFD0 ... 0xFFE4:
+    case VRANGE32(0xFFD0, 0xFFE4):
         /* Implementation defined identification registers */
        goto read_impl_defined;
 
@@ -903,21 +1026,10 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, 
mmio_info_t *info,
         *r = vgic_reg32_extract(GICV3_GICD_PIDR2, info);
         return 1;
 
-    case 0xFFEC ... 0xFFFC:
+    case VRANGE32(0xFFEC, 0xFFFC):
          /* Implementation defined identification registers */
          goto read_impl_defined;
 
-    case 0x00c:
-    case 0x044:
-    case 0x04c:
-    case 0x05c ... 0x07c:
-    case 0xf30 ... 0x5fcc:
-    case 0x8000 ... 0xbfcc:
-        /* These are reserved register addresses */
-        printk(XENLOG_G_DEBUG
-               "%pv: vGICD: RAZ on reserved register offset %#08x\n",
-               v, gicd_reg);
-        goto read_as_zero;
     default:
         printk(XENLOG_G_ERR "%pv: vGICD: unhandled read r%d offset %#08x\n",
                v, dabt.reg, gicd_reg);
@@ -941,7 +1053,14 @@ read_as_zero:
 
 read_impl_defined:
     printk(XENLOG_G_DEBUG
-           "%pv: vGICD: RAZ on implemention defined register offset %#08x\n",
+           "%pv: vGICD: RAZ on implementation defined register offset %#08x\n",
+           v, gicd_reg);
+    *r = 0;
+    return 1;
+
+read_reserved:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICD: RAZ on reserved register offset %#08x\n",
            v, gicd_reg);
     *r = 0;
     return 1;
@@ -987,33 +1106,46 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, 
mmio_info_t *info,
         /* RO -- write ignored */
         goto write_ignore_32;
 
+    case VREG32(0x000C):
+        goto write_reserved;
+
     case VREG32(GICD_STATUSR):
         /* RO -- write ignored */
         goto write_ignore_32;
 
+    case VRANGE32(0x0014, 0x001C):
+        goto write_reserved;
+
+    case VRANGE32(0x0020, 0x003C):
+        goto write_impl_defined;
+
     case VREG32(GICD_SETSPI_NSR):
         /* Message based SPI is not implemented */
         goto write_ignore_32;
 
+    case VREG32(0x0044):
+        goto write_reserved;
+
     case VREG32(GICD_CLRSPI_NSR):
         /* Message based SPI is not implemented */
         goto write_ignore_32;
 
+    case VREG32(0x004C):
+        goto write_reserved;
+
     case VREG32(GICD_SETSPI_SR):
         /* Message based SPI is not implemented */
         goto write_ignore_32;
 
+    case VREG32(0x0054):
+        goto write_reserved;
+
     case VREG32(GICD_CLRSPI_SR):
         /* Message based SPI is not implemented */
         goto write_ignore_32;
 
-    case 0x020 ... 0x03c:
-    case 0xc000 ... 0xffcc:
-        /* Implementation defined -- write ignored */
-        printk(XENLOG_G_DEBUG
-               "%pv: vGICD: WI on implementation defined register offset 
%#08x\n",
-               v, gicd_reg);
-        goto write_ignore_32;
+    case VRANGE32(0x005C, 0x007C):
+        goto write_reserved;
 
     case VRANGE32(GICD_IGROUPR, GICD_IGROUPRN):
     case VRANGE32(GICD_ISENABLER, GICD_ISENABLERN):
@@ -1029,22 +1161,6 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, 
mmio_info_t *info,
         return __vgic_v3_distr_common_mmio_write("vGICD", v, info,
                                                  gicd_reg, r);
 
-    case VRANGE64(GICD_IROUTER32, GICD_IROUTER1019):
-    {
-        uint64_t irouter;
-
-        if ( !vgic_reg64_check_access(dabt) ) goto bad_width;
-        rank = vgic_rank_offset(v, 64, gicd_reg - GICD_IROUTER,
-                                DABT_DOUBLE_WORD);
-        if ( rank == NULL ) goto write_ignore;
-        vgic_lock_rank(v, rank, flags);
-        irouter = vgic_fetch_irouter(rank, gicd_reg - GICD_IROUTER);
-        vgic_reg64_update(&irouter, r, info);
-        vgic_store_irouter(v->domain, rank, gicd_reg - GICD_IROUTER, irouter);
-        vgic_unlock_rank(v, rank, flags);
-        return 1;
-    }
-
     case VRANGE32(GICD_NSACR, GICD_NSACRN):
         /* We do not implement security extensions for guests, write ignore */
         goto write_ignore_32;
@@ -1063,7 +1179,32 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, 
mmio_info_t *info,
         if ( dabt.size != DABT_WORD ) goto bad_width;
         return 0;
 
-    case 0xFFD0 ... 0xFFE4:
+    case VRANGE32(0x0F30, 0x60FC):
+        goto write_reserved;
+
+    case VRANGE64(GICD_IROUTER32, GICD_IROUTER1019):
+    {
+        uint64_t irouter;
+
+        if ( !vgic_reg64_check_access(dabt) ) goto bad_width;
+        rank = vgic_rank_offset(v, 64, gicd_reg - GICD_IROUTER,
+                                DABT_DOUBLE_WORD);
+        if ( rank == NULL ) goto write_ignore;
+        vgic_lock_rank(v, rank, flags);
+        irouter = vgic_fetch_irouter(rank, gicd_reg - GICD_IROUTER);
+        vgic_reg64_update(&irouter, r, info);
+        vgic_store_irouter(v->domain, rank, gicd_reg - GICD_IROUTER, irouter);
+        vgic_unlock_rank(v, rank, flags);
+        return 1;
+    }
+
+    case VRANGE32(0x7FE0, 0xBFFC):
+        goto write_reserved;
+
+    case VRANGE32(0xC000, 0xFFCC):
+        goto write_impl_defined;
+
+    case VRANGE32(0xFFD0, 0xFFE4):
         /* Implementation defined identification registers */
        goto write_impl_defined;
 
@@ -1071,21 +1212,10 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, 
mmio_info_t *info,
         /* RO -- write ignore */
         goto write_ignore_32;
 
-    case 0xFFEC ... 0xFFFC:
+    case VRANGE32(0xFFEC, 0xFFFC):
          /* Implementation defined identification registers */
          goto write_impl_defined;
 
-    case 0x00c:
-    case 0x044:
-    case 0x04c:
-    case 0x05c ... 0x07c:
-    case 0xf30 ... 0x5fcc:
-    case 0x8000 ... 0xbfcc:
-        /* Reserved register addresses */
-        printk(XENLOG_G_DEBUG
-               "%pv: vGICD: write unknown 0x00c 0xfcc  r%d offset %#08x\n",
-               v, dabt.reg, gicd_reg);
-        goto write_ignore;
     default:
         printk(XENLOG_G_ERR
                "%pv: vGICD: unhandled write r%d=%"PRIregister" offset %#08x\n",
@@ -1112,6 +1242,12 @@ write_impl_defined:
            "%pv: vGICD: WI on implementation defined register offset %#08x\n",
            v, gicd_reg);
     return 1;
+
+write_reserved:
+    printk(XENLOG_G_DEBUG
+           "%pv: vGICD: WI on reserved register offset %#08x\n",
+           v, gicd_reg);
+    return 1;
 }
 
 static int vgic_v3_to_sgi(struct vcpu *v, register_t sgir)
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.