cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

exynos4210.c (19379B)


      1/*
      2 *  Samsung exynos4210 SoC emulation
      3 *
      4 *  Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
      5 *    Maksim Kozlov <m.kozlov@samsung.com>
      6 *    Evgeny Voevodin <e.voevodin@samsung.com>
      7 *    Igor Mitsyanko  <i.mitsyanko@samsung.com>
      8 *
      9 *  This program is free software; you can redistribute it and/or modify it
     10 *  under the terms of the GNU General Public License as published by the
     11 *  Free Software Foundation; either version 2 of the License, or
     12 *  (at your option) any later version.
     13 *
     14 *  This program is distributed in the hope that it will be useful, but WITHOUT
     15 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     16 *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
     17 *  for more details.
     18 *
     19 *  You should have received a copy of the GNU General Public License along
     20 *  with this program; if not, see <http://www.gnu.org/licenses/>.
     21 *
     22 */
     23
     24#include "qemu/osdep.h"
     25#include "qapi/error.h"
     26#include "cpu.h"
     27#include "hw/cpu/a9mpcore.h"
     28#include "hw/irq.h"
     29#include "sysemu/blockdev.h"
     30#include "sysemu/sysemu.h"
     31#include "hw/sysbus.h"
     32#include "hw/arm/boot.h"
     33#include "hw/loader.h"
     34#include "hw/qdev-properties.h"
     35#include "hw/arm/exynos4210.h"
     36#include "hw/sd/sdhci.h"
     37#include "hw/usb/hcd-ehci.h"
     38
     39#define EXYNOS4210_CHIPID_ADDR         0x10000000
     40
     41/* PWM */
     42#define EXYNOS4210_PWM_BASE_ADDR       0x139D0000
     43
     44/* RTC */
     45#define EXYNOS4210_RTC_BASE_ADDR       0x10070000
     46
     47/* MCT */
     48#define EXYNOS4210_MCT_BASE_ADDR       0x10050000
     49
     50/* I2C */
     51#define EXYNOS4210_I2C_SHIFT           0x00010000
     52#define EXYNOS4210_I2C_BASE_ADDR       0x13860000
     53/* Interrupt Group of External Interrupt Combiner for I2C */
     54#define EXYNOS4210_I2C_INTG            27
     55#define EXYNOS4210_HDMI_INTG           16
     56
     57/* UART's definitions */
     58#define EXYNOS4210_UART0_BASE_ADDR     0x13800000
     59#define EXYNOS4210_UART1_BASE_ADDR     0x13810000
     60#define EXYNOS4210_UART2_BASE_ADDR     0x13820000
     61#define EXYNOS4210_UART3_BASE_ADDR     0x13830000
     62#define EXYNOS4210_UART0_FIFO_SIZE     256
     63#define EXYNOS4210_UART1_FIFO_SIZE     64
     64#define EXYNOS4210_UART2_FIFO_SIZE     16
     65#define EXYNOS4210_UART3_FIFO_SIZE     16
     66/* Interrupt Group of External Interrupt Combiner for UART */
     67#define EXYNOS4210_UART_INT_GRP        26
     68
     69/* External GIC */
     70#define EXYNOS4210_EXT_GIC_CPU_BASE_ADDR    0x10480000
     71#define EXYNOS4210_EXT_GIC_DIST_BASE_ADDR   0x10490000
     72
     73/* Combiner */
     74#define EXYNOS4210_EXT_COMBINER_BASE_ADDR   0x10440000
     75#define EXYNOS4210_INT_COMBINER_BASE_ADDR   0x10448000
     76
     77/* SD/MMC host controllers */
     78#define EXYNOS4210_SDHCI_CAPABILITIES       0x05E80080
     79#define EXYNOS4210_SDHCI_BASE_ADDR          0x12510000
     80#define EXYNOS4210_SDHCI_ADDR(n)            (EXYNOS4210_SDHCI_BASE_ADDR + \
     81                                                0x00010000 * (n))
     82#define EXYNOS4210_SDHCI_NUMBER             4
     83
     84/* PMU SFR base address */
     85#define EXYNOS4210_PMU_BASE_ADDR            0x10020000
     86
     87/* Clock controller SFR base address */
     88#define EXYNOS4210_CLK_BASE_ADDR            0x10030000
     89
     90/* PRNG/HASH SFR base address */
     91#define EXYNOS4210_RNG_BASE_ADDR            0x10830400
     92
     93/* Display controllers (FIMD) */
     94#define EXYNOS4210_FIMD0_BASE_ADDR          0x11C00000
     95
     96/* EHCI */
     97#define EXYNOS4210_EHCI_BASE_ADDR           0x12580000
     98
     99/* DMA */
    100#define EXYNOS4210_PL330_BASE0_ADDR         0x12680000
    101#define EXYNOS4210_PL330_BASE1_ADDR         0x12690000
    102#define EXYNOS4210_PL330_BASE2_ADDR         0x12850000
    103
    104static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
    105                                    0x09, 0x00, 0x00, 0x00 };
    106
    107static uint64_t exynos4210_chipid_and_omr_read(void *opaque, hwaddr offset,
    108                                               unsigned size)
    109{
    110    assert(offset < sizeof(chipid_and_omr));
    111    return chipid_and_omr[offset];
    112}
    113
    114static void exynos4210_chipid_and_omr_write(void *opaque, hwaddr offset,
    115                                            uint64_t value, unsigned size)
    116{
    117    return;
    118}
    119
    120static const MemoryRegionOps exynos4210_chipid_and_omr_ops = {
    121    .read = exynos4210_chipid_and_omr_read,
    122    .write = exynos4210_chipid_and_omr_write,
    123    .endianness = DEVICE_NATIVE_ENDIAN,
    124    .impl = {
    125        .max_access_size = 1,
    126    }
    127};
    128
    129void exynos4210_write_secondary(ARMCPU *cpu,
    130        const struct arm_boot_info *info)
    131{
    132    int n;
    133    uint32_t smpboot[] = {
    134        0xe59f3034, /* ldr r3, External gic_cpu_if */
    135        0xe59f2034, /* ldr r2, Internal gic_cpu_if */
    136        0xe59f0034, /* ldr r0, startaddr */
    137        0xe3a01001, /* mov r1, #1 */
    138        0xe5821000, /* str r1, [r2] */
    139        0xe5831000, /* str r1, [r3] */
    140        0xe3a010ff, /* mov r1, #0xff */
    141        0xe5821004, /* str r1, [r2, #4] */
    142        0xe5831004, /* str r1, [r3, #4] */
    143        0xf57ff04f, /* dsb */
    144        0xe320f003, /* wfi */
    145        0xe5901000, /* ldr     r1, [r0] */
    146        0xe1110001, /* tst     r1, r1 */
    147        0x0afffffb, /* beq     <wfi> */
    148        0xe12fff11, /* bx      r1 */
    149        EXYNOS4210_EXT_GIC_CPU_BASE_ADDR,
    150        0,          /* gic_cpu_if: base address of Internal GIC CPU interface */
    151        0           /* bootreg: Boot register address is held here */
    152    };
    153    smpboot[ARRAY_SIZE(smpboot) - 1] = info->smp_bootreg_addr;
    154    smpboot[ARRAY_SIZE(smpboot) - 2] = info->gic_cpu_if_addr;
    155    for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
    156        smpboot[n] = tswap32(smpboot[n]);
    157    }
    158    rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot),
    159                       info->smp_loader_start);
    160}
    161
    162static uint64_t exynos4210_calc_affinity(int cpu)
    163{
    164    /* Exynos4210 has 0x9 as cluster ID */
    165    return (0x9 << ARM_AFF1_SHIFT) | cpu;
    166}
    167
    168static DeviceState *pl330_create(uint32_t base, qemu_or_irq *orgate,
    169                                 qemu_irq irq, int nreq, int nevents, int width)
    170{
    171    SysBusDevice *busdev;
    172    DeviceState *dev;
    173    int i;
    174
    175    dev = qdev_new("pl330");
    176    object_property_set_link(OBJECT(dev), "memory",
    177                             OBJECT(get_system_memory()),
    178                             &error_fatal);
    179    qdev_prop_set_uint8(dev, "num_events", nevents);
    180    qdev_prop_set_uint8(dev, "num_chnls",  8);
    181    qdev_prop_set_uint8(dev, "num_periph_req",  nreq);
    182
    183    qdev_prop_set_uint8(dev, "wr_cap", 4);
    184    qdev_prop_set_uint8(dev, "wr_q_dep", 8);
    185    qdev_prop_set_uint8(dev, "rd_cap", 4);
    186    qdev_prop_set_uint8(dev, "rd_q_dep", 8);
    187    qdev_prop_set_uint8(dev, "data_width", width);
    188    qdev_prop_set_uint16(dev, "data_buffer_dep", width);
    189    busdev = SYS_BUS_DEVICE(dev);
    190    sysbus_realize_and_unref(busdev, &error_fatal);
    191    sysbus_mmio_map(busdev, 0, base);
    192
    193    object_property_set_int(OBJECT(orgate), "num-lines", nevents + 1,
    194                            &error_abort);
    195    qdev_realize(DEVICE(orgate), NULL, &error_abort);
    196
    197    for (i = 0; i < nevents + 1; i++) {
    198        sysbus_connect_irq(busdev, i, qdev_get_gpio_in(DEVICE(orgate), i));
    199    }
    200    qdev_connect_gpio_out(DEVICE(orgate), 0, irq);
    201    return dev;
    202}
    203
    204static void exynos4210_realize(DeviceState *socdev, Error **errp)
    205{
    206    Exynos4210State *s = EXYNOS4210_SOC(socdev);
    207    MemoryRegion *system_mem = get_system_memory();
    208    qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
    209    SysBusDevice *busdev;
    210    DeviceState *dev, *uart[4], *pl330[3];
    211    int i, n;
    212
    213    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
    214        Object *cpuobj = object_new(ARM_CPU_TYPE_NAME("cortex-a9"));
    215
    216        /* By default A9 CPUs have EL3 enabled.  This board does not currently
    217         * support EL3 so the CPU EL3 property is disabled before realization.
    218         */
    219        if (object_property_find(cpuobj, "has_el3")) {
    220            object_property_set_bool(cpuobj, "has_el3", false, &error_fatal);
    221        }
    222
    223        s->cpu[n] = ARM_CPU(cpuobj);
    224        object_property_set_int(cpuobj, "mp-affinity",
    225                                exynos4210_calc_affinity(n), &error_abort);
    226        object_property_set_int(cpuobj, "reset-cbar",
    227                                EXYNOS4210_SMP_PRIVATE_BASE_ADDR,
    228                                &error_abort);
    229        qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
    230    }
    231
    232    /*** IRQs ***/
    233
    234    s->irq_table = exynos4210_init_irq(&s->irqs);
    235
    236    /* IRQ Gate */
    237    for (i = 0; i < EXYNOS4210_NCPUS; i++) {
    238        dev = qdev_new("exynos4210.irq_gate");
    239        qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
    240        sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
    241        /* Get IRQ Gate input in gate_irq */
    242        for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
    243            gate_irq[i][n] = qdev_get_gpio_in(dev, n);
    244        }
    245        busdev = SYS_BUS_DEVICE(dev);
    246
    247        /* Connect IRQ Gate output to CPU's IRQ line */
    248        sysbus_connect_irq(busdev, 0,
    249                           qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
    250    }
    251
    252    /* Private memory region and Internal GIC */
    253    dev = qdev_new(TYPE_A9MPCORE_PRIV);
    254    qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
    255    busdev = SYS_BUS_DEVICE(dev);
    256    sysbus_realize_and_unref(busdev, &error_fatal);
    257    sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
    258    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
    259        sysbus_connect_irq(busdev, n, gate_irq[n][0]);
    260    }
    261    for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
    262        s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
    263    }
    264
    265    /* Cache controller */
    266    sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
    267
    268    /* External GIC */
    269    dev = qdev_new("exynos4210.gic");
    270    qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
    271    busdev = SYS_BUS_DEVICE(dev);
    272    sysbus_realize_and_unref(busdev, &error_fatal);
    273    /* Map CPU interface */
    274    sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
    275    /* Map Distributer interface */
    276    sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
    277    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
    278        sysbus_connect_irq(busdev, n, gate_irq[n][1]);
    279    }
    280    for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
    281        s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
    282    }
    283
    284    /* Internal Interrupt Combiner */
    285    dev = qdev_new("exynos4210.combiner");
    286    busdev = SYS_BUS_DEVICE(dev);
    287    sysbus_realize_and_unref(busdev, &error_fatal);
    288    for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
    289        sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
    290    }
    291    exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
    292    sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
    293
    294    /* External Interrupt Combiner */
    295    dev = qdev_new("exynos4210.combiner");
    296    qdev_prop_set_uint32(dev, "external", 1);
    297    busdev = SYS_BUS_DEVICE(dev);
    298    sysbus_realize_and_unref(busdev, &error_fatal);
    299    for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
    300        sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
    301    }
    302    exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
    303    sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
    304
    305    /* Initialize board IRQs. */
    306    exynos4210_init_board_irqs(&s->irqs);
    307
    308    /*** Memory ***/
    309
    310    /* Chip-ID and OMR */
    311    memory_region_init_io(&s->chipid_mem, OBJECT(socdev),
    312                          &exynos4210_chipid_and_omr_ops, NULL,
    313                          "exynos4210.chipid", sizeof(chipid_and_omr));
    314    memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR,
    315                                &s->chipid_mem);
    316
    317    /* Internal ROM */
    318    memory_region_init_rom(&s->irom_mem, OBJECT(socdev), "exynos4210.irom",
    319                           EXYNOS4210_IROM_SIZE, &error_fatal);
    320    memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR,
    321                                &s->irom_mem);
    322    /* mirror of iROM */
    323    memory_region_init_alias(&s->irom_alias_mem, OBJECT(socdev),
    324                             "exynos4210.irom_alias", &s->irom_mem, 0,
    325                             EXYNOS4210_IROM_SIZE);
    326    memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR,
    327                                &s->irom_alias_mem);
    328
    329    /* Internal RAM */
    330    memory_region_init_ram(&s->iram_mem, NULL, "exynos4210.iram",
    331                           EXYNOS4210_IRAM_SIZE, &error_fatal);
    332    memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR,
    333                                &s->iram_mem);
    334
    335   /* PMU.
    336    * The only reason of existence at the moment is that secondary CPU boot
    337    * loader uses PMU INFORM5 register as a holding pen.
    338    */
    339    sysbus_create_simple("exynos4210.pmu", EXYNOS4210_PMU_BASE_ADDR, NULL);
    340
    341    sysbus_create_simple("exynos4210.clk", EXYNOS4210_CLK_BASE_ADDR, NULL);
    342    sysbus_create_simple("exynos4210.rng", EXYNOS4210_RNG_BASE_ADDR, NULL);
    343
    344    /* PWM */
    345    sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR,
    346                          s->irq_table[exynos4210_get_irq(22, 0)],
    347                          s->irq_table[exynos4210_get_irq(22, 1)],
    348                          s->irq_table[exynos4210_get_irq(22, 2)],
    349                          s->irq_table[exynos4210_get_irq(22, 3)],
    350                          s->irq_table[exynos4210_get_irq(22, 4)],
    351                          NULL);
    352    /* RTC */
    353    sysbus_create_varargs("exynos4210.rtc", EXYNOS4210_RTC_BASE_ADDR,
    354                          s->irq_table[exynos4210_get_irq(23, 0)],
    355                          s->irq_table[exynos4210_get_irq(23, 1)],
    356                          NULL);
    357
    358    /* Multi Core Timer */
    359    dev = qdev_new("exynos4210.mct");
    360    busdev = SYS_BUS_DEVICE(dev);
    361    sysbus_realize_and_unref(busdev, &error_fatal);
    362    for (n = 0; n < 4; n++) {
    363        /* Connect global timer interrupts to Combiner gpio_in */
    364        sysbus_connect_irq(busdev, n,
    365                s->irq_table[exynos4210_get_irq(1, 4 + n)]);
    366    }
    367    /* Connect local timer interrupts to Combiner gpio_in */
    368    sysbus_connect_irq(busdev, 4,
    369            s->irq_table[exynos4210_get_irq(51, 0)]);
    370    sysbus_connect_irq(busdev, 5,
    371            s->irq_table[exynos4210_get_irq(35, 3)]);
    372    sysbus_mmio_map(busdev, 0, EXYNOS4210_MCT_BASE_ADDR);
    373
    374    /*** I2C ***/
    375    for (n = 0; n < EXYNOS4210_I2C_NUMBER; n++) {
    376        uint32_t addr = EXYNOS4210_I2C_BASE_ADDR + EXYNOS4210_I2C_SHIFT * n;
    377        qemu_irq i2c_irq;
    378
    379        if (n < 8) {
    380            i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_I2C_INTG, n)];
    381        } else {
    382            i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_HDMI_INTG, 1)];
    383        }
    384
    385        dev = qdev_new("exynos4210.i2c");
    386        busdev = SYS_BUS_DEVICE(dev);
    387        sysbus_realize_and_unref(busdev, &error_fatal);
    388        sysbus_connect_irq(busdev, 0, i2c_irq);
    389        sysbus_mmio_map(busdev, 0, addr);
    390        s->i2c_if[n] = (I2CBus *)qdev_get_child_bus(dev, "i2c");
    391    }
    392
    393
    394    /*** UARTs ***/
    395    uart[0] = exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
    396                           EXYNOS4210_UART0_FIFO_SIZE, 0, serial_hd(0),
    397                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]);
    398
    399    uart[1] = exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
    400                           EXYNOS4210_UART1_FIFO_SIZE, 1, serial_hd(1),
    401                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]);
    402
    403    uart[2] = exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
    404                           EXYNOS4210_UART2_FIFO_SIZE, 2, serial_hd(2),
    405                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]);
    406
    407    uart[3] = exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
    408                           EXYNOS4210_UART3_FIFO_SIZE, 3, serial_hd(3),
    409                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]);
    410
    411    /*** SD/MMC host controllers ***/
    412    for (n = 0; n < EXYNOS4210_SDHCI_NUMBER; n++) {
    413        DeviceState *carddev;
    414        BlockBackend *blk;
    415        DriveInfo *di;
    416
    417        /* Compatible with:
    418         * - SD Host Controller Specification Version 2.0
    419         * - SDIO Specification Version 2.0
    420         * - MMC Specification Version 4.3
    421         * - SDMA
    422         * - ADMA2
    423         *
    424         * As this part of the Exynos4210 is not publically available,
    425         * we used the "HS-MMC Controller S3C2416X RISC Microprocessor"
    426         * public datasheet which is very similar (implementing
    427         * MMC Specification Version 4.0 being the only difference noted)
    428         */
    429        dev = qdev_new(TYPE_S3C_SDHCI);
    430        qdev_prop_set_uint64(dev, "capareg", EXYNOS4210_SDHCI_CAPABILITIES);
    431
    432        busdev = SYS_BUS_DEVICE(dev);
    433        sysbus_realize_and_unref(busdev, &error_fatal);
    434        sysbus_mmio_map(busdev, 0, EXYNOS4210_SDHCI_ADDR(n));
    435        sysbus_connect_irq(busdev, 0, s->irq_table[exynos4210_get_irq(29, n)]);
    436
    437        di = drive_get(IF_SD, 0, n);
    438        blk = di ? blk_by_legacy_dinfo(di) : NULL;
    439        carddev = qdev_new(TYPE_SD_CARD);
    440        qdev_prop_set_drive(carddev, "drive", blk);
    441        qdev_realize_and_unref(carddev, qdev_get_child_bus(dev, "sd-bus"),
    442                               &error_fatal);
    443    }
    444
    445    /*** Display controller (FIMD) ***/
    446    sysbus_create_varargs("exynos4210.fimd", EXYNOS4210_FIMD0_BASE_ADDR,
    447            s->irq_table[exynos4210_get_irq(11, 0)],
    448            s->irq_table[exynos4210_get_irq(11, 1)],
    449            s->irq_table[exynos4210_get_irq(11, 2)],
    450            NULL);
    451
    452    sysbus_create_simple(TYPE_EXYNOS4210_EHCI, EXYNOS4210_EHCI_BASE_ADDR,
    453            s->irq_table[exynos4210_get_irq(28, 3)]);
    454
    455    /*** DMA controllers ***/
    456    pl330[0] = pl330_create(EXYNOS4210_PL330_BASE0_ADDR,
    457                            &s->pl330_irq_orgate[0],
    458                            s->irq_table[exynos4210_get_irq(21, 0)],
    459                            32, 32, 32);
    460    pl330[1] = pl330_create(EXYNOS4210_PL330_BASE1_ADDR,
    461                            &s->pl330_irq_orgate[1],
    462                            s->irq_table[exynos4210_get_irq(21, 1)],
    463                            32, 32, 32);
    464    pl330[2] = pl330_create(EXYNOS4210_PL330_BASE2_ADDR,
    465                            &s->pl330_irq_orgate[2],
    466                            s->irq_table[exynos4210_get_irq(20, 1)],
    467                            1, 31, 64);
    468
    469    sysbus_connect_irq(SYS_BUS_DEVICE(uart[0]), 1,
    470                       qdev_get_gpio_in(pl330[0], 15));
    471    sysbus_connect_irq(SYS_BUS_DEVICE(uart[1]), 1,
    472                       qdev_get_gpio_in(pl330[1], 15));
    473    sysbus_connect_irq(SYS_BUS_DEVICE(uart[2]), 1,
    474                       qdev_get_gpio_in(pl330[0], 17));
    475    sysbus_connect_irq(SYS_BUS_DEVICE(uart[3]), 1,
    476                       qdev_get_gpio_in(pl330[1], 17));
    477}
    478
    479static void exynos4210_init(Object *obj)
    480{
    481    Exynos4210State *s = EXYNOS4210_SOC(obj);
    482    int i;
    483
    484    for (i = 0; i < ARRAY_SIZE(s->pl330_irq_orgate); i++) {
    485        char *name = g_strdup_printf("pl330-irq-orgate%d", i);
    486        qemu_or_irq *orgate = &s->pl330_irq_orgate[i];
    487
    488        object_initialize_child(obj, name, orgate, TYPE_OR_IRQ);
    489        g_free(name);
    490    }
    491}
    492
    493static void exynos4210_class_init(ObjectClass *klass, void *data)
    494{
    495    DeviceClass *dc = DEVICE_CLASS(klass);
    496
    497    dc->realize = exynos4210_realize;
    498}
    499
    500static const TypeInfo exynos4210_info = {
    501    .name = TYPE_EXYNOS4210_SOC,
    502    .parent = TYPE_SYS_BUS_DEVICE,
    503    .instance_size = sizeof(Exynos4210State),
    504    .instance_init = exynos4210_init,
    505    .class_init = exynos4210_class_init,
    506};
    507
    508static void exynos4210_register_types(void)
    509{
    510    type_register_static(&exynos4210_info);
    511}
    512
    513type_init(exynos4210_register_types)