gem5  v19.0.0.0
gic_v3_cpu_interface.cc
Go to the documentation of this file.
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 
44 
45 #include "arch/arm/isa.hh"
46 #include "debug/GIC.hh"
47 #include "dev/arm/gic_v3.hh"
50 
51 const uint8_t Gicv3CPUInterface::GIC_MIN_BPR;
53 
55  : BaseISADevice(),
56  gic(gic),
57  redistributor(nullptr),
58  distributor(nullptr),
59  cpuId(cpu_id)
60 {
61  hppi.prio = 0xff;
63 }
64 
65 void
67 {
70 }
71 
72 void
74 {
75  if (intid == hppi.intid)
76  hppi.prio = 0xff;
77 }
78 
79 void
81 {
82  maintenanceInterrupt = gic->params()->maint_int->get(tc);
83 }
84 
85 bool
87 {
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 
99 bool
101 {
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 
113 RegVal
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) {
126  }
127 
129  }
130 
131  case MISCREG_ICC_AP1R1:
133 
134  // only implemented if supporting 6 or more bits of priority
135  case MISCREG_ICC_AP1R2:
137 
138  // only implemented if supporting 7 or more bits of priority
139  case MISCREG_ICC_AP1R3:
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) {
149  }
150 
151  break;
152  }
153 
154  case MISCREG_ICC_AP0R1:
156 
157  // only implemented if supporting 6 or more bits of priority
158  case MISCREG_ICC_AP0R2:
160 
161  // only implemented if supporting 7 or more bits of priority
162  case MISCREG_ICC_AP0R3:
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:
170  if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
172  }
173 
174  break;
175  }
176 
178  ICH_VMCR_EL2 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:
187  if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
189  }
190 
192  break;
193  }
194 
196  ICH_VMCR_EL2 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:
205  ICC_IGRPEN1_EL3 igrp_el3 = 0;
206  igrp_el3.EnableGrp1S = ((ICC_IGRPEN1_EL1)isa->readMiscRegNoEffect(
208 
209  igrp_el3.EnableGrp1NS = ((ICC_IGRPEN1_EL1)isa->readMiscRegNoEffect(
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)) {
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: {
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) {
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 =
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) {
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 =
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) {
317  }
318 
320  break;
321  }
322 
323  // Binary Point Register 1
324  case MISCREG_ICC_BPR1:
325  case MISCREG_ICC_BPR1_EL1: {
327  break;
328  }
329 
330  // Virtual Binary Point Register 0
331  case MISCREG_ICV_BPR0_EL1: {
332  ICH_VMCR_EL2 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 =
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)) {
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 =
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) {
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 ||
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 =
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;
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) {
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 ||
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 =
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;
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)) {
561  }
562 
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:
627  break;
628 
629  // only implemented if supporting 6 or more bits of priority
630  case MISCREG_ICH_AP0R1:
632  // only implemented if supporting 7 or more bits of priority
633  case MISCREG_ICH_AP0R2:
635  // only implemented if supporting 7 or more bits of priority
636  case MISCREG_ICH_AP0R3:
638  // Unimplemented registers are RAZ/WI
639  return 0;
640 
641  // Hyp Active Priorities Group 1 Registers
642  case MISCREG_ICH_AP1R0:
644  break;
645 
646  // only implemented if supporting 6 or more bits of priority
647  case MISCREG_ICH_AP1R1:
649  // only implemented if supporting 7 or more bits of priority
650  case MISCREG_ICH_AP1R2:
652  // only implemented if supporting 7 or more bits of priority
653  case MISCREG_ICH_AP1R3:
655  // Unimplemented registers are RAZ/WI
656  return 0;
657 
658  // Maintenance Interrupt State Register
659  case MISCREG_ICH_MISR:
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:
683  break;
684 
685  // Empty List Register Status Register
686  case MISCREG_ICH_ELRSR:
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 =
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
704  // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 high half part)
705  value = value >> 32;
706  break;
707 
708  // List Registers
710  // AArch32 (maps to AArch64 MISCREG_ICH_LR<n>_EL2 low half part)
711  value = value & 0xffffffff;
712  break;
713 
714  // List Registers
716  break;
717 
718  // Virtual Machine Control Register
719  case MISCREG_ICH_VMCR:
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 
733 void
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:
746  if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
748  }
749 
751  return;
752 
753  case MISCREG_ICC_AP1R1:
755 
756  // only implemented if supporting 6 or more bits of priority
757  case MISCREG_ICC_AP1R2:
759 
760  // only implemented if supporting 7 or more bits of priority
761  case MISCREG_ICC_AP1R3:
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:
769  if ((currEL() == EL1) && !inSecureState() && hcr_fmo) {
771  }
772 
773  break;
774 
775  case MISCREG_ICC_AP0R1:
777 
778  // only implemented if supporting 6 or more bits of priority
779  case MISCREG_ICC_AP0R2:
781 
782  // only implemented if supporting 7 or more bits of priority
783  case MISCREG_ICC_AP0R3:
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
839  } else {
840  ICH_LR_EL2 ich_lr_el2 =
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 
874 
875  if (highestActiveGroup() == Gicv3::G0S) {
876  return;
877  }
878 
879  if (distributor->DS == 0) {
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
918  } else {
919  ICH_LR_EL2 ich_lr_el2 =
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
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 =
1067 
1068  val = val > GIC_MIN_BPR ? val : GIC_MIN_BPR;
1069  if (haveEL(EL3) && !isEL3OrMon() && icc_ctlr_el1_s.CBPR) {
1071  } else {
1073  }
1074  return;
1075  } else {
1076  // group == Gicv3::G1NS
1077  ICC_CTLR_EL1 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 {
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 =
1098  ICH_VMCR_EL2 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 
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 =
1145 
1146  ICC_CTLR_EL3 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 
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 =
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 =
1220  ich_vmcr_el2.VCBPR = icv_ctlr_el1.CBPR;
1221  ich_vmcr_el2.VEOIM = icv_ctlr_el1.EOImode;
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 =
1246  ICC_CTLR_EL1 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);
1262  icc_ctlr_el1_ns);
1263  }
1264 
1265  ICC_CTLR_EL3 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 =
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 =
1316  ich_vmcr_el2.VPMR = val & 0xff;
1317 
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 
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 =
1340  ich_vmcr_el2.VENG0 = enable;
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 
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 =
1363  ich_vmcr_el2.VENG1 = enable;
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 
1375  MISCREG_ICC_IGRPEN1_EL1_S, icc_igrpen1_el3.EnableGrp1S);
1377  MISCREG_ICC_IGRPEN1_EL1_NS, icc_igrpen1_el3.EnableGrp1NS);
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: {
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: {
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 =
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
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 =
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 
1616 RegVal
1618 {
1619  return isa->readMiscRegNoEffect(
1620  isa->snsBankedIndex64(misc_reg, !isSecureBelowEL3()));
1621 }
1622 
1623 void
1625 {
1627  isa->snsBankedIndex64(misc_reg, !isSecureBelowEL3()), val);
1628 }
1629 
1630 int
1632 {
1633  for (uint32_t lr_idx = 0; lr_idx < VIRTUAL_NUM_LIST_REGS; lr_idx++) {
1634  ICH_LR_EL2 ich_lr_el2 =
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 
1647 uint32_t
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 
1673 uint32_t
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 
1708 void
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 
1737 uint8_t
1739 {
1740  int apr_max = 1 << (VIRTUAL_PREEMPTION_BITS - 5);
1741 
1742  for (int i = 0; i < apr_max; 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;
1756  return (vapr0_count + i * 32) << (GIC_MIN_VBPR + 1);
1757  } else {
1758  vapr1 &= vapr1 - 1;
1760  return (vapr1_count + i * 32) << (GIC_MIN_VBPR + 1);
1761  }
1762  }
1763 
1764  return 0xff;
1765 }
1766 
1767 void
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 =
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 
1811 void
1812 Gicv3CPUInterface::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);
1855 }
1856 
1857 void
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 
1878 void
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 
1890 }
1891 
1892 void
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  */
1917 uint32_t
1919 {
1920  ICC_CTLR_EL1 icc_ctlr_el1_s =
1922  ICC_CTLR_EL1 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 
1948 uint32_t
1950 {
1951  ICH_VMCR_EL2 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 
1974 bool
1976 {
1977  if (isEL3OrMon()) {
1978  ICC_CTLR_EL3 icc_ctlr_el3 =
1980  return icc_ctlr_el3.EOImode_EL3;
1981  } else {
1982  ICC_CTLR_EL1 icc_ctlr_el1 = 0;
1983  if (inSecureState())
1985  else
1987  return icc_ctlr_el1.EOImode;
1988  }
1989 }
1990 
1991 bool
1993 {
1994  ICH_VMCR_EL2 ich_vmcr_el2 = isa->readMiscRegNoEffect(MISCREG_ICH_VMCR_EL2);
1995  return ich_vmcr_el2.VEOIM;
1996 }
1997 
1998 int
2000 {
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 
2020 void
2022 {
2023  distributor->update();
2024 }
2025 
2026 void
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()) {
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) {
2049  } else {
2051  }
2052 
2053  if (signal_FIQ) {
2055  } else {
2057  }
2058 }
2059 
2060 void
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 =
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) {
2085  }
2086  }
2087 
2088  if (signal_IRQ) {
2089  DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
2090  "posting int as %d!\n", ArmISA::INT_VIRT_IRQ);
2092  } else {
2094  }
2095 
2096  if (signal_FIQ) {
2097  DPRINTF(GIC, "Gicv3CPUInterface::virtualUpdate(): "
2098  "posting int as %d!\n", ArmISA::INT_VIRT_FIQ);
2100  } else {
2102  }
2103 }
2104 
2105 // Returns the index of the LR with the HPPI
2106 int
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 =
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 
2150 bool
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 =
2161  uint8_t prio = ich_lr_el2.Priority;
2162  uint8_t vpmr =
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 
2186 uint8_t
2188 {
2189  uint8_t num_aprs = 1 << (VIRTUAL_PRIORITY_BITS - 5);
2190 
2191  for (int i = 0; i < num_aprs; i++) {
2192  RegVal vapr =
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 
2207 void
2209 {
2210  // Increment the EOICOUNT field in 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);
2216 }
2217 
2218 // spec section 4.6.2
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 
2249 bool
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 
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 
2282 uint8_t
2284 {
2285  uint32_t apr = isa->readMiscRegNoEffect(MISCREG_ICC_AP0R0_EL1) |
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 
2297 bool
2299 {
2300  switch (group) {
2301  case Gicv3::G0S: {
2302  ICC_IGRPEN0_EL1 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 =
2310  return icc_igrpen1_el1_s.Enable && distributor->EnableGrp1S;
2311  }
2312 
2313  case Gicv3::G1NS: {
2314  ICC_IGRPEN1_EL1 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 
2324 bool
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 
2336 int
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 
2361 bool
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 
2381 bool
2383 {
2385  return haveEL(EL3) && scr.ns == 0;
2386 }
2387 
2388 bool
2390 {
2391  CPSR cpsr = isa->readMiscRegNoEffect(MISCREG_CPSR);
2392  return opModeIs64((OperatingMode)(uint8_t) cpsr.mode);
2393 }
2394 
2395 bool
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
2413 uint64_t
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 =
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 
2446 Gicv3CPUInterface::ICH_MISR_EL2
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 =
2453  ICH_VMCR_EL2 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 
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 =
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 
2534 RegVal
2536 {
2537  bool hcr_imo = getHCREL2IMO();
2538  if ((currEL() == EL1) && !inSecureState() && hcr_imo) {
2540  }
2541 
2542  RegVal bpr = 0;
2543 
2544  if (group == Gicv3::G1S) {
2545  ICC_CTLR_EL1 icc_ctlr_el1_s =
2547 
2548  if (!isEL3OrMon() && icc_ctlr_el1_s.CBPR) {
2550  } else {
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 =
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
2563  bpr = bpr < 7 ? bpr : 7;
2564  } else {
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 
2575 void
2577 {
2581 }
2582 
2583 void
2585 {
2589 }
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
void deactivateIRQ(uint32_t int_id)
#define DPRINTF(x,...)
Definition: trace.hh:229
int ctz32(uint32_t value)
Count trailing zeros in a 32-bit value.
Definition: bitfield.hh:298
static const uint64_t ICH_LR_EL2_STATE_ACTIVE
void setThreadContext(ThreadContext *tc) override
MiscRegIndex
Definition: miscregs.hh:57
static const int PPI_MAX
Definition: gic_v3.hh:80
Definition: gic_v3.hh:54
void virtualActivateIRQ(uint32_t lrIdx)
Bitfield< 7 > i
static const uint8_t GIC_MIN_BPR_NS
bool haveSecurity() const
Returns true if this system implements the Security Extensions.
Definition: system.hh:185
RegVal bpr1(Gicv3::GroupId group)
static const uint64_t ICH_LR_EL2_STATE_PENDING
RegVal readMiscRegNoEffect(int misc_reg) const
Definition: isa.cc:437
const Params * params() const
Definition: gic_v3.hh:116
void setMiscReg(int misc_reg, RegVal val) override
Write to a system register belonging to this device.
RegVal readMiscReg(int misc_reg) override
Read a system register belonging to this device.
OperatingMode
Definition: types.hh:592
Base class for devices that use the MiscReg interfaces.
Definition: isa_device.hh:60
uint64_t RegVal
Definition: types.hh:168
void deactivateIRQ(uint32_t intid, Gicv3::GroupId group)
const char *const miscRegName[]
Definition: miscregs.hh:1021
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: cprintf.cc:42
uint32_t virtualGroupPriorityMask(Gicv3::GroupId group) const
InterruptTypes
Definition: isa_traits.hh:104
void resetHppi(uint32_t intid)
static const int INTID_NONSECURE
Definition: gic_v3.hh:74
ThreadContext is the external interface to all thread state for anything outside of the CPU...
uint64_t eoiMaintenanceInterruptStatus() const
Bitfield< 63 > val
Definition: misc.hh:771
ExceptionLevel
Definition: types.hh:585
static const int SGI_MAX
Definition: gic_v3.hh:78
void setMiscRegNoEffect(int misc_reg, RegVal val)
Definition: isa.cc:768
uint32_t groupPriorityMask(Gicv3::GroupId group)
void deassertInt(uint32_t cpu, ArmISA::InterruptTypes int_type)
Definition: gic_v3.cc:220
static const uint8_t VIRTUAL_NUM_LIST_REGS
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:645
Bitfield< 0 > ns
uint8_t virtualHighestActivePriority() const
Bitfield< 11 > enable
Definition: misc.hh:1053
Bitfield< 3, 2 > el
int snsBankedIndex64(MiscRegIndex reg, bool ns) const
Definition: isa.hh:693
uint32_t getHPPIR1() const
Gicv3Distributor * distributor
void serialize(CheckpointOut &cp) const override
Serialize an object.
static const uint8_t GIC_MIN_VBPR
uint8_t highestActivePriority() const
void activateIRQ(uint32_t int_id)
static const uint8_t VIRTUAL_PREEMPTION_BITS
int64 int_type
Definition: sc_nbdefs.hh:206
static const uint8_t VIRTUAL_PRIORITY_BITS
void setClrLPI(uint64_t data, bool set)
unsigned numContexts() const
Definition: system.hh:206
void activateIRQ(uint32_t int_id)
T insertBits(T val, int first, int last, B bit_val)
Returns val with bits first to last set to the LSBs of bit_val.
Definition: bitfield.hh:132
GroupId
Definition: gic_v3.hh:91
static const int INTID_SPURIOUS
Definition: gic_v3.hh:75
Gicv3Redistributor * getRedistributor(ContextID context_id) const
Definition: gic_v3.hh:149
bool haveVirtualization() const
Returns true if this system implements the virtualization Extensions.
Definition: system.hh:194
Gicv3Distributor * distributor
static const uint8_t GIC_MIN_BPR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:643
RegVal readBankedMiscReg(MiscRegIndex misc_reg) const
#define UNSERIALIZE_ENUM(scalar)
Definition: serialize.hh:651
static const uint32_t SMALLEST_LPI_ID
bool groupEnabled(Gicv3::GroupId group) const
Gicv3::GroupId getIntGroup(int int_id) const
int virtualFindActive(uint32_t intid) const
virtual void raise()=0
Signal an interrupt.
std::ostream CheckpointOut
Definition: serialize.hh:68
bool virtualIsEOISplitMode() const
Gicv3CPUInterface(Gicv3 *gic, uint32_t cpu_id)
void postInt(uint32_t cpu, ArmISA::InterruptTypes int_type)
Definition: gic_v3.cc:207
ArmISA::InterruptTypes intSignalType(Gicv3::GroupId group) const
void dropPriority(Gicv3::GroupId group)
Bitfield< 27, 24 > gic
bool hppviCanPreempt(int lrIdx) const
bool haveEL(ArmISA::ExceptionLevel el) const
ICH_MISR_EL2 maintenanceInterruptStatus() const
ArmInterruptPin * maintenanceInterrupt
EndBitUnion(ICV_CTLR_EL1) protected void generateSGI(RegVal val, Gicv3::GroupId group)
#define warn(...)
Definition: logging.hh:212
uint32_t getAffinity() const
Gicv3::GroupId getIntGroup(int int_id) const
void setBankedMiscReg(MiscRegIndex misc_reg, RegVal val) const
bool inSecureState(ThreadContext *tc)
Definition: utility.cc:195
uint32_t getHPPIR0() const
T bits(T val, int first, int last)
Extract the bitfield from position &#39;first&#39; to &#39;last&#39; (inclusive) from &#39;val&#39; and right justify it...
Definition: bitfield.hh:72
ArmSystem * getSystem() const
Definition: base_gic.hh:106
Bitfield< 9, 8 > rs
static const uint64_t ICH_LR_EL2_STATE_ACTIVE_PENDING
#define SERIALIZE_ENUM(scalar)
Definition: serialize.hh:649
void virtualDeactivateIRQ(int lrIdx)
Gicv3Redistributor * redistributor
void sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns)
void deactivateIRQ(uint32_t int_id)
static const int INTID_SECURE
Definition: gic_v3.hh:73
Gicv3Distributor * getDistributor() const
Definition: gic_v3.hh:143

Generated on Fri Feb 28 2020 16:27:00 for gem5 by doxygen 1.8.13