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
This commit is contained in:
parent
3f6c925f37
commit
aa941b9445
17
ecc.h
17
ecc.h
@ -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);
|
||||
}
|
||||
|
37
hw/ads7846.c
37
hw/ads7846.c
@ -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;
|
||||
}
|
||||
|
31
hw/i2c.c
31
hw/i2c.c
@ -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);
|
||||
}
|
||||
|
4
hw/i2c.h
4
hw/i2c.h
@ -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);
|
||||
|
157
hw/ide.c
157
hw/ide.c
@ -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;
|
||||
}
|
||||
|
37
hw/max111x.c
37
hw/max111x.c
@ -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;
|
||||
}
|
||||
|
||||
|
38
hw/max7310.c
38
hw/max7310.c
@ -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;
|
||||
}
|
||||
|
||||
|
47
hw/nand.c
47
hw/nand.c
@ -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;
|
||||
}
|
||||
|
||||
|
315
hw/pxa2xx.c
315
hw/pxa2xx.c
@ -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;
|
||||
}
|
||||
|
||||
/* Real-Time Clock */
|
||||
#define RCNR 0x00 /* RTC Counter register */
|
||||
#define RTAR 0x04 /* RTC Alarm register */
|
||||
@ -1052,7 +1163,19 @@ static void pxa2xx_rtc_write(void *opaque, target_phys_addr_t addr,
|
||||
}
|
||||
}
|
||||
|
||||
static void pxa2xx_rtc_reset(struct pxa2xx_state_s *s)
|
||||
static CPUReadMemoryFunc *pxa2xx_rtc_readfn[] = {
|
||||
pxa2xx_rtc_read,
|
||||
pxa2xx_rtc_read,
|
||||
pxa2xx_rtc_read,
|
||||
};
|
||||
|
||||
static CPUWriteMemoryFunc *pxa2xx_rtc_writefn[] = {
|
||||
pxa2xx_rtc_write,
|
||||
pxa2xx_rtc_write,
|
||||
pxa2xx_rtc_write,
|
||||
};
|
||||
|
||||
static void pxa2xx_rtc_init(struct pxa2xx_state_s *s)
|
||||
{
|
||||
struct tm *tm;
|
||||
time_t ti;
|
||||
@ -1086,17 +1209,61 @@ static void pxa2xx_rtc_reset(struct pxa2xx_state_s *s)
|
||||
s->rtc_pi = qemu_new_timer(rt_clock, pxa2xx_rtc_pi_tick, s);
|
||||
}
|
||||
|
||||
static CPUReadMemoryFunc *pxa2xx_rtc_readfn[] = {
|
||||
pxa2xx_rtc_read,
|
||||
pxa2xx_rtc_read,
|
||||
pxa2xx_rtc_read,
|
||||
};
|
||||
static void pxa2xx_rtc_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque;
|
||||
|
||||
static CPUWriteMemoryFunc *pxa2xx_rtc_writefn[] = {
|
||||
pxa2xx_rtc_write,
|
||||
pxa2xx_rtc_write,
|
||||
pxa2xx_rtc_write,
|
||||
};
|
||||
pxa2xx_rtc_hzupdate(s);
|
||||
pxa2xx_rtc_piupdate(s);
|
||||
pxa2xx_rtc_swupdate(s);
|
||||
|
||||
qemu_put_be32s(f, &s->rttr);
|
||||
qemu_put_be32s(f, &s->rtsr);
|
||||
qemu_put_be32s(f, &s->rtar);
|
||||
qemu_put_be32s(f, &s->rdar1);
|
||||
qemu_put_be32s(f, &s->rdar2);
|
||||
qemu_put_be32s(f, &s->ryar1);
|
||||
qemu_put_be32s(f, &s->ryar2);
|
||||
qemu_put_be32s(f, &s->swar1);
|
||||
qemu_put_be32s(f, &s->swar2);
|
||||
qemu_put_be32s(f, &s->piar);
|
||||
qemu_put_be32s(f, &s->last_rcnr);
|
||||
qemu_put_be32s(f, &s->last_rdcr);
|
||||
qemu_put_be32s(f, &s->last_rycr);
|
||||
qemu_put_be32s(f, &s->last_swcr);
|
||||
qemu_put_be32s(f, &s->last_rtcpicr);
|
||||
qemu_put_be64s(f, &s->last_hz);
|
||||
qemu_put_be64s(f, &s->last_sw);
|
||||
qemu_put_be64s(f, &s->last_pi);
|
||||
}
|
||||
|
||||
static int pxa2xx_rtc_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque;
|
||||
|
||||
qemu_get_be32s(f, &s->rttr);
|
||||
qemu_get_be32s(f, &s->rtsr);
|
||||
qemu_get_be32s(f, &s->rtar);
|
||||
qemu_get_be32s(f, &s->rdar1);
|
||||
qemu_get_be32s(f, &s->rdar2);
|
||||
qemu_get_be32s(f, &s->ryar1);
|
||||
qemu_get_be32s(f, &s->ryar2);
|
||||
qemu_get_be32s(f, &s->swar1);
|
||||
qemu_get_be32s(f, &s->swar2);
|
||||
qemu_get_be32s(f, &s->piar);
|
||||
qemu_get_be32s(f, &s->last_rcnr);
|
||||
qemu_get_be32s(f, &s->last_rdcr);
|
||||
qemu_get_be32s(f, &s->last_rycr);
|
||||
qemu_get_be32s(f, &s->last_swcr);
|
||||
qemu_get_be32s(f, &s->last_rtcpicr);
|
||||
qemu_get_be64s(f, &s->last_hz);
|
||||
qemu_get_be64s(f, &s->last_sw);
|
||||
qemu_get_be64s(f, &s->last_pi);
|
||||
|
||||
pxa2xx_rtc_alarm_update(s, s->rtsr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* I2C Interface */
|
||||
struct pxa2xx_i2c_s {
|
||||
@ -1289,6 +1456,33 @@ static CPUWriteMemoryFunc *pxa2xx_i2c_writefn[] = {
|
||||
pxa2xx_i2c_write,
|
||||
};
|
||||
|
||||
static void pxa2xx_i2c_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) opaque;
|
||||
|
||||
qemu_put_be16s(f, &s->control);
|
||||
qemu_put_be16s(f, &s->status);
|
||||
qemu_put_8s(f, &s->ibmr);
|
||||
qemu_put_8s(f, &s->data);
|
||||
|
||||
i2c_bus_save(f, s->bus);
|
||||
i2c_slave_save(f, &s->slave);
|
||||
}
|
||||
|
||||
static int pxa2xx_i2c_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) opaque;
|
||||
|
||||
qemu_get_be16s(f, &s->control);
|
||||
qemu_get_be16s(f, &s->status);
|
||||
qemu_get_8s(f, &s->ibmr);
|
||||
qemu_get_8s(f, &s->data);
|
||||
|
||||
i2c_bus_load(f, s->bus);
|
||||
i2c_slave_load(f, &s->slave);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base,
|
||||
qemu_irq irq, int ioregister)
|
||||
{
|
||||
@ -1309,6 +1503,9 @@ struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base,
|
||||
cpu_register_physical_memory(s->base & 0xfffff000, 0xfff, iomemtype);
|
||||
}
|
||||
|
||||
register_savevm("pxa2xx_i2c", base, 0,
|
||||
pxa2xx_i2c_save, pxa2xx_i2c_load, s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -1470,6 +1667,40 @@ static CPUWriteMemoryFunc *pxa2xx_i2s_writefn[] = {
|
||||
pxa2xx_i2s_write,
|
||||
};
|
||||
|
||||
static void pxa2xx_i2s_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
struct pxa2xx_i2s_s *s = (struct pxa2xx_i2s_s *) opaque;
|
||||
|
||||
qemu_put_be32s(f, &s->control[0]);
|
||||
qemu_put_be32s(f, &s->control[1]);
|
||||
qemu_put_be32s(f, &s->status);
|
||||
qemu_put_be32s(f, &s->mask);
|
||||
qemu_put_be32s(f, &s->clk);
|
||||
|
||||
qemu_put_be32(f, s->enable);
|
||||
qemu_put_be32(f, s->rx_len);
|
||||
qemu_put_be32(f, s->tx_len);
|
||||
qemu_put_be32(f, s->fifo_len);
|
||||
}
|
||||
|
||||
static int pxa2xx_i2s_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
struct pxa2xx_i2s_s *s = (struct pxa2xx_i2s_s *) opaque;
|
||||
|
||||
qemu_get_be32s(f, &s->control[0]);
|
||||
qemu_get_be32s(f, &s->control[1]);
|
||||
qemu_get_be32s(f, &s->status);
|
||||
qemu_get_be32s(f, &s->mask);
|
||||
qemu_get_be32s(f, &s->clk);
|
||||
|
||||
s->enable = qemu_get_be32(f);
|
||||
s->rx_len = qemu_get_be32(f);
|
||||
s->tx_len = qemu_get_be32(f);
|
||||
s->fifo_len = qemu_get_be32(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pxa2xx_i2s_data_req(void *opaque, int tx, int rx)
|
||||
{
|
||||
struct pxa2xx_i2s_s *s = (struct pxa2xx_i2s_s *) opaque;
|
||||
@ -1510,6 +1741,9 @@ static struct pxa2xx_i2s_s *pxa2xx_i2s_init(target_phys_addr_t base,
|
||||
pxa2xx_i2s_writefn, s);
|
||||
cpu_register_physical_memory(s->base & 0xfff00000, 0xfffff, iomemtype);
|
||||
|
||||
register_savevm("pxa2xx_i2s", base, 0,
|
||||
pxa2xx_i2s_save, pxa2xx_i2s_load, s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -1712,6 +1946,45 @@ static void pxa2xx_fir_event(void *opaque, int event)
|
||||
{
|
||||
}
|
||||
|
||||
static void pxa2xx_fir_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
struct pxa2xx_fir_s *s = (struct pxa2xx_fir_s *) opaque;
|
||||
int i;
|
||||
|
||||
qemu_put_be32(f, s->enable);
|
||||
|
||||
qemu_put_8s(f, &s->control[0]);
|
||||
qemu_put_8s(f, &s->control[1]);
|
||||
qemu_put_8s(f, &s->control[2]);
|
||||
qemu_put_8s(f, &s->status[0]);
|
||||
qemu_put_8s(f, &s->status[1]);
|
||||
|
||||
qemu_put_byte(f, s->rx_len);
|
||||
for (i = 0; i < s->rx_len; i ++)
|
||||
qemu_put_byte(f, s->rx_fifo[(s->rx_start + i) & 63]);
|
||||
}
|
||||
|
||||
static int pxa2xx_fir_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
struct pxa2xx_fir_s *s = (struct pxa2xx_fir_s *) opaque;
|
||||
int i;
|
||||
|
||||
s->enable = qemu_get_be32(f);
|
||||
|
||||
qemu_get_8s(f, &s->control[0]);
|
||||
qemu_get_8s(f, &s->control[1]);
|
||||
qemu_get_8s(f, &s->control[2]);
|
||||
qemu_get_8s(f, &s->status[0]);
|
||||
qemu_get_8s(f, &s->status[1]);
|
||||
|
||||
s->rx_len = qemu_get_byte(f);
|
||||
s->rx_start = 0;
|
||||
for (i = 0; i < s->rx_len; i ++)
|
||||
s->rx_fifo[i] = qemu_get_byte(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pxa2xx_fir_s *pxa2xx_fir_init(target_phys_addr_t base,
|
||||
qemu_irq irq, struct pxa2xx_dma_state_s *dma,
|
||||
CharDriverState *chr)
|
||||
@ -1735,6 +2008,8 @@ static struct pxa2xx_fir_s *pxa2xx_fir_init(target_phys_addr_t base,
|
||||
qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty,
|
||||
pxa2xx_fir_rx, pxa2xx_fir_event, s);
|
||||
|
||||
register_savevm("pxa2xx_fir", 0, 0, pxa2xx_fir_save, pxa2xx_fir_load, s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -1763,6 +2038,7 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size,
|
||||
|
||||
s->env = cpu_init();
|
||||
cpu_arm_set_model(s->env, revision ?: "pxa270");
|
||||
register_savevm("cpu", 0, 0, cpu_save, cpu_load, s->env);
|
||||
|
||||
/* SDRAM & Internal Memory Storage */
|
||||
cpu_register_physical_memory(PXA2XX_SDRAM_BASE,
|
||||
@ -1800,6 +2076,7 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size,
|
||||
iomemtype = cpu_register_io_memory(0, pxa2xx_cm_readfn,
|
||||
pxa2xx_cm_writefn, s);
|
||||
cpu_register_physical_memory(s->cm_base, 0xfff, iomemtype);
|
||||
register_savevm("pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s);
|
||||
|
||||
cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s);
|
||||
|
||||
@ -1810,6 +2087,7 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size,
|
||||
iomemtype = cpu_register_io_memory(0, pxa2xx_mm_readfn,
|
||||
pxa2xx_mm_writefn, s);
|
||||
cpu_register_physical_memory(s->mm_base, 0xfff, iomemtype);
|
||||
register_savevm("pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s);
|
||||
|
||||
for (i = 0; pxa27x_ssp[i].io_base; i ++);
|
||||
s->ssp = (struct pxa2xx_ssp_s **)
|
||||
@ -1824,6 +2102,8 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size,
|
||||
iomemtype = cpu_register_io_memory(0, pxa2xx_ssp_readfn,
|
||||
pxa2xx_ssp_writefn, &ssp[i]);
|
||||
cpu_register_physical_memory(ssp[i].base, 0xfff, iomemtype);
|
||||
register_savevm("pxa2xx_ssp", i, 0,
|
||||
pxa2xx_ssp_save, pxa2xx_ssp_load, s);
|
||||
}
|
||||
|
||||
if (usb_enabled) {
|
||||
@ -1837,7 +2117,8 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size,
|
||||
iomemtype = cpu_register_io_memory(0, pxa2xx_rtc_readfn,
|
||||
pxa2xx_rtc_writefn, s);
|
||||
cpu_register_physical_memory(s->rtc_base, 0xfff, iomemtype);
|
||||
pxa2xx_rtc_reset(s);
|
||||
pxa2xx_rtc_init(s);
|
||||
register_savevm("pxa2xx_rtc", 0, 0, pxa2xx_rtc_save, pxa2xx_rtc_load, s);
|
||||
|
||||
/* Note that PM registers are in the same page with PWRI2C registers.
|
||||
* As a workaround we don't map PWRI2C into memory and we expect
|
||||
@ -1849,6 +2130,7 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size,
|
||||
iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn,
|
||||
pxa2xx_pm_writefn, s);
|
||||
cpu_register_physical_memory(s->pm_base, 0xfff, iomemtype);
|
||||
register_savevm("pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s);
|
||||
|
||||
s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma);
|
||||
|
||||
@ -1869,6 +2151,7 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size,
|
||||
|
||||
s->env = cpu_init();
|
||||
cpu_arm_set_model(s->env, "pxa255");
|
||||
register_savevm("cpu", 0, 0, cpu_save, cpu_load, s->env);
|
||||
|
||||
/* SDRAM & Internal Memory Storage */
|
||||
cpu_register_physical_memory(PXA2XX_SDRAM_BASE, sdram_size,
|
||||
@ -1905,6 +2188,7 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size,
|
||||
iomemtype = cpu_register_io_memory(0, pxa2xx_cm_readfn,
|
||||
pxa2xx_cm_writefn, s);
|
||||
cpu_register_physical_memory(s->cm_base, 0xfff, iomemtype);
|
||||
register_savevm("pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s);
|
||||
|
||||
cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s);
|
||||
|
||||
@ -1915,6 +2199,7 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size,
|
||||
iomemtype = cpu_register_io_memory(0, pxa2xx_mm_readfn,
|
||||
pxa2xx_mm_writefn, s);
|
||||
cpu_register_physical_memory(s->mm_base, 0xfff, iomemtype);
|
||||
register_savevm("pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s);
|
||||
|
||||
for (i = 0; pxa255_ssp[i].io_base; i ++);
|
||||
s->ssp = (struct pxa2xx_ssp_s **)
|
||||
@ -1929,6 +2214,8 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size,
|
||||
iomemtype = cpu_register_io_memory(0, pxa2xx_ssp_readfn,
|
||||
pxa2xx_ssp_writefn, &ssp[i]);
|
||||
cpu_register_physical_memory(ssp[i].base, 0xfff, iomemtype);
|
||||
register_savevm("pxa2xx_ssp", i, 0,
|
||||
pxa2xx_ssp_save, pxa2xx_ssp_load, s);
|
||||
}
|
||||
|
||||
if (usb_enabled) {
|
||||
@ -1942,7 +2229,8 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size,
|
||||
iomemtype = cpu_register_io_memory(0, pxa2xx_rtc_readfn,
|
||||
pxa2xx_rtc_writefn, s);
|
||||
cpu_register_physical_memory(s->rtc_base, 0xfff, iomemtype);
|
||||
pxa2xx_rtc_reset(s);
|
||||
pxa2xx_rtc_init(s);
|
||||
register_savevm("pxa2xx_rtc", 0, 0, pxa2xx_rtc_save, pxa2xx_rtc_load, s);
|
||||
|
||||
/* Note that PM registers are in the same page with PWRI2C registers.
|
||||
* As a workaround we don't map PWRI2C into memory and we expect
|
||||
@ -1954,6 +2242,7 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size,
|
||||
iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn,
|
||||
pxa2xx_pm_writefn, s);
|
||||
cpu_register_physical_memory(s->pm_base, 0xfff, iomemtype);
|
||||
register_savevm("pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s);
|
||||
|
||||
s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma);
|
||||
|
||||
|
@ -430,6 +430,61 @@ static CPUWriteMemoryFunc *pxa2xx_dma_writefn[] = {
|
||||
pxa2xx_dma_write
|
||||
};
|
||||
|
||||
static void pxa2xx_dma_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
struct pxa2xx_dma_state_s *s = (struct pxa2xx_dma_state_s *) opaque;
|
||||
int i;
|
||||
|
||||
qemu_put_be32(f, s->channels);
|
||||
|
||||
qemu_put_be32s(f, &s->stopintr);
|
||||
qemu_put_be32s(f, &s->eorintr);
|
||||
qemu_put_be32s(f, &s->rasintr);
|
||||
qemu_put_be32s(f, &s->startintr);
|
||||
qemu_put_be32s(f, &s->endintr);
|
||||
qemu_put_be32s(f, &s->align);
|
||||
qemu_put_be32s(f, &s->pio);
|
||||
|
||||
qemu_put_buffer(f, s->req, PXA2XX_DMA_NUM_REQUESTS);
|
||||
for (i = 0; i < s->channels; i ++) {
|
||||
qemu_put_betl(f, s->chan[i].descr);
|
||||
qemu_put_betl(f, s->chan[i].src);
|
||||
qemu_put_betl(f, s->chan[i].dest);
|
||||
qemu_put_be32s(f, &s->chan[i].cmd);
|
||||
qemu_put_be32s(f, &s->chan[i].state);
|
||||
qemu_put_be32(f, s->chan[i].request);
|
||||
};
|
||||
}
|
||||
|
||||
static int pxa2xx_dma_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
struct pxa2xx_dma_state_s *s = (struct pxa2xx_dma_state_s *) opaque;
|
||||
int i;
|
||||
|
||||
if (qemu_get_be32(f) != s->channels)
|
||||
return -EINVAL;
|
||||
|
||||
qemu_get_be32s(f, &s->stopintr);
|
||||
qemu_get_be32s(f, &s->eorintr);
|
||||
qemu_get_be32s(f, &s->rasintr);
|
||||
qemu_get_be32s(f, &s->startintr);
|
||||
qemu_get_be32s(f, &s->endintr);
|
||||
qemu_get_be32s(f, &s->align);
|
||||
qemu_get_be32s(f, &s->pio);
|
||||
|
||||
qemu_get_buffer(f, s->req, PXA2XX_DMA_NUM_REQUESTS);
|
||||
for (i = 0; i < s->channels; i ++) {
|
||||
s->chan[i].descr = qemu_get_betl(f);
|
||||
s->chan[i].src = qemu_get_betl(f);
|
||||
s->chan[i].dest = qemu_get_betl(f);
|
||||
qemu_get_be32s(f, &s->chan[i].cmd);
|
||||
qemu_get_be32s(f, &s->chan[i].state);
|
||||
s->chan[i].request = qemu_get_be32(f);
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pxa2xx_dma_state_s *pxa2xx_dma_init(target_phys_addr_t base,
|
||||
qemu_irq irq, int channels)
|
||||
{
|
||||
@ -455,6 +510,8 @@ static struct pxa2xx_dma_state_s *pxa2xx_dma_init(target_phys_addr_t base,
|
||||
pxa2xx_dma_writefn, s);
|
||||
cpu_register_physical_memory(base, 0x0000ffff, iomemtype);
|
||||
|
||||
register_savevm("pxa2xx_dma", 0, 0, pxa2xx_dma_save, pxa2xx_dma_load, s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -247,6 +247,51 @@ static CPUWriteMemoryFunc *pxa2xx_gpio_writefn[] = {
|
||||
pxa2xx_gpio_write
|
||||
};
|
||||
|
||||
static void pxa2xx_gpio_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque;
|
||||
int i;
|
||||
|
||||
qemu_put_be32(f, s->lines);
|
||||
|
||||
for (i = 0; i < PXA2XX_GPIO_BANKS; i ++) {
|
||||
qemu_put_be32s(f, &s->ilevel[i]);
|
||||
qemu_put_be32s(f, &s->olevel[i]);
|
||||
qemu_put_be32s(f, &s->dir[i]);
|
||||
qemu_put_be32s(f, &s->rising[i]);
|
||||
qemu_put_be32s(f, &s->falling[i]);
|
||||
qemu_put_be32s(f, &s->status[i]);
|
||||
qemu_put_be32s(f, &s->gafr[i * 2 + 0]);
|
||||
qemu_put_be32s(f, &s->gafr[i * 2 + 1]);
|
||||
|
||||
qemu_put_be32s(f, &s->prev_level[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static int pxa2xx_gpio_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque;
|
||||
int i;
|
||||
|
||||
if (qemu_get_be32(f) != s->lines)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < PXA2XX_GPIO_BANKS; i ++) {
|
||||
qemu_get_be32s(f, &s->ilevel[i]);
|
||||
qemu_get_be32s(f, &s->olevel[i]);
|
||||
qemu_get_be32s(f, &s->dir[i]);
|
||||
qemu_get_be32s(f, &s->rising[i]);
|
||||
qemu_get_be32s(f, &s->falling[i]);
|
||||
qemu_get_be32s(f, &s->status[i]);
|
||||
qemu_get_be32s(f, &s->gafr[i * 2 + 0]);
|
||||
qemu_get_be32s(f, &s->gafr[i * 2 + 1]);
|
||||
|
||||
qemu_get_be32s(f, &s->prev_level[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct pxa2xx_gpio_info_s *pxa2xx_gpio_init(target_phys_addr_t base,
|
||||
CPUState *env, qemu_irq *pic, int lines)
|
||||
{
|
||||
@ -265,6 +310,9 @@ struct pxa2xx_gpio_info_s *pxa2xx_gpio_init(target_phys_addr_t base,
|
||||
pxa2xx_gpio_writefn, s);
|
||||
cpu_register_physical_memory(base, 0x00000fff, iomemtype);
|
||||
|
||||
register_savevm("pxa2xx_gpio", 0, 0,
|
||||
pxa2xx_gpio_save, pxa2xx_gpio_load, s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -924,6 +924,81 @@ void pxa2xx_lcdc_orientation(void *opaque, int angle)
|
||||
pxa2xx_lcdc_resize(s);
|
||||
}
|
||||
|
||||
static void pxa2xx_lcdc_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
|
||||
int i;
|
||||
|
||||
qemu_put_be32(f, s->irqlevel);
|
||||
qemu_put_be32(f, s->transp);
|
||||
|
||||
for (i = 0; i < 6; i ++)
|
||||
qemu_put_be32s(f, &s->control[i]);
|
||||
for (i = 0; i < 2; i ++)
|
||||
qemu_put_be32s(f, &s->status[i]);
|
||||
for (i = 0; i < 2; i ++)
|
||||
qemu_put_be32s(f, &s->ovl1c[i]);
|
||||
for (i = 0; i < 2; i ++)
|
||||
qemu_put_be32s(f, &s->ovl2c[i]);
|
||||
qemu_put_be32s(f, &s->ccr);
|
||||
qemu_put_be32s(f, &s->cmdcr);
|
||||
qemu_put_be32s(f, &s->trgbr);
|
||||
qemu_put_be32s(f, &s->tcr);
|
||||
qemu_put_be32s(f, &s->liidr);
|
||||
qemu_put_8s(f, &s->bscntr);
|
||||
|
||||
for (i = 0; i < 7; i ++) {
|
||||
qemu_put_betl(f, s->dma_ch[i].branch);
|
||||
qemu_put_byte(f, s->dma_ch[i].up);
|
||||
qemu_put_buffer(f, s->dma_ch[i].pbuffer, sizeof(s->dma_ch[i].pbuffer));
|
||||
|
||||
qemu_put_betl(f, s->dma_ch[i].descriptor);
|
||||
qemu_put_betl(f, s->dma_ch[i].source);
|
||||
qemu_put_be32s(f, &s->dma_ch[i].id);
|
||||
qemu_put_be32s(f, &s->dma_ch[i].command);
|
||||
}
|
||||
}
|
||||
|
||||
static int pxa2xx_lcdc_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
|
||||
int i;
|
||||
|
||||
s->irqlevel = qemu_get_be32(f);
|
||||
s->transp = qemu_get_be32(f);
|
||||
|
||||
for (i = 0; i < 6; i ++)
|
||||
qemu_get_be32s(f, &s->control[i]);
|
||||
for (i = 0; i < 2; i ++)
|
||||
qemu_get_be32s(f, &s->status[i]);
|
||||
for (i = 0; i < 2; i ++)
|
||||
qemu_get_be32s(f, &s->ovl1c[i]);
|
||||
for (i = 0; i < 2; i ++)
|
||||
qemu_get_be32s(f, &s->ovl2c[i]);
|
||||
qemu_get_be32s(f, &s->ccr);
|
||||
qemu_get_be32s(f, &s->cmdcr);
|
||||
qemu_get_be32s(f, &s->trgbr);
|
||||
qemu_get_be32s(f, &s->tcr);
|
||||
qemu_get_be32s(f, &s->liidr);
|
||||
qemu_get_8s(f, &s->bscntr);
|
||||
|
||||
for (i = 0; i < 7; i ++) {
|
||||
s->dma_ch[i].branch = qemu_get_betl(f);
|
||||
s->dma_ch[i].up = qemu_get_byte(f);
|
||||
qemu_get_buffer(f, s->dma_ch[i].pbuffer, sizeof(s->dma_ch[i].pbuffer));
|
||||
|
||||
s->dma_ch[i].descriptor = qemu_get_betl(f);
|
||||
s->dma_ch[i].source = qemu_get_betl(f);
|
||||
qemu_get_be32s(f, &s->dma_ch[i].id);
|
||||
qemu_get_be32s(f, &s->dma_ch[i].command);
|
||||
}
|
||||
|
||||
s->bpp = LCCR3_BPP(s->control[3]);
|
||||
s->xres = s->yres = s->pal_for = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BITS 8
|
||||
#include "pxa2xx_template.h"
|
||||
#define BITS 15
|
||||
@ -989,6 +1064,10 @@ struct pxa2xx_lcdc_s *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq,
|
||||
fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
register_savevm("pxa2xx_lcdc", 0, 0,
|
||||
pxa2xx_lcdc_save, pxa2xx_lcdc_load, s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -443,6 +443,84 @@ static CPUWriteMemoryFunc *pxa2xx_mmci_writefn[] = {
|
||||
pxa2xx_mmci_writew
|
||||
};
|
||||
|
||||
static void pxa2xx_mmci_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
struct pxa2xx_mmci_s *s = (struct pxa2xx_mmci_s *) opaque;
|
||||
int i;
|
||||
|
||||
qemu_put_be32s(f, &s->status);
|
||||
qemu_put_be32s(f, &s->clkrt);
|
||||
qemu_put_be32s(f, &s->spi);
|
||||
qemu_put_be32s(f, &s->cmdat);
|
||||
qemu_put_be32s(f, &s->resp_tout);
|
||||
qemu_put_be32s(f, &s->read_tout);
|
||||
qemu_put_be32(f, s->blklen);
|
||||
qemu_put_be32(f, s->numblk);
|
||||
qemu_put_be32s(f, &s->intmask);
|
||||
qemu_put_be32s(f, &s->intreq);
|
||||
qemu_put_be32(f, s->cmd);
|
||||
qemu_put_be32s(f, &s->arg);
|
||||
qemu_put_be32(f, s->cmdreq);
|
||||
qemu_put_be32(f, s->active);
|
||||
qemu_put_be32(f, s->bytesleft);
|
||||
|
||||
qemu_put_byte(f, s->tx_len);
|
||||
for (i = 0; i < s->tx_len; i ++)
|
||||
qemu_put_byte(f, s->tx_fifo[(s->tx_start + i) & 63]);
|
||||
|
||||
qemu_put_byte(f, s->rx_len);
|
||||
for (i = 0; i < s->rx_len; i ++)
|
||||
qemu_put_byte(f, s->rx_fifo[(s->rx_start + i) & 31]);
|
||||
|
||||
qemu_put_byte(f, s->resp_len);
|
||||
for (i = s->resp_len; i < 9; i ++)
|
||||
qemu_put_be16s(f, &s->resp_fifo[i]);
|
||||
}
|
||||
|
||||
static int pxa2xx_mmci_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
struct pxa2xx_mmci_s *s = (struct pxa2xx_mmci_s *) opaque;
|
||||
int i;
|
||||
|
||||
qemu_get_be32s(f, &s->status);
|
||||
qemu_get_be32s(f, &s->clkrt);
|
||||
qemu_get_be32s(f, &s->spi);
|
||||
qemu_get_be32s(f, &s->cmdat);
|
||||
qemu_get_be32s(f, &s->resp_tout);
|
||||
qemu_get_be32s(f, &s->read_tout);
|
||||
s->blklen = qemu_get_be32(f);
|
||||
s->numblk = qemu_get_be32(f);
|
||||
qemu_get_be32s(f, &s->intmask);
|
||||
qemu_get_be32s(f, &s->intreq);
|
||||
s->cmd = qemu_get_be32(f);
|
||||
qemu_get_be32s(f, &s->arg);
|
||||
s->cmdreq = qemu_get_be32(f);
|
||||
s->active = qemu_get_be32(f);
|
||||
s->bytesleft = qemu_get_be32(f);
|
||||
|
||||
s->tx_len = qemu_get_byte(f);
|
||||
s->tx_start = 0;
|
||||
if (s->tx_len >= sizeof(s->tx_fifo) || s->tx_len < 0)
|
||||
return -EINVAL;
|
||||
for (i = 0; i < s->tx_len; i ++)
|
||||
s->tx_fifo[i] = qemu_get_byte(f);
|
||||
|
||||
s->rx_len = qemu_get_byte(f);
|
||||
s->rx_start = 0;
|
||||
if (s->rx_len >= sizeof(s->rx_fifo) || s->rx_len < 0)
|
||||
return -EINVAL;
|
||||
for (i = 0; i < s->rx_len; i ++)
|
||||
s->rx_fifo[i] = qemu_get_byte(f);
|
||||
|
||||
s->resp_len = qemu_get_byte(f);
|
||||
if (s->resp_len > 9 || s->resp_len < 0)
|
||||
return -EINVAL;
|
||||
for (i = s->resp_len; i < 9; i ++)
|
||||
qemu_get_be16s(f, &s->resp_fifo[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct pxa2xx_mmci_s *pxa2xx_mmci_init(target_phys_addr_t base,
|
||||
qemu_irq irq, void *dma)
|
||||
{
|
||||
@ -461,6 +539,9 @@ struct pxa2xx_mmci_s *pxa2xx_mmci_init(target_phys_addr_t base,
|
||||
/* Instantiate the actual storage */
|
||||
s->card = sd_init(sd_bdrv);
|
||||
|
||||
register_savevm("pxa2xx_mmci", 0, 0,
|
||||
pxa2xx_mmci_save, pxa2xx_mmci_load, s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -245,6 +245,41 @@ static CPUWriteMemoryFunc *pxa2xx_pic_writefn[] = {
|
||||
pxa2xx_pic_mem_write,
|
||||
};
|
||||
|
||||
static void pxa2xx_pic_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
struct pxa2xx_pic_state_s *s = (struct pxa2xx_pic_state_s *) opaque;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i ++)
|
||||
qemu_put_be32s(f, &s->int_enabled[i]);
|
||||
for (i = 0; i < 2; i ++)
|
||||
qemu_put_be32s(f, &s->int_pending[i]);
|
||||
for (i = 0; i < 2; i ++)
|
||||
qemu_put_be32s(f, &s->is_fiq[i]);
|
||||
qemu_put_be32s(f, &s->int_idle);
|
||||
for (i = 0; i < PXA2XX_PIC_SRCS; i ++)
|
||||
qemu_put_be32s(f, &s->priority[i]);
|
||||
}
|
||||
|
||||
static int pxa2xx_pic_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
struct pxa2xx_pic_state_s *s = (struct pxa2xx_pic_state_s *) opaque;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i ++)
|
||||
qemu_get_be32s(f, &s->int_enabled[i]);
|
||||
for (i = 0; i < 2; i ++)
|
||||
qemu_get_be32s(f, &s->int_pending[i]);
|
||||
for (i = 0; i < 2; i ++)
|
||||
qemu_get_be32s(f, &s->is_fiq[i]);
|
||||
qemu_get_be32s(f, &s->int_idle);
|
||||
for (i = 0; i < PXA2XX_PIC_SRCS; i ++)
|
||||
qemu_get_be32s(f, &s->priority[i]);
|
||||
|
||||
pxa2xx_pic_update(opaque);
|
||||
return 0;
|
||||
}
|
||||
|
||||
qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env)
|
||||
{
|
||||
struct pxa2xx_pic_state_s *s;
|
||||
@ -276,5 +311,7 @@ qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env)
|
||||
/* Enable IC coprocessor access. */
|
||||
cpu_arm_set_cp_io(env, 6, pxa2xx_pic_cp_read, pxa2xx_pic_cp_write, s);
|
||||
|
||||
register_savevm("pxa2xx_pic", 0, 0, pxa2xx_pic_save, pxa2xx_pic_load, s);
|
||||
|
||||
return qi;
|
||||
}
|
||||
|
@ -364,6 +364,73 @@ static void pxa2xx_timer_tick4(void *opaque)
|
||||
pxa2xx_timer_update4(i, qemu_get_clock(vm_clock), t->tm.num - 4);
|
||||
}
|
||||
|
||||
static void pxa2xx_timer_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
|
||||
int i;
|
||||
|
||||
qemu_put_be32s(f, &s->clock);
|
||||
qemu_put_be32s(f, &s->oldclock);
|
||||
qemu_put_be64s(f, &s->lastload);
|
||||
|
||||
for (i = 0; i < 4; i ++) {
|
||||
qemu_put_be32s(f, &s->timer[i].value);
|
||||
qemu_put_be32(f, s->timer[i].level);
|
||||
}
|
||||
if (s->tm4)
|
||||
for (i = 0; i < 8; i ++) {
|
||||
qemu_put_be32s(f, &s->tm4[i].tm.value);
|
||||
qemu_put_be32(f, s->tm4[i].tm.level);
|
||||
qemu_put_be32s(f, &s->tm4[i].oldclock);
|
||||
qemu_put_be32s(f, &s->tm4[i].clock);
|
||||
qemu_put_be64s(f, &s->tm4[i].lastload);
|
||||
qemu_put_be32s(f, &s->tm4[i].freq);
|
||||
qemu_put_be32s(f, &s->tm4[i].control);
|
||||
}
|
||||
|
||||
qemu_put_be32s(f, &s->events);
|
||||
qemu_put_be32s(f, &s->irq_enabled);
|
||||
qemu_put_be32s(f, &s->reset3);
|
||||
qemu_put_be32s(f, &s->snapshot);
|
||||
}
|
||||
|
||||
static int pxa2xx_timer_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
|
||||
int64_t now;
|
||||
int i;
|
||||
|
||||
qemu_get_be32s(f, &s->clock);
|
||||
qemu_get_be32s(f, &s->oldclock);
|
||||
qemu_get_be64s(f, &s->lastload);
|
||||
|
||||
now = qemu_get_clock(vm_clock);
|
||||
for (i = 0; i < 4; i ++) {
|
||||
qemu_get_be32s(f, &s->timer[i].value);
|
||||
s->timer[i].level = qemu_get_be32(f);
|
||||
}
|
||||
pxa2xx_timer_update(s, now);
|
||||
|
||||
if (s->tm4)
|
||||
for (i = 0; i < 8; i ++) {
|
||||
qemu_get_be32s(f, &s->tm4[i].tm.value);
|
||||
s->tm4[i].tm.level = qemu_get_be32(f);
|
||||
qemu_get_be32s(f, &s->tm4[i].oldclock);
|
||||
qemu_get_be32s(f, &s->tm4[i].clock);
|
||||
qemu_get_be64s(f, &s->tm4[i].lastload);
|
||||
qemu_get_be32s(f, &s->tm4[i].freq);
|
||||
qemu_get_be32s(f, &s->tm4[i].control);
|
||||
pxa2xx_timer_update4(s, now, i);
|
||||
}
|
||||
|
||||
qemu_get_be32s(f, &s->events);
|
||||
qemu_get_be32s(f, &s->irq_enabled);
|
||||
qemu_get_be32s(f, &s->reset3);
|
||||
qemu_get_be32s(f, &s->snapshot);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base,
|
||||
qemu_irq *irqs)
|
||||
{
|
||||
@ -392,6 +459,10 @@ static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base,
|
||||
iomemtype = cpu_register_io_memory(0, pxa2xx_timer_readfn,
|
||||
pxa2xx_timer_writefn, s);
|
||||
cpu_register_physical_memory(base, 0x00000fff, iomemtype);
|
||||
|
||||
register_savevm("pxa2xx_timer", 0, 0,
|
||||
pxa2xx_timer_save, pxa2xx_timer_load, s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
115
hw/spitz.c
115
hw/spitz.c
@ -109,6 +109,24 @@ static void sl_writeb(void *opaque, target_phys_addr_t addr,
|
||||
}
|
||||
}
|
||||
|
||||
static void sl_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
struct sl_nand_s *s = (struct sl_nand_s *) opaque;
|
||||
|
||||
qemu_put_8s(f, &s->ctl);
|
||||
ecc_put(f, &s->ecc);
|
||||
}
|
||||
|
||||
static int sl_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
struct sl_nand_s *s = (struct sl_nand_s *) opaque;
|
||||
|
||||
qemu_get_8s(f, &s->ctl);
|
||||
ecc_get(f, &s->ecc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum {
|
||||
FLASH_128M,
|
||||
FLASH_1024M,
|
||||
@ -140,6 +158,8 @@ static void sl_flash_register(struct pxa2xx_state_s *cpu, int size)
|
||||
iomemtype = cpu_register_io_memory(0, sl_readfn,
|
||||
sl_writefn, s);
|
||||
cpu_register_physical_memory(s->target_base, 0x40, iomemtype);
|
||||
|
||||
register_savevm("sl_flash", 0, 0, sl_save, sl_load, s);
|
||||
}
|
||||
|
||||
/* Spitz Keyboard */
|
||||
@ -406,6 +426,38 @@ static void spitz_keyboard_pre_map(struct spitz_keyboard_s *s)
|
||||
#undef CTRL
|
||||
#undef FN
|
||||
|
||||
static void spitz_keyboard_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
struct spitz_keyboard_s *s = (struct spitz_keyboard_s *) opaque;
|
||||
int i;
|
||||
|
||||
qemu_put_be16s(f, &s->sense_state);
|
||||
qemu_put_be16s(f, &s->strobe_state);
|
||||
for (i = 0; i < 5; i ++)
|
||||
qemu_put_byte(f, spitz_gpio_invert[i]);
|
||||
}
|
||||
|
||||
static int spitz_keyboard_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
struct spitz_keyboard_s *s = (struct spitz_keyboard_s *) opaque;
|
||||
int i;
|
||||
|
||||
qemu_get_be16s(f, &s->sense_state);
|
||||
qemu_get_be16s(f, &s->strobe_state);
|
||||
for (i = 0; i < 5; i ++)
|
||||
spitz_gpio_invert[i] = qemu_get_byte(f);
|
||||
|
||||
/* Release all pressed keys */
|
||||
memset(s->keyrow, 0, sizeof(s->keyrow));
|
||||
spitz_keyboard_sense_update(s);
|
||||
s->modifiers = 0;
|
||||
s->imodifiers = 0;
|
||||
s->fifopos = 0;
|
||||
s->fifolen = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spitz_keyboard_register(struct pxa2xx_state_s *cpu)
|
||||
{
|
||||
int i, j;
|
||||
@ -429,6 +481,9 @@ static void spitz_keyboard_register(struct pxa2xx_state_s *cpu)
|
||||
|
||||
spitz_keyboard_pre_map(s);
|
||||
qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s);
|
||||
|
||||
register_savevm("spitz_keyboard", 0, 0,
|
||||
spitz_keyboard_save, spitz_keyboard_load, s);
|
||||
}
|
||||
|
||||
/* SCOOP devices */
|
||||
@ -597,6 +652,42 @@ static inline void scoop_gpio_handler_set(struct scoop_info_s *s, int line,
|
||||
s->handler[line].opaque = opaque;
|
||||
}
|
||||
|
||||
static void scoop_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
struct scoop_info_s *s = (struct scoop_info_s *) opaque;
|
||||
qemu_put_be16s(f, &s->status);
|
||||
qemu_put_be16s(f, &s->power);
|
||||
qemu_put_be32s(f, &s->gpio_level);
|
||||
qemu_put_be32s(f, &s->gpio_dir);
|
||||
qemu_put_be32s(f, &s->prev_level);
|
||||
qemu_put_be16s(f, &s->mcr);
|
||||
qemu_put_be16s(f, &s->cdr);
|
||||
qemu_put_be16s(f, &s->ccr);
|
||||
qemu_put_be16s(f, &s->irr);
|
||||
qemu_put_be16s(f, &s->imr);
|
||||
qemu_put_be16s(f, &s->isr);
|
||||
qemu_put_be16s(f, &s->gprr);
|
||||
}
|
||||
|
||||
static int scoop_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
struct scoop_info_s *s = (struct scoop_info_s *) opaque;
|
||||
qemu_get_be16s(f, &s->status);
|
||||
qemu_get_be16s(f, &s->power);
|
||||
qemu_get_be32s(f, &s->gpio_level);
|
||||
qemu_get_be32s(f, &s->gpio_dir);
|
||||
qemu_get_be32s(f, &s->prev_level);
|
||||
qemu_get_be16s(f, &s->mcr);
|
||||
qemu_get_be16s(f, &s->cdr);
|
||||
qemu_get_be16s(f, &s->ccr);
|
||||
qemu_get_be16s(f, &s->irr);
|
||||
qemu_get_be16s(f, &s->imr);
|
||||
qemu_get_be16s(f, &s->isr);
|
||||
qemu_get_be16s(f, &s->gprr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct scoop_info_s *spitz_scoop_init(struct pxa2xx_state_s *cpu,
|
||||
int count) {
|
||||
int iomemtype;
|
||||
@ -615,6 +706,7 @@ static struct scoop_info_s *spitz_scoop_init(struct pxa2xx_state_s *cpu,
|
||||
iomemtype = cpu_register_io_memory(0, scoop_readfn,
|
||||
scoop_writefn, &s[0]);
|
||||
cpu_register_physical_memory(s[0].target_base, 0xfff, iomemtype);
|
||||
register_savevm("scoop", 0, 0, scoop_save, scoop_load, &s[0]);
|
||||
|
||||
if (count < 2)
|
||||
return s;
|
||||
@ -622,6 +714,7 @@ static struct scoop_info_s *spitz_scoop_init(struct pxa2xx_state_s *cpu,
|
||||
iomemtype = cpu_register_io_memory(0, scoop_readfn,
|
||||
scoop_writefn, &s[1]);
|
||||
cpu_register_physical_memory(s[1].target_base, 0xfff, iomemtype);
|
||||
register_savevm("scoop", 1, 0, scoop_save, scoop_load, &s[1]);
|
||||
|
||||
return s;
|
||||
}
|
||||
@ -763,6 +856,26 @@ static void spitz_pendown_set(void *opaque, int line, int level)
|
||||
pxa2xx_gpio_set(cpu->gpio, SPITZ_GPIO_TP_INT, level);
|
||||
}
|
||||
|
||||
static void spitz_ssp_save(QEMUFile *f, void *opaque)
|
||||
{
|
||||
qemu_put_be32(f, lcd_en);
|
||||
qemu_put_be32(f, ads_en);
|
||||
qemu_put_be32(f, max_en);
|
||||
qemu_put_be32(f, bl_intensity);
|
||||
qemu_put_be32(f, bl_power);
|
||||
}
|
||||
|
||||
static int spitz_ssp_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
lcd_en = qemu_get_be32(f);
|
||||
ads_en = qemu_get_be32(f);
|
||||
max_en = qemu_get_be32(f);
|
||||
bl_intensity = qemu_get_be32(f);
|
||||
bl_power = qemu_get_be32(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spitz_ssp_attach(struct pxa2xx_state_s *cpu)
|
||||
{
|
||||
lcd_en = ads_en = max_en = 0;
|
||||
@ -786,6 +899,8 @@ static void spitz_ssp_attach(struct pxa2xx_state_s *cpu)
|
||||
|
||||
bl_intensity = 0x20;
|
||||
bl_power = 0;
|
||||
|
||||
register_savevm("spitz_ssp", 0, 0, spitz_ssp_save, spitz_ssp_load, cpu);
|
||||
}
|
||||
|
||||
/* CF Microdrive */
|
||||
|
89
hw/wm8750.c
89
hw/wm8750.c
@ -491,6 +491,93 @@ static int wm8750_rx(i2c_slave *i2c)
|
||||
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 *)
|
||||
@ -502,6 +589,8 @@ i2c_slave *wm8750_init(i2c_bus *bus, AudioState *audio)
|
||||
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;
|
||||
}
|
||||
|
||||
|
133
vl.c
133
vl.c
@ -5679,13 +5679,144 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user