From patchwork Sun Jul 31 17:57:35 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Avi Kivity X-Patchwork-Id: 107639 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 350CEB6F98 for ; Mon, 1 Aug 2011 05:58:40 +1000 (EST) Received: from localhost ([::1]:50261 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QnaIC-0007AT-Ev for incoming@patchwork.ozlabs.org; Sun, 31 Jul 2011 13:59:12 -0400 Received: from eggs.gnu.org ([140.186.70.92]:50266) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QnaHH-0004yW-AX for qemu-devel@nongnu.org; Sun, 31 Jul 2011 13:58:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QnaHC-0007e9-61 for qemu-devel@nongnu.org; Sun, 31 Jul 2011 13:58:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:35187) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QnaHB-0007dC-Qm for qemu-devel@nongnu.org; Sun, 31 Jul 2011 13:58:10 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p6VHw8cc025691 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 31 Jul 2011 13:58:08 -0400 Received: from cleopatra.tlv.redhat.com (cleopatra.tlv.redhat.com [10.35.255.11]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p6VHw7d6019823; Sun, 31 Jul 2011 13:58:07 -0400 Received: from s01.tlv.redhat.com (s01.tlv.redhat.com [10.35.255.8]) by cleopatra.tlv.redhat.com (Postfix) with ESMTP id AD0F6250B41; Sun, 31 Jul 2011 20:58:04 +0300 (IDT) From: Avi Kivity To: Anthony Liguori , qemu-devel@nongnu.org Date: Sun, 31 Jul 2011 20:57:35 +0300 Message-Id: <1312135082-31985-13-git-send-email-avi@redhat.com> In-Reply-To: <1312135082-31985-1-git-send-email-avi@redhat.com> References: <1312135082-31985-1-git-send-email-avi@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: kvm@vger.kernel.org, "Michael S. Tsirkin" Subject: [Qemu-devel] [PATCH 12/39] pci: allow I/O BARs to be registered with pci_register_bar_region() 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 Signed-off-by: Avi Kivity --- hw/pci.c | 43 +++++++++++++++++++++++-------------------- hw/pci.h | 1 + hw/pci_internals.h | 3 ++- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index 2659d96..980840f 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -271,7 +271,8 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent, qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name); assert(PCI_FUNC(devfn_min) == 0); bus->devfn_min = devfn_min; - bus->address_space = address_space_mem; + bus->address_space_mem = address_space_mem; + bus->address_space_io = address_space_io; /* host bridge */ QLIST_INIT(&bus->child); @@ -847,12 +848,11 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev) r = &pci_dev->io_regions[i]; if (!r->size || r->addr == PCI_BAR_UNMAPPED) continue; - if (r->type == PCI_BASE_ADDRESS_SPACE_IO) { - isa_unassign_ioport(r->addr, r->filtered_size); + if (r->memory) { + memory_region_del_subregion(r->address_space, r->memory); } else { - if (r->memory) { - memory_region_del_subregion(pci_dev->bus->address_space, - r->memory); + if (r->type == PCI_BASE_ADDRESS_SPACE_IO) { + isa_unassign_ioport(r->addr, r->filtered_size); } else { cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus, r->addr), @@ -934,9 +934,11 @@ static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num, pcibus_t addr, pcibus_t size, int type) { - memory_region_add_subregion_overlap(pci_dev->bus->address_space, + PCIIORegion *r = &pci_dev->io_regions[region_num]; + + memory_region_add_subregion_overlap(r->address_space, addr, - pci_dev->io_regions[region_num].memory, + r->memory, 1); } @@ -953,9 +955,13 @@ void pci_register_bar_region(PCIDevice *pci_dev, int region_num, uint8_t attr, MemoryRegion *memory) { pci_register_bar(pci_dev, region_num, memory_region_size(memory), - PCI_BASE_ADDRESS_SPACE_MEMORY | attr, + attr, pci_simple_bar_mapfunc_region); pci_dev->io_regions[region_num].memory = memory; + pci_dev->io_regions[region_num].address_space + = attr & PCI_BASE_ADDRESS_SPACE_IO + ? pci_dev->bus->address_space_io + : pci_dev->bus->address_space_mem; } pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num) @@ -1090,7 +1096,9 @@ static void pci_update_mappings(PCIDevice *d) /* now do the real mapping */ if (r->addr != PCI_BAR_UNMAPPED) { - if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { + if (r->memory) { + memory_region_del_subregion(r->address_space, r->memory); + } else if (r->type & PCI_BASE_ADDRESS_SPACE_IO) { int class; /* NOTE: specific hack for IDE in PC case: only one byte must be mapped. */ @@ -1101,16 +1109,11 @@ static void pci_update_mappings(PCIDevice *d) isa_unassign_ioport(r->addr, r->filtered_size); } } else { - if (r->memory) { - memory_region_del_subregion(d->bus->address_space, - r->memory); - } else { - cpu_register_physical_memory(pci_to_cpu_addr(d->bus, - r->addr), - r->filtered_size, - IO_MEM_UNASSIGNED); - qemu_unregister_coalesced_mmio(r->addr, r->filtered_size); - } + cpu_register_physical_memory(pci_to_cpu_addr(d->bus, + r->addr), + r->filtered_size, + IO_MEM_UNASSIGNED); + qemu_unregister_coalesced_mmio(r->addr, r->filtered_size); } } r->addr = new_addr; diff --git a/hw/pci.h b/hw/pci.h index 45b30fa..928e96c 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -95,6 +95,7 @@ typedef struct PCIIORegion { PCIMapIORegionFunc *map_func; ram_addr_t ram_addr; MemoryRegion *memory; + MemoryRegion *address_space; } PCIIORegion; #define PCI_ROM_SLOT 6 diff --git a/hw/pci_internals.h b/hw/pci_internals.h index c3a463a..c7fd23d 100644 --- a/hw/pci_internals.h +++ b/hw/pci_internals.h @@ -25,7 +25,8 @@ struct PCIBus { PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX]; PCIDevice *parent_dev; target_phys_addr_t mem_base; - MemoryRegion *address_space; + MemoryRegion *address_space_mem; + MemoryRegion *address_space_io; QLIST_HEAD(, PCIBus) child; /* this will be replaced by qdev later */ QLIST_ENTRY(PCIBus) sibling;/* this will be replaced by qdev later */