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:
@@ -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
@@ -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
@@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 = .{
|
||||||
|
|||||||
@@ -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,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user