:p
atchew
Login
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
The following changes since commit 159107e390609f71b78268a4888563dcdce6ac65: Merge tag 'pull-hex-20260102' of https://github.com/quic/qemu into staging (2026-01-05 07:35:40 +1100) are available in the Git repository at: https://github.com/legoater/qemu/ tags/pull-aspeed-20260105 for you to fetch changes up to 9cbd8ee7f67fceee51d3c993a282e5adc397b6b9: hw/i2c/aspeed: Fix wrong I2CC_DMA_LEN when I2CM_DMA_TX/RX_ADDR set first (2026-01-05 10:38:02 +0100) ---------------------------------------------------------------- aspeed queue: * Removed the ast2700-a0 SoC and ast2700a0-evb machine. * Added SGPIO support to the ast2700 SoC, including unit tests. * Added several FRU EEPROMs to the Catalina board. * Added support for the new AST1060 SoC and ast1060-evb machine, including functional tests. * Fixed the silicon revision ID register for AST2600 and AST1030 SoCs. * Added an SFDP table for a Winbond flash chip. * Updated documentation for Aspeed boards. ---------------------------------------------------------------- Cédric Le Goater (1): tests/functional: Fix URL of gb200nvl-bmc image Jamin Lin (18): hw/block/m25p80: Add SFDP table for Winbond W25Q02JVM flash hw/misc/aspeed_scu: Fix the revision ID cannot be set in the SOC layer for AST2600 and AST1030 hhw/misc/aspeed_scu: Add AST1060 A2 silicon revision definition hw/arm/aspeed_ast10x0: Add common init function for AST10x0 SoCs hw/arm/aspeed_ast10x0: Add common realize function for AST10x0 SoCs hw/arm/aspeed_ast10x0: Pass SoC name to common init for AST10x0 family reuse hw/arm/aspeed_ast10x0: Add AST1060 SoC support hw/arm/aspeed_ast10x0_evb: Add AST1060 EVB machine support tests/functional/arm/test_aspeed_ast1060: Add functional tests for Aspeed AST1060 SoC docs/system/arm/aspeed: Update Aspeed and 2700 family boards list docs/system/arm/aspeed: Update Aspeed MiniBMC section to include AST1060 processor hw/arm: Remove ast2700a0-evb machine hw/arm/aspeed_ast27x0: Remove ast2700-a0 SOC hw/intc/aspeed: Remove GIC 128 - 136 docs/specs/aspeed-intc: Remove GIC 128 - 136 hw/intc/aspeed: Remove SSP 128 - 138 hw/intc/aspeed: Remove TSP 128 - 138 hw/i2c/aspeed: Fix wrong I2CC_DMA_LEN when I2CM_DMA_TX/RX_ADDR set first Patrick Williams (11): hw/arm/aspeed: catalina: add BSM FRU EEPROM hw/arm/aspeed: catalina: add DC-SCM FRU EEPROM hw/arm/aspeed: catalina: add PDB FRU EEPROM hw/arm/aspeed: catalina: add OSFP FRU EEPROM hw/arm/aspeed: catalina: add FIO FRU EEPROM hw/arm/aspeed: catalina: add HDD FRU EEPROM hw/arm/aspeed: catalina: add GB200 FRU EEPROM hw/arm/aspeed: catalina: add GB200-IO FRU EEPROM hw/arm/aspeed: catalina: add HMC FRU EEPROM hw/arm/aspeed: catalina: add NIC FRU EEPROM hw/arm/aspeed: catalina: add Cable Cartridge FRU EEPROM Yubin Zou (6): hw/gpio/aspeed_sgpio: Add basic device model for Aspeed SGPIO hw/gpio/aspeed_sgpio: Add QOM property accessors for SGPIO pins hw/gpio/aspeed_sgpio: Implement SGPIO interrupt handling hw/arm/aspeed_soc: Update Aspeed SoC to support two SGPIO controllers hw/arm/aspeed_ast27x0: Wire SGPIO controller to AST2700 SoC test/qtest: Add Unit test for Aspeed SGPIO docs/about/deprecated.rst | 8 - docs/about/removed-features.rst | 8 + docs/specs/aspeed-intc.rst | 92 ++--- docs/system/arm/aspeed.rst | 27 +- hw/block/m25p80_sfdp.h | 1 + include/hw/arm/aspeed_soc.h | 8 +- include/hw/gpio/aspeed_sgpio.h | 68 ++++ include/hw/misc/aspeed_scu.h | 1 + hw/arm/aspeed_ast10x0.c | 213 ++++++---- hw/arm/aspeed_ast10x0_evb.c | 23 ++ hw/arm/aspeed_ast2600_catalina.c | 473 ++++++++++++++++++++++- hw/arm/aspeed_ast27x0-ssp.c | 13 +- hw/arm/aspeed_ast27x0-tsp.c | 13 +- hw/arm/aspeed_ast27x0.c | 151 ++------ hw/arm/aspeed_ast27x0_evb.c | 26 -- hw/block/m25p80.c | 2 + hw/block/m25p80_sfdp.c | 36 ++ hw/gpio/aspeed_sgpio.c | 346 +++++++++++++++++ hw/i2c/aspeed_i2c.c | 10 +- hw/intc/aspeed_intc.c | 161 +------- hw/misc/aspeed_scu.c | 5 +- tests/qtest/ast2700-sgpio-test.c | 165 ++++++++ hw/gpio/meson.build | 1 + tests/functional/arm/meson.build | 1 + tests/functional/arm/test_aspeed_ast1060.py | 52 +++ tests/functional/arm/test_aspeed_gb200nvl_bmc.py | 2 +- tests/qtest/meson.build | 1 + 27 files changed, 1403 insertions(+), 504 deletions(-) create mode 100644 include/hw/gpio/aspeed_sgpio.h create mode 100644 hw/gpio/aspeed_sgpio.c create mode 100644 tests/qtest/ast2700-sgpio-test.c create mode 100644 tests/functional/arm/test_aspeed_ast1060.py
From: Jamin Lin <jamin_lin@aspeedtech.com> Add the SFDP data table for Winbond W25Q02JVM flash device. The table was generated under Linux kernel by dumping the SFDP content using the following command: ``` hexdump -v -e '8/1 "0x%02x, " "\n"' \ /sys/bus/spi/devices/spi0.0/spi-nor/sfdp ``` 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/20251112030553.291734-3-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/block/m25p80_sfdp.h | 1 + hw/block/m25p80.c | 2 ++ hw/block/m25p80_sfdp.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h index XXXXXXX..XXXXXXX 100644 --- a/hw/block/m25p80_sfdp.h +++ b/hw/block/m25p80_sfdp.h @@ -XXX,XX +XXX,XX @@ uint8_t m25p80_sfdp_w25q256(uint32_t addr); uint8_t m25p80_sfdp_w25q512jv(uint32_t addr); uint8_t m25p80_sfdp_w25q80bl(uint32_t addr); uint8_t m25p80_sfdp_w25q01jvq(uint32_t addr); +uint8_t m25p80_sfdp_w25q02jvm(uint32_t addr); uint8_t m25p80_sfdp_is25wp256(uint32_t addr); diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index XXXXXXX..XXXXXXX 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -XXX,XX +XXX,XX @@ static const FlashPartInfo known_devices[] = { .sfdp_read = m25p80_sfdp_w25q512jv }, { INFO("w25q01jvq", 0xef4021, 0, 64 << 10, 2048, ER_4K), .sfdp_read = m25p80_sfdp_w25q01jvq }, + { INFO("w25q02jvm", 0xef7022, 0, 64 << 10, 4096, ER_4K), + .sfdp_read = m25p80_sfdp_w25q02jvm }, /* Microchip */ { INFO("25csm04", 0x29cc00, 0x100, 64 << 10, 8, 0) }, diff --git a/hw/block/m25p80_sfdp.c b/hw/block/m25p80_sfdp.c index XXXXXXX..XXXXXXX 100644 --- a/hw/block/m25p80_sfdp.c +++ b/hw/block/m25p80_sfdp.c @@ -XXX,XX +XXX,XX @@ static const uint8_t sfdp_w25q80bl[] = { }; define_sfdp_read(w25q80bl); +static const uint8_t sfdp_w25q02jvm[] = { + 0x53, 0x46, 0x44, 0x50, 0x06, 0x01, 0x01, 0xff, + 0x00, 0x06, 0x01, 0x10, 0x80, 0x00, 0x00, 0xff, + 0x84, 0x00, 0x01, 0x02, 0xd0, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x01, 0x02, 0xf0, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xe5, 0x20, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0x44, 0xeb, 0x08, 0x6b, 0x08, 0x3b, 0x42, 0xbb, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0xff, 0xff, 0x40, 0xeb, 0x0c, 0x20, 0x0f, 0x52, + 0x10, 0xd8, 0x00, 0x00, 0x36, 0x02, 0xa6, 0x00, + 0x82, 0xea, 0x14, 0xe2, 0xe9, 0x63, 0x76, 0x33, + 0x7a, 0x75, 0x7a, 0x75, 0xf7, 0xa2, 0xd5, 0x5c, + 0x19, 0xf7, 0x4d, 0xff, 0xe9, 0x70, 0xf9, 0xa5, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0a, 0xf0, 0xff, 0x21, 0xff, 0xdc, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +}; +define_sfdp_read(w25q02jvm); + /* * Integrated Silicon Solution (ISSI) */ -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> According to the design of the AST2600, it has a Silicon Revision ID Register, specifically SCU004 and SCU014, to set the Revision ID for the AST2600. For the AST2600 A3, SCU004 is set to 0x05030303 and SCU014 is set to 0x05030303. In the "aspeed_ast2600_scu_reset" function, the hardcoded value "AST2600_A3_SILICON_REV" was used for SCU004, while "s->silicon_rev" was used for SCU014. The value of "s->silicon_rev" is set by the SoC layer via the "silicon-rev" property. This patch aligns both SCU004 and SCU014 to use "s->silicon_rev" for consistency and flexibility. Similarly, the "aspeed_ast1030_scu_reset" function also used a fixed revision constant ("AST1030_A1_SILICON_REV"). This change updates it to use the same "s->silicon_rev" property, ensuring that both SoCs follow a consistent and configurable revision handling mechanism. 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/20251112030553.291734-4-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/misc/aspeed_scu.c | 4 ++-- 1 file changed, 2 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 @@ static void aspeed_ast2600_scu_reset(DeviceState *dev) * of actual revision. QEMU and Linux only support A1 onwards so this is * sufficient. */ - s->regs[AST2600_SILICON_REV] = AST2600_A3_SILICON_REV; + s->regs[AST2600_SILICON_REV] = s->silicon_rev; s->regs[AST2600_SILICON_REV2] = s->silicon_rev; s->regs[AST2600_HW_STRAP1] = s->hw_strap1; s->regs[AST2600_HW_STRAP2] = s->hw_strap2; @@ -XXX,XX +XXX,XX @@ static void aspeed_ast1030_scu_reset(DeviceState *dev) memcpy(s->regs, asc->resets, asc->nr_regs * 4); - s->regs[AST2600_SILICON_REV] = AST1030_A1_SILICON_REV; + s->regs[AST2600_SILICON_REV] = s->silicon_rev; s->regs[AST2600_SILICON_REV2] = s->silicon_rev; s->regs[AST2600_HW_STRAP1] = s->hw_strap1; s->regs[AST2600_HW_STRAP2] = s->hw_strap2; -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> Add a new silicon revision constant AST1060_A2_SILICON_REV for the AST1060 SoC. This allows the SCU model and related SoC layers to identify and handle AST1060 A2 revision properly in the same way as other Aspeed SoC families. 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/20251112030553.291734-5-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- include/hw/misc/aspeed_scu.h | 1 + hw/misc/aspeed_scu.c | 1 + 2 files changed, 2 insertions(+) diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/misc/aspeed_scu.h +++ b/include/hw/misc/aspeed_scu.h @@ -XXX,XX +XXX,XX @@ struct AspeedSCUState { #define AST2600_A3_SILICON_REV 0x05030303U #define AST1030_A0_SILICON_REV 0x80000000U #define AST1030_A1_SILICON_REV 0x80010000U +#define AST1060_A2_SILICON_REV 0xA0030000U #define AST2700_A0_SILICON_REV 0x06000103U #define AST2720_A0_SILICON_REV 0x06000203U #define AST2750_A0_SILICON_REV 0x06000003U 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 @@ static uint32_t aspeed_silicon_revs[] = { AST2600_A3_SILICON_REV, AST1030_A0_SILICON_REV, AST1030_A1_SILICON_REV, + AST1060_A2_SILICON_REV, AST2700_A0_SILICON_REV, AST2720_A0_SILICON_REV, AST2750_A0_SILICON_REV, -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> Introduce a new common initialization function aspeed_soc_ast10x0_init() for AST10x0 series SoCs. This separates the shared initialization logic from the AST1030-specific part, allowing reuse by future SoCs such as AST1060. The AST1060 does not include the LPC and PECI models, so the common initializer is used for all shared modules, while aspeed_soc_ast1030_init() adds initialization of LPC and PECI, which are unique to AST1030. This refactor improves code reuse and prepares the codebase for supporting the AST1060 platform. No functional changes. 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/20251112030553.291734-6-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast10x0.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast10x0.c +++ b/hw/arm/aspeed_ast10x0.c @@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_soc_ast1030_get_irq(AspeedSoCState *s, int dev) return qdev_get_gpio_in(DEVICE(&a->armv7m), sc->irqmap[dev]); } -static void aspeed_soc_ast1030_init(Object *obj) +static void aspeed_soc_ast10x0_init(Object *obj) { Aspeed10x0SoCState *a = ASPEED10X0_SOC(obj); AspeedSoCState *s = ASPEED_SOC(obj); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_init(Object *obj) object_initialize_child(obj, "spi[*]", &s->spi[i], typename); } - object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC); - - object_initialize_child(obj, "peci", &s->peci, TYPE_ASPEED_PECI); - object_initialize_child(obj, "sbc", &s->sbc, TYPE_ASPEED_AST10X0_SBC); for (i = 0; i < sc->wdts_num; i++) { @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_init(Object *obj) TYPE_UNIMPLEMENTED_DEVICE); } +static void aspeed_soc_ast1030_init(Object *obj) +{ + AspeedSoCState *s = ASPEED_SOC(obj); + + aspeed_soc_ast10x0_init(obj); + object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC); + object_initialize_child(obj, "peci", &s->peci, TYPE_ASPEED_PECI); +} + static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) { Aspeed10x0SoCState *a = ASPEED10X0_SOC(dev_soc); -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> Introduce a new common realize function aspeed_soc_ast10x0_realize() for AST10x0 series SoCs. The shared initialization and realization logic is now placed in this common function to improve code reuse and reduce duplication between different SoCs in the same family. The AST1030 realization function aspeed_soc_ast1030_realize() is updated to call the new common routine and then perform realization of its own specific devices such as LPC and PECI, which are not present on future SoCs like AST1060. This refactor simplifies maintenance and prepares the framework for adding AST1060 support. No functional changes. 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/20251112030553.291734-7-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast10x0.c | 128 ++++++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 58 deletions(-) diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast10x0.c +++ b/hw/arm/aspeed_ast10x0.c @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_init(Object *obj) object_initialize_child(obj, "peci", &s->peci, TYPE_ASPEED_PECI); } -static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) +static bool aspeed_soc_ast10x0_realize(Aspeed10x0SoCState *a, Error **errp) { - Aspeed10x0SoCState *a = ASPEED10X0_SOC(dev_soc); - AspeedSoCState *s = ASPEED_SOC(dev_soc); + AspeedSoCState *s = ASPEED_SOC(a); AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); DeviceState *armv7m; Error *err = NULL; @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) if (!clock_has_source(s->sysclk)) { error_setg(errp, "sysclk clock must be wired up by the board code"); - return; + return false; } /* General I/O memory space to catch all unimplemented device */ @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) "aspeed.sbc", sc->memmap[ASPEED_DEV_SBC], 0x40000); - /* AST1030 CPU Core */ + /* AST10x0 CPU Core */ armv7m = DEVICE(&a->armv7m); qdev_prop_set_uint32(armv7m, "num-irq", 256); qdev_prop_set_string(armv7m, "cpu-type", @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) memory_region_init_ram(&s->sram, OBJECT(s), sram_name, sc->sram_size, &err); if (err != NULL) { error_propagate(errp, err); - return; + return false; } memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SRAM], @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) sc->secsram_size, &err); if (err != NULL) { error_propagate(errp, err); - return; + return false; } memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SECSRAM], &s->secsram); /* SCU */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { - return; + return false; } aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(&s->sram), &error_abort); if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) { - return; + return false; } aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->i2c), 0, sc->memmap[ASPEED_DEV_I2C]); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) /* I3C */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->i3c), errp)) { - return; + return false; } aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->i3c), 0, sc->memmap[ASPEED_DEV_I3C]); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->i3c.devices[i]), 0, irq); } - /* PECI */ - if (!sysbus_realize(SYS_BUS_DEVICE(&s->peci), errp)) { - return; - } - aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->peci), 0, - sc->memmap[ASPEED_DEV_PECI]); - sysbus_connect_irq(SYS_BUS_DEVICE(&s->peci), 0, - aspeed_soc_ast1030_get_irq(s, ASPEED_DEV_PECI)); - - /* LPC */ - if (!sysbus_realize(SYS_BUS_DEVICE(&s->lpc), errp)) { - return; - } - aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->lpc), 0, - sc->memmap[ASPEED_DEV_LPC]); - - /* Connect the LPC IRQ to the GIC. It is otherwise unused. */ - sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 0, - aspeed_soc_ast1030_get_irq(s, ASPEED_DEV_LPC)); - - /* - * On the AST1030 LPC subdevice IRQs are connected straight to the GIC. - */ - sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_1, - qdev_get_gpio_in(DEVICE(&a->armv7m), - sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_1)); - - sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_2, - qdev_get_gpio_in(DEVICE(&a->armv7m), - sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_2)); - - sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_3, - qdev_get_gpio_in(DEVICE(&a->armv7m), - sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_3)); - - sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_4, - qdev_get_gpio_in(DEVICE(&a->armv7m), - sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_4)); - /* 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; + return false; } sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, aspeed_soc_ast1030_get_irq(s, uart)); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) object_property_set_link(OBJECT(&s->timerctrl), "scu", OBJECT(&s->scu), &error_abort); if (!sysbus_realize(SYS_BUS_DEVICE(&s->timerctrl), errp)) { - return; + return false; } aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->timerctrl), 0, sc->memmap[ASPEED_DEV_TIMER1]); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) /* ADC */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->adc), errp)) { - return; + return false; } aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->adc), 0, sc->memmap[ASPEED_DEV_ADC]); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) object_property_set_link(OBJECT(&s->fmc), "dram", OBJECT(&s->sram), &error_abort); if (!sysbus_realize(SYS_BUS_DEVICE(&s->fmc), errp)) { - return; + return false; } aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->fmc), 0, sc->memmap[ASPEED_DEV_FMC]); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) object_property_set_link(OBJECT(&s->spi[i]), "dram", OBJECT(&s->sram), &error_abort); if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) { - return; + return false; } aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->spi[i]), 0, sc->memmap[ASPEED_DEV_SPI1 + i]); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) /* Secure Boot Controller */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->sbc), errp)) { - return; + return false; } aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->sbc), 0, sc->memmap[ASPEED_DEV_SBC]); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) object_property_set_link(OBJECT(&s->hace), "dram", OBJECT(&s->sram), &error_abort); if (!sysbus_realize(SYS_BUS_DEVICE(&s->hace), errp)) { - return; + return false; } aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->hace), 0, sc->memmap[ASPEED_DEV_HACE]); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) object_property_set_link(OBJECT(&s->wdt[i]), "scu", OBJECT(&s->scu), &error_abort); if (!sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), errp)) { - return; + return false; } aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->wdt[i]), 0, wdt_offset); } /* GPIO */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) { - return; + return false; } aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_DEV_GPIO]); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->jtag[1]), "aspeed.jtag", sc->memmap[ASPEED_DEV_JTAG1], 0x20); + + return true; +} + +static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) +{ + Aspeed10x0SoCState *a = ASPEED10X0_SOC(dev_soc); + AspeedSoCState *s = ASPEED_SOC(dev_soc); + AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); + + if (!aspeed_soc_ast10x0_realize(a, errp)) { + return; + } + + /* PECI */ + if (!sysbus_realize(SYS_BUS_DEVICE(&s->peci), errp)) { + return; + } + aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->peci), 0, + sc->memmap[ASPEED_DEV_PECI]); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->peci), 0, + aspeed_soc_ast1030_get_irq(s, ASPEED_DEV_PECI)); + + /* LPC */ + if (!sysbus_realize(SYS_BUS_DEVICE(&s->lpc), errp)) { + return; + } + aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->lpc), 0, + sc->memmap[ASPEED_DEV_LPC]); + + /* Connect the LPC IRQ to the GIC. It is otherwise unused. */ + sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 0, + aspeed_soc_ast1030_get_irq(s, ASPEED_DEV_LPC)); + + /* + * On the AST1030 LPC subdevice IRQs are connected straight to the GIC. + */ + sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_1, + qdev_get_gpio_in(DEVICE(&a->armv7m), + sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_1)); + + sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_2, + qdev_get_gpio_in(DEVICE(&a->armv7m), + sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_2)); + + sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_3, + qdev_get_gpio_in(DEVICE(&a->armv7m), + sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_3)); + + sysbus_connect_irq(SYS_BUS_DEVICE(&s->lpc), 1 + aspeed_lpc_kcs_4, + qdev_get_gpio_in(DEVICE(&a->armv7m), + sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_4)); } static void aspeed_soc_ast1030_class_init(ObjectClass *klass, const void *data) -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> Refactor the AST10x0 common initialization to accept a socname parameter. The AST1030 model can be reused by AST1060 since they share most of the same controllers. This approach allows AST1060 to leverage the existing AST1030 initialization flow while keeping separate SoC-specific init functions for components that differ. This prepares the framework for AST1060 support, allowing it to reuse AST1030 device models and initialization flow without code duplication. No functional changes. 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/20251112030553.291734-8-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast10x0.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast10x0.c +++ b/hw/arm/aspeed_ast10x0.c @@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_soc_ast1030_get_irq(AspeedSoCState *s, int dev) return qdev_get_gpio_in(DEVICE(&a->armv7m), sc->irqmap[dev]); } -static void aspeed_soc_ast10x0_init(Object *obj) +static void aspeed_soc_ast10x0_init(Object *obj, const char *socname) { Aspeed10x0SoCState *a = ASPEED10X0_SOC(obj); AspeedSoCState *s = ASPEED_SOC(obj); AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); - char socname[8]; char typename[64]; int i; - if (sscanf(object_get_typename(obj), "%7s", socname) != 1) { - g_assert_not_reached(); - } - object_initialize_child(obj, "armv7m", &a->armv7m, TYPE_ARMV7M); s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_init(Object *obj) { AspeedSoCState *s = ASPEED_SOC(obj); - aspeed_soc_ast10x0_init(obj); + aspeed_soc_ast10x0_init(obj, "ast1030"); object_initialize_child(obj, "lpc", &s->lpc, TYPE_ASPEED_LPC); object_initialize_child(obj, "peci", &s->peci, TYPE_ASPEED_PECI); } -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> Add initial support for the Aspeed AST1060 SoC. The AST1060 reuses most of the AST1030 peripheral device models, as the two SoCs share nearly the same controllers including WDT, SCU, TIMER, HACE, ADC, I2C, FMC, and SPI. A new common initialization and realization framework (ast10x0_init and ast10x0_realize) is leveraged so AST1060 can instantiate the existing AST1030 models without redefining duplicate device types. 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/20251112030553.291734-9-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast10x0.c | 59 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast10x0.c +++ b/hw/arm/aspeed_ast10x0.c @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_init(Object *obj) object_initialize_child(obj, "peci", &s->peci, TYPE_ASPEED_PECI); } +static void aspeed_soc_ast1060_init(Object *obj) +{ + /* + * The AST1060 SoC reuses the AST1030 device models. Since all peripheral + * models (e.g. WDT, SCU, TIMER, HACE, ADC, I2C, FMC, SPI) defined for + * AST1030 are compatible with AST1060, we simply reuse the existing + * AST1030 models for AST1060. + * + * To simplify the implementation, AST1060 sets its socname to that of + * AST1030, avoiding the need to create a full set of new + * TYPE_ASPEED_1060_XXX device definitions. This allows the same + * TYPE_ASPEED_1030_WDT and other models to be instantiated for both + * SoCs. + */ + aspeed_soc_ast10x0_init(obj, "ast1030"); +} + static bool aspeed_soc_ast10x0_realize(Aspeed10x0SoCState *a, Error **errp) { AspeedSoCState *s = ASPEED_SOC(a); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) sc->irqmap[ASPEED_DEV_KCS] + aspeed_lpc_kcs_4)); } +static void aspeed_soc_ast1060_realize(DeviceState *dev_soc, Error **errp) +{ + Aspeed10x0SoCState *a = ASPEED10X0_SOC(dev_soc); + + if (!aspeed_soc_ast10x0_realize(a, errp)) { + return; + } +} + static void aspeed_soc_ast1030_class_init(ObjectClass *klass, const void *data) { static const char * const valid_cpu_types[] = { @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast1030_class_init(ObjectClass *klass, const void *data) sc->num_cpus = 1; } +static void aspeed_soc_ast1060_class_init(ObjectClass *klass, const void *data) +{ + static const char * const valid_cpu_types[] = { + ARM_CPU_TYPE_NAME("cortex-m4"), /* TODO cortex-m4f */ + NULL + }; + DeviceClass *dc = DEVICE_CLASS(klass); + AspeedSoCClass *sc = ASPEED_SOC_CLASS(dc); + + /* Reason: The Aspeed SoC can only be instantiated from a board */ + dc->user_creatable = false; + dc->realize = aspeed_soc_ast1060_realize; + + sc->valid_cpu_types = valid_cpu_types; + sc->silicon_rev = AST1060_A2_SILICON_REV; + sc->sram_size = 0xc0000; + sc->secsram_size = 0x40000; /* 256 * KiB */ + sc->spis_num = 2; + sc->wdts_num = 4; + sc->uarts_num = 1; + sc->uarts_base = ASPEED_DEV_UART5; + sc->irqmap = aspeed_soc_ast1030_irqmap; + sc->memmap = aspeed_soc_ast1030_memmap; + sc->num_cpus = 1; +} + static const TypeInfo aspeed_soc_ast10x0_types[] = { { .name = TYPE_ASPEED10X0_SOC, @@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_soc_ast10x0_types[] = { .parent = TYPE_ASPEED10X0_SOC, .instance_init = aspeed_soc_ast1030_init, .class_init = aspeed_soc_ast1030_class_init, - }, + }, { + .name = "ast1060-a2", + .parent = TYPE_ASPEED10X0_SOC, + .instance_init = aspeed_soc_ast1060_init, + .class_init = aspeed_soc_ast1060_class_init, + } }; DEFINE_TYPES(aspeed_soc_ast10x0_types) -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> Add a new machine definition ast1060-evb to support the Aspeed AST1060 evaluation board. The new EVB reuses the same MiniBMC framework used by AST1030, as both SoCs share the same core peripherals and controller designs. The AST1060 EVB machine initializes the ast1060-a2 SoC and sets the FMC and SPI flash models (w25q80bl and w25q02jvm) for simulation. This enables QEMU to boot and emulate firmware images for AST1060-based platforms. 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/20251112030553.291734-10-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast10x0_evb.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/hw/arm/aspeed_ast10x0_evb.c b/hw/arm/aspeed_ast10x0_evb.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast10x0_evb.c +++ b/hw/arm/aspeed_ast10x0_evb.c @@ -XXX,XX +XXX,XX @@ static void aspeed_minibmc_machine_ast1030_evb_class_init(ObjectClass *oc, aspeed_machine_class_init_cpus_defaults(mc); } +static void aspeed_minibmc_machine_ast1060_evb_class_init(ObjectClass *oc, + const void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); + + mc->desc = "Aspeed AST1060 Platform Root of Trust (Cortex-M4)"; + amc->soc_name = "ast1060-a2"; + amc->hw_strap1 = 0; + amc->hw_strap2 = 0; + mc->init = aspeed_minibmc_machine_init; + amc->fmc_model = "w25q80bl"; + amc->spi_model = "w25q02jvm"; + amc->num_cs = 2; + amc->macs_mask = 0; + aspeed_machine_class_init_cpus_defaults(mc); +} + static const TypeInfo aspeed_ast10x0_evb_types[] = { { .name = MACHINE_TYPE_NAME("ast1030-evb"), .parent = TYPE_ASPEED_MACHINE, .class_init = aspeed_minibmc_machine_ast1030_evb_class_init, .interfaces = arm_machine_interfaces, + }, { + .name = MACHINE_TYPE_NAME("ast1060-evb"), + .parent = TYPE_ASPEED_MACHINE, + .class_init = aspeed_minibmc_machine_ast1060_evb_class_init, + .interfaces = arm_machine_interfaces, } }; -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> Add functional tests for the Aspeed AST1060 SoC and its evaluation board. The new test test_aspeed_ast1060.py validates booting the AST1060 EVB machine using the Zephyr OS and ASPEED PROT application (ast1060_prot_v03.02.tgz) and ensures basic console functionality. 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/20251112030553.291734-11-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- tests/functional/arm/meson.build | 1 + tests/functional/arm/test_aspeed_ast1060.py | 52 +++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 tests/functional/arm/test_aspeed_ast1060.py diff --git a/tests/functional/arm/meson.build b/tests/functional/arm/meson.build index XXXXXXX..XXXXXXX 100644 --- a/tests/functional/arm/meson.build +++ b/tests/functional/arm/meson.build @@ -XXX,XX +XXX,XX @@ tests_arm_system_quick = [ tests_arm_system_thorough = [ 'aspeed_ast1030', + 'aspeed_ast1060', 'aspeed_palmetto', 'aspeed_romulus', 'aspeed_witherspoon', diff --git a/tests/functional/arm/test_aspeed_ast1060.py b/tests/functional/arm/test_aspeed_ast1060.py new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/tests/functional/arm/test_aspeed_ast1060.py @@ -XXX,XX +XXX,XX @@ +#!/usr/bin/env python3 +# +# Functional test that boots the ASPEED SoCs with firmware +# +# Copyright (C) 2025 ASPEED Technology Inc +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from aspeed import AspeedTest +from qemu_test import Asset, exec_command_and_wait_for_pattern + + +class AST1060Machine(AspeedTest): + ASSET_ASPEED_AST1060_PROT_3_02 = Asset( + ('https://github.com/AspeedTech-BMC' + '/aspeed-zephyr-project/releases/download/v03.02' + '/ast1060_prot_v03.02.tgz'), + 'dd5f1adc935316ddd1906506a02e15567bd7290657b52320f1a225564cc175bd') + + def test_arm_ast1060_prot_3_02(self): + self.set_machine('ast1060-evb') + + kernel_name = "ast1060_prot/zephyr.bin" + kernel_file = self.archive_extract( + self.ASSET_ASPEED_AST1060_PROT_3_02, member=kernel_name) + + self.vm.set_console() + self.vm.add_args('-kernel', kernel_file, '-nographic') + self.vm.launch() + self.wait_for_console_pattern("Booting Zephyr OS") + exec_command_and_wait_for_pattern(self, "help", + "Available commands") + + def test_arm_ast1060_otp_blockdev_device(self): + self.vm.set_machine("ast1060-evb") + + kernel_name = "ast1060_prot/zephyr.bin" + kernel_file = self.archive_extract(self.ASSET_ASPEED_AST1060_PROT_3_02, + member=kernel_name) + otp_img = self.generate_otpmem_image() + + self.vm.set_console() + self.vm.add_args( + "-kernel", kernel_file, + "-blockdev", f"driver=file,filename={otp_img},node-name=otp", + "-global", "aspeed-otp.drive=otp", + ) + self.vm.launch() + self.wait_for_console_pattern("Booting Zephyr OS") + +if __name__ == '__main__': + AspeedTest.main() -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> Remove the ast2700-evb entry from the Aspeed family boards list in the documentation. The AST2700 platform now belongs to the new Aspeed 2700 family group, which has its own dedicated documentation section and board definitions. Update the Aspeed 2700 family boards list in the documentation to include the new ast2700fc board entry. 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/20251112030553.291734-12-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- docs/system/arm/aspeed.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 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``, ``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``) -==================================================================================================================================================================================================================================================================================================================================================================================================================================== +Aspeed family boards (``ast2500-evb``, ``ast2600-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 @@ configuration file for OTP memory: done > otpmem.img fi -Aspeed 2700 family boards (``ast2700-evb``) -================================================================== +Aspeed 2700 family boards (``ast2700-evb``, ``ast2700fc``) +========================================================== The QEMU Aspeed machines model BMCs of Aspeed evaluation boards. They are based on different releases of the Aspeed SoC : -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> Added details describing AST1060 as a Platform Root of Trust processor board alongside AST1030 MiniBMC, and extended the list of missing devices to include SMBus Filter and QSPI Monitor controllers. 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/20251112030553.291734-13-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- docs/system/arm/aspeed.rst | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 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 @@ Use ``tio`` or another terminal emulator to connect to the consoles: $ tio /dev/pts/57 -Aspeed minibmc family boards (``ast1030-evb``) -================================================================== +Aspeed MiniBMC and Platform Root of Trust processor family boards (``ast1030-evb``, ``ast1060-evb``) +==================================================================================================== -The QEMU Aspeed machines model mini BMCs of various Aspeed evaluation -boards. They are based on different releases of the -Aspeed SoC : the AST1030 integrating an ARM Cortex M4F CPU (200MHz). +The QEMU Aspeed machines model mini BMCs and Platform Root of Trust processors of various Aspeed +evaluation boards. They are based on different releases of the Aspeed SoC : the AST1030 (MiniBMC) +and AST1060 (Platform Root of Trust Processor), both integrating an ARM Cortex M4F CPU (200MHz). The SoC comes with SRAM, SPI, I2C, etc. -AST1030 SoC based machines : +AST10x0 SoC based machines : - ``ast1030-evb`` Aspeed AST1030 Evaluation board (Cortex-M4F) +- ``ast1060-evb`` Aspeed AST1060 Evaluation board (Cortex-M4F) Supported devices ----------------- - * SMP (for the AST1030 Cortex-M4F) + * SMP (for the Cortex-M4F) * Interrupt Controller (VIC) * Timer Controller * I2C Controller @@ -XXX,XX +XXX,XX @@ Missing devices * Virtual UART * eSPI Controller * I3C Controller + * SMBus Filter Controller + * QSPI Monitor Controller Boot options ------------ @@ -XXX,XX +XXX,XX @@ To boot a kernel directly from a Zephyr build tree: .. code-block:: bash $ qemu-system-arm -M ast1030-evb -nographic \ - -kernel zephyr.elf + -kernel zephyr.bin -- 2.52.0
From: Patrick Williams <patrick@stwcx.xyz> Use ipmitool/frugen tool to generate a BSM image based on a sanitized set of data from a real device EEPROM. Signed-off-by: Patrick Williams <patrick@stwcx.xyz> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251217-catalina-eeproms-v1-1-dc7b276efd57@stwcx.xyz Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast2600_catalina.c | 40 +++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/hw/arm/aspeed_ast2600_catalina.c b/hw/arm/aspeed_ast2600_catalina.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast2600_catalina.c +++ b/hw/arm/aspeed_ast2600_catalina.c @@ -XXX,XX +XXX,XX @@ #define TYPE_TMP421 "tmp421" #define TYPE_DS1338 "ds1338" +/* + * "BMC Storage Module" FRU data. Generated with frugen. + * + * { + * "board": { + * "mfg": "Quanta", + * "pname": "BMC Storage Module (QEMU)", + * "pn": "00000000000", + * "serial": "00000000000000", + * "date": "01/12/2025 00:00", + * "custom": ["09-100183"] + * }, + * "product": { + * "mfg": "Quanta", + * "pname": "CI-Catalina", + * "pn": "10000000001", + * "ver": "MP", + * "serial": "10000000000000", + * "atag": "QEMU" + * } + * } + */ +static const uint8_t bsm_eeprom[] = { + 0x01, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x00, 0xf4, 0x01, 0x09, 0x19, 0x8c, + 0x19, 0xf0, 0xc6, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x61, 0xd9, 0x42, 0x4d, + 0x43, 0x20, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x20, 0x4d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x20, 0x28, 0x51, 0x45, 0x4d, 0x55, 0x29, 0x8b, + 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x89, + 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x01, 0xc0, 0x87, 0x50, + 0xd6, 0x44, 0x10, 0x14, 0x61, 0x13, 0xc1, 0x59, 0x01, 0x07, 0x19, 0xc6, + 0x51, 0x75, 0x61, 0x6e, 0x74, 0x61, 0xcb, 0x43, 0x49, 0x2d, 0x43, 0x61, + 0x74, 0x61, 0x6c, 0x69, 0x6e, 0x61, 0x89, 0x11, 0x04, 0x41, 0x10, 0x04, + 0x41, 0x10, 0x14, 0x01, 0x82, 0x2d, 0x0c, 0x8b, 0x11, 0x04, 0x41, 0x10, + 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x83, 0x71, 0xd9, 0xd6, 0xc0, + 0xc1, 0x00, 0x00, 0x37 +}; +static const size_t bsm_eeprom_len = sizeof(bsm_eeprom); + static void catalina_bmc_i2c_init(AspeedMachineState *bmc) { /* Reference from v6.16-rc2 aspeed-bmc-facebook-catalina.dts */ @@ -XXX,XX +XXX,XX @@ static void catalina_bmc_i2c_init(AspeedMachineState *bmc) /* eeprom@50 */ at24c_eeprom_init(i2c[9], 0x50, 8 * KiB); /* eeprom@56 */ - at24c_eeprom_init(i2c[9], 0x56, 8 * KiB); + at24c_eeprom_init_rom(i2c[9], 0x56, 8 * KiB, bsm_eeprom, bsm_eeprom_len); /* &i2c10 */ /* temperature-sensor@1f - tpm421 */ -- 2.52.0
From: Patrick Williams <patrick@stwcx.xyz> Use ipmitool/frugen tool to generate a DC-SCM image based on a sanitized set of data from a real device EEPROM. Signed-off-by: Patrick Williams <patrick@stwcx.xyz> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251217-catalina-eeproms-v1-2-dc7b276efd57@stwcx.xyz Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast2600_catalina.c | 41 +++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/hw/arm/aspeed_ast2600_catalina.c b/hw/arm/aspeed_ast2600_catalina.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast2600_catalina.c +++ b/hw/arm/aspeed_ast2600_catalina.c @@ -XXX,XX +XXX,XX @@ static const uint8_t bsm_eeprom[] = { }; static const size_t bsm_eeprom_len = sizeof(bsm_eeprom); +/* + * "Secure Control Module" FRU data. Generated with frugen. + * + * { + * "board": { + * "mfg": "Quanta", + * "pname": "Catalina SCM MP (QEMU)", + * "pn": "00000000000", + * "serial": "00000000000000", + * "date": "01/12/2025 00:00", + * "custom": ["19-100325"] + * }, + * "product": { + * "mfg": "Quanta", + * "pname": "CI-Catalina", + * "pn": "10000000001", + * "ver": "MP", + * "serial": "10000000000000", + * "atag": "QEMU" + * } + * } + * + */ +static const uint8_t scm_eeprom[] = { + 0x01, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x00, 0xf4, 0x01, 0x09, 0x19, 0x8c, + 0x19, 0xf0, 0xc6, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x61, 0xd6, 0x43, 0x61, + 0x74, 0x61, 0x6c, 0x69, 0x6e, 0x61, 0x20, 0x53, 0x43, 0x4d, 0x20, 0x4d, + 0x50, 0x20, 0x28, 0x51, 0x45, 0x4d, 0x55, 0x29, 0x8b, 0x10, 0x04, 0x41, + 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x89, 0x10, 0x04, 0x41, + 0x10, 0x04, 0x41, 0x10, 0x04, 0x01, 0xc0, 0x87, 0x51, 0xd6, 0x44, 0x10, + 0x34, 0x49, 0x15, 0xc1, 0x00, 0x00, 0x00, 0xc1, 0x01, 0x07, 0x19, 0xc6, + 0x51, 0x75, 0x61, 0x6e, 0x74, 0x61, 0xcb, 0x43, 0x49, 0x2d, 0x43, 0x61, + 0x74, 0x61, 0x6c, 0x69, 0x6e, 0x61, 0x89, 0x11, 0x04, 0x41, 0x10, 0x04, + 0x41, 0x10, 0x14, 0x01, 0x82, 0x2d, 0x0c, 0x8b, 0x11, 0x04, 0x41, 0x10, + 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x83, 0x71, 0xd9, 0xd6, 0xc0, + 0xc1, 0x00, 0x00, 0x37 +}; +static const size_t scm_eeprom_len = sizeof(scm_eeprom); + static void catalina_bmc_i2c_init(AspeedMachineState *bmc) { /* Reference from v6.16-rc2 aspeed-bmc-facebook-catalina.dts */ @@ -XXX,XX +XXX,XX @@ static void catalina_bmc_i2c_init(AspeedMachineState *bmc) /* temperature-sensor@4b - tpm75 */ i2c_slave_create_simple(i2c[9], TYPE_TMP75, 0x4b); /* eeprom@50 */ - at24c_eeprom_init(i2c[9], 0x50, 8 * KiB); + at24c_eeprom_init_rom(i2c[9], 0x50, 8 * KiB, scm_eeprom, scm_eeprom_len); /* eeprom@56 */ at24c_eeprom_init_rom(i2c[9], 0x56, 8 * KiB, bsm_eeprom, bsm_eeprom_len); -- 2.52.0
From: Patrick Williams <patrick@stwcx.xyz> Use ipmitool/frugen tool to generate a PDB image based on a sanitized set of data from a real device EEPROM. Signed-off-by: Patrick Williams <patrick@stwcx.xyz> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251217-catalina-eeproms-v1-3-dc7b276efd57@stwcx.xyz Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast2600_catalina.c | 51 +++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/hw/arm/aspeed_ast2600_catalina.c b/hw/arm/aspeed_ast2600_catalina.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast2600_catalina.c +++ b/hw/arm/aspeed_ast2600_catalina.c @@ -XXX,XX +XXX,XX @@ static const uint8_t scm_eeprom[] = { }; static const size_t scm_eeprom_len = sizeof(scm_eeprom); +/* + * "Power Distribution Board" FRU data. Generated with frugen. + * + * { + * "board": { + * "mfg": "Quanta", + * "pname": "Catalina PDB MP (QEMU)", + * "pn": "00000000000", + * "serial": "00000000000000", + * "date": "01/12/2025 00:00", + * "custom": [ + * "19-100579", + * "", + * "", + * "hsc-ltc fsc-max vr-delta gndsen-ina p12vsen-ina p12vfan-mps" + * ] + * }, + * "product": { + * "mfg": "Quanta", + * "pname": "CI-Catalina", + * "pn": "10000000001", + * "ver": "MP", + * "serial": "10000000000000", + * "atag": "QEMU" + * } + * } + */ +static const uint8_t pdb_eeprom[] = { + 0x01, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0xec, 0x01, 0x11, 0x19, 0x8c, + 0x19, 0xf0, 0xc6, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x61, 0xd6, 0x43, 0x61, + 0x74, 0x61, 0x6c, 0x69, 0x6e, 0x61, 0x20, 0x50, 0x44, 0x42, 0x20, 0x4d, + 0x50, 0x20, 0x28, 0x51, 0x45, 0x4d, 0x55, 0x29, 0x8b, 0x10, 0x04, 0x41, + 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x89, 0x10, 0x04, 0x41, + 0x10, 0x04, 0x41, 0x10, 0x04, 0x01, 0xc0, 0x87, 0x51, 0xd6, 0x44, 0x10, + 0x54, 0x5d, 0x19, 0xc0, 0xc0, 0xfb, 0x68, 0x73, 0x63, 0x2d, 0x6c, 0x74, + 0x63, 0x20, 0x66, 0x73, 0x63, 0x2d, 0x6d, 0x61, 0x78, 0x20, 0x76, 0x72, + 0x2d, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x20, 0x67, 0x6e, 0x64, 0x73, 0x65, + 0x6e, 0x2d, 0x69, 0x6e, 0x61, 0x20, 0x70, 0x31, 0x32, 0x76, 0x73, 0x65, + 0x6e, 0x2d, 0x69, 0x6e, 0x61, 0x20, 0x70, 0x31, 0x32, 0x76, 0x66, 0x61, + 0x6e, 0x2d, 0x6d, 0x70, 0x73, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, + 0x01, 0x07, 0x19, 0xc6, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x61, 0xcb, 0x43, + 0x49, 0x2d, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x69, 0x6e, 0x61, 0x89, 0x11, + 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x14, 0x01, 0x82, 0x2d, 0x0c, 0x8b, + 0x11, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x83, + 0x71, 0xd9, 0xd6, 0xc0, 0xc1, 0x00, 0x00, 0x37 +}; +static const size_t pdb_eeprom_len = sizeof(pdb_eeprom); + static void catalina_bmc_i2c_init(AspeedMachineState *bmc) { /* Reference from v6.16-rc2 aspeed-bmc-facebook-catalina.dts */ @@ -XXX,XX +XXX,XX @@ static void catalina_bmc_i2c_init(AspeedMachineState *bmc) /* i2c1mux0ch5 */ /* eeprom@54 */ - at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 5), 0x54, 8 * KiB); + at24c_eeprom_init_rom(pca954x_i2c_get_bus(i2c_mux, 5), 0x54, 8 * KiB, + pdb_eeprom, pdb_eeprom_len); /* tpm75@4f */ i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 5), TYPE_TMP75, 0x4f); -- 2.52.0
From: Patrick Williams <patrick@stwcx.xyz> Use ipmitool/frugen tool to generate an OSFP image based on a sanitized set of data from a real device EEPROM. Signed-off-by: Patrick Williams <patrick@stwcx.xyz> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251217-catalina-eeproms-v1-4-dc7b276efd57@stwcx.xyz Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast2600_catalina.c | 41 +++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/hw/arm/aspeed_ast2600_catalina.c b/hw/arm/aspeed_ast2600_catalina.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast2600_catalina.c +++ b/hw/arm/aspeed_ast2600_catalina.c @@ -XXX,XX +XXX,XX @@ static const uint8_t pdb_eeprom[] = { }; static const size_t pdb_eeprom_len = sizeof(pdb_eeprom); +/* + * OSFP Carrier Board FRU data. Generated with frugen. + * + * { + * "board": { + * "mfg": "Quanta", + * "pname": "Catalina OSFP MP (QEMU)", + * "pn": "00000000000", + * "serial": "00000000000000", + * "date": "01/12/2025 00:00", + * "custom": ["19-100316"] + * }, + * "product": { + * "mfg": "Quanta", + * "pname": "CI-Catalina", + * "pn": "10000000001", + * "ver": "MP", + * "serial": "10000000000000", + * "atag": "QEMU" + * } + * } + */ +static const uint8_t osfp_eeprom[] = { + 0x01, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x00, 0xf4, 0x01, 0x09, 0x19, 0x8c, + 0x19, 0xf0, 0xc6, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x61, 0xd7, 0x43, 0x61, + 0x74, 0x61, 0x6c, 0x69, 0x6e, 0x61, 0x20, 0x4f, 0x53, 0x46, 0x50, 0x20, + 0x4d, 0x50, 0x20, 0x28, 0x51, 0x45, 0x4d, 0x55, 0x29, 0x8b, 0x10, 0x04, + 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x89, 0x10, 0x04, + 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x01, 0xc0, 0x87, 0x51, 0xd6, 0x44, + 0x10, 0x34, 0x45, 0x16, 0xc1, 0x00, 0x00, 0x6e, 0x01, 0x07, 0x19, 0xc6, + 0x51, 0x75, 0x61, 0x6e, 0x74, 0x61, 0xcb, 0x43, 0x49, 0x2d, 0x43, 0x61, + 0x74, 0x61, 0x6c, 0x69, 0x6e, 0x61, 0x89, 0x11, 0x04, 0x41, 0x10, 0x04, + 0x41, 0x10, 0x14, 0x01, 0x82, 0x2d, 0x0c, 0x8b, 0x11, 0x04, 0x41, 0x10, + 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x83, 0x71, 0xd9, 0xd6, 0xc0, + 0xc1, 0x00, 0x00, 0x37 +}; +static const size_t osfp_eeprom_len = sizeof(osfp_eeprom); + static void catalina_bmc_i2c_init(AspeedMachineState *bmc) { /* Reference from v6.16-rc2 aspeed-bmc-facebook-catalina.dts */ @@ -XXX,XX +XXX,XX @@ static void catalina_bmc_i2c_init(AspeedMachineState *bmc) 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); + at24c_eeprom_init_rom(pca954x_i2c_get_bus(i2c_mux, 6), 0x51, 8 * KiB, + osfp_eeprom, osfp_eeprom_len); /* i2c1mux0ch7 */ /* eeprom@53 */ -- 2.52.0
From: Patrick Williams <patrick@stwcx.xyz> Use ipmitool/frugen tool to generate an FIO image based on a sanitized set of data from a real device EEPROM. Signed-off-by: Patrick Williams <patrick@stwcx.xyz> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251217-catalina-eeproms-v1-5-dc7b276efd57@stwcx.xyz Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast2600_catalina.c | 41 +++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/hw/arm/aspeed_ast2600_catalina.c b/hw/arm/aspeed_ast2600_catalina.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast2600_catalina.c +++ b/hw/arm/aspeed_ast2600_catalina.c @@ -XXX,XX +XXX,XX @@ static const uint8_t osfp_eeprom[] = { }; static const size_t osfp_eeprom_len = sizeof(osfp_eeprom); +/* + * "Front IO" FRU data. Generated with frugen. + * + * { + * "board": { + * "mfg": "Quanta", + * "pname": "Catalina FIO MP (QEMU)", + * "pn": "00000000000", + * "serial": "00000000000000", + * "date": "01/12/2025 00:00", + * "custom": ["19-100290"] + * }, + * "product": { + * "mfg": "Quanta", + * "pname": "CI-Catalina", + * "pn": "10000000001", + * "ver": "MP", + * "serial": "10000000000000", + * "atag": "QEMU" + * } + * } + */ +static const uint8_t fio_eeprom[] = { + 0x01, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x00, 0xf4, 0x01, 0x09, 0x19, 0x8c, + 0x19, 0xf0, 0xc6, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x61, 0xd6, 0x43, 0x61, + 0x74, 0x61, 0x6c, 0x69, 0x6e, 0x61, 0x20, 0x46, 0x49, 0x4f, 0x20, 0x4d, + 0x50, 0x20, 0x28, 0x51, 0x45, 0x4d, 0x55, 0x29, 0x8b, 0x10, 0x04, 0x41, + 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x89, 0x10, 0x04, 0x41, + 0x10, 0x04, 0x41, 0x10, 0x04, 0x01, 0xc0, 0x87, 0x51, 0xd6, 0x44, 0x10, + 0x24, 0x65, 0x10, 0xc1, 0x00, 0x00, 0x00, 0xbf, 0x01, 0x07, 0x19, 0xc6, + 0x51, 0x75, 0x61, 0x6e, 0x74, 0x61, 0xcb, 0x43, 0x49, 0x2d, 0x43, 0x61, + 0x74, 0x61, 0x6c, 0x69, 0x6e, 0x61, 0x89, 0x11, 0x04, 0x41, 0x10, 0x04, + 0x41, 0x10, 0x14, 0x01, 0x82, 0x2d, 0x0c, 0x8b, 0x11, 0x04, 0x41, 0x10, + 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x83, 0x71, 0xd9, 0xd6, 0xc0, + 0xc1, 0x00, 0x00, 0x37 +}; +static const size_t fio_eeprom_len = sizeof(fio_eeprom); + static void catalina_bmc_i2c_init(AspeedMachineState *bmc) { /* Reference from v6.16-rc2 aspeed-bmc-facebook-catalina.dts */ @@ -XXX,XX +XXX,XX @@ static void catalina_bmc_i2c_init(AspeedMachineState *bmc) /* i2c1mux0ch7 */ /* eeprom@53 */ - at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, 7), 0x53, 8 * KiB); + at24c_eeprom_init_rom(pca954x_i2c_get_bus(i2c_mux, 7), 0x53, 8 * KiB, + fio_eeprom, fio_eeprom_len); /* temperature-sensor@4b - tmp75 */ i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 7), TYPE_TMP75, 0x4b); -- 2.52.0
From: Patrick Williams <patrick@stwcx.xyz> Use ipmitool/frugen tool to generate a HDD image based on a sanitized set of data from a real device EEPROM. Signed-off-by: Patrick Williams <patrick@stwcx.xyz> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251217-catalina-eeproms-v1-6-dc7b276efd57@stwcx.xyz Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast2600_catalina.c | 41 +++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/hw/arm/aspeed_ast2600_catalina.c b/hw/arm/aspeed_ast2600_catalina.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast2600_catalina.c +++ b/hw/arm/aspeed_ast2600_catalina.c @@ -XXX,XX +XXX,XX @@ static const uint8_t fio_eeprom[] = { }; static const size_t fio_eeprom_len = sizeof(fio_eeprom); +/* + * HDD Carrier Board FRU data. Generated with frugen. + * + * { + * "board": { + * "mfg": "Quanta", + * "pname": "Catalina HDD MP (QEMU)", + * "pn": "00000000000", + * "serial": "00000000000000", + * "date": "01/12/2025 00:00", + * "custom": ["19-100319", "", "", "adc-ina"] + * }, + * "product": { + * "mfg": "Quanta", + * "pname": "CI-Catalina", + * "pn": "10000000001", + * "ver": "MP", + * "serial": "10000000000000", + * "atag": "QEMU" + * } + * } + */ +static const uint8_t hdd_eeprom[] = { + 0x01, 0x00, 0x00, 0x01, 0x0b, 0x00, 0x00, 0xf3, 0x01, 0x0a, 0x19, 0x8c, + 0x19, 0xf0, 0xc6, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x61, 0xd6, 0x43, 0x61, + 0x74, 0x61, 0x6c, 0x69, 0x6e, 0x61, 0x20, 0x48, 0x44, 0x44, 0x20, 0x4d, + 0x50, 0x20, 0x28, 0x51, 0x45, 0x4d, 0x55, 0x29, 0x8b, 0x10, 0x04, 0x41, + 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x89, 0x10, 0x04, 0x41, + 0x10, 0x04, 0x41, 0x10, 0x04, 0x01, 0xc0, 0x87, 0x51, 0xd6, 0x44, 0x10, + 0x34, 0x45, 0x19, 0xc0, 0xc0, 0xc7, 0x61, 0x64, 0x63, 0x2d, 0x69, 0x6e, + 0x61, 0xc1, 0x00, 0xff, 0x01, 0x07, 0x19, 0xc6, 0x51, 0x75, 0x61, 0x6e, + 0x74, 0x61, 0xcb, 0x43, 0x49, 0x2d, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x69, + 0x6e, 0x61, 0x89, 0x11, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x14, 0x01, + 0x82, 0x2d, 0x0c, 0x8b, 0x11, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, + 0x41, 0x10, 0x04, 0x83, 0x71, 0xd9, 0xd6, 0xc0, 0xc1, 0x00, 0x00, 0x37 +}; +static const size_t hdd_eeprom_len = sizeof(hdd_eeprom); + static void catalina_bmc_i2c_init(AspeedMachineState *bmc) { /* Reference from v6.16-rc2 aspeed-bmc-facebook-catalina.dts */ @@ -XXX,XX +XXX,XX @@ static void catalina_bmc_i2c_init(AspeedMachineState *bmc) 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); + at24c_eeprom_init_rom(pca954x_i2c_get_bus(i2c_mux, 6), 0x52, 8 * KiB, + hdd_eeprom, hdd_eeprom_len); /* i2c5mux0ch7 */ /* ina230@40 - no model */ /* ina230@41 - no model */ -- 2.52.0
From: Patrick Williams <patrick@stwcx.xyz> Use ipmitool/frugen tool to generate a GB200 image based on a sanitized set of data from a real device EEPROM. Signed-off-by: Patrick Williams <patrick@stwcx.xyz> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251217-catalina-eeproms-v1-7-dc7b276efd57@stwcx.xyz Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast2600_catalina.c | 45 ++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/hw/arm/aspeed_ast2600_catalina.c b/hw/arm/aspeed_ast2600_catalina.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast2600_catalina.c +++ b/hw/arm/aspeed_ast2600_catalina.c @@ -XXX,XX +XXX,XX @@ static const uint8_t hdd_eeprom[] = { }; static const size_t hdd_eeprom_len = sizeof(hdd_eeprom); +/* + * GB200 CPU/GPU Board FRU data. Generated with frugen. + * + * { + * "board": { + * "mfg": "NVIDIA", + * "pname": "PG548 (QEMU)", + * "pn": "000-00000-0000-000", + * "serial": "0000000000000", + * "date": "01/12/2025 00:00", + * "custom": ["Version: A", "Rework:"] + * }, + * "product": { + * "mfg": "NVIDIA", + * "pname": "GB200 1CPU:1GPU Board PC", + * "pn": "100-00000-0000-001", + * "ver": "E01", + * "serial": "1000000000001", + * "atag": "QEMU" + * } + * } + */ +static const uint8_t gb200_eeprom[] = { + 0x01, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x00, 0xf4, 0x01, 0x09, 0x19, 0x8c, + 0x19, 0xf0, 0x85, 0xae, 0x9d, 0x92, 0x69, 0x08, 0x89, 0xf0, 0x59, 0x51, + 0x18, 0x80, 0xc4, 0x65, 0x5b, 0x27, 0x8a, 0x10, 0x04, 0x41, 0x10, 0x04, + 0x41, 0x10, 0x04, 0x41, 0x10, 0x8e, 0x10, 0x04, 0x35, 0x10, 0x04, 0x41, + 0x50, 0x03, 0x41, 0x10, 0xd4, 0x40, 0x10, 0x04, 0xc0, 0xca, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x41, 0xc7, 0x52, 0x65, 0x77, + 0x6f, 0x72, 0x6b, 0x3a, 0xc1, 0x00, 0x00, 0x37, 0x01, 0x09, 0x19, 0x85, + 0xae, 0x9d, 0x92, 0x69, 0x08, 0xd8, 0x47, 0x42, 0x32, 0x30, 0x30, 0x20, + 0x31, 0x43, 0x50, 0x55, 0x3a, 0x31, 0x47, 0x50, 0x55, 0x20, 0x42, 0x6f, + 0x61, 0x72, 0x64, 0x20, 0x50, 0x43, 0x8e, 0x11, 0x04, 0x35, 0x10, 0x04, + 0x41, 0x50, 0x03, 0x41, 0x10, 0xd4, 0x40, 0x50, 0x04, 0x83, 0x25, 0x14, + 0x01, 0x8a, 0x11, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x11, + 0x83, 0x71, 0xd9, 0xd6, 0xc0, 0xc1, 0x00, 0x17 +}; +static const size_t gb200_eeprom_len = sizeof(gb200_eeprom); + static void catalina_bmc_i2c_init(AspeedMachineState *bmc) { /* Reference from v6.16-rc2 aspeed-bmc-facebook-catalina.dts */ @@ -XXX,XX +XXX,XX @@ static void catalina_bmc_i2c_init(AspeedMachineState *bmc) /* &i2c12 */ /* eeprom@50 */ - at24c_eeprom_init(i2c[12], 0x50, 8 * KiB); + at24c_eeprom_init_rom(i2c[12], 0x50, 8 * KiB, + gb200_eeprom, gb200_eeprom_len); /* &i2c13 */ /* eeprom@50 */ - at24c_eeprom_init(i2c[13], 0x50, 8 * KiB); + at24c_eeprom_init_rom(i2c[13], 0x50, 8 * KiB, + gb200_eeprom, gb200_eeprom_len); /* eeprom@54 */ at24c_eeprom_init(i2c[13], 0x54, 256); /* eeprom@55 */ -- 2.52.0
From: Patrick Williams <patrick@stwcx.xyz> Use ipmitool/frugen tool to generate a GB200-IO image based on a sanitized set of data from a real device EEPROM. Signed-off-by: Patrick Williams <patrick@stwcx.xyz> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251217-catalina-eeproms-v1-8-dc7b276efd57@stwcx.xyz Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast2600_catalina.c | 43 ++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/hw/arm/aspeed_ast2600_catalina.c b/hw/arm/aspeed_ast2600_catalina.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast2600_catalina.c +++ b/hw/arm/aspeed_ast2600_catalina.c @@ -XXX,XX +XXX,XX @@ static const uint8_t gb200_eeprom[] = { }; static const size_t gb200_eeprom_len = sizeof(gb200_eeprom); +/* + * GB200 IO Board FRU data. Generated with frugen. + * + * { + * "board": { + * "mfg": "Nvidia", + * "pname": "2x ConnectX-7 Mezz (QEMU)", + * "pn": "000-00000-0000-000", + * "serial": "000000000000", + * "date": "01/12/2025 00:00" + * }, + * "product": { + * "mfg": "Nvidia", + * "pname": "2x ConnectX-7 Mezz", + * "pn": "100-00000-0000-001", + * "ver": "A1", + * "serial": "100000000001", + * "atag": "QEMU" + * } + * } + */ +static const uint8_t gb200io_eeprom[] = { + 0x01, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x00, 0xf4, 0x01, 0x09, 0x19, 0x8c, + 0x19, 0xf0, 0xc6, 0x4e, 0x76, 0x69, 0x64, 0x69, 0x61, 0xd9, 0x32, 0x78, + 0x20, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x58, 0x2d, 0x37, 0x20, + 0x4d, 0x65, 0x7a, 0x7a, 0x20, 0x28, 0x51, 0x45, 0x4d, 0x55, 0x29, 0x89, + 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x8e, 0x10, 0x04, + 0x35, 0x10, 0x04, 0x41, 0x50, 0x03, 0x41, 0x10, 0xd4, 0x40, 0x10, 0x04, + 0xc0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x01, 0x08, 0x19, 0xc6, + 0x4e, 0x76, 0x69, 0x64, 0x69, 0x61, 0xd2, 0x32, 0x78, 0x20, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x58, 0x2d, 0x37, 0x20, 0x4d, 0x65, 0x7a, + 0x7a, 0x8e, 0x11, 0x04, 0x35, 0x10, 0x04, 0x41, 0x50, 0x03, 0x41, 0x10, + 0xd4, 0x40, 0x50, 0x04, 0x82, 0x61, 0x04, 0x89, 0x11, 0x04, 0x41, 0x10, + 0x04, 0x41, 0x10, 0x04, 0x45, 0x83, 0x71, 0xd9, 0xd6, 0xc0, 0xc1, 0x04 +}; +static const size_t gb200io_eeprom_len = sizeof(gb200io_eeprom); + static void catalina_bmc_i2c_init(AspeedMachineState *bmc) { /* Reference from v6.16-rc2 aspeed-bmc-facebook-catalina.dts */ @@ -XXX,XX +XXX,XX @@ static void catalina_bmc_i2c_init(AspeedMachineState *bmc) 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); + at24c_eeprom_init_rom(pca954x_i2c_get_bus(i2c_mux, 1), 0x50, 8 * KiB, + gb200io_eeprom, gb200io_eeprom_len); /* i2c-mux@73 (PCA9546) on i2c0 */ i2c_slave_create_simple(i2c[0], TYPE_PCA9546, 0x73); @@ -XXX,XX +XXX,XX @@ static void catalina_bmc_i2c_init(AspeedMachineState *bmc) 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); + at24c_eeprom_init_rom(pca954x_i2c_get_bus(i2c_mux, 1), 0x50, 8 * KiB, + gb200io_eeprom, gb200io_eeprom_len); /* i2c-mux@77 (PCA9546) on i2c0 */ i2c_slave_create_simple(i2c[0], TYPE_PCA9546, 0x77); -- 2.52.0
From: Patrick Williams <patrick@stwcx.xyz> Use ipmitool/frugen tool to generate a HMC image based on a sanitized set of data from a real device EEPROM. Signed-off-by: Patrick Williams <patrick@stwcx.xyz> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251217-catalina-eeproms-v1-9-dc7b276efd57@stwcx.xyz Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast2600_catalina.c | 42 +++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/hw/arm/aspeed_ast2600_catalina.c b/hw/arm/aspeed_ast2600_catalina.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast2600_catalina.c +++ b/hw/arm/aspeed_ast2600_catalina.c @@ -XXX,XX +XXX,XX @@ static const uint8_t gb200io_eeprom[] = { }; static const size_t gb200io_eeprom_len = sizeof(gb200io_eeprom); +/* + * HMC ("HGX Management Controller") FRU data. Generated with frugen. + * + * { + * "board": { + * "mfg": "NVIDIA", + * "pname": "P4764-A02 (QEMU)", + * "pn": "000-00000-0000-000", + * "serial": "0000000000000", + * "date": "01/12/2025 00:00", + * "custom": ["Version: G", "Rework: R0"] + * }, + * "product": { + * "mfg": "NVIDIA", + * "pname": "HMC for GB200 NVL72", + * "pn": "100-00000-0000-001", + * "ver": "A1", + * "serial": "1000000000001", + * "atag": "QEMU" + * } + * } + */ +static const uint8_t hmc_eeprom[] = { + 0x01, 0x00, 0x00, 0x01, 0x0b, 0x00, 0x00, 0xf3, 0x01, 0x0a, 0x19, 0x8c, + 0x19, 0xf0, 0x85, 0xae, 0x9d, 0x92, 0x69, 0x08, 0x8c, 0x30, 0x75, 0x59, + 0x54, 0x13, 0x42, 0x12, 0x80, 0xc4, 0x65, 0x5b, 0x27, 0x8a, 0x10, 0x04, + 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x8e, 0x10, 0x04, 0x35, + 0x10, 0x04, 0x41, 0x50, 0x03, 0x41, 0x10, 0xd4, 0x40, 0x10, 0x04, 0xc0, + 0xca, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x47, 0xca, + 0x52, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x3a, 0x20, 0x52, 0x30, 0xc1, 0x00, + 0x00, 0x00, 0x00, 0x81, 0x01, 0x09, 0x19, 0x85, 0xae, 0x9d, 0x92, 0x69, + 0x08, 0xd3, 0x48, 0x4d, 0x43, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x47, 0x42, + 0x32, 0x30, 0x30, 0x20, 0x4e, 0x56, 0x4c, 0x37, 0x32, 0x8e, 0x11, 0x04, + 0x35, 0x10, 0x04, 0x41, 0x50, 0x03, 0x41, 0x10, 0xd4, 0x40, 0x50, 0x04, + 0x82, 0x61, 0x04, 0x8a, 0x11, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, + 0x41, 0x11, 0x83, 0x71, 0xd9, 0xd6, 0xc0, 0xc1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x65 +}; +static const size_t hmc_eeprom_len = sizeof(hmc_eeprom); + static void catalina_bmc_i2c_init(AspeedMachineState *bmc) { /* Reference from v6.16-rc2 aspeed-bmc-facebook-catalina.dts */ @@ -XXX,XX +XXX,XX @@ static void catalina_bmc_i2c_init(AspeedMachineState *bmc) /* eeprom@55 */ at24c_eeprom_init(i2c[13], 0x55, 256); /* eeprom@57 */ - at24c_eeprom_init(i2c[13], 0x57, 256); + at24c_eeprom_init_rom(i2c[13], 0x57, 256, hmc_eeprom, hmc_eeprom_len); /* &i2c14 */ /* io_expander9 - pca9555@10 */ -- 2.52.0
From: Patrick Williams <patrick@stwcx.xyz> Use ipmitool/frugen tool to generate a CX-7 NIC image based on a sanitized set of data from a real device EEPROM. Signed-off-by: Patrick Williams <patrick@stwcx.xyz> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251217-catalina-eeproms-v1-10-dc7b276efd57@stwcx.xyz Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast2600_catalina.c | 42 ++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/hw/arm/aspeed_ast2600_catalina.c b/hw/arm/aspeed_ast2600_catalina.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast2600_catalina.c +++ b/hw/arm/aspeed_ast2600_catalina.c @@ -XXX,XX +XXX,XX @@ static const uint8_t hmc_eeprom[] = { }; static const size_t hmc_eeprom_len = sizeof(hmc_eeprom); +/* + * CX-7 NIC FRU data. Generated with frugen. + * + * { + * "board": { + * "mfg": "Nvidia", + * "pname": "Nvidia ConnectX-7 OCP3.0 (QEMU)", + * "pn": "CX70000000-000_00", + * "serial": "000000000000", + * "date": "01/12/2025 00:00" + * }, + * "product": { + * "mfg": "Nvidia", + * "pname": "Nvidia ConnectX-7 OCP3.0", + * "pn": "CX71000000-000_01", + * "ver": "A7", + * "serial": "100000000001", + * "atag": "QEMU" + * } + * } + */ +static const uint8_t nic_eeprom[] = { + 0x01, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x00, 0xf4, 0x01, 0x09, 0x19, 0x8c, + 0x19, 0xf0, 0xc6, 0x4e, 0x76, 0x69, 0x64, 0x69, 0x61, 0xdf, 0x4e, 0x76, + 0x69, 0x64, 0x69, 0x61, 0x20, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x58, 0x2d, 0x37, 0x20, 0x4f, 0x43, 0x50, 0x33, 0x2e, 0x30, 0x20, 0x28, + 0x51, 0x45, 0x4d, 0x55, 0x29, 0x89, 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, + 0x10, 0x04, 0x41, 0x8d, 0x23, 0x7e, 0x41, 0x10, 0x04, 0x41, 0x10, 0xd4, + 0x40, 0x10, 0xf4, 0x43, 0x10, 0xc0, 0xc1, 0xc3, 0x01, 0x09, 0x19, 0xc6, + 0x4e, 0x76, 0x69, 0x64, 0x69, 0x61, 0xd8, 0x4e, 0x76, 0x69, 0x64, 0x69, + 0x61, 0x20, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x58, 0x2d, 0x37, + 0x20, 0x4f, 0x43, 0x50, 0x33, 0x2e, 0x30, 0x8d, 0x23, 0x7e, 0x45, 0x10, + 0x04, 0x41, 0x10, 0xd4, 0x40, 0x10, 0xf4, 0x43, 0x11, 0x82, 0xe1, 0x05, + 0x89, 0x11, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x45, 0x83, 0x71, + 0xd9, 0xd6, 0xc0, 0xc1, 0x00, 0x00, 0x00, 0xf3 +}; +static const size_t nic_eeprom_len = sizeof(nic_eeprom); + static void catalina_bmc_i2c_init(AspeedMachineState *bmc) { /* Reference from v6.16-rc2 aspeed-bmc-facebook-catalina.dts */ @@ -XXX,XX +XXX,XX @@ static void catalina_bmc_i2c_init(AspeedMachineState *bmc) /* temperature-sensor@1f - tpm421 */ i2c_slave_create_simple(i2c[10], TYPE_TMP421, 0x1f); /* eeprom@50 */ - at24c_eeprom_init(i2c[10], 0x50, 8 * KiB); + at24c_eeprom_init_rom(i2c[10], 0x50, 8 * KiB, nic_eeprom, nic_eeprom_len); /* &i2c11 */ /* ssif-bmc@10 - no model */ @@ -XXX,XX +XXX,XX @@ static void catalina_bmc_i2c_init(AspeedMachineState *bmc) /* temperature-sensor@1f - tmp421 */ i2c_slave_create_simple(i2c[15], TYPE_TMP421, 0x1f); /* eeprom@52 */ - at24c_eeprom_init(i2c[15], 0x52, 8 * KiB); + at24c_eeprom_init_rom(i2c[15], 0x52, 8 * KiB, nic_eeprom, nic_eeprom_len); } static void aspeed_machine_catalina_class_init(ObjectClass *oc, -- 2.52.0
From: Patrick Williams <patrick@stwcx.xyz> Use ipmitool/frugen tool to generate a Cable Cart image based on a sanitized set of data from a real device EEPROM. The EEPROM bus/address did not match device tree for one of the EEPROMs so move it from bus 13 / 55 to bus 12 / 54. Signed-off-by: Patrick Williams <patrick@stwcx.xyz> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251217-catalina-eeproms-v1-11-dc7b276efd57@stwcx.xyz Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast2600_catalina.c | 46 +++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/hw/arm/aspeed_ast2600_catalina.c b/hw/arm/aspeed_ast2600_catalina.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast2600_catalina.c +++ b/hw/arm/aspeed_ast2600_catalina.c @@ -XXX,XX +XXX,XX @@ static const uint8_t nic_eeprom[] = { }; static const size_t nic_eeprom_len = sizeof(nic_eeprom); +/* + * Cable Cartridge FRU data. Generated with frugen. + * + * { + * "board": { + * "mfg": "Nvidia", + * "pname": "18x1RU CBL Cartridge (QEMU)", + * "pn": "000-0000-000", + * "serial": "0000000000000", + * "date": "01/12/2025 00:00" + * }, + * "product": { + * "mfg": "Nvidia", + * "pname": "18x1RU CBL Cartridge", + * "pn": "100-00000-0000-001", + * "ver": "E.4", + * "serial": "1000000000001", + * "atag": "QEMU" + * } + * } + */ +static const uint8_t cable_eeprom[] = { + 0x01, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x00, 0xf4, 0x01, 0x09, 0x19, 0x8c, + 0x19, 0xf0, 0xc6, 0x4e, 0x76, 0x69, 0x64, 0x69, 0x61, 0xdb, 0x31, 0x38, + 0x78, 0x31, 0x52, 0x55, 0x20, 0x43, 0x42, 0x4c, 0x20, 0x43, 0x61, 0x72, + 0x74, 0x72, 0x69, 0x64, 0x67, 0x65, 0x20, 0x28, 0x51, 0x45, 0x4d, 0x55, + 0x29, 0x8a, 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, + 0x89, 0x10, 0x04, 0x35, 0x10, 0x04, 0x41, 0x0d, 0x04, 0x41, 0xc0, 0xc1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x01, 0x09, 0x19, 0xc6, + 0x4e, 0x76, 0x69, 0x64, 0x69, 0x61, 0xd4, 0x31, 0x38, 0x78, 0x31, 0x52, + 0x55, 0x20, 0x43, 0x42, 0x4c, 0x20, 0x43, 0x61, 0x72, 0x74, 0x72, 0x69, + 0x64, 0x67, 0x65, 0x8e, 0x11, 0x04, 0x35, 0x10, 0x04, 0x41, 0x50, 0x03, + 0x41, 0x10, 0xd4, 0x40, 0x50, 0x04, 0x83, 0xa5, 0x43, 0x01, 0x8a, 0x11, + 0x04, 0x41, 0x10, 0x04, 0x41, 0x10, 0x04, 0x41, 0x11, 0x83, 0x71, 0xd9, + 0xd6, 0xc0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x25 +}; +static const size_t cable_eeprom_len = sizeof(cable_eeprom); + static void catalina_bmc_i2c_init(AspeedMachineState *bmc) { /* Reference from v6.16-rc2 aspeed-bmc-facebook-catalina.dts */ @@ -XXX,XX +XXX,XX @@ static void catalina_bmc_i2c_init(AspeedMachineState *bmc) /* eeprom@50 */ at24c_eeprom_init_rom(i2c[12], 0x50, 8 * KiB, gb200_eeprom, gb200_eeprom_len); + /* eeprom@54 */ + at24c_eeprom_init_rom(i2c[12], 0x54, 256, + cable_eeprom, cable_eeprom_len); /* &i2c13 */ /* eeprom@50 */ at24c_eeprom_init_rom(i2c[13], 0x50, 8 * KiB, gb200_eeprom, gb200_eeprom_len); /* eeprom@54 */ - at24c_eeprom_init(i2c[13], 0x54, 256); - /* eeprom@55 */ - at24c_eeprom_init(i2c[13], 0x55, 256); + at24c_eeprom_init_rom(i2c[13], 0x54, 256, + cable_eeprom, cable_eeprom_len); /* eeprom@57 */ at24c_eeprom_init_rom(i2c[13], 0x57, 256, hmc_eeprom, hmc_eeprom_len); -- 2.52.0
From: Yubin Zou <yubinz@google.com> This initial implementation includes the basic device structure, memory-mapped register definitions, and read/write handlers for the SGPIO control registers. Signed-off-by: Yubin Zou <yubinz@google.com> Reviewed-by: Kane Chen <kane_chen@aspeedtech.com> Link: https://lore.kernel.org/qemu-devel/20251219-aspeed-sgpio-v5-1-fd5593178144@google.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- include/hw/gpio/aspeed_sgpio.h | 66 +++++++++++++++ hw/gpio/aspeed_sgpio.c | 145 +++++++++++++++++++++++++++++++++ hw/gpio/meson.build | 1 + 3 files changed, 212 insertions(+) create mode 100644 include/hw/gpio/aspeed_sgpio.h create mode 100644 hw/gpio/aspeed_sgpio.c diff --git a/include/hw/gpio/aspeed_sgpio.h b/include/hw/gpio/aspeed_sgpio.h new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/include/hw/gpio/aspeed_sgpio.h @@ -XXX,XX +XXX,XX @@ +/* + * ASPEED Serial GPIO Controller + * + * Copyright 2025 Google LLC. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef ASPEED_SGPIO_H +#define ASPEED_SGPIO_H + +#include "hw/core/sysbus.h" +#include "qom/object.h" +#include "hw/core/registerfields.h" + +#define TYPE_ASPEED_SGPIO "aspeed.sgpio" +OBJECT_DECLARE_TYPE(AspeedSGPIOState, AspeedSGPIOClass, ASPEED_SGPIO) + +#define ASPEED_SGPIO_MAX_PIN_PAIR 256 +#define ASPEED_SGPIO_MAX_INT 8 + +/* AST2700 SGPIO Register Address Offsets */ +REG32(SGPIO_INT_STATUS_0, 0x40) +REG32(SGPIO_INT_STATUS_1, 0x44) +REG32(SGPIO_INT_STATUS_2, 0x48) +REG32(SGPIO_INT_STATUS_3, 0x4C) +REG32(SGPIO_INT_STATUS_4, 0x50) +REG32(SGPIO_INT_STATUS_5, 0x54) +REG32(SGPIO_INT_STATUS_6, 0x58) +REG32(SGPIO_INT_STATUS_7, 0x5C) +/* AST2700 SGPIO_0 - SGPIO_255 Control Register */ +REG32(SGPIO_0_CONTROL, 0x80) + SHARED_FIELD(SGPIO_SERIAL_OUT_VAL, 0, 1) + SHARED_FIELD(SGPIO_PARALLEL_OUT_VAL, 1, 1) + SHARED_FIELD(SGPIO_INT_EN, 2, 1) + SHARED_FIELD(SGPIO_INT_TYPE, 3, 3) + SHARED_FIELD(SGPIO_RESET_POLARITY, 6, 1) + SHARED_FIELD(SGPIO_RESERVED_1, 7, 2) + SHARED_FIELD(SGPIO_INPUT_MASK, 9, 1) + SHARED_FIELD(SGPIO_PARALLEL_EN, 10, 1) + SHARED_FIELD(SGPIO_PARALLEL_IN_MODE, 11, 1) + SHARED_FIELD(SGPIO_INT_STATUS, 12, 1) + SHARED_FIELD(SGPIO_SERIAL_IN_VAL, 13, 1) + SHARED_FIELD(SGPIO_PARALLEL_IN_VAL, 14, 1) + SHARED_FIELD(SGPIO_RESERVED_2, 15, 12) + SHARED_FIELD(SGPIO_WRITE_PROTECT, 31, 1) +REG32(SGPIO_255_CONTROL, 0x47C) + +struct AspeedSGPIOClass { + SysBusDeviceClass parent_class; + uint32_t nr_sgpio_pin_pairs; + uint64_t mem_size; + const MemoryRegionOps *reg_ops; +}; + +struct AspeedSGPIOState { + /* <private> */ + SysBusDevice parent; + + /*< public >*/ + MemoryRegion iomem; + qemu_irq irq; + uint32_t ctrl_regs[ASPEED_SGPIO_MAX_PIN_PAIR]; + uint32_t int_regs[ASPEED_SGPIO_MAX_INT]; +}; + +#endif /* ASPEED_SGPIO_H */ diff --git a/hw/gpio/aspeed_sgpio.c b/hw/gpio/aspeed_sgpio.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/hw/gpio/aspeed_sgpio.c @@ -XXX,XX +XXX,XX @@ +/* + * ASPEED Serial GPIO Controller + * + * Copyright 2025 Google LLC. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/host-utils.h" +#include "qemu/log.h" +#include "qemu/error-report.h" +#include "qapi/error.h" +#include "qapi/visitor.h" +#include "hw/core/qdev-properties.h" +#include "hw/gpio/aspeed_sgpio.h" + +static uint64_t aspeed_sgpio_2700_read_control_reg(AspeedSGPIOState *s, + uint32_t reg) +{ + AspeedSGPIOClass *agc = ASPEED_SGPIO_GET_CLASS(s); + uint32_t idx = reg - R_SGPIO_0_CONTROL; + if (idx >= agc->nr_sgpio_pin_pairs) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: pin index: %d, out of bounds\n", + __func__, idx); + return 0; + } + return s->ctrl_regs[idx]; +} + +static void aspeed_sgpio_2700_write_control_reg(AspeedSGPIOState *s, + uint32_t reg, uint64_t data) +{ + AspeedSGPIOClass *agc = ASPEED_SGPIO_GET_CLASS(s); + uint32_t idx = reg - R_SGPIO_0_CONTROL; + if (idx >= agc->nr_sgpio_pin_pairs) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: pin index: %d, out of bounds\n", + __func__, idx); + return; + } + s->ctrl_regs[idx] = data; +} + +static uint64_t aspeed_sgpio_2700_read(void *opaque, hwaddr offset, + uint32_t size) +{ + AspeedSGPIOState *s = ASPEED_SGPIO(opaque); + uint64_t value = 0; + uint64_t reg; + + reg = offset >> 2; + + switch (reg) { + case R_SGPIO_0_CONTROL ... R_SGPIO_255_CONTROL: + value = aspeed_sgpio_2700_read_control_reg(s, reg); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%" + HWADDR_PRIx"\n", __func__, offset); + return 0; + } + + return value; +} + +static void aspeed_sgpio_2700_write(void *opaque, hwaddr offset, uint64_t data, + uint32_t size) +{ + AspeedSGPIOState *s = ASPEED_SGPIO(opaque); + uint64_t reg; + + reg = offset >> 2; + + switch (reg) { + case R_SGPIO_0_CONTROL ... R_SGPIO_255_CONTROL: + aspeed_sgpio_2700_write_control_reg(s, reg, data); + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%" + HWADDR_PRIx"\n", __func__, offset); + return; + } +} + +static const MemoryRegionOps aspeed_sgpio_2700_ops = { + .read = aspeed_sgpio_2700_read, + .write = aspeed_sgpio_2700_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid.min_access_size = 4, + .valid.max_access_size = 4, +}; + +static void aspeed_sgpio_realize(DeviceState *dev, Error **errp) +{ + AspeedSGPIOState *s = ASPEED_SGPIO(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + AspeedSGPIOClass *agc = ASPEED_SGPIO_GET_CLASS(s); + + /* Interrupt parent line */ + sysbus_init_irq(sbd, &s->irq); + + memory_region_init_io(&s->iomem, OBJECT(s), agc->reg_ops, s, + TYPE_ASPEED_SGPIO, agc->mem_size); + + sysbus_init_mmio(sbd, &s->iomem); +} + +static void aspeed_sgpio_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = aspeed_sgpio_realize; + dc->desc = "Aspeed SGPIO Controller"; +} + +static void aspeed_sgpio_2700_class_init(ObjectClass *klass, const void *data) +{ + AspeedSGPIOClass *agc = ASPEED_SGPIO_CLASS(klass); + agc->nr_sgpio_pin_pairs = ASPEED_SGPIO_MAX_PIN_PAIR; + agc->mem_size = 0x1000; + agc->reg_ops = &aspeed_sgpio_2700_ops; +} + +static const TypeInfo aspeed_sgpio_info = { + .name = TYPE_ASPEED_SGPIO, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(AspeedSGPIOState), + .class_size = sizeof(AspeedSGPIOClass), + .class_init = aspeed_sgpio_class_init, + .abstract = true, +}; + +static const TypeInfo aspeed_sgpio_ast2700_info = { + .name = TYPE_ASPEED_SGPIO "-ast2700", + .parent = TYPE_ASPEED_SGPIO, + .class_init = aspeed_sgpio_2700_class_init, +}; + +static void aspeed_sgpio_register_types(void) +{ + type_register_static(&aspeed_sgpio_info); + type_register_static(&aspeed_sgpio_ast2700_info); +} + +type_init(aspeed_sgpio_register_types); diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build index XXXXXXX..XXXXXXX 100644 --- a/hw/gpio/meson.build +++ b/hw/gpio/meson.build @@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_RASPI', if_true: files( )) system_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_gpio.c')) system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_gpio.c')) +system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_sgpio.c')) system_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpio.c')) system_ss.add(when: 'CONFIG_PCF8574', if_true: files('pcf8574.c')) -- 2.52.0
From: Yubin Zou <yubinz@google.com> The `aspeed_sgpio_get_pin` and `aspeed_sgpio_set_pin` functions are implemented to get and set the level of individual SGPIO pins. These are then exposed as boolean properties on the SGPIO device object. Signed-off-by: Yubin Zou <yubinz@google.com> Reviewed-by: Kane Chen <kane_chen@aspeedtech.com> Link: https://lore.kernel.org/qemu-devel/20251219-aspeed-sgpio-v5-2-fd5593178144@google.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/gpio/aspeed_sgpio.c | 79 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/hw/gpio/aspeed_sgpio.c b/hw/gpio/aspeed_sgpio.c index XXXXXXX..XXXXXXX 100644 --- a/hw/gpio/aspeed_sgpio.c +++ b/hw/gpio/aspeed_sgpio.c @@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_sgpio_2700_read(void *opaque, hwaddr offset, reg = offset >> 2; switch (reg) { + case R_SGPIO_INT_STATUS_0 ... R_SGPIO_INT_STATUS_7: + break; case R_SGPIO_0_CONTROL ... R_SGPIO_255_CONTROL: value = aspeed_sgpio_2700_read_control_reg(s, reg); break; @@ -XXX,XX +XXX,XX @@ static void aspeed_sgpio_2700_write(void *opaque, hwaddr offset, uint64_t data, } } +static bool aspeed_sgpio_get_pin_level(AspeedSGPIOState *s, int pin) +{ + uint32_t value = s->ctrl_regs[pin >> 1]; + bool is_input = !(pin % 2); + uint32_t bit_mask = 0; + + if (is_input) { + bit_mask = SGPIO_SERIAL_IN_VAL_MASK; + } else { + bit_mask = SGPIO_SERIAL_OUT_VAL_MASK; + } + + return value & bit_mask; +} + +static void aspeed_sgpio_set_pin_level(AspeedSGPIOState *s, int pin, bool level) +{ + uint32_t value = s->ctrl_regs[pin >> 1]; + bool is_input = !(pin % 2); + uint32_t bit_mask = 0; + + if (is_input) { + bit_mask = SGPIO_SERIAL_IN_VAL_MASK; + } else { + bit_mask = SGPIO_SERIAL_OUT_VAL_MASK; + } + + if (level) { + value |= bit_mask; + } else { + value &= ~bit_mask; + } + s->ctrl_regs[pin >> 1] = value; +} + +static void aspeed_sgpio_get_pin(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + bool level = true; + int pin = 0xfff; + AspeedSGPIOState *s = ASPEED_SGPIO(obj); + + if (sscanf(name, "sgpio%03d", &pin) != 1) { + error_setg(errp, "%s: error reading %s", __func__, name); + return; + } + level = aspeed_sgpio_get_pin_level(s, pin); + visit_type_bool(v, name, &level, errp); +} + +static void aspeed_sgpio_set_pin(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + bool level; + int pin = 0xfff; + AspeedSGPIOState *s = ASPEED_SGPIO(obj); + + if (!visit_type_bool(v, name, &level, errp)) { + return; + } + if (sscanf(name, "sgpio%03d", &pin) != 1) { + error_setg(errp, "%s: error reading %s", __func__, name); + return; + } + aspeed_sgpio_set_pin_level(s, pin, level); +} + static const MemoryRegionOps aspeed_sgpio_2700_ops = { .read = aspeed_sgpio_2700_read, .write = aspeed_sgpio_2700_write, @@ -XXX,XX +XXX,XX @@ static void aspeed_sgpio_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, &s->iomem); } +static void aspeed_sgpio_init(Object *obj) +{ + for (int i = 0; i < ASPEED_SGPIO_MAX_PIN_PAIR * 2; i++) { + g_autofree char *name = g_strdup_printf("sgpio%03d", i); + object_property_add(obj, name, "bool", aspeed_sgpio_get_pin, + aspeed_sgpio_set_pin, NULL, NULL); + } +} + static void aspeed_sgpio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_sgpio_ast2700_info = { .name = TYPE_ASPEED_SGPIO "-ast2700", .parent = TYPE_ASPEED_SGPIO, .class_init = aspeed_sgpio_2700_class_init, + .instance_init = aspeed_sgpio_init, }; static void aspeed_sgpio_register_types(void) -- 2.52.0
From: Yubin Zou <yubinz@google.com> The SGPIO controller can generate interrupts based on various pin state changes, such as rising/falling edges or high/low levels. This change adds the necessary logic to detect these events, update the interrupt status registers, and signal the interrupt to the SoC. Signed-off-by: Yubin Zou <yubinz@google.com> Reviewed-by: Kane Chen <kane_chen@aspeedtech.com> Link: https://lore.kernel.org/qemu-devel/20251219-aspeed-sgpio-v5-3-fd5593178144@google.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- include/hw/gpio/aspeed_sgpio.h | 2 + hw/gpio/aspeed_sgpio.c | 126 ++++++++++++++++++++++++++++++++- 2 files changed, 126 insertions(+), 2 deletions(-) diff --git a/include/hw/gpio/aspeed_sgpio.h b/include/hw/gpio/aspeed_sgpio.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/gpio/aspeed_sgpio.h +++ b/include/hw/gpio/aspeed_sgpio.h @@ -XXX,XX +XXX,XX @@ struct AspeedSGPIOState { /*< public >*/ MemoryRegion iomem; + int pending; qemu_irq irq; + qemu_irq sgpios[ASPEED_SGPIO_MAX_PIN_PAIR]; uint32_t ctrl_regs[ASPEED_SGPIO_MAX_PIN_PAIR]; uint32_t int_regs[ASPEED_SGPIO_MAX_INT]; }; diff --git a/hw/gpio/aspeed_sgpio.c b/hw/gpio/aspeed_sgpio.c index XXXXXXX..XXXXXXX 100644 --- a/hw/gpio/aspeed_sgpio.c +++ b/hw/gpio/aspeed_sgpio.c @@ -XXX,XX +XXX,XX @@ #include "qemu/error-report.h" #include "qapi/error.h" #include "qapi/visitor.h" +#include "hw/core/irq.h" #include "hw/core/qdev-properties.h" #include "hw/gpio/aspeed_sgpio.h" +/* + * For each set of gpios there are three sensitivity registers that control + * the interrupt trigger mode. + * + * | 2 | 1 | 0 | trigger mode + * ----------------------------- + * | 0 | 0 | 0 | falling-edge + * | 0 | 0 | 1 | rising-edge + * | 0 | 1 | 0 | level-low + * | 0 | 1 | 1 | level-high + * | 1 | X | X | dual-edge + */ + +/* GPIO Interrupt Triggers */ +#define ASPEED_FALLING_EDGE 0 +#define ASPEED_RISING_EDGE 1 +#define ASPEED_LEVEL_LOW 2 +#define ASPEED_LEVEL_HIGH 3 +#define ASPEED_DUAL_EDGE 4 + +static void aspeed_clear_irq(AspeedSGPIOState *s, int idx) +{ + uint32_t reg_index = idx / 32; + uint32_t bit_index = idx % 32; + uint32_t pending = extract32(s->int_regs[reg_index], bit_index, 1); + + assert(s->pending >= pending); + + /* No change to s->pending if pending is 0 */ + s->pending -= pending; + + /* + * The write acknowledged the interrupt regardless of whether it + * was pending or not. The post-condition is that it mustn't be + * pending. Unconditionally clear the status bit. + */ + s->int_regs[reg_index] = deposit32(s->int_regs[reg_index], bit_index, 1, 0); +} + +static void aspeed_evaluate_irq(AspeedSGPIOState *s, int sgpio_prev_high, + int sgpio_curr_high, int idx) +{ + uint32_t ctrl = s->ctrl_regs[idx]; + uint32_t falling_edge = 0, rising_edge = 0; + uint32_t int_trigger = SHARED_FIELD_EX32(ctrl, SGPIO_INT_TYPE); + uint32_t int_enabled = SHARED_FIELD_EX32(ctrl, SGPIO_INT_EN); + uint32_t reg_index = idx / 32; + uint32_t bit_index = idx % 32; + + if (!int_enabled) { + return; + } + + /* Detect edges */ + if (sgpio_curr_high && !sgpio_prev_high) { + rising_edge = 1; + } else if (!sgpio_curr_high && sgpio_prev_high) { + falling_edge = 1; + } + + if (((int_trigger == ASPEED_FALLING_EDGE) && falling_edge) || + ((int_trigger == ASPEED_RISING_EDGE) && rising_edge) || + ((int_trigger == ASPEED_LEVEL_LOW) && !sgpio_curr_high) || + ((int_trigger == ASPEED_LEVEL_HIGH) && sgpio_curr_high) || + ((int_trigger >= ASPEED_DUAL_EDGE) && (rising_edge || falling_edge))) + { + s->int_regs[reg_index] = deposit32(s->int_regs[reg_index], + bit_index, 1, 1); + /* Trigger the VIC IRQ */ + s->pending++; + } +} + +static void aspeed_sgpio_update(AspeedSGPIOState *s, uint32_t idx, + uint32_t value) +{ + uint32_t old = s->ctrl_regs[idx]; + uint32_t new = value; + uint32_t diff = (old ^ new); + if (diff) { + /* If the interrupt clear bit is set */ + if (SHARED_FIELD_EX32(new, SGPIO_INT_STATUS)) { + aspeed_clear_irq(s, idx); + /* Clear the interrupt clear bit */ + new &= ~SGPIO_INT_STATUS_MASK; + } + + /* Update the control register. */ + s->ctrl_regs[idx] = new; + + /* If the output value is changed */ + if (SHARED_FIELD_EX32(diff, SGPIO_SERIAL_OUT_VAL)) { + /* ...trigger the line-state IRQ */ + qemu_set_irq(s->sgpios[idx], 1); + } + + /* If the input value is changed */ + if (SHARED_FIELD_EX32(diff, SGPIO_SERIAL_IN_VAL)) { + aspeed_evaluate_irq(s, + SHARED_FIELD_EX32(old, SGPIO_SERIAL_IN_VAL), + SHARED_FIELD_EX32(new, SGPIO_SERIAL_IN_VAL), + idx); + } + } + qemu_set_irq(s->irq, !!(s->pending)); +} + +static uint64_t aspeed_sgpio_2700_read_int_status_reg(AspeedSGPIOState *s, + uint32_t reg) +{ + uint32_t idx = reg - R_SGPIO_INT_STATUS_0; + if (idx >= ASPEED_SGPIO_MAX_INT) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: interrupt status index: %d, out of bounds\n", + __func__, idx); + return 0; + } + return s->int_regs[idx]; +} + static uint64_t aspeed_sgpio_2700_read_control_reg(AspeedSGPIOState *s, uint32_t reg) { @@ -XXX,XX +XXX,XX @@ static void aspeed_sgpio_2700_write_control_reg(AspeedSGPIOState *s, __func__, idx); return; } - s->ctrl_regs[idx] = data; + aspeed_sgpio_update(s, idx, data); } static uint64_t aspeed_sgpio_2700_read(void *opaque, hwaddr offset, @@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_sgpio_2700_read(void *opaque, hwaddr offset, switch (reg) { case R_SGPIO_INT_STATUS_0 ... R_SGPIO_INT_STATUS_7: + value = aspeed_sgpio_2700_read_int_status_reg(s, reg); break; case R_SGPIO_0_CONTROL ... R_SGPIO_255_CONTROL: value = aspeed_sgpio_2700_read_control_reg(s, reg); @@ -XXX,XX +XXX,XX @@ static void aspeed_sgpio_set_pin_level(AspeedSGPIOState *s, int pin, bool level) } else { value &= ~bit_mask; } - s->ctrl_regs[pin >> 1] = value; + aspeed_sgpio_update(s, pin >> 1, value); } static void aspeed_sgpio_get_pin(Object *obj, Visitor *v, const char *name, -- 2.52.0
From: Yubin Zou <yubinz@google.com> This commit updates the Aspeed SoC model to support two SGPIO controllers, reflecting the hardware capabilities of the AST2700 The memory map and interrupt map are updated to include entries for two SGPIO controllers (SGPIOM0 and SGPIOM1). This change is a prerequisite for the full implementation of the SGPIO device model. Signed-off-by: Yubin Zou <yubinz@google.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251219-aspeed-sgpio-v5-4-fd5593178144@google.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- include/hw/arm/aspeed_soc.h | 8 ++++++-- hw/arm/aspeed_ast10x0.c | 6 +++--- hw/arm/aspeed_ast27x0.c | 10 ++++++++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/arm/aspeed_soc.h +++ b/include/hw/arm/aspeed_soc.h @@ -XXX,XX +XXX,XX @@ #include "hw/net/ftgmac100.h" #include "target/arm/cpu.h" #include "hw/gpio/aspeed_gpio.h" +#include "hw/gpio/aspeed_sgpio.h" #include "hw/sd/aspeed_sdhci.h" #include "hw/usb/hcd-ehci.h" #include "qom/object.h" @@ -XXX,XX +XXX,XX @@ #define VBOOTROM_FILE_NAME "ast27x0_bootrom.bin" #define ASPEED_SPIS_NUM 3 +#define ASPEED_SGPIO_NUM 2 #define ASPEED_EHCIS_NUM 4 #define ASPEED_WDTS_NUM 8 #define ASPEED_CPUS_NUM 4 @@ -XXX,XX +XXX,XX @@ struct AspeedSoCState { AspeedMiiState mii[ASPEED_MACS_NUM]; AspeedGPIOState gpio; AspeedGPIOState gpio_1_8v; + AspeedSGPIOState sgpiom[ASPEED_SGPIO_NUM]; AspeedSDHCIState sdhci; AspeedSDHCIState emmc; AspeedLPCState lpc; @@ -XXX,XX +XXX,XX @@ struct AspeedSoCState { UnimplementedDeviceState pwm; UnimplementedDeviceState espi; UnimplementedDeviceState udc; - UnimplementedDeviceState sgpiom; UnimplementedDeviceState ltpi; UnimplementedDeviceState jtag[ASPEED_JTAG_NUM]; AspeedAPB2OPBState fsi[2]; @@ -XXX,XX +XXX,XX @@ struct AspeedSoCClass { uint64_t secsram_size; int pcie_num; int spis_num; + int sgpio_num; int ehcis_num; int wdts_num; int macs_num; @@ -XXX,XX +XXX,XX @@ enum { ASPEED_DEV_SDHCI, ASPEED_DEV_GPIO, ASPEED_DEV_GPIO_1_8V, + ASPEED_DEV_SGPIOM0, + ASPEED_DEV_SGPIOM1, ASPEED_DEV_RTC, ASPEED_DEV_TIMER1, ASPEED_DEV_TIMER2, @@ -XXX,XX +XXX,XX @@ enum { ASPEED_DEV_I3C, ASPEED_DEV_ESPI, ASPEED_DEV_UDC, - ASPEED_DEV_SGPIOM, ASPEED_DEV_JTAG0, ASPEED_DEV_JTAG1, ASPEED_DEV_FSI1, diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast10x0.c +++ b/hw/arm/aspeed_ast10x0.c @@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast1030_memmap[] = { [ASPEED_DEV_ESPI] = 0x7E6EE000, [ASPEED_DEV_SBC] = 0x7E6F2000, [ASPEED_DEV_GPIO] = 0x7E780000, - [ASPEED_DEV_SGPIOM] = 0x7E780500, + [ASPEED_DEV_SGPIOM0] = 0x7E780500, [ASPEED_DEV_TIMER1] = 0x7E782000, [ASPEED_DEV_UART1] = 0x7E783000, [ASPEED_DEV_UART2] = 0x7E78D000, @@ -XXX,XX +XXX,XX @@ static const int aspeed_soc_ast1030_irqmap[] = { [ASPEED_DEV_I2C] = 110, /* 110 ~ 123 */ [ASPEED_DEV_KCS] = 138, /* 138 -> 142 */ [ASPEED_DEV_UDC] = 9, - [ASPEED_DEV_SGPIOM] = 51, + [ASPEED_DEV_SGPIOM0] = 51, [ASPEED_DEV_JTAG0] = 27, [ASPEED_DEV_JTAG1] = 53, }; @@ -XXX,XX +XXX,XX @@ static bool aspeed_soc_ast10x0_realize(Aspeed10x0SoCState *a, Error **errp) sc->memmap[ASPEED_DEV_UDC], 0x1000); aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->sgpiom), "aspeed.sgpiom", - sc->memmap[ASPEED_DEV_SGPIOM], 0x100); + sc->memmap[ASPEED_DEV_SGPIOM0], 0x100); aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->jtag[0]), "aspeed.jtag", diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0.c +++ b/hw/arm/aspeed_ast27x0.c @@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast2700_memmap[] = { [ASPEED_DEV_ADC] = 0x14C00000, [ASPEED_DEV_SCUIO] = 0x14C02000, [ASPEED_DEV_GPIO] = 0x14C0B000, + [ASPEED_DEV_SGPIOM0] = 0x14C0C000, + [ASPEED_DEV_SGPIOM1] = 0x14C0D000, [ASPEED_DEV_I2C] = 0x14C0F000, [ASPEED_DEV_INTCIO] = 0x14C18000, [ASPEED_DEV_PCIE_PHY2] = 0x14C1C000, @@ -XXX,XX +XXX,XX @@ static const int aspeed_soc_ast2700a0_irqmap[] = { [ASPEED_DEV_KCS] = 128, [ASPEED_DEV_ADC] = 130, [ASPEED_DEV_GPIO] = 130, + [ASPEED_DEV_SGPIOM0] = 130, + [ASPEED_DEV_SGPIOM1] = 130, [ASPEED_DEV_I2C] = 130, [ASPEED_DEV_FMC] = 131, [ASPEED_DEV_WDT] = 131, @@ -XXX,XX +XXX,XX @@ static const int aspeed_soc_ast2700a1_irqmap[] = { [ASPEED_DEV_I2C] = 194, [ASPEED_DEV_ADC] = 194, [ASPEED_DEV_GPIO] = 194, + [ASPEED_DEV_SGPIOM0] = 194, + [ASPEED_DEV_SGPIOM1] = 194, [ASPEED_DEV_FMC] = 195, [ASPEED_DEV_WDT] = 195, [ASPEED_DEV_PWM] = 195, @@ -XXX,XX +XXX,XX @@ static const int ast2700_gic130_gic194_intcmap[] = { [ASPEED_DEV_I2C] = 0, [ASPEED_DEV_ADC] = 16, [ASPEED_DEV_GPIO] = 18, + [ASPEED_DEV_SGPIOM0] = 21, + [ASPEED_DEV_SGPIOM1] = 24, }; /* GICINT 131 */ @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc, const void *data) sc->sram_size = 0x20000; sc->pcie_num = 0; sc->spis_num = 3; + sc->sgpio_num = 2; sc->ehcis_num = 2; sc->wdts_num = 8; sc->macs_num = 1; @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2700a1_class_init(ObjectClass *oc, const void *data) sc->sram_size = 0x20000; sc->pcie_num = 3; sc->spis_num = 3; + sc->sgpio_num = 2; sc->ehcis_num = 4; sc->wdts_num = 8; sc->macs_num = 3; -- 2.52.0
From: Yubin Zou <yubinz@google.com> This commit integrates the Aspeed SGPIO controller into the AST2700 Signed-off-by: Yubin Zou <yubinz@google.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20251219-aspeed-sgpio-v5-5-fd5593178144@google.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast27x0.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0.c +++ b/hw/arm/aspeed_ast27x0.c @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2700_init(Object *obj) snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname); object_initialize_child(obj, "gpio", &s->gpio, typename); + snprintf(typename, sizeof(typename), "aspeed.sgpio-%s", socname); + for (i = 0; i < sc->sgpio_num; i++) { + object_initialize_child(obj, "sgpio[*]", &s->sgpiom[i], typename); + } + object_initialize_child(obj, "rtc", &s->rtc, TYPE_ASPEED_RTC); snprintf(typename, sizeof(typename), "aspeed.sdhci-%s", socname); @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0, aspeed_soc_ast2700_get_irq(s, ASPEED_DEV_GPIO)); + /* SGPIO */ + for (i = 0; i < sc->sgpio_num; i++) { + if (!sysbus_realize(SYS_BUS_DEVICE(&s->sgpiom[i]), errp)) { + return; + } + aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->sgpiom[i]), 0, + sc->memmap[ASPEED_DEV_SGPIOM0 + i]); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->sgpiom[i]), 0, + aspeed_soc_ast2700_get_irq(s, ASPEED_DEV_SGPIOM0 + i)); + } + /* RTC */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->rtc), errp)) { return; -- 2.52.0
From: Yubin Zou <yubinz@google.com> This commit introduces a new qtest for the Aspeed SGPIO controller The test covers the following: - Setting and clearing SGPIO output pins and verifying the pin state. - Setting and clearing SGPIO input pins and verifying the pin state. - Verifying that level-high interrupts are correctly triggered and cleared. Signed-off-by: Yubin Zou <yubinz@google.com> Reviewed-by: Kane Chen <kane_chen@aspeedtech.com> Link: https://lore.kernel.org/qemu-devel/20251219-aspeed-sgpio-v5-6-fd5593178144@google.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- tests/qtest/ast2700-sgpio-test.c | 165 +++++++++++++++++++++++++++++++ tests/qtest/meson.build | 1 + 2 files changed, 166 insertions(+) create mode 100644 tests/qtest/ast2700-sgpio-test.c diff --git a/tests/qtest/ast2700-sgpio-test.c b/tests/qtest/ast2700-sgpio-test.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/tests/qtest/ast2700-sgpio-test.c @@ -XXX,XX +XXX,XX @@ +/* + * QTest testcase for the ASPEED AST2700 SGPIO Controller. + * + * SPDX-License-Identifier: GPL-2.0-or-later + * Copyright (C) 2025 Google LLC. + */ + +#include "qemu/osdep.h" +#include "qemu/bitops.h" +#include "qobject/qdict.h" +#include "libqtest-single.h" +#include "hw/core/registerfields.h" +#include "hw/gpio/aspeed_sgpio.h" + +#define AST2700_SGPIO0_BASE 0x14C0C000 +#define AST2700_SGPIO1_BASE 0x14C0D000 + +static void test_output_pins(const char *machine, const uint32_t base, int idx) +{ + QTestState *s = qtest_init(machine); + char name[16]; + char qom_path[64]; + uint32_t offset = 0; + uint32_t value = 0; + for (int i = 0; i < ASPEED_SGPIO_MAX_PIN_PAIR; i++) { + /* Odd index is output port */ + sprintf(name, "sgpio%03d", i * 2 + 1); + sprintf(qom_path, "/machine/soc/sgpio[%d]", idx); + offset = base + (R_SGPIO_0_CONTROL + i) * 4; + /* set serial output */ + qtest_writel(s, offset, 0x00000001); + value = qtest_readl(s, offset); + g_assert_cmphex(SHARED_FIELD_EX32(value, SGPIO_SERIAL_OUT_VAL), ==, 1); + g_assert_cmphex(qtest_qom_get_bool(s, qom_path, name), ==, true); + + /* clear serial output */ + qtest_writel(s, offset, 0x00000000); + value = qtest_readl(s, offset); + g_assert_cmphex(SHARED_FIELD_EX32(value, SGPIO_SERIAL_OUT_VAL), ==, 0); + g_assert_cmphex(qtest_qom_get_bool(s, qom_path, name), ==, false); + } + qtest_quit(s); +} + +static void test_input_pins(const char *machine, const uint32_t base, int idx) +{ + QTestState *s = qtest_init(machine); + char name[16]; + char qom_path[64]; + uint32_t offset = 0; + uint32_t value = 0; + for (int i = 0; i < ASPEED_SGPIO_MAX_PIN_PAIR; i++) { + /* Even index is input port */ + sprintf(name, "sgpio%03d", i * 2); + sprintf(qom_path, "/machine/soc/sgpio[%d]", idx); + offset = base + (R_SGPIO_0_CONTROL + i) * 4; + /* set serial input */ + qtest_qom_set_bool(s, qom_path, name, true); + value = qtest_readl(s, offset); + g_assert_cmphex(SHARED_FIELD_EX32(value, SGPIO_SERIAL_IN_VAL), ==, 1); + g_assert_cmphex(qtest_qom_get_bool(s, qom_path, name), ==, true); + + /* clear serial input */ + qtest_qom_set_bool(s, qom_path, name, false); + value = qtest_readl(s, offset); + g_assert_cmphex(SHARED_FIELD_EX32(value, SGPIO_SERIAL_IN_VAL), ==, 0); + g_assert_cmphex(qtest_qom_get_bool(s, qom_path, name), ==, false); + } + qtest_quit(s); +} + +static void test_irq_level_high(const char *machine, + const uint32_t base, int idx) +{ + QTestState *s = qtest_init(machine); + char name[16]; + char qom_path[64]; + uint32_t ctrl_offset = 0; + uint32_t int_offset = 0; + uint32_t int_reg_idx = 0; + uint32_t int_bit_idx = 0; + uint32_t value = 0; + for (int i = 0; i < ASPEED_SGPIO_MAX_PIN_PAIR; i++) { + /* Even index is input port */ + sprintf(name, "sgpio%03d", i * 2); + sprintf(qom_path, "/machine/soc/sgpio[%d]", idx); + int_reg_idx = i / 32; + int_bit_idx = i % 32; + int_offset = base + (R_SGPIO_INT_STATUS_0 + int_reg_idx) * 4; + ctrl_offset = base + (R_SGPIO_0_CONTROL + i) * 4; + + /* Enable the interrupt */ + value = SHARED_FIELD_DP32(value, SGPIO_INT_EN, 1); + qtest_writel(s, ctrl_offset, value); + + /* Set the interrupt type to level-high trigger */ + value = SHARED_FIELD_DP32(qtest_readl(s, ctrl_offset), + SGPIO_INT_TYPE, 3); + qtest_writel(s, ctrl_offset, value); + + /* Set serial input high */ + qtest_qom_set_bool(s, qom_path, name, true); + value = qtest_readl(s, ctrl_offset); + g_assert_cmphex(SHARED_FIELD_EX32(value, SGPIO_SERIAL_IN_VAL), ==, 1); + + /* Interrupt status is set */ + value = qtest_readl(s, int_offset); + g_assert_cmphex(extract32(value, int_bit_idx, 1), ==, 1); + + /* Clear Interrupt */ + value = SHARED_FIELD_DP32(qtest_readl(s, ctrl_offset), + SGPIO_INT_STATUS, 1); + qtest_writel(s, ctrl_offset, value); + value = qtest_readl(s, int_offset); + g_assert_cmphex(extract32(value, int_bit_idx, 1), ==, 0); + + /* Clear serial input */ + qtest_qom_set_bool(s, qom_path, name, false); + value = qtest_readl(s, ctrl_offset); + g_assert_cmphex(SHARED_FIELD_EX32(value, SGPIO_SERIAL_IN_VAL), ==, 0); + } + qtest_quit(s); +} + +static void test_ast_2700_sgpio_input(void) +{ + test_input_pins("-machine ast2700-evb", + AST2700_SGPIO0_BASE, 0); + test_input_pins("-machine ast2700-evb", + AST2700_SGPIO1_BASE, 1); +} + +static void test_ast_2700_sgpio_output(void) +{ + test_output_pins("-machine ast2700-evb", + AST2700_SGPIO0_BASE, 0); + test_output_pins("-machine ast2700-evb", + AST2700_SGPIO1_BASE, 1); + test_irq_level_high("-machine ast2700-evb", + AST2700_SGPIO0_BASE, 0); + test_irq_level_high("-machine ast2700-evb", + AST2700_SGPIO1_BASE, 1); +} + +static void test_ast_2700_sgpio_irq(void) +{ + test_irq_level_high("-machine ast2700-evb", + AST2700_SGPIO0_BASE, 0); + test_irq_level_high("-machine ast2700-evb", + AST2700_SGPIO1_BASE, 1); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + qtest_add_func("/ast2700/sgpio/ast_2700_sgpio_input", + test_ast_2700_sgpio_input); + qtest_add_func("/ast2700/sgpio/ast_2700_sgpio_output", + test_ast_2700_sgpio_output); + qtest_add_func("/ast2700/sgpio/ast_2700_sgpio_irq", + test_ast_2700_sgpio_irq); + + 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_aspeed = \ qtests_aspeed64 = \ ['ast2700-gpio-test', 'ast2700-hace-test', + 'ast2700-sgpio-test', 'ast2700-smc-test'] qtests_stm32l4x5 = \ -- 2.52.0
Commit [1] moved the FW image of the gb200nvl-bmc machine and broke the associated functional test. Fix that. [1] https://github.com/legoater/qemu-aspeed-boot/commit/52451b2472eeb40aa97e131aeea327e9d4a8a78a Cc: Ed Tanous <etanous@nvidia.com> Cc: Patrick Williams <patrick@stwcx.xyz> Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org> Link: https://lore.kernel.org/qemu-devel/20251222073351.166720-1-clg@redhat.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- tests/functional/arm/test_aspeed_gb200nvl_bmc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/arm/test_aspeed_gb200nvl_bmc.py b/tests/functional/arm/test_aspeed_gb200nvl_bmc.py index XXXXXXX..XXXXXXX 100755 --- a/tests/functional/arm/test_aspeed_gb200nvl_bmc.py +++ b/tests/functional/arm/test_aspeed_gb200nvl_bmc.py @@ -XXX,XX +XXX,XX @@ 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', + 'https://github.com/legoater/qemu-aspeed-boot/raw/refs/heads/master/images/gb200nvl-bmc/openbmc-20250702182348/obmc-phosphor-image-gb200nvl-obmc-20250702182348.static.mtd.xz', 'b84819317cb3dc762895ad507705978ef000bfc77c50c33a63bdd37921db0dbc') def test_arm_aspeed_gb200_openbmc(self): -- 2.52.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/20250901040808.1454742-2-jamin_lin@aspeedtech.com [ clg: Updated docs/about/removed-features.rst ] Signed-off-by: Cédric Le Goater <clg@redhat.com> --- docs/about/deprecated.rst | 8 -------- docs/about/removed-features.rst | 8 ++++++++ hw/arm/aspeed_ast27x0_evb.c | 26 -------------------------- 3 files changed, 8 insertions(+), 34 deletions(-) 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. - Arm ``sonorapass-bmc`` machine (since 10.2) ''''''''''''''''''''''''''''''''''''''''''' diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/about/removed-features.rst +++ b/docs/about/removed-features.rst @@ -XXX,XX +XXX,XX @@ Mips ``mipssim`` machine (removed in 10.2) Linux dropped support for this virtual machine type in kernel v3.7, and there was also no binary available online to use with that board. +Arm ``ast2700a0-evb`` machine (since 11.0) +'''''''''''''''''''''''''''''''''''''''''' + +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. + linux-user mode CPUs -------------------- diff --git a/hw/arm/aspeed_ast27x0_evb.c b/hw/arm/aspeed_ast27x0_evb.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0_evb.c +++ b/hw/arm/aspeed_ast27x0_evb.c @@ -XXX,XX +XXX,XX @@ static void ast2700_evb_i2c_init(AspeedMachineState *bmc) TYPE_TMP105, 0x4d); } -static void aspeed_machine_ast2700a0_evb_class_init(ObjectClass *oc, - const void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); - - mc->desc = "Aspeed AST2700 A0 EVB (Cortex-A35)"; - amc->soc_name = "ast2700-a0"; - amc->hw_strap1 = AST2700_EVB_HW_STRAP1; - amc->hw_strap2 = AST2700_EVB_HW_STRAP2; - amc->fmc_model = "w25q01jvq"; - amc->spi_model = "w25q512jv"; - amc->num_cs = 2; - amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON | ASPEED_MAC2_ON; - amc->uart_default = ASPEED_DEV_UART12; - amc->i2c_init = ast2700_evb_i2c_init; - amc->vbootrom = true; - mc->default_ram_size = 1 * GiB; - aspeed_machine_class_init_cpus_defaults(mc); -} - static void aspeed_machine_ast2700a1_evb_class_init(ObjectClass *oc, const void *data) { @@ -XXX,XX +XXX,XX @@ static void aspeed_machine_ast2700a1_evb_class_init(ObjectClass *oc, static const TypeInfo aspeed_ast27x0_evb_types[] = { { - .name = MACHINE_TYPE_NAME("ast2700a0-evb"), - .parent = TYPE_ASPEED_MACHINE, - .class_init = aspeed_machine_ast2700a0_evb_class_init, - .interfaces = aarch64_machine_interfaces, - }, { .name = MACHINE_TYPE_NAME("ast2700a1-evb"), .parent = TYPE_ASPEED_MACHINE, .class_init = aspeed_machine_ast2700a1_evb_class_init, -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> The ast2700-a1 SOC represented the first revision of the AST2700 and was intended as an early engineering sample rather than a production platform. A newer revision, A1, is now supported, and the ast2700-a1 SOC 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/20250901040808.1454742-3-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast27x0.c | 84 ----------------------------------------- 1 file changed, 84 deletions(-) diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0.c +++ b/hw/arm/aspeed_ast27x0.c @@ -XXX,XX +XXX,XX @@ static const hwaddr aspeed_soc_ast2700_memmap[] = { #define AST2700_MAX_IRQ 256 /* Shared Peripheral Interrupt values below are offset by -32 from datasheet */ -static const int aspeed_soc_ast2700a0_irqmap[] = { - [ASPEED_DEV_SDMC] = 0, - [ASPEED_DEV_HACE] = 4, - [ASPEED_DEV_XDMA] = 5, - [ASPEED_DEV_UART4] = 8, - [ASPEED_DEV_SCU] = 12, - [ASPEED_DEV_RTC] = 13, - [ASPEED_DEV_EMMC] = 15, - [ASPEED_DEV_TIMER1] = 16, - [ASPEED_DEV_TIMER2] = 17, - [ASPEED_DEV_TIMER3] = 18, - [ASPEED_DEV_TIMER4] = 19, - [ASPEED_DEV_TIMER5] = 20, - [ASPEED_DEV_TIMER6] = 21, - [ASPEED_DEV_TIMER7] = 22, - [ASPEED_DEV_TIMER8] = 23, - [ASPEED_DEV_DP] = 28, - [ASPEED_DEV_EHCI1] = 33, - [ASPEED_DEV_EHCI2] = 37, - [ASPEED_DEV_LPC] = 128, - [ASPEED_DEV_IBT] = 128, - [ASPEED_DEV_KCS] = 128, - [ASPEED_DEV_ADC] = 130, - [ASPEED_DEV_GPIO] = 130, - [ASPEED_DEV_SGPIOM0] = 130, - [ASPEED_DEV_SGPIOM1] = 130, - [ASPEED_DEV_I2C] = 130, - [ASPEED_DEV_FMC] = 131, - [ASPEED_DEV_WDT] = 131, - [ASPEED_DEV_PWM] = 131, - [ASPEED_DEV_I3C] = 131, - [ASPEED_DEV_UART0] = 132, - [ASPEED_DEV_UART1] = 132, - [ASPEED_DEV_UART2] = 132, - [ASPEED_DEV_UART3] = 132, - [ASPEED_DEV_UART5] = 132, - [ASPEED_DEV_UART6] = 132, - [ASPEED_DEV_UART7] = 132, - [ASPEED_DEV_UART8] = 132, - [ASPEED_DEV_UART9] = 132, - [ASPEED_DEV_UART10] = 132, - [ASPEED_DEV_UART11] = 132, - [ASPEED_DEV_UART12] = 132, - [ASPEED_DEV_ETH1] = 132, - [ASPEED_DEV_ETH2] = 132, - [ASPEED_DEV_ETH3] = 132, - [ASPEED_DEV_PECI] = 133, - [ASPEED_DEV_SDHCI] = 133, -}; - static const int aspeed_soc_ast2700a1_irqmap[] = { [ASPEED_DEV_SDMC] = 0, [ASPEED_DEV_HACE] = 4, @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp) AST2700_SOC_IOMEM_SIZE); } -static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc, const void *data) -{ - static const char * const valid_cpu_types[] = { - ARM_CPU_TYPE_NAME("cortex-a35"), - NULL - }; - DeviceClass *dc = DEVICE_CLASS(oc); - AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); - - /* Reason: The Aspeed SoC can only be instantiated from a board */ - dc->user_creatable = false; - dc->realize = aspeed_soc_ast2700_realize; - - sc->valid_cpu_types = valid_cpu_types; - sc->silicon_rev = AST2700_A0_SILICON_REV; - sc->sram_size = 0x20000; - sc->pcie_num = 0; - sc->spis_num = 3; - sc->sgpio_num = 2; - sc->ehcis_num = 2; - sc->wdts_num = 8; - sc->macs_num = 1; - sc->uarts_num = 13; - sc->num_cpus = 4; - sc->uarts_base = ASPEED_DEV_UART0; - sc->irqmap = aspeed_soc_ast2700a0_irqmap; - sc->memmap = aspeed_soc_ast2700_memmap; -} - static void aspeed_soc_ast2700a1_class_init(ObjectClass *oc, const void *data) { static const char * const valid_cpu_types[] = { @@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_soc_ast27x0_types[] = { .parent = TYPE_ASPEED_SOC, .instance_size = sizeof(Aspeed27x0SoCState), .abstract = true, - }, { - .name = "ast2700-a0", - .parent = TYPE_ASPEED27X0_SOC, - .instance_init = aspeed_soc_ast2700_init, - .class_init = aspeed_soc_ast2700a0_class_init, }, { .name = "ast2700-a1", -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> The GIC interrupts 128 - 136 were only used by the AST2700 A0 SoC. Since the AST2700 A0 has been deprecated, these interrupt definitions are no longer needed. This commit removes them to clean up the codebase. 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/20250901040808.1454742-4-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast27x0.c | 47 +++++++++---------------------------- hw/intc/aspeed_intc.c | 51 ++--------------------------------------- 2 files changed, 13 insertions(+), 85 deletions(-) diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/aspeed_ast27x0.c +++ b/hw/arm/aspeed_ast27x0.c @@ -XXX,XX +XXX,XX @@ static const int aspeed_soc_ast2700a1_irqmap[] = { [ASPEED_DEV_SDHCI] = 197, }; -/* GICINT 128 */ /* GICINT 192 */ -static const int ast2700_gic128_gic192_intcmap[] = { +static const int ast2700_gic192_intcmap[] = { [ASPEED_DEV_LPC] = 0, [ASPEED_DEV_IBT] = 2, [ASPEED_DEV_KCS] = 4, }; -/* GICINT 129 */ /* GICINT 193 */ -/* GICINT 130 */ /* GICINT 194 */ -static const int ast2700_gic130_gic194_intcmap[] = { +static const int ast2700_gic194_intcmap[] = { [ASPEED_DEV_I2C] = 0, [ASPEED_DEV_ADC] = 16, [ASPEED_DEV_GPIO] = 18, @@ -XXX,XX +XXX,XX @@ static const int ast2700_gic130_gic194_intcmap[] = { [ASPEED_DEV_SGPIOM1] = 24, }; -/* GICINT 131 */ /* GICINT 195 */ -static const int ast2700_gic131_gic195_intcmap[] = { +static const int ast2700_gic195_intcmap[] = { [ASPEED_DEV_I3C] = 0, [ASPEED_DEV_WDT] = 16, [ASPEED_DEV_FMC] = 25, [ASPEED_DEV_PWM] = 29, }; -/* GICINT 132 */ /* GICINT 196 */ -static const int ast2700_gic132_gic196_intcmap[] = { +static const int ast2700_gic196_intcmap[] = { [ASPEED_DEV_ETH1] = 0, [ASPEED_DEV_ETH2] = 1, [ASPEED_DEV_ETH3] = 2, @@ -XXX,XX +XXX,XX @@ static const int ast2700_gic132_gic196_intcmap[] = { [ASPEED_DEV_PCIE2] = 31, }; -/* GICINT 133 */ /* GICINT 197 */ -static const int ast2700_gic133_gic197_intcmap[] = { +static const int ast2700_gic197_intcmap[] = { [ASPEED_DEV_SDHCI] = 1, [ASPEED_DEV_PECI] = 4, }; -/* GICINT 128 ~ 136 */ /* GICINT 192 ~ 201 */ struct gic_intc_irq_info { int irq; @@ -XXX,XX +XXX,XX @@ struct gic_intc_irq_info { }; static const struct gic_intc_irq_info ast2700_gic_intcmap[] = { - {192, 1, 0, ast2700_gic128_gic192_intcmap}, + {192, 1, 0, ast2700_gic192_intcmap}, {193, 1, 1, NULL}, - {194, 1, 2, ast2700_gic130_gic194_intcmap}, - {195, 1, 3, ast2700_gic131_gic195_intcmap}, - {196, 1, 4, ast2700_gic132_gic196_intcmap}, - {197, 1, 5, ast2700_gic133_gic197_intcmap}, + {194, 1, 2, ast2700_gic194_intcmap}, + {195, 1, 3, ast2700_gic195_intcmap}, + {196, 1, 4, ast2700_gic196_intcmap}, + {197, 1, 5, ast2700_gic197_intcmap}, {198, 1, 6, NULL}, {199, 1, 7, NULL}, {200, 1, 8, NULL}, {201, 1, 9, NULL}, - {128, 0, 1, ast2700_gic128_gic192_intcmap}, - {129, 0, 2, NULL}, - {130, 0, 3, ast2700_gic130_gic194_intcmap}, - {131, 0, 4, ast2700_gic131_gic195_intcmap}, - {132, 0, 5, ast2700_gic132_gic196_intcmap}, - {133, 0, 6, ast2700_gic133_gic197_intcmap}, - {134, 0, 7, NULL}, - {135, 0, 8, NULL}, - {136, 0, 9, NULL}, }; static qemu_irq aspeed_soc_ast2700_get_irq(AspeedSoCState *s, int dev) @@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_soc_ast2700_get_irq_index(AspeedSoCState *s, int dev, } /* - * Invalid OR gate index, device IRQ should be between 128 to 136 - * and 192 to 201. + * Invalid OR gate index, device IRQ should be between 192 to 201. */ g_assert_not_reached(); } @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp) } /* INTC -> GIC192 - GIC201 */ - /* INTC -> GIC128 - GIC136 */ for (i = 0; i < ic->num_outpins; i++) { sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc[0]), i, qdev_get_gpio_in(DEVICE(&a->gic), @@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp) /* * The AST2700 I2C controller has one source INTC per bus. * - * For AST2700 A0: - * I2C bus interrupts are connected to the OR gate from bit 0 to bit - * 15, and the OR gate output pin is connected to the input pin of - * GICINT130 of INTC (CPU Die). Then, the output pin is connected to - * the GIC. - * - * For AST2700 A1: * I2C bus interrupts are connected to the OR gate from bit 0 to bit * 15, and the OR gate output pin is connected to the input pin of * GICINT194 of INTCIO (IO Die). Then, the output pin is connected diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/aspeed_intc.c +++ b/hw/intc/aspeed_intc.c @@ -XXX,XX +XXX,XX @@ * because its memory region is start at 0x1000 * */ -REG32(GICINT128_EN, 0x000) -REG32(GICINT128_STATUS, 0x004) -REG32(GICINT129_EN, 0x100) -REG32(GICINT129_STATUS, 0x104) -REG32(GICINT130_EN, 0x200) -REG32(GICINT130_STATUS, 0x204) -REG32(GICINT131_EN, 0x300) -REG32(GICINT131_STATUS, 0x304) -REG32(GICINT132_EN, 0x400) -REG32(GICINT132_STATUS, 0x404) -REG32(GICINT133_EN, 0x500) -REG32(GICINT133_STATUS, 0x504) -REG32(GICINT134_EN, 0x600) -REG32(GICINT134_STATUS, 0x604) -REG32(GICINT135_EN, 0x700) -REG32(GICINT135_STATUS, 0x704) -REG32(GICINT136_EN, 0x800) -REG32(GICINT136_STATUS, 0x804) REG32(GICINT192_201_EN, 0xB00) REG32(GICINT192_201_STATUS, 0xB04) @@ -XXX,XX +XXX,XX @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data, trace_aspeed_intc_write(name, offset, size, data); switch (reg) { - case R_GICINT128_EN: - case R_GICINT129_EN: - case R_GICINT130_EN: - case R_GICINT131_EN: - case R_GICINT132_EN: - case R_GICINT133_EN: - case R_GICINT134_EN: - case R_GICINT135_EN: - case R_GICINT136_EN: case R_GICINT192_201_EN: aspeed_intc_enable_handler(s, offset, data); break; - case R_GICINT128_STATUS: - case R_GICINT129_STATUS: - case R_GICINT130_STATUS: - case R_GICINT131_STATUS: - case R_GICINT132_STATUS: - case R_GICINT133_STATUS: - case R_GICINT134_STATUS: - case R_GICINT135_STATUS: - case R_GICINT136_STATUS: - aspeed_intc_status_handler(s, offset, data); - break; case R_GICINT192_201_STATUS: aspeed_intc_status_handler_multi_outpins(s, offset, data); break; @@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_intc_info = { static AspeedINTCIRQ aspeed_2700_intc_irqs[ASPEED_INTC_MAX_INPINS] = { {0, 0, 10, R_GICINT192_201_EN, R_GICINT192_201_STATUS}, - {1, 10, 1, R_GICINT128_EN, R_GICINT128_STATUS}, - {2, 11, 1, R_GICINT129_EN, R_GICINT129_STATUS}, - {3, 12, 1, R_GICINT130_EN, R_GICINT130_STATUS}, - {4, 13, 1, R_GICINT131_EN, R_GICINT131_STATUS}, - {5, 14, 1, R_GICINT132_EN, R_GICINT132_STATUS}, - {6, 15, 1, R_GICINT133_EN, R_GICINT133_STATUS}, - {7, 16, 1, R_GICINT134_EN, R_GICINT134_STATUS}, - {8, 17, 1, R_GICINT135_EN, R_GICINT135_STATUS}, - {9, 18, 1, R_GICINT136_EN, R_GICINT136_STATUS}, }; static void aspeed_2700_intc_class_init(ObjectClass *klass, const void *data) @@ -XXX,XX +XXX,XX @@ static void aspeed_2700_intc_class_init(ObjectClass *klass, const void *data) dc->desc = "ASPEED 2700 INTC Controller"; aic->num_lines = 32; - aic->num_inpins = 10; - aic->num_outpins = 19; + aic->num_inpins = 1; + aic->num_outpins = 10; aic->mem_size = 0x4000; aic->nr_regs = 0xB08 >> 2; aic->reg_offset = 0x1000; -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> The GIC interrupts 128 - 136 were only used by the AST2700 A0 SoC. Since the AST2700 A0 has been deprecated, these interrupt definitions are no longer needed. This commit removes them to clean up the codebase. 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/20250901040808.1454742-5-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- docs/specs/aspeed-intc.rst | 92 +++++++++++--------------------------- 1 file changed, 25 insertions(+), 67 deletions(-) diff --git a/docs/specs/aspeed-intc.rst b/docs/specs/aspeed-intc.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/specs/aspeed-intc.rst +++ b/docs/specs/aspeed-intc.rst @@ -XXX,XX +XXX,XX @@ Bit GIC 9 201 ==== ==== -AST2700 A0 ----------- -It has only one INTC controller, and currently, only GIC 128-136 is supported. -To support both AST2700 A1 and AST2700 A0, there are 10 OR gates in the INTC, -with gates 1 to 9 supporting GIC 128-136. - -Design for GICINT 132 ---------------------- -The orgate has interrupt sources ranging from 0 to 31, with its output pin -connected to INTC. The output pin is then connected to GIC 132. - -Block Diagram of GICINT 196 for AST2700 A1 and GICINT 132 for AST2700 A0 +Block Diagram of GICINT 196 for AST2700 A1 ------------------------------------------------------------------------ .. code-block:: @@ -XXX,XX +XXX,XX @@ Block Diagram of GICINT 196 for AST2700 A1 and GICINT 132 for AST2700 A0 | To GICINT196 | | | | ETH1 |-----------| |--------------------------| |--------------| | - | -------->|0 | | INTCIO | | orgates[0] | | + | ------->|0 | | INTCIO | | orgates[0] | | | ETH2 | 4| orgates[0]------>|inpin[0]-------->outpin[0]|------->| 0 | | - | -------->|1 5| orgates[1]------>|inpin[1]-------->outpin[1]|------->| 1 | | + | ------->|1 5| orgates[1]------>|inpin[1]-------->outpin[1]|------->| 1 | | | ETH3 | 6| orgates[2]------>|inpin[2]-------->outpin[2]|------->| 2 | | - | -------->|2 19| orgates[3]------>|inpin[3]-------->outpin[3]|------->| 3 OR[0:9] |-----| | + | ------->|2 19| orgates[3]------>|inpin[3]-------->outpin[3]|------->| 3 OR[0:9] |-----| | | UART0 | 20|-->orgates[4]------>|inpin[4]-------->outpin[4]|------->| 4 | | | - | -------->|7 21| orgates[5]------>|inpin[5]-------->outpin[5]|------->| 5 | | | + | ------->|7 21| orgates[5]------>|inpin[5]-------->outpin[5]|------->| 5 | | | | UART1 | 22| orgates[6]------>|inpin[6]-------->outpin[6]|------->| 6 | | | - | -------->|8 23| orgates[7]------>|inpin[7]-------->outpin[7]|------->| 7 | | | + | ------->|8 23| orgates[7]------>|inpin[7]-------->outpin[7]|------->| 7 | | | | UART2 | 24| orgates[8]------>|inpin[8]-------->outpin[8]|------->| 8 | | | - | -------->|9 25| orgates[9]------>|inpin[9]-------->outpin[9]|------->| 9 | | | + | ------->|9 25| orgates[9]------>|inpin[9]-------->outpin[9]|------->| 9 | | | | UART3 | 26| |--------------------------| |--------------| | | - | ---------|10 27| | | + | ------->|10 27| | | | UART5 | 28| | | - | -------->|11 29| | | + | ------->|11 29| | | | UART6 | | | | - | -------->|12 30| |-----------------------------------------------------------------------| | + | ------->|12 30| |-----------------------------------------------------------------------| | | UART7 | 31| | | - | -------->|13 | | | - | UART8 | OR[0:31] | | |------------------------------| |----------| | - | -------->|14 | | | INTC | | GIC | | - | UART9 | | | |inpin[0:0]--------->outpin[0] |---------->|192 | | - | -------->|15 | | |inpin[0:1]--------->outpin[1] |---------->|193 | | - | UART10 | | | |inpin[0:2]--------->outpin[2] |---------->|194 | | - | -------->|16 | | |inpin[0:3]--------->outpin[3] |---------->|195 | | - | UART11 | | |--------------> |inpin[0:4]--------->outpin[4] |---------->|196 | | - | -------->|17 | |inpin[0:5]--------->outpin[5] |---------->|197 | | - | UART12 | | |inpin[0:6]--------->outpin[6] |---------->|198 | | - | -------->|18 | |inpin[0:7]--------->outpin[7] |---------->|199 | | - | |-----------| |inpin[0:8]--------->outpin[8] |---------->|200 | | - | |inpin[0:9]--------->outpin[9] |---------->|201 | | - |-------------------------------------------------------------------------------------------------------| - |-------------------------------------------------------------------------------------------------------| - | ETH1 |-----------| orgates[1]------->|inpin[1]----------->outpin[10]|---------->|128 | | - | -------->|0 | orgates[2]------->|inpin[2]----------->outpin[11]|---------->|129 | | - | ETH2 | 4| orgates[3]------->|inpin[3]----------->outpin[12]|---------->|130 | | - | -------->|1 5| orgates[4]------->|inpin[4]----------->outpin[13]|---------->|131 | | - | ETH3 | 6|---->orgates[5]------->|inpin[5]----------->outpin[14]|---------->|132 | | - | -------->|2 19| orgates[6]------->|inpin[6]----------->outpin[15]|---------->|133 | | - | UART0 | 20| orgates[7]------->|inpin[7]----------->outpin[16]|---------->|134 | | - | -------->|7 21| orgates[8]------->|inpin[8]----------->outpin[17]|---------->|135 | | - | UART1 | 22| orgates[9]------->|inpin[9]----------->outpin[18]|---------->|136 | | - | -------->|8 23| |------------------------------| |----------| | - | UART2 | 24| | - | -------->|9 25| AST2700 A0 Design | - | UART3 | 26| | - | -------->|10 27| | - | UART5 | 28| | - | -------->|11 29| GICINT132 | - | UART6 | | | - | -------->|12 30| | - | UART7 | 31| | - | -------->|13 | | - | UART8 | OR[0:31] | | - | -------->|14 | | - | UART9 | | | - | -------->|15 | | - | UART10 | | | - | -------->|16 | | - | UART11 | | | - | -------->|17 | | - | UART12 | | | - | -------->|18 | | - | |-----------| | + | ------->|13 | | | + | UART8 | OR[0:31] | | |-----------------------------| |----------| | + | ------->|14 | | | INTC | | GIC | | + | UART9 | | | |inpin[0:0]--------->outpin[0]|--------->|192 | | + | ------->|15 | | |inpin[0:1]--------->outpin[1]|--------->|193 | | + | UART10 | | | |inpin[0:2]--------->outpin[2]|--------->|194 | | + | ------->|16 | | |inpin[0:3]--------->outpin[3]|--------->|195 | | + | UART11 | | |--------------> |inpin[0:4]--------->outpin[4]|--------->|196 | | + | ------->|17 | |inpin[0:5]--------->outpin[5]|--------->|197 | | + | UART12 | | |inpin[0:6]--------->outpin[6]|--------->|198 | | + | ------->|18 | |inpin[0:7]--------->outpin[7]|--------->|199 | | + | |-----------| |inpin[0:8]--------->outpin[8]|--------->|200 | | + | |inpin[0:9]--------->outpin[9]|--------->|201 | | + | |-----------------------------| |----------| | + | | | | |-------------------------------------------------------------------------------------------------------| -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> The SSP interrupts 128 - 138 were only used by the AST2700 A0 SoC. Since the AST2700 A0 has been deprecated, these interrupt definitions are no longer needed. This commit removes them to clean up the codebase. 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/20260102090746.1130033-2-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast27x0-ssp.c | 13 ++------- hw/intc/aspeed_intc.c | 55 ++----------------------------------- 2 files changed, 4 insertions(+), 64 deletions(-) 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 int aspeed_soc_ast27x0ssp_irqmap[] = { }; /* SSPINT 164 */ -static const int ast2700_ssp132_ssp164_intcmap[] = { +static const int ast2700_ssp164_intcmap[] = { [ASPEED_DEV_UART0] = 7, [ASPEED_DEV_UART1] = 8, [ASPEED_DEV_UART2] = 9, @@ -XXX,XX +XXX,XX @@ static struct nvic_intc_irq_info ast2700_ssp_intcmap[] = { {161, 1, 1, NULL}, {162, 1, 2, NULL}, {163, 1, 3, NULL}, - {164, 1, 4, ast2700_ssp132_ssp164_intcmap}, + {164, 1, 4, ast2700_ssp164_intcmap}, {165, 1, 5, NULL}, {166, 1, 6, NULL}, {167, 1, 7, NULL}, {168, 1, 8, NULL}, {169, 1, 9, NULL}, - {128, 0, 1, NULL}, - {129, 0, 2, NULL}, - {130, 0, 3, NULL}, - {131, 0, 4, NULL}, - {132, 0, 5, ast2700_ssp132_ssp164_intcmap}, - {133, 0, 6, NULL}, - {134, 0, 7, NULL}, - {135, 0, 8, NULL}, - {136, 0, 9, NULL}, }; static qemu_irq aspeed_soc_ast27x0ssp_get_irq(AspeedCoprocessorState *s, diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/aspeed_intc.c +++ b/hw/intc/aspeed_intc.c @@ -XXX,XX +XXX,XX @@ REG32(GICINT197_STATUS, 0x54) /* * SSP INTC Registers */ -REG32(SSPINT128_EN, 0x2000) -REG32(SSPINT128_STATUS, 0x2004) -REG32(SSPINT129_EN, 0x2100) -REG32(SSPINT129_STATUS, 0x2104) -REG32(SSPINT130_EN, 0x2200) -REG32(SSPINT130_STATUS, 0x2204) -REG32(SSPINT131_EN, 0x2300) -REG32(SSPINT131_STATUS, 0x2304) -REG32(SSPINT132_EN, 0x2400) -REG32(SSPINT132_STATUS, 0x2404) -REG32(SSPINT133_EN, 0x2500) -REG32(SSPINT133_STATUS, 0x2504) -REG32(SSPINT134_EN, 0x2600) -REG32(SSPINT134_STATUS, 0x2604) -REG32(SSPINT135_EN, 0x2700) -REG32(SSPINT135_STATUS, 0x2704) -REG32(SSPINT136_EN, 0x2800) -REG32(SSPINT136_STATUS, 0x2804) -REG32(SSPINT137_EN, 0x2900) -REG32(SSPINT137_STATUS, 0x2904) -REG32(SSPINT138_EN, 0x2A00) -REG32(SSPINT138_STATUS, 0x2A04) REG32(SSPINT160_169_EN, 0x2B00) REG32(SSPINT160_169_STATUS, 0x2B04) @@ -XXX,XX +XXX,XX @@ static void aspeed_ssp_intc_write(void *opaque, hwaddr offset, uint64_t data, trace_aspeed_intc_write(name, offset, size, data); switch (reg) { - case R_SSPINT128_EN: - case R_SSPINT129_EN: - case R_SSPINT130_EN: - case R_SSPINT131_EN: - case R_SSPINT132_EN: - case R_SSPINT133_EN: - case R_SSPINT134_EN: - case R_SSPINT135_EN: - case R_SSPINT136_EN: case R_SSPINT160_169_EN: aspeed_intc_enable_handler(s, offset, data); break; - case R_SSPINT128_STATUS: - case R_SSPINT129_STATUS: - case R_SSPINT130_STATUS: - case R_SSPINT131_STATUS: - case R_SSPINT132_STATUS: - case R_SSPINT133_STATUS: - case R_SSPINT134_STATUS: - case R_SSPINT135_STATUS: - case R_SSPINT136_STATUS: - aspeed_intc_status_handler(s, offset, data); - break; case R_SSPINT160_169_STATUS: aspeed_intc_status_handler_multi_outpins(s, offset, data); break; @@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_2700_intcio_info = { static AspeedINTCIRQ aspeed_2700ssp_intc_irqs[ASPEED_INTC_MAX_INPINS] = { {0, 0, 10, R_SSPINT160_169_EN, R_SSPINT160_169_STATUS}, - {1, 10, 1, R_SSPINT128_EN, R_SSPINT128_STATUS}, - {2, 11, 1, R_SSPINT129_EN, R_SSPINT129_STATUS}, - {3, 12, 1, R_SSPINT130_EN, R_SSPINT130_STATUS}, - {4, 13, 1, R_SSPINT131_EN, R_SSPINT131_STATUS}, - {5, 14, 1, R_SSPINT132_EN, R_SSPINT132_STATUS}, - {6, 15, 1, R_SSPINT133_EN, R_SSPINT133_STATUS}, - {7, 16, 1, R_SSPINT134_EN, R_SSPINT134_STATUS}, - {8, 17, 1, R_SSPINT135_EN, R_SSPINT135_STATUS}, - {9, 18, 1, R_SSPINT136_EN, R_SSPINT136_STATUS}, }; static void aspeed_2700ssp_intc_class_init(ObjectClass *klass, const void *data) @@ -XXX,XX +XXX,XX @@ static void aspeed_2700ssp_intc_class_init(ObjectClass *klass, const void *data) dc->desc = "ASPEED 2700 SSP INTC Controller"; aic->num_lines = 32; - aic->num_inpins = 10; - aic->num_outpins = 19; + aic->num_inpins = 1; + aic->num_outpins = 10; aic->mem_size = 0x4000; aic->nr_regs = 0x2B08 >> 2; aic->reg_offset = 0x0; -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> The SSP interrupts 128 - 138 were only used by the AST2700 A0 SoC. Since the AST2700 A0 has been deprecated, these interrupt definitions are no longer needed. This commit removes them to clean up the codebase. 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/20260102090746.1130033-3-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/arm/aspeed_ast27x0-tsp.c | 13 ++------- hw/intc/aspeed_intc.c | 55 ++----------------------------------- 2 files changed, 4 insertions(+), 64 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 @@ static const int aspeed_soc_ast27x0tsp_irqmap[] = { }; /* TSPINT 164 */ -static const int ast2700_tsp132_tsp164_intcmap[] = { +static const int ast2700_tsp164_intcmap[] = { [ASPEED_DEV_UART0] = 7, [ASPEED_DEV_UART1] = 8, [ASPEED_DEV_UART2] = 9, @@ -XXX,XX +XXX,XX @@ static struct nvic_intc_irq_info ast2700_tsp_intcmap[] = { {161, 1, 1, NULL}, {162, 1, 2, NULL}, {163, 1, 3, NULL}, - {164, 1, 4, ast2700_tsp132_tsp164_intcmap}, + {164, 1, 4, ast2700_tsp164_intcmap}, {165, 1, 5, NULL}, {166, 1, 6, NULL}, {167, 1, 7, NULL}, {168, 1, 8, NULL}, {169, 1, 9, NULL}, - {128, 0, 1, NULL}, - {129, 0, 2, NULL}, - {130, 0, 3, NULL}, - {131, 0, 4, NULL}, - {132, 0, 5, ast2700_tsp132_tsp164_intcmap}, - {133, 0, 6, NULL}, - {134, 0, 7, NULL}, - {135, 0, 8, NULL}, - {136, 0, 9, NULL}, }; static qemu_irq aspeed_soc_ast27x0tsp_get_irq(AspeedCoprocessorState *s, diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/aspeed_intc.c +++ b/hw/intc/aspeed_intc.c @@ -XXX,XX +XXX,XX @@ REG32(SSPINT165_STATUS, 0x1D4) /* * TSP INTC Registers */ -REG32(TSPINT128_EN, 0x3000) -REG32(TSPINT128_STATUS, 0x3004) -REG32(TSPINT129_EN, 0x3100) -REG32(TSPINT129_STATUS, 0x3104) -REG32(TSPINT130_EN, 0x3200) -REG32(TSPINT130_STATUS, 0x3204) -REG32(TSPINT131_EN, 0x3300) -REG32(TSPINT131_STATUS, 0x3304) -REG32(TSPINT132_EN, 0x3400) -REG32(TSPINT132_STATUS, 0x3404) -REG32(TSPINT133_EN, 0x3500) -REG32(TSPINT133_STATUS, 0x3504) -REG32(TSPINT134_EN, 0x3600) -REG32(TSPINT134_STATUS, 0x3604) -REG32(TSPINT135_EN, 0x3700) -REG32(TSPINT135_STATUS, 0x3704) -REG32(TSPINT136_EN, 0x3800) -REG32(TSPINT136_STATUS, 0x3804) -REG32(TSPINT137_EN, 0x3900) -REG32(TSPINT137_STATUS, 0x3904) -REG32(TSPINT138_EN, 0x3A00) -REG32(TSPINT138_STATUS, 0x3A04) REG32(TSPINT160_169_EN, 0x3B00) REG32(TSPINT160_169_STATUS, 0x3B04) @@ -XXX,XX +XXX,XX @@ static void aspeed_tsp_intc_write(void *opaque, hwaddr offset, uint64_t data, trace_aspeed_intc_write(name, offset, size, data); switch (reg) { - case R_TSPINT128_EN: - case R_TSPINT129_EN: - case R_TSPINT130_EN: - case R_TSPINT131_EN: - case R_TSPINT132_EN: - case R_TSPINT133_EN: - case R_TSPINT134_EN: - case R_TSPINT135_EN: - case R_TSPINT136_EN: case R_TSPINT160_169_EN: aspeed_intc_enable_handler(s, offset, data); break; - case R_TSPINT128_STATUS: - case R_TSPINT129_STATUS: - case R_TSPINT130_STATUS: - case R_TSPINT131_STATUS: - case R_TSPINT132_STATUS: - case R_TSPINT133_STATUS: - case R_TSPINT134_STATUS: - case R_TSPINT135_STATUS: - case R_TSPINT136_STATUS: - aspeed_intc_status_handler(s, offset, data); - break; case R_TSPINT160_169_STATUS: aspeed_intc_status_handler_multi_outpins(s, offset, data); break; @@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_2700ssp_intcio_info = { static AspeedINTCIRQ aspeed_2700tsp_intc_irqs[ASPEED_INTC_MAX_INPINS] = { {0, 0, 10, R_TSPINT160_169_EN, R_TSPINT160_169_STATUS}, - {1, 10, 1, R_TSPINT128_EN, R_TSPINT128_STATUS}, - {2, 11, 1, R_TSPINT129_EN, R_TSPINT129_STATUS}, - {3, 12, 1, R_TSPINT130_EN, R_TSPINT130_STATUS}, - {4, 13, 1, R_TSPINT131_EN, R_TSPINT131_STATUS}, - {5, 14, 1, R_TSPINT132_EN, R_TSPINT132_STATUS}, - {6, 15, 1, R_TSPINT133_EN, R_TSPINT133_STATUS}, - {7, 16, 1, R_TSPINT134_EN, R_TSPINT134_STATUS}, - {8, 17, 1, R_TSPINT135_EN, R_TSPINT135_STATUS}, - {9, 18, 1, R_TSPINT136_EN, R_TSPINT136_STATUS}, }; static void aspeed_2700tsp_intc_class_init(ObjectClass *klass, const void *data) @@ -XXX,XX +XXX,XX @@ static void aspeed_2700tsp_intc_class_init(ObjectClass *klass, const void *data) dc->desc = "ASPEED 2700 TSP INTC Controller"; aic->num_lines = 32; - aic->num_inpins = 10; - aic->num_outpins = 19; + aic->num_inpins = 1; + aic->num_outpins = 10; aic->mem_size = 0x4000; aic->nr_regs = 0x3B08 >> 2; aic->reg_offset = 0; -- 2.52.0
From: Jamin Lin <jamin_lin@aspeedtech.com> In the previous design, the I2C model would update I2CC_DMA_LEN (0x54) based on the value of I2CM_DMA_LEN (0x1C) when the firmware set either I2CM_DMA_TX_ADDR (0x30) or I2CM_DMA_RX_ADDR (0x34). However, this only worked correctly if the firmware set I2CM_DMA_LEN before setting I2CM_DMA_TX_ADDR or I2CM_DMA_RX_ADDR. If the firmware instead set I2CM_DMA_TX_ADDR or I2CM_DMA_RX_ADDR before setting I2CM_DMA_LEN, the value written to I2CC_DMA_LEN would be incorrect. To fix this issue, the model should be updated to set I2CC_DMA_LEN when the firmware writes to the I2CM_DMA_LEN register, rather than when it writes to the I2CM_DMA_RX_ADDR and I2CM_DMA_TX_ADDR registers. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Fixes: ba2cccd64e90 ("aspeed: i2c: Add new mode support") Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20260102090746.1130033-4-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com> --- hw/i2c/aspeed_i2c.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c index XXXXXXX..XXXXXXX 100644 --- a/hw/i2c/aspeed_i2c.c +++ b/hw/i2c/aspeed_i2c.c @@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset, bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32, FIELD_EX32(value, I2CM_DMA_TX_ADDR, ADDR)); - bus->regs[R_I2CC_DMA_LEN] = ARRAY_FIELD_EX32(bus->regs, I2CM_DMA_LEN, - TX_BUF_LEN) + 1; break; case A_I2CM_DMA_RX_ADDR: bus->regs[R_I2CM_DMA_RX_ADDR] = FIELD_EX32(value, I2CM_DMA_RX_ADDR, @@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset, bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32, FIELD_EX32(value, I2CM_DMA_RX_ADDR, ADDR)); - bus->regs[R_I2CC_DMA_LEN] = ARRAY_FIELD_EX32(bus->regs, I2CM_DMA_LEN, - RX_BUF_LEN) + 1; break; case A_I2CM_DMA_LEN: w1t = FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN_W1T) || @@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset, if (FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN_W1T)) { ARRAY_FIELD_DP32(bus->regs, I2CM_DMA_LEN, RX_BUF_LEN, FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN)); + bus->regs[R_I2CC_DMA_LEN] = ARRAY_FIELD_EX32(bus->regs, + I2CM_DMA_LEN, + RX_BUF_LEN) + 1; } if (FIELD_EX32(value, I2CM_DMA_LEN, TX_BUF_LEN_W1T)) { ARRAY_FIELD_DP32(bus->regs, I2CM_DMA_LEN, TX_BUF_LEN, FIELD_EX32(value, I2CM_DMA_LEN, TX_BUF_LEN)); + bus->regs[R_I2CC_DMA_LEN] = ARRAY_FIELD_EX32(bus->regs, + I2CM_DMA_LEN, + TX_BUF_LEN) + 1; } break; case A_I2CM_DMA_LEN_STS: -- 2.52.0