Initial definitions for a simple machine using an AST2600 SoC (Cortex
CPU).

Differences with the AST2400 and the AST2500 SoCs are handled using
the ASPEED_IS_AST2600() macro. This is not optimal but it is not too
invasive either. We could modify the model to add custom instance_init
and realize handlers in the future.

Signed-off-by: Cédric Le Goater <c...@kaod.org>
---
 include/hw/arm/aspeed_soc.h  |   4 +
 include/hw/misc/aspeed_scu.h |   1 +
 hw/arm/aspeed.c              |  18 ++++
 hw/arm/aspeed_soc.c          | 189 ++++++++++++++++++++++++++++++++---
 4 files changed, 197 insertions(+), 15 deletions(-)

diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index b427f2668a8a..74db48374531 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -12,6 +12,7 @@
 #ifndef ASPEED_SOC_H
 #define ASPEED_SOC_H
 
+#include "hw/cpu/a15mpcore.h"
 #include "hw/intc/aspeed_vic.h"
 #include "hw/misc/aspeed_scu.h"
 #include "hw/misc/aspeed_sdmc.h"
@@ -38,6 +39,7 @@ typedef struct AspeedSoCState {
     /*< public >*/
     ARMCPU cpu[ASPEED_CPUS_NUM];
     uint32_t num_cpus;
+    A15MPPrivState     a7mpcore;
     MemoryRegion sram;
     AspeedVICState vic;
     AspeedRtcState rtc;
@@ -51,6 +53,7 @@ typedef struct AspeedSoCState {
     AspeedWDTState wdt[ASPEED_WDTS_NUM];
     FTGMAC100State ftgmac100[ASPEED_MACS_NUM];
     AspeedGPIOState gpio;
+    AspeedGPIOState gpio_1_8v;
     AspeedSDHCIState sdhci;
 } AspeedSoCState;
 
@@ -97,6 +100,7 @@ enum {
     ASPEED_SRAM,
     ASPEED_SDHCI,
     ASPEED_GPIO,
+    ASPEED_GPIO_1_8V,
     ASPEED_RTC,
     ASPEED_TIMER1,
     ASPEED_TIMER2,
diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
index 1d7f7ffc1598..670804e85f28 100644
--- a/include/hw/misc/aspeed_scu.h
+++ b/include/hw/misc/aspeed_scu.h
@@ -43,6 +43,7 @@ typedef struct AspeedSCUState {
 #define AST2600_A0_SILICON_REV   0x05000303U
 
 #define ASPEED_IS_AST2500(si_rev)     ((((si_rev) >> 24) & 0xff) == 0x04)
+#define ASPEED_IS_AST2600(si_rev)     ((((si_rev) >> 24) & 0xff) == 0x05)
 
 extern bool is_supported_silicon_rev(uint32_t silicon_rev);
 
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 03cc0952e8f3..f4f1dd29b011 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -88,6 +88,9 @@ struct AspeedBoardState {
 /* Witherspoon hardware value: 0xF10AD216 (but use romulus definition) */
 #define WITHERSPOON_BMC_HW_STRAP1 ROMULUS_BMC_HW_STRAP1
 
+/* AST2600 evb hardware value: (QEMU prototype) */
+#define AST2600_EVB_HW_STRAP1 AST2500_EVB_HW_STRAP1
+
 /*
  * The max ram region is for firmwares that scan the address space
  * with load/store to guess how much RAM the SoC has.
@@ -294,6 +297,12 @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
     i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "ds1338", 
0x32);
 }
 
+static void ast2600_evb_i2c_init(AspeedBoardState *bmc)
+{
+    /* Start with some devices on our I2C busses */
+    ast2500_evb_i2c_init(bmc);
+}
+
 static void romulus_bmc_i2c_init(AspeedBoardState *bmc)
 {
     AspeedSoCState *soc = &bmc->soc;
@@ -441,6 +450,15 @@ static const AspeedBoardConfig aspeed_boards[] = {
         .num_cs    = 2,
         .i2c_init  = witherspoon_bmc_i2c_init,
         .ram       = 512 * MiB,
+    }, {
+        .name      = MACHINE_TYPE_NAME("ast2600-evb"),
+        .desc      = "Aspeed AST2600 EVB (Cortex A7)",
+        .soc_name  = "ast2600-a0",
+        .hw_strap1 = AST2600_EVB_HW_STRAP1,
+        .fmc_model = "mx25l25635e",
+        .spi_model = "mx25l25635e",
+        .num_cs    = 1,
+        .i2c_init  = ast2600_evb_i2c_init,
     },
 };
 
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 5c5fcb810944..80d7f206004c 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -81,6 +81,38 @@ static const hwaddr aspeed_soc_ast2500_memmap[] = {
     [ASPEED_SDRAM]  = 0x80000000,
 };
 
+static const hwaddr aspeed_soc_ast2600_memmap[] = {
+    [ASPEED_SRAM]      = 0x10000000,
+    /* 0x16000000     0x17FFFFFF : AHB BUS do LPC Bus bridge */
+    [ASPEED_IOMEM]     = 0x1E600000,
+    [ASPEED_PWM]       = 0x1E610000,
+    [ASPEED_FMC]       = 0x1E620000,
+    [ASPEED_SPI1]      = 0x1E630000,
+    [ASPEED_SPI2]      = 0x1E641000,
+    [ASPEED_ETH1]      = 0x1E660000,
+    [ASPEED_ETH2]      = 0x1E680000,
+    [ASPEED_VIC]       = 0x1E6C0000,
+    [ASPEED_SDMC]      = 0x1E6E0000,
+    [ASPEED_SCU]       = 0x1E6E2000,
+    [ASPEED_XDMA]      = 0x1E6E7000,
+    [ASPEED_ADC]       = 0x1E6E9000,
+    [ASPEED_SDHCI]     = 0x1E740000,
+    [ASPEED_GPIO]      = 0x1E780000,
+    [ASPEED_GPIO_1_8V] = 0x1E780800,
+    [ASPEED_RTC]       = 0x1E781000,
+    [ASPEED_TIMER1]    = 0x1E782000,
+    [ASPEED_WDT]       = 0x1E785000,
+    [ASPEED_LPC]       = 0x1E789000,
+    [ASPEED_IBT]       = 0x1E789140,
+    [ASPEED_I2C]       = 0x1E78A000,
+    [ASPEED_UART1]     = 0x1E783000,
+    [ASPEED_UART5]     = 0x1E784000,
+    [ASPEED_VUART]     = 0x1E787000,
+    [ASPEED_SDRAM]     = 0x80000000,
+};
+
+#define ASPEED_A7MPCORE_ADDR 0x40460000
+
 static const int aspeed_soc_ast2400_irqmap[] = {
     [ASPEED_UART1]  = 9,
     [ASPEED_UART2]  = 32,
@@ -115,6 +147,41 @@ static const int aspeed_soc_ast2400_irqmap[] = {
 
 #define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
 
+#define ASPEED_SOC_AST2600_MAX_IRQ 128
+
+static const int aspeed_soc_ast2600_irqmap[] = {
+    [ASPEED_UART1]     = 47,
+    [ASPEED_UART2]     = 48,
+    [ASPEED_UART3]     = 49,
+    [ASPEED_UART4]     = 50,
+    [ASPEED_UART5]     = 8,
+    [ASPEED_VUART]     = 8,
+    [ASPEED_FMC]       = 39,
+    [ASPEED_SDMC]      = 0,
+    [ASPEED_SCU]       = 12,
+    [ASPEED_XDMA]      = 6,
+    [ASPEED_ADC]       = 46,
+    [ASPEED_SDHCI]     = 43,
+    [ASPEED_GPIO]      = 40,
+    [ASPEED_GPIO_1_8V] = 11,
+    [ASPEED_RTC]       = 13,
+    [ASPEED_TIMER1]    = 16,
+    [ASPEED_TIMER2]    = 17,
+    [ASPEED_TIMER3]    = 18,
+    [ASPEED_TIMER4]    = 19,
+    [ASPEED_TIMER5]    = 20,
+    [ASPEED_TIMER6]    = 21,
+    [ASPEED_TIMER7]    = 22,
+    [ASPEED_TIMER8]    = 23,
+    [ASPEED_WDT]       = 24,
+    [ASPEED_PWM]       = 44,
+    [ASPEED_LPC]       = 35,
+    [ASPEED_IBT]       = 35,    /* LPC */
+    [ASPEED_I2C]       = 110,   /* 110 -> 125 */
+    [ASPEED_ETH1]      = 2,
+    [ASPEED_ETH2]      = 3,
+};
+
 static const AspeedSoCInfo aspeed_socs[] = {
     {
         .name         = "ast2400-a1",
@@ -136,14 +203,26 @@ static const AspeedSoCInfo aspeed_socs[] = {
         .irqmap       = aspeed_soc_ast2500_irqmap,
         .memmap       = aspeed_soc_ast2500_memmap,
         .num_cpus     = 1,
+    }, {
+        .name         = "ast2600-a0",
+        .cpu_type     = ARM_CPU_TYPE_NAME("cortex-a7"),
+        .silicon_rev  = AST2600_A0_SILICON_REV,
+        .sram_size    = 0x10000,
+        .spis_num     = 2,
+        .wdts_num     = 4,
+        .irqmap       = aspeed_soc_ast2600_irqmap,
+        .memmap       = aspeed_soc_ast2600_memmap,
+        .num_cpus     = 2,
     },
 };
 
 static qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int ctrl)
 {
     AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+    DeviceState *intc = ASPEED_IS_AST2600(sc->info->silicon_rev) ?
+        DEVICE(&s->a7mpcore) : DEVICE(&s->vic);
 
-    return qdev_get_gpio_in(DEVICE(&s->vic), sc->info->irqmap[ctrl]);
+    return qdev_get_gpio_in(intc, sc->info->irqmap[ctrl]);
 }
 
 static void aspeed_soc_init(Object *obj)
@@ -176,8 +255,13 @@ static void aspeed_soc_init(Object *obj)
     object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu),
                               "hw-prot-key", &error_abort);
 
-    sysbus_init_child_obj(obj, "vic", OBJECT(&s->vic), sizeof(s->vic),
-                          TYPE_ASPEED_VIC);
+    if (ASPEED_IS_AST2600(sc->info->silicon_rev)) {
+        sysbus_init_child_obj(obj, "a7mpcore", &s->a7mpcore,
+                              sizeof(s->a7mpcore), TYPE_A15MPCORE_PRIV);
+    } else {
+        sysbus_init_child_obj(obj, "vic", OBJECT(&s->vic), sizeof(s->vic),
+                              TYPE_ASPEED_VIC);
+    }
 
     sysbus_init_child_obj(obj, "rtc", OBJECT(&s->rtc), sizeof(s->rtc),
                           TYPE_ASPEED_RTC);
@@ -233,6 +317,12 @@ static void aspeed_soc_init(Object *obj)
     sysbus_init_child_obj(obj, "gpio", OBJECT(&s->gpio), sizeof(s->gpio),
                           typename);
 
+    if (ASPEED_IS_AST2600(sc->info->silicon_rev)) {
+        snprintf(typename, sizeof(typename), "aspeed.gpio-%s-1_8v", socname);
+        sysbus_init_child_obj(obj, "gpio_1_8v", OBJECT(&s->gpio_1_8v),
+                              sizeof(s->gpio_1_8v), typename);
+    }
+
     sysbus_init_child_obj(obj, "sdc", OBJECT(&s->sdhci), sizeof(s->sdhci),
                           TYPE_ASPEED_SDHCI);
 
@@ -243,6 +333,16 @@ static void aspeed_soc_init(Object *obj)
     }
 }
 
+/*
+ * ASPEED ast2600 has 0xf as cluster ID
+ *
+ * 
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0388e/CIHEBGFG.html
+ */
+static uint64_t aspeed_calc_affinity(int cpu)
+{
+    return (0xf << ARM_AFF1_SHIFT) | cpu;
+}
+
 static void aspeed_soc_realize(DeviceState *dev, Error **errp)
 {
     int i;
@@ -262,6 +362,23 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
 
     /* CPU */
     for (i = 0; i < s->num_cpus; i++) {
+        if (ASPEED_IS_AST2600(sc->info->silicon_rev)) {
+            object_property_set_int(OBJECT(&s->cpu[i]), QEMU_PSCI_CONDUIT_SMC,
+                                    "psci-conduit", &error_abort);
+            if (s->num_cpus > 1) {
+                object_property_set_int(OBJECT(&s->cpu[i]),
+                                        ASPEED_A7MPCORE_ADDR,
+                                        "reset-cbar", &error_abort);
+            }
+            object_property_set_int(OBJECT(&s->cpu[i]), 
aspeed_calc_affinity(i),
+                                    "mp-affinity", &error_abort);
+
+            /*
+             * TODO: the secondary CPUs are started and a boot helper
+             * is needed when using -kernel
+             */
+        }
+
         object_property_set_bool(OBJECT(&s->cpu[i]), true, "realized", &err);
         if (err) {
             error_propagate(errp, err);
@@ -269,6 +386,48 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
         }
     }
 
+    /* A7MPCORE */
+    if (ASPEED_IS_AST2600(sc->info->silicon_rev)) {
+        qemu_irq irq;
+
+        object_property_set_int(OBJECT(&s->a7mpcore), s->num_cpus, "num-cpu",
+                                &error_abort);
+        object_property_set_int(OBJECT(&s->a7mpcore),
+                                ASPEED_SOC_AST2600_MAX_IRQ + GIC_INTERNAL,
+                                "num-irq", &error_abort);
+
+        object_property_set_bool(OBJECT(&s->a7mpcore), true, "realized",
+                                 &error_abort);
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, ASPEED_A7MPCORE_ADDR);
+
+        for (i = 0; i < s->num_cpus; i++) {
+            SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore);
+            DeviceState  *d   = DEVICE(qemu_get_cpu(i));
+
+            irq = qdev_get_gpio_in(d, ARM_CPU_IRQ);
+            sysbus_connect_irq(sbd, i, irq);
+            irq = qdev_get_gpio_in(d, ARM_CPU_FIQ);
+            sysbus_connect_irq(sbd, i + s->num_cpus, irq);
+            irq = qdev_get_gpio_in(d, ARM_CPU_VIRQ);
+            sysbus_connect_irq(sbd, i + 2 * s->num_cpus, irq);
+            irq = qdev_get_gpio_in(d, ARM_CPU_VFIQ);
+            sysbus_connect_irq(sbd, i + 3 * s->num_cpus, irq);
+        }
+    } else {
+        /* VIC */
+        object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0,
+                        sc->info->memmap[ASPEED_VIC]);
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
+                           qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
+                           qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
+    }
+
     /* SRAM */
     memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram",
                            sc->info->sram_size, &err);
@@ -287,18 +446,6 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
     }
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, sc->info->memmap[ASPEED_SCU]);
 
-    /* VIC */
-    object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
-    if (err) {
-        error_propagate(errp, err);
-        return;
-    }
-    sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, sc->info->memmap[ASPEED_VIC]);
-    sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
-                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ));
-    sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
-                       qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ));
-
     /* RTC */
     object_property_set_bool(OBJECT(&s->rtc), true, "realized", &err);
     if (err) {
@@ -433,6 +580,18 @@ static void aspeed_soc_realize(DeviceState *dev, Error 
**errp)
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0,
                        aspeed_soc_get_irq(s, ASPEED_GPIO));
 
+    if (ASPEED_IS_AST2600(sc->info->silicon_rev)) {
+        object_property_set_bool(OBJECT(&s->gpio_1_8v), true, "realized", 
&err);
+        if (err) {
+            error_propagate(errp, err);
+            return;
+        }
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio_1_8v), 0,
+                        sc->info->memmap[ASPEED_GPIO_1_8V]);
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio_1_8v), 0,
+                           aspeed_soc_get_irq(s, ASPEED_GPIO_1_8V));
+    }
+
     /* SDHCI */
     object_property_set_bool(OBJECT(&s->sdhci), true, "realized", &err);
     if (err) {
-- 
2.21.0


Reply via email to