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 "qemu/units.h"
  15#include "qapi/error.h"
  16#include "hw/misc/unimp.h"
  17#include "hw/arm/aspeed_soc.h"
  18#include "hw/char/serial.h"
  19#include "qemu/module.h"
  20#include "qemu/error-report.h"
  21#include "hw/i2c/aspeed_i2c.h"
  22#include "net/net.h"
  23#include "sysemu/sysemu.h"
  24
  25#define ASPEED_SOC_IOMEM_SIZE       0x00200000
  26
  27static const hwaddr aspeed_soc_ast2400_memmap[] = {
  28    [ASPEED_DEV_SPI_BOOT]  =  ASPEED_SOC_SPI_BOOT_ADDR,
  29    [ASPEED_DEV_IOMEM]  = 0x1E600000,
  30    [ASPEED_DEV_FMC]    = 0x1E620000,
  31    [ASPEED_DEV_SPI1]   = 0x1E630000,
  32    [ASPEED_DEV_EHCI1]  = 0x1E6A1000,
  33    [ASPEED_DEV_VIC]    = 0x1E6C0000,
  34    [ASPEED_DEV_SDMC]   = 0x1E6E0000,
  35    [ASPEED_DEV_SCU]    = 0x1E6E2000,
  36    [ASPEED_DEV_HACE]   = 0x1E6E3000,
  37    [ASPEED_DEV_XDMA]   = 0x1E6E7000,
  38    [ASPEED_DEV_VIDEO]  = 0x1E700000,
  39    [ASPEED_DEV_ADC]    = 0x1E6E9000,
  40    [ASPEED_DEV_SRAM]   = 0x1E720000,
  41    [ASPEED_DEV_SDHCI]  = 0x1E740000,
  42    [ASPEED_DEV_GPIO]   = 0x1E780000,
  43    [ASPEED_DEV_RTC]    = 0x1E781000,
  44    [ASPEED_DEV_TIMER1] = 0x1E782000,
  45    [ASPEED_DEV_WDT]    = 0x1E785000,
  46    [ASPEED_DEV_PWM]    = 0x1E786000,
  47    [ASPEED_DEV_LPC]    = 0x1E789000,
  48    [ASPEED_DEV_IBT]    = 0x1E789140,
  49    [ASPEED_DEV_I2C]    = 0x1E78A000,
  50    [ASPEED_DEV_PECI]   = 0x1E78B000,
  51    [ASPEED_DEV_ETH1]   = 0x1E660000,
  52    [ASPEED_DEV_ETH2]   = 0x1E680000,
  53    [ASPEED_DEV_UART1]  = 0x1E783000,
  54    [ASPEED_DEV_UART2]  = 0x1E78D000,
  55    [ASPEED_DEV_UART3]  = 0x1E78E000,
  56    [ASPEED_DEV_UART4]  = 0x1E78F000,
  57    [ASPEED_DEV_UART5]  = 0x1E784000,
  58    [ASPEED_DEV_VUART]  = 0x1E787000,
  59    [ASPEED_DEV_SDRAM]  = 0x40000000,
  60};
  61
  62static const hwaddr aspeed_soc_ast2500_memmap[] = {
  63    [ASPEED_DEV_SPI_BOOT]  = ASPEED_SOC_SPI_BOOT_ADDR,
  64    [ASPEED_DEV_IOMEM]  = 0x1E600000,
  65    [ASPEED_DEV_FMC]    = 0x1E620000,
  66    [ASPEED_DEV_SPI1]   = 0x1E630000,
  67    [ASPEED_DEV_SPI2]   = 0x1E631000,
  68    [ASPEED_DEV_EHCI1]  = 0x1E6A1000,
  69    [ASPEED_DEV_EHCI2]  = 0x1E6A3000,
  70    [ASPEED_DEV_VIC]    = 0x1E6C0000,
  71    [ASPEED_DEV_SDMC]   = 0x1E6E0000,
  72    [ASPEED_DEV_SCU]    = 0x1E6E2000,
  73    [ASPEED_DEV_HACE]   = 0x1E6E3000,
  74    [ASPEED_DEV_XDMA]   = 0x1E6E7000,
  75    [ASPEED_DEV_ADC]    = 0x1E6E9000,
  76    [ASPEED_DEV_VIDEO]  = 0x1E700000,
  77    [ASPEED_DEV_SRAM]   = 0x1E720000,
  78    [ASPEED_DEV_SDHCI]  = 0x1E740000,
  79    [ASPEED_DEV_GPIO]   = 0x1E780000,
  80    [ASPEED_DEV_RTC]    = 0x1E781000,
  81    [ASPEED_DEV_TIMER1] = 0x1E782000,
  82    [ASPEED_DEV_WDT]    = 0x1E785000,
  83    [ASPEED_DEV_PWM]    = 0x1E786000,
  84    [ASPEED_DEV_LPC]    = 0x1E789000,
  85    [ASPEED_DEV_IBT]    = 0x1E789140,
  86    [ASPEED_DEV_I2C]    = 0x1E78A000,
  87    [ASPEED_DEV_PECI]   = 0x1E78B000,
  88    [ASPEED_DEV_ETH1]   = 0x1E660000,
  89    [ASPEED_DEV_ETH2]   = 0x1E680000,
  90    [ASPEED_DEV_UART1]  = 0x1E783000,
  91    [ASPEED_DEV_UART2]  = 0x1E78D000,
  92    [ASPEED_DEV_UART3]  = 0x1E78E000,
  93    [ASPEED_DEV_UART4]  = 0x1E78F000,
  94    [ASPEED_DEV_UART5]  = 0x1E784000,
  95    [ASPEED_DEV_VUART]  = 0x1E787000,
  96    [ASPEED_DEV_SDRAM]  = 0x80000000,
  97};
  98
  99static const int aspeed_soc_ast2400_irqmap[] = {
 100    [ASPEED_DEV_UART1]  = 9,
 101    [ASPEED_DEV_UART2]  = 32,
 102    [ASPEED_DEV_UART3]  = 33,
 103    [ASPEED_DEV_UART4]  = 34,
 104    [ASPEED_DEV_UART5]  = 10,
 105    [ASPEED_DEV_VUART]  = 8,
 106    [ASPEED_DEV_FMC]    = 19,
 107    [ASPEED_DEV_EHCI1]  = 5,
 108    [ASPEED_DEV_EHCI2]  = 13,
 109    [ASPEED_DEV_SDMC]   = 0,
 110    [ASPEED_DEV_SCU]    = 21,
 111    [ASPEED_DEV_ADC]    = 31,
 112    [ASPEED_DEV_GPIO]   = 20,
 113    [ASPEED_DEV_RTC]    = 22,
 114    [ASPEED_DEV_TIMER1] = 16,
 115    [ASPEED_DEV_TIMER2] = 17,
 116    [ASPEED_DEV_TIMER3] = 18,
 117    [ASPEED_DEV_TIMER4] = 35,
 118    [ASPEED_DEV_TIMER5] = 36,
 119    [ASPEED_DEV_TIMER6] = 37,
 120    [ASPEED_DEV_TIMER7] = 38,
 121    [ASPEED_DEV_TIMER8] = 39,
 122    [ASPEED_DEV_WDT]    = 27,
 123    [ASPEED_DEV_PWM]    = 28,
 124    [ASPEED_DEV_LPC]    = 8,
 125    [ASPEED_DEV_I2C]    = 12,
 126    [ASPEED_DEV_PECI]   = 15,
 127    [ASPEED_DEV_ETH1]   = 2,
 128    [ASPEED_DEV_ETH2]   = 3,
 129    [ASPEED_DEV_XDMA]   = 6,
 130    [ASPEED_DEV_SDHCI]  = 26,
 131    [ASPEED_DEV_HACE]   = 4,
 132};
 133
 134#define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
 135
 136static qemu_irq aspeed_soc_ast2400_get_irq(AspeedSoCState *s, int dev)
 137{
 138    AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
 139
 140    return qdev_get_gpio_in(DEVICE(&s->vic), sc->irqmap[dev]);
 141}
 142
 143static void aspeed_soc_init(Object *obj)
 144{
 145    AspeedSoCState *s = ASPEED_SOC(obj);
 146    AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
 147    int i;
 148    char socname[8];
 149    char typename[64];
 150
 151    if (sscanf(sc->name, "%7s", socname) != 1) {
 152        g_assert_not_reached();
 153    }
 154
 155    for (i = 0; i < sc->num_cpus; i++) {
 156        object_initialize_child(obj, "cpu[*]", &s->cpu[i], sc->cpu_type);
 157    }
 158
 159    snprintf(typename, sizeof(typename), "aspeed.scu-%s", socname);
 160    object_initialize_child(obj, "scu", &s->scu, typename);
 161    qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev",
 162                         sc->silicon_rev);
 163    object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
 164                              "hw-strap1");
 165    object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
 166                              "hw-strap2");
 167    object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu),
 168                              "hw-prot-key");
 169
 170    object_initialize_child(obj, "vic", &s->vic, TYPE_ASPEED_VIC);
 171
 172    object_initialize_child(obj, "rtc", &s->rtc, TYPE_ASPEED_RTC);
 173
 174    snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
 175    object_initialize_child(obj, "timerctrl", &s->timerctrl, typename);
 176
 177    snprintf(typename, sizeof(typename), "aspeed.adc-%s", socname);
 178    object_initialize_child(obj, "adc", &s->adc, typename);
 179
 180    snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
 181    object_initialize_child(obj, "i2c", &s->i2c, typename);
 182
 183    object_initialize_child(obj, "peci", &s->peci, TYPE_ASPEED_PECI);
 184
 185    snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
 186    object_initialize_child(obj, "fmc", &s->fmc, typename);
 187
 188    for (i = 0; i < sc->spis_num; i++) {
 189        snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
 190        object_initialize_child(obj, "spi[*]", &s->spi[i], typename);
 191    }
 192
 193    for (i = 0; i < sc->ehcis_num; i++) {
 194        object_initialize_child(obj, "ehci[*]", &s->ehci[i],
 195                                TYPE_PLATFORM_EHCI);
 196    }
 197
 198    snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname);
 199    object_initialize_child(obj, "sdmc", &s->sdmc, typename);
 200    object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
 201                              "ram-size");
 202
 203    for (i = 0; i < sc->wdts_num; i++) {
 204        snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
 205        object_initialize_child(obj, "wdt[*]", &s->wdt[i], typename);
 206    }
 207
 208    for (i = 0; i < sc->macs_num; i++) {
 209        object_initialize_child(obj, "ftgmac100[*]", &s->ftgmac100[i],
 210                                TYPE_FTGMAC100);
 211    }
 212
 213    for (i = 0; i < sc->uarts_num; i++) {
 214        object_initialize_child(obj, "uart[*]", &s->uart[i], TYPE_SERIAL_MM);
 215    }
 216
 217    snprintf(typename, sizeof(typename), TYPE_ASPEED_XDMA "-%s", socname);
 218    object_initialize_child(obj, "xdma", &s->xdma, typename);
 219
 220    snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
 221    object_initialize_child(obj, "gpio", &s->gpio, typename);
 222
 223    object_initialize_child(obj, "sdc", &s->sdhci, TYPE_ASPEED_SDHCI);
 224
 225    object_property_set_int(OBJECT(&s->sdhci), "num-slots", 2, &error_abort);
 226
 227    /* Init sd card slot class here so that they're under the correct parent */
 228    for (i = 0; i < ASPEED_SDHCI_NUM_SLOTS; ++i) {
 229        object_initialize_child(obj, "sdhci[*]", &s->sdhci.slots[i],
 230                                TYPE_SYSBUS_SDHCI);
 231    }
 232
 233    object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC);
 234
 235    snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname);
 236    object_initialize_child(obj, "hace", &s->hace, typename);
 237
 238    object_initialize_child(obj, "iomem", &s->iomem, TYPE_UNIMPLEMENTED_DEVICE);
 239    object_initialize_child(obj, "video", &s->video, TYPE_UNIMPLEMENTED_DEVICE);
 240}
 241
 242static void aspeed_soc_realize(DeviceState *dev, Error **errp)
 243{
 244    int i;
 245    AspeedSoCState *s = ASPEED_SOC(dev);
 246    AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
 247    Error *err = NULL;
 248    g_autofree char *sram_name = NULL;
 249
 250    /* Default boot region (SPI memory or ROMs) */
 251    memory_region_init(&s->spi_boot_container, OBJECT(s),
 252                       "aspeed.spi_boot_container", 0x10000000);
 253    memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SPI_BOOT],
 254                                &s->spi_boot_container);
 255
 256    /* IO space */
 257    aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->iomem), "aspeed.io",
 258                                  sc->memmap[ASPEED_DEV_IOMEM],
 259                                  ASPEED_SOC_IOMEM_SIZE);
 260
 261    /* Video engine stub */
 262    aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->video), "aspeed.video",
 263                                  sc->memmap[ASPEED_DEV_VIDEO], 0x1000);
 264
 265    /* CPU */
 266    for (i = 0; i < sc->num_cpus; i++) {
 267        object_property_set_link(OBJECT(&s->cpu[i]), "memory",
 268                                 OBJECT(s->memory), &error_abort);
 269        if (!qdev_realize(DEVICE(&s->cpu[i]), NULL, errp)) {
 270            return;
 271        }
 272    }
 273
 274    /* SRAM */
 275    sram_name = g_strdup_printf("aspeed.sram.%d", CPU(&s->cpu[0])->cpu_index);
 276    memory_region_init_ram(&s->sram, OBJECT(s), sram_name, sc->sram_size, &err);
 277    if (err) {
 278        error_propagate(errp, err);
 279        return;
 280    }
 281    memory_region_add_subregion(s->memory,
 282                                sc->memmap[ASPEED_DEV_SRAM], &s->sram);
 283
 284    /* SCU */
 285    if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) {
 286        return;
 287    }
 288    aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]);
 289
 290    /* VIC */
 291    if (!sysbus_realize(SYS_BUS_DEVICE(&s->vic), errp)) {
 292        return;
 293    }
 294    aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->vic), 0, sc->memmap[ASPEED_DEV_VIC]);
 295    sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
 296                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
 297    sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
 298                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
 299
 300    /* RTC */
 301    if (!sysbus_realize(SYS_BUS_DEVICE(&s->rtc), errp)) {
 302        return;
 303    }
 304    aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->rtc), 0, sc->memmap[ASPEED_DEV_RTC]);
 305    sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0,
 306                       aspeed_soc_get_irq(s, ASPEED_DEV_RTC));
 307
 308    /* Timer */
 309    object_property_set_link(OBJECT(&s->timerctrl), "scu", OBJECT(&s->scu),
 310                             &error_abort);
 311    if (!sysbus_realize(SYS_BUS_DEVICE(&s->timerctrl), errp)) {
 312        return;
 313    }
 314    aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->timerctrl), 0,
 315                    sc->memmap[ASPEED_DEV_TIMER1]);
 316    for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
 317        qemu_irq irq = aspeed_soc_get_irq(s, ASPEED_DEV_TIMER1 + i);
 318        sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
 319    }
 320
 321    /* ADC */
 322    if (!sysbus_realize(SYS_BUS_DEVICE(&s->adc), errp)) {
 323        return;
 324    }
 325    aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->adc), 0, sc->memmap[ASPEED_DEV_ADC]);
 326    sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
 327                       aspeed_soc_get_irq(s, ASPEED_DEV_ADC));
 328
 329    /* UART */
 330    if (!aspeed_soc_uart_realize(s, errp)) {
 331        return;
 332    }
 333
 334    /* I2C */
 335    object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(s->dram_mr),
 336                             &error_abort);
 337    if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) {
 338        return;
 339    }
 340    aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_DEV_I2C]);
 341    sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
 342                       aspeed_soc_get_irq(s, ASPEED_DEV_I2C));
 343
 344    /* PECI */
 345    if (!sysbus_realize(SYS_BUS_DEVICE(&s->peci), errp)) {
 346        return;
 347    }
 348    aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->peci), 0,
 349                    sc->memmap[ASPEED_DEV_PECI]);
 350    sysbus_connect_irq(SYS_BUS_DEVICE(&s->peci), 0,
 351                       aspeed_soc_get_irq(s, ASPEED_DEV_PECI));
 352
 353    /* FMC, The number of CS is set at the board level */
 354    object_property_set_link(OBJECT(&s->fmc), "dram", OBJECT(s->dram_mr),
 355                             &error_abort);
 356    if (!sysbus_realize(SYS_BUS_DEVICE(&s->fmc), errp)) {
 357        return;
 358    }
 359    aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_DEV_FMC]);
 360    aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->fmc), 1,
 361                    ASPEED_SMC_GET_CLASS(&s->fmc)->flash_window_base);
 362    sysbus_connect_irq(SYS_BUS_DEVICE(&s->fmc), 0,
 363                       aspeed_soc_get_irq(s, ASPEED_DEV_FMC));
 364
 365    /* Set up an alias on the FMC CE0 region (boot default) */
 366    MemoryRegion *fmc0_mmio = &s->fmc.flashes[0].mmio;
 367    memory_region_init_alias(&s->spi_boot, OBJECT(s), "aspeed.spi_boot",
 368                             fmc0_mmio, 0, memory_region_size(fmc0_mmio));
 369    memory_region_add_subregion(&s->spi_boot_container, 0x0, &s->spi_boot);
 370
 371    /* SPI */
 372    for (i = 0; i < sc->spis_num; i++) {
 373        if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) {
 374            return;
 375        }
 376        aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->spi[i]), 0,
 377                        sc->memmap[ASPEED_DEV_SPI1 + i]);
 378        aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->spi[i]), 1,
 379                        ASPEED_SMC_GET_CLASS(&s->spi[i])->flash_window_base);
 380    }
 381
 382    /* EHCI */
 383    for (i = 0; i < sc->ehcis_num; i++) {
 384        if (!sysbus_realize(SYS_BUS_DEVICE(&s->ehci[i]), errp)) {
 385            return;
 386        }
 387        aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->ehci[i]), 0,
 388                        sc->memmap[ASPEED_DEV_EHCI1 + i]);
 389        sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0,
 390                           aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i));
 391    }
 392
 393    /* SDMC - SDRAM Memory Controller */
 394    if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdmc), errp)) {
 395        return;
 396    }
 397    aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->sdmc), 0,
 398                    sc->memmap[ASPEED_DEV_SDMC]);
 399
 400    /* Watch dog */
 401    for (i = 0; i < sc->wdts_num; i++) {
 402        AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
 403        hwaddr wdt_offset = sc->memmap[ASPEED_DEV_WDT] + i * awc->iosize;
 404
 405        object_property_set_link(OBJECT(&s->wdt[i]), "scu", OBJECT(&s->scu),
 406                                 &error_abort);
 407        if (!sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), errp)) {
 408            return;
 409        }
 410        aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->wdt[i]), 0, wdt_offset);
 411    }
 412
 413    /* RAM  */
 414    if (!aspeed_soc_dram_init(s, errp)) {
 415        return;
 416    }
 417
 418    /* Net */
 419    for (i = 0; i < sc->macs_num; i++) {
 420        object_property_set_bool(OBJECT(&s->ftgmac100[i]), "aspeed", true,
 421                                 &error_abort);
 422        if (!sysbus_realize(SYS_BUS_DEVICE(&s->ftgmac100[i]), errp)) {
 423            return;
 424        }
 425        aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
 426                        sc->memmap[ASPEED_DEV_ETH1 + i]);
 427        sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
 428                           aspeed_soc_get_irq(s, ASPEED_DEV_ETH1 + i));
 429    }
 430
 431    /* XDMA */
 432    if (!sysbus_realize(SYS_BUS_DEVICE(&s->xdma), errp)) {
 433        return;
 434    }
 435    aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->xdma), 0,
 436                    sc->memmap[ASPEED_DEV_XDMA]);
 437    sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0,
 438                       aspeed_soc_get_irq(s, ASPEED_DEV_XDMA));
 439
 440    /* GPIO */
 441    if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
 442        return;
 443    }
 444    aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->gpio), 0,
 445                    sc->memmap[ASPEED_DEV_GPIO]);
 446    sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0,
 447                       aspeed_soc_get_irq(s, ASPEED_DEV_GPIO));
 448
 449    /* SDHCI */
 450    if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdhci), errp)) {
 451        return;
 452    }
 453    aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->sdhci), 0,
 454                    sc->memmap[ASPEED_DEV_SDHCI]);
 455    sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0,
 456                       aspeed_soc_get_irq(s, ASPEED_DEV_SDHCI));
 457
 458    /* LPC */
 459    if (!sysbus_realize(SYS_BUS_DEVICE(&s->lpc), errp)) {
 460        return;
 461    }
 462    aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->lpc), 0, sc->memmap[ASPEED_DEV_LPC]);
 463
 464    /* Connect the LPC IRQ to the VIC */
 465    sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 0,
 466                       aspeed_soc_get_irq(s, ASPEED_DEV_LPC));
 467
 468    /*
 469     * On the AST2400 and AST2500 the one LPC IRQ is shared between all of the
 470     * subdevices. Connect the LPC subdevice IRQs to the LPC controller IRQ (by
 471     * contrast, on the AST2600, the subdevice IRQs are connected straight to
 472     * the GIC).
 473     *
 474     * LPC subdevice IRQ sources are offset from 1 because the shared IRQ output
 475     * to the VIC is at offset 0.
 476     */
 477    sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_1,
 478                       qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_1));
 479
 480    sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_2,
 481                       qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_2));
 482
 483    sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_3,
 484                       qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_3));
 485
 486    sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_4,
 487                       qdev_get_gpio_in(DEVICE(&s->lpc), aspeed_lpc_kcs_4));
 488
 489    /* HACE */
 490    object_property_set_link(OBJECT(&s->hace), "dram", OBJECT(s->dram_mr),
 491                             &error_abort);
 492    if (!sysbus_realize(SYS_BUS_DEVICE(&s->hace), errp)) {
 493        return;
 494    }
 495    aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->hace), 0,
 496                    sc->memmap[ASPEED_DEV_HACE]);
 497    sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0,
 498                       aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
 499}
 500static Property aspeed_soc_properties[] = {
 501    DEFINE_PROP_LINK("memory", AspeedSoCState, memory, TYPE_MEMORY_REGION,
 502                     MemoryRegion *),
 503    DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
 504                     MemoryRegion *),
 505    DEFINE_PROP_END_OF_LIST(),
 506};
 507
 508static void aspeed_soc_class_init(ObjectClass *oc, void *data)
 509{
 510    DeviceClass *dc = DEVICE_CLASS(oc);
 511
 512    dc->realize = aspeed_soc_realize;
 513    /* Reason: Uses serial_hds and nd_table in realize() directly */
 514    dc->user_creatable = false;
 515    device_class_set_props(dc, aspeed_soc_properties);
 516}
 517
 518static const TypeInfo aspeed_soc_type_info = {
 519    .name           = TYPE_ASPEED_SOC,
 520    .parent         = TYPE_DEVICE,
 521    .instance_size  = sizeof(AspeedSoCState),
 522    .class_size     = sizeof(AspeedSoCClass),
 523    .class_init     = aspeed_soc_class_init,
 524    .abstract       = true,
 525};
 526
 527static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data)
 528{
 529    AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc);
 530
 531    sc->name         = "ast2400-a1";
 532    sc->cpu_type     = ARM_CPU_TYPE_NAME("arm926");
 533    sc->silicon_rev  = AST2400_A1_SILICON_REV;
 534    sc->sram_size    = 0x8000;
 535    sc->spis_num     = 1;
 536    sc->ehcis_num    = 1;
 537    sc->wdts_num     = 2;
 538    sc->macs_num     = 2;
 539    sc->uarts_num    = 5;
 540    sc->irqmap       = aspeed_soc_ast2400_irqmap;
 541    sc->memmap       = aspeed_soc_ast2400_memmap;
 542    sc->num_cpus     = 1;
 543    sc->get_irq      = aspeed_soc_ast2400_get_irq;
 544}
 545
 546static const TypeInfo aspeed_soc_ast2400_type_info = {
 547    .name           = "ast2400-a1",
 548    .parent         = TYPE_ASPEED_SOC,
 549    .instance_init  = aspeed_soc_init,
 550    .instance_size  = sizeof(AspeedSoCState),
 551    .class_init     = aspeed_soc_ast2400_class_init,
 552};
 553
 554static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data)
 555{
 556    AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc);
 557
 558    sc->name         = "ast2500-a1";
 559    sc->cpu_type     = ARM_CPU_TYPE_NAME("arm1176");
 560    sc->silicon_rev  = AST2500_A1_SILICON_REV;
 561    sc->sram_size    = 0x9000;
 562    sc->spis_num     = 2;
 563    sc->ehcis_num    = 2;
 564    sc->wdts_num     = 3;
 565    sc->macs_num     = 2;
 566    sc->uarts_num    = 5;
 567    sc->irqmap       = aspeed_soc_ast2500_irqmap;
 568    sc->memmap       = aspeed_soc_ast2500_memmap;
 569    sc->num_cpus     = 1;
 570    sc->get_irq      = aspeed_soc_ast2400_get_irq;
 571}
 572
 573static const TypeInfo aspeed_soc_ast2500_type_info = {
 574    .name           = "ast2500-a1",
 575    .parent         = TYPE_ASPEED_SOC,
 576    .instance_init  = aspeed_soc_init,
 577    .instance_size  = sizeof(AspeedSoCState),
 578    .class_init     = aspeed_soc_ast2500_class_init,
 579};
 580static void aspeed_soc_register_types(void)
 581{
 582    type_register_static(&aspeed_soc_type_info);
 583    type_register_static(&aspeed_soc_ast2400_type_info);
 584    type_register_static(&aspeed_soc_ast2500_type_info);
 585};
 586
 587type_init(aspeed_soc_register_types);
 588
 589qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev)
 590{
 591    return ASPEED_SOC_GET_CLASS(s)->get_irq(s, dev);
 592}
 593
 594bool aspeed_soc_uart_realize(AspeedSoCState *s, Error **errp)
 595{
 596    AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
 597    SerialMM *smm;
 598
 599    for (int i = 0, uart = ASPEED_DEV_UART1; i < sc->uarts_num; i++, uart++) {
 600        smm = &s->uart[i];
 601
 602        /* Chardev property is set by the machine. */
 603        qdev_prop_set_uint8(DEVICE(smm), "regshift", 2);
 604        qdev_prop_set_uint32(DEVICE(smm), "baudbase", 38400);
 605        qdev_set_legacy_instance_id(DEVICE(smm), sc->memmap[uart], 2);
 606        qdev_prop_set_uint8(DEVICE(smm), "endianness", DEVICE_LITTLE_ENDIAN);
 607        if (!sysbus_realize(SYS_BUS_DEVICE(smm), errp)) {
 608            return false;
 609        }
 610
 611        sysbus_connect_irq(SYS_BUS_DEVICE(smm), 0, aspeed_soc_get_irq(s, uart));
 612        aspeed_mmio_map(s, SYS_BUS_DEVICE(smm), 0, sc->memmap[uart]);
 613    }
 614
 615    return true;
 616}
 617
 618void aspeed_soc_uart_set_chr(AspeedSoCState *s, int dev, Chardev *chr)
 619{
 620    AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
 621    int i = dev - ASPEED_DEV_UART1;
 622
 623    g_assert(0 <= i && i < ARRAY_SIZE(s->uart) && i < sc->uarts_num);
 624    qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", chr);
 625}
 626
 627/*
 628 * SDMC should be realized first to get correct RAM size and max size
 629 * values
 630 */
 631bool aspeed_soc_dram_init(AspeedSoCState *s, Error **errp)
 632{
 633    AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
 634    ram_addr_t ram_size, max_ram_size;
 635
 636    ram_size = object_property_get_uint(OBJECT(&s->sdmc), "ram-size",
 637                                        &error_abort);
 638    max_ram_size = object_property_get_uint(OBJECT(&s->sdmc), "max-ram-size",
 639                                            &error_abort);
 640
 641    memory_region_init(&s->dram_container, OBJECT(s), "ram-container",
 642                       max_ram_size);
 643    memory_region_add_subregion(&s->dram_container, 0, s->dram_mr);
 644
 645    /*
 646     * Add a memory region beyond the RAM region to let firmwares scan
 647     * the address space with load/store and guess how much RAM the
 648     * SoC has.
 649     */
 650    if (ram_size < max_ram_size) {
 651        DeviceState *dev = qdev_new(TYPE_UNIMPLEMENTED_DEVICE);
 652
 653        qdev_prop_set_string(dev, "name", "ram-empty");
 654        qdev_prop_set_uint64(dev, "size", max_ram_size  - ram_size);
 655        if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp)) {
 656            return false;
 657        }
 658
 659        memory_region_add_subregion_overlap(&s->dram_container, ram_size,
 660                      sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0), -1000);
 661    }
 662
 663    memory_region_add_subregion(s->memory,
 664                      sc->memmap[ASPEED_DEV_SDRAM], &s->dram_container);
 665    return true;
 666}
 667
 668void aspeed_mmio_map(AspeedSoCState *s, SysBusDevice *dev, int n, hwaddr addr)
 669{
 670    memory_region_add_subregion(s->memory, addr,
 671                                sysbus_mmio_get_region(dev, n));
 672}
 673
 674void aspeed_mmio_map_unimplemented(AspeedSoCState *s, SysBusDevice *dev,
 675                                   const char *name, hwaddr addr, uint64_t size)
 676{
 677    qdev_prop_set_string(DEVICE(dev), "name", name);
 678    qdev_prop_set_uint64(DEVICE(dev), "size", size);
 679    sysbus_realize(dev, &error_abort);
 680
 681    memory_region_add_subregion_overlap(s->memory, addr,
 682                                        sysbus_mmio_get_region(dev, 0), -1000);
 683}
 684