fix / debug
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
//! M19.1 (this increment): claim the bridge, map its ECAM window (resource 0;
|
//! M19.1 (this increment): claim the bridge, map its ECAM window (resource 0;
|
||||||
//! the bus range and the MMIO apertures follow it), walk every
|
//! the bus range and the MMIO apertures follow it), walk every
|
||||||
//! bus/device/function config header, and log what the walk finds — ending
|
//! bus/device/function config header, and log what the walk finds — ending
|
||||||
//! with "system/drviers/pci-bus: N functions found", which the `pci-scan` scenario compares
|
//! with "/system/drviers/pci-bus: N functions found", which the `pci-scan` scenario compares
|
||||||
//! against the kernel's own enumeration. Registration and reports (M19.2), and
|
//! against the kernel's own enumeration. Registration and reports (M19.2), and
|
||||||
//! the kernel walk's retirement (M19.3), build on this proven-equivalent scan.
|
//! the kernel walk's retirement (M19.3), build on this proven-equivalent scan.
|
||||||
|
|
||||||
@@ -31,9 +31,9 @@ fn logFunction(bus: u64, dev: u64, function: u64, class_triple: u32) void {
|
|||||||
const pif = pci_class.progIfName(cc.base, cc.subclass, cc.prog_if);
|
const pif = pci_class.progIfName(cc.base, cc.subclass, cc.prog_if);
|
||||||
var line: [200]u8 = undefined;
|
var line: [200]u8 = undefined;
|
||||||
const text = if (pif.len != 0)
|
const text = if (pif.len != 0)
|
||||||
std.fmt.bufPrint(&line, "system/drviers/pci-bus: {d}:{d}.{d} class 0x{x:0>2} ({s}) subclass 0x{x:0>2} ({s}) progif 0x{x:0>2} ({s})\n", .{ bus, dev, function, cc.base, pci_class.className(cc.base), cc.subclass, pci_class.subclassName(cc.base, cc.subclass), cc.prog_if, pif }) catch return
|
std.fmt.bufPrint(&line, "/system/drviers/pci-bus: {d}:{d}.{d} class 0x{x:0>2} ({s}) subclass 0x{x:0>2} ({s}) progif 0x{x:0>2} ({s})\n", .{ bus, dev, function, cc.base, pci_class.className(cc.base), cc.subclass, pci_class.subclassName(cc.base, cc.subclass), cc.prog_if, pif }) catch return
|
||||||
else
|
else
|
||||||
std.fmt.bufPrint(&line, "system/drviers/pci-bus: {d}:{d}.{d} class 0x{x:0>2} ({s}) subclass 0x{x:0>2} ({s}) progif 0x{x:0>2}\n", .{ bus, dev, function, cc.base, pci_class.className(cc.base), cc.subclass, pci_class.subclassName(cc.base, cc.subclass), cc.prog_if }) catch return;
|
std.fmt.bufPrint(&line, "/system/drviers/pci-bus: {d}:{d}.{d} class 0x{x:0>2} ({s}) subclass 0x{x:0>2} ({s}) progif 0x{x:0>2}\n", .{ bus, dev, function, cc.base, pci_class.className(cc.base), cc.subclass, pci_class.subclassName(cc.base, cc.subclass), cc.prog_if }) catch return;
|
||||||
_ = runtime.system.write(text);
|
_ = runtime.system.write(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,37 +74,37 @@ fn configWrite16(bus: u64, dev: u64, function: u64, offset: u64, value: u16) voi
|
|||||||
fn initialise(endpoint: runtime.ipc.Handle) bool {
|
fn initialise(endpoint: runtime.ipc.Handle) bool {
|
||||||
_ = endpoint;
|
_ = endpoint;
|
||||||
if (!device.claim(bridge_id)) {
|
if (!device.claim(bridge_id)) {
|
||||||
writeLine("system/drviers/pci-bus: unable to claim bridge device {d}\n", .{bridge_id});
|
writeLine("/system/drviers/pci-bus: unable to claim bridge device {d}\n", .{bridge_id});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const buffer = runtime.allocator().alloc(device.DeviceDescriptor, 64) catch {
|
const buffer = runtime.allocator().alloc(device.DeviceDescriptor, 64) catch {
|
||||||
_ = runtime.system.write("system/drviers/pci-bus: out of memory\n");
|
_ = runtime.system.write("/system/drviers/pci-bus: out of memory\n");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
const total = device.enumerate(buffer);
|
const total = device.enumerate(buffer);
|
||||||
const descriptor = for (buffer[0..@min(total, buffer.len)]) |d| {
|
const descriptor = for (buffer[0..@min(total, buffer.len)]) |d| {
|
||||||
if (d.id == bridge_id) break d;
|
if (d.id == bridge_id) break d;
|
||||||
} else {
|
} else {
|
||||||
writeLine("system/drviers/pci-bus: device {d} not in the device tree\n", .{bridge_id});
|
writeLine("/system/drviers/pci-bus: device {d} not in the device tree\n", .{bridge_id});
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
// Resource 0 is the ECAM window (1 MiB of config space per bus); the bus
|
// Resource 0 is the ECAM window (1 MiB of config space per bus); the bus
|
||||||
// range rides beside it. The MMIO apertures (M19.0) come after both.
|
// range rides beside it. The MMIO apertures (M19.0) come after both.
|
||||||
if (descriptor.resource_count < 2 or descriptor.resources[0].kind != @intFromEnum(device.ResourceKind.memory)) {
|
if (descriptor.resource_count < 2 or descriptor.resources[0].kind != @intFromEnum(device.ResourceKind.memory)) {
|
||||||
_ = runtime.system.write("system/drviers/pci-bus: bridge has no ECAM window\n");
|
_ = runtime.system.write("/system/drviers/pci-bus: bridge has no ECAM window\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const bus_range = for (descriptor.resources[0..@intCast(descriptor.resource_count)]) |resource| {
|
const bus_range = for (descriptor.resources[0..@intCast(descriptor.resource_count)]) |resource| {
|
||||||
if (resource.kind == @intFromEnum(device.ResourceKind.bus_range)) break resource;
|
if (resource.kind == @intFromEnum(device.ResourceKind.bus_range)) break resource;
|
||||||
} else {
|
} else {
|
||||||
_ = runtime.system.write("system/drviers/pci-bus: bridge has no bus range\n");
|
_ = runtime.system.write("/system/drviers/pci-bus: bridge has no bus range\n");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
start_bus = bus_range.start;
|
start_bus = bus_range.start;
|
||||||
bus_count = bus_range.len;
|
bus_count = bus_range.len;
|
||||||
ecam_physical = descriptor.resources[0].start;
|
ecam_physical = descriptor.resources[0].start;
|
||||||
ecam_base = device.mmioMap(bridge_id, 0) orelse {
|
ecam_base = device.mmioMap(bridge_id, 0) orelse {
|
||||||
_ = runtime.system.write("system/drviers/pci-bus: ECAM mmio_map failed\n");
|
_ = runtime.system.write("/system/drviers/pci-bus: ECAM mmio_map failed\n");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -116,17 +116,17 @@ fn initialise(endpoint: runtime.ipc.Handle) bool {
|
|||||||
if (manager == null) runtime.system.sleep(20);
|
if (manager == null) runtime.system.sleep(20);
|
||||||
}
|
}
|
||||||
const h = manager orelse {
|
const h = manager orelse {
|
||||||
_ = runtime.system.write("system/drviers/pci-bus: no device manager to hello\n");
|
_ = runtime.system.write("/system/drviers/pci-bus: no device manager to hello\n");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
const hello = protocol.Hello{ .role = @intFromEnum(protocol.Role.bus), .device_id = bridge_id };
|
const hello = protocol.Hello{ .role = @intFromEnum(protocol.Role.bus), .device_id = bridge_id };
|
||||||
var reply: [protocol.message_maximum]u8 = undefined;
|
var reply: [protocol.message_maximum]u8 = undefined;
|
||||||
const n = runtime.ipc.call(h, std.mem.asBytes(&hello), &reply) catch {
|
const n = runtime.ipc.call(h, std.mem.asBytes(&hello), &reply) catch {
|
||||||
_ = runtime.system.write("system/drviers/pci-bus: hello call failed\n");
|
_ = runtime.system.write("/system/drviers/pci-bus: hello call failed\n");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
if (n < protocol.reply_size or std.mem.bytesToValue(protocol.HelloReply, reply[0..protocol.reply_size]).status != 0) {
|
if (n < protocol.reply_size or std.mem.bytesToValue(protocol.HelloReply, reply[0..protocol.reply_size]).status != 0) {
|
||||||
_ = runtime.system.write("system/drviers/pci-bus: hello refused\n");
|
_ = runtime.system.write("/system/drviers/pci-bus: hello refused\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
manager_handle = h;
|
manager_handle = h;
|
||||||
@@ -159,7 +159,7 @@ fn scan() void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writeLine("system/drviers/pci-bus: {d} functions found\n", .{found});
|
writeLine("/system/drviers/pci-bus: {d} functions found\n", .{found});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register one function under the bridge and report it to the manager. The
|
/// Register one function under the bridge and report it to the manager. The
|
||||||
@@ -229,7 +229,7 @@ fn registerAndReport(bus: u64, dev: u64, function: u64, class_triple: u32) void
|
|||||||
}
|
}
|
||||||
|
|
||||||
const registered = device.register(bridge_id, &descriptor) orelse {
|
const registered = device.register(bridge_id, &descriptor) orelse {
|
||||||
writeLine("system/drviers/pci-bus: register refused for {d}:{d}.{d}\n", .{ bus, dev, function });
|
writeLine("/system/drviers/pci-bus: register refused for {d}:{d}.{d}\n", .{ bus, dev, function });
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
const report = protocol.ChildAdded{
|
const report = protocol.ChildAdded{
|
||||||
@@ -240,7 +240,7 @@ fn registerAndReport(bus: u64, dev: u64, function: u64, class_triple: u32) void
|
|||||||
};
|
};
|
||||||
var reply: [protocol.message_maximum]u8 = undefined;
|
var reply: [protocol.message_maximum]u8 = undefined;
|
||||||
_ = runtime.ipc.call(manager_handle, std.mem.asBytes(&report), &reply) catch {
|
_ = runtime.ipc.call(manager_handle, std.mem.asBytes(&report), &reply) catch {
|
||||||
writeLine("system/drviers/pci-bus: child report for {d}:{d}.{d} failed\n", .{ bus, dev, function });
|
writeLine("/system/drviers/pci-bus: child report for {d}:{d}.{d} failed\n", .{ bus, dev, function });
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +255,7 @@ fn onMessage(message: []const u8, reply: []u8, sender: u32, capability: ?runtime
|
|||||||
pub fn main(init: runtime.process.Init) void {
|
pub fn main(init: runtime.process.Init) void {
|
||||||
const argument = init.arguments.get(1) orelse return; // bare (ramdisk sweep): stay silent
|
const argument = init.arguments.get(1) orelse return; // bare (ramdisk sweep): stay silent
|
||||||
bridge_id = std.fmt.parseInt(u64, argument, 10) catch {
|
bridge_id = std.fmt.parseInt(u64, argument, 10) catch {
|
||||||
writeLine("system/drviers/pci-bus: malformed bridge device id '{s}'\n", .{argument});
|
writeLine("/system/drviers/pci-bus: malformed bridge device id '{s}'\n", .{argument});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
runtime.service.run(protocol.message_maximum, .{
|
runtime.service.run(protocol.message_maximum, .{
|
||||||
|
|||||||
@@ -30,19 +30,19 @@ fn writeLine(comptime fmt: []const u8, arguments: anytype) void {
|
|||||||
/// attaches, or null if nothing was spawned.
|
/// attaches, or null if nothing was spawned.
|
||||||
fn spawnIdentifiedDriver(controller: ps2.Controller, port: ps2.Port) ?ps2.DeviceType {
|
fn spawnIdentifiedDriver(controller: ps2.Controller, port: ps2.Port) ?ps2.DeviceType {
|
||||||
const device_type = controller.identifyDevice(port) orelse {
|
const device_type = controller.identifyDevice(port) orelse {
|
||||||
writeLine("system/drivers/ps2-bus: identify timed out on port {s}\n", .{@tagName(port)});
|
writeLine("/system/drivers/ps2-bus: identify timed out on port {s}\n", .{@tagName(port)});
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
const driver_name = device_type.driverName() orelse {
|
const driver_name = device_type.driverName() orelse {
|
||||||
writeLine("system/drivers/ps2-bus: unrecognized device on port {s}\n", .{@tagName(port)});
|
writeLine("/system/drivers/ps2-bus: unrecognized device on port {s}\n", .{@tagName(port)});
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
const hid = device_type.hid() orelse "";
|
const hid = device_type.hid() orelse "";
|
||||||
if (runtime.system.spawnWithArguments(driver_name, &.{hid}) != null) {
|
if (runtime.system.spawnWithArguments(driver_name, &.{hid}) != null) {
|
||||||
writeLine("system/drivers/ps2-bus: port {s} is a {s}, spawned {s}\n", .{ @tagName(port), hid, driver_name });
|
writeLine("/system/drivers/ps2-bus: port {s} is a {s}, spawned {s}\n", .{ @tagName(port), hid, driver_name });
|
||||||
return device_type;
|
return device_type;
|
||||||
}
|
}
|
||||||
writeLine("system/drivers/ps2-bus: failed to spawn {s}\n", .{driver_name});
|
writeLine("/system/drivers/ps2-bus: failed to spawn {s}\n", .{driver_name});
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ fn handleAttach(message: []const u8, got: ipc.Received, out: []u8) usize {
|
|||||||
const device_type = maybe_type orelse continue;
|
const device_type = maybe_type orelse continue;
|
||||||
if (@intFromEnum(device_type) != request.device_type) continue;
|
if (@intFromEnum(device_type) != request.device_type) continue;
|
||||||
port_endpoints[port_index] = endpoint;
|
port_endpoints[port_index] = endpoint;
|
||||||
writeLine("system/drivers/ps2-bus: {s} driver attached\n", .{@tagName(device_type)});
|
writeLine("/system/drivers/ps2-bus: {s} driver attached\n", .{@tagName(device_type)});
|
||||||
return reply.write(out, .ok);
|
return reply.write(out, .ok);
|
||||||
}
|
}
|
||||||
return reply.write(out, .no_such_device);
|
return reply.write(out, .no_such_device);
|
||||||
@@ -91,7 +91,7 @@ fn handleAttach(message: []const u8, got: ipc.Received, out: []u8) usize {
|
|||||||
|
|
||||||
pub fn main() void {
|
pub fn main() void {
|
||||||
const buffer = runtime.allocator().alloc(device.DeviceDescriptor, 64) catch {
|
const buffer = runtime.allocator().alloc(device.DeviceDescriptor, 64) catch {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: out of memory\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: out of memory\n");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -103,16 +103,16 @@ pub fn main() void {
|
|||||||
// 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, acpi_ids.HardwareId.ps2_keyboard.hid());
|
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");
|
||||||
|
|
||||||
if (!device.claim(controller_device_descriptor.id)) {
|
if (!device.claim(controller_device_descriptor.id)) {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: unable to claim controller \n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: unable to claim controller \n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const controller = ps2.Controller.init(controller_device_descriptor) orelse {
|
const controller = ps2.Controller.init(controller_device_descriptor) orelse {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: controller is missing its IO ports\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: controller is missing its IO ports\n");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
maybe_controller = controller;
|
maybe_controller = controller;
|
||||||
@@ -123,7 +123,7 @@ pub fn main() void {
|
|||||||
controller.flushOutputBuffer();
|
controller.flushOutputBuffer();
|
||||||
|
|
||||||
const current = controller.readConfigurationByte() orelse {
|
const current = controller.readConfigurationByte() orelse {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: controller configuration timed out\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: controller configuration timed out\n");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -132,49 +132,49 @@ pub fn main() void {
|
|||||||
ps2.configuration_first_port_translation);
|
ps2.configuration_first_port_translation);
|
||||||
|
|
||||||
if (controller.writeConfigurationByte(update) == null) {
|
if (controller.writeConfigurationByte(update) == null) {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: controller configuration timed out\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: controller configuration timed out\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controller.performSelfTest()) |reply| {
|
if (controller.performSelfTest()) |reply| {
|
||||||
if (reply != ps2.response_controller_test_passed) {
|
if (reply != ps2.response_controller_test_passed) {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: perform controller self test failed\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: perform controller self test failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: controller self test timed out\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: controller self test timed out\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
has_two_channels = controller.hasTwoChannels() orelse {
|
has_two_channels = controller.hasTwoChannels() orelse {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: controller channels timed out\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: controller channels timed out\n");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (has_two_channels) {
|
if (has_two_channels) {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: has two channels\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: has two channels\n");
|
||||||
// keep the bus quiet until we have tested the ports and are ready to use them
|
// keep the bus quiet until we have tested the ports and are ready to use them
|
||||||
controller.disablePort(.two);
|
controller.disablePort(.two);
|
||||||
} else {
|
} else {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: has one channel\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: has one channel\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// interface tests: always test port 1, test port 2 only if it exists
|
// interface tests: always test port 1, test port 2 only if it exists
|
||||||
const port_one_works = (controller.testPort(.one) orelse {
|
const port_one_works = (controller.testPort(.one) orelse {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: port 1 test timed out\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: port 1 test timed out\n");
|
||||||
return;
|
return;
|
||||||
}) == ps2.response_port_test_passed;
|
}) == ps2.response_port_test_passed;
|
||||||
|
|
||||||
var port_two_works = false;
|
var port_two_works = false;
|
||||||
if (has_two_channels) {
|
if (has_two_channels) {
|
||||||
port_two_works = (controller.testPort(.two) orelse {
|
port_two_works = (controller.testPort(.two) orelse {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: port 2 test timed out\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: port 2 test timed out\n");
|
||||||
return;
|
return;
|
||||||
}) == ps2.response_port_test_passed;
|
}) == ps2.response_port_test_passed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!port_one_works and !port_two_works) {
|
if (!port_one_works and !port_two_works) {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: no usable ports\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: no usable ports\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,16 +188,16 @@ pub fn main() void {
|
|||||||
// abort bring-up of the other one
|
// abort bring-up of the other one
|
||||||
if (port_one_works) {
|
if (port_one_works) {
|
||||||
if (controller.resetDevice(.one)) |passed| {
|
if (controller.resetDevice(.one)) |passed| {
|
||||||
if (!passed) _ = runtime.system.write("system/drivers/ps2-bus: port 1 device reset failed\n");
|
if (!passed) _ = runtime.system.write("/system/drivers/ps2-bus: port 1 device reset failed\n");
|
||||||
} else {
|
} else {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: port 1 device reset timed out\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: port 1 device reset timed out\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (port_two_works) {
|
if (port_two_works) {
|
||||||
if (controller.resetDevice(.two)) |passed| {
|
if (controller.resetDevice(.two)) |passed| {
|
||||||
if (!passed) _ = runtime.system.write("system/drivers/ps2-bus: port 2 device reset failed\n");
|
if (!passed) _ = runtime.system.write("/system/drivers/ps2-bus: port 2 device reset failed\n");
|
||||||
} else {
|
} else {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: port 2 device reset timed out\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: port 2 device reset timed out\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,13 +207,13 @@ pub fn main() void {
|
|||||||
if (port_one_works) port_device_types[@intFromEnum(ps2.Port.one)] = spawnIdentifiedDriver(controller, .one);
|
if (port_one_works) port_device_types[@intFromEnum(ps2.Port.one)] = spawnIdentifiedDriver(controller, .one);
|
||||||
if (port_two_works) port_device_types[@intFromEnum(ps2.Port.two)] = spawnIdentifiedDriver(controller, .two);
|
if (port_two_works) port_device_types[@intFromEnum(ps2.Port.two)] = spawnIdentifiedDriver(controller, .two);
|
||||||
} else {
|
} else {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: no PS/2 controller found\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: no PS/2 controller found\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const controller = maybe_controller.?;
|
const controller = maybe_controller.?;
|
||||||
const interrupt_index = maybe_interrupt_index orelse {
|
const interrupt_index = maybe_interrupt_index orelse {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: controller is missing its IRQ\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: controller is missing its IRQ\n");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -221,11 +221,11 @@ pub fn main() void {
|
|||||||
// well-known id so the children can find it, the way input subscribers find
|
// well-known id so the children can find it, the way input subscribers find
|
||||||
// the input service.
|
// the input service.
|
||||||
const endpoint = ipc.createIpcEndpoint() orelse {
|
const endpoint = ipc.createIpcEndpoint() orelse {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: no endpoint\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: no endpoint\n");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if (!ipc.register(.ps2_bus, endpoint)) {
|
if (!ipc.register(.ps2_bus, endpoint)) {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: register failed\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: register failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ pub fn main() void {
|
|||||||
// let the controller raise them — an interrupt with nobody bound is lost.
|
// let the controller raise them — an interrupt with nobody bound is lost.
|
||||||
controller.drainOutputBuffer();
|
controller.drainOutputBuffer();
|
||||||
if (!device.irqBind(controller.device_id, interrupt_index, endpoint)) {
|
if (!device.irqBind(controller.device_id, interrupt_index, endpoint)) {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: irq_bind failed\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: irq_bind failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,21 +253,21 @@ pub fn main() void {
|
|||||||
.gsi = descriptor.resources[auxiliary_index].start,
|
.gsi = descriptor.resources[auxiliary_index].start,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: auxiliary irq_bind failed\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: auxiliary irq_bind failed\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var configuration = controller.readConfigurationByte() orelse {
|
var configuration = controller.readConfigurationByte() orelse {
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: controller configuration timed out\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: controller configuration timed out\n");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if (port_device_types[@intFromEnum(ps2.Port.one)] != null) configuration |= ps2.Port.one.interruptBit();
|
if (port_device_types[@intFromEnum(ps2.Port.one)] != null) configuration |= ps2.Port.one.interruptBit();
|
||||||
if (maybe_auxiliary_interrupt != null) configuration |= ps2.Port.two.interruptBit();
|
if (maybe_auxiliary_interrupt != null) configuration |= ps2.Port.two.interruptBit();
|
||||||
_ = controller.writeConfigurationByte(configuration);
|
_ = controller.writeConfigurationByte(configuration);
|
||||||
|
|
||||||
_ = runtime.system.write("system/drivers/ps2-bus: ok\n");
|
_ = runtime.system.write("/system/drivers/ps2-bus: ok\n");
|
||||||
|
|
||||||
// The forwarding loop: an IRQ1 notification drains the output buffer, routing
|
// The forwarding loop: an IRQ1 notification drains the output buffer, routing
|
||||||
// each byte to the attached driver of the port it came from; a client message
|
// each byte to the attached driver of the port it came from; a client message
|
||||||
|
|||||||
@@ -33,20 +33,20 @@ var controller_id: u64 = protocol.no_device;
|
|||||||
fn initialise(endpoint: runtime.ipc.Handle) bool {
|
fn initialise(endpoint: runtime.ipc.Handle) bool {
|
||||||
_ = endpoint;
|
_ = endpoint;
|
||||||
if (!device.claim(controller_id)) {
|
if (!device.claim(controller_id)) {
|
||||||
writeLine("system/drivers/usb-xhci-bus: unable to claim controller device {d}\n", .{controller_id});
|
writeLine("/system/drivers/usb-xhci-bus: unable to claim controller device {d}\n", .{controller_id});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch our own descriptor back for the controller's resources.
|
// Fetch our own descriptor back for the controller's resources.
|
||||||
const buffer = runtime.allocator().alloc(device.DeviceDescriptor, 64) catch {
|
const buffer = runtime.allocator().alloc(device.DeviceDescriptor, 64) catch {
|
||||||
_ = runtime.system.write("system/drivers/usb-xhci-bus: out of memory\n");
|
_ = runtime.system.write("/system/drivers/usb-xhci-bus: out of memory\n");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
const total = device.enumerate(buffer);
|
const total = device.enumerate(buffer);
|
||||||
const descriptor = for (buffer[0..@min(total, buffer.len)]) |d| {
|
const descriptor = for (buffer[0..@min(total, buffer.len)]) |d| {
|
||||||
if (d.id == controller_id) break d;
|
if (d.id == controller_id) break d;
|
||||||
} else {
|
} else {
|
||||||
writeLine("system/drivers/usb-xhci-bus: device {d} not in the device tree\n", .{controller_id});
|
writeLine("/system/drivers/usb-xhci-bus: device {d} not in the device tree\n", .{controller_id});
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -59,16 +59,16 @@ fn initialise(endpoint: runtime.ipc.Handle) bool {
|
|||||||
break resource;
|
break resource;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
writeLine("system/drivers/usb-xhci-bus: controller device {d} has no register BAR\n", .{controller_id});
|
writeLine("/system/drivers/usb-xhci-bus: controller device {d} has no register BAR\n", .{controller_id});
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
writeLine("system/drivers/usb-xhci-bus: claimed controller device {d} (registers at 0x{x}, {d} bytes)\n", .{
|
writeLine("/system/drivers/usb-xhci-bus: claimed controller device {d} (registers at 0x{x}, {d} bytes)\n", .{
|
||||||
controller_id,
|
controller_id,
|
||||||
register_window.start,
|
register_window.start,
|
||||||
register_window.len,
|
register_window.len,
|
||||||
});
|
});
|
||||||
register_base = device.mmioMap(controller_id, register_index) orelse {
|
register_base = device.mmioMap(controller_id, register_index) orelse {
|
||||||
_ = runtime.system.write("system/drivers/usb-xhci-bus: mmio_map failed\n");
|
_ = runtime.system.write("/system/drivers/usb-xhci-bus: mmio_map failed\n");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -81,20 +81,20 @@ fn initialise(endpoint: runtime.ipc.Handle) bool {
|
|||||||
if (manager == null) runtime.system.sleep(20);
|
if (manager == null) runtime.system.sleep(20);
|
||||||
}
|
}
|
||||||
const h = manager orelse {
|
const h = manager orelse {
|
||||||
_ = runtime.system.write("system/drivers/usb-xhci-bus: no device manager to hello\n");
|
_ = runtime.system.write("/system/drivers/usb-xhci-bus: no device manager to hello\n");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
const hello = protocol.Hello{ .role = @intFromEnum(protocol.Role.bus), .device_id = controller_id };
|
const hello = protocol.Hello{ .role = @intFromEnum(protocol.Role.bus), .device_id = controller_id };
|
||||||
var reply: [protocol.message_maximum]u8 = undefined;
|
var reply: [protocol.message_maximum]u8 = undefined;
|
||||||
const n = runtime.ipc.call(h, std.mem.asBytes(&hello), &reply) catch {
|
const n = runtime.ipc.call(h, std.mem.asBytes(&hello), &reply) catch {
|
||||||
_ = runtime.system.write("system/drivers/usb-xhci-bus: hello call failed\n");
|
_ = runtime.system.write("/system/drivers/usb-xhci-bus: hello call failed\n");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
if (n < protocol.reply_size or std.mem.bytesToValue(protocol.HelloReply, reply[0..protocol.reply_size]).status != 0) {
|
if (n < protocol.reply_size or std.mem.bytesToValue(protocol.HelloReply, reply[0..protocol.reply_size]).status != 0) {
|
||||||
_ = runtime.system.write("system/drivers/usb-xhci-bus: hello refused\n");
|
_ = runtime.system.write("/system/drivers/usb-xhci-bus: hello refused\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_ = runtime.system.write("system/drivers/usb-xhci-bus: hello acknowledged\n");
|
_ = runtime.system.write("/system/drivers/usb-xhci-bus: hello acknowledged\n");
|
||||||
|
|
||||||
scanPorts(h);
|
scanPorts(h);
|
||||||
return true;
|
return true;
|
||||||
@@ -135,7 +135,7 @@ fn scanPorts(manager: runtime.ipc.Handle) void {
|
|||||||
const capability_length = readRegister(0) & 0xFF;
|
const capability_length = readRegister(0) & 0xFF;
|
||||||
const structural = readRegister(0x04);
|
const structural = readRegister(0x04);
|
||||||
const maximum_ports: u32 = structural >> 24;
|
const maximum_ports: u32 = structural >> 24;
|
||||||
writeLine("system/drivers/usb-xhci-bus: {d} root-hub ports\n", .{maximum_ports});
|
writeLine("/system/drivers/usb-xhci-bus: {d} root-hub ports\n", .{maximum_ports});
|
||||||
|
|
||||||
// PORTSC registers: operational base + 0x400 + 0x10 per port (1-based).
|
// PORTSC registers: operational base + 0x400 + 0x10 per port (1-based).
|
||||||
var port: u32 = 1;
|
var port: u32 = 1;
|
||||||
@@ -145,7 +145,7 @@ fn scanPorts(manager: runtime.ipc.Handle) void {
|
|||||||
if (port_status & 1 == 0) continue; // CCS: nothing connected
|
if (port_status & 1 == 0) continue; // CCS: nothing connected
|
||||||
connected += 1;
|
connected += 1;
|
||||||
const speed = (port_status >> 10) & 0xF; // the PORTSC port-speed class
|
const speed = (port_status >> 10) & 0xF; // the PORTSC port-speed class
|
||||||
writeLine("system/drivers/usb-xhci-bus: port {d} connected — {s} (speed class {d})\n", .{ port, speedName(speed), speed });
|
writeLine("/system/drivers/usb-xhci-bus: port {d} connected — {s} (speed class {d})\n", .{ port, speedName(speed), speed });
|
||||||
|
|
||||||
const report = protocol.ChildAdded{
|
const report = protocol.ChildAdded{
|
||||||
.parent = controller_id,
|
.parent = controller_id,
|
||||||
@@ -154,11 +154,11 @@ fn scanPorts(manager: runtime.ipc.Handle) void {
|
|||||||
};
|
};
|
||||||
var reply: [protocol.message_maximum]u8 = undefined;
|
var reply: [protocol.message_maximum]u8 = undefined;
|
||||||
_ = runtime.ipc.call(manager, std.mem.asBytes(&report), &reply) catch {
|
_ = runtime.ipc.call(manager, std.mem.asBytes(&report), &reply) catch {
|
||||||
writeLine("system/drivers/usb-xhci-bus: child report for port {d} failed\n", .{port});
|
writeLine("/system/drivers/usb-xhci-bus: child report for port {d} failed\n", .{port});
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (connected == 0) _ = runtime.system.write("system/drivers/usb-xhci-bus: no devices connected\n");
|
if (connected == 0) _ = runtime.system.write("/system/drivers/usb-xhci-bus: no devices connected\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// No bus protocol to serve yet — transfer requests arrive with the USB track.
|
/// No bus protocol to serve yet — transfer requests arrive with the USB track.
|
||||||
@@ -172,11 +172,11 @@ fn onMessage(message: []const u8, reply: []u8, sender: u32, capability: ?runtime
|
|||||||
|
|
||||||
pub fn main(init: runtime.process.Init) void {
|
pub fn main(init: runtime.process.Init) void {
|
||||||
const argument = init.arguments.get(1) orelse {
|
const argument = init.arguments.get(1) orelse {
|
||||||
_ = runtime.system.write("system/drivers/usb-xhci-bus: missing controller device id (argv[1])\n");
|
_ = runtime.system.write("/system/drivers/usb-xhci-bus: missing controller device id (argv[1])\n");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
controller_id = std.fmt.parseInt(u64, argument, 10) catch {
|
controller_id = std.fmt.parseInt(u64, argument, 10) catch {
|
||||||
writeLine("system/drivers/usb-xhci-bus: malformed controller device id '{s}'\n", .{argument});
|
writeLine("/system/drivers/usb-xhci-bus: malformed controller device id '{s}'\n", .{argument});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
runtime.service.run(protocol.message_maximum, .{
|
runtime.service.run(protocol.message_maximum, .{
|
||||||
|
|||||||
@@ -72,16 +72,16 @@ pub fn main(init: runtime.process.Init) void {
|
|||||||
const expected: ?usize = if (init.arguments.get(1)) |a| (std.fmt.parseInt(usize, a, 10) catch null) else null;
|
const expected: ?usize = if (init.arguments.get(1)) |a| (std.fmt.parseInt(usize, a, 10) catch null) else null;
|
||||||
|
|
||||||
const buffer = runtime.allocator().alloc(device.DeviceDescriptor, 64) catch {
|
const buffer = runtime.allocator().alloc(device.DeviceDescriptor, 64) catch {
|
||||||
_ = runtime.system.write("system/services/acpi: out of memory\n");
|
_ = runtime.system.write("/system/services/acpi: out of memory\n");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
const node = findTablesNode(buffer) orelse {
|
const node = findTablesNode(buffer) orelse {
|
||||||
_ = runtime.system.write("system/services/acpi: no acpi-tables node to claim\n");
|
_ = runtime.system.write("/system/services/acpi: no acpi-tables node to claim\n");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
node_id = node.id;
|
node_id = node.id;
|
||||||
if (!device.claim(node_id)) {
|
if (!device.claim(node_id)) {
|
||||||
_ = runtime.system.write("system/services/acpi: unable to claim acpi-tables\n");
|
_ = runtime.system.write("/system/services/acpi: unable to claim acpi-tables\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,17 +103,17 @@ pub fn main(init: runtime.process.Init) void {
|
|||||||
if (block_count == blocks.len) break;
|
if (block_count == blocks.len) break;
|
||||||
}
|
}
|
||||||
if (block_count == 0) {
|
if (block_count == 0) {
|
||||||
_ = runtime.system.write("system/services/acpi: no AML blobs on the node\n");
|
_ = runtime.system.write("/system/services/acpi: no AML blobs on the node\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = aml.parse(runtime.allocator(), blocks[0..block_count]) catch {
|
const result = aml.parse(runtime.allocator(), blocks[0..block_count]) catch {
|
||||||
_ = runtime.system.write("system/services/acpi: AML parse failed\n");
|
_ = runtime.system.write("/system/services/acpi: AML parse failed\n");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
var namespace = result.namespace;
|
var namespace = result.namespace;
|
||||||
const devices = aml.deviceCount(&namespace);
|
const devices = aml.deviceCount(&namespace);
|
||||||
writeLine("system/services/acpi: parsed {d} AML blob(s), {d} namespace devices\n", .{ block_count, devices });
|
writeLine("/system/services/acpi: parsed {d} AML blob(s), {d} namespace devices\n", .{ block_count, devices });
|
||||||
if (expected) |want| {
|
if (expected) |want| {
|
||||||
if (devices == want) {
|
if (devices == want) {
|
||||||
_ = runtime.system.write("acpi-parse: ok\n");
|
_ = runtime.system.write("acpi-parse: ok\n");
|
||||||
@@ -150,9 +150,9 @@ pub fn main(init: runtime.process.Init) void {
|
|||||||
const hid = entry.hid[0..entry.hid_len];
|
const hid = entry.hid[0..entry.hid_len];
|
||||||
const desc = acpi_ids.description(hid);
|
const desc = acpi_ids.description(hid);
|
||||||
if (desc.len != 0)
|
if (desc.len != 0)
|
||||||
writeLine("system/services/acpi: reported {s} (device {d}, {d} resources) — {s}\n", .{ hid, entry.device_id, entry.resource_count, desc })
|
writeLine("/system/services/acpi: reported {s} (device {d}, {d} resources) — {s}\n", .{ hid, entry.device_id, entry.resource_count, desc })
|
||||||
else
|
else
|
||||||
writeLine("system/services/acpi: reported {s} (device {d}, {d} resources)\n", .{ hid, entry.device_id, entry.resource_count });
|
writeLine("/system/services/acpi: reported {s} (device {d}, {d} resources)\n", .{ hid, entry.device_id, entry.resource_count });
|
||||||
if (manager) |h| {
|
if (manager) |h| {
|
||||||
var report = protocol.ChildAdded{
|
var report = protocol.ChildAdded{
|
||||||
.parent = node_id,
|
.parent = node_id,
|
||||||
@@ -165,7 +165,7 @@ pub fn main(init: runtime.process.Init) void {
|
|||||||
_ = runtime.ipc.call(h, std.mem.asBytes(&report), &reply) catch {};
|
_ = runtime.ipc.call(h, std.mem.asBytes(&report), &reply) catch {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writeLine("system/services/acpi: reported {d} device(s) to the manager\n", .{registered_count});
|
writeLine("/system/services/acpi: reported {d} device(s) to the manager\n", .{registered_count});
|
||||||
|
|
||||||
// Stay resident: the claim holds, and the service is here to grow into the
|
// Stay resident: the claim holds, and the service is here to grow into the
|
||||||
// supervised discoverer (M20.3, then the M21 event side on the SCI).
|
// supervised discoverer (M20.3, then the M21 event side on the SCI).
|
||||||
@@ -207,7 +207,7 @@ fn registerDevice(node: *aml.Node, hid: [8]u8, interpreter: *aml.Interpreter) vo
|
|||||||
applyCrs(&descriptor, node, interpreter);
|
applyCrs(&descriptor, node, interpreter);
|
||||||
|
|
||||||
const id = device.register(node_id, &descriptor) orelse {
|
const id = device.register(node_id, &descriptor) orelse {
|
||||||
writeLine("system/services/acpi: register refused for {s}\n", .{hid[0..@intCast(hid_len)]});
|
writeLine("/system/services/acpi: register refused for {s}\n", .{hid[0..@intCast(hid_len)]});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
registered[registered_count] = .{ .hid = hid, .hid_len = @intCast(hid_len), .device_id = id, .resource_count = descriptor.resource_count };
|
registered[registered_count] = .{ .hid = hid, .hid_len = @intCast(hid_len), .device_id = id, .resource_count = descriptor.resource_count };
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ fn addChild(parent: u64, bus_address: u64, identity: u64, device_id: u64, report
|
|||||||
fn pruneChildrenOf(reporter: u32) void {
|
fn pruneChildrenOf(reporter: u32) void {
|
||||||
for (&children) |*child| {
|
for (&children) |*child| {
|
||||||
if (child.used and child.reporter == reporter) {
|
if (child.used and child.reporter == reporter) {
|
||||||
writeLine("system/services/device-manager: child removed (device {d} port {d})\n", .{ child.parent, child.bus_address });
|
writeLine("/system/services/device-manager: child removed (device {d} port {d})\n", .{ child.parent, child.bus_address });
|
||||||
child.used = false;
|
child.used = false;
|
||||||
const event = protocol.ChildRemoved{ .parent = child.parent, .bus_address = child.bus_address };
|
const event = protocol.ChildRemoved{ .parent = child.parent, .bus_address = child.bus_address };
|
||||||
publishEvent(std.mem.asBytes(&event));
|
publishEvent(std.mem.asBytes(&event));
|
||||||
@@ -238,7 +238,7 @@ fn addDriver(name: []const u8, device_id: u64, speaks_protocol: bool) void {
|
|||||||
spawnDriver(driver);
|
spawnDriver(driver);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
writeLine("system/services/device-manager: driver table full; cannot supervise {s}\n", .{name});
|
writeLine("/system/services/device-manager: driver table full; cannot supervise {s}\n", .{name});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// (Re)spawn a driver instance: supervised on the manager's own endpoint, the
|
/// (Re)spawn a driver instance: supervised on the manager's own endpoint, the
|
||||||
@@ -253,7 +253,7 @@ fn spawnDriver(driver: *Driver) void {
|
|||||||
argument_count = 1;
|
argument_count = 1;
|
||||||
}
|
}
|
||||||
const child = system.spawnSupervised(driver.name(), arguments[0..argument_count], manager_endpoint) orelse {
|
const child = system.spawnSupervised(driver.name(), arguments[0..argument_count], manager_endpoint) orelse {
|
||||||
writeLine("system/services/device-manager: failed to spawn {s}\n", .{driver.name()});
|
writeLine("/system/services/device-manager: failed to spawn {s}\n", .{driver.name()});
|
||||||
driver.state = .failed;
|
driver.state = .failed;
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -267,9 +267,9 @@ fn spawnDriver(driver: *Driver) void {
|
|||||||
driver.state = .running;
|
driver.state = .running;
|
||||||
}
|
}
|
||||||
if (driver.device_id != protocol.no_device) {
|
if (driver.device_id != protocol.no_device) {
|
||||||
writeLine("system/services/device-manager: spawned {s} for device {d}\n", .{ driver.name(), driver.device_id });
|
writeLine("/system/services/device-manager: spawned {s} for device {d}\n", .{ driver.name(), driver.device_id });
|
||||||
} else {
|
} else {
|
||||||
writeLine("system/services/device-manager: spawned {s}\n", .{driver.name()});
|
writeLine("/system/services/device-manager: spawned {s}\n", .{driver.name()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +281,7 @@ fn onDriverExit(driver: *Driver) void {
|
|||||||
const reason = runtime.process.exitReason(driver.process_id) orelse .fault;
|
const reason = runtime.process.exitReason(driver.process_id) orelse .fault;
|
||||||
if (reason == .exited) {
|
if (reason == .exited) {
|
||||||
driver.state = .stopped;
|
driver.state = .stopped;
|
||||||
writeLine("system/services/device-manager: {s} exited cleanly; not restarting\n", .{driver.name()});
|
writeLine("/system/services/device-manager: {s} exited cleanly; not restarting\n", .{driver.name()});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const now = system.clock();
|
const now = system.clock();
|
||||||
@@ -289,13 +289,13 @@ fn onDriverExit(driver: *Driver) void {
|
|||||||
driver.restarts = if (alive_ns < fast_death_ns) driver.restarts + 1 else 1;
|
driver.restarts = if (alive_ns < fast_death_ns) driver.restarts + 1 else 1;
|
||||||
if (driver.restarts >= crash_loop_cap) {
|
if (driver.restarts >= crash_loop_cap) {
|
||||||
driver.state = .failed;
|
driver.state = .failed;
|
||||||
writeLine("system/services/device-manager: {s} is failing repeatedly (crash loop); giving up\n", .{driver.name()});
|
writeLine("/system/services/device-manager: {s} is failing repeatedly (crash loop); giving up\n", .{driver.name()});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const delay_ms = backoff_base_ms << @intCast(driver.restarts - 1);
|
const delay_ms = backoff_base_ms << @intCast(driver.restarts - 1);
|
||||||
driver.state = .restarting;
|
driver.state = .restarting;
|
||||||
driver.restart_due_ns = now + delay_ms * 1_000_000;
|
driver.restart_due_ns = now + delay_ms * 1_000_000;
|
||||||
writeLine("system/services/device-manager: restarting {s} in {d} ms (died: {s})\n", .{ driver.name(), delay_ms, @tagName(reason) });
|
writeLine("/system/services/device-manager: restarting {s} in {d} ms (died: {s})\n", .{ driver.name(), delay_ms, @tagName(reason) });
|
||||||
_ = system.timerOnce(manager_endpoint, delay_ms + 50);
|
_ = system.timerOnce(manager_endpoint, delay_ms + 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,7 +306,7 @@ fn onDriverExit(driver: *Driver) void {
|
|||||||
fn sweepDeadlines() void {
|
fn sweepDeadlines() void {
|
||||||
const now = system.clock();
|
const now = system.clock();
|
||||||
if (test_kill_pid != 0 and now >= test_kill_due_ns) {
|
if (test_kill_pid != 0 and now >= test_kill_due_ns) {
|
||||||
writeLine("system/services/device-manager: test mode: killing the reporter\n", .{});
|
writeLine("/system/services/device-manager: test mode: killing the reporter\n", .{});
|
||||||
_ = system.kill(test_kill_pid);
|
_ = system.kill(test_kill_pid);
|
||||||
test_kill_pid = 0;
|
test_kill_pid = 0;
|
||||||
}
|
}
|
||||||
@@ -314,7 +314,7 @@ fn sweepDeadlines() void {
|
|||||||
if (!driver.used) continue;
|
if (!driver.used) continue;
|
||||||
switch (driver.state) {
|
switch (driver.state) {
|
||||||
.awaiting_hello => if (now >= driver.hello_deadline_ns) {
|
.awaiting_hello => if (now >= driver.hello_deadline_ns) {
|
||||||
writeLine("system/services/device-manager: {s} missed its hello deadline\n", .{driver.name()});
|
writeLine("/system/services/device-manager: {s} missed its hello deadline\n", .{driver.name()});
|
||||||
_ = system.kill(driver.process_id);
|
_ = system.kill(driver.process_id);
|
||||||
// The exit notification finishes the job via onDriverExit.
|
// The exit notification finishes the job via onDriverExit.
|
||||||
},
|
},
|
||||||
@@ -331,7 +331,7 @@ fn initialise(endpoint: runtime.ipc.Handle) bool {
|
|||||||
|
|
||||||
// Enumerate into a heap buffer (too big for the one-page user stack).
|
// Enumerate into a heap buffer (too big for the one-page user stack).
|
||||||
const buffer = runtime.allocator().alloc(device.DeviceDescriptor, 64) catch {
|
const buffer = runtime.allocator().alloc(device.DeviceDescriptor, 64) catch {
|
||||||
_ = runtime.system.write("system/services/device-manager: out of memory\n");
|
_ = runtime.system.write("/system/services/device-manager: out of memory\n");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
const total = device.enumerate(buffer);
|
const total = device.enumerate(buffer);
|
||||||
@@ -372,9 +372,9 @@ fn initialise(endpoint: runtime.ipc.Handle) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (matched == 0) {
|
if (matched == 0) {
|
||||||
_ = runtime.system.write("system/services/device-manager: no matchable devices\n");
|
_ = runtime.system.write("/system/services/device-manager: no matchable devices\n");
|
||||||
} else {
|
} else {
|
||||||
_ = runtime.system.write("system/services/device-manager: ok\n");
|
_ = runtime.system.write("/system/services/device-manager: ok\n");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -395,13 +395,13 @@ fn onMessage(message: []const u8, reply: []u8, sender: u32, capability: ?runtime
|
|||||||
var status: i32 = 0;
|
var status: i32 = 0;
|
||||||
if (hello.version != protocol.version) {
|
if (hello.version != protocol.version) {
|
||||||
status = -1;
|
status = -1;
|
||||||
writeLine("system/services/device-manager: refused hello (version {d}) from process {d}\n", .{ hello.version, sender });
|
writeLine("/system/services/device-manager: refused hello (version {d}) from process {d}\n", .{ hello.version, sender });
|
||||||
} else if (driverByProcess(sender)) |driver| {
|
} else if (driverByProcess(sender)) |driver| {
|
||||||
driver.state = .running;
|
driver.state = .running;
|
||||||
writeLine("system/services/device-manager: hello from {s} (device {d})\n", .{ driver.name(), hello.device_id });
|
writeLine("/system/services/device-manager: hello from {s} (device {d})\n", .{ driver.name(), hello.device_id });
|
||||||
} else {
|
} else {
|
||||||
status = -1;
|
status = -1;
|
||||||
writeLine("system/services/device-manager: hello from unknown process {d}\n", .{sender});
|
writeLine("/system/services/device-manager: hello from unknown process {d}\n", .{sender});
|
||||||
}
|
}
|
||||||
const hello_reply = protocol.HelloReply{ .status = status };
|
const hello_reply = protocol.HelloReply{ .status = status };
|
||||||
@memcpy(reply[0..protocol.reply_size], std.mem.asBytes(&hello_reply));
|
@memcpy(reply[0..protocol.reply_size], std.mem.asBytes(&hello_reply));
|
||||||
@@ -417,7 +417,7 @@ fn onChildAdded(message: []const u8, reply: []u8, sender: u32) usize {
|
|||||||
var status: i32 = 0;
|
var status: i32 = 0;
|
||||||
if (driverByProcess(sender)) |driver| {
|
if (driverByProcess(sender)) |driver| {
|
||||||
if (!addChild(report.parent, report.bus_address, report.identity, report.device_id, sender)) status = -1;
|
if (!addChild(report.parent, report.bus_address, report.identity, report.device_id, sender)) status = -1;
|
||||||
writeLine("system/services/device-manager: child added (device {d} port {d}, identity {d}) by {s}\n", .{ report.parent, report.bus_address, report.identity, driver.name() });
|
writeLine("/system/services/device-manager: child added (device {d} port {d}, identity {d}) by {s}\n", .{ report.parent, report.bus_address, report.identity, driver.name() });
|
||||||
if (status == 0) publishEvent(message[0..protocol.child_added_size]);
|
if (status == 0) publishEvent(message[0..protocol.child_added_size]);
|
||||||
// Matching from reports (M19.3): a registered child whose identity
|
// Matching from reports (M19.3): a registered child whose identity
|
||||||
// names a driver gets one, once — re-reports after a bus restart
|
// names a driver gets one, once — re-reports after a bus restart
|
||||||
@@ -478,7 +478,7 @@ fn onChildRemoved(message: []const u8, reply: []u8, sender: u32) usize {
|
|||||||
var status: i32 = -1;
|
var status: i32 = -1;
|
||||||
for (&children) |*child| {
|
for (&children) |*child| {
|
||||||
if (child.used and child.parent == report.parent and child.bus_address == report.bus_address and child.reporter == sender) {
|
if (child.used and child.parent == report.parent and child.bus_address == report.bus_address and child.reporter == sender) {
|
||||||
writeLine("system/services/device-manager: child removed (device {d} port {d})\n", .{ child.parent, child.bus_address });
|
writeLine("/system/services/device-manager: child removed (device {d} port {d})\n", .{ child.parent, child.bus_address });
|
||||||
child.used = false;
|
child.used = false;
|
||||||
status = 0;
|
status = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ pub fn main() void {
|
|||||||
// the extern malloc/free symbols; Zig code uses this allocator.)
|
// the extern malloc/free symbols; Zig code uses this allocator.)
|
||||||
const gpa = runtime.allocator();
|
const gpa = runtime.allocator();
|
||||||
if (gpa.alloc(u8, 64)) |buffer| {
|
if (gpa.alloc(u8, 64)) |buffer| {
|
||||||
const message = "system/services/init:: heap ok\n";
|
const message = "/system/services/init: heap ok\n";
|
||||||
@memcpy(buffer[0..message.len], message);
|
@memcpy(buffer[0..message.len], message);
|
||||||
_ = runtime.system.write(buffer[0..message.len]);
|
_ = runtime.system.write(buffer[0..message.len]);
|
||||||
gpa.free(buffer);
|
gpa.free(buffer);
|
||||||
@@ -42,7 +42,7 @@ pub fn main() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
_ = runtime.system.write("system/services/init:: heartbeat\n");
|
_ = runtime.system.write("/system/services/init: heartbeat\n");
|
||||||
runtime.system.sleep(1000);
|
runtime.system.sleep(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,14 +115,14 @@ fn handle(message: []const u8, got: ipc.Received, out: []u8) usize {
|
|||||||
|
|
||||||
pub fn main() void {
|
pub fn main() void {
|
||||||
const endpoint = ipc.createIpcEndpoint() orelse {
|
const endpoint = ipc.createIpcEndpoint() orelse {
|
||||||
_ = system.write("system/services/input: no endpoint\n");
|
_ = system.write("/system/services/input: no endpoint\n");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if (!ipc.register(.input, endpoint)) {
|
if (!ipc.register(.input, endpoint)) {
|
||||||
_ = system.write("system/services/input: register failed\n");
|
_ = system.write("/system/services/input: register failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_ = system.write("system/services/input: ready\n");
|
_ = system.write("/system/services/input: ready\n");
|
||||||
|
|
||||||
var reply_buffer: [protocol.reply_size]u8 = undefined;
|
var reply_buffer: [protocol.reply_size]u8 = undefined;
|
||||||
var reply_len: usize = 0;
|
var reply_len: usize = 0;
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ fn releaseClientHandles(client: u32) void {
|
|||||||
released += 1;
|
released += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (released != 0) writeLine("system/services/vfs: released {d} handle(s) for dead client {d}\n", .{ released, client });
|
if (released != 0) writeLine("/system/services/vfs: released {d} handle(s) for dead client {d}\n", .{ released, client });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle one request from `sender`; write the reply into `out`, return its length.
|
/// Handle one request from `sender`; write the reply into `out`, return its length.
|
||||||
@@ -144,9 +144,9 @@ fn handle(message: []const u8, out: []u8, sender: u32, capability: ?runtime.ipc.
|
|||||||
/// to release them (docs/process-lifecycle.md).
|
/// to release them (docs/process-lifecycle.md).
|
||||||
fn initialise(endpoint: runtime.ipc.Handle) bool {
|
fn initialise(endpoint: runtime.ipc.Handle) bool {
|
||||||
if (!runtime.process.subscribeExits(endpoint)) {
|
if (!runtime.process.subscribeExits(endpoint)) {
|
||||||
_ = runtime.system.write("system/services/vfs: exit subscription failed\n");
|
_ = runtime.system.write("/system/services/vfs: exit subscription failed\n");
|
||||||
}
|
}
|
||||||
_ = runtime.system.write("system/services/vfs: ready\n");
|
_ = runtime.system.write("/system/services/vfs: ready\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user