2 * Copyright (c) 2018 Metempsy Technology Consulting
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * Authors: Jairo Balart
31 #include "dev/arm/gic_v3_cpu_interface.hh"
33 #include "arch/arm/isa.hh"
34 #include "debug/GIC.hh"
35 #include "dev/arm/gic_v3.hh"
36 #include "dev/arm/gic_v3_distributor.hh"
37 #include "dev/arm/gic_v3_redistributor.hh"
39 Gicv3CPUInterface::Gicv3CPUInterface(Gicv3
* gic
, uint32_t cpu_id
)
42 redistributor(nullptr),
48 Gicv3CPUInterface::~Gicv3CPUInterface()
53 Gicv3CPUInterface::init()
55 redistributor
= gic
->getRedistributor(cpuId
);
56 distributor
= gic
->getDistributor();
60 Gicv3CPUInterface::initState()
66 Gicv3CPUInterface::reset()
72 Gicv3CPUInterface::getHCREL2FMO()
74 HCR hcr
= isa
->readMiscRegNoEffect(MISCREG_HCR_EL2
);
76 if (hcr
.tge
&& hcr
.e2h
) {
86 Gicv3CPUInterface::getHCREL2IMO()
88 HCR hcr
= isa
->readMiscRegNoEffect(MISCREG_HCR_EL2
);
90 if (hcr
.tge
&& hcr
.e2h
) {
100 Gicv3CPUInterface::readMiscReg(int misc_reg
)
102 ArmISA::MiscReg value
= isa
->readMiscRegNoEffect(misc_reg
);
103 bool hcr_fmo
= getHCREL2FMO();
104 bool hcr_imo
= getHCREL2IMO();
107 case MISCREG_ICC_AP1R0
:
108 case MISCREG_ICC_AP1R0_EL1
: {
109 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
110 return isa
->readMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1
);
116 case MISCREG_ICC_AP1R1
:
117 case MISCREG_ICC_AP1R1_EL1
:
119 // only implemented if supporting 6 or more bits of priority
120 case MISCREG_ICC_AP1R2
:
121 case MISCREG_ICC_AP1R2_EL1
:
123 // only implemented if supporting 7 or more bits of priority
124 case MISCREG_ICC_AP1R3
:
125 case MISCREG_ICC_AP1R3_EL1
:
126 // only implemented if supporting 7 or more bits of priority
129 case MISCREG_ICC_AP0R0
:
130 case MISCREG_ICC_AP0R0_EL1
: {
131 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
132 return isa
->readMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1
);
138 case MISCREG_ICC_AP0R1
:
139 case MISCREG_ICC_AP0R1_EL1
:
141 // only implemented if supporting 6 or more bits of priority
142 case MISCREG_ICC_AP0R2
:
143 case MISCREG_ICC_AP0R2_EL1
:
145 // only implemented if supporting 7 or more bits of priority
146 case MISCREG_ICC_AP0R3
:
147 case MISCREG_ICC_AP0R3_EL1
:
148 // only implemented if supporting 7 or more bits of priority
151 case MISCREG_ICC_IGRPEN0
:
152 case MISCREG_ICC_IGRPEN0_EL1
: {
153 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
154 return isa
->readMiscRegNoEffect(MISCREG_ICV_IGRPEN0_EL1
);
160 case MISCREG_ICC_IGRPEN1
:
161 case MISCREG_ICC_IGRPEN1_EL1
: {
162 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
163 return isa
->readMiscRegNoEffect(MISCREG_ICV_IGRPEN1_EL1
);
169 case MISCREG_ICC_MGRPEN1
:
170 case MISCREG_ICC_IGRPEN1_EL3
: {
171 // EnableGrp1S and EnableGrp1NS are aliased with
172 // ICC_IGRPEN1_EL1_S.Enable and ICC_IGRPEN1_EL1_NS.Enable
174 isa
->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S
) &
175 ICC_IGRPEN1_EL1_ENABLE
;
176 bool enable_grp_1ns
=
177 isa
->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS
) &
178 ICC_IGRPEN1_EL1_ENABLE
;
182 value
|= ICC_IGRPEN1_EL3_ENABLEGRP1S
;
185 if (enable_grp_1ns
) {
186 value
|= ICC_IGRPEN1_EL3_ENABLEGRP1NS
;
192 case MISCREG_ICC_RPR
:
193 case MISCREG_ICC_RPR_EL1
: {
194 if ((currEL() == EL1
) && !inSecureState() &&
195 (hcr_imo
|| hcr_fmo
)) {
196 return readMiscReg(MISCREG_ICV_RPR_EL1
);
199 uint8_t rprio
= highestActivePriority();
201 if (haveEL(EL3
) && !inSecureState() &&
202 (isa
->readMiscRegNoEffect(MISCREG_SCR_EL3
) & (1U << 2))) {
203 /* NS GIC access and Group 0 is inaccessible to NS */
204 if ((rprio
& 0x80) == 0) {
205 /* NS should not see priorities in the Secure half of the
208 } else if (rprio
!= 0xff) {
209 /* Non-idle priority: show the Non-secure view of it */
210 rprio
= (rprio
<< 1) & 0xff;
218 case MISCREG_ICV_RPR_EL1
: {
219 value
= virtualHighestActivePriority();
223 case MISCREG_ICC_HPPIR0
:
224 case MISCREG_ICC_HPPIR0_EL1
: {
225 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
226 return readMiscReg(MISCREG_ICV_HPPIR0_EL1
);
233 case MISCREG_ICV_HPPIR0_EL1
: {
234 value
= Gicv3::INTID_SPURIOUS
;
235 int lr_idx
= getHPPVILR();
239 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
240 Gicv3::GroupId group
=
241 lr
& ICH_LR_EL2_GROUP
? Gicv3::G1NS
: Gicv3::G0S
;
243 if (group
== Gicv3::G0S
) {
244 value
= bits(lr
, 31, 0);
251 case MISCREG_ICC_HPPIR1
:
252 case MISCREG_ICC_HPPIR1_EL1
: {
253 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
254 return readMiscReg(MISCREG_ICV_HPPIR1_EL1
);
261 case MISCREG_ICV_HPPIR1_EL1
: {
262 value
= Gicv3::INTID_SPURIOUS
;
263 int lr_idx
= getHPPVILR();
267 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
268 Gicv3::GroupId group
=
269 lr
& ICH_LR_EL2_GROUP
? Gicv3::G1NS
: Gicv3::G0S
;
271 if (group
== Gicv3::G1NS
) {
272 value
= bits(lr
, 31, 0);
279 case MISCREG_ICC_BPR0
:
280 case MISCREG_ICC_BPR0_EL1
:
281 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
282 return readMiscReg(MISCREG_ICV_BPR0_EL1
);
287 case MISCREG_ICC_BPR1
:
288 case MISCREG_ICC_BPR1_EL1
:
289 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
290 return readMiscReg(MISCREG_ICV_BPR1_EL1
);
294 Gicv3::GroupId group
=
295 misc_reg
== MISCREG_ICC_BPR0_EL1
? Gicv3::G0S
: Gicv3::G1S
;
297 if (group
== Gicv3::G1S
&& !inSecureState()) {
301 if ((group
== Gicv3::G1S
) &&
303 (isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S
)
304 & ICC_CTLR_EL1_CBPR
)) {
308 bool sat_inc
= false;
310 if ((group
== Gicv3::G1NS
) &&
312 (isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS
)
313 & ICC_CTLR_EL1_CBPR
)) {
314 // Reads return BPR0 + 1 saturated to 7, WI
321 if (group
== Gicv3::G0S
) {
322 bpr
= isa
->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1
);
324 bpr
= isa
->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1
);
339 case MISCREG_ICV_BPR0_EL1
:
340 case MISCREG_ICV_BPR1_EL1
: {
341 Gicv3::GroupId group
=
342 misc_reg
== MISCREG_ICV_BPR0_EL1
? Gicv3::G0S
: Gicv3::G1NS
;
343 ArmISA::MiscReg ich_vmcr_el2
=
344 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
345 bool sat_inc
= false;
347 if (group
== Gicv3::G1NS
&& (ich_vmcr_el2
& ICH_VMCR_EL2_VCBPR
)) {
348 // reads return bpr0 + 1 saturated to 7, writes ignored
355 if (group
== Gicv3::G0S
) {
356 vbpr
= bits(ich_vmcr_el2
, 23, 21);
358 vbpr
= bits(ich_vmcr_el2
, 20, 18);
373 case MISCREG_ICC_PMR
:
374 case MISCREG_ICC_PMR_EL1
: // Priority Mask Register
375 if ((currEL() == EL1
) && !inSecureState() &&
376 (hcr_imo
|| hcr_fmo
)) {
377 return isa
->readMiscRegNoEffect(MISCREG_ICV_PMR_EL1
);
380 if (haveEL(EL3
) && !inSecureState() &&
381 (isa
->readMiscRegNoEffect(MISCREG_SCR_EL3
) & (1U << 2))) {
382 /* NS GIC access and Group 0 is inaccessible to NS */
383 if ((value
& 0x80) == 0) {
384 /* NS should not see priorities in the Secure half of the
387 } else if (value
!= 0xff) {
388 /* Non-idle priority: show the Non-secure view of it */
389 value
= (value
<< 1) & 0xff;
395 case MISCREG_ICC_IAR0
:
396 case MISCREG_ICC_IAR0_EL1
: { // Interrupt Acknowledge Register 0
397 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
398 return readMiscReg(MISCREG_ICV_IAR0_EL1
);
403 if (hppiCanPreempt()) {
404 int_id
= getHPPIR0();
406 // avoid activation for special interrupts
407 if (int_id
< Gicv3::INTID_SECURE
) {
408 activateIRQ(int_id
, hppi
.group
);
411 int_id
= Gicv3::INTID_SPURIOUS
;
418 case MISCREG_ICV_IAR0_EL1
: {
419 int lr_idx
= getHPPVILR();
420 uint32_t int_id
= Gicv3::INTID_SPURIOUS
;
424 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
426 if (!(lr
& ICH_LR_EL2_GROUP
) && hppviCanPreempt(lr_idx
)) {
427 int_id
= value
= bits(lr
, 31, 0);
429 if (int_id
< Gicv3::INTID_SECURE
||
430 int_id
> Gicv3::INTID_SPURIOUS
) {
431 virtualActivateIRQ(lr_idx
);
433 // Bogus... Pseudocode says:
434 // - Move from pending to invalid...
435 // - Return de bogus id...
436 lr
&= ~ICH_LR_EL2_STATE_PENDING_BIT
;
437 isa
->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
,
448 case MISCREG_ICC_IAR1
:
449 case MISCREG_ICC_IAR1_EL1
: { // Interrupt Acknowledge Register 1
450 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
451 return readMiscReg(MISCREG_ICV_IAR1_EL1
);
456 if (hppiCanPreempt()) {
457 int_id
= getHPPIR1();
459 // avoid activation for special interrupts
460 if (int_id
< Gicv3::INTID_SECURE
) {
461 activateIRQ(int_id
, hppi
.group
);
464 int_id
= Gicv3::INTID_SPURIOUS
;
471 case MISCREG_ICV_IAR1_EL1
: {
472 int lr_idx
= getHPPVILR();
473 uint32_t int_id
= Gicv3::INTID_SPURIOUS
;
477 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
479 if (lr
& ICH_LR_EL2_GROUP
&& hppviCanPreempt(lr_idx
)) {
480 int_id
= value
= bits(lr
, 31, 0);
482 if (int_id
< Gicv3::INTID_SECURE
||
483 int_id
> Gicv3::INTID_SPURIOUS
) {
484 virtualActivateIRQ(lr_idx
);
486 // Bogus... Pseudocode says:
487 // - Move from pending to invalid...
488 // - Return de bogus id...
489 lr
&= ~ICH_LR_EL2_STATE_PENDING_BIT
;
490 isa
->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
,
501 case MISCREG_ICC_SRE
:
502 case MISCREG_ICC_SRE_EL1
: { // System Register Enable Register
506 if (haveEL(EL3
) && !distributor
->DS
) {
507 // DIB is RO alias of ICC_SRE_EL3.DIB
508 // DFB is RO alias of ICC_SRE_EL3.DFB
509 ArmISA::MiscReg icc_sre_el3
=
510 isa
->readMiscRegNoEffect(MISCREG_ICC_SRE_EL3
);
511 dfb
= icc_sre_el3
& ICC_SRE_EL3_DFB
;
512 dib
= icc_sre_el3
& ICC_SRE_EL3_DIB
;
513 } else if (haveEL(EL3
) && distributor
->DS
) {
514 // DIB is RW alias of ICC_SRE_EL3.DIB
515 // DFB is RW alias of ICC_SRE_EL3.DFB
516 ArmISA::MiscReg icc_sre_el3
=
517 isa
->readMiscRegNoEffect(MISCREG_ICC_SRE_EL3
);
518 dfb
= icc_sre_el3
& ICC_SRE_EL3_DFB
;
519 dib
= icc_sre_el3
& ICC_SRE_EL3_DIB
;
520 } else if ((!haveEL(EL3
) || distributor
->DS
) and haveEL(EL2
)) {
521 // DIB is RO alias of ICC_SRE_EL2.DIB
522 // DFB is RO alias of ICC_SRE_EL2.DFB
523 ArmISA::MiscReg icc_sre_el2
=
524 isa
->readMiscRegNoEffect(MISCREG_ICC_SRE_EL2
);
525 dfb
= icc_sre_el2
& ICC_SRE_EL2_DFB
;
526 dib
= icc_sre_el2
& ICC_SRE_EL2_DIB
;
528 dfb
= value
& ICC_SRE_EL1_DFB
;
529 dib
= value
& ICC_SRE_EL1_DIB
;
532 value
= ICC_SRE_EL1_SRE
;
535 value
|= ICC_SRE_EL1_DFB
;
539 value
|= ICC_SRE_EL1_DIB
;
545 case MISCREG_ICC_HSRE
:
546 case MISCREG_ICC_SRE_EL2
: // System Register Enable Register
549 * (Secure EL1 accesses to Secure ICC_SRE_EL1 do not trap to EL2,
551 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
552 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
553 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
555 value
= ICC_SRE_EL2_ENABLE
| ICC_SRE_EL2_DIB
| ICC_SRE_EL2_DFB
|
559 case MISCREG_ICC_MSRE
:
560 case MISCREG_ICC_SRE_EL3
: // System Register Enable Register
563 * (Secure EL1 accesses to Secure ICC_SRE_EL1 do not trap to EL3,
565 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
566 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
567 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
569 value
= ICC_SRE_EL3_ENABLE
| ICC_SRE_EL3_DIB
| ICC_SRE_EL3_DFB
|
573 case MISCREG_ICC_CTLR
:
574 case MISCREG_ICC_CTLR_EL1
: { // Control Register
575 if ((currEL() == EL1
) && !inSecureState() &&
576 (hcr_imo
|| hcr_fmo
)) {
577 return readMiscReg(MISCREG_ICV_CTLR_EL1
);
580 // Add value for RO bits
581 // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
582 // PRIbits [10:8], number of priority bits implemented, minus one
583 value
|= ICC_CTLR_EL1_RSS
| ICC_CTLR_EL1_A3V
|
584 (1 << 11) | ((PRIORITY_BITS
- 1) << 8);
588 case MISCREG_ICV_CTLR_EL1
: {
589 value
= ICC_CTLR_EL1_A3V
| (1 << ICC_CTLR_EL1_IDBITS_SHIFT
) |
590 (7 << ICC_CTLR_EL1_PRIBITS_SHIFT
);
591 ArmISA::MiscReg ich_vmcr_el2
=
592 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
594 if (ich_vmcr_el2
& ICH_VMCR_EL2_VEOIM
) {
595 value
|= ICC_CTLR_EL1_EOIMODE
;
598 if (ich_vmcr_el2
& ICH_VMCR_EL2_VCBPR
) {
599 value
|= ICC_CTLR_EL1_CBPR
;
605 case MISCREG_ICC_MCTLR
:
606 case MISCREG_ICC_CTLR_EL3
: {
607 // Add value for RO bits
610 // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
611 // PRIbits [10:8], number of priority bits implemented, minus one
612 value
|= ICC_CTLR_EL3_RSS
| ICC_CTLR_EL3_A3V
| (0 << 11) |
613 ((PRIORITY_BITS
- 1) << 8);
615 ArmISA::MiscReg icc_ctlr_el1_ns
=
616 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS
);
617 ArmISA::MiscReg icc_ctlr_el1_s
=
618 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S
);
620 if (icc_ctlr_el1_ns
& ICC_CTLR_EL1_EOIMODE
) {
621 value
|= ICC_CTLR_EL3_EOIMODE_EL1NS
;
624 if (icc_ctlr_el1_ns
& ICC_CTLR_EL1_CBPR
) {
625 value
|= ICC_CTLR_EL3_CBPR_EL1NS
;
628 if (icc_ctlr_el1_s
& ICC_CTLR_EL1_EOIMODE
) {
629 value
|= ICC_CTLR_EL3_EOIMODE_EL1S
;
632 if (icc_ctlr_el1_s
& ICC_CTLR_EL1_CBPR
) {
633 value
|= ICC_CTLR_EL3_CBPR_EL1S
;
639 case MISCREG_ICH_HCR
:
640 case MISCREG_ICH_HCR_EL2
:
643 case MISCREG_ICH_AP0R0
:
644 case MISCREG_ICH_AP0R0_EL2
:
647 case MISCREG_ICH_AP1R0
:
648 case MISCREG_ICH_AP1R0_EL2
:
651 case MISCREG_ICH_MISR
:
652 case MISCREG_ICH_MISR_EL2
: {
654 // Scan list registers and fill in the U, NP and EOI bits
655 eoiMaintenanceInterruptStatus((uint32_t *) &value
);
656 ArmISA::MiscReg ich_hcr_el2
=
657 isa
->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2
);
658 ArmISA::MiscReg ich_vmcr_el2
=
659 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
662 (ICH_HCR_EL2_LRENPIE
| ICH_HCR_EL2_EOICOUNT_MASK
)) {
663 value
|= ICH_MISR_EL2_LRENP
;
666 if ((ich_hcr_el2
& ICH_HCR_EL2_VGRP0EIE
) &&
667 (ich_vmcr_el2
& ICH_VMCR_EL2_VENG0
)) {
668 value
|= ICH_MISR_EL2_VGRP0E
;
671 if ((ich_hcr_el2
& ICH_HCR_EL2_VGRP0DIE
) &&
672 !(ich_vmcr_el2
& ICH_VMCR_EL2_VENG1
)) {
673 value
|= ICH_MISR_EL2_VGRP0D
;
676 if ((ich_hcr_el2
& ICH_HCR_EL2_VGRP1EIE
) &&
677 (ich_vmcr_el2
& ICH_VMCR_EL2_VENG1
)) {
678 value
|= ICH_MISR_EL2_VGRP1E
;
681 if ((ich_hcr_el2
& ICH_HCR_EL2_VGRP1DIE
) &&
682 !(ich_vmcr_el2
& ICH_VMCR_EL2_VENG1
)) {
683 value
|= ICH_MISR_EL2_VGRP1D
;
689 case MISCREG_ICH_VTR
:
690 case MISCREG_ICH_VTR_EL2
:
695 * SEIS [22] == 0 (SEI Support)
697 * (Non-zero values supported for Affinity 3 in SGI genearion)
699 * (Support for direct injection of virtual interrupts)
700 * TDS [19] == 0 (Implementation supports ICH_HCR_EL2.TDIR)
703 value
= (16 - 1) << 0 |
707 ((VIRTUAL_NUM_LIST_REGS
- 1) << ICH_VTR_EL2_LISTREGS_SHIFT
) |
711 (1 << ICH_VTR_EL2_IDBITS_SHIFT
) |
712 ((VIRTUAL_PREEMPTION_BITS
- 1) << ICH_VTR_EL2_PREBITS_SHIFT
) |
713 ((VIRTUAL_PRIORITY_BITS
- 1) << ICH_VTR_EL2_PRIBITS_SHIFT
);
716 case MISCREG_ICH_EISR
:
717 case MISCREG_ICH_EISR_EL2
:
718 value
= eoiMaintenanceInterruptStatus(nullptr);
721 case MISCREG_ICH_ELRSR
:
722 case MISCREG_ICH_ELRSR_EL2
:
725 for (int lr_idx
= 0; lr_idx
< VIRTUAL_NUM_LIST_REGS
; lr_idx
++) {
727 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
729 if ((lr
& ICH_LR_EL2_STATE_MASK
) == 0 &&
730 ((lr
& ICH_LR_EL2_HW
) != 0 ||
731 (lr
& ICH_LR_EL2_EOI
) == 0)) {
732 value
|= (1 << lr_idx
);
738 case MISCREG_ICH_LRC0
... MISCREG_ICH_LRC15
:
739 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
743 case MISCREG_ICH_LR0
... MISCREG_ICH_LR15
:
744 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
745 value
= value
& 0xffffffff;
748 case MISCREG_ICH_LR0_EL2
... MISCREG_ICH_LR15_EL2
:
751 case MISCREG_ICH_VMCR
:
752 case MISCREG_ICH_VMCR_EL2
:
756 panic("Gicv3CPUInterface::readMiscReg(): "
757 "unknown register %d (%s)",
758 misc_reg
, miscRegName
[misc_reg
]);
761 DPRINTF(GIC
, "Gicv3CPUInterface::readMiscReg(): "
762 "register %s value %#x\n", miscRegName
[misc_reg
], value
);
767 Gicv3CPUInterface::setMiscReg(int misc_reg
, ArmISA::MiscReg val
)
769 bool do_virtual_update
= false;
770 DPRINTF(GIC
, "Gicv3CPUInterface::setMiscReg(): "
771 "register %s value %#x\n", miscRegName
[misc_reg
], val
);
772 bool hcr_fmo
= getHCREL2FMO();
773 bool hcr_imo
= getHCREL2IMO();
776 case MISCREG_ICC_AP1R0
:
777 case MISCREG_ICC_AP1R0_EL1
:
778 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
779 return isa
->setMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1
, val
);
784 case MISCREG_ICC_AP1R1
:
785 case MISCREG_ICC_AP1R1_EL1
:
787 // only implemented if supporting 6 or more bits of priority
788 case MISCREG_ICC_AP1R2
:
789 case MISCREG_ICC_AP1R2_EL1
:
791 // only implemented if supporting 7 or more bits of priority
792 case MISCREG_ICC_AP1R3
:
793 case MISCREG_ICC_AP1R3_EL1
:
794 // only implemented if supporting 7 or more bits of priority
797 case MISCREG_ICC_AP0R0
:
798 case MISCREG_ICC_AP0R0_EL1
:
799 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
800 return isa
->setMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1
, val
);
805 case MISCREG_ICC_AP0R1
:
806 case MISCREG_ICC_AP0R1_EL1
:
808 // only implemented if supporting 6 or more bits of priority
809 case MISCREG_ICC_AP0R2
:
810 case MISCREG_ICC_AP0R2_EL1
:
812 // only implemented if supporting 7 or more bits of priority
813 case MISCREG_ICC_AP0R3
:
814 case MISCREG_ICC_AP0R3_EL1
:
815 // only implemented if supporting 7 or more bits of priority
818 case MISCREG_ICC_EOIR0
:
819 case MISCREG_ICC_EOIR0_EL1
: { // End Of Interrupt Register 0
820 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
821 return setMiscReg(MISCREG_ICV_EOIR0_EL1
, val
);
824 int int_id
= val
& 0xffffff;
826 // avoid activation for special interrupts
827 if (int_id
>= Gicv3::INTID_SECURE
) {
831 Gicv3::GroupId group
= Gicv3::G0S
;
833 if (highestActiveGroup() != group
) {
839 if (!isEOISplitMode()) {
840 deactivateIRQ(int_id
, group
);
846 case MISCREG_ICV_EOIR0_EL1
: {
847 int int_id
= val
& 0xffffff;
849 // avoid deactivation for special interrupts
850 if (int_id
>= Gicv3::INTID_SECURE
&&
851 int_id
<= Gicv3::INTID_SPURIOUS
) {
855 uint8_t drop_prio
= virtualDropPriority();
857 if (drop_prio
== 0xff) {
861 int lr_idx
= virtualFindActive(int_id
);
864 // No LR found matching
865 virtualIncrementEOICount();
868 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
869 Gicv3::GroupId lr_group
=
870 lr
& ICH_LR_EL2_GROUP
? Gicv3::G1NS
: Gicv3::G0S
;
871 uint8_t lr_group_prio
= bits(lr
, 55, 48) & 0xf8;
873 if (lr_group
== Gicv3::G0S
&& lr_group_prio
== drop_prio
) {
874 //JAIRO if (!virtualIsEOISplitMode())
876 virtualDeactivateIRQ(lr_idx
);
885 case MISCREG_ICC_EOIR1
:
886 case MISCREG_ICC_EOIR1_EL1
: { // End Of Interrupt Register 1
887 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
888 return setMiscReg(MISCREG_ICV_EOIR1_EL1
, val
);
891 int int_id
= val
& 0xffffff;
893 // avoid deactivation for special interrupts
894 if (int_id
>= Gicv3::INTID_SECURE
) {
898 Gicv3::GroupId group
=
899 inSecureState() ? Gicv3::G1S
: Gicv3::G1NS
;
901 if (highestActiveGroup() == Gicv3::G0S
) {
905 if (distributor
->DS
== 0) {
906 if (highestActiveGroup() == Gicv3::G1S
&& !inSecureState()) {
908 } else if (highestActiveGroup() == Gicv3::G1NS
&&
909 !(!inSecureState() or (currEL() == EL3
))) {
916 if (!isEOISplitMode()) {
917 deactivateIRQ(int_id
, group
);
923 case MISCREG_ICV_EOIR1_EL1
: {
924 int int_id
= val
& 0xffffff;
926 // avoid deactivation for special interrupts
927 if (int_id
>= Gicv3::INTID_SECURE
&&
928 int_id
<= Gicv3::INTID_SPURIOUS
) {
932 uint8_t drop_prio
= virtualDropPriority();
934 if (drop_prio
== 0xff) {
938 int lr_idx
= virtualFindActive(int_id
);
941 // No LR found matching
942 virtualIncrementEOICount();
945 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
946 Gicv3::GroupId lr_group
=
947 lr
& ICH_LR_EL2_GROUP
? Gicv3::G1NS
: Gicv3::G0S
;
948 uint8_t lr_group_prio
= bits(lr
, 55, 48) & 0xf8;
950 if (lr_group
== Gicv3::G1NS
&& lr_group_prio
== drop_prio
) {
951 if (!virtualIsEOISplitMode()) {
952 virtualDeactivateIRQ(lr_idx
);
961 case MISCREG_ICC_DIR
:
962 case MISCREG_ICC_DIR_EL1
: { // Deactivate Interrupt Register
963 if ((currEL() == EL1
) && !inSecureState() &&
964 (hcr_imo
|| hcr_fmo
)) {
965 return setMiscReg(MISCREG_ICV_DIR_EL1
, val
);
968 int int_id
= val
& 0xffffff;
970 // avoid deactivation for special interrupts
971 if (int_id
>= Gicv3::INTID_SECURE
) {
975 if (!isEOISplitMode()) {
980 * Check whether we're allowed to deactivate.
981 * These checks are correspond to the spec's pseudocode.
983 Gicv3::GroupId group
=
984 int_id
>= 32 ? distributor
->getIntGroup(int_id
) :
985 redistributor
->getIntGroup(int_id
);
986 bool irq_is_grp0
= group
== Gicv3::G0S
;
987 bool single_sec_state
= distributor
->DS
;
988 bool irq_is_secure
= !single_sec_state
&& (group
!= Gicv3::G1NS
);
989 SCR scr_el3
= isa
->readMiscRegNoEffect(MISCREG_SCR_EL3
);
990 bool route_fiq_to_el3
= scr_el3
.fiq
;
991 bool route_irq_to_el3
= scr_el3
.irq
;
992 bool route_fiq_to_el2
= hcr_fmo
;
993 bool route_irq_to_el2
= hcr_imo
;
1000 if (single_sec_state
&& irq_is_grp0
&& !route_fiq_to_el3
) {
1004 if (!irq_is_secure
&& !irq_is_grp0
&& !route_irq_to_el3
) {
1011 if (!isSecureBelowEL3()) {
1012 if (single_sec_state
&& irq_is_grp0
&&
1013 !route_fiq_to_el3
&& !route_fiq_to_el2
) {
1017 if (!irq_is_secure
&& !irq_is_grp0
&&
1018 !route_irq_to_el3
&& !route_irq_to_el2
) {
1022 if (irq_is_grp0
&& !route_fiq_to_el3
) {
1027 (!irq_is_secure
|| !single_sec_state
) &&
1028 !route_irq_to_el3
) {
1039 deactivateIRQ(int_id
, group
);
1043 case MISCREG_ICV_DIR_EL1
: {
1044 int int_id
= val
& 0xffffff;
1046 // avoid deactivation for special interrupts
1047 if (int_id
>= Gicv3::INTID_SECURE
&&
1048 int_id
<= Gicv3::INTID_SPURIOUS
) {
1052 if (!virtualIsEOISplitMode()) {
1056 int lr_idx
= virtualFindActive(int_id
);
1059 // No LR found matching
1060 virtualIncrementEOICount();
1062 virtualDeactivateIRQ(lr_idx
);
1069 case MISCREG_ICC_BPR0
:
1070 case MISCREG_ICC_BPR0_EL1
: // Binary Point Register 0
1071 case MISCREG_ICC_BPR1
:
1072 case MISCREG_ICC_BPR1_EL1
: { // Binary Point Register 1
1073 if ((currEL() == EL1
) && !inSecureState()) {
1074 if (misc_reg
== MISCREG_ICC_BPR0_EL1
&& hcr_fmo
) {
1075 return setMiscReg(MISCREG_ICV_BPR0_EL1
, val
);
1076 } else if (misc_reg
== MISCREG_ICC_BPR1_EL1
&& hcr_imo
) {
1077 return setMiscReg(MISCREG_ICV_BPR1_EL1
, val
);
1081 Gicv3::GroupId group
=
1082 misc_reg
== MISCREG_ICC_BPR0_EL1
? Gicv3::G0S
: Gicv3::G1S
;
1084 if (group
== Gicv3::G1S
&& !inSecureState()) {
1085 group
= Gicv3::G1NS
;
1088 if ((group
== Gicv3::G1S
) &&
1090 (isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S
) &
1091 ICC_CTLR_EL1_CBPR
)) {
1095 if ((group
== Gicv3::G1NS
) &&
1097 (isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS
) &
1098 ICC_CTLR_EL1_CBPR
)) {
1099 // Reads return BPR0 + 1 saturated to 7, WI
1103 uint8_t min_val
= (group
== Gicv3::G1NS
) ?
1104 GIC_MIN_BPR_NS
: GIC_MIN_BPR
;
1107 if (val
< min_val
) {
1114 case MISCREG_ICV_BPR0_EL1
:
1115 case MISCREG_ICV_BPR1_EL1
: {
1116 Gicv3::GroupId group
=
1117 misc_reg
== MISCREG_ICV_BPR0_EL1
? Gicv3::G0S
: Gicv3::G1NS
;
1118 ArmISA::MiscReg ich_vmcr_el2
=
1119 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
1121 if (group
== Gicv3::G1NS
&& (ich_vmcr_el2
& ICH_VMCR_EL2_VCBPR
)) {
1122 // reads return bpr0 + 1 saturated to 7, writes ignored
1126 uint8_t min_VPBR
= 7 - VIRTUAL_PREEMPTION_BITS
;
1128 if (group
!= Gicv3::G0S
) {
1132 if (val
< min_VPBR
) {
1136 if (group
== Gicv3::G0S
) {
1137 ich_vmcr_el2
= insertBits(ich_vmcr_el2
,
1138 ICH_VMCR_EL2_VBPR0_SHIFT
+ 2, ICH_VMCR_EL2_VBPR0_SHIFT
,
1141 ich_vmcr_el2
= insertBits(ich_vmcr_el2
,
1142 ICH_VMCR_EL2_VBPR1_SHIFT
+ 2, ICH_VMCR_EL2_VBPR1_SHIFT
,
1146 isa
->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
, ich_vmcr_el2
);
1147 do_virtual_update
= true;
1151 case MISCREG_ICC_CTLR
:
1152 case MISCREG_ICC_CTLR_EL1
: { // Control Register
1153 if ((currEL() == EL1
) && !inSecureState() &&
1154 (hcr_imo
|| hcr_fmo
)) {
1155 return setMiscReg(MISCREG_ICV_CTLR_EL1
, val
);
1164 * If EL3 is implemented and GICD_CTLR.DS == 0, then PMHE is RO.
1165 * So, only CBPR[0] and EOIMODE[1] are RW.
1166 * If EL3 is implemented and GICD_CTLR.DS == 0, then CBPR is RO.
1170 if (haveEL(EL3
) and distributor
->DS
== 0) {
1171 mask
= ICC_CTLR_EL1_EOIMODE
;
1172 } else if (haveEL(EL3
) and distributor
->DS
== 1) {
1173 mask
= ICC_CTLR_EL1_PMHE
| ICC_CTLR_EL1_CBPR
|
1174 ICC_CTLR_EL1_EOIMODE
;
1176 mask
= ICC_CTLR_EL1_CBPR
| ICC_CTLR_EL1_EOIMODE
;
1179 ArmISA::MiscReg old_val
=
1180 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1
);
1182 val
= old_val
| (val
& mask
);
1186 case MISCREG_ICV_CTLR_EL1
: {
1187 ArmISA::MiscReg ich_vmcr_el2
=
1188 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
1189 ich_vmcr_el2
= insertBits(ich_vmcr_el2
, ICH_VMCR_EL2_VCBPR_SHIFT
,
1190 val
& ICC_CTLR_EL1_CBPR
? 1 : 0);
1191 ich_vmcr_el2
= insertBits(ich_vmcr_el2
, ICH_VMCR_EL2_VEOIM_SHIFT
,
1192 val
& ICC_CTLR_EL1_EOIMODE
? 1 : 0);
1193 isa
->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
, ich_vmcr_el2
);
1194 do_virtual_update
= true;
1198 case MISCREG_ICC_MCTLR
:
1199 case MISCREG_ICC_CTLR_EL3
: {
1200 ArmISA::MiscReg icc_ctlr_el1_s
=
1201 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S
);
1202 ArmISA::MiscReg icc_ctlr_el1_ns
=
1203 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS
);
1205 // ICC_CTLR_EL1(NS).EOImode is an alias of
1206 // ICC_CTLR_EL3.EOImode_EL1NS
1207 if (val
& ICC_CTLR_EL3_EOIMODE_EL1NS
) {
1208 icc_ctlr_el1_ns
|= ICC_CTLR_EL1_EOIMODE
;
1210 icc_ctlr_el1_ns
&= ~ICC_CTLR_EL1_EOIMODE
;
1213 // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS
1214 if (val
& ICC_CTLR_EL3_CBPR_EL1NS
) {
1215 icc_ctlr_el1_ns
|= ICC_CTLR_EL1_CBPR
;
1217 icc_ctlr_el1_ns
&= ~ICC_CTLR_EL1_CBPR
;
1220 // ICC_CTLR_EL1(S).EOImode is an alias of ICC_CTLR_EL3.EOImode_EL1S
1221 if (val
& ICC_CTLR_EL3_EOIMODE_EL1S
) {
1222 icc_ctlr_el1_s
|= ICC_CTLR_EL1_EOIMODE
;
1224 icc_ctlr_el1_s
&= ~ICC_CTLR_EL1_EOIMODE
;
1227 // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S
1228 if (val
& ICC_CTLR_EL3_CBPR_EL1S
) {
1229 icc_ctlr_el1_s
|= ICC_CTLR_EL1_CBPR
;
1231 icc_ctlr_el1_s
&= ~ICC_CTLR_EL1_CBPR
;
1234 isa
->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S
, icc_ctlr_el1_s
);
1235 isa
->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS
, icc_ctlr_el1_ns
);
1236 // Only ICC_CTLR_EL3_EOIMODE_EL3 is writable
1237 ArmISA::MiscReg old_icc_ctlr_el3
=
1238 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3
);
1239 old_icc_ctlr_el3
&= ~(ICC_CTLR_EL3_EOIMODE_EL3
| ICC_CTLR_EL3_RM
);
1240 val
= old_icc_ctlr_el3
|
1241 (val
& (ICC_CTLR_EL3_EOIMODE_EL3
| ICC_CTLR_EL3_RM
));
1245 case MISCREG_ICC_PMR
:
1246 case MISCREG_ICC_PMR_EL1
: { // Priority Mask Register
1247 if ((currEL() == EL1
) && !inSecureState() &&
1248 (hcr_imo
|| hcr_fmo
)) {
1249 return isa
->setMiscRegNoEffect(MISCREG_ICV_PMR_EL1
, val
);
1253 SCR scr_el3
= isa
->readMiscRegNoEffect(MISCREG_SCR_EL3
);
1255 if (haveEL(EL3
) && !inSecureState() && (scr_el3
.fiq
)) {
1257 * NS access and Group 0 is inaccessible to NS: return the
1258 * NS view of the current priority
1260 ArmISA::MiscReg old_icc_pmr_el1
=
1261 isa
->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1
);
1263 if (!(old_icc_pmr_el1
& 0x80)) {
1264 /* Current PMR in the secure range, don't allow NS to
1269 val
= (val
>> 1) | 0x80;
1272 val
&= ~0U << (8 - PRIORITY_BITS
);
1276 case MISCREG_ICC_IGRPEN0
:
1277 case MISCREG_ICC_IGRPEN0_EL1
: { // Interrupt Group 0 Enable Register
1278 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
1279 return setMiscReg(MISCREG_ICV_IGRPEN0_EL1
, val
);
1285 case MISCREG_ICV_IGRPEN0_EL1
: {
1286 bool enable
= val
& 0x1;
1287 ArmISA::MiscReg ich_vmcr_el2
=
1288 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
1289 ich_vmcr_el2
= insertBits(ich_vmcr_el2
,
1290 ICH_VMCR_EL2_VENG0_SHIFT
, enable
);
1291 isa
->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
, ich_vmcr_el2
);
1296 case MISCREG_ICC_IGRPEN1
:
1297 case MISCREG_ICC_IGRPEN1_EL1
: { // Interrupt Group 1 Enable Register
1298 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
1299 return setMiscReg(MISCREG_ICV_IGRPEN1_EL1
, val
);
1305 case MISCREG_ICV_IGRPEN1_EL1
: {
1306 bool enable
= val
& 0x1;
1307 ArmISA::MiscReg ich_vmcr_el2
=
1308 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
1309 ich_vmcr_el2
= insertBits(ich_vmcr_el2
,
1310 ICH_VMCR_EL2_VENG1_SHIFT
, enable
);
1311 isa
->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
, ich_vmcr_el2
);
1316 case MISCREG_ICC_MGRPEN1
:
1317 case MISCREG_ICC_IGRPEN1_EL3
: {
1318 // EnableGrp1S and EnableGrp1NS are aliased with
1319 // ICC_IGRPEN1_EL1_S.Enable and ICC_IGRPEN1_EL1_NS.Enable
1320 bool enable_grp_1s
= val
& ICC_IGRPEN1_EL3_ENABLEGRP1S
;
1321 bool enable_grp_1ns
= val
& ICC_IGRPEN1_EL3_ENABLEGRP1NS
;
1322 isa
->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S
, enable_grp_1s
);
1323 isa
->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS
, enable_grp_1ns
);
1327 // Software Generated Interrupt Group 0 Register
1328 case MISCREG_ICC_SGI0R
:
1329 case MISCREG_ICC_SGI0R_EL1
:
1331 // Software Generated Interrupt Group 1 Register
1332 case MISCREG_ICC_SGI1R
:
1333 case MISCREG_ICC_SGI1R_EL1
:
1335 // Alias Software Generated Interrupt Group 1 Register
1336 case MISCREG_ICC_ASGI1R
:
1337 case MISCREG_ICC_ASGI1R_EL1
: {
1338 bool ns
= !inSecureState();
1339 Gicv3::GroupId group
;
1341 if (misc_reg
== MISCREG_ICC_SGI1R_EL1
) {
1342 group
= ns
? Gicv3::G1NS
: Gicv3::G1S
;
1343 } else if (misc_reg
== MISCREG_ICC_ASGI1R_EL1
) {
1344 group
= ns
? Gicv3::G1S
: Gicv3::G1NS
;
1349 if (distributor
->DS
&& group
== Gicv3::G1S
) {
1353 uint8_t aff3
= bits(val
, 55, 48);
1354 uint8_t aff2
= bits(val
, 39, 32);
1355 uint8_t aff1
= bits(val
, 23, 16);;
1356 uint16_t target_list
= bits(val
, 15, 0);
1357 uint32_t int_id
= bits(val
, 27, 24);
1358 bool irm
= bits(val
, 40, 40);
1359 uint8_t rs
= bits(val
, 47, 44);
1361 for (int i
= 0; i
< gic
->getSystem()->numContexts(); i
++) {
1362 Gicv3Redistributor
* redistributor_i
=
1363 gic
->getRedistributor(i
);
1364 uint32_t affinity_i
= redistributor_i
->getAffinity();
1367 // Interrupts routed to all PEs in the system,
1369 if (affinity_i
== redistributor
->getAffinity()) {
1373 // Interrupts routed to the PEs specified by
1374 // Aff3.Aff2.Aff1.<target list>
1375 if ((affinity_i
>> 8) !=
1376 ((aff3
<< 16) | (aff2
<< 8) | (aff1
<< 0))) {
1380 uint8_t aff0_i
= bits(affinity_i
, 7, 0);
1382 if (!(aff0_i
>= rs
* 16 && aff0_i
< (rs
+ 1) * 16 &&
1383 ((0x1 << (aff0_i
- rs
* 16)) & target_list
))) {
1388 redistributor_i
->sendSGI(int_id
, group
, ns
);
1394 case MISCREG_ICC_SRE
:
1395 case MISCREG_ICC_SRE_EL1
: { // System Register Enable Register EL1
1396 if (!(val
& ICC_SRE_EL1_SRE
)) {
1397 warn("Gicv3CPUInterface::setMiscReg(): "
1398 "ICC_SRE_EL*.SRE is RAO/WI, legacy not supported!\n");
1401 bool dfb
= val
& ICC_SRE_EL1_DFB
;
1402 bool dib
= val
& ICC_SRE_EL1_DIB
;
1404 if (haveEL(EL3
) && !distributor
->DS
) {
1405 // DIB is RO alias of ICC_SRE_EL3.DIB
1406 // DFB is RO alias of ICC_SRE_EL3.DFB
1407 } else if (haveEL(EL3
) && distributor
->DS
) {
1408 // DIB is RW alias of ICC_SRE_EL3.DIB
1409 // DFB is RW alias of ICC_SRE_EL3.DFB
1410 ArmISA::MiscReg icc_sre_el3
=
1411 isa
->readMiscRegNoEffect(MISCREG_ICC_SRE_EL3
);
1412 icc_sre_el3
= insertBits(icc_sre_el3
, ICC_SRE_EL3_DFB
, dfb
);
1413 icc_sre_el3
= insertBits(icc_sre_el3
, ICC_SRE_EL3_DIB
, dib
);
1414 isa
->setMiscRegNoEffect(MISCREG_ICC_SRE_EL3
, icc_sre_el3
);
1415 } else if ((!haveEL(EL3
) || distributor
->DS
) and haveEL(EL2
)) {
1416 // DIB is RO alias of ICC_SRE_EL2.DIB
1417 // DFB is RO alias of ICC_SRE_EL2.DFB
1419 isa
->setMiscRegNoEffect(misc_reg
, val
);
1425 case MISCREG_ICC_HSRE
:
1426 case MISCREG_ICC_SRE_EL2
: // System Register Enable Register EL2
1427 case MISCREG_ICC_MSRE
:
1428 case MISCREG_ICC_SRE_EL3
: // System Register Enable Register EL3
1429 if (!(val
& (1 << 0))) {
1430 warn("Gicv3CPUInterface::setMiscReg(): "
1431 "ICC_SRE_EL*.SRE is RAO/WI, legacy not supported!\n");
1434 // All bits are RAO/WI
1437 case MISCREG_ICH_HCR
:
1438 case MISCREG_ICH_HCR_EL2
:
1439 val
&= ICH_HCR_EL2_EN
| ICH_HCR_EL2_UIE
| ICH_HCR_EL2_LRENPIE
|
1440 ICH_HCR_EL2_NPIE
| ICH_HCR_EL2_VGRP0EIE
|
1441 ICH_HCR_EL2_VGRP0DIE
| ICH_HCR_EL2_VGRP1EIE
|
1442 ICH_HCR_EL2_VGRP1DIE
| ICH_HCR_EL2_TC
| ICH_HCR_EL2_TALL0
|
1443 ICH_HCR_EL2_TALL1
| ICH_HCR_EL2_TDIR
|
1444 ICH_HCR_EL2_EOICOUNT_MASK
;
1445 do_virtual_update
= true;
1448 case MISCREG_ICH_LRC0
... MISCREG_ICH_LRC15
:
1449 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
1451 // Enforce RES0 bits in priority field, 5 of 8 bits used
1452 val
= insertBits(val
, ICH_LRC_PRIORITY_SHIFT
+ 2,
1453 ICH_LRC_PRIORITY_SHIFT
, 0);
1454 ArmISA::MiscReg old_val
= isa
->readMiscRegNoEffect(misc_reg
);
1455 val
= (old_val
& 0xffffffff) | (val
<< 32);
1456 do_virtual_update
= true;
1460 case MISCREG_ICH_LR0
... MISCREG_ICH_LR15
: {
1461 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
1462 ArmISA::MiscReg old_val
= isa
->readMiscRegNoEffect(misc_reg
);
1463 val
= (old_val
& 0xffffffff00000000) | (val
& 0xffffffff);
1464 do_virtual_update
= true;
1468 case MISCREG_ICH_LR0_EL2
... MISCREG_ICH_LR15_EL2
: { // AArch64
1469 // Enforce RES0 bits in priority field, 5 of 8 bits used
1470 val
= insertBits(val
, ICH_LR_EL2_PRIORITY_SHIFT
+ 2,
1471 ICH_LR_EL2_PRIORITY_SHIFT
, 0);
1472 do_virtual_update
= true;
1476 case MISCREG_ICH_VMCR
:
1477 case MISCREG_ICH_VMCR_EL2
: {
1478 val
&= ICH_VMCR_EL2_VENG0
| ICH_VMCR_EL2_VENG1
|
1479 ICH_VMCR_EL2_VCBPR
| ICH_VMCR_EL2_VEOIM
|
1480 ICH_VMCR_EL2_VBPR1_MASK
| ICH_VMCR_EL2_VBPR0_MASK
|
1481 ICH_VMCR_EL2_VPMR_MASK
;
1482 val
|= ICH_VMCR_EL2_VFIQEN
; // RES1
1483 // Check VBPRs against minimun allowed value
1484 uint8_t vbpr0
= bits(val
, 23, 21);
1485 uint8_t vbpr1
= bits(val
, 20, 18);
1486 uint8_t min_vpr0
= 7 - VIRTUAL_PREEMPTION_BITS
;
1487 uint8_t min_vpr1
= min_vpr0
+ 1;
1488 vbpr0
= vbpr0
< min_vpr0
? min_vpr0
: vbpr0
;
1489 vbpr1
= vbpr1
< min_vpr1
? min_vpr1
: vbpr1
;
1490 val
= insertBits(val
, ICH_VMCR_EL2_VBPR0_SHIFT
+ 2,
1491 ICH_VMCR_EL2_VBPR0_SHIFT
, vbpr0
);
1492 val
= insertBits(val
, ICH_VMCR_EL2_VBPR1_SHIFT
+ 2,
1493 ICH_VMCR_EL2_VBPR1_SHIFT
, vbpr1
);
1497 case MISCREG_ICH_AP0R0
... MISCREG_ICH_AP0R3
:
1498 case MISCREG_ICH_AP0R0_EL2
... MISCREG_ICH_AP0R3_EL2
:
1499 case MISCREG_ICH_AP1R0
... MISCREG_ICH_AP1R3
:
1500 case MISCREG_ICH_AP1R0_EL2
... MISCREG_ICH_AP1R3_EL2
:
1504 panic("Gicv3CPUInterface::setMiscReg(): "
1505 "unknown register %d (%s)",
1506 misc_reg
, miscRegName
[misc_reg
]);
1509 isa
->setMiscRegNoEffect(misc_reg
, val
);
1511 if (do_virtual_update
) {
1517 Gicv3CPUInterface::virtualFindActive(uint32_t int_id
)
1519 for (uint32_t lr_idx
= 0; lr_idx
< VIRTUAL_NUM_LIST_REGS
; lr_idx
++) {
1520 ArmISA::MiscReg lr
=
1521 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
1522 uint32_t lr_intid
= bits(lr
, 31, 0);
1524 if ((lr
& ICH_LR_EL2_STATE_ACTIVE_BIT
) && lr_intid
== int_id
) {
1533 Gicv3CPUInterface::getHPPIR0()
1535 if (hppi
.prio
== 0xff) {
1536 return Gicv3::INTID_SPURIOUS
;
1539 bool irq_is_secure
= !distributor
->DS
&& hppi
.group
!= Gicv3::G1NS
;
1541 if ((hppi
.group
!= Gicv3::G0S
) && isEL3OrMon()) {
1542 /* Indicate to EL3 that there's a Group 1 interrupt for the
1543 * other state pending.
1545 return irq_is_secure
? Gicv3::INTID_SECURE
: Gicv3::INTID_NONSECURE
;
1548 if ((hppi
.group
!= Gicv3::G0S
)) { // && !isEL3OrMon())
1549 return Gicv3::INTID_SPURIOUS
;
1552 if (irq_is_secure
&& !inSecureState()) {
1553 // Secure interrupts not visible in Non-secure
1554 return Gicv3::INTID_SPURIOUS
;
1561 Gicv3CPUInterface::getHPPIR1()
1563 if (hppi
.prio
== 0xff) {
1564 return Gicv3::INTID_SPURIOUS
;
1567 //if ((currEL() == EL3) && ICC_CTLR_EL3_RM)
1568 if ((currEL() == EL3
) &&
1569 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3
) & ICC_CTLR_EL3_RM
) {
1570 if (hppi
.group
== Gicv3::G0S
) {
1571 return Gicv3::INTID_SECURE
;
1572 } else if (hppi
.group
== Gicv3::G1NS
) {
1573 return Gicv3::INTID_NONSECURE
;
1577 if (hppi
.group
== Gicv3::G0S
) {
1578 return Gicv3::INTID_SPURIOUS
;
1581 bool irq_is_secure
= (distributor
->DS
== 0) && (hppi
.group
!= Gicv3::G1NS
);
1583 if (irq_is_secure
) {
1584 if (!inSecureState()) {
1585 // Secure interrupts not visible in Non-secure
1586 return Gicv3::INTID_SPURIOUS
;
1588 } else if (!isEL3OrMon() && inSecureState()) {
1589 // Group 1 non-secure interrupts not visible in Secure EL1
1590 return Gicv3::INTID_SPURIOUS
;
1597 Gicv3CPUInterface::dropPriority(Gicv3::GroupId group
)
1600 ArmISA::MiscReg apr
;
1601 apr_misc_reg
= group
== Gicv3::G0S
?
1602 MISCREG_ICC_AP0R0_EL1
: MISCREG_ICC_AP1R0_EL1
;
1603 apr
= isa
->readMiscRegNoEffect(apr_misc_reg
);
1606 /* Clear the lowest set bit */
1608 isa
->setMiscRegNoEffect(apr_misc_reg
, apr
);
1615 Gicv3CPUInterface::virtualDropPriority()
1617 /* Drop the priority of the currently active virtual interrupt
1618 * (favouring group 0 if there is a set active bit at
1619 * the same priority for both group 0 and group 1).
1620 * Return the priority value for the bit we just cleared,
1621 * or 0xff if no bits were set in the AP registers at all.
1622 * Note that though the ich_apr[] are uint64_t only the low
1623 * 32 bits are actually relevant.
1625 int apr_max
= 1 << (VIRTUAL_PREEMPTION_BITS
- 5);
1627 for (int i
= 0; i
< apr_max
; i
++) {
1628 ArmISA::MiscReg vapr0
=
1629 isa
->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2
+ i
);
1630 ArmISA::MiscReg vapr1
=
1631 isa
->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2
+ i
);
1633 if (!vapr0
&& !vapr1
) {
1637 int vapr0_count
= ctz32(vapr0
);
1638 int vapr1_count
= ctz32(vapr1
);
1640 if (vapr0_count
<= vapr1_count
) {
1641 /* Clear the lowest set bit */
1643 isa
->setMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2
+ i
, vapr0
);
1644 return (vapr0_count
+ i
* 32) << (GIC_MIN_VBPR
+ 1);
1646 /* Clear the lowest set bit */
1648 isa
->setMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2
+ i
, vapr1
);
1649 return (vapr1_count
+ i
* 32) << (GIC_MIN_VBPR
+ 1);
1657 Gicv3CPUInterface::activateIRQ(uint32_t int_id
, Gicv3::GroupId group
)
1659 // Update active priority registers.
1660 uint32_t prio
= hppi
.prio
& 0xf8;
1661 int apr_bit
= prio
>> (8 - PRIORITY_BITS
);
1662 int reg_bit
= apr_bit
% 32;
1663 int apr_idx
= group
== Gicv3::G0S
?
1664 MISCREG_ICC_AP0R0_EL1
: MISCREG_ICC_AP1R0_EL1
;
1665 ArmISA::MiscReg apr
= isa
->readMiscRegNoEffect(apr_idx
);
1666 apr
|= (1 << reg_bit
);
1667 isa
->setMiscRegNoEffect(apr_idx
, apr
);
1669 // Move interrupt state from pending to active.
1670 if (int_id
< Gicv3::SGI_MAX
+ Gicv3::PPI_MAX
) {
1671 // SGI or PPI, redistributor
1672 redistributor
->activateIRQ(int_id
);
1673 redistributor
->updateAndInformCPUInterface();
1674 } else if (int_id
< Gicv3::INTID_SECURE
) {
1676 distributor
->activateIRQ(int_id
);
1677 distributor
->updateAndInformCPUInterfaces();
1682 Gicv3CPUInterface::virtualActivateIRQ(uint32_t lr_idx
)
1684 // Update active priority registers.
1685 ArmISA::MiscReg lr
= isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+
1687 Gicv3::GroupId group
= lr
& ICH_LR_EL2_GROUP
? Gicv3::G1NS
: Gicv3::G0S
;
1688 uint8_t prio
= bits(lr
, 55, 48) & 0xf8;
1689 int apr_bit
= prio
>> (8 - VIRTUAL_PREEMPTION_BITS
);
1690 int reg_no
= apr_bit
/ 32;
1691 int reg_bit
= apr_bit
% 32;
1692 int apr_idx
= group
== Gicv3::G0S
?
1693 MISCREG_ICH_AP0R0_EL2
+ reg_no
: MISCREG_ICH_AP1R0_EL2
+ reg_no
;
1694 ArmISA::MiscReg apr
= isa
->readMiscRegNoEffect(apr_idx
);
1695 apr
|= (1 << reg_bit
);
1696 isa
->setMiscRegNoEffect(apr_idx
, apr
);
1697 // Move interrupt state from pending to active.
1698 lr
&= ~ICH_LR_EL2_STATE_PENDING_BIT
;
1699 lr
|= ICH_LR_EL2_STATE_ACTIVE_BIT
;
1700 isa
->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
, lr
);
1704 Gicv3CPUInterface::deactivateIRQ(uint32_t int_id
, Gicv3::GroupId group
)
1706 if (int_id
< Gicv3::SGI_MAX
+ Gicv3::PPI_MAX
) {
1707 // SGI or PPI, redistributor
1708 redistributor
->deactivateIRQ(int_id
);
1709 redistributor
->updateAndInformCPUInterface();
1710 } else if (int_id
< Gicv3::INTID_SECURE
) {
1712 distributor
->deactivateIRQ(int_id
);
1713 distributor
->updateAndInformCPUInterfaces();
1720 Gicv3CPUInterface::virtualDeactivateIRQ(int lr_idx
)
1722 ArmISA::MiscReg lr
= isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+
1725 if (lr
& ICH_LR_EL2_HW
) {
1726 // Deactivate the associated physical interrupt
1727 int pintid
= bits(lr
, 41, 32);
1729 if (pintid
< Gicv3::INTID_SECURE
) {
1730 Gicv3::GroupId group
=
1731 pintid
>= 32 ? distributor
->getIntGroup(pintid
) :
1732 redistributor
->getIntGroup(pintid
);
1733 deactivateIRQ(pintid
, group
);
1737 // Remove the active bit
1738 lr
&= ~ICH_LR_EL2_STATE_ACTIVE_BIT
;
1739 isa
->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
, lr
);
1743 * Return a mask word which clears the subpriority bits from
1744 * a priority value for an interrupt in the specified group.
1745 * This depends on the BPR value. For CBPR0 (S or NS):
1746 * a BPR of 0 means the group priority bits are [7:1];
1747 * a BPR of 1 means they are [7:2], and so on down to
1749 * a BPR of 7 meaning no group priority bits at all.
1751 * a BPR of 0 is impossible (the minimum value is 1)
1752 * a BPR of 1 means the group priority bits are [7:1];
1753 * a BPR of 2 means they are [7:2], and so on down to
1755 * a BPR of 7 meaning the group priority is [7].
1757 * Which BPR to use depends on the group of the interrupt and
1758 * the current ICC_CTLR.CBPR settings.
1760 * This corresponds to the GroupBits() pseudocode from 4.8.2.
1763 Gicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group
)
1765 if ((group
== Gicv3::G1S
&&
1766 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S
)
1767 & ICC_CTLR_EL1_CBPR
) ||
1768 (group
== Gicv3::G1NS
&&
1769 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS
)
1770 & ICC_CTLR_EL1_CBPR
)) {
1776 if (group
== Gicv3::G0S
) {
1777 bpr
= isa
->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1
) & 0x7;
1779 bpr
= isa
->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1
) & 0x7;
1782 if (group
== Gicv3::G1NS
) {
1787 return ~0U << (bpr
+ 1);
1791 Gicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group
)
1793 ArmISA::MiscReg ich_vmcr_el2
=
1794 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
1796 if (group
== Gicv3::G1NS
&& (ich_vmcr_el2
& ICH_VMCR_EL2_VCBPR
)) {
1802 if (group
== Gicv3::G0S
) {
1803 bpr
= bits(ich_vmcr_el2
, 23, 21);
1805 bpr
= bits(ich_vmcr_el2
, 20, 18);
1808 if (group
== Gicv3::G1NS
) {
1813 return ~0U << (bpr
+ 1);
1817 Gicv3CPUInterface::isEOISplitMode()
1820 return isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3
) &
1821 ICC_CTLR_EL3_EOIMODE_EL3
;
1823 return isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1
) &
1824 ICC_CTLR_EL1_EOIMODE
;
1829 Gicv3CPUInterface::virtualIsEOISplitMode()
1831 ArmISA::MiscReg ich_vmcr_el2
=
1832 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
1833 return ich_vmcr_el2
& ICH_VMCR_EL2_VEOIM
;
1837 Gicv3CPUInterface::highestActiveGroup()
1839 int g0_ctz
= ctz32(isa
->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1
));
1840 int gq_ctz
= ctz32(isa
->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S
));
1841 int g1nz_ctz
= ctz32(isa
->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS
));
1843 if (g1nz_ctz
< g0_ctz
&& g1nz_ctz
< gq_ctz
) {
1847 if (gq_ctz
< g0_ctz
) {
1859 Gicv3CPUInterface::update()
1861 bool signal_IRQ
= false;
1862 bool signal_FIQ
= false;
1864 if (hppi
.group
== Gicv3::G1S
&& !haveEL(EL3
)) {
1866 * Secure enabled GIC sending a G1S IRQ to a secure disabled
1867 * CPU -> send G0 IRQ
1869 hppi
.group
= Gicv3::G0S
;
1872 if (hppiCanPreempt()) {
1873 ArmISA::InterruptTypes int_type
= intSignalType(hppi
.group
);
1874 DPRINTF(GIC
, "Gicv3CPUInterface::update(): "
1875 "posting int as %d!\n", int_type
);
1876 int_type
== ArmISA::INT_IRQ
? signal_IRQ
= true : signal_FIQ
= true;
1880 gic
->postInt(cpuId
, ArmISA::INT_IRQ
);
1882 gic
->deassertInt(cpuId
, ArmISA::INT_IRQ
);
1886 gic
->postInt(cpuId
, ArmISA::INT_FIQ
);
1888 gic
->deassertInt(cpuId
, ArmISA::INT_FIQ
);
1893 Gicv3CPUInterface::virtualUpdate()
1895 bool signal_IRQ
= false;
1896 bool signal_FIQ
= false;
1897 int lr_idx
= getHPPVILR();
1900 ArmISA::MiscReg ich_lr_el2
=
1901 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
1903 if (hppviCanPreempt(lr_idx
)) {
1904 if (ich_lr_el2
& ICH_LR_EL2_GROUP
) {
1912 ArmISA::MiscReg ich_hcr_el2
=
1913 isa
->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2
);
1915 if (ich_hcr_el2
& ICH_HCR_EL2_EN
) {
1916 if (maintenanceInterruptStatus()) {
1917 redistributor
->sendPPInt(25);
1922 DPRINTF(GIC
, "Gicv3CPUInterface::virtualUpdate(): "
1923 "posting int as %d!\n", ArmISA::INT_VIRT_IRQ
);
1924 gic
->postInt(cpuId
, ArmISA::INT_VIRT_IRQ
);
1926 gic
->deassertInt(cpuId
, ArmISA::INT_VIRT_IRQ
);
1930 DPRINTF(GIC
, "Gicv3CPUInterface::virtualUpdate(): "
1931 "posting int as %d!\n", ArmISA::INT_VIRT_FIQ
);
1932 gic
->postInt(cpuId
, ArmISA::INT_VIRT_FIQ
);
1934 gic
->deassertInt(cpuId
, ArmISA::INT_VIRT_FIQ
);
1938 // Returns the intex of the LR with the HPPI
1940 Gicv3CPUInterface::getHPPVILR()
1943 ArmISA::MiscReg ich_vmcr_el2
=
1944 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
1946 if (!(ich_vmcr_el2
& (ICH_VMCR_EL2_VENG0
| ICH_VMCR_EL2_VENG1
))) {
1947 // VG0 and VG1 disabled...
1951 uint8_t highest_prio
= 0xff;
1953 for (int i
= 0; i
< 16; i
++) {
1954 ArmISA::MiscReg ich_lri_el2
=
1955 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ i
);
1956 uint8_t state
= bits(ich_lri_el2
, 63, 62);
1958 if (state
!= Gicv3::INT_PENDING
) {
1962 if (ich_lri_el2
& ICH_LR_EL2_GROUP
) {
1964 if (!(ich_vmcr_el2
& ICH_VMCR_EL2_VENG1
)) {
1969 if (!(ich_vmcr_el2
& ICH_VMCR_EL2_VENG0
)) {
1974 uint8_t prio
= bits(ich_lri_el2
, 55, 48);
1976 if (prio
< highest_prio
) {
1977 highest_prio
= prio
;
1986 Gicv3CPUInterface::hppviCanPreempt(int lr_idx
)
1988 ArmISA::MiscReg lr
= isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+
1991 if (!(isa
->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2
) & ICH_HCR_EL2_EN
)) {
1992 // virtual interface is disabled
1996 uint8_t prio
= bits(lr
, 55, 48);
1998 bits(isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
), 31, 24);
2005 uint8_t rprio
= virtualHighestActivePriority();
2007 if (rprio
== 0xff) {
2011 Gicv3::GroupId group
= lr
& ICH_LR_EL2_GROUP
? Gicv3::G1NS
: Gicv3::G0S
;
2012 uint32_t prio_mask
= virtualGroupPriorityMask(group
);
2014 if ((prio
& prio_mask
) < (rprio
& prio_mask
)) {
2022 Gicv3CPUInterface::virtualHighestActivePriority()
2024 uint8_t num_aprs
= 1 << (VIRTUAL_PRIORITY_BITS
- 5);
2026 for (int i
= 0; i
< num_aprs
; i
++) {
2027 ArmISA::MiscReg vapr
=
2028 isa
->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2
+ i
) |
2029 isa
->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2
+ i
);
2035 return (i
* 32 + ctz32(vapr
)) << (GIC_MIN_VBPR
+ 1);
2038 // no active interrups, return idle priority
2043 Gicv3CPUInterface::virtualIncrementEOICount()
2045 // Increment the EOICOUNT field in ICH_HCR_EL2
2046 ArmISA::MiscReg ich_hcr_el2
=
2047 isa
->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2
);
2048 uint32_t EOI_cout
= bits(ich_hcr_el2
, 31, 27);
2050 ich_hcr_el2
= insertBits(ich_hcr_el2
, 31, 27, EOI_cout
);
2051 isa
->setMiscRegNoEffect(MISCREG_ICH_HCR_EL2
, ich_hcr_el2
);
2055 * Should we signal the interrupt as IRQ or FIQ?
2056 * see spec section 4.6.2
2058 ArmISA::InterruptTypes
2059 Gicv3CPUInterface::intSignalType(Gicv3::GroupId group
)
2061 bool is_fiq
= false;
2069 is_fiq
= (distributor
->DS
== 0) &&
2070 (!inSecureState() || ((currEL() == EL3
) && isAA64()));
2074 is_fiq
= (distributor
->DS
== 0) && inSecureState();
2078 panic("Gicv3CPUInterface::intSignalType(): invalid group!");
2082 return ArmISA::INT_FIQ
;
2084 return ArmISA::INT_IRQ
;
2089 Gicv3CPUInterface::hppiCanPreempt()
2091 if (hppi
.prio
== 0xff) {
2092 // there is no pending interrupt
2096 if (!groupEnabled(hppi
.group
)) {
2097 // group disabled at CPU interface
2101 if (hppi
.prio
>= isa
->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1
)) {
2106 uint8_t rprio
= highestActivePriority();
2108 if (rprio
== 0xff) {
2112 uint32_t prio_mask
= groupPriorityMask(hppi
.group
);
2114 if ((hppi
.prio
& prio_mask
) < (rprio
& prio_mask
)) {
2122 Gicv3CPUInterface::highestActivePriority()
2124 uint32_t apr
= isa
->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1
) |
2125 isa
->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS
) |
2126 isa
->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S
);
2129 return ctz32(apr
) << (GIC_MIN_BPR
+ 1);
2132 // no active interrups, return idle priority
2137 Gicv3CPUInterface::groupEnabled(Gicv3::GroupId group
)
2141 return isa
->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1
) &
2142 ICC_IGRPEN0_EL1_ENABLE
;
2145 //if (distributor->DS)
2147 // return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS) &
2148 // ICC_IGRPEN1_EL1_ENABLE;
2152 return isa
->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S
) &
2153 ICC_IGRPEN1_EL1_ENABLE
;
2158 return isa
->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS
) &
2159 ICC_IGRPEN1_EL1_ENABLE
;
2162 panic("Gicv3CPUInterface::groupEnable(): invalid group!\n");
2167 Gicv3CPUInterface::inSecureState()
2169 if (!gic
->getSystem()->haveSecurity()) {
2173 CPSR cpsr
= isa
->readMiscRegNoEffect(MISCREG_CPSR
);
2174 SCR scr
= isa
->readMiscRegNoEffect(MISCREG_SCR
);
2175 return ArmISA::inSecureState(scr
, cpsr
);
2179 Gicv3CPUInterface::currEL()
2181 CPSR cpsr
= isa
->readMiscRegNoEffect(MISCREG_CPSR
);
2182 bool is_64
= opModeIs64((OperatingMode
)(uint8_t) cpsr
.mode
);
2185 return (ExceptionLevel
)(uint8_t) cpsr
.el
;
2187 switch (cpsr
.mode
) {
2204 Gicv3CPUInterface::haveEL(ExceptionLevel el
)
2212 return gic
->getSystem()->haveVirtualization();
2215 return gic
->getSystem()->haveSecurity();
2218 warn("Unimplemented Exception Level\n");
2224 Gicv3CPUInterface::isSecureBelowEL3()
2226 SCR scr
= isa
->readMiscRegNoEffect(MISCREG_SCR_EL3
);
2227 return haveEL(EL3
) && scr
.ns
== 0;
2231 Gicv3CPUInterface::isAA64()
2233 CPSR cpsr
= isa
->readMiscRegNoEffect(MISCREG_CPSR
);
2234 return opModeIs64((OperatingMode
)(uint8_t) cpsr
.mode
);
2238 Gicv3CPUInterface::isEL3OrMon()
2241 CPSR cpsr
= isa
->readMiscRegNoEffect(MISCREG_CPSR
);
2242 bool is_64
= opModeIs64((OperatingMode
)(uint8_t) cpsr
.mode
);
2244 if (is_64
&& (cpsr
.el
== EL3
)) {
2246 } else if (!is_64
&& (cpsr
.mode
== MODE_MON
)) {
2255 Gicv3CPUInterface::eoiMaintenanceInterruptStatus(uint32_t * misr
)
2257 /* Return a set of bits indicating the EOI maintenance interrupt status
2258 * for each list register. The EOI maintenance interrupt status is
2259 * 1 if LR.State == 0 && LR.HW == 0 && LR.EOI == 1
2260 * (see the GICv3 spec for the ICH_EISR_EL2 register).
2261 * If misr is not NULL then we should also collect the information
2262 * about the MISR.EOI, MISR.NP and MISR.U bits.
2265 int valid_count
= 0;
2266 bool seen_pending
= false;
2268 for (int lr_idx
= 0; lr_idx
< VIRTUAL_NUM_LIST_REGS
; lr_idx
++) {
2269 ArmISA::MiscReg lr
=
2270 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
2272 if ((lr
& (ICH_LR_EL2_STATE_MASK
| ICH_LR_EL2_HW
| ICH_LR_EL2_EOI
)) ==
2274 value
|= (1 << lr_idx
);
2277 if ((lr
& ICH_LR_EL2_STATE_MASK
)) {
2281 if (bits(lr
, ICH_LR_EL2_STATE_SHIFT
+ ICH_LR_EL2_STATE_LENGTH
,
2282 ICH_LR_EL2_STATE_SHIFT
) == ICH_LR_EL2_STATE_PENDING
) {
2283 seen_pending
= true;
2288 ArmISA::MiscReg ich_hcr_el2
=
2289 isa
->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2
);
2291 if (valid_count
< 2 && (ich_hcr_el2
& ICH_HCR_EL2_UIE
)) {
2292 *misr
|= ICH_MISR_EL2_U
;
2295 if (!seen_pending
&& (ich_hcr_el2
& ICH_HCR_EL2_NPIE
)) {
2296 *misr
|= ICH_MISR_EL2_NP
;
2300 *misr
|= ICH_MISR_EL2_EOI
;
2308 Gicv3CPUInterface::maintenanceInterruptStatus()
2310 /* Return a set of bits indicating the maintenance interrupt status
2311 * (as seen in the ICH_MISR_EL2 register).
2314 /* Scan list registers and fill in the U, NP and EOI bits */
2315 eoiMaintenanceInterruptStatus(&value
);
2316 ArmISA::MiscReg ich_hcr_el2
=
2317 isa
->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2
);
2318 ArmISA::MiscReg ich_vmcr_el2
=
2319 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
2321 if (ich_hcr_el2
& (ICH_HCR_EL2_LRENPIE
| ICH_HCR_EL2_EOICOUNT_MASK
)) {
2322 value
|= ICH_MISR_EL2_LRENP
;
2325 if ((ich_hcr_el2
& ICH_HCR_EL2_VGRP0EIE
) &&
2326 (ich_vmcr_el2
& ICH_VMCR_EL2_VENG0
)) {
2327 value
|= ICH_MISR_EL2_VGRP0E
;
2330 if ((ich_hcr_el2
& ICH_HCR_EL2_VGRP0DIE
) &&
2331 !(ich_vmcr_el2
& ICH_VMCR_EL2_VENG1
)) {
2332 value
|= ICH_MISR_EL2_VGRP0D
;
2335 if ((ich_hcr_el2
& ICH_HCR_EL2_VGRP1EIE
) &&
2336 (ich_vmcr_el2
& ICH_VMCR_EL2_VENG1
)) {
2337 value
|= ICH_MISR_EL2_VGRP1E
;
2340 if ((ich_hcr_el2
& ICH_HCR_EL2_VGRP1DIE
) &&
2341 !(ich_vmcr_el2
& ICH_VMCR_EL2_VENG1
)) {
2342 value
|= ICH_MISR_EL2_VGRP1D
;
2349 Gicv3CPUInterface::serialize(CheckpointOut
& cp
) const
2351 SERIALIZE_SCALAR(hppi
.intid
);
2352 SERIALIZE_SCALAR(hppi
.prio
);
2353 SERIALIZE_ENUM(hppi
.group
);
2357 Gicv3CPUInterface::unserialize(CheckpointIn
& cp
)
2359 UNSERIALIZE_SCALAR(hppi
.intid
);
2360 UNSERIALIZE_SCALAR(hppi
.prio
);
2361 UNSERIALIZE_ENUM(hppi
.group
);