-/*
+/*
* Arm PrimeCell PL190 Vector Interrupt Controller
*
* Copyright (c) 2006 CodeSourcery.
* This code is licenced under the GPL.
*/
-#include "vl.h"
-#include "arm_pic.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 {
- arm_pic_handler handler;
- uint32_t base;
- DisplayState *ds;
+ SysBusDevice busdev;
uint32_t level;
uint32_t soft_level;
uint32_t irq_enable;
/* Current priority level. */
int priority;
int prev_prio[PL190_NUM_PRIO];
- void *parent;
- int irq;
- int fiq;
+ qemu_irq irq;
+ qemu_irq fiq;
} pl190_state;
static const unsigned char pl190_id[] =
int set;
set = (level & s->prio_mask[s->priority]) != 0;
- pic_set_irq_new(s->parent, s->irq, set);
+ qemu_set_irq(s->irq, set);
set = ((s->level | s->soft_level) & s->fiq_select) != 0;
- pic_set_irq_new(s->parent, s->fiq, set);
+ qemu_set_irq(s->fiq, set);
}
static void pl190_set_irq(void *opaque, int irq, int level)
pl190_state *s = (pl190_state *)opaque;
int i;
- offset -= s->base;
if (offset >= 0xfe0 && offset < 0x1000) {
return pl190_id[(offset - 0xfe0) >> 2];
}
case 13: /* DEFVECTADDR */
return s->vect_addr[16];
default:
- cpu_abort (cpu_single_env, "pl190_read: Bad offset %x\n", offset);
+ hw_error("pl190_read: Bad offset %x\n", (int)offset);
return 0;
}
}
{
pl190_state *s = (pl190_state *)opaque;
- offset -= s->base;
if (offset >= 0x100 && offset < 0x140) {
s->vect_addr[(offset - 0x100) >> 2] = val;
pl190_update_vectors(s);
s->default_addr = val;
break;
case 0xc0: /* ITCR */
- if (val)
- cpu_abort(cpu_single_env, "pl190: Test mode not implemented\n");
+ if (val) {
+ hw_error("pl190: Test mode not implemented\n");
+ }
break;
default:
- cpu_abort(cpu_single_env, "pl190_write: Bad offset %x\n", offset);
+ hw_error("pl190_write: Bad offset %x\n", (int)offset);
return;
}
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
};
-void pl190_reset(pl190_state *s)
+static void pl190_reset(pl190_state *s)
{
int i;
pl190_update_vectors(s);
}
-void *pl190_init(uint32_t base, void *parent, int irq, int fiq)
+static int pl190_init(SysBusDevice *dev)
{
- pl190_state *s;
+ 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,
+ iomemtype = cpu_register_io_memory(pl190_readfn,
pl190_writefn, s);
- cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- s->handler = pl190_set_irq;
- s->base = base;
- s->parent = parent;
- s->irq = irq;
- s->fiq = fiq;
+ 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);
pl190_reset(s);
/* ??? Save/restore. */
- return s;
+ return 0;
}
+
+static void pl190_register_devices(void)
+{
+ sysbus_register_dev("pl190", sizeof(pl190_state), pl190_init);
+}
+
+device_init(pl190_register_devices)