Commit aa941b94 authored by balrog's avatar balrog
Browse files

Savevm/loadvm bits for ARM core, the PXA2xx peripherals and Spitz hardware.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2857 c046a42c-6fe2-441c-8c8c-71466251a162
parent 3f6c925f
......@@ -75,3 +75,20 @@ static inline void ecc_reset(struct ecc_state_s *s)
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);
}
......@@ -104,10 +104,41 @@ static void ads7846_ts_event(void *opaque,
if (s->pressure == !buttons_state) {
s->pressure = !!buttons_state;
ads7846_int_update(s);
ads7846_int_update(s);
}
}
static void ads7846_save(QEMUFile *f, void *opaque)
{
struct ads7846_state_s *s = (struct ads7846_state_s *) opaque;
int i;
for (i = 0; i < 8; i ++)
qemu_put_be32(f, s->input[i]);
qemu_put_be32(f, s->noise);
qemu_put_be32(f, s->cycle);
qemu_put_be32(f, s->output);
}
static int ads7846_load(QEMUFile *f, void *opaque, int version_id)
{
struct ads7846_state_s *s = (struct ads7846_state_s *) opaque;
int i;
for (i = 0; i < 8; i ++)
s->input[i] = qemu_get_be32(f);
s->noise = qemu_get_be32(f);
s->cycle = qemu_get_be32(f);
s->output = qemu_get_be32(f);
s->pressure = 0;
ads7846_int_update(s);
return 0;
}
static int ads7846_iid = 0;
struct ads7846_state_s *ads7846_init(qemu_irq penirq)
{
struct ads7846_state_s *s;
......@@ -127,5 +158,9 @@ struct ads7846_state_s *ads7846_init(qemu_irq penirq)
"QEMU ADS7846-driven Touchscreen");
ads7846_int_update(s);
register_savevm("ads7846", ads7846_iid ++, 0,
ads7846_save, ads7846_load, s);
return s;
}
......@@ -115,3 +115,34 @@ void i2c_nack(i2c_bus *bus)
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);
}
......@@ -45,6 +45,10 @@ void i2c_end_transfer(i2c_bus *bus);
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);
......
......@@ -2416,6 +2416,62 @@ static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2)
register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state);
}
/* save per IDE drive data */
static void ide_save(QEMUFile* f, IDEState *s)
{
qemu_put_be32s(f, &s->mult_sectors);
qemu_put_be32s(f, &s->identify_set);
if (s->identify_set) {
qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512);
}
qemu_put_8s(f, &s->feature);
qemu_put_8s(f, &s->error);
qemu_put_be32s(f, &s->nsector);
qemu_put_8s(f, &s->sector);
qemu_put_8s(f, &s->lcyl);
qemu_put_8s(f, &s->hcyl);
qemu_put_8s(f, &s->hob_feature);
qemu_put_8s(f, &s->hob_nsector);
qemu_put_8s(f, &s->hob_sector);
qemu_put_8s(f, &s->hob_lcyl);
qemu_put_8s(f, &s->hob_hcyl);
qemu_put_8s(f, &s->select);
qemu_put_8s(f, &s->status);
qemu_put_8s(f, &s->lba48);
qemu_put_8s(f, &s->sense_key);
qemu_put_8s(f, &s->asc);
/* XXX: if a transfer is pending, we do not save it yet */
}
/* load per IDE drive data */
static void ide_load(QEMUFile* f, IDEState *s)
{
qemu_get_be32s(f, &s->mult_sectors);
qemu_get_be32s(f, &s->identify_set);
if (s->identify_set) {
qemu_get_buffer(f, (uint8_t *)s->identify_data, 512);
}
qemu_get_8s(f, &s->feature);
qemu_get_8s(f, &s->error);
qemu_get_be32s(f, &s->nsector);
qemu_get_8s(f, &s->sector);
qemu_get_8s(f, &s->lcyl);
qemu_get_8s(f, &s->hcyl);
qemu_get_8s(f, &s->hob_feature);
qemu_get_8s(f, &s->hob_nsector);
qemu_get_8s(f, &s->hob_sector);
qemu_get_8s(f, &s->hob_lcyl);
qemu_get_8s(f, &s->hob_hcyl);
qemu_get_8s(f, &s->select);
qemu_get_8s(f, &s->status);
qemu_get_8s(f, &s->lba48);
qemu_get_8s(f, &s->sense_key);
qemu_get_8s(f, &s->asc);
/* XXX: if a transfer is pending, we do not save it yet */
}
/***********************************************************/
/* ISA IDE definitions */
......@@ -2731,30 +2787,7 @@ static void pci_ide_save(QEMUFile* f, void *opaque)
/* per IDE drive data */
for(i = 0; i < 4; i++) {
IDEState *s = &d->ide_if[i];
qemu_put_be32s(f, &s->mult_sectors);
qemu_put_be32s(f, &s->identify_set);
if (s->identify_set) {
qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512);
}
qemu_put_8s(f, &s->feature);
qemu_put_8s(f, &s->error);
qemu_put_be32s(f, &s->nsector);
qemu_put_8s(f, &s->sector);
qemu_put_8s(f, &s->lcyl);
qemu_put_8s(f, &s->hcyl);
qemu_put_8s(f, &s->hob_feature);
qemu_put_8s(f, &s->hob_nsector);
qemu_put_8s(f, &s->hob_sector);
qemu_put_8s(f, &s->hob_lcyl);
qemu_put_8s(f, &s->hob_hcyl);
qemu_put_8s(f, &s->select);
qemu_put_8s(f, &s->status);
qemu_put_8s(f, &s->lba48);
qemu_put_8s(f, &s->sense_key);
qemu_put_8s(f, &s->asc);
/* XXX: if a transfer is pending, we do not save it yet */
ide_save(f, &d->ide_if[i]);
}
}
......@@ -2788,30 +2821,7 @@ static int pci_ide_load(QEMUFile* f, void *opaque, int version_id)
/* per IDE drive data */
for(i = 0; i < 4; i++) {
IDEState *s = &d->ide_if[i];
qemu_get_be32s(f, &s->mult_sectors);
qemu_get_be32s(f, &s->identify_set);
if (s->identify_set) {
qemu_get_buffer(f, (uint8_t *)s->identify_data, 512);
}
qemu_get_8s(f, &s->feature);
qemu_get_8s(f, &s->error);
qemu_get_be32s(f, &s->nsector);
qemu_get_8s(f, &s->sector);
qemu_get_8s(f, &s->lcyl);
qemu_get_8s(f, &s->hcyl);
qemu_get_8s(f, &s->hob_feature);
qemu_get_8s(f, &s->hob_nsector);
qemu_get_8s(f, &s->hob_sector);
qemu_get_8s(f, &s->hob_lcyl);
qemu_get_8s(f, &s->hob_hcyl);
qemu_get_8s(f, &s->select);
qemu_get_8s(f, &s->status);
qemu_get_8s(f, &s->lba48);
qemu_get_8s(f, &s->sense_key);
qemu_get_8s(f, &s->asc);
/* XXX: if a transfer is pending, we do not save it yet */
ide_load(f, &d->ide_if[i]);
}
return 0;
}
......@@ -3255,6 +3265,54 @@ static void md_common_write(void *opaque, uint32_t at, uint16_t value)
}
}
static void md_save(QEMUFile *f, void *opaque)
{
struct md_s *s = (struct md_s *) opaque;
int i;
uint8_t drive1_selected;
qemu_put_8s(f, &s->opt);
qemu_put_8s(f, &s->stat);
qemu_put_8s(f, &s->pins);
qemu_put_8s(f, &s->ctrl);
qemu_put_be16s(f, &s->io);
qemu_put_byte(f, s->cycle);
drive1_selected = (s->ide->cur_drive != s->ide);
qemu_put_8s(f, &s->ide->cmd);
qemu_put_8s(f, &drive1_selected);
for (i = 0; i < 2; i ++)
ide_save(f, &s->ide[i]);
}
static int md_load(QEMUFile *f, void *opaque, int version_id)
{
struct md_s *s = (struct md_s *) opaque;
int i;
uint8_t drive1_selected;
qemu_get_8s(f, &s->opt);
qemu_get_8s(f, &s->stat);
qemu_get_8s(f, &s->pins);
qemu_get_8s(f, &s->ctrl);
qemu_get_be16s(f, &s->io);
s->cycle = qemu_get_byte(f);
qemu_get_8s(f, &s->ide->cmd);
qemu_get_8s(f, &drive1_selected);
s->ide->cur_drive = &s->ide[(drive1_selected != 0)];
for (i = 0; i < 2; i ++)
ide_load(f, &s->ide[i]);
return 0;
}
static int md_iid = 0;
static const uint8_t dscm1xxxx_cis[0x14a] = {
[0x000] = CISTPL_DEVICE, /* 5V Device Information */
[0x002] = 0x03, /* Tuple length = 4 bytes */
......@@ -3480,5 +3538,8 @@ struct pcmcia_card_s *dscm1xxxx_init(BlockDriverState *bdrv)
md->ide->is_cf = 1;
md->ide->mdata_size = METADATA_SIZE;
md->ide->mdata_storage = (uint8_t *) qemu_mallocz(METADATA_SIZE);
register_savevm("microdrive", md_iid ++, 0, md_save, md_load, md);
return &md->card;
}
......@@ -89,6 +89,39 @@ void max111x_write(void *opaque, uint32_t value)
qemu_irq_raise(s->interrupt);
}
static void max111x_save(QEMUFile *f, void *opaque)
{
struct max111x_s *s = (struct max111x_s *) opaque;
int i;
qemu_put_8s(f, &s->tb1);
qemu_put_8s(f, &s->rb2);
qemu_put_8s(f, &s->rb3);
qemu_put_be32(f, s->inputs);
qemu_put_be32(f, s->com);
for (i = 0; i < s->inputs; i ++)
qemu_put_byte(f, s->input[i]);
}
static int max111x_load(QEMUFile *f, void *opaque, int version_id)
{
struct max111x_s *s = (struct max111x_s *) opaque;
int i;
qemu_get_8s(f, &s->tb1);
qemu_get_8s(f, &s->rb2);
qemu_get_8s(f, &s->rb3);
if (s->inputs != qemu_get_be32(f))
return -EINVAL;
s->com = qemu_get_be32(f);
for (i = 0; i < s->inputs; i ++)
s->input[i] = qemu_get_byte(f);
return 0;
}
static int max111x_iid = 0;
static struct max111x_s *max111x_init(qemu_irq cb)
{
struct max111x_s *s;
......@@ -108,6 +141,10 @@ static struct max111x_s *max111x_init(qemu_irq cb)
s->input[6] = 0x90;
s->input[7] = 0x80;
s->com = 0;
register_savevm("max111x", max111x_iid ++, 0,
max111x_save, max111x_load, s);
return s;
}
......
......@@ -143,6 +143,41 @@ static void max7310_event(i2c_slave *i2c, enum i2c_event event)
}
}
static void max7310_save(QEMUFile *f, void *opaque)
{
struct max7310_s *s = (struct max7310_s *) opaque;
qemu_put_be32(f, s->i2c_command_byte);
qemu_put_be32(f, s->len);
qemu_put_8s(f, &s->level);
qemu_put_8s(f, &s->direction);
qemu_put_8s(f, &s->polarity);
qemu_put_8s(f, &s->status);
qemu_put_8s(f, &s->command);
i2c_slave_save(f, &s->i2c);
}
static int max7310_load(QEMUFile *f, void *opaque, int version_id)
{
struct max7310_s *s = (struct max7310_s *) opaque;
s->i2c_command_byte = qemu_get_be32(f);
s->len = qemu_get_be32(f);
qemu_get_8s(f, &s->level);
qemu_get_8s(f, &s->direction);
qemu_get_8s(f, &s->polarity);
qemu_get_8s(f, &s->status);
qemu_get_8s(f, &s->command);
i2c_slave_load(f, &s->i2c);
return 0;
}
static int max7310_iid = 0;
static void max7310_gpio_set(void *opaque, int line, int level)
{
struct max7310_s *s = (struct max7310_s *) opaque;
......@@ -169,6 +204,9 @@ struct i2c_slave *max7310_init(i2c_bus *bus)
max7310_reset(&s->i2c);
register_savevm("max7310", max7310_iid ++, 0,
max7310_save, max7310_load, s);
return &s->i2c;
}
......
......@@ -273,6 +273,50 @@ static void nand_command(struct nand_flash_s *s)
}
}
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 @@ struct nand_flash_s *nand_init(int manf_id, int chip_id)
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;
}
......
......@@ -141,6 +141,26 @@ static CPUWriteMemoryFunc *pxa2xx_pm_writefn[] = {
pxa2xx_pm_write,
};
static void pxa2xx_pm_save(QEMUFile *f, void *opaque)
{
struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque;
int i;
for (i = 0; i < 0x40; i ++)
qemu_put_be32s(f, &s->pm_regs[i]);
}
static int pxa2xx_pm_load(QEMUFile *f, void *opaque, int version_id)
{
struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque;
int i;
for (i = 0; i < 0x40; i ++)
qemu_get_be32s(f, &s->pm_regs[i]);
return 0;
}
#define CCCR 0x00 /* Core Clock Configuration register */
#define CKEN 0x04 /* Clock Enable register */
#define OSCC 0x08 /* Oscillator Configuration register */
......@@ -204,6 +224,30 @@ static CPUWriteMemoryFunc *pxa2xx_cm_writefn[] = {
pxa2xx_cm_write,
};
static void pxa2xx_cm_save(QEMUFile *f, void *opaque)
{
struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque;
int i;
for (i = 0; i < 4; i ++)
qemu_put_be32s(f, &s->cm_regs[i]);
qemu_put_be32s(f, &s->clkcfg);
qemu_put_be32s(f, &s->pmnc);
}
static int pxa2xx_cm_load(QEMUFile *f, void *opaque, int version_id)
{
struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque;
int i;
for (i = 0; i < 4; i ++)
qemu_get_be32s(f, &s->cm_regs[i]);
qemu_get_be32s(f, &s->clkcfg);
qemu_get_be32s(f, &s->pmnc);
return 0;
}
static uint32_t pxa2xx_clkpwr_read(void *opaque, int op2, int reg, int crm)
{
struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque;
......@@ -482,6 +526,26 @@ static CPUWriteMemoryFunc *pxa2xx_mm_writefn[] = {
pxa2xx_mm_write,
};
static void pxa2xx_mm_save(QEMUFile *f, void *opaque)
{
struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque;
int i;
for (i = 0; i < 0x1a; i ++)
qemu_put_be32s(f, &s->mm_regs[i]);
}
static int pxa2xx_mm_load(QEMUFile *f, void *opaque, int version_id)
{
struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque;
int i;
for (i = 0; i < 0x1a; i ++)
qemu_get_be32s(f, &s->mm_regs[i]);
return 0;
}
/* Synchronous Serial Ports */
struct pxa2xx_ssp_s {
target_phys_addr_t base;
......@@ -761,6 +825,53 @@ static CPUWriteMemoryFunc *pxa2xx_ssp_writefn[] = {
pxa2xx_ssp_write,
};
static void pxa2xx_ssp_save(QEMUFile *f, void *opaque)
{
struct pxa2xx_ssp_s *s = (struct pxa2xx_ssp_s *) opaque;
int i;
qemu_put_be32(f, s->enable);
qemu_put_be32s(f, &s->sscr[0]);
qemu_put_be32s(f, &s->sscr[1]);
qemu_put_be32s(f, &s->sspsp);
qemu_put_be32s(f, &s->ssto);
qemu_put_be32s(f, &s->ssitr);
qemu_put_be32s(f, &s->sssr);
qemu_put_8s(f, &s->sstsa);
qemu_put_8s(f, &s->ssrsa);
qemu_put_8s(f, &s->ssacd);
qemu_put_byte(f, s->rx_level);
for (i = 0; i < s->rx_level; i ++)
qemu_put_byte(f, s->rx_fifo[(s->rx_start + i) & 0xf]);
}
static int pxa2xx_ssp_load(QEMUFile *f, void *opaque, int version_id)
{
struct pxa2xx_ssp_s *s = (struct pxa2xx_ssp_s *) opaque;
int i;
s->enable = qemu_get_be32(f);
qemu_get_be32s(f, &s->sscr[0]);
qemu_get_be32s(f, &s->sscr[1]);
qemu_get_be32s(f, &s->sspsp);
qemu_get_be32s(f, &s->ssto);
qemu_get_be32s(f, &s->ssitr);
qemu_get_be32s(f, &s->sssr);
qemu_get_8s(f, &s->sstsa);
qemu_get_8s(f, &s->ssrsa);
qemu_get_8s(f, &s->ssacd);
s->rx_level = qemu_get_byte(f);
s->rx_start = 0;
for (i = 0; i < s->rx_level; i ++)
s->rx_fifo[i] = qemu_get_byte(f);
return 0;
}