gem5 [DEVELOP-FOR-25.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;
245 if (level) {
247 } else {
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) {
257 } else if (deliveryMode == delivery_mode::NMI && !pendingNmi) {
260 } else if (deliveryMode == delivery_mode::ExtInt && !pendingExtInt) {
261 pendingExtInt = true;
263 } else if (deliveryMode == delivery_mode::INIT && !pendingInit) {
266 } else if (deliveryMode == delivery_mode::SIPI &&
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);
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{
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;
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),
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.
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 }
581 for (auto id: apics) {
582 PacketPtr pkt = buildIntTriggerPacket(id, message);
583 intRequestPort.sendMessage(pkt, sys->isTimingMode(),
584 [this](PacketPtr pkt) { completeIPI(pkt); });
585 }
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.
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);
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{
691 (IRRV > ISRV && bits(IRRV, 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.
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());
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 }
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;
758 // Clear it out of the IRR.
760 updateIRRV();
761 }
762}
763
764void
788
789void
791{
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
827
828} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
ThreadContext * tc
Definition interrupts.hh:44
BaseInterrupts(const Params &p)
Definition interrupts.hh:49
virtual void setThreadContext(ThreadContext *_tc)
Definition interrupts.hh:51
virtual std::string name() const
Definition named.hh:60
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)
Bitfield< 15 > trigger
Definition interrupts.hh:93
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
void setRegArrayBit(ApicRegIndex base, uint8_t vector)
AddrRangeList getIntAddrRange() const
Bitfield< 10, 8 > deliveryMode
Definition interrupts.hh:89
void setReg(ApicRegIndex reg, uint32_t val)
AddrRangeList getAddrRanges() const
X86LocalApicParams Params
IntRequestPort< Interrupts > intRequestPort
Tick read(PacketPtr pkt)
bool getRegArrayBit(ApicRegIndex base, uint8_t vector)
uint32_t regs[NUM_APIC_REGS]
Definition interrupts.hh:85
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 clearRegArrayBit(ApicRegIndex base, uint8_t vector)
void requestInterrupt(uint8_t vector, uint8_t deliveryMode, bool level)
PioPort< Interrupts > pioPort
ClockDomain & clockDomain
Definition interrupts.hh:82
void serialize(CheckpointOut &cp) const override
Serialize an object.
Tick write(PacketPtr pkt)
void setThreadContext(ThreadContext *_tc) override
IntResponsePort< Interrupts > intResponsePort
Fault getInterrupt() override
uint32_t readReg(ApicRegIndex miscReg)
void lowerInterruptPin(int number)
STL list class.
Definition stl.hh:51
AddrRange RangeEx(Addr start, Addr end)
AddrRange RangeSize(Addr start, Addr size)
std::list< AddrRange > AddrRangeList
Convenience typedef for a collection of address ranges.
Definition addr_range.hh:64
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
void schedule(Event &event, Tick when)
Definition eventq.hh:1012
void reschedule(Event &event, Tick when, bool always=false)
Definition eventq.hh:1030
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:220
#define hack_once(...)
Definition logging.hh:296
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:246
#define UNSERIALIZE_ARRAY(member, size)
Definition serialize.hh:618
#define SERIALIZE_ARRAY(member, size)
Definition serialize.hh:610
#define warn(...)
Definition logging.hh:288
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
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< 0 > p
Definition pagetable.hh:151
static ApicRegIndex APIC_INTERRUPT_REQUEST(int index)
Definition apic.hh:88
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 Arm Limited 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
Packet * PacketPtr
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 Mon May 26 2025 09:18:58 for gem5 by doxygen 1.13.2