# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
# Date 1173364641 0
# Node ID fdbd9b91a030b1c8a0715b3319d57a864279491e
# Parent 18cf0c56226db12b6d4d80e087569b2b9dd05b46
[HVM] Save/restore: back-port IDE controller save routine from current qemu.
Also, send an interrupt and an error code to the guest on restore if we
dropped an active request when we saved.
Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
---
tools/ioemu/hw/ide.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 115 insertions(+)
diff -r 18cf0c56226d -r fdbd9b91a030 tools/ioemu/hw/ide.c
--- a/tools/ioemu/hw/ide.c Thu Mar 08 14:29:09 2007 +0000
+++ b/tools/ioemu/hw/ide.c Thu Mar 08 14:37:21 2007 +0000
@@ -2602,6 +2602,120 @@ void pci_cmd646_ide_init(PCIBus *bus, Bl
#endif /* DMA_MULTI_THREAD */
}
+static void pci_ide_save(QEMUFile* f, void *opaque)
+{
+ PCIIDEState *d = opaque;
+ int i;
+
+ for(i = 0; i < 2; i++) {
+ BMDMAState *bm = &d->bmdma[i];
+ qemu_put_8s(f, &bm->cmd);
+ qemu_put_8s(f, &bm->status);
+ qemu_put_be32s(f, &bm->addr);
+ /* XXX: if a transfer is pending, we do not save it yet */
+ }
+
+ /* per IDE interface data */
+ for(i = 0; i < 2; i++) {
+ IDEState *s = &d->ide_if[i * 2];
+ uint8_t drive1_selected;
+ qemu_put_8s(f, &s->cmd);
+ drive1_selected = (s->cur_drive != s);
+ qemu_put_8s(f, &drive1_selected);
+ }
+
+ /* per IDE drive data */
+ for(i = 0; i < 4; i++) {
+ IDEState *s = &d->ide_if[i];
+ qemu_put_be32s(f, &s->mult_sectors);
+ qemu_put_be32s(f, &s->identify_set);
+ if (s->identify_set) {
+ qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512);
+ }
+ qemu_put_8s(f, &s->write_cache);
+ 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);
+ /* XXX: if a transfer is pending, we do not save it yet */
+ }
+}
+
+static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
+{
+ PCIIDEState *d = opaque;
+ int ret, i;
+
+ if (version_id != 1)
+ return -EINVAL;
+
+ for(i = 0; i < 2; i++) {
+ BMDMAState *bm = &d->bmdma[i];
+ qemu_get_8s(f, &bm->cmd);
+ qemu_get_8s(f, &bm->status);
+ qemu_get_be32s(f, &bm->addr);
+ /* XXX: if a transfer is pending, we do not save it yet */
+ }
+
+ /* per IDE interface data */
+ for(i = 0; i < 2; i++) {
+ IDEState *s = &d->ide_if[i * 2];
+ uint8_t drive1_selected;
+ qemu_get_8s(f, &s->cmd);
+ qemu_get_8s(f, &drive1_selected);
+ s->cur_drive = &d->ide_if[i * 2 + (drive1_selected != 0)];
+ }
+
+ /* per IDE drive data */
+ for(i = 0; i < 4; i++) {
+ IDEState *s = &d->ide_if[i];
+ qemu_get_be32s(f, &s->mult_sectors);
+ qemu_get_be32s(f, &s->identify_set);
+ if (s->identify_set) {
+ qemu_get_buffer(f, (uint8_t *)s->identify_data, 512);
+ }
+ qemu_get_8s(f, &s->write_cache);
+ 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);
+ /* XXX: if a transfer is pending, we do not save it yet */
+ if (s->status & (DRQ_STAT|BUSY_STAT)) {
+ /* Tell the guest that its transfer has gone away */
+ ide_abort_command(s);
+ ide_set_irq(s);
+ }
+ }
+ return 0;
+}
+
+
/* hd_table must contain 4 block drivers */
/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn)
@@ -2643,6 +2757,7 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
buffered_pio_init();
register_savevm("ide_pci", 0, 1, generic_pci_save, generic_pci_load, d);
+ register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d);
#ifdef DMA_MULTI_THREAD
dma_create_thread();
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|