Commit c3d78997a3235b2bb500c9eae4f0389550d77a35
1 parent
e6cf6a8c
minimal PCI IDE save/restore
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2117 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
113 additions
and
0 deletions
hw/ide.c
| ... | ... | @@ -2409,6 +2409,117 @@ void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table, |
| 2409 | 2409 | cmd646_set_irq, d, 1); |
| 2410 | 2410 | } |
| 2411 | 2411 | |
| 2412 | +static void pci_ide_save(QEMUFile* f, void *opaque) | |
| 2413 | +{ | |
| 2414 | + PCIIDEState *d = opaque; | |
| 2415 | + int i; | |
| 2416 | + | |
| 2417 | + pci_device_save(&d->dev, f); | |
| 2418 | + | |
| 2419 | + for(i = 0; i < 2; i++) { | |
| 2420 | + BMDMAState *bm = &d->bmdma[i]; | |
| 2421 | + qemu_put_8s(f, &bm->cmd); | |
| 2422 | + qemu_put_8s(f, &bm->status); | |
| 2423 | + qemu_put_be32s(f, &bm->addr); | |
| 2424 | + /* XXX: if a transfer is pending, we do not save it yet */ | |
| 2425 | + } | |
| 2426 | + | |
| 2427 | + /* per IDE interface data */ | |
| 2428 | + for(i = 0; i < 2; i++) { | |
| 2429 | + IDEState *s = &d->ide_if[i * 2]; | |
| 2430 | + uint8_t drive1_selected; | |
| 2431 | + qemu_put_8s(f, &s->cmd); | |
| 2432 | + drive1_selected = (s->cur_drive != s); | |
| 2433 | + qemu_put_8s(f, &drive1_selected); | |
| 2434 | + } | |
| 2435 | + | |
| 2436 | + /* per IDE drive data */ | |
| 2437 | + for(i = 0; i < 4; i++) { | |
| 2438 | + IDEState *s = &d->ide_if[i]; | |
| 2439 | + qemu_put_be32s(f, &s->mult_sectors); | |
| 2440 | + qemu_put_be32s(f, &s->identify_set); | |
| 2441 | + if (s->identify_set) { | |
| 2442 | + qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512); | |
| 2443 | + } | |
| 2444 | + qemu_put_8s(f, &s->feature); | |
| 2445 | + qemu_put_8s(f, &s->error); | |
| 2446 | + qemu_put_be32s(f, &s->nsector); | |
| 2447 | + qemu_put_8s(f, &s->sector); | |
| 2448 | + qemu_put_8s(f, &s->lcyl); | |
| 2449 | + qemu_put_8s(f, &s->hcyl); | |
| 2450 | + qemu_put_8s(f, &s->hob_feature); | |
| 2451 | + qemu_put_8s(f, &s->hob_nsector); | |
| 2452 | + qemu_put_8s(f, &s->hob_sector); | |
| 2453 | + qemu_put_8s(f, &s->hob_lcyl); | |
| 2454 | + qemu_put_8s(f, &s->hob_hcyl); | |
| 2455 | + qemu_put_8s(f, &s->select); | |
| 2456 | + qemu_put_8s(f, &s->status); | |
| 2457 | + qemu_put_8s(f, &s->lba48); | |
| 2458 | + | |
| 2459 | + qemu_put_8s(f, &s->sense_key); | |
| 2460 | + qemu_put_8s(f, &s->asc); | |
| 2461 | + /* XXX: if a transfer is pending, we do not save it yet */ | |
| 2462 | + } | |
| 2463 | +} | |
| 2464 | + | |
| 2465 | +static int pci_ide_load(QEMUFile* f, void *opaque, int version_id) | |
| 2466 | +{ | |
| 2467 | + PCIIDEState *d = opaque; | |
| 2468 | + int ret, i; | |
| 2469 | + | |
| 2470 | + if (version_id != 1) | |
| 2471 | + return -EINVAL; | |
| 2472 | + ret = pci_device_load(&d->dev, f); | |
| 2473 | + if (ret < 0) | |
| 2474 | + return ret; | |
| 2475 | + | |
| 2476 | + for(i = 0; i < 2; i++) { | |
| 2477 | + BMDMAState *bm = &d->bmdma[i]; | |
| 2478 | + qemu_get_8s(f, &bm->cmd); | |
| 2479 | + qemu_get_8s(f, &bm->status); | |
| 2480 | + qemu_get_be32s(f, &bm->addr); | |
| 2481 | + /* XXX: if a transfer is pending, we do not save it yet */ | |
| 2482 | + } | |
| 2483 | + | |
| 2484 | + /* per IDE interface data */ | |
| 2485 | + for(i = 0; i < 2; i++) { | |
| 2486 | + IDEState *s = &d->ide_if[i * 2]; | |
| 2487 | + uint8_t drive1_selected; | |
| 2488 | + qemu_get_8s(f, &s->cmd); | |
| 2489 | + qemu_get_8s(f, &drive1_selected); | |
| 2490 | + s->cur_drive = &d->ide_if[i * 2 + (drive1_selected != 0)]; | |
| 2491 | + } | |
| 2492 | + | |
| 2493 | + /* per IDE drive data */ | |
| 2494 | + for(i = 0; i < 4; i++) { | |
| 2495 | + IDEState *s = &d->ide_if[i]; | |
| 2496 | + qemu_get_be32s(f, &s->mult_sectors); | |
| 2497 | + qemu_get_be32s(f, &s->identify_set); | |
| 2498 | + if (s->identify_set) { | |
| 2499 | + qemu_get_buffer(f, (uint8_t *)s->identify_data, 512); | |
| 2500 | + } | |
| 2501 | + qemu_get_8s(f, &s->feature); | |
| 2502 | + qemu_get_8s(f, &s->error); | |
| 2503 | + qemu_get_be32s(f, &s->nsector); | |
| 2504 | + qemu_get_8s(f, &s->sector); | |
| 2505 | + qemu_get_8s(f, &s->lcyl); | |
| 2506 | + qemu_get_8s(f, &s->hcyl); | |
| 2507 | + qemu_get_8s(f, &s->hob_feature); | |
| 2508 | + qemu_get_8s(f, &s->hob_nsector); | |
| 2509 | + qemu_get_8s(f, &s->hob_sector); | |
| 2510 | + qemu_get_8s(f, &s->hob_lcyl); | |
| 2511 | + qemu_get_8s(f, &s->hob_hcyl); | |
| 2512 | + qemu_get_8s(f, &s->select); | |
| 2513 | + qemu_get_8s(f, &s->status); | |
| 2514 | + qemu_get_8s(f, &s->lba48); | |
| 2515 | + | |
| 2516 | + qemu_get_8s(f, &s->sense_key); | |
| 2517 | + qemu_get_8s(f, &s->asc); | |
| 2518 | + /* XXX: if a transfer is pending, we do not save it yet */ | |
| 2519 | + } | |
| 2520 | + return 0; | |
| 2521 | +} | |
| 2522 | + | |
| 2412 | 2523 | /* hd_table must contain 4 block drivers */ |
| 2413 | 2524 | /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */ |
| 2414 | 2525 | void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn) |
| ... | ... | @@ -2442,6 +2553,8 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn) |
| 2442 | 2553 | pic_set_irq_new, isa_pic, 15); |
| 2443 | 2554 | ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); |
| 2444 | 2555 | ide_init_ioport(&d->ide_if[2], 0x170, 0x376); |
| 2556 | + | |
| 2557 | + register_savevm("ide", 0, 1, pci_ide_save, pci_ide_load, d); | |
| 2445 | 2558 | } |
| 2446 | 2559 | |
| 2447 | 2560 | /***********************************************************/ | ... | ... |