9#define IA32_APIC_BASE_MSR 0x1BULL
10#define APIC_BASE_RESERVED 0xFFF0000000000000ULL
12#define LAPIC_PAGE_SIZE 0x1000
13#define LAPIC_MAP_FLAGS (PAGE_PRESENT | PAGE_RW | PAGE_PCD)
52static void lapic_wait_icr(
void) {
62 uint32_t vector = 0xFF;
63 svr = (svr & 0xFFFFFF00) | vector;
67static void map_lapic(uint64_t lapicPhysicalAddr) {
83static inline uint64_t get_lapic_base_address(
void) {
90 uint64_t msr_value = ((uint64_t)edx << 32) | eax;
94 return msr_value & ~0xFFFULL;
100 if (!(apic_msr & (1ULL << 11))) {
102 apic_msr |= (1ULL << 11);
105 map_lapic(get_lapic_base_address());
108 uint32_t svr = (0xFF) | (1 << 8);
114 map_lapic(get_lapic_base_address());
130 uint32_t high = ((uint32_t)apic_id) << 24;
149#define APIC_LVT_TIMER_PERIODIC (1U << 17)
150#define APIC_TIMER_MASKED (1U << 16)
152static uint32_t calibrate_lapic_ticks_per_10ms(
void) {
156 const uint32_t start = 0xFFFFFFFFU;
162 uint32_t ticks = start - curr;
163 if (ticks == 0)
return 0;
168static uint32_t g_apic_ticks_per_10ms = 0;
173 if (g_apic_ticks_per_10ms == 0) {
174 g_apic_ticks_per_10ms = calibrate_lapic_ticks_per_10ms();
180 if (hz == 0)
return -1;
183 if (g_apic_ticks_per_10ms == 0) {
188 uint32_t period_ms = 1000 / hz;
189 uint64_t initial = ((uint64_t)g_apic_ticks_per_10ms * (uint64_t)period_ms) / 10ULL;
190 if (initial == 0) initial = 1;
void lapic_timer_calibrate(void)
void lapic_mmio_write(uint32_t off, uint32_t val)
int init_lapic_timer(uint32_t hz)
#define IA32_APIC_BASE_MSR
void lapic_send_ipi(uint8_t apic_id, uint8_t vector, uint32_t flags)
void MhRequestSoftwareInterrupt(IN IRQL RequestIrql)
void lapic_init_siv(void)
void lapic_init_cpu(void)
uint32_t lapic_mmio_read(uint32_t off)
#define APIC_LVT_TIMER_PERIODIC
NORETURN void MeBugCheckEx(IN enum _BUGCHECK_CODES BugCheckCode, IN void *BugCheckParameter1, IN void *BugCheckParameter2, IN void *BugCheckParameter3, IN void *BugCheckParameter4)
FORCEINLINE uint64_t __readmsr(uint32_t msr)
FORCEINLINE void __writemsr(uint32_t msr, uint64_t value)
FORCEINLINE void __pause(void)
bool MeDisableInterrupts(void)
void MeEnableInterrupts(IN bool EnabledBefore)
PMMPTE MiGetPtePointer(IN uintptr_t va)
@ INVALID_INTERRUPT_REQUEST
FORCEINLINE PPROCESSOR MeGetCurrentProcessor(void)
#define PhysicalMemoryOffset
#define MI_WRITE_PTE(_PtePointer, _Va, _Pa, _Flags)
void pit_sleep_ms(uint32_t ms)
volatile bool DpcInterruptRequested
uintptr_t LapicAddressPhys
volatile uint32_t * LapicAddressVirt
volatile bool ApcInterruptRequested