From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Mswe7-0002zU-CV for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:42:55 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Mswe3-0002xY-3t for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:42:54 -0400 Received: from [199.232.76.173] (port=41723 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Mswe2-0002xE-Hh for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:42:50 -0400 Received: from mail.valinux.co.jp ([210.128.90.3]:55566) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Mswe1-0000Ib-OG for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:42:50 -0400 From: Isaku Yamahata Date: Wed, 30 Sep 2009 19:18:05 +0900 Message-Id: <1254305917-14784-30-git-send-email-yamahata@valinux.co.jp> In-Reply-To: <1254305917-14784-1-git-send-email-yamahata@valinux.co.jp> References: <1254305917-14784-1-git-send-email-yamahata@valinux.co.jp> Subject: [Qemu-devel] [PATCH 29/61] pci: factor out the logic to get pci device from address. List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, anthony@codemonkey.ws Cc: yamahata@valinux.co.jp factor out conversion logic from io port address into bus+dev+func with bit shift operation and conversion bus+dev+func into pci device. They will be used later. This patch also eliminates the logic duplication. Signed-off-by: Isaku Yamahata --- hw/pci.c | 105 ++++++++++++++++++++++++++++++++++--------------------------- 1 files changed, 58 insertions(+), 47 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index 5d6b3ea..d1745ab 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -587,71 +587,82 @@ static PCIBus *pci_find_bus_from(PCIBus *from, int bus_num) return s; } -void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len) +static PCIDevice *pci_bdf_to_dev(PCIBus *s, int bus_num, unsigned int devfn) { - PCIBus *s = opaque; - PCIDevice *pci_dev; - int config_addr, bus_num; - -#if 0 - PCI_DPRINTF("pci_data_write: addr=%08"PRIx32" val=%08"PRIx32" len=%d\n", - addr, val, len); -#endif - bus_num = (addr >> 16) & 0xff; s = pci_find_bus_from(s, bus_num); if (!s) - return; - pci_dev = s->devices[(addr >> 8) & 0xff]; + return NULL; + + return s->devices[devfn]; +} + +static void pci_dev_data_write(PCIDevice *pci_dev, + uint32_t config_addr, uint32_t val, int len) +{ + assert(len == 1 || len == 2 || len == 4); if (!pci_dev) return; - config_addr = addr & 0xff; - PCI_DPRINTF("pci_config_write: %s: " - "addr=%02"PRIx32" val=%08"PRI32x" len=%d\n", - pci_dev->name, config_addr, val, len); + + PCI_DPRINTF("%s: %s: addr=%02"PRIx32" val=%08"PRI32x" len=%d\n", + __func__, pci_dev->name, config_addr, val, len); pci_dev->config_write(pci_dev, config_addr, val, len); } -uint32_t pci_data_read(void *opaque, uint32_t addr, int len) +static uint32_t pci_dev_data_read(PCIDevice *pci_dev, + uint32_t config_addr, int len) { - PCIBus *s = opaque; - PCIDevice *pci_dev; - int config_addr, bus_num; uint32_t val; - bus_num = (addr >> 16) & 0xff; - s = pci_find_bus_from(s, bus_num); - if (!s) - goto fail; - pci_dev = s->devices[(addr >> 8) & 0xff]; + assert(len == 1 || len == 2 || len == 4); if (!pci_dev) { - fail: - switch(len) { - case 1: - val = 0xff; - break; - case 2: - val = 0xffff; - break; - default: - case 4: - val = 0xffffffff; - break; - } - goto the_end; + val = (1 << (len * 8)) - 1; + } else { + val = pci_dev->config_read(pci_dev, config_addr, len); + PCI_DPRINTF("%s: %s: addr=%02"PRIx32" val=%08"PRIx32" len=%d\n", + __func__, pci_dev->name, config_addr, val, len); } - config_addr = addr & 0xff; - val = pci_dev->config_read(pci_dev, config_addr, len); - PCI_DPRINTF("pci_config_read: %s: " - "addr=%02"PRIx32" val=%08"PRIx32" len=%d\n", - pci_dev->name, config_addr, val, len); - the_end: + #if 0 - PCI_DPRINTF("pci_data_read: addr=%08"PRIx32" val=%08"PRIx32" len=%d\n", - addr, val, len); + PCI_DPRINTF("%s: addr=%08"PRIx32" val=%08"PRIx32" len=%d\n", + __func__, addr, val, len); #endif return val; } +static void pci_addr_to_dev(PCIBus *s, uint32_t addr, + PCIDevice **pci_dev, uint32_t *config_addr) +{ + int bus_num = (addr >> 16) & 0xff; + unsigned int devfn = (addr >> 8) & 0xff; + + *pci_dev = pci_bdf_to_dev(s, bus_num, devfn); + *config_addr = addr & 0xff; +} + +void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len) +{ + PCIBus *s = opaque; + PCIDevice *pci_dev; + uint32_t config_addr; + +#if 0 + PCI_DPRINTF("pci_data_write: addr=%08"PRIx32" val=%08"PRIx32" len=%d\n", + addr, val, len); +#endif + + pci_addr_to_dev(s, addr, &pci_dev, &config_addr); + pci_dev_data_write(pci_dev, config_addr, val, len); +} + +uint32_t pci_data_read(void *opaque, uint32_t addr, int len) +{ + PCIBus *s = opaque; + PCIDevice *pci_dev; + uint32_t config_addr; + + pci_addr_to_dev(s, addr, &pci_dev, &config_addr); + return pci_dev_data_read(pci_dev, config_addr, len); +} /***********************************************************/ /* generic PCI irq support */ -- 1.6.0.2