device-manager: data-driven driver matching via /etc/devices.csv
Replace the three hardcoded switch tables (pciDriverForIdentity, hidDriverFor, usbDriverForIdentity) with an authoritative, human-readable device registry the manager reads at boot. Matching is most-specific-wins across base/subclass/prog_if/vendor/device/subsystem/hid, so a precise vendor:device rule and a generic class rule coexist; an unmatched device is logged, never guessed. This resolves docs' "matching stays code until the third bus". - ABI: child_added and DeviceDescriptor gain vendor/device/subsystem; child_added gains a bus discriminator (BusKind) so PCI and USB class triples match against the right namespace. - pci-bus reads vendor/device (config 0x00) and subsystem (0x2C, type-0) and reports them. - library/device/registry: freestanding CSV parser + matchDriver() with specificity scoring; 5 unit tests wired into `zig build test`. - etc/devices.csv bundled into the initrd; the kernel serves /etc directly, so the manager reads it before any filesystem service is up (fat starts later). - virtio-gpu: drop the now-redundant post-spawn 1AF4:1050 re-confirm, since the registry binds this driver by exact identity. - Remove the orphaned system/drivers/display driver (unreferenced by build or registry). - docs: new devices-csv.md; device-manager.md "matching stays code" resolved. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KJqSiLLchDUUCoXn5jsiwd
This commit is contained in:
@@ -284,6 +284,13 @@ pub fn build(b: *std.Build) void {
|
||||
const pci_class_module = b.addModule("pci-class", .{
|
||||
.root_source_file = b.path("library/device/pci/pci-class.zig"),
|
||||
});
|
||||
// The device registry: parse /etc/devices.csv into match rules and bind a
|
||||
// reported device to a driver — the data-driven, authoritative replacement for
|
||||
// the manager's hand-written switch tables. Pure logic (no hardware, no
|
||||
// syscalls), so it unit-tests with plain `zig test`; the manager imports it.
|
||||
const device_registry_module = b.addModule("device-registry", .{
|
||||
.root_source_file = b.path("library/device/registry/device-registry.zig"),
|
||||
});
|
||||
// ACPI/PnP hardware-ID (_HID) names — the flat analog of pci-class for acpi_device
|
||||
// nodes. Also shared reference data.
|
||||
// The AML interpreter, a build module so the ring-3 acpi service can run the
|
||||
@@ -729,12 +736,10 @@ pub fn build(b: *std.Build) void {
|
||||
if (discovery == .acpi) programModule(discovery_exe).addImport("device-manager-protocol", device_manager_protocol_module);
|
||||
if (discovery == .acpi) programModule(discovery_exe).addImport("power-protocol", power_protocol_module);
|
||||
const device_manager_exe = addUserBinary(b, kernel_target, &default_imports, "device-manager", "system/services/device-manager/device-manager.zig");
|
||||
// Names the xHCI PCI class triple from the shared taxonomy instead of a bare 0x0C0330.
|
||||
programModule(device_manager_exe).addImport("pci-class", pci_class_module);
|
||||
programModule(device_manager_exe).addImport("device-manager-protocol", device_manager_protocol_module);
|
||||
// The manager matches reported USB interfaces by their (class,subclass,protocol)
|
||||
// triple (usbDriverForIdentity), built from the named usb-ids codes.
|
||||
programModule(device_manager_exe).addImport("usb-ids", usb_ids_module);
|
||||
// Driver matching is data-driven: the manager parses /etc/devices.csv into this
|
||||
// module's rules and binds each reported device by most-specific match.
|
||||
programModule(device_manager_exe).addImport("device-registry", device_registry_module);
|
||||
// The input service and its exercisers: the fan-out server, a hardware-free synthetic
|
||||
// source, and a subscriber that doubles as the `input` test's oracle. See docs/input.md.
|
||||
const input_exe = addUserBinary(b, kernel_target, &default_imports, "input", "system/services/input/input.zig");
|
||||
@@ -764,6 +769,11 @@ pub fn build(b: *std.Build) void {
|
||||
.{ .path = "system/services/input", .binary = input_exe.getEmittedBin() },
|
||||
.{ .path = "system/services/discovery", .binary = discovery_exe.getEmittedBin() },
|
||||
.{ .path = "system/services/logger", .binary = logger_exe.getEmittedBin() },
|
||||
// A data file, not a binary: the device registry the manager reads at boot.
|
||||
// Packing it under /etc makes the kernel auto-mount /etc as a read-only
|
||||
// initrd tree (system/kernel/vfs.zig setInitialRamdisk), so the manager can
|
||||
// fs.open("/etc/devices.csv") with no filesystem service running.
|
||||
.{ .path = "etc/devices.csv", .binary = b.path("etc/devices.csv") },
|
||||
.{ .path = "system/drivers/ps2-bus", .binary = ps2_bus_exe.getEmittedBin() },
|
||||
.{ .path = "system/drivers/ps2-keyboard", .binary = ps2_keyboard_exe.getEmittedBin() },
|
||||
.{ .path = "system/drivers/ps2-mouse", .binary = ps2_mouse_exe.getEmittedBin() },
|
||||
@@ -1078,6 +1088,7 @@ pub fn build(b: *std.Build) void {
|
||||
"library/device/acpi/aml/aml.zig", // AML parse + interpret, incl. Notify dispatch (M21)
|
||||
"library/device/usb/usb-abi.zig", // wire sizes + bit packings + set-up packet encodings
|
||||
"library/device/usb/usb-ids.zig", // class/subclass/protocol code assignments
|
||||
"library/device/registry/device-registry.zig", // /etc/devices.csv parse + most-specific driver match
|
||||
"library/device/mmio/mmio.zig", // barriers assemble + registers round-trip
|
||||
"system/drivers/ps2-bus/scancode.zig", // set-2 decode + keyboard state machine
|
||||
"system/drivers/ps2-bus/mouse-packet.zig", // 3-byte mouse packet assembly
|
||||
|
||||
Reference in New Issue
Block a user