refactor kernel to use device platform discovery

This commit is contained in:
Daniel Samson
2026-07-08 10:06:46 +01:00
parent 2ee898a91e
commit 7d3417fe86
9 changed files with 572 additions and 43 deletions
+19 -7
View File
@@ -41,12 +41,24 @@ its own, forever.
The reload count isn't picked arbitrarily — it's **calibrated to real time**,
which the [real-time](vision.md) scheduling guarantees depend on. Since the LAPIC
timer's raw rate is bus-clock dependent and unknown up front, `calibrate` measures
it against the **PIT** (the legacy 8254, whose 1.193182 MHz is fixed): run the
LAPIC timer one-shot from its maximum count while the PIT counts out a known 10 ms
(polling channel 2, no interrupt needed), then see how far the LAPIC got. That
yields its counts-per-millisecond, from which `initTimer(hz)` computes the reload
count for any target frequency. danos runs it at **1000 Hz** (a 1 ms tick).
timer's raw rate is bus-clock dependent and unknown up front, `calibrate` runs the
LAPIC timer one-shot from its maximum count while a **reference clock** counts out a
known 10 ms, then sees how far the LAPIC got — its counts-per-millisecond, from which
`initTimer(hz)` computes the reload count for any target frequency. danos runs it at
**1000 Hz** (a 1 ms tick).
The reference clock is chosen in order of preference, so danos calibrates on
legacy-free **UEFI Class 3** hardware where the old 8254 PIT may be *absent* (polling
a missing PIT would hang the boot):
1. **CPUID leaf 0x15** — the CPU's TSC frequency directly, needing no external timer
at all (the LAPIC is then measured against the TSC).
2. The **HPET**, discovered via ACPI (see [discovery](discovery.md) / [acpi](acpi.md)).
3. The **ACPI PM timer** (a fixed 3.579545 MHz counter from the FADT).
4. The **PIT** (legacy 8254, 1.193182 MHz) — last resort, and bounded so it can't hang.
All four yield the same rate; on QEMU (no CPUID crystal enumeration) it lands on the
HPET, matching the PIT numbers to within measurement jitter.
## The high-resolution clock (TSC)
@@ -55,7 +67,7 @@ real-time system to *measure* with (interrupt latency, jitter, timeouts). So the
same calibration also measures the **TSC** (Time Stamp Counter): a per-core cycle
counter read with `rdtsc` in a couple of cycles, giving roughly **nanosecond**
resolution — a million times finer than the tick. We snapshot the TSC across the
same 10 ms PIT window to get its frequency (measured ~3.6 GHz on the test host).
same 10 ms calibration window to get its frequency (measured ~1 GHz under QEMU).
The monotonic clock is exposed as one function per resolution — `nanos()`,
`micros()`, `millis()` — each scaling the cycle delta directly at its unit (with a