summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2011-04-27 17:25:42 +0300
committerAlon Levy <alevy@redhat.com>2011-07-22 04:37:38 +0300
commit3b99e0e25337aa8aecdc7b414ca8021cb12628e1 (patch)
tree1f66f632f05b46c14233426135a994006af3371e
parent267ce8421450bdbe99df8ac0c0b55482a19203ef (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.c130
-rw-r--r--src/spiceqxl_driver.h11
5 files changed, 179 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index a4cb420..d0705e0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -62,6 +62,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..d1c23a2
--- /dev/null
+++ b/src/spiceqxl_driver.c
@@ -0,0 +1,130 @@
+/* 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"
+
+#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 */