/*
 * ARM Integrator CP System emulation.
 *
 * Copyright (c) 2005-2007 CodeSourcery.
 * Written by Paul Brook
 *
 * This code is licensed under the GPL
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-common.h"
#include "cpu.h"
#include "hw/sysbus.h"
#include "hw/devices.h"
#include "hw/boards.h"
#include "hw/arm/arm.h"
#include "hw/misc/arm_integrator_debug.h"
#include "net/net.h"
#include "exec/address-spaces.h"
#include "sysemu/sysemu.h"
#include "qemu/error-report.h"
#include "hw/char/pl011.h"

#define TYPE_INTEGRATOR_CM "integrator_core"
#define INTEGRATOR_CM(obj) \
    OBJECT_CHECK(IntegratorCMState, (obj), TYPE_INTEGRATOR_CM)

typedef struct IntegratorCMState {
    /*< private >*/
    SysBusDevice parent_obj;
    /*< public >*/

    MemoryRegion iomem;
    uint32_t memsz;
    MemoryRegion flash;
    uint32_t cm_osc;
    uint32_t cm_ctrl;
    uint32_t cm_lock;
    uint32_t cm_auxosc;
    uint32_t cm_sdram;
    uint32_t cm_init;
    uint32_t cm_flags;
    uint32_t cm_nvflags;
    uint32_t cm_refcnt_offset;
    uint32_t int_level;
    uint32_t irq_enabled;
    uint32_t fiq_enabled;
} IntegratorCMState;

static uint8_t integrator_spd[128] = {
   128, 8, 4, 11, 9, 1, 64, 0,  2, 0xa0, 0xa0, 0, 0, 8, 0, 1,
   0xe, 4, 0x1c, 1, 2, 0x20, 0xc0, 0, 0, 0, 0, 0x30, 0x28, 0x30, 0x28, 0x40
};

static const VMStateDescription vmstate_integratorcm = {
    .name = "integratorcm",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields      = (VMStateField[]) {
        VMSTATE_UINT32(cm_osc, IntegratorCMState),
        VMSTATE_UINT32(cm_ctrl, IntegratorCMState),
        VMSTATE_UINT32(cm_lock, IntegratorCMState),
        VMSTATE_UINT32(cm_auxosc, IntegratorCMState),
        VMSTATE_UINT32(cm_sdram, IntegratorCMState),
        VMSTATE_UINT32(cm_init, IntegratorCMState),
        VMSTATE_UINT32(cm_flags, IntegratorCMState),
        VMSTATE_UINT32(cm_nvflags, IntegratorCMState),
        VMSTATE_UINT32(int_level, IntegratorCMState),
        VMSTATE_UINT32(irq_enabled, IntegratorCMState),
        VMSTATE_UINT32(fiq_enabled, IntegratorCMState),
        VMSTATE_END_OF_LIST()
    }
};

static uint64_t integratorcm_read(void *opaque, hwaddr offset,
                                  unsigned size)
{
    IntegratorCMState *s = opaque;
    if (offset >= 0x100 && offset < 0x200) {
        /* CM_SPD */
        if (offset >= 0x180)
            return 0;
        return integrator_spd[offset >> 2];
    }
    switch (offset >> 2) {
    case 0: /* CM_ID */
        return 0x411a3001;
    case 1: /* CM_PROC */
        return 0;
    case 2: /* CM_OSC */
        return s->cm_osc;
    case 3: /* CM_CTRL */
        return s->cm_ctrl;
    case 4: /* CM_STAT */
        return 0x00100000;
    case 5: /* CM_LOCK */
        if (s->cm_lock == 0xa05f) {
            return 0x1a05f;
        } else {
            return s->cm_lock;
        }
    case 6: /* CM_LMBUSCNT */
        /* ??? High frequency timer.  */
        hw_error("integratorcm_read: CM_LMBUSCNT");
    case 7: /* CM_AUXOSC */
        return s->cm_auxosc;
    case 8: /* CM_SDRAM */
        return s->cm_sdram;
    case 9: /* CM_INIT */
        return s->cm_init;
    case 10: /* CM_REFCNT */
        /* This register, CM_REFCNT, provides a 32-bit count value.
         * The count increments at the fixed reference clock frequency of 24MHz
         * and can be used as a real-time counter.
         */
        return (uint32_t)muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,
                                  1000) - s->cm_refcnt_offset;
    case 12: /* CM_FLAGS */
        return s->cm_flags;
    case 14: /* CM_NVFLAGS */
        return s->cm_nvflags;
    case 16: /* CM_IRQ_STAT */
        return s->int_level & s->irq_enabled;
    case 17: /* CM_IRQ_RSTAT */
        return s->int_level;
    case 18: /* CM_IRQ_ENSET */
        return s->irq_enabled;
    case 20: /* CM_SOFT_INTSET */
        return s->int_level & 1;
    case 24: /* CM_FIQ_STAT */
        return s->int_level & s->fiq_enabled;
    case 25: /* CM_FIQ_RSTAT */
        return s->int_level;
    case 26: /* CM_FIQ_ENSET */
        return s->fiq_enabled;
    case 32: /* CM_VOLTAGE_CTL0 */
    case 33: /* CM_VOLTAGE_CTL1 */
    case 34: /* CM_VOLTAGE_CTL2 */
    case 35: /* CM_VOLTAGE_CTL3 */
        /* ??? Voltage control unimplemented.  */
        return 0;
    default:
        hw_error("integratorcm_read: Unimplemented offset 0x%x\n",
                 (int)offset);
        return 0;
    }
}

static void integratorcm_do_remap(IntegratorCMState *s)
{
    /* Sync memory region state with CM_CTRL REMAP bit:
     * bit 0 => flash at address 0; bit 1 => RAM
     */
    memory_region_set_enabled(&s->flash, !(s->cm_ctrl & 4));
}

static void integratorcm_set_ctrl(IntegratorCMState *s, uint32_t value)
{
    if (value & 8) {
        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
    }
    if ((s->cm_ctrl ^ value) & 1) {
        /* (value & 1) != 0 means the green "MISC LED" is lit.
         * We don't have any nice place to display LEDs. printf is a bad
         * idea because Linux uses the LED as a heartbeat and the output
         * will swamp anything else on the terminal.
         */
    }
    /* Note that the RESET bit [3] always reads as zero */
    s->cm_ctrl = (s->cm_ctrl & ~5) | (value & 5);
    integratorcm_do_remap(s);
}

static void integratorcm_update(IntegratorCMState *s)
{
    /* ??? The CPU irq/fiq is raised when either the core module or base PIC
       are active.  */
    if (s->int_level & (s->irq_enabled | s->fiq_enabled))
        hw_error("Core module interrupt\n");
}

static void integratorcm_write(void *opaque, hwaddr offset,
                               uint64_t value, unsigned size)
{
    IntegratorCMState *s = opaque;
    switch (offset >> 2) {
    case 2: /* CM_OSC */
        if (s->cm_lock == 0xa05f)
            s->cm_osc = value;
        break;
    case 3: /* CM_CTRL */
        integratorcm_set_ctrl(s, value);
        break;
    case 5: /* CM_LOCK */
        s->cm_lock = value & 0xffff;
        break;
    case 7: /* CM_AUXOSC */
        if (s->cm_lock == 0xa05f)
            s->cm_auxosc = value;
        break;
    case 8: /* CM_SDRAM */
        s->cm_sdram = value;
        break;
    case 9: /* CM_INIT */
        /* ??? This can change the memory bus frequency.  */
        s->cm_init = value;
        break;
    case 12: /* CM_FLAGSS */
        s->cm_flags |= value;
        break;
    case 13: /* CM_FLAGSC */
        s->cm_flags &= ~value;
        break;
    case 14: /* CM_NVFLAGSS */
        s->cm_nvflags |= value;
        break;
    case 15: /* CM_NVFLAGSS */
        s->cm_nvflags &= ~value;
        break;
    case 18: /* CM_IRQ_ENSET */
        s->irq_enabled |= value;
        integratorcm_update(s);
        break;
    case 19: /* CM_IRQ_ENCLR */
        s->irq_enabled &= ~value;
        integratorcm_update(s);
        break;
    case 20: /* CM_SOFT_INTSET */
        s->int_level |= (value & 1);
        integratorcm_update(s);
        break;
    case 21: /* CM_SOFT_INTCLR */
        s->int_level &= ~(value & 1);
        integratorcm_update(s);
        break;
    case 26: /* CM_FIQ_ENSET */
        s->fiq_enabled |= value;
        integratorcm_update(s);
        break;
    case 27: /* CM_FIQ_ENCLR */
        s->fiq_enabled &= ~value;
        integratorcm_update(s);
        break;
    case 32: /* CM_VOLTAGE_CTL0 */
    case 33: /* CM_VOLTAGE_CTL1 */
    case 34: /* CM_VOLTAGE_CTL2 */
    case 35: /* CM_VOLTAGE_CTL3 */
        /* ??? Voltage control unimplemented.  */
        break;
    default:
        hw_error("integratorcm_write: Unimplemented offset 0x%x\n",
                 (int)offset);
        break;
    }
}

/* Integrator/CM control registers.  */

static const MemoryRegionOps integratorcm_ops = {
    .read = integratorcm_read,
    .write = integratorcm_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void integratorcm_init(Object *obj)
{
    IntegratorCMState *s = INTEGRATOR_CM(obj);
    SysBusDevice *dev = SYS_BUS_DEVICE(obj);

    s->cm_osc = 0x01000048;
    /* ??? What should the high bits of this value be?  */
    s->cm_auxosc = 0x0007feff;
    s->cm_sdram = 0x00011122;
    memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
    s->cm_init = 0x00000112;
    s->cm_refcnt_offset = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,
                                   1000);
    memory_region_init_ram(&s->flash, obj, "integrator.flash", 0x100000,
                           &error_fatal);
    vmstate_register_ram_global(&s->flash);

    memory_region_init_io(&s->iomem, obj, &integratorcm_ops, s,
                          "integratorcm", 0x00800000);
    sysbus_init_mmio(dev, &s->iomem);

    integratorcm_do_remap(s);
    /* ??? Save/restore.  */
}

static void integratorcm_realize(DeviceState *d, Error **errp)
{
    IntegratorCMState *s = INTEGRATOR_CM(d);

    if (s->memsz >= 256) {
        integrator_spd[31] = 64;
        s->cm_sdram |= 0x10;
    } else if (s->memsz >= 128) {
        integrator_spd[31] = 32;
        s->cm_sdram |= 0x0c;
    } else if (s->memsz >= 64) {
        integrator_spd[31] = 16;
        s->cm_sdram |= 0x08;
    } else if (s->memsz >= 32) {
        integrator_spd[31] = 4;
        s->cm_sdram |= 0x04;
    } else {
        integrator_spd[31] = 2;
    }
}

/* Integrator/CP hardware emulation.  */
/* Primary interrupt controller.  */

#define TYPE_INTEGRATOR_PIC "integrator_pic"
#define INTEGRATOR_PIC(obj) \
   OBJECT_CHECK(icp_pic_state, (obj), TYPE_INTEGRATOR_PIC)

typedef struct icp_pic_state {
    /*< private >*/
    SysBusDevice parent_obj;
    /*< public >*/

    MemoryRegion iomem;
    uint32_t level;
    uint32_t irq_enabled;
    uint32_t fiq_enabled;
    qemu_irq parent_irq;
    qemu_irq parent_fiq;
} icp_pic_state;

static const VMStateDescription vmstate_icp_pic = {
    .name = "icp_pic",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields      = (VMStateField[]) {
        VMSTATE_UINT32(level, icp_pic_state),
        VMSTATE_UINT32(irq_enabled, icp_pic_state),
        VMSTATE_UINT32(fiq_enabled, icp_pic_state),
        VMSTATE_END_OF_LIST()
    }
};

static void icp_pic_update(icp_pic_state *s)
{
    uint32_t flags;

    flags = (s->level & s->irq_enabled);
    qemu_set_irq(s->parent_irq, flags != 0);
    flags = (s->level & s->fiq_enabled);
    qemu_set_irq(s->parent_fiq, flags != 0);
}

static void icp_pic_set_irq(void *opaque, int irq, int level)
{
    icp_pic_state *s = (icp_pic_state *)opaque;
    if (level)
        s->level |= 1 << irq;
    else
        s->level &= ~(1 << irq);
    icp_pic_update(s);
}

static uint64_t icp_pic_read(void *opaque, hwaddr offset,
                             unsigned size)
{
    icp_pic_state *s = (icp_pic_state *)opaque;

    switch (offset >> 2) {
    case 0: /* IRQ_STATUS */
        return s->level & s->irq_enabled;
    case 1: /* IRQ_RAWSTAT */
        return s->level;
    case 2: /* IRQ_ENABLESET */
        return s->irq_enabled;
    case 4: /* INT_SOFTSET */
        return s->level & 1;
    case 8: /* FRQ_STATUS */
        return s->level & s->fiq_enabled;
    case 9: /* FRQ_RAWSTAT */
        return s->level;
    case 10: /* FRQ_ENABLESET */
        return s->fiq_enabled;
    case 3: /* IRQ_ENABLECLR */
    case 5: /* INT_SOFTCLR */
    case 11: /* FRQ_ENABLECLR */
    default:
        printf ("icp_pic_read: Bad register offset 0x%x\n", (int)offset);
        return 0;
    }
}

static void icp_pic_write(void *opaque, hwaddr offset,
                          uint64_t value, unsigned size)
{
    icp_pic_state *s = (icp_pic_state *)opaque;

    switch (offset >> 2) {
    case 2: /* IRQ_ENABLESET */
        s->irq_enabled |= value;
        break;
    case 3: /* IRQ_ENABLECLR */
        s->irq_enabled &= ~value;
        break;
    case 4: /* INT_SOFTSET */
        if (value & 1)
            icp_pic_set_irq(s, 0, 1);
        break;
    case 5: /* INT_SOFTCLR */
        if (value & 1)
            icp_pic_set_irq(s, 0, 0);
        break;
    case 10: /* FRQ_ENABLESET */
        s->fiq_enabled |= value;
        break;
    case 11: /* FRQ_ENABLECLR */
        s->fiq_enabled &= ~value;
        break;
    case 0: /* IRQ_STATUS */
    case 1: /* IRQ_RAWSTAT */
    case 8: /* FRQ_STATUS */
    case 9: /* FRQ_RAWSTAT */
    default:
        printf ("icp_pic_write: Bad register offset 0x%x\n", (int)offset);
        return;
    }
    icp_pic_update(s);
}

static const MemoryRegionOps icp_pic_ops = {
    .read = icp_pic_read,
    .write = icp_pic_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void icp_pic_init(Object *obj)
{
    DeviceState *dev = DEVICE(obj);
    icp_pic_state *s = INTEGRATOR_PIC(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    qdev_init_gpio_in(dev, icp_pic_set_irq, 32);
    sysbus_init_irq(sbd, &s->parent_irq);
    sysbus_init_irq(sbd, &s->parent_fiq);
    memory_region_init_io(&s->iomem, obj, &icp_pic_ops, s,
                          "icp-pic", 0x00800000);
    sysbus_init_mmio(sbd, &s->iomem);
}

/* CP control registers.  */

#define TYPE_ICP_CONTROL_REGS "icp-ctrl-regs"
#define ICP_CONTROL_REGS(obj) \
    OBJECT_CHECK(ICPCtrlRegsState, (obj), TYPE_ICP_CONTROL_REGS)

typedef struct ICPCtrlRegsState {
    /*< private >*/
    SysBusDevice parent_obj;
    /*< public >*/

    MemoryRegion iomem;

    qemu_irq mmc_irq;
    uint32_t intreg_state;
} ICPCtrlRegsState;

#define ICP_GPIO_MMC_WPROT      "mmc-wprot"
#define ICP_GPIO_MMC_CARDIN     "mmc-cardin"

#define ICP_INTREG_WPROT        (1 << 0)
#define ICP_INTREG_CARDIN       (1 << 3)

static const VMStateDescription vmstate_icp_control = {
    .name = "icp_control",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields      = (VMStateField[]) {
        VMSTATE_UINT32(intreg_state, ICPCtrlRegsState),
        VMSTATE_END_OF_LIST()
    }
};

static uint64_t icp_control_read(void *opaque, hwaddr offset,
                                 unsigned size)
{
    ICPCtrlRegsState *s = opaque;

    switch (offset >> 2) {
    case 0: /* CP_IDFIELD */
        return 0x41034003;
    case 1: /* CP_FLASHPROG */
        return 0;
    case 2: /* CP_INTREG */
        return s->intreg_state;
    case 3: /* CP_DECODE */
        return 0x11;
    default:
        hw_error("icp_control_read: Bad offset %x\n", (int)offset);
        return 0;
    }
}

static void icp_control_write(void *opaque, hwaddr offset,
                          uint64_t value, unsigned size)
{
    ICPCtrlRegsState *s = opaque;

    switch (offset >> 2) {
    case 2: /* CP_INTREG */
        s->intreg_state &= ~(value & ICP_INTREG_CARDIN);
        qemu_set_irq(s->mmc_irq, !!(s->intreg_state & ICP_INTREG_CARDIN));
        break;
    case 1: /* CP_FLASHPROG */
    case 3: /* CP_DECODE */
        /* Nothing interesting implemented yet.  */
        break;
    default:
        hw_error("icp_control_write: Bad offset %x\n", (int)offset);
    }
}

static const MemoryRegionOps icp_control_ops = {
    .read = icp_control_read,
    .write = icp_control_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void icp_control_mmc_wprot(void *opaque, int line, int level)
{
    ICPCtrlRegsState *s = opaque;

    s->intreg_state &= ~ICP_INTREG_WPROT;
    if (level) {
        s->intreg_state |= ICP_INTREG_WPROT;
    }
}

static void icp_control_mmc_cardin(void *opaque, int line, int level)
{
    ICPCtrlRegsState *s = opaque;

    /* line is released by writing to CP_INTREG */
    if (level) {
        s->intreg_state |= ICP_INTREG_CARDIN;
        qemu_set_irq(s->mmc_irq, 1);
    }
}

static void icp_control_init(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    ICPCtrlRegsState *s = ICP_CONTROL_REGS(obj);
    DeviceState *dev = DEVICE(obj);

    memory_region_init_io(&s->iomem, OBJECT(s), &icp_control_ops, s,
                          "icp_ctrl_regs", 0x00800000);
    sysbus_init_mmio(sbd, &s->iomem);

    qdev_init_gpio_in_named(dev, icp_control_mmc_wprot, ICP_GPIO_MMC_WPROT, 1);
    qdev_init_gpio_in_named(dev, icp_control_mmc_cardin,
                            ICP_GPIO_MMC_CARDIN, 1);
    sysbus_init_irq(sbd, &s->mmc_irq);
}


/* Board init.  */

static struct arm_boot_info integrator_binfo = {
    .loader_start = 0x0,
    .board_id = 0x113,
};

static void integratorcp_init(MachineState *machine)
{
    ram_addr_t ram_size = machine->ram_size;
    const char *cpu_model = machine->cpu_model;
    const char *kernel_filename = machine->kernel_filename;
    const char *kernel_cmdline = machine->kernel_cmdline;
    const char *initrd_filename = machine->initrd_filename;
    char **cpustr;
    ObjectClass *cpu_oc;
    CPUClass *cc;
    Object *cpuobj;
    ARMCPU *cpu;
    const char *typename;
    MemoryRegion *address_space_mem = get_system_memory();
    MemoryRegion *ram = g_new(MemoryRegion, 1);
    MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
    qemu_irq pic[32];
    DeviceState *dev, *sic, *icp;
    int i;
    Error *err = NULL;

    if (!cpu_model) {
        cpu_model = "arm926";
    }

    cpustr = g_strsplit(cpu_model, ",", 2);

    cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]);
    if (!cpu_oc) {
        fprintf(stderr, "Unable to find CPU definition\n");
        exit(1);
    }
    typename = object_class_get_name(cpu_oc);

    cc = CPU_CLASS(cpu_oc);
    cc->parse_features(typename, cpustr[1], &err);
    g_strfreev(cpustr);
    if (err) {
        error_report_err(err);
        exit(1);
    }

    cpuobj = object_new(typename);

    /* By default ARM1176 CPUs have EL3 enabled.  This board does not
     * currently support EL3 so the CPU EL3 property is disabled before
     * realization.
     */
    if (object_property_find(cpuobj, "has_el3", NULL)) {
        object_property_set_bool(cpuobj, false, "has_el3", &error_fatal);
    }

    object_property_set_bool(cpuobj, true, "realized", &error_fatal);

    cpu = ARM_CPU(cpuobj);

    memory_region_allocate_system_memory(ram, NULL, "integrator.ram",
                                         ram_size);
    /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash.  */
    /* ??? RAM should repeat to fill physical memory space.  */
    /* SDRAM at address zero*/
    memory_region_add_subregion(address_space_mem, 0, ram);
    /* And again at address 0x80000000 */
    memory_region_init_alias(ram_alias, NULL, "ram.alias", ram, 0, ram_size);
    memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias);

    dev = qdev_create(NULL, TYPE_INTEGRATOR_CM);
    qdev_prop_set_uint32(dev, "memsz", ram_size >> 20);
    qdev_init_nofail(dev);
    sysbus_mmio_map((SysBusDevice *)dev, 0, 0x10000000);

    dev = sysbus_create_varargs(TYPE_INTEGRATOR_PIC, 0x14000000,
                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
                                NULL);
    for (i = 0; i < 32; i++) {
        pic[i] = qdev_get_gpio_in(dev, i);
    }
    sic = sysbus_create_simple(TYPE_INTEGRATOR_PIC, 0xca000000, pic[26]);
    sysbus_create_varargs("integrator_pit", 0x13000000,
                          pic[5], pic[6], pic[7], NULL);
    sysbus_create_simple("pl031", 0x15000000, pic[8]);
    pl011_create(0x16000000, pic[1], serial_hds[0]);
    pl011_create(0x17000000, pic[2], serial_hds[1]);
    icp = sysbus_create_simple(TYPE_ICP_CONTROL_REGS, 0xcb000000,
                               qdev_get_gpio_in(sic, 3));
    sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]);
    sysbus_create_simple("pl050_mouse", 0x19000000, pic[4]);
    sysbus_create_simple(TYPE_INTEGRATOR_DEBUG, 0x1a000000, 0);

    dev = sysbus_create_varargs("pl181", 0x1c000000, pic[23], pic[24], NULL);
    qdev_connect_gpio_out(dev, 0,
                          qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_WPROT, 0));
    qdev_connect_gpio_out(dev, 1,
                          qdev_get_gpio_in_named(icp, ICP_GPIO_MMC_CARDIN, 0));

    if (nd_table[0].used)
        smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);

    sysbus_create_simple("pl110", 0xc0000000, pic[22]);

    integrator_binfo.ram_size = ram_size;
    integrator_binfo.kernel_filename = kernel_filename;
    integrator_binfo.kernel_cmdline = kernel_cmdline;
    integrator_binfo.initrd_filename = initrd_filename;
    arm_load_kernel(cpu, &integrator_binfo);
}

static void integratorcp_machine_init(MachineClass *mc)
{
    mc->desc = "ARM Integrator/CP (ARM926EJ-S)";
    mc->init = integratorcp_init;
}

DEFINE_MACHINE("integratorcp", integratorcp_machine_init)

static Property core_properties[] = {
    DEFINE_PROP_UINT32("memsz", IntegratorCMState, memsz, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static void core_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->props = core_properties;
    dc->realize = integratorcm_realize;
    dc->vmsd = &vmstate_integratorcm;
}

static void icp_pic_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->vmsd = &vmstate_icp_pic;
}

static void icp_control_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->vmsd = &vmstate_icp_control;
}

static const TypeInfo core_info = {
    .name          = TYPE_INTEGRATOR_CM,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(IntegratorCMState),
    .instance_init = integratorcm_init,
    .class_init    = core_class_init,
};

static const TypeInfo icp_pic_info = {
    .name          = TYPE_INTEGRATOR_PIC,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(icp_pic_state),
    .instance_init = icp_pic_init,
    .class_init    = icp_pic_class_init,
};

static const TypeInfo icp_ctrl_regs_info = {
    .name          = TYPE_ICP_CONTROL_REGS,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(ICPCtrlRegsState),
    .instance_init = icp_control_init,
    .class_init    = icp_control_class_init,
};

static void integratorcp_register_types(void)
{
    type_register_static(&icp_pic_info);
    type_register_static(&core_info);
    type_register_static(&icp_ctrl_regs_info);
}

type_init(integratorcp_register_types)
