Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > aadbe78a25743146bb784eee19f007c5 > files > 24

kvm-83-164.el5_5.9.src.rpm

From 9d8322f9ae1ec90946e17f27162c6a29242df82e Mon Sep 17 00:00:00 2001
From: Yonit Halperin <yonith@qumranet.com>
Date: Thu, 8 Jan 2009 20:09:08 +0200
Subject: [PATCH 23/54] qemu: control qxl ram size via command line

RH-Type: improvement(qxl)
RH-Upstream-status: pending
---
 qemu/hw/pc.c  |    5 ++-
 qemu/hw/pc.h  |    8 ++++-
 qemu/hw/qxl.c |   78 ++++++++++++++++++++++++++++----------------------------
 qemu/vl.c     |   43 +++++++++++++++++++++++++++++--
 4 files changed, 88 insertions(+), 46 deletions(-)

diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index 75e014f..52e17fd 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -1015,8 +1015,9 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
         isa_vga_init(ds, phys_ram_base + vga_ram_addr,
                          vga_ram_addr, vga_ram_size);
         for (i = 0; i < num_qxl_device; i++) {
-            ram_addr_t qxl_ram = qemu_ram_alloc(QXL_MEM_SIZE);
-            qxl_init(pci_bus, phys_ram_base + qxl_ram, qxl_ram, QXL_MEM_SIZE);
+            uint32_t qxl_total_mem_size = qxl_get_total_mem_size(qxl_ram_size);
+            ram_addr_t qxl_ram = qemu_ram_alloc(qxl_total_mem_size);
+            qxl_init(pci_bus, phys_ram_base + qxl_ram, qxl_ram, qxl_total_mem_size, qxl_ram_size);
         }
 #endif
     } else if (vmsvga_enabled) {
diff --git a/qemu/hw/pc.h b/qemu/hw/pc.h
index a4aede5..3ccc448 100644
--- a/qemu/hw/pc.h
+++ b/qemu/hw/pc.h
@@ -161,18 +161,22 @@ void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
 /*qxl.c*/
 #ifdef CONFIG_QXL
 
-#define QXL_MEM_SIZE (1024 * 1024 * (32 + 9))
+#define QXL_MAX_RAM_SIZE (256 * 1024 * 1024)
 #define QXL_MAX_MONITORS 4
 
 extern int using_qxl;
 extern int num_qxl_device;
+extern uint32_t qxl_ram_size;
 
 void qxl_init(PCIBus *bus, uint8_t *vram,
               unsigned long vram_offset,
-              uint32_t vram_size);
+              uint32_t vram_size, uint32_t in_ram_size);
+
 void qxl_init_display(DisplayState *ds);
 int qxl_vga_touch(void);
 void qxl_do_set_log_level(int log_level);
+uint32_t qxl_get_total_mem_size(uint32_t in_ram_size);
+uint32_t qxl_get_min_ram_size(void);
 
 #endif
 
diff --git a/qemu/hw/qxl.c b/qemu/hw/qxl.c
index 9ce2072..b3125d0 100644
--- a/qemu/hw/qxl.c
+++ b/qemu/hw/qxl.c
@@ -19,7 +19,7 @@
 
 //#define QXL_IO_MEM
 
-#define QXL_RAM_SIZE (32 * 1024 * 1024)
+#define QXL_VRAM_SIZE 4096
 #define QXL_DEFAULT_COMPRESSION_LEVEL 0
 #define QXL_SHARED_VGA_MODE FALSE
 #define QXL_SAVE_VERSION 3
@@ -191,6 +191,8 @@ static void qxl_reset_state(PCIQXLDevice *d);
 
 static QXLVga qxl_vga;
 
+inline uint32_t msb_mask(uint32_t val);
+
 inline void atomic_or(uint32_t *var, uint32_t add)
 {
    __asm__ __volatile__ ("lock; orl %1, %0" : "+m" (*var) : "r" (add) : "memory");
@@ -211,26 +213,15 @@ static void qxl_init_modes()
     }
 }
 
-static UINT32 qxl_max_x_res()
+static UINT32 qxl_max_res_area()
 {
-    UINT32 res = 0;
+    UINT32 area = 0;
     int i;
 
     for (i = 0; i < sizeof(qxl_modes) / sizeof(QXLMode); i++) {
-        res = MAX(qxl_modes[i].x_res, res);
+        area = MAX(qxl_modes[i].x_res*qxl_modes[i].y_res, area);
     }
-    return res;
-}
-
-static UINT32 qxl_max_y_res()
-{
-    UINT32 res = 0;
-    int i;
-
-    for (i = 0; i < sizeof(qxl_modes) / sizeof(QXLMode); i++) {
-        res = MAX(qxl_modes[i].y_res, res);
-    }
-    return res;
+    return area;
 }
 
 static int irq_level(PCIQXLDevice *d)
@@ -257,6 +248,21 @@ void qxl_do_set_log_level(int log_level)
     }
 }
 
+uint32_t qxl_get_total_mem_size(uint32_t in_ram_size)
+{
+    uint32_t ram_size = msb_mask(in_ram_size*2 - 1);
+    uint32_t rom_size = sizeof(QXLRom) + sizeof(QXLModes) + sizeof(qxl_modes);
+    rom_size = MAX(rom_size, TARGET_PAGE_SIZE);
+    rom_size = msb_mask(rom_size*2 - 1);
+
+    return (QXL_VRAM_SIZE + rom_size + ram_size);
+}
+
+uint32_t qxl_get_min_ram_size(void)
+{
+    return (qxl_max_res_area() * sizeof(uint32_t) * 3);
+}
+
 static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
 {
     ASSERT(d->state.running);
@@ -805,7 +811,7 @@ static uint32_t init_qxl_rom(PCIQXLDevice *d, uint8_t *buf, uint32_t vram_size,
     rom->id = d->id;
     rom->mode = 0;
     rom->modes_offset = sizeof(QXLRom);
-    rom->draw_area_size =qxl_max_x_res() * sizeof(uint32_t) * qxl_max_y_res();
+    rom->draw_area_size = qxl_max_res_area()* sizeof(uint32_t);
     rom->compression_level = QXL_DEFAULT_COMPRESSION_LEVEL;
     rom->log_level = 0;
 
@@ -821,7 +827,7 @@ static uint32_t init_qxl_rom(PCIQXLDevice *d, uint8_t *buf, uint32_t vram_size,
     return (uint32_t)((uint8_t *)&modes->modes[i] - buf);
 }
 
-static void init_qxl_ram(QXLState *s, uint8_t *buf)
+static void init_qxl_ram(QXLState *s, uint8_t *buf, uint32_t actual_ram_size)
 {
     uint32_t draw_area_size;
     uint32_t ram_header_size;
@@ -830,9 +836,9 @@ static void init_qxl_ram(QXLState *s, uint8_t *buf)
 
     draw_area_size = s->rom->draw_area_size;
     ram_header_size = ALIGN(sizeof(*s->ram), 8);
-    ASSERT(ram_header_size + draw_area_size < QXL_RAM_SIZE);
+    ASSERT(ram_header_size + draw_area_size < actual_ram_size);
 
-    s->rom->ram_header_offset = QXL_RAM_SIZE - ram_header_size;
+    s->rom->ram_header_offset = actual_ram_size - ram_header_size;
     s->ram = (QXLRam *)(buf + s->rom->ram_header_offset);
     s->ram->magic = QXL_RAM_MAGIC;
     RING_INIT(&s->ram->cmd_ring);
@@ -842,8 +848,7 @@ static void init_qxl_ram(QXLState *s, uint8_t *buf)
 
     s->rom->draw_area_offset = s->rom->ram_header_offset - draw_area_size;
     s->rom->pages_offset = 0;
-    s->rom->num_io_pages = (QXL_RAM_SIZE - (draw_area_size + ram_header_size)) >> TARGET_PAGE_BITS;
-    ASSERT((s->rom->num_io_pages << TARGET_PAGE_BITS) >= VGA_RAM_SIZE);
+    s->rom->num_io_pages = (actual_ram_size - (draw_area_size + ram_header_size)) >> TARGET_PAGE_BITS;
     printf("%s: npages %u\n", __FUNCTION__, s->rom->num_io_pages);
 }
 
@@ -1423,12 +1428,13 @@ static void creat_native_worker(PCIQXLDevice *d, int id)
 static int device_id = 0;
 
 void qxl_init(PCIBus *bus, uint8_t *vram, unsigned long vram_offset, 
-              uint32_t vram_size)
+              uint32_t vram_size, uint32_t in_ram_size)
 {
     PCIQXLDevice *d;
     PCIConf *pci_conf;
     uint32_t rom_size;
     uint32_t max_fb;
+    uint32_t qxl_ram_size = msb_mask(in_ram_size*2 - 1);
 
     d = (PCIQXLDevice*)pci_register_device(bus, QXL_DEV_NAME,
                                            sizeof(PCIQXLDevice), -1, NULL,
@@ -1460,21 +1466,21 @@ void qxl_init(PCIBus *bus, uint8_t *vram, unsigned long vram_offset,
 
     memset(vram, 0xff, vram_size);
 
-    ASSERT(vram_size > QXL_RAM_SIZE);
-    rom_size = init_qxl_rom(d, vram + QXL_RAM_SIZE , vram_size - QXL_RAM_SIZE, &max_fb);
+    ASSERT(vram_size > qxl_ram_size);
+    rom_size = init_qxl_rom(d, vram + qxl_ram_size , vram_size - qxl_ram_size, &max_fb);
     rom_size = MAX(rom_size, TARGET_PAGE_SIZE);  
     rom_size = msb_mask(rom_size * 2 - 1);
-    d->state.rom_offset = vram_offset + QXL_RAM_SIZE;
+    d->state.rom_offset = vram_offset + qxl_ram_size;
     d->state.rom_size = rom_size;
 
-    ASSERT(QXL_RAM_SIZE + rom_size < vram_size);
-    init_qxl_ram(&d->state, vram);
+    ASSERT(qxl_ram_size + rom_size < vram_size);
+    init_qxl_ram(&d->state, vram, in_ram_size);
     d->state.ram_offset = vram_offset;
-    d->state.ram_size = QXL_RAM_SIZE;
+    d->state.ram_size = qxl_ram_size;
 
-    d->state.vram = vram + rom_size + QXL_RAM_SIZE;
-    d->state.vram_offset = vram_offset + rom_size + QXL_RAM_SIZE;
-    d->state.vram_size = msb_mask(vram_size - (QXL_RAM_SIZE + rom_size));
+    d->state.vram = vram + rom_size + qxl_ram_size;
+    d->state.vram_offset = vram_offset + rom_size + qxl_ram_size;
+    d->state.vram_size = msb_mask(vram_size - (qxl_ram_size + rom_size));
 
     printf("%s: rom(%p, 0x%x, 0x%x) ram(%p, 0x%x, 0x%x) vram(%p, 0x%lx, 0x%x)\n",
            __FUNCTION__,
@@ -1487,13 +1493,7 @@ void qxl_init(PCIBus *bus, uint8_t *vram, unsigned long vram_offset,
            d->state.vram,
            d->state.vram_offset,
            d->state.vram_size);
-   
-    if (d->state.vram_size < max_fb) {
-        printf("%s: bad vram size, vram %u rom %u max_fb %u\n",
-               __FUNCTION__, vram_size, rom_size, max_fb);
-        exit(-1);
-    }
-
+ 
     pci_register_io_region(&d->pci_dev, QXL_IO_RANGE_INDEX,
                            msb_mask(QXL_IO_RANGE_SIZE * 2 - 1),
                            PCI_ADDRESS_SPACE_IO, ioport_map);
diff --git a/qemu/vl.c b/qemu/vl.c
index b02a85c..4ed4375 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -270,8 +270,10 @@ static QEMUTimer *icount_rt_timer;
 static QEMUTimer *icount_vm_timer;
 
 #ifdef CONFIG_QXL
+#define DEFAULT_QXL_RAM_MB_SIZE 64
 int using_qxl = 0;
 int num_qxl_device = 0;
+uint32_t qxl_ram_size = 0;
 #endif
 
 #ifdef CONFIG_SPICE
@@ -4047,7 +4049,9 @@ static void help(int exitcode)
            "-name string    set the name of the guest\n"
            "-uuid %%08x-%%04x-%%04x-%%04x-%%012x specify machine UUID\n"
 #ifdef CONFIG_QXL
-           "-qxl <num>      use qxl display device\n"
+           "-qxl <num>[,ram=megs]\n"
+           "                use 'num' qxl display devices, each with RAM size of 'megs' MB\n"
+           "                [default=%d]\n"
 #endif
 #ifdef CONFIG_SPICE
            "-spice <args>   use spice\n"
@@ -4182,6 +4186,9 @@ static void help(int exitcode)
            ,
            "qemu",
            DEFAULT_RAM_SIZE,
+#ifdef CONFIG_QXL
+           DEFAULT_QXL_RAM_MB_SIZE,
+#endif
 #ifndef _WIN32
            DEFAULT_NETWORK_SCRIPT,
            DEFAULT_NETWORK_DOWN_SCRIPT,
@@ -5378,7 +5385,9 @@ int main(int argc, char **argv, char **envp)
 #endif
 #ifdef CONFIG_QXL
             case QEMU_OPTION_qxl: {
-                int devices = strtol(optarg, NULL, 0);
+                const char *p;
+                int devices = strtol(optarg, (char **)&p, 0);
+
                 if (devices < 0 || devices > QXL_MAX_MONITORS ) {
                     fprintf(stderr, "qemu: invalid number of qxl devices, use 0 to %d\n",
                             QXL_MAX_MONITORS);
@@ -5386,6 +5395,34 @@ int main(int argc, char **argv, char **envp)
                 }
                 num_qxl_device = devices;
                 using_qxl = (num_qxl_device > 0) ? 1 : 0;
+                if (using_qxl) {
+                    if (*p==',') {
+                        char buf[32];
+                        p++;
+                        if (get_param_value(buf, sizeof(buf), "ram", p)) {
+                            qxl_ram_size = strtol(buf, NULL, 0);
+                        }
+                        else {
+                            fprintf(stderr, "qemu: invalid qxl format\n");
+                            exit(-1);
+                        }
+                    } else if (*p!='\0') {
+                        fprintf(stderr, "qemu: invalid qxl format\n");
+                        exit(-1);
+                    } else {
+                        qxl_ram_size = DEFAULT_QXL_RAM_MB_SIZE;
+                    }
+
+                    qxl_ram_size <<= 20;
+       
+                    if ((qxl_ram_size > QXL_MAX_RAM_SIZE) ||
+                        (qxl_ram_size < qxl_get_min_ram_size()))
+                    {
+                        fprintf(stderr, "qemu: invalid qxl ram size\n");
+                        exit(-1);
+                    }
+                }
+
                 break;
             }
 #endif
@@ -5772,7 +5809,7 @@ int main(int argc, char **argv, char **envp)
 
 #ifdef CONFIG_QXL
     if (using_qxl) {
-        phys_ram_size += num_qxl_device * QXL_MEM_SIZE;
+        phys_ram_size += num_qxl_device * qxl_get_total_mem_size(qxl_ram_size);
     }
 #endif
 
-- 
1.6.1