[Spice-devel] [RFCv2 13/21] xspice: implement map_helper, unmap_helper, add init_qxl_rom

Alon Levy alevy at redhat.com
Fri Apr 29 02:49:51 PDT 2011


Memory is taken from malloc instead of from the pci bar.

Adds shadow_rom to qxl_screen_t.

Introduces init_qxl_rom, which is directly taken from the qxl device
in qemu. Plenty of TODO's added in this commit about various constants
and about factoring out the code to not do this copy paste from qemu.
---
 src/Makefile.am       |    1 +
 src/qxl.h             |   22 ++++++++
 src/qxl_driver.c      |   15 ++++++
 src/spiceqxl_driver.c |  132 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/spiceqxl_driver.h |   11 ++++
 5 files changed, 181 insertions(+), 0 deletions(-)
 create mode 100644 src/spiceqxl_driver.c
 create mode 100644 src/spiceqxl_driver.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 6f2cb56..6ecb17d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -60,6 +60,7 @@ spiceqxl_drv_la_LIBADD = uxa/libuxa.la
 spiceqxl_drv_la_SOURCES =				\
 	qxl.h					\
 	spiceqxl_io_port.c			\
+	spiceqxl_driver.c			\
 	qxl_driver.c				\
 	qxl_image.c				\
 	qxl_surface.c				\
diff --git a/src/qxl.h b/src/qxl.h
index 443871b..6a0138e 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -179,6 +179,11 @@ struct _qxl_screen_t
     void *			vt_surfaces;
 
     OptionInfoRec	options[OPTION_COUNT + 1];
+
+#ifdef XSPICE
+    /* XSpice specific */
+    struct QXLRom		shadow_rom;    /* Parameter RAM */
+#endif /* XSPICE */
 };
 
 static inline uint64_t
@@ -366,4 +371,21 @@ static inline void ioport_write(qxl_screen_t *qxl, int port, int val)
 }
 #endif
 
+#ifdef XSPICE
+
+// Taken from qemu's qxl.c, not sure the values make sense? we
+// only have a single slot, and it is never changed after being added,
+// so not a problem?
+#define MEMSLOT_GENERATION_BITS 8
+#define MEMSLOT_SLOT_BITS 1
+
+// qemu/cpu-all.h
+#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
+// qemu/target-i386/cpu.h
+#define TARGET_PAGE_BITS 12
+
+#define NUM_SURFACES 1024
+
+#endif /* XSPICE */
+
 #endif // QXL_H
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index c77a5f1..eeff535 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -37,6 +37,10 @@
 #include "qxl.h"
 #include "assert.h"
 
+#ifdef XSPICE
+#include "spiceqxl_driver.h"
+#endif /* XSPICE */
+
 #if 0
 #define CHECK_POINT() ErrorF ("%s: %d  (%s)\n", __FILE__, __LINE__, __FUNCTION__);
 #endif
@@ -208,11 +212,22 @@ qxl_blank_screen(ScreenPtr pScreen, int mode)
 static void
 unmap_memory_helper(qxl_screen_t *qxl, int scrnIndex)
 {
+    free(qxl->ram);
+    free(qxl->vram);
+    free(qxl->rom);
 }
 
 static void
 map_memory_helper(qxl_screen_t *qxl, int scrnIndex)
 {
+    qxl->ram = malloc(RAM_SIZE);
+    qxl->ram_physical = qxl->ram;
+    qxl->vram = malloc(VRAM_SIZE);
+    qxl->vram_size = VRAM_SIZE;
+    qxl->vram_physical = qxl->vram;
+    qxl->rom = malloc(ROM_SIZE);
+
+    init_qxl_rom(qxl, ROM_SIZE);
 }
 #else /* Default */
 static void
diff --git a/src/spiceqxl_driver.c b/src/spiceqxl_driver.c
new file mode 100644
index 0000000..07cbeef
--- /dev/null
+++ b/src/spiceqxl_driver.c
@@ -0,0 +1,132 @@
+/* most of the code is still in qxl_driver.c, but for clarity parts are moved
+ * here, and only used / compiled if XSPICE is defined */
+
+#include "qxl.h"
+#include "spiceqxl_driver.h"
+
+// From qxl.c, TODO - factor out
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#define QXL_MODE_EX(x_res, y_res)                 \
+    QXL_MODE_16_32(x_res, y_res, 0),              \
+    QXL_MODE_16_32(y_res, x_res, 1),              \
+    QXL_MODE_16_32(x_res, y_res, 2),              \
+    QXL_MODE_16_32(y_res, x_res, 3)
+
+#define QXL_MODE_16_32(x_res, y_res, orientation) \
+    QXL_MODE(x_res, y_res, 16, orientation),      \
+    QXL_MODE(x_res, y_res, 32, orientation)
+
+#define QXL_MODE(_x, _y, _b, _o)                  \
+    {   .x_res = _x,                              \
+        .y_res = _y,                              \
+        .bits  = _b,                              \
+        .stride = (_x) * (_b) / 8,                \
+        .x_mili = PIXEL_SIZE * (_x),              \
+        .y_mili = PIXEL_SIZE * (_y),              \
+        .orientation = _o,                        \
+    }
+
+#define PIXEL_SIZE 0.2936875 //1280x1024 is 14.8" x 11.9"
+
+#define ALIGN(x, y) (((x)+(y)-1) & ~((y)-1))
+
+static QXLMode qxl_modes[] = {
+    QXL_MODE_EX(640, 480),
+    QXL_MODE_EX(800, 480),
+    QXL_MODE_EX(800, 600),
+    QXL_MODE_EX(832, 624),
+    QXL_MODE_EX(960, 640),
+    QXL_MODE_EX(1024, 600),
+    QXL_MODE_EX(1024, 768),
+    QXL_MODE_EX(1152, 864),
+    QXL_MODE_EX(1152, 870),
+    QXL_MODE_EX(1280, 720),
+    QXL_MODE_EX(1280, 760),
+    QXL_MODE_EX(1280, 768),
+    QXL_MODE_EX(1280, 800),
+    QXL_MODE_EX(1280, 960),
+    QXL_MODE_EX(1280, 1024),
+    QXL_MODE_EX(1360, 768),
+    QXL_MODE_EX(1366, 768),
+    QXL_MODE_EX(1400, 1050),
+    QXL_MODE_EX(1440, 900),
+    QXL_MODE_EX(1600, 900),
+    QXL_MODE_EX(1600, 1200),
+    QXL_MODE_EX(1680, 1050),
+    QXL_MODE_EX(1920, 1080),
+#if VGA_RAM_SIZE >= (16 * 1024 * 1024)
+    /* these modes need more than 8 MB video memory */
+    QXL_MODE_EX(1920, 1200),
+    QXL_MODE_EX(1920, 1440),
+    QXL_MODE_EX(2048, 1536),
+    QXL_MODE_EX(2560, 1440),
+    QXL_MODE_EX(2560, 1600),
+#endif
+#if VGA_RAM_SIZE >= (32 * 1024 * 1024)
+    /* these modes need more than 16 MB video memory */
+    QXL_MODE_EX(2560, 2048),
+    QXL_MODE_EX(2800, 2100),
+    QXL_MODE_EX(3200, 2400),
+#endif
+};
+
+
+// TODO - reuse code from qxl.c?
+void init_qxl_rom(qxl_screen_t* qxl, uint32_t rom_size)
+{
+    QXLRom *rom = qxl->rom;
+    struct QXLModes *modes = (struct QXLModes *)(rom + 1);
+    uint32_t ram_header_size;
+    uint32_t surface0_area_size;
+    uint32_t num_pages;
+    uint32_t fb, maxfb = 0;
+    int i;
+
+    memset(rom, 0, rom_size);
+
+    rom->magic         = QXL_ROM_MAGIC;
+    rom->id            = 0; // TODO - multihead?
+    rom->log_level     = 3;
+    rom->modes_offset  = (sizeof(QXLRom));
+
+    rom->slot_gen_bits = MEMSLOT_GENERATION_BITS;
+    rom->slot_id_bits  = MEMSLOT_SLOT_BITS;
+    rom->slots_start   = 0;
+    rom->slots_end     = 1;
+    rom->n_surfaces    = (NUM_SURFACES);
+
+    modes->n_modes     = (ARRAY_SIZE(qxl_modes));
+    for (i = 0; i < modes->n_modes; i++) {
+        fb = qxl_modes[i].y_res * qxl_modes[i].stride;
+        if (maxfb < fb) {
+            maxfb = fb;
+        }
+        modes->modes[i].id          = (i);
+        modes->modes[i].x_res       = (qxl_modes[i].x_res);
+        modes->modes[i].y_res       = (qxl_modes[i].y_res);
+        modes->modes[i].bits        = (qxl_modes[i].bits);
+        modes->modes[i].stride      = (qxl_modes[i].stride);
+        modes->modes[i].x_mili      = (qxl_modes[i].x_mili);
+        modes->modes[i].y_mili      = (qxl_modes[i].y_mili);
+        modes->modes[i].orientation = (qxl_modes[i].orientation);
+    }
+    if (maxfb < VGA_RAM_SIZE) // TODO - id != 0? (in original code from qxl.c)
+        maxfb = VGA_RAM_SIZE;
+
+    ram_header_size    = ALIGN(sizeof(struct QXLRam), 4096);
+    surface0_area_size = ALIGN(maxfb, 4096);
+    num_pages          = VRAM_SIZE;
+    num_pages         -= ram_header_size;
+    num_pages         -= surface0_area_size;
+    num_pages          = num_pages / TARGET_PAGE_SIZE;
+
+    rom->draw_area_offset   = (0);
+    rom->surface0_area_size = (surface0_area_size);
+    rom->pages_offset       = (surface0_area_size);
+    rom->num_pages          = (num_pages);
+    rom->ram_header_offset  = (VRAM_SIZE - ram_header_size);
+
+    qxl->shadow_rom = *qxl->rom;         // TODO - do we need this?
+}
diff --git a/src/spiceqxl_driver.h b/src/spiceqxl_driver.h
new file mode 100644
index 0000000..25e4ce5
--- /dev/null
+++ b/src/spiceqxl_driver.h
@@ -0,0 +1,11 @@
+#ifndef SPICEQXL_DRIVER_H
+#define SPICEQXL_DRIVER_H 1
+
+#define VGA_RAM_SIZE (16 * 1024 * 1024)
+
+#define RAM_SIZE (128L<<20) // must be >VGA_RAM_SIZE
+#define VRAM_SIZE (128L<<20)
+#define ROM_SIZE (1<<20) // TODO - put correct size
+
+void init_qxl_rom(qxl_screen_t* qxl, uint32_t rom_size);
+#endif /* SPICEQXL_DRIVER_H */
-- 
1.7.4.4



More information about the Spice-devel mailing list