aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2025-05-05 11:26:52 -0400
committerStefan Hajnoczi <stefanha@redhat.com>2025-05-05 11:26:52 -0400
commit6d0d9add0d98effc7045466249921a09845225ac (patch)
tree96f8e6d63c15e0cb039d2b82237dadef414e0032
parentdc1ed8f256c446cbf33e090f0e214d0311a771a7 (diff)
parentf32ef57f7de98ec36da52b0a13bd5d18ac4bd583 (diff)
downloadqemu-6d0d9add0d98effc7045466249921a09845225ac.zip
qemu-6d0d9add0d98effc7045466249921a09845225ac.tar.gz
qemu-6d0d9add0d98effc7045466249921a09845225ac.tar.bz2
Merge tag 'pull-aspeed-20250505' of https://github.com/legoater/qemu into staging
aspeed queue: * Fixed AST2700 SPI model issues * Updated SDK images * Added FW support to the AST2700 EVB machines * Introduced an AST27x0 multi-SoC machine # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmgYf0sACgkQUaNDx8/7 # 7KGYGxAAokBF+jSjl7DgDbpkKu0RhJeV02rUPXIDehyBW+NcjL3xcG8f36wraZ4+ # SYGESnWCymKlQi9ZYdqIQ86w4WSNDQ1s1pjefcvqEFBTCny1TRwNgocBQkdBcNhb # 1iIBpOu5c8j6i83U73W46OXwPBopXI2OzcxvX0lclOze3+qzHT6CDYgezXoNlJtG # RSJjeFO9sEghPgXzkBMrCotV4n7pDGeSpB9nSFfkzRekEbq3rzT6s6JxS1pylzut # g6YU6YqFl+RrR/5HRo5hIFE+YmqDvTpYnd8k5sJq9CxYSIXMkJImxssvg2oO5aoF # BVv/XxWVJ/oDEorXg5qNaRHzVk3StEX42boDQgj+dWsp1Q/4jdokrgFu7KSUT22q # mp4Px+Z5xlX5z6TNwp6yvb9Wobr23KjgXRqqqqLEftYrqaI6Nr/vcKjZZ438GzCd # SpKXxIAlXci1bAaDUTdfQnJyKe+ltJ7wOX1auQFqpI0CYe5Jcu3En6M799ne9azy # TvfMq0GN1oGNJoYRRmH51gNF0vlnDsDhDHod6i6ZmBFWGnMOtbti3nnEaAdk7JWB # pueux79YdE+f1q7SuA2X2OEchFxE/kA0B6SxP+IwXEcDyGNfZ6UJWoZGB9amc090 # pTQB1HHOGDEkYsReely1isTDCoZBqzDUreEhPssO0E9Pb/ZfeCE= # =vBwk # -----END PGP SIGNATURE----- # gpg: Signature made Mon 05 May 2025 05:05:15 EDT # gpg: using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1 # gpg: Good signature from "Cédric Le Goater <clg@redhat.com>" [full] # gpg: aka "Cédric Le Goater <clg@kaod.org>" [full] # Primary key fingerprint: A0F6 6548 F048 95EB FE6B 0B60 51A3 43C7 CFFB ECA1 * tag 'pull-aspeed-20250505' of https://github.com/legoater/qemu: (24 commits) docs: Add support for ast2700fc machine tests/function/aspeed: Add functional test for ast2700fc hw/arm: Introduce ASPEED AST2700 A1 full core machine hw/arm/aspeed_ast27x0-tsp: Introduce AST27x0 A1 TSP SoC hw/arm/aspeed_ast27x0-ssp: Introduce AST27x0 A1 SSP SoC hw/intc/aspeed: Add support for AST2700 TSP INTC hw/intc/aspeed: Add support for AST2700 SSP INTC aspeed: ast27x0: Correct hex notation for device addresses aspeed: ast27x0: Map unimplemented devices in SoC memory docs/system/arm/aspeed: Support vbootrom for AST2700 docs/system/arm/aspeed: move AST2700 content to new section tests/functional/aspeed: Add to test vbootrom for AST2700 hw/arm/aspeed: Add support for loading vbootrom image via "-bios" hw/arm/aspeed_ast27x0 Introduce vbootrom memory region tests/functional/aspeed: extract boot and login sequence into helper function tests/functional/aspeed: Update test ASPEED SDK v09.06 tests/functional/aspeed: Move I2C test into shared helper for AST2700 reuse hw/arm/aspeed_ast27x0: Rename variable sram_name to name in ast2700 realize tests/functional/aspeed: Update test ASPEED SDK v03.00 for AST1030 tests/functional/aspeed: Update test ASPEED SDK v09.06 for AST2600 ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r--MAINTAINERS1
-rw-r--r--docs/system/arm/aspeed.rst164
-rw-r--r--hw/arm/aspeed.c36
-rw-r--r--hw/arm/aspeed_ast27x0-fc.c192
-rw-r--r--hw/arm/aspeed_ast27x0-ssp.c294
-rw-r--r--hw/arm/aspeed_ast27x0-tsp.c294
-rw-r--r--hw/arm/aspeed_ast27x0.c125
-rw-r--r--hw/arm/meson.build6
-rw-r--r--hw/intc/aspeed_intc.c416
-rw-r--r--hw/ssi/aspeed_smc.c4
-rw-r--r--include/hw/arm/aspeed.h1
-rw-r--r--include/hw/arm/aspeed_soc.h38
-rw-r--r--include/hw/intc/aspeed_intc.h5
-rw-r--r--pc-bios/README6
-rw-r--r--pc-bios/ast27x0_bootrom.binbin0 -> 15552 bytes
-rw-r--r--pc-bios/meson.build1
-rw-r--r--tests/functional/meson.build6
-rwxr-xr-xtests/functional/test_aarch64_aspeed_ast2700.py (renamed from tests/functional/test_aarch64_aspeed.py)82
-rwxr-xr-xtests/functional/test_aarch64_aspeed_ast2700fc.py135
-rwxr-xr-xtests/functional/test_arm_aspeed_ast1030.py10
-rwxr-xr-xtests/functional/test_arm_aspeed_ast2500.py8
-rwxr-xr-xtests/functional/test_arm_aspeed_ast2600.py15
22 files changed, 1757 insertions, 82 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 8cd9626..e748b63 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1174,6 +1174,7 @@ F: docs/system/arm/fby35.rst
F: tests/*/*aspeed*
F: tests/*/*ast2700*
F: hw/arm/fby35.c
+F: pc-bios/ast27x0_bootrom.bin
NRF51
M: Joel Stanley <joel@jms.id.au>
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
index 97fd6a0..58a8020 100644
--- a/docs/system/arm/aspeed.rst
+++ b/docs/system/arm/aspeed.rst
@@ -1,12 +1,11 @@
-Aspeed family boards (``ast2500-evb``, ``ast2600-evb``, ``ast2700-evb``, ``bletchley-bmc``, ``fuji-bmc``, ``fby35-bmc``, ``fp5280g2-bmc``, ``g220a-bmc``, ``palmetto-bmc``, ``qcom-dc-scm-v1-bmc``, ``qcom-firework-bmc``, ``quanta-q71l-bmc``, ``rainier-bmc``, ``romulus-bmc``, ``sonorapass-bmc``, ``supermicrox11-bmc``, ``supermicrox11spi-bmc``, ``tiogapass-bmc``, ``witherspoon-bmc``, ``yosemitev2-bmc``)
-==================================================================================================================================================================================================================================================================================================================================================================================================================
+Aspeed family boards (``ast2500-evb``, ``ast2600-evb``, ``ast2700-evb``, ``ast2700fc``, ``bletchley-bmc``, ``fuji-bmc``, ``fby35-bmc``, ``fp5280g2-bmc``, ``g220a-bmc``, ``palmetto-bmc``, ``qcom-dc-scm-v1-bmc``, ``qcom-firework-bmc``, ``quanta-q71l-bmc``, ``rainier-bmc``, ``romulus-bmc``, ``sonorapass-bmc``, ``supermicrox11-bmc``, ``supermicrox11spi-bmc``, ``tiogapass-bmc``, ``witherspoon-bmc``, ``yosemitev2-bmc``)
+=================================================================================================================================================================================================================================================================================================================================================================================================================================
The QEMU Aspeed machines model BMCs of various OpenPOWER systems and
Aspeed evaluation boards. They are based on different releases of the
Aspeed SoC : the AST2400 integrating an ARM926EJ-S CPU (400MHz), the
AST2500 with an ARM1176JZS CPU (800MHz), the AST2600
-with dual cores ARM Cortex-A7 CPUs (1.2GHz) and more recently the AST2700
-with quad cores ARM Cortex-A35 64 bits CPUs (1.6GHz)
+with dual cores ARM Cortex-A7 CPUs (1.2GHz).
The SoC comes with RAM, Gigabit ethernet, USB, SD/MMC, USB, SPI, I2C,
etc.
@@ -39,10 +38,6 @@ AST2600 SoC based machines :
- ``qcom-dc-scm-v1-bmc`` Qualcomm DC-SCM V1 BMC
- ``qcom-firework-bmc`` Qualcomm Firework BMC
-AST2700 SoC based machines :
-
-- ``ast2700-evb`` Aspeed AST2700 Evaluation board (Cortex-A35)
-
Supported devices
-----------------
@@ -247,10 +242,78 @@ under Linux), use :
-M ast2500-evb,bmc-console=uart3
+Aspeed 2700 family boards (``ast2700-evb``)
+==================================================================
+
+The QEMU Aspeed machines model BMCs of Aspeed evaluation boards.
+They are based on different releases of the Aspeed SoC :
+the AST2700 with quad cores ARM Cortex-A35 64 bits CPUs (1.6GHz).
+
+The SoC comes with RAM, Gigabit ethernet, USB, SD/MMC, USB, SPI, I2C,
+etc.
+
+AST2700 SoC based machines :
+
+- ``ast2700-evb`` Aspeed AST2700 Evaluation board (Cortex-A35)
+- ``ast2700fc`` Aspeed AST2700 Evaluation board (Cortex-A35 + Cortex-M4)
+
+Supported devices
+-----------------
+ * Interrupt Controller
+ * Timer Controller
+ * RTC Controller
+ * I2C Controller
+ * System Control Unit (SCU)
+ * SRAM mapping
+ * X-DMA Controller (basic interface)
+ * Static Memory Controller (SMC or FMC) - Only SPI Flash support
+ * SPI Memory Controller
+ * USB 2.0 Controller
+ * SD/MMC storage controllers
+ * SDRAM controller (dummy interface for basic settings and training)
+ * Watchdog Controller
+ * GPIO Controller (Master only)
+ * UART
+ * Ethernet controllers
+ * Front LEDs (PCA9552 on I2C bus)
+ * LPC Peripheral Controller (a subset of subdevices are supported)
+ * Hash/Crypto Engine (HACE) - Hash support only. TODO: Crypto
+ * ADC
+ * eMMC Boot Controller (dummy)
+ * PECI Controller (minimal)
+ * I3C Controller
+ * Internal Bridge Controller (SLI dummy)
+
+Missing devices
+---------------
+ * PWM and Fan Controller
+ * Slave GPIO Controller
+ * Super I/O Controller
+ * PCI-Express 1 Controller
+ * Graphic Display Controller
+ * MCTP Controller
+ * Mailbox Controller
+ * Virtual UART
+ * eSPI Controller
+
+Boot options
+------------
+
+Images can be downloaded from the ASPEED Forked OpenBMC GitHub release repository :
+
+ https://github.com/AspeedTech-BMC/openbmc/releases
+
Booting the ast2700-evb machine
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Boot the AST2700 machine from the flash image, use an MTD drive :
+Boot the AST2700 machine from the flash image.
+
+There are two supported methods for booting the AST2700 machine with a flash image:
+
+Manual boot using ``-device loader``:
+
+It causes all 4 CPU cores to start execution from address ``0x430000000``, which
+corresponds to the BL31 image load address.
.. code-block:: bash
@@ -270,6 +333,89 @@ Boot the AST2700 machine from the flash image, use an MTD drive :
-drive file=${IMGDIR}/image-bmc,format=raw,if=mtd \
-nographic
+Boot using a virtual boot ROM (``-bios``):
+
+If users do not specify the ``-bios option``, QEMU will attempt to load the
+default vbootrom image ``ast27x0_bootrom.bin`` from either the current working
+directory or the ``pc-bios`` directory within the QEMU source tree.
+
+.. code-block:: bash
+
+ $ qemu-system-aarch64 -M ast2700-evb \
+ -drive file=image-bmc,format=raw,if=mtd \
+ -nographic
+
+The ``-bios`` option allows users to specify a custom path for the vbootrom
+image to be loaded during boot. This will load the vbootrom image from the
+specified path in the ${HOME} directory.
+
+.. code-block:: bash
+
+ -bios ${HOME}/ast27x0_bootrom.bin
+
+Booting the ast2700fc machine
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+AST2700 features four Cortex-A35 primary processors and two Cortex-M4 coprocessors.
+**ast2700-evb** machine focuses on emulating the four Cortex-A35 primary processors,
+**ast2700fc** machine extends **ast2700-evb** by adding support for the two Cortex-M4 coprocessors.
+
+Steps to boot the AST2700fc machine:
+
+1. Ensure you have the following AST2700A1 binaries available in a directory
+
+ * u-boot-nodtb.bin
+ * u-boot.dtb
+ * bl31.bin
+ * optee/tee-raw.bin
+ * image-bmc
+ * zephyr-aspeed-ssp.elf (for SSP firmware, CPU 5)
+ * zephyr-aspeed-tsp.elf (for TSP firmware, CPU 6)
+
+2. Execute the following command to start ``ast2700fc`` machine:
+
+.. code-block:: bash
+
+ IMGDIR=ast2700-default
+ UBOOT_SIZE=$(stat --format=%s -L ${IMGDIR}/u-boot-nodtb.bin)
+
+ $ qemu-system-aarch64 -M ast2700fc \
+ -device loader,force-raw=on,addr=0x400000000,file=${IMGDIR}/u-boot-nodtb.bin \
+ -device loader,force-raw=on,addr=$((0x400000000 + ${UBOOT_SIZE})),file=${IMGDIR}/u-boot.dtb \
+ -device loader,force-raw=on,addr=0x430000000,file=${IMGDIR}/bl31.bin \
+ -device loader,force-raw=on,addr=0x430080000,file=${IMGDIR}/optee/tee-raw.bin \
+ -device loader,cpu-num=0,addr=0x430000000 \
+ -device loader,cpu-num=1,addr=0x430000000 \
+ -device loader,cpu-num=2,addr=0x430000000 \
+ -device loader,cpu-num=3,addr=0x430000000 \
+ -drive file=${IMGDIR}/image-bmc,if=mtd,format=raw \
+ -device loader,file=${IMGDIR}/zephyr-aspeed-ssp.elf,cpu-num=4 \
+ -device loader,file=${IMGDIR}/zephyr-aspeed-tsp.elf,cpu-num=5 \
+ -serial pty -serial pty -serial pty \
+ -snapshot \
+ -S -nographic
+
+After launching QEMU, serial devices will be automatically redirected.
+Example output:
+
+.. code-block:: bash
+
+ char device redirected to /dev/pts/55 (label serial0)
+ char device redirected to /dev/pts/56 (label serial1)
+ char device redirected to /dev/pts/57 (label serial2)
+
+- serial0: Console for the four Cortex-A35 primary processors.
+- serial1 and serial2: Consoles for the two Cortex-M4 coprocessors.
+
+Use ``tio`` or another terminal emulator to connect to the consoles:
+
+.. code-block:: bash
+
+ $ tio /dev/pts/55
+ $ tio /dev/pts/56
+ $ tio /dev/pts/57
+
+
Aspeed minibmc family boards (``ast1030-evb``)
==================================================================
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 20f418f..d0b3336 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -27,6 +27,7 @@
#include "system/reset.h"
#include "hw/loader.h"
#include "qemu/error-report.h"
+#include "qemu/datadir.h"
#include "qemu/units.h"
#include "hw/qdev-clock.h"
#include "system/system.h"
@@ -305,6 +306,33 @@ static void aspeed_install_boot_rom(AspeedMachineState *bmc, BlockBackend *blk,
rom_size, &error_abort);
}
+#define VBOOTROM_FILE_NAME "ast27x0_bootrom.bin"
+
+/*
+ * This function locates the vbootrom image file specified via the command line
+ * using the -bios option. It loads the specified image into the vbootrom
+ * memory region and handles errors if the file cannot be found or loaded.
+ */
+static void aspeed_load_vbootrom(AspeedMachineState *bmc, const char *bios_name,
+ Error **errp)
+{
+ g_autofree char *filename = NULL;
+ AspeedSoCState *soc = bmc->soc;
+ int ret;
+
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+ if (!filename) {
+ error_setg(errp, "Could not find vbootrom image '%s'", bios_name);
+ return;
+ }
+
+ ret = load_image_mr(filename, &soc->vbootrom);
+ if (ret < 0) {
+ error_setg(errp, "Failed to load vbootrom image '%s'", bios_name);
+ return;
+ }
+}
+
void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
unsigned int count, int unit0)
{
@@ -380,6 +408,7 @@ static void aspeed_machine_init(MachineState *machine)
AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
AspeedSoCClass *sc;
int i;
+ const char *bios_name = NULL;
DriveInfo *emmc0 = NULL;
bool boot_emmc;
@@ -482,6 +511,11 @@ static void aspeed_machine_init(MachineState *machine)
}
}
+ if (amc->vbootrom) {
+ bios_name = machine->firmware ?: VBOOTROM_FILE_NAME;
+ aspeed_load_vbootrom(bmc, bios_name, &error_abort);
+ }
+
arm_load_kernel(ARM_CPU(first_cpu), machine, &aspeed_board_binfo);
}
@@ -1701,6 +1735,7 @@ static void aspeed_machine_ast2700a0_evb_class_init(ObjectClass *oc,
amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON | ASPEED_MAC2_ON;
amc->uart_default = ASPEED_DEV_UART12;
amc->i2c_init = ast2700_evb_i2c_init;
+ amc->vbootrom = true;
mc->auto_create_sdcard = true;
mc->default_ram_size = 1 * GiB;
aspeed_machine_class_init_cpus_defaults(mc);
@@ -1722,6 +1757,7 @@ static void aspeed_machine_ast2700a1_evb_class_init(ObjectClass *oc,
amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON | ASPEED_MAC2_ON;
amc->uart_default = ASPEED_DEV_UART12;
amc->i2c_init = ast2700_evb_i2c_init;
+ amc->vbootrom = true;
mc->auto_create_sdcard = true;
mc->default_ram_size = 1 * GiB;
aspeed_machine_class_init_cpus_defaults(mc);
diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c
new file mode 100644
index 0000000..125a3ad
--- /dev/null
+++ b/hw/arm/aspeed_ast27x0-fc.c
@@ -0,0 +1,192 @@
+/*
+ * ASPEED SoC 2700 family
+ *
+ * Copyright (C) 2025 ASPEED Technology Inc.
+ *
+ * This code is licensed under the GPL version 2 or later. See
+ * the COPYING file in the top-level directory.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qapi/error.h"
+#include "system/block-backend.h"
+#include "system/system.h"
+#include "hw/arm/aspeed.h"
+#include "hw/boards.h"
+#include "hw/qdev-clock.h"
+#include "hw/arm/aspeed_soc.h"
+#include "hw/loader.h"
+#include "hw/arm/boot.h"
+#include "hw/block/flash.h"
+
+
+#define TYPE_AST2700A1FC MACHINE_TYPE_NAME("ast2700fc")
+OBJECT_DECLARE_SIMPLE_TYPE(Ast2700FCState, AST2700A1FC);
+
+static struct arm_boot_info ast2700fc_board_info = {
+ .board_id = -1, /* device-tree-only board */
+};
+
+struct Ast2700FCState {
+ MachineState parent_obj;
+
+ MemoryRegion ca35_memory;
+ MemoryRegion ca35_dram;
+ MemoryRegion ssp_memory;
+ MemoryRegion tsp_memory;
+
+ Clock *ssp_sysclk;
+ Clock *tsp_sysclk;
+
+ Aspeed27x0SoCState ca35;
+ Aspeed27x0SSPSoCState ssp;
+ Aspeed27x0TSPSoCState tsp;
+
+ bool mmio_exec;
+};
+
+#define AST2700FC_BMC_RAM_SIZE (2 * GiB)
+#define AST2700FC_CM4_DRAM_SIZE (32 * MiB)
+
+#define AST2700FC_HW_STRAP1 0x000000C0
+#define AST2700FC_HW_STRAP2 0x00000003
+#define AST2700FC_FMC_MODEL "w25q01jvq"
+#define AST2700FC_SPI_MODEL "w25q512jv"
+
+static void ast2700fc_ca35_init(MachineState *machine)
+{
+ Ast2700FCState *s = AST2700A1FC(machine);
+ AspeedSoCState *soc;
+ AspeedSoCClass *sc;
+
+ object_initialize_child(OBJECT(s), "ca35", &s->ca35, "ast2700-a1");
+ soc = ASPEED_SOC(&s->ca35);
+ sc = ASPEED_SOC_GET_CLASS(soc);
+
+ memory_region_init(&s->ca35_memory, OBJECT(&s->ca35), "ca35-memory",
+ UINT64_MAX);
+
+ if (!memory_region_init_ram(&s->ca35_dram, OBJECT(&s->ca35), "ca35-dram",
+ AST2700FC_BMC_RAM_SIZE, &error_abort)) {
+ return;
+ }
+ if (!object_property_set_link(OBJECT(&s->ca35), "memory",
+ OBJECT(&s->ca35_memory),
+ &error_abort)) {
+ return;
+ };
+ if (!object_property_set_link(OBJECT(&s->ca35), "dram",
+ OBJECT(&s->ca35_dram), &error_abort)) {
+ return;
+ }
+ if (!object_property_set_int(OBJECT(&s->ca35), "ram-size",
+ AST2700FC_BMC_RAM_SIZE, &error_abort)) {
+ return;
+ }
+ if (!object_property_set_int(OBJECT(&s->ca35), "hw-strap1",
+ AST2700FC_HW_STRAP1, &error_abort)) {
+ return;
+ }
+ if (!object_property_set_int(OBJECT(&s->ca35), "hw-strap2",
+ AST2700FC_HW_STRAP2, &error_abort)) {
+ return;
+ }
+ aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART12, serial_hd(0));
+ if (!qdev_realize(DEVICE(&s->ca35), NULL, &error_abort)) {
+ return;
+ }
+
+ /*
+ * AST2700 EVB has a LM75 temperature sensor on I2C bus 0 at address 0x4d.
+ */
+ i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 0), "tmp105", 0x4d);
+
+ aspeed_board_init_flashes(&soc->fmc, AST2700FC_FMC_MODEL, 2, 0);
+ aspeed_board_init_flashes(&soc->spi[0], AST2700FC_SPI_MODEL, 1, 2);
+
+ ast2700fc_board_info.ram_size = machine->ram_size;
+ ast2700fc_board_info.loader_start = sc->memmap[ASPEED_DEV_SDRAM];
+
+ arm_load_kernel(ARM_CPU(first_cpu), machine, &ast2700fc_board_info);
+}
+
+static void ast2700fc_ssp_init(MachineState *machine)
+{
+ AspeedSoCState *soc;
+ Ast2700FCState *s = AST2700A1FC(machine);
+ s->ssp_sysclk = clock_new(OBJECT(s), "SSP_SYSCLK");
+ clock_set_hz(s->ssp_sysclk, 200000000ULL);
+
+ object_initialize_child(OBJECT(s), "ssp", &s->ssp, TYPE_ASPEED27X0SSP_SOC);
+ memory_region_init(&s->ssp_memory, OBJECT(&s->ssp), "ssp-memory",
+ UINT64_MAX);
+
+ qdev_connect_clock_in(DEVICE(&s->ssp), "sysclk", s->ssp_sysclk);
+ if (!object_property_set_link(OBJECT(&s->ssp), "memory",
+ OBJECT(&s->ssp_memory), &error_abort)) {
+ return;
+ }
+
+ soc = ASPEED_SOC(&s->ssp);
+ aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART4, serial_hd(1));
+ if (!qdev_realize(DEVICE(&s->ssp), NULL, &error_abort)) {
+ return;
+ }
+}
+
+static void ast2700fc_tsp_init(MachineState *machine)
+{
+ AspeedSoCState *soc;
+ Ast2700FCState *s = AST2700A1FC(machine);
+ s->tsp_sysclk = clock_new(OBJECT(s), "TSP_SYSCLK");
+ clock_set_hz(s->tsp_sysclk, 200000000ULL);
+
+ object_initialize_child(OBJECT(s), "tsp", &s->tsp, TYPE_ASPEED27X0TSP_SOC);
+ memory_region_init(&s->tsp_memory, OBJECT(&s->tsp), "tsp-memory",
+ UINT64_MAX);
+
+ qdev_connect_clock_in(DEVICE(&s->tsp), "sysclk", s->tsp_sysclk);
+ if (!object_property_set_link(OBJECT(&s->tsp), "memory",
+ OBJECT(&s->tsp_memory), &error_abort)) {
+ return;
+ }
+
+ soc = ASPEED_SOC(&s->tsp);
+ aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART7, serial_hd(2));
+ if (!qdev_realize(DEVICE(&s->tsp), NULL, &error_abort)) {
+ return;
+ }
+}
+
+static void ast2700fc_init(MachineState *machine)
+{
+ ast2700fc_ca35_init(machine);
+ ast2700fc_ssp_init(machine);
+ ast2700fc_tsp_init(machine);
+}
+
+static void ast2700fc_class_init(ObjectClass *oc, const void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->alias = "ast2700fc";
+ mc->desc = "ast2700 full core support";
+ mc->init = ast2700fc_init;
+ mc->no_floppy = 1;
+ mc->no_cdrom = 1;
+ mc->min_cpus = mc->max_cpus = mc->default_cpus = 6;
+}
+
+static const TypeInfo ast2700fc_types[] = {
+ {
+ .name = MACHINE_TYPE_NAME("ast2700fc"),
+ .parent = TYPE_MACHINE,
+ .class_init = ast2700fc_class_init,
+ .instance_size = sizeof(Ast2700FCState),
+ },
+};
+
+DEFINE_TYPES(ast2700fc_types)
diff --git a/hw/arm/aspeed_ast27x0-ssp.c b/hw/arm/aspeed_ast27x0-ssp.c
new file mode 100644
index 0000000..80ec599
--- /dev/null
+++ b/hw/arm/aspeed_ast27x0-ssp.c
@@ -0,0 +1,294 @@
+/*
+ * ASPEED Ast27x0 SSP SoC
+ *
+ * Copyright (C) 2025 ASPEED Technology Inc.
+ *
+ * This code is licensed under the GPL version 2 or later. See
+ * the COPYING file in the top-level directory.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/qdev-clock.h"
+#include "hw/misc/unimp.h"
+#include "hw/arm/aspeed_soc.h"
+
+#define AST2700_SSP_RAM_SIZE (32 * MiB)
+
+static const hwaddr aspeed_soc_ast27x0ssp_memmap[] = {
+ [ASPEED_DEV_SRAM] = 0x00000000,
+ [ASPEED_DEV_INTC] = 0x72100000,
+ [ASPEED_DEV_SCU] = 0x72C02000,
+ [ASPEED_DEV_SCUIO] = 0x74C02000,
+ [ASPEED_DEV_UART0] = 0x74C33000,
+ [ASPEED_DEV_UART1] = 0x74C33100,
+ [ASPEED_DEV_UART2] = 0x74C33200,
+ [ASPEED_DEV_UART3] = 0x74C33300,
+ [ASPEED_DEV_UART4] = 0x72C1A000,
+ [ASPEED_DEV_INTCIO] = 0x74C18000,
+ [ASPEED_DEV_IPC0] = 0x72C1C000,
+ [ASPEED_DEV_IPC1] = 0x74C39000,
+ [ASPEED_DEV_UART5] = 0x74C33400,
+ [ASPEED_DEV_UART6] = 0x74C33500,
+ [ASPEED_DEV_UART7] = 0x74C33600,
+ [ASPEED_DEV_UART8] = 0x74C33700,
+ [ASPEED_DEV_UART9] = 0x74C33800,
+ [ASPEED_DEV_UART10] = 0x74C33900,
+ [ASPEED_DEV_UART11] = 0x74C33A00,
+ [ASPEED_DEV_UART12] = 0x74C33B00,
+ [ASPEED_DEV_TIMER1] = 0x72C10000,
+};
+
+static const int aspeed_soc_ast27x0ssp_irqmap[] = {
+ [ASPEED_DEV_SCU] = 12,
+ [ASPEED_DEV_UART0] = 164,
+ [ASPEED_DEV_UART1] = 164,
+ [ASPEED_DEV_UART2] = 164,
+ [ASPEED_DEV_UART3] = 164,
+ [ASPEED_DEV_UART4] = 8,
+ [ASPEED_DEV_UART5] = 164,
+ [ASPEED_DEV_UART6] = 164,
+ [ASPEED_DEV_UART7] = 164,
+ [ASPEED_DEV_UART8] = 164,
+ [ASPEED_DEV_UART9] = 164,
+ [ASPEED_DEV_UART10] = 164,
+ [ASPEED_DEV_UART11] = 164,
+ [ASPEED_DEV_UART12] = 164,
+ [ASPEED_DEV_TIMER1] = 16,
+};
+
+/* SSPINT 164 */
+static const int ast2700_ssp132_ssp164_intcmap[] = {
+ [ASPEED_DEV_UART0] = 7,
+ [ASPEED_DEV_UART1] = 8,
+ [ASPEED_DEV_UART2] = 9,
+ [ASPEED_DEV_UART3] = 10,
+ [ASPEED_DEV_UART5] = 11,
+ [ASPEED_DEV_UART6] = 12,
+ [ASPEED_DEV_UART7] = 13,
+ [ASPEED_DEV_UART8] = 14,
+ [ASPEED_DEV_UART9] = 15,
+ [ASPEED_DEV_UART10] = 16,
+ [ASPEED_DEV_UART11] = 17,
+ [ASPEED_DEV_UART12] = 18,
+};
+
+struct nvic_intc_irq_info {
+ int irq;
+ int intc_idx;
+ int orgate_idx;
+ const int *ptr;
+};
+
+static struct nvic_intc_irq_info ast2700_ssp_intcmap[] = {
+ {160, 1, 0, NULL},
+ {161, 1, 1, NULL},
+ {162, 1, 2, NULL},
+ {163, 1, 3, NULL},
+ {164, 1, 4, ast2700_ssp132_ssp164_intcmap},
+ {165, 1, 5, NULL},
+ {166, 1, 6, NULL},
+ {167, 1, 7, NULL},
+ {168, 1, 8, NULL},
+ {169, 1, 9, NULL},
+ {128, 0, 1, NULL},
+ {129, 0, 2, NULL},
+ {130, 0, 3, NULL},
+ {131, 0, 4, NULL},
+ {132, 0, 5, ast2700_ssp132_ssp164_intcmap},
+ {133, 0, 6, NULL},
+ {134, 0, 7, NULL},
+ {135, 0, 8, NULL},
+ {136, 0, 9, NULL},
+};
+
+static qemu_irq aspeed_soc_ast27x0ssp_get_irq(AspeedSoCState *s, int dev)
+{
+ Aspeed27x0SSPSoCState *a = ASPEED27X0SSP_SOC(s);
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+
+ int or_idx;
+ int idx;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ast2700_ssp_intcmap); i++) {
+ if (sc->irqmap[dev] == ast2700_ssp_intcmap[i].irq) {
+ assert(ast2700_ssp_intcmap[i].ptr);
+ or_idx = ast2700_ssp_intcmap[i].orgate_idx;
+ idx = ast2700_ssp_intcmap[i].intc_idx;
+ return qdev_get_gpio_in(DEVICE(&a->intc[idx].orgates[or_idx]),
+ ast2700_ssp_intcmap[i].ptr[dev]);
+ }
+ }
+
+ return qdev_get_gpio_in(DEVICE(&a->armv7m), sc->irqmap[dev]);
+}
+
+static void aspeed_soc_ast27x0ssp_init(Object *obj)
+{
+ Aspeed27x0SSPSoCState *a = ASPEED27X0SSP_SOC(obj);
+ AspeedSoCState *s = ASPEED_SOC(obj);
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+ int i;
+
+ object_initialize_child(obj, "armv7m", &a->armv7m, TYPE_ARMV7M);
+ object_initialize_child(obj, "scu", &s->scu, TYPE_ASPEED_2700_SCU);
+ s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
+ qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", sc->silicon_rev);
+
+ for (i = 0; i < sc->uarts_num; i++) {
+ object_initialize_child(obj, "uart[*]", &s->uart[i], TYPE_SERIAL_MM);
+ }
+
+ object_initialize_child(obj, "intc0", &a->intc[0],
+ TYPE_ASPEED_2700SSP_INTC);
+ object_initialize_child(obj, "intc1", &a->intc[1],
+ TYPE_ASPEED_2700SSP_INTCIO);
+
+ object_initialize_child(obj, "timerctrl", &s->timerctrl,
+ TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "ipc0", &a->ipc[0],
+ TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "ipc1", &a->ipc[1],
+ TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "scuio", &a->scuio,
+ TYPE_UNIMPLEMENTED_DEVICE);
+}
+
+static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp)
+{
+ Aspeed27x0SSPSoCState *a = ASPEED27X0SSP_SOC(dev_soc);
+ AspeedSoCState *s = ASPEED_SOC(dev_soc);
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+ DeviceState *armv7m;
+ g_autofree char *sram_name = NULL;
+ int i;
+
+ if (!clock_has_source(s->sysclk)) {
+ error_setg(errp, "sysclk clock must be wired up by the board code");
+ return;
+ }
+
+ /* AST27X0 SSP Core */
+ armv7m = DEVICE(&a->armv7m);
+ qdev_prop_set_uint32(armv7m, "num-irq", 256);
+ qdev_prop_set_string(armv7m, "cpu-type", aspeed_soc_cpu_type(sc));
+ qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
+ object_property_set_link(OBJECT(&a->armv7m), "memory",
+ OBJECT(s->memory), &error_abort);
+ sysbus_realize(SYS_BUS_DEVICE(&a->armv7m), &error_abort);
+
+ sram_name = g_strdup_printf("aspeed.dram.%d",
+ CPU(a->armv7m.cpu)->cpu_index);
+
+ if (!memory_region_init_ram(&s->sram, OBJECT(s), sram_name, sc->sram_size,
+ errp)) {
+ return;
+ }
+ memory_region_add_subregion(s->memory,
+ sc->memmap[ASPEED_DEV_SRAM],
+ &s->sram);
+
+ /* SCU */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) {
+ return;
+ }
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]);
+
+ /* INTC */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc[0]), errp)) {
+ return;
+ }
+
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->intc[0]), 0,
+ sc->memmap[ASPEED_DEV_INTC]);
+
+ /* INTCIO */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc[1]), errp)) {
+ return;
+ }
+
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->intc[1]), 0,
+ sc->memmap[ASPEED_DEV_INTCIO]);
+
+ /* irq source orgates -> INTC0 */
+ for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[0])->num_inpins; i++) {
+ qdev_connect_gpio_out(DEVICE(&a->intc[0].orgates[i]), 0,
+ qdev_get_gpio_in(DEVICE(&a->intc[0]), i));
+ }
+ for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[0])->num_outpins; i++) {
+ assert(i < ARRAY_SIZE(ast2700_ssp_intcmap));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc[0]), i,
+ qdev_get_gpio_in(DEVICE(&a->armv7m),
+ ast2700_ssp_intcmap[i].irq));
+ }
+ /* irq source orgates -> INTCIO */
+ for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[1])->num_inpins; i++) {
+ qdev_connect_gpio_out(DEVICE(&a->intc[1].orgates[i]), 0,
+ qdev_get_gpio_in(DEVICE(&a->intc[1]), i));
+ }
+ /* INTCIO -> INTC */
+ for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[1])->num_outpins; i++) {
+ sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc[1]), i,
+ qdev_get_gpio_in(DEVICE(&a->intc[0].orgates[0]), i));
+ }
+ /* UART */
+ if (!aspeed_soc_uart_realize(s, errp)) {
+ return;
+ }
+
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->timerctrl),
+ "aspeed.timerctrl",
+ sc->memmap[ASPEED_DEV_TIMER1], 0x200);
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&a->ipc[0]),
+ "aspeed.ipc0",
+ sc->memmap[ASPEED_DEV_IPC0], 0x1000);
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&a->ipc[1]),
+ "aspeed.ipc1",
+ sc->memmap[ASPEED_DEV_IPC1], 0x1000);
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&a->scuio),
+ "aspeed.scuio",
+ sc->memmap[ASPEED_DEV_SCUIO], 0x1000);
+}
+
+static void aspeed_soc_ast27x0ssp_class_init(ObjectClass *klass, const void *data)
+{
+ static const char * const valid_cpu_types[] = {
+ ARM_CPU_TYPE_NAME("cortex-m4"), /* TODO: cortex-m4f */
+ NULL
+ };
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedSoCClass *sc = ASPEED_SOC_CLASS(dc);
+
+ /* Reason: The Aspeed SoC can only be instantiated from a board */
+ dc->user_creatable = false;
+ dc->realize = aspeed_soc_ast27x0ssp_realize;
+
+ sc->valid_cpu_types = valid_cpu_types;
+ sc->silicon_rev = AST2700_A1_SILICON_REV;
+ sc->sram_size = AST2700_SSP_RAM_SIZE;
+ sc->spis_num = 0;
+ sc->ehcis_num = 0;
+ sc->wdts_num = 0;
+ sc->macs_num = 0;
+ sc->uarts_num = 13;
+ sc->uarts_base = ASPEED_DEV_UART0;
+ sc->irqmap = aspeed_soc_ast27x0ssp_irqmap;
+ sc->memmap = aspeed_soc_ast27x0ssp_memmap;
+ sc->num_cpus = 1;
+ sc->get_irq = aspeed_soc_ast27x0ssp_get_irq;
+}
+
+static const TypeInfo aspeed_soc_ast27x0ssp_types[] = {
+ {
+ .name = TYPE_ASPEED27X0SSP_SOC,
+ .parent = TYPE_ASPEED_SOC,
+ .instance_size = sizeof(Aspeed27x0SSPSoCState),
+ .instance_init = aspeed_soc_ast27x0ssp_init,
+ .class_init = aspeed_soc_ast27x0ssp_class_init,
+ },
+};
+
+DEFINE_TYPES(aspeed_soc_ast27x0ssp_types)
diff --git a/hw/arm/aspeed_ast27x0-tsp.c b/hw/arm/aspeed_ast27x0-tsp.c
new file mode 100644
index 0000000..4e0efae
--- /dev/null
+++ b/hw/arm/aspeed_ast27x0-tsp.c
@@ -0,0 +1,294 @@
+/*
+ * ASPEED Ast27x0 TSP SoC
+ *
+ * Copyright (C) 2025 ASPEED Technology Inc.
+ *
+ * This code is licensed under the GPL version 2 or later. See
+ * the COPYING file in the top-level directory.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/qdev-clock.h"
+#include "hw/misc/unimp.h"
+#include "hw/arm/aspeed_soc.h"
+
+#define AST2700_TSP_RAM_SIZE (32 * MiB)
+
+static const hwaddr aspeed_soc_ast27x0tsp_memmap[] = {
+ [ASPEED_DEV_SRAM] = 0x00000000,
+ [ASPEED_DEV_INTC] = 0x72100000,
+ [ASPEED_DEV_SCU] = 0x72C02000,
+ [ASPEED_DEV_SCUIO] = 0x74C02000,
+ [ASPEED_DEV_UART0] = 0x74C33000,
+ [ASPEED_DEV_UART1] = 0x74C33100,
+ [ASPEED_DEV_UART2] = 0x74C33200,
+ [ASPEED_DEV_UART3] = 0x74C33300,
+ [ASPEED_DEV_UART4] = 0x72C1A000,
+ [ASPEED_DEV_INTCIO] = 0x74C18000,
+ [ASPEED_DEV_IPC0] = 0x72C1C000,
+ [ASPEED_DEV_IPC1] = 0x74C39000,
+ [ASPEED_DEV_UART5] = 0x74C33400,
+ [ASPEED_DEV_UART6] = 0x74C33500,
+ [ASPEED_DEV_UART7] = 0x74C33600,
+ [ASPEED_DEV_UART8] = 0x74C33700,
+ [ASPEED_DEV_UART9] = 0x74C33800,
+ [ASPEED_DEV_UART10] = 0x74C33900,
+ [ASPEED_DEV_UART11] = 0x74C33A00,
+ [ASPEED_DEV_UART12] = 0x74C33B00,
+ [ASPEED_DEV_TIMER1] = 0x72C10000,
+};
+
+static const int aspeed_soc_ast27x0tsp_irqmap[] = {
+ [ASPEED_DEV_SCU] = 12,
+ [ASPEED_DEV_UART0] = 164,
+ [ASPEED_DEV_UART1] = 164,
+ [ASPEED_DEV_UART2] = 164,
+ [ASPEED_DEV_UART3] = 164,
+ [ASPEED_DEV_UART4] = 8,
+ [ASPEED_DEV_UART5] = 164,
+ [ASPEED_DEV_UART6] = 164,
+ [ASPEED_DEV_UART7] = 164,
+ [ASPEED_DEV_UART8] = 164,
+ [ASPEED_DEV_UART9] = 164,
+ [ASPEED_DEV_UART10] = 164,
+ [ASPEED_DEV_UART11] = 164,
+ [ASPEED_DEV_UART12] = 164,
+ [ASPEED_DEV_TIMER1] = 16,
+};
+
+/* TSPINT 164 */
+static const int ast2700_tsp132_tsp164_intcmap[] = {
+ [ASPEED_DEV_UART0] = 7,
+ [ASPEED_DEV_UART1] = 8,
+ [ASPEED_DEV_UART2] = 9,
+ [ASPEED_DEV_UART3] = 10,
+ [ASPEED_DEV_UART5] = 11,
+ [ASPEED_DEV_UART6] = 12,
+ [ASPEED_DEV_UART7] = 13,
+ [ASPEED_DEV_UART8] = 14,
+ [ASPEED_DEV_UART9] = 15,
+ [ASPEED_DEV_UART10] = 16,
+ [ASPEED_DEV_UART11] = 17,
+ [ASPEED_DEV_UART12] = 18,
+};
+
+struct nvic_intc_irq_info {
+ int irq;
+ int intc_idx;
+ int orgate_idx;
+ const int *ptr;
+};
+
+static struct nvic_intc_irq_info ast2700_tsp_intcmap[] = {
+ {160, 1, 0, NULL},
+ {161, 1, 1, NULL},
+ {162, 1, 2, NULL},
+ {163, 1, 3, NULL},
+ {164, 1, 4, ast2700_tsp132_tsp164_intcmap},
+ {165, 1, 5, NULL},
+ {166, 1, 6, NULL},
+ {167, 1, 7, NULL},
+ {168, 1, 8, NULL},
+ {169, 1, 9, NULL},
+ {128, 0, 1, NULL},
+ {129, 0, 2, NULL},
+ {130, 0, 3, NULL},
+ {131, 0, 4, NULL},
+ {132, 0, 5, ast2700_tsp132_tsp164_intcmap},
+ {133, 0, 6, NULL},
+ {134, 0, 7, NULL},
+ {135, 0, 8, NULL},
+ {136, 0, 9, NULL},
+};
+
+static qemu_irq aspeed_soc_ast27x0tsp_get_irq(AspeedSoCState *s, int dev)
+{
+ Aspeed27x0TSPSoCState *a = ASPEED27X0TSP_SOC(s);
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+
+ int or_idx;
+ int idx;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ast2700_tsp_intcmap); i++) {
+ if (sc->irqmap[dev] == ast2700_tsp_intcmap[i].irq) {
+ assert(ast2700_tsp_intcmap[i].ptr);
+ or_idx = ast2700_tsp_intcmap[i].orgate_idx;
+ idx = ast2700_tsp_intcmap[i].intc_idx;
+ return qdev_get_gpio_in(DEVICE(&a->intc[idx].orgates[or_idx]),
+ ast2700_tsp_intcmap[i].ptr[dev]);
+ }
+ }
+
+ return qdev_get_gpio_in(DEVICE(&a->armv7m), sc->irqmap[dev]);
+}
+
+static void aspeed_soc_ast27x0tsp_init(Object *obj)
+{
+ Aspeed27x0TSPSoCState *a = ASPEED27X0TSP_SOC(obj);
+ AspeedSoCState *s = ASPEED_SOC(obj);
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+ int i;
+
+ object_initialize_child(obj, "armv7m", &a->armv7m, TYPE_ARMV7M);
+ object_initialize_child(obj, "scu", &s->scu, TYPE_ASPEED_2700_SCU);
+ s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
+ qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", sc->silicon_rev);
+
+ for (i = 0; i < sc->uarts_num; i++) {
+ object_initialize_child(obj, "uart[*]", &s->uart[i], TYPE_SERIAL_MM);
+ }
+
+ object_initialize_child(obj, "intc0", &a->intc[0],
+ TYPE_ASPEED_2700TSP_INTC);
+ object_initialize_child(obj, "intc1", &a->intc[1],
+ TYPE_ASPEED_2700TSP_INTCIO);
+
+ object_initialize_child(obj, "timerctrl", &s->timerctrl,
+ TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "ipc0", &a->ipc[0],
+ TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "ipc1", &a->ipc[1],
+ TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "scuio", &a->scuio,
+ TYPE_UNIMPLEMENTED_DEVICE);
+}
+
+static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp)
+{
+ Aspeed27x0TSPSoCState *a = ASPEED27X0TSP_SOC(dev_soc);
+ AspeedSoCState *s = ASPEED_SOC(dev_soc);
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+ DeviceState *armv7m;
+ g_autofree char *sram_name = NULL;
+ int i;
+
+ if (!clock_has_source(s->sysclk)) {
+ error_setg(errp, "sysclk clock must be wired up by the board code");
+ return;
+ }
+
+ /* AST27X0 TSP Core */
+ armv7m = DEVICE(&a->armv7m);
+ qdev_prop_set_uint32(armv7m, "num-irq", 256);
+ qdev_prop_set_string(armv7m, "cpu-type", aspeed_soc_cpu_type(sc));
+ qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk);
+ object_property_set_link(OBJECT(&a->armv7m), "memory",
+ OBJECT(s->memory), &error_abort);
+ sysbus_realize(SYS_BUS_DEVICE(&a->armv7m), &error_abort);
+
+ sram_name = g_strdup_printf("aspeed.dram.%d",
+ CPU(a->armv7m.cpu)->cpu_index);
+
+ if (!memory_region_init_ram(&s->sram, OBJECT(s), sram_name, sc->sram_size,
+ errp)) {
+ return;
+ }
+ memory_region_add_subregion(s->memory,
+ sc->memmap[ASPEED_DEV_SRAM],
+ &s->sram);
+
+ /* SCU */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) {
+ return;
+ }
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]);
+
+ /* INTC */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc[0]), errp)) {
+ return;
+ }
+
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->intc[0]), 0,
+ sc->memmap[ASPEED_DEV_INTC]);
+
+ /* INTCIO */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc[1]), errp)) {
+ return;
+ }
+
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->intc[1]), 0,
+ sc->memmap[ASPEED_DEV_INTCIO]);
+
+ /* irq source orgates -> INTC */
+ for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[0])->num_inpins; i++) {
+ qdev_connect_gpio_out(DEVICE(&a->intc[0].orgates[i]), 0,
+ qdev_get_gpio_in(DEVICE(&a->intc[0]), i));
+ }
+ for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[0])->num_outpins; i++) {
+ assert(i < ARRAY_SIZE(ast2700_tsp_intcmap));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc[0]), i,
+ qdev_get_gpio_in(DEVICE(&a->armv7m),
+ ast2700_tsp_intcmap[i].irq));
+ }
+ /* irq source orgates -> INTC */
+ for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[1])->num_inpins; i++) {
+ qdev_connect_gpio_out(DEVICE(&a->intc[1].orgates[i]), 0,
+ qdev_get_gpio_in(DEVICE(&a->intc[1]), i));
+ }
+ /* INTCIO -> INTC */
+ for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[1])->num_outpins; i++) {
+ sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc[1]), i,
+ qdev_get_gpio_in(DEVICE(&a->intc[0].orgates[0]), i));
+ }
+ /* UART */
+ if (!aspeed_soc_uart_realize(s, errp)) {
+ return;
+ }
+
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->timerctrl),
+ "aspeed.timerctrl",
+ sc->memmap[ASPEED_DEV_TIMER1], 0x200);
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&a->ipc[0]),
+ "aspeed.ipc0",
+ sc->memmap[ASPEED_DEV_IPC0], 0x1000);
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&a->ipc[1]),
+ "aspeed.ipc1",
+ sc->memmap[ASPEED_DEV_IPC1], 0x1000);
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&a->scuio),
+ "aspeed.scuio",
+ sc->memmap[ASPEED_DEV_SCUIO], 0x1000);
+}
+
+static void aspeed_soc_ast27x0tsp_class_init(ObjectClass *klass, const void *data)
+{
+ static const char * const valid_cpu_types[] = {
+ ARM_CPU_TYPE_NAME("cortex-m4"), /* TODO cortex-m4f */
+ NULL
+ };
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedSoCClass *sc = ASPEED_SOC_CLASS(dc);
+
+ /* Reason: The Aspeed SoC can only be instantiated from a board */
+ dc->user_creatable = false;
+ dc->realize = aspeed_soc_ast27x0tsp_realize;
+
+ sc->valid_cpu_types = valid_cpu_types;
+ sc->silicon_rev = AST2700_A1_SILICON_REV;
+ sc->sram_size = AST2700_TSP_RAM_SIZE;
+ sc->spis_num = 0;
+ sc->ehcis_num = 0;
+ sc->wdts_num = 0;
+ sc->macs_num = 0;
+ sc->uarts_num = 13;
+ sc->uarts_base = ASPEED_DEV_UART0;
+ sc->irqmap = aspeed_soc_ast27x0tsp_irqmap;
+ sc->memmap = aspeed_soc_ast27x0tsp_memmap;
+ sc->num_cpus = 1;
+ sc->get_irq = aspeed_soc_ast27x0tsp_get_irq;
+}
+
+static const TypeInfo aspeed_soc_ast27x0tsp_types[] = {
+ {
+ .name = TYPE_ASPEED27X0TSP_SOC,
+ .parent = TYPE_ASPEED_SOC,
+ .instance_size = sizeof(Aspeed27x0TSPSoCState),
+ .instance_init = aspeed_soc_ast27x0tsp_init,
+ .class_init = aspeed_soc_ast27x0tsp_class_init,
+ },
+};
+
+DEFINE_TYPES(aspeed_soc_ast27x0tsp_types)
diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index 63a366f..1974a25 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -23,8 +23,19 @@
#include "qobject/qlist.h"
#include "qemu/log.h"
+#define AST2700_SOC_IO_SIZE 0x01000000
+#define AST2700_SOC_IOMEM_SIZE 0x01000000
+#define AST2700_SOC_DPMCU_SIZE 0x00040000
+#define AST2700_SOC_LTPI_SIZE 0x01000000
+
static const hwaddr aspeed_soc_ast2700_memmap[] = {
+ [ASPEED_DEV_IOMEM] = 0x00000000,
+ [ASPEED_DEV_VBOOTROM] = 0x00000000,
[ASPEED_DEV_SRAM] = 0x10000000,
+ [ASPEED_DEV_DPMCU] = 0x11000000,
+ [ASPEED_DEV_IOMEM0] = 0x12000000,
+ [ASPEED_DEV_EHCI1] = 0x12061000,
+ [ASPEED_DEV_EHCI2] = 0x12063000,
[ASPEED_DEV_HACE] = 0x12070000,
[ASPEED_DEV_EMMC] = 0x12090000,
[ASPEED_DEV_INTC] = 0x12100000,
@@ -35,7 +46,8 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = {
[ASPEED_DEV_RTC] = 0x12C0F000,
[ASPEED_DEV_TIMER1] = 0x12C10000,
[ASPEED_DEV_SLI] = 0x12C17000,
- [ASPEED_DEV_UART4] = 0X12C1A000,
+ [ASPEED_DEV_UART4] = 0x12C1A000,
+ [ASPEED_DEV_IOMEM1] = 0x14000000,
[ASPEED_DEV_FMC] = 0x14000000,
[ASPEED_DEV_SPI0] = 0x14010000,
[ASPEED_DEV_SPI1] = 0x14020000,
@@ -47,27 +59,30 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = {
[ASPEED_DEV_ETH2] = 0x14060000,
[ASPEED_DEV_ETH3] = 0x14070000,
[ASPEED_DEV_SDHCI] = 0x14080000,
+ [ASPEED_DEV_EHCI3] = 0x14121000,
+ [ASPEED_DEV_EHCI4] = 0x14123000,
[ASPEED_DEV_ADC] = 0x14C00000,
[ASPEED_DEV_SCUIO] = 0x14C02000,
[ASPEED_DEV_GPIO] = 0x14C0B000,
[ASPEED_DEV_I2C] = 0x14C0F000,
[ASPEED_DEV_INTCIO] = 0x14C18000,
[ASPEED_DEV_SLIIO] = 0x14C1E000,
- [ASPEED_DEV_VUART] = 0X14C30000,
- [ASPEED_DEV_UART0] = 0X14C33000,
- [ASPEED_DEV_UART1] = 0X14C33100,
- [ASPEED_DEV_UART2] = 0X14C33200,
- [ASPEED_DEV_UART3] = 0X14C33300,
- [ASPEED_DEV_UART5] = 0X14C33400,
- [ASPEED_DEV_UART6] = 0X14C33500,
- [ASPEED_DEV_UART7] = 0X14C33600,
- [ASPEED_DEV_UART8] = 0X14C33700,
- [ASPEED_DEV_UART9] = 0X14C33800,
- [ASPEED_DEV_UART10] = 0X14C33900,
- [ASPEED_DEV_UART11] = 0X14C33A00,
- [ASPEED_DEV_UART12] = 0X14C33B00,
+ [ASPEED_DEV_VUART] = 0x14C30000,
+ [ASPEED_DEV_UART0] = 0x14C33000,
+ [ASPEED_DEV_UART1] = 0x14C33100,
+ [ASPEED_DEV_UART2] = 0x14C33200,
+ [ASPEED_DEV_UART3] = 0x14C33300,
+ [ASPEED_DEV_UART5] = 0x14C33400,
+ [ASPEED_DEV_UART6] = 0x14C33500,
+ [ASPEED_DEV_UART7] = 0x14C33600,
+ [ASPEED_DEV_UART8] = 0x14C33700,
+ [ASPEED_DEV_UART9] = 0x14C33800,
+ [ASPEED_DEV_UART10] = 0x14C33900,
+ [ASPEED_DEV_UART11] = 0x14C33A00,
+ [ASPEED_DEV_UART12] = 0x14C33B00,
[ASPEED_DEV_WDT] = 0x14C37000,
[ASPEED_DEV_SPI_BOOT] = 0x100000000,
+ [ASPEED_DEV_LTPI] = 0x300000000,
[ASPEED_DEV_SDRAM] = 0x400000000,
};
@@ -91,6 +106,8 @@ static const int aspeed_soc_ast2700a0_irqmap[] = {
[ASPEED_DEV_TIMER7] = 22,
[ASPEED_DEV_TIMER8] = 23,
[ASPEED_DEV_DP] = 28,
+ [ASPEED_DEV_EHCI1] = 33,
+ [ASPEED_DEV_EHCI2] = 37,
[ASPEED_DEV_LPC] = 128,
[ASPEED_DEV_IBT] = 128,
[ASPEED_DEV_KCS] = 128,
@@ -137,6 +154,8 @@ static const int aspeed_soc_ast2700a1_irqmap[] = {
[ASPEED_DEV_TIMER7] = 22,
[ASPEED_DEV_TIMER8] = 23,
[ASPEED_DEV_DP] = 28,
+ [ASPEED_DEV_EHCI1] = 33,
+ [ASPEED_DEV_EHCI2] = 37,
[ASPEED_DEV_LPC] = 192,
[ASPEED_DEV_IBT] = 192,
[ASPEED_DEV_KCS] = 192,
@@ -212,6 +231,8 @@ static const int ast2700_gic132_gic196_intcmap[] = {
[ASPEED_DEV_UART10] = 16,
[ASPEED_DEV_UART11] = 17,
[ASPEED_DEV_UART12] = 18,
+ [ASPEED_DEV_EHCI3] = 28,
+ [ASPEED_DEV_EHCI4] = 29,
};
/* GICINT 133 */
@@ -434,6 +455,11 @@ static void aspeed_soc_ast2700_init(Object *obj)
object_initialize_child(obj, "spi[*]", &s->spi[i], typename);
}
+ for (i = 0; i < sc->ehcis_num; i++) {
+ object_initialize_child(obj, "ehci[*]", &s->ehci[i],
+ TYPE_PLATFORM_EHCI);
+ }
+
snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname);
object_initialize_child(obj, "sdmc", &s->sdmc, typename);
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
@@ -491,6 +517,16 @@ static void aspeed_soc_ast2700_init(Object *obj)
snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname);
object_initialize_child(obj, "hace", &s->hace, typename);
+ object_initialize_child(obj, "dpmcu", &s->dpmcu,
+ TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "ltpi", &s->ltpi,
+ TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "iomem", &s->iomem,
+ TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "iomem0", &s->iomem0,
+ TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "iomem1", &s->iomem1,
+ TYPE_UNIMPLEMENTED_DEVICE);
}
/*
@@ -526,8 +562,11 @@ static bool aspeed_soc_ast2700_gic_realize(DeviceState *dev, Error **errp)
if (!sysbus_realize(gicbusdev, errp)) {
return false;
}
- sysbus_mmio_map(gicbusdev, 0, sc->memmap[ASPEED_GIC_DIST]);
- sysbus_mmio_map(gicbusdev, 1, sc->memmap[ASPEED_GIC_REDIST]);
+
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->gic), 0,
+ sc->memmap[ASPEED_GIC_DIST]);
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->gic), 1,
+ sc->memmap[ASPEED_GIC_REDIST]);
for (i = 0; i < sc->num_cpus; i++) {
DeviceState *cpudev = DEVICE(&a->cpu[i]);
@@ -577,7 +616,7 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
AspeedINTCClass *ic = ASPEED_INTC_GET_CLASS(&a->intc[0]);
AspeedINTCClass *icio = ASPEED_INTC_GET_CLASS(&a->intc[1]);
- g_autofree char *sram_name = NULL;
+ g_autofree char *name = NULL;
qemu_irq irq;
/* Default boot region (SPI memory or ROMs) */
@@ -649,14 +688,22 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
}
/* SRAM */
- sram_name = g_strdup_printf("aspeed.sram.%d", CPU(&a->cpu[0])->cpu_index);
- if (!memory_region_init_ram(&s->sram, OBJECT(s), sram_name, sc->sram_size,
- errp)) {
+ name = g_strdup_printf("aspeed.sram.%d", CPU(&a->cpu[0])->cpu_index);
+ if (!memory_region_init_ram(&s->sram, OBJECT(s), name, sc->sram_size,
+ errp)) {
return;
}
memory_region_add_subregion(s->memory,
sc->memmap[ASPEED_DEV_SRAM], &s->sram);
+ /* VBOOTROM */
+ if (!memory_region_init_ram(&s->vbootrom, OBJECT(s), "aspeed.vbootrom",
+ 0x20000, errp)) {
+ return;
+ }
+ memory_region_add_subregion(s->memory,
+ sc->memmap[ASPEED_DEV_VBOOTROM], &s->vbootrom);
+
/* SCU */
if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) {
return;
@@ -709,6 +756,17 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
ASPEED_SMC_GET_CLASS(&s->spi[i])->flash_window_base);
}
+ /* EHCI */
+ for (i = 0; i < sc->ehcis_num; i++) {
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->ehci[i]), errp)) {
+ return;
+ }
+ aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->ehci[i]), 0,
+ sc->memmap[ASPEED_DEV_EHCI1 + i]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0,
+ aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i));
+ }
+
/*
* SDMC - SDRAM Memory Controller
* The SDMC controller is unlocked at SPL stage.
@@ -876,11 +934,26 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0,
aspeed_soc_get_irq(s, ASPEED_DEV_HACE));
- create_unimplemented_device("ast2700.dpmcu", 0x11000000, 0x40000);
- create_unimplemented_device("ast2700.iomem0", 0x12000000, 0x01000000);
- create_unimplemented_device("ast2700.iomem1", 0x14000000, 0x01000000);
- create_unimplemented_device("ast2700.ltpi", 0x30000000, 0x1000000);
- create_unimplemented_device("ast2700.io", 0x0, 0x4000000);
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->dpmcu),
+ "aspeed.dpmcu",
+ sc->memmap[ASPEED_DEV_DPMCU],
+ AST2700_SOC_DPMCU_SIZE);
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->ltpi),
+ "aspeed.ltpi",
+ sc->memmap[ASPEED_DEV_LTPI],
+ AST2700_SOC_LTPI_SIZE);
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->iomem),
+ "aspeed.io",
+ sc->memmap[ASPEED_DEV_IOMEM],
+ AST2700_SOC_IO_SIZE);
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->iomem0),
+ "aspeed.iomem0",
+ sc->memmap[ASPEED_DEV_IOMEM0],
+ AST2700_SOC_IOMEM_SIZE);
+ aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->iomem1),
+ "aspeed.iomem1",
+ sc->memmap[ASPEED_DEV_IOMEM1],
+ AST2700_SOC_IOMEM_SIZE);
}
static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc, const void *data)
@@ -900,6 +973,7 @@ static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc, const void *data)
sc->silicon_rev = AST2700_A0_SILICON_REV;
sc->sram_size = 0x20000;
sc->spis_num = 3;
+ sc->ehcis_num = 2;
sc->wdts_num = 8;
sc->macs_num = 1;
sc->uarts_num = 13;
@@ -927,6 +1001,7 @@ static void aspeed_soc_ast2700a1_class_init(ObjectClass *oc, const void *data)
sc->silicon_rev = AST2700_A1_SILICON_REV;
sc->sram_size = 0x20000;
sc->spis_num = 3;
+ sc->ehcis_num = 4;
sc->wdts_num = 8;
sc->macs_num = 3;
sc->uarts_num = 13;
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index 09b1cfe..5098795 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -44,10 +44,14 @@ arm_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
'aspeed_soc_common.c',
'aspeed_ast2400.c',
'aspeed_ast2600.c',
+ 'aspeed_ast27x0-ssp.c',
+ 'aspeed_ast27x0-tsp.c',
'aspeed_ast10x0.c',
'aspeed_eeprom.c',
'fby35.c'))
-arm_common_ss.add(when: ['CONFIG_ASPEED_SOC', 'TARGET_AARCH64'], if_true: files('aspeed_ast27x0.c'))
+arm_common_ss.add(when: ['CONFIG_ASPEED_SOC', 'TARGET_AARCH64'], if_true: files(
+ 'aspeed_ast27x0.c',
+ 'aspeed_ast27x0-fc.c',))
arm_common_ss.add(when: 'CONFIG_MPS2', if_true: files('mps2.c'))
arm_common_ss.add(when: 'CONFIG_MPS2', if_true: files('mps2-tz.c'))
arm_common_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-soc.c'))
diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c
index be7f516..33fcbe7 100644
--- a/hw/intc/aspeed_intc.c
+++ b/hw/intc/aspeed_intc.c
@@ -62,6 +62,95 @@ REG32(GICINT196_STATUS, 0x44)
REG32(GICINT197_EN, 0x50)
REG32(GICINT197_STATUS, 0x54)
+/*
+ * SSP INTC Registers
+ */
+REG32(SSPINT128_EN, 0x2000)
+REG32(SSPINT128_STATUS, 0x2004)
+REG32(SSPINT129_EN, 0x2100)
+REG32(SSPINT129_STATUS, 0x2104)
+REG32(SSPINT130_EN, 0x2200)
+REG32(SSPINT130_STATUS, 0x2204)
+REG32(SSPINT131_EN, 0x2300)
+REG32(SSPINT131_STATUS, 0x2304)
+REG32(SSPINT132_EN, 0x2400)
+REG32(SSPINT132_STATUS, 0x2404)
+REG32(SSPINT133_EN, 0x2500)
+REG32(SSPINT133_STATUS, 0x2504)
+REG32(SSPINT134_EN, 0x2600)
+REG32(SSPINT134_STATUS, 0x2604)
+REG32(SSPINT135_EN, 0x2700)
+REG32(SSPINT135_STATUS, 0x2704)
+REG32(SSPINT136_EN, 0x2800)
+REG32(SSPINT136_STATUS, 0x2804)
+REG32(SSPINT137_EN, 0x2900)
+REG32(SSPINT137_STATUS, 0x2904)
+REG32(SSPINT138_EN, 0x2A00)
+REG32(SSPINT138_STATUS, 0x2A04)
+REG32(SSPINT160_169_EN, 0x2B00)
+REG32(SSPINT160_169_STATUS, 0x2B04)
+
+/*
+ * SSP INTCIO Registers
+ */
+REG32(SSPINT160_EN, 0x180)
+REG32(SSPINT160_STATUS, 0x184)
+REG32(SSPINT161_EN, 0x190)
+REG32(SSPINT161_STATUS, 0x194)
+REG32(SSPINT162_EN, 0x1A0)
+REG32(SSPINT162_STATUS, 0x1A4)
+REG32(SSPINT163_EN, 0x1B0)
+REG32(SSPINT163_STATUS, 0x1B4)
+REG32(SSPINT164_EN, 0x1C0)
+REG32(SSPINT164_STATUS, 0x1C4)
+REG32(SSPINT165_EN, 0x1D0)
+REG32(SSPINT165_STATUS, 0x1D4)
+
+/*
+ * TSP INTC Registers
+ */
+REG32(TSPINT128_EN, 0x3000)
+REG32(TSPINT128_STATUS, 0x3004)
+REG32(TSPINT129_EN, 0x3100)
+REG32(TSPINT129_STATUS, 0x3104)
+REG32(TSPINT130_EN, 0x3200)
+REG32(TSPINT130_STATUS, 0x3204)
+REG32(TSPINT131_EN, 0x3300)
+REG32(TSPINT131_STATUS, 0x3304)
+REG32(TSPINT132_EN, 0x3400)
+REG32(TSPINT132_STATUS, 0x3404)
+REG32(TSPINT133_EN, 0x3500)
+REG32(TSPINT133_STATUS, 0x3504)
+REG32(TSPINT134_EN, 0x3600)
+REG32(TSPINT134_STATUS, 0x3604)
+REG32(TSPINT135_EN, 0x3700)
+REG32(TSPINT135_STATUS, 0x3704)
+REG32(TSPINT136_EN, 0x3800)
+REG32(TSPINT136_STATUS, 0x3804)
+REG32(TSPINT137_EN, 0x3900)
+REG32(TSPINT137_STATUS, 0x3904)
+REG32(TSPINT138_EN, 0x3A00)
+REG32(TSPINT138_STATUS, 0x3A04)
+REG32(TSPINT160_169_EN, 0x3B00)
+REG32(TSPINT160_169_STATUS, 0x3B04)
+
+/*
+ * TSP INTCIO Registers
+ */
+
+REG32(TSPINT160_EN, 0x200)
+REG32(TSPINT160_STATUS, 0x204)
+REG32(TSPINT161_EN, 0x210)
+REG32(TSPINT161_STATUS, 0x214)
+REG32(TSPINT162_EN, 0x220)
+REG32(TSPINT162_STATUS, 0x224)
+REG32(TSPINT163_EN, 0x230)
+REG32(TSPINT163_STATUS, 0x234)
+REG32(TSPINT164_EN, 0x240)
+REG32(TSPINT164_STATUS, 0x244)
+REG32(TSPINT165_EN, 0x250)
+REG32(TSPINT165_STATUS, 0x254)
+
static const AspeedINTCIRQ *aspeed_intc_get_irq(AspeedINTCClass *aic,
uint32_t reg)
{
@@ -450,6 +539,90 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data,
}
}
+static void aspeed_ssp_intc_write(void *opaque, hwaddr offset, uint64_t data,
+ unsigned size)
+{
+ AspeedINTCState *s = ASPEED_INTC(opaque);
+ const char *name = object_get_typename(OBJECT(s));
+ uint32_t reg = offset >> 2;
+
+ trace_aspeed_intc_write(name, offset, size, data);
+
+ switch (reg) {
+ case R_SSPINT128_EN:
+ case R_SSPINT129_EN:
+ case R_SSPINT130_EN:
+ case R_SSPINT131_EN:
+ case R_SSPINT132_EN:
+ case R_SSPINT133_EN:
+ case R_SSPINT134_EN:
+ case R_SSPINT135_EN:
+ case R_SSPINT136_EN:
+ case R_SSPINT160_169_EN:
+ aspeed_intc_enable_handler(s, offset, data);
+ break;
+ case R_SSPINT128_STATUS:
+ case R_SSPINT129_STATUS:
+ case R_SSPINT130_STATUS:
+ case R_SSPINT131_STATUS:
+ case R_SSPINT132_STATUS:
+ case R_SSPINT133_STATUS:
+ case R_SSPINT134_STATUS:
+ case R_SSPINT135_STATUS:
+ case R_SSPINT136_STATUS:
+ aspeed_intc_status_handler(s, offset, data);
+ break;
+ case R_SSPINT160_169_STATUS:
+ aspeed_intc_status_handler_multi_outpins(s, offset, data);
+ break;
+ default:
+ s->regs[reg] = data;
+ break;
+ }
+}
+
+static void aspeed_tsp_intc_write(void *opaque, hwaddr offset, uint64_t data,
+ unsigned size)
+{
+ AspeedINTCState *s = ASPEED_INTC(opaque);
+ const char *name = object_get_typename(OBJECT(s));
+ uint32_t reg = offset >> 2;
+
+ trace_aspeed_intc_write(name, offset, size, data);
+
+ switch (reg) {
+ case R_TSPINT128_EN:
+ case R_TSPINT129_EN:
+ case R_TSPINT130_EN:
+ case R_TSPINT131_EN:
+ case R_TSPINT132_EN:
+ case R_TSPINT133_EN:
+ case R_TSPINT134_EN:
+ case R_TSPINT135_EN:
+ case R_TSPINT136_EN:
+ case R_TSPINT160_169_EN:
+ aspeed_intc_enable_handler(s, offset, data);
+ break;
+ case R_TSPINT128_STATUS:
+ case R_TSPINT129_STATUS:
+ case R_TSPINT130_STATUS:
+ case R_TSPINT131_STATUS:
+ case R_TSPINT132_STATUS:
+ case R_TSPINT133_STATUS:
+ case R_TSPINT134_STATUS:
+ case R_TSPINT135_STATUS:
+ case R_TSPINT136_STATUS:
+ aspeed_intc_status_handler(s, offset, data);
+ break;
+ case R_TSPINT160_169_STATUS:
+ aspeed_intc_status_handler_multi_outpins(s, offset, data);
+ break;
+ default:
+ s->regs[reg] = data;
+ break;
+ }
+}
+
static uint64_t aspeed_intcio_read(void *opaque, hwaddr offset,
unsigned int size)
{
@@ -496,6 +669,69 @@ static void aspeed_intcio_write(void *opaque, hwaddr offset, uint64_t data,
}
}
+static void aspeed_ssp_intcio_write(void *opaque, hwaddr offset, uint64_t data,
+ unsigned size)
+{
+ AspeedINTCState *s = ASPEED_INTC(opaque);
+ const char *name = object_get_typename(OBJECT(s));
+ uint32_t reg = offset >> 2;
+
+ trace_aspeed_intc_write(name, offset, size, data);
+
+ switch (reg) {
+ case R_SSPINT160_EN:
+ case R_SSPINT161_EN:
+ case R_SSPINT162_EN:
+ case R_SSPINT163_EN:
+ case R_SSPINT164_EN:
+ case R_SSPINT165_EN:
+ aspeed_intc_enable_handler(s, offset, data);
+ break;
+ case R_SSPINT160_STATUS:
+ case R_SSPINT161_STATUS:
+ case R_SSPINT162_STATUS:
+ case R_SSPINT163_STATUS:
+ case R_SSPINT164_STATUS:
+ case R_SSPINT165_STATUS:
+ aspeed_intc_status_handler(s, offset, data);
+ break;
+ default:
+ s->regs[reg] = data;
+ break;
+ }
+}
+
+static void aspeed_tsp_intcio_write(void *opaque, hwaddr offset, uint64_t data,
+ unsigned size)
+{
+ AspeedINTCState *s = ASPEED_INTC(opaque);
+ const char *name = object_get_typename(OBJECT(s));
+ uint32_t reg = offset >> 2;
+
+ trace_aspeed_intc_write(name, offset, size, data);
+
+ switch (reg) {
+ case R_TSPINT160_EN:
+ case R_TSPINT161_EN:
+ case R_TSPINT162_EN:
+ case R_TSPINT163_EN:
+ case R_TSPINT164_EN:
+ case R_TSPINT165_EN:
+ aspeed_intc_enable_handler(s, offset, data);
+ break;
+ case R_TSPINT160_STATUS:
+ case R_TSPINT161_STATUS:
+ case R_TSPINT162_STATUS:
+ case R_TSPINT163_STATUS:
+ case R_TSPINT164_STATUS:
+ case R_TSPINT165_STATUS:
+ aspeed_intc_status_handler(s, offset, data);
+ break;
+ default:
+ s->regs[reg] = data;
+ break;
+ }
+}
static const MemoryRegionOps aspeed_intc_ops = {
.read = aspeed_intc_read,
@@ -517,6 +753,46 @@ static const MemoryRegionOps aspeed_intcio_ops = {
}
};
+static const MemoryRegionOps aspeed_ssp_intc_ops = {
+ .read = aspeed_intc_read,
+ .write = aspeed_ssp_intc_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ }
+};
+
+static const MemoryRegionOps aspeed_ssp_intcio_ops = {
+ .read = aspeed_intcio_read,
+ .write = aspeed_ssp_intcio_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ }
+};
+
+static const MemoryRegionOps aspeed_tsp_intc_ops = {
+ .read = aspeed_intc_read,
+ .write = aspeed_tsp_intc_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ }
+};
+
+static const MemoryRegionOps aspeed_tsp_intcio_ops = {
+ .read = aspeed_intcio_read,
+ .write = aspeed_tsp_intcio_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ }
+};
+
static void aspeed_intc_instance_init(Object *obj)
{
AspeedINTCState *s = ASPEED_INTC(obj);
@@ -674,11 +950,151 @@ static const TypeInfo aspeed_2700_intcio_info = {
.class_init = aspeed_2700_intcio_class_init,
};
+static AspeedINTCIRQ aspeed_2700ssp_intc_irqs[ASPEED_INTC_MAX_INPINS] = {
+ {0, 0, 10, R_SSPINT160_169_EN, R_SSPINT160_169_STATUS},
+ {1, 10, 1, R_SSPINT128_EN, R_SSPINT128_STATUS},
+ {2, 11, 1, R_SSPINT129_EN, R_SSPINT129_STATUS},
+ {3, 12, 1, R_SSPINT130_EN, R_SSPINT130_STATUS},
+ {4, 13, 1, R_SSPINT131_EN, R_SSPINT131_STATUS},
+ {5, 14, 1, R_SSPINT132_EN, R_SSPINT132_STATUS},
+ {6, 15, 1, R_SSPINT133_EN, R_SSPINT133_STATUS},
+ {7, 16, 1, R_SSPINT134_EN, R_SSPINT134_STATUS},
+ {8, 17, 1, R_SSPINT135_EN, R_SSPINT135_STATUS},
+ {9, 18, 1, R_SSPINT136_EN, R_SSPINT136_STATUS},
+};
+
+static void aspeed_2700ssp_intc_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass);
+
+ dc->desc = "ASPEED 2700 SSP INTC Controller";
+ aic->num_lines = 32;
+ aic->num_inpins = 10;
+ aic->num_outpins = 19;
+ aic->mem_size = 0x4000;
+ aic->nr_regs = 0x2B08 >> 2;
+ aic->reg_offset = 0x0;
+ aic->reg_ops = &aspeed_ssp_intc_ops;
+ aic->irq_table = aspeed_2700ssp_intc_irqs;
+ aic->irq_table_count = ARRAY_SIZE(aspeed_2700ssp_intc_irqs);
+}
+
+static const TypeInfo aspeed_2700ssp_intc_info = {
+ .name = TYPE_ASPEED_2700SSP_INTC,
+ .parent = TYPE_ASPEED_INTC,
+ .class_init = aspeed_2700ssp_intc_class_init,
+};
+
+static AspeedINTCIRQ aspeed_2700ssp_intcio_irqs[ASPEED_INTC_MAX_INPINS] = {
+ {0, 0, 1, R_SSPINT160_EN, R_SSPINT160_STATUS},
+ {1, 1, 1, R_SSPINT161_EN, R_SSPINT161_STATUS},
+ {2, 2, 1, R_SSPINT162_EN, R_SSPINT162_STATUS},
+ {3, 3, 1, R_SSPINT163_EN, R_SSPINT163_STATUS},
+ {4, 4, 1, R_SSPINT164_EN, R_SSPINT164_STATUS},
+ {5, 5, 1, R_SSPINT165_EN, R_SSPINT165_STATUS},
+};
+
+static void aspeed_2700ssp_intcio_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass);
+
+ dc->desc = "ASPEED 2700 SSP INTC IO Controller";
+ aic->num_lines = 32;
+ aic->num_inpins = 6;
+ aic->num_outpins = 6;
+ aic->mem_size = 0x400;
+ aic->nr_regs = 0x1d8 >> 2;
+ aic->reg_offset = 0;
+ aic->reg_ops = &aspeed_ssp_intcio_ops;
+ aic->irq_table = aspeed_2700ssp_intcio_irqs;
+ aic->irq_table_count = ARRAY_SIZE(aspeed_2700ssp_intcio_irqs);
+}
+
+static const TypeInfo aspeed_2700ssp_intcio_info = {
+ .name = TYPE_ASPEED_2700SSP_INTCIO,
+ .parent = TYPE_ASPEED_INTC,
+ .class_init = aspeed_2700ssp_intcio_class_init,
+};
+
+static AspeedINTCIRQ aspeed_2700tsp_intc_irqs[ASPEED_INTC_MAX_INPINS] = {
+ {0, 0, 10, R_TSPINT160_169_EN, R_TSPINT160_169_STATUS},
+ {1, 10, 1, R_TSPINT128_EN, R_TSPINT128_STATUS},
+ {2, 11, 1, R_TSPINT129_EN, R_TSPINT129_STATUS},
+ {3, 12, 1, R_TSPINT130_EN, R_TSPINT130_STATUS},
+ {4, 13, 1, R_TSPINT131_EN, R_TSPINT131_STATUS},
+ {5, 14, 1, R_TSPINT132_EN, R_TSPINT132_STATUS},
+ {6, 15, 1, R_TSPINT133_EN, R_TSPINT133_STATUS},
+ {7, 16, 1, R_TSPINT134_EN, R_TSPINT134_STATUS},
+ {8, 17, 1, R_TSPINT135_EN, R_TSPINT135_STATUS},
+ {9, 18, 1, R_TSPINT136_EN, R_TSPINT136_STATUS},
+};
+
+static void aspeed_2700tsp_intc_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass);
+
+ dc->desc = "ASPEED 2700 TSP INTC Controller";
+ aic->num_lines = 32;
+ aic->num_inpins = 10;
+ aic->num_outpins = 19;
+ aic->mem_size = 0x4000;
+ aic->nr_regs = 0x3B08 >> 2;
+ aic->reg_offset = 0;
+ aic->reg_ops = &aspeed_tsp_intc_ops;
+ aic->irq_table = aspeed_2700tsp_intc_irqs;
+ aic->irq_table_count = ARRAY_SIZE(aspeed_2700tsp_intc_irqs);
+}
+
+static const TypeInfo aspeed_2700tsp_intc_info = {
+ .name = TYPE_ASPEED_2700TSP_INTC,
+ .parent = TYPE_ASPEED_INTC,
+ .class_init = aspeed_2700tsp_intc_class_init,
+};
+
+static AspeedINTCIRQ aspeed_2700tsp_intcio_irqs[ASPEED_INTC_MAX_INPINS] = {
+ {0, 0, 1, R_TSPINT160_EN, R_TSPINT160_STATUS},
+ {1, 1, 1, R_TSPINT161_EN, R_TSPINT161_STATUS},
+ {2, 2, 1, R_TSPINT162_EN, R_TSPINT162_STATUS},
+ {3, 3, 1, R_TSPINT163_EN, R_TSPINT163_STATUS},
+ {4, 4, 1, R_TSPINT164_EN, R_TSPINT164_STATUS},
+ {5, 5, 1, R_TSPINT165_EN, R_TSPINT165_STATUS},
+};
+
+static void aspeed_2700tsp_intcio_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass);
+
+ dc->desc = "ASPEED 2700 TSP INTC IO Controller";
+ aic->num_lines = 32;
+ aic->num_inpins = 6;
+ aic->num_outpins = 6;
+ aic->mem_size = 0x400;
+ aic->nr_regs = 0x258 >> 2;
+ aic->reg_offset = 0x0;
+ aic->reg_ops = &aspeed_tsp_intcio_ops;
+ aic->irq_table = aspeed_2700tsp_intcio_irqs;
+ aic->irq_table_count = ARRAY_SIZE(aspeed_2700tsp_intcio_irqs);
+}
+
+static const TypeInfo aspeed_2700tsp_intcio_info = {
+ .name = TYPE_ASPEED_2700TSP_INTCIO,
+ .parent = TYPE_ASPEED_INTC,
+ .class_init = aspeed_2700tsp_intcio_class_init,
+};
+
static void aspeed_intc_register_types(void)
{
type_register_static(&aspeed_intc_info);
type_register_static(&aspeed_2700_intc_info);
type_register_static(&aspeed_2700_intcio_info);
+ type_register_static(&aspeed_2700ssp_intc_info);
+ type_register_static(&aspeed_2700ssp_intcio_info);
+ type_register_static(&aspeed_2700tsp_intc_info);
+ type_register_static(&aspeed_2700tsp_intcio_info);
}
type_init(aspeed_intc_register_types);
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 0d38f95..614528b 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -359,7 +359,7 @@ static const MemoryRegionOps aspeed_smc_flash_default_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 1,
- .max_access_size = 4,
+ .max_access_size = 8,
},
};
@@ -670,7 +670,7 @@ static const MemoryRegionOps aspeed_smc_flash_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 1,
- .max_access_size = 4,
+ .max_access_size = 8,
},
};
diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
index 9cae45a..973277b 100644
--- a/include/hw/arm/aspeed.h
+++ b/include/hw/arm/aspeed.h
@@ -40,6 +40,7 @@ struct AspeedMachineClass {
void (*i2c_init)(AspeedMachineState *bmc);
uint32_t uart_default;
bool sdhci_wp_inverted;
+ bool vbootrom;
};
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index f069d17..217ef0e 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -43,7 +43,7 @@
#include "hw/intc/arm_gicv3.h"
#define ASPEED_SPIS_NUM 3
-#define ASPEED_EHCIS_NUM 2
+#define ASPEED_EHCIS_NUM 4
#define ASPEED_WDTS_NUM 8
#define ASPEED_CPUS_NUM 4
#define ASPEED_MACS_NUM 4
@@ -59,6 +59,7 @@ struct AspeedSoCState {
MemoryRegion sram;
MemoryRegion spi_boot_container;
MemoryRegion spi_boot;
+ MemoryRegion vbootrom;
AddressSpace dram_as;
AspeedRtcState rtc;
AspeedTimerCtrlState timerctrl;
@@ -90,6 +91,8 @@ struct AspeedSoCState {
SerialMM uart[ASPEED_UARTS_NUM];
Clock *sysclk;
UnimplementedDeviceState iomem;
+ UnimplementedDeviceState iomem0;
+ UnimplementedDeviceState iomem1;
UnimplementedDeviceState video;
UnimplementedDeviceState emmc_boot_controller;
UnimplementedDeviceState dpmcu;
@@ -97,6 +100,7 @@ struct AspeedSoCState {
UnimplementedDeviceState espi;
UnimplementedDeviceState udc;
UnimplementedDeviceState sgpiom;
+ UnimplementedDeviceState ltpi;
UnimplementedDeviceState jtag[ASPEED_JTAG_NUM];
AspeedAPB2OPBState fsi[2];
};
@@ -142,6 +146,30 @@ struct Aspeed10x0SoCState {
ARMv7MState armv7m;
};
+struct Aspeed27x0SSPSoCState {
+ AspeedSoCState parent;
+ AspeedINTCState intc[2];
+ UnimplementedDeviceState ipc[2];
+ UnimplementedDeviceState scuio;
+
+ ARMv7MState armv7m;
+};
+
+#define TYPE_ASPEED27X0SSP_SOC "aspeed27x0ssp-soc"
+OBJECT_DECLARE_SIMPLE_TYPE(Aspeed27x0SSPSoCState, ASPEED27X0SSP_SOC)
+
+struct Aspeed27x0TSPSoCState {
+ AspeedSoCState parent;
+ AspeedINTCState intc[2];
+ UnimplementedDeviceState ipc[2];
+ UnimplementedDeviceState scuio;
+
+ ARMv7MState armv7m;
+};
+
+#define TYPE_ASPEED27X0TSP_SOC "aspeed27x0tsp-soc"
+OBJECT_DECLARE_SIMPLE_TYPE(Aspeed27x0TSPSoCState, ASPEED27X0TSP_SOC)
+
#define TYPE_ASPEED10X0_SOC "aspeed10x0-soc"
OBJECT_DECLARE_SIMPLE_TYPE(Aspeed10x0SoCState, ASPEED10X0_SOC)
@@ -169,8 +197,12 @@ struct AspeedSoCClass {
const char *aspeed_soc_cpu_type(AspeedSoCClass *sc);
enum {
+ ASPEED_DEV_VBOOTROM,
ASPEED_DEV_SPI_BOOT,
ASPEED_DEV_IOMEM,
+ ASPEED_DEV_IOMEM0,
+ ASPEED_DEV_IOMEM1,
+ ASPEED_DEV_LTPI,
ASPEED_DEV_UART0,
ASPEED_DEV_UART1,
ASPEED_DEV_UART2,
@@ -192,6 +224,8 @@ enum {
ASPEED_DEV_SPI2,
ASPEED_DEV_EHCI1,
ASPEED_DEV_EHCI2,
+ ASPEED_DEV_EHCI3,
+ ASPEED_DEV_EHCI4,
ASPEED_DEV_VIC,
ASPEED_DEV_INTC,
ASPEED_DEV_INTCIO,
@@ -249,6 +283,8 @@ enum {
ASPEED_DEV_SLIIO,
ASPEED_GIC_DIST,
ASPEED_GIC_REDIST,
+ ASPEED_DEV_IPC0,
+ ASPEED_DEV_IPC1,
};
qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev);
diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h
index 3727ba2..5128838 100644
--- a/include/hw/intc/aspeed_intc.h
+++ b/include/hw/intc/aspeed_intc.h
@@ -15,6 +15,11 @@
#define TYPE_ASPEED_INTC "aspeed.intc"
#define TYPE_ASPEED_2700_INTC TYPE_ASPEED_INTC "-ast2700"
#define TYPE_ASPEED_2700_INTCIO TYPE_ASPEED_INTC "io-ast2700"
+#define TYPE_ASPEED_2700SSP_INTC TYPE_ASPEED_INTC "-ast2700ssp"
+#define TYPE_ASPEED_2700SSP_INTCIO TYPE_ASPEED_INTC "io-ast2700ssp"
+#define TYPE_ASPEED_2700TSP_INTC TYPE_ASPEED_INTC "-ast2700tsp"
+#define TYPE_ASPEED_2700TSP_INTCIO TYPE_ASPEED_INTC "io-ast2700tsp"
+
OBJECT_DECLARE_TYPE(AspeedINTCState, AspeedINTCClass, ASPEED_INTC)
#define ASPEED_INTC_MAX_INPINS 10
diff --git a/pc-bios/README b/pc-bios/README
index f0f13e1..d009c37 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -89,6 +89,12 @@
more features over time as needed. The source code is available at:
https://github.com/google/vbootrom
+- ast27x0_bootrom.bin is a simplified, free (Apache 2.0) boot ROM for
+ ASPEED AST27x0 BMC SOC. It currently implements the bare minimum to
+ load, parse, initialize and run boot images stored in SPI flash, but may grow
+ more features over time as needed. The source code is available at:
+ https://github.com/google/vbootrom
+
- hppa-firmware.img (32-bit) and hppa-firmware64.img (64-bit) are firmware
files for the HP-PARISC (hppa) architecture.
They are built form the SeaBIOS-hppa sources, which is a fork of SeaBIOS
diff --git a/pc-bios/ast27x0_bootrom.bin b/pc-bios/ast27x0_bootrom.bin
new file mode 100644
index 0000000..0b9b3a2
--- /dev/null
+++ b/pc-bios/ast27x0_bootrom.bin
Binary files differ
diff --git a/pc-bios/meson.build b/pc-bios/meson.build
index 34d8cc4f..79bb2e1 100644
--- a/pc-bios/meson.build
+++ b/pc-bios/meson.build
@@ -28,6 +28,7 @@ if unpack_edk2_blobs
endif
blobs = [
+ 'ast27x0_bootrom.bin',
'bios.bin',
'bios-256k.bin',
'bios-microvm.bin',
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
index b317ad4..ab9df03 100644
--- a/tests/functional/meson.build
+++ b/tests/functional/meson.build
@@ -11,7 +11,8 @@ endif
# Timeouts for individual tests that can be slow e.g. with debugging enabled
test_timeouts = {
- 'aarch64_aspeed' : 600,
+ 'aarch64_aspeed_ast2700' : 600,
+ 'aarch64_aspeed_ast2700fc' : 600,
'aarch64_raspi4' : 480,
'aarch64_reverse_debug' : 180,
'aarch64_rme_virt' : 1200,
@@ -79,7 +80,8 @@ tests_aarch64_system_quick = [
]
tests_aarch64_system_thorough = [
- 'aarch64_aspeed',
+ 'aarch64_aspeed_ast2700',
+ 'aarch64_aspeed_ast2700fc',
'aarch64_raspi3',
'aarch64_raspi4',
'aarch64_replay',
diff --git a/tests/functional/test_aarch64_aspeed.py b/tests/functional/test_aarch64_aspeed_ast2700.py
index c7f3b3b..d02dc79 100755
--- a/tests/functional/test_aarch64_aspeed.py
+++ b/tests/functional/test_aarch64_aspeed_ast2700.py
@@ -18,22 +18,52 @@ class AST2x00MachineSDK(QemuSystemTest):
def do_test_aarch64_aspeed_sdk_start(self, image):
self.require_netdev('user')
self.vm.set_console()
+ self.vm.add_args('-device',
+ 'tmp105,bus=aspeed.i2c.bus.1,address=0x4d,id=tmp-test')
self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw',
'-net', 'nic', '-net', 'user', '-snapshot')
self.vm.launch()
+ def verify_vbootrom_firmware_flow(self):
+ wait_for_console_pattern(self, 'Found valid FIT image')
+ wait_for_console_pattern(self, '[uboot] loading')
+ wait_for_console_pattern(self, 'done')
+ wait_for_console_pattern(self, '[fdt] loading')
+ wait_for_console_pattern(self, 'done')
+ wait_for_console_pattern(self, '[tee] loading')
+ wait_for_console_pattern(self, 'done')
+ wait_for_console_pattern(self, '[atf] loading')
+ wait_for_console_pattern(self, 'done')
+ wait_for_console_pattern(self, 'Jumping to BL31 (Trusted Firmware-A)')
+
+ def verify_openbmc_boot_and_login(self, name):
wait_for_console_pattern(self, 'U-Boot 2023.10')
wait_for_console_pattern(self, '## Loading kernel from FIT Image')
wait_for_console_pattern(self, 'Starting kernel ...')
- ASSET_SDK_V905_AST2700 = Asset(
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/ast2700-a0-default-obmc.tar.gz',
- 'cfbbd1cce72f2a3b73b9080c41eecdadebb7077fba4f7806d72ac99f3e84b74a')
+ wait_for_console_pattern(self, f'{name} login:')
+ exec_command_and_wait_for_pattern(self, 'root', 'Password:')
+ exec_command_and_wait_for_pattern(self, '0penBmc', f'root@{name}:~#')
- ASSET_SDK_V905_AST2700A1 = Asset(
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/ast2700-default-obmc.tar.gz',
- 'c1f4496aec06743c812a6e9a1a18d032f34d62f3ddb6956e924fef62aa2046a5')
+ ASSET_SDK_V906_AST2700 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2700-a0-default-obmc.tar.gz',
+ '7247b6f19dbfb700686f8d9f723ac23f3eb229226c0589cb9b06b80d1b61f3cb')
+
+ ASSET_SDK_V906_AST2700A1 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2700-default-obmc.tar.gz',
+ 'f1d53e0be8a404ecce3e105f72bc50fa4e090ad13160ffa91b10a6e0233a9dc6')
+
+ def do_ast2700_i2c_test(self):
+ exec_command_and_wait_for_pattern(self,
+ 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device ',
+ 'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d')
+ exec_command_and_wait_for_pattern(self,
+ 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '0')
+ self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
+ property='temperature', value=18000)
+ exec_command_and_wait_for_pattern(self,
+ 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '18000')
def start_ast2700_test(self, name):
num_cpu = 4
@@ -73,38 +103,38 @@ class AST2x00MachineSDK(QemuSystemTest):
f'loader,addr=0x430000000,cpu-num={i}')
self.vm.add_args('-smp', str(num_cpu))
- self.vm.add_args('-device',
- 'tmp105,bus=aspeed.i2c.bus.1,address=0x4d,id=tmp-test')
self.do_test_aarch64_aspeed_sdk_start(
self.scratch_file(name, 'image-bmc'))
- wait_for_console_pattern(self, f'{name} login:')
-
- exec_command_and_wait_for_pattern(self, 'root', 'Password:')
- exec_command_and_wait_for_pattern(self, '0penBmc', f'root@{name}:~#')
-
- exec_command_and_wait_for_pattern(self,
- 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device ',
- 'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d')
- exec_command_and_wait_for_pattern(self,
- 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '0')
- self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
- property='temperature', value=18000)
- exec_command_and_wait_for_pattern(self,
- 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '18000')
+ def start_ast2700_test_vbootrom(self, name):
+ self.vm.add_args('-bios', 'ast27x0_bootrom.bin')
+ self.do_test_aarch64_aspeed_sdk_start(
+ self.scratch_file(name, 'image-bmc'))
- def test_aarch64_ast2700_evb_sdk_v09_05(self):
+ def test_aarch64_ast2700_evb_sdk_v09_06(self):
self.set_machine('ast2700-evb')
- self.archive_extract(self.ASSET_SDK_V905_AST2700)
+ self.archive_extract(self.ASSET_SDK_V906_AST2700)
self.start_ast2700_test('ast2700-a0-default')
+ self.verify_openbmc_boot_and_login('ast2700-a0-default')
+ self.do_ast2700_i2c_test()
- def test_aarch64_ast2700a1_evb_sdk_v09_05(self):
+ def test_aarch64_ast2700a1_evb_sdk_v09_06(self):
self.set_machine('ast2700a1-evb')
- self.archive_extract(self.ASSET_SDK_V905_AST2700A1)
+ self.archive_extract(self.ASSET_SDK_V906_AST2700A1)
self.start_ast2700_test('ast2700-default')
+ self.verify_openbmc_boot_and_login('ast2700-default')
+ self.do_ast2700_i2c_test()
+
+ def test_aarch64_ast2700a1_evb_sdk_vbootrom_v09_06(self):
+ self.set_machine('ast2700a1-evb')
+ self.archive_extract(self.ASSET_SDK_V906_AST2700A1)
+ self.start_ast2700_test_vbootrom('ast2700-default')
+ self.verify_vbootrom_firmware_flow()
+ self.verify_openbmc_boot_and_login('ast2700-default')
+ self.do_ast2700_i2c_test()
if __name__ == '__main__':
QemuSystemTest.main()
diff --git a/tests/functional/test_aarch64_aspeed_ast2700fc.py b/tests/functional/test_aarch64_aspeed_ast2700fc.py
new file mode 100755
index 0000000..b85370e
--- /dev/null
+++ b/tests/functional/test_aarch64_aspeed_ast2700fc.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots the ASPEED SoCs with firmware
+#
+# Copyright (C) 2022 ASPEED Technology Inc
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+
+from qemu_test import QemuSystemTest, Asset
+from qemu_test import wait_for_console_pattern
+from qemu_test import exec_command_and_wait_for_pattern
+
+
+class AST2x00MachineSDK(QemuSystemTest):
+
+ def do_test_aarch64_aspeed_sdk_start(self, image):
+ self.require_netdev('user')
+ self.vm.set_console()
+ self.vm.add_args('-device',
+ 'tmp105,bus=aspeed.i2c.bus.1,address=0x4d,id=tmp-test')
+ self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw',
+ '-net', 'nic', '-net', 'user', '-snapshot')
+
+ self.vm.launch()
+
+ def verify_openbmc_boot_and_login(self, name):
+ wait_for_console_pattern(self, 'U-Boot 2023.10')
+ wait_for_console_pattern(self, '## Loading kernel from FIT Image')
+ wait_for_console_pattern(self, 'Starting kernel ...')
+
+ wait_for_console_pattern(self, f'{name} login:')
+ exec_command_and_wait_for_pattern(self, 'root', 'Password:')
+ exec_command_and_wait_for_pattern(self, '0penBmc', f'root@{name}:~#')
+
+ ASSET_SDK_V906_AST2700 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2700-default-obmc.tar.gz',
+ 'f1d53e0be8a404ecce3e105f72bc50fa4e090ad13160ffa91b10a6e0233a9dc6')
+
+ def do_ast2700_i2c_test(self):
+ exec_command_and_wait_for_pattern(self,
+ 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device ',
+ 'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d')
+ exec_command_and_wait_for_pattern(self,
+ 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '0')
+ self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
+ property='temperature', value=18000)
+ exec_command_and_wait_for_pattern(self,
+ 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '18000')
+
+ def do_ast2700fc_ssp_test(self):
+ self.vm.shutdown()
+ self.vm.set_console(console_index=1)
+ self.vm.launch()
+
+ exec_command_and_wait_for_pattern(self, '\012', 'ssp:~$')
+ exec_command_and_wait_for_pattern(self, 'version',
+ 'Zephyr version 3.7.1')
+ exec_command_and_wait_for_pattern(self, 'md 72c02000 1',
+ '[72c02000] 06010103')
+
+ def do_ast2700fc_tsp_test(self):
+ self.vm.shutdown()
+ self.vm.set_console(console_index=2)
+ self.vm.launch()
+
+ exec_command_and_wait_for_pattern(self, '\012', 'tsp:~$')
+ exec_command_and_wait_for_pattern(self, 'version',
+ 'Zephyr version 3.7.1')
+ exec_command_and_wait_for_pattern(self, 'md 72c02000 1',
+ '[72c02000] 06010103')
+
+ def start_ast2700fc_test(self, name):
+ ca35_core = 4
+ uboot_size = os.path.getsize(self.scratch_file(name,
+ 'u-boot-nodtb.bin'))
+ uboot_dtb_load_addr = hex(0x400000000 + uboot_size)
+
+ load_images_list = [
+ {
+ 'addr': '0x400000000',
+ 'file': self.scratch_file(name,
+ 'u-boot-nodtb.bin')
+ },
+ {
+ 'addr': str(uboot_dtb_load_addr),
+ 'file': self.scratch_file(name, 'u-boot.dtb')
+ },
+ {
+ 'addr': '0x430000000',
+ 'file': self.scratch_file(name, 'bl31.bin')
+ },
+ {
+ 'addr': '0x430080000',
+ 'file': self.scratch_file(name, 'optee',
+ 'tee-raw.bin')
+ }
+ ]
+
+ for load_image in load_images_list:
+ addr = load_image['addr']
+ file = load_image['file']
+ self.vm.add_args('-device',
+ f'loader,force-raw=on,addr={addr},file={file}')
+
+ for i in range(ca35_core):
+ self.vm.add_args('-device',
+ f'loader,addr=0x430000000,cpu-num={i}')
+
+ load_elf_list = {
+ 'ssp': self.scratch_file(name, 'zephyr-aspeed-ssp.elf'),
+ 'tsp': self.scratch_file(name, 'zephyr-aspeed-tsp.elf')
+ }
+
+ for cpu_num, key in enumerate(load_elf_list, start=4):
+ file = load_elf_list[key]
+ self.vm.add_args('-device',
+ f'loader,file={file},cpu-num={cpu_num}')
+
+ self.do_test_aarch64_aspeed_sdk_start(
+ self.scratch_file(name, 'image-bmc'))
+
+ def test_aarch64_ast2700fc_sdk_v09_06(self):
+ self.set_machine('ast2700fc')
+
+ self.archive_extract(self.ASSET_SDK_V906_AST2700)
+ self.start_ast2700fc_test('ast2700-default')
+ self.verify_openbmc_boot_and_login('ast2700-default')
+ self.do_ast2700_i2c_test()
+ self.do_ast2700fc_ssp_test()
+ self.do_ast2700fc_tsp_test()
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_arm_aspeed_ast1030.py b/tests/functional/test_arm_aspeed_ast1030.py
index d45d9f7..77037f0 100755
--- a/tests/functional/test_arm_aspeed_ast1030.py
+++ b/tests/functional/test_arm_aspeed_ast1030.py
@@ -12,17 +12,17 @@ from qemu_test import exec_command_and_wait_for_pattern
class AST1030Machine(LinuxKernelTest):
- ASSET_ZEPHYR_1_04 = Asset(
+ ASSET_ZEPHYR_3_00 = Asset(
('https://github.com/AspeedTech-BMC'
- '/zephyr/releases/download/v00.01.04/ast1030-evb-demo.zip'),
- '4ac6210adcbc61294927918707c6762483fd844dde5e07f3ba834ad1f91434d3')
+ '/zephyr/releases/download/v00.03.00/ast1030-evb-demo.zip'),
+ '37fe3ecd4a1b9d620971a15b96492a81093435396eeac69b6f3e384262ff555f')
- def test_ast1030_zephyros_1_04(self):
+ def test_ast1030_zephyros_3_00(self):
self.set_machine('ast1030-evb')
kernel_name = "ast1030-evb-demo/zephyr.elf"
kernel_file = self.archive_extract(
- self.ASSET_ZEPHYR_1_04, member=kernel_name)
+ self.ASSET_ZEPHYR_3_00, member=kernel_name)
self.vm.set_console()
self.vm.add_args('-kernel', kernel_file, '-nographic')
diff --git a/tests/functional/test_arm_aspeed_ast2500.py b/tests/functional/test_arm_aspeed_ast2500.py
index a3b4457..6923fe8 100755
--- a/tests/functional/test_arm_aspeed_ast2500.py
+++ b/tests/functional/test_arm_aspeed_ast2500.py
@@ -37,14 +37,14 @@ class AST2500Machine(AspeedTest):
self.do_test_arm_aspeed_buildroot_poweroff()
- ASSET_SDK_V806_AST2500 = Asset(
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2500-default-obmc.tar.gz',
- 'e1755f3cadff69190438c688d52dd0f0d399b70a1e14b1d3d5540fc4851d38ca')
+ ASSET_SDK_V906_AST2500 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2500-default-obmc.tar.gz',
+ '542db84645b4efd8aed50385d7f4dd1caff379a987032311cfa7b563a3addb2a')
def test_arm_ast2500_evb_sdk(self):
self.set_machine('ast2500-evb')
- self.archive_extract(self.ASSET_SDK_V806_AST2500)
+ self.archive_extract(self.ASSET_SDK_V906_AST2500)
self.do_test_arm_aspeed_sdk_start(
self.scratch_file("ast2500-default", "image-bmc"))
diff --git a/tests/functional/test_arm_aspeed_ast2600.py b/tests/functional/test_arm_aspeed_ast2600.py
index 5ef52f0..fdae4c9 100755
--- a/tests/functional/test_arm_aspeed_ast2600.py
+++ b/tests/functional/test_arm_aspeed_ast2600.py
@@ -97,26 +97,27 @@ class AST2600Machine(AspeedTest):
self.do_test_arm_aspeed_buildroot_poweroff()
- ASSET_SDK_V806_AST2600_A2 = Asset(
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2600-a2-obmc.tar.gz',
- '9083506135f622d5e7351fcf7d4e1c7125cee5ba16141220c0ba88931f3681a4')
+ ASSET_SDK_V906_AST2600 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2600-default-obmc.tar.gz',
+ '768d76e247896ad78c154b9cff4f766da2ce65f217d620b286a4a03a8a4f68f5')
def test_arm_ast2600_evb_sdk(self):
self.set_machine('ast2600-evb')
- self.archive_extract(self.ASSET_SDK_V806_AST2600_A2)
+ self.archive_extract(self.ASSET_SDK_V906_AST2600)
self.vm.add_args('-device',
'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test')
self.vm.add_args('-device',
'ds1338,bus=aspeed.i2c.bus.5,address=0x32')
self.do_test_arm_aspeed_sdk_start(
- self.scratch_file("ast2600-a2", "image-bmc"))
+ self.scratch_file("ast2600-default", "image-bmc"))
- self.wait_for_console_pattern('ast2600-a2 login:')
+ self.wait_for_console_pattern('ast2600-default login:')
exec_command_and_wait_for_pattern(self, 'root', 'Password:')
- exec_command_and_wait_for_pattern(self, '0penBmc', 'root@ast2600-a2:~#')
+ exec_command_and_wait_for_pattern(self, '0penBmc',
+ 'root@ast2600-default:~#')
exec_command_and_wait_for_pattern(self,
'echo lm75 0x4d > /sys/class/i2c-dev/i2c-5/device/new_device',