qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] Patch: NE2000 savevm problem solved!
@ 2004-09-24 10:07 Johannes Schindelin
  2004-09-27 18:30 ` Gianni Tedesco
  0 siblings, 1 reply; 4+ messages in thread
From: Johannes Schindelin @ 2004-09-24 10:07 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1221 bytes --]

Hi,

With the attached patch, Win98 guest resumes -user-net properly after
loadvm'ming.

It adds savevm functions for NE2000State and PCIDevice, which I created by
"perl qemu-struct2savevm.pl NE2000State ne2000 < hw/ne2000.c" and
"perl qemu-struct2savevm.pl PCIDevice generic_pci < hw/ne2000.c".

Two issues remain:
- *Every* PCIDevice is now savevm'ed, because the savevm handler is
  registered in pci_register_device.
- the savevm handler is therefore registered with the name passed to
  pci_register_device. It would be probably better to prefix that with
  "pci_" (note that it only works at the moment because vga registers
  a "vga" savevm handler, while the PCI device is registered as "VGA").

I am willing to fix those issues when you tell me what solution you
prefer.

BTW, it would be sufficient to add savevm handlers for ne2000, its
PCIDevice, and piix3_state. Leave one out and you break user networking.
Knoppix only resumes properly, because it does not modify the irq of the
ne2000 card, and is much more clever about the internal state of that
card being possibly randomly reset.

Ciao,
Dscho

P.S.: If somebody cares for a technical description of savevm handlers, I
will write what I learnt so far.

[-- Attachment #2: Type: TEXT/PLAIN, Size: 3501 bytes --]

diff -Nurb qemu_cvs/hw/ne2000.c qemu_ne2000_savevm/hw/ne2000.c
--- qemu_cvs/hw/ne2000.c	2004-09-24 05:28:43.000000000 +0200
+++ qemu_ne2000_savevm/hw/ne2000.c	2004-09-24 05:28:43.000000000 +0200
@@ -538,6 +538,59 @@
     return 0;
 }
 
+static void ne2000_save(QEMUFile* f,void* opaque)
+{
+	NE2000State* s=(NE2000State*)opaque;
+
+	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);
+	qemu_put_be32s(f, &s->irq);
+	qemu_put_buffer(f, s->mem, NE2000_MEM_SIZE);
+}
+
+static int ne2000_load(QEMUFile* f,void* opaque,int version_id)
+{
+	NE2000State* s=(NE2000State*)opaque;
+
+	if (version_id != 1)
+            return -EINVAL;
+
+	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, &s->irq);
+	qemu_get_buffer(f, s->mem, NE2000_MEM_SIZE);
+
+	return 0;
+}
+
 void isa_ne2000_init(int base, int irq, NetDriverState *nd)
 {
     NE2000State *s;
@@ -546,6 +599,8 @@
     if (!s)
         return;
     
+    register_savevm("ne2000", 0, 1, ne2000_save, ne2000_load, s);
+
     register_ioport_write(base, 16, 1, ne2000_ioport_write, s);
     register_ioport_read(base, 16, 1, ne2000_ioport_read, s);
 
@@ -620,4 +675,8 @@
     s->nd = nd;
     ne2000_reset(s);
     qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s);
+
+    register_savevm("ne2000", 0, 1, ne2000_save, ne2000_load, s);
+
 }
+
diff -Nurb qemu_cvs/hw/pci.c qemu_ne2000_savevm/hw/pci.c
--- qemu_cvs/hw/pci.c	2004-09-24 05:28:43.000000000 +0200
+++ qemu_ne2000_savevm/hw/pci.c	2004-09-24 05:28:43.000000000 +0200
@@ -62,6 +62,31 @@
     return bus;
 }
 
+static void generic_pci_save(QEMUFile* f,void* opaque)
+{
+	PCIDevice* s=(PCIDevice*)opaque;
+
+	qemu_put_buffer(f, s->config, 256);
+	qemu_put_be32s(f, &s->devfn);
+	qemu_put_buffer(f, s->name, 64);
+	qemu_put_be32s(f, &s->irq_index);
+}
+
+static int generic_pci_load(QEMUFile* f,void* opaque,int version_id)
+{
+	PCIDevice* s=(PCIDevice*)opaque;
+
+	if (version_id != 1)
+            return -EINVAL;
+
+	qemu_get_buffer(f, s->config, 256);
+	qemu_get_be32s(f, &s->devfn);
+	qemu_get_buffer(f, s->name, 64);
+	qemu_get_be32s(f, &s->irq_index);
+
+	return 0;
+}
+
 /* -1 for devfn means auto assign */
 PCIDevice *pci_register_device(PCIBus *bus, const char *name, 
                                int instance_size, int devfn,
@@ -96,6 +121,9 @@
     pci_dev->config_write = config_write;
     pci_dev->irq_index = pci_irq_index++;
     bus->devices[devfn] = pci_dev;
+
+    register_savevm(name, 0, 1, generic_pci_save, generic_pci_load, pci_dev);
+
     return pci_dev;
 }
 

[-- Attachment #3: Type: APPLICATION/x-perl, Size: 1657 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2004-09-28  2:41 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-09-24 10:07 [Qemu-devel] Patch: NE2000 savevm problem solved! Johannes Schindelin
2004-09-27 18:30 ` Gianni Tedesco
2004-09-27 22:23   ` Johannes Schindelin
2004-09-28  2:34     ` Gianni Tedesco

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).