diff options
-rw-r--r-- | hw/e1000.c | 185 | ||||
-rw-r--r-- | hw/eepro100.c | 194 | ||||
-rw-r--r-- | hw/eeprom93xx.c | 102 | ||||
-rw-r--r-- | hw/fdc.c | 2 | ||||
-rw-r--r-- | hw/hw.h | 196 | ||||
-rw-r--r-- | hw/ide/cmd646.c | 2 | ||||
-rw-r--r-- | hw/ide/core.c | 153 | ||||
-rw-r--r-- | hw/ide/internal.h | 18 | ||||
-rw-r--r-- | hw/ide/isa.c | 31 | ||||
-rw-r--r-- | hw/ide/macio.c | 42 | ||||
-rw-r--r-- | hw/ide/microdrive.c | 63 | ||||
-rw-r--r-- | hw/ide/mmio.c | 53 | ||||
-rw-r--r-- | hw/ide/pci.c | 95 | ||||
-rw-r--r-- | hw/ide/pci.h | 4 | ||||
-rw-r--r-- | hw/ide/piix.c | 2 | ||||
-rw-r--r-- | hw/lance.c | 3 | ||||
-rw-r--r-- | hw/lsi53c895a.c | 246 | ||||
-rw-r--r-- | hw/mc146818rtc.c | 220 | ||||
-rw-r--r-- | hw/ne2000-isa.c | 2 | ||||
-rw-r--r-- | hw/ne2000.c | 133 | ||||
-rw-r--r-- | hw/ne2000.h | 3 | ||||
-rw-r--r-- | hw/parallel.c | 23 | ||||
-rw-r--r-- | hw/pc.h | 2 | ||||
-rw-r--r-- | hw/pci-hotplug.c | 56 | ||||
-rw-r--r-- | hw/pci.c | 2 | ||||
-rw-r--r-- | hw/pci_ids.h | 1 | ||||
-rw-r--r-- | hw/pcnet.c | 106 | ||||
-rw-r--r-- | hw/pcnet.h | 3 | ||||
-rw-r--r-- | hw/rtl8139.c | 347 | ||||
-rw-r--r-- | hw/serial.c | 37 | ||||
-rw-r--r-- | hw/usb-uhci.c | 83 | ||||
-rw-r--r-- | hw/vga-isa-mm.c | 2 | ||||
-rw-r--r-- | hw/vga-isa.c | 2 | ||||
-rw-r--r-- | hw/vga-pci.c | 34 | ||||
-rw-r--r-- | hw/vga.c | 132 | ||||
-rw-r--r-- | hw/vga_int.h | 7 | ||||
-rw-r--r-- | hw/vmware_vga.c | 168 | ||||
-rw-r--r-- | hw/wdt_i6300esb.c | 81 | ||||
-rw-r--r-- | hw/wdt_ib700.c | 53 | ||||
-rw-r--r-- | migration.c | 6 | ||||
-rw-r--r-- | migration.h | 6 | ||||
-rw-r--r-- | monitor.c | 11 | ||||
-rw-r--r-- | posix-aio-compat.c | 65 | ||||
-rw-r--r-- | qemu-char.c | 6 | ||||
-rw-r--r-- | qemu-config.c | 3 | ||||
-rw-r--r-- | qemu-monitor.hx | 27 | ||||
-rw-r--r-- | savevm.c | 54 | ||||
-rw-r--r-- | sysemu.h | 3 | ||||
-rw-r--r-- | target-i386/machine.c | 2 |
49 files changed, 1261 insertions, 1810 deletions
diff --git a/hw/e1000.c b/hw/e1000.c index 924c40dbd..5f61f4e83 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -881,110 +881,88 @@ e1000_mmio_readw(void *opaque, target_phys_addr_t addr) (8 * (addr & 3))) & 0xffff; } -static const int mac_regtosave[] = { - CTRL, EECD, EERD, GPRC, GPTC, ICR, ICS, IMC, IMS, - LEDCTL, MANC, MDIC, MPC, PBA, RCTL, RDBAH, RDBAL, RDH, - RDLEN, RDT, STATUS, SWSM, TCTL, TDBAH, TDBAL, TDH, TDLEN, - TDT, TORH, TORL, TOTH, TOTL, TPR, TPT, TXDCTL, WUFC, - VET, -}; -enum { MAC_NSAVE = ARRAY_SIZE(mac_regtosave) }; - -static const struct { - int size; - int array0; -} mac_regarraystosave[] = { {32, RA}, {128, MTA}, {128, VFTA} }; -enum { MAC_NARRAYS = ARRAY_SIZE(mac_regarraystosave) }; - -static void -nic_save(QEMUFile *f, void *opaque) +static bool is_version_1(void *opaque, int version_id) { - E1000State *s = opaque; - int i, j; - - pci_device_save(&s->dev, f); - qemu_put_be32(f, 0); - qemu_put_be32s(f, &s->rxbuf_size); - qemu_put_be32s(f, &s->rxbuf_min_shift); - qemu_put_be32s(f, &s->eecd_state.val_in); - qemu_put_be16s(f, &s->eecd_state.bitnum_in); - qemu_put_be16s(f, &s->eecd_state.bitnum_out); - qemu_put_be16s(f, &s->eecd_state.reading); - qemu_put_be32s(f, &s->eecd_state.old_eecd); - qemu_put_8s(f, &s->tx.ipcss); - qemu_put_8s(f, &s->tx.ipcso); - qemu_put_be16s(f, &s->tx.ipcse); - qemu_put_8s(f, &s->tx.tucss); - qemu_put_8s(f, &s->tx.tucso); - qemu_put_be16s(f, &s->tx.tucse); - qemu_put_be32s(f, &s->tx.paylen); - qemu_put_8s(f, &s->tx.hdr_len); - qemu_put_be16s(f, &s->tx.mss); - qemu_put_be16s(f, &s->tx.size); - qemu_put_be16s(f, &s->tx.tso_frames); - qemu_put_8s(f, &s->tx.sum_needed); - qemu_put_s8s(f, &s->tx.ip); - qemu_put_s8s(f, &s->tx.tcp); - qemu_put_buffer(f, s->tx.header, sizeof s->tx.header); - qemu_put_buffer(f, s->tx.data, sizeof s->tx.data); - for (i = 0; i < 64; i++) - qemu_put_be16s(f, s->eeprom_data + i); - for (i = 0; i < 0x20; i++) - qemu_put_be16s(f, s->phy_reg + i); - for (i = 0; i < MAC_NSAVE; i++) - qemu_put_be32s(f, s->mac_reg + mac_regtosave[i]); - for (i = 0; i < MAC_NARRAYS; i++) - for (j = 0; j < mac_regarraystosave[i].size; j++) - qemu_put_be32s(f, - s->mac_reg + mac_regarraystosave[i].array0 + j); + return version_id == 1; } -static int -nic_load(QEMUFile *f, void *opaque, int version_id) -{ - E1000State *s = opaque; - int i, j, ret; - - if ((ret = pci_device_load(&s->dev, f)) < 0) - return ret; - if (version_id == 1) - qemu_get_sbe32s(f, &i); /* once some unused instance id */ - qemu_get_be32(f); /* Ignored. Was mmio_base. */ - qemu_get_be32s(f, &s->rxbuf_size); - qemu_get_be32s(f, &s->rxbuf_min_shift); - qemu_get_be32s(f, &s->eecd_state.val_in); - qemu_get_be16s(f, &s->eecd_state.bitnum_in); - qemu_get_be16s(f, &s->eecd_state.bitnum_out); - qemu_get_be16s(f, &s->eecd_state.reading); - qemu_get_be32s(f, &s->eecd_state.old_eecd); - qemu_get_8s(f, &s->tx.ipcss); - qemu_get_8s(f, &s->tx.ipcso); - qemu_get_be16s(f, &s->tx.ipcse); - qemu_get_8s(f, &s->tx.tucss); - qemu_get_8s(f, &s->tx.tucso); - qemu_get_be16s(f, &s->tx.tucse); - qemu_get_be32s(f, &s->tx.paylen); - qemu_get_8s(f, &s->tx.hdr_len); - qemu_get_be16s(f, &s->tx.mss); - qemu_get_be16s(f, &s->tx.size); - qemu_get_be16s(f, &s->tx.tso_frames); - qemu_get_8s(f, &s->tx.sum_needed); - qemu_get_s8s(f, &s->tx.ip); - qemu_get_s8s(f, &s->tx.tcp); - qemu_get_buffer(f, s->tx.header, sizeof s->tx.header); - qemu_get_buffer(f, s->tx.data, sizeof s->tx.data); - for (i = 0; i < 64; i++) - qemu_get_be16s(f, s->eeprom_data + i); - for (i = 0; i < 0x20; i++) - qemu_get_be16s(f, s->phy_reg + i); - for (i = 0; i < MAC_NSAVE; i++) - qemu_get_be32s(f, s->mac_reg + mac_regtosave[i]); - for (i = 0; i < MAC_NARRAYS; i++) - for (j = 0; j < mac_regarraystosave[i].size; j++) - qemu_get_be32s(f, - s->mac_reg + mac_regarraystosave[i].array0 + j); - return 0; -} +static const VMStateDescription vmstate_e1000 = { + .name = "e1000", + .version_id = 2, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_PCI_DEVICE(dev, E1000State), + VMSTATE_UNUSED_TEST(is_version_1, 4), /* was instance id */ + VMSTATE_UNUSED(4), /* Was mmio_base. */ + VMSTATE_UINT32(rxbuf_size, E1000State), + VMSTATE_UINT32(rxbuf_min_shift, E1000State), + VMSTATE_UINT32(eecd_state.val_in, E1000State), + VMSTATE_UINT16(eecd_state.bitnum_in, E1000State), + VMSTATE_UINT16(eecd_state.bitnum_out, E1000State), + VMSTATE_UINT16(eecd_state.reading, E1000State), + VMSTATE_UINT32(eecd_state.old_eecd, E1000State), + VMSTATE_UINT8(tx.ipcss, E1000State), + VMSTATE_UINT8(tx.ipcso, E1000State), + VMSTATE_UINT16(tx.ipcse, E1000State), + VMSTATE_UINT8(tx.tucss, E1000State), + VMSTATE_UINT8(tx.tucso, E1000State), + VMSTATE_UINT16(tx.tucse, E1000State), + VMSTATE_UINT32(tx.paylen, E1000State), + VMSTATE_UINT8(tx.hdr_len, E1000State), + VMSTATE_UINT16(tx.mss, E1000State), + VMSTATE_UINT16(tx.size, E1000State), + VMSTATE_UINT16(tx.tso_frames, E1000State), + VMSTATE_UINT8(tx.sum_needed, E1000State), + VMSTATE_INT8(tx.ip, E1000State), + VMSTATE_INT8(tx.tcp, E1000State), + VMSTATE_BUFFER(tx.header, E1000State), + VMSTATE_BUFFER(tx.data, E1000State), + VMSTATE_UINT16_ARRAY(eeprom_data, E1000State, 64), + VMSTATE_UINT16_ARRAY(phy_reg, E1000State, 0x20), + VMSTATE_UINT32(mac_reg[CTRL], E1000State), + VMSTATE_UINT32(mac_reg[EECD], E1000State), + VMSTATE_UINT32(mac_reg[EERD], E1000State), + VMSTATE_UINT32(mac_reg[GPRC], E1000State), + VMSTATE_UINT32(mac_reg[GPTC], E1000State), + VMSTATE_UINT32(mac_reg[ICR], E1000State), + VMSTATE_UINT32(mac_reg[ICS], E1000State), + VMSTATE_UINT32(mac_reg[IMC], E1000State), + VMSTATE_UINT32(mac_reg[IMS], E1000State), + VMSTATE_UINT32(mac_reg[LEDCTL], E1000State), + VMSTATE_UINT32(mac_reg[MANC], E1000State), + VMSTATE_UINT32(mac_reg[MDIC], E1000State), + VMSTATE_UINT32(mac_reg[MPC], E1000State), + VMSTATE_UINT32(mac_reg[PBA], E1000State), + VMSTATE_UINT32(mac_reg[RCTL], E1000State), + VMSTATE_UINT32(mac_reg[RDBAH], E1000State), + VMSTATE_UINT32(mac_reg[RDBAL], E1000State), + VMSTATE_UINT32(mac_reg[RDH], E1000State), + VMSTATE_UINT32(mac_reg[RDLEN], E1000State), + VMSTATE_UINT32(mac_reg[RDT], E1000State), + VMSTATE_UINT32(mac_reg[STATUS], E1000State), + VMSTATE_UINT32(mac_reg[SWSM], E1000State), + VMSTATE_UINT32(mac_reg[TCTL], E1000State), + VMSTATE_UINT32(mac_reg[TDBAH], E1000State), + VMSTATE_UINT32(mac_reg[TDBAL], E1000State), + VMSTATE_UINT32(mac_reg[TDH], E1000State), + VMSTATE_UINT32(mac_reg[TDLEN], E1000State), + VMSTATE_UINT32(mac_reg[TDT], E1000State), + VMSTATE_UINT32(mac_reg[TORH], E1000State), + VMSTATE_UINT32(mac_reg[TORL], E1000State), + VMSTATE_UINT32(mac_reg[TOTH], E1000State), + VMSTATE_UINT32(mac_reg[TOTL], E1000State), + VMSTATE_UINT32(mac_reg[TPR], E1000State), + VMSTATE_UINT32(mac_reg[TPT], E1000State), + VMSTATE_UINT32(mac_reg[TXDCTL], E1000State), + VMSTATE_UINT32(mac_reg[WUFC], E1000State), + VMSTATE_UINT32(mac_reg[VET], E1000State), + VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, RA, 32), + VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, MTA, 128), + VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, VFTA, 128), + VMSTATE_END_OF_LIST() + } +}; static const uint16_t e1000_eeprom_template[64] = { 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, @@ -1068,7 +1046,7 @@ pci_e1000_uninit(PCIDevice *dev) cpu_unregister_io_memory(d->mmio_index); qemu_del_vlan_client(d->vc); - unregister_savevm("e1000", d); + vmstate_unregister(&vmstate_e1000, d); return 0; } @@ -1089,7 +1067,6 @@ static int pci_e1000_init(PCIDevice *pci_dev) E1000State *d = DO_UPCAST(E1000State, dev, pci_dev); uint8_t *pci_conf; uint16_t checksum = 0; - static const char info_str[] = "e1000"; int i; uint8_t *macaddr; @@ -1133,7 +1110,7 @@ static int pci_e1000_init(PCIDevice *pci_dev) qemu_format_nic_info_str(d->vc, macaddr); - register_savevm(info_str, -1, 2, nic_save, nic_load, d); + vmstate_register(-1, &vmstate_e1000, d); e1000_reset(d); #if 0 /* rom bev support is broken -> can't load unconditionally */ diff --git a/hw/eepro100.c b/hw/eepro100.c index d77ca42cd..6e1e389ed 100644 --- a/hw/eepro100.c +++ b/hw/eepro100.c @@ -220,6 +220,8 @@ typedef struct { /* Data in mem is always in the byte order of the controller (le). */ uint8_t mem[PCI_MEM_SIZE]; + /* vmstate for each particular nic */ + VMStateDescription *vmstate; } EEPRO100State; /* Default values for MDI (PHY) registers */ @@ -1597,141 +1599,62 @@ static ssize_t nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size return size; } -static int nic_load(QEMUFile * f, void *opaque, int version_id) -{ - EEPRO100State *s = opaque; - int i; - int ret; - - if (version_id > 3) - return -EINVAL; - - ret = pci_device_load(&s->dev, f); - if (ret < 0) { - return ret; - } - - /* Skip unused entries. */ - qemu_fseek(f, 32, SEEK_CUR); - - qemu_get_buffer(f, s->mult, 8); - qemu_get_buffer(f, s->mem, sizeof(s->mem)); - - /* Restore all members of struct between scb_stat and mem. */ - qemu_get_8s(f, &s->scb_stat); - qemu_get_8s(f, &s->int_stat); - /* Skip unused entries. */ - qemu_fseek(f, 3 * 4, SEEK_CUR); - qemu_get_buffer(f, s->conf.macaddr.a, 6); - /* Skip unused entries. */ - qemu_fseek(f, 19 * 4, SEEK_CUR); - for (i = 0; i < 32; i++) { - qemu_get_be16s(f, &s->mdimem[i]); - } - /* The eeprom should be saved and restored by its own routines. */ - qemu_get_be32s(f, &s->device); - // TODO check device. - qemu_get_be32s(f, &s->pointer); - qemu_get_be32s(f, &s->cu_base); - qemu_get_be32s(f, &s->cu_offset); - qemu_get_be32s(f, &s->ru_base); - qemu_get_be32s(f, &s->ru_offset); - qemu_get_be32s(f, &s->statsaddr); - /* Restore epro100_stats_t statistics. */ - qemu_get_be32s(f, &s->statistics.tx_good_frames); - qemu_get_be32s(f, &s->statistics.tx_max_collisions); - qemu_get_be32s(f, &s->statistics.tx_late_collisions); - qemu_get_be32s(f, &s->statistics.tx_underruns); - qemu_get_be32s(f, &s->statistics.tx_lost_crs); - qemu_get_be32s(f, &s->statistics.tx_deferred); - qemu_get_be32s(f, &s->statistics.tx_single_collisions); - qemu_get_be32s(f, &s->statistics.tx_multiple_collisions); - qemu_get_be32s(f, &s->statistics.tx_total_collisions); - qemu_get_be32s(f, &s->statistics.rx_good_frames); - qemu_get_be32s(f, &s->statistics.rx_crc_errors); - qemu_get_be32s(f, &s->statistics.rx_alignment_errors); - qemu_get_be32s(f, &s->statistics.rx_resource_errors); - qemu_get_be32s(f, &s->statistics.rx_overrun_errors); - qemu_get_be32s(f, &s->statistics.rx_cdt_errors); - qemu_get_be32s(f, &s->statistics.rx_short_frame_errors); - qemu_get_be32s(f, &s->statistics.fc_xmt_pause); - qemu_get_be32s(f, &s->statistics.fc_rcv_pause); - qemu_get_be32s(f, &s->statistics.fc_rcv_unsupported); - qemu_get_be16s(f, &s->statistics.xmt_tco_frames); - qemu_get_be16s(f, &s->statistics.rcv_tco_frames); - qemu_get_be32s(f, &s->statistics.complete); +static const VMStateDescription vmstate_eepro100 = { + .version_id = 3, + .minimum_version_id = 2, + .minimum_version_id_old = 2, + .fields = (VMStateField []) { + VMSTATE_PCI_DEVICE(dev, EEPRO100State), + VMSTATE_UNUSED(32), + VMSTATE_BUFFER(mult, EEPRO100State), + VMSTATE_BUFFER(mem, EEPRO100State), + /* Save all members of struct between scb_stat and mem. */ + VMSTATE_UINT8(scb_stat, EEPRO100State), + VMSTATE_UINT8(int_stat, EEPRO100State), + VMSTATE_UNUSED(3*4), + VMSTATE_MACADDR(conf.macaddr, EEPRO100State), + VMSTATE_UNUSED(19*4), + VMSTATE_UINT16_ARRAY(mdimem, EEPRO100State, 32), + /* The eeprom should be saved and restored by its own routines. */ + VMSTATE_UINT32(device, EEPRO100State), + /* TODO check device. */ + VMSTATE_UINT32(pointer, EEPRO100State), + VMSTATE_UINT32(cu_base, EEPRO100State), + VMSTATE_UINT32(cu_offset, EEPRO100State), + VMSTATE_UINT32(ru_base, EEPRO100State), + VMSTATE_UINT32(ru_offset, EEPRO100State), + VMSTATE_UINT32(statsaddr, EEPRO100State), + /* Save epro100_stats_t statistics. */ + VMSTATE_UINT32(statistics.tx_good_frames, EEPRO100State), + VMSTATE_UINT32(statistics.tx_max_collisions, EEPRO100State), + VMSTATE_UINT32(statistics.tx_late_collisions, EEPRO100State), + VMSTATE_UINT32(statistics.tx_underruns, EEPRO100State), + VMSTATE_UINT32(statistics.tx_lost_crs, EEPRO100State), + VMSTATE_UINT32(statistics.tx_deferred, EEPRO100State), + VMSTATE_UINT32(statistics.tx_single_collisions, EEPRO100State), + VMSTATE_UINT32(statistics.tx_multiple_collisions, EEPRO100State), + VMSTATE_UINT32(statistics.tx_total_collisions, EEPRO100State), + VMSTATE_UINT32(statistics.rx_good_frames, EEPRO100State), + VMSTATE_UINT32(statistics.rx_crc_errors, EEPRO100State), + VMSTATE_UINT32(statistics.rx_alignment_errors, EEPRO100State), + VMSTATE_UINT32(statistics.rx_resource_errors, EEPRO100State), + VMSTATE_UINT32(statistics.rx_overrun_errors, EEPRO100State), + VMSTATE_UINT32(statistics.rx_cdt_errors, EEPRO100State), + VMSTATE_UINT32(statistics.rx_short_frame_errors, EEPRO100State), + VMSTATE_UINT32(statistics.fc_xmt_pause, EEPRO100State), + VMSTATE_UINT32(statistics.fc_rcv_pause, EEPRO100State), + VMSTATE_UINT32(statistics.fc_rcv_unsupported, EEPRO100State), + VMSTATE_UINT16(statistics.xmt_tco_frames, EEPRO100State), + VMSTATE_UINT16(statistics.rcv_tco_frames, EEPRO100State), + VMSTATE_UINT32(statistics.complete, EEPRO100State), #if 0 - qemu_get_be16s(f, &s->status); + VMSTATE_UINT16(status, EEPRO100State), #endif - - /* Configuration bytes. */ - qemu_get_buffer(f, s->configuration, sizeof(s->configuration)); - - return 0; -} - -static void nic_save(QEMUFile * f, void *opaque) -{ - EEPRO100State *s = opaque; - int i; - - pci_device_save(&s->dev, f); - - /* Skip unused entries. */ - qemu_fseek(f, 32, SEEK_CUR); - - qemu_put_buffer(f, s->mult, 8); - qemu_put_buffer(f, s->mem, sizeof(s->mem)); - - /* Save all members of struct between scb_stat and mem. */ - qemu_put_8s(f, &s->scb_stat); - qemu_put_8s(f, &s->int_stat); - /* Skip unused entries. */ - qemu_fseek(f, 3 * 4, SEEK_CUR); - qemu_put_buffer(f, s->conf.macaddr.a, 6); - /* Skip unused entries. */ - qemu_fseek(f, 19 * 4, SEEK_CUR); - for (i = 0; i < 32; i++) { - qemu_put_be16s(f, &s->mdimem[i]); + /* Configuration bytes. */ + VMSTATE_BUFFER(configuration, EEPRO100State), + VMSTATE_END_OF_LIST() } - /* The eeprom should be saved and restored by its own routines. */ - qemu_put_be32s(f, &s->device); - qemu_put_be32s(f, &s->pointer); - qemu_put_be32s(f, &s->cu_base); - qemu_put_be32s(f, &s->cu_offset); - qemu_put_be32s(f, &s->ru_base); - qemu_put_be32s(f, &s->ru_offset); - qemu_put_be32s(f, &s->statsaddr); - /* Save epro100_stats_t statistics. */ - qemu_put_be32s(f, &s->statistics.tx_good_frames); - qemu_put_be32s(f, &s->statistics.tx_max_collisions); - qemu_put_be32s(f, &s->statistics.tx_late_collisions); - qemu_put_be32s(f, &s->statistics.tx_underruns); - qemu_put_be32s(f, &s->statistics.tx_lost_crs); - qemu_put_be32s(f, &s->statistics.tx_deferred); - qemu_put_be32s(f, &s->statistics.tx_single_collisions); - qemu_put_be32s(f, &s->statistics.tx_multiple_collisions); - qemu_put_be32s(f, &s->statistics.tx_total_collisions); - qemu_put_be32s(f, &s->statistics.rx_good_frames); - qemu_put_be32s(f, &s->statistics.rx_crc_errors); - qemu_put_be32s(f, &s->statistics.rx_alignment_errors); - qemu_put_be32s(f, &s->statistics.rx_resource_errors); - qemu_put_be32s(f, &s->statistics.rx_overrun_errors); - qemu_put_be32s(f, &s->statistics.rx_cdt_errors); - qemu_put_be32s(f, &s->statistics.rx_short_frame_errors); - qemu_put_be32s(f, &s->statistics.fc_xmt_pause); - qemu_put_be32s(f, &s->statistics.fc_rcv_pause); - qemu_put_be32s(f, &s->statistics.fc_rcv_unsupported); - qemu_put_be16s(f, &s->statistics.xmt_tco_frames); - qemu_put_be16s(f, &s->statistics.rcv_tco_frames); - qemu_put_be32s(f, &s->statistics.complete); -#if 0 - qemu_put_be16s(f, &s->status); -#endif - - /* Configuration bytes. */ - qemu_put_buffer(f, s->configuration, sizeof(s->configuration)); -} +}; static void nic_cleanup(VLANClientState *vc) { @@ -1745,7 +1668,7 @@ static int pci_nic_uninit(PCIDevice *pci_dev) EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); cpu_unregister_io_memory(s->mmio_index); - unregister_savevm(s->vc->model, s); + vmstate_unregister(s->vmstate, s); eeprom93xx_free(s->eeprom); qemu_del_vlan_client(s->vc); return 0; @@ -1793,7 +1716,10 @@ static int nic_init(PCIDevice *pci_dev, uint32_t device) qemu_register_reset(nic_reset, s); - register_savevm(s->vc->model, -1, 3, nic_save, nic_load, s); + s->vmstate = qemu_malloc(sizeof(vmstate_eepro100)); + memcpy(s->vmstate, &vmstate_eepro100, sizeof(vmstate_eepro100)); + s->vmstate->name = s->vc->model; + vmstate_register(-1, s->vmstate, s); return 0; } diff --git a/hw/eeprom93xx.c b/hw/eeprom93xx.c index 66dfc43d5..43244e771 100644 --- a/hw/eeprom93xx.c +++ b/hw/eeprom93xx.c @@ -89,66 +89,63 @@ struct _eeprom_t { /* Code for saving and restoring of EEPROM state. */ -static void eeprom_save(QEMUFile *f, void *opaque) +/* Restore an uint16_t from an uint8_t + This is a Big hack, but it is how the old state did it. + */ + +static int get_uint16_from_uint8(QEMUFile *f, void *pv, size_t size) { - /* Save EEPROM data. */ - unsigned address; - eeprom_t *eeprom = (eeprom_t *)opaque; + uint16_t *v = pv; + *v = qemu_get_ubyte(f); + return 0; +} - qemu_put_byte(f, eeprom->tick); - qemu_put_byte(f, eeprom->address); - qemu_put_byte(f, eeprom->command); - qemu_put_byte(f, eeprom->writeable); +static void put_unused(QEMUFile *f, void *pv, size_t size) +{ + fprintf(stderr, "uint16_from_uint8 is used only for backwards compatibility.\n"); + fprintf(stderr, "Never should be used to write a new state.\n"); + exit(0); +} - qemu_put_byte(f, eeprom->eecs); - qemu_put_byte(f, eeprom->eesk); - qemu_put_byte(f, eeprom->eedo); +const VMStateInfo vmstate_hack_uint16_from_uint8 = { + .name = "uint16_from_uint8", + .get = get_uint16_from_uint8, + .put = put_unused, +}; - qemu_put_byte(f, eeprom->addrbits); - qemu_put_be16(f, eeprom->size); - qemu_put_be16(f, eeprom->data); - for (address = 0; address < eeprom->size; address++) { - qemu_put_be16(f, eeprom->contents[address]); - } -} +#define VMSTATE_UINT16_HACK_TEST(_f, _s, _t) \ + VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_hack_uint16_from_uint8, uint16_t) -static int eeprom_load(QEMUFile *f, void *opaque, int version_id) +static bool is_old_eeprom_version(void *opaque, int version_id) { - /* Load EEPROM data from saved data if version and EEPROM size - of data and current EEPROM are identical. */ - eeprom_t *eeprom = (eeprom_t *)opaque; - int result = -EINVAL; - if (version_id >= OLD_EEPROM_VERSION) { - unsigned address; - int size = eeprom->size; - - eeprom->tick = qemu_get_byte(f); - eeprom->address = qemu_get_byte(f); - eeprom->command = qemu_get_byte(f); - eeprom->writeable = qemu_get_byte(f); + return version_id == OLD_EEPROM_VERSION; +} - eeprom->eecs = qemu_get_byte(f); - eeprom->eesk = qemu_get_byte(f); - eeprom->eedo = qemu_get_byte(f); +static const VMStateDescription vmstate_eeprom = { + .name = "eeprom", + .version_id = EEPROM_VERSION, + .minimum_version_id = OLD_EEPROM_VERSION, + .minimum_version_id_old = OLD_EEPROM_VERSION, + .fields = (VMStateField []) { + VMSTATE_UINT8(tick, eeprom_t), + VMSTATE_UINT8(address, eeprom_t), + VMSTATE_UINT8(command, eeprom_t), + VMSTATE_UINT8(writeable, eeprom_t), - eeprom->addrbits = qemu_get_byte(f); - if (version_id == OLD_EEPROM_VERSION) { - eeprom->size = qemu_get_byte(f); - qemu_get_byte(f); - } else { - eeprom->size = qemu_get_be16(f); - } + VMSTATE_UINT8(eecs, eeprom_t), + VMSTATE_UINT8(eesk, eeprom_t), + VMSTATE_UINT8(eedo, eeprom_t), - if (eeprom->size == size) { - eeprom->data = qemu_get_be16(f); - for (address = 0; address < eeprom->size; address++) { - eeprom->contents[address] = qemu_get_be16(f); - } - result = 0; - } + VMSTATE_UINT8(addrbits, eeprom_t), + VMSTATE_UINT16_HACK_TEST(size, eeprom_t, is_old_eeprom_version), + VMSTATE_UNUSED_TEST(is_old_eeprom_version, 1), + VMSTATE_UINT16_EQUAL_V(size, eeprom_t, EEPROM_VERSION), + VMSTATE_UINT16(data, eeprom_t), + VMSTATE_VARRAY_UINT16_UNSAFE(contents, eeprom_t, size, 0, + vmstate_info_uint16, uint16_t), + VMSTATE_END_OF_LIST() } - return result; -} +}; void eeprom93xx_write(eeprom_t *eeprom, int eecs, int eesk, int eedi) { @@ -319,8 +316,7 @@ eeprom_t *eeprom93xx_new(uint16_t nwords) /* Output DO is tristate, read results in 1. */ eeprom->eedo = 1; logout("eeprom = 0x%p, nwords = %u\n", eeprom, nwords); - register_savevm("eeprom", EEPROM_INSTANCE, EEPROM_VERSION, - eeprom_save, eeprom_load, eeprom); + vmstate_register(0, &vmstate_eeprom, eeprom); return eeprom; } @@ -328,7 +324,7 @@ void eeprom93xx_free(eeprom_t *eeprom) { /* Destroy EEPROM. */ logout("eeprom = 0x%p\n", eeprom); - unregister_savevm("eeprom", eeprom); + vmstate_unregister(&vmstate_eeprom, eeprom); qemu_free(eeprom); } @@ -679,7 +679,7 @@ static const VMStateDescription vmstate_fdc = { VMSTATE_UINT8(status1, fdctrl_t), VMSTATE_UINT8(status2, fdctrl_t), /* Command FIFO */ - VMSTATE_VARRAY(fifo, fdctrl_t, fifo_size, 0, vmstate_info_uint8, uint8), + VMSTATE_VARRAY_INT32(fifo, fdctrl_t, fifo_size, 0, vmstate_info_uint8, uint8), VMSTATE_UINT32(data_pos, fdctrl_t), VMSTATE_UINT32(data_len, fdctrl_t), VMSTATE_UINT8(data_state, fdctrl_t), @@ -281,13 +281,14 @@ struct VMStateInfo { }; enum VMStateFlags { - VMS_SINGLE = 0x001, - VMS_POINTER = 0x002, - VMS_ARRAY = 0x004, - VMS_STRUCT = 0x008, - VMS_VARRAY = 0x010, /* Array with size in another field */ - VMS_BUFFER = 0x020, /* static sized buffer */ + VMS_SINGLE = 0x001, + VMS_POINTER = 0x002, + VMS_ARRAY = 0x004, + VMS_STRUCT = 0x008, + VMS_VARRAY_INT32 = 0x010, /* Array with size in int32_t field*/ + VMS_BUFFER = 0x020, /* static sized buffer */ VMS_ARRAY_OF_POINTER = 0x040, + VMS_VARRAY_UINT16 = 0x080, /* Array with size in uint16_t field */ }; typedef struct { @@ -322,6 +323,7 @@ extern const VMStateInfo vmstate_info_int32; extern const VMStateInfo vmstate_info_int64; extern const VMStateInfo vmstate_info_uint8_equal; +extern const VMStateInfo vmstate_info_uint16_equal; extern const VMStateInfo vmstate_info_int32_equal; extern const VMStateInfo vmstate_info_int32_le; @@ -337,28 +339,38 @@ extern const VMStateInfo vmstate_info_u64; extern const VMStateInfo vmstate_info_timer; extern const VMStateInfo vmstate_info_ptimer; extern const VMStateInfo vmstate_info_buffer; +extern const VMStateInfo vmstate_info_unused_buffer; #define type_check_array(t1,t2,n) ((t1(*)[n])0 - (t2*)0) #define type_check_pointer(t1,t2) ((t1**)0 - (t2*)0) -#define VMSTATE_SINGLE(_field, _state, _version, _info, _type) { \ - .name = (stringify(_field)), \ - .version_id = (_version), \ - .size = sizeof(_type), \ - .info = &(_info), \ - .flags = VMS_SINGLE, \ - .offset = offsetof(_state, _field) \ - + type_check(_type,typeof_field(_state, _field)) \ -} +#define vmstate_offset_value(_state, _field, _type) \ + (offsetof(_state, _field) + \ + type_check(_type, typeof_field(_state, _field))) + +#define vmstate_offset_pointer(_state, _field, _type) \ + (offsetof(_state, _field) + \ + type_check_pointer(_type, typeof_field(_state, _field))) -#define VMSTATE_SINGLE_TEST(_field, _state, _test, _info, _type) { \ +#define vmstate_offset_array(_state, _field, _type, _num) \ + (offsetof(_state, _field) + \ + type_check_array(_type, typeof_field(_state, _field), _num)) + +#define vmstate_offset_sub_array(_state, _field, _type, _start) \ + (offsetof(_state, _field[_start])) + +#define vmstate_offset_buffer(_state, _field) \ + vmstate_offset_array(_state, _field, uint8_t, \ + sizeof(typeof_field(_state, _field))) + +#define VMSTATE_SINGLE_TEST(_field, _state, _test, _version, _info, _type) { \ .name = (stringify(_field)), \ + .version_id = (_version), \ .field_exists = (_test), \ .size = sizeof(_type), \ .info = &(_info), \ .flags = VMS_SINGLE, \ - .offset = offsetof(_state, _field) \ - + type_check(_type,typeof_field(_state, _field)) \ + .offset = vmstate_offset_value(_state, _field, _type), \ } #define VMSTATE_POINTER(_field, _state, _version, _info, _type) { \ @@ -367,8 +379,7 @@ extern const VMStateInfo vmstate_info_buffer; .info = &(_info), \ .size = sizeof(_type), \ .flags = VMS_SINGLE|VMS_POINTER, \ - .offset = offsetof(_state, _field) \ - + type_check(_type,typeof_field(_state, _field)) \ + .offset = vmstate_offset_value(_state, _field, _type), \ } #define VMSTATE_ARRAY(_field, _state, _num, _version, _info, _type) {\ @@ -378,8 +389,7 @@ extern const VMStateInfo vmstate_info_buffer; .info = &(_info), \ .size = sizeof(_type), \ .flags = VMS_ARRAY, \ - .offset = offsetof(_state, _field) \ - + type_check_array(_type,typeof_field(_state, _field),_num) \ + .offset = vmstate_offset_array(_state, _field, _type, _num), \ } #define VMSTATE_ARRAY_TEST(_field, _state, _num, _test, _info, _type) {\ @@ -389,20 +399,37 @@ extern const VMStateInfo vmstate_info_buffer; .info = &(_info), \ .size = sizeof(_type), \ .flags = VMS_ARRAY, \ - .offset = offsetof(_state, _field) \ - + type_check_array(_type,typeof_field(_state, _field),_num) \ + .offset = vmstate_offset_array(_state, _field, _type, _num),\ +} + +#define VMSTATE_SUB_ARRAY(_field, _state, _start, _num, _version, _info, _type) { \ + .name = (stringify(_field)), \ + .version_id = (_version), \ + .num = (_num), \ + .info = &(_info), \ + .size = sizeof(_type), \ + .flags = VMS_ARRAY, \ + .offset = vmstate_offset_sub_array(_state, _field, _type, _start), \ +} + +#define VMSTATE_VARRAY_INT32(_field, _state, _field_num, _version, _info, _type) {\ + .name = (stringify(_field)), \ + .version_id = (_version), \ + .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \ + .info = &(_info), \ + .size = sizeof(_type), \ + .flags = VMS_VARRAY_INT32|VMS_POINTER, \ + .offset = vmstate_offset_pointer(_state, _field, _type), \ } -#define VMSTATE_VARRAY(_field, _state, _field_num, _version, _info, _type) {\ +#define VMSTATE_VARRAY_UINT16_UNSAFE(_field, _state, _field_num, _version, _info, _type) {\ .name = (stringify(_field)), \ .version_id = (_version), \ - .num_offset = offsetof(_state, _field_num) \ - + type_check(int32_t,typeof_field(_state, _field_num)), \ + .num_offset = vmstate_offset_value(_state, _field_num, uint16_t),\ .info = &(_info), \ .size = sizeof(_type), \ - .flags = VMS_VARRAY|VMS_POINTER, \ - .offset = offsetof(_state, _field) \ - + type_check_pointer(_type,typeof_field(_state, _field)) \ + .flags = VMS_VARRAY_UINT16, \ + .offset = offsetof(_state, _field), \ } #define VMSTATE_STRUCT(_field, _state, _version, _vmsd, _type) { \ @@ -411,8 +438,7 @@ extern const VMStateInfo vmstate_info_buffer; .vmsd = &(_vmsd), \ .size = sizeof(_type), \ .flags = VMS_STRUCT, \ - .offset = offsetof(_state, _field) \ - + type_check(_type,typeof_field(_state, _field)) \ + .offset = vmstate_offset_value(_state, _field, _type), \ } #define VMSTATE_STRUCT_POINTER(_field, _state, _vmsd, _type) { \ @@ -420,8 +446,7 @@ extern const VMStateInfo vmstate_info_buffer; .vmsd = &(_vmsd), \ .size = sizeof(_type), \ .flags = VMS_STRUCT|VMS_POINTER, \ - .offset = offsetof(_state, _field) \ - + type_check(_type,typeof_field(_state, _field)) \ + .offset = vmstate_offset_value(_state, _field, _type), \ } #define VMSTATE_ARRAY_OF_POINTER(_field, _state, _num, _version, _info, _type) {\ @@ -431,8 +456,7 @@ extern const VMStateInfo vmstate_info_buffer; .info = &(_info), \ .size = sizeof(_type), \ .flags = VMS_ARRAY|VMS_ARRAY_OF_POINTER, \ - .offset = offsetof(_state, _field) \ - + type_check_array(_type,typeof_field(_state, _field),_num) \ + .offset = vmstate_offset_array(_state, _field, _type, _num), \ } #define VMSTATE_STRUCT_ARRAY(_field, _state, _num, _version, _vmsd, _type) { \ @@ -442,41 +466,46 @@ extern const VMStateInfo vmstate_info_buffer; .vmsd = &(_vmsd), \ .size = sizeof(_type), \ .flags = VMS_STRUCT|VMS_ARRAY, \ - .offset = offsetof(_state, _field) \ - + type_check_array(_type,typeof_field(_state, _field),_num) \ + .offset = vmstate_offset_array(_state, _field, _type, _num), \ } #define VMSTATE_STRUCT_ARRAY_SIZE_UINT8(_field, _state, _field__num, _version, _vmsd, _type) { \ .name = (stringify(_field)), \ - .num_offset = offsetof(_state, _field_num) \ - + type_check(uint8_t,typeof_field(_state, _field_num)), \ + .num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \ .version_id = (_version), \ .vmsd = &(_vmsd), \ .size = sizeof(_type), \ .flags = VMS_STRUCT|VMS_ARRAY, \ - .offset = offsetof(_state, _field) \ - + type_check_array(_type,typeof_field(_state, _field),_num) \ + .offset = vmstate_offset_array(_state, _field, _type, _num), \ } -#define VMSTATE_STATIC_BUFFER(_field, _state, _version) { \ - .name = (stringify(_field)), \ - .version_id = (_version), \ - .size = sizeof(typeof_field(_state,_field)), \ - .info = &vmstate_info_buffer, \ - .flags = VMS_BUFFER, \ - .offset = offsetof(_state, _field) \ - + type_check_array(uint8_t,typeof_field(_state, _field),sizeof(typeof_field(_state,_field))) \ +#define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \ + .name = (stringify(_field)), \ + .version_id = (_version), \ + .field_exists = (_test), \ + .size = (_size - _start), \ + .info = &vmstate_info_buffer, \ + .flags = VMS_BUFFER, \ + .offset = vmstate_offset_buffer(_state, _field) + _start, \ } -#define VMSTATE_BUFFER_START_MIDDLE(_field, _state, start) { \ +#define VMSTATE_BUFFER_UNSAFE(_field, _state, _version, _size) { \ .name = (stringify(_field)), \ - .size = sizeof(typeof_field(_state,_field)) - start, \ + .version_id = (_version), \ + .size = (_size), \ .info = &vmstate_info_buffer, \ .flags = VMS_BUFFER, \ - .offset = offsetof(_state, _field) + start \ - + type_check_array(uint8_t,typeof_field(_state, _field),sizeof(typeof_field(_state,_field))) \ + .offset = offsetof(_state, _field), \ } +#define VMSTATE_UNUSED_BUFFER(_test, _version, _size) { \ + .name = "unused", \ + .field_exists = (_test), \ + .version_id = (_version), \ + .size = (_size), \ + .info = &vmstate_info_unused_buffer, \ + .flags = VMS_BUFFER, \ +} extern const VMStateDescription vmstate_pci_device; #define VMSTATE_PCI_DEVICE(_field, _state) { \ @@ -484,8 +513,7 @@ extern const VMStateDescription vmstate_pci_device; .size = sizeof(PCIDevice), \ .vmsd = &vmstate_pci_device, \ .flags = VMS_STRUCT, \ - .offset = offsetof(_state, _field) \ - + type_check(PCIDevice,typeof_field(_state, _field)) \ + .offset = vmstate_offset_value(_state, _field, PCIDevice), \ } extern const VMStateDescription vmstate_i2c_slave; @@ -495,8 +523,19 @@ extern const VMStateDescription vmstate_i2c_slave; .size = sizeof(i2c_slave), \ .vmsd = &vmstate_i2c_slave, \ .flags = VMS_STRUCT, \ - .offset = offsetof(_state, _field) \ - + type_check(i2c_slave,typeof_field(_state, _field)) \ + .offset = vmstate_offset_value(_state, _field, i2c_slave), \ +} + +#define vmstate_offset_macaddr(_state, _field) \ + vmstate_offset_array(_state, _field.a, uint8_t, \ + sizeof(typeof_field(_state, _field))) + +#define VMSTATE_MACADDR(_field, _state) { \ + .name = (stringify(_field)), \ + .size = sizeof(MACAddr), \ + .info = &vmstate_info_uint8, \ + .flags = VMS_BUFFER, \ + .offset = vmstate_offset_macaddr(_state, _field), \ } /* _f : field name @@ -506,6 +545,9 @@ extern const VMStateDescription vmstate_i2c_slave; _v : version */ +#define VMSTATE_SINGLE(_field, _state, _version, _info, _type) \ + VMSTATE_SINGLE_TEST(_field, _state, NULL, _version, _info, _type) + #define VMSTATE_INT8_V(_f, _s, _v) \ VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int8, int8_t) #define VMSTATE_INT16_V(_f, _s, _v) \ @@ -554,6 +596,12 @@ extern const VMStateDescription vmstate_i2c_slave; #define VMSTATE_UINT8_EQUAL(_f, _s) \ VMSTATE_SINGLE(_f, _s, 0, vmstate_info_uint8_equal, uint8_t) +#define VMSTATE_UINT16_EQUAL(_f, _s) \ + VMSTATE_SINGLE(_f, _s, 0, vmstate_info_uint16_equal, uint16_t) + +#define VMSTATE_UINT16_EQUAL_V(_f, _s, _v) \ + VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint16_equal, uint16_t) + #define VMSTATE_INT32_EQUAL(_f, _s) \ VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_equal, int32_t) @@ -561,7 +609,7 @@ extern const VMStateDescription vmstate_i2c_slave; VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t) #define VMSTATE_UINT32_TEST(_f, _s, _t) \ - VMSTATE_SINGLE_TEST(_f, _s, _t, vmstate_info_uint32, uint32_t) + VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint32, uint32_t) #define VMSTATE_TIMER_V(_f, _s, _v) \ VMSTATE_POINTER(_f, _s, _v, vmstate_info_timer, QEMUTimer *) @@ -614,17 +662,35 @@ extern const VMStateDescription vmstate_i2c_slave; #define VMSTATE_INT32_ARRAY(_f, _s, _n) \ VMSTATE_INT32_ARRAY_V(_f, _s, _n, 0) -#define VMSTATE_INT32_VARRAY_V(_f, _s, _f_n, _v) \ - VMSTATE_VARRAY(_f, _s, _f_n, _v, vmstate_info_int32, int32_t) +#define VMSTATE_UINT32_SUB_ARRAY(_f, _s, _start, _num) \ + VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint32, uint32_t) -#define VMSTATE_INT32_VARRAY(_f, _s, _f_n) \ - VMSTATE_INT32_VARRAY_V(_f, _s, _f_n, 0) +#define VMSTATE_UINT32_ARRAY(_f, _s, _n) \ + VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0) #define VMSTATE_BUFFER_V(_f, _s, _v) \ - VMSTATE_STATIC_BUFFER(_f, _s, _v) + VMSTATE_STATIC_BUFFER(_f, _s, _v, NULL, 0, sizeof(typeof_field(_s, _f))) #define VMSTATE_BUFFER(_f, _s) \ - VMSTATE_STATIC_BUFFER(_f, _s, 0) + VMSTATE_BUFFER_V(_f, _s, 0) + +#define VMSTATE_PARTIAL_BUFFER(_f, _s, _size) \ + VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, 0, _size) + +#define VMSTATE_BUFFER_START_MIDDLE(_f, _s, _start) \ + VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, _start, sizeof(typeof_field(_s, _f))) + +#define VMSTATE_BUFFER_TEST(_f, _s, _test) \ + VMSTATE_STATIC_BUFFER(_f, _s, 0, _test, 0, sizeof(typeof_field(_s, _f))) + +#define VMSTATE_UNUSED_V(_v, _size) \ + VMSTATE_UNUSED_BUFFER(NULL, _v, _size) + +#define VMSTATE_UNUSED(_size) \ + VMSTATE_UNUSED_V(0, _size) + +#define VMSTATE_UNUSED_TEST(_test, _size) \ + VMSTATE_UNUSED_BUFFER(_test, 0, _size) #ifdef NEED_CPU_H #if TARGET_LONG_BITS == 64 diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index 5c8f61525..ea116fce7 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -233,7 +233,7 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev) ide_init2(&d->bus[0], NULL, NULL, irq[0]); ide_init2(&d->bus[1], NULL, NULL, irq[1]); - register_savevm("ide", 0, 3, pci_ide_save, pci_ide_load, d); + vmstate_register(0, &vmstate_ide_pci, d); qemu_register_reset(cmd646_reset, d); cmd646_reset(d); return 0; diff --git a/hw/ide/core.c b/hw/ide/core.c index 0b6de6caa..fffcd0028 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -1942,28 +1942,29 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val) break; case 0x03: { /* set transfer mode */ uint8_t val = s->nsector & 0x07; + uint16_t *identify_data = (uint16_t *)s->identify_data; switch (s->nsector >> 3) { case 0x00: /* pio default */ case 0x01: /* pio mode */ - put_le16(s->identify_data + 62,0x07); - put_le16(s->identify_data + 63,0x07); - put_le16(s->identify_data + 88,0x3f); + put_le16(identify_data + 62,0x07); + put_le16(identify_data + 63,0x07); + put_le16(identify_data + 88,0x3f); break; case 0x02: /* sigle word dma mode*/ - put_le16(s->identify_data + 62,0x07 | (1 << (val + 8))); - put_le16(s->identify_data + 63,0x07); - put_le16(s->identify_data + 88,0x3f); + put_le16(identify_data + 62,0x07 | (1 << (val + 8))); + put_le16(identify_data + 63,0x07); + put_le16(identify_data + 88,0x3f); break; case 0x04: /* mdma mode */ - put_le16(s->identify_data + 62,0x07); - put_le16(s->identify_data + 63,0x07 | (1 << (val + 8))); - put_le16(s->identify_data + 88,0x3f); + put_le16(identify_data + 62,0x07); + put_le16(identify_data + 63,0x07 | (1 << (val + 8))); + put_le16(identify_data + 88,0x3f); break; case 0x08: /* udma mode */ - put_le16(s->identify_data + 62,0x07); - put_le16(s->identify_data + 63,0x07); - put_le16(s->identify_data + 88,0x3f | (1 << (val + 8))); + put_le16(identify_data + 62,0x07); + put_le16(identify_data + 63,0x07); + put_le16(identify_data + 88,0x3f | (1 << (val + 8))); break; default: goto abort_cmd; @@ -2590,81 +2591,69 @@ void ide_init_ioport(IDEBus *bus, int iobase, int iobase2) register_ioport_read(iobase, 4, 4, ide_data_readl, bus); } -/* save per IDE drive data */ -void ide_save(QEMUFile* f, IDEState *s) +static bool is_identify_set(void *opaque, int version_id) { - qemu_put_be32(f, s->mult_sectors); - qemu_put_be32(f, s->identify_set); - if (s->identify_set) { - qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512); - } - qemu_put_8s(f, &s->feature); - qemu_put_8s(f, &s->error); - qemu_put_be32s(f, &s->nsector); - qemu_put_8s(f, &s->sector); - qemu_put_8s(f, &s->lcyl); - qemu_put_8s(f, &s->hcyl); - qemu_put_8s(f, &s->hob_feature); - qemu_put_8s(f, &s->hob_nsector); - qemu_put_8s(f, &s->hob_sector); - qemu_put_8s(f, &s->hob_lcyl); - qemu_put_8s(f, &s->hob_hcyl); - qemu_put_8s(f, &s->select); - qemu_put_8s(f, &s->status); - qemu_put_8s(f, &s->lba48); - - qemu_put_8s(f, &s->sense_key); - qemu_put_8s(f, &s->asc); - qemu_put_8s(f, &s->cdrom_changed); - /* XXX: if a transfer is pending, we do not save it yet */ -} - -/* load per IDE drive data */ -void ide_load(QEMUFile* f, IDEState *s, int version_id) -{ - s->mult_sectors=qemu_get_be32(f); - s->identify_set=qemu_get_be32(f); - if (s->identify_set) { - qemu_get_buffer(f, (uint8_t *)s->identify_data, 512); - } - qemu_get_8s(f, &s->feature); - qemu_get_8s(f, &s->error); - qemu_get_be32s(f, &s->nsector); - qemu_get_8s(f, &s->sector); - qemu_get_8s(f, &s->lcyl); - qemu_get_8s(f, &s->hcyl); - qemu_get_8s(f, &s->hob_feature); - qemu_get_8s(f, &s->hob_nsector); - qemu_get_8s(f, &s->hob_sector); - qemu_get_8s(f, &s->hob_lcyl); - qemu_get_8s(f, &s->hob_hcyl); - qemu_get_8s(f, &s->select); - qemu_get_8s(f, &s->status); - qemu_get_8s(f, &s->lba48); - - qemu_get_8s(f, &s->sense_key); - qemu_get_8s(f, &s->asc); - if (version_id == 3) { - qemu_get_8s(f, &s->cdrom_changed); - } else { - if (s->sense_key == SENSE_UNIT_ATTENTION && - s->asc == ASC_MEDIUM_MAY_HAVE_CHANGED) - s->cdrom_changed = 1; - } - /* XXX: if a transfer is pending, we do not save it yet */ -} + IDEState *s = opaque; -void idebus_save(QEMUFile* f, IDEBus *bus) -{ - qemu_put_8s(f, &bus->cmd); - qemu_put_8s(f, &bus->unit); + return s->identify_set != 0; } -void idebus_load(QEMUFile* f, IDEBus *bus, int version_id) +static int ide_drive_post_load(void *opaque, int version_id) { - qemu_get_8s(f, &bus->cmd); - qemu_get_8s(f, &bus->unit); -} + IDEState *s = opaque; + + if (version_id < 3) { + if (s->sense_key == SENSE_UNIT_ATTENTION && + s->asc == ASC_MEDIUM_MAY_HAVE_CHANGED) { + s->cdrom_changed = 1; + } + } + return 0; +} + +const VMStateDescription vmstate_ide_drive = { + .name = "ide_drive", + .version_id = 3, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .post_load = ide_drive_post_load, + .fields = (VMStateField []) { + VMSTATE_INT32(mult_sectors, IDEState), + VMSTATE_INT32(identify_set, IDEState), + VMSTATE_BUFFER_TEST(identify_data, IDEState, is_identify_set), + VMSTATE_UINT8(feature, IDEState), + VMSTATE_UINT8(error, IDEState), + VMSTATE_UINT32(nsector, IDEState), + VMSTATE_UINT8(sector, IDEState), + VMSTATE_UINT8(lcyl, IDEState), + VMSTATE_UINT8(hcyl, IDEState), + VMSTATE_UINT8(hob_feature, IDEState), + VMSTATE_UINT8(hob_sector, IDEState), + VMSTATE_UINT8(hob_nsector, IDEState), + VMSTATE_UINT8(hob_lcyl, IDEState), + VMSTATE_UINT8(hob_hcyl, IDEState), + VMSTATE_UINT8(select, IDEState), + VMSTATE_UINT8(status, IDEState), + VMSTATE_UINT8(lba48, IDEState), + VMSTATE_UINT8(sense_key, IDEState), + VMSTATE_UINT8(asc, IDEState), + VMSTATE_UINT8_V(cdrom_changed, IDEState, 3), + /* XXX: if a transfer is pending, we do not save it yet */ + VMSTATE_END_OF_LIST() + } +}; + +const VMStateDescription vmstate_ide_bus = { + .name = "ide_bus", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT8(cmd, IDEBus), + VMSTATE_UINT8(unit, IDEBus), + VMSTATE_END_OF_LIST() + } +}; /***********************************************************/ /* PCI IDE definitions */ diff --git a/hw/ide/internal.h b/hw/ide/internal.h index 2e4043110..cfae4c29b 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -374,7 +374,7 @@ struct IDEState { int64_t nb_sectors; int mult_sectors; int identify_set; - uint16_t identify_data[256]; + uint8_t identify_data[512]; int drive_serial; char drive_serial_str[21]; /* ide regs */ @@ -512,10 +512,18 @@ static inline void ide_set_irq(IDEBus *bus) } /* hw/ide/core.c */ -void ide_save(QEMUFile* f, IDEState *s); -void ide_load(QEMUFile* f, IDEState *s, int version_id); -void idebus_save(QEMUFile* f, IDEBus *bus); -void idebus_load(QEMUFile* f, IDEBus *bus, int version_id); +extern const VMStateDescription vmstate_ide_bus; + +#define VMSTATE_IDE_BUS(_field, _state) \ + VMSTATE_STRUCT(_field, _state, 1, vmstate_ide_bus, IDEBus) + +#define VMSTATE_IDE_BUS_ARRAY(_field, _state, _num) \ + VMSTATE_STRUCT_ARRAY(_field, _state, _num, 1, vmstate_ide_bus, IDEBus) + +extern const VMStateDescription vmstate_ide_drive; + +#define VMSTATE_IDE_DRIVES(_field, _state) \ + VMSTATE_STRUCT_ARRAY(_field, _state, 2, 3, vmstate_ide_drive, IDEState) void ide_reset(IDEState *s); int64_t ide_get_sector(IDEState *s); diff --git a/hw/ide/isa.c b/hw/ide/isa.c index 9f0fdd649..fe67bcdf7 100644 --- a/hw/ide/isa.c +++ b/hw/ide/isa.c @@ -44,24 +44,17 @@ typedef struct ISAIDEState { qemu_irq irq; } ISAIDEState; -static void isa_ide_save(QEMUFile* f, void *opaque) -{ - ISAIDEState *s = opaque; - - idebus_save(f, &s->bus); - ide_save(f, &s->bus.ifs[0]); - ide_save(f, &s->bus.ifs[1]); -} - -static int isa_ide_load(QEMUFile* f, void *opaque, int version_id) -{ - ISAIDEState *s = opaque; - - idebus_load(f, &s->bus, version_id); - ide_load(f, &s->bus.ifs[0], version_id); - ide_load(f, &s->bus.ifs[1], version_id); - return 0; -} +static const VMStateDescription vmstate_ide_isa = { + .name = "isa-ide", + .version_id = 3, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField []) { + VMSTATE_IDE_BUS(bus, ISAIDEState), + VMSTATE_IDE_DRIVES(bus.ifs, ISAIDEState), + VMSTATE_END_OF_LIST() + } +}; static int isa_ide_initfn(ISADevice *dev) { @@ -71,7 +64,7 @@ static int isa_ide_initfn(ISADevice *dev) ide_init_ioport(&s->bus, s->iobase, s->iobase2); isa_init_irq(dev, &s->irq, s->isairq); ide_init2(&s->bus, NULL, NULL, s->irq); - register_savevm("isa-ide", 0, 3, isa_ide_save, isa_ide_load, s); + vmstate_register(0, &vmstate_ide_isa, s); return 0; }; diff --git a/hw/ide/macio.c b/hw/ide/macio.c index a11223e6f..e02e4993e 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -291,37 +291,17 @@ static CPUReadMemoryFunc * const pmac_ide_read[] = { pmac_ide_readl, }; -static void pmac_ide_save(QEMUFile *f, void *opaque) -{ - MACIOIDEState *d = opaque; - unsigned int i; - - /* per IDE interface data */ - idebus_save(f, &d->bus); - - /* per IDE drive data */ - for(i = 0; i < 2; i++) { - ide_save(f, &d->bus.ifs[i]); - } -} - -static int pmac_ide_load(QEMUFile *f, void *opaque, int version_id) -{ - MACIOIDEState *d = opaque; - unsigned int i; - - if (version_id != 1 && version_id != 3) - return -EINVAL; - - /* per IDE interface data */ - idebus_load(f, &d->bus, version_id); - - /* per IDE drive data */ - for(i = 0; i < 2; i++) { - ide_load(f, &d->bus.ifs[i], version_id); +static const VMStateDescription vmstate_pmac = { + .name = "ide", + .version_id = 3, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField []) { + VMSTATE_IDE_BUS(bus, MACIOIDEState), + VMSTATE_IDE_DRIVES(bus.ifs, MACIOIDEState), + VMSTATE_END_OF_LIST() } - return 0; -} +}; static void pmac_ide_reset(void *opaque) { @@ -348,7 +328,7 @@ int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq, pmac_ide_memory = cpu_register_io_memory(pmac_ide_read, pmac_ide_write, d); - register_savevm("ide", 0, 3, pmac_ide_save, pmac_ide_load, d); + vmstate_register(0, &vmstate_pmac, d); qemu_register_reset(pmac_ide_reset, d); pmac_ide_reset(d); diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c index aeb77a030..9f7789d61 100644 --- a/hw/ide/microdrive.c +++ b/hw/ide/microdrive.c @@ -51,7 +51,7 @@ typedef struct { uint8_t ctrl; uint16_t io; - int cycle; + uint8_t cycle; } MicroDriveState; /* Register bitfields */ @@ -300,48 +300,23 @@ static void md_common_write(void *opaque, uint32_t at, uint16_t value) } } -static void md_save(QEMUFile *f, void *opaque) -{ - MicroDriveState *s = opaque; - int i; - - qemu_put_8s(f, &s->opt); - qemu_put_8s(f, &s->stat); - qemu_put_8s(f, &s->pins); - - qemu_put_8s(f, &s->ctrl); - qemu_put_be16s(f, &s->io); - qemu_put_byte(f, s->cycle); - - idebus_save(f, &s->bus); - - for (i = 0; i < 2; i ++) - ide_save(f, &s->bus.ifs[i]); -} - -static int md_load(QEMUFile *f, void *opaque, int version_id) -{ - MicroDriveState *s = opaque; - int i; - - if (version_id != 0 && version_id != 3) - return -EINVAL; - - qemu_get_8s(f, &s->opt); - qemu_get_8s(f, &s->stat); - qemu_get_8s(f, &s->pins); - - qemu_get_8s(f, &s->ctrl); - qemu_get_be16s(f, &s->io); - s->cycle = qemu_get_byte(f); - - idebus_load(f, &s->bus, version_id); - - for (i = 0; i < 2; i ++) - ide_load(f, &s->bus.ifs[i], version_id); - - return 0; -} +const VMStateDescription vmstate_microdrive = { + .name = "microdrive", + .version_id = 3, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField []) { + VMSTATE_UINT8(opt, MicroDriveState), + VMSTATE_UINT8(stat, MicroDriveState), + VMSTATE_UINT8(pins, MicroDriveState), + VMSTATE_UINT8(ctrl, MicroDriveState), + VMSTATE_UINT16(io, MicroDriveState), + VMSTATE_UINT8(cycle, MicroDriveState), + VMSTATE_IDE_BUS(bus, MicroDriveState), + VMSTATE_IDE_DRIVES(bus.ifs, MicroDriveState), + VMSTATE_END_OF_LIST() + } +}; static const uint8_t dscm1xxxx_cis[0x14a] = { [0x000] = CISTPL_DEVICE, /* 5V Device Information */ @@ -569,7 +544,7 @@ PCMCIACardState *dscm1xxxx_init(DriveInfo *bdrv) md->bus.ifs[0].mdata_size = METADATA_SIZE; md->bus.ifs[0].mdata_storage = (uint8_t *) qemu_mallocz(METADATA_SIZE); - register_savevm("microdrive", -1, 3, md_save, md_load, md); + vmstate_register(-1, &vmstate_microdrive, md); return &md->card; } diff --git a/hw/ide/mmio.c b/hw/ide/mmio.c index 7a6bf3249..84a20e5ea 100644 --- a/hw/ide/mmio.c +++ b/hw/ide/mmio.c @@ -37,31 +37,29 @@ */ typedef struct { - IDEBus *bus; + IDEBus bus; int shift; } MMIOState; static uint32_t mmio_ide_read (void *opaque, target_phys_addr_t addr) { MMIOState *s = opaque; - IDEBus *bus = s->bus; addr >>= s->shift; if (addr & 7) - return ide_ioport_read(bus, addr); + return ide_ioport_read(&s->bus, addr); else - return ide_data_readw(bus, 0); + return ide_data_readw(&s->bus, 0); } static void mmio_ide_write (void *opaque, target_phys_addr_t addr, uint32_t val) { MMIOState *s = opaque; - IDEBus *bus = s->bus; addr >>= s->shift; if (addr & 7) - ide_ioport_write(bus, addr, val); + ide_ioport_write(&s->bus, addr, val); else - ide_data_writew(bus, 0, val); + ide_data_writew(&s->bus, 0, val); } static CPUReadMemoryFunc * const mmio_ide_reads[] = { @@ -79,16 +77,14 @@ static CPUWriteMemoryFunc * const mmio_ide_writes[] = { static uint32_t mmio_ide_status_read (void *opaque, target_phys_addr_t addr) { MMIOState *s= opaque; - IDEBus *bus = s->bus; - return ide_status_read(bus, 0); + return ide_status_read(&s->bus, 0); } static void mmio_ide_cmd_write (void *opaque, target_phys_addr_t addr, uint32_t val) { MMIOState *s = opaque; - IDEBus *bus = s->bus; - ide_cmd_write(bus, 0, val); + ide_cmd_write(&s->bus, 0, val); } static CPUReadMemoryFunc * const mmio_ide_status[] = { @@ -103,42 +99,33 @@ static CPUWriteMemoryFunc * const mmio_ide_cmd[] = { mmio_ide_cmd_write, }; -static void mmio_ide_save(QEMUFile* f, void *opaque) -{ - MMIOState *s = opaque; - - idebus_save(f, s->bus); - ide_save(f, &s->bus->ifs[0]); - ide_save(f, &s->bus->ifs[1]); -} - -static int mmio_ide_load(QEMUFile* f, void *opaque, int version_id) -{ - MMIOState *s = opaque; - - idebus_load(f, s->bus, version_id); - ide_load(f, &s->bus->ifs[0], version_id); - ide_load(f, &s->bus->ifs[1], version_id); - return 0; -} +static const VMStateDescription vmstate_ide_mmio = { + .name = "mmio-ide", + .version_id = 3, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField []) { + VMSTATE_IDE_BUS(bus, MMIOState), + VMSTATE_IDE_DRIVES(bus.ifs, MMIOState), + VMSTATE_END_OF_LIST() + } +}; void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2, qemu_irq irq, int shift, DriveInfo *hd0, DriveInfo *hd1) { MMIOState *s = qemu_mallocz(sizeof(MMIOState)); - IDEBus *bus = qemu_mallocz(sizeof(*bus)); int mem1, mem2; - ide_init2(bus, hd0, hd1, irq); + ide_init2(&s->bus, hd0, hd1, irq); - s->bus = bus; s->shift = shift; mem1 = cpu_register_io_memory(mmio_ide_reads, mmio_ide_writes, s); mem2 = cpu_register_io_memory(mmio_ide_status, mmio_ide_cmd, s); cpu_register_physical_memory(membase, 16 << shift, mem1); cpu_register_physical_memory(membase2, 2 << shift, mem2); - register_savevm("mmio-ide", 0, 3, mmio_ide_save, mmio_ide_load, s); + vmstate_register(0, &vmstate_ide_mmio, s); } diff --git a/hw/ide/pci.c b/hw/ide/pci.c index dea126a3c..780fc5f11 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -121,75 +121,52 @@ void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val) bm->cur_addr = bm->addr; } -void pci_ide_save(QEMUFile* f, void *opaque) -{ - PCIIDEState *d = opaque; - int i; - - pci_device_save(&d->dev, f); - - for(i = 0; i < 2; i++) { - BMDMAState *bm = &d->bmdma[i]; - uint8_t ifidx; - qemu_put_8s(f, &bm->cmd); - qemu_put_8s(f, &bm->status); - qemu_put_be32s(f, &bm->addr); - qemu_put_sbe64s(f, &bm->sector_num); - qemu_put_be32s(f, &bm->nsector); - ifidx = bm->unit + 2*i; - qemu_put_8s(f, &ifidx); - /* XXX: if a transfer is pending, we do not save it yet */ +static const VMStateDescription vmstate_bmdma = { + .name = "ide bmdma", + .version_id = 3, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField []) { + VMSTATE_UINT8(cmd, BMDMAState), + VMSTATE_UINT8(status, BMDMAState), + VMSTATE_UINT32(addr, BMDMAState), + VMSTATE_INT64(sector_num, BMDMAState), + VMSTATE_UINT32(nsector, BMDMAState), + VMSTATE_UINT8(unit, BMDMAState), + VMSTATE_END_OF_LIST() } +}; - /* per IDE interface data */ - for(i = 0; i < 2; i++) { - idebus_save(f, d->bus+i); - } - - /* per IDE drive data */ - for(i = 0; i < 2; i++) { - ide_save(f, &d->bus[i].ifs[0]); - ide_save(f, &d->bus[i].ifs[1]); - } -} - -int pci_ide_load(QEMUFile* f, void *opaque, int version_id) +static int ide_pci_post_load(void *opaque, int version_id) { PCIIDEState *d = opaque; - int ret, i; - - if (version_id != 2 && version_id != 3) - return -EINVAL; - ret = pci_device_load(&d->dev, f); - if (ret < 0) - return ret; - - for(i = 0; i < 2; i++) { - BMDMAState *bm = &d->bmdma[i]; - uint8_t ifidx; - qemu_get_8s(f, &bm->cmd); - qemu_get_8s(f, &bm->status); - qemu_get_be32s(f, &bm->addr); - qemu_get_sbe64s(f, &bm->sector_num); - qemu_get_be32s(f, &bm->nsector); - qemu_get_8s(f, &ifidx); - bm->unit = ifidx & 1; - /* XXX: if a transfer is pending, we do not save it yet */ - } - - /* per IDE interface data */ - for(i = 0; i < 2; i++) { - idebus_load(f, d->bus+i, version_id); - } + int i; - /* per IDE drive data */ for(i = 0; i < 2; i++) { - ide_load(f, &d->bus[i].ifs[0], version_id); - ide_load(f, &d->bus[i].ifs[1], version_id); + /* current versions always store 0/1, but older version + stored bigger values. We only need last bit */ + d->bmdma[i].unit &= 1; } return 0; } +const VMStateDescription vmstate_ide_pci = { + .name = "ide", + .version_id = 3, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .post_load = ide_pci_post_load, + .fields = (VMStateField []) { + VMSTATE_PCI_DEVICE(dev, PCIIDEState), + VMSTATE_STRUCT_ARRAY(bmdma, PCIIDEState, 2, 0, + vmstate_bmdma, BMDMAState), + VMSTATE_IDE_BUS_ARRAY(bus, PCIIDEState, 2), + VMSTATE_IDE_DRIVES(bus[0].ifs, PCIIDEState), + VMSTATE_IDE_DRIVES(bus[1].ifs, PCIIDEState), + VMSTATE_END_OF_LIST() + } +}; + void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table) { PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); diff --git a/hw/ide/pci.h b/hw/ide/pci.h index 93775030b..d46a95eb9 100644 --- a/hw/ide/pci.h +++ b/hw/ide/pci.h @@ -17,7 +17,7 @@ uint32_t bmdma_addr_readw(void *opaque, uint32_t addr); void bmdma_addr_writew(void *opaque, uint32_t addr, uint32_t val); uint32_t bmdma_addr_readl(void *opaque, uint32_t addr); void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val); -void pci_ide_save(QEMUFile* f, void *opaque); -int pci_ide_load(QEMUFile* f, void *opaque, int version_id); void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table); + +extern const VMStateDescription vmstate_ide_pci; #endif diff --git a/hw/ide/piix.c b/hw/ide/piix.c index ddce6847d..a17bf5951 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -124,7 +124,7 @@ static int pci_piix_ide_initfn(PCIIDEState *d) pci_register_bar(&d->dev, 4, 0x10, PCI_ADDRESS_SPACE_IO, bmdma_map); - register_savevm("ide", 0, 3, pci_ide_save, pci_ide_load, d); + vmstate_register(0, &vmstate_ide_pci, d); ide_bus_new(&d->bus[0], &d->dev.qdev); ide_bus_new(&d->bus[1], &d->dev.qdev); diff --git a/hw/lance.c b/hw/lance.c index 99c25a80b..0a96644b4 100644 --- a/hw/lance.c +++ b/hw/lance.c @@ -96,6 +96,7 @@ static void lance_cleanup(VLANClientState *vc) { PCNetState *d = vc->opaque; + vmstate_unregister(&vmstate_pcnet, d); pcnet_common_cleanup(d); } @@ -116,7 +117,7 @@ static int lance_init(SysBusDevice *dev) s->phys_mem_read = ledma_memory_read; s->phys_mem_write = ledma_memory_write; - register_savevm("pcnet", -1, 3, pcnet_save, pcnet_load, s); + vmstate_register(-1, &vmstate_pcnet, d); return pcnet_common_init(&dev->qdev, s, lance_cleanup); } diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index a4d3a5740..3966f2f98 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -1959,173 +1959,97 @@ static void lsi_mmio_mapfunc(PCIDevice *pci_dev, int region_num, cpu_register_physical_memory(addr + 0, 0x400, s->mmio_io_addr); } -static void lsi_scsi_save(QEMUFile *f, void *opaque) +static void lsi_pre_save(void *opaque) { LSIState *s = opaque; assert(s->dma_buf == NULL); assert(s->current_dma_len == 0); assert(s->active_commands == 0); - - pci_device_save(&s->dev, f); - - qemu_put_sbe32s(f, &s->carry); - qemu_put_sbe32s(f, &s->sense); - qemu_put_sbe32s(f, &s->msg_action); - qemu_put_sbe32s(f, &s->msg_len); - qemu_put_buffer(f, s->msg, sizeof (s->msg)); - qemu_put_sbe32s(f, &s->waiting); - - qemu_put_be32s(f, &s->dsa); - qemu_put_be32s(f, &s->temp); - qemu_put_be32s(f, &s->dnad); - qemu_put_be32s(f, &s->dbc); - qemu_put_8s(f, &s->istat0); - qemu_put_8s(f, &s->istat1); - qemu_put_8s(f, &s->dcmd); - qemu_put_8s(f, &s->dstat); - qemu_put_8s(f, &s->dien); - qemu_put_8s(f, &s->sist0); - qemu_put_8s(f, &s->sist1); - qemu_put_8s(f, &s->sien0); - qemu_put_8s(f, &s->sien1); - qemu_put_8s(f, &s->mbox0); - qemu_put_8s(f, &s->mbox1); - qemu_put_8s(f, &s->dfifo); - qemu_put_8s(f, &s->ctest2); - qemu_put_8s(f, &s->ctest3); - qemu_put_8s(f, &s->ctest4); - qemu_put_8s(f, &s->ctest5); - qemu_put_8s(f, &s->ccntl0); - qemu_put_8s(f, &s->ccntl1); - qemu_put_be32s(f, &s->dsp); - qemu_put_be32s(f, &s->dsps); - qemu_put_8s(f, &s->dmode); - qemu_put_8s(f, &s->dcntl); - qemu_put_8s(f, &s->scntl0); - qemu_put_8s(f, &s->scntl1); - qemu_put_8s(f, &s->scntl2); - qemu_put_8s(f, &s->scntl3); - qemu_put_8s(f, &s->sstat0); - qemu_put_8s(f, &s->sstat1); - qemu_put_8s(f, &s->scid); - qemu_put_8s(f, &s->sxfer); - qemu_put_8s(f, &s->socl); - qemu_put_8s(f, &s->sdid); - qemu_put_8s(f, &s->ssid); - qemu_put_8s(f, &s->sfbr); - qemu_put_8s(f, &s->stest1); - qemu_put_8s(f, &s->stest2); - qemu_put_8s(f, &s->stest3); - qemu_put_8s(f, &s->sidl); - qemu_put_8s(f, &s->stime0); - qemu_put_8s(f, &s->respid0); - qemu_put_8s(f, &s->respid1); - qemu_put_be32s(f, &s->mmrs); - qemu_put_be32s(f, &s->mmws); - qemu_put_be32s(f, &s->sfs); - qemu_put_be32s(f, &s->drs); - qemu_put_be32s(f, &s->sbms); - qemu_put_be32s(f, &s->dbms); - qemu_put_be32s(f, &s->dnad64); - qemu_put_be32s(f, &s->pmjad1); - qemu_put_be32s(f, &s->pmjad2); - qemu_put_be32s(f, &s->rbc); - qemu_put_be32s(f, &s->ua); - qemu_put_be32s(f, &s->ia); - qemu_put_be32s(f, &s->sbc); - qemu_put_be32s(f, &s->csbc); - qemu_put_buffer(f, (uint8_t *)s->scratch, sizeof (s->scratch)); - qemu_put_8s(f, &s->sbr); - - qemu_put_buffer(f, (uint8_t *)s->script_ram, sizeof (s->script_ram)); } -static int lsi_scsi_load(QEMUFile *f, void *opaque, int version_id) -{ - LSIState *s = opaque; - int ret; - - if (version_id > 0) { - return -EINVAL; +static const VMStateDescription vmstate_lsi_scsi = { + .name = "lsiscsi", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .pre_save = lsi_pre_save, + .fields = (VMStateField []) { + VMSTATE_PCI_DEVICE(dev, LSIState), + + VMSTATE_INT32(carry, LSIState), + VMSTATE_INT32(sense, LSIState), + VMSTATE_INT32(msg_action, LSIState), + VMSTATE_INT32(msg_len, LSIState), + VMSTATE_BUFFER(msg, LSIState), + VMSTATE_INT32(waiting, LSIState), + + VMSTATE_UINT32(dsa, LSIState), + VMSTATE_UINT32(temp, LSIState), + VMSTATE_UINT32(dnad, LSIState), + VMSTATE_UINT32(dbc, LSIState), + VMSTATE_UINT8(istat0, LSIState), + VMSTATE_UINT8(istat1, LSIState), + VMSTATE_UINT8(dcmd, LSIState), + VMSTATE_UINT8(dstat, LSIState), + VMSTATE_UINT8(dien, LSIState), + VMSTATE_UINT8(sist0, LSIState), + VMSTATE_UINT8(sist1, LSIState), + VMSTATE_UINT8(sien0, LSIState), + VMSTATE_UINT8(sien1, LSIState), + VMSTATE_UINT8(mbox0, LSIState), + VMSTATE_UINT8(mbox1, LSIState), + VMSTATE_UINT8(dfifo, LSIState), + VMSTATE_UINT8(ctest2, LSIState), + VMSTATE_UINT8(ctest3, LSIState), + VMSTATE_UINT8(ctest4, LSIState), + VMSTATE_UINT8(ctest5, LSIState), + VMSTATE_UINT8(ccntl0, LSIState), + VMSTATE_UINT8(ccntl1, LSIState), + VMSTATE_UINT32(dsp, LSIState), + VMSTATE_UINT32(dsps, LSIState), + VMSTATE_UINT8(dmode, LSIState), + VMSTATE_UINT8(dcntl, LSIState), + VMSTATE_UINT8(scntl0, LSIState), + VMSTATE_UINT8(scntl1, LSIState), + VMSTATE_UINT8(scntl2, LSIState), + VMSTATE_UINT8(scntl3, LSIState), + VMSTATE_UINT8(sstat0, LSIState), + VMSTATE_UINT8(sstat1, LSIState), + VMSTATE_UINT8(scid, LSIState), + VMSTATE_UINT8(sxfer, LSIState), + VMSTATE_UINT8(socl, LSIState), + VMSTATE_UINT8(sdid, LSIState), + VMSTATE_UINT8(ssid, LSIState), + VMSTATE_UINT8(sfbr, LSIState), + VMSTATE_UINT8(stest1, LSIState), + VMSTATE_UINT8(stest2, LSIState), + VMSTATE_UINT8(stest3, LSIState), + VMSTATE_UINT8(sidl, LSIState), + VMSTATE_UINT8(stime0, LSIState), + VMSTATE_UINT8(respid0, LSIState), + VMSTATE_UINT8(respid1, LSIState), + VMSTATE_UINT32(mmrs, LSIState), + VMSTATE_UINT32(mmws, LSIState), + VMSTATE_UINT32(sfs, LSIState), + VMSTATE_UINT32(drs, LSIState), + VMSTATE_UINT32(sbms, LSIState), + VMSTATE_UINT32(dbms, LSIState), + VMSTATE_UINT32(dnad64, LSIState), + VMSTATE_UINT32(pmjad1, LSIState), + VMSTATE_UINT32(pmjad2, LSIState), + VMSTATE_UINT32(rbc, LSIState), + VMSTATE_UINT32(ua, LSIState), + VMSTATE_UINT32(ia, LSIState), + VMSTATE_UINT32(sbc, LSIState), + VMSTATE_UINT32(csbc, LSIState), + VMSTATE_BUFFER_UNSAFE(scratch, LSIState, 0, 18 * sizeof(uint32_t)), + VMSTATE_UINT8(sbr, LSIState), + + VMSTATE_BUFFER_UNSAFE(script_ram, LSIState, 0, 2048 * sizeof(uint32_t)), + VMSTATE_END_OF_LIST() } - - if ((ret = pci_device_load(&s->dev, f)) < 0) - return ret; - - qemu_get_sbe32s(f, &s->carry); - qemu_get_sbe32s(f, &s->sense); - qemu_get_sbe32s(f, &s->msg_action); - qemu_get_sbe32s(f, &s->msg_len); - qemu_get_buffer(f, s->msg, sizeof (s->msg)); - qemu_get_sbe32s(f, &s->waiting); - - qemu_get_be32s(f, &s->dsa); - qemu_get_be32s(f, &s->temp); - qemu_get_be32s(f, &s->dnad); - qemu_get_be32s(f, &s->dbc); - qemu_get_8s(f, &s->istat0); - qemu_get_8s(f, &s->istat1); - qemu_get_8s(f, &s->dcmd); - qemu_get_8s(f, &s->dstat); - qemu_get_8s(f, &s->dien); - qemu_get_8s(f, &s->sist0); - qemu_get_8s(f, &s->sist1); - qemu_get_8s(f, &s->sien0); - qemu_get_8s(f, &s->sien1); - qemu_get_8s(f, &s->mbox0); - qemu_get_8s(f, &s->mbox1); - qemu_get_8s(f, &s->dfifo); - qemu_get_8s(f, &s->ctest2); - qemu_get_8s(f, &s->ctest3); - qemu_get_8s(f, &s->ctest4); - qemu_get_8s(f, &s->ctest5); - qemu_get_8s(f, &s->ccntl0); - qemu_get_8s(f, &s->ccntl1); - qemu_get_be32s(f, &s->dsp); - qemu_get_be32s(f, &s->dsps); - qemu_get_8s(f, &s->dmode); - qemu_get_8s(f, &s->dcntl); - qemu_get_8s(f, &s->scntl0); - qemu_get_8s(f, &s->scntl1); - qemu_get_8s(f, &s->scntl2); - qemu_get_8s(f, &s->scntl3); - qemu_get_8s(f, &s->sstat0); - qemu_get_8s(f, &s->sstat1); - qemu_get_8s(f, &s->scid); - qemu_get_8s(f, &s->sxfer); - qemu_get_8s(f, &s->socl); - qemu_get_8s(f, &s->sdid); - qemu_get_8s(f, &s->ssid); - qemu_get_8s(f, &s->sfbr); - qemu_get_8s(f, &s->stest1); - qemu_get_8s(f, &s->stest2); - qemu_get_8s(f, &s->stest3); - qemu_get_8s(f, &s->sidl); - qemu_get_8s(f, &s->stime0); - qemu_get_8s(f, &s->respid0); - qemu_get_8s(f, &s->respid1); - qemu_get_be32s(f, &s->mmrs); - qemu_get_be32s(f, &s->mmws); - qemu_get_be32s(f, &s->sfs); - qemu_get_be32s(f, &s->drs); - qemu_get_be32s(f, &s->sbms); - qemu_get_be32s(f, &s->dbms); - qemu_get_be32s(f, &s->dnad64); - qemu_get_be32s(f, &s->pmjad1); - qemu_get_be32s(f, &s->pmjad2); - qemu_get_be32s(f, &s->rbc); - qemu_get_be32s(f, &s->ua); - qemu_get_be32s(f, &s->ia); - qemu_get_be32s(f, &s->sbc); - qemu_get_be32s(f, &s->csbc); - qemu_get_buffer(f, (uint8_t *)s->scratch, sizeof (s->scratch)); - qemu_get_8s(f, &s->sbr); - - qemu_get_buffer(f, (uint8_t *)s->script_ram, sizeof (s->script_ram)); - - return 0; -} +}; static int lsi_scsi_uninit(PCIDevice *d) { @@ -2178,8 +2102,10 @@ static int lsi_scsi_init(PCIDevice *dev) lsi_soft_reset(s); scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, lsi_command_complete); - scsi_bus_legacy_handle_cmdline(&s->bus); - register_savevm("lsiscsi", -1, 0, lsi_scsi_save, lsi_scsi_load, s); + if (!dev->qdev.hotplugged) { + scsi_bus_legacy_handle_cmdline(&s->bus); + } + vmstate_register(-1, &vmstate_lsi_scsi, s); return 0; } diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index e6e6cbfc5..61ddf0b35 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -76,16 +76,15 @@ struct RTCState { int64_t next_periodic_time; /* second update */ int64_t next_second_time; -#ifdef TARGET_I386 uint32_t irq_coalesced; uint32_t period; QEMUTimer *coalesced_timer; -#endif QEMUTimer *second_timer; QEMUTimer *second_timer2; }; -static void rtc_irq_raise(qemu_irq irq) { +static void rtc_irq_raise(qemu_irq irq) +{ /* When HPET is operating in legacy mode, RTC interrupts are disabled * We block qemu_irq_raise, but not qemu_irq_lower, in case legacy * mode is established while interrupt is raised. We want it to @@ -503,78 +502,46 @@ static void rtc_set_date_from_host(RTCState *s) rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val); } -static void rtc_save(QEMUFile *f, void *opaque) +static int rtc_post_load(void *opaque, int version_id) { - RTCState *s = opaque; - - qemu_put_buffer(f, s->cmos_data, 128); - qemu_put_8s(f, &s->cmos_index); - - qemu_put_be32(f, s->current_tm.tm_sec); - qemu_put_be32(f, s->current_tm.tm_min); - qemu_put_be32(f, s->current_tm.tm_hour); - qemu_put_be32(f, s->current_tm.tm_wday); - qemu_put_be32(f, s->current_tm.tm_mday); - qemu_put_be32(f, s->current_tm.tm_mon); - qemu_put_be32(f, s->current_tm.tm_year); - - qemu_put_timer(f, s->periodic_timer); - qemu_put_be64(f, s->next_periodic_time); - - qemu_put_be64(f, s->next_second_time); - qemu_put_timer(f, s->second_timer); - qemu_put_timer(f, s->second_timer2); -} - -static int rtc_load(QEMUFile *f, void *opaque, int version_id) -{ - RTCState *s = opaque; - - if (version_id != 1) - return -EINVAL; - - qemu_get_buffer(f, s->cmos_data, 128); - qemu_get_8s(f, &s->cmos_index); - - s->current_tm.tm_sec=qemu_get_be32(f); - s->current_tm.tm_min=qemu_get_be32(f); - s->current_tm.tm_hour=qemu_get_be32(f); - s->current_tm.tm_wday=qemu_get_be32(f); - s->current_tm.tm_mday=qemu_get_be32(f); - s->current_tm.tm_mon=qemu_get_be32(f); - s->current_tm.tm_year=qemu_get_be32(f); - - qemu_get_timer(f, s->periodic_timer); - s->next_periodic_time=qemu_get_be64(f); - - s->next_second_time=qemu_get_be64(f); - qemu_get_timer(f, s->second_timer); - qemu_get_timer(f, s->second_timer2); - return 0; -} - #ifdef TARGET_I386 -static void rtc_save_td(QEMUFile *f, void *opaque) -{ - RTCState *s = opaque; - - qemu_put_be32(f, s->irq_coalesced); - qemu_put_be32(f, s->period); -} - -static int rtc_load_td(QEMUFile *f, void *opaque, int version_id) -{ RTCState *s = opaque; - if (version_id != 1) - return -EINVAL; - - s->irq_coalesced = qemu_get_be32(f); - s->period = qemu_get_be32(f); - rtc_coalesced_timer_update(s); + if (version_id >= 2) { + if (rtc_td_hack) { + rtc_coalesced_timer_update(s); + } + } +#endif return 0; } -#endif + +static const VMStateDescription vmstate_rtc = { + .name = "mc146818rtc", + .version_id = 2, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .post_load = rtc_post_load, + .fields = (VMStateField []) { + VMSTATE_BUFFER(cmos_data, RTCState), + VMSTATE_UINT8(cmos_index, RTCState), + VMSTATE_INT32(current_tm.tm_sec, RTCState), + VMSTATE_INT32(current_tm.tm_min, RTCState), + VMSTATE_INT32(current_tm.tm_hour, RTCState), + VMSTATE_INT32(current_tm.tm_wday, RTCState), + VMSTATE_INT32(current_tm.tm_mday, RTCState), + VMSTATE_INT32(current_tm.tm_mon, RTCState), + VMSTATE_INT32(current_tm.tm_year, RTCState), + VMSTATE_TIMER(periodic_timer, RTCState), + VMSTATE_INT64(next_periodic_time, RTCState), + VMSTATE_INT64(next_second_time, RTCState), + VMSTATE_TIMER(second_timer, RTCState), + VMSTATE_TIMER(second_timer2, RTCState), + VMSTATE_UINT32_V(irq_coalesced, RTCState, 2), + VMSTATE_UINT32_V(period, RTCState, 2), + VMSTATE_END_OF_LIST() + } +}; static void rtc_reset(void *opaque) { @@ -622,11 +589,7 @@ static int rtc_initfn(ISADevice *dev) register_ioport_write(base, 2, 1, cmos_ioport_write, s); register_ioport_read(base, 2, 1, cmos_ioport_read, s); - register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s); -#ifdef TARGET_I386 - if (rtc_td_hack) - register_savevm("mc146818rtc-td", base, 1, rtc_save_td, rtc_load_td, s); -#endif + vmstate_register(base, &vmstate_rtc, s); qemu_register_reset(rtc_reset, s); return 0; } @@ -657,112 +620,3 @@ static void mc146818rtc_register(void) isa_qdev_register(&mc146818rtc_info); } device_init(mc146818rtc_register) - -/* Memory mapped interface */ -static uint32_t cmos_mm_readb (void *opaque, target_phys_addr_t addr) -{ - RTCState *s = opaque; - - return cmos_ioport_read(s, addr >> s->it_shift) & 0xFF; -} - -static void cmos_mm_writeb (void *opaque, - target_phys_addr_t addr, uint32_t value) -{ - RTCState *s = opaque; - - cmos_ioport_write(s, addr >> s->it_shift, value & 0xFF); -} - -static uint32_t cmos_mm_readw (void *opaque, target_phys_addr_t addr) -{ - RTCState *s = opaque; - uint32_t val; - - val = cmos_ioport_read(s, addr >> s->it_shift) & 0xFFFF; -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap16(val); -#endif - return val; -} - -static void cmos_mm_writew (void *opaque, - target_phys_addr_t addr, uint32_t value) -{ - RTCState *s = opaque; -#ifdef TARGET_WORDS_BIGENDIAN - value = bswap16(value); -#endif - cmos_ioport_write(s, addr >> s->it_shift, value & 0xFFFF); -} - -static uint32_t cmos_mm_readl (void *opaque, target_phys_addr_t addr) -{ - RTCState *s = opaque; - uint32_t val; - - val = cmos_ioport_read(s, addr >> s->it_shift); -#ifdef TARGET_WORDS_BIGENDIAN - val = bswap32(val); -#endif - return val; -} - -static void cmos_mm_writel (void *opaque, - target_phys_addr_t addr, uint32_t value) -{ - RTCState *s = opaque; -#ifdef TARGET_WORDS_BIGENDIAN - value = bswap32(value); -#endif - cmos_ioport_write(s, addr >> s->it_shift, value); -} - -static CPUReadMemoryFunc * const rtc_mm_read[] = { - &cmos_mm_readb, - &cmos_mm_readw, - &cmos_mm_readl, -}; - -static CPUWriteMemoryFunc * const rtc_mm_write[] = { - &cmos_mm_writeb, - &cmos_mm_writew, - &cmos_mm_writel, -}; - -RTCState *rtc_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, - int base_year) -{ - RTCState *s; - int io_memory; - - s = qemu_mallocz(sizeof(RTCState)); - - s->irq = irq; - s->cmos_data[RTC_REG_A] = 0x26; - s->cmos_data[RTC_REG_B] = 0x02; - s->cmos_data[RTC_REG_C] = 0x00; - s->cmos_data[RTC_REG_D] = 0x80; - - s->base_year = base_year; - rtc_set_date_from_host(s); - - s->periodic_timer = qemu_new_timer(rtc_clock, rtc_periodic_timer, s); - s->second_timer = qemu_new_timer(rtc_clock, rtc_update_second, s); - s->second_timer2 = qemu_new_timer(rtc_clock, rtc_update_second2, s); - - s->next_second_time = - qemu_get_clock(rtc_clock) + (get_ticks_per_sec() * 99) / 100; - qemu_mod_timer(s->second_timer2, s->next_second_time); - - io_memory = cpu_register_io_memory(rtc_mm_read, rtc_mm_write, s); - cpu_register_physical_memory(base, 2 << it_shift, io_memory); - - register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s); -#ifdef TARGET_I386 - if (rtc_td_hack) - register_savevm("mc146818rtc-td", base, 1, rtc_save_td, rtc_load_td, s); -#endif - qemu_register_reset(rtc_reset, s); - return s; -} diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c index 1da0d5446..8da0e8bb3 100644 --- a/hw/ne2000-isa.c +++ b/hw/ne2000-isa.c @@ -69,7 +69,7 @@ static int isa_ne2000_initfn(ISADevice *dev) isa_ne2000_cleanup, s); qemu_format_nic_info_str(s->vc, s->c.macaddr.a); - register_savevm("ne2000", -1, 2, ne2000_save, ne2000_load, s); + vmstate_register(-1, &vmstate_ne2000, s); return 0; } diff --git a/hw/ne2000.c b/hw/ne2000.c index 41893b353..a7a45778e 100644 --- a/hw/ne2000.c +++ b/hw/ne2000.c @@ -623,94 +623,57 @@ uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr) return 0; } -void ne2000_save(QEMUFile* f, void* opaque) +static int ne2000_post_load(void* opaque, int version_id) { - NE2000State* s = opaque; - uint32_t tmp; - - qemu_put_8s(f, &s->rxcr); - - qemu_put_8s(f, &s->cmd); - qemu_put_be32s(f, &s->start); - qemu_put_be32s(f, &s->stop); - qemu_put_8s(f, &s->boundary); - qemu_put_8s(f, &s->tsr); - qemu_put_8s(f, &s->tpsr); - qemu_put_be16s(f, &s->tcnt); - qemu_put_be16s(f, &s->rcnt); - qemu_put_be32s(f, &s->rsar); - qemu_put_8s(f, &s->rsr); - qemu_put_8s(f, &s->isr); - qemu_put_8s(f, &s->dcfg); - qemu_put_8s(f, &s->imr); - qemu_put_buffer(f, s->phys, 6); - qemu_put_8s(f, &s->curpag); - qemu_put_buffer(f, s->mult, 8); - tmp = 0; - qemu_put_be32s(f, &tmp); /* ignored, was irq */ - qemu_put_buffer(f, s->mem, NE2000_MEM_SIZE); -} - -int ne2000_load(QEMUFile* f, void* opaque, int version_id) -{ - NE2000State* s = opaque; - uint32_t tmp; - - if (version_id > 3) - return -EINVAL; - - if (version_id >= 2) { - qemu_get_8s(f, &s->rxcr); - } else { - s->rxcr = 0x0c; - } - - qemu_get_8s(f, &s->cmd); - qemu_get_be32s(f, &s->start); - qemu_get_be32s(f, &s->stop); - qemu_get_8s(f, &s->boundary); - qemu_get_8s(f, &s->tsr); - qemu_get_8s(f, &s->tpsr); - qemu_get_be16s(f, &s->tcnt); - qemu_get_be16s(f, &s->rcnt); - qemu_get_be32s(f, &s->rsar); - qemu_get_8s(f, &s->rsr); - qemu_get_8s(f, &s->isr); - qemu_get_8s(f, &s->dcfg); - qemu_get_8s(f, &s->imr); - qemu_get_buffer(f, s->phys, 6); - qemu_get_8s(f, &s->curpag); - qemu_get_buffer(f, s->mult, 8); - qemu_get_be32s(f, &tmp); /* ignored */ - qemu_get_buffer(f, s->mem, NE2000_MEM_SIZE); - - return 0; -} - -static void pci_ne2000_save(QEMUFile* f, void* opaque) -{ - PCINE2000State* s = opaque; + NE2000State* s = opaque; - pci_device_save(&s->dev, f); - ne2000_save(f, &s->ne2000); + if (version_id < 2) { + s->rxcr = 0x0c; + } + return 0; } -static int pci_ne2000_load(QEMUFile* f, void* opaque, int version_id) -{ - PCINE2000State* s = opaque; - int ret; - - if (version_id > 3) - return -EINVAL; - - if (version_id >= 3) { - ret = pci_device_load(&s->dev, f); - if (ret < 0) - return ret; - } +const VMStateDescription vmstate_ne2000 = { + .name = "ne2000", + .version_id = 2, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .post_load = ne2000_post_load, + .fields = (VMStateField []) { + VMSTATE_UINT8_V(rxcr, NE2000State, 2), + VMSTATE_UINT8(cmd, NE2000State), + VMSTATE_UINT32(start, NE2000State), + VMSTATE_UINT32(stop, NE2000State), + VMSTATE_UINT8(boundary, NE2000State), + VMSTATE_UINT8(tsr, NE2000State), + VMSTATE_UINT8(tpsr, NE2000State), + VMSTATE_UINT16(tcnt, NE2000State), + VMSTATE_UINT16(rcnt, NE2000State), + VMSTATE_UINT32(rsar, NE2000State), + VMSTATE_UINT8(rsr, NE2000State), + VMSTATE_UINT8(isr, NE2000State), + VMSTATE_UINT8(dcfg, NE2000State), + VMSTATE_UINT8(imr, NE2000State), + VMSTATE_BUFFER(phys, NE2000State), + VMSTATE_UINT8(curpag, NE2000State), + VMSTATE_BUFFER(mult, NE2000State), + VMSTATE_UNUSED(4), /* was irq */ + VMSTATE_BUFFER(mem, NE2000State), + VMSTATE_END_OF_LIST() + } +}; - return ne2000_load(f, &s->ne2000, version_id); -} +const VMStateDescription vmstate_pci_ne2000 = { + .name = "ne2000", + .version_id = 3, + .minimum_version_id = 3, + .minimum_version_id_old = 3, + .fields = (VMStateField []) { + VMSTATE_PCI_DEVICE(dev, PCINE2000State), + VMSTATE_STRUCT(ne2000, PCINE2000State, 0, vmstate_ne2000, NE2000State), + VMSTATE_END_OF_LIST() + } +}; /***********************************************************/ /* PCI NE2000 definitions */ @@ -776,7 +739,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev) } } - register_savevm("ne2000", -1, 3, pci_ne2000_save, pci_ne2000_load, d); + vmstate_register(-1, &vmstate_pci_ne2000, d); return 0; } @@ -785,7 +748,7 @@ static int pci_ne2000_exit(PCIDevice *pci_dev) PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev); NE2000State *s = &d->ne2000; - unregister_savevm("ne2000", s); + vmstate_unregister(&vmstate_pci_ne2000, s); qemu_del_vlan_client(s->vc); return 0; } diff --git a/hw/ne2000.h b/hw/ne2000.h index 78422465c..2bbce71e6 100644 --- a/hw/ne2000.h +++ b/hw/ne2000.h @@ -33,8 +33,7 @@ void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val); uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr); void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val); uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr); -void ne2000_save(QEMUFile* f, void* opaque); -int ne2000_load(QEMUFile* f, void* opaque, int version_id); +extern const VMStateDescription vmstate_ne2000; void ne2000_reset(NE2000State *s); int ne2000_can_receive(VLANClientState *vc); ssize_t ne2000_receive(VLANClientState *vc, const uint8_t *buf, size_t size_); diff --git a/hw/parallel.c b/hw/parallel.c index 92eecb152..79fa8f66b 100644 --- a/hw/parallel.c +++ b/hw/parallel.c @@ -80,6 +80,7 @@ struct ParallelState { typedef struct ISAParallelState { ISADevice dev; + uint32_t index; uint32_t iobase; uint32_t isairq; ParallelState state; @@ -445,11 +446,14 @@ static void parallel_reset(void *opaque) s->last_read_offset = ~0U; } +static const int isa_parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc }; + static int parallel_isa_initfn(ISADevice *dev) { + static int index; ISAParallelState *isa = DO_UPCAST(ISAParallelState, dev, dev); ParallelState *s = &isa->state; - int base = isa->iobase; + int base; uint8_t dummy; if (!s->chr) { @@ -457,6 +461,15 @@ static int parallel_isa_initfn(ISADevice *dev) exit(1); } + if (isa->index == -1) + isa->index = index; + if (isa->index >= MAX_PARALLEL_PORTS) + return -1; + if (isa->iobase == -1) + isa->iobase = isa_parallel_io[isa->index]; + index++; + + base = isa->iobase; isa_init_irq(dev, &s->irq, isa->isairq); parallel_reset(s); qemu_register_reset(parallel_reset, s); @@ -483,15 +496,12 @@ static int parallel_isa_initfn(ISADevice *dev) return 0; } -static const int isa_parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc }; - ParallelState *parallel_init(int index, CharDriverState *chr) { ISADevice *dev; dev = isa_create("isa-parallel"); - qdev_prop_set_uint32(&dev->qdev, "iobase", isa_parallel_io[index]); - qdev_prop_set_uint32(&dev->qdev, "irq", 7); + qdev_prop_set_uint32(&dev->qdev, "index", index); qdev_prop_set_chr(&dev->qdev, "chardev", chr); if (qdev_init(&dev->qdev) < 0) return NULL; @@ -579,7 +589,8 @@ static ISADeviceInfo parallel_isa_info = { .qdev.size = sizeof(ISAParallelState), .init = parallel_isa_initfn, .qdev.props = (Property[]) { - DEFINE_PROP_HEX32("iobase", ISAParallelState, iobase, 0x378), + DEFINE_PROP_HEX32("index", ISAParallelState, index, -1), + DEFINE_PROP_HEX32("iobase", ISAParallelState, iobase, -1), DEFINE_PROP_UINT32("irq", ISAParallelState, isairq, 7), DEFINE_PROP_CHR("chardev", ISAParallelState, state.chr), DEFINE_PROP_END_OF_LIST(), @@ -89,8 +89,6 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, typedef struct RTCState RTCState; RTCState *rtc_init(int base_year); -RTCState *rtc_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, - int base_year); void rtc_set_memory(RTCState *s, int addr, int val); void rtc_set_date(RTCState *s, const struct tm *tm); void cmos_set_s3_resume(void); diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c index 15f96a3ff..e7be07a0f 100644 --- a/hw/pci-hotplug.c +++ b/hw/pci-hotplug.c @@ -62,6 +62,33 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon, return pci_nic_init(&nd_table[ret], "rtl8139", devaddr); } +static int scsi_hot_add(DeviceState *adapter, DriveInfo *dinfo, int printinfo) +{ + SCSIBus *scsibus; + SCSIDevice *scsidev; + + scsibus = DO_UPCAST(SCSIBus, qbus, QLIST_FIRST(&adapter->child_bus)); + if (!scsibus || strcmp(scsibus->qbus.info->name, "SCSI") != 0) { + qemu_error("Device is not a SCSI adapter\n"); + return -1; + } + + /* + * drive_init() tries to find a default for dinfo->unit. Doesn't + * work at all for hotplug though as we assign the device to a + * specific bus instead of the first bus with spare scsi ids. + * + * Ditch the calculated value and reload from option string (if + * specified). + */ + dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1); + scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo, dinfo->unit); + + if (printinfo) + qemu_error("OK bus %d, unit %d\n", scsibus->busnr, scsidev->id); + return 0; +} + void drive_hot_add(Monitor *mon, const QDict *qdict) { int dom, pci_bus; @@ -71,7 +98,6 @@ void drive_hot_add(Monitor *mon, const QDict *qdict) DriveInfo *dinfo = NULL; const char *pci_addr = qdict_get_str(qdict, "pci_addr"); const char *opts = qdict_get_str(qdict, "opts"); - BusState *scsibus; dinfo = add_init_drive(opts); if (!dinfo) @@ -93,12 +119,9 @@ void drive_hot_add(Monitor *mon, const QDict *qdict) monitor_printf(mon, "no pci device with address %s\n", pci_addr); goto err; } - scsibus = QLIST_FIRST(&dev->qdev.child_bus); - scsi_bus_legacy_add_drive(DO_UPCAST(SCSIBus, qbus, scsibus), - dinfo, dinfo->unit); - monitor_printf(mon, "OK bus %d, unit %d\n", - dinfo->bus, - dinfo->unit); + if (scsi_hot_add(&dev->qdev, dinfo, 1) != 0) { + goto err; + } break; case IF_NONE: monitor_printf(mon, "OK\n"); @@ -160,7 +183,19 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon, switch (type) { case IF_SCSI: + if (!dinfo) { + monitor_printf(mon, "scsi requires a backing file/device.\n"); + return NULL; + } dev = pci_create(bus, devfn, "lsi53c895a"); + if (qdev_init(&dev->qdev) < 0) + dev = NULL; + if (dev) { + if (scsi_hot_add(&dev->qdev, dinfo, 0) != 0) { + qdev_unplug(&dev->qdev); + dev = NULL; + } + } break; case IF_VIRTIO: if (!dinfo) { @@ -169,12 +204,12 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon, } dev = pci_create(bus, devfn, "virtio-blk-pci"); qdev_prop_set_drive(&dev->qdev, "drive", dinfo); + if (qdev_init(&dev->qdev) < 0) + dev = NULL; break; default: dev = NULL; } - if (!dev || qdev_init(&dev->qdev) < 0) - return NULL; return dev; } @@ -253,7 +288,8 @@ void pci_device_hot_remove(Monitor *mon, const char *pci_addr) qdev_unplug(&d->qdev); } -void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict) +void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict, + QObject **ret_data) { pci_device_hot_remove(mon, qdict_get_str(qdict, "pci_addr")); } @@ -82,7 +82,7 @@ static const VMStateDescription vmstate_pcibus = { .minimum_version_id_old = 1, .fields = (VMStateField []) { VMSTATE_INT32_EQUAL(nirq, PCIBus), - VMSTATE_INT32_VARRAY(irq_count, PCIBus, nirq), + VMSTATE_VARRAY_INT32(irq_count, PCIBus, nirq, 0, vmstate_info_int32, int32_t), VMSTATE_END_OF_LIST() } }; diff --git a/hw/pci_ids.h b/hw/pci_ids.h index 3afe6748f..63379c234 100644 --- a/hw/pci_ids.h +++ b/hw/pci_ids.h @@ -88,6 +88,7 @@ #define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_DEVICE_ID_INTEL_82441 0x1237 #define PCI_DEVICE_ID_INTEL_82801AA_5 0x2415 +#define PCI_DEVICE_ID_INTEL_ESB_9 0x25ab #define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 #define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 #define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020 diff --git a/hw/pcnet.c b/hw/pcnet.c index eb64d33c3..044d7acff 100644 --- a/hw/pcnet.c +++ b/hw/pcnet.c @@ -1844,78 +1844,46 @@ static uint32_t pcnet_mmio_readl(void *opaque, target_phys_addr_t addr) return val; } - -void pcnet_save(QEMUFile *f, void *opaque) +static bool is_version_2(void *opaque, int version_id) { - PCNetState *s = opaque; - unsigned int i; - - qemu_put_sbe32(f, s->rap); - qemu_put_sbe32(f, s->isr); - qemu_put_sbe32(f, s->lnkst); - qemu_put_be32s(f, &s->rdra); - qemu_put_be32s(f, &s->tdra); - qemu_put_buffer(f, s->prom, 16); - for (i = 0; i < 128; i++) - qemu_put_be16s(f, &s->csr[i]); - for (i = 0; i < 32; i++) - qemu_put_be16s(f, &s->bcr[i]); - qemu_put_be64s(f, &s->timer); - qemu_put_sbe32(f, s->xmit_pos); - qemu_put_buffer(f, s->buffer, 4096); - qemu_put_sbe32(f, s->tx_busy); - qemu_put_timer(f, s->poll_timer); + return version_id == 2; } -int pcnet_load(QEMUFile *f, void *opaque, int version_id) -{ - PCNetState *s = opaque; - int i, dummy; - - if (version_id < 2 || version_id > 3) - return -EINVAL; - - qemu_get_sbe32s(f, &s->rap); - qemu_get_sbe32s(f, &s->isr); - qemu_get_sbe32s(f, &s->lnkst); - qemu_get_be32s(f, &s->rdra); - qemu_get_be32s(f, &s->tdra); - qemu_get_buffer(f, s->prom, 16); - for (i = 0; i < 128; i++) - qemu_get_be16s(f, &s->csr[i]); - for (i = 0; i < 32; i++) - qemu_get_be16s(f, &s->bcr[i]); - qemu_get_be64s(f, &s->timer); - qemu_get_sbe32s(f, &s->xmit_pos); - if (version_id == 2) { - qemu_get_sbe32s(f, &dummy); +const VMStateDescription vmstate_pcnet = { + .name = "pcnet", + .version_id = 3, + .minimum_version_id = 2, + .minimum_version_id_old = 2, + .fields = (VMStateField []) { + VMSTATE_INT32(rap, PCNetState), + VMSTATE_INT32(isr, PCNetState), + VMSTATE_INT32(lnkst, PCNetState), + VMSTATE_UINT32(rdra, PCNetState), + VMSTATE_UINT32(tdra, PCNetState), + VMSTATE_BUFFER(prom, PCNetState), + VMSTATE_UINT16_ARRAY(csr, PCNetState, 128), + VMSTATE_UINT16_ARRAY(bcr, PCNetState, 32), + VMSTATE_UINT64(timer, PCNetState), + VMSTATE_INT32(xmit_pos, PCNetState), + VMSTATE_BUFFER(buffer, PCNetState), + VMSTATE_UNUSED_TEST(is_version_2, 4), + VMSTATE_INT32(tx_busy, PCNetState), + VMSTATE_TIMER(poll_timer, PCNetState), + VMSTATE_END_OF_LIST() } - qemu_get_buffer(f, s->buffer, 4096); - qemu_get_sbe32s(f, &s->tx_busy); - qemu_get_timer(f, s->poll_timer); - - return 0; -} - -static void pci_pcnet_save(QEMUFile *f, void *opaque) -{ - PCIPCNetState *s = opaque; - - pci_device_save(&s->pci_dev, f); - pcnet_save(f, &s->state); -} - -static int pci_pcnet_load(QEMUFile *f, void *opaque, int version_id) -{ - PCIPCNetState *s = opaque; - int ret; - - ret = pci_device_load(&s->pci_dev, f); - if (ret < 0) - return ret; +}; - return pcnet_load(f, &s->state, version_id); -} +static const VMStateDescription vmstate_pci_pcnet = { + .name = "pcnet", + .version_id = 3, + .minimum_version_id = 2, + .minimum_version_id_old = 2, + .fields = (VMStateField []) { + VMSTATE_PCI_DEVICE(pci_dev, PCIPCNetState), + VMSTATE_STRUCT(state, PCIPCNetState, 0, vmstate_pcnet, PCNetState), + VMSTATE_END_OF_LIST() + } +}; void pcnet_common_cleanup(PCNetState *d) { @@ -1987,7 +1955,7 @@ static int pci_pcnet_uninit(PCIDevice *dev) PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev); cpu_unregister_io_memory(d->state.mmio_index); - unregister_savevm("pcnet", d); + vmstate_unregister(&vmstate_pci_pcnet, d); qemu_del_timer(d->state.poll_timer); qemu_free_timer(d->state.poll_timer); qemu_del_vlan_client(d->state.vc); @@ -2037,7 +2005,7 @@ static int pci_pcnet_init(PCIDevice *pci_dev) s->phys_mem_read = pci_physical_memory_read; s->phys_mem_write = pci_physical_memory_write; - register_savevm("pcnet", -1, 3, pci_pcnet_save, pci_pcnet_load, d); + vmstate_register(-1, &vmstate_pci_pcnet, d); if (!pci_dev->qdev.hotplugged) { static int loaded = 0; diff --git a/hw/pcnet.h b/hw/pcnet.h index a94b6054a..e61d5a447 100644 --- a/hw/pcnet.h +++ b/hw/pcnet.h @@ -35,5 +35,4 @@ uint32_t pcnet_ioport_readw(void *opaque, uint32_t addr); void pcnet_common_cleanup(PCNetState *d); int pcnet_common_init(DeviceState *dev, PCNetState *s, NetCleanup *cleanup); -void pcnet_save(QEMUFile *f, void *opaque); -int pcnet_load(QEMUFile *f, void *opaque, int version_id); +extern const VMStateDescription vmstate_pcnet; diff --git a/hw/rtl8139.c b/hw/rtl8139.c index de602469e..10c7040b8 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -417,12 +417,6 @@ static void RTL8139TallyCounters_clear(RTL8139TallyCounters* counters); /* Writes tally counters to specified physical memory address */ static void RTL8139TallyCounters_physical_memory_write(target_phys_addr_t tc_addr, RTL8139TallyCounters* counters); -/* Loads values of tally counters from VM state file */ -static void RTL8139TallyCounters_load(QEMUFile* f, RTL8139TallyCounters *tally_counters); - -/* Saves values of tally counters to VM state file */ -static void RTL8139TallyCounters_save(QEMUFile* f, RTL8139TallyCounters *tally_counters); - typedef struct RTL8139State { PCIDevice dev; uint8_t phys[8]; /* mac address */ @@ -1328,40 +1322,28 @@ static void RTL8139TallyCounters_physical_memory_write(target_phys_addr_t tc_add } /* Loads values of tally counters from VM state file */ -static void RTL8139TallyCounters_load(QEMUFile* f, RTL8139TallyCounters *tally_counters) -{ - qemu_get_be64s(f, &tally_counters->TxOk); - qemu_get_be64s(f, &tally_counters->RxOk); - qemu_get_be64s(f, &tally_counters->TxERR); - qemu_get_be32s(f, &tally_counters->RxERR); - qemu_get_be16s(f, &tally_counters->MissPkt); - qemu_get_be16s(f, &tally_counters->FAE); - qemu_get_be32s(f, &tally_counters->Tx1Col); - qemu_get_be32s(f, &tally_counters->TxMCol); - qemu_get_be64s(f, &tally_counters->RxOkPhy); - qemu_get_be64s(f, &tally_counters->RxOkBrd); - qemu_get_be32s(f, &tally_counters->RxOkMul); - qemu_get_be16s(f, &tally_counters->TxAbt); - qemu_get_be16s(f, &tally_counters->TxUndrn); -} - -/* Saves values of tally counters to VM state file */ -static void RTL8139TallyCounters_save(QEMUFile* f, RTL8139TallyCounters *tally_counters) -{ - qemu_put_be64s(f, &tally_counters->TxOk); - qemu_put_be64s(f, &tally_counters->RxOk); - qemu_put_be64s(f, &tally_counters->TxERR); - qemu_put_be32s(f, &tally_counters->RxERR); - qemu_put_be16s(f, &tally_counters->MissPkt); - qemu_put_be16s(f, &tally_counters->FAE); - qemu_put_be32s(f, &tally_counters->Tx1Col); - qemu_put_be32s(f, &tally_counters->TxMCol); - qemu_put_be64s(f, &tally_counters->RxOkPhy); - qemu_put_be64s(f, &tally_counters->RxOkBrd); - qemu_put_be32s(f, &tally_counters->RxOkMul); - qemu_put_be16s(f, &tally_counters->TxAbt); - qemu_put_be16s(f, &tally_counters->TxUndrn); -} + +static const VMStateDescription vmstate_tally_counters = { + .name = "tally_counters", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT64(TxOk, RTL8139TallyCounters), + VMSTATE_UINT64(RxOk, RTL8139TallyCounters), + VMSTATE_UINT64(TxERR, RTL8139TallyCounters), + VMSTATE_UINT32(RxERR, RTL8139TallyCounters), + VMSTATE_UINT16(MissPkt, RTL8139TallyCounters), + VMSTATE_UINT16(FAE, RTL8139TallyCounters), + VMSTATE_UINT32(Tx1Col, RTL8139TallyCounters), + VMSTATE_UINT32(TxMCol, RTL8139TallyCounters), + VMSTATE_UINT64(RxOkPhy, RTL8139TallyCounters), + VMSTATE_UINT64(RxOkBrd, RTL8139TallyCounters), + VMSTATE_UINT16(TxAbt, RTL8139TallyCounters), + VMSTATE_UINT16(TxUndrn, RTL8139TallyCounters), + VMSTATE_END_OF_LIST() + } +}; static void rtl8139_ChipCmd_write(RTL8139State *s, uint32_t val) { @@ -3115,212 +3097,97 @@ static uint32_t rtl8139_mmio_readl(void *opaque, target_phys_addr_t addr) return val; } -/* */ - -static void rtl8139_save(QEMUFile* f,void* opaque) -{ - RTL8139State* s = opaque; - unsigned int i; - - pci_device_save(&s->dev, f); - - qemu_put_buffer(f, s->phys, 6); - qemu_put_buffer(f, s->mult, 8); - - for (i=0; i<4; ++i) - { - qemu_put_be32s(f, &s->TxStatus[i]); /* TxStatus0 */ - } - for (i=0; i<4; ++i) - { - qemu_put_be32s(f, &s->TxAddr[i]); /* TxAddr0 */ - } - - qemu_put_be32s(f, &s->RxBuf); /* Receive buffer */ - qemu_put_be32s(f, &s->RxBufferSize);/* internal variable, receive ring buffer size in C mode */ - qemu_put_be32s(f, &s->RxBufPtr); - qemu_put_be32s(f, &s->RxBufAddr); - - qemu_put_be16s(f, &s->IntrStatus); - qemu_put_be16s(f, &s->IntrMask); - - qemu_put_be32s(f, &s->TxConfig); - qemu_put_be32s(f, &s->RxConfig); - qemu_put_be32s(f, &s->RxMissed); - qemu_put_be16s(f, &s->CSCR); - - qemu_put_8s(f, &s->Cfg9346); - qemu_put_8s(f, &s->Config0); - qemu_put_8s(f, &s->Config1); - qemu_put_8s(f, &s->Config3); - qemu_put_8s(f, &s->Config4); - qemu_put_8s(f, &s->Config5); - - qemu_put_8s(f, &s->clock_enabled); - qemu_put_8s(f, &s->bChipCmdState); - - qemu_put_be16s(f, &s->MultiIntr); - - qemu_put_be16s(f, &s->BasicModeCtrl); - qemu_put_be16s(f, &s->BasicModeStatus); - qemu_put_be16s(f, &s->NWayAdvert); - qemu_put_be16s(f, &s->NWayLPAR); - qemu_put_be16s(f, &s->NWayExpansion); - - qemu_put_be16s(f, &s->CpCmd); - qemu_put_8s(f, &s->TxThresh); - - i = 0; - qemu_put_be32s(f, &i); /* unused. */ - qemu_put_buffer(f, s->conf.macaddr.a, 6); - qemu_put_be32(f, s->rtl8139_mmio_io_addr); - - qemu_put_be32s(f, &s->currTxDesc); - qemu_put_be32s(f, &s->currCPlusRxDesc); - qemu_put_be32s(f, &s->currCPlusTxDesc); - qemu_put_be32s(f, &s->RxRingAddrLO); - qemu_put_be32s(f, &s->RxRingAddrHI); - - for (i=0; i<EEPROM_9346_SIZE; ++i) - { - qemu_put_be16s(f, &s->eeprom.contents[i]); - } - qemu_put_be32(f, s->eeprom.mode); - qemu_put_be32s(f, &s->eeprom.tick); - qemu_put_8s(f, &s->eeprom.address); - qemu_put_be16s(f, &s->eeprom.input); - qemu_put_be16s(f, &s->eeprom.output); - - qemu_put_8s(f, &s->eeprom.eecs); - qemu_put_8s(f, &s->eeprom.eesk); - qemu_put_8s(f, &s->eeprom.eedi); - qemu_put_8s(f, &s->eeprom.eedo); - - qemu_put_be32s(f, &s->TCTR); - qemu_put_be32s(f, &s->TimerInt); - qemu_put_be64(f, s->TCTR_base); - - RTL8139TallyCounters_save(f, &s->tally_counters); - - qemu_put_be32s(f, &s->cplus_enabled); -} - -static int rtl8139_load(QEMUFile* f,void* opaque,int version_id) +static int rtl8139_post_load(void *opaque, int version_id) { RTL8139State* s = opaque; - unsigned int i; - int ret; - - /* just 2 versions for now */ - if (version_id > 4) - return -EINVAL; - - if (version_id >= 3) { - ret = pci_device_load(&s->dev, f); - if (ret < 0) - return ret; - } - - /* saved since version 1 */ - qemu_get_buffer(f, s->phys, 6); - qemu_get_buffer(f, s->mult, 8); - - for (i=0; i<4; ++i) - { - qemu_get_be32s(f, &s->TxStatus[i]); /* TxStatus0 */ - } - for (i=0; i<4; ++i) - { - qemu_get_be32s(f, &s->TxAddr[i]); /* TxAddr0 */ - } - - qemu_get_be32s(f, &s->RxBuf); /* Receive buffer */ - qemu_get_be32s(f, &s->RxBufferSize);/* internal variable, receive ring buffer size in C mode */ - qemu_get_be32s(f, &s->RxBufPtr); - qemu_get_be32s(f, &s->RxBufAddr); - - qemu_get_be16s(f, &s->IntrStatus); - qemu_get_be16s(f, &s->IntrMask); - - qemu_get_be32s(f, &s->TxConfig); - qemu_get_be32s(f, &s->RxConfig); - qemu_get_be32s(f, &s->RxMissed); - qemu_get_be16s(f, &s->CSCR); - - qemu_get_8s(f, &s->Cfg9346); - qemu_get_8s(f, &s->Config0); - qemu_get_8s(f, &s->Config1); - qemu_get_8s(f, &s->Config3); - qemu_get_8s(f, &s->Config4); - qemu_get_8s(f, &s->Config5); - - qemu_get_8s(f, &s->clock_enabled); - qemu_get_8s(f, &s->bChipCmdState); - - qemu_get_be16s(f, &s->MultiIntr); - - qemu_get_be16s(f, &s->BasicModeCtrl); - qemu_get_be16s(f, &s->BasicModeStatus); - qemu_get_be16s(f, &s->NWayAdvert); - qemu_get_be16s(f, &s->NWayLPAR); - qemu_get_be16s(f, &s->NWayExpansion); - - qemu_get_be16s(f, &s->CpCmd); - qemu_get_8s(f, &s->TxThresh); - - qemu_get_be32s(f, &i); /* unused. */ - qemu_get_buffer(f, s->conf.macaddr.a, 6); - s->rtl8139_mmio_io_addr=qemu_get_be32(f); - - qemu_get_be32s(f, &s->currTxDesc); - qemu_get_be32s(f, &s->currCPlusRxDesc); - qemu_get_be32s(f, &s->currCPlusTxDesc); - qemu_get_be32s(f, &s->RxRingAddrLO); - qemu_get_be32s(f, &s->RxRingAddrHI); - - for (i=0; i<EEPROM_9346_SIZE; ++i) - { - qemu_get_be16s(f, &s->eeprom.contents[i]); - } - s->eeprom.mode=qemu_get_be32(f); - qemu_get_be32s(f, &s->eeprom.tick); - qemu_get_8s(f, &s->eeprom.address); - qemu_get_be16s(f, &s->eeprom.input); - qemu_get_be16s(f, &s->eeprom.output); - - qemu_get_8s(f, &s->eeprom.eecs); - qemu_get_8s(f, &s->eeprom.eesk); - qemu_get_8s(f, &s->eeprom.eedi); - qemu_get_8s(f, &s->eeprom.eedo); - - /* saved since version 2 */ - if (version_id >= 2) - { - qemu_get_be32s(f, &s->TCTR); - qemu_get_be32s(f, &s->TimerInt); - s->TCTR_base=qemu_get_be64(f); - - RTL8139TallyCounters_load(f, &s->tally_counters); - } - else - { - /* not saved, use default */ - s->TCTR = 0; - s->TimerInt = 0; - s->TCTR_base = 0; - - RTL8139TallyCounters_clear(&s->tally_counters); - } - - if (version_id >= 4) { - qemu_get_be32s(f, &s->cplus_enabled); - } else { + if (version_id < 4) { s->cplus_enabled = s->CpCmd != 0; } return 0; } +static const VMStateDescription vmstate_rtl8139 = { + .name = "rtl8139", + .version_id = 4, + .minimum_version_id = 3, + .minimum_version_id_old = 3, + .post_load = rtl8139_post_load, + .fields = (VMStateField []) { + VMSTATE_PCI_DEVICE(dev, RTL8139State), + VMSTATE_PARTIAL_BUFFER(phys, RTL8139State, 6), + VMSTATE_BUFFER(mult, RTL8139State), + VMSTATE_UINT32_ARRAY(TxStatus, RTL8139State, 4), + VMSTATE_UINT32_ARRAY(TxAddr, RTL8139State, 4), + + VMSTATE_UINT32(RxBuf, RTL8139State), + VMSTATE_UINT32(RxBufferSize, RTL8139State), + VMSTATE_UINT32(RxBufPtr, RTL8139State), + VMSTATE_UINT32(RxBufAddr, RTL8139State), + + VMSTATE_UINT16(IntrStatus, RTL8139State), + VMSTATE_UINT16(IntrMask, RTL8139State), + + VMSTATE_UINT32(TxConfig, RTL8139State), + VMSTATE_UINT32(RxConfig, RTL8139State), + VMSTATE_UINT32(RxMissed, RTL8139State), + VMSTATE_UINT16(CSCR, RTL8139State), + + VMSTATE_UINT8(Cfg9346, RTL8139State), + VMSTATE_UINT8(Config0, RTL8139State), + VMSTATE_UINT8(Config1, RTL8139State), + VMSTATE_UINT8(Config3, RTL8139State), + VMSTATE_UINT8(Config4, RTL8139State), + VMSTATE_UINT8(Config5, RTL8139State), + + VMSTATE_UINT8(clock_enabled, RTL8139State), + VMSTATE_UINT8(bChipCmdState, RTL8139State), + + VMSTATE_UINT16(MultiIntr, RTL8139State), + + VMSTATE_UINT16(BasicModeCtrl, RTL8139State), + VMSTATE_UINT16(BasicModeStatus, RTL8139State), + VMSTATE_UINT16(NWayAdvert, RTL8139State), + VMSTATE_UINT16(NWayLPAR, RTL8139State), + VMSTATE_UINT16(NWayExpansion, RTL8139State), + + VMSTATE_UINT16(CpCmd, RTL8139State), + VMSTATE_UINT8(TxThresh, RTL8139State), + + VMSTATE_UNUSED(4), + VMSTATE_MACADDR(conf.macaddr, RTL8139State), + VMSTATE_INT32(rtl8139_mmio_io_addr, RTL8139State), + + VMSTATE_UINT32(currTxDesc, RTL8139State), + VMSTATE_UINT32(currCPlusRxDesc, RTL8139State), + VMSTATE_UINT32(currCPlusTxDesc, RTL8139State), + VMSTATE_UINT32(RxRingAddrLO, RTL8139State), + VMSTATE_UINT32(RxRingAddrHI, RTL8139State), + + VMSTATE_UINT16_ARRAY(eeprom.contents, RTL8139State, EEPROM_9346_SIZE), + VMSTATE_INT32(eeprom.mode, RTL8139State), + VMSTATE_UINT32(eeprom.tick, RTL8139State), + VMSTATE_UINT8(eeprom.address, RTL8139State), + VMSTATE_UINT16(eeprom.input, RTL8139State), + VMSTATE_UINT16(eeprom.output, RTL8139State), + + VMSTATE_UINT8(eeprom.eecs, RTL8139State), + VMSTATE_UINT8(eeprom.eesk, RTL8139State), + VMSTATE_UINT8(eeprom.eedi, RTL8139State), + VMSTATE_UINT8(eeprom.eedo, RTL8139State), + + VMSTATE_UINT32(TCTR, RTL8139State), + VMSTATE_UINT32(TimerInt, RTL8139State), + VMSTATE_INT64(TCTR_base, RTL8139State), + + VMSTATE_STRUCT(tally_counters, RTL8139State, 0, + vmstate_tally_counters, RTL8139TallyCounters), + + VMSTATE_UINT32_V(cplus_enabled, RTL8139State, 4), + VMSTATE_END_OF_LIST() + } +}; + /***********************************************************/ /* PCI RTL8139 definitions */ @@ -3433,7 +3300,7 @@ static int pci_rtl8139_uninit(PCIDevice *dev) qemu_del_timer(s->timer); qemu_free_timer(s->timer); #endif - unregister_savevm("rtl8139", s); + vmstate_unregister(&vmstate_rtl8139, s); qemu_del_vlan_client(s->vc); return 0; } @@ -3475,7 +3342,7 @@ static int pci_rtl8139_init(PCIDevice *dev) s->cplus_txbuffer_len = 0; s->cplus_txbuffer_offset = 0; - register_savevm("rtl8139", -1, 4, rtl8139_save, rtl8139_load, s); + vmstate_register(-1, &vmstate_rtl8139, s); #ifdef RTL8139_ONBOARD_TIMER s->timer = qemu_new_timer(vm_clock, rtl8139_timer, s); diff --git a/hw/serial.c b/hw/serial.c index eb14f11ba..86ac543ec 100644 --- a/hw/serial.c +++ b/hw/serial.c @@ -148,6 +148,7 @@ struct SerialState { typedef struct ISASerialState { ISADevice dev; + uint32_t index; uint32_t iobase; uint32_t isairq; SerialState state; @@ -648,17 +649,13 @@ static void serial_pre_save(void *opaque) s->fcr_vmstate = s->fcr; } -static int serial_pre_load(void *opaque) -{ - SerialState *s = opaque; - s->fcr_vmstate = 0; - return 0; -} - static int serial_post_load(void *opaque, int version_id) { SerialState *s = opaque; + if (version_id < 3) { + s->fcr_vmstate = 0; + } /* Initialize fcr via setter to perform essential side-effects */ serial_ioport_write(s, 0x02, s->fcr_vmstate); return 0; @@ -669,7 +666,6 @@ static const VMStateDescription vmstate_serial = { .version_id = 3, .minimum_version_id = 2, .pre_save = serial_pre_save, - .pre_load = serial_pre_load, .post_load = serial_post_load, .fields = (VMStateField []) { VMSTATE_UINT16_V(divider, SerialState, 2), @@ -733,11 +729,25 @@ static void serial_init_core(SerialState *s) serial_event, s); } +static const int isa_serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; +static const int isa_serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 }; + static int serial_isa_initfn(ISADevice *dev) { + static int index; ISASerialState *isa = DO_UPCAST(ISASerialState, dev, dev); SerialState *s = &isa->state; + if (isa->index == -1) + isa->index = index; + if (isa->index >= MAX_SERIAL_PORTS) + return -1; + if (isa->iobase == -1) + isa->iobase = isa_serial_io[isa->index]; + if (isa->isairq == -1) + isa->isairq = isa_serial_irq[isa->index]; + index++; + s->baudbase = 115200; isa_init_irq(dev, &s->irq, isa->isairq); serial_init_core(s); @@ -748,16 +758,12 @@ static int serial_isa_initfn(ISADevice *dev) return 0; } -static const int isa_serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; -static const int isa_serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 }; - SerialState *serial_isa_init(int index, CharDriverState *chr) { ISADevice *dev; dev = isa_create("isa-serial"); - qdev_prop_set_uint32(&dev->qdev, "iobase", isa_serial_io[index]); - qdev_prop_set_uint32(&dev->qdev, "irq", isa_serial_irq[index]); + qdev_prop_set_uint32(&dev->qdev, "index", index); qdev_prop_set_chr(&dev->qdev, "chardev", chr); if (qdev_init(&dev->qdev) < 0) return NULL; @@ -886,8 +892,9 @@ static ISADeviceInfo serial_isa_info = { .qdev.size = sizeof(ISASerialState), .init = serial_isa_initfn, .qdev.props = (Property[]) { - DEFINE_PROP_HEX32("iobase", ISASerialState, iobase, 0x3f8), - DEFINE_PROP_UINT32("irq", ISASerialState, isairq, 4), + DEFINE_PROP_HEX32("index", ISASerialState, index, -1), + DEFINE_PROP_HEX32("iobase", ISASerialState, iobase, -1), + DEFINE_PROP_UINT32("irq", ISASerialState, isairq, -1), DEFINE_PROP_CHR("chardev", ISASerialState, state.chr), DEFINE_PROP_END_OF_LIST(), }, diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c index a3ed9b282..67a9a233c 100644 --- a/hw/usb-uhci.c +++ b/hw/usb-uhci.c @@ -139,6 +139,7 @@ typedef struct UHCIState { /* Active packets */ UHCIAsync *async_pending; UHCIAsync *async_pool; + uint8_t num_ports_vmstate; } UHCIState; typedef struct UHCI_TD { @@ -350,59 +351,46 @@ static void uhci_reset(void *opaque) uhci_async_cancel_all(s); } -static void uhci_save(QEMUFile *f, void *opaque) +static void uhci_pre_save(void *opaque) { UHCIState *s = opaque; - uint8_t num_ports = NB_PORTS; - int i; uhci_async_cancel_all(s); - - pci_device_save(&s->dev, f); - - qemu_put_8s(f, &num_ports); - for (i = 0; i < num_ports; ++i) - qemu_put_be16s(f, &s->ports[i].ctrl); - qemu_put_be16s(f, &s->cmd); - qemu_put_be16s(f, &s->status); - qemu_put_be16s(f, &s->intr); - qemu_put_be16s(f, &s->frnum); - qemu_put_be32s(f, &s->fl_base_addr); - qemu_put_8s(f, &s->sof_timing); - qemu_put_8s(f, &s->status2); - qemu_put_timer(f, s->frame_timer); } -static int uhci_load(QEMUFile *f, void *opaque, int version_id) -{ - UHCIState *s = opaque; - uint8_t num_ports; - int i, ret; - - if (version_id > 1) - return -EINVAL; - - ret = pci_device_load(&s->dev, f); - if (ret < 0) - return ret; - - qemu_get_8s(f, &num_ports); - if (num_ports != NB_PORTS) - return -EINVAL; - - for (i = 0; i < num_ports; ++i) - qemu_get_be16s(f, &s->ports[i].ctrl); - qemu_get_be16s(f, &s->cmd); - qemu_get_be16s(f, &s->status); - qemu_get_be16s(f, &s->intr); - qemu_get_be16s(f, &s->frnum); - qemu_get_be32s(f, &s->fl_base_addr); - qemu_get_8s(f, &s->sof_timing); - qemu_get_8s(f, &s->status2); - qemu_get_timer(f, s->frame_timer); +static const VMStateDescription vmstate_uhci_port = { + .name = "uhci port", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_UINT16(ctrl, UHCIPort), + VMSTATE_END_OF_LIST() + } +}; - return 0; -} +static const VMStateDescription vmstate_uhci = { + .name = "uhci", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .pre_save = uhci_pre_save, + .fields = (VMStateField []) { + VMSTATE_PCI_DEVICE(dev, UHCIState), + VMSTATE_UINT8_EQUAL(num_ports_vmstate, UHCIState), + VMSTATE_STRUCT_ARRAY(ports, UHCIState, NB_PORTS, 1, + vmstate_uhci_port, UHCIPort), + VMSTATE_UINT16(cmd, UHCIState), + VMSTATE_UINT16(status, UHCIState), + VMSTATE_UINT16(intr, UHCIState), + VMSTATE_UINT16(frnum, UHCIState), + VMSTATE_UINT32(fl_base_addr, UHCIState), + VMSTATE_UINT8(sof_timing, UHCIState), + VMSTATE_UINT8(status2, UHCIState), + VMSTATE_TIMER(frame_timer, UHCIState), + VMSTATE_END_OF_LIST() + } +}; static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) { @@ -1088,6 +1076,7 @@ static int usb_uhci_common_initfn(UHCIState *s) usb_register_port(&s->bus, &s->ports[i].port, s, i, uhci_attach); } s->frame_timer = qemu_new_timer(vm_clock, uhci_frame_timer, s); + s->num_ports_vmstate = NB_PORTS; qemu_register_reset(uhci_reset, s); uhci_reset(s); @@ -1097,7 +1086,7 @@ static int usb_uhci_common_initfn(UHCIState *s) pci_register_bar(&s->dev, 4, 0x20, PCI_ADDRESS_SPACE_IO, uhci_map); - register_savevm("uhci", 0, 1, uhci_save, uhci_load, s); + vmstate_register(0, &vmstate_uhci, s); return 0; } diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c index f8fc940ed..2faefa51b 100644 --- a/hw/vga-isa-mm.c +++ b/hw/vga-isa-mm.c @@ -100,7 +100,7 @@ static void vga_mm_init(ISAVGAMMState *s, target_phys_addr_t vram_base, s_ioport_ctrl = cpu_register_io_memory(vga_mm_read_ctrl, vga_mm_write_ctrl, s); vga_io_memory = cpu_register_io_memory(vga_mem_read, vga_mem_write, s); - register_savevm("vga", 0, 2, vga_common_save, vga_common_load, s); + vmstate_register(0, &vmstate_vga_common, s); cpu_register_physical_memory(ctrl_base, 0x100000, s_ioport_ctrl); s->vga.bank_offset = 0; diff --git a/hw/vga-isa.c b/hw/vga-isa.c index 7fa31d374..801121ae5 100644 --- a/hw/vga-isa.c +++ b/hw/vga-isa.c @@ -36,7 +36,7 @@ int isa_vga_init(void) vga_common_init(s, VGA_RAM_SIZE); vga_init(s); - register_savevm("vga", 0, 2, vga_common_save, vga_common_load, s); + vmstate_register(0, &vmstate_vga_common, s); s->ds = graphic_console_init(s->update, s->invalidate, s->screen_dump, s->text_update, s); diff --git a/hw/vga-pci.c b/hw/vga-pci.c index c3be3a0f6..a0ac62975 100644 --- a/hw/vga-pci.c +++ b/hw/vga-pci.c @@ -34,29 +34,17 @@ typedef struct PCIVGAState { VGACommonState vga; } PCIVGAState; -static void pci_vga_save(QEMUFile *f, void *opaque) -{ - PCIVGAState *s = opaque; - - pci_device_save(&s->dev, f); - vga_common_save(f, &s->vga); -} - -static int pci_vga_load(QEMUFile *f, void *opaque, int version_id) -{ - PCIVGAState *s = opaque; - int ret; - - if (version_id > 2) - return -EINVAL; - - if (version_id >= 2) { - ret = pci_device_load(&s->dev, f); - if (ret < 0) - return ret; +static const VMStateDescription vmstate_vga_pci = { + .name = "vga", + .version_id = 2, + .minimum_version_id = 2, + .minimum_version_id_old = 2, + .fields = (VMStateField []) { + VMSTATE_PCI_DEVICE(dev, PCIVGAState), + VMSTATE_STRUCT(vga, PCIVGAState, 0, vmstate_vga_common, VGACommonState), + VMSTATE_END_OF_LIST() } - return vga_common_load(f, &s->vga, version_id); -} +}; static void vga_map(PCIDevice *pci_dev, int region_num, uint32_t addr, uint32_t size, int type) @@ -95,7 +83,7 @@ static int pci_vga_initfn(PCIDevice *dev) // vga + console init vga_common_init(s, VGA_RAM_SIZE); vga_init(s); - register_savevm("vga", 0, 2, pci_vga_save, pci_vga_load, d); + vmstate_register(0, &vmstate_vga_pci, d); s->ds = graphic_console_init(s->update, s->invalidate, s->screen_dump, s->text_update, s); @@ -2169,98 +2169,57 @@ CPUWriteMemoryFunc * const vga_mem_write[3] = { vga_mem_writel, }; -void vga_common_save(QEMUFile *f, void *opaque) +static int vga_common_post_load(void *opaque, int version_id) { VGACommonState *s = opaque; - int i; - - qemu_put_be32s(f, &s->latch); - qemu_put_8s(f, &s->sr_index); - qemu_put_buffer(f, s->sr, 8); - qemu_put_8s(f, &s->gr_index); - qemu_put_buffer(f, s->gr, 16); - qemu_put_8s(f, &s->ar_index); - qemu_put_buffer(f, s->ar, 21); - qemu_put_be32(f, s->ar_flip_flop); - qemu_put_8s(f, &s->cr_index); - qemu_put_buffer(f, s->cr, 256); - qemu_put_8s(f, &s->msr); - qemu_put_8s(f, &s->fcr); - qemu_put_byte(f, s->st00); - qemu_put_8s(f, &s->st01); - - qemu_put_8s(f, &s->dac_state); - qemu_put_8s(f, &s->dac_sub_index); - qemu_put_8s(f, &s->dac_read_index); - qemu_put_8s(f, &s->dac_write_index); - qemu_put_buffer(f, s->dac_cache, 3); - qemu_put_buffer(f, s->palette, 768); - - qemu_put_be32(f, s->bank_offset); -#ifdef CONFIG_BOCHS_VBE - qemu_put_byte(f, 1); - qemu_put_be16s(f, &s->vbe_index); - for(i = 0; i < VBE_DISPI_INDEX_NB; i++) - qemu_put_be16s(f, &s->vbe_regs[i]); - qemu_put_be32s(f, &s->vbe_start_addr); - qemu_put_be32s(f, &s->vbe_line_offset); - qemu_put_be32s(f, &s->vbe_bank_mask); -#else - qemu_put_byte(f, 0); -#endif -} - -int vga_common_load(QEMUFile *f, void *opaque, int version_id) -{ - VGACommonState *s = opaque; - int is_vbe, i; - - if (version_id > 2) - return -EINVAL; - - qemu_get_be32s(f, &s->latch); - qemu_get_8s(f, &s->sr_index); - qemu_get_buffer(f, s->sr, 8); - qemu_get_8s(f, &s->gr_index); - qemu_get_buffer(f, s->gr, 16); - qemu_get_8s(f, &s->ar_index); - qemu_get_buffer(f, s->ar, 21); - s->ar_flip_flop=qemu_get_be32(f); - qemu_get_8s(f, &s->cr_index); - qemu_get_buffer(f, s->cr, 256); - qemu_get_8s(f, &s->msr); - qemu_get_8s(f, &s->fcr); - qemu_get_8s(f, &s->st00); - qemu_get_8s(f, &s->st01); - - qemu_get_8s(f, &s->dac_state); - qemu_get_8s(f, &s->dac_sub_index); - qemu_get_8s(f, &s->dac_read_index); - qemu_get_8s(f, &s->dac_write_index); - qemu_get_buffer(f, s->dac_cache, 3); - qemu_get_buffer(f, s->palette, 768); - - s->bank_offset=qemu_get_be32(f); - is_vbe = qemu_get_byte(f); -#ifdef CONFIG_BOCHS_VBE - if (!is_vbe) - return -EINVAL; - qemu_get_be16s(f, &s->vbe_index); - for(i = 0; i < VBE_DISPI_INDEX_NB; i++) - qemu_get_be16s(f, &s->vbe_regs[i]); - qemu_get_be32s(f, &s->vbe_start_addr); - qemu_get_be32s(f, &s->vbe_line_offset); - qemu_get_be32s(f, &s->vbe_bank_mask); -#else - if (is_vbe) - return -EINVAL; -#endif /* force refresh */ s->graphic_mode = -1; return 0; } +const VMStateDescription vmstate_vga_common = { + .name = "vga", + .version_id = 2, + .minimum_version_id = 2, + .minimum_version_id_old = 2, + .post_load = vga_common_post_load, + .fields = (VMStateField []) { + VMSTATE_UINT32(latch, VGACommonState), + VMSTATE_UINT8(sr_index, VGACommonState), + VMSTATE_PARTIAL_BUFFER(sr, VGACommonState, 8), + VMSTATE_UINT8(gr_index, VGACommonState), + VMSTATE_PARTIAL_BUFFER(gr, VGACommonState, 16), + VMSTATE_UINT8(ar_index, VGACommonState), + VMSTATE_BUFFER(ar, VGACommonState), + VMSTATE_INT32(ar_flip_flop, VGACommonState), + VMSTATE_UINT8(cr_index, VGACommonState), + VMSTATE_BUFFER(cr, VGACommonState), + VMSTATE_UINT8(msr, VGACommonState), + VMSTATE_UINT8(fcr, VGACommonState), + VMSTATE_UINT8(st00, VGACommonState), + VMSTATE_UINT8(st01, VGACommonState), + + VMSTATE_UINT8(dac_state, VGACommonState), + VMSTATE_UINT8(dac_sub_index, VGACommonState), + VMSTATE_UINT8(dac_read_index, VGACommonState), + VMSTATE_UINT8(dac_write_index, VGACommonState), + VMSTATE_BUFFER(dac_cache, VGACommonState), + VMSTATE_BUFFER(palette, VGACommonState), + + VMSTATE_INT32(bank_offset, VGACommonState), + VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState), +#ifdef CONFIG_BOCHS_VBE + VMSTATE_UINT16(vbe_index, VGACommonState), + VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB), + VMSTATE_UINT32(vbe_start_addr, VGACommonState), + VMSTATE_UINT32(vbe_line_offset, VGACommonState), + VMSTATE_UINT32(vbe_bank_mask, VGACommonState), +#endif + VMSTATE_END_OF_LIST() + } +}; + void vga_common_init(VGACommonState *s, int vga_ram_size) { int i, j, v, b; @@ -2288,6 +2247,11 @@ void vga_common_init(VGACommonState *s, int vga_ram_size) expand4to8[i] = v; } +#ifdef CONFIG_BOCHS_VBE + s->is_vbe_vmstate = 1; +#else + s->is_vbe_vmstate = 0; +#endif s->vram_offset = qemu_ram_alloc(vga_ram_size); s->vram_ptr = qemu_get_ram_ptr(s->vram_offset); s->vram_size = vga_ram_size; diff --git a/hw/vga_int.h b/hw/vga_int.h index fcfe72d95..2b2172dbb 100644 --- a/hw/vga_int.h +++ b/hw/vga_int.h @@ -21,6 +21,9 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + +#include <hw/hw.h> + #define MSR_COLOR_EMULATION 0x01 #define MSR_PAGE_SELECT 0x20 @@ -175,6 +178,7 @@ typedef struct VGACommonState { vga_retrace_fn retrace; vga_update_retrace_info_fn update_retrace_info; union vga_retrace retrace_info; + uint8_t is_vbe_vmstate; } VGACommonState; static inline int c6_to_8(int v) @@ -192,8 +196,7 @@ void vga_common_reset(VGACommonState *s); void vga_dirty_log_start(VGACommonState *s); void vga_dirty_log_stop(VGACommonState *s); -void vga_common_save(QEMUFile *f, void *opaque); -int vga_common_load(QEMUFile *f, void *opaque, int version_id); +extern const VMStateDescription vmstate_vga_common; uint32_t vga_ioport_read(void *opaque, uint32_t addr); void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val); uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr); diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c index a273f3593..77d766912 100644 --- a/hw/vmware_vga.c +++ b/hw/vmware_vga.c @@ -26,20 +26,15 @@ #include "pci.h" #define VERBOSE -#define EMBED_STDVGA #undef DIRECT_VRAM #define HW_RECT_ACCEL #define HW_FILL_ACCEL #define HW_MOUSE_ACCEL -#ifdef EMBED_STDVGA # include "vga_int.h" -#endif struct vmsvga_state_s { -#ifdef EMBED_STDVGA VGACommonState vga; -#endif int width; int height; @@ -55,12 +50,6 @@ struct vmsvga_state_s { int on; } cursor; -#ifndef EMBED_STDVGA - DisplayState *ds; - int vram_size; - ram_addr_t vram_offset; - uint8_t *vram_ptr; -#endif target_phys_addr_t vram_base; int index; @@ -630,20 +619,20 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s) static uint32_t vmsvga_index_read(void *opaque, uint32_t address) { - struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque; + struct vmsvga_state_s *s = opaque; return s->index; } static void vmsvga_index_write(void *opaque, uint32_t address, uint32_t index) { - struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque; + struct vmsvga_state_s *s = opaque; s->index = index; } static uint32_t vmsvga_value_read(void *opaque, uint32_t address) { uint32_t caps; - struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque; + struct vmsvga_state_s *s = opaque; switch (s->index) { case SVGA_REG_ID: return s->svgaid; @@ -761,7 +750,7 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value) { - struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque; + struct vmsvga_state_s *s = opaque; switch (s->index) { case SVGA_REG_ID: if (value == SVGA_ID_2 || value == SVGA_ID_1 || value == SVGA_ID_0) @@ -774,9 +763,7 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value) s->width = -1; s->height = -1; s->invalidated = 1; -#ifdef EMBED_STDVGA s->vga.invalidate(&s->vga); -#endif if (s->enable) s->fb_size = ((s->depth + 7) >> 3) * s->new_width * s->new_height; break; @@ -892,11 +879,9 @@ static inline void vmsvga_size(struct vmsvga_state_s *s) static void vmsvga_update_display(void *opaque) { - struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque; + struct vmsvga_state_s *s = opaque; if (!s->enable) { -#ifdef EMBED_STDVGA s->vga.update(&s->vga); -#endif return; } @@ -960,11 +945,9 @@ static void vmsvga_reset(struct vmsvga_state_s *s) static void vmsvga_invalidate_display(void *opaque) { - struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque; + struct vmsvga_state_s *s = opaque; if (!s->enable) { -#ifdef EMBED_STDVGA s->vga.invalidate(&s->vga); -#endif return; } @@ -975,11 +958,9 @@ static void vmsvga_invalidate_display(void *opaque) available */ static void vmsvga_screen_dump(void *opaque, const char *filename) { - struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque; + struct vmsvga_state_s *s = opaque; if (!s->enable) { -#ifdef EMBED_STDVGA s->vga.screen_dump(&s->vga, filename); -#endif return; } @@ -993,7 +974,7 @@ static void vmsvga_screen_dump(void *opaque, const char *filename) static void vmsvga_text_update(void *opaque, console_ch_t *chardata) { - struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque; + struct vmsvga_state_s *s = opaque; if (s->vga.text_update) s->vga.text_update(&s->vga, chardata); @@ -1002,7 +983,7 @@ static void vmsvga_text_update(void *opaque, console_ch_t *chardata) #ifdef DIRECT_VRAM static uint32_t vmsvga_vram_readb(void *opaque, target_phys_addr_t addr) { - struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque; + struct vmsvga_state_s *s = opaque; if (addr < s->fb_size) return *(uint8_t *) (ds_get_data(s->ds) + addr); else @@ -1011,7 +992,7 @@ static uint32_t vmsvga_vram_readb(void *opaque, target_phys_addr_t addr) static uint32_t vmsvga_vram_readw(void *opaque, target_phys_addr_t addr) { - struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque; + struct vmsvga_state_s *s = opaque; if (addr < s->fb_size) return *(uint16_t *) (ds_get_data(s->ds) + addr); else @@ -1020,7 +1001,7 @@ static uint32_t vmsvga_vram_readw(void *opaque, target_phys_addr_t addr) static uint32_t vmsvga_vram_readl(void *opaque, target_phys_addr_t addr) { - struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque; + struct vmsvga_state_s *s = opaque; if (addr < s->fb_size) return *(uint32_t *) (ds_get_data(s->ds) + addr); else @@ -1030,7 +1011,7 @@ static uint32_t vmsvga_vram_readl(void *opaque, target_phys_addr_t addr) static void vmsvga_vram_writeb(void *opaque, target_phys_addr_t addr, uint32_t value) { - struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque; + struct vmsvga_state_s *s = opaque; if (addr < s->fb_size) *(uint8_t *) (ds_get_data(s->ds) + addr) = value; else @@ -1040,7 +1021,7 @@ static void vmsvga_vram_writeb(void *opaque, target_phys_addr_t addr, static void vmsvga_vram_writew(void *opaque, target_phys_addr_t addr, uint32_t value) { - struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque; + struct vmsvga_state_s *s = opaque; if (addr < s->fb_size) *(uint16_t *) (ds_get_data(s->ds) + addr) = value; else @@ -1050,7 +1031,7 @@ static void vmsvga_vram_writew(void *opaque, target_phys_addr_t addr, static void vmsvga_vram_writel(void *opaque, target_phys_addr_t addr, uint32_t value) { - struct vmsvga_state_s *s = (struct vmsvga_state_s *) opaque; + struct vmsvga_state_s *s = opaque; if (addr < s->fb_size) *(uint32_t *) (ds_get_data(s->ds) + addr) = value; else @@ -1070,49 +1051,9 @@ static CPUWriteMemoryFunc * const vmsvga_vram_write[] = { }; #endif -static void vmsvga_save(struct vmsvga_state_s *s, QEMUFile *f) +static int vmsvga_post_load(void *opaque, int version_id) { - qemu_put_be32(f, s->depth); - qemu_put_be32(f, s->enable); - qemu_put_be32(f, s->config); - qemu_put_be32(f, s->cursor.id); - qemu_put_be32(f, s->cursor.x); - qemu_put_be32(f, s->cursor.y); - qemu_put_be32(f, s->cursor.on); - qemu_put_be32(f, s->index); - qemu_put_buffer(f, (uint8_t *) s->scratch, s->scratch_size * 4); - qemu_put_be32(f, s->new_width); - qemu_put_be32(f, s->new_height); - qemu_put_be32s(f, &s->guest); - qemu_put_be32s(f, &s->svgaid); - qemu_put_be32(f, s->syncing); - qemu_put_be32(f, s->fb_size); -} - -static int vmsvga_load(struct vmsvga_state_s *s, QEMUFile *f) -{ - int depth; - depth=qemu_get_be32(f); - s->enable=qemu_get_be32(f); - s->config=qemu_get_be32(f); - s->cursor.id=qemu_get_be32(f); - s->cursor.x=qemu_get_be32(f); - s->cursor.y=qemu_get_be32(f); - s->cursor.on=qemu_get_be32(f); - s->index=qemu_get_be32(f); - qemu_get_buffer(f, (uint8_t *) s->scratch, s->scratch_size * 4); - s->new_width=qemu_get_be32(f); - s->new_height=qemu_get_be32(f); - qemu_get_be32s(f, &s->guest); - qemu_get_be32s(f, &s->svgaid); - s->syncing=qemu_get_be32(f); - s->fb_size=qemu_get_be32(f); - - if (s->enable && depth != s->depth) { - printf("%s: need colour depth of %i bits to resume operation.\n", - __FUNCTION__, depth); - return -EINVAL; - } + struct vmsvga_state_s *s = opaque; s->invalidated = 1; if (s->config) @@ -1121,27 +1062,61 @@ static int vmsvga_load(struct vmsvga_state_s *s, QEMUFile *f) return 0; } +const VMStateDescription vmstate_vmware_vga_internal = { + .name = "vmware_vga_internal", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .post_load = vmsvga_post_load, + .fields = (VMStateField []) { + VMSTATE_INT32_EQUAL(depth, struct vmsvga_state_s), + VMSTATE_INT32(enable, struct vmsvga_state_s), + VMSTATE_INT32(config, struct vmsvga_state_s), + VMSTATE_INT32(cursor.id, struct vmsvga_state_s), + VMSTATE_INT32(cursor.x, struct vmsvga_state_s), + VMSTATE_INT32(cursor.y, struct vmsvga_state_s), + VMSTATE_INT32(cursor.on, struct vmsvga_state_s), + VMSTATE_INT32(index, struct vmsvga_state_s), + VMSTATE_VARRAY_INT32(scratch, struct vmsvga_state_s, + scratch_size, 0, vmstate_info_uint32, uint32_t), + VMSTATE_INT32(new_width, struct vmsvga_state_s), + VMSTATE_INT32(new_height, struct vmsvga_state_s), + VMSTATE_UINT32(guest, struct vmsvga_state_s), + VMSTATE_UINT32(svgaid, struct vmsvga_state_s), + VMSTATE_INT32(syncing, struct vmsvga_state_s), + VMSTATE_INT32(fb_size, struct vmsvga_state_s), + VMSTATE_END_OF_LIST() + } +}; + +const VMStateDescription vmstate_vmware_vga = { + .name = "vmware_vga", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField []) { + VMSTATE_PCI_DEVICE(card, struct pci_vmsvga_state_s), + VMSTATE_STRUCT(chip, struct pci_vmsvga_state_s, 0, + vmstate_vmware_vga_internal, struct vmsvga_state_s), + VMSTATE_END_OF_LIST() + } +}; + static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size) { s->scratch_size = SVGA_SCRATCH_SIZE; - s->scratch = (uint32_t *) qemu_malloc(s->scratch_size * 4); + s->scratch = qemu_malloc(s->scratch_size * 4); vmsvga_reset(s); -#ifdef EMBED_STDVGA vga_common_init(&s->vga, vga_ram_size); vga_init(&s->vga); - register_savevm("vga", 0, 2, vga_common_save, vga_common_load, &s->vga); -#else - s->vram_size = vga_ram_size; - s->vram_offset = qemu_ram_alloc(vga_ram_size); - s->vram_ptr = qemu_get_ram_ptr(s->vram_offset); -#endif + vmstate_register(0, &vmstate_vga_common, &s->vga); s->vga.ds = graphic_console_init(vmsvga_update_display, vmsvga_invalidate_display, vmsvga_screen_dump, - vmsvga_text_update, &s->vga); + vmsvga_text_update, s); #ifdef CONFIG_BOCHS_VBE /* XXX: use optimized standard vga accesses */ @@ -1150,29 +1125,6 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size) #endif } -static void pci_vmsvga_save(QEMUFile *f, void *opaque) -{ - struct pci_vmsvga_state_s *s = (struct pci_vmsvga_state_s *) opaque; - pci_device_save(&s->card, f); - vmsvga_save(&s->chip, f); -} - -static int pci_vmsvga_load(QEMUFile *f, void *opaque, int version_id) -{ - struct pci_vmsvga_state_s *s = (struct pci_vmsvga_state_s *) opaque; - int ret; - - ret = pci_device_load(&s->card, f); - if (ret < 0) - return ret; - - ret = vmsvga_load(&s->chip, f); - if (ret < 0) - return ret; - - return 0; -} - static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num, uint32_t addr, uint32_t size, int type) { @@ -1236,7 +1188,7 @@ static int pci_vmsvga_initfn(PCIDevice *dev) vmsvga_init(&s->chip, VGA_RAM_SIZE); - register_savevm("vmware_vga", 0, 0, pci_vmsvga_save, pci_vmsvga_load, s); + vmstate_register(0, &vmstate_vmware_vga, s); return 0; } diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c index 3abaa87cf..40081cae6 100644 --- a/hw/wdt_i6300esb.c +++ b/hw/wdt_i6300esb.c @@ -36,10 +36,6 @@ #define i6300esb_debug(fs,...) #endif -#ifndef PCI_DEVICE_ID_INTEL_ESB_9 -#define PCI_DEVICE_ID_INTEL_ESB_9 0x25ab -#endif - /* PCI configuration registers */ #define ESB_CONFIG_REG 0x60 /* Config register */ #define ESB_LOCK_REG 0x68 /* WDT lock register */ @@ -163,7 +159,7 @@ static void i6300esb_reset(I6300State *d) */ static void i6300esb_timer_expired(void *vp) { - I6300State *d = (I6300State *) vp; + I6300State *d = vp; i6300esb_debug("stage %d\n", d->stage); @@ -257,7 +253,7 @@ static uint32_t i6300esb_mem_readb(void *vp, target_phys_addr_t addr) static uint32_t i6300esb_mem_readw(void *vp, target_phys_addr_t addr) { uint32_t data = 0; - I6300State *d = (I6300State *) vp; + I6300State *d = vp; i6300esb_debug("addr = %x\n", (int) addr); @@ -281,7 +277,7 @@ static uint32_t i6300esb_mem_readl(void *vp, target_phys_addr_t addr) static void i6300esb_mem_writeb(void *vp, target_phys_addr_t addr, uint32_t val) { - I6300State *d = (I6300State *) vp; + I6300State *d = vp; i6300esb_debug("addr = %x, val = %x\n", (int) addr, val); @@ -293,7 +289,7 @@ static void i6300esb_mem_writeb(void *vp, target_phys_addr_t addr, uint32_t val) static void i6300esb_mem_writew(void *vp, target_phys_addr_t addr, uint32_t val) { - I6300State *d = (I6300State *) vp; + I6300State *d = vp; i6300esb_debug("addr = %x, val = %x\n", (int) addr, val); @@ -326,7 +322,7 @@ static void i6300esb_mem_writew(void *vp, target_phys_addr_t addr, uint32_t val) static void i6300esb_mem_writel(void *vp, target_phys_addr_t addr, uint32_t val) { - I6300State *d = (I6300State *) vp; + I6300State *d = vp; i6300esb_debug ("addr = %x, val = %x\n", (int) addr, val); @@ -369,48 +365,28 @@ static void i6300esb_map(PCIDevice *dev, int region_num, /* qemu_register_coalesced_mmio (addr, 0x10); ? */ } -static void i6300esb_save(QEMUFile *f, void *vp) -{ - I6300State *d = (I6300State *) vp; - - pci_device_save(&d->dev, f); - qemu_put_be32(f, d->reboot_enabled); - qemu_put_be32(f, d->clock_scale); - qemu_put_be32(f, d->int_type); - qemu_put_be32(f, d->free_run); - qemu_put_be32(f, d->locked); - qemu_put_be32(f, d->enabled); - qemu_put_timer(f, d->timer); - qemu_put_be32(f, d->timer1_preload); - qemu_put_be32(f, d->timer2_preload); - qemu_put_be32(f, d->stage); - qemu_put_be32(f, d->unlock_state); - qemu_put_be32(f, d->previous_reboot_flag); -} - -static int i6300esb_load(QEMUFile *f, void *vp, int version) -{ - I6300State *d = (I6300State *) vp; - - if (version != sizeof (I6300State)) - return -EINVAL; - - pci_device_load(&d->dev, f); - d->reboot_enabled = qemu_get_be32(f); - d->clock_scale = qemu_get_be32(f); - d->int_type = qemu_get_be32(f); - d->free_run = qemu_get_be32(f); - d->locked = qemu_get_be32(f); - d->enabled = qemu_get_be32(f); - qemu_get_timer(f, d->timer); - d->timer1_preload = qemu_get_be32(f); - d->timer2_preload = qemu_get_be32(f); - d->stage = qemu_get_be32(f); - d->unlock_state = qemu_get_be32(f); - d->previous_reboot_flag = qemu_get_be32(f); - - return 0; -} +static const VMStateDescription vmstate_i6300esb = { + .name = "i6300esb_wdt", + .version_id = sizeof(I6300State), + .minimum_version_id = sizeof(I6300State), + .minimum_version_id_old = sizeof(I6300State), + .fields = (VMStateField []) { + VMSTATE_PCI_DEVICE(dev, I6300State), + VMSTATE_INT32(reboot_enabled, I6300State), + VMSTATE_INT32(clock_scale, I6300State), + VMSTATE_INT32(int_type, I6300State), + VMSTATE_INT32(free_run, I6300State), + VMSTATE_INT32(locked, I6300State), + VMSTATE_INT32(enabled, I6300State), + VMSTATE_TIMER(timer, I6300State), + VMSTATE_UINT32(timer1_preload, I6300State), + VMSTATE_UINT32(timer2_preload, I6300State), + VMSTATE_INT32(stage, I6300State), + VMSTATE_INT32(unlock_state, I6300State), + VMSTATE_INT32(previous_reboot_flag, I6300State), + VMSTATE_END_OF_LIST() + } +}; static int i6300esb_init(PCIDevice *dev) { @@ -439,8 +415,7 @@ static int i6300esb_init(PCIDevice *dev) pci_register_bar(&d->dev, 0, 0x10, PCI_ADDRESS_SPACE_MEM, i6300esb_map); - register_savevm("i6300esb_wdt", -1, sizeof(I6300State), - i6300esb_save, i6300esb_load, d); + vmstate_register(-1, &vmstate_i6300esb, d); return 0; } diff --git a/hw/wdt_ib700.c b/hw/wdt_ib700.c index 0ee3a5cc0..d67bf9eb4 100644 --- a/hw/wdt_ib700.c +++ b/hw/wdt_ib700.c @@ -35,15 +35,20 @@ #define ib700_debug(fs,...) #endif +typedef struct IB700state { + ISADevice dev; + QEMUTimer *timer; +} IB700State; + /* This is the timer. We use a global here because the watchdog * code ensures there is only one watchdog (it is located at a fixed, * unchangable IO port, so there could only ever be one anyway). */ -static QEMUTimer *timer = NULL; /* A write to this register enables the timer. */ static void ib700_write_enable_reg(void *vp, uint32_t addr, uint32_t data) { + IB700State *s = vp; static int time_map[] = { 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0 @@ -53,47 +58,49 @@ static void ib700_write_enable_reg(void *vp, uint32_t addr, uint32_t data) ib700_debug("addr = %x, data = %x\n", addr, data); timeout = (int64_t) time_map[data & 0xF] * get_ticks_per_sec(); - qemu_mod_timer(timer, qemu_get_clock (vm_clock) + timeout); + qemu_mod_timer(s->timer, qemu_get_clock (vm_clock) + timeout); } /* A write (of any value) to this register disables the timer. */ static void ib700_write_disable_reg(void *vp, uint32_t addr, uint32_t data) { + IB700State *s = vp; + ib700_debug("addr = %x, data = %x\n", addr, data); - qemu_del_timer(timer); + qemu_del_timer(s->timer); } /* This is called when the watchdog expires. */ static void ib700_timer_expired(void *vp) { + IB700State *s = vp; + ib700_debug("watchdog expired\n"); watchdog_perform_action(); - qemu_del_timer(timer); + qemu_del_timer(s->timer); } -static void ib700_save(QEMUFile *f, void *vp) -{ - qemu_put_timer(f, timer); -} - -static int ib700_load(QEMUFile *f, void *vp, int version) -{ - if (version != 0) - return -EINVAL; - - qemu_get_timer(f, timer); - - return 0; -} +static const VMStateDescription vmstate_ib700 = { + .name = "ib700_wdt", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .fields = (VMStateField []) { + VMSTATE_TIMER(timer, IB700State), + VMSTATE_END_OF_LIST() + } +}; static int wdt_ib700_init(ISADevice *dev) { - timer = qemu_new_timer(vm_clock, ib700_timer_expired, NULL); - register_savevm("ib700_wdt", -1, 0, ib700_save, ib700_load, NULL); - register_ioport_write(0x441, 2, 1, ib700_write_disable_reg, NULL); - register_ioport_write(0x443, 2, 1, ib700_write_enable_reg, NULL); + IB700State *s = DO_UPCAST(IB700State, dev, dev); + + s->timer = qemu_new_timer(vm_clock, ib700_timer_expired, s); + vmstate_register(-1, &vmstate_ib700, s); + register_ioport_write(0x441, 2, 1, ib700_write_disable_reg, s); + register_ioport_write(0x443, 2, 1, ib700_write_enable_reg, s); return 0; } @@ -105,7 +112,7 @@ static WatchdogTimerModel model = { static ISADeviceInfo wdt_ib700_info = { .qdev.name = "ib700", - .qdev.size = sizeof(ISADevice), + .qdev.size = sizeof(IB700State), .init = wdt_ib700_init, }; diff --git a/migration.c b/migration.c index 7f93e3fcd..b20beb730 100644 --- a/migration.c +++ b/migration.c @@ -52,7 +52,7 @@ void qemu_start_incoming_migration(const char *uri) fprintf(stderr, "unknown migration protocol: %s\n", uri); } -void do_migrate(Monitor *mon, const QDict *qdict) +void do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) { MigrationState *s = NULL; const char *p; @@ -82,7 +82,7 @@ void do_migrate(Monitor *mon, const QDict *qdict) } } -void do_migrate_cancel(Monitor *mon, const QDict *qdict) +void do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data) { MigrationState *s = current_migration; @@ -90,7 +90,7 @@ void do_migrate_cancel(Monitor *mon, const QDict *qdict) s->cancel(s); } -void do_migrate_set_speed(Monitor *mon, const QDict *qdict) +void do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data) { double d; char *ptr; diff --git a/migration.h b/migration.h index 53b923d4b..2d28b8f39 100644 --- a/migration.h +++ b/migration.h @@ -50,11 +50,11 @@ struct FdMigrationState void qemu_start_incoming_migration(const char *uri); -void do_migrate(Monitor *mon, const QDict *qdict); +void do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data); -void do_migrate_cancel(Monitor *mon, const QDict *qdict); +void do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data); -void do_migrate_set_speed(Monitor *mon, const QDict *qdict); +void do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data); uint64_t migrate_max_downtime(void); @@ -599,7 +599,7 @@ static int eject_device(Monitor *mon, BlockDriverState *bs, int force) return 0; } -static void do_eject(Monitor *mon, const QDict *qdict) +static void do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data) { BlockDriverState *bs; int force = qdict_get_int(qdict, "force"); @@ -1006,7 +1006,7 @@ static void do_print(Monitor *mon, const QDict *qdict) monitor_printf(mon, "\n"); } -static void do_memory_save(Monitor *mon, const QDict *qdict) +static void do_memory_save(Monitor *mon, const QDict *qdict, QObject **ret_data) { FILE *f; uint32_t size = qdict_get_int(qdict, "size"); @@ -1037,7 +1037,8 @@ static void do_memory_save(Monitor *mon, const QDict *qdict) fclose(f); } -static void do_physical_memory_save(Monitor *mon, const QDict *qdict) +static void do_physical_memory_save(Monitor *mon, const QDict *qdict, + QObject **ret_data) { FILE *f; uint32_t l; @@ -1879,7 +1880,7 @@ static void do_inject_mce(Monitor *mon, const QDict *qdict) } #endif -static void do_getfd(Monitor *mon, const QDict *qdict) +static void do_getfd(Monitor *mon, const QDict *qdict, QObject **ret_data) { const char *fdname = qdict_get_str(qdict, "fdname"); mon_fd_t *monfd; @@ -1920,7 +1921,7 @@ static void do_getfd(Monitor *mon, const QDict *qdict) QLIST_INSERT_HEAD(&mon->fds, monfd, next); } -static void do_closefd(Monitor *mon, const QDict *qdict) +static void do_closefd(Monitor *mon, const QDict *qdict, QObject **ret_data) { const char *fdname = qdict_get_str(qdict, "fdname"); mon_fd_t *monfd; diff --git a/posix-aio-compat.c b/posix-aio-compat.c index 65f2bfdef..4007be376 100644 --- a/posix-aio-compat.c +++ b/posix-aio-compat.c @@ -414,47 +414,25 @@ static int qemu_paio_error(struct qemu_paiocb *aiocb) return ret; } -static void posix_aio_read(void *opaque) +static int posix_aio_process_queue(void *opaque) { PosixAioState *s = opaque; struct qemu_paiocb *acb, **pacb; int ret; - union { - struct qemu_signalfd_siginfo siginfo; - char buf[128]; - } sig; - size_t offset; - - /* try to read from signalfd, don't freak out if we can't read anything */ - offset = 0; - while (offset < 128) { - ssize_t len; - - len = read(s->fd, sig.buf + offset, 128 - offset); - if (len == -1 && errno == EINTR) - continue; - if (len == -1 && errno == EAGAIN) { - /* there is no natural reason for this to happen, - * so we'll spin hard until we get everything just - * to be on the safe side. */ - if (offset > 0) - continue; - } - - offset += len; - } + int result = 0; for(;;) { pacb = &s->first_aio; for(;;) { acb = *pacb; if (!acb) - goto the_end; + return result; ret = qemu_paio_error(acb); if (ret == ECANCELED) { /* remove the request */ *pacb = acb->next; qemu_aio_release(acb); + result = 1; } else if (ret != EINPROGRESS) { /* end of aio */ if (ret == 0) { @@ -471,13 +449,46 @@ static void posix_aio_read(void *opaque) /* call the callback */ acb->common.cb(acb->common.opaque, ret); qemu_aio_release(acb); + result = 1; break; } else { pacb = &acb->next; } } } - the_end: ; + + return result; +} + +static void posix_aio_read(void *opaque) +{ + PosixAioState *s = opaque; + union { + struct qemu_signalfd_siginfo siginfo; + char buf[128]; + } sig; + size_t offset; + + /* try to read from signalfd, don't freak out if we can't read anything */ + offset = 0; + while (offset < 128) { + ssize_t len; + + len = read(s->fd, sig.buf + offset, 128 - offset); + if (len == -1 && errno == EINTR) + continue; + if (len == -1 && errno == EAGAIN) { + /* there is no natural reason for this to happen, + * so we'll spin hard until we get everything just + * to be on the safe side. */ + if (offset > 0) + continue; + } + + offset += len; + } + + posix_aio_process_queue(s); } static int posix_aio_flush(void *opaque) diff --git a/qemu-char.c b/qemu-char.c index 0fd402c46..23d2a0710 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -729,7 +729,7 @@ static void term_exit(void) fcntl(0, F_SETFL, old_fd0_flags); } -static void term_init(void) +static void term_init(QemuOpts *opts) { struct termios tty; @@ -742,7 +742,7 @@ static void term_init(void) tty.c_oflag |= OPOST; tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN); /* if graphical mode, we allow Ctrl-C handling */ - if (display_type == DT_NOGRAPHIC) + if (!qemu_opt_get_bool(opts, "signal", display_type != DT_NOGRAPHIC)) tty.c_lflag &= ~ISIG; tty.c_cflag &= ~(CSIZE|PARENB); tty.c_cflag |= CS8; @@ -775,7 +775,7 @@ static CharDriverState *qemu_chr_open_stdio(QemuOpts *opts) chr->chr_close = qemu_chr_close_stdio; qemu_set_fd_handler2(0, stdio_read_poll, stdio_read, NULL, chr); stdio_nb_clients++; - term_init(); + term_init(opts); return chr; } diff --git a/qemu-config.c b/qemu-config.c index 4fb789811..b4cebca06 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -138,6 +138,9 @@ QemuOptsList qemu_chardev_opts = { },{ .name = "mux", .type = QEMU_OPT_BOOL, + },{ + .name = "signal", + .type = QEMU_OPT_BOOL, }, { /* end if list */ } }, diff --git a/qemu-monitor.hx b/qemu-monitor.hx index 547747886..6e0d94ba7 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -133,7 +133,8 @@ ETEXI .args_type = "force:-f,filename:B", .params = "[-f] device", .help = "eject a removable medium (use -f to force it)", - .mhandler.cmd = do_eject, + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_eject, }, STEXI @@ -666,7 +667,8 @@ ETEXI .args_type = "val:l,size:i,filename:s", .params = "addr size file", .help = "save to disk virtual memory dump starting at 'addr' of size 'size'", - .mhandler.cmd = do_memory_save, + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_memory_save, }, STEXI @@ -679,7 +681,8 @@ ETEXI .args_type = "val:l,size:i,filename:s", .params = "addr size file", .help = "save to disk physical memory dump starting at 'addr' of size 'size'", - .mhandler.cmd = do_physical_memory_save, + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_physical_memory_save, }, STEXI @@ -724,7 +727,8 @@ ETEXI .args_type = "detach:-d,uri:s", .params = "[-d] uri", .help = "migrate to URI (using -d to not wait for completion)", - .mhandler.cmd = do_migrate, + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_migrate, }, STEXI @@ -737,7 +741,8 @@ ETEXI .args_type = "", .params = "", .help = "cancel the current VM migration", - .mhandler.cmd = do_migrate_cancel, + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_migrate_cancel, }, STEXI @@ -750,7 +755,8 @@ ETEXI .args_type = "value:s", .params = "value", .help = "set maximum speed (in bytes) for migrations", - .mhandler.cmd = do_migrate_set_speed, + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_migrate_set_speed, }, STEXI @@ -811,7 +817,8 @@ ETEXI .args_type = "pci_addr:s", .params = "[[<domain>:]<bus>:]<slot>", .help = "hot remove PCI device", - .mhandler.cmd = do_pci_device_hot_remove, + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_pci_device_hot_remove, }, #endif @@ -1006,7 +1013,8 @@ ETEXI .args_type = "fdname:s", .params = "getfd name", .help = "receive a file descriptor via SCM rights and assign it a name", - .mhandler.cmd = do_getfd, + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_getfd, }, STEXI @@ -1021,7 +1029,8 @@ ETEXI .args_type = "fdname:s", .params = "closefd name", .help = "close a file descriptor previously passed via SCM rights", - .mhandler.cmd = do_closefd, + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_closefd, }, STEXI @@ -900,11 +900,31 @@ static int get_uint8_equal(QEMUFile *f, void *pv, size_t size) } const VMStateInfo vmstate_info_uint8_equal = { - .name = "int32 equal", + .name = "uint8 equal", .get = get_uint8_equal, .put = put_uint8, }; +/* 16 bit unsigned int int. See that the received value is the same than the one + in the field */ + +static int get_uint16_equal(QEMUFile *f, void *pv, size_t size) +{ + uint16_t *v = pv; + uint16_t v2; + qemu_get_be16s(f, &v2); + + if (*v == v2) + return 0; + return -EINVAL; +} + +const VMStateInfo vmstate_info_uint16_equal = { + .name = "uint16 equal", + .get = get_uint16_equal, + .put = put_uint16, +}; + /* timers */ static int get_timer(QEMUFile *f, void *pv, size_t size) @@ -947,6 +967,26 @@ const VMStateInfo vmstate_info_buffer = { .put = put_buffer, }; +/* unused buffers: space that was used for some fields that are + not usefull anymore */ + +static int get_unused_buffer(QEMUFile *f, void *pv, size_t size) +{ + qemu_fseek(f, size, SEEK_CUR); + return 0; +} + +static void put_unused_buffer(QEMUFile *f, void *pv, size_t size) +{ + qemu_fseek(f, size, SEEK_CUR); +} + +const VMStateInfo vmstate_info_unused_buffer = { + .name = "unused_buffer", + .get = get_unused_buffer, + .put = put_unused_buffer, +}; + typedef struct SaveStateEntry { QTAILQ_ENTRY(SaveStateEntry) entry; char idstr[256]; @@ -1101,8 +1141,10 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, if (field->flags & VMS_ARRAY) { n_elems = field->num; - } else if (field->flags & VMS_VARRAY) { - n_elems = *(size_t *)(opaque+field->num_offset); + } else if (field->flags & VMS_VARRAY_INT32) { + n_elems = *(int32_t *)(opaque+field->num_offset); + } else if (field->flags & VMS_VARRAY_UINT16) { + n_elems = *(uint16_t *)(opaque+field->num_offset); } if (field->flags & VMS_POINTER) { base_addr = *(void **)base_addr; @@ -1148,8 +1190,10 @@ void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd, if (field->flags & VMS_ARRAY) { n_elems = field->num; - } else if (field->flags & VMS_VARRAY) { - n_elems = *(size_t *)(opaque+field->num_offset); + } else if (field->flags & VMS_VARRAY_INT32) { + n_elems = *(int32_t *)(opaque+field->num_offset); + } else if (field->flags & VMS_VARRAY_UINT16) { + n_elems = *(uint16_t *)(opaque+field->num_offset); } if (field->flags & VMS_POINTER) { base_addr = *(void **)base_addr; @@ -214,7 +214,8 @@ DriveInfo *add_init_drive(const char *opts); void pci_device_hot_add(Monitor *mon, const QDict *qdict); void drive_hot_add(Monitor *mon, const QDict *qdict); void pci_device_hot_remove(Monitor *mon, const char *pci_addr); -void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict); +void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict, + QObject **ret_data); /* serial ports */ diff --git a/target-i386/machine.c b/target-i386/machine.c index f6fdc9ddd..2b88fea63 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -315,7 +315,7 @@ static const VMStateInfo vmstate_hack_uint64_as_uint32 = { }; #define VMSTATE_HACK_UINT32(_f, _s, _t) \ - VMSTATE_SINGLE_TEST(_f, _s, _t, vmstate_hack_uint64_as_uint32, uint64_t) + VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_hack_uint64_as_uint32, uint64_t) #endif static void cpu_pre_save(void *opaque) |