r2052 - in trunk/src/host/qemu-neo1973: . hw
andrew at sita.openmoko.org
andrew at sita.openmoko.org
Tue May 22 01:47:19 CEST 2007
Author: andrew
Date: 2007-05-22 01:47:12 +0200 (Tue, 22 May 2007)
New Revision: 2052
Modified:
trunk/src/host/qemu-neo1973/ecc.h
trunk/src/host/qemu-neo1973/hw/i2c.c
trunk/src/host/qemu-neo1973/hw/i2c.h
trunk/src/host/qemu-neo1973/hw/jbt6k74.c
trunk/src/host/qemu-neo1973/hw/nand.c
trunk/src/host/qemu-neo1973/hw/neo1973.c
trunk/src/host/qemu-neo1973/hw/pcf5060x.c
trunk/src/host/qemu-neo1973/hw/s3c2410.c
trunk/src/host/qemu-neo1973/hw/s3c24xx_gpio.c
trunk/src/host/qemu-neo1973/hw/s3c24xx_lcd.c
trunk/src/host/qemu-neo1973/hw/s3c24xx_mmci.c
trunk/src/host/qemu-neo1973/hw/s3c24xx_rtc.c
trunk/src/host/qemu-neo1973/hw/s3c24xx_udc.c
trunk/src/host/qemu-neo1973/hw/wm8750.c
trunk/src/host/qemu-neo1973/hw/wm8753.c
trunk/src/host/qemu-neo1973/vl.c
Log:
"savevm"/"loadvm" support for ARM cores, the S3C peripherals and random other hardware.
Allow snapshot storing in mtdblock images and rip out some of the hardcoded HDD snapshot checks.
Modified: trunk/src/host/qemu-neo1973/ecc.h
===================================================================
--- trunk/src/host/qemu-neo1973/ecc.h 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/ecc.h 2007-05-21 23:47:12 UTC (rev 2052)
@@ -75,3 +75,20 @@
s->cp = 0x00;
s->count = 0;
}
+
+/* Save/restore */
+static inline void ecc_put(QEMUFile *f, struct ecc_state_s *s)
+{
+ qemu_put_8s(f, &s->cp);
+ qemu_put_be16s(f, &s->lp[0]);
+ qemu_put_be16s(f, &s->lp[1]);
+ qemu_put_be16s(f, &s->count);
+}
+
+static inline void ecc_get(QEMUFile *f, struct ecc_state_s *s)
+{
+ qemu_get_8s(f, &s->cp);
+ qemu_get_be16s(f, &s->lp[0]);
+ qemu_get_be16s(f, &s->lp[1]);
+ qemu_get_be16s(f, &s->count);
+}
Modified: trunk/src/host/qemu-neo1973/hw/i2c.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/i2c.c 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/hw/i2c.c 2007-05-21 23:47:12 UTC (rev 2052)
@@ -115,3 +115,34 @@
dev->event(dev, I2C_NACK);
}
+void i2c_bus_save(QEMUFile *f, i2c_bus *bus)
+{
+ qemu_put_byte(f, bus->current_dev ? bus->current_dev->address : 0x00);
+}
+
+void i2c_bus_load(QEMUFile *f, i2c_bus *bus)
+{
+ i2c_slave *dev;
+ uint8_t address = qemu_get_byte(f);
+
+ if (address) {
+ for (dev = bus->dev; dev; dev = dev->next)
+ if (dev->address == address) {
+ bus->current_dev = dev;
+ return;
+ }
+
+ fprintf(stderr, "%s: I2C slave with address %02x disappeared\n",
+ __FUNCTION__, address);
+ }
+}
+
+void i2c_slave_save(QEMUFile *f, i2c_slave *dev)
+{
+ qemu_put_byte(f, dev->address);
+}
+
+void i2c_slave_load(QEMUFile *f, i2c_slave *dev)
+{
+ dev->address = qemu_get_byte(f);
+}
Modified: trunk/src/host/qemu-neo1973/hw/i2c.h
===================================================================
--- trunk/src/host/qemu-neo1973/hw/i2c.h 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/hw/i2c.h 2007-05-21 23:47:12 UTC (rev 2052)
@@ -45,6 +45,10 @@
void i2c_nack(i2c_bus *bus);
int i2c_send(i2c_bus *bus, uint8_t data);
int i2c_recv(i2c_bus *bus);
+void i2c_bus_save(QEMUFile *f, i2c_bus *bus);
+void i2c_bus_load(QEMUFile *f, i2c_bus *bus);
+void i2c_slave_save(QEMUFile *f, i2c_slave *dev);
+void i2c_slave_load(QEMUFile *f, i2c_slave *dev);
/* max7310.c */
i2c_slave *max7310_init(i2c_bus *bus);
Modified: trunk/src/host/qemu-neo1973/hw/jbt6k74.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/jbt6k74.c 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/hw/jbt6k74.c 2007-05-21 23:47:12 UTC (rev 2052)
@@ -216,10 +216,48 @@
return ret;
}
+static void jbt6k74_save(QEMUFile *f, void *opaque)
+{
+ struct jbt6k74_s *s = (struct jbt6k74_s *) opaque;
+ int i;
+
+ qemu_put_8s(f, &s->command);
+ qemu_put_be32s(f, &s->parameter);
+ qemu_put_be32s(f, &s->response);
+ qemu_put_be32(f, s->dc);
+ qemu_put_be32(f, s->bit);
+ qemu_put_be32(f, s->bytes);
+ qemu_put_be32(f, s->respbit);
+ for (i = 0; i < 0x100; i ++)
+ qemu_put_be16s(f, &s->regs[i]);
+}
+
+static int jbt6k74_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct jbt6k74_s *s = (struct jbt6k74_s *) opaque;
+ int i;
+
+ qemu_get_8s(f, &s->command);
+ qemu_get_be32s(f, &s->parameter);
+ qemu_get_be32s(f, &s->response);
+ s->dc = qemu_get_be32(f);
+ s->bit = qemu_get_be32(f);
+ s->bytes = qemu_get_be32(f);
+ s->respbit = qemu_get_be32(f);
+ for (i = 0; i < 0x100; i ++)
+ qemu_get_be16s(f, &s->regs[i]);
+
+ return 0;
+}
+
+static int jbt6k74_iid = 0;
+
void *jbt6k74_init()
{
struct jbt6k74_s *s = qemu_mallocz(sizeof(struct jbt6k74_s));
jbt6k74_reset(s);
+ register_savevm("jbt6k74", jbt6k74_iid ++, 0,
+ jbt6k74_save, jbt6k74_load, s);
return s;
}
Modified: trunk/src/host/qemu-neo1973/hw/nand.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/nand.c 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/hw/nand.c 2007-05-21 23:47:12 UTC (rev 2052)
@@ -273,6 +273,50 @@
}
}
+static void nand_save(QEMUFile *f, void *opaque)
+{
+ struct nand_flash_s *s = (struct nand_flash_s *) opaque;
+ qemu_put_byte(f, s->cle);
+ qemu_put_byte(f, s->ale);
+ qemu_put_byte(f, s->ce);
+ qemu_put_byte(f, s->wp);
+ qemu_put_byte(f, s->gnd);
+ qemu_put_buffer(f, s->io, sizeof(s->io));
+ qemu_put_be32(f, s->ioaddr - s->io);
+ qemu_put_be32(f, s->iolen);
+
+ qemu_put_be32s(f, &s->cmd);
+ qemu_put_be32s(f, &s->addr);
+ qemu_put_be32(f, s->addrlen);
+ qemu_put_be32(f, s->status);
+ qemu_put_be32(f, s->offset);
+ /* XXX: do we want to save s->storage too? */
+}
+
+static int nand_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct nand_flash_s *s = (struct nand_flash_s *) opaque;
+ s->cle = qemu_get_byte(f);
+ s->ale = qemu_get_byte(f);
+ s->ce = qemu_get_byte(f);
+ s->wp = qemu_get_byte(f);
+ s->gnd = qemu_get_byte(f);
+ qemu_get_buffer(f, s->io, sizeof(s->io));
+ s->ioaddr = s->io + qemu_get_be32(f);
+ s->iolen = qemu_get_be32(f);
+ if (s->ioaddr >= s->io + sizeof(s->io) || s->ioaddr < s->io)
+ return -EINVAL;
+
+ qemu_get_be32s(f, &s->cmd);
+ qemu_get_be32s(f, &s->addr);
+ s->addrlen = qemu_get_be32(f);
+ s->status = qemu_get_be32(f);
+ s->offset = qemu_get_be32(f);
+ return 0;
+}
+
+static int nand_iid = 0;
+
/*
* Chip inputs are CLE, ALE, CE, WP, GND and eight I/O pins. Chip
* outputs are R/B and eight I/O pins.
@@ -443,6 +487,9 @@
if (pagesize)
s->storage = (uint8_t *) memset(qemu_malloc(s->pages * pagesize),
0xff, s->pages * pagesize);
+
+ register_savevm("nand", nand_iid ++, 0, nand_save, nand_load, s);
+
return s;
}
Modified: trunk/src/host/qemu-neo1973/hw/neo1973.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/neo1973.c 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/hw/neo1973.c 2007-05-21 23:47:12 UTC (rev 2052)
@@ -276,6 +276,21 @@
return 0;
}
+static void lm_save(QEMUFile *f, void *opaque)
+{
+ struct lm4857_s *s = (struct lm4857_s *) opaque;
+ qemu_put_buffer(f, s->regs, sizeof(s->regs));
+ i2c_slave_save(f, &s->i2c);
+}
+
+static int lm_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct lm4857_s *s = (struct lm4857_s *) opaque;
+ qemu_get_buffer(f, s->regs, sizeof(s->regs));
+ i2c_slave_load(f, &s->i2c);
+ return 0;
+}
+
i2c_slave *lm4857_init(i2c_bus *bus)
{
struct lm4857_s *s = (struct lm4857_s *)
@@ -285,6 +300,7 @@
s->i2c.recv = lm_rx;
lm_reset(&s->i2c);
+ register_savevm("lm4857", 0, 0, lm_save, lm_load, s);
return &s->i2c;
}
Modified: trunk/src/host/qemu-neo1973/hw/pcf5060x.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/pcf5060x.c 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/hw/pcf5060x.c 2007-05-21 23:47:12 UTC (rev 2052)
@@ -785,6 +785,137 @@
pcf_update(s);
}
+static void pcf_save(QEMUFile *f, void *opaque)
+{
+ struct pcf_s *s = (struct pcf_s *) opaque;
+ qemu_put_be32(f, s->firstbyte);
+ qemu_put_be32(f, s->charging);
+ qemu_put_8s(f, &s->reg);
+ qemu_put_8s(f, &s->oocs);
+ qemu_put_8s(f, &s->oocc[0]);
+ qemu_put_8s(f, &s->oocc[1]);
+ qemu_put_8s(f, &s->intr[0]);
+ qemu_put_8s(f, &s->intr[1]);
+ qemu_put_8s(f, &s->intr[2]);
+ qemu_put_8s(f, &s->intm[0]);
+ qemu_put_8s(f, &s->intm[1]);
+ qemu_put_8s(f, &s->intm[2]);
+ qemu_put_8s(f, &s->pssc);
+ qemu_put_8s(f, &s->pwrokm);
+ qemu_put_8s(f, &s->dcdc[0]);
+ qemu_put_8s(f, &s->dcdc[1]);
+ qemu_put_8s(f, &s->dcdc[2]);
+ qemu_put_8s(f, &s->dcdc[3]);
+ qemu_put_8s(f, &s->dcdec[0]);
+ qemu_put_8s(f, &s->dcdec[1]);
+ qemu_put_8s(f, &s->dcudc[0]);
+ qemu_put_8s(f, &s->dcudc[1]);
+ qemu_put_8s(f, &s->ioregc);
+ qemu_put_8s(f, &s->dregc[0]);
+ qemu_put_8s(f, &s->dregc[1]);
+ qemu_put_8s(f, &s->dregc[2]);
+ qemu_put_8s(f, &s->lpregc[0]);
+ qemu_put_8s(f, &s->lpregc[1]);
+ qemu_put_8s(f, &s->mbcc[0]);
+ qemu_put_8s(f, &s->mbcc[1]);
+ qemu_put_8s(f, &s->mbcc[2]);
+ qemu_put_8s(f, &s->bbcc);
+ qemu_put_8s(f, &s->adcc[0]);
+ qemu_put_8s(f, &s->adcc[1]);
+ qemu_put_8s(f, &s->adcs[0]);
+ qemu_put_8s(f, &s->adcs[1]);
+ qemu_put_8s(f, &s->adcs[2]);
+ qemu_put_8s(f, &s->acdc[0]);
+ qemu_put_8s(f, &s->bvmc);
+ qemu_put_8s(f, &s->pwmc[0]);
+ qemu_put_8s(f, &s->ledc[0]);
+ qemu_put_8s(f, &s->ledc[1]);
+ qemu_put_8s(f, &s->gpoc[0]);
+ qemu_put_8s(f, &s->gpoc[1]);
+ qemu_put_8s(f, &s->gpoc[2]);
+ qemu_put_8s(f, &s->gpoc[3]);
+ qemu_put_8s(f, &s->gpoc[4]);
+ qemu_put_be32(f, s->ts.x);
+ qemu_put_be32(f, s->ts.y);
+ qemu_put_be32s(f, &s->rtc.sec);
+ qemu_put_8s(f, &s->rtc.alm_sec);
+ qemu_put_8s(f, &s->rtc.alm_min);
+ qemu_put_8s(f, &s->rtc.alm_hour);
+ qemu_put_8s(f, &s->rtc.alm_wday);
+ qemu_put_8s(f, &s->rtc.alm_mday);
+ qemu_put_8s(f, &s->rtc.alm_mon);
+ qemu_put_8s(f, &s->rtc.alm_year);
+ qemu_put_8s(f, &s->gpo);
+ i2c_slave_save(f, &s->i2c);
+}
+
+static int pcf_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct pcf_s *s = (struct pcf_s *) opaque;
+ s->firstbyte = qemu_get_be32(f);
+ s->charging = qemu_get_be32(f);
+ qemu_get_8s(f, &s->reg);
+ qemu_get_8s(f, &s->oocs);
+ qemu_get_8s(f, &s->oocc[0]);
+ qemu_get_8s(f, &s->oocc[1]);
+ qemu_get_8s(f, &s->intr[0]);
+ qemu_get_8s(f, &s->intr[1]);
+ qemu_get_8s(f, &s->intr[2]);
+ qemu_get_8s(f, &s->intm[0]);
+ qemu_get_8s(f, &s->intm[1]);
+ qemu_get_8s(f, &s->intm[2]);
+ qemu_get_8s(f, &s->pssc);
+ qemu_get_8s(f, &s->pwrokm);
+ qemu_get_8s(f, &s->dcdc[0]);
+ qemu_get_8s(f, &s->dcdc[1]);
+ qemu_get_8s(f, &s->dcdc[2]);
+ qemu_get_8s(f, &s->dcdc[3]);
+ qemu_get_8s(f, &s->dcdec[0]);
+ qemu_get_8s(f, &s->dcdec[1]);
+ qemu_get_8s(f, &s->dcudc[0]);
+ qemu_get_8s(f, &s->dcudc[1]);
+ qemu_get_8s(f, &s->ioregc);
+ qemu_get_8s(f, &s->dregc[0]);
+ qemu_get_8s(f, &s->dregc[1]);
+ qemu_get_8s(f, &s->dregc[2]);
+ qemu_get_8s(f, &s->lpregc[0]);
+ qemu_get_8s(f, &s->lpregc[1]);
+ qemu_get_8s(f, &s->mbcc[0]);
+ qemu_get_8s(f, &s->mbcc[1]);
+ qemu_get_8s(f, &s->mbcc[2]);
+ qemu_get_8s(f, &s->bbcc);
+ qemu_get_8s(f, &s->adcc[0]);
+ qemu_get_8s(f, &s->adcc[1]);
+ qemu_get_8s(f, &s->adcs[0]);
+ qemu_get_8s(f, &s->adcs[1]);
+ qemu_get_8s(f, &s->adcs[2]);
+ qemu_get_8s(f, &s->acdc[0]);
+ qemu_get_8s(f, &s->bvmc);
+ qemu_get_8s(f, &s->pwmc[0]);
+ qemu_get_8s(f, &s->ledc[0]);
+ qemu_get_8s(f, &s->ledc[1]);
+ qemu_get_8s(f, &s->gpoc[0]);
+ qemu_get_8s(f, &s->gpoc[1]);
+ qemu_get_8s(f, &s->gpoc[2]);
+ qemu_get_8s(f, &s->gpoc[3]);
+ qemu_get_8s(f, &s->gpoc[4]);
+ s->ts.x = qemu_get_be32(f);
+ s->ts.y = qemu_get_be32(f);
+ qemu_get_be32s(f, &s->rtc.sec);
+ qemu_get_8s(f, &s->rtc.alm_sec);
+ qemu_get_8s(f, &s->rtc.alm_min);
+ qemu_get_8s(f, &s->rtc.alm_hour);
+ qemu_get_8s(f, &s->rtc.alm_wday);
+ qemu_get_8s(f, &s->rtc.alm_mday);
+ qemu_get_8s(f, &s->rtc.alm_mon);
+ qemu_get_8s(f, &s->rtc.alm_year);
+ qemu_get_8s(f, &s->gpo);
+ i2c_slave_load(f, &s->i2c);
+ return 0;
+}
+
+static int pcf_iid = 0;
+
i2c_slave *pcf5060x_init(i2c_bus *bus, qemu_irq irq, int tsc)
{
struct pcf_s *s = (struct pcf_s *)
@@ -804,9 +935,11 @@
if (tsc) {
/* We want absolute coordinates */
qemu_add_mouse_event_handler(pcf_adc_event, s, 1,
- "QEMU ADS7846-driven Touchscreen");
+ "QEMU PCF50606-driven Touchscreen");
}
+ register_savevm("pcf5060x", pcf_iid ++, 0, pcf_save, pcf_load, s);
+
return &s->i2c;
}
Modified: trunk/src/host/qemu-neo1973/hw/s3c2410.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/s3c2410.c 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/hw/s3c2410.c 2007-05-21 23:47:12 UTC (rev 2052)
@@ -287,6 +287,34 @@
s3c_pic_write,
};
+static void s3c_pic_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_pic_state_s *s = (struct s3c_pic_state_s *) opaque;
+ qemu_put_be32s(f, &s->srcpnd);
+ qemu_put_be32s(f, &s->intpnd);
+ qemu_put_be32s(f, &s->intmsk);
+ qemu_put_be32s(f, &s->intmod);
+ qemu_put_be32s(f, &s->priority);
+ qemu_put_be32s(f, &s->subsrcpnd);
+ qemu_put_be32s(f, &s->intsubmsk);
+ qemu_put_be32(f, s->intoffset);
+}
+
+static int s3c_pic_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_pic_state_s *s = (struct s3c_pic_state_s *) opaque;
+ qemu_get_be32s(f, &s->srcpnd);
+ qemu_get_be32s(f, &s->intpnd);
+ qemu_get_be32s(f, &s->intmsk);
+ qemu_get_be32s(f, &s->intmod);
+ qemu_get_be32s(f, &s->priority);
+ qemu_get_be32s(f, &s->subsrcpnd);
+ qemu_get_be32s(f, &s->intsubmsk);
+ s->intoffset = qemu_get_be32(f);
+ s3c_pic_update(s);
+ return 0;
+}
+
struct s3c_pic_state_s *s3c_pic_init(target_phys_addr_t base,
qemu_irq *arm_pic)
{
@@ -304,6 +332,8 @@
s3c_pic_writefn, s);
cpu_register_physical_memory(s->base, 0xffffff, iomemtype);
+ register_savevm("s3c24xx_pic", 0, 0, s3c_pic_save, s3c_pic_load, s);
+
return s;
}
@@ -386,6 +416,23 @@
s3c_mc_write,
};
+static void s3c_mc_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_state_s *s = (struct s3c_state_s *) opaque;
+ int i;
+ for (i = 0; i < 13; i ++)
+ qemu_put_be32s(f, &s->mc_regs[i]);
+}
+
+static int s3c_mc_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_state_s *s = (struct s3c_state_s *) opaque;
+ int i;
+ for (i = 0; i < 13; i ++)
+ qemu_get_be32s(f, &s->mc_regs[i]);
+ return 0;
+}
+
/* NAND Flash controller */
#define S3C_NFCONF 0x00 /* NAND Flash Configuration register */
#define S3C_NFCMD 0x04 /* NAND Flash Command Set register */
@@ -504,6 +551,27 @@
s3c_nand_write,
};
+static void s3c_nand_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_state_s *s = (struct s3c_state_s *) opaque;
+ qemu_put_be16s(f, &s->nfconf);
+ qemu_put_8s(f, &s->nfcmd);
+ qemu_put_8s(f, &s->nfaddr);
+ qemu_put_be32(f, s->nfwp);
+ ecc_put(f, &s->nfecc);
+}
+
+static int s3c_nand_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_state_s *s = (struct s3c_state_s *) opaque;
+ qemu_get_be16s(f, &s->nfconf);
+ qemu_get_8s(f, &s->nfcmd);
+ qemu_get_8s(f, &s->nfaddr);
+ s->nfwp = qemu_get_be32(f);
+ ecc_get(f, &s->nfecc);
+ return 0;
+}
+
/* Clock & power management */
#define S3C_LOCKTIME 0x00 /* PLL Lock Time Count register */
#define S3C_MPLLCON 0x04 /* MPLL Configuration register */
@@ -588,6 +656,23 @@
s3c_clkpwr_write,
};
+static void s3c_clkpwr_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_state_s *s = (struct s3c_state_s *) opaque;
+ int i;
+ for (i = 0; i < 6; i ++)
+ qemu_put_be32s(f, &s->clkpwr_regs[i]);
+}
+
+static int s3c_clkpwr_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_state_s *s = (struct s3c_state_s *) opaque;
+ int i;
+ for (i = 0; i < 6; i ++)
+ qemu_get_be32s(f, &s->clkpwr_regs[i]);
+ return 0;
+}
+
/* DMA controller */
#define S3C_DMA_CH_N 4
@@ -792,6 +877,43 @@
s3c_dma_write,
};
+static void s3c_dma_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_dma_state_s *s = (struct s3c_dma_state_s *) opaque;
+ int i;
+ for (i = 0; i < S3C_DMA_CH_N; i ++) {
+ qemu_put_be32(f, s->ch[i].curr_tc);
+ qemu_put_be32(f, s->ch[i].req);
+ qemu_put_be32s(f, &s->ch[i].con);
+ qemu_put_be32s(f, &s->ch[i].isrc);
+ qemu_put_be32s(f, &s->ch[i].isrcc);
+ qemu_put_be32s(f, &s->ch[i].idst);
+ qemu_put_be32s(f, &s->ch[i].idstc);
+ qemu_put_be32s(f, &s->ch[i].csrc);
+ qemu_put_be32s(f, &s->ch[i].cdst);
+ qemu_put_be32s(f, &s->ch[i].mask);
+ }
+}
+
+static int s3c_dma_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_dma_state_s *s = (struct s3c_dma_state_s *) opaque;
+ int i;
+ for (i = 0; i < S3C_DMA_CH_N; i ++) {
+ s->ch[i].curr_tc = qemu_get_be32(f);
+ s->ch[i].req = qemu_get_be32(f);
+ qemu_get_be32s(f, &s->ch[i].con);
+ qemu_get_be32s(f, &s->ch[i].isrc);
+ qemu_get_be32s(f, &s->ch[i].isrcc);
+ qemu_get_be32s(f, &s->ch[i].idst);
+ qemu_get_be32s(f, &s->ch[i].idstc);
+ qemu_get_be32s(f, &s->ch[i].csrc);
+ qemu_get_be32s(f, &s->ch[i].cdst);
+ qemu_get_be32s(f, &s->ch[i].mask);
+ }
+ return 0;
+}
+
struct s3c_dma_state_s *s3c_dma_init(target_phys_addr_t base, qemu_irq *pic)
{
int iomemtype;
@@ -811,6 +933,8 @@
s3c_dma_writefn, s);
cpu_register_physical_memory(s->base, 0xffffff, iomemtype);
+ register_savevm("s3c24xx_dma", 0, 0, s3c_dma_save, s3c_dma_load, s);
+
return s;
}
@@ -1047,6 +1171,52 @@
s3c_timers_write,
};
+static void s3c_timers_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_timers_state_s *s = (struct s3c_timers_state_s *) opaque;
+ int i;
+ for (i = 0; i < 5; i ++) {
+ qemu_put_be32(f, s->timer[i].running);
+ s3c_timers_stop(s, i);
+ qemu_put_be32s(f, &s->timer[i].divider);
+ qemu_put_be16s(f, &s->timer[i].count);
+ qemu_put_be64s(f, &s->timer[i].reload);
+ }
+
+ for (i = 0; i < 4; i ++)
+ qemu_put_be16s(f, &s->compareb[i]);
+ for (i = 0; i < 5; i ++)
+ qemu_put_be16s(f, &s->countb[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_put_be32s(f, &s->config[i]);
+ qemu_put_be32s(f, &s->control);
+}
+
+static int s3c_timers_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_timers_state_s *s = (struct s3c_timers_state_s *) opaque;
+ int i;
+ for (i = 0; i < 5; i ++) {
+ s->timer[i].running = qemu_get_be32(f);
+ qemu_get_be32s(f, &s->timer[i].divider);
+ qemu_get_be16s(f, &s->timer[i].count);
+ qemu_get_be64s(f, &s->timer[i].reload);
+ }
+
+ for (i = 0; i < 4; i ++)
+ qemu_get_be16s(f, &s->compareb[i]);
+ for (i = 0; i < 5; i ++)
+ qemu_get_be16s(f, &s->countb[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_get_be32s(f, &s->config[i]);
+ qemu_get_be32s(f, &s->control);
+
+ for (i = 0; i < 5; i ++)
+ s3c_timers_start(s, i);
+
+ return 0;
+}
+
struct s3c_timers_state_s *s3c_timers_init(target_phys_addr_t base,
qemu_irq *pic, qemu_irq *dma)
{
@@ -1072,6 +1242,9 @@
s3c_timers_writefn, s);
cpu_register_physical_memory(s->base, 0xffffff, iomemtype);
+ register_savevm("s3c24xx_timers", 0, 0,
+ s3c_timers_save, s3c_timers_load, s);
+
return s;
}
@@ -1367,6 +1540,38 @@
s3c_uart_write,
};
+static void s3c_uart_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_uart_state_s *s = (struct s3c_uart_state_s *) opaque;
+ qemu_put_8s(f, &s->data);
+ qemu_put_buffer(f, s->rxfifo, sizeof(s->rxfifo));
+ qemu_put_be32(f, s->rxstart);
+ qemu_put_be32(f, s->rxlen);
+ qemu_put_8s(f, &s->lcontrol);
+ qemu_put_8s(f, &s->fcontrol);
+ qemu_put_8s(f, &s->mcontrol);
+ qemu_put_be16s(f, &s->control);
+ qemu_put_be16s(f, &s->brdiv);
+ qemu_put_8s(f, &s->errstat);
+}
+
+static int s3c_uart_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_uart_state_s *s = (struct s3c_uart_state_s *) opaque;
+ qemu_get_8s(f, &s->data);
+ qemu_get_buffer(f, s->rxfifo, sizeof(s->rxfifo));
+ s->rxstart = qemu_get_be32(f);
+ s->rxlen = qemu_get_be32(f);
+ qemu_get_8s(f, &s->lcontrol);
+ qemu_get_8s(f, &s->fcontrol);
+ qemu_get_8s(f, &s->mcontrol);
+ qemu_get_be16s(f, &s->control);
+ qemu_get_be16s(f, &s->brdiv);
+ qemu_get_8s(f, &s->errstat);
+
+ return 0;
+}
+
struct s3c_uart_state_s *s3c_uart_init(target_phys_addr_t base,
qemu_irq *irqs, qemu_irq *dma)
{
@@ -1384,6 +1589,8 @@
s3c_uart_writefn, s);
cpu_register_physical_memory(s->base, 0xfff, iomemtype);
+ register_savevm("s3c24xx_uart", base, 0, s3c_uart_save, s3c_uart_load, s);
+
return s;
}
@@ -1430,7 +1637,7 @@
static void s3c_adc_start(struct s3c_adc_state_s *s)
{
- if (!s->enable && (s->ts & 7) == 0)
+ if (!s->enable || (s->ts & 7) == 0)
return;
s->control &= ~(1 << 15);
s->in_idx = (s->control >> 3) & 7;
@@ -1547,6 +1754,45 @@
s3c_adc_write,
};
+static void s3c_adc_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_adc_state_s *s = (struct s3c_adc_state_s *) opaque;
+ int i;
+ qemu_put_be32(f, s->enable);
+ for (i = 0; i < 8; i ++)
+ qemu_put_be32(f, s->input[i]);
+ qemu_put_be32(f, s->in_idx);
+ qemu_put_be32(f, s->noise);
+
+ qemu_put_be16s(f, &s->control);
+ qemu_put_be16s(f, &s->ts);
+ qemu_put_be16s(f, &s->delay);
+ qemu_put_be16s(f, &s->xdata);
+ qemu_put_be16s(f, &s->ydata);
+}
+
+static int s3c_adc_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_adc_state_s *s = (struct s3c_adc_state_s *) opaque;
+ int i;
+ s->enable = qemu_get_be32(f);
+ for (i = 0; i < 8; i ++)
+ s->input[i] = qemu_get_be32(f);
+ s->in_idx = qemu_get_be32(f);
+ s->noise = qemu_get_be32(f);
+
+ qemu_get_be16s(f, &s->control);
+ qemu_get_be16s(f, &s->ts);
+ qemu_get_be16s(f, &s->delay);
+ qemu_get_be16s(f, &s->xdata);
+ qemu_get_be16s(f, &s->ydata);
+
+ if (s->enable && (s->ts & 7) && !(s->control & (1 << 15)))
+ s3c_adc_start(s);
+
+ return 0;
+}
+
struct s3c_adc_state_s *s3c_adc_init(target_phys_addr_t base, qemu_irq irq,
qemu_irq tcirq)
{
@@ -1570,6 +1816,8 @@
qemu_add_mouse_event_handler(s3c_adc_event, s, 1,
"QEMU S3C2410-driven Touchscreen");
+ register_savevm("s3c24xx_adc", 0, 0, s3c_adc_save, s3c_adc_load, s);
+
return s;
}
@@ -1769,6 +2017,37 @@
s3c_i2c_write,
};
+static void s3c_i2c_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_i2c_state_s *s = (struct s3c_i2c_state_s *) opaque;
+ qemu_put_8s(f, &s->control);
+ qemu_put_8s(f, &s->status);
+ qemu_put_8s(f, &s->data);
+ qemu_put_8s(f, &s->addy);
+
+ qemu_put_be32(f, s->busy);
+ qemu_put_be32(f, s->newstart);
+
+ i2c_bus_save(f, s->bus);
+ i2c_slave_save(f, &s->slave);
+}
+
+static int s3c_i2c_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_i2c_state_s *s = (struct s3c_i2c_state_s *) opaque;
+ qemu_get_8s(f, &s->control);
+ qemu_get_8s(f, &s->status);
+ qemu_get_8s(f, &s->data);
+ qemu_get_8s(f, &s->addy);
+
+ s->busy = qemu_get_be32(f);
+ s->newstart = qemu_get_be32(f);
+
+ i2c_bus_load(f, s->bus);
+ i2c_slave_load(f, &s->slave);
+ return 0;
+}
+
struct s3c_i2c_state_s *s3c_i2c_init(target_phys_addr_t base, qemu_irq irq)
{
int iomemtype;
@@ -1788,6 +2067,8 @@
s3c_i2c_writefn, s);
cpu_register_physical_memory(s->base, 0xffffff, iomemtype);
+ register_savevm("s3c24xx_i2c", 0, 0, s3c_i2c_save, s3c_i2c_load, s);
+
return s;
}
@@ -1950,6 +2231,44 @@
s3c_spi_write,
};
+static void s3c_spi_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_spi_state_s *s = (struct s3c_spi_state_s *) opaque;
+ int i;
+ for (i = 0; i < 2; i ++) {
+ qemu_put_8s(f, &s->chan[i].control);
+ qemu_put_8s(f, &s->chan[i].pin);
+ qemu_put_8s(f, &s->chan[i].pre);
+
+ qemu_put_8s(f, &s->chan[i].txbuf);
+ qemu_put_8s(f, &s->chan[i].rxbuf);
+ qemu_put_be32(f, s->chan[i].cs_pin);
+ qemu_put_be32(f, s->chan[i].clk_pin);
+ qemu_put_be32(f, s->chan[i].mosi_pin);
+ qemu_put_be32(f, s->chan[i].bit);
+ }
+}
+
+static int s3c_spi_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_spi_state_s *s = (struct s3c_spi_state_s *) opaque;
+ int i;
+ for (i = 0; i < 2; i ++) {
+ qemu_get_8s(f, &s->chan[i].control);
+ qemu_get_8s(f, &s->chan[i].pin);
+ qemu_get_8s(f, &s->chan[i].pre);
+
+ qemu_get_8s(f, &s->chan[i].txbuf);
+ qemu_get_8s(f, &s->chan[i].rxbuf);
+ s->chan[i].cs_pin = qemu_get_be32(f);
+ s->chan[i].clk_pin = qemu_get_be32(f);
+ s->chan[i].mosi_pin = qemu_get_be32(f);
+ s->chan[i].bit = qemu_get_be32(f);
+ }
+
+ return 0;
+}
+
static void s3c_spi_bitbang_cs(void *opaque, int line, int level)
{
struct s3c_spi_state_s *s = (struct s3c_spi_state_s *) opaque;
@@ -2051,6 +2370,8 @@
s3c_spi_bitbang_init(s, gpio);
+ register_savevm("s3c24xx_spi", 0, 0, s3c_spi_save, s3c_spi_load, s);
+
return s;
}
@@ -2192,6 +2513,40 @@
s3c_i2s_write,
};
+static void s3c_i2s_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_i2s_state_s *s = (struct s3c_i2s_state_s *) opaque;
+ qemu_put_be16s(f, &s->control);
+ qemu_put_be16s(f, &s->mode);
+ qemu_put_be16s(f, &s->prescaler);
+ qemu_put_be16s(f, &s->fcontrol);
+
+ qemu_put_be32(f, s->tx_en);
+ qemu_put_be32(f, s->rx_en);
+ qemu_put_be32(f, s->tx_len);
+ qemu_put_be32(f, s->rx_len);
+ qemu_put_be16(f, s->buffer);
+ qemu_put_be32(f, s->cycle);
+}
+
+static int s3c_i2s_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_i2s_state_s *s = (struct s3c_i2s_state_s *) opaque;
+ qemu_get_be16s(f, &s->control);
+ qemu_get_be16s(f, &s->mode);
+ qemu_get_be16s(f, &s->prescaler);
+ qemu_get_be16s(f, &s->fcontrol);
+
+ s->tx_en = qemu_get_be32(f);
+ s->rx_en = qemu_get_be32(f);
+ s->tx_len = qemu_get_be32(f);
+ s->rx_len = qemu_get_be32(f);
+ s->buffer = qemu_get_be16(f);
+ s->cycle = qemu_get_be32(f);
+
+ return 0;
+}
+
static void s3c_i2s_data_req(void *opaque, int tx, int rx)
{
struct s3c_i2s_state_s *s = (struct s3c_i2s_state_s *) opaque;
@@ -2216,6 +2571,8 @@
s3c_i2s_writefn, s);
cpu_register_physical_memory(s->base, 0xffffff, iomemtype);
+ register_savevm("s3c24xx_iis", 0, 0, s3c_i2s_save, s3c_i2s_load, s);
+
return s;
}
@@ -2336,6 +2693,30 @@
s3c_wdt_write,
};
+static void s3c_wdt_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_wdt_state_s *s = (struct s3c_wdt_state_s *) opaque;
+
+ s3c_wdt_stop(s);
+ qemu_put_be16s(f, &s->control);
+ qemu_put_be16s(f, &s->data);
+ qemu_put_be16s(f, &s->count);
+ qemu_put_be64s(f, &s->timestamp);
+}
+
+static int s3c_wdt_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_wdt_state_s *s = (struct s3c_wdt_state_s *) opaque;
+
+ qemu_get_be16s(f, &s->control);
+ qemu_get_be16s(f, &s->data);
+ qemu_get_be16s(f, &s->count);
+ qemu_get_be64s(f, &s->timestamp);
+ s3c_wdt_start(s);
+
+ return 0;
+}
+
struct s3c_wdt_state_s *s3c_wdt_init(target_phys_addr_t base, qemu_irq irq)
{
int iomemtype;
@@ -2352,6 +2733,8 @@
s3c_wdt_writefn, s);
cpu_register_physical_memory(s->base, 0xffffff, iomemtype);
+ register_savevm("s3c24xx_wdt", 0, 0, s3c_wdt_save, s3c_wdt_load, s);
+
return s;
}
@@ -2414,6 +2797,7 @@
s->env = cpu_init();
cpu_arm_set_model(s->env, "arm920t");
+ register_savevm("cpu", 0, 0, cpu_save, cpu_load, s->env);
cpu_register_physical_memory(S3C_RAM_BASE, sdram_size,
qemu_ram_alloc(sdram_size) | IO_MEM_RAM);
@@ -2426,6 +2810,7 @@
s3c_mc_reset(s);
iomemtype = cpu_register_io_memory(0, s3c_mc_readfn, s3c_mc_writefn, s);
cpu_register_physical_memory(s->mc_base, 0xffffff, iomemtype);
+ register_savevm("s3c24xx_mc", 0, 0, s3c_mc_save, s3c_mc_load, s);
s->pic = s3c_pic_init(0x4a000000, arm_pic_init_cpu(s->env));
s->irq = s3c_pic_get(s->pic);
@@ -2438,6 +2823,8 @@
iomemtype = cpu_register_io_memory(0, s3c_clkpwr_readfn,
s3c_clkpwr_writefn, s);
cpu_register_physical_memory(s->clkpwr_base, 0xffffff, iomemtype);
+ register_savevm("s3c24xx_clkpwr", 0, 0,
+ s3c_clkpwr_save, s3c_clkpwr_load, s);
s->lcd = s3c_lcd_init(0x4d000000, ds, s->irq[S3C_PIC_LCD]);
@@ -2446,6 +2833,7 @@
iomemtype = cpu_register_io_memory(0, s3c_nand_readfn,
s3c_nand_writefn, s);
cpu_register_physical_memory(s->nand_base, 0xffffff, iomemtype);
+ register_savevm("s3c24xx_nand", 0, 0, s3c_nand_save, s3c_nand_load, s);
for (i = 0; s3c2410_uart[i].base; i ++) {
s->uart[i] = s3c_uart_init(s3c2410_uart[i].base,
Modified: trunk/src/host/qemu-neo1973/hw/s3c24xx_gpio.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/s3c24xx_gpio.c 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/hw/s3c24xx_gpio.c 2007-05-21 23:47:12 UTC (rev 2052)
@@ -313,6 +313,58 @@
s3c_gpio_write,
};
+static void s3c_gpio_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_gpio_state_s *s = (struct s3c_gpio_state_s *) opaque;
+ int i;
+ for (i = 0; i < S3C_IO_BANKS; i ++) {
+ qemu_put_be32s(f, &s->bank[i].con);
+ qemu_put_be32s(f, &s->bank[i].dat);
+ qemu_put_be32s(f, &s->bank[i].up);
+ qemu_put_be32s(f, &s->bank[i].mask);
+ }
+
+ qemu_put_be32s(f, &s->inform[0]);
+ qemu_put_be32s(f, &s->inform[1]);
+ qemu_put_be32s(f, &s->pwrstat);
+ qemu_put_be32s(f, &s->misccr);
+ qemu_put_be32s(f, &s->dclkcon);
+ qemu_put_be32s(f, &s->extint[0]);
+ qemu_put_be32s(f, &s->extint[1]);
+ qemu_put_be32s(f, &s->extint[2]);
+ qemu_put_be32s(f, &s->eintflt[0]);
+ qemu_put_be32s(f, &s->eintflt[1]);
+ qemu_put_be32s(f, &s->eintmask);
+ qemu_put_be32s(f, &s->eintpend);
+}
+
+static int s3c_gpio_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_gpio_state_s *s = (struct s3c_gpio_state_s *) opaque;
+ int i;
+ for (i = 0; i < S3C_IO_BANKS; i ++) {
+ qemu_get_be32s(f, &s->bank[i].con);
+ qemu_get_be32s(f, &s->bank[i].dat);
+ qemu_get_be32s(f, &s->bank[i].up);
+ qemu_get_be32s(f, &s->bank[i].mask);
+ }
+
+ qemu_get_be32s(f, &s->inform[0]);
+ qemu_get_be32s(f, &s->inform[1]);
+ qemu_get_be32s(f, &s->pwrstat);
+ qemu_get_be32s(f, &s->misccr);
+ qemu_get_be32s(f, &s->dclkcon);
+ qemu_get_be32s(f, &s->extint[0]);
+ qemu_get_be32s(f, &s->extint[1]);
+ qemu_get_be32s(f, &s->extint[2]);
+ qemu_get_be32s(f, &s->eintflt[0]);
+ qemu_get_be32s(f, &s->eintflt[1]);
+ qemu_get_be32s(f, &s->eintmask);
+ qemu_get_be32s(f, &s->eintpend);
+
+ return 0;
+}
+
struct s3c_gpio_state_s *s3c_gpio_init(target_phys_addr_t base, qemu_irq *pic)
{
int iomemtype;
@@ -338,5 +390,7 @@
s3c_gpio_writefn, s);
cpu_register_physical_memory(s->base, 0xffffff, iomemtype);
+ register_savevm("s3c24xx_io", 0, 0, s3c_gpio_save, s3c_gpio_load, s);
+
return s;
}
Modified: trunk/src/host/qemu-neo1973/hw/s3c24xx_lcd.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/s3c24xx_lcd.c 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/hw/s3c24xx_lcd.c 2007-05-21 23:47:12 UTC (rev 2052)
@@ -471,6 +471,61 @@
#define BITS 32
#include "s3c24xx_template.h"
+static void s3c_lcd_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_lcd_state_s *s = (struct s3c_lcd_state_s *) opaque;
+ int i;
+ for (i = 0; i < 5; i ++)
+ qemu_put_be32s(f, &s->con[i]);
+ for (i = 0; i < 3; i ++)
+ qemu_put_be32s(f, &s->saddr[i]);
+ qemu_put_be32s(f, &s->r);
+ qemu_put_be32s(f, &s->g);
+ qemu_put_be16s(f, &s->b);
+ qemu_put_be32s(f, &s->dithmode);
+ qemu_put_be32s(f, &s->tpal);
+ qemu_put_8s(f, &s->intpnd);
+ qemu_put_8s(f, &s->srcpnd);
+ qemu_put_8s(f, &s->intmsk);
+ qemu_put_8s(f, &s->lpcsel);
+ for (i = 0; i < 0x100; i ++)
+ qemu_put_be16s(f, &s->raw_pal[i]);
+}
+
+static int s3c_lcd_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_lcd_state_s *s = (struct s3c_lcd_state_s *) opaque;
+ int i;
+ for (i = 0; i < 5; i ++)
+ qemu_get_be32s(f, &s->con[i]);
+ for (i = 0; i < 3; i ++)
+ qemu_get_be32s(f, &s->saddr[i]);
+ qemu_get_be32s(f, &s->r);
+ qemu_get_be32s(f, &s->g);
+ qemu_get_be16s(f, &s->b);
+ qemu_get_be32s(f, &s->dithmode);
+ qemu_get_be32s(f, &s->tpal);
+ qemu_get_8s(f, &s->intpnd);
+ qemu_get_8s(f, &s->srcpnd);
+ qemu_get_8s(f, &s->intmsk);
+ qemu_get_8s(f, &s->lpcsel);
+
+ s->invalidate = 1;
+ s->invalidatep = 1;
+ s->width = -1;
+ s->height = -1;
+ s->bpp = (s->con[0] >> 1) & 0xf;
+ s->enable = s->con[0] & 1;
+ s->msb = (s->con[4] >> 12) & 1;
+ s->frm565 = (s->con[4] >> 11) & 1;
+ s->fb = phys_ram_base + (((s->saddr[0] << 1) & 0x7ffffffe) - S3C_RAM_BASE);
+
+ for (i = 0; i < 0x100; i ++)
+ qemu_get_be16s(f, &s->raw_pal[i]);
+
+ return 0;
+}
+
struct s3c_lcd_state_s *s3c_lcd_init(target_phys_addr_t base, DisplayState *ds,
qemu_irq irq)
{
@@ -491,6 +546,8 @@
s3c_lcd_writefn, s);
cpu_register_physical_memory(s->base, 0xffffff, iomemtype);
+ register_savevm("s3c24xx_lcd", 0, 0, s3c_lcd_save, s3c_lcd_load, s);
+
switch (s->ds->depth) {
case 0:
s->dest_width = 0;
Modified: trunk/src/host/qemu-neo1973/hw/s3c24xx_mmci.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/s3c24xx_mmci.c 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/hw/s3c24xx_mmci.c 2007-05-21 23:47:12 UTC (rev 2052)
@@ -355,6 +355,62 @@
s3c_mmci_write,
};
+static void s3c_mmci_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_mmci_state_s *s = (struct s3c_mmci_state_s *) opaque;
+ qemu_put_be32(f, s->blklen);
+ qemu_put_be32(f, s->blknum);
+ qemu_put_be32(f, s->blklen_cnt);
+ qemu_put_be32(f, s->blknum_cnt);
+ qemu_put_buffer(f, s->fifo, sizeof(s->fifo));
+ qemu_put_be32(f, s->fifolen);
+ qemu_put_be32(f, s->fifostart);
+ qemu_put_be32(f, s->data);
+
+ qemu_put_be32s(f, &s->control);
+ qemu_put_be32s(f, &s->arg);
+ qemu_put_be32s(f, &s->ccontrol);
+ qemu_put_be32s(f, &s->cstatus);
+ qemu_put_be32s(f, &s->dcontrol);
+ qemu_put_be32s(f, &s->dstatus);
+ qemu_put_be32s(f, &s->resp[0]);
+ qemu_put_be32s(f, &s->resp[1]);
+ qemu_put_be32s(f, &s->resp[2]);
+ qemu_put_be32s(f, &s->resp[3]);
+ qemu_put_be16s(f, &s->dtimer);
+ qemu_put_be32s(f, &s->mask);
+ qemu_put_8s(f, &s->prescaler);
+}
+
+static int s3c_mmci_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_mmci_state_s *s = (struct s3c_mmci_state_s *) opaque;
+ s->blklen = qemu_get_be32(f);
+ s->blknum = qemu_get_be32(f);
+ s->blklen_cnt = qemu_get_be32(f);
+ s->blknum_cnt = qemu_get_be32(f);
+ qemu_get_buffer(f, s->fifo, sizeof(s->fifo));
+ s->fifolen = qemu_get_be32(f);
+ s->fifostart = qemu_get_be32(f);
+ s->data = qemu_get_be32(f);
+
+ qemu_get_be32s(f, &s->control);
+ qemu_get_be32s(f, &s->arg);
+ qemu_get_be32s(f, &s->ccontrol);
+ qemu_get_be32s(f, &s->cstatus);
+ qemu_get_be32s(f, &s->dcontrol);
+ qemu_get_be32s(f, &s->dstatus);
+ qemu_get_be32s(f, &s->resp[0]);
+ qemu_get_be32s(f, &s->resp[1]);
+ qemu_get_be32s(f, &s->resp[2]);
+ qemu_get_be32s(f, &s->resp[3]);
+ qemu_get_be16s(f, &s->dtimer);
+ qemu_get_be32s(f, &s->mask);
+ qemu_get_8s(f, &s->prescaler);
+
+ return 0;
+}
+
struct s3c_mmci_state_s *s3c_mmci_init(target_phys_addr_t base,
qemu_irq irq, qemu_irq *dma)
{
@@ -372,6 +428,8 @@
s3c_mmci_writefn, s);
cpu_register_physical_memory(s->base, 0xffffff, iomemtype);
+ register_savevm("s3c24xx_mmci", 0, 0, s3c_mmci_save, s3c_mmci_load, s);
+
/* Instantiate the actual storage */
s->card = sd_init(sd_bdrv);
Modified: trunk/src/host/qemu-neo1973/hw/s3c24xx_rtc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/s3c24xx_rtc.c 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/hw/s3c24xx_rtc.c 2007-05-21 23:47:12 UTC (rev 2052)
@@ -268,6 +268,46 @@
s3c_rtc_write,
};
+static void s3c_rtc_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_rtc_state_s *s = (struct s3c_rtc_state_s *) opaque;
+ qemu_put_be64s(f, &s->next);
+ qemu_put_8s(f, &s->control);
+ qemu_put_8s(f, &s->tick);
+ qemu_put_8s(f, &s->alarm);
+ qemu_put_8s(f, &s->almsec);
+ qemu_put_8s(f, &s->almmin);
+ qemu_put_8s(f, &s->almday);
+ qemu_put_8s(f, &s->almhour);
+ qemu_put_8s(f, &s->almmon);
+ qemu_put_8s(f, &s->almyear);
+ qemu_put_8s(f, &s->reset);
+ qemu_put_be32s(f, &s->sec);
+}
+
+static int s3c_rtc_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_rtc_state_s *s = (struct s3c_rtc_state_s *) opaque;
+ qemu_get_be64s(f, &s->next);
+ qemu_get_8s(f, &s->control);
+ qemu_get_8s(f, &s->tick);
+ qemu_get_8s(f, &s->alarm);
+ qemu_get_8s(f, &s->almsec);
+ qemu_get_8s(f, &s->almmin);
+ qemu_get_8s(f, &s->almday);
+ qemu_get_8s(f, &s->almhour);
+ qemu_get_8s(f, &s->almmon);
+ qemu_get_8s(f, &s->almyear);
+ qemu_get_8s(f, &s->reset);
+ qemu_get_be32s(f, &s->sec);
+
+ s->enable = (s->control == 0x1);
+ if (s->tick & (1 << 7))
+ s3c_rtc_tick_mod(s);
+
+ return 0;
+}
+
struct s3c_rtc_state_s *s3c_rtc_init(target_phys_addr_t base, qemu_irq irq)
{
int iomemtype;
@@ -287,5 +327,7 @@
s3c_rtc_writefn, s);
cpu_register_physical_memory(s->base, 0xffffff, iomemtype);
+ register_savevm("s3c24xx_rtc", 0, 0, s3c_rtc_save, s3c_rtc_load, s);
+
return s;
}
Modified: trunk/src/host/qemu-neo1973/hw/s3c24xx_udc.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/s3c24xx_udc.c 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/hw/s3c24xx_udc.c 2007-05-21 23:47:12 UTC (rev 2052)
@@ -523,6 +523,67 @@
s3c_udc_write,
};
+static void s3c_udc_save(QEMUFile *f, void *opaque)
+{
+ struct s3c_udc_state_s *s = (struct s3c_udc_state_s *) opaque;
+ int i;
+ qemu_put_8s(f, &s->ep0.csr);
+ qemu_put_8s(f, &s->ep0.maxpacket);
+
+ for (i = 0; i < S3C_EPS - 1; i ++) {
+ qemu_put_8s(f, &s->ep1[i].in_csr[0]);
+ qemu_put_8s(f, &s->ep1[i].in_csr[1]);
+ qemu_put_8s(f, &s->ep1[i].out_csr[0]);
+ qemu_put_8s(f, &s->ep1[i].out_csr[1]);
+ qemu_put_8s(f, &s->ep1[i].maxpacket);
+ qemu_put_8s(f, &s->ep1[i].control);
+ qemu_put_8s(f, &s->ep1[i].unit_cnt);
+ qemu_put_8s(f, &s->ep1[i].fifo_cnt);
+ qemu_put_be32s(f, &s->ep1[i].dma_size);
+ }
+
+ qemu_put_8s(f, &s->index);
+ qemu_put_8s(f, &s->power);
+ qemu_put_8s(f, &s->ep_intr);
+ qemu_put_8s(f, &s->ep_mask);
+ qemu_put_8s(f, &s->usb_intr);
+ qemu_put_8s(f, &s->usb_mask);
+ qemu_put_be16s(f, &s->frame);
+ qemu_put_8s(f, &s->address);
+}
+
+static int s3c_udc_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct s3c_udc_state_s *s = (struct s3c_udc_state_s *) opaque;
+ int i;
+ /* TODO: Make it look more like a disconnect */
+ qemu_put_8s(f, &s->ep0.csr);
+ qemu_put_8s(f, &s->ep0.maxpacket);
+
+ for (i = 0; i < S3C_EPS - 1; i ++) {
+ qemu_put_8s(f, &s->ep1[i].in_csr[0]);
+ qemu_put_8s(f, &s->ep1[i].in_csr[1]);
+ qemu_put_8s(f, &s->ep1[i].out_csr[0]);
+ qemu_put_8s(f, &s->ep1[i].out_csr[1]);
+ qemu_put_8s(f, &s->ep1[i].maxpacket);
+ qemu_put_8s(f, &s->ep1[i].control);
+ qemu_put_8s(f, &s->ep1[i].unit_cnt);
+ qemu_put_8s(f, &s->ep1[i].fifo_cnt);
+ qemu_put_be32s(f, &s->ep1[i].dma_size);
+ }
+
+ qemu_put_8s(f, &s->index);
+ qemu_put_8s(f, &s->power);
+ qemu_put_8s(f, &s->ep_intr);
+ qemu_put_8s(f, &s->ep_mask);
+ qemu_put_8s(f, &s->usb_intr);
+ qemu_put_8s(f, &s->usb_mask);
+ qemu_put_be16s(f, &s->frame);
+ qemu_put_8s(f, &s->address);
+
+ return 0;
+}
+
static int s3c_udc_handle_packet(USBDevice *dev, USBPacket *p)
{
struct s3c_udc_state_s *s = (struct s3c_udc_state_s *) dev->opaque;
@@ -690,6 +751,8 @@
s3c_udc_writefn, s);
cpu_register_physical_memory(s->base, 0xffffff, iomemtype);
+ register_savevm("s3c24xx_udc", 0, 0, s3c_udc_save, s3c_udc_load, s);
+
qemu_register_usb_gadget(&s->dev);
return s;
Modified: trunk/src/host/qemu-neo1973/hw/wm8750.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/wm8750.c 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/hw/wm8750.c 2007-05-21 23:47:12 UTC (rev 2052)
@@ -491,6 +491,93 @@
return 0x00;
}
+static void wm8750_save(QEMUFile *f, void *opaque)
+{
+ struct wm8750_s *s = (struct wm8750_s *) opaque;
+ int i;
+ qemu_put_8s(f, &s->i2c_data[0]);
+ qemu_put_8s(f, &s->i2c_data[1]);
+ qemu_put_be32(f, s->i2c_len);
+ qemu_put_be32(f, s->enable);
+ qemu_put_be32(f, s->idx_in);
+ qemu_put_be32(f, s->req_in);
+ qemu_put_be32(f, s->idx_out);
+ qemu_put_be32(f, s->req_out);
+
+ for (i = 0; i < 7; i ++)
+ qemu_put_8s(f, &s->outvol[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_put_8s(f, &s->outmute[i]);
+ for (i = 0; i < 4; i ++)
+ qemu_put_8s(f, &s->invol[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_put_8s(f, &s->inmute[i]);
+
+ for (i = 0; i < 2; i ++)
+ qemu_put_8s(f, &s->diff[i]);
+ qemu_put_8s(f, &s->pol);
+ qemu_put_8s(f, &s->ds);
+ for (i = 0; i < 2; i ++)
+ qemu_put_8s(f, &s->monomix[i]);
+ qemu_put_8s(f, &s->alc);
+ qemu_put_8s(f, &s->mute);
+ for (i = 0; i < 4; i ++)
+ qemu_put_8s(f, &s->path[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_put_8s(f, &s->mpath[i]);
+ qemu_put_8s(f, &s->format);
+ qemu_put_8s(f, &s->power);
+ qemu_put_be32s(f, &s->inmask);
+ qemu_put_be32s(f, &s->outmask);
+ qemu_put_byte(f, (s->rate - wm_rate_table) / sizeof(*s->rate));
+ i2c_slave_save(f, &s->i2c);
+}
+
+static int wm8750_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct wm8750_s *s = (struct wm8750_s *) opaque;
+ int i;
+ qemu_get_8s(f, &s->i2c_data[0]);
+ qemu_get_8s(f, &s->i2c_data[1]);
+ s->i2c_len = qemu_get_be32(f);
+ s->enable = qemu_get_be32(f);
+ s->idx_in = qemu_get_be32(f);
+ s->req_in = qemu_get_be32(f);
+ s->idx_out = qemu_get_be32(f);
+ s->req_out = qemu_get_be32(f);
+
+ for (i = 0; i < 7; i ++)
+ qemu_get_8s(f, &s->outvol[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_get_8s(f, &s->outmute[i]);
+ for (i = 0; i < 4; i ++)
+ qemu_get_8s(f, &s->invol[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_get_8s(f, &s->inmute[i]);
+
+ for (i = 0; i < 2; i ++)
+ qemu_get_8s(f, &s->diff[i]);
+ qemu_get_8s(f, &s->pol);
+ qemu_get_8s(f, &s->ds);
+ for (i = 0; i < 2; i ++)
+ qemu_get_8s(f, &s->monomix[i]);
+ qemu_get_8s(f, &s->alc);
+ qemu_get_8s(f, &s->mute);
+ for (i = 0; i < 4; i ++)
+ qemu_get_8s(f, &s->path[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_get_8s(f, &s->mpath[i]);
+ qemu_get_8s(f, &s->format);
+ qemu_get_8s(f, &s->power);
+ qemu_get_be32s(f, &s->inmask);
+ qemu_get_be32s(f, &s->outmask);
+ s->rate = &wm_rate_table[(uint8_t) qemu_get_byte(f) & 0x1f];
+ i2c_slave_load(f, &s->i2c);
+ return 0;
+}
+
+static int wm8750_iid = 0;
+
i2c_slave *wm8750_init(i2c_bus *bus, AudioState *audio)
{
struct wm8750_s *s = (struct wm8750_s *)
@@ -501,6 +588,9 @@
AUD_register_card(audio, CODEC, &s->card);
wm8750_reset(&s->i2c);
+
+ register_savevm(CODEC, wm8750_iid ++, 0, wm8750_save, wm8750_load, s);
+
return &s->i2c;
}
Modified: trunk/src/host/qemu-neo1973/hw/wm8753.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/wm8753.c 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/hw/wm8753.c 2007-05-21 23:47:12 UTC (rev 2052)
@@ -715,6 +715,115 @@
wm8753_int_update(s);
}
+static void wm8753_save(QEMUFile *f, void *opaque)
+{
+ struct wm8753_s *s = (struct wm8753_s *) opaque;
+ int i;
+ qemu_put_8s(f, &s->i2c_data[0]);
+ qemu_put_8s(f, &s->i2c_data[1]);
+ qemu_put_be32(f, s->i2c_len);
+ qemu_put_be32(f, s->enable);
+ qemu_put_be32(f, s->idx_in);
+ qemu_put_be32(f, s->req_in);
+ qemu_put_be32(f, s->idx_out);
+ qemu_put_be32(f, s->req_out);
+
+ for (i = 0; i < 7; i ++)
+ qemu_put_8s(f, &s->outvol[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_put_8s(f, &s->outmute[i]);
+ for (i = 0; i < 4; i ++)
+ qemu_put_8s(f, &s->invol[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_put_8s(f, &s->inmute[i]);
+ qemu_put_8s(f, &s->adcin);
+ for (i = 0; i < 2; i ++)
+ qemu_put_8s(f, &s->inctl[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_put_8s(f, &s->recmix[i]);
+ qemu_put_8s(f, &s->adc);
+ qemu_put_8s(f, &s->intpol);
+ qemu_put_8s(f, &s->intmask);
+ qemu_put_8s(f, &s->intlevel);
+ qemu_put_8s(f, &s->inten);
+ qemu_put_8s(f, &s->intinput);
+ qemu_put_8s(f, &s->inthigh);
+ qemu_put_8s(f, &s->intintr);
+ qemu_put_8s(f, &s->intprev);
+ for (i = 0; i < 8; i ++)
+ qemu_put_byte(f, s->line[i].type);
+ qemu_put_8s(f, &s->response);
+ qemu_put_be32s(f, &s->inmask);
+ qemu_put_be32s(f, &s->outmask);
+ qemu_put_byte(f, (s->rate - wm_rate_table) / sizeof(*s->rate));
+ for (i = 0; i < 4; i ++)
+ qemu_put_8s(f, &s->path[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_put_8s(f, &s->mpath[i]);
+ qemu_put_8s(f, &s->format);
+ qemu_put_8s(f, &s->alc);
+ qemu_put_8s(f, &s->mute);
+ for (i = 0; i < 4; i ++)
+ qemu_put_be16s(f, &s->power[i]);
+ i2c_slave_save(f, &s->i2c);
+}
+
+static int wm8753_load(QEMUFile *f, void *opaque, int version_id)
+{
+ struct wm8753_s *s = (struct wm8753_s *) opaque;
+ int i;
+ qemu_get_8s(f, &s->i2c_data[0]);
+ qemu_get_8s(f, &s->i2c_data[1]);
+ s->i2c_len = qemu_get_be32(f);
+ s->enable = qemu_get_be32(f);
+ s->idx_in = qemu_get_be32(f);
+ s->req_in = qemu_get_be32(f);
+ s->idx_out = qemu_get_be32(f);
+ s->req_out = qemu_get_be32(f);
+
+ for (i = 0; i < 7; i ++)
+ qemu_get_8s(f, &s->outvol[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_get_8s(f, &s->outmute[i]);
+ for (i = 0; i < 4; i ++)
+ qemu_get_8s(f, &s->invol[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_get_8s(f, &s->inmute[i]);
+ qemu_get_8s(f, &s->adcin);
+ for (i = 0; i < 2; i ++)
+ qemu_get_8s(f, &s->inctl[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_get_8s(f, &s->recmix[i]);
+ qemu_get_8s(f, &s->adc);
+ qemu_get_8s(f, &s->intpol);
+ qemu_get_8s(f, &s->intmask);
+ qemu_get_8s(f, &s->intlevel);
+ qemu_get_8s(f, &s->inten);
+ qemu_get_8s(f, &s->intinput);
+ qemu_get_8s(f, &s->inthigh);
+ qemu_get_8s(f, &s->intintr);
+ qemu_get_8s(f, &s->intprev);
+ for (i = 0; i < 8; i ++)
+ s->line[i].type = qemu_get_byte(f);
+ qemu_get_8s(f, &s->response);
+ qemu_get_be32s(f, &s->inmask);
+ qemu_get_be32s(f, &s->outmask);
+ s->rate = &wm_rate_table[(uint8_t) qemu_get_byte(f) & 0x1f];
+ for (i = 0; i < 4; i ++)
+ qemu_get_8s(f, &s->path[i]);
+ for (i = 0; i < 2; i ++)
+ qemu_get_8s(f, &s->mpath[i]);
+ qemu_get_8s(f, &s->format);
+ qemu_get_8s(f, &s->alc);
+ qemu_get_8s(f, &s->mute);
+ for (i = 0; i < 4; i ++)
+ qemu_get_be16s(f, &s->power[i]);
+ i2c_slave_load(f, &s->i2c);
+ return 0;
+}
+
+static int wm8753_iid = 0;
+
i2c_slave *wm8753_init(i2c_bus *bus, AudioState *audio)
{
struct wm8753_s *s = (struct wm8753_s *)
@@ -726,6 +835,9 @@
AUD_register_card(audio, CODEC, &s->card);
wm8753_reset(&s->i2c);
+
+ register_savevm(CODEC, wm8753_iid ++, 0, wm8753_save, wm8753_load, s);
+
return &s->i2c;
}
Modified: trunk/src/host/qemu-neo1973/vl.c
===================================================================
--- trunk/src/host/qemu-neo1973/vl.c 2007-05-21 23:27:58 UTC (rev 2051)
+++ trunk/src/host/qemu-neo1973/vl.c 2007-05-21 23:47:12 UTC (rev 2052)
@@ -1361,6 +1361,8 @@
for (i = 0; i < MAX_DISKS; i++) {
if (bs_table[i])
bdrv_commit(bs_table[i]);
+ if (mtd_bdrv)
+ bdrv_commit(mtd_bdrv);
}
}
break;
@@ -5283,6 +5285,9 @@
if (bdrv_can_snapshot(bs))
goto ok;
}
+ bs = mtd_bdrv;
+ if (bdrv_can_snapshot(bs))
+ goto ok;
return NULL;
ok:
bs_snapshots = bs;
@@ -5313,9 +5318,9 @@
void do_savevm(const char *name)
{
- BlockDriverState *bs, *bs1;
+ BlockDriverState *bs;
QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
- int must_delete, ret, i;
+ int must_delete, ret;
BlockDriverInfo bdi1, *bdi = &bdi1;
QEMUFile *f;
int saved_vm_running;
@@ -5387,22 +5392,19 @@
/* create the snapshots */
- for(i = 0; i < MAX_DISKS; i++) {
- bs1 = bs_table[i];
- if (bdrv_has_snapshot(bs1)) {
- if (must_delete) {
- ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
- if (ret < 0) {
- term_printf("Error while deleting snapshot on '%s'\n",
- bdrv_get_device_name(bs1));
- }
- }
- ret = bdrv_snapshot_create(bs1, sn);
+ if (bdrv_has_snapshot(bs)) {
+ if (must_delete) {
+ ret = bdrv_snapshot_delete(bs, old_sn->id_str);
if (ret < 0) {
- term_printf("Error while creating snapshot on '%s'\n",
- bdrv_get_device_name(bs1));
+ term_printf("Error while deleting snapshot on '%s'\n",
+ bdrv_get_device_name(bs));
}
}
+ ret = bdrv_snapshot_create(bs, sn);
+ if (ret < 0) {
+ term_printf("Error while creating snapshot on '%s'\n",
+ bdrv_get_device_name(bs));
+ }
}
the_end:
@@ -5412,10 +5414,10 @@
void do_loadvm(const char *name)
{
- BlockDriverState *bs, *bs1;
+ BlockDriverState *bs;
BlockDriverInfo bdi1, *bdi = &bdi1;
QEMUFile *f;
- int i, ret;
+ int ret;
int saved_vm_running;
bs = get_bs_snapshots();
@@ -5430,31 +5432,25 @@
saved_vm_running = vm_running;
vm_stop(0);
- for(i = 0; i <= MAX_DISKS; i++) {
- bs1 = bs_table[i];
- if (bdrv_has_snapshot(bs1)) {
- ret = bdrv_snapshot_goto(bs1, name);
- if (ret < 0) {
- if (bs != bs1)
- term_printf("Warning: ");
- switch(ret) {
- case -ENOTSUP:
- term_printf("Snapshots not supported on device '%s'\n",
- bdrv_get_device_name(bs1));
- break;
- case -ENOENT:
- term_printf("Could not find snapshot '%s' on device '%s'\n",
- name, bdrv_get_device_name(bs1));
- break;
- default:
- term_printf("Error %d while activating snapshot on '%s'\n",
- ret, bdrv_get_device_name(bs1));
- break;
- }
- /* fatal on snapshot block device */
- if (bs == bs1)
- goto the_end;
+ if (bdrv_has_snapshot(bs)) {
+ ret = bdrv_snapshot_goto(bs, name);
+ if (ret < 0) {
+ switch(ret) {
+ case -ENOTSUP:
+ term_printf("Snapshots not supported on device '%s'\n",
+ bdrv_get_device_name(bs));
+ break;
+ case -ENOENT:
+ term_printf("Could not find snapshot '%s' on device '%s'\n",
+ name, bdrv_get_device_name(bs));
+ break;
+ default:
+ term_printf("Error %d while activating snapshot on '%s'\n",
+ ret, bdrv_get_device_name(bs));
+ break;
}
+ /* fatal on snapshot block device */
+ goto the_end;
}
}
@@ -5482,34 +5478,31 @@
void do_delvm(const char *name)
{
- BlockDriverState *bs, *bs1;
- int i, ret;
+ BlockDriverState *bs;
+ int ret;
bs = get_bs_snapshots();
if (!bs) {
term_printf("No block device supports snapshots\n");
return;
}
-
- for(i = 0; i <= MAX_DISKS; i++) {
- bs1 = bs_table[i];
- if (bdrv_has_snapshot(bs1)) {
- ret = bdrv_snapshot_delete(bs1, name);
- if (ret < 0) {
- if (ret == -ENOTSUP)
- term_printf("Snapshots not supported on device '%s'\n",
- bdrv_get_device_name(bs1));
- else
- term_printf("Error %d while deleting snapshot on '%s'\n",
- ret, bdrv_get_device_name(bs1));
- }
+
+ if (bdrv_has_snapshot(bs)) {
+ ret = bdrv_snapshot_delete(bs, name);
+ if (ret < 0) {
+ if (ret == -ENOTSUP)
+ term_printf("Snapshots not supported on device '%s'\n",
+ bdrv_get_device_name(bs));
+ else
+ term_printf("Error %d while deleting snapshot on '%s'\n",
+ ret, bdrv_get_device_name(bs));
}
}
}
void do_info_snapshots(void)
{
- BlockDriverState *bs, *bs1;
+ BlockDriverState *bs;
QEMUSnapshotInfo *sn_tab, *sn;
int nb_sns, i;
char buf[256];
@@ -5520,13 +5513,8 @@
return;
}
term_printf("Snapshot devices:");
- for(i = 0; i <= MAX_DISKS; i++) {
- bs1 = bs_table[i];
- if (bdrv_has_snapshot(bs1)) {
- if (bs == bs1)
- term_printf(" %s", bdrv_get_device_name(bs1));
- }
- }
+ if (bdrv_has_snapshot(bs))
+ term_printf(" %s", bdrv_get_device_name(bs));
term_printf("\n");
nb_sns = bdrv_snapshot_list(bs, &sn_tab);
@@ -5899,13 +5887,144 @@
#elif defined(TARGET_ARM)
-/* ??? Need to implement these. */
void cpu_save(QEMUFile *f, void *opaque)
{
+ int i;
+ CPUARMState *env = (CPUARMState *)opaque;
+
+ for (i = 0; i < 16; i++) {
+ qemu_put_be32(f, env->regs[i]);
+ }
+ qemu_put_be32(f, cpsr_read(env));
+ qemu_put_be32(f, env->spsr);
+ for (i = 0; i < 6; i++) {
+ qemu_put_be32(f, env->banked_spsr[i]);
+ qemu_put_be32(f, env->banked_r13[i]);
+ qemu_put_be32(f, env->banked_r14[i]);
+ }
+ for (i = 0; i < 5; i++) {
+ qemu_put_be32(f, env->usr_regs[i]);
+ qemu_put_be32(f, env->fiq_regs[i]);
+ }
+ qemu_put_be32(f, env->cp15.c0_cpuid);
+ qemu_put_be32(f, env->cp15.c0_cachetype);
+ qemu_put_be32(f, env->cp15.c1_sys);
+ qemu_put_be32(f, env->cp15.c1_coproc);
+ qemu_put_be32(f, env->cp15.c2_base);
+ qemu_put_be32(f, env->cp15.c2_data);
+ qemu_put_be32(f, env->cp15.c2_insn);
+ qemu_put_be32(f, env->cp15.c3);
+ qemu_put_be32(f, env->cp15.c5_insn);
+ qemu_put_be32(f, env->cp15.c5_data);
+ for (i = 0; i < 8; i++) {
+ qemu_put_be32(f, env->cp15.c6_region[i]);
+ }
+ qemu_put_be32(f, env->cp15.c6_insn);
+ qemu_put_be32(f, env->cp15.c6_data);
+ qemu_put_be32(f, env->cp15.c9_insn);
+ qemu_put_be32(f, env->cp15.c9_data);
+ qemu_put_be32(f, env->cp15.c13_fcse);
+ qemu_put_be32(f, env->cp15.c13_context);
+ qemu_put_be32(f, env->cp15.c15_cpar);
+
+ qemu_put_be32(f, env->features);
+
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
+ for (i = 0; i < 16; i++) {
+ CPU_DoubleU u;
+ u.d = env->vfp.regs[i];
+ qemu_put_be32(f, u.l.upper);
+ qemu_put_be32(f, u.l.lower);
+ }
+ for (i = 0; i < 16; i++) {
+ qemu_put_be32(f, env->vfp.xregs[i]);
+ }
+
+ /* TODO: Should use proper FPSCR access functions. */
+ qemu_put_be32(f, env->vfp.vec_len);
+ qemu_put_be32(f, env->vfp.vec_stride);
+ }
+
+ if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
+ for (i = 0; i < 16; i++) {
+ qemu_put_be64(f, env->iwmmxt.regs[i]);
+ }
+ for (i = 0; i < 16; i++) {
+ qemu_put_be32(f, env->iwmmxt.cregs[i]);
+ }
+ }
}
int cpu_load(QEMUFile *f, void *opaque, int version_id)
{
+ CPUARMState *env = (CPUARMState *)opaque;
+ int i;
+
+ if (version_id != 0)
+ return -EINVAL;
+
+ for (i = 0; i < 16; i++) {
+ env->regs[i] = qemu_get_be32(f);
+ }
+ cpsr_write(env, qemu_get_be32(f), 0xffffffff);
+ env->spsr = qemu_get_be32(f);
+ for (i = 0; i < 6; i++) {
+ env->banked_spsr[i] = qemu_get_be32(f);
+ env->banked_r13[i] = qemu_get_be32(f);
+ env->banked_r14[i] = qemu_get_be32(f);
+ }
+ for (i = 0; i < 5; i++) {
+ env->usr_regs[i] = qemu_get_be32(f);
+ env->fiq_regs[i] = qemu_get_be32(f);
+ }
+ env->cp15.c0_cpuid = qemu_get_be32(f);
+ env->cp15.c0_cachetype = qemu_get_be32(f);
+ env->cp15.c1_sys = qemu_get_be32(f);
+ env->cp15.c1_coproc = qemu_get_be32(f);
+ env->cp15.c2_base = qemu_get_be32(f);
+ env->cp15.c2_data = qemu_get_be32(f);
+ env->cp15.c2_insn = qemu_get_be32(f);
+ env->cp15.c3 = qemu_get_be32(f);
+ env->cp15.c5_insn = qemu_get_be32(f);
+ env->cp15.c5_data = qemu_get_be32(f);
+ for (i = 0; i < 8; i++) {
+ env->cp15.c6_region[i] = qemu_get_be32(f);
+ }
+ env->cp15.c6_insn = qemu_get_be32(f);
+ env->cp15.c6_data = qemu_get_be32(f);
+ env->cp15.c9_insn = qemu_get_be32(f);
+ env->cp15.c9_data = qemu_get_be32(f);
+ env->cp15.c13_fcse = qemu_get_be32(f);
+ env->cp15.c13_context = qemu_get_be32(f);
+ env->cp15.c15_cpar = qemu_get_be32(f);
+
+ env->features = qemu_get_be32(f);
+
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
+ for (i = 0; i < 16; i++) {
+ CPU_DoubleU u;
+ u.l.upper = qemu_get_be32(f);
+ u.l.lower = qemu_get_be32(f);
+ env->vfp.regs[i] = u.d;
+ }
+ for (i = 0; i < 16; i++) {
+ env->vfp.xregs[i] = qemu_get_be32(f);
+ }
+
+ /* TODO: Should use proper FPSCR access functions. */
+ env->vfp.vec_len = qemu_get_be32(f);
+ env->vfp.vec_stride = qemu_get_be32(f);
+ }
+
+ if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
+ for (i = 0; i < 16; i++) {
+ env->iwmmxt.regs[i] = qemu_get_be64(f);
+ }
+ for (i = 0; i < 16; i++) {
+ env->iwmmxt.cregs[i] = qemu_get_be32(f);
+ }
+ }
+
return 0;
}
More information about the commitlog
mailing list