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