Re: [PATCH v3 18/18] hw/arm/aspeed: Model AST1700 I3C block as unimplemented device
On 12/8/25 19:23, Nabih Estefan wrote: On Sun, Dec 7, 2025 at 11:47 PM Kane Chen via wrote: From: Kane-Chen-AS AST1700 exposes more I3C buses than the current dummy I3C model provides. When Linux probes the I3C devices on AST1700 this mismatch can trigger a kernel panic. Model the I3C block as an unimplemented device to make the missing functionality explicit and avoid unexpected side effects. This wires up the I3C interrupt lines for the IO expanders and adds the corresponding device entries for the AST1700 model. No functional I3C emulation is provided yet; this only prevents crashes and documents the missing piece. Would you be able to help review Joe Komlodi's I3C support patchset (link below)? I think it probably fills in this gap. yes. I have been keeping Joe's series in my tree for a while now. It looks saneand it would be great if someone could dedicate some time to the review. Can we make this a target for QEMU 11.0 ? Thanks, C.
Re: [PATCH v3 18/18] hw/arm/aspeed: Model AST1700 I3C block as unimplemented device
On Sun, Dec 7, 2025 at 11:47 PM Kane Chen via wrote:
>
> From: Kane-Chen-AS
>
> AST1700 exposes more I3C buses than the current dummy I3C model
> provides. When Linux probes the I3C devices on AST1700 this mismatch
> can trigger a kernel panic. Model the I3C block as an unimplemented
> device to make the missing functionality explicit and avoid unexpected
> side effects.
>
> This wires up the I3C interrupt lines for the IO expanders and adds the
> corresponding device entries for the AST1700 model.
>
> No functional I3C emulation is provided yet; this only prevents crashes and
> documents the missing piece.
Would you be able to help review Joe Komlodi's I3C support patchset
(link below)?
I think it probably fills in this gap.
(We don't need to block this submission on that landing though)
https://lists.gnu.org/archive/html/qemu-arm/2025-06/msg00403.html
>
> Signed-off-by: Kane-Chen-AS
> ---
> include/hw/arm/aspeed_ast1700.h | 3 +++
> include/hw/arm/aspeed_soc.h | 2 ++
> hw/arm/aspeed_ast1700.c | 17 +
> hw/arm/aspeed_ast27x0.c | 18 --
> 4 files changed, 38 insertions(+), 2 deletions(-)
>
> diff --git a/include/hw/arm/aspeed_ast1700.h b/include/hw/arm/aspeed_ast1700.h
> index 490f2a3b05..874b4d63fe 100644
> --- a/include/hw/arm/aspeed_ast1700.h
> +++ b/include/hw/arm/aspeed_ast1700.h
> @@ -19,6 +19,7 @@
> #include "hw/ssi/aspeed_smc.h"
> #include "hw/watchdog/wdt_aspeed.h"
> #include "hw/char/serial-mm.h"
> +#include "hw/misc/unimp.h"
>
> #define AST1700_SGPIO_NUM2
> #define AST1700_WDT_NUM 9
> @@ -45,6 +46,8 @@ struct AspeedAST1700SoCState {
> AspeedI2CState i2c;
> AspeedPWMState pwm;
> AspeedWDTState wdt[AST1700_WDT_NUM];
> +
> +UnimplementedDeviceState i3c;
> };
>
> #endif /* ASPEED_AST1700_H */
> diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
> index 602ce3924d..4207887d0f 100644
> --- a/include/hw/arm/aspeed_soc.h
> +++ b/include/hw/arm/aspeed_soc.h
> @@ -294,6 +294,8 @@ enum {
> ASPEED_DEV_IOEXP1_I2C,
> ASPEED_DEV_IOEXP0_INTCIO,
> ASPEED_DEV_IOEXP1_INTCIO,
> +ASPEED_DEV_IOEXP0_I3C,
> +ASPEED_DEV_IOEXP1_I3C,
> };
>
> const char *aspeed_soc_cpu_type(const char * const *valid_cpu_types);
> diff --git a/hw/arm/aspeed_ast1700.c b/hw/arm/aspeed_ast1700.c
> index e027ae02ad..67ff278241 100644
> --- a/hw/arm/aspeed_ast1700.c
> +++ b/hw/arm/aspeed_ast1700.c
> @@ -15,6 +15,7 @@
>
> #define AST2700_SOC_LTPI_SIZE0x0100
> #define AST1700_SOC_SRAM_SIZE0x0004
> +#define AST1700_SOC_I3C_SIZE 0x0001
>
> enum {
> ASPEED_AST1700_DEV_SPI0,
> @@ -26,6 +27,7 @@ enum {
> ASPEED_AST1700_DEV_SGPIOM0,
> ASPEED_AST1700_DEV_SGPIOM1,
> ASPEED_AST1700_DEV_I2C,
> +ASPEED_AST1700_DEV_I3C,
> ASPEED_AST1700_DEV_UART12,
> ASPEED_AST1700_DEV_LTPI_CTRL,
> ASPEED_AST1700_DEV_WDT,
> @@ -42,6 +44,7 @@ static const hwaddr aspeed_ast1700_io_memmap[] = {
> [ASPEED_AST1700_DEV_SGPIOM0] = 0x00C0C000,
> [ASPEED_AST1700_DEV_SGPIOM1] = 0x00C0D000,
> [ASPEED_AST1700_DEV_I2C] = 0x00C0F000,
> +[ASPEED_AST1700_DEV_I3C] = 0x00C2,
> [ASPEED_AST1700_DEV_UART12]= 0x00C33B00,
> [ASPEED_AST1700_DEV_LTPI_CTRL] = 0x00C34000,
> [ASPEED_AST1700_DEV_WDT] = 0x00C37000,
> @@ -171,6 +174,15 @@ static void aspeed_ast1700_realize(DeviceState *dev,
> Error **errp)
> wdt_offset,
> sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->wdt[i]),
> 0));
> }
> +
> +/* I3C */
> +qdev_prop_set_string(DEVICE(&s->i3c), "name", "ioexp-i3c");
> +qdev_prop_set_uint64(DEVICE(&s->i3c), "size", AST1700_SOC_I3C_SIZE);
> +sysbus_realize(SYS_BUS_DEVICE(&s->i3c), errp);
> +memory_region_add_subregion_overlap(&s->iomem,
> +aspeed_ast1700_io_memmap[ASPEED_AST1700_DEV_I3C],
> +sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->i3c), 0),
> +-1000);
> }
>
> static void aspeed_ast1700_instance_init(Object *obj)
> @@ -219,6 +231,11 @@ static void aspeed_ast1700_instance_init(Object *obj)
> object_initialize_child(obj, "ioexp-wdt[*]",
> &s->wdt[i], "aspeed.wdt-ast2700");
> }
> +
> +/* I3C */
> +object_initialize_child(obj, "ioexp-i3c[*]", &s->i3c,
> +TYPE_UNIMPLEMENTED_DEVICE);
> +
> return;
> }
>
> diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
> index 7433d365a3..5604a5b8e4 100644
> --- a/hw/arm/aspeed_ast27x0.c
> +++ b/hw/arm/aspeed_ast27x0.c
> @@ -206,7 +206,9 @@ static const int aspeed_soc_ast2700a1_irqmap[] = {
> [ASPEED_DEV_PECI] = 197,
> [ASPEED_DEV_SDHCI] = 197,
> [ASPEED_DEV_IOEXP0_I2C] = 198,
> +[ASPEED_DEV_IOEXP0_I3C] = 199,
> [ASPEED_DEV_IOEXP1_I2C] = 200,
> +[ASPEED_DEV_IOEXP1_I3C] = 201,
> };
>
> /* GICINT
[PATCH v3 18/18] hw/arm/aspeed: Model AST1700 I3C block as unimplemented device
From: Kane-Chen-AS
AST1700 exposes more I3C buses than the current dummy I3C model
provides. When Linux probes the I3C devices on AST1700 this mismatch
can trigger a kernel panic. Model the I3C block as an unimplemented
device to make the missing functionality explicit and avoid unexpected
side effects.
This wires up the I3C interrupt lines for the IO expanders and adds the
corresponding device entries for the AST1700 model.
No functional I3C emulation is provided yet; this only prevents crashes and
documents the missing piece.
Signed-off-by: Kane-Chen-AS
---
include/hw/arm/aspeed_ast1700.h | 3 +++
include/hw/arm/aspeed_soc.h | 2 ++
hw/arm/aspeed_ast1700.c | 17 +
hw/arm/aspeed_ast27x0.c | 18 --
4 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/include/hw/arm/aspeed_ast1700.h b/include/hw/arm/aspeed_ast1700.h
index 490f2a3b05..874b4d63fe 100644
--- a/include/hw/arm/aspeed_ast1700.h
+++ b/include/hw/arm/aspeed_ast1700.h
@@ -19,6 +19,7 @@
#include "hw/ssi/aspeed_smc.h"
#include "hw/watchdog/wdt_aspeed.h"
#include "hw/char/serial-mm.h"
+#include "hw/misc/unimp.h"
#define AST1700_SGPIO_NUM2
#define AST1700_WDT_NUM 9
@@ -45,6 +46,8 @@ struct AspeedAST1700SoCState {
AspeedI2CState i2c;
AspeedPWMState pwm;
AspeedWDTState wdt[AST1700_WDT_NUM];
+
+UnimplementedDeviceState i3c;
};
#endif /* ASPEED_AST1700_H */
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
index 602ce3924d..4207887d0f 100644
--- a/include/hw/arm/aspeed_soc.h
+++ b/include/hw/arm/aspeed_soc.h
@@ -294,6 +294,8 @@ enum {
ASPEED_DEV_IOEXP1_I2C,
ASPEED_DEV_IOEXP0_INTCIO,
ASPEED_DEV_IOEXP1_INTCIO,
+ASPEED_DEV_IOEXP0_I3C,
+ASPEED_DEV_IOEXP1_I3C,
};
const char *aspeed_soc_cpu_type(const char * const *valid_cpu_types);
diff --git a/hw/arm/aspeed_ast1700.c b/hw/arm/aspeed_ast1700.c
index e027ae02ad..67ff278241 100644
--- a/hw/arm/aspeed_ast1700.c
+++ b/hw/arm/aspeed_ast1700.c
@@ -15,6 +15,7 @@
#define AST2700_SOC_LTPI_SIZE0x0100
#define AST1700_SOC_SRAM_SIZE0x0004
+#define AST1700_SOC_I3C_SIZE 0x0001
enum {
ASPEED_AST1700_DEV_SPI0,
@@ -26,6 +27,7 @@ enum {
ASPEED_AST1700_DEV_SGPIOM0,
ASPEED_AST1700_DEV_SGPIOM1,
ASPEED_AST1700_DEV_I2C,
+ASPEED_AST1700_DEV_I3C,
ASPEED_AST1700_DEV_UART12,
ASPEED_AST1700_DEV_LTPI_CTRL,
ASPEED_AST1700_DEV_WDT,
@@ -42,6 +44,7 @@ static const hwaddr aspeed_ast1700_io_memmap[] = {
[ASPEED_AST1700_DEV_SGPIOM0] = 0x00C0C000,
[ASPEED_AST1700_DEV_SGPIOM1] = 0x00C0D000,
[ASPEED_AST1700_DEV_I2C] = 0x00C0F000,
+[ASPEED_AST1700_DEV_I3C] = 0x00C2,
[ASPEED_AST1700_DEV_UART12]= 0x00C33B00,
[ASPEED_AST1700_DEV_LTPI_CTRL] = 0x00C34000,
[ASPEED_AST1700_DEV_WDT] = 0x00C37000,
@@ -171,6 +174,15 @@ static void aspeed_ast1700_realize(DeviceState *dev, Error
**errp)
wdt_offset,
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->wdt[i]), 0));
}
+
+/* I3C */
+qdev_prop_set_string(DEVICE(&s->i3c), "name", "ioexp-i3c");
+qdev_prop_set_uint64(DEVICE(&s->i3c), "size", AST1700_SOC_I3C_SIZE);
+sysbus_realize(SYS_BUS_DEVICE(&s->i3c), errp);
+memory_region_add_subregion_overlap(&s->iomem,
+aspeed_ast1700_io_memmap[ASPEED_AST1700_DEV_I3C],
+sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->i3c), 0),
+-1000);
}
static void aspeed_ast1700_instance_init(Object *obj)
@@ -219,6 +231,11 @@ static void aspeed_ast1700_instance_init(Object *obj)
object_initialize_child(obj, "ioexp-wdt[*]",
&s->wdt[i], "aspeed.wdt-ast2700");
}
+
+/* I3C */
+object_initialize_child(obj, "ioexp-i3c[*]", &s->i3c,
+TYPE_UNIMPLEMENTED_DEVICE);
+
return;
}
diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c
index 7433d365a3..5604a5b8e4 100644
--- a/hw/arm/aspeed_ast27x0.c
+++ b/hw/arm/aspeed_ast27x0.c
@@ -206,7 +206,9 @@ static const int aspeed_soc_ast2700a1_irqmap[] = {
[ASPEED_DEV_PECI] = 197,
[ASPEED_DEV_SDHCI] = 197,
[ASPEED_DEV_IOEXP0_I2C] = 198,
+[ASPEED_DEV_IOEXP0_I3C] = 199,
[ASPEED_DEV_IOEXP1_I2C] = 200,
+[ASPEED_DEV_IOEXP1_I3C] = 201,
};
/* GICINT 128 */
@@ -275,12 +277,24 @@ static const int ast2700_gic198_intcmap[] = {
[ASPEED_DEV_IOEXP0_I2C] = 0, /* 0 - 15 */
};
+/* Primary AST1700 Interrupts */
+/* A1: GINTC 199 */
+static const int ast2700_gic199_intcmap[] = {
+[ASPEED_DEV_IOEXP0_I3C] = 0, /* 0 - 15 */
+};
+
/* Secondary AST1700 Interrupts */
/* A1: GINTC 200 */
static const int ast2700_gic200_intcmap[] = {
[ASPEED_DEV_IOEXP1_I2C] = 0, /* 0 - 15 */
};
+/* Secondary AST1700 Interrupts */
+/* A1: GINTC 201 */
+static const int ast2700_gic2
