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