gem5  v20.1.0.0
gic_v3_redistributor.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019-2020 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 
42 
43 #include "arch/arm/utility.hh"
44 #include "debug/GIC.hh"
47 
48 using namespace ArmISA;
49 
50 const AddrRange Gicv3Redistributor::GICR_IPRIORITYR(SGI_base + 0x0400,
51  SGI_base + 0x0420);
52 
54  : gic(gic),
55  distributor(nullptr),
56  cpuInterface(nullptr),
57  cpuId(cpu_id),
58  memProxy(nullptr),
59  peInLowPowerState(true),
60  irqGroup(Gicv3::SGI_MAX + Gicv3::PPI_MAX, 0),
61  irqEnabled(Gicv3::SGI_MAX + Gicv3::PPI_MAX, false),
62  irqPending(Gicv3::SGI_MAX + Gicv3::PPI_MAX, false),
63  irqPendingIspendr(Gicv3::SGI_MAX + Gicv3::PPI_MAX, false),
64  irqActive(Gicv3::SGI_MAX + Gicv3::PPI_MAX, false),
65  irqPriority(Gicv3::SGI_MAX + Gicv3::PPI_MAX, 0),
66  irqConfig(Gicv3::SGI_MAX + Gicv3::PPI_MAX, Gicv3::INT_EDGE_TRIGGERED),
67  irqGrpmod(Gicv3::SGI_MAX + Gicv3::PPI_MAX, 0),
68  irqNsacr(Gicv3::SGI_MAX + Gicv3::PPI_MAX, 0),
69  DPG1S(false),
70  DPG1NS(false),
71  DPG0(false),
72  EnableLPIs(false),
73  lpiConfigurationTablePtr(0),
74  lpiIDBits(0),
75  lpiPendingTablePtr(0),
76  addrRangeSize(gic->params()->gicv4 ? 0x40000 : 0x20000)
77 {
78 }
79 
80 void
82 {
85 
87 }
88 
89 uint64_t
90 Gicv3Redistributor::read(Addr addr, size_t size, bool is_secure_access)
91 {
92  if (GICR_IPRIORITYR.contains(addr)) { // Interrupt Priority Registers
93  uint64_t value = 0;
94  int first_intid = addr - GICR_IPRIORITYR.start();
95 
96  for (int i = 0, int_id = first_intid; i < size; i++, int_id++) {
97  uint8_t prio = irqPriority[int_id];
98 
99  if (!distributor->DS && !is_secure_access) {
100  if (getIntGroup(int_id) != Gicv3::G1NS) {
101  // RAZ/WI for non-secure accesses for secure interrupts
102  continue;
103  } else {
104  // NS view
105  prio = (prio << 1) & 0xff;
106  }
107  }
108 
109  value |= prio << (i * 8);
110  }
111 
112  return value;
113  }
114 
115  switch (addr) {
116  case GICR_CTLR: { // Control Register
117  uint64_t value = 0;
118 
119  if (DPG1S) {
120  value |= GICR_CTLR_DPG1S;
121  }
122 
123  if (DPG1NS) {
124  value |= GICR_CTLR_DPG1NS;
125  }
126 
127  if (DPG0) {
128  value |= GICR_CTLR_DPG0;
129  }
130 
131  if (EnableLPIs) {
132  value |= GICR_CTLR_ENABLE_LPIS;
133  }
134 
135  return value;
136  }
137 
138  case GICR_IIDR: // Implementer Identification Register
139  //return 0x43b; // r0p0 GIC-500
140  return 0;
141 
142  case GICR_TYPER: { // Type Register
143  /*
144  * Affinity_Value [63:32] == X
145  * (The identity of the PE associated with this Redistributor)
146  * CommonLPIAff [25:24] == 01
147  * (All Redistributors with the same Aff3 value must share an
148  * LPI Configuration table)
149  * Processor_Number [23:8] == X
150  * (A unique identifier for the PE)
151  * DPGS [5] == 1
152  * (GICR_CTLR.DPG* bits are supported)
153  * Last [4] == X
154  * (This Redistributor is the highest-numbered Redistributor in
155  * a series of contiguous Redistributor pages)
156  * DirectLPI [3] == 1
157  * (direct injection of LPIs supported)
158  * VLPIS [1] == 0
159  * (virtual LPIs not supported)
160  * PLPIS [0] == 1
161  * (physical LPIs supported)
162  */
163  uint64_t affinity = getAffinity();
164  int last = cpuId == (gic->getSystem()->threads.size() - 1);
165  return (affinity << 32) | (1 << 24) | (cpuId << 8) |
166  (1 << 5) | (last << 4) | (1 << 3) | (1 << 0);
167  }
168 
169  case GICR_WAKER: // Wake Register
170  if (!distributor->DS && !is_secure_access) {
171  // RAZ/WI for non-secure accesses
172  return 0;
173  }
174 
175  if (peInLowPowerState) {
177  } else {
178  return 0;
179  }
180 
181  case GICR_PIDR0: { // Peripheral ID0 Register
182  return 0x92; // Part number, bits[7:0]
183  }
184 
185  case GICR_PIDR1: { // Peripheral ID1 Register
186  uint8_t des_0 = 0xB; // JEP106 identification code, bits[3:0]
187  uint8_t part_1 = 0x4; // Part number, bits[11:8]
188  return (des_0 << 4) | (part_1 << 0);
189  }
190 
191  case GICR_PIDR2: { // Peripheral ID2 Register
192  uint8_t arch_rev = 0x3; // 0x3 GICv3
193  uint8_t jedec = 0x1; // JEP code
194  uint8_t des_1 = 0x3; // JEP106 identification code, bits[6:4]
195  return (arch_rev << 4) | (jedec << 3) | (des_1 << 0);
196  }
197 
198  case GICR_PIDR3: // Peripheral ID3 Register
199  return 0x0; // Implementation defined
200 
201  case GICR_PIDR4: { // Peripheral ID4 Register
202  uint8_t size = 0x4; // 64 KB software visible page
203  uint8_t des_2 = 0x4; // ARM implementation
204  return (size << 4) | (des_2 << 0);
205  }
206 
207  case GICR_PIDR5: // Peripheral ID5 Register
208  case GICR_PIDR6: // Peripheral ID6 Register
209  case GICR_PIDR7: // Peripheral ID7 Register
210  return 0; // RES0
211 
212  case GICR_IGROUPR0: { // Interrupt Group Register 0
213  uint64_t value = 0;
214 
215  if (!distributor->DS && !is_secure_access) {
216  // RAZ/WI for non-secure accesses
217  return 0;
218  }
219 
220  for (int int_id = 0; int_id < 8 * size; int_id++) {
221  value |= (irqGroup[int_id] << int_id);
222  }
223 
224  return value;
225  }
226 
227  case GICR_ISENABLER0: // Interrupt Set-Enable Register 0
228  case GICR_ICENABLER0: { // Interrupt Clear-Enable Register 0
229  uint64_t value = 0;
230 
231  for (int int_id = 0; int_id < 8 * size; int_id++) {
232  if (!distributor->DS && !is_secure_access) {
233  // RAZ/WI for non-secure accesses for secure interrupts
234  if (getIntGroup(int_id) != Gicv3::G1NS) {
235  continue;
236  }
237  }
238 
239  if (irqEnabled[int_id]) {
240  value |= (1 << int_id);
241  }
242  }
243 
244  return value;
245  }
246 
247  case GICR_ISPENDR0: // Interrupt Set-Pending Register 0
248  case GICR_ICPENDR0: { // Interrupt Clear-Pending Register 0
249  uint64_t value = 0;
250 
251  for (int int_id = 0; int_id < 8 * size; int_id++) {
252  if (!distributor->DS && !is_secure_access) {
253  // RAZ/WI for non-secure accesses for secure interrupts
254  if (getIntGroup(int_id) != Gicv3::G1NS) {
255  continue;
256  }
257  }
258 
259  value |= (irqPending[int_id] << int_id);
260  }
261 
262  return value;
263  }
264 
265  case GICR_ISACTIVER0: // Interrupt Set-Active Register 0
266  case GICR_ICACTIVER0: { // Interrupt Clear-Active Register 0
267  uint64_t value = 0;
268 
269  for (int int_id = 0; int_id < 8 * size; int_id++) {
270  if (!distributor->DS && !is_secure_access) {
271  // RAZ/WI for non-secure accesses for secure interrupts
272  if (getIntGroup(int_id) != Gicv3::G1NS) {
273  continue;
274  }
275  }
276 
277  value |= irqActive[int_id] << int_id;
278  }
279 
280  return value;
281  }
282 
283  case GICR_ICFGR0: // SGI Configuration Register
284  case GICR_ICFGR1: { // PPI Configuration Register
285  uint64_t value = 0;
286  uint32_t first_int_id = addr == GICR_ICFGR0 ? 0 : Gicv3::SGI_MAX;
287 
288  for (int i = 0, int_id = first_int_id; i < 32;
289  i = i + 2, int_id++) {
290  if (!distributor->DS && !is_secure_access) {
291  // RAZ/WI for non-secure accesses for secure interrupts
292  if (getIntGroup(int_id) != Gicv3::G1NS) {
293  continue;
294  }
295  }
296 
297  if (irqConfig[int_id] == Gicv3::INT_EDGE_TRIGGERED) {
298  value |= (0x2) << i;
299  }
300  }
301 
302  return value;
303  }
304 
305  case GICR_IGRPMODR0: { // Interrupt Group Modifier Register 0
306  uint64_t value = 0;
307 
308  if (distributor->DS) {
309  value = 0;
310  } else {
311  if (!is_secure_access) {
312  // RAZ/WI for non-secure accesses
313  value = 0;
314  } else {
315  for (int int_id = 0; int_id < 8 * size; int_id++) {
316  value |= irqGrpmod[int_id] << int_id;
317  }
318  }
319  }
320 
321  return value;
322  }
323 
324  case GICR_NSACR: { // Non-secure Access Control Register
325  uint64_t value = 0;
326 
327  if (distributor->DS) {
328  // RAZ/WI
329  value = 0;
330  } else {
331  if (!is_secure_access) {
332  // RAZ/WI
333  value = 0;
334  } else {
335  for (int i = 0, int_id = 0; i < 8 * size;
336  i = i + 2, int_id++) {
337  value |= irqNsacr[int_id] << i;
338  }
339  }
340  }
341 
342  return value;
343  }
344 
345  case GICR_PROPBASER: // Redistributor Properties Base Address Register
346  // OuterCache, bits [58:56]
347  // 000 Memory type defined in InnerCache field
348  // Physical_Address, bits [51:12]
349  // Bits [51:12] of the physical address containing the LPI
350  // Configuration table
351  // Shareability, bits [11:10]
352  // 00 Non-shareable
353  // InnerCache, bits [9:7]
354  // 000 Device-nGnRnE
355  // IDbits, bits [4:0]
356  // limited by GICD_TYPER.IDbits
358 
359  // Redistributor LPI Pending Table Base Address Register
360  case GICR_PENDBASER:
361  // PTZ, bit [62]
362  // Pending Table Zero
363  // OuterCache, bits [58:56]
364  // 000 Memory type defined in InnerCache field
365  // Physical_Address, bits [51:16]
366  // Bits [51:16] of the physical address containing the LPI Pending
367  // table
368  // Shareability, bits [11:10]
369  // 00 Non-shareable
370  // InnerCache, bits [9:7]
371  // 000 Device-nGnRnE
372  return lpiPendingTablePtr;
373 
374  // Redistributor Synchronize Register
375  case GICR_SYNCR:
376  return 0;
377 
378  default:
379  panic("Gicv3Redistributor::read(): invalid offset %#x\n", addr);
380  break;
381  }
382 }
383 
384 void
385 Gicv3Redistributor::write(Addr addr, uint64_t data, size_t size,
386  bool is_secure_access)
387 {
388  if (GICR_IPRIORITYR.contains(addr)) { // Interrupt Priority Registers
389  int first_intid = addr - GICR_IPRIORITYR.start();
390 
391  for (int i = 0, int_id = first_intid; i < size; i++, int_id++) {
392  uint8_t prio = bits(data, (i + 1) * 8 - 1, (i * 8));
393 
394  if (!distributor->DS && !is_secure_access) {
395  if (getIntGroup(int_id) != Gicv3::G1NS) {
396  // RAZ/WI for non-secure accesses for secure interrupts
397  continue;
398  } else {
399  // NS view
400  prio = 0x80 | (prio >> 1);
401  }
402  }
403 
404  irqPriority[int_id] = prio;
405  DPRINTF(GIC, "Gicv3Redistributor::write(): "
406  "int_id %d priority %d\n", int_id, irqPriority[int_id]);
407  }
408 
409  return;
410  }
411 
412  switch (addr) {
413  case GICR_CTLR: {
414  // GICR_TYPER.LPIS is 0 so EnableLPIs is RES0
415  EnableLPIs = data & GICR_CTLR_ENABLE_LPIS;
419  break;
420  }
421 
422  case GICR_WAKER: // Wake Register
423  {
424  if (!distributor->DS && !is_secure_access) {
425  // RAZ/WI for non-secure accesses
426  return;
427  }
428 
429  bool pe_was_low_power = peInLowPowerState;
431  if (!pe_was_low_power && peInLowPowerState) {
432  DPRINTF(GIC, "Gicv3Redistributor::write(): "
433  "PE entering in low power state\n");
435  } else if (pe_was_low_power && !peInLowPowerState) {
436  DPRINTF(GIC, "Gicv3Redistributor::write(): powering up PE\n");
439  }
440  break;
441  }
442 
443  case GICR_IGROUPR0: // Interrupt Group Register 0
444  if (!distributor->DS && !is_secure_access) {
445  // RAZ/WI for non-secure accesses
446  return;
447  }
448 
449  for (int int_id = 0; int_id < 8 * size; int_id++) {
450  irqGroup[int_id] = data & (1 << int_id) ? 1 : 0;
451  DPRINTF(GIC, "Gicv3Redistributor::write(): "
452  "int_id %d group %d\n", int_id, irqGroup[int_id]);
453  }
454 
455  break;
456 
457  case GICR_ISENABLER0: // Interrupt Set-Enable Register 0
458  for (int int_id = 0; int_id < 8 * size; int_id++) {
459  if (!distributor->DS && !is_secure_access) {
460  // RAZ/WI for non-secure accesses for secure interrupts
461  if (getIntGroup(int_id) != Gicv3::G1NS) {
462  continue;
463  }
464  }
465 
466  bool enable = data & (1 << int_id) ? 1 : 0;
467 
468  if (enable) {
469  irqEnabled[int_id] = true;
470  }
471 
472  DPRINTF(GIC, "Gicv3Redistributor::write(): "
473  "int_id %d enable %i\n", int_id, irqEnabled[int_id]);
474  }
475 
476  break;
477 
478  case GICR_ICENABLER0: // Interrupt Clear-Enable Register 0
479  for (int int_id = 0; int_id < 8 * size; int_id++) {
480  if (!distributor->DS && !is_secure_access) {
481  // RAZ/WI for non-secure accesses for secure interrupts
482  if (getIntGroup(int_id) != Gicv3::G1NS) {
483  continue;
484  }
485  }
486 
487  bool disable = data & (1 << int_id) ? 1 : 0;
488 
489  if (disable) {
490  irqEnabled[int_id] = false;
491  }
492 
493  DPRINTF(GIC, "Gicv3Redistributor::write(): "
494  "int_id %d enable %i\n", int_id, irqEnabled[int_id]);
495  }
496 
497  break;
498 
499  case GICR_ISPENDR0: // Interrupt Set-Pending Register 0
500  for (int int_id = 0; int_id < 8 * size; int_id++) {
501  if (!distributor->DS && !is_secure_access) {
502  // RAZ/WI for non-secure accesses for secure interrupts
503  if (getIntGroup(int_id) != Gicv3::G1NS) {
504  continue;
505  }
506  }
507 
508  bool pending = data & (1 << int_id) ? 1 : 0;
509 
510  if (pending) {
511  DPRINTF(GIC, "Gicv3Redistributor::write() "
512  "(GICR_ISPENDR0): int_id %d (PPI) "
513  "pending bit set\n", int_id);
514  irqPending[int_id] = true;
515  irqPendingIspendr[int_id] = true;
516  }
517  }
518 
520  break;
521 
522  case GICR_ICPENDR0:// Interrupt Clear-Pending Register 0
523  for (int int_id = 0; int_id < 8 * size; int_id++) {
524  if (!distributor->DS && !is_secure_access) {
525  // RAZ/WI for non-secure accesses for secure interrupts
526  if (getIntGroup(int_id) != Gicv3::G1NS) {
527  continue;
528  }
529  }
530 
531  bool clear = data & (1 << int_id) ? 1 : 0;
532 
533  if (clear && treatAsEdgeTriggered(int_id)) {
534  irqPending[int_id] = false;
535  }
536  }
537 
538  break;
539 
540  case GICR_ISACTIVER0: // Interrupt Set-Active Register 0
541  for (int int_id = 0; int_id < 8 * size; int_id++) {
542  if (!distributor->DS && !is_secure_access) {
543  // RAZ/WI for non-secure accesses for secure interrupts
544  if (getIntGroup(int_id) != Gicv3::G1NS) {
545  continue;
546  }
547  }
548 
549  bool activate = data & (1 << int_id) ? 1 : 0;
550 
551  if (activate) {
552  if (!irqActive[int_id]) {
553  DPRINTF(GIC, "Gicv3Redistributor::write(): "
554  "int_id %d active set\n", int_id);
555  }
556 
557  irqActive[int_id] = true;
558  }
559  }
560 
561  break;
562 
563  case GICR_ICACTIVER0: // Interrupt Clear-Active Register 0
564  for (int int_id = 0; int_id < 8 * size; int_id++) {
565  if (!distributor->DS && !is_secure_access) {
566  // RAZ/WI for non-secure accesses for secure interrupts
567  if (getIntGroup(int_id) != Gicv3::G1NS) {
568  continue;
569  }
570  }
571 
572  bool clear = data & (1 << int_id) ? 1 : 0;
573 
574  if (clear) {
575  if (irqActive[int_id]) {
576  DPRINTF(GIC, "Gicv3Redistributor::write(): "
577  "int_id %d active cleared\n", int_id);
578  }
579 
580  irqActive[int_id] = false;
581  }
582  }
583 
584  break;
585 
586  case GICR_ICFGR0: // SGI Configuration Register
587  // WI
588  return;
589  case GICR_ICFGR1: { // PPI Configuration Register
590  int first_intid = Gicv3::SGI_MAX;
591 
592  for (int i = 0, int_id = first_intid; i < 8 * size;
593  i = i + 2, int_id++) {
594  if (!distributor->DS && !is_secure_access) {
595  // RAZ/WI for non-secure accesses for secure interrupts
596  if (getIntGroup(int_id) != Gicv3::G1NS) {
597  continue;
598  }
599  }
600 
601  irqConfig[int_id] = data & (0x2 << i) ?
604  DPRINTF(GIC, "Gicv3Redistributor::write(): "
605  "int_id %d (PPI) config %d\n",
606  int_id, irqConfig[int_id]);
607  }
608 
609  break;
610  }
611 
612  case GICR_IGRPMODR0: { // Interrupt Group Modifier Register 0
613  if (distributor->DS) {
614  // RAZ/WI if secutiry disabled
615  } else {
616  for (int int_id = 0; int_id < 8 * size; int_id++) {
617  if (!is_secure_access) {
618  // RAZ/WI for non-secure accesses
619  continue;
620  }
621 
622  irqGrpmod[int_id] = data & (1 << int_id);
623  }
624  }
625 
626  break;
627  }
628 
629  case GICR_NSACR: { // Non-secure Access Control Register
630  if (distributor->DS) {
631  // RAZ/WI
632  } else {
633  if (!is_secure_access) {
634  // RAZ/WI
635  } else {
636  for (int i = 0, int_id = 0; i < 8 * size;
637  i = i + 2, int_id++) {
638  irqNsacr[int_id] = (data >> i) & 0x3;
639  }
640  }
641  }
642 
643  break;
644  }
645 
646  case GICR_SETLPIR: // Set LPI Pending Register
647  setClrLPI(data, true);
648  break;
649 
650  case GICR_CLRLPIR: // Clear LPI Pending Register
651  setClrLPI(data, false);
652  break;
653 
654  case GICR_PROPBASER: { // Redistributor Properties Base Address Register
655  // OuterCache, bits [58:56]
656  // 000 Memory type defined in InnerCache field
657  // Physical_Address, bits [51:12]
658  // Bits [51:12] of the physical address containing the LPI
659  // Configuration table
660  // Shareability, bits [11:10]
661  // 00 Non-shareable
662  // InnerCache, bits [9:7]
663  // 000 Device-nGnRnE
664  // IDbits, bits [4:0]
665  // limited by GICD_TYPER.IDbits (= 0xf)
666  lpiConfigurationTablePtr = data & 0xFFFFFFFFFF000;
667  lpiIDBits = data & 0x1f;
668 
669  // 0xf here matches the value of GICD_TYPER.IDbits.
670  // TODO - make GICD_TYPER.IDbits a parameter instead of a hardcoded
671  // value
672  if (lpiIDBits > 0xf) {
673  lpiIDBits = 0xf;
674  }
675 
676  break;
677  }
678 
679  // Redistributor LPI Pending Table Base Address Register
680  case GICR_PENDBASER:
681  // PTZ, bit [62]
682  // Pending Table Zero
683  // OuterCache, bits [58:56]
684  // 000 Memory type defined in InnerCache field
685  // Physical_Address, bits [51:16]
686  // Bits [51:16] of the physical address containing the LPI Pending
687  // table
688  // Shareability, bits [11:10]
689  // 00 Non-shareable
690  // InnerCache, bits [9:7]
691  // 000 Device-nGnRnE
692  lpiPendingTablePtr = data & 0xFFFFFFFFF0000;
693  break;
694 
695  case GICR_INVLPIR: { // Redistributor Invalidate LPI Register
696  // Do nothing: no caching supported
697  break;
698  }
699 
700  case GICR_INVALLR: { // Redistributor Invalidate All Register
701  // Do nothing: no caching supported
702  break;
703  }
704 
705  default:
706  panic("Gicv3Redistributor::write(): invalid offset %#x\n", addr);
707  break;
708  }
709 }
710 
711 void
713 {
714  assert((int_id >= Gicv3::SGI_MAX) &&
715  (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX));
716  irqPending[int_id] = true;
717  irqPendingIspendr[int_id] = false;
718  DPRINTF(GIC, "Gicv3Redistributor::sendPPInt(): "
719  "int_id %d (PPI) pending bit set\n", int_id);
721 }
722 
723 void
725 {
726  assert((int_id >= Gicv3::SGI_MAX) &&
727  (int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX));
728 
729  if (isLevelSensitive(int_id)) {
730  irqPending[int_id] = false;
731  }
732 }
733 
734 void
735 Gicv3Redistributor::sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns)
736 {
737  assert(int_id < Gicv3::SGI_MAX);
738  Gicv3::GroupId int_group = getIntGroup(int_id);
739 
740  bool forward = false;
741 
742  if (ns) {
743  // Non-Secure EL1 and EL2 access
744  int nsaccess = irqNsacr[int_id];
745  if (int_group == Gicv3::G0S) {
746 
747  forward = distributor->DS || (nsaccess >= 1);
748 
749  } else if (int_group == Gicv3::G1S) {
750  forward = ((group == Gicv3::G1S || group == Gicv3::G1NS ) &&
751  nsaccess == 2);
752  } else {
753  // G1NS
754  forward = group == Gicv3::G1NS;
755  }
756  } else {
757  // Secure EL1 and EL3 access
758  forward = (group == int_group) ||
759  (group == Gicv3::G1S && int_group == Gicv3::G0S &&
760  distributor->DS);
761  }
762 
763  if (!forward) return;
764 
765  irqPending[int_id] = true;
766  irqPendingIspendr[int_id] = false;
767  DPRINTF(GIC, "Gicv3ReDistributor::sendSGI(): "
768  "int_id %d (SGI) pending bit set\n", int_id);
770 }
771 
773 Gicv3Redistributor::intStatus(uint32_t int_id) const
774 {
775  assert(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX);
776 
777  if (irqPending[int_id]) {
778  if (irqActive[int_id]) {
780  }
781 
782  return Gicv3::INT_PENDING;
783  } else if (irqActive[int_id]) {
784  return Gicv3::INT_ACTIVE;
785  } else {
786  return Gicv3::INT_INACTIVE;
787  }
788 }
789 
790 void
792 {
793  distributor->update();
794 }
795 
796 /*
797  * Recalculate the highest priority pending interrupt after a
798  * change to redistributor state.
799  */
800 void
802 {
803  for (int int_id = 0; int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX; int_id++) {
804  Gicv3::GroupId int_group = getIntGroup(int_id);
805  bool group_enabled = distributor->groupEnabled(int_group);
806 
807  if (irqPending[int_id] && irqEnabled[int_id] &&
808  !irqActive[int_id] && group_enabled) {
809  if ((irqPriority[int_id] < cpuInterface->hppi.prio) ||
810  /*
811  * Multiple pending ints with same priority.
812  * Implementation choice which one to signal.
813  * Our implementation selects the one with the lower id.
814  */
815  (irqPriority[int_id] == cpuInterface->hppi.prio &&
816  int_id < cpuInterface->hppi.intid)) {
817  cpuInterface->hppi.intid = int_id;
818  cpuInterface->hppi.prio = irqPriority[int_id];
819  cpuInterface->hppi.group = int_group;
820  }
821  }
822  }
823 
824  // Check LPIs
825  if (EnableLPIs) {
826 
827  const uint32_t largest_lpi_id = 1 << (lpiIDBits + 1);
828  const uint32_t number_lpis = largest_lpi_id - SMALLEST_LPI_ID + 1;
829 
830  uint8_t lpi_pending_table[largest_lpi_id / 8];
831  uint8_t lpi_config_table[number_lpis];
832 
834  lpi_pending_table,
835  sizeof(lpi_pending_table));
836 
838  lpi_config_table,
839  sizeof(lpi_config_table));
840 
841  for (int lpi_id = SMALLEST_LPI_ID; lpi_id < largest_lpi_id;
842  lpi_id++) {
843  uint32_t lpi_pending_entry_byte = lpi_id / 8;
844  uint8_t lpi_pending_entry_bit_position = lpi_id % 8;
845  bool lpi_is_pending = lpi_pending_table[lpi_pending_entry_byte] &
846  1 << lpi_pending_entry_bit_position;
847  uint32_t lpi_configuration_entry_index = lpi_id - SMALLEST_LPI_ID;
848 
849  LPIConfigurationTableEntry config_entry =
850  lpi_config_table[lpi_configuration_entry_index];
851 
852  bool lpi_is_enable = config_entry.enable;
853 
854  // LPIs are always Non-secure Group 1 interrupts,
855  // in a system where two Security states are enabled.
856  Gicv3::GroupId lpi_group = Gicv3::G1NS;
857  bool group_enabled = distributor->groupEnabled(lpi_group);
858 
859  if (lpi_is_pending && lpi_is_enable && group_enabled) {
860  uint8_t lpi_priority = config_entry.priority << 2;
861 
862  if ((lpi_priority < cpuInterface->hppi.prio) ||
863  (lpi_priority == cpuInterface->hppi.prio &&
864  lpi_id < cpuInterface->hppi.intid)) {
865  cpuInterface->hppi.intid = lpi_id;
866  cpuInterface->hppi.prio = lpi_priority;
867  cpuInterface->hppi.group = lpi_group;
868  }
869  }
870  }
871  }
872 
873  if (peInLowPowerState) {
877  }
878  } else {
879  cpuInterface->update();
880  }
881 }
882 
883 uint8_t
885 {
886  Addr lpi_pending_entry_ptr = lpiPendingTablePtr + (lpi_id / 8);
887 
888  uint8_t lpi_pending_entry;
889  memProxy->readBlob(lpi_pending_entry_ptr,
890  &lpi_pending_entry,
891  sizeof(lpi_pending_entry));
892 
893  return lpi_pending_entry;
894 }
895 
896 void
897 Gicv3Redistributor::writeEntryLPI(uint32_t lpi_id, uint8_t lpi_pending_entry)
898 {
899  Addr lpi_pending_entry_ptr = lpiPendingTablePtr + (lpi_id / 8);
900 
901  memProxy->writeBlob(lpi_pending_entry_ptr,
902  &lpi_pending_entry,
903  sizeof(lpi_pending_entry));
904 }
905 
906 bool
908 {
909  // Fetch the LPI pending entry from memory
910  uint8_t lpi_pending_entry = readEntryLPI(lpi_id);
911 
912  uint8_t lpi_pending_entry_bit_position = lpi_id % 8;
913  bool is_set = lpi_pending_entry & (1 << lpi_pending_entry_bit_position);
914 
915  return is_set;
916 }
917 
918 void
920 {
921  if (!EnableLPIs) {
922  // Writes to GICR_SETLPIR or GICR_CLRLPIR have not effect if
923  // GICR_CTLR.EnableLPIs == 0.
924  return;
925  }
926 
927  uint32_t lpi_id = data & 0xffffffff;
928  uint32_t largest_lpi_id = 1 << (lpiIDBits + 1);
929 
930  if (lpi_id > largest_lpi_id) {
931  // Writes to GICR_SETLPIR or GICR_CLRLPIR have not effect if
932  // pINTID value specifies an unimplemented LPI.
933  return;
934  }
935 
936  // Fetch the LPI pending entry from memory
937  uint8_t lpi_pending_entry = readEntryLPI(lpi_id);
938 
939  uint8_t lpi_pending_entry_bit_position = lpi_id % 8;
940  bool is_set = lpi_pending_entry & (1 << lpi_pending_entry_bit_position);
941 
942  if (set) {
943  if (is_set) {
944  // Writes to GICR_SETLPIR have not effect if the pINTID field
945  // corresponds to an LPI that is already pending.
946  return;
947  }
948 
949  lpi_pending_entry |= 1 << (lpi_pending_entry_bit_position);
950  } else {
951  if (!is_set) {
952  // Writes to GICR_SETLPIR have not effect if the pINTID field
953  // corresponds to an LPI that is not pending.
954  return;
955  }
956 
957  lpi_pending_entry &= ~(1 << (lpi_pending_entry_bit_position));
958 
959  // Remove the pending state from the cpu interface
960  cpuInterface->resetHppi(lpi_id);
961  }
962 
963  writeEntryLPI(lpi_id, lpi_pending_entry);
964 
966 }
967 
970 {
971  assert(int_id < (Gicv3::SGI_MAX + Gicv3::PPI_MAX));
972 
973  if (distributor->DS) {
974  if (irqGroup[int_id] == 0) {
975  return Gicv3::G0S;
976  } else {
977  return Gicv3::G1NS;
978  }
979  } else {
980  if (irqGrpmod[int_id] == 0 && irqGroup[int_id] == 0) {
981  return Gicv3::G0S;
982  } else if (irqGrpmod[int_id] == 0 && irqGroup[int_id] == 1) {
983  return Gicv3::G1NS;
984  } else if (irqGrpmod[int_id] == 1 && irqGroup[int_id] == 0) {
985  return Gicv3::G1S;
986  } else if (irqGrpmod[int_id] == 1 && irqGroup[int_id] == 1) {
987  return Gicv3::G1NS;
988  }
989  }
990 
991  M5_UNREACHABLE;
992 }
993 
994 void
996 {
997  if (treatAsEdgeTriggered(int_id)) {
998  irqPending[int_id] = false;
999  }
1000  irqActive[int_id] = true;
1001 }
1002 
1003 void
1005 {
1006  irqActive[int_id] = false;
1007 }
1008 
1009 uint32_t
1011 {
1013  uint64_t mpidr = getMPIDR(gic->getSystem(), tc);
1014  /*
1015  * Aff3 = MPIDR[39:32]
1016  * (Note getMPIDR() returns uint32_t so Aff3 is always 0...)
1017  * Aff2 = MPIDR[23:16]
1018  * Aff1 = MPIDR[15:8]
1019  * Aff0 = MPIDR[7:0]
1020  * affinity = Aff3.Aff2.Aff1.Aff0
1021  */
1022  uint64_t affinity = ((mpidr & 0xff00000000) >> 8) | (mpidr & (0xffffff));
1023  return affinity;
1024 }
1025 
1026 bool
1028 {
1029  if (peInLowPowerState) {
1030  return false;
1031  }
1032 
1033  if (!distributor->groupEnabled(group)) {
1034  return false;
1035  }
1036 
1037  if ((group == Gicv3::G1S) && DPG1S) {
1038  return false;
1039  }
1040 
1041  if ((group == Gicv3::G1NS) && DPG1NS) {
1042  return false;
1043  }
1044 
1045  if ((group == Gicv3::G0S) && DPG0) {
1046  return false;
1047  }
1048 
1049  return true;
1050 }
1051 
1052 void
1054 {
1072 }
1073 
1074 void
1076 {
1094 }
Gicv3Redistributor::gic
Gicv3 * gic
Definition: gic_v3_redistributor.hh:62
Gicv3::INT_EDGE_TRIGGERED
@ INT_EDGE_TRIGGERED
Definition: gic_v3.hh:98
gic_v3_cpu_interface.hh
Gicv3Redistributor::activateIRQ
void activateIRQ(uint32_t int_id)
Definition: gic_v3_redistributor.cc:995
Gicv3Redistributor::getAffinity
uint32_t getAffinity() const
Definition: gic_v3_redistributor.cc:1010
ArmISA::ns
Bitfield< 0 > ns
Definition: miscregs_types.hh:328
Gicv3Redistributor::irqPendingIspendr
std::vector< bool > irqPendingIspendr
Definition: gic_v3_redistributor.hh:156
Gicv3Redistributor::lpiIDBits
uint8_t lpiIDBits
Definition: gic_v3_redistributor.hh:169
Gicv3::G1NS
@ G1NS
Definition: gic_v3.hh:93
Gicv3Redistributor::GICR_PENDBASER
@ GICR_PENDBASER
Definition: gic_v3_redistributor.hh:144
gic_v3_redistributor.hh
Gicv3Redistributor::distributor
Gicv3Distributor * distributor
Definition: gic_v3_redistributor.hh:63
data
const char data[]
Definition: circlebuf.test.cc:42
Gicv3Redistributor::GICR_IIDR
@ GICR_IIDR
Definition: gic_v3_redistributor.hh:79
Gicv3Redistributor::GICR_PIDR2
@ GICR_PIDR2
Definition: gic_v3_redistributor.hh:89
Gicv3::PPI_MAX
static const int PPI_MAX
Definition: gic_v3.hh:79
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:797
Gicv3Redistributor::GICR_ICPENDR0
@ GICR_ICPENDR0
Definition: gic_v3_redistributor.hh:117
Gicv3Redistributor::GICR_WAKER_ProcessorSleep
static const uint32_t GICR_WAKER_ProcessorSleep
Definition: gic_v3_redistributor.hh:102
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
UNSERIALIZE_CONTAINER
#define UNSERIALIZE_CONTAINER(member)
Definition: serialize.hh:856
System::physProxy
PortProxy physProxy
Port to physical memory used for writing object files into ram at boot.
Definition: system.hh:324
Gicv3Redistributor::lpiConfigurationTablePtr
Addr lpiConfigurationTablePtr
Definition: gic_v3_redistributor.hh:168
Gicv3Redistributor::read
uint64_t read(Addr addr, size_t size, bool is_secure_access)
Definition: gic_v3_redistributor.cc:90
Gicv3CPUInterface::hppi
hppi_t hppi
Definition: gic_v3_cpu_interface.hh:160
Gicv3Redistributor::GICR_PIDR0
@ GICR_PIDR0
Definition: gic_v3_redistributor.hh:85
Gicv3::getDistributor
Gicv3Distributor * getDistributor() const
Definition: gic_v3.hh:144
Gicv3Redistributor::GICR_CTLR_DPG0
static const uint32_t GICR_CTLR_DPG0
Definition: gic_v3_redistributor.hh:179
Gicv3::SGI_MAX
static const int SGI_MAX
Definition: gic_v3.hh:77
Gicv3Redistributor::writeEntryLPI
void writeEntryLPI(uint32_t intid, uint8_t lpi_entry)
Definition: gic_v3_redistributor.cc:897
Gicv3Redistributor::GICR_ISACTIVER0
@ GICR_ISACTIVER0
Definition: gic_v3_redistributor.hh:119
Gicv3Redistributor::Gicv3Redistributor
Gicv3Redistributor(Gicv3 *gic, uint32_t cpu_id)
Definition: gic_v3_redistributor.cc:53
Gicv3Redistributor::GICR_IGRPMODR0
@ GICR_IGRPMODR0
Definition: gic_v3_redistributor.hh:127
Gicv3Redistributor::irqPending
std::vector< bool > irqPending
Definition: gic_v3_redistributor.hh:155
AddrRange::contains
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:435
Gicv3CPUInterface::resetHppi
void resetHppi(uint32_t intid)
Definition: gic_v3_cpu_interface.cc:74
Gicv3Redistributor::cpuId
uint32_t cpuId
Definition: gic_v3_redistributor.hh:65
Gicv3Redistributor::GICR_CTLR
@ GICR_CTLR
Definition: gic_v3_redistributor.hh:77
Gicv3Redistributor::GICR_SYNCR
@ GICR_SYNCR
Definition: gic_v3_redistributor.hh:150
ArmISA::getMPIDR
RegVal getMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
This helper function is returning the value of MPIDR_EL1.
Definition: utility.cc:264
ArmISA
Definition: ccregs.hh:41
Gicv3Redistributor::irqActive
std::vector< bool > irqActive
Definition: gic_v3_redistributor.hh:157
Gicv3Redistributor::isPendingLPI
bool isPendingLPI(uint32_t intid)
Definition: gic_v3_redistributor.cc:907
Gicv3Redistributor::GICR_WAKER
@ GICR_WAKER
Definition: gic_v3_redistributor.hh:83
Gicv3Redistributor::isLevelSensitive
bool isLevelSensitive(uint32_t int_id) const
Definition: gic_v3_redistributor.hh:227
Trace::disable
void disable()
Definition: trace.cc:98
Gicv3Redistributor::irqGroup
std::vector< uint8_t > irqGroup
Definition: gic_v3_redistributor.hh:153
Gicv3Redistributor::irqPriority
std::vector< uint8_t > irqPriority
Definition: gic_v3_redistributor.hh:158
Gicv3Redistributor::GICR_CTLR_DPG1S
static const uint32_t GICR_CTLR_DPG1S
Definition: gic_v3_redistributor.hh:181
PortProxy::writeBlob
void writeBlob(Addr addr, const void *p, int size) const
Same as tryWriteBlob, but insists on success.
Definition: port_proxy.hh:187
Gicv3Redistributor::GICR_ICFGR1
@ GICR_ICFGR1
Definition: gic_v3_redistributor.hh:125
Gicv3::G0S
@ G0S
Definition: gic_v3.hh:91
Gicv3Redistributor::EnableLPIs
bool EnableLPIs
Definition: gic_v3_redistributor.hh:166
Gicv3::INT_ACTIVE_PENDING
@ INT_ACTIVE_PENDING
Definition: gic_v3.hh:86
Gicv3Redistributor::readEntryLPI
uint8_t readEntryLPI(uint32_t intid)
Definition: gic_v3_redistributor.cc:884
Gicv3Redistributor::clearPPInt
void clearPPInt(uint32_t int_id)
Definition: gic_v3_redistributor.cc:724
Gicv3Redistributor::irqConfig
std::vector< Gicv3::IntTriggerType > irqConfig
Definition: gic_v3_redistributor.hh:159
Gicv3Redistributor::getIntGroup
Gicv3::GroupId getIntGroup(int int_id) const
Definition: gic_v3_redistributor.cc:969
Gicv3CPUInterface::hppi_t::group
Gicv3::GroupId group
Definition: gic_v3_cpu_interface.hh:157
Gicv3::INT_LEVEL_SENSITIVE
@ INT_LEVEL_SENSITIVE
Definition: gic_v3.hh:97
cp
Definition: cprintf.cc:40
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
Gicv3Redistributor::GICR_CTLR_DPG1NS
static const uint32_t GICR_CTLR_DPG1NS
Definition: gic_v3_redistributor.hh:180
AddrRange
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition: addr_range.hh:68
Gicv3Redistributor::irqEnabled
std::vector< bool > irqEnabled
Definition: gic_v3_redistributor.hh:154
Gicv3Distributor::update
void update()
Definition: gic_v3_distributor.cc:1078
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
Gicv3Redistributor::cpuInterface
Gicv3CPUInterface * cpuInterface
Definition: gic_v3_redistributor.hh:64
Gicv3::INT_ACTIVE
@ INT_ACTIVE
Definition: gic_v3.hh:85
Gicv3Distributor::groupEnabled
bool groupEnabled(Gicv3::GroupId group) const
Definition: gic_v3_distributor.hh:182
Gicv3Redistributor::GICR_INVLPIR
@ GICR_INVLPIR
Definition: gic_v3_redistributor.hh:146
Gicv3Redistributor::peInLowPowerState
bool peInLowPowerState
Definition: gic_v3_redistributor.hh:105
Gicv3CPUInterface::assertWakeRequest
void assertWakeRequest(void)
Definition: gic_v3_cpu_interface.cc:2595
Gicv3CPUInterface::deassertWakeRequest
void deassertWakeRequest(void)
Definition: gic_v3_cpu_interface.cc:2605
Gicv3Redistributor::GICR_ISPENDR0
@ GICR_ISPENDR0
Definition: gic_v3_redistributor.hh:115
Gicv3Redistributor::GICR_PIDR7
@ GICR_PIDR7
Definition: gic_v3_redistributor.hh:99
Gicv3::IntStatus
IntStatus
Definition: gic_v3.hh:82
Gicv3Redistributor::lpiPendingTablePtr
Addr lpiPendingTablePtr
Definition: gic_v3_redistributor.hh:170
System::Threads::size
int size() const
Definition: system.hh:204
Gicv3Redistributor::GICR_PIDR1
@ GICR_PIDR1
Definition: gic_v3_redistributor.hh:87
Gicv3Redistributor::GICR_PIDR6
@ GICR_PIDR6
Definition: gic_v3_redistributor.hh:97
Gicv3
Definition: gic_v3.hh:53
Gicv3Redistributor::GICR_PIDR4
@ GICR_PIDR4
Definition: gic_v3_redistributor.hh:93
Gicv3Redistributor::GICR_ICACTIVER0
@ GICR_ICACTIVER0
Definition: gic_v3_redistributor.hh:121
Gicv3CPUInterface::update
void update()
Definition: gic_v3_cpu_interface.cc:2030
Gicv3::GroupId
GroupId
Definition: gic_v3.hh:90
Gicv3Redistributor::GICR_NSACR
@ GICR_NSACR
Definition: gic_v3_redistributor.hh:129
Gicv3Distributor::DS
bool DS
Definition: gic_v3_distributor.hh:147
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Gicv3::G1S
@ G1S
Definition: gic_v3.hh:92
Gicv3Redistributor::GICR_TYPER
@ GICR_TYPER
Definition: gic_v3_redistributor.hh:81
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:790
Gicv3Redistributor::GICR_IGROUPR0
@ GICR_IGROUPR0
Definition: gic_v3_redistributor.hh:109
Gicv3Redistributor::GICR_IPRIORITYR
static const AddrRange GICR_IPRIORITYR
Definition: gic_v3_redistributor.hh:133
utility.hh
Gicv3Redistributor::DPG0
bool DPG0
Definition: gic_v3_redistributor.hh:165
Gicv3Redistributor::GICR_SETLPIR
@ GICR_SETLPIR
Definition: gic_v3_redistributor.hh:138
Gicv3Redistributor::DPG1NS
bool DPG1NS
Definition: gic_v3_redistributor.hh:164
Gicv3Redistributor::GICR_WAKER_ChildrenAsleep
static const uint32_t GICR_WAKER_ChildrenAsleep
Definition: gic_v3_redistributor.hh:103
Gicv3Redistributor::sendSGI
void sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns)
Definition: gic_v3_redistributor.cc:735
System::threads
Threads threads
Definition: system.hh:309
Gicv3Redistributor::GICR_ISENABLER0
@ GICR_ISENABLER0
Definition: gic_v3_redistributor.hh:111
Gicv3Redistributor::GICR_PROPBASER
@ GICR_PROPBASER
Definition: gic_v3_redistributor.hh:142
Gicv3Redistributor::intStatus
Gicv3::IntStatus intStatus(uint32_t int_id) const
Definition: gic_v3_redistributor.cc:773
Gicv3Redistributor::GICR_PIDR5
@ GICR_PIDR5
Definition: gic_v3_redistributor.hh:95
Gicv3Redistributor::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: gic_v3_redistributor.cc:1053
Gicv3Redistributor::write
void write(Addr addr, uint64_t data, size_t size, bool is_secure_access)
Definition: gic_v3_redistributor.cc:385
AddrRange::start
Addr start() const
Get the start address of the range.
Definition: addr_range.hh:314
Gicv3Redistributor::GICR_INVALLR
@ GICR_INVALLR
Definition: gic_v3_redistributor.hh:148
Gicv3::getCPUInterface
Gicv3CPUInterface * getCPUInterface(int cpu_id) const
Definition: gic_v3.hh:137
Gicv3Redistributor::DPG1S
bool DPG1S
Definition: gic_v3_redistributor.hh:163
Gicv3CPUInterface::clearPendingInterrupts
void clearPendingInterrupts(void)
Definition: gic_v3_cpu_interface.cc:2588
SERIALIZE_CONTAINER
#define SERIALIZE_CONTAINER(member)
Definition: serialize.hh:848
ArmISA::gic
Bitfield< 27, 24 > gic
Definition: miscregs_types.hh:171
Gicv3Redistributor::sendPPInt
void sendPPInt(uint32_t int_id)
Definition: gic_v3_redistributor.cc:712
addr
ip6_addr_t addr
Definition: inet.hh:423
Gicv3Redistributor::irqGrpmod
std::vector< uint8_t > irqGrpmod
Definition: gic_v3_redistributor.hh:160
Gicv3CPUInterface::hppi_t::intid
uint32_t intid
Definition: gic_v3_cpu_interface.hh:155
Gicv3::INT_PENDING
@ INT_PENDING
Definition: gic_v3.hh:84
Gicv3Redistributor::deactivateIRQ
void deactivateIRQ(uint32_t int_id)
Definition: gic_v3_redistributor.cc:1004
Gicv3Redistributor::update
void update()
Definition: gic_v3_redistributor.cc:801
Gicv3Redistributor::GICR_ICFGR0
@ GICR_ICFGR0
Definition: gic_v3_redistributor.hh:123
Gicv3Redistributor::init
void init()
Definition: gic_v3_redistributor.cc:81
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:63
Gicv3Redistributor::enable
Bitfield< 0 > enable
Definition: gic_v3_redistributor.hh:175
BaseGic::getSystem
ArmSystem * getSystem() const
Definition: base_gic.hh:104
Gicv3Redistributor::SMALLEST_LPI_ID
static const uint32_t SMALLEST_LPI_ID
Definition: gic_v3_redistributor.hh:194
Gicv3Redistributor::updateDistributor
void updateDistributor()
Definition: gic_v3_redistributor.cc:791
Gicv3CPUInterface::havePendingInterrupts
bool havePendingInterrupts(void) const
Definition: gic_v3_cpu_interface.cc:2582
Gicv3Redistributor::treatAsEdgeTriggered
bool treatAsEdgeTriggered(uint32_t int_id) const
This helper is used to check if an interrupt should be treated as edge triggered in the following sce...
Definition: gic_v3_redistributor.hh:243
Gicv3Redistributor::canBeSelectedFor1toNInterrupt
bool canBeSelectedFor1toNInterrupt(Gicv3::GroupId group) const
Definition: gic_v3_redistributor.cc:1027
Gicv3Redistributor::GICR_CLRLPIR
@ GICR_CLRLPIR
Definition: gic_v3_redistributor.hh:140
CheckpointIn
Definition: serialize.hh:67
Gicv3CPUInterface::hppi_t::prio
uint8_t prio
Definition: gic_v3_cpu_interface.hh:156
PortProxy::readBlob
void readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
Definition: port_proxy.hh:177
Gicv3Redistributor::GICR_PIDR3
@ GICR_PIDR3
Definition: gic_v3_redistributor.hh:91
gic_v3_distributor.hh
Gicv3Redistributor::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: gic_v3_redistributor.cc:1075
Gicv3Redistributor::setClrLPI
void setClrLPI(uint64_t data, bool set)
Definition: gic_v3_redistributor.cc:919
Gicv3Redistributor::GICR_ICENABLER0
@ GICR_ICENABLER0
Definition: gic_v3_redistributor.hh:113
Gicv3Redistributor::memProxy
PortProxy * memProxy
Definition: gic_v3_redistributor.hh:66
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
Gicv3Redistributor::irqNsacr
std::vector< uint8_t > irqNsacr
Definition: gic_v3_redistributor.hh:161
Gicv3::INT_INACTIVE
@ INT_INACTIVE
Definition: gic_v3.hh:83
bits
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:75

Generated on Wed Sep 30 2020 14:02:10 for gem5 by doxygen 1.8.17