278
}
279
cs->irs_ist_baser[domain] = FIELD_DP64(cs->irs_ist_baser[domain],
280
IRS_IST_BASER, VALID, valid);
281
+ s->phys_lpi_config[domain].valid = false;
282
+ trace_gicv5_ist_invalid(domain_name[domain]);
283
return;
284
}
285
cs->irs_ist_baser[domain] = value;
286
+
287
+ if (FIELD_EX64(cs->irs_ist_baser[domain], IRS_IST_BASER, VALID)) {
288
+ /*
289
+ * If the guest just set VALID then capture data into config struct,
290
+ * sanitize the reserved values, and expand fields out into byte counts.
291
+ */
292
+ GICv5ISTConfig *cfg = &s->phys_lpi_config[domain];
293
+ uint8_t istbits, l2bits, l2_idx_bits;
294
+ uint8_t id_bits = FIELD_EX64(cs->irs_ist_cfgr[domain],
295
+ IRS_IST_CFGR, LPI_ID_BITS);
296
+ id_bits = MIN(MAX(id_bits, QEMU_GICV5_MIN_LPI_ID_BITS), QEMU_GICV5_ID_BITS);
297
+
298
+ switch (FIELD_EX64(cs->irs_ist_cfgr[domain], IRS_IST_CFGR, ISTSZ)) {
299
+ case 0:
300
+ case 3: /* reserved: acts like the minimum required size */
301
+ istbits = 2;
302
+ break;
303
+ case 1:
304
+ istbits = 3;
305
+ break;
306
+ case 2:
307
+ istbits = 4;
308
+ break;
309
+ default:
310
+ g_assert_not_reached();
311
+ }
312
+ switch (FIELD_EX64(cs->irs_ist_cfgr[domain], IRS_IST_CFGR, L2SZ)) {
313
+ case 0:
314
+ case 3: /* reserved; CONSTRAINED UNPREDICTABLE */
315
+ l2bits = 12; /* 4K: 12 bits */
316
+ break;
317
+ case 1:
318
+ l2bits = 14; /* 16K: 14 bits */
319
+ break;
320
+ case 2:
321
+ l2bits = 16; /* 64K: 16 bits */
322
+ break;
323
+ default:
324
+ g_assert_not_reached();
325
+ }
326
+ /*
327
+ * Calculate how many bits of an ID index the L2 table
328
+ * (e.g. if we need 14 bits to index each byte in a 16K L2 table,
329
+ * but each entry is 4 bytes wide then we need 14 - 2 = 12 bits
330
+ * to index an entry in the table).
331
+ */
332
+ l2_idx_bits = l2bits - istbits;
333
+ cfg->base = cs->irs_ist_baser[domain] & R_IRS_IST_BASER_ADDR_MASK;
334
+ cfg->id_bits = id_bits;
335
+ cfg->istsz = 1 << istbits;
336
+ cfg->l2_idx_bits = l2_idx_bits;
337
+ cfg->structure = FIELD_EX64(cs->irs_ist_cfgr[domain],
338
+ IRS_IST_CFGR, STRUCTURE);
339
+ cfg->valid = true;
340
+ trace_gicv5_ist_valid(domain_name[domain], cfg->base, cfg->id_bits,
341
+ cfg->l2_idx_bits, cfg->istsz, cfg->structure);
342
+ }
343
}
344
345
static bool config_readl(GICv5 *s, GICv5Domain domain, hwaddr offset,
612
if (c->parent_phases.hold) {
613
c->parent_phases.hold(obj, type);
614
}
615
+
616
+ /* IRS_IST_BASER and IRS_IST_CFGR reset to 0, clear cached info */
617
+ for (int i = 0; i < NUM_GICV5_DOMAINS; i++) {
618
+ s->phys_lpi_config[i].valid = false;
619
+ }
620
}
621
622
static void gicv5_set_idregs(GICv5Common *cs)