qemu/hw/arm/mps2.c
<<
>>
Prefs
   1/*
   2 * ARM V2M MPS2 board emulation.
   3 *
   4 * Copyright (c) 2017 Linaro Limited
   5 * Written by Peter Maydell
   6 *
   7 *  This program is free software; you can redistribute it and/or modify
   8 *  it under the terms of the GNU General Public License version 2 or
   9 *  (at your option) any later version.
  10 */
  11
  12/* The MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
  13 * FPGA but is otherwise the same as the 2). Since the CPU itself
  14 * and most of the devices are in the FPGA, the details of the board
  15 * as seen by the guest depend significantly on the FPGA image.
  16 * We model the following FPGA images:
  17 *  "mps2-an385" -- Cortex-M3 as documented in ARM Application Note AN385
  18 *  "mps2-an386" -- Cortex-M4 as documented in ARM Application Note AN386
  19 *  "mps2-an500" -- Cortex-M7 as documented in ARM Application Note AN500
  20 *  "mps2-an511" -- Cortex-M3 'DesignStart' as documented in AN511
  21 *
  22 * Links to the TRM for the board itself and to the various Application
  23 * Notes which document the FPGA images can be found here:
  24 *   https://developer.arm.com/products/system-design/development-boards/cortex-m-prototyping-system
  25 */
  26
  27#include "qemu/osdep.h"
  28#include "qemu/units.h"
  29#include "qemu/cutils.h"
  30#include "qapi/error.h"
  31#include "qemu/error-report.h"
  32#include "hw/arm/boot.h"
  33#include "hw/arm/armv7m.h"
  34#include "hw/or-irq.h"
  35#include "hw/boards.h"
  36#include "exec/address-spaces.h"
  37#include "sysemu/sysemu.h"
  38#include "hw/qdev-properties.h"
  39#include "hw/misc/unimp.h"
  40#include "hw/char/cmsdk-apb-uart.h"
  41#include "hw/timer/cmsdk-apb-timer.h"
  42#include "hw/timer/cmsdk-apb-dualtimer.h"
  43#include "hw/misc/mps2-scc.h"
  44#include "hw/misc/mps2-fpgaio.h"
  45#include "hw/ssi/pl022.h"
  46#include "hw/i2c/arm_sbcon_i2c.h"
  47#include "hw/net/lan9118.h"
  48#include "net/net.h"
  49#include "hw/watchdog/cmsdk-apb-watchdog.h"
  50#include "hw/qdev-clock.h"
  51#include "qom/object.h"
  52
  53typedef enum MPS2FPGAType {
  54    FPGA_AN385,
  55    FPGA_AN386,
  56    FPGA_AN500,
  57    FPGA_AN511,
  58} MPS2FPGAType;
  59
  60struct MPS2MachineClass {
  61    MachineClass parent;
  62    MPS2FPGAType fpga_type;
  63    uint32_t scc_id;
  64    bool has_block_ram;
  65    hwaddr ethernet_base;
  66    hwaddr psram_base;
  67};
  68
  69struct MPS2MachineState {
  70    MachineState parent;
  71
  72    ARMv7MState armv7m;
  73    MemoryRegion ssram1;
  74    MemoryRegion ssram1_m;
  75    MemoryRegion ssram23;
  76    MemoryRegion ssram23_m;
  77    MemoryRegion blockram;
  78    MemoryRegion blockram_m1;
  79    MemoryRegion blockram_m2;
  80    MemoryRegion blockram_m3;
  81    MemoryRegion sram;
  82    /* FPGA APB subsystem */
  83    MPS2SCC scc;
  84    MPS2FPGAIO fpgaio;
  85    /* CMSDK APB subsystem */
  86    CMSDKAPBDualTimer dualtimer;
  87    CMSDKAPBWatchdog watchdog;
  88    CMSDKAPBTimer timer[2];
  89    Clock *sysclk;
  90    Clock *refclk;
  91};
  92
  93#define TYPE_MPS2_MACHINE "mps2"
  94#define TYPE_MPS2_AN385_MACHINE MACHINE_TYPE_NAME("mps2-an385")
  95#define TYPE_MPS2_AN386_MACHINE MACHINE_TYPE_NAME("mps2-an386")
  96#define TYPE_MPS2_AN500_MACHINE MACHINE_TYPE_NAME("mps2-an500")
  97#define TYPE_MPS2_AN511_MACHINE MACHINE_TYPE_NAME("mps2-an511")
  98
  99OBJECT_DECLARE_TYPE(MPS2MachineState, MPS2MachineClass, MPS2_MACHINE)
 100
 101/* Main SYSCLK frequency in Hz */
 102#define SYSCLK_FRQ 25000000
 103
 104/*
 105 * The Application Notes don't say anything about how the
 106 * systick reference clock is configured. (Quite possibly
 107 * they don't have one at all.) This 1MHz clock matches the
 108 * pre-existing behaviour that used to be hardcoded in the
 109 * armv7m_systick implementation.
 110 */
 111#define REFCLK_FRQ (1 * 1000 * 1000)
 112
 113/* Initialize the auxiliary RAM region @mr and map it into
 114 * the memory map at @base.
 115 */
 116static void make_ram(MemoryRegion *mr, const char *name,
 117                     hwaddr base, hwaddr size)
 118{
 119    memory_region_init_ram(mr, NULL, name, size, &error_fatal);
 120    memory_region_add_subregion(get_system_memory(), base, mr);
 121}
 122
 123/* Create an alias of an entire original MemoryRegion @orig
 124 * located at @base in the memory map.
 125 */
 126static void make_ram_alias(MemoryRegion *mr, const char *name,
 127                           MemoryRegion *orig, hwaddr base)
 128{
 129    memory_region_init_alias(mr, NULL, name, orig, 0,
 130                             memory_region_size(orig));
 131    memory_region_add_subregion(get_system_memory(), base, mr);
 132}
 133
 134static void mps2_common_init(MachineState *machine)
 135{
 136    MPS2MachineState *mms = MPS2_MACHINE(machine);
 137    MPS2MachineClass *mmc = MPS2_MACHINE_GET_CLASS(machine);
 138    MemoryRegion *system_memory = get_system_memory();
 139    MachineClass *mc = MACHINE_GET_CLASS(machine);
 140    DeviceState *armv7m, *sccdev;
 141    int i;
 142
 143    if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
 144        error_report("This board can only be used with CPU %s",
 145                     mc->default_cpu_type);
 146        exit(1);
 147    }
 148
 149    if (machine->ram_size != mc->default_ram_size) {
 150        char *sz = size_to_str(mc->default_ram_size);
 151        error_report("Invalid RAM size, should be %s", sz);
 152        g_free(sz);
 153        exit(EXIT_FAILURE);
 154    }
 155
 156    /* This clock doesn't need migration because it is fixed-frequency */
 157    mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
 158    clock_set_hz(mms->sysclk, SYSCLK_FRQ);
 159
 160    mms->refclk = clock_new(OBJECT(machine), "REFCLK");
 161    clock_set_hz(mms->refclk, REFCLK_FRQ);
 162
 163    /* The FPGA images have an odd combination of different RAMs,
 164     * because in hardware they are different implementations and
 165     * connected to different buses, giving varying performance/size
 166     * tradeoffs. For QEMU they're all just RAM, though. We arbitrarily
 167     * call the 16MB our "system memory", as it's the largest lump.
 168     *
 169     * AN385/AN386/AN511:
 170     *  0x21000000 .. 0x21ffffff : PSRAM (16MB)
 171     * AN385/AN386/AN500:
 172     *  0x00000000 .. 0x003fffff : ZBT SSRAM1
 173     *  0x00400000 .. 0x007fffff : mirror of ZBT SSRAM1
 174     *  0x20000000 .. 0x203fffff : ZBT SSRAM 2&3
 175     *  0x20400000 .. 0x207fffff : mirror of ZBT SSRAM 2&3
 176     * AN385/AN386 only:
 177     *  0x01000000 .. 0x01003fff : block RAM (16K)
 178     *  0x01004000 .. 0x01007fff : mirror of above
 179     *  0x01008000 .. 0x0100bfff : mirror of above
 180     *  0x0100c000 .. 0x0100ffff : mirror of above
 181     * AN511 only:
 182     *  0x00000000 .. 0x0003ffff : FPGA block RAM
 183     *  0x00400000 .. 0x007fffff : ZBT SSRAM1
 184     *  0x20000000 .. 0x2001ffff : SRAM
 185     *  0x20400000 .. 0x207fffff : ZBT SSRAM 2&3
 186     * AN500 only:
 187     *  0x60000000 .. 0x60ffffff : PSRAM (16MB)
 188     *
 189     * The AN385/AN386 has a feature where the lowest 16K can be mapped
 190     * either to the bottom of the ZBT SSRAM1 or to the block RAM.
 191     * This is of no use for QEMU so we don't implement it (as if
 192     * zbt_boot_ctrl is always zero).
 193     */
 194    memory_region_add_subregion(system_memory, mmc->psram_base, machine->ram);
 195
 196    if (mmc->has_block_ram) {
 197        make_ram(&mms->blockram, "mps.blockram", 0x01000000, 0x4000);
 198        make_ram_alias(&mms->blockram_m1, "mps.blockram_m1",
 199                       &mms->blockram, 0x01004000);
 200        make_ram_alias(&mms->blockram_m2, "mps.blockram_m2",
 201                       &mms->blockram, 0x01008000);
 202        make_ram_alias(&mms->blockram_m3, "mps.blockram_m3",
 203                       &mms->blockram, 0x0100c000);
 204    }
 205
 206    switch (mmc->fpga_type) {
 207    case FPGA_AN385:
 208    case FPGA_AN386:
 209    case FPGA_AN500:
 210        make_ram(&mms->ssram1, "mps.ssram1", 0x0, 0x400000);
 211        make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", &mms->ssram1, 0x400000);
 212        make_ram(&mms->ssram23, "mps.ssram23", 0x20000000, 0x400000);
 213        make_ram_alias(&mms->ssram23_m, "mps.ssram23_m",
 214                       &mms->ssram23, 0x20400000);
 215        break;
 216    case FPGA_AN511:
 217        make_ram(&mms->blockram, "mps.blockram", 0x0, 0x40000);
 218        make_ram(&mms->ssram1, "mps.ssram1", 0x00400000, 0x00800000);
 219        make_ram(&mms->sram, "mps.sram", 0x20000000, 0x20000);
 220        make_ram(&mms->ssram23, "mps.ssram23", 0x20400000, 0x400000);
 221        break;
 222    default:
 223        g_assert_not_reached();
 224    }
 225
 226    object_initialize_child(OBJECT(mms), "armv7m", &mms->armv7m, TYPE_ARMV7M);
 227    armv7m = DEVICE(&mms->armv7m);
 228    switch (mmc->fpga_type) {
 229    case FPGA_AN385:
 230    case FPGA_AN386:
 231    case FPGA_AN500:
 232        qdev_prop_set_uint32(armv7m, "num-irq", 32);
 233        break;
 234    case FPGA_AN511:
 235        qdev_prop_set_uint32(armv7m, "num-irq", 64);
 236        break;
 237    default:
 238        g_assert_not_reached();
 239    }
 240    qdev_connect_clock_in(armv7m, "cpuclk", mms->sysclk);
 241    qdev_connect_clock_in(armv7m, "refclk", mms->refclk);
 242    qdev_prop_set_string(armv7m, "cpu-type", machine->cpu_type);
 243    qdev_prop_set_bit(armv7m, "enable-bitband", true);
 244    object_property_set_link(OBJECT(&mms->armv7m), "memory",
 245                             OBJECT(system_memory), &error_abort);
 246    sysbus_realize(SYS_BUS_DEVICE(&mms->armv7m), &error_fatal);
 247
 248    create_unimplemented_device("zbtsmram mirror", 0x00400000, 0x00400000);
 249    create_unimplemented_device("RESERVED 1", 0x00800000, 0x00800000);
 250    create_unimplemented_device("Block RAM", 0x01000000, 0x00010000);
 251    create_unimplemented_device("RESERVED 2", 0x01010000, 0x1EFF0000);
 252    create_unimplemented_device("RESERVED 3", 0x20800000, 0x00800000);
 253    create_unimplemented_device("PSRAM", 0x21000000, 0x01000000);
 254    /* These three ranges all cover multiple devices; we may implement
 255     * some of them below (in which case the real device takes precedence
 256     * over the unimplemented-region mapping).
 257     */
 258    create_unimplemented_device("CMSDK APB peripheral region @0x40000000",
 259                                0x40000000, 0x00010000);
 260    create_unimplemented_device("CMSDK AHB peripheral region @0x40010000",
 261                                0x40010000, 0x00010000);
 262    create_unimplemented_device("Extra peripheral region @0x40020000",
 263                                0x40020000, 0x00010000);
 264
 265    create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
 266    create_unimplemented_device("VGA", 0x41000000, 0x0200000);
 267
 268    switch (mmc->fpga_type) {
 269    case FPGA_AN385:
 270    case FPGA_AN386:
 271    case FPGA_AN500:
 272    {
 273        /* The overflow IRQs for UARTs 0, 1 and 2 are ORed together.
 274         * Overflow for UARTs 4 and 5 doesn't trigger any interrupt.
 275         */
 276        Object *orgate;
 277        DeviceState *orgate_dev;
 278
 279        orgate = object_new(TYPE_OR_IRQ);
 280        object_property_set_int(orgate, "num-lines", 6, &error_fatal);
 281        qdev_realize(DEVICE(orgate), NULL, &error_fatal);
 282        orgate_dev = DEVICE(orgate);
 283        qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
 284
 285        for (i = 0; i < 5; i++) {
 286            DeviceState *dev;
 287            SysBusDevice *s;
 288
 289            static const hwaddr uartbase[] = {0x40004000, 0x40005000,
 290                                              0x40006000, 0x40007000,
 291                                              0x40009000};
 292            /* RX irq number; TX irq is always one greater */
 293            static const int uartirq[] = {0, 2, 4, 18, 20};
 294            qemu_irq txovrint = NULL, rxovrint = NULL;
 295
 296            if (i < 3) {
 297                txovrint = qdev_get_gpio_in(orgate_dev, i * 2);
 298                rxovrint = qdev_get_gpio_in(orgate_dev, i * 2 + 1);
 299            }
 300
 301            dev = qdev_new(TYPE_CMSDK_APB_UART);
 302            s = SYS_BUS_DEVICE(dev);
 303            qdev_prop_set_chr(dev, "chardev", serial_hd(i));
 304            qdev_prop_set_uint32(dev, "pclk-frq", SYSCLK_FRQ);
 305            sysbus_realize_and_unref(s, &error_fatal);
 306            sysbus_mmio_map(s, 0, uartbase[i]);
 307            sysbus_connect_irq(s, 0, qdev_get_gpio_in(armv7m, uartirq[i] + 1));
 308            sysbus_connect_irq(s, 1, qdev_get_gpio_in(armv7m, uartirq[i]));
 309            sysbus_connect_irq(s, 2, txovrint);
 310            sysbus_connect_irq(s, 3, rxovrint);
 311        }
 312        break;
 313    }
 314    case FPGA_AN511:
 315    {
 316        /* The overflow IRQs for all UARTs are ORed together.
 317         * Tx and Rx IRQs for each UART are ORed together.
 318         */
 319        Object *orgate;
 320        DeviceState *orgate_dev;
 321
 322        orgate = object_new(TYPE_OR_IRQ);
 323        object_property_set_int(orgate, "num-lines", 10, &error_fatal);
 324        qdev_realize(DEVICE(orgate), NULL, &error_fatal);
 325        orgate_dev = DEVICE(orgate);
 326        qdev_connect_gpio_out(orgate_dev, 0, qdev_get_gpio_in(armv7m, 12));
 327
 328        for (i = 0; i < 5; i++) {
 329            /* system irq numbers for the combined tx/rx for each UART */
 330            static const int uart_txrx_irqno[] = {0, 2, 45, 46, 56};
 331            static const hwaddr uartbase[] = {0x40004000, 0x40005000,
 332                                              0x4002c000, 0x4002d000,
 333                                              0x4002e000};
 334            Object *txrx_orgate;
 335            DeviceState *txrx_orgate_dev, *dev;
 336            SysBusDevice *s;
 337
 338            txrx_orgate = object_new(TYPE_OR_IRQ);
 339            object_property_set_int(txrx_orgate, "num-lines", 2, &error_fatal);
 340            qdev_realize(DEVICE(txrx_orgate), NULL, &error_fatal);
 341            txrx_orgate_dev = DEVICE(txrx_orgate);
 342            qdev_connect_gpio_out(txrx_orgate_dev, 0,
 343                                  qdev_get_gpio_in(armv7m, uart_txrx_irqno[i]));
 344
 345            dev = qdev_new(TYPE_CMSDK_APB_UART);
 346            s = SYS_BUS_DEVICE(dev);
 347            qdev_prop_set_chr(dev, "chardev", serial_hd(i));
 348            qdev_prop_set_uint32(dev, "pclk-frq", SYSCLK_FRQ);
 349            sysbus_realize_and_unref(s, &error_fatal);
 350            sysbus_mmio_map(s, 0, uartbase[i]);
 351            sysbus_connect_irq(s, 0, qdev_get_gpio_in(txrx_orgate_dev, 0));
 352            sysbus_connect_irq(s, 1, qdev_get_gpio_in(txrx_orgate_dev, 1));
 353            sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
 354            sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
 355        }
 356        break;
 357    }
 358    default:
 359        g_assert_not_reached();
 360    }
 361    for (i = 0; i < 4; i++) {
 362        static const hwaddr gpiobase[] = {0x40010000, 0x40011000,
 363                                          0x40012000, 0x40013000};
 364        create_unimplemented_device("cmsdk-ahb-gpio", gpiobase[i], 0x1000);
 365    }
 366
 367    /* CMSDK APB subsystem */
 368    for (i = 0; i < ARRAY_SIZE(mms->timer); i++) {
 369        g_autofree char *name = g_strdup_printf("timer%d", i);
 370        hwaddr base = 0x40000000 + i * 0x1000;
 371        int irqno = 8 + i;
 372        SysBusDevice *sbd;
 373
 374        object_initialize_child(OBJECT(mms), name, &mms->timer[i],
 375                                TYPE_CMSDK_APB_TIMER);
 376        sbd = SYS_BUS_DEVICE(&mms->timer[i]);
 377        qdev_connect_clock_in(DEVICE(&mms->timer[i]), "pclk", mms->sysclk);
 378        sysbus_realize_and_unref(sbd, &error_fatal);
 379        sysbus_mmio_map(sbd, 0, base);
 380        sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(armv7m, irqno));
 381    }
 382
 383    object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
 384                            TYPE_CMSDK_APB_DUALTIMER);
 385    qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->sysclk);
 386    sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
 387    sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
 388                       qdev_get_gpio_in(armv7m, 10));
 389    sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
 390    object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
 391                            TYPE_CMSDK_APB_WATCHDOG);
 392    qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->sysclk);
 393    sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
 394    sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
 395                       qdev_get_gpio_in_named(armv7m, "NMI", 0));
 396    sysbus_mmio_map(SYS_BUS_DEVICE(&mms->watchdog), 0, 0x40008000);
 397
 398    /* FPGA APB subsystem */
 399    object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
 400    sccdev = DEVICE(&mms->scc);
 401    qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
 402    qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
 403    qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
 404    /* All these FPGA images have the same OSCCLK configuration */
 405    qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
 406    qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
 407    qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
 408    qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
 409    sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
 410    sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
 411    object_initialize_child(OBJECT(mms), "fpgaio",
 412                            &mms->fpgaio, TYPE_MPS2_FPGAIO);
 413    qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", 25000000);
 414    sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
 415    sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0x40028000);
 416    sysbus_create_simple(TYPE_PL022, 0x40025000,        /* External ADC */
 417                         qdev_get_gpio_in(armv7m, 22));
 418    for (i = 0; i < 2; i++) {
 419        static const int spi_irqno[] = {11, 24};
 420        static const hwaddr spibase[] = {0x40020000,    /* APB */
 421                                         0x40021000,    /* LCD */
 422                                         0x40026000,    /* Shield0 */
 423                                         0x40027000};   /* Shield1 */
 424        DeviceState *orgate_dev;
 425        Object *orgate;
 426        int j;
 427
 428        orgate = object_new(TYPE_OR_IRQ);
 429        object_property_set_int(orgate, "num-lines", 2, &error_fatal);
 430        orgate_dev = DEVICE(orgate);
 431        qdev_realize(orgate_dev, NULL, &error_fatal);
 432        qdev_connect_gpio_out(orgate_dev, 0,
 433                              qdev_get_gpio_in(armv7m, spi_irqno[i]));
 434        for (j = 0; j < 2; j++) {
 435            sysbus_create_simple(TYPE_PL022, spibase[2 * i + j],
 436                                 qdev_get_gpio_in(orgate_dev, j));
 437        }
 438    }
 439    for (i = 0; i < 4; i++) {
 440        static const hwaddr i2cbase[] = {0x40022000,    /* Touch */
 441                                         0x40023000,    /* Audio */
 442                                         0x40029000,    /* Shield0 */
 443                                         0x4002a000};   /* Shield1 */
 444        DeviceState *dev;
 445
 446        dev = sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
 447        if (i < 2) {
 448            /*
 449             * internal-only bus: mark it full to avoid user-created
 450             * i2c devices being plugged into it.
 451             */
 452            BusState *qbus = qdev_get_child_bus(dev, "i2c");
 453            qbus_mark_full(qbus);
 454        }
 455    }
 456    create_unimplemented_device("i2s", 0x40024000, 0x400);
 457
 458    /* In hardware this is a LAN9220; the LAN9118 is software compatible
 459     * except that it doesn't support the checksum-offload feature.
 460     */
 461    lan9118_init(&nd_table[0], mmc->ethernet_base,
 462                 qdev_get_gpio_in(armv7m,
 463                                  mmc->fpga_type == FPGA_AN511 ? 47 : 13));
 464
 465    armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
 466                       0, 0x400000);
 467}
 468
 469static void mps2_class_init(ObjectClass *oc, void *data)
 470{
 471    MachineClass *mc = MACHINE_CLASS(oc);
 472
 473    mc->init = mps2_common_init;
 474    mc->max_cpus = 1;
 475    mc->default_ram_size = 16 * MiB;
 476    mc->default_ram_id = "mps.ram";
 477}
 478
 479static void mps2_an385_class_init(ObjectClass *oc, void *data)
 480{
 481    MachineClass *mc = MACHINE_CLASS(oc);
 482    MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
 483
 484    mc->desc = "ARM MPS2 with AN385 FPGA image for Cortex-M3";
 485    mmc->fpga_type = FPGA_AN385;
 486    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
 487    mmc->scc_id = 0x41043850;
 488    mmc->psram_base = 0x21000000;
 489    mmc->ethernet_base = 0x40200000;
 490    mmc->has_block_ram = true;
 491}
 492
 493static void mps2_an386_class_init(ObjectClass *oc, void *data)
 494{
 495    MachineClass *mc = MACHINE_CLASS(oc);
 496    MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
 497
 498    mc->desc = "ARM MPS2 with AN386 FPGA image for Cortex-M4";
 499    mmc->fpga_type = FPGA_AN386;
 500    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m4");
 501    mmc->scc_id = 0x41043860;
 502    mmc->psram_base = 0x21000000;
 503    mmc->ethernet_base = 0x40200000;
 504    mmc->has_block_ram = true;
 505}
 506
 507static void mps2_an500_class_init(ObjectClass *oc, void *data)
 508{
 509    MachineClass *mc = MACHINE_CLASS(oc);
 510    MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
 511
 512    mc->desc = "ARM MPS2 with AN500 FPGA image for Cortex-M7";
 513    mmc->fpga_type = FPGA_AN500;
 514    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m7");
 515    mmc->scc_id = 0x41045000;
 516    mmc->psram_base = 0x60000000;
 517    mmc->ethernet_base = 0xa0000000;
 518    mmc->has_block_ram = false;
 519}
 520
 521static void mps2_an511_class_init(ObjectClass *oc, void *data)
 522{
 523    MachineClass *mc = MACHINE_CLASS(oc);
 524    MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc);
 525
 526    mc->desc = "ARM MPS2 with AN511 DesignStart FPGA image for Cortex-M3";
 527    mmc->fpga_type = FPGA_AN511;
 528    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
 529    mmc->scc_id = 0x41045110;
 530    mmc->psram_base = 0x21000000;
 531    mmc->ethernet_base = 0x40200000;
 532    mmc->has_block_ram = false;
 533}
 534
 535static const TypeInfo mps2_info = {
 536    .name = TYPE_MPS2_MACHINE,
 537    .parent = TYPE_MACHINE,
 538    .abstract = true,
 539    .instance_size = sizeof(MPS2MachineState),
 540    .class_size = sizeof(MPS2MachineClass),
 541    .class_init = mps2_class_init,
 542};
 543
 544static const TypeInfo mps2_an385_info = {
 545    .name = TYPE_MPS2_AN385_MACHINE,
 546    .parent = TYPE_MPS2_MACHINE,
 547    .class_init = mps2_an385_class_init,
 548};
 549
 550static const TypeInfo mps2_an386_info = {
 551    .name = TYPE_MPS2_AN386_MACHINE,
 552    .parent = TYPE_MPS2_MACHINE,
 553    .class_init = mps2_an386_class_init,
 554};
 555
 556static const TypeInfo mps2_an500_info = {
 557    .name = TYPE_MPS2_AN500_MACHINE,
 558    .parent = TYPE_MPS2_MACHINE,
 559    .class_init = mps2_an500_class_init,
 560};
 561
 562static const TypeInfo mps2_an511_info = {
 563    .name = TYPE_MPS2_AN511_MACHINE,
 564    .parent = TYPE_MPS2_MACHINE,
 565    .class_init = mps2_an511_class_init,
 566};
 567
 568static void mps2_machine_init(void)
 569{
 570    type_register_static(&mps2_info);
 571    type_register_static(&mps2_an385_info);
 572    type_register_static(&mps2_an386_info);
 573    type_register_static(&mps2_an500_info);
 574    type_register_static(&mps2_an511_info);
 575}
 576
 577type_init(mps2_machine_init);
 578