Commit d2269f6f64e1b707fc8ea5d43102589c03dd090e
1 parent
dfd92d3a
save VGA PCI state
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2113 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
96 additions
and
56 deletions
hw/cirrus_vga.c
... | ... | @@ -2905,6 +2905,9 @@ static void cirrus_vga_save(QEMUFile *f, void *opaque) |
2905 | 2905 | { |
2906 | 2906 | CirrusVGAState *s = opaque; |
2907 | 2907 | |
2908 | + if (s->pci_dev) | |
2909 | + pci_device_save(s->pci_dev, f); | |
2910 | + | |
2908 | 2911 | qemu_put_be32s(f, &s->latch); |
2909 | 2912 | qemu_put_8s(f, &s->sr_index); |
2910 | 2913 | qemu_put_buffer(f, s->sr, 256); |
... | ... | @@ -2943,10 +2946,17 @@ static void cirrus_vga_save(QEMUFile *f, void *opaque) |
2943 | 2946 | static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id) |
2944 | 2947 | { |
2945 | 2948 | CirrusVGAState *s = opaque; |
2949 | + int ret; | |
2946 | 2950 | |
2947 | - if (version_id != 1) | |
2951 | + if (version_id > 2) | |
2948 | 2952 | return -EINVAL; |
2949 | 2953 | |
2954 | + if (s->pci_dev && version_id >= 2) { | |
2955 | + ret = pci_device_load(s->pci_dev, f); | |
2956 | + if (ret < 0) | |
2957 | + return ret; | |
2958 | + } | |
2959 | + | |
2950 | 2960 | qemu_get_be32s(f, &s->latch); |
2951 | 2961 | qemu_get_8s(f, &s->sr_index); |
2952 | 2962 | qemu_get_buffer(f, s->sr, 256); |
... | ... | @@ -3100,7 +3110,7 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) |
3100 | 3110 | s->cursor_invalidate = cirrus_cursor_invalidate; |
3101 | 3111 | s->cursor_draw_line = cirrus_cursor_draw_line; |
3102 | 3112 | |
3103 | - register_savevm("cirrus_vga", 0, 1, cirrus_vga_save, cirrus_vga_load, s); | |
3113 | + register_savevm("cirrus_vga", 0, 2, cirrus_vga_save, cirrus_vga_load, s); | |
3104 | 3114 | } |
3105 | 3115 | |
3106 | 3116 | /*************************************** |
... | ... | @@ -3178,6 +3188,7 @@ void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, |
3178 | 3188 | vga_common_init((VGAState *)s, |
3179 | 3189 | ds, vga_ram_base, vga_ram_offset, vga_ram_size); |
3180 | 3190 | cirrus_init_common(s, device_id, 1); |
3191 | + s->pci_dev = (PCIDevice *)d; | |
3181 | 3192 | |
3182 | 3193 | /* setup memory space */ |
3183 | 3194 | /* memory #0 LFB */ | ... | ... |
hw/vga.c
... | ... | @@ -143,9 +143,6 @@ static uint32_t expand4[256]; |
143 | 143 | static uint16_t expand2[256]; |
144 | 144 | static uint8_t expand4to8[16]; |
145 | 145 | |
146 | -VGAState *vga_state; | |
147 | -int vga_io_memory; | |
148 | - | |
149 | 146 | static void vga_screen_dump(void *opaque, const char *filename); |
150 | 147 | |
151 | 148 | static uint32_t vga_ioport_read(void *opaque, uint32_t addr) |
... | ... | @@ -1624,6 +1621,9 @@ static void vga_save(QEMUFile *f, void *opaque) |
1624 | 1621 | VGAState *s = opaque; |
1625 | 1622 | int i; |
1626 | 1623 | |
1624 | + if (s->pci_dev) | |
1625 | + pci_device_save(s->pci_dev, f); | |
1626 | + | |
1627 | 1627 | qemu_put_be32s(f, &s->latch); |
1628 | 1628 | qemu_put_8s(f, &s->sr_index); |
1629 | 1629 | qemu_put_buffer(f, s->sr, 8); |
... | ... | @@ -1663,11 +1663,17 @@ static void vga_save(QEMUFile *f, void *opaque) |
1663 | 1663 | static int vga_load(QEMUFile *f, void *opaque, int version_id) |
1664 | 1664 | { |
1665 | 1665 | VGAState *s = opaque; |
1666 | - int is_vbe, i; | |
1666 | + int is_vbe, i, ret; | |
1667 | 1667 | |
1668 | - if (version_id != 1) | |
1668 | + if (version_id > 2) | |
1669 | 1669 | return -EINVAL; |
1670 | 1670 | |
1671 | + if (s->pci_dev && version_id >= 2) { | |
1672 | + ret = pci_device_load(s->pci_dev, f); | |
1673 | + if (ret < 0) | |
1674 | + return ret; | |
1675 | + } | |
1676 | + | |
1671 | 1677 | qemu_get_be32s(f, &s->latch); |
1672 | 1678 | qemu_get_8s(f, &s->sr_index); |
1673 | 1679 | qemu_get_buffer(f, s->sr, 8); |
... | ... | @@ -1711,10 +1717,16 @@ static int vga_load(QEMUFile *f, void *opaque, int version_id) |
1711 | 1717 | return 0; |
1712 | 1718 | } |
1713 | 1719 | |
1720 | +typedef struct PCIVGAState { | |
1721 | + PCIDevice dev; | |
1722 | + VGAState vga_state; | |
1723 | +} PCIVGAState; | |
1724 | + | |
1714 | 1725 | static void vga_map(PCIDevice *pci_dev, int region_num, |
1715 | 1726 | uint32_t addr, uint32_t size, int type) |
1716 | 1727 | { |
1717 | - VGAState *s = vga_state; | |
1728 | + PCIVGAState *d = (PCIVGAState *)pci_dev; | |
1729 | + VGAState *s = &d->vga_state; | |
1718 | 1730 | if (region_num == PCI_ROM_SLOT) { |
1719 | 1731 | cpu_register_physical_memory(addr, s->bios_size, s->bios_offset); |
1720 | 1732 | } else { |
... | ... | @@ -1761,24 +1773,14 @@ void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, |
1761 | 1773 | s->get_resolution = vga_get_resolution; |
1762 | 1774 | graphic_console_init(s->ds, vga_update_display, vga_invalidate_display, |
1763 | 1775 | vga_screen_dump, s); |
1764 | - /* XXX: currently needed for display */ | |
1765 | - vga_state = s; | |
1766 | 1776 | } |
1767 | 1777 | |
1768 | - | |
1769 | -int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, | |
1770 | - unsigned long vga_ram_offset, int vga_ram_size, | |
1771 | - unsigned long vga_bios_offset, int vga_bios_size) | |
1778 | +/* used by both ISA and PCI */ | |
1779 | +static void vga_init(VGAState *s) | |
1772 | 1780 | { |
1773 | - VGAState *s; | |
1781 | + int vga_io_memory; | |
1774 | 1782 | |
1775 | - s = qemu_mallocz(sizeof(VGAState)); | |
1776 | - if (!s) | |
1777 | - return -1; | |
1778 | - | |
1779 | - vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size); | |
1780 | - | |
1781 | - register_savevm("vga", 0, 1, vga_save, vga_load, s); | |
1783 | + register_savevm("vga", 0, 2, vga_save, vga_load, s); | |
1782 | 1784 | |
1783 | 1785 | register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s); |
1784 | 1786 | |
... | ... | @@ -1823,43 +1825,69 @@ int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, |
1823 | 1825 | vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write, s); |
1824 | 1826 | cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000, |
1825 | 1827 | vga_io_memory); |
1828 | +} | |
1829 | + | |
1830 | +int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base, | |
1831 | + unsigned long vga_ram_offset, int vga_ram_size) | |
1832 | +{ | |
1833 | + VGAState *s; | |
1834 | + | |
1835 | + s = qemu_mallocz(sizeof(VGAState)); | |
1836 | + if (!s) | |
1837 | + return -1; | |
1838 | + | |
1839 | + vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size); | |
1840 | + vga_init(s); | |
1826 | 1841 | |
1827 | - if (bus) { | |
1828 | - PCIDevice *d; | |
1829 | - uint8_t *pci_conf; | |
1830 | - | |
1831 | - d = pci_register_device(bus, "VGA", | |
1832 | - sizeof(PCIDevice), | |
1833 | - -1, NULL, NULL); | |
1834 | - pci_conf = d->config; | |
1835 | - pci_conf[0x00] = 0x34; // dummy VGA (same as Bochs ID) | |
1836 | - pci_conf[0x01] = 0x12; | |
1837 | - pci_conf[0x02] = 0x11; | |
1838 | - pci_conf[0x03] = 0x11; | |
1839 | - pci_conf[0x0a] = 0x00; // VGA controller | |
1840 | - pci_conf[0x0b] = 0x03; | |
1841 | - pci_conf[0x0e] = 0x00; // header_type | |
1842 | - | |
1843 | - /* XXX: vga_ram_size must be a power of two */ | |
1844 | - pci_register_io_region(d, 0, vga_ram_size, | |
1845 | - PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map); | |
1846 | - if (vga_bios_size != 0) { | |
1847 | - unsigned int bios_total_size; | |
1848 | - s->bios_offset = vga_bios_offset; | |
1849 | - s->bios_size = vga_bios_size; | |
1850 | - /* must be a power of two */ | |
1851 | - bios_total_size = 1; | |
1852 | - while (bios_total_size < vga_bios_size) | |
1853 | - bios_total_size <<= 1; | |
1854 | - pci_register_io_region(d, PCI_ROM_SLOT, bios_total_size, | |
1855 | - PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map); | |
1856 | - } | |
1857 | - } else { | |
1858 | 1842 | #ifdef CONFIG_BOCHS_VBE |
1859 | - /* XXX: use optimized standard vga accesses */ | |
1860 | - cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, | |
1861 | - vga_ram_size, vga_ram_offset); | |
1843 | + /* XXX: use optimized standard vga accesses */ | |
1844 | + cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, | |
1845 | + vga_ram_size, vga_ram_offset); | |
1862 | 1846 | #endif |
1847 | + return 0; | |
1848 | +} | |
1849 | + | |
1850 | +int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, | |
1851 | + unsigned long vga_ram_offset, int vga_ram_size, | |
1852 | + unsigned long vga_bios_offset, int vga_bios_size) | |
1853 | +{ | |
1854 | + PCIVGAState *d; | |
1855 | + VGAState *s; | |
1856 | + uint8_t *pci_conf; | |
1857 | + | |
1858 | + d = (PCIVGAState *)pci_register_device(bus, "VGA", | |
1859 | + sizeof(PCIVGAState), | |
1860 | + -1, NULL, NULL); | |
1861 | + if (!d) | |
1862 | + return -1; | |
1863 | + s = &d->vga_state; | |
1864 | + | |
1865 | + vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size); | |
1866 | + vga_init(s); | |
1867 | + s->pci_dev = &d->dev; | |
1868 | + | |
1869 | + pci_conf = d->dev.config; | |
1870 | + pci_conf[0x00] = 0x34; // dummy VGA (same as Bochs ID) | |
1871 | + pci_conf[0x01] = 0x12; | |
1872 | + pci_conf[0x02] = 0x11; | |
1873 | + pci_conf[0x03] = 0x11; | |
1874 | + pci_conf[0x0a] = 0x00; // VGA controller | |
1875 | + pci_conf[0x0b] = 0x03; | |
1876 | + pci_conf[0x0e] = 0x00; // header_type | |
1877 | + | |
1878 | + /* XXX: vga_ram_size must be a power of two */ | |
1879 | + pci_register_io_region(&d->dev, 0, vga_ram_size, | |
1880 | + PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map); | |
1881 | + if (vga_bios_size != 0) { | |
1882 | + unsigned int bios_total_size; | |
1883 | + s->bios_offset = vga_bios_offset; | |
1884 | + s->bios_size = vga_bios_size; | |
1885 | + /* must be a power of two */ | |
1886 | + bios_total_size = 1; | |
1887 | + while (bios_total_size < vga_bios_size) | |
1888 | + bios_total_size <<= 1; | |
1889 | + pci_register_io_region(&d->dev, PCI_ROM_SLOT, bios_total_size, | |
1890 | + PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map); | |
1863 | 1891 | } |
1864 | 1892 | return 0; |
1865 | 1893 | } | ... | ... |