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
+48 -1
View File
@@ -131,6 +131,53 @@ fn kmain(boot_info: *const BootInfo) noreturn {
// AML namespace parse integrity: consumed should equal total.
const am = platform.amlStats();
serial0.debugPrint(" aml : {d} namespace nodes, parsed {d}/{d} bytes\n", .{ am.nodes, am.consumed, am.total });
// Feed the arch layer the discovered addresses/facts so it makes no legacy
// assumptions — the point of all this on UEFI Class 3 firmware. MMIO bases
// (HPET, I/O APIC) come from the device tree; scalar facts from ACPI.
const pinfo = platform.platformInfo();
const hpet_base: u64 = if (dt.firstOfClass(.timer)) |t|
(if (t.firstResource(.memory)) |r| r.start else 0)
else
0;
var ioapic_base: u64 = 0;
var ioapic_gsi: u32 = 0;
if (dt.firstOfClass(.interrupt_controller)) |ic| {
if (ic.firstResource(.memory)) |r| ioapic_base = r.start;
if (ic.firstResource(.irq)) |r| ioapic_gsi = @intCast(r.start);
}
var isos: [16]arch.IsoEntry = undefined;
const iso_n = @min(pinfo.override_count, isos.len);
for (0..iso_n) |i| isos[i] = .{
.source = pinfo.overrides[i].source,
.gsi = pinfo.overrides[i].gsi,
.flags = pinfo.overrides[i].flags,
};
const pm_timer: ?arch.PmTimer = if (pinfo.pm_timer.present())
.{ .mmio = pinfo.pm_timer.mmio, .address = pinfo.pm_timer.address, .is_32bit = pinfo.pm_timer_32bit }
else
null;
arch.configurePlatform(.{
.pic_present = pinfo.pic_present,
.hpet_base = hpet_base,
.pm_timer = pm_timer,
.ioapic_base = ioapic_base,
.ioapic_gsi_base = ioapic_gsi,
.overrides = isos[0..iso_n],
});
if (pinfo.spcr_uart) |u| arch.serialReconfigure(u.mmio, u.address);
serial0.debugWrite("danos: platform\n");
serial0.debugPrint(" 8259 PIC : {s}\n", .{if (pinfo.pic_present) "present" else "absent"});
serial0.debugPrint(" lapic base : 0x{x}\n", .{pinfo.lapic_base});
serial0.debugPrint(" hpet base : 0x{x}\n", .{hpet_base});
serial0.debugPrint(" pm timer : {s} 0x{x} ({s})\n", .{ if (pinfo.pm_timer.mmio) "mmio" else "io", pinfo.pm_timer.address, if (pinfo.pm_timer_32bit) "32-bit" else "24-bit" });
if (pinfo.spcr_uart) |u| {
serial0.debugPrint(" console UART: {s} 0x{x} (SPCR type {d})\n", .{ if (u.mmio) "mmio" else "io", u.address, pinfo.spcr_kind });
} else {
serial0.debugWrite(" console UART: none in SPCR -> legacy COM1\n");
}
serial0.debugPrint(" ioapic : base 0x{x}, {d} inputs (masked); entry0 low 0x{x}\n", .{ ioapic_base, arch.ioapicEntryCount(), arch.ioapicEntryLow(0) });
} else |err| {
serial0.debugPrint("\ndanos: device discovery failed: {s}\n", .{@errorName(err)});
}
@@ -143,7 +190,7 @@ fn kmain(boot_info: *const BootInfo) noreturn {
// the timer preempts among tasks.
arch.startTimer();
arch.enableInterrupts();
serial0.debugPrint("danos: timer online ({d} Hz tick; LAPIC {d} MHz, TSC {d} MHz measured)\n", .{ arch.timer_hz, arch.lapicHz() / 1_000_000, arch.tscHz() / 1_000_000 });
serial0.debugPrint("danos: timer online ({d} Hz tick; LAPIC {d} MHz, TSC {d} MHz; calibrated via {s})\n", .{ arch.timer_hz, arch.lapicHz() / 1_000_000, arch.tscHz() / 1_000_000, arch.timerCalibrationSource() });
// In a test build (`zig build -Dtest-case=<name>`), run that case and stop.
// Normal builds fall through to the idle halt.