@samitouri / QOSamiQemu / commits / 64eef0e6c3

hw/misc/mps2-fpgaio.c: add GPIOALT2 register

Add GPIOALT2 register for new an555 board. Implement register access as RW with LOG_UNIMP for writes. Add "has-gpioalt2" property to make each board configurable. Add gpioalt2 vmstate subsection for device state migration. Reviewed-by: Owen Giles <owen.giles@hpe.com> Reviewed-by: Robert Elliott <elliott@hpe.com> Signed-off-by: Simon Xu <simonxhy0404@gmail.com> Message-Id: <20260805153005.9989-10-simonxhy0404@gmail.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Simon Xu committed Aug 17, 2026 at 19:26 UTC 64eef0e6c3bbfd56ed559bad63724c393ecdf684
3 files changed +43
hw/arm/mps2-tz.c
+6
@@ -122,6 +122,7 @@ struct MPS2TZMachineClass {
122 uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
123 bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
124 bool fpgaio_has_dbgctrl; /* Does FPGAIO have DBGCTRL register? */
125 + bool fpgaio_has_gpioalt2; /* Does FPGAIO have GPIOALT2 register? */
126 int numirq; /* Number of external interrupts */
127 int uart_overflow_irq; /* number of the combined UART overflow IRQ */
128 uint32_t init_svtor; /* init-svtor setting for SSE */
@@ -494,6 +495,7 @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
495 qdev_prop_set_uint32(DEVICE(fpgaio), "num-leds", mmc->fpgaio_num_leds);
496 qdev_prop_set_bit(DEVICE(fpgaio), "has-switches", mmc->fpgaio_has_switches);
497 qdev_prop_set_bit(DEVICE(fpgaio), "has-dbgctrl", mmc->fpgaio_has_dbgctrl);
498 + qdev_prop_set_bit(DEVICE(fpgaio), "has-gpioalt2", mmc->fpgaio_has_gpioalt2);
499 sysbus_realize(SYS_BUS_DEVICE(fpgaio), &error_fatal);
500 return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0);
501 }
@@ -1350,6 +1352,7 @@ static void mps2tz_an505_class_init(ObjectClass *oc, const void *data)
1352 mmc->fpgaio_num_leds = 2;
1353 mmc->fpgaio_has_switches = false;
1354 mmc->fpgaio_has_dbgctrl = false;
1355 + mmc->fpgaio_has_gpioalt2 = false;
1356 mmc->numirq = 92;
1357 mmc->uart_overflow_irq = 47;
1358 mmc->init_svtor = 0x10000000;
@@ -1384,6 +1387,7 @@ static void mps2tz_an521_class_init(ObjectClass *oc, const void *data)
1387 mmc->fpgaio_num_leds = 2;
1388 mmc->fpgaio_has_switches = false;
1389 mmc->fpgaio_has_dbgctrl = false;
1390 + mmc->fpgaio_has_gpioalt2 = false;
1391 mmc->numirq = 92;
1392 mmc->uart_overflow_irq = 47;
1393 mmc->init_svtor = 0x10000000;
@@ -1418,6 +1422,7 @@ static void mps3tz_an524_class_init(ObjectClass *oc, const void *data)
1422 mmc->fpgaio_num_leds = 10;
1423 mmc->fpgaio_has_switches = true;
1424 mmc->fpgaio_has_dbgctrl = false;
1425 + mmc->fpgaio_has_gpioalt2 = false;
1426 mmc->numirq = 95;
1427 mmc->uart_overflow_irq = 47;
1428 mmc->init_svtor = 0x10000000;
@@ -1457,6 +1462,7 @@ static void mps3tz_an547_class_init(ObjectClass *oc, const void *data)
1462 mmc->fpgaio_num_leds = 10;
1463 mmc->fpgaio_has_switches = true;
1464 mmc->fpgaio_has_dbgctrl = true;
1465 + mmc->fpgaio_has_gpioalt2 = false;
1466 mmc->numirq = 96;
1467 mmc->uart_overflow_irq = 48;
1468 mmc->init_svtor = 0x00000000;
hw/misc/mps2-fpgaio.c
+35
@@ -31,6 +31,7 @@
31 REG32(LED0, 0)
32 REG32(DBGCTRL, 4)
33 REG32(BUTTON, 8)
34 +REG32(GPIOALT2, 0xc)
35 REG32(CLK1HZ, 0x10)
36 REG32(CLK100HZ, 0x14)
37 REG32(COUNTER, 0x18)
@@ -142,6 +143,9 @@ static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
143 */
144 r = 0;
145 break;
146 + case A_GPIOALT2:
147 + r = s->gpioalt2;
148 + break;
149 case A_PRESCALE:
150 r = s->prescale;
151 break;
@@ -210,6 +214,14 @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
214 "MPS2 FPGAIO: DBGCTRL unimplemented\n");
215 s->dbgctrl = value;
216 break;
217 + case A_GPIOALT2:
218 + if (!s->has_gpioalt2) {
219 + goto bad_offset;
220 + }
221 + qemu_log_mask(LOG_UNIMP,
222 + "MPS2 FPGAIO: GPIOALT2 unimplemented\n");
223 + s->gpioalt2 = value;
224 + break;
225 case A_PRESCALE:
226 resync_counter(s);
227 s->prescale = value;
@@ -301,6 +313,24 @@ static void mps2_fpgaio_realize(DeviceState *dev, Error **errp)
313 }
314 }
315
316 +static bool needed_gpioalt2(void *opaque)
317 +{
318 + MPS2FPGAIO *s = MPS2_FPGAIO(opaque);
319 +
320 + return s->has_gpioalt2;
321 +}
322 +
323 +static const VMStateDescription mps2_fpgaio_gpioalt2_vmstate = {
324 + .name = "mps2-fpgaio/gpioalt2",
325 + .version_id = 1,
326 + .minimum_version_id = 1,
327 + .needed = needed_gpioalt2,
328 + .fields = (const VMStateField[]) {
329 + VMSTATE_UINT32(gpioalt2, MPS2FPGAIO),
330 + VMSTATE_END_OF_LIST()
331 + }
332 +};
333 +
334 static const VMStateDescription mps2_fpgaio_vmstate = {
335 .name = "mps2-fpgaio",
336 .version_id = 3,
@@ -317,6 +347,10 @@ static const VMStateDescription mps2_fpgaio_vmstate = {
347 VMSTATE_INT64(pscntr_sync_ticks, MPS2FPGAIO),
348 VMSTATE_END_OF_LIST()
349 },
350 + .subsections = (const VMStateDescription * const []) {
351 + &mps2_fpgaio_gpioalt2_vmstate,
352 + NULL
353 + }
354 };
355
356 static const Property mps2_fpgaio_properties[] = {
@@ -326,6 +360,7 @@ static const Property mps2_fpgaio_properties[] = {
360 DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
361 DEFINE_PROP_BOOL("has-switches", MPS2FPGAIO, has_switches, false),
362 DEFINE_PROP_BOOL("has-dbgctrl", MPS2FPGAIO, has_dbgctrl, false),
363 + DEFINE_PROP_BOOL("has-gpioalt2", MPS2FPGAIO, has_gpioalt2, false),
364 };
365
366 static void mps2_fpgaio_class_init(ObjectClass *klass, const void *data)
include/hw/misc/mps2-fpgaio.h
+2
@@ -40,11 +40,13 @@ struct MPS2FPGAIO {
40 uint32_t num_leds;
41 bool has_switches;
42 bool has_dbgctrl;
43 + bool has_gpioalt2;
44
45 uint32_t led0;
46 uint32_t prescale;
47 uint32_t misc;
48 uint32_t dbgctrl;
49 + uint32_t gpioalt2;
50
51 /* QEMU_CLOCK_VIRTUAL time at which counter and pscntr were last synced */
52 int64_t pscntr_sync_ticks;