Browse Source

aspeed queue:

* Removed the ast2700-a0 SoC and ast2700a0-evb machine.
 * Added SGPIO support to the ast2700 SoC, including unit tests.
 * Added several FRU EEPROMs to the Catalina board.
 * Added support for the new AST1060 SoC and ast1060-evb machine,
   including functional tests.
 * Fixed the silicon revision ID register for AST2600 and AST1030 SoCs.
 * Added an SFDP table for a Winbond flash chip.
 * Updated documentation for Aspeed boards.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmlbtGMACgkQUaNDx8/7
 7KGtVBAAgiCDME1oXrc+ZVmYn8RtRsx/lakp4prbqRbs6A8qoITk3ao6WjNd2k3P
 kOkvB/xQCqRDSSJIpp8BQhUzDet80b8KUz16iTw1m7KubMIqapmOxVkGJqSc9kGT
 PfLVjB60rHqiCkInNaaMXxMQuY0iAFKS+SDM8mCGaay0MXdvsEIi+XIcxv2TX0Jo
 tnHMaJxtSKfzY3QiM7yeB+WryzOlzQ7IMqRkai9tCN1y3XyDy8PodelZFCIGXw/N
 tw04Z3q/LhmxT6kjvYLmeTETne+1k69gfME+7JhB1hPSrIgdIqM9qyXCROb0U8/W
 5mJDkm84blHc4QWITdewiyhIGps9ITxqlIelCExPL1GpEubSg5BVkqFbIjMv+6HJ
 2XcBbP+rG6IdEpxeT+PcHw5HvOfLjMY6kGrawpK4s2id5jI9GSSyNY5k576tqRzg
 P10GfeKUDNDj1nYhUfOmzL6qXb9TqIyQtOVJVGcHkaASnXIqFvL6rYQHcttFej08
 YepKqvYBBSwsb2TdSb1t6VKTgCublFUD4jdhph3iqVmfQRl3ei8WJHFKCt8aQ235
 HqXzcmBDoTFYqJ97SAg1bvydhVL+rDpd//gcPqVw2cwMnTa2S3zvgI6xj1oBTEf8
 YiRPtFYJ03Y9baNZRdGdYAErxIdiliZh+OYfaEFNNn5Zuqp6tYQ=
 =64bG
 -----END PGP SIGNATURE-----

Merge tag 'pull-aspeed-20260105' of https://github.com/legoater/qemu into staging

aspeed queue:

* Removed the ast2700-a0 SoC and ast2700a0-evb machine.
* Added SGPIO support to the ast2700 SoC, including unit tests.
* Added several FRU EEPROMs to the Catalina board.
* Added support for the new AST1060 SoC and ast1060-evb machine,
  including functional tests.
* Fixed the silicon revision ID register for AST2600 and AST1030 SoCs.
* Added an SFDP table for a Winbond flash chip.
* Updated documentation for Aspeed boards.

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAmlbtGMACgkQUaNDx8/7
# 7KGtVBAAgiCDME1oXrc+ZVmYn8RtRsx/lakp4prbqRbs6A8qoITk3ao6WjNd2k3P
# kOkvB/xQCqRDSSJIpp8BQhUzDet80b8KUz16iTw1m7KubMIqapmOxVkGJqSc9kGT
# PfLVjB60rHqiCkInNaaMXxMQuY0iAFKS+SDM8mCGaay0MXdvsEIi+XIcxv2TX0Jo
# tnHMaJxtSKfzY3QiM7yeB+WryzOlzQ7IMqRkai9tCN1y3XyDy8PodelZFCIGXw/N
# tw04Z3q/LhmxT6kjvYLmeTETne+1k69gfME+7JhB1hPSrIgdIqM9qyXCROb0U8/W
# 5mJDkm84blHc4QWITdewiyhIGps9ITxqlIelCExPL1GpEubSg5BVkqFbIjMv+6HJ
# 2XcBbP+rG6IdEpxeT+PcHw5HvOfLjMY6kGrawpK4s2id5jI9GSSyNY5k576tqRzg
# P10GfeKUDNDj1nYhUfOmzL6qXb9TqIyQtOVJVGcHkaASnXIqFvL6rYQHcttFej08
# YepKqvYBBSwsb2TdSb1t6VKTgCublFUD4jdhph3iqVmfQRl3ei8WJHFKCt8aQ235
# HqXzcmBDoTFYqJ97SAg1bvydhVL+rDpd//gcPqVw2cwMnTa2S3zvgI6xj1oBTEf8
# YiRPtFYJ03Y9baNZRdGdYAErxIdiliZh+OYfaEFNNn5Zuqp6tYQ=
# =64bG
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 05 Jan 2026 11:53:55 PM AEDT
# gpg:                using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1
# gpg: Good signature from "Cédric Le Goater <clg@redhat.com>" [full]
# gpg:                 aka "Cédric Le Goater <clg@kaod.org>" [full]

* tag 'pull-aspeed-20260105' of https://github.com/legoater/qemu: (36 commits)
  hw/i2c/aspeed: Fix wrong I2CC_DMA_LEN when I2CM_DMA_TX/RX_ADDR set first
  hw/intc/aspeed: Remove TSP 128 - 138
  hw/intc/aspeed: Remove SSP 128 - 138
  docs/specs/aspeed-intc: Remove GIC 128 - 136
  hw/intc/aspeed: Remove GIC 128 - 136
  hw/arm/aspeed_ast27x0: Remove ast2700-a0 SOC
  hw/arm: Remove ast2700a0-evb machine
  tests/functional: Fix URL of gb200nvl-bmc image
  test/qtest: Add Unit test for Aspeed SGPIO
  hw/arm/aspeed_ast27x0: Wire SGPIO controller to AST2700 SoC
  hw/arm/aspeed_soc: Update Aspeed SoC to support two SGPIO controllers
  hw/gpio/aspeed_sgpio: Implement SGPIO interrupt handling
  hw/gpio/aspeed_sgpio: Add QOM property accessors for SGPIO pins
  hw/gpio/aspeed_sgpio: Add basic device model for Aspeed SGPIO
  hw/arm/aspeed: catalina: add Cable Cartridge FRU EEPROM
  hw/arm/aspeed: catalina: add NIC FRU EEPROM
  hw/arm/aspeed: catalina: add HMC FRU EEPROM
  hw/arm/aspeed: catalina: add GB200-IO FRU EEPROM
  hw/arm/aspeed: catalina: add GB200 FRU EEPROM
  hw/arm/aspeed: catalina: add HDD FRU EEPROM
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
pull/316/head
Richard Henderson 3 months ago
parent
commit
0fc482b73d
  1. 8
      docs/about/deprecated.rst
  2. 8
      docs/about/removed-features.rst
  3. 92
      docs/specs/aspeed-intc.rst
  4. 27
      docs/system/arm/aspeed.rst
  5. 213
      hw/arm/aspeed_ast10x0.c
  6. 23
      hw/arm/aspeed_ast10x0_evb.c
  7. 473
      hw/arm/aspeed_ast2600_catalina.c
  8. 13
      hw/arm/aspeed_ast27x0-ssp.c
  9. 13
      hw/arm/aspeed_ast27x0-tsp.c
  10. 151
      hw/arm/aspeed_ast27x0.c
  11. 26
      hw/arm/aspeed_ast27x0_evb.c
  12. 2
      hw/block/m25p80.c
  13. 36
      hw/block/m25p80_sfdp.c
  14. 1
      hw/block/m25p80_sfdp.h
  15. 346
      hw/gpio/aspeed_sgpio.c
  16. 1
      hw/gpio/meson.build
  17. 10
      hw/i2c/aspeed_i2c.c
  18. 161
      hw/intc/aspeed_intc.c
  19. 5
      hw/misc/aspeed_scu.c
  20. 8
      include/hw/arm/aspeed_soc.h
  21. 68
      include/hw/gpio/aspeed_sgpio.h
  22. 1
      include/hw/misc/aspeed_scu.h
  23. 1
      tests/functional/arm/meson.build
  24. 52
      tests/functional/arm/test_aspeed_ast1060.py
  25. 2
      tests/functional/arm/test_aspeed_gb200nvl_bmc.py
  26. 165
      tests/qtest/ast2700-sgpio-test.c
  27. 1
      tests/qtest/meson.build

8
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)
'''''''''''''''''''''''''''''''''''''''''''

8
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
--------------------

92
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 | |
| |-----------------------------| |----------| |
| |
| |
|-------------------------------------------------------------------------------------------------------|

27
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

213
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)

23
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,
}
};

473
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,

13
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,

13
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,

151
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",

26
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,

2
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) },

36
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)
*/

1
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);

346
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);

1
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'))

10
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:

161
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;

5
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;

8
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,

68
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 {
/* <private> */
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 */

1
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

1
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',

52
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()

2
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):

165
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();
}

1
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 = \

Loading…
Cancel
Save