[Spice-devel] [spice-protocol PATCH 06/46] qxlhw: move ram, rom, ram_header to qxlhw_pci.h

Alon Levy alevy at redhat.com
Tue Apr 10 04:50:02 PDT 2012


Four callbacks are added to the qxlhw struct:
    device_reset
    reset
    map_memory
    unmap_memory

 * The relevant code is moved from qxl_driver.c to qxlhw_pci.c
 * qxl_ring.h gets a qxlhw reference and uses qxlhw_pci_ioport_write
 * pci specific functions are introduced for ram, rom and ram header
  access, they will be dropped once the conversion to qxlhw is complete.
  qxlhw_pci_get_ram_header
  qxlhw_pci_get_ram
  qxlhw_pci_get_rom
---
 src/qxl.h              |   14 --
 src/qxl_driver.c       |  279 ++++-------------------------------
 src/qxl_ring.c         |    9 +-
 src/qxl_ring.h         |    3 +-
 src/qxl_surface.c      |   25 ++--
 src/qxlhw.c            |   20 +++
 src/qxlhw.h            |   16 ++
 src/qxlhw_pci.c        |  379 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/qxlhw_pci.h        |    7 +
 src/spiceqxl_display.c |   19 ++-
 src/spiceqxl_driver.c  |    5 +-
 src/spiceqxl_io_port.c |   17 ++-
 12 files changed, 494 insertions(+), 299 deletions(-)

diff --git a/src/qxl.h b/src/qxl.h
index f3f1446..929a5de 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -126,11 +126,6 @@ struct _qxl_screen_t
 {
     struct qxlhw *              hw;
     /* These are the names QXL uses */
-    void *			ram;	/* Command RAM */
-    void *			ram_physical;
-    void *			vram;	/* Surface RAM */
-    void *			vram_physical;
-    struct QXLRom *		rom;    /* Parameter RAM */
     
     struct qxl_ring *		command_ring;
     struct qxl_ring *		cursor_ring;
@@ -139,9 +134,7 @@ struct _qxl_screen_t
     int				num_modes;
     struct QXLMode *		modes;
     int				io_base;
-    void *			surface0_area;
     long			surface0_size;
-    long			vram_size;
 
     int				virtual_x;
     int				virtual_y;
@@ -353,13 +346,6 @@ static inline void set_surface (PixmapPtr pixmap, qxl_surface_t *surface)
     dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, surface);
 }
 
-static inline struct QXLRam *
-get_ram_header (qxl_screen_t *qxl)
-{
-    return (struct QXLRam *)
-	((uint8_t *)qxl->ram + qxl->rom->ram_header_offset);
-}
-
 /*
  * Images
  */
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 0791821..f56a43e 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -39,11 +39,12 @@
 #include <errno.h>
 #include <time.h>
 #include <stdlib.h>
+#include "assert.h"
 #include "qxl.h"
 #include "qxl_ring.h"
 #include "qxl_mem.h"
-#include "assert.h"
 #include "qxlhw.h"
+#include "qxlhw_pci.h"
 #include "qxl_option_helpers.h"
 
 #ifdef XSPICE
@@ -135,8 +136,7 @@ qxl_available_options (int chipid, int busid)
 #ifndef XSPICE
 static void qxl_wait_for_io_command(qxl_screen_t *qxl)
 {
-    struct QXLRam *ram_header = (void *)(
-        (unsigned long)qxl->ram + qxl->rom->ram_header_offset);
+    struct QXLRam *ram_header = qxlhw_pci_get_ram_header(qxl->hw);
 
     while (!(ram_header->int_pending & QXL_INTERRUPT_IO_CMD)) {
         usleep(1);
@@ -159,20 +159,6 @@ void qxl_update_area(qxl_screen_t *qxl)
 #endif
 }
 
-void qxl_memslot_add(qxl_screen_t *qxl, uint8_t id)
-{
-#ifndef XSPICE
-    if (qxl->pci->revision >= 3) {
-        ioport_write(qxl, QXL_IO_MEMSLOT_ADD_ASYNC, id);
-        qxl_wait_for_io_command(qxl);
-    } else {
-        ioport_write(qxl, QXL_IO_MEMSLOT_ADD, id);
-    }
-#else
-    ioport_write(qxl, QXL_IO_MEMSLOT_ADD, id);
-#endif
-}
-
 void qxl_create_primary(qxl_screen_t *qxl)
 {
 #ifndef XSPICE
@@ -306,8 +292,7 @@ qxl_allocnf (qxl_screen_t *qxl, unsigned long size)
     
     while (!(result = qxl_alloc (qxl->mem, size)))
     {
-	struct QXLRam *ram_header = (void *)(
-	    (unsigned long)qxl->ram + qxl->rom->ram_header_offset);
+	struct QXLRam *ram_header = qxlhw_pci_get_ram_header(qxl->hw);
     
 	/* Rather than go out of memory, we simply tell the
 	 * device to dump everything
@@ -352,139 +337,6 @@ qxl_blank_screen(ScreenPtr pScreen, int mode)
 
 #ifdef XSPICE
 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
-unmap_memory_helper(qxl_screen_t *qxl, int scrnIndex)
-{
-#ifdef XSERVER_LIBPCIACCESS
-    if (qxl->ram)
-	pci_device_unmap_range(qxl->pci, qxl->ram, qxl->pci->regions[0].size);
-    if (qxl->vram)
-	pci_device_unmap_range(qxl->pci, qxl->vram, qxl->pci->regions[1].size);
-    if (qxl->rom)
-	pci_device_unmap_range(qxl->pci, qxl->rom, qxl->pci->regions[2].size);
-#else
-    if (qxl->ram)
-	xf86UnMapVidMem(scrnIndex, qxl->ram, (1 << qxl->pci->size[0]));
-    if (qxl->vram)
-	xf86UnMapVidMem(scrnIndex, qxl->vram, (1 << qxl->pci->size[1]));
-    if (qxl->rom)
-	xf86UnMapVidMem(scrnIndex, qxl->rom, (1 << qxl->pci->size[2]));
-#endif
-}
-
-static void
-map_memory_helper(qxl_screen_t *qxl, int scrnIndex)
-{
-#ifdef XSERVER_LIBPCIACCESS
-    pci_device_map_range(qxl->pci, qxl->pci->regions[0].base_addr,
-			 qxl->pci->regions[0].size,
-			 PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE,
-			 &qxl->ram);
-    qxl->ram_physical = u64_to_pointer (qxl->pci->regions[0].base_addr);
-
-    pci_device_map_range(qxl->pci, qxl->pci->regions[1].base_addr,
-			 qxl->pci->regions[1].size,
-			 PCI_DEV_MAP_FLAG_WRITABLE,
-			 &qxl->vram);
-    qxl->vram_physical = u64_to_pointer (qxl->pci->regions[1].base_addr);
-    qxl->vram_size = qxl->pci->regions[1].size;
-
-    pci_device_map_range(qxl->pci, qxl->pci->regions[2].base_addr,
-			 qxl->pci->regions[2].size, 0,
-			 (void **)&qxl->rom);
-
-    qxl->io_base = qxl->pci->regions[3].base_addr;
-#else
-    qxl->ram = xf86MapPciMem(scrnIndex, VIDMEM_FRAMEBUFFER,
-			     qxl->pci_tag, qxl->pci->memBase[0],
-			     (1 << qxl->pci->size[0]));
-    qxl->ram_physical = (void *)qxl->pci->memBase[0];
-
-    qxl->vram = xf86MapPciMem(scrnIndex, VIDMEM_MMIO | VIDMEM_MMIO_32BIT,
-			      qxl->pci_tag, qxl->pci->memBase[1],
-			      (1 << qxl->pci->size[1]));
-    qxl->vram_physical = (void *)qxl->pci->memBase[1];
-    qxl->vram_size = (1 << qxl->pci->size[1]);
-
-    qxl->rom = xf86MapPciMem(scrnIndex, VIDMEM_MMIO | VIDMEM_MMIO_32BIT,
-			     qxl->pci_tag, qxl->pci->memBase[2],
-			     (1 << qxl->pci->size[2]));
-
-    qxl->io_base = qxl->pci->ioBase[3];
-#endif
-}
-#endif /* XSPICE */
-
-static void
-qxl_unmap_memory(qxl_screen_t *qxl, int scrnIndex)
-{
-#ifdef XSPICE
-    if (qxl->worker) {
-        qxl->worker->stop(qxl->worker);
-        qxl->worker_running = FALSE;
-    }
-#endif
-    unmap_memory_helper(qxl, scrnIndex);
-    qxl->ram = qxl->ram_physical = qxl->vram = qxl->rom = NULL;
-
-    qxl->num_modes = 0;
-    qxl->modes = NULL;
-}
-
-static Bool
-qxl_map_memory(qxl_screen_t *qxl, int scrnIndex)
-{
-    map_memory_helper(qxl, scrnIndex);
-
-    if (!qxl->ram || !qxl->vram || !qxl->rom)
-	return FALSE;
-
-    xf86DrvMsg(scrnIndex, X_INFO, "framebuffer at %p (%d KB)\n",
-	       qxl->ram, qxl->rom->surface0_area_size / 1024);
-
-    xf86DrvMsg(scrnIndex, X_INFO, "command ram at %p (%d KB)\n",
-	       (void *)((unsigned long)qxl->ram + qxl->rom->surface0_area_size),
-	       (qxl->rom->num_pages * getpagesize() - qxl->rom->surface0_area_size)/1024);
-
-    xf86DrvMsg(scrnIndex, X_INFO, "vram at %p (%ld KB)\n",
-	       qxl->vram, qxl->vram_size / 1024);
-
-    xf86DrvMsg(scrnIndex, X_INFO, "rom at %p\n", qxl->rom);
-
-    qxl->num_modes = *(uint32_t *)((uint8_t *)qxl->rom + qxl->rom->modes_offset);
-    qxl->modes = (struct QXLMode *)(((uint8_t *)qxl->rom) + qxl->rom->modes_offset + 4);
-    qxl->surface0_area = qxl->ram;
-    qxl->surface0_size = qxl->rom->surface0_area_size;
-
-    qxl->mem = qxl_mem_create ((void *)((unsigned long)qxl->ram + qxl->surface0_size),
-			       qxl->rom->num_pages * getpagesize() - qxl->surface0_size);
-    qxl->surf_mem = qxl_mem_create ((void *)((unsigned long)qxl->vram), qxl->vram_size);
-
-    return TRUE;
-}
-
-#ifdef XSPICE
-static void
 qxl_save_state(ScrnInfoPtr pScrn)
 {
 }
@@ -513,72 +365,6 @@ qxl_restore_state(ScrnInfoPtr pScrn)
 }
 #endif /* XSPICE */
 
-static uint8_t
-setup_slot(qxl_screen_t *qxl, uint8_t slot_index_offset,
-    unsigned long start_phys_addr, unsigned long end_phys_addr,
-    uint64_t start_virt_addr, uint64_t end_virt_addr)
-{
-    uint64_t high_bits;
-    qxl_memslot_t *slot;
-    uint8_t slot_index;
-    struct QXLRam *ram_header;
-    ram_header = (void *)((unsigned long)qxl->ram + (unsigned long)qxl->rom->ram_header_offset);
-
-    slot_index = qxl->rom->slots_start + slot_index_offset;
-    slot = &qxl->mem_slots[slot_index];
-    slot->start_phys_addr = start_phys_addr;
-    slot->end_phys_addr = end_phys_addr;
-    slot->start_virt_addr = start_virt_addr;
-    slot->end_virt_addr = end_virt_addr;
-
-    ram_header->mem_slot.mem_start = slot->start_phys_addr;
-    ram_header->mem_slot.mem_end = slot->end_phys_addr;
-
-    qxl_memslot_add(qxl, slot_index);
-
-    slot->generation = qxl->rom->slot_generation;
-    
-    high_bits = slot_index << qxl->slot_gen_bits;
-    high_bits |= slot->generation;
-    high_bits <<= (64 - (qxl->slot_gen_bits + qxl->slot_id_bits));
-    slot->high_bits = high_bits;
-    return slot_index;
-}
-
-static void
-qxl_reset (qxl_screen_t *qxl)
-{
-    ioport_write(qxl, QXL_IO_RESET, 0);
-    /* Mem slots */
-    ErrorF ("slots start: %d, slots end: %d\n",
-	    qxl->rom->slots_start,
-	    qxl->rom->slots_end);
-
-    /* Main slot */
-    qxl->n_mem_slots = qxl->rom->slots_end;
-    qxl->slot_gen_bits = qxl->rom->slot_gen_bits;
-    qxl->slot_id_bits = qxl->rom->slot_id_bits;
-    qxl->va_slot_mask = (~(uint64_t)0) >> (qxl->slot_id_bits + qxl->slot_gen_bits);
-
-    qxl->mem_slots = xnfalloc (qxl->n_mem_slots * sizeof (qxl_memslot_t));
-
-#ifdef XSPICE
-    qxl->main_mem_slot = qxl->vram_mem_slot = setup_slot(qxl, 0, 0, ~0, 0, ~0);
-#else /* QXL */
-    qxl->main_mem_slot = setup_slot(qxl, 0,
-        (unsigned long)qxl->ram_physical,
-        (unsigned long)qxl->ram_physical + (unsigned long)qxl->rom->num_pages * getpagesize(),
-        (uint64_t)(uintptr_t)qxl->ram,
-        (uint64_t)(uintptr_t)qxl->ram + (unsigned long)qxl->rom->num_pages * getpagesize()
-    );
-    qxl->vram_mem_slot = setup_slot(qxl, 1,
-        (unsigned long)qxl->vram_physical,
-        (unsigned long)qxl->vram_physical + (unsigned long)qxl->vram_size,
-        (uint64_t)(uintptr_t)qxl->vram,
-        (uint64_t)(uintptr_t)qxl->vram + (uint64_t)qxl->vram_size);
-#endif
-}
-
 static Bool
 qxl_close_screen(int scrnIndex, ScreenPtr pScreen)
 {
@@ -597,13 +383,13 @@ qxl_close_screen(int scrnIndex, ScreenPtr pScreen)
 
 #ifndef XSPICE
     if (!xf86IsPrimaryPci (qxl->pci) && qxl->primary)
-       qxl_reset (qxl);
+       qxlhw_reset (qxl->hw);
 #endif
     
     if (pScrn->vtSema)
     {
         qxl_restore_state(pScrn);
-	qxl_unmap_memory(qxl, scrnIndex);
+	qxlhw_unmap_memory(qxl->hw, scrnIndex);
     }
     pScrn->vtSema = FALSE;
 
@@ -651,7 +437,7 @@ qxl_switch_mode(int scrnIndex, DisplayModePtr p, int flags)
 	qxl_surface_cache_sanity_check (qxl->surface_cache);
     }
 	
-    qxl_reset (qxl);
+    qxlhw_reset (qxl->hw);
     
     ErrorF ("done reset\n");
 
@@ -1058,23 +844,24 @@ qxl_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 {
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     qxl_screen_t *qxl = pScrn->driverPrivate;
-    struct QXLRam *ram_header;
+    struct QXLRom *rom;
     VisualPtr visual;
 
     CHECK_POINT();
 
     qxl->pScrn = pScrn;
 
-    if (!qxl_map_memory(qxl, scrnIndex))
+    if (!qxlhw_map_memory(qxl->hw, scrnIndex))
 	return FALSE;
 
 #ifdef XSPICE
     spiceqxl_screen_init(scrnIndex, pScrn, qxl);
 #endif
-    ram_header = (void *)((unsigned long)qxl->ram + (unsigned long)qxl->rom->ram_header_offset);
+    rom = qxlhw_pci_get_rom(qxl->hw);
+    assert(rom);
     
-    printf ("ram_header at %d\n", qxl->rom->ram_header_offset);
-    printf ("surf0 size: %d\n", qxl->rom->surface0_area_size);
+    printf ("ram_header at %d\n", rom->ram_header_offset);
+    printf ("surf0 size: %d\n", rom->surface0_area_size);
     
     qxl_save_state(pScrn);
     qxl_blank_screen(pScreen, SCREEN_SAVER_ON);
@@ -1132,24 +919,9 @@ qxl_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     qxl->uxa = uxa_driver_alloc ();
     
     /* Set up resources */
-    qxl_reset (qxl);
+    qxlhw_reset (qxl->hw);
     ErrorF ("done reset\n");
 
-#ifndef XSPICE
-    qxl->io_pages = (void *)((unsigned long)qxl->ram);
-    qxl->io_pages_physical = (void *)((unsigned long)qxl->ram_physical);
-#endif
-
-    qxl->command_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->cmd_ring),
-					 sizeof (struct QXLCommand),
-					 QXL_COMMAND_RING_SIZE, QXL_IO_NOTIFY_CMD, qxl);
-    qxl->cursor_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->cursor_ring),
-					sizeof (struct QXLCommand),
-					QXL_CURSOR_RING_SIZE, QXL_IO_NOTIFY_CURSOR, qxl);
-    qxl->release_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->release_ring),
-					 sizeof (uint64_t),
-					 QXL_RELEASE_RING_SIZE, 0, qxl);
-
     qxl->surface_cache = qxl_surface_cache_create (qxl);
     
     /* xf86DPMSInit(pScreen, xf86DPMSSet, 0); */
@@ -1281,8 +1053,9 @@ static Bool
 qxl_check_device(ScrnInfoPtr pScrn, qxl_screen_t *qxl)
 {
     int scrnIndex = pScrn->scrnIndex;
-    struct QXLRom *rom = qxl->rom;
-    struct QXLRam *ram_header = (void *)((unsigned long)qxl->ram + rom->ram_header_offset);
+    struct QXLRom *rom = qxlhw_pci_get_rom(qxl->hw);
+    struct QXLRam *ram_header = qxlhw_pci_get_ram_header(qxl->hw);
+    void *ram = qxlhw_pci_get_ram(qxl->hw);
     
     CHECK_POINT();
     
@@ -1299,7 +1072,7 @@ qxl_check_device(ScrnInfoPtr pScrn, qxl_screen_t *qxl)
 	       rom->log_level);
     
     xf86DrvMsg(scrnIndex, X_INFO, "%d io pages at 0x%lx\n",
-	       rom->num_pages, (unsigned long)qxl->ram);
+	       rom->num_pages, (unsigned long)ram);
     
     xf86DrvMsg(scrnIndex, X_INFO, "RAM header offset: 0x%x\n", rom->ram_header_offset);
 
@@ -1418,6 +1191,7 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
     int *linePitches = NULL;
     DisplayModePtr mode;
     unsigned int max_x = 0, max_y = 0;
+    struct QXLRom *rom;
 
     /* In X server 1.7.5, Xorg -configure will cause this
      * function to get called without a confScreen.
@@ -1471,18 +1245,19 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
     xf86DrvMsg(scrnIndex, X_INFO, "Fallback Cache: %s\n",
 	       qxl->enable_fallback_cache? "Enabled" : "Disabled");
     
-    if (!qxl_map_memory(qxl, scrnIndex))
+    if (!qxlhw_map_memory(qxl->hw, scrnIndex))
 	goto out;
-    
+    rom = qxlhw_pci_get_rom(qxl->hw);
+
 #ifndef XSPICE
     if (!qxl_check_device(pScrn, qxl))
 	goto out;
 #else
     xspice_init_qxl_ram(qxl); /* initialize the rings */
 #endif
-    pScrn->videoRam = (qxl->rom->num_pages * 4096) / 1024;
+    pScrn->videoRam = (rom->num_pages * 4096) / 1024;
     xf86DrvMsg(scrnIndex, X_INFO, "%d KB of video RAM\n", pScrn->videoRam);
-    xf86DrvMsg(scrnIndex, X_INFO, "%d surfaces\n", qxl->rom->n_surfaces);
+    xf86DrvMsg(scrnIndex, X_INFO, "%d surfaces\n", rom->n_surfaces);
 
     /* ddc stuff here */
     
@@ -1523,8 +1298,8 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
            to a virtual size which will not fit into the framebuffer when this
            happens we prefer max width and make height as large as possible */
         if (max_x * max_y * (pScrn->bitsPerPixel / 8) >
-                qxl->rom->surface0_area_size)
-            pScrn->display->virtualY = qxl->rom->surface0_area_size /
+                rom->surface0_area_size)
+            pScrn->display->virtualY = rom->surface0_area_size /
                                        (max_x * (pScrn->bitsPerPixel / 8));
         else
             pScrn->display->virtualY = max_y;
@@ -1575,7 +1350,7 @@ qxl_pre_init(ScrnInfoPtr pScrn, int flags)
 #endif
 
     /* hate */
-    qxl_unmap_memory(qxl, scrnIndex);
+    qxlhw_unmap_memory(qxl->hw, scrnIndex);
     
     CHECK_POINT();
     
diff --git a/src/qxl_ring.c b/src/qxl_ring.c
index 7aea083..b0e646f 100644
--- a/src/qxl_ring.c
+++ b/src/qxl_ring.c
@@ -34,6 +34,7 @@
 #include <sched.h>
 #include "qxl.h"
 #include "qxl_ring.h"
+#include "qxlhw_pci.h"
 
 struct ring
 {
@@ -47,7 +48,7 @@ struct qxl_ring
     int			element_size;
     int			n_elements;
     int			io_port_prod_notify;
-    qxl_screen_t    *qxl;
+    struct qxlhw_pci    *pci;
 };
 
 struct qxl_ring *
@@ -55,7 +56,7 @@ qxl_ring_create (struct qxl_ring_header *header,
 		 int                     element_size,
 		 int                     n_elements,
 		 int			 io_port_prod_notify,
-		 qxl_screen_t           *qxl)
+		 struct qxlhw_pci       *pci)
 {
     struct qxl_ring *ring;
 
@@ -67,7 +68,7 @@ qxl_ring_create (struct qxl_ring_header *header,
     ring->element_size = element_size;
     ring->n_elements = n_elements;
     ring->io_port_prod_notify = io_port_prod_notify;
-    ring->qxl = qxl;
+    ring->pci = pci;
     return ring;
 }
 
@@ -100,7 +101,7 @@ qxl_ring_push (struct qxl_ring *ring,
     mem_barrier();
 
     if (header->prod == header->notify_on_prod) {
-        ioport_write (ring->qxl, ring->io_port_prod_notify, 0);
+        qxlhw_pci_ioport_write (ring->pci, ring->io_port_prod_notify, 0);
     }
 }
 
diff --git a/src/qxl_ring.h b/src/qxl_ring.h
index bcf1e6f..7d71805 100644
--- a/src/qxl_ring.h
+++ b/src/qxl_ring.h
@@ -17,6 +17,7 @@ struct qxl_ring_header {
 #pragma pack(pop)
 
 struct qxl_ring;
+struct qxlhw_pci;
 
 /*
  * Rings
@@ -25,7 +26,7 @@ struct qxl_ring * qxl_ring_create      (struct qxl_ring_header *header,
 					int                     element_size,
 					int                     n_elements,
 					int                     prod_notify,
-					qxl_screen_t           *qxl);
+					struct qxlhw_pci       *pci);
 void              qxl_ring_push        (struct qxl_ring        *ring,
 					const void             *element);
 Bool              qxl_ring_pop         (struct qxl_ring        *ring,
diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index af8d67f..6343337 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -51,6 +51,7 @@
 #include "qxl.h"
 #include "qxl_ring.h"
 #include "qxl_mem.h"
+#include "qxlhw_pci.h"
 
 typedef struct evacuated_surface_t evacuated_surface_t;
 
@@ -125,7 +126,8 @@ struct surface_cache_t
 static Bool
 surface_cache_init (surface_cache_t *cache, qxl_screen_t *qxl)
 {
-    int n_surfaces = qxl->rom->n_surfaces;
+    struct QXLRom *rom = qxlhw_pci_get_rom(qxl->hw);
+    int n_surfaces = rom->n_surfaces;
     int i;
 
     cache->all_surfaces = calloc (n_surfaces, sizeof (qxl_surface_t));
@@ -295,14 +297,14 @@ qxl_surface_t *
 qxl_surface_cache_create_primary (surface_cache_t	*cache,
 				  struct QXLMode	*mode)
 {
-    struct QXLRam *ram_header =
-	(void *)((unsigned long)cache->qxl->ram + cache->qxl->rom->ram_header_offset);
+    qxl_screen_t *qxl = cache->qxl;
+    struct QXLRam *ram_header = qxlhw_pci_get_ram_header(qxl->hw);
+    void *ram = qxlhw_pci_get_ram(qxl->hw);
     struct QXLSurfaceCreate *create = &(ram_header->create_surface);
     pixman_format_code_t format;
     uint8_t *dev_addr;
     pixman_image_t *dev_image, *host_image;
     qxl_surface_t *surface;
-    qxl_screen_t *qxl = cache->qxl;
 
     if (mode->bits == 16)
     {
@@ -314,7 +316,7 @@ qxl_surface_cache_create_primary (surface_cache_t	*cache,
     }
     else
     {
-	xf86DrvMsg (cache->qxl->pScrn->scrnIndex, X_ERROR,
+	xf86DrvMsg (qxl->pScrn->scrnIndex, X_ERROR,
 		    "Unknown bit depth %d\n", mode->bits);
 	return NULL;
     }
@@ -326,11 +328,11 @@ qxl_surface_cache_create_primary (surface_cache_t	*cache,
     create->position = 0; /* What is this? The Windows driver doesn't use it */
     create->flags = 0;
     create->type = QXL_SURF_TYPE_PRIMARY;
-    create->mem = physical_address (cache->qxl, cache->qxl->ram, cache->qxl->main_mem_slot);
+    create->mem = physical_address (qxl, ram, qxl->main_mem_slot);
 
     qxl_create_primary(qxl);
 
-    dev_addr = (uint8_t *)qxl->ram + mode->stride * (mode->y_res - 1);
+    dev_addr = (uint8_t *)ram + mode->stride * (mode->y_res - 1);
 
     dev_image = pixman_image_create_bits (format, mode->x_res, mode->y_res,
 					  (uint32_t *)dev_addr, -mode->stride);
@@ -405,6 +407,7 @@ make_drawable (qxl_screen_t *qxl, int surface, uint8_t type,
 	       /* , pRegion clip */)
 {
     struct QXLDrawable *drawable;
+    struct QXLRom *rom = qxlhw_pci_get_rom(qxl->hw);
     int i;
     
     drawable = qxl_allocnf (qxl, sizeof *drawable);
@@ -435,7 +438,7 @@ make_drawable (qxl_screen_t *qxl, int surface, uint8_t type,
     if (rect)
 	drawable->bbox = *rect;
     
-    drawable->mm_time = qxl->rom->mm_clock;
+    drawable->mm_time = rom->mm_clock;
     
     return drawable;
 }
@@ -545,7 +548,7 @@ surface_send_create (surface_cache_t *cache,
     /* the final + stride is to work around a bug where the device apparently 
      * scribbles after the end of the image
      */
-    qxl_garbage_collect (cache->qxl);
+    qxl_garbage_collect (qxl);
 retry2:
     address = qxl_alloc (qxl->surf_mem, stride * height + stride);
 
@@ -576,7 +579,7 @@ retry:
     surface = surface_get_from_free_list (cache);
     if (!surface)
     {
-	if (!qxl_handle_oom (cache->qxl))
+	if (!qxl_handle_oom (qxl))
 	{
 	    ErrorF ("  Out of surfaces\n");
 	    qxl_free (qxl->surf_mem, address);
@@ -818,7 +821,7 @@ qxl_surface_flush (qxl_surface_t *surface)
 static void
 download_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
 {
-    struct QXLRam *ram_header = get_ram_header (surface->cache->qxl);
+    struct QXLRam *ram_header = qxlhw_pci_get_ram_header (surface->cache->qxl->hw);
     
     ram_header->update_area.top = y1;
     ram_header->update_area.bottom = y2;
diff --git a/src/qxlhw.c b/src/qxlhw.c
index 5673251..a335ee7 100644
--- a/src/qxlhw.c
+++ b/src/qxlhw.c
@@ -17,3 +17,23 @@ struct qxlhw *qxlhw_create(qxl_screen_t *qxl, ScrnInfoPtr pScrn)
     }
     return ret;
 }
+
+void qxlhw_device_reset(struct qxlhw *base)
+{
+        base->device_reset(base);
+}
+
+void qxlhw_reset(struct qxlhw *base)
+{
+        base->reset(base);
+}
+
+Bool qxlhw_map_memory(struct qxlhw *base, int scrnIndex)
+{
+        return base->map_memory(base, scrnIndex);
+}
+
+void qxlhw_unmap_memory(struct qxlhw *base, int scrnIndex)
+{
+        base->unmap_memory(base, scrnIndex);
+}
diff --git a/src/qxlhw.h b/src/qxlhw.h
index 8c8925b..c943cc8 100644
--- a/src/qxlhw.h
+++ b/src/qxlhw.h
@@ -1,10 +1,18 @@
 #ifndef QXLHW_H
 #define QXLHW_H
 
+#include <stdint.h>
+
 #include "qxl.h"
 
 struct qxlhw {
     qxl_screen_t *qxl;
+
+    /* device callbacks */
+    void (*device_reset)(struct qxlhw *base);
+    void (*reset)(struct qxlhw *base);
+    Bool (*map_memory)(struct qxlhw *base, int scrnIndex);
+    void (*unmap_memory)(struct qxlhw *base, int scrnIndex);
 };
 
 void qxlhw_init(struct qxlhw *base, qxl_screen_t *qxl);
@@ -13,4 +21,12 @@ void qxlhw_init(struct qxlhw *base, qxl_screen_t *qxl);
  * to use. currently just PCI. */
 struct qxlhw *qxlhw_create(qxl_screen_t *qxl, ScrnInfoPtr pScrn);
 
+/* reset vs device_reset - device_reset is just the io / drm call,
+ * reset does -- what? (definition, not contents) */
+void qxlhw_device_reset(struct qxlhw *base);
+void qxlhw_reset(struct qxlhw *base);
+
+Bool qxlhw_map_memory(struct qxlhw *base, int scrnIndex);
+void qxlhw_unmap_memory(struct qxlhw *base, int scrnIndex);
+
 #endif // QXLHW_H
diff --git a/src/qxlhw_pci.c b/src/qxlhw_pci.c
index 2d7ac94..d671498 100644
--- a/src/qxlhw_pci.c
+++ b/src/qxlhw_pci.c
@@ -1,11 +1,372 @@
 /* vim: set ts=8 : */
 
+#include <unistd.h>
+
+#include "qxl_ring.h"
+#include "qxl_mem.h"
 #include "qxlhw_pci.h"
 
+#ifdef XSPICE
+#include "spiceqxl_driver.h"
+#endif
+
 struct qxlhw_pci {
     struct qxlhw base;
+
+    /* These are the names QXL uses */
+    void *			ram;	/* Command RAM */
+    void *			ram_physical;
+    void *			vram;	/* Surface RAM */
+    void *			vram_physical;
+    struct QXLRom *		rom;    /* Parameter RAM */
+#ifdef XSPICE
+    struct QXLRom		shadow_rom;    /* Parameter RAM */
+#endif
+
+    struct qxl_ring *		command_ring;
+    struct qxl_ring *		cursor_ring;
+    struct qxl_ring *		release_ring;
+
+    int				io_base;
+    void *			surface0_area;
+    long			vram_size;
+
+    qxl_memslot_t *		mem_slots;
+    uint8_t			n_mem_slots;
+
+    uint8_t			main_mem_slot;
+    uint8_t			slot_id_bits;
+    uint8_t			slot_gen_bits;
+    uint64_t			va_slot_mask;
+
+    /* Commands */
+    struct qxl_mem *		mem;   /* Context for qxl_alloc/free */
+
+    /* Surfaces */
+    struct qxl_mem *		surf_mem;  /* Context for qxl_surf_alloc/free */
+
+    uint8_t			vram_mem_slot;
+#ifndef XSPICE
+    void *			io_pages;
+    void *			io_pages_physical;
+
+    vgaRegRec                   vgaRegs;
+#endif /* XSPICE */
 };
 
+struct QXLRam *
+qxlhw_pci_get_ram_header (struct qxlhw *base)
+{
+    struct qxlhw_pci *hw = (struct qxlhw_pci *)base;
+
+    return (struct QXLRam *)
+	((uint8_t *)hw->ram + hw->rom->ram_header_offset);
+}
+
+void
+qxlhw_pci_ioport_write(struct qxlhw_pci *hw, uint32_t port, uint32_t val)
+{
+#ifdef XSPICE
+/* device to spice-server, now xspice to spice-server */
+    xspice_ioport_write(hw->base.qxl, port, val);
+#else
+    outb(hw->io_base + port, val);
+#endif
+}
+
+#ifndef XSPICE
+static void qxlhw_pci_wait_for_io_command(struct qxlhw_pci *hw)
+{
+    struct QXLRam *ram_header = (void *)(
+        (unsigned long)hw->ram + hw->rom->ram_header_offset);
+
+    while (!(ram_header->int_pending & QXL_INTERRUPT_IO_CMD)) {
+        usleep(1);
+    }
+    ram_header->int_pending &= ~QXL_INTERRUPT_IO_CMD;
+}
+#endif
+
+static void qxlhw_pci_memslot_add(struct qxlhw_pci *hw, uint8_t id)
+{
+#ifndef XSPICE
+    qxl_screen_t *qxl = hw->base.qxl;
+
+    if (qxl->pci->revision >= 3) {
+        qxlhw_pci_ioport_write(hw, QXL_IO_MEMSLOT_ADD_ASYNC, id);
+        qxlhw_pci_wait_for_io_command(hw);
+    } else {
+        qxlhw_pci_ioport_write(hw, QXL_IO_MEMSLOT_ADD, id);
+    }
+#else
+    qxlhw_pci_ioport_write(hw, QXL_IO_MEMSLOT_ADD, id);
+#endif
+}
+
+#ifdef XSPICE
+static void
+unmap_memory_helper(struct qxlhw_pci *hw, int scrnIndex)
+{
+    free(hw->ram);
+    free(hw->vram);
+    free(hw->rom);
+}
+
+static void
+map_memory_helper(struct qxlhw_pci *hw, int scrnIndex)
+{
+    hw->ram = malloc(RAM_SIZE);
+    hw->ram_physical = hw->ram;
+    hw->vram = malloc(VRAM_SIZE);
+    hw->vram_size = VRAM_SIZE;
+    hw->vram_physical = hw->vram;
+    hw->rom = malloc(ROM_SIZE);
+
+    init_qxl_rom(hw->base.qxl, ROM_SIZE);
+}
+#else /* Default */
+static void
+unmap_memory_helper(struct qxlhw_pci *hw, int scrnIndex)
+{
+    qxl_screen_t *qxl = hw->base.qxl;
+
+#ifdef XSERVER_LIBPCIACCESS
+    if (hw->ram)
+	pci_device_unmap_range(qxl->pci, hw->ram, qxl->pci->regions[0].size);
+    if (hw->vram)
+	pci_device_unmap_range(qxl->pci, hw->vram, qxl->pci->regions[1].size);
+    if (hw->rom)
+	pci_device_unmap_range(qxl->pci, hw->rom, qxl->pci->regions[2].size);
+#else
+    if (hw->ram)
+	xf86UnMapVidMem(scrnIndex, hw->ram, (1 << qxl->pci->size[0]));
+    if (hw->vram)
+	xf86UnMapVidMem(scrnIndex, hw->vram, (1 << qxl->pci->size[1]));
+    if (hw->rom)
+	xf86UnMapVidMem(scrnIndex, hw->rom, (1 << qxl->pci->size[2]));
+#endif
+}
+
+static void
+map_memory_helper(struct qxlhw_pci *hw, int scrnIndex)
+{
+    qxl_screen_t *qxl = hw->base.qxl;
+
+#ifdef XSERVER_LIBPCIACCESS
+    pci_device_map_range(qxl->pci, qxl->pci->regions[0].base_addr,
+			 qxl->pci->regions[0].size,
+			 PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE,
+			 &hw->ram);
+    hw->ram_physical = u64_to_pointer (qxl->pci->regions[0].base_addr);
+
+    pci_device_map_range(qxl->pci, qxl->pci->regions[1].base_addr,
+			 qxl->pci->regions[1].size,
+			 PCI_DEV_MAP_FLAG_WRITABLE,
+			 &hw->vram);
+    hw->vram_physical = u64_to_pointer (qxl->pci->regions[1].base_addr);
+    hw->vram_size = qxl->pci->regions[1].size;
+
+    pci_device_map_range(qxl->pci, qxl->pci->regions[2].base_addr,
+			 qxl->pci->regions[2].size, 0,
+			 (void **)&hw->rom);
+
+    hw->io_base = qxl->pci->regions[3].base_addr;
+#else
+    hw->ram = xf86MapPciMem(scrnIndex, VIDMEM_FRAMEBUFFER,
+			     qxl->pci_tag, qxl->pci->memBase[0],
+			     (1 << qxl->pci->size[0]));
+    hw->ram_physical = (void *)qxl->pci->memBase[0];
+
+    hw->vram = xf86MapPciMem(scrnIndex, VIDMEM_MMIO | VIDMEM_MMIO_32BIT,
+			      qxl->pci_tag, qxl->pci->memBase[1],
+			      (1 << qxl->pci->size[1]));
+    hw->vram_physical = (void *)qxl->pci->memBase[1];
+    hw->vram_size = (1 << qxl->pci->size[1]);
+
+    hw->rom = xf86MapPciMem(scrnIndex, VIDMEM_MMIO | VIDMEM_MMIO_32BIT,
+			     qxl->pci_tag, qxl->pci->memBase[2],
+			     (1 << qxl->pci->size[2]));
+
+    hw->io_base = qxl->pci->ioBase[3];
+#endif
+}
+#endif /* XSPICE */
+
+static void
+qxlhw_pci_unmap_memory(struct qxlhw *base, int scrnIndex)
+{
+    struct qxlhw_pci *hw = (struct qxlhw_pci *)base;
+    qxl_screen_t *qxl = base->qxl;
+
+#ifdef XSPICE
+    if (qxl->worker) {
+        qxl->worker->stop(qxl->worker);
+        qxl->worker_running = FALSE;
+    }
+#endif
+    unmap_memory_helper(hw, scrnIndex);
+    hw->ram = hw->ram_physical = hw->vram = hw->rom = NULL;
+
+    /* modes are still in qxl_screen_t. Mode setting in general
+     * needs to be removed in favor of continuous mode setting via
+     * guest agent. */
+    qxl->num_modes = 0;
+    qxl->modes = NULL;
+}
+
+static Bool
+qxlhw_pci_map_memory(struct qxlhw *base, int scrnIndex)
+{
+    struct qxlhw_pci *hw = (struct qxlhw_pci *)base;
+    qxl_screen_t *qxl = base->qxl;
+
+    map_memory_helper(hw, scrnIndex);
+
+    if (!hw->ram || !hw->vram || !hw->rom)
+	return FALSE;
+
+    xf86DrvMsg(scrnIndex, X_INFO, "framebuffer at %p (%d KB)\n",
+	       hw->ram, hw->rom->surface0_area_size / 1024);
+
+    xf86DrvMsg(scrnIndex, X_INFO, "command ram at %p (%d KB)\n",
+	       (void *)((unsigned long)hw->ram + hw->rom->surface0_area_size),
+	       (hw->rom->num_pages * getpagesize() - hw->rom->surface0_area_size)/1024);
+
+    xf86DrvMsg(scrnIndex, X_INFO, "vram at %p (%ld KB)\n",
+	       hw->vram, hw->vram_size / 1024);
+
+    xf86DrvMsg(scrnIndex, X_INFO, "rom at %p\n", hw->rom);
+
+    qxl->num_modes = *(uint32_t *)((uint8_t *)hw->rom + hw->rom->modes_offset);
+    qxl->modes = (struct QXLMode *)(((uint8_t *)hw->rom) + hw->rom->modes_offset + 4);
+    hw->surface0_area = hw->ram;
+    qxl->surface0_size = hw->rom->surface0_area_size;
+
+    hw->mem = qxl_mem_create ((void *)((unsigned long)hw->ram + qxl->surface0_size),
+			       hw->rom->num_pages * getpagesize() - qxl->surface0_size);
+    hw->surf_mem = qxl_mem_create ((void *)((unsigned long)hw->vram), hw->vram_size);
+    // Set the pointers in qxl_screen_t since they are still used:
+    base->qxl->mem = hw->mem;
+    base->qxl->surf_mem = hw->surf_mem;
+
+    return TRUE;
+}
+
+static uint8_t
+setup_slot(struct qxlhw_pci *hw, uint8_t slot_index_offset,
+    unsigned long start_phys_addr, unsigned long end_phys_addr,
+    uint64_t start_virt_addr, uint64_t end_virt_addr)
+{
+    uint64_t high_bits;
+    qxl_memslot_t *slot;
+    uint8_t slot_index;
+    struct QXLRam *ram_header;
+
+    ram_header = (void *)((unsigned long)hw->ram + (unsigned long)hw->rom->ram_header_offset);
+
+    slot_index = hw->rom->slots_start + slot_index_offset;
+    slot = &hw->mem_slots[slot_index];
+    slot->start_phys_addr = start_phys_addr;
+    slot->end_phys_addr = end_phys_addr;
+    slot->start_virt_addr = start_virt_addr;
+    slot->end_virt_addr = end_virt_addr;
+
+    ram_header->mem_slot.mem_start = slot->start_phys_addr;
+    ram_header->mem_slot.mem_end = slot->end_phys_addr;
+
+    qxlhw_pci_memslot_add(hw, slot_index);
+
+    slot->generation = hw->rom->slot_generation;
+
+    high_bits = slot_index << hw->slot_gen_bits;
+    high_bits |= slot->generation;
+    high_bits <<= (64 - (hw->slot_gen_bits + hw->slot_id_bits));
+    slot->high_bits = high_bits;
+    return slot_index;
+}
+
+static void qxlhw_pci_device_reset(struct qxlhw *base)
+{
+    struct qxlhw_pci *hw = (struct qxlhw_pci *)base;
+
+    qxlhw_pci_ioport_write(hw, QXL_IO_RESET, 0);
+}
+
+static void qxlhw_pci_reset(struct qxlhw *base)
+{
+    struct qxlhw_pci *hw = (struct qxlhw_pci *)base;
+    struct QXLRam *ram_header;
+
+    ram_header = (void *)((unsigned long)hw->ram + (unsigned long)hw->rom->ram_header_offset);
+
+    qxlhw_pci_device_reset(&hw->base);
+    ErrorF ("done reset\n");
+
+#ifndef XSPICE
+    hw->io_pages = (void *)((unsigned long)hw->ram);
+    hw->io_pages_physical = (void *)((unsigned long)hw->ram_physical);
+#endif
+
+    hw->command_ring = qxl_ring_create (
+            (struct qxl_ring_header *)&(ram_header->cmd_ring),
+            sizeof (struct QXLCommand),
+            QXL_COMMAND_RING_SIZE, QXL_IO_NOTIFY_CMD, hw);
+    hw->cursor_ring = qxl_ring_create (
+            (struct qxl_ring_header *)&(ram_header->cursor_ring),
+            sizeof (struct QXLCommand),
+            QXL_CURSOR_RING_SIZE, QXL_IO_NOTIFY_CURSOR, hw);
+    hw->release_ring = qxl_ring_create (
+            (struct qxl_ring_header *)&(ram_header->release_ring),
+            sizeof (uint64_t),
+            QXL_RELEASE_RING_SIZE, 0, hw);
+
+    /* Mem slots */
+    ErrorF ("slots start: %d, slots end: %d\n",
+	    hw->rom->slots_start,
+	    hw->rom->slots_end);
+
+    /* Main slot */
+    hw->n_mem_slots = hw->rom->slots_end;
+    hw->slot_gen_bits = hw->rom->slot_gen_bits;
+    hw->slot_id_bits = hw->rom->slot_id_bits;
+    hw->va_slot_mask = (~(uint64_t)0) >> (hw->slot_id_bits + hw->slot_gen_bits);
+
+    hw->mem_slots = xnfalloc (hw->n_mem_slots * sizeof (qxl_memslot_t));
+
+    /* TODO: free required? does this get called twice, from pre_init and init,
+     * or even once per reset? */
+#ifdef XSPICE
+    hw->main_mem_slot = hw->vram_mem_slot = setup_slot(hw, 0, 0, ~0, 0, ~0);
+#else /* QXL */
+    hw->main_mem_slot = setup_slot(hw, 0,
+        (unsigned long)hw->ram_physical,
+        (unsigned long)hw->ram_physical + (unsigned long)hw->rom->num_pages * getpagesize(),
+        (uint64_t)(uintptr_t)hw->ram,
+        (uint64_t)(uintptr_t)hw->ram + (unsigned long)hw->rom->num_pages * getpagesize()
+    );
+    hw->vram_mem_slot = setup_slot(hw, 1,
+        (unsigned long)hw->vram_physical,
+        (unsigned long)hw->vram_physical + (unsigned long)hw->vram_size,
+        (uint64_t)(uintptr_t)hw->vram,
+        (uint64_t)(uintptr_t)hw->vram + (uint64_t)hw->vram_size);
+#endif
+    // Set the pointers in qxl_screen_t since they are still used:
+#ifndef XSPICE
+    base->qxl->io_pages = hw->io_pages;
+    base->qxl->io_pages_physical = hw->io_pages_physical;
+#endif
+    base->qxl->mem_slots = hw->mem_slots;
+    base->qxl->command_ring = hw->command_ring;
+    base->qxl->cursor_ring = hw->cursor_ring;
+    base->qxl->release_ring = hw->release_ring;
+    base->qxl->n_mem_slots = hw->n_mem_slots;
+    base->qxl->slot_gen_bits = hw->slot_gen_bits;
+    base->qxl->slot_id_bits = hw->slot_id_bits;
+    base->qxl->va_slot_mask = hw->va_slot_mask;
+    base->qxl->main_mem_slot = hw->main_mem_slot;
+    base->qxl->vram_mem_slot = hw->vram_mem_slot;
+}
+
 /* public entry point */
 struct qxlhw *create_qxlhw_pci(qxl_screen_t *qxl, ScrnInfoPtr pScrn)
 {
@@ -13,5 +374,23 @@ struct qxlhw *create_qxlhw_pci(qxl_screen_t *qxl, ScrnInfoPtr pScrn)
     struct qxlhw *base = &ret->base;
 
     qxlhw_init(base, qxl);
+    base->device_reset = qxlhw_pci_device_reset;
+    base->reset = qxlhw_pci_reset;
+    base->map_memory = qxlhw_pci_map_memory;
+    base->unmap_memory = qxlhw_pci_unmap_memory;
     return base;
 }
+
+struct QXLRom *qxlhw_pci_get_rom(struct qxlhw *base)
+{
+    struct qxlhw_pci *hw = (struct qxlhw_pci *)base;
+
+    return hw->rom;
+}
+
+void *qxlhw_pci_get_ram(struct qxlhw *base)
+{
+    struct qxlhw_pci *hw = (struct qxlhw_pci *)base;
+
+    return hw->ram;
+}
diff --git a/src/qxlhw_pci.h b/src/qxlhw_pci.h
index 45c58da..c2bddaa 100644
--- a/src/qxlhw_pci.h
+++ b/src/qxlhw_pci.h
@@ -11,4 +11,11 @@ struct qxlhw_pci;
 
 struct qxlhw *create_qxlhw_pci(qxl_screen_t *qxl, ScrnInfoPtr pScrn);
 
+void qxlhw_pci_ioport_write(struct qxlhw_pci *hw, uint32_t io_port, uint32_t val);
+
+struct QXLRam *qxlhw_pci_get_ram_header(struct qxlhw *base);
+void *qxlhw_pci_get_ram(struct qxlhw *base);
+void *qxlhw_pci_get_vram(struct qxlhw *base);
+struct QXLRom *qxlhw_pci_get_rom(struct qxlhw *base);
+
 #endif
diff --git a/src/spiceqxl_display.c b/src/spiceqxl_display.c
index ea61430..85088fa 100644
--- a/src/spiceqxl_display.c
+++ b/src/spiceqxl_display.c
@@ -26,6 +26,7 @@
 #include <spice.h>
 
 #include "qxl.h"
+#include "qxlhw_pci.h"
 #include "spiceqxl_display.h"
 
 #ifndef container_of
@@ -102,18 +103,20 @@ static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
 static void interface_set_compression_level(QXLInstance *sin, int level)
 {
     qxl_screen_t *qxl = container_of(sin, qxl_screen_t, display_sin);
+    struct QXLRom *rom = qxlhw_pci_get_rom(qxl->hw);
 
     dprint(qxl, 1, "%s: %d\n", __FUNCTION__, level);
     qxl->shadow_rom.compression_level = level;
-    qxl->rom->compression_level = level;
+    rom->compression_level = level;
 }
 
 static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
 {
     qxl_screen_t *qxl = container_of(sin, qxl_screen_t, display_sin);
+    struct QXLRom *rom = qxlhw_pci_get_rom(qxl->hw);
 
     qxl->shadow_rom.mm_clock = mm_time;
-    qxl->rom->mm_clock = mm_time;
+    rom->mm_clock = mm_time;
 }
 
 static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
@@ -143,7 +146,7 @@ void qxl_send_events(qxl_screen_t *qxl, int events)
 static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
 {
     qxl_screen_t *qxl = container_of(sin, qxl_screen_t, display_sin);
-    QXLRam *ram = get_ram_header(qxl);
+    QXLRam *ram = qxlhw_pci_get_ram_header(qxl->hw);
     QXLCommandRing *ring;
     QXLCommand *cmd;
     int notify;
@@ -173,7 +176,7 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
 static int interface_req_cmd_notification(QXLInstance *sin)
 {
     qxl_screen_t *qxl = container_of(sin, qxl_screen_t, display_sin);
-    QXLRam *header = get_ram_header(qxl);
+    QXLRam *header = qxlhw_pci_get_ram_header(qxl->hw);
     int wait = 1;
 
     SPICE_RING_CONS_WAIT(&header->cmd_ring, wait);
@@ -183,7 +186,7 @@ static int interface_req_cmd_notification(QXLInstance *sin)
 /* called from spice server thread context only */
 static inline void qxl_push_free_res(qxl_screen_t *qxl, int flush)
 {
-    QXLRam *header = get_ram_header(qxl);
+    QXLRam *header = qxlhw_pci_get_ram_header(qxl->hw);
     QXLReleaseRing *ring = &header->release_ring;
     uint64_t *item;
     int notify;
@@ -222,7 +225,7 @@ static void interface_release_resource(QXLInstance *sin,
                                        struct QXLReleaseInfoExt ext)
 {
     qxl_screen_t *qxl = container_of(sin, qxl_screen_t, display_sin);
-    QXLRam *ram = get_ram_header(qxl);
+    QXLRam *ram = qxlhw_pci_get_ram_header(qxl->hw);
     QXLReleaseRing *ring;
     uint64_t *item, id;
 
@@ -254,7 +257,7 @@ static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *
     qxl_screen_t *qxl = container_of(sin, qxl_screen_t, display_sin);
     QXLCursorRing *ring;
     QXLCommand *cmd;
-    QXLRam *ram = get_ram_header(qxl);
+    QXLRam *ram = qxlhw_pci_get_ram_header(qxl->hw);
     int notify;
 
     ring = &ram->cursor_ring;
@@ -279,7 +282,7 @@ static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *
 static int interface_req_cursor_notification(QXLInstance *sin)
 {
     qxl_screen_t *qxl = container_of(sin, qxl_screen_t, display_sin);
-    QXLRam *ram = get_ram_header(qxl);
+    QXLRam *ram = qxlhw_pci_get_ram_header(qxl->hw);
     int wait = 1;
 
     SPICE_RING_CONS_WAIT(&ram->cursor_ring, wait);
diff --git a/src/spiceqxl_driver.c b/src/spiceqxl_driver.c
index dea5190..d657cf0 100644
--- a/src/spiceqxl_driver.c
+++ b/src/spiceqxl_driver.c
@@ -31,6 +31,7 @@
 #endif
 
 #include "qxl.h"
+#include "qxlhw_pci.h"
 #include "spiceqxl_driver.h"
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
@@ -103,7 +104,7 @@ static QXLMode qxl_modes[] = {
 // TODO - reuse code from qxl.c?
 void init_qxl_rom(qxl_screen_t* qxl, uint32_t rom_size)
 {
-    QXLRom *rom = qxl->rom;
+    QXLRom *rom = qxlhw_pci_get_rom(qxl->hw);
     struct QXLModes *modes = (struct QXLModes *)(rom + 1);
     uint32_t ram_header_size;
     uint32_t surface0_area_size;
@@ -155,5 +156,5 @@ void init_qxl_rom(qxl_screen_t* qxl, uint32_t rom_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?
+    qxl->shadow_rom = *qxlhw_pci_get_rom(qxl->hw);    // TODO - do we need this?
 }
diff --git a/src/spiceqxl_io_port.c b/src/spiceqxl_io_port.c
index edd73dd..0b8acc8 100644
--- a/src/spiceqxl_io_port.c
+++ b/src/spiceqxl_io_port.c
@@ -29,6 +29,7 @@
 #include <spice.h>
 
 #include "qxl.h"
+#include "qxlhw_pci.h"
 #include "spiceqxl_io_port.h"
 
 /* TODO: taken from qemu qxl.c, try to remove dupplication */
@@ -78,7 +79,7 @@ static void __attribute__ ((format (printf, 2, 3))) dprint(int _level, const cha
 
 void xspice_init_qxl_ram(qxl_screen_t *qxl)
 {
-    QXLRam *ram = get_ram_header(qxl);
+    struct QXLRam *ram = qxlhw_pci_get_ram_header(qxl->hw);
     uint64_t *item;
 
     ram->magic       = QXL_RAM_MAGIC;
@@ -93,12 +94,13 @@ void xspice_init_qxl_ram(qxl_screen_t *qxl)
 
 static void qxl_reset_state(qxl_screen_t *qxl)
 {
-    QXLRam *ram = get_ram_header(qxl);
+    QXLRam *ram = qxlhw_pci_get_ram_header(qxl->hw);
+    struct QXLRom *rom = qxlhw_pci_get_rom(qxl->hw);
 
     assert(SPICE_RING_IS_EMPTY(&ram->cmd_ring));
     assert(SPICE_RING_IS_EMPTY(&ram->cursor_ring));
     qxl->shadow_rom.update_id = 0;
-    *qxl->rom = qxl->shadow_rom;
+    *rom = qxl->shadow_rom;
     xspice_init_qxl_ram(qxl);
     qxl->num_free_res = 0;
     qxl->last_release = NULL;
@@ -108,7 +110,7 @@ static void qxl_reset_state(qxl_screen_t *qxl)
 
 static void qxl_check_state(qxl_screen_t *qxl)
 {
-    QXLRam *ram = get_ram_header(qxl);
+    QXLRam *ram = qxlhw_pci_get_ram_header(qxl->hw);
 
     assert(SPICE_RING_IS_EMPTY(&ram->cmd_ring));
     assert(SPICE_RING_IS_EMPTY(&ram->cursor_ring));
@@ -175,7 +177,8 @@ static void qxl_destroy_primary(qxl_screen_t *qxl)
 static void qxl_set_mode(qxl_screen_t *qxl, int modenr)
 {
     struct QXLMode *mode = qxl->modes + modenr;
-    uint64_t devmem = pointer_to_u64(qxl->ram);
+    struct QXLRom *rom = qxlhw_pci_get_rom(qxl->hw);
+    uint64_t devmem = pointer_to_u64(qxlhw_pci_get_ram(qxl->hw));
     QXLSurfaceCreate surface = {
         .width      = mode->x_res,
         .height     = mode->y_res,
@@ -200,13 +203,13 @@ static void qxl_set_mode(qxl_screen_t *qxl, int modenr)
     }
 #endif
     qxl->shadow_rom.mode = modenr;
-    qxl->rom->mode = modenr;
+    rom->mode = modenr;
 }
 
 /* called from Xorg thread - not worker thread! */
 void xspice_ioport_write(qxl_screen_t *qxl, uint32_t io_port, uint32_t val)
 {
-    QXLRam *header = get_ram_header(qxl);
+    QXLRam *header = qxlhw_pci_get_ram_header(qxl->hw);
 
     if (!qxl->worker_running) {
         return;
-- 
1.7.9.3



More information about the Spice-devel mailing list