48,51d47
< Gicv3CPUInterface::~Gicv3CPUInterface()
< {
< }
<
72c68
< Gicv3CPUInterface::getHCREL2FMO()
---
> Gicv3CPUInterface::getHCREL2FMO() const
86c82
< Gicv3CPUInterface::getHCREL2IMO()
---
> Gicv3CPUInterface::getHCREL2IMO() const
106a103
> // Active Priorities Group 1 Registers
128a126
> // Active Priorities Group 0 Registers
150a149
> // Interrupt Group 0 Enable register EL1
154c153
< return readMiscReg(MISCREG_ICV_IGRPEN0_EL1);
---
> return isa->readMiscRegNoEffect(MISCREG_ICV_IGRPEN0_EL1);
160,166c159
< case MISCREG_ICV_IGRPEN0_EL1: {
< RegVal ich_vmcr_el2 =
< isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
< value = bits(ich_vmcr_el2, ICH_VMCR_EL2_VENG0_SHIFT);
< break;
< }
<
---
> // Interrupt Group 1 Enable register EL1
170c163
< return readMiscReg(MISCREG_ICV_IGRPEN1_EL1);
---
> return isa->readMiscRegNoEffect(MISCREG_ICV_IGRPEN1_EL1);
176,182c169
< case MISCREG_ICV_IGRPEN1_EL1: {
< RegVal ich_vmcr_el2 =
< isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
< value = bits(ich_vmcr_el2, ICH_VMCR_EL2_VENG1_SHIFT);
< break;
< }
<
---
> // Interrupt Group 1 Enable register EL3
184,202c171
< case MISCREG_ICC_IGRPEN1_EL3: {
< // EnableGrp1S and EnableGrp1NS are aliased with
< // ICC_IGRPEN1_EL1_S.Enable and ICC_IGRPEN1_EL1_NS.Enable
< bool enable_grp_1s =
< isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S) &
< ICC_IGRPEN1_EL1_ENABLE;
< bool enable_grp_1ns =
< isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS) &
< ICC_IGRPEN1_EL1_ENABLE;
< value = 0;
<
< if (enable_grp_1s) {
< value |= ICC_IGRPEN1_EL3_ENABLEGRP1S;
< }
<
< if (enable_grp_1ns) {
< value |= ICC_IGRPEN1_EL3_ENABLEGRP1NS;
< }
<
---
> case MISCREG_ICC_IGRPEN1_EL3:
204d172
< }
205a174
> // Running Priority Register
209c178
< (hcr_imo || hcr_fmo)) {
---
> (hcr_imo || hcr_fmo)) {
216,217c185,187
< (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
< /* NS GIC access and Group 0 is inaccessible to NS */
---
> (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
> // Spec section 4.8.1
> // For Non-secure access to ICC_RPR_EL1 when SCR_EL3.FIQ == 1
219,220c189,190
< /* NS should not see priorities in the Secure half of the
< * range */
---
> // If the current priority mask value is in the range of
> // 0x00-0x7F a read access returns the value 0x0
223c193,195
< /* Non-idle priority: show the Non-secure view of it */
---
> // If the current priority mask value is in the range of
> // 0x80-0xFF a read access returns the Non-secure read of
> // the current value
231a204
> // Virtual Running Priority Register
236a210
> // Highest Priority Pending Interrupt Register 0
246a221
> // Virtual Highest Priority Pending Interrupt Register 0
252c227
< RegVal lr =
---
> ICH_LR_EL2 ich_lr_el2 =
255c230
< lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;
---
> ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
258c233
< value = bits(lr, 31, 0);
---
> value = ich_lr_el2.vINTID;
264a240
> // Highest Priority Pending Interrupt Register 1
274a251
> // Virtual Highest Priority Pending Interrupt Register 1
280c257
< RegVal lr =
---
> ICH_LR_EL2 ich_lr_el2 =
283c260
< lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;
---
> ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
286c263
< value = bits(lr, 31, 0);
---
> value = ich_lr_el2.vINTID;
292a270
> // Binary Point Register 0
300a279
> // Binary Point Register 1
302,305c281,284
< case MISCREG_ICC_BPR1_EL1:
< if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
< return readMiscReg(MISCREG_ICV_BPR1_EL1);
< }
---
> case MISCREG_ICC_BPR1_EL1: {
> if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
> return readMiscReg(MISCREG_ICV_BPR1_EL1);
> }
307d285
< {
315,318c293,297
< if ((group == Gicv3::G1S) &&
< !isEL3OrMon() &&
< (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S)
< & ICC_CTLR_EL1_CBPR)) {
---
> ICC_CTLR_EL1 icc_ctlr_el1_s =
> isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
>
> if ((group == Gicv3::G1S) && !isEL3OrMon() &&
> icc_ctlr_el1_s.CBPR) {
324,327c303,307
< if ((group == Gicv3::G1NS) &&
< (currEL() < EL3) &&
< (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS)
< & ICC_CTLR_EL1_CBPR)) {
---
> ICC_CTLR_EL1 icc_ctlr_el1_ns =
> isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
>
> if ((group == Gicv3::G1NS) && (currEL() < EL3) &&
> icc_ctlr_el1_ns.CBPR) {
351c331
< }
---
> }
352a333
> // Virtual Binary Point Register 1
357c338
< RegVal ich_vmcr_el2 =
---
> ICH_VMCR_EL2 ich_vmcr_el2 =
361,362c342,343
< if (group == Gicv3::G1NS && (ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR)) {
< // reads return bpr0 + 1 saturated to 7, writes ignored
---
> if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
> // bpr0 + 1 saturated to 7, WI
370c351
< vbpr = bits(ich_vmcr_el2, 23, 21);
---
> vbpr = ich_vmcr_el2.VBPR0;
372c353
< vbpr = bits(ich_vmcr_el2, 20, 18);
---
> vbpr = ich_vmcr_el2.VBPR1;
386a368
> // Interrupt Priority Mask Register
388,391c370,372
< case MISCREG_ICC_PMR_EL1: // Priority Mask Register
< if ((currEL() == EL1) && !inSecureState() &&
< (hcr_imo || hcr_fmo)) {
< return readMiscReg(MISCREG_ICV_PMR_EL1);
---
> case MISCREG_ICC_PMR_EL1:
> if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
> return isa->readMiscRegNoEffect(MISCREG_ICV_PMR_EL1);
395,396c376,378
< (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
< /* NS GIC access and Group 0 is inaccessible to NS */
---
> (isa->readMiscRegNoEffect(MISCREG_SCR_EL3) & (1U << 2))) {
> // Spec section 4.8.1
> // For Non-secure access to ICC_PMR_EL1 when SCR_EL3.FIQ == 1:
398,399c380,381
< /* NS should not see priorities in the Secure half of the
< * range */
---
> // If the current priority mask value is in the range of
> // 0x00-0x7F a read access returns the value 0x00.
402c384,386
< /* Non-idle priority: show the Non-secure view of it */
---
> // If the current priority mask value is in the range of
> // 0x80-0xFF a read access returns the Non-secure read of the
> // current value.
409,416c393
< case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
< RegVal ich_vmcr_el2 =
< isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
<
< value = ich_vmcr_el2 >> ICH_VMCR_EL2_VPMR_SHIFT;
< break;
< }
<
---
> // Interrupt Acknowledge Register 0
418c395
< case MISCREG_ICC_IAR0_EL1: { // Interrupt Acknowledge Register 0
---
> case MISCREG_ICC_IAR0_EL1: {
439a417
> // Virtual Interrupt Acknowledge Register 0
445c423
< RegVal lr =
---
> ICH_LR_EL2 ich_lr_el2 =
448,449c426,427
< if (!(lr & ICH_LR_EL2_GROUP) && hppviCanPreempt(lr_idx)) {
< int_id = value = bits(lr, 31, 0);
---
> if (!ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
> int_id = ich_lr_el2.vINTID;
452c430
< int_id > Gicv3::INTID_SPURIOUS) {
---
> int_id > Gicv3::INTID_SPURIOUS) {
458c436
< lr &= ~ICH_LR_EL2_STATE_PENDING_BIT;
---
> ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
460c438
< lr);
---
> ich_lr_el2);
469a448
> // Interrupt Acknowledge Register 1
471c450
< case MISCREG_ICC_IAR1_EL1: { // Interrupt Acknowledge Register 1
---
> case MISCREG_ICC_IAR1_EL1: {
485,492d463
<
< // LPIs are not activated and when acked their pending
< // bit is cleared
< if (int_id >= Gicv3Redistributor::SMALLEST_LPI_ID)
< {
< redistributor->setClrLPI(int_id, false);
< }
<
500a472
> // Virtual Interrupt Acknowledge Register 1
506c478
< RegVal lr =
---
> ICH_LR_EL2 ich_lr_el2 =
509,510c481,482
< if (lr & ICH_LR_EL2_GROUP && hppviCanPreempt(lr_idx)) {
< int_id = value = bits(lr, 31, 0);
---
> if (ich_lr_el2.Group && hppviCanPreempt(lr_idx)) {
> int_id = ich_lr_el2.vINTID;
513c485
< int_id > Gicv3::INTID_SPURIOUS) {
---
> int_id > Gicv3::INTID_SPURIOUS) {
519c491
< lr &= ~ICH_LR_EL2_STATE_PENDING_BIT;
---
> ich_lr_el2.State = ICH_LR_EL2_STATE_INVALID;
521c493
< lr);
---
> ich_lr_el2);
530a503
> // System Register Enable Register EL1
532,571c505,515
< case MISCREG_ICC_SRE_EL1: { // System Register Enable Register
< bool dfb;
< bool dib;
<
< if (haveEL(EL3) && !distributor->DS) {
< // DIB is RO alias of ICC_SRE_EL3.DIB
< // DFB is RO alias of ICC_SRE_EL3.DFB
< RegVal icc_sre_el3 =
< isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL3);
< dfb = icc_sre_el3 & ICC_SRE_EL3_DFB;
< dib = icc_sre_el3 & ICC_SRE_EL3_DIB;
< } else if (haveEL(EL3) && distributor->DS) {
< // DIB is RW alias of ICC_SRE_EL3.DIB
< // DFB is RW alias of ICC_SRE_EL3.DFB
< RegVal icc_sre_el3 =
< isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL3);
< dfb = icc_sre_el3 & ICC_SRE_EL3_DFB;
< dib = icc_sre_el3 & ICC_SRE_EL3_DIB;
< } else if ((!haveEL(EL3) || distributor->DS) and haveEL(EL2)) {
< // DIB is RO alias of ICC_SRE_EL2.DIB
< // DFB is RO alias of ICC_SRE_EL2.DFB
< RegVal icc_sre_el2 =
< isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL2);
< dfb = icc_sre_el2 & ICC_SRE_EL2_DFB;
< dib = icc_sre_el2 & ICC_SRE_EL2_DIB;
< } else {
< dfb = value & ICC_SRE_EL1_DFB;
< dib = value & ICC_SRE_EL1_DIB;
< }
<
< value = ICC_SRE_EL1_SRE;
<
< if (dfb) {
< value |= ICC_SRE_EL1_DFB;
< }
<
< if (dib) {
< value |= ICC_SRE_EL1_DIB;
< }
<
---
> case MISCREG_ICC_SRE_EL1: {
> /*
> * DIB [2] == 1 (IRQ bypass not supported, RAO/WI)
> * DFB [1] == 1 (FIQ bypass not supported, RAO/WI)
> * SRE [0] == 1 (Only system register interface supported, RAO/WI)
> */
> ICC_SRE_EL1 icc_sre_el1 = 0;
> icc_sre_el1.SRE = 1;
> icc_sre_el1.DIB = 1;
> icc_sre_el1.DFB = 1;
> value = icc_sre_el1;
574a519
> // System Register Enable Register EL2
576c521
< case MISCREG_ICC_SRE_EL2: // System Register Enable Register
---
> case MISCREG_ICC_SRE_EL2: {
579,580c524
< * (Secure EL1 accesses to Secure ICC_SRE_EL1 do not trap to EL2,
< * RAO/WI)
---
> * (EL1 accesses to ICC_SRE_EL1 do not trap to EL2, RAO/WI)
585,586c529,534
< value = ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_DIB | ICC_SRE_EL2_DFB |
< ICC_SRE_EL2_SRE;
---
> ICC_SRE_EL2 icc_sre_el2 = 0;
> icc_sre_el2.SRE = 1;
> icc_sre_el2.DIB = 1;
> icc_sre_el2.DFB = 1;
> icc_sre_el2.Enable = 1;
> value = icc_sre_el2;
587a536
> }
588a538
> // System Register Enable Register EL3
590c540
< case MISCREG_ICC_SRE_EL3: // System Register Enable Register
---
> case MISCREG_ICC_SRE_EL3: {
593,594c543,545
< * (Secure EL1 accesses to Secure ICC_SRE_EL1 do not trap to EL3,
< * RAO/WI)
---
> * (EL1 accesses to ICC_SRE_EL1 do not trap to EL3.
> * EL2 accesses to ICC_SRE_EL1 and ICC_SRE_EL2 do not trap to EL3.
> * RAO/WI)
599,600c550,555
< value = ICC_SRE_EL3_ENABLE | ICC_SRE_EL3_DIB | ICC_SRE_EL3_DFB |
< ICC_SRE_EL3_SRE;
---
> ICC_SRE_EL3 icc_sre_el3 = 0;
> icc_sre_el3.SRE = 1;
> icc_sre_el3.DIB = 1;
> icc_sre_el3.DFB = 1;
> icc_sre_el3.Enable = 1;
> value = icc_sre_el3;
601a557
> }
602a559
> // Control Register
604,606c561,562
< case MISCREG_ICC_CTLR_EL1: { // Control Register
< if ((currEL() == EL1) && !inSecureState() &&
< (hcr_imo || hcr_fmo)) {
---
> case MISCREG_ICC_CTLR_EL1: {
> if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
610c566,571
< // Add value for RO bits
---
> // Enforce value for RO bits
> // ExtRange [19], INTIDs in the range 1024..8191 not supported
> // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
> // A3V [15], supports non-zero values of the Aff3 field in SGI
> // generation System registers
> // SEIS [14], does not support generation of SEIs (deprecated)
613,614c574,581
< value |= ICC_CTLR_EL1_RSS | ICC_CTLR_EL1_A3V |
< (1 << 11) | ((PRIORITY_BITS - 1) << 8);
---
> ICC_CTLR_EL1 icc_ctlr_el1 = value;
> icc_ctlr_el1.ExtRange = 0;
> icc_ctlr_el1.RSS = 1;
> icc_ctlr_el1.A3V = 1;
> icc_ctlr_el1.SEIS = 0;
> icc_ctlr_el1.IDbits = 1;
> icc_ctlr_el1.PRIbits = PRIORITY_BITS - 1;
> value = icc_ctlr_el1;
617a585
> // Virtual Control Register
619,631c587,593
< value = ICC_CTLR_EL1_A3V | (1 << ICC_CTLR_EL1_IDBITS_SHIFT) |
< (7 << ICC_CTLR_EL1_PRIBITS_SHIFT);
< RegVal ich_vmcr_el2 =
< isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
<
< if (ich_vmcr_el2 & ICH_VMCR_EL2_VEOIM) {
< value |= ICC_CTLR_EL1_EOIMODE;
< }
<
< if (ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR) {
< value |= ICC_CTLR_EL1_CBPR;
< }
<
---
> ICV_CTLR_EL1 icv_ctlr_el1 = value;
> icv_ctlr_el1.RSS = 0;
> icv_ctlr_el1.A3V = 1;
> icv_ctlr_el1.SEIS = 0;
> icv_ctlr_el1.IDbits = 1;
> icv_ctlr_el1.PRIbits = 7;
> value = icv_ctlr_el1;
634a597
> // Control Register
637,639c600,606
< // Add value for RO bits
< // RSS [18]
< // A3V [15]
---
> // Enforce value for RO bits
> // ExtRange [19], INTIDs in the range 1024..8191 not supported
> // RSS [18], SGIs with affinity level 0 values of 0-255 are supported
> // nDS [17], supports disabling of security
> // A3V [15], supports non-zero values of the Aff3 field in SGI
> // generation System registers
> // SEIS [14], does not support generation of SEIs (deprecated)
642,665c609,617
< value |= ICC_CTLR_EL3_RSS | ICC_CTLR_EL3_A3V | (0 << 11) |
< ((PRIORITY_BITS - 1) << 8);
< // Aliased bits...
< RegVal icc_ctlr_el1_ns =
< isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
< RegVal icc_ctlr_el1_s =
< isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
<
< if (icc_ctlr_el1_ns & ICC_CTLR_EL1_EOIMODE) {
< value |= ICC_CTLR_EL3_EOIMODE_EL1NS;
< }
<
< if (icc_ctlr_el1_ns & ICC_CTLR_EL1_CBPR) {
< value |= ICC_CTLR_EL3_CBPR_EL1NS;
< }
<
< if (icc_ctlr_el1_s & ICC_CTLR_EL1_EOIMODE) {
< value |= ICC_CTLR_EL3_EOIMODE_EL1S;
< }
<
< if (icc_ctlr_el1_s & ICC_CTLR_EL1_CBPR) {
< value |= ICC_CTLR_EL3_CBPR_EL1S;
< }
<
---
> ICC_CTLR_EL3 icc_ctlr_el3 = value;
> icc_ctlr_el3.ExtRange = 0;
> icc_ctlr_el3.RSS = 1;
> icc_ctlr_el3.nDS = 0;
> icc_ctlr_el3.A3V = 1;
> icc_ctlr_el3.SEIS = 0;
> icc_ctlr_el3.IDbits = 0;
> icc_ctlr_el3.PRIbits = PRIORITY_BITS - 1;
> value = icc_ctlr_el3;
668a621
> // Hyp Control Register
672a626
> // Hyp Active Priorities Group 0 Registers
676a631
> // Hyp Active Priorities Group 1 Registers
680a636
> // Maintenance Interrupt State Register
682,689c638,640
< case MISCREG_ICH_MISR_EL2: {
< value = 0;
< // Scan list registers and fill in the U, NP and EOI bits
< eoiMaintenanceInterruptStatus((uint32_t *) &value);
< RegVal ich_hcr_el2 =
< isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
< RegVal ich_vmcr_el2 =
< isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
---
> case MISCREG_ICH_MISR_EL2:
> value = maintenanceInterruptStatus();
> break;
691,694c642,645
< if (ich_hcr_el2 &
< (ICH_HCR_EL2_LRENPIE | ICH_HCR_EL2_EOICOUNT_MASK)) {
< value |= ICH_MISR_EL2_LRENP;
< }
---
> // VGIC Type Register
> case MISCREG_ICH_VTR:
> case MISCREG_ICH_VTR_EL2: {
> ICH_VTR_EL2 ich_vtr_el2 = value;
696,699c647,651
< if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP0EIE) &&
< (ich_vmcr_el2 & ICH_VMCR_EL2_VENG0)) {
< value |= ICH_MISR_EL2_VGRP0E;
< }
---
> ich_vtr_el2.ListRegs = VIRTUAL_NUM_LIST_REGS - 1;
> ich_vtr_el2.A3V = 1;
> ich_vtr_el2.IDbits = 1;
> ich_vtr_el2.PREbits = VIRTUAL_PREEMPTION_BITS - 1;
> ich_vtr_el2.PRIbits = VIRTUAL_PRIORITY_BITS - 1;
701,716c653,654
< if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP0DIE) &&
< !(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
< value |= ICH_MISR_EL2_VGRP0D;
< }
<
< if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP1EIE) &&
< (ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
< value |= ICH_MISR_EL2_VGRP1E;
< }
<
< if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP1DIE) &&
< !(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
< value |= ICH_MISR_EL2_VGRP1D;
< }
<
< break;
---
> value = ich_vtr_el2;
> break;
719,745c657
< case MISCREG_ICH_VTR:
< case MISCREG_ICH_VTR_EL2:
< /*
< * PRIbits [31:29]
< * PREbits [28:26]
< * IDbits [25:23]
< * SEIS [22] == 0 (SEI Support)
< * A3V [21] == 1
< * (Non-zero values supported for Affinity 3 in SGI genearion)
< * nV4 [20] == 0
< * (Support for direct injection of virtual interrupts)
< * TDS [19] == 0 (Implementation supports ICH_HCR_EL2.TDIR)
< * ListRegs [4:0]
< */
< value = (16 - 1) << 0 |
< (5 - 1) << 26 |
< (5 - 1) << 29;
< value =
< ((VIRTUAL_NUM_LIST_REGS - 1) << ICH_VTR_EL2_LISTREGS_SHIFT) |
< // ICH_VTR_EL2_TDS |
< // ICH_VTR_EL2_NV4 |
< ICH_VTR_EL2_A3V |
< (1 << ICH_VTR_EL2_IDBITS_SHIFT) |
< ((VIRTUAL_PREEMPTION_BITS - 1) << ICH_VTR_EL2_PREBITS_SHIFT) |
< ((VIRTUAL_PRIORITY_BITS - 1) << ICH_VTR_EL2_PRIBITS_SHIFT);
< break;
<
---
> // End of Interrupt Status Register
748c660
< value = eoiMaintenanceInterruptStatus(nullptr);
---
> value = eoiMaintenanceInterruptStatus();
750a663
> // Empty List Register Status Register
756c669
< RegVal lr =
---
> ICH_LR_EL2 ich_lr_el2 =
759,761c672,673
< if ((lr & ICH_LR_EL2_STATE_MASK) == 0 &&
< ((lr & ICH_LR_EL2_HW) != 0 ||
< (lr & ICH_LR_EL2_EOI) == 0)) {
---
> if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
> (ich_lr_el2.HW || !ich_lr_el2.EOI)) {
767a680
> // List Registers
772a686
> // List Registers
777a692
> // List Registers
780a696
> // Virtual Machine Control Register
786,788c702,703
< panic("Gicv3CPUInterface::readMiscReg(): "
< "unknown register %d (%s)",
< misc_reg, miscRegName[misc_reg]);
---
> panic("Gicv3CPUInterface::readMiscReg(): unknown register %d (%s)",
> misc_reg, miscRegName[misc_reg]);
791,792c706,707
< DPRINTF(GIC, "Gicv3CPUInterface::readMiscReg(): "
< "register %s value %#x\n", miscRegName[misc_reg], value);
---
> DPRINTF(GIC, "Gicv3CPUInterface::readMiscReg(): register %s value %#x\n",
> miscRegName[misc_reg], value);
800,801c715,716
< DPRINTF(GIC, "Gicv3CPUInterface::setMiscReg(): "
< "register %s value %#x\n", miscRegName[misc_reg], val);
---
> DPRINTF(GIC, "Gicv3CPUInterface::setMiscReg(): register %s value %#x\n",
> miscRegName[misc_reg], val);
805a721
> // Active Priorities Group 1 Registers
826a743
> // Active Priorities Group 0 Registers
847a765
> // End Of Interrupt Register 0
875a794
> // Virtual End Of Interrupt Register 0
897c816
< RegVal lr =
---
> ICH_LR_EL2 ich_lr_el2 =
900,901c819,820
< lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;
< uint8_t lr_group_prio = bits(lr, 55, 48) & 0xf8;
---
> ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
> uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
904c823
< //JAIRO if (!virtualIsEOISplitMode())
---
> //if (!virtualIsEOISplitMode())
914a834
> // End Of Interrupt Register 1
916c836
< case MISCREG_ICC_EOIR1_EL1: { // End Of Interrupt Register 1
---
> case MISCREG_ICC_EOIR1_EL1: {
928,929c848
< Gicv3::GroupId group =
< inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
---
> Gicv3::GroupId group = inSecureState() ? Gicv3::G1S : Gicv3::G1NS;
939c858
< !(!inSecureState() or (currEL() == EL3))) {
---
> !(!inSecureState() or (currEL() == EL3))) {
952a872
> // Virtual End Of Interrupt Register 1
958c878
< int_id <= Gicv3::INTID_SPURIOUS) {
---
> int_id <= Gicv3::INTID_SPURIOUS) {
971c891
< // No LR found matching
---
> // No matching LR found
974c894
< RegVal lr =
---
> ICH_LR_EL2 ich_lr_el2 =
977,978c897,898
< lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;
< uint8_t lr_group_prio = bits(lr, 55, 48) & 0xf8;
---
> ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
> uint8_t lr_group_prio = ich_lr_el2.Priority & 0xf8;
990a911
> // Deactivate Interrupt Register
992c913
< case MISCREG_ICC_DIR_EL1: { // Deactivate Interrupt Register
---
> case MISCREG_ICC_DIR_EL1: {
994c915
< (hcr_imo || hcr_fmo)) {
---
> (hcr_imo || hcr_fmo)) {
1000c921,924
< // avoid deactivation for special interrupts
---
> // The following checks are as per spec pseudocode
> // aarch64/support/ICC_DIR_EL1
>
> // Check for spurious ID
1004a929
> // EOI mode is not set, so don't deactivate
1009,1012d933
< /*
< * Check whether we're allowed to deactivate.
< * These checks are correspond to the spec's pseudocode.
< */
1043c964
< !route_fiq_to_el3 && !route_fiq_to_el2) {
---
> !route_fiq_to_el3 && !route_fiq_to_el2) {
1048c969
< !route_irq_to_el3 && !route_irq_to_el2) {
---
> !route_irq_to_el3 && !route_irq_to_el2) {
1057,1058c978,979
< (!irq_is_secure || !single_sec_state) &&
< !route_irq_to_el3) {
---
> (!irq_is_secure || !single_sec_state) &&
> !route_irq_to_el3) {
1072a994
> // Deactivate Virtual Interrupt Register
1078c1000
< int_id <= Gicv3::INTID_SPURIOUS) {
---
> int_id <= Gicv3::INTID_SPURIOUS) {
1089c1011
< // No LR found matching
---
> // No matching LR found
1098a1021
> // Binary Point Register 0
1100c1023,1024
< case MISCREG_ICC_BPR0_EL1: // Binary Point Register 0
---
> case MISCREG_ICC_BPR0_EL1:
> // Binary Point Register 1
1102c1026
< case MISCREG_ICC_BPR1_EL1: { // Binary Point Register 1
---
> case MISCREG_ICC_BPR1_EL1: {
1118,1121c1042,1046
< if ((group == Gicv3::G1S) &&
< !isEL3OrMon() &&
< (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S) &
< ICC_CTLR_EL1_CBPR)) {
---
> ICC_CTLR_EL1 icc_ctlr_el1_s =
> isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
>
> if ((group == Gicv3::G1S) && !isEL3OrMon() &&
> icc_ctlr_el1_s.CBPR) {
1125,1129c1050,1055
< if ((group == Gicv3::G1NS) &&
< (currEL() < EL3) &&
< (isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS) &
< ICC_CTLR_EL1_CBPR)) {
< // Reads return BPR0 + 1 saturated to 7, WI
---
> ICC_CTLR_EL1 icc_ctlr_el1_ns =
> isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
>
> if ((group == Gicv3::G1NS) && (currEL() < EL3) &&
> icc_ctlr_el1_ns.CBPR) {
> // BPR0 + 1 saturated to 7, WI
1143a1070
> // Virtual Binary Point Register 0
1144a1072
> // Virtual Binary Point Register 1
1148c1076
< RegVal ich_vmcr_el2 =
---
> ICH_VMCR_EL2 ich_vmcr_el2 =
1151,1152c1079,1080
< if (group == Gicv3::G1NS && (ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR)) {
< // reads return bpr0 + 1 saturated to 7, writes ignored
---
> if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
> // BPR0 + 1 saturated to 7, WI
1167,1169c1095
< ich_vmcr_el2 = insertBits(ich_vmcr_el2,
< ICH_VMCR_EL2_VBPR0_SHIFT + 2, ICH_VMCR_EL2_VBPR0_SHIFT,
< val);
---
> ich_vmcr_el2.VBPR0 = val;
1171,1173c1097
< ich_vmcr_el2 = insertBits(ich_vmcr_el2,
< ICH_VMCR_EL2_VBPR1_SHIFT + 2, ICH_VMCR_EL2_VBPR1_SHIFT,
< val);
---
> ich_vmcr_el2.VBPR1 = val;
1180a1105
> // Control Register EL1
1182,1184c1107,1108
< case MISCREG_ICC_CTLR_EL1: { // Control Register
< if ((currEL() == EL1) && !inSecureState() &&
< (hcr_imo || hcr_fmo)) {
---
> case MISCREG_ICC_CTLR_EL1: {
> if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
1188a1113
> * ExtRange is RO.
1194,1196d1118
< * If EL3 is implemented and GICD_CTLR.DS == 0, then PMHE is RO.
< * So, only CBPR[0] and EOIMODE[1] are RW.
< * If EL3 is implemented and GICD_CTLR.DS == 0, then CBPR is RO.
1198c1120,1122
< uint64_t mask;
---
> ICC_CTLR_EL1 requested_icc_ctlr_el1 = val;
> ICC_CTLR_EL1 icc_ctlr_el1 =
> isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1);
1200,1204c1124,1140
< if (haveEL(EL3) and distributor->DS == 0) {
< mask = ICC_CTLR_EL1_EOIMODE;
< } else if (haveEL(EL3) and distributor->DS == 1) {
< mask = ICC_CTLR_EL1_PMHE | ICC_CTLR_EL1_CBPR |
< ICC_CTLR_EL1_EOIMODE;
---
> ICC_CTLR_EL3 icc_ctlr_el3 =
> isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
>
> // The following could be refactored but it is following
> // spec description section 9.2.6 point by point.
>
> // PMHE
> if (haveEL(EL3)) {
> // PMHE is alias of ICC_CTLR_EL3.PMHE
>
> if (distributor->DS == 0) {
> // PMHE is RO
> } else if (distributor->DS == 1) {
> // PMHE is RW
> icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
> icc_ctlr_el3.PMHE = icc_ctlr_el1.PMHE;
> }
1206c1142,1143
< mask = ICC_CTLR_EL1_CBPR | ICC_CTLR_EL1_EOIMODE;
---
> // PMHE is RW (by implementation choice)
> icc_ctlr_el1.PMHE = requested_icc_ctlr_el1.PMHE;
1209,1212c1146,1180
< RegVal old_val =
< isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1);
< old_val &= ~mask;
< val = old_val | (val & mask);
---
> // EOImode
> icc_ctlr_el1.EOImode = requested_icc_ctlr_el1.EOImode;
>
> if (inSecureState()) {
> // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1S
> icc_ctlr_el3.EOImode_EL1S = icc_ctlr_el1.EOImode;
> } else {
> // EOIMode is alias of ICC_CTLR_EL3.EOImode_EL1NS
> icc_ctlr_el3.EOImode_EL1NS = icc_ctlr_el1.EOImode;
> }
>
> // CBPR
> if (haveEL(EL3)) {
> // CBPR is alias of ICC_CTLR_EL3.CBPR_EL1{S,NS}
>
> if (distributor->DS == 0) {
> // CBPR is RO
> } else {
> // CBPR is RW
> icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
>
> if (inSecureState()) {
> icc_ctlr_el3.CBPR_EL1S = icc_ctlr_el1.CBPR;
> } else {
> icc_ctlr_el3.CBPR_EL1NS = icc_ctlr_el1.CBPR;
> }
> }
> } else {
> // CBPR is RW
> icc_ctlr_el1.CBPR = requested_icc_ctlr_el1.CBPR;
> }
>
> isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL3, icc_ctlr_el3);
>
> val = icc_ctlr_el1;
1215a1184
> // Virtual Control Register
1217,1225c1186,1201
< RegVal ich_vmcr_el2 =
< isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
< ich_vmcr_el2 = insertBits(ich_vmcr_el2, ICH_VMCR_EL2_VCBPR_SHIFT,
< val & ICC_CTLR_EL1_CBPR ? 1 : 0);
< ich_vmcr_el2 = insertBits(ich_vmcr_el2, ICH_VMCR_EL2_VEOIM_SHIFT,
< val & ICC_CTLR_EL1_EOIMODE ? 1 : 0);
< isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
< do_virtual_update = true;
< break;
---
> ICV_CTLR_EL1 requested_icv_ctlr_el1 = val;
> ICV_CTLR_EL1 icv_ctlr_el1 =
> isa->readMiscRegNoEffect(MISCREG_ICV_CTLR_EL1);
> icv_ctlr_el1.EOImode = requested_icv_ctlr_el1.EOImode;
> icv_ctlr_el1.CBPR = requested_icv_ctlr_el1.CBPR;
> val = icv_ctlr_el1;
>
> // Aliases
> // ICV_CTLR_EL1.CBPR aliases ICH_VMCR_EL2.VCBPR.
> // ICV_CTLR_EL1.EOImode aliases ICH_VMCR_EL2.VEOIM.
> ICH_VMCR_EL2 ich_vmcr_el2 =
> isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
> ich_vmcr_el2.VCBPR = icv_ctlr_el1.CBPR;
> ich_vmcr_el2.VEOIM = icv_ctlr_el1.EOImode;
> isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
> break;
1227a1204
> // Control Register EL3
1230,1233c1207,1217
< RegVal icc_ctlr_el1_s =
< isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
< RegVal icc_ctlr_el1_ns =
< isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
---
> /*
> * ExtRange is RO.
> * RSS is RO.
> * nDS is RO.
> * A3V is RO.
> * SEIS is RO.
> * IDbits is RO.
> * PRIbits is RO.
> * PMHE is RAO/WI, priority-based routing is always used.
> */
> ICC_CTLR_EL3 requested_icc_ctlr_el3 = val;
1235,1241c1219,1225
< // ICC_CTLR_EL1(NS).EOImode is an alias of
< // ICC_CTLR_EL3.EOImode_EL1NS
< if (val & ICC_CTLR_EL3_EOIMODE_EL1NS) {
< icc_ctlr_el1_ns |= ICC_CTLR_EL1_EOIMODE;
< } else {
< icc_ctlr_el1_ns &= ~ICC_CTLR_EL1_EOIMODE;
< }
---
> // Aliases
> if (haveEL(EL3))
> {
> ICC_CTLR_EL1 icc_ctlr_el1_s =
> isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
> ICC_CTLR_EL1 icc_ctlr_el1_ns =
> isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
1243,1248c1227,1236
< // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS
< if (val & ICC_CTLR_EL3_CBPR_EL1NS) {
< icc_ctlr_el1_ns |= ICC_CTLR_EL1_CBPR;
< } else {
< icc_ctlr_el1_ns &= ~ICC_CTLR_EL1_CBPR;
< }
---
> // ICC_CTLR_EL1(NS).EOImode is an alias of
> // ICC_CTLR_EL3.EOImode_EL1NS
> icc_ctlr_el1_ns.EOImode = requested_icc_ctlr_el3.EOImode_EL1NS;
> // ICC_CTLR_EL1(S).EOImode is an alias of
> // ICC_CTLR_EL3.EOImode_EL1S
> icc_ctlr_el1_s.EOImode = requested_icc_ctlr_el3.EOImode_EL1S;
> // ICC_CTLR_EL1(NS).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1NS
> icc_ctlr_el1_ns.CBPR = requested_icc_ctlr_el3.CBPR_EL1NS;
> // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S
> icc_ctlr_el1_s.CBPR = requested_icc_ctlr_el3.CBPR_EL1S;
1250,1254c1238,1240
< // ICC_CTLR_EL1(S).EOImode is an alias of ICC_CTLR_EL3.EOImode_EL1S
< if (val & ICC_CTLR_EL3_EOIMODE_EL1S) {
< icc_ctlr_el1_s |= ICC_CTLR_EL1_EOIMODE;
< } else {
< icc_ctlr_el1_s &= ~ICC_CTLR_EL1_EOIMODE;
---
> isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S, icc_ctlr_el1_s);
> isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS,
> icc_ctlr_el1_ns);
1257,1267c1243
< // ICC_CTLR_EL1(S).CBPR is an alias of ICC_CTLR_EL3.CBPR_EL1S
< if (val & ICC_CTLR_EL3_CBPR_EL1S) {
< icc_ctlr_el1_s |= ICC_CTLR_EL1_CBPR;
< } else {
< icc_ctlr_el1_s &= ~ICC_CTLR_EL1_CBPR;
< }
<
< isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S, icc_ctlr_el1_s);
< isa->setMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS, icc_ctlr_el1_ns);
< // Only ICC_CTLR_EL3_EOIMODE_EL3 is writable
< RegVal old_icc_ctlr_el3 =
---
> ICC_CTLR_EL3 icc_ctlr_el3 =
1269,1271c1245,1253
< old_icc_ctlr_el3 &= ~(ICC_CTLR_EL3_EOIMODE_EL3 | ICC_CTLR_EL3_RM);
< val = old_icc_ctlr_el3 |
< (val & (ICC_CTLR_EL3_EOIMODE_EL3 | ICC_CTLR_EL3_RM));
---
>
> icc_ctlr_el3.RM = requested_icc_ctlr_el3.RM;
> icc_ctlr_el3.EOImode_EL1NS = requested_icc_ctlr_el3.EOImode_EL1NS;
> icc_ctlr_el3.EOImode_EL1S = requested_icc_ctlr_el3.EOImode_EL1S;
> icc_ctlr_el3.EOImode_EL3 = requested_icc_ctlr_el3.EOImode_EL3;
> icc_ctlr_el3.CBPR_EL1NS = requested_icc_ctlr_el3.CBPR_EL1NS;
> icc_ctlr_el3.CBPR_EL1S = requested_icc_ctlr_el3.CBPR_EL1S;
>
> val = icc_ctlr_el3;
1274a1257
> // Priority Mask Register
1276,1279c1259,1261
< case MISCREG_ICC_PMR_EL1: { // Priority Mask Register
< if ((currEL() == EL1) && !inSecureState() &&
< (hcr_imo || hcr_fmo)) {
< return setMiscReg(MISCREG_ICV_PMR_EL1, val);
---
> case MISCREG_ICC_PMR_EL1: {
> if ((currEL() == EL1) && !inSecureState() && (hcr_imo || hcr_fmo)) {
> return isa->setMiscRegNoEffect(MISCREG_ICV_PMR_EL1, val);
1286,1289c1268,1269
< /*
< * NS access and Group 0 is inaccessible to NS: return the
< * NS view of the current priority
< */
---
> // Spec section 4.8.1
> // For Non-secure access to ICC_PMR_EL1 SCR_EL3.FIQ == 1:
1294,1295c1274,1275
< /* Current PMR in the secure range, don't allow NS to
< * change it */
---
> // If the current priority mask value is in the range of
> // 0x00-0x7F then WI
1298a1279,1283
> // If the current priority mask value is in the range of
> // 0x80-0xFF then a write access to ICC_PMR_EL1 succeeds,
> // based on the Non-secure read of the priority mask value
> // written to the register.
>
1306,1318c1291
< case MISCREG_ICV_PMR_EL1: { // Priority Mask Register
< RegVal ich_vmcr_el2 =
< isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
< ich_vmcr_el2 = insertBits(
< ich_vmcr_el2,
< ICH_VMCR_EL2_VPMR_SHIFT + ICH_VMCR_EL2_VPMR_LENGTH - 1,
< ICH_VMCR_EL2_VPMR_SHIFT, val);
<
< isa->setMiscRegNoEffect(MISCREG_ICH_VMCR_EL2, ich_vmcr_el2);
< virtualUpdate();
< return;
< }
<
---
> // Interrupt Group 0 Enable Register EL1
1320c1293
< case MISCREG_ICC_IGRPEN0_EL1: { // Interrupt Group 0 Enable Register
---
> case MISCREG_ICC_IGRPEN0_EL1: {
1327a1301
> // Virtual Interrupt Group 0 Enable register
1330c1304
< RegVal ich_vmcr_el2 =
---
> ICH_VMCR_EL2 ich_vmcr_el2 =
1332,1333c1306
< ich_vmcr_el2 = insertBits(ich_vmcr_el2,
< ICH_VMCR_EL2_VENG0_SHIFT, enable);
---
> ich_vmcr_el2.VENG0 = enable;
1338a1312
> // Interrupt Group 1 Enable register EL1
1340c1314
< case MISCREG_ICC_IGRPEN1_EL1: { // Interrupt Group 1 Enable Register
---
> case MISCREG_ICC_IGRPEN1_EL1: {
1344a1319,1335
> if (haveEL(EL3)) {
> ICC_IGRPEN1_EL1 icc_igrpen1_el1 = val;
> ICC_IGRPEN1_EL3 icc_igrpen1_el3 =
> isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL3);
>
> if (inSecureState()) {
> // Enable is RW alias of ICC_IGRPEN1_EL3.EnableGrp1S
> icc_igrpen1_el3.EnableGrp1S = icc_igrpen1_el1.Enable;
> } else {
> // Enable is RW alias of ICC_IGRPEN1_EL3.EnableGrp1NS
> icc_igrpen1_el3.EnableGrp1NS = icc_igrpen1_el1.Enable;
> }
>
> isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL3,
> icc_igrpen1_el3);
> }
>
1347a1339
> // Virtual Interrupt Group 1 Enable register
1350c1342
< RegVal ich_vmcr_el2 =
---
> ICH_VMCR_EL2 ich_vmcr_el2 =
1352,1353c1344
< ich_vmcr_el2 = insertBits(ich_vmcr_el2,
< ICH_VMCR_EL2_VENG1_SHIFT, enable);
---
> ich_vmcr_el2.VENG1 = enable;
1358a1350
> // Interrupt Group 1 Enable register
1361,1367c1353,1366
< // EnableGrp1S and EnableGrp1NS are aliased with
< // ICC_IGRPEN1_EL1_S.Enable and ICC_IGRPEN1_EL1_NS.Enable
< bool enable_grp_1s = val & ICC_IGRPEN1_EL3_ENABLEGRP1S;
< bool enable_grp_1ns = val & ICC_IGRPEN1_EL3_ENABLEGRP1NS;
< isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S, enable_grp_1s);
< isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS, enable_grp_1ns);
< return;
---
> ICC_IGRPEN1_EL3 icc_igrpen1_el3 = val;
> ICC_IGRPEN1_EL1 icc_igrpen1_el1 =
> isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1);
>
> if (inSecureState()) {
> // ICC_IGRPEN1_EL1.Enable is RW alias of EnableGrp1S
> icc_igrpen1_el1.Enable = icc_igrpen1_el3.EnableGrp1S;
> } else {
> // ICC_IGRPEN1_EL1.Enable is RW alias of EnableGrp1NS
> icc_igrpen1_el1.Enable = icc_igrpen1_el3.EnableGrp1NS;
> }
>
> isa->setMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1, icc_igrpen1_el1);
> break;
1370c1369
< // Software Generated Interrupt Group 0 Register
---
> // Software Generated Interrupt Group 0 Register
1374c1373
< // Software Generated Interrupt Group 1 Register
---
> // Software Generated Interrupt Group 1 Register
1378c1377
< // Alias Software Generated Interrupt Group 1 Register
---
> // Alias Software Generated Interrupt Group 1 Register
1419c1418
< ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) {
---
> ((aff3 << 16) | (aff2 << 8) | (aff1 << 0))) {
1426c1425
< ((0x1 << (aff0_i - rs * 16)) & target_list))) {
---
> ((0x1 << (aff0_i - rs * 16)) & target_list))) {
1436a1436
> // System Register Enable Register EL1
1438,1467c1438,1439
< case MISCREG_ICC_SRE_EL1: { // System Register Enable Register EL1
< if (!(val & ICC_SRE_EL1_SRE)) {
< warn("Gicv3CPUInterface::setMiscReg(): "
< "ICC_SRE_EL*.SRE is RAO/WI, legacy not supported!\n");
< }
<
< bool dfb = val & ICC_SRE_EL1_DFB;
< bool dib = val & ICC_SRE_EL1_DIB;
<
< if (haveEL(EL3) && !distributor->DS) {
< // DIB is RO alias of ICC_SRE_EL3.DIB
< // DFB is RO alias of ICC_SRE_EL3.DFB
< } else if (haveEL(EL3) && distributor->DS) {
< // DIB is RW alias of ICC_SRE_EL3.DIB
< // DFB is RW alias of ICC_SRE_EL3.DFB
< RegVal icc_sre_el3 =
< isa->readMiscRegNoEffect(MISCREG_ICC_SRE_EL3);
< icc_sre_el3 = insertBits(icc_sre_el3, ICC_SRE_EL3_DFB, dfb);
< icc_sre_el3 = insertBits(icc_sre_el3, ICC_SRE_EL3_DIB, dib);
< isa->setMiscRegNoEffect(MISCREG_ICC_SRE_EL3, icc_sre_el3);
< } else if ((!haveEL(EL3) || distributor->DS) and haveEL(EL2)) {
< // DIB is RO alias of ICC_SRE_EL2.DIB
< // DFB is RO alias of ICC_SRE_EL2.DFB
< } else {
< isa->setMiscRegNoEffect(misc_reg, val);
< }
<
< return;
< }
<
---
> case MISCREG_ICC_SRE_EL1:
> // System Register Enable Register EL2
1469c1441,1442
< case MISCREG_ICC_SRE_EL2: // System Register Enable Register EL2
---
> case MISCREG_ICC_SRE_EL2:
> // System Register Enable Register EL3
1471,1476c1444
< case MISCREG_ICC_SRE_EL3: // System Register Enable Register EL3
< if (!(val & (1 << 0))) {
< warn("Gicv3CPUInterface::setMiscReg(): "
< "ICC_SRE_EL*.SRE is RAO/WI, legacy not supported!\n");
< }
<
---
> case MISCREG_ICC_SRE_EL3:
1478c1446
< break;
---
> return;
1479a1448
> // Hyp Control Register
1481,1487c1450,1476
< case MISCREG_ICH_HCR_EL2:
< val &= ICH_HCR_EL2_EN | ICH_HCR_EL2_UIE | ICH_HCR_EL2_LRENPIE |
< ICH_HCR_EL2_NPIE | ICH_HCR_EL2_VGRP0EIE |
< ICH_HCR_EL2_VGRP0DIE | ICH_HCR_EL2_VGRP1EIE |
< ICH_HCR_EL2_VGRP1DIE | ICH_HCR_EL2_TC | ICH_HCR_EL2_TALL0 |
< ICH_HCR_EL2_TALL1 | ICH_HCR_EL2_TDIR |
< ICH_HCR_EL2_EOICOUNT_MASK;
---
> case MISCREG_ICH_HCR_EL2: {
> ICH_HCR_EL2 requested_ich_hcr_el2 = val;
> ICH_HCR_EL2 ich_hcr_el2 =
> isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
>
> if (requested_ich_hcr_el2.EOIcount >= ich_hcr_el2.EOIcount)
> {
> // EOIcount - Permitted behaviors are:
> // - Increment EOIcount.
> // - Leave EOIcount unchanged.
> ich_hcr_el2.EOIcount = requested_ich_hcr_el2.EOIcount;
> }
>
> ich_hcr_el2.TDIR = requested_ich_hcr_el2.TDIR;
> ich_hcr_el2.TSEI = requested_ich_hcr_el2.TSEI;
> ich_hcr_el2.TALL1 = requested_ich_hcr_el2.TALL1;;
> ich_hcr_el2.TALL0 = requested_ich_hcr_el2.TALL0;;
> ich_hcr_el2.TC = requested_ich_hcr_el2.TC;
> ich_hcr_el2.VGrp1DIE = requested_ich_hcr_el2.VGrp1DIE;
> ich_hcr_el2.VGrp1EIE = requested_ich_hcr_el2.VGrp1EIE;
> ich_hcr_el2.VGrp0DIE = requested_ich_hcr_el2.VGrp0DIE;
> ich_hcr_el2.VGrp0EIE = requested_ich_hcr_el2.VGrp0EIE;
> ich_hcr_el2.NPIE = requested_ich_hcr_el2.NPIE;
> ich_hcr_el2.LRENPIE = requested_ich_hcr_el2.LRENPIE;
> ich_hcr_el2.UIE = requested_ich_hcr_el2.UIE;
> ich_hcr_el2.En = requested_ich_hcr_el2.En;
> val = ich_hcr_el2;
1489a1479
> }
1491c1481,1482
< case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15:
---
> // List Registers
> case MISCREG_ICH_LRC0 ... MISCREG_ICH_LRC15: {
1493,1500c1484,1510
< {
< // Enforce RES0 bits in priority field, 5 of 8 bits used
< val = insertBits(val, ICH_LRC_PRIORITY_SHIFT + 2,
< ICH_LRC_PRIORITY_SHIFT, 0);
< RegVal old_val = isa->readMiscRegNoEffect(misc_reg);
< val = (old_val & 0xffffffff) | (val << 32);
< do_virtual_update = true;
< break;
---
> ICH_LRC requested_ich_lrc = val;
> ICH_LRC ich_lrc = isa->readMiscRegNoEffect(misc_reg);
>
> ich_lrc.State = requested_ich_lrc.State;
> ich_lrc.HW = requested_ich_lrc.HW;
> ich_lrc.Group = requested_ich_lrc.Group;
>
> // Priority, bits [23:16]
> // At least five bits must be implemented.
> // Unimplemented bits are RES0 and start from bit[16] up to bit[18].
> // We implement 5 bits.
> ich_lrc.Priority = (requested_ich_lrc.Priority & 0xf8) |
> (ich_lrc.Priority & 0x07);
>
> // pINTID, bits [12:0]
> // When ICH_LR<n>.HW is 0 this field has the following meaning:
> // - Bits[12:10] : RES0.
> // - Bit[9] : EOI.
> // - Bits[8:0] : RES0.
> // When ICH_LR<n>.HW is 1:
> // - This field is only required to implement enough bits to hold a
> // valid value for the implemented INTID size. Any unused higher
> // order bits are RES0.
> if (requested_ich_lrc.HW == 0) {
> ich_lrc.EOI = requested_ich_lrc.EOI;
> } else {
> ich_lrc.pINTID = requested_ich_lrc.pINTID;
1502a1513,1518
> val = ich_lrc;
> do_virtual_update = true;
> break;
> }
>
> // List Registers
1510a1527
> // List Registers
1512,1514c1529,1564
< // Enforce RES0 bits in priority field, 5 of 8 bits used
< val = insertBits(val, ICH_LR_EL2_PRIORITY_SHIFT + 2,
< ICH_LR_EL2_PRIORITY_SHIFT, 0);
---
> ICH_LR_EL2 requested_ich_lr_el2 = val;
> ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(misc_reg);
>
> ich_lr_el2.State = requested_ich_lr_el2.State;
> ich_lr_el2.HW = requested_ich_lr_el2.HW;
> ich_lr_el2.Group = requested_ich_lr_el2.Group;
>
> // Priority, bits [55:48]
> // At least five bits must be implemented.
> // Unimplemented bits are RES0 and start from bit[48] up to bit[50].
> // We implement 5 bits.
> ich_lr_el2.Priority = (requested_ich_lr_el2.Priority & 0xf8) |
> (ich_lr_el2.Priority & 0x07);
>
> // pINTID, bits [44:32]
> // When ICH_LR<n>_EL2.HW is 0 this field has the following meaning:
> // - Bits[44:42] : RES0.
> // - Bit[41] : EOI.
> // - Bits[40:32] : RES0.
> // When ICH_LR<n>_EL2.HW is 1:
> // - This field is only required to implement enough bits to hold a
> // valid value for the implemented INTID size. Any unused higher
> // order bits are RES0.
> if (requested_ich_lr_el2.HW == 0) {
> ich_lr_el2.EOI = requested_ich_lr_el2.EOI;
> } else {
> ich_lr_el2.pINTID = requested_ich_lr_el2.pINTID;
> }
>
> // vINTID, bits [31:0]
> // It is IMPLEMENTATION DEFINED how many bits are implemented,
> // though at least 16 bits must be implemented.
> // Unimplemented bits are RES0.
> ich_lr_el2.vINTID = requested_ich_lr_el2.vINTID;
>
> val = ich_lr_el2;
1518a1569
> // Virtual Machine Control Register
1521,1528c1572,1575
< val &= ICH_VMCR_EL2_VENG0 | ICH_VMCR_EL2_VENG1 |
< ICH_VMCR_EL2_VCBPR | ICH_VMCR_EL2_VEOIM |
< ICH_VMCR_EL2_VBPR1_MASK | ICH_VMCR_EL2_VBPR0_MASK |
< ICH_VMCR_EL2_VPMR_MASK;
< val |= ICH_VMCR_EL2_VFIQEN; // RES1
< // Check VBPRs against minimun allowed value
< uint8_t vbpr0 = bits(val, 23, 21);
< uint8_t vbpr1 = bits(val, 20, 18);
---
> ICH_VMCR_EL2 requested_ich_vmcr_el2 = val;
> ICH_VMCR_EL2 ich_vmcr_el2 =
> isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
> ich_vmcr_el2.VPMR = requested_ich_vmcr_el2.VPMR;
1529a1577,1583
>
> if (requested_ich_vmcr_el2.VBPR0 < min_vpr0) {
> ich_vmcr_el2.VBPR0 = min_vpr0;
> } else {
> ich_vmcr_el2.VBPR0 = requested_ich_vmcr_el2.VBPR0;
> }
>
1531,1536c1585,1596
< vbpr0 = vbpr0 < min_vpr0 ? min_vpr0 : vbpr0;
< vbpr1 = vbpr1 < min_vpr1 ? min_vpr1 : vbpr1;
< val = insertBits(val, ICH_VMCR_EL2_VBPR0_SHIFT + 2,
< ICH_VMCR_EL2_VBPR0_SHIFT, vbpr0);
< val = insertBits(val, ICH_VMCR_EL2_VBPR1_SHIFT + 2,
< ICH_VMCR_EL2_VBPR1_SHIFT, vbpr1);
---
>
> if (requested_ich_vmcr_el2.VBPR1 < min_vpr1) {
> ich_vmcr_el2.VBPR1 = min_vpr1;
> } else {
> ich_vmcr_el2.VBPR1 = requested_ich_vmcr_el2.VBPR1;
> }
>
> ich_vmcr_el2.VEOIM = requested_ich_vmcr_el2.VEOIM;
> ich_vmcr_el2.VCBPR = requested_ich_vmcr_el2.VCBPR;
> ich_vmcr_el2.VENG1 = requested_ich_vmcr_el2.VENG1;
> ich_vmcr_el2.VENG0 = requested_ich_vmcr_el2.VENG0;
> val = ich_vmcr_el2;
1539a1600
> // Hyp Active Priorities Group 0 Registers
1541a1603
> // Hyp Active Priorities Group 1 Registers
1547,1549c1609,1610
< panic("Gicv3CPUInterface::setMiscReg(): "
< "unknown register %d (%s)",
< misc_reg, miscRegName[misc_reg]);
---
> panic("Gicv3CPUInterface::setMiscReg(): unknown register %d (%s)",
> misc_reg, miscRegName[misc_reg]);
1560c1621
< Gicv3CPUInterface::virtualFindActive(uint32_t int_id)
---
> Gicv3CPUInterface::virtualFindActive(uint32_t int_id) const
1563c1624
< RegVal lr =
---
> ICH_LR_EL2 ich_lr_el2 =
1565d1625
< uint32_t lr_intid = bits(lr, 31, 0);
1567c1627,1629
< if ((lr & ICH_LR_EL2_STATE_ACTIVE_BIT) && lr_intid == int_id) {
---
> if (((ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE) ||
> (ich_lr_el2.State == ICH_LR_EL2_STATE_ACTIVE_PENDING)) &&
> (ich_lr_el2.vINTID == int_id)) {
1576c1638
< Gicv3CPUInterface::getHPPIR0()
---
> Gicv3CPUInterface::getHPPIR0() const
1585,1587c1647
< /* Indicate to EL3 that there's a Group 1 interrupt for the
< * other state pending.
< */
---
> // interrupt for the other state pending
1604c1664
< Gicv3CPUInterface::getHPPIR1()
---
> Gicv3CPUInterface::getHPPIR1() const
1610,1612c1670,1671
< //if ((currEL() == EL3) && ICC_CTLR_EL3_RM)
< if ((currEL() == EL3) &&
< isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3) & ICC_CTLR_EL3_RM) {
---
> ICC_CTLR_EL3 icc_ctlr_el3 = isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
> if ((currEL() == EL3) && icc_ctlr_el3.RM) {
1649d1707
< /* Clear the lowest set bit */
1660,1667d1717
< /* Drop the priority of the currently active virtual interrupt
< * (favouring group 0 if there is a set active bit at
< * the same priority for both group 0 and group 1).
< * Return the priority value for the bit we just cleared,
< * or 0xff if no bits were set in the AP registers at all.
< * Note that though the ich_apr[] are uint64_t only the low
< * 32 bits are actually relevant.
< */
1682d1731
< /* Clear the lowest set bit */
1687d1735
< /* Clear the lowest set bit */
1726c1774
< RegVal lr = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
---
> ICH_LR_EL2 ich_lr_el = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
1728,1729c1776,1777
< Gicv3::GroupId group = lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;
< uint8_t prio = bits(lr, 55, 48) & 0xf8;
---
> Gicv3::GroupId group = ich_lr_el.Group ? Gicv3::G1NS : Gicv3::G0S;
> uint8_t prio = ich_lr_el.Priority & 0xf8;
1739,1741c1787,1788
< lr &= ~ICH_LR_EL2_STATE_PENDING_BIT;
< lr |= ICH_LR_EL2_STATE_ACTIVE_BIT;
< isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, lr);
---
> ich_lr_el.State = ICH_LR_EL2_STATE_ACTIVE;
> isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el);
1763c1810
< RegVal lr = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
---
> ICH_LR_EL2 ich_lr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 +
1766c1813
< if (lr & ICH_LR_EL2_HW) {
---
> if (ich_lr_el2.HW) {
1768,1774c1815,1819
< int pintid = bits(lr, 41, 32);
<
< if (pintid < Gicv3::INTID_SECURE) {
< Gicv3::GroupId group =
< pintid >= 32 ? distributor->getIntGroup(pintid) :
< redistributor->getIntGroup(pintid);
< deactivateIRQ(pintid, group);
---
> if (ich_lr_el2.pINTID < Gicv3::INTID_SECURE) {
> Gicv3::GroupId group = ich_lr_el2.pINTID >= 32 ?
> distributor->getIntGroup(ich_lr_el2.pINTID) :
> redistributor->getIntGroup(ich_lr_el2.pINTID);
> deactivateIRQ(ich_lr_el2.pINTID, group);
1779,1780c1824,1825
< lr &= ~ICH_LR_EL2_STATE_ACTIVE_BIT;
< isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, lr);
---
> ich_lr_el2.State = ich_lr_el2.State & ~ICH_LR_EL2_STATE_ACTIVE;
> isa->setMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx, ich_lr_el2);
1784,1801c1829,1830
< * Return a mask word which clears the subpriority bits from
< * a priority value for an interrupt in the specified group.
< * This depends on the BPR value. For CBPR0 (S or NS):
< * a BPR of 0 means the group priority bits are [7:1];
< * a BPR of 1 means they are [7:2], and so on down to
< * ...
< * a BPR of 7 meaning no group priority bits at all.
< * For CBPR1 NS:
< * a BPR of 0 is impossible (the minimum value is 1)
< * a BPR of 1 means the group priority bits are [7:1];
< * a BPR of 2 means they are [7:2], and so on down to
< * ...
< * a BPR of 7 meaning the group priority is [7].
< *
< * Which BPR to use depends on the group of the interrupt and
< * the current ICC_CTLR.CBPR settings.
< *
< * This corresponds to the GroupBits() pseudocode from 4.8.2.
---
> * Returns the priority group field for the current BPR value for the group.
> * GroupBits() Pseudocode from spec.
1804c1833
< Gicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group)
---
> Gicv3CPUInterface::groupPriorityMask(Gicv3::GroupId group) const
1806,1811c1835,1841
< if ((group == Gicv3::G1S &&
< isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S)
< & ICC_CTLR_EL1_CBPR) ||
< (group == Gicv3::G1NS &&
< isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS)
< & ICC_CTLR_EL1_CBPR)) {
---
> ICC_CTLR_EL1 icc_ctlr_el1_s =
> isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_S);
> ICC_CTLR_EL1 icc_ctlr_el1_ns =
> isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1_NS);
>
> if ((group == Gicv3::G1S && icc_ctlr_el1_s.CBPR) ||
> (group == Gicv3::G1NS && icc_ctlr_el1_ns.CBPR)) {
1832c1862
< Gicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group)
---
> Gicv3CPUInterface::virtualGroupPriorityMask(Gicv3::GroupId group) const
1834c1864
< RegVal ich_vmcr_el2 =
---
> ICH_VMCR_EL2 ich_vmcr_el2 =
1837c1867
< if (group == Gicv3::G1NS && (ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR)) {
---
> if ((group == Gicv3::G1NS) && ich_vmcr_el2.VCBPR) {
1844c1874
< bpr = bits(ich_vmcr_el2, 23, 21);
---
> bpr = ich_vmcr_el2.VBPR0;
1846c1876
< bpr = bits(ich_vmcr_el2, 20, 18);
---
> bpr = ich_vmcr_el2.VBPR1;
1858c1888
< Gicv3CPUInterface::isEOISplitMode()
---
> Gicv3CPUInterface::isEOISplitMode() const
1861,1862c1891,1893
< return isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3) &
< ICC_CTLR_EL3_EOIMODE_EL3;
---
> ICC_CTLR_EL3 icc_ctlr_el3 =
> isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL3);
> return icc_ctlr_el3.EOImode_EL3;
1864,1865c1895,1897
< return isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1) &
< ICC_CTLR_EL1_EOIMODE;
---
> ICC_CTLR_EL1 icc_ctlr_el1 =
> isa->readMiscRegNoEffect(MISCREG_ICC_CTLR_EL1);
> return icc_ctlr_el1.EOImode;
1870c1902
< Gicv3CPUInterface::virtualIsEOISplitMode()
---
> Gicv3CPUInterface::virtualIsEOISplitMode() const
1872,1873c1904,1905
< RegVal ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
< return ich_vmcr_el2 & ICH_VMCR_EL2_VEOIM;
---
> ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
> return ich_vmcr_el2.VEOIM;
1877c1909
< Gicv3CPUInterface::highestActiveGroup()
---
> Gicv3CPUInterface::highestActiveGroup() const
1940c1972
< RegVal ich_lr_el2 =
---
> ICH_LR_EL2 ich_lr_el2 =
1944c1976
< if (ich_lr_el2 & ICH_LR_EL2_GROUP) {
---
> if (ich_lr_el2.Group) {
1952c1984
< RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
---
> ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
1954c1986
< if (ich_hcr_el2 & ICH_HCR_EL2_EN) {
---
> if (ich_hcr_el2.En) {
1977c2009
< // Returns the intex of the LR with the HPPI
---
> // Returns the index of the LR with the HPPI
1979c2011
< Gicv3CPUInterface::getHPPVILR()
---
> Gicv3CPUInterface::getHPPVILR() const
1982c2014
< RegVal ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
---
> ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1984c2016
< if (!(ich_vmcr_el2 & (ICH_VMCR_EL2_VENG0 | ICH_VMCR_EL2_VENG1))) {
---
> if (!ich_vmcr_el2.VENG0 && !ich_vmcr_el2.VENG1) {
1992c2024
< RegVal ich_lri_el2 =
---
> ICH_LR_EL2 ich_lr_el2 =
1994d2025
< uint8_t state = bits(ich_lri_el2, 63, 62);
1996c2027
< if (state != Gicv3::INT_PENDING) {
---
> if (ich_lr_el2.State != Gicv3::INT_PENDING) {
2000c2031
< if (ich_lri_el2 & ICH_LR_EL2_GROUP) {
---
> if (ich_lr_el2.Group) {
2002c2033
< if (!(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
---
> if (!ich_vmcr_el2.VENG1) {
2007c2038
< if (!(ich_vmcr_el2 & ICH_VMCR_EL2_VENG0)) {
---
> if (!ich_vmcr_el2.VENG0) {
2012c2043
< uint8_t prio = bits(ich_lri_el2, 55, 48);
---
> uint8_t prio = ich_lr_el2.Priority;
2024c2055
< Gicv3CPUInterface::hppviCanPreempt(int lr_idx)
---
> Gicv3CPUInterface::hppviCanPreempt(int lr_idx) const
2026,2028c2057,2058
< RegVal lr = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
<
< if (!(isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2) & ICH_HCR_EL2_EN)) {
---
> ICH_HCR_EL2 ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
> if (!ich_hcr_el2.En) {
2033c2063,2065
< uint8_t prio = bits(lr, 55, 48);
---
> ICH_LR_EL2 ich_lr_el2 =
> isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
> uint8_t prio = ich_lr_el2.Priority;
2048c2080
< Gicv3::GroupId group = lr & ICH_LR_EL2_GROUP ? Gicv3::G1NS : Gicv3::G0S;
---
> Gicv3::GroupId group = ich_lr_el2.Group ? Gicv3::G1NS : Gicv3::G0S;
2059c2091
< Gicv3CPUInterface::virtualHighestActivePriority()
---
> Gicv3CPUInterface::virtualHighestActivePriority() const
2090,2093c2122
< /*
< * Should we signal the interrupt as IRQ or FIQ?
< * see spec section 4.6.2
< */
---
> // spec section 4.6.2
2095c2124
< Gicv3CPUInterface::intSignalType(Gicv3::GroupId group)
---
> Gicv3CPUInterface::intSignalType(Gicv3::GroupId group) const
2125c2154
< Gicv3CPUInterface::hppiCanPreempt()
---
> Gicv3CPUInterface::hppiCanPreempt() const
2158c2187
< Gicv3CPUInterface::highestActivePriority()
---
> Gicv3CPUInterface::highestActivePriority() const
2173c2202
< Gicv3CPUInterface::groupEnabled(Gicv3::GroupId group)
---
> Gicv3CPUInterface::groupEnabled(Gicv3::GroupId group) const
2176,2178c2205,2209
< case Gicv3::G0S:
< return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1) &
< ICC_IGRPEN0_EL1_ENABLE;
---
> case Gicv3::G0S: {
> ICC_IGRPEN0_EL1 icc_igrpen0_el1 =
> isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN0_EL1);
> return icc_igrpen0_el1.Enable;
> }
2180,2189c2211,2215
< case Gicv3::G1S:
< //if (distributor->DS)
< //{
< // return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS) &
< // ICC_IGRPEN1_EL1_ENABLE;
< //}
< //else
< //{
< return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S) &
< ICC_IGRPEN1_EL1_ENABLE;
---
> case Gicv3::G1S: {
> ICC_IGRPEN1_EL1 icc_igrpen1_el1_s =
> isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_S);
> return icc_igrpen1_el1_s.Enable;
> }
2191c2217,2221
< //}
---
> case Gicv3::G1NS: {
> ICC_IGRPEN1_EL1 icc_igrpen1_el1_ns =
> isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS);
> return icc_igrpen1_el1_ns.Enable;
> }
2193,2196d2222
< case Gicv3::G1NS:
< return isa->readMiscRegNoEffect(MISCREG_ICC_IGRPEN1_EL1_NS) &
< ICC_IGRPEN1_EL1_ENABLE;
<
2203c2229
< Gicv3CPUInterface::inSecureState()
---
> Gicv3CPUInterface::inSecureState() const
2215c2241
< Gicv3CPUInterface::currEL()
---
> Gicv3CPUInterface::currEL() const
2240c2266
< Gicv3CPUInterface::haveEL(ExceptionLevel el)
---
> Gicv3CPUInterface::haveEL(ExceptionLevel el) const
2260c2286
< Gicv3CPUInterface::isSecureBelowEL3()
---
> Gicv3CPUInterface::isSecureBelowEL3() const
2267c2293
< Gicv3CPUInterface::isAA64()
---
> Gicv3CPUInterface::isAA64() const
2274c2300
< Gicv3CPUInterface::isEL3OrMon()
---
> Gicv3CPUInterface::isEL3OrMon() const
2290,2291c2316,2318
< uint32_t
< Gicv3CPUInterface::eoiMaintenanceInterruptStatus(uint32_t * misr)
---
> // Computes ICH_EISR_EL2
> uint64_t
> Gicv3CPUInterface::eoiMaintenanceInterruptStatus() const
2293,2302c2320,2333
< /* Return a set of bits indicating the EOI maintenance interrupt status
< * for each list register. The EOI maintenance interrupt status is
< * 1 if LR.State == 0 && LR.HW == 0 && LR.EOI == 1
< * (see the GICv3 spec for the ICH_EISR_EL2 register).
< * If misr is not NULL then we should also collect the information
< * about the MISR.EOI, MISR.NP and MISR.U bits.
< */
< uint32_t value = 0;
< int valid_count = 0;
< bool seen_pending = false;
---
> // ICH_EISR_EL2
> // Bits [63:16] - RES0
> // Status<n>, bit [n], for n = 0 to 15
> // EOI maintenance interrupt status bit for List register <n>:
> // 0 if List register <n>, ICH_LR<n>_EL2, does not have an EOI
> // maintenance interrupt.
> // 1 if List register <n>, ICH_LR<n>_EL2, has an EOI maintenance
> // interrupt that has not been handled.
> //
> // For any ICH_LR<n>_EL2, the corresponding status bit is set to 1 if all
> // of the following are true:
> // - ICH_LR<n>_EL2.State is 0b00 (ICH_LR_EL2_STATE_INVALID).
> // - ICH_LR<n>_EL2.HW is 0.
> // - ICH_LR<n>_EL2.EOI (bit [41]) is 1.
2303a2335,2336
> uint64_t value = 0;
>
2305c2338,2339
< RegVal lr = isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
---
> ICH_LR_EL2 ich_lr_el2 =
> isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2307,2308c2341,2342
< if ((lr & (ICH_LR_EL2_STATE_MASK | ICH_LR_EL2_HW | ICH_LR_EL2_EOI)) ==
< ICH_LR_EL2_EOI) {
---
> if ((ich_lr_el2.State == ICH_LR_EL2_STATE_INVALID) &&
> !ich_lr_el2.HW && ich_lr_el2.EOI) {
2310a2345
> }
2312,2314c2347,2348
< if ((lr & ICH_LR_EL2_STATE_MASK)) {
< valid_count++;
< }
---
> return value;
> }
2316,2319c2350,2365
< if (bits(lr, ICH_LR_EL2_STATE_SHIFT + ICH_LR_EL2_STATE_LENGTH,
< ICH_LR_EL2_STATE_SHIFT) == ICH_LR_EL2_STATE_PENDING) {
< seen_pending = true;
< }
---
> Gicv3CPUInterface::ICH_MISR_EL2
> Gicv3CPUInterface::maintenanceInterruptStatus() const
> {
> // Comments are copied from SPEC section 9.4.7 (ID012119)
> ICH_MISR_EL2 ich_misr_el2 = 0;
> ICH_HCR_EL2 ich_hcr_el2 =
> isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
> ICH_VMCR_EL2 ich_vmcr_el2 =
> isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
>
> // End Of Interrupt. [bit 0]
> // This maintenance interrupt is asserted when at least one bit in
> // ICH_EISR_EL2 is 1.
>
> if (eoiMaintenanceInterruptStatus()) {
> ich_misr_el2.EOI = 1;
2322,2324c2368,2374
< if (misr) {
< RegVal ich_hcr_el2 =
< isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
---
> // Underflow. [bit 1]
> // This maintenance interrupt is asserted when ICH_HCR_EL2.UIE==1 and
> // zero or one of the List register entries are marked as a valid
> // interrupt, that is, if the corresponding ICH_LR<n>_EL2.State bits
> // do not equal 0x0.
> uint32_t num_valid_interrupts = 0;
> uint32_t num_pending_interrupts = 0;
2326,2328c2376,2378
< if (valid_count < 2 && (ich_hcr_el2 & ICH_HCR_EL2_UIE)) {
< *misr |= ICH_MISR_EL2_U;
< }
---
> for (int lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
> ICH_LR_EL2 ich_lr_el2 =
> isa->readMiscRegNoEffect(MISCREG_ICH_LR0_EL2 + lr_idx);
2330,2331c2380,2381
< if (!seen_pending && (ich_hcr_el2 & ICH_HCR_EL2_NPIE)) {
< *misr |= ICH_MISR_EL2_NP;
---
> if (ich_lr_el2.State != ICH_LR_EL2_STATE_INVALID) {
> num_valid_interrupts++;
2334,2335c2384,2385
< if (value) {
< *misr |= ICH_MISR_EL2_EOI;
---
> if (ich_lr_el2.State == ICH_LR_EL2_STATE_PENDING) {
> num_pending_interrupts++;
2339,2340c2389,2391
< return value;
< }
---
> if (ich_hcr_el2.UIE && (num_valid_interrupts < 2)) {
> ich_misr_el2.U = 1;
> }
2342,2352c2393,2398
< uint32_t
< Gicv3CPUInterface::maintenanceInterruptStatus()
< {
< /* Return a set of bits indicating the maintenance interrupt status
< * (as seen in the ICH_MISR_EL2 register).
< */
< uint32_t value = 0;
< /* Scan list registers and fill in the U, NP and EOI bits */
< eoiMaintenanceInterruptStatus(&value);
< RegVal ich_hcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_HCR_EL2);
< RegVal ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
---
> // List Register Entry Not Present. [bit 2]
> // This maintenance interrupt is asserted when ICH_HCR_EL2.LRENPIE==1
> // and ICH_HCR_EL2.EOIcount is non-zero.
> if (ich_hcr_el2.LRENPIE && ich_hcr_el2.EOIcount) {
> ich_misr_el2.LRENP = 1;
> }
2354,2355c2400,2404
< if (ich_hcr_el2 & (ICH_HCR_EL2_LRENPIE | ICH_HCR_EL2_EOICOUNT_MASK)) {
< value |= ICH_MISR_EL2_LRENP;
---
> // No Pending. [bit 3]
> // This maintenance interrupt is asserted when ICH_HCR_EL2.NPIE==1 and
> // no List register is in pending state.
> if (ich_hcr_el2.NPIE && (num_pending_interrupts == 0)) {
> ich_misr_el2.NP = 1;
2358,2360c2407,2411
< if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP0EIE) &&
< (ich_vmcr_el2 & ICH_VMCR_EL2_VENG0)) {
< value |= ICH_MISR_EL2_VGRP0E;
---
> // vPE Group 0 Enabled. [bit 4]
> // This maintenance interrupt is asserted when
> // ICH_HCR_EL2.VGrp0EIE==1 and ICH_VMCR_EL2.VENG0==1.
> if (ich_hcr_el2.VGrp0EIE && ich_vmcr_el2.VENG0) {
> ich_misr_el2.VGrp0E = 1;
2363,2365c2414,2418
< if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP0DIE) &&
< !(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
< value |= ICH_MISR_EL2_VGRP0D;
---
> // vPE Group 0 Disabled. [bit 5]
> // This maintenance interrupt is asserted when
> // ICH_HCR_EL2.VGrp0DIE==1 and ICH_VMCR_EL2.VENG0==0.
> if (ich_hcr_el2.VGrp0DIE && !ich_vmcr_el2.VENG0) {
> ich_misr_el2.VGrp0D = 1;
2368,2370c2421,2425
< if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP1EIE) &&
< (ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
< value |= ICH_MISR_EL2_VGRP1E;
---
> // vPE Group 1 Enabled. [bit 6]
> // This maintenance interrupt is asserted when
> // ICH_HCR_EL2.VGrp1EIE==1 and ICH_VMCR_EL2.VENG1==is 1.
> if (ich_hcr_el2.VGrp1EIE && ich_vmcr_el2.VENG1) {
> ich_misr_el2.VGrp1E = 1;
2373,2375c2428,2432
< if ((ich_hcr_el2 & ICH_HCR_EL2_VGRP1DIE) &&
< !(ich_vmcr_el2 & ICH_VMCR_EL2_VENG1)) {
< value |= ICH_MISR_EL2_VGRP1D;
---
> // vPE Group 1 Disabled. [bit 7]
> // This maintenance interrupt is asserted when
> // ICH_HCR_EL2.VGrp1DIE==1 and ICH_VMCR_EL2.VENG1==is 0.
> if (ich_hcr_el2.VGrp1DIE && !ich_vmcr_el2.VENG1) {
> ich_misr_el2.VGrp1D = 1;
2378c2435
< return value;
---
> return ich_misr_el2;