Add a machine for the Facebook Minerva Chassis Management Module (BMC),
an AST2600-based board modelled from its device tree
(aspeed-bmc-facebook-minerva.dts).

The board uses INA230 and INA238 power monitors, TMP75 temperature
sensors, PCA9555 IO expanders, PCA9545 and PCA9548 I2C muxes, AT24C
EEPROMs and a DS1339 RTC.

Every device the Minerva device tree describes and QEMU already models
is instantiated. The remaining ones (LTC4287, XDP710, MAX31790, PCF8563
and IPMB) have no QEMU model and are left documented as comments.

Signed-off-by: Emmanuel Blot <[email protected]>
---
 docs/system/arm/aspeed.rst      |   1 +
 hw/arm/aspeed_ast2600_minerva.c | 180 ++++++++++++++++++++++++++++++++++++++++
 hw/arm/meson.build              |   1 +
 3 files changed, 182 insertions(+)

diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
index f38f33cbe1..bbd3d9cdf4 100644
--- a/docs/system/arm/aspeed.rst
+++ b/docs/system/arm/aspeed.rst
@@ -36,6 +36,7 @@ AST2600 SoC based machines :
 - ``catalina-bmc``         Facebook Catalina BMC
 - ``sanmiguel-bmc``        Facebook SanMiguel BMC
 - ``anacapa-bmc``          Facebook Anacapa BMC
+- ``minerva-bmc``          Facebook Minerva BMC
 - ``gb200nvl-bmc``         Nvidia GB200nvl BMC
 
 Supported devices
diff --git a/hw/arm/aspeed_ast2600_minerva.c b/hw/arm/aspeed_ast2600_minerva.c
new file mode 100644
index 0000000000..1f46ac7d58
--- /dev/null
+++ b/hw/arm/aspeed_ast2600_minerva.c
@@ -0,0 +1,180 @@
+/*
+ * Facebook Minerva Chassis Management Module
+ *
+ * Copyright (c) 2026 Meta Platforms, Inc. and affiliates.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/arm/aspeed.h"
+#include "hw/arm/aspeed_soc.h"
+#include "hw/i2c/i2c_mux_pca954x.h"
+#include "hw/gpio/pca9552.h"
+#include "hw/nvram/eeprom_at24c.h"
+#include "hw/rtc/ds1338.h"
+#include "hw/sensor/ina230.h"
+#include "hw/sensor/ina238.h"
+#include "hw/sensor/tmp105.h"
+
+/*
+ * Minerva hardware values.
+ */
+#define MINERVA_BMC_HW_STRAP1 0x00002002
+#define MINERVA_BMC_HW_STRAP2 0x00000800
+#define MINERVA_BMC_RAM_SIZE ASPEED_RAM_SIZE(2 * GiB)
+
+/*
+ * Fan Controller Board (FCB).  The Minerva BMC device tree describes six
+ * identical FCBs, each hanging off one channel of the PCA9548 on i2c2.
+ */
+static void minerva_fcb_i2c_init(I2CBus *bus)
+{
+    /* eeprom@50 - atmel,24c128 */
+    at24c_eeprom_init(bus, 0x50, 16 * KiB);
+    /* pwm@5e - maxim,max31790 (no model) */
+    /* power-sensor@40/41/44/45 - ti,ina238 */
+    i2c_slave_create_simple(bus, TYPE_INA238, 0x40);
+    i2c_slave_create_simple(bus, TYPE_INA238, 0x41);
+    i2c_slave_create_simple(bus, TYPE_INA238, 0x44);
+    i2c_slave_create_simple(bus, TYPE_INA238, 0x45);
+    /* temperature-sensor@4b - tmp75 */
+    i2c_slave_create_simple(bus, TYPE_TMP75, 0x4b);
+    /* gpio@11/12/13/17 - pca9555 */
+    i2c_slave_create_simple(bus, TYPE_PCA9555, 0x11);
+    i2c_slave_create_simple(bus, TYPE_PCA9555, 0x12);
+    i2c_slave_create_simple(bus, TYPE_PCA9555, 0x13);
+    i2c_slave_create_simple(bus, TYPE_PCA9555, 0x17);
+}
+
+static void minerva_pca9545_eeprom_init(I2CBus *bus, uint8_t addr,
+                                        unsigned neeprom)
+{
+    I2CSlave *i2c_mux = i2c_slave_create_simple(bus, TYPE_PCA9545, addr);
+
+    for (unsigned idx = 0; idx < neeprom; idx++) {
+        at24c_eeprom_init(pca954x_i2c_get_bus(i2c_mux, idx), 0x50, 8 * KiB);
+    }
+}
+
+static void minerva_bmc_i2c_init(AspeedMachineState *bmc)
+{
+    /* Reference: aspeed-bmc-facebook-minerva.dts */
+
+    AspeedSoCState *soc = bmc->soc;
+    I2CBus *i2c[16] = {};
+    I2CSlave *i2c_mux;
+
+    for (unsigned idx = 0; idx < ARRAY_SIZE(i2c); idx++) {
+        i2c[idx] = aspeed_i2c_get_bus(&soc->i2c, idx);
+    }
+
+    /* &i2c0 */
+    /* power-monitor@40/41 - ti,ina230 */
+    i2c_slave_create_simple(i2c[0], TYPE_INA230, 0x40);
+    i2c_slave_create_simple(i2c[0], TYPE_INA230, 0x41);
+    /* power-monitor@44 - lltc,ltc4287 (no model) */
+    /* power-monitor@43 - infineon,xdp710 (no model) */
+    /* leds_gpio: gpio@19 - pca9555 */
+    i2c_slave_create_simple(i2c[0], TYPE_PCA9555, 0x19);
+    /* gpio@11/12/13 - pca9555 */
+    i2c_slave_create_simple(i2c[0], TYPE_PCA9555, 0x11);
+    i2c_slave_create_simple(i2c[0], TYPE_PCA9555, 0x12);
+    i2c_slave_create_simple(i2c[0], TYPE_PCA9555, 0x13);
+
+    /* &i2c1 */
+    /* temperature-sensor@4b/4f - tmp75 */
+    i2c_slave_create_simple(i2c[1], TYPE_TMP75, 0x4b);
+    i2c_slave_create_simple(i2c[1], TYPE_TMP75, 0x4f);
+    /* eeprom@54 - atmel,24c128 */
+    at24c_eeprom_init(i2c[1], 0x54, 16 * KiB);
+
+    /* &i2c2 */
+    /* i2c-mux@77 (PCA9548) - six Fan Controller Boards */
+    i2c_mux = i2c_slave_create_simple(i2c[2], TYPE_PCA9548, 0x77);
+    /* FCB 1 - imux16 (channel 1) */
+    minerva_fcb_i2c_init(pca954x_i2c_get_bus(i2c_mux, 1));
+    /* FCB 2 - imux17 (channel 0) */
+    minerva_fcb_i2c_init(pca954x_i2c_get_bus(i2c_mux, 0));
+    /* FCB 3 - imux18 (channel 3) */
+    minerva_fcb_i2c_init(pca954x_i2c_get_bus(i2c_mux, 3));
+    /* FCB 4 - imux19 (channel 2) */
+    minerva_fcb_i2c_init(pca954x_i2c_get_bus(i2c_mux, 2));
+    /* FCB 5 - imux20 (channel 4) */
+    minerva_fcb_i2c_init(pca954x_i2c_get_bus(i2c_mux, 4));
+    /* FCB 6 - imux21 (channel 5) */
+    minerva_fcb_i2c_init(pca954x_i2c_get_bus(i2c_mux, 5));
+    /* imux22/imux23 (channels 6/7) - empty */
+
+    /* &i2c3 */
+    /* i2c-mux@72 (PCA9545) - imux24-27, eeprom@50 on each channel */
+    minerva_pca9545_eeprom_init(i2c[3], 0x72, 4);
+
+    /* &i2c4 */
+    /* i2c-mux@72 (PCA9545) - imux28-31, eeprom@50 on each channel */
+    minerva_pca9545_eeprom_init(i2c[4], 0x72, 4);
+
+    /* &i2c5 */
+    /* i2c-mux@72 (PCA9545) - imux32-35, eeprom@50 on each channel */
+    minerva_pca9545_eeprom_init(i2c[5], 0x72, 4);
+
+    /* &i2c6 */
+    /* i2c-mux@72 (PCA9545) - imux36-39, eeprom@50 on each channel */
+    minerva_pca9545_eeprom_init(i2c[6], 0x72, 4);
+
+    /* &i2c7 - empty */
+    /* &i2c8 - empty */
+
+    /* &i2c9 */
+    /* eeprom@50 - atmel,24c64 */
+    at24c_eeprom_init(i2c[9], 0x50, 8 * KiB);
+    /* rtc@51 - nxp,pcf8563 (no model) */
+    /* rtc@68 - dallas,ds1339 */
+    i2c_slave_create_simple(i2c[9], TYPE_DS1339, 0x68);
+
+    /* &i2c12 */
+    /* i2c-mux@70 (PCA9545) - imux40-42 eeprom@50, imux43 empty */
+    minerva_pca9545_eeprom_init(i2c[12], 0x70, 3);
+
+    /* &i2c13 */
+    /* i2c-mux@70 (PCA9545) - imux44-46 eeprom@50, imux47 empty */
+    minerva_pca9545_eeprom_init(i2c[13], 0x70, 3);
+
+    /* &i2c14 */
+    /* ipmb@10 - ipmb-dev (no model) */
+
+    /* &i2c15 */
+    /* eeprom@50 - atmel,24c128 */
+    at24c_eeprom_init(i2c[15], 0x50, 16 * KiB);
+    /* eeprom@56 - atmel,24c64 */
+    at24c_eeprom_init(i2c[15], 0x56, 8 * KiB);
+}
+
+static void aspeed_machine_minerva_class_init(ObjectClass *oc,
+                                              const void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+
+    mc->desc       = "Facebook Minerva BMC (Cortex-A7)";
+    amc->soc_name  = "ast2600-a3";
+    amc->hw_strap1 = MINERVA_BMC_HW_STRAP1;
+    amc->hw_strap2 = MINERVA_BMC_HW_STRAP2;
+    amc->fmc_model = "mx66l1g45g";
+    amc->spi_model = NULL;
+    amc->num_cs    = 2;
+    amc->macs_mask = ASPEED_MAC3_ON;
+    amc->i2c_init  = minerva_bmc_i2c_init;
+    mc->default_ram_size = MINERVA_BMC_RAM_SIZE;
+    aspeed_machine_class_init_cpus_defaults(mc);
+}
+
+static const TypeInfo aspeed_ast2600_minerva_types[] = {
+    {
+        .name          = MACHINE_TYPE_NAME("minerva-bmc"),
+        .parent        = TYPE_ASPEED_MACHINE,
+        .class_init    = aspeed_machine_minerva_class_init,
+    }
+};
+
+DEFINE_TYPES(aspeed_ast2600_minerva_types)
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index bcc068de04..a9e8270b85 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -63,6 +63,7 @@ arm_common_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
   'aspeed_ast2600_fby35.c',
   'aspeed_ast2600_fuji.c',
   'aspeed_ast2600_gb200nvl.c',
+  'aspeed_ast2600_minerva.c',
   'aspeed_ast2600_rainier.c',
   'aspeed_ast2600_sanmiguel.c',
   'aspeed_ast10x0.c',

-- 
2.50.1


Reply via email to