commit d2269f6f64e1b707fc8ea5d43102589c03dd090e
Author: bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Date:   Thu Aug 17 10:44:00 2006 +0000

    save VGA PCI state
    
    
    git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2113 c046a42c-6fe2-441c-8c8c-71466251a162

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index d186d79..94163e5 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2905,6 +2905,9 @@ static void cirrus_vga_save(QEMUFile *f, void *opaque)
 {
     CirrusVGAState *s = opaque;
 
+    if (s->pci_dev)
+        pci_device_save(s->pci_dev, f);
+
     qemu_put_be32s(f, &s->latch);
     qemu_put_8s(f, &s->sr_index);
     qemu_put_buffer(f, s->sr, 256);
@@ -2943,10 +2946,17 @@ static void cirrus_vga_save(QEMUFile *f, void *opaque)
 static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id)
 {
     CirrusVGAState *s = opaque;
+    int ret;
 
-    if (version_id != 1)
+    if (version_id > 2)
         return -EINVAL;
 
+    if (s->pci_dev && version_id >= 2) {
+        ret = pci_device_load(s->pci_dev, f);
+        if (ret < 0)
+            return ret;
+    }
+
     qemu_get_be32s(f, &s->latch);
     qemu_get_8s(f, &s->sr_index);
     qemu_get_buffer(f, s->sr, 256);
@@ -3100,7 +3110,7 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
     s->cursor_invalidate = cirrus_cursor_invalidate;
     s->cursor_draw_line = cirrus_cursor_draw_line;
 
-    register_savevm("cirrus_vga", 0, 1, cirrus_vga_save, cirrus_vga_load, s);
+    register_savevm("cirrus_vga", 0, 2, cirrus_vga_save, cirrus_vga_load, s);
 }
 
 /***************************************
@@ -3178,6 +3188,7 @@ void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
     vga_common_init((VGAState *)s, 
                     ds, vga_ram_base, vga_ram_offset, vga_ram_size);
     cirrus_init_common(s, device_id, 1);
+    s->pci_dev = (PCIDevice *)d;
 
     /* setup memory space */
     /* memory #0 LFB */
diff --git a/hw/vga.c b/hw/vga.c
index 8f748b3..c77b9f9 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -143,9 +143,6 @@ static uint32_t expand4[256];
 static uint16_t expand2[256];
 static uint8_t expand4to8[16];
 
-VGAState *vga_state;
-int vga_io_memory;
-
 static void vga_screen_dump(void *opaque, const char *filename);
 
 static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
@@ -1624,6 +1621,9 @@ static void vga_save(QEMUFile *f, void *opaque)
     VGAState *s = opaque;
     int i;
 
+    if (s->pci_dev)
+        pci_device_save(s->pci_dev, f);
+
     qemu_put_be32s(f, &s->latch);
     qemu_put_8s(f, &s->sr_index);
     qemu_put_buffer(f, s->sr, 8);
@@ -1663,11 +1663,17 @@ static void vga_save(QEMUFile *f, void *opaque)
 static int vga_load(QEMUFile *f, void *opaque, int version_id)
 {
     VGAState *s = opaque;
-    int is_vbe, i;
+    int is_vbe, i, ret;
 
-    if (version_id != 1)
+    if (version_id > 2)
         return -EINVAL;
 
+    if (s->pci_dev && version_id >= 2) {
+        ret = pci_device_load(s->pci_dev, f);
+        if (ret < 0)
+            return ret;
+    }
+
     qemu_get_be32s(f, &s->latch);
     qemu_get_8s(f, &s->sr_index);
     qemu_get_buffer(f, s->sr, 8);
@@ -1711,10 +1717,16 @@ static int vga_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
+typedef struct PCIVGAState {
+    PCIDevice dev;
+    VGAState vga_state;
+} PCIVGAState;
+
 static void vga_map(PCIDevice *pci_dev, int region_num, 
                     uint32_t addr, uint32_t size, int type)
 {
-    VGAState *s = vga_state;
+    PCIVGAState *d = (PCIVGAState *)pci_dev;
+    VGAState *s = &d->vga_state;
     if (region_num == PCI_ROM_SLOT) {
         cpu_register_physical_memory(addr, s->bios_size, s->bios_offset);
     } else {
@@ -1761,24 +1773,14 @@ void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
     s->get_resolution = vga_get_resolution;
     graphic_console_init(s->ds, vga_update_display, vga_invalidate_display,
                          vga_screen_dump, s);
-    /* XXX: currently needed for display */
-    vga_state = s;
 }
 
-
-int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, 
-                   unsigned long vga_ram_offset, int vga_ram_size,
-                   unsigned long vga_bios_offset, int vga_bios_size)
+/* used by both ISA and PCI */
+static void vga_init(VGAState *s)
 {
-    VGAState *s;
+    int vga_io_memory;
 
-    s = qemu_mallocz(sizeof(VGAState));
-    if (!s)
-        return -1;
-
-    vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
-
-    register_savevm("vga", 0, 1, vga_save, vga_load, s);
+    register_savevm("vga", 0, 2, vga_save, vga_load, s);
 
     register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
 
@@ -1823,43 +1825,69 @@ int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
     vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write, s);
     cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000, 
                                  vga_io_memory);
+}
+
+int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base, 
+                 unsigned long vga_ram_offset, int vga_ram_size)
+{
+    VGAState *s;
+
+    s = qemu_mallocz(sizeof(VGAState));
+    if (!s)
+        return -1;
+
+    vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
+    vga_init(s);
 
-    if (bus) {
-        PCIDevice *d;
-        uint8_t *pci_conf;
-
-        d = pci_register_device(bus, "VGA", 
-                                sizeof(PCIDevice),
-                                -1, NULL, NULL);
-        pci_conf = d->config;
-        pci_conf[0x00] = 0x34; // dummy VGA (same as Bochs ID)
-        pci_conf[0x01] = 0x12;
-        pci_conf[0x02] = 0x11;
-        pci_conf[0x03] = 0x11;
-        pci_conf[0x0a] = 0x00; // VGA controller 
-        pci_conf[0x0b] = 0x03;
-        pci_conf[0x0e] = 0x00; // header_type
-
-        /* XXX: vga_ram_size must be a power of two */
-        pci_register_io_region(d, 0, vga_ram_size, 
-                               PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
-        if (vga_bios_size != 0) {
-            unsigned int bios_total_size;
-            s->bios_offset = vga_bios_offset;
-            s->bios_size = vga_bios_size;
-            /* must be a power of two */
-            bios_total_size = 1;
-            while (bios_total_size < vga_bios_size)
-                bios_total_size <<= 1;
-            pci_register_io_region(d, PCI_ROM_SLOT, bios_total_size, 
-                                   PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
-        }
-    } else {
 #ifdef CONFIG_BOCHS_VBE
-        /* XXX: use optimized standard vga accesses */
-        cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, 
-                                     vga_ram_size, vga_ram_offset);
+    /* XXX: use optimized standard vga accesses */
+    cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, 
+                                 vga_ram_size, vga_ram_offset);
 #endif
+    return 0;
+}
+
+int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, 
+                 unsigned long vga_ram_offset, int vga_ram_size,
+                 unsigned long vga_bios_offset, int vga_bios_size)
+{
+    PCIVGAState *d;
+    VGAState *s;
+    uint8_t *pci_conf;
+    
+    d = (PCIVGAState *)pci_register_device(bus, "VGA", 
+                                           sizeof(PCIVGAState),
+                                           -1, NULL, NULL);
+    if (!d)
+        return -1;
+    s = &d->vga_state;
+    
+    vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
+    vga_init(s);
+    s->pci_dev = &d->dev;
+    
+    pci_conf = d->dev.config;
+    pci_conf[0x00] = 0x34; // dummy VGA (same as Bochs ID)
+    pci_conf[0x01] = 0x12;
+    pci_conf[0x02] = 0x11;
+    pci_conf[0x03] = 0x11;
+    pci_conf[0x0a] = 0x00; // VGA controller 
+    pci_conf[0x0b] = 0x03;
+    pci_conf[0x0e] = 0x00; // header_type
+    
+    /* XXX: vga_ram_size must be a power of two */
+    pci_register_io_region(&d->dev, 0, vga_ram_size, 
+                           PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
+    if (vga_bios_size != 0) {
+        unsigned int bios_total_size;
+        s->bios_offset = vga_bios_offset;
+        s->bios_size = vga_bios_size;
+        /* must be a power of two */
+        bios_total_size = 1;
+        while (bios_total_size < vga_bios_size)
+            bios_total_size <<= 1;
+        pci_register_io_region(&d->dev, PCI_ROM_SLOT, bios_total_size, 
+                               PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
     }
     return 0;
 }
diff --git a/hw/vga_int.h b/hw/vga_int.h
index b33ab57..e4a4a46 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -83,6 +83,7 @@
     unsigned int vram_size;                                             \
     unsigned long bios_offset;                                          \
     unsigned int bios_size;                                             \
+    PCIDevice *pci_dev;                                                 \
     uint32_t latch;                                                     \
     uint8_t sr_index;                                                   \
     uint8_t sr[256];                                                    \
