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