reorg: normalise every protocol alias to its module name
Finish the direct-import convention: a protocol is now aliased to its module name in snake_case in every file that imports one — consumers and the runtime client wrappers alike. This kills the last of the alias variety (the generic `protocol`, plus `power` and `transfer`), so `device_manager_protocol.Hello` means the same thing everywhere and grepping a module name finds all its uses. Pure rename (identifier uses only; prose references left untouched via a guarded pattern). 14 files, 299/299 lines. zig build + test green; 16 QEMU cases pass (smoke, device-manager, driver-restart, device-list, pci-scan, usb-hid, usb-storage, display-service, display-native, display-reattach, input, acpi-ps2, vfs, fat-mount, power-button, orderly-shutdown).
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
|
||||
const std = @import("std");
|
||||
const runtime = @import("runtime");
|
||||
const protocol = @import("device-manager-protocol");
|
||||
const device_manager_protocol = @import("device-manager-protocol");
|
||||
const device = runtime.device;
|
||||
const pci_class = @import("pci-class");
|
||||
|
||||
@@ -32,7 +32,7 @@ fn logFunction(bus: u64, dev: u64, function: u64, class_triple: u32) void {
|
||||
_ = runtime.system.write(text);
|
||||
}
|
||||
|
||||
var bridge_id: u64 = protocol.no_device;
|
||||
var bridge_id: u64 = device_manager_protocol.no_device;
|
||||
var ecam_base: usize = 0;
|
||||
var ecam_physical: u64 = 0;
|
||||
var start_bus: u64 = 0;
|
||||
@@ -209,13 +209,13 @@ fn registerAndReport(bus: u64, dev: u64, function: u64, class_triple: u32) void
|
||||
std.log.info("register refused for {d}:{d}.{d}", .{ bus, dev, function });
|
||||
return;
|
||||
};
|
||||
const report = protocol.ChildAdded{
|
||||
const report = device_manager_protocol.ChildAdded{
|
||||
.parent = bridge_id,
|
||||
.bus_address = (bus << 8) | (dev << 3) | function,
|
||||
.identity = class_triple,
|
||||
.device_id = registered,
|
||||
};
|
||||
var reply: [protocol.message_maximum]u8 = undefined;
|
||||
var reply: [device_manager_protocol.message_maximum]u8 = undefined;
|
||||
_ = runtime.ipc.call(manager_handle, std.mem.asBytes(&report), &reply) catch {
|
||||
std.log.info("child report for {d}:{d}.{d} failed", .{ bus, dev, function });
|
||||
};
|
||||
@@ -235,7 +235,7 @@ pub fn main(init: runtime.process.Init) void {
|
||||
std.log.info("malformed bridge device id '{s}'", .{argument});
|
||||
return;
|
||||
};
|
||||
runtime.service.run(protocol.message_maximum, .{
|
||||
runtime.service.run(device_manager_protocol.message_maximum, .{
|
||||
.init = initialise,
|
||||
.on_message = onMessage,
|
||||
});
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
|
||||
const std = @import("std");
|
||||
const runtime = @import("runtime");
|
||||
const protocol = @import("device-manager-protocol");
|
||||
const device_manager_protocol = @import("device-manager-protocol");
|
||||
const device = runtime.device;
|
||||
const usb_ids = @import("usb-ids");
|
||||
const usb_abi = @import("usb-abi");
|
||||
const transfer = @import("usb-transfer-protocol");
|
||||
const usb_transfer_protocol = @import("usb-transfer-protocol");
|
||||
const library = @import("usb-xhci-library.zig");
|
||||
|
||||
/// The controller engine (reset, rings, transfers), stood up in `initialise`.
|
||||
@@ -64,7 +64,7 @@ fn reportEndpointFor(device_token: u64) ?usize {
|
||||
return null;
|
||||
}
|
||||
|
||||
var controller_id: u64 = protocol.no_device;
|
||||
var controller_id: u64 = device_manager_protocol.no_device;
|
||||
|
||||
/// Claim the assigned controller, find its register window, and hello the
|
||||
/// manager. Any failure returns false: the process exits cleanly, which the
|
||||
@@ -300,11 +300,11 @@ fn tearDownHubDevice(manager: runtime.ipc.Handle, engine: *library.Controller, d
|
||||
const key = hubPortKey(dev.parent_slot, dev.parent_port);
|
||||
for (dev.interfaces[0..dev.interface_count]) |*interface| {
|
||||
if (interface.registered_device_id == 0) continue;
|
||||
const event = protocol.ChildRemoved{
|
||||
const event = device_manager_protocol.ChildRemoved{
|
||||
.parent = controller_id,
|
||||
.bus_address = (@as(u64, key) << 8) | interface.number,
|
||||
};
|
||||
var reply: [protocol.message_maximum]u8 = undefined;
|
||||
var reply: [device_manager_protocol.message_maximum]u8 = undefined;
|
||||
_ = runtime.ipc.call(manager, std.mem.asBytes(&event), &reply) catch {};
|
||||
interface.registered_device_id = 0;
|
||||
}
|
||||
@@ -330,11 +330,11 @@ fn tearDownPort(manager: runtime.ipc.Handle, engine: *library.Controller, port:
|
||||
std.log.info("port {d} disconnected", .{port});
|
||||
for (usb_device.interfaces[0..usb_device.interface_count]) |*interface| {
|
||||
if (interface.registered_device_id == 0) continue;
|
||||
const event = protocol.ChildRemoved{
|
||||
const event = device_manager_protocol.ChildRemoved{
|
||||
.parent = controller_id,
|
||||
.bus_address = (@as(u64, port) << 8) | interface.number,
|
||||
};
|
||||
var reply: [protocol.message_maximum]u8 = undefined;
|
||||
var reply: [device_manager_protocol.message_maximum]u8 = undefined;
|
||||
_ = runtime.ipc.call(manager, std.mem.asBytes(&event), &reply) catch {
|
||||
std.log.info("child-removed report for port {d} interface {d} failed", .{ port, interface.number });
|
||||
};
|
||||
@@ -371,13 +371,13 @@ fn reportInterface(manager: runtime.ipc.Handle, port: u32, interface: library.In
|
||||
return null;
|
||||
};
|
||||
|
||||
const report = protocol.ChildAdded{
|
||||
const report = device_manager_protocol.ChildAdded{
|
||||
.parent = controller_id,
|
||||
.bus_address = (@as(u64, port) << 8) | interface.number,
|
||||
.identity = identity,
|
||||
.device_id = registered,
|
||||
};
|
||||
var reply: [protocol.message_maximum]u8 = undefined;
|
||||
var reply: [device_manager_protocol.message_maximum]u8 = undefined;
|
||||
_ = runtime.ipc.call(manager, std.mem.asBytes(&report), &reply) catch {
|
||||
std.log.info("child report for port {d} interface {d} failed", .{ port, interface.number });
|
||||
return null;
|
||||
@@ -401,10 +401,10 @@ fn onMessage(message: []const u8, reply: []u8, sender: u32, capability: ?runtime
|
||||
if (message.len < 4) return 0;
|
||||
const operation = std.mem.readInt(u32, message[0..4], .little);
|
||||
return switch (operation) {
|
||||
@intFromEnum(transfer.Operation.open) => handleOpen(message, reply, capability),
|
||||
@intFromEnum(transfer.Operation.control) => handleControl(message, reply),
|
||||
@intFromEnum(transfer.Operation.interrupt_subscribe) => handleSubscribe(message, reply),
|
||||
@intFromEnum(transfer.Operation.bulk) => handleBulk(message, reply),
|
||||
@intFromEnum(usb_transfer_protocol.Operation.open) => handleOpen(message, reply, capability),
|
||||
@intFromEnum(usb_transfer_protocol.Operation.control) => handleControl(message, reply),
|
||||
@intFromEnum(usb_transfer_protocol.Operation.interrupt_subscribe) => handleSubscribe(message, reply),
|
||||
@intFromEnum(usb_transfer_protocol.Operation.bulk) => handleBulk(message, reply),
|
||||
else => 0,
|
||||
};
|
||||
}
|
||||
@@ -419,14 +419,14 @@ fn writeReply(reply: []u8, value: anytype) usize {
|
||||
/// endpoint (for interrupt reports), and answer with a device token + the
|
||||
/// interface's endpoints so the class driver need not re-read the config.
|
||||
fn handleOpen(message: []const u8, reply: []u8, capability: ?runtime.ipc.Handle) usize {
|
||||
if (message.len < @sizeOf(transfer.OpenRequest)) return writeReply(reply, transfer.OpenReply{ .status = -1, .endpoint_count = 0, .device_token = 0, .interface_class = 0, .interface_subclass = 0, .interface_protocol = 0, .interface_number = 0 });
|
||||
const request = std.mem.bytesToValue(transfer.OpenRequest, message[0..@sizeOf(transfer.OpenRequest)]);
|
||||
const engine = if (controller) |*c| c else return writeReply(reply, transfer.OpenReply{ .status = -1, .endpoint_count = 0, .device_token = 0, .interface_class = 0, .interface_subclass = 0, .interface_protocol = 0, .interface_number = 0 });
|
||||
const found = engine.findInterface(request.device_id) orelse return writeReply(reply, transfer.OpenReply{ .status = -1, .endpoint_count = 0, .device_token = 0, .interface_class = 0, .interface_subclass = 0, .interface_protocol = 0, .interface_number = 0 });
|
||||
if (message.len < @sizeOf(usb_transfer_protocol.OpenRequest)) return writeReply(reply, usb_transfer_protocol.OpenReply{ .status = -1, .endpoint_count = 0, .device_token = 0, .interface_class = 0, .interface_subclass = 0, .interface_protocol = 0, .interface_number = 0 });
|
||||
const request = std.mem.bytesToValue(usb_transfer_protocol.OpenRequest, message[0..@sizeOf(usb_transfer_protocol.OpenRequest)]);
|
||||
const engine = if (controller) |*c| c else return writeReply(reply, usb_transfer_protocol.OpenReply{ .status = -1, .endpoint_count = 0, .device_token = 0, .interface_class = 0, .interface_subclass = 0, .interface_protocol = 0, .interface_number = 0 });
|
||||
const found = engine.findInterface(request.device_id) orelse return writeReply(reply, usb_transfer_protocol.OpenReply{ .status = -1, .endpoint_count = 0, .device_token = 0, .interface_class = 0, .interface_subclass = 0, .interface_protocol = 0, .interface_number = 0 });
|
||||
|
||||
if (capability) |endpoint| recordOpen(request.device_id, endpoint);
|
||||
|
||||
var open_reply = transfer.OpenReply{
|
||||
var open_reply = usb_transfer_protocol.OpenReply{
|
||||
.status = 0,
|
||||
.endpoint_count = found.interface.endpoint_count,
|
||||
.device_token = request.device_id,
|
||||
@@ -435,7 +435,7 @@ fn handleOpen(message: []const u8, reply: []u8, capability: ?runtime.ipc.Handle)
|
||||
.interface_protocol = found.interface.protocol,
|
||||
.interface_number = found.interface.number,
|
||||
};
|
||||
const count = @min(found.interface.endpoint_count, transfer.max_reported_endpoints);
|
||||
const count = @min(found.interface.endpoint_count, usb_transfer_protocol.max_reported_endpoints);
|
||||
for (found.interface.endpoints[0..count], 0..) |endpoint, index| {
|
||||
open_reply.endpoints[index] = .{
|
||||
.address = endpoint.address,
|
||||
@@ -449,45 +449,45 @@ fn handleOpen(message: []const u8, reply: []u8, capability: ?runtime.ipc.Handle)
|
||||
|
||||
/// control: one EP0 control transfer, small data inline both ways.
|
||||
fn handleControl(message: []const u8, reply: []u8) usize {
|
||||
if (message.len < @sizeOf(transfer.ControlRequest)) return writeReply(reply, transfer.ControlReply{ .status = -1, .actual_length = 0 });
|
||||
const request = std.mem.bytesToValue(transfer.ControlRequest, message[0..@sizeOf(transfer.ControlRequest)]);
|
||||
const engine = if (controller) |*c| c else return writeReply(reply, transfer.ControlReply{ .status = -1, .actual_length = 0 });
|
||||
const found = engine.findInterface(request.device_token) orelse return writeReply(reply, transfer.ControlReply{ .status = -1, .actual_length = 0 });
|
||||
if (message.len < @sizeOf(usb_transfer_protocol.ControlRequest)) return writeReply(reply, usb_transfer_protocol.ControlReply{ .status = -1, .actual_length = 0 });
|
||||
const request = std.mem.bytesToValue(usb_transfer_protocol.ControlRequest, message[0..@sizeOf(usb_transfer_protocol.ControlRequest)]);
|
||||
const engine = if (controller) |*c| c else return writeReply(reply, usb_transfer_protocol.ControlReply{ .status = -1, .actual_length = 0 });
|
||||
const found = engine.findInterface(request.device_token) orelse return writeReply(reply, usb_transfer_protocol.ControlReply{ .status = -1, .actual_length = 0 });
|
||||
|
||||
const setup = std.mem.bytesToValue(usb_abi.Request, &request.setup);
|
||||
const direction_in = request.direction_in != 0;
|
||||
const data_length = @min(request.data_length, transfer.max_inline_data);
|
||||
var data: [transfer.max_inline_data]u8 = undefined;
|
||||
const data_length = @min(request.data_length, usb_transfer_protocol.max_inline_data);
|
||||
var data: [usb_transfer_protocol.max_inline_data]u8 = undefined;
|
||||
if (!direction_in) @memcpy(data[0..data_length], request.data[0..data_length]);
|
||||
|
||||
const ok = engine.controlTransfer(found.device, setup, data[0..data_length], direction_in);
|
||||
var control_reply = transfer.ControlReply{ .status = if (ok) 0 else -1, .actual_length = if (ok) data_length else 0 };
|
||||
var control_reply = usb_transfer_protocol.ControlReply{ .status = if (ok) 0 else -1, .actual_length = if (ok) data_length else 0 };
|
||||
if (ok and direction_in) @memcpy(control_reply.data[0..data_length], data[0..data_length]);
|
||||
return writeReply(reply, control_reply);
|
||||
}
|
||||
|
||||
/// interrupt_subscribe: arm periodic IN polling; reports flow back asynchronously.
|
||||
fn handleSubscribe(message: []const u8, reply: []u8) usize {
|
||||
if (message.len < @sizeOf(transfer.InterruptSubscribeRequest)) return writeReply(reply, transfer.InterruptSubscribeReply{ .status = -1 });
|
||||
const request = std.mem.bytesToValue(transfer.InterruptSubscribeRequest, message[0..@sizeOf(transfer.InterruptSubscribeRequest)]);
|
||||
const engine = if (controller) |*c| c else return writeReply(reply, transfer.InterruptSubscribeReply{ .status = -1 });
|
||||
const found = engine.findInterface(request.device_token) orelse return writeReply(reply, transfer.InterruptSubscribeReply{ .status = -1 });
|
||||
const endpoint = library.Controller.endpointForAddress(found.interface, request.endpoint_address) orelse return writeReply(reply, transfer.InterruptSubscribeReply{ .status = -1 });
|
||||
const report_endpoint = reportEndpointFor(request.device_token) orelse return writeReply(reply, transfer.InterruptSubscribeReply{ .status = -1 });
|
||||
if (message.len < @sizeOf(usb_transfer_protocol.InterruptSubscribeRequest)) return writeReply(reply, usb_transfer_protocol.InterruptSubscribeReply{ .status = -1 });
|
||||
const request = std.mem.bytesToValue(usb_transfer_protocol.InterruptSubscribeRequest, message[0..@sizeOf(usb_transfer_protocol.InterruptSubscribeRequest)]);
|
||||
const engine = if (controller) |*c| c else return writeReply(reply, usb_transfer_protocol.InterruptSubscribeReply{ .status = -1 });
|
||||
const found = engine.findInterface(request.device_token) orelse return writeReply(reply, usb_transfer_protocol.InterruptSubscribeReply{ .status = -1 });
|
||||
const endpoint = library.Controller.endpointForAddress(found.interface, request.endpoint_address) orelse return writeReply(reply, usb_transfer_protocol.InterruptSubscribeReply{ .status = -1 });
|
||||
const report_endpoint = reportEndpointFor(request.device_token) orelse return writeReply(reply, usb_transfer_protocol.InterruptSubscribeReply{ .status = -1 });
|
||||
const ok = engine.subscribeInterrupt(found.device, endpoint, request.device_token, report_endpoint);
|
||||
return writeReply(reply, transfer.InterruptSubscribeReply{ .status = if (ok) 0 else -1 });
|
||||
return writeReply(reply, usb_transfer_protocol.InterruptSubscribeReply{ .status = if (ok) 0 else -1 });
|
||||
}
|
||||
|
||||
/// bulk: one bulk transfer to/from the class driver's own DMA buffer (by physical
|
||||
/// address), so sector-sized data never crosses IPC.
|
||||
fn handleBulk(message: []const u8, reply: []u8) usize {
|
||||
if (message.len < @sizeOf(transfer.BulkRequest)) return writeReply(reply, transfer.BulkReply{ .status = -1, .actual_length = 0 });
|
||||
const request = std.mem.bytesToValue(transfer.BulkRequest, message[0..@sizeOf(transfer.BulkRequest)]);
|
||||
const engine = if (controller) |*c| c else return writeReply(reply, transfer.BulkReply{ .status = -1, .actual_length = 0 });
|
||||
const found = engine.findInterface(request.device_token) orelse return writeReply(reply, transfer.BulkReply{ .status = -1, .actual_length = 0 });
|
||||
const endpoint = library.Controller.endpointForAddress(found.interface, request.endpoint_address) orelse return writeReply(reply, transfer.BulkReply{ .status = -1, .actual_length = 0 });
|
||||
if (message.len < @sizeOf(usb_transfer_protocol.BulkRequest)) return writeReply(reply, usb_transfer_protocol.BulkReply{ .status = -1, .actual_length = 0 });
|
||||
const request = std.mem.bytesToValue(usb_transfer_protocol.BulkRequest, message[0..@sizeOf(usb_transfer_protocol.BulkRequest)]);
|
||||
const engine = if (controller) |*c| c else return writeReply(reply, usb_transfer_protocol.BulkReply{ .status = -1, .actual_length = 0 });
|
||||
const found = engine.findInterface(request.device_token) orelse return writeReply(reply, usb_transfer_protocol.BulkReply{ .status = -1, .actual_length = 0 });
|
||||
const endpoint = library.Controller.endpointForAddress(found.interface, request.endpoint_address) orelse return writeReply(reply, usb_transfer_protocol.BulkReply{ .status = -1, .actual_length = 0 });
|
||||
const transferred = engine.bulkTransfer(found.device, endpoint, request.physical_address, request.length);
|
||||
return writeReply(reply, transfer.BulkReply{ .status = if (transferred != null) 0 else -1, .actual_length = transferred orelse 0 });
|
||||
return writeReply(reply, usb_transfer_protocol.BulkReply{ .status = if (transferred != null) 0 else -1, .actual_length = transferred orelse 0 });
|
||||
}
|
||||
|
||||
/// The poll timer landed: drain any interrupt reports off the event ring and push
|
||||
@@ -543,12 +543,12 @@ fn onNotification(badge: u64) void {
|
||||
if (serviced >= 32) break;
|
||||
}
|
||||
while (engine.takeReport()) |report| {
|
||||
var message = transfer.InterruptReport{
|
||||
var message = usb_transfer_protocol.InterruptReport{
|
||||
.device_token = report.device_token,
|
||||
.endpoint_address = report.endpoint_address,
|
||||
.length = @intCast(@min(report.length, transfer.max_report_data)),
|
||||
.length = @intCast(@min(report.length, usb_transfer_protocol.max_report_data)),
|
||||
};
|
||||
const n = @min(report.length, transfer.max_report_data);
|
||||
const n = @min(report.length, usb_transfer_protocol.max_report_data);
|
||||
@memcpy(message.data[0..n], report.data[0..n]);
|
||||
_ = runtime.ipc.send(report.report_endpoint, std.mem.asBytes(&message));
|
||||
}
|
||||
@@ -565,7 +565,7 @@ pub fn main(init: runtime.process.Init) void {
|
||||
std.log.info("malformed controller device id '{s}'", .{argument});
|
||||
return;
|
||||
};
|
||||
runtime.service.run(transfer.message_maximum, .{
|
||||
runtime.service.run(usb_transfer_protocol.message_maximum, .{
|
||||
.service = .usb_bus,
|
||||
.init = initialise,
|
||||
.on_message = onMessage,
|
||||
|
||||
@@ -15,8 +15,8 @@ const runtime = @import("runtime");
|
||||
const aml = @import("aml");
|
||||
const acpi_ids = @import("acpi-ids");
|
||||
const device = runtime.device;
|
||||
const protocol = @import("device-manager-protocol");
|
||||
const power = @import("power-protocol");
|
||||
const device_manager_protocol = @import("device-manager-protocol");
|
||||
const power_protocol = @import("power-protocol");
|
||||
/// AML opcode/prefix bytes by name (`zero_opcode`, `byte_prefix`, …) — so the `_HID`
|
||||
/// integer decode names the opcodes instead of bare 0x0A/0x0B/… (docs/coding-standards.md).
|
||||
const opcodes = aml.opcodes;
|
||||
@@ -184,7 +184,7 @@ pub fn main(init: runtime.process.Init) void {
|
||||
readFadt(fadt);
|
||||
s5_valid = readSleepS5(&persistent_namespace);
|
||||
|
||||
runtime.service.run(power.message_maximum, .{
|
||||
runtime.service.run(power_protocol.message_maximum, .{
|
||||
.service = .power,
|
||||
.init = onInit,
|
||||
.on_message = onMessage,
|
||||
@@ -215,9 +215,9 @@ fn onInit(endpoint: runtime.ipc.Handle) bool {
|
||||
else
|
||||
std.log.info("reported {s} (device {d}, {d} resources)", .{ hid, entry.device_id, entry.resource_count });
|
||||
if (manager) |h| {
|
||||
var report = protocol.ChildAdded{ .parent = node_id, .bus_address = entry.device_id, .identity = 0, .device_id = entry.device_id };
|
||||
var report = device_manager_protocol.ChildAdded{ .parent = node_id, .bus_address = entry.device_id, .identity = 0, .device_id = entry.device_id };
|
||||
@memcpy(report.hid[0..entry.hid_len], entry.hid[0..entry.hid_len]);
|
||||
var reply: [protocol.message_maximum]u8 = undefined;
|
||||
var reply: [device_manager_protocol.message_maximum]u8 = undefined;
|
||||
_ = runtime.ipc.call(h, std.mem.asBytes(&report), &reply) catch {};
|
||||
}
|
||||
}
|
||||
@@ -365,8 +365,8 @@ fn publishNotify(node: *aml.Node, code: u64) void {
|
||||
// Map the notified device's _HID to a domain event where we recognize it.
|
||||
var hid: [8]u8 = .{0} ** 8;
|
||||
if (readHid(node, &global_interpreter)) |h| hid = h;
|
||||
const which: power.Event = if (std.mem.eql(u8, hid[0..7], "PNP0C0A")) .battery else if (std.mem.eql(u8, hid[0..7], "ACPI0003")) .ac else if (std.mem.eql(u8, hid[0..7], "PNP0C0D")) .lid else .notify;
|
||||
var event = power.EventMessage{ .event = @intFromEnum(which), .code = @truncate(code) };
|
||||
const which: power_protocol.Event = if (std.mem.eql(u8, hid[0..7], "PNP0C0A")) .battery else if (std.mem.eql(u8, hid[0..7], "ACPI0003")) .ac else if (std.mem.eql(u8, hid[0..7], "PNP0C0D")) .lid else .notify;
|
||||
var event = power_protocol.EventMessage{ .event = @intFromEnum(which), .code = @truncate(code) };
|
||||
event.hid = hid;
|
||||
std.log.info("power: notify {s} code {d}", .{ hid[0..7], code });
|
||||
publishEvent(std.mem.asBytes(&event));
|
||||
@@ -380,7 +380,7 @@ fn writeHex2(out: []u8, n: u32) void {
|
||||
}
|
||||
|
||||
fn publishButton() void {
|
||||
const event = power.EventMessage{ .event = @intFromEnum(power.Event.power_button) };
|
||||
const event = power_protocol.EventMessage{ .event = @intFromEnum(power_protocol.Event.power_button) };
|
||||
publishEvent(std.mem.asBytes(&event));
|
||||
}
|
||||
|
||||
@@ -429,7 +429,7 @@ fn onNotification(badge: u64) void {
|
||||
fn onMessage(message: []const u8, reply: []u8, sender: u32, capability: ?runtime.ipc.Handle) usize {
|
||||
if (message.len < 1) return 0;
|
||||
switch (message[0]) {
|
||||
@intFromEnum(power.Operation.subscribe) => {
|
||||
@intFromEnum(power_protocol.Operation.subscribe) => {
|
||||
var status: i32 = -1;
|
||||
if (capability) |handle| {
|
||||
for (&subscribers, 0..) |*slot, si| {
|
||||
@@ -441,20 +441,20 @@ fn onMessage(message: []const u8, reply: []u8, sender: u32, capability: ?runtime
|
||||
}
|
||||
}
|
||||
}
|
||||
const r = power.Reply{ .status = status };
|
||||
@memcpy(reply[0..@sizeOf(power.Reply)], std.mem.asBytes(&r));
|
||||
return @sizeOf(power.Reply);
|
||||
const r = power_protocol.Reply{ .status = status };
|
||||
@memcpy(reply[0..@sizeOf(power_protocol.Reply)], std.mem.asBytes(&r));
|
||||
return @sizeOf(power_protocol.Reply);
|
||||
},
|
||||
@intFromEnum(power.Operation.shutdown) => {
|
||||
@intFromEnum(power_protocol.Operation.shutdown) => {
|
||||
// Honored only from a power subscriber — init, which has already run
|
||||
// the stop sequence over everything else. The power service is
|
||||
// mechanism (write S5); deciding *when* to shut down and stopping
|
||||
// the rest of the system first is init's policy.
|
||||
const allowed = isSubscriber(sender);
|
||||
const r = power.Reply{ .status = if (allowed) 0 else -1 };
|
||||
@memcpy(reply[0..@sizeOf(power.Reply)], std.mem.asBytes(&r));
|
||||
const r = power_protocol.Reply{ .status = if (allowed) 0 else -1 };
|
||||
@memcpy(reply[0..@sizeOf(power_protocol.Reply)], std.mem.asBytes(&r));
|
||||
if (allowed) enterS5();
|
||||
return @sizeOf(power.Reply);
|
||||
return @sizeOf(power_protocol.Reply);
|
||||
},
|
||||
else => return 0,
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
const std = @import("std");
|
||||
const runtime = @import("runtime");
|
||||
const protocol = @import("device-manager-protocol");
|
||||
const device_manager_protocol = @import("device-manager-protocol");
|
||||
|
||||
pub fn main(init: runtime.process.Init) void {
|
||||
const argument = init.arguments.get(1) orelse return; // bare: stay silent
|
||||
@@ -29,8 +29,8 @@ pub fn main(init: runtime.process.Init) void {
|
||||
if (manager == null) runtime.system.sleep(20);
|
||||
}
|
||||
const h = manager orelse return;
|
||||
const hello = protocol.Hello{ .role = @intFromEnum(protocol.Role.device), .device_id = assigned };
|
||||
var reply: [protocol.message_maximum]u8 = undefined;
|
||||
const hello = device_manager_protocol.Hello{ .role = @intFromEnum(device_manager_protocol.Role.device), .device_id = assigned };
|
||||
var reply: [device_manager_protocol.message_maximum]u8 = undefined;
|
||||
_ = runtime.ipc.call(h, std.mem.asBytes(&hello), &reply) catch return;
|
||||
|
||||
_ = runtime.system.write("crash-test: faulting now\n");
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
const std = @import("std");
|
||||
const runtime = @import("runtime");
|
||||
const protocol = @import("device-manager-protocol");
|
||||
const device_manager_protocol = @import("device-manager-protocol");
|
||||
|
||||
fn writeLine(comptime fmt: []const u8, arguments: anytype) void {
|
||||
var line: [96]u8 = undefined;
|
||||
@@ -27,26 +27,26 @@ pub fn main() void {
|
||||
|
||||
// The snapshot — polled briefly, because at boot the bus drivers may still
|
||||
// be scanning: an empty first answer usually just means "too early".
|
||||
var reply: [protocol.message_maximum]u8 = undefined;
|
||||
var reply: [device_manager_protocol.message_maximum]u8 = undefined;
|
||||
var count: u32 = 0;
|
||||
var length: usize = 0;
|
||||
tries = 0;
|
||||
while (tries < 20) : (tries += 1) {
|
||||
const request = protocol.Enumerate{};
|
||||
const request = device_manager_protocol.Enumerate{};
|
||||
length = runtime.ipc.call(h, std.mem.asBytes(&request), &reply) catch 0;
|
||||
if (length >= @sizeOf(protocol.EnumerateReply)) {
|
||||
count = std.mem.bytesToValue(protocol.EnumerateReply, reply[0..@sizeOf(protocol.EnumerateReply)]).count;
|
||||
if (length >= @sizeOf(device_manager_protocol.EnumerateReply)) {
|
||||
count = std.mem.bytesToValue(device_manager_protocol.EnumerateReply, reply[0..@sizeOf(device_manager_protocol.EnumerateReply)]).count;
|
||||
if (count != 0) break;
|
||||
}
|
||||
runtime.system.sleep(100);
|
||||
}
|
||||
writeLine("device-list: {d} devices\n", .{count});
|
||||
var offset: usize = @sizeOf(protocol.EnumerateReply);
|
||||
var offset: usize = @sizeOf(device_manager_protocol.EnumerateReply);
|
||||
var index: u32 = 0;
|
||||
while (index < count and offset + @sizeOf(protocol.ChildEntry) <= length) : (index += 1) {
|
||||
const entry = std.mem.bytesToValue(protocol.ChildEntry, reply[offset..][0..@sizeOf(protocol.ChildEntry)]);
|
||||
while (index < count and offset + @sizeOf(device_manager_protocol.ChildEntry) <= length) : (index += 1) {
|
||||
const entry = std.mem.bytesToValue(device_manager_protocol.ChildEntry, reply[offset..][0..@sizeOf(device_manager_protocol.ChildEntry)]);
|
||||
writeLine("device-list: device {d} port {d} identity {d}\n", .{ entry.parent, entry.bus_address, entry.identity });
|
||||
offset += @sizeOf(protocol.ChildEntry);
|
||||
offset += @sizeOf(device_manager_protocol.ChildEntry);
|
||||
}
|
||||
|
||||
// The subscription: our endpoint rides as the call's capability; events
|
||||
@@ -55,26 +55,26 @@ pub fn main() void {
|
||||
_ = runtime.system.write("device-list: no endpoint\n");
|
||||
return;
|
||||
};
|
||||
const subscribe = protocol.Subscribe{};
|
||||
const subscribe = device_manager_protocol.Subscribe{};
|
||||
_ = runtime.ipc.callCap(h, std.mem.asBytes(&subscribe), &reply, endpoint) catch {
|
||||
_ = runtime.system.write("device-list: subscribe failed\n");
|
||||
return;
|
||||
};
|
||||
_ = runtime.system.write("device-list: subscribed\n");
|
||||
|
||||
var receive: [protocol.message_maximum]u8 = undefined;
|
||||
var receive: [device_manager_protocol.message_maximum]u8 = undefined;
|
||||
while (true) {
|
||||
const got = runtime.ipc.replyWait(endpoint, &.{}, &receive, null);
|
||||
if (!got.isMessage() or got.len < 1) continue;
|
||||
switch (receive[0]) {
|
||||
@intFromEnum(protocol.Operation.child_added) => {
|
||||
if (got.len < protocol.child_added_size) continue;
|
||||
const event = std.mem.bytesToValue(protocol.ChildAdded, receive[0..protocol.child_added_size]);
|
||||
@intFromEnum(device_manager_protocol.Operation.child_added) => {
|
||||
if (got.len < device_manager_protocol.child_added_size) continue;
|
||||
const event = std.mem.bytesToValue(device_manager_protocol.ChildAdded, receive[0..device_manager_protocol.child_added_size]);
|
||||
writeLine("device-list: added (device {d} port {d})\n", .{ event.parent, event.bus_address });
|
||||
},
|
||||
@intFromEnum(protocol.Operation.child_removed) => {
|
||||
if (got.len < protocol.child_removed_size) continue;
|
||||
const event = std.mem.bytesToValue(protocol.ChildRemoved, receive[0..protocol.child_removed_size]);
|
||||
@intFromEnum(device_manager_protocol.Operation.child_removed) => {
|
||||
if (got.len < device_manager_protocol.child_removed_size) continue;
|
||||
const event = std.mem.bytesToValue(device_manager_protocol.ChildRemoved, receive[0..device_manager_protocol.child_removed_size]);
|
||||
writeLine("device-list: removed (device {d} port {d})\n", .{ event.parent, event.bus_address });
|
||||
},
|
||||
else => {},
|
||||
|
||||
@@ -20,7 +20,7 @@ const runtime = @import("runtime");
|
||||
const acpi_ids = @import("acpi-ids");
|
||||
const pci_class = @import("pci-class");
|
||||
const usb_ids = @import("usb-ids");
|
||||
const protocol = @import("device-manager-protocol");
|
||||
const device_manager_protocol = @import("device-manager-protocol");
|
||||
const device = runtime.device;
|
||||
const system = runtime.system;
|
||||
|
||||
@@ -134,8 +134,8 @@ const Driver = struct {
|
||||
used: bool = false,
|
||||
name_buffer: [64]u8 = undefined, // fits a full binary path (abi.maximum_process_name)
|
||||
name_len: usize = 0,
|
||||
// The assigned device id (becomes argv[1]), or protocol.no_device.
|
||||
device_id: u64 = protocol.no_device,
|
||||
// The assigned device id (becomes argv[1]), or device_manager_protocol.no_device.
|
||||
device_id: u64 = device_manager_protocol.no_device,
|
||||
// Whether this driver speaks the protocol (hello expected, deadline
|
||||
// enforced). Legacy drivers (e.g. ps2-bus) are supervised and restarted
|
||||
// but not yet required to hello.
|
||||
@@ -189,7 +189,7 @@ const Child = struct {
|
||||
parent: u64 = 0,
|
||||
bus_address: u64 = 0,
|
||||
identity: u64 = 0,
|
||||
// The kernel device id (registered by the reporter), or protocol.no_device.
|
||||
// The kernel device id (registered by the reporter), or device_manager_protocol.no_device.
|
||||
device_id: u64 = 0,
|
||||
reporter: u32 = 0, // the reporting driver instance's process id
|
||||
};
|
||||
@@ -225,7 +225,7 @@ fn pruneChildrenOf(reporter: u32) void {
|
||||
if (child.used and child.reporter == reporter) {
|
||||
std.log.info("child removed (device {d} port {d})", .{ child.parent, child.bus_address });
|
||||
child.used = false;
|
||||
const event = protocol.ChildRemoved{ .parent = child.parent, .bus_address = child.bus_address };
|
||||
const event = device_manager_protocol.ChildRemoved{ .parent = child.parent, .bus_address = child.bus_address };
|
||||
publishEvent(std.mem.asBytes(&event));
|
||||
}
|
||||
}
|
||||
@@ -280,7 +280,7 @@ fn spawnDriver(driver: *Driver) void {
|
||||
var id_text: [20]u8 = undefined;
|
||||
var arguments: [1][]const u8 = undefined;
|
||||
var argument_count: usize = 0;
|
||||
if (driver.device_id != protocol.no_device) {
|
||||
if (driver.device_id != device_manager_protocol.no_device) {
|
||||
arguments[0] = std.fmt.bufPrint(&id_text, "{d}", .{driver.device_id}) catch return;
|
||||
argument_count = 1;
|
||||
}
|
||||
@@ -298,7 +298,7 @@ fn spawnDriver(driver: *Driver) void {
|
||||
} else {
|
||||
driver.state = .running;
|
||||
}
|
||||
if (driver.device_id != protocol.no_device) {
|
||||
if (driver.device_id != device_manager_protocol.no_device) {
|
||||
std.log.info("spawned {s} for device {d}", .{ driver.name(), driver.device_id });
|
||||
} else {
|
||||
std.log.info("spawned {s}", .{driver.name()});
|
||||
@@ -390,7 +390,7 @@ fn initialise(endpoint: runtime.ipc.Handle) bool {
|
||||
// under the neutral name "discovery", spawned once at startup. It finds and
|
||||
// claims the acpi-tables (or devicetree-blob) node itself. Not a per-device
|
||||
// match — it is the discoverer, not a driver bound to one device.
|
||||
addDriver("discovery", protocol.no_device, false);
|
||||
addDriver("discovery", device_manager_protocol.no_device, false);
|
||||
|
||||
if (test_restart_mode) {
|
||||
// The driver-restart scenario's fixture: claims device 0 (the tree
|
||||
@@ -410,18 +410,18 @@ fn initialise(endpoint: runtime.ipc.Handle) bool {
|
||||
fn onMessage(message: []const u8, reply: []u8, sender: u32, capability: ?runtime.ipc.Handle) usize {
|
||||
if (message.len < 1) return 0;
|
||||
switch (message[0]) {
|
||||
@intFromEnum(protocol.Operation.child_added) => return onChildAdded(message, reply, sender),
|
||||
@intFromEnum(protocol.Operation.child_removed) => return onChildRemoved(message, reply, sender),
|
||||
@intFromEnum(protocol.Operation.enumerate) => return onEnumerate(reply),
|
||||
@intFromEnum(protocol.Operation.subscribe) => return onSubscribe(reply, capability),
|
||||
@intFromEnum(protocol.Operation.hello) => {},
|
||||
@intFromEnum(device_manager_protocol.Operation.child_added) => return onChildAdded(message, reply, sender),
|
||||
@intFromEnum(device_manager_protocol.Operation.child_removed) => return onChildRemoved(message, reply, sender),
|
||||
@intFromEnum(device_manager_protocol.Operation.enumerate) => return onEnumerate(reply),
|
||||
@intFromEnum(device_manager_protocol.Operation.subscribe) => return onSubscribe(reply, capability),
|
||||
@intFromEnum(device_manager_protocol.Operation.hello) => {},
|
||||
else => return 0,
|
||||
}
|
||||
if (message.len < protocol.hello_size) return 0;
|
||||
const hello = std.mem.bytesToValue(protocol.Hello, message[0..protocol.hello_size]);
|
||||
if (message.len < device_manager_protocol.hello_size) return 0;
|
||||
const hello = std.mem.bytesToValue(device_manager_protocol.Hello, message[0..device_manager_protocol.hello_size]);
|
||||
|
||||
var status: i32 = 0;
|
||||
if (hello.version != protocol.version) {
|
||||
if (hello.version != device_manager_protocol.version) {
|
||||
status = -1;
|
||||
std.log.info("refused hello (version {d}) from process {d}", .{ hello.version, sender });
|
||||
} else if (driverByProcess(sender)) |driver| {
|
||||
@@ -439,26 +439,26 @@ fn onMessage(message: []const u8, reply: []u8, sender: u32, capability: ?runtime
|
||||
status = -1;
|
||||
std.log.info("hello from unknown process {d}", .{sender});
|
||||
}
|
||||
const hello_reply = protocol.HelloReply{ .status = status };
|
||||
@memcpy(reply[0..protocol.reply_size], std.mem.asBytes(&hello_reply));
|
||||
return protocol.reply_size;
|
||||
const hello_reply = device_manager_protocol.HelloReply{ .status = status };
|
||||
@memcpy(reply[0..device_manager_protocol.reply_size], std.mem.asBytes(&hello_reply));
|
||||
return device_manager_protocol.reply_size;
|
||||
}
|
||||
|
||||
/// A bus driver reported a discovered device: mirror it, and in
|
||||
/// test-usb-restart mode kill the reporter once after its second child — the
|
||||
/// deterministic trigger for prune -> backoff -> respawn -> re-report.
|
||||
fn onChildAdded(message: []const u8, reply: []u8, sender: u32) usize {
|
||||
if (message.len < protocol.child_added_size) return 0;
|
||||
const report = std.mem.bytesToValue(protocol.ChildAdded, message[0..protocol.child_added_size]);
|
||||
if (message.len < device_manager_protocol.child_added_size) return 0;
|
||||
const report = std.mem.bytesToValue(device_manager_protocol.ChildAdded, message[0..device_manager_protocol.child_added_size]);
|
||||
var status: i32 = 0;
|
||||
if (driverByProcess(sender)) |driver| {
|
||||
if (!addChild(report.parent, report.bus_address, report.identity, report.device_id, sender)) status = -1;
|
||||
std.log.info("child added (device {d} port {d}, identity {d}) by {s}", .{ 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..device_manager_protocol.child_added_size]);
|
||||
// Matching from reports (M19.3): a registered child whose identity
|
||||
// names a driver gets one, once — re-reports after a bus restart
|
||||
// dedupe on the registered id, exactly like the registrations do.
|
||||
if (status == 0 and report.device_id != protocol.no_device) {
|
||||
if (status == 0 and report.device_id != device_manager_protocol.no_device) {
|
||||
if (pciDriverForIdentity(report.identity)) |child_driver| {
|
||||
if (!driverForDevice(report.device_id)) addDriver(child_driver, report.device_id, true);
|
||||
}
|
||||
@@ -472,15 +472,15 @@ fn onChildAdded(message: []const u8, reply: []u8, sender: u32) usize {
|
||||
const hid_len = std.mem.indexOfScalar(u8, &report.hid, 0) orelse report.hid.len;
|
||||
if (hid_len != 0) {
|
||||
if (hidDriverFor(report.hid[0..hid_len])) |hid_driver| {
|
||||
if (!alreadySupervised(hid_driver)) addDriver(hid_driver, protocol.no_device, false);
|
||||
if (!alreadySupervised(hid_driver)) addDriver(hid_driver, device_manager_protocol.no_device, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
const report_reply = protocol.ReportReply{ .status = status };
|
||||
@memcpy(reply[0..@sizeOf(protocol.ReportReply)], std.mem.asBytes(&report_reply));
|
||||
const report_reply = device_manager_protocol.ReportReply{ .status = status };
|
||||
@memcpy(reply[0..@sizeOf(device_manager_protocol.ReportReply)], std.mem.asBytes(&report_reply));
|
||||
if (test_pci_restart_mode and !test_usb_killed) {
|
||||
if (driverByProcess(sender)) |driver| {
|
||||
if (std.mem.eql(u8, driver.name(), "pci-bus") and childCountOf(sender) >= 3) {
|
||||
@@ -508,14 +508,14 @@ fn onChildAdded(message: []const u8, reply: []u8, sender: u32) usize {
|
||||
}
|
||||
}
|
||||
}
|
||||
return @sizeOf(protocol.ReportReply);
|
||||
return @sizeOf(device_manager_protocol.ReportReply);
|
||||
}
|
||||
|
||||
/// A bus driver reported a device gone (hot-unplug; no sender exists yet, but
|
||||
/// the handler is protocol-complete — death-pruning covers removal until then).
|
||||
fn onChildRemoved(message: []const u8, reply: []u8, sender: u32) usize {
|
||||
if (message.len < protocol.child_removed_size) return 0;
|
||||
const report = std.mem.bytesToValue(protocol.ChildRemoved, message[0..protocol.child_removed_size]);
|
||||
if (message.len < device_manager_protocol.child_removed_size) return 0;
|
||||
const report = std.mem.bytesToValue(device_manager_protocol.ChildRemoved, message[0..device_manager_protocol.child_removed_size]);
|
||||
var status: i32 = -1;
|
||||
for (&children) |*child| {
|
||||
if (child.used and child.parent == report.parent and child.bus_address == report.bus_address and child.reporter == sender) {
|
||||
@@ -524,25 +524,25 @@ fn onChildRemoved(message: []const u8, reply: []u8, sender: u32) usize {
|
||||
status = 0;
|
||||
}
|
||||
}
|
||||
const report_reply = protocol.ReportReply{ .status = status };
|
||||
@memcpy(reply[0..@sizeOf(protocol.ReportReply)], std.mem.asBytes(&report_reply));
|
||||
return @sizeOf(protocol.ReportReply);
|
||||
const report_reply = device_manager_protocol.ReportReply{ .status = status };
|
||||
@memcpy(reply[0..@sizeOf(device_manager_protocol.ReportReply)], std.mem.asBytes(&report_reply));
|
||||
return @sizeOf(device_manager_protocol.ReportReply);
|
||||
}
|
||||
|
||||
/// An application asked for the tree: the mirror, as a header plus entries.
|
||||
fn onEnumerate(reply: []u8) usize {
|
||||
var count: u32 = 0;
|
||||
var offset: usize = @sizeOf(protocol.EnumerateReply);
|
||||
var offset: usize = @sizeOf(device_manager_protocol.EnumerateReply);
|
||||
for (&children) |*child| {
|
||||
if (!child.used) continue;
|
||||
if (offset + @sizeOf(protocol.ChildEntry) > reply.len) break;
|
||||
const entry = protocol.ChildEntry{ .parent = child.parent, .bus_address = child.bus_address, .identity = child.identity };
|
||||
@memcpy(reply[offset..][0..@sizeOf(protocol.ChildEntry)], std.mem.asBytes(&entry));
|
||||
offset += @sizeOf(protocol.ChildEntry);
|
||||
if (offset + @sizeOf(device_manager_protocol.ChildEntry) > reply.len) break;
|
||||
const entry = device_manager_protocol.ChildEntry{ .parent = child.parent, .bus_address = child.bus_address, .identity = child.identity };
|
||||
@memcpy(reply[offset..][0..@sizeOf(device_manager_protocol.ChildEntry)], std.mem.asBytes(&entry));
|
||||
offset += @sizeOf(device_manager_protocol.ChildEntry);
|
||||
count += 1;
|
||||
}
|
||||
const header = protocol.EnumerateReply{ .status = 0, .count = count };
|
||||
@memcpy(reply[0..@sizeOf(protocol.EnumerateReply)], std.mem.asBytes(&header));
|
||||
const header = device_manager_protocol.EnumerateReply{ .status = 0, .count = count };
|
||||
@memcpy(reply[0..@sizeOf(device_manager_protocol.EnumerateReply)], std.mem.asBytes(&header));
|
||||
return offset;
|
||||
}
|
||||
|
||||
@@ -558,9 +558,9 @@ fn onSubscribe(reply: []u8, capability: ?runtime.ipc.Handle) usize {
|
||||
}
|
||||
}
|
||||
}
|
||||
const report_reply = protocol.ReportReply{ .status = status };
|
||||
@memcpy(reply[0..@sizeOf(protocol.ReportReply)], std.mem.asBytes(&report_reply));
|
||||
return @sizeOf(protocol.ReportReply);
|
||||
const report_reply = device_manager_protocol.ReportReply{ .status = status };
|
||||
@memcpy(reply[0..@sizeOf(device_manager_protocol.ReportReply)], std.mem.asBytes(&report_reply));
|
||||
return @sizeOf(device_manager_protocol.ReportReply);
|
||||
}
|
||||
|
||||
fn onNotification(badge: u64) void {
|
||||
@@ -579,7 +579,7 @@ pub fn main(init: runtime.process.Init) void {
|
||||
test_pci_restart_mode = std.mem.eql(u8, mode, "test-pci-restart");
|
||||
test_scanout_restart_mode = std.mem.eql(u8, mode, "test-scanout-restart");
|
||||
}
|
||||
runtime.service.run(protocol.message_maximum, .{
|
||||
runtime.service.run(device_manager_protocol.message_maximum, .{
|
||||
.service = .device_manager,
|
||||
.init = initialise,
|
||||
.on_message = onMessage,
|
||||
|
||||
@@ -20,7 +20,7 @@ const runtime = @import("runtime");
|
||||
const compositor = @import("compositor.zig");
|
||||
const backend_mod = @import("backend.zig");
|
||||
|
||||
const protocol = @import("display-protocol");
|
||||
const display_protocol = @import("display-protocol");
|
||||
const ipc = runtime.ipc;
|
||||
const system = runtime.system;
|
||||
const input = runtime.input;
|
||||
@@ -326,7 +326,7 @@ fn attachScanout(stride: u32, width: u32, height: u32, format: u32, refresh_hz:
|
||||
.refresh_hz = refresh_hz,
|
||||
.scanout = scanout,
|
||||
} };
|
||||
background = protocol.pack(format, 0x20, 0x30, 0x48); // re-pack the wallpaper for the mode
|
||||
background = display_protocol.pack(format, 0x20, 0x30, 0x48); // re-pack the wallpaper for the mode
|
||||
updateFrameClock(); // the GOP floor's clock dies here — pace by the GPU's EDID now
|
||||
addDamage(screenRect()); // the whole new surface must be painted
|
||||
pending_native_verify = true;
|
||||
@@ -389,8 +389,8 @@ fn modesetSelfCheck() void {
|
||||
/// backend surface — and reads the composited result back. Cleans up after itself.
|
||||
fn selfCheck() void {
|
||||
const format = backend.info().format;
|
||||
const red = protocol.pack(format, 0xC0, 0x20, 0x20);
|
||||
const green = protocol.pack(format, 0x20, 0xC0, 0x20);
|
||||
const red = display_protocol.pack(format, 0xC0, 0x20, 0x20);
|
||||
const green = display_protocol.pack(format, 0x20, 0xC0, 0x20);
|
||||
const bottom = createLayer(100, 100, 80, 80, 0, true) orelse return fail_check("create");
|
||||
const top = createLayer(140, 140, 80, 80, 1, true) orelse return fail_check("create");
|
||||
_ = fillLayer(bottom, Rect.init(0, 0, 80, 80), red);
|
||||
@@ -559,7 +559,7 @@ fn startCursorTracking() void {
|
||||
return;
|
||||
};
|
||||
cursor_layer = id;
|
||||
_ = fillLayer(id, Rect.init(0, 0, cursor_size, cursor_size), protocol.pack(mode.format, 0xF0, 0xF0, 0xF0));
|
||||
_ = fillLayer(id, Rect.init(0, 0, cursor_size, cursor_size), display_protocol.pack(mode.format, 0xF0, 0xF0, 0xF0));
|
||||
present(); // show the cursor at its start position
|
||||
|
||||
_ = Thread.spawn(.{}, mouseListener, .{ mode.width, mode.height }) catch {
|
||||
@@ -575,7 +575,7 @@ fn initialise(endpoint: ipc.Handle) bool {
|
||||
// Pick the scanout backend (GOP today). It logs the reason on failure.
|
||||
backend = backend_mod.select() orelse return false;
|
||||
const mode = backend.info();
|
||||
background = protocol.pack(mode.format, 0x20, 0x30, 0x48); // a dark slate wallpaper
|
||||
background = display_protocol.pack(mode.format, 0x20, 0x30, 0x48); // a dark slate wallpaper
|
||||
|
||||
// Clear the whole screen through the compose surface → present path (double buffering:
|
||||
// no direct-to-scanout drawing).
|
||||
@@ -596,7 +596,7 @@ fn initialise(endpoint: ipc.Handle) bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
fn writeReply(reply: []u8, value: protocol.Reply) usize {
|
||||
fn writeReply(reply: []u8, value: display_protocol.Reply) usize {
|
||||
const bytes = std.mem.asBytes(&value);
|
||||
@memcpy(reply[0..bytes.len], bytes);
|
||||
return bytes.len;
|
||||
@@ -612,61 +612,61 @@ fn fail(reply: []u8) usize {
|
||||
|
||||
fn onMessage(message: []const u8, reply: []u8, sender: u32, capability: ?ipc.Handle) usize {
|
||||
_ = sender;
|
||||
if (message.len < protocol.request_size) return fail(reply);
|
||||
const request = std.mem.bytesToValue(protocol.Request, message[0..protocol.request_size]);
|
||||
const payload = message[protocol.request_size..];
|
||||
if (message.len < display_protocol.request_size) return fail(reply);
|
||||
const request = std.mem.bytesToValue(display_protocol.Request, message[0..display_protocol.request_size]);
|
||||
const payload = message[display_protocol.request_size..];
|
||||
// Switch on the raw operation value — an out-of-range one must fail cleanly, not
|
||||
// panic an `@enumFromInt`.
|
||||
switch (request.operation) {
|
||||
@intFromEnum(protocol.Operation.info) => {
|
||||
@intFromEnum(display_protocol.Operation.info) => {
|
||||
const m = backend.info();
|
||||
return writeReply(reply, .{ .status = 0, .width = m.width, .height = m.height, .pitch = m.pitch, .format = m.format });
|
||||
},
|
||||
@intFromEnum(protocol.Operation.create_layer) => {
|
||||
@intFromEnum(display_protocol.Operation.create_layer) => {
|
||||
// x/y are signed coordinates carried in the u32 wire fields — reinterpret the
|
||||
// bits (@bitCast), don't range-check (@intCast) which a negative would fail.
|
||||
const slot = createLayer(@bitCast(request.x), @bitCast(request.y), request.width, request.height, request.z, request.visible != 0) orelse return fail(reply);
|
||||
return writeReply(reply, .{ .status = 0, .layer = slot });
|
||||
},
|
||||
@intFromEnum(protocol.Operation.configure_layer) => {
|
||||
@intFromEnum(display_protocol.Operation.configure_layer) => {
|
||||
return if (configureLayer(request.layer, @bitCast(request.x), @bitCast(request.y), request.z, request.visible != 0)) ok(reply) else fail(reply);
|
||||
},
|
||||
@intFromEnum(protocol.Operation.destroy_layer) => {
|
||||
@intFromEnum(display_protocol.Operation.destroy_layer) => {
|
||||
return if (destroyLayer(request.layer)) ok(reply) else fail(reply);
|
||||
},
|
||||
@intFromEnum(protocol.Operation.fill_rect) => {
|
||||
@intFromEnum(display_protocol.Operation.fill_rect) => {
|
||||
const local = Rect.init(@bitCast(request.x), @bitCast(request.y), @intCast(request.width), @intCast(request.height));
|
||||
return if (fillLayer(request.layer, local, request.colour)) ok(reply) else fail(reply);
|
||||
},
|
||||
@intFromEnum(protocol.Operation.blit_tile) => {
|
||||
@intFromEnum(display_protocol.Operation.blit_tile) => {
|
||||
return if (blitLayer(request.layer, @bitCast(request.x), @bitCast(request.y), request.width, request.height, payload)) ok(reply) else fail(reply);
|
||||
},
|
||||
@intFromEnum(protocol.Operation.damage) => {
|
||||
@intFromEnum(display_protocol.Operation.damage) => {
|
||||
const l = layerAt(request.layer) orelse return fail(reply);
|
||||
const screen = Rect{ .x = l.x + @as(i32, @bitCast(request.x)), .y = l.y + @as(i32, @bitCast(request.y)), .w = @intCast(request.width), .h = @intCast(request.height) };
|
||||
addDamage(screen.intersect(layerScreenRect(l)));
|
||||
return ok(reply);
|
||||
},
|
||||
@intFromEnum(protocol.Operation.present) => {
|
||||
@intFromEnum(display_protocol.Operation.present) => {
|
||||
// Scheduled, not immediate: the frame clock composites the accumulated damage
|
||||
// at the next tick, so back-to-back client presents coalesce into one frame.
|
||||
schedulePresent();
|
||||
return ok(reply);
|
||||
},
|
||||
@intFromEnum(protocol.Operation.attach_scanout) => {
|
||||
@intFromEnum(display_protocol.Operation.attach_scanout) => {
|
||||
return attachScanout(request.x, request.width, request.height, request.colour, request.y, capability, reply);
|
||||
},
|
||||
@intFromEnum(protocol.Operation.set_mode) => {
|
||||
@intFromEnum(display_protocol.Operation.set_mode) => {
|
||||
if (!backend.setMode(request.width, request.height)) return fail(reply);
|
||||
addDamage(screenRect()); // repaint the whole screen at the new resolution
|
||||
present();
|
||||
return ok(reply);
|
||||
},
|
||||
@intFromEnum(protocol.Operation.get_modes) => {
|
||||
@intFromEnum(display_protocol.Operation.get_modes) => {
|
||||
var list: [4]backend_mod.Mode = undefined;
|
||||
const count = backend.modes(&list);
|
||||
var response = protocol.ModesReply{ .status = 0, .count = @intCast(count), .modes = undefined };
|
||||
for (0..protocol.max_modes) |i| {
|
||||
var response = display_protocol.ModesReply{ .status = 0, .count = @intCast(count), .modes = undefined };
|
||||
for (0..display_protocol.max_modes) |i| {
|
||||
response.modes[i] = if (i < count)
|
||||
.{ .width = list[i].width, .height = list[i].height }
|
||||
else
|
||||
@@ -692,7 +692,7 @@ fn onNotification(badge: u64) void {
|
||||
}
|
||||
|
||||
pub fn main() void {
|
||||
runtime.service.run(protocol.message_maximum, .{
|
||||
runtime.service.run(display_protocol.message_maximum, .{
|
||||
.service = .display,
|
||||
.init = initialise,
|
||||
.on_message = onMessage,
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
const std = @import("std");
|
||||
const runtime = @import("runtime");
|
||||
const power = @import("power-protocol");
|
||||
const power_protocol = @import("power-protocol");
|
||||
const build_options = @import("build_options");
|
||||
|
||||
/// The system services init brings up at boot, in order, by binary path. This is
|
||||
@@ -105,7 +105,7 @@ pub fn main() void {
|
||||
// and the handler below — folds away entirely when serial is off.
|
||||
if (build_options.serial) _ = runtime.system.timerOnce(supervision_endpoint, 1000);
|
||||
|
||||
var receive: [power.message_maximum]u8 = undefined;
|
||||
var receive: [power_protocol.message_maximum]u8 = undefined;
|
||||
while (true) {
|
||||
const got = runtime.ipc.replyWait(supervision_endpoint, &.{}, &receive, null);
|
||||
if (runtime.process.signalsFrom(got.badge)) |signals| {
|
||||
@@ -117,9 +117,9 @@ pub fn main() void {
|
||||
_ = runtime.system.timerOnce(supervision_endpoint, 1000);
|
||||
continue;
|
||||
}
|
||||
if (got.isMessage() and got.len >= 2 and receive[0] == @intFromEnum(power.Operation.event)) {
|
||||
if (got.isMessage() and got.len >= 2 and receive[0] == @intFromEnum(power_protocol.Operation.event)) {
|
||||
// A power event (the only buffered messages init receives).
|
||||
if (receive[1] == @intFromEnum(power.Event.power_button)) shutDown();
|
||||
if (receive[1] == @intFromEnum(power_protocol.Event.power_button)) shutDown();
|
||||
continue;
|
||||
}
|
||||
if (got.isChildExit()) {
|
||||
@@ -171,8 +171,8 @@ fn subscribePower() void {
|
||||
// a `terminate` signal still drives shutdown. Silent so the no-ramdisk init
|
||||
// test's heartbeat marker is the next line written.
|
||||
const h = handle orelse return;
|
||||
const request = power.Subscribe{};
|
||||
var reply: [power.message_maximum]u8 = undefined;
|
||||
const request = power_protocol.Subscribe{};
|
||||
var reply: [power_protocol.message_maximum]u8 = undefined;
|
||||
_ = runtime.ipc.callCap(h, std.mem.asBytes(&request), &reply, supervision_endpoint) catch {};
|
||||
}
|
||||
|
||||
@@ -192,8 +192,8 @@ fn shutDown() void {
|
||||
if (child_ids[i] != 0) runtime.process.stop(child_ids[i], 2000, supervision_endpoint);
|
||||
}
|
||||
if (runtime.ipc.lookup(.power)) |h| {
|
||||
const request = power.Shutdown{};
|
||||
var reply: [power.message_maximum]u8 = undefined;
|
||||
const request = power_protocol.Shutdown{};
|
||||
var reply: [power_protocol.message_maximum]u8 = undefined;
|
||||
_ = runtime.ipc.call(h, std.mem.asBytes(&request), &reply) catch {};
|
||||
}
|
||||
// If S5 did not take, init has nothing left to do but idle.
|
||||
|
||||
Reference in New Issue
Block a user