/*
 *  Samsung exynos4210 SoC emulation
 *
 *  Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
 *    Maksim Kozlov <m.kozlov@samsung.com>
 *    Evgeny Voevodin <e.voevodin@samsung.com>
 *    Igor Mitsyanko  <i.mitsyanko@samsung.com>
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the
 *  Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 *  for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "cpu.h"
#include "hw/cpu/a9mpcore.h"
#include "hw/irq.h"
#include "sysemu/blockdev.h"
#include "sysemu/sysemu.h"
#include "hw/sysbus.h"
#include "hw/arm/boot.h"
#include "hw/loader.h"
#include "hw/qdev-properties.h"
#include "hw/arm/exynos4210.h"
#include "hw/sd/sdhci.h"
#include "hw/usb/hcd-ehci.h"

#define EXYNOS4210_CHIPID_ADDR         0x10000000

/* PWM */
#define EXYNOS4210_PWM_BASE_ADDR       0x139D0000

/* RTC */
#define EXYNOS4210_RTC_BASE_ADDR       0x10070000

/* MCT */
#define EXYNOS4210_MCT_BASE_ADDR       0x10050000

/* I2C */
#define EXYNOS4210_I2C_SHIFT           0x00010000
#define EXYNOS4210_I2C_BASE_ADDR       0x13860000
/* Interrupt Group of External Interrupt Combiner for I2C */
#define EXYNOS4210_I2C_INTG            27
#define EXYNOS4210_HDMI_INTG           16

/* UART's definitions */
#define EXYNOS4210_UART0_BASE_ADDR     0x13800000
#define EXYNOS4210_UART1_BASE_ADDR     0x13810000
#define EXYNOS4210_UART2_BASE_ADDR     0x13820000
#define EXYNOS4210_UART3_BASE_ADDR     0x13830000
#define EXYNOS4210_UART0_FIFO_SIZE     256
#define EXYNOS4210_UART1_FIFO_SIZE     64
#define EXYNOS4210_UART2_FIFO_SIZE     16
#define EXYNOS4210_UART3_FIFO_SIZE     16
/* Interrupt Group of External Interrupt Combiner for UART */
#define EXYNOS4210_UART_INT_GRP        26

/* External GIC */
#define EXYNOS4210_EXT_GIC_CPU_BASE_ADDR    0x10480000
#define EXYNOS4210_EXT_GIC_DIST_BASE_ADDR   0x10490000

/* Combiner */
#define EXYNOS4210_EXT_COMBINER_BASE_ADDR   0x10440000
#define EXYNOS4210_INT_COMBINER_BASE_ADDR   0x10448000

/* SD/MMC host controllers */
#define EXYNOS4210_SDHCI_CAPABILITIES       0x05E80080
#define EXYNOS4210_SDHCI_BASE_ADDR          0x12510000
#define EXYNOS4210_SDHCI_ADDR(n)            (EXYNOS4210_SDHCI_BASE_ADDR + \
                                                0x00010000 * (n))
#define EXYNOS4210_SDHCI_NUMBER             4

/* PMU SFR base address */
#define EXYNOS4210_PMU_BASE_ADDR            0x10020000

/* Clock controller SFR base address */
#define EXYNOS4210_CLK_BASE_ADDR            0x10030000

/* PRNG/HASH SFR base address */
#define EXYNOS4210_RNG_BASE_ADDR            0x10830400

/* Display controllers (FIMD) */
#define EXYNOS4210_FIMD0_BASE_ADDR          0x11C00000

/* EHCI */
#define EXYNOS4210_EHCI_BASE_ADDR           0x12580000

/* DMA */
#define EXYNOS4210_PL330_BASE0_ADDR         0x12680000
#define EXYNOS4210_PL330_BASE1_ADDR         0x12690000
#define EXYNOS4210_PL330_BASE2_ADDR         0x12850000

enum ExtGicId {
    EXT_GIC_ID_MDMA_LCD0 = 66,
    EXT_GIC_ID_PDMA0,
    EXT_GIC_ID_PDMA1,
    EXT_GIC_ID_TIMER0,
    EXT_GIC_ID_TIMER1,
    EXT_GIC_ID_TIMER2,
    EXT_GIC_ID_TIMER3,
    EXT_GIC_ID_TIMER4,
    EXT_GIC_ID_MCT_L0,
    EXT_GIC_ID_WDT,
    EXT_GIC_ID_RTC_ALARM,
    EXT_GIC_ID_RTC_TIC,
    EXT_GIC_ID_GPIO_XB,
    EXT_GIC_ID_GPIO_XA,
    EXT_GIC_ID_MCT_L1,
    EXT_GIC_ID_IEM_APC,
    EXT_GIC_ID_IEM_IEC,
    EXT_GIC_ID_NFC,
    EXT_GIC_ID_UART0,
    EXT_GIC_ID_UART1,
    EXT_GIC_ID_UART2,
    EXT_GIC_ID_UART3,
    EXT_GIC_ID_UART4,
    EXT_GIC_ID_MCT_G0,
    EXT_GIC_ID_I2C0,
    EXT_GIC_ID_I2C1,
    EXT_GIC_ID_I2C2,
    EXT_GIC_ID_I2C3,
    EXT_GIC_ID_I2C4,
    EXT_GIC_ID_I2C5,
    EXT_GIC_ID_I2C6,
    EXT_GIC_ID_I2C7,
    EXT_GIC_ID_SPI0,
    EXT_GIC_ID_SPI1,
    EXT_GIC_ID_SPI2,
    EXT_GIC_ID_MCT_G1,
    EXT_GIC_ID_USB_HOST,
    EXT_GIC_ID_USB_DEVICE,
    EXT_GIC_ID_MODEMIF,
    EXT_GIC_ID_HSMMC0,
    EXT_GIC_ID_HSMMC1,
    EXT_GIC_ID_HSMMC2,
    EXT_GIC_ID_HSMMC3,
    EXT_GIC_ID_SDMMC,
    EXT_GIC_ID_MIPI_CSI_4LANE,
    EXT_GIC_ID_MIPI_DSI_4LANE,
    EXT_GIC_ID_MIPI_CSI_2LANE,
    EXT_GIC_ID_MIPI_DSI_2LANE,
    EXT_GIC_ID_ONENAND_AUDI,
    EXT_GIC_ID_ROTATOR,
    EXT_GIC_ID_FIMC0,
    EXT_GIC_ID_FIMC1,
    EXT_GIC_ID_FIMC2,
    EXT_GIC_ID_FIMC3,
    EXT_GIC_ID_JPEG,
    EXT_GIC_ID_2D,
    EXT_GIC_ID_PCIe,
    EXT_GIC_ID_MIXER,
    EXT_GIC_ID_HDMI,
    EXT_GIC_ID_HDMI_I2C,
    EXT_GIC_ID_MFC,
    EXT_GIC_ID_TVENC,
};

enum ExtInt {
    EXT_GIC_ID_EXTINT0 = 48,
    EXT_GIC_ID_EXTINT1,
    EXT_GIC_ID_EXTINT2,
    EXT_GIC_ID_EXTINT3,
    EXT_GIC_ID_EXTINT4,
    EXT_GIC_ID_EXTINT5,
    EXT_GIC_ID_EXTINT6,
    EXT_GIC_ID_EXTINT7,
    EXT_GIC_ID_EXTINT8,
    EXT_GIC_ID_EXTINT9,
    EXT_GIC_ID_EXTINT10,
    EXT_GIC_ID_EXTINT11,
    EXT_GIC_ID_EXTINT12,
    EXT_GIC_ID_EXTINT13,
    EXT_GIC_ID_EXTINT14,
    EXT_GIC_ID_EXTINT15
};

/*
 * External GIC sources which are not from External Interrupt Combiner or
 * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
 * which is INTG16 in Internal Interrupt Combiner.
 */

static const uint32_t
combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
    /* int combiner groups 16-19 */
    { }, { }, { }, { },
    /* int combiner group 20 */
    { 0, EXT_GIC_ID_MDMA_LCD0 },
    /* int combiner group 21 */
    { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
    /* int combiner group 22 */
    { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
            EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
    /* int combiner group 23 */
    { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
    /* int combiner group 24 */
    { EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
    /* int combiner group 25 */
    { EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
    /* int combiner group 26 */
    { EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
            EXT_GIC_ID_UART4 },
    /* int combiner group 27 */
    { EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
            EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
            EXT_GIC_ID_I2C7 },
    /* int combiner group 28 */
    { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
    /* int combiner group 29 */
    { EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
     EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
    /* int combiner group 30 */
    { EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
    /* int combiner group 31 */
    { EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
    /* int combiner group 32 */
    { EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
    /* int combiner group 33 */
    { EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
    /* int combiner group 34 */
    { EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
    /* int combiner group 35 */
    { 0, 0, 0, EXT_GIC_ID_MCT_L1 },
    /* int combiner group 36 */
    { EXT_GIC_ID_MIXER },
    /* int combiner group 37 */
    { EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
     EXT_GIC_ID_EXTINT7 },
    /* groups 38-50 */
    { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
    /* int combiner group 51 */
    { EXT_GIC_ID_MCT_L0 },
    /* group 52 */
    { },
    /* int combiner group 53 */
    { EXT_GIC_ID_WDT },
    /* groups 54-63 */
    { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
};

#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit)  ((grp) * 8 + (bit))
#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq)       ((irq) / 8)
#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
    ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))

/*
 * Some interrupt lines go to multiple combiner inputs.
 * This data structure defines those: each array element is
 * a list of combiner inputs which are connected together;
 * the one with the smallest interrupt ID value must be first.
 * As with combiner_grp_to_gic_id[], we rely on (0, 0) not being
 * wired to anything so we can use 0 as a terminator.
 */
#define IRQNO(G, B) EXYNOS4210_COMBINER_GET_IRQ_NUM(G, B)
#define IRQNONE 0

#define COMBINERMAP_SIZE 16

static const int combinermap[COMBINERMAP_SIZE][6] = {
    /* MDNIE_LCD1 */
    { IRQNO(0, 4), IRQNO(1, 0), IRQNONE },
    { IRQNO(0, 5), IRQNO(1, 1), IRQNONE },
    { IRQNO(0, 6), IRQNO(1, 2), IRQNONE },
    { IRQNO(0, 7), IRQNO(1, 3), IRQNONE },
    /* TMU */
    { IRQNO(2, 4), IRQNO(3, 4), IRQNONE },
    { IRQNO(2, 5), IRQNO(3, 5), IRQNONE },
    { IRQNO(2, 6), IRQNO(3, 6), IRQNONE },
    { IRQNO(2, 7), IRQNO(3, 7), IRQNONE },
    /* LCD1 */
    { IRQNO(11, 4), IRQNO(12, 0), IRQNONE },
    { IRQNO(11, 5), IRQNO(12, 1), IRQNONE },
    { IRQNO(11, 6), IRQNO(12, 2), IRQNONE },
    { IRQNO(11, 7), IRQNO(12, 3), IRQNONE },
    /* Multi-core timer */
    { IRQNO(1, 4), IRQNO(12, 4), IRQNO(35, 4), IRQNO(51, 4), IRQNO(53, 4), IRQNONE },
    { IRQNO(1, 5), IRQNO(12, 5), IRQNO(35, 5), IRQNO(51, 5), IRQNO(53, 5), IRQNONE },
    { IRQNO(1, 6), IRQNO(12, 6), IRQNO(35, 6), IRQNO(51, 6), IRQNO(53, 6), IRQNONE },
    { IRQNO(1, 7), IRQNO(12, 7), IRQNO(35, 7), IRQNO(51, 7), IRQNO(53, 7), IRQNONE },
};

#undef IRQNO

static const int *combinermap_entry(int irq)
{
    /*
     * If the interrupt number passed in is the first entry in some
     * line of the combinermap, return a pointer to that line;
     * otherwise return NULL.
     */
    int i;
    for (i = 0; i < COMBINERMAP_SIZE; i++) {
        if (combinermap[i][0] == irq) {
            return combinermap[i];
        }
    }
    return NULL;
}

static int mapline_size(const int *mapline)
{
    /* Return number of entries in this mapline in total */
    int i = 0;

    if (!mapline) {
        /* Not in the map? IRQ goes to exactly one combiner input */
        return 1;
    }
    while (*mapline != IRQNONE) {
        mapline++;
        i++;
    }
    return i;
}

/*
 * Initialize board IRQs.
 * These IRQs contain split Int/External Combiner and External Gic IRQs.
 */
static void exynos4210_init_board_irqs(Exynos4210State *s)
{
    uint32_t grp, bit, irq_id, n;
    DeviceState *extgicdev = DEVICE(&s->ext_gic);
    DeviceState *intcdev = DEVICE(&s->int_combiner);
    DeviceState *extcdev = DEVICE(&s->ext_combiner);
    int splitcount = 0;
    DeviceState *splitter;
    const int *mapline;
    int numlines, splitin, in;

    for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
        irq_id = 0;
        if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4)) {
            /* MCT_G0 is passed to External GIC */
            irq_id = EXT_GIC_ID_MCT_G0;
        }
        if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5)) {
            /* MCT_G1 is passed to External and GIC */
            irq_id = EXT_GIC_ID_MCT_G1;
        }

        if (s->irq_table[n]) {
            /*
             * This must be some non-first entry in a combinermap line,
             * and we've already filled it in.
             */
            continue;
        }
        mapline = combinermap_entry(n);
        /*
         * We need to connect the IRQ to multiple inputs on both combiners
         * and possibly also to the external GIC.
         */
        numlines = 2 * mapline_size(mapline);
        if (irq_id) {
            numlines++;
        }
        assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
        splitter = DEVICE(&s->splitter[splitcount]);
        qdev_prop_set_uint16(splitter, "num-lines", numlines);
        qdev_realize(splitter, NULL, &error_abort);
        splitcount++;

        in = n;
        splitin = 0;
        for (;;) {
            s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
            qdev_connect_gpio_out(splitter, splitin,
                                  qdev_get_gpio_in(intcdev, in));
            qdev_connect_gpio_out(splitter, splitin + 1,
                                  qdev_get_gpio_in(extcdev, in));
            splitin += 2;
            if (!mapline) {
                break;
            }
            mapline++;
            in = *mapline;
            if (in == IRQNONE) {
                break;
            }
        }
        if (irq_id) {
            qdev_connect_gpio_out(splitter, splitin,
                                  qdev_get_gpio_in(extgicdev, irq_id - 32));
        }
    }
    for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
        /* these IDs are passed to Internal Combiner and External GIC */
        grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
        bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
        irq_id = combiner_grp_to_gic_id[grp -
                     EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];

        if (s->irq_table[n]) {
            /*
             * This must be some non-first entry in a combinermap line,
             * and we've already filled it in.
             */
            continue;
        }

        if (irq_id) {
            assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
            splitter = DEVICE(&s->splitter[splitcount]);
            qdev_prop_set_uint16(splitter, "num-lines", 2);
            qdev_realize(splitter, NULL, &error_abort);
            splitcount++;
            s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
            qdev_connect_gpio_out(splitter, 0, qdev_get_gpio_in(intcdev, n));
            qdev_connect_gpio_out(splitter, 1,
                                  qdev_get_gpio_in(extgicdev, irq_id - 32));
        } else {
            s->irq_table[n] = qdev_get_gpio_in(intcdev, n);
        }
    }
    /*
     * We check this here to avoid a more obscure assert later when
     * qdev_assert_realized_properly() checks that we realized every
     * child object we initialized.
     */
    assert(splitcount == EXYNOS4210_NUM_SPLITTERS);
}

/*
 * Get IRQ number from exynos4210 IRQ subsystem stub.
 * To identify IRQ source use internal combiner group and bit number
 *  grp - group number
 *  bit - bit number inside group
 */
uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
{
    return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
}

static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
                                    0x09, 0x00, 0x00, 0x00 };

static uint64_t exynos4210_chipid_and_omr_read(void *opaque, hwaddr offset,
                                               unsigned size)
{
    assert(offset < sizeof(chipid_and_omr));
    return chipid_and_omr[offset];
}

static void exynos4210_chipid_and_omr_write(void *opaque, hwaddr offset,
                                            uint64_t value, unsigned size)
{
    return;
}

static const MemoryRegionOps exynos4210_chipid_and_omr_ops = {
    .read = exynos4210_chipid_and_omr_read,
    .write = exynos4210_chipid_and_omr_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .impl = {
        .max_access_size = 1,
    }
};

void exynos4210_write_secondary(ARMCPU *cpu,
        const struct arm_boot_info *info)
{
    int n;
    uint32_t smpboot[] = {
        0xe59f3034, /* ldr r3, External gic_cpu_if */
        0xe59f2034, /* ldr r2, Internal gic_cpu_if */
        0xe59f0034, /* ldr r0, startaddr */
        0xe3a01001, /* mov r1, #1 */
        0xe5821000, /* str r1, [r2] */
        0xe5831000, /* str r1, [r3] */
        0xe3a010ff, /* mov r1, #0xff */
        0xe5821004, /* str r1, [r2, #4] */
        0xe5831004, /* str r1, [r3, #4] */
        0xf57ff04f, /* dsb */
        0xe320f003, /* wfi */
        0xe5901000, /* ldr     r1, [r0] */
        0xe1110001, /* tst     r1, r1 */
        0x0afffffb, /* beq     <wfi> */
        0xe12fff11, /* bx      r1 */
        EXYNOS4210_EXT_GIC_CPU_BASE_ADDR,
        0,          /* gic_cpu_if: base address of Internal GIC CPU interface */
        0           /* bootreg: Boot register address is held here */
    };
    smpboot[ARRAY_SIZE(smpboot) - 1] = info->smp_bootreg_addr;
    smpboot[ARRAY_SIZE(smpboot) - 2] = info->gic_cpu_if_addr;
    for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
        smpboot[n] = tswap32(smpboot[n]);
    }
    rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot),
                       info->smp_loader_start);
}

static uint64_t exynos4210_calc_affinity(int cpu)
{
    /* Exynos4210 has 0x9 as cluster ID */
    return (0x9 << ARM_AFF1_SHIFT) | cpu;
}

static DeviceState *pl330_create(uint32_t base, OrIRQState *orgate,
                                 qemu_irq irq, int nreq, int nevents, int width)
{
    SysBusDevice *busdev;
    DeviceState *dev;
    int i;

    dev = qdev_new("pl330");
    object_property_set_link(OBJECT(dev), "memory",
                             OBJECT(get_system_memory()),
                             &error_fatal);
    qdev_prop_set_uint8(dev, "num_events", nevents);
    qdev_prop_set_uint8(dev, "num_chnls",  8);
    qdev_prop_set_uint8(dev, "num_periph_req",  nreq);

    qdev_prop_set_uint8(dev, "wr_cap", 4);
    qdev_prop_set_uint8(dev, "wr_q_dep", 8);
    qdev_prop_set_uint8(dev, "rd_cap", 4);
    qdev_prop_set_uint8(dev, "rd_q_dep", 8);
    qdev_prop_set_uint8(dev, "data_width", width);
    qdev_prop_set_uint16(dev, "data_buffer_dep", width);
    busdev = SYS_BUS_DEVICE(dev);
    sysbus_realize_and_unref(busdev, &error_fatal);
    sysbus_mmio_map(busdev, 0, base);

    object_property_set_int(OBJECT(orgate), "num-lines", nevents + 1,
                            &error_abort);
    qdev_realize(DEVICE(orgate), NULL, &error_abort);

    for (i = 0; i < nevents + 1; i++) {
        sysbus_connect_irq(busdev, i, qdev_get_gpio_in(DEVICE(orgate), i));
    }
    qdev_connect_gpio_out(DEVICE(orgate), 0, irq);
    return dev;
}

static void exynos4210_realize(DeviceState *socdev, Error **errp)
{
    Exynos4210State *s = EXYNOS4210_SOC(socdev);
    MemoryRegion *system_mem = get_system_memory();
    SysBusDevice *busdev;
    DeviceState *dev, *uart[4], *pl330[3];
    int i, n;

    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
        Object *cpuobj = object_new(ARM_CPU_TYPE_NAME("cortex-a9"));

        /* By default A9 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")) {
            object_property_set_bool(cpuobj, "has_el3", false, &error_fatal);
        }

        s->cpu[n] = ARM_CPU(cpuobj);
        object_property_set_int(cpuobj, "mp-affinity",
                                exynos4210_calc_affinity(n), &error_abort);
        object_property_set_int(cpuobj, "reset-cbar",
                                EXYNOS4210_SMP_PRIVATE_BASE_ADDR,
                                &error_abort);
        qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
    }

    /* IRQ Gate */
    for (i = 0; i < EXYNOS4210_NCPUS; i++) {
        DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
        object_property_set_int(OBJECT(orgate), "num-lines",
                                EXYNOS4210_IRQ_GATE_NINPUTS,
                                &error_abort);
        qdev_realize(orgate, NULL, &error_abort);
        qdev_connect_gpio_out(orgate, 0,
                              qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
    }

    /* Private memory region and Internal GIC */
    qdev_prop_set_uint32(DEVICE(&s->a9mpcore), "num-cpu", EXYNOS4210_NCPUS);
    busdev = SYS_BUS_DEVICE(&s->a9mpcore);
    sysbus_realize(busdev, &error_fatal);
    sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
        sysbus_connect_irq(busdev, n,
                           qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
    }

    /* Cache controller */
    sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);

    /* External GIC */
    qdev_prop_set_uint32(DEVICE(&s->ext_gic), "num-cpu", EXYNOS4210_NCPUS);
    busdev = SYS_BUS_DEVICE(&s->ext_gic);
    sysbus_realize(busdev, &error_fatal);
    /* Map CPU interface */
    sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
    /* Map Distributer interface */
    sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
        sysbus_connect_irq(busdev, n,
                           qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
    }

    /* Internal Interrupt Combiner */
    busdev = SYS_BUS_DEVICE(&s->int_combiner);
    sysbus_realize(busdev, &error_fatal);
    for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
        sysbus_connect_irq(busdev, n,
                           qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
    }
    sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);

    /* External Interrupt Combiner */
    qdev_prop_set_uint32(DEVICE(&s->ext_combiner), "external", 1);
    busdev = SYS_BUS_DEVICE(&s->ext_combiner);
    sysbus_realize(busdev, &error_fatal);
    for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
        sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
    }
    sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);

    /* Initialize board IRQs. */
    exynos4210_init_board_irqs(s);

    /*** Memory ***/

    /* Chip-ID and OMR */
    memory_region_init_io(&s->chipid_mem, OBJECT(socdev),
                          &exynos4210_chipid_and_omr_ops, NULL,
                          "exynos4210.chipid", sizeof(chipid_and_omr));
    memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR,
                                &s->chipid_mem);

    /* Internal ROM */
    memory_region_init_rom(&s->irom_mem, OBJECT(socdev), "exynos4210.irom",
                           EXYNOS4210_IROM_SIZE, &error_fatal);
    memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR,
                                &s->irom_mem);
    /* mirror of iROM */
    memory_region_init_alias(&s->irom_alias_mem, OBJECT(socdev),
                             "exynos4210.irom_alias", &s->irom_mem, 0,
                             EXYNOS4210_IROM_SIZE);
    memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR,
                                &s->irom_alias_mem);

    /* Internal RAM */
    memory_region_init_ram(&s->iram_mem, NULL, "exynos4210.iram",
                           EXYNOS4210_IRAM_SIZE, &error_fatal);
    memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR,
                                &s->iram_mem);

   /* PMU.
    * The only reason of existence at the moment is that secondary CPU boot
    * loader uses PMU INFORM5 register as a holding pen.
    */
    sysbus_create_simple("exynos4210.pmu", EXYNOS4210_PMU_BASE_ADDR, NULL);

    sysbus_create_simple("exynos4210.clk", EXYNOS4210_CLK_BASE_ADDR, NULL);
    sysbus_create_simple("exynos4210.rng", EXYNOS4210_RNG_BASE_ADDR, NULL);

    /* PWM */
    sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR,
                          s->irq_table[exynos4210_get_irq(22, 0)],
                          s->irq_table[exynos4210_get_irq(22, 1)],
                          s->irq_table[exynos4210_get_irq(22, 2)],
                          s->irq_table[exynos4210_get_irq(22, 3)],
                          s->irq_table[exynos4210_get_irq(22, 4)],
                          NULL);
    /* RTC */
    sysbus_create_varargs("exynos4210.rtc", EXYNOS4210_RTC_BASE_ADDR,
                          s->irq_table[exynos4210_get_irq(23, 0)],
                          s->irq_table[exynos4210_get_irq(23, 1)],
                          NULL);

    /* Multi Core Timer */
    dev = qdev_new("exynos4210.mct");
    busdev = SYS_BUS_DEVICE(dev);
    sysbus_realize_and_unref(busdev, &error_fatal);
    for (n = 0; n < 4; n++) {
        /* Connect global timer interrupts to Combiner gpio_in */
        sysbus_connect_irq(busdev, n,
                s->irq_table[exynos4210_get_irq(1, 4 + n)]);
    }
    /* Connect local timer interrupts to Combiner gpio_in */
    sysbus_connect_irq(busdev, 4,
            s->irq_table[exynos4210_get_irq(51, 0)]);
    sysbus_connect_irq(busdev, 5,
            s->irq_table[exynos4210_get_irq(35, 3)]);
    sysbus_mmio_map(busdev, 0, EXYNOS4210_MCT_BASE_ADDR);

    /*** I2C ***/
    for (n = 0; n < EXYNOS4210_I2C_NUMBER; n++) {
        uint32_t addr = EXYNOS4210_I2C_BASE_ADDR + EXYNOS4210_I2C_SHIFT * n;
        qemu_irq i2c_irq;

        if (n < 8) {
            i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_I2C_INTG, n)];
        } else {
            i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_HDMI_INTG, 1)];
        }

        dev = qdev_new("exynos4210.i2c");
        busdev = SYS_BUS_DEVICE(dev);
        sysbus_realize_and_unref(busdev, &error_fatal);
        sysbus_connect_irq(busdev, 0, i2c_irq);
        sysbus_mmio_map(busdev, 0, addr);
        s->i2c_if[n] = (I2CBus *)qdev_get_child_bus(dev, "i2c");
    }


    /*** UARTs ***/
    uart[0] = exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
                           EXYNOS4210_UART0_FIFO_SIZE, 0, serial_hd(0),
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]);

    uart[1] = exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
                           EXYNOS4210_UART1_FIFO_SIZE, 1, serial_hd(1),
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]);

    uart[2] = exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
                           EXYNOS4210_UART2_FIFO_SIZE, 2, serial_hd(2),
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]);

    uart[3] = exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
                           EXYNOS4210_UART3_FIFO_SIZE, 3, serial_hd(3),
                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]);

    /*** SD/MMC host controllers ***/
    for (n = 0; n < EXYNOS4210_SDHCI_NUMBER; n++) {
        DeviceState *carddev;
        BlockBackend *blk;
        DriveInfo *di;

        /* Compatible with:
         * - SD Host Controller Specification Version 2.0
         * - SDIO Specification Version 2.0
         * - MMC Specification Version 4.3
         * - SDMA
         * - ADMA2
         *
         * As this part of the Exynos4210 is not publicly available,
         * we used the "HS-MMC Controller S3C2416X RISC Microprocessor"
         * public datasheet which is very similar (implementing
         * MMC Specification Version 4.0 being the only difference noted)
         */
        dev = qdev_new(TYPE_S3C_SDHCI);
        qdev_prop_set_uint64(dev, "capareg", EXYNOS4210_SDHCI_CAPABILITIES);

        busdev = SYS_BUS_DEVICE(dev);
        sysbus_realize_and_unref(busdev, &error_fatal);
        sysbus_mmio_map(busdev, 0, EXYNOS4210_SDHCI_ADDR(n));
        sysbus_connect_irq(busdev, 0, s->irq_table[exynos4210_get_irq(29, n)]);

        di = drive_get(IF_SD, 0, n);
        blk = di ? blk_by_legacy_dinfo(di) : NULL;
        carddev = qdev_new(TYPE_SD_CARD);
        qdev_prop_set_drive(carddev, "drive", blk);
        qdev_realize_and_unref(carddev, qdev_get_child_bus(dev, "sd-bus"),
                               &error_fatal);
    }

    /*** Display controller (FIMD) ***/
    sysbus_create_varargs("exynos4210.fimd", EXYNOS4210_FIMD0_BASE_ADDR,
            s->irq_table[exynos4210_get_irq(11, 0)],
            s->irq_table[exynos4210_get_irq(11, 1)],
            s->irq_table[exynos4210_get_irq(11, 2)],
            NULL);

    sysbus_create_simple(TYPE_EXYNOS4210_EHCI, EXYNOS4210_EHCI_BASE_ADDR,
            s->irq_table[exynos4210_get_irq(28, 3)]);

    /*** DMA controllers ***/
    pl330[0] = pl330_create(EXYNOS4210_PL330_BASE0_ADDR,
                            &s->pl330_irq_orgate[0],
                            s->irq_table[exynos4210_get_irq(21, 0)],
                            32, 32, 32);
    pl330[1] = pl330_create(EXYNOS4210_PL330_BASE1_ADDR,
                            &s->pl330_irq_orgate[1],
                            s->irq_table[exynos4210_get_irq(21, 1)],
                            32, 32, 32);
    pl330[2] = pl330_create(EXYNOS4210_PL330_BASE2_ADDR,
                            &s->pl330_irq_orgate[2],
                            s->irq_table[exynos4210_get_irq(20, 1)],
                            1, 31, 64);

    sysbus_connect_irq(SYS_BUS_DEVICE(uart[0]), 1,
                       qdev_get_gpio_in(pl330[0], 15));
    sysbus_connect_irq(SYS_BUS_DEVICE(uart[1]), 1,
                       qdev_get_gpio_in(pl330[1], 15));
    sysbus_connect_irq(SYS_BUS_DEVICE(uart[2]), 1,
                       qdev_get_gpio_in(pl330[0], 17));
    sysbus_connect_irq(SYS_BUS_DEVICE(uart[3]), 1,
                       qdev_get_gpio_in(pl330[1], 17));
}

static void exynos4210_init(Object *obj)
{
    Exynos4210State *s = EXYNOS4210_SOC(obj);
    int i;

    for (i = 0; i < ARRAY_SIZE(s->pl330_irq_orgate); i++) {
        char *name = g_strdup_printf("pl330-irq-orgate%d", i);
        OrIRQState *orgate = &s->pl330_irq_orgate[i];

        object_initialize_child(obj, name, orgate, TYPE_OR_IRQ);
        g_free(name);
    }

    for (i = 0; i < ARRAY_SIZE(s->cpu_irq_orgate); i++) {
        g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
        object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
    }

    for (i = 0; i < ARRAY_SIZE(s->splitter); i++) {
        g_autofree char *name = g_strdup_printf("irq-splitter%d", i);
        object_initialize_child(obj, name, &s->splitter[i], TYPE_SPLIT_IRQ);
    }

    object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
    object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
    object_initialize_child(obj, "int-combiner", &s->int_combiner,
                            TYPE_EXYNOS4210_COMBINER);
    object_initialize_child(obj, "ext-combiner", &s->ext_combiner,
                            TYPE_EXYNOS4210_COMBINER);
}

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

    dc->realize = exynos4210_realize;
}

static const TypeInfo exynos4210_info = {
    .name = TYPE_EXYNOS4210_SOC,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(Exynos4210State),
    .instance_init = exynos4210_init,
    .class_init = exynos4210_class_init,
};

static void exynos4210_register_types(void)
{
    type_register_static(&exynos4210_info);
}

type_init(exynos4210_register_types)
