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

Generated on Tue Sep 21 2021 12:25:13 for gem5 by doxygen 1.8.17