The flip: ACPI enumeration leaves the kernel (M20.3)
The kernel no longer folds AML Device objects into the device tree — the ring-3 acpi service is the sole builder of _HID device nodes. The kernel keeps building the namespace only for the \_S5 sleep type, and still seeds the static tables (MADT, HPET, MCFG, FADT) and the acpi-tables node. The device manager matches ps2-bus from the service's _HID reports (PNP0303 / PNP0F13, singleton-deduped) instead of boot-snapshot nodes; its dead boot-snapshot ps2 arm is gone. The service registers every device before reporting any, so a driver the manager spawns on the first report already sees the full set — no keyboard-before-mouse race. The acpi-ps2 scenario proves the whole chain: report -> spawn -> ps2-bus finds the controller and attaches its keyboard, entirely in ring 3. The ioport test moved to the acpi-tables I/O window, since the kernel-built PS/2 node it used to scan for no longer exists. The retired device-building functions in acpi.zig are dead but retained (a botched mechanical deletion is worse mid-migration than a follow-up sweep, which is flagged as a task). Suite 58/58.
This commit is contained in:
+15
-7
@@ -150,6 +150,8 @@ pub fn run(case: []const u8, boot_information: *const BootInformation) void {
|
||||
acpiParseTest(boot_information);
|
||||
} else if (eql(case, "acpi-report")) {
|
||||
acpiReportTest(boot_information);
|
||||
} else if (eql(case, "acpi-ps2")) {
|
||||
acpiReportTest(boot_information); // same spawn; the harness regex differs
|
||||
} else if (eql(case, "initial-ramdisk")) {
|
||||
initialRamdiskTest(boot_information);
|
||||
} else if (eql(case, "vfs")) {
|
||||
@@ -1134,12 +1136,18 @@ fn ioPortTest() void {
|
||||
var buffer: [64]device_abi.DeviceDescriptor = undefined;
|
||||
const n = @min(devices_broker.enumerate(&buffer), buffer.len);
|
||||
|
||||
// Post-M20.3 the PS/2 node is registered at runtime by the ring-3 acpi
|
||||
// service, so it is absent from this boot snapshot. Exercise the same
|
||||
// io_port claim/resolve mechanism against the acpi-tables node's broad I/O
|
||||
// grant — the window that now carries port authority (the service uses it
|
||||
// for exactly this). The PS/2 status port 0x64 is offset 0x64 within it.
|
||||
var found_id: ?u64 = null;
|
||||
var found_res: u64 = 0;
|
||||
outer: for (buffer[0..n]) |d| {
|
||||
if (d.class != @intFromEnum(device_abi.DeviceClass.acpi_tables)) continue;
|
||||
for (0..d.resource_count) |ri| {
|
||||
const r = d.resources[ri];
|
||||
if (r.kind == @intFromEnum(device_abi.ResourceKind.io_port) and r.start == 0x64 and r.len >= 1) {
|
||||
if (r.kind == @intFromEnum(device_abi.ResourceKind.io_port) and r.start == 0 and r.len > 0x64) {
|
||||
found_id = d.id;
|
||||
found_res = ri;
|
||||
break :outer;
|
||||
@@ -1147,18 +1155,18 @@ fn ioPortTest() void {
|
||||
}
|
||||
}
|
||||
const id = found_id orelse {
|
||||
check("discovered the PS/2 status port (io_port 0x64)", false);
|
||||
check("discovered the acpi-tables I/O window", false);
|
||||
result();
|
||||
return;
|
||||
};
|
||||
check("discovered the PS/2 status port (io_port 0x64)", true);
|
||||
check("discovered the acpi-tables I/O window", true);
|
||||
|
||||
const me = scheduler.current();
|
||||
check("claimed the io_port device", devices_broker.claim(id, me.id));
|
||||
check("an in-range access resolves to port 0x64", process.resolveIoPort(me, id, found_res, 0, 1) == 0x64);
|
||||
check("an over-wide access is refused", process.resolveIoPort(me, id, found_res, 0, 2) == null);
|
||||
check("an out-of-range offset is refused", process.resolveIoPort(me, id, found_res, 1, 1) == null);
|
||||
check("an unclaimed device id is refused", process.resolveIoPort(me, 0xDEAD_BEEF, found_res, 0, 1) == null);
|
||||
check("an in-range access resolves to port 0x64", process.resolveIoPort(me, id, found_res, 0x64, 1) == 0x64);
|
||||
check("a 4-byte access at the last port is refused", process.resolveIoPort(me, id, found_res, 0xFFFF, 4) == null);
|
||||
check("an out-of-range offset is refused", process.resolveIoPort(me, id, found_res, 0x10000, 1) == null);
|
||||
check("an unclaimed device id is refused", process.resolveIoPort(me, 0xDEAD_BEEF, found_res, 0x64, 1) == null);
|
||||
|
||||
// The kernel actually issues the `in`. Reaching this line at all proves it didn't
|
||||
// fault; a width-1 read must return a single byte.
|
||||
|
||||
Reference in New Issue
Block a user