integratorcp.c 15.9 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"
P
Paolo Bonzini 已提交
14
#include "net/net.h"
15
#include "exec/address-spaces.h"
16
#include "sysemu/sysemu.h"
B
bellard 已提交
17 18

typedef struct {
P
Paul Brook 已提交
19
    SysBusDevice busdev;
20
    MemoryRegion iomem;
G
Gerd Hoffmann 已提交
21
    uint32_t memsz;
22
    MemoryRegion flash;
B
bellard 已提交
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
    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 int_level;
    uint32_t irq_enabled;
    uint32_t fiq_enabled;
} integratorcm_state;

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 已提交
41
static uint64_t integratorcm_read(void *opaque, hwaddr offset,
42
                                  unsigned size)
B
bellard 已提交
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
{
    integratorcm_state *s = (integratorcm_state *)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.  */
P
Paul Brook 已提交
70
        hw_error("integratorcm_read: CM_LMBUSCNT");
B
bellard 已提交
71 72 73 74 75 76 77 78
    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_REFCT */
        /* ??? High frequency timer.  */
P
Paul Brook 已提交
79
        hw_error("integratorcm_read: CM_REFCT");
B
bellard 已提交
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
    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 已提交
105 106
        hw_error("integratorcm_read: Unimplemented offset 0x%x\n",
                 (int)offset);
B
bellard 已提交
107 108 109 110
        return 0;
    }
}

111
static void integratorcm_do_remap(integratorcm_state *s)
B
bellard 已提交
112
{
113 114 115 116
    /* 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 已提交
117 118 119 120 121
}

static void integratorcm_set_ctrl(integratorcm_state *s, uint32_t value)
{
    if (value & 8) {
122
        qemu_system_reset_request();
B
bellard 已提交
123
    }
124 125 126 127 128 129
    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 已提交
130
    }
131 132
    /* Note that the RESET bit [3] always reads as zero */
    s->cm_ctrl = (s->cm_ctrl & ~5) | (value & 5);
133
    integratorcm_do_remap(s);
B
bellard 已提交
134 135 136 137 138 139 140
}

static void integratorcm_update(integratorcm_state *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))
P
Paul Brook 已提交
141
        hw_error("Core module interrupt\n");
B
bellard 已提交
142 143
}

A
Avi Kivity 已提交
144
static void integratorcm_write(void *opaque, hwaddr offset,
145
                               uint64_t value, unsigned size)
B
bellard 已提交
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 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
{
    integratorcm_state *s = (integratorcm_state *)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:
P
Paul Brook 已提交
213 214
        hw_error("integratorcm_write: Unimplemented offset 0x%x\n",
                 (int)offset);
B
bellard 已提交
215 216 217 218 219 220
        break;
    }
}

/* Integrator/CM control registers.  */

221 222 223 224
static const MemoryRegionOps integratorcm_ops = {
    .read = integratorcm_read,
    .write = integratorcm_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
B
bellard 已提交
225 226
};

227
static int integratorcm_init(SysBusDevice *dev)
B
bellard 已提交
228
{
P
Paul Brook 已提交
229
    integratorcm_state *s = FROM_SYSBUS(integratorcm_state, dev);
B
bellard 已提交
230 231 232 233 234

    s->cm_osc = 0x01000048;
    /* ??? What should the high bits of this value be?  */
    s->cm_auxosc = 0x0007feff;
    s->cm_sdram = 0x00011122;
G
Gerd Hoffmann 已提交
235
    if (s->memsz >= 256) {
B
bellard 已提交
236 237
        integrator_spd[31] = 64;
        s->cm_sdram |= 0x10;
G
Gerd Hoffmann 已提交
238
    } else if (s->memsz >= 128) {
B
bellard 已提交
239 240
        integrator_spd[31] = 32;
        s->cm_sdram |= 0x0c;
G
Gerd Hoffmann 已提交
241
    } else if (s->memsz >= 64) {
B
bellard 已提交
242 243
        integrator_spd[31] = 16;
        s->cm_sdram |= 0x08;
G
Gerd Hoffmann 已提交
244
    } else if (s->memsz >= 32) {
B
bellard 已提交
245 246 247 248 249 250 251
        integrator_spd[31] = 4;
        s->cm_sdram |= 0x04;
    } else {
        integrator_spd[31] = 2;
    }
    memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
    s->cm_init = 0x00000112;
252
    memory_region_init_ram(&s->flash, NULL, "integrator.flash", 0x100000);
253
    vmstate_register_ram_global(&s->flash);
B
bellard 已提交
254

255
    memory_region_init_io(&s->iomem, NULL, &integratorcm_ops, s,
256
                          "integratorcm", 0x00800000);
257
    sysbus_init_mmio(dev, &s->iomem);
258

259
    integratorcm_do_remap(s);
B
bellard 已提交
260
    /* ??? Save/restore.  */
261
    return 0;
B
bellard 已提交
262 263 264 265 266 267 268
}

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

typedef struct icp_pic_state
{
P
Paul Brook 已提交
269
  SysBusDevice busdev;
270
  MemoryRegion iomem;
B
bellard 已提交
271 272 273
  uint32_t level;
  uint32_t irq_enabled;
  uint32_t fiq_enabled;
P
pbrook 已提交
274 275
  qemu_irq parent_irq;
  qemu_irq parent_fiq;
B
bellard 已提交
276 277 278 279
} icp_pic_state;

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

P
pbrook 已提交
282 283 284 285
    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 已提交
286 287
}

288
static void icp_pic_set_irq(void *opaque, int irq, int level)
B
bellard 已提交
289
{
290
    icp_pic_state *s = (icp_pic_state *)opaque;
B
bellard 已提交
291
    if (level)
292
        s->level |= 1 << irq;
B
bellard 已提交
293
    else
294
        s->level &= ~(1 << irq);
B
bellard 已提交
295 296 297
    icp_pic_update(s);
}

A
Avi Kivity 已提交
298
static uint64_t icp_pic_read(void *opaque, hwaddr offset,
299
                             unsigned size)
B
bellard 已提交
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
{
    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 已提交
322
        printf ("icp_pic_read: Bad register offset 0x%x\n", (int)offset);
B
bellard 已提交
323 324 325 326
        return 0;
    }
}

A
Avi Kivity 已提交
327
static void icp_pic_write(void *opaque, hwaddr offset,
328
                          uint64_t value, unsigned size)
B
bellard 已提交
329 330 331 332 333 334 335 336 337 338 339 340
{
    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 已提交
341
            icp_pic_set_irq(s, 0, 1);
B
bellard 已提交
342 343 344
        break;
    case 5: /* INT_SOFTCLR */
        if (value & 1)
P
pbrook 已提交
345
            icp_pic_set_irq(s, 0, 0);
B
bellard 已提交
346 347 348 349 350 351 352 353 354 355 356 357
        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 已提交
358
        printf ("icp_pic_write: Bad register offset 0x%x\n", (int)offset);
B
bellard 已提交
359 360 361 362 363
        return;
    }
    icp_pic_update(s);
}

364 365 366 367
static const MemoryRegionOps icp_pic_ops = {
    .read = icp_pic_read,
    .write = icp_pic_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
B
bellard 已提交
368 369
};

370
static int icp_pic_init(SysBusDevice *dev)
B
bellard 已提交
371
{
P
Paul Brook 已提交
372
    icp_pic_state *s = FROM_SYSBUS(icp_pic_state, dev);
B
bellard 已提交
373

P
Paul Brook 已提交
374
    qdev_init_gpio_in(&dev->qdev, icp_pic_set_irq, 32);
P
Paul Brook 已提交
375 376
    sysbus_init_irq(dev, &s->parent_irq);
    sysbus_init_irq(dev, &s->parent_fiq);
377
    memory_region_init_io(&s->iomem, NULL, &icp_pic_ops, s, "icp-pic", 0x00800000);
378
    sysbus_init_mmio(dev, &s->iomem);
379
    return 0;
B
bellard 已提交
380 381 382
}

/* CP control registers.  */
383

A
Avi Kivity 已提交
384
static uint64_t icp_control_read(void *opaque, hwaddr offset,
385
                                 unsigned size)
B
bellard 已提交
386 387 388 389 390 391 392 393 394 395 396
{
    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 已提交
397
        hw_error("icp_control_read: Bad offset %x\n", (int)offset);
B
bellard 已提交
398 399 400 401
        return 0;
    }
}

A
Avi Kivity 已提交
402
static void icp_control_write(void *opaque, hwaddr offset,
403
                          uint64_t value, unsigned size)
B
bellard 已提交
404 405 406 407 408 409 410 411
{
    switch (offset >> 2) {
    case 1: /* CP_FLASHPROG */
    case 2: /* CP_INTREG */
    case 3: /* CP_DECODE */
        /* Nothing interesting implemented yet.  */
        break;
    default:
P
Paul Brook 已提交
412
        hw_error("icp_control_write: Bad offset %x\n", (int)offset);
B
bellard 已提交
413 414 415
    }
}

416 417 418 419
static const MemoryRegionOps icp_control_ops = {
    .read = icp_control_read,
    .write = icp_control_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
B
bellard 已提交
420 421
};

A
Avi Kivity 已提交
422
static void icp_control_init(hwaddr base)
B
bellard 已提交
423
{
424
    MemoryRegion *io;
B
bellard 已提交
425

426
    io = (MemoryRegion *)g_malloc0(sizeof(MemoryRegion));
427
    memory_region_init_io(io, NULL, &icp_control_ops, NULL,
428 429
                          "control", 0x00800000);
    memory_region_add_subregion(get_system_memory(), base, io);
B
bellard 已提交
430 431 432 433 434 435
    /* ??? Save/restore.  */
}


/* Board init.  */

436 437 438 439 440
static struct arm_boot_info integrator_binfo = {
    .loader_start = 0x0,
    .board_id = 0x113,
};

441
static void integratorcp_init(QEMUMachineInitArgs *args)
B
bellard 已提交
442
{
443 444 445 446 447
    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;
448
    ARMCPU *cpu;
449 450 451
    MemoryRegion *address_space_mem = get_system_memory();
    MemoryRegion *ram = g_new(MemoryRegion, 1);
    MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
P
Paul Brook 已提交
452
    qemu_irq pic[32];
P
pbrook 已提交
453
    qemu_irq *cpu_pic;
P
Paul Brook 已提交
454 455
    DeviceState *dev;
    int i;
B
bellard 已提交
456

457
    if (!cpu_model) {
P
pbrook 已提交
458
        cpu_model = "arm926";
459 460 461
    }
    cpu = cpu_arm_init(cpu_model);
    if (!cpu) {
B
bellard 已提交
462 463 464
        fprintf(stderr, "Unable to find CPU definition\n");
        exit(1);
    }
465

466
    memory_region_init_ram(ram, NULL, "integrator.ram", ram_size);
467
    vmstate_register_ram_global(ram);
B
bellard 已提交
468
    /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash.  */
T
ths 已提交
469
    /* ??? RAM should repeat to fill physical memory space.  */
B
bellard 已提交
470
    /* SDRAM at address zero*/
471
    memory_region_add_subregion(address_space_mem, 0, ram);
B
bellard 已提交
472
    /* And again at address 0x80000000 */
473
    memory_region_init_alias(ram_alias, NULL, "ram.alias", ram, 0, ram_size);
474
    memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias);
B
bellard 已提交
475

P
Paul Brook 已提交
476
    dev = qdev_create(NULL, "integrator_core");
G
Gerd Hoffmann 已提交
477
    qdev_prop_set_uint32(dev, "memsz", ram_size >> 20);
M
Markus Armbruster 已提交
478
    qdev_init_nofail(dev);
P
Paul Brook 已提交
479 480
    sysbus_mmio_map((SysBusDevice *)dev, 0, 0x10000000);

481
    cpu_pic = arm_pic_init_cpu(cpu);
P
Paul Brook 已提交
482 483 484 485
    dev = sysbus_create_varargs("integrator_pic", 0x14000000,
                                cpu_pic[ARM_PIC_CPU_IRQ],
                                cpu_pic[ARM_PIC_CPU_FIQ], NULL);
    for (i = 0; i < 32; i++) {
P
Paul Brook 已提交
486
        pic[i] = qdev_get_gpio_in(dev, i);
P
Paul Brook 已提交
487
    }
P
Paul Brook 已提交
488 489 490
    sysbus_create_simple("integrator_pic", 0xca000000, pic[26]);
    sysbus_create_varargs("integrator_pit", 0x13000000,
                          pic[5], pic[6], pic[7], NULL);
P
Paul Brook 已提交
491
    sysbus_create_simple("pl031", 0x15000000, pic[8]);
P
Paul Brook 已提交
492 493
    sysbus_create_simple("pl011", 0x16000000, pic[1]);
    sysbus_create_simple("pl011", 0x17000000, pic[2]);
B
bellard 已提交
494
    icp_control_init(0xcb000000);
P
Paul Brook 已提交
495 496
    sysbus_create_simple("pl050_keyboard", 0x18000000, pic[3]);
    sysbus_create_simple("pl050_mouse", 0x19000000, pic[4]);
P
Paul Brook 已提交
497
    sysbus_create_varargs("pl181", 0x1c000000, pic[23], pic[24], NULL);
S
Stefan Hajnoczi 已提交
498
    if (nd_table[0].used)
499
        smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
P
Paul Brook 已提交
500 501

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

503 504 505 506
    integrator_binfo.ram_size = ram_size;
    integrator_binfo.kernel_filename = kernel_filename;
    integrator_binfo.kernel_cmdline = kernel_cmdline;
    integrator_binfo.initrd_filename = initrd_filename;
507
    arm_load_kernel(cpu, &integrator_binfo);
B
bellard 已提交
508 509
}

510
static QEMUMachine integratorcp_machine = {
511 512 513
    .name = "integratorcp",
    .desc = "ARM Integrator/CP (ARM926EJ-S)",
    .init = integratorcp_init,
514
    .is_default = 1,
515
    DEFAULT_MACHINE_OPTIONS,
B
bellard 已提交
516
};
P
Paul Brook 已提交
517

518 519 520 521 522 523 524
static void integratorcp_machine_init(void)
{
    qemu_register_machine(&integratorcp_machine);
}

machine_init(integratorcp_machine_init);

525 526 527 528 529 530 531
static Property core_properties[] = {
    DEFINE_PROP_UINT32("memsz", integratorcm_state, memsz, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static void core_class_init(ObjectClass *klass, void *data)
{
532
    DeviceClass *dc = DEVICE_CLASS(klass);
533 534 535
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    k->init = integratorcm_init;
536
    dc->props = core_properties;
537 538
}

539
static const TypeInfo core_info = {
540 541 542 543
    .name          = "integrator_core",
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(integratorcm_state),
    .class_init    = core_class_init,
544 545 546 547 548 549 550 551 552
};

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

    sdc->init = icp_pic_init;
}

553
static const TypeInfo icp_pic_info = {
554 555 556 557
    .name          = "integrator_pic",
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(icp_pic_state),
    .class_init    = icp_pic_class_init,
G
Gerd Hoffmann 已提交
558 559
};

A
Andreas Färber 已提交
560
static void integratorcp_register_types(void)
P
Paul Brook 已提交
561
{
562 563
    type_register_static(&icp_pic_info);
    type_register_static(&core_info);
P
Paul Brook 已提交
564 565
}

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