* [PATCH v2 00/10] hw/arm/aspeed: Add AST1040 peripheral support
@ 2026-06-02 5:28 Jamin Lin
2026-06-02 5:28 ` [PATCH v2 01/10] hw/i2c/aspeed_i2c: Introduce dma_addr_lo_mask to unify DMA address handling Jamin Lin
` (9 more replies)
0 siblings, 10 replies; 19+ messages in thread
From: Jamin Lin @ 2026-06-02 5:28 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Kane Chen, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Jamin Lin, Troy Lee
This series extends the AST1040 SoC model by adding support for several
peripherals that are compatible with existing AST2700 controller models.
The AST1040 shares a number of peripheral IP blocks with the AST2700,
allowing the existing QEMU models to be reused with minimal changes.
This series adds support for ADC, PECI, GPIO, SGPIO, I2C, and watchdog
controllers, and updates the AST1040 EVB machine to instantiate onboard
I2C devices for validation.
For I2C support, a new AST1040 I2C type is introduced. The model
inherits the AST2700 I2C architecture, including DMA support and
64-bit DMA address registers, while constraining DMA accesses to the
16 MiB HyperRAM address space available on AST1040.
Depends on:
https://github.com/legoater/qemu.git (branch: aspeed-next)
v1:
1. Support ADC, GPIO, SGPIO, I2C and PECI
v2:
1. Address review feedback.
2. Fix issues reported during review.
Jamin Lin (10):
hw/i2c/aspeed_i2c: Introduce dma_addr_lo_mask to unify DMA address
handling
hw/i2c/aspeed_i2c: Increase AST2700 buffer mode size and adjust offset
hw/arm/aspeed_ast1040: Reuse AST2700 ADC model
hw/arm/aspeed_ast1040: Introduce PECI support
hw/arm/aspeed_ast1040: Reuse AST2700 GPIO controller model
hw/arm/aspeed_ast1040: Add SGPIO controller support
hw/i2c/aspeed_i2c: Introduce AST1040 I2C model
hw/arm/aspeed_ast1040: Introduce I2C support
hw/arm/aspeed_ast1040_evb: Introduce onboard I2C device
hw/arm/aspeed_ast1040: Reuse AST2700 watchdog models
include/hw/i2c/aspeed_i2c.h | 8 ++-
hw/arm/aspeed_ast1040.c | 97 +++++++++++++++++++++++++++++-----
hw/arm/aspeed_ast1040_evb.c | 18 +++++++
hw/i2c/aspeed_i2c.c | 101 ++++++++++++++++++++++++------------
4 files changed, 175 insertions(+), 49 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 01/10] hw/i2c/aspeed_i2c: Introduce dma_addr_lo_mask to unify DMA address handling
2026-06-02 5:28 [PATCH v2 00/10] hw/arm/aspeed: Add AST1040 peripheral support Jamin Lin
@ 2026-06-02 5:28 ` Jamin Lin
2026-06-02 6:26 ` Cédric Le Goater
2026-06-02 5:28 ` [PATCH v2 02/10] hw/i2c/aspeed_i2c: Increase AST2700 buffer mode size and adjust offset Jamin Lin
` (8 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Jamin Lin @ 2026-06-02 5:28 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Kane Chen, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Jamin Lin, Troy Lee
The Aspeed I2C controller has two register layouts.
The AST2500 uses the old mode with a single DMA address register (I2CD_DMA_ADDR)
where the address is 4-byte aligned and masked to 0x3ffffffc.
From AST2600 onwards, the new mode provides separate master TX/RX and slave RX DMA
address registers (I2CM_DMA_TX_ADDR, I2CM_DMA_RX_ADDR, I2CS_DMA_RX_ADDR)
with different address widths per SoC:
AST2600 (new mode): 0x7fffffff - bits[30:0]
AST1030 (new mode): 0x7fffffff - bits[30:0]
AST1060 (new mode): 0x7fffffff - bits[30:0]
AST2700 (new mode): 0xffffffff - bits[31:0]
Introduce dma_addr_lo_mask as a per-class attribute and apply it
uniformly when storing DMA address register writes and when loading
the address into dma_dram_offset for both master and slave paths.
This replaces the previous FIELD_EX32 extractions (which incorrectly
stripped bit 31 on AST2700) and the hardcoded 0x3ffffffc literal in
the old-mode path.
Fixes: 1809ab6a67359e0876981cd05d2a50b2843eabad ("hw/i2c/aspeed: Add AST2700 support")
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
include/hw/i2c/aspeed_i2c.h | 5 +----
hw/i2c/aspeed_i2c.c | 22 +++++++++++++---------
2 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
index d42cb4865a..1fc229f699 100644
--- a/include/hw/i2c/aspeed_i2c.h
+++ b/include/hw/i2c/aspeed_i2c.h
@@ -209,13 +209,9 @@ REG32(I2CS_DMA_LEN, 0x2c)
FIELD(I2CS_DMA_LEN, TX_BUF_LEN_W1T, 15, 1)
FIELD(I2CS_DMA_LEN, TX_BUF_LEN, 0, 11)
REG32(I2CM_DMA_TX_ADDR, 0x30)
- FIELD(I2CM_DMA_TX_ADDR, ADDR, 0, 31)
REG32(I2CM_DMA_RX_ADDR, 0x34)
- FIELD(I2CM_DMA_RX_ADDR, ADDR, 0, 31)
REG32(I2CS_DMA_TX_ADDR, 0x38)
- FIELD(I2CS_DMA_TX_ADDR, ADDR, 0, 31)
REG32(I2CS_DMA_RX_ADDR, 0x3c)
- FIELD(I2CS_DMA_RX_ADDR, ADDR, 0, 31)
REG32(I2CS_DEV_ADDR, 0x40)
REG32(I2CM_DMA_LEN_STS, 0x48)
FIELD(I2CM_DMA_LEN_STS, RX_LEN, 16, 13)
@@ -303,6 +299,7 @@ struct AspeedI2CClass {
bool has_share_pool;
uint64_t mem_size;
bool has_dma64;
+ uint32_t dma_addr_lo_mask;
};
static inline bool aspeed_i2c_is_new_mode(AspeedI2CState *s)
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
index 4a6732a185..a6b44174f5 100644
--- a/hw/i2c/aspeed_i2c.c
+++ b/hw/i2c/aspeed_i2c.c
@@ -236,7 +236,7 @@ static void aspeed_i2c_set_tx_dma_dram_offset(AspeedI2CBus *bus)
value = bus->regs[R_I2CM_DMA_TX_ADDR];
bus->dma_dram_offset =
deposit64(bus->dma_dram_offset, 0, 32,
- FIELD_EX32(value, I2CM_DMA_TX_ADDR, ADDR));
+ value & aic->dma_addr_lo_mask);
if (aic->has_dma64) {
value = bus->regs[R_I2CM_DMA_TX_ADDR_HI];
bus->dma_dram_offset =
@@ -246,7 +246,7 @@ static void aspeed_i2c_set_tx_dma_dram_offset(AspeedI2CBus *bus)
} else {
value = bus->regs[R_I2CD_DMA_ADDR];
bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32,
- value & 0x3ffffffc);
+ value & aic->dma_addr_lo_mask);
}
}
@@ -261,7 +261,7 @@ static void aspeed_i2c_set_rx_dma_dram_offset(AspeedI2CBus *bus)
value = bus->regs[R_I2CM_DMA_RX_ADDR];
bus->dma_dram_offset =
deposit64(bus->dma_dram_offset, 0, 32,
- FIELD_EX32(value, I2CM_DMA_RX_ADDR, ADDR));
+ value & aic->dma_addr_lo_mask);
if (aic->has_dma64) {
value = bus->regs[R_I2CM_DMA_RX_ADDR_HI];
bus->dma_dram_offset =
@@ -271,7 +271,7 @@ static void aspeed_i2c_set_rx_dma_dram_offset(AspeedI2CBus *bus)
} else {
value = bus->regs[R_I2CD_DMA_ADDR];
bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32,
- value & 0x3ffffffc);
+ value & aic->dma_addr_lo_mask);
}
}
@@ -735,12 +735,10 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
aspeed_i2c_bus_raise_interrupt(bus);
break;
case A_I2CM_DMA_TX_ADDR:
- bus->regs[R_I2CM_DMA_TX_ADDR] = FIELD_EX32(value, I2CM_DMA_TX_ADDR,
- ADDR);
+ bus->regs[R_I2CM_DMA_TX_ADDR] = value & aic->dma_addr_lo_mask;
break;
case A_I2CM_DMA_RX_ADDR:
- bus->regs[R_I2CM_DMA_RX_ADDR] = FIELD_EX32(value, I2CM_DMA_RX_ADDR,
- ADDR);
+ bus->regs[R_I2CM_DMA_RX_ADDR] = value & aic->dma_addr_lo_mask;
break;
case A_I2CM_DMA_LEN:
w1t = FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN_W1T) ||
@@ -1375,6 +1373,8 @@ static void aspeed_i2c_class_init(ObjectClass *klass, const void *data)
static int aspeed_i2c_bus_new_slave_event(AspeedI2CBus *bus,
enum i2c_event event)
{
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
+
switch (event) {
case I2C_START_SEND_ASYNC:
if (!SHARED_ARRAY_FIELD_EX32(bus->regs, R_I2CS_CMD, RX_DMA_EN)) {
@@ -1385,7 +1385,7 @@ static int aspeed_i2c_bus_new_slave_event(AspeedI2CBus *bus,
ARRAY_FIELD_DP32(bus->regs, I2CS_DMA_LEN_STS, RX_LEN, 0);
bus->dma_dram_offset =
deposit64(bus->dma_dram_offset, 0, 32,
- ARRAY_FIELD_EX32(bus->regs, I2CS_DMA_RX_ADDR, ADDR));
+ bus->regs[R_I2CS_DMA_RX_ADDR] & aic->dma_addr_lo_mask);
bus->regs[R_I2CC_DMA_LEN] =
ARRAY_FIELD_EX32(bus->regs, I2CS_DMA_LEN, RX_BUF_LEN) + 1;
i2c_ack(bus->bus);
@@ -1608,6 +1608,7 @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, const void *data)
aic->check_sram = true;
aic->has_dma = true;
aic->mem_size = 0x1000;
+ aic->dma_addr_lo_mask = 0x3ffffffc;
}
static qemu_irq aspeed_2600_i2c_bus_get_irq(AspeedI2CBus *bus)
@@ -1631,6 +1632,7 @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, const void *data)
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
aic->has_dma = true;
aic->mem_size = 0x1000;
+ aic->dma_addr_lo_mask = 0x7fffffff;
}
static void aspeed_1030_i2c_class_init(ObjectClass *klass, const void *data)
@@ -1649,6 +1651,7 @@ static void aspeed_1030_i2c_class_init(ObjectClass *klass, const void *data)
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
aic->has_dma = true;
aic->mem_size = 0x10000;
+ aic->dma_addr_lo_mask = 0x7fffffff;
}
static void aspeed_2700_i2c_class_init(ObjectClass *klass, const void *data)
@@ -1670,6 +1673,7 @@ static void aspeed_2700_i2c_class_init(ObjectClass *klass, const void *data)
aic->has_dma = true;
aic->mem_size = 0x2000;
aic->has_dma64 = true;
+ aic->dma_addr_lo_mask = 0xffffffff;
}
static const TypeInfo aspeed_i2c_types[] = {
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 02/10] hw/i2c/aspeed_i2c: Increase AST2700 buffer mode size and adjust offset
2026-06-02 5:28 [PATCH v2 00/10] hw/arm/aspeed: Add AST1040 peripheral support Jamin Lin
2026-06-02 5:28 ` [PATCH v2 01/10] hw/i2c/aspeed_i2c: Introduce dma_addr_lo_mask to unify DMA address handling Jamin Lin
@ 2026-06-02 5:28 ` Jamin Lin
2026-06-02 6:33 ` Cédric Le Goater
2026-06-02 5:28 ` [PATCH v2 03/10] hw/arm/aspeed_ast1040: Reuse AST2700 ADC model Jamin Lin
` (7 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Jamin Lin @ 2026-06-02 5:28 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Kane Chen, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Jamin Lin, Troy Lee
Update the AST2700 I2C buffer mode configuration to match
the latest firmware definition:
- Increase buffer mode pool size from 0x20 to 0x40
- Adjust buffer mode base offset to 0x1c0
Since the buffer mode region size changes, the migration state
layout is also modified. Bump the VMState version numbers to
prevent incompatible migration between old and new machine states.
Fixes: 1809ab6a67359e0876981cd05d2a50b2843eabad ("hw/i2c/aspeed: Add AST2700 support")
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
include/hw/i2c/aspeed_i2c.h | 2 +-
hw/i2c/aspeed_i2c.c | 46 ++++++++++++++++++-------------------
2 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
index 1fc229f699..b2e4d2fb9d 100644
--- a/include/hw/i2c/aspeed_i2c.h
+++ b/include/hw/i2c/aspeed_i2c.h
@@ -35,7 +35,7 @@ OBJECT_DECLARE_TYPE(AspeedI2CState, AspeedI2CClass, ASPEED_I2C)
#define ASPEED_I2C_NR_BUSSES 16
#define ASPEED_I2C_SHARE_POOL_SIZE 0x800
-#define ASPEED_I2C_BUS_POOL_SIZE 0x20
+#define ASPEED_I2C_BUS_POOL_SIZE 0x40
#define ASPEED_I2C_NEW_NUM_REG (0xa0 >> 2)
#define A_I2CD_M_STOP_CMD BIT(5)
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
index a6b44174f5..595b5fcf5c 100644
--- a/hw/i2c/aspeed_i2c.c
+++ b/hw/i2c/aspeed_i2c.c
@@ -1132,8 +1132,8 @@ static const MemoryRegionOps aspeed_i2c_bus_pool_ops = {
static const VMStateDescription aspeed_i2c_bus_vmstate = {
.name = TYPE_ASPEED_I2C,
- .version_id = 7,
- .minimum_version_id = 6,
+ .version_id = 8,
+ .minimum_version_id = 7,
.fields = (const VMStateField[]) {
VMSTATE_UINT32_ARRAY(regs, AspeedI2CBus, ASPEED_I2C_NEW_NUM_REG),
VMSTATE_UINT32_V(pending_intr_sts, AspeedI2CBus, 7),
@@ -1145,8 +1145,8 @@ static const VMStateDescription aspeed_i2c_bus_vmstate = {
static const VMStateDescription aspeed_i2c_vmstate = {
.name = TYPE_ASPEED_I2C,
- .version_id = 3,
- .minimum_version_id = 3,
+ .version_id = 4,
+ .minimum_version_id = 4,
.fields = (const VMStateField[]) {
VMSTATE_UINT32(intr_status, AspeedI2CState),
VMSTATE_STRUCT_ARRAY(busses, AspeedI2CState,
@@ -1250,37 +1250,37 @@ static void aspeed_i2c_instance_init(Object *obj)
* Address Definitions (AST2700)
* 0x000 ... 0x0FF: Global Register
* 0x100 ... 0x19F: Device 0
- * 0x1A0 ... 0x1BF: Device 0 buffer
+ * 0x1C0 ... 0x1FF: Device 0 buffer
* 0x200 ... 0x29F: Device 1
- * 0x2A0 ... 0x2BF: Device 1 buffer
+ * 0x2C0 ... 0x2FF: Device 1 buffer
* 0x300 ... 0x39F: Device 2
- * 0x3A0 ... 0x3BF: Device 2 buffer
+ * 0x3C0 ... 0x3FF: Device 2 buffer
* 0x400 ... 0x49F: Device 3
- * 0x4A0 ... 0x4BF: Device 3 buffer
+ * 0x4C0 ... 0x4FF: Device 3 buffer
* 0x500 ... 0x59F: Device 4
- * 0x5A0 ... 0x5BF: Device 4 buffer
+ * 0x5C0 ... 0x5FF: Device 4 buffer
* 0x600 ... 0x69F: Device 5
- * 0x6A0 ... 0x6BF: Device 5 buffer
+ * 0x6C0 ... 0x6FF: Device 5 buffer
* 0x700 ... 0x79F: Device 6
- * 0x7A0 ... 0x7BF: Device 6 buffer
+ * 0x7C0 ... 0x7FF: Device 6 buffer
* 0x800 ... 0x89F: Device 7
- * 0x8A0 ... 0x8BF: Device 7 buffer
+ * 0x8C0 ... 0x8FF: Device 7 buffer
* 0x900 ... 0x99F: Device 8
- * 0x9A0 ... 0x9BF: Device 8 buffer
+ * 0x9C0 ... 0x9FF: Device 8 buffer
* 0xA00 ... 0xA9F: Device 9
- * 0xAA0 ... 0xABF: Device 9 buffer
+ * 0xAC0 ... 0xAFF: Device 9 buffer
* 0xB00 ... 0xB9F: Device 10
- * 0xBA0 ... 0xBBF: Device 10 buffer
+ * 0xBC0 ... 0xBFF: Device 10 buffer
* 0xC00 ... 0xC9F: Device 11
- * 0xCA0 ... 0xCBF: Device 11 buffer
+ * 0xCC0 ... 0xCFF: Device 11 buffer
* 0xD00 ... 0xD9F: Device 12
- * 0xDA0 ... 0xDBF: Device 12 buffer
+ * 0xDC0 ... 0xDFF: Device 12 buffer
* 0xE00 ... 0xE9F: Device 13
- * 0xEA0 ... 0xEBF: Device 13 buffer
+ * 0xEC0 ... 0xEFF: Device 13 buffer
* 0xF00 ... 0xF9F: Device 14
- * 0xFA0 ... 0xFBF: Device 14 buffer
+ * 0xFC0 ... 0xFFF: Device 14 buffer
* 0x1000 ... 0x109F: Device 15
- * 0x10A0 ... 0x10BF: Device 15 buffer
+ * 0x10C0 ... 0x10BF: Device 15 buffer
*/
static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
{
@@ -1666,9 +1666,9 @@ static void aspeed_2700_i2c_class_init(ObjectClass *klass, const void *data)
aic->reg_gap_size = 0x60;
aic->gap = -1; /* no gap */
aic->bus_get_irq = aspeed_2600_i2c_bus_get_irq;
- aic->pool_size = 0x20;
- aic->pool_gap_size = 0xe0;
- aic->pool_base = 0x1a0;
+ aic->pool_size = 0x40;
+ aic->pool_gap_size = 0xc0;
+ aic->pool_base = 0x1c0;
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
aic->has_dma = true;
aic->mem_size = 0x2000;
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 03/10] hw/arm/aspeed_ast1040: Reuse AST2700 ADC model
2026-06-02 5:28 [PATCH v2 00/10] hw/arm/aspeed: Add AST1040 peripheral support Jamin Lin
2026-06-02 5:28 ` [PATCH v2 01/10] hw/i2c/aspeed_i2c: Introduce dma_addr_lo_mask to unify DMA address handling Jamin Lin
2026-06-02 5:28 ` [PATCH v2 02/10] hw/i2c/aspeed_i2c: Increase AST2700 buffer mode size and adjust offset Jamin Lin
@ 2026-06-02 5:28 ` Jamin Lin
2026-06-02 5:28 ` [PATCH v2 04/10] hw/arm/aspeed_ast1040: Introduce PECI support Jamin Lin
` (6 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Jamin Lin @ 2026-06-02 5:28 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Kane Chen, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Jamin Lin, Troy Lee, Cédric Le Goater
Instead of introducing a dedicated TYPE_ASPEED_1040_ADC model,
initialize the existing AST2700 ADC device directly for AST1040.
This avoids unnecessary duplication and keeps the codebase simpler
and easier to maintain.
Add ADC device initialization and realization support to the
AST1040 SoC model using TYPE_ASPEED_2700_ADC.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
hw/arm/aspeed_ast1040.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/hw/arm/aspeed_ast1040.c b/hw/arm/aspeed_ast1040.c
index 8efcdad8f6..b736e690e5 100644
--- a/hw/arm/aspeed_ast1040.c
+++ b/hw/arm/aspeed_ast1040.c
@@ -107,6 +107,8 @@ static void aspeed_soc_ast1040_init(Object *obj)
object_initialize_child(obj, "uart[*]", &s->uart[i], TYPE_SERIAL_MM);
}
+ object_initialize_child(obj, "adc", &s->adc, TYPE_ASPEED_2700_ADC);
+
object_initialize_child(obj, "pwm", &s->pwm, TYPE_UNIMPLEMENTED_DEVICE);
object_initialize_child(obj, "espi", &s->espi, TYPE_UNIMPLEMENTED_DEVICE);
object_initialize_child(obj, "udc", &s->udc, TYPE_UNIMPLEMENTED_DEVICE);
@@ -188,6 +190,15 @@ static void aspeed_soc_ast1040_realize(DeviceState *dev_soc, Error **errp)
aspeed_soc_ast1040_get_irq(s, uart));
}
+ /* ADC */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->adc), errp)) {
+ return;
+ }
+ aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->adc), 0,
+ sc->memmap[ASPEED_DEV_ADC]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
+ aspeed_soc_ast1040_get_irq(s, ASPEED_DEV_ADC));
+
/* Unimplemented peripherals */
aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->pwm),
"aspeed.pwm",
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 04/10] hw/arm/aspeed_ast1040: Introduce PECI support
2026-06-02 5:28 [PATCH v2 00/10] hw/arm/aspeed: Add AST1040 peripheral support Jamin Lin
` (2 preceding siblings ...)
2026-06-02 5:28 ` [PATCH v2 03/10] hw/arm/aspeed_ast1040: Reuse AST2700 ADC model Jamin Lin
@ 2026-06-02 5:28 ` Jamin Lin
2026-06-02 5:28 ` [PATCH v2 05/10] hw/arm/aspeed_ast1040: Reuse AST2700 GPIO controller model Jamin Lin
` (5 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Jamin Lin @ 2026-06-02 5:28 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Kane Chen, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Jamin Lin, Troy Lee, Cédric Le Goater
Introduce PECI support for the AST1040 SoC model.
This change adds the PECI MMIO region and IRQ mapping,
initializes the PECI device instance, and realizes the
controller during SoC initialization.
The PECI controller is mapped at 0x74C1F000 and connected
to IRQ 164.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
hw/arm/aspeed_ast1040.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/hw/arm/aspeed_ast1040.c b/hw/arm/aspeed_ast1040.c
index b736e690e5..9ae0a0e7a4 100644
--- a/hw/arm/aspeed_ast1040.c
+++ b/hw/arm/aspeed_ast1040.c
@@ -31,6 +31,7 @@ static const hwaddr aspeed_soc_ast1040_memmap[] = {
[ASPEED_DEV_SGPIOM0] = 0x74C0C000,
[ASPEED_DEV_SGPIOM1] = 0x74C0D000,
[ASPEED_DEV_I2C] = 0x74C0F000,
+ [ASPEED_DEV_PECI] = 0x74C1F000,
[ASPEED_DEV_I3C] = 0x74C20000,
[ASPEED_DEV_UART0] = 0x74C33000,
[ASPEED_DEV_UART1] = 0x74C33100,
@@ -76,6 +77,7 @@ static const int aspeed_soc_ast1040_irqmap[] = {
[ASPEED_DEV_UART11] = 146,
[ASPEED_DEV_UART12] = 147,
[ASPEED_DEV_JTAG0] = 162,
+ [ASPEED_DEV_PECI] = 164,
};
static qemu_irq aspeed_soc_ast1040_get_irq(AspeedSoCState *s, int dev)
@@ -108,6 +110,7 @@ static void aspeed_soc_ast1040_init(Object *obj)
}
object_initialize_child(obj, "adc", &s->adc, TYPE_ASPEED_2700_ADC);
+ object_initialize_child(obj, "peci", &s->peci, TYPE_ASPEED_PECI);
object_initialize_child(obj, "pwm", &s->pwm, TYPE_UNIMPLEMENTED_DEVICE);
object_initialize_child(obj, "espi", &s->espi, TYPE_UNIMPLEMENTED_DEVICE);
@@ -199,6 +202,15 @@ static void aspeed_soc_ast1040_realize(DeviceState *dev_soc, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->adc), 0,
aspeed_soc_ast1040_get_irq(s, ASPEED_DEV_ADC));
+ /* 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_ast1040_get_irq(s, ASPEED_DEV_PECI));
+
/* Unimplemented peripherals */
aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->pwm),
"aspeed.pwm",
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 05/10] hw/arm/aspeed_ast1040: Reuse AST2700 GPIO controller model
2026-06-02 5:28 [PATCH v2 00/10] hw/arm/aspeed: Add AST1040 peripheral support Jamin Lin
` (3 preceding siblings ...)
2026-06-02 5:28 ` [PATCH v2 04/10] hw/arm/aspeed_ast1040: Introduce PECI support Jamin Lin
@ 2026-06-02 5:28 ` Jamin Lin
2026-06-02 5:28 ` [PATCH v2 06/10] hw/arm/aspeed_ast1040: Add SGPIO controller support Jamin Lin
` (4 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Jamin Lin @ 2026-06-02 5:28 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Kane Chen, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Jamin Lin, Troy Lee, Cédric Le Goater
The AST1040 GPIO controller is compatible with the AST2700 GPIO
controller implementation.
Reuse the existing "aspeed.gpio-ast2700" device model for AST1040
instead of introducing a separate implementation.
Add the GPIO device initialization, MMIO mapping, and IRQ wiring
for the AST1040 SoC model.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
hw/arm/aspeed_ast1040.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/hw/arm/aspeed_ast1040.c b/hw/arm/aspeed_ast1040.c
index 9ae0a0e7a4..c6b22186ce 100644
--- a/hw/arm/aspeed_ast1040.c
+++ b/hw/arm/aspeed_ast1040.c
@@ -111,6 +111,7 @@ static void aspeed_soc_ast1040_init(Object *obj)
object_initialize_child(obj, "adc", &s->adc, TYPE_ASPEED_2700_ADC);
object_initialize_child(obj, "peci", &s->peci, TYPE_ASPEED_PECI);
+ object_initialize_child(obj, "gpio", &s->gpio, "aspeed.gpio-ast2700");
object_initialize_child(obj, "pwm", &s->pwm, TYPE_UNIMPLEMENTED_DEVICE);
object_initialize_child(obj, "espi", &s->espi, TYPE_UNIMPLEMENTED_DEVICE);
@@ -211,6 +212,15 @@ static void aspeed_soc_ast1040_realize(DeviceState *dev_soc, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->peci), 0,
aspeed_soc_ast1040_get_irq(s, ASPEED_DEV_PECI));
+ /* GPIO */
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
+ return;
+ }
+ aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->gpio), 0,
+ sc->memmap[ASPEED_DEV_GPIO]);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0,
+ aspeed_soc_ast1040_get_irq(s, ASPEED_DEV_GPIO));
+
/* Unimplemented peripherals */
aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->pwm),
"aspeed.pwm",
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 06/10] hw/arm/aspeed_ast1040: Add SGPIO controller support
2026-06-02 5:28 [PATCH v2 00/10] hw/arm/aspeed: Add AST1040 peripheral support Jamin Lin
` (4 preceding siblings ...)
2026-06-02 5:28 ` [PATCH v2 05/10] hw/arm/aspeed_ast1040: Reuse AST2700 GPIO controller model Jamin Lin
@ 2026-06-02 5:28 ` Jamin Lin
2026-06-02 5:28 ` [PATCH v2 07/10] hw/i2c/aspeed_i2c: Introduce AST1040 I2C model Jamin Lin
` (3 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Jamin Lin @ 2026-06-02 5:28 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Kane Chen, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Jamin Lin, Troy Lee, Cédric Le Goater
The AST1040 SGPIO controller is compatible with the AST2700
SGPIO controller implementation.
AST1040 contains two SGPIO controllers, so reuse the existing
"aspeed.sgpio-ast2700" device model instead of keeping them as
unimplemented devices.
MMIO mapping:
- SGPIOM0 : 0x74C0C000
- SGPIOM1 : 0x74C0D000
IRQ mapping:
- SGPIOM0 : IRQ 85
- SGPIOM1 : IRQ 88
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
hw/arm/aspeed_ast1040.c | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/hw/arm/aspeed_ast1040.c b/hw/arm/aspeed_ast1040.c
index c6b22186ce..77211ce1f3 100644
--- a/hw/arm/aspeed_ast1040.c
+++ b/hw/arm/aspeed_ast1040.c
@@ -56,6 +56,7 @@ static const int aspeed_soc_ast1040_irqmap[] = {
[ASPEED_DEV_ADC] = 80,
[ASPEED_DEV_GPIO] = 82,
[ASPEED_DEV_SGPIOM0] = 85,
+ [ASPEED_DEV_SGPIOM1] = 88,
[ASPEED_DEV_TIMER1] = 92,
[ASPEED_DEV_I3C] = 96, /* 96 ~ 103 */
[ASPEED_DEV_WDT] = 112,
@@ -112,14 +113,14 @@ static void aspeed_soc_ast1040_init(Object *obj)
object_initialize_child(obj, "adc", &s->adc, TYPE_ASPEED_2700_ADC);
object_initialize_child(obj, "peci", &s->peci, TYPE_ASPEED_PECI);
object_initialize_child(obj, "gpio", &s->gpio, "aspeed.gpio-ast2700");
+ for (i = 0; i < sc->sgpio_num; i++) {
+ object_initialize_child(obj, "sgpio[*]", &s->sgpiom[i],
+ "aspeed.sgpio-ast2700");
+ }
object_initialize_child(obj, "pwm", &s->pwm, TYPE_UNIMPLEMENTED_DEVICE);
object_initialize_child(obj, "espi", &s->espi, TYPE_UNIMPLEMENTED_DEVICE);
object_initialize_child(obj, "udc", &s->udc, TYPE_UNIMPLEMENTED_DEVICE);
- object_initialize_child(obj, "sgpiom[0]", &s->sgpiom[0],
- TYPE_UNIMPLEMENTED_DEVICE);
- object_initialize_child(obj, "sgpiom[1]", &s->sgpiom[1],
- TYPE_UNIMPLEMENTED_DEVICE);
object_initialize_child(obj, "jtag[0]", &s->jtag[0],
TYPE_UNIMPLEMENTED_DEVICE);
object_initialize_child(obj, "jtag[1]", &s->jtag[1],
@@ -221,6 +222,17 @@ static void aspeed_soc_ast1040_realize(DeviceState *dev_soc, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0,
aspeed_soc_ast1040_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_ast1040_get_irq(s, ASPEED_DEV_SGPIOM0 + i));
+ }
+
/* Unimplemented peripherals */
aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->pwm),
"aspeed.pwm",
@@ -234,14 +246,6 @@ static void aspeed_soc_ast1040_realize(DeviceState *dev_soc, Error **errp)
"aspeed.udc",
sc->memmap[ASPEED_DEV_UDC], 0x4000);
- aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->sgpiom[0]),
- "aspeed.sgpiom0",
- sc->memmap[ASPEED_DEV_SGPIOM0], 0x1000);
-
- aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->sgpiom[1]),
- "aspeed.sgpiom1",
- sc->memmap[ASPEED_DEV_SGPIOM1], 0x1000);
-
aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->jtag[0]),
"aspeed.jtag0",
sc->memmap[ASPEED_DEV_JTAG0], 0x100);
@@ -269,6 +273,7 @@ static void aspeed_soc_ast1040_class_init(ObjectClass *klass, const void *data)
sc->sram_size[0] = 128 * KiB;
sc->sram_size[1] = 16 * MiB; /* Hyper RAM */
sc->uarts_num = 13;
+ sc->sgpio_num = 2;
sc->uarts_base = ASPEED_DEV_UART0;
sc->irqmap = aspeed_soc_ast1040_irqmap;
sc->memmap = aspeed_soc_ast1040_memmap;
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 07/10] hw/i2c/aspeed_i2c: Introduce AST1040 I2C model
2026-06-02 5:28 [PATCH v2 00/10] hw/arm/aspeed: Add AST1040 peripheral support Jamin Lin
` (5 preceding siblings ...)
2026-06-02 5:28 ` [PATCH v2 06/10] hw/arm/aspeed_ast1040: Add SGPIO controller support Jamin Lin
@ 2026-06-02 5:28 ` Jamin Lin
2026-06-02 5:28 ` [PATCH v2 08/10] hw/arm/aspeed_ast1040: Introduce I2C support Jamin Lin
` (2 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Jamin Lin @ 2026-06-02 5:28 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Kane Chen, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Jamin Lin, Troy Lee, Cédric Le Goater
Introduce the AST1040 I2C controller model.
The AST1040 I2C controller is compatible with the AST2700 I2C controller,
including DMA support and the 64-bit DMA address registers. Set has_dma64 so
firmware can access the high address register and program it to zero, as the
CM4 CPU only supports 32-bit addressing.
Since AST1040 has 16MB HyperRAM, limit the DMA low address mask to
0x00ffffff.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
include/hw/i2c/aspeed_i2c.h | 1 +
hw/i2c/aspeed_i2c.c | 33 +++++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
index b2e4d2fb9d..156998e7c1 100644
--- a/include/hw/i2c/aspeed_i2c.h
+++ b/include/hw/i2c/aspeed_i2c.h
@@ -30,6 +30,7 @@
#define TYPE_ASPEED_2500_I2C TYPE_ASPEED_I2C "-ast2500"
#define TYPE_ASPEED_2600_I2C TYPE_ASPEED_I2C "-ast2600"
#define TYPE_ASPEED_1030_I2C TYPE_ASPEED_I2C "-ast1030"
+#define TYPE_ASPEED_1040_I2C TYPE_ASPEED_I2C "-ast1040"
#define TYPE_ASPEED_2700_I2C TYPE_ASPEED_I2C "-ast2700"
OBJECT_DECLARE_TYPE(AspeedI2CState, AspeedI2CClass, ASPEED_I2C)
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
index 595b5fcf5c..a810ef9ff1 100644
--- a/hw/i2c/aspeed_i2c.c
+++ b/hw/i2c/aspeed_i2c.c
@@ -1654,6 +1654,34 @@ static void aspeed_1030_i2c_class_init(ObjectClass *klass, const void *data)
aic->dma_addr_lo_mask = 0x7fffffff;
}
+static void aspeed_1040_i2c_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedI2CClass *aic = ASPEED_I2C_CLASS(klass);
+
+ dc->desc = "ASPEED 1040 I2C Controller";
+
+ /*
+ * AST1040 reuses the AST2700 I2C controller implementation since
+ * the AST1040 is compatible with AST2700. The only difference
+ * is that AST1040 HyperRAM is limited to 16 MiB, so the DMA low
+ * address mask is restricted accordingly.
+ */
+ aic->num_busses = 16;
+ aic->reg_size = 0xa0;
+ aic->reg_gap_size = 0x60;
+ aic->gap = -1; /* no gap */
+ aic->bus_get_irq = aspeed_2600_i2c_bus_get_irq;
+ aic->pool_size = 0x40;
+ aic->pool_gap_size = 0xc0;
+ aic->pool_base = 0x1c0;
+ aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
+ aic->has_dma = true;
+ aic->mem_size = 0x2000;
+ aic->has_dma64 = true;
+ aic->dma_addr_lo_mask = 0x00ffffff;
+}
+
static void aspeed_2700_i2c_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -1703,6 +1731,11 @@ static const TypeInfo aspeed_i2c_types[] = {
.parent = TYPE_ASPEED_I2C,
.class_init = aspeed_1030_i2c_class_init,
},
+ {
+ .name = TYPE_ASPEED_1040_I2C,
+ .parent = TYPE_ASPEED_I2C,
+ .class_init = aspeed_1040_i2c_class_init,
+ },
{
.name = TYPE_ASPEED_2400_I2C,
.parent = TYPE_ASPEED_I2C,
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 08/10] hw/arm/aspeed_ast1040: Introduce I2C support
2026-06-02 5:28 [PATCH v2 00/10] hw/arm/aspeed: Add AST1040 peripheral support Jamin Lin
` (6 preceding siblings ...)
2026-06-02 5:28 ` [PATCH v2 07/10] hw/i2c/aspeed_i2c: Introduce AST1040 I2C model Jamin Lin
@ 2026-06-02 5:28 ` Jamin Lin
2026-06-02 6:33 ` Cédric Le Goater
2026-06-02 5:28 ` [PATCH v2 09/10] hw/arm/aspeed_ast1040_evb: Introduce onboard I2C device Jamin Lin
2026-06-02 5:28 ` [PATCH v2 10/10] hw/arm/aspeed_ast1040: Reuse AST2700 watchdog models Jamin Lin
9 siblings, 1 reply; 19+ messages in thread
From: Jamin Lin @ 2026-06-02 5:28 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Kane Chen, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Jamin Lin, Troy Lee
Introduce I2C controller support for the AST1040 SoC model.
The I2C model type is selected from the SoC type name, allowing the AST1040
SoC to use the corresponding aspeed.i2c-ast1040 model.
The I2C controller is mapped at 0x74C0F000 and uses IRQs
64 - 77, with one IRQ assigned per I2C bus.
The controller DRAM link is connected to SRAM1 (HyperRAM)
for DMA support.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/arm/aspeed_ast1040.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/hw/arm/aspeed_ast1040.c b/hw/arm/aspeed_ast1040.c
index 77211ce1f3..6d1cb9b102 100644
--- a/hw/arm/aspeed_ast1040.c
+++ b/hw/arm/aspeed_ast1040.c
@@ -117,6 +117,7 @@ static void aspeed_soc_ast1040_init(Object *obj)
object_initialize_child(obj, "sgpio[*]", &s->sgpiom[i],
"aspeed.sgpio-ast2700");
}
+ object_initialize_child(obj, "i2c", &s->i2c, TYPE_ASPEED_1040_I2C);
object_initialize_child(obj, "pwm", &s->pwm, TYPE_UNIMPLEMENTED_DEVICE);
object_initialize_child(obj, "espi", &s->espi, TYPE_UNIMPLEMENTED_DEVICE);
@@ -233,6 +234,21 @@ static void aspeed_soc_ast1040_realize(DeviceState *dev_soc, Error **errp)
aspeed_soc_ast1040_get_irq(s, ASPEED_DEV_SGPIOM0 + i));
}
+ /* I2C */
+ object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(&s->sram[1]),
+ &error_abort);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) {
+ return;
+ }
+ aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->i2c), 0,
+ sc->memmap[ASPEED_DEV_I2C]);
+ for (i = 0; i < ASPEED_I2C_GET_CLASS(&s->i2c)->num_busses; i++) {
+ qemu_irq irq = qdev_get_gpio_in(DEVICE(&a->armv7m),
+ sc->irqmap[ASPEED_DEV_I2C] + i);
+ /* The AST1040 I2C controller has one IRQ per bus. */
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c.busses[i]), 0, irq);
+ }
+
/* Unimplemented peripherals */
aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->pwm),
"aspeed.pwm",
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 09/10] hw/arm/aspeed_ast1040_evb: Introduce onboard I2C device
2026-06-02 5:28 [PATCH v2 00/10] hw/arm/aspeed: Add AST1040 peripheral support Jamin Lin
` (7 preceding siblings ...)
2026-06-02 5:28 ` [PATCH v2 08/10] hw/arm/aspeed_ast1040: Introduce I2C support Jamin Lin
@ 2026-06-02 5:28 ` Jamin Lin
2026-06-02 6:34 ` Cédric Le Goater
2026-06-02 5:28 ` [PATCH v2 10/10] hw/arm/aspeed_ast1040: Reuse AST2700 watchdog models Jamin Lin
9 siblings, 1 reply; 19+ messages in thread
From: Jamin Lin @ 2026-06-02 5:28 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Kane Chen, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Jamin Lin, Troy Lee
Introduce onboard I2C device initialization for the AST1040
EVB model.
This change adds the initial onboard I2C device setup flow
and instantiates a 24C08 SMBus EEPROM device connected to
I2C bus 0, matching the current AST1040 EVB hardware design.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
hw/arm/aspeed_ast1040_evb.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/hw/arm/aspeed_ast1040_evb.c b/hw/arm/aspeed_ast1040_evb.c
index 1d9b55247f..66f08ccbe6 100644
--- a/hw/arm/aspeed_ast1040_evb.c
+++ b/hw/arm/aspeed_ast1040_evb.c
@@ -14,6 +14,7 @@
#include "hw/arm/aspeed_soc.h"
#include "hw/core/qdev-clock.h"
#include "system/system.h"
+#include "hw/i2c/smbus_eeprom.h"
#define AST1040_INTERNAL_FLASH_SIZE (4 * MiB)
/* Main SYSCLK frequency in Hz (400MHz) */
@@ -38,12 +39,28 @@ static void aspeed_bic_machine_init(MachineState *machine)
aspeed_connect_serial_hds_to_uarts(bmc);
qdev_realize(DEVICE(bmc->soc), NULL, &error_abort);
+ if (amc->i2c_init) {
+ amc->i2c_init(bmc);
+ }
+
armv7m_load_kernel(ARM_CPU(first_cpu),
machine->kernel_filename,
0,
AST1040_INTERNAL_FLASH_SIZE);
}
+static void ast1040_evb_i2c_init(AspeedMachineState *bmc)
+{
+ AspeedSoCState *soc = bmc->soc;
+
+ /* U10 24C08 connects to SDA/SCL Group 1 by default */
+ uint8_t *eeprom_buf = g_malloc0(32 * KiB);
+ smbus_eeprom_init_one(aspeed_i2c_get_bus(&soc->i2c, 0), 0x50, eeprom_buf);
+
+ /* U11 LM75 connects to SDA/SCL Group 2 by default */
+ i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 1), "tmp105", 0x4d);
+}
+
static void aspeed_machine_ast1040_evb_class_init(ObjectClass *oc,
const void *data)
{
@@ -55,6 +72,7 @@ static void aspeed_machine_ast1040_evb_class_init(ObjectClass *oc,
amc->hw_strap1 = 0;
amc->hw_strap2 = 0;
mc->init = aspeed_bic_machine_init;
+ amc->i2c_init = ast1040_evb_i2c_init;
mc->default_ram_size = 0;
amc->macs_mask = 0;
amc->uart_default = ASPEED_DEV_UART12;
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 10/10] hw/arm/aspeed_ast1040: Reuse AST2700 watchdog models
2026-06-02 5:28 [PATCH v2 00/10] hw/arm/aspeed: Add AST1040 peripheral support Jamin Lin
` (8 preceding siblings ...)
2026-06-02 5:28 ` [PATCH v2 09/10] hw/arm/aspeed_ast1040_evb: Introduce onboard I2C device Jamin Lin
@ 2026-06-02 5:28 ` Jamin Lin
9 siblings, 0 replies; 19+ messages in thread
From: Jamin Lin @ 2026-06-02 5:28 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Kane Chen, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Jamin Lin, Troy Lee, Cédric Le Goater
Instantiate and realize the watchdog models for the AST1040 SoC.
The AST1040 watchdog controller is compatible with the AST2700 watchdog
controller, so reuse the existing AST2700 watchdog model.
Configure the AST1040 SoC with 8 watchdog instances and map them to
their corresponding MMIO regions. The first watchdog controller (WDT0) is
located at 0x74c37000, with subsequent watchdogs placed according to the
controller register space size.
Each watchdog is linked to the SCU device before realization to provide the
required reset and system control interactions.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
hw/arm/aspeed_ast1040.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/hw/arm/aspeed_ast1040.c b/hw/arm/aspeed_ast1040.c
index 6d1cb9b102..57ffc0807a 100644
--- a/hw/arm/aspeed_ast1040.c
+++ b/hw/arm/aspeed_ast1040.c
@@ -119,6 +119,11 @@ static void aspeed_soc_ast1040_init(Object *obj)
}
object_initialize_child(obj, "i2c", &s->i2c, TYPE_ASPEED_1040_I2C);
+ for (i = 0; i < sc->wdts_num; i++) {
+ object_initialize_child(obj, "wdt[*]", &s->wdt[i],
+ "aspeed.wdt-ast2700");
+ }
+
object_initialize_child(obj, "pwm", &s->pwm, TYPE_UNIMPLEMENTED_DEVICE);
object_initialize_child(obj, "espi", &s->espi, TYPE_UNIMPLEMENTED_DEVICE);
object_initialize_child(obj, "udc", &s->udc, TYPE_UNIMPLEMENTED_DEVICE);
@@ -249,6 +254,19 @@ static void aspeed_soc_ast1040_realize(DeviceState *dev_soc, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c.busses[i]), 0, irq);
}
+ /* Watch dog */
+ for (i = 0; i < sc->wdts_num; i++) {
+ AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
+ hwaddr wdt_offset = sc->memmap[ASPEED_DEV_WDT] + i * awc->iosize;
+
+ 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;
+ }
+ aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->wdt[i]), 0, wdt_offset);
+ }
+
/* Unimplemented peripherals */
aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->pwm),
"aspeed.pwm",
@@ -290,6 +308,7 @@ static void aspeed_soc_ast1040_class_init(ObjectClass *klass, const void *data)
sc->sram_size[1] = 16 * MiB; /* Hyper RAM */
sc->uarts_num = 13;
sc->sgpio_num = 2;
+ sc->wdts_num = 8;
sc->uarts_base = ASPEED_DEV_UART0;
sc->irqmap = aspeed_soc_ast1040_irqmap;
sc->memmap = aspeed_soc_ast1040_memmap;
--
2.43.0
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH v2 01/10] hw/i2c/aspeed_i2c: Introduce dma_addr_lo_mask to unify DMA address handling
2026-06-02 5:28 ` [PATCH v2 01/10] hw/i2c/aspeed_i2c: Introduce dma_addr_lo_mask to unify DMA address handling Jamin Lin
@ 2026-06-02 6:26 ` Cédric Le Goater
2026-06-03 2:58 ` Jamin Lin
0 siblings, 1 reply; 19+ messages in thread
From: Cédric Le Goater @ 2026-06-02 6:26 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Kane Chen,
Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Troy Lee
On 6/2/26 07:28, Jamin Lin wrote:
> The Aspeed I2C controller has two register layouts.
>
> The AST2500 uses the old mode with a single DMA address register (I2CD_DMA_ADDR)
> where the address is 4-byte aligned and masked to 0x3ffffffc.
>
> From AST2600 onwards, the new mode provides separate master TX/RX and slave RX DMA
> address registers (I2CM_DMA_TX_ADDR, I2CM_DMA_RX_ADDR, I2CS_DMA_RX_ADDR)
> with different address widths per SoC:
> AST2600 (new mode): 0x7fffffff - bits[30:0]
> AST1030 (new mode): 0x7fffffff - bits[30:0]
> AST1060 (new mode): 0x7fffffff - bits[30:0]
> AST2700 (new mode): 0xffffffff - bits[31:0]
>
> Introduce dma_addr_lo_mask as a per-class attribute and apply it
> uniformly when storing DMA address register writes and when loading
> the address into dma_dram_offset for both master and slave paths.
> This replaces the previous FIELD_EX32 extractions (which incorrectly
> stripped bit 31 on AST2700) and the hardcoded 0x3ffffffc literal in
> the old-mode path.
>
> Fixes: 1809ab6a67359e0876981cd05d2a50b2843eabad ("hw/i2c/aspeed: Add AST2700 support")
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
> include/hw/i2c/aspeed_i2c.h | 5 +----
> hw/i2c/aspeed_i2c.c | 22 +++++++++++++---------
> 2 files changed, 14 insertions(+), 13 deletions(-)
aspeed_i2c_bus_new_write() still has :
case A_I2CS_DMA_RX_ADDR:
bus->regs[R_I2CS_DMA_RX_ADDR] = value;
Is that ok ?
Thanks,
C.
>
> diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
> index d42cb4865a..1fc229f699 100644
> --- a/include/hw/i2c/aspeed_i2c.h
> +++ b/include/hw/i2c/aspeed_i2c.h
> @@ -209,13 +209,9 @@ REG32(I2CS_DMA_LEN, 0x2c)
> FIELD(I2CS_DMA_LEN, TX_BUF_LEN_W1T, 15, 1)
> FIELD(I2CS_DMA_LEN, TX_BUF_LEN, 0, 11)
> REG32(I2CM_DMA_TX_ADDR, 0x30)
> - FIELD(I2CM_DMA_TX_ADDR, ADDR, 0, 31)
> REG32(I2CM_DMA_RX_ADDR, 0x34)
> - FIELD(I2CM_DMA_RX_ADDR, ADDR, 0, 31)
> REG32(I2CS_DMA_TX_ADDR, 0x38)
> - FIELD(I2CS_DMA_TX_ADDR, ADDR, 0, 31)
> REG32(I2CS_DMA_RX_ADDR, 0x3c)
> - FIELD(I2CS_DMA_RX_ADDR, ADDR, 0, 31)
> REG32(I2CS_DEV_ADDR, 0x40)
> REG32(I2CM_DMA_LEN_STS, 0x48)
> FIELD(I2CM_DMA_LEN_STS, RX_LEN, 16, 13)
> @@ -303,6 +299,7 @@ struct AspeedI2CClass {
> bool has_share_pool;
> uint64_t mem_size;
> bool has_dma64;
> + uint32_t dma_addr_lo_mask;
> };
>
> static inline bool aspeed_i2c_is_new_mode(AspeedI2CState *s)
> diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
> index 4a6732a185..a6b44174f5 100644
> --- a/hw/i2c/aspeed_i2c.c
> +++ b/hw/i2c/aspeed_i2c.c
> @@ -236,7 +236,7 @@ static void aspeed_i2c_set_tx_dma_dram_offset(AspeedI2CBus *bus)
> value = bus->regs[R_I2CM_DMA_TX_ADDR];
> bus->dma_dram_offset =
> deposit64(bus->dma_dram_offset, 0, 32,
> - FIELD_EX32(value, I2CM_DMA_TX_ADDR, ADDR));
> + value & aic->dma_addr_lo_mask);
> if (aic->has_dma64) {
> value = bus->regs[R_I2CM_DMA_TX_ADDR_HI];
> bus->dma_dram_offset =
> @@ -246,7 +246,7 @@ static void aspeed_i2c_set_tx_dma_dram_offset(AspeedI2CBus *bus)
> } else {
> value = bus->regs[R_I2CD_DMA_ADDR];
> bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32,
> - value & 0x3ffffffc);
> + value & aic->dma_addr_lo_mask);
> }
> }
>
> @@ -261,7 +261,7 @@ static void aspeed_i2c_set_rx_dma_dram_offset(AspeedI2CBus *bus)
> value = bus->regs[R_I2CM_DMA_RX_ADDR];
> bus->dma_dram_offset =
> deposit64(bus->dma_dram_offset, 0, 32,
> - FIELD_EX32(value, I2CM_DMA_RX_ADDR, ADDR));
> + value & aic->dma_addr_lo_mask);
> if (aic->has_dma64) {
> value = bus->regs[R_I2CM_DMA_RX_ADDR_HI];
> bus->dma_dram_offset =
> @@ -271,7 +271,7 @@ static void aspeed_i2c_set_rx_dma_dram_offset(AspeedI2CBus *bus)
> } else {
> value = bus->regs[R_I2CD_DMA_ADDR];
> bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32,
> - value & 0x3ffffffc);
> + value & aic->dma_addr_lo_mask);
> }
> }
>
> @@ -735,12 +735,10 @@ static void aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
> aspeed_i2c_bus_raise_interrupt(bus);
> break;
> case A_I2CM_DMA_TX_ADDR:
> - bus->regs[R_I2CM_DMA_TX_ADDR] = FIELD_EX32(value, I2CM_DMA_TX_ADDR,
> - ADDR);
> + bus->regs[R_I2CM_DMA_TX_ADDR] = value & aic->dma_addr_lo_mask;
> break;
> case A_I2CM_DMA_RX_ADDR:
> - bus->regs[R_I2CM_DMA_RX_ADDR] = FIELD_EX32(value, I2CM_DMA_RX_ADDR,
> - ADDR);
> + bus->regs[R_I2CM_DMA_RX_ADDR] = value & aic->dma_addr_lo_mask;
> break;
> case A_I2CM_DMA_LEN:
> w1t = FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN_W1T) ||
> @@ -1375,6 +1373,8 @@ static void aspeed_i2c_class_init(ObjectClass *klass, const void *data)
> static int aspeed_i2c_bus_new_slave_event(AspeedI2CBus *bus,
> enum i2c_event event)
> {
> + AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
> +
> switch (event) {
> case I2C_START_SEND_ASYNC:
> if (!SHARED_ARRAY_FIELD_EX32(bus->regs, R_I2CS_CMD, RX_DMA_EN)) {
> @@ -1385,7 +1385,7 @@ static int aspeed_i2c_bus_new_slave_event(AspeedI2CBus *bus,
> ARRAY_FIELD_DP32(bus->regs, I2CS_DMA_LEN_STS, RX_LEN, 0);
> bus->dma_dram_offset =
> deposit64(bus->dma_dram_offset, 0, 32,
> - ARRAY_FIELD_EX32(bus->regs, I2CS_DMA_RX_ADDR, ADDR));
> + bus->regs[R_I2CS_DMA_RX_ADDR] & aic->dma_addr_lo_mask);
> bus->regs[R_I2CC_DMA_LEN] =
> ARRAY_FIELD_EX32(bus->regs, I2CS_DMA_LEN, RX_BUF_LEN) + 1;
> i2c_ack(bus->bus);
> @@ -1608,6 +1608,7 @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, const void *data)
> aic->check_sram = true;
> aic->has_dma = true;
> aic->mem_size = 0x1000;
> + aic->dma_addr_lo_mask = 0x3ffffffc;
> }
>
> static qemu_irq aspeed_2600_i2c_bus_get_irq(AspeedI2CBus *bus)
> @@ -1631,6 +1632,7 @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, const void *data)
> aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
> aic->has_dma = true;
> aic->mem_size = 0x1000;
> + aic->dma_addr_lo_mask = 0x7fffffff;
> }
>
> static void aspeed_1030_i2c_class_init(ObjectClass *klass, const void *data)
> @@ -1649,6 +1651,7 @@ static void aspeed_1030_i2c_class_init(ObjectClass *klass, const void *data)
> aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
> aic->has_dma = true;
> aic->mem_size = 0x10000;
> + aic->dma_addr_lo_mask = 0x7fffffff;
> }
>
> static void aspeed_2700_i2c_class_init(ObjectClass *klass, const void *data)
> @@ -1670,6 +1673,7 @@ static void aspeed_2700_i2c_class_init(ObjectClass *klass, const void *data)
> aic->has_dma = true;
> aic->mem_size = 0x2000;
> aic->has_dma64 = true;
> + aic->dma_addr_lo_mask = 0xffffffff;
> }
>
> static const TypeInfo aspeed_i2c_types[] = {
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 02/10] hw/i2c/aspeed_i2c: Increase AST2700 buffer mode size and adjust offset
2026-06-02 5:28 ` [PATCH v2 02/10] hw/i2c/aspeed_i2c: Increase AST2700 buffer mode size and adjust offset Jamin Lin
@ 2026-06-02 6:33 ` Cédric Le Goater
2026-06-02 8:22 ` Jamin Lin
0 siblings, 1 reply; 19+ messages in thread
From: Cédric Le Goater @ 2026-06-02 6:33 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Kane Chen,
Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Troy Lee
On 6/2/26 07:28, Jamin Lin wrote:
> Update the AST2700 I2C buffer mode configuration to match
> the latest firmware definition:
> - Increase buffer mode pool size from 0x20 to 0x40
> - Adjust buffer mode base offset to 0x1c0
>
> Since the buffer mode region size changes, the migration state
> layout is also modified. Bump the VMState version numbers to
> prevent incompatible migration between old and new machine states.
>
> Fixes: 1809ab6a67359e0876981cd05d2a50b2843eabad ("hw/i2c/aspeed: Add AST2700 support")
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
> include/hw/i2c/aspeed_i2c.h | 2 +-
> hw/i2c/aspeed_i2c.c | 46 ++++++++++++++++++-------------------
> 2 files changed, 24 insertions(+), 24 deletions(-)
>
> diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
> index 1fc229f699..b2e4d2fb9d 100644
> --- a/include/hw/i2c/aspeed_i2c.h
> +++ b/include/hw/i2c/aspeed_i2c.h
> @@ -35,7 +35,7 @@ OBJECT_DECLARE_TYPE(AspeedI2CState, AspeedI2CClass, ASPEED_I2C)
>
> #define ASPEED_I2C_NR_BUSSES 16
> #define ASPEED_I2C_SHARE_POOL_SIZE 0x800
> -#define ASPEED_I2C_BUS_POOL_SIZE 0x20
> +#define ASPEED_I2C_BUS_POOL_SIZE 0x40
> #define ASPEED_I2C_NEW_NUM_REG (0xa0 >> 2)
>
> #define A_I2CD_M_STOP_CMD BIT(5)
> diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
> index a6b44174f5..595b5fcf5c 100644
> --- a/hw/i2c/aspeed_i2c.c
> +++ b/hw/i2c/aspeed_i2c.c
> @@ -1132,8 +1132,8 @@ static const MemoryRegionOps aspeed_i2c_bus_pool_ops = {
>
> static const VMStateDescription aspeed_i2c_bus_vmstate = {
> .name = TYPE_ASPEED_I2C,
> - .version_id = 7,
> - .minimum_version_id = 6,
> + .version_id = 8,
> + .minimum_version_id = 7,
I think min should be '8'. QEMU can not deserialise a v7 format
of the pool array. It reads exactly ASPEED_I2C_BUS_POOL_SIZE bytes
from the migration stream. But the size has changed.
> .fields = (const VMStateField[]) {
> VMSTATE_UINT32_ARRAY(regs, AspeedI2CBus, ASPEED_I2C_NEW_NUM_REG),
> VMSTATE_UINT32_V(pending_intr_sts, AspeedI2CBus, 7),
> @@ -1145,8 +1145,8 @@ static const VMStateDescription aspeed_i2c_bus_vmstate = {
>
> static const VMStateDescription aspeed_i2c_vmstate = {
> .name = TYPE_ASPEED_I2C,
> - .version_id = 3,
> - .minimum_version_id = 3,
> + .version_id = 4,
> + .minimum_version_id = 4,
> .fields = (const VMStateField[]) {
> VMSTATE_UINT32(intr_status, AspeedI2CState),
> VMSTATE_STRUCT_ARRAY(busses, AspeedI2CState,
> @@ -1250,37 +1250,37 @@ static void aspeed_i2c_instance_init(Object *obj)
> * Address Definitions (AST2700)
> * 0x000 ... 0x0FF: Global Register
> * 0x100 ... 0x19F: Device 0
> - * 0x1A0 ... 0x1BF: Device 0 buffer
> + * 0x1C0 ... 0x1FF: Device 0 buffer
> * 0x200 ... 0x29F: Device 1
> - * 0x2A0 ... 0x2BF: Device 1 buffer
> + * 0x2C0 ... 0x2FF: Device 1 buffer
> * 0x300 ... 0x39F: Device 2
> - * 0x3A0 ... 0x3BF: Device 2 buffer
> + * 0x3C0 ... 0x3FF: Device 2 buffer
> * 0x400 ... 0x49F: Device 3
> - * 0x4A0 ... 0x4BF: Device 3 buffer
> + * 0x4C0 ... 0x4FF: Device 3 buffer
> * 0x500 ... 0x59F: Device 4
> - * 0x5A0 ... 0x5BF: Device 4 buffer
> + * 0x5C0 ... 0x5FF: Device 4 buffer
> * 0x600 ... 0x69F: Device 5
> - * 0x6A0 ... 0x6BF: Device 5 buffer
> + * 0x6C0 ... 0x6FF: Device 5 buffer
> * 0x700 ... 0x79F: Device 6
> - * 0x7A0 ... 0x7BF: Device 6 buffer
> + * 0x7C0 ... 0x7FF: Device 6 buffer
> * 0x800 ... 0x89F: Device 7
> - * 0x8A0 ... 0x8BF: Device 7 buffer
> + * 0x8C0 ... 0x8FF: Device 7 buffer
> * 0x900 ... 0x99F: Device 8
> - * 0x9A0 ... 0x9BF: Device 8 buffer
> + * 0x9C0 ... 0x9FF: Device 8 buffer
> * 0xA00 ... 0xA9F: Device 9
> - * 0xAA0 ... 0xABF: Device 9 buffer
> + * 0xAC0 ... 0xAFF: Device 9 buffer
> * 0xB00 ... 0xB9F: Device 10
> - * 0xBA0 ... 0xBBF: Device 10 buffer
> + * 0xBC0 ... 0xBFF: Device 10 buffer
> * 0xC00 ... 0xC9F: Device 11
> - * 0xCA0 ... 0xCBF: Device 11 buffer
> + * 0xCC0 ... 0xCFF: Device 11 buffer
> * 0xD00 ... 0xD9F: Device 12
> - * 0xDA0 ... 0xDBF: Device 12 buffer
> + * 0xDC0 ... 0xDFF: Device 12 buffer
> * 0xE00 ... 0xE9F: Device 13
> - * 0xEA0 ... 0xEBF: Device 13 buffer
> + * 0xEC0 ... 0xEFF: Device 13 buffer
> * 0xF00 ... 0xF9F: Device 14
> - * 0xFA0 ... 0xFBF: Device 14 buffer
> + * 0xFC0 ... 0xFFF: Device 14 buffer
> * 0x1000 ... 0x109F: Device 15
> - * 0x10A0 ... 0x10BF: Device 15 buffer
> + * 0x10C0 ... 0x10BF: Device 15 buffer
> */
> static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
> {
> @@ -1666,9 +1666,9 @@ static void aspeed_2700_i2c_class_init(ObjectClass *klass, const void *data)
> aic->reg_gap_size = 0x60;
> aic->gap = -1; /* no gap */
> aic->bus_get_irq = aspeed_2600_i2c_bus_get_irq;
> - aic->pool_size = 0x20;
> - aic->pool_gap_size = 0xe0;
> - aic->pool_base = 0x1a0;
> + aic->pool_size = 0x40;
> + aic->pool_gap_size = 0xc0;
> + aic->pool_base = 0x1c0;
> aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
> aic->has_dma = true;
> aic->mem_size = 0x2000;
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 08/10] hw/arm/aspeed_ast1040: Introduce I2C support
2026-06-02 5:28 ` [PATCH v2 08/10] hw/arm/aspeed_ast1040: Introduce I2C support Jamin Lin
@ 2026-06-02 6:33 ` Cédric Le Goater
2026-06-02 8:41 ` Jamin Lin
0 siblings, 1 reply; 19+ messages in thread
From: Cédric Le Goater @ 2026-06-02 6:33 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Kane Chen,
Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Troy Lee
On 6/2/26 07:28, Jamin Lin wrote:
> Introduce I2C controller support for the AST1040 SoC model.
>
> The I2C model type is selected from the SoC type name, allowing the AST1040
> SoC to use the corresponding aspeed.i2c-ast1040 model.
>
> The I2C controller is mapped at 0x74C0F000 and uses IRQs
> 64 - 77, with one IRQ assigned per I2C bus.
64 - 79. The irqmap array needs a change too.
>
> The controller DRAM link is connected to SRAM1 (HyperRAM)
> for DMA support.
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
> hw/arm/aspeed_ast1040.c | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/hw/arm/aspeed_ast1040.c b/hw/arm/aspeed_ast1040.c
> index 77211ce1f3..6d1cb9b102 100644
> --- a/hw/arm/aspeed_ast1040.c
> +++ b/hw/arm/aspeed_ast1040.c
> @@ -117,6 +117,7 @@ static void aspeed_soc_ast1040_init(Object *obj)
> object_initialize_child(obj, "sgpio[*]", &s->sgpiom[i],
> "aspeed.sgpio-ast2700");
> }
> + object_initialize_child(obj, "i2c", &s->i2c, TYPE_ASPEED_1040_I2C);
>
> object_initialize_child(obj, "pwm", &s->pwm, TYPE_UNIMPLEMENTED_DEVICE);
> object_initialize_child(obj, "espi", &s->espi, TYPE_UNIMPLEMENTED_DEVICE);
> @@ -233,6 +234,21 @@ static void aspeed_soc_ast1040_realize(DeviceState *dev_soc, Error **errp)
> aspeed_soc_ast1040_get_irq(s, ASPEED_DEV_SGPIOM0 + i));
> }
>
> + /* I2C */
> + object_property_set_link(OBJECT(&s->i2c), "dram", OBJECT(&s->sram[1]),
> + &error_abort);
> + if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) {
> + return;
> + }
> + aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->i2c), 0,
> + sc->memmap[ASPEED_DEV_I2C]);
> + for (i = 0; i < ASPEED_I2C_GET_CLASS(&s->i2c)->num_busses; i++) {
> + qemu_irq irq = qdev_get_gpio_in(DEVICE(&a->armv7m),
> + sc->irqmap[ASPEED_DEV_I2C] + i);
> + /* The AST1040 I2C controller has one IRQ per bus. */
> + sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c.busses[i]), 0, irq);
> + }
> +
> /* Unimplemented peripherals */
> aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->pwm),
> "aspeed.pwm",
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 09/10] hw/arm/aspeed_ast1040_evb: Introduce onboard I2C device
2026-06-02 5:28 ` [PATCH v2 09/10] hw/arm/aspeed_ast1040_evb: Introduce onboard I2C device Jamin Lin
@ 2026-06-02 6:34 ` Cédric Le Goater
2026-06-03 1:31 ` Jamin Lin
0 siblings, 1 reply; 19+ messages in thread
From: Cédric Le Goater @ 2026-06-02 6:34 UTC (permalink / raw)
To: Jamin Lin, Peter Maydell, Steven Lee, Troy Lee, Kane Chen,
Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Troy Lee
On 6/2/26 07:28, Jamin Lin wrote:
> Introduce onboard I2C device initialization for the AST1040
> EVB model.
>
> This change adds the initial onboard I2C device setup flow
> and instantiates a 24C08 SMBus EEPROM device connected to
> I2C bus 0, matching the current AST1040 EVB hardware design.
>
> Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> ---
> hw/arm/aspeed_ast1040_evb.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/hw/arm/aspeed_ast1040_evb.c b/hw/arm/aspeed_ast1040_evb.c
> index 1d9b55247f..66f08ccbe6 100644
> --- a/hw/arm/aspeed_ast1040_evb.c
> +++ b/hw/arm/aspeed_ast1040_evb.c
> @@ -14,6 +14,7 @@
> #include "hw/arm/aspeed_soc.h"
> #include "hw/core/qdev-clock.h"
> #include "system/system.h"
> +#include "hw/i2c/smbus_eeprom.h"
>
> #define AST1040_INTERNAL_FLASH_SIZE (4 * MiB)
> /* Main SYSCLK frequency in Hz (400MHz) */
> @@ -38,12 +39,28 @@ static void aspeed_bic_machine_init(MachineState *machine)
> aspeed_connect_serial_hds_to_uarts(bmc);
> qdev_realize(DEVICE(bmc->soc), NULL, &error_abort);
>
> + if (amc->i2c_init) {
> + amc->i2c_init(bmc);
> + }
> +
> armv7m_load_kernel(ARM_CPU(first_cpu),
> machine->kernel_filename,
> 0,
> AST1040_INTERNAL_FLASH_SIZE);
> }
>
> +static void ast1040_evb_i2c_init(AspeedMachineState *bmc)
> +{
> + AspeedSoCState *soc = bmc->soc;
> +
> + /* U10 24C08 connects to SDA/SCL Group 1 by default */
> + uint8_t *eeprom_buf = g_malloc0(32 * KiB);
The smbus-eeprom device's internal buffer is 256 bytes.
We have been copy/pasting this 32 * KiB size for a while it seems but
SMBUS_EEPROM_SIZE would be enough.
Anyhow,
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> + smbus_eeprom_init_one(aspeed_i2c_get_bus(&soc->i2c, 0), 0x50, eeprom_buf);
> +
> + /* U11 LM75 connects to SDA/SCL Group 2 by default */
> + i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 1), "tmp105", 0x4d);
> +}
> +
> static void aspeed_machine_ast1040_evb_class_init(ObjectClass *oc,
> const void *data)
> {
> @@ -55,6 +72,7 @@ static void aspeed_machine_ast1040_evb_class_init(ObjectClass *oc,
> amc->hw_strap1 = 0;
> amc->hw_strap2 = 0;
> mc->init = aspeed_bic_machine_init;
> + amc->i2c_init = ast1040_evb_i2c_init;
> mc->default_ram_size = 0;
> amc->macs_mask = 0;
> amc->uart_default = ASPEED_DEV_UART12;
^ permalink raw reply [flat|nested] 19+ messages in thread
* RE: [PATCH v2 02/10] hw/i2c/aspeed_i2c: Increase AST2700 buffer mode size and adjust offset
2026-06-02 6:33 ` Cédric Le Goater
@ 2026-06-02 8:22 ` Jamin Lin
0 siblings, 0 replies; 19+ messages in thread
From: Jamin Lin @ 2026-06-02 8:22 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Kane Chen, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Troy Lee
Hi Cédric
> Subject: Re: [PATCH v2 02/10] hw/i2c/aspeed_i2c: Increase AST2700 buffer
> mode size and adjust offset
>
> On 6/2/26 07:28, Jamin Lin wrote:
> > Update the AST2700 I2C buffer mode configuration to match the latest
> > firmware definition:
> > - Increase buffer mode pool size from 0x20 to 0x40
> > - Adjust buffer mode base offset to 0x1c0
> >
> > Since the buffer mode region size changes, the migration state layout
> > is also modified. Bump the VMState version numbers to prevent
> > incompatible migration between old and new machine states.
> >
> > Fixes: 1809ab6a67359e0876981cd05d2a50b2843eabad ("hw/i2c/aspeed:
> Add
> > AST2700 support")
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> > include/hw/i2c/aspeed_i2c.h | 2 +-
> > hw/i2c/aspeed_i2c.c | 46 ++++++++++++++++++-------------------
> > 2 files changed, 24 insertions(+), 24 deletions(-)
> >
> > diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
> > index 1fc229f699..b2e4d2fb9d 100644
> > --- a/include/hw/i2c/aspeed_i2c.h
> > +++ b/include/hw/i2c/aspeed_i2c.h
> > @@ -35,7 +35,7 @@ OBJECT_DECLARE_TYPE(AspeedI2CState,
> AspeedI2CClass,
> > ASPEED_I2C)
> >
> > #define ASPEED_I2C_NR_BUSSES 16
> > #define ASPEED_I2C_SHARE_POOL_SIZE 0x800 -#define
> > ASPEED_I2C_BUS_POOL_SIZE 0x20
> > +#define ASPEED_I2C_BUS_POOL_SIZE 0x40
> > #define ASPEED_I2C_NEW_NUM_REG (0xa0 >> 2)
> >
> > #define A_I2CD_M_STOP_CMD BIT(5)
> > diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c index
> > a6b44174f5..595b5fcf5c 100644
> > --- a/hw/i2c/aspeed_i2c.c
> > +++ b/hw/i2c/aspeed_i2c.c
> > @@ -1132,8 +1132,8 @@ static const MemoryRegionOps
> > aspeed_i2c_bus_pool_ops = {
> >
> > static const VMStateDescription aspeed_i2c_bus_vmstate = {
> > .name = TYPE_ASPEED_I2C,
> > - .version_id = 7,
> > - .minimum_version_id = 6,
> > + .version_id = 8,
> > + .minimum_version_id = 7,
>
>
> I think min should be '8'. QEMU can not deserialise a v7 format of the pool
> array. It reads exactly ASPEED_I2C_BUS_POOL_SIZE bytes from the migration
> stream. But the size has changed.
>
Thanks for the review and suggestion.
Will do.
Jamin
>
> > .fields = (const VMStateField[]) {
> > VMSTATE_UINT32_ARRAY(regs, AspeedI2CBus,
> ASPEED_I2C_NEW_NUM_REG),
> > VMSTATE_UINT32_V(pending_intr_sts, AspeedI2CBus, 7), @@
> > -1145,8 +1145,8 @@ static const VMStateDescription
> > aspeed_i2c_bus_vmstate = {
> >
> > static const VMStateDescription aspeed_i2c_vmstate = {
> > .name = TYPE_ASPEED_I2C,
> > - .version_id = 3,
> > - .minimum_version_id = 3,
> > + .version_id = 4,
> > + .minimum_version_id = 4,
> > .fields = (const VMStateField[]) {
> > VMSTATE_UINT32(intr_status, AspeedI2CState),
> > VMSTATE_STRUCT_ARRAY(busses, AspeedI2CState, @@
> -1250,37
> > +1250,37 @@ static void aspeed_i2c_instance_init(Object *obj)
> > * Address Definitions (AST2700)
> > * 0x000 ... 0x0FF: Global Register
> > * 0x100 ... 0x19F: Device 0
> > - * 0x1A0 ... 0x1BF: Device 0 buffer
> > + * 0x1C0 ... 0x1FF: Device 0 buffer
> > * 0x200 ... 0x29F: Device 1
> > - * 0x2A0 ... 0x2BF: Device 1 buffer
> > + * 0x2C0 ... 0x2FF: Device 1 buffer
> > * 0x300 ... 0x39F: Device 2
> > - * 0x3A0 ... 0x3BF: Device 2 buffer
> > + * 0x3C0 ... 0x3FF: Device 2 buffer
> > * 0x400 ... 0x49F: Device 3
> > - * 0x4A0 ... 0x4BF: Device 3 buffer
> > + * 0x4C0 ... 0x4FF: Device 3 buffer
> > * 0x500 ... 0x59F: Device 4
> > - * 0x5A0 ... 0x5BF: Device 4 buffer
> > + * 0x5C0 ... 0x5FF: Device 4 buffer
> > * 0x600 ... 0x69F: Device 5
> > - * 0x6A0 ... 0x6BF: Device 5 buffer
> > + * 0x6C0 ... 0x6FF: Device 5 buffer
> > * 0x700 ... 0x79F: Device 6
> > - * 0x7A0 ... 0x7BF: Device 6 buffer
> > + * 0x7C0 ... 0x7FF: Device 6 buffer
> > * 0x800 ... 0x89F: Device 7
> > - * 0x8A0 ... 0x8BF: Device 7 buffer
> > + * 0x8C0 ... 0x8FF: Device 7 buffer
> > * 0x900 ... 0x99F: Device 8
> > - * 0x9A0 ... 0x9BF: Device 8 buffer
> > + * 0x9C0 ... 0x9FF: Device 8 buffer
> > * 0xA00 ... 0xA9F: Device 9
> > - * 0xAA0 ... 0xABF: Device 9 buffer
> > + * 0xAC0 ... 0xAFF: Device 9 buffer
> > * 0xB00 ... 0xB9F: Device 10
> > - * 0xBA0 ... 0xBBF: Device 10 buffer
> > + * 0xBC0 ... 0xBFF: Device 10 buffer
> > * 0xC00 ... 0xC9F: Device 11
> > - * 0xCA0 ... 0xCBF: Device 11 buffer
> > + * 0xCC0 ... 0xCFF: Device 11 buffer
> > * 0xD00 ... 0xD9F: Device 12
> > - * 0xDA0 ... 0xDBF: Device 12 buffer
> > + * 0xDC0 ... 0xDFF: Device 12 buffer
> > * 0xE00 ... 0xE9F: Device 13
> > - * 0xEA0 ... 0xEBF: Device 13 buffer
> > + * 0xEC0 ... 0xEFF: Device 13 buffer
> > * 0xF00 ... 0xF9F: Device 14
> > - * 0xFA0 ... 0xFBF: Device 14 buffer
> > + * 0xFC0 ... 0xFFF: Device 14 buffer
> > * 0x1000 ... 0x109F: Device 15
> > - * 0x10A0 ... 0x10BF: Device 15 buffer
> > + * 0x10C0 ... 0x10BF: Device 15 buffer
> > */
> > static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
> > {
> > @@ -1666,9 +1666,9 @@ static void
> aspeed_2700_i2c_class_init(ObjectClass *klass, const void *data)
> > aic->reg_gap_size = 0x60;
> > aic->gap = -1; /* no gap */
> > aic->bus_get_irq = aspeed_2600_i2c_bus_get_irq;
> > - aic->pool_size = 0x20;
> > - aic->pool_gap_size = 0xe0;
> > - aic->pool_base = 0x1a0;
> > + aic->pool_size = 0x40;
> > + aic->pool_gap_size = 0xc0;
> > + aic->pool_base = 0x1c0;
> > aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
> > aic->has_dma = true;
> > aic->mem_size = 0x2000;
^ permalink raw reply [flat|nested] 19+ messages in thread
* RE: [PATCH v2 08/10] hw/arm/aspeed_ast1040: Introduce I2C support
2026-06-02 6:33 ` Cédric Le Goater
@ 2026-06-02 8:41 ` Jamin Lin
0 siblings, 0 replies; 19+ messages in thread
From: Jamin Lin @ 2026-06-02 8:41 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Kane Chen, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Troy Lee
Hi Cédric,
> Subject: Re: [PATCH v2 08/10] hw/arm/aspeed_ast1040: Introduce I2C support
>
> On 6/2/26 07:28, Jamin Lin wrote:
> > Introduce I2C controller support for the AST1040 SoC model.
> >
> > The I2C model type is selected from the SoC type name, allowing the
> > AST1040 SoC to use the corresponding aspeed.i2c-ast1040 model.
> >
> > The I2C controller is mapped at 0x74C0F000 and uses IRQs
> > 64 - 77, with one IRQ assigned per I2C bus.
>
> 64 - 79. The irqmap array needs a change too.
>
Sorry, that's my mistake.
After checking the AST1040 datasheet, I confirmed that the AST1040 I2C controller supports 14 buses.
Therefore, the IRQ range should indeed be 64 - 77, with one IRQ assigned to each bus.
I'll update the patch accordingly and set the I2C bus count to 14 (devices 0 - 13).
https://patchwork.kernel.org/project/qemu-devel/patch/20260602052827.1535299-8-jamin_lin@aspeedtech.com/
Thanks for catching this.
Jamin
> >
> > The controller DRAM link is connected to SRAM1 (HyperRAM) for DMA
> > support.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> > hw/arm/aspeed_ast1040.c | 16 ++++++++++++++++
> > 1 file changed, 16 insertions(+)
> >
> > diff --git a/hw/arm/aspeed_ast1040.c b/hw/arm/aspeed_ast1040.c index
> > 77211ce1f3..6d1cb9b102 100644
> > --- a/hw/arm/aspeed_ast1040.c
> > +++ b/hw/arm/aspeed_ast1040.c
> > @@ -117,6 +117,7 @@ static void aspeed_soc_ast1040_init(Object *obj)
> > object_initialize_child(obj, "sgpio[*]", &s->sgpiom[i],
> > "aspeed.sgpio-ast2700");
> > }
> > + object_initialize_child(obj, "i2c", &s->i2c,
> > + TYPE_ASPEED_1040_I2C);
> >
> > object_initialize_child(obj, "pwm", &s->pwm,
> TYPE_UNIMPLEMENTED_DEVICE);
> > object_initialize_child(obj, "espi", &s->espi,
> > TYPE_UNIMPLEMENTED_DEVICE); @@ -233,6 +234,21 @@ static void
> aspeed_soc_ast1040_realize(DeviceState *dev_soc, Error **errp)
> > aspeed_soc_ast1040_get_irq(s,
> ASPEED_DEV_SGPIOM0 + i));
> > }
> >
> > + /* I2C */
> > + object_property_set_link(OBJECT(&s->i2c), "dram",
> OBJECT(&s->sram[1]),
> > + &error_abort);
> > + if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) {
> > + return;
> > + }
> > + aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&s->i2c), 0,
> > + sc->memmap[ASPEED_DEV_I2C]);
> > + for (i = 0; i < ASPEED_I2C_GET_CLASS(&s->i2c)->num_busses; i++) {
> > + qemu_irq irq = qdev_get_gpio_in(DEVICE(&a->armv7m),
> > +
> sc->irqmap[ASPEED_DEV_I2C] + i);
> > + /* The AST1040 I2C controller has one IRQ per bus. */
> > + sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c.busses[i]), 0, irq);
> > + }
> > +
> > /* Unimplemented peripherals */
> > aspeed_mmio_map_unimplemented(s->memory,
> SYS_BUS_DEVICE(&s->pwm),
> > "aspeed.pwm",
^ permalink raw reply [flat|nested] 19+ messages in thread
* RE: [PATCH v2 09/10] hw/arm/aspeed_ast1040_evb: Introduce onboard I2C device
2026-06-02 6:34 ` Cédric Le Goater
@ 2026-06-03 1:31 ` Jamin Lin
0 siblings, 0 replies; 19+ messages in thread
From: Jamin Lin @ 2026-06-03 1:31 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Kane Chen, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Troy Lee
Hi Cédric
> Subject: Re: [PATCH v2 09/10] hw/arm/aspeed_ast1040_evb: Introduce
> onboard I2C device
>
> On 6/2/26 07:28, Jamin Lin wrote:
> > Introduce onboard I2C device initialization for the AST1040 EVB model.
> >
> > This change adds the initial onboard I2C device setup flow and
> > instantiates a 24C08 SMBus EEPROM device connected to I2C bus 0,
> > matching the current AST1040 EVB hardware design.
> >
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> > hw/arm/aspeed_ast1040_evb.c | 18 ++++++++++++++++++
> > 1 file changed, 18 insertions(+)
> >
> > diff --git a/hw/arm/aspeed_ast1040_evb.c b/hw/arm/aspeed_ast1040_evb.c
> > index 1d9b55247f..66f08ccbe6 100644
> > --- a/hw/arm/aspeed_ast1040_evb.c
> > +++ b/hw/arm/aspeed_ast1040_evb.c
> > @@ -14,6 +14,7 @@
> > #include "hw/arm/aspeed_soc.h"
> > #include "hw/core/qdev-clock.h"
> > #include "system/system.h"
> > +#include "hw/i2c/smbus_eeprom.h"
> >
> > #define AST1040_INTERNAL_FLASH_SIZE (4 * MiB)
> > /* Main SYSCLK frequency in Hz (400MHz) */ @@ -38,12 +39,28 @@
> > static void aspeed_bic_machine_init(MachineState *machine)
> > aspeed_connect_serial_hds_to_uarts(bmc);
> > qdev_realize(DEVICE(bmc->soc), NULL, &error_abort);
> >
> > + if (amc->i2c_init) {
> > + amc->i2c_init(bmc);
> > + }
> > +
> > armv7m_load_kernel(ARM_CPU(first_cpu),
> > machine->kernel_filename,
> > 0,
> > AST1040_INTERNAL_FLASH_SIZE);
> > }
> >
> > +static void ast1040_evb_i2c_init(AspeedMachineState *bmc) {
> > + AspeedSoCState *soc = bmc->soc;
> > +
> > + /* U10 24C08 connects to SDA/SCL Group 1 by default */
> > + uint8_t *eeprom_buf = g_malloc0(32 * KiB);
>
I will change it to 256 in v3.
If you would prefer to use SMBUS_EEPROM_SIZE, I can handle that in a separate cleanup patch series:
Move #define SMBUS_EEPROM_SIZE 256 to include/hw/i2c/smbus_eeprom.h.
Update the ASPEED machine models to use SMBUS_EEPROM_SIZE instead of hard-coded EEPROM buffer sizes.
I also noticed that several ASPEED machine models currently use inconsistent EEPROM sizes:
hw/arm/aspeed_ast1040_evb.c: SMBUS_EEPROM_SIZE
hw/arm/aspeed_ast2500_supermicro-x11spi.c: 32 * 1024
hw/arm/aspeed_ast2400_supermicrox11.c: 32 * 1024
hw/arm/aspeed_ast2500_evb.c: 8 * 1024
hw/arm/aspeed_ast10x0_evb.c: 32 * 1024
hw/arm/aspeed_ast2600_evb.c: 8 * 1024
hw/arm/aspeed_ast2400_palmetto.c: 32 * 1024
hw/arm/aspeed_ast2500_witherspoon.c: 8 * 1024
Do you mean that we should update all of these ASPEED machine models to use:
uint8_t *eeprom_buf = g_malloc0(SMBUS_EEPROM_SIZE);
instead of the current hard-coded sizes?
Thanks,
Jamin
>
> The smbus-eeprom device's internal buffer is 256 bytes.
>
> We have been copy/pasting this 32 * KiB size for a while it seems but
> SMBUS_EEPROM_SIZE would be enough.
>
> Anyhow,
>
>
> Reviewed-by: Cédric Le Goater <clg@redhat.com>
>
> Thanks,
>
> C.
>
>
>
> > + smbus_eeprom_init_one(aspeed_i2c_get_bus(&soc->i2c, 0), 0x50,
> > + eeprom_buf);
> > +
> > + /* U11 LM75 connects to SDA/SCL Group 2 by default */
> > + i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 1),
> > +"tmp105", 0x4d); }
> > +
> > static void aspeed_machine_ast1040_evb_class_init(ObjectClass *oc,
> > const void
> *data)
> > {
> > @@ -55,6 +72,7 @@ static void
> aspeed_machine_ast1040_evb_class_init(ObjectClass *oc,
> > amc->hw_strap1 = 0;
> > amc->hw_strap2 = 0;
> > mc->init = aspeed_bic_machine_init;
> > + amc->i2c_init = ast1040_evb_i2c_init;
> > mc->default_ram_size = 0;
> > amc->macs_mask = 0;
> > amc->uart_default = ASPEED_DEV_UART12;
^ permalink raw reply [flat|nested] 19+ messages in thread
* RE: [PATCH v2 01/10] hw/i2c/aspeed_i2c: Introduce dma_addr_lo_mask to unify DMA address handling
2026-06-02 6:26 ` Cédric Le Goater
@ 2026-06-03 2:58 ` Jamin Lin
0 siblings, 0 replies; 19+ messages in thread
From: Jamin Lin @ 2026-06-03 2:58 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Kane Chen, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Troy Lee
Hi Cédric
> Subject: Re: [PATCH v2 01/10] hw/i2c/aspeed_i2c: Introduce
> dma_addr_lo_mask to unify DMA address handling
>
> On 6/2/26 07:28, Jamin Lin wrote:
> > The Aspeed I2C controller has two register layouts.
> >
> > The AST2500 uses the old mode with a single DMA address register
> > (I2CD_DMA_ADDR) where the address is 4-byte aligned and masked to
> 0x3ffffffc.
> >
> > From AST2600 onwards, the new mode provides separate master TX/RX
> and
> > slave RX DMA address registers (I2CM_DMA_TX_ADDR,
> I2CM_DMA_RX_ADDR,
> > I2CS_DMA_RX_ADDR) with different address widths per SoC:
> > AST2600 (new mode): 0x7fffffff - bits[30:0]
> > AST1030 (new mode): 0x7fffffff - bits[30:0]
> > AST1060 (new mode): 0x7fffffff - bits[30:0]
> > AST2700 (new mode): 0xffffffff - bits[31:0]
> >
> > Introduce dma_addr_lo_mask as a per-class attribute and apply it
> > uniformly when storing DMA address register writes and when loading
> > the address into dma_dram_offset for both master and slave paths.
> > This replaces the previous FIELD_EX32 extractions (which incorrectly
> > stripped bit 31 on AST2700) and the hardcoded 0x3ffffffc literal in
> > the old-mode path.
> >
> > Fixes: 1809ab6a67359e0876981cd05d2a50b2843eabad ("hw/i2c/aspeed:
> Add
> > AST2700 support")
> > Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
> > ---
> > include/hw/i2c/aspeed_i2c.h | 5 +----
> > hw/i2c/aspeed_i2c.c | 22 +++++++++++++---------
> > 2 files changed, 14 insertions(+), 13 deletions(-)
>
> aspeed_i2c_bus_new_write() still has :
>
> case A_I2CS_DMA_RX_ADDR:
> bus->regs[R_I2CS_DMA_RX_ADDR] = value;
>
> Is that ok ?
>
Thanks for the review and suggestion.
Will add.
Jamin
> Thanks,
>
> C.
>
>
> >
> > diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
> > index d42cb4865a..1fc229f699 100644
> > --- a/include/hw/i2c/aspeed_i2c.h
> > +++ b/include/hw/i2c/aspeed_i2c.h
> > @@ -209,13 +209,9 @@ REG32(I2CS_DMA_LEN, 0x2c)
> > FIELD(I2CS_DMA_LEN, TX_BUF_LEN_W1T, 15, 1)
> > FIELD(I2CS_DMA_LEN, TX_BUF_LEN, 0, 11)
> > REG32(I2CM_DMA_TX_ADDR, 0x30)
> > - FIELD(I2CM_DMA_TX_ADDR, ADDR, 0, 31)
> > REG32(I2CM_DMA_RX_ADDR, 0x34)
> > - FIELD(I2CM_DMA_RX_ADDR, ADDR, 0, 31)
> > REG32(I2CS_DMA_TX_ADDR, 0x38)
> > - FIELD(I2CS_DMA_TX_ADDR, ADDR, 0, 31)
> > REG32(I2CS_DMA_RX_ADDR, 0x3c)
> > - FIELD(I2CS_DMA_RX_ADDR, ADDR, 0, 31)
> > REG32(I2CS_DEV_ADDR, 0x40)
> > REG32(I2CM_DMA_LEN_STS, 0x48)
> > FIELD(I2CM_DMA_LEN_STS, RX_LEN, 16, 13) @@ -303,6 +299,7 @@
> > struct AspeedI2CClass {
> > bool has_share_pool;
> > uint64_t mem_size;
> > bool has_dma64;
> > + uint32_t dma_addr_lo_mask;
> > };
> >
> > static inline bool aspeed_i2c_is_new_mode(AspeedI2CState *s) diff
> > --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c index
> > 4a6732a185..a6b44174f5 100644
> > --- a/hw/i2c/aspeed_i2c.c
> > +++ b/hw/i2c/aspeed_i2c.c
> > @@ -236,7 +236,7 @@ static void
> aspeed_i2c_set_tx_dma_dram_offset(AspeedI2CBus *bus)
> > value = bus->regs[R_I2CM_DMA_TX_ADDR];
> > bus->dma_dram_offset =
> > deposit64(bus->dma_dram_offset, 0, 32,
> > - FIELD_EX32(value, I2CM_DMA_TX_ADDR,
> ADDR));
> > + value & aic->dma_addr_lo_mask);
> > if (aic->has_dma64) {
> > value = bus->regs[R_I2CM_DMA_TX_ADDR_HI];
> > bus->dma_dram_offset =
> > @@ -246,7 +246,7 @@ static void
> aspeed_i2c_set_tx_dma_dram_offset(AspeedI2CBus *bus)
> > } else {
> > value = bus->regs[R_I2CD_DMA_ADDR];
> > bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0,
> 32,
> > - value & 0x3ffffffc);
> > + value &
> > + aic->dma_addr_lo_mask);
> > }
> > }
> >
> > @@ -261,7 +261,7 @@ static void
> aspeed_i2c_set_rx_dma_dram_offset(AspeedI2CBus *bus)
> > value = bus->regs[R_I2CM_DMA_RX_ADDR];
> > bus->dma_dram_offset =
> > deposit64(bus->dma_dram_offset, 0, 32,
> > - FIELD_EX32(value, I2CM_DMA_RX_ADDR,
> ADDR));
> > + value & aic->dma_addr_lo_mask);
> > if (aic->has_dma64) {
> > value = bus->regs[R_I2CM_DMA_RX_ADDR_HI];
> > bus->dma_dram_offset =
> > @@ -271,7 +271,7 @@ static void
> aspeed_i2c_set_rx_dma_dram_offset(AspeedI2CBus *bus)
> > } else {
> > value = bus->regs[R_I2CD_DMA_ADDR];
> > bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0,
> 32,
> > - value & 0x3ffffffc);
> > + value &
> > + aic->dma_addr_lo_mask);
> > }
> > }
> >
> > @@ -735,12 +735,10 @@ static void
> aspeed_i2c_bus_new_write(AspeedI2CBus *bus, hwaddr offset,
> > aspeed_i2c_bus_raise_interrupt(bus);
> > break;
> > case A_I2CM_DMA_TX_ADDR:
> > - bus->regs[R_I2CM_DMA_TX_ADDR] = FIELD_EX32(value,
> I2CM_DMA_TX_ADDR,
> > - ADDR);
> > + bus->regs[R_I2CM_DMA_TX_ADDR] = value &
> > + aic->dma_addr_lo_mask;
> > break;
> > case A_I2CM_DMA_RX_ADDR:
> > - bus->regs[R_I2CM_DMA_RX_ADDR] = FIELD_EX32(value,
> I2CM_DMA_RX_ADDR,
> > - ADDR);
> > + bus->regs[R_I2CM_DMA_RX_ADDR] = value &
> > + aic->dma_addr_lo_mask;
> > break;
> > case A_I2CM_DMA_LEN:
> > w1t = FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN_W1T)
> || @@
> > -1375,6 +1373,8 @@ static void aspeed_i2c_class_init(ObjectClass *klass,
> const void *data)
> > static int aspeed_i2c_bus_new_slave_event(AspeedI2CBus *bus,
> > enum i2c_event
> event)
> > {
> > + AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
> > +
> > switch (event) {
> > case I2C_START_SEND_ASYNC:
> > if (!SHARED_ARRAY_FIELD_EX32(bus->regs, R_I2CS_CMD,
> > RX_DMA_EN)) { @@ -1385,7 +1385,7 @@ static int
> aspeed_i2c_bus_new_slave_event(AspeedI2CBus *bus,
> > ARRAY_FIELD_DP32(bus->regs, I2CS_DMA_LEN_STS, RX_LEN,
> 0);
> > bus->dma_dram_offset =
> > deposit64(bus->dma_dram_offset, 0, 32,
> > - ARRAY_FIELD_EX32(bus->regs,
> I2CS_DMA_RX_ADDR, ADDR));
> > + bus->regs[R_I2CS_DMA_RX_ADDR] &
> > + aic->dma_addr_lo_mask);
> > bus->regs[R_I2CC_DMA_LEN] =
> > ARRAY_FIELD_EX32(bus->regs, I2CS_DMA_LEN,
> RX_BUF_LEN) + 1;
> > i2c_ack(bus->bus);
> > @@ -1608,6 +1608,7 @@ static void
> aspeed_2500_i2c_class_init(ObjectClass *klass, const void *data)
> > aic->check_sram = true;
> > aic->has_dma = true;
> > aic->mem_size = 0x1000;
> > + aic->dma_addr_lo_mask = 0x3ffffffc;
> > }
> >
> > static qemu_irq aspeed_2600_i2c_bus_get_irq(AspeedI2CBus *bus) @@
> > -1631,6 +1632,7 @@ static void aspeed_2600_i2c_class_init(ObjectClass
> *klass, const void *data)
> > aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
> > aic->has_dma = true;
> > aic->mem_size = 0x1000;
> > + aic->dma_addr_lo_mask = 0x7fffffff;
> > }
> >
> > static void aspeed_1030_i2c_class_init(ObjectClass *klass, const
> > void *data) @@ -1649,6 +1651,7 @@ static void
> aspeed_1030_i2c_class_init(ObjectClass *klass, const void *data)
> > aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
> > aic->has_dma = true;
> > aic->mem_size = 0x10000;
> > + aic->dma_addr_lo_mask = 0x7fffffff;
> > }
> >
> > static void aspeed_2700_i2c_class_init(ObjectClass *klass, const
> > void *data) @@ -1670,6 +1673,7 @@ static void
> aspeed_2700_i2c_class_init(ObjectClass *klass, const void *data)
> > aic->has_dma = true;
> > aic->mem_size = 0x2000;
> > aic->has_dma64 = true;
> > + aic->dma_addr_lo_mask = 0xffffffff;
> > }
> >
> > static const TypeInfo aspeed_i2c_types[] = {
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2026-06-03 2:59 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-02 5:28 [PATCH v2 00/10] hw/arm/aspeed: Add AST1040 peripheral support Jamin Lin
2026-06-02 5:28 ` [PATCH v2 01/10] hw/i2c/aspeed_i2c: Introduce dma_addr_lo_mask to unify DMA address handling Jamin Lin
2026-06-02 6:26 ` Cédric Le Goater
2026-06-03 2:58 ` Jamin Lin
2026-06-02 5:28 ` [PATCH v2 02/10] hw/i2c/aspeed_i2c: Increase AST2700 buffer mode size and adjust offset Jamin Lin
2026-06-02 6:33 ` Cédric Le Goater
2026-06-02 8:22 ` Jamin Lin
2026-06-02 5:28 ` [PATCH v2 03/10] hw/arm/aspeed_ast1040: Reuse AST2700 ADC model Jamin Lin
2026-06-02 5:28 ` [PATCH v2 04/10] hw/arm/aspeed_ast1040: Introduce PECI support Jamin Lin
2026-06-02 5:28 ` [PATCH v2 05/10] hw/arm/aspeed_ast1040: Reuse AST2700 GPIO controller model Jamin Lin
2026-06-02 5:28 ` [PATCH v2 06/10] hw/arm/aspeed_ast1040: Add SGPIO controller support Jamin Lin
2026-06-02 5:28 ` [PATCH v2 07/10] hw/i2c/aspeed_i2c: Introduce AST1040 I2C model Jamin Lin
2026-06-02 5:28 ` [PATCH v2 08/10] hw/arm/aspeed_ast1040: Introduce I2C support Jamin Lin
2026-06-02 6:33 ` Cédric Le Goater
2026-06-02 8:41 ` Jamin Lin
2026-06-02 5:28 ` [PATCH v2 09/10] hw/arm/aspeed_ast1040_evb: Introduce onboard I2C device Jamin Lin
2026-06-02 6:34 ` Cédric Le Goater
2026-06-03 1:31 ` Jamin Lin
2026-06-02 5:28 ` [PATCH v2 10/10] hw/arm/aspeed_ast1040: Reuse AST2700 watchdog models Jamin Lin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.