save VGA PCI state
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2113 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
dfd92d3a46
commit
d2269f6f64
|
@ -2905,6 +2905,9 @@ static void cirrus_vga_save(QEMUFile *f, void *opaque)
|
||||||
{
|
{
|
||||||
CirrusVGAState *s = opaque;
|
CirrusVGAState *s = opaque;
|
||||||
|
|
||||||
|
if (s->pci_dev)
|
||||||
|
pci_device_save(s->pci_dev, f);
|
||||||
|
|
||||||
qemu_put_be32s(f, &s->latch);
|
qemu_put_be32s(f, &s->latch);
|
||||||
qemu_put_8s(f, &s->sr_index);
|
qemu_put_8s(f, &s->sr_index);
|
||||||
qemu_put_buffer(f, s->sr, 256);
|
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)
|
static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id)
|
||||||
{
|
{
|
||||||
CirrusVGAState *s = opaque;
|
CirrusVGAState *s = opaque;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (version_id != 1)
|
if (version_id > 2)
|
||||||
return -EINVAL;
|
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_be32s(f, &s->latch);
|
||||||
qemu_get_8s(f, &s->sr_index);
|
qemu_get_8s(f, &s->sr_index);
|
||||||
qemu_get_buffer(f, s->sr, 256);
|
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_invalidate = cirrus_cursor_invalidate;
|
||||||
s->cursor_draw_line = cirrus_cursor_draw_line;
|
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,
|
vga_common_init((VGAState *)s,
|
||||||
ds, vga_ram_base, vga_ram_offset, vga_ram_size);
|
ds, vga_ram_base, vga_ram_offset, vga_ram_size);
|
||||||
cirrus_init_common(s, device_id, 1);
|
cirrus_init_common(s, device_id, 1);
|
||||||
|
s->pci_dev = (PCIDevice *)d;
|
||||||
|
|
||||||
/* setup memory space */
|
/* setup memory space */
|
||||||
/* memory #0 LFB */
|
/* memory #0 LFB */
|
||||||
|
|
132
hw/vga.c
132
hw/vga.c
|
@ -143,9 +143,6 @@ static uint32_t expand4[256];
|
||||||
static uint16_t expand2[256];
|
static uint16_t expand2[256];
|
||||||
static uint8_t expand4to8[16];
|
static uint8_t expand4to8[16];
|
||||||
|
|
||||||
VGAState *vga_state;
|
|
||||||
int vga_io_memory;
|
|
||||||
|
|
||||||
static void vga_screen_dump(void *opaque, const char *filename);
|
static void vga_screen_dump(void *opaque, const char *filename);
|
||||||
|
|
||||||
static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
|
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;
|
VGAState *s = opaque;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (s->pci_dev)
|
||||||
|
pci_device_save(s->pci_dev, f);
|
||||||
|
|
||||||
qemu_put_be32s(f, &s->latch);
|
qemu_put_be32s(f, &s->latch);
|
||||||
qemu_put_8s(f, &s->sr_index);
|
qemu_put_8s(f, &s->sr_index);
|
||||||
qemu_put_buffer(f, s->sr, 8);
|
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)
|
static int vga_load(QEMUFile *f, void *opaque, int version_id)
|
||||||
{
|
{
|
||||||
VGAState *s = opaque;
|
VGAState *s = opaque;
|
||||||
int is_vbe, i;
|
int is_vbe, i, ret;
|
||||||
|
|
||||||
if (version_id != 1)
|
if (version_id > 2)
|
||||||
return -EINVAL;
|
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_be32s(f, &s->latch);
|
||||||
qemu_get_8s(f, &s->sr_index);
|
qemu_get_8s(f, &s->sr_index);
|
||||||
qemu_get_buffer(f, s->sr, 8);
|
qemu_get_buffer(f, s->sr, 8);
|
||||||
|
@ -1711,10 +1717,16 @@ static int vga_load(QEMUFile *f, void *opaque, int version_id)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct PCIVGAState {
|
||||||
|
PCIDevice dev;
|
||||||
|
VGAState vga_state;
|
||||||
|
} PCIVGAState;
|
||||||
|
|
||||||
static void vga_map(PCIDevice *pci_dev, int region_num,
|
static void vga_map(PCIDevice *pci_dev, int region_num,
|
||||||
uint32_t addr, uint32_t size, int type)
|
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) {
|
if (region_num == PCI_ROM_SLOT) {
|
||||||
cpu_register_physical_memory(addr, s->bios_size, s->bios_offset);
|
cpu_register_physical_memory(addr, s->bios_size, s->bios_offset);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1761,24 +1773,14 @@ void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
|
||||||
s->get_resolution = vga_get_resolution;
|
s->get_resolution = vga_get_resolution;
|
||||||
graphic_console_init(s->ds, vga_update_display, vga_invalidate_display,
|
graphic_console_init(s->ds, vga_update_display, vga_invalidate_display,
|
||||||
vga_screen_dump, s);
|
vga_screen_dump, s);
|
||||||
/* XXX: currently needed for display */
|
|
||||||
vga_state = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* used by both ISA and PCI */
|
||||||
int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
|
static void vga_init(VGAState *s)
|
||||||
unsigned long vga_ram_offset, int vga_ram_size,
|
|
||||||
unsigned long vga_bios_offset, int vga_bios_size)
|
|
||||||
{
|
{
|
||||||
VGAState *s;
|
int vga_io_memory;
|
||||||
|
|
||||||
s = qemu_mallocz(sizeof(VGAState));
|
register_savevm("vga", 0, 2, vga_save, vga_load, s);
|
||||||
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_ioport_write(0x3c0, 16, 1, vga_ioport_write, 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);
|
vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write, s);
|
||||||
cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
|
cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
|
||||||
vga_io_memory);
|
vga_io_memory);
|
||||||
|
}
|
||||||
|
|
||||||
if (bus) {
|
int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
|
||||||
PCIDevice *d;
|
unsigned long vga_ram_offset, int vga_ram_size)
|
||||||
uint8_t *pci_conf;
|
{
|
||||||
|
VGAState *s;
|
||||||
|
|
||||||
d = pci_register_device(bus, "VGA",
|
s = qemu_mallocz(sizeof(VGAState));
|
||||||
sizeof(PCIDevice),
|
if (!s)
|
||||||
-1, NULL, NULL);
|
return -1;
|
||||||
pci_conf = d->config;
|
|
||||||
pci_conf[0x00] = 0x34; // dummy VGA (same as Bochs ID)
|
vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
|
||||||
pci_conf[0x01] = 0x12;
|
vga_init(s);
|
||||||
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
|
#ifdef CONFIG_BOCHS_VBE
|
||||||
/* XXX: use optimized standard vga accesses */
|
/* XXX: use optimized standard vga accesses */
|
||||||
cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
|
cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
|
||||||
vga_ram_size, vga_ram_offset);
|
vga_ram_size, vga_ram_offset);
|
||||||
#endif
|
#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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,7 @@
|
||||||
unsigned int vram_size; \
|
unsigned int vram_size; \
|
||||||
unsigned long bios_offset; \
|
unsigned long bios_offset; \
|
||||||
unsigned int bios_size; \
|
unsigned int bios_size; \
|
||||||
|
PCIDevice *pci_dev; \
|
||||||
uint32_t latch; \
|
uint32_t latch; \
|
||||||
uint8_t sr_index; \
|
uint8_t sr_index; \
|
||||||
uint8_t sr[256]; \
|
uint8_t sr[256]; \
|
||||||
|
|
Loading…
Reference in New Issue