Name ACPI hardware IDs instead of magic _HID strings

Turn acpi-ids.zig's flat name table into a HardwareId enum modeled on
ps2-library's Port: one entry() switch holds the registry (variant ->
_HID string + human-readable name), with hid(), description(), and
fromHid() methods. The free description(hid) lookup the kernel's
device-tree dump uses survives, implemented over the enum, and a new
test round-trips every variant through fromHid.

Callers now name the device instead of quoting its id:

- ps2-library's DeviceType.hid() and ps2-bus's descriptor lookups use
  HardwareId.ps2_keyboard / .ps2_mouse.
- device-manager's driverFor parses the HID once with fromHid and
  switches on named values.
- acpi.zig's isPciRootNode carried the same ids twice, as strings and
  as packed-EISA integers (0x030AD041/0x080AD041); both branches now
  decode to the string form and answer through one isPciRootHid helper
  using .pci_bus / .pci_express_root_bridge.
- build.zig threads the acpi-ids module (previously kernel-only) into
  every user binary, like xkeyboard-config.
This commit is contained in:
Daniel Samson
2026-07-11 23:23:16 +01:00
parent 5725d35e5b
commit 88e92254e9
6 changed files with 158 additions and 73 deletions
+18 -14
View File
@@ -61,6 +61,7 @@ fn addUserBinary(
posix_module: *std.Build.Module, posix_module: *std.Build.Module,
mmio_module: *std.Build.Module, mmio_module: *std.Build.Module,
xkeyboard_config_module: *std.Build.Module, xkeyboard_config_module: *std.Build.Module,
acpi_ids_module: *std.Build.Module,
name: []const u8, name: []const u8,
root: []const u8, root: []const u8,
) *std.Build.Step.Compile { ) *std.Build.Step.Compile {
@@ -85,6 +86,9 @@ fn addUserBinary(
// Keyboard layouts (keycode + modifiers -> keysym/character), available // Keyboard layouts (keycode + modifiers -> keysym/character), available
// to any program that wants it. See library/xkeyboard-config/. // to any program that wants it. See library/xkeyboard-config/.
.{ .name = "xkeyboard-config", .module = xkeyboard_config_module }, .{ .name = "xkeyboard-config", .module = xkeyboard_config_module },
// ACPI/PnP hardware-ID registry, so drivers name devices
// (HardwareId.ps2_keyboard) instead of magic "_HID" strings.
.{ .name = "acpi-ids", .module = acpi_ids_module },
}, },
}), }),
}); });
@@ -312,7 +316,7 @@ pub fn build(b: *std.Build) void {
// Built by the shared user-binary recipe (see addUserBinary): freestanding, // Built by the shared user-binary recipe (see addUserBinary): freestanding,
// linked into the kernel's user region against the `runtime` runtime library, and // linked into the kernel's user region against the `runtime` runtime library, and
// started in ring 3 by the kernel's user-ELF loader. // started in ring 3 by the kernel's user-ELF loader.
const init_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, "init", "system/services/init/init.zig"); const init_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "init", "system/services/init/init.zig");
const init_install = b.addInstallArtifact(init_exe, .{ .dest_dir = .{ .override = .{ .custom = "system/services" } } }); const init_install = b.addInstallArtifact(init_exe, .{ .dest_dir = .{ .override = .{ .custom = "system/services" } } });
b.getInstallStep().dependOn(&init_install.step); b.getInstallStep().dependOn(&init_install.step);
@@ -320,21 +324,21 @@ pub fn build(b: *std.Build) void {
// Each is built by the same user-binary recipe, then packed into one image by // Each is built by the same user-binary recipe, then packed into one image by
// the host-side make-initial-ramdisk tool. The bootloader ferries the image to the kernel, // the host-side make-initial-ramdisk tool. The bootloader ferries the image to the kernel,
// which unpacks it and spawns each program (system/initial-ramdisk.zig). // which unpacks it and spawns each program (system/initial-ramdisk.zig).
const vfs_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, "vfs", "system/services/vfs/vfs.zig"); const vfs_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "vfs", "system/services/vfs/vfs.zig");
const vfstest_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, "vfs-test", "system/services/vfs/vfs-test.zig"); const vfstest_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "vfs-test", "system/services/vfs/vfs-test.zig");
const hpet_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, "hpet", "system/drivers/hpet/hpet.zig"); const hpet_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "hpet", "system/drivers/hpet/hpet.zig");
const bus_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, "bus", "system/drivers/bus/bus.zig"); const bus_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "bus", "system/drivers/bus/bus.zig");
const ps2_bus_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, "bus", "system/drivers/ps2-bus/ps2-bus.zig"); const ps2_bus_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "bus", "system/drivers/ps2-bus/ps2-bus.zig");
const ps2_keyboard_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, "ps2-keyboard", "system/drivers/ps2-bus/keyboard.zig"); const ps2_keyboard_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "ps2-keyboard", "system/drivers/ps2-bus/keyboard.zig");
const ps2_mouse_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, "ps2-mouse", "system/drivers/ps2-bus/mouse.zig"); const ps2_mouse_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "ps2-mouse", "system/drivers/ps2-bus/mouse.zig");
const device_manager_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, "device-manager", "system/services/device-manager/device-manager.zig"); const device_manager_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "device-manager", "system/services/device-manager/device-manager.zig");
// The input service and its exercisers: the fan-out server, a hardware-free synthetic // 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. // source, and a subscriber that doubles as the `input` test's oracle. See docs/input.md.
const input_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, "input", "system/services/input/input.zig"); const input_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "input", "system/services/input/input.zig");
const input_source_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, "input-source", "system/services/input-source/input-source.zig"); const input_source_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "input-source", "system/services/input-source/input-source.zig");
const input_test_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, "input-test", "system/services/input-test/input-test.zig"); const input_test_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "input-test", "system/services/input-test/input-test.zig");
const args_echo_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, "args-echo", "system/services/args-echo/args-echo.zig"); const args_echo_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "args-echo", "system/services/args-echo/args-echo.zig");
const process_test_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, "process-test", "system/services/process-test/process-test.zig"); const process_test_exe = addUserBinary(b, kernel_target, runtime_module, posix_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "process-test", "system/services/process-test/process-test.zig");
// Pack the user binaries into the initial_ramdisk image with the host-side Python tool // Pack the user binaries into the initial_ramdisk image with the host-side Python tool
// (the container format is trivial, and Python sidesteps std API churn). Args: // (the container format is trivial, and Python sidesteps std API churn). Args:
+115 -45
View File
@@ -1,60 +1,120 @@
//! ACPI / PnP hardware-ID (`_HID`) names: the flat analog of pci-class.zig for //! ACPI / PnP hardware-ID (`_HID`) names: the flat analog of pci-class.zig for
//! `acpi_device` nodes. Unlike PCI, ACPI has no class/subclass/prog-IF taxonomy — a //! `acpi_device` nodes. Unlike PCI, ACPI has no class/subclass/prog-IF taxonomy — a
//! device's identity *is* its `_HID` string (`PNP0303` simply means "PS/2 keyboard"), //! device's identity *is* its `_HID` string (`PNP0303` simply means "PS/2 keyboard"),
//! so this is a plain id -> description registry rather than a hierarchical decoder. //! so this is a plain id <-> name registry rather than a hierarchical decoder.
//! The well-known PnP/ACPI IDs; vendor-specific ids (e.g. `QEMU0002`, `INTC1234`) have //! The well-known PnP/ACPI IDs; vendor-specific ids (e.g. `QEMU0002`, `INTC1234`) have
//! no standard name and return "". Pure reference data, so it is shared by kernel //! no standard name and decode to nothing. Pure reference data, so it is shared by
//! discovery (the device-tree dump) and any user-space tool. //! kernel discovery (the device-tree dump) and any user-space driver or tool.
//!
//! Code that means a specific device names the `HardwareId` variant instead of its
//! `_HID` string — `HardwareId.ps2_keyboard.hid()` reads without a registry lookup,
//! where a bare `"PNP0303"` does not.
const std = @import("std"); const std = @import("std");
/// The common standard PnP/ACPI hardware IDs, as named values. Prefix ranges hint at
/// the grouping (PNP03xx keyboards, PNP0Fxx pointing devices, PNP0Cxx ACPI
/// power/thermal, PNP0Axx buses), but there is no formal hierarchy — hence a flat
/// enum over a flat registry.
pub const HardwareId = enum {
programmable_interrupt_controller,
system_timer,
high_precision_event_timer,
dma_controller,
ps2_keyboard,
parallel_port,
ecp_parallel_port,
serial_port,
floppy_disk_controller,
system_speaker,
pci_bus,
generic_container,
/// The second id the ACPI spec assigns the same "Generic Container Device" name.
generic_container_extended,
pci_express_root_bridge,
real_time_clock,
system_board,
motherboard_reserved_resources,
math_coprocessor,
acpi_system_board,
embedded_controller,
control_method_battery,
fan,
power_button,
lid,
sleep_button,
pci_interrupt_link,
microsoft_ps2_mouse,
ps2_mouse,
ac_adapter,
processor_device,
processor_aggregator,
processor_container,
const Entry = struct { hid: []const u8, name: []const u8 }; const Entry = struct { hid: []const u8, name: []const u8 };
/// The common standard PnP/ACPI hardware IDs. Prefix ranges hint at the grouping /// The registry row for this id: its `_HID` string and human-readable name.
/// (PNP03xx keyboards, PNP0Fxx pointing devices, PNP0Cxx ACPI power/thermal, fn entry(self: HardwareId) Entry {
/// PNP0Axx buses), but there is no formal hierarchy — hence a flat table. return switch (self) {
const table = [_]Entry{ .programmable_interrupt_controller => .{ .hid = "PNP0000", .name = "Programmable Interrupt Controller (PIC)" },
.{ .hid = "PNP0000", .name = "Programmable Interrupt Controller (PIC)" }, .system_timer => .{ .hid = "PNP0100", .name = "System Timer (PIT)" },
.{ .hid = "PNP0100", .name = "System Timer (PIT)" }, .high_precision_event_timer => .{ .hid = "PNP0103", .name = "High Precision Event Timer (HPET)" },
.{ .hid = "PNP0103", .name = "High Precision Event Timer (HPET)" }, .dma_controller => .{ .hid = "PNP0200", .name = "DMA Controller" },
.{ .hid = "PNP0200", .name = "DMA Controller" }, .ps2_keyboard => .{ .hid = "PNP0303", .name = "PS/2 Keyboard" },
.{ .hid = "PNP0303", .name = "PS/2 Keyboard" }, .parallel_port => .{ .hid = "PNP0400", .name = "Standard LPT Parallel Port" },
.{ .hid = "PNP0400", .name = "Standard LPT Parallel Port" }, .ecp_parallel_port => .{ .hid = "PNP0401", .name = "ECP Parallel Port" },
.{ .hid = "PNP0401", .name = "ECP Parallel Port" }, .serial_port => .{ .hid = "PNP0501", .name = "16550A-compatible Serial Port" },
.{ .hid = "PNP0501", .name = "16550A-compatible Serial Port" }, .floppy_disk_controller => .{ .hid = "PNP0700", .name = "PC Floppy Disk Controller" },
.{ .hid = "PNP0700", .name = "PC Floppy Disk Controller" }, .system_speaker => .{ .hid = "PNP0800", .name = "System Speaker" },
.{ .hid = "PNP0800", .name = "System Speaker" }, .pci_bus => .{ .hid = "PNP0A03", .name = "PCI Bus" },
.{ .hid = "PNP0A03", .name = "PCI Bus" }, .generic_container => .{ .hid = "PNP0A05", .name = "Generic Container Device" },
.{ .hid = "PNP0A05", .name = "Generic Container Device" }, .generic_container_extended => .{ .hid = "PNP0A06", .name = "Generic Container Device" },
.{ .hid = "PNP0A06", .name = "Generic Container Device" }, .pci_express_root_bridge => .{ .hid = "PNP0A08", .name = "PCI Express Root Bridge" },
.{ .hid = "PNP0A08", .name = "PCI Express Root Bridge" }, .real_time_clock => .{ .hid = "PNP0B00", .name = "Real-Time Clock (RTC)" },
.{ .hid = "PNP0B00", .name = "Real-Time Clock (RTC)" }, .system_board => .{ .hid = "PNP0C01", .name = "System Board" },
.{ .hid = "PNP0C01", .name = "System Board" }, .motherboard_reserved_resources => .{ .hid = "PNP0C02", .name = "Motherboard Reserved Resources" },
.{ .hid = "PNP0C02", .name = "Motherboard Reserved Resources" }, .math_coprocessor => .{ .hid = "PNP0C04", .name = "Math Coprocessor" },
.{ .hid = "PNP0C04", .name = "Math Coprocessor" }, .acpi_system_board => .{ .hid = "PNP0C08", .name = "ACPI System Board" },
.{ .hid = "PNP0C08", .name = "ACPI System Board" }, .embedded_controller => .{ .hid = "PNP0C09", .name = "ACPI Embedded Controller" },
.{ .hid = "PNP0C09", .name = "ACPI Embedded Controller" }, .control_method_battery => .{ .hid = "PNP0C0A", .name = "ACPI Control Method Battery" },
.{ .hid = "PNP0C0A", .name = "ACPI Control Method Battery" }, .fan => .{ .hid = "PNP0C0B", .name = "ACPI Fan" },
.{ .hid = "PNP0C0B", .name = "ACPI Fan" }, .power_button => .{ .hid = "PNP0C0C", .name = "ACPI Power Button" },
.{ .hid = "PNP0C0C", .name = "ACPI Power Button" }, .lid => .{ .hid = "PNP0C0D", .name = "ACPI Lid" },
.{ .hid = "PNP0C0D", .name = "ACPI Lid" }, .sleep_button => .{ .hid = "PNP0C0E", .name = "ACPI Sleep Button" },
.{ .hid = "PNP0C0E", .name = "ACPI Sleep Button" }, .pci_interrupt_link => .{ .hid = "PNP0C0F", .name = "PCI Interrupt Link Device" },
.{ .hid = "PNP0C0F", .name = "PCI Interrupt Link Device" }, .microsoft_ps2_mouse => .{ .hid = "PNP0F03", .name = "Microsoft PS/2 Mouse" },
.{ .hid = "PNP0F03", .name = "Microsoft PS/2 Mouse" }, .ps2_mouse => .{ .hid = "PNP0F13", .name = "PS/2 Mouse" },
.{ .hid = "PNP0F13", .name = "PS/2 Mouse" }, .ac_adapter => .{ .hid = "ACPI0003", .name = "AC Adapter" },
.{ .hid = "ACPI0003", .name = "AC Adapter" }, .processor_device => .{ .hid = "ACPI0007", .name = "Processor Device" },
.{ .hid = "ACPI0007", .name = "Processor Device" }, .processor_aggregator => .{ .hid = "ACPI000C", .name = "Processor Aggregator" },
.{ .hid = "ACPI000C", .name = "Processor Aggregator" }, .processor_container => .{ .hid = "ACPI0010", .name = "Processor Container" },
.{ .hid = "ACPI0010", .name = "Processor Container" }, };
}
/// This id's `_HID` string (e.g. `.ps2_keyboard` -> "PNP0303").
pub fn hid(self: HardwareId) []const u8 {
return self.entry().hid;
}
/// This id's human-readable name (e.g. `.ps2_keyboard` -> "PS/2 Keyboard").
pub fn description(self: HardwareId) []const u8 {
return self.entry().name;
}
/// The named value for a `_HID` string, or null if it is not a known standard
/// id (vendor-specific ids are not in the registry).
pub fn fromHid(hid_string: []const u8) ?HardwareId {
for (std.enums.values(HardwareId)) |id| {
if (std.mem.eql(u8, id.hid(), hid_string)) return id;
}
return null;
}
}; };
/// The human-readable name for a `_HID`, or "" if it is not a known standard id /// The human-readable name for a `_HID` string, or "" if it is not a known standard
/// (vendor-specific ids have no registry name — callers just print the raw HID). /// id (vendor-specific ids have no registry name — callers just print the raw HID).
pub fn description(hid: []const u8) []const u8 { pub fn description(hid: []const u8) []const u8 {
for (table) |entry| { return (HardwareId.fromHid(hid) orelse return "").description();
if (std.mem.eql(u8, entry.hid, hid)) return entry.name;
}
return "";
} }
test "decodes standard PnP/ACPI ids and leaves the rest alone" { test "decodes standard PnP/ACPI ids and leaves the rest alone" {
@@ -66,3 +126,13 @@ test "decodes standard PnP/ACPI ids and leaves the rest alone" {
try eq("", description("QEMU0002")); // vendor-specific: no standard name try eq("", description("QEMU0002")); // vendor-specific: no standard name
try eq("", description("")); // no HID at all try eq("", description("")); // no HID at all
} }
test "named values round-trip through their _HID strings" {
const testing = std.testing;
try testing.expectEqualStrings("PNP0303", HardwareId.ps2_keyboard.hid());
try testing.expectEqual(@as(?HardwareId, .ps2_mouse), HardwareId.fromHid("PNP0F13"));
try testing.expectEqual(@as(?HardwareId, null), HardwareId.fromHid("QEMU0002"));
for (std.enums.values(HardwareId)) |id| {
try testing.expectEqual(@as(?HardwareId, id), HardwareId.fromHid(id.hid()));
}
}
+12 -6
View File
@@ -17,6 +17,7 @@
const std = @import("std"); const std = @import("std");
const boot_handoff = @import("boot-handoff"); const boot_handoff = @import("boot-handoff");
const abi = @import("abi"); const abi = @import("abi");
const acpi_ids = @import("acpi-ids");
const parameters = @import("parameters"); const parameters = @import("parameters");
const device_model = @import("device-model.zig"); const device_model = @import("device-model.zig");
const aml = @import("aml/aml.zig"); const aml = @import("aml/aml.zig");
@@ -914,7 +915,14 @@ fn readAdr(node: *aml.Node) ?u32 {
return @truncate(readIntObj(n.value, &p) orelse return null); return @truncate(readIntObj(n.value, &p) orelse return null);
} }
/// Whether a namespace device is a PCI(e) host bridge (`PNP0A03` / `PNP0A08`). /// Whether a `_HID` string names a PCI(e) host bridge.
fn isPciRootHid(hid: []const u8) bool {
const id = acpi_ids.HardwareId.fromHid(hid) orelse return false;
return id == .pci_bus or id == .pci_express_root_bridge;
}
/// Whether a namespace device is a PCI(e) host bridge. A packed EISA id is decoded
/// to its string form first, so both encodings answer through the one registry.
fn isPciRootNode(node: *aml.Node) bool { fn isPciRootNode(node: *aml.Node) bool {
const hid = aml.Namespace.childOf(node, seg4("_HID")) orelse return false; const hid = aml.Namespace.childOf(node, seg4("_HID")) orelse return false;
if (hid.kind != .name or hid.value.len == 0) return false; if (hid.kind != .name or hid.value.len == 0) return false;
@@ -922,12 +930,10 @@ fn isPciRootNode(node: *aml.Node) bool {
0x00, 0x01, 0xFF, 0x0A, 0x0B, 0x0C, 0x0E => { 0x00, 0x01, 0xFF, 0x0A, 0x0B, 0x0C, 0x0E => {
var p: usize = 0; var p: usize = 0;
const n = readIntObj(hid.value, &p) orelse return false; const n = readIntObj(hid.value, &p) orelse return false;
return n == 0x030AD041 or n == 0x080AD041; // PNP0A03 / PNP0A08 var buffer: [8]u8 = undefined;
}, return isPciRootHid(eisaIdToStr(@truncate(n), &buffer));
0x0D => {
const s = cstr(hid.value[1..]);
return std.mem.eql(u8, s, "PNP0A03") or std.mem.eql(u8, s, "PNP0A08");
}, },
0x0D => return isPciRootHid(cstr(hid.value[1..])),
else => return false, else => return false,
} }
} }
+3 -2
View File
@@ -11,6 +11,7 @@
//! - irq 0xc len 0x1 //! - irq 0xc len 0x1
const std = @import("std"); const std = @import("std");
const runtime = @import("runtime"); const runtime = @import("runtime");
const acpi_ids = @import("acpi-ids");
const ps2 = @import("ps2-library.zig"); const ps2 = @import("ps2-library.zig");
const device = runtime.device; const device = runtime.device;
const ipc = runtime.ipc; const ipc = runtime.ipc;
@@ -100,7 +101,7 @@ pub fn main() void {
// The 8042's IO ports (0x60/0x64) are enumerated under the keyboard ACPI node // The 8042's IO ports (0x60/0x64) are enumerated under the keyboard ACPI node
// (PNP0303), so we init the controller from that descriptor — but which device // (PNP0303), so we init the controller from that descriptor — but which device
// is on which port is decided later by identify, not by this HID. // is on which port is decided later by identify, not by this HID.
const maybe_controller_device_descriptor = device.findDeviceDescriptorByHid(buffer, "PNP0303"); const maybe_controller_device_descriptor = device.findDeviceDescriptorByHid(buffer, acpi_ids.HardwareId.ps2_keyboard.hid());
if (maybe_controller_device_descriptor) |controller_device_descriptor| { if (maybe_controller_device_descriptor) |controller_device_descriptor| {
_ = runtime.system.write("system/drivers/ps2-bus: found PS/2 controller\n"); _ = runtime.system.write("system/drivers/ps2-bus: found PS/2 controller\n");
_ = runtime.system.write("system/drivers/ps2-bus: initializing controller\n"); _ = runtime.system.write("system/drivers/ps2-bus: initializing controller\n");
@@ -243,7 +244,7 @@ pub fn main() void {
// to the *port*, whatever device identify found on it. // to the *port*, whatever device identify found on it.
var maybe_auxiliary_interrupt: ?struct { device_id: u64, interrupt_index: u64, gsi: u64 } = null; var maybe_auxiliary_interrupt: ?struct { device_id: u64, interrupt_index: u64, gsi: u64 } = null;
if (port_device_types[@intFromEnum(ps2.Port.Two)] != null) { if (port_device_types[@intFromEnum(ps2.Port.Two)] != null) {
if (device.findDeviceDescriptorByHid(buffer, "PNP0F13")) |descriptor| { if (device.findDeviceDescriptorByHid(buffer, acpi_ids.HardwareId.ps2_mouse.hid())) |descriptor| {
if (findInterruptResourceIndex(descriptor)) |auxiliary_index| { if (findInterruptResourceIndex(descriptor)) |auxiliary_index| {
if (device.claim(descriptor.id) and device.irqBind(descriptor.id, auxiliary_index, endpoint)) { if (device.claim(descriptor.id) and device.irqBind(descriptor.id, auxiliary_index, endpoint)) {
maybe_auxiliary_interrupt = .{ maybe_auxiliary_interrupt = .{
+3 -2
View File
@@ -1,6 +1,7 @@
//! shared definitions between the different PS/2 drivers //! shared definitions between the different PS/2 drivers
const std = @import("std"); const std = @import("std");
const runtime = @import("runtime"); const runtime = @import("runtime");
const acpi_ids = @import("acpi-ids");
const device = runtime.device; const device = runtime.device;
const system = runtime.system; const system = runtime.system;
@@ -261,8 +262,8 @@ pub const DeviceType = enum(u32) {
/// its command-line argument, or null if we could not classify it. /// its command-line argument, or null if we could not classify it.
pub fn hid(self: DeviceType) ?[]const u8 { pub fn hid(self: DeviceType) ?[]const u8 {
return switch (self) { return switch (self) {
.keyboard => "PNP0303", .keyboard => acpi_ids.HardwareId.ps2_keyboard.hid(),
.mouse => "PNP0F13", .mouse => acpi_ids.HardwareId.ps2_mouse.hid(),
.unknown => null, .unknown => null,
}; };
} }
@@ -14,6 +14,7 @@
//! that redundancy so the manager is the sole owner of driver spawning.) //! that redundancy so the manager is the sole owner of driver spawning.)
const std = @import("std"); const std = @import("std");
const runtime = @import("runtime"); const runtime = @import("runtime");
const acpi_ids = @import("acpi-ids");
const device = runtime.device; const device = runtime.device;
const system = runtime.system; const system = runtime.system;
@@ -34,9 +35,11 @@ fn driverFor(d: device.DeviceDescriptor) ?[]const u8 {
if (d.class == @intFromEnum(device.DeviceClass.timer)) return "hpet"; if (d.class == @intFromEnum(device.DeviceClass.timer)) return "hpet";
// detect device via hid // detect device via hid
const hid = d.hid[0..@intCast(d.hid_len)]; const hid = d.hid[0..@intCast(d.hid_len)];
if (std.mem.eql(u8, hid, "PNP0303") or std.mem.eql(u8, hid, "PNP0F13")) return "ps2-bus"; const id = acpi_ids.HardwareId.fromHid(hid) orelse return null;
return switch (id) {
return null; .ps2_keyboard, .ps2_mouse => "ps2-bus",
else => null,
};
} }