All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
To: joro@8bytes.org
Cc: paul@codesourcery.com, blauwirbel@gmail.com,
	anthony@codemonkey.ws, avi@redhat.com, kvm@vger.kernel.org,
	qemu-devel@nongnu.org,
	Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
Subject: [PATCH 2/7] pci: memory access API and IOMMU support
Date: Sun, 15 Aug 2010 22:27:17 +0300	[thread overview]
Message-ID: <1281900442-29971-3-git-send-email-eduard.munteanu@linux360.ro> (raw)
In-Reply-To: <1281900442-29971-1-git-send-email-eduard.munteanu@linux360.ro>

PCI devices should access memory through pci_memory_*() instead of
cpu_physical_memory_*(). This also provides support for translation and
access checking in case an IOMMU is emulated.

Memory maps are treated as remote IOTLBs (that is, translation caches
belonging to the IOMMU-aware device itself). Clients (devices) must
provide callbacks for map invalidation in case these maps are
persistent beyond the current I/O context, e.g. AIO DMA transfers.

Signed-off-by: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
---
 hw/pci.c      |  197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 hw/pci.h      |   74 +++++++++++++++++++++
 qemu-common.h |    1 +
 3 files changed, 271 insertions(+), 1 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 6871728..8668e06 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -58,6 +58,18 @@ struct PCIBus {
        Keep a count of the number of devices with raised IRQs.  */
     int nirq;
     int *irq_count;
+
+    PCIDevice                       *iommu;
+    PCITranslateFunc                *translate;
+};
+
+struct PCIMemoryMap {
+    pcibus_t                        addr;
+    pcibus_t                        len;
+    target_phys_addr_t              paddr;
+    PCIInvalidateMapFunc            *invalidate;
+    void                            *invalidate_opaque;
+    QLIST_ENTRY(PCIMemoryMap)       list;
 };
 
 static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
@@ -166,6 +178,19 @@ static void pci_device_reset(PCIDevice *dev)
     pci_update_mappings(dev);
 }
 
+static int pci_no_translate(PCIDevice *iommu,
+                            PCIDevice *dev,
+                            pcibus_t addr,
+                            target_phys_addr_t *paddr,
+                            target_phys_addr_t *len,
+                            unsigned perms)
+{
+    *paddr = addr;
+    *len = -1;
+
+    return 0;
+}
+
 static void pci_bus_reset(void *opaque)
 {
     PCIBus *bus = opaque;
@@ -227,7 +252,10 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
                          const char *name, int devfn_min)
 {
     qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
-    bus->devfn_min = devfn_min;
+
+    bus->devfn_min              = devfn_min;
+    bus->iommu                  = NULL;
+    bus->translate              = pci_no_translate;
 
     /* host bridge */
     QLIST_INIT(&bus->child);
@@ -2029,6 +2057,173 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
     }
 }
 
+void pci_register_iommu(PCIDevice *iommu,
+                        PCITranslateFunc *translate)
+{
+    iommu->bus->iommu = iommu;
+    iommu->bus->translate = translate;
+}
+
+void pci_memory_rw(PCIDevice *dev,
+                   pcibus_t addr,
+                   uint8_t *buf,
+                   pcibus_t len,
+                   int is_write)
+{
+    int err;
+    unsigned perms;
+    PCIDevice *iommu = dev->bus->iommu;
+    target_phys_addr_t paddr, plen;
+
+    perms = is_write ? IOMMU_PERM_WRITE : IOMMU_PERM_READ;
+
+    while (len) {
+        err = dev->bus->translate(iommu, dev, addr, &paddr, &plen, perms);
+        if (err)
+            return;
+
+        /* The translation might be valid for larger regions. */
+        if (plen > len)
+            plen = len;
+
+        cpu_physical_memory_rw(paddr, buf, plen, is_write);
+
+        len -= plen;
+        addr += plen;
+        buf += plen;
+    }
+}
+
+static void pci_memory_register_map(PCIDevice *dev,
+                                    pcibus_t addr,
+                                    pcibus_t len,
+                                    target_phys_addr_t paddr,
+                                    PCIInvalidateMapFunc *invalidate,
+                                    void *invalidate_opaque)
+{
+    PCIMemoryMap *map;
+
+    map = qemu_malloc(sizeof(PCIMemoryMap));
+    map->addr               = addr;
+    map->len                = len;
+    map->paddr              = paddr;
+    map->invalidate         = invalidate;
+    map->invalidate_opaque  = invalidate_opaque;
+
+    QLIST_INSERT_HEAD(&dev->memory_maps, map, list);
+}
+
+static void pci_memory_unregister_map(PCIDevice *dev,
+                                      target_phys_addr_t paddr,
+                                      target_phys_addr_t len)
+{
+    PCIMemoryMap *map;
+
+    QLIST_FOREACH(map, &dev->memory_maps, list) {
+        if (map->paddr == paddr && map->len == len) {
+            QLIST_REMOVE(map, list);
+            free(map);
+        }
+    }
+}
+
+void pci_memory_invalidate_range(PCIDevice *dev,
+                                 pcibus_t addr,
+                                 pcibus_t len)
+{
+    PCIMemoryMap *map;
+
+    QLIST_FOREACH(map, &dev->memory_maps, list) {
+        if (range_covers_range(addr, len, map->addr, map->len)) {
+            map->invalidate(map->invalidate_opaque);
+            QLIST_REMOVE(map, list);
+            free(map);
+        }
+    }
+}
+
+void *pci_memory_map(PCIDevice *dev,
+                     PCIInvalidateMapFunc *cb,
+                     void *opaque,
+                     pcibus_t addr,
+                     target_phys_addr_t *len,
+                     int is_write)
+{
+    int err;
+    unsigned perms;
+    PCIDevice *iommu = dev->bus->iommu;
+    target_phys_addr_t paddr, plen;
+
+    perms = is_write ? IOMMU_PERM_WRITE : IOMMU_PERM_READ;
+
+    plen = *len;
+    err = dev->bus->translate(iommu, dev, addr, &paddr, &plen, perms);
+    if (err)
+        return NULL;
+
+    /*
+     * If this is true, the virtual region is contiguous,
+     * but the translated physical region isn't. We just
+     * clamp *len, much like cpu_physical_memory_map() does.
+     */
+    if (plen < *len)
+        *len = plen;
+
+    /* We treat maps as remote TLBs to cope with stuff like AIO. */
+    if (cb)
+        pci_memory_register_map(dev, addr, *len, paddr, cb, opaque);
+
+    return cpu_physical_memory_map(paddr, len, is_write);
+}
+
+void pci_memory_unmap(PCIDevice *dev,
+                      void *buffer,
+                      target_phys_addr_t len,
+                      int is_write,
+                      target_phys_addr_t access_len)
+{
+    cpu_physical_memory_unmap(buffer, len, is_write, access_len);
+    pci_memory_unregister_map(dev, (target_phys_addr_t) buffer, len);
+}
+
+#define DEFINE_PCI_LD(suffix, size)                                       \
+uint##size##_t pci_ld##suffix(PCIDevice *dev, pcibus_t addr)              \
+{                                                                         \
+    int err;                                                              \
+    target_phys_addr_t paddr, plen;                                       \
+                                                                          \
+    err = dev->bus->translate(dev->bus->iommu, dev,                       \
+                              addr, &paddr, &plen, IOMMU_PERM_READ);      \
+    if (err || (plen < size / 8))                                         \
+        return 0;                                                         \
+                                                                          \
+    return ld##suffix##_phys(paddr);                                      \
+}
+
+#define DEFINE_PCI_ST(suffix, size)                                       \
+void pci_st##suffix(PCIDevice *dev, pcibus_t addr, uint##size##_t val)    \
+{                                                                         \
+    int err;                                                              \
+    target_phys_addr_t paddr, plen;                                       \
+                                                                          \
+    err = dev->bus->translate(dev->bus->iommu, dev,                       \
+                              addr, &paddr, &plen, IOMMU_PERM_WRITE);     \
+    if (err || (plen < size / 8))                                         \
+        return;                                                           \
+                                                                          \
+    st##suffix##_phys(paddr, val);                                        \
+}
+
+DEFINE_PCI_LD(ub, 8)
+DEFINE_PCI_LD(uw, 16)
+DEFINE_PCI_LD(l, 32)
+DEFINE_PCI_LD(q, 64)                  
+
+DEFINE_PCI_ST(b, 8)
+DEFINE_PCI_ST(w, 16)
+DEFINE_PCI_ST(l, 32)
+DEFINE_PCI_ST(q, 64)
+
 static PCIDeviceInfo bridge_info = {
     .qdev.name    = "pci-bridge",
     .qdev.size    = sizeof(PCIBridge),
diff --git a/hw/pci.h b/hw/pci.h
index 5a6cdb5..a62bc8e 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -203,6 +203,8 @@ struct PCIDevice {
         PCICapConfigReadFunc *config_read;
         PCICapConfigWriteFunc *config_write;
     } cap;
+
+    QLIST_HEAD(, PCIMemoryMap) memory_maps;
 };
 
 PCIDevice *pci_register_device(PCIBus *bus, const char *name,
@@ -440,4 +442,76 @@ static inline int ranges_overlap(uint64_t first1, uint64_t len1,
     return !(last2 < first1 || last1 < first2);
 }
 
+/*
+ * Memory I/O and PCI IOMMU definitions.
+ */
+
+#define IOMMU_PERM_READ     (1 << 0)
+#define IOMMU_PERM_WRITE    (1 << 1)
+#define IOMMU_PERM_RW       (IOMMU_PERM_READ | IOMMU_PERM_WRITE)
+
+typedef int PCIInvalidateMapFunc(void *opaque);
+typedef int PCITranslateFunc(PCIDevice *iommu,
+                             PCIDevice *dev,
+                             pcibus_t addr,
+                             target_phys_addr_t *paddr,
+                             target_phys_addr_t *len,
+                             unsigned perms);
+
+extern void pci_memory_rw(PCIDevice *dev,
+                          pcibus_t addr,
+                          uint8_t *buf,
+                          pcibus_t len,
+                          int is_write);
+extern void *pci_memory_map(PCIDevice *dev,
+                            PCIInvalidateMapFunc *cb,
+                            void *opaque,
+                            pcibus_t addr,
+                            target_phys_addr_t *len,
+                            int is_write);
+extern void pci_memory_unmap(PCIDevice *dev,
+                             void *buffer,
+                             target_phys_addr_t len,
+                             int is_write,
+                             target_phys_addr_t access_len);
+extern void pci_register_iommu(PCIDevice *dev,
+                               PCITranslateFunc *translate);
+extern void pci_memory_invalidate_range(PCIDevice *dev,
+                                        pcibus_t addr,
+                                        pcibus_t len);
+
+#define DECLARE_PCI_LD(suffix, size)                                    \
+extern uint##size##_t pci_ld##suffix(PCIDevice *dev, pcibus_t addr);
+
+#define DECLARE_PCI_ST(suffix, size)                                    \
+extern void pci_st##suffix(PCIDevice *dev,                              \
+                           pcibus_t addr,                               \
+                           uint##size##_t val);
+
+DECLARE_PCI_LD(ub, 8)
+DECLARE_PCI_LD(uw, 16)
+DECLARE_PCI_LD(l, 32)
+DECLARE_PCI_LD(q, 64)                  
+
+DECLARE_PCI_ST(b, 8)
+DECLARE_PCI_ST(w, 16)
+DECLARE_PCI_ST(l, 32)
+DECLARE_PCI_ST(q, 64)
+
+static inline void pci_memory_read(PCIDevice *dev,
+                                   pcibus_t addr,
+                                   uint8_t *buf,
+                                   pcibus_t len)
+{
+    pci_memory_rw(dev, addr, buf, len, 0);
+}
+
+static inline void pci_memory_write(PCIDevice *dev,
+                                    pcibus_t addr,
+                                    const uint8_t *buf,
+                                    pcibus_t len)
+{
+    pci_memory_rw(dev, addr, (uint8_t *) buf, len, 1);
+}
+
 #endif
diff --git a/qemu-common.h b/qemu-common.h
index 3fb2f0b..40c6d58 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -218,6 +218,7 @@ typedef struct SMBusDevice SMBusDevice;
 typedef struct PCIHostState PCIHostState;
 typedef struct PCIExpressHost PCIExpressHost;
 typedef struct PCIBus PCIBus;
+typedef struct PCIMemoryMap PCIMemoryMap;
 typedef struct PCIDevice PCIDevice;
 typedef struct SerialState SerialState;
 typedef struct IRQState *qemu_irq;
-- 
1.7.1


WARNING: multiple messages have this Message-ID (diff)
From: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
To: joro@8bytes.org
Cc: kvm@vger.kernel.org, qemu-devel@nongnu.org, blauwirbel@gmail.com,
	paul@codesourcery.com,
	Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>,
	avi@redhat.com
Subject: [Qemu-devel] [PATCH 2/7] pci: memory access API and IOMMU support
Date: Sun, 15 Aug 2010 22:27:17 +0300	[thread overview]
Message-ID: <1281900442-29971-3-git-send-email-eduard.munteanu@linux360.ro> (raw)
In-Reply-To: <1281900442-29971-1-git-send-email-eduard.munteanu@linux360.ro>

PCI devices should access memory through pci_memory_*() instead of
cpu_physical_memory_*(). This also provides support for translation and
access checking in case an IOMMU is emulated.

Memory maps are treated as remote IOTLBs (that is, translation caches
belonging to the IOMMU-aware device itself). Clients (devices) must
provide callbacks for map invalidation in case these maps are
persistent beyond the current I/O context, e.g. AIO DMA transfers.

Signed-off-by: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
---
 hw/pci.c      |  197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 hw/pci.h      |   74 +++++++++++++++++++++
 qemu-common.h |    1 +
 3 files changed, 271 insertions(+), 1 deletions(-)

diff --git a/hw/pci.c b/hw/pci.c
index 6871728..8668e06 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -58,6 +58,18 @@ struct PCIBus {
        Keep a count of the number of devices with raised IRQs.  */
     int nirq;
     int *irq_count;
+
+    PCIDevice                       *iommu;
+    PCITranslateFunc                *translate;
+};
+
+struct PCIMemoryMap {
+    pcibus_t                        addr;
+    pcibus_t                        len;
+    target_phys_addr_t              paddr;
+    PCIInvalidateMapFunc            *invalidate;
+    void                            *invalidate_opaque;
+    QLIST_ENTRY(PCIMemoryMap)       list;
 };
 
 static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
@@ -166,6 +178,19 @@ static void pci_device_reset(PCIDevice *dev)
     pci_update_mappings(dev);
 }
 
+static int pci_no_translate(PCIDevice *iommu,
+                            PCIDevice *dev,
+                            pcibus_t addr,
+                            target_phys_addr_t *paddr,
+                            target_phys_addr_t *len,
+                            unsigned perms)
+{
+    *paddr = addr;
+    *len = -1;
+
+    return 0;
+}
+
 static void pci_bus_reset(void *opaque)
 {
     PCIBus *bus = opaque;
@@ -227,7 +252,10 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
                          const char *name, int devfn_min)
 {
     qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
-    bus->devfn_min = devfn_min;
+
+    bus->devfn_min              = devfn_min;
+    bus->iommu                  = NULL;
+    bus->translate              = pci_no_translate;
 
     /* host bridge */
     QLIST_INIT(&bus->child);
@@ -2029,6 +2057,173 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
     }
 }
 
+void pci_register_iommu(PCIDevice *iommu,
+                        PCITranslateFunc *translate)
+{
+    iommu->bus->iommu = iommu;
+    iommu->bus->translate = translate;
+}
+
+void pci_memory_rw(PCIDevice *dev,
+                   pcibus_t addr,
+                   uint8_t *buf,
+                   pcibus_t len,
+                   int is_write)
+{
+    int err;
+    unsigned perms;
+    PCIDevice *iommu = dev->bus->iommu;
+    target_phys_addr_t paddr, plen;
+
+    perms = is_write ? IOMMU_PERM_WRITE : IOMMU_PERM_READ;
+
+    while (len) {
+        err = dev->bus->translate(iommu, dev, addr, &paddr, &plen, perms);
+        if (err)
+            return;
+
+        /* The translation might be valid for larger regions. */
+        if (plen > len)
+            plen = len;
+
+        cpu_physical_memory_rw(paddr, buf, plen, is_write);
+
+        len -= plen;
+        addr += plen;
+        buf += plen;
+    }
+}
+
+static void pci_memory_register_map(PCIDevice *dev,
+                                    pcibus_t addr,
+                                    pcibus_t len,
+                                    target_phys_addr_t paddr,
+                                    PCIInvalidateMapFunc *invalidate,
+                                    void *invalidate_opaque)
+{
+    PCIMemoryMap *map;
+
+    map = qemu_malloc(sizeof(PCIMemoryMap));
+    map->addr               = addr;
+    map->len                = len;
+    map->paddr              = paddr;
+    map->invalidate         = invalidate;
+    map->invalidate_opaque  = invalidate_opaque;
+
+    QLIST_INSERT_HEAD(&dev->memory_maps, map, list);
+}
+
+static void pci_memory_unregister_map(PCIDevice *dev,
+                                      target_phys_addr_t paddr,
+                                      target_phys_addr_t len)
+{
+    PCIMemoryMap *map;
+
+    QLIST_FOREACH(map, &dev->memory_maps, list) {
+        if (map->paddr == paddr && map->len == len) {
+            QLIST_REMOVE(map, list);
+            free(map);
+        }
+    }
+}
+
+void pci_memory_invalidate_range(PCIDevice *dev,
+                                 pcibus_t addr,
+                                 pcibus_t len)
+{
+    PCIMemoryMap *map;
+
+    QLIST_FOREACH(map, &dev->memory_maps, list) {
+        if (range_covers_range(addr, len, map->addr, map->len)) {
+            map->invalidate(map->invalidate_opaque);
+            QLIST_REMOVE(map, list);
+            free(map);
+        }
+    }
+}
+
+void *pci_memory_map(PCIDevice *dev,
+                     PCIInvalidateMapFunc *cb,
+                     void *opaque,
+                     pcibus_t addr,
+                     target_phys_addr_t *len,
+                     int is_write)
+{
+    int err;
+    unsigned perms;
+    PCIDevice *iommu = dev->bus->iommu;
+    target_phys_addr_t paddr, plen;
+
+    perms = is_write ? IOMMU_PERM_WRITE : IOMMU_PERM_READ;
+
+    plen = *len;
+    err = dev->bus->translate(iommu, dev, addr, &paddr, &plen, perms);
+    if (err)
+        return NULL;
+
+    /*
+     * If this is true, the virtual region is contiguous,
+     * but the translated physical region isn't. We just
+     * clamp *len, much like cpu_physical_memory_map() does.
+     */
+    if (plen < *len)
+        *len = plen;
+
+    /* We treat maps as remote TLBs to cope with stuff like AIO. */
+    if (cb)
+        pci_memory_register_map(dev, addr, *len, paddr, cb, opaque);
+
+    return cpu_physical_memory_map(paddr, len, is_write);
+}
+
+void pci_memory_unmap(PCIDevice *dev,
+                      void *buffer,
+                      target_phys_addr_t len,
+                      int is_write,
+                      target_phys_addr_t access_len)
+{
+    cpu_physical_memory_unmap(buffer, len, is_write, access_len);
+    pci_memory_unregister_map(dev, (target_phys_addr_t) buffer, len);
+}
+
+#define DEFINE_PCI_LD(suffix, size)                                       \
+uint##size##_t pci_ld##suffix(PCIDevice *dev, pcibus_t addr)              \
+{                                                                         \
+    int err;                                                              \
+    target_phys_addr_t paddr, plen;                                       \
+                                                                          \
+    err = dev->bus->translate(dev->bus->iommu, dev,                       \
+                              addr, &paddr, &plen, IOMMU_PERM_READ);      \
+    if (err || (plen < size / 8))                                         \
+        return 0;                                                         \
+                                                                          \
+    return ld##suffix##_phys(paddr);                                      \
+}
+
+#define DEFINE_PCI_ST(suffix, size)                                       \
+void pci_st##suffix(PCIDevice *dev, pcibus_t addr, uint##size##_t val)    \
+{                                                                         \
+    int err;                                                              \
+    target_phys_addr_t paddr, plen;                                       \
+                                                                          \
+    err = dev->bus->translate(dev->bus->iommu, dev,                       \
+                              addr, &paddr, &plen, IOMMU_PERM_WRITE);     \
+    if (err || (plen < size / 8))                                         \
+        return;                                                           \
+                                                                          \
+    st##suffix##_phys(paddr, val);                                        \
+}
+
+DEFINE_PCI_LD(ub, 8)
+DEFINE_PCI_LD(uw, 16)
+DEFINE_PCI_LD(l, 32)
+DEFINE_PCI_LD(q, 64)                  
+
+DEFINE_PCI_ST(b, 8)
+DEFINE_PCI_ST(w, 16)
+DEFINE_PCI_ST(l, 32)
+DEFINE_PCI_ST(q, 64)
+
 static PCIDeviceInfo bridge_info = {
     .qdev.name    = "pci-bridge",
     .qdev.size    = sizeof(PCIBridge),
diff --git a/hw/pci.h b/hw/pci.h
index 5a6cdb5..a62bc8e 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -203,6 +203,8 @@ struct PCIDevice {
         PCICapConfigReadFunc *config_read;
         PCICapConfigWriteFunc *config_write;
     } cap;
+
+    QLIST_HEAD(, PCIMemoryMap) memory_maps;
 };
 
 PCIDevice *pci_register_device(PCIBus *bus, const char *name,
@@ -440,4 +442,76 @@ static inline int ranges_overlap(uint64_t first1, uint64_t len1,
     return !(last2 < first1 || last1 < first2);
 }
 
+/*
+ * Memory I/O and PCI IOMMU definitions.
+ */
+
+#define IOMMU_PERM_READ     (1 << 0)
+#define IOMMU_PERM_WRITE    (1 << 1)
+#define IOMMU_PERM_RW       (IOMMU_PERM_READ | IOMMU_PERM_WRITE)
+
+typedef int PCIInvalidateMapFunc(void *opaque);
+typedef int PCITranslateFunc(PCIDevice *iommu,
+                             PCIDevice *dev,
+                             pcibus_t addr,
+                             target_phys_addr_t *paddr,
+                             target_phys_addr_t *len,
+                             unsigned perms);
+
+extern void pci_memory_rw(PCIDevice *dev,
+                          pcibus_t addr,
+                          uint8_t *buf,
+                          pcibus_t len,
+                          int is_write);
+extern void *pci_memory_map(PCIDevice *dev,
+                            PCIInvalidateMapFunc *cb,
+                            void *opaque,
+                            pcibus_t addr,
+                            target_phys_addr_t *len,
+                            int is_write);
+extern void pci_memory_unmap(PCIDevice *dev,
+                             void *buffer,
+                             target_phys_addr_t len,
+                             int is_write,
+                             target_phys_addr_t access_len);
+extern void pci_register_iommu(PCIDevice *dev,
+                               PCITranslateFunc *translate);
+extern void pci_memory_invalidate_range(PCIDevice *dev,
+                                        pcibus_t addr,
+                                        pcibus_t len);
+
+#define DECLARE_PCI_LD(suffix, size)                                    \
+extern uint##size##_t pci_ld##suffix(PCIDevice *dev, pcibus_t addr);
+
+#define DECLARE_PCI_ST(suffix, size)                                    \
+extern void pci_st##suffix(PCIDevice *dev,                              \
+                           pcibus_t addr,                               \
+                           uint##size##_t val);
+
+DECLARE_PCI_LD(ub, 8)
+DECLARE_PCI_LD(uw, 16)
+DECLARE_PCI_LD(l, 32)
+DECLARE_PCI_LD(q, 64)                  
+
+DECLARE_PCI_ST(b, 8)
+DECLARE_PCI_ST(w, 16)
+DECLARE_PCI_ST(l, 32)
+DECLARE_PCI_ST(q, 64)
+
+static inline void pci_memory_read(PCIDevice *dev,
+                                   pcibus_t addr,
+                                   uint8_t *buf,
+                                   pcibus_t len)
+{
+    pci_memory_rw(dev, addr, buf, len, 0);
+}
+
+static inline void pci_memory_write(PCIDevice *dev,
+                                    pcibus_t addr,
+                                    const uint8_t *buf,
+                                    pcibus_t len)
+{
+    pci_memory_rw(dev, addr, (uint8_t *) buf, len, 1);
+}
+
 #endif
diff --git a/qemu-common.h b/qemu-common.h
index 3fb2f0b..40c6d58 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -218,6 +218,7 @@ typedef struct SMBusDevice SMBusDevice;
 typedef struct PCIHostState PCIHostState;
 typedef struct PCIExpressHost PCIExpressHost;
 typedef struct PCIBus PCIBus;
+typedef struct PCIMemoryMap PCIMemoryMap;
 typedef struct PCIDevice PCIDevice;
 typedef struct SerialState SerialState;
 typedef struct IRQState *qemu_irq;
-- 
1.7.1

  parent reply	other threads:[~2010-08-15 19:30 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-15 19:27 [PATCH 0/7] AMD IOMMU emulation patches v3 Eduard - Gabriel Munteanu
2010-08-15 19:27 ` [Qemu-devel] " Eduard - Gabriel Munteanu
2010-08-15 19:27 ` [PATCH 1/7] pci: add range_covers_range() Eduard - Gabriel Munteanu
2010-08-15 19:27   ` [Qemu-devel] " Eduard - Gabriel Munteanu
2010-08-18  4:39   ` Isaku Yamahata
2010-08-18  4:39     ` Isaku Yamahata
2010-08-15 19:27 ` Eduard - Gabriel Munteanu [this message]
2010-08-15 19:27   ` [Qemu-devel] [PATCH 2/7] pci: memory access API and IOMMU support Eduard - Gabriel Munteanu
2010-08-18  5:02   ` Isaku Yamahata
2010-08-18  5:02     ` Isaku Yamahata
2010-08-15 19:27 ` [PATCH 3/7] AMD IOMMU emulation Eduard - Gabriel Munteanu
2010-08-15 19:27   ` [Qemu-devel] " Eduard - Gabriel Munteanu
2010-08-16 17:57   ` Blue Swirl
2010-08-16 17:57     ` [Qemu-devel] " Blue Swirl
2010-08-15 19:27 ` [PATCH 4/7] ide: use the PCI memory access interface Eduard - Gabriel Munteanu
2010-08-15 19:27   ` [Qemu-devel] " Eduard - Gabriel Munteanu
2010-08-15 19:27 ` [PATCH 5/7] rtl8139: " Eduard - Gabriel Munteanu
2010-08-15 19:27   ` [Qemu-devel] " Eduard - Gabriel Munteanu
2010-08-15 19:27 ` [PATCH 6/7] eepro100: " Eduard - Gabriel Munteanu
2010-08-15 19:27   ` [Qemu-devel] " Eduard - Gabriel Munteanu
2010-08-15 19:27 ` [PATCH 7/7] ac97: " Eduard - Gabriel Munteanu
2010-08-15 19:27   ` [Qemu-devel] " Eduard - Gabriel Munteanu
2010-08-15 20:42   ` malc
2010-08-15 20:42     ` malc
2010-08-16  1:47 ` [PATCH 0/7] AMD IOMMU emulation patches v3 Anthony Liguori
2010-08-16  1:47   ` [Qemu-devel] " Anthony Liguori
2010-08-28 14:54 [PATCH 0/7] AMD IOMMU emulation patchset v4 Eduard - Gabriel Munteanu
2010-08-28 14:54 ` [PATCH 2/7] pci: memory access API and IOMMU support Eduard - Gabriel Munteanu
2010-09-02  5:28   ` Michael S. Tsirkin
2010-09-02  8:40     ` Eduard - Gabriel Munteanu
2010-09-02  9:49       ` Michael S. Tsirkin
2010-09-04  9:01         ` Blue Swirl
2010-09-05  7:10           ` Michael S. Tsirkin
2010-08-29 20:44 [PATCH 0/7] AMD IOMMU emulation patchset v4 Blue Swirl
2010-08-29 22:08 ` [PATCH 2/7] pci: memory access API and IOMMU support Eduard - Gabriel Munteanu
2010-08-29 22:11   ` Eduard - Gabriel Munteanu

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=1281900442-29971-3-git-send-email-eduard.munteanu@linux360.ro \
    --to=eduard.munteanu@linux360.ro \
    --cc=anthony@codemonkey.ws \
    --cc=avi@redhat.com \
    --cc=blauwirbel@gmail.com \
    --cc=joro@8bytes.org \
    --cc=kvm@vger.kernel.org \
    --cc=paul@codesourcery.com \
    --cc=qemu-devel@nongnu.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.