Revision 23e39294 hw/stellaris.c
b/hw/stellaris.c | ||
---|---|---|
286 | 286 |
gptm_write |
287 | 287 |
}; |
288 | 288 |
|
289 |
static void gptm_save(QEMUFile *f, void *opaque) |
|
290 |
{ |
|
291 |
gptm_state *s = (gptm_state *)opaque; |
|
292 |
|
|
293 |
qemu_put_be32(f, s->config); |
|
294 |
qemu_put_be32(f, s->mode[0]); |
|
295 |
qemu_put_be32(f, s->mode[1]); |
|
296 |
qemu_put_be32(f, s->control); |
|
297 |
qemu_put_be32(f, s->state); |
|
298 |
qemu_put_be32(f, s->mask); |
|
299 |
qemu_put_be32(f, s->mode[0]); |
|
300 |
qemu_put_be32(f, s->mode[0]); |
|
301 |
qemu_put_be32(f, s->load[0]); |
|
302 |
qemu_put_be32(f, s->load[1]); |
|
303 |
qemu_put_be32(f, s->match[0]); |
|
304 |
qemu_put_be32(f, s->match[1]); |
|
305 |
qemu_put_be32(f, s->prescale[0]); |
|
306 |
qemu_put_be32(f, s->prescale[1]); |
|
307 |
qemu_put_be32(f, s->match_prescale[0]); |
|
308 |
qemu_put_be32(f, s->match_prescale[1]); |
|
309 |
qemu_put_be32(f, s->rtc); |
|
310 |
qemu_put_be64(f, s->tick[0]); |
|
311 |
qemu_put_be64(f, s->tick[1]); |
|
312 |
qemu_put_timer(f, s->timer[0]); |
|
313 |
qemu_put_timer(f, s->timer[1]); |
|
314 |
} |
|
315 |
|
|
316 |
static int gptm_load(QEMUFile *f, void *opaque, int version_id) |
|
317 |
{ |
|
318 |
gptm_state *s = (gptm_state *)opaque; |
|
319 |
|
|
320 |
if (version_id != 1) |
|
321 |
return -EINVAL; |
|
322 |
|
|
323 |
s->config = qemu_get_be32(f); |
|
324 |
s->mode[0] = qemu_get_be32(f); |
|
325 |
s->mode[1] = qemu_get_be32(f); |
|
326 |
s->control = qemu_get_be32(f); |
|
327 |
s->state = qemu_get_be32(f); |
|
328 |
s->mask = qemu_get_be32(f); |
|
329 |
s->mode[0] = qemu_get_be32(f); |
|
330 |
s->mode[0] = qemu_get_be32(f); |
|
331 |
s->load[0] = qemu_get_be32(f); |
|
332 |
s->load[1] = qemu_get_be32(f); |
|
333 |
s->match[0] = qemu_get_be32(f); |
|
334 |
s->match[1] = qemu_get_be32(f); |
|
335 |
s->prescale[0] = qemu_get_be32(f); |
|
336 |
s->prescale[1] = qemu_get_be32(f); |
|
337 |
s->match_prescale[0] = qemu_get_be32(f); |
|
338 |
s->match_prescale[1] = qemu_get_be32(f); |
|
339 |
s->rtc = qemu_get_be32(f); |
|
340 |
s->tick[0] = qemu_get_be64(f); |
|
341 |
s->tick[1] = qemu_get_be64(f); |
|
342 |
qemu_get_timer(f, s->timer[0]); |
|
343 |
qemu_get_timer(f, s->timer[1]); |
|
344 |
|
|
345 |
return 0; |
|
346 |
} |
|
347 |
|
|
289 | 348 |
static void stellaris_gptm_init(uint32_t base, qemu_irq irq, qemu_irq trigger) |
290 | 349 |
{ |
291 | 350 |
int iomemtype; |
... | ... | |
302 | 361 |
cpu_register_physical_memory(base, 0x00001000, iomemtype); |
303 | 362 |
s->timer[0] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[0]); |
304 | 363 |
s->timer[1] = qemu_new_timer(vm_clock, gptm_tick, &s->opaque[1]); |
305 |
/* ??? Save/restore. */
|
|
364 |
register_savevm("stellaris_gptm", -1, 1, gptm_save, gptm_load, s);
|
|
306 | 365 |
} |
307 | 366 |
|
308 | 367 |
|
... | ... | |
452 | 511 |
} |
453 | 512 |
} |
454 | 513 |
|
514 |
static void ssys_calculate_system_clock(ssys_state *s) |
|
515 |
{ |
|
516 |
system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1); |
|
517 |
} |
|
518 |
|
|
455 | 519 |
static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value) |
456 | 520 |
{ |
457 | 521 |
ssys_state *s = (ssys_state *)opaque; |
... | ... | |
484 | 548 |
s->int_status |= (1 << 6); |
485 | 549 |
} |
486 | 550 |
s->rcc = value; |
487 |
system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
|
|
551 |
ssys_calculate_system_clock(s);
|
|
488 | 552 |
break; |
489 | 553 |
case 0x100: /* RCGC0 */ |
490 | 554 |
s->rcgc[0] = value; |
... | ... | |
548 | 612 |
s->dcgc[0] = 1; |
549 | 613 |
} |
550 | 614 |
|
615 |
static void ssys_save(QEMUFile *f, void *opaque) |
|
616 |
{ |
|
617 |
ssys_state *s = (ssys_state *)opaque; |
|
618 |
|
|
619 |
qemu_put_be32(f, s->pborctl); |
|
620 |
qemu_put_be32(f, s->ldopctl); |
|
621 |
qemu_put_be32(f, s->int_mask); |
|
622 |
qemu_put_be32(f, s->int_status); |
|
623 |
qemu_put_be32(f, s->resc); |
|
624 |
qemu_put_be32(f, s->rcc); |
|
625 |
qemu_put_be32(f, s->rcgc[0]); |
|
626 |
qemu_put_be32(f, s->rcgc[1]); |
|
627 |
qemu_put_be32(f, s->rcgc[2]); |
|
628 |
qemu_put_be32(f, s->scgc[0]); |
|
629 |
qemu_put_be32(f, s->scgc[1]); |
|
630 |
qemu_put_be32(f, s->scgc[2]); |
|
631 |
qemu_put_be32(f, s->dcgc[0]); |
|
632 |
qemu_put_be32(f, s->dcgc[1]); |
|
633 |
qemu_put_be32(f, s->dcgc[2]); |
|
634 |
qemu_put_be32(f, s->clkvclr); |
|
635 |
qemu_put_be32(f, s->ldoarst); |
|
636 |
} |
|
637 |
|
|
638 |
static int ssys_load(QEMUFile *f, void *opaque, int version_id) |
|
639 |
{ |
|
640 |
ssys_state *s = (ssys_state *)opaque; |
|
641 |
|
|
642 |
if (version_id != 1) |
|
643 |
return -EINVAL; |
|
644 |
|
|
645 |
s->pborctl = qemu_get_be32(f); |
|
646 |
s->ldopctl = qemu_get_be32(f); |
|
647 |
s->int_mask = qemu_get_be32(f); |
|
648 |
s->int_status = qemu_get_be32(f); |
|
649 |
s->resc = qemu_get_be32(f); |
|
650 |
s->rcc = qemu_get_be32(f); |
|
651 |
s->rcgc[0] = qemu_get_be32(f); |
|
652 |
s->rcgc[1] = qemu_get_be32(f); |
|
653 |
s->rcgc[2] = qemu_get_be32(f); |
|
654 |
s->scgc[0] = qemu_get_be32(f); |
|
655 |
s->scgc[1] = qemu_get_be32(f); |
|
656 |
s->scgc[2] = qemu_get_be32(f); |
|
657 |
s->dcgc[0] = qemu_get_be32(f); |
|
658 |
s->dcgc[1] = qemu_get_be32(f); |
|
659 |
s->dcgc[2] = qemu_get_be32(f); |
|
660 |
s->clkvclr = qemu_get_be32(f); |
|
661 |
s->ldoarst = qemu_get_be32(f); |
|
662 |
ssys_calculate_system_clock(s); |
|
663 |
|
|
664 |
return 0; |
|
665 |
} |
|
666 |
|
|
551 | 667 |
static void stellaris_sys_init(uint32_t base, qemu_irq irq, |
552 | 668 |
stellaris_board_info * board, |
553 | 669 |
uint8_t *macaddr) |
... | ... | |
567 | 683 |
ssys_writefn, s); |
568 | 684 |
cpu_register_physical_memory(base, 0x00001000, iomemtype); |
569 | 685 |
ssys_reset(s); |
570 |
/* ??? Save/restore. */
|
|
686 |
register_savevm("stellaris_sys", -1, 1, ssys_save, ssys_load, s);
|
|
571 | 687 |
} |
572 | 688 |
|
573 | 689 |
|
... | ... | |
737 | 853 |
stellaris_i2c_write |
738 | 854 |
}; |
739 | 855 |
|
856 |
static void stellaris_i2c_save(QEMUFile *f, void *opaque) |
|
857 |
{ |
|
858 |
stellaris_i2c_state *s = (stellaris_i2c_state *)opaque; |
|
859 |
|
|
860 |
qemu_put_be32(f, s->msa); |
|
861 |
qemu_put_be32(f, s->mcs); |
|
862 |
qemu_put_be32(f, s->mdr); |
|
863 |
qemu_put_be32(f, s->mtpr); |
|
864 |
qemu_put_be32(f, s->mimr); |
|
865 |
qemu_put_be32(f, s->mris); |
|
866 |
qemu_put_be32(f, s->mcr); |
|
867 |
} |
|
868 |
|
|
869 |
static int stellaris_i2c_load(QEMUFile *f, void *opaque, int version_id) |
|
870 |
{ |
|
871 |
stellaris_i2c_state *s = (stellaris_i2c_state *)opaque; |
|
872 |
|
|
873 |
if (version_id != 1) |
|
874 |
return -EINVAL; |
|
875 |
|
|
876 |
s->msa = qemu_get_be32(f); |
|
877 |
s->mcs = qemu_get_be32(f); |
|
878 |
s->mdr = qemu_get_be32(f); |
|
879 |
s->mtpr = qemu_get_be32(f); |
|
880 |
s->mimr = qemu_get_be32(f); |
|
881 |
s->mris = qemu_get_be32(f); |
|
882 |
s->mcr = qemu_get_be32(f); |
|
883 |
|
|
884 |
return 0; |
|
885 |
} |
|
886 |
|
|
740 | 887 |
static void stellaris_i2c_init(uint32_t base, qemu_irq irq, i2c_bus *bus) |
741 | 888 |
{ |
742 | 889 |
stellaris_i2c_state *s; |
... | ... | |
752 | 899 |
cpu_register_physical_memory(base, 0x00001000, iomemtype); |
753 | 900 |
/* ??? For now we only implement the master interface. */ |
754 | 901 |
stellaris_i2c_reset(s); |
902 |
register_savevm("stellaris_i2c", -1, 1, |
|
903 |
stellaris_i2c_save, stellaris_i2c_load, s); |
|
755 | 904 |
} |
756 | 905 |
|
757 | 906 |
/* Analogue to Digital Converter. This is only partially implemented, |
... | ... | |
785 | 934 |
} fifo[4]; |
786 | 935 |
uint32_t ssmux[4]; |
787 | 936 |
uint32_t ssctl[4]; |
937 |
uint32_t noise; |
|
788 | 938 |
qemu_irq irq; |
789 | 939 |
} stellaris_adc_state; |
790 | 940 |
|
... | ... | |
833 | 983 |
static void stellaris_adc_trigger(void *opaque, int irq, int level) |
834 | 984 |
{ |
835 | 985 |
stellaris_adc_state *s = (stellaris_adc_state *)opaque; |
836 |
/* Some applications use the ADC as a random number source, so introduce |
|
837 |
some variation into the signal. */ |
|
838 |
static uint32_t noise = 0; |
|
839 | 986 |
|
840 | 987 |
if ((s->actss & 1) == 0) { |
841 | 988 |
return; |
842 | 989 |
} |
843 | 990 |
|
844 |
noise = noise * 314159 + 1; |
|
991 |
/* Some applications use the ADC as a random number source, so introduce |
|
992 |
some variation into the signal. */ |
|
993 |
s->noise = s->noise * 314159 + 1; |
|
845 | 994 |
/* ??? actual inputs not implemented. Return an arbitrary value. */ |
846 |
stellaris_adc_fifo_write(s, 0, 0x200 + ((noise >> 16) & 7)); |
|
995 |
stellaris_adc_fifo_write(s, 0, 0x200 + ((s->noise >> 16) & 7));
|
|
847 | 996 |
s->ris |= 1; |
848 | 997 |
stellaris_adc_update(s); |
849 | 998 |
} |
... | ... | |
983 | 1132 |
stellaris_adc_write |
984 | 1133 |
}; |
985 | 1134 |
|
1135 |
static void stellaris_adc_save(QEMUFile *f, void *opaque) |
|
1136 |
{ |
|
1137 |
stellaris_adc_state *s = (stellaris_adc_state *)opaque; |
|
1138 |
int i; |
|
1139 |
int j; |
|
1140 |
|
|
1141 |
qemu_put_be32(f, s->actss); |
|
1142 |
qemu_put_be32(f, s->ris); |
|
1143 |
qemu_put_be32(f, s->im); |
|
1144 |
qemu_put_be32(f, s->emux); |
|
1145 |
qemu_put_be32(f, s->ostat); |
|
1146 |
qemu_put_be32(f, s->ustat); |
|
1147 |
qemu_put_be32(f, s->sspri); |
|
1148 |
qemu_put_be32(f, s->sac); |
|
1149 |
for (i = 0; i < 4; i++) { |
|
1150 |
qemu_put_be32(f, s->fifo[i].state); |
|
1151 |
for (j = 0; j < 16; j++) { |
|
1152 |
qemu_put_be32(f, s->fifo[i].data[j]); |
|
1153 |
} |
|
1154 |
qemu_put_be32(f, s->ssmux[i]); |
|
1155 |
qemu_put_be32(f, s->ssctl[i]); |
|
1156 |
} |
|
1157 |
qemu_put_be32(f, s->noise); |
|
1158 |
} |
|
1159 |
|
|
1160 |
static int stellaris_adc_load(QEMUFile *f, void *opaque, int version_id) |
|
1161 |
{ |
|
1162 |
stellaris_adc_state *s = (stellaris_adc_state *)opaque; |
|
1163 |
int i; |
|
1164 |
int j; |
|
1165 |
|
|
1166 |
if (version_id != 1) |
|
1167 |
return -EINVAL; |
|
1168 |
|
|
1169 |
s->actss = qemu_get_be32(f); |
|
1170 |
s->ris = qemu_get_be32(f); |
|
1171 |
s->im = qemu_get_be32(f); |
|
1172 |
s->emux = qemu_get_be32(f); |
|
1173 |
s->ostat = qemu_get_be32(f); |
|
1174 |
s->ustat = qemu_get_be32(f); |
|
1175 |
s->sspri = qemu_get_be32(f); |
|
1176 |
s->sac = qemu_get_be32(f); |
|
1177 |
for (i = 0; i < 4; i++) { |
|
1178 |
s->fifo[i].state = qemu_get_be32(f); |
|
1179 |
for (j = 0; j < 16; j++) { |
|
1180 |
s->fifo[i].data[j] = qemu_get_be32(f); |
|
1181 |
} |
|
1182 |
s->ssmux[i] = qemu_get_be32(f); |
|
1183 |
s->ssctl[i] = qemu_get_be32(f); |
|
1184 |
} |
|
1185 |
s->noise = qemu_get_be32(f); |
|
1186 |
|
|
1187 |
return 0; |
|
1188 |
} |
|
1189 |
|
|
986 | 1190 |
static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq irq) |
987 | 1191 |
{ |
988 | 1192 |
stellaris_adc_state *s; |
... | ... | |
998 | 1202 |
cpu_register_physical_memory(base, 0x00001000, iomemtype); |
999 | 1203 |
stellaris_adc_reset(s); |
1000 | 1204 |
qi = qemu_allocate_irqs(stellaris_adc_trigger, s, 1); |
1205 |
register_savevm("stellaris_adc", -1, 1, |
|
1206 |
stellaris_adc_save, stellaris_adc_load, s); |
|
1001 | 1207 |
return qi[0]; |
1002 | 1208 |
} |
1003 | 1209 |
|
... | ... | |
1029 | 1235 |
return s->xfer_cb[s->current_dev](s->opaque[s->current_dev], val); |
1030 | 1236 |
} |
1031 | 1237 |
|
1238 |
static void stellaris_ssi_bus_save(QEMUFile *f, void *opaque) |
|
1239 |
{ |
|
1240 |
stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque; |
|
1241 |
|
|
1242 |
qemu_put_be32(f, s->current_dev); |
|
1243 |
} |
|
1244 |
|
|
1245 |
static int stellaris_ssi_bus_load(QEMUFile *f, void *opaque, int version_id) |
|
1246 |
{ |
|
1247 |
stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque; |
|
1248 |
|
|
1249 |
if (version_id != 1) |
|
1250 |
return -EINVAL; |
|
1251 |
|
|
1252 |
s->current_dev = qemu_get_be32(f); |
|
1253 |
|
|
1254 |
return 0; |
|
1255 |
} |
|
1256 |
|
|
1032 | 1257 |
static void *stellaris_ssi_bus_init(qemu_irq *irqp, |
1033 | 1258 |
ssi_xfer_cb cb0, void *opaque0, |
1034 | 1259 |
ssi_xfer_cb cb1, void *opaque1) |
... | ... | |
1043 | 1268 |
s->opaque[1] = opaque1; |
1044 | 1269 |
qi = qemu_allocate_irqs(stellaris_ssi_bus_select, s, 1); |
1045 | 1270 |
*irqp = *qi; |
1271 |
register_savevm("stellaris_ssi_bus", -1, 1, |
|
1272 |
stellaris_ssi_bus_save, stellaris_ssi_bus_load, s); |
|
1046 | 1273 |
return s; |
1047 | 1274 |
} |
1048 | 1275 |
|
Also available in: Unified diff