9
#include "qemu/osdep.h"
10
#include "hw/core/registerfields.h"
11
#include "hw/intc/arm_gicv5.h"
12
+#include "hw/intc/arm_gicv5_stream.h"
13
#include "qapi/error.h"
14
#include "qemu/log.h"
15
#include "trace.h"
24
[GICV5_ID_REALM] = "Realm",
25
};
26
27
+static const char *inttype_name(GICv5IntType t)
28
+{
29
+ /*
30
+ * We have to be more cautious with getting human readable names
31
+ * for a GICv5IntType for trace strings than we do with the domain
32
+ * enum, because here the value can come from a guest register
33
+ * field.
34
+ */
35
+ static const char *names[] = {
36
+ [GICV5_PPI] = "PPI",
37
+ [GICV5_LPI] = "LPI",
38
+ [GICV5_SPI] = "SPI",
39
+ };
40
+ if (t >= ARRAY_SIZE(names) || !names[t]) {
41
+ return "RESERVED";
42
+ }
43
+ return names[t];
44
+}
45
+
46
REG32(IRS_IDR0, 0x0)
47
FIELD(IRS_IDR0, INT_DOM, 0, 2)
48
FIELD(IRS_IDR0, PA_RANGE, 2, 4)
285
REG64(IRS_SWERR_SYNDROMER1, 0x3d0)
286
FIELD(IRS_SWERR_SYNDROMER2, ADDR, 3, 53)
287
288
+FIELD(L1_ISTE, VALID, 0, 1)
289
+FIELD(L1_ISTE, L2_ADDR, 12, 44)
290
+
291
+FIELD(L2_ISTE, PENDING, 0, 1)
292
+FIELD(L2_ISTE, ACTIVE, 1, 1)
293
+FIELD(L2_ISTE, HM, 2, 1)
294
+FIELD(L2_ISTE, ENABLE, 3, 1)
295
+FIELD(L2_ISTE, IRM, 4, 1)
296
+FIELD(L2_ISTE, HWU, 9, 2)
297
+FIELD(L2_ISTE, PRIORITY, 11, 5)
298
+FIELD(L2_ISTE, IAFFID, 16, 16)
299
+
300
+static MemTxAttrs irs_txattrs(GICv5Common *cs, GICv5Domain domain)
301
+{
302
+ /*
303
+ * Return a MemTxAttrs to use for IRS memory accesses. IRS_CR1
304
+ * has the usual Arm cacheability/shareability attributes, but
305
+ * QEMU doesn't care about those. All we need to specify here is
306
+ * the correct security attributes, which depend on the interrupt
307
+ * domain. Conveniently, our GICv5Domain encoding matches the
308
+ * ARMSecuritySpace one (because both follow an architecturally
309
+ * specified field). The exception is that the EL3 domain must be
310
+ * Secure instead of Root if we don't implement Realm.
311
+ */
312
+ if (domain == GICV5_ID_EL3 &&
313
+ !gicv5_domain_implemented(cs, GICV5_ID_REALM)) {
314
+ domain = GICV5_ID_S;
315
+ }
316
+ return (MemTxAttrs) {
317
+ .space = domain,
318
+ .secure = domain == GICV5_ID_S || domain == GICV5_ID_EL3,
319
+ };
320
+}
321
+
322
+static hwaddr l1_iste_addr(GICv5Common *cs, const GICv5ISTConfig *cfg,
323
+ uint32_t id)
324
+{
325
+ /*
326
+ * In a 2-level IST configuration, return the address of the L1
327
+ * IST entry for this interrupt ID. The bottom l2_idx_bits of the
328
+ * ID value are the index into the L2 table, and the higher bits
329
+ * of the ID index the L1 table.
330
+ */
331
+ uint32_t l1_index = id >> cfg->l2_idx_bits;
332
+ return cfg->base + (l1_index * 8);
333
+}
334
+
335
+static bool get_l2_iste_addr(GICv5Common *cs, const GICv5ISTConfig *cfg,
336
+ uint32_t id, hwaddr *l2_iste_addr)
337
+{
338
+ /*
339
+ * Get the address of the L2 interrupt state table entry for this
340
+ * interrupt. On success, fill in l2_iste_addr and return true.
341
+ * On failure, return false.
342
+ */
343
+ hwaddr l2_base;
344
+
345
+ if (!cfg->valid) {
346
+ return false;
347
+ }
348
+
349
+ if (id >= (1 << cfg->id_bits)) {
350
+ return false;
351
+ }
352
+
353
+ if (cfg->structure) {
354
+ /*
355
+ * 2-level table: read the L1 IST. The bottom l2_idx_bits of
356
+ * the ID value are the index into the L2 table, and the
357
+ * higher bits of the ID index the L1 table. There is always
358
+ * at least one L1 table entry.
359
+ */
360
+ hwaddr l1_addr = l1_iste_addr(cs, cfg, id);
361
+ uint64_t l1_iste;
362
+ MemTxResult res;
363
+
364
+ l1_iste = address_space_ldq_le(&cs->dma_as, l1_addr,
365
+ cfg->txattrs, &res);
366
+ if (res != MEMTX_OK) {
367
+ /* Reportable with EC=0x01 if sw error reporting implemented */
368
+ qemu_log_mask(LOG_GUEST_ERROR, "L1 ISTE lookup failed for ID 0x%x"
369
+ " at physical address 0x" HWADDR_FMT_plx "\n",
370
+ id, l1_addr);
371
+ return false;
372
+ }
373
+ if (!FIELD_EX64(l1_iste, L1_ISTE, VALID)) {
374
+ return false;
375
+ }
376
+ l2_base = l1_iste & R_L1_ISTE_L2_ADDR_MASK;
377
+ id = extract32(id, 0, cfg->l2_idx_bits);
378
+ } else {
379
+ /* 1-level table */
380
+ l2_base = cfg->base;
381
+ }
382
+
383
+ *l2_iste_addr = l2_base + (id * cfg->istsz);
384
+ return true;
385
+}
386
+
387
+static bool read_l2_iste_mem(GICv5Common *cs, const GICv5ISTConfig *cfg,
388
+ hwaddr addr, uint32_t *l2_iste)
389
+{
390
+ MemTxResult res;
391
+
392
+ *l2_iste = address_space_ldl_le(&cs->dma_as, addr, cfg->txattrs, &res);
393
+ if (res != MEMTX_OK) {
394
+ /* Reportable with EC=0x02 if sw error reporting implemented */
395
+ qemu_log_mask(LOG_GUEST_ERROR, "L2 ISTE read failed at physical "
396
+ "address 0x" HWADDR_FMT_plx "\n", addr);
397
+ }
398
+ return res == MEMTX_OK;
399
+}
400
+
401
+static bool write_l2_iste_mem(GICv5Common *cs, const GICv5ISTConfig *cfg,
402
+ hwaddr addr, uint32_t l2_iste)
403
+{
404
+ MemTxResult res;
405
+
406
+ address_space_stl_le(&cs->dma_as, addr, l2_iste, cfg->txattrs, &res);
407
+ if (res != MEMTX_OK) {
408
+ /* Reportable with EC=0x02 if sw error reporting implemented */
409
+ qemu_log_mask(LOG_GUEST_ERROR, "L2 ISTE write failed at physical "
410
+ "address 0x" HWADDR_FMT_plx "\n", addr);
411
+ }
412
+ return res == MEMTX_OK;
413
+}
414
+
415
+/*
416
+ * This is returned by get_l2_iste() and has everything we need to do
417
+ * the writeback of the L2 ISTE word in put_l2_iste(). Currently the
418
+ * get/put functions always directly do guest memory reads and writes
419
+ * to update the L2 ISTE. In a future commit we will add support for a
420
+ * cache of some of the ISTE data in a local hashtable; the APIs are
421
+ * designed with that in mind.
422
+ */
423
+typedef struct L2_ISTE_Handle {
424
+ hwaddr l2_iste_addr;
425
+ uint32_t l2_iste;
426
+} L2_ISTE_Handle;
427
+
428
+static uint32_t *get_l2_iste(GICv5Common *cs, const GICv5ISTConfig *cfg,
429
+ uint32_t id, L2_ISTE_Handle *h)
430
+{
431
+ /*
432
+ * Find the L2 ISTE for the interrupt @id.
433
+ *
434
+ * We return a pointer to the ISTE: the caller can freely read and
435
+ * modify the uint64_t pointed to to update the ISTE. If the
436
+ * caller modifies the L2 ISTE word, it must call put_l2_iste(),
437
+ * passing it @h, to write back the ISTE. If the caller is only
438
+ * reading the L2 ISTE, it does not need to call put_l2_iste().
439
+ *
440
+ * We fill in @h with information needed for put_l2_iste().
441
+ *
442
+ * If the ISTE could not be read (typically because of a memory
443
+ * error), return NULL.
444
+ */
445
+ if (!get_l2_iste_addr(cs, cfg, id, &h->l2_iste_addr) ||
446
+ !read_l2_iste_mem(cs, cfg, h->l2_iste_addr, &h->l2_iste)) {
447
+ return NULL;
448
+ }
449
+ return &h->l2_iste;
450
+}
451
+
452
+static void put_l2_iste(GICv5Common *cs, const GICv5ISTConfig *cfg,
453
+ L2_ISTE_Handle *h)
454
+{
455
+ /*
456
+ * Write back the modified L2_ISTE word found with get_l2_iste().
457
+ * Once this has been called the L2_ISTE_Handle @h and the pointer
458
+ * to the L2 ISTE word are no longer valid.
459
+ */
460
+ write_l2_iste_mem(cs, cfg, h->l2_iste_addr, h->l2_iste);
461
+}
462
+
463
+void gicv5_set_priority(GICv5Common *cs, uint32_t id, uint8_t priority,
464
+ GICv5Domain domain, GICv5IntType type, bool virtual)
465
+{
466
+ GICv5 *s = ARM_GICV5(cs);
467
+
468
+ trace_gicv5_set_priority(domain_name[domain], inttype_name(type), virtual,
469
+ id, priority);
470
+ /* We must ignore unimplemented low-order priority bits */
471
+ priority &= MAKE_64BIT_MASK(5 - QEMU_GICV5_PRI_BITS, QEMU_GICV5_PRI_BITS);
472
+
473
+ if (virtual) {
474
+ qemu_log_mask(LOG_GUEST_ERROR, "gicv5_set_priority: tried to set "
475
+ "priority of a virtual interrupt\n");
476
+ return;
477
+ }
478
+
479
+ switch (type) {
480
+ case GICV5_LPI:
481
+ {
482
+ const GICv5ISTConfig *cfg = &s->phys_lpi_config[domain];
483
+ L2_ISTE_Handle h;
484
+ uint32_t *l2_iste_p = get_l2_iste(cs, cfg, id, &h);
485
+
486
+ if (!l2_iste_p) {
487
+ return;
488
+ }
489
+ *l2_iste_p = FIELD_DP32(*l2_iste_p, L2_ISTE, PRIORITY, priority);
490
+ put_l2_iste(cs, cfg, &h);
491
+ break;
492
+ }
493
+ default:
494
+ qemu_log_mask(LOG_GUEST_ERROR, "gicv5_set_priority: tried to set "
495
+ "priority of bad interrupt type %d\n", type);
496
+ return;
497
+ }
498
+}
499
+
500
static void irs_ist_baser_write(GICv5 *s, GICv5Domain domain, uint64_t value)
501
{
502
GICv5Common *cs = ARM_GICV5_COMMON(s);
563
*/
564
l2_idx_bits = l2bits - istbits;
565
cfg->base = cs->irs_ist_baser[domain] & R_IRS_IST_BASER_ADDR_MASK;
566
+ cfg->txattrs = irs_txattrs(cs, domain),
567
cfg->id_bits = id_bits;
568
cfg->istsz = 1 << istbits;
569
cfg->l2_idx_bits = l2_idx_bits;