summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2011-04-27 17:25:42 +0300
committerAlon Levy <alevy@redhat.com>2011-05-24 16:33:11 +0300
commitf9b4f1b9eb1ecb3c31043f379d201d62415a78e6 (patch)
treebda9b6d31569dd9ac2c7a23934b599dc08a89671
parent5d5a24fcbe9a0c60e169c853690f41e8236bfbc5 (diff)
xspice: implement map_helper, unmap_helper, add init_qxl_rom
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.
-rw-r--r--src/Makefile.am1
-rw-r--r--src/qxl.h22
-rw-r--r--src/qxl_driver.c15
-rw-r--r--src/spiceqxl_driver.c132
-rw-r--r--src/spiceqxl_driver.h11
5 files changed, 181 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 5112811..efaccb3 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 6bc7aa7..626b1bc 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 */