@samitouri / QOSamiQemu / commits / dba6f5c1df

hw/arm/ast27x0: Share single SCUIO instance across PSP, SSP, and TSP

AST2700 has a single SCUIO hardware block, memory-mapped at 0x14C02000–0x14C03FFF from the perspective of the main CA35 processor (PSP). The SSP and TSP coprocessors access this same SCUIO block at different addresses: 0x74C02000–0x74C03FFF. Previously, each subsystem (PSP, SSP, and TSP) instantiated its own SCUIO device, resulting in three independent SCUIO instances in the QEMU model. In real hardware, however, only a single SCUIO exists and is shared among all processors. This commit reworks the SCUIO model to correctly reflect the hardware behavior by allowing SSP and TSP to reference the PSP’s SCUIO instance. The following changes are introduced: - Add a scuio property to Aspeed27x0CoprocessorState for linking the coprocessor to the PSP’s SCUIO instance. - Replace per-coprocessor SCUIO instantiation with a shared SCUIO link. - Add "MemoryRegion scuio_alias" to model address remapping for SSP and TSP. - Create SCUIO alias regions in both SSP and TSP coprocessors and map them at 0x74C02000 to mirror the PSP’s SCUIO registers. - Ensure the SCUIO device in PSP is realized before SSP/TSP alias setup. With this change, PSP, SSP, and TSP now share a consistent SCUIO state, matching the single-SCUIO hardware design of AST2700. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Tested-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Link: https://lore.kernel.org/qemu-devel/20260717084559.3477061-7-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com>

Jamin Lin committed Jul 17, 2026 at 08:46 UTC dba6f5c1df462830bf6daa82d7c08c34f76cc164
4 files changed +36 -12
hw/arm/aspeed_ast27x0-fc.c
+4
@@ -157,6 +157,8 @@ static bool ast2700fc_ssp_init(Ast2700FCState *s, AspeedSoCState *psp,
157 OBJECT(&psp->sram), &error_abort);
158 object_property_set_link(OBJECT(&s->ssp), "scu",
159 OBJECT(&s->ca35.scu), &error_abort);
160 + object_property_set_link(OBJECT(&s->ssp), "scuio",
161 + OBJECT(&psp->scuio), &error_abort);
162 if (!qdev_realize(DEVICE(&s->ssp), NULL, errp)) {
163 return false;
164 }
@@ -187,6 +189,8 @@ static bool ast2700fc_tsp_init(Ast2700FCState *s, AspeedSoCState *psp,
189 OBJECT(&psp->sram), &error_abort);
190 object_property_set_link(OBJECT(&s->tsp), "scu",
191 OBJECT(&s->ca35.scu), &error_abort);
192 + object_property_set_link(OBJECT(&s->tsp), "scuio",
193 + OBJECT(&psp->scuio), &error_abort);
194 if (!qdev_realize(DEVICE(&s->tsp), NULL, errp)) {
195 return false;
196 }
hw/arm/aspeed_ast27x0-ssp.c
+15 -5
@@ -142,8 +142,6 @@ static void aspeed_soc_ast27x0ssp_init(Object *obj)
142 TYPE_UNIMPLEMENTED_DEVICE);
143 object_initialize_child(obj, "ipc1", &a->ipc[1],
144 TYPE_UNIMPLEMENTED_DEVICE);
145 - object_initialize_child(obj, "scuio", &a->scuio,
146 - TYPE_UNIMPLEMENTED_DEVICE);
145 object_initialize_child(obj, "pric0", &a->pric[0],
146 TYPE_UNIMPLEMENTED_DEVICE);
147 object_initialize_child(obj, "pric1", &a->pric[1],
@@ -173,6 +171,12 @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp)
171 return;
172 }
173
174 + if (!a->scuio) {
175 + error_setg(errp, TYPE_ASPEED27X0SSP_COPROCESSOR
176 + ": 'scuio' link is not set");
177 + return;
178 + }
179 +
180 /* AST27X0 SSP Core */
181 armv7m = DEVICE(&a->armv7m);
182 qdev_prop_set_uint32(armv7m, "num-irq", 256);
@@ -207,6 +211,13 @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp)
211 memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SCU],
212 &a->scu_alias);
213
214 + /* SCUIO */
215 + memory_region_init_alias(&a->scuio_alias, OBJECT(a), "scuio.alias",
216 + &a->scuio->iomem, 0,
217 + memory_region_size(&a->scuio->iomem));
218 + memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SCUIO],
219 + &a->scuio_alias);
220 +
221 /* INTC */
222 if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc[0]), errp)) {
223 return;
@@ -267,9 +278,6 @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp)
278 aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&a->ipc[1]),
279 "aspeed.ipc1",
280 sc->memmap[ASPEED_DEV_IPC1], 0x1000);
270 - aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&a->scuio),
271 - "aspeed.scuio",
272 - sc->memmap[ASPEED_DEV_SCUIO], 0x1000);
281 aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&a->pric[0]),
282 "aspeed.pric0",
283 sc->memmap[ASPEED_DEV_PRIC0], 0x1000);
@@ -284,6 +292,8 @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp)
292 static const Property aspeed_27x0_coprocessor_properties[] = {
293 DEFINE_PROP_LINK("scu", Aspeed27x0CoprocessorState, scu,
294 TYPE_ASPEED_2700_SCU, Aspeed2700SCUState *),
295 + DEFINE_PROP_LINK("scuio", Aspeed27x0CoprocessorState, scuio,
296 + TYPE_ASPEED_SCU, AspeedSCUState *),
297 };
298
299 static void aspeed_soc_ast27x0ssp_class_init(ObjectClass *klass,
hw/arm/aspeed_ast27x0-tsp.c
+15 -5
@@ -142,8 +142,6 @@ static void aspeed_soc_ast27x0tsp_init(Object *obj)
142 TYPE_UNIMPLEMENTED_DEVICE);
143 object_initialize_child(obj, "ipc1", &a->ipc[1],
144 TYPE_UNIMPLEMENTED_DEVICE);
145 - object_initialize_child(obj, "scuio", &a->scuio,
146 - TYPE_UNIMPLEMENTED_DEVICE);
145 object_initialize_child(obj, "pric0", &a->pric[0],
146 TYPE_UNIMPLEMENTED_DEVICE);
147 object_initialize_child(obj, "pric1", &a->pric[1],
@@ -173,6 +171,12 @@ static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp)
171 return;
172 }
173
174 + if (!a->scuio) {
175 + error_setg(errp, TYPE_ASPEED27X0TSP_COPROCESSOR
176 + ": 'scuio' link is not set");
177 + return;
178 + }
179 +
180 /* AST27X0 TSP Core */
181 armv7m = DEVICE(&a->armv7m);
182 qdev_prop_set_uint32(armv7m, "num-irq", 256);
@@ -207,6 +211,13 @@ static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp)
211 memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SCU],
212 &a->scu_alias);
213
214 + /* SCUIO */
215 + memory_region_init_alias(&a->scuio_alias, OBJECT(a), "scuio.alias",
216 + &a->scuio->iomem, 0,
217 + memory_region_size(&a->scuio->iomem));
218 + memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SCUIO],
219 + &a->scuio_alias);
220 +
221 /* INTC */
222 if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc[0]), errp)) {
223 return;
@@ -267,9 +278,6 @@ static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp)
278 aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&a->ipc[1]),
279 "aspeed.ipc1",
280 sc->memmap[ASPEED_DEV_IPC1], 0x1000);
270 - aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&a->scuio),
271 - "aspeed.scuio",
272 - sc->memmap[ASPEED_DEV_SCUIO], 0x1000);
281 aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&a->pric[0]),
282 "aspeed.pric0",
283 sc->memmap[ASPEED_DEV_PRIC0], 0x1000);
@@ -284,6 +292,8 @@ static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp)
292 static const Property aspeed_27x0_coprocessor_properties[] = {
293 DEFINE_PROP_LINK("scu", Aspeed27x0CoprocessorState, scu,
294 TYPE_ASPEED_2700_SCU, Aspeed2700SCUState *),
295 + DEFINE_PROP_LINK("scuio", Aspeed27x0CoprocessorState, scuio,
296 + TYPE_ASPEED_SCU, AspeedSCUState *),
297 };
298
299 static void aspeed_soc_ast27x0tsp_class_init(ObjectClass *klass,
include/hw/arm/aspeed_coprocessor.h
+2 -2
@@ -22,7 +22,6 @@ struct AspeedCoprocessorState {
22 MemoryRegion uart_alias;
23 Clock *sysclk;
24
25 - AspeedSCUState scuio;
25 AspeedTimerCtrlState timerctrl;
26 SerialMM *uart;
27 int uart_dev;
@@ -45,14 +44,15 @@ struct Aspeed27x0CoprocessorState {
44 AspeedCoprocessorState parent;
45 AspeedINTCState intc[2];
46 UnimplementedDeviceState ipc[2];
48 - UnimplementedDeviceState scuio;
47 UnimplementedDeviceState pric[2];
48 UnimplementedDeviceState otp;
49
50 ARMv7MState armv7m;
51
52 MemoryRegion scu_alias;
53 + MemoryRegion scuio_alias;
54 Aspeed2700SCUState *scu;
55 + AspeedSCUState *scuio;
56 };
57
58 #define TYPE_ASPEED27X0SSP_COPROCESSOR "aspeed27x0ssp-coprocessor"