All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [0/10]  Preliminary work for IOMMU emulation support; the easy bits
@ 2011-09-01  5:00 David Gibson
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA David Gibson
                   ` (10 more replies)
  0 siblings, 11 replies; 34+ messages in thread
From: David Gibson @ 2011-09-01  5:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: joerg.roedel, aliguori, rth, agraf, eduard.munteanu

A while back, Eduard - Gabriel Munteanu send a series of patches
implementing support for emulating the AMD IOMMU in conjunction with
qemu emulated PCI devices.  A revised patch series added support for
the Intel IOMMU, and I also send a revised version of this series
which added support for the hypervisor mediated IOMMU on the pseries
machine.

Richard Henderson also weighed in on the discussion, and there's still
a fair bit to be thrashed out in terms of exactly how to set up an
IOMMU / DMA translation subsystem.

However, really only 2 or 3 patches in any of these series have
contained anything interesting.  The rest of the series has been
converting existing PCI emulated devices to use the new DMA interface
which worked through the IOMMU translation, whatever it was.  While we
keep working out what we want for the guts of the IOMMU support, these
device conversion patches keep bitrotting against updates to the
various device implementations themselves.

Really, regardless of whether we're actually implementing IOMMU
translation, it makes sense that qemu code should distinguish between
when it is really operating in CPU physical addresses and when it is
operating in bus or DMA addresses which might have some kind of
translation into physical addresses.

This series, therefore, begins the conversion of existing PCI device
emulation code to use new (stub) pci dma access functions.  These are
for now, just defined to be untranslated cpu physical memory accesses,
as before, but has two advantages:

   * It becomes obvious where the code is working with dma addresses,
     so it's easier to grep for what might be affected by an IOMMU or
     other bus address translation.

   * The new stubs take the PCIDevice *, from which any of the various
     suggested IOMMU interfaces should be able to locate the correct
     IOMMU translation context.

This series only converts the easy cases so far.  That is simple
direct DMA access from device code:
cpu_physical_memory_{read,write}(), ld*_phys() and st*_phys().  It
doesn't handle devices which use the scatter/gather code (just ide and
UHCI, so far).  I plan to address that later, but I have some details
still to work out.

Anthony, please apply.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-01  5:00 [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits David Gibson
@ 2011-09-01  5:00 ` David Gibson
  2011-09-01 15:35   ` Michael S. Tsirkin
                     ` (2 more replies)
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 02/10] rtl8139: Use PCI DMA stub functions David Gibson
                   ` (9 subsequent siblings)
  10 siblings, 3 replies; 34+ messages in thread
From: David Gibson @ 2011-09-01  5:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: joerg.roedel, aliguori, rth, agraf, eduard.munteanu

This patch adds functions to pci.[ch] to perform PCI DMA operations.  At
present, these are just stubs which perform directly cpu physical memory
accesses.

Using these stubs, however, distinguishes PCI device DMA transactions from
other accesses to physical memory, which will allow PCI IOMMU support to
be added in one place, rather than updating every PCI driver at that time.

That is, it allows us to update individual PCI drivers to support an IOMMU
without having yet determined the details of how the IOMMU emulation will
operate.  This will let us remove the most bitrot-sensitive part of an
IOMMU patch in advance.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 dma.h    |    2 ++
 hw/pci.c |   31 +++++++++++++++++++++++++++++++
 hw/pci.h |   33 +++++++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/dma.h b/dma.h
index a6db5ba..06e91cb 100644
--- a/dma.h
+++ b/dma.h
@@ -15,6 +15,8 @@
 #include "hw/hw.h"
 #include "block.h"
 
+typedef target_phys_addr_t dma_addr_t;
+
 typedef struct {
     target_phys_addr_t base;
     target_phys_addr_t len;
diff --git a/hw/pci.c b/hw/pci.c
index 1cdcbb7..842b066 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -2211,3 +2211,34 @@ MemoryRegion *pci_address_space(PCIDevice *dev)
 {
     return dev->bus->address_space_mem;
 }
+
+#define DEFINE_LDST_DMA(_lname, _sname, _bits) \
+    uint##_bits##_t ld##_lname##_pci_dma(PCIDevice *dev, dma_addr_t addr) \
+    { \
+        uint##_bits##_t val; \
+        pci_dma_read(dev, addr, &val, sizeof(val)); \
+        return le##_bits##_to_cpu(val); \
+    } \
+    void st##_sname##_pci_dma(PCIDevice *dev, \
+                              dma_addr_t addr, uint##_bits##_t val) \
+    { \
+        val = cpu_to_le##_bits(val); \
+        pci_dma_write(dev, addr, &val, sizeof(val)); \
+    }
+
+uint8_t ldub_pci_dma(PCIDevice *dev, dma_addr_t addr)
+{
+    uint8_t val;
+
+    pci_dma_read(dev, addr, &val, sizeof(val));
+    return val;
+}
+
+void stb_pci_dma(PCIDevice *dev, dma_addr_t addr, uint8_t val)
+{
+    pci_dma_write(dev, addr, &val, sizeof(val));
+}
+
+DEFINE_LDST_DMA(uw, w, 16);
+DEFINE_LDST_DMA(l, l, 32);
+DEFINE_LDST_DMA(q, q, 64);
diff --git a/hw/pci.h b/hw/pci.h
index 391217e..401d14a 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -6,6 +6,7 @@
 
 #include "qdev.h"
 #include "memory.h"
+#include "dma.h"
 
 /* PCI includes legacy ISA access.  */
 #include "isa.h"
@@ -492,4 +493,36 @@ static inline uint32_t pci_config_size(const PCIDevice *d)
     return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE;
 }
 
+/* DMA access functions */
+static inline int pci_dma_rw(PCIDevice *dev, dma_addr_t addr,
+                             void *buf, dma_addr_t len, int is_write)
+{
+    cpu_physical_memory_rw(addr, buf, len, is_write);
+    return 0;
+}
+
+static inline int pci_dma_read(PCIDevice *dev, dma_addr_t addr,
+                               void *buf, dma_addr_t len)
+{
+    return pci_dma_rw(dev, addr, buf, len, 0);
+}
+
+static inline int pci_dma_write(PCIDevice *dev, dma_addr_t addr,
+                                const void *buf, dma_addr_t len)
+{
+    return pci_dma_rw(dev, addr, (void *) buf, len, 1);
+}
+
+#define DECLARE_LDST_DMA(_lname, _sname, _bits) \
+    uint##_bits##_t ld##_lname##_pci_dma(PCIDevice *dev, dma_addr_t addr); \
+    void st##_sname##_pci_dma(PCIDevice *dev, dma_addr_t addr, \
+                              uint##_bits##_t val);            \
+
+DECLARE_LDST_DMA(ub, b, 8);
+DECLARE_LDST_DMA(uw, w, 16);
+DECLARE_LDST_DMA(l, l, 32);
+DECLARE_LDST_DMA(q, q, 64);
+
+#undef DECLARE_LDST_DMA
+
 #endif
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 02/10] rtl8139: Use PCI DMA stub functions
  2011-09-01  5:00 [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits David Gibson
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA David Gibson
@ 2011-09-01  5:00 ` David Gibson
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 03/10] eepro100: " David Gibson
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 34+ messages in thread
From: David Gibson @ 2011-09-01  5:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: joerg.roedel, aliguori, rth, agraf, eduard.munteanu

From: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>

This updates the rtl8139 device emulation to use the explicit PCI DMA
functions, instead of directly calling physical memory access functions.

Signed-off-by: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/rtl8139.c |   98 +++++++++++++++++++++++++++++----------------------------
 1 files changed, 50 insertions(+), 48 deletions(-)

diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index c5de5b4..af71cce 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -53,6 +53,7 @@
 
 #include "hw.h"
 #include "pci.h"
+#include "dma.h"
 #include "qemu-timer.h"
 #include "net.h"
 #include "loader.h"
@@ -427,9 +428,6 @@ typedef struct RTL8139TallyCounters
 /* Clears all tally counters */
 static void RTL8139TallyCounters_clear(RTL8139TallyCounters* counters);
 
-/* Writes tally counters to specified physical memory address */
-static void RTL8139TallyCounters_physical_memory_write(target_phys_addr_t tc_addr, RTL8139TallyCounters* counters);
-
 typedef struct RTL8139State {
     PCIDevice dev;
     uint8_t phys[8]; /* mac address */
@@ -512,6 +510,9 @@ typedef struct RTL8139State {
     int rtl8139_mmio_io_addr_dummy;
 } RTL8139State;
 
+/* Writes tally counters to memory via DMA */
+static void RTL8139TallyCounters_dma_write(RTL8139State *s, dma_addr_t tc_addr);
+
 static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time);
 
 static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command)
@@ -773,15 +774,15 @@ static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size)
 
             if (size > wrapped)
             {
-                cpu_physical_memory_write( s->RxBuf + s->RxBufAddr,
-                                           buf, size-wrapped );
+                pci_dma_write(&s->dev, s->RxBuf + s->RxBufAddr,
+                              buf, size-wrapped);
             }
 
             /* reset buffer pointer */
             s->RxBufAddr = 0;
 
-            cpu_physical_memory_write( s->RxBuf + s->RxBufAddr,
-                                       buf + (size-wrapped), wrapped );
+            pci_dma_write(&s->dev, s->RxBuf + s->RxBufAddr,
+                          buf + (size-wrapped), wrapped);
 
             s->RxBufAddr = wrapped;
 
@@ -790,13 +791,13 @@ static void rtl8139_write_buffer(RTL8139State *s, const void *buf, int size)
     }
 
     /* non-wrapping path or overwrapping enabled */
-    cpu_physical_memory_write( s->RxBuf + s->RxBufAddr, buf, size );
+    pci_dma_write(&s->dev, s->RxBuf + s->RxBufAddr, buf, size);
 
     s->RxBufAddr += size;
 }
 
 #define MIN_BUF_SIZE 60
-static inline target_phys_addr_t rtl8139_addr64(uint32_t low, uint32_t high)
+static inline dma_addr_t rtl8139_addr64(uint32_t low, uint32_t high)
 {
 #if TARGET_PHYS_ADDR_BITS > 32
     return low | ((target_phys_addr_t)high << 32);
@@ -979,7 +980,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
 /* w3 high 32bit of Rx buffer ptr */
 
         int descriptor = s->currCPlusRxDesc;
-        target_phys_addr_t cplus_rx_ring_desc;
+        dma_addr_t cplus_rx_ring_desc;
 
         cplus_rx_ring_desc = rtl8139_addr64(s->RxRingAddrLO, s->RxRingAddrHI);
         cplus_rx_ring_desc += 16 * descriptor;
@@ -990,13 +991,13 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
 
         uint32_t val, rxdw0,rxdw1,rxbufLO,rxbufHI;
 
-        cpu_physical_memory_read(cplus_rx_ring_desc,    (uint8_t *)&val, 4);
+        pci_dma_read(&s->dev, cplus_rx_ring_desc, (uint8_t *)&val, 4);
         rxdw0 = le32_to_cpu(val);
-        cpu_physical_memory_read(cplus_rx_ring_desc+4,  (uint8_t *)&val, 4);
+        pci_dma_read(&s->dev, cplus_rx_ring_desc+4, (uint8_t *)&val, 4);
         rxdw1 = le32_to_cpu(val);
-        cpu_physical_memory_read(cplus_rx_ring_desc+8,  (uint8_t *)&val, 4);
+        pci_dma_read(&s->dev, cplus_rx_ring_desc+8, (uint8_t *)&val, 4);
         rxbufLO = le32_to_cpu(val);
-        cpu_physical_memory_read(cplus_rx_ring_desc+12, (uint8_t *)&val, 4);
+        pci_dma_read(&s->dev, cplus_rx_ring_desc+12, (uint8_t *)&val, 4);
         rxbufHI = le32_to_cpu(val);
 
         DPRINTF("+++ C+ mode RX descriptor %d %08x %08x %08x %08x\n",
@@ -1060,16 +1061,16 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
             return size_;
         }
 
-        target_phys_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI);
+        dma_addr_t rx_addr = rtl8139_addr64(rxbufLO, rxbufHI);
 
         /* receive/copy to target memory */
         if (dot1q_buf) {
-            cpu_physical_memory_write(rx_addr, buf, 2 * ETHER_ADDR_LEN);
-            cpu_physical_memory_write(rx_addr + 2 * ETHER_ADDR_LEN,
-                buf + 2 * ETHER_ADDR_LEN + VLAN_HLEN,
-                size - 2 * ETHER_ADDR_LEN);
+            pci_dma_write(&s->dev, rx_addr, buf, 2 * ETHER_ADDR_LEN);
+            pci_dma_write(&s->dev, rx_addr + 2 * ETHER_ADDR_LEN,
+                          buf + 2 * ETHER_ADDR_LEN + VLAN_HLEN,
+                          size - 2 * ETHER_ADDR_LEN);
         } else {
-            cpu_physical_memory_write(rx_addr, buf, size);
+            pci_dma_write(&s->dev, rx_addr, buf, size);
         }
 
         if (s->CpCmd & CPlusRxChkSum)
@@ -1079,7 +1080,7 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
 
         /* write checksum */
         val = cpu_to_le32(crc32(0, buf, size_));
-        cpu_physical_memory_write( rx_addr+size, (uint8_t *)&val, 4);
+        pci_dma_write(&s->dev, rx_addr+size, (uint8_t *)&val, 4);
 
 /* first segment of received packet flag */
 #define CP_RX_STATUS_FS (1<<29)
@@ -1125,9 +1126,9 @@ static ssize_t rtl8139_do_receive(VLANClientState *nc, const uint8_t *buf, size_
 
         /* update ring data */
         val = cpu_to_le32(rxdw0);
-        cpu_physical_memory_write(cplus_rx_ring_desc,    (uint8_t *)&val, 4);
+        pci_dma_write(&s->dev, cplus_rx_ring_desc, (uint8_t *)&val, 4);
         val = cpu_to_le32(rxdw1);
-        cpu_physical_memory_write(cplus_rx_ring_desc+4,  (uint8_t *)&val, 4);
+        pci_dma_write(&s->dev, cplus_rx_ring_desc+4, (uint8_t *)&val, 4);
 
         /* update tally counter */
         ++s->tally_counters.RxOk;
@@ -1307,50 +1308,51 @@ static void RTL8139TallyCounters_clear(RTL8139TallyCounters* counters)
     counters->TxUndrn = 0;
 }
 
-static void RTL8139TallyCounters_physical_memory_write(target_phys_addr_t tc_addr, RTL8139TallyCounters* tally_counters)
+static void RTL8139TallyCounters_dma_write(RTL8139State *s, dma_addr_t tc_addr)
 {
+    RTL8139TallyCounters *tally_counters = &s->tally_counters;
     uint16_t val16;
     uint32_t val32;
     uint64_t val64;
 
     val64 = cpu_to_le64(tally_counters->TxOk);
-    cpu_physical_memory_write(tc_addr + 0,    (uint8_t *)&val64, 8);
+    pci_dma_write(&s->dev, tc_addr + 0,     (uint8_t *)&val64, 8);
 
     val64 = cpu_to_le64(tally_counters->RxOk);
-    cpu_physical_memory_write(tc_addr + 8,    (uint8_t *)&val64, 8);
+    pci_dma_write(&s->dev, tc_addr + 8,     (uint8_t *)&val64, 8);
 
     val64 = cpu_to_le64(tally_counters->TxERR);
-    cpu_physical_memory_write(tc_addr + 16,    (uint8_t *)&val64, 8);
+    pci_dma_write(&s->dev, tc_addr + 16,    (uint8_t *)&val64, 8);
 
     val32 = cpu_to_le32(tally_counters->RxERR);
-    cpu_physical_memory_write(tc_addr + 24,    (uint8_t *)&val32, 4);
+    pci_dma_write(&s->dev, tc_addr + 24,    (uint8_t *)&val32, 4);
 
     val16 = cpu_to_le16(tally_counters->MissPkt);
-    cpu_physical_memory_write(tc_addr + 28,    (uint8_t *)&val16, 2);
+    pci_dma_write(&s->dev, tc_addr + 28,    (uint8_t *)&val16, 2);
 
     val16 = cpu_to_le16(tally_counters->FAE);
-    cpu_physical_memory_write(tc_addr + 30,    (uint8_t *)&val16, 2);
+    pci_dma_write(&s->dev, tc_addr + 30,    (uint8_t *)&val16, 2);
 
     val32 = cpu_to_le32(tally_counters->Tx1Col);
-    cpu_physical_memory_write(tc_addr + 32,    (uint8_t *)&val32, 4);
+    pci_dma_write(&s->dev, tc_addr + 32,    (uint8_t *)&val32, 4);
 
     val32 = cpu_to_le32(tally_counters->TxMCol);
-    cpu_physical_memory_write(tc_addr + 36,    (uint8_t *)&val32, 4);
+    pci_dma_write(&s->dev, tc_addr + 36,    (uint8_t *)&val32, 4);
 
     val64 = cpu_to_le64(tally_counters->RxOkPhy);
-    cpu_physical_memory_write(tc_addr + 40,    (uint8_t *)&val64, 8);
+    pci_dma_write(&s->dev, tc_addr + 40,    (uint8_t *)&val64, 8);
 
     val64 = cpu_to_le64(tally_counters->RxOkBrd);
-    cpu_physical_memory_write(tc_addr + 48,    (uint8_t *)&val64, 8);
+    pci_dma_write(&s->dev, tc_addr + 48,    (uint8_t *)&val64, 8);
 
     val32 = cpu_to_le32(tally_counters->RxOkMul);
-    cpu_physical_memory_write(tc_addr + 56,    (uint8_t *)&val32, 4);
+    pci_dma_write(&s->dev, tc_addr + 56,    (uint8_t *)&val32, 4);
 
     val16 = cpu_to_le16(tally_counters->TxAbt);
-    cpu_physical_memory_write(tc_addr + 60,    (uint8_t *)&val16, 2);
+    pci_dma_write(&s->dev, tc_addr + 60,    (uint8_t *)&val16, 2);
 
     val16 = cpu_to_le16(tally_counters->TxUndrn);
-    cpu_physical_memory_write(tc_addr + 62,    (uint8_t *)&val16, 2);
+    pci_dma_write(&s->dev, tc_addr + 62,    (uint8_t *)&val16, 2);
 }
 
 /* Loads values of tally counters from VM state file */
@@ -1842,7 +1844,7 @@ static int rtl8139_transmit_one(RTL8139State *s, int descriptor)
     DPRINTF("+++ transmit reading %d bytes from host memory at 0x%08x\n",
         txsize, s->TxAddr[descriptor]);
 
-    cpu_physical_memory_read(s->TxAddr[descriptor], txbuffer, txsize);
+    pci_dma_read(&s->dev, s->TxAddr[descriptor], txbuffer, txsize);
 
     /* Mark descriptor as transferred */
     s->TxStatus[descriptor] |= TxHostOwns;
@@ -1963,8 +1965,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
 
     int descriptor = s->currCPlusTxDesc;
 
-    target_phys_addr_t cplus_tx_ring_desc =
-        rtl8139_addr64(s->TxAddr[0], s->TxAddr[1]);
+    dma_addr_t cplus_tx_ring_desc = rtl8139_addr64(s->TxAddr[0], s->TxAddr[1]);
 
     /* Normal priority ring */
     cplus_tx_ring_desc += 16 * descriptor;
@@ -1975,13 +1976,13 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
 
     uint32_t val, txdw0,txdw1,txbufLO,txbufHI;
 
-    cpu_physical_memory_read(cplus_tx_ring_desc,    (uint8_t *)&val, 4);
+    pci_dma_read(&s->dev, cplus_tx_ring_desc,    (uint8_t *)&val, 4);
     txdw0 = le32_to_cpu(val);
-    cpu_physical_memory_read(cplus_tx_ring_desc+4,  (uint8_t *)&val, 4);
+    pci_dma_read(&s->dev, cplus_tx_ring_desc+4,  (uint8_t *)&val, 4);
     txdw1 = le32_to_cpu(val);
-    cpu_physical_memory_read(cplus_tx_ring_desc+8,  (uint8_t *)&val, 4);
+    pci_dma_read(&s->dev, cplus_tx_ring_desc+8,  (uint8_t *)&val, 4);
     txbufLO = le32_to_cpu(val);
-    cpu_physical_memory_read(cplus_tx_ring_desc+12, (uint8_t *)&val, 4);
+    pci_dma_read(&s->dev, cplus_tx_ring_desc+12, (uint8_t *)&val, 4);
     txbufHI = le32_to_cpu(val);
 
     DPRINTF("+++ C+ mode TX descriptor %d %08x %08x %08x %08x\n", descriptor,
@@ -2047,7 +2048,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
     }
 
     int txsize = txdw0 & CP_TX_BUFFER_SIZE_MASK;
-    target_phys_addr_t tx_addr = rtl8139_addr64(txbufLO, txbufHI);
+    dma_addr_t tx_addr = rtl8139_addr64(txbufLO, txbufHI);
 
     /* make sure we have enough space to assemble the packet */
     if (!s->cplus_txbuffer)
@@ -2089,7 +2090,8 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
         TARGET_FMT_plx" to offset %d\n", txsize, tx_addr,
         s->cplus_txbuffer_offset);
 
-    cpu_physical_memory_read(tx_addr, s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize);
+    pci_dma_read(&s->dev, tx_addr,
+                 s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize);
     s->cplus_txbuffer_offset += txsize;
 
     /* seek to next Rx descriptor */
@@ -2116,7 +2118,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
 
     /* update ring data */
     val = cpu_to_le32(txdw0);
-    cpu_physical_memory_write(cplus_tx_ring_desc,    (uint8_t *)&val, 4);
+    pci_dma_write(&s->dev, cplus_tx_ring_desc, (uint8_t *)&val, 4);
 
     /* Now decide if descriptor being processed is holding the last segment of packet */
     if (txdw0 & CP_TX_LS)
@@ -2475,7 +2477,7 @@ static void rtl8139_TxStatus_write(RTL8139State *s, uint32_t txRegOffset, uint32
             target_phys_addr_t tc_addr = rtl8139_addr64(s->TxStatus[0] & ~0x3f, s->TxStatus[1]);
 
             /* dump tally counters to specified memory location */
-            RTL8139TallyCounters_physical_memory_write( tc_addr, &s->tally_counters);
+            RTL8139TallyCounters_dma_write(s, tc_addr);
 
             /* mark dump completed */
             s->TxStatus[0] &= ~0x8;
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 03/10] eepro100: Use PCI DMA stub functions
  2011-09-01  5:00 [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits David Gibson
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA David Gibson
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 02/10] rtl8139: Use PCI DMA stub functions David Gibson
@ 2011-09-01  5:00 ` David Gibson
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 04/10] ac97: " David Gibson
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 34+ messages in thread
From: David Gibson @ 2011-09-01  5:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: joerg.roedel, aliguori, rth, agraf, eduard.munteanu

From: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>

This updates the eepro100 device emulation to use the explicit PCI DMA
functions, instead of directly calling physical memory access functions.

Signed-off-by: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
Signed-off-by: David Gibson <dwg@au1.ibm.com>
---
 hw/eepro100.c |  113 +++++++++++++++++++++------------------------------------
 1 files changed, 41 insertions(+), 72 deletions(-)

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 4e3c52f..9f57371 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -46,6 +46,7 @@
 #include "net.h"
 #include "eeprom93xx.h"
 #include "sysemu.h"
+#include "dma.h"
 
 /* QEMU sends frames smaller than 60 bytes to ethernet nics.
  * Such frames are rejected by real nics and their emulations.
@@ -315,38 +316,6 @@ static const uint16_t eepro100_mdi_mask[] = {
     0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 };
 
-/* Read a 16 bit little endian value from physical memory. */
-static uint16_t e100_ldw_le_phys(target_phys_addr_t addr)
-{
-    /* Load 16 bit (little endian) word from emulated hardware. */
-    uint16_t val;
-    cpu_physical_memory_read(addr, &val, sizeof(val));
-    return le16_to_cpu(val);
-}
-
-/* Read a 32 bit little endian value from physical memory. */
-static uint32_t e100_ldl_le_phys(target_phys_addr_t addr)
-{
-    /* Load 32 bit (little endian) word from emulated hardware. */
-    uint32_t val;
-    cpu_physical_memory_read(addr, &val, sizeof(val));
-    return le32_to_cpu(val);
-}
-
-/* Write a 16 bit little endian value to physical memory. */
-static void e100_stw_le_phys(target_phys_addr_t addr, uint16_t val)
-{
-    val = cpu_to_le16(val);
-    cpu_physical_memory_write(addr, &val, sizeof(val));
-}
-
-/* Write a 32 bit little endian value to physical memory. */
-static void e100_stl_le_phys(target_phys_addr_t addr, uint32_t val)
-{
-    val = cpu_to_le32(val);
-    cpu_physical_memory_write(addr, &val, sizeof(val));
-}
-
 #define POLYNOMIAL 0x04c11db6
 
 /* From FreeBSD */
@@ -744,21 +713,22 @@ static void dump_statistics(EEPRO100State * s)
      * values which really matter.
      * Number of data should check configuration!!!
      */
-    cpu_physical_memory_write(s->statsaddr, &s->statistics, s->stats_size);
-    e100_stl_le_phys(s->statsaddr + 0, s->statistics.tx_good_frames);
-    e100_stl_le_phys(s->statsaddr + 36, s->statistics.rx_good_frames);
-    e100_stl_le_phys(s->statsaddr + 48, s->statistics.rx_resource_errors);
-    e100_stl_le_phys(s->statsaddr + 60, s->statistics.rx_short_frame_errors);
+    pci_dma_write(&s->dev, s->statsaddr,
+                  (uint8_t *) & s->statistics, s->stats_size);
+    stl_pci_dma(&s->dev, s->statsaddr + 0, s->statistics.tx_good_frames);
+    stl_pci_dma(&s->dev, s->statsaddr + 36, s->statistics.rx_good_frames);
+    stl_pci_dma(&s->dev, s->statsaddr + 48, s->statistics.rx_resource_errors);
+    stl_pci_dma(&s->dev, s->statsaddr + 60, s->statistics.rx_short_frame_errors);
 #if 0
-    e100_stw_le_phys(s->statsaddr + 76, s->statistics.xmt_tco_frames);
-    e100_stw_le_phys(s->statsaddr + 78, s->statistics.rcv_tco_frames);
+    stw_pci_dma(&s->dev, s->statsaddr + 76, s->statistics.xmt_tco_frames);
+    stw_pci_dma(&s->dev, s->statsaddr + 78, s->statistics.rcv_tco_frames);
     missing("CU dump statistical counters");
 #endif
 }
 
 static void read_cb(EEPRO100State *s)
 {
-    cpu_physical_memory_read(s->cb_address, &s->tx, sizeof(s->tx));
+    pci_dma_read(&s->dev, s->cb_address, (uint8_t *) &s->tx, sizeof(s->tx));
     s->tx.status = le16_to_cpu(s->tx.status);
     s->tx.command = le16_to_cpu(s->tx.command);
     s->tx.link = le32_to_cpu(s->tx.link);
@@ -788,18 +758,17 @@ static void tx_command(EEPRO100State *s)
     }
     assert(tcb_bytes <= sizeof(buf));
     while (size < tcb_bytes) {
-        uint32_t tx_buffer_address = e100_ldl_le_phys(tbd_address);
-        uint16_t tx_buffer_size = e100_ldw_le_phys(tbd_address + 4);
+        uint32_t tx_buffer_address = ldl_pci_dma(&s->dev, tbd_address);
+        uint16_t tx_buffer_size = lduw_pci_dma(&s->dev, tbd_address + 4);
 #if 0
-        uint16_t tx_buffer_el = e100_ldw_le_phys(tbd_address + 6);
+        uint16_t tx_buffer_el = lduw_pci_dma(&s->dev, tbd_address + 6);
 #endif
         tbd_address += 8;
         TRACE(RXTX, logout
             ("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n",
              tx_buffer_address, tx_buffer_size));
         tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
-        cpu_physical_memory_read(tx_buffer_address, &buf[size],
-                                 tx_buffer_size);
+        pci_dma_read(&s->dev, tx_buffer_address, &buf[size], tx_buffer_size);
         size += tx_buffer_size;
     }
     if (tbd_array == 0xffffffff) {
@@ -810,16 +779,16 @@ static void tx_command(EEPRO100State *s)
         if (s->has_extended_tcb_support && !(s->configuration[6] & BIT(4))) {
             /* Extended Flexible TCB. */
             for (; tbd_count < 2; tbd_count++) {
-                uint32_t tx_buffer_address = e100_ldl_le_phys(tbd_address);
-                uint16_t tx_buffer_size = e100_ldw_le_phys(tbd_address + 4);
-                uint16_t tx_buffer_el = e100_ldw_le_phys(tbd_address + 6);
+                uint32_t tx_buffer_address = ldl_pci_dma(&s->dev, tbd_address);
+                uint16_t tx_buffer_size = lduw_pci_dma(&s->dev, tbd_address + 4);
+                uint16_t tx_buffer_el = lduw_pci_dma(&s->dev, tbd_address + 6);
                 tbd_address += 8;
                 TRACE(RXTX, logout
                     ("TBD (extended flexible mode): buffer address 0x%08x, size 0x%04x\n",
                      tx_buffer_address, tx_buffer_size));
                 tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
-                cpu_physical_memory_read(tx_buffer_address, &buf[size],
-                                         tx_buffer_size);
+                pci_dma_read(&s->dev, tx_buffer_address,
+                             &buf[size], tx_buffer_size);
                 size += tx_buffer_size;
                 if (tx_buffer_el & 1) {
                     break;
@@ -828,16 +797,16 @@ static void tx_command(EEPRO100State *s)
         }
         tbd_address = tbd_array;
         for (; tbd_count < s->tx.tbd_count; tbd_count++) {
-            uint32_t tx_buffer_address = e100_ldl_le_phys(tbd_address);
-            uint16_t tx_buffer_size = e100_ldw_le_phys(tbd_address + 4);
-            uint16_t tx_buffer_el = e100_ldw_le_phys(tbd_address + 6);
+            uint32_t tx_buffer_address = ldl_pci_dma(&s->dev, tbd_address);
+            uint16_t tx_buffer_size = lduw_pci_dma(&s->dev, tbd_address + 4);
+            uint16_t tx_buffer_el = lduw_pci_dma(&s->dev, tbd_address + 6);
             tbd_address += 8;
             TRACE(RXTX, logout
                 ("TBD (flexible mode): buffer address 0x%08x, size 0x%04x\n",
                  tx_buffer_address, tx_buffer_size));
             tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
-            cpu_physical_memory_read(tx_buffer_address, &buf[size],
-                                     tx_buffer_size);
+            pci_dma_read(&s->dev, tx_buffer_address,
+                         &buf[size], tx_buffer_size);
             size += tx_buffer_size;
             if (tx_buffer_el & 1) {
                 break;
@@ -862,7 +831,7 @@ static void set_multicast_list(EEPRO100State *s)
     TRACE(OTHER, logout("multicast list, multicast count = %u\n", multicast_count));
     for (i = 0; i < multicast_count; i += 6) {
         uint8_t multicast_addr[6];
-        cpu_physical_memory_read(s->cb_address + 10 + i, multicast_addr, 6);
+        pci_dma_read(&s->dev, s->cb_address + 10 + i, multicast_addr, 6);
         TRACE(OTHER, logout("multicast entry %s\n", nic_dump(multicast_addr, 6)));
         unsigned mcast_idx = compute_mcast_idx(multicast_addr);
         assert(mcast_idx < 64);
@@ -896,12 +865,12 @@ static void action_command(EEPRO100State *s)
             /* Do nothing. */
             break;
         case CmdIASetup:
-            cpu_physical_memory_read(s->cb_address + 8, &s->conf.macaddr.a[0], 6);
+            pci_dma_read(&s->dev, s->cb_address + 8, &s->conf.macaddr.a[0], 6);
             TRACE(OTHER, logout("macaddr: %s\n", nic_dump(&s->conf.macaddr.a[0], 6)));
             break;
         case CmdConfigure:
-            cpu_physical_memory_read(s->cb_address + 8, &s->configuration[0],
-                                     sizeof(s->configuration));
+            pci_dma_read(&s->dev, s->cb_address + 8,
+                         &s->configuration[0], sizeof(s->configuration));
             TRACE(OTHER, logout("configuration: %s\n",
                                 nic_dump(&s->configuration[0], 16)));
             TRACE(OTHER, logout("configuration: %s\n",
@@ -938,7 +907,7 @@ static void action_command(EEPRO100State *s)
             break;
         }
         /* Write new status. */
-        e100_stw_le_phys(s->cb_address, s->tx.status | ok_status | STATUS_C);
+        stw_pci_dma(&s->dev, s->cb_address, s->tx.status | ok_status | STATUS_C);
         if (bit_i) {
             /* CU completed action. */
             eepro100_cx_interrupt(s);
@@ -1005,7 +974,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
         /* Dump statistical counters. */
         TRACE(OTHER, logout("val=0x%02x (dump stats)\n", val));
         dump_statistics(s);
-        e100_stl_le_phys(s->statsaddr + s->stats_size, 0xa005);
+        stl_pci_dma(&s->dev, s->statsaddr + s->stats_size, 0xa005);
         break;
     case CU_CMD_BASE:
         /* Load CU base. */
@@ -1016,7 +985,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
         /* Dump and reset statistical counters. */
         TRACE(OTHER, logout("val=0x%02x (dump stats and reset)\n", val));
         dump_statistics(s);
-        e100_stl_le_phys(s->statsaddr + s->stats_size, 0xa007);
+        stl_pci_dma(&s->dev, s->statsaddr + s->stats_size, 0xa007);
         memset(&s->statistics, 0, sizeof(s->statistics));
         break;
     case CU_SRESUME:
@@ -1310,10 +1279,10 @@ static void eepro100_write_port(EEPRO100State *s)
     case PORT_SELFTEST:
         TRACE(OTHER, logout("selftest address=0x%08x\n", address));
         eepro100_selftest_t data;
-        cpu_physical_memory_read(address, &data, sizeof(data));
+        pci_dma_read(&s->dev, address, (uint8_t *) & data, sizeof(data));
         data.st_sign = 0xffffffff;
         data.st_result = 0;
-        cpu_physical_memory_write(address, &data, sizeof(data));
+        pci_dma_write(&s->dev, address, (uint8_t *) & data, sizeof(data));
         break;
     case PORT_SELECTIVE_RESET:
         TRACE(OTHER, logout("selective reset, selftest address=0x%08x\n", address));
@@ -1729,8 +1698,8 @@ static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size
     }
     /* !!! */
     eepro100_rx_t rx;
-    cpu_physical_memory_read(s->ru_base + s->ru_offset, &rx,
-                             sizeof(eepro100_rx_t));
+    pci_dma_read(&s->dev, s->ru_base + s->ru_offset,
+                 (uint8_t *) &rx, sizeof(eepro100_rx_t));
     uint16_t rfd_command = le16_to_cpu(rx.command);
     uint16_t rfd_size = le16_to_cpu(rx.size);
 
@@ -1746,10 +1715,10 @@ static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size
 #endif
     TRACE(OTHER, logout("command 0x%04x, link 0x%08x, addr 0x%08x, size %u\n",
           rfd_command, rx.link, rx.rx_buf_addr, rfd_size));
-    e100_stw_le_phys(s->ru_base + s->ru_offset +
-                     offsetof(eepro100_rx_t, status), rfd_status);
-    e100_stw_le_phys(s->ru_base + s->ru_offset +
-                     offsetof(eepro100_rx_t, count), size);
+    stw_pci_dma(&s->dev, s->ru_base + s->ru_offset +
+                offsetof(eepro100_rx_t, status), rfd_status);
+    stw_pci_dma(&s->dev, s->ru_base + s->ru_offset +
+                offsetof(eepro100_rx_t, count), size);
     /* Early receive interrupt not supported. */
 #if 0
     eepro100_er_interrupt(s);
@@ -1763,8 +1732,8 @@ static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size
 #if 0
     assert(!(s->configuration[17] & BIT(0)));
 #endif
-    cpu_physical_memory_write(s->ru_base + s->ru_offset +
-                              sizeof(eepro100_rx_t), buf, size);
+    pci_dma_write(&s->dev, s->ru_base + s->ru_offset +
+                  sizeof(eepro100_rx_t), buf, size);
     s->statistics.rx_good_frames++;
     eepro100_fr_interrupt(s);
     s->ru_offset = le32_to_cpu(rx.link);
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 04/10] ac97: Use PCI DMA stub functions
  2011-09-01  5:00 [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits David Gibson
                   ` (2 preceding siblings ...)
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 03/10] eepro100: " David Gibson
@ 2011-09-01  5:00 ` David Gibson
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 05/10] es1370: " David Gibson
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 34+ messages in thread
From: David Gibson @ 2011-09-01  5:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: joerg.roedel, aliguori, rth, agraf, eduard.munteanu

From: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>

This updates the ac97 device emulation to use the explicit PCI DMA
functions, instead of directly calling physical memory access functions.

Signed-off-by: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/ac97.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/ac97.c b/hw/ac97.c
index 541d9a4..14bdbcd 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -18,6 +18,7 @@
 #include "audiodev.h"
 #include "audio/audio.h"
 #include "pci.h"
+#include "dma.h"
 
 enum {
     AC97_Reset                     = 0x00,
@@ -224,7 +225,7 @@ static void fetch_bd (AC97LinkState *s, AC97BusMasterRegs *r)
 {
     uint8_t b[8];
 
-    cpu_physical_memory_read (r->bdbar + r->civ * 8, b, 8);
+    pci_dma_read (&s->dev, r->bdbar + r->civ * 8, b, 8);
     r->bd_valid = 1;
     r->bd.addr = le32_to_cpu (*(uint32_t *) &b[0]) & ~3;
     r->bd.ctl_len = le32_to_cpu (*(uint32_t *) &b[4]);
@@ -973,7 +974,7 @@ static int write_audio (AC97LinkState *s, AC97BusMasterRegs *r,
     while (temp) {
         int copied;
         to_copy = audio_MIN (temp, sizeof (tmpbuf));
-        cpu_physical_memory_read (addr, tmpbuf, to_copy);
+        pci_dma_read (&s->dev, addr, tmpbuf, to_copy);
         copied = AUD_write (s->voice_po, tmpbuf, to_copy);
         dolog ("write_audio max=%x to_copy=%x copied=%x\n",
                max, to_copy, copied);
@@ -1054,7 +1055,7 @@ static int read_audio (AC97LinkState *s, AC97BusMasterRegs *r,
             *stop = 1;
             break;
         }
-        cpu_physical_memory_write (addr, tmpbuf, acquired);
+        pci_dma_write (&s->dev, addr, tmpbuf, acquired);
         temp -= acquired;
         addr += acquired;
         nread += acquired;
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 05/10] es1370: Use PCI DMA stub functions
  2011-09-01  5:00 [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits David Gibson
                   ` (3 preceding siblings ...)
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 04/10] ac97: " David Gibson
@ 2011-09-01  5:00 ` David Gibson
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 06/10] e1000: " David Gibson
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 34+ messages in thread
From: David Gibson @ 2011-09-01  5:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: joerg.roedel, aliguori, rth, agraf, eduard.munteanu

From: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>

This updates the es1370 device emulation to use the explicit PCI DMA
functions, instead of directly calling physical memory access functions.

Signed-off-by: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/es1370.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/es1370.c b/hw/es1370.c
index a9387d1..fbbb94f 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -30,6 +30,7 @@
 #include "audiodev.h"
 #include "audio/audio.h"
 #include "pci.h"
+#include "dma.h"
 
 /* Missing stuff:
    SCTRL_P[12](END|ST)INC
@@ -802,7 +803,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,
             if (!acquired)
                 break;
 
-            cpu_physical_memory_write (addr, tmpbuf, acquired);
+            pci_dma_write (&s->dev, addr, tmpbuf, acquired);
 
             temp -= acquired;
             addr += acquired;
@@ -816,7 +817,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,
             int copied, to_copy;
 
             to_copy = audio_MIN ((size_t) temp, sizeof (tmpbuf));
-            cpu_physical_memory_read (addr, tmpbuf, to_copy);
+            pci_dma_read (&s->dev, addr, tmpbuf, to_copy);
             copied = AUD_write (voice, tmpbuf, to_copy);
             if (!copied)
                 break;
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 06/10] e1000: Use PCI DMA stub functions
  2011-09-01  5:00 [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits David Gibson
                   ` (4 preceding siblings ...)
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 05/10] es1370: " David Gibson
@ 2011-09-01  5:00 ` David Gibson
  2011-09-01  5:01 ` [Qemu-devel] [PATCH 07/10] lsi53c895a: " David Gibson
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 34+ messages in thread
From: David Gibson @ 2011-09-01  5:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: joerg.roedel, aliguori, rth, agraf, eduard.munteanu

From: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>

This updates the e1000 device emulation to use the explicit PCI DMA
functions, instead of directly calling physical memory access functions.

Signed-off-by: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/e1000.c |   29 +++++++++++++++--------------
 1 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/hw/e1000.c b/hw/e1000.c
index a6d12c5..b782b49 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -31,6 +31,7 @@
 #include "net/checksum.h"
 #include "loader.h"
 #include "sysemu.h"
+#include "dma.h"
 
 #include "e1000_hw.h"
 
@@ -465,7 +466,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
             bytes = split_size;
             if (tp->size + bytes > msh)
                 bytes = msh - tp->size;
-            cpu_physical_memory_read(addr, tp->data + tp->size, bytes);
+            pci_dma_read(&s->dev, addr, tp->data + tp->size, bytes);
             if ((sz = tp->size + bytes) >= hdr && tp->size < hdr)
                 memmove(tp->header, tp->data, hdr);
             tp->size = sz;
@@ -480,7 +481,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
         // context descriptor TSE is not set, while data descriptor TSE is set
         DBGOUT(TXERR, "TCP segmentaion Error\n");
     } else {
-        cpu_physical_memory_read(addr, tp->data + tp->size, split_size);
+        pci_dma_read(&s->dev, addr, tp->data + tp->size, split_size);
         tp->size += split_size;
     }
 
@@ -496,7 +497,7 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
 }
 
 static uint32_t
-txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp)
+txdesc_writeback(E1000State *s, dma_addr_t base, struct e1000_tx_desc *dp)
 {
     uint32_t txd_upper, txd_lower = le32_to_cpu(dp->lower.data);
 
@@ -505,8 +506,8 @@ txdesc_writeback(target_phys_addr_t base, struct e1000_tx_desc *dp)
     txd_upper = (le32_to_cpu(dp->upper.data) | E1000_TXD_STAT_DD) &
                 ~(E1000_TXD_STAT_EC | E1000_TXD_STAT_LC | E1000_TXD_STAT_TU);
     dp->upper.data = cpu_to_le32(txd_upper);
-    cpu_physical_memory_write(base + ((char *)&dp->upper - (char *)dp),
-                              (void *)&dp->upper, sizeof(dp->upper));
+    pci_dma_write(&s->dev, base + ((char *)&dp->upper - (char *)dp),
+                  (void *)&dp->upper, sizeof(dp->upper));
     return E1000_ICR_TXDW;
 }
 
@@ -521,7 +522,7 @@ static uint64_t tx_desc_base(E1000State *s)
 static void
 start_xmit(E1000State *s)
 {
-    target_phys_addr_t base;
+    dma_addr_t base;
     struct e1000_tx_desc desc;
     uint32_t tdh_start = s->mac_reg[TDH], cause = E1000_ICS_TXQE;
 
@@ -533,14 +534,14 @@ start_xmit(E1000State *s)
     while (s->mac_reg[TDH] != s->mac_reg[TDT]) {
         base = tx_desc_base(s) +
                sizeof(struct e1000_tx_desc) * s->mac_reg[TDH];
-        cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
+        pci_dma_read(&s->dev, base, (void *)&desc, sizeof(desc));
 
         DBGOUT(TX, "index %d: %p : %x %x\n", s->mac_reg[TDH],
                (void *)(intptr_t)desc.buffer_addr, desc.lower.data,
                desc.upper.data);
 
         process_tx_desc(s, &desc);
-        cause |= txdesc_writeback(base, &desc);
+        cause |= txdesc_writeback(s, base, &desc);
 
         if (++s->mac_reg[TDH] * sizeof(desc) >= s->mac_reg[TDLEN])
             s->mac_reg[TDH] = 0;
@@ -668,7 +669,7 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
 {
     E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
     struct e1000_rx_desc desc;
-    target_phys_addr_t base;
+    dma_addr_t base;
     unsigned int n, rdt;
     uint32_t rdh_start;
     uint16_t vlan_special = 0;
@@ -713,7 +714,7 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
             desc_size = s->rxbuf_size;
         }
         base = rx_desc_base(s) + sizeof(desc) * s->mac_reg[RDH];
-        cpu_physical_memory_read(base, (void *)&desc, sizeof(desc));
+        pci_dma_read(&s->dev, base, (void *)&desc, sizeof(desc));
         desc.special = vlan_special;
         desc.status |= (vlan_status | E1000_RXD_STAT_DD);
         if (desc.buffer_addr) {
@@ -722,9 +723,9 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
                 if (copy_size > s->rxbuf_size) {
                     copy_size = s->rxbuf_size;
                 }
-                cpu_physical_memory_write(le64_to_cpu(desc.buffer_addr),
-                                          (void *)(buf + desc_offset + vlan_offset),
-                                          copy_size);
+                pci_dma_write(&s->dev, le64_to_cpu(desc.buffer_addr),
+                                 (void *)(buf + desc_offset + vlan_offset),
+                                 copy_size);
             }
             desc_offset += desc_size;
             desc.length = cpu_to_le16(desc_size);
@@ -738,7 +739,7 @@ e1000_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
         } else { // as per intel docs; skip descriptors with null buf addr
             DBGOUT(RX, "Null RX descriptor!!\n");
         }
-        cpu_physical_memory_write(base, (void *)&desc, sizeof(desc));
+        pci_dma_write(&s->dev, base, (void *)&desc, sizeof(desc));
 
         if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
             s->mac_reg[RDH] = 0;
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 07/10] lsi53c895a: Use PCI DMA stub functions
  2011-09-01  5:00 [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits David Gibson
                   ` (5 preceding siblings ...)
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 06/10] e1000: " David Gibson
@ 2011-09-01  5:01 ` David Gibson
  2011-09-01  5:01 ` [Qemu-devel] [PATCH 08/10] pcnet-pci: " David Gibson
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 34+ messages in thread
From: David Gibson @ 2011-09-01  5:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: joerg.roedel, aliguori, rth, agraf, eduard.munteanu

From: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>

This updates the lsi53c895a device emulation to use the explicit PCI DMA
functions, instead of directly calling physical memory access functions.

Signed-off-by: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/lsi53c895a.c |   30 ++++++++++++++----------------
 1 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 1643a63..f1f6800 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -16,6 +16,7 @@
 #include "pci.h"
 #include "scsi.h"
 #include "block_int.h"
+#include "dma.h"
 
 //#define DEBUG_LSI
 //#define DEBUG_LSI_REG
@@ -391,10 +392,7 @@ static inline uint32_t read_dword(LSIState *s, uint32_t addr)
 {
     uint32_t buf;
 
-    /* XXX: an optimization here used to fast-path the read from scripts
-     * memory.  But that bypasses any iommu.
-     */
-    cpu_physical_memory_read(addr, (uint8_t *)&buf, 4);
+    pci_dma_read(&s->dev, addr, (uint8_t *)&buf, 4);
     return cpu_to_le32(buf);
 }
 
@@ -533,7 +531,7 @@ static void lsi_bad_selection(LSIState *s, uint32_t id)
 static void lsi_do_dma(LSIState *s, int out)
 {
     uint32_t count, id;
-    target_phys_addr_t addr;
+    dma_addr_t addr;
     SCSIDevice *dev;
 
     assert(s->current);
@@ -572,9 +570,9 @@ static void lsi_do_dma(LSIState *s, int out)
     }
     /* ??? Set SFBR to first data byte.  */
     if (out) {
-        cpu_physical_memory_read(addr, s->current->dma_buf, count);
+        pci_dma_read(&s->dev, addr, s->current->dma_buf, count);
     } else {
-        cpu_physical_memory_write(addr, s->current->dma_buf, count);
+        pci_dma_write(&s->dev, addr, s->current->dma_buf, count);
     }
     s->current->dma_len -= count;
     if (s->current->dma_len == 0) {
@@ -767,7 +765,7 @@ static void lsi_do_command(LSIState *s)
     DPRINTF("Send command len=%d\n", s->dbc);
     if (s->dbc > 16)
         s->dbc = 16;
-    cpu_physical_memory_read(s->dnad, buf, s->dbc);
+    pci_dma_read(&s->dev, s->dnad, buf, s->dbc);
     s->sfbr = buf[0];
     s->command_complete = 0;
 
@@ -818,7 +816,7 @@ static void lsi_do_status(LSIState *s)
     s->dbc = 1;
     status = s->status;
     s->sfbr = status;
-    cpu_physical_memory_write(s->dnad, &status, 1);
+    pci_dma_write(&s->dev, s->dnad, &status, 1);
     lsi_set_phase(s, PHASE_MI);
     s->msg_action = 1;
     lsi_add_msg_byte(s, 0); /* COMMAND COMPLETE */
@@ -832,7 +830,7 @@ static void lsi_do_msgin(LSIState *s)
     len = s->msg_len;
     if (len > s->dbc)
         len = s->dbc;
-    cpu_physical_memory_write(s->dnad, s->msg, len);
+    pci_dma_write(&s->dev, s->dnad, s->msg, len);
     /* Linux drivers rely on the last byte being in the SIDL.  */
     s->sidl = s->msg[len - 1];
     s->msg_len -= len;
@@ -864,7 +862,7 @@ static void lsi_do_msgin(LSIState *s)
 static uint8_t lsi_get_msgbyte(LSIState *s)
 {
     uint8_t data;
-    cpu_physical_memory_read(s->dnad, &data, 1);
+    pci_dma_read(&s->dev, s->dnad, &data, 1);
     s->dnad++;
     s->dbc--;
     return data;
@@ -1019,8 +1017,8 @@ static void lsi_memcpy(LSIState *s, uint32_t dest, uint32_t src, int count)
     DPRINTF("memcpy dest 0x%08x src 0x%08x count %d\n", dest, src, count);
     while (count) {
         n = (count > LSI_BUF_SIZE) ? LSI_BUF_SIZE : count;
-        cpu_physical_memory_read(src, buf, n);
-        cpu_physical_memory_write(dest, buf, n);
+        pci_dma_read(&s->dev, src, buf, n);
+        pci_dma_write(&s->dev, dest, buf, n);
         src += n;
         dest += n;
         count -= n;
@@ -1088,7 +1086,7 @@ again:
 
             /* 32-bit Table indirect */
             offset = sxt24(addr);
-            cpu_physical_memory_read(s->dsa + offset, (uint8_t *)buf, 8);
+            pci_dma_read(&s->dev, s->dsa + offset, (uint8_t *)buf, 8);
             /* byte count is stored in bits 0:23 only */
             s->dbc = cpu_to_le32(buf[0]) & 0xffffff;
             s->rbc = s->dbc;
@@ -1447,7 +1445,7 @@ again:
             n = (insn & 7);
             reg = (insn >> 16) & 0xff;
             if (insn & (1 << 24)) {
-                cpu_physical_memory_read(addr, data, n);
+                pci_dma_read(&s->dev, addr, data, n);
                 DPRINTF("Load reg 0x%x size %d addr 0x%08x = %08x\n", reg, n,
                         addr, *(int *)data);
                 for (i = 0; i < n; i++) {
@@ -1458,7 +1456,7 @@ again:
                 for (i = 0; i < n; i++) {
                     data[i] = lsi_reg_readb(s, reg + i);
                 }
-                cpu_physical_memory_write(addr, data, n);
+                pci_dma_write(&s->dev, addr, data, n);
             }
         }
     }
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 08/10] pcnet-pci: Use PCI DMA stub functions
  2011-09-01  5:00 [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits David Gibson
                   ` (6 preceding siblings ...)
  2011-09-01  5:01 ` [Qemu-devel] [PATCH 07/10] lsi53c895a: " David Gibson
@ 2011-09-01  5:01 ` David Gibson
  2011-09-01  5:01 ` [Qemu-devel] [PATCH 09/10] usb-ohci: " David Gibson
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 34+ messages in thread
From: David Gibson @ 2011-09-01  5:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: joerg.roedel, aliguori, rth, agraf, eduard.munteanu

From: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>

This updates the pcnet-pci device emulation to use the explicit PCI DMA
functions, instead of directly calling physical memory access functions.

Signed-off-by: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/pcnet-pci.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 51e1320..40403a9 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -31,6 +31,7 @@
 #include "net.h"
 #include "loader.h"
 #include "qemu-timer.h"
+#include "dma.h"
 
 #include "pcnet.h"
 
@@ -230,13 +231,13 @@ static const MemoryRegionOps pcnet_mmio_ops = {
 static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
                                       uint8_t *buf, int len, int do_bswap)
 {
-    cpu_physical_memory_write(addr, buf, len);
+    pci_dma_write(dma_opaque, addr, buf, len);
 }
 
 static void pci_physical_memory_read(void *dma_opaque, target_phys_addr_t addr,
                                      uint8_t *buf, int len, int do_bswap)
 {
-    cpu_physical_memory_read(addr, buf, len);
+    pci_dma_read(dma_opaque, addr, buf, len);
 }
 
 static void pci_pcnet_cleanup(VLANClientState *nc)
@@ -302,6 +303,7 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
     s->irq = pci_dev->irq[0];
     s->phys_mem_read = pci_physical_memory_read;
     s->phys_mem_write = pci_physical_memory_write;
+    s->dma_opaque = pci_dev;
 
     if (!pci_dev->qdev.hotplugged) {
         static int loaded = 0;
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 09/10] usb-ohci: Use PCI DMA stub functions
  2011-09-01  5:00 [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits David Gibson
                   ` (7 preceding siblings ...)
  2011-09-01  5:01 ` [Qemu-devel] [PATCH 08/10] pcnet-pci: " David Gibson
@ 2011-09-01  5:01 ` David Gibson
  2011-09-01 10:10   ` Gerd Hoffmann
  2011-09-01  5:01 ` [Qemu-devel] [PATCH 10/10] intel-hda: " David Gibson
  2011-09-01 11:33 ` [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits Eduard - Gabriel Munteanu
  10 siblings, 1 reply; 34+ messages in thread
From: David Gibson @ 2011-09-01  5:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: joerg.roedel, aliguori, rth, agraf, eduard.munteanu

From: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>

This updates the usb-ohci device emulation to use the explicit PCI DMA
functions, instead of directly calling physical memory access functions.

Signed-off-by: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/usb-ohci.c |   46 ++++++++++++++++++++++++++++------------------
 1 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index d30db3f..d3c0641 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -30,6 +30,7 @@
 #include "qemu-timer.h"
 #include "usb.h"
 #include "pci.h"
+#include "dma.h"
 #include "usb-ohci.h"
 #include "sysbus.h"
 #include "qdev-addr.h"
@@ -116,6 +117,14 @@ typedef struct {
 
 } OHCIState;
 
+typedef struct {
+    PCIDevice pci_dev;
+    OHCIState state;
+    char *masterbus;
+    uint32_t num_ports;
+    uint32_t firstport;
+} OHCIPCIState;
+
 /* Host Controller Communications Area */
 struct ohci_hcca {
     uint32_t intr[32];
@@ -463,12 +472,13 @@ static void ohci_reset(void *opaque)
 static inline int get_dwords(OHCIState *ohci,
                              uint32_t addr, uint32_t *buf, int num)
 {
+    OHCIPCIState *s = container_of(ohci, OHCIPCIState, state);
     int i;
 
     addr += ohci->localmem_base;
 
     for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
-        cpu_physical_memory_read(addr, buf, sizeof(*buf));
+        pci_dma_read(&s->pci_dev, addr, buf, sizeof(*buf));
         *buf = le32_to_cpu(*buf);
     }
 
@@ -479,13 +489,14 @@ static inline int get_dwords(OHCIState *ohci,
 static inline int put_dwords(OHCIState *ohci,
                              uint32_t addr, uint32_t *buf, int num)
 {
+    OHCIPCIState *s = container_of(ohci, OHCIPCIState, state);
     int i;
 
     addr += ohci->localmem_base;
 
     for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
         uint32_t tmp = cpu_to_le32(*buf);
-        cpu_physical_memory_write(addr, &tmp, sizeof(tmp));
+        pci_dma_write(&s->pci_dev, addr, &tmp, sizeof(tmp));
     }
 
     return 1;
@@ -495,12 +506,13 @@ static inline int put_dwords(OHCIState *ohci,
 static inline int get_words(OHCIState *ohci,
                             uint32_t addr, uint16_t *buf, int num)
 {
+    OHCIPCIState *s = container_of(ohci, OHCIPCIState, state);
     int i;
 
     addr += ohci->localmem_base;
 
     for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
-        cpu_physical_memory_read(addr, buf, sizeof(*buf));
+        pci_dma_read(&s->pci_dev, addr, buf, sizeof(*buf));
         *buf = le16_to_cpu(*buf);
     }
 
@@ -511,13 +523,14 @@ static inline int get_words(OHCIState *ohci,
 static inline int put_words(OHCIState *ohci,
                             uint32_t addr, uint16_t *buf, int num)
 {
+    OHCIPCIState *s = container_of(ohci, OHCIPCIState, state);
     int i;
 
     addr += ohci->localmem_base;
 
     for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
         uint16_t tmp = cpu_to_le16(*buf);
-        cpu_physical_memory_write(addr, &tmp, sizeof(tmp));
+        pci_dma_write(&s->pci_dev, addr, &tmp, sizeof(tmp));
     }
 
     return 1;
@@ -545,7 +558,8 @@ static inline int ohci_read_iso_td(OHCIState *ohci,
 static inline int ohci_read_hcca(OHCIState *ohci,
                                  uint32_t addr, struct ohci_hcca *hcca)
 {
-    cpu_physical_memory_read(addr + ohci->localmem_base, hcca, sizeof(*hcca));
+    OHCIPCIState *s = container_of(ohci, OHCIPCIState, state);
+    pci_dma_read(&s->pci_dev, addr + ohci->localmem_base, hcca, sizeof(*hcca));
     return 1;
 }
 
@@ -571,7 +585,9 @@ static inline int ohci_put_iso_td(OHCIState *ohci,
 static inline int ohci_put_hcca(OHCIState *ohci,
                                 uint32_t addr, struct ohci_hcca *hcca)
 {
-    cpu_physical_memory_write(addr + ohci->localmem_base, hcca, sizeof(*hcca));
+    OHCIPCIState *s = container_of(ohci, OHCIPCIState, state);
+
+    pci_dma_write(&s->pci_dev, addr + ohci->localmem_base, hcca, sizeof(*hcca));
     return 1;
 }
 
@@ -579,6 +595,7 @@ static inline int ohci_put_hcca(OHCIState *ohci,
 static void ohci_copy_td(OHCIState *ohci, struct ohci_td *td,
                          uint8_t *buf, int len, int write)
 {
+    OHCIPCIState *s = container_of(ohci, OHCIPCIState, state);
     uint32_t ptr;
     uint32_t n;
 
@@ -586,12 +603,12 @@ static void ohci_copy_td(OHCIState *ohci, struct ohci_td *td,
     n = 0x1000 - (ptr & 0xfff);
     if (n > len)
         n = len;
-    cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, n, write);
+    pci_dma_rw(&s->pci_dev, ptr + ohci->localmem_base, buf, n, write);
     if (n == len)
         return;
     ptr = td->be & ~0xfffu;
     buf += n;
-    cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, len - n, write);
+    pci_dma_rw(&s->pci_dev, ptr + ohci->localmem_base, buf, len - n, write);
 }
 
 /* Read/Write the contents of an ISO TD from/to main memory.  */
@@ -599,6 +616,7 @@ static void ohci_copy_iso_td(OHCIState *ohci,
                              uint32_t start_addr, uint32_t end_addr,
                              uint8_t *buf, int len, int write)
 {
+    OHCIPCIState *s = container_of(ohci, OHCIPCIState, state);
     uint32_t ptr;
     uint32_t n;
 
@@ -606,12 +624,12 @@ static void ohci_copy_iso_td(OHCIState *ohci,
     n = 0x1000 - (ptr & 0xfff);
     if (n > len)
         n = len;
-    cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, n, write);
+    pci_dma_rw(&s->pci_dev, ptr + ohci->localmem_base, buf, n, write);
     if (n == len)
         return;
     ptr = end_addr & ~0xfffu;
     buf += n;
-    cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, len - n, write);
+    pci_dma_rw(&s->pci_dev, ptr + ohci->localmem_base, buf, len - n, write);
 }
 
 static void ohci_process_lists(OHCIState *ohci, int completion);
@@ -1767,14 +1785,6 @@ static int usb_ohci_init(OHCIState *ohci, DeviceState *dev,
     return 0;
 }
 
-typedef struct {
-    PCIDevice pci_dev;
-    OHCIState state;
-    char *masterbus;
-    uint32_t num_ports;
-    uint32_t firstport;
-} OHCIPCIState;
-
 static int usb_ohci_initfn_pci(struct PCIDevice *dev)
 {
     OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, dev);
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [Qemu-devel] [PATCH 10/10] intel-hda: Use PCI DMA stub functions
  2011-09-01  5:00 [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits David Gibson
                   ` (8 preceding siblings ...)
  2011-09-01  5:01 ` [Qemu-devel] [PATCH 09/10] usb-ohci: " David Gibson
@ 2011-09-01  5:01 ` David Gibson
  2011-09-01 10:16   ` Gerd Hoffmann
  2011-09-01 11:33 ` [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits Eduard - Gabriel Munteanu
  10 siblings, 1 reply; 34+ messages in thread
From: David Gibson @ 2011-09-01  5:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: joerg.roedel, aliguori, rth, agraf, eduard.munteanu

This updates the intel-hda device emulation to use the explicit PCI DMA
functions, instead of directly calling physical memory access functions.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 hw/intel-hda.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 4272204..392bfc5 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -24,6 +24,7 @@
 #include "audiodev.h"
 #include "intel-hda.h"
 #include "intel-hda-defs.h"
+#include "dma.h"
 
 /* --------------------------------------------------------------------- */
 /* hda bus                                                               */
@@ -425,8 +426,7 @@ static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,
         dprint(d, 3, "dma: entry %d, pos %d/%d, copy %d\n",
                st->be, st->bp, st->bpl[st->be].len, copy);
 
-        cpu_physical_memory_rw(st->bpl[st->be].addr + st->bp,
-                               buf, copy, !output);
+        pci_dma_rw(&d->pci, st->bpl[st->be].addr + st->bp, buf, copy, !output);
         st->lpib += copy;
         st->bp += copy;
         buf += copy;
@@ -470,7 +470,7 @@ static void intel_hda_parse_bdl(IntelHDAState *d, IntelHDAStream *st)
     g_free(st->bpl);
     st->bpl = g_malloc(sizeof(bpl) * st->bentries);
     for (i = 0; i < st->bentries; i++, addr += 16) {
-        cpu_physical_memory_read(addr, buf, 16);
+        pci_dma_read(&d->pci, addr, buf, 16);
         st->bpl[i].addr  = le64_to_cpu(*(uint64_t *)buf);
         st->bpl[i].len   = le32_to_cpu(*(uint32_t *)(buf + 8));
         st->bpl[i].flags = le32_to_cpu(*(uint32_t *)(buf + 12));
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 09/10] usb-ohci: Use PCI DMA stub functions
  2011-09-01  5:01 ` [Qemu-devel] [PATCH 09/10] usb-ohci: " David Gibson
@ 2011-09-01 10:10   ` Gerd Hoffmann
  2011-09-02  1:47     ` David Gibson
  0 siblings, 1 reply; 34+ messages in thread
From: Gerd Hoffmann @ 2011-09-01 10:10 UTC (permalink / raw)
  To: David Gibson
  Cc: aliguori, joerg.roedel, qemu-devel, agraf, eduard.munteanu, rth

On 09/01/11 07:01, David Gibson wrote:
> From: Eduard - Gabriel Munteanu<eduard.munteanu@linux360.ro>
>
> This updates the usb-ohci device emulation to use the explicit PCI DMA
> functions, instead of directly calling physical memory access functions.

It isn't that simple.

There are non-PCI ohci devices which I think you break with this patch.

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 10/10] intel-hda: Use PCI DMA stub functions
  2011-09-01  5:01 ` [Qemu-devel] [PATCH 10/10] intel-hda: " David Gibson
@ 2011-09-01 10:16   ` Gerd Hoffmann
  2011-09-02  1:42     ` David Gibson
  0 siblings, 1 reply; 34+ messages in thread
From: Gerd Hoffmann @ 2011-09-01 10:16 UTC (permalink / raw)
  To: David Gibson
  Cc: aliguori, joerg.roedel, qemu-devel, agraf, eduard.munteanu, rth

On 09/01/11 07:01, David Gibson wrote:
> This updates the intel-hda device emulation to use the explicit PCI DMA
> functions, instead of directly calling physical memory access functions.

There are some calls to {st,ld}l_le_phys() which need conversion too.

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits
  2011-09-01  5:00 [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits David Gibson
                   ` (9 preceding siblings ...)
  2011-09-01  5:01 ` [Qemu-devel] [PATCH 10/10] intel-hda: " David Gibson
@ 2011-09-01 11:33 ` Eduard - Gabriel Munteanu
  2011-09-02  0:36   ` David Gibson
  10 siblings, 1 reply; 34+ messages in thread
From: Eduard - Gabriel Munteanu @ 2011-09-01 11:33 UTC (permalink / raw)
  To: David Gibson; +Cc: agraf, aliguori, qemu-devel, joerg.roedel, rth

On Thu, Sep 01, 2011 at 03:00:53PM +1000, David Gibson wrote:
> A while back, Eduard - Gabriel Munteanu send a series of patches
> implementing support for emulating the AMD IOMMU in conjunction with
> qemu emulated PCI devices.  A revised patch series added support for
> the Intel IOMMU, and I also send a revised version of this series
> which added support for the hypervisor mediated IOMMU on the pseries
> machine.
> 
> Richard Henderson also weighed in on the discussion, and there's still
> a fair bit to be thrashed out in terms of exactly how to set up an
> IOMMU / DMA translation subsystem.
> 
> However, really only 2 or 3 patches in any of these series have
> contained anything interesting.  The rest of the series has been
> converting existing PCI emulated devices to use the new DMA interface
> which worked through the IOMMU translation, whatever it was.  While we
> keep working out what we want for the guts of the IOMMU support, these
> device conversion patches keep bitrotting against updates to the
> various device implementations themselves.

Hi,

This sounds like a good idea. We should be able to agree on these bits,
at least, and get them merged.

> Really, regardless of whether we're actually implementing IOMMU
> translation, it makes sense that qemu code should distinguish between
> when it is really operating in CPU physical addresses and when it is
> operating in bus or DMA addresses which might have some kind of
> translation into physical addresses.
> 
> This series, therefore, begins the conversion of existing PCI device
> emulation code to use new (stub) pci dma access functions.  These are
> for now, just defined to be untranslated cpu physical memory accesses,
> as before, but has two advantages:
> 
>    * It becomes obvious where the code is working with dma addresses,
>      so it's easier to grep for what might be affected by an IOMMU or
>      other bus address translation.
> 
>    * The new stubs take the PCIDevice *, from which any of the various
>      suggested IOMMU interfaces should be able to locate the correct
>      IOMMU translation context.
> 
> This series only converts the easy cases so far.  That is simple
> direct DMA access from device code:
> cpu_physical_memory_{read,write}(), ld*_phys() and st*_phys().  It
> doesn't handle devices which use the scatter/gather code (just ide and
> UHCI, so far).  I plan to address that later, but I have some details
> still to work out.

I think AHCI belongs on that list too, my patches didn't handle it
either.

Somewhere down the road we could try to poison the old cpu_*
interfaces, as suggested by others before.

> Anthony, please apply.

It's nice to see this topic got revived. I'll try to post my latest
SeaBIOS patches these days. The reason I didn't last time was I didn't
get much review/acks/naks on the IOMMU patches from core devs. Hopefully
things will go smoother this time.


	Cheers,
	Eduard

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA David Gibson
@ 2011-09-01 15:35   ` Michael S. Tsirkin
  2011-09-02  0:39     ` David Gibson
  2011-09-02  4:38     ` David Gibson
  2011-09-01 15:55   ` Anthony Liguori
  2011-09-23 16:37   ` Anthony Liguori
  2 siblings, 2 replies; 34+ messages in thread
From: Michael S. Tsirkin @ 2011-09-01 15:35 UTC (permalink / raw)
  To: David Gibson
  Cc: aliguori, joerg.roedel, qemu-devel, agraf, eduard.munteanu, rth

On Thu, Sep 01, 2011 at 03:00:54PM +1000, David Gibson wrote:
> This patch adds functions to pci.[ch] to perform PCI DMA operations.  At
> present, these are just stubs which perform directly cpu physical memory
> accesses.
> 
> Using these stubs, however, distinguishes PCI device DMA transactions from
> other accesses to physical memory, which will allow PCI IOMMU support to
> be added in one place, rather than updating every PCI driver at that time.
> 
> That is, it allows us to update individual PCI drivers to support an IOMMU
> without having yet determined the details of how the IOMMU emulation will
> operate.  This will let us remove the most bitrot-sensitive part of an
> IOMMU patch in advance.
> 
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>  dma.h    |    2 ++
>  hw/pci.c |   31 +++++++++++++++++++++++++++++++
>  hw/pci.h |   33 +++++++++++++++++++++++++++++++++
>  3 files changed, 66 insertions(+), 0 deletions(-)
> 
> diff --git a/dma.h b/dma.h
> index a6db5ba..06e91cb 100644
> --- a/dma.h
> +++ b/dma.h
> @@ -15,6 +15,8 @@
>  #include "hw/hw.h"
>  #include "block.h"
>  
> +typedef target_phys_addr_t dma_addr_t;
> +
>  typedef struct {
>      target_phys_addr_t base;
>      target_phys_addr_t len;
> diff --git a/hw/pci.c b/hw/pci.c
> index 1cdcbb7..842b066 100644
> --- a/hw/pci.c
> +++ b/hw/pci.c
> @@ -2211,3 +2211,34 @@ MemoryRegion *pci_address_space(PCIDevice *dev)
>  {
>      return dev->bus->address_space_mem;
>  }
> +
> +#define DEFINE_LDST_DMA(_lname, _sname, _bits) \
> +    uint##_bits##_t ld##_lname##_pci_dma(PCIDevice *dev, dma_addr_t addr) \
> +    { \
> +        uint##_bits##_t val; \
> +        pci_dma_read(dev, addr, &val, sizeof(val)); \
> +        return le##_bits##_to_cpu(val); \
> +    } \
> +    void st##_sname##_pci_dma(PCIDevice *dev, \
> +                              dma_addr_t addr, uint##_bits##_t val) \
> +    { \
> +        val = cpu_to_le##_bits(val); \
> +        pci_dma_write(dev, addr, &val, sizeof(val)); \
> +    }
> +
> +uint8_t ldub_pci_dma(PCIDevice *dev, dma_addr_t addr)
> +{
> +    uint8_t val;
> +
> +    pci_dma_read(dev, addr, &val, sizeof(val));
> +    return val;
> +}
> +
> +void stb_pci_dma(PCIDevice *dev, dma_addr_t addr, uint8_t val)
> +{
> +    pci_dma_write(dev, addr, &val, sizeof(val));
> +}
> +
> +DEFINE_LDST_DMA(uw, w, 16);
> +DEFINE_LDST_DMA(l, l, 32);
> +DEFINE_LDST_DMA(q, q, 64);
> diff --git a/hw/pci.h b/hw/pci.h
> index 391217e..401d14a 100644
> --- a/hw/pci.h
> +++ b/hw/pci.h
> @@ -6,6 +6,7 @@
>  
>  #include "qdev.h"
>  #include "memory.h"
> +#include "dma.h"
>  
>  /* PCI includes legacy ISA access.  */
>  #include "isa.h"
> @@ -492,4 +493,36 @@ static inline uint32_t pci_config_size(const PCIDevice *d)
>      return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE;
>  }
>  
> +/* DMA access functions */
> +static inline int pci_dma_rw(PCIDevice *dev, dma_addr_t addr,
> +                             void *buf, dma_addr_t len, int is_write)
> +{
> +    cpu_physical_memory_rw(addr, buf, len, is_write);
> +    return 0;
> +}
> +
> +static inline int pci_dma_read(PCIDevice *dev, dma_addr_t addr,
> +                               void *buf, dma_addr_t len)
> +{
> +    return pci_dma_rw(dev, addr, buf, len, 0);
> +}
> +
> +static inline int pci_dma_write(PCIDevice *dev, dma_addr_t addr,
> +                                const void *buf, dma_addr_t len)
> +{
> +    return pci_dma_rw(dev, addr, (void *) buf, len, 1);
> +}
> +
> +#define DECLARE_LDST_DMA(_lname, _sname, _bits) \
> +    uint##_bits##_t ld##_lname##_pci_dma(PCIDevice *dev, dma_addr_t addr); \
> +    void st##_sname##_pci_dma(PCIDevice *dev, dma_addr_t addr, \
> +                              uint##_bits##_t val);            \

prefix macros with PCI_ please.

> +DECLARE_LDST_DMA(ub, b, 8);
> +DECLARE_LDST_DMA(uw, w, 16);
> +DECLARE_LDST_DMA(l, l, 32);
> +DECLARE_LDST_DMA(q, q, 64);
> +
> +#undef DECLARE_LDST_DMA
> +
>  #endif

I'd prefer the stubs to be inline. Not just as an optimization:
it also makes it easier to grok what goes on in the common
no-iommu case.

-- 
MST

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA David Gibson
  2011-09-01 15:35   ` Michael S. Tsirkin
@ 2011-09-01 15:55   ` Anthony Liguori
  2011-09-01 16:03     ` Avi Kivity
  2011-09-03  1:16     ` Richard Henderson
  2011-09-23 16:37   ` Anthony Liguori
  2 siblings, 2 replies; 34+ messages in thread
From: Anthony Liguori @ 2011-09-01 15:55 UTC (permalink / raw)
  To: David Gibson
  Cc: joerg.roedel, agraf, qemu-devel, Avi Kivity, eduard.munteanu, rth

On 09/01/2011 12:00 AM, David Gibson wrote:
> This patch adds functions to pci.[ch] to perform PCI DMA operations.  At
> present, these are just stubs which perform directly cpu physical memory
> accesses.
>
> Using these stubs, however, distinguishes PCI device DMA transactions from
> other accesses to physical memory, which will allow PCI IOMMU support to
> be added in one place, rather than updating every PCI driver at that time.
>
> That is, it allows us to update individual PCI drivers to support an IOMMU
> without having yet determined the details of how the IOMMU emulation will
> operate.  This will let us remove the most bitrot-sensitive part of an
> IOMMU patch in advance.
>
> Signed-off-by: David Gibson<david@gibson.dropbear.id.au>

I think this is the wrong approach given the introduction of the memory API.

I think we should have a generic memory access function that takes a 
MemoryRegion as it's first argument.

The PCI bus should then expose one memory region for each device (that's 
how it can figure out where the access is coming from).

Richard/Avi, what do you think?

Regards,

Anthony Liguori

> ---
>   dma.h    |    2 ++
>   hw/pci.c |   31 +++++++++++++++++++++++++++++++
>   hw/pci.h |   33 +++++++++++++++++++++++++++++++++
>   3 files changed, 66 insertions(+), 0 deletions(-)
>
> diff --git a/dma.h b/dma.h
> index a6db5ba..06e91cb 100644
> --- a/dma.h
> +++ b/dma.h
> @@ -15,6 +15,8 @@
>   #include "hw/hw.h"
>   #include "block.h"
>
> +typedef target_phys_addr_t dma_addr_t;
> +
>   typedef struct {
>       target_phys_addr_t base;
>       target_phys_addr_t len;
> diff --git a/hw/pci.c b/hw/pci.c
> index 1cdcbb7..842b066 100644
> --- a/hw/pci.c
> +++ b/hw/pci.c
> @@ -2211,3 +2211,34 @@ MemoryRegion *pci_address_space(PCIDevice *dev)
>   {
>       return dev->bus->address_space_mem;
>   }
> +
> +#define DEFINE_LDST_DMA(_lname, _sname, _bits) \
> +    uint##_bits##_t ld##_lname##_pci_dma(PCIDevice *dev, dma_addr_t addr) \
> +    { \
> +        uint##_bits##_t val; \
> +        pci_dma_read(dev, addr,&val, sizeof(val)); \
> +        return le##_bits##_to_cpu(val); \
> +    } \
> +    void st##_sname##_pci_dma(PCIDevice *dev, \
> +                              dma_addr_t addr, uint##_bits##_t val) \
> +    { \
> +        val = cpu_to_le##_bits(val); \
> +        pci_dma_write(dev, addr,&val, sizeof(val)); \
> +    }
> +
> +uint8_t ldub_pci_dma(PCIDevice *dev, dma_addr_t addr)
> +{
> +    uint8_t val;
> +
> +    pci_dma_read(dev, addr,&val, sizeof(val));
> +    return val;
> +}
> +
> +void stb_pci_dma(PCIDevice *dev, dma_addr_t addr, uint8_t val)
> +{
> +    pci_dma_write(dev, addr,&val, sizeof(val));
> +}
> +
> +DEFINE_LDST_DMA(uw, w, 16);
> +DEFINE_LDST_DMA(l, l, 32);
> +DEFINE_LDST_DMA(q, q, 64);
> diff --git a/hw/pci.h b/hw/pci.h
> index 391217e..401d14a 100644
> --- a/hw/pci.h
> +++ b/hw/pci.h
> @@ -6,6 +6,7 @@
>
>   #include "qdev.h"
>   #include "memory.h"
> +#include "dma.h"
>
>   /* PCI includes legacy ISA access.  */
>   #include "isa.h"
> @@ -492,4 +493,36 @@ static inline uint32_t pci_config_size(const PCIDevice *d)
>       return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE;
>   }
>
> +/* DMA access functions */
> +static inline int pci_dma_rw(PCIDevice *dev, dma_addr_t addr,
> +                             void *buf, dma_addr_t len, int is_write)
> +{
> +    cpu_physical_memory_rw(addr, buf, len, is_write);
> +    return 0;
> +}
> +
> +static inline int pci_dma_read(PCIDevice *dev, dma_addr_t addr,
> +                               void *buf, dma_addr_t len)
> +{
> +    return pci_dma_rw(dev, addr, buf, len, 0);
> +}
> +
> +static inline int pci_dma_write(PCIDevice *dev, dma_addr_t addr,
> +                                const void *buf, dma_addr_t len)
> +{
> +    return pci_dma_rw(dev, addr, (void *) buf, len, 1);
> +}
> +
> +#define DECLARE_LDST_DMA(_lname, _sname, _bits) \
> +    uint##_bits##_t ld##_lname##_pci_dma(PCIDevice *dev, dma_addr_t addr); \
> +    void st##_sname##_pci_dma(PCIDevice *dev, dma_addr_t addr, \
> +                              uint##_bits##_t val);            \
> +
> +DECLARE_LDST_DMA(ub, b, 8);
> +DECLARE_LDST_DMA(uw, w, 16);
> +DECLARE_LDST_DMA(l, l, 32);
> +DECLARE_LDST_DMA(q, q, 64);
> +
> +#undef DECLARE_LDST_DMA
> +
>   #endif

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-01 15:55   ` Anthony Liguori
@ 2011-09-01 16:03     ` Avi Kivity
  2011-09-01 16:05       ` Anthony Liguori
  2011-09-02  4:40       ` David Gibson
  2011-09-03  1:16     ` Richard Henderson
  1 sibling, 2 replies; 34+ messages in thread
From: Avi Kivity @ 2011-09-01 16:03 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: joerg.roedel, agraf, qemu-devel, eduard.munteanu, David Gibson, rth

On 09/01/2011 06:55 PM, Anthony Liguori wrote:
> On 09/01/2011 12:00 AM, David Gibson wrote:
>> This patch adds functions to pci.[ch] to perform PCI DMA operations.  At
>> present, these are just stubs which perform directly cpu physical memory
>> accesses.
>>
>> Using these stubs, however, distinguishes PCI device DMA transactions 
>> from
>> other accesses to physical memory, which will allow PCI IOMMU support to
>> be added in one place, rather than updating every PCI driver at that 
>> time.
>>
>> That is, it allows us to update individual PCI drivers to support an 
>> IOMMU
>> without having yet determined the details of how the IOMMU emulation 
>> will
>> operate.  This will let us remove the most bitrot-sensitive part of an
>> IOMMU patch in advance.
>>
>> Signed-off-by: David Gibson<david@gibson.dropbear.id.au>
>
> I think this is the wrong approach given the introduction of the 
> memory API.
>
> I think we should have a generic memory access function that takes a 
> MemoryRegion as it's first argument.
>
> The PCI bus should then expose one memory region for each device 
> (that's how it can figure out where the access is coming from).
>
> Richard/Avi, what do you think?
>

I think the patchset is fine.  It routes all access through 
pci_dma_rw(), which accepts a PCIDevice.  We can later define 
pci_dma_rw() in terms of the memory API and get the benefit of the 
memory hierarchy.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-01 16:03     ` Avi Kivity
@ 2011-09-01 16:05       ` Anthony Liguori
  2011-09-01 16:11         ` Avi Kivity
                           ` (2 more replies)
  2011-09-02  4:40       ` David Gibson
  1 sibling, 3 replies; 34+ messages in thread
From: Anthony Liguori @ 2011-09-01 16:05 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Anthony Liguori, joerg.roedel, agraf, qemu-devel,
	eduard.munteanu, rth, David Gibson

On 09/01/2011 11:03 AM, Avi Kivity wrote:
> On 09/01/2011 06:55 PM, Anthony Liguori wrote:
>> On 09/01/2011 12:00 AM, David Gibson wrote:
>>> This patch adds functions to pci.[ch] to perform PCI DMA operations. At
>>> present, these are just stubs which perform directly cpu physical memory
>>> accesses.
>>>
>>> Using these stubs, however, distinguishes PCI device DMA transactions
>>> from
>>> other accesses to physical memory, which will allow PCI IOMMU support to
>>> be added in one place, rather than updating every PCI driver at that
>>> time.
>>>
>>> That is, it allows us to update individual PCI drivers to support an
>>> IOMMU
>>> without having yet determined the details of how the IOMMU emulation
>>> will
>>> operate. This will let us remove the most bitrot-sensitive part of an
>>> IOMMU patch in advance.
>>>
>>> Signed-off-by: David Gibson<david@gibson.dropbear.id.au>
>>
>> I think this is the wrong approach given the introduction of the
>> memory API.
>>
>> I think we should have a generic memory access function that takes a
>> MemoryRegion as it's first argument.
>>
>> The PCI bus should then expose one memory region for each device
>> (that's how it can figure out where the access is coming from).
>>
>> Richard/Avi, what do you think?
>>
>
> I think the patchset is fine. It routes all access through pci_dma_rw(),
> which accepts a PCIDevice. We can later define pci_dma_rw() in terms of
> the memory API and get the benefit of the memory hierarchy.

The challenge is what you do about something like ne2k where the core 
chipset can either be a PCI device or an ISA device.  You would have to 
implement a wrapper around pci_dma_rw() in order to turn it into 
cpu_physical_memory_rw when doing ISA.

Regards,

Anthony Liguori

>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-01 16:05       ` Anthony Liguori
@ 2011-09-01 16:11         ` Avi Kivity
  2011-09-01 16:32           ` Anthony Liguori
  2011-09-02  0:38         ` David Gibson
  2011-09-02  8:37         ` Avi Kivity
  2 siblings, 1 reply; 34+ messages in thread
From: Avi Kivity @ 2011-09-01 16:11 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Anthony Liguori, joerg.roedel, agraf, qemu-devel,
	eduard.munteanu, rth, David Gibson

On 09/01/2011 07:05 PM, Anthony Liguori wrote:
>> I think the patchset is fine. It routes all access through pci_dma_rw(),
>> which accepts a PCIDevice. We can later define pci_dma_rw() in terms of
>> the memory API and get the benefit of the memory hierarchy.
>
>
> The challenge is what you do about something like ne2k where the core 
> chipset can either be a PCI device or an ISA device.  You would have 
> to implement a wrapper around pci_dma_rw() in order to turn it into 
> cpu_physical_memory_rw when doing ISA.
>

True.  But I still think it's the right thing.

We can't really pass a MemoryRegion as the source address, since there 
is no per-device MemoryRegion.  We can use pci_address_space() for basic 
offsetting, and for bypassing bridge windows, but iommu source detection 
has to use the PCIDevice directly.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-01 16:11         ` Avi Kivity
@ 2011-09-01 16:32           ` Anthony Liguori
  2011-09-02  8:35             ` Avi Kivity
  0 siblings, 1 reply; 34+ messages in thread
From: Anthony Liguori @ 2011-09-01 16:32 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Anthony Liguori, joerg.roedel, agraf, qemu-devel,
	eduard.munteanu, David Gibson, rth

On 09/01/2011 11:11 AM, Avi Kivity wrote:
> On 09/01/2011 07:05 PM, Anthony Liguori wrote:
>>> I think the patchset is fine. It routes all access through pci_dma_rw(),
>>> which accepts a PCIDevice. We can later define pci_dma_rw() in terms of
>>> the memory API and get the benefit of the memory hierarchy.
>>
>>
>> The challenge is what you do about something like ne2k where the core
>> chipset can either be a PCI device or an ISA device. You would have to
>> implement a wrapper around pci_dma_rw() in order to turn it into
>> cpu_physical_memory_rw when doing ISA.
>>
>
> True. But I still think it's the right thing.
>
> We can't really pass a MemoryRegion as the source address, since there
> is no per-device MemoryRegion.

Couldn't the PCI bus expose 255 MemoryRegions though?  It could still 
use the pci_address_space I think since that should include RAM too, right?

In fact, initially, you could have a 
pci_bus_get_device_memory_region(bus, dev) that just returns 
pci_address_space().

You just need the memory_st[bwl] functions I think.

Regards,

Anthony Liguori

  We can use pci_address_space() for basic
> offsetting, and for bypassing bridge windows, but iommu source detection
> has to use the PCIDevice directly.
>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits
  2011-09-01 11:33 ` [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits Eduard - Gabriel Munteanu
@ 2011-09-02  0:36   ` David Gibson
  0 siblings, 0 replies; 34+ messages in thread
From: David Gibson @ 2011-09-02  0:36 UTC (permalink / raw)
  To: Eduard - Gabriel Munteanu; +Cc: agraf, aliguori, qemu-devel, joerg.roedel, rth

On Thu, Sep 01, 2011 at 02:33:41PM +0300, Eduard - Gabriel Munteanu wrote:
> On Thu, Sep 01, 2011 at 03:00:53PM +1000, David Gibson wrote:
> > A while back, Eduard - Gabriel Munteanu send a series of patches
> > implementing support for emulating the AMD IOMMU in conjunction with
> > qemu emulated PCI devices.  A revised patch series added support for
> > the Intel IOMMU, and I also send a revised version of this series
> > which added support for the hypervisor mediated IOMMU on the pseries
> > machine.
> > 
> > Richard Henderson also weighed in on the discussion, and there's still
> > a fair bit to be thrashed out in terms of exactly how to set up an
> > IOMMU / DMA translation subsystem.
> > 
> > However, really only 2 or 3 patches in any of these series have
> > contained anything interesting.  The rest of the series has been
> > converting existing PCI emulated devices to use the new DMA interface
> > which worked through the IOMMU translation, whatever it was.  While we
> > keep working out what we want for the guts of the IOMMU support, these
> > device conversion patches keep bitrotting against updates to the
> > various device implementations themselves.
> 
> Hi,
> 
> This sounds like a good idea. We should be able to agree on these bits,
> at least, and get them merged.
> 
> > Really, regardless of whether we're actually implementing IOMMU
> > translation, it makes sense that qemu code should distinguish between
> > when it is really operating in CPU physical addresses and when it is
> > operating in bus or DMA addresses which might have some kind of
> > translation into physical addresses.
> > 
> > This series, therefore, begins the conversion of existing PCI device
> > emulation code to use new (stub) pci dma access functions.  These are
> > for now, just defined to be untranslated cpu physical memory accesses,
> > as before, but has two advantages:
> > 
> >    * It becomes obvious where the code is working with dma addresses,
> >      so it's easier to grep for what might be affected by an IOMMU or
> >      other bus address translation.
> > 
> >    * The new stubs take the PCIDevice *, from which any of the various
> >      suggested IOMMU interfaces should be able to locate the correct
> >      IOMMU translation context.
> > 
> > This series only converts the easy cases so far.  That is simple
> > direct DMA access from device code:
> > cpu_physical_memory_{read,write}(), ld*_phys() and st*_phys().  It
> > doesn't handle devices which use the scatter/gather code (just ide and
> > UHCI, so far).  I plan to address that later, but I have some details
> > still to work out.
> 
> I think AHCI belongs on that list too, my patches didn't handle it
> either.

Ah, yes.  I was lumping that in with IDE.

> Somewhere down the road we could try to poison the old cpu_*
> interfaces, as suggested by others before.
> 
> > Anthony, please apply.
> 
> It's nice to see this topic got revived. I'll try to post my latest
> SeaBIOS patches these days. The reason I didn't last time was I didn't
> get much review/acks/naks on the IOMMU patches from core devs. Hopefully
> things will go smoother this time.
> 
> 
> 	Cheers,
> 	Eduard
> 

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-01 16:05       ` Anthony Liguori
  2011-09-01 16:11         ` Avi Kivity
@ 2011-09-02  0:38         ` David Gibson
  2011-09-02  8:37         ` Avi Kivity
  2 siblings, 0 replies; 34+ messages in thread
From: David Gibson @ 2011-09-02  0:38 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Anthony Liguori, joerg.roedel, qemu-devel, agraf, Avi Kivity,
	eduard.munteanu, rth

On Thu, Sep 01, 2011 at 11:05:48AM -0500, Anthony Liguori wrote:
> On 09/01/2011 11:03 AM, Avi Kivity wrote:
> >On 09/01/2011 06:55 PM, Anthony Liguori wrote:
> >>On 09/01/2011 12:00 AM, David Gibson wrote:
[snip]
> The challenge is what you do about something like ne2k where the
> core chipset can either be a PCI device or an ISA device.  You would
> have to implement a wrapper around pci_dma_rw() in order to turn it
> into cpu_physical_memory_rw when doing ISA.

That would be one of the less-easy cases I'm still thinking about...

I don't think it invalidates this patchset, though.


-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-01 15:35   ` Michael S. Tsirkin
@ 2011-09-02  0:39     ` David Gibson
  2011-09-02  4:38     ` David Gibson
  1 sibling, 0 replies; 34+ messages in thread
From: David Gibson @ 2011-09-02  0:39 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: aliguori, joerg.roedel, qemu-devel, agraf, eduard.munteanu, rth

On Thu, Sep 01, 2011 at 06:35:51PM +0300, Michael S. Tsirkin wrote:
> On Thu, Sep 01, 2011 at 03:00:54PM +1000, David Gibson wrote:
[snip]
> > +DECLARE_LDST_DMA(ub, b, 8);
> > +DECLARE_LDST_DMA(uw, w, 16);
> > +DECLARE_LDST_DMA(l, l, 32);
> > +DECLARE_LDST_DMA(q, q, 64);
> > +
> > +#undef DECLARE_LDST_DMA
> > +
> >  #endif
> 
> I'd prefer the stubs to be inline. Not just as an optimization:
> it also makes it easier to grok what goes on in the common
> no-iommu case.

So would I, but that doesn't work because of the poisonong of the phys
access functions.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 10/10] intel-hda: Use PCI DMA stub functions
  2011-09-01 10:16   ` Gerd Hoffmann
@ 2011-09-02  1:42     ` David Gibson
  0 siblings, 0 replies; 34+ messages in thread
From: David Gibson @ 2011-09-02  1:42 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: aliguori, joerg.roedel, qemu-devel, agraf, eduard.munteanu, rth

On Thu, Sep 01, 2011 at 12:16:25PM +0200, Gerd Hoffmann wrote:
> On 09/01/11 07:01, David Gibson wrote:
> >This updates the intel-hda device emulation to use the explicit PCI DMA
> >functions, instead of directly calling physical memory access functions.
> 
> There are some calls to {st,ld}l_le_phys() which need conversion
> too.

Ah, thanks for pointing those out.  I'll fold the fix into the next
iteration of my patchset.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 09/10] usb-ohci: Use PCI DMA stub functions
  2011-09-01 10:10   ` Gerd Hoffmann
@ 2011-09-02  1:47     ` David Gibson
  0 siblings, 0 replies; 34+ messages in thread
From: David Gibson @ 2011-09-02  1:47 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: aliguori, joerg.roedel, qemu-devel, agraf, eduard.munteanu, rth

On Thu, Sep 01, 2011 at 12:10:48PM +0200, Gerd Hoffmann wrote:
> On 09/01/11 07:01, David Gibson wrote:
> >From: Eduard - Gabriel Munteanu<eduard.munteanu@linux360.ro>
> >
> >This updates the usb-ohci device emulation to use the explicit PCI DMA
> >functions, instead of directly calling physical memory access functions.
> 
> It isn't that simple.
> 
> There are non-PCI ohci devices which I think you break with this
> patch.

Ah, good point.  I'll remove the OHCI patch from the next iteration of
this series, and fix it properly later with some of the other harder
cases like ne2k.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-01 15:35   ` Michael S. Tsirkin
  2011-09-02  0:39     ` David Gibson
@ 2011-09-02  4:38     ` David Gibson
  2011-09-05  7:55       ` Michael S. Tsirkin
  1 sibling, 1 reply; 34+ messages in thread
From: David Gibson @ 2011-09-02  4:38 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: aliguori, joerg.roedel, qemu-devel, agraf, eduard.munteanu, rth

On Thu, Sep 01, 2011 at 06:35:51PM +0300, Michael S. Tsirkin wrote:
> On Thu, Sep 01, 2011 at 03:00:54PM +1000, David Gibson wrote:
[snip]
> > +#define DECLARE_LDST_DMA(_lname, _sname, _bits) \
> > +    uint##_bits##_t ld##_lname##_pci_dma(PCIDevice *dev, dma_addr_t addr); \
> > +    void st##_sname##_pci_dma(PCIDevice *dev, dma_addr_t addr, \
> > +                              uint##_bits##_t val);            \
> 
> prefix macros with PCI_ please.

Corrected for the next spin.

> > +DECLARE_LDST_DMA(ub, b, 8);
> > +DECLARE_LDST_DMA(uw, w, 16);
> > +DECLARE_LDST_DMA(l, l, 32);
> > +DECLARE_LDST_DMA(q, q, 64);
> > +
> > +#undef DECLARE_LDST_DMA
> > +
> >  #endif
> 
> I'd prefer the stubs to be inline. Not just as an optimization:
> it also makes it easier to grok what goes on in the common
> no-iommu case.

To elaborate on my earlier mail.  The problem with making them inlines
is that the cpu_physical_*() functions then appear in pci.h, which is
used in pci.c amongst other places that are included in
libhw32/libhw64, where those functions are poisoned.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-01 16:03     ` Avi Kivity
  2011-09-01 16:05       ` Anthony Liguori
@ 2011-09-02  4:40       ` David Gibson
  1 sibling, 0 replies; 34+ messages in thread
From: David Gibson @ 2011-09-02  4:40 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Anthony Liguori, joerg.roedel, agraf, qemu-devel, eduard.munteanu, rth

On Thu, Sep 01, 2011 at 07:03:34PM +0300, Avi Kivity wrote:
> On 09/01/2011 06:55 PM, Anthony Liguori wrote:
> >On 09/01/2011 12:00 AM, David Gibson wrote:
> >>This patch adds functions to pci.[ch] to perform PCI DMA operations.  At
> >>present, these are just stubs which perform directly cpu physical memory
> >>accesses.
> >>
> >>Using these stubs, however, distinguishes PCI device DMA
> >>transactions from
> >>other accesses to physical memory, which will allow PCI IOMMU support to
> >>be added in one place, rather than updating every PCI driver at
> >>that time.
> >>
> >>That is, it allows us to update individual PCI drivers to
> >>support an IOMMU
> >>without having yet determined the details of how the IOMMU
> >>emulation will
> >>operate.  This will let us remove the most bitrot-sensitive part of an
> >>IOMMU patch in advance.
> >>
> >>Signed-off-by: David Gibson<david@gibson.dropbear.id.au>
> >
> >I think this is the wrong approach given the introduction of the
> >memory API.
> >
> >I think we should have a generic memory access function that takes
> >a MemoryRegion as it's first argument.
> >
> >The PCI bus should then expose one memory region for each device
> >(that's how it can figure out where the access is coming from).
> >
> >Richard/Avi, what do you think?
> 
> I think the patchset is fine.  It routes all access through
> pci_dma_rw(), which accepts a PCIDevice.  We can later define
> pci_dma_rw() in terms of the memory API and get the benefit of the
> memory hierarchy.

Right.  Exactly what to use as a handle on the right bus / DMA
addressing context is something still to be thrashed out - a
MemoryRegion may well be the right answer.

But whatever we do there, a convenience wrapper would be useful for
the common case of PCI devices - certainly the correct addressing
context should be reachable from the PCI device.

This approach means we can get most of the PCI drivers IOMMU ready
now, and we just need fix the final IOMMU support in one place,
instead of in every PCI driver.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-01 16:32           ` Anthony Liguori
@ 2011-09-02  8:35             ` Avi Kivity
  2011-09-03 12:25               ` Blue Swirl
  0 siblings, 1 reply; 34+ messages in thread
From: Avi Kivity @ 2011-09-02  8:35 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Anthony Liguori, joerg.roedel, agraf, qemu-devel,
	eduard.munteanu, David Gibson, rth

On 09/01/2011 07:32 PM, Anthony Liguori wrote:
>> True. But I still think it's the right thing.
>>
>> We can't really pass a MemoryRegion as the source address, since there
>> is no per-device MemoryRegion.
>
>
> Couldn't the PCI bus expose 255 MemoryRegions though? 

What would those mean?  A MemoryRegion is something that can respond to 
reads and writes.

> It could still use the pci_address_space I think since that should 
> include RAM too, right?
>

No.

> In fact, initially, you could have a 
> pci_bus_get_device_memory_region(bus, dev) that just returns 
> pci_address_space().
>
> You just need the memory_st[bwl] functions I think.
>

Maybe we need a different type of object here - MemoryClient or something.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-01 16:05       ` Anthony Liguori
  2011-09-01 16:11         ` Avi Kivity
  2011-09-02  0:38         ` David Gibson
@ 2011-09-02  8:37         ` Avi Kivity
  2011-09-03  3:04           ` Eduard - Gabriel Munteanu
  2 siblings, 1 reply; 34+ messages in thread
From: Avi Kivity @ 2011-09-02  8:37 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: Anthony Liguori, joerg.roedel, agraf, qemu-devel,
	eduard.munteanu, rth, David Gibson

On 09/01/2011 07:05 PM, Anthony Liguori wrote:
>
> The challenge is what you do about something like ne2k where the core 
> chipset can either be a PCI device or an ISA device.  You would have 
> to implement a wrapper around pci_dma_rw() in order to turn it into 
> cpu_physical_memory_rw when doing ISA.

btw, ISA DMA is very different, no?  You program a dma controller to 
copy memory from the device to RAM (or vice versa); the device never 
initiates a transaction IIRC.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-01 15:55   ` Anthony Liguori
  2011-09-01 16:03     ` Avi Kivity
@ 2011-09-03  1:16     ` Richard Henderson
  1 sibling, 0 replies; 34+ messages in thread
From: Richard Henderson @ 2011-09-03  1:16 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: joerg.roedel, agraf, qemu-devel, Avi Kivity, eduard.munteanu,
	David Gibson

On 09/01/2011 09:25 PM, Anthony Liguori wrote:
> I think this is the wrong approach given the introduction of the memory API.
> 
> I think we should have a generic memory access function that takes a MemoryRegion as it's first argument.
> 
> The PCI bus should then expose one memory region for each device (that's how it can figure out where the access is coming from).

A MemoryRegion is the wrong abstraction for the device's view back into system memory.
The new memory API really has nothing to do with DMA or an IOMMU.  Think about it:
99.999% of the time we're writing to the one MemoryRegion that is RAM (with the other
remaining fraction being pci-pci dma tricks), except in a non-contiguous manner.
Obviously we need something else to represent the non-contiguous-ness.

I suppose you could abuse Avi's AddressSpace, with hundreds of MemoryRegion aliases,
but that would be a horrible interface to actually use in this situation.

I think David's patch is fine, as far as it goes for the majority of the PCI-only 
devices that we emulate.  As for the devices attached to more than one bus, they'll
just have to wait until we actually hash out the underlying dma api.


r~

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-02  8:37         ` Avi Kivity
@ 2011-09-03  3:04           ` Eduard - Gabriel Munteanu
  0 siblings, 0 replies; 34+ messages in thread
From: Eduard - Gabriel Munteanu @ 2011-09-03  3:04 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Anthony Liguori, joerg.roedel, agraf, qemu-devel, rth, David Gibson

On Fri, Sep 02, 2011 at 11:37:25AM +0300, Avi Kivity wrote:
> On 09/01/2011 07:05 PM, Anthony Liguori wrote:
> >
> > The challenge is what you do about something like ne2k where the core 
> > chipset can either be a PCI device or an ISA device.  You would have 
> > to implement a wrapper around pci_dma_rw() in order to turn it into 
> > cpu_physical_memory_rw when doing ISA.
> 
> btw, ISA DMA is very different, no?  You program a dma controller to 
> copy memory from the device to RAM (or vice versa); the device never 
> initiates a transaction IIRC.

It seems to me ISA devices should use memory I/O primitives exposed by
the ISA bus code. Or maybe the DMA controllers involved should be doing
that. As for either-PCI/ISA devices, they can handle dispatching DMA
through the right interface themselves.

Anyway, I'm not sure why we're worrying about this now. Do we even have
IOMMUs for such use cases?


	Eduard

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-02  8:35             ` Avi Kivity
@ 2011-09-03 12:25               ` Blue Swirl
  0 siblings, 0 replies; 34+ messages in thread
From: Blue Swirl @ 2011-09-03 12:25 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Anthony Liguori, joerg.roedel, agraf, qemu-devel,
	eduard.munteanu, rth, David Gibson

On Fri, Sep 2, 2011 at 8:35 AM, Avi Kivity <avi@redhat.com> wrote:
> On 09/01/2011 07:32 PM, Anthony Liguori wrote:
>>>
>>> True. But I still think it's the right thing.
>>>
>>> We can't really pass a MemoryRegion as the source address, since there
>>> is no per-device MemoryRegion.
>>
>>
>> Couldn't the PCI bus expose 255 MemoryRegions though?
>
> What would those mean?  A MemoryRegion is something that can respond to
> reads and writes.

If I understand Anthony's idea, the MemoryRegion (one of 255 in this
case) would identify the device in bus agnostic (even PIO vs. MMIO)
way. In the numerous previously failed attempts to manage generic DMA,
the upstream handle was either an opaque pointer, bus specific
structure or IOMMU handle, but this is much better. From the device
MemoryRegion, the bus should be discoverable and then the bus can
resolve the chain back to host RAM with similar logic to perform the
DMA via IOMMUs or whatever strange buses or devices are involved in
between. Awesome!

>> It could still use the pci_address_space I think since that should include
>> RAM too, right?
>>
>
> No.
>
>> In fact, initially, you could have a pci_bus_get_device_memory_region(bus,
>> dev) that just returns pci_address_space().
>>
>> You just need the memory_st[bwl] functions I think.
>>
>
> Maybe we need a different type of object here - MemoryClient or something.
>
> --
> I have a truly marvellous patch that fixes the bug which this
> signature is too narrow to contain.
>
>
>

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-02  4:38     ` David Gibson
@ 2011-09-05  7:55       ` Michael S. Tsirkin
  0 siblings, 0 replies; 34+ messages in thread
From: Michael S. Tsirkin @ 2011-09-05  7:55 UTC (permalink / raw)
  To: qemu-devel, joerg.roedel, aliguori, rth, agraf, eduard.munteanu

On Fri, Sep 02, 2011 at 02:38:25PM +1000, David Gibson wrote:
> > I'd prefer the stubs to be inline. Not just as an optimization:
> > it also makes it easier to grok what goes on in the common
> > no-iommu case.
> 
> To elaborate on my earlier mail.  The problem with making them inlines
> is that the cpu_physical_*() functions then appear in pci.h, which is
> used in pci.c amongst other places that are included in
> libhw32/libhw64, where those functions are poisoned.

Hmm, how are they poisoned?
I thought almost all devices currently use cpu_physical_*()?
For example, e1000 uses cpu_physical_memory_write and
it seems to get included in libhw32/libhw64 without issues.


> -- 
> David Gibson			| I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
> 				| _way_ _around_!
> http://www.ozlabs.org/~dgibson

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA
  2011-09-01  5:00 ` [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA David Gibson
  2011-09-01 15:35   ` Michael S. Tsirkin
  2011-09-01 15:55   ` Anthony Liguori
@ 2011-09-23 16:37   ` Anthony Liguori
  2 siblings, 0 replies; 34+ messages in thread
From: Anthony Liguori @ 2011-09-23 16:37 UTC (permalink / raw)
  To: David Gibson; +Cc: joerg.roedel, agraf, eduard.munteanu, qemu-devel, rth

On 09/01/2011 12:00 AM, David Gibson wrote:
> This patch adds functions to pci.[ch] to perform PCI DMA operations.  At
> present, these are just stubs which perform directly cpu physical memory
> accesses.
>
> Using these stubs, however, distinguishes PCI device DMA transactions from
> other accesses to physical memory, which will allow PCI IOMMU support to
> be added in one place, rather than updating every PCI driver at that time.
>
> That is, it allows us to update individual PCI drivers to support an IOMMU
> without having yet determined the details of how the IOMMU emulation will
> operate.  This will let us remove the most bitrot-sensitive part of an
> IOMMU patch in advance.
>
> Signed-off-by: David Gibson<david@gibson.dropbear.id.au>

Please include wrappers for cpu_physical_memory_map/unmap and I'll apply.

Regards,

Anthony Liguori

> ---
>   dma.h    |    2 ++
>   hw/pci.c |   31 +++++++++++++++++++++++++++++++
>   hw/pci.h |   33 +++++++++++++++++++++++++++++++++
>   3 files changed, 66 insertions(+), 0 deletions(-)
>
> diff --git a/dma.h b/dma.h
> index a6db5ba..06e91cb 100644
> --- a/dma.h
> +++ b/dma.h
> @@ -15,6 +15,8 @@
>   #include "hw/hw.h"
>   #include "block.h"
>
> +typedef target_phys_addr_t dma_addr_t;
> +
>   typedef struct {
>       target_phys_addr_t base;
>       target_phys_addr_t len;
> diff --git a/hw/pci.c b/hw/pci.c
> index 1cdcbb7..842b066 100644
> --- a/hw/pci.c
> +++ b/hw/pci.c
> @@ -2211,3 +2211,34 @@ MemoryRegion *pci_address_space(PCIDevice *dev)
>   {
>       return dev->bus->address_space_mem;
>   }
> +
> +#define DEFINE_LDST_DMA(_lname, _sname, _bits) \
> +    uint##_bits##_t ld##_lname##_pci_dma(PCIDevice *dev, dma_addr_t addr) \
> +    { \
> +        uint##_bits##_t val; \
> +        pci_dma_read(dev, addr,&val, sizeof(val)); \
> +        return le##_bits##_to_cpu(val); \
> +    } \
> +    void st##_sname##_pci_dma(PCIDevice *dev, \
> +                              dma_addr_t addr, uint##_bits##_t val) \
> +    { \
> +        val = cpu_to_le##_bits(val); \
> +        pci_dma_write(dev, addr,&val, sizeof(val)); \
> +    }
> +
> +uint8_t ldub_pci_dma(PCIDevice *dev, dma_addr_t addr)
> +{
> +    uint8_t val;
> +
> +    pci_dma_read(dev, addr,&val, sizeof(val));
> +    return val;
> +}
> +
> +void stb_pci_dma(PCIDevice *dev, dma_addr_t addr, uint8_t val)
> +{
> +    pci_dma_write(dev, addr,&val, sizeof(val));
> +}
> +
> +DEFINE_LDST_DMA(uw, w, 16);
> +DEFINE_LDST_DMA(l, l, 32);
> +DEFINE_LDST_DMA(q, q, 64);
> diff --git a/hw/pci.h b/hw/pci.h
> index 391217e..401d14a 100644
> --- a/hw/pci.h
> +++ b/hw/pci.h
> @@ -6,6 +6,7 @@
>
>   #include "qdev.h"
>   #include "memory.h"
> +#include "dma.h"
>
>   /* PCI includes legacy ISA access.  */
>   #include "isa.h"
> @@ -492,4 +493,36 @@ static inline uint32_t pci_config_size(const PCIDevice *d)
>       return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE;
>   }
>
> +/* DMA access functions */
> +static inline int pci_dma_rw(PCIDevice *dev, dma_addr_t addr,
> +                             void *buf, dma_addr_t len, int is_write)
> +{
> +    cpu_physical_memory_rw(addr, buf, len, is_write);
> +    return 0;
> +}
> +
> +static inline int pci_dma_read(PCIDevice *dev, dma_addr_t addr,
> +                               void *buf, dma_addr_t len)
> +{
> +    return pci_dma_rw(dev, addr, buf, len, 0);
> +}
> +
> +static inline int pci_dma_write(PCIDevice *dev, dma_addr_t addr,
> +                                const void *buf, dma_addr_t len)
> +{
> +    return pci_dma_rw(dev, addr, (void *) buf, len, 1);
> +}
> +
> +#define DECLARE_LDST_DMA(_lname, _sname, _bits) \
> +    uint##_bits##_t ld##_lname##_pci_dma(PCIDevice *dev, dma_addr_t addr); \
> +    void st##_sname##_pci_dma(PCIDevice *dev, dma_addr_t addr, \
> +                              uint##_bits##_t val);            \
> +
> +DECLARE_LDST_DMA(ub, b, 8);
> +DECLARE_LDST_DMA(uw, w, 16);
> +DECLARE_LDST_DMA(l, l, 32);
> +DECLARE_LDST_DMA(q, q, 64);
> +
> +#undef DECLARE_LDST_DMA
> +
>   #endif

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2011-09-23 16:37 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-01  5:00 [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits David Gibson
2011-09-01  5:00 ` [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA David Gibson
2011-09-01 15:35   ` Michael S. Tsirkin
2011-09-02  0:39     ` David Gibson
2011-09-02  4:38     ` David Gibson
2011-09-05  7:55       ` Michael S. Tsirkin
2011-09-01 15:55   ` Anthony Liguori
2011-09-01 16:03     ` Avi Kivity
2011-09-01 16:05       ` Anthony Liguori
2011-09-01 16:11         ` Avi Kivity
2011-09-01 16:32           ` Anthony Liguori
2011-09-02  8:35             ` Avi Kivity
2011-09-03 12:25               ` Blue Swirl
2011-09-02  0:38         ` David Gibson
2011-09-02  8:37         ` Avi Kivity
2011-09-03  3:04           ` Eduard - Gabriel Munteanu
2011-09-02  4:40       ` David Gibson
2011-09-03  1:16     ` Richard Henderson
2011-09-23 16:37   ` Anthony Liguori
2011-09-01  5:00 ` [Qemu-devel] [PATCH 02/10] rtl8139: Use PCI DMA stub functions David Gibson
2011-09-01  5:00 ` [Qemu-devel] [PATCH 03/10] eepro100: " David Gibson
2011-09-01  5:00 ` [Qemu-devel] [PATCH 04/10] ac97: " David Gibson
2011-09-01  5:00 ` [Qemu-devel] [PATCH 05/10] es1370: " David Gibson
2011-09-01  5:00 ` [Qemu-devel] [PATCH 06/10] e1000: " David Gibson
2011-09-01  5:01 ` [Qemu-devel] [PATCH 07/10] lsi53c895a: " David Gibson
2011-09-01  5:01 ` [Qemu-devel] [PATCH 08/10] pcnet-pci: " David Gibson
2011-09-01  5:01 ` [Qemu-devel] [PATCH 09/10] usb-ohci: " David Gibson
2011-09-01 10:10   ` Gerd Hoffmann
2011-09-02  1:47     ` David Gibson
2011-09-01  5:01 ` [Qemu-devel] [PATCH 10/10] intel-hda: " David Gibson
2011-09-01 10:16   ` Gerd Hoffmann
2011-09-02  1:42     ` David Gibson
2011-09-01 11:33 ` [Qemu-devel] [0/10] Preliminary work for IOMMU emulation support; the easy bits Eduard - Gabriel Munteanu
2011-09-02  0:36   ` David Gibson

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.