gem5 v24.0.0.0
Loading...
Searching...
No Matches
gic_v3_cpu_interface.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019, 2021-2022 Arm Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2018 Metempsy Technology Consulting
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
42
43#include "arch/arm/faults.hh"
44#include "arch/arm/isa.hh"
45#include "debug/GIC.hh"
46#include "dev/arm/gic_v3.hh"
49
50namespace gem5
51{
52
53using namespace ArmISA;
54
57
59 : BaseISADevice(),
60 gic(gic),
61 redistributor(nullptr),
62 distributor(nullptr),
63 tc(_tc),
64 maintenanceInterrupt(gic->params().maint_int->get(tc)),
65 cpuId(tc->contextId())
66{
67 hppi.prio = 0xff;
69
70 setISA(static_cast<ISA*>(tc->getIsaPtr()));
71}
72
73void
79
80void
82{
83 if (intid == hppi.intid)
84 hppi.prio = 0xff;
85}
86
87void
89{
90 tc = _tc;
91 maintenanceInterrupt = gic->params().maint_int->get(tc);
93 "Invalid maintenance interrupt number\n");
94}
95
96bool
98{
100
101 if (hcr.tge && hcr.e2h) {
102 return false;
103 } else if (hcr.tge) {
104 return true;
105 } else {
106 return hcr.fmo;
107 }
108}
109
110bool
112{
114
115 if (hcr.tge && hcr.e2h) {
116 return false;
117 } else if (hcr.tge) {
118 return true;
119 } else {
120 return hcr.imo;
121 }
122}
123
124RegVal
126{
127 RegVal value = isa->readMiscRegNoEffect(misc_reg);
128 bool hcr_fmo = getHCREL2FMO();
129 bool hcr_imo = getHCREL2IMO();
130
131 switch (misc_reg) {
132 // Active Priorities Group 1 Registers
135 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
137 }
138
140 }
141
144
145 // only implemented if supporting 6 or more bits of priority
148
149 // only implemented if supporting 7 or more bits of priority
152 // only implemented if supporting 7 or more bits of priority
153 return 0;
154
155 // Active Priorities Group 0 Registers
158 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
160 }
161
162 break;
163 }
164
167
168 // only implemented if supporting 6 or more bits of priority
171
172 // only implemented if supporting 7 or more bits of priority
175 // only implemented if supporting 7 or more bits of priority
176 return 0;
177
178 // Interrupt Group 0 Enable register EL1
181 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
183 }
184
185 break;
186 }
187
189 ICH_VMCR_EL2 ich_vmcr_el2 =
191 value = ich_vmcr_el2.VENG0;
192 break;
193 }
194
195 // Interrupt Group 1 Enable register EL1
198 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
200 }
201
203 break;
204 }
205
207 ICH_VMCR_EL2 ich_vmcr_el2 =
209 value = ich_vmcr_el2.VENG1;
210 break;
211 }
212
213 // Interrupt Group 1 Enable register EL3
216 ICC_IGRPEN1_EL3 igrp_el3 = 0;
217 igrp_el3.EnableGrp1S = ((ICC_IGRPEN1_EL1)isa->readMiscRegNoEffect(
219
220 igrp_el3.EnableGrp1NS = ((ICC_IGRPEN1_EL1)isa->readMiscRegNoEffect(
222
223 value = igrp_el3;
224 break;
225 }
226
227 // Running Priority Register
228 case MISCREG_ICC_RPR:
229 case MISCREG_ICC_RPR_EL1: {
230 if ((currEL() == EL1) && !inSecureState() &&
231 (hcr_imo || hcr_fmo)) {
233 }
234
235 uint8_t rprio = highestActivePriority();
236
237 if (haveEL(EL3) && !inSecureState() &&
238 (tc->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
239 // Spec section 4.8.1
240 // For Non-secure access to ICC_RPR_EL1 when SCR_EL3.FIQ == 1
241 if ((rprio & 0x80) == 0) {
242 // If the current priority mask value is in the range of
243 // 0x00-0x7F a read access returns the value 0x0
244 rprio = 0;
245 } else if (rprio != 0xff) {
246 // If the current priority mask value is in the range of
247 // 0x80-0xFF a read access returns the Non-secure read of
248 // the current value
249 rprio = (rprio << 1) & 0xff;
250 }
251 }
252
253 value = rprio;
254 break;
255 }
256
257 // Virtual Running Priority Register
258 case MISCREG_ICV_RPR_EL1: {
260 break;
261 }
262
263 // Highest Priority Pending Interrupt Register 0
266 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
268 }
269
270 value = getHPPIR0();
271 break;
272 }
273
274 // Virtual Highest Priority Pending Interrupt Register 0
276 value = Gicv3::INTID_SPURIOUS;
277 int lr_idx = getHPPVILR();
278
279 if (lr_idx >= 0) {
280 ICH_LR_EL2 ich_lr_el2 =
282 Gicv3::GroupId group =
283 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
284
285 if (group == Gicv3::G0S) {
286 value = ich_lr_el2.vINTID;
287 }
288 }
289
290 break;
291 }
292
293 // Highest Priority Pending Interrupt Register 1
296 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
298 }
299
300 value = getHPPIR1();
301 break;
302 }
303
304 // Virtual Highest Priority Pending Interrupt Register 1
306 value = Gicv3::INTID_SPURIOUS;
307 int lr_idx = getHPPVILR();
308
309 if (lr_idx >= 0) {
310 ICH_LR_EL2 ich_lr_el2 =
312 Gicv3::GroupId group =
313 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
314
315 if (group == Gicv3::G1NS) {
316 value = ich_lr_el2.vINTID;
317 }
318 }
319
320 break;
321 }
322
323 // Binary Point Register 0
324 case MISCREG_ICC_BPR0:
326 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
328 }
329
331 break;
332 }
333
334 // Binary Point Register 1
335 case MISCREG_ICC_BPR1:
338 break;
339 }
340
341 // Virtual Binary Point Register 0
343 ICH_VMCR_EL2 ich_vmcr_el2 =
345
346 value = ich_vmcr_el2.VBPR0;
347 break;
348 }
349
350 // Virtual Binary Point Register 1
352 ICH_VMCR_EL2 ich_vmcr_el2 =
354
355 if (ich_vmcr_el2.VCBPR) {
356 // bpr0 + 1 saturated to 7, WI
357 value = ich_vmcr_el2.VBPR0 + 1;
358 value = value < 7 ? value : 7;
359 } else {
360 value = ich_vmcr_el2.VBPR1;
361 }
362
363 break;
364 }
365
366 // Interrupt Priority Mask Register
367 case MISCREG_ICC_PMR:
369 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
371 }
372
373 if (haveEL(EL3) && !inSecureState() &&
374 (tc->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
375 // Spec section 4.8.1
376 // For Non-secure access to ICC_PMR_EL1 when SCR_EL3.FIQ == 1:
377 if ((value & 0x80) == 0) {
378 // If the current priority mask value is in the range of
379 // 0x00-0x7F a read access returns the value 0x00.
380 value = 0;
381 } else if (value != 0xff) {
382 // If the current priority mask value is in the range of
383 // 0x80-0xFF a read access returns the Non-secure read of the
384 // current value.
385 value = (value << 1) & 0xff;
386 }
387 }
388
389 break;
390
391 case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
392 ICH_VMCR_EL2 ich_vmcr_el2 =
394
395 value = ich_vmcr_el2.VPMR;
396 break;
397 }
398
399 // Interrupt Acknowledge Register 0
400 case MISCREG_ICC_IAR0:
402 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
404 }
405
406 uint32_t int_id;
407
408 if (hppiCanPreempt()) {
409 int_id = getHPPIR0();
410
411 // avoid activation for special interrupts
412 if (int_id < Gicv3::INTID_SECURE ||
414 activateIRQ(int_id, hppi.group);
415 }
416 } else {
417 int_id = Gicv3::INTID_SPURIOUS;
418 }
419
420 value = int_id;
421 break;
422 }
423
424 // Virtual Interrupt Acknowledge Register 0
426 int lr_idx = getHPPVILR();
427 uint32_t int_id = Gicv3::INTID_SPURIOUS;
428
429 if (lr_idx >= 0) {
430 ICH_LR_EL2 ich_lr_el2 =
432
433 if (!ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
434 int_id = ich_lr_el2.vINTID;
435
436 if (int_id < Gicv3::INTID_SECURE ||
437 int_id > Gicv3::INTID_SPURIOUS) {
438 virtualActivateIRQ(lr_idx);
439 } else {
440 // Bogus... Pseudocode says:
441 // - Move from pending to invalid...
442 // - Return de bogus id...
443 ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
445 ich_lr_el2);
446 }
447 }
448 }
449
450 value = int_id;
452 break;
453 }
454
455 // Interrupt Acknowledge Register 1
456 case MISCREG_ICC_IAR1:
458 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
460 }
461
462 uint32_t int_id;
463
464 if (hppiCanPreempt()) {
465 int_id = getHPPIR1();
466
467 // avoid activation for special interrupts
468 if (int_id < Gicv3::INTID_SECURE ||
470 activateIRQ(int_id, hppi.group);
471 }
472 } else {
473 int_id = Gicv3::INTID_SPURIOUS;
474 }
475
476 value = int_id;
477 break;
478 }
479
480 // Virtual Interrupt Acknowledge Register 1
482 int lr_idx = getHPPVILR();
483 uint32_t int_id = Gicv3::INTID_SPURIOUS;
484
485 if (lr_idx >= 0) {
486 ICH_LR_EL2 ich_lr_el2 =
488
489 if (ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
490 int_id = ich_lr_el2.vINTID;
491
492 if (int_id < Gicv3::INTID_SECURE ||
493 int_id > Gicv3::INTID_SPURIOUS) {
494 virtualActivateIRQ(lr_idx);
495 } else {
496 // Bogus... Pseudocode says:
497 // - Move from pending to invalid...
498 // - Return de bogus id...
499 ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
501 ich_lr_el2);
502 }
503 }
504 }
505
506 value = int_id;
508 break;
509 }
510
511 // System Register Enable Register EL1
512 case MISCREG_ICC_SRE:
513 case MISCREG_ICC_SRE_EL1: {
514 /*
515 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
516 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
517 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
518 */
519 ICC_SRE_EL1 icc_sre_el1 = 0;
520 icc_sre_el1.SRE = 1;
521 icc_sre_el1.DIB = 1;
522 icc_sre_el1.DFB = 1;
523 value = icc_sre_el1;
524 break;
525 }
526
527 // System Register Enable Register EL2
528 case MISCREG_ICC_HSRE:
529 case MISCREG_ICC_SRE_EL2: {
530 /*
531 * Enable [3] == 1
532 * (EL1 accesses to ICC_SRE_EL1 do not trap to EL2, RAO/WI)
533 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
534 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
535 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
536 */
537 ICC_SRE_EL2 icc_sre_el2 = 0;
538 icc_sre_el2.SRE = 1;
539 icc_sre_el2.DIB = 1;
540 icc_sre_el2.DFB = 1;
541 icc_sre_el2.Enable = 1;
542 value = icc_sre_el2;
543 break;
544 }
545
546 // System Register Enable Register EL3
547 case MISCREG_ICC_MSRE:
548 case MISCREG_ICC_SRE_EL3: {
549 /*
550 * Enable [3] == 1
551 * (EL1 accesses to ICC_SRE_EL1 do not trap to EL3.
552 * EL2 accesses to ICC_SRE_EL1 and ICC_SRE_EL2 do not trap to EL3.
553 * RAO/WI)
554 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
555 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
556 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
557 */
558 ICC_SRE_EL3 icc_sre_el3 = 0;
559 icc_sre_el3.SRE = 1;
560 icc_sre_el3.DIB = 1;
561 icc_sre_el3.DFB = 1;
562 icc_sre_el3.Enable = 1;
563 value = icc_sre_el3;
564 break;
565 }
566
567 // Control Register
568 case MISCREG_ICC_CTLR:
570 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
572 }
573
575 // Enforce value for RO bits
576 // ExtRange [19], INTIDs in the range 1024..8191 not supported
577 // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
578 // A3V [15], supports non-zero values of the Aff3 field in SGI
579 // generation System registers
580 // SEIS [14], does not support generation of SEIs (deprecated)
581 // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
582 // PRIbits [10:8], number of priority bits implemented, minus one
583 ICC_CTLR_EL1 icc_ctlr_el1 = value;
584 icc_ctlr_el1.ExtRange = 0;
585 icc_ctlr_el1.RSS = 1;
586 icc_ctlr_el1.A3V = 1;
587 icc_ctlr_el1.SEIS = 0;
588 icc_ctlr_el1.IDbits = 1;
589 icc_ctlr_el1.PRIbits = PRIORITY_BITS - 1;
590 value = icc_ctlr_el1;
591 break;
592 }
593
594 // Virtual Control Register
596 ICV_CTLR_EL1 icv_ctlr_el1 = value;
597 icv_ctlr_el1.RSS = 0;
598 icv_ctlr_el1.A3V = 1;
599 icv_ctlr_el1.SEIS = 0;
600 icv_ctlr_el1.IDbits = 1;
601 icv_ctlr_el1.PRIbits = 7;
602 value = icv_ctlr_el1;
603 break;
604 }
605
606 // Control Register
609 // Enforce value for RO bits
610 // ExtRange [19], INTIDs in the range 1024..8191 not supported
611 // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
612 // nDS [17], supports disabling of security
613 // A3V [15], supports non-zero values of the Aff3 field in SGI
614 // generation System registers
615 // SEIS [14], does not support generation of SEIs (deprecated)
616 // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
617 // PRIbits [10:8], number of priority bits implemented, minus one
618 ICC_CTLR_EL3 icc_ctlr_el3 = value;
619 icc_ctlr_el3.ExtRange = 0;
620 icc_ctlr_el3.RSS = 1;
621 icc_ctlr_el3.nDS = 0;
622 icc_ctlr_el3.A3V = 1;
623 icc_ctlr_el3.SEIS = 0;
624 icc_ctlr_el3.IDbits = 0;
625 icc_ctlr_el3.PRIbits = PRIORITY_BITS - 1;
626 value = icc_ctlr_el3;
627 break;
628 }
629
630 // Hyp Control Register
631 case MISCREG_ICH_HCR:
633 break;
634
635 // Hyp Active Priorities Group 0 Registers
638 break;
639
640 // only implemented if supporting 6 or more bits of priority
643 // only implemented if supporting 7 or more bits of priority
646 // only implemented if supporting 7 or more bits of priority
649 // Unimplemented registers are RAZ/WI
650 return 0;
651
652 // Hyp Active Priorities Group 1 Registers
655 break;
656
657 // only implemented if supporting 6 or more bits of priority
660 // only implemented if supporting 7 or more bits of priority
663 // only implemented if supporting 7 or more bits of priority
666 // Unimplemented registers are RAZ/WI
667 return 0;
668
669 // Maintenance Interrupt State Register
670 case MISCREG_ICH_MISR:
673 break;
674
675 // VGIC Type Register
676 case MISCREG_ICH_VTR:
677 case MISCREG_ICH_VTR_EL2: {
678 ICH_VTR_EL2 ich_vtr_el2 = value;
679
680 ich_vtr_el2.ListRegs = VIRTUAL_NUM_LIST_REGS - 1;
681 ich_vtr_el2.A3V = 1;
682 ich_vtr_el2.IDbits = 1;
683 ich_vtr_el2.PREbits = VIRTUAL_PREEMPTION_BITS - 1;
684 ich_vtr_el2.PRIbits = VIRTUAL_PRIORITY_BITS - 1;
685
686 value = ich_vtr_el2;
687 break;
688 }
689
690 // End of Interrupt Status Register
691 case MISCREG_ICH_EISR:
694 break;
695
696 // Empty List Register Status Register
699 value = 0;
700
701 for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
702 ICH_LR_EL2 ich_lr_el2 =
704
705 if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
706 (ich_lr_el2.HW || !ich_lr_el2.EOI)) {
707 value |= (1 << lr_idx);
708 }
709 }
710
711 break;
712
713 // List Registers
715 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
716 value = value >> 32;
717 break;
718
719 // List Registers
721 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
722 value = value & 0xffffffff;
723 break;
724
725 // List Registers
727 break;
728
729 // Virtual Machine Control Register
730 case MISCREG_ICH_VMCR:
732 break;
733
734 default:
735 panic("Gicv3CPUInterface::readMiscReg(): unknown register %d (%s)",
736 misc_reg, miscRegName[misc_reg]);
737 }
738
739 DPRINTF(GIC, "Gicv3CPUInterface::readMiscReg(): register %s value %#x\n",
740 miscRegName[misc_reg], value);
741 return value;
742}
743
744void
746{
747 bool do_virtual_update = false;
748 DPRINTF(GIC, "Gicv3CPUInterface::setMiscReg(): register %s value %#x\n",
749 miscRegName[misc_reg], val);
750 bool hcr_fmo = getHCREL2FMO();
751 bool hcr_imo = getHCREL2IMO();
752
753 switch (misc_reg) {
754 // Active Priorities Group 1 Registers
757 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
759 }
760
762 return;
763
766
767 // only implemented if supporting 6 or more bits of priority
770
771 // only implemented if supporting 7 or more bits of priority
774 // only implemented if supporting 7 or more bits of priority
775 break;
776
777 // Active Priorities Group 0 Registers
780 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
782 }
783
784 break;
785
788
789 // only implemented if supporting 6 or more bits of priority
792
793 // only implemented if supporting 7 or more bits of priority
796 // only implemented if supporting 7 or more bits of priority
797 break;
798
799 // End Of Interrupt Register 0
801 case MISCREG_ICC_EOIR0_EL1: { // End Of Interrupt Register 0
802 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
804 }
805
806 int int_id = val & 0xffffff;
807
808 // avoid activation for special interrupts
809 if (int_id >= Gicv3::INTID_SECURE &&
810 int_id <= Gicv3::INTID_SPURIOUS) {
811 return;
812 }
813
815
816 if (highestActiveGroup() != group) {
817 return;
818 }
819
820 dropPriority(group);
821
822 if (!isEOISplitMode()) {
823 deactivateIRQ(int_id, group);
824 }
825
826 break;
827 }
828
829 // Virtual End Of Interrupt Register 0
831 int int_id = val & 0xffffff;
832
833 // avoid deactivation for special interrupts
834 if (int_id >= Gicv3::INTID_SECURE &&
835 int_id <= Gicv3::INTID_SPURIOUS) {
836 return;
837 }
838
839 uint8_t drop_prio = virtualDropPriority();
840
841 if (drop_prio == 0xff) {
842 return;
843 }
844
845 int lr_idx = virtualFindActive(int_id);
846
847 if (lr_idx < 0) {
848 // No LR found matching
850 } else {
851 ICH_LR_EL2 ich_lr_el2 =
853 Gicv3::GroupId lr_group =
854 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
855 uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
856
857 if (lr_group == Gicv3::G0S && lr_group_prio == drop_prio) {
858 //if (!virtualIsEOISplitMode())
859 {
860 virtualDeactivateIRQ(lr_idx);
861 }
862 }
863 }
864
866 break;
867 }
868
869 // End Of Interrupt Register 1
872 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
874 }
875
876 int int_id = val & 0xffffff;
877
878 // avoid deactivation for special interrupts
879 if (int_id >= Gicv3::INTID_SECURE &&
880 int_id <= Gicv3::INTID_SPURIOUS) {
881 return;
882 }
883
885
887 return;
888 }
889
890 if (distributor->DS == 0) {
892 return;
893 } else if (highestActiveGroup() == Gicv3::G1NS &&
894 !(!inSecureState() or (currEL() == EL3))) {
895 return;
896 }
897 }
898
899 dropPriority(group);
900
901 if (!isEOISplitMode()) {
902 deactivateIRQ(int_id, group);
903 }
904
905 break;
906 }
907
908 // Virtual End Of Interrupt Register 1
910 int int_id = val & 0xffffff;
911
912 // avoid deactivation for special interrupts
913 if (int_id >= Gicv3::INTID_SECURE &&
914 int_id <= Gicv3::INTID_SPURIOUS) {
915 return;
916 }
917
918 uint8_t drop_prio = virtualDropPriority();
919
920 if (drop_prio == 0xff) {
921 return;
922 }
923
924 int lr_idx = virtualFindActive(int_id);
925
926 if (lr_idx < 0) {
927 // No matching LR found
929 } else {
930 ICH_LR_EL2 ich_lr_el2 =
932 Gicv3::GroupId lr_group =
933 ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
934 uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
935
936 if (lr_group == Gicv3::G1NS && lr_group_prio == drop_prio) {
937 if (!virtualIsEOISplitMode()) {
938 virtualDeactivateIRQ(lr_idx);
939 }
940 }
941 }
942
944 break;
945 }
946
947 // Deactivate Interrupt Register
948 case MISCREG_ICC_DIR:
949 case MISCREG_ICC_DIR_EL1: {
950 if ((currEL() == EL1) && !inSecureState() &&
951 (hcr_imo || hcr_fmo)) {
953 }
954
955 int int_id = val & 0xffffff;
956
957 // The following checks are as per spec pseudocode
958 // aarch64/support/ICC_DIR_EL1
959
960 // Check for spurious ID
961 if (int_id >= Gicv3::INTID_SECURE) {
962 return;
963 }
964
965 // EOI mode is not set, so don't deactivate
966 if (!isEOISplitMode()) {
967 return;
968 }
969
970 Gicv3::GroupId group =
971 int_id >= 32 ? distributor->getIntGroup(int_id) :
972 redistributor->getIntGroup(int_id);
973 bool irq_is_grp0 = group == Gicv3::G0S;
974 bool single_sec_state = distributor->DS;
975 bool irq_is_secure = !single_sec_state && (group != Gicv3::G1NS);
976 SCR scr_el3 = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
977 bool route_fiq_to_el3 = scr_el3.fiq;
978 bool route_irq_to_el3 = scr_el3.irq;
979 bool route_fiq_to_el2 = hcr_fmo;
980 bool route_irq_to_el2 = hcr_imo;
981
982 switch (currEL()) {
983 case EL3:
984 break;
985
986 case EL2:
987 if (single_sec_state && irq_is_grp0 && !route_fiq_to_el3) {
988 break;
989 }
990
991 if (!irq_is_secure && !irq_is_grp0 && !route_irq_to_el3) {
992 break;
993 }
994
995 return;
996
997 case EL1:
998 if (!isSecureBelowEL3()) {
999 if (single_sec_state && irq_is_grp0 &&
1000 !route_fiq_to_el3 && !route_fiq_to_el2) {
1001 break;
1002 }
1003
1004 if (!irq_is_secure && !irq_is_grp0 &&
1005 !route_irq_to_el3 && !route_irq_to_el2) {
1006 break;
1007 }
1008 } else {
1009 if (irq_is_grp0 && !route_fiq_to_el3) {
1010 break;
1011 }
1012
1013 if (!irq_is_grp0 &&
1014 (!irq_is_secure || !single_sec_state) &&
1015 !route_irq_to_el3) {
1016 break;
1017 }
1018 }
1019
1020 return;
1021
1022 default:
1023 break;
1024 }
1025
1026 deactivateIRQ(int_id, group);
1027 break;
1028 }
1029
1030 // Deactivate Virtual Interrupt Register
1031 case MISCREG_ICV_DIR_EL1: {
1032 int int_id = val & 0xffffff;
1033
1034 // avoid deactivation for special interrupts
1035 if (int_id >= Gicv3::INTID_SECURE &&
1036 int_id <= Gicv3::INTID_SPURIOUS) {
1037 return;
1038 }
1039
1040 if (!virtualIsEOISplitMode()) {
1041 return;
1042 }
1043
1044 int lr_idx = virtualFindActive(int_id);
1045
1046 if (lr_idx < 0) {
1047 // No matching LR found
1049 } else {
1050 virtualDeactivateIRQ(lr_idx);
1051 }
1052
1053 virtualUpdate();
1054 break;
1055 }
1056
1057 // Binary Point Register 0
1058 case MISCREG_ICC_BPR0:
1059 case MISCREG_ICC_BPR0_EL1: {
1060 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
1062 }
1063 break;
1064 }
1065 // Binary Point Register 1
1066 case MISCREG_ICC_BPR1:
1067 case MISCREG_ICC_BPR1_EL1: {
1068 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
1070 }
1071
1072 val &= 0x7;
1073
1074 if (isSecureBelowEL3()) {
1075 // group == Gicv3::G1S
1076 ICC_CTLR_EL1 icc_ctlr_el1_s =
1078
1080 if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_s.CBPR) {
1082 } else {
1084 }
1085 return;
1086 } else {
1087 // group == Gicv3::G1NS
1088 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1090
1092 if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_ns.CBPR) {
1093 // Non secure writes from EL1 and EL2 are ignored
1094 } else {
1096 }
1097 return;
1098 }
1099
1100 break;
1101 }
1102
1103 // Virtual Binary Point Register 0
1105 // Virtual Binary Point Register 1
1106 case MISCREG_ICV_BPR1_EL1: {
1107 Gicv3::GroupId group =
1109 ICH_VMCR_EL2 ich_vmcr_el2 =
1111
1112 if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
1113 // BPR0 + 1 saturated to 7, WI
1114 return;
1115 }
1116
1117 uint8_t min_VPBR = 7 - VIRTUAL_PREEMPTION_BITS;
1118
1119 if (group != Gicv3::G0S) {
1120 min_VPBR++;
1121 }
1122
1123 if (val < min_VPBR) {
1124 val = min_VPBR;
1125 }
1126
1127 if (group == Gicv3::G0S) {
1128 ich_vmcr_el2.VBPR0 = val;
1129 } else {
1130 ich_vmcr_el2.VBPR1 = val;
1131 }
1132
1134 do_virtual_update = true;
1135 break;
1136 }
1137
1138 // Control Register EL1
1139 case MISCREG_ICC_CTLR:
1140 case MISCREG_ICC_CTLR_EL1: {
1141 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
1143 }
1144
1145 /*
1146 * ExtRange is RO.
1147 * RSS is RO.
1148 * A3V is RO.
1149 * SEIS is RO.
1150 * IDbits is RO.
1151 * PRIbits is RO.
1152 */
1153 ICC_CTLR_EL1 requested_icc_ctlr_el1 = val;
1154 ICC_CTLR_EL1 icc_ctlr_el1 =
1156
1157 ICC_CTLR_EL3 icc_ctlr_el3 =
1159
1160 // The following could be refactored but it is following
1161 // spec description section 9.2.6 point by point.
1162
1163 // PMHE
1164 if (haveEL(EL3)) {
1165 // PMHE is alias of ICC_CTLR_EL3.PMHE
1166
1167 if (distributor->DS == 0) {
1168 // PMHE is RO
1169 } else if (distributor->DS == 1) {
1170 // PMHE is RW
1171 icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
1172 icc_ctlr_el3.PMHE = icc_ctlr_el1.PMHE;
1173 }
1174 } else {
1175 // PMHE is RW (by implementation choice)
1176 icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
1177 }
1178
1179 // EOImode
1180 icc_ctlr_el1.EOImode = requested_icc_ctlr_el1.EOImode;
1181
1182 if (inSecureState()) {
1183 // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1S
1184 icc_ctlr_el3.EOImode_EL1S = icc_ctlr_el1.EOImode;
1185 } else {
1186 // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1NS
1187 icc_ctlr_el3.EOImode_EL1NS = icc_ctlr_el1.EOImode;
1188 }
1189
1190 // CBPR
1191 if (haveEL(EL3)) {
1192 // CBPR is alias of ICC_CTLR_EL3.CBPR_EL1{S,NS}
1193
1194 if (distributor->DS == 0) {
1195 // CBPR is RO
1196 } else {
1197 // CBPR is RW
1198 icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
1199
1200 if (inSecureState()) {
1201 icc_ctlr_el3.CBPR_EL1S = icc_ctlr_el1.CBPR;
1202 } else {
1203 icc_ctlr_el3.CBPR_EL1NS = icc_ctlr_el1.CBPR;
1204 }
1205 }
1206 } else {
1207 // CBPR is RW
1208 icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
1209 }
1210
1212
1214 return;
1215 }
1216
1217 // Virtual Control Register
1218 case MISCREG_ICV_CTLR_EL1: {
1219 ICV_CTLR_EL1 requested_icv_ctlr_el1 = val;
1220 ICV_CTLR_EL1 icv_ctlr_el1 =
1222 icv_ctlr_el1.EOImode = requested_icv_ctlr_el1.EOImode;
1223 icv_ctlr_el1.CBPR = requested_icv_ctlr_el1.CBPR;
1224 val = icv_ctlr_el1;
1225
1226 // Aliases
1227 // ICV_CTLR_EL1.CBPR aliases ICH_VMCR_EL2.VCBPR.
1228 // ICV_CTLR_EL1.EOImode aliases ICH_VMCR_EL2.VEOIM.
1229 ICH_VMCR_EL2 ich_vmcr_el2 =
1231 ich_vmcr_el2.VCBPR = icv_ctlr_el1.CBPR;
1232 ich_vmcr_el2.VEOIM = icv_ctlr_el1.EOImode;
1234 break;
1235 }
1236
1237 // Control Register EL3
1238 case MISCREG_ICC_MCTLR:
1239 case MISCREG_ICC_CTLR_EL3: {
1240 /*
1241 * ExtRange is RO.
1242 * RSS is RO.
1243 * nDS is RO.
1244 * A3V is RO.
1245 * SEIS is RO.
1246 * IDbits is RO.
1247 * PRIbits is RO.
1248 * PMHE is RAO/WI, priority-based routing is always used.
1249 */
1250 ICC_CTLR_EL3 requested_icc_ctlr_el3 = val;
1251
1252 // Aliases
1253 if (haveEL(EL3))
1254 {
1255 ICC_CTLR_EL1 icc_ctlr_el1_s =
1257 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1259
1260 // ICC_CTLR_EL1(NS).EOImode is an alias of
1261 // ICC_CTLR_EL3.EOImode_EL1NS
1262 icc_ctlr_el1_ns.EOImode = requested_icc_ctlr_el3.EOImode_EL1NS;
1263 // ICC_CTLR_EL1(S).EOImode is an alias of
1264 // ICC_CTLR_EL3.EOImode_EL1S
1265 icc_ctlr_el1_s.EOImode = requested_icc_ctlr_el3.EOImode_EL1S;
1266 // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS
1267 icc_ctlr_el1_ns.CBPR = requested_icc_ctlr_el3.CBPR_EL1NS;
1268 // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S
1269 icc_ctlr_el1_s.CBPR = requested_icc_ctlr_el3.CBPR_EL1S;
1270
1273 icc_ctlr_el1_ns);
1274 }
1275
1276 ICC_CTLR_EL3 icc_ctlr_el3 =
1278
1279 icc_ctlr_el3.RM = requested_icc_ctlr_el3.RM;
1280 icc_ctlr_el3.EOImode_EL1NS = requested_icc_ctlr_el3.EOImode_EL1NS;
1281 icc_ctlr_el3.EOImode_EL1S = requested_icc_ctlr_el3.EOImode_EL1S;
1282 icc_ctlr_el3.EOImode_EL3 = requested_icc_ctlr_el3.EOImode_EL3;
1283 icc_ctlr_el3.CBPR_EL1NS = requested_icc_ctlr_el3.CBPR_EL1NS;
1284 icc_ctlr_el3.CBPR_EL1S = requested_icc_ctlr_el3.CBPR_EL1S;
1285
1286 val = icc_ctlr_el3;
1287 break;
1288 }
1289
1290 // Priority Mask Register
1291 case MISCREG_ICC_PMR:
1292 case MISCREG_ICC_PMR_EL1: {
1293 if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
1295 }
1296
1297 val &= 0xff;
1298 SCR scr_el3 = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
1299
1300 if (haveEL(EL3) && !inSecureState() && (scr_el3.fiq)) {
1301 // Spec section 4.8.1
1302 // For Non-secure access to ICC_PMR_EL1 SCR_EL3.FIQ == 1:
1303 RegVal old_icc_pmr_el1 =
1305
1306 if (!(old_icc_pmr_el1 & 0x80)) {
1307 // If the current priority mask value is in the range of
1308 // 0x00-0x7F then WI
1309 return;
1310 }
1311
1312 // If the current priority mask value is in the range of
1313 // 0x80-0xFF then a write access to ICC_PMR_EL1 succeeds,
1314 // based on the Non-secure read of the priority mask value
1315 // written to the register.
1316
1317 val = (val >> 1) | 0x80;
1318 }
1319
1320 val &= ~0U << (8 - PRIORITY_BITS);
1321 break;
1322 }
1323
1324 case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
1325 ICH_VMCR_EL2 ich_vmcr_el2 =
1327 ich_vmcr_el2.VPMR = val & 0xff;
1328
1330 virtualUpdate();
1331 return;
1332 }
1333
1334 // Interrupt Group 0 Enable Register EL1
1337 if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
1339 }
1340
1343 return;
1344 }
1345
1346 // Virtual Interrupt Group 0 Enable register
1348 bool enable = val & 0x1;
1349 ICH_VMCR_EL2 ich_vmcr_el2 =
1351 ich_vmcr_el2.VENG0 = enable;
1353 virtualUpdate();
1354 return;
1355 }
1356
1357 // Interrupt Group 1 Enable register EL1
1360 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
1362 }
1363
1366 return;
1367 }
1368
1369 // Virtual Interrupt Group 1 Enable register
1371 bool enable = val & 0x1;
1372 ICH_VMCR_EL2 ich_vmcr_el2 =
1374 ich_vmcr_el2.VENG1 = enable;
1376 virtualUpdate();
1377 return;
1378 }
1379
1380 // Interrupt Group 1 Enable register
1383 ICC_IGRPEN1_EL3 icc_igrpen1_el3 = val;
1384
1386 MISCREG_ICC_IGRPEN1_EL1_S, icc_igrpen1_el3.EnableGrp1S);
1388 MISCREG_ICC_IGRPEN1_EL1_NS, icc_igrpen1_el3.EnableGrp1NS);
1390 return;
1391 }
1392
1393 // Software Generated Interrupt Group 0 Register
1394 case MISCREG_ICC_SGI0R:
1397 break;
1398
1399 // Software Generated Interrupt Group 1 Register
1400 case MISCREG_ICC_SGI1R:
1401 case MISCREG_ICC_SGI1R_EL1: {
1403
1404 generateSGI(val, group);
1405 break;
1406 }
1407
1408 // Alias Software Generated Interrupt Group 1 Register
1409 case MISCREG_ICC_ASGI1R:
1412
1413 generateSGI(val, group);
1414 break;
1415 }
1416
1417 // System Register Enable Register EL1
1418 case MISCREG_ICC_SRE:
1420 // System Register Enable Register EL2
1421 case MISCREG_ICC_HSRE:
1423 // System Register Enable Register EL3
1424 case MISCREG_ICC_MSRE:
1426 // All bits are RAO/WI
1427 return;
1428
1429 // Hyp Control Register
1430 case MISCREG_ICH_HCR:
1431 case MISCREG_ICH_HCR_EL2: {
1432 ICH_HCR_EL2 requested_ich_hcr_el2 = val;
1433 ICH_HCR_EL2 ich_hcr_el2 =
1435
1436 if (requested_ich_hcr_el2.EOIcount >= ich_hcr_el2.EOIcount)
1437 {
1438 // EOIcount - Permitted behaviors are:
1439 // - Increment EOIcount.
1440 // - Leave EOIcount unchanged.
1441 ich_hcr_el2.EOIcount = requested_ich_hcr_el2.EOIcount;
1442 }
1443
1444 ich_hcr_el2.TDIR = requested_ich_hcr_el2.TDIR;
1445 ich_hcr_el2.TSEI = requested_ich_hcr_el2.TSEI;
1446 ich_hcr_el2.TALL1 = requested_ich_hcr_el2.TALL1;;
1447 ich_hcr_el2.TALL0 = requested_ich_hcr_el2.TALL0;;
1448 ich_hcr_el2.TC = requested_ich_hcr_el2.TC;
1449 ich_hcr_el2.VGrp1DIE = requested_ich_hcr_el2.VGrp1DIE;
1450 ich_hcr_el2.VGrp1EIE = requested_ich_hcr_el2.VGrp1EIE;
1451 ich_hcr_el2.VGrp0DIE = requested_ich_hcr_el2.VGrp0DIE;
1452 ich_hcr_el2.VGrp0EIE = requested_ich_hcr_el2.VGrp0EIE;
1453 ich_hcr_el2.NPIE = requested_ich_hcr_el2.NPIE;
1454 ich_hcr_el2.LRENPIE = requested_ich_hcr_el2.LRENPIE;
1455 ich_hcr_el2.UIE = requested_ich_hcr_el2.UIE;
1456 ich_hcr_el2.En = requested_ich_hcr_el2.En;
1457 val = ich_hcr_el2;
1458 do_virtual_update = true;
1459 break;
1460 }
1461
1462 // List Registers
1464 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
1465 ICH_LRC requested_ich_lrc = val;
1466 ICH_LRC ich_lrc = isa->readMiscRegNoEffect(misc_reg);
1467
1468 ich_lrc.State = requested_ich_lrc.State;
1469 ich_lrc.HW = requested_ich_lrc.HW;
1470 ich_lrc.Group = requested_ich_lrc.Group;
1471
1472 // Priority, bits [23:16]
1473 // At least five bits must be implemented.
1474 // Unimplemented bits are RES0 and start from bit[16] up to bit[18].
1475 // We implement 5 bits.
1476 ich_lrc.Priority = (requested_ich_lrc.Priority & 0xf8) |
1477 (ich_lrc.Priority & 0x07);
1478
1479 // pINTID, bits [12:0]
1480 // When ICH_LR<n>.HW is 0 this field has the following meaning:
1481 // - Bits[12:10] : RES0.
1482 // - Bit[9] : EOI.
1483 // - Bits[8:0] : RES0.
1484 // When ICH_LR<n>.HW is 1:
1485 // - This field is only required to implement enough bits to hold a
1486 // valid value for the implemented INTID size. Any unused higher
1487 // order bits are RES0.
1488 if (requested_ich_lrc.HW == 0) {
1489 ich_lrc.EOI = requested_ich_lrc.EOI;
1490 } else {
1491 ich_lrc.pINTID = requested_ich_lrc.pINTID;
1492 }
1493
1494 val = ich_lrc;
1495 do_virtual_update = true;
1496 break;
1497 }
1498
1499 // List Registers
1501 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
1502 RegVal old_val = isa->readMiscRegNoEffect(misc_reg);
1503 val = (old_val & 0xffffffff00000000) | (val & 0xffffffff);
1504 do_virtual_update = true;
1505 break;
1506 }
1507
1508 // List Registers
1509 case MISCREG_ICH_LR0_EL2 ... MISCREG_ICH_LR15_EL2: { // AArch64
1510 ICH_LR_EL2 requested_ich_lr_el2 = val;
1511 ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(misc_reg);
1512
1513 ich_lr_el2.State = requested_ich_lr_el2.State;
1514 ich_lr_el2.HW = requested_ich_lr_el2.HW;
1515 ich_lr_el2.Group = requested_ich_lr_el2.Group;
1516
1517 // Priority, bits [55:48]
1518 // At least five bits must be implemented.
1519 // Unimplemented bits are RES0 and start from bit[48] up to bit[50].
1520 // We implement 5 bits.
1521 ich_lr_el2.Priority = (requested_ich_lr_el2.Priority & 0xf8) |
1522 (ich_lr_el2.Priority & 0x07);
1523
1524 // pINTID, bits [44:32]
1525 // When ICH_LR<n>_EL2.HW is 0 this field has the following meaning:
1526 // - Bits[44:42] : RES0.
1527 // - Bit[41] : EOI.
1528 // - Bits[40:32] : RES0.
1529 // When ICH_LR<n>_EL2.HW is 1:
1530 // - This field is only required to implement enough bits to hold a
1531 // valid value for the implemented INTID size. Any unused higher
1532 // order bits are RES0.
1533 if (requested_ich_lr_el2.HW == 0) {
1534 ich_lr_el2.EOI = requested_ich_lr_el2.EOI;
1535 } else {
1536 ich_lr_el2.pINTID = requested_ich_lr_el2.pINTID;
1537 }
1538
1539 // vINTID, bits [31:0]
1540 // It is IMPLEMENTATION DEFINED how many bits are implemented,
1541 // though at least 16 bits must be implemented.
1542 // Unimplemented bits are RES0.
1543 ich_lr_el2.vINTID = requested_ich_lr_el2.vINTID;
1544
1545 val = ich_lr_el2;
1546 do_virtual_update = true;
1547 break;
1548 }
1549
1550 // Virtual Machine Control Register
1551 case MISCREG_ICH_VMCR:
1552 case MISCREG_ICH_VMCR_EL2: {
1553 ICH_VMCR_EL2 requested_ich_vmcr_el2 = val;
1554 ICH_VMCR_EL2 ich_vmcr_el2 =
1556 ich_vmcr_el2.VPMR = requested_ich_vmcr_el2.VPMR;
1557 uint8_t min_vpr0 = 7 - VIRTUAL_PREEMPTION_BITS;
1558
1559 if (requested_ich_vmcr_el2.VBPR0 < min_vpr0) {
1560 ich_vmcr_el2.VBPR0 = min_vpr0;
1561 } else {
1562 ich_vmcr_el2.VBPR0 = requested_ich_vmcr_el2.VBPR0;
1563 }
1564
1565 uint8_t min_vpr1 = min_vpr0 + 1;
1566
1567 if (requested_ich_vmcr_el2.VBPR1 < min_vpr1) {
1568 ich_vmcr_el2.VBPR1 = min_vpr1;
1569 } else {
1570 ich_vmcr_el2.VBPR1 = requested_ich_vmcr_el2.VBPR1;
1571 }
1572
1573 ich_vmcr_el2.VEOIM = requested_ich_vmcr_el2.VEOIM;
1574 ich_vmcr_el2.VCBPR = requested_ich_vmcr_el2.VCBPR;
1575 ich_vmcr_el2.VENG1 = requested_ich_vmcr_el2.VENG1;
1576 ich_vmcr_el2.VENG0 = requested_ich_vmcr_el2.VENG0;
1577 val = ich_vmcr_el2;
1578 break;
1579 }
1580
1581 // Hyp Active Priorities Group 0 Registers
1582 case MISCREG_ICH_AP0R0:
1584 break;
1585
1586 // only implemented if supporting 6 or more bits of priority
1587 case MISCREG_ICH_AP0R1:
1589 // only implemented if supporting 7 or more bits of priority
1590 case MISCREG_ICH_AP0R2:
1592 // only implemented if supporting 7 or more bits of priority
1593 case MISCREG_ICH_AP0R3:
1595 // Unimplemented registers are RAZ/WI
1596 return;
1597
1598 // Hyp Active Priorities Group 1 Registers
1599 case MISCREG_ICH_AP1R0:
1601 break;
1602
1603 // only implemented if supporting 6 or more bits of priority
1604 case MISCREG_ICH_AP1R1:
1606 // only implemented if supporting 7 or more bits of priority
1607 case MISCREG_ICH_AP1R2:
1609 // only implemented if supporting 7 or more bits of priority
1610 case MISCREG_ICH_AP1R3:
1612 // Unimplemented registers are RAZ/WI
1613 return;
1614
1615 default:
1616 panic("Gicv3CPUInterface::setMiscReg(): unknown register %d (%s)",
1617 misc_reg, miscRegName[misc_reg]);
1618 }
1619
1620 isa->setMiscRegNoEffect(misc_reg, val);
1621
1622 if (do_virtual_update) {
1623 virtualUpdate();
1624 }
1625}
1626
1627RegVal
1633
1634void
1640
1641int
1643{
1644 for (uint32_t lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
1645 ICH_LR_EL2 ich_lr_el2 =
1647
1648 if (((ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE) ||
1649 (ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE_PENDING)) &&
1650 (ich_lr_el2.vINTID == int_id)) {
1651 return lr_idx;
1652 }
1653 }
1654
1655 return -1;
1656}
1657
1658uint32_t
1660{
1661 if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
1662 return Gicv3::INTID_SPURIOUS;
1663 }
1664
1665 bool irq_is_secure = !distributor->DS && hppi.group != Gicv3::G1NS;
1666
1667 if ((hppi.group != Gicv3::G0S) && isEL3OrMon()) {
1668 // interrupt for the other state pending
1669 return irq_is_secure ? Gicv3::INTID_SECURE : Gicv3::INTID_NONSECURE;
1670 }
1671
1672 if ((hppi.group != Gicv3::G0S)) { // && !isEL3OrMon())
1673 return Gicv3::INTID_SPURIOUS;
1674 }
1675
1676 if (irq_is_secure && !inSecureState()) {
1677 // Secure interrupts not visible in Non-secure
1678 return Gicv3::INTID_SPURIOUS;
1679 }
1680
1681 return hppi.intid;
1682}
1683
1684uint32_t
1686{
1687 if (hppi.prio == 0xff || !groupEnabled(hppi.group)) {
1688 return Gicv3::INTID_SPURIOUS;
1689 }
1690
1691 ICC_CTLR_EL3 icc_ctlr_el3 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
1692 if ((currEL() == EL3) && icc_ctlr_el3.RM) {
1693 if (hppi.group == Gicv3::G0S) {
1694 return Gicv3::INTID_SECURE;
1695 } else if (hppi.group == Gicv3::G1NS) {
1697 }
1698 }
1699
1700 if (hppi.group == Gicv3::G0S) {
1701 return Gicv3::INTID_SPURIOUS;
1702 }
1703
1704 bool irq_is_secure = (distributor->DS == 0) && (hppi.group != Gicv3::G1NS);
1705
1706 if (irq_is_secure) {
1707 if (!inSecureState()) {
1708 // Secure interrupts not visible in Non-secure
1709 return Gicv3::INTID_SPURIOUS;
1710 }
1711 } else if (!isEL3OrMon() && inSecureState()) {
1712 // Group 1 non-secure interrupts not visible in Secure EL1
1713 return Gicv3::INTID_SPURIOUS;
1714 }
1715
1716 return hppi.intid;
1717}
1718
1719void
1721{
1722 int apr_misc_reg = 0;
1723
1724 switch (group) {
1725 case Gicv3::G0S:
1726 apr_misc_reg = MISCREG_ICC_AP0R0_EL1;
1727 break;
1728 case Gicv3::G1S:
1729 apr_misc_reg = MISCREG_ICC_AP1R0_EL1_S;
1730 break;
1731 case Gicv3::G1NS:
1732 apr_misc_reg = MISCREG_ICC_AP1R0_EL1_NS;
1733 break;
1734 default:
1735 panic("Invalid Gicv3::GroupId");
1736 }
1737
1738 RegVal apr = isa->readMiscRegNoEffect(apr_misc_reg);
1739
1740 if (apr) {
1741 apr &= apr - 1;
1742 isa->setMiscRegNoEffect(apr_misc_reg, apr);
1743 }
1744
1745 update();
1746}
1747
1748uint8_t
1750{
1751 int apr_max = 1 << (VIRTUAL_PREEMPTION_BITS - 5);
1752
1753 for (int i = 0; i < apr_max; i++) {
1756
1757 if (!vapr0 && !vapr1) {
1758 continue;
1759 }
1760
1761 int vapr0_count = ctz32(vapr0);
1762 int vapr1_count = ctz32(vapr1);
1763
1764 if (vapr0_count <= vapr1_count) {
1765 vapr0 &= vapr0 - 1;
1767 return (vapr0_count + i * 32) << (GIC_MIN_VBPR + 1);
1768 } else {
1769 vapr1 &= vapr1 - 1;
1771 return (vapr1_count + i * 32) << (GIC_MIN_VBPR + 1);
1772 }
1773 }
1774
1775 return 0xff;
1776}
1777
1778void
1780{
1781 uint8_t aff3 = bits(val, 55, 48);
1782 uint8_t aff2 = bits(val, 39, 32);
1783 uint8_t aff1 = bits(val, 23, 16);;
1784 uint16_t target_list = bits(val, 15, 0);
1785 uint32_t int_id = bits(val, 27, 24);
1786 bool irm = bits(val, 40, 40);
1787 uint8_t rs = bits(val, 47, 44);
1788
1789 bool ns = !inSecureState();
1790
1791 for (int i = 0; i < gic->getSystem()->threads.size(); i++) {
1792 Gicv3Redistributor * redistributor_i =
1794 uint32_t affinity_i = redistributor_i->getAffinity();
1795
1796 if (irm) {
1797 // Interrupts routed to all PEs in the system,
1798 // excluding "self"
1799 if (affinity_i == redistributor->getAffinity()) {
1800 continue;
1801 }
1802 } else {
1803 // Interrupts routed to the PEs specified by
1804 // Aff3.Aff2.Aff1.<target list>
1805 if ((affinity_i >> 8) !=
1806 ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) {
1807 continue;
1808 }
1809
1810 uint8_t aff0_i = bits(affinity_i, 7, 0);
1811
1812 if (!(aff0_i >= rs * 16 && aff0_i < (rs + 1) * 16 &&
1813 ((0x1 << (aff0_i - rs * 16)) & target_list))) {
1814 continue;
1815 }
1816 }
1817
1818 redistributor_i->sendSGI(int_id, group, ns);
1819 }
1820}
1821
1822void
1823Gicv3CPUInterface::activateIRQ(uint32_t int_id, Gicv3::GroupId group)
1824{
1825 // Update active priority registers.
1826 uint32_t prio = hppi.prio & 0xf8;
1827 int apr_bit = prio >> (8 - PRIORITY_BITS);
1828 int reg_bit = apr_bit % 32;
1829
1830 int apr_idx = 0;
1831 switch (group) {
1832 case Gicv3::G0S:
1833 apr_idx = MISCREG_ICC_AP0R0_EL1;
1834 break;
1835 case Gicv3::G1S:
1836 apr_idx = MISCREG_ICC_AP1R0_EL1_S;
1837 break;
1838 case Gicv3::G1NS:
1839 apr_idx = MISCREG_ICC_AP1R0_EL1_NS;
1840 break;
1841 default:
1842 panic("Invalid Gicv3::GroupId");
1843 }
1844
1845 RegVal apr = isa->readMiscRegNoEffect(apr_idx);
1846 apr |= (1 << reg_bit);
1847 isa->setMiscRegNoEffect(apr_idx, apr);
1848
1849 // Move interrupt state from pending to active.
1850 if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
1851 // SGI or PPI, redistributor
1852 redistributor->activateIRQ(int_id);
1853 } else if (int_id < Gicv3::INTID_SECURE) {
1854 // SPI, distributor
1855 distributor->activateIRQ(int_id);
1856 } else if (int_id >= Gicv3Redistributor::SMALLEST_LPI_ID) {
1857 // LPI, Redistributor
1858 redistributor->setClrLPI(int_id, false);
1859 }
1860
1861 // By setting the priority to 0xff we are effectively
1862 // making the int_id not pending anymore at the cpu
1863 // interface.
1864 resetHppi(int_id);
1866}
1867
1868void
1870{
1871 // Update active priority registers.
1872 ICH_LR_EL2 ich_lr_el = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
1873 lr_idx);
1874 Gicv3::GroupId group = ich_lr_el.Group ? Gicv3::G1NS : Gicv3::G0S;
1875 uint8_t prio = ich_lr_el.Priority & 0xf8;
1876 int apr_bit = prio >> (8 - VIRTUAL_PREEMPTION_BITS);
1877 int reg_no = apr_bit / 32;
1878 int reg_bit = apr_bit % 32;
1879 int apr_idx = group == Gicv3::G0S ?
1880 MISCREG_ICH_AP0R0_EL2 + reg_no : MISCREG_ICH_AP1R0_EL2 + reg_no;
1881 RegVal apr = isa->readMiscRegNoEffect(apr_idx);
1882 apr |= (1 << reg_bit);
1883 isa->setMiscRegNoEffect(apr_idx, apr);
1884 // Move interrupt state from pending to active.
1885 ich_lr_el.State = ICH_LR_EL2_STATE_ACTIVE;
1886 isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el);
1887}
1888
1889void
1891{
1892 if (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX) {
1893 // SGI or PPI, redistributor
1895 } else if (int_id < Gicv3::INTID_SECURE) {
1896 // SPI, distributor
1897 distributor->deactivateIRQ(int_id);
1898 }
1899
1901}
1902
1903void
1905{
1906 ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
1907 lr_idx);
1908
1909 if (ich_lr_el2.HW) {
1910 // Deactivate the associated physical interrupt
1911 if (ich_lr_el2.pINTID < Gicv3::INTID_SECURE) {
1912 Gicv3::GroupId group = ich_lr_el2.pINTID >= 32 ?
1913 distributor->getIntGroup(ich_lr_el2.pINTID) :
1914 redistributor->getIntGroup(ich_lr_el2.pINTID);
1915 deactivateIRQ(ich_lr_el2.pINTID, group);
1916 }
1917 }
1918
1919 // Remove the active bit
1920 ich_lr_el2.State = ich_lr_el2.State & ~ICH_LR_EL2_STATE_ACTIVE;
1921 isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el2);
1922}
1923
1924/*
1925 * Returns the priority group field for the current BPR value for the group.
1926 * GroupBits() Pseudocode from spec.
1927 */
1928uint32_t
1930{
1931 ICC_CTLR_EL1 icc_ctlr_el1_s =
1933 ICC_CTLR_EL1 icc_ctlr_el1_ns =
1935
1936 if ((group == Gicv3::G1S && icc_ctlr_el1_s.CBPR) ||
1937 (group == Gicv3::G1NS && icc_ctlr_el1_ns.CBPR)) {
1938 group = Gicv3::G0S;
1939 }
1940
1941 int bpr;
1942
1943 if (group == Gicv3::G0S) {
1944 bpr = readMiscReg(MISCREG_ICC_BPR0_EL1) & 0x7;
1945 } else if (group == Gicv3::G1S) {
1946 bpr = bpr1(Gicv3::G1S) & 0x7;
1947 } else {
1948 bpr = bpr1(Gicv3::G1NS) & 0x7;
1949 }
1950
1951 if (group == Gicv3::G1NS) {
1952 assert(bpr > 0);
1953 bpr--;
1954 }
1955
1956 return ~0U << (bpr + 1);
1957}
1958
1959uint32_t
1961{
1962 ICH_VMCR_EL2 ich_vmcr_el2 =
1964
1965 if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
1966 group = Gicv3::G0S;
1967 }
1968
1969 int bpr;
1970
1971 if (group == Gicv3::G0S) {
1972 bpr = ich_vmcr_el2.VBPR0;
1973 } else {
1974 bpr = ich_vmcr_el2.VBPR1;
1975 }
1976
1977 if (group == Gicv3::G1NS) {
1978 assert(bpr > 0);
1979 bpr--;
1980 }
1981
1982 return ~0U << (bpr + 1);
1983}
1984
1985bool
1987{
1988 if (isEL3OrMon()) {
1989 ICC_CTLR_EL3 icc_ctlr_el3 =
1991 return icc_ctlr_el3.EOImode_EL3;
1992 } else {
1993 ICC_CTLR_EL1 icc_ctlr_el1 = 0;
1994 if (inSecureState())
1996 else
1998 return icc_ctlr_el1.EOImode;
1999 }
2000}
2001
2002bool
2004{
2005 ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
2006 return ich_vmcr_el2.VEOIM;
2007}
2008
2009int
2011{
2015
2016 if (g1nz_ctz < g0_ctz && g1nz_ctz < gq_ctz) {
2017 return Gicv3::G1NS;
2018 }
2019
2020 if (gq_ctz < g0_ctz) {
2021 return Gicv3::G1S;
2022 }
2023
2024 if (g0_ctz < 32) {
2025 return Gicv3::G0S;
2026 }
2027
2028 return -1;
2029}
2030
2031void
2036
2037void
2039{
2040 if (gic->blockIntUpdate())
2041 return;
2042
2043 bool signal_IRQ = false;
2044 bool signal_FIQ = false;
2045
2046 if (hppi.group == Gicv3::G1S && !haveEL(EL3)) {
2047 /*
2048 * Secure enabled GIC sending a G1S IRQ to a secure disabled
2049 * CPU -> send G0 IRQ
2050 */
2052 }
2053
2054 if (hppiCanPreempt()) {
2056 DPRINTF(GIC, "Gicv3CPUInterface::update(): "
2057 "posting int as %d!\n", int_type);
2058 int_type == INT_IRQ ? signal_IRQ = true : signal_FIQ = true;
2059 }
2060
2061 if (signal_IRQ) {
2063 } else {
2065 }
2066
2067 if (signal_FIQ) {
2069 } else {
2071 }
2072}
2073
2074void
2076{
2077 if (gic->blockIntUpdate())
2078 return;
2079
2080 bool signal_IRQ = false;
2081 bool signal_FIQ = false;
2082 int lr_idx = getHPPVILR();
2083
2084 if (lr_idx >= 0) {
2085 ICH_LR_EL2 ich_lr_el2 =
2087
2088 if (hppviCanPreempt(lr_idx)) {
2089 if (ich_lr_el2.Group) {
2090 signal_IRQ = true;
2091 } else {
2092 signal_FIQ = true;
2093 }
2094 }
2095 }
2096
2097 ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
2098
2099 const bool maint_pending = redistributor->irqPending[
2101
2102 if (ich_hcr_el2.En && !maint_pending && maintenanceInterruptStatus()) {
2104 } else if (maint_pending) {
2106 }
2107
2108 if (signal_IRQ) {
2109 DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
2110 "posting int as %d!\n", INT_VIRT_IRQ);
2112 } else {
2114 }
2115
2116 if (signal_FIQ) {
2117 DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
2118 "posting int as %d!\n", INT_VIRT_FIQ);
2120 } else {
2122 }
2123}
2124
2125// Returns the index of the LR with the HPPI
2126int
2128{
2129 int idx = -1;
2130 ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
2131
2132 if (!ich_vmcr_el2.VENG0 && !ich_vmcr_el2.VENG1) {
2133 // VG0 and VG1 disabled...
2134 return idx;
2135 }
2136
2137 uint8_t highest_prio = 0xff;
2138
2139 for (int i = 0; i < 16; i++) {
2140 ICH_LR_EL2 ich_lr_el2 =
2142
2143 if (ich_lr_el2.State != Gicv3::INT_PENDING) {
2144 continue;
2145 }
2146
2147 if (ich_lr_el2.Group) {
2148 // VG1
2149 if (!ich_vmcr_el2.VENG1) {
2150 continue;
2151 }
2152 } else {
2153 // VG0
2154 if (!ich_vmcr_el2.VENG0) {
2155 continue;
2156 }
2157 }
2158
2159 uint8_t prio = ich_lr_el2.Priority;
2160
2161 if (prio < highest_prio) {
2162 highest_prio = prio;
2163 idx = i;
2164 }
2165 }
2166
2167 return idx;
2168}
2169
2170bool
2172{
2173 ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
2174 if (!ich_hcr_el2.En) {
2175 // virtual interface is disabled
2176 return false;
2177 }
2178
2179 ICH_LR_EL2 ich_lr_el2 =
2181 uint8_t prio = ich_lr_el2.Priority;
2182 uint8_t vpmr =
2184
2185 if (prio >= vpmr) {
2186 // prioriry masked
2187 return false;
2188 }
2189
2190 uint8_t rprio = virtualHighestActivePriority();
2191
2192 if (rprio == 0xff) {
2193 return true;
2194 }
2195
2196 Gicv3::GroupId group = ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
2197 uint32_t prio_mask = virtualGroupPriorityMask(group);
2198
2199 if ((prio & prio_mask) < (rprio & prio_mask)) {
2200 return true;
2201 }
2202
2203 return false;
2204}
2205
2206uint8_t
2208{
2209 uint8_t num_aprs = 1 << (VIRTUAL_PRIORITY_BITS - 5);
2210
2211 for (int i = 0; i < num_aprs; i++) {
2212 RegVal vapr =
2215
2216 if (!vapr) {
2217 continue;
2218 }
2219
2220 return (i * 32 + ctz32(vapr)) << (GIC_MIN_VBPR + 1);
2221 }
2222
2223 // no active interrups, return idle priority
2224 return 0xff;
2225}
2226
2227void
2229{
2230 // Increment the EOICOUNT field in ICH_HCR_EL2
2232 uint32_t EOI_cout = bits(ich_hcr_el2, 31, 27);
2233 EOI_cout++;
2234 ich_hcr_el2 = insertBits(ich_hcr_el2, 31, 27, EOI_cout);
2236}
2237
2238// spec section 4.6.2
2241{
2242 bool is_fiq = false;
2243
2244 switch (group) {
2245 case Gicv3::G0S:
2246 is_fiq = true;
2247 break;
2248
2249 case Gicv3::G1S:
2250 is_fiq = (distributor->DS == 0) &&
2251 (!inSecureState() || ((currEL() == EL3) && isAA64()));
2252 break;
2253
2254 case Gicv3::G1NS:
2255 is_fiq = (distributor->DS == 0) && inSecureState();
2256 break;
2257
2258 default:
2259 panic("Gicv3CPUInterface::intSignalType(): invalid group!");
2260 }
2261
2262 if (is_fiq) {
2263 return INT_FIQ;
2264 } else {
2265 return INT_IRQ;
2266 }
2267}
2268
2269bool
2271{
2272 if (hppi.prio == 0xff) {
2273 // there is no pending interrupt
2274 return false;
2275 }
2276
2277 if (!groupEnabled(hppi.group)) {
2278 // group disabled at CPU interface
2279 return false;
2280 }
2281
2283 // priority masked
2284 return false;
2285 }
2286
2287 uint8_t rprio = highestActivePriority();
2288
2289 if (rprio == 0xff) {
2290 return true;
2291 }
2292
2293 uint32_t prio_mask = groupPriorityMask(hppi.group);
2294
2295 if ((hppi.prio & prio_mask) < (rprio & prio_mask)) {
2296 return true;
2297 }
2298
2299 return false;
2300}
2301
2302uint8_t
2304{
2308
2309 if (apr) {
2310 return ctz32(apr) << (GIC_MIN_BPR + 1);
2311 }
2312
2313 // no active interrups, return idle priority
2314 return 0xff;
2315}
2316
2317bool
2319{
2320 switch (group) {
2321 case Gicv3::G0S: {
2322 ICC_IGRPEN0_EL1 icc_igrpen0_el1 =
2324 return icc_igrpen0_el1.Enable && distributor->EnableGrp0;
2325 }
2326
2327 case Gicv3::G1S: {
2328 ICC_IGRPEN1_EL1 icc_igrpen1_el1_s =
2330 return icc_igrpen1_el1_s.Enable && distributor->EnableGrp1S;
2331 }
2332
2333 case Gicv3::G1NS: {
2334 ICC_IGRPEN1_EL1 icc_igrpen1_el1_ns =
2336 return icc_igrpen1_el1_ns.Enable && distributor->EnableGrp1NS;
2337 }
2338
2339 default:
2340 panic("Gicv3CPUInterface::groupEnable(): invalid group!\n");
2341 }
2342}
2343
2344bool
2346{
2347 return ArmISA::isSecure(tc);
2348}
2349
2352{
2353 return ArmISA::currEL(tc);
2354}
2355
2356bool
2358{
2359 switch (el) {
2360 case EL0:
2361 case EL1:
2362 return true;
2363
2364 case EL2:
2365 return gic->getSystem()->has(ArmExtension::VIRTUALIZATION);
2366
2367 case EL3:
2368 return gic->getSystem()->has(ArmExtension::SECURITY);
2369
2370 default:
2371 warn("Unimplemented Exception Level\n");
2372 return false;
2373 }
2374}
2375
2376bool
2381
2382bool
2384{
2385 return ArmISA::inAArch64(tc);
2386}
2387
2388bool
2390{
2391 return currEL() == EL3;
2392}
2393
2394// Computes ICH_EISR_EL2
2395uint64_t
2397{
2398 // ICH_EISR_EL2
2399 // Bits [63:16] - RES0
2400 // Status<n>, bit [n], for n = 0 to 15
2401 // EOI maintenance interrupt status bit for List register <n>:
2402 // 0 if List register <n>, ICH_LR<n>_EL2, does not have an EOI
2403 // maintenance interrupt.
2404 // 1 if List register <n>, ICH_LR<n>_EL2, has an EOI maintenance
2405 // interrupt that has not been handled.
2406 //
2407 // For any ICH_LR<n>_EL2, the corresponding status bit is set to 1 if all
2408 // of the following are true:
2409 // - ICH_LR<n>_EL2.State is 0b00 (ICH_LR_EL2_STATE_INVALID).
2410 // - ICH_LR<n>_EL2.HW is 0.
2411 // - ICH_LR<n>_EL2.EOI (bit [41]) is 1.
2412
2413 uint64_t value = 0;
2414
2415 for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
2416 ICH_LR_EL2 ich_lr_el2 =
2418
2419 if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
2420 !ich_lr_el2.HW && ich_lr_el2.EOI) {
2421 value |= (1 << lr_idx);
2422 }
2423 }
2424
2425 return value;
2426}
2427
2428Gicv3CPUInterface::ICH_MISR_EL2
2430{
2431 // Comments are copied from SPEC section 9.4.7 (ID012119)
2432 ICH_MISR_EL2 ich_misr_el2 = 0;
2433 ICH_HCR_EL2 ich_hcr_el2 =
2435 ICH_VMCR_EL2 ich_vmcr_el2 =
2437
2438 // End Of Interrupt. [bit 0]
2439 // This maintenance interrupt is asserted when at least one bit in
2440 // ICH_EISR_EL2 is 1.
2441
2443 ich_misr_el2.EOI = 1;
2444 }
2445
2446 // Underflow. [bit 1]
2447 // This maintenance interrupt is asserted when ICH_HCR_EL2.UIE==1 and
2448 // zero or one of the List register entries are marked as a valid
2449 // interrupt, that is, if the corresponding ICH_LR<n>_EL2.State bits
2450 // do not equal 0x0.
2451 uint32_t num_valid_interrupts = 0;
2452 uint32_t num_pending_interrupts = 0;
2453
2454 for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
2455 ICH_LR_EL2 ich_lr_el2 =
2457
2458 if (ich_lr_el2.State != ICH_LR_EL2_STATE_INVALID) {
2459 num_valid_interrupts++;
2460 }
2461
2462 if (ich_lr_el2.State == ICH_LR_EL2_STATE_PENDING) {
2463 num_pending_interrupts++;
2464 }
2465 }
2466
2467 if (ich_hcr_el2.UIE && (num_valid_interrupts < 2)) {
2468 ich_misr_el2.U = 1;
2469 }
2470
2471 // List Register Entry Not Present. [bit 2]
2472 // This maintenance interrupt is asserted when ICH_HCR_EL2.LRENPIE==1
2473 // and ICH_HCR_EL2.EOIcount is non-zero.
2474 if (ich_hcr_el2.LRENPIE && ich_hcr_el2.EOIcount) {
2475 ich_misr_el2.LRENP = 1;
2476 }
2477
2478 // No Pending. [bit 3]
2479 // This maintenance interrupt is asserted when ICH_HCR_EL2.NPIE==1 and
2480 // no List register is in pending state.
2481 if (ich_hcr_el2.NPIE && (num_pending_interrupts == 0)) {
2482 ich_misr_el2.NP = 1;
2483 }
2484
2485 // vPE Group 0 Enabled. [bit 4]
2486 // This maintenance interrupt is asserted when
2487 // ICH_HCR_EL2.VGrp0EIE==1 and ICH_VMCR_EL2.VENG0==1.
2488 if (ich_hcr_el2.VGrp0EIE && ich_vmcr_el2.VENG0) {
2489 ich_misr_el2.VGrp0E = 1;
2490 }
2491
2492 // vPE Group 0 Disabled. [bit 5]
2493 // This maintenance interrupt is asserted when
2494 // ICH_HCR_EL2.VGrp0DIE==1 and ICH_VMCR_EL2.VENG0==0.
2495 if (ich_hcr_el2.VGrp0DIE && !ich_vmcr_el2.VENG0) {
2496 ich_misr_el2.VGrp0D = 1;
2497 }
2498
2499 // vPE Group 1 Enabled. [bit 6]
2500 // This maintenance interrupt is asserted when
2501 // ICH_HCR_EL2.VGrp1EIE==1 and ICH_VMCR_EL2.VENG1==is 1.
2502 if (ich_hcr_el2.VGrp1EIE && ich_vmcr_el2.VENG1) {
2503 ich_misr_el2.VGrp1E = 1;
2504 }
2505
2506 // vPE Group 1 Disabled. [bit 7]
2507 // This maintenance interrupt is asserted when
2508 // ICH_HCR_EL2.VGrp1DIE==1 and ICH_VMCR_EL2.VENG1==is 0.
2509 if (ich_hcr_el2.VGrp1DIE && !ich_vmcr_el2.VENG1) {
2510 ich_misr_el2.VGrp1D = 1;
2511 }
2512
2513 return ich_misr_el2;
2514}
2515
2516RegVal
2518{
2519 bool hcr_imo = getHCREL2IMO();
2520 if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
2522 }
2523
2524 RegVal bpr = 0;
2525
2526 if (group == Gicv3::G1S) {
2527 ICC_CTLR_EL1 icc_ctlr_el1_s =
2529
2530 if (!isEL3OrMon() && icc_ctlr_el1_s.CBPR) {
2532 } else {
2534 bpr = bpr > GIC_MIN_BPR ? bpr : GIC_MIN_BPR;
2535 }
2536 } else if (group == Gicv3::G1NS) {
2537 ICC_CTLR_EL1 icc_ctlr_el1_ns =
2539
2540 // Check if EL3 is implemented and this is a non secure accesses at
2541 // EL1 and EL2
2542 if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_ns.CBPR) {
2543 // Reads return BPR0 + 1 saturated to 7, WI
2545 bpr = bpr < 7 ? bpr : 7;
2546 } else {
2548 bpr = bpr > GIC_MIN_BPR_NS ? bpr : GIC_MIN_BPR_NS;
2549 }
2550 } else {
2551 panic("Should be used with G1S and G1NS only\n");
2552 }
2553
2554 return bpr;
2555}
2556
2557bool
2559{
2560 return gic->haveAsserted(cpuId) || hppi.prio != 0xff;
2561}
2562
2563void
2569
2570void
2572{
2573 auto *tc = gic->getSystem()->threads[cpuId];
2575 Reset().invoke(tc);
2576 tc->activate();
2577 }
2578}
2579
2580void
2586
2587void
2609
2610void
2617
2618void
2625
2626} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
Base class for devices that use the MiscReg interfaces.
Definition isa_device.hh:62
virtual void setISA(ISA *isa)
Definition isa_device.cc:55
void setMiscRegNoEffect(RegIndex idx, RegVal val) override
Definition isa.cc:662
int snsBankedIndex64(MiscRegIndex reg, bool ns) const
Definition isa.hh:326
RegVal readMiscRegNoEffect(RegIndex idx) const override
Definition isa.cc:387
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:741
virtual void clear()=0
Clear a signalled interrupt.
virtual void raise()=0
Signal an interrupt.
uint32_t num() const
Get interrupt number.
Definition base_gic.hh:216
static bool callSetWakeRequest(ThreadContext *tc)
Notify the power controller of WAKEREQUEST assertion.
Definition system.cc:214
bool has(ArmExtension ext) const
Definition system.hh:158
static void callClearWakeRequest(ThreadContext *tc)
Notify the power controller of WAKEREQUEST deassertion.
Definition system.cc:223
const Params & params() const
Definition base_gic.cc:78
virtual bool blockIntUpdate() const
When trasferring the state between two GICs (essentially writing architectural registers) an interrup...
Definition base_gic.hh:130
ArmSystem * getSystem() const
Definition base_gic.hh:114
void dropPriority(Gicv3::GroupId group)
static const uint8_t VIRTUAL_PREEMPTION_BITS
void unserialize(CheckpointIn &cp) override
Unserialize an object.
bool groupEnabled(Gicv3::GroupId group) const
void resetHppi(uint32_t intid)
EndBitUnion(ICV_CTLR_EL1) protected void generateSGI(RegVal val, Gicv3::GroupId group)
void serialize(CheckpointOut &cp) const override
Serialize an object.
ArmISA::InterruptTypes intSignalType(Gicv3::GroupId group) const
ArmISA::ExceptionLevel currEL() const
uint64_t eoiMaintenanceInterruptStatus() const
bool hppviCanPreempt(int lrIdx) const
void virtualActivateIRQ(uint32_t lrIdx)
Gicv3Redistributor * redistributor
RegVal bpr1(Gicv3::GroupId group)
void setThreadContext(ThreadContext *tc) override
static const uint8_t GIC_MIN_BPR
RegVal readBankedMiscReg(ArmISA::MiscRegIndex misc_reg) const
uint32_t groupPriorityMask(Gicv3::GroupId group)
ArmInterruptPin * maintenanceInterrupt
ICH_MISR_EL2 maintenanceInterruptStatus() const
static const uint8_t GIC_MIN_BPR_NS
void deactivateIRQ(uint32_t intid, Gicv3::GroupId group)
static const uint64_t ICH_LR_EL2_STATE_ACTIVE_PENDING
static const uint8_t VIRTUAL_NUM_LIST_REGS
uint8_t virtualHighestActivePriority() const
void setBankedMiscReg(ArmISA::MiscRegIndex misc_reg, RegVal val) const
uint32_t virtualGroupPriorityMask(Gicv3::GroupId group) const
void setMiscReg(int misc_reg, RegVal val) override
Write to a system register belonging to this device.
static const uint64_t ICH_LR_EL2_STATE_ACTIVE
static const uint64_t ICH_LR_EL2_STATE_PENDING
Gicv3CPUInterface(Gicv3 *gic, ThreadContext *tc)
bool haveEL(ArmISA::ExceptionLevel el) const
int virtualFindActive(uint32_t intid) const
static const uint8_t GIC_MIN_VBPR
RegVal readMiscReg(int misc_reg) override
Read a system register belonging to this device.
static const uint8_t VIRTUAL_PRIORITY_BITS
void copy(Gicv3Registers *from, Gicv3Registers *to)
void activateIRQ(uint32_t int_id)
void deactivateIRQ(uint32_t int_id)
Gicv3::GroupId getIntGroup(int int_id) const
void activateIRQ(uint32_t int_id)
Gicv3::GroupId getIntGroup(int int_id) const
void deactivateIRQ(uint32_t int_id)
static const uint32_t SMALLEST_LPI_ID
void sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns)
void setClrLPI(uint64_t data, bool set)
static void copyCpuRegister(Gicv3Registers *from, Gicv3Registers *to, const ArmISA::Affinity &aff, ArmISA::MiscRegIndex misc_reg)
Definition gic_v3.cc:82
static const int SGI_MAX
Definition gic_v3.hh:119
Gicv3Redistributor * getRedistributor(ContextID context_id) const
Definition gic_v3.hh:202
void deassertInt(uint32_t cpu, ArmISA::InterruptTypes int_type)
Definition gic_v3.cc:303
Gicv3Distributor * getDistributor() const
Definition gic_v3.hh:196
bool haveAsserted(uint32_t cpu) const
Definition gic_v3.cc:317
static const int PPI_MAX
Definition gic_v3.hh:121
static const int INTID_NONSECURE
Definition gic_v3.hh:115
void deassertAll(uint32_t cpu)
Definition gic_v3.cc:310
static const int INTID_SPURIOUS
Definition gic_v3.hh:116
static const int INTID_SECURE
Definition gic_v3.hh:114
void postInt(uint32_t cpu, ArmISA::InterruptTypes int_type)
Definition gic_v3.cc:282
Threads threads
Definition system.hh:310
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual void activate()=0
Set the status to Active.
virtual BaseISA * getIsaPtr() const =0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition bitfield.hh:79
constexpr int ctz32(uint32_t value)
Count trailing zeros in a 32-bit value.
Definition bitfield.hh:473
constexpr T insertBits(T val, unsigned first, unsigned last, B bit_val)
Returns val with bits first to last set to the LSBs of bit_val.
Definition bitfield.hh:185
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
#define SERIALIZE_ENUM(scalar)
Definition serialize.hh:591
#define UNSERIALIZE_ENUM(scalar)
Definition serialize.hh:598
#define warn(...)
Definition logging.hh:256
Bitfield< 15, 8 > aff1
Definition types.hh:208
ExceptionLevel currEL(const ThreadContext *tc)
Returns the current Exception Level (EL) of the provided ThreadContext.
Definition utility.cc:133
bool isSecure(ThreadContext *tc)
Definition utility.cc:74
Bitfield< 11, 0 > affinity
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 27, 24 > gic
Bitfield< 9, 8 > rs
bool isSecureBelowEL3(ThreadContext *tc)
Definition utility.cc:86
Bitfield< 0 > ns
Bitfield< 23, 16 > aff2
Definition types.hh:207
@ MISCREG_ICH_VMCR
Definition misc.hh:1080
@ MISCREG_ICC_BPR1_EL1_NS
Definition misc.hh:928
@ MISCREG_ICC_IGRPEN1_EL1_NS
Definition misc.hh:938
@ MISCREG_ICV_BPR0_EL1
Definition misc.hh:981
@ MISCREG_ICH_AP0R2_EL2
Definition misc.hh:948
@ MISCREG_ICC_IGRPEN1
Definition misc.hh:1053
@ MISCREG_ICC_IAR1_EL1
Definition misc.hh:924
@ MISCREG_ICH_AP1R1
Definition misc.hh:1072
@ MISCREG_ICV_RPR_EL1
Definition misc.hh:999
@ MISCREG_ICC_MGRPEN1
Definition misc.hh:1057
@ MISCREG_ICC_IGRPEN1_EL3
Definition misc.hh:943
@ MISCREG_ICC_IGRPEN1_EL1_S
Definition misc.hh:939
@ MISCREG_ICC_PMR_EL1
Definition misc.hh:898
@ MISCREG_ICV_CTLR_EL1
Definition misc.hh:1009
@ MISCREG_ICC_AP1R3
Definition misc.hh:1033
@ MISCREG_ICC_MCTLR
Definition misc.hh:1056
@ MISCREG_ICV_AP0R0_EL1
Definition misc.hh:982
@ MISCREG_ICC_AP1R0_EL1
Definition misc.hh:907
@ MISCREG_ICC_BPR0_EL1
Definition misc.hh:902
@ MISCREG_ICH_LR15_EL2
Definition misc.hh:975
@ MISCREG_ICH_MISR
Definition misc.hh:1077
@ MISCREG_ICH_LRC0
Definition misc.hh:1097
@ MISCREG_ICV_EOIR1_EL1
Definition misc.hh:1004
@ MISCREG_ICV_IGRPEN0_EL1
Definition misc.hh:1015
@ MISCREG_SCR_EL3
Definition misc.hh:604
@ MISCREG_ICH_HCR_EL2
Definition misc.hh:954
@ MISCREG_ICC_AP0R3
Definition misc.hh:1023
@ MISCREG_ICC_AP1R0_EL1_S
Definition misc.hh:909
@ MISCREG_ICH_ELRSR_EL2
Definition misc.hh:958
@ MISCREG_ICH_AP1R3
Definition misc.hh:1074
@ MISCREG_ICH_AP1R3_EL2
Definition misc.hh:953
@ MISCREG_ICH_AP0R3
Definition misc.hh:1070
@ MISCREG_ICC_IGRPEN0
Definition misc.hh:1052
@ MISCREG_ICC_DIR
Definition misc.hh:1044
@ MISCREG_ICC_HSRE
Definition misc.hh:1049
@ MISCREG_ICH_ELRSR
Definition misc.hh:1079
@ MISCREG_ICC_AP1R1_EL1
Definition misc.hh:910
@ MISCREG_ICC_RPR_EL1
Definition misc.hh:920
@ MISCREG_ICC_AP0R3_EL1
Definition misc.hh:906
@ MISCREG_ICC_AP0R1
Definition misc.hh:1021
@ MISCREG_ICC_SRE_EL1
Definition misc.hh:933
@ MISCREG_ICH_LRC15
Definition misc.hh:1112
@ MISCREG_ICC_SRE_EL2
Definition misc.hh:940
@ MISCREG_ICH_HCR
Definition misc.hh:1075
@ MISCREG_ICC_IAR0
Definition misc.hh:1050
@ MISCREG_ICV_IAR0_EL1
Definition misc.hh:978
@ MISCREG_ICC_ASGI1R_EL1
Definition misc.hh:922
@ MISCREG_ICC_CTLR
Definition misc.hh:1041
@ MISCREG_ICC_EOIR0
Definition misc.hh:1045
@ MISCREG_ICC_AP1R0
Definition misc.hh:1024
@ MISCREG_ICC_HPPIR0_EL1
Definition misc.hh:901
@ MISCREG_ICC_SGI1R_EL1
Definition misc.hh:921
@ MISCREG_ICV_PMR_EL1
Definition misc.hh:977
@ MISCREG_ICC_SGI1R
Definition misc.hh:1062
@ MISCREG_ICC_PMR
Definition misc.hh:1059
@ MISCREG_ICC_AP1R2
Definition misc.hh:1030
@ MISCREG_ICH_AP1R2_EL2
Definition misc.hh:952
@ MISCREG_ICC_CTLR_EL1_NS
Definition misc.hh:931
@ MISCREG_ICH_VTR
Definition misc.hh:1076
@ MISCREG_ICH_AP0R1_EL2
Definition misc.hh:947
@ MISCREG_ICC_SRE
Definition misc.hh:1063
@ MISCREG_ICC_CTLR_EL3
Definition misc.hh:941
@ MISCREG_ICC_CTLR_EL1
Definition misc.hh:930
@ MISCREG_HCR_EL2
Definition misc.hh:595
@ MISCREG_ICV_IAR1_EL1
Definition misc.hh:1003
@ MISCREG_ICV_HPPIR0_EL1
Definition misc.hh:980
@ MISCREG_ICH_AP1R0
Definition misc.hh:1071
@ MISCREG_ICC_AP0R2
Definition misc.hh:1022
@ MISCREG_ICV_DIR_EL1
Definition misc.hh:998
@ MISCREG_ICC_DIR_EL1
Definition misc.hh:919
@ MISCREG_ICC_SRE_EL3
Definition misc.hh:942
@ MISCREG_ICV_BPR1_EL1
Definition misc.hh:1006
@ MISCREG_ICV_AP1R0_EL1
Definition misc.hh:986
@ MISCREG_ICH_AP1R1_EL2
Definition misc.hh:951
@ MISCREG_ICH_AP1R2
Definition misc.hh:1073
@ MISCREG_ICC_AP1R0_EL1_NS
Definition misc.hh:908
@ MISCREG_ICC_EOIR0_EL1
Definition misc.hh:900
@ MISCREG_ICC_IAR1
Definition misc.hh:1051
@ MISCREG_ICH_LR15
Definition misc.hh:1096
@ MISCREG_ICH_AP0R0
Definition misc.hh:1067
@ MISCREG_ICC_EOIR1_EL1
Definition misc.hh:925
@ MISCREG_ICH_AP0R3_EL2
Definition misc.hh:949
@ MISCREG_ICH_AP0R1
Definition misc.hh:1068
@ MISCREG_ICH_EISR
Definition misc.hh:1078
@ MISCREG_ICC_BPR0
Definition misc.hh:1037
@ MISCREG_ICC_AP0R0_EL1
Definition misc.hh:903
@ MISCREG_ICC_IGRPEN0_EL1
Definition misc.hh:936
@ MISCREG_ICH_VMCR_EL2
Definition misc.hh:959
@ MISCREG_ICC_EOIR1
Definition misc.hh:1046
@ MISCREG_ICC_SGI0R_EL1
Definition misc.hh:923
@ MISCREG_ICV_EOIR0_EL1
Definition misc.hh:979
@ MISCREG_ICC_IGRPEN1_EL1
Definition misc.hh:937
@ MISCREG_ICC_AP0R0
Definition misc.hh:1020
@ MISCREG_ICC_HPPIR0
Definition misc.hh:1047
@ MISCREG_ICC_AP0R2_EL1
Definition misc.hh:905
@ MISCREG_ICC_SGI0R
Definition misc.hh:1061
@ MISCREG_ICH_AP0R0_EL2
Definition misc.hh:946
@ MISCREG_ICH_MISR_EL2
Definition misc.hh:956
@ MISCREG_ICV_IGRPEN1_EL1
Definition misc.hh:1016
@ MISCREG_ICC_AP1R1
Definition misc.hh:1027
@ MISCREG_ICH_LR0
Definition misc.hh:1081
@ MISCREG_ICH_EISR_EL2
Definition misc.hh:957
@ MISCREG_ICC_BPR1_EL1
Definition misc.hh:927
@ MISCREG_ICC_AP0R1_EL1
Definition misc.hh:904
@ MISCREG_ICH_LR0_EL2
Definition misc.hh:960
@ MISCREG_ICC_IAR0_EL1
Definition misc.hh:899
@ MISCREG_ICC_BPR1_EL1_S
Definition misc.hh:929
@ MISCREG_ICV_HPPIR1_EL1
Definition misc.hh:1005
@ MISCREG_ICC_MSRE
Definition misc.hh:1058
@ MISCREG_ICC_AP1R2_EL1
Definition misc.hh:913
@ MISCREG_ICC_HPPIR1_EL1
Definition misc.hh:926
@ MISCREG_ICC_AP1R3_EL1
Definition misc.hh:916
@ MISCREG_ICC_RPR
Definition misc.hh:1060
@ MISCREG_ICC_ASGI1R
Definition misc.hh:1036
@ MISCREG_ICH_AP1R0_EL2
Definition misc.hh:950
@ MISCREG_ICH_VTR_EL2
Definition misc.hh:955
@ MISCREG_ICC_BPR1
Definition misc.hh:1038
@ MISCREG_ICH_AP0R2
Definition misc.hh:1069
@ MISCREG_ICC_CTLR_EL1_S
Definition misc.hh:932
@ MISCREG_ICC_HPPIR1
Definition misc.hh:1048
Bitfield< 3, 2 > el
Definition misc_types.hh:73
const char *const miscRegName[]
Definition misc.hh:1815
bool inAArch64(ThreadContext *tc)
Definition utility.cc:126
Bitfield< 25, 21 > to
Definition types.hh:96
Bitfield< 11 > enable
Definition misc.hh:1086
Bitfield< 63 > val
Definition misc.hh:804
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
uint64_t RegVal
Definition types.hh:173
std::ostream CheckpointOut
Definition serialize.hh:66
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568

Generated on Tue Jun 18 2024 16:24:02 for gem5 by doxygen 1.11.0