On 4/14/07, Blue Swirl <[EMAIL PROTECTED]> wrote:
On 4/13/07, Paul Brook <[EMAIL PROTECTED]> wrote:
> > I'd like to commit the attached FDC and M48T59 device save and reset
> > methods. After this change, all Sparc32 devices can be saved.
> >
> > Any comments?
>
> Do you also need to save the state of the attached drives?
Yes, at least motor state, head position and last operation status.
I'll update the patch.
Is this version OK?
Index: qemu/hw/fdc.c
===================================================================
--- qemu.orig/hw/fdc.c 2007-04-13 19:22:56.000000000 +0000
+++ qemu/hw/fdc.c 2007-04-14 06:47:30.000000000 +0000
@@ -1,7 +1,7 @@
/*
* QEMU Floppy disk emulator (Intel 82078)
*
- * Copyright (c) 2003 Jocelyn Mayer
+ * Copyright (c) 2003, 2007 Jocelyn Mayer
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -485,6 +485,99 @@
fdctrl_write_mem,
};
+static void fd_save (QEMUFile *f, fdrive_t *fd)
+{
+ uint8_t tmp;
+
+ tmp = fd->drflags;
+ qemu_put_8s(f, &tmp);
+ qemu_put_8s(f, &fd->head);
+ qemu_put_8s(f, &fd->track);
+ qemu_put_8s(f, &fd->sect);
+ qemu_put_8s(f, &fd->dir);
+ qemu_put_8s(f, &fd->rw);
+}
+
+static void fdc_save (QEMUFile *f, void *opaque)
+{
+ fdctrl_t *s = opaque;
+
+ qemu_put_8s(f, &s->state);
+ qemu_put_8s(f, &s->dma_en);
+ qemu_put_8s(f, &s->cur_drv);
+ qemu_put_8s(f, &s->bootsel);
+ qemu_put_buffer(f, s->fifo, FD_SECTOR_LEN);
+ qemu_put_be32s(f, &s->data_pos);
+ qemu_put_be32s(f, &s->data_len);
+ qemu_put_8s(f, &s->data_state);
+ qemu_put_8s(f, &s->data_dir);
+ qemu_put_8s(f, &s->int_status);
+ qemu_put_8s(f, &s->eot);
+ qemu_put_8s(f, &s->timer0);
+ qemu_put_8s(f, &s->timer1);
+ qemu_put_8s(f, &s->precomp_trk);
+ qemu_put_8s(f, &s->config);
+ qemu_put_8s(f, &s->lock);
+ qemu_put_8s(f, &s->pwrd);
+ fd_save(f, s->drives[0]);
+ fd_save(f, s->drives[1]);
+}
+
+static int fd_load (QEMUFile *f, fdrive_t *fd)
+{
+ uint8_t tmp;
+
+ qemu_get_8s(f, &tmp);
+ fd->drflags = tmp;
+ qemu_get_8s(f, &fd->head);
+ qemu_get_8s(f, &fd->track);
+ qemu_get_8s(f, &fd->sect);
+ qemu_get_8s(f, &fd->dir);
+ qemu_get_8s(f, &fd->rw);
+
+ return 0;
+}
+
+static int fdc_load (QEMUFile *f, void *opaque, int version_id)
+{
+ fdctrl_t *s = opaque;
+ int ret;
+
+ if (version_id != 1)
+ return -EINVAL;
+
+ qemu_get_8s(f, &s->state);
+ qemu_get_8s(f, &s->dma_en);
+ qemu_get_8s(f, &s->cur_drv);
+ qemu_get_8s(f, &s->bootsel);
+ qemu_get_buffer(f, s->fifo, FD_SECTOR_LEN);
+ qemu_get_be32s(f, &s->data_pos);
+ qemu_get_be32s(f, &s->data_len);
+ qemu_get_8s(f, &s->data_state);
+ qemu_get_8s(f, &s->data_dir);
+ qemu_get_8s(f, &s->int_status);
+ qemu_get_8s(f, &s->eot);
+ qemu_get_8s(f, &s->timer0);
+ qemu_get_8s(f, &s->timer1);
+ qemu_get_8s(f, &s->precomp_trk);
+ qemu_get_8s(f, &s->config);
+ qemu_get_8s(f, &s->lock);
+ qemu_get_8s(f, &s->pwrd);
+
+ ret = fd_load(f, s->drives[0]);
+ if (ret == 0)
+ ret = fd_load(f, s->drives[1]);
+
+ return ret;
+}
+
+static void fdctrl_external_reset(void *opaque)
+{
+ fdctrl_t *s = opaque;
+
+ fdctrl_reset(s, 0);
+}
+
fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped,
uint32_t io_base,
BlockDriverState **fds)
@@ -525,6 +618,8 @@
register_ioport_write(io_base + 0x01, 5, 1, &fdctrl_write, fdctrl);
register_ioport_write(io_base + 0x07, 1, 1, &fdctrl_write, fdctrl);
}
+ register_savevm("fdc", io_base, 1, fdc_save, fdc_load, fdctrl);
+ qemu_register_reset(fdctrl_external_reset, fdctrl);
for (i = 0; i < 2; i++) {
fd_revalidate(&fdctrl->drives[i]);
}
Index: qemu/hw/m48t59.c
===================================================================
--- qemu.orig/hw/m48t59.c 2007-04-13 19:22:56.000000000 +0000
+++ qemu/hw/m48t59.c 2007-04-14 06:51:03.000000000 +0000
@@ -1,7 +1,7 @@
/*
* QEMU M48T59 and M48T08 NVRAM emulation for PPC PREP and Sparc platforms
*
- * Copyright (c) 2003-2005 Jocelyn Mayer
+ * Copyright (c) 2003-2005, 2007 Jocelyn Mayer
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -575,12 +575,47 @@
&nvram_readl,
};
+static void m48t59_save(QEMUFile *f, void *opaque)
+{
+ m48t59_t *s = opaque;
+
+ qemu_put_8s(f, &s->lock);
+ qemu_put_be16s(f, &s->addr);
+ qemu_put_buffer(f, s->buffer, s->size);
+}
+
+static int m48t59_load(QEMUFile *f, void *opaque, int version_id)
+{
+ m48t59_t *s = opaque;
+
+ if (version_id != 1)
+ return -EINVAL;
+
+ qemu_get_8s(f, &s->lock);
+ qemu_get_be16s(f, &s->addr);
+ qemu_get_buffer(f, s->buffer, s->size);
+
+ return 0;
+}
+
+static void m48t59_reset(void *opaque)
+{
+ m48t59_t *NVRAM = opaque;
+
+ if (NVRAM->alrm_timer != NULL)
+ qemu_del_timer(NVRAM->alrm_timer);
+
+ if (NVRAM->wd_timer != NULL)
+ qemu_del_timer(NVRAM->wd_timer);
+}
+
/* Initialisation routine */
m48t59_t *m48t59_init (qemu_irq IRQ, target_ulong mem_base,
uint32_t io_base, uint16_t size,
int type)
{
m48t59_t *s;
+ target_ulong save_base;
s = qemu_mallocz(sizeof(m48t59_t));
if (!s)
@@ -610,5 +645,9 @@
}
s->lock = 0;
+ qemu_register_reset(m48t59_reset, s);
+ save_base = mem_base ? mem_base : io_base;
+ register_savevm("m48t59", save_base, 1, m48t59_save, m48t59_load, s);
+
return s;
}