From: Jamin Lin <jamin_lin@aspeedtech.com>
To: "Cédric Le Goater" <clg@kaod.org>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Steven Lee" <steven_lee@aspeedtech.com>,
"Troy Lee" <leetroy@gmail.com>,
"Kane Chen" <kane_chen@aspeedtech.com>,
"Andrew Jeffery" <andrew@codeconstruct.com.au>,
"Joel Stanley" <joel@jms.id.au>,
"Pierrick Bouvier" <pierrick.bouvier@oss.qualcomm.com>,
"open list:ASPEED BMCs" <qemu-arm@nongnu.org>,
"open list:All patches CC here" <qemu-devel@nongnu.org>
Cc: Jamin Lin <jamin_lin@aspeedtech.com>, Troy Lee <troy_lee@aspeedtech.com>
Subject: [PATCH v2 6/9] hw/arm/aspeed: Introduce AST1040 A0 SoC model
Date: Mon, 25 May 2026 05:30:45 +0000 [thread overview]
Message-ID: <20260525053036.3305181-7-jamin_lin@aspeedtech.com> (raw)
In-Reply-To: <20260525053036.3305181-1-jamin_lin@aspeedtech.com>
The AST1040 is based on an ARM Cortex-M4F CPU core. Since QEMU
currently does not provide Cortex-M4F support, use the existing
Cortex-M4 CPU model as a temporary replacement.
This initial implementation provides the basic infrastructure
required to boot firmware and run a minimal firmware shell,
including:
- ARM Cortex-M4 CPU integration
- NVIC interrupt controller support
- Internal HyperRAM and SRAM memory regions
- SCU integration
- UART devices and interrupt wiring
AST1040 SCU behavior is compatible with the AST2700 SCUIO model,
so reuse the existing AST2700 SCUIO implementation directly
instead of introducing another identical SCU model. This reduces
duplicate code and helps minimize long-term codebase maintenance.
Several peripherals are currently modeled as unimplemented
devices and can be added incrementally in future updates.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/arm/aspeed_ast1040.c | 254 ++++++++++++++++++++++++++++++++++++++++
hw/arm/meson.build | 3 +-
2 files changed, 256 insertions(+), 1 deletion(-)
create mode 100644 hw/arm/aspeed_ast1040.c
diff --git a/hw/arm/aspeed_ast1040.c b/hw/arm/aspeed_ast1040.c
new file mode 100644
index 0000000000..8efcdad8f6
--- /dev/null
+++ b/hw/arm/aspeed_ast1040.c
@@ -0,0 +1,254 @@
+/*
+ * ASPEED AST1040 SoC
+ *
+ * Copyright (C) 2026 ASPEED Technology Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "system/address-spaces.h"
+#include "system/system.h"
+#include "hw/core/qdev-clock.h"
+#include "hw/misc/unimp.h"
+#include "hw/arm/aspeed_soc.h"
+
+static const hwaddr aspeed_soc_ast1040_memmap[] = {
+ [ASPEED_DEV_SRAM1] = 0x00000000, /* Hyper RAM */
+ [ASPEED_DEV_FMC] = 0x74000000,
+ [ASPEED_DEV_SPI0] = 0x74010000,
+ [ASPEED_DEV_SPI1] = 0x74020000,
+ [ASPEED_DEV_PWM] = 0x740C0000,
+ [ASPEED_DEV_UDC] = 0x74120000,
+ [ASPEED_DEV_SRAM0] = 0x74B80000,
+ [ASPEED_DEV_ADC] = 0x74C00000,
+ [ASPEED_DEV_JTAG0] = 0x74C01000,
+ [ASPEED_DEV_SCU] = 0x74C02000,
+ [ASPEED_DEV_ESPI] = 0x74C05000,
+ [ASPEED_DEV_JTAG1] = 0x74C09000,
+ [ASPEED_DEV_GPIO] = 0x74C0B000,
+ [ASPEED_DEV_SGPIOM0] = 0x74C0C000,
+ [ASPEED_DEV_SGPIOM1] = 0x74C0D000,
+ [ASPEED_DEV_I2C] = 0x74C0F000,
+ [ASPEED_DEV_I3C] = 0x74C20000,
+ [ASPEED_DEV_UART0] = 0x74C33000,
+ [ASPEED_DEV_UART1] = 0x74C33100,
+ [ASPEED_DEV_UART2] = 0x74C33200,
+ [ASPEED_DEV_UART3] = 0x74C33300,
+ [ASPEED_DEV_UART4] = 0x74C33400,
+ [ASPEED_DEV_UART5] = 0x74C33500,
+ [ASPEED_DEV_UART6] = 0x74C33600,
+ [ASPEED_DEV_UART7] = 0x74C33700,
+ [ASPEED_DEV_UART8] = 0x74C33800,
+ [ASPEED_DEV_UART9] = 0x74C33900,
+ [ASPEED_DEV_UART10] = 0x74C33A00,
+ [ASPEED_DEV_UART11] = 0x74C33B00,
+ [ASPEED_DEV_UART12] = 0x74C33C00,
+ [ASPEED_DEV_WDT] = 0x74C37000,
+ [ASPEED_DEV_TIMER1] = 0x74C3A000,
+};
+
+static const int aspeed_soc_ast1040_irqmap[] = {
+ [ASPEED_DEV_ESPI] = 10,
+ [ASPEED_DEV_I2C] = 64, /* 64 ~ 77 */
+ [ASPEED_DEV_ADC] = 80,
+ [ASPEED_DEV_GPIO] = 82,
+ [ASPEED_DEV_SGPIOM0] = 85,
+ [ASPEED_DEV_TIMER1] = 92,
+ [ASPEED_DEV_I3C] = 96, /* 96 ~ 103 */
+ [ASPEED_DEV_WDT] = 112,
+ [ASPEED_DEV_FMC] = 121,
+ [ASPEED_DEV_SPI0] = 122,
+ [ASPEED_DEV_SPI1] = 123,
+ [ASPEED_DEV_PWM] = 125,
+ [ASPEED_DEV_UART0] = 135,
+ [ASPEED_DEV_UART1] = 136,
+ [ASPEED_DEV_UART2] = 137,
+ [ASPEED_DEV_UART3] = 138,
+ [ASPEED_DEV_UART4] = 139,
+ [ASPEED_DEV_UART5] = 140,
+ [ASPEED_DEV_UART6] = 141,
+ [ASPEED_DEV_UART7] = 142,
+ [ASPEED_DEV_UART8] = 143,
+ [ASPEED_DEV_UART9] = 144,
+ [ASPEED_DEV_UART10] = 145,
+ [ASPEED_DEV_UART11] = 146,
+ [ASPEED_DEV_UART12] = 147,
+ [ASPEED_DEV_JTAG0] = 162,
+};
+
+static qemu_irq aspeed_soc_ast1040_get_irq(AspeedSoCState *s, int dev)
+{
+ Aspeed10x0SoCState *a = ASPEED10X0_SOC(s);
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+
+ return qdev_get_gpio_in(DEVICE(&a->armv7m), sc->irqmap[dev]);
+}
+
+static void aspeed_soc_ast1040_init(Object *obj)
+{
+ Aspeed10x0SoCState *a = ASPEED10X0_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);
+
+ s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0);
+
+ /* AST1040 uses the AST2700 SCUIO model */
+ object_initialize_child(obj, "scu", &s->scu, TYPE_ASPEED_2700_SCUIO);
+ qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", sc->silicon_rev);
+
+ object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu), "hw-strap1");
+ object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu), "hw-strap2");
+
+ for (i = 0; i < sc->uarts_num; i++) {
+ object_initialize_child(obj, "uart[*]", &s->uart[i], TYPE_SERIAL_MM);
+ }
+
+ object_initialize_child(obj, "pwm", &s->pwm, TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "espi", &s->espi, TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "udc", &s->udc, TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "sgpiom[0]", &s->sgpiom[0],
+ TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "sgpiom[1]", &s->sgpiom[1],
+ TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "jtag[0]", &s->jtag[0],
+ TYPE_UNIMPLEMENTED_DEVICE);
+ object_initialize_child(obj, "jtag[1]", &s->jtag[1],
+ TYPE_UNIMPLEMENTED_DEVICE);
+}
+
+static void aspeed_soc_ast1040_realize(DeviceState *dev_soc, Error **errp)
+{
+ Aspeed10x0SoCState *a = ASPEED10X0_SOC(dev_soc);
+ AspeedSoCState *s = ASPEED_SOC(dev_soc);
+ AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
+ g_autofree char *hyperram_name = NULL;
+ g_autofree char *sram_name = NULL;
+ DeviceState *armv7m;
+ Error *err = NULL;
+ int uart;
+ int i;
+
+ if (!clock_has_source(s->sysclk)) {
+ error_setg(errp, "sysclk clock must be wired up by the board code");
+ return;
+ }
+
+ /* AST1040 CPU 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->valid_cpu_types));
+ 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);
+
+ /* Internal SRAM */
+ sram_name = g_strdup_printf("aspeed.sram.%d",
+ CPU(a->armv7m.cpu)->cpu_index);
+ memory_region_init_ram(&s->sram[0], OBJECT(s), sram_name,
+ sc->sram_size[0], &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SRAM0],
+ &s->sram[0]);
+
+ /* Internal Hyper RAM */
+ hyperram_name = g_strdup_printf("aspeed.hyperram.%d",
+ CPU(a->armv7m.cpu)->cpu_index);
+ memory_region_init_ram(&s->sram[1], OBJECT(s), hyperram_name,
+ sc->sram_size[1], &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SRAM1],
+ &s->sram[1]);
+
+ /* SCU */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) {
+ return;
+ }
+ aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->scu), 0,
+ sc->memmap[ASPEED_DEV_SCU]);
+
+ /* UART */
+ for (i = 0, uart = sc->uarts_base; i < sc->uarts_num; i++, uart++) {
+ if (!aspeed_soc_uart_realize(s->memory, &s->uart[i],
+ sc->memmap[uart], errp)) {
+ return;
+ }
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
+ aspeed_soc_ast1040_get_irq(s, uart));
+ }
+
+ /* Unimplemented peripherals */
+ aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->pwm),
+ "aspeed.pwm",
+ sc->memmap[ASPEED_DEV_PWM], 0x10000);
+
+ aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->espi),
+ "aspeed.espi",
+ sc->memmap[ASPEED_DEV_ESPI], 0x1000);
+
+ aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->udc),
+ "aspeed.udc",
+ sc->memmap[ASPEED_DEV_UDC], 0x4000);
+
+ aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->sgpiom[0]),
+ "aspeed.sgpiom0",
+ sc->memmap[ASPEED_DEV_SGPIOM0], 0x1000);
+
+ aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->sgpiom[1]),
+ "aspeed.sgpiom1",
+ sc->memmap[ASPEED_DEV_SGPIOM1], 0x1000);
+
+ aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->jtag[0]),
+ "aspeed.jtag0",
+ sc->memmap[ASPEED_DEV_JTAG0], 0x100);
+
+ aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->jtag[1]),
+ "aspeed.jtag1",
+ sc->memmap[ASPEED_DEV_JTAG1], 0x100);
+}
+
+static void aspeed_soc_ast1040_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_ast1040_realize;
+
+ sc->valid_cpu_types = valid_cpu_types;
+ sc->silicon_rev = AST1040_A0_SILICON_REV;
+ sc->sram_size[0] = 128 * KiB;
+ sc->sram_size[1] = 16 * MiB; /* Hyper RAM */
+ sc->uarts_num = 13;
+ sc->uarts_base = ASPEED_DEV_UART0;
+ sc->irqmap = aspeed_soc_ast1040_irqmap;
+ sc->memmap = aspeed_soc_ast1040_memmap;
+ sc->num_cpus = 1;
+}
+
+static const TypeInfo aspeed_soc_ast1040_types[] = {
+ {
+ .name = "ast1040-a0",
+ .parent = TYPE_ASPEED10X0_SOC,
+ .instance_init = aspeed_soc_ast1040_init,
+ .class_init = aspeed_soc_ast1040_class_init,
+ }
+};
+
+DEFINE_TYPES(aspeed_soc_ast1040_types)
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index 80068f70bb..fa3a848492 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -62,7 +62,8 @@ arm_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
'aspeed_ast2600_gb200nvl.c',
'aspeed_ast2600_rainier.c',
'aspeed_ast10x0.c',
- 'aspeed_ast10x0_evb.c'))
+ 'aspeed_ast10x0_evb.c',
+ 'aspeed_ast1040.c'))
arm_common_ss.add(when: ['CONFIG_ASPEED_SOC', 'TARGET_AARCH64'], if_true: files(
'aspeed_ast1700.c',
'aspeed_ast27x0.c',
--
2.43.0
next prev parent reply other threads:[~2026-05-25 5:32 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-25 5:30 [PATCH v2 0/9] hw/arm/aspeed: Introduce initial AST1040 support Jamin Lin
2026-05-25 5:30 ` [PATCH v2 1/9] hw/arm/aspeed: Convert SRAM MemoryRegion to array type Jamin Lin
2026-05-25 5:30 ` [PATCH v2 2/9] hw/arm/aspeed: Convert SRAM size definition " Jamin Lin
2026-05-25 5:30 ` [PATCH v2 3/9] hw/arm/aspeed: Rename SRAM memmap entry for multi-SRAM support Jamin Lin
2026-05-25 5:30 ` [PATCH v2 4/9] hw/arm/aspeed: Consolidate secure SRAM into SRAM array Jamin Lin
2026-05-25 5:30 ` [PATCH v2 5/9] hw/misc/aspeed_scu: Add AST1040 A0 silicon revision ID Jamin Lin
2026-05-25 5:30 ` Jamin Lin [this message]
2026-05-25 5:30 ` [PATCH v2 7/9] hw/arm/aspeed: Add AST1040 EVB machine model Jamin Lin
2026-05-25 5:30 ` [PATCH v2 8/9] tests/function/aspeed: Add AST1040 functional test Jamin Lin
2026-05-25 5:30 ` [PATCH v2 9/9] docs/system/arm/aspeed: Add AST1040 Bridge IC evaluation board Jamin Lin
2026-05-26 4:58 ` [PATCH v2 0/9] hw/arm/aspeed: Introduce initial AST1040 support Cédric Le Goater
2026-05-26 5:02 ` Cédric Le Goater
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260525053036.3305181-7-jamin_lin@aspeedtech.com \
--to=jamin_lin@aspeedtech.com \
--cc=andrew@codeconstruct.com.au \
--cc=clg@kaod.org \
--cc=joel@jms.id.au \
--cc=kane_chen@aspeedtech.com \
--cc=leetroy@gmail.com \
--cc=peter.maydell@linaro.org \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=steven_lee@aspeedtech.com \
--cc=troy_lee@aspeedtech.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.