From patchwork Fri Nov 19 23:19:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Williamson X-Patchwork-Id: 343531 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oAJNJsN2010275 for ; Fri, 19 Nov 2010 23:19:55 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932282Ab0KSXTw (ORCPT ); Fri, 19 Nov 2010 18:19:52 -0500 Received: from mx1.redhat.com ([209.132.183.28]:53100 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932178Ab0KSXTv (ORCPT ); Fri, 19 Nov 2010 18:19:51 -0500 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id oAJNJo0j023097 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 19 Nov 2010 18:19:50 -0500 Received: from s20.home (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id oAJNJnDe006861; Fri, 19 Nov 2010 18:19:49 -0500 From: Alex Williamson Subject: [PATCH v3 4/9] pci: Replace used bitmap with config byte map To: kvm@vger.kernel.org, mst@redhat.com Cc: qemu-devel@nongnu.org, alex.williamson@redhat.com, chrisw@redhat.com Date: Fri, 19 Nov 2010 16:19:49 -0700 Message-ID: <20101119231941.22162.38903.stgit@s20.home> In-Reply-To: <20101119231138.22162.93647.stgit@s20.home> References: <20101119231138.22162.93647.stgit@s20.home> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Fri, 19 Nov 2010 23:19:55 +0000 (UTC) diff --git a/hw/device-assignment.c b/hw/device-assignment.c index 76aacac..a4fad60 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -423,7 +423,7 @@ static void assigned_dev_pci_write_config(PCIDevice *d, uint32_t address, if ((address >= 0x10 && address <= 0x24) || address == 0x30 || address == 0x34 || address == 0x3c || address == 0x3d || - pci_access_cap_config(d, address, len)) { + (address > PCI_CONFIG_HEADER_SIZE && d->config_map[address])) { /* used for update-mappings (BAR emulation) */ pci_default_write_config(d, address, val, len); return; @@ -459,7 +459,7 @@ static uint32_t assigned_dev_pci_read_config(PCIDevice *d, uint32_t address, if (address < 0x4 || (pci_dev->need_emulate_cmd && address == 0x4) || (address >= 0x10 && address <= 0x24) || address == 0x30 || address == 0x34 || address == 0x3c || address == 0x3d || - pci_access_cap_config(d, address, len)) { + (address > PCI_CONFIG_HEADER_SIZE && d->config_map[address])) { val = pci_default_read_config(d, address, len); DEBUG("(%x.%x): address=%04x val=0x%08x len=%d\n", (d->devfn >> 3) & 0x1F, (d->devfn & 0x7), address, val, len); diff --git a/hw/pci.c b/hw/pci.c index f2896d9..cbe6fb7 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -712,7 +712,7 @@ static void pci_config_alloc(PCIDevice *pci_dev) pci_dev->cmask = qemu_mallocz(config_size); pci_dev->wmask = qemu_mallocz(config_size); pci_dev->w1cmask = qemu_mallocz(config_size); - pci_dev->used = qemu_mallocz(config_size); + pci_dev->config_map = qemu_mallocz(config_size); } static void pci_config_free(PCIDevice *pci_dev) @@ -721,7 +721,7 @@ static void pci_config_free(PCIDevice *pci_dev) qemu_free(pci_dev->cmask); qemu_free(pci_dev->wmask); qemu_free(pci_dev->w1cmask); - qemu_free(pci_dev->used); + qemu_free(pci_dev->config_map); } /* -1 for devfn means auto assign */ @@ -751,6 +751,8 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, pci_dev->irq_state = 0; pci_config_alloc(pci_dev); + memset(pci_dev->config_map, 0xff, PCI_CONFIG_HEADER_SIZE); + if (!is_bridge) { pci_set_default_subsystem_id(pci_dev); } @@ -1083,21 +1085,13 @@ uint32_t pci_default_read_config(PCIDevice *d, { assert(len == 1 || len == 2 || len == 4); - if (pci_access_cap_config(d, address, len)) { + if (address > PCI_CONFIG_HEADER_SIZE && d->config_map[address]) { return d->cap.config_read(d, address, len); } return pci_read_config(d, address, len); } -int pci_access_cap_config(PCIDevice *pci_dev, uint32_t address, int len) -{ - if (pci_dev->cap.supported && address >= pci_dev->cap.start && - (address + len) < pci_dev->cap.start + pci_dev->cap.length) - return 1; - return 0; -} - uint32_t pci_default_cap_read_config(PCIDevice *pci_dev, uint32_t address, int len) { @@ -1122,7 +1116,7 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) int i, was_irq_disabled = pci_irq_disabled(d); uint32_t config_size = pci_config_size(d); - if (pci_access_cap_config(d, addr, l)) { + if (addr > PCI_CONFIG_HEADER_SIZE && d->config_map[addr]) { d->cap.config_write(d, addr, val, l); return; } @@ -1789,7 +1783,7 @@ static int pci_find_space(PCIDevice *pdev, uint8_t size) int offset = PCI_CONFIG_HEADER_SIZE; int i; for (i = PCI_CONFIG_HEADER_SIZE; i < config_size; ++i) - if (pdev->used[i]) + if (pdev->config_map[i]) offset = i + 1; else if (i - offset + 1 == size) return offset; @@ -1908,7 +1902,7 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, config[PCI_CAP_LIST_ID] = cap_id; config[PCI_CAP_LIST_NEXT] = pdev->config[PCI_CAPABILITY_LIST]; pdev->config[PCI_CAPABILITY_LIST] = offset; - memset(pdev->used + offset, 0xFF, size); + memset(pdev->config_map + offset, cap_id, size); /* Make capability read-only by default */ memset(pdev->wmask + offset, 0, size); /* Check capability by default */ @@ -1933,7 +1927,7 @@ void pci_del_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size) memset(pdev->w1cmask + offset, 0, size); /* Clear cmask as device-specific registers can't be checked */ memset(pdev->cmask + offset, 0, size); - memset(pdev->used + offset, 0, size); + memset(pdev->config_map + offset, 0, size); if (!pdev->config[PCI_CAPABILITY_LIST]) { pdev->config[PCI_STATUS] &= ~PCI_STATUS_CAP_LIST; @@ -1941,12 +1935,6 @@ void pci_del_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size) } } -/* Reserve space for capability at a known offset (to call after load). */ -void pci_reserve_capability(PCIDevice *pdev, uint8_t offset, uint8_t size) -{ - memset(pdev->used + offset, 0xff, size); -} - uint8_t pci_find_capability(PCIDevice *pdev, uint8_t cap_id) { return pci_find_capability_list(pdev, cap_id, NULL); diff --git a/hw/pci.h b/hw/pci.h index fafc2bb..bd15b43 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -157,8 +157,8 @@ struct PCIDevice { /* Used to implement RW1C(Write 1 to Clear) bytes */ uint8_t *w1cmask; - /* Used to allocate config space for capabilities. */ - uint8_t *used; + /* Used to allocate config space and track capabilities. */ + uint8_t *config_map; /* the following fields are read only */ PCIBus *bus; @@ -250,8 +250,6 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, void pci_del_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size); -void pci_reserve_capability(PCIDevice *pci_dev, uint8_t offset, uint8_t size); - uint8_t pci_find_capability(PCIDevice *pci_dev, uint8_t cap_id); uint32_t pci_default_read_config(PCIDevice *d, @@ -264,8 +262,6 @@ uint32_t pci_default_cap_read_config(PCIDevice *pci_dev, uint32_t address, int len); void pci_default_cap_write_config(PCIDevice *pci_dev, uint32_t address, uint32_t val, int len); -int pci_access_cap_config(PCIDevice *pci_dev, uint32_t address, int len); - typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level); typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num); typedef int (*pci_hotplug_fn)(DeviceState *qdev, PCIDevice *pci_dev, int state);