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 | } | ... | ... |