* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "hw/sparc/sun4m.h"
#include "monitor/monitor.h"
#include "hw/sysbus.h"
+#include "hw/intc/intc.h"
#include "trace.h"
//#define DEBUG_IRQ_COUNT
uint32_t irl_out;
} SLAVIO_CPUINTCTLState;
+#define TYPE_SLAVIO_INTCTL "slavio_intctl"
+#define SLAVIO_INTCTL(obj) \
+ OBJECT_CHECK(SLAVIO_INTCTLState, (obj), TYPE_SLAVIO_INTCTL)
+
typedef struct SLAVIO_INTCTLState {
- SysBusDevice busdev;
+ SysBusDevice parent_obj;
+
MemoryRegion iomem;
#ifdef DEBUG_IRQ_COUNT
uint64_t irq_count[32];
},
};
-void slavio_pic_info(Monitor *mon, DeviceState *dev)
-{
- SysBusDevice *sd;
- SLAVIO_INTCTLState *s;
- int i;
-
- sd = SYS_BUS_DEVICE(dev);
- s = FROM_SYSBUS(SLAVIO_INTCTLState, sd);
- for (i = 0; i < MAX_CPUS; i++) {
- monitor_printf(mon, "per-cpu %d: pending 0x%08x\n", i,
- s->slaves[i].intreg_pending);
- }
- monitor_printf(mon, "master: pending 0x%08x, disabled 0x%08x\n",
- s->intregm_pending, s->intregm_disabled);
-}
-
-void slavio_irq_info(Monitor *mon, DeviceState *dev)
-{
-#ifndef DEBUG_IRQ_COUNT
- monitor_printf(mon, "irq statistic code not compiled.\n");
-#else
- SysBusDevice *sd;
- SLAVIO_INTCTLState *s;
- int i;
- int64_t count;
-
- sd = SYS_BUS_DEVICE(dev);
- s = FROM_SYSBUS(SLAVIO_INTCTLState, sd);
- monitor_printf(mon, "IRQ statistics:\n");
- for (i = 0; i < 32; i++) {
- count = s->irq_count[i];
- if (count > 0)
- monitor_printf(mon, "%2d: %" PRId64 "\n", i, count);
- }
-#endif
-}
-
static const uint32_t intbit_to_level[] = {
2, 3, 5, 7, 9, 11, 13, 2, 3, 5, 7, 9, 11, 13, 12, 12,
6, 13, 4, 10, 8, 9, 11, 0, 0, 0, 0, 15, 15, 15, 15, 0,
CPU_IRQ_TIMER_IN;
if (i == s->target_cpu) {
for (j = 0; j < 32; j++) {
- if ((s->intregm_pending & (1 << j)) && intbit_to_level[j]) {
+ if ((s->intregm_pending & (1U << j)) && intbit_to_level[j]) {
s->slaves[i].intreg_pending |= 1 << intbit_to_level[j];
}
}
.name ="slavio_intctl_cpu",
.version_id = 1,
.minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField []) {
+ .fields = (VMStateField[]) {
VMSTATE_UINT32(intreg_pending, SLAVIO_CPUINTCTLState),
VMSTATE_END_OF_LIST()
}
.name ="slavio_intctl",
.version_id = 1,
.minimum_version_id = 1,
- .minimum_version_id_old = 1,
.post_load = vmstate_intctl_post_load,
- .fields = (VMStateField []) {
+ .fields = (VMStateField[]) {
VMSTATE_STRUCT_ARRAY(slaves, SLAVIO_INTCTLState, MAX_CPUS, 1,
vmstate_intctl_cpu, SLAVIO_CPUINTCTLState),
VMSTATE_UINT32(intregm_pending, SLAVIO_INTCTLState),
static void slavio_intctl_reset(DeviceState *d)
{
- SLAVIO_INTCTLState *s = container_of(d, SLAVIO_INTCTLState, busdev.qdev);
+ SLAVIO_INTCTLState *s = SLAVIO_INTCTL(d);
int i;
for (i = 0; i < MAX_CPUS; i++) {
slavio_check_interrupts(s, 0);
}
-static int slavio_intctl_init1(SysBusDevice *dev)
+#ifdef DEBUG_IRQ_COUNT
+static bool slavio_intctl_get_statistics(InterruptStatsProvider *obj,
+ uint64_t **irq_counts,
+ unsigned int *nb_irqs)
+{
+ SLAVIO_INTCTLState *s = SLAVIO_INTCTL(obj);
+ *irq_counts = s->irq_count;
+ *nb_irqs = ARRAY_SIZE(s->irq_count);
+ return true;
+}
+#endif
+
+static void slavio_intctl_print_info(InterruptStatsProvider *obj, Monitor *mon)
+{
+ SLAVIO_INTCTLState *s = SLAVIO_INTCTL(obj);
+ int i;
+
+ for (i = 0; i < MAX_CPUS; i++) {
+ monitor_printf(mon, "per-cpu %d: pending 0x%08x\n", i,
+ s->slaves[i].intreg_pending);
+ }
+ monitor_printf(mon, "master: pending 0x%08x, disabled 0x%08x\n",
+ s->intregm_pending, s->intregm_disabled);
+}
+
+static void slavio_intctl_init(Object *obj)
{
- SLAVIO_INTCTLState *s = FROM_SYSBUS(SLAVIO_INTCTLState, dev);
+ DeviceState *dev = DEVICE(obj);
+ SLAVIO_INTCTLState *s = SLAVIO_INTCTL(obj);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
unsigned int i, j;
char slave_name[45];
- qdev_init_gpio_in(&dev->qdev, slavio_set_irq_all, 32 + MAX_CPUS);
- memory_region_init_io(&s->iomem, OBJECT(s), &slavio_intctlm_mem_ops, s,
+ qdev_init_gpio_in(dev, slavio_set_irq_all, 32 + MAX_CPUS);
+ memory_region_init_io(&s->iomem, obj, &slavio_intctlm_mem_ops, s,
"master-interrupt-controller", INTCTLM_SIZE);
- sysbus_init_mmio(dev, &s->iomem);
+ sysbus_init_mmio(sbd, &s->iomem);
for (i = 0; i < MAX_CPUS; i++) {
snprintf(slave_name, sizeof(slave_name),
"slave-interrupt-controller-%i", i);
for (j = 0; j < MAX_PILS; j++) {
- sysbus_init_irq(dev, &s->cpu_irqs[i][j]);
+ sysbus_init_irq(sbd, &s->cpu_irqs[i][j]);
}
memory_region_init_io(&s->slaves[i].iomem, OBJECT(s),
&slavio_intctl_mem_ops,
&s->slaves[i], slave_name, INTCTL_SIZE);
- sysbus_init_mmio(dev, &s->slaves[i].iomem);
+ sysbus_init_mmio(sbd, &s->slaves[i].iomem);
s->slaves[i].cpu = i;
s->slaves[i].master = s;
}
-
- return 0;
}
static void slavio_intctl_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+ InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass);
- k->init = slavio_intctl_init1;
dc->reset = slavio_intctl_reset;
dc->vmsd = &vmstate_intctl;
+#ifdef DEBUG_IRQ_COUNT
+ ic->get_statistics = slavio_intctl_get_statistics;
+#endif
+ ic->print_info = slavio_intctl_print_info;
}
static const TypeInfo slavio_intctl_info = {
- .name = "slavio_intctl",
+ .name = TYPE_SLAVIO_INTCTL,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SLAVIO_INTCTLState),
+ .instance_init = slavio_intctl_init,
.class_init = slavio_intctl_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_INTERRUPT_STATS_PROVIDER },
+ { }
+ },
};
static void slavio_intctl_register_types(void)