gem5  v20.1.0.0
gic_v3_distributor.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 <algorithm>
44 
45 #include "base/intmath.hh"
46 #include "debug/GIC.hh"
47 #include "dev/arm/gic_v3.hh"
50 
51 const AddrRange Gicv3Distributor::GICD_IGROUPR (0x0080, 0x0100);
52 const AddrRange Gicv3Distributor::GICD_ISENABLER (0x0100, 0x0180);
53 const AddrRange Gicv3Distributor::GICD_ICENABLER (0x0180, 0x0200);
54 const AddrRange Gicv3Distributor::GICD_ISPENDR (0x0200, 0x0280);
55 const AddrRange Gicv3Distributor::GICD_ICPENDR (0x0280, 0x0300);
56 const AddrRange Gicv3Distributor::GICD_ISACTIVER (0x0300, 0x0380);
57 const AddrRange Gicv3Distributor::GICD_ICACTIVER (0x0380, 0x0400);
58 const AddrRange Gicv3Distributor::GICD_IPRIORITYR(0x0400, 0x0800);
59 const AddrRange Gicv3Distributor::GICD_ITARGETSR (0x0800, 0x0900);
60 const AddrRange Gicv3Distributor::GICD_ICFGR (0x0c00, 0x0d00);
61 const AddrRange Gicv3Distributor::GICD_IGRPMODR (0x0d00, 0x0d80);
62 const AddrRange Gicv3Distributor::GICD_NSACR (0x0e00, 0x0f00);
63 const AddrRange Gicv3Distributor::GICD_CPENDSGIR (0x0f10, 0x0f20);
64 const AddrRange Gicv3Distributor::GICD_SPENDSGIR (0x0f20, 0x0f30);
65 const AddrRange Gicv3Distributor::GICD_IROUTER (0x6000, 0x7fe0);
66 
68  : gic(gic),
69  itLines(it_lines),
70  ARE(true),
71  EnableGrp1S(0),
72  EnableGrp1NS(0),
73  EnableGrp0(0),
74  irqGroup(it_lines, 0),
75  irqEnabled(it_lines, false),
76  irqPending(it_lines, false),
77  irqPendingIspendr(it_lines, false),
78  irqActive(it_lines, false),
79  irqPriority(it_lines, 0xAA),
80  irqConfig(it_lines, Gicv3::INT_LEVEL_SENSITIVE),
81  irqGrpmod(it_lines, 0),
82  irqNsacr(it_lines, 0),
83  irqAffinityRouting(it_lines, 0),
84  gicdTyper(0),
85  gicdPidr0(0x92),
86  gicdPidr1(0xb4),
87  gicdPidr2(0x3b),
88  gicdPidr3(0),
89  gicdPidr4(0x44)
90 {
91  panic_if(it_lines > Gicv3::INTID_SECURE, "Invalid value for it_lines!");
92  /*
93  * RSS [26] == 1
94  * (The implementation does supports targeted SGIs with affinity
95  * level 0 values of 0 - 255)
96  * No1N [25] == 1
97  * (1 of N SPI interrupts are not supported)
98  * A3V [24] == 1
99  * (Supports nonzero values of Affinity level 3)
100  * IDbits [23:19] == 0xf
101  * (The number of interrupt identifier bits supported, minus one)
102  * DVIS [18] == 0
103  * (The implementation does not support Direct Virtual LPI
104  * injection)
105  * LPIS [17] == 1
106  * (The implementation does not support LPIs)
107  * MBIS [16] == 1
108  * (The implementation supports message-based interrupts
109  * by writing to Distributor registers)
110  * SecurityExtn [10] == X
111  * (The GIC implementation supports two Security states)
112  * CPUNumber [7:5] == 0
113  * (since for us ARE is always 1 [(ARE = 0) == Gicv2 legacy])
114  * ITLinesNumber [4:0] == N
115  * (MaxSPIIntId = 32 (N + 1) - 1)
116  */
117  int max_spi_int_id = itLines - 1;
118  int it_lines_number = divCeil(max_spi_int_id + 1, 32) - 1;
119  gicdTyper = (1 << 26) | (1 << 25) | (1 << 24) | (IDBITS << 19) |
120  (1 << 17) | (1 << 16) |
121  ((gic->getSystem()->haveSecurity() ? 1 : 0) << 10) |
122  (it_lines_number << 0);
123 
124  if (gic->getSystem()->haveSecurity()) {
125  DS = false;
126  } else {
127  DS = true;
128  }
129 }
130 
131 void
133 {
134 }
135 
136 uint64_t
137 Gicv3Distributor::read(Addr addr, size_t size, bool is_secure_access)
138 {
139  if (GICD_IGROUPR.contains(addr)) { // Interrupt Group Registers
140  uint64_t val = 0x0;
141 
142  if (!DS && !is_secure_access) {
143  // RAZ/WI for non-secure accesses
144  return 0;
145  }
146 
147  int first_intid = (addr - GICD_IGROUPR.start()) * 8;
148 
149  if (isNotSPI(first_intid)) {
150  return 0;
151  }
152 
153  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
154  i++, int_id++) {
155  val |= irqGroup[int_id] << i;
156  }
157 
158  return val;
159  } else if (GICD_ISENABLER.contains(addr)) {
160  // Interrupt Set-Enable Registers
161  uint64_t val = 0x0;
162  int first_intid = (addr - GICD_ISENABLER.start()) * 8;
163 
164  if (isNotSPI(first_intid)) {
165  return 0;
166  }
167 
168  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
169  i++, int_id++) {
170 
171  if (nsAccessToSecInt(int_id, is_secure_access))
172  {
173  continue;
174  }
175 
176  val |= irqEnabled[int_id] << i;
177  }
178 
179  return val;
180  } else if (GICD_ICENABLER.contains(addr)) {
181  // Interrupt Clear-Enable Registers
182  uint64_t val = 0x0;
183  int first_intid = (addr - GICD_ICENABLER.start()) * 8;
184 
185  if (isNotSPI(first_intid)) {
186  return 0;
187  }
188 
189  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
190  i++, int_id++) {
191 
192  if (nsAccessToSecInt(int_id, is_secure_access))
193  {
194  continue;
195  }
196 
197  val |= (irqEnabled[int_id] << i);
198  }
199 
200  return val;
201  } else if (GICD_ISPENDR.contains(addr)) {
202  // Interrupt Set-Pending Registers
203  uint64_t val = 0x0;
204  int first_intid = (addr - GICD_ISPENDR.start()) * 8;
205 
206  if (isNotSPI(first_intid)) {
207  return 0;
208  }
209 
210  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
211  i++, int_id++) {
212 
213  if (nsAccessToSecInt(int_id, is_secure_access))
214  {
215  if (irqNsacr[int_id] == 0) {
216  // Group 0 or Secure Group 1 interrupts are RAZ/WI
217  continue;
218  }
219  }
220 
221  val |= (irqPending[int_id] << i);
222  }
223 
224  return val;
225  } else if (GICD_ICPENDR.contains(addr)) {
226  // Interrupt Clear-Pending Registers
227  uint64_t val = 0x0;
228  int first_intid = (addr - GICD_ICPENDR.start()) * 8;
229 
230  if (isNotSPI(first_intid)) {
231  return 0;
232  }
233 
234  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
235  i++, int_id++) {
236 
237  if (nsAccessToSecInt(int_id, is_secure_access))
238  {
239  if (irqNsacr[int_id] < 2) {
240  // Group 0 or Secure Group 1 interrupts are RAZ/WI
241  continue;
242  }
243  }
244 
245  val |= (irqPending[int_id] << i);
246  }
247 
248  return val;
249  } else if (GICD_ISACTIVER.contains(addr)) {
250  // Interrupt Set-Active Registers
251  int first_intid = (addr - GICD_ISACTIVER.start()) * 8;
252 
253  if (isNotSPI(first_intid)) {
254  return 0;
255  }
256 
257  uint64_t val = 0x0;
258 
259  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
260  i++, int_id++) {
261 
262  if (nsAccessToSecInt(int_id, is_secure_access))
263  {
264  // Group 0 or Secure Group 1 interrupts are RAZ/WI
265  if (irqNsacr[int_id] < 2) {
266  continue;
267  }
268  }
269 
270  val |= (irqActive[int_id] << i);
271  }
272 
273  return val;
274  } else if (GICD_ICACTIVER.contains(addr)) {
275  // Interrupt Clear-Active Registers
276  int first_intid = (addr - GICD_ICACTIVER.start()) * 8;
277 
278  if (isNotSPI(first_intid)) {
279  return 0;
280  }
281 
282  uint64_t val = 0x0;
283 
284  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
285  i++, int_id++) {
286 
287  if (nsAccessToSecInt(int_id, is_secure_access))
288  {
289  if (irqNsacr[int_id] < 2) {
290  continue;
291  }
292  }
293 
294  val |= (irqActive[int_id] << i);
295  }
296 
297  return val;
298  } else if (GICD_IPRIORITYR.contains(addr)) {
299  // Interrupt Priority Registers
300  uint64_t val = 0x0;
301  int first_intid = addr - GICD_IPRIORITYR.start();
302 
303  if (isNotSPI(first_intid)) {
304  return 0;
305  }
306 
307  for (int i = 0, int_id = first_intid; i < size && int_id < itLines;
308  i++, int_id++) {
309 
310  uint8_t prio = irqPriority[int_id];
311 
312  if (!DS && !is_secure_access) {
313  if (getIntGroup(int_id) != Gicv3::G1NS) {
314  // RAZ/WI for non-secure accesses for secure interrupts
315  continue;
316  } else {
317  // NS view
318  prio = (prio << 1) & 0xff;
319  }
320  }
321 
322  val |= prio << (i * 8);
323  }
324 
325  return val;
326  } else if (GICD_ITARGETSR.contains(addr)) {
327  // Interrupt Processor Targets Registers
328  // ARE always on, RAZ/WI
329  warn("Gicv3Distributor::read(): "
330  "GICD_ITARGETSR is RAZ/WI, legacy not supported!\n");
331  return 0;
332  } else if (GICD_ICFGR.contains(addr)) {
333  // Interrupt Configuration Registers
334  int first_intid = (addr - GICD_ICFGR.start()) * 4;
335 
336  if (isNotSPI(first_intid)) {
337  return 0;
338  }
339 
340  uint64_t val = 0x0;
341 
342  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
343  i = i + 2, int_id++) {
344 
345  if (nsAccessToSecInt(int_id, is_secure_access))
346  {
347  continue;
348  }
349 
350  if (irqConfig[int_id] == Gicv3::INT_EDGE_TRIGGERED) {
351  val |= (0x2 << i);
352  }
353  }
354 
355  return val;
356  } else if (GICD_IGRPMODR.contains(addr)) {
357  // Interrupt Group Modifier Registers
358  if (DS) {
359  // RAZ/WI if security disabled
360  return 0;
361  } else {
362  if (!is_secure_access) {
363  // RAZ/WI for non-secure accesses
364  return 0;
365  } else {
366  int first_intid = (addr - GICD_IGRPMODR.start()) * 8;
367 
368  if (isNotSPI(first_intid)) {
369  return 0;
370  }
371 
372  uint64_t val = 0x0;
373 
374  for (int i = 0, int_id = first_intid;
375  i < 8 * size && int_id < itLines; i++, int_id++) {
376  val |= irqGrpmod[int_id] << i;
377  }
378 
379  return val;
380  }
381  }
382  } else if (GICD_NSACR.contains(addr)) {
383  // Non-secure Access Control Registers
384  // 2 bits per interrupt
385  int first_intid = (addr - GICD_NSACR.start()) * 4;
386 
387  if (isNotSPI(first_intid)) {
388  return 0;
389  }
390 
391  if (DS || (!DS && !is_secure_access)) {
392  return 0;
393  }
394 
395  uint64_t val = 0x0;
396 
397  for (int i = 0, int_id = first_intid;
398  i < 8 * size && int_id < itLines; i = i + 2, int_id++) {
399  val |= irqNsacr[int_id] << i;
400  }
401 
402  return val;
403  } else if (GICD_CPENDSGIR.contains(addr)) { // SGI Clear-Pending Registers
404  // ARE always on, RAZ/WI
405  warn("Gicv3Distributor::read(): "
406  "GICD_CPENDSGIR is RAZ/WI, legacy not supported!\n");
407  return 0x0;
408  } else if (GICD_SPENDSGIR.contains(addr)) { // SGI Set-Pending Registers
409  // ARE always on, RAZ/WI
410  warn("Gicv3Distributor::read(): "
411  "GICD_SPENDSGIR is RAZ/WI, legacy not supported!\n");
412  return 0x0;
413  } else if (GICD_IROUTER.contains(addr)) { // Interrupt Routing Registers
414  // 64 bit registers. 2 or 1 access.
415  int int_id = (addr - GICD_IROUTER.start()) / 8;
416 
417  if (isNotSPI(int_id)) {
418  return 0;
419  }
420 
421  if (nsAccessToSecInt(int_id, is_secure_access))
422  {
423  if (irqNsacr[int_id] < 3) {
424  return 0;
425  }
426  }
427 
428  if (size == 4) {
429  if (addr & 7) { // high half of 64 bit register
430  return irqAffinityRouting[int_id] >> 32;
431  } else { // high low of 64 bit register
432  return irqAffinityRouting[int_id] & 0xFFFFFFFF;
433  }
434  } else {
435  return irqAffinityRouting[int_id];
436  }
437  }
438 
439  switch (addr) {
440  case GICD_CTLR: // Control Register
441  if (!DS) {
442  if (is_secure_access) {
443  // E1NWF [7] RAZ/WI
444  // DS [6] - Disable Security
445  // ARE_NS [5] RAO/WI
446  // ARE_S [4] RAO/WI
447  // EnableGrp1S [2]
448  // EnableGrp1NS [1]
449  // EnableGrp0 [0]
450  return (EnableGrp0 << 0) |
451  (EnableGrp1NS << 1) |
452  (EnableGrp1S << 2) |
453  (1 << 4) |
454  (1 << 5) |
455  (DS << 6);
456  } else {
457  // ARE_NS [4] RAO/WI;
458  // EnableGrp1A [1] is a read-write alias of the Secure
459  // GICD_CTLR.EnableGrp1NS
460  // EnableGrp1 [0] RES0
461  return (1 << 4) | (EnableGrp1NS << 1);
462  }
463  } else {
464  return (DS << 6) | (ARE << 4) |
465  (EnableGrp1NS << 1) | (EnableGrp0 << 0);
466  }
467 
468  case GICD_TYPER: // Interrupt Controller Type Register
469  return gicdTyper;
470 
471  case GICD_IIDR: // Implementer Identification Register
472  //return 0x43b; // ARM JEP106 code (r0p0 GIC-500)
473  return 0;
474 
475  case GICD_STATUSR: // Error Reporting Status Register
476  // Optional register, RAZ/WI
477  return 0x0;
478 
479  case GICD_PIDR0: // Peripheral ID0 Register
480  return gicdPidr0;
481 
482  case GICD_PIDR1: // Peripheral ID1 Register
483  return gicdPidr1;
484 
485  case GICD_PIDR2: // Peripheral ID2 Register
486  return gicdPidr2;
487 
488  case GICD_PIDR3: // Peripheral ID3 Register
489  return gicdPidr3;
490 
491  case GICD_PIDR4: // Peripheral ID4 Register
492  return gicdPidr4;
493 
494  case GICD_PIDR5: // Peripheral ID5 Register
495  case GICD_PIDR6: // Peripheral ID6 Register
496  case GICD_PIDR7: // Peripheral ID7 Register
497  return 0; // RES0
498 
499  default:
500  panic("Gicv3Distributor::read(): invalid offset %#x\n", addr);
501  break;
502  }
503 }
504 
505 void
506 Gicv3Distributor::write(Addr addr, uint64_t data, size_t size,
507  bool is_secure_access)
508 {
509  if (GICD_IGROUPR.contains(addr)) { // Interrupt Group Registers
510  if (!DS && !is_secure_access) {
511  // RAZ/WI for non-secure accesses
512  return;
513  }
514 
515  int first_intid = (addr - GICD_IGROUPR.start()) * 8;
516 
517  if (isNotSPI(first_intid)) {
518  return;
519  }
520 
521  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
522  i++, int_id++) {
523  irqGroup[int_id] = data & (1 << i) ? 1 : 0;
524  DPRINTF(GIC, "Gicv3Distributor::write(): int_id %d group %d\n",
525  int_id, irqGroup[int_id]);
526  }
527 
528  return;
529  } else if (GICD_ISENABLER.contains(addr)) {
530  // Interrupt Set-Enable Registers
531  int first_intid = (addr - GICD_ISENABLER.start()) * 8;
532 
533  if (isNotSPI(first_intid)) {
534  return;
535  }
536 
537  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
538  i++, int_id++) {
539 
540  if (nsAccessToSecInt(int_id, is_secure_access))
541  {
542  continue;
543  }
544 
545  bool enable = data & (1 << i) ? 1 : 0;
546 
547  if (enable) {
548  if (!irqEnabled[int_id]) {
549  DPRINTF(GIC, "Gicv3Distributor::write(): "
550  "int_id %d enabled\n", int_id);
551  }
552 
553  irqEnabled[int_id] = true;
554  }
555  }
556 
557  return;
558  } else if (GICD_ICENABLER.contains(addr)) {
559  // Interrupt Clear-Enable Registers
560  int first_intid = (addr - GICD_ICENABLER.start()) * 8;
561 
562  if (isNotSPI(first_intid)) {
563  return;
564  }
565 
566  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
567  i++, int_id++) {
568 
569  if (nsAccessToSecInt(int_id, is_secure_access))
570  {
571  continue;
572  }
573 
574  bool disable = data & (1 << i) ? 1 : 0;
575 
576  if (disable) {
577  if (irqEnabled[int_id]) {
578  DPRINTF(GIC, "Gicv3Distributor::write(): "
579  "int_id %d disabled\n", int_id);
580  }
581 
582  irqEnabled[int_id] = false;
583  }
584  }
585 
586  return;
587  } else if (GICD_ISPENDR.contains(addr)) {
588  // Interrupt Set-Pending Registers
589  int first_intid = (addr - GICD_ISPENDR.start()) * 8;
590 
591  if (isNotSPI(first_intid)) {
592  return;
593  }
594 
595  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
596  i++, int_id++) {
597 
598  if (nsAccessToSecInt(int_id, is_secure_access))
599  {
600  if (irqNsacr[int_id] == 0) {
601  // Group 0 or Secure Group 1 interrupts are RAZ/WI
602  continue;
603  }
604  }
605 
606  bool pending = data & (1 << i) ? 1 : 0;
607 
608  if (pending) {
609  DPRINTF(GIC, "Gicv3Distributor::write() (GICD_ISPENDR): "
610  "int_id %d (SPI) pending bit set\n", int_id);
611  irqPending[int_id] = true;
612  irqPendingIspendr[int_id] = true;
613  }
614  }
615 
616  update();
617  return;
618  } else if (GICD_ICPENDR.contains(addr)) {
619  // Interrupt Clear-Pending Registers
620  int first_intid = (addr - GICD_ICPENDR.start()) * 8;
621 
622  if (isNotSPI(first_intid)) {
623  return;
624  }
625 
626  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
627  i++, int_id++) {
628 
629  if (nsAccessToSecInt(int_id, is_secure_access))
630  {
631  if (irqNsacr[int_id] < 2) {
632  // Group 0 or Secure Group 1 interrupts are RAZ/WI
633  continue;
634  }
635  }
636 
637  bool clear = data & (1 << i) ? 1 : 0;
638 
639  if (clear && treatAsEdgeTriggered(int_id)) {
640  irqPending[int_id] = false;
641  clearIrqCpuInterface(int_id);
642  }
643  }
644 
645  update();
646  return;
647  } else if (GICD_ISACTIVER.contains(addr)) {
648  // Interrupt Set-Active Registers
649  int first_intid = (addr - GICD_ISACTIVER.start()) * 8;
650 
651  if (isNotSPI(first_intid)) {
652  return;
653  }
654 
655  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
656  i++, int_id++) {
657 
658  if (nsAccessToSecInt(int_id, is_secure_access))
659  {
660  continue;
661  }
662 
663  bool active = data & (1 << i) ? 1 : 0;
664 
665  if (active) {
666  irqActive[int_id] = 1;
667  }
668  }
669 
670  return;
671  } else if (GICD_ICACTIVER.contains(addr)) {
672  // Interrupt Clear-Active Registers
673  int first_intid = (addr - GICD_ICACTIVER.start()) * 8;
674 
675  if (isNotSPI(first_intid)) {
676  return;
677  }
678 
679  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
680  i++, int_id++) {
681 
682  if (nsAccessToSecInt(int_id, is_secure_access))
683  {
684  continue;
685  }
686 
687  bool clear = data & (1 << i) ? 1 : 0;
688 
689  if (clear) {
690  if (irqActive[int_id]) {
691  DPRINTF(GIC, "Gicv3Distributor::write(): "
692  "int_id %d active cleared\n", int_id);
693  }
694 
695  irqActive[int_id] = false;
696  }
697  }
698 
699  return;
700  } else if (GICD_IPRIORITYR.contains(addr)) {
701  // Interrupt Priority Registers
702  int first_intid = addr - GICD_IPRIORITYR.start();
703 
704  if (isNotSPI(first_intid)) {
705  return;
706  }
707 
708  for (int i = 0, int_id = first_intid; i < size && int_id < itLines;
709  i++, int_id++) {
710  uint8_t prio = bits(data, (i + 1) * 8 - 1, (i * 8));
711 
712  if (!DS && !is_secure_access) {
713  if (getIntGroup(int_id) != Gicv3::G1NS) {
714  // RAZ/WI for non-secure accesses to secure interrupts
715  continue;
716  } else {
717  prio = 0x80 | (prio >> 1);
718  }
719  }
720 
721  irqPriority[int_id] = prio;
722  DPRINTF(GIC, "Gicv3Distributor::write(): int_id %d priority %d\n",
723  int_id, irqPriority[int_id]);
724  }
725 
726  return;
727  } else if (GICD_ITARGETSR.contains(addr)) {
728  // Interrupt Processor Targets Registers
729  // ARE always on, RAZ/WI
730  warn("Gicv3Distributor::write(): "
731  "GICD_ITARGETSR is RAZ/WI, legacy not supported!\n");
732  return;
733  } else if (GICD_ICFGR.contains(addr)) {
734  // Interrupt Configuration Registers
735  // for x = 0 to 15:
736  // GICD_ICFGR[2x] = RES0
737  // GICD_ICFGR[2x + 1] =
738  // 0 level-sensitive
739  // 1 edge-triggered
740  int first_intid = (addr - GICD_ICFGR.start()) * 4;
741 
742  if (isNotSPI(first_intid)) {
743  return;
744  }
745 
746  for (int i = 0, int_id = first_intid; i < 8 * size && int_id < itLines;
747  i = i + 2, int_id++) {
748 
749  if (nsAccessToSecInt(int_id, is_secure_access)) {
750  continue;
751  }
752 
753  irqConfig[int_id] = data & (0x2 << i) ?
756  DPRINTF(GIC, "Gicv3Distributor::write(): int_id %d config %d\n",
757  int_id, irqConfig[int_id]);
758  }
759 
760  return;
761  } else if (GICD_IGRPMODR.contains(addr)) {
762  // Interrupt Group Modifier Registers
763  if (DS) {
764  return;
765  } else {
766  if (!is_secure_access) {
767  // RAZ/WI for non-secure accesses
768  return;
769  } else {
770  int first_intid = (addr - GICD_IGRPMODR.start()) * 8;
771 
772  if (isNotSPI(first_intid)) {
773  return;
774  }
775 
776  for (int i = 0, int_id = first_intid;
777  i < 8 * size && int_id < itLines; i++, int_id++) {
778  irqGrpmod[int_id] = bits(data, i);
779  }
780 
781  return ;
782  }
783  }
784 
785  } else if (GICD_NSACR.contains(addr)) {
786  // Non-secure Access Control Registers
787  // 2 bits per interrupt
788  int first_intid = (addr - GICD_NSACR.start()) * 4;
789 
790  if (isNotSPI(first_intid)) {
791  return;
792  }
793 
794  if (DS || (!DS && !is_secure_access)) {
795  return;
796  }
797 
798  for (int i = 0, int_id = first_intid;
799  i < 8 * size && int_id < itLines; i = i + 2, int_id++) {
800  irqNsacr[int_id] = (data >> (2 * int_id)) & 0x3;
801  }
802 
803  return;
804  } else if (GICD_IROUTER.contains(addr)) { // Interrupt Routing Registers
805  // 64 bit registers. 2 accesses.
806  int int_id = (addr - GICD_IROUTER.start()) / 8;
807 
808  if (isNotSPI(int_id)) {
809  return;
810  }
811 
812  if (nsAccessToSecInt(int_id, is_secure_access))
813  {
814  if (irqNsacr[int_id] < 3) {
815  // Group 0 or Secure Group 1 interrupts are RAZ/WI
816  return;
817  }
818  }
819 
820  if (size == 4) {
821  if (addr & 7) { // high half of 64 bit register
822  irqAffinityRouting[int_id] =
823  (irqAffinityRouting[int_id] & 0xffffffff) | (data << 32);
824  } else { // low half of 64 bit register
825  irqAffinityRouting[int_id] =
826  (irqAffinityRouting[int_id] & 0xffffffff00000000) |
827  (data & 0xffffffff);
828  }
829  } else {
830  irqAffinityRouting[int_id] = data;
831  }
832 
833  DPRINTF(GIC, "Gicv3Distributor::write(): "
834  "int_id %d GICD_IROUTER %#llx\n",
835  int_id, irqAffinityRouting[int_id]);
836  return;
837  }
838 
839  switch (addr) {
840  case GICD_CTLR: // Control Register
841  if (DS) {
842  /*
843  * E1NWF [7]
844  * 1 of N wakeup functionality not supported, RAZ/WI
845  * DS [6] - RAO/WI
846  * ARE [4]
847  * affinity routing always on, no GICv2 legacy, RAO/WI
848  * EnableGrp1 [1]
849  * EnableGrp0 [0]
850  */
851  if ((data & (1 << 4)) == 0) {
852  warn("Gicv3Distributor::write(): "
853  "setting ARE to 0 is not supported!\n");
854  }
855 
857  EnableGrp0 = data & GICD_CTLR_ENABLEGRP0;
858  DPRINTF(GIC, "Gicv3Distributor::write(): (DS 1)"
859  "EnableGrp1NS %d EnableGrp0 %d\n",
861  } else {
862  if (is_secure_access) {
863  /*
864  * E1NWF [7]
865  * 1 of N wakeup functionality not supported, RAZ/WI
866  * DS [6]
867  * ARE_NS [5]
868  * affinity routing always on, no GICv2 legacy, RAO/WI
869  * ARE_S [4]
870  * affinity routing always on, no GICv2 legacy, RAO/WI
871  * EnableGrp1S [2]
872  * EnableGrp1NS [1]
873  * EnableGrp0 [0]
874  */
875  if ((data & (1 << 5)) == 0) {
876  warn("Gicv3Distributor::write(): "
877  "setting ARE_NS to 0 is not supported!\n");
878  }
879 
880  if ((data & (1 << 4)) == 0) {
881  warn("Gicv3Distributor::write(): "
882  "setting ARE_S to 0 is not supported!\n");
883  }
884 
885  DS = data & GICD_CTLR_DS;
888  EnableGrp0 = data & GICD_CTLR_ENABLEGRP0;
889  DPRINTF(GIC, "Gicv3Distributor::write(): (DS 0 secure)"
890  "DS %d "
891  "EnableGrp1S %d EnableGrp1NS %d EnableGrp0 %d\n",
893 
894  if (data & GICD_CTLR_DS) {
895  EnableGrp1S = 0;
896  }
897  } else {
898  /*
899  * ARE_NS [4] RAO/WI;
900  * EnableGrp1A [1] is a read-write alias of the Secure
901  * GICD_CTLR.EnableGrp1NS
902  * EnableGrp1 [0] RES0
903  */
904  if ((data & (1 << 4)) == 0) {
905  warn("Gicv3Distributor::write(): "
906  "setting ARE_NS to 0 is not supported!\n");
907  }
908 
910  DPRINTF(GIC, "Gicv3Distributor::write(): (DS 0 non-secure)"
911  "EnableGrp1NS %d\n", EnableGrp1NS);
912  }
913  }
914 
915  update();
916 
917  break;
918 
919  case GICD_SGIR: // Error Reporting Status Register
920  // Only if affinity routing is disabled, RES0
921  break;
922 
923  case GICD_SETSPI_NSR: {
924  // Writes to this register have no effect if:
925  // * The value written specifies an invalid SPI.
926  // * The SPI is already pending.
927  // * The value written specifies a Secure SPI, the value is
928  // written by a Non-secure access, and the value of the
929  // corresponding GICD_NSACR<n> register is 0.
930  const uint32_t intid = bits(data, 9, 0);
931  if (isNotSPI(intid) || irqPending[intid] ||
932  (nsAccessToSecInt(intid, is_secure_access) &&
933  irqNsacr[intid] == 0)) {
934  return;
935  } else {
936  // Valid SPI, set interrupt pending
937  sendInt(intid);
938  }
939  break;
940  }
941 
942  case GICD_CLRSPI_NSR: {
943  // Writes to this register have no effect if:
944  // * The value written specifies an invalid SPI.
945  // * The SPI is not pending.
946  // * The value written specifies a Secure SPI, the value is
947  // written by a Non-secure access, and the value of the
948  // corresponding GICD_NSACR<n> register is less than 0b10.
949  const uint32_t intid = bits(data, 9, 0);
950  if (isNotSPI(intid) || !irqPending[intid] ||
951  (nsAccessToSecInt(intid, is_secure_access) &&
952  irqNsacr[intid] < 2)) {
953  return;
954  } else {
955  // Valid SPI, clear interrupt pending
956  deassertSPI(intid);
957  }
958  break;
959  }
960 
961  case GICD_SETSPI_SR: {
962  // Writes to this register have no effect if:
963  // * GICD_CTLR.DS = 1 (WI)
964  // * The value written specifies an invalid SPI.
965  // * The SPI is already pending.
966  // * The value is written by a Non-secure access.
967  const uint32_t intid = bits(data, 9, 0);
968  if (DS || isNotSPI(intid) || irqPending[intid] || !is_secure_access) {
969  return;
970  } else {
971  // Valid SPI, set interrupt pending
972  sendInt(intid);
973  }
974  break;
975  }
976 
977  case GICD_CLRSPI_SR: {
978  // Writes to this register have no effect if:
979  // * GICD_CTLR.DS = 1 (WI)
980  // * The value written specifies an invalid SPI.
981  // * The SPI is not pending.
982  // * The value is written by a Non-secure access.
983  const uint32_t intid = bits(data, 9, 0);
984  if (DS || isNotSPI(intid) || !irqPending[intid] || !is_secure_access) {
985  return;
986  } else {
987  // Valid SPI, clear interrupt pending
988  deassertSPI(intid);
989  }
990  break;
991  }
992 
993  default:
994  panic("Gicv3Distributor::write(): invalid offset %#x\n", addr);
995  break;
996  }
997 }
998 
999 void
1001 {
1002  panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!");
1003  panic_if(int_id > itLines, "Invalid SPI!");
1004  irqPending[int_id] = true;
1005  irqPendingIspendr[int_id] = false;
1006  DPRINTF(GIC, "Gicv3Distributor::sendInt(): "
1007  "int_id %d (SPI) pending bit set\n", int_id);
1008  update();
1009 }
1010 
1011 void
1013 {
1014  // Edge-triggered interrupts remain pending until software
1015  // writes GICD_ICPENDR, GICD_CLRSPI_* or activates them via ICC_IAR
1016  if (isLevelSensitive(int_id)) {
1017  deassertSPI(int_id);
1018  }
1019 }
1020 
1021 void
1023 {
1024  panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!");
1025  panic_if(int_id > itLines, "Invalid SPI!");
1026  irqPending[int_id] = false;
1027  clearIrqCpuInterface(int_id);
1028 
1029  update();
1030 }
1031 
1033 Gicv3Distributor::route(uint32_t int_id)
1034 {
1035  IROUTER affinity_routing = irqAffinityRouting[int_id];
1036  Gicv3Redistributor * target_redistributor = nullptr;
1037 
1038  const Gicv3::GroupId int_group = getIntGroup(int_id);
1039 
1040  if (affinity_routing.IRM) {
1041  // Interrupts routed to any PE defined as a participating node
1042  for (int i = 0; i < gic->getSystem()->threads.size(); i++) {
1043  Gicv3Redistributor * redistributor_i =
1045 
1046  if (redistributor_i->
1047  canBeSelectedFor1toNInterrupt(int_group)) {
1048  target_redistributor = redistributor_i;
1049  break;
1050  }
1051  }
1052  } else {
1053  uint32_t affinity = (affinity_routing.Aff3 << 24) |
1054  (affinity_routing.Aff2 << 16) |
1055  (affinity_routing.Aff1 << 8) |
1056  (affinity_routing.Aff0 << 0);
1057  target_redistributor =
1058  gic->getRedistributorByAffinity(affinity);
1059  }
1060 
1061  if (!target_redistributor) {
1062  // Interrrupts targeting not present cpus must remain pending
1063  return nullptr;
1064  } else {
1065  return target_redistributor->getCPUInterface();
1066  }
1067 }
1068 
1069 void
1071 {
1072  auto cpu_interface = route(int_id);
1073  if (cpu_interface)
1074  cpu_interface->resetHppi(int_id);
1075 }
1076 
1077 void
1079 {
1080  // Find the highest priority pending SPI
1081  for (int int_id = Gicv3::SGI_MAX + Gicv3::PPI_MAX; int_id < itLines;
1082  int_id++) {
1083  Gicv3::GroupId int_group = getIntGroup(int_id);
1084  bool group_enabled = groupEnabled(int_group);
1085 
1086  if (irqPending[int_id] && irqEnabled[int_id] &&
1087  !irqActive[int_id] && group_enabled) {
1088 
1089  // Find the cpu interface where to route the interrupt
1090  Gicv3CPUInterface *target_cpu_interface = route(int_id);
1091 
1092  // Invalid routing
1093  if (!target_cpu_interface) continue;
1094 
1095  if ((irqPriority[int_id] < target_cpu_interface->hppi.prio) ||
1096  (irqPriority[int_id] == target_cpu_interface->hppi.prio &&
1097  int_id < target_cpu_interface->hppi.intid)) {
1098 
1099  target_cpu_interface->hppi.intid = int_id;
1100  target_cpu_interface->hppi.prio = irqPriority[int_id];
1101  target_cpu_interface->hppi.group = int_group;
1102  }
1103  }
1104  }
1105 
1106  // Update all redistributors
1107  for (int i = 0; i < gic->getSystem()->threads.size(); i++) {
1109  }
1110 }
1111 
1113 Gicv3Distributor::intStatus(uint32_t int_id) const
1114 {
1115  panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!");
1116  panic_if(int_id > itLines, "Invalid SPI!");
1117 
1118  if (irqPending[int_id]) {
1119  if (irqActive[int_id]) {
1121  }
1122 
1123  return Gicv3::INT_PENDING;
1124  } else if (irqActive[int_id]) {
1125  return Gicv3::INT_ACTIVE;
1126  } else {
1127  return Gicv3::INT_INACTIVE;
1128  }
1129 }
1130 
1133 {
1134  panic_if(int_id < Gicv3::SGI_MAX + Gicv3::PPI_MAX, "Invalid SPI!");
1135  panic_if(int_id > itLines, "Invalid SPI!");
1136 
1137  if (DS) {
1138  if (irqGroup[int_id] == 1) {
1139  return Gicv3::G1NS;
1140  } else {
1141  return Gicv3::G0S;
1142  }
1143  } else {
1144  if (irqGrpmod[int_id] == 0 && irqGroup[int_id] == 0) {
1145  return Gicv3::G0S;
1146  } else if (irqGrpmod[int_id] == 0 && irqGroup[int_id] == 1) {
1147  return Gicv3::G1NS;
1148  } else if (irqGrpmod[int_id] == 1 && irqGroup[int_id] == 0) {
1149  return Gicv3::G1S;
1150  } else if (irqGrpmod[int_id] == 1 && irqGroup[int_id] == 1) {
1151  return Gicv3::G1NS;
1152  }
1153  }
1154 
1155  M5_UNREACHABLE;
1156 }
1157 
1158 void
1160 {
1161  if (treatAsEdgeTriggered(int_id)) {
1162  irqPending[int_id] = false;
1163  }
1164  irqActive[int_id] = true;
1165 }
1166 
1167 void
1169 {
1170  irqActive[int_id] = false;
1171 }
1172 
1173 void
1175 {
1191 }
1192 
1193 void
1195 {
1211 }
Gicv3::INT_EDGE_TRIGGERED
@ INT_EDGE_TRIGGERED
Definition: gic_v3.hh:98
gic_v3_cpu_interface.hh
Gicv3Distributor::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: gic_v3_distributor.cc:1194
Gicv3::INTID_SECURE
static const int INTID_SECURE
Definition: gic_v3.hh:72
Gicv3Distributor::GICD_PIDR3
@ GICD_PIDR3
Definition: gic_v3_distributor.hh:87
Gicv3Distributor::isNotSPI
bool isNotSPI(uint32_t int_id) const
Definition: gic_v3_distributor.hh:217
Gicv3Distributor::GICD_ICFGR
static const AddrRange GICD_ICFGR
Definition: gic_v3_distributor.hh:117
Gicv3Distributor::GICD_SETSPI_NSR
@ GICD_SETSPI_NSR
Definition: gic_v3_distributor.hh:71
Gicv3Distributor::gicdPidr1
uint32_t gicdPidr1
Definition: gic_v3_distributor.hh:164
Gicv3Redistributor::irqPendingIspendr
std::vector< bool > irqPendingIspendr
Definition: gic_v3_redistributor.hh:156
warn
#define warn(...)
Definition: logging.hh:239
Gicv3::G1NS
@ G1NS
Definition: gic_v3.hh:93
Gicv3Distributor::GICD_IIDR
@ GICD_IIDR
Definition: gic_v3_distributor.hh:67
gic_v3_redistributor.hh
Gicv3Distributor::GICD_PIDR2
@ GICD_PIDR2
Definition: gic_v3_distributor.hh:85
data
const char data[]
Definition: circlebuf.test.cc:42
Gicv3Distributor::GICD_IPRIORITYR
static const AddrRange GICD_IPRIORITYR
Definition: gic_v3_distributor.hh:113
Gicv3Distributor::irqEnabled
std::vector< bool > irqEnabled
Definition: gic_v3_distributor.hh:152
Gicv3::PPI_MAX
static const int PPI_MAX
Definition: gic_v3.hh:79
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:797
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
UNSERIALIZE_CONTAINER
#define UNSERIALIZE_CONTAINER(member)
Definition: serialize.hh:856
Gicv3CPUInterface::hppi
hppi_t hppi
Definition: gic_v3_cpu_interface.hh:160
Gicv3Distributor::ARE
bool ARE
Definition: gic_v3_distributor.hh:146
Gicv3Distributor::GICD_CTLR_DS
static const uint32_t GICD_CTLR_DS
Definition: gic_v3_distributor.hh:144
Gicv3Distributor::Gicv3Distributor
Gicv3Distributor(Gicv3 *gic, uint32_t it_lines)
Definition: gic_v3_distributor.cc:67
Gicv3::SGI_MAX
static const int SGI_MAX
Definition: gic_v3.hh:77
Gicv3Distributor::GICD_PIDR6
@ GICD_PIDR6
Definition: gic_v3_distributor.hh:93
Gicv3Distributor::GICD_ICACTIVER
static const AddrRange GICD_ICACTIVER
Definition: gic_v3_distributor.hh:111
Gicv3Distributor::GICD_STATUSR
@ GICD_STATUSR
Definition: gic_v3_distributor.hh:69
Gicv3Distributor::itLines
const uint32_t itLines
Definition: gic_v3_distributor.hh:59
Gicv3Distributor::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: gic_v3_distributor.cc:1174
Gicv3Redistributor::irqPending
std::vector< bool > irqPending
Definition: gic_v3_redistributor.hh:155
Gicv3Distributor::route
Gicv3CPUInterface * route(uint32_t int_id)
Definition: gic_v3_distributor.cc:1033
AddrRange::contains
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:435
Gicv3Distributor::GICD_NSACR
static const AddrRange GICD_NSACR
Definition: gic_v3_distributor.hh:121
Gicv3Distributor::GICD_TYPER
@ GICD_TYPER
Definition: gic_v3_distributor.hh:65
Gicv3Distributor::GICD_SETSPI_SR
@ GICD_SETSPI_SR
Definition: gic_v3_distributor.hh:75
Gicv3Distributor::intStatus
Gicv3::IntStatus intStatus(uint32_t int_id) const
Definition: gic_v3_distributor.cc:1113
Gicv3Distributor::getIntGroup
Gicv3::GroupId getIntGroup(int int_id) const
Definition: gic_v3_distributor.cc:1132
Gicv3Distributor::clearInt
void clearInt(uint32_t int_id)
Definition: gic_v3_distributor.cc:1012
Gicv3Distributor::irqActive
std::vector< bool > irqActive
Definition: gic_v3_distributor.hh:155
Gicv3::getRedistributorByAffinity
Gicv3Redistributor * getRedistributorByAffinity(uint32_t affinity) const
Definition: gic_v3.cc:237
Gicv3Redistributor::irqActive
std::vector< bool > irqActive
Definition: gic_v3_redistributor.hh:157
Gicv3Distributor::GICD_CTLR_ENABLEGRP1S
static const uint32_t GICD_CTLR_ENABLEGRP1S
Definition: gic_v3_distributor.hh:143
Gicv3Distributor::GICD_IGRPMODR
static const AddrRange GICD_IGRPMODR
Definition: gic_v3_distributor.hh:119
Trace::disable
void disable()
Definition: trace.cc:98
Gicv3Distributor::GICD_ICPENDR
static const AddrRange GICD_ICPENDR
Definition: gic_v3_distributor.hh:107
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
Gicv3Distributor::irqConfig
std::vector< Gicv3::IntTriggerType > irqConfig
Definition: gic_v3_distributor.hh:157
Gicv3Distributor::GICD_CTLR_ENABLEGRP1NS
static const uint32_t GICD_CTLR_ENABLEGRP1NS
Definition: gic_v3_distributor.hh:141
Gicv3::G0S
@ G0S
Definition: gic_v3.hh:91
Gicv3Distributor::GICD_PIDR7
@ GICD_PIDR7
Definition: gic_v3_distributor.hh:95
Gicv3::INT_ACTIVE_PENDING
@ INT_ACTIVE_PENDING
Definition: gic_v3.hh:86
Gicv3Distributor::GICD_SPENDSGIR
static const AddrRange GICD_SPENDSGIR
Definition: gic_v3_distributor.hh:125
Gicv3Redistributor::irqConfig
std::vector< Gicv3::IntTriggerType > irqConfig
Definition: gic_v3_redistributor.hh:159
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
divCeil
T divCeil(const T &a, const U &b)
Definition: intmath.hh:114
cp
Definition: cprintf.cc:40
Gicv3Distributor::gic
Gicv3 * gic
Definition: gic_v3_distributor.hh:58
Gicv3Distributor::GICD_CTLR_ENABLEGRP1A
static const uint32_t GICD_CTLR_ENABLEGRP1A
Definition: gic_v3_distributor.hh:142
Gicv3Distributor::irqGroup
std::vector< uint8_t > irqGroup
Definition: gic_v3_distributor.hh:151
ArmSystem::haveSecurity
bool haveSecurity() const
Returns true if this system implements the Security Extensions.
Definition: system.hh:161
AddrRange
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition: addr_range.hh:68
Gicv3Distributor::irqPendingIspendr
std::vector< bool > irqPendingIspendr
Definition: gic_v3_distributor.hh:154
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
Gicv3Distributor::EnableGrp1S
bool EnableGrp1S
Definition: gic_v3_distributor.hh:148
Gicv3::INT_ACTIVE
@ INT_ACTIVE
Definition: gic_v3.hh:85
Gicv3Distributor::groupEnabled
bool groupEnabled(Gicv3::GroupId group) const
Definition: gic_v3_distributor.hh:182
Gicv3Distributor::GICD_IROUTER
static const AddrRange GICD_IROUTER
Definition: gic_v3_distributor.hh:127
Gicv3Distributor::deactivateIRQ
void deactivateIRQ(uint32_t int_id)
Definition: gic_v3_distributor.cc:1168
Gicv3::IntStatus
IntStatus
Definition: gic_v3.hh:82
Gicv3Distributor::GICD_PIDR4
@ GICD_PIDR4
Definition: gic_v3_distributor.hh:89
Gicv3Distributor::gicdPidr0
uint32_t gicdPidr0
Definition: gic_v3_distributor.hh:163
Gicv3Distributor::read
uint64_t read(Addr addr, size_t size, bool is_secure_access)
Definition: gic_v3_distributor.cc:137
Gicv3
Definition: gic_v3.hh:53
Gicv3Distributor::GICD_PIDR5
@ GICD_PIDR5
Definition: gic_v3_distributor.hh:91
Gicv3Redistributor::getCPUInterface
Gicv3CPUInterface * getCPUInterface() const
Definition: gic_v3_redistributor.hh:202
Gicv3::GroupId
GroupId
Definition: gic_v3.hh:90
X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:769
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
Gicv3Distributor::GICD_CLRSPI_SR
@ GICD_CLRSPI_SR
Definition: gic_v3_distributor.hh:77
Gicv3::getRedistributor
Gicv3Redistributor * getRedistributor(ContextID context_id) const
Definition: gic_v3.hh:150
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:790
Gicv3Distributor::EnableGrp0
bool EnableGrp0
Definition: gic_v3_distributor.hh:150
Gicv3Distributor::irqGrpmod
std::vector< uint8_t > irqGrpmod
Definition: gic_v3_distributor.hh:158
Gicv3Distributor::gicdTyper
uint32_t gicdTyper
Definition: gic_v3_distributor.hh:162
Gicv3CPUInterface
Definition: gic_v3_cpu_interface.hh:50
Gicv3Distributor::GICD_PIDR1
@ GICD_PIDR1
Definition: gic_v3_distributor.hh:83
Gicv3Distributor::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_distributor.hh:242
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:197
Gicv3Distributor::GICD_CLRSPI_NSR
@ GICD_CLRSPI_NSR
Definition: gic_v3_distributor.hh:73
Gicv3Distributor::GICD_SGIR
@ GICD_SGIR
Definition: gic_v3_distributor.hh:79
Gicv3Distributor::GICD_ICENABLER
static const AddrRange GICD_ICENABLER
Definition: gic_v3_distributor.hh:103
Gicv3Distributor::init
void init()
Definition: gic_v3_distributor.cc:132
AddrRange::start
Addr start() const
Get the start address of the range.
Definition: addr_range.hh:314
Gicv3Distributor::GICD_ITARGETSR
static const AddrRange GICD_ITARGETSR
Definition: gic_v3_distributor.hh:115
X86ISA::enable
Bitfield< 11 > enable
Definition: misc.hh:1051
SERIALIZE_CONTAINER
#define SERIALIZE_CONTAINER(member)
Definition: serialize.hh:848
ArmISA::gic
Bitfield< 27, 24 > gic
Definition: miscregs_types.hh:171
Gicv3Distributor::irqPriority
std::vector< uint8_t > irqPriority
Definition: gic_v3_distributor.hh:156
Gicv3Distributor::deassertSPI
void deassertSPI(uint32_t int_id)
Definition: gic_v3_distributor.cc:1022
Gicv3Distributor::nsAccessToSecInt
bool nsAccessToSecInt(uint32_t int_id, bool is_secure_access) const
Definition: gic_v3_distributor.hh:247
Gicv3Distributor::GICD_CTLR
@ GICD_CTLR
Definition: gic_v3_distributor.hh:63
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
Gicv3Distributor::irqNsacr
std::vector< uint8_t > irqNsacr
Definition: gic_v3_distributor.hh:159
Gicv3::INT_PENDING
@ INT_PENDING
Definition: gic_v3.hh:84
Gicv3Redistributor::update
void update()
Definition: gic_v3_redistributor.cc:801
Gicv3Distributor::irqAffinityRouting
std::vector< IROUTER > irqAffinityRouting
Definition: gic_v3_distributor.hh:160
Gicv3Distributor::GICD_ISENABLER
static const AddrRange GICD_ISENABLER
Definition: gic_v3_distributor.hh:101
Gicv3Distributor::GICD_PIDR0
@ GICD_PIDR0
Definition: gic_v3_distributor.hh:81
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:63
Gicv3Distributor::isLevelSensitive
bool isLevelSensitive(uint32_t int_id) const
Definition: gic_v3_distributor.hh:226
Gicv3Distributor::GICD_ISPENDR
static const AddrRange GICD_ISPENDR
Definition: gic_v3_distributor.hh:105
BaseGic::getSystem
ArmSystem * getSystem() const
Definition: base_gic.hh:104
Gicv3Distributor::GICD_CPENDSGIR
static const AddrRange GICD_CPENDSGIR
Definition: gic_v3_distributor.hh:123
Gicv3Distributor::irqPending
std::vector< bool > irqPending
Definition: gic_v3_distributor.hh:153
Gicv3Distributor::gicdPidr4
uint32_t gicdPidr4
Definition: gic_v3_distributor.hh:167
Gicv3Distributor::clearIrqCpuInterface
void clearIrqCpuInterface(uint32_t int_id)
Definition: gic_v3_distributor.cc:1070
intmath.hh
Gicv3Redistributor::canBeSelectedFor1toNInterrupt
bool canBeSelectedFor1toNInterrupt(Gicv3::GroupId group) const
Definition: gic_v3_redistributor.cc:1027
CheckpointIn
Definition: serialize.hh:67
Gicv3Distributor::write
void write(Addr addr, uint64_t data, size_t size, bool is_secure_access)
Definition: gic_v3_distributor.cc:506
Gicv3CPUInterface::hppi_t::prio
uint8_t prio
Definition: gic_v3_cpu_interface.hh:156
Gicv3Distributor::gicdPidr2
uint32_t gicdPidr2
Definition: gic_v3_distributor.hh:165
gic_v3_distributor.hh
Gicv3Distributor::sendInt
void sendInt(uint32_t int_id)
Definition: gic_v3_distributor.cc:1000
Gicv3Distributor::GICD_IGROUPR
static const AddrRange GICD_IGROUPR
Definition: gic_v3_distributor.hh:99
Gicv3Distributor::IDBITS
static const uint32_t IDBITS
Definition: gic_v3_distributor.hh:172
gic_v3.hh
Gicv3Redistributor
Definition: gic_v3_redistributor.hh:52
Gicv3Distributor::EnableGrp1NS
bool EnableGrp1NS
Definition: gic_v3_distributor.hh:149
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
Gicv3Distributor::GICD_ISACTIVER
static const AddrRange GICD_ISACTIVER
Definition: gic_v3_distributor.hh:109
Gicv3Distributor::gicdPidr3
uint32_t gicdPidr3
Definition: gic_v3_distributor.hh:166
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
Gicv3Distributor::activateIRQ
void activateIRQ(uint32_t int_id)
Definition: gic_v3_distributor.cc:1159

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