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 <kane_chen@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Nabih Estefan <nabihestefan@google.com>
Tested-by: Nabih Estefan <nabihestefan@google.com>
Link: https://lore.kernel.org/qemu-devel/20260204082113.3955407-19-kane_chen@aspeedtech.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
#define AST2700_SOC_LTPI_SIZE 0x01000000
#define AST1700_SOC_SRAM_SIZE 0x00040000
+#define AST1700_SOC_I3C_SIZE 0x00010000
enum {
ASPEED_AST1700_DEV_SPI0,
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,
[ASPEED_AST1700_DEV_SGPIOM0] = 0x00C0C000,
[ASPEED_AST1700_DEV_SGPIOM1] = 0x00C0D000,
[ASPEED_AST1700_DEV_I2C] = 0x00C0F000,
+ [ASPEED_AST1700_DEV_I3C] = 0x00C20000,
[ASPEED_AST1700_DEV_UART12] = 0x00C33B00,
[ASPEED_AST1700_DEV_LTPI_CTRL] = 0x00C34000,
[ASPEED_AST1700_DEV_WDT] = 0x00C37000,
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)
&s->wdt[i], "aspeed.wdt-ast2700");
}
+ /* I3C */
+ object_initialize_child(obj, "ioexp-i3c", &s->i3c,
+ TYPE_UNIMPLEMENTED_DEVICE);
+
return;
}
[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 192 */
[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_gic201_intcmap[] = {
+ [ASPEED_DEV_IOEXP1_I3C] = 0, /* 0 - 15 */
+};
+
/* GICINT 192 ~ 201 */
struct gic_intc_irq_info {
int irq;
{196, 1, 4, ast2700_gic196_intcmap},
{197, 1, 5, ast2700_gic197_intcmap},
{198, 2, 0, ast2700_gic198_intcmap},
- {199, 1, 7, NULL},
+ {199, 2, 1, ast2700_gic199_intcmap},
{200, 3, 0, ast2700_gic200_intcmap},
- {201, 1, 9, NULL},
+ {201, 3, 1, ast2700_gic201_intcmap},
};
static qemu_irq aspeed_soc_ast2700_get_irq(AspeedSoCState *s, int dev)
#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_NUM 2
#define AST1700_WDT_NUM 9
AspeedI2CState i2c;
AspeedPWMState pwm;
AspeedWDTState wdt[AST1700_WDT_NUM];
+
+ UnimplementedDeviceState i3c;
};
#endif /* ASPEED_AST1700_H */
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);