gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
51
52#include <list>
53#include <memory>
54
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"
63#include "mem/packet_access.hh"
64#include "sim/full_system.hh"
65#include "sim/system.hh"
66
67namespace gem5
68{
69
70int
71divideFromConf(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
81namespace 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:
102 break;
103 case 0xA0:
105 break;
106 case 0xB0:
107 regNum = APIC_EOI;
108 break;
109 case 0xD0:
111 break;
112 case 0xE0:
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:
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:
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
193Tick
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
210Tick
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}
227void
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 */
236 if (deliveryMode == delivery_mode::Fixed ||
237 deliveryMode == delivery_mode::LowestPriority) {
238 DPRINTF(LocalApic, "Interrupt is an %s.\n",
239 delivery_mode::names[deliveryMode]);
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 }
251 } else if (!delivery_mode::isReserved(deliveryMode)) {
252 DPRINTF(LocalApic, "Interrupt is an %s.\n",
253 delivery_mode::names[deliveryMode]);
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
277void
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
302void
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
311void
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 // Update APIC ID to consider SMT threads
321 initialApicId = tc->contextId();
322 regs[APIC_ID] = (initialApicId << 24);
323 pioAddr = x86LocalAPICAddress(initialApicId, 0);
324}
325
326
327void
329{
330 panic_if(!intRequestPort.isConnected(),
331 "Int port not connected to anything!");
332 panic_if(!pioPort.isConnected(),
333 "Pio port of %s not connected to anything!", name());
334
335 intResponsePort.sendRangeChange();
336 pioPort.sendRangeChange();
337}
338
339
340Tick
342{
343 Addr offset = pkt->getAddr() - x86InterruptAddress(initialApicId, 0);
344 assert(pkt->cmd == MemCmd::WriteReq);
345 switch(offset)
346 {
347 case 0:
348 {
349 TriggerIntMessage message = pkt->getRaw<TriggerIntMessage>();
350 DPRINTF(LocalApic,
351 "Got Trigger Interrupt message with vector %#x.\n",
352 message.vector);
353
354 requestInterrupt(message.vector,
355 message.deliveryMode, message.trigger);
356 }
357 break;
358 default:
359 panic("Local apic got unknown interrupt message at offset %#x.\n",
360 offset);
361 break;
362 }
363 pkt->makeAtomicResponse();
364 return pioDelay;
365}
366
367
368void
370{
371 if (--pendingIPIs == 0) {
372 InterruptCommandRegLow low = regs[APIC_INTERRUPT_COMMAND_LOW];
373 // Record that the ICR is now idle.
374 low.deliveryStatus = 0;
375 regs[APIC_INTERRUPT_COMMAND_LOW] = low;
376 }
377 DPRINTF(LocalApic, "ICR is now idle.\n");
378 delete pkt;
379}
380
381
384{
385 assert(tc);
386 AddrRangeList ranges;
387 ranges.push_back(RangeSize(pioAddr, PageBytes));
388 return ranges;
389}
390
391
394{
395 AddrRangeList ranges;
396 ranges.push_back(RangeEx(x86InterruptAddress(initialApicId, 0),
397 x86InterruptAddress(initialApicId, 0) +
399 return ranges;
400}
401
402
403uint32_t
405{
406 if (reg >= APIC_TRIGGER_MODE(0) &&
407 reg <= APIC_TRIGGER_MODE(15)) {
408 panic("Local APIC Trigger Mode registers are unimplemented.\n");
409 }
410 switch (reg) {
412 panic("Local APIC Arbitration Priority register unimplemented.\n");
413 break;
415 panic("Local APIC Processor Priority register unimplemented.\n");
416 break;
418 regs[APIC_INTERNAL_STATE] &= ~0x1ULL;
419 break;
421 {
422 if (apicTimerEvent.scheduled()) {
423 // Compute how many m5 ticks happen per count.
424 uint64_t ticksPerCount = clockPeriod() *
426 // Compute how many m5 ticks are left.
427 uint64_t val = apicTimerEvent.when() - curTick();
428 // Turn that into a count.
429 val = (val + ticksPerCount - 1) / ticksPerCount;
430 return val;
431 } else {
432 return 0;
433 }
434 }
435 default:
436 break;
437 }
438 return regs[reg];
439}
440
441void
443{
444 uint32_t newVal = val;
445 if (reg >= APIC_IN_SERVICE(0) &&
446 reg <= APIC_IN_SERVICE(15)) {
447 panic("Local APIC In-Service registers are unimplemented.\n");
448 }
449 if (reg >= APIC_TRIGGER_MODE(0) &&
450 reg <= APIC_TRIGGER_MODE(15)) {
451 panic("Local APIC Trigger Mode registers are unimplemented.\n");
452 }
453 if (reg >= APIC_INTERRUPT_REQUEST(0) &&
455 panic("Local APIC Interrupt Request registers "
456 "are unimplemented.\n");
457 }
458 switch (reg) {
459 case APIC_ID:
460 newVal = val & 0xFF;
461 break;
462 case APIC_VERSION:
463 // The Local APIC Version register is read only.
464 return;
466 newVal = val & 0xFF;
467 break;
469 panic("Local APIC Arbitration Priority register unimplemented.\n");
470 break;
472 panic("Local APIC Processor Priority register unimplemented.\n");
473 break;
474 case APIC_EOI:
475 // Remove the interrupt that just completed from the local apic state.
476 clearRegArrayBit(APIC_IN_SERVICE_BASE, ISRV);
477 updateISRV();
478 return;
480 newVal = val & 0xFF000000;
481 break;
483 newVal = val | 0x0FFFFFFF;
484 break;
486 regs[APIC_INTERNAL_STATE] &= ~(1ULL << 1);
487 regs[APIC_INTERNAL_STATE] |= val & (1 << 8);
488 if (val & (1 << 9))
489 warn("Focus processor checking not implemented.\n");
490 break;
492 {
493 if (regs[APIC_INTERNAL_STATE] & 0x1) {
494 regs[APIC_INTERNAL_STATE] &= ~0x1ULL;
495 newVal = 0;
496 } else {
497 regs[APIC_INTERNAL_STATE] |= 0x1ULL;
498 return;
499 }
500
501 }
502 break;
504 {
505 InterruptCommandRegLow low = regs[APIC_INTERRUPT_COMMAND_LOW];
506 // Check if we're already sending an IPI.
507 if (low.deliveryStatus) {
508 newVal = low;
509 break;
510 }
511 low = val;
512 InterruptCommandRegHigh high = regs[APIC_INTERRUPT_COMMAND_HIGH];
513 TriggerIntMessage message = 0;
514 message.destination = high.destination;
515 message.vector = low.vector;
516 message.deliveryMode = low.deliveryMode;
517 message.destMode = low.destMode;
518 message.level = low.level;
519 message.trigger = low.trigger;
520 std::list<int> apics;
521 int numContexts = sys->threads.size();
522 switch (low.destShorthand) {
523 case 0:
524 if (message.deliveryMode == delivery_mode::LowestPriority) {
525 panic("Lowest priority delivery mode "
526 "IPIs aren't implemented.\n");
527 }
528 if (message.destMode == 1) {
529 int dest = message.destination;
530 hack_once("Assuming logical destinations are 1 << id.\n");
531 for (int i = 0; i < numContexts; i++) {
532 if (dest & 0x1)
533 apics.push_back(i);
534 dest = dest >> 1;
535 }
536 } else {
537 if (message.destination == 0xFF) {
538 for (int i = 0; i < numContexts; i++) {
539 if (i == initialApicId) {
540 requestInterrupt(message.vector,
541 message.deliveryMode, message.trigger);
542 } else {
543 apics.push_back(i);
544 }
545 }
546 } else {
547 if (message.destination == initialApicId) {
548 requestInterrupt(message.vector,
549 message.deliveryMode, message.trigger);
550 } else {
551 apics.push_back(message.destination);
552 }
553 }
554 }
555 break;
556 case 1:
557 newVal = val;
558 requestInterrupt(message.vector,
559 message.deliveryMode, message.trigger);
560 break;
561 case 2:
562 requestInterrupt(message.vector,
563 message.deliveryMode, message.trigger);
564 // Fall through
565 case 3:
566 {
567 for (int i = 0; i < numContexts; i++) {
568 if (i != initialApicId) {
569 apics.push_back(i);
570 }
571 }
572 }
573 break;
574 }
575 // Record that an IPI is being sent if one actually is.
576 if (apics.size()) {
577 low.deliveryStatus = 1;
578 pendingIPIs += apics.size();
579 }
580 regs[APIC_INTERRUPT_COMMAND_LOW] = low;
581 for (auto id: apics) {
582 PacketPtr pkt = buildIntTriggerPacket(id, message);
583 intRequestPort.sendMessage(pkt, sys->isTimingMode(),
584 [this](PacketPtr pkt) { completeIPI(pkt); });
585 }
586 newVal = regs[APIC_INTERRUPT_COMMAND_LOW];
587 }
588 break;
589 case APIC_LVT_TIMER:
592 case APIC_LVT_LINT0:
593 case APIC_LVT_LINT1:
594 case APIC_LVT_ERROR:
595 {
596 uint64_t readOnlyMask = (1 << 12) | (1 << 14);
597 newVal = (val & ~readOnlyMask) |
598 (regs[reg] & readOnlyMask);
599 }
600 break;
602 {
603 newVal = bits(val, 31, 0);
604 // Compute how many timer ticks we're being programmed for.
605 uint64_t newCount = newVal *
607 // Schedule on the edge of the next tick plus the new count.
608 Tick offset = curTick() % clockPeriod();
609 if (offset) {
610 reschedule(apicTimerEvent,
611 curTick() + (newCount + 1) *
612 clockPeriod() - offset, true);
613 } else {
614 if (newCount)
615 reschedule(apicTimerEvent,
616 curTick() + newCount *
617 clockPeriod(), true);
618 }
619 }
620 break;
622 //Local APIC Current Count register is read only.
623 return;
625 newVal = val & 0xB;
626 break;
627 default:
628 break;
629 }
630 regs[reg] = newVal;
631 return;
632}
633
634
636 : BaseInterrupts(p), sys(p.system), clockDomain(*p.clk_domain),
637 apicTimerEvent([this]{ processApicTimerEvent(); }, name()),
638 intResponsePort(name() + ".int_responder", this, this),
639 intRequestPort(name() + ".int_requestor", this, this, p.int_latency),
640 lint0Pin(name() + ".lint0", 0, this, 0),
641 lint1Pin(name() + ".lint1", 0, this, 1),
642 pioPort(this), pioDelay(p.pio_latency)
643{
644 memset(regs, 0, sizeof(regs));
645 //Set the local apic DFR to the flat model.
646 regs[APIC_DESTINATION_FORMAT] = (uint32_t)(-1);
647
648 // At reset, all LVT entries start out zeroed, except for their mask bit.
649 LVTEntry masked = 0;
650 masked.masked = 1;
651
652 regs[APIC_LVT_TIMER] = masked;
653 regs[APIC_LVT_THERMAL_SENSOR] = masked;
655 regs[APIC_LVT_LINT0] = masked;
656 regs[APIC_LVT_LINT1] = masked;
657 regs[APIC_LVT_ERROR] = masked;
658
660
661 regs[APIC_VERSION] = (5 << 16) | 0x14;
662}
663
664
665bool
667{
668 RFLAGS rflags = tc->readMiscRegNoEffect(misc_reg::Rflags);
669 if (pendingUnmaskableInt) {
670 DPRINTF(LocalApic, "Reported pending unmaskable interrupt.\n");
671 return true;
672 }
673 if (rflags.intf) {
674 if (pendingExtInt) {
675 DPRINTF(LocalApic, "Reported pending external interrupt.\n");
676 return true;
677 }
678 if (IRRV > ISRV && bits(IRRV, 7, 4) >
679 bits(regs[APIC_TASK_PRIORITY], 7, 4)) {
680 DPRINTF(LocalApic, "Reported pending regular interrupt.\n");
681 return true;
682 }
683 }
684 return false;
685}
686
687bool
689{
690 return pendingUnmaskableInt || pendingExtInt ||
691 (IRRV > ISRV && bits(IRRV, 7, 4) >
692 bits(regs[APIC_TASK_PRIORITY], 7, 4));
693}
694
695Fault
697{
698 assert(checkInterrupts());
699 // These are all probably fairly uncommon, so we'll make them easier to
700 // check for.
701 if (pendingUnmaskableInt) {
702 if (pendingSmi) {
703 DPRINTF(LocalApic, "Generated SMI fault object.\n");
704 return std::make_shared<SystemManagementInterrupt>();
705 } else if (pendingNmi) {
706 DPRINTF(LocalApic, "Generated NMI fault object.\n");
707 return std::make_shared<NonMaskableInterrupt>(nmiVector);
708 } else if (pendingInit) {
709 DPRINTF(LocalApic, "Generated INIT fault object.\n");
710 return std::make_shared<InitInterrupt>(initVector);
711 } else if (pendingStartup) {
712 DPRINTF(LocalApic, "Generating SIPI fault object.\n");
713 return std::make_shared<StartupInterrupt>(startupVector);
714 } else {
715 panic("pendingUnmaskableInt set, but no unmaskable "
716 "ints were pending.\n");
717 return NoFault;
718 }
719 } else if (pendingExtInt) {
720 DPRINTF(LocalApic, "Generated external interrupt fault object.\n");
721 return std::make_shared<ExternalInterrupt>(extIntVector);
722 } else {
723 DPRINTF(LocalApic, "Generated regular interrupt fault object.\n");
724 // The only thing left are fixed and lowest priority interrupts.
725 return std::make_shared<ExternalInterrupt>(IRRV);
726 }
727}
728
729void
731{
732 assert(checkInterrupts());
733 if (pendingUnmaskableInt) {
734 if (pendingSmi) {
735 DPRINTF(LocalApic, "SMI sent to core.\n");
736 pendingSmi = false;
737 } else if (pendingNmi) {
738 DPRINTF(LocalApic, "NMI sent to core.\n");
739 pendingNmi = false;
740 } else if (pendingInit) {
741 DPRINTF(LocalApic, "Init sent to core.\n");
742 pendingInit = false;
743 startedUp = false;
744 } else if (pendingStartup) {
745 DPRINTF(LocalApic, "SIPI sent to core.\n");
746 pendingStartup = false;
747 startedUp = true;
748 }
749 if (!(pendingSmi || pendingNmi || pendingInit || pendingStartup))
750 pendingUnmaskableInt = false;
751 } else if (pendingExtInt) {
752 pendingExtInt = false;
753 } else {
754 DPRINTF(LocalApic, "Interrupt %d sent to core.\n", IRRV);
755 // Mark the interrupt as "in service".
756 ISRV = IRRV;
757 setRegArrayBit(APIC_IN_SERVICE_BASE, ISRV);
758 // Clear it out of the IRR.
759 clearRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, IRRV);
760 updateIRRV();
761 }
762}
763
764void
766{
768 SERIALIZE_SCALAR(pendingSmi);
769 SERIALIZE_SCALAR(smiVector);
770 SERIALIZE_SCALAR(pendingNmi);
771 SERIALIZE_SCALAR(nmiVector);
772 SERIALIZE_SCALAR(pendingExtInt);
773 SERIALIZE_SCALAR(extIntVector);
774 SERIALIZE_SCALAR(pendingInit);
775 SERIALIZE_SCALAR(initVector);
776 SERIALIZE_SCALAR(pendingStartup);
777 SERIALIZE_SCALAR(startupVector);
778 SERIALIZE_SCALAR(startedUp);
779 SERIALIZE_SCALAR(pendingUnmaskableInt);
780 SERIALIZE_SCALAR(pendingIPIs);
781 SERIALIZE_SCALAR(IRRV);
782 SERIALIZE_SCALAR(ISRV);
783 bool apicTimerEventScheduled = apicTimerEvent.scheduled();
784 SERIALIZE_SCALAR(apicTimerEventScheduled);
785 Tick apicTimerEventTick = apicTimerEvent.when();
786 SERIALIZE_SCALAR(apicTimerEventTick);
787}
788
789void
791{
793 UNSERIALIZE_SCALAR(pendingSmi);
794 UNSERIALIZE_SCALAR(smiVector);
795 UNSERIALIZE_SCALAR(pendingNmi);
796 UNSERIALIZE_SCALAR(nmiVector);
797 UNSERIALIZE_SCALAR(pendingExtInt);
798 UNSERIALIZE_SCALAR(extIntVector);
799 UNSERIALIZE_SCALAR(pendingInit);
800 UNSERIALIZE_SCALAR(initVector);
801 UNSERIALIZE_SCALAR(pendingStartup);
802 UNSERIALIZE_SCALAR(startupVector);
803 UNSERIALIZE_SCALAR(startedUp);
804 UNSERIALIZE_SCALAR(pendingUnmaskableInt);
805 UNSERIALIZE_SCALAR(pendingIPIs);
806 UNSERIALIZE_SCALAR(IRRV);
807 UNSERIALIZE_SCALAR(ISRV);
808 bool apicTimerEventScheduled;
809 UNSERIALIZE_SCALAR(apicTimerEventScheduled);
810 if (apicTimerEventScheduled) {
811 Tick apicTimerEventTick;
812 UNSERIALIZE_SCALAR(apicTimerEventTick);
813 if (apicTimerEvent.scheduled()) {
814 reschedule(apicTimerEvent, apicTimerEventTick, true);
815 } else {
816 schedule(apicTimerEvent, apicTimerEventTick);
817 }
818 }
819}
820
821void
823{
824 if (triggerTimerInterrupt())
825 setReg(APIC_INITIAL_COUNT, readReg(APIC_INITIAL_COUNT));
826}
827
828} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
virtual void setThreadContext(ThreadContext *_tc)
Definition interrupts.hh:51
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
Addr getAddr() const
Definition packet.hh:807
void setData(const uint8_t *p)
Copy data into the packet from the provided pointer.
Definition packet.hh:1293
unsigned getSize() const
Definition packet.hh:817
T getRaw() const
Get the data in the packet without byte swapping.
void makeAtomicResponse()
Definition packet.hh:1074
MemCmd cmd
The command field of the packet.
Definition packet.hh:372
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
void writeData(uint8_t *p) const
Copy data from the packet to the memory at the provided pointer.
Definition packet.hh:1322
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual int cpuId() const =0
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Interrupts(const Params &p)
void completeIPI(PacketPtr pkt)
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
bool checkInterrupts() const override
AddrRangeList getIntAddrRange() const
void setReg(ApicRegIndex reg, uint32_t val)
AddrRangeList getAddrRanges() const
X86LocalApicParams Params
Tick read(PacketPtr pkt)
void updateIntrInfo() override
bool checkInterruptsRaw() const
Check if there are pending interrupts without ignoring the interrupts disabled flag.
Tick recvMessage(PacketPtr pkt)
void raiseInterruptPin(int number)
void requestInterrupt(uint8_t vector, uint8_t deliveryMode, bool level)
void serialize(CheckpointOut &cp) const override
Serialize an object.
Tick write(PacketPtr pkt)
void setThreadContext(ThreadContext *_tc) override
Fault getInterrupt() override
uint32_t readReg(ApicRegIndex miscReg)
void lowerInterruptPin(int number)
AddrRange RangeEx(Addr start, Addr end)
AddrRange RangeSize(Addr start, Addr size)
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:79
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define hack_once(...)
Definition logging.hh:264
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:214
#define UNSERIALIZE_ARRAY(member, size)
Definition serialize.hh:618
#define SERIALIZE_ARRAY(member, size)
Definition serialize.hh:610
#define warn(...)
Definition logging.hh:256
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 6, 5 > shift
Definition types.hh:117
Bitfield< 30 > dm
Bitfield< 5, 3 > reg
Definition types.hh:92
Bitfield< 15 > system
Definition misc.hh:1032
static ApicRegIndex APIC_TRIGGER_MODE(int index)
Definition apic.hh:82
Bitfield< 63 > val
Definition misc.hh:804
static PacketPtr buildIntAcknowledgePacket()
Definition intmessage.hh:91
Bitfield< 20 > level
Definition intmessage.hh:51
Bitfield< 18, 16 > deliveryMode
Definition intmessage.hh:49
const Addr PhysAddrAPICRangeSize
Definition x86_traits.hh:74
static PacketPtr buildIntTriggerPacket(int id, TriggerIntMessage message)
Definition intmessage.hh:84
@ APIC_TRIGGER_MODE_BASE
Definition apic.hh:53
@ APIC_INTERNAL_STATE
Definition apic.hh:70
@ APIC_LVT_LINT0
Definition apic.hh:63
@ APIC_TASK_PRIORITY
Definition apic.hh:43
@ APIC_LOGICAL_DESTINATION
Definition apic.hh:47
@ APIC_LVT_LINT1
Definition apic.hh:64
@ APIC_CURRENT_COUNT
Definition apic.hh:67
@ APIC_INTERRUPT_COMMAND_HIGH
Definition apic.hh:59
@ APIC_INITIAL_COUNT
Definition apic.hh:66
@ APIC_DESTINATION_FORMAT
Definition apic.hh:48
@ APIC_VERSION
Definition apic.hh:42
@ APIC_INTERRUPT_REQUEST_BASE
Definition apic.hh:55
@ APIC_INTERRUPT_COMMAND_LOW
Definition apic.hh:58
@ APIC_LVT_THERMAL_SENSOR
Definition apic.hh:61
@ APIC_PROCESSOR_PRIORITY
Definition apic.hh:45
@ APIC_ARBITRATION_PRIORITY
Definition apic.hh:44
@ NUM_APIC_REGS
Definition apic.hh:72
@ APIC_SPURIOUS_INTERRUPT_VECTOR
Definition apic.hh:49
@ APIC_DIVIDE_CONFIGURATION
Definition apic.hh:68
@ APIC_ERROR_STATUS
Definition apic.hh:57
@ APIC_LVT_TIMER
Definition apic.hh:60
@ APIC_IN_SERVICE_BASE
Definition apic.hh:51
@ APIC_LVT_PERFORMANCE_MONITORING_COUNTERS
Definition apic.hh:62
@ APIC_LVT_ERROR
Definition apic.hh:65
Bitfield< 15, 8 > vector
Definition intmessage.hh:48
Bitfield< 0 > p
Definition pagetable.hh:151
static ApicRegIndex APIC_INTERRUPT_REQUEST(int index)
Definition apic.hh:88
Bitfield< 21 > trigger
Definition intmessage.hh:52
static ApicRegIndex APIC_IN_SERVICE(int index)
Definition apic.hh:76
static Addr x86LocalAPICAddress(const uint8_t id, const uint16_t addr)
Definition x86_traits.hh:92
ApicRegIndex decodeAddr(Addr paddr)
Definition interrupts.cc:85
static Addr x86InterruptAddress(const uint8_t id, const uint16_t addr)
Definition x86_traits.hh:99
const Addr PageBytes
Definition page_size.hh:49
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
std::shared_ptr< FaultBase > Fault
Definition types.hh:249
T letoh(T value)
Definition byteswap.hh:173
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
std::ostream CheckpointOut
Definition serialize.hh:66
int divideFromConf(uint32_t conf)
Definition interrupts.cc:71
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition root.cc:220
uint64_t Tick
Tick count type.
Definition types.hh:58
T htole(T value)
Definition byteswap.hh:172
constexpr decltype(nullptr) NoFault
Definition types.hh:253
Declaration of top level class for PC platform components.
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568
const std::string & name()
Definition trace.cc:48

Generated on Tue Jun 18 2024 16:23:57 for gem5 by doxygen 1.11.0