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