Commit 30ca2aab8e7419d2c8cf597743633a6477840277
1 parent
8a8a608f
ne2000 savevm support (Johannes Schindelin)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1092 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
84 additions
and
1 deletions
hw/ne2000.c
| ... | ... | @@ -538,6 +538,59 @@ static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr) |
| 538 | 538 | return 0; |
| 539 | 539 | } |
| 540 | 540 | |
| 541 | +static void ne2000_save(QEMUFile* f,void* opaque) | |
| 542 | +{ | |
| 543 | + NE2000State* s=(NE2000State*)opaque; | |
| 544 | + | |
| 545 | + qemu_put_8s(f, &s->cmd); | |
| 546 | + qemu_put_be32s(f, &s->start); | |
| 547 | + qemu_put_be32s(f, &s->stop); | |
| 548 | + qemu_put_8s(f, &s->boundary); | |
| 549 | + qemu_put_8s(f, &s->tsr); | |
| 550 | + qemu_put_8s(f, &s->tpsr); | |
| 551 | + qemu_put_be16s(f, &s->tcnt); | |
| 552 | + qemu_put_be16s(f, &s->rcnt); | |
| 553 | + qemu_put_be32s(f, &s->rsar); | |
| 554 | + qemu_put_8s(f, &s->rsr); | |
| 555 | + qemu_put_8s(f, &s->isr); | |
| 556 | + qemu_put_8s(f, &s->dcfg); | |
| 557 | + qemu_put_8s(f, &s->imr); | |
| 558 | + qemu_put_buffer(f, s->phys, 6); | |
| 559 | + qemu_put_8s(f, &s->curpag); | |
| 560 | + qemu_put_buffer(f, s->mult, 8); | |
| 561 | + qemu_put_be32s(f, &s->irq); | |
| 562 | + qemu_put_buffer(f, s->mem, NE2000_MEM_SIZE); | |
| 563 | +} | |
| 564 | + | |
| 565 | +static int ne2000_load(QEMUFile* f,void* opaque,int version_id) | |
| 566 | +{ | |
| 567 | + NE2000State* s=(NE2000State*)opaque; | |
| 568 | + | |
| 569 | + if (version_id != 1) | |
| 570 | + return -EINVAL; | |
| 571 | + | |
| 572 | + qemu_get_8s(f, &s->cmd); | |
| 573 | + qemu_get_be32s(f, &s->start); | |
| 574 | + qemu_get_be32s(f, &s->stop); | |
| 575 | + qemu_get_8s(f, &s->boundary); | |
| 576 | + qemu_get_8s(f, &s->tsr); | |
| 577 | + qemu_get_8s(f, &s->tpsr); | |
| 578 | + qemu_get_be16s(f, &s->tcnt); | |
| 579 | + qemu_get_be16s(f, &s->rcnt); | |
| 580 | + qemu_get_be32s(f, &s->rsar); | |
| 581 | + qemu_get_8s(f, &s->rsr); | |
| 582 | + qemu_get_8s(f, &s->isr); | |
| 583 | + qemu_get_8s(f, &s->dcfg); | |
| 584 | + qemu_get_8s(f, &s->imr); | |
| 585 | + qemu_get_buffer(f, s->phys, 6); | |
| 586 | + qemu_get_8s(f, &s->curpag); | |
| 587 | + qemu_get_buffer(f, s->mult, 8); | |
| 588 | + qemu_get_be32s(f, &s->irq); | |
| 589 | + qemu_get_buffer(f, s->mem, NE2000_MEM_SIZE); | |
| 590 | + | |
| 591 | + return 0; | |
| 592 | +} | |
| 593 | + | |
| 541 | 594 | void isa_ne2000_init(int base, int irq, NetDriverState *nd) |
| 542 | 595 | { |
| 543 | 596 | NE2000State *s; |
| ... | ... | @@ -562,6 +615,9 @@ void isa_ne2000_init(int base, int irq, NetDriverState *nd) |
| 562 | 615 | ne2000_reset(s); |
| 563 | 616 | |
| 564 | 617 | qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s); |
| 618 | + | |
| 619 | + register_savevm("ne2000", 0, 1, ne2000_save, ne2000_load, s); | |
| 620 | + | |
| 565 | 621 | } |
| 566 | 622 | |
| 567 | 623 | /***********************************************************/ |
| ... | ... | @@ -612,7 +668,7 @@ void pci_ne2000_init(PCIBus *bus, NetDriverState *nd) |
| 612 | 668 | pci_conf[0x0e] = 0x00; // header_type |
| 613 | 669 | pci_conf[0x3d] = 1; // interrupt pin 0 |
| 614 | 670 | |
| 615 | - pci_register_io_region((PCIDevice *)d, 0, 0x100, | |
| 671 | + pci_register_io_region(&d->dev, 0, 0x100, | |
| 616 | 672 | PCI_ADDRESS_SPACE_IO, ne2000_map); |
| 617 | 673 | s = &d->ne2000; |
| 618 | 674 | s->irq = 16; // PCI interrupt |
| ... | ... | @@ -620,4 +676,9 @@ void pci_ne2000_init(PCIBus *bus, NetDriverState *nd) |
| 620 | 676 | s->nd = nd; |
| 621 | 677 | ne2000_reset(s); |
| 622 | 678 | qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s); |
| 679 | + | |
| 680 | + /* XXX: instance number ? */ | |
| 681 | + register_savevm("ne2000", 0, 1, ne2000_save, ne2000_load, s); | |
| 682 | + register_savevm("ne2000_pci", 0, 1, generic_pci_save, generic_pci_load, | |
| 683 | + &d->dev); | |
| 623 | 684 | } | ... | ... |
hw/pci.c
| ... | ... | @@ -62,6 +62,24 @@ static PCIBus *pci_register_bus(void) |
| 62 | 62 | return bus; |
| 63 | 63 | } |
| 64 | 64 | |
| 65 | +void generic_pci_save(QEMUFile* f, void *opaque) | |
| 66 | +{ | |
| 67 | + PCIDevice* s=(PCIDevice*)opaque; | |
| 68 | + | |
| 69 | + qemu_put_buffer(f, s->config, 256); | |
| 70 | +} | |
| 71 | + | |
| 72 | +int generic_pci_load(QEMUFile* f, void *opaque, int version_id) | |
| 73 | +{ | |
| 74 | + PCIDevice* s=(PCIDevice*)opaque; | |
| 75 | + | |
| 76 | + if (version_id != 1) | |
| 77 | + return -EINVAL; | |
| 78 | + | |
| 79 | + qemu_get_buffer(f, s->config, 256); | |
| 80 | + return 0; | |
| 81 | +} | |
| 82 | + | |
| 65 | 83 | /* -1 for devfn means auto assign */ |
| 66 | 84 | PCIDevice *pci_register_device(PCIBus *bus, const char *name, |
| 67 | 85 | int instance_size, int devfn, |
| ... | ... | @@ -558,6 +576,8 @@ void piix3_init(PCIBus *bus) |
| 558 | 576 | |
| 559 | 577 | d = (PIIX3State *)pci_register_device(bus, "PIIX3", sizeof(PIIX3State), |
| 560 | 578 | -1, NULL, NULL); |
| 579 | + register_savevm("PIIX3", 0, 1, generic_pci_save, generic_pci_load, d); | |
| 580 | + | |
| 561 | 581 | piix3_state = d; |
| 562 | 582 | pci_conf = d->dev.config; |
| 563 | 583 | ... | ... |
vl.h
| ... | ... | @@ -480,6 +480,8 @@ uint32_t pci_default_read_config(PCIDevice *d, |
| 480 | 480 | uint32_t address, int len); |
| 481 | 481 | void pci_default_write_config(PCIDevice *d, |
| 482 | 482 | uint32_t address, uint32_t val, int len); |
| 483 | +void generic_pci_save(QEMUFile* f, void *opaque); | |
| 484 | +int generic_pci_load(QEMUFile* f, void *opaque, int version_id); | |
| 483 | 485 | |
| 484 | 486 | extern struct PIIX3State *piix3_state; |
| 485 | 487 | ... | ... |