]> xenbits.xensource.com Git - people/julieng/xen-unstable.git/commitdiff
xen/arm: io: Extend write/read handler to pass private data
authorJulien Grall <julien.grall@citrix.com>
Tue, 29 Sep 2015 14:44:39 +0000 (15:44 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Thu, 1 Oct 2015 12:48:45 +0000 (13:48 +0100)
Some handlers may require to use private data in order to get quickly
information related to the region emulated.

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

index 8e55d49033b2661717306d56481968f305bef81e..b8f4a18c49470647678dacd2028ead081e7f1b39 100644 (file)
@@ -27,7 +27,7 @@ int handle_mmio(mmio_info_t *info)
 {
     struct vcpu *v = current;
     int i;
-    const struct mmio_handler *mmio_handler;
+    const struct mmio_handler *mmio_handler = NULL;
     const struct io_handler *io_handlers = &v->domain->arch.io_handlers;
 
     for ( i = 0; i < io_handlers->num_entries; i++ )
@@ -36,19 +36,23 @@ int handle_mmio(mmio_info_t *info)
 
         if ( (info->gpa >= mmio_handler->addr) &&
              (info->gpa < (mmio_handler->addr + mmio_handler->size)) )
-        {
-            return info->dabt.write ?
-                mmio_handler->mmio_handler_ops->write_handler(v, info) :
-                mmio_handler->mmio_handler_ops->read_handler(v, info);
-        }
+            break;
     }
 
-    return 0;
+    if ( i == io_handlers->num_entries )
+        return 0;
+
+    if ( info->dabt.write )
+        return mmio_handler->mmio_handler_ops->write_handler(v, info,
+                                                             mmio_handler->priv);
+    else
+        return mmio_handler->mmio_handler_ops->read_handler(v, info,
+                                                            mmio_handler->priv);
 }
 
 void register_mmio_handler(struct domain *d,
                            const struct mmio_handler_ops *handle,
-                           paddr_t addr, paddr_t size)
+                           paddr_t addr, paddr_t size, void *priv)
 {
     struct io_handler *handler = &d->arch.io_handlers;
 
@@ -59,6 +63,7 @@ void register_mmio_handler(struct domain *d,
     handler->mmio_handlers[handler->num_entries].mmio_handler_ops = handle;
     handler->mmio_handlers[handler->num_entries].addr = addr;
     handler->mmio_handlers[handler->num_entries].size = size;
+    handler->mmio_handlers[handler->num_entries].priv = priv;
     dsb(ish);
     handler->num_entries++;
 
index fa7159875ac1ede460ce2ac957225efb3769e743..8e50f22ad22f3ae497a5c09925375c75cc71eb12 100644 (file)
@@ -50,7 +50,8 @@ void vgic_v2_setup_hw(paddr_t dbase, paddr_t cbase, paddr_t vbase)
     vgic_v2_hw.vbase = vbase;
 }
 
-static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info)
+static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
+                                   void *priv)
 {
     struct hsr_dabt dabt = info->dabt;
     struct cpu_user_regs *regs = guest_cpu_user_regs();
@@ -247,7 +248,8 @@ static int vgic_v2_to_sgi(struct vcpu *v, register_t sgir)
     return vgic_to_sgi(v, sgir, sgi_mode, virq, &target);
 }
 
-static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info)
+static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
+                                    void *priv)
 {
     struct hsr_dabt dabt = info->dabt;
     struct cpu_user_regs *regs = guest_cpu_user_regs();
@@ -590,7 +592,7 @@ static int vgic_v2_domain_init(struct domain *d)
                sizeof(d->arch.vgic.shared_irqs[i].v2.itargets));
 
     register_mmio_handler(d, &vgic_v2_distr_mmio_handler, d->arch.vgic.dbase,
-                          PAGE_SIZE);
+                          PAGE_SIZE, NULL);
 
     return 0;
 }
index f1c482da04705dd466e80d8e121da4ce64e95593..6a4feb2ae35ef0952af03e65762346e98c89b73f 100644 (file)
@@ -634,7 +634,8 @@ static inline struct vcpu *get_vcpu_from_rdist(paddr_t gpa,
     return d->vcpu[vcpu_id];
 }
 
-static int vgic_v3_rdistr_mmio_read(struct vcpu *v, mmio_info_t *info)
+static int vgic_v3_rdistr_mmio_read(struct vcpu *v, mmio_info_t *info,
+                                    void *priv)
 {
     uint32_t offset;
 
@@ -656,7 +657,8 @@ static int vgic_v3_rdistr_mmio_read(struct vcpu *v, mmio_info_t *info)
     return 0;
 }
 
-static int vgic_v3_rdistr_mmio_write(struct vcpu *v, mmio_info_t *info)
+static int vgic_v3_rdistr_mmio_write(struct vcpu *v, mmio_info_t *info,
+                                     void *priv)
 {
     uint32_t offset;
 
@@ -678,7 +680,8 @@ static int vgic_v3_rdistr_mmio_write(struct vcpu *v, mmio_info_t *info)
     return 0;
 }
 
-static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info)
+static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
+                                   void *priv)
 {
     struct hsr_dabt dabt = info->dabt;
     struct cpu_user_regs *regs = guest_cpu_user_regs();
@@ -835,7 +838,8 @@ read_as_zero:
     return 1;
 }
 
-static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info)
+static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
+                                    void *priv)
 {
     struct hsr_dabt dabt = info->dabt;
     struct cpu_user_regs *regs = guest_cpu_user_regs();
@@ -1200,7 +1204,7 @@ static int vgic_v3_domain_init(struct domain *d)
 
     /* Register mmio handle for the Distributor */
     register_mmio_handler(d, &vgic_distr_mmio_handler, d->arch.vgic.dbase,
-                          SZ_64K);
+                          SZ_64K, NULL);
 
     /*
      * Register mmio handler per contiguous region occupied by the
@@ -1210,7 +1214,8 @@ static int vgic_v3_domain_init(struct domain *d)
     for ( i = 0; i < d->arch.vgic.nr_regions; i++ )
         register_mmio_handler(d, &vgic_rdistr_mmio_handler,
             d->arch.vgic.rdist_regions[i].base,
-            d->arch.vgic.rdist_regions[i].size);
+            d->arch.vgic.rdist_regions[i].size,
+            NULL);
 
     d->arch.vgic.ctlr = VGICD_CTLR_DEFAULT;
 
index d9f4249652c573946e57c6c9e67a1f26ab859232..51d0557860816a9262e5eebc4f03debdf822f0c1 100644 (file)
@@ -45,8 +45,8 @@
 
 #define domain_has_vuart(d) ((d)->arch.vuart.info != NULL)
 
-static int vuart_mmio_read(struct vcpu *v, mmio_info_t *info);
-static int vuart_mmio_write(struct vcpu *v, mmio_info_t *info);
+static int vuart_mmio_read(struct vcpu *v, mmio_info_t *info, void *priv);
+static int vuart_mmio_write(struct vcpu *v, mmio_info_t *info, void *priv);
 
 static const struct mmio_handler_ops vuart_mmio_handler = {
     .read_handler  = vuart_mmio_read,
@@ -70,7 +70,8 @@ int domain_vuart_init(struct domain *d)
 
     register_mmio_handler(d, &vuart_mmio_handler,
                           d->arch.vuart.info->base_addr,
-                          d->arch.vuart.info->size);
+                          d->arch.vuart.info->size,
+                          NULL);
 
     return 0;
 }
@@ -105,7 +106,7 @@ static void vuart_print_char(struct vcpu *v, char c)
     spin_unlock(&uart->lock);
 }
 
-static int vuart_mmio_read(struct vcpu *v, mmio_info_t *info)
+static int vuart_mmio_read(struct vcpu *v, mmio_info_t *info, void *priv)
 {
     struct domain *d = v->domain;
     struct hsr_dabt dabt = info->dabt;
@@ -125,7 +126,7 @@ static int vuart_mmio_read(struct vcpu *v, mmio_info_t *info)
     return 1;
 }
 
-static int vuart_mmio_write(struct vcpu *v, mmio_info_t *info)
+static int vuart_mmio_write(struct vcpu *v, mmio_info_t *info, void *priv)
 {
     struct domain *d = v->domain;
     struct hsr_dabt dabt = info->dabt;
index 0160f09a38c348671e563e6f2a60874ea57b261d..294c18b3909011a6dff8d4ee131df31bbf06cda9 100644 (file)
@@ -32,8 +32,8 @@ typedef struct
     paddr_t gpa;
 } mmio_info_t;
 
-typedef int (*mmio_read_t)(struct vcpu *v, mmio_info_t *info);
-typedef int (*mmio_write_t)(struct vcpu *v, mmio_info_t *info);
+typedef int (*mmio_read_t)(struct vcpu *v, mmio_info_t *info, void *priv);
+typedef int (*mmio_write_t)(struct vcpu *v, mmio_info_t *info, void *priv);
 typedef int (*mmio_check_t)(struct vcpu *v, paddr_t addr);
 
 struct mmio_handler_ops {
@@ -45,6 +45,7 @@ struct mmio_handler {
     paddr_t addr;
     paddr_t size;
     const struct mmio_handler_ops *mmio_handler_ops;
+    void *priv;
 };
 
 struct io_handler {
@@ -56,7 +57,7 @@ struct io_handler {
 extern int handle_mmio(mmio_info_t *info);
 void register_mmio_handler(struct domain *d,
                            const struct mmio_handler_ops *handle,
-                           paddr_t addr, paddr_t size);
+                           paddr_t addr, paddr_t size, void *priv);
 int domain_io_init(struct domain *d);
 
 #endif  /* __ASM_ARM_MMIO_H__ */