Patchwork [2/2] Variable VRAM size

login
register
mail settings
Submitter John Baboval
Date Oct. 28, 2011, 7:24 p.m.
Message ID <4EAB0175.9080507@virtualcomputer.com>
Download mbox | patch
Permalink /patch/122487/
State New
Headers show

Comments

John Baboval - Oct. 28, 2011, 7:24 p.m.
High resolution VGA modes require more than the default 8MB of VGA
RAM. Add a command line parameter to allow larger sizes.

Signed-off-by: John V. Baboval <john.baboval@virtualcomputer.com>
---
  hw/vga.c        |   64 
++++++++++++++++++++++++++++++++++++++++++++++++++----
  hw/vga_int.h    |    4 +++
  qemu-options.hx |    3 ++
  vl.c            |    4 +++
  4 files changed, 70 insertions(+), 5 deletions(-)
Gerd Hoffmann - Nov. 1, 2011, 9 a.m.
On 10/28/11 21:24, John Baboval wrote:
> High resolution VGA modes require more than the default 8MB of VGA
> RAM. Add a command line parameter to allow larger sizes.

This should be implemented as (qdev) device property.

cheers,
  Gerd

Patch

diff --git a/hw/vga.c b/hw/vga.c
index ca79aa1..8003eda 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -565,23 +565,76 @@  static uint32_t vbe_ioport_read_index(void 
*opaque, uint32_t addr)
      return val;
  }
  +typedef struct vga_ram_info {
+     int max_xres;
+     int max_yres;
+     int max_bpp;
+} vga_ram_info_t;
+
+static vga_ram_info_t vbe_ram_info(int ramsize)
+{
+    vga_ram_info_t s;
+    s.max_bpp = 32;
+
+    switch(ramsize) {
+    case 8 * 1024 * 1024:
+        s.max_xres = 1920;
+        s.max_yres = 1080;
+        break;
+    case 16 * 1024 * 1024:
+        s.max_xres = 2560;
+        s.max_yres = 1600;
+        break;
+    default:
+    case 32 * 1024 * 1024:
+        s.max_xres = 2560;
+        s.max_yres = 2048;
+        break;
+    }
+    return s;
+}
+
+static int vga_ram_sz = VGA_RAM_SIZE;
+void set_vga_ram_size(int size)
+{
+    const char *msg = NULL;
+
+    if (size < 8)
+        msg = "is too small";
+    else if (size > 512)
+        msg = "is too large";
+    else if (size != (size & ~(size - 1)))
+        msg = "is not a power of 2";
+    if (msg) {
+        fprintf(stderr, "VGA RAM size %d %s\n", size, msg);
+        exit(1);
+    }
+    vga_ram_sz = size * 1024 * 1024;
+}
+
+int vga_ram_size(void)
+{
+    return vga_ram_sz;
+}
+
  static uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
  {
      VGACommonState *s = opaque;
      uint32_t val;
+    vga_ram_info_t vs = vbe_ram_info(s->vram_size);
       if (s->vbe_index < VBE_DISPI_INDEX_NB) {
          if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_GETCAPS) {
              switch(s->vbe_index) {
                  /* XXX: do not hardcode ? */
              case VBE_DISPI_INDEX_XRES:
-                val = VBE_DISPI_MAX_XRES;
+                val = vs.max_xres;
                  break;
              case VBE_DISPI_INDEX_YRES:
-                val = VBE_DISPI_MAX_YRES;
+                val = vs.max_yres;
                  break;
              case VBE_DISPI_INDEX_BPP:
-                val = VBE_DISPI_MAX_BPP;
+                val = vs.max_bpp;
                  break;
              default:
                  val = s->vbe_regs[s->vbe_index];
@@ -610,6 +663,7 @@  static void vbe_ioport_write_index(void *opaque, 
uint32_t addr, uint32_t val)
  static void vbe_ioport_write_data(void *opaque, uint32_t addr, 
uint32_t val)
  {
      VGACommonState *s = opaque;
+    vga_ram_info_t vs = vbe_ram_info(s->vram_size);
       if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
  #ifdef DEBUG_BOCHS_VBE
@@ -626,12 +680,12 @@  static void vbe_ioport_write_data(void *opaque, 
uint32_t addr, uint32_t val)
              }
              break;
          case VBE_DISPI_INDEX_XRES:
-            if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
+            if ((val <= vs.max_xres) && ((val & 7) == 0)) {
                  s->vbe_regs[s->vbe_index] = val;
              }
              break;
          case VBE_DISPI_INDEX_YRES:
-            if (val <= VBE_DISPI_MAX_YRES) {
+            if (val <= vs.max_yres) {
                  s->vbe_regs[s->vbe_index] = val;
              }
              break;
diff --git a/hw/vga_int.h b/hw/vga_int.h
index c1e700f..3864fba 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -24,6 +24,7 @@ 
   #include <hw/hw.h>
  #include "memory.h"
+#include "console.h"
   #define MSR_COLOR_EMULATION 0x01
  #define MSR_PAGE_SELECT     0x20
@@ -224,6 +225,9 @@  void vga_init_vbe(VGACommonState *s, MemoryRegion 
*address_space);
  extern const uint8_t sr_mask[8];
  extern const uint8_t gr_mask[16];
  +void set_vga_ram_size(int size);
+int vga_ram_size(void);
+
  #define VGA_RAM_SIZE (8192 * 1024)
  #define VGABIOS_FILENAME "vgabios.bin"
  #define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
diff --git a/qemu-options.hx b/qemu-options.hx
index 5d2a776..00177f3 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -896,6 +896,9 @@  Disable VGA card.
  @end table
  ETEXI
  +DEF("vga-mem", HAS_ARG, QEMU_OPTION_vga_ram_size,
+ "-vga-mem megs              set virtual FB size to megs MB\n", 
QEMU_ARCH_ALL)
+
  DEF("full-screen", 0, QEMU_OPTION_full_screen,
      "-full-screen    start in full screen\n", QEMU_ARCH_ALL)
  STEXI
diff --git a/vl.c b/vl.c
index 1ddb17b..66277d6 100644
--- a/vl.c
+++ b/vl.c
@@ -126,6 +126,7 @@  int main(int argc, char **argv)
  #include "hw/xen.h"
  #include "hw/qdev.h"
  #include "hw/loader.h"
+#include "hw/vga_int.h"
  #include "bt-host.h"
  #include "net.h"
  #include "net/slirp.h"
@@ -2585,6 +2586,9 @@  int main(int argc, char **argv, char **envp)
              case QEMU_OPTION_vga:
                  select_vgahw (optarg);
                  break;
+            case QEMU_OPTION_vga_ram_size:
+                set_vga_ram_size(atoi(optarg));
+                break;
              case QEMU_OPTION_g:
                  {
                      const char *p;