|
@@ -15,6 +15,7 @@
|
|
#include "qemu/timer.h"
|
|
#include "qemu/timer.h"
|
|
#include "hw/ptimer.h"
|
|
#include "hw/ptimer.h"
|
|
#include "sysemu/sysemu.h"
|
|
#include "sysemu/sysemu.h"
|
|
|
|
+#include "hw/sysbus.h"
|
|
|
|
|
|
/* General purpose timer module. */
|
|
/* General purpose timer module. */
|
|
typedef struct {
|
|
typedef struct {
|
|
@@ -159,6 +160,8 @@ static m5206_timer_state *m5206_timer_init(qemu_irq irq)
|
|
/* System Integration Module. */
|
|
/* System Integration Module. */
|
|
|
|
|
|
typedef struct {
|
|
typedef struct {
|
|
|
|
+ SysBusDevice parent_obj;
|
|
|
|
+
|
|
M68kCPU *cpu;
|
|
M68kCPU *cpu;
|
|
MemoryRegion iomem;
|
|
MemoryRegion iomem;
|
|
m5206_timer_state *timer[2];
|
|
m5206_timer_state *timer[2];
|
|
@@ -174,6 +177,8 @@ typedef struct {
|
|
uint8_t uivr[2];
|
|
uint8_t uivr[2];
|
|
} m5206_mbar_state;
|
|
} m5206_mbar_state;
|
|
|
|
|
|
|
|
+#define MCF5206_MBAR(obj) OBJECT_CHECK(m5206_mbar_state, (obj), TYPE_MCF5206_MBAR)
|
|
|
|
+
|
|
/* Interrupt controller. */
|
|
/* Interrupt controller. */
|
|
|
|
|
|
static int m5206_find_pending_irq(m5206_mbar_state *s)
|
|
static int m5206_find_pending_irq(m5206_mbar_state *s)
|
|
@@ -257,8 +262,10 @@ static void m5206_mbar_set_irq(void *opaque, int irq, int level)
|
|
|
|
|
|
/* System Integration Module. */
|
|
/* System Integration Module. */
|
|
|
|
|
|
-static void m5206_mbar_reset(m5206_mbar_state *s)
|
|
|
|
|
|
+static void m5206_mbar_reset(DeviceState *dev)
|
|
{
|
|
{
|
|
|
|
+ m5206_mbar_state *s = MCF5206_MBAR(dev);
|
|
|
|
+
|
|
s->scr = 0xc0;
|
|
s->scr = 0xc0;
|
|
s->icr[1] = 0x04;
|
|
s->icr[1] = 0x04;
|
|
s->icr[2] = 0x08;
|
|
s->icr[2] = 0x08;
|
|
@@ -578,24 +585,43 @@ static const MemoryRegionOps m5206_mbar_ops = {
|
|
.endianness = DEVICE_NATIVE_ENDIAN,
|
|
.endianness = DEVICE_NATIVE_ENDIAN,
|
|
};
|
|
};
|
|
|
|
|
|
-qemu_irq *mcf5206_init(MemoryRegion *sysmem, uint32_t base, M68kCPU *cpu)
|
|
|
|
|
|
+static void mcf5206_mbar_realize(DeviceState *dev, Error **errp)
|
|
{
|
|
{
|
|
- m5206_mbar_state *s;
|
|
|
|
|
|
+ m5206_mbar_state *s = MCF5206_MBAR(dev);
|
|
qemu_irq *pic;
|
|
qemu_irq *pic;
|
|
|
|
|
|
- s = g_new0(m5206_mbar_state, 1);
|
|
|
|
-
|
|
|
|
memory_region_init_io(&s->iomem, NULL, &m5206_mbar_ops, s,
|
|
memory_region_init_io(&s->iomem, NULL, &m5206_mbar_ops, s,
|
|
"mbar", 0x00001000);
|
|
"mbar", 0x00001000);
|
|
- memory_region_add_subregion(sysmem, base, &s->iomem);
|
|
|
|
|
|
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
|
|
|
|
|
|
pic = qemu_allocate_irqs(m5206_mbar_set_irq, s, 14);
|
|
pic = qemu_allocate_irqs(m5206_mbar_set_irq, s, 14);
|
|
s->timer[0] = m5206_timer_init(pic[9]);
|
|
s->timer[0] = m5206_timer_init(pic[9]);
|
|
s->timer[1] = m5206_timer_init(pic[10]);
|
|
s->timer[1] = m5206_timer_init(pic[10]);
|
|
s->uart[0] = mcf_uart_init(pic[12], serial_hd(0));
|
|
s->uart[0] = mcf_uart_init(pic[12], serial_hd(0));
|
|
s->uart[1] = mcf_uart_init(pic[13], serial_hd(1));
|
|
s->uart[1] = mcf_uart_init(pic[13], serial_hd(1));
|
|
- s->cpu = cpu;
|
|
|
|
|
|
+ s->cpu = M68K_CPU(qemu_get_cpu(0));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void mcf5206_mbar_class_init(ObjectClass *oc, void *data)
|
|
|
|
+{
|
|
|
|
+ DeviceClass *dc = DEVICE_CLASS(oc);
|
|
|
|
|
|
- m5206_mbar_reset(s);
|
|
|
|
- return pic;
|
|
|
|
|
|
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
|
|
|
+ dc->desc = "MCF5206 system integration module";
|
|
|
|
+ dc->realize = mcf5206_mbar_realize;
|
|
|
|
+ dc->reset = m5206_mbar_reset;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+static const TypeInfo mcf5206_mbar_info = {
|
|
|
|
+ .name = TYPE_MCF5206_MBAR,
|
|
|
|
+ .parent = TYPE_SYS_BUS_DEVICE,
|
|
|
|
+ .instance_size = sizeof(m5206_mbar_state),
|
|
|
|
+ .class_init = mcf5206_mbar_class_init,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static void mcf5206_mbar_register_types(void)
|
|
|
|
+{
|
|
|
|
+ type_register_static(&mcf5206_mbar_info);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+type_init(mcf5206_mbar_register_types)
|