Add runtime.time, drop demo drivers, harden TSC timekeeping
Time is a kernel concern in danos: the kernel owns the scheduling timer and already exposes monotonic time via the clock/sleep/timer_bind syscalls, so a userspace time service would be a redundant, slower path. This adds the generic runtime.time module over those syscalls, retires the two demonstration drivers, reorganizes the milestone docs, and makes the monotonic clock correct on Intel, AMD, and inside any VM. runtime.time (library/runtime/time.zig) - Instant/Duration interface: now, sleep, spin, after, monotonicNanos, available - a thin layer over system.clock/sleep/timerOnce; unit-tested arithmetic Remove the demo drivers hpet and bus (a teaching example belongs in the docs, not shipped in the tree) - system/drivers/ now holds only real drivers: pci-bus, ps2-bus, usb-xhci-bus - device-manager end-to-end test repointed to pci-bus (asserts on kernel state: the process table and the device tree, not a racy serial marker) - device_register containment moved to a new in-kernel `containment` test - the driver-model worked example moved inline into docs/drivers.md Reorganize milestone docs into topic docs - m17-m18 / m19-m20 / m21 plans dissolved into process-lifecycle, device-manager, discovery, and acpi docs; new docs/power.md and docs/timers.md; ~20 citations repointed; plan docs deleted TSC reliability (apic.zig, smp.zig, cpu.zig, kernel.zig) - check the invariant-TSC bit (CPUID 0x80000007 EDX[8]) on Intel and AMD - cross-core "warp" check at SMP bring-up, pairwise BSP<->AP as each core comes up - fall back to the HPET clocksource when the TSC is not invariant (a bare VM) or not synchronized (a warp), switched continuously so time never jumps - boot log reports the outcome; new tsc-sync test exercises the TSC + warp path Verified: zig build; zig build test; 60/60 QEMU cases (incl. new containment and tsc-sync).
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
//! /system/services/acpi — the ACPI discovery service: the x86 firmware
|
||||
//! interpreter, moved out of ring 0 (docs/m19-m20-plan.md, M20). Claims the
|
||||
//! interpreter, moved out of ring 0 (docs/discovery.md). Claims the
|
||||
//! `acpi-tables` node the kernel publishes (the AML blobs, the broad io_port
|
||||
//! grant, a broad irq window, the SCI), and runs the **shared AML module** in
|
||||
//! ring 3 — the same parser and interpreter the kernel uses.
|
||||
@@ -321,7 +321,7 @@ fn onSci() void {
|
||||
/// handler method (`_Lxx` level / `_Exx` edge), drain the Notify queue the
|
||||
/// method produced, and publish an event per notified device. Then clear the
|
||||
/// status bit. QEMU raises no GPEs on this config, so this path is exercised by
|
||||
/// host unit tests (docs/m21-plan.md decision 5); on real hardware it carries
|
||||
/// host unit tests (docs/acpi.md — ACPI events); on real hardware it carries
|
||||
/// battery/AC/lid. The embedded controller's `_Qxx` queries are out of scope.
|
||||
fn handleGpe() void {
|
||||
handleGpeBlock(gpe0_blk, gpe0_len, 0);
|
||||
@@ -476,7 +476,7 @@ fn walkDevices(node: *aml.Node, interpreter: *aml.Interpreter) void {
|
||||
|
||||
if (readHid(c, interpreter)) |hid| {
|
||||
// Skip PCI roots — pci-bus already reports PCI functions; ACPI adds
|
||||
// only the non-PCI _HID devices (docs/m19-m20-plan.md M20.2). The two
|
||||
// only the non-PCI _HID devices (docs/device-manager.md — matching). The two
|
||||
// roots are named through the shared registry, not bare _HID strings.
|
||||
const id = acpi_ids.HardwareId.fromHid(hid[0..7]);
|
||||
if (id != .pci_bus and id != .pci_express_root_bridge) {
|
||||
|
||||
@@ -31,17 +31,6 @@ fn writeLine(comptime fmt: []const u8, arguments: anytype) void {
|
||||
_ = runtime.system.write(std.fmt.bufPrint(&line, fmt, arguments) catch return);
|
||||
}
|
||||
|
||||
/// The driver that serves each device — the policy table. In a fuller system
|
||||
/// this comes from a manifest (docs/device-manager.md: the third bus type
|
||||
/// triggers it); for now a static map. `null` = no driver for this class yet.
|
||||
fn driverFor(d: device.DeviceDescriptor) ?[]const u8 {
|
||||
// The HPET timer node is still kernel-seeded (from the HPET table, not AML).
|
||||
// PS/2 and other _HID devices now arrive as acpi-service reports and match
|
||||
// in onChildAdded (M20.3), not from this boot snapshot.
|
||||
if (d.class == @intFromEnum(device.DeviceClass.timer)) return "hpet";
|
||||
return null;
|
||||
}
|
||||
|
||||
/// The PCI class/subclass/prog-IF triple of an xHCI (USB 3) host controller —
|
||||
/// Serial Bus Controller / USB Controller / XHCI — named from pci-class.zig rather
|
||||
/// than written as the bare 0x0C0330 (docs/coding-standards.md, "Named values").
|
||||
@@ -107,7 +96,7 @@ const Driver = struct {
|
||||
// The assigned device id (becomes argv[1]), or protocol.no_device.
|
||||
device_id: u64 = protocol.no_device,
|
||||
// Whether this driver speaks the protocol (hello expected, deadline
|
||||
// enforced). Legacy drivers (hpet, ps2-bus) are supervised and restarted
|
||||
// enforced). Legacy drivers (e.g. ps2-bus) are supervised and restarted
|
||||
// but not yet required to hello.
|
||||
speaks_protocol: bool = false,
|
||||
process_id: u32 = 0,
|
||||
@@ -346,19 +335,15 @@ fn initialise(endpoint: runtime.ipc.Handle) bool {
|
||||
addDriver("pci-bus", descriptor.id, true);
|
||||
continue;
|
||||
}
|
||||
// PCI functions no longer appear in the boot snapshot (M19.3): the
|
||||
// pci-bus driver reports them, and onChildAdded matches from reports.
|
||||
const driver_name = driverFor(descriptor) orelse continue;
|
||||
matched += 1;
|
||||
// Skip a singleton that is already alive (the initial-ramdisk sweep test
|
||||
// starts every bundled binary bare, this manager included) — spawning a
|
||||
// second instance would only lose the claim race and churn the log.
|
||||
if (!alreadySupervised(driver_name) and !system.isProcessRunning(driver_name)) {
|
||||
addDriver(driver_name, protocol.no_device, false);
|
||||
}
|
||||
// Nothing else is matched from the boot snapshot today. The kernel-seeded
|
||||
// HPET timer node is served by the kernel's own clock (docs/timers.md), not
|
||||
// a user-space driver; PCI functions and PS/2 _HID devices arrive later as
|
||||
// pci-bus / acpi-service reports and match in onChildAdded (docs/discovery.md).
|
||||
// A fuller system's static class->driver manifest (docs/device-manager.md)
|
||||
// would slot in here.
|
||||
}
|
||||
|
||||
// The discovery service (docs/m19-m20-plan.md M20): one per firmware, packed
|
||||
// The discovery service (docs/discovery.md): one per firmware, packed
|
||||
// under the neutral name "discovery", spawned once at startup. It finds and
|
||||
// claims the acpi-tables (or devicetree-blob) node itself. Not a per-device
|
||||
// match — it is the discoverer, not a driver bound to one device.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! /system/services/fdt — the devicetree discovery service: the ARM twin of the
|
||||
//! acpi service (docs/m19-m20-plan.md decision 7). **Placeholder: not
|
||||
//! acpi service (docs/discovery.md — firmware neutrality). **Placeholder: not
|
||||
//! implemented.** It exists so the build's `-Ddiscovery` option has both of its
|
||||
//! values from day one; the implementation lands with the Raspberry Pi
|
||||
//! bring-up (docs/arm.md).
|
||||
@@ -15,7 +15,7 @@
|
||||
//! resident under the manager's supervision (hello, restart, the usual
|
||||
//! contract).
|
||||
//!
|
||||
//! Known prerequisite recorded in the plan: `DeviceDescriptor`'s 8-byte `hid`
|
||||
//! Known prerequisite recorded in docs/discovery.md: `DeviceDescriptor`'s 8-byte `hid`
|
||||
//! cannot hold an FDT `compatible` string ("brcm,bcm2835-aux-uart") — identity
|
||||
//! widens before this file grows a body.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//! The power protocol (docs/m21-plan.md): system power's domain-named surface,
|
||||
//! The power protocol (docs/power.md): system power's domain-named surface,
|
||||
//! registered under `ServiceId.power`. On x86 the acpi service serves it; on
|
||||
//! ARM a PSCI/mailbox service will register the same id — subscribers never
|
||||
//! learn which firmware they are on (m19-m20-plan.md decision 7). The
|
||||
//! vfs-protocol pattern: extern-struct messages, a version, reserved fields.
|
||||
//! learn which firmware they are on (docs/discovery.md — firmware neutrality).
|
||||
//! The vfs-protocol pattern: extern-struct messages, a version, reserved fields.
|
||||
|
||||
/// The protocol version a client states nowhere yet — reserved for the day a
|
||||
/// handshake needs it; requests carry it so a mismatch can be refused loudly.
|
||||
|
||||
Reference in New Issue
Block a user