diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst index ac31a2bce4..7abb3dab59 100644 --- a/docs/about/deprecated.rst +++ b/docs/about/deprecated.rst @@ -280,14 +280,6 @@ 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 422b9c98d3..e81d79da47 100644 --- a/docs/about/removed-features.rst +++ b/docs/about/removed-features.rst @@ -1136,6 +1136,14 @@ 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/docs/specs/aspeed-intc.rst b/docs/specs/aspeed-intc.rst index 9cefd7f37f..892a74a0c3 100644 --- a/docs/specs/aspeed-intc.rst +++ b/docs/specs/aspeed-intc.rst @@ -47,18 +47,7 @@ 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:: @@ -68,69 +57,38 @@ 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 | | + | |-----------------------------| |----------| | + | | | | |-------------------------------------------------------------------------------------------------------| diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst index 6317c0e910..4fa1739cb5 100644 --- a/docs/system/arm/aspeed.rst +++ b/docs/system/arm/aspeed.rst @@ -1,5 +1,5 @@ -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 @@ -274,8 +274,8 @@ 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 : @@ -448,23 +448,24 @@ 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 @@ -492,6 +493,8 @@ Missing devices * Virtual UART * eSPI Controller * I3C Controller + * SMBus Filter Controller + * QSPI Monitor Controller Boot options ------------ @@ -507,4 +510,4 @@ 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 diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c index f923b9505b..41a4e82c1f 100644 --- a/hw/arm/aspeed_ast10x0.c +++ b/hw/arm/aspeed_ast10x0.c @@ -36,7 +36,7 @@ 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, @@ -94,7 +94,7 @@ 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, }; @@ -107,19 +107,14 @@ 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, 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); @@ -150,10 +145,6 @@ 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++) { @@ -185,10 +176,35 @@ static void aspeed_soc_ast1030_init(Object *obj) TYPE_UNIMPLEMENTED_DEVICE); } -static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) +static void aspeed_soc_ast1030_init(Object *obj) { - Aspeed10x0SoCState *a = ASPEED10X0_SOC(dev_soc); - AspeedSoCState *s = ASPEED_SOC(dev_soc); + AspeedSoCState *s = ASPEED_SOC(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); +} + +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); AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); DeviceState *armv7m; Error *err = NULL; @@ -198,7 +214,7 @@ 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 */ @@ -211,7 +227,7 @@ 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", @@ -227,7 +243,7 @@ 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], @@ -236,14 +252,14 @@ 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]); @@ -253,7 +269,7 @@ 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]); @@ -266,7 +282,7 @@ 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]); @@ -277,50 +293,11 @@ 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)); @@ -330,7 +307,7 @@ 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]); @@ -341,7 +318,7 @@ 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]); @@ -352,7 +329,7 @@ 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]); @@ -366,7 +343,7 @@ 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]); @@ -378,7 +355,7 @@ 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]); @@ -387,7 +364,7 @@ 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]); @@ -402,14 +379,14 @@ 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]); @@ -429,7 +406,7 @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, 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", @@ -437,6 +414,67 @@ 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_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) @@ -467,6 +505,32 @@ 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, @@ -478,7 +542,12 @@ 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) diff --git a/hw/arm/aspeed_ast10x0_evb.c b/hw/arm/aspeed_ast10x0_evb.c index 329578a542..c19563d1f0 100644 --- a/hw/arm/aspeed_ast10x0_evb.c +++ b/hw/arm/aspeed_ast10x0_evb.c @@ -96,12 +96,35 @@ 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, } }; diff --git a/hw/arm/aspeed_ast2600_catalina.c b/hw/arm/aspeed_ast2600_catalina.c index 91977a4d3c..4edb30bb16 100644 --- a/hw/arm/aspeed_ast2600_catalina.c +++ b/hw/arm/aspeed_ast2600_catalina.c @@ -26,6 +26,437 @@ #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); + +/* + * "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); + +/* + * "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); + +/* + * 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); + +/* + * "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); + +/* + * 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); + +/* + * 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); + +/* + * 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); + +/* + * 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); + +/* + * 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); + +/* + * 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 */ @@ -51,7 +482,8 @@ 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); @@ -67,7 +499,8 @@ 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); @@ -89,7 +522,8 @@ 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); @@ -101,11 +535,13 @@ 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 */ - 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); @@ -126,7 +562,8 @@ 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 */ @@ -145,32 +582,36 @@ 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(i2c[9], 0x56, 8 * KiB); + at24c_eeprom_init_rom(i2c[9], 0x56, 8 * KiB, bsm_eeprom, bsm_eeprom_len); /* &i2c10 */ /* 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 */ /* &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); + /* eeprom@54 */ + at24c_eeprom_init_rom(i2c[12], 0x54, 256, + cable_eeprom, cable_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 */ - 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(i2c[13], 0x57, 256); + at24c_eeprom_init_rom(i2c[13], 0x57, 256, hmc_eeprom, hmc_eeprom_len); /* &i2c14 */ /* io_expander9 - pca9555@10 */ @@ -190,7 +631,7 @@ 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, diff --git a/hw/arm/aspeed_ast27x0-ssp.c b/hw/arm/aspeed_ast27x0-ssp.c index 04d3705659..cee937b37e 100644 --- a/hw/arm/aspeed_ast27x0-ssp.c +++ b/hw/arm/aspeed_ast27x0-ssp.c @@ -62,7 +62,7 @@ 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, @@ -89,21 +89,12 @@ 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/arm/aspeed_ast27x0-tsp.c b/hw/arm/aspeed_ast27x0-tsp.c index f40c70fea5..9c11c016ca 100644 --- a/hw/arm/aspeed_ast27x0-tsp.c +++ b/hw/arm/aspeed_ast27x0-tsp.c @@ -62,7 +62,7 @@ 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, @@ -89,21 +89,12 @@ 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/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index 95f155fcf1..d17f446661 100644 --- a/hw/arm/aspeed_ast27x0.c +++ b/hw/arm/aspeed_ast27x0.c @@ -69,6 +69,8 @@ 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, @@ -98,54 +100,6 @@ 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_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, @@ -173,6 +127,8 @@ 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, @@ -197,37 +153,34 @@ 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, + [ASPEED_DEV_SGPIOM0] = 21, + [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, @@ -248,14 +201,12 @@ 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; @@ -265,25 +216,16 @@ 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) @@ -327,8 +269,7 @@ 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(); } @@ -511,6 +452,11 @@ 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); @@ -738,7 +684,6 @@ 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), @@ -938,13 +883,6 @@ 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 @@ -967,6 +905,17 @@ 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; @@ -1045,34 +994,6 @@ 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->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[] = { @@ -1091,6 +1012,7 @@ 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; @@ -1107,11 +1029,6 @@ 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", diff --git a/hw/arm/aspeed_ast27x0_evb.c b/hw/arm/aspeed_ast27x0_evb.c index 0c4e9cd9cd..31f7d61117 100644 --- a/hw/arm/aspeed_ast27x0_evb.c +++ b/hw/arm/aspeed_ast27x0_evb.c @@ -28,27 +28,6 @@ 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) { @@ -73,11 +52,6 @@ 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, diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index 4a758f83dc..b8a2543c0b 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -364,6 +364,8 @@ 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 a03a291a09..87878c2bf0 100644 --- a/hw/block/m25p80_sfdp.c +++ b/hw/block/m25p80_sfdp.c @@ -440,6 +440,42 @@ 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) */ diff --git a/hw/block/m25p80_sfdp.h b/hw/block/m25p80_sfdp.h index 35785686a0..c1e532de5a 100644 --- a/hw/block/m25p80_sfdp.h +++ b/hw/block/m25p80_sfdp.h @@ -27,6 +27,7 @@ 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/gpio/aspeed_sgpio.c b/hw/gpio/aspeed_sgpio.c new file mode 100644 index 0000000000..0c53b03464 --- /dev/null +++ b/hw/gpio/aspeed_sgpio.c @@ -0,0 +1,346 @@ +/* + * 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/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) +{ + 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; + } + aspeed_sgpio_update(s, 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_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); + 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 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; + } + aspeed_sgpio_update(s, 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, + .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_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); + + 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, + .instance_init = aspeed_sgpio_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 74840619c0..6a67ee958f 100644 --- a/hw/gpio/meson.build +++ b/hw/gpio/meson.build @@ -16,5 +16,6 @@ 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')) diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c index faf2160c06..1b8ac561c3 100644 --- a/hw/i2c/aspeed_i2c.c +++ b/hw/i2c/aspeed_i2c.c @@ -656,8 +656,6 @@ 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, @@ -665,8 +663,6 @@ 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) || @@ -679,10 +675,16 @@ 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: diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index f14c340b60..77fae39205 100644 --- a/hw/intc/aspeed_intc.c +++ b/hw/intc/aspeed_intc.c @@ -21,24 +21,6 @@ * 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) @@ -65,28 +47,6 @@ 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) @@ -109,28 +69,6 @@ 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) @@ -507,29 +445,9 @@ 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; @@ -549,29 +467,9 @@ 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; @@ -591,29 +489,9 @@ 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; @@ -891,15 +769,6 @@ 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) @@ -909,8 +778,8 @@ 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; @@ -958,15 +827,6 @@ 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) @@ -976,8 +836,8 @@ 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; @@ -1027,15 +887,6 @@ 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) @@ -1045,8 +896,8 @@ 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; diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c index d27e0c7f91..6829efa2dc 100644 --- a/hw/misc/aspeed_scu.c +++ b/hw/misc/aspeed_scu.c @@ -565,6 +565,7 @@ 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, @@ -841,7 +842,7 @@ 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; @@ -1137,7 +1138,7 @@ 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; diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h index 4b8e599f1a..18ff961a38 100644 --- a/include/hw/arm/aspeed_soc.h +++ b/include/hw/arm/aspeed_soc.h @@ -32,6 +32,7 @@ #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" @@ -46,6 +47,7 @@ #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 @@ -89,6 +91,7 @@ struct AspeedSoCState { AspeedMiiState mii[ASPEED_MACS_NUM]; AspeedGPIOState gpio; AspeedGPIOState gpio_1_8v; + AspeedSGPIOState sgpiom[ASPEED_SGPIO_NUM]; AspeedSDHCIState sdhci; AspeedSDHCIState emmc; AspeedLPCState lpc; @@ -106,7 +109,6 @@ struct AspeedSoCState { UnimplementedDeviceState pwm; UnimplementedDeviceState espi; UnimplementedDeviceState udc; - UnimplementedDeviceState sgpiom; UnimplementedDeviceState ltpi; UnimplementedDeviceState jtag[ASPEED_JTAG_NUM]; AspeedAPB2OPBState fsi[2]; @@ -166,6 +168,7 @@ struct AspeedSoCClass { uint64_t secsram_size; int pcie_num; int spis_num; + int sgpio_num; int ehcis_num; int wdts_num; int macs_num; @@ -221,6 +224,8 @@ 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, @@ -263,7 +268,6 @@ 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/include/hw/gpio/aspeed_sgpio.h b/include/hw/gpio/aspeed_sgpio.h new file mode 100644 index 0000000000..68276baf81 --- /dev/null +++ b/include/hw/gpio/aspeed_sgpio.h @@ -0,0 +1,68 @@ +/* + * 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 { + /* */ + SysBusDevice parent; + + /*< 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]; +}; + +#endif /* ASPEED_SGPIO_H */ diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h index 35b841960a..9e28bd4d2e 100644 --- a/include/hw/misc/aspeed_scu.h +++ b/include/hw/misc/aspeed_scu.h @@ -51,6 +51,7 @@ 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/tests/functional/arm/meson.build b/tests/functional/arm/meson.build index d1ed076a6a..1762a49604 100644 --- a/tests/functional/arm/meson.build +++ b/tests/functional/arm/meson.build @@ -28,6 +28,7 @@ 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 0000000000..034efa5342 --- /dev/null +++ b/tests/functional/arm/test_aspeed_ast1060.py @@ -0,0 +1,52 @@ +#!/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() diff --git a/tests/functional/arm/test_aspeed_gb200nvl_bmc.py b/tests/functional/arm/test_aspeed_gb200nvl_bmc.py index 8e8e3f05c1..e5f2dce0f5 100755 --- a/tests/functional/arm/test_aspeed_gb200nvl_bmc.py +++ b/tests/functional/arm/test_aspeed_gb200nvl_bmc.py @@ -11,7 +11,7 @@ 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', + '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): diff --git a/tests/qtest/ast2700-sgpio-test.c b/tests/qtest/ast2700-sgpio-test.c new file mode 100644 index 0000000000..56c54cca9b --- /dev/null +++ b/tests/qtest/ast2700-sgpio-test.c @@ -0,0 +1,165 @@ +/* + * 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 08fba9695b..0f053fb56d 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -221,6 +221,7 @@ qtests_aspeed = \ qtests_aspeed64 = \ ['ast2700-gpio-test', 'ast2700-hace-test', + 'ast2700-sgpio-test', 'ast2700-smc-test'] qtests_stm32l4x5 = \