56753ff
From f1e729a041efbd2d562e8202407e927745210bbd Mon Sep 17 00:00:00 2001
56753ff
From: Gerd Hoffmann <kraxel@redhat.com>
56753ff
Date: Fri, 14 Oct 2011 18:05:48 +0200
56753ff
Subject: [PATCH 431/434] qxl: add optinal 64bit vram bar
56753ff
56753ff
This patch adds an 64bit pci bar for vram.  It is turned off by default.
56753ff
It can be enabled by setting the size of the 64bit bar to be larger than
56753ff
the 32bit bar.  Both 32bit and 64bit bar refer to the same memory.  Only
56753ff
the first part of the memory is available via 32bit bar.
56753ff
56753ff
The intention is to allow large vram sizes for 64bit guests, by allowing
56753ff
the vram bar being mapped above 4G, so we don't have to squeeze it into
56753ff
the pci I/O window below 4G.
56753ff
56753ff
With vram_size_mb=16 and vram64_size_mb=256 it looks like this:
56753ff
56753ff
00:02.0 VGA compatible controller: Red Hat, Inc. Device 0100 (rev 02) (prog-if 00 [VGA controller])
56753ff
        Subsystem: Red Hat, Inc Device 1100
56753ff
        Physical Slot: 2
56753ff
        Flags: fast devsel, IRQ 10
56753ff
        Memory at f8000000 (32-bit, non-prefetchable) [size=64M]
56753ff
        Memory at fc000000 (32-bit, non-prefetchable) [size=16M]
56753ff
        Memory at fd020000 (32-bit, non-prefetchable) [size=8K]
56753ff
        I/O ports at c5a0 [size=32]
56753ff
        Memory at ffe0000000 (64-bit, prefetchable) [size=256M]
56753ff
        Expansion ROM at fd000000 [disabled] [size=64K]
56753ff
56753ff
[ mapping above 4G needs patched seabios:
56753ff
  http://www.kraxel.org/cgit/seabios/commit/?h=pci64 ]
56753ff
56753ff
Conflicts:
56753ff
56753ff
	hw/qxl.c
56753ff
---
56753ff
 hw/qxl.c |   51 ++++++++++++++++++++++++++++++++++++++++++++-------
56753ff
 hw/qxl.h |    7 +++++++
56753ff
 2 files changed, 51 insertions(+), 7 deletions(-)
56753ff
56753ff
diff --git a/hw/qxl.c b/hw/qxl.c
56753ff
index bcdf274..18f3759 100644
56753ff
--- a/hw/qxl.c
56753ff
+++ b/hw/qxl.c
56753ff
@@ -1002,6 +1002,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
56753ff
     static const int regions[] = {
56753ff
         QXL_RAM_RANGE_INDEX,
56753ff
         QXL_VRAM_RANGE_INDEX,
56753ff
+        QXL_VRAM64_RANGE_INDEX,
56753ff
     };
56753ff
     uint64_t guest_start;
56753ff
     uint64_t guest_end;
56753ff
@@ -1046,6 +1047,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
56753ff
         virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram);
56753ff
         break;
56753ff
     case QXL_VRAM_RANGE_INDEX:
56753ff
+    case 4 /* vram 64bit */:
56753ff
         virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar);
56753ff
         break;
56753ff
     default:
56753ff
@@ -1630,18 +1632,28 @@ static void qxl_init_ramsize(PCIQXLDevice *qxl, uint32_t ram_min_mb)
56753ff
         qxl->vga.vram_size = ram_min_mb * 1024 * 1024;
56753ff
     }
56753ff
 
56753ff
-    /* vram (surfaces, bar 1) */
56753ff
+    /* vram32 (surfaces, 32bit, bar 1) */
56753ff
+    if (qxl->vram32_size_mb != -1) {
56753ff
+        qxl->vram32_size = qxl->vram32_size_mb * 1024 * 1024;
56753ff
+    }
56753ff
+    if (qxl->vram32_size < 4096) {
56753ff
+        qxl->vram32_size = 4096;
56753ff
+    }
56753ff
+
56753ff
+    /* vram (surfaces, 64bit, bar 4+5) */
56753ff
     if (qxl->vram_size_mb != -1) {
56753ff
         qxl->vram_size = qxl->vram_size_mb * 1024 * 1024;
56753ff
     }
56753ff
-    if (qxl->vram_size < 4096) {
56753ff
-        qxl->vram_size = 4096;
56753ff
+    if (qxl->vram_size < qxl->vram32_size) {
56753ff
+        qxl->vram_size = qxl->vram32_size;
56753ff
     }
56753ff
+
56753ff
     if (qxl->revision == 1) {
56753ff
+        qxl->vram32_size = 4096;
56753ff
         qxl->vram_size = 4096;
56753ff
     }
56753ff
-
56753ff
     qxl->vga.vram_size = msb_mask(qxl->vga.vram_size * 2 - 1);
56753ff
+    qxl->vram32_size = msb_mask(qxl->vram32_size * 2 - 1);
56753ff
     qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1);
56753ff
 }
56753ff
 
56753ff
@@ -1683,6 +1695,8 @@ static int qxl_init_common(PCIQXLDevice *qxl)
56753ff
 
56753ff
     memory_region_init_ram(&qxl->vram_bar, &qxl->pci.qdev, "qxl.vram",
56753ff
                            qxl->vram_size);
56753ff
+    memory_region_init_alias(&qxl->vram32_bar, "qxl.vram32", &qxl->vram_bar,
56753ff
+                             0, qxl->vram32_size);
56753ff
 
56753ff
     io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
56753ff
     if (qxl->revision == 1) {
56753ff
@@ -1706,7 +1720,29 @@ static int qxl_init_common(PCIQXLDevice *qxl)
56753ff
                      PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vga.vram);
56753ff
 
56753ff
     pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX,
56753ff
-                     PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram_bar);
56753ff
+                     PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram32_bar);
56753ff
+
56753ff
+    if (qxl->vram32_size < qxl->vram_size) {
56753ff
+        /*
56753ff
+         * Make the 64bit vram bar show up only in case it is
56753ff
+         * configured to be larger than the 32bit vram bar.
56753ff
+         */
56753ff
+        pci_register_bar(&qxl->pci, QXL_VRAM64_RANGE_INDEX,
56753ff
+                         PCI_BASE_ADDRESS_SPACE_MEMORY |
56753ff
+                         PCI_BASE_ADDRESS_MEM_TYPE_64 |
56753ff
+                         PCI_BASE_ADDRESS_MEM_PREFETCH,
56753ff
+                         &qxl->vram_bar);
56753ff
+    }
56753ff
+
56753ff
+    /* print pci bar details */
56753ff
+    dprint(qxl, 1, "ram/%s: %d MB [region 0]\n",
56753ff
+           qxl->id == 0 ? "pri" : "sec",
56753ff
+           qxl->vga.vram_size / (1024*1024));
56753ff
+    dprint(qxl, 1, "vram/32: %d MB [region 1]\n",
56753ff
+           qxl->vram32_size / (1024*1024));
56753ff
+    dprint(qxl, 1, "vram/64: %d MB %s\n",
56753ff
+           qxl->vram_size / (1024*1024),
56753ff
+           qxl->vram32_size < qxl->vram_size ? "[region 4]" : "[unmapped]");
56753ff
 
56753ff
     qxl->ssd.qxl.base.sif = &qxl_interface.base;
56753ff
     qxl->ssd.qxl.id = qxl->id;
56753ff
@@ -1918,7 +1954,7 @@ static VMStateDescription qxl_vmstate = {
56753ff
 static Property qxl_properties[] = {
56753ff
         DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size,
56753ff
                            64 * 1024 * 1024),
56753ff
-        DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size,
56753ff
+        DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram32_size,
56753ff
                            64 * 1024 * 1024),
56753ff
         DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision,
56753ff
                            QXL_DEFAULT_REVISION),
56753ff
@@ -1926,7 +1962,8 @@ static Property qxl_properties[] = {
56753ff
         DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
56753ff
         DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
56753ff
         DEFINE_PROP_UINT32("ram_size_mb",  PCIQXLDevice, ram_size_mb, -1),
56753ff
-        DEFINE_PROP_UINT32("vram_size_mb", PCIQXLDevice, vram_size_mb, -1),
56753ff
+        DEFINE_PROP_UINT32("vram_size_mb", PCIQXLDevice, vram32_size_mb, 0),
56753ff
+        DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, 0),
56753ff
         DEFINE_PROP_END_OF_LIST(),
56753ff
 };
56753ff
 
56753ff
diff --git a/hw/qxl.h b/hw/qxl.h
56753ff
index 86e415b..11a0db3 100644
56753ff
--- a/hw/qxl.h
56753ff
+++ b/hw/qxl.h
56753ff
@@ -16,6 +16,10 @@ enum qxl_mode {
56753ff
     QXL_MODE_NATIVE,
56753ff
 };
56753ff
 
56753ff
+#ifndef QXL_VRAM64_RANGE_INDEX
56753ff
+#define QXL_VRAM64_RANGE_INDEX 4
56753ff
+#endif
56753ff
+
56753ff
 #define QXL_UNDEFINED_IO UINT32_MAX
56753ff
 
56753ff
 #define QXL_NUM_DIRTY_RECTS 64
56753ff
@@ -88,6 +92,8 @@ typedef struct PCIQXLDevice {
56753ff
     /* vram pci bar */
56753ff
     uint32_t           vram_size;
56753ff
     MemoryRegion       vram_bar;
56753ff
+    uint32_t           vram32_size;
56753ff
+    MemoryRegion       vram32_bar;
56753ff
 
56753ff
     /* io bar */
56753ff
     MemoryRegion       io_bar;
56753ff
@@ -95,6 +101,7 @@ typedef struct PCIQXLDevice {
56753ff
     /* user-friendly properties (in megabytes) */
56753ff
     uint32_t          ram_size_mb;
56753ff
     uint32_t          vram_size_mb;
56753ff
+    uint32_t          vram32_size_mb;
56753ff
 
56753ff
     /* qxl_render_update state */
56753ff
     int                render_update_cookie_num;
56753ff
-- 
56753ff
1.7.10
56753ff