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