Commit aa941b944500bf77f0bdbfa0a7112b4e89670ff1
1 parent
3f6c925f
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
Showing
18 changed files
with
1330 additions
and
63 deletions
ecc.h
@@ -75,3 +75,20 @@ static inline void ecc_reset(struct ecc_state_s *s) | @@ -75,3 +75,20 @@ static inline void ecc_reset(struct ecc_state_s *s) | ||
75 | s->cp = 0x00; | 75 | s->cp = 0x00; |
76 | s->count = 0; | 76 | s->count = 0; |
77 | } | 77 | } |
78 | + | ||
79 | +/* Save/restore */ | ||
80 | +static inline void ecc_put(QEMUFile *f, struct ecc_state_s *s) | ||
81 | +{ | ||
82 | + qemu_put_8s(f, &s->cp); | ||
83 | + qemu_put_be16s(f, &s->lp[0]); | ||
84 | + qemu_put_be16s(f, &s->lp[1]); | ||
85 | + qemu_put_be16s(f, &s->count); | ||
86 | +} | ||
87 | + | ||
88 | +static inline void ecc_get(QEMUFile *f, struct ecc_state_s *s) | ||
89 | +{ | ||
90 | + qemu_get_8s(f, &s->cp); | ||
91 | + qemu_get_be16s(f, &s->lp[0]); | ||
92 | + qemu_get_be16s(f, &s->lp[1]); | ||
93 | + qemu_get_be16s(f, &s->count); | ||
94 | +} |
hw/ads7846.c
@@ -104,10 +104,41 @@ static void ads7846_ts_event(void *opaque, | @@ -104,10 +104,41 @@ static void ads7846_ts_event(void *opaque, | ||
104 | if (s->pressure == !buttons_state) { | 104 | if (s->pressure == !buttons_state) { |
105 | s->pressure = !!buttons_state; | 105 | s->pressure = !!buttons_state; |
106 | 106 | ||
107 | - ads7846_int_update(s); | 107 | + ads7846_int_update(s); |
108 | } | 108 | } |
109 | } | 109 | } |
110 | 110 | ||
111 | +static void ads7846_save(QEMUFile *f, void *opaque) | ||
112 | +{ | ||
113 | + struct ads7846_state_s *s = (struct ads7846_state_s *) opaque; | ||
114 | + int i; | ||
115 | + | ||
116 | + for (i = 0; i < 8; i ++) | ||
117 | + qemu_put_be32(f, s->input[i]); | ||
118 | + qemu_put_be32(f, s->noise); | ||
119 | + qemu_put_be32(f, s->cycle); | ||
120 | + qemu_put_be32(f, s->output); | ||
121 | +} | ||
122 | + | ||
123 | +static int ads7846_load(QEMUFile *f, void *opaque, int version_id) | ||
124 | +{ | ||
125 | + struct ads7846_state_s *s = (struct ads7846_state_s *) opaque; | ||
126 | + int i; | ||
127 | + | ||
128 | + for (i = 0; i < 8; i ++) | ||
129 | + s->input[i] = qemu_get_be32(f); | ||
130 | + s->noise = qemu_get_be32(f); | ||
131 | + s->cycle = qemu_get_be32(f); | ||
132 | + s->output = qemu_get_be32(f); | ||
133 | + | ||
134 | + s->pressure = 0; | ||
135 | + ads7846_int_update(s); | ||
136 | + | ||
137 | + return 0; | ||
138 | +} | ||
139 | + | ||
140 | +static int ads7846_iid = 0; | ||
141 | + | ||
111 | struct ads7846_state_s *ads7846_init(qemu_irq penirq) | 142 | struct ads7846_state_s *ads7846_init(qemu_irq penirq) |
112 | { | 143 | { |
113 | struct ads7846_state_s *s; | 144 | struct ads7846_state_s *s; |
@@ -127,5 +158,9 @@ struct ads7846_state_s *ads7846_init(qemu_irq penirq) | @@ -127,5 +158,9 @@ struct ads7846_state_s *ads7846_init(qemu_irq penirq) | ||
127 | "QEMU ADS7846-driven Touchscreen"); | 158 | "QEMU ADS7846-driven Touchscreen"); |
128 | 159 | ||
129 | ads7846_int_update(s); | 160 | ads7846_int_update(s); |
161 | + | ||
162 | + register_savevm("ads7846", ads7846_iid ++, 0, | ||
163 | + ads7846_save, ads7846_load, s); | ||
164 | + | ||
130 | return s; | 165 | return s; |
131 | } | 166 | } |
hw/i2c.c
@@ -115,3 +115,34 @@ void i2c_nack(i2c_bus *bus) | @@ -115,3 +115,34 @@ void i2c_nack(i2c_bus *bus) | ||
115 | dev->event(dev, I2C_NACK); | 115 | dev->event(dev, I2C_NACK); |
116 | } | 116 | } |
117 | 117 | ||
118 | +void i2c_bus_save(QEMUFile *f, i2c_bus *bus) | ||
119 | +{ | ||
120 | + qemu_put_byte(f, bus->current_dev ? bus->current_dev->address : 0x00); | ||
121 | +} | ||
122 | + | ||
123 | +void i2c_bus_load(QEMUFile *f, i2c_bus *bus) | ||
124 | +{ | ||
125 | + i2c_slave *dev; | ||
126 | + uint8_t address = qemu_get_byte(f); | ||
127 | + | ||
128 | + if (address) { | ||
129 | + for (dev = bus->dev; dev; dev = dev->next) | ||
130 | + if (dev->address == address) { | ||
131 | + bus->current_dev = dev; | ||
132 | + return; | ||
133 | + } | ||
134 | + | ||
135 | + fprintf(stderr, "%s: I2C slave with address %02x disappeared\n", | ||
136 | + __FUNCTION__, address); | ||
137 | + } | ||
138 | +} | ||
139 | + | ||
140 | +void i2c_slave_save(QEMUFile *f, i2c_slave *dev) | ||
141 | +{ | ||
142 | + qemu_put_byte(f, dev->address); | ||
143 | +} | ||
144 | + | ||
145 | +void i2c_slave_load(QEMUFile *f, i2c_slave *dev) | ||
146 | +{ | ||
147 | + dev->address = qemu_get_byte(f); | ||
148 | +} |
hw/i2c.h
@@ -45,6 +45,10 @@ void i2c_end_transfer(i2c_bus *bus); | @@ -45,6 +45,10 @@ void i2c_end_transfer(i2c_bus *bus); | ||
45 | void i2c_nack(i2c_bus *bus); | 45 | void i2c_nack(i2c_bus *bus); |
46 | int i2c_send(i2c_bus *bus, uint8_t data); | 46 | int i2c_send(i2c_bus *bus, uint8_t data); |
47 | int i2c_recv(i2c_bus *bus); | 47 | int i2c_recv(i2c_bus *bus); |
48 | +void i2c_bus_save(QEMUFile *f, i2c_bus *bus); | ||
49 | +void i2c_bus_load(QEMUFile *f, i2c_bus *bus); | ||
50 | +void i2c_slave_save(QEMUFile *f, i2c_slave *dev); | ||
51 | +void i2c_slave_load(QEMUFile *f, i2c_slave *dev); | ||
48 | 52 | ||
49 | /* max7310.c */ | 53 | /* max7310.c */ |
50 | i2c_slave *max7310_init(i2c_bus *bus); | 54 | i2c_slave *max7310_init(i2c_bus *bus); |
hw/ide.c
@@ -2416,6 +2416,62 @@ static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2) | @@ -2416,6 +2416,62 @@ static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2) | ||
2416 | register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state); | 2416 | register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state); |
2417 | } | 2417 | } |
2418 | 2418 | ||
2419 | +/* save per IDE drive data */ | ||
2420 | +static void ide_save(QEMUFile* f, IDEState *s) | ||
2421 | +{ | ||
2422 | + qemu_put_be32s(f, &s->mult_sectors); | ||
2423 | + qemu_put_be32s(f, &s->identify_set); | ||
2424 | + if (s->identify_set) { | ||
2425 | + qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512); | ||
2426 | + } | ||
2427 | + qemu_put_8s(f, &s->feature); | ||
2428 | + qemu_put_8s(f, &s->error); | ||
2429 | + qemu_put_be32s(f, &s->nsector); | ||
2430 | + qemu_put_8s(f, &s->sector); | ||
2431 | + qemu_put_8s(f, &s->lcyl); | ||
2432 | + qemu_put_8s(f, &s->hcyl); | ||
2433 | + qemu_put_8s(f, &s->hob_feature); | ||
2434 | + qemu_put_8s(f, &s->hob_nsector); | ||
2435 | + qemu_put_8s(f, &s->hob_sector); | ||
2436 | + qemu_put_8s(f, &s->hob_lcyl); | ||
2437 | + qemu_put_8s(f, &s->hob_hcyl); | ||
2438 | + qemu_put_8s(f, &s->select); | ||
2439 | + qemu_put_8s(f, &s->status); | ||
2440 | + qemu_put_8s(f, &s->lba48); | ||
2441 | + | ||
2442 | + qemu_put_8s(f, &s->sense_key); | ||
2443 | + qemu_put_8s(f, &s->asc); | ||
2444 | + /* XXX: if a transfer is pending, we do not save it yet */ | ||
2445 | +} | ||
2446 | + | ||
2447 | +/* load per IDE drive data */ | ||
2448 | +static void ide_load(QEMUFile* f, IDEState *s) | ||
2449 | +{ | ||
2450 | + qemu_get_be32s(f, &s->mult_sectors); | ||
2451 | + qemu_get_be32s(f, &s->identify_set); | ||
2452 | + if (s->identify_set) { | ||
2453 | + qemu_get_buffer(f, (uint8_t *)s->identify_data, 512); | ||
2454 | + } | ||
2455 | + qemu_get_8s(f, &s->feature); | ||
2456 | + qemu_get_8s(f, &s->error); | ||
2457 | + qemu_get_be32s(f, &s->nsector); | ||
2458 | + qemu_get_8s(f, &s->sector); | ||
2459 | + qemu_get_8s(f, &s->lcyl); | ||
2460 | + qemu_get_8s(f, &s->hcyl); | ||
2461 | + qemu_get_8s(f, &s->hob_feature); | ||
2462 | + qemu_get_8s(f, &s->hob_nsector); | ||
2463 | + qemu_get_8s(f, &s->hob_sector); | ||
2464 | + qemu_get_8s(f, &s->hob_lcyl); | ||
2465 | + qemu_get_8s(f, &s->hob_hcyl); | ||
2466 | + qemu_get_8s(f, &s->select); | ||
2467 | + qemu_get_8s(f, &s->status); | ||
2468 | + qemu_get_8s(f, &s->lba48); | ||
2469 | + | ||
2470 | + qemu_get_8s(f, &s->sense_key); | ||
2471 | + qemu_get_8s(f, &s->asc); | ||
2472 | + /* XXX: if a transfer is pending, we do not save it yet */ | ||
2473 | +} | ||
2474 | + | ||
2419 | /***********************************************************/ | 2475 | /***********************************************************/ |
2420 | /* ISA IDE definitions */ | 2476 | /* ISA IDE definitions */ |
2421 | 2477 | ||
@@ -2731,30 +2787,7 @@ static void pci_ide_save(QEMUFile* f, void *opaque) | @@ -2731,30 +2787,7 @@ static void pci_ide_save(QEMUFile* f, void *opaque) | ||
2731 | 2787 | ||
2732 | /* per IDE drive data */ | 2788 | /* per IDE drive data */ |
2733 | for(i = 0; i < 4; i++) { | 2789 | for(i = 0; i < 4; i++) { |
2734 | - IDEState *s = &d->ide_if[i]; | ||
2735 | - qemu_put_be32s(f, &s->mult_sectors); | ||
2736 | - qemu_put_be32s(f, &s->identify_set); | ||
2737 | - if (s->identify_set) { | ||
2738 | - qemu_put_buffer(f, (const uint8_t *)s->identify_data, 512); | ||
2739 | - } | ||
2740 | - qemu_put_8s(f, &s->feature); | ||
2741 | - qemu_put_8s(f, &s->error); | ||
2742 | - qemu_put_be32s(f, &s->nsector); | ||
2743 | - qemu_put_8s(f, &s->sector); | ||
2744 | - qemu_put_8s(f, &s->lcyl); | ||
2745 | - qemu_put_8s(f, &s->hcyl); | ||
2746 | - qemu_put_8s(f, &s->hob_feature); | ||
2747 | - qemu_put_8s(f, &s->hob_nsector); | ||
2748 | - qemu_put_8s(f, &s->hob_sector); | ||
2749 | - qemu_put_8s(f, &s->hob_lcyl); | ||
2750 | - qemu_put_8s(f, &s->hob_hcyl); | ||
2751 | - qemu_put_8s(f, &s->select); | ||
2752 | - qemu_put_8s(f, &s->status); | ||
2753 | - qemu_put_8s(f, &s->lba48); | ||
2754 | - | ||
2755 | - qemu_put_8s(f, &s->sense_key); | ||
2756 | - qemu_put_8s(f, &s->asc); | ||
2757 | - /* XXX: if a transfer is pending, we do not save it yet */ | 2790 | + ide_save(f, &d->ide_if[i]); |
2758 | } | 2791 | } |
2759 | } | 2792 | } |
2760 | 2793 | ||
@@ -2788,30 +2821,7 @@ static int pci_ide_load(QEMUFile* f, void *opaque, int version_id) | @@ -2788,30 +2821,7 @@ static int pci_ide_load(QEMUFile* f, void *opaque, int version_id) | ||
2788 | 2821 | ||
2789 | /* per IDE drive data */ | 2822 | /* per IDE drive data */ |
2790 | for(i = 0; i < 4; i++) { | 2823 | for(i = 0; i < 4; i++) { |
2791 | - IDEState *s = &d->ide_if[i]; | ||
2792 | - qemu_get_be32s(f, &s->mult_sectors); | ||
2793 | - qemu_get_be32s(f, &s->identify_set); | ||
2794 | - if (s->identify_set) { | ||
2795 | - qemu_get_buffer(f, (uint8_t *)s->identify_data, 512); | ||
2796 | - } | ||
2797 | - qemu_get_8s(f, &s->feature); | ||
2798 | - qemu_get_8s(f, &s->error); | ||
2799 | - qemu_get_be32s(f, &s->nsector); | ||
2800 | - qemu_get_8s(f, &s->sector); | ||
2801 | - qemu_get_8s(f, &s->lcyl); | ||
2802 | - qemu_get_8s(f, &s->hcyl); | ||
2803 | - qemu_get_8s(f, &s->hob_feature); | ||
2804 | - qemu_get_8s(f, &s->hob_nsector); | ||
2805 | - qemu_get_8s(f, &s->hob_sector); | ||
2806 | - qemu_get_8s(f, &s->hob_lcyl); | ||
2807 | - qemu_get_8s(f, &s->hob_hcyl); | ||
2808 | - qemu_get_8s(f, &s->select); | ||
2809 | - qemu_get_8s(f, &s->status); | ||
2810 | - qemu_get_8s(f, &s->lba48); | ||
2811 | - | ||
2812 | - qemu_get_8s(f, &s->sense_key); | ||
2813 | - qemu_get_8s(f, &s->asc); | ||
2814 | - /* XXX: if a transfer is pending, we do not save it yet */ | 2824 | + ide_load(f, &d->ide_if[i]); |
2815 | } | 2825 | } |
2816 | return 0; | 2826 | return 0; |
2817 | } | 2827 | } |
@@ -3255,6 +3265,54 @@ static void md_common_write(void *opaque, uint32_t at, uint16_t value) | @@ -3255,6 +3265,54 @@ static void md_common_write(void *opaque, uint32_t at, uint16_t value) | ||
3255 | } | 3265 | } |
3256 | } | 3266 | } |
3257 | 3267 | ||
3268 | +static void md_save(QEMUFile *f, void *opaque) | ||
3269 | +{ | ||
3270 | + struct md_s *s = (struct md_s *) opaque; | ||
3271 | + int i; | ||
3272 | + uint8_t drive1_selected; | ||
3273 | + | ||
3274 | + qemu_put_8s(f, &s->opt); | ||
3275 | + qemu_put_8s(f, &s->stat); | ||
3276 | + qemu_put_8s(f, &s->pins); | ||
3277 | + | ||
3278 | + qemu_put_8s(f, &s->ctrl); | ||
3279 | + qemu_put_be16s(f, &s->io); | ||
3280 | + qemu_put_byte(f, s->cycle); | ||
3281 | + | ||
3282 | + drive1_selected = (s->ide->cur_drive != s->ide); | ||
3283 | + qemu_put_8s(f, &s->ide->cmd); | ||
3284 | + qemu_put_8s(f, &drive1_selected); | ||
3285 | + | ||
3286 | + for (i = 0; i < 2; i ++) | ||
3287 | + ide_save(f, &s->ide[i]); | ||
3288 | +} | ||
3289 | + | ||
3290 | +static int md_load(QEMUFile *f, void *opaque, int version_id) | ||
3291 | +{ | ||
3292 | + struct md_s *s = (struct md_s *) opaque; | ||
3293 | + int i; | ||
3294 | + uint8_t drive1_selected; | ||
3295 | + | ||
3296 | + qemu_get_8s(f, &s->opt); | ||
3297 | + qemu_get_8s(f, &s->stat); | ||
3298 | + qemu_get_8s(f, &s->pins); | ||
3299 | + | ||
3300 | + qemu_get_8s(f, &s->ctrl); | ||
3301 | + qemu_get_be16s(f, &s->io); | ||
3302 | + s->cycle = qemu_get_byte(f); | ||
3303 | + | ||
3304 | + qemu_get_8s(f, &s->ide->cmd); | ||
3305 | + qemu_get_8s(f, &drive1_selected); | ||
3306 | + s->ide->cur_drive = &s->ide[(drive1_selected != 0)]; | ||
3307 | + | ||
3308 | + for (i = 0; i < 2; i ++) | ||
3309 | + ide_load(f, &s->ide[i]); | ||
3310 | + | ||
3311 | + return 0; | ||
3312 | +} | ||
3313 | + | ||
3314 | +static int md_iid = 0; | ||
3315 | + | ||
3258 | static const uint8_t dscm1xxxx_cis[0x14a] = { | 3316 | static const uint8_t dscm1xxxx_cis[0x14a] = { |
3259 | [0x000] = CISTPL_DEVICE, /* 5V Device Information */ | 3317 | [0x000] = CISTPL_DEVICE, /* 5V Device Information */ |
3260 | [0x002] = 0x03, /* Tuple length = 4 bytes */ | 3318 | [0x002] = 0x03, /* Tuple length = 4 bytes */ |
@@ -3480,5 +3538,8 @@ struct pcmcia_card_s *dscm1xxxx_init(BlockDriverState *bdrv) | @@ -3480,5 +3538,8 @@ struct pcmcia_card_s *dscm1xxxx_init(BlockDriverState *bdrv) | ||
3480 | md->ide->is_cf = 1; | 3538 | md->ide->is_cf = 1; |
3481 | md->ide->mdata_size = METADATA_SIZE; | 3539 | md->ide->mdata_size = METADATA_SIZE; |
3482 | md->ide->mdata_storage = (uint8_t *) qemu_mallocz(METADATA_SIZE); | 3540 | md->ide->mdata_storage = (uint8_t *) qemu_mallocz(METADATA_SIZE); |
3541 | + | ||
3542 | + register_savevm("microdrive", md_iid ++, 0, md_save, md_load, md); | ||
3543 | + | ||
3483 | return &md->card; | 3544 | return &md->card; |
3484 | } | 3545 | } |
hw/max111x.c
@@ -89,6 +89,39 @@ void max111x_write(void *opaque, uint32_t value) | @@ -89,6 +89,39 @@ void max111x_write(void *opaque, uint32_t value) | ||
89 | qemu_irq_raise(s->interrupt); | 89 | qemu_irq_raise(s->interrupt); |
90 | } | 90 | } |
91 | 91 | ||
92 | +static void max111x_save(QEMUFile *f, void *opaque) | ||
93 | +{ | ||
94 | + struct max111x_s *s = (struct max111x_s *) opaque; | ||
95 | + int i; | ||
96 | + | ||
97 | + qemu_put_8s(f, &s->tb1); | ||
98 | + qemu_put_8s(f, &s->rb2); | ||
99 | + qemu_put_8s(f, &s->rb3); | ||
100 | + qemu_put_be32(f, s->inputs); | ||
101 | + qemu_put_be32(f, s->com); | ||
102 | + for (i = 0; i < s->inputs; i ++) | ||
103 | + qemu_put_byte(f, s->input[i]); | ||
104 | +} | ||
105 | + | ||
106 | +static int max111x_load(QEMUFile *f, void *opaque, int version_id) | ||
107 | +{ | ||
108 | + struct max111x_s *s = (struct max111x_s *) opaque; | ||
109 | + int i; | ||
110 | + | ||
111 | + qemu_get_8s(f, &s->tb1); | ||
112 | + qemu_get_8s(f, &s->rb2); | ||
113 | + qemu_get_8s(f, &s->rb3); | ||
114 | + if (s->inputs != qemu_get_be32(f)) | ||
115 | + return -EINVAL; | ||
116 | + s->com = qemu_get_be32(f); | ||
117 | + for (i = 0; i < s->inputs; i ++) | ||
118 | + s->input[i] = qemu_get_byte(f); | ||
119 | + | ||
120 | + return 0; | ||
121 | +} | ||
122 | + | ||
123 | +static int max111x_iid = 0; | ||
124 | + | ||
92 | static struct max111x_s *max111x_init(qemu_irq cb) | 125 | static struct max111x_s *max111x_init(qemu_irq cb) |
93 | { | 126 | { |
94 | struct max111x_s *s; | 127 | struct max111x_s *s; |
@@ -108,6 +141,10 @@ static struct max111x_s *max111x_init(qemu_irq cb) | @@ -108,6 +141,10 @@ static struct max111x_s *max111x_init(qemu_irq cb) | ||
108 | s->input[6] = 0x90; | 141 | s->input[6] = 0x90; |
109 | s->input[7] = 0x80; | 142 | s->input[7] = 0x80; |
110 | s->com = 0; | 143 | s->com = 0; |
144 | + | ||
145 | + register_savevm("max111x", max111x_iid ++, 0, | ||
146 | + max111x_save, max111x_load, s); | ||
147 | + | ||
111 | return s; | 148 | return s; |
112 | } | 149 | } |
113 | 150 |
hw/max7310.c
@@ -143,6 +143,41 @@ static void max7310_event(i2c_slave *i2c, enum i2c_event event) | @@ -143,6 +143,41 @@ static void max7310_event(i2c_slave *i2c, enum i2c_event event) | ||
143 | } | 143 | } |
144 | } | 144 | } |
145 | 145 | ||
146 | +static void max7310_save(QEMUFile *f, void *opaque) | ||
147 | +{ | ||
148 | + struct max7310_s *s = (struct max7310_s *) opaque; | ||
149 | + | ||
150 | + qemu_put_be32(f, s->i2c_command_byte); | ||
151 | + qemu_put_be32(f, s->len); | ||
152 | + | ||
153 | + qemu_put_8s(f, &s->level); | ||
154 | + qemu_put_8s(f, &s->direction); | ||
155 | + qemu_put_8s(f, &s->polarity); | ||
156 | + qemu_put_8s(f, &s->status); | ||
157 | + qemu_put_8s(f, &s->command); | ||
158 | + | ||
159 | + i2c_slave_save(f, &s->i2c); | ||
160 | +} | ||
161 | + | ||
162 | +static int max7310_load(QEMUFile *f, void *opaque, int version_id) | ||
163 | +{ | ||
164 | + struct max7310_s *s = (struct max7310_s *) opaque; | ||
165 | + | ||
166 | + s->i2c_command_byte = qemu_get_be32(f); | ||
167 | + s->len = qemu_get_be32(f); | ||
168 | + | ||
169 | + qemu_get_8s(f, &s->level); | ||
170 | + qemu_get_8s(f, &s->direction); | ||
171 | + qemu_get_8s(f, &s->polarity); | ||
172 | + qemu_get_8s(f, &s->status); | ||
173 | + qemu_get_8s(f, &s->command); | ||
174 | + | ||
175 | + i2c_slave_load(f, &s->i2c); | ||
176 | + return 0; | ||
177 | +} | ||
178 | + | ||
179 | +static int max7310_iid = 0; | ||
180 | + | ||
146 | static void max7310_gpio_set(void *opaque, int line, int level) | 181 | static void max7310_gpio_set(void *opaque, int line, int level) |
147 | { | 182 | { |
148 | struct max7310_s *s = (struct max7310_s *) opaque; | 183 | struct max7310_s *s = (struct max7310_s *) opaque; |
@@ -169,6 +204,9 @@ struct i2c_slave *max7310_init(i2c_bus *bus) | @@ -169,6 +204,9 @@ struct i2c_slave *max7310_init(i2c_bus *bus) | ||
169 | 204 | ||
170 | max7310_reset(&s->i2c); | 205 | max7310_reset(&s->i2c); |
171 | 206 | ||
207 | + register_savevm("max7310", max7310_iid ++, 0, | ||
208 | + max7310_save, max7310_load, s); | ||
209 | + | ||
172 | return &s->i2c; | 210 | return &s->i2c; |
173 | } | 211 | } |
174 | 212 |
hw/nand.c
@@ -273,6 +273,50 @@ static void nand_command(struct nand_flash_s *s) | @@ -273,6 +273,50 @@ static void nand_command(struct nand_flash_s *s) | ||
273 | } | 273 | } |
274 | } | 274 | } |
275 | 275 | ||
276 | +static void nand_save(QEMUFile *f, void *opaque) | ||
277 | +{ | ||
278 | + struct nand_flash_s *s = (struct nand_flash_s *) opaque; | ||
279 | + qemu_put_byte(f, s->cle); | ||
280 | + qemu_put_byte(f, s->ale); | ||
281 | + qemu_put_byte(f, s->ce); | ||
282 | + qemu_put_byte(f, s->wp); | ||
283 | + qemu_put_byte(f, s->gnd); | ||
284 | + qemu_put_buffer(f, s->io, sizeof(s->io)); | ||
285 | + qemu_put_be32(f, s->ioaddr - s->io); | ||
286 | + qemu_put_be32(f, s->iolen); | ||
287 | + | ||
288 | + qemu_put_be32s(f, &s->cmd); | ||
289 | + qemu_put_be32s(f, &s->addr); | ||
290 | + qemu_put_be32(f, s->addrlen); | ||
291 | + qemu_put_be32(f, s->status); | ||
292 | + qemu_put_be32(f, s->offset); | ||
293 | + /* XXX: do we want to save s->storage too? */ | ||
294 | +} | ||
295 | + | ||
296 | +static int nand_load(QEMUFile *f, void *opaque, int version_id) | ||
297 | +{ | ||
298 | + struct nand_flash_s *s = (struct nand_flash_s *) opaque; | ||
299 | + s->cle = qemu_get_byte(f); | ||
300 | + s->ale = qemu_get_byte(f); | ||
301 | + s->ce = qemu_get_byte(f); | ||
302 | + s->wp = qemu_get_byte(f); | ||
303 | + s->gnd = qemu_get_byte(f); | ||
304 | + qemu_get_buffer(f, s->io, sizeof(s->io)); | ||
305 | + s->ioaddr = s->io + qemu_get_be32(f); | ||
306 | + s->iolen = qemu_get_be32(f); | ||
307 | + if (s->ioaddr >= s->io + sizeof(s->io) || s->ioaddr < s->io) | ||
308 | + return -EINVAL; | ||
309 | + | ||
310 | + qemu_get_be32s(f, &s->cmd); | ||
311 | + qemu_get_be32s(f, &s->addr); | ||
312 | + s->addrlen = qemu_get_be32(f); | ||
313 | + s->status = qemu_get_be32(f); | ||
314 | + s->offset = qemu_get_be32(f); | ||
315 | + return 0; | ||
316 | +} | ||
317 | + | ||
318 | +static int nand_iid = 0; | ||
319 | + | ||
276 | /* | 320 | /* |
277 | * Chip inputs are CLE, ALE, CE, WP, GND and eight I/O pins. Chip | 321 | * Chip inputs are CLE, ALE, CE, WP, GND and eight I/O pins. Chip |
278 | * outputs are R/B and eight I/O pins. | 322 | * 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) | @@ -443,6 +487,9 @@ struct nand_flash_s *nand_init(int manf_id, int chip_id) | ||
443 | if (pagesize) | 487 | if (pagesize) |
444 | s->storage = (uint8_t *) memset(qemu_malloc(s->pages * pagesize), | 488 | s->storage = (uint8_t *) memset(qemu_malloc(s->pages * pagesize), |
445 | 0xff, s->pages * pagesize); | 489 | 0xff, s->pages * pagesize); |
490 | + | ||
491 | + register_savevm("nand", nand_iid ++, 0, nand_save, nand_load, s); | ||
492 | + | ||
446 | return s; | 493 | return s; |
447 | } | 494 | } |
448 | 495 |
hw/pxa2xx.c
@@ -141,6 +141,26 @@ static CPUWriteMemoryFunc *pxa2xx_pm_writefn[] = { | @@ -141,6 +141,26 @@ static CPUWriteMemoryFunc *pxa2xx_pm_writefn[] = { | ||
141 | pxa2xx_pm_write, | 141 | pxa2xx_pm_write, |
142 | }; | 142 | }; |
143 | 143 | ||
144 | +static void pxa2xx_pm_save(QEMUFile *f, void *opaque) | ||
145 | +{ | ||
146 | + struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; | ||
147 | + int i; | ||
148 | + | ||
149 | + for (i = 0; i < 0x40; i ++) | ||
150 | + qemu_put_be32s(f, &s->pm_regs[i]); | ||
151 | +} | ||
152 | + | ||
153 | +static int pxa2xx_pm_load(QEMUFile *f, void *opaque, int version_id) | ||
154 | +{ | ||
155 | + struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; | ||
156 | + int i; | ||
157 | + | ||
158 | + for (i = 0; i < 0x40; i ++) | ||
159 | + qemu_get_be32s(f, &s->pm_regs[i]); | ||
160 | + | ||
161 | + return 0; | ||
162 | +} | ||
163 | + | ||
144 | #define CCCR 0x00 /* Core Clock Configuration register */ | 164 | #define CCCR 0x00 /* Core Clock Configuration register */ |
145 | #define CKEN 0x04 /* Clock Enable register */ | 165 | #define CKEN 0x04 /* Clock Enable register */ |
146 | #define OSCC 0x08 /* Oscillator Configuration register */ | 166 | #define OSCC 0x08 /* Oscillator Configuration register */ |
@@ -204,6 +224,30 @@ static CPUWriteMemoryFunc *pxa2xx_cm_writefn[] = { | @@ -204,6 +224,30 @@ static CPUWriteMemoryFunc *pxa2xx_cm_writefn[] = { | ||
204 | pxa2xx_cm_write, | 224 | pxa2xx_cm_write, |
205 | }; | 225 | }; |
206 | 226 | ||
227 | +static void pxa2xx_cm_save(QEMUFile *f, void *opaque) | ||
228 | +{ | ||
229 | + struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; | ||
230 | + int i; | ||
231 | + | ||
232 | + for (i = 0; i < 4; i ++) | ||
233 | + qemu_put_be32s(f, &s->cm_regs[i]); | ||
234 | + qemu_put_be32s(f, &s->clkcfg); | ||
235 | + qemu_put_be32s(f, &s->pmnc); | ||
236 | +} | ||
237 | + | ||
238 | +static int pxa2xx_cm_load(QEMUFile *f, void *opaque, int version_id) | ||
239 | +{ | ||
240 | + struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; | ||
241 | + int i; | ||
242 | + | ||
243 | + for (i = 0; i < 4; i ++) | ||
244 | + qemu_get_be32s(f, &s->cm_regs[i]); | ||
245 | + qemu_get_be32s(f, &s->clkcfg); | ||
246 | + qemu_get_be32s(f, &s->pmnc); | ||
247 | + | ||
248 | + return 0; | ||
249 | +} | ||
250 | + | ||
207 | static uint32_t pxa2xx_clkpwr_read(void *opaque, int op2, int reg, int crm) | 251 | static uint32_t pxa2xx_clkpwr_read(void *opaque, int op2, int reg, int crm) |
208 | { | 252 | { |
209 | struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; | 253 | struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; |
@@ -482,6 +526,26 @@ static CPUWriteMemoryFunc *pxa2xx_mm_writefn[] = { | @@ -482,6 +526,26 @@ static CPUWriteMemoryFunc *pxa2xx_mm_writefn[] = { | ||
482 | pxa2xx_mm_write, | 526 | pxa2xx_mm_write, |
483 | }; | 527 | }; |
484 | 528 | ||
529 | +static void pxa2xx_mm_save(QEMUFile *f, void *opaque) | ||
530 | +{ | ||
531 | + struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; | ||
532 | + int i; | ||
533 | + | ||
534 | + for (i = 0; i < 0x1a; i ++) | ||
535 | + qemu_put_be32s(f, &s->mm_regs[i]); | ||
536 | +} | ||
537 | + | ||
538 | +static int pxa2xx_mm_load(QEMUFile *f, void *opaque, int version_id) | ||
539 | +{ | ||
540 | + struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; | ||
541 | + int i; | ||
542 | + | ||
543 | + for (i = 0; i < 0x1a; i ++) | ||
544 | + qemu_get_be32s(f, &s->mm_regs[i]); | ||
545 | + | ||
546 | + return 0; | ||
547 | +} | ||
548 | + | ||
485 | /* Synchronous Serial Ports */ | 549 | /* Synchronous Serial Ports */ |
486 | struct pxa2xx_ssp_s { | 550 | struct pxa2xx_ssp_s { |
487 | target_phys_addr_t base; | 551 | target_phys_addr_t base; |
@@ -761,6 +825,53 @@ static CPUWriteMemoryFunc *pxa2xx_ssp_writefn[] = { | @@ -761,6 +825,53 @@ static CPUWriteMemoryFunc *pxa2xx_ssp_writefn[] = { | ||
761 | pxa2xx_ssp_write, | 825 | pxa2xx_ssp_write, |
762 | }; | 826 | }; |
763 | 827 | ||
828 | +static void pxa2xx_ssp_save(QEMUFile *f, void *opaque) | ||
829 | +{ | ||
830 | + struct pxa2xx_ssp_s *s = (struct pxa2xx_ssp_s *) opaque; | ||
831 | + int i; | ||
832 | + | ||
833 | + qemu_put_be32(f, s->enable); | ||
834 | + | ||
835 | + qemu_put_be32s(f, &s->sscr[0]); | ||
836 | + qemu_put_be32s(f, &s->sscr[1]); | ||
837 | + qemu_put_be32s(f, &s->sspsp); | ||
838 | + qemu_put_be32s(f, &s->ssto); | ||
839 | + qemu_put_be32s(f, &s->ssitr); | ||
840 | + qemu_put_be32s(f, &s->sssr); | ||
841 | + qemu_put_8s(f, &s->sstsa); | ||
842 | + qemu_put_8s(f, &s->ssrsa); | ||
843 | + qemu_put_8s(f, &s->ssacd); | ||
844 | + | ||
845 | + qemu_put_byte(f, s->rx_level); | ||
846 | + for (i = 0; i < s->rx_level; i ++) | ||
847 | + qemu_put_byte(f, s->rx_fifo[(s->rx_start + i) & 0xf]); | ||
848 | +} | ||
849 | + | ||
850 | +static int pxa2xx_ssp_load(QEMUFile *f, void *opaque, int version_id) | ||
851 | +{ | ||
852 | + struct pxa2xx_ssp_s *s = (struct pxa2xx_ssp_s *) opaque; | ||
853 | + int i; | ||
854 | + | ||
855 | + s->enable = qemu_get_be32(f); | ||
856 | + | ||
857 | + qemu_get_be32s(f, &s->sscr[0]); | ||
858 | + qemu_get_be32s(f, &s->sscr[1]); | ||
859 | + qemu_get_be32s(f, &s->sspsp); | ||
860 | + qemu_get_be32s(f, &s->ssto); | ||
861 | + qemu_get_be32s(f, &s->ssitr); | ||
862 | + qemu_get_be32s(f, &s->sssr); | ||
863 | + qemu_get_8s(f, &s->sstsa); | ||
864 | + qemu_get_8s(f, &s->ssrsa); | ||
865 | + qemu_get_8s(f, &s->ssacd); | ||
866 | + | ||
867 | + s->rx_level = qemu_get_byte(f); | ||
868 | + s->rx_start = 0; | ||
869 | + for (i = 0; i < s->rx_level; i ++) | ||
870 | + s->rx_fifo[i] = qemu_get_byte(f); | ||
871 | + | ||
872 | + return 0; | ||
873 | +} | ||
874 | + | ||
764 | /* Real-Time Clock */ | 875 | /* Real-Time Clock */ |
765 | #define RCNR 0x00 /* RTC Counter register */ | 876 | #define RCNR 0x00 /* RTC Counter register */ |
766 | #define RTAR 0x04 /* RTC Alarm register */ | 877 | #define RTAR 0x04 /* RTC Alarm register */ |
@@ -1052,7 +1163,19 @@ static void pxa2xx_rtc_write(void *opaque, target_phys_addr_t addr, | @@ -1052,7 +1163,19 @@ static void pxa2xx_rtc_write(void *opaque, target_phys_addr_t addr, | ||
1052 | } | 1163 | } |
1053 | } | 1164 | } |
1054 | 1165 | ||
1055 | -static void pxa2xx_rtc_reset(struct pxa2xx_state_s *s) | 1166 | +static CPUReadMemoryFunc *pxa2xx_rtc_readfn[] = { |
1167 | + pxa2xx_rtc_read, | ||
1168 | + pxa2xx_rtc_read, | ||
1169 | + pxa2xx_rtc_read, | ||
1170 | +}; | ||
1171 | + | ||
1172 | +static CPUWriteMemoryFunc *pxa2xx_rtc_writefn[] = { | ||
1173 | + pxa2xx_rtc_write, | ||
1174 | + pxa2xx_rtc_write, | ||
1175 | + pxa2xx_rtc_write, | ||
1176 | +}; | ||
1177 | + | ||
1178 | +static void pxa2xx_rtc_init(struct pxa2xx_state_s *s) | ||
1056 | { | 1179 | { |
1057 | struct tm *tm; | 1180 | struct tm *tm; |
1058 | time_t ti; | 1181 | time_t ti; |
@@ -1086,17 +1209,61 @@ static void pxa2xx_rtc_reset(struct pxa2xx_state_s *s) | @@ -1086,17 +1209,61 @@ static void pxa2xx_rtc_reset(struct pxa2xx_state_s *s) | ||
1086 | s->rtc_pi = qemu_new_timer(rt_clock, pxa2xx_rtc_pi_tick, s); | 1209 | s->rtc_pi = qemu_new_timer(rt_clock, pxa2xx_rtc_pi_tick, s); |
1087 | } | 1210 | } |
1088 | 1211 | ||
1089 | -static CPUReadMemoryFunc *pxa2xx_rtc_readfn[] = { | ||
1090 | - pxa2xx_rtc_read, | ||
1091 | - pxa2xx_rtc_read, | ||
1092 | - pxa2xx_rtc_read, | ||
1093 | -}; | 1212 | +static void pxa2xx_rtc_save(QEMUFile *f, void *opaque) |
1213 | +{ | ||
1214 | + struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; | ||
1094 | 1215 | ||
1095 | -static CPUWriteMemoryFunc *pxa2xx_rtc_writefn[] = { | ||
1096 | - pxa2xx_rtc_write, | ||
1097 | - pxa2xx_rtc_write, | ||
1098 | - pxa2xx_rtc_write, | ||
1099 | -}; | 1216 | + pxa2xx_rtc_hzupdate(s); |
1217 | + pxa2xx_rtc_piupdate(s); | ||
1218 | + pxa2xx_rtc_swupdate(s); | ||
1219 | + | ||
1220 | + qemu_put_be32s(f, &s->rttr); | ||
1221 | + qemu_put_be32s(f, &s->rtsr); | ||
1222 | + qemu_put_be32s(f, &s->rtar); | ||
1223 | + qemu_put_be32s(f, &s->rdar1); | ||
1224 | + qemu_put_be32s(f, &s->rdar2); | ||
1225 | + qemu_put_be32s(f, &s->ryar1); | ||
1226 | + qemu_put_be32s(f, &s->ryar2); | ||
1227 | + qemu_put_be32s(f, &s->swar1); | ||
1228 | + qemu_put_be32s(f, &s->swar2); | ||
1229 | + qemu_put_be32s(f, &s->piar); | ||
1230 | + qemu_put_be32s(f, &s->last_rcnr); | ||
1231 | + qemu_put_be32s(f, &s->last_rdcr); | ||
1232 | + qemu_put_be32s(f, &s->last_rycr); | ||
1233 | + qemu_put_be32s(f, &s->last_swcr); | ||
1234 | + qemu_put_be32s(f, &s->last_rtcpicr); | ||
1235 | + qemu_put_be64s(f, &s->last_hz); | ||
1236 | + qemu_put_be64s(f, &s->last_sw); | ||
1237 | + qemu_put_be64s(f, &s->last_pi); | ||
1238 | +} | ||
1239 | + | ||
1240 | +static int pxa2xx_rtc_load(QEMUFile *f, void *opaque, int version_id) | ||
1241 | +{ | ||
1242 | + struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque; | ||
1243 | + | ||
1244 | + qemu_get_be32s(f, &s->rttr); | ||
1245 | + qemu_get_be32s(f, &s->rtsr); | ||
1246 | + qemu_get_be32s(f, &s->rtar); | ||
1247 | + qemu_get_be32s(f, &s->rdar1); | ||
1248 | + qemu_get_be32s(f, &s->rdar2); | ||
1249 | + qemu_get_be32s(f, &s->ryar1); | ||
1250 | + qemu_get_be32s(f, &s->ryar2); | ||
1251 | + qemu_get_be32s(f, &s->swar1); | ||
1252 | + qemu_get_be32s(f, &s->swar2); | ||
1253 | + qemu_get_be32s(f, &s->piar); | ||
1254 | + qemu_get_be32s(f, &s->last_rcnr); | ||
1255 | + qemu_get_be32s(f, &s->last_rdcr); | ||
1256 | + qemu_get_be32s(f, &s->last_rycr); | ||
1257 | + qemu_get_be32s(f, &s->last_swcr); | ||
1258 | + qemu_get_be32s(f, &s->last_rtcpicr); | ||
1259 | + qemu_get_be64s(f, &s->last_hz); | ||
1260 | + qemu_get_be64s(f, &s->last_sw); | ||
1261 | + qemu_get_be64s(f, &s->last_pi); | ||
1262 | + | ||
1263 | + pxa2xx_rtc_alarm_update(s, s->rtsr); | ||
1264 | + | ||
1265 | + return 0; | ||
1266 | +} | ||
1100 | 1267 | ||
1101 | /* I2C Interface */ | 1268 | /* I2C Interface */ |
1102 | struct pxa2xx_i2c_s { | 1269 | struct pxa2xx_i2c_s { |
@@ -1289,6 +1456,33 @@ static CPUWriteMemoryFunc *pxa2xx_i2c_writefn[] = { | @@ -1289,6 +1456,33 @@ static CPUWriteMemoryFunc *pxa2xx_i2c_writefn[] = { | ||
1289 | pxa2xx_i2c_write, | 1456 | pxa2xx_i2c_write, |
1290 | }; | 1457 | }; |
1291 | 1458 | ||
1459 | +static void pxa2xx_i2c_save(QEMUFile *f, void *opaque) | ||
1460 | +{ | ||
1461 | + struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) opaque; | ||
1462 | + | ||
1463 | + qemu_put_be16s(f, &s->control); | ||
1464 | + qemu_put_be16s(f, &s->status); | ||
1465 | + qemu_put_8s(f, &s->ibmr); | ||
1466 | + qemu_put_8s(f, &s->data); | ||
1467 | + | ||
1468 | + i2c_bus_save(f, s->bus); | ||
1469 | + i2c_slave_save(f, &s->slave); | ||
1470 | +} | ||
1471 | + | ||
1472 | +static int pxa2xx_i2c_load(QEMUFile *f, void *opaque, int version_id) | ||
1473 | +{ | ||
1474 | + struct pxa2xx_i2c_s *s = (struct pxa2xx_i2c_s *) opaque; | ||
1475 | + | ||
1476 | + qemu_get_be16s(f, &s->control); | ||
1477 | + qemu_get_be16s(f, &s->status); | ||
1478 | + qemu_get_8s(f, &s->ibmr); | ||
1479 | + qemu_get_8s(f, &s->data); | ||
1480 | + | ||
1481 | + i2c_bus_load(f, s->bus); | ||
1482 | + i2c_slave_load(f, &s->slave); | ||
1483 | + return 0; | ||
1484 | +} | ||
1485 | + | ||
1292 | struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base, | 1486 | struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base, |
1293 | qemu_irq irq, int ioregister) | 1487 | qemu_irq irq, int ioregister) |
1294 | { | 1488 | { |
@@ -1309,6 +1503,9 @@ struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base, | @@ -1309,6 +1503,9 @@ struct pxa2xx_i2c_s *pxa2xx_i2c_init(target_phys_addr_t base, | ||
1309 | cpu_register_physical_memory(s->base & 0xfffff000, 0xfff, iomemtype); | 1503 | cpu_register_physical_memory(s->base & 0xfffff000, 0xfff, iomemtype); |
1310 | } | 1504 | } |
1311 | 1505 | ||
1506 | + register_savevm("pxa2xx_i2c", base, 0, | ||
1507 | + pxa2xx_i2c_save, pxa2xx_i2c_load, s); | ||
1508 | + | ||
1312 | return s; | 1509 | return s; |
1313 | } | 1510 | } |
1314 | 1511 | ||
@@ -1470,6 +1667,40 @@ static CPUWriteMemoryFunc *pxa2xx_i2s_writefn[] = { | @@ -1470,6 +1667,40 @@ static CPUWriteMemoryFunc *pxa2xx_i2s_writefn[] = { | ||
1470 | pxa2xx_i2s_write, | 1667 | pxa2xx_i2s_write, |
1471 | }; | 1668 | }; |
1472 | 1669 | ||
1670 | +static void pxa2xx_i2s_save(QEMUFile *f, void *opaque) | ||
1671 | +{ | ||
1672 | + struct pxa2xx_i2s_s *s = (struct pxa2xx_i2s_s *) opaque; | ||
1673 | + | ||
1674 | + qemu_put_be32s(f, &s->control[0]); | ||
1675 | + qemu_put_be32s(f, &s->control[1]); | ||
1676 | + qemu_put_be32s(f, &s->status); | ||
1677 | + qemu_put_be32s(f, &s->mask); | ||
1678 | + qemu_put_be32s(f, &s->clk); | ||
1679 | + | ||
1680 | + qemu_put_be32(f, s->enable); | ||
1681 | + qemu_put_be32(f, s->rx_len); | ||
1682 | + qemu_put_be32(f, s->tx_len); | ||
1683 | + qemu_put_be32(f, s->fifo_len); | ||
1684 | +} | ||
1685 | + | ||
1686 | +static int pxa2xx_i2s_load(QEMUFile *f, void *opaque, int version_id) | ||
1687 | +{ | ||
1688 | + struct pxa2xx_i2s_s *s = (struct pxa2xx_i2s_s *) opaque; | ||
1689 | + | ||
1690 | + qemu_get_be32s(f, &s->control[0]); | ||
1691 | + qemu_get_be32s(f, &s->control[1]); | ||
1692 | + qemu_get_be32s(f, &s->status); | ||
1693 | + qemu_get_be32s(f, &s->mask); | ||
1694 | + qemu_get_be32s(f, &s->clk); | ||
1695 | + | ||
1696 | + s->enable = qemu_get_be32(f); | ||
1697 | + s->rx_len = qemu_get_be32(f); | ||
1698 | + s->tx_len = qemu_get_be32(f); | ||
1699 | + s->fifo_len = qemu_get_be32(f); | ||
1700 | + | ||
1701 | + return 0; | ||
1702 | +} | ||
1703 | + | ||
1473 | static void pxa2xx_i2s_data_req(void *opaque, int tx, int rx) | 1704 | static void pxa2xx_i2s_data_req(void *opaque, int tx, int rx) |
1474 | { | 1705 | { |
1475 | struct pxa2xx_i2s_s *s = (struct pxa2xx_i2s_s *) opaque; | 1706 | 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, | @@ -1510,6 +1741,9 @@ static struct pxa2xx_i2s_s *pxa2xx_i2s_init(target_phys_addr_t base, | ||
1510 | pxa2xx_i2s_writefn, s); | 1741 | pxa2xx_i2s_writefn, s); |
1511 | cpu_register_physical_memory(s->base & 0xfff00000, 0xfffff, iomemtype); | 1742 | cpu_register_physical_memory(s->base & 0xfff00000, 0xfffff, iomemtype); |
1512 | 1743 | ||
1744 | + register_savevm("pxa2xx_i2s", base, 0, | ||
1745 | + pxa2xx_i2s_save, pxa2xx_i2s_load, s); | ||
1746 | + | ||
1513 | return s; | 1747 | return s; |
1514 | } | 1748 | } |
1515 | 1749 | ||
@@ -1712,6 +1946,45 @@ static void pxa2xx_fir_event(void *opaque, int event) | @@ -1712,6 +1946,45 @@ static void pxa2xx_fir_event(void *opaque, int event) | ||
1712 | { | 1946 | { |
1713 | } | 1947 | } |
1714 | 1948 | ||
1949 | +static void pxa2xx_fir_save(QEMUFile *f, void *opaque) | ||
1950 | +{ | ||
1951 | + struct pxa2xx_fir_s *s = (struct pxa2xx_fir_s *) opaque; | ||
1952 | + int i; | ||
1953 | + | ||
1954 | + qemu_put_be32(f, s->enable); | ||
1955 | + | ||
1956 | + qemu_put_8s(f, &s->control[0]); | ||
1957 | + qemu_put_8s(f, &s->control[1]); | ||
1958 | + qemu_put_8s(f, &s->control[2]); | ||
1959 | + qemu_put_8s(f, &s->status[0]); | ||
1960 | + qemu_put_8s(f, &s->status[1]); | ||
1961 | + | ||
1962 | + qemu_put_byte(f, s->rx_len); | ||
1963 | + for (i = 0; i < s->rx_len; i ++) | ||
1964 | + qemu_put_byte(f, s->rx_fifo[(s->rx_start + i) & 63]); | ||
1965 | +} | ||
1966 | + | ||
1967 | +static int pxa2xx_fir_load(QEMUFile *f, void *opaque, int version_id) | ||
1968 | +{ | ||
1969 | + struct pxa2xx_fir_s *s = (struct pxa2xx_fir_s *) opaque; | ||
1970 | + int i; | ||
1971 | + | ||
1972 | + s->enable = qemu_get_be32(f); | ||
1973 | + | ||
1974 | + qemu_get_8s(f, &s->control[0]); | ||
1975 | + qemu_get_8s(f, &s->control[1]); | ||
1976 | + qemu_get_8s(f, &s->control[2]); | ||
1977 | + qemu_get_8s(f, &s->status[0]); | ||
1978 | + qemu_get_8s(f, &s->status[1]); | ||
1979 | + | ||
1980 | + s->rx_len = qemu_get_byte(f); | ||
1981 | + s->rx_start = 0; | ||
1982 | + for (i = 0; i < s->rx_len; i ++) | ||
1983 | + s->rx_fifo[i] = qemu_get_byte(f); | ||
1984 | + | ||
1985 | + return 0; | ||
1986 | +} | ||
1987 | + | ||
1715 | static struct pxa2xx_fir_s *pxa2xx_fir_init(target_phys_addr_t base, | 1988 | static struct pxa2xx_fir_s *pxa2xx_fir_init(target_phys_addr_t base, |
1716 | qemu_irq irq, struct pxa2xx_dma_state_s *dma, | 1989 | qemu_irq irq, struct pxa2xx_dma_state_s *dma, |
1717 | CharDriverState *chr) | 1990 | CharDriverState *chr) |
@@ -1735,6 +2008,8 @@ static struct pxa2xx_fir_s *pxa2xx_fir_init(target_phys_addr_t base, | @@ -1735,6 +2008,8 @@ static struct pxa2xx_fir_s *pxa2xx_fir_init(target_phys_addr_t base, | ||
1735 | qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty, | 2008 | qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty, |
1736 | pxa2xx_fir_rx, pxa2xx_fir_event, s); | 2009 | pxa2xx_fir_rx, pxa2xx_fir_event, s); |
1737 | 2010 | ||
2011 | + register_savevm("pxa2xx_fir", 0, 0, pxa2xx_fir_save, pxa2xx_fir_load, s); | ||
2012 | + | ||
1738 | return s; | 2013 | return s; |
1739 | } | 2014 | } |
1740 | 2015 | ||
@@ -1763,6 +2038,7 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, | @@ -1763,6 +2038,7 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, | ||
1763 | 2038 | ||
1764 | s->env = cpu_init(); | 2039 | s->env = cpu_init(); |
1765 | cpu_arm_set_model(s->env, revision ?: "pxa270"); | 2040 | cpu_arm_set_model(s->env, revision ?: "pxa270"); |
2041 | + register_savevm("cpu", 0, 0, cpu_save, cpu_load, s->env); | ||
1766 | 2042 | ||
1767 | /* SDRAM & Internal Memory Storage */ | 2043 | /* SDRAM & Internal Memory Storage */ |
1768 | cpu_register_physical_memory(PXA2XX_SDRAM_BASE, | 2044 | cpu_register_physical_memory(PXA2XX_SDRAM_BASE, |
@@ -1800,6 +2076,7 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, | @@ -1800,6 +2076,7 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, | ||
1800 | iomemtype = cpu_register_io_memory(0, pxa2xx_cm_readfn, | 2076 | iomemtype = cpu_register_io_memory(0, pxa2xx_cm_readfn, |
1801 | pxa2xx_cm_writefn, s); | 2077 | pxa2xx_cm_writefn, s); |
1802 | cpu_register_physical_memory(s->cm_base, 0xfff, iomemtype); | 2078 | cpu_register_physical_memory(s->cm_base, 0xfff, iomemtype); |
2079 | + register_savevm("pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s); | ||
1803 | 2080 | ||
1804 | cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s); | 2081 | cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s); |
1805 | 2082 | ||
@@ -1810,6 +2087,7 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, | @@ -1810,6 +2087,7 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, | ||
1810 | iomemtype = cpu_register_io_memory(0, pxa2xx_mm_readfn, | 2087 | iomemtype = cpu_register_io_memory(0, pxa2xx_mm_readfn, |
1811 | pxa2xx_mm_writefn, s); | 2088 | pxa2xx_mm_writefn, s); |
1812 | cpu_register_physical_memory(s->mm_base, 0xfff, iomemtype); | 2089 | cpu_register_physical_memory(s->mm_base, 0xfff, iomemtype); |
2090 | + register_savevm("pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s); | ||
1813 | 2091 | ||
1814 | for (i = 0; pxa27x_ssp[i].io_base; i ++); | 2092 | for (i = 0; pxa27x_ssp[i].io_base; i ++); |
1815 | s->ssp = (struct pxa2xx_ssp_s **) | 2093 | s->ssp = (struct pxa2xx_ssp_s **) |
@@ -1824,6 +2102,8 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, | @@ -1824,6 +2102,8 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, | ||
1824 | iomemtype = cpu_register_io_memory(0, pxa2xx_ssp_readfn, | 2102 | iomemtype = cpu_register_io_memory(0, pxa2xx_ssp_readfn, |
1825 | pxa2xx_ssp_writefn, &ssp[i]); | 2103 | pxa2xx_ssp_writefn, &ssp[i]); |
1826 | cpu_register_physical_memory(ssp[i].base, 0xfff, iomemtype); | 2104 | cpu_register_physical_memory(ssp[i].base, 0xfff, iomemtype); |
2105 | + register_savevm("pxa2xx_ssp", i, 0, | ||
2106 | + pxa2xx_ssp_save, pxa2xx_ssp_load, s); | ||
1827 | } | 2107 | } |
1828 | 2108 | ||
1829 | if (usb_enabled) { | 2109 | if (usb_enabled) { |
@@ -1837,7 +2117,8 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, | @@ -1837,7 +2117,8 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, | ||
1837 | iomemtype = cpu_register_io_memory(0, pxa2xx_rtc_readfn, | 2117 | iomemtype = cpu_register_io_memory(0, pxa2xx_rtc_readfn, |
1838 | pxa2xx_rtc_writefn, s); | 2118 | pxa2xx_rtc_writefn, s); |
1839 | cpu_register_physical_memory(s->rtc_base, 0xfff, iomemtype); | 2119 | cpu_register_physical_memory(s->rtc_base, 0xfff, iomemtype); |
1840 | - pxa2xx_rtc_reset(s); | 2120 | + pxa2xx_rtc_init(s); |
2121 | + register_savevm("pxa2xx_rtc", 0, 0, pxa2xx_rtc_save, pxa2xx_rtc_load, s); | ||
1841 | 2122 | ||
1842 | /* Note that PM registers are in the same page with PWRI2C registers. | 2123 | /* Note that PM registers are in the same page with PWRI2C registers. |
1843 | * As a workaround we don't map PWRI2C into memory and we expect | 2124 | * 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, | @@ -1849,6 +2130,7 @@ struct pxa2xx_state_s *pxa270_init(unsigned int sdram_size, | ||
1849 | iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn, | 2130 | iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn, |
1850 | pxa2xx_pm_writefn, s); | 2131 | pxa2xx_pm_writefn, s); |
1851 | cpu_register_physical_memory(s->pm_base, 0xfff, iomemtype); | 2132 | cpu_register_physical_memory(s->pm_base, 0xfff, iomemtype); |
2133 | + register_savevm("pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s); | ||
1852 | 2134 | ||
1853 | s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma); | 2135 | s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma); |
1854 | 2136 | ||
@@ -1869,6 +2151,7 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, | @@ -1869,6 +2151,7 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, | ||
1869 | 2151 | ||
1870 | s->env = cpu_init(); | 2152 | s->env = cpu_init(); |
1871 | cpu_arm_set_model(s->env, "pxa255"); | 2153 | cpu_arm_set_model(s->env, "pxa255"); |
2154 | + register_savevm("cpu", 0, 0, cpu_save, cpu_load, s->env); | ||
1872 | 2155 | ||
1873 | /* SDRAM & Internal Memory Storage */ | 2156 | /* SDRAM & Internal Memory Storage */ |
1874 | cpu_register_physical_memory(PXA2XX_SDRAM_BASE, sdram_size, | 2157 | cpu_register_physical_memory(PXA2XX_SDRAM_BASE, sdram_size, |
@@ -1905,6 +2188,7 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, | @@ -1905,6 +2188,7 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, | ||
1905 | iomemtype = cpu_register_io_memory(0, pxa2xx_cm_readfn, | 2188 | iomemtype = cpu_register_io_memory(0, pxa2xx_cm_readfn, |
1906 | pxa2xx_cm_writefn, s); | 2189 | pxa2xx_cm_writefn, s); |
1907 | cpu_register_physical_memory(s->cm_base, 0xfff, iomemtype); | 2190 | cpu_register_physical_memory(s->cm_base, 0xfff, iomemtype); |
2191 | + register_savevm("pxa2xx_cm", 0, 0, pxa2xx_cm_save, pxa2xx_cm_load, s); | ||
1908 | 2192 | ||
1909 | cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s); | 2193 | cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s); |
1910 | 2194 | ||
@@ -1915,6 +2199,7 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, | @@ -1915,6 +2199,7 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, | ||
1915 | iomemtype = cpu_register_io_memory(0, pxa2xx_mm_readfn, | 2199 | iomemtype = cpu_register_io_memory(0, pxa2xx_mm_readfn, |
1916 | pxa2xx_mm_writefn, s); | 2200 | pxa2xx_mm_writefn, s); |
1917 | cpu_register_physical_memory(s->mm_base, 0xfff, iomemtype); | 2201 | cpu_register_physical_memory(s->mm_base, 0xfff, iomemtype); |
2202 | + register_savevm("pxa2xx_mm", 0, 0, pxa2xx_mm_save, pxa2xx_mm_load, s); | ||
1918 | 2203 | ||
1919 | for (i = 0; pxa255_ssp[i].io_base; i ++); | 2204 | for (i = 0; pxa255_ssp[i].io_base; i ++); |
1920 | s->ssp = (struct pxa2xx_ssp_s **) | 2205 | s->ssp = (struct pxa2xx_ssp_s **) |
@@ -1929,6 +2214,8 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, | @@ -1929,6 +2214,8 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, | ||
1929 | iomemtype = cpu_register_io_memory(0, pxa2xx_ssp_readfn, | 2214 | iomemtype = cpu_register_io_memory(0, pxa2xx_ssp_readfn, |
1930 | pxa2xx_ssp_writefn, &ssp[i]); | 2215 | pxa2xx_ssp_writefn, &ssp[i]); |
1931 | cpu_register_physical_memory(ssp[i].base, 0xfff, iomemtype); | 2216 | cpu_register_physical_memory(ssp[i].base, 0xfff, iomemtype); |
2217 | + register_savevm("pxa2xx_ssp", i, 0, | ||
2218 | + pxa2xx_ssp_save, pxa2xx_ssp_load, s); | ||
1932 | } | 2219 | } |
1933 | 2220 | ||
1934 | if (usb_enabled) { | 2221 | if (usb_enabled) { |
@@ -1942,7 +2229,8 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, | @@ -1942,7 +2229,8 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, | ||
1942 | iomemtype = cpu_register_io_memory(0, pxa2xx_rtc_readfn, | 2229 | iomemtype = cpu_register_io_memory(0, pxa2xx_rtc_readfn, |
1943 | pxa2xx_rtc_writefn, s); | 2230 | pxa2xx_rtc_writefn, s); |
1944 | cpu_register_physical_memory(s->rtc_base, 0xfff, iomemtype); | 2231 | cpu_register_physical_memory(s->rtc_base, 0xfff, iomemtype); |
1945 | - pxa2xx_rtc_reset(s); | 2232 | + pxa2xx_rtc_init(s); |
2233 | + register_savevm("pxa2xx_rtc", 0, 0, pxa2xx_rtc_save, pxa2xx_rtc_load, s); | ||
1946 | 2234 | ||
1947 | /* Note that PM registers are in the same page with PWRI2C registers. | 2235 | /* Note that PM registers are in the same page with PWRI2C registers. |
1948 | * As a workaround we don't map PWRI2C into memory and we expect | 2236 | * 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, | @@ -1954,6 +2242,7 @@ struct pxa2xx_state_s *pxa255_init(unsigned int sdram_size, | ||
1954 | iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn, | 2242 | iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn, |
1955 | pxa2xx_pm_writefn, s); | 2243 | pxa2xx_pm_writefn, s); |
1956 | cpu_register_physical_memory(s->pm_base, 0xfff, iomemtype); | 2244 | cpu_register_physical_memory(s->pm_base, 0xfff, iomemtype); |
2245 | + register_savevm("pxa2xx_pm", 0, 0, pxa2xx_pm_save, pxa2xx_pm_load, s); | ||
1957 | 2246 | ||
1958 | s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma); | 2247 | s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma); |
1959 | 2248 |
hw/pxa2xx_dma.c
@@ -430,6 +430,61 @@ static CPUWriteMemoryFunc *pxa2xx_dma_writefn[] = { | @@ -430,6 +430,61 @@ static CPUWriteMemoryFunc *pxa2xx_dma_writefn[] = { | ||
430 | pxa2xx_dma_write | 430 | pxa2xx_dma_write |
431 | }; | 431 | }; |
432 | 432 | ||
433 | +static void pxa2xx_dma_save(QEMUFile *f, void *opaque) | ||
434 | +{ | ||
435 | + struct pxa2xx_dma_state_s *s = (struct pxa2xx_dma_state_s *) opaque; | ||
436 | + int i; | ||
437 | + | ||
438 | + qemu_put_be32(f, s->channels); | ||
439 | + | ||
440 | + qemu_put_be32s(f, &s->stopintr); | ||
441 | + qemu_put_be32s(f, &s->eorintr); | ||
442 | + qemu_put_be32s(f, &s->rasintr); | ||
443 | + qemu_put_be32s(f, &s->startintr); | ||
444 | + qemu_put_be32s(f, &s->endintr); | ||
445 | + qemu_put_be32s(f, &s->align); | ||
446 | + qemu_put_be32s(f, &s->pio); | ||
447 | + | ||
448 | + qemu_put_buffer(f, s->req, PXA2XX_DMA_NUM_REQUESTS); | ||
449 | + for (i = 0; i < s->channels; i ++) { | ||
450 | + qemu_put_betl(f, s->chan[i].descr); | ||
451 | + qemu_put_betl(f, s->chan[i].src); | ||
452 | + qemu_put_betl(f, s->chan[i].dest); | ||
453 | + qemu_put_be32s(f, &s->chan[i].cmd); | ||
454 | + qemu_put_be32s(f, &s->chan[i].state); | ||
455 | + qemu_put_be32(f, s->chan[i].request); | ||
456 | + }; | ||
457 | +} | ||
458 | + | ||
459 | +static int pxa2xx_dma_load(QEMUFile *f, void *opaque, int version_id) | ||
460 | +{ | ||
461 | + struct pxa2xx_dma_state_s *s = (struct pxa2xx_dma_state_s *) opaque; | ||
462 | + int i; | ||
463 | + | ||
464 | + if (qemu_get_be32(f) != s->channels) | ||
465 | + return -EINVAL; | ||
466 | + | ||
467 | + qemu_get_be32s(f, &s->stopintr); | ||
468 | + qemu_get_be32s(f, &s->eorintr); | ||
469 | + qemu_get_be32s(f, &s->rasintr); | ||
470 | + qemu_get_be32s(f, &s->startintr); | ||
471 | + qemu_get_be32s(f, &s->endintr); | ||
472 | + qemu_get_be32s(f, &s->align); | ||
473 | + qemu_get_be32s(f, &s->pio); | ||
474 | + | ||
475 | + qemu_get_buffer(f, s->req, PXA2XX_DMA_NUM_REQUESTS); | ||
476 | + for (i = 0; i < s->channels; i ++) { | ||
477 | + s->chan[i].descr = qemu_get_betl(f); | ||
478 | + s->chan[i].src = qemu_get_betl(f); | ||
479 | + s->chan[i].dest = qemu_get_betl(f); | ||
480 | + qemu_get_be32s(f, &s->chan[i].cmd); | ||
481 | + qemu_get_be32s(f, &s->chan[i].state); | ||
482 | + s->chan[i].request = qemu_get_be32(f); | ||
483 | + }; | ||
484 | + | ||
485 | + return 0; | ||
486 | +} | ||
487 | + | ||
433 | static struct pxa2xx_dma_state_s *pxa2xx_dma_init(target_phys_addr_t base, | 488 | static struct pxa2xx_dma_state_s *pxa2xx_dma_init(target_phys_addr_t base, |
434 | qemu_irq irq, int channels) | 489 | qemu_irq irq, int channels) |
435 | { | 490 | { |
@@ -455,6 +510,8 @@ static struct pxa2xx_dma_state_s *pxa2xx_dma_init(target_phys_addr_t base, | @@ -455,6 +510,8 @@ static struct pxa2xx_dma_state_s *pxa2xx_dma_init(target_phys_addr_t base, | ||
455 | pxa2xx_dma_writefn, s); | 510 | pxa2xx_dma_writefn, s); |
456 | cpu_register_physical_memory(base, 0x0000ffff, iomemtype); | 511 | cpu_register_physical_memory(base, 0x0000ffff, iomemtype); |
457 | 512 | ||
513 | + register_savevm("pxa2xx_dma", 0, 0, pxa2xx_dma_save, pxa2xx_dma_load, s); | ||
514 | + | ||
458 | return s; | 515 | return s; |
459 | } | 516 | } |
460 | 517 |
hw/pxa2xx_gpio.c
@@ -247,6 +247,51 @@ static CPUWriteMemoryFunc *pxa2xx_gpio_writefn[] = { | @@ -247,6 +247,51 @@ static CPUWriteMemoryFunc *pxa2xx_gpio_writefn[] = { | ||
247 | pxa2xx_gpio_write | 247 | pxa2xx_gpio_write |
248 | }; | 248 | }; |
249 | 249 | ||
250 | +static void pxa2xx_gpio_save(QEMUFile *f, void *opaque) | ||
251 | +{ | ||
252 | + struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque; | ||
253 | + int i; | ||
254 | + | ||
255 | + qemu_put_be32(f, s->lines); | ||
256 | + | ||
257 | + for (i = 0; i < PXA2XX_GPIO_BANKS; i ++) { | ||
258 | + qemu_put_be32s(f, &s->ilevel[i]); | ||
259 | + qemu_put_be32s(f, &s->olevel[i]); | ||
260 | + qemu_put_be32s(f, &s->dir[i]); | ||
261 | + qemu_put_be32s(f, &s->rising[i]); | ||
262 | + qemu_put_be32s(f, &s->falling[i]); | ||
263 | + qemu_put_be32s(f, &s->status[i]); | ||
264 | + qemu_put_be32s(f, &s->gafr[i * 2 + 0]); | ||
265 | + qemu_put_be32s(f, &s->gafr[i * 2 + 1]); | ||
266 | + | ||
267 | + qemu_put_be32s(f, &s->prev_level[i]); | ||
268 | + } | ||
269 | +} | ||
270 | + | ||
271 | +static int pxa2xx_gpio_load(QEMUFile *f, void *opaque, int version_id) | ||
272 | +{ | ||
273 | + struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque; | ||
274 | + int i; | ||
275 | + | ||
276 | + if (qemu_get_be32(f) != s->lines) | ||
277 | + return -EINVAL; | ||
278 | + | ||
279 | + for (i = 0; i < PXA2XX_GPIO_BANKS; i ++) { | ||
280 | + qemu_get_be32s(f, &s->ilevel[i]); | ||
281 | + qemu_get_be32s(f, &s->olevel[i]); | ||
282 | + qemu_get_be32s(f, &s->dir[i]); | ||
283 | + qemu_get_be32s(f, &s->rising[i]); | ||
284 | + qemu_get_be32s(f, &s->falling[i]); | ||
285 | + qemu_get_be32s(f, &s->status[i]); | ||
286 | + qemu_get_be32s(f, &s->gafr[i * 2 + 0]); | ||
287 | + qemu_get_be32s(f, &s->gafr[i * 2 + 1]); | ||
288 | + | ||
289 | + qemu_get_be32s(f, &s->prev_level[i]); | ||
290 | + } | ||
291 | + | ||
292 | + return 0; | ||
293 | +} | ||
294 | + | ||
250 | struct pxa2xx_gpio_info_s *pxa2xx_gpio_init(target_phys_addr_t base, | 295 | struct pxa2xx_gpio_info_s *pxa2xx_gpio_init(target_phys_addr_t base, |
251 | CPUState *env, qemu_irq *pic, int lines) | 296 | CPUState *env, qemu_irq *pic, int lines) |
252 | { | 297 | { |
@@ -265,6 +310,9 @@ struct pxa2xx_gpio_info_s *pxa2xx_gpio_init(target_phys_addr_t base, | @@ -265,6 +310,9 @@ struct pxa2xx_gpio_info_s *pxa2xx_gpio_init(target_phys_addr_t base, | ||
265 | pxa2xx_gpio_writefn, s); | 310 | pxa2xx_gpio_writefn, s); |
266 | cpu_register_physical_memory(base, 0x00000fff, iomemtype); | 311 | cpu_register_physical_memory(base, 0x00000fff, iomemtype); |
267 | 312 | ||
313 | + register_savevm("pxa2xx_gpio", 0, 0, | ||
314 | + pxa2xx_gpio_save, pxa2xx_gpio_load, s); | ||
315 | + | ||
268 | return s; | 316 | return s; |
269 | } | 317 | } |
270 | 318 |
hw/pxa2xx_lcd.c
@@ -924,6 +924,81 @@ void pxa2xx_lcdc_orientation(void *opaque, int angle) | @@ -924,6 +924,81 @@ void pxa2xx_lcdc_orientation(void *opaque, int angle) | ||
924 | pxa2xx_lcdc_resize(s); | 924 | pxa2xx_lcdc_resize(s); |
925 | } | 925 | } |
926 | 926 | ||
927 | +static void pxa2xx_lcdc_save(QEMUFile *f, void *opaque) | ||
928 | +{ | ||
929 | + struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque; | ||
930 | + int i; | ||
931 | + | ||
932 | + qemu_put_be32(f, s->irqlevel); | ||
933 | + qemu_put_be32(f, s->transp); | ||
934 | + | ||
935 | + for (i = 0; i < 6; i ++) | ||
936 | + qemu_put_be32s(f, &s->control[i]); | ||
937 | + for (i = 0; i < 2; i ++) | ||
938 | + qemu_put_be32s(f, &s->status[i]); | ||
939 | + for (i = 0; i < 2; i ++) | ||
940 | + qemu_put_be32s(f, &s->ovl1c[i]); | ||
941 | + for (i = 0; i < 2; i ++) | ||
942 | + qemu_put_be32s(f, &s->ovl2c[i]); | ||
943 | + qemu_put_be32s(f, &s->ccr); | ||
944 | + qemu_put_be32s(f, &s->cmdcr); | ||
945 | + qemu_put_be32s(f, &s->trgbr); | ||
946 | + qemu_put_be32s(f, &s->tcr); | ||
947 | + qemu_put_be32s(f, &s->liidr); | ||
948 | + qemu_put_8s(f, &s->bscntr); | ||
949 | + | ||
950 | + for (i = 0; i < 7; i ++) { | ||
951 | + qemu_put_betl(f, s->dma_ch[i].branch); | ||
952 | + qemu_put_byte(f, s->dma_ch[i].up); | ||
953 | + qemu_put_buffer(f, s->dma_ch[i].pbuffer, sizeof(s->dma_ch[i].pbuffer)); | ||
954 | + | ||
955 | + qemu_put_betl(f, s->dma_ch[i].descriptor); | ||
956 | + qemu_put_betl(f, s->dma_ch[i].source); | ||
957 | + qemu_put_be32s(f, &s->dma_ch[i].id); | ||
958 | + qemu_put_be32s(f, &s->dma_ch[i].command); | ||
959 | + } | ||
960 | +} | ||
961 | + | ||
962 | +static int pxa2xx_lcdc_load(QEMUFile *f, void *opaque, int version_id) | ||
963 | +{ | ||
964 | + struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque; | ||
965 | + int i; | ||
966 | + | ||
967 | + s->irqlevel = qemu_get_be32(f); | ||
968 | + s->transp = qemu_get_be32(f); | ||
969 | + | ||
970 | + for (i = 0; i < 6; i ++) | ||
971 | + qemu_get_be32s(f, &s->control[i]); | ||
972 | + for (i = 0; i < 2; i ++) | ||
973 | + qemu_get_be32s(f, &s->status[i]); | ||
974 | + for (i = 0; i < 2; i ++) | ||
975 | + qemu_get_be32s(f, &s->ovl1c[i]); | ||
976 | + for (i = 0; i < 2; i ++) | ||
977 | + qemu_get_be32s(f, &s->ovl2c[i]); | ||
978 | + qemu_get_be32s(f, &s->ccr); | ||
979 | + qemu_get_be32s(f, &s->cmdcr); | ||
980 | + qemu_get_be32s(f, &s->trgbr); | ||
981 | + qemu_get_be32s(f, &s->tcr); | ||
982 | + qemu_get_be32s(f, &s->liidr); | ||
983 | + qemu_get_8s(f, &s->bscntr); | ||
984 | + | ||
985 | + for (i = 0; i < 7; i ++) { | ||
986 | + s->dma_ch[i].branch = qemu_get_betl(f); | ||
987 | + s->dma_ch[i].up = qemu_get_byte(f); | ||
988 | + qemu_get_buffer(f, s->dma_ch[i].pbuffer, sizeof(s->dma_ch[i].pbuffer)); | ||
989 | + | ||
990 | + s->dma_ch[i].descriptor = qemu_get_betl(f); | ||
991 | + s->dma_ch[i].source = qemu_get_betl(f); | ||
992 | + qemu_get_be32s(f, &s->dma_ch[i].id); | ||
993 | + qemu_get_be32s(f, &s->dma_ch[i].command); | ||
994 | + } | ||
995 | + | ||
996 | + s->bpp = LCCR3_BPP(s->control[3]); | ||
997 | + s->xres = s->yres = s->pal_for = -1; | ||
998 | + | ||
999 | + return 0; | ||
1000 | +} | ||
1001 | + | ||
927 | #define BITS 8 | 1002 | #define BITS 8 |
928 | #include "pxa2xx_template.h" | 1003 | #include "pxa2xx_template.h" |
929 | #define BITS 15 | 1004 | #define BITS 15 |
@@ -989,6 +1064,10 @@ struct pxa2xx_lcdc_s *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq, | @@ -989,6 +1064,10 @@ struct pxa2xx_lcdc_s *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq, | ||
989 | fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__); | 1064 | fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__); |
990 | exit(1); | 1065 | exit(1); |
991 | } | 1066 | } |
1067 | + | ||
1068 | + register_savevm("pxa2xx_lcdc", 0, 0, | ||
1069 | + pxa2xx_lcdc_save, pxa2xx_lcdc_load, s); | ||
1070 | + | ||
992 | return s; | 1071 | return s; |
993 | } | 1072 | } |
994 | 1073 |
hw/pxa2xx_mmci.c
@@ -443,6 +443,84 @@ static CPUWriteMemoryFunc *pxa2xx_mmci_writefn[] = { | @@ -443,6 +443,84 @@ static CPUWriteMemoryFunc *pxa2xx_mmci_writefn[] = { | ||
443 | pxa2xx_mmci_writew | 443 | pxa2xx_mmci_writew |
444 | }; | 444 | }; |
445 | 445 | ||
446 | +static void pxa2xx_mmci_save(QEMUFile *f, void *opaque) | ||
447 | +{ | ||
448 | + struct pxa2xx_mmci_s *s = (struct pxa2xx_mmci_s *) opaque; | ||
449 | + int i; | ||
450 | + | ||
451 | + qemu_put_be32s(f, &s->status); | ||
452 | + qemu_put_be32s(f, &s->clkrt); | ||
453 | + qemu_put_be32s(f, &s->spi); | ||
454 | + qemu_put_be32s(f, &s->cmdat); | ||
455 | + qemu_put_be32s(f, &s->resp_tout); | ||
456 | + qemu_put_be32s(f, &s->read_tout); | ||
457 | + qemu_put_be32(f, s->blklen); | ||
458 | + qemu_put_be32(f, s->numblk); | ||
459 | + qemu_put_be32s(f, &s->intmask); | ||
460 | + qemu_put_be32s(f, &s->intreq); | ||
461 | + qemu_put_be32(f, s->cmd); | ||
462 | + qemu_put_be32s(f, &s->arg); | ||
463 | + qemu_put_be32(f, s->cmdreq); | ||
464 | + qemu_put_be32(f, s->active); | ||
465 | + qemu_put_be32(f, s->bytesleft); | ||
466 | + | ||
467 | + qemu_put_byte(f, s->tx_len); | ||
468 | + for (i = 0; i < s->tx_len; i ++) | ||
469 | + qemu_put_byte(f, s->tx_fifo[(s->tx_start + i) & 63]); | ||
470 | + | ||
471 | + qemu_put_byte(f, s->rx_len); | ||
472 | + for (i = 0; i < s->rx_len; i ++) | ||
473 | + qemu_put_byte(f, s->rx_fifo[(s->rx_start + i) & 31]); | ||
474 | + | ||
475 | + qemu_put_byte(f, s->resp_len); | ||
476 | + for (i = s->resp_len; i < 9; i ++) | ||
477 | + qemu_put_be16s(f, &s->resp_fifo[i]); | ||
478 | +} | ||
479 | + | ||
480 | +static int pxa2xx_mmci_load(QEMUFile *f, void *opaque, int version_id) | ||
481 | +{ | ||
482 | + struct pxa2xx_mmci_s *s = (struct pxa2xx_mmci_s *) opaque; | ||
483 | + int i; | ||
484 | + | ||
485 | + qemu_get_be32s(f, &s->status); | ||
486 | + qemu_get_be32s(f, &s->clkrt); | ||
487 | + qemu_get_be32s(f, &s->spi); | ||
488 | + qemu_get_be32s(f, &s->cmdat); | ||
489 | + qemu_get_be32s(f, &s->resp_tout); | ||
490 | + qemu_get_be32s(f, &s->read_tout); | ||
491 | + s->blklen = qemu_get_be32(f); | ||
492 | + s->numblk = qemu_get_be32(f); | ||
493 | + qemu_get_be32s(f, &s->intmask); | ||
494 | + qemu_get_be32s(f, &s->intreq); | ||
495 | + s->cmd = qemu_get_be32(f); | ||
496 | + qemu_get_be32s(f, &s->arg); | ||
497 | + s->cmdreq = qemu_get_be32(f); | ||
498 | + s->active = qemu_get_be32(f); | ||
499 | + s->bytesleft = qemu_get_be32(f); | ||
500 | + | ||
501 | + s->tx_len = qemu_get_byte(f); | ||
502 | + s->tx_start = 0; | ||
503 | + if (s->tx_len >= sizeof(s->tx_fifo) || s->tx_len < 0) | ||
504 | + return -EINVAL; | ||
505 | + for (i = 0; i < s->tx_len; i ++) | ||
506 | + s->tx_fifo[i] = qemu_get_byte(f); | ||
507 | + | ||
508 | + s->rx_len = qemu_get_byte(f); | ||
509 | + s->rx_start = 0; | ||
510 | + if (s->rx_len >= sizeof(s->rx_fifo) || s->rx_len < 0) | ||
511 | + return -EINVAL; | ||
512 | + for (i = 0; i < s->rx_len; i ++) | ||
513 | + s->rx_fifo[i] = qemu_get_byte(f); | ||
514 | + | ||
515 | + s->resp_len = qemu_get_byte(f); | ||
516 | + if (s->resp_len > 9 || s->resp_len < 0) | ||
517 | + return -EINVAL; | ||
518 | + for (i = s->resp_len; i < 9; i ++) | ||
519 | + qemu_get_be16s(f, &s->resp_fifo[i]); | ||
520 | + | ||
521 | + return 0; | ||
522 | +} | ||
523 | + | ||
446 | struct pxa2xx_mmci_s *pxa2xx_mmci_init(target_phys_addr_t base, | 524 | struct pxa2xx_mmci_s *pxa2xx_mmci_init(target_phys_addr_t base, |
447 | qemu_irq irq, void *dma) | 525 | qemu_irq irq, void *dma) |
448 | { | 526 | { |
@@ -461,6 +539,9 @@ struct pxa2xx_mmci_s *pxa2xx_mmci_init(target_phys_addr_t base, | @@ -461,6 +539,9 @@ struct pxa2xx_mmci_s *pxa2xx_mmci_init(target_phys_addr_t base, | ||
461 | /* Instantiate the actual storage */ | 539 | /* Instantiate the actual storage */ |
462 | s->card = sd_init(sd_bdrv); | 540 | s->card = sd_init(sd_bdrv); |
463 | 541 | ||
542 | + register_savevm("pxa2xx_mmci", 0, 0, | ||
543 | + pxa2xx_mmci_save, pxa2xx_mmci_load, s); | ||
544 | + | ||
464 | return s; | 545 | return s; |
465 | } | 546 | } |
466 | 547 |
hw/pxa2xx_pic.c
@@ -245,6 +245,41 @@ static CPUWriteMemoryFunc *pxa2xx_pic_writefn[] = { | @@ -245,6 +245,41 @@ static CPUWriteMemoryFunc *pxa2xx_pic_writefn[] = { | ||
245 | pxa2xx_pic_mem_write, | 245 | pxa2xx_pic_mem_write, |
246 | }; | 246 | }; |
247 | 247 | ||
248 | +static void pxa2xx_pic_save(QEMUFile *f, void *opaque) | ||
249 | +{ | ||
250 | + struct pxa2xx_pic_state_s *s = (struct pxa2xx_pic_state_s *) opaque; | ||
251 | + int i; | ||
252 | + | ||
253 | + for (i = 0; i < 2; i ++) | ||
254 | + qemu_put_be32s(f, &s->int_enabled[i]); | ||
255 | + for (i = 0; i < 2; i ++) | ||
256 | + qemu_put_be32s(f, &s->int_pending[i]); | ||
257 | + for (i = 0; i < 2; i ++) | ||
258 | + qemu_put_be32s(f, &s->is_fiq[i]); | ||
259 | + qemu_put_be32s(f, &s->int_idle); | ||
260 | + for (i = 0; i < PXA2XX_PIC_SRCS; i ++) | ||
261 | + qemu_put_be32s(f, &s->priority[i]); | ||
262 | +} | ||
263 | + | ||
264 | +static int pxa2xx_pic_load(QEMUFile *f, void *opaque, int version_id) | ||
265 | +{ | ||
266 | + struct pxa2xx_pic_state_s *s = (struct pxa2xx_pic_state_s *) opaque; | ||
267 | + int i; | ||
268 | + | ||
269 | + for (i = 0; i < 2; i ++) | ||
270 | + qemu_get_be32s(f, &s->int_enabled[i]); | ||
271 | + for (i = 0; i < 2; i ++) | ||
272 | + qemu_get_be32s(f, &s->int_pending[i]); | ||
273 | + for (i = 0; i < 2; i ++) | ||
274 | + qemu_get_be32s(f, &s->is_fiq[i]); | ||
275 | + qemu_get_be32s(f, &s->int_idle); | ||
276 | + for (i = 0; i < PXA2XX_PIC_SRCS; i ++) | ||
277 | + qemu_get_be32s(f, &s->priority[i]); | ||
278 | + | ||
279 | + pxa2xx_pic_update(opaque); | ||
280 | + return 0; | ||
281 | +} | ||
282 | + | ||
248 | qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env) | 283 | qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env) |
249 | { | 284 | { |
250 | struct pxa2xx_pic_state_s *s; | 285 | struct pxa2xx_pic_state_s *s; |
@@ -276,5 +311,7 @@ qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env) | @@ -276,5 +311,7 @@ qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env) | ||
276 | /* Enable IC coprocessor access. */ | 311 | /* Enable IC coprocessor access. */ |
277 | cpu_arm_set_cp_io(env, 6, pxa2xx_pic_cp_read, pxa2xx_pic_cp_write, s); | 312 | cpu_arm_set_cp_io(env, 6, pxa2xx_pic_cp_read, pxa2xx_pic_cp_write, s); |
278 | 313 | ||
314 | + register_savevm("pxa2xx_pic", 0, 0, pxa2xx_pic_save, pxa2xx_pic_load, s); | ||
315 | + | ||
279 | return qi; | 316 | return qi; |
280 | } | 317 | } |
hw/pxa2xx_timer.c
@@ -364,6 +364,73 @@ static void pxa2xx_timer_tick4(void *opaque) | @@ -364,6 +364,73 @@ static void pxa2xx_timer_tick4(void *opaque) | ||
364 | pxa2xx_timer_update4(i, qemu_get_clock(vm_clock), t->tm.num - 4); | 364 | pxa2xx_timer_update4(i, qemu_get_clock(vm_clock), t->tm.num - 4); |
365 | } | 365 | } |
366 | 366 | ||
367 | +static void pxa2xx_timer_save(QEMUFile *f, void *opaque) | ||
368 | +{ | ||
369 | + pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque; | ||
370 | + int i; | ||
371 | + | ||
372 | + qemu_put_be32s(f, &s->clock); | ||
373 | + qemu_put_be32s(f, &s->oldclock); | ||
374 | + qemu_put_be64s(f, &s->lastload); | ||
375 | + | ||
376 | + for (i = 0; i < 4; i ++) { | ||
377 | + qemu_put_be32s(f, &s->timer[i].value); | ||
378 | + qemu_put_be32(f, s->timer[i].level); | ||
379 | + } | ||
380 | + if (s->tm4) | ||
381 | + for (i = 0; i < 8; i ++) { | ||
382 | + qemu_put_be32s(f, &s->tm4[i].tm.value); | ||
383 | + qemu_put_be32(f, s->tm4[i].tm.level); | ||
384 | + qemu_put_be32s(f, &s->tm4[i].oldclock); | ||
385 | + qemu_put_be32s(f, &s->tm4[i].clock); | ||
386 | + qemu_put_be64s(f, &s->tm4[i].lastload); | ||
387 | + qemu_put_be32s(f, &s->tm4[i].freq); | ||
388 | + qemu_put_be32s(f, &s->tm4[i].control); | ||
389 | + } | ||
390 | + | ||
391 | + qemu_put_be32s(f, &s->events); | ||
392 | + qemu_put_be32s(f, &s->irq_enabled); | ||
393 | + qemu_put_be32s(f, &s->reset3); | ||
394 | + qemu_put_be32s(f, &s->snapshot); | ||
395 | +} | ||
396 | + | ||
397 | +static int pxa2xx_timer_load(QEMUFile *f, void *opaque, int version_id) | ||
398 | +{ | ||
399 | + pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque; | ||
400 | + int64_t now; | ||
401 | + int i; | ||
402 | + | ||
403 | + qemu_get_be32s(f, &s->clock); | ||
404 | + qemu_get_be32s(f, &s->oldclock); | ||
405 | + qemu_get_be64s(f, &s->lastload); | ||
406 | + | ||
407 | + now = qemu_get_clock(vm_clock); | ||
408 | + for (i = 0; i < 4; i ++) { | ||
409 | + qemu_get_be32s(f, &s->timer[i].value); | ||
410 | + s->timer[i].level = qemu_get_be32(f); | ||
411 | + } | ||
412 | + pxa2xx_timer_update(s, now); | ||
413 | + | ||
414 | + if (s->tm4) | ||
415 | + for (i = 0; i < 8; i ++) { | ||
416 | + qemu_get_be32s(f, &s->tm4[i].tm.value); | ||
417 | + s->tm4[i].tm.level = qemu_get_be32(f); | ||
418 | + qemu_get_be32s(f, &s->tm4[i].oldclock); | ||
419 | + qemu_get_be32s(f, &s->tm4[i].clock); | ||
420 | + qemu_get_be64s(f, &s->tm4[i].lastload); | ||
421 | + qemu_get_be32s(f, &s->tm4[i].freq); | ||
422 | + qemu_get_be32s(f, &s->tm4[i].control); | ||
423 | + pxa2xx_timer_update4(s, now, i); | ||
424 | + } | ||
425 | + | ||
426 | + qemu_get_be32s(f, &s->events); | ||
427 | + qemu_get_be32s(f, &s->irq_enabled); | ||
428 | + qemu_get_be32s(f, &s->reset3); | ||
429 | + qemu_get_be32s(f, &s->snapshot); | ||
430 | + | ||
431 | + return 0; | ||
432 | +} | ||
433 | + | ||
367 | static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base, | 434 | static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base, |
368 | qemu_irq *irqs) | 435 | qemu_irq *irqs) |
369 | { | 436 | { |
@@ -392,6 +459,10 @@ static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base, | @@ -392,6 +459,10 @@ static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base, | ||
392 | iomemtype = cpu_register_io_memory(0, pxa2xx_timer_readfn, | 459 | iomemtype = cpu_register_io_memory(0, pxa2xx_timer_readfn, |
393 | pxa2xx_timer_writefn, s); | 460 | pxa2xx_timer_writefn, s); |
394 | cpu_register_physical_memory(base, 0x00000fff, iomemtype); | 461 | cpu_register_physical_memory(base, 0x00000fff, iomemtype); |
462 | + | ||
463 | + register_savevm("pxa2xx_timer", 0, 0, | ||
464 | + pxa2xx_timer_save, pxa2xx_timer_load, s); | ||
465 | + | ||
395 | return s; | 466 | return s; |
396 | } | 467 | } |
397 | 468 |
hw/spitz.c
@@ -109,6 +109,24 @@ static void sl_writeb(void *opaque, target_phys_addr_t addr, | @@ -109,6 +109,24 @@ static void sl_writeb(void *opaque, target_phys_addr_t addr, | ||
109 | } | 109 | } |
110 | } | 110 | } |
111 | 111 | ||
112 | +static void sl_save(QEMUFile *f, void *opaque) | ||
113 | +{ | ||
114 | + struct sl_nand_s *s = (struct sl_nand_s *) opaque; | ||
115 | + | ||
116 | + qemu_put_8s(f, &s->ctl); | ||
117 | + ecc_put(f, &s->ecc); | ||
118 | +} | ||
119 | + | ||
120 | +static int sl_load(QEMUFile *f, void *opaque, int version_id) | ||
121 | +{ | ||
122 | + struct sl_nand_s *s = (struct sl_nand_s *) opaque; | ||
123 | + | ||
124 | + qemu_get_8s(f, &s->ctl); | ||
125 | + ecc_get(f, &s->ecc); | ||
126 | + | ||
127 | + return 0; | ||
128 | +} | ||
129 | + | ||
112 | enum { | 130 | enum { |
113 | FLASH_128M, | 131 | FLASH_128M, |
114 | FLASH_1024M, | 132 | FLASH_1024M, |
@@ -140,6 +158,8 @@ static void sl_flash_register(struct pxa2xx_state_s *cpu, int size) | @@ -140,6 +158,8 @@ static void sl_flash_register(struct pxa2xx_state_s *cpu, int size) | ||
140 | iomemtype = cpu_register_io_memory(0, sl_readfn, | 158 | iomemtype = cpu_register_io_memory(0, sl_readfn, |
141 | sl_writefn, s); | 159 | sl_writefn, s); |
142 | cpu_register_physical_memory(s->target_base, 0x40, iomemtype); | 160 | cpu_register_physical_memory(s->target_base, 0x40, iomemtype); |
161 | + | ||
162 | + register_savevm("sl_flash", 0, 0, sl_save, sl_load, s); | ||
143 | } | 163 | } |
144 | 164 | ||
145 | /* Spitz Keyboard */ | 165 | /* Spitz Keyboard */ |
@@ -406,6 +426,38 @@ static void spitz_keyboard_pre_map(struct spitz_keyboard_s *s) | @@ -406,6 +426,38 @@ static void spitz_keyboard_pre_map(struct spitz_keyboard_s *s) | ||
406 | #undef CTRL | 426 | #undef CTRL |
407 | #undef FN | 427 | #undef FN |
408 | 428 | ||
429 | +static void spitz_keyboard_save(QEMUFile *f, void *opaque) | ||
430 | +{ | ||
431 | + struct spitz_keyboard_s *s = (struct spitz_keyboard_s *) opaque; | ||
432 | + int i; | ||
433 | + | ||
434 | + qemu_put_be16s(f, &s->sense_state); | ||
435 | + qemu_put_be16s(f, &s->strobe_state); | ||
436 | + for (i = 0; i < 5; i ++) | ||
437 | + qemu_put_byte(f, spitz_gpio_invert[i]); | ||
438 | +} | ||
439 | + | ||
440 | +static int spitz_keyboard_load(QEMUFile *f, void *opaque, int version_id) | ||
441 | +{ | ||
442 | + struct spitz_keyboard_s *s = (struct spitz_keyboard_s *) opaque; | ||
443 | + int i; | ||
444 | + | ||
445 | + qemu_get_be16s(f, &s->sense_state); | ||
446 | + qemu_get_be16s(f, &s->strobe_state); | ||
447 | + for (i = 0; i < 5; i ++) | ||
448 | + spitz_gpio_invert[i] = qemu_get_byte(f); | ||
449 | + | ||
450 | + /* Release all pressed keys */ | ||
451 | + memset(s->keyrow, 0, sizeof(s->keyrow)); | ||
452 | + spitz_keyboard_sense_update(s); | ||
453 | + s->modifiers = 0; | ||
454 | + s->imodifiers = 0; | ||
455 | + s->fifopos = 0; | ||
456 | + s->fifolen = 0; | ||
457 | + | ||
458 | + return 0; | ||
459 | +} | ||
460 | + | ||
409 | static void spitz_keyboard_register(struct pxa2xx_state_s *cpu) | 461 | static void spitz_keyboard_register(struct pxa2xx_state_s *cpu) |
410 | { | 462 | { |
411 | int i, j; | 463 | int i, j; |
@@ -429,6 +481,9 @@ static void spitz_keyboard_register(struct pxa2xx_state_s *cpu) | @@ -429,6 +481,9 @@ static void spitz_keyboard_register(struct pxa2xx_state_s *cpu) | ||
429 | 481 | ||
430 | spitz_keyboard_pre_map(s); | 482 | spitz_keyboard_pre_map(s); |
431 | qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s); | 483 | qemu_add_kbd_event_handler((QEMUPutKBDEvent *) spitz_keyboard_handler, s); |
484 | + | ||
485 | + register_savevm("spitz_keyboard", 0, 0, | ||
486 | + spitz_keyboard_save, spitz_keyboard_load, s); | ||
432 | } | 487 | } |
433 | 488 | ||
434 | /* SCOOP devices */ | 489 | /* SCOOP devices */ |
@@ -597,6 +652,42 @@ static inline void scoop_gpio_handler_set(struct scoop_info_s *s, int line, | @@ -597,6 +652,42 @@ static inline void scoop_gpio_handler_set(struct scoop_info_s *s, int line, | ||
597 | s->handler[line].opaque = opaque; | 652 | s->handler[line].opaque = opaque; |
598 | } | 653 | } |
599 | 654 | ||
655 | +static void scoop_save(QEMUFile *f, void *opaque) | ||
656 | +{ | ||
657 | + struct scoop_info_s *s = (struct scoop_info_s *) opaque; | ||
658 | + qemu_put_be16s(f, &s->status); | ||
659 | + qemu_put_be16s(f, &s->power); | ||
660 | + qemu_put_be32s(f, &s->gpio_level); | ||
661 | + qemu_put_be32s(f, &s->gpio_dir); | ||
662 | + qemu_put_be32s(f, &s->prev_level); | ||
663 | + qemu_put_be16s(f, &s->mcr); | ||
664 | + qemu_put_be16s(f, &s->cdr); | ||
665 | + qemu_put_be16s(f, &s->ccr); | ||
666 | + qemu_put_be16s(f, &s->irr); | ||
667 | + qemu_put_be16s(f, &s->imr); | ||
668 | + qemu_put_be16s(f, &s->isr); | ||
669 | + qemu_put_be16s(f, &s->gprr); | ||
670 | +} | ||
671 | + | ||
672 | +static int scoop_load(QEMUFile *f, void *opaque, int version_id) | ||
673 | +{ | ||
674 | + struct scoop_info_s *s = (struct scoop_info_s *) opaque; | ||
675 | + qemu_get_be16s(f, &s->status); | ||
676 | + qemu_get_be16s(f, &s->power); | ||
677 | + qemu_get_be32s(f, &s->gpio_level); | ||
678 | + qemu_get_be32s(f, &s->gpio_dir); | ||
679 | + qemu_get_be32s(f, &s->prev_level); | ||
680 | + qemu_get_be16s(f, &s->mcr); | ||
681 | + qemu_get_be16s(f, &s->cdr); | ||
682 | + qemu_get_be16s(f, &s->ccr); | ||
683 | + qemu_get_be16s(f, &s->irr); | ||
684 | + qemu_get_be16s(f, &s->imr); | ||
685 | + qemu_get_be16s(f, &s->isr); | ||
686 | + qemu_get_be16s(f, &s->gprr); | ||
687 | + | ||
688 | + return 0; | ||
689 | +} | ||
690 | + | ||
600 | static struct scoop_info_s *spitz_scoop_init(struct pxa2xx_state_s *cpu, | 691 | static struct scoop_info_s *spitz_scoop_init(struct pxa2xx_state_s *cpu, |
601 | int count) { | 692 | int count) { |
602 | int iomemtype; | 693 | int iomemtype; |
@@ -615,6 +706,7 @@ static struct scoop_info_s *spitz_scoop_init(struct pxa2xx_state_s *cpu, | @@ -615,6 +706,7 @@ static struct scoop_info_s *spitz_scoop_init(struct pxa2xx_state_s *cpu, | ||
615 | iomemtype = cpu_register_io_memory(0, scoop_readfn, | 706 | iomemtype = cpu_register_io_memory(0, scoop_readfn, |
616 | scoop_writefn, &s[0]); | 707 | scoop_writefn, &s[0]); |
617 | cpu_register_physical_memory(s[0].target_base, 0xfff, iomemtype); | 708 | cpu_register_physical_memory(s[0].target_base, 0xfff, iomemtype); |
709 | + register_savevm("scoop", 0, 0, scoop_save, scoop_load, &s[0]); | ||
618 | 710 | ||
619 | if (count < 2) | 711 | if (count < 2) |
620 | return s; | 712 | return s; |
@@ -622,6 +714,7 @@ static struct scoop_info_s *spitz_scoop_init(struct pxa2xx_state_s *cpu, | @@ -622,6 +714,7 @@ static struct scoop_info_s *spitz_scoop_init(struct pxa2xx_state_s *cpu, | ||
622 | iomemtype = cpu_register_io_memory(0, scoop_readfn, | 714 | iomemtype = cpu_register_io_memory(0, scoop_readfn, |
623 | scoop_writefn, &s[1]); | 715 | scoop_writefn, &s[1]); |
624 | cpu_register_physical_memory(s[1].target_base, 0xfff, iomemtype); | 716 | cpu_register_physical_memory(s[1].target_base, 0xfff, iomemtype); |
717 | + register_savevm("scoop", 1, 0, scoop_save, scoop_load, &s[1]); | ||
625 | 718 | ||
626 | return s; | 719 | return s; |
627 | } | 720 | } |
@@ -763,6 +856,26 @@ static void spitz_pendown_set(void *opaque, int line, int level) | @@ -763,6 +856,26 @@ static void spitz_pendown_set(void *opaque, int line, int level) | ||
763 | pxa2xx_gpio_set(cpu->gpio, SPITZ_GPIO_TP_INT, level); | 856 | pxa2xx_gpio_set(cpu->gpio, SPITZ_GPIO_TP_INT, level); |
764 | } | 857 | } |
765 | 858 | ||
859 | +static void spitz_ssp_save(QEMUFile *f, void *opaque) | ||
860 | +{ | ||
861 | + qemu_put_be32(f, lcd_en); | ||
862 | + qemu_put_be32(f, ads_en); | ||
863 | + qemu_put_be32(f, max_en); | ||
864 | + qemu_put_be32(f, bl_intensity); | ||
865 | + qemu_put_be32(f, bl_power); | ||
866 | +} | ||
867 | + | ||
868 | +static int spitz_ssp_load(QEMUFile *f, void *opaque, int version_id) | ||
869 | +{ | ||
870 | + lcd_en = qemu_get_be32(f); | ||
871 | + ads_en = qemu_get_be32(f); | ||
872 | + max_en = qemu_get_be32(f); | ||
873 | + bl_intensity = qemu_get_be32(f); | ||
874 | + bl_power = qemu_get_be32(f); | ||
875 | + | ||
876 | + return 0; | ||
877 | +} | ||
878 | + | ||
766 | static void spitz_ssp_attach(struct pxa2xx_state_s *cpu) | 879 | static void spitz_ssp_attach(struct pxa2xx_state_s *cpu) |
767 | { | 880 | { |
768 | lcd_en = ads_en = max_en = 0; | 881 | lcd_en = ads_en = max_en = 0; |
@@ -786,6 +899,8 @@ static void spitz_ssp_attach(struct pxa2xx_state_s *cpu) | @@ -786,6 +899,8 @@ static void spitz_ssp_attach(struct pxa2xx_state_s *cpu) | ||
786 | 899 | ||
787 | bl_intensity = 0x20; | 900 | bl_intensity = 0x20; |
788 | bl_power = 0; | 901 | bl_power = 0; |
902 | + | ||
903 | + register_savevm("spitz_ssp", 0, 0, spitz_ssp_save, spitz_ssp_load, cpu); | ||
789 | } | 904 | } |
790 | 905 | ||
791 | /* CF Microdrive */ | 906 | /* CF Microdrive */ |
hw/wm8750.c
@@ -491,6 +491,93 @@ static int wm8750_rx(i2c_slave *i2c) | @@ -491,6 +491,93 @@ static int wm8750_rx(i2c_slave *i2c) | ||
491 | return 0x00; | 491 | return 0x00; |
492 | } | 492 | } |
493 | 493 | ||
494 | +static void wm8750_save(QEMUFile *f, void *opaque) | ||
495 | +{ | ||
496 | + struct wm8750_s *s = (struct wm8750_s *) opaque; | ||
497 | + int i; | ||
498 | + qemu_put_8s(f, &s->i2c_data[0]); | ||
499 | + qemu_put_8s(f, &s->i2c_data[1]); | ||
500 | + qemu_put_be32(f, s->i2c_len); | ||
501 | + qemu_put_be32(f, s->enable); | ||
502 | + qemu_put_be32(f, s->idx_in); | ||
503 | + qemu_put_be32(f, s->req_in); | ||
504 | + qemu_put_be32(f, s->idx_out); | ||
505 | + qemu_put_be32(f, s->req_out); | ||
506 | + | ||
507 | + for (i = 0; i < 7; i ++) | ||
508 | + qemu_put_8s(f, &s->outvol[i]); | ||
509 | + for (i = 0; i < 2; i ++) | ||
510 | + qemu_put_8s(f, &s->outmute[i]); | ||
511 | + for (i = 0; i < 4; i ++) | ||
512 | + qemu_put_8s(f, &s->invol[i]); | ||
513 | + for (i = 0; i < 2; i ++) | ||
514 | + qemu_put_8s(f, &s->inmute[i]); | ||
515 | + | ||
516 | + for (i = 0; i < 2; i ++) | ||
517 | + qemu_put_8s(f, &s->diff[i]); | ||
518 | + qemu_put_8s(f, &s->pol); | ||
519 | + qemu_put_8s(f, &s->ds); | ||
520 | + for (i = 0; i < 2; i ++) | ||
521 | + qemu_put_8s(f, &s->monomix[i]); | ||
522 | + qemu_put_8s(f, &s->alc); | ||
523 | + qemu_put_8s(f, &s->mute); | ||
524 | + for (i = 0; i < 4; i ++) | ||
525 | + qemu_put_8s(f, &s->path[i]); | ||
526 | + for (i = 0; i < 2; i ++) | ||
527 | + qemu_put_8s(f, &s->mpath[i]); | ||
528 | + qemu_put_8s(f, &s->format); | ||
529 | + qemu_put_8s(f, &s->power); | ||
530 | + qemu_put_be32s(f, &s->inmask); | ||
531 | + qemu_put_be32s(f, &s->outmask); | ||
532 | + qemu_put_byte(f, (s->rate - wm_rate_table) / sizeof(*s->rate)); | ||
533 | + i2c_slave_save(f, &s->i2c); | ||
534 | +} | ||
535 | + | ||
536 | +static int wm8750_load(QEMUFile *f, void *opaque, int version_id) | ||
537 | +{ | ||
538 | + struct wm8750_s *s = (struct wm8750_s *) opaque; | ||
539 | + int i; | ||
540 | + qemu_get_8s(f, &s->i2c_data[0]); | ||
541 | + qemu_get_8s(f, &s->i2c_data[1]); | ||
542 | + s->i2c_len = qemu_get_be32(f); | ||
543 | + s->enable = qemu_get_be32(f); | ||
544 | + s->idx_in = qemu_get_be32(f); | ||
545 | + s->req_in = qemu_get_be32(f); | ||
546 | + s->idx_out = qemu_get_be32(f); | ||
547 | + s->req_out = qemu_get_be32(f); | ||
548 | + | ||
549 | + for (i = 0; i < 7; i ++) | ||
550 | + qemu_get_8s(f, &s->outvol[i]); | ||
551 | + for (i = 0; i < 2; i ++) | ||
552 | + qemu_get_8s(f, &s->outmute[i]); | ||
553 | + for (i = 0; i < 4; i ++) | ||
554 | + qemu_get_8s(f, &s->invol[i]); | ||
555 | + for (i = 0; i < 2; i ++) | ||
556 | + qemu_get_8s(f, &s->inmute[i]); | ||
557 | + | ||
558 | + for (i = 0; i < 2; i ++) | ||
559 | + qemu_get_8s(f, &s->diff[i]); | ||
560 | + qemu_get_8s(f, &s->pol); | ||
561 | + qemu_get_8s(f, &s->ds); | ||
562 | + for (i = 0; i < 2; i ++) | ||
563 | + qemu_get_8s(f, &s->monomix[i]); | ||
564 | + qemu_get_8s(f, &s->alc); | ||
565 | + qemu_get_8s(f, &s->mute); | ||
566 | + for (i = 0; i < 4; i ++) | ||
567 | + qemu_get_8s(f, &s->path[i]); | ||
568 | + for (i = 0; i < 2; i ++) | ||
569 | + qemu_get_8s(f, &s->mpath[i]); | ||
570 | + qemu_get_8s(f, &s->format); | ||
571 | + qemu_get_8s(f, &s->power); | ||
572 | + qemu_get_be32s(f, &s->inmask); | ||
573 | + qemu_get_be32s(f, &s->outmask); | ||
574 | + s->rate = &wm_rate_table[(uint8_t) qemu_get_byte(f) & 0x1f]; | ||
575 | + i2c_slave_load(f, &s->i2c); | ||
576 | + return 0; | ||
577 | +} | ||
578 | + | ||
579 | +static int wm8750_iid = 0; | ||
580 | + | ||
494 | i2c_slave *wm8750_init(i2c_bus *bus, AudioState *audio) | 581 | i2c_slave *wm8750_init(i2c_bus *bus, AudioState *audio) |
495 | { | 582 | { |
496 | struct wm8750_s *s = (struct wm8750_s *) | 583 | struct wm8750_s *s = (struct wm8750_s *) |
@@ -502,6 +589,8 @@ i2c_slave *wm8750_init(i2c_bus *bus, AudioState *audio) | @@ -502,6 +589,8 @@ i2c_slave *wm8750_init(i2c_bus *bus, AudioState *audio) | ||
502 | AUD_register_card(audio, CODEC, &s->card); | 589 | AUD_register_card(audio, CODEC, &s->card); |
503 | wm8750_reset(&s->i2c); | 590 | wm8750_reset(&s->i2c); |
504 | 591 | ||
592 | + register_savevm(CODEC, wm8750_iid ++, 0, wm8750_save, wm8750_load, s); | ||
593 | + | ||
505 | return &s->i2c; | 594 | return &s->i2c; |
506 | } | 595 | } |
507 | 596 |
vl.c
@@ -5679,13 +5679,144 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | @@ -5679,13 +5679,144 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) | ||
5679 | 5679 | ||
5680 | #elif defined(TARGET_ARM) | 5680 | #elif defined(TARGET_ARM) |
5681 | 5681 | ||
5682 | -/* ??? Need to implement these. */ | ||
5683 | void cpu_save(QEMUFile *f, void *opaque) | 5682 | void cpu_save(QEMUFile *f, void *opaque) |
5684 | { | 5683 | { |
5684 | + int i; | ||
5685 | + CPUARMState *env = (CPUARMState *)opaque; | ||
5686 | + | ||
5687 | + for (i = 0; i < 16; i++) { | ||
5688 | + qemu_put_be32(f, env->regs[i]); | ||
5689 | + } | ||
5690 | + qemu_put_be32(f, cpsr_read(env)); | ||
5691 | + qemu_put_be32(f, env->spsr); | ||
5692 | + for (i = 0; i < 6; i++) { | ||
5693 | + qemu_put_be32(f, env->banked_spsr[i]); | ||
5694 | + qemu_put_be32(f, env->banked_r13[i]); | ||
5695 | + qemu_put_be32(f, env->banked_r14[i]); | ||
5696 | + } | ||
5697 | + for (i = 0; i < 5; i++) { | ||
5698 | + qemu_put_be32(f, env->usr_regs[i]); | ||
5699 | + qemu_put_be32(f, env->fiq_regs[i]); | ||
5700 | + } | ||
5701 | + qemu_put_be32(f, env->cp15.c0_cpuid); | ||
5702 | + qemu_put_be32(f, env->cp15.c0_cachetype); | ||
5703 | + qemu_put_be32(f, env->cp15.c1_sys); | ||
5704 | + qemu_put_be32(f, env->cp15.c1_coproc); | ||
5705 | + qemu_put_be32(f, env->cp15.c2_base); | ||
5706 | + qemu_put_be32(f, env->cp15.c2_data); | ||
5707 | + qemu_put_be32(f, env->cp15.c2_insn); | ||
5708 | + qemu_put_be32(f, env->cp15.c3); | ||
5709 | + qemu_put_be32(f, env->cp15.c5_insn); | ||
5710 | + qemu_put_be32(f, env->cp15.c5_data); | ||
5711 | + for (i = 0; i < 8; i++) { | ||
5712 | + qemu_put_be32(f, env->cp15.c6_region[i]); | ||
5713 | + } | ||
5714 | + qemu_put_be32(f, env->cp15.c6_insn); | ||
5715 | + qemu_put_be32(f, env->cp15.c6_data); | ||
5716 | + qemu_put_be32(f, env->cp15.c9_insn); | ||
5717 | + qemu_put_be32(f, env->cp15.c9_data); | ||
5718 | + qemu_put_be32(f, env->cp15.c13_fcse); | ||
5719 | + qemu_put_be32(f, env->cp15.c13_context); | ||
5720 | + qemu_put_be32(f, env->cp15.c15_cpar); | ||
5721 | + | ||
5722 | + qemu_put_be32(f, env->features); | ||
5723 | + | ||
5724 | + if (arm_feature(env, ARM_FEATURE_VFP)) { | ||
5725 | + for (i = 0; i < 16; i++) { | ||
5726 | + CPU_DoubleU u; | ||
5727 | + u.d = env->vfp.regs[i]; | ||
5728 | + qemu_put_be32(f, u.l.upper); | ||
5729 | + qemu_put_be32(f, u.l.lower); | ||
5730 | + } | ||
5731 | + for (i = 0; i < 16; i++) { | ||
5732 | + qemu_put_be32(f, env->vfp.xregs[i]); | ||
5733 | + } | ||
5734 | + | ||
5735 | + /* TODO: Should use proper FPSCR access functions. */ | ||
5736 | + qemu_put_be32(f, env->vfp.vec_len); | ||
5737 | + qemu_put_be32(f, env->vfp.vec_stride); | ||
5738 | + } | ||
5739 | + | ||
5740 | + if (arm_feature(env, ARM_FEATURE_IWMMXT)) { | ||
5741 | + for (i = 0; i < 16; i++) { | ||
5742 | + qemu_put_be64(f, env->iwmmxt.regs[i]); | ||
5743 | + } | ||
5744 | + for (i = 0; i < 16; i++) { | ||
5745 | + qemu_put_be32(f, env->iwmmxt.cregs[i]); | ||
5746 | + } | ||
5747 | + } | ||
5685 | } | 5748 | } |
5686 | 5749 | ||
5687 | int cpu_load(QEMUFile *f, void *opaque, int version_id) | 5750 | int cpu_load(QEMUFile *f, void *opaque, int version_id) |
5688 | { | 5751 | { |
5752 | + CPUARMState *env = (CPUARMState *)opaque; | ||
5753 | + int i; | ||
5754 | + | ||
5755 | + if (version_id != 0) | ||
5756 | + return -EINVAL; | ||
5757 | + | ||
5758 | + for (i = 0; i < 16; i++) { | ||
5759 | + env->regs[i] = qemu_get_be32(f); | ||
5760 | + } | ||
5761 | + cpsr_write(env, qemu_get_be32(f), 0xffffffff); | ||
5762 | + env->spsr = qemu_get_be32(f); | ||
5763 | + for (i = 0; i < 6; i++) { | ||
5764 | + env->banked_spsr[i] = qemu_get_be32(f); | ||
5765 | + env->banked_r13[i] = qemu_get_be32(f); | ||
5766 | + env->banked_r14[i] = qemu_get_be32(f); | ||
5767 | + } | ||
5768 | + for (i = 0; i < 5; i++) { | ||
5769 | + env->usr_regs[i] = qemu_get_be32(f); | ||
5770 | + env->fiq_regs[i] = qemu_get_be32(f); | ||
5771 | + } | ||
5772 | + env->cp15.c0_cpuid = qemu_get_be32(f); | ||
5773 | + env->cp15.c0_cachetype = qemu_get_be32(f); | ||
5774 | + env->cp15.c1_sys = qemu_get_be32(f); | ||
5775 | + env->cp15.c1_coproc = qemu_get_be32(f); | ||
5776 | + env->cp15.c2_base = qemu_get_be32(f); | ||
5777 | + env->cp15.c2_data = qemu_get_be32(f); | ||
5778 | + env->cp15.c2_insn = qemu_get_be32(f); | ||
5779 | + env->cp15.c3 = qemu_get_be32(f); | ||
5780 | + env->cp15.c5_insn = qemu_get_be32(f); | ||
5781 | + env->cp15.c5_data = qemu_get_be32(f); | ||
5782 | + for (i = 0; i < 8; i++) { | ||
5783 | + env->cp15.c6_region[i] = qemu_get_be32(f); | ||
5784 | + } | ||
5785 | + env->cp15.c6_insn = qemu_get_be32(f); | ||
5786 | + env->cp15.c6_data = qemu_get_be32(f); | ||
5787 | + env->cp15.c9_insn = qemu_get_be32(f); | ||
5788 | + env->cp15.c9_data = qemu_get_be32(f); | ||
5789 | + env->cp15.c13_fcse = qemu_get_be32(f); | ||
5790 | + env->cp15.c13_context = qemu_get_be32(f); | ||
5791 | + env->cp15.c15_cpar = qemu_get_be32(f); | ||
5792 | + | ||
5793 | + env->features = qemu_get_be32(f); | ||
5794 | + | ||
5795 | + if (arm_feature(env, ARM_FEATURE_VFP)) { | ||
5796 | + for (i = 0; i < 16; i++) { | ||
5797 | + CPU_DoubleU u; | ||
5798 | + u.l.upper = qemu_get_be32(f); | ||
5799 | + u.l.lower = qemu_get_be32(f); | ||
5800 | + env->vfp.regs[i] = u.d; | ||
5801 | + } | ||
5802 | + for (i = 0; i < 16; i++) { | ||
5803 | + env->vfp.xregs[i] = qemu_get_be32(f); | ||
5804 | + } | ||
5805 | + | ||
5806 | + /* TODO: Should use proper FPSCR access functions. */ | ||
5807 | + env->vfp.vec_len = qemu_get_be32(f); | ||
5808 | + env->vfp.vec_stride = qemu_get_be32(f); | ||
5809 | + } | ||
5810 | + | ||
5811 | + if (arm_feature(env, ARM_FEATURE_IWMMXT)) { | ||
5812 | + for (i = 0; i < 16; i++) { | ||
5813 | + env->iwmmxt.regs[i] = qemu_get_be64(f); | ||
5814 | + } | ||
5815 | + for (i = 0; i < 16; i++) { | ||
5816 | + env->iwmmxt.cregs[i] = qemu_get_be32(f); | ||
5817 | + } | ||
5818 | + } | ||
5819 | + | ||
5689 | return 0; | 5820 | return 0; |
5690 | } | 5821 | } |
5691 | 5822 |