gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
gic_v2.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, 2013, 2015-2018 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  * Authors: Ali Saidi
41  * Prakash Ramrakhyani
42  */
43 
44 #include "dev/arm/gic_v2.hh"
45 
46 #include "base/trace.hh"
47 #include "debug/Checkpoint.hh"
48 #include "debug/GIC.hh"
49 #include "debug/IPI.hh"
50 #include "debug/Interrupt.hh"
51 #include "mem/packet.hh"
52 #include "mem/packet_access.hh"
53 
54 const AddrRange GicV2::GICD_IGROUPR (0x080, 0x100);
55 const AddrRange GicV2::GICD_ISENABLER (0x100, 0x180);
56 const AddrRange GicV2::GICD_ICENABLER (0x180, 0x200);
57 const AddrRange GicV2::GICD_ISPENDR (0x200, 0x280);
58 const AddrRange GicV2::GICD_ICPENDR (0x280, 0x300);
59 const AddrRange GicV2::GICD_ISACTIVER (0x300, 0x380);
60 const AddrRange GicV2::GICD_ICACTIVER (0x380, 0x400);
61 const AddrRange GicV2::GICD_IPRIORITYR(0x400, 0x800);
62 const AddrRange GicV2::GICD_ITARGETSR (0x800, 0xc00);
63 const AddrRange GicV2::GICD_ICFGR (0xc00, 0xd00);
64 
66  : BaseGic(p),
67  gicdPIDR(p->gicd_pidr),
68  gicdIIDR(p->gicd_iidr),
69  giccIIDR(p->gicc_iidr),
70  distRange(RangeSize(p->dist_addr, DIST_SIZE)),
71  cpuRange(RangeSize(p->cpu_addr, p->cpu_size)),
72  addrRanges{distRange, cpuRange},
73  distPioDelay(p->dist_pio_delay),
74  cpuPioDelay(p->cpu_pio_delay), intLatency(p->int_latency),
75  enabled(false), haveGem5Extensions(p->gem5_extensions),
76  itLines(p->it_lines),
77  intEnabled {}, pendingInt {}, activeInt {},
78  intPriority {}, cpuTarget {}, intConfig {},
83 {
84  for (int x = 0; x < CPU_MAX; x++) {
85  iccrpr[x] = 0xff;
86  cpuControl[x] = 0;
87  cpuPriority[x] = 0xff;
89  // Initialize cpu highest int
91  postIntEvent[x] =
92  new EventFunctionWrapper([this, x]{ postDelayedInt(x); },
93  "Post Interrupt to CPU");
94  postFiqEvent[x] =
95  new EventFunctionWrapper([this, x]{ postDelayedFiq(x); },
96  "Post FIQ to CPU");
97  }
98  DPRINTF(Interrupt, "cpuEnabled[0]=%d cpuEnabled[1]=%d\n", cpuEnabled(0),
99  cpuEnabled(1));
100 
101  gem5ExtensionsEnabled = false;
102 }
103 
105 {
106  for (int x = 0; x < CPU_MAX; x++) {
107  delete postIntEvent[x];
108  delete postFiqEvent[x];
109  }
110 }
111 
112 Tick
114 {
115  const Addr addr = pkt->getAddr();
116 
117  if (distRange.contains(addr))
118  return readDistributor(pkt);
119  else if (cpuRange.contains(addr))
120  return readCpu(pkt);
121  else
122  panic("Read to unknown address %#x\n", pkt->getAddr());
123 }
124 
125 
126 Tick
128 {
129  const Addr addr = pkt->getAddr();
130 
131  if (distRange.contains(addr))
132  return writeDistributor(pkt);
133  else if (cpuRange.contains(addr))
134  return writeCpu(pkt);
135  else
136  panic("Write to unknown address %#x\n", pkt->getAddr());
137 }
138 
139 Tick
141 {
142  const Addr daddr = pkt->getAddr() - distRange.start();
143  const ContextID ctx = pkt->req->contextId();
144 
145  DPRINTF(GIC, "gic distributor read register %#x\n", daddr);
146 
147  const uint32_t resp = readDistributor(ctx, daddr, pkt->getSize());
148 
149  switch (pkt->getSize()) {
150  case 1:
151  pkt->setLE<uint8_t>(resp);
152  break;
153  case 2:
154  pkt->setLE<uint16_t>(resp);
155  break;
156  case 4:
157  pkt->setLE<uint32_t>(resp);
158  break;
159  default:
160  panic("Invalid size while reading Distributor regs in GIC: %d\n",
161  pkt->getSize());
162  }
163 
164  pkt->makeAtomicResponse();
165  return distPioDelay;
166 }
167 
168 uint32_t
169 GicV2::readDistributor(ContextID ctx, Addr daddr, size_t resp_sz)
170 {
171  if (GICD_IGROUPR.contains(daddr)) {
172  uint32_t ix = (daddr - GICD_IGROUPR.start()) >> 2;
173  assert(ix < 32);
174  return getIntGroup(ctx, ix);
175  }
176 
177  if (GICD_ISENABLER.contains(daddr)) {
178  uint32_t ix = (daddr - GICD_ISENABLER.start()) >> 2;
179  assert(ix < 32);
180  return getIntEnabled(ctx, ix);
181  }
182 
183  if (GICD_ICENABLER.contains(daddr)) {
184  uint32_t ix = (daddr - GICD_ICENABLER.start()) >> 2;
185  assert(ix < 32);
186  return getIntEnabled(ctx, ix);
187  }
188 
189  if (GICD_ISPENDR.contains(daddr)) {
190  uint32_t ix = (daddr - GICD_ISPENDR.start()) >> 2;
191  assert(ix < 32);
192  return getPendingInt(ctx, ix);
193  }
194 
195  if (GICD_ICPENDR.contains(daddr)) {
196  uint32_t ix = (daddr - GICD_ICPENDR.start()) >> 2;
197  assert(ix < 32);
198  return getPendingInt(ctx, ix);
199  }
200 
201  if (GICD_ISACTIVER.contains(daddr)) {
202  uint32_t ix = (daddr - GICD_ISACTIVER.start()) >> 2;
203  assert(ix < 32);
204  return getActiveInt(ctx, ix);
205  }
206 
207  if (GICD_ICACTIVER.contains(daddr)) {
208  uint32_t ix = (daddr - GICD_ICACTIVER.start()) >> 2;
209  assert(ix < 32);
210  return getActiveInt(ctx, ix);
211  }
212 
213  if (GICD_IPRIORITYR.contains(daddr)) {
214  Addr int_num = daddr - GICD_IPRIORITYR.start();
215  assert(int_num < INT_LINES_MAX);
216  DPRINTF(Interrupt, "Reading interrupt priority at int# %#x \n",
217  int_num);
218 
219  switch (resp_sz) {
220  default: // will panic() after return to caller anyway
221  case 1:
222  return getIntPriority(ctx, int_num);
223  case 2:
224  assert((int_num + 1) < INT_LINES_MAX);
225  return (getIntPriority(ctx, int_num) |
226  getIntPriority(ctx, int_num+1) << 8);
227  case 4:
228  assert((int_num + 3) < INT_LINES_MAX);
229  return (getIntPriority(ctx, int_num) |
230  getIntPriority(ctx, int_num+1) << 8 |
231  getIntPriority(ctx, int_num+2) << 16 |
232  getIntPriority(ctx, int_num+3) << 24);
233  }
234  }
235 
236  if (GICD_ITARGETSR.contains(daddr)) {
237  Addr int_num = daddr - GICD_ITARGETSR.start();
238  DPRINTF(GIC, "Reading processor target register for int# %#x \n",
239  int_num);
240  assert(int_num < INT_LINES_MAX);
241 
242  if (resp_sz == 1) {
243  return getCpuTarget(ctx, int_num);
244  } else {
245  assert(resp_sz == 4);
246  int_num = mbits(int_num, 31, 2);
247  return (getCpuTarget(ctx, int_num) |
248  getCpuTarget(ctx, int_num+1) << 8 |
249  getCpuTarget(ctx, int_num+2) << 16 |
250  getCpuTarget(ctx, int_num+3) << 24) ;
251  }
252  }
253 
254  if (GICD_ICFGR.contains(daddr)) {
255  uint32_t ix = (daddr - GICD_ICFGR.start()) >> 2;
256  assert(ix < 64);
259  return intConfig[ix];
260  }
261 
262  switch(daddr) {
263  case GICD_CTLR:
264  return enabled;
265  case GICD_TYPER:
266  /* The 0x100 is a made-up flag to show that gem5 extensions
267  * are available,
268  * write 0x200 to this register to enable it. */
269  return (((sys->numRunningContexts() - 1) << 5) |
270  (itLines/INT_BITS_MAX -1) |
271  (haveGem5Extensions ? 0x100 : 0x0));
272  case GICD_PIDR0:
273  //ARM defined DevID
274  return (gicdPIDR & 0xFF);
275  case GICD_PIDR1:
276  return ((gicdPIDR >> 8) & 0xFF);
277  case GICD_PIDR2:
278  return ((gicdPIDR >> 16) & 0xFF);
279  case GICD_PIDR3:
280  return ((gicdPIDR >> 24) & 0xFF);
281  case GICD_IIDR:
282  /* revision id is resorted to 1 and variant to 0*/
283  return gicdIIDR;
284  default:
285  panic("Tried to read Gic distributor at offset %#x\n", daddr);
286  break;
287  }
288 }
289 
290 Tick
292 {
293  const Addr daddr = pkt->getAddr() - cpuRange.start();
294 
295  assert(pkt->req->hasContextId());
296  const ContextID ctx = pkt->req->contextId();
297  assert(ctx < sys->numRunningContexts());
298 
299  DPRINTF(GIC, "gic cpu read register %#x cpu context: %d\n", daddr,
300  ctx);
301 
302  pkt->setLE<uint32_t>(readCpu(ctx, daddr));
303 
304  pkt->makeAtomicResponse();
305  return cpuPioDelay;
306 }
307 
308 uint32_t
310 {
311  switch(daddr) {
312  case GICC_IIDR:
313  return giccIIDR;
314  case GICC_CTLR:
315  return cpuControl[ctx];
316  case GICC_PMR:
317  return cpuPriority[ctx];
318  case GICC_BPR:
319  return cpuBpr[ctx];
320  case GICC_IAR:
321  if (enabled && cpuEnabled(ctx)) {
322  int active_int = cpuHighestInt[ctx];
323  IAR iar = 0;
324  iar.ack_id = active_int;
325  iar.cpu_id = 0;
326  if (active_int < SGI_MAX) {
327  // this is a software interrupt from another CPU
328  if (!gem5ExtensionsEnabled) {
329  panic_if(!cpuSgiPending[active_int],
330  "Interrupt %d active but no CPU generated it?\n",
331  active_int);
332  for (int x = 0; x < sys->numRunningContexts(); x++) {
333  // See which CPU generated the interrupt
334  uint8_t cpugen =
335  bits(cpuSgiPending[active_int], 7 + 8 * x, 8 * x);
336  if (cpugen & (1 << ctx)) {
337  iar.cpu_id = x;
338  break;
339  }
340  }
341  uint64_t sgi_num = ULL(1) << (ctx + 8 * iar.cpu_id);
342  cpuSgiActive[iar.ack_id] |= sgi_num;
343  cpuSgiPending[iar.ack_id] &= ~sgi_num;
344  } else {
345  uint64_t sgi_num = ULL(1) << iar.ack_id;
346  cpuSgiActiveExt[ctx] |= sgi_num;
347  cpuSgiPendingExt[ctx] &= ~sgi_num;
348  }
349  } else if (active_int < (SGI_MAX + PPI_MAX) ) {
350  uint32_t int_num = 1 << (cpuHighestInt[ctx] - SGI_MAX);
351  cpuPpiActive[ctx] |= int_num;
352  updateRunPri();
353  cpuPpiPending[ctx] &= ~int_num;
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 
365  DPRINTF(Interrupt,
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  uint32_t pkt_data M5_VAR_USED;
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  assert(ix < INT_BITS_MAX*2);
529  intConfig[ix] = data;
530  if (data & NN_CONFIG_MASK)
531  warn("GIC N:N mode selected and not supported at this time\n");
532  return;
533  }
534 
535  switch(daddr) {
536  case GICD_CTLR:
537  enabled = data;
538  DPRINTF(Interrupt, "Distributor enable flag set to = %d\n", enabled);
539  break;
540  case GICD_TYPER:
541  /* 0x200 is a made-up flag to enable gem5 extension functionality.
542  * This reg is not normally written.
543  */
544  gem5ExtensionsEnabled = (data & 0x200) && haveGem5Extensions;
545  DPRINTF(GIC, "gem5 extensions %s\n",
546  gem5ExtensionsEnabled ? "enabled" : "disabled");
547  break;
548  case GICD_SGIR:
549  softInt(ctx, data);
550  break;
551  default:
552  panic("Tried to write Gic distributor at offset %#x\n", daddr);
553  break;
554  }
555 }
556 
557 Tick
559 {
560  const Addr daddr = pkt->getAddr() - cpuRange.start();
561 
562  assert(pkt->req->hasContextId());
563  const ContextID ctx = pkt->req->contextId();
564  const uint32_t data = pkt->getLE<uint32_t>();
565 
566  DPRINTF(GIC, "gic cpu write register cpu:%d %#x val: %#x\n",
567  ctx, daddr, data);
568 
569  writeCpu(ctx, daddr, data);
570 
571  pkt->makeAtomicResponse();
572  return cpuPioDelay;
573 }
574 
575 void
576 GicV2::writeCpu(ContextID ctx, Addr daddr, uint32_t data)
577 {
578  switch(daddr) {
579  case GICC_CTLR:
580  cpuControl[ctx] = data;
581  break;
582  case GICC_PMR:
583  cpuPriority[ctx] = data;
584  break;
585  case GICC_BPR: {
586  auto bpr = data & 0x7;
587  if (bpr < GICC_BPR_MINIMUM)
588  bpr = GICC_BPR_MINIMUM;
589  cpuBpr[ctx] = bpr;
590  break;
591  }
592  case GICC_EOIR: {
593  const IAR iar = data;
594  if (iar.ack_id < SGI_MAX) {
595  // Clear out the bit that corresponds to the cleared int
596  uint64_t clr_int = ULL(1) << (ctx + 8 * iar.cpu_id);
597  if (!(cpuSgiActive[iar.ack_id] & clr_int) &&
598  !(cpuSgiActiveExt[ctx] & (1 << iar.ack_id)))
599  panic("Done handling a SGI that isn't active?\n");
601  cpuSgiActiveExt[ctx] &= ~(1 << iar.ack_id);
602  else
603  cpuSgiActive[iar.ack_id] &= ~clr_int;
604  } else if (iar.ack_id < (SGI_MAX + PPI_MAX) ) {
605  uint32_t int_num = 1 << (iar.ack_id - SGI_MAX);
606  if (!(cpuPpiActive[ctx] & int_num))
607  warn("CPU %d Done handling a PPI interrupt "
608  "that isn't active?\n", ctx);
609  cpuPpiActive[ctx] &= ~int_num;
610  } else {
611  uint32_t int_num = 1 << intNumToBit(iar.ack_id);
612  if (!(getActiveInt(ctx, intNumToWord(iar.ack_id)) & int_num))
613  warn("Done handling interrupt that isn't active: %d\n",
614  intNumToBit(iar.ack_id));
615  getActiveInt(ctx, intNumToWord(iar.ack_id)) &= ~int_num;
616  }
617  updateRunPri();
618  DPRINTF(Interrupt, "CPU %d done handling intr IAR = %d from cpu %d\n",
619  ctx, iar.ack_id, iar.cpu_id);
620  break;
621  }
622  case GICC_APR0:
623  case GICC_APR1:
624  case GICC_APR2:
625  case GICC_APR3:
626  warn("GIC APRn write ignored because not implemented: %#x\n", daddr);
627  break;
628  case GICC_DIR:
629  warn("GIC DIR write ignored because not implemented: %#x\n", daddr);
630  break;
631  default:
632  panic("Tried to write Gic cpu at offset %#x\n", daddr);
633  break;
634  }
635  if (cpuEnabled(ctx)) updateIntState(-1);
636 }
637 
640  if (bankedRegs.size() <= ctx)
641  bankedRegs.resize(ctx + 1);
642 
643  if (!bankedRegs[ctx])
644  bankedRegs[ctx] = new BankedRegs;
645  return *bankedRegs[ctx];
646 }
647 
648 void
650 {
651  if (gem5ExtensionsEnabled) {
652  switch (swi.list_type) {
653  case 0: {
654  // interrupt cpus specified
655  int dest = swi.cpu_list;
656  DPRINTF(IPI, "Generating softIRQ from CPU %d for CPU %d\n",
657  ctx, dest);
658  if (cpuEnabled(dest)) {
659  cpuSgiPendingExt[dest] |= (1 << swi.sgi_id);
660  DPRINTF(IPI, "SGI[%d]=%#x\n", dest,
661  cpuSgiPendingExt[dest]);
662  }
663  } break;
664  case 1: {
665  // interrupt all
666  for (int i = 0; i < sys->numContexts(); i++) {
667  DPRINTF(IPI, "Processing CPU %d\n", i);
668  if (!cpuEnabled(i))
669  continue;
670  cpuSgiPendingExt[i] |= 1 << swi.sgi_id;
671  DPRINTF(IPI, "SGI[%d]=%#x\n", swi.sgi_id,
673  }
674  } break;
675  case 2: {
676  // Interrupt requesting cpu only
677  DPRINTF(IPI, "Generating softIRQ from CPU %d for CPU %d\n",
678  ctx, ctx);
679  if (cpuEnabled(ctx)) {
680  cpuSgiPendingExt[ctx] |= (1 << swi.sgi_id);
681  DPRINTF(IPI, "SGI[%d]=%#x\n", ctx,
682  cpuSgiPendingExt[ctx]);
683  }
684  } break;
685  }
686  } else {
687  switch (swi.list_type) {
688  case 1:
689  // interrupt all
690  uint8_t cpu_list;
691  cpu_list = 0;
692  for (int x = 0; x < sys->numContexts(); x++)
693  cpu_list |= cpuEnabled(x) ? 1 << x : 0;
694  swi.cpu_list = cpu_list;
695  break;
696  case 2:
697  // interrupt requesting cpu only
698  swi.cpu_list = 1 << ctx;
699  break;
700  // else interrupt cpus specified
701  }
702 
703  DPRINTF(IPI, "Generating softIRQ from CPU %d for %#x\n", ctx,
704  swi.cpu_list);
705  for (int i = 0; i < sys->numContexts(); i++) {
706  DPRINTF(IPI, "Processing CPU %d\n", i);
707  if (!cpuEnabled(i))
708  continue;
709  if (swi.cpu_list & (1 << i))
710  cpuSgiPending[swi.sgi_id] |= (1 << i) << (8 * ctx);
711  DPRINTF(IPI, "SGI[%d]=%#x\n", swi.sgi_id,
712  cpuSgiPending[swi.sgi_id]);
713  }
714  }
715  updateIntState(-1);
716 }
717 
718 uint64_t
720 {
721  if (cpu > sys->numContexts())
722  panic("Invalid CPU ID\n");
723  return ULL(0x0101010101010101) << cpu;
724 }
725 
726 uint8_t
728 {
729  // see Table 3-2 in IHI0048B.b (GICv2)
730  // mask some low-order priority bits per BPR value
731  // NB: the GIC prioritization scheme is upside down:
732  // lower values are higher priority; masking off bits
733  // actually creates a higher priority, not lower.
734  return cpuPriority[cpu] & (0xff00 >> (7 - cpuBpr[cpu]));
735 }
736 
737 void
739 {
740  for (int cpu = 0; cpu < sys->numContexts(); cpu++) {
741  if (!cpuEnabled(cpu))
742  continue;
743 
744  /*@todo use hint to do less work. */
745  int highest_int = SPURIOUS_INT;
746  // Priorities below that set in GICC_PMR can be ignored
747  uint8_t highest_pri = getCpuPriority(cpu);
748 
749  // Check SGIs
750  for (int swi = 0; swi < SGI_MAX; swi++) {
751  if (!cpuSgiPending[swi] && !cpuSgiPendingExt[cpu])
752  continue;
753  if ((cpuSgiPending[swi] & genSwiMask(cpu)) ||
754  (cpuSgiPendingExt[cpu] & (1 << swi)))
755  if (highest_pri > getIntPriority(cpu, swi)) {
756  highest_pri = getIntPriority(cpu, swi);
757  highest_int = swi;
758  }
759  }
760 
761  // Check PPIs
762  if (cpuPpiPending[cpu]) {
763  for (int ppi_idx = 0, int_num = SGI_MAX;
764  int_num < PPI_MAX + SGI_MAX;
765  ppi_idx++, int_num++) {
766 
767  const bool ppi_pending = bits(cpuPpiPending[cpu], ppi_idx);
768  const bool ppi_enabled = bits(getIntEnabled(cpu, 0), int_num);
769  const bool higher_priority =
770  highest_pri > getIntPriority(cpu, int_num);
771 
772  if (ppi_pending && ppi_enabled && higher_priority) {
773  highest_pri = getIntPriority(cpu, int_num);
774  highest_int = int_num;
775  }
776  }
777  }
778 
779  bool mp_sys = sys->numRunningContexts() > 1;
780  // Check other ints
781  for (int x = 0; x < (itLines/INT_BITS_MAX); x++) {
782  if (getIntEnabled(cpu, x) & getPendingInt(cpu, x)) {
783  for (int y = 0; y < INT_BITS_MAX; y++) {
784  uint32_t int_nm = x * INT_BITS_MAX + y;
785  DPRINTF(GIC, "Checking for interrupt# %d \n",int_nm);
786  /* Set current pending int as highest int for current cpu
787  if the interrupt's priority higher than current priority
788  and if current cpu is the target (for mp configs only)
789  */
790  if ((bits(getIntEnabled(cpu, x), y)
791  &bits(getPendingInt(cpu, x), y)) &&
792  (getIntPriority(cpu, int_nm) < highest_pri))
793  if ((!mp_sys) ||
795  ? (getCpuTarget(cpu, int_nm) == cpu)
796  : (getCpuTarget(cpu, int_nm) & (1 << cpu)))) {
797  highest_pri = getIntPriority(cpu, int_nm);
798  highest_int = int_nm;
799  }
800  }
801  }
802  }
803 
804  uint32_t prev_highest = cpuHighestInt[cpu];
805  cpuHighestInt[cpu] = highest_int;
806 
807  if (highest_int == SPURIOUS_INT) {
808  if (isLevelSensitive(cpu, prev_highest)) {
809 
810  DPRINTF(Interrupt, "Clear IRQ for cpu%d\n", cpu);
811  clearInt(cpu, prev_highest);
812  }
813  continue;
814  }
815 
816  /* @todo make this work for more than one cpu, need to handle 1:N, N:N
817  * models */
818  if (enabled && cpuEnabled(cpu) &&
819  (highest_pri < getCpuPriority(cpu)) &&
820  !(getActiveInt(cpu, intNumToWord(highest_int))
821  & (1 << intNumToBit(highest_int)))) {
822 
823  DPRINTF(Interrupt, "Posting interrupt %d to cpu%d\n", highest_int,
824  cpu);
825 
826  if (isFiq(cpu, highest_int)) {
827  postFiq(cpu, curTick() + intLatency);
828  } else {
829  postInt(cpu, curTick() + intLatency);
830  }
831  }
832  }
833 }
834 
835 void
837 {
838  for (int cpu = 0; cpu < sys->numContexts(); cpu++) {
839  if (!cpuEnabled(cpu))
840  continue;
841  uint8_t maxPriority = 0xff;
842  for (int i = 0; i < itLines; i++) {
843  if (i < SGI_MAX) {
844  if (((cpuSgiActive[i] & genSwiMask(cpu)) ||
845  (cpuSgiActiveExt[cpu] & (1 << i))) &&
846  (getIntPriority(cpu, i) < maxPriority))
847  maxPriority = getIntPriority(cpu, i);
848  } else if (i < (SGI_MAX + PPI_MAX)) {
849  if ((cpuPpiActive[cpu] & ( 1 << (i - SGI_MAX))) &&
850  (getIntPriority(cpu, i) < maxPriority))
851  maxPriority = getIntPriority(cpu, i);
852 
853  } else {
854  if (getActiveInt(cpu, intNumToWord(i))
855  & (1 << intNumToBit(i)))
856  if (getIntPriority(cpu, i) < maxPriority)
857  maxPriority = getIntPriority(cpu, i);
858  }
859  }
860  iccrpr[cpu] = maxPriority;
861  }
862 }
863 
864 void
865 GicV2::sendInt(uint32_t num)
866 {
867  uint8_t target = getCpuTarget(0, num);
868  DPRINTF(Interrupt, "Received Interrupt number %d, cpuTarget %#x: \n",
869  num, target);
870  if ((target & (target - 1)) && !gem5ExtensionsEnabled)
871  panic("Multiple targets for peripheral interrupts is not supported\n");
872  panic_if(num < SGI_MAX + PPI_MAX,
873  "sentInt() must only be used for interrupts 32 and higher");
874  getPendingInt(target, intNumToWord(num)) |= 1 << intNumToBit(num);
876 }
877 
878 void
879 GicV2::sendPPInt(uint32_t num, uint32_t cpu)
880 {
881  DPRINTF(Interrupt, "Received PPI %d, cpuTarget %#x: \n",
882  num, cpu);
883  cpuPpiPending[cpu] |= 1 << (num - SGI_MAX);
885 }
886 
887 void
888 GicV2::clearInt(uint32_t num)
889 {
890  if (isLevelSensitive(0, num)) {
891  uint8_t target = getCpuTarget(0, num);
892 
893  DPRINTF(Interrupt,
894  "Received Clear interrupt number %d, cpuTarget %#x:\n",
895  num, target);
896 
897  getPendingInt(target, intNumToWord(num)) &= ~(1 << intNumToBit(num));
899  } else {
900  /* Nothing to do :
901  * Edge-triggered interrupt remain pending until software
902  * writes GICD_ICPENDR or reads GICC_IAR */
903  }
904 }
905 
906 void
907 GicV2::clearPPInt(uint32_t num, uint32_t cpu)
908 {
909  DPRINTF(Interrupt, "Clearing PPI %d, cpuTarget %#x: \n",
910  num, cpu);
911  cpuPpiPending[cpu] &= ~(1 << (num - SGI_MAX));
913 }
914 
915 void
916 GicV2::clearInt(ContextID ctx, uint32_t int_num)
917 {
918  if (isFiq(ctx, int_num)) {
920  } else {
922  }
923 }
924 
925 void
926 GicV2::postInt(uint32_t cpu, Tick when)
927 {
928  if (!(postIntEvent[cpu]->scheduled())) {
930  eventq->schedule(postIntEvent[cpu], when);
931  }
932 }
933 
934 void
936 {
939  assert(pendingDelayedInterrupts >= 0);
940  if (pendingDelayedInterrupts == 0)
941  signalDrainDone();
942 }
943 
944 void
945 GicV2::postFiq(uint32_t cpu, Tick when)
946 {
947  if (!(postFiqEvent[cpu]->scheduled())) {
949  eventq->schedule(postFiqEvent[cpu], when);
950  }
951 }
952 
953 bool
955 {
956  return version == GicVersion::GIC_V2;
957 }
958 
959 void
961 {
964  assert(pendingDelayedInterrupts >= 0);
965  if (pendingDelayedInterrupts == 0)
966  signalDrainDone();
967 }
968 
971 {
972  if (pendingDelayedInterrupts == 0) {
973  return DrainState::Drained;
974  } else {
975  return DrainState::Draining;
976  }
977 }
978 
979 
980 void
982 {
983  // There may be pending interrupts if checkpointed from Kvm; post them.
984  updateIntState(-1);
985 }
986 
987 void
989 {
990  DPRINTF(Checkpoint, "Serializing Arm GIC\n");
991 
1013 
1014  for (uint32_t i=0; i < bankedRegs.size(); ++i) {
1015  if (!bankedRegs[i])
1016  continue;
1017  bankedRegs[i]->serializeSection(cp, csprintf("bankedRegs%i", i));
1018  }
1019 }
1020 
1021 void
1023 {
1029 }
1030 
1031 void
1033 {
1034  DPRINTF(Checkpoint, "Unserializing Arm GIC\n");
1035 
1056 
1057  // Handle checkpoints from before we drained the GIC to prevent
1058  // in-flight interrupts.
1059  if (cp.entryExists(Serializable::currentSection(), "interrupt_time")) {
1060  Tick interrupt_time[CPU_MAX];
1061  UNSERIALIZE_ARRAY(interrupt_time, CPU_MAX);
1062 
1063  for (uint32_t cpu = 0; cpu < CPU_MAX; cpu++) {
1064  if (interrupt_time[cpu])
1065  schedule(postIntEvent[cpu], interrupt_time[cpu]);
1066  }
1067  }
1068 
1070  gem5ExtensionsEnabled = false;
1071 
1072  for (uint32_t i=0; i < CPU_MAX; ++i) {
1073  ScopedCheckpointSection sec(cp, csprintf("bankedRegs%i", i));
1076  }
1077  }
1078 }
1079 
1080 void
1082 {
1088 }
1089 
1090 GicV2 *
1091 GicV2Params::create()
1092 {
1093  return new GicV2(this);
1094 }
IntrControl * intrctrl
Pointer to the interrupt controller.
Definition: platform.hh:56
EventQueue * eventq
A pointer to this object&#39;s event queue.
Definition: eventq.hh:730
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
uint32_t cpuSgiActiveExt[CPU_MAX]
Definition: gic_v2.hh:396
void clearInt(ContextID ctx, uint32_t int_num)
Clears a cpu IRQ or FIQ signal.
Definition: gic_v2.cc:916
#define DPRINTF(x,...)
Definition: trace.hh:229
static const int GLOBAL_INT_LINES
Definition: gic_v2.hh:124
Bitfield< 23, 16 > cpu_list
Definition: gic_v2.hh:132
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:584
static const AddrRange GICD_IGROUPR
Definition: gic_v2.hh:82
EndBitUnion(CTLR) protected const AddrRange cpuRange
Address range for the distributor interface.
Definition: gic_v2.hh:145
Platform * platform
Platform this GIC belongs to.
Definition: base_gic.hh:116
Registers "banked for each connected processor" per ARM IHI0048B.
Definition: gic_v2.hh:180
const uint32_t gicdIIDR
Definition: gic_v2.hh:79
uint32_t intEnabled[INT_BITS_MAX-1]
GICD_I{S,C}ENABLER{1..31} interrupt enable bits for global interrupts 1b per interrupt, 32 bits per word, 31 words.
Definition: gic_v2.hh:216
uint32_t iccrpr[CPU_MAX]
read only running priority register, 1 per cpu
Definition: gic_v2.hh:269
Bitfield< 7 > i
DrainState
Object drain/handover states.
Definition: drain.hh:71
static const int PPI_MAX
Definition: gic_v2.hh:112
Running normally.
#define UNSERIALIZE_OPT_SCALAR(scalar)
Definition: serialize.hh:646
BaseGicParams Params
Definition: base_gic.hh:67
static const AddrRange GICD_ISENABLER
Definition: gic_v2.hh:83
CTLR cpuControl[CPU_MAX]
GICC_CTLR: CPU interface control register.
Definition: gic_v2.hh:373
GicV2(const Params *p)
Definition: gic_v2.cc:65
void post(int cpu_id, int int_num, int index)
Definition: intr_control.cc:50
static const AddrRange GICD_ICENABLER
Definition: gic_v2.hh:84
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:406
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:275
void softInt(ContextID ctx, SWI swi)
software generated interrupt
Definition: gic_v2.cc:649
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: gic_v2.cc:1081
uint32_t & getActiveInt(ContextID ctx, uint32_t ix)
Definition: gic_v2.hh:245
ip6_addr_t addr
Definition: inet.hh:335
uint32_t pendingInt[INT_BITS_MAX-1]
GICD_I{S,C}PENDR{1..31} interrupt pending bits for global interrupts 1b per interrupt, 32 bits per word, 31 words.
Definition: gic_v2.hh:229
Tick readCpu(PacketPtr pkt)
Handle a read to the cpu portion of the GIC.
Definition: gic_v2.cc:291
void signalDrainDone() const
Signal that an object is drained.
Definition: drain.hh:267
uint8_t cpuBpr[CPU_MAX]
Binary point registers.
Definition: gic_v2.hh:380
static const int SGI_MASK
Mask off SGI&#39;s when setting/clearing pending bits.
Definition: gic_v2.hh:115
Tick write(PacketPtr pkt) override
A PIO read to the device, immediately split up into writeDistributor() or writeCpu() ...
Definition: gic_v2.cc:127
Bitfield< 23, 0 > offset
Definition: types.hh:154
EventFunctionWrapper * postFiqEvent[CPU_MAX]
Definition: gic_v2.hh:439
static const int INT_LINES_MAX
Definition: gic_v2.hh:123
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: gic_v2.cc:1032
Definition: cprintf.cc:42
const Tick intLatency
Latency for a interrupt to get to CPU.
Definition: gic_v2.hh:164
virtual void updateIntState(int hint)
See if some processor interrupt flags need to be enabled/disabled.
Definition: gic_v2.cc:738
static const AddrRange GICD_ISACTIVER
Definition: gic_v2.hh:87
static const AddrRange GICD_IPRIORITYR
Definition: gic_v2.hh:89
bool isLevelSensitive(ContextID ctx, uint32_t ix)
Definition: gic_v2.hh:328
const Tick distPioDelay
Latency for a distributor operation.
Definition: gic_v2.hh:158
int numRunningContexts()
Return number of running (non-halted) thread contexts in system.
Definition: system.cc:336
void setLE(T v)
Set the value in the data pointer to v as little endian.
bool gem5ExtensionsEnabled
gem5 many-core extension enabled by driver
Definition: gic_v2.hh:174
uint8_t & getIntPriority(ContextID ctx, uint32_t ix)
Definition: gic_v2.hh:277
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: gic_v2.cc:1022
RequestPtr req
A pointer to the original request.
Definition: packet.hh:327
Tick read(PacketPtr pkt) override
A PIO read to the device, immediately split up into readDistributor() or readCpu() ...
Definition: gic_v2.cc:113
uint32_t cpuPpiActive[CPU_MAX]
Definition: gic_v2.hh:401
unsigned getSize() const
Definition: packet.hh:736
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition: addr_range.hh:72
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:645
static const int SPURIOUS_INT
Definition: gic_v2.hh:121
static const int NN_CONFIG_MASK
Mask for bits that config N:N mode in GICD_ICFGR&#39;s.
Definition: gic_v2.hh:118
Tick curTick()
The current simulated tick.
Definition: core.hh:47
const uint32_t gicdPIDR
Definition: gic_v2.hh:78
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:162
Tick readDistributor(PacketPtr pkt)
Handle a read to the distributor portion of the GIC.
Definition: gic_v2.cc:140
static const int CPU_MAX
Definition: gic_v2.hh:120
void makeAtomicResponse()
Definition: packet.hh:949
uint64_t cpuSgiPending[SGI_MAX]
One bit per cpu per software interrupt that is pending for each possible sgi source.
Definition: gic_v2.hh:389
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:257
uint64_t Tick
Tick count type.
Definition: types.hh:63
uint64_t genSwiMask(int cpu)
generate a bit mask to check cpuSgi for an interrupt.
Definition: gic_v2.cc:719
int intNumToWord(int num) const
Definition: gic_v2.hh:420
static const int SGI_MAX
Definition: gic_v2.hh:111
bool supportsVersion(GicVersion version) override
Check if version supported.
Definition: gic_v2.cc:954
uint64_t cpuSgiActive[SGI_MAX]
Definition: gic_v2.hh:390
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:658
bool cpuEnabled(ContextID ctx) const
CPU enabled: Checks if GICC_CTLR.EnableGrp0 or EnableGrp1 are set.
Definition: gic_v2.hh:365
Addr getAddr() const
Definition: packet.hh:726
unsigned numContexts() const
Definition: system.hh:206
uint8_t cpuPriority[CPU_MAX]
CPU priority.
Definition: gic_v2.hh:376
DrainState drain() override
Notify an object that it needs to drain its state.
Definition: gic_v2.cc:970
static const int INT_BITS_MAX
Definition: gic_v2.hh:122
static const AddrRange GICD_ICACTIVER
Definition: gic_v2.hh:88
GicVersion
Definition: base_gic.hh:68
uint32_t activeInt[INT_BITS_MAX-1]
GICD_I{S,C}ACTIVER{1..31} interrupt active bits for global interrupts 1b per interrupt, 32 bits per word, 31 words.
Definition: gic_v2.hh:243
uint32_t & getIntGroup(ContextID ctx, uint32_t ix)
Definition: gic_v2.hh:259
uint32_t & getIntEnabled(ContextID ctx, uint32_t ix)
Definition: gic_v2.hh:218
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Draining buffers pending serialization/handover.
#define ULL(N)
uint64_t constant
Definition: types.hh:50
System * sys
Definition: io_device.hh:105
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:255
void postInt(uint32_t cpu, Tick when)
Post an interrupt to a CPU with a delay.
Definition: gic_v2.cc:926
void sendInt(uint32_t number) override
Post an interrupt from a device that is connected to the GIC.
Definition: gic_v2.cc:865
static const AddrRange GICD_ICPENDR
Definition: gic_v2.hh:86
std::vector< BankedRegs * > bankedRegs
Definition: gic_v2.hh:209
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:643
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:661
EventFunctionWrapper * postIntEvent[CPU_MAX]
Definition: gic_v2.hh:438
uint32_t & getPendingInt(ContextID ctx, uint32_t ix)
Definition: gic_v2.hh:231
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: gic_v2.cc:988
Definition: gic_v2.hh:61
void clearPPInt(uint32_t num, uint32_t cpu) override
Definition: gic_v2.cc:907
Tick writeCpu(PacketPtr pkt)
Handle a write to the cpu portion of the GIC.
Definition: gic_v2.cc:558
uint32_t cpuHighestInt[CPU_MAX]
highest interrupt that is interrupting CPU
Definition: gic_v2.hh:383
Declaration of the Packet class.
int pendingDelayedInterrupts
Definition: gic_v2.hh:440
std::ostream CheckpointOut
Definition: serialize.hh:68
BankedRegs & getBankedRegs(ContextID)
Definition: gic_v2.cc:639
void postDelayedFiq(uint32_t cpu)
Definition: gic_v2.cc:960
uint8_t getCpuPriority(unsigned cpu)
Definition: gic_v2.cc:727
uint8_t getCpuTarget(ContextID ctx, uint32_t ix)
Definition: gic_v2.hh:301
void postDelayedInt(uint32_t cpu)
Deliver a delayed interrupt to the target CPU.
Definition: gic_v2.cc:935
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:395
uint32_t itLines
Number of itLines enabled.
Definition: gic_v2.hh:177
bool sectionExists(const std::string &section)
Definition: serialize.cc:313
Implementation of a GICv2.
void schedule(Event *event, Tick when, bool global=false)
Schedule the given event on this queue.
Definition: eventq_impl.hh:42
const Tick cpuPioDelay
Latency for a cpu operation.
Definition: gic_v2.hh:161
static const std::string & currentSection()
Get the fully-qualified name of the active section.
Definition: serialize.cc:244
void schedule(Event &event, Tick when)
Definition: eventq.hh:744
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:351
bool entryExists(const std::string &section, const std::string &entry)
Definition: serialize.cc:288
static const AddrRange GICD_ITARGETSR
Definition: gic_v2.hh:90
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
bool enabled
Gic enabled.
Definition: gic_v2.hh:168
Addr start() const
Get the start address of the range.
Definition: addr_range.hh:297
void drainResume() override
Resume execution after a successful drain.
Definition: gic_v2.cc:981
static const AddrRange GICD_ICFGR
Definition: gic_v2.hh:91
Bitfield< 3, 0 > mask
Definition: types.hh:64
uint8_t cpuTarget[GLOBAL_INT_LINES]
GICD_ITARGETSR{8..255} an 8 bit cpu target id for each global interrupt.
Definition: gic_v2.hh:299
#define warn(...)
Definition: logging.hh:212
const uint32_t giccIIDR
Definition: gic_v2.hh:80
static const AddrRange GICD_ISPENDR
Definition: gic_v2.hh:85
void sendPPInt(uint32_t num, uint32_t cpu) override
Interface call for private peripheral interrupts.
Definition: gic_v2.cc:879
static const int NumArgumentRegs M5_VAR_USED
Definition: process.cc:84
~GicV2()
Definition: gic_v2.cc:104
T mbits(T val, int first, int last)
Mask off the given bits in place like bits() but without shifting.
Definition: bitfield.hh:96
T bits(T val, int first, int last)
Extract the bitfield from position &#39;first&#39; to &#39;last&#39; (inclusive) from &#39;val&#39; and right justify it...
Definition: bitfield.hh:72
void clear(int cpu_id, int int_num, int index)
Definition: intr_control.cc:59
Tick writeDistributor(PacketPtr pkt)
Handle a write to the distributor portion of the GIC.
Definition: gic_v2.cc:389
Scoped checkpoint section helper class.
Definition: serialize.hh:173
Bitfield< 0 > p
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:185
void updateRunPri()
Update the register that records priority of the highest priority active interrupt.
Definition: gic_v2.cc:836
Bitfield< 1 > x
Definition: types.hh:105
const char data[]
uint32_t cpuPpiPending[CPU_MAX]
One bit per private peripheral interrupt.
Definition: gic_v2.hh:400
void postFiq(uint32_t cpu, Tick when)
Definition: gic_v2.cc:945
int ContextID
Globally unique thread context ID.
Definition: types.hh:231
uint32_t intConfig[INT_BITS_MAX *2]
2 bit per interrupt signaling if it&#39;s level or edge sensitive and if it is 1:N or N:N ...
Definition: gic_v2.hh:326
const bool haveGem5Extensions
Are gem5 extensions available?
Definition: gic_v2.hh:171
static const int GICC_BPR_MINIMUM
minimum value for Binary Point Register ("IMPLEMENTATION DEFINED"); chosen for consistency with Linux...
Definition: gic_v2.hh:128
int intNumToBit(int num) const
Definition: gic_v2.hh:421

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