* This code is licensed under the GPL.
*/
+#include "qemu/osdep.h"
#include "hw/sysbus.h"
+#include "qemu/log.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;
+#define TYPE_PL190 "pl190"
+#define PL190(obj) OBJECT_CHECK(PL190State, (obj), TYPE_PL190)
+
+typedef struct PL190State {
+ SysBusDevice parent_obj;
+
MemoryRegion iomem;
uint32_t level;
uint32_t soft_level;
int prev_prio[PL190_NUM_PRIO];
qemu_irq irq;
qemu_irq fiq;
-} pl190_state;
+} PL190State;
static const unsigned char pl190_id[] =
{ 0x90, 0x11, 0x04, 0x00, 0x0D, 0xf0, 0x05, 0xb1 };
-static inline uint32_t pl190_irq_level(pl190_state *s)
+static inline uint32_t pl190_irq_level(PL190State *s)
{
return (s->level | s->soft_level) & s->irq_enable & ~s->fiq_select;
}
/* Update interrupts. */
-static void pl190_update(pl190_state *s)
+static void pl190_update(PL190State *s)
{
uint32_t level = pl190_irq_level(s);
int set;
static void pl190_set_irq(void *opaque, int irq, int level)
{
- pl190_state *s = (pl190_state *)opaque;
+ PL190State *s = (PL190State *)opaque;
if (level)
s->level |= 1u << irq;
pl190_update(s);
}
-static void pl190_update_vectors(pl190_state *s)
+static void pl190_update_vectors(PL190State *s)
{
uint32_t mask;
int i;
static uint64_t pl190_read(void *opaque, hwaddr offset,
unsigned size)
{
- pl190_state *s = (pl190_state *)opaque;
+ PL190State *s = (PL190State *)opaque;
int i;
if (offset >= 0xfe0 && offset < 0x1000) {
static void pl190_write(void *opaque, hwaddr offset,
uint64_t val, unsigned size)
{
- pl190_state *s = (pl190_state *)opaque;
+ PL190State *s = (PL190State *)opaque;
if (offset >= 0x100 && offset < 0x140) {
s->vect_addr[(offset - 0x100) >> 2] = val;
static void pl190_reset(DeviceState *d)
{
- pl190_state *s = DO_UPCAST(pl190_state, busdev.qdev, d);
- int i;
+ PL190State *s = PL190(d);
+ int i;
- for (i = 0; i < 16; i++)
- {
- s->vect_addr[i] = 0;
- s->vect_control[i] = 0;
+ for (i = 0; i < 16; i++) {
+ s->vect_addr[i] = 0;
+ s->vect_control[i] = 0;
}
- s->vect_addr[16] = 0;
- s->prio_mask[17] = 0xffffffff;
- s->priority = PL190_NUM_PRIO;
- pl190_update_vectors(s);
+ s->vect_addr[16] = 0;
+ s->prio_mask[17] = 0xffffffff;
+ s->priority = PL190_NUM_PRIO;
+ pl190_update_vectors(s);
}
-static int pl190_init(SysBusDevice *dev)
+static void pl190_init(Object *obj)
{
- pl190_state *s = FROM_SYSBUS(pl190_state, dev);
+ DeviceState *dev = DEVICE(obj);
+ PL190State *s = PL190(obj);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
- memory_region_init_io(&s->iomem, OBJECT(s), &pl190_ops, s, "pl190", 0x1000);
- sysbus_init_mmio(dev, &s->iomem);
- qdev_init_gpio_in(&dev->qdev, pl190_set_irq, 32);
- sysbus_init_irq(dev, &s->irq);
- sysbus_init_irq(dev, &s->fiq);
- return 0;
+ memory_region_init_io(&s->iomem, obj, &pl190_ops, s, "pl190", 0x1000);
+ sysbus_init_mmio(sbd, &s->iomem);
+ qdev_init_gpio_in(dev, pl190_set_irq, 32);
+ sysbus_init_irq(sbd, &s->irq);
+ sysbus_init_irq(sbd, &s->fiq);
}
static const VMStateDescription vmstate_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_UINT32(level, PL190State),
+ VMSTATE_UINT32(soft_level, PL190State),
+ VMSTATE_UINT32(irq_enable, PL190State),
+ VMSTATE_UINT32(fiq_select, PL190State),
+ VMSTATE_UINT8_ARRAY(vect_control, PL190State, 16),
+ VMSTATE_UINT32_ARRAY(vect_addr, PL190State, PL190_NUM_PRIO),
+ VMSTATE_UINT32_ARRAY(prio_mask, PL190State, PL190_NUM_PRIO+1),
+ VMSTATE_INT32(protected, PL190State),
+ VMSTATE_INT32(priority, PL190State),
+ VMSTATE_INT32_ARRAY(prev_prio, PL190State, PL190_NUM_PRIO),
VMSTATE_END_OF_LIST()
}
};
static void pl190_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
- k->init = pl190_init;
- dc->no_user = 1;
dc->reset = pl190_reset;
dc->vmsd = &vmstate_pl190;
}
static const TypeInfo pl190_info = {
- .name = "pl190",
+ .name = TYPE_PL190,
.parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(pl190_state),
+ .instance_size = sizeof(PL190State),
+ .instance_init = pl190_init,
.class_init = pl190_class_init,
};