Commit 67b557859d596fda918b096af8ed0db27af9ec5a
1 parent
260cfc43
Add savevm and reset support for OpenPic
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6544 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
135 additions
and
2 deletions
hw/openpic.c
| ... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 | /* |
| 25 | 25 | * |
| 26 | 26 | * Based on OpenPic implementations: |
| 27 | - * - Intel GW80314 I/O compagnion chip developper's manual | |
| 27 | + * - Intel GW80314 I/O companion chip developer's manual | |
| 28 | 28 | * - Motorola MPC8245 & MPC8540 user manuals. |
| 29 | 29 | * - Motorola MCP750 (aka Raven) programmer manual. |
| 30 | 30 | * - Motorola Harrier programmer manuel |
| ... | ... | @@ -367,8 +367,9 @@ static void openpic_set_irq(void *opaque, int n_IRQ, int level) |
| 367 | 367 | openpic_update_irq(opp, n_IRQ); |
| 368 | 368 | } |
| 369 | 369 | |
| 370 | -static void openpic_reset (openpic_t *opp) | |
| 370 | +static void openpic_reset (void *opaque) | |
| 371 | 371 | { |
| 372 | + openpic_t *opp = (openpic_t *)opaque; | |
| 372 | 373 | int i; |
| 373 | 374 | |
| 374 | 375 | opp->glbc = 0x80000000; |
| ... | ... | @@ -1001,6 +1002,135 @@ static void openpic_map(PCIDevice *pci_dev, int region_num, |
| 1001 | 1002 | #endif |
| 1002 | 1003 | } |
| 1003 | 1004 | |
| 1005 | +static void openpic_save_IRQ_queue(QEMUFile* f, IRQ_queue_t *q) | |
| 1006 | +{ | |
| 1007 | + unsigned int i; | |
| 1008 | + | |
| 1009 | + for (i = 0; i < BF_WIDTH(MAX_IRQ); i++) | |
| 1010 | + qemu_put_be32s(f, &q->queue[i]); | |
| 1011 | + | |
| 1012 | + qemu_put_sbe32s(f, &q->next); | |
| 1013 | + qemu_put_sbe32s(f, &q->priority); | |
| 1014 | +} | |
| 1015 | + | |
| 1016 | +static void openpic_save(QEMUFile* f, void *opaque) | |
| 1017 | +{ | |
| 1018 | + openpic_t *opp = (openpic_t *)opaque; | |
| 1019 | + unsigned int i; | |
| 1020 | + | |
| 1021 | + qemu_put_be32s(f, &opp->frep); | |
| 1022 | + qemu_put_be32s(f, &opp->glbc); | |
| 1023 | + qemu_put_be32s(f, &opp->micr); | |
| 1024 | + qemu_put_be32s(f, &opp->veni); | |
| 1025 | + qemu_put_be32s(f, &opp->pint); | |
| 1026 | + qemu_put_be32s(f, &opp->spve); | |
| 1027 | + qemu_put_be32s(f, &opp->tifr); | |
| 1028 | + | |
| 1029 | + for (i = 0; i < MAX_IRQ; i++) { | |
| 1030 | + qemu_put_be32s(f, &opp->src[i].ipvp); | |
| 1031 | + qemu_put_be32s(f, &opp->src[i].ide); | |
| 1032 | + qemu_put_sbe32s(f, &opp->src[i].type); | |
| 1033 | + qemu_put_sbe32s(f, &opp->src[i].last_cpu); | |
| 1034 | + qemu_put_sbe32s(f, &opp->src[i].pending); | |
| 1035 | + } | |
| 1036 | + | |
| 1037 | + for (i = 0; i < MAX_IRQ; i++) { | |
| 1038 | + qemu_put_be32s(f, &opp->dst[i].pctp); | |
| 1039 | + qemu_put_be32s(f, &opp->dst[i].pcsr); | |
| 1040 | + openpic_save_IRQ_queue(f, &opp->dst[i].raised); | |
| 1041 | + openpic_save_IRQ_queue(f, &opp->dst[i].servicing); | |
| 1042 | + } | |
| 1043 | + | |
| 1044 | + qemu_put_sbe32s(f, &opp->nb_cpus); | |
| 1045 | + | |
| 1046 | + for (i = 0; i < MAX_TMR; i++) { | |
| 1047 | + qemu_put_be32s(f, &opp->timers[i].ticc); | |
| 1048 | + qemu_put_be32s(f, &opp->timers[i].tibc); | |
| 1049 | + } | |
| 1050 | + | |
| 1051 | +#if MAX_DBL > 0 | |
| 1052 | + qemu_put_be32s(f, &opp->dar); | |
| 1053 | + | |
| 1054 | + for (i = 0; i < MAX_DBL; i++) { | |
| 1055 | + qemu_put_be32s(f, &opp->doorbells[i].dmr); | |
| 1056 | + } | |
| 1057 | +#endif | |
| 1058 | + | |
| 1059 | +#if MAX_MBX > 0 | |
| 1060 | + for (i = 0; i < MAX_MAILBOXES; i++) { | |
| 1061 | + qemu_put_be32s(f, &opp->mailboxes[i].mbr); | |
| 1062 | + } | |
| 1063 | +#endif | |
| 1064 | + | |
| 1065 | + pci_device_save(&opp->pci_dev, f); | |
| 1066 | +} | |
| 1067 | + | |
| 1068 | +static void openpic_load_IRQ_queue(QEMUFile* f, IRQ_queue_t *q) | |
| 1069 | +{ | |
| 1070 | + unsigned int i; | |
| 1071 | + | |
| 1072 | + for (i = 0; i < BF_WIDTH(MAX_IRQ); i++) | |
| 1073 | + qemu_get_be32s(f, &q->queue[i]); | |
| 1074 | + | |
| 1075 | + qemu_get_sbe32s(f, &q->next); | |
| 1076 | + qemu_get_sbe32s(f, &q->priority); | |
| 1077 | +} | |
| 1078 | + | |
| 1079 | +static int openpic_load(QEMUFile* f, void *opaque, int version_id) | |
| 1080 | +{ | |
| 1081 | + openpic_t *opp = (openpic_t *)opaque; | |
| 1082 | + unsigned int i; | |
| 1083 | + | |
| 1084 | + if (version_id != 1) | |
| 1085 | + return -EINVAL; | |
| 1086 | + | |
| 1087 | + qemu_get_be32s(f, &opp->frep); | |
| 1088 | + qemu_get_be32s(f, &opp->glbc); | |
| 1089 | + qemu_get_be32s(f, &opp->micr); | |
| 1090 | + qemu_get_be32s(f, &opp->veni); | |
| 1091 | + qemu_get_be32s(f, &opp->pint); | |
| 1092 | + qemu_get_be32s(f, &opp->spve); | |
| 1093 | + qemu_get_be32s(f, &opp->tifr); | |
| 1094 | + | |
| 1095 | + for (i = 0; i < MAX_IRQ; i++) { | |
| 1096 | + qemu_get_be32s(f, &opp->src[i].ipvp); | |
| 1097 | + qemu_get_be32s(f, &opp->src[i].ide); | |
| 1098 | + qemu_get_sbe32s(f, &opp->src[i].type); | |
| 1099 | + qemu_get_sbe32s(f, &opp->src[i].last_cpu); | |
| 1100 | + qemu_get_sbe32s(f, &opp->src[i].pending); | |
| 1101 | + } | |
| 1102 | + | |
| 1103 | + for (i = 0; i < MAX_IRQ; i++) { | |
| 1104 | + qemu_get_be32s(f, &opp->dst[i].pctp); | |
| 1105 | + qemu_get_be32s(f, &opp->dst[i].pcsr); | |
| 1106 | + openpic_load_IRQ_queue(f, &opp->dst[i].raised); | |
| 1107 | + openpic_load_IRQ_queue(f, &opp->dst[i].servicing); | |
| 1108 | + } | |
| 1109 | + | |
| 1110 | + qemu_get_sbe32s(f, &opp->nb_cpus); | |
| 1111 | + | |
| 1112 | + for (i = 0; i < MAX_TMR; i++) { | |
| 1113 | + qemu_get_be32s(f, &opp->timers[i].ticc); | |
| 1114 | + qemu_get_be32s(f, &opp->timers[i].tibc); | |
| 1115 | + } | |
| 1116 | + | |
| 1117 | +#if MAX_DBL > 0 | |
| 1118 | + qemu_get_be32s(f, &opp->dar); | |
| 1119 | + | |
| 1120 | + for (i = 0; i < MAX_DBL; i++) { | |
| 1121 | + qemu_get_be32s(f, &opp->doorbells[i].dmr); | |
| 1122 | + } | |
| 1123 | +#endif | |
| 1124 | + | |
| 1125 | +#if MAX_MBX > 0 | |
| 1126 | + for (i = 0; i < MAX_MAILBOXES; i++) { | |
| 1127 | + qemu_get_be32s(f, &opp->mailboxes[i].mbr); | |
| 1128 | + } | |
| 1129 | +#endif | |
| 1130 | + | |
| 1131 | + return pci_device_load(&opp->pci_dev, f); | |
| 1132 | +} | |
| 1133 | + | |
| 1004 | 1134 | qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus, |
| 1005 | 1135 | qemu_irq **irqs, qemu_irq irq_out) |
| 1006 | 1136 | { |
| ... | ... | @@ -1055,6 +1185,9 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus, |
| 1055 | 1185 | for (i = 0; i < nb_cpus; i++) |
| 1056 | 1186 | opp->dst[i].irqs = irqs[i]; |
| 1057 | 1187 | opp->irq_out = irq_out; |
| 1188 | + | |
| 1189 | + register_savevm("openpic", 0, 1, openpic_save, openpic_load, opp); | |
| 1190 | + qemu_register_reset(openpic_reset, opp); | |
| 1058 | 1191 | openpic_reset(opp); |
| 1059 | 1192 | if (pmem_index) |
| 1060 | 1193 | *pmem_index = opp->mem_index; | ... | ... |