58 #include "debug/LocalApic.hh"
72 int shift = ((conf & 0x8) >> 1) | (conf & 0x3);
182 panic(
"Accessed reserved register field %#x.\n", paddr);
195 panic(
"Accessed more than one register at a time in the APIC!\n");
199 "Reading Local APIC register %d at offset %#x as %#x.\n",
212 panic(
"Accessed more than one register at a time in the APIC!\n");
217 "Writing Local APIC register %d at offset %#x as %#x.\n",
234 DPRINTF(LocalApic,
"Interrupt is an %s.\n",
248 DPRINTF(LocalApic,
"Interrupt is an %s.\n",
251 pendingUnmaskableInt = pendingSmi =
true;
253 }
else if (
deliveryMode == DeliveryMode::NMI && !pendingNmi) {
254 pendingUnmaskableInt = pendingNmi =
true;
256 }
else if (
deliveryMode == DeliveryMode::ExtInt && !pendingExtInt) {
257 pendingExtInt =
true;
259 }
else if (
deliveryMode == DeliveryMode::INIT && !pendingInit) {
260 pendingUnmaskableInt = pendingInit =
true;
263 !pendingStartup && !startedUp) {
264 pendingUnmaskableInt = pendingStartup =
true;
269 tc->getCpuPtr()->wakeup(0);
278 "Local APICs can't be moved between CPUs with different IDs.");
282 initialApicId = tc->cpuId();
283 regs[
APIC_ID] = (initialApicId << 24);
291 panic_if(!intRequestPort.isConnected(),
292 "Int port not connected to anything!");
294 "Pio port of %s not connected to anything!",
name());
296 intResponsePort.sendRangeChange();
297 pioPort.sendRangeChange();
310 TriggerIntMessage message = pkt->
getRaw<TriggerIntMessage>();
312 "Got Trigger Interrupt message with vector %#x.\n",
315 requestInterrupt(message.vector,
316 message.deliveryMode, message.trigger);
320 panic(
"Local apic got unknown interrupt message at offset %#x.\n",
332 if (--pendingIPIs == 0) {
335 low.deliveryStatus = 0;
338 DPRINTF(LocalApic,
"ICR is now idle.\n");
369 panic(
"Local APIC Trigger Mode registers are unimplemented.\n");
373 panic(
"Local APIC Arbitration Priority register unimplemented.\n");
376 panic(
"Local APIC Processor Priority register unimplemented.\n");
383 if (apicTimerEvent.scheduled()) {
385 uint64_t ticksPerCount = clockPeriod() *
388 uint64_t
val = apicTimerEvent.when() -
curTick();
390 val = (
val + ticksPerCount - 1) / ticksPerCount;
405 uint32_t newVal =
val;
408 panic(
"Local APIC In-Service registers are unimplemented.\n");
412 panic(
"Local APIC Trigger Mode registers are unimplemented.\n");
416 panic(
"Local APIC Interrupt Request registers "
417 "are unimplemented.\n");
430 panic(
"Local APIC Arbitration Priority register unimplemented.\n");
433 panic(
"Local APIC Processor Priority register unimplemented.\n");
441 newVal =
val & 0xFF000000;
444 newVal =
val | 0x0FFFFFFF;
450 warn(
"Focus processor checking not implemented.\n");
468 if (low.deliveryStatus) {
474 TriggerIntMessage message = 0;
475 message.destination = high.destination;
476 message.vector = low.vector;
477 message.deliveryMode = low.deliveryMode;
478 message.destMode = low.destMode;
479 message.level = low.level;
480 message.trigger = low.trigger;
482 int numContexts = sys->threads.size();
483 switch (low.destShorthand) {
485 if (message.deliveryMode == DeliveryMode::LowestPriority) {
486 panic(
"Lowest priority delivery mode "
487 "IPIs aren't implemented.\n");
489 if (message.destMode == 1) {
490 int dest = message.destination;
491 hack_once(
"Assuming logical destinations are 1 << id.\n");
492 for (
int i = 0;
i < numContexts;
i++) {
498 if (message.destination == 0xFF) {
499 for (
int i = 0;
i < numContexts;
i++) {
500 if (
i == initialApicId) {
501 requestInterrupt(message.vector,
502 message.deliveryMode, message.trigger);
508 if (message.destination == initialApicId) {
509 requestInterrupt(message.vector,
510 message.deliveryMode, message.trigger);
512 apics.push_back(message.destination);
519 requestInterrupt(message.vector,
520 message.deliveryMode, message.trigger);
523 requestInterrupt(message.vector,
524 message.deliveryMode, message.trigger);
528 for (
int i = 0;
i < numContexts;
i++) {
529 if (
i != initialApicId) {
538 low.deliveryStatus = 1;
539 pendingIPIs += apics.size();
542 for (
auto id: apics) {
544 intRequestPort.sendMessage(pkt, sys->isTimingMode(),
545 [
this](
PacketPtr pkt) { completeIPI(pkt); });
557 uint64_t readOnlyMask = (1 << 12) | (1 << 14);
558 newVal = (
val & ~readOnlyMask) |
559 (regs[
reg] & readOnlyMask);
566 uint64_t newCount = newVal *
571 reschedule(apicTimerEvent,
573 clockPeriod() -
offset,
true);
576 reschedule(apicTimerEvent,
578 clockPeriod(),
true);
599 pendingSmi(
false), smiVector(0),
600 pendingNmi(
false), nmiVector(0),
601 pendingExtInt(
false), extIntVector(0),
602 pendingInit(
false), initVector(0),
603 pendingStartup(
false), startupVector(0),
604 startedUp(
false), pendingUnmaskableInt(
false),
606 intResponsePort(
name() +
".int_responder",
this,
this),
607 intRequestPort(
name() +
".int_requestor",
this,
this,
p->int_latency),
608 pioPort(
this), pioDelay(
p->pio_latency)
610 memset(regs, 0,
sizeof(regs));
624 if (pendingUnmaskableInt) {
625 DPRINTF(LocalApic,
"Reported pending unmaskable interrupt.\n");
630 DPRINTF(LocalApic,
"Reported pending external interrupt.\n");
633 if (IRRV > ISRV &&
bits(IRRV, 7, 4) >
635 DPRINTF(LocalApic,
"Reported pending regular interrupt.\n");
645 return pendingUnmaskableInt || pendingExtInt ||
646 (IRRV > ISRV &&
bits(IRRV, 7, 4) >
653 assert(checkInterrupts());
656 if (pendingUnmaskableInt) {
658 DPRINTF(LocalApic,
"Generated SMI fault object.\n");
659 return std::make_shared<SystemManagementInterrupt>();
660 }
else if (pendingNmi) {
661 DPRINTF(LocalApic,
"Generated NMI fault object.\n");
662 return std::make_shared<NonMaskableInterrupt>(nmiVector);
663 }
else if (pendingInit) {
664 DPRINTF(LocalApic,
"Generated INIT fault object.\n");
665 return std::make_shared<InitInterrupt>(initVector);
666 }
else if (pendingStartup) {
667 DPRINTF(LocalApic,
"Generating SIPI fault object.\n");
668 return std::make_shared<StartupInterrupt>(startupVector);
670 panic(
"pendingUnmaskableInt set, but no unmaskable "
671 "ints were pending.\n");
674 }
else if (pendingExtInt) {
675 DPRINTF(LocalApic,
"Generated external interrupt fault object.\n");
676 return std::make_shared<ExternalInterrupt>(extIntVector);
678 DPRINTF(LocalApic,
"Generated regular interrupt fault object.\n");
680 return std::make_shared<ExternalInterrupt>(IRRV);
687 assert(checkInterrupts());
688 if (pendingUnmaskableInt) {
690 DPRINTF(LocalApic,
"SMI sent to core.\n");
692 }
else if (pendingNmi) {
693 DPRINTF(LocalApic,
"NMI sent to core.\n");
695 }
else if (pendingInit) {
696 DPRINTF(LocalApic,
"Init sent to core.\n");
699 }
else if (pendingStartup) {
700 DPRINTF(LocalApic,
"SIPI sent to core.\n");
701 pendingStartup =
false;
704 if (!(pendingSmi || pendingNmi || pendingInit || pendingStartup))
705 pendingUnmaskableInt =
false;
706 }
else if (pendingExtInt) {
707 pendingExtInt =
false;
709 DPRINTF(LocalApic,
"Interrupt %d sent to core.\n", IRRV);
738 bool apicTimerEventScheduled = apicTimerEvent.scheduled();
740 Tick apicTimerEventTick = apicTimerEvent.when();
763 bool apicTimerEventScheduled;
765 if (apicTimerEventScheduled) {
766 Tick apicTimerEventTick;
768 if (apicTimerEvent.scheduled()) {
769 reschedule(apicTimerEvent, apicTimerEventTick,
true);
771 schedule(apicTimerEvent, apicTimerEventTick);
777 X86LocalApicParams::create()
784 if (triggerTimerInterrupt())