gem5  v20.1.0.0
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 "cpu/base.hh"
58 #include "debug/LocalApic.hh"
59 #include "dev/x86/i82094aa.hh"
60 #include "dev/x86/pc.hh"
61 #include "dev/x86/south_bridge.hh"
62 #include "mem/packet_access.hh"
63 #include "sim/full_system.hh"
64 #include "sim/system.hh"
65 
66 int
67 divideFromConf(uint32_t conf)
68 {
69  // This figures out what division we want from the division configuration
70  // register in the local APIC. The encoding is a little odd but it can
71  // be deciphered fairly easily.
72  int shift = ((conf & 0x8) >> 1) | (conf & 0x3);
73  shift = (shift + 1) % 8;
74  return 1 << shift;
75 }
76 
77 namespace X86ISA
78 {
79 
82 {
83  ApicRegIndex regNum;
84  paddr &= ~mask(3);
85  switch (paddr)
86  {
87  case 0x20:
88  regNum = APIC_ID;
89  break;
90  case 0x30:
91  regNum = APIC_VERSION;
92  break;
93  case 0x80:
94  regNum = APIC_TASK_PRIORITY;
95  break;
96  case 0x90:
98  break;
99  case 0xA0:
100  regNum = APIC_PROCESSOR_PRIORITY;
101  break;
102  case 0xB0:
103  regNum = APIC_EOI;
104  break;
105  case 0xD0:
106  regNum = APIC_LOGICAL_DESTINATION;
107  break;
108  case 0xE0:
109  regNum = APIC_DESTINATION_FORMAT;
110  break;
111  case 0xF0:
113  break;
114  case 0x100:
115  case 0x110:
116  case 0x120:
117  case 0x130:
118  case 0x140:
119  case 0x150:
120  case 0x160:
121  case 0x170:
122  regNum = APIC_IN_SERVICE((paddr - 0x100) / 0x10);
123  break;
124  case 0x180:
125  case 0x190:
126  case 0x1A0:
127  case 0x1B0:
128  case 0x1C0:
129  case 0x1D0:
130  case 0x1E0:
131  case 0x1F0:
132  regNum = APIC_TRIGGER_MODE((paddr - 0x180) / 0x10);
133  break;
134  case 0x200:
135  case 0x210:
136  case 0x220:
137  case 0x230:
138  case 0x240:
139  case 0x250:
140  case 0x260:
141  case 0x270:
142  regNum = APIC_INTERRUPT_REQUEST((paddr - 0x200) / 0x10);
143  break;
144  case 0x280:
145  regNum = APIC_ERROR_STATUS;
146  break;
147  case 0x300:
149  break;
150  case 0x310:
152  break;
153  case 0x320:
154  regNum = APIC_LVT_TIMER;
155  break;
156  case 0x330:
157  regNum = APIC_LVT_THERMAL_SENSOR;
158  break;
159  case 0x340:
161  break;
162  case 0x350:
163  regNum = APIC_LVT_LINT0;
164  break;
165  case 0x360:
166  regNum = APIC_LVT_LINT1;
167  break;
168  case 0x370:
169  regNum = APIC_LVT_ERROR;
170  break;
171  case 0x380:
172  regNum = APIC_INITIAL_COUNT;
173  break;
174  case 0x390:
175  regNum = APIC_CURRENT_COUNT;
176  break;
177  case 0x3E0:
178  regNum = APIC_DIVIDE_CONFIGURATION;
179  break;
180  default:
181  // A reserved register field.
182  panic("Accessed reserved register field %#x.\n", paddr);
183  break;
184  }
185  return regNum;
186 }
187 }
188 
189 Tick
191 {
192  Addr offset = pkt->getAddr() - pioAddr;
193  // Make sure we're at least only accessing one register.
194  if ((offset & ~mask(3)) != ((offset + pkt->getSize()) & ~mask(3)))
195  panic("Accessed more than one register at a time in the APIC!\n");
197  uint32_t val = htole(readReg(reg));
198  DPRINTF(LocalApic,
199  "Reading Local APIC register %d at offset %#x as %#x.\n",
200  reg, offset, val);
201  pkt->setData(((uint8_t *)&val) + (offset & mask(3)));
202  pkt->makeAtomicResponse();
203  return pioDelay;
204 }
205 
206 Tick
208 {
209  Addr offset = pkt->getAddr() - pioAddr;
210  // Make sure we're at least only accessing one register.
211  if ((offset & ~mask(3)) != ((offset + pkt->getSize()) & ~mask(3)))
212  panic("Accessed more than one register at a time in the APIC!\n");
214  uint32_t val = regs[reg];
215  pkt->writeData(((uint8_t *)&val) + (offset & mask(3)));
216  DPRINTF(LocalApic,
217  "Writing Local APIC register %d at offset %#x as %#x.\n",
218  reg, offset, letoh(val));
219  setReg(reg, letoh(val));
220  pkt->makeAtomicResponse();
221  return pioDelay;
222 }
223 void
225  uint8_t deliveryMode, bool level)
226 {
227  /*
228  * Fixed and lowest-priority delivery mode interrupts are handled
229  * using the IRR/ISR registers, checking against the TPR, etc.
230  * The SMI, NMI, ExtInt, INIT, etc interrupts go straight through.
231  */
232  if (deliveryMode == DeliveryMode::Fixed ||
233  deliveryMode == DeliveryMode::LowestPriority) {
234  DPRINTF(LocalApic, "Interrupt is an %s.\n",
235  DeliveryMode::names[deliveryMode]);
236  // Queue up the interrupt in the IRR.
237  if (vector > IRRV)
238  IRRV = vector;
239  if (!getRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector)) {
240  setRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector);
241  if (level) {
242  setRegArrayBit(APIC_TRIGGER_MODE_BASE, vector);
243  } else {
244  clearRegArrayBit(APIC_TRIGGER_MODE_BASE, vector);
245  }
246  }
247  } else if (!DeliveryMode::isReserved(deliveryMode)) {
248  DPRINTF(LocalApic, "Interrupt is an %s.\n",
249  DeliveryMode::names[deliveryMode]);
250  if (deliveryMode == DeliveryMode::SMI && !pendingSmi) {
251  pendingUnmaskableInt = pendingSmi = true;
252  smiVector = vector;
253  } else if (deliveryMode == DeliveryMode::NMI && !pendingNmi) {
254  pendingUnmaskableInt = pendingNmi = true;
255  nmiVector = vector;
256  } else if (deliveryMode == DeliveryMode::ExtInt && !pendingExtInt) {
257  pendingExtInt = true;
258  extIntVector = vector;
259  } else if (deliveryMode == DeliveryMode::INIT && !pendingInit) {
260  pendingUnmaskableInt = pendingInit = true;
261  initVector = vector;
262  } else if (deliveryMode == DeliveryMode::SIPI &&
263  !pendingStartup && !startedUp) {
264  pendingUnmaskableInt = pendingStartup = true;
265  startupVector = vector;
266  }
267  }
268  if (FullSystem)
269  tc->getCpuPtr()->wakeup(0);
270 }
271 
272 
273 void
275 {
276  assert(_tc);
277  panic_if(tc != NULL && tc->cpuId() != _tc->cpuId(),
278  "Local APICs can't be moved between CPUs with different IDs.");
279 
281 
282  initialApicId = tc->cpuId();
283  regs[APIC_ID] = (initialApicId << 24);
284  pioAddr = x86LocalAPICAddress(initialApicId, 0);
285 }
286 
287 
288 void
290 {
291  panic_if(!intRequestPort.isConnected(),
292  "Int port not connected to anything!");
293  panic_if(!pioPort.isConnected(),
294  "Pio port of %s not connected to anything!", name());
295 
296  intResponsePort.sendRangeChange();
297  pioPort.sendRangeChange();
298 }
299 
300 
301 Tick
303 {
304  Addr offset = pkt->getAddr() - x86InterruptAddress(initialApicId, 0);
305  assert(pkt->cmd == MemCmd::WriteReq);
306  switch(offset)
307  {
308  case 0:
309  {
310  TriggerIntMessage message = pkt->getRaw<TriggerIntMessage>();
311  DPRINTF(LocalApic,
312  "Got Trigger Interrupt message with vector %#x.\n",
313  message.vector);
314 
315  requestInterrupt(message.vector,
316  message.deliveryMode, message.trigger);
317  }
318  break;
319  default:
320  panic("Local apic got unknown interrupt message at offset %#x.\n",
321  offset);
322  break;
323  }
324  pkt->makeAtomicResponse();
325  return pioDelay;
326 }
327 
328 
329 void
331 {
332  if (--pendingIPIs == 0) {
333  InterruptCommandRegLow low = regs[APIC_INTERRUPT_COMMAND_LOW];
334  // Record that the ICR is now idle.
335  low.deliveryStatus = 0;
336  regs[APIC_INTERRUPT_COMMAND_LOW] = low;
337  }
338  DPRINTF(LocalApic, "ICR is now idle.\n");
339  delete pkt;
340 }
341 
342 
345 {
346  assert(tc);
347  AddrRangeList ranges;
348  ranges.push_back(RangeSize(pioAddr, PageBytes));
349  return ranges;
350 }
351 
352 
355 {
356  AddrRangeList ranges;
357  ranges.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
358  x86InterruptAddress(initialApicId, 0) +
360  return ranges;
361 }
362 
363 
364 uint32_t
366 {
367  if (reg >= APIC_TRIGGER_MODE(0) &&
368  reg <= APIC_TRIGGER_MODE(15)) {
369  panic("Local APIC Trigger Mode registers are unimplemented.\n");
370  }
371  switch (reg) {
373  panic("Local APIC Arbitration Priority register unimplemented.\n");
374  break;
376  panic("Local APIC Processor Priority register unimplemented.\n");
377  break;
378  case APIC_ERROR_STATUS:
379  regs[APIC_INTERNAL_STATE] &= ~ULL(0x1);
380  break;
381  case APIC_CURRENT_COUNT:
382  {
383  if (apicTimerEvent.scheduled()) {
384  // Compute how many m5 ticks happen per count.
385  uint64_t ticksPerCount = clockPeriod() *
387  // Compute how many m5 ticks are left.
388  uint64_t val = apicTimerEvent.when() - curTick();
389  // Turn that into a count.
390  val = (val + ticksPerCount - 1) / ticksPerCount;
391  return val;
392  } else {
393  return 0;
394  }
395  }
396  default:
397  break;
398  }
399  return regs[reg];
400 }
401 
402 void
404 {
405  uint32_t newVal = val;
406  if (reg >= APIC_IN_SERVICE(0) &&
407  reg <= APIC_IN_SERVICE(15)) {
408  panic("Local APIC In-Service registers are unimplemented.\n");
409  }
410  if (reg >= APIC_TRIGGER_MODE(0) &&
411  reg <= APIC_TRIGGER_MODE(15)) {
412  panic("Local APIC Trigger Mode registers are unimplemented.\n");
413  }
414  if (reg >= APIC_INTERRUPT_REQUEST(0) &&
415  reg <= APIC_INTERRUPT_REQUEST(15)) {
416  panic("Local APIC Interrupt Request registers "
417  "are unimplemented.\n");
418  }
419  switch (reg) {
420  case APIC_ID:
421  newVal = val & 0xFF;
422  break;
423  case APIC_VERSION:
424  // The Local APIC Version register is read only.
425  return;
426  case APIC_TASK_PRIORITY:
427  newVal = val & 0xFF;
428  break;
430  panic("Local APIC Arbitration Priority register unimplemented.\n");
431  break;
433  panic("Local APIC Processor Priority register unimplemented.\n");
434  break;
435  case APIC_EOI:
436  // Remove the interrupt that just completed from the local apic state.
437  clearRegArrayBit(APIC_IN_SERVICE_BASE, ISRV);
438  updateISRV();
439  return;
441  newVal = val & 0xFF000000;
442  break;
444  newVal = val | 0x0FFFFFFF;
445  break;
447  regs[APIC_INTERNAL_STATE] &= ~ULL(1 << 1);
448  regs[APIC_INTERNAL_STATE] |= val & (1 << 8);
449  if (val & (1 << 9))
450  warn("Focus processor checking not implemented.\n");
451  break;
452  case APIC_ERROR_STATUS:
453  {
454  if (regs[APIC_INTERNAL_STATE] & 0x1) {
455  regs[APIC_INTERNAL_STATE] &= ~ULL(0x1);
456  newVal = 0;
457  } else {
458  regs[APIC_INTERNAL_STATE] |= ULL(0x1);
459  return;
460  }
461 
462  }
463  break;
465  {
466  InterruptCommandRegLow low = regs[APIC_INTERRUPT_COMMAND_LOW];
467  // Check if we're already sending an IPI.
468  if (low.deliveryStatus) {
469  newVal = low;
470  break;
471  }
472  low = val;
473  InterruptCommandRegHigh high = regs[APIC_INTERRUPT_COMMAND_HIGH];
474  TriggerIntMessage message = 0;
475  message.destination = high.destination;
476  message.vector = low.vector;
477  message.deliveryMode = low.deliveryMode;
478  message.destMode = low.destMode;
479  message.level = low.level;
480  message.trigger = low.trigger;
481  std::list<int> apics;
482  int numContexts = sys->threads.size();
483  switch (low.destShorthand) {
484  case 0:
485  if (message.deliveryMode == DeliveryMode::LowestPriority) {
486  panic("Lowest priority delivery mode "
487  "IPIs aren't implemented.\n");
488  }
489  if (message.destMode == 1) {
490  int dest = message.destination;
491  hack_once("Assuming logical destinations are 1 << id.\n");
492  for (int i = 0; i < numContexts; i++) {
493  if (dest & 0x1)
494  apics.push_back(i);
495  dest = dest >> 1;
496  }
497  } else {
498  if (message.destination == 0xFF) {
499  for (int i = 0; i < numContexts; i++) {
500  if (i == initialApicId) {
501  requestInterrupt(message.vector,
502  message.deliveryMode, message.trigger);
503  } else {
504  apics.push_back(i);
505  }
506  }
507  } else {
508  if (message.destination == initialApicId) {
509  requestInterrupt(message.vector,
510  message.deliveryMode, message.trigger);
511  } else {
512  apics.push_back(message.destination);
513  }
514  }
515  }
516  break;
517  case 1:
518  newVal = val;
519  requestInterrupt(message.vector,
520  message.deliveryMode, message.trigger);
521  break;
522  case 2:
523  requestInterrupt(message.vector,
524  message.deliveryMode, message.trigger);
525  // Fall through
526  case 3:
527  {
528  for (int i = 0; i < numContexts; i++) {
529  if (i != initialApicId) {
530  apics.push_back(i);
531  }
532  }
533  }
534  break;
535  }
536  // Record that an IPI is being sent if one actually is.
537  if (apics.size()) {
538  low.deliveryStatus = 1;
539  pendingIPIs += apics.size();
540  }
541  regs[APIC_INTERRUPT_COMMAND_LOW] = low;
542  for (auto id: apics) {
543  PacketPtr pkt = buildIntTriggerPacket(id, message);
544  intRequestPort.sendMessage(pkt, sys->isTimingMode(),
545  [this](PacketPtr pkt) { completeIPI(pkt); });
546  }
547  newVal = regs[APIC_INTERRUPT_COMMAND_LOW];
548  }
549  break;
550  case APIC_LVT_TIMER:
553  case APIC_LVT_LINT0:
554  case APIC_LVT_LINT1:
555  case APIC_LVT_ERROR:
556  {
557  uint64_t readOnlyMask = (1 << 12) | (1 << 14);
558  newVal = (val & ~readOnlyMask) |
559  (regs[reg] & readOnlyMask);
560  }
561  break;
562  case APIC_INITIAL_COUNT:
563  {
564  newVal = bits(val, 31, 0);
565  // Compute how many timer ticks we're being programmed for.
566  uint64_t newCount = newVal *
568  // Schedule on the edge of the next tick plus the new count.
569  Tick offset = curTick() % clockPeriod();
570  if (offset) {
571  reschedule(apicTimerEvent,
572  curTick() + (newCount + 1) *
573  clockPeriod() - offset, true);
574  } else {
575  if (newCount)
576  reschedule(apicTimerEvent,
577  curTick() + newCount *
578  clockPeriod(), true);
579  }
580  }
581  break;
582  case APIC_CURRENT_COUNT:
583  //Local APIC Current Count register is read only.
584  return;
586  newVal = val & 0xB;
587  break;
588  default:
589  break;
590  }
591  regs[reg] = newVal;
592  return;
593 }
594 
595 
597  : BaseInterrupts(p), sys(p->system), clockDomain(*p->clk_domain),
598  apicTimerEvent([this]{ processApicTimerEvent(); }, name()),
599  pendingSmi(false), smiVector(0),
600  pendingNmi(false), nmiVector(0),
601  pendingExtInt(false), extIntVector(0),
602  pendingInit(false), initVector(0),
603  pendingStartup(false), startupVector(0),
604  startedUp(false), pendingUnmaskableInt(false),
605  pendingIPIs(0),
606  intResponsePort(name() + ".int_responder", this, this),
607  intRequestPort(name() + ".int_requestor", this, this, p->int_latency),
608  pioPort(this), pioDelay(p->pio_latency)
609 {
610  memset(regs, 0, sizeof(regs));
611  //Set the local apic DFR to the flat model.
612  regs[APIC_DESTINATION_FORMAT] = (uint32_t)(-1);
613  ISRV = 0;
614  IRRV = 0;
615 
616  regs[APIC_VERSION] = (5 << 16) | 0x14;
617 }
618 
619 
620 bool
622 {
623  RFLAGS rflags = tc->readMiscRegNoEffect(MISCREG_RFLAGS);
624  if (pendingUnmaskableInt) {
625  DPRINTF(LocalApic, "Reported pending unmaskable interrupt.\n");
626  return true;
627  }
628  if (rflags.intf) {
629  if (pendingExtInt) {
630  DPRINTF(LocalApic, "Reported pending external interrupt.\n");
631  return true;
632  }
633  if (IRRV > ISRV && bits(IRRV, 7, 4) >
634  bits(regs[APIC_TASK_PRIORITY], 7, 4)) {
635  DPRINTF(LocalApic, "Reported pending regular interrupt.\n");
636  return true;
637  }
638  }
639  return false;
640 }
641 
642 bool
644 {
645  return pendingUnmaskableInt || pendingExtInt ||
646  (IRRV > ISRV && bits(IRRV, 7, 4) >
647  bits(regs[APIC_TASK_PRIORITY], 7, 4));
648 }
649 
650 Fault
652 {
653  assert(checkInterrupts());
654  // These are all probably fairly uncommon, so we'll make them easier to
655  // check for.
656  if (pendingUnmaskableInt) {
657  if (pendingSmi) {
658  DPRINTF(LocalApic, "Generated SMI fault object.\n");
659  return std::make_shared<SystemManagementInterrupt>();
660  } else if (pendingNmi) {
661  DPRINTF(LocalApic, "Generated NMI fault object.\n");
662  return std::make_shared<NonMaskableInterrupt>(nmiVector);
663  } else if (pendingInit) {
664  DPRINTF(LocalApic, "Generated INIT fault object.\n");
665  return std::make_shared<InitInterrupt>(initVector);
666  } else if (pendingStartup) {
667  DPRINTF(LocalApic, "Generating SIPI fault object.\n");
668  return std::make_shared<StartupInterrupt>(startupVector);
669  } else {
670  panic("pendingUnmaskableInt set, but no unmaskable "
671  "ints were pending.\n");
672  return NoFault;
673  }
674  } else if (pendingExtInt) {
675  DPRINTF(LocalApic, "Generated external interrupt fault object.\n");
676  return std::make_shared<ExternalInterrupt>(extIntVector);
677  } else {
678  DPRINTF(LocalApic, "Generated regular interrupt fault object.\n");
679  // The only thing left are fixed and lowest priority interrupts.
680  return std::make_shared<ExternalInterrupt>(IRRV);
681  }
682 }
683 
684 void
686 {
687  assert(checkInterrupts());
688  if (pendingUnmaskableInt) {
689  if (pendingSmi) {
690  DPRINTF(LocalApic, "SMI sent to core.\n");
691  pendingSmi = false;
692  } else if (pendingNmi) {
693  DPRINTF(LocalApic, "NMI sent to core.\n");
694  pendingNmi = false;
695  } else if (pendingInit) {
696  DPRINTF(LocalApic, "Init sent to core.\n");
697  pendingInit = false;
698  startedUp = false;
699  } else if (pendingStartup) {
700  DPRINTF(LocalApic, "SIPI sent to core.\n");
701  pendingStartup = false;
702  startedUp = true;
703  }
704  if (!(pendingSmi || pendingNmi || pendingInit || pendingStartup))
705  pendingUnmaskableInt = false;
706  } else if (pendingExtInt) {
707  pendingExtInt = false;
708  } else {
709  DPRINTF(LocalApic, "Interrupt %d sent to core.\n", IRRV);
710  // Mark the interrupt as "in service".
711  ISRV = IRRV;
712  setRegArrayBit(APIC_IN_SERVICE_BASE, ISRV);
713  // Clear it out of the IRR.
714  clearRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, IRRV);
715  updateIRRV();
716  }
717 }
718 
719 void
721 {
723  SERIALIZE_SCALAR(pendingSmi);
724  SERIALIZE_SCALAR(smiVector);
725  SERIALIZE_SCALAR(pendingNmi);
726  SERIALIZE_SCALAR(nmiVector);
727  SERIALIZE_SCALAR(pendingExtInt);
728  SERIALIZE_SCALAR(extIntVector);
729  SERIALIZE_SCALAR(pendingInit);
730  SERIALIZE_SCALAR(initVector);
731  SERIALIZE_SCALAR(pendingStartup);
732  SERIALIZE_SCALAR(startupVector);
733  SERIALIZE_SCALAR(startedUp);
734  SERIALIZE_SCALAR(pendingUnmaskableInt);
735  SERIALIZE_SCALAR(pendingIPIs);
736  SERIALIZE_SCALAR(IRRV);
737  SERIALIZE_SCALAR(ISRV);
738  bool apicTimerEventScheduled = apicTimerEvent.scheduled();
739  SERIALIZE_SCALAR(apicTimerEventScheduled);
740  Tick apicTimerEventTick = apicTimerEvent.when();
741  SERIALIZE_SCALAR(apicTimerEventTick);
742 }
743 
744 void
746 {
748  UNSERIALIZE_SCALAR(pendingSmi);
749  UNSERIALIZE_SCALAR(smiVector);
750  UNSERIALIZE_SCALAR(pendingNmi);
751  UNSERIALIZE_SCALAR(nmiVector);
752  UNSERIALIZE_SCALAR(pendingExtInt);
753  UNSERIALIZE_SCALAR(extIntVector);
754  UNSERIALIZE_SCALAR(pendingInit);
755  UNSERIALIZE_SCALAR(initVector);
756  UNSERIALIZE_SCALAR(pendingStartup);
757  UNSERIALIZE_SCALAR(startupVector);
758  UNSERIALIZE_SCALAR(startedUp);
759  UNSERIALIZE_SCALAR(pendingUnmaskableInt);
760  UNSERIALIZE_SCALAR(pendingIPIs);
761  UNSERIALIZE_SCALAR(IRRV);
762  UNSERIALIZE_SCALAR(ISRV);
763  bool apicTimerEventScheduled;
764  UNSERIALIZE_SCALAR(apicTimerEventScheduled);
765  if (apicTimerEventScheduled) {
766  Tick apicTimerEventTick;
767  UNSERIALIZE_SCALAR(apicTimerEventTick);
768  if (apicTimerEvent.scheduled()) {
769  reschedule(apicTimerEvent, apicTimerEventTick, true);
770  } else {
771  schedule(apicTimerEvent, apicTimerEventTick);
772  }
773  }
774 }
775 
777 X86LocalApicParams::create()
778 {
779  return new X86ISA::Interrupts(this);
780 }
781 
782 void
784  if (triggerTimerInterrupt())
785  setReg(APIC_INITIAL_COUNT, readReg(APIC_INITIAL_COUNT));
786 }
X86ISA::APIC_TASK_PRIORITY
@ APIC_TASK_PRIORITY
Definition: apic.hh:40
Packet::makeAtomicResponse
void makeAtomicResponse()
Definition: packet.hh:1016
X86ISA::APIC_LVT_PERFORMANCE_MONITORING_COUNTERS
@ APIC_LVT_PERFORMANCE_MONITORING_COUNTERS
Definition: apic.hh:59
apic.hh
X86ISA::Interrupts::completeIPI
void completeIPI(PacketPtr pkt)
Definition: interrupts.cc:330
warn
#define warn(...)
Definition: logging.hh:239
X86ISA::Interrupts::requestInterrupt
void requestInterrupt(uint8_t vector, uint8_t deliveryMode, bool level)
Definition: interrupts.cc:224
system.hh
hack_once
#define hack_once(...)
Definition: logging.hh:245
south_bridge.hh
X86ISA::Interrupts::Interrupts
Interrupts(Params *p)
Definition: interrupts.cc:596
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:797
Packet::getAddr
Addr getAddr() const
Definition: packet.hh:754
X86ISA::x86InterruptAddress
static Addr x86InterruptAddress(const uint8_t id, const uint16_t addr)
Definition: x86_traits.hh:100
X86ISA::APIC_DIVIDE_CONFIGURATION
@ APIC_DIVIDE_CONFIGURATION
Definition: apic.hh:65
Packet::writeData
void writeData(uint8_t *p) const
Copy data from the packet to the memory at the provided pointer.
Definition: packet.hh:1254
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
X86ISA::Interrupts::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: interrupts.cc:745
X86ISA::Interrupts::getAddrRanges
AddrRangeList getAddrRanges() const
Definition: interrupts.cc:344
X86ISA::Interrupts::pioDelay
Tick pioDelay
Definition: interrupts.hh:183
X86ISA::APIC_LVT_THERMAL_SENSOR
@ APIC_LVT_THERMAL_SENSOR
Definition: apic.hh:58
htole
T htole(T value)
Definition: byteswap.hh:140
intmessage.hh
divideFromConf
int divideFromConf(uint32_t conf)
Definition: interrupts.cc:67
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
interrupts.hh
X86ISA::APIC_INTERRUPT_REQUEST
static ApicRegIndex APIC_INTERRUPT_REQUEST(int index)
Definition: apic.hh:85
FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:132
Packet::getSize
unsigned getSize() const
Definition: packet.hh:764
X86ISA::APIC_DESTINATION_FORMAT
@ APIC_DESTINATION_FORMAT
Definition: apic.hh:45
X86ISA::ApicRegIndex
ApicRegIndex
Definition: apic.hh:36
X86ISA::APIC_VERSION
@ APIC_VERSION
Definition: apic.hh:39
X86ISA::reg
Bitfield< 5, 3 > reg
Definition: types.hh:87
Packet::setData
void setData(const uint8_t *p)
Copy data into the packet from the provided pointer.
Definition: packet.hh:1225
MemCmd::WriteReq
@ WriteReq
Definition: packet.hh:85
X86ISA::system
Bitfield< 15 > system
Definition: misc.hh:997
X86ISA::Interrupts::setReg
void setReg(ApicRegIndex reg, uint32_t val)
Definition: interrupts.cc:403
X86ISA::Interrupts::getIntAddrRange
AddrRangeList getIntAddrRange() const
Definition: interrupts.cc:354
letoh
T letoh(T value)
Definition: byteswap.hh:141
cp
Definition: cprintf.cc:40
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
pc.hh
i82094aa.hh
ArmISA::shift
Bitfield< 6, 5 > shift
Definition: types.hh:126
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
X86ISA::MISCREG_RFLAGS
@ MISCREG_RFLAGS
Definition: misc.hh:134
Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:240
X86ISA::APIC_ID
@ APIC_ID
Definition: apic.hh:38
X86ISA::Interrupts::checkInterrupts
bool checkInterrupts() const override
Definition: interrupts.cc:621
X86ISA::APIC_ARBITRATION_PRIORITY
@ APIC_ARBITRATION_PRIORITY
Definition: apic.hh:41
RangeSize
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:638
X86ISA::PageBytes
const Addr PageBytes
Definition: isa_traits.hh:48
X86ISA::APIC_IN_SERVICE_BASE
@ APIC_IN_SERVICE_BASE
Definition: apic.hh:48
ThreadContext::cpuId
virtual int cpuId() const =0
BaseInterrupts::Params
BaseInterruptsParams Params
Definition: interrupts.hh:43
X86ISA::APIC_INTERRUPT_COMMAND_LOW
@ APIC_INTERRUPT_COMMAND_LOW
Definition: apic.hh:55
SERIALIZE_ARRAY
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:832
X86ISA::APIC_IN_SERVICE
static ApicRegIndex APIC_IN_SERVICE(int index)
Definition: apic.hh:73
X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:769
NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:245
X86ISA
This is exposed globally, independent of the ISA.
Definition: acpi.hh:55
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
name
const std::string & name()
Definition: trace.cc:50
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:790
X86ISA::Interrupts::updateIntrInfo
void updateIntrInfo() override
Definition: interrupts.cc:685
packet_access.hh
X86ISA::APIC_TRIGGER_MODE_BASE
@ APIC_TRIGGER_MODE_BASE
Definition: apic.hh:50
full_system.hh
X86ISA::x86LocalAPICAddress
static Addr x86LocalAPICAddress(const uint8_t id, const uint16_t addr)
Definition: x86_traits.hh:93
X86ISA::offset
offset
Definition: misc.hh:1024
X86ISA::Interrupts::pioAddr
Addr pioAddr
Definition: interrupts.hh:184
X86ISA::Interrupts::checkInterruptsRaw
bool checkInterruptsRaw() const
Check if there are pending interrupts without ignoring the interrupts disabled flag.
Definition: interrupts.cc:643
X86ISA::Interrupts::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: interrupts.cc:720
Packet::cmd
MemCmd cmd
The command field of the packet.
Definition: packet.hh:335
Packet::getRaw
T getRaw() const
Get the data in the packet without byte swapping.
Definition: packet_access.hh:49
X86ISA::APIC_ERROR_STATUS
@ APIC_ERROR_STATUS
Definition: apic.hh:54
X86ISA::NUM_APIC_REGS
@ NUM_APIC_REGS
Definition: apic.hh:69
X86ISA::level
Bitfield< 20 > level
Definition: intmessage.hh:47
X86ISA::Interrupts::readReg
uint32_t readReg(ApicRegIndex miscReg)
Definition: interrupts.cc:365
X86ISA::APIC_INTERNAL_STATE
@ APIC_INTERNAL_STATE
Definition: apic.hh:67
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
X86ISA::buildIntTriggerPacket
static PacketPtr buildIntTriggerPacket(int id, TriggerIntMessage message)
Definition: intmessage.hh:79
base.hh
X86ISA::p
Bitfield< 0 > p
Definition: pagetable.hh:151
UNSERIALIZE_ARRAY
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:840
X86ISA::vector
Bitfield< 15, 8 > vector
Definition: intmessage.hh:44
BaseInterrupts::setThreadContext
virtual void setThreadContext(ThreadContext *_tc)
Definition: interrupts.hh:47
X86ISA::Interrupts::recvMessage
Tick recvMessage(PacketPtr pkt)
Definition: interrupts.cc:302
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
X86ISA::PhysAddrAPICRangeSize
const Addr PhysAddrAPICRangeSize
Definition: x86_traits.hh:78
X86ISA::APIC_PROCESSOR_PRIORITY
@ APIC_PROCESSOR_PRIORITY
Definition: apic.hh:42
X86ISA::APIC_CURRENT_COUNT
@ APIC_CURRENT_COUNT
Definition: apic.hh:64
X86ISA::decodeAddr
ApicRegIndex decodeAddr(Addr paddr)
Definition: interrupts.cc:81
X86ISA::Interrupts::processApicTimerEvent
void processApicTimerEvent()
Definition: interrupts.cc:783
X86ISA::APIC_INTERRUPT_COMMAND_HIGH
@ APIC_INTERRUPT_COMMAND_HIGH
Definition: apic.hh:56
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:63
X86ISA::APIC_LVT_LINT1
@ APIC_LVT_LINT1
Definition: apic.hh:61
X86ISA::mask
mask
Definition: misc.hh:796
RangeEx
AddrRange RangeEx(Addr start, Addr end)
Definition: addr_range.hh:624
X86ISA::APIC_LVT_TIMER
@ APIC_LVT_TIMER
Definition: apic.hh:57
X86ISA::APIC_TRIGGER_MODE
static ApicRegIndex APIC_TRIGGER_MODE(int index)
Definition: apic.hh:79
X86ISA::APIC_LVT_ERROR
@ APIC_LVT_ERROR
Definition: apic.hh:62
X86ISA::Interrupts::write
Tick write(PacketPtr pkt)
Definition: interrupts.cc:207
X86ISA::APIC_INTERRUPT_REQUEST_BASE
@ APIC_INTERRUPT_REQUEST_BASE
Definition: apic.hh:52
X86ISA::APIC_EOI
@ APIC_EOI
Definition: apic.hh:43
X86ISA::Interrupts::setThreadContext
void setThreadContext(ThreadContext *_tc) override
Definition: interrupts.cc:274
std::list< AddrRange >
X86ISA::APIC_SPURIOUS_INTERRUPT_VECTOR
@ APIC_SPURIOUS_INTERRUPT_VECTOR
Definition: apic.hh:46
BaseInterrupts
Definition: interrupts.hh:37
CheckpointIn
Definition: serialize.hh:67
X86ISA::APIC_LVT_LINT0
@ APIC_LVT_LINT0
Definition: apic.hh:60
X86ISA::APIC_LOGICAL_DESTINATION
@ APIC_LOGICAL_DESTINATION
Definition: apic.hh:44
X86ISA::Interrupts
Definition: interrupts.hh:74
X86ISA::APIC_INITIAL_COUNT
@ APIC_INITIAL_COUNT
Definition: apic.hh:63
X86ISA::Interrupts::getInterrupt
Fault getInterrupt() override
Definition: interrupts.cc:651
X86ISA::deliveryMode
Bitfield< 18, 16 > deliveryMode
Definition: intmessage.hh:45
X86ISA::Interrupts::read
Tick read(PacketPtr pkt)
Definition: interrupts.cc:190
ULL
#define ULL(N)
uint64_t constant
Definition: types.hh:50
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
X86ISA::Interrupts::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: interrupts.cc:289
curTick
Tick curTick()
The current simulated tick.
Definition: core.hh:45
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:01:58 for gem5 by doxygen 1.8.17