:p
atchew
Login
The following changes since commit 3c0b42c68f98fb276fa248012642be8cbf2cab70: Merge tag 'pull-request-2025-10-21' of https://gitlab.com/thuth/qemu into staging (2025-10-21 08:59:35 -0500) are available in the Git repository at: https://github.com/legoater/qemu/ tags/pull-aspeed-20251022 for you to fetch changes up to d7bd42a740d0e8887540d7b450d0bdb2d6ba31ea: hw/arm/aspeed: Remove ast2700fc self-aliasing (2025-10-22 08:14:09 +0200) ---------------------------------------------------------------- aspeed queue: * Improve AST2700 co-processor models * Add vbootrom support to the ast2700fc multi-soc machine * Bump SDK version to v09.08 for the ast2700fc machine * Add 32 bits property for Aspeed GPIOs * Change ast2600-evb machine flash model to w25q512jv ---------------------------------------------------------------- Cédric Le Goater (1): hw/arm/aspeed: ast2600-evb: Use w25q512jv flash model Felix Wu (2): hw/gpio: Add property for ASPEED GPIO in 32 bits basis tests/qtest: Add qtest for for ASPEED GPIO gpio-set property Jamin Lin (12): hw/arm/aspeed_ast27x0-ssp: Add SDRAM region and fix naming and size to 512MB hw/arm/aspeed_ast27x0-tsp: Add SDRAM region and fix naming and size to 512MB hw/arm/ast27x0: Add SRAM link and alias mapping for SSP coprocessor hw/arm/ast27x0: Add SRAM link and alias mapping for TSP coprocessor hw/arm/ast27x0: Share single SCU instance across PSP, SSP, and TSP hw/arm/ast27x0: Share single UART set across PSP, SSP, and TSP hw/arm/aspeed_ast27x0-fc: Map FMC0 flash contents into CA35 boot ROM hw/arm/aspeed_ast27x0-fc: Add VBOOTROM support tests/functional/aarch64/ast2700fc: Update test ASPEED SDK v09.08 tests/functional/aarch64/ast2700fc: Add eth2 network interface check in PCIe test tests/functional/aarch64/ast2700fc: Move coprocessor image loading to common function tests/functional/aarch64/ast2700fc: Add vbootrom test Philippe Mathieu-Daudé (1): hw/arm/aspeed: Remove ast2700fc self-aliasing include/hw/arm/aspeed_coprocessor.h | 14 +-- include/qobject/qdict.h | 1 + hw/arm/aspeed.c | 4 +- hw/arm/aspeed_ast27x0-fc.c | 56 ++++++++---- hw/arm/aspeed_ast27x0-ssp.c | 69 +++++++------- hw/arm/aspeed_ast27x0-tsp.c | 69 +++++++------- hw/arm/aspeed_coprocessor_common.c | 7 ++ hw/gpio/aspeed_gpio.c | 57 ++++++++++++ qobject/qdict.c | 13 +++ tests/qtest/aspeed_gpio-test.c | 105 ++++++++++++++++++++-- tests/qtest/aspeed_smc-test.c | 4 +- tests/functional/aarch64/test_aspeed_ast2700fc.py | 51 +++++++---- 12 files changed, 331 insertions(+), 119 deletions(-)
From: Jamin Lin <jamin_lin@aspeedtech.com> Previously, the SSP memory was incorrectly modeled as "SRAM" with a 32 MB size. This change introduces a new sdram field in AspeedCoprocessorState and updates the realization logic accordingly. Rename from SRAM to SDRAM and correct size from 32MB to 512MB to match hardware. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251015062210.3128710-2-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- include/hw/arm/aspeed_coprocessor.h | 1 + hw/arm/aspeed_ast27x0-ssp.c | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/include/hw/arm/aspeed_coprocessor.h b/include/hw/arm/aspeed_coprocessor.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/arm/aspeed_coprocessor.h +++ b/include/hw/arm/aspeed_coprocessor.h @@ -XXX,XX +XXX,XX @@ struct AspeedCoprocessorState { DeviceState parent; MemoryRegion *memory; + MemoryRegion sdram; MemoryRegion sram; Clock *sysclk; diff --git a/hw/arm/aspeed_ast27x0-ssp.c b/hw/arm/aspeed_ast27x0-ssp.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0-ssp.c +++ b/hw/arm/aspeed_ast27x0-ssp.c @@ -XXX,XX +XXX,XX @@ #include "hw/arm/aspeed_soc.h" #include "hw/arm/aspeed_coprocessor.h" -#define AST2700_SSP_RAM_SIZE (32 * MiB) +#define AST2700_SSP_SDRAM_SIZE (512 * MiB) static const hwaddr aspeed_soc_ast27x0ssp_memmap[] = { - [ASPEED_DEV_SRAM] = 0x00000000, + [ASPEED_DEV_SDRAM] = 0x00000000, [ASPEED_DEV_INTC] = 0x72100000, [ASPEED_DEV_SCU] = 0x72C02000, [ASPEED_DEV_SCUIO] = 0x74C02000, @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp) AspeedCoprocessorState *s = ASPEED_COPROCESSOR(dev_soc); AspeedCoprocessorClass *sc = ASPEED_COPROCESSOR_GET_CLASS(s); DeviceState *armv7m; - g_autofree char *sram_name = NULL; + g_autofree char *sdram_name = NULL; int uart; int i; @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp) 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, - AST2700_SSP_RAM_SIZE, errp)) { + /* SDRAM */ + sdram_name = g_strdup_printf("aspeed.sdram.%d", + CPU(a->armv7m.cpu)->cpu_index); + if (!memory_region_init_ram(&s->sdram, OBJECT(s), sdram_name, + AST2700_SSP_SDRAM_SIZE, errp)) { return; } memory_region_add_subregion(s->memory, - sc->memmap[ASPEED_DEV_SRAM], - &s->sram); + sc->memmap[ASPEED_DEV_SDRAM], + &s->sdram); /* SCU */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { -- 2.51.0
From: Jamin Lin <jamin_lin@aspeedtech.com> Previously, the TSP memory was incorrectly modeled as "SRAM" with a 32 MB size. Rename from SRAM to SDRAM and correct size from 32MB to 512MB to match hardware. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251015062210.3128710-3-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast27x0-tsp.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/hw/arm/aspeed_ast27x0-tsp.c b/hw/arm/aspeed_ast27x0-tsp.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0-tsp.c +++ b/hw/arm/aspeed_ast27x0-tsp.c @@ -XXX,XX +XXX,XX @@ #include "hw/arm/aspeed_soc.h" #include "hw/arm/aspeed_coprocessor.h" -#define AST2700_TSP_RAM_SIZE (32 * MiB) +#define AST2700_TSP_SDRAM_SIZE (512 * MiB) static const hwaddr aspeed_soc_ast27x0tsp_memmap[] = { - [ASPEED_DEV_SRAM] = 0x00000000, + [ASPEED_DEV_SDRAM] = 0x00000000, [ASPEED_DEV_INTC] = 0x72100000, [ASPEED_DEV_SCU] = 0x72C02000, [ASPEED_DEV_SCUIO] = 0x74C02000, @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp) AspeedCoprocessorState *s = ASPEED_COPROCESSOR(dev_soc); AspeedCoprocessorClass *sc = ASPEED_COPROCESSOR_GET_CLASS(s); DeviceState *armv7m; - g_autofree char *sram_name = NULL; + g_autofree char *sdram_name = NULL; int uart; int i; @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp) 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, - AST2700_TSP_RAM_SIZE, errp)) { + /* SDRAM */ + sdram_name = g_strdup_printf("aspeed.sdram.%d", + CPU(a->armv7m.cpu)->cpu_index); + if (!memory_region_init_ram(&s->sdram, OBJECT(s), sdram_name, + AST2700_TSP_SDRAM_SIZE, errp)) { return; } memory_region_add_subregion(s->memory, - sc->memmap[ASPEED_DEV_SRAM], - &s->sram); + sc->memmap[ASPEED_DEV_SDRAM], + &s->sdram); /* SCU */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { -- 2.51.0
From: Jamin Lin <jamin_lin@aspeedtech.com> AST2700 has a 128KB SRAM, physically mapped at 0x10000000–0x1001FFFF for the PSP (CA35) processor. The SSP coprocessor shares this same SRAM but accesses it through a different address window at 0x70000000–0x7001FFFF. To model this shared-memory behavior in QEMU, this commit introduces a linked SRAM property and alias mapping between the PSP and SSP subsystems. Changes include: - Add a "MemoryRegion *sram" link and "MemoryRegion sram_alias" to AspeedCoprocessorState. - Register the new "sram" property in aspeed_coprocessor_common.c. - In aspeed_ast27x0-fc.c, connect the SSP coprocessor’s "sram" link to the PSP’s SRAM region. - In aspeed_ast27x0-ssp.c, create an alias mapping for SRAM at 0x70000000 – 0x7001FFFF in the SSP’s memory map. This ensures that the SSP can correctly access the shared SRAM contents through its own address space while maintaining a consistent physical backing region. It also guarantees that the SRAM is realized before the SSP device, ensuring successful alias setup. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251015062210.3128710-4-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- include/hw/arm/aspeed_coprocessor.h | 3 ++- hw/arm/aspeed_ast27x0-fc.c | 4 ++++ hw/arm/aspeed_ast27x0-ssp.c | 7 +++++++ hw/arm/aspeed_coprocessor_common.c | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/hw/arm/aspeed_coprocessor.h b/include/hw/arm/aspeed_coprocessor.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/arm/aspeed_coprocessor.h +++ b/include/hw/arm/aspeed_coprocessor.h @@ -XXX,XX +XXX,XX @@ struct AspeedCoprocessorState { MemoryRegion *memory; MemoryRegion sdram; - MemoryRegion sram; + MemoryRegion *sram; + MemoryRegion sram_alias; Clock *sysclk; AspeedSCUState scu; diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0-fc.c +++ b/hw/arm/aspeed_ast27x0-fc.c @@ -XXX,XX +XXX,XX @@ static bool ast2700fc_ssp_init(MachineState *machine, Error **errp) AspeedCoprocessorState *soc; AspeedCoprocessorClass *sc; Ast2700FCState *s = AST2700A1FC(machine); + AspeedSoCState *psp = ASPEED_SOC(&s->ca35); + s->ssp_sysclk = clock_new(OBJECT(s), "SSP_SYSCLK"); clock_set_hz(s->ssp_sysclk, 200000000ULL); @@ -XXX,XX +XXX,XX @@ static bool ast2700fc_ssp_init(MachineState *machine, Error **errp) sc = ASPEED_COPROCESSOR_GET_CLASS(soc); aspeed_soc_uart_set_chr(soc->uart, ASPEED_DEV_UART4, sc->uarts_base, sc->uarts_num, serial_hd(1)); + object_property_set_link(OBJECT(&s->ssp), "sram", + OBJECT(&psp->sram), &error_abort); if (!qdev_realize(DEVICE(&s->ssp), NULL, errp)) { return false; } diff --git a/hw/arm/aspeed_ast27x0-ssp.c b/hw/arm/aspeed_ast27x0-ssp.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0-ssp.c +++ b/hw/arm/aspeed_ast27x0-ssp.c @@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast27x0ssp_memmap[] = { [ASPEED_DEV_SDRAM] = 0x00000000, + [ASPEED_DEV_SRAM] = 0x70000000, [ASPEED_DEV_INTC] = 0x72100000, [ASPEED_DEV_SCU] = 0x72C02000, [ASPEED_DEV_SCUIO] = 0x74C02000, @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp) sc->memmap[ASPEED_DEV_SDRAM], &s->sdram); + /* SRAM */ + memory_region_init_alias(&s->sram_alias, OBJECT(s), "sram.alias", + s->sram, 0, memory_region_size(s->sram)); + memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SRAM], + &s->sram_alias); + /* SCU */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { return; diff --git a/hw/arm/aspeed_coprocessor_common.c b/hw/arm/aspeed_coprocessor_common.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_coprocessor_common.c +++ b/hw/arm/aspeed_coprocessor_common.c @@ -XXX,XX +XXX,XX @@ static void aspeed_coprocessor_realize(DeviceState *dev, Error **errp) static const Property aspeed_coprocessor_properties[] = { DEFINE_PROP_LINK("memory", AspeedCoprocessorState, memory, TYPE_MEMORY_REGION, MemoryRegion *), + DEFINE_PROP_LINK("sram", AspeedCoprocessorState, sram, TYPE_MEMORY_REGION, + MemoryRegion *), }; static void aspeed_coprocessor_class_init(ObjectClass *oc, const void *data) -- 2.51.0
From: Jamin Lin <jamin_lin@aspeedtech.com> AST2700 has a 128KB SRAM, physically mapped at 0x10000000–0x1001FFFF for the PSP (CA35) processor. The TSP coprocessor shares this same SRAM but accesses it through a different address window at 0x70000000–0x7001FFFF. To model this shared-memory behavior in QEMU, this commit introduces a linked SRAM property and alias mapping between the PSP and TSP subsystems. Changes include: - Add the SRAM alias mapping at 0x70000000 in aspeed_ast27x0-tsp.c. - In aspeed_ast27x0-fc.c, connect the TSP coprocessor’s "sram" link to the PSP’s SRAM region. - Ensure the alias region is initialized during TSP SoC realization so the TSP can correctly access shared SRAM through its own address space. This ensures that the TSP and PSP share the same physical SRAM backing. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251015062210.3128710-5-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast27x0-fc.c | 4 ++++ hw/arm/aspeed_ast27x0-tsp.c | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0-fc.c +++ b/hw/arm/aspeed_ast27x0-fc.c @@ -XXX,XX +XXX,XX @@ static bool ast2700fc_tsp_init(MachineState *machine, Error **errp) AspeedCoprocessorState *soc; AspeedCoprocessorClass *sc; Ast2700FCState *s = AST2700A1FC(machine); + AspeedSoCState *psp = ASPEED_SOC(&s->ca35); + s->tsp_sysclk = clock_new(OBJECT(s), "TSP_SYSCLK"); clock_set_hz(s->tsp_sysclk, 200000000ULL); @@ -XXX,XX +XXX,XX @@ static bool ast2700fc_tsp_init(MachineState *machine, Error **errp) sc = ASPEED_COPROCESSOR_GET_CLASS(soc); aspeed_soc_uart_set_chr(soc->uart, ASPEED_DEV_UART7, sc->uarts_base, sc->uarts_num, serial_hd(2)); + object_property_set_link(OBJECT(&s->tsp), "sram", + OBJECT(&psp->sram), &error_abort); if (!qdev_realize(DEVICE(&s->tsp), NULL, errp)) { return false; } diff --git a/hw/arm/aspeed_ast27x0-tsp.c b/hw/arm/aspeed_ast27x0-tsp.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0-tsp.c +++ b/hw/arm/aspeed_ast27x0-tsp.c @@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast27x0tsp_memmap[] = { [ASPEED_DEV_SDRAM] = 0x00000000, + [ASPEED_DEV_SRAM] = 0x70000000, [ASPEED_DEV_INTC] = 0x72100000, [ASPEED_DEV_SCU] = 0x72C02000, [ASPEED_DEV_SCUIO] = 0x74C02000, @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp) sc->memmap[ASPEED_DEV_SDRAM], &s->sdram); + /* SRAM */ + memory_region_init_alias(&s->sram_alias, OBJECT(s), "sram.alias", + s->sram, 0, memory_region_size(s->sram)); + memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SRAM], + &s->sram_alias); + /* SCU */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { return; -- 2.51.0
From: Jamin Lin <jamin_lin@aspeedtech.com> AST2700 has a single SCU hardware block, memory-mapped at 0x12C02000–0x12C03FFF from the perspective of the main CA35 processor (PSP). The SSP and TSP coprocessors access this same SCU block at different addresses: 0x72C02000–0x72C03FFF. Previously, each subsystem (PSP, SSP, and TSP) instantiated its own SCU device, resulting in three independent SCU instances in the QEMU model. In real hardware, however, only a single SCU exists and is shared among all processors. This commit reworks the SCU model to correctly reflect the hardware behavior by allowing SSP and TSP to reference the PSP’s SCU instance. The following changes are introduced: - Add a scu property to AspeedCoprocessorState for linking the coprocessor to the PSP’s SCU instance. - Replace per-coprocessor SCU instantiation with a shared SCU link. - Add "MemoryRegion scu_alias" to model address remapping for SSP and TSP. - Create SCU alias regions in both SSP and TSP coprocessors and map them at 0x72C02000 to mirror the PSP’s SCU registers. - Ensure the SCU device in PSP is realized before SSP/TSP alias setup. With this change, PSP, SSP, and TSP now share a consistent SCU state, matching the single-SCU hardware design of AST2700. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251015062210.3128710-6-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- include/hw/arm/aspeed_coprocessor.h | 4 ++-- hw/arm/aspeed_ast27x0-fc.c | 4 ++++ hw/arm/aspeed_ast27x0-ssp.c | 13 +++++-------- hw/arm/aspeed_ast27x0-tsp.c | 13 +++++-------- hw/arm/aspeed_coprocessor_common.c | 2 ++ 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/include/hw/arm/aspeed_coprocessor.h b/include/hw/arm/aspeed_coprocessor.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/arm/aspeed_coprocessor.h +++ b/include/hw/arm/aspeed_coprocessor.h @@ -XXX,XX +XXX,XX @@ struct AspeedCoprocessorState { MemoryRegion sdram; MemoryRegion *sram; MemoryRegion sram_alias; + MemoryRegion scu_alias; Clock *sysclk; - AspeedSCUState scu; + AspeedSCUState *scu; AspeedSCUState scuio; AspeedTimerCtrlState timerctrl; SerialMM uart[ASPEED_UARTS_NUM]; @@ -XXX,XX +XXX,XX @@ struct AspeedCoprocessorClass { /** valid_cpu_types: NULL terminated array of a single CPU type. */ const char * const *valid_cpu_types; - uint32_t silicon_rev; const hwaddr *memmap; const int *irqmap; int uarts_base; diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0-fc.c +++ b/hw/arm/aspeed_ast27x0-fc.c @@ -XXX,XX +XXX,XX @@ static bool ast2700fc_ssp_init(MachineState *machine, Error **errp) sc->uarts_num, serial_hd(1)); object_property_set_link(OBJECT(&s->ssp), "sram", OBJECT(&psp->sram), &error_abort); + object_property_set_link(OBJECT(&s->ssp), "scu", + OBJECT(&psp->scu), &error_abort); if (!qdev_realize(DEVICE(&s->ssp), NULL, errp)) { return false; } @@ -XXX,XX +XXX,XX @@ static bool ast2700fc_tsp_init(MachineState *machine, Error **errp) sc->uarts_num, serial_hd(2)); object_property_set_link(OBJECT(&s->tsp), "sram", OBJECT(&psp->sram), &error_abort); + object_property_set_link(OBJECT(&s->tsp), "scu", + OBJECT(&psp->scu), &error_abort); if (!qdev_realize(DEVICE(&s->tsp), NULL, errp)) { return false; } diff --git a/hw/arm/aspeed_ast27x0-ssp.c b/hw/arm/aspeed_ast27x0-ssp.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0-ssp.c +++ b/hw/arm/aspeed_ast27x0-ssp.c @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0ssp_init(Object *obj) 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); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp) &s->sram_alias); /* 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]); + memory_region_init_alias(&s->scu_alias, OBJECT(s), "scu.alias", + &s->scu->iomem, 0, + memory_region_size(&s->scu->iomem)); + memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SCU], + &s->scu_alias); /* INTC */ if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc[0]), errp)) { @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0ssp_class_init(ObjectClass *klass, dc->realize = aspeed_soc_ast27x0ssp_realize; sc->valid_cpu_types = valid_cpu_types; - sc->silicon_rev = AST2700_A1_SILICON_REV; sc->uarts_num = 13; sc->uarts_base = ASPEED_DEV_UART0; sc->irqmap = aspeed_soc_ast27x0ssp_irqmap; diff --git a/hw/arm/aspeed_ast27x0-tsp.c b/hw/arm/aspeed_ast27x0-tsp.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0-tsp.c +++ b/hw/arm/aspeed_ast27x0-tsp.c @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0tsp_init(Object *obj) 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); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp) &s->sram_alias); /* 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]); + memory_region_init_alias(&s->scu_alias, OBJECT(s), "scu.alias", + &s->scu->iomem, 0, + memory_region_size(&s->scu->iomem)); + memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SCU], + &s->scu_alias); /* INTC */ if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc[0]), errp)) { @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0tsp_class_init(ObjectClass *klass, dc->realize = aspeed_soc_ast27x0tsp_realize; sc->valid_cpu_types = valid_cpu_types; - sc->silicon_rev = AST2700_A1_SILICON_REV; sc->uarts_num = 13; sc->uarts_base = ASPEED_DEV_UART0; sc->irqmap = aspeed_soc_ast27x0tsp_irqmap; diff --git a/hw/arm/aspeed_coprocessor_common.c b/hw/arm/aspeed_coprocessor_common.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_coprocessor_common.c +++ b/hw/arm/aspeed_coprocessor_common.c @@ -XXX,XX +XXX,XX @@ static const Property aspeed_coprocessor_properties[] = { TYPE_MEMORY_REGION, MemoryRegion *), DEFINE_PROP_LINK("sram", AspeedCoprocessorState, sram, TYPE_MEMORY_REGION, MemoryRegion *), + DEFINE_PROP_LINK("scu", AspeedCoprocessorState, scu, TYPE_ASPEED_SCU, + AspeedSCUState *), }; static void aspeed_coprocessor_class_init(ObjectClass *oc, const void *data) -- 2.51.0
From: Jamin Lin <jamin_lin@aspeedtech.com> In the original model, each subsystem (PSP, SSP, and TSP) created its own set of 13 UART devices, resulting in a total of 39 UART instances. However, on real AST2700 hardware, there is only one set of 13 UARTs shared among all processors. This commit reworks the UART handling to correctly model the shared hardware design. The PSP now creates the full set of 13 UART instances, while the SSP and TSP link to the corresponding shared UART device through object properties. Changes include: - Add "DEFINE_PROP_LINK("uart", ...)" and "DEFINE_PROP_INT32("uart-dev", ...)" to allow each coprocessor to reference a specific shared UART instance. - Modify SSP to link to PSP’s UART4, and TSP to link to PSP’s UART7. - Introduce "uart_alias" to remap the UART’s MMIO region into the coprocessor’s memory space. - Redirect the UART interrupt to the coprocessor’s NVIC, replacing the default routing to the PSP’s GIC. With this change, only one set of 13 UART devices is instantiated by the PSP, while the SSP and TSP reuse them via aliasing and shared interrupt routing, matching the real AST2700 hardware behavior. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251015062210.3128710-7-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- include/hw/arm/aspeed_coprocessor.h | 6 +++--- hw/arm/aspeed_ast27x0-fc.c | 24 ++++++++++++------------ hw/arm/aspeed_ast27x0-ssp.c | 29 ++++++++++++----------------- hw/arm/aspeed_ast27x0-tsp.c | 29 ++++++++++++----------------- hw/arm/aspeed_coprocessor_common.c | 3 +++ 5 files changed, 42 insertions(+), 49 deletions(-) diff --git a/include/hw/arm/aspeed_coprocessor.h b/include/hw/arm/aspeed_coprocessor.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/arm/aspeed_coprocessor.h +++ b/include/hw/arm/aspeed_coprocessor.h @@ -XXX,XX +XXX,XX @@ struct AspeedCoprocessorState { MemoryRegion sdram; MemoryRegion *sram; MemoryRegion sram_alias; + MemoryRegion uart_alias; MemoryRegion scu_alias; Clock *sysclk; AspeedSCUState *scu; AspeedSCUState scuio; AspeedTimerCtrlState timerctrl; - SerialMM uart[ASPEED_UARTS_NUM]; + SerialMM *uart; + int uart_dev; }; #define TYPE_ASPEED_COPROCESSOR "aspeed-coprocessor" @@ -XXX,XX +XXX,XX @@ struct AspeedCoprocessorClass { const char * const *valid_cpu_types; const hwaddr *memmap; const int *irqmap; - int uarts_base; - int uarts_num; }; struct Aspeed27x0CoprocessorState { diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0-fc.c +++ b/hw/arm/aspeed_ast27x0-fc.c @@ -XXX,XX +XXX,XX @@ static bool ast2700fc_ca35_init(MachineState *machine, Error **errp) AST2700FC_HW_STRAP2, &error_abort); aspeed_soc_uart_set_chr(soc->uart, ASPEED_DEV_UART12, sc->uarts_base, sc->uarts_num, serial_hd(0)); + aspeed_soc_uart_set_chr(soc->uart, ASPEED_DEV_UART4, sc->uarts_base, + sc->uarts_num, serial_hd(1)); + aspeed_soc_uart_set_chr(soc->uart, ASPEED_DEV_UART7, sc->uarts_base, + sc->uarts_num, serial_hd(2)); if (!qdev_realize(DEVICE(&s->ca35), NULL, errp)) { return false; } @@ -XXX,XX +XXX,XX @@ static bool ast2700fc_ca35_init(MachineState *machine, Error **errp) static bool ast2700fc_ssp_init(MachineState *machine, Error **errp) { - AspeedCoprocessorState *soc; - AspeedCoprocessorClass *sc; Ast2700FCState *s = AST2700A1FC(machine); AspeedSoCState *psp = ASPEED_SOC(&s->ca35); @@ -XXX,XX +XXX,XX @@ static bool ast2700fc_ssp_init(MachineState *machine, Error **errp) object_property_set_link(OBJECT(&s->ssp), "memory", OBJECT(&s->ssp_memory), &error_abort); - soc = ASPEED_COPROCESSOR(&s->ssp); - sc = ASPEED_COPROCESSOR_GET_CLASS(soc); - aspeed_soc_uart_set_chr(soc->uart, ASPEED_DEV_UART4, sc->uarts_base, - sc->uarts_num, serial_hd(1)); + object_property_set_link(OBJECT(&s->ssp), "uart", + OBJECT(&psp->uart[4]), &error_abort); + object_property_set_int(OBJECT(&s->ssp), "uart-dev", ASPEED_DEV_UART4, + &error_abort); object_property_set_link(OBJECT(&s->ssp), "sram", OBJECT(&psp->sram), &error_abort); object_property_set_link(OBJECT(&s->ssp), "scu", @@ -XXX,XX +XXX,XX @@ static bool ast2700fc_ssp_init(MachineState *machine, Error **errp) static bool ast2700fc_tsp_init(MachineState *machine, Error **errp) { - AspeedCoprocessorState *soc; - AspeedCoprocessorClass *sc; Ast2700FCState *s = AST2700A1FC(machine); AspeedSoCState *psp = ASPEED_SOC(&s->ca35); @@ -XXX,XX +XXX,XX @@ static bool ast2700fc_tsp_init(MachineState *machine, Error **errp) object_property_set_link(OBJECT(&s->tsp), "memory", OBJECT(&s->tsp_memory), &error_abort); - soc = ASPEED_COPROCESSOR(&s->tsp); - sc = ASPEED_COPROCESSOR_GET_CLASS(soc); - aspeed_soc_uart_set_chr(soc->uart, ASPEED_DEV_UART7, sc->uarts_base, - sc->uarts_num, serial_hd(2)); + object_property_set_link(OBJECT(&s->tsp), "uart", + OBJECT(&psp->uart[7]), &error_abort); + object_property_set_int(OBJECT(&s->tsp), "uart-dev", ASPEED_DEV_UART7, + &error_abort); object_property_set_link(OBJECT(&s->tsp), "sram", OBJECT(&psp->sram), &error_abort); object_property_set_link(OBJECT(&s->tsp), "scu", diff --git a/hw/arm/aspeed_ast27x0-ssp.c b/hw/arm/aspeed_ast27x0-ssp.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0-ssp.c +++ b/hw/arm/aspeed_ast27x0-ssp.c @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0ssp_init(Object *obj) { Aspeed27x0CoprocessorState *a = ASPEED27X0SSP_COPROCESSOR(obj); AspeedCoprocessorState *s = ASPEED_COPROCESSOR(obj); - AspeedCoprocessorClass *sc = ASPEED_COPROCESSOR_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); - 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], @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp) AspeedCoprocessorClass *sc = ASPEED_COPROCESSOR_GET_CLASS(s); DeviceState *armv7m; g_autofree char *sdram_name = NULL; - int uart; int i; if (!clock_has_source(s->sysclk)) { @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc[1]), i, qdev_get_gpio_in(DEVICE(&a->intc[0].orgates[0]), i)); } + /* 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_ast27x0ssp_get_irq(s, uart)); - } + memory_region_init_alias(&s->uart_alias, OBJECT(s), "uart.alias", + &s->uart->serial.io, 0, + memory_region_size(&s->uart->serial.io)); + memory_region_add_subregion(s->memory, sc->memmap[s->uart_dev], + &s->uart_alias); + /* + * Redirect the UART interrupt to the NVIC, replacing the default routing + * to the PSP's GIC. + */ + sysbus_connect_irq(SYS_BUS_DEVICE(s->uart), 0, + aspeed_soc_ast27x0ssp_get_irq(s, s->uart_dev)); aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->timerctrl), "aspeed.timerctrl", @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0ssp_class_init(ObjectClass *klass, dc->realize = aspeed_soc_ast27x0ssp_realize; sc->valid_cpu_types = valid_cpu_types; - sc->uarts_num = 13; - sc->uarts_base = ASPEED_DEV_UART0; sc->irqmap = aspeed_soc_ast27x0ssp_irqmap; sc->memmap = aspeed_soc_ast27x0ssp_memmap; } diff --git a/hw/arm/aspeed_ast27x0-tsp.c b/hw/arm/aspeed_ast27x0-tsp.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0-tsp.c +++ b/hw/arm/aspeed_ast27x0-tsp.c @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0tsp_init(Object *obj) { Aspeed27x0CoprocessorState *a = ASPEED27X0TSP_COPROCESSOR(obj); AspeedCoprocessorState *s = ASPEED_COPROCESSOR(obj); - AspeedCoprocessorClass *sc = ASPEED_COPROCESSOR_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); - 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], @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp) AspeedCoprocessorClass *sc = ASPEED_COPROCESSOR_GET_CLASS(s); DeviceState *armv7m; g_autofree char *sdram_name = NULL; - int uart; int i; if (!clock_has_source(s->sysclk)) { @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc[1]), i, qdev_get_gpio_in(DEVICE(&a->intc[0].orgates[0]), i)); } + /* 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_ast27x0tsp_get_irq(s, uart)); - } + memory_region_init_alias(&s->uart_alias, OBJECT(s), "uart.alias", + &s->uart->serial.io, 0, + memory_region_size(&s->uart->serial.io)); + memory_region_add_subregion(s->memory, sc->memmap[s->uart_dev], + &s->uart_alias); + /* + * Redirect the UART interrupt to the NVIC, replacing the default routing + * to the PSP's GIC. + */ + sysbus_connect_irq(SYS_BUS_DEVICE(s->uart), 0, + aspeed_soc_ast27x0tsp_get_irq(s, s->uart_dev)); aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->timerctrl), "aspeed.timerctrl", @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast27x0tsp_class_init(ObjectClass *klass, dc->realize = aspeed_soc_ast27x0tsp_realize; sc->valid_cpu_types = valid_cpu_types; - sc->uarts_num = 13; - sc->uarts_base = ASPEED_DEV_UART0; sc->irqmap = aspeed_soc_ast27x0tsp_irqmap; sc->memmap = aspeed_soc_ast27x0tsp_memmap; } diff --git a/hw/arm/aspeed_coprocessor_common.c b/hw/arm/aspeed_coprocessor_common.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_coprocessor_common.c +++ b/hw/arm/aspeed_coprocessor_common.c @@ -XXX,XX +XXX,XX @@ static const Property aspeed_coprocessor_properties[] = { MemoryRegion *), DEFINE_PROP_LINK("scu", AspeedCoprocessorState, scu, TYPE_ASPEED_SCU, AspeedSCUState *), + DEFINE_PROP_LINK("uart", AspeedCoprocessorState, uart, TYPE_SERIAL_MM, + SerialMM *), + DEFINE_PROP_INT32("uart-dev", AspeedCoprocessorState, uart_dev, 0), }; static void aspeed_coprocessor_class_init(ObjectClass *oc, const void *data) -- 2.51.0
From: Jamin Lin <jamin_lin@aspeedtech.com> This patch introduces a dedicated ca35_boot_rom memory region and copies the FMC0 flash data into it. The motivation is to support the upcoming vbootrom. The vbootrom replaces the existing BOOTMCU (RISC-V 32 SPL) flow, which currently reads the "image-bmc" from FMC_CS0 and loads the following components into DRAM: - Trusted Firmware-A - OP-TEE OS - u-boot-nodtb.bin - u-boot.dtb After loading, BOOTMCU releases the CA35 reset so that CA35 can start executing Trusted Firmware-A. The vbootrom follows the same sequence: CA35 fetches "image-bmc" from FMC0 flash at the SPI boot ROM base address (0x100000000), parses the FIT image, loads each component into its designated DRAM location, and then jumps to Trusted Firmware-A. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251015062210.3128710-8-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast27x0-fc.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0-fc.c +++ b/hw/arm/aspeed_ast27x0-fc.c @@ -XXX,XX +XXX,XX @@ struct Ast2700FCState { MemoryRegion ca35_memory; MemoryRegion ca35_dram; + MemoryRegion ca35_boot_rom; MemoryRegion ssp_memory; MemoryRegion tsp_memory; @@ -XXX,XX +XXX,XX @@ struct Ast2700FCState { Aspeed27x0SoCState ca35; Aspeed27x0CoprocessorState ssp; Aspeed27x0CoprocessorState tsp; - - bool mmio_exec; }; #define AST2700FC_BMC_RAM_SIZE (1 * GiB) @@ -XXX,XX +XXX,XX @@ static bool ast2700fc_ca35_init(MachineState *machine, Error **errp) Ast2700FCState *s = AST2700A1FC(machine); AspeedSoCState *soc; AspeedSoCClass *sc; + BlockBackend *fmc0 = NULL; + DeviceState *dev = NULL; + uint64_t rom_size; object_initialize_child(OBJECT(s), "ca35", &s->ca35, "ast2700-a1"); soc = ASPEED_SOC(&s->ca35); @@ -XXX,XX +XXX,XX @@ static bool ast2700fc_ca35_init(MachineState *machine, Error **errp) ast2700fc_board_info.ram_size = machine->ram_size; ast2700fc_board_info.loader_start = sc->memmap[ASPEED_DEV_SDRAM]; + dev = ssi_get_cs(soc->fmc.spi, 0); + fmc0 = dev ? m25p80_get_blk(dev) : NULL; + + if (fmc0) { + rom_size = memory_region_size(&soc->spi_boot); + aspeed_install_boot_rom(soc, fmc0, &s->ca35_boot_rom, rom_size); + } + arm_load_kernel(ARM_CPU(first_cpu), machine, &ast2700fc_board_info); return true; -- 2.51.0
From: Jamin Lin <jamin_lin@aspeedtech.com> Introduces support for loading a vbootrom image into the dedicated vbootrom memory region in the AST2700 Full Core machine. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251015062210.3128710-9-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast27x0-fc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0-fc.c +++ b/hw/arm/aspeed_ast27x0-fc.c @@ -XXX,XX +XXX,XX @@ static bool ast2700fc_ca35_init(MachineState *machine, Error **errp) Ast2700FCState *s = AST2700A1FC(machine); AspeedSoCState *soc; AspeedSoCClass *sc; + const char *bios_name = NULL; BlockBackend *fmc0 = NULL; DeviceState *dev = NULL; uint64_t rom_size; @@ -XXX,XX +XXX,XX @@ static bool ast2700fc_ca35_init(MachineState *machine, Error **errp) aspeed_install_boot_rom(soc, fmc0, &s->ca35_boot_rom, rom_size); } + /* VBOOTROM */ + bios_name = machine->firmware ?: VBOOTROM_FILE_NAME; + aspeed_load_vbootrom(soc, bios_name, errp); + arm_load_kernel(ARM_CPU(first_cpu), machine, &ast2700fc_board_info); return true; -- 2.51.0
From: Jamin Lin <jamin_lin@aspeedtech.com> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251015062210.3128710-10-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- tests/functional/aarch64/test_aspeed_ast2700fc.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/functional/aarch64/test_aspeed_ast2700fc.py b/tests/functional/aarch64/test_aspeed_ast2700fc.py index XXXXXXX..XXXXXXX 100755 --- a/tests/functional/aarch64/test_aspeed_ast2700fc.py +++ b/tests/functional/aarch64/test_aspeed_ast2700fc.py @@ -XXX,XX +XXX,XX @@ def verify_openbmc_boot_and_login(self, name): 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') + ASSET_SDK_V908_AST2700 = Asset( + 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.08/ast2700-default-obmc.tar.gz', + 'eac3dc409b7ea3cd4b03d4792d3cebd469792ad893cb51e1d15f0fc20bd1e2cd') def do_ast2700_i2c_test(self): exec_command_and_wait_for_pattern(self, @@ -XXX,XX +XXX,XX @@ def do_ast2700fc_ssp_test(self): 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, '\012', 'ssp_tsp:~$') exec_command_and_wait_for_pattern(self, 'version', 'Zephyr version 3.7.1') exec_command_and_wait_for_pattern(self, 'md 72c02000 1', @@ -XXX,XX +XXX,XX @@ def start_ast2700fc_test(self, name): self.do_test_aarch64_aspeed_sdk_start( self.scratch_file(name, 'image-bmc')) - def test_aarch64_ast2700fc_sdk_v09_06(self): + def test_aarch64_ast2700fc_sdk_v09_08(self): self.set_machine('ast2700fc') - self.archive_extract(self.ASSET_SDK_V906_AST2700) + self.archive_extract(self.ASSET_SDK_V908_AST2700) self.start_ast2700fc_test('ast2700-default') self.verify_openbmc_boot_and_login('ast2700-default') self.do_ast2700_i2c_test() -- 2.51.0
From: Jamin Lin <jamin_lin@aspeedtech.com> Enhance the AST2700 functional PCIe test to verify the network interface configuration for eth2. This adds an additional command to check the IP address assignment on eth2 to ensure network functionality is correctly initialized in the test environment. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251015062210.3128710-11-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- tests/functional/aarch64/test_aspeed_ast2700fc.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/functional/aarch64/test_aspeed_ast2700fc.py b/tests/functional/aarch64/test_aspeed_ast2700fc.py index XXXXXXX..XXXXXXX 100755 --- a/tests/functional/aarch64/test_aspeed_ast2700fc.py +++ b/tests/functional/aarch64/test_aspeed_ast2700fc.py @@ -XXX,XX +XXX,XX @@ def do_ast2700_pcie_test(self): 'lspci -s 0002:01:00.0', '0002:01:00.0 Ethernet controller: ' 'Intel Corporation 82574L Gigabit Network Connection') + exec_command_and_wait_for_pattern(self, + 'ip addr show dev eth2', + 'inet 10.0.2.15/24') def do_ast2700fc_ssp_test(self): self.vm.shutdown() @@ -XXX,XX +XXX,XX @@ def start_ast2700fc_test(self, name): def test_aarch64_ast2700fc_sdk_v09_08(self): self.set_machine('ast2700fc') + self.require_netdev('user') self.archive_extract(self.ASSET_SDK_V908_AST2700) self.start_ast2700fc_test('ast2700-default') -- 2.51.0
From: Jamin Lin <jamin_lin@aspeedtech.com> This removes duplicate code in start_ast2700fc_test() and prepares for reuse in upcoming VBOOTROM tests. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251015062210.3128710-12-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- .../aarch64/test_aspeed_ast2700fc.py | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tests/functional/aarch64/test_aspeed_ast2700fc.py b/tests/functional/aarch64/test_aspeed_ast2700fc.py index XXXXXXX..XXXXXXX 100755 --- a/tests/functional/aarch64/test_aspeed_ast2700fc.py +++ b/tests/functional/aarch64/test_aspeed_ast2700fc.py @@ -XXX,XX +XXX,XX @@ def verify_openbmc_boot_and_login(self, name): exec_command_and_wait_for_pattern(self, 'root', 'Password:') exec_command_and_wait_for_pattern(self, '0penBmc', f'root@{name}:~#') + def load_ast2700fc_coprocessor(self, name): + 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}') + ASSET_SDK_V908_AST2700 = Asset( 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.08/ast2700-default-obmc.tar.gz', 'eac3dc409b7ea3cd4b03d4792d3cebd469792ad893cb51e1d15f0fc20bd1e2cd') @@ -XXX,XX +XXX,XX @@ def start_ast2700fc_test(self, name): 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.load_ast2700fc_coprocessor(name) self.do_test_aarch64_aspeed_sdk_start( self.scratch_file(name, 'image-bmc')) -- 2.51.0
From: Jamin Lin <jamin_lin@aspeedtech.com> Add start_ast2700fc_test_vbootrom() which boots the ast2700fc machine with -bios ast27x0_bootrom.bin and reuses the coprocessor loader. Add test_aarch64_ast2700fc_sdk_vbootrom_v09_08() to test the vbootrom with ast2700fc machine. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251015062210.3128710-13-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- tests/functional/aarch64/test_aspeed_ast2700fc.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/functional/aarch64/test_aspeed_ast2700fc.py b/tests/functional/aarch64/test_aspeed_ast2700fc.py index XXXXXXX..XXXXXXX 100755 --- a/tests/functional/aarch64/test_aspeed_ast2700fc.py +++ b/tests/functional/aarch64/test_aspeed_ast2700fc.py @@ -XXX,XX +XXX,XX @@ def start_ast2700fc_test(self, name): self.do_test_aarch64_aspeed_sdk_start( self.scratch_file(name, 'image-bmc')) + def start_ast2700fc_test_vbootrom(self, name): + self.vm.add_args('-bios', 'ast27x0_bootrom.bin') + self.load_ast2700fc_coprocessor(name) + self.do_test_aarch64_aspeed_sdk_start( + self.scratch_file(name, 'image-bmc')) + def test_aarch64_ast2700fc_sdk_v09_08(self): self.set_machine('ast2700fc') self.require_netdev('user') @@ -XXX,XX +XXX,XX @@ def test_aarch64_ast2700fc_sdk_v09_08(self): self.do_ast2700fc_ssp_test() self.do_ast2700fc_tsp_test() + def test_aarch64_ast2700fc_sdk_vbootrom_v09_08(self): + self.set_machine('ast2700fc') + + self.archive_extract(self.ASSET_SDK_V908_AST2700) + self.start_ast2700fc_test_vbootrom('ast2700-default') + self.verify_openbmc_boot_and_login('ast2700-default') + self.do_ast2700fc_ssp_test() + self.do_ast2700fc_tsp_test() + if __name__ == '__main__': QemuSystemTest.main() -- 2.51.0
From: Felix Wu <flwu@google.com> Added 32 bits property for ASPEED GPIO. Previously it can only be access in bitwise manner. The changes to qobject is to index gpios with array indices on top of accessing with registers. This allows for easier gpio access, especially in tests with complex behaviors that requires large number of gpios at a time, like fault injection and networking behaviors. Indexing multiple gpios at once allows qmp/side band client to no longer hardcode and populate register names and manipulate them faster. Signed-off-by: Felix Wu <flwu@google.com> Reviewed-by: Andrew Jeffery <andrew@codeconstruct.com.au> Link: https://lore.kernel.org/qemu-devel/20251015011830.1688468-2-lixiaoyan@google.com [ clg: wrapped commit log lines ] Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/gpio/aspeed_gpio.c | 57 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c index XXXXXXX..XXXXXXX 100644 --- a/hw/gpio/aspeed_gpio.c +++ b/hw/gpio/aspeed_gpio.c @@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_2700_write(void *opaque, hwaddr offset, } /* Setup functions */ +static void aspeed_gpio_set_set(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + uint32_t set_val = 0; + AspeedGPIOState *s = ASPEED_GPIO(obj); + AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s); + int set_idx = 0; + + if (!visit_type_uint32(v, name, &set_val, errp)) { + return; + } + + if (sscanf(name, "gpio-set[%d]", &set_idx) != 1) { + error_setg(errp, "%s: error reading %s", __func__, name); + return; + } + + if (set_idx >= agc->nr_gpio_sets || set_idx < 0) { + error_setg(errp, "%s: invalid set_idx %s", __func__, name); + return; + } + + aspeed_gpio_update(s, &s->sets[set_idx], set_val, + ~s->sets[set_idx].direction); +} + +static void aspeed_gpio_get_set(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + uint32_t set_val = 0; + AspeedGPIOState *s = ASPEED_GPIO(obj); + AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s); + int set_idx = 0; + + if (sscanf(name, "gpio-set[%d]", &set_idx) != 1) { + error_setg(errp, "%s: error reading %s", __func__, name); + return; + } + + if (set_idx >= agc->nr_gpio_sets || set_idx < 0) { + error_setg(errp, "%s: invalid set_idx %s", __func__, name); + return; + } + + set_val = s->sets[set_idx].data_value; + visit_type_uint32(v, name, &set_val, errp); +} + +/****************** Setup functions ******************/ static const GPIOSetProperties ast2400_set_props[ASPEED_GPIO_MAX_NR_SETS] = { [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} }, [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} }, @@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_init(Object *obj) g_free(name); } } + + for (int i = 0; i < agc->nr_gpio_sets; i++) { + char *name = g_strdup_printf("gpio-set[%d]", i); + object_property_add(obj, name, "uint32", aspeed_gpio_get_set, + aspeed_gpio_set_set, NULL, NULL); + } } static const VMStateDescription vmstate_gpio_regs = { -- 2.51.0
From: Felix Wu <flwu@google.com> - Added qtests to test gpio-set property for ASPEED. - Added function to get uint in qdict. Signed-off-by: Felix Wu <flwu@google.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251015011830.1688468-3-lixiaoyan@google.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- include/qobject/qdict.h | 1 + qobject/qdict.c | 13 ++++ tests/qtest/aspeed_gpio-test.c | 105 ++++++++++++++++++++++++++++++--- 3 files changed, 110 insertions(+), 9 deletions(-) diff --git a/include/qobject/qdict.h b/include/qobject/qdict.h index XXXXXXX..XXXXXXX 100644 --- a/include/qobject/qdict.h +++ b/include/qobject/qdict.h @@ -XXX,XX +XXX,XX @@ void qdict_put_str(QDict *qdict, const char *key, const char *value); double qdict_get_double(const QDict *qdict, const char *key); int64_t qdict_get_int(const QDict *qdict, const char *key); +uint64_t qdict_get_uint(const QDict *qdict, const char *key); bool qdict_get_bool(const QDict *qdict, const char *key); QList *qdict_get_qlist(const QDict *qdict, const char *key); QDict *qdict_get_qdict(const QDict *qdict, const char *key); diff --git a/qobject/qdict.c b/qobject/qdict.c index XXXXXXX..XXXXXXX 100644 --- a/qobject/qdict.c +++ b/qobject/qdict.c @@ -XXX,XX +XXX,XX @@ int64_t qdict_get_int(const QDict *qdict, const char *key) return qnum_get_int(qobject_to(QNum, qdict_get(qdict, key))); } +/** + * qdict_get_uint(): Get an unsigned integer mapped by 'key' + * + * This function assumes that 'key' exists and it stores a + * QNum representable as uint. + * + * Return unsigned integer mapped by 'key'. + */ +uint64_t qdict_get_uint(const QDict *qdict, const char *key) +{ + return qnum_get_uint(qobject_to(QNum, qdict_get(qdict, key))); +} + /** * qdict_get_bool(): Get a bool mapped by 'key' * diff --git a/tests/qtest/aspeed_gpio-test.c b/tests/qtest/aspeed_gpio-test.c index XXXXXXX..XXXXXXX 100644 --- a/tests/qtest/aspeed_gpio-test.c +++ b/tests/qtest/aspeed_gpio-test.c @@ -XXX,XX +XXX,XX @@ #include "qemu/timer.h" #include "qobject/qdict.h" #include "libqtest-single.h" +#include "qemu/typedefs.h" #define AST2600_GPIO_BASE 0x1E780000 #define GPIO_ABCD_DATA_VALUE 0x000 #define GPIO_ABCD_DIRECTION 0x004 +static uint32_t qtest_qom_get_uint32(QTestState *s, const char *path, + const char *property) +{ + QDict *r; + + uint32_t res; + r = qtest_qmp(s, "{ 'execute': 'qom-get', 'arguments': " + "{ 'path': %s, 'property': %s } }", path, property); + res = qdict_get_uint(r, "return"); + qobject_unref(r); + + return res; +} + +static void qtest_qom_set_uint32(QTestState *s, const char *path, + const char *property, uint32_t value) +{ + QDict *r; + + r = qtest_qmp(s, "{ 'execute': 'qom-set', 'arguments': " + "{ 'path': %s, 'property': %s, 'value': %" PRIu32 " } }", + path, property, value); + qobject_unref(r); +} + +static const char *resp_get_error(QDict *r, const char* error_key) +{ + QDict *qdict; + + g_assert(r); + + qdict = qdict_get_qdict(r, "error"); + if (qdict) { + return qdict_get_str(qdict, error_key); + } + + return NULL; +} + +static bool qtest_qom_check_error(QTestState *s, const char *path, + const char *property, const char *error_msg, + const char *error_msg_key) +{ + QDict *r; + bool b; + + r = qtest_qmp(s, "{ 'execute': 'qom-get', 'arguments': " + "{ 'path': %s, 'property': %s } }", path, property); + b = g_str_equal(resp_get_error(r, error_msg_key), error_msg); + qobject_unref(r); + + return b; +} + static void test_set_colocated_pins(const void *data) { QTestState *s = (QTestState *)data; - + const char path[] = "/machine/soc/gpio"; /* * gpioV4-7 occupy bits within a single 32-bit value, so we want to make * sure that modifying one doesn't affect the other. */ - qtest_qom_set_bool(s, "/machine/soc/gpio", "gpioV4", true); - qtest_qom_set_bool(s, "/machine/soc/gpio", "gpioV5", false); - qtest_qom_set_bool(s, "/machine/soc/gpio", "gpioV6", true); - qtest_qom_set_bool(s, "/machine/soc/gpio", "gpioV7", false); - g_assert(qtest_qom_get_bool(s, "/machine/soc/gpio", "gpioV4")); - g_assert(!qtest_qom_get_bool(s, "/machine/soc/gpio", "gpioV5")); - g_assert(qtest_qom_get_bool(s, "/machine/soc/gpio", "gpioV6")); - g_assert(!qtest_qom_get_bool(s, "/machine/soc/gpio", "gpioV7")); + qtest_qom_set_bool(s, path, "gpioV4", true); + qtest_qom_set_bool(s, path, "gpioV5", false); + qtest_qom_set_bool(s, path, "gpioV6", true); + qtest_qom_set_bool(s, path, "gpioV7", false); + g_assert(qtest_qom_get_bool(s, path, "gpioV4")); + g_assert(!qtest_qom_get_bool(s, path, "gpioV5")); + g_assert(qtest_qom_get_bool(s, path, "gpioV6")); + g_assert(!qtest_qom_get_bool(s, path, "gpioV7")); + + /* + * Testing the gpio-set[%d] properties, using individual gpio boolean + * properties to do cross check. + * We use gpioR4-7 for test, Setting them to be 0b1010. + */ + qtest_qom_set_uint32(s, path, "gpio-set[4]", 0x0); + g_assert(qtest_qom_get_uint32(s, path, "gpio-set[4]") == 0x0); + qtest_qom_set_uint32(s, path, "gpio-set[4]", 0xa000); + g_assert(qtest_qom_get_uint32(s, path, "gpio-set[4]") == 0xa000); + + g_assert(!qtest_qom_get_bool(s, path, "gpioR4")); + g_assert(qtest_qom_get_bool(s, path, "gpioR5")); + g_assert(!qtest_qom_get_bool(s, path, "gpioR6")); + g_assert(qtest_qom_get_bool(s, path, "gpioR7")); + + /* + * Testing the invalid indexing, the response info should contain following + * info: + * {key: "class", value: "GenericError"} + * + * For pins, it should follow "gpio%2[A-Z]%1d" or "gpio%3[18A-E]%1d" format. + */ + const char error_msg[] = "GenericError"; + const char error_msg_key[] = "class"; + + g_assert(qtest_qom_check_error(s, path, "gpioR+1", error_msg, + error_msg_key)); + g_assert(qtest_qom_check_error(s, path, "gpio-set[99]", error_msg, + error_msg_key)); + g_assert(qtest_qom_check_error(s, path, "gpio-set[-3]", error_msg, + error_msg_key)); } static void test_set_input_pins(const void *data) -- 2.51.0
The ast2600-evb machine model is using the "mx66u51235f" flash model, which has issues with recent Linux kernels (6.15+) when reading SFDP data. Change the flash model to "w25q512jv", which is the model present on some ast2600a3 EVB board and is known to work correctly with recent kernels. Adjust the corresponding qtest to reflect the new JEDEC ID of the w25q512jv flash. Reviewed-by: Jamin Lin <jamin_lin@aspeedtech.com> Link: https://lore.kernel.org/qemu-devel/20251016212437.1046135-1-clg@redhat.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed.c | 4 ++-- tests/qtest/aspeed_smc-test.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -XXX,XX +XXX,XX @@ static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, amc->soc_name = "ast2600-a3"; amc->hw_strap1 = AST2600_EVB_HW_STRAP1; amc->hw_strap2 = AST2600_EVB_HW_STRAP2; - amc->fmc_model = "mx66u51235f"; - amc->spi_model = "mx66u51235f"; + amc->fmc_model = "w25q512jv"; + amc->spi_model = "w25q512jv"; amc->num_cs = 1; amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON | ASPEED_MAC2_ON | ASPEED_MAC3_ON; diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c index XXXXXXX..XXXXXXX 100644 --- a/tests/qtest/aspeed_smc-test.c +++ b/tests/qtest/aspeed_smc-test.c @@ -XXX,XX +XXX,XX @@ static void test_ast2600_evb(AspeedSMCTestData *data) "-drive file=%s,format=raw,if=mtd", data->tmp_path); - /* fmc cs0 with mx66u51235f flash */ + /* fmc cs0 with w25q512jv flash */ data->flash_base = 0x20000000; data->spi_base = 0x1E620000; - data->jedec_id = 0xc2253a; + data->jedec_id = 0xef4020; data->cs = 0; data->node = "/machine/soc/fmc/ssi.0/child[0]"; /* beyond 16MB */ -- 2.51.0
From: Philippe Mathieu-Daudé <philmd@linaro.org> Remove pointless alias to the very same machine: $ qemu-system-aarch64 -M help | fgrep ast2700fc ast2700fc ast2700 full core support (alias of ast2700fc) ast2700fc ast2700 full core support Fixes: a74faf35efc ("hw/arm: Introduce ASPEED AST2700 A1 full core machine") Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251021110427.93991-1-philmd@linaro.org Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast27x0-fc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0-fc.c +++ b/hw/arm/aspeed_ast27x0-fc.c @@ -XXX,XX +XXX,XX @@ 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; -- 2.51.0
The following changes since commit c77283dd5d79149f4e7e9edd00f65416c648ee59: Merge tag 'pull-request-2025-07-02' of https://gitlab.com/thuth/qemu into staging (2025-07-03 06:01:41 -0400) are available in the Git repository at: https://github.com/legoater/qemu/ tags/pull-aspeed-20250704 for you to fetch changes up to 3a34dad2c0d25cebafed40696bbbdeb7ff4b9c7d: tests/functional: Add gb200 tests (2025-07-03 17:36:45 +0200) ---------------------------------------------------------------- aspeed queue: * Improved AST2700 SoC modeling (SDMC, SCU) * Fixed hardware strapping of 'bletchley-bmc' machine * Added new Meta 'catalina-bmc' machine and functional test using OpenBMC * Improved AST2600 SCU protection key modeling * Introduced AST2600 SCU unit tests * Deprecated 'ast2700a0-evb' machine * Added new NVIDIA 'gb200-bmc' machine and functional test using OpenBMC ---------------------------------------------------------------- Ed Tanous (4): hw/arm/aspeed: Add second SPI chip to Aspeed model docs: add support for gb200-bmc hw/arm/aspeed: Add GB200 BMC target tests/functional: Add gb200 tests Jamin Lin (3): hw/misc/aspeed_sdmc: Skipping dram_init in u-boot for AST2700 hw/misc/aspeed_scu: Support the Frequency Counter Control register for AST2700 aspeed: Deprecate the ast2700a0-evb machine Patrick Williams (2): hw/arm/aspeed: bletchley: update hw strap values hw/arm/aspeed: add Catalina machine type Tan Siewert (2): hw/misc/aspeed_scu: Handle AST2600 protection key registers correctly tests/qtest: Add test for ASPEED SCU docs/about/deprecated.rst | 8 + docs/system/arm/aspeed.rst | 4 +- hw/arm/aspeed_eeprom.h | 3 + include/hw/arm/aspeed.h | 2 + hw/arm/aspeed.c | 285 ++++++++++++++++++++++- hw/arm/aspeed_eeprom.c | 21 ++ hw/misc/aspeed_scu.c | 22 +- hw/misc/aspeed_sdmc.c | 3 + tests/qtest/aspeed_scu-test.c | 231 ++++++++++++++++++ hw/arm/Kconfig | 1 + tests/functional/aspeed.py | 9 +- tests/functional/meson.build | 4 + tests/functional/test_arm_aspeed_catalina.py | 25 ++ tests/functional/test_arm_aspeed_gb200nvl_bmc.py | 26 +++ tests/qtest/meson.build | 1 + 15 files changed, 636 insertions(+), 9 deletions(-) create mode 100644 tests/qtest/aspeed_scu-test.c create mode 100755 tests/functional/test_arm_aspeed_catalina.py create mode 100644 tests/functional/test_arm_aspeed_gb200nvl_bmc.py
From: Jamin Lin <jamin_lin@aspeedtech.com> On AST2700 SoC, QEMU now sets BIT6 in VGA0 SCRATCH register to indicate that DDR training has completed, thus skipping the dram_init(). To align with the recent U-Boot changes, where the Main Control Register's BIT16 is checked to skip the dram_init() process, this patch sets BIT16 in the SDMC Main Control Register at reset time. This allows both the main U-Boot stage to correctly detect and bypass DRAM initialization when running under QEMU. Reference: - QEMU: https://github.com/qemu/qemu/commit/2d082fea485ee455a70ed3e963cdf9a70f34858a - U-Boot: https://github.com/AspeedTech-BMC/u-boot/commit/94e5435504fb0d8888f5c1bfd3fa284cdd6aaf9b Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250618080006.846355-2-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/misc/aspeed_sdmc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c index XXXXXXX..XXXXXXX 100644 --- a/hw/misc/aspeed_sdmc.c +++ b/hw/misc/aspeed_sdmc.c @@ -XXX,XX +XXX,XX @@ static void aspeed_2700_sdmc_reset(DeviceState *dev) /* Set ram size bit and defaults values */ s->regs[R_MAIN_CONF] = asc->compute_conf(s, 0); + /* Skipping dram init */ + s->regs[R_MAIN_CONTROL] = BIT(16); + if (s->unlocked) { s->regs[R_2700_PROT] = PROT_UNLOCKED; } -- 2.50.0
From: Jamin Lin <jamin_lin@aspeedtech.com> According to the datasheet: BIT[1] (SCU_FREQ_OSC_EN) enables the oscillator frequency measurement counter. BIT[6] (SCU_FREQ_DONE) indicates the measurement is finished. Firmware polls BIT[6] to determine when measurement is complete. The flag can be cleared by writing BIT[1] to 0. To simulate this hardware behavior in QEMU: If BIT[1] is set to 1, BIT[6] is immediately set to 1 to avoid firmware hanging during polling. If BIT[1] is cleared to 0, BIT[6] is also cleared to 0 to match hardware semantics. The initial value of this register is initialized to 0x80, reflecting the default value confirmed from an EVB register dump. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250618080006.846355-3-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/misc/aspeed_scu.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c index XXXXXXX..XXXXXXX 100644 --- a/hw/misc/aspeed_scu.c +++ b/hw/misc/aspeed_scu.c @@ -XXX,XX +XXX,XX @@ #define AST2700_SCUIO_UARTCLK_GEN TO_REG(0x330) #define AST2700_SCUIO_HUARTCLK_GEN TO_REG(0x334) #define AST2700_SCUIO_CLK_DUTY_MEAS_RST TO_REG(0x388) +#define AST2700_SCUIO_FREQ_CNT_CTL TO_REG(0x3A0) #define SCU_IO_REGION_SIZE 0x1000 @@ -XXX,XX +XXX,XX @@ static void aspeed_ast2700_scuio_write(void *opaque, hwaddr offset, s->regs[reg - 1] ^= data; updated = true; break; + case AST2700_SCUIO_FREQ_CNT_CTL: + s->regs[reg] = deposit32(s->regs[reg], 6, 1, !!(data & BIT(1))); + updated = true; + break; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Unhandled write at offset 0x%" HWADDR_PRIx "\n", @@ -XXX,XX +XXX,XX @@ static const uint32_t ast2700_a0_resets_io[ASPEED_AST2700_SCU_NR_REGS] = { [AST2700_SCUIO_UARTCLK_GEN] = 0x00014506, [AST2700_SCUIO_HUARTCLK_GEN] = 0x000145c0, [AST2700_SCUIO_CLK_DUTY_MEAS_RST] = 0x0c9100d2, + [AST2700_SCUIO_FREQ_CNT_CTL] = 0x00000080, }; static void aspeed_2700_scuio_class_init(ObjectClass *klass, const void *data) -- 2.50.0
From: Patrick Williams <patrick@stwcx.xyz> Update the Bletchley hardware strap register values per actual hardware: ``` root@bmc:~# devmem 0x1e6e2500 0x00002000 root@bmc:~# devmem 0x1e6e2510 0x00000801 ``` Signed-off-by: Patrick Williams <patrick@stwcx.xyz> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250619035850.2682690-1-patrick@stwcx.xyz Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -XXX,XX +XXX,XX @@ struct AspeedMachineState { #define FUJI_BMC_HW_STRAP2 0x00000000 /* Bletchley hardware value */ -/* TODO: Leave same as EVB for now. */ -#define BLETCHLEY_BMC_HW_STRAP1 AST2600_EVB_HW_STRAP1 -#define BLETCHLEY_BMC_HW_STRAP2 AST2600_EVB_HW_STRAP2 +#define BLETCHLEY_BMC_HW_STRAP1 0x00002000 +#define BLETCHLEY_BMC_HW_STRAP2 0x00000801 /* Qualcomm DC-SCM hardware value */ #define QCOM_DC_SCM_V1_BMC_HW_STRAP1 0x00000000 -- 2.50.0
From: Patrick Williams <patrick@stwcx.xyz> Add the 'catalina-bmc' machine type based on the kernel DTS[1] as of 6.16-rc2. The i2c model is as complete as the current QEMU models support, but in some cases I substituted devices that are close enough for present functionality. Strap registers are were verified with hardware. This has been tested with an openbmc image built from [2]. Add a functional test in line with Bletchley, pointing at an image obtained from the OpenBMC Jenkins server. [1]: https://github.com/torvalds/linux/blob/v6.16-rc2/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-catalina.dts [2]: https://github.com/openbmc/openbmc/commit/5bc73ec261f981d5e586bda5ac78eb0cbd5f92b0 Signed-off-by: Patrick Williams <patrick@stwcx.xyz> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250619151458.2831859-1-patrick@stwcx.xyz Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed.c | 200 +++++++++++++++++++ hw/arm/Kconfig | 1 + tests/functional/meson.build | 2 + tests/functional/test_arm_aspeed_catalina.py | 25 +++ 4 files changed, 228 insertions(+) create mode 100755 tests/functional/test_arm_aspeed_catalina.py diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -XXX,XX +XXX,XX @@ #include "hw/i2c/i2c_mux_pca954x.h" #include "hw/i2c/smbus_eeprom.h" #include "hw/gpio/pca9552.h" +#include "hw/gpio/pca9554.h" #include "hw/nvram/eeprom_at24c.h" #include "hw/sensor/tmp105.h" #include "hw/misc/led.h" @@ -XXX,XX +XXX,XX @@ static void fuji_bmc_i2c_init(AspeedMachineState *bmc) } #define TYPE_TMP421 "tmp421" +#define TYPE_DS1338 "ds1338" + +/* Catalina hardware value */ +#define CATALINA_BMC_HW_STRAP1 0x00002002 +#define CATALINA_BMC_HW_STRAP2 0x00000800 + +#define CATALINA_BMC_RAM_SIZE ASPEED_RAM_SIZE(2 * GiB) + +static void catalina_bmc_i2c_init(AspeedMachineState *bmc) +{ + /* Reference from v6.16-rc2 aspeed-bmc-facebook-catalina.dts */ + + AspeedSoCState *soc = bmc->soc; + I2CBus *i2c[16] = {}; + I2CSlave *i2c_mux; + + /* busses 0-15 are all used. */ + for (int i = 0; i < ARRAY_SIZE(i2c); i++) { + i2c[i] = aspeed_i2c_get_bus(&soc->i2c, i); + } + + /* &i2c0 */ + /* i2c-mux@71 (PCA9546) on i2c0 */ + i2c_slave_create_simple(i2c[0], TYPE_PCA9546, 0x71); + + /* i2c-mux@72 (PCA9546) on i2c0 */ + i2c_mux = i2c_slave_create_simple(i2c[0], TYPE_PCA9546, 0x72); + + /* i2c0mux1ch1 */ + /* io_expander7 - pca9535@20 */ + i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 1), + TYPE_PCA9552, 0x20); + /* eeprom@50 */ + at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x50, 8 * KiB); + + /* i2c-mux@73 (PCA9546) on i2c0 */ + i2c_slave_create_simple(i2c[0], TYPE_PCA9546, 0x73); + + /* i2c-mux@75 (PCA9546) on i2c0 */ + i2c_slave_create_simple(i2c[0], TYPE_PCA9546, 0x75); + + /* i2c-mux@76 (PCA9546) on i2c0 */ + i2c_mux = i2c_slave_create_simple(i2c[0], TYPE_PCA9546, 0x76); + + /* i2c0mux4ch1 */ + /* io_expander8 - pca9535@21 */ + i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 1), + TYPE_PCA9552, 0x21); + /* eeprom@50 */ + at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 1), 0x50, 8 * KiB); + + /* i2c-mux@77 (PCA9546) on i2c0 */ + i2c_slave_create_simple(i2c[0], TYPE_PCA9546, 0x77); + + + /* &i2c1 */ + /* i2c-mux@70 (PCA9548) on i2c1 */ + i2c_mux = i2c_slave_create_simple(i2c[1], TYPE_PCA9548, 0x70); + /* i2c1mux0ch0 */ + /* ina238@41 - no model */ + /* ina238@42 - no model */ + /* ina238@44 - no model */ + /* i2c1mux0ch1 */ + /* ina238@41 - no model */ + /* ina238@43 - no model */ + /* i2c1mux0ch4 */ + /* ltc4287@42 - no model */ + /* ltc4287@43 - no model */ + + /* i2c1mux0ch5 */ + /* eeprom@54 */ + at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 5), 0x54, 8 * KiB); + /* tpm75@4f */ + i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), TYPE_TMP75, 0x4f); + + /* i2c1mux0ch6 */ + /* io_expander5 - pca9554@27 */ + i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 6), + TYPE_PCA9554, 0x27); + /* io_expander6 - pca9555@25 */ + i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 6), + TYPE_PCA9552, 0x25); + /* eeprom@51 */ + at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 6), 0x51, 8 * KiB); + + /* i2c1mux0ch7 */ + /* eeprom@53 */ + at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 7), 0x53, 8 * KiB); + /* temperature-sensor@4b - tmp75 */ + i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 7), TYPE_TMP75, 0x4b); + + /* &i2c2 */ + /* io_expander0 - pca9555@20 */ + i2c_slave_create_simple(i2c[2], TYPE_PCA9552, 0x20); + /* io_expander0 - pca9555@21 */ + i2c_slave_create_simple(i2c[2], TYPE_PCA9552, 0x21); + /* io_expander0 - pca9555@27 */ + i2c_slave_create_simple(i2c[2], TYPE_PCA9552, 0x27); + /* eeprom@50 */ + at24c_eeprom_init(i2c[2], 0x50, 8 * KiB); + /* eeprom@51 */ + at24c_eeprom_init(i2c[2], 0x51, 8 * KiB); + + /* &i2c5 */ + /* i2c-mux@70 (PCA9548) on i2c5 */ + i2c_mux = i2c_slave_create_simple(i2c[5], TYPE_PCA9548, 0x70); + /* i2c5mux0ch6 */ + /* eeprom@52 */ + at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 6), 0x52, 8 * KiB); + /* i2c5mux0ch7 */ + /* ina230@40 - no model */ + /* ina230@41 - no model */ + /* ina230@44 - no model */ + /* ina230@45 - no model */ + + /* &i2c6 */ + /* io_expander3 - pca9555@21 */ + i2c_slave_create_simple(i2c[6], TYPE_PCA9552, 0x21); + /* rtc@6f - nct3018y */ + i2c_slave_create_simple(i2c[6], TYPE_DS1338, 0x6f); + + /* &i2c9 */ + /* io_expander4 - pca9555@4f */ + i2c_slave_create_simple(i2c[9], TYPE_PCA9552, 0x4f); + /* temperature-sensor@4b - tpm75 */ + i2c_slave_create_simple(i2c[9], TYPE_TMP75, 0x4b); + /* eeprom@50 */ + at24c_eeprom_init(i2c[9], 0x50, 8 * KiB); + /* eeprom@56 */ + at24c_eeprom_init(i2c[9], 0x56, 8 * KiB); + + /* &i2c10 */ + /* temperature-sensor@1f - tpm421 */ + i2c_slave_create_simple(i2c[10], TYPE_TMP421, 0x1f); + /* eeprom@50 */ + at24c_eeprom_init(i2c[10], 0x50, 8 * KiB); + + /* &i2c11 */ + /* ssif-bmc@10 - no model */ + + /* &i2c12 */ + /* eeprom@50 */ + at24c_eeprom_init(i2c[12], 0x50, 8 * KiB); + + /* &i2c13 */ + /* eeprom@50 */ + at24c_eeprom_init(i2c[13], 0x50, 8 * KiB); + /* eeprom@54 */ + at24c_eeprom_init(i2c[13], 0x54, 256); + /* eeprom@55 */ + at24c_eeprom_init(i2c[13], 0x55, 256); + /* eeprom@57 */ + at24c_eeprom_init(i2c[13], 0x57, 256); + + /* &i2c14 */ + /* io_expander9 - pca9555@10 */ + i2c_slave_create_simple(i2c[14], TYPE_PCA9552, 0x10); + /* io_expander10 - pca9555@11 */ + i2c_slave_create_simple(i2c[14], TYPE_PCA9552, 0x11); + /* io_expander11 - pca9555@12 */ + i2c_slave_create_simple(i2c[14], TYPE_PCA9552, 0x12); + /* io_expander12 - pca9555@13 */ + i2c_slave_create_simple(i2c[14], TYPE_PCA9552, 0x13); + /* io_expander13 - pca9555@14 */ + i2c_slave_create_simple(i2c[14], TYPE_PCA9552, 0x14); + /* io_expander14 - pca9555@15 */ + i2c_slave_create_simple(i2c[14], TYPE_PCA9552, 0x15); + + /* &i2c15 */ + /* temperature-sensor@1f - tmp421 */ + i2c_slave_create_simple(i2c[15], TYPE_TMP421, 0x1f); + /* eeprom@52 */ + at24c_eeprom_init(i2c[15], 0x52, 8 * KiB); +} static void bletchley_bmc_i2c_init(AspeedMachineState *bmc) { @@ -XXX,XX +XXX,XX @@ static void aspeed_machine_bletchley_class_init(ObjectClass *oc, aspeed_machine_class_init_cpus_defaults(mc); } +static void aspeed_machine_catalina_class_init(ObjectClass *oc, + const void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); + + mc->desc = "Facebook Catalina BMC (Cortex-A7)"; + amc->soc_name = "ast2600-a3"; + amc->hw_strap1 = CATALINA_BMC_HW_STRAP1; + amc->hw_strap2 = CATALINA_BMC_HW_STRAP2; + amc->fmc_model = "w25q01jvq"; + amc->spi_model = NULL; + amc->num_cs = 2; + amc->macs_mask = ASPEED_MAC2_ON; + amc->i2c_init = catalina_bmc_i2c_init; + mc->auto_create_sdcard = true; + mc->default_ram_size = CATALINA_BMC_RAM_SIZE; + aspeed_machine_class_init_cpus_defaults(mc); + aspeed_machine_ast2600_class_emmc_init(oc); +} + static void fby35_reset(MachineState *state, ResetType type) { AspeedMachineState *bmc = ASPEED_MACHINE(state); @@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_machine_types[] = { .name = MACHINE_TYPE_NAME("bletchley-bmc"), .parent = TYPE_ASPEED_MACHINE, .class_init = aspeed_machine_bletchley_class_init, + }, { + .name = MACHINE_TYPE_NAME("catalina-bmc"), + .parent = TYPE_ASPEED_MACHINE, + .class_init = aspeed_machine_catalina_class_init, }, { .name = MACHINE_TYPE_NAME("fby35-bmc"), .parent = MACHINE_TYPE_NAME("ast2600-evb"), diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -XXX,XX +XXX,XX @@ config ASPEED_SOC select I2C select DPS310 select PCA9552 + select PCA9554 select SERIAL_MM select SMBUS_EEPROM select PCA954X diff --git a/tests/functional/meson.build b/tests/functional/meson.build index XXXXXXX..XXXXXXX 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -XXX,XX +XXX,XX @@ test_timeouts = { 'arm_aspeed_ast2500' : 720, 'arm_aspeed_ast2600' : 1200, 'arm_aspeed_bletchley' : 480, + 'arm_aspeed_catalina' : 480, 'arm_aspeed_rainier' : 480, 'arm_bpim2u' : 500, 'arm_collie' : 180, @@ -XXX,XX +XXX,XX @@ tests_arm_system_thorough = [ 'arm_aspeed_ast2500', 'arm_aspeed_ast2600', 'arm_aspeed_bletchley', + 'arm_aspeed_catalina', 'arm_aspeed_rainier', 'arm_bpim2u', 'arm_canona1100', diff --git a/tests/functional/test_arm_aspeed_catalina.py b/tests/functional/test_arm_aspeed_catalina.py new file mode 100755 index XXXXXXX..XXXXXXX --- /dev/null +++ b/tests/functional/test_arm_aspeed_catalina.py @@ -XXX,XX +XXX,XX @@ +#!/usr/bin/env python3 +# +# Functional test that boots the ASPEED machines +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from qemu_test import Asset +from aspeed import AspeedTest + + +class CatalinaMachine(AspeedTest): + + ASSET_CATALINA_FLASH = Asset( + 'https://github.com/legoater/qemu-aspeed-boot/raw/a866feb5ef81245b4827a214584bf6bcc72939f6/images/catalina-bmc/obmc-phosphor-image-catalina-20250619123021.static.mtd.xz', + '287402e1ba021991e06be1d098f509444a02a3d81a73a932f66528b159e864f9') + + def test_arm_ast2600_catalina_openbmc(self): + image_path = self.uncompress(self.ASSET_CATALINA_FLASH) + + self.do_test_arm_aspeed_openbmc('catalina-bmc', image=image_path, + uboot='2019.04', cpu_id='0xf00', + soc='AST2600 rev A3') + +if __name__ == '__main__': + AspeedTest.main() -- 2.50.0
From: Tan Siewert <tan@siewert.io> The AST2600 SCU has two protection key registers (0x00 and 0x10) that both need to be unlocked. (Un-)locking 0x00 modifies both protection key registers, while modifying 0x10 only modifies itself. This commit updates the SCU write logic to reject writes unless both protection key registers are unlocked, matching the behaviour of real hardware. Signed-off-by: Tan Siewert <tan@siewert.io> Reviewed-by: Jamin Lin <jamin_lin@aspeedtech.com> Link: https://lore.kernel.org/qemu-devel/20250619085329.42125-1-tan@siewert.io Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/misc/aspeed_scu.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c index XXXXXXX..XXXXXXX 100644 --- a/hw/misc/aspeed_scu.c +++ b/hw/misc/aspeed_scu.c @@ -XXX,XX +XXX,XX @@ #define BMC_DEV_ID TO_REG(0x1A4) #define AST2600_PROT_KEY TO_REG(0x00) +#define AST2600_PROT_KEY2 TO_REG(0x10) #define AST2600_SILICON_REV TO_REG(0x04) #define AST2600_SILICON_REV2 TO_REG(0x14) #define AST2600_SYS_RST_CTRL TO_REG(0x40) @@ -XXX,XX +XXX,XX @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, int reg = TO_REG(offset); /* Truncate here so bitwise operations below behave as expected */ uint32_t data = data64; + bool prot_data_state = data == ASPEED_SCU_PROT_KEY; + bool unlocked = s->regs[AST2600_PROT_KEY] && s->regs[AST2600_PROT_KEY2]; if (reg >= ASPEED_AST2600_SCU_NR_REGS) { qemu_log_mask(LOG_GUEST_ERROR, @@ -XXX,XX +XXX,XX @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, return; } - if (reg > PROT_KEY && !s->regs[PROT_KEY]) { + if ((reg != AST2600_PROT_KEY && reg != AST2600_PROT_KEY2) && !unlocked) { qemu_log_mask(LOG_GUEST_ERROR, "%s: SCU is locked!\n", __func__); + return; } trace_aspeed_scu_write(offset, size, data); switch (reg) { case AST2600_PROT_KEY: - s->regs[reg] = (data == ASPEED_SCU_PROT_KEY) ? 1 : 0; + /* + * Writing a value to SCU000 will modify both protection + * registers to each protection register individually. + */ + s->regs[AST2600_PROT_KEY] = prot_data_state; + s->regs[AST2600_PROT_KEY2] = prot_data_state; + return; + case AST2600_PROT_KEY2: + s->regs[AST2600_PROT_KEY2] = prot_data_state; return; case AST2600_HW_STRAP1: case AST2600_HW_STRAP2: -- 2.50.0
From: Tan Siewert <tan@siewert.io> This adds basic tests for the ASPEED System Control Unit (SCU) and its protection mechanism on the AST2500 and AST2600 platforms. The tests verify: - That SCU protection registers can be unlocked and locked again - That modifying the primary protection register on AST2600 also affects the secondary one - That writes to protected SCU registers are blocked unless protection registers are unlocked explicitly These tests ensure proper emulation of hardware locking behaviour and help catch regressions in SCU access logic. Signed-off-by: Tan Siewert <tan@siewert.io> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250630112646.74944-1-tan@siewert.io [ clg: Reordered file list in meson.build ] Signed-off-by: Cédric Le Goater <clg@redhat.com> --- tests/qtest/aspeed_scu-test.c | 231 ++++++++++++++++++++++++++++++++++ tests/qtest/meson.build | 1 + 2 files changed, 232 insertions(+) create mode 100644 tests/qtest/aspeed_scu-test.c diff --git a/tests/qtest/aspeed_scu-test.c b/tests/qtest/aspeed_scu-test.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/tests/qtest/aspeed_scu-test.c @@ -XXX,XX +XXX,XX @@ +/* + * QTest testcase for the ASPEED AST2500 and AST2600 SCU. + * + * SPDX-License-Identifier: GPL-2.0-or-later + * Copyright (C) 2025 Tan Siewert + */ + +#include "qemu/osdep.h" +#include "libqtest-single.h" + +/* + * SCU base, as well as protection key are + * the same on AST2500 and 2600. + */ +#define AST_SCU_BASE 0x1E6E2000 +#define AST_SCU_PROT_LOCK_STATE 0x0 +#define AST_SCU_PROT_LOCK_VALUE 0x2 +#define AST_SCU_PROT_UNLOCK_STATE 0x1 +#define AST_SCU_PROT_UNLOCK_VALUE 0x1688A8A8 + +#define AST2500_MACHINE "-machine ast2500-evb" +#define AST2500_SCU_PROT_REG 0x00 +#define AST2500_SCU_MISC_2_CONTROL_REG 0x4C + +#define AST2600_MACHINE "-machine ast2600-evb" +/* AST2600 has two protection registers */ +#define AST2600_SCU_PROT_REG 0x000 +#define AST2600_SCU_PROT_REG2 0x010 +#define AST2600_SCU_MISC_2_CONTROL_REG 0x0C4 + +#define TEST_LOCK_ARBITRARY_VALUE 0xABCDEFAB + +/** + * Assert that a given register matches an expected value. + * + * Reads the register and checks if its value equals the expected value. + * + * @param *s - QTest machine state + * @param reg - Address of the register to be checked + * @param expected - Expected register value + */ +static inline void assert_register_eq(QTestState *s, + uint32_t reg, + uint32_t expected) +{ + uint32_t value = qtest_readl(s, reg); + g_assert_cmphex(value, ==, expected); +} + +/** + * Assert that a given register does not match a specific value. + * + * Reads the register and checks that its value is not equal to the + * provided value. + * + * @param *s - QTest machine state + * @param reg - Address of the register to be checked + * @param not_expected - Value the register must not contain + */ +static inline void assert_register_neq(QTestState *s, + uint32_t reg, + uint32_t not_expected) +{ + uint32_t value = qtest_readl(s, reg); + g_assert_cmphex(value, !=, not_expected); +} + +/** + * Test whether the SCU can be locked and unlocked correctly. + * + * When testing multiple registers, this function assumes that writing + * to the first register also affects the others. However, writing to + * any other register only affects itself. + * + * @param *machine - input machine configuration, passed directly + * to QTest + * @param regs[] - List of registers to be checked + * @param regc - amount of arguments for registers to be checked + */ +static void test_protection_register(const char *machine, + const uint32_t regs[], + const int regc) +{ + QTestState *s = qtest_init(machine); + + for (int i = 0; i < regc; i++) { + uint32_t reg = regs[i]; + + qtest_writel(s, reg, AST_SCU_PROT_UNLOCK_VALUE); + assert_register_eq(s, reg, AST_SCU_PROT_UNLOCK_STATE); + + /** + * Check that other registers are unlocked too, if more + * than one is available. + */ + if (regc > 1 && i == 0) { + /* Initialise at 1 instead of 0 to skip first */ + for (int j = 1; j < regc; j++) { + uint32_t add_reg = regs[j]; + assert_register_eq(s, add_reg, AST_SCU_PROT_UNLOCK_STATE); + } + } + + /* Lock the register again */ + qtest_writel(s, reg, AST_SCU_PROT_LOCK_VALUE); + assert_register_eq(s, reg, AST_SCU_PROT_LOCK_STATE); + + /* And the same for locked state */ + if (regc > 1 && i == 0) { + /* Initialise at 1 instead of 0 to skip first */ + for (int j = 1; j < regc; j++) { + uint32_t add_reg = regs[j]; + assert_register_eq(s, add_reg, AST_SCU_PROT_LOCK_STATE); + } + } + } + + qtest_quit(s); +} + +static void test_2500_protection_register(void) +{ + uint32_t regs[] = { AST_SCU_BASE + AST2500_SCU_PROT_REG }; + + test_protection_register(AST2500_MACHINE, + regs, + ARRAY_SIZE(regs)); +} + +static void test_2600_protection_register(void) +{ + /** + * The AST2600 has two protection registers, both + * being required to be unlocked to do any operation. + * + * Modifying SCU000 also modifies SCU010, but modifying + * SCU010 only will keep SCU000 untouched. + */ + uint32_t regs[] = { AST_SCU_BASE + AST2600_SCU_PROT_REG, + AST_SCU_BASE + AST2600_SCU_PROT_REG2 }; + + test_protection_register(AST2600_MACHINE, + regs, + ARRAY_SIZE(regs)); +} + +/** + * Test if SCU register writes are correctly allowed or blocked + * depending on the protection register state. + * + * The test first locks the protection register and verifies that + * writes to the target SCU register are rejected. It then unlocks + * the protection register and confirms that the written value is + * retained when unlocked. + * + * @param *machine - input machine configuration, passed directly + * to QTest + * @param protection_register - first SCU protection key register + * (only one for keeping it simple) + * @param test_register - Register to be used for writing arbitrary + * values + */ +static void test_write_permission_lock_state(const char *machine, + const uint32_t protection_register, + const uint32_t test_register) +{ + QTestState *s = qtest_init(machine); + + /* Arbitrary value to lock provided SCU protection register */ + qtest_writel(s, protection_register, AST_SCU_PROT_LOCK_VALUE); + + /* Ensure that the SCU is really locked */ + assert_register_eq(s, protection_register, AST_SCU_PROT_LOCK_STATE); + + /* Write a known arbitrary value to test that the write is blocked */ + qtest_writel(s, test_register, TEST_LOCK_ARBITRARY_VALUE); + + /* We do not want to have the written value to be saved */ + assert_register_neq(s, test_register, TEST_LOCK_ARBITRARY_VALUE); + + /** + * Unlock the SCU and verify that it can be written to. + * Assumes that the first SCU protection register is sufficient to + * unlock all protection registers, if multiple are present. + */ + qtest_writel(s, protection_register, AST_SCU_PROT_UNLOCK_VALUE); + assert_register_eq(s, protection_register, AST_SCU_PROT_UNLOCK_STATE); + + /* Write a known arbitrary value to test that the write works */ + qtest_writel(s, test_register, TEST_LOCK_ARBITRARY_VALUE); + + /* Ensure that the written value is retained */ + assert_register_eq(s, test_register, TEST_LOCK_ARBITRARY_VALUE); + + qtest_quit(s); +} + +static void test_2500_write_permission_lock_state(void) +{ + test_write_permission_lock_state( + AST2500_MACHINE, + AST_SCU_BASE + AST2500_SCU_PROT_REG, + AST_SCU_BASE + AST2500_SCU_MISC_2_CONTROL_REG + ); +} + +static void test_2600_write_permission_lock_state(void) +{ + test_write_permission_lock_state( + AST2600_MACHINE, + AST_SCU_BASE + AST2600_SCU_PROT_REG, + AST_SCU_BASE + AST2600_SCU_MISC_2_CONTROL_REG + ); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + qtest_add_func("/ast2500/scu/protection_register", + test_2500_protection_register); + qtest_add_func("/ast2600/scu/protection_register", + test_2600_protection_register); + + qtest_add_func("/ast2500/scu/write_permission_lock_state", + test_2500_write_permission_lock_state); + qtest_add_func("/ast2600/scu/write_permission_lock_state", + test_2600_write_permission_lock_state); + + return g_test_run(); +} diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index XXXXXXX..XXXXXXX 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -XXX,XX +XXX,XX @@ qtests_npcm8xx = \ qtests_aspeed = \ ['aspeed_gpio-test', 'aspeed_hace-test', + 'aspeed_scu-test', 'aspeed_smc-test'] qtests_aspeed64 = \ ['ast2700-gpio-test', -- 2.50.0
From: Jamin Lin <jamin_lin@aspeedtech.com> The ast2700a0-evb machine represents the first revision of the AST2700 and serves as the initial engineering sample rather than a production version. A newer revision, A1, is now supported, and the ast2700a1-evb should replace the older A0 version. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250703052400.2927831-1-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- docs/about/deprecated.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/about/deprecated.rst +++ b/docs/about/deprecated.rst @@ -XXX,XX +XXX,XX @@ deprecated; use the new name ``dtb-randomness`` instead. The new name better reflects the way this property affects all random data within the device tree blob, not just the ``kaslr-seed`` node. +Arm ``ast2700a0-evb`` machine (since 10.1) +'''''''''''''''''''''''''''''''''''''''''' + +The ``ast2700a0-evb`` machine represents the first revision of the AST2700 +and serves as the initial engineering sample rather than a production version. +A newer revision, A1, is now supported, and the ``ast2700a1-evb`` should +replace the older A0 version. + Mips ``mipssim`` machine (since 10.0) ''''''''''''''''''''''''''''''''''''' -- 2.50.0
From: Ed Tanous <etanous@nvidia.com> Aspeed2600 has two spi lanes; Add a new struct that can mount the second SPI. Signed-off-by: Ed Tanous <etanous@nvidia.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250703144249.3348879-2-etanous@nvidia.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- include/hw/arm/aspeed.h | 2 ++ hw/arm/aspeed.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/arm/aspeed.h +++ b/include/hw/arm/aspeed.h @@ -XXX,XX +XXX,XX @@ struct AspeedMachineClass { uint32_t hw_strap2; const char *fmc_model; const char *spi_model; + const char *spi2_model; uint32_t num_cs; + uint32_t num_cs2; uint32_t macs_mask; void (*i2c_init)(AspeedMachineState *bmc); uint32_t uart_default; diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -XXX,XX +XXX,XX @@ static void aspeed_machine_init(MachineState *machine) aspeed_board_init_flashes(&bmc->soc->spi[0], bmc->spi_model ? bmc->spi_model : amc->spi_model, 1, amc->num_cs); + aspeed_board_init_flashes(&bmc->soc->spi[1], + amc->spi2_model, 1, amc->num_cs2); } if (machine->kernel_filename && sc->num_cpus > 1) { -- 2.50.0
From: Ed Tanous <etanous@nvidia.com> This patch updates the docs for support of gb200-bmc. Signed-off-by: Ed Tanous <etanous@nvidia.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250703144249.3348879-3-etanous@nvidia.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- docs/system/arm/aspeed.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/arm/aspeed.rst +++ b/docs/system/arm/aspeed.rst @@ -XXX,XX +XXX,XX @@ -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``, ``bletchley-bmc``, ``fuji-bmc``, ``gb200nvl-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 @@ -XXX,XX +XXX,XX @@ AST2600 SoC based machines : - ``fuji-bmc`` Facebook Fuji BMC - ``bletchley-bmc`` Facebook Bletchley BMC - ``fby35-bmc`` Facebook fby35 BMC +- ``gb200nvl-bmc`` Nvidia GB200nvl BMC - ``qcom-dc-scm-v1-bmc`` Qualcomm DC-SCM V1 BMC - ``qcom-firework-bmc`` Qualcomm Firework BMC -- 2.50.0
From: Ed Tanous <etanous@nvidia.com> GB200nvl72 is a system for for accelerated compute. This is a model for the BMC target within the system. This is based on the device tree aspeed-bmc-nvidia-gb200nvl-bmc.dts from: [1] https://github.com/openbmc/linux/blob/dev-6.6/arch/arm/boot/dts/aspeed/aspeed-bmc-nvidia-gb200nvl-bmc.dts Signed-off-by: Ed Tanous <etanous@nvidia.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250703144249.3348879-4-etanous@nvidia.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_eeprom.h | 3 ++ hw/arm/aspeed.c | 78 ++++++++++++++++++++++++++++++++++++++++++ hw/arm/aspeed_eeprom.c | 21 ++++++++++++ 3 files changed, 102 insertions(+) diff --git a/hw/arm/aspeed_eeprom.h b/hw/arm/aspeed_eeprom.h index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_eeprom.h +++ b/hw/arm/aspeed_eeprom.h @@ -XXX,XX +XXX,XX @@ extern const size_t rainier_bb_fruid_len; extern const uint8_t rainier_bmc_fruid[]; extern const size_t rainier_bmc_fruid_len; +extern const uint8_t gb200nvl_bmc_fruid[]; +extern const size_t gb200nvl_bmc_fruid_len; + #endif diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -XXX,XX +XXX,XX @@ struct AspeedMachineState { #define BLETCHLEY_BMC_HW_STRAP1 0x00002000 #define BLETCHLEY_BMC_HW_STRAP2 0x00000801 +/* GB200NVL hardware value */ +#define GB200NVL_BMC_HW_STRAP1 AST2600_EVB_HW_STRAP1 +#define GB200NVL_BMC_HW_STRAP2 AST2600_EVB_HW_STRAP2 + /* Qualcomm DC-SCM hardware value */ #define QCOM_DC_SCM_V1_BMC_HW_STRAP1 0x00000000 #define QCOM_DC_SCM_V1_BMC_HW_STRAP2 0x00000041 @@ -XXX,XX +XXX,XX @@ static void create_pca9552(AspeedSoCState *soc, int bus_id, int addr) TYPE_PCA9552, addr); } +static I2CSlave *create_pca9554(AspeedSoCState *soc, int bus_id, int addr) +{ + return i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, bus_id), + TYPE_PCA9554, addr); +} + static void sonorapass_bmc_i2c_init(AspeedMachineState *bmc) { AspeedSoCState *soc = bmc->soc; @@ -XXX,XX +XXX,XX @@ static void bletchley_bmc_i2c_init(AspeedMachineState *bmc) i2c_slave_create_simple(i2c[12], TYPE_PCA9552, 0x67); } + +static void gb200nvl_bmc_i2c_init(AspeedMachineState *bmc) +{ + AspeedSoCState *soc = bmc->soc; + I2CBus *i2c[15] = {}; + DeviceState *dev; + for (int i = 0; i < sizeof(i2c) / sizeof(i2c[0]); i++) { + if ((i == 11) || (i == 12) || (i == 13)) { + continue; + } + i2c[i] = aspeed_i2c_get_bus(&soc->i2c, i); + } + + /* Bus 5 Expander */ + create_pca9554(soc, 4, 0x21); + + /* Mux I2c Expanders */ + i2c_slave_create_simple(i2c[5], "pca9546", 0x71); + i2c_slave_create_simple(i2c[5], "pca9546", 0x72); + i2c_slave_create_simple(i2c[5], "pca9546", 0x73); + i2c_slave_create_simple(i2c[5], "pca9546", 0x75); + i2c_slave_create_simple(i2c[5], "pca9546", 0x76); + i2c_slave_create_simple(i2c[5], "pca9546", 0x77); + + /* Bus 10 */ + dev = DEVICE(create_pca9554(soc, 9, 0x20)); + + /* Set FPGA_READY */ + object_property_set_str(OBJECT(dev), "pin1", "high", &error_fatal); + + create_pca9554(soc, 9, 0x21); + at24c_eeprom_init(i2c[9], 0x50, 64 * KiB); + at24c_eeprom_init(i2c[9], 0x51, 64 * KiB); + + /* Bus 11 */ + at24c_eeprom_init_rom(i2c[10], 0x50, 256, gb200nvl_bmc_fruid, + gb200nvl_bmc_fruid_len); +} + static void fby35_i2c_init(AspeedMachineState *bmc) { AspeedSoCState *soc = bmc->soc; @@ -XXX,XX +XXX,XX @@ static void aspeed_machine_catalina_class_init(ObjectClass *oc, aspeed_machine_ast2600_class_emmc_init(oc); } +#define GB200NVL_BMC_RAM_SIZE ASPEED_RAM_SIZE(1 * GiB) + +static void aspeed_machine_gb200nvl_class_init(ObjectClass *oc, + const void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); + + mc->desc = "Nvidia GB200NVL BMC (Cortex-A7)"; + amc->soc_name = "ast2600-a3"; + amc->hw_strap1 = GB200NVL_BMC_HW_STRAP1; + amc->hw_strap2 = GB200NVL_BMC_HW_STRAP2; + amc->fmc_model = "mx66u51235f"; + amc->spi_model = "mx66u51235f"; + amc->num_cs = 2; + + amc->spi2_model = "mx66u51235f"; + amc->num_cs2 = 1; + amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON; + amc->i2c_init = gb200nvl_bmc_i2c_init; + mc->default_ram_size = GB200NVL_BMC_RAM_SIZE; + aspeed_machine_class_init_cpus_defaults(mc); + aspeed_machine_ast2600_class_emmc_init(oc); +} + static void fby35_reset(MachineState *state, ResetType type) { AspeedMachineState *bmc = ASPEED_MACHINE(state); @@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_machine_types[] = { .name = MACHINE_TYPE_NAME("bletchley-bmc"), .parent = TYPE_ASPEED_MACHINE, .class_init = aspeed_machine_bletchley_class_init, + }, { + .name = MACHINE_TYPE_NAME("gb200nvl-bmc"), + .parent = TYPE_ASPEED_MACHINE, + .class_init = aspeed_machine_gb200nvl_class_init, }, { .name = MACHINE_TYPE_NAME("catalina-bmc"), .parent = TYPE_ASPEED_MACHINE, diff --git a/hw/arm/aspeed_eeprom.c b/hw/arm/aspeed_eeprom.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_eeprom.c +++ b/hw/arm/aspeed_eeprom.c @@ -XXX,XX +XXX,XX @@ const uint8_t rainier_bmc_fruid[] = { 0x31, 0x50, 0x46, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, }; +const uint8_t gb200nvl_bmc_fruid[] = { + 0x01, 0x00, 0x00, 0x01, 0x0b, 0x00, 0x00, 0xf3, 0x01, 0x0a, 0x19, 0x1f, + 0x0f, 0xe6, 0xc6, 0x4e, 0x56, 0x49, 0x44, 0x49, 0x41, 0xc5, 0x50, 0x33, + 0x38, 0x30, 0x39, 0xcd, 0x31, 0x35, 0x38, 0x33, 0x33, 0x32, 0x34, 0x38, + 0x30, 0x30, 0x31, 0x35, 0x30, 0xd2, 0x36, 0x39, 0x39, 0x2d, 0x31, 0x33, + 0x38, 0x30, 0x39, 0x2d, 0x30, 0x34, 0x30, 0x34, 0x2d, 0x36, 0x30, 0x30, + 0xc0, 0x01, 0x01, 0xd6, 0x4d, 0x41, 0x43, 0x3a, 0x20, 0x33, 0x43, 0x3a, + 0x36, 0x44, 0x3a, 0x36, 0x36, 0x3a, 0x31, 0x34, 0x3a, 0x43, 0x38, 0x3a, + 0x37, 0x41, 0xc1, 0x3b, 0x01, 0x09, 0x19, 0xc6, 0x4e, 0x56, 0x49, 0x44, + 0x49, 0x41, 0xc9, 0x50, 0x33, 0x38, 0x30, 0x39, 0x2d, 0x42, 0x4d, 0x43, + 0xd2, 0x36, 0x39, 0x39, 0x2d, 0x31, 0x33, 0x38, 0x30, 0x39, 0x2d, 0x30, + 0x34, 0x30, 0x34, 0x2d, 0x36, 0x30, 0x30, 0xc4, 0x41, 0x45, 0x2e, 0x31, + 0xcd, 0x31, 0x35, 0x38, 0x33, 0x33, 0x32, 0x34, 0x38, 0x30, 0x30, 0x31, + 0x35, 0x30, 0xc0, 0xc4, 0x76, 0x30, 0x2e, 0x31, 0xc1, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + +}; + const size_t tiogapass_bmc_fruid_len = sizeof(tiogapass_bmc_fruid); const size_t fby35_nic_fruid_len = sizeof(fby35_nic_fruid); const size_t fby35_bb_fruid_len = sizeof(fby35_bb_fruid); @@ -XXX,XX +XXX,XX @@ const size_t fby35_bmc_fruid_len = sizeof(fby35_bmc_fruid); const size_t yosemitev2_bmc_fruid_len = sizeof(yosemitev2_bmc_fruid); const size_t rainier_bb_fruid_len = sizeof(rainier_bb_fruid); const size_t rainier_bmc_fruid_len = sizeof(rainier_bmc_fruid); +const size_t gb200nvl_bmc_fruid_len = sizeof(gb200nvl_bmc_fruid); + -- 2.50.0
From: Ed Tanous <etanous@nvidia.com> To support the newly added gb200 machine, add appropriate tests and extend do_test_arm_aspeed_openbmc() to support the hostname of this new system: "gb200nvl-obmc". Signed-off-by: Ed Tanous <etanous@nvidia.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250703144249.3348879-5-etanous@nvidia.com [ clg: Adjust commit log to document do_test_arm_aspeed_openbmc() change ] Signed-off-by: Cédric Le Goater <clg@redhat.com> --- tests/functional/aspeed.py | 9 +++++-- tests/functional/meson.build | 2 ++ .../test_arm_aspeed_gb200nvl_bmc.py | 26 +++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 tests/functional/test_arm_aspeed_gb200nvl_bmc.py diff --git a/tests/functional/aspeed.py b/tests/functional/aspeed.py index XXXXXXX..XXXXXXX 100644 --- a/tests/functional/aspeed.py +++ b/tests/functional/aspeed.py @@ -XXX,XX +XXX,XX @@ class AspeedTest(LinuxKernelTest): def do_test_arm_aspeed_openbmc(self, machine, image, uboot='2019.04', - cpu_id='0x0', soc='AST2500 rev A1'): - hostname = machine.removesuffix('-bmc') + cpu_id='0x0', soc='AST2500 rev A1', + image_hostname=None): + # Allow for the image hostname to not end in "-bmc" + if image_hostname is not None: + hostname = image_hostname + else: + hostname = machine.removesuffix('-bmc') self.set_machine(machine) self.vm.set_console() diff --git a/tests/functional/meson.build b/tests/functional/meson.build index XXXXXXX..XXXXXXX 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -XXX,XX +XXX,XX @@ test_timeouts = { 'arm_aspeed_ast2600' : 1200, 'arm_aspeed_bletchley' : 480, 'arm_aspeed_catalina' : 480, + 'arm_aspeed_gb200nvl_bmc' : 480, 'arm_aspeed_rainier' : 480, 'arm_bpim2u' : 500, 'arm_collie' : 180, @@ -XXX,XX +XXX,XX @@ tests_arm_system_thorough = [ 'arm_aspeed_ast2600', 'arm_aspeed_bletchley', 'arm_aspeed_catalina', + 'arm_aspeed_gb200nvl_bmc', 'arm_aspeed_rainier', 'arm_bpim2u', 'arm_canona1100', diff --git a/tests/functional/test_arm_aspeed_gb200nvl_bmc.py b/tests/functional/test_arm_aspeed_gb200nvl_bmc.py new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/tests/functional/test_arm_aspeed_gb200nvl_bmc.py @@ -XXX,XX +XXX,XX @@ +#!/usr/bin/env python3 +# +# Functional test that boots the ASPEED machines +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from qemu_test import Asset +from aspeed import AspeedTest + + +class GB200Machine(AspeedTest): + + ASSET_GB200_FLASH = Asset( + 'https://github.com/legoater/qemu-aspeed-boot/raw/refs/heads/master/images/gb200nvl-obmc/obmc-phosphor-image-gb200nvl-obmc-20250702182348.static.mtd.xz', + 'b84819317cb3dc762895ad507705978ef000bfc77c50c33a63bdd37921db0dbc') + + def test_arm_aspeed_gb200_openbmc(self): + image_path = self.uncompress(self.ASSET_GB200_FLASH) + + self.do_test_arm_aspeed_openbmc('gb200nvl-bmc', image=image_path, + uboot='2019.04', cpu_id='0xf00', + soc='AST2600 rev A3', + image_hostname='gb200nvl-obmc') + +if __name__ == '__main__': + AspeedTest.main() -- 2.50.0