From patchwork Thu Sep 1 05:00:54 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 112795 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B0601B6F9D for ; Thu, 1 Sep 2011 15:01:31 +1000 (EST) Received: from localhost ([::1]:34428 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QyzP6-0006LP-9R for incoming@patchwork.ozlabs.org; Thu, 01 Sep 2011 01:01:28 -0400 Received: from eggs.gnu.org ([140.186.70.92]:42631) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QyzOy-0006Ky-HI for qemu-devel@nongnu.org; Thu, 01 Sep 2011 01:01:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QyzOw-0000Za-5i for qemu-devel@nongnu.org; Thu, 01 Sep 2011 01:01:20 -0400 Received: from ozlabs.org ([203.10.76.45]:45316) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QyzOv-0000XZ-Jq for qemu-devel@nongnu.org; Thu, 01 Sep 2011 01:01:18 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 9F767B6F7F; Thu, 1 Sep 2011 15:01:14 +1000 (EST) From: David Gibson To: qemu-devel@nongnu.org Date: Thu, 1 Sep 2011 15:00:54 +1000 Message-Id: <1314853263-2086-2-git-send-email-david@gibson.dropbear.id.au> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1314853263-2086-1-git-send-email-david@gibson.dropbear.id.au> References: <1314853263-2086-1-git-send-email-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 203.10.76.45 Cc: joerg.roedel@amd.com, aliguori@us.ibm.com, rth@twiddle.net, agraf@suse.de, eduard.munteanu@linux360.ro Subject: [Qemu-devel] [PATCH 01/10] Add stub functions for PCI device models to do PCI DMA X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- 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