From patchwork Fri Mar 9 05:01:48 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 145666 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 9A1D6B6FB6 for ; Fri, 9 Mar 2012 17:06:12 +1100 (EST) Received: from localhost ([::1]:33642 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S5rzY-0002a8-5u for incoming@patchwork.ozlabs.org; Fri, 09 Mar 2012 00:03:48 -0500 Received: from eggs.gnu.org ([208.118.235.92]:58549) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S5ryJ-0000bQ-8A for qemu-devel@nongnu.org; Fri, 09 Mar 2012 00:02:35 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S5rxy-0000Ge-Re for qemu-devel@nongnu.org; Fri, 09 Mar 2012 00:02:30 -0500 Received: from ozlabs.org ([203.10.76.45]:38677) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S5rxy-0000FS-9c for qemu-devel@nongnu.org; Fri, 09 Mar 2012 00:02:10 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 18C6EB6FD7; Fri, 9 Mar 2012 16:02:07 +1100 (EST) From: David Gibson To: qemu-devel@nongnu.org Date: Fri, 9 Mar 2012 16:01:48 +1100 Message-Id: <1331269308-22372-14-git-send-email-david@gibson.dropbear.id.au> X-Mailer: git-send-email 1.7.9.1 In-Reply-To: <1331269308-22372-1-git-send-email-david@gibson.dropbear.id.au> References: <1331269308-22372-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: rth@twiddle.net, mst@redhat.com, agraf@suse.de, David Gibson , eduard.munteanu@linux360.ro Subject: [Qemu-devel] [PATCH 13/13] pseries: Implement IOMMU and DMA for PAPR PCI devices 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 Currently the pseries machine emulation does not support DMA for emulated PCI devices, because the PAPR spec always requires a (guest visible, paravirtualized) IOMMU which was not implemented. Now that we have infrastructure for IOMMU emulation, we can correct this and allow PCI DMA for pseries. With the existing PAPR IOMMU code used for VIO devices, this is almost trivial. We use a single DMAContext for each (virtual) PCI host bridge, which is the usual configuration on real PAPR machines (which often have _many_ PCI host bridges). Cc: Alex Graf Signed-off-by: David Gibson --- hw/spapr.h | 1 + hw/spapr_pci.c | 15 +++++++++++++++ hw/spapr_pci.h | 1 + 3 files changed, 17 insertions(+), 0 deletions(-) diff --git a/hw/spapr.h b/hw/spapr.h index 210b868..00b15c8 100644 --- a/hw/spapr.h +++ b/hw/spapr.h @@ -328,6 +328,7 @@ typedef struct sPAPRTCE { } sPAPRTCE; #define SPAPR_VIO_BASE_LIOBN 0x00000000 +#define SPAPR_PCI_BASE_LIOBN 0x80000000 void spapr_iommu_init(void); DMAContext *spapr_tce_new_dma_context(uint32_t liobn, size_t window_size); diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 523227b..b53fd40 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -201,6 +201,14 @@ static MemoryRegionOps spapr_io_ops = { /* * PHB PCI device */ +static DMAContext *spapr_pci_dma_context_fn(PCIBus *bus, void *opaque, + int devfn) +{ + sPAPRPHBState *phb = opaque; + + return phb->dma; +} + static int spapr_phb_init(SysBusDevice *s) { sPAPRPHBState *phb = FROM_SYSBUS(sPAPRPHBState, s); @@ -208,6 +216,7 @@ static int spapr_phb_init(SysBusDevice *s) char namebuf[64]; int i; PCIBus *bus; + uint32_t liobn; sprintf(busname, "pci@%" PRIx64, phb->buid); @@ -248,6 +257,10 @@ static int spapr_phb_init(SysBusDevice *s) PCI_DEVFN(0, 0), SPAPR_PCI_NUM_LSI); + liobn = SPAPR_PCI_BASE_LIOBN | (pci_find_domain(bus) << 16); + phb->dma = spapr_tce_new_dma_context(liobn, 0x40000000); + pci_setup_iommu(bus, spapr_pci_dma_context_fn, phb); + QLIST_INSERT_HEAD(&spapr->phbs, phb, list); /* Initialize the LSI table */ @@ -400,6 +413,8 @@ int spapr_populate_pci_devices(sPAPRPHBState *phb, _FDT(fdt_setprop(fdt, bus_off, "interrupt-map", &interrupt_map, 7 * sizeof(interrupt_map[0]))); + spapr_dma_dt(fdt, bus_off, "ibm,dma-window", phb->dma); + return 0; } diff --git a/hw/spapr_pci.h b/hw/spapr_pci.h index b4b8a73..365c75e 100644 --- a/hw/spapr_pci.h +++ b/hw/spapr_pci.h @@ -37,6 +37,7 @@ typedef struct sPAPRPHBState { MemoryRegion memspace, iospace; target_phys_addr_t mem_win_addr, mem_win_size, io_win_addr, io_win_size; MemoryRegion memwindow, iowindow; + DMAContext *dma; struct { uint32_t dt_irq;