From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MO4g3-0002kD-V4 for qemu-devel@nongnu.org; Tue, 07 Jul 2009 03:01:19 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MO4fz-0002ii-7Q for qemu-devel@nongnu.org; Tue, 07 Jul 2009 03:01:19 -0400 Received: from [199.232.76.173] (port=54087 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MO4fy-0002iX-VD for qemu-devel@nongnu.org; Tue, 07 Jul 2009 03:01:15 -0400 Received: from mx20.gnu.org ([199.232.41.8]:52651) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MO4fy-0006Cy-8l for qemu-devel@nongnu.org; Tue, 07 Jul 2009 03:01:14 -0400 Received: from mail.valinux.co.jp ([210.128.90.3]) by mx20.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MO4fx-0003ba-5F for qemu-devel@nongnu.org; Tue, 07 Jul 2009 03:01:13 -0400 From: Isaku Yamahata Date: Tue, 7 Jul 2009 15:59:27 +0900 Message-Id: <1246949967-4778-7-git-send-email-yamahata@valinux.co.jp> In-Reply-To: <1246949967-4778-1-git-send-email-yamahata@valinux.co.jp> References: <1246949967-4778-1-git-send-email-yamahata@valinux.co.jp> Subject: [Qemu-devel] [PATCH 6/6] pci: 64bit bar support. List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: yamahata@valinux.co.jp implemented pci 64bit bar support. Signed-off-by: Isaku Yamahata --- hw/pci.c | 47 +++++++++++++++++++++++++++++++++++++++++------ hw/pci.h | 8 ++++++++ 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index 4f5b6e9..79a66b8 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -411,9 +411,15 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, } else { addr = 0x10 + region_num * 4; } + *(uint32_t *)(pci_dev->config + addr) = cpu_to_le32(type); - *(uint32_t *)(pci_dev->wmask + addr) = cpu_to_le32(wmask & 0xffffffff); - *(uint32_t *)(pci_dev->cmask + addr) = 0xffffffff; + if (pci_bar_is_64bit(r)) { + *(uint64_t *)(pci_dev->wmask + addr) = cpu_to_le64(wmask); + *(uint64_t *)(pci_dev->cmask + addr) = ~0ULL; + } else { + *(uint32_t *)(pci_dev->wmask + addr) = cpu_to_le32(wmask & 0xffffffff); + *(uint32_t *)(pci_dev->cmask + addr) = 0xffffffff; + } } static void pci_update_mappings(PCIDevice *d) @@ -449,8 +455,14 @@ static void pci_update_mappings(PCIDevice *d) } } else { if (cmd & PCI_COMMAND_MEMORY) { - new_addr = le32_to_cpu(*(uint32_t *)(d->config + - config_ofs)); + + if (pci_bar_is_64bit(r)) { + new_addr = le64_to_cpu(*(uint64_t *)(d->config + + config_ofs)); + } else { + new_addr = le32_to_cpu(*(uint32_t *)(d->config + + config_ofs)); + } /* the ROM slot has a specific enable bit */ if (i == PCI_ROM_SLOT && !(new_addr & 1)) goto no_mem_map; @@ -465,7 +477,8 @@ static void pci_update_mappings(PCIDevice *d) /* keep old behaviour * without this, PC ide doesn't work well. */ - last_addr == PCI_BAR_UNMAPPED32) { + (!pci_bar_is_64bit(r) && + last_addr == PCI_BAR_UNMAPPED32)) { new_addr = PCI_BAR_UNMAPPED; } } else { @@ -722,7 +735,29 @@ static void pci_info_device(PCIDevice *d) monitor_printf(mon, "I/O at 0x%04"PRIx64" [0x%04"PRIx64"].\n", r->addr, r->addr + r->size - 1); } else { - monitor_printf(mon, "32 bit memory at 0x%08"PRIx64" [0x%08"PRIx64"].\n", + const char *type; + const char* prefetch; + + switch (r->type & PCI_ADDRESS_SPACE_MEM_TYPE_MASK) { + case PCI_ADDRESS_SPACE_MEM: + type = "32 bit"; + break; + case PCI_ADDRESS_SPACE_MEM_64: + type = "64 bit"; + break; + default: + type = "unknown"; + break; + } + + prefetch = ""; + if (r->type & PCI_ADDRESS_SPACE_MEM_PREFETCH) { + prefetch = " prefetchable"; + } + + monitor_printf(mon, "%s%s memory at " + "0x%08"PRIx64" [0x%08"PRIx64"].\n", + type, prefetch, r->addr, r->addr + r->size - 1); } } diff --git a/hw/pci.h b/hw/pci.h index 5290176..e4a280f 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -80,6 +80,8 @@ typedef int PCIUnregisterFunc(PCIDevice *pci_dev); #define PCI_ADDRESS_SPACE_MEM 0x00 #define PCI_ADDRESS_SPACE_IO 0x01 +#define PCI_ADDRESS_SPACE_MEM_64 0x04 /* 64 bit address */ +#define PCI_ADDRESS_SPACE_MEM_TYPE_MASK 0x06 #define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08 typedef struct PCIIORegion { @@ -91,6 +93,12 @@ typedef struct PCIIORegion { PCIMapIORegionFunc *map_func; } PCIIORegion; +static inline int pci_bar_is_64bit(const PCIIORegion *r) +{ + return (r->type & PCI_ADDRESS_SPACE_MEM_TYPE_MASK) == + PCI_ADDRESS_SPACE_MEM_64; +} + #define PCI_ROM_SLOT 6 #define PCI_NUM_REGIONS 7 -- 1.6.0.2