qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 6/6] pci: 64bit bar support.


From: Isaku Yamahata
Subject: [Qemu-devel] [PATCH 6/6] pci: 64bit bar support.
Date: Tue, 7 Jul 2009 15:59:27 +0900

implemented pci 64bit bar support.

Signed-off-by: Isaku Yamahata <address@hidden>
---
 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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]