提交 e5f6e732 编写于 作者: M Mark Cave-Ayland 提交者: Alexander Graf

openpic: convert to vmstate

Signed-off-by: NMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: NAlexander Graf <agraf@suse.de>
Reviewed-by: NJuan Quintela <quintela@redhat.com>
Signed-off-by: NAlexander Graf <agraf@suse.de>
上级 2ada66f9
...@@ -207,6 +207,7 @@ typedef enum IRQType { ...@@ -207,6 +207,7 @@ typedef enum IRQType {
typedef struct IRQQueue { typedef struct IRQQueue {
unsigned long *queue; unsigned long *queue;
int32_t queue_size; /* Only used for VMSTATE_BITMAP */
int next; int next;
int priority; int priority;
} IRQQueue; } IRQQueue;
...@@ -242,6 +243,15 @@ typedef struct IRQSource { ...@@ -242,6 +243,15 @@ typedef struct IRQSource {
#define IDR_EP 0x80000000 /* external pin */ #define IDR_EP 0x80000000 /* external pin */
#define IDR_CI 0x40000000 /* critical interrupt */ #define IDR_CI 0x40000000 /* critical interrupt */
typedef struct OpenPICTimer {
uint32_t tccr; /* Global timer current count register */
uint32_t tbcr; /* Global timer base count register */
} OpenPICTimer;
typedef struct OpenPICMSI {
uint32_t msir; /* Shared Message Signaled Interrupt Register */
} OpenPICMSI;
typedef struct IRQDest { typedef struct IRQDest {
int32_t ctpr; /* CPU current task priority */ int32_t ctpr; /* CPU current task priority */
IRQQueue raised; IRQQueue raised;
...@@ -290,14 +300,9 @@ typedef struct OpenPICState { ...@@ -290,14 +300,9 @@ typedef struct OpenPICState {
IRQDest dst[MAX_CPU]; IRQDest dst[MAX_CPU];
uint32_t nb_cpus; uint32_t nb_cpus;
/* Timer registers */ /* Timer registers */
struct { OpenPICTimer timers[OPENPIC_MAX_TMR];
uint32_t tccr; /* Global timer current count register */
uint32_t tbcr; /* Global timer base count register */
} timers[OPENPIC_MAX_TMR];
/* Shared MSI registers */ /* Shared MSI registers */
struct { OpenPICMSI msi[MAX_MSI];
uint32_t msir; /* Shared Message Signaled Interrupt Register */
} msi[MAX_MSI];
uint32_t max_irq; uint32_t max_irq;
uint32_t irq_ipi0; uint32_t irq_ipi0;
uint32_t irq_tim0; uint32_t irq_tim0;
...@@ -1289,130 +1294,6 @@ static const MemoryRegionOps openpic_summary_ops_be = { ...@@ -1289,130 +1294,6 @@ static const MemoryRegionOps openpic_summary_ops_be = {
}, },
}; };
static void openpic_save_IRQ_queue(QEMUFile* f, IRQQueue *q)
{
unsigned int i;
for (i = 0; i < BITS_TO_LONGS(IRQQUEUE_SIZE_BITS); i++) {
/* Always put the lower half of a 64-bit long first, in case we
* restore on a 32-bit host. The least significant bits correspond
* to lower IRQ numbers in the bitmap.
*/
qemu_put_be32(f, (uint32_t)q->queue[i]);
#if LONG_MAX > 0x7FFFFFFF
qemu_put_be32(f, (uint32_t)(q->queue[i] >> 32));
#endif
}
qemu_put_sbe32s(f, &q->next);
qemu_put_sbe32s(f, &q->priority);
}
static void openpic_save(QEMUFile* f, void *opaque)
{
OpenPICState *opp = (OpenPICState *)opaque;
unsigned int i;
qemu_put_be32s(f, &opp->gcr);
qemu_put_be32s(f, &opp->vir);
qemu_put_be32s(f, &opp->pir);
qemu_put_be32s(f, &opp->spve);
qemu_put_be32s(f, &opp->tfrr);
qemu_put_be32s(f, &opp->nb_cpus);
for (i = 0; i < opp->nb_cpus; i++) {
qemu_put_sbe32s(f, &opp->dst[i].ctpr);
openpic_save_IRQ_queue(f, &opp->dst[i].raised);
openpic_save_IRQ_queue(f, &opp->dst[i].servicing);
qemu_put_buffer(f, (uint8_t *)&opp->dst[i].outputs_active,
sizeof(opp->dst[i].outputs_active));
}
for (i = 0; i < OPENPIC_MAX_TMR; i++) {
qemu_put_be32s(f, &opp->timers[i].tccr);
qemu_put_be32s(f, &opp->timers[i].tbcr);
}
for (i = 0; i < opp->max_irq; i++) {
qemu_put_be32s(f, &opp->src[i].ivpr);
qemu_put_be32s(f, &opp->src[i].idr);
qemu_put_be32s(f, &opp->src[i].destmask);
qemu_put_sbe32s(f, &opp->src[i].last_cpu);
qemu_put_sbe32s(f, &opp->src[i].pending);
}
}
static void openpic_load_IRQ_queue(QEMUFile* f, IRQQueue *q)
{
unsigned int i;
for (i = 0; i < BITS_TO_LONGS(IRQQUEUE_SIZE_BITS); i++) {
unsigned long val;
val = qemu_get_be32(f);
#if LONG_MAX > 0x7FFFFFFF
val <<= 32;
val |= qemu_get_be32(f);
#endif
q->queue[i] = val;
}
qemu_get_sbe32s(f, &q->next);
qemu_get_sbe32s(f, &q->priority);
}
static int openpic_load(QEMUFile* f, void *opaque, int version_id)
{
OpenPICState *opp = (OpenPICState *)opaque;
unsigned int i, nb_cpus;
if (version_id != 2) {
return -EINVAL;
}
qemu_get_be32s(f, &opp->gcr);
qemu_get_be32s(f, &opp->vir);
qemu_get_be32s(f, &opp->pir);
qemu_get_be32s(f, &opp->spve);
qemu_get_be32s(f, &opp->tfrr);
qemu_get_be32s(f, &nb_cpus);
if (opp->nb_cpus != nb_cpus) {
return -EINVAL;
}
assert(nb_cpus > 0 && nb_cpus <= MAX_CPU);
for (i = 0; i < opp->nb_cpus; i++) {
qemu_get_sbe32s(f, &opp->dst[i].ctpr);
openpic_load_IRQ_queue(f, &opp->dst[i].raised);
openpic_load_IRQ_queue(f, &opp->dst[i].servicing);
qemu_get_buffer(f, (uint8_t *)&opp->dst[i].outputs_active,
sizeof(opp->dst[i].outputs_active));
}
for (i = 0; i < OPENPIC_MAX_TMR; i++) {
qemu_get_be32s(f, &opp->timers[i].tccr);
qemu_get_be32s(f, &opp->timers[i].tbcr);
}
for (i = 0; i < opp->max_irq; i++) {
uint32_t val;
val = qemu_get_be32(f);
write_IRQreg_ivpr(opp, i, val);
val = qemu_get_be32(f);
write_IRQreg_idr(opp, i, val);
qemu_get_be32s(f, &opp->src[i].destmask);
qemu_get_sbe32s(f, &opp->src[i].last_cpu);
qemu_get_sbe32s(f, &opp->src[i].pending);
}
return 0;
}
static void openpic_reset(DeviceState *d) static void openpic_reset(DeviceState *d)
{ {
OpenPICState *opp = OPENPIC(d); OpenPICState *opp = OPENPIC(d);
...@@ -1527,6 +1408,110 @@ static void map_list(OpenPICState *opp, const MemReg *list, int *count) ...@@ -1527,6 +1408,110 @@ static void map_list(OpenPICState *opp, const MemReg *list, int *count)
} }
} }
static const VMStateDescription vmstate_openpic_irq_queue = {
.name = "openpic_irq_queue",
.version_id = 0,
.minimum_version_id = 0,
.fields = (VMStateField[]) {
VMSTATE_BITMAP(queue, IRQQueue, 0, queue_size),
VMSTATE_INT32(next, IRQQueue),
VMSTATE_INT32(priority, IRQQueue),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_openpic_irqdest = {
.name = "openpic_irqdest",
.version_id = 0,
.minimum_version_id = 0,
.fields = (VMStateField[]) {
VMSTATE_INT32(ctpr, IRQDest),
VMSTATE_STRUCT(raised, IRQDest, 0, vmstate_openpic_irq_queue,
IRQQueue),
VMSTATE_STRUCT(servicing, IRQDest, 0, vmstate_openpic_irq_queue,
IRQQueue),
VMSTATE_UINT32_ARRAY(outputs_active, IRQDest, OPENPIC_OUTPUT_NB),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_openpic_irqsource = {
.name = "openpic_irqsource",
.version_id = 0,
.minimum_version_id = 0,
.fields = (VMStateField[]) {
VMSTATE_UINT32(ivpr, IRQSource),
VMSTATE_UINT32(idr, IRQSource),
VMSTATE_UINT32(destmask, IRQSource),
VMSTATE_INT32(last_cpu, IRQSource),
VMSTATE_INT32(pending, IRQSource),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_openpic_timer = {
.name = "openpic_timer",
.version_id = 0,
.minimum_version_id = 0,
.fields = (VMStateField[]) {
VMSTATE_UINT32(tccr, OpenPICTimer),
VMSTATE_UINT32(tbcr, OpenPICTimer),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_openpic_msi = {
.name = "openpic_msi",
.version_id = 0,
.minimum_version_id = 0,
.fields = (VMStateField[]) {
VMSTATE_UINT32(msir, OpenPICMSI),
VMSTATE_END_OF_LIST()
}
};
static int openpic_post_load(void *opaque, int version_id)
{
OpenPICState *opp = (OpenPICState *)opaque;
int i;
/* Update internal ivpr and idr variables */
for (i = 0; i < opp->max_irq; i++) {
write_IRQreg_idr(opp, i, opp->src[i].idr);
write_IRQreg_ivpr(opp, i, opp->src[i].ivpr);
}
return 0;
}
static const VMStateDescription vmstate_openpic = {
.name = "openpic",
.version_id = 3,
.minimum_version_id = 3,
.post_load = openpic_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT32(gcr, OpenPICState),
VMSTATE_UINT32(vir, OpenPICState),
VMSTATE_UINT32(pir, OpenPICState),
VMSTATE_UINT32(spve, OpenPICState),
VMSTATE_UINT32(tfrr, OpenPICState),
VMSTATE_UINT32(max_irq, OpenPICState),
VMSTATE_STRUCT_VARRAY_UINT32(src, OpenPICState, max_irq, 0,
vmstate_openpic_irqsource, IRQSource),
VMSTATE_UINT32_EQUAL(nb_cpus, OpenPICState),
VMSTATE_STRUCT_VARRAY_UINT32(dst, OpenPICState, nb_cpus, 0,
vmstate_openpic_irqdest, IRQDest),
VMSTATE_STRUCT_ARRAY(timers, OpenPICState, OPENPIC_MAX_TMR, 0,
vmstate_openpic_timer, OpenPICTimer),
VMSTATE_STRUCT_ARRAY(msi, OpenPICState, MAX_MSI, 0,
vmstate_openpic_msi, OpenPICMSI),
VMSTATE_UINT32(irq_ipi0, OpenPICState),
VMSTATE_UINT32(irq_tim0, OpenPICState),
VMSTATE_UINT32(irq_msi, OpenPICState),
VMSTATE_END_OF_LIST()
}
};
static void openpic_init(Object *obj) static void openpic_init(Object *obj)
{ {
OpenPICState *opp = OPENPIC(obj); OpenPICState *opp = OPENPIC(obj);
...@@ -1634,13 +1619,12 @@ static void openpic_realize(DeviceState *dev, Error **errp) ...@@ -1634,13 +1619,12 @@ static void openpic_realize(DeviceState *dev, Error **errp)
sysbus_init_irq(d, &opp->dst[i].irqs[j]); sysbus_init_irq(d, &opp->dst[i].irqs[j]);
} }
opp->dst[i].raised.queue_size = IRQQUEUE_SIZE_BITS;
opp->dst[i].raised.queue = bitmap_new(IRQQUEUE_SIZE_BITS); opp->dst[i].raised.queue = bitmap_new(IRQQUEUE_SIZE_BITS);
opp->dst[i].servicing.queue_size = IRQQUEUE_SIZE_BITS;
opp->dst[i].servicing.queue = bitmap_new(IRQQUEUE_SIZE_BITS); opp->dst[i].servicing.queue = bitmap_new(IRQQUEUE_SIZE_BITS);
} }
register_savevm(dev, "openpic", 0, 2,
openpic_save, openpic_load, opp);
sysbus_init_mmio(d, &opp->mem); sysbus_init_mmio(d, &opp->mem);
qdev_init_gpio_in(dev, openpic_set_irq, opp->max_irq); qdev_init_gpio_in(dev, openpic_set_irq, opp->max_irq);
} }
...@@ -1658,6 +1642,7 @@ static void openpic_class_init(ObjectClass *oc, void *data) ...@@ -1658,6 +1642,7 @@ static void openpic_class_init(ObjectClass *oc, void *data)
dc->realize = openpic_realize; dc->realize = openpic_realize;
dc->props = openpic_properties; dc->props = openpic_properties;
dc->reset = openpic_reset; dc->reset = openpic_reset;
dc->vmsd = &vmstate_openpic;
} }
static const TypeInfo openpic_info = { static const TypeInfo openpic_info = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册