qemu/hw/arm/aspeed_soc.c
<<
>>
Prefs
   1/*
   2 * ASPEED SoC family
   3 *
   4 * Andrew Jeffery <andrew@aj.id.au>
   5 * Jeremy Kerr <jk@ozlabs.org>
   6 *
   7 * Copyright 2016 IBM Corp.
   8 *
   9 * This code is licensed under the GPL version 2 or later.  See
  10 * the COPYING file in the top-level directory.
  11 */
  12
  13#include "qemu/osdep.h"
  14#include "qapi/error.h"
  15#include "hw/misc/unimp.h"
  16#include "hw/arm/aspeed_soc.h"
  17#include "hw/char/serial.h"
  18#include "qemu/module.h"
  19#include "qemu/error-report.h"
  20#include "hw/i2c/aspeed_i2c.h"
  21#include "net/net.h"
  22#include "sysemu/sysemu.h"
  23
  24#define ASPEED_SOC_IOMEM_SIZE       0x00200000
  25
  26static const hwaddr aspeed_soc_ast2400_memmap[] = {
  27    [ASPEED_DEV_IOMEM]  = 0x1E600000,
  28    [ASPEED_DEV_FMC]    = 0x1E620000,
  29    [ASPEED_DEV_SPI1]   = 0x1E630000,
  30    [ASPEED_DEV_EHCI1]  = 0x1E6A1000,
  31    [ASPEED_DEV_VIC]    = 0x1E6C0000,
  32    [ASPEED_DEV_SDMC]   = 0x1E6E0000,
  33    [ASPEED_DEV_SCU]    = 0x1E6E2000,
  34    [ASPEED_DEV_HACE]   = 0x1E6E3000,
  35    [ASPEED_DEV_XDMA]   = 0x1E6E7000,
  36    [ASPEED_DEV_VIDEO]  = 0x1E700000,
  37    [ASPEED_DEV_ADC]    = 0x1E6E9000,
  38    [ASPEED_DEV_SRAM]   = 0x1E720000,
  39    [ASPEED_DEV_SDHCI]  = 0x1E740000,
  40    [ASPEED_DEV_GPIO]   = 0x1E780000,
  41    [ASPEED_DEV_RTC]    = 0x1E781000,
  42    [ASPEED_DEV_TIMER1] = 0x1E782000,
  43    [ASPEED_DEV_WDT]    = 0x1E785000,
  44    [ASPEED_DEV_PWM]    = 0x1E786000,
  45    [ASPEED_DEV_LPC]    = 0x1E789000,
  46    [ASPEED_DEV_IBT]    = 0x1E789140,
  47    [ASPEED_DEV_I2C]    = 0x1E78A000,
  48    [ASPEED_DEV_ETH1]   = 0x1E660000,
  49    [ASPEED_DEV_ETH2]   = 0x1E680000,
  50    [ASPEED_DEV_UART1]  = 0x1E783000,
  51    [ASPEED_DEV_UART5]  = 0x1E784000,
  52    [ASPEED_DEV_VUART]  = 0x1E787000,
  53    [ASPEED_DEV_SDRAM]  = 0x40000000,
  54};
  55
  56static const hwaddr aspeed_soc_ast2500_memmap[] = {
  57    [ASPEED_DEV_IOMEM]  = 0x1E600000,
  58    [ASPEED_DEV_FMC]    = 0x1E620000,
  59    [ASPEED_DEV_SPI1]   = 0x1E630000,
  60    [ASPEED_DEV_SPI2]   = 0x1E631000,
  61    [ASPEED_DEV_EHCI1]  = 0x1E6A1000,
  62    [ASPEED_DEV_EHCI2]  = 0x1E6A3000,
  63    [ASPEED_DEV_VIC]    = 0x1E6C0000,
  64    [ASPEED_DEV_SDMC]   = 0x1E6E0000,
  65    [ASPEED_DEV_SCU]    = 0x1E6E2000,
  66    [ASPEED_DEV_HACE]   = 0x1E6E3000,
  67    [ASPEED_DEV_XDMA]   = 0x1E6E7000,
  68    [ASPEED_DEV_ADC]    = 0x1E6E9000,
  69    [ASPEED_DEV_VIDEO]  = 0x1E700000,
  70    [ASPEED_DEV_SRAM]   = 0x1E720000,
  71    [ASPEED_DEV_SDHCI]  = 0x1E740000,
  72    [ASPEED_DEV_GPIO]   = 0x1E780000,
  73    [ASPEED_DEV_RTC]    = 0x1E781000,
  74    [ASPEED_DEV_TIMER1] = 0x1E782000,
  75    [ASPEED_DEV_WDT]    = 0x1E785000,
  76    [ASPEED_DEV_PWM]    = 0x1E786000,
  77    [ASPEED_DEV_LPC]    = 0x1E789000,
  78    [ASPEED_DEV_IBT]    = 0x1E789140,
  79    [ASPEED_DEV_I2C]    = 0x1E78A000,
  80    [ASPEED_DEV_ETH1]   = 0x1E660000,
  81    [ASPEED_DEV_ETH2]   = 0x1E680000,
  82    [ASPEED_DEV_UART1]  = 0x1E783000,
  83    [ASPEED_DEV_UART5]  = 0x1E784000,
  84    [ASPEED_DEV_VUART]  = 0x1E787000,
  85    [ASPEED_DEV_SDRAM]  = 0x80000000,
  86};
  87
  88static const int aspeed_soc_ast2400_irqmap[] = {
  89    [ASPEED_DEV_UART1]  = 9,
  90    [ASPEED_DEV_UART2]  = 32,
  91    [ASPEED_DEV_UART3]  = 33,
  92    [ASPEED_DEV_UART4]  = 34,
  93    [ASPEED_DEV_UART5]  = 10,
  94    [ASPEED_DEV_VUART]  = 8,
  95    [ASPEED_DEV_FMC]    = 19,
  96    [ASPEED_DEV_EHCI1]  = 5,
  97    [ASPEED_DEV_EHCI2]  = 13,
  98    [ASPEED_DEV_SDMC]   = 0,
  99    [ASPEED_DEV_SCU]    = 21,
 100    [ASPEED_DEV_ADC]    = 31,
 101    [ASPEED_DEV_GPIO]   = 20,
 102    [ASPEED_DEV_RTC]    = 22,
 103    [ASPEED_DEV_TIMER1] = 16,
 104    [ASPEED_DEV_TIMER2] = 17,
 105    [ASPEED_DEV_TIMER3] = 18,
 106    [ASPEED_DEV_TIMER4] = 35,
 107    [ASPEED_DEV_TIMER5] = 36,
 108    [ASPEED_DEV_TIMER6] = 37,
 109    [ASPEED_DEV_TIMER7] = 38,
 110    [ASPEED_DEV_TIMER8] = 39,
 111    [ASPEED_DEV_WDT]    = 27,
 112    [ASPEED_DEV_PWM]    = 28,
 113    [ASPEED_DEV_LPC]    = 8,
 114    [ASPEED_DEV_I2C]    = 12,
 115    [ASPEED_DEV_ETH1]   = 2,
 116    [ASPEED_DEV_ETH2]   = 3,
 117    [ASPEED_DEV_XDMA]   = 6,
 118    [ASPEED_DEV_SDHCI]  = 26,
 119    [ASPEED_DEV_HACE]   = 4,
 120};
 121
 122#define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
 123
 124static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
 125{
 126    AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
 127
 128    return qdev_get_gpio_in(DEVICE(&s->vic), sc->irqmap[ctrl]);
 129}
 130
 131static void aspeed_soc_init(Object *obj)
 132{
 133    AspeedSoCState *s = ASPEED_SOC(obj);
 134    AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
 135    int i;
 136    char socname[8];
 137    char typename[64];
 138
 139    if (sscanf(sc->name, "%7s", socname) != 1) {
 140        g_assert_not_reached();
 141    }
 142
 143    for (i = 0; i < sc->num_cpus; i++) {
 144        object_initialize_child(obj, "cpu[*]", &s->cpu[i], sc->cpu_type);
 145    }
 146
 147    snprintf(typename, sizeof(typename), "aspeed.scu-%s", socname);
 148    object_initialize_child(obj, "scu", &s->scu, typename);
 149    qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev",
 150                         sc->silicon_rev);
 151    object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
 152                              "hw-strap1");
 153    object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
 154                              "hw-strap2");
 155    object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu),
 156                              "hw-prot-key");
 157
 158    object_initialize_child(obj, "vic", &s->vic, TYPE_ASPEED_VIC);
 159
 160    object_initialize_child(obj, "rtc", &s->rtc, TYPE_ASPEED_RTC);
 161
 162    snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
 163    object_initialize_child(obj, "timerctrl", &s->timerctrl, typename);
 164
 165    snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
 166    object_initialize_child(obj, "i2c", &s->i2c, typename);
 167
 168    snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
 169    object_initialize_child(obj, "fmc", &s->fmc, typename);
 170    object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs");
 171
 172    for (i = 0; i < sc->spis_num; i++) {
 173        snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
 174        object_initialize_child(obj, "spi[*]", &s->spi[i], typename);
 175    }
 176
 177    for (i = 0; i < sc->ehcis_num; i++) {
 178        object_initialize_child(obj, "ehci[*]", &s->ehci[i],
 179                                TYPE_PLATFORM_EHCI);
 180    }
 181
 182    snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname);
 183    object_initialize_child(obj, "sdmc", &s->sdmc, typename);
 184    object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
 185                              "ram-size");
 186    object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc),
 187                              "max-ram-size");
 188
 189    for (i = 0; i < sc->wdts_num; i++) {
 190        snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
 191        object_initialize_child(obj, "wdt[*]", &s->wdt[i], typename);
 192    }
 193
 194    for (i = 0; i < sc->macs_num; i++) {
 195        object_initialize_child(obj, "ftgmac100[*]", &s->ftgmac100[i],
 196                                TYPE_FTGMAC100);
 197    }
 198
 199    snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s", socname);
 200    object_initialize_child(obj, "xdma", &s->xdma, typename);
 201
 202    snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
 203    object_initialize_child(obj, "gpio", &s->gpio, typename);
 204
 205    object_initialize_child(obj, "sdc", &s->sdhci, TYPE_ASPEED_SDHCI);
 206
 207    object_property_set_int(OBJECT(&s->sdhci), "num-slots", 2, &error_abort);
 208
 209    /* Init sd card slot class here so that they're under the correct parent */
 210    for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
 211        object_initialize_child(obj, "sdhci[*]", &s->sdhci.slots[i],
 212                                TYPE_SYSBUS_SDHCI);
 213    }
 214
 215    object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC);
 216
 217    snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname);
 218    object_initialize_child(obj, "hace", &s->hace, typename);
 219}
 220
 221static void aspeed_soc_realize(DeviceState *dev, Error **errp)
 222{
 223    int i;
 224    AspeedSoCState *s = ASPEED_SOC(dev);
 225    AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
 226    Error *err = NULL;
 227
 228    /* IO space */
 229    create_unimplemented_device("aspeed_soc.io", sc->memmap[ASPEED_DEV_IOMEM],
 230                                ASPEED_SOC_IOMEM_SIZE);
 231
 232    /* Video engine stub */
 233    create_unimplemented_device("aspeed.video", sc->memmap[ASPEED_DEV_VIDEO],
 234                                0x1000);
 235
 236    /* CPU */
 237    for (i = 0; i < sc->num_cpus; i++) {
 238        if (!qdev_realize(DEVICE(&s->cpu[i]), NULL, errp)) {
 239            return;
 240        }
 241    }
 242
 243    /* SRAM */
 244    memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram",
 245                           sc->sram_size, &err);
 246    if (err) {
 247        error_propagate(errp, err);
 248        return;
 249    }
 250    memory_region_add_subregion(get_system_memory(),
 251                                sc->memmap[ASPEED_DEV_SRAM], &s->sram);
 252
 253    /* SCU */
 254    if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) {
 255        return;
 256    }
 257    sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]);
 258
 259    /* VIC */
 260    if (!sysbus_realize(SYS_BUS_DEVICE(&s->vic), errp)) {
 261        return;
 262    }
 263    sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->memmap[ASPEED_DEV_VIC]);
 264    sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
 265                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
 266    sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
 267                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
 268
 269    /* RTC */
 270    if (!sysbus_realize(SYS_BUS_DEVICE(&s->rtc), errp)) {
 271        return;
 272    }
 273    sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, sc->memmap[ASPEED_DEV_RTC]);
 274    sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0,
 275                       aspeed_soc_get_irq(s, ASPEED_DEV_RTC));
 276
 277    /* Timer */
 278    object_property_set_link(OBJECT(&s->timerctrl), "scu", OBJECT(&s->scu),
 279                             &error_abort);
 280    if (!sysbus_realize(SYS_BUS_DEVICE(&s->timerctrl), errp)) {
 281        return;
 282    }
 283    sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0,
 284                    sc->memmap[ASPEED_DEV_TIMER1]);
 285    for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
 286        qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_DEV_TIMER1 + i);
 287        sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
 288    }
 289
 290    /* UART - attach an 8250 to the IO space as our UART5 */
 291    serial_mm_init(get_system_memory(), sc->memmap[ASPEED_DEV_UART5], 2,
 292                   aspeed_soc_get_irq(s, ASPEED_DEV_UART5), 38400,
 293                   serial_hd(0), DEVICE_LITTLE_ENDIAN);
 294
 295    /* I2C */
 296    object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(s->dram_mr),
 297                             &error_abort);
 298    if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) {
 299        return;
 300    }
 301    sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_DEV_I2C]);
 302    sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
 303                       aspeed_soc_get_irq(s, ASPEED_DEV_I2C));
 304
 305    /* FMC, The number of CS is set at the board level */
 306    object_property_set_link(OBJECT(&s->fmc), "dram", OBJECT(s->dram_mr),
 307                             &error_abort);
 308    if (!sysbus_realize(SYS_BUS_DEVICE(&s->fmc), errp)) {
 309        return;
 310    }
 311    sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_DEV_FMC]);
 312    sysbus_mmio_map(SYS_BUS_DEVICE(&s->fmc), 1,
 313                    s->fmc.ctrl->flash_window_base);
 314    sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0,
 315                       aspeed_soc_get_irq(s, ASPEED_DEV_FMC));
 316
 317    /* SPI */
 318    for (i = 0; i < sc->spis_num; i++) {
 319        object_property_set_int(OBJECT(&s->spi[i]), "num-cs", 1, &error_abort);
 320        if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) {
 321            return;
 322        }
 323        sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
 324                        sc->memmap[ASPEED_DEV_SPI1 + i]);
 325        sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 1,
 326                        s->spi[i].ctrl->flash_window_base);
 327    }
 328
 329    /* EHCI */
 330    for (i = 0; i < sc->ehcis_num; i++) {
 331        if (!sysbus_realize(SYS_BUS_DEVICE(&s->ehci[i]), errp)) {
 332            return;
 333        }
 334        sysbus_mmio_map(SYS_BUS_DEVICE(&s->ehci[i]), 0,
 335                        sc->memmap[ASPEED_DEV_EHCI1 + i]);
 336        sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0,
 337                           aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i));
 338    }
 339
 340    /* SDMC - SDRAM Memory Controller */
 341    if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) {
 342        return;
 343    }
 344    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, sc->memmap[ASPEED_DEV_SDMC]);
 345
 346    /* Watch dog */
 347    for (i = 0; i < sc->wdts_num; i++) {
 348        AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
 349
 350        object_property_set_link(OBJECT(&s->wdt[i]), "scu", OBJECT(&s->scu),
 351                                 &error_abort);
 352        if (!sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), errp)) {
 353            return;
 354        }
 355        sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
 356                        sc->memmap[ASPEED_DEV_WDT] + i * awc->offset);
 357    }
 358
 359    /* Net */
 360    for (i = 0; i < sc->macs_num; i++) {
 361        object_property_set_bool(OBJECT(&s->ftgmac100[i]), "aspeed", true,
 362                                 &error_abort);
 363        if (!sysbus_realize(SYS_BUS_DEVICE(&s->ftgmac100[i]), errp)) {
 364            return;
 365        }
 366        sysbus_mmio_map(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
 367                        sc->memmap[ASPEED_DEV_ETH1 + i]);
 368        sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
 369                           aspeed_soc_get_irq(s, ASPEED_DEV_ETH1 + i));
 370    }
 371
 372    /* XDMA */
 373    if (!sysbus_realize(SYS_BUS_DEVICE(&s->xdma), errp)) {
 374        return;
 375    }
 376    sysbus_mmio_map(SYS_BUS_DEVICE(&s->xdma), 0,
 377                    sc->memmap[ASPEED_DEV_XDMA]);
 378    sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0,
 379                       aspeed_soc_get_irq(s, ASPEED_DEV_XDMA));
 380
 381    /* GPIO */
 382    if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
 383        return;
 384    }
 385    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_DEV_GPIO]);
 386    sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0,
 387                       aspeed_soc_get_irq(s, ASPEED_DEV_GPIO));
 388
 389    /* SDHCI */
 390    if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdhci), errp)) {
 391        return;
 392    }
 393    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdhci), 0,
 394                    sc->memmap[ASPEED_DEV_SDHCI]);
 395    sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0,
 396                       aspeed_soc_get_irq(s, ASPEED_DEV_SDHCI));
 397
 398    /* LPC */
 399    if (!sysbus_realize(SYS_BUS_DEVICE(&s->lpc), errp)) {
 400        return;
 401    }
 402    sysbus_mmio_map(SYS_BUS_DEVICE(&s->lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
 403
 404    /* Connect the LPC IRQ to the VIC */
 405    sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 0,
 406                       aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
 407
 408    /*
 409     * On the AST2400 and AST2500 the one LPC IRQ is shared between all of the
 410     * subdevices. Connect the LPC subdevice IRQs to the LPC controller IRQ (by
 411     * contrast, on the AST2600, the subdevice IRQs are connected straight to
 412     * the GIC).
 413     *
 414     * LPC subdevice IRQ sources are offset from 1 because the shared IRQ output
 415     * to the VIC is at offset 0.
 416     */
 417    sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_1,
 418                       qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_1));
 419
 420    sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_2,
 421                       qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_2));
 422
 423    sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_3,
 424                       qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_3));
 425
 426    sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_4,
 427                       qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_4));
 428
 429    /* HACE */
 430    object_property_set_link(OBJECT(&s->hace), "dram", OBJECT(s->dram_mr),
 431                             &error_abort);
 432    if (!sysbus_realize(SYS_BUS_DEVICE(&s->hace), errp)) {
 433        return;
 434    }
 435    sysbus_mmio_map(SYS_BUS_DEVICE(&s->hace), 0, sc->memmap[ASPEED_DEV_HACE]);
 436    sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0,
 437                       aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
 438}
 439static Property aspeed_soc_properties[] = {
 440    DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
 441                     MemoryRegion *),
 442    DEFINE_PROP_END_OF_LIST(),
 443};
 444
 445static void aspeed_soc_class_init(ObjectClass *oc, void *data)
 446{
 447    DeviceClass *dc = DEVICE_CLASS(oc);
 448
 449    dc->realize = aspeed_soc_realize;
 450    /* Reason: Uses serial_hds and nd_table in realize() directly */
 451    dc->user_creatable = false;
 452    device_class_set_props(dc, aspeed_soc_properties);
 453}
 454
 455static const TypeInfo aspeed_soc_type_info = {
 456    .name           = TYPE_ASPEED_SOC,
 457    .parent         = TYPE_DEVICE,
 458    .instance_size  = sizeof(AspeedSoCState),
 459    .class_size     = sizeof(AspeedSoCClass),
 460    .class_init     = aspeed_soc_class_init,
 461    .abstract       = true,
 462};
 463
 464static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data)
 465{
 466    AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc);
 467
 468    sc->name         = "ast2400-a1";
 469    sc->cpu_type     = ARM_CPU_TYPE_NAME("arm926");
 470    sc->silicon_rev  = AST2400_A1_SILICON_REV;
 471    sc->sram_size    = 0x8000;
 472    sc->spis_num     = 1;
 473    sc->ehcis_num    = 1;
 474    sc->wdts_num     = 2;
 475    sc->macs_num     = 2;
 476    sc->irqmap       = aspeed_soc_ast2400_irqmap;
 477    sc->memmap       = aspeed_soc_ast2400_memmap;
 478    sc->num_cpus     = 1;
 479}
 480
 481static const TypeInfo aspeed_soc_ast2400_type_info = {
 482    .name           = "ast2400-a1",
 483    .parent         = TYPE_ASPEED_SOC,
 484    .instance_init  = aspeed_soc_init,
 485    .instance_size  = sizeof(AspeedSoCState),
 486    .class_init     = aspeed_soc_ast2400_class_init,
 487};
 488
 489static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data)
 490{
 491    AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc);
 492
 493    sc->name         = "ast2500-a1";
 494    sc->cpu_type     = ARM_CPU_TYPE_NAME("arm1176");
 495    sc->silicon_rev  = AST2500_A1_SILICON_REV;
 496    sc->sram_size    = 0x9000;
 497    sc->spis_num     = 2;
 498    sc->ehcis_num    = 2;
 499    sc->wdts_num     = 3;
 500    sc->macs_num     = 2;
 501    sc->irqmap       = aspeed_soc_ast2500_irqmap;
 502    sc->memmap       = aspeed_soc_ast2500_memmap;
 503    sc->num_cpus     = 1;
 504}
 505
 506static const TypeInfo aspeed_soc_ast2500_type_info = {
 507    .name           = "ast2500-a1",
 508    .parent         = TYPE_ASPEED_SOC,
 509    .instance_init  = aspeed_soc_init,
 510    .instance_size  = sizeof(AspeedSoCState),
 511    .class_init     = aspeed_soc_ast2500_class_init,
 512};
 513static void aspeed_soc_register_types(void)
 514{
 515    type_register_static(&aspeed_soc_type_info);
 516    type_register_static(&aspeed_soc_ast2400_type_info);
 517    type_register_static(&aspeed_soc_ast2500_type_info);
 518};
 519
 520type_init(aspeed_soc_register_types)
 521