2 * Copyright (c) 2019 ARM Limited
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.
14 * Copyright (c) 2018 Metempsy Technology Consulting
15 * All rights reserved.
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.
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.
41 #include "dev/arm/gic_v3_cpu_interface.hh"
43 #include "arch/arm/isa.hh"
44 #include "debug/GIC.hh"
45 #include "dev/arm/gic_v3.hh"
46 #include "dev/arm/gic_v3_distributor.hh"
47 #include "dev/arm/gic_v3_redistributor.hh"
49 const uint8_t Gicv3CPUInterface::GIC_MIN_BPR
;
50 const uint8_t Gicv3CPUInterface::GIC_MIN_BPR_NS
;
52 Gicv3CPUInterface::Gicv3CPUInterface(Gicv3
* gic
, uint32_t cpu_id
)
55 redistributor(nullptr),
60 hppi
.intid
= Gicv3::INTID_SPURIOUS
;
64 Gicv3CPUInterface::init()
66 redistributor
= gic
->getRedistributor(cpuId
);
67 distributor
= gic
->getDistributor();
71 Gicv3CPUInterface::resetHppi(uint32_t intid
)
73 if (intid
== hppi
.intid
)
78 Gicv3CPUInterface::setThreadContext(ThreadContext
*tc
)
80 maintenanceInterrupt
= gic
->params()->maint_int
->get(tc
);
84 Gicv3CPUInterface::getHCREL2FMO() const
86 HCR hcr
= isa
->readMiscRegNoEffect(MISCREG_HCR_EL2
);
88 if (hcr
.tge
&& hcr
.e2h
) {
98 Gicv3CPUInterface::getHCREL2IMO() const
100 HCR hcr
= isa
->readMiscRegNoEffect(MISCREG_HCR_EL2
);
102 if (hcr
.tge
&& hcr
.e2h
) {
104 } else if (hcr
.tge
) {
112 Gicv3CPUInterface::readMiscReg(int misc_reg
)
114 RegVal value
= isa
->readMiscRegNoEffect(misc_reg
);
115 bool hcr_fmo
= getHCREL2FMO();
116 bool hcr_imo
= getHCREL2IMO();
119 // Active Priorities Group 1 Registers
120 case MISCREG_ICC_AP1R0
:
121 case MISCREG_ICC_AP1R0_EL1
: {
122 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
123 return isa
->readMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1
);
126 return readBankedMiscReg(MISCREG_ICC_AP1R0_EL1
);
129 case MISCREG_ICC_AP1R1
:
130 case MISCREG_ICC_AP1R1_EL1
:
132 // only implemented if supporting 6 or more bits of priority
133 case MISCREG_ICC_AP1R2
:
134 case MISCREG_ICC_AP1R2_EL1
:
136 // only implemented if supporting 7 or more bits of priority
137 case MISCREG_ICC_AP1R3
:
138 case MISCREG_ICC_AP1R3_EL1
:
139 // only implemented if supporting 7 or more bits of priority
142 // Active Priorities Group 0 Registers
143 case MISCREG_ICC_AP0R0
:
144 case MISCREG_ICC_AP0R0_EL1
: {
145 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
146 return isa
->readMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1
);
152 case MISCREG_ICC_AP0R1
:
153 case MISCREG_ICC_AP0R1_EL1
:
155 // only implemented if supporting 6 or more bits of priority
156 case MISCREG_ICC_AP0R2
:
157 case MISCREG_ICC_AP0R2_EL1
:
159 // only implemented if supporting 7 or more bits of priority
160 case MISCREG_ICC_AP0R3
:
161 case MISCREG_ICC_AP0R3_EL1
:
162 // only implemented if supporting 7 or more bits of priority
165 // Interrupt Group 0 Enable register EL1
166 case MISCREG_ICC_IGRPEN0
:
167 case MISCREG_ICC_IGRPEN0_EL1
: {
168 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
169 return readMiscReg(MISCREG_ICV_IGRPEN0_EL1
);
175 case MISCREG_ICV_IGRPEN0_EL1
: {
176 ICH_VMCR_EL2 ich_vmcr_el2
=
177 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
178 value
= ich_vmcr_el2
.VENG0
;
182 // Interrupt Group 1 Enable register EL1
183 case MISCREG_ICC_IGRPEN1
:
184 case MISCREG_ICC_IGRPEN1_EL1
: {
185 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
186 return readMiscReg(MISCREG_ICV_IGRPEN1_EL1
);
189 value
= readBankedMiscReg(MISCREG_ICC_IGRPEN1_EL1
);
193 case MISCREG_ICV_IGRPEN1_EL1
: {
194 ICH_VMCR_EL2 ich_vmcr_el2
=
195 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
196 value
= ich_vmcr_el2
.VENG1
;
200 // Interrupt Group 1 Enable register EL3
201 case MISCREG_ICC_MGRPEN1
:
202 case MISCREG_ICC_IGRPEN1_EL3
: {
203 ICC_IGRPEN1_EL3 igrp_el3
= 0;
204 igrp_el3
.EnableGrp1S
= ((ICC_IGRPEN1_EL1
)isa
->readMiscRegNoEffect(
205 MISCREG_ICC_IGRPEN1_EL1_S
)).Enable
;
207 igrp_el3
.EnableGrp1NS
= ((ICC_IGRPEN1_EL1
)isa
->readMiscRegNoEffect(
208 MISCREG_ICC_IGRPEN1_EL1_NS
)).Enable
;
214 // Running Priority Register
215 case MISCREG_ICC_RPR
:
216 case MISCREG_ICC_RPR_EL1
: {
217 if ((currEL() == EL1
) && !inSecureState() &&
218 (hcr_imo
|| hcr_fmo
)) {
219 return readMiscReg(MISCREG_ICV_RPR_EL1
);
222 uint8_t rprio
= highestActivePriority();
224 if (haveEL(EL3
) && !inSecureState() &&
225 (isa
->readMiscRegNoEffect(MISCREG_SCR_EL3
) & (1U << 2))) {
226 // Spec section 4.8.1
227 // For Non-secure access to ICC_RPR_EL1 when SCR_EL3.FIQ == 1
228 if ((rprio
& 0x80) == 0) {
229 // If the current priority mask value is in the range of
230 // 0x00-0x7F a read access returns the value 0x0
232 } else if (rprio
!= 0xff) {
233 // If the current priority mask value is in the range of
234 // 0x80-0xFF a read access returns the Non-secure read of
236 rprio
= (rprio
<< 1) & 0xff;
244 // Virtual Running Priority Register
245 case MISCREG_ICV_RPR_EL1
: {
246 value
= virtualHighestActivePriority();
250 // Highest Priority Pending Interrupt Register 0
251 case MISCREG_ICC_HPPIR0
:
252 case MISCREG_ICC_HPPIR0_EL1
: {
253 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
254 return readMiscReg(MISCREG_ICV_HPPIR0_EL1
);
261 // Virtual Highest Priority Pending Interrupt Register 0
262 case MISCREG_ICV_HPPIR0_EL1
: {
263 value
= Gicv3::INTID_SPURIOUS
;
264 int lr_idx
= getHPPVILR();
267 ICH_LR_EL2 ich_lr_el2
=
268 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
269 Gicv3::GroupId group
=
270 ich_lr_el2
.Group
? Gicv3::G1NS
: Gicv3::G0S
;
272 if (group
== Gicv3::G0S
) {
273 value
= ich_lr_el2
.vINTID
;
280 // Highest Priority Pending Interrupt Register 1
281 case MISCREG_ICC_HPPIR1
:
282 case MISCREG_ICC_HPPIR1_EL1
: {
283 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
284 return readMiscReg(MISCREG_ICV_HPPIR1_EL1
);
291 // Virtual Highest Priority Pending Interrupt Register 1
292 case MISCREG_ICV_HPPIR1_EL1
: {
293 value
= Gicv3::INTID_SPURIOUS
;
294 int lr_idx
= getHPPVILR();
297 ICH_LR_EL2 ich_lr_el2
=
298 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
299 Gicv3::GroupId group
=
300 ich_lr_el2
.Group
? Gicv3::G1NS
: Gicv3::G0S
;
302 if (group
== Gicv3::G1NS
) {
303 value
= ich_lr_el2
.vINTID
;
310 // Binary Point Register 0
311 case MISCREG_ICC_BPR0
:
312 case MISCREG_ICC_BPR0_EL1
: {
313 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
314 return readMiscReg(MISCREG_ICV_BPR0_EL1
);
317 value
= isa
->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1
);
321 // Binary Point Register 1
322 case MISCREG_ICC_BPR1
:
323 case MISCREG_ICC_BPR1_EL1
: {
324 value
= bpr1(isSecureBelowEL3() ? Gicv3::G1S
: Gicv3::G1NS
);
328 // Virtual Binary Point Register 0
329 case MISCREG_ICV_BPR0_EL1
: {
330 ICH_VMCR_EL2 ich_vmcr_el2
=
331 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
333 value
= ich_vmcr_el2
.VBPR0
;
337 // Virtual Binary Point Register 1
338 case MISCREG_ICV_BPR1_EL1
: {
339 ICH_VMCR_EL2 ich_vmcr_el2
=
340 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
342 if (ich_vmcr_el2
.VCBPR
) {
343 // bpr0 + 1 saturated to 7, WI
344 value
= ich_vmcr_el2
.VBPR0
+ 1;
345 value
= value
< 7 ? value
: 7;
347 value
= ich_vmcr_el2
.VBPR1
;
353 // Interrupt Priority Mask Register
354 case MISCREG_ICC_PMR
:
355 case MISCREG_ICC_PMR_EL1
:
356 if ((currEL() == EL1
) && !inSecureState() && (hcr_imo
|| hcr_fmo
)) {
357 return readMiscReg(MISCREG_ICV_PMR_EL1
);
360 if (haveEL(EL3
) && !inSecureState() &&
361 (isa
->readMiscRegNoEffect(MISCREG_SCR_EL3
) & (1U << 2))) {
362 // Spec section 4.8.1
363 // For Non-secure access to ICC_PMR_EL1 when SCR_EL3.FIQ == 1:
364 if ((value
& 0x80) == 0) {
365 // If the current priority mask value is in the range of
366 // 0x00-0x7F a read access returns the value 0x00.
368 } else if (value
!= 0xff) {
369 // If the current priority mask value is in the range of
370 // 0x80-0xFF a read access returns the Non-secure read of the
372 value
= (value
<< 1) & 0xff;
378 case MISCREG_ICV_PMR_EL1
: { // Priority Mask Register
379 ICH_VMCR_EL2 ich_vmcr_el2
=
380 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
382 value
= ich_vmcr_el2
.VPMR
;
386 // Interrupt Acknowledge Register 0
387 case MISCREG_ICC_IAR0
:
388 case MISCREG_ICC_IAR0_EL1
: {
389 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
390 return readMiscReg(MISCREG_ICV_IAR0_EL1
);
395 if (hppiCanPreempt()) {
396 int_id
= getHPPIR0();
398 // avoid activation for special interrupts
399 if (int_id
< Gicv3::INTID_SECURE
||
400 int_id
>= Gicv3Redistributor::SMALLEST_LPI_ID
) {
401 activateIRQ(int_id
, hppi
.group
);
404 int_id
= Gicv3::INTID_SPURIOUS
;
411 // Virtual Interrupt Acknowledge Register 0
412 case MISCREG_ICV_IAR0_EL1
: {
413 int lr_idx
= getHPPVILR();
414 uint32_t int_id
= Gicv3::INTID_SPURIOUS
;
417 ICH_LR_EL2 ich_lr_el2
=
418 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
420 if (!ich_lr_el2
.Group
&& hppviCanPreempt(lr_idx
)) {
421 int_id
= ich_lr_el2
.vINTID
;
423 if (int_id
< Gicv3::INTID_SECURE
||
424 int_id
> Gicv3::INTID_SPURIOUS
) {
425 virtualActivateIRQ(lr_idx
);
427 // Bogus... Pseudocode says:
428 // - Move from pending to invalid...
429 // - Return de bogus id...
430 ich_lr_el2
.State
= ICH_LR_EL2_STATE_INVALID
;
431 isa
->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
,
442 // Interrupt Acknowledge Register 1
443 case MISCREG_ICC_IAR1
:
444 case MISCREG_ICC_IAR1_EL1
: {
445 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
446 return readMiscReg(MISCREG_ICV_IAR1_EL1
);
451 if (hppiCanPreempt()) {
452 int_id
= getHPPIR1();
454 // avoid activation for special interrupts
455 if (int_id
< Gicv3::INTID_SECURE
||
456 int_id
>= Gicv3Redistributor::SMALLEST_LPI_ID
) {
457 activateIRQ(int_id
, hppi
.group
);
460 int_id
= Gicv3::INTID_SPURIOUS
;
467 // Virtual Interrupt Acknowledge Register 1
468 case MISCREG_ICV_IAR1_EL1
: {
469 int lr_idx
= getHPPVILR();
470 uint32_t int_id
= Gicv3::INTID_SPURIOUS
;
473 ICH_LR_EL2 ich_lr_el2
=
474 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
476 if (ich_lr_el2
.Group
&& hppviCanPreempt(lr_idx
)) {
477 int_id
= ich_lr_el2
.vINTID
;
479 if (int_id
< Gicv3::INTID_SECURE
||
480 int_id
> Gicv3::INTID_SPURIOUS
) {
481 virtualActivateIRQ(lr_idx
);
483 // Bogus... Pseudocode says:
484 // - Move from pending to invalid...
485 // - Return de bogus id...
486 ich_lr_el2
.State
= ICH_LR_EL2_STATE_INVALID
;
487 isa
->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
,
498 // System Register Enable Register EL1
499 case MISCREG_ICC_SRE
:
500 case MISCREG_ICC_SRE_EL1
: {
502 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
503 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
504 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
506 ICC_SRE_EL1 icc_sre_el1
= 0;
514 // System Register Enable Register EL2
515 case MISCREG_ICC_HSRE
:
516 case MISCREG_ICC_SRE_EL2
: {
519 * (EL1 accesses to ICC_SRE_EL1 do not trap to EL2, RAO/WI)
520 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
521 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
522 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
524 ICC_SRE_EL2 icc_sre_el2
= 0;
528 icc_sre_el2
.Enable
= 1;
533 // System Register Enable Register EL3
534 case MISCREG_ICC_MSRE
:
535 case MISCREG_ICC_SRE_EL3
: {
538 * (EL1 accesses to ICC_SRE_EL1 do not trap to EL3.
539 * EL2 accesses to ICC_SRE_EL1 and ICC_SRE_EL2 do not trap to EL3.
541 * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
542 * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
543 * SRE [0] == 1 (Only system register interface supported, RAO/WI)
545 ICC_SRE_EL3 icc_sre_el3
= 0;
549 icc_sre_el3
.Enable
= 1;
555 case MISCREG_ICC_CTLR
:
556 case MISCREG_ICC_CTLR_EL1
: {
557 if ((currEL() == EL1
) && !inSecureState() && (hcr_imo
|| hcr_fmo
)) {
558 return readMiscReg(MISCREG_ICV_CTLR_EL1
);
561 value
= readBankedMiscReg(MISCREG_ICC_CTLR_EL1
);
562 // Enforce value for RO bits
563 // ExtRange [19], INTIDs in the range 1024..8191 not supported
564 // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
565 // A3V [15], supports non-zero values of the Aff3 field in SGI
566 // generation System registers
567 // SEIS [14], does not support generation of SEIs (deprecated)
568 // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
569 // PRIbits [10:8], number of priority bits implemented, minus one
570 ICC_CTLR_EL1 icc_ctlr_el1
= value
;
571 icc_ctlr_el1
.ExtRange
= 0;
572 icc_ctlr_el1
.RSS
= 1;
573 icc_ctlr_el1
.A3V
= 1;
574 icc_ctlr_el1
.SEIS
= 0;
575 icc_ctlr_el1
.IDbits
= 1;
576 icc_ctlr_el1
.PRIbits
= PRIORITY_BITS
- 1;
577 value
= icc_ctlr_el1
;
581 // Virtual Control Register
582 case MISCREG_ICV_CTLR_EL1
: {
583 ICV_CTLR_EL1 icv_ctlr_el1
= value
;
584 icv_ctlr_el1
.RSS
= 0;
585 icv_ctlr_el1
.A3V
= 1;
586 icv_ctlr_el1
.SEIS
= 0;
587 icv_ctlr_el1
.IDbits
= 1;
588 icv_ctlr_el1
.PRIbits
= 7;
589 value
= icv_ctlr_el1
;
594 case MISCREG_ICC_MCTLR
:
595 case MISCREG_ICC_CTLR_EL3
: {
596 // Enforce value for RO bits
597 // ExtRange [19], INTIDs in the range 1024..8191 not supported
598 // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
599 // nDS [17], supports disabling of security
600 // A3V [15], supports non-zero values of the Aff3 field in SGI
601 // generation System registers
602 // SEIS [14], does not support generation of SEIs (deprecated)
603 // IDbits [13:11], 001 = 24 bits | 000 = 16 bits
604 // PRIbits [10:8], number of priority bits implemented, minus one
605 ICC_CTLR_EL3 icc_ctlr_el3
= value
;
606 icc_ctlr_el3
.ExtRange
= 0;
607 icc_ctlr_el3
.RSS
= 1;
608 icc_ctlr_el3
.nDS
= 0;
609 icc_ctlr_el3
.A3V
= 1;
610 icc_ctlr_el3
.SEIS
= 0;
611 icc_ctlr_el3
.IDbits
= 0;
612 icc_ctlr_el3
.PRIbits
= PRIORITY_BITS
- 1;
613 value
= icc_ctlr_el3
;
617 // Hyp Control Register
618 case MISCREG_ICH_HCR
:
619 case MISCREG_ICH_HCR_EL2
:
622 // Hyp Active Priorities Group 0 Registers
623 case MISCREG_ICH_AP0R0
:
624 case MISCREG_ICH_AP0R0_EL2
:
627 // only implemented if supporting 6 or more bits of priority
628 case MISCREG_ICH_AP0R1
:
629 case MISCREG_ICH_AP0R1_EL2
:
630 // only implemented if supporting 7 or more bits of priority
631 case MISCREG_ICH_AP0R2
:
632 case MISCREG_ICH_AP0R2_EL2
:
633 // only implemented if supporting 7 or more bits of priority
634 case MISCREG_ICH_AP0R3
:
635 case MISCREG_ICH_AP0R3_EL2
:
636 // Unimplemented registers are RAZ/WI
639 // Hyp Active Priorities Group 1 Registers
640 case MISCREG_ICH_AP1R0
:
641 case MISCREG_ICH_AP1R0_EL2
:
644 // only implemented if supporting 6 or more bits of priority
645 case MISCREG_ICH_AP1R1
:
646 case MISCREG_ICH_AP1R1_EL2
:
647 // only implemented if supporting 7 or more bits of priority
648 case MISCREG_ICH_AP1R2
:
649 case MISCREG_ICH_AP1R2_EL2
:
650 // only implemented if supporting 7 or more bits of priority
651 case MISCREG_ICH_AP1R3
:
652 case MISCREG_ICH_AP1R3_EL2
:
653 // Unimplemented registers are RAZ/WI
656 // Maintenance Interrupt State Register
657 case MISCREG_ICH_MISR
:
658 case MISCREG_ICH_MISR_EL2
:
659 value
= maintenanceInterruptStatus();
662 // VGIC Type Register
663 case MISCREG_ICH_VTR
:
664 case MISCREG_ICH_VTR_EL2
: {
665 ICH_VTR_EL2 ich_vtr_el2
= value
;
667 ich_vtr_el2
.ListRegs
= VIRTUAL_NUM_LIST_REGS
- 1;
669 ich_vtr_el2
.IDbits
= 1;
670 ich_vtr_el2
.PREbits
= VIRTUAL_PREEMPTION_BITS
- 1;
671 ich_vtr_el2
.PRIbits
= VIRTUAL_PRIORITY_BITS
- 1;
677 // End of Interrupt Status Register
678 case MISCREG_ICH_EISR
:
679 case MISCREG_ICH_EISR_EL2
:
680 value
= eoiMaintenanceInterruptStatus();
683 // Empty List Register Status Register
684 case MISCREG_ICH_ELRSR
:
685 case MISCREG_ICH_ELRSR_EL2
:
688 for (int lr_idx
= 0; lr_idx
< VIRTUAL_NUM_LIST_REGS
; lr_idx
++) {
689 ICH_LR_EL2 ich_lr_el2
=
690 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
692 if ((ich_lr_el2
.State
== ICH_LR_EL2_STATE_INVALID
) &&
693 (ich_lr_el2
.HW
|| !ich_lr_el2
.EOI
)) {
694 value
|= (1 << lr_idx
);
701 case MISCREG_ICH_LRC0
... MISCREG_ICH_LRC15
:
702 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
707 case MISCREG_ICH_LR0
... MISCREG_ICH_LR15
:
708 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
709 value
= value
& 0xffffffff;
713 case MISCREG_ICH_LR0_EL2
... MISCREG_ICH_LR15_EL2
:
716 // Virtual Machine Control Register
717 case MISCREG_ICH_VMCR
:
718 case MISCREG_ICH_VMCR_EL2
:
722 panic("Gicv3CPUInterface::readMiscReg(): unknown register %d (%s)",
723 misc_reg
, miscRegName
[misc_reg
]);
726 DPRINTF(GIC
, "Gicv3CPUInterface::readMiscReg(): register %s value %#x\n",
727 miscRegName
[misc_reg
], value
);
732 Gicv3CPUInterface::setMiscReg(int misc_reg
, RegVal val
)
734 bool do_virtual_update
= false;
735 DPRINTF(GIC
, "Gicv3CPUInterface::setMiscReg(): register %s value %#x\n",
736 miscRegName
[misc_reg
], val
);
737 bool hcr_fmo
= getHCREL2FMO();
738 bool hcr_imo
= getHCREL2IMO();
741 // Active Priorities Group 1 Registers
742 case MISCREG_ICC_AP1R0
:
743 case MISCREG_ICC_AP1R0_EL1
:
744 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
745 return isa
->setMiscRegNoEffect(MISCREG_ICV_AP1R0_EL1
, val
);
748 setBankedMiscReg(MISCREG_ICC_AP1R0_EL1
, val
);
751 case MISCREG_ICC_AP1R1
:
752 case MISCREG_ICC_AP1R1_EL1
:
754 // only implemented if supporting 6 or more bits of priority
755 case MISCREG_ICC_AP1R2
:
756 case MISCREG_ICC_AP1R2_EL1
:
758 // only implemented if supporting 7 or more bits of priority
759 case MISCREG_ICC_AP1R3
:
760 case MISCREG_ICC_AP1R3_EL1
:
761 // only implemented if supporting 7 or more bits of priority
764 // Active Priorities Group 0 Registers
765 case MISCREG_ICC_AP0R0
:
766 case MISCREG_ICC_AP0R0_EL1
:
767 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
768 return isa
->setMiscRegNoEffect(MISCREG_ICV_AP0R0_EL1
, val
);
773 case MISCREG_ICC_AP0R1
:
774 case MISCREG_ICC_AP0R1_EL1
:
776 // only implemented if supporting 6 or more bits of priority
777 case MISCREG_ICC_AP0R2
:
778 case MISCREG_ICC_AP0R2_EL1
:
780 // only implemented if supporting 7 or more bits of priority
781 case MISCREG_ICC_AP0R3
:
782 case MISCREG_ICC_AP0R3_EL1
:
783 // only implemented if supporting 7 or more bits of priority
786 // End Of Interrupt Register 0
787 case MISCREG_ICC_EOIR0
:
788 case MISCREG_ICC_EOIR0_EL1
: { // End Of Interrupt Register 0
789 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
790 return setMiscReg(MISCREG_ICV_EOIR0_EL1
, val
);
793 int int_id
= val
& 0xffffff;
795 // avoid activation for special interrupts
796 if (int_id
>= Gicv3::INTID_SECURE
&&
797 int_id
<= Gicv3::INTID_SPURIOUS
) {
801 Gicv3::GroupId group
= Gicv3::G0S
;
803 if (highestActiveGroup() != group
) {
809 if (!isEOISplitMode()) {
810 deactivateIRQ(int_id
, group
);
816 // Virtual End Of Interrupt Register 0
817 case MISCREG_ICV_EOIR0_EL1
: {
818 int int_id
= val
& 0xffffff;
820 // avoid deactivation for special interrupts
821 if (int_id
>= Gicv3::INTID_SECURE
&&
822 int_id
<= Gicv3::INTID_SPURIOUS
) {
826 uint8_t drop_prio
= virtualDropPriority();
828 if (drop_prio
== 0xff) {
832 int lr_idx
= virtualFindActive(int_id
);
835 // No LR found matching
836 virtualIncrementEOICount();
838 ICH_LR_EL2 ich_lr_el2
=
839 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
840 Gicv3::GroupId lr_group
=
841 ich_lr_el2
.Group
? Gicv3::G1NS
: Gicv3::G0S
;
842 uint8_t lr_group_prio
= ich_lr_el2
.Priority
& 0xf8;
844 if (lr_group
== Gicv3::G0S
&& lr_group_prio
== drop_prio
) {
845 //if (!virtualIsEOISplitMode())
847 virtualDeactivateIRQ(lr_idx
);
856 // End Of Interrupt Register 1
857 case MISCREG_ICC_EOIR1
:
858 case MISCREG_ICC_EOIR1_EL1
: {
859 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
860 return setMiscReg(MISCREG_ICV_EOIR1_EL1
, val
);
863 int int_id
= val
& 0xffffff;
865 // avoid deactivation for special interrupts
866 if (int_id
>= Gicv3::INTID_SECURE
&&
867 int_id
<= Gicv3::INTID_SPURIOUS
) {
871 Gicv3::GroupId group
= inSecureState() ? Gicv3::G1S
: Gicv3::G1NS
;
873 if (highestActiveGroup() == Gicv3::G0S
) {
877 if (distributor
->DS
== 0) {
878 if (highestActiveGroup() == Gicv3::G1S
&& !inSecureState()) {
880 } else if (highestActiveGroup() == Gicv3::G1NS
&&
881 !(!inSecureState() or (currEL() == EL3
))) {
888 if (!isEOISplitMode()) {
889 deactivateIRQ(int_id
, group
);
895 // Virtual End Of Interrupt Register 1
896 case MISCREG_ICV_EOIR1_EL1
: {
897 int int_id
= val
& 0xffffff;
899 // avoid deactivation for special interrupts
900 if (int_id
>= Gicv3::INTID_SECURE
&&
901 int_id
<= Gicv3::INTID_SPURIOUS
) {
905 uint8_t drop_prio
= virtualDropPriority();
907 if (drop_prio
== 0xff) {
911 int lr_idx
= virtualFindActive(int_id
);
914 // No matching LR found
915 virtualIncrementEOICount();
917 ICH_LR_EL2 ich_lr_el2
=
918 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
919 Gicv3::GroupId lr_group
=
920 ich_lr_el2
.Group
? Gicv3::G1NS
: Gicv3::G0S
;
921 uint8_t lr_group_prio
= ich_lr_el2
.Priority
& 0xf8;
923 if (lr_group
== Gicv3::G1NS
&& lr_group_prio
== drop_prio
) {
924 if (!virtualIsEOISplitMode()) {
925 virtualDeactivateIRQ(lr_idx
);
934 // Deactivate Interrupt Register
935 case MISCREG_ICC_DIR
:
936 case MISCREG_ICC_DIR_EL1
: {
937 if ((currEL() == EL1
) && !inSecureState() &&
938 (hcr_imo
|| hcr_fmo
)) {
939 return setMiscReg(MISCREG_ICV_DIR_EL1
, val
);
942 int int_id
= val
& 0xffffff;
944 // The following checks are as per spec pseudocode
945 // aarch64/support/ICC_DIR_EL1
947 // Check for spurious ID
948 if (int_id
>= Gicv3::INTID_SECURE
) {
952 // EOI mode is not set, so don't deactivate
953 if (!isEOISplitMode()) {
957 Gicv3::GroupId group
=
958 int_id
>= 32 ? distributor
->getIntGroup(int_id
) :
959 redistributor
->getIntGroup(int_id
);
960 bool irq_is_grp0
= group
== Gicv3::G0S
;
961 bool single_sec_state
= distributor
->DS
;
962 bool irq_is_secure
= !single_sec_state
&& (group
!= Gicv3::G1NS
);
963 SCR scr_el3
= isa
->readMiscRegNoEffect(MISCREG_SCR_EL3
);
964 bool route_fiq_to_el3
= scr_el3
.fiq
;
965 bool route_irq_to_el3
= scr_el3
.irq
;
966 bool route_fiq_to_el2
= hcr_fmo
;
967 bool route_irq_to_el2
= hcr_imo
;
974 if (single_sec_state
&& irq_is_grp0
&& !route_fiq_to_el3
) {
978 if (!irq_is_secure
&& !irq_is_grp0
&& !route_irq_to_el3
) {
985 if (!isSecureBelowEL3()) {
986 if (single_sec_state
&& irq_is_grp0
&&
987 !route_fiq_to_el3
&& !route_fiq_to_el2
) {
991 if (!irq_is_secure
&& !irq_is_grp0
&&
992 !route_irq_to_el3
&& !route_irq_to_el2
) {
996 if (irq_is_grp0
&& !route_fiq_to_el3
) {
1001 (!irq_is_secure
|| !single_sec_state
) &&
1002 !route_irq_to_el3
) {
1013 deactivateIRQ(int_id
, group
);
1017 // Deactivate Virtual Interrupt Register
1018 case MISCREG_ICV_DIR_EL1
: {
1019 int int_id
= val
& 0xffffff;
1021 // avoid deactivation for special interrupts
1022 if (int_id
>= Gicv3::INTID_SECURE
&&
1023 int_id
<= Gicv3::INTID_SPURIOUS
) {
1027 if (!virtualIsEOISplitMode()) {
1031 int lr_idx
= virtualFindActive(int_id
);
1034 // No matching LR found
1035 virtualIncrementEOICount();
1037 virtualDeactivateIRQ(lr_idx
);
1044 // Binary Point Register 0
1045 case MISCREG_ICC_BPR0
:
1046 case MISCREG_ICC_BPR0_EL1
: {
1047 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
1048 return setMiscReg(MISCREG_ICV_BPR0_EL1
, val
);
1052 // Binary Point Register 1
1053 case MISCREG_ICC_BPR1
:
1054 case MISCREG_ICC_BPR1_EL1
: {
1055 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
1056 return setMiscReg(MISCREG_ICV_BPR1_EL1
, val
);
1061 if (isSecureBelowEL3()) {
1062 // group == Gicv3::G1S
1063 ICC_CTLR_EL1 icc_ctlr_el1_s
=
1064 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S
);
1066 val
= val
> GIC_MIN_BPR
? val
: GIC_MIN_BPR
;
1067 if (haveEL(EL3
) && !isEL3OrMon() && icc_ctlr_el1_s
.CBPR
) {
1068 isa
->setMiscRegNoEffect(MISCREG_ICC_BPR0_EL1
, val
);
1070 isa
->setMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_S
, val
);
1074 // group == Gicv3::G1NS
1075 ICC_CTLR_EL1 icc_ctlr_el1_ns
=
1076 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS
);
1078 val
= val
> GIC_MIN_BPR_NS
? val
: GIC_MIN_BPR_NS
;
1079 if (haveEL(EL3
) && !isEL3OrMon() && icc_ctlr_el1_ns
.CBPR
) {
1080 // Non secure writes from EL1 and EL2 are ignored
1082 isa
->setMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_NS
, val
);
1090 // Virtual Binary Point Register 0
1091 case MISCREG_ICV_BPR0_EL1
:
1092 // Virtual Binary Point Register 1
1093 case MISCREG_ICV_BPR1_EL1
: {
1094 Gicv3::GroupId group
=
1095 misc_reg
== MISCREG_ICV_BPR0_EL1
? Gicv3::G0S
: Gicv3::G1NS
;
1096 ICH_VMCR_EL2 ich_vmcr_el2
=
1097 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
1099 if ((group
== Gicv3::G1NS
) && ich_vmcr_el2
.VCBPR
) {
1100 // BPR0 + 1 saturated to 7, WI
1104 uint8_t min_VPBR
= 7 - VIRTUAL_PREEMPTION_BITS
;
1106 if (group
!= Gicv3::G0S
) {
1110 if (val
< min_VPBR
) {
1114 if (group
== Gicv3::G0S
) {
1115 ich_vmcr_el2
.VBPR0
= val
;
1117 ich_vmcr_el2
.VBPR1
= val
;
1120 isa
->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
, ich_vmcr_el2
);
1121 do_virtual_update
= true;
1125 // Control Register EL1
1126 case MISCREG_ICC_CTLR
:
1127 case MISCREG_ICC_CTLR_EL1
: {
1128 if ((currEL() == EL1
) && !inSecureState() && (hcr_imo
|| hcr_fmo
)) {
1129 return setMiscReg(MISCREG_ICV_CTLR_EL1
, val
);
1140 ICC_CTLR_EL1 requested_icc_ctlr_el1
= val
;
1141 ICC_CTLR_EL1 icc_ctlr_el1
=
1142 readBankedMiscReg(MISCREG_ICC_CTLR_EL1
);
1144 ICC_CTLR_EL3 icc_ctlr_el3
=
1145 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3
);
1147 // The following could be refactored but it is following
1148 // spec description section 9.2.6 point by point.
1152 // PMHE is alias of ICC_CTLR_EL3.PMHE
1154 if (distributor
->DS
== 0) {
1156 } else if (distributor
->DS
== 1) {
1158 icc_ctlr_el1
.PMHE
= requested_icc_ctlr_el1
.PMHE
;
1159 icc_ctlr_el3
.PMHE
= icc_ctlr_el1
.PMHE
;
1162 // PMHE is RW (by implementation choice)
1163 icc_ctlr_el1
.PMHE
= requested_icc_ctlr_el1
.PMHE
;
1167 icc_ctlr_el1
.EOImode
= requested_icc_ctlr_el1
.EOImode
;
1169 if (inSecureState()) {
1170 // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1S
1171 icc_ctlr_el3
.EOImode_EL1S
= icc_ctlr_el1
.EOImode
;
1173 // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1NS
1174 icc_ctlr_el3
.EOImode_EL1NS
= icc_ctlr_el1
.EOImode
;
1179 // CBPR is alias of ICC_CTLR_EL3.CBPR_EL1{S,NS}
1181 if (distributor
->DS
== 0) {
1185 icc_ctlr_el1
.CBPR
= requested_icc_ctlr_el1
.CBPR
;
1187 if (inSecureState()) {
1188 icc_ctlr_el3
.CBPR_EL1S
= icc_ctlr_el1
.CBPR
;
1190 icc_ctlr_el3
.CBPR_EL1NS
= icc_ctlr_el1
.CBPR
;
1195 icc_ctlr_el1
.CBPR
= requested_icc_ctlr_el1
.CBPR
;
1198 isa
->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL3
, icc_ctlr_el3
);
1200 setBankedMiscReg(MISCREG_ICC_CTLR_EL1
, icc_ctlr_el1
);
1204 // Virtual Control Register
1205 case MISCREG_ICV_CTLR_EL1
: {
1206 ICV_CTLR_EL1 requested_icv_ctlr_el1
= val
;
1207 ICV_CTLR_EL1 icv_ctlr_el1
=
1208 isa
->readMiscRegNoEffect(MISCREG_ICV_CTLR_EL1
);
1209 icv_ctlr_el1
.EOImode
= requested_icv_ctlr_el1
.EOImode
;
1210 icv_ctlr_el1
.CBPR
= requested_icv_ctlr_el1
.CBPR
;
1214 // ICV_CTLR_EL1.CBPR aliases ICH_VMCR_EL2.VCBPR.
1215 // ICV_CTLR_EL1.EOImode aliases ICH_VMCR_EL2.VEOIM.
1216 ICH_VMCR_EL2 ich_vmcr_el2
=
1217 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
1218 ich_vmcr_el2
.VCBPR
= icv_ctlr_el1
.CBPR
;
1219 ich_vmcr_el2
.VEOIM
= icv_ctlr_el1
.EOImode
;
1220 isa
->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
, ich_vmcr_el2
);
1224 // Control Register EL3
1225 case MISCREG_ICC_MCTLR
:
1226 case MISCREG_ICC_CTLR_EL3
: {
1235 * PMHE is RAO/WI, priority-based routing is always used.
1237 ICC_CTLR_EL3 requested_icc_ctlr_el3
= val
;
1242 ICC_CTLR_EL1 icc_ctlr_el1_s
=
1243 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S
);
1244 ICC_CTLR_EL1 icc_ctlr_el1_ns
=
1245 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS
);
1247 // ICC_CTLR_EL1(NS).EOImode is an alias of
1248 // ICC_CTLR_EL3.EOImode_EL1NS
1249 icc_ctlr_el1_ns
.EOImode
= requested_icc_ctlr_el3
.EOImode_EL1NS
;
1250 // ICC_CTLR_EL1(S).EOImode is an alias of
1251 // ICC_CTLR_EL3.EOImode_EL1S
1252 icc_ctlr_el1_s
.EOImode
= requested_icc_ctlr_el3
.EOImode_EL1S
;
1253 // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS
1254 icc_ctlr_el1_ns
.CBPR
= requested_icc_ctlr_el3
.CBPR_EL1NS
;
1255 // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S
1256 icc_ctlr_el1_s
.CBPR
= requested_icc_ctlr_el3
.CBPR_EL1S
;
1258 isa
->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S
, icc_ctlr_el1_s
);
1259 isa
->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS
,
1263 ICC_CTLR_EL3 icc_ctlr_el3
=
1264 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3
);
1266 icc_ctlr_el3
.RM
= requested_icc_ctlr_el3
.RM
;
1267 icc_ctlr_el3
.EOImode_EL1NS
= requested_icc_ctlr_el3
.EOImode_EL1NS
;
1268 icc_ctlr_el3
.EOImode_EL1S
= requested_icc_ctlr_el3
.EOImode_EL1S
;
1269 icc_ctlr_el3
.EOImode_EL3
= requested_icc_ctlr_el3
.EOImode_EL3
;
1270 icc_ctlr_el3
.CBPR_EL1NS
= requested_icc_ctlr_el3
.CBPR_EL1NS
;
1271 icc_ctlr_el3
.CBPR_EL1S
= requested_icc_ctlr_el3
.CBPR_EL1S
;
1277 // Priority Mask Register
1278 case MISCREG_ICC_PMR
:
1279 case MISCREG_ICC_PMR_EL1
: {
1280 if ((currEL() == EL1
) && !inSecureState() && (hcr_imo
|| hcr_fmo
)) {
1281 return setMiscReg(MISCREG_ICV_PMR_EL1
, val
);
1285 SCR scr_el3
= isa
->readMiscRegNoEffect(MISCREG_SCR_EL3
);
1287 if (haveEL(EL3
) && !inSecureState() && (scr_el3
.fiq
)) {
1288 // Spec section 4.8.1
1289 // For Non-secure access to ICC_PMR_EL1 SCR_EL3.FIQ == 1:
1290 RegVal old_icc_pmr_el1
=
1291 isa
->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1
);
1293 if (!(old_icc_pmr_el1
& 0x80)) {
1294 // If the current priority mask value is in the range of
1295 // 0x00-0x7F then WI
1299 // If the current priority mask value is in the range of
1300 // 0x80-0xFF then a write access to ICC_PMR_EL1 succeeds,
1301 // based on the Non-secure read of the priority mask value
1302 // written to the register.
1304 val
= (val
>> 1) | 0x80;
1307 val
&= ~0U << (8 - PRIORITY_BITS
);
1311 case MISCREG_ICV_PMR_EL1
: { // Priority Mask Register
1312 ICH_VMCR_EL2 ich_vmcr_el2
=
1313 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
1314 ich_vmcr_el2
.VPMR
= val
& 0xff;
1316 isa
->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
, ich_vmcr_el2
);
1321 // Interrupt Group 0 Enable Register EL1
1322 case MISCREG_ICC_IGRPEN0
:
1323 case MISCREG_ICC_IGRPEN0_EL1
: {
1324 if ((currEL() == EL1
) && !inSecureState() && hcr_fmo
) {
1325 return setMiscReg(MISCREG_ICV_IGRPEN0_EL1
, val
);
1328 isa
->setMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1
, val
);
1329 updateDistributor();
1333 // Virtual Interrupt Group 0 Enable register
1334 case MISCREG_ICV_IGRPEN0_EL1
: {
1335 bool enable
= val
& 0x1;
1336 ICH_VMCR_EL2 ich_vmcr_el2
=
1337 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
1338 ich_vmcr_el2
.VENG0
= enable
;
1339 isa
->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
, ich_vmcr_el2
);
1344 // Interrupt Group 1 Enable register EL1
1345 case MISCREG_ICC_IGRPEN1
:
1346 case MISCREG_ICC_IGRPEN1_EL1
: {
1347 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
1348 return setMiscReg(MISCREG_ICV_IGRPEN1_EL1
, val
);
1351 setBankedMiscReg(MISCREG_ICC_IGRPEN1_EL1
, val
);
1352 updateDistributor();
1356 // Virtual Interrupt Group 1 Enable register
1357 case MISCREG_ICV_IGRPEN1_EL1
: {
1358 bool enable
= val
& 0x1;
1359 ICH_VMCR_EL2 ich_vmcr_el2
=
1360 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
1361 ich_vmcr_el2
.VENG1
= enable
;
1362 isa
->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
, ich_vmcr_el2
);
1367 // Interrupt Group 1 Enable register
1368 case MISCREG_ICC_MGRPEN1
:
1369 case MISCREG_ICC_IGRPEN1_EL3
: {
1370 ICC_IGRPEN1_EL3 icc_igrpen1_el3
= val
;
1372 isa
->setMiscRegNoEffect(
1373 MISCREG_ICC_IGRPEN1_EL1_S
, icc_igrpen1_el3
.EnableGrp1S
);
1374 isa
->setMiscRegNoEffect(
1375 MISCREG_ICC_IGRPEN1_EL1_NS
, icc_igrpen1_el3
.EnableGrp1NS
);
1376 updateDistributor();
1380 // Software Generated Interrupt Group 0 Register
1381 case MISCREG_ICC_SGI0R
:
1382 case MISCREG_ICC_SGI0R_EL1
:
1383 generateSGI(val
, Gicv3::G0S
);
1386 // Software Generated Interrupt Group 1 Register
1387 case MISCREG_ICC_SGI1R
:
1388 case MISCREG_ICC_SGI1R_EL1
: {
1389 Gicv3::GroupId group
= inSecureState() ? Gicv3::G1S
: Gicv3::G1NS
;
1391 generateSGI(val
, group
);
1395 // Alias Software Generated Interrupt Group 1 Register
1396 case MISCREG_ICC_ASGI1R
:
1397 case MISCREG_ICC_ASGI1R_EL1
: {
1398 Gicv3::GroupId group
= inSecureState() ? Gicv3::G1NS
: Gicv3::G1S
;
1400 generateSGI(val
, group
);
1404 // System Register Enable Register EL1
1405 case MISCREG_ICC_SRE
:
1406 case MISCREG_ICC_SRE_EL1
:
1407 // System Register Enable Register EL2
1408 case MISCREG_ICC_HSRE
:
1409 case MISCREG_ICC_SRE_EL2
:
1410 // System Register Enable Register EL3
1411 case MISCREG_ICC_MSRE
:
1412 case MISCREG_ICC_SRE_EL3
:
1413 // All bits are RAO/WI
1416 // Hyp Control Register
1417 case MISCREG_ICH_HCR
:
1418 case MISCREG_ICH_HCR_EL2
: {
1419 ICH_HCR_EL2 requested_ich_hcr_el2
= val
;
1420 ICH_HCR_EL2 ich_hcr_el2
=
1421 isa
->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2
);
1423 if (requested_ich_hcr_el2
.EOIcount
>= ich_hcr_el2
.EOIcount
)
1425 // EOIcount - Permitted behaviors are:
1426 // - Increment EOIcount.
1427 // - Leave EOIcount unchanged.
1428 ich_hcr_el2
.EOIcount
= requested_ich_hcr_el2
.EOIcount
;
1431 ich_hcr_el2
.TDIR
= requested_ich_hcr_el2
.TDIR
;
1432 ich_hcr_el2
.TSEI
= requested_ich_hcr_el2
.TSEI
;
1433 ich_hcr_el2
.TALL1
= requested_ich_hcr_el2
.TALL1
;;
1434 ich_hcr_el2
.TALL0
= requested_ich_hcr_el2
.TALL0
;;
1435 ich_hcr_el2
.TC
= requested_ich_hcr_el2
.TC
;
1436 ich_hcr_el2
.VGrp1DIE
= requested_ich_hcr_el2
.VGrp1DIE
;
1437 ich_hcr_el2
.VGrp1EIE
= requested_ich_hcr_el2
.VGrp1EIE
;
1438 ich_hcr_el2
.VGrp0DIE
= requested_ich_hcr_el2
.VGrp0DIE
;
1439 ich_hcr_el2
.VGrp0EIE
= requested_ich_hcr_el2
.VGrp0EIE
;
1440 ich_hcr_el2
.NPIE
= requested_ich_hcr_el2
.NPIE
;
1441 ich_hcr_el2
.LRENPIE
= requested_ich_hcr_el2
.LRENPIE
;
1442 ich_hcr_el2
.UIE
= requested_ich_hcr_el2
.UIE
;
1443 ich_hcr_el2
.En
= requested_ich_hcr_el2
.En
;
1445 do_virtual_update
= true;
1450 case MISCREG_ICH_LRC0
... MISCREG_ICH_LRC15
: {
1451 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
1452 ICH_LRC requested_ich_lrc
= val
;
1453 ICH_LRC ich_lrc
= isa
->readMiscRegNoEffect(misc_reg
);
1455 ich_lrc
.State
= requested_ich_lrc
.State
;
1456 ich_lrc
.HW
= requested_ich_lrc
.HW
;
1457 ich_lrc
.Group
= requested_ich_lrc
.Group
;
1459 // Priority, bits [23:16]
1460 // At least five bits must be implemented.
1461 // Unimplemented bits are RES0 and start from bit[16] up to bit[18].
1462 // We implement 5 bits.
1463 ich_lrc
.Priority
= (requested_ich_lrc
.Priority
& 0xf8) |
1464 (ich_lrc
.Priority
& 0x07);
1466 // pINTID, bits [12:0]
1467 // When ICH_LR<n>.HW is 0 this field has the following meaning:
1468 // - Bits[12:10] : RES0.
1470 // - Bits[8:0] : RES0.
1471 // When ICH_LR<n>.HW is 1:
1472 // - This field is only required to implement enough bits to hold a
1473 // valid value for the implemented INTID size. Any unused higher
1474 // order bits are RES0.
1475 if (requested_ich_lrc
.HW
== 0) {
1476 ich_lrc
.EOI
= requested_ich_lrc
.EOI
;
1478 ich_lrc
.pINTID
= requested_ich_lrc
.pINTID
;
1482 do_virtual_update
= true;
1487 case MISCREG_ICH_LR0
... MISCREG_ICH_LR15
: {
1488 // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
1489 RegVal old_val
= isa
->readMiscRegNoEffect(misc_reg
);
1490 val
= (old_val
& 0xffffffff00000000) | (val
& 0xffffffff);
1491 do_virtual_update
= true;
1496 case MISCREG_ICH_LR0_EL2
... MISCREG_ICH_LR15_EL2
: { // AArch64
1497 ICH_LR_EL2 requested_ich_lr_el2
= val
;
1498 ICH_LR_EL2 ich_lr_el2
= isa
->readMiscRegNoEffect(misc_reg
);
1500 ich_lr_el2
.State
= requested_ich_lr_el2
.State
;
1501 ich_lr_el2
.HW
= requested_ich_lr_el2
.HW
;
1502 ich_lr_el2
.Group
= requested_ich_lr_el2
.Group
;
1504 // Priority, bits [55:48]
1505 // At least five bits must be implemented.
1506 // Unimplemented bits are RES0 and start from bit[48] up to bit[50].
1507 // We implement 5 bits.
1508 ich_lr_el2
.Priority
= (requested_ich_lr_el2
.Priority
& 0xf8) |
1509 (ich_lr_el2
.Priority
& 0x07);
1511 // pINTID, bits [44:32]
1512 // When ICH_LR<n>_EL2.HW is 0 this field has the following meaning:
1513 // - Bits[44:42] : RES0.
1515 // - Bits[40:32] : RES0.
1516 // When ICH_LR<n>_EL2.HW is 1:
1517 // - This field is only required to implement enough bits to hold a
1518 // valid value for the implemented INTID size. Any unused higher
1519 // order bits are RES0.
1520 if (requested_ich_lr_el2
.HW
== 0) {
1521 ich_lr_el2
.EOI
= requested_ich_lr_el2
.EOI
;
1523 ich_lr_el2
.pINTID
= requested_ich_lr_el2
.pINTID
;
1526 // vINTID, bits [31:0]
1527 // It is IMPLEMENTATION DEFINED how many bits are implemented,
1528 // though at least 16 bits must be implemented.
1529 // Unimplemented bits are RES0.
1530 ich_lr_el2
.vINTID
= requested_ich_lr_el2
.vINTID
;
1533 do_virtual_update
= true;
1537 // Virtual Machine Control Register
1538 case MISCREG_ICH_VMCR
:
1539 case MISCREG_ICH_VMCR_EL2
: {
1540 ICH_VMCR_EL2 requested_ich_vmcr_el2
= val
;
1541 ICH_VMCR_EL2 ich_vmcr_el2
=
1542 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
1543 ich_vmcr_el2
.VPMR
= requested_ich_vmcr_el2
.VPMR
;
1544 uint8_t min_vpr0
= 7 - VIRTUAL_PREEMPTION_BITS
;
1546 if (requested_ich_vmcr_el2
.VBPR0
< min_vpr0
) {
1547 ich_vmcr_el2
.VBPR0
= min_vpr0
;
1549 ich_vmcr_el2
.VBPR0
= requested_ich_vmcr_el2
.VBPR0
;
1552 uint8_t min_vpr1
= min_vpr0
+ 1;
1554 if (requested_ich_vmcr_el2
.VBPR1
< min_vpr1
) {
1555 ich_vmcr_el2
.VBPR1
= min_vpr1
;
1557 ich_vmcr_el2
.VBPR1
= requested_ich_vmcr_el2
.VBPR1
;
1560 ich_vmcr_el2
.VEOIM
= requested_ich_vmcr_el2
.VEOIM
;
1561 ich_vmcr_el2
.VCBPR
= requested_ich_vmcr_el2
.VCBPR
;
1562 ich_vmcr_el2
.VENG1
= requested_ich_vmcr_el2
.VENG1
;
1563 ich_vmcr_el2
.VENG0
= requested_ich_vmcr_el2
.VENG0
;
1568 // Hyp Active Priorities Group 0 Registers
1569 case MISCREG_ICH_AP0R0
:
1570 case MISCREG_ICH_AP0R0_EL2
:
1573 // only implemented if supporting 6 or more bits of priority
1574 case MISCREG_ICH_AP0R1
:
1575 case MISCREG_ICH_AP0R1_EL2
:
1576 // only implemented if supporting 7 or more bits of priority
1577 case MISCREG_ICH_AP0R2
:
1578 case MISCREG_ICH_AP0R2_EL2
:
1579 // only implemented if supporting 7 or more bits of priority
1580 case MISCREG_ICH_AP0R3
:
1581 case MISCREG_ICH_AP0R3_EL2
:
1582 // Unimplemented registers are RAZ/WI
1585 // Hyp Active Priorities Group 1 Registers
1586 case MISCREG_ICH_AP1R0
:
1587 case MISCREG_ICH_AP1R0_EL2
:
1590 // only implemented if supporting 6 or more bits of priority
1591 case MISCREG_ICH_AP1R1
:
1592 case MISCREG_ICH_AP1R1_EL2
:
1593 // only implemented if supporting 7 or more bits of priority
1594 case MISCREG_ICH_AP1R2
:
1595 case MISCREG_ICH_AP1R2_EL2
:
1596 // only implemented if supporting 7 or more bits of priority
1597 case MISCREG_ICH_AP1R3
:
1598 case MISCREG_ICH_AP1R3_EL2
:
1599 // Unimplemented registers are RAZ/WI
1603 panic("Gicv3CPUInterface::setMiscReg(): unknown register %d (%s)",
1604 misc_reg
, miscRegName
[misc_reg
]);
1607 isa
->setMiscRegNoEffect(misc_reg
, val
);
1609 if (do_virtual_update
) {
1615 Gicv3CPUInterface::readBankedMiscReg(MiscRegIndex misc_reg
) const
1617 return isa
->readMiscRegNoEffect(
1618 isa
->snsBankedIndex64(misc_reg
, !isSecureBelowEL3()));
1622 Gicv3CPUInterface::setBankedMiscReg(MiscRegIndex misc_reg
, RegVal val
) const
1624 isa
->setMiscRegNoEffect(
1625 isa
->snsBankedIndex64(misc_reg
, !isSecureBelowEL3()), val
);
1629 Gicv3CPUInterface::virtualFindActive(uint32_t int_id
) const
1631 for (uint32_t lr_idx
= 0; lr_idx
< VIRTUAL_NUM_LIST_REGS
; lr_idx
++) {
1632 ICH_LR_EL2 ich_lr_el2
=
1633 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
1635 if (((ich_lr_el2
.State
== ICH_LR_EL2_STATE_ACTIVE
) ||
1636 (ich_lr_el2
.State
== ICH_LR_EL2_STATE_ACTIVE_PENDING
)) &&
1637 (ich_lr_el2
.vINTID
== int_id
)) {
1646 Gicv3CPUInterface::getHPPIR0() const
1648 if (hppi
.prio
== 0xff || !groupEnabled(hppi
.group
)) {
1649 return Gicv3::INTID_SPURIOUS
;
1652 bool irq_is_secure
= !distributor
->DS
&& hppi
.group
!= Gicv3::G1NS
;
1654 if ((hppi
.group
!= Gicv3::G0S
) && isEL3OrMon()) {
1655 // interrupt for the other state pending
1656 return irq_is_secure
? Gicv3::INTID_SECURE
: Gicv3::INTID_NONSECURE
;
1659 if ((hppi
.group
!= Gicv3::G0S
)) { // && !isEL3OrMon())
1660 return Gicv3::INTID_SPURIOUS
;
1663 if (irq_is_secure
&& !inSecureState()) {
1664 // Secure interrupts not visible in Non-secure
1665 return Gicv3::INTID_SPURIOUS
;
1672 Gicv3CPUInterface::getHPPIR1() const
1674 if (hppi
.prio
== 0xff || !groupEnabled(hppi
.group
)) {
1675 return Gicv3::INTID_SPURIOUS
;
1678 ICC_CTLR_EL3 icc_ctlr_el3
= isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3
);
1679 if ((currEL() == EL3
) && icc_ctlr_el3
.RM
) {
1680 if (hppi
.group
== Gicv3::G0S
) {
1681 return Gicv3::INTID_SECURE
;
1682 } else if (hppi
.group
== Gicv3::G1NS
) {
1683 return Gicv3::INTID_NONSECURE
;
1687 if (hppi
.group
== Gicv3::G0S
) {
1688 return Gicv3::INTID_SPURIOUS
;
1691 bool irq_is_secure
= (distributor
->DS
== 0) && (hppi
.group
!= Gicv3::G1NS
);
1693 if (irq_is_secure
) {
1694 if (!inSecureState()) {
1695 // Secure interrupts not visible in Non-secure
1696 return Gicv3::INTID_SPURIOUS
;
1698 } else if (!isEL3OrMon() && inSecureState()) {
1699 // Group 1 non-secure interrupts not visible in Secure EL1
1700 return Gicv3::INTID_SPURIOUS
;
1707 Gicv3CPUInterface::dropPriority(Gicv3::GroupId group
)
1709 int apr_misc_reg
= 0;
1713 apr_misc_reg
= MISCREG_ICC_AP0R0_EL1
;
1716 apr_misc_reg
= MISCREG_ICC_AP1R0_EL1_S
;
1719 apr_misc_reg
= MISCREG_ICC_AP1R0_EL1_NS
;
1722 panic("Invalid Gicv3::GroupId");
1725 RegVal apr
= isa
->readMiscRegNoEffect(apr_misc_reg
);
1729 isa
->setMiscRegNoEffect(apr_misc_reg
, apr
);
1736 Gicv3CPUInterface::virtualDropPriority()
1738 int apr_max
= 1 << (VIRTUAL_PREEMPTION_BITS
- 5);
1740 for (int i
= 0; i
< apr_max
; i
++) {
1741 RegVal vapr0
= isa
->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2
+ i
);
1742 RegVal vapr1
= isa
->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2
+ i
);
1744 if (!vapr0
&& !vapr1
) {
1748 int vapr0_count
= ctz32(vapr0
);
1749 int vapr1_count
= ctz32(vapr1
);
1751 if (vapr0_count
<= vapr1_count
) {
1753 isa
->setMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2
+ i
, vapr0
);
1754 return (vapr0_count
+ i
* 32) << (GIC_MIN_VBPR
+ 1);
1757 isa
->setMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2
+ i
, vapr1
);
1758 return (vapr1_count
+ i
* 32) << (GIC_MIN_VBPR
+ 1);
1766 Gicv3CPUInterface::generateSGI(RegVal val
, Gicv3::GroupId group
)
1768 uint8_t aff3
= bits(val
, 55, 48);
1769 uint8_t aff2
= bits(val
, 39, 32);
1770 uint8_t aff1
= bits(val
, 23, 16);;
1771 uint16_t target_list
= bits(val
, 15, 0);
1772 uint32_t int_id
= bits(val
, 27, 24);
1773 bool irm
= bits(val
, 40, 40);
1774 uint8_t rs
= bits(val
, 47, 44);
1776 bool ns
= !inSecureState();
1778 for (int i
= 0; i
< gic
->getSystem()->numContexts(); i
++) {
1779 Gicv3Redistributor
* redistributor_i
=
1780 gic
->getRedistributor(i
);
1781 uint32_t affinity_i
= redistributor_i
->getAffinity();
1784 // Interrupts routed to all PEs in the system,
1786 if (affinity_i
== redistributor
->getAffinity()) {
1790 // Interrupts routed to the PEs specified by
1791 // Aff3.Aff2.Aff1.<target list>
1792 if ((affinity_i
>> 8) !=
1793 ((aff3
<< 16) | (aff2
<< 8) | (aff1
<< 0))) {
1797 uint8_t aff0_i
= bits(affinity_i
, 7, 0);
1799 if (!(aff0_i
>= rs
* 16 && aff0_i
< (rs
+ 1) * 16 &&
1800 ((0x1 << (aff0_i
- rs
* 16)) & target_list
))) {
1805 redistributor_i
->sendSGI(int_id
, group
, ns
);
1810 Gicv3CPUInterface::activateIRQ(uint32_t int_id
, Gicv3::GroupId group
)
1812 // Update active priority registers.
1813 uint32_t prio
= hppi
.prio
& 0xf8;
1814 int apr_bit
= prio
>> (8 - PRIORITY_BITS
);
1815 int reg_bit
= apr_bit
% 32;
1820 apr_idx
= MISCREG_ICC_AP0R0_EL1
;
1823 apr_idx
= MISCREG_ICC_AP1R0_EL1_S
;
1826 apr_idx
= MISCREG_ICC_AP1R0_EL1_NS
;
1829 panic("Invalid Gicv3::GroupId");
1832 RegVal apr
= isa
->readMiscRegNoEffect(apr_idx
);
1833 apr
|= (1 << reg_bit
);
1834 isa
->setMiscRegNoEffect(apr_idx
, apr
);
1836 // Move interrupt state from pending to active.
1837 if (int_id
< Gicv3::SGI_MAX
+ Gicv3::PPI_MAX
) {
1838 // SGI or PPI, redistributor
1839 redistributor
->activateIRQ(int_id
);
1840 } else if (int_id
< Gicv3::INTID_SECURE
) {
1842 distributor
->activateIRQ(int_id
);
1843 } else if (int_id
>= Gicv3Redistributor::SMALLEST_LPI_ID
) {
1844 // LPI, Redistributor
1845 redistributor
->setClrLPI(int_id
, false);
1848 // By setting the priority to 0xff we are effectively
1849 // making the int_id not pending anymore at the cpu
1852 updateDistributor();
1856 Gicv3CPUInterface::virtualActivateIRQ(uint32_t lr_idx
)
1858 // Update active priority registers.
1859 ICH_LR_EL2 ich_lr_el
= isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+
1861 Gicv3::GroupId group
= ich_lr_el
.Group
? Gicv3::G1NS
: Gicv3::G0S
;
1862 uint8_t prio
= ich_lr_el
.Priority
& 0xf8;
1863 int apr_bit
= prio
>> (8 - VIRTUAL_PREEMPTION_BITS
);
1864 int reg_no
= apr_bit
/ 32;
1865 int reg_bit
= apr_bit
% 32;
1866 int apr_idx
= group
== Gicv3::G0S
?
1867 MISCREG_ICH_AP0R0_EL2
+ reg_no
: MISCREG_ICH_AP1R0_EL2
+ reg_no
;
1868 RegVal apr
= isa
->readMiscRegNoEffect(apr_idx
);
1869 apr
|= (1 << reg_bit
);
1870 isa
->setMiscRegNoEffect(apr_idx
, apr
);
1871 // Move interrupt state from pending to active.
1872 ich_lr_el
.State
= ICH_LR_EL2_STATE_ACTIVE
;
1873 isa
->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
, ich_lr_el
);
1877 Gicv3CPUInterface::deactivateIRQ(uint32_t int_id
, Gicv3::GroupId group
)
1879 if (int_id
< Gicv3::SGI_MAX
+ Gicv3::PPI_MAX
) {
1880 // SGI or PPI, redistributor
1881 redistributor
->deactivateIRQ(int_id
);
1882 } else if (int_id
< Gicv3::INTID_SECURE
) {
1884 distributor
->deactivateIRQ(int_id
);
1887 updateDistributor();
1891 Gicv3CPUInterface::virtualDeactivateIRQ(int lr_idx
)
1893 ICH_LR_EL2 ich_lr_el2
= isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+
1896 if (ich_lr_el2
.HW
) {
1897 // Deactivate the associated physical interrupt
1898 if (ich_lr_el2
.pINTID
< Gicv3::INTID_SECURE
) {
1899 Gicv3::GroupId group
= ich_lr_el2
.pINTID
>= 32 ?
1900 distributor
->getIntGroup(ich_lr_el2
.pINTID
) :
1901 redistributor
->getIntGroup(ich_lr_el2
.pINTID
);
1902 deactivateIRQ(ich_lr_el2
.pINTID
, group
);
1906 // Remove the active bit
1907 ich_lr_el2
.State
= ich_lr_el2
.State
& ~ICH_LR_EL2_STATE_ACTIVE
;
1908 isa
->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
, ich_lr_el2
);
1912 * Returns the priority group field for the current BPR value for the group.
1913 * GroupBits() Pseudocode from spec.
1916 Gicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group
)
1918 ICC_CTLR_EL1 icc_ctlr_el1_s
=
1919 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S
);
1920 ICC_CTLR_EL1 icc_ctlr_el1_ns
=
1921 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS
);
1923 if ((group
== Gicv3::G1S
&& icc_ctlr_el1_s
.CBPR
) ||
1924 (group
== Gicv3::G1NS
&& icc_ctlr_el1_ns
.CBPR
)) {
1930 if (group
== Gicv3::G0S
) {
1931 bpr
= readMiscReg(MISCREG_ICC_BPR0_EL1
) & 0x7;
1932 } else if (group
== Gicv3::G1S
) {
1933 bpr
= bpr1(Gicv3::G1S
) & 0x7;
1935 bpr
= bpr1(Gicv3::G1NS
) & 0x7;
1938 if (group
== Gicv3::G1NS
) {
1943 return ~0U << (bpr
+ 1);
1947 Gicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group
) const
1949 ICH_VMCR_EL2 ich_vmcr_el2
=
1950 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
1952 if ((group
== Gicv3::G1NS
) && ich_vmcr_el2
.VCBPR
) {
1958 if (group
== Gicv3::G0S
) {
1959 bpr
= ich_vmcr_el2
.VBPR0
;
1961 bpr
= ich_vmcr_el2
.VBPR1
;
1964 if (group
== Gicv3::G1NS
) {
1969 return ~0U << (bpr
+ 1);
1973 Gicv3CPUInterface::isEOISplitMode() const
1976 ICC_CTLR_EL3 icc_ctlr_el3
=
1977 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3
);
1978 return icc_ctlr_el3
.EOImode_EL3
;
1980 ICC_CTLR_EL1 icc_ctlr_el1
= 0;
1981 if (inSecureState())
1982 icc_ctlr_el1
= isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S
);
1984 icc_ctlr_el1
= isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS
);
1985 return icc_ctlr_el1
.EOImode
;
1990 Gicv3CPUInterface::virtualIsEOISplitMode() const
1992 ICH_VMCR_EL2 ich_vmcr_el2
= isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
1993 return ich_vmcr_el2
.VEOIM
;
1997 Gicv3CPUInterface::highestActiveGroup() const
1999 int g0_ctz
= ctz32(isa
->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1
));
2000 int gq_ctz
= ctz32(isa
->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S
));
2001 int g1nz_ctz
= ctz32(isa
->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS
));
2003 if (g1nz_ctz
< g0_ctz
&& g1nz_ctz
< gq_ctz
) {
2007 if (gq_ctz
< g0_ctz
) {
2019 Gicv3CPUInterface::updateDistributor()
2021 distributor
->update();
2025 Gicv3CPUInterface::update()
2027 bool signal_IRQ
= false;
2028 bool signal_FIQ
= false;
2030 if (hppi
.group
== Gicv3::G1S
&& !haveEL(EL3
)) {
2032 * Secure enabled GIC sending a G1S IRQ to a secure disabled
2033 * CPU -> send G0 IRQ
2035 hppi
.group
= Gicv3::G0S
;
2038 if (hppiCanPreempt()) {
2039 ArmISA::InterruptTypes int_type
= intSignalType(hppi
.group
);
2040 DPRINTF(GIC
, "Gicv3CPUInterface::update(): "
2041 "posting int as %d!\n", int_type
);
2042 int_type
== ArmISA::INT_IRQ
? signal_IRQ
= true : signal_FIQ
= true;
2046 gic
->postInt(cpuId
, ArmISA::INT_IRQ
);
2048 gic
->deassertInt(cpuId
, ArmISA::INT_IRQ
);
2052 gic
->postInt(cpuId
, ArmISA::INT_FIQ
);
2054 gic
->deassertInt(cpuId
, ArmISA::INT_FIQ
);
2059 Gicv3CPUInterface::virtualUpdate()
2061 bool signal_IRQ
= false;
2062 bool signal_FIQ
= false;
2063 int lr_idx
= getHPPVILR();
2066 ICH_LR_EL2 ich_lr_el2
=
2067 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
2069 if (hppviCanPreempt(lr_idx
)) {
2070 if (ich_lr_el2
.Group
) {
2078 ICH_HCR_EL2 ich_hcr_el2
= isa
->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2
);
2080 if (ich_hcr_el2
.En
) {
2081 if (maintenanceInterruptStatus()) {
2082 maintenanceInterrupt
->raise();
2087 DPRINTF(GIC
, "Gicv3CPUInterface::virtualUpdate(): "
2088 "posting int as %d!\n", ArmISA::INT_VIRT_IRQ
);
2089 gic
->postInt(cpuId
, ArmISA::INT_VIRT_IRQ
);
2091 gic
->deassertInt(cpuId
, ArmISA::INT_VIRT_IRQ
);
2095 DPRINTF(GIC
, "Gicv3CPUInterface::virtualUpdate(): "
2096 "posting int as %d!\n", ArmISA::INT_VIRT_FIQ
);
2097 gic
->postInt(cpuId
, ArmISA::INT_VIRT_FIQ
);
2099 gic
->deassertInt(cpuId
, ArmISA::INT_VIRT_FIQ
);
2103 // Returns the index of the LR with the HPPI
2105 Gicv3CPUInterface::getHPPVILR() const
2108 ICH_VMCR_EL2 ich_vmcr_el2
= isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
2110 if (!ich_vmcr_el2
.VENG0
&& !ich_vmcr_el2
.VENG1
) {
2111 // VG0 and VG1 disabled...
2115 uint8_t highest_prio
= 0xff;
2117 for (int i
= 0; i
< 16; i
++) {
2118 ICH_LR_EL2 ich_lr_el2
=
2119 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ i
);
2121 if (ich_lr_el2
.State
!= Gicv3::INT_PENDING
) {
2125 if (ich_lr_el2
.Group
) {
2127 if (!ich_vmcr_el2
.VENG1
) {
2132 if (!ich_vmcr_el2
.VENG0
) {
2137 uint8_t prio
= ich_lr_el2
.Priority
;
2139 if (prio
< highest_prio
) {
2140 highest_prio
= prio
;
2149 Gicv3CPUInterface::hppviCanPreempt(int lr_idx
) const
2151 ICH_HCR_EL2 ich_hcr_el2
= isa
->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2
);
2152 if (!ich_hcr_el2
.En
) {
2153 // virtual interface is disabled
2157 ICH_LR_EL2 ich_lr_el2
=
2158 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
2159 uint8_t prio
= ich_lr_el2
.Priority
;
2161 bits(isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
), 31, 24);
2168 uint8_t rprio
= virtualHighestActivePriority();
2170 if (rprio
== 0xff) {
2174 Gicv3::GroupId group
= ich_lr_el2
.Group
? Gicv3::G1NS
: Gicv3::G0S
;
2175 uint32_t prio_mask
= virtualGroupPriorityMask(group
);
2177 if ((prio
& prio_mask
) < (rprio
& prio_mask
)) {
2185 Gicv3CPUInterface::virtualHighestActivePriority() const
2187 uint8_t num_aprs
= 1 << (VIRTUAL_PRIORITY_BITS
- 5);
2189 for (int i
= 0; i
< num_aprs
; i
++) {
2191 isa
->readMiscRegNoEffect(MISCREG_ICH_AP0R0_EL2
+ i
) |
2192 isa
->readMiscRegNoEffect(MISCREG_ICH_AP1R0_EL2
+ i
);
2198 return (i
* 32 + ctz32(vapr
)) << (GIC_MIN_VBPR
+ 1);
2201 // no active interrups, return idle priority
2206 Gicv3CPUInterface::virtualIncrementEOICount()
2208 // Increment the EOICOUNT field in ICH_HCR_EL2
2209 RegVal ich_hcr_el2
= isa
->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2
);
2210 uint32_t EOI_cout
= bits(ich_hcr_el2
, 31, 27);
2212 ich_hcr_el2
= insertBits(ich_hcr_el2
, 31, 27, EOI_cout
);
2213 isa
->setMiscRegNoEffect(MISCREG_ICH_HCR_EL2
, ich_hcr_el2
);
2216 // spec section 4.6.2
2217 ArmISA::InterruptTypes
2218 Gicv3CPUInterface::intSignalType(Gicv3::GroupId group
) const
2220 bool is_fiq
= false;
2228 is_fiq
= (distributor
->DS
== 0) &&
2229 (!inSecureState() || ((currEL() == EL3
) && isAA64()));
2233 is_fiq
= (distributor
->DS
== 0) && inSecureState();
2237 panic("Gicv3CPUInterface::intSignalType(): invalid group!");
2241 return ArmISA::INT_FIQ
;
2243 return ArmISA::INT_IRQ
;
2248 Gicv3CPUInterface::hppiCanPreempt()
2250 if (hppi
.prio
== 0xff) {
2251 // there is no pending interrupt
2255 if (!groupEnabled(hppi
.group
)) {
2256 // group disabled at CPU interface
2260 if (hppi
.prio
>= isa
->readMiscRegNoEffect(MISCREG_ICC_PMR_EL1
)) {
2265 uint8_t rprio
= highestActivePriority();
2267 if (rprio
== 0xff) {
2271 uint32_t prio_mask
= groupPriorityMask(hppi
.group
);
2273 if ((hppi
.prio
& prio_mask
) < (rprio
& prio_mask
)) {
2281 Gicv3CPUInterface::highestActivePriority() const
2283 uint32_t apr
= isa
->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1
) |
2284 isa
->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_NS
) |
2285 isa
->readMiscRegNoEffect(MISCREG_ICC_AP1R0_EL1_S
);
2288 return ctz32(apr
) << (GIC_MIN_BPR
+ 1);
2291 // no active interrups, return idle priority
2296 Gicv3CPUInterface::groupEnabled(Gicv3::GroupId group
) const
2300 ICC_IGRPEN0_EL1 icc_igrpen0_el1
=
2301 isa
->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1
);
2302 return icc_igrpen0_el1
.Enable
&& distributor
->EnableGrp0
;
2306 ICC_IGRPEN1_EL1 icc_igrpen1_el1_s
=
2307 isa
->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S
);
2308 return icc_igrpen1_el1_s
.Enable
&& distributor
->EnableGrp1S
;
2312 ICC_IGRPEN1_EL1 icc_igrpen1_el1_ns
=
2313 isa
->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS
);
2314 return icc_igrpen1_el1_ns
.Enable
&& distributor
->EnableGrp1NS
;
2318 panic("Gicv3CPUInterface::groupEnable(): invalid group!\n");
2323 Gicv3CPUInterface::inSecureState() const
2325 if (!gic
->getSystem()->haveSecurity()) {
2329 CPSR cpsr
= isa
->readMiscRegNoEffect(MISCREG_CPSR
);
2330 SCR scr
= isa
->readMiscRegNoEffect(MISCREG_SCR
);
2331 return ArmISA::inSecureState(scr
, cpsr
);
2335 Gicv3CPUInterface::currEL() const
2337 CPSR cpsr
= isa
->readMiscRegNoEffect(MISCREG_CPSR
);
2338 bool is_64
= opModeIs64((OperatingMode
)(uint8_t) cpsr
.mode
);
2341 return (ExceptionLevel
)(uint8_t) cpsr
.el
;
2343 switch (cpsr
.mode
) {
2360 Gicv3CPUInterface::haveEL(ExceptionLevel el
) const
2368 return gic
->getSystem()->haveVirtualization();
2371 return gic
->getSystem()->haveSecurity();
2374 warn("Unimplemented Exception Level\n");
2380 Gicv3CPUInterface::isSecureBelowEL3() const
2382 SCR scr
= isa
->readMiscRegNoEffect(MISCREG_SCR_EL3
);
2383 return haveEL(EL3
) && scr
.ns
== 0;
2387 Gicv3CPUInterface::isAA64() const
2389 CPSR cpsr
= isa
->readMiscRegNoEffect(MISCREG_CPSR
);
2390 return opModeIs64((OperatingMode
)(uint8_t) cpsr
.mode
);
2394 Gicv3CPUInterface::isEL3OrMon() const
2397 CPSR cpsr
= isa
->readMiscRegNoEffect(MISCREG_CPSR
);
2398 bool is_64
= opModeIs64((OperatingMode
)(uint8_t) cpsr
.mode
);
2400 if (is_64
&& (cpsr
.el
== EL3
)) {
2402 } else if (!is_64
&& (cpsr
.mode
== MODE_MON
)) {
2410 // Computes ICH_EISR_EL2
2412 Gicv3CPUInterface::eoiMaintenanceInterruptStatus() const
2415 // Bits [63:16] - RES0
2416 // Status<n>, bit [n], for n = 0 to 15
2417 // EOI maintenance interrupt status bit for List register <n>:
2418 // 0 if List register <n>, ICH_LR<n>_EL2, does not have an EOI
2419 // maintenance interrupt.
2420 // 1 if List register <n>, ICH_LR<n>_EL2, has an EOI maintenance
2421 // interrupt that has not been handled.
2423 // For any ICH_LR<n>_EL2, the corresponding status bit is set to 1 if all
2424 // of the following are true:
2425 // - ICH_LR<n>_EL2.State is 0b00 (ICH_LR_EL2_STATE_INVALID).
2426 // - ICH_LR<n>_EL2.HW is 0.
2427 // - ICH_LR<n>_EL2.EOI (bit [41]) is 1.
2431 for (int lr_idx
= 0; lr_idx
< VIRTUAL_NUM_LIST_REGS
; lr_idx
++) {
2432 ICH_LR_EL2 ich_lr_el2
=
2433 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
2435 if ((ich_lr_el2
.State
== ICH_LR_EL2_STATE_INVALID
) &&
2436 !ich_lr_el2
.HW
&& ich_lr_el2
.EOI
) {
2437 value
|= (1 << lr_idx
);
2444 Gicv3CPUInterface::ICH_MISR_EL2
2445 Gicv3CPUInterface::maintenanceInterruptStatus() const
2447 // Comments are copied from SPEC section 9.4.7 (ID012119)
2448 ICH_MISR_EL2 ich_misr_el2
= 0;
2449 ICH_HCR_EL2 ich_hcr_el2
=
2450 isa
->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2
);
2451 ICH_VMCR_EL2 ich_vmcr_el2
=
2452 isa
->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2
);
2454 // End Of Interrupt. [bit 0]
2455 // This maintenance interrupt is asserted when at least one bit in
2456 // ICH_EISR_EL2 is 1.
2458 if (eoiMaintenanceInterruptStatus()) {
2459 ich_misr_el2
.EOI
= 1;
2462 // Underflow. [bit 1]
2463 // This maintenance interrupt is asserted when ICH_HCR_EL2.UIE==1 and
2464 // zero or one of the List register entries are marked as a valid
2465 // interrupt, that is, if the corresponding ICH_LR<n>_EL2.State bits
2466 // do not equal 0x0.
2467 uint32_t num_valid_interrupts
= 0;
2468 uint32_t num_pending_interrupts
= 0;
2470 for (int lr_idx
= 0; lr_idx
< VIRTUAL_NUM_LIST_REGS
; lr_idx
++) {
2471 ICH_LR_EL2 ich_lr_el2
=
2472 isa
->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2
+ lr_idx
);
2474 if (ich_lr_el2
.State
!= ICH_LR_EL2_STATE_INVALID
) {
2475 num_valid_interrupts
++;
2478 if (ich_lr_el2
.State
== ICH_LR_EL2_STATE_PENDING
) {
2479 num_pending_interrupts
++;
2483 if (ich_hcr_el2
.UIE
&& (num_valid_interrupts
< 2)) {
2487 // List Register Entry Not Present. [bit 2]
2488 // This maintenance interrupt is asserted when ICH_HCR_EL2.LRENPIE==1
2489 // and ICH_HCR_EL2.EOIcount is non-zero.
2490 if (ich_hcr_el2
.LRENPIE
&& ich_hcr_el2
.EOIcount
) {
2491 ich_misr_el2
.LRENP
= 1;
2494 // No Pending. [bit 3]
2495 // This maintenance interrupt is asserted when ICH_HCR_EL2.NPIE==1 and
2496 // no List register is in pending state.
2497 if (ich_hcr_el2
.NPIE
&& (num_pending_interrupts
== 0)) {
2498 ich_misr_el2
.NP
= 1;
2501 // vPE Group 0 Enabled. [bit 4]
2502 // This maintenance interrupt is asserted when
2503 // ICH_HCR_EL2.VGrp0EIE==1 and ICH_VMCR_EL2.VENG0==1.
2504 if (ich_hcr_el2
.VGrp0EIE
&& ich_vmcr_el2
.VENG0
) {
2505 ich_misr_el2
.VGrp0E
= 1;
2508 // vPE Group 0 Disabled. [bit 5]
2509 // This maintenance interrupt is asserted when
2510 // ICH_HCR_EL2.VGrp0DIE==1 and ICH_VMCR_EL2.VENG0==0.
2511 if (ich_hcr_el2
.VGrp0DIE
&& !ich_vmcr_el2
.VENG0
) {
2512 ich_misr_el2
.VGrp0D
= 1;
2515 // vPE Group 1 Enabled. [bit 6]
2516 // This maintenance interrupt is asserted when
2517 // ICH_HCR_EL2.VGrp1EIE==1 and ICH_VMCR_EL2.VENG1==is 1.
2518 if (ich_hcr_el2
.VGrp1EIE
&& ich_vmcr_el2
.VENG1
) {
2519 ich_misr_el2
.VGrp1E
= 1;
2522 // vPE Group 1 Disabled. [bit 7]
2523 // This maintenance interrupt is asserted when
2524 // ICH_HCR_EL2.VGrp1DIE==1 and ICH_VMCR_EL2.VENG1==is 0.
2525 if (ich_hcr_el2
.VGrp1DIE
&& !ich_vmcr_el2
.VENG1
) {
2526 ich_misr_el2
.VGrp1D
= 1;
2529 return ich_misr_el2
;
2533 Gicv3CPUInterface::bpr1(Gicv3::GroupId group
)
2535 bool hcr_imo
= getHCREL2IMO();
2536 if ((currEL() == EL1
) && !inSecureState() && hcr_imo
) {
2537 return readMiscReg(MISCREG_ICV_BPR1_EL1
);
2542 if (group
== Gicv3::G1S
) {
2543 ICC_CTLR_EL1 icc_ctlr_el1_s
=
2544 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S
);
2546 if (!isEL3OrMon() && icc_ctlr_el1_s
.CBPR
) {
2547 bpr
= isa
->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1
);
2549 bpr
= isa
->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_S
);
2550 bpr
= bpr
> GIC_MIN_BPR
? bpr
: GIC_MIN_BPR
;
2552 } else if (group
== Gicv3::G1NS
) {
2553 ICC_CTLR_EL1 icc_ctlr_el1_ns
=
2554 isa
->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS
);
2556 // Check if EL3 is implemented and this is a non secure accesses at
2558 if (haveEL(EL3
) && !isEL3OrMon() && icc_ctlr_el1_ns
.CBPR
) {
2559 // Reads return BPR0 + 1 saturated to 7, WI
2560 bpr
= isa
->readMiscRegNoEffect(MISCREG_ICC_BPR0_EL1
) + 1;
2561 bpr
= bpr
< 7 ? bpr
: 7;
2563 bpr
= isa
->readMiscRegNoEffect(MISCREG_ICC_BPR1_EL1_NS
);
2564 bpr
= bpr
> GIC_MIN_BPR_NS
? bpr
: GIC_MIN_BPR_NS
;
2567 panic("Should be used with G1S and G1NS only\n");
2574 Gicv3CPUInterface::serialize(CheckpointOut
& cp
) const
2576 SERIALIZE_SCALAR(hppi
.intid
);
2577 SERIALIZE_SCALAR(hppi
.prio
);
2578 SERIALIZE_ENUM(hppi
.group
);
2582 Gicv3CPUInterface::unserialize(CheckpointIn
& cp
)
2584 UNSERIALIZE_SCALAR(hppi
.intid
);
2585 UNSERIALIZE_SCALAR(hppi
.prio
);
2586 UNSERIALIZE_ENUM(hppi
.group
);