gem5  v21.1.0.2
gic_v2.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, 2013, 2015-2018, 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) 2005 The Regents of The University of Michigan
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 
41 #include "dev/arm/gic_v2.hh"
42 
43 #include "base/compiler.hh"
44 #include "base/trace.hh"
45 #include "cpu/base.hh"
46 #include "debug/Checkpoint.hh"
47 #include "debug/GIC.hh"
48 #include "debug/IPI.hh"
49 #include "debug/Interrupt.hh"
50 #include "mem/packet.hh"
51 #include "mem/packet_access.hh"
52 
53 namespace gem5
54 {
55 
56 const AddrRange GicV2::GICD_IGROUPR (0x080, 0x100);
57 const AddrRange GicV2::GICD_ISENABLER (0x100, 0x180);
58 const AddrRange GicV2::GICD_ICENABLER (0x180, 0x200);
59 const AddrRange GicV2::GICD_ISPENDR (0x200, 0x280);
60 const AddrRange GicV2::GICD_ICPENDR (0x280, 0x300);
61 const AddrRange GicV2::GICD_ISACTIVER (0x300, 0x380);
62 const AddrRange GicV2::GICD_ICACTIVER (0x380, 0x400);
63 const AddrRange GicV2::GICD_IPRIORITYR(0x400, 0x800);
64 const AddrRange GicV2::GICD_ITARGETSR (0x800, 0xc00);
65 const AddrRange GicV2::GICD_ICFGR (0xc00, 0xd00);
66 
68  : BaseGic(p),
69  gicdPIDR(p.gicd_pidr),
70  gicdIIDR(p.gicd_iidr),
71  giccIIDR(p.gicc_iidr),
72  distRange(RangeSize(p.dist_addr, DIST_SIZE)),
73  cpuRange(RangeSize(p.cpu_addr, p.cpu_size)),
74  addrRanges{distRange, cpuRange},
75  distPioDelay(p.dist_pio_delay),
76  cpuPioDelay(p.cpu_pio_delay), intLatency(p.int_latency),
77  enabled(false), haveGem5Extensions(p.gem5_extensions),
78  itLines(p.it_lines),
79  intEnabled {}, pendingInt {}, activeInt {},
80  intPriority {}, intConfig {}, cpuTarget {},
81  cpuSgiPending {}, cpuSgiActive {},
82  cpuSgiPendingExt {}, cpuSgiActiveExt {},
83  cpuPpiPending {}, cpuPpiActive {},
84  pendingDelayedInterrupts(0)
85 {
86  for (int x = 0; x < CPU_MAX; x++) {
87  iccrpr[x] = 0xff;
88  cpuControl[x] = 0;
89  cpuPriority[x] = 0xff;
90  cpuBpr[x] = GICC_BPR_MINIMUM;
91  // Initialize cpu highest int
92  cpuHighestInt[x] = SPURIOUS_INT;
93  postIntEvent[x] =
94  new EventFunctionWrapper([this, x]{ postDelayedInt(x); },
95  "Post Interrupt to CPU");
96  postFiqEvent[x] =
97  new EventFunctionWrapper([this, x]{ postDelayedFiq(x); },
98  "Post FIQ to CPU");
99  }
100  DPRINTF(Interrupt, "cpuEnabled[0]=%d cpuEnabled[1]=%d\n", cpuEnabled(0),
101  cpuEnabled(1));
102 
103  gem5ExtensionsEnabled = false;
104 }
105 
107 {
108  for (int x = 0; x < CPU_MAX; x++) {
109  delete postIntEvent[x];
110  delete postFiqEvent[x];
111  }
112 }
113 
114 Tick
116 {
117  const Addr addr = pkt->getAddr();
118 
119  if (distRange.contains(addr))
120  return readDistributor(pkt);
121  else if (cpuRange.contains(addr))
122  return readCpu(pkt);
123  else
124  panic("Read to unknown address %#x\n", pkt->getAddr());
125 }
126 
127 
128 Tick
130 {
131  const Addr addr = pkt->getAddr();
132 
133  if (distRange.contains(addr))
134  return writeDistributor(pkt);
135  else if (cpuRange.contains(addr))
136  return writeCpu(pkt);
137  else
138  panic("Write to unknown address %#x\n", pkt->getAddr());
139 }
140 
141 Tick
143 {
144  const Addr daddr = pkt->getAddr() - distRange.start();
145  const ContextID ctx = pkt->req->contextId();
146 
147  DPRINTF(GIC, "gic distributor read register %#x\n", daddr);
148 
149  const uint32_t resp = readDistributor(ctx, daddr, pkt->getSize());
150 
151  switch (pkt->getSize()) {
152  case 1:
153  pkt->setLE<uint8_t>(resp);
154  break;
155  case 2:
156  pkt->setLE<uint16_t>(resp);
157  break;
158  case 4:
159  pkt->setLE<uint32_t>(resp);
160  break;
161  default:
162  panic("Invalid size while reading Distributor regs in GIC: %d\n",
163  pkt->getSize());
164  }
165 
166  pkt->makeAtomicResponse();
167  return distPioDelay;
168 }
169 
170 uint32_t
171 GicV2::readDistributor(ContextID ctx, Addr daddr, size_t resp_sz)
172 {
173  if (GICD_IGROUPR.contains(daddr)) {
174  uint32_t ix = (daddr - GICD_IGROUPR.start()) >> 2;
175  assert(ix < 32);
176  return getIntGroup(ctx, ix);
177  }
178 
179  if (GICD_ISENABLER.contains(daddr)) {
180  uint32_t ix = (daddr - GICD_ISENABLER.start()) >> 2;
181  assert(ix < 32);
182  return getIntEnabled(ctx, ix);
183  }
184 
185  if (GICD_ICENABLER.contains(daddr)) {
186  uint32_t ix = (daddr - GICD_ICENABLER.start()) >> 2;
187  assert(ix < 32);
188  return getIntEnabled(ctx, ix);
189  }
190 
191  if (GICD_ISPENDR.contains(daddr)) {
192  uint32_t ix = (daddr - GICD_ISPENDR.start()) >> 2;
193  assert(ix < 32);
194  return getPendingInt(ctx, ix);
195  }
196 
197  if (GICD_ICPENDR.contains(daddr)) {
198  uint32_t ix = (daddr - GICD_ICPENDR.start()) >> 2;
199  assert(ix < 32);
200  return getPendingInt(ctx, ix);
201  }
202 
203  if (GICD_ISACTIVER.contains(daddr)) {
204  uint32_t ix = (daddr - GICD_ISACTIVER.start()) >> 2;
205  assert(ix < 32);
206  return getActiveInt(ctx, ix);
207  }
208 
209  if (GICD_ICACTIVER.contains(daddr)) {
210  uint32_t ix = (daddr - GICD_ICACTIVER.start()) >> 2;
211  assert(ix < 32);
212  return getActiveInt(ctx, ix);
213  }
214 
215  if (GICD_IPRIORITYR.contains(daddr)) {
216  Addr int_num = daddr - GICD_IPRIORITYR.start();
217  assert(int_num < INT_LINES_MAX);
218  DPRINTF(Interrupt, "Reading interrupt priority at int# %#x \n",
219  int_num);
220 
221  switch (resp_sz) {
222  default: // will panic() after return to caller anyway
223  case 1:
224  return getIntPriority(ctx, int_num);
225  case 2:
226  assert((int_num + 1) < INT_LINES_MAX);
227  return (getIntPriority(ctx, int_num) |
228  getIntPriority(ctx, int_num+1) << 8);
229  case 4:
230  assert((int_num + 3) < INT_LINES_MAX);
231  return (getIntPriority(ctx, int_num) |
232  getIntPriority(ctx, int_num+1) << 8 |
233  getIntPriority(ctx, int_num+2) << 16 |
234  getIntPriority(ctx, int_num+3) << 24);
235  }
236  }
237 
238  if (GICD_ITARGETSR.contains(daddr)) {
239  Addr int_num = daddr - GICD_ITARGETSR.start();
240  DPRINTF(GIC, "Reading processor target register for int# %#x \n",
241  int_num);
242  assert(int_num < INT_LINES_MAX);
243 
244  if (resp_sz == 1) {
245  return getCpuTarget(ctx, int_num);
246  } else {
247  assert(resp_sz == 4);
248  int_num = mbits(int_num, 31, 2);
249  return (getCpuTarget(ctx, int_num) |
250  getCpuTarget(ctx, int_num+1) << 8 |
251  getCpuTarget(ctx, int_num+2) << 16 |
252  getCpuTarget(ctx, int_num+3) << 24) ;
253  }
254  }
255 
256  if (GICD_ICFGR.contains(daddr)) {
257  uint32_t ix = (daddr - GICD_ICFGR.start()) >> 2;
258  return getIntConfig(ctx, ix);
259  }
260 
261  switch(daddr) {
262  case GICD_CTLR:
263  return enabled;
264  case GICD_TYPER:
265  /* The 0x100 is a made-up flag to show that gem5 extensions
266  * are available,
267  * write 0x200 to this register to enable it. */
268  return (((sys->threads.numRunning() - 1) << 5) |
269  (itLines/INT_BITS_MAX -1) |
270  (haveGem5Extensions ? 0x100 : 0x0));
271  case GICD_PIDR0:
272  //ARM defined DevID
273  return (gicdPIDR & 0xFF);
274  case GICD_PIDR1:
275  return ((gicdPIDR >> 8) & 0xFF);
276  case GICD_PIDR2:
277  return ((gicdPIDR >> 16) & 0xFF);
278  case GICD_PIDR3:
279  return ((gicdPIDR >> 24) & 0xFF);
280  case GICD_IIDR:
281  /* revision id is resorted to 1 and variant to 0*/
282  return gicdIIDR;
283  default:
284  panic("Tried to read Gic distributor at offset %#x\n", daddr);
285  break;
286  }
287 }
288 
289 Tick
291 {
292  const Addr daddr = pkt->getAddr() - cpuRange.start();
293 
294  assert(pkt->req->hasContextId());
295  const ContextID ctx = pkt->req->contextId();
296  assert(ctx < sys->threads.numRunning());
297 
298  DPRINTF(GIC, "gic cpu read register %#x cpu context: %d\n", daddr, ctx);
299 
300  pkt->setLE<uint32_t>(readCpu(ctx, daddr));
301 
302  pkt->makeAtomicResponse();
303  return cpuPioDelay;
304 }
305 
306 uint32_t
308 {
309  switch(daddr) {
310  case GICC_IIDR:
311  return giccIIDR;
312  case GICC_CTLR:
313  return cpuControl[ctx];
314  case GICC_PMR:
315  return cpuPriority[ctx];
316  case GICC_BPR:
317  return cpuBpr[ctx];
318  case GICC_IAR:
319  if (enabled && cpuEnabled(ctx)) {
320  int active_int = cpuHighestInt[ctx];
321  IAR iar = 0;
322  iar.ack_id = active_int;
323  iar.cpu_id = 0;
324  if (active_int < SGI_MAX) {
325  // this is a software interrupt from another CPU
326  if (!gem5ExtensionsEnabled) {
327  panic_if(!cpuSgiPending[active_int],
328  "Interrupt %d active but no CPU generated it?\n",
329  active_int);
330  for (int x = 0; x < sys->threads.numRunning(); x++) {
331  // See which CPU generated the interrupt
332  uint8_t cpugen =
333  bits(cpuSgiPending[active_int], 7 + 8 * x, 8 * x);
334  if (cpugen & (1 << ctx)) {
335  iar.cpu_id = x;
336  break;
337  }
338  }
339  uint64_t sgi_num = 1ULL << (ctx + 8 * iar.cpu_id);
340  cpuSgiActive[iar.ack_id] |= sgi_num;
341  cpuSgiPending[iar.ack_id] &= ~sgi_num;
342  } else {
343  uint64_t sgi_num = 1ULL << iar.ack_id;
344  cpuSgiActiveExt[ctx] |= sgi_num;
345  cpuSgiPendingExt[ctx] &= ~sgi_num;
346  }
347  } else if (active_int < (SGI_MAX + PPI_MAX) ) {
348  uint32_t int_num = 1 << (cpuHighestInt[ctx] - SGI_MAX);
349  cpuPpiActive[ctx] |= int_num;
350  updateRunPri();
351  if (!isLevelSensitive(ctx, active_int)) {
352  cpuPpiPending[ctx] &= ~int_num;
353  }
354 
355  } else {
356  uint32_t int_num = 1 << intNumToBit(cpuHighestInt[ctx]);
357  getActiveInt(ctx, intNumToWord(cpuHighestInt[ctx])) |= int_num;
358  updateRunPri();
359  if (!isLevelSensitive(ctx, active_int)) {
361  &= ~int_num;
362  }
363  }
364 
366  "CPU %d reading IAR.id=%d IAR.cpu=%d, iar=0x%x\n",
367  ctx, iar.ack_id, iar.cpu_id, iar);
369  updateIntState(-1);
370  clearInt(ctx, active_int);
371  return iar;
372  } else {
373  return SPURIOUS_INT;
374  }
375 
376  break;
377  case GICC_RPR:
378  return iccrpr[0];
379  case GICC_HPPIR:
380  panic("Need to implement HPIR");
381  break;
382  default:
383  panic("Tried to read Gic cpu at offset %#x\n", daddr);
384  break;
385  }
386 }
387 
388 Tick
390 {
391  const Addr daddr = pkt->getAddr() - distRange.start();
392 
393  assert(pkt->req->hasContextId());
394  const ContextID ctx = pkt->req->contextId();
395  const size_t data_sz = pkt->getSize();
396 
397  GEM5_VAR_USED uint32_t pkt_data;
398  switch (data_sz)
399  {
400  case 1:
401  pkt_data = pkt->getLE<uint8_t>();
402  break;
403  case 2:
404  pkt_data = pkt->getLE<uint16_t>();
405  break;
406  case 4:
407  pkt_data = pkt->getLE<uint32_t>();
408  break;
409  default:
410  panic("Invalid size when writing to priority regs in Gic: %d\n",
411  data_sz);
412  }
413 
414  DPRINTF(GIC, "gic distributor write register %#x size %#x value %#x \n",
415  daddr, data_sz, pkt_data);
416 
417  writeDistributor(ctx, daddr, pkt_data, data_sz);
418 
419  pkt->makeAtomicResponse();
420  return distPioDelay;
421 }
422 
423 void
425  size_t data_sz)
426 {
427  if (GICD_IGROUPR.contains(daddr)) {
428  uint32_t ix = (daddr - GICD_IGROUPR.start()) >> 2;
429  assert(ix < 32);
430  getIntGroup(ctx, ix) |= data;
431  return;
432  }
433 
434  if (GICD_ISENABLER.contains(daddr)) {
435  uint32_t ix = (daddr - GICD_ISENABLER.start()) >> 2;
436  assert(ix < 32);
437  getIntEnabled(ctx, ix) |= data;
438  return;
439  }
440 
441  if (GICD_ICENABLER.contains(daddr)) {
442  uint32_t ix = (daddr - GICD_ICENABLER.start()) >> 2;
443  assert(ix < 32);
444  getIntEnabled(ctx, ix) &= ~data;
445  return;
446  }
447 
448  if (GICD_ISPENDR.contains(daddr)) {
449  uint32_t ix = (daddr - GICD_ISPENDR.start()) >> 2;
450  auto mask = data;
451  if (ix == 0) mask &= SGI_MASK; // Don't allow SGIs to be changed
452  getPendingInt(ctx, ix) |= mask;
453  updateIntState(ix);
454  return;
455  }
456 
457  if (GICD_ICPENDR.contains(daddr)) {
458  uint32_t ix = (daddr - GICD_ICPENDR.start()) >> 2;
459  auto mask = data;
460  if (ix == 0) mask &= SGI_MASK; // Don't allow SGIs to be changed
461  getPendingInt(ctx, ix) &= ~mask;
462  updateIntState(ix);
463  return;
464  }
465 
466  if (GICD_ISACTIVER.contains(daddr)) {
467  uint32_t ix = (daddr - GICD_ISACTIVER.start()) >> 2;
468  getActiveInt(ctx, ix) |= data;
469  return;
470  }
471 
472  if (GICD_ICACTIVER.contains(daddr)) {
473  uint32_t ix = (daddr - GICD_ICACTIVER.start()) >> 2;
474  getActiveInt(ctx, ix) &= ~data;
475  return;
476  }
477 
478  if (GICD_IPRIORITYR.contains(daddr)) {
479  Addr int_num = daddr - GICD_IPRIORITYR.start();
480  switch(data_sz) {
481  case 1:
482  getIntPriority(ctx, int_num) = data;
483  break;
484  case 2: {
485  getIntPriority(ctx, int_num) = bits(data, 7, 0);
486  getIntPriority(ctx, int_num + 1) = bits(data, 15, 8);
487  break;
488  }
489  case 4: {
490  getIntPriority(ctx, int_num) = bits(data, 7, 0);
491  getIntPriority(ctx, int_num + 1) = bits(data, 15, 8);
492  getIntPriority(ctx, int_num + 2) = bits(data, 23, 16);
493  getIntPriority(ctx, int_num + 3) = bits(data, 31, 24);
494  break;
495  }
496  default:
497  panic("Invalid size when writing to priority regs in Gic: %d\n",
498  data_sz);
499  }
500 
501  updateIntState(-1);
502  updateRunPri();
503  return;
504  }
505 
506  if (GICD_ITARGETSR.contains(daddr)) {
507  Addr int_num = daddr - GICD_ITARGETSR.start();
508  // Interrupts 0-31 are read only
509  unsigned offset = SGI_MAX + PPI_MAX;
510  if (int_num >= offset) {
511  unsigned ix = int_num - offset; // index into cpuTarget array
512  if (data_sz == 1) {
513  cpuTarget[ix] = data & 0xff;
514  } else {
515  assert (data_sz == 4);
516  cpuTarget[ix] = bits(data, 7, 0);
517  cpuTarget[ix+1] = bits(data, 15, 8);
518  cpuTarget[ix+2] = bits(data, 23, 16);
519  cpuTarget[ix+3] = bits(data, 31, 24);
520  }
521  updateIntState(int_num >> 2);
522  }
523  return;
524  }
525 
526  if (GICD_ICFGR.contains(daddr)) {
527  uint32_t ix = (daddr - GICD_ICFGR.start()) >> 2;
528  // Since the GICD_ICFGR0 is RO (WI), we are discarding the write
529  // if ix = 0
530  if (ix != 0)
531  getIntConfig(ctx, ix) = data;
532  if (data & NN_CONFIG_MASK)
533  warn("GIC N:N mode selected and not supported at this time\n");
534  return;
535  }
536 
537  switch(daddr) {
538  case GICD_CTLR:
539  enabled = data;
540  DPRINTF(Interrupt, "Distributor enable flag set to = %d\n", enabled);
541  break;
542  case GICD_TYPER:
543  /* 0x200 is a made-up flag to enable gem5 extension functionality.
544  * This reg is not normally written.
545  */
547  DPRINTF(GIC, "gem5 extensions %s\n",
548  gem5ExtensionsEnabled ? "enabled" : "disabled");
549  break;
550  case GICD_SGIR:
551  softInt(ctx, data);
552  break;
553  default:
554  panic("Tried to write Gic distributor at offset %#x\n", daddr);
555  break;
556  }
557 }
558 
559 Tick
561 {
562  const Addr daddr = pkt->getAddr() - cpuRange.start();
563 
564  assert(pkt->req->hasContextId());
565  const ContextID ctx = pkt->req->contextId();
566  const uint32_t data = pkt->getLE<uint32_t>();
567 
568  DPRINTF(GIC, "gic cpu write register cpu:%d %#x val: %#x\n",
569  ctx, daddr, data);
570 
571  writeCpu(ctx, daddr, data);
572 
573  pkt->makeAtomicResponse();
574  return cpuPioDelay;
575 }
576 
577 void
578 GicV2::writeCpu(ContextID ctx, Addr daddr, uint32_t data)
579 {
580  switch(daddr) {
581  case GICC_CTLR:
582  cpuControl[ctx] = data;
583  break;
584  case GICC_PMR:
585  cpuPriority[ctx] = data;
586  break;
587  case GICC_BPR: {
588  auto bpr = data & 0x7;
589  if (bpr < GICC_BPR_MINIMUM)
590  bpr = GICC_BPR_MINIMUM;
591  cpuBpr[ctx] = bpr;
592  break;
593  }
594  case GICC_EOIR: {
595  const IAR iar = data;
596  if (iar.ack_id < SGI_MAX) {
597  // Clear out the bit that corresponds to the cleared int
598  uint64_t clr_int = 1ULL << (ctx + 8 * iar.cpu_id);
599  if (!(cpuSgiActive[iar.ack_id] & clr_int) &&
600  !(cpuSgiActiveExt[ctx] & (1 << iar.ack_id)))
601  panic("Done handling a SGI that isn't active?\n");
603  cpuSgiActiveExt[ctx] &= ~(1 << iar.ack_id);
604  else
605  cpuSgiActive[iar.ack_id] &= ~clr_int;
606  } else if (iar.ack_id < (SGI_MAX + PPI_MAX) ) {
607  uint32_t int_num = 1 << (iar.ack_id - SGI_MAX);
608  if (!(cpuPpiActive[ctx] & int_num))
609  warn("CPU %d Done handling a PPI interrupt "
610  "that isn't active?\n", ctx);
611  cpuPpiActive[ctx] &= ~int_num;
612  } else {
613  uint32_t int_num = 1 << intNumToBit(iar.ack_id);
614  if (!(getActiveInt(ctx, intNumToWord(iar.ack_id)) & int_num))
615  warn("Done handling interrupt that isn't active: %d\n",
616  intNumToBit(iar.ack_id));
617  getActiveInt(ctx, intNumToWord(iar.ack_id)) &= ~int_num;
618  }
619  updateRunPri();
620  DPRINTF(Interrupt, "CPU %d done handling intr IAR = %d from cpu %d\n",
621  ctx, iar.ack_id, iar.cpu_id);
622  break;
623  }
624  case GICC_APR0:
625  case GICC_APR1:
626  case GICC_APR2:
627  case GICC_APR3:
628  warn("GIC APRn write ignored because not implemented: %#x\n", daddr);
629  break;
630  case GICC_DIR:
631  warn("GIC DIR write ignored because not implemented: %#x\n", daddr);
632  break;
633  default:
634  panic("Tried to write Gic cpu at offset %#x\n", daddr);
635  break;
636  }
637  if (cpuEnabled(ctx)) updateIntState(-1);
638 }
639 
642  if (bankedRegs.size() <= ctx)
643  bankedRegs.resize(ctx + 1);
644 
645  if (!bankedRegs[ctx])
646  bankedRegs[ctx] = new BankedRegs;
647  return *bankedRegs[ctx];
648 }
649 
650 void
652 {
653  if (gem5ExtensionsEnabled) {
654  switch (swi.list_type) {
655  case 0: {
656  // interrupt cpus specified
657  int dest = swi.cpu_list;
658  DPRINTF(IPI, "Generating softIRQ from CPU %d for CPU %d\n",
659  ctx, dest);
660  if (cpuEnabled(dest)) {
661  cpuSgiPendingExt[dest] |= (1 << swi.sgi_id);
662  DPRINTF(IPI, "SGI[%d]=%#x\n", dest,
663  cpuSgiPendingExt[dest]);
664  }
665  } break;
666  case 1: {
667  // interrupt all
668  for (int i = 0; i < sys->threads.size(); i++) {
669  DPRINTF(IPI, "Processing CPU %d\n", i);
670  if (!cpuEnabled(i))
671  continue;
672  cpuSgiPendingExt[i] |= 1 << swi.sgi_id;
673  DPRINTF(IPI, "SGI[%d]=%#x\n", swi.sgi_id,
675  }
676  } break;
677  case 2: {
678  // Interrupt requesting cpu only
679  DPRINTF(IPI, "Generating softIRQ from CPU %d for CPU %d\n",
680  ctx, ctx);
681  if (cpuEnabled(ctx)) {
682  cpuSgiPendingExt[ctx] |= (1 << swi.sgi_id);
683  DPRINTF(IPI, "SGI[%d]=%#x\n", ctx,
684  cpuSgiPendingExt[ctx]);
685  }
686  } break;
687  }
688  } else {
689  switch (swi.list_type) {
690  case 1:
691  // interrupt all
692  uint8_t cpu_list;
693  cpu_list = 0;
694  for (int x = 0; x < sys->threads.size(); x++)
695  cpu_list |= cpuEnabled(x) ? 1 << x : 0;
696  swi.cpu_list = cpu_list;
697  break;
698  case 2:
699  // interrupt requesting cpu only
700  swi.cpu_list = 1 << ctx;
701  break;
702  // else interrupt cpus specified
703  }
704 
705  DPRINTF(IPI, "Generating softIRQ from CPU %d for %#x\n", ctx,
706  swi.cpu_list);
707  for (int i = 0; i < sys->threads.size(); i++) {
708  DPRINTF(IPI, "Processing CPU %d\n", i);
709  if (!cpuEnabled(i))
710  continue;
711  if (swi.cpu_list & (1 << i))
712  cpuSgiPending[swi.sgi_id] |= (1 << i) << (8 * ctx);
713  DPRINTF(IPI, "SGI[%d]=%#x\n", swi.sgi_id,
714  cpuSgiPending[swi.sgi_id]);
715  }
716  }
717  updateIntState(-1);
718 }
719 
720 uint64_t
722 {
723  panic_if(cpu > sys->threads.size(), "Invalid CPU ID.");
724  return 0x0101010101010101ULL << cpu;
725 }
726 
727 uint8_t
729 {
730  // see Table 3-2 in IHI0048B.b (GICv2)
731  // mask some low-order priority bits per BPR value
732  // NB: the GIC prioritization scheme is upside down:
733  // lower values are higher priority; masking off bits
734  // actually creates a higher priority, not lower.
735  return cpuPriority[cpu] & (0xff00 >> (7 - cpuBpr[cpu]));
736 }
737 
738 void
740 {
741  for (int cpu = 0; cpu < sys->threads.size(); cpu++) {
742  if (!cpuEnabled(cpu))
743  continue;
744 
745  /*@todo use hint to do less work. */
746  int highest_int = SPURIOUS_INT;
747  // Priorities below that set in GICC_PMR can be ignored
748  uint8_t highest_pri = getCpuPriority(cpu);
749 
750  // Check SGIs
751  for (int swi = 0; swi < SGI_MAX; swi++) {
752  if (!cpuSgiPending[swi] && !cpuSgiPendingExt[cpu])
753  continue;
754  if ((cpuSgiPending[swi] & genSwiMask(cpu)) ||
755  (cpuSgiPendingExt[cpu] & (1 << swi)))
756  if (highest_pri > getIntPriority(cpu, swi)) {
757  highest_pri = getIntPriority(cpu, swi);
758  highest_int = swi;
759  }
760  }
761 
762  // Check PPIs
763  if (cpuPpiPending[cpu]) {
764  for (int ppi_idx = 0, int_num = SGI_MAX;
765  int_num < PPI_MAX + SGI_MAX;
766  ppi_idx++, int_num++) {
767 
768  const bool ppi_pending = bits(cpuPpiPending[cpu], ppi_idx);
769  const bool ppi_enabled = bits(getIntEnabled(cpu, 0), int_num);
770  const bool higher_priority =
771  highest_pri > getIntPriority(cpu, int_num);
772 
773  if (ppi_pending && ppi_enabled && higher_priority) {
774  highest_pri = getIntPriority(cpu, int_num);
775  highest_int = int_num;
776  }
777  }
778  }
779 
780  bool mp_sys = sys->threads.numRunning() > 1;
781  // Check other ints
782  for (int x = 0; x < (itLines/INT_BITS_MAX); x++) {
783  if (getIntEnabled(cpu, x) & getPendingInt(cpu, x)) {
784  for (int y = 0; y < INT_BITS_MAX; y++) {
785  uint32_t int_nm = x * INT_BITS_MAX + y;
786  DPRINTF(GIC, "Checking for interrupt# %d \n",int_nm);
787  /* Set current pending int as highest int for current cpu
788  if the interrupt's priority higher than current priority
789  and if current cpu is the target (for mp configs only)
790  */
791  if ((bits(getIntEnabled(cpu, x), y)
792  &bits(getPendingInt(cpu, x), y)) &&
793  (getIntPriority(cpu, int_nm) < highest_pri))
794  if ((!mp_sys) ||
796  ? (getCpuTarget(cpu, int_nm) == cpu)
797  : (getCpuTarget(cpu, int_nm) & (1 << cpu)))) {
798  highest_pri = getIntPriority(cpu, int_nm);
799  highest_int = int_nm;
800  }
801  }
802  }
803  }
804 
805  uint32_t prev_highest = cpuHighestInt[cpu];
806  cpuHighestInt[cpu] = highest_int;
807 
808  if (highest_int == SPURIOUS_INT) {
809  if (isLevelSensitive(cpu, prev_highest)) {
810 
811  DPRINTF(Interrupt, "Clear IRQ for cpu%d\n", cpu);
812  clearInt(cpu, prev_highest);
813  }
814  continue;
815  }
816 
817  /* @todo make this work for more than one cpu, need to handle 1:N, N:N
818  * models */
819  if (enabled && cpuEnabled(cpu) &&
820  (highest_pri < getCpuPriority(cpu)) &&
821  !(getActiveInt(cpu, intNumToWord(highest_int))
822  & (1 << intNumToBit(highest_int)))) {
823 
824  DPRINTF(Interrupt, "Posting interrupt %d to cpu%d\n", highest_int,
825  cpu);
826 
827  if (isFiq(cpu, highest_int)) {
828  postFiq(cpu, curTick() + intLatency);
829  } else {
830  postInt(cpu, curTick() + intLatency);
831  }
832  }
833  }
834 }
835 
836 void
838 {
839  for (int cpu = 0; cpu < sys->threads.size(); cpu++) {
840  if (!cpuEnabled(cpu))
841  continue;
842  uint8_t maxPriority = 0xff;
843  for (int i = 0; i < itLines; i++) {
844  if (i < SGI_MAX) {
845  if (((cpuSgiActive[i] & genSwiMask(cpu)) ||
846  (cpuSgiActiveExt[cpu] & (1 << i))) &&
847  (getIntPriority(cpu, i) < maxPriority))
848  maxPriority = getIntPriority(cpu, i);
849  } else if (i < (SGI_MAX + PPI_MAX)) {
850  if ((cpuPpiActive[cpu] & ( 1 << (i - SGI_MAX))) &&
851  (getIntPriority(cpu, i) < maxPriority))
852  maxPriority = getIntPriority(cpu, i);
853 
854  } else {
855  if (getActiveInt(cpu, intNumToWord(i))
856  & (1 << intNumToBit(i)))
857  if (getIntPriority(cpu, i) < maxPriority)
858  maxPriority = getIntPriority(cpu, i);
859  }
860  }
861  iccrpr[cpu] = maxPriority;
862  }
863 }
864 
865 void
866 GicV2::sendInt(uint32_t num)
867 {
868  uint8_t target = getCpuTarget(0, num);
869  DPRINTF(Interrupt, "Received Interrupt number %d, cpuTarget %#x: \n",
870  num, target);
871  if ((target & (target - 1)) && !gem5ExtensionsEnabled)
872  panic("Multiple targets for peripheral interrupts is not supported\n");
873  panic_if(num < SGI_MAX + PPI_MAX,
874  "sentInt() must only be used for interrupts 32 and higher");
875  getPendingInt(target, intNumToWord(num)) |= 1 << intNumToBit(num);
877 }
878 
879 void
880 GicV2::sendPPInt(uint32_t num, uint32_t cpu)
881 {
882  DPRINTF(Interrupt, "Received PPI %d, cpuTarget %#x: \n",
883  num, cpu);
884  cpuPpiPending[cpu] |= 1 << (num - SGI_MAX);
886 }
887 
888 void
889 GicV2::clearInt(uint32_t num)
890 {
891  if (isLevelSensitive(0, num)) {
892  uint8_t target = getCpuTarget(0, num);
893 
895  "Received Clear interrupt number %d, cpuTarget %#x:\n",
896  num, target);
897 
898  getPendingInt(target, intNumToWord(num)) &= ~(1 << intNumToBit(num));
900  } else {
901  /* Nothing to do :
902  * Edge-triggered interrupt remain pending until software
903  * writes GICD_ICPENDR or reads GICC_IAR */
904  }
905 }
906 
907 void
908 GicV2::clearPPInt(uint32_t num, uint32_t cpu)
909 {
910  if (isLevelSensitive(cpu, num)) {
911  DPRINTF(Interrupt, "Clearing PPI %d, cpuTarget %#x: \n",
912  num, cpu);
913  cpuPpiPending[cpu] &= ~(1 << (num - SGI_MAX));
915  } else {
916  /* Nothing to do :
917  * Edge-triggered interrupt remain pending until software
918  * writes GICD_ICPENDR or reads GICC_IAR */
919  }
920 }
921 
922 void
923 GicV2::clearInt(ContextID ctx, uint32_t int_num)
924 {
925  auto tc = sys->threads[ctx];
926  if (isFiq(ctx, int_num)) {
927  tc->getCpuPtr()->clearInterrupt(tc->threadId(), ArmISA::INT_FIQ, 0);
928  } else {
929  tc->getCpuPtr()->clearInterrupt(tc->threadId(), ArmISA::INT_IRQ, 0);
930  }
931 }
932 
933 void
934 GicV2::postInt(uint32_t cpu, Tick when)
935 {
936  if (!(postIntEvent[cpu]->scheduled())) {
938  eventq->schedule(postIntEvent[cpu], when);
939  }
940 }
941 
942 void
944 {
945  auto tc = sys->threads[cpu];
946  tc->getCpuPtr()->postInterrupt(tc->threadId(), ArmISA::INT_IRQ, 0);
948  assert(pendingDelayedInterrupts >= 0);
949  if (pendingDelayedInterrupts == 0)
950  signalDrainDone();
951 }
952 
953 void
954 GicV2::postFiq(uint32_t cpu, Tick when)
955 {
956  if (!(postFiqEvent[cpu]->scheduled())) {
958  eventq->schedule(postFiqEvent[cpu], when);
959  }
960 }
961 
962 bool
964 {
965  return version == GicVersion::GIC_V2;
966 }
967 
968 void
970 {
971  auto tc = sys->threads[cpu];
972  tc->getCpuPtr()->postInterrupt(tc->threadId(), ArmISA::INT_FIQ, 0);
974  assert(pendingDelayedInterrupts >= 0);
975  if (pendingDelayedInterrupts == 0)
976  signalDrainDone();
977 }
978 
981 {
982  if (pendingDelayedInterrupts == 0) {
983  return DrainState::Drained;
984  } else {
985  return DrainState::Draining;
986  }
987 }
988 
989 
990 void
992 {
993  // There may be pending interrupts if checkpointed from Kvm; post them.
994  updateIntState(-1);
995 }
996 
997 void
999 {
1000  DPRINTF(Checkpoint, "Serializing Arm GIC\n");
1001 
1023 
1024  for (uint32_t i=0; i < bankedRegs.size(); ++i) {
1025  if (!bankedRegs[i])
1026  continue;
1027  bankedRegs[i]->serializeSection(cp, csprintf("bankedRegs%i", i));
1028  }
1029 }
1030 
1031 void
1033 {
1040 }
1041 
1042 void
1044 {
1045  DPRINTF(Checkpoint, "Unserializing Arm GIC\n");
1046 
1067 
1068  // Handle checkpoints from before we drained the GIC to prevent
1069  // in-flight interrupts.
1070  if (cp.entryExists(Serializable::currentSection(), "interrupt_time")) {
1071  Tick interrupt_time[CPU_MAX];
1072  UNSERIALIZE_ARRAY(interrupt_time, CPU_MAX);
1073 
1074  for (uint32_t cpu = 0; cpu < CPU_MAX; cpu++) {
1075  if (interrupt_time[cpu])
1076  schedule(postIntEvent[cpu], interrupt_time[cpu]);
1077  }
1078  }
1079 
1081  gem5ExtensionsEnabled = false;
1082 
1083  for (uint32_t i=0; i < CPU_MAX; ++i) {
1084  ScopedCheckpointSection sec(cp, csprintf("bankedRegs%i", i));
1087  }
1088  }
1089 }
1090 
1091 void
1093 {
1100 }
1101 
1102 } // namespace gem5
gem5::GicV2::clearInt
void clearInt(ContextID ctx, uint32_t int_num)
Clears a cpu IRQ or FIQ signal.
Definition: gic_v2.cc:923
gem5::GicV2::BankedRegs::activeInt
uint32_t activeInt
GICD_I{S,C}ACTIVER0 interrupt active bits for first 32 interrupts, 1b per interrupt.
Definition: gic_v2.hh:195
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::GicV2::iccrpr
uint32_t iccrpr[CPU_MAX]
read only running priority register, 1 per cpu
Definition: gic_v2.hh:285
gem5::GicV2::BankedRegs::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: gic_v2.cc:1032
gem5::GicV2::SGI_MAX
static const int SGI_MAX
Definition: gic_v2.hh:114
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::GicV2::GICD_IPRIORITYR
static const AddrRange GICD_IPRIORITYR
Definition: gic_v2.hh:91
gem5::GicV2::intLatency
const Tick intLatency
Latency for a interrupt to get to CPU.
Definition: gic_v2.hh:167
gem5::System::Threads::size
int size() const
Definition: system.hh:216
gem5::GicV2::writeDistributor
Tick writeDistributor(PacketPtr pkt)
Handle a write to the distributor portion of the GIC.
Definition: gic_v2.cc:389
gem5::GicV2::cpuPpiPending
uint32_t cpuPpiPending[CPU_MAX]
One bit per private peripheral interrupt.
Definition: gic_v2.hh:440
gem5::GicV2::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: gic_v2.cc:1043
gem5::GicV2::GICC_APR3
@ GICC_APR3
Definition: gic_v2.hh:109
gem5::GicV2::activeInt
uint32_t activeInt[INT_BITS_MAX-1]
GICD_I{S,C}ACTIVER{1..31} interrupt active bits for global interrupts 1b per interrupt,...
Definition: gic_v2.hh:255
data
const char data[]
Definition: circlebuf.test.cc:48
gem5::GicV2::GICD_SGIR
@ GICD_SGIR
Definition: gic_v2.hh:71
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
gem5::GicV2::softInt
void softInt(ContextID ctx, SWI swi)
software generated interrupt
Definition: gic_v2.cc:651
gem5::GicV2::GICD_CTLR
@ GICD_CTLR
Definition: gic_v2.hh:68
gem5::GicV2::getActiveInt
uint32_t & getActiveInt(ContextID ctx, uint32_t ix)
Definition: gic_v2.hh:258
gem5::RangeSize
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:661
gem5::GicV2::getIntGroup
uint32_t & getIntGroup(ContextID ctx, uint32_t ix)
Definition: gic_v2.hh:274
gem5::GicV2::pendingInt
uint32_t pendingInt[INT_BITS_MAX-1]
GICD_I{S,C}PENDR{1..31} interrupt pending bits for global interrupts 1b per interrupt,...
Definition: gic_v2.hh:239
gem5::GicV2::drainResume
void drainResume() override
Resume execution after a successful drain.
Definition: gic_v2.cc:991
gem5::GicV2::cpuPpiActive
uint32_t cpuPpiActive[CPU_MAX]
Definition: gic_v2.hh:441
gem5::GicV2::INT_LINES_MAX
static const int INT_LINES_MAX
Definition: gic_v2.hh:126
gem5::GicV2::GICC_RPR
@ GICC_RPR
Definition: gic_v2.hh:103
gem5::GicV2::GICC_EOIR
@ GICC_EOIR
Definition: gic_v2.hh:102
gem5::GicV2::GICC_CTLR
@ GICC_CTLR
Definition: gic_v2.hh:98
gem5::Packet::req
RequestPtr req
A pointer to the original request.
Definition: packet.hh:366
gem5::GicV2::GICD_ISPENDR
static const AddrRange GICD_ISPENDR
Definition: gic_v2.hh:87
gem5::GicV2::GICC_APR0
@ GICC_APR0
Definition: gic_v2.hh:106
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::GicV2::postDelayedInt
void postDelayedInt(uint32_t cpu)
Deliver a delayed interrupt to the target CPU.
Definition: gic_v2.cc:943
gem5::GicV2::GICD_IIDR
@ GICD_IIDR
Definition: gic_v2.hh:70
gem5::ArmISA::INT_FIQ
@ INT_FIQ
Definition: interrupts.hh:63
gem5::GicV2::GICD_TYPER
@ GICD_TYPER
Definition: gic_v2.hh:69
gem5::GicV2::GICD_ICPENDR
static const AddrRange GICD_ICPENDR
Definition: gic_v2.hh:88
gem5::EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1019
gem5::csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
gem5::Packet::makeAtomicResponse
void makeAtomicResponse()
Definition: packet.hh:1043
gem5::GicV2::cpuSgiPendingExt
uint32_t cpuSgiPendingExt[CPU_MAX]
SGI pending arrays for gem5 GIC extension mode, which instead keeps 16 SGI pending bits for each of t...
Definition: gic_v2.hh:435
gem5::mbits
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
Definition: bitfield.hh:103
gem5::GicV2::SPURIOUS_INT
static const int SPURIOUS_INT
Definition: gic_v2.hh:124
gem5::GicV2::updateRunPri
void updateRunPri()
Update the register that records priority of the highest priority active interrupt.
Definition: gic_v2.cc:837
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
gem5::GicV2::getBankedRegs
BankedRegs & getBankedRegs(ContextID)
Definition: gic_v2.cc:641
gem5::GicV2::GICD_PIDR3
@ GICD_PIDR3
Definition: gic_v2.hh:75
gem5::GicV2::cpuPioDelay
const Tick cpuPioDelay
Latency for a cpu operation.
Definition: gic_v2.hh:164
gem5::GicV2::bankedRegs
std::vector< BankedRegs * > bankedRegs
Definition: gic_v2.hh:217
gem5::GicV2::pendingDelayedInterrupts
int pendingDelayedInterrupts
Definition: gic_v2.hh:480
gem5::GicV2::postDelayedFiq
void postDelayedFiq(uint32_t cpu)
Definition: gic_v2.cc:969
gem5::GicV2::cpuSgiActive
uint64_t cpuSgiActive[SGI_MAX]
Definition: gic_v2.hh:430
gem5::mask
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
Definition: bitfield.hh:63
packet.hh
gem5::GicV2::readCpu
Tick readCpu(PacketPtr pkt)
Handle a read to the cpu portion of the GIC.
Definition: gic_v2.cc:290
gem5::GicV2::gicdPIDR
const uint32_t gicdPIDR
Definition: gic_v2.hh:80
gem5::GicV2::BankedRegs::pendingInt
uint32_t pendingInt
GICD_I{S,C}PENDR0 interrupt pending bits for first 32 interrupts, 1b per interrupt.
Definition: gic_v2.hh:191
gem5::GicV2::intEnabled
uint32_t intEnabled[INT_BITS_MAX-1]
GICD_I{S,C}ENABLER{1..31} interrupt enable bits for global interrupts 1b per interrupt,...
Definition: gic_v2.hh:224
gem5::GicV2::cpuEnabled
bool cpuEnabled(ContextID ctx) const
CPU enabled: Checks if GICC_CTLR.EnableGrp0 or EnableGrp1 are set.
Definition: gic_v2.hh:404
gem5::GicV2::GICC_HPPIR
@ GICC_HPPIR
Definition: gic_v2.hh:104
gem5::GicV2::GICD_IGROUPR
static const AddrRange GICD_IGROUPR
Definition: gic_v2.hh:84
gem5::GicV2::intConfig
uint32_t intConfig[INT_BITS_MAX *2 - 2]
GICD_ICFGR{2...63} 2 bit per interrupt signaling if it's level or edge sensitive and if it is 1:N or ...
Definition: gic_v2.hh:308
gem5::GicV2::sendInt
void sendInt(uint32_t number) override
Post an interrupt from a device that is connected to the GIC.
Definition: gic_v2.cc:866
gem5::GicV2::BankedRegs::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: gic_v2.cc:1092
gem5::DrainState
DrainState
Object drain/handover states.
Definition: drain.hh:74
gem5::GicV2::isLevelSensitive
bool isLevelSensitive(ContextID ctx, uint32_t int_num)
Definition: gic_v2.hh:359
gem5::GicV2::giccIIDR
const uint32_t giccIIDR
Definition: gic_v2.hh:82
gem5::GicV2::genSwiMask
uint64_t genSwiMask(int cpu)
generate a bit mask to check cpuSgi for an interrupt.
Definition: gic_v2.cc:721
gem5::GicV2::intNumToBit
int intNumToBit(int num) const
Definition: gic_v2.hh:461
gem5::BaseGic
Definition: base_gic.hh:72
gem5::GicV2::cpu_list
Bitfield< 23, 16 > cpu_list
Definition: gic_v2.hh:135
gem5::GicV2::getIntPriority
uint8_t & getIntPriority(ContextID ctx, uint32_t ix)
Definition: gic_v2.hh:294
gem5::GicV2::cpuSgiActiveExt
uint32_t cpuSgiActiveExt[CPU_MAX]
Definition: gic_v2.hh:436
gem5::GicV2::GICC_IAR
@ GICC_IAR
Definition: gic_v2.hh:101
gem5::GicV2::postFiqEvent
EventFunctionWrapper * postFiqEvent[CPU_MAX]
Definition: gic_v2.hh:479
gem5::GicV2::GICC_IIDR
@ GICC_IIDR
Definition: gic_v2.hh:110
gem5::GicV2::GLOBAL_INT_LINES
static const int GLOBAL_INT_LINES
Definition: gic_v2.hh:127
gem5::GicV2::isFiq
bool isFiq(ContextID ctx, uint32_t int_num)
This method checks if an interrupt ID must be signaled or has been signaled as a FIQ to the cpu.
Definition: gic_v2.hh:388
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:283
gem5::GicV2::cpuControl
CTLR cpuControl[CPU_MAX]
GICC_CTLR: CPU interface control register.
Definition: gic_v2.hh:413
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::GicV2::haveGem5Extensions
const bool haveGem5Extensions
Are gem5 extensions available?
Definition: gic_v2.hh:174
gem5::GicV2::distPioDelay
const Tick distPioDelay
Latency for a distributor operation.
Definition: gic_v2.hh:161
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::GicV2::BankedRegs::intEnabled
uint32_t intEnabled
GICD_I{S,C}ENABLER0 interrupt enable bits for first 32 interrupts, 1b per interrupt.
Definition: gic_v2.hh:187
gem5::GicV2::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: gic_v2.cc:998
gem5::PioDevice::sys
System * sys
Definition: io_device.hh:105
gem5::GicV2::GICD_ISENABLER
static const AddrRange GICD_ISENABLER
Definition: gic_v2.hh:85
gem5::GicV2::GICC_PMR
@ GICC_PMR
Definition: gic_v2.hh:99
gem5::EventManager::eventq
EventQueue * eventq
A pointer to this object's event queue.
Definition: eventq.hh:991
gem5::GicV2::intGroup
uint32_t intGroup[INT_BITS_MAX-1]
GICD_IGROUPR{1..31} interrupt group bits for global interrupts 1b per interrupt, 32 bits per word,...
Definition: gic_v2.hh:271
UNSERIALIZE_OPT_SCALAR
#define UNSERIALIZE_OPT_SCALAR(scalar)
Definition: serialize.hh:582
gem5::GicV2::enabled
bool enabled
Gic enabled.
Definition: gic_v2.hh:171
gem5::GicV2::INT_BITS_MAX
static const int INT_BITS_MAX
Definition: gic_v2.hh:125
gem5::GicV2::updateIntState
virtual void updateIntState(int hint)
See if some processor interrupt flags need to be enabled/disabled.
Definition: gic_v2.cc:739
gem5::GicV2::getIntEnabled
uint32_t & getIntEnabled(ContextID ctx, uint32_t ix)
Definition: gic_v2.hh:227
gem5::GicV2::postFiq
void postFiq(uint32_t cpu, Tick when)
Definition: gic_v2.cc:954
gem5::GicV2::write
Tick write(PacketPtr pkt) override
A PIO read to the device, immediately split up into writeDistributor() or writeCpu()
Definition: gic_v2.cc:129
gem5::GicV2::BankedRegs
Registers "banked for each connected processor" per ARM IHI0048B.
Definition: gic_v2.hh:183
gem5::ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:144
gem5::GicV2::BankedRegs::intGroup
uint32_t intGroup
GICD_IGROUPR0 interrupt group bits for first 32 interrupts, 1b per interrupt.
Definition: gic_v2.hh:199
gem5::GicV2::GICD_ICFGR
static const AddrRange GICD_ICFGR
Definition: gic_v2.hh:93
gem5::GicV2::writeCpu
Tick writeCpu(PacketPtr pkt)
Handle a write to the cpu portion of the GIC.
Definition: gic_v2.cc:560
gem5::GicV2::GICD_PIDR2
@ GICD_PIDR2
Definition: gic_v2.hh:74
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::GicV2::GICD_ICENABLER
static const AddrRange GICD_ICENABLER
Definition: gic_v2.hh:86
gem5::GicV2::GICD_ISACTIVER
static const AddrRange GICD_ISACTIVER
Definition: gic_v2.hh:89
gem5::GicV2::read
Tick read(PacketPtr pkt) override
A PIO read to the device, immediately split up into readDistributor() or readCpu()
Definition: gic_v2.cc:115
SERIALIZE_ARRAY
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:610
gem5::DrainState::Drained
@ Drained
Buffers drained, ready for serialization/handover.
gem5::GicV2::GICC_BPR
@ GICC_BPR
Definition: gic_v2.hh:100
gem5::BaseGic::Params
BaseGicParams Params
Definition: base_gic.hh:75
gem5::GicV2::gem5ExtensionsEnabled
bool gem5ExtensionsEnabled
gem5 many-core extension enabled by driver
Definition: gic_v2.hh:177
gem5::GicV2::cpuPriority
uint8_t cpuPriority[CPU_MAX]
CPU priority.
Definition: gic_v2.hh:416
gem5::GicV2::GICC_APR1
@ GICC_APR1
Definition: gic_v2.hh:107
gem5::GicV2::CPU_MAX
static const int CPU_MAX
Definition: gic_v2.hh:123
gem5::GicV2::getCpuPriority
uint8_t getCpuPriority(unsigned cpu)
Definition: gic_v2.cc:728
gem5::GicV2::~GicV2
~GicV2()
Definition: gic_v2.cc:106
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::GicV2::readDistributor
Tick readDistributor(PacketPtr pkt)
Handle a read to the distributor portion of the GIC.
Definition: gic_v2.cc:142
gem5::GicV2::cpuSgiPending
uint64_t cpuSgiPending[SGI_MAX]
One bit per cpu per software interrupt that is pending for each possible sgi source.
Definition: gic_v2.hh:429
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568
packet_access.hh
gem5::BaseGic::GicVersion
GicVersion
Definition: base_gic.hh:76
gem5::GicV2::getIntConfig
uint32_t & getIntConfig(ContextID ctx, uint32_t ix)
Reads the GICD_ICFGRn register.
Definition: gic_v2.hh:317
gem5::statistics::enabled
bool enabled()
Definition: statistics.cc:280
gem5::Serializable::currentSection
static const std::string & currentSection()
Gets the fully-qualified name of the active section.
Definition: serialize.cc:130
gem5::GicV2::GICC_DIR
@ GICC_DIR
Definition: gic_v2.hh:111
gem5::GicV2::clearPPInt
void clearPPInt(uint32_t num, uint32_t cpu) override
Definition: gic_v2.cc:908
gem5::GicV2::supportsVersion
bool supportsVersion(GicVersion version) override
Check if version supported.
Definition: gic_v2.cc:963
gem5::Drainable::signalDrainDone
void signalDrainDone() const
Signal that an object is drained.
Definition: drain.hh:305
gem5::GicV2::cpuTarget
uint8_t cpuTarget[GLOBAL_INT_LINES]
GICD_ITARGETSR{8..255} an 8 bit cpu target id for each global interrupt.
Definition: gic_v2.hh:331
gem5::GicV2::itLines
uint32_t itLines
Number of itLines enabled.
Definition: gic_v2.hh:180
gem5::GicV2::GICD_ITARGETSR
static const AddrRange GICD_ITARGETSR
Definition: gic_v2.hh:92
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::GicV2::BankedRegs::intPriority
uint8_t intPriority[SGI_MAX+PPI_MAX]
GICD_IPRIORITYR{0..7} interrupt priority for SGIs and PPIs.
Definition: gic_v2.hh:207
gem5::RiscvISA::x
Bitfield< 3 > x
Definition: pagetable.hh:73
gem5::CheckpointIn::sectionExists
bool sectionExists(const std::string &section)
Definition: serialize.cc:200
gem5::GicV2::getPendingInt
uint32_t & getPendingInt(ContextID ctx, uint32_t ix)
Definition: gic_v2.hh:242
gem5::ArmISA::INT_IRQ
@ INT_IRQ
Definition: interrupts.hh:62
base.hh
UNSERIALIZE_ARRAY
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:618
gem5::System::threads
Threads threads
Definition: system.hh:316
gem5::GicV2::postInt
void postInt(uint32_t cpu, Tick when)
Post an interrupt to a CPU with a delay.
Definition: gic_v2.cc:934
gem5::GicV2::GicV2
GicV2(const Params &p)
Definition: gic_v2.cc:67
gem5::GicV2::GICD_ICACTIVER
static const AddrRange GICD_ICACTIVER
Definition: gic_v2.hh:90
gem5::GicV2::getCpuTarget
uint8_t getCpuTarget(ContextID ctx, uint32_t ix) const
Definition: gic_v2.hh:334
gem5::GicV2::BankedRegs::intConfig
uint32_t intConfig[2]
GICD_ICFGR0, GICD_ICFGR1 interrupt config bits for first 32 interrupts, 2b per interrupt.
Definition: gic_v2.hh:203
gem5::ContextID
int ContextID
Globally unique thread context ID.
Definition: types.hh:246
gem5::GicV2::gicdIIDR
const uint32_t gicdIIDR
Definition: gic_v2.hh:81
gem5::GicV2::GICD_PIDR1
@ GICD_PIDR1
Definition: gic_v2.hh:73
gem5::GicV2::intPriority
uint8_t intPriority[GLOBAL_INT_LINES]
GICD_IPRIORITYR{8..255} an 8 bit priority (lower is higher priority) for each of the global (not repl...
Definition: gic_v2.hh:291
gem5::Packet::getLE
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
Definition: packet_access.hh:78
gem5::EventQueue::schedule
void schedule(Event *event, Tick when, bool global=false)
Schedule the given event on this queue.
Definition: eventq.hh:764
gem5::GicV2::GICC_APR2
@ GICC_APR2
Definition: gic_v2.hh:108
gem5::CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:66
gem5::GicV2::postIntEvent
EventFunctionWrapper * postIntEvent[CPU_MAX]
Definition: gic_v2.hh:478
gem5::GicV2::GICC_BPR_MINIMUM
static const int GICC_BPR_MINIMUM
minimum value for Binary Point Register ("IMPLEMENTATION DEFINED"); chosen for consistency with Linux...
Definition: gic_v2.hh:131
gem5::GicV2::cpuBpr
uint8_t cpuBpr[CPU_MAX]
Binary point registers.
Definition: gic_v2.hh:420
trace.hh
gem5::Packet::setLE
void setLE(T v)
Set the value in the data pointer to v as little endian.
Definition: packet_access.hh:108
gem5::CheckpointIn::entryExists
bool entryExists(const std::string &section, const std::string &entry)
Definition: serialize.cc:178
gem5::GicV2::cpuRange
const EndBitUnion(CTLR) protected AddrRange cpuRange
Address range for the distributor interface.
Definition: gic_v2.hh:148
gem5::GicV2::GICD_PIDR0
@ GICD_PIDR0
Definition: gic_v2.hh:72
gem5::Packet::getAddr
Addr getAddr() const
Definition: packet.hh:781
gem5::GicV2::intNumToWord
int intNumToWord(int num) const
Definition: gic_v2.hh:460
gem5::GicV2::SGI_MASK
static const int SGI_MASK
Mask off SGI's when setting/clearing pending bits.
Definition: gic_v2.hh:118
gic_v2.hh
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::GicV2::drain
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
Definition: gic_v2.cc:980
gem5::BaseGic::GicVersion::GIC_V2
@ GIC_V2
gem5::Serializable::ScopedCheckpointSection
Definition: serialize.hh:172
gem5::GicV2::sendPPInt
void sendPPInt(uint32_t num, uint32_t cpu) override
Interface call for private peripheral interrupts.
Definition: gic_v2.cc:880
gem5::ArmISA::Interrupt
Definition: faults.hh:557
gem5::GicV2::NN_CONFIG_MASK
static const int NN_CONFIG_MASK
Mask for bits that config N:N mode in GICD_ICFGR's.
Definition: gic_v2.hh:121
gem5::GicV2::cpuHighestInt
uint32_t cpuHighestInt[CPU_MAX]
highest interrupt that is interrupting CPU
Definition: gic_v2.hh:423
gem5::System::Threads::numRunning
int numRunning() const
Definition: system.cc:157
gem5::GicV2::PPI_MAX
static const int PPI_MAX
Definition: gic_v2.hh:115
gem5::Packet::getSize
unsigned getSize() const
Definition: packet.hh:791
gem5::DrainState::Draining
@ Draining
Draining buffers pending serialization/handover.
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84

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