diff --git a/Cargo.toml b/Cargo.toml index 70eeb4256..7a5054f5b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,6 +75,9 @@ serde_yaml = { version = "0.9" } serde_json = { version = "1.0", default-features = false, features = ["alloc"] } lzma-rs = { version = "0.3" } +[patch.crates-io] +r-efi = { git = "https://github.com/joschock/r-efi.git", branch = "add_usb_io" } + [workspace.lints.clippy] indexing_slicing = "deny" undocumented_unsafe_blocks = "warn" diff --git a/sdk/patina/src/lib.rs b/sdk/patina/src/lib.rs index 9a6e735ba..2eb970ba8 100644 --- a/sdk/patina/src/lib.rs +++ b/sdk/patina/src/lib.rs @@ -61,6 +61,8 @@ pub mod tpl_mutex; pub mod uefi_decompress; #[cfg(any(test, feature = "alloc"))] pub mod uefi_protocol; +#[cfg(any(test, feature = "alloc"))] +pub mod vendor_protocols; /// Re-export of the [`safe-mmio`](https://crates.io/crates/safe-mmio) crate. /// diff --git a/sdk/patina/src/uefi_protocol.rs b/sdk/patina/src/uefi_protocol.rs index 702e56dcc..286ce2124 100644 --- a/sdk/patina/src/uefi_protocol.rs +++ b/sdk/patina/src/uefi_protocol.rs @@ -87,3 +87,4 @@ impl_r_efi_protocol!(tcp6); impl_r_efi_protocol!(timestamp); impl_r_efi_protocol!(udp4); impl_r_efi_protocol!(udp6); +impl_r_efi_protocol!(usb_io); diff --git a/sdk/patina/src/vendor_protocols.rs b/sdk/patina/src/vendor_protocols.rs new file mode 100644 index 000000000..96a2d4e8f --- /dev/null +++ b/sdk/patina/src/vendor_protocols.rs @@ -0,0 +1,13 @@ +//! Vendor-specific UEFI protocol definitions. +//! +//! Protocols in this module are not part of the UEFI or PI specifications but +//! follow the UEFI protocol model. They are defined by platform vendors. +//! +//! ## License +//! +//! Copyright (c) Microsoft Corporation. +//! +//! SPDX-License-Identifier: Apache-2.0 +//! + +pub mod hid_io; diff --git a/sdk/patina/src/vendor_protocols/hid_io.rs b/sdk/patina/src/vendor_protocols/hid_io.rs new file mode 100644 index 000000000..4e786fd09 --- /dev/null +++ b/sdk/patina/src/vendor_protocols/hid_io.rs @@ -0,0 +1,76 @@ +//! HidIo protocol FFI definitions. +//! +//! Defines the HidIo protocol interface struct, types, and GUID shared between +//! producers (e.g. `usb_hid`) and consumers (e.g. `uefi_hid`) of the protocol. +//! +//! ## License +//! +//! Copyright (c) Microsoft Corporation. +//! +//! SPDX-License-Identifier: Apache-2.0 +//! + +use core::ffi::c_void; + +use r_efi::efi; + +/// HidIo interface GUID: 3EA93936-6BF4-49D6-AA50-D9F5B9AD8CFF +pub const HID_IO_PROTOCOL_GUID: crate::BinaryGuid = + crate::BinaryGuid::from_string("3EA93936-6BF4-49D6-AA50-D9F5B9AD8CFF"); + +/// HID report types per the HID specification. +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[repr(C)] +pub enum HidReportType { + /// Input report (device to host). + InputReport = 1, + /// Output report (host to device). + OutputReport = 2, + /// Feature report (bidirectional). + Feature = 3, +} + +/// Callback type for receiving asynchronous input reports. +pub type HidIoReportCallback = + unsafe extern "efiapi" fn(report_buffer_size: u16, report_buffer: *mut c_void, context: *mut c_void); + +/// The HID_IO protocol FFI interface. +#[repr(C)] +pub struct HidIoProtocol { + /// Retrieves the HID report descriptor from the device. + pub get_report_descriptor: unsafe extern "efiapi" fn( + this: *const HidIoProtocol, + report_descriptor_size: *mut usize, + report_descriptor_buffer: *mut c_void, + ) -> efi::Status, + /// Retrieves a HID report of the specified type from the device. + pub get_report: unsafe extern "efiapi" fn( + this: *const HidIoProtocol, + report_id: u8, + report_type: HidReportType, + report_buffer_size: usize, + report_buffer: *mut c_void, + ) -> efi::Status, + /// Sends a HID report of the specified type to the device. + pub set_report: unsafe extern "efiapi" fn( + this: *const HidIoProtocol, + report_id: u8, + report_type: HidReportType, + report_buffer_size: usize, + report_buffer: *mut c_void, + ) -> efi::Status, + /// Registers a callback for asynchronous input report notifications. + pub register_report_callback: unsafe extern "efiapi" fn( + this: *const HidIoProtocol, + callback: HidIoReportCallback, + context: *mut c_void, + ) -> efi::Status, + /// Unregisters a previously registered input report callback. + pub unregister_report_callback: + unsafe extern "efiapi" fn(this: *const HidIoProtocol, callback: HidIoReportCallback) -> efi::Status, +} + +// SAFETY: HidIoProtocol is a C-compatible struct whose layout matches the HidIo GUID interface. +unsafe impl crate::uefi_protocol::ProtocolInterface for HidIoProtocol { + const PROTOCOL_GUID: crate::BinaryGuid = HID_IO_PROTOCOL_GUID; +}