Revision d7a6c270 hw/fdc.c
b/hw/fdc.c | ||
---|---|---|
481 | 481 |
uint8_t sra; |
482 | 482 |
uint8_t srb; |
483 | 483 |
uint8_t dor; |
484 |
uint8_t dor_vmstate; /* only used as temp during vmstate */ |
|
484 | 485 |
uint8_t tdr; |
485 | 486 |
uint8_t dsr; |
486 | 487 |
uint8_t msr; |
... | ... | |
490 | 491 |
uint8_t status2; |
491 | 492 |
/* Command FIFO */ |
492 | 493 |
uint8_t *fifo; |
494 |
int32_t fifo_size; |
|
493 | 495 |
uint32_t data_pos; |
494 | 496 |
uint32_t data_len; |
495 | 497 |
uint8_t data_state; |
... | ... | |
508 | 510 |
/* Sun4m quirks? */ |
509 | 511 |
int sun4m; |
510 | 512 |
/* Floppy drives */ |
513 |
uint8_t num_floppies; |
|
511 | 514 |
fdrive_t drives[MAX_FD]; |
512 | 515 |
int reset_sensei; |
513 | 516 |
}; |
... | ... | |
627 | 630 |
NULL, |
628 | 631 |
}; |
629 | 632 |
|
630 |
static void fd_save (QEMUFile *f, fdrive_t *fd) |
|
631 |
{ |
|
632 |
qemu_put_8s(f, &fd->head); |
|
633 |
qemu_put_8s(f, &fd->track); |
|
634 |
qemu_put_8s(f, &fd->sect); |
|
635 |
} |
|
633 |
static const VMStateDescription vmstate_fdrive = { |
|
634 |
.name = "fdrive", |
|
635 |
.version_id = 1, |
|
636 |
.minimum_version_id = 1, |
|
637 |
.minimum_version_id_old = 1, |
|
638 |
.fields = (VMStateField []) { |
|
639 |
VMSTATE_UINT8(head, fdrive_t), |
|
640 |
VMSTATE_UINT8(track, fdrive_t), |
|
641 |
VMSTATE_UINT8(sect, fdrive_t), |
|
642 |
VMSTATE_END_OF_LIST() |
|
643 |
} |
|
644 |
}; |
|
636 | 645 |
|
637 |
static void fdc_save (QEMUFile *f, void *opaque)
|
|
646 |
static void fdc_pre_save(const void *opaque)
|
|
638 | 647 |
{ |
639 |
fdctrl_t *s = opaque; |
|
640 |
uint8_t tmp; |
|
641 |
int i; |
|
642 |
uint8_t dor = s->dor | GET_CUR_DRV(s); |
|
648 |
fdctrl_t *s = (void *)opaque; |
|
643 | 649 |
|
644 |
/* Controller state */ |
|
645 |
qemu_put_8s(f, &s->sra); |
|
646 |
qemu_put_8s(f, &s->srb); |
|
647 |
qemu_put_8s(f, &dor); |
|
648 |
qemu_put_8s(f, &s->tdr); |
|
649 |
qemu_put_8s(f, &s->dsr); |
|
650 |
qemu_put_8s(f, &s->msr); |
|
651 |
qemu_put_8s(f, &s->status0); |
|
652 |
qemu_put_8s(f, &s->status1); |
|
653 |
qemu_put_8s(f, &s->status2); |
|
654 |
/* Command FIFO */ |
|
655 |
qemu_put_buffer(f, s->fifo, FD_SECTOR_LEN); |
|
656 |
qemu_put_be32s(f, &s->data_pos); |
|
657 |
qemu_put_be32s(f, &s->data_len); |
|
658 |
qemu_put_8s(f, &s->data_state); |
|
659 |
qemu_put_8s(f, &s->data_dir); |
|
660 |
qemu_put_8s(f, &s->eot); |
|
661 |
/* States kept only to be returned back */ |
|
662 |
qemu_put_8s(f, &s->timer0); |
|
663 |
qemu_put_8s(f, &s->timer1); |
|
664 |
qemu_put_8s(f, &s->precomp_trk); |
|
665 |
qemu_put_8s(f, &s->config); |
|
666 |
qemu_put_8s(f, &s->lock); |
|
667 |
qemu_put_8s(f, &s->pwrd); |
|
668 |
|
|
669 |
tmp = MAX_FD; |
|
670 |
qemu_put_8s(f, &tmp); |
|
671 |
for (i = 0; i < MAX_FD; i++) |
|
672 |
fd_save(f, &s->drives[i]); |
|
650 |
s->dor_vmstate = s->dor | GET_CUR_DRV(s); |
|
673 | 651 |
} |
674 | 652 |
|
675 |
static int fd_load (QEMUFile *f, fdrive_t *fd)
|
|
653 |
static int fdc_post_load(void *opaque)
|
|
676 | 654 |
{ |
677 |
qemu_get_8s(f, &fd->head); |
|
678 |
qemu_get_8s(f, &fd->track); |
|
679 |
qemu_get_8s(f, &fd->sect); |
|
655 |
fdctrl_t *s = opaque; |
|
680 | 656 |
|
657 |
SET_CUR_DRV(s, s->dor_vmstate & FD_DOR_SELMASK); |
|
658 |
s->dor = s->dor_vmstate & ~FD_DOR_SELMASK; |
|
681 | 659 |
return 0; |
682 | 660 |
} |
683 | 661 |
|
684 |
static int fdc_load (QEMUFile *f, void *opaque, int version_id) |
|
685 |
{ |
|
686 |
fdctrl_t *s = opaque; |
|
687 |
int i, ret = 0; |
|
688 |
uint8_t n; |
|
689 |
|
|
690 |
if (version_id != 2) |
|
691 |
return -EINVAL; |
|
692 |
|
|
693 |
/* Controller state */ |
|
694 |
qemu_get_8s(f, &s->sra); |
|
695 |
qemu_get_8s(f, &s->srb); |
|
696 |
qemu_get_8s(f, &s->dor); |
|
697 |
SET_CUR_DRV(s, s->dor & FD_DOR_SELMASK); |
|
698 |
s->dor &= ~FD_DOR_SELMASK; |
|
699 |
qemu_get_8s(f, &s->tdr); |
|
700 |
qemu_get_8s(f, &s->dsr); |
|
701 |
qemu_get_8s(f, &s->msr); |
|
702 |
qemu_get_8s(f, &s->status0); |
|
703 |
qemu_get_8s(f, &s->status1); |
|
704 |
qemu_get_8s(f, &s->status2); |
|
705 |
/* Command FIFO */ |
|
706 |
qemu_get_buffer(f, s->fifo, FD_SECTOR_LEN); |
|
707 |
qemu_get_be32s(f, &s->data_pos); |
|
708 |
qemu_get_be32s(f, &s->data_len); |
|
709 |
qemu_get_8s(f, &s->data_state); |
|
710 |
qemu_get_8s(f, &s->data_dir); |
|
711 |
qemu_get_8s(f, &s->eot); |
|
712 |
/* States kept only to be returned back */ |
|
713 |
qemu_get_8s(f, &s->timer0); |
|
714 |
qemu_get_8s(f, &s->timer1); |
|
715 |
qemu_get_8s(f, &s->precomp_trk); |
|
716 |
qemu_get_8s(f, &s->config); |
|
717 |
qemu_get_8s(f, &s->lock); |
|
718 |
qemu_get_8s(f, &s->pwrd); |
|
719 |
qemu_get_8s(f, &n); |
|
720 |
|
|
721 |
if (n > MAX_FD) |
|
722 |
return -EINVAL; |
|
723 |
|
|
724 |
for (i = 0; i < n; i++) { |
|
725 |
ret = fd_load(f, &s->drives[i]); |
|
726 |
if (ret != 0) |
|
727 |
break; |
|
662 |
static const VMStateDescription vmstate_fdc = { |
|
663 |
.name = "fdc", |
|
664 |
.version_id = 2, |
|
665 |
.minimum_version_id = 2, |
|
666 |
.minimum_version_id_old = 2, |
|
667 |
.pre_save = fdc_pre_save, |
|
668 |
.post_load = fdc_post_load, |
|
669 |
.fields = (VMStateField []) { |
|
670 |
/* Controller State */ |
|
671 |
VMSTATE_UINT8(sra, fdctrl_t), |
|
672 |
VMSTATE_UINT8(srb, fdctrl_t), |
|
673 |
VMSTATE_UINT8(dor_vmstate, fdctrl_t), |
|
674 |
VMSTATE_UINT8(tdr, fdctrl_t), |
|
675 |
VMSTATE_UINT8(dsr, fdctrl_t), |
|
676 |
VMSTATE_UINT8(msr, fdctrl_t), |
|
677 |
VMSTATE_UINT8(status0, fdctrl_t), |
|
678 |
VMSTATE_UINT8(status1, fdctrl_t), |
|
679 |
VMSTATE_UINT8(status2, fdctrl_t), |
|
680 |
/* Command FIFO */ |
|
681 |
VMSTATE_VARRAY(fifo, fdctrl_t, fifo_size, 0, vmstate_info_uint8, uint8), |
|
682 |
VMSTATE_UINT32(data_pos, fdctrl_t), |
|
683 |
VMSTATE_UINT32(data_len, fdctrl_t), |
|
684 |
VMSTATE_UINT8(data_state, fdctrl_t), |
|
685 |
VMSTATE_UINT8(data_dir, fdctrl_t), |
|
686 |
VMSTATE_UINT8(eot, fdctrl_t), |
|
687 |
/* States kept only to be returned back */ |
|
688 |
VMSTATE_UINT8(timer0, fdctrl_t), |
|
689 |
VMSTATE_UINT8(timer1, fdctrl_t), |
|
690 |
VMSTATE_UINT8(precomp_trk, fdctrl_t), |
|
691 |
VMSTATE_UINT8(config, fdctrl_t), |
|
692 |
VMSTATE_UINT8(lock, fdctrl_t), |
|
693 |
VMSTATE_UINT8(pwrd, fdctrl_t), |
|
694 |
VMSTATE_UINT8_EQUAL(num_floppies, fdctrl_t), |
|
695 |
VMSTATE_STRUCT_ARRAY(drives, fdctrl_t, MAX_FD, 1, |
|
696 |
vmstate_fdrive, fdrive_t), |
|
697 |
VMSTATE_END_OF_LIST() |
|
728 | 698 |
} |
729 |
|
|
730 |
return ret; |
|
731 |
} |
|
699 |
}; |
|
732 | 700 |
|
733 | 701 |
static void fdctrl_external_reset(void *opaque) |
734 | 702 |
{ |
... | ... | |
1951 | 1919 |
|
1952 | 1920 |
FLOPPY_DPRINTF("init controller\n"); |
1953 | 1921 |
fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN); |
1922 |
fdctrl->fifo_size = 512; |
|
1954 | 1923 |
fdctrl->result_timer = qemu_new_timer(vm_clock, |
1955 | 1924 |
fdctrl_result_timer, fdctrl); |
1956 | 1925 |
|
1957 | 1926 |
fdctrl->version = 0x90; /* Intel 82078 controller */ |
1958 | 1927 |
fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */ |
1928 |
fdctrl->num_floppies = MAX_FD; |
|
1959 | 1929 |
|
1960 | 1930 |
fdctrl_external_reset(fdctrl); |
1961 |
register_savevm("fdc", -1, 2, fdc_save, fdc_load, fdctrl);
|
|
1931 |
vmstate_register(-1, &vmstate_fdc, fdctrl);
|
|
1962 | 1932 |
qemu_register_reset(fdctrl_external_reset, fdctrl); |
1963 | 1933 |
return 0; |
1964 | 1934 |
} |
Also available in: Unified diff