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

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