diff --git a/build.zig b/build.zig index e4ea6cf..74c8926 100644 --- a/build.zig +++ b/build.zig @@ -375,7 +375,7 @@ pub fn build(b: *std.Build) void { // module the same way vfs-protocol is. Shared by the input service, the runtime's // `input` helper (subscribe/publish), and every source and subscriber. const input_protocol_module = b.addModule("input-protocol", .{ - .root_source_file = b.path("system/services/input/protocol.zig"), + .root_source_file = b.path("library/protocol/input/input-protocol.zig"), }); // The danos-native user-space runtime: system_call wrappers, the C-convention @@ -547,7 +547,9 @@ pub fn build(b: *std.Build) void { const vfstest_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "vfs-test", "system/services/vfs-test/vfs-test.zig"); const ps2_bus_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "ps2-bus", "system/drivers/ps2-bus/ps2-bus.zig"); const ps2_keyboard_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "ps2-keyboard", "system/drivers/ps2-bus/keyboard.zig"); + programModule(ps2_keyboard_exe).addImport("input-protocol", input_protocol_module); const ps2_mouse_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "ps2-mouse", "system/drivers/ps2-bus/mouse.zig"); + programModule(ps2_mouse_exe).addImport("input-protocol", input_protocol_module); const usb_xhci_bus_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "usb-xhci-bus", "system/drivers/usb-xhci-bus/usb-xhci-bus.zig"); // The xHCI bus driver builds chapter-9 requests and decodes descriptors from // usb-abi, and reports each interface's (class,subclass,protocol) identity via @@ -561,9 +563,11 @@ pub fn build(b: *std.Build) void { const usb_hid_keyboard_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "usb-hid-keyboard", "system/drivers/usb-hid/keyboard.zig"); programModule(usb_hid_keyboard_exe).addImport("usb", usb_module); programModule(usb_hid_keyboard_exe).addImport("usb-abi", usb_abi_module); + programModule(usb_hid_keyboard_exe).addImport("input-protocol", input_protocol_module); const usb_hid_mouse_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "usb-hid-mouse", "system/drivers/usb-hid/mouse.zig"); programModule(usb_hid_mouse_exe).addImport("usb", usb_module); programModule(usb_hid_mouse_exe).addImport("usb-abi", usb_abi_module); + programModule(usb_hid_mouse_exe).addImport("input-protocol", input_protocol_module); // The USB mass-storage class driver: opens its device via runtime.usb, drives it // with Bulk-Only Transport + SCSI, and serves the block protocol under `.block`. const usb_storage_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "usb-storage", "system/drivers/usb-storage/usb-storage.zig"); @@ -614,6 +618,7 @@ pub fn build(b: *std.Build) void { // The input service and its exercisers: the fan-out server, a hardware-free synthetic // source, and a subscriber that doubles as the `input` test's oracle. See docs/input.md. const input_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "input", "system/services/input/input.zig"); + programModule(input_exe).addImport("input-protocol", input_protocol_module); const input_source_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "input-source", "system/services/input-source/input-source.zig"); const input_test_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "input-test", "system/services/input-test/input-test.zig"); const args_echo_exe = addUserBinary(b, kernel_target, runtime_module, mmio_module, xkeyboard_config_module, acpi_ids_module, "args-echo", "system/services/args-echo/args-echo.zig"); diff --git a/system/services/input/protocol.zig b/library/protocol/input/input-protocol.zig similarity index 100% rename from system/services/input/protocol.zig rename to library/protocol/input/input-protocol.zig diff --git a/library/runtime/runtime.zig b/library/runtime/runtime.zig index f9b4039..5476f6e 100644 --- a/library/runtime/runtime.zig +++ b/library/runtime/runtime.zig @@ -30,8 +30,6 @@ pub const power_protocol = @import("power-protocol"); /// Keyboard-event listening (subscribe/next) and broadcasting (publish), over the input /// service. See library/runtime/input.zig and system/services/input/. pub const input = @import("input.zig"); -/// The input wire protocol (shared with the input service and its clients). -pub const input_protocol = @import("input-protocol"); /// POSIX-style file API: open/read/write/lseek/stat/close. /// C stdio: fopen/fread/fwrite/fseek/ftell/fclose over unistd. /// Device access for drivers: enumerate/claim/mmioMap. diff --git a/system/drivers/ps2-bus/keyboard.zig b/system/drivers/ps2-bus/keyboard.zig index a486a7a..ba7a27a 100644 --- a/system/drivers/ps2-bus/keyboard.zig +++ b/system/drivers/ps2-bus/keyboard.zig @@ -21,7 +21,7 @@ const ps2 = @import("ps2-library.zig"); const scancode = @import("scancode.zig"); const device = runtime.device; const ipc = runtime.ipc; -const protocol = runtime.input_protocol; +const input_protocol = @import("input-protocol"); /// Look up the ps2-bus service, retrying while the bus (which spawned us before /// registering) is still coming up. @@ -46,7 +46,7 @@ fn characterFor(layout: *const xkb.Layout, usage: u8, modifiers: scancode.Modifi .control = modifiers.control, }); if (mapping.character) |character| return character; - return switch (@as(protocol.Keycode, @enumFromInt(usage))) { + return switch (@as(input_protocol.Keycode, @enumFromInt(usage))) { .enter, .keypad_enter => '\n', .tab => '\t', .backspace => 0x08, @@ -58,9 +58,9 @@ fn characterFor(layout: *const xkb.Layout, usage: u8, modifiers: scancode.Modifi /// The input protocol's modifier word for a snapshot. fn modifierWord(modifiers: scancode.ModifierSnapshot) u32 { var word: u32 = 0; - if (modifiers.shift) word |= protocol.modifier_shift; - if (modifiers.control) word |= protocol.modifier_control; - if (modifiers.alt) word |= protocol.modifier_alt; + if (modifiers.shift) word |= input_protocol.modifier_shift; + if (modifiers.control) word |= input_protocol.modifier_control; + if (modifiers.alt) word |= input_protocol.modifier_alt; return word; } @@ -133,7 +133,7 @@ pub fn main(init: runtime.process.Init) void { switch (transition.action) { .pressed => { _ = source.publishKeyboardEvent(.{ - .kind = @intFromEnum(protocol.EventKind.key_down), + .kind = @intFromEnum(input_protocol.EventKind.key_down), .keycode = key.usage, .character = 0, .modifiers = modifiers, @@ -141,7 +141,7 @@ pub fn main(init: runtime.process.Init) void { const character = characterFor(layout, key.usage, transition.modifiers); if (character != 0) { _ = source.publishKeyboardEvent(.{ - .kind = @intFromEnum(protocol.EventKind.key_press), + .kind = @intFromEnum(input_protocol.EventKind.key_press), .keycode = key.usage, .character = character, .modifiers = modifiers, @@ -154,7 +154,7 @@ pub fn main(init: runtime.process.Init) void { const character = characterFor(layout, key.usage, transition.modifiers); if (character != 0) { _ = source.publishKeyboardEvent(.{ - .kind = @intFromEnum(protocol.EventKind.key_press), + .kind = @intFromEnum(input_protocol.EventKind.key_press), .keycode = key.usage, .character = character, .modifiers = modifiers, @@ -163,7 +163,7 @@ pub fn main(init: runtime.process.Init) void { }, .released => { _ = source.publishKeyboardEvent(.{ - .kind = @intFromEnum(protocol.EventKind.key_up), + .kind = @intFromEnum(input_protocol.EventKind.key_up), .keycode = key.usage, .character = 0, .modifiers = modifiers, diff --git a/system/drivers/ps2-bus/mouse.zig b/system/drivers/ps2-bus/mouse.zig index 98043da..45d83ea 100644 --- a/system/drivers/ps2-bus/mouse.zig +++ b/system/drivers/ps2-bus/mouse.zig @@ -20,7 +20,7 @@ const ps2 = @import("ps2-library.zig"); const mouse_packet = @import("mouse-packet.zig"); const device = runtime.device; const ipc = runtime.ipc; -const protocol = runtime.input_protocol; +const input_protocol = @import("input-protocol"); /// Look up the ps2-bus service, retrying while the bus (which spawned us before /// registering) is still coming up. @@ -36,9 +36,9 @@ fn lookupBus() ?ipc.Handle { /// The protocol's pressed-button bitmask for a packet. fn buttonMask(packet: mouse_packet.Packet) u32 { var mask: u32 = 0; - if (packet.left) mask |= protocol.mouse_button_left; - if (packet.right) mask |= protocol.mouse_button_right; - if (packet.middle) mask |= protocol.mouse_button_middle; + if (packet.left) mask |= input_protocol.mouse_button_left; + if (packet.right) mask |= input_protocol.mouse_button_right; + if (packet.middle) mask |= input_protocol.mouse_button_middle; return mask; } @@ -104,9 +104,9 @@ pub fn main(init: runtime.process.Init) void { // A button transition per changed button, carrying the new whole mask. const changed = buttons ^ new_buttons; - for ([_]u32{ protocol.mouse_button_left, protocol.mouse_button_right, protocol.mouse_button_middle }) |button| { + for ([_]u32{ input_protocol.mouse_button_left, input_protocol.mouse_button_right, input_protocol.mouse_button_middle }) |button| { if (changed & button == 0) continue; - const kind: protocol.MouseEventKind = if (new_buttons & button != 0) .button_down else .button_up; + const kind: input_protocol.MouseEventKind = if (new_buttons & button != 0) .button_down else .button_up; _ = source.publishMouseEvent(.{ .kind = @intFromEnum(kind), .button = button, @@ -121,7 +121,7 @@ pub fn main(init: runtime.process.Init) void { if (packet.dx != 0 or packet.dy != 0) { _ = source.publishMouseEvent(.{ - .kind = @intFromEnum(protocol.MouseEventKind.motion), + .kind = @intFromEnum(input_protocol.MouseEventKind.motion), .button = 0, .dx = packet.dx, .dy = packet.dy, diff --git a/system/drivers/usb-hid/keyboard.zig b/system/drivers/usb-hid/keyboard.zig index b8aff5b..0347722 100644 --- a/system/drivers/usb-hid/keyboard.zig +++ b/system/drivers/usb-hid/keyboard.zig @@ -22,7 +22,7 @@ const xkb = @import("xkeyboard-config"); const hid = @import("hid-report.zig"); const ipc = runtime.ipc; const process = runtime.process; -const input_protocol = runtime.input_protocol; +const input_protocol = @import("input-protocol"); // The modifier state a character lookup needs — derived from the report's // modifier byte, plus the driver-tracked caps-lock toggle. diff --git a/system/drivers/usb-hid/mouse.zig b/system/drivers/usb-hid/mouse.zig index 3467373..52e3183 100644 --- a/system/drivers/usb-hid/mouse.zig +++ b/system/drivers/usb-hid/mouse.zig @@ -17,7 +17,7 @@ const usb_abi = @import("usb-abi"); const hid = @import("hid-report.zig"); const ipc = runtime.ipc; const process = runtime.process; -const input_protocol = runtime.input_protocol; +const input_protocol = @import("input-protocol"); // The current pressed-button bitmask in input-protocol terms. fn buttonMask(buttons: u8) u32 { diff --git a/system/services/input/input.zig b/system/services/input/input.zig index 0658fa2..a2bab86 100644 --- a/system/services/input/input.zig +++ b/system/services/input/input.zig @@ -21,7 +21,7 @@ const std = @import("std"); const runtime = @import("runtime"); -const protocol = runtime.input_protocol; +const input_protocol = @import("input-protocol"); const ipc = runtime.ipc; const system = runtime.system; @@ -32,7 +32,7 @@ const Subscriber = struct { used: bool = false, endpoint: ipc.Handle = 0, task_id: u32 = 0, - /// Which device classes this subscriber wants (an OR of protocol.device_*). An event + /// Which device classes this subscriber wants (an OR of input_protocol.device_*). An event /// is delivered only if its device's bit is set here. device_mask: u32 = 0, }; @@ -74,9 +74,9 @@ fn addSubscriber(endpoint: ipc.Handle, task_id: u32, device_mask: u32) bool { /// Push `event` to every subscriber whose interest mask includes its device class. /// `ipc.send` never blocks, so a slow or dead subscriber cannot stall delivery to others. -fn broadcast(event: protocol.InputEvent) void { +fn broadcast(event: input_protocol.InputEvent) void { const bytes = std.mem.asBytes(&event); - const bit = protocol.deviceBit(event.device); + const bit = input_protocol.deviceBit(event.device); for (&subscribers) |*sub| { if (sub.used and sub.device_mask & bit != 0) _ = ipc.send(sub.endpoint, bytes); } @@ -88,20 +88,20 @@ fn broadcast(event: protocol.InputEvent) void { fn handle(message: []const u8, got: ipc.Received, out: []u8) usize { const reply = struct { fn write(buffer: []u8, status: i32) usize { - const header = protocol.Reply{ .status = status }; - @memcpy(buffer[0..protocol.reply_size], std.mem.asBytes(&header)); - return protocol.reply_size; + const header = input_protocol.Reply{ .status = status }; + @memcpy(buffer[0..input_protocol.reply_size], std.mem.asBytes(&header)); + return input_protocol.reply_size; } }; - if (message.len < protocol.request_size) return reply.write(out, -1); - const request = std.mem.bytesToValue(protocol.Request, message[0..protocol.request_size]); + if (message.len < input_protocol.request_size) return reply.write(out, -1); + const request = std.mem.bytesToValue(input_protocol.Request, message[0..input_protocol.request_size]); - switch (@as(protocol.Operation, @enumFromInt(request.operation))) { + switch (@as(input_protocol.Operation, @enumFromInt(request.operation))) { .subscribe => { const endpoint = got.cap orelse return reply.write(out, -1); // no endpoint passed // A zero mask means "everything" (a subscriber that named no class still wants input). - const mask = if (request.device_mask == 0) protocol.device_all else request.device_mask; + const mask = if (request.device_mask == 0) input_protocol.device_all else request.device_mask; pruneDeadSubscribers(); if (!addSubscriber(endpoint, @intCast(got.badge), mask)) return reply.write(out, -1); // table full return reply.write(out, 0); @@ -124,9 +124,9 @@ pub fn main() void { } _ = system.write("/system/services/input: ready\n"); - var reply_buffer: [protocol.reply_size]u8 = undefined; + var reply_buffer: [input_protocol.reply_size]u8 = undefined; var reply_len: usize = 0; - var receive: [protocol.request_size]u8 = undefined; + var receive: [input_protocol.request_size]u8 = undefined; while (true) { const got = ipc.replyWait(endpoint, reply_buffer[0..reply_len], &receive, null); // Only synchronous client requests (subscribe/publish) arrive here; nothing sends