diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index d186d797ac..94163e598d 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 8f748b3711..c77b9f9ff1 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); +} - if (bus) { - PCIDevice *d; - uint8_t *pci_conf; +int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base, + unsigned long vga_ram_offset, int vga_ram_size) +{ + VGAState *s; - 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 + 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); - /* 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 b33ab575da..e4a4a46cd4 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]; \