1
2
3
4
5
6
7
8
9
10
11
12#include "qemu/osdep.h"
13#include "qemu/log.h"
14#include "trace.h"
15#include "gicv3_internal.h"
16
17static uint32_t mask_group(GICv3CPUState *cs, MemTxAttrs attrs)
18{
19
20
21
22
23
24 if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
25
26 return cs->gicr_igroupr0;
27 }
28 return 0xFFFFFFFFU;
29}
30
31static int gicr_ns_access(GICv3CPUState *cs, int irq)
32{
33
34 assert(irq < 16);
35 return extract32(cs->gicr_nsacr, irq * 2, 2);
36}
37
38static void gicr_write_set_bitmap_reg(GICv3CPUState *cs, MemTxAttrs attrs,
39 uint32_t *reg, uint32_t val)
40{
41
42 val &= mask_group(cs, attrs);
43 *reg |= val;
44 gicv3_redist_update(cs);
45}
46
47static void gicr_write_clear_bitmap_reg(GICv3CPUState *cs, MemTxAttrs attrs,
48 uint32_t *reg, uint32_t val)
49{
50
51 val &= mask_group(cs, attrs);
52 *reg &= ~val;
53 gicv3_redist_update(cs);
54}
55
56static uint32_t gicr_read_bitmap_reg(GICv3CPUState *cs, MemTxAttrs attrs,
57 uint32_t reg)
58{
59 reg &= mask_group(cs, attrs);
60 return reg;
61}
62
63static uint8_t gicr_read_ipriorityr(GICv3CPUState *cs, MemTxAttrs attrs,
64 int irq)
65{
66
67
68
69
70 uint32_t prio;
71
72 prio = cs->gicr_ipriorityr[irq];
73
74 if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
75 if (!(cs->gicr_igroupr0 & (1U << irq))) {
76
77 return 0;
78 }
79
80 prio = (prio << 1) & 0xff;
81 }
82 return prio;
83}
84
85static void gicr_write_ipriorityr(GICv3CPUState *cs, MemTxAttrs attrs, int irq,
86 uint8_t value)
87{
88
89
90
91
92 if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
93 if (!(cs->gicr_igroupr0 & (1U << irq))) {
94
95 return;
96 }
97
98 value = 0x80 | (value >> 1);
99 }
100 cs->gicr_ipriorityr[irq] = value;
101}
102
103static MemTxResult gicr_readb(GICv3CPUState *cs, hwaddr offset,
104 uint64_t *data, MemTxAttrs attrs)
105{
106 switch (offset) {
107 case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f:
108 *data = gicr_read_ipriorityr(cs, attrs, offset - GICR_IPRIORITYR);
109 return MEMTX_OK;
110 default:
111 return MEMTX_ERROR;
112 }
113}
114
115static MemTxResult gicr_writeb(GICv3CPUState *cs, hwaddr offset,
116 uint64_t value, MemTxAttrs attrs)
117{
118 switch (offset) {
119 case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f:
120 gicr_write_ipriorityr(cs, attrs, offset - GICR_IPRIORITYR, value);
121 gicv3_redist_update(cs);
122 return MEMTX_OK;
123 default:
124 return MEMTX_ERROR;
125 }
126}
127
128static MemTxResult gicr_readl(GICv3CPUState *cs, hwaddr offset,
129 uint64_t *data, MemTxAttrs attrs)
130{
131 switch (offset) {
132 case GICR_CTLR:
133 *data = cs->gicr_ctlr;
134 return MEMTX_OK;
135 case GICR_IIDR:
136 *data = gicv3_iidr();
137 return MEMTX_OK;
138 case GICR_TYPER:
139 *data = extract64(cs->gicr_typer, 0, 32);
140 return MEMTX_OK;
141 case GICR_TYPER + 4:
142 *data = extract64(cs->gicr_typer, 32, 32);
143 return MEMTX_OK;
144 case GICR_STATUSR:
145
146
147
148 *data = 0;
149 return MEMTX_OK;
150 case GICR_WAKER:
151 *data = cs->gicr_waker;
152 return MEMTX_OK;
153 case GICR_PROPBASER:
154 *data = extract64(cs->gicr_propbaser, 0, 32);
155 return MEMTX_OK;
156 case GICR_PROPBASER + 4:
157 *data = extract64(cs->gicr_propbaser, 32, 32);
158 return MEMTX_OK;
159 case GICR_PENDBASER:
160 *data = extract64(cs->gicr_pendbaser, 0, 32);
161 return MEMTX_OK;
162 case GICR_PENDBASER + 4:
163 *data = extract64(cs->gicr_pendbaser, 32, 32);
164 return MEMTX_OK;
165 case GICR_IGROUPR0:
166 if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
167 *data = 0;
168 return MEMTX_OK;
169 }
170 *data = cs->gicr_igroupr0;
171 return MEMTX_OK;
172 case GICR_ISENABLER0:
173 case GICR_ICENABLER0:
174 *data = gicr_read_bitmap_reg(cs, attrs, cs->gicr_ienabler0);
175 return MEMTX_OK;
176 case GICR_ISPENDR0:
177 case GICR_ICPENDR0:
178 {
179
180
181
182 uint32_t val = cs->gicr_ipendr0 | (~cs->edge_trigger & cs->level);
183 *data = gicr_read_bitmap_reg(cs, attrs, val);
184 return MEMTX_OK;
185 }
186 case GICR_ISACTIVER0:
187 case GICR_ICACTIVER0:
188 *data = gicr_read_bitmap_reg(cs, attrs, cs->gicr_iactiver0);
189 return MEMTX_OK;
190 case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f:
191 {
192 int i, irq = offset - GICR_IPRIORITYR;
193 uint32_t value = 0;
194
195 for (i = irq + 3; i >= irq; i--) {
196 value <<= 8;
197 value |= gicr_read_ipriorityr(cs, attrs, i);
198 }
199 *data = value;
200 return MEMTX_OK;
201 }
202 case GICR_ICFGR0:
203 case GICR_ICFGR1:
204 {
205
206
207
208 uint32_t value;
209
210 value = cs->edge_trigger & mask_group(cs, attrs);
211 value = extract32(value, (offset == GICR_ICFGR1) ? 16 : 0, 16);
212 value = half_shuffle32(value) << 1;
213 *data = value;
214 return MEMTX_OK;
215 }
216 case GICR_IGRPMODR0:
217 if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
218
219
220
221 *data = 0;
222 return MEMTX_OK;
223 }
224 *data = cs->gicr_igrpmodr0;
225 return MEMTX_OK;
226 case GICR_NSACR:
227 if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
228
229
230
231 *data = 0;
232 return MEMTX_OK;
233 }
234 *data = cs->gicr_nsacr;
235 return MEMTX_OK;
236 case GICR_IDREGS ... GICR_IDREGS + 0x2f:
237 *data = gicv3_idreg(offset - GICR_IDREGS);
238 return MEMTX_OK;
239 default:
240 return MEMTX_ERROR;
241 }
242}
243
244static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset,
245 uint64_t value, MemTxAttrs attrs)
246{
247 switch (offset) {
248 case GICR_CTLR:
249
250
251
252
253
254 if (cs->gicr_typer & GICR_TYPER_PLPIS) {
255 if (value & GICR_CTLR_ENABLE_LPIS) {
256 cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS;
257
258 gicv3_redist_update_lpi(cs);
259 } else {
260 cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS;
261
262 gicv3_redist_update(cs);
263 }
264 }
265 return MEMTX_OK;
266 case GICR_STATUSR:
267
268 return MEMTX_OK;
269 case GICR_WAKER:
270
271
272
273
274
275
276
277
278
279
280
281 value &= GICR_WAKER_ProcessorSleep;
282 if (value & GICR_WAKER_ProcessorSleep) {
283 value |= GICR_WAKER_ChildrenAsleep;
284 }
285 cs->gicr_waker = value;
286 return MEMTX_OK;
287 case GICR_PROPBASER:
288 cs->gicr_propbaser = deposit64(cs->gicr_propbaser, 0, 32, value);
289 return MEMTX_OK;
290 case GICR_PROPBASER + 4:
291 cs->gicr_propbaser = deposit64(cs->gicr_propbaser, 32, 32, value);
292 return MEMTX_OK;
293 case GICR_PENDBASER:
294 cs->gicr_pendbaser = deposit64(cs->gicr_pendbaser, 0, 32, value);
295 return MEMTX_OK;
296 case GICR_PENDBASER + 4:
297 cs->gicr_pendbaser = deposit64(cs->gicr_pendbaser, 32, 32, value);
298 return MEMTX_OK;
299 case GICR_IGROUPR0:
300 if (!attrs.secure && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
301 return MEMTX_OK;
302 }
303 cs->gicr_igroupr0 = value;
304 gicv3_redist_update(cs);
305 return MEMTX_OK;
306 case GICR_ISENABLER0:
307 gicr_write_set_bitmap_reg(cs, attrs, &cs->gicr_ienabler0, value);
308 return MEMTX_OK;
309 case GICR_ICENABLER0:
310 gicr_write_clear_bitmap_reg(cs, attrs, &cs->gicr_ienabler0, value);
311 return MEMTX_OK;
312 case GICR_ISPENDR0:
313 gicr_write_set_bitmap_reg(cs, attrs, &cs->gicr_ipendr0, value);
314 return MEMTX_OK;
315 case GICR_ICPENDR0:
316 gicr_write_clear_bitmap_reg(cs, attrs, &cs->gicr_ipendr0, value);
317 return MEMTX_OK;
318 case GICR_ISACTIVER0:
319 gicr_write_set_bitmap_reg(cs, attrs, &cs->gicr_iactiver0, value);
320 return MEMTX_OK;
321 case GICR_ICACTIVER0:
322 gicr_write_clear_bitmap_reg(cs, attrs, &cs->gicr_iactiver0, value);
323 return MEMTX_OK;
324 case GICR_IPRIORITYR ... GICR_IPRIORITYR + 0x1f:
325 {
326 int i, irq = offset - GICR_IPRIORITYR;
327
328 for (i = irq; i < irq + 4; i++, value >>= 8) {
329 gicr_write_ipriorityr(cs, attrs, i, value);
330 }
331 gicv3_redist_update(cs);
332 return MEMTX_OK;
333 }
334 case GICR_ICFGR0:
335
336 return MEMTX_OK;
337 case GICR_ICFGR1:
338 {
339 uint32_t mask;
340
341
342
343
344
345 value = half_unshuffle32(value >> 1) << 16;
346 mask = mask_group(cs, attrs) & 0xffff0000U;
347
348 cs->edge_trigger &= ~mask;
349 cs->edge_trigger |= (value & mask);
350
351 gicv3_redist_update(cs);
352 return MEMTX_OK;
353 }
354 case GICR_IGRPMODR0:
355 if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
356
357
358
359 return MEMTX_OK;
360 }
361 cs->gicr_igrpmodr0 = value;
362 gicv3_redist_update(cs);
363 return MEMTX_OK;
364 case GICR_NSACR:
365 if ((cs->gic->gicd_ctlr & GICD_CTLR_DS) || !attrs.secure) {
366
367
368
369 return MEMTX_OK;
370 }
371 cs->gicr_nsacr = value;
372
373 return MEMTX_OK;
374 case GICR_IIDR:
375 case GICR_TYPER:
376 case GICR_IDREGS ... GICR_IDREGS + 0x2f:
377
378 qemu_log_mask(LOG_GUEST_ERROR,
379 "%s: invalid guest write to RO register at offset "
380 TARGET_FMT_plx "\n", __func__, offset);
381 return MEMTX_OK;
382 default:
383 return MEMTX_ERROR;
384 }
385}
386
387static MemTxResult gicr_readll(GICv3CPUState *cs, hwaddr offset,
388 uint64_t *data, MemTxAttrs attrs)
389{
390 switch (offset) {
391 case GICR_TYPER:
392 *data = cs->gicr_typer;
393 return MEMTX_OK;
394 case GICR_PROPBASER:
395 *data = cs->gicr_propbaser;
396 return MEMTX_OK;
397 case GICR_PENDBASER:
398 *data = cs->gicr_pendbaser;
399 return MEMTX_OK;
400 default:
401 return MEMTX_ERROR;
402 }
403}
404
405static MemTxResult gicr_writell(GICv3CPUState *cs, hwaddr offset,
406 uint64_t value, MemTxAttrs attrs)
407{
408 switch (offset) {
409 case GICR_PROPBASER:
410 cs->gicr_propbaser = value;
411 return MEMTX_OK;
412 case GICR_PENDBASER:
413 cs->gicr_pendbaser = value;
414 return MEMTX_OK;
415 case GICR_TYPER:
416
417 qemu_log_mask(LOG_GUEST_ERROR,
418 "%s: invalid guest write to RO register at offset "
419 TARGET_FMT_plx "\n", __func__, offset);
420 return MEMTX_OK;
421 default:
422 return MEMTX_ERROR;
423 }
424}
425
426MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
427 unsigned size, MemTxAttrs attrs)
428{
429 GICv3RedistRegion *region = opaque;
430 GICv3State *s = region->gic;
431 GICv3CPUState *cs;
432 MemTxResult r;
433 int cpuidx;
434
435 assert((offset & (size - 1)) == 0);
436
437
438
439
440
441
442
443
444
445 cpuidx = region->cpuidx + offset / GICV3_REDIST_SIZE;
446 offset %= GICV3_REDIST_SIZE;
447
448 cs = &s->cpu[cpuidx];
449
450 switch (size) {
451 case 1:
452 r = gicr_readb(cs, offset, data, attrs);
453 break;
454 case 4:
455 r = gicr_readl(cs, offset, data, attrs);
456 break;
457 case 8:
458 r = gicr_readll(cs, offset, data, attrs);
459 break;
460 default:
461 r = MEMTX_ERROR;
462 break;
463 }
464
465 if (r == MEMTX_ERROR) {
466 qemu_log_mask(LOG_GUEST_ERROR,
467 "%s: invalid guest read at offset " TARGET_FMT_plx
468 " size %u\n", __func__, offset, size);
469 trace_gicv3_redist_badread(gicv3_redist_affid(cs), offset,
470 size, attrs.secure);
471
472
473
474
475
476 r = MEMTX_OK;
477 *data = 0;
478 } else {
479 trace_gicv3_redist_read(gicv3_redist_affid(cs), offset, *data,
480 size, attrs.secure);
481 }
482 return r;
483}
484
485MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
486 unsigned size, MemTxAttrs attrs)
487{
488 GICv3RedistRegion *region = opaque;
489 GICv3State *s = region->gic;
490 GICv3CPUState *cs;
491 MemTxResult r;
492 int cpuidx;
493
494 assert((offset & (size - 1)) == 0);
495
496
497
498
499
500
501
502
503
504 cpuidx = region->cpuidx + offset / GICV3_REDIST_SIZE;
505 offset %= GICV3_REDIST_SIZE;
506
507 cs = &s->cpu[cpuidx];
508
509 switch (size) {
510 case 1:
511 r = gicr_writeb(cs, offset, data, attrs);
512 break;
513 case 4:
514 r = gicr_writel(cs, offset, data, attrs);
515 break;
516 case 8:
517 r = gicr_writell(cs, offset, data, attrs);
518 break;
519 default:
520 r = MEMTX_ERROR;
521 break;
522 }
523
524 if (r == MEMTX_ERROR) {
525 qemu_log_mask(LOG_GUEST_ERROR,
526 "%s: invalid guest write at offset " TARGET_FMT_plx
527 " size %u\n", __func__, offset, size);
528 trace_gicv3_redist_badwrite(gicv3_redist_affid(cs), offset, data,
529 size, attrs.secure);
530
531
532
533
534
535 r = MEMTX_OK;
536 } else {
537 trace_gicv3_redist_write(gicv3_redist_affid(cs), offset, data,
538 size, attrs.secure);
539 }
540 return r;
541}
542
543static void gicv3_redist_check_lpi_priority(GICv3CPUState *cs, int irq)
544{
545 AddressSpace *as = &cs->gic->dma_as;
546 uint64_t lpict_baddr;
547 uint8_t lpite;
548 uint8_t prio;
549
550 lpict_baddr = cs->gicr_propbaser & R_GICR_PROPBASER_PHYADDR_MASK;
551
552 address_space_read(as, lpict_baddr + ((irq - GICV3_LPI_INTID_START) *
553 sizeof(lpite)), MEMTXATTRS_UNSPECIFIED, &lpite,
554 sizeof(lpite));
555
556 if (!(lpite & LPI_CTE_ENABLED)) {
557 return;
558 }
559
560 if (cs->gic->gicd_ctlr & GICD_CTLR_DS) {
561 prio = lpite & LPI_PRIORITY_MASK;
562 } else {
563 prio = ((lpite & LPI_PRIORITY_MASK) >> 1) | 0x80;
564 }
565
566 if ((prio < cs->hpplpi.prio) ||
567 ((prio == cs->hpplpi.prio) && (irq <= cs->hpplpi.irq))) {
568 cs->hpplpi.irq = irq;
569 cs->hpplpi.prio = prio;
570
571 cs->hpplpi.grp = GICV3_G1NS;
572 }
573}
574
575void gicv3_redist_update_lpi_only(GICv3CPUState *cs)
576{
577
578
579
580
581
582
583
584 AddressSpace *as = &cs->gic->dma_as;
585 uint64_t lpipt_baddr;
586 uint32_t pendt_size = 0;
587 uint8_t pend;
588 int i, bit;
589 uint64_t idbits;
590
591 idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
592 GICD_TYPER_IDBITS);
593
594 if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser ||
595 !cs->gicr_pendbaser) {
596 return;
597 }
598
599 cs->hpplpi.prio = 0xff;
600
601 lpipt_baddr = cs->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
602
603
604 pendt_size = (1ULL << (idbits + 1));
605
606 for (i = GICV3_LPI_INTID_START / 8; i < pendt_size / 8; i++) {
607 address_space_read(as, lpipt_baddr + i, MEMTXATTRS_UNSPECIFIED, &pend,
608 sizeof(pend));
609
610 while (pend) {
611 bit = ctz32(pend);
612 gicv3_redist_check_lpi_priority(cs, i * 8 + bit);
613 pend &= ~(1 << bit);
614 }
615 }
616}
617
618void gicv3_redist_update_lpi(GICv3CPUState *cs)
619{
620 gicv3_redist_update_lpi_only(cs);
621 gicv3_redist_update(cs);
622}
623
624void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level)
625{
626
627
628
629
630 AddressSpace *as = &cs->gic->dma_as;
631 uint64_t lpipt_baddr;
632 bool ispend = false;
633 uint8_t pend;
634
635
636
637
638
639 lpipt_baddr = cs->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
640
641 address_space_read(as, lpipt_baddr + ((irq / 8) * sizeof(pend)),
642 MEMTXATTRS_UNSPECIFIED, &pend, sizeof(pend));
643
644 ispend = extract32(pend, irq % 8, 1);
645
646
647 if (ispend == level) {
648 return;
649 }
650 pend = deposit32(pend, irq % 8, 1, level ? 1 : 0);
651
652 address_space_write(as, lpipt_baddr + ((irq / 8) * sizeof(pend)),
653 MEMTXATTRS_UNSPECIFIED, &pend, sizeof(pend));
654
655
656
657
658
659 if (level) {
660 gicv3_redist_check_lpi_priority(cs, irq);
661 gicv3_redist_update(cs);
662 } else {
663 if (irq == cs->hpplpi.irq) {
664 gicv3_redist_update_lpi(cs);
665 }
666 }
667}
668
669void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
670{
671 uint64_t idbits;
672
673 idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
674 GICD_TYPER_IDBITS);
675
676 if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser ||
677 !cs->gicr_pendbaser || (irq > (1ULL << (idbits + 1)) - 1) ||
678 irq < GICV3_LPI_INTID_START) {
679 return;
680 }
681
682
683 gicv3_redist_lpi_pending(cs, irq, level);
684}
685
686void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level)
687{
688
689 if (level == extract32(cs->level, irq, 1)) {
690 return;
691 }
692
693 trace_gicv3_redist_set_irq(gicv3_redist_affid(cs), irq, level);
694
695 cs->level = deposit32(cs->level, irq, 1, level);
696
697 if (level) {
698
699 if (extract32(cs->edge_trigger, irq, 1)) {
700 cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 1);
701 }
702 }
703
704 gicv3_redist_update(cs);
705}
706
707void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns)
708{
709
710 int irqgrp = gicv3_irq_group(cs->gic, cs, irq);
711
712
713
714
715
716 if (grp == GICV3_G1 && irqgrp == GICV3_G0) {
717 grp = GICV3_G0;
718 }
719
720 if (grp != irqgrp) {
721 return;
722 }
723
724 if (ns && !(cs->gic->gicd_ctlr & GICD_CTLR_DS)) {
725
726 int nsaccess = gicr_ns_access(cs, irq);
727
728 if ((irqgrp == GICV3_G0 && nsaccess < 1) ||
729 (irqgrp == GICV3_G1 && nsaccess < 2)) {
730 return;
731 }
732 }
733
734
735 trace_gicv3_redist_send_sgi(gicv3_redist_affid(cs), irq);
736 cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 1);
737 gicv3_redist_update(cs);
738}
739