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