integratorcp.c 16.8 KB
Newer Older
1
/*
B
bellard 已提交
2 3
 * ARM Integrator CP System emulation.
 *
4
 * Copyright (c) 2005-2007 CodeSourcery.
B
bellard 已提交
5 6
 * Written by Paul Brook
 *
M
Matthew Fernandez 已提交
7
 * This code is licensed under the GPL
B
bellard 已提交
8 9
 */

10
#include "hw/sysbus.h"
11
#include "hw/devices.h"
12
#include "hw/boards.h"
13
#include "hw/arm/arm.h"
14
#include "hw/misc/arm_integrator_debug.h"
P
Paolo Bonzini 已提交
15
#include "net/net.h"
16
#include "exec/address-spaces.h"
17
#include "sysemu/sysemu.h"
B
bellard 已提交
18

19 20 21 22 23 24 25 26 27
#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 >*/

28
    MemoryRegion iomem;
G
Gerd Hoffmann 已提交
29
    uint32_t memsz;
30
    MemoryRegion flash;
B
bellard 已提交
31 32 33 34 35 36 37 38
    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;
39
    uint32_t cm_refcnt_offset;
B
bellard 已提交
40 41 42
    uint32_t int_level;
    uint32_t irq_enabled;
    uint32_t fiq_enabled;
43
} IntegratorCMState;
B
bellard 已提交
44 45 46 47 48 49

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
};

A
Avi Kivity 已提交
50
static uint64_t integratorcm_read(void *opaque, hwaddr offset,
51
                                  unsigned size)
B
bellard 已提交
52
{
53
    IntegratorCMState *s = opaque;
B
bellard 已提交
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
    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.  */
P
Paul Brook 已提交
79
        hw_error("integratorcm_read: CM_LMBUSCNT");
B
bellard 已提交
80 81 82 83 84 85
    case 7: /* CM_AUXOSC */
        return s->cm_auxosc;
    case 8: /* CM_SDRAM */
        return s->cm_sdram;
    case 9: /* CM_INIT */
        return s->cm_init;
86 87 88 89 90 91 92
    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;
B
bellard 已提交
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
    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:
P
Paul Brook 已提交
118 119
        hw_error("integratorcm_read: Unimplemented offset 0x%x\n",
                 (int)offset);
B
bellard 已提交
120 121 122 123
        return 0;
    }
}

124
static void integratorcm_do_remap(IntegratorCMState *s)
B
bellard 已提交
125
{
126 127 128 129
    /* 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));
B
bellard 已提交
130 131
}

132
static void integratorcm_set_ctrl(IntegratorCMState *s, uint32_t value)
B
bellard 已提交
133 134
{
    if (value & 8) {
135
        qemu_system_reset_request();
B
bellard 已提交
136
    }
137 138 139 140 141 142
    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.
         */
B
bellard 已提交
143
    }
144 145
    /* Note that the RESET bit [3] always reads as zero */
    s->cm_ctrl = (s->cm_ctrl & ~5) | (value & 5);
146
    integratorcm_do_remap(s);
B
bellard 已提交
147 148
}

149
static void integratorcm_update(IntegratorCMState *s)
B
bellard 已提交
150 151 152 153
{
    /* ??? 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))
P
Paul Brook 已提交
154
        hw_error("Core module interrupt\n");
B
bellard 已提交
155 156
}

A
Avi Kivity 已提交
157
static void integratorcm_write(void *opaque, hwaddr offset,
158
                               uint64_t value, unsigned size)
B
bellard 已提交
159
{
160
    IntegratorCMState *s = opaque;
B
bellard 已提交
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
    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:
P
Paul Brook 已提交
226 227
        hw_error("integratorcm_write: Unimplemented offset 0x%x\n",
                 (int)offset);
B
bellard 已提交
228 229 230 231 232 233
        break;
    }
}

/* Integrator/CM control registers.  */

234 235 236 237
static const MemoryRegionOps integratorcm_ops = {
    .read = integratorcm_read,
    .write = integratorcm_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
B
bellard 已提交
238 239
};

240
static int integratorcm_init(SysBusDevice *dev)
B
bellard 已提交
241
{
242
    IntegratorCMState *s = INTEGRATOR_CM(dev);
B
bellard 已提交
243 244 245 246 247

    s->cm_osc = 0x01000048;
    /* ??? What should the high bits of this value be?  */
    s->cm_auxosc = 0x0007feff;
    s->cm_sdram = 0x00011122;
G
Gerd Hoffmann 已提交
248
    if (s->memsz >= 256) {
B
bellard 已提交
249 250
        integrator_spd[31] = 64;
        s->cm_sdram |= 0x10;
G
Gerd Hoffmann 已提交
251
    } else if (s->memsz >= 128) {
B
bellard 已提交
252 253
        integrator_spd[31] = 32;
        s->cm_sdram |= 0x0c;
G
Gerd Hoffmann 已提交
254
    } else if (s->memsz >= 64) {
B
bellard 已提交
255 256
        integrator_spd[31] = 16;
        s->cm_sdram |= 0x08;
G
Gerd Hoffmann 已提交
257
    } else if (s->memsz >= 32) {
B
bellard 已提交
258 259 260 261 262 263 264
        integrator_spd[31] = 4;
        s->cm_sdram |= 0x04;
    } else {
        integrator_spd[31] = 2;
    }
    memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
    s->cm_init = 0x00000112;
265 266
    s->cm_refcnt_offset = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24,
                                   1000);
267
    memory_region_init_ram(&s->flash, OBJECT(s), "integrator.flash", 0x100000);
268
    vmstate_register_ram_global(&s->flash);
B
bellard 已提交
269

270
    memory_region_init_io(&s->iomem, OBJECT(s), &integratorcm_ops, s,
271
                          "integratorcm", 0x00800000);
272
    sysbus_init_mmio(dev, &s->iomem);
273

274
    integratorcm_do_remap(s);
B
bellard 已提交
275
    /* ??? Save/restore.  */
276
    return 0;
B
bellard 已提交
277 278 279 280 281
}

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

282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
#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;
B
bellard 已提交
297 298 299 300
} icp_pic_state;

static void icp_pic_update(icp_pic_state *s)
{
301
    uint32_t flags;
B
bellard 已提交
302

P
pbrook 已提交
303 304 305 306
    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);
B
bellard 已提交
307 308
}

309
static void icp_pic_set_irq(void *opaque, int irq, int level)
B
bellard 已提交
310
{
311
    icp_pic_state *s = (icp_pic_state *)opaque;
B
bellard 已提交
312
    if (level)
313
        s->level |= 1 << irq;
B
bellard 已提交
314
    else
315
        s->level &= ~(1 << irq);
B
bellard 已提交
316 317 318
    icp_pic_update(s);
}

A
Avi Kivity 已提交
319
static uint64_t icp_pic_read(void *opaque, hwaddr offset,
320
                             unsigned size)
B
bellard 已提交
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
{
    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:
P
pbrook 已提交
343
        printf ("icp_pic_read: Bad register offset 0x%x\n", (int)offset);
B
bellard 已提交
344 345 346 347
        return 0;
    }
}

A
Avi Kivity 已提交
348
static void icp_pic_write(void *opaque, hwaddr offset,
349
                          uint64_t value, unsigned size)
B
bellard 已提交
350 351 352 353 354 355 356 357 358 359 360 361
{
    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)
P
pbrook 已提交
362
            icp_pic_set_irq(s, 0, 1);
B
bellard 已提交
363 364 365
        break;
    case 5: /* INT_SOFTCLR */
        if (value & 1)
P
pbrook 已提交
366
            icp_pic_set_irq(s, 0, 0);
B
bellard 已提交
367 368 369 370 371 372 373 374 375 376 377 378
        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:
P
pbrook 已提交
379
        printf ("icp_pic_write: Bad register offset 0x%x\n", (int)offset);
B
bellard 已提交
380 381 382 383 384
        return;
    }
    icp_pic_update(s);
}

385 386 387 388
static const MemoryRegionOps icp_pic_ops = {
    .read = icp_pic_read,
    .write = icp_pic_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
B
bellard 已提交
389 390
};

391
static int icp_pic_init(SysBusDevice *sbd)
B
bellard 已提交
392
{
393 394
    DeviceState *dev = DEVICE(sbd);
    icp_pic_state *s = INTEGRATOR_PIC(dev);
B
bellard 已提交
395

396 397 398
    qdev_init_gpio_in(dev, icp_pic_set_irq, 32);
    sysbus_init_irq(sbd, &s->parent_irq);
    sysbus_init_irq(sbd, &s->parent_fiq);
399 400
    memory_region_init_io(&s->iomem, OBJECT(s), &icp_pic_ops, s,
                          "icp-pic", 0x00800000);
401
    sysbus_init_mmio(sbd, &s->iomem);
402
    return 0;
B
bellard 已提交
403 404 405
}

/* CP control registers.  */
406

A
Avi Kivity 已提交
407
static uint64_t icp_control_read(void *opaque, hwaddr offset,
408
                                 unsigned size)
B
bellard 已提交
409 410 411 412 413 414 415 416 417 418 419
{
    switch (offset >> 2) {
    case 0: /* CP_IDFIELD */
        return 0x41034003;
    case 1: /* CP_FLASHPROG */
        return 0;
    case 2: /* CP_INTREG */
        return 0;
    case 3: /* CP_DECODE */
        return 0x11;
    default:
P
Paul Brook 已提交
420
        hw_error("icp_control_read: Bad offset %x\n", (int)offset);
B
bellard 已提交
421 422 423 424
        return 0;
    }
}

A
Avi Kivity 已提交
425
static void icp_control_write(void *opaque, hwaddr offset,
426
                          uint64_t value, unsigned size)
B
bellard 已提交
427 428 429 430 431 432 433 434
{
    switch (offset >> 2) {
    case 1: /* CP_FLASHPROG */
    case 2: /* CP_INTREG */
    case 3: /* CP_DECODE */
        /* Nothing interesting implemented yet.  */
        break;
    default:
P
Paul Brook 已提交
435
        hw_error("icp_control_write: Bad offset %x\n", (int)offset);
B
bellard 已提交
436 437 438
    }
}

439 440 441 442
static const MemoryRegionOps icp_control_ops = {
    .read = icp_control_read,
    .write = icp_control_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
B
bellard 已提交
443 444
};

A
Avi Kivity 已提交
445
static void icp_control_init(hwaddr base)
B
bellard 已提交
446
{
447
    MemoryRegion *io;
B
bellard 已提交
448

449
    io = (MemoryRegion *)g_malloc0(sizeof(MemoryRegion));
450
    memory_region_init_io(io, NULL, &icp_control_ops, NULL,
451 452
                          "control", 0x00800000);
    memory_region_add_subregion(get_system_memory(), base, io);
B
bellard 已提交
453 454 455 456 457 458
    /* ??? Save/restore.  */
}


/* Board init.  */

459 460 461 462 463
static struct arm_boot_info integrator_binfo = {
    .loader_start = 0x0,
    .board_id = 0x113,
};

464
static void integratorcp_init(QEMUMachineInitArgs *args)
B
bellard 已提交
465
{
466 467 468 469 470
    ram_addr_t ram_size = args->ram_size;
    const char *cpu_model = args->cpu_model;
    const char *kernel_filename = args->kernel_filename;
    const char *kernel_cmdline = args->kernel_cmdline;
    const char *initrd_filename = args->initrd_filename;
471
    ARMCPU *cpu;
472 473 474
    MemoryRegion *address_space_mem = get_system_memory();
    MemoryRegion *ram = g_new(MemoryRegion, 1);
    MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
P
Paul Brook 已提交
475 476 477
    qemu_irq pic[32];
    DeviceState *dev;
    int i;
B
bellard 已提交
478

479
    if (!cpu_model) {
P
pbrook 已提交
480
        cpu_model = "arm926";
481 482 483
    }
    cpu = cpu_arm_init(cpu_model);
    if (!cpu) {
B
bellard 已提交
484 485 486
        fprintf(stderr, "Unable to find CPU definition\n");
        exit(1);
    }
487

488
    memory_region_init_ram(ram, NULL, "integrator.ram", ram_size);
489
    vmstate_register_ram_global(ram);
B
bellard 已提交
490
    /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash.  */
T
ths 已提交
491
    /* ??? RAM should repeat to fill physical memory space.  */
B
bellard 已提交
492
    /* SDRAM at address zero*/
493
    memory_region_add_subregion(address_space_mem, 0, ram);
B
bellard 已提交
494
    /* And again at address 0x80000000 */
495
    memory_region_init_alias(ram_alias, NULL, "ram.alias", ram, 0, ram_size);
496
    memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias);
B
bellard 已提交
497

498
    dev = qdev_create(NULL, TYPE_INTEGRATOR_CM);
G
Gerd Hoffmann 已提交
499
    qdev_prop_set_uint32(dev, "memsz", ram_size >> 20);
M
Markus Armbruster 已提交
500
    qdev_init_nofail(dev);
P
Paul Brook 已提交
501 502
    sysbus_mmio_map((SysBusDevice *)dev, 0, 0x10000000);

503
    dev = sysbus_create_varargs(TYPE_INTEGRATOR_PIC, 0x14000000,
504 505 506
                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
                                NULL);
P
Paul Brook 已提交
507
    for (i = 0; i < 32; i++) {
P
Paul Brook 已提交
508
        pic[i] = qdev_get_gpio_in(dev, i);
P
Paul Brook 已提交
509
    }
510
    sysbus_create_simple(TYPE_INTEGRATOR_PIC, 0xca000000, pic[26]);
P
Paul Brook 已提交
511 512
    sysbus_create_varargs("integrator_pit", 0x13000000,
                          pic[5], pic[6], pic[7], NULL);
P
Paul Brook 已提交
513
    sysbus_create_simple("pl031", 0x15000000, pic[8]);
P
Paul Brook 已提交
514 515
    sysbus_create_simple("pl011", 0x16000000, pic[1]);
    sysbus_create_simple("pl011", 0x17000000, pic[2]);
B
bellard 已提交
516
    icp_control_init(0xcb000000);
P
Paul Brook 已提交
517 518
    sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]);
    sysbus_create_simple("pl050_mouse", 0x19000000, pic[4]);
519
    sysbus_create_simple(TYPE_INTEGRATOR_DEBUG, 0x1a000000, 0);
P
Paul Brook 已提交
520
    sysbus_create_varargs("pl181", 0x1c000000, pic[23], pic[24], NULL);
S
Stefan Hajnoczi 已提交
521
    if (nd_table[0].used)
522
        smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
P
Paul Brook 已提交
523 524

    sysbus_create_simple("pl110", 0xc0000000, pic[22]);
B
bellard 已提交
525

526 527 528 529
    integrator_binfo.ram_size = ram_size;
    integrator_binfo.kernel_filename = kernel_filename;
    integrator_binfo.kernel_cmdline = kernel_cmdline;
    integrator_binfo.initrd_filename = initrd_filename;
530
    arm_load_kernel(cpu, &integrator_binfo);
B
bellard 已提交
531 532
}

533
static QEMUMachine integratorcp_machine = {
534 535 536
    .name = "integratorcp",
    .desc = "ARM Integrator/CP (ARM926EJ-S)",
    .init = integratorcp_init,
537
    .is_default = 1,
B
bellard 已提交
538
};
P
Paul Brook 已提交
539

540 541 542 543 544 545 546
static void integratorcp_machine_init(void)
{
    qemu_register_machine(&integratorcp_machine);
}

machine_init(integratorcp_machine_init);

547
static Property core_properties[] = {
548
    DEFINE_PROP_UINT32("memsz", IntegratorCMState, memsz, 0),
549 550 551 552 553
    DEFINE_PROP_END_OF_LIST(),
};

static void core_class_init(ObjectClass *klass, void *data)
{
554
    DeviceClass *dc = DEVICE_CLASS(klass);
555 556 557
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    k->init = integratorcm_init;
558
    dc->props = core_properties;
559 560
}

561
static const TypeInfo core_info = {
562
    .name          = TYPE_INTEGRATOR_CM,
563
    .parent        = TYPE_SYS_BUS_DEVICE,
564
    .instance_size = sizeof(IntegratorCMState),
565
    .class_init    = core_class_init,
566 567 568 569 570 571 572 573 574
};

static void icp_pic_class_init(ObjectClass *klass, void *data)
{
    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);

    sdc->init = icp_pic_init;
}

575
static const TypeInfo icp_pic_info = {
576
    .name          = TYPE_INTEGRATOR_PIC,
577 578 579
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(icp_pic_state),
    .class_init    = icp_pic_class_init,
G
Gerd Hoffmann 已提交
580 581
};

A
Andreas Färber 已提交
582
static void integratorcp_register_types(void)
P
Paul Brook 已提交
583
{
584 585
    type_register_static(&icp_pic_info);
    type_register_static(&core_info);
P
Paul Brook 已提交
586 587
}

A
Andreas Färber 已提交
588
type_init(integratorcp_register_types)