hw/intc/arm_gicv5: Implement IRS ID regs
Implement the IRS frame ID registers IRS_IDR[0-7], IRS_IIDR and IRS_AIDR. These are all 32-bit registers. We make these fields in the GIC state struct rather than just hardcoding them in the register read function so that we can later code "do this only if X is implemented" as a test on the ID register value. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20260327111700.795099-11-peter.maydell@linaro.org
Peter Maydell committed
Mar 27, 2026 at 11:16 UTC
405ad2e76f13254b57f25bfc965bd8f532e729f8
2 files changed
+154
hw/intc/arm_gicv5.c
+115
@@ -268,6 +268,65 @@ REG64(IRS_SWERR_SYNDROMER1, 0x3d0)
268
static bool config_readl(GICv5 *s, GICv5Domain domain, hwaddr offset,
269
uint64_t *data, MemTxAttrs attrs)
270
{
271
+ GICv5Common *cs = ARM_GICV5_COMMON(s);
272
+ uint32_t v = 0;
273
+
274
+ switch (offset) {
275
+ case A_IRS_IDR0:
276
+ v = cs->irs_idr0;
277
+ /* INT_DOM reports the domain this register is for */
278
+ v = FIELD_DP32(v, IRS_IDR0, INT_DOM, domain);
279
+ if (domain != GICV5_ID_REALM) {
280
+ /* MEC field RES0 except for the Realm domain */
281
+ v &= ~R_IRS_IDR0_MEC_MASK;
282
+ }
283
+ if (domain == GICV5_ID_EL3) {
284
+ /* VIRT is RES0 for EL3 domain */
285
+ v &= ~R_IRS_IDR0_VIRT_MASK;
286
+ /* ...which means VIRT_ONE_N is also RES0 */
287
+ v &= ~R_IRS_IDR0_VIRT_ONE_N_MASK;
288
+ }
289
+ return true;
290
+
291
+ case A_IRS_IDR1:
292
+ *data = cs->irs_idr1;
293
+ return true;
294
+
295
+ case A_IRS_IDR2:
296
+ *data = cs->irs_idr2;
297
+ return true;
298
+
299
+ case A_IRS_IDR3:
300
+ /* In EL3 IDR0.VIRT is 0 so this is RES0 */
301
+ *data = domain == GICV5_ID_EL3 ? 0 : cs->irs_idr3;
302
+ return true;
303
+
304
+ case A_IRS_IDR4:
305
+ /* In EL3 IDR0.VIRT is 0 so this is RES0 */
306
+ *data = domain == GICV5_ID_EL3 ? 0 : cs->irs_idr4;
307
+ return true;
308
+
309
+ case A_IRS_IDR5:
310
+ *data = cs->irs_idr5;
311
+ return true;
312
+
313
+ case A_IRS_IDR6:
314
+ *data = cs->irs_idr6;
315
+ return true;
316
+
317
+ case A_IRS_IDR7:
318
+ *data = cs->irs_idr7;
319
+ return true;
320
+
321
+ case A_IRS_IIDR:
322
+ *data = cs->irs_iidr;
323
+ return true;
324
+
325
+ case A_IRS_AIDR:
326
+ *data = cs->irs_aidr;
327
+ return true;
328
+ }
329
+
330
return false;
331
}
332
@@ -422,6 +481,60 @@ static void gicv5_reset_hold(Object *obj, ResetType type)
481
}
482
}
483
484
+static void gicv5_set_idregs(GICv5Common *cs)
485
+{
486
+ /* Set the ID register value fields */
487
+ uint32_t v;
488
+
489
+ /*
490
+ * Fields in IDR0 for optional parts of the spec that we don't
491
+ * implement are 0.
492
+ */
493
+ v = 0;
494
+ /*
495
+ * We can handle physical addresses of any size, so report support
496
+ * for 56 bits of physical address space.
497
+ */
498
+ v = FIELD_DP32(v, IRS_IDR0, PA_RANGE, 7);
499
+ v = FIELD_DP32(v, IRS_IDR0, IRSID, cs->irsid);
500
+ cs->irs_idr0 = v;
501
+
502
+ v = 0;
503
+ v = FIELD_DP32(v, IRS_IDR1, PE_CNT, cs->num_cpus);
504
+ v = FIELD_DP32(v, IRS_IDR1, IAFFID_BITS, QEMU_GICV5_IAFFID_BITS - 1);
505
+ v = FIELD_DP32(v, IRS_IDR1, PRI_BITS, QEMU_GICV5_PRI_BITS - 1);
506
+ cs->irs_idr1 = v;
507
+
508
+ v = 0;
509
+ /* We always support physical LPIs with 2-level ISTs of all sizes */
510
+ v = FIELD_DP32(v, IRS_IDR2, ID_BITS, QEMU_GICV5_ID_BITS);
511
+ v = FIELD_DP32(v, IRS_IDR2, LPI, 1);
512
+ v = FIELD_DP32(v, IRS_IDR2, MIN_LPI_ID_BITS, QEMU_GICV5_MIN_LPI_ID_BITS);
513
+ v = FIELD_DP32(v, IRS_IDR2, IST_LEVELS, 1);
514
+ v = FIELD_DP32(v, IRS_IDR2, IST_L2SZ, 7);
515
+ /* Our impl does not need IST metadata, so ISTMD and ISTMD_SZ are 0 */
516
+ cs->irs_idr2 = v;
517
+
518
+ /* We don't implement virtualization yet, so these are zero */
519
+ cs->irs_idr3 = 0;
520
+ cs->irs_idr4 = 0;
521
+
522
+ /* These three have just one field each */
523
+ cs->irs_idr5 = FIELD_DP32(0, IRS_IDR5, SPI_RANGE, cs->spi_range);
524
+ cs->irs_idr6 = FIELD_DP32(0, IRS_IDR6, SPI_IRS_RANGE, cs->spi_irs_range);
525
+ cs->irs_idr7 = FIELD_DP32(0, IRS_IDR7, SPI_BASE, cs->spi_base);
526
+
527
+ v = 0;
528
+ v = FIELD_DP32(v, IRS_IIDR, IMPLEMENTER, QEMU_GICV5_IMPLEMENTER);
529
+ v = FIELD_DP32(v, IRS_IIDR, REVISION, QEMU_GICV5_REVISION);
530
+ v = FIELD_DP32(v, IRS_IIDR, VARIANT, QEMU_GICV5_VARIANT);
531
+ v = FIELD_DP32(v, IRS_IIDR, PRODUCTID, QEMU_GICV5_PRODUCTID);
532
+ cs->irs_iidr = v;
533
+
534
+ /* This is a GICv5.0 IRS, so all fields are zero */
535
+ cs->irs_aidr = 0;
536
+}
537
+
538
static void gicv5_realize(DeviceState *dev, Error **errp)
539
{
540
GICv5Common *cs = ARM_GICV5_COMMON(dev);
@@ -448,6 +561,8 @@ static void gicv5_realize(DeviceState *dev, Error **errp)
561
* NS domain.
562
*/
563
cs->implemented_domains = (1 << GICV5_ID_NS);
564
+
565
+ gicv5_set_idregs(cs);
566
gicv5_common_init_irqs_and_mmio(cs, gicv5_set_spi, config_frame_ops);
567
}
568
include/hw/intc/arm_gicv5_common.h
+39
@@ -65,6 +65,18 @@ struct GICv5Common {
65
/* Bits here are set for each physical interrupt domain implemented */
66
uint8_t implemented_domains;
67
68
+ /* ID register values: set at realize, constant thereafter */
69
+ uint32_t irs_idr0;
70
+ uint32_t irs_idr1;
71
+ uint32_t irs_idr2;
72
+ uint32_t irs_idr3;
73
+ uint32_t irs_idr4;
74
+ uint32_t irs_idr5;
75
+ uint32_t irs_idr6;
76
+ uint32_t irs_idr7;
77
+ uint32_t irs_iidr;
78
+ uint32_t irs_aidr;
79
+
80
/* Properties */
81
uint32_t num_cpus;
82
ARMCPU **cpus;
@@ -84,6 +96,33 @@ struct GICv5CommonClass {
96
97
#define IRS_CONFIG_FRAME_SIZE 0x10000
98
99
+/*
100
+ * The architecture allows a GICv5 to implement less than the full
101
+ * width for various ID fields. QEMU's implementation always supports
102
+ * the full width of these fields. These constants define our
103
+ * implementation's limits.
104
+ */
105
+
106
+/* Number of INTID.ID bits we support */
107
+#define QEMU_GICV5_ID_BITS 24
108
+/* Min LPI_ID_BITS supported */
109
+#define QEMU_GICV5_MIN_LPI_ID_BITS 14
110
+/* IAFFID bits supported */
111
+#define QEMU_GICV5_IAFFID_BITS 16
112
+/* Number of priority bits supported in the IRS */
113
+#define QEMU_GICV5_PRI_BITS 5
114
+
115
+/*
116
+ * There are no TRMs currently published for hardware implementations
117
+ * of GICv5 that we might identify ourselves as. Instead, we borrow
118
+ * the Arm Implementer code and pick a fake product ID that is
119
+ * unlikely to be used by any real Arm hardware.
120
+ */
121
+#define QEMU_GICV5_IMPLEMENTER 0x43b
122
+#define QEMU_GICV5_PRODUCTID 0xfff
123
+#define QEMU_GICV5_REVISION 0
124
+#define QEMU_GICV5_VARIANT 0
125
+
126
/**
127
* gicv5_common_init_irqs_and_mmio: Create IRQs and MMIO regions for the GICv5
128
* @s: GIC object