* This code is licenced under the GPL.
*/
-#include "hw.h"
-#include "primecell.h"
+#include "sysbus.h"
/* The number of virtual priority levels. 16 user vectors plus the
unvectored IRQ. Chained interrupts would require an additional level
#define PL190_NUM_PRIO 17
typedef struct {
+ SysBusDevice busdev;
uint32_t level;
uint32_t soft_level;
uint32_t irq_enable;
uint32_t fiq_select;
- uint32_t default_addr;
uint8_t vect_control[16];
uint32_t vect_addr[PL190_NUM_PRIO];
/* Mask containing interrupts with higher priority than this one. */
s->priority = s->prev_prio[s->priority];
break;
case 13: /* DEFVECTADDR */
- s->default_addr = val;
+ s->vect_addr[16] = val;
break;
case 0xc0: /* ITCR */
if (val) {
pl190_update(s);
}
-static CPUReadMemoryFunc *pl190_readfn[] = {
+static CPUReadMemoryFunc * const pl190_readfn[] = {
pl190_read,
pl190_read,
pl190_read
};
-static CPUWriteMemoryFunc *pl190_writefn[] = {
+static CPUWriteMemoryFunc * const pl190_writefn[] = {
pl190_write,
pl190_write,
pl190_write
};
-static void pl190_reset(pl190_state *s)
+static void pl190_reset(DeviceState *d)
{
+ pl190_state *s = DO_UPCAST(pl190_state, busdev.qdev, d);
int i;
for (i = 0; i < 16; i++)
pl190_update_vectors(s);
}
-qemu_irq *pl190_init(uint32_t base, qemu_irq irq, qemu_irq fiq)
+static int pl190_init(SysBusDevice *dev)
{
- pl190_state *s;
- qemu_irq *qi;
+ pl190_state *s = FROM_SYSBUS(pl190_state, dev);
int iomemtype;
- s = (pl190_state *)qemu_mallocz(sizeof(pl190_state));
- iomemtype = cpu_register_io_memory(0, pl190_readfn,
- pl190_writefn, s);
- cpu_register_physical_memory(base, 0x00001000, iomemtype);
- qi = qemu_allocate_irqs(pl190_set_irq, s, 32);
- s->irq = irq;
- s->fiq = fiq;
- pl190_reset(s);
- /* ??? Save/restore. */
- return qi;
+ iomemtype = cpu_register_io_memory(pl190_readfn,
+ pl190_writefn, s,
+ DEVICE_NATIVE_ENDIAN);
+ sysbus_init_mmio(dev, 0x1000, iomemtype);
+ qdev_init_gpio_in(&dev->qdev, pl190_set_irq, 32);
+ sysbus_init_irq(dev, &s->irq);
+ sysbus_init_irq(dev, &s->fiq);
+ return 0;
}
+
+static const VMStateDescription vmstate_pl190 = {
+ .name = "pl190",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(level, pl190_state),
+ VMSTATE_UINT32(soft_level, pl190_state),
+ VMSTATE_UINT32(irq_enable, pl190_state),
+ VMSTATE_UINT32(fiq_select, pl190_state),
+ VMSTATE_UINT8_ARRAY(vect_control, pl190_state, 16),
+ VMSTATE_UINT32_ARRAY(vect_addr, pl190_state, PL190_NUM_PRIO),
+ VMSTATE_UINT32_ARRAY(prio_mask, pl190_state, PL190_NUM_PRIO+1),
+ VMSTATE_INT32(protected, pl190_state),
+ VMSTATE_INT32(priority, pl190_state),
+ VMSTATE_INT32_ARRAY(prev_prio, pl190_state, PL190_NUM_PRIO),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static SysBusDeviceInfo pl190_info = {
+ .init = pl190_init,
+ .qdev.name = "pl190",
+ .qdev.size = sizeof(pl190_state),
+ .qdev.vmsd = &vmstate_pl190,
+ .qdev.reset = pl190_reset,
+ .qdev.no_user = 1,
+};
+
+static void pl190_register_devices(void)
+{
+ sysbus_register_withprop(&pl190_info);
+}
+
+device_init(pl190_register_devices)