59 #include "debug/LocalApic.hh"
76 int shift = ((conf & 0x8) >> 1) | (conf & 0x3);
186 panic(
"Accessed reserved register field %#x.\n", paddr);
199 panic(
"Accessed more than one register at a time in the APIC!\n");
203 "Reading Local APIC register %d at offset %#x as %#x.\n",
216 panic(
"Accessed more than one register at a time in the APIC!\n");
221 "Writing Local APIC register %d at offset %#x as %#x.\n",
238 DPRINTF(LocalApic,
"Interrupt is an %s.\n",
252 DPRINTF(LocalApic,
"Interrupt is an %s.\n",
254 if (
deliveryMode == delivery_mode::SMI && !pendingSmi) {
255 pendingUnmaskableInt = pendingSmi =
true;
257 }
else if (
deliveryMode == delivery_mode::NMI && !pendingNmi) {
258 pendingUnmaskableInt = pendingNmi =
true;
260 }
else if (
deliveryMode == delivery_mode::ExtInt && !pendingExtInt) {
261 pendingExtInt =
true;
263 }
else if (
deliveryMode == delivery_mode::INIT && !pendingInit) {
264 pendingUnmaskableInt = pendingInit =
true;
267 !pendingStartup && !startedUp) {
268 pendingUnmaskableInt = pendingStartup =
true;
273 tc->getCpuPtr()->wakeup(0);
281 "Asked to raise unrecognized int pin %d.", number);
282 DPRINTF(LocalApic,
"Raised wired interrupt pin LINT%d.\n", number);
284 const LVTEntry entry =
288 DPRINTF(LocalApic,
"The interrupt was masked.\n");
293 auto on_completion = [
this,
dm=entry.deliveryMode,
trigger=entry.trigger](
298 intRequestPort.sendMessage(pkt, sys->isTimingMode(), on_completion);
306 "Asked to lower unrecognized int pin %d.", number);
307 DPRINTF(LocalApic,
"Lowered wired interrupt pin LINT%d.\n", number);
316 "Local APICs can't be moved between CPUs with different IDs.");
321 initialApicId = tc->contextId();
322 regs[
APIC_ID] = (initialApicId << 24);
330 panic_if(!intRequestPort.isConnected(),
331 "Int port not connected to anything!");
333 "Pio port of %s not connected to anything!",
name());
335 intResponsePort.sendRangeChange();
336 pioPort.sendRangeChange();
349 TriggerIntMessage message = pkt->
getRaw<TriggerIntMessage>();
351 "Got Trigger Interrupt message with vector %#x.\n",
354 requestInterrupt(message.vector,
355 message.deliveryMode, message.trigger);
359 panic(
"Local apic got unknown interrupt message at offset %#x.\n",
371 if (--pendingIPIs == 0) {
374 low.deliveryStatus = 0;
377 DPRINTF(LocalApic,
"ICR is now idle.\n");
408 panic(
"Local APIC Trigger Mode registers are unimplemented.\n");
412 panic(
"Local APIC Arbitration Priority register unimplemented.\n");
415 panic(
"Local APIC Processor Priority register unimplemented.\n");
422 if (apicTimerEvent.scheduled()) {
424 uint64_t ticksPerCount = clockPeriod() *
427 uint64_t
val = apicTimerEvent.when() -
curTick();
429 val = (
val + ticksPerCount - 1) / ticksPerCount;
444 uint32_t newVal =
val;
447 panic(
"Local APIC In-Service registers are unimplemented.\n");
451 panic(
"Local APIC Trigger Mode registers are unimplemented.\n");
455 panic(
"Local APIC Interrupt Request registers "
456 "are unimplemented.\n");
469 panic(
"Local APIC Arbitration Priority register unimplemented.\n");
472 panic(
"Local APIC Processor Priority register unimplemented.\n");
480 newVal =
val & 0xFF000000;
483 newVal =
val | 0x0FFFFFFF;
489 warn(
"Focus processor checking not implemented.\n");
507 if (low.deliveryStatus) {
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;
521 int numContexts = sys->threads.size();
522 switch (low.destShorthand) {
524 if (message.deliveryMode == delivery_mode::LowestPriority) {
525 panic(
"Lowest priority delivery mode "
526 "IPIs aren't implemented.\n");
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++) {
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);
547 if (message.destination == initialApicId) {
548 requestInterrupt(message.vector,
549 message.deliveryMode, message.trigger);
551 apics.push_back(message.destination);
558 requestInterrupt(message.vector,
559 message.deliveryMode, message.trigger);
562 requestInterrupt(message.vector,
563 message.deliveryMode, message.trigger);
567 for (
int i = 0;
i < numContexts;
i++) {
568 if (
i != initialApicId) {
577 low.deliveryStatus = 1;
578 pendingIPIs += apics.size();
581 for (
auto id: apics) {
583 intRequestPort.sendMessage(pkt, sys->isTimingMode(),
584 [
this](
PacketPtr pkt) { completeIPI(pkt); });
596 uint64_t readOnlyMask = (1 << 12) | (1 << 14);
597 newVal = (
val & ~readOnlyMask) |
598 (regs[
reg] & readOnlyMask);
605 uint64_t newCount = newVal *
610 reschedule(apicTimerEvent,
612 clockPeriod() -
offset,
true);
615 reschedule(apicTimerEvent,
617 clockPeriod(),
true);
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)
644 memset(regs, 0,
sizeof(regs));
669 if (pendingUnmaskableInt) {
670 DPRINTF(LocalApic,
"Reported pending unmaskable interrupt.\n");
675 DPRINTF(LocalApic,
"Reported pending external interrupt.\n");
678 if (IRRV > ISRV &&
bits(IRRV, 7, 4) >
680 DPRINTF(LocalApic,
"Reported pending regular interrupt.\n");
690 return pendingUnmaskableInt || pendingExtInt ||
691 (IRRV > ISRV &&
bits(IRRV, 7, 4) >
698 assert(checkInterrupts());
701 if (pendingUnmaskableInt) {
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);
715 panic(
"pendingUnmaskableInt set, but no unmaskable "
716 "ints were pending.\n");
719 }
else if (pendingExtInt) {
720 DPRINTF(LocalApic,
"Generated external interrupt fault object.\n");
721 return std::make_shared<ExternalInterrupt>(extIntVector);
723 DPRINTF(LocalApic,
"Generated regular interrupt fault object.\n");
725 return std::make_shared<ExternalInterrupt>(IRRV);
732 assert(checkInterrupts());
733 if (pendingUnmaskableInt) {
735 DPRINTF(LocalApic,
"SMI sent to core.\n");
737 }
else if (pendingNmi) {
738 DPRINTF(LocalApic,
"NMI sent to core.\n");
740 }
else if (pendingInit) {
741 DPRINTF(LocalApic,
"Init sent to core.\n");
744 }
else if (pendingStartup) {
745 DPRINTF(LocalApic,
"SIPI sent to core.\n");
746 pendingStartup =
false;
749 if (!(pendingSmi || pendingNmi || pendingInit || pendingStartup))
750 pendingUnmaskableInt =
false;
751 }
else if (pendingExtInt) {
752 pendingExtInt =
false;
754 DPRINTF(LocalApic,
"Interrupt %d sent to core.\n", IRRV);
783 bool apicTimerEventScheduled = apicTimerEvent.scheduled();
785 Tick apicTimerEventTick = apicTimerEvent.when();
808 bool apicTimerEventScheduled;
810 if (apicTimerEventScheduled) {
811 Tick apicTimerEventTick;
813 if (apicTimerEvent.scheduled()) {
814 reschedule(apicTimerEvent, apicTimerEventTick,
true);
816 schedule(apicTimerEvent, apicTimerEventTick);
824 if (triggerTimerInterrupt())