Files
MontaukOS/kernel/src/Timekeeping/ApicTimer.hpp
T

55 lines
2.0 KiB
C++

/*
* ApicTimer.hpp
* Local APIC timer for periodic tick interrupts and timekeeping
* Copyright (c) 2025 Daniel Hammer
*/
#pragma once
#include <cstdint>
namespace Timekeeping {
// Initialize the APIC timer: calibrate against PIT, start periodic interrupts
void ApicTimerInitialize();
// Initialize the scheduler timer on an AP using the BSP calibration.
void ApicTimerInitializeAP();
// Idle APs are woken for runnable work by the reschedule IPI, so their
// periodic scheduler timer can remain masked until a process is dispatched.
void ApicTimerEnterApIdle();
void ApicTimerLeaveApIdle();
// Reinitialize the APIC timer after S3 resume using the previously
// calibrated tick rate. Skips PIT calibration and IRQ registration
// (both survive in RAM). Only reprograms the timer hardware registers.
void ApicTimerReinitialize();
// Get the monotonic tick count (increments on each timer interrupt)
uint64_t GetTicks();
// Get elapsed milliseconds since timer initialization
uint64_t GetMilliseconds();
// Enable scheduler tick (called after scheduler is initialized)
void EnableSchedulerTick();
// Run bounded process-context bottom halves from an idle CPU.
void ServiceDeferredWork();
// Enter one idle wait cycle for the current CPU. Uses HLT and relies on
// the boot-time periodic LAPIC timer to wake -- one-shot wake doesn't
// survive deep C-states on some laptop CPUs.
void IdleOnce(bool hasMwait, volatile uint64_t* monitorAddr = nullptr);
// Busy-wait sleep for the given number of milliseconds
void Sleep(uint64_t ms);
// Spin for at least `ms` milliseconds without descheduling. Usable from
// boot code, before the scheduler runs, and with interrupts disabled
// (falls back to timed I/O port writes when the tick is not advancing).
void BusyWaitMs(uint64_t ms);
// Spin for at least `us` microseconds. Port-0x80 timed, so it errs long.
void BusyWaitUs(uint64_t us);
};