20#ifndef KERNEL_MACHINE_X86_COMMON_LOCAL_APIC_H
21#define KERNEL_MACHINE_X86_COMMON_LOCAL_APIC_H
26#include "pedigree/kernel/Atomic.h"
27#include "pedigree/kernel/compiler.h"
28#include "pedigree/kernel/machine/SchedulerTimer.h"
29#include "pedigree/kernel/processor/InterruptHandler.h"
30#include "pedigree/kernel/processor/MemoryMappedIo.h"
31#include "pedigree/kernel/processor/Processor.h"
32#include "pedigree/kernel/processor/ProcessorInformation.h"
33#include "pedigree/kernel/processor/state_forward.h"
34#include "pedigree/kernel/processor/types.h"
36#include "LocalApicTimerHandlerSlots.h"
37#include "LocalApicTlbShootdown.h"
41#define IPI_TLB_SHOOTDOWN_VECTOR 0xF9
42#define IPI_RESCHEDULE_VECTOR 0xFA
43#define IPI_PROCESSOR_CONTROL_VECTOR 0xFB
44#define ERROR_VECTOR 0xFC
45#define SPURIOUS_VECTOR 0xFD
46#define TIMER_VECTOR 0xFE
55 enum class ProcessorControlState :
size_t { Idle, Paused, Unavailable, Terminal };
56 enum class ProcessorControlOwnership { Fresh, Quiesced, Failed, Terminal };
61 : m_IoSpace(
"Local APIC"),
67 m_ProcessorControlOwner(),
69 m_TlbTerminalFailure(),
71 m_ProcessorControlState(static_cast<size_t>(ProcessorControlState::Idle)),
72 m_ControlledProcessorCount(0),
73 m_TerminalProcessorCount(0),
74 m_TerminalProcessorMask(0) {}
76 inline virtual ~LocalApic() {}
94 deliveryModeFixed = 0,
95 deliveryModeLowestPriority = 1,
99 deliveryModeStartup = 6,
100 deliveryModeExtInt = 7
109 MUST_USE_RESULT bool interProcessorInterrupt(uint8_t destinationApicId, uint8_t vector,
110 size_t deliveryMode,
bool bAssert,
111 bool bLevelTriggered);
117 MUST_USE_RESULT bool interProcessorInterruptAllExcludingThis(uint8_t vector,
size_t deliveryMode);
125 uint64_t processors = ~uint64_t(0));
131 void endTlbInvalidation();
137 bool tlbInvalidationFailureActive()
const;
138 bool tlbInvalidationTerminal()
const;
141 void servicePendingTlbShootdown();
144 void servicePendingTerminalProcessorControl();
146 enum class ProcessorControlResult {
150 AcknowledgementTimedOut,
155 MUST_USE_RESULT ProcessorControlResult quiesceAllOtherProcessors(
size_t expectedProcessors);
162 MUST_USE_RESULT ProcessorControlResult haltAllOtherProcessors(
size_t expectedProcessors);
171 uint64_t nominalQuantumNs()
const override;
175 bool armDeadline(uint64_t absoluteMonotonicNs)
override;
181 return m_Handlers.registerHandler(getId(), handler);
193 LocalApic(
const LocalApic&);
205 bool waitForIcrIdle();
206 bool submitIcr(uint32_t high, uint32_t low);
207 uint32_t readRegister(uint32_t offset);
208 void writeRegister(uint32_t value, uint32_t offset);
210 ProcessorControlState processorControlState()
const;
211 bool acquireProcessorControlOwner(
bool acceptRetained, ProcessorControlOwnership& ownership);
212 bool releaseProcessorControlOwner();
213 ProcessorControlResult completeTerminalControl(
size_t expectedProcessors);
214 ProcessorControlResult retainTerminalControl(ProcessorControlResult result);
215 bool acquireTlbShootdownBarrier();
216 bool releaseTlbShootdownBarrier();
217 bool adoptTerminalTlbShootdownBarrier();
218 bool waitForTlbMutationDrain();
219 bool waitForProcessorCount(
size_t expectedProcessors);
220 bool waitForTerminalProcessorCount(
size_t expectedProcessors);
221 bool waitForProcessorDrain();
222 ProcessorControlResult retainFailedControl(ProcessorControlResult result);
223 ProcessorControlResult releaseProcessorControlOrRetainFailure(ProcessorControlResult released,
224 ProcessorControlResult retained);
225 ProcessorControlResult retainQuiescedControl(ProcessorControlResult result);
226 ProcessorControlResult finishFailedQuiesce(ProcessorControlResult result);
227 ProcessorControlResult unwindQuiesce(ProcessorControlResult failure);
228 bool markTerminalProcessor(
size_t processor);
229 void enterTerminalProcessorControl()
NORETURN;
234 virtual
void interrupt(
size_t nInterruptNumber, InterruptState& state);
238 uint64_t m_PhysicalAddress;
245 size_t m_BusFrequency;
248 uint64_t lastInterruptNs;
250 uint64_t armedDeadlineNs;
252 TimerState m_TimerState[LocalApicTimerHandlerSlots::Capacity];
Abstract base class for interrupt-handlers.
SchedulerTimer & operator=(const SchedulerTimer &)
static bool canRemoveHandlerInCurrentContext()
virtual bool armDeadline(uint64_t)
virtual bool registerHandler(SchedulerTimerHandler *handler)=0
virtual bool removeHandler(SchedulerTimerHandler *handler)=0
virtual bool supportsOneShot() const
#define INITIALISATION_ONLY
uintptr_t physicalAddress(physical_uintptr_t address) PURE