58 #include "debug/LocalApic.hh"
75 int shift = ((conf & 0x8) >> 1) | (conf & 0x3);
185 panic(
"Accessed reserved register field %#x.\n", paddr);
198 panic(
"Accessed more than one register at a time in the APIC!\n");
202 "Reading Local APIC register %d at offset %#x as %#x.\n",
215 panic(
"Accessed more than one register at a time in the APIC!\n");
220 "Writing Local APIC register %d at offset %#x as %#x.\n",
237 DPRINTF(LocalApic,
"Interrupt is an %s.\n",
251 DPRINTF(LocalApic,
"Interrupt is an %s.\n",
254 pendingUnmaskableInt = pendingSmi =
true;
257 pendingUnmaskableInt = pendingNmi =
true;
260 pendingExtInt =
true;
263 pendingUnmaskableInt = pendingInit =
true;
266 !pendingStartup && !startedUp) {
267 pendingUnmaskableInt = pendingStartup =
true;
272 tc->getCpuPtr()->wakeup(0);
281 "Local APICs can't be moved between CPUs with different IDs.");
285 initialApicId = tc->cpuId();
286 regs[
APIC_ID] = (initialApicId << 24);
294 panic_if(!intRequestPort.isConnected(),
295 "Int port not connected to anything!");
297 "Pio port of %s not connected to anything!",
name());
299 intResponsePort.sendRangeChange();
300 pioPort.sendRangeChange();
313 TriggerIntMessage message = pkt->
getRaw<TriggerIntMessage>();
315 "Got Trigger Interrupt message with vector %#x.\n",
318 requestInterrupt(message.vector,
319 message.deliveryMode, message.trigger);
323 panic(
"Local apic got unknown interrupt message at offset %#x.\n",
335 if (--pendingIPIs == 0) {
338 low.deliveryStatus = 0;
341 DPRINTF(LocalApic,
"ICR is now idle.\n");
372 panic(
"Local APIC Trigger Mode registers are unimplemented.\n");
376 panic(
"Local APIC Arbitration Priority register unimplemented.\n");
379 panic(
"Local APIC Processor Priority register unimplemented.\n");
386 if (apicTimerEvent.scheduled()) {
388 uint64_t ticksPerCount = clockPeriod() *
391 uint64_t
val = apicTimerEvent.when() -
curTick();
393 val = (
val + ticksPerCount - 1) / ticksPerCount;
408 uint32_t newVal =
val;
411 panic(
"Local APIC In-Service registers are unimplemented.\n");
415 panic(
"Local APIC Trigger Mode registers are unimplemented.\n");
419 panic(
"Local APIC Interrupt Request registers "
420 "are unimplemented.\n");
433 panic(
"Local APIC Arbitration Priority register unimplemented.\n");
436 panic(
"Local APIC Processor Priority register unimplemented.\n");
444 newVal =
val & 0xFF000000;
447 newVal =
val | 0x0FFFFFFF;
453 warn(
"Focus processor checking not implemented.\n");
471 if (low.deliveryStatus) {
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;
485 int numContexts = sys->threads.size();
486 switch (low.destShorthand) {
489 panic(
"Lowest priority delivery mode "
490 "IPIs aren't implemented.\n");
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++) {
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);
511 if (message.destination == initialApicId) {
512 requestInterrupt(message.vector,
513 message.deliveryMode, message.trigger);
515 apics.push_back(message.destination);
522 requestInterrupt(message.vector,
523 message.deliveryMode, message.trigger);
526 requestInterrupt(message.vector,
527 message.deliveryMode, message.trigger);
531 for (
int i = 0;
i < numContexts;
i++) {
532 if (
i != initialApicId) {
541 low.deliveryStatus = 1;
542 pendingIPIs += apics.size();
545 for (
auto id: apics) {
547 intRequestPort.sendMessage(pkt, sys->isTimingMode(),
548 [
this](
PacketPtr pkt) { completeIPI(pkt); });
560 uint64_t readOnlyMask = (1 << 12) | (1 << 14);
561 newVal = (
val & ~readOnlyMask) |
562 (regs[
reg] & readOnlyMask);
569 uint64_t newCount = newVal *
574 reschedule(apicTimerEvent,
576 clockPeriod() -
offset,
true);
579 reschedule(apicTimerEvent,
581 clockPeriod(),
true);
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),
609 intResponsePort(
name() +
".int_responder",
this,
this),
610 intRequestPort(
name() +
".int_requestor",
this,
this,
p.int_latency),
611 pioPort(
this), pioDelay(
p.pio_latency)
613 memset(regs, 0,
sizeof(regs));
627 if (pendingUnmaskableInt) {
628 DPRINTF(LocalApic,
"Reported pending unmaskable interrupt.\n");
633 DPRINTF(LocalApic,
"Reported pending external interrupt.\n");
636 if (IRRV > ISRV &&
bits(IRRV, 7, 4) >
638 DPRINTF(LocalApic,
"Reported pending regular interrupt.\n");
648 return pendingUnmaskableInt || pendingExtInt ||
649 (IRRV > ISRV &&
bits(IRRV, 7, 4) >
656 assert(checkInterrupts());
659 if (pendingUnmaskableInt) {
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);
673 panic(
"pendingUnmaskableInt set, but no unmaskable "
674 "ints were pending.\n");
677 }
else if (pendingExtInt) {
678 DPRINTF(LocalApic,
"Generated external interrupt fault object.\n");
679 return std::make_shared<ExternalInterrupt>(extIntVector);
681 DPRINTF(LocalApic,
"Generated regular interrupt fault object.\n");
683 return std::make_shared<ExternalInterrupt>(IRRV);
690 assert(checkInterrupts());
691 if (pendingUnmaskableInt) {
693 DPRINTF(LocalApic,
"SMI sent to core.\n");
695 }
else if (pendingNmi) {
696 DPRINTF(LocalApic,
"NMI sent to core.\n");
698 }
else if (pendingInit) {
699 DPRINTF(LocalApic,
"Init sent to core.\n");
702 }
else if (pendingStartup) {
703 DPRINTF(LocalApic,
"SIPI sent to core.\n");
704 pendingStartup =
false;
707 if (!(pendingSmi || pendingNmi || pendingInit || pendingStartup))
708 pendingUnmaskableInt =
false;
709 }
else if (pendingExtInt) {
710 pendingExtInt =
false;
712 DPRINTF(LocalApic,
"Interrupt %d sent to core.\n", IRRV);
741 bool apicTimerEventScheduled = apicTimerEvent.scheduled();
743 Tick apicTimerEventTick = apicTimerEvent.when();
766 bool apicTimerEventScheduled;
768 if (apicTimerEventScheduled) {
769 Tick apicTimerEventTick;
771 if (apicTimerEvent.scheduled()) {
772 reschedule(apicTimerEvent, apicTimerEventTick,
true);
774 schedule(apicTimerEvent, apicTimerEventTick);
782 if (triggerTimerInterrupt())