gem5  v22.0.0.2
interrupts.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2013 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) 2008 The Hewlett-Packard Development Company
15  * All rights reserved.
16  *
17  * The license below extends only to copyright in the software and shall
18  * not be construed as granting a license to any other intellectual
19  * property including but not limited to intellectual property relating
20  * to a hardware implementation of the functionality of the software
21  * licensed hereunder. You may use the software subject to the license
22  * terms below provided that you ensure that this notice is replicated
23  * unmodified and in its entirety in all distributions of the software,
24  * modified or unmodified, in source code or in binary form.
25  *
26  * Redistribution and use in source and binary forms, with or without
27  * modification, are permitted provided that the following conditions are
28  * met: redistributions of source code must retain the above copyright
29  * notice, this list of conditions and the following disclaimer;
30  * redistributions in binary form must reproduce the above copyright
31  * notice, this list of conditions and the following disclaimer in the
32  * documentation and/or other materials provided with the distribution;
33  * neither the name of the copyright holders nor the names of its
34  * contributors may be used to endorse or promote products derived from
35  * this software without specific prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
38  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
39  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
40  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
41  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48  */
49 
50 #include "arch/x86/interrupts.hh"
51 
52 #include <list>
53 #include <memory>
54 
55 #include "arch/x86/intmessage.hh"
56 #include "arch/x86/regs/apic.hh"
57 #include "arch/x86/regs/misc.hh"
58 #include "cpu/base.hh"
59 #include "debug/LocalApic.hh"
60 #include "dev/x86/i82094aa.hh"
61 #include "dev/x86/pc.hh"
62 #include "dev/x86/south_bridge.hh"
63 #include "mem/packet_access.hh"
64 #include "sim/full_system.hh"
65 #include "sim/system.hh"
66 
67 namespace gem5
68 {
69 
70 int
71 divideFromConf(uint32_t conf)
72 {
73  // This figures out what division we want from the division configuration
74  // register in the local APIC. The encoding is a little odd but it can
75  // be deciphered fairly easily.
76  int shift = ((conf & 0x8) >> 1) | (conf & 0x3);
77  shift = (shift + 1) % 8;
78  return 1 << shift;
79 }
80 
81 namespace X86ISA
82 {
83 
86 {
87  ApicRegIndex regNum;
88  paddr &= ~mask(3);
89  switch (paddr)
90  {
91  case 0x20:
92  regNum = APIC_ID;
93  break;
94  case 0x30:
95  regNum = APIC_VERSION;
96  break;
97  case 0x80:
98  regNum = APIC_TASK_PRIORITY;
99  break;
100  case 0x90:
101  regNum = APIC_ARBITRATION_PRIORITY;
102  break;
103  case 0xA0:
104  regNum = APIC_PROCESSOR_PRIORITY;
105  break;
106  case 0xB0:
107  regNum = APIC_EOI;
108  break;
109  case 0xD0:
110  regNum = APIC_LOGICAL_DESTINATION;
111  break;
112  case 0xE0:
113  regNum = APIC_DESTINATION_FORMAT;
114  break;
115  case 0xF0:
117  break;
118  case 0x100:
119  case 0x110:
120  case 0x120:
121  case 0x130:
122  case 0x140:
123  case 0x150:
124  case 0x160:
125  case 0x170:
126  regNum = APIC_IN_SERVICE((paddr - 0x100) / 0x10);
127  break;
128  case 0x180:
129  case 0x190:
130  case 0x1A0:
131  case 0x1B0:
132  case 0x1C0:
133  case 0x1D0:
134  case 0x1E0:
135  case 0x1F0:
136  regNum = APIC_TRIGGER_MODE((paddr - 0x180) / 0x10);
137  break;
138  case 0x200:
139  case 0x210:
140  case 0x220:
141  case 0x230:
142  case 0x240:
143  case 0x250:
144  case 0x260:
145  case 0x270:
146  regNum = APIC_INTERRUPT_REQUEST((paddr - 0x200) / 0x10);
147  break;
148  case 0x280:
149  regNum = APIC_ERROR_STATUS;
150  break;
151  case 0x300:
153  break;
154  case 0x310:
156  break;
157  case 0x320:
158  regNum = APIC_LVT_TIMER;
159  break;
160  case 0x330:
161  regNum = APIC_LVT_THERMAL_SENSOR;
162  break;
163  case 0x340:
165  break;
166  case 0x350:
167  regNum = APIC_LVT_LINT0;
168  break;
169  case 0x360:
170  regNum = APIC_LVT_LINT1;
171  break;
172  case 0x370:
173  regNum = APIC_LVT_ERROR;
174  break;
175  case 0x380:
176  regNum = APIC_INITIAL_COUNT;
177  break;
178  case 0x390:
179  regNum = APIC_CURRENT_COUNT;
180  break;
181  case 0x3E0:
182  regNum = APIC_DIVIDE_CONFIGURATION;
183  break;
184  default:
185  // A reserved register field.
186  panic("Accessed reserved register field %#x.\n", paddr);
187  break;
188  }
189  return regNum;
190 }
191 }
192 
193 Tick
195 {
196  Addr offset = pkt->getAddr() - pioAddr;
197  // Make sure we're at least only accessing one register.
198  if ((offset & ~mask(3)) != ((offset + pkt->getSize()) & ~mask(3)))
199  panic("Accessed more than one register at a time in the APIC!\n");
201  uint32_t val = htole(readReg(reg));
202  DPRINTF(LocalApic,
203  "Reading Local APIC register %d at offset %#x as %#x.\n",
204  reg, offset, val);
205  pkt->setData(((uint8_t *)&val) + (offset & mask(3)));
206  pkt->makeAtomicResponse();
207  return pioDelay;
208 }
209 
210 Tick
212 {
213  Addr offset = pkt->getAddr() - pioAddr;
214  // Make sure we're at least only accessing one register.
215  if ((offset & ~mask(3)) != ((offset + pkt->getSize()) & ~mask(3)))
216  panic("Accessed more than one register at a time in the APIC!\n");
218  uint32_t val = regs[reg];
219  pkt->writeData(((uint8_t *)&val) + (offset & mask(3)));
220  DPRINTF(LocalApic,
221  "Writing Local APIC register %d at offset %#x as %#x.\n",
222  reg, offset, letoh(val));
223  setReg(reg, letoh(val));
224  pkt->makeAtomicResponse();
225  return pioDelay;
226 }
227 void
229  uint8_t deliveryMode, bool level)
230 {
231  /*
232  * Fixed and lowest-priority delivery mode interrupts are handled
233  * using the IRR/ISR registers, checking against the TPR, etc.
234  * The SMI, NMI, ExtInt, INIT, etc interrupts go straight through.
235  */
238  DPRINTF(LocalApic, "Interrupt is an %s.\n",
240  // Queue up the interrupt in the IRR.
241  if (vector > IRRV)
242  IRRV = vector;
243  if (!getRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector)) {
244  setRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector);
245  if (level) {
246  setRegArrayBit(APIC_TRIGGER_MODE_BASE, vector);
247  } else {
248  clearRegArrayBit(APIC_TRIGGER_MODE_BASE, vector);
249  }
250  }
252  DPRINTF(LocalApic, "Interrupt is an %s.\n",
254  if (deliveryMode == delivery_mode::SMI && !pendingSmi) {
255  pendingUnmaskableInt = pendingSmi = true;
256  smiVector = vector;
257  } else if (deliveryMode == delivery_mode::NMI && !pendingNmi) {
258  pendingUnmaskableInt = pendingNmi = true;
259  nmiVector = vector;
260  } else if (deliveryMode == delivery_mode::ExtInt && !pendingExtInt) {
261  pendingExtInt = true;
262  extIntVector = vector;
263  } else if (deliveryMode == delivery_mode::INIT && !pendingInit) {
264  pendingUnmaskableInt = pendingInit = true;
265  initVector = vector;
266  } else if (deliveryMode == delivery_mode::SIPI &&
267  !pendingStartup && !startedUp) {
268  pendingUnmaskableInt = pendingStartup = true;
269  startupVector = vector;
270  }
271  }
272  if (FullSystem)
273  tc->getCpuPtr()->wakeup(0);
274 }
275 
276 
277 void
279 {
280  panic_if(number < 0 || number > 1,
281  "Asked to raise unrecognized int pin %d.", number);
282  DPRINTF(LocalApic, "Raised wired interrupt pin LINT%d.\n", number);
283 
284  const LVTEntry entry =
285  regs[(number == 0) ? APIC_LVT_LINT0 : APIC_LVT_LINT1];
286 
287  if (entry.masked) {
288  DPRINTF(LocalApic, "The interrupt was masked.\n");
289  return;
290  }
291 
293  auto on_completion = [this, dm=entry.deliveryMode, trigger=entry.trigger](
294  PacketPtr pkt) {
295  requestInterrupt(pkt->getLE<uint8_t>(), dm, trigger);
296  delete pkt;
297  };
298  intRequestPort.sendMessage(pkt, sys->isTimingMode(), on_completion);
299 }
300 
301 
302 void
304 {
305  panic_if(number < 0 || number > 1,
306  "Asked to lower unrecognized int pin %d.", number);
307  DPRINTF(LocalApic, "Lowered wired interrupt pin LINT%d.\n", number);
308 }
309 
310 
311 void
313 {
314  assert(_tc);
315  panic_if(tc != NULL && tc->cpuId() != _tc->cpuId(),
316  "Local APICs can't be moved between CPUs with different IDs.");
317 
319 
320  initialApicId = tc->cpuId();
321  regs[APIC_ID] = (initialApicId << 24);
322  pioAddr = x86LocalAPICAddress(initialApicId, 0);
323 }
324 
325 
326 void
328 {
329  panic_if(!intRequestPort.isConnected(),
330  "Int port not connected to anything!");
331  panic_if(!pioPort.isConnected(),
332  "Pio port of %s not connected to anything!", name());
333 
334  intResponsePort.sendRangeChange();
335  pioPort.sendRangeChange();
336 }
337 
338 
339 Tick
341 {
342  Addr offset = pkt->getAddr() - x86InterruptAddress(initialApicId, 0);
343  assert(pkt->cmd == MemCmd::WriteReq);
344  switch(offset)
345  {
346  case 0:
347  {
348  TriggerIntMessage message = pkt->getRaw<TriggerIntMessage>();
349  DPRINTF(LocalApic,
350  "Got Trigger Interrupt message with vector %#x.\n",
351  message.vector);
352 
353  requestInterrupt(message.vector,
354  message.deliveryMode, message.trigger);
355  }
356  break;
357  default:
358  panic("Local apic got unknown interrupt message at offset %#x.\n",
359  offset);
360  break;
361  }
362  pkt->makeAtomicResponse();
363  return pioDelay;
364 }
365 
366 
367 void
369 {
370  if (--pendingIPIs == 0) {
371  InterruptCommandRegLow low = regs[APIC_INTERRUPT_COMMAND_LOW];
372  // Record that the ICR is now idle.
373  low.deliveryStatus = 0;
374  regs[APIC_INTERRUPT_COMMAND_LOW] = low;
375  }
376  DPRINTF(LocalApic, "ICR is now idle.\n");
377  delete pkt;
378 }
379 
380 
383 {
384  assert(tc);
385  AddrRangeList ranges;
386  ranges.push_back(RangeSize(pioAddr, PageBytes));
387  return ranges;
388 }
389 
390 
393 {
394  AddrRangeList ranges;
395  ranges.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
396  x86InterruptAddress(initialApicId, 0) +
398  return ranges;
399 }
400 
401 
402 uint32_t
404 {
405  if (reg >= APIC_TRIGGER_MODE(0) &&
406  reg <= APIC_TRIGGER_MODE(15)) {
407  panic("Local APIC Trigger Mode registers are unimplemented.\n");
408  }
409  switch (reg) {
411  panic("Local APIC Arbitration Priority register unimplemented.\n");
412  break;
414  panic("Local APIC Processor Priority register unimplemented.\n");
415  break;
416  case APIC_ERROR_STATUS:
417  regs[APIC_INTERNAL_STATE] &= ~0x1ULL;
418  break;
419  case APIC_CURRENT_COUNT:
420  {
421  if (apicTimerEvent.scheduled()) {
422  // Compute how many m5 ticks happen per count.
423  uint64_t ticksPerCount = clockPeriod() *
425  // Compute how many m5 ticks are left.
426  uint64_t val = apicTimerEvent.when() - curTick();
427  // Turn that into a count.
428  val = (val + ticksPerCount - 1) / ticksPerCount;
429  return val;
430  } else {
431  return 0;
432  }
433  }
434  default:
435  break;
436  }
437  return regs[reg];
438 }
439 
440 void
442 {
443  uint32_t newVal = val;
444  if (reg >= APIC_IN_SERVICE(0) &&
445  reg <= APIC_IN_SERVICE(15)) {
446  panic("Local APIC In-Service registers are unimplemented.\n");
447  }
448  if (reg >= APIC_TRIGGER_MODE(0) &&
449  reg <= APIC_TRIGGER_MODE(15)) {
450  panic("Local APIC Trigger Mode registers are unimplemented.\n");
451  }
452  if (reg >= APIC_INTERRUPT_REQUEST(0) &&
453  reg <= APIC_INTERRUPT_REQUEST(15)) {
454  panic("Local APIC Interrupt Request registers "
455  "are unimplemented.\n");
456  }
457  switch (reg) {
458  case APIC_ID:
459  newVal = val & 0xFF;
460  break;
461  case APIC_VERSION:
462  // The Local APIC Version register is read only.
463  return;
464  case APIC_TASK_PRIORITY:
465  newVal = val & 0xFF;
466  break;
468  panic("Local APIC Arbitration Priority register unimplemented.\n");
469  break;
471  panic("Local APIC Processor Priority register unimplemented.\n");
472  break;
473  case APIC_EOI:
474  // Remove the interrupt that just completed from the local apic state.
475  clearRegArrayBit(APIC_IN_SERVICE_BASE, ISRV);
476  updateISRV();
477  return;
479  newVal = val & 0xFF000000;
480  break;
482  newVal = val | 0x0FFFFFFF;
483  break;
485  regs[APIC_INTERNAL_STATE] &= ~(1ULL << 1);
486  regs[APIC_INTERNAL_STATE] |= val & (1 << 8);
487  if (val & (1 << 9))
488  warn("Focus processor checking not implemented.\n");
489  break;
490  case APIC_ERROR_STATUS:
491  {
492  if (regs[APIC_INTERNAL_STATE] & 0x1) {
493  regs[APIC_INTERNAL_STATE] &= ~0x1ULL;
494  newVal = 0;
495  } else {
496  regs[APIC_INTERNAL_STATE] |= 0x1ULL;
497  return;
498  }
499 
500  }
501  break;
503  {
504  InterruptCommandRegLow low = regs[APIC_INTERRUPT_COMMAND_LOW];
505  // Check if we're already sending an IPI.
506  if (low.deliveryStatus) {
507  newVal = low;
508  break;
509  }
510  low = val;
511  InterruptCommandRegHigh high = regs[APIC_INTERRUPT_COMMAND_HIGH];
512  TriggerIntMessage message = 0;
513  message.destination = high.destination;
514  message.vector = low.vector;
515  message.deliveryMode = low.deliveryMode;
516  message.destMode = low.destMode;
517  message.level = low.level;
518  message.trigger = low.trigger;
519  std::list<int> apics;
520  int numContexts = sys->threads.size();
521  switch (low.destShorthand) {
522  case 0:
523  if (message.deliveryMode == delivery_mode::LowestPriority) {
524  panic("Lowest priority delivery mode "
525  "IPIs aren't implemented.\n");
526  }
527  if (message.destMode == 1) {
528  int dest = message.destination;
529  hack_once("Assuming logical destinations are 1 << id.\n");
530  for (int i = 0; i < numContexts; i++) {
531  if (dest & 0x1)
532  apics.push_back(i);
533  dest = dest >> 1;
534  }
535  } else {
536  if (message.destination == 0xFF) {
537  for (int i = 0; i < numContexts; i++) {
538  if (i == initialApicId) {
539  requestInterrupt(message.vector,
540  message.deliveryMode, message.trigger);
541  } else {
542  apics.push_back(i);
543  }
544  }
545  } else {
546  if (message.destination == initialApicId) {
547  requestInterrupt(message.vector,
548  message.deliveryMode, message.trigger);
549  } else {
550  apics.push_back(message.destination);
551  }
552  }
553  }
554  break;
555  case 1:
556  newVal = val;
557  requestInterrupt(message.vector,
558  message.deliveryMode, message.trigger);
559  break;
560  case 2:
561  requestInterrupt(message.vector,
562  message.deliveryMode, message.trigger);
563  // Fall through
564  case 3:
565  {
566  for (int i = 0; i < numContexts; i++) {
567  if (i != initialApicId) {
568  apics.push_back(i);
569  }
570  }
571  }
572  break;
573  }
574  // Record that an IPI is being sent if one actually is.
575  if (apics.size()) {
576  low.deliveryStatus = 1;
577  pendingIPIs += apics.size();
578  }
579  regs[APIC_INTERRUPT_COMMAND_LOW] = low;
580  for (auto id: apics) {
581  PacketPtr pkt = buildIntTriggerPacket(id, message);
582  intRequestPort.sendMessage(pkt, sys->isTimingMode(),
583  [this](PacketPtr pkt) { completeIPI(pkt); });
584  }
585  newVal = regs[APIC_INTERRUPT_COMMAND_LOW];
586  }
587  break;
588  case APIC_LVT_TIMER:
591  case APIC_LVT_LINT0:
592  case APIC_LVT_LINT1:
593  case APIC_LVT_ERROR:
594  {
595  uint64_t readOnlyMask = (1 << 12) | (1 << 14);
596  newVal = (val & ~readOnlyMask) |
597  (regs[reg] & readOnlyMask);
598  }
599  break;
600  case APIC_INITIAL_COUNT:
601  {
602  newVal = bits(val, 31, 0);
603  // Compute how many timer ticks we're being programmed for.
604  uint64_t newCount = newVal *
606  // Schedule on the edge of the next tick plus the new count.
607  Tick offset = curTick() % clockPeriod();
608  if (offset) {
609  reschedule(apicTimerEvent,
610  curTick() + (newCount + 1) *
611  clockPeriod() - offset, true);
612  } else {
613  if (newCount)
614  reschedule(apicTimerEvent,
615  curTick() + newCount *
616  clockPeriod(), true);
617  }
618  }
619  break;
620  case APIC_CURRENT_COUNT:
621  //Local APIC Current Count register is read only.
622  return;
624  newVal = val & 0xB;
625  break;
626  default:
627  break;
628  }
629  regs[reg] = newVal;
630  return;
631 }
632 
633 
635  : BaseInterrupts(p), sys(p.system), clockDomain(*p.clk_domain),
636  apicTimerEvent([this]{ processApicTimerEvent(); }, name()),
637  intResponsePort(name() + ".int_responder", this, this),
638  intRequestPort(name() + ".int_requestor", this, this, p.int_latency),
639  lint0Pin(name() + ".lint0", 0, this, 0),
640  lint1Pin(name() + ".lint1", 0, this, 1),
641  pioPort(this), pioDelay(p.pio_latency)
642 {
643  memset(regs, 0, sizeof(regs));
644  //Set the local apic DFR to the flat model.
645  regs[APIC_DESTINATION_FORMAT] = (uint32_t)(-1);
646 
647  // At reset, all LVT entries start out zeroed, except for their mask bit.
648  LVTEntry masked = 0;
649  masked.masked = 1;
650 
651  regs[APIC_LVT_TIMER] = masked;
652  regs[APIC_LVT_THERMAL_SENSOR] = masked;
654  regs[APIC_LVT_LINT0] = masked;
655  regs[APIC_LVT_LINT1] = masked;
656  regs[APIC_LVT_ERROR] = masked;
657 
658  regs[APIC_SPURIOUS_INTERRUPT_VECTOR] = 0xff;
659 
660  regs[APIC_VERSION] = (5 << 16) | 0x14;
661 }
662 
663 
664 bool
666 {
667  RFLAGS rflags = tc->readMiscRegNoEffect(misc_reg::Rflags);
668  if (pendingUnmaskableInt) {
669  DPRINTF(LocalApic, "Reported pending unmaskable interrupt.\n");
670  return true;
671  }
672  if (rflags.intf) {
673  if (pendingExtInt) {
674  DPRINTF(LocalApic, "Reported pending external interrupt.\n");
675  return true;
676  }
677  if (IRRV > ISRV && bits(IRRV, 7, 4) >
678  bits(regs[APIC_TASK_PRIORITY], 7, 4)) {
679  DPRINTF(LocalApic, "Reported pending regular interrupt.\n");
680  return true;
681  }
682  }
683  return false;
684 }
685 
686 bool
688 {
689  return pendingUnmaskableInt || pendingExtInt ||
690  (IRRV > ISRV && bits(IRRV, 7, 4) >
691  bits(regs[APIC_TASK_PRIORITY], 7, 4));
692 }
693 
694 Fault
696 {
697  assert(checkInterrupts());
698  // These are all probably fairly uncommon, so we'll make them easier to
699  // check for.
700  if (pendingUnmaskableInt) {
701  if (pendingSmi) {
702  DPRINTF(LocalApic, "Generated SMI fault object.\n");
703  return std::make_shared<SystemManagementInterrupt>();
704  } else if (pendingNmi) {
705  DPRINTF(LocalApic, "Generated NMI fault object.\n");
706  return std::make_shared<NonMaskableInterrupt>(nmiVector);
707  } else if (pendingInit) {
708  DPRINTF(LocalApic, "Generated INIT fault object.\n");
709  return std::make_shared<InitInterrupt>(initVector);
710  } else if (pendingStartup) {
711  DPRINTF(LocalApic, "Generating SIPI fault object.\n");
712  return std::make_shared<StartupInterrupt>(startupVector);
713  } else {
714  panic("pendingUnmaskableInt set, but no unmaskable "
715  "ints were pending.\n");
716  return NoFault;
717  }
718  } else if (pendingExtInt) {
719  DPRINTF(LocalApic, "Generated external interrupt fault object.\n");
720  return std::make_shared<ExternalInterrupt>(extIntVector);
721  } else {
722  DPRINTF(LocalApic, "Generated regular interrupt fault object.\n");
723  // The only thing left are fixed and lowest priority interrupts.
724  return std::make_shared<ExternalInterrupt>(IRRV);
725  }
726 }
727 
728 void
730 {
731  assert(checkInterrupts());
732  if (pendingUnmaskableInt) {
733  if (pendingSmi) {
734  DPRINTF(LocalApic, "SMI sent to core.\n");
735  pendingSmi = false;
736  } else if (pendingNmi) {
737  DPRINTF(LocalApic, "NMI sent to core.\n");
738  pendingNmi = false;
739  } else if (pendingInit) {
740  DPRINTF(LocalApic, "Init sent to core.\n");
741  pendingInit = false;
742  startedUp = false;
743  } else if (pendingStartup) {
744  DPRINTF(LocalApic, "SIPI sent to core.\n");
745  pendingStartup = false;
746  startedUp = true;
747  }
748  if (!(pendingSmi || pendingNmi || pendingInit || pendingStartup))
749  pendingUnmaskableInt = false;
750  } else if (pendingExtInt) {
751  pendingExtInt = false;
752  } else {
753  DPRINTF(LocalApic, "Interrupt %d sent to core.\n", IRRV);
754  // Mark the interrupt as "in service".
755  ISRV = IRRV;
756  setRegArrayBit(APIC_IN_SERVICE_BASE, ISRV);
757  // Clear it out of the IRR.
758  clearRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, IRRV);
759  updateIRRV();
760  }
761 }
762 
763 void
765 {
767  SERIALIZE_SCALAR(pendingSmi);
768  SERIALIZE_SCALAR(smiVector);
769  SERIALIZE_SCALAR(pendingNmi);
770  SERIALIZE_SCALAR(nmiVector);
771  SERIALIZE_SCALAR(pendingExtInt);
772  SERIALIZE_SCALAR(extIntVector);
773  SERIALIZE_SCALAR(pendingInit);
774  SERIALIZE_SCALAR(initVector);
775  SERIALIZE_SCALAR(pendingStartup);
776  SERIALIZE_SCALAR(startupVector);
777  SERIALIZE_SCALAR(startedUp);
778  SERIALIZE_SCALAR(pendingUnmaskableInt);
779  SERIALIZE_SCALAR(pendingIPIs);
780  SERIALIZE_SCALAR(IRRV);
781  SERIALIZE_SCALAR(ISRV);
782  bool apicTimerEventScheduled = apicTimerEvent.scheduled();
783  SERIALIZE_SCALAR(apicTimerEventScheduled);
784  Tick apicTimerEventTick = apicTimerEvent.when();
785  SERIALIZE_SCALAR(apicTimerEventTick);
786 }
787 
788 void
790 {
792  UNSERIALIZE_SCALAR(pendingSmi);
793  UNSERIALIZE_SCALAR(smiVector);
794  UNSERIALIZE_SCALAR(pendingNmi);
795  UNSERIALIZE_SCALAR(nmiVector);
796  UNSERIALIZE_SCALAR(pendingExtInt);
797  UNSERIALIZE_SCALAR(extIntVector);
798  UNSERIALIZE_SCALAR(pendingInit);
799  UNSERIALIZE_SCALAR(initVector);
800  UNSERIALIZE_SCALAR(pendingStartup);
801  UNSERIALIZE_SCALAR(startupVector);
802  UNSERIALIZE_SCALAR(startedUp);
803  UNSERIALIZE_SCALAR(pendingUnmaskableInt);
804  UNSERIALIZE_SCALAR(pendingIPIs);
805  UNSERIALIZE_SCALAR(IRRV);
806  UNSERIALIZE_SCALAR(ISRV);
807  bool apicTimerEventScheduled;
808  UNSERIALIZE_SCALAR(apicTimerEventScheduled);
809  if (apicTimerEventScheduled) {
810  Tick apicTimerEventTick;
811  UNSERIALIZE_SCALAR(apicTimerEventTick);
812  if (apicTimerEvent.scheduled()) {
813  reschedule(apicTimerEvent, apicTimerEventTick, true);
814  } else {
815  schedule(apicTimerEvent, apicTimerEventTick);
816  }
817  }
818 }
819 
820 void
822 {
823  if (triggerTimerInterrupt())
825 }
826 
827 } // namespace gem5
gem5::X86ISA::level
Bitfield< 20 > level
Definition: intmessage.hh:51
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::X86ISA::mask
mask
Definition: misc.hh:796
gem5::X86ISA::Interrupts::read
Tick read(PacketPtr pkt)
Definition: interrupts.cc:194
gem5::NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:253
apic.hh
warn
#define warn(...)
Definition: logging.hh:246
gem5::X86ISA::APIC_INTERRUPT_COMMAND_LOW
@ APIC_INTERRUPT_COMMAND_LOW
Definition: apic.hh:58
system.hh
gem5::X86ISA::APIC_LOGICAL_DESTINATION
@ APIC_LOGICAL_DESTINATION
Definition: apic.hh:47
gem5::divideFromConf
int divideFromConf(uint32_t conf)
Definition: interrupts.cc:71
hack_once
#define hack_once(...)
Definition: logging.hh:254
south_bridge.hh
gem5::X86ISA::Interrupts::lowerInterruptPin
void lowerInterruptPin(int number)
Definition: interrupts.cc:303
gem5::X86ISA::x86LocalAPICAddress
static Addr x86LocalAPICAddress(const uint8_t id, const uint16_t addr)
Definition: x86_traits.hh:91
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
gem5::X86ISA::APIC_LVT_LINT1
@ APIC_LVT_LINT1
Definition: apic.hh:64
gem5::X86ISA::Interrupts::setReg
void setReg(ApicRegIndex reg, uint32_t val)
Definition: interrupts.cc:441
gem5::X86ISA::APIC_INTERRUPT_COMMAND_HIGH
@ APIC_INTERRUPT_COMMAND_HIGH
Definition: apic.hh:59
gem5::X86ISA::vector
Bitfield< 15, 8 > vector
Definition: intmessage.hh:48
gem5::X86ISA::Interrupts::checkInterrupts
bool checkInterrupts() const override
Definition: interrupts.cc:665
gem5::RangeSize
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:815
gem5::X86ISA::ApicRegIndex
ApicRegIndex
Definition: apic.hh:39
gem5::Packet::setData
void setData(const uint8_t *p)
Copy data into the packet from the provided pointer.
Definition: packet.hh:1265
gem5::X86ISA::APIC_LVT_LINT0
@ APIC_LVT_LINT0
Definition: apic.hh:63
gem5::X86ISA::APIC_ERROR_STATUS
@ APIC_ERROR_STATUS
Definition: apic.hh:57
gem5::X86ISA::Interrupts::checkInterruptsRaw
bool checkInterruptsRaw() const
Check if there are pending interrupts without ignoring the interrupts disabled flag.
Definition: interrupts.cc:687
gem5::X86ISA::delivery_mode::isReserved
static bool isReserved(int mode)
Definition: intmessage.hh:76
gem5::BaseInterrupts
Definition: interrupts.hh:41
gem5::X86ISA::APIC_CURRENT_COUNT
@ APIC_CURRENT_COUNT
Definition: apic.hh:67
gem5::X86ISA::APIC_SPURIOUS_INTERRUPT_VECTOR
@ APIC_SPURIOUS_INTERRUPT_VECTOR
Definition: apic.hh:49
gem5::CheckpointIn
Definition: serialize.hh:68
gem5::X86ISA::Interrupts::setThreadContext
void setThreadContext(ThreadContext *_tc) override
Definition: interrupts.cc:312
intmessage.hh
gem5::X86ISA::decodeAddr
ApicRegIndex decodeAddr(Addr paddr)
Definition: interrupts.cc:85
gem5::X86ISA::offset
offset
Definition: misc.hh:1024
gem5::X86ISA::APIC_TRIGGER_MODE
static ApicRegIndex APIC_TRIGGER_MODE(int index)
Definition: apic.hh:82
gem5::X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:769
interrupts.hh
gem5::guest_abi::setReg
tc setReg(id, &reg)
gem5::X86ISA::APIC_DIVIDE_CONFIGURATION
@ APIC_DIVIDE_CONFIGURATION
Definition: apic.hh:68
gem5::X86ISA::Interrupts::processApicTimerEvent
void processApicTimerEvent()
Definition: interrupts.cc:821
gem5::X86ISA::system
Bitfield< 15 > system
Definition: misc.hh:997
gem5::X86ISA::APIC_LVT_PERFORMANCE_MONITORING_COUNTERS
@ APIC_LVT_PERFORMANCE_MONITORING_COUNTERS
Definition: apic.hh:62
gem5::Packet::makeAtomicResponse
void makeAtomicResponse()
Definition: packet.hh:1056
gem5::X86ISA::delivery_mode::Fixed
@ Fixed
Definition: intmessage.hh:60
gem5::X86ISA::Interrupts::Interrupts
Interrupts(const Params &p)
Definition: interrupts.cc:634
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:67
gem5::X86ISA::APIC_ARBITRATION_PRIORITY
@ APIC_ARBITRATION_PRIORITY
Definition: apic.hh:44
gem5::X86ISA::APIC_TRIGGER_MODE_BASE
@ APIC_TRIGGER_MODE_BASE
Definition: apic.hh:53
gem5::X86ISA::delivery_mode::LowestPriority
@ LowestPriority
Definition: intmessage.hh:61
gem5::ThreadContext::cpuId
virtual int cpuId() const =0
gem5::X86ISA::APIC_LVT_THERMAL_SENSOR
@ APIC_LVT_THERMAL_SENSOR
Definition: apic.hh:61
gem5::letoh
T letoh(T value)
Definition: byteswap.hh:173
gem5::RangeEx
AddrRange RangeEx(Addr start, Addr end)
Definition: addr_range.hh:797
gem5::X86ISA::delivery_mode::SMI
@ SMI
Definition: intmessage.hh:62
gem5::X86ISA::Interrupts::completeIPI
void completeIPI(PacketPtr pkt)
Definition: interrupts.cc:368
gem5::ArmISA::shift
Bitfield< 6, 5 > shift
Definition: types.hh:117
gem5::X86ISA::Interrupts::getIntAddrRange
AddrRangeList getIntAddrRange() const
Definition: interrupts.cc:392
gem5::X86ISA::APIC_INTERNAL_STATE
@ APIC_INTERNAL_STATE
Definition: apic.hh:70
gem5::X86ISA::Interrupts::updateIntrInfo
void updateIntrInfo() override
Definition: interrupts.cc:729
gem5::high
high
Definition: intmath.hh:176
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:94
gem5::Packet::getRaw
T getRaw() const
Get the data in the packet without byte swapping.
Definition: packet_access.hh:52
pc.hh
gem5::Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
gem5::X86ISA::APIC_LVT_TIMER
@ APIC_LVT_TIMER
Definition: apic.hh:60
i82094aa.hh
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:291
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::X86ISA::APIC_EOI
@ APIC_EOI
Definition: apic.hh:46
gem5::X86ISA::Interrupts::raiseInterruptPin
void raiseInterruptPin(int number)
Definition: interrupts.cc:278
gem5::BaseInterrupts::setThreadContext
virtual void setThreadContext(ThreadContext *_tc)
Definition: interrupts.hh:51
gem5::X86ISA::delivery_mode::NMI
@ NMI
Definition: intmessage.hh:63
gem5::X86ISA::APIC_INTERRUPT_REQUEST_BASE
@ APIC_INTERRUPT_REQUEST_BASE
Definition: apic.hh:55
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
SERIALIZE_ARRAY
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:610
gem5::X86ISA::delivery_mode::names
static const char *const names[NumModes]
Definition: intmessage.hh:70
gem5::X86ISA::APIC_INTERRUPT_REQUEST
static ApicRegIndex APIC_INTERRUPT_REQUEST(int index)
Definition: apic.hh:88
gem5::Packet::cmd
MemCmd cmd
The command field of the packet.
Definition: packet.hh:369
gem5::Packet::writeData
void writeData(uint8_t *p) const
Copy data from the packet to the memory at the provided pointer.
Definition: packet.hh:1294
gem5::X86ISA::delivery_mode::INIT
@ INIT
Definition: intmessage.hh:64
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
name
const std::string & name()
Definition: trace.cc:49
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568
packet_access.hh
gem5::X86ISA::Interrupts::readReg
uint32_t readReg(ApicRegIndex miscReg)
Definition: interrupts.cc:403
full_system.hh
gem5::X86ISA::reg
Bitfield< 5, 3 > reg
Definition: types.hh:92
gem5::X86ISA::delivery_mode::ExtInt
@ ExtInt
Definition: intmessage.hh:66
gem5::FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:220
gem5::X86ISA::APIC_TASK_PRIORITY
@ APIC_TASK_PRIORITY
Definition: apic.hh:43
gem5::MipsISA::dm
Bitfield< 30 > dm
Definition: dt_constants.hh:43
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:204
gem5::X86ISA::buildIntTriggerPacket
static PacketPtr buildIntTriggerPacket(int id, TriggerIntMessage message)
Definition: intmessage.hh:85
gem5::X86ISA::PhysAddrAPICRangeSize
const Addr PhysAddrAPICRangeSize
Definition: x86_traits.hh:73
base.hh
gem5::X86ISA::APIC_PROCESSOR_PRIORITY
@ APIC_PROCESSOR_PRIORITY
Definition: apic.hh:45
UNSERIALIZE_ARRAY
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:618
gem5::X86ISA::x86InterruptAddress
static Addr x86InterruptAddress(const uint8_t id, const uint16_t addr)
Definition: x86_traits.hh:98
gem5::X86ISA::Interrupts::pioDelay
Tick pioDelay
Definition: interrupts.hh:191
gem5::X86ISA::APIC_INITIAL_COUNT
@ APIC_INITIAL_COUNT
Definition: apic.hh:66
gem5::X86ISA::APIC_VERSION
@ APIC_VERSION
Definition: apic.hh:42
gem5::X86ISA::Interrupts::requestInterrupt
void requestInterrupt(uint8_t vector, uint8_t deliveryMode, bool level)
Definition: interrupts.cc:228
gem5::X86ISA::Interrupts::write
Tick write(PacketPtr pkt)
Definition: interrupts.cc:211
gem5::X86ISA::APIC_IN_SERVICE_BASE
@ APIC_IN_SERVICE_BASE
Definition: apic.hh:51
gem5::X86ISA::Interrupts::getInterrupt
Fault getInterrupt() override
Definition: interrupts.cc:695
gem5::htole
T htole(T value)
Definition: byteswap.hh:172
gem5::MemCmd::WriteReq
@ WriteReq
Definition: packet.hh:89
gem5::X86ISA::buildIntAcknowledgePacket
static PacketPtr buildIntAcknowledgePacket()
Definition: intmessage.hh:92
gem5::X86ISA::Interrupts::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: interrupts.cc:327
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::X86ISA::p
Bitfield< 0 > p
Definition: pagetable.hh:151
gem5::X86ISA::misc_reg::Rflags
@ Rflags
Definition: misc.hh:143
gem5::X86ISA::Interrupts::pioAddr
Addr pioAddr
Definition: interrupts.hh:192
gem5::CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:66
gem5::X86ISA::APIC_IN_SERVICE
static ApicRegIndex APIC_IN_SERVICE(int index)
Definition: apic.hh:76
std::list< AddrRange >
gem5::Packet::getAddr
Addr getAddr() const
Definition: packet.hh:790
gem5::X86ISA::PageBytes
const Addr PageBytes
Definition: page_size.hh:49
gem5::BaseInterrupts::Params
BaseInterruptsParams Params
Definition: interrupts.hh:47
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::X86ISA::APIC_LVT_ERROR
@ APIC_LVT_ERROR
Definition: apic.hh:65
gem5::X86ISA::APIC_ID
@ APIC_ID
Definition: apic.hh:41
misc.hh
gem5::X86ISA::deliveryMode
Bitfield< 18, 16 > deliveryMode
Definition: intmessage.hh:49
gem5::X86ISA::Interrupts::recvMessage
Tick recvMessage(PacketPtr pkt)
Definition: interrupts.cc:340
gem5::X86ISA::Interrupts::getAddrRanges
AddrRangeList getAddrRanges() const
Definition: interrupts.cc:382
gem5::Packet::getSize
unsigned getSize() const
Definition: packet.hh:800
gem5::X86ISA::Interrupts::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: interrupts.cc:789
gem5::X86ISA::Interrupts::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: interrupts.cc:764
gem5::X86ISA::trigger
Bitfield< 21 > trigger
Definition: intmessage.hh:52
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
gem5::X86ISA::APIC_DESTINATION_FORMAT
@ APIC_DESTINATION_FORMAT
Definition: apic.hh:48
gem5::X86ISA::NUM_APIC_REGS
@ NUM_APIC_REGS
Definition: apic.hh:72
gem5::X86ISA::delivery_mode::SIPI
@ SIPI
Definition: intmessage.hh:65

Generated on Thu Jul 28 2022 13:32:22 for gem5 by doxygen 1.8.17