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

fsl-imx25.c (12646B)


      1/*
      2 * Copyright (c) 2013 Jean-Christophe Dubois <jcd@tribudubois.net>
      3 *
      4 * i.MX25 SOC emulation.
      5 *
      6 * Based on hw/arm/xlnx-zynqmp.c
      7 *
      8 * Copyright (C) 2015 Xilinx Inc
      9 * Written by Peter Crosthwaite <peter.crosthwaite@xilinx.com>
     10 *
     11 *  This program is free software; you can redistribute it and/or modify it
     12 *  under the terms of the GNU General Public License as published by the
     13 *  Free Software Foundation; either version 2 of the License, or
     14 *  (at your option) any later version.
     15 *
     16 *  This program is distributed in the hope that it will be useful, but WITHOUT
     17 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     18 *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
     19 *  for more details.
     20 *
     21 *  You should have received a copy of the GNU General Public License along
     22 *  with this program; if not, see <http://www.gnu.org/licenses/>.
     23 */
     24
     25#include "qemu/osdep.h"
     26#include "qapi/error.h"
     27#include "hw/arm/fsl-imx25.h"
     28#include "sysemu/sysemu.h"
     29#include "hw/qdev-properties.h"
     30#include "chardev/char.h"
     31
     32#define IMX25_ESDHC_CAPABILITIES     0x07e20000
     33
     34static void fsl_imx25_init(Object *obj)
     35{
     36    FslIMX25State *s = FSL_IMX25(obj);
     37    int i;
     38
     39    object_initialize_child(obj, "cpu", &s->cpu, ARM_CPU_TYPE_NAME("arm926"));
     40
     41    object_initialize_child(obj, "avic", &s->avic, TYPE_IMX_AVIC);
     42
     43    object_initialize_child(obj, "ccm", &s->ccm, TYPE_IMX25_CCM);
     44
     45    for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
     46        object_initialize_child(obj, "uart[*]", &s->uart[i], TYPE_IMX_SERIAL);
     47    }
     48
     49    for (i = 0; i < FSL_IMX25_NUM_GPTS; i++) {
     50        object_initialize_child(obj, "gpt[*]", &s->gpt[i], TYPE_IMX25_GPT);
     51    }
     52
     53    for (i = 0; i < FSL_IMX25_NUM_EPITS; i++) {
     54        object_initialize_child(obj, "epit[*]", &s->epit[i], TYPE_IMX_EPIT);
     55    }
     56
     57    object_initialize_child(obj, "fec", &s->fec, TYPE_IMX_FEC);
     58
     59    object_initialize_child(obj, "rngc", &s->rngc, TYPE_IMX_RNGC);
     60
     61    for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
     62        object_initialize_child(obj, "i2c[*]", &s->i2c[i], TYPE_IMX_I2C);
     63    }
     64
     65    for (i = 0; i < FSL_IMX25_NUM_GPIOS; i++) {
     66        object_initialize_child(obj, "gpio[*]", &s->gpio[i], TYPE_IMX_GPIO);
     67    }
     68
     69    for (i = 0; i < FSL_IMX25_NUM_ESDHCS; i++) {
     70        object_initialize_child(obj, "sdhc[*]", &s->esdhc[i], TYPE_IMX_USDHC);
     71    }
     72
     73    for (i = 0; i < FSL_IMX25_NUM_USBS; i++) {
     74        object_initialize_child(obj, "usb[*]", &s->usb[i], TYPE_CHIPIDEA);
     75    }
     76
     77    object_initialize_child(obj, "wdt", &s->wdt, TYPE_IMX2_WDT);
     78}
     79
     80static void fsl_imx25_realize(DeviceState *dev, Error **errp)
     81{
     82    FslIMX25State *s = FSL_IMX25(dev);
     83    uint8_t i;
     84    Error *err = NULL;
     85
     86    if (!qdev_realize(DEVICE(&s->cpu), NULL, errp)) {
     87        return;
     88    }
     89
     90    if (!sysbus_realize(SYS_BUS_DEVICE(&s->avic), errp)) {
     91        return;
     92    }
     93    sysbus_mmio_map(SYS_BUS_DEVICE(&s->avic), 0, FSL_IMX25_AVIC_ADDR);
     94    sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 0,
     95                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
     96    sysbus_connect_irq(SYS_BUS_DEVICE(&s->avic), 1,
     97                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
     98
     99    if (!sysbus_realize(SYS_BUS_DEVICE(&s->ccm), errp)) {
    100        return;
    101    }
    102    sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX25_CCM_ADDR);
    103
    104    /* Initialize all UARTs */
    105    for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
    106        static const struct {
    107            hwaddr addr;
    108            unsigned int irq;
    109        } serial_table[FSL_IMX25_NUM_UARTS] = {
    110            { FSL_IMX25_UART1_ADDR, FSL_IMX25_UART1_IRQ },
    111            { FSL_IMX25_UART2_ADDR, FSL_IMX25_UART2_IRQ },
    112            { FSL_IMX25_UART3_ADDR, FSL_IMX25_UART3_IRQ },
    113            { FSL_IMX25_UART4_ADDR, FSL_IMX25_UART4_IRQ },
    114            { FSL_IMX25_UART5_ADDR, FSL_IMX25_UART5_IRQ }
    115        };
    116
    117        qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hd(i));
    118
    119        if (!sysbus_realize(SYS_BUS_DEVICE(&s->uart[i]), errp)) {
    120            return;
    121        }
    122        sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr);
    123        sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
    124                           qdev_get_gpio_in(DEVICE(&s->avic),
    125                                            serial_table[i].irq));
    126    }
    127
    128    /* Initialize all GPT timers */
    129    for (i = 0; i < FSL_IMX25_NUM_GPTS; i++) {
    130        static const struct {
    131            hwaddr addr;
    132            unsigned int irq;
    133        } gpt_table[FSL_IMX25_NUM_GPTS] = {
    134            { FSL_IMX25_GPT1_ADDR, FSL_IMX25_GPT1_IRQ },
    135            { FSL_IMX25_GPT2_ADDR, FSL_IMX25_GPT2_IRQ },
    136            { FSL_IMX25_GPT3_ADDR, FSL_IMX25_GPT3_IRQ },
    137            { FSL_IMX25_GPT4_ADDR, FSL_IMX25_GPT4_IRQ }
    138        };
    139
    140        s->gpt[i].ccm = IMX_CCM(&s->ccm);
    141
    142        if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpt[i]), errp)) {
    143            return;
    144        }
    145        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, gpt_table[i].addr);
    146        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
    147                           qdev_get_gpio_in(DEVICE(&s->avic),
    148                                            gpt_table[i].irq));
    149    }
    150
    151    /* Initialize all EPIT timers */
    152    for (i = 0; i < FSL_IMX25_NUM_EPITS; i++) {
    153        static const struct {
    154            hwaddr addr;
    155            unsigned int irq;
    156        } epit_table[FSL_IMX25_NUM_EPITS] = {
    157            { FSL_IMX25_EPIT1_ADDR, FSL_IMX25_EPIT1_IRQ },
    158            { FSL_IMX25_EPIT2_ADDR, FSL_IMX25_EPIT2_IRQ }
    159        };
    160
    161        s->epit[i].ccm = IMX_CCM(&s->ccm);
    162
    163        if (!sysbus_realize(SYS_BUS_DEVICE(&s->epit[i]), errp)) {
    164            return;
    165        }
    166        sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0, epit_table[i].addr);
    167        sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
    168                           qdev_get_gpio_in(DEVICE(&s->avic),
    169                                            epit_table[i].irq));
    170    }
    171
    172    object_property_set_uint(OBJECT(&s->fec), "phy-num", s->phy_num, &err);
    173    qdev_set_nic_properties(DEVICE(&s->fec), &nd_table[0]);
    174
    175    if (!sysbus_realize(SYS_BUS_DEVICE(&s->fec), errp)) {
    176        return;
    177    }
    178    sysbus_mmio_map(SYS_BUS_DEVICE(&s->fec), 0, FSL_IMX25_FEC_ADDR);
    179    sysbus_connect_irq(SYS_BUS_DEVICE(&s->fec), 0,
    180                       qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX25_FEC_IRQ));
    181
    182    if (!sysbus_realize(SYS_BUS_DEVICE(&s->rngc), errp)) {
    183        return;
    184    }
    185    sysbus_mmio_map(SYS_BUS_DEVICE(&s->rngc), 0, FSL_IMX25_RNGC_ADDR);
    186    sysbus_connect_irq(SYS_BUS_DEVICE(&s->rngc), 0,
    187                       qdev_get_gpio_in(DEVICE(&s->avic), FSL_IMX25_RNGC_IRQ));
    188
    189    /* Initialize all I2C */
    190    for (i = 0; i < FSL_IMX25_NUM_I2CS; i++) {
    191        static const struct {
    192            hwaddr addr;
    193            unsigned int irq;
    194        } i2c_table[FSL_IMX25_NUM_I2CS] = {
    195            { FSL_IMX25_I2C1_ADDR, FSL_IMX25_I2C1_IRQ },
    196            { FSL_IMX25_I2C2_ADDR, FSL_IMX25_I2C2_IRQ },
    197            { FSL_IMX25_I2C3_ADDR, FSL_IMX25_I2C3_IRQ }
    198        };
    199
    200        if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c[i]), errp)) {
    201            return;
    202        }
    203        sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr);
    204        sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
    205                           qdev_get_gpio_in(DEVICE(&s->avic),
    206                                            i2c_table[i].irq));
    207    }
    208
    209    /* Initialize all GPIOs */
    210    for (i = 0; i < FSL_IMX25_NUM_GPIOS; i++) {
    211        static const struct {
    212            hwaddr addr;
    213            unsigned int irq;
    214        } gpio_table[FSL_IMX25_NUM_GPIOS] = {
    215            { FSL_IMX25_GPIO1_ADDR, FSL_IMX25_GPIO1_IRQ },
    216            { FSL_IMX25_GPIO2_ADDR, FSL_IMX25_GPIO2_IRQ },
    217            { FSL_IMX25_GPIO3_ADDR, FSL_IMX25_GPIO3_IRQ },
    218            { FSL_IMX25_GPIO4_ADDR, FSL_IMX25_GPIO4_IRQ }
    219        };
    220
    221        if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio[i]), errp)) {
    222            return;
    223        }
    224        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr);
    225        /* Connect GPIO IRQ to PIC */
    226        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
    227                           qdev_get_gpio_in(DEVICE(&s->avic),
    228                                            gpio_table[i].irq));
    229    }
    230
    231    /* Initialize all SDHC */
    232    for (i = 0; i < FSL_IMX25_NUM_ESDHCS; i++) {
    233        static const struct {
    234            hwaddr addr;
    235            unsigned int irq;
    236        } esdhc_table[FSL_IMX25_NUM_ESDHCS] = {
    237            { FSL_IMX25_ESDHC1_ADDR, FSL_IMX25_ESDHC1_IRQ },
    238            { FSL_IMX25_ESDHC2_ADDR, FSL_IMX25_ESDHC2_IRQ },
    239        };
    240
    241        object_property_set_uint(OBJECT(&s->esdhc[i]), "sd-spec-version", 2,
    242                                 &error_abort);
    243        object_property_set_uint(OBJECT(&s->esdhc[i]), "capareg",
    244                                 IMX25_ESDHC_CAPABILITIES, &error_abort);
    245        object_property_set_uint(OBJECT(&s->esdhc[i]), "vendor",
    246                                 SDHCI_VENDOR_IMX, &error_abort);
    247        if (!sysbus_realize(SYS_BUS_DEVICE(&s->esdhc[i]), errp)) {
    248            return;
    249        }
    250        sysbus_mmio_map(SYS_BUS_DEVICE(&s->esdhc[i]), 0, esdhc_table[i].addr);
    251        sysbus_connect_irq(SYS_BUS_DEVICE(&s->esdhc[i]), 0,
    252                           qdev_get_gpio_in(DEVICE(&s->avic),
    253                                            esdhc_table[i].irq));
    254    }
    255
    256    /* USB */
    257    for (i = 0; i < FSL_IMX25_NUM_USBS; i++) {
    258        static const struct {
    259            hwaddr addr;
    260            unsigned int irq;
    261        } usb_table[FSL_IMX25_NUM_USBS] = {
    262            { FSL_IMX25_USB1_ADDR, FSL_IMX25_USB1_IRQ },
    263            { FSL_IMX25_USB2_ADDR, FSL_IMX25_USB2_IRQ },
    264        };
    265
    266        sysbus_realize(SYS_BUS_DEVICE(&s->usb[i]), &error_abort);
    267        sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0, usb_table[i].addr);
    268        sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i]), 0,
    269                           qdev_get_gpio_in(DEVICE(&s->avic),
    270                                            usb_table[i].irq));
    271    }
    272
    273    /* Watchdog */
    274    object_property_set_bool(OBJECT(&s->wdt), "pretimeout-support", true,
    275                             &error_abort);
    276    sysbus_realize(SYS_BUS_DEVICE(&s->wdt), &error_abort);
    277    sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt), 0, FSL_IMX25_WDT_ADDR);
    278    sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt), 0,
    279                                      qdev_get_gpio_in(DEVICE(&s->avic),
    280                                                       FSL_IMX25_WDT_IRQ));
    281
    282    /* initialize 2 x 16 KB ROM */
    283    memory_region_init_rom(&s->rom[0], OBJECT(dev), "imx25.rom0",
    284                           FSL_IMX25_ROM0_SIZE, &err);
    285    if (err) {
    286        error_propagate(errp, err);
    287        return;
    288    }
    289    memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM0_ADDR,
    290                                &s->rom[0]);
    291    memory_region_init_rom(&s->rom[1], OBJECT(dev), "imx25.rom1",
    292                           FSL_IMX25_ROM1_SIZE, &err);
    293    if (err) {
    294        error_propagate(errp, err);
    295        return;
    296    }
    297    memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM1_ADDR,
    298                                &s->rom[1]);
    299
    300    /* initialize internal RAM (128 KB) */
    301    memory_region_init_ram(&s->iram, NULL, "imx25.iram", FSL_IMX25_IRAM_SIZE,
    302                           &err);
    303    if (err) {
    304        error_propagate(errp, err);
    305        return;
    306    }
    307    memory_region_add_subregion(get_system_memory(), FSL_IMX25_IRAM_ADDR,
    308                                &s->iram);
    309
    310    /* internal RAM (128 KB) is aliased over 128 MB - 128 KB */
    311    memory_region_init_alias(&s->iram_alias, OBJECT(dev), "imx25.iram_alias",
    312                             &s->iram, 0, FSL_IMX25_IRAM_ALIAS_SIZE);
    313    memory_region_add_subregion(get_system_memory(), FSL_IMX25_IRAM_ALIAS_ADDR,
    314                                &s->iram_alias);
    315}
    316
    317static Property fsl_imx25_properties[] = {
    318    DEFINE_PROP_UINT32("fec-phy-num", FslIMX25State, phy_num, 0),
    319    DEFINE_PROP_END_OF_LIST(),
    320};
    321
    322static void fsl_imx25_class_init(ObjectClass *oc, void *data)
    323{
    324    DeviceClass *dc = DEVICE_CLASS(oc);
    325
    326    device_class_set_props(dc, fsl_imx25_properties);
    327    dc->realize = fsl_imx25_realize;
    328    dc->desc = "i.MX25 SOC";
    329    /*
    330     * Reason: uses serial_hds in realize and the imx25 board does not
    331     * support multiple CPUs
    332     */
    333    dc->user_creatable = false;
    334}
    335
    336static const TypeInfo fsl_imx25_type_info = {
    337    .name = TYPE_FSL_IMX25,
    338    .parent = TYPE_DEVICE,
    339    .instance_size = sizeof(FslIMX25State),
    340    .instance_init = fsl_imx25_init,
    341    .class_init = fsl_imx25_class_init,
    342};
    343
    344static void fsl_imx25_register_types(void)
    345{
    346    type_register_static(&fsl_imx25_type_info);
    347}
    348
    349type_init(fsl_imx25_register_types)