uefi_raw/protocol/
device_path.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3mod device_path_gen;
4
5use crate::{guid, Boolean, Char16, Guid};
6
7pub use device_path_gen::{acpi, bios_boot_spec, end, hardware, media, messaging};
8
9/// Device path protocol.
10///
11/// A device path contains one or more device path instances made up of
12/// variable-length nodes.
13///
14/// Note that the fields in this struct define the header at the start of each
15/// node; a device path is typically larger than these four bytes.
16#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
17#[repr(C)]
18pub struct DevicePathProtocol {
19    pub major_type: DeviceType,
20    pub sub_type: DeviceSubType,
21    /// Total length of the type including the fixed header as u16 in LE order.
22    pub length: [u8; 2],
23    // followed by payload (dynamically sized)
24}
25
26impl DevicePathProtocol {
27    pub const GUID: Guid = guid!("09576e91-6d3f-11d2-8e39-00a0c969723b");
28
29    /// Returns the total length of the device path node.
30    #[must_use]
31    pub const fn length(&self) -> u16 {
32        u16::from_le_bytes(self.length)
33    }
34}
35
36newtype_enum! {
37/// Type identifier for a device path node.
38pub enum DeviceType: u8 => {
39    /// Hardware Device Path.
40    ///
41    /// This Device Path defines how a device is attached to the resource domain of a system, where resource domain is
42    /// simply the shared memory, memory mapped I/ O, and I/O space of the system.
43    HARDWARE = 0x01,
44    /// ACPI Device Path.
45    ///
46    /// This Device Path is used to describe devices whose enumeration is not described in an industry-standard fashion.
47    /// These devices must be described using ACPI AML in the ACPI namespace; this Device Path is a linkage to the ACPI
48    /// namespace.
49    ACPI = 0x02,
50    /// Messaging Device Path.
51    ///
52    /// This Device Path is used to describe the connection of devices outside the resource domain of the system. This
53    /// Device Path can describe physical messaging information such as a SCSI ID, or abstract information such as
54    /// networking protocol IP addresses.
55    MESSAGING = 0x03,
56    /// Media Device Path.
57    ///
58    /// This Device Path is used to describe the portion of a medium that is being abstracted by a boot service.
59    /// For example, a Media Device Path could define which partition on a hard drive was being used.
60    MEDIA = 0x04,
61    /// BIOS Boot Specification Device Path.
62    ///
63    /// This Device Path is used to point to boot legacy operating systems; it is based on the BIOS Boot Specification
64    /// Version 1.01.
65    BIOS_BOOT_SPEC = 0x05,
66    /// End of Hardware Device Path.
67    ///
68    /// Depending on the Sub-Type, this Device Path node is used to indicate the end of the Device Path instance or
69    /// Device Path structure.
70    END = 0x7F,
71}}
72
73/// Sub-type identifier for a device path node.
74#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
75#[repr(transparent)]
76pub struct DeviceSubType(pub u8);
77
78impl DeviceSubType {
79    /// PCI Device Path.
80    pub const HARDWARE_PCI: Self = Self(1);
81    /// PCCARD Device Path.
82    pub const HARDWARE_PCCARD: Self = Self(2);
83    /// Memory-mapped Device Path.
84    pub const HARDWARE_MEMORY_MAPPED: Self = Self(3);
85    /// Vendor-Defined Device Path.
86    pub const HARDWARE_VENDOR: Self = Self(4);
87    /// Controller Device Path.
88    pub const HARDWARE_CONTROLLER: Self = Self(5);
89    /// BMC Device Path.
90    pub const HARDWARE_BMC: Self = Self(6);
91
92    /// ACPI Device Path.
93    pub const ACPI: Self = Self(1);
94    /// Expanded ACPI Device Path.
95    pub const ACPI_EXPANDED: Self = Self(2);
96    /// ACPI _ADR Device Path.
97    pub const ACPI_ADR: Self = Self(3);
98    /// NVDIMM Device Path.
99    pub const ACPI_NVDIMM: Self = Self(4);
100
101    /// ATAPI Device Path.
102    pub const MESSAGING_ATAPI: Self = Self(1);
103    /// SCSI Device Path.
104    pub const MESSAGING_SCSI: Self = Self(2);
105    /// Fibre Channel Device Path.
106    pub const MESSAGING_FIBRE_CHANNEL: Self = Self(3);
107    /// 1394 Device Path.
108    pub const MESSAGING_1394: Self = Self(4);
109    /// USB Device Path.
110    pub const MESSAGING_USB: Self = Self(5);
111    /// I2O Device Path.
112    pub const MESSAGING_I2O: Self = Self(6);
113    /// Infiniband Device Path.
114    pub const MESSAGING_INFINIBAND: Self = Self(9);
115    /// Vendor-Defined Device Path.
116    pub const MESSAGING_VENDOR: Self = Self(10);
117    /// MAC Address Device Path.
118    pub const MESSAGING_MAC_ADDRESS: Self = Self(11);
119    /// IPV4 Device Path.
120    pub const MESSAGING_IPV4: Self = Self(12);
121    /// IPV6 Device Path.
122    pub const MESSAGING_IPV6: Self = Self(13);
123    /// UART Device Path.
124    pub const MESSAGING_UART: Self = Self(14);
125    /// USB Class Device Path.
126    pub const MESSAGING_USB_CLASS: Self = Self(15);
127    /// USB WWID Device Path.
128    pub const MESSAGING_USB_WWID: Self = Self(16);
129    /// Device Logical Unit.
130    pub const MESSAGING_DEVICE_LOGICAL_UNIT: Self = Self(17);
131    /// SATA Device Path.
132    pub const MESSAGING_SATA: Self = Self(18);
133    /// iSCSI Device Path node (base information).
134    pub const MESSAGING_ISCSI: Self = Self(19);
135    /// VLAN Device Path node.
136    pub const MESSAGING_VLAN: Self = Self(20);
137    /// Fibre Channel Ex Device Path.
138    pub const MESSAGING_FIBRE_CHANNEL_EX: Self = Self(21);
139    /// Serial Attached SCSI (SAS) Ex Device Path.
140    pub const MESSAGING_SCSI_SAS_EX: Self = Self(22);
141    /// NVM Express Namespace Device Path.
142    pub const MESSAGING_NVME_NAMESPACE: Self = Self(23);
143    /// Uniform Resource Identifiers (URI) Device Path.
144    pub const MESSAGING_URI: Self = Self(24);
145    /// UFS Device Path.
146    pub const MESSAGING_UFS: Self = Self(25);
147    /// SD (Secure Digital) Device Path.
148    pub const MESSAGING_SD: Self = Self(26);
149    /// Bluetooth Device Path.
150    pub const MESSAGING_BLUETOOTH: Self = Self(27);
151    /// Wi-Fi Device Path.
152    pub const MESSAGING_WIFI: Self = Self(28);
153    /// eMMC (Embedded Multi-Media Card) Device Path.
154    pub const MESSAGING_EMMC: Self = Self(29);
155    /// BluetoothLE Device Path.
156    pub const MESSAGING_BLUETOOTH_LE: Self = Self(30);
157    /// DNS Device Path.
158    pub const MESSAGING_DNS: Self = Self(31);
159    /// NVDIMM Namespace Device Path.
160    pub const MESSAGING_NVDIMM_NAMESPACE: Self = Self(32);
161    /// REST Service Device Path.
162    pub const MESSAGING_REST_SERVICE: Self = Self(33);
163    /// NVME over Fabric (NVMe-oF) Namespace Device Path.
164    pub const MESSAGING_NVME_OF_NAMESPACE: Self = Self(34);
165
166    /// Hard Drive Media Device Path.
167    pub const MEDIA_HARD_DRIVE: Self = Self(1);
168    /// CD-ROM Media Device Path.
169    pub const MEDIA_CD_ROM: Self = Self(2);
170    /// Vendor-Defined Media Device Path.
171    pub const MEDIA_VENDOR: Self = Self(3);
172    /// File Path Media Device Path.
173    pub const MEDIA_FILE_PATH: Self = Self(4);
174    /// Media Protocol Device Path.
175    pub const MEDIA_PROTOCOL: Self = Self(5);
176    /// PIWG Firmware File.
177    pub const MEDIA_PIWG_FIRMWARE_FILE: Self = Self(6);
178    /// PIWG Firmware Volume.
179    pub const MEDIA_PIWG_FIRMWARE_VOLUME: Self = Self(7);
180    /// Relative Offset Range.
181    pub const MEDIA_RELATIVE_OFFSET_RANGE: Self = Self(8);
182    /// RAM Disk Device Path.
183    pub const MEDIA_RAM_DISK: Self = Self(9);
184
185    /// BIOS Boot Specification Device Path.
186    pub const BIOS_BOOT_SPECIFICATION: Self = Self(1);
187
188    /// End this instance of a Device Path and start a new one.
189    pub const END_INSTANCE: Self = Self(0x01);
190    /// End entire Device Path.
191    pub const END_ENTIRE: Self = Self(0xff);
192}
193
194#[derive(Debug)]
195#[repr(C)]
196pub struct DevicePathToTextProtocol {
197    pub convert_device_node_to_text: unsafe extern "efiapi" fn(
198        device_node: *const DevicePathProtocol,
199        display_only: Boolean,
200        allow_shortcuts: Boolean,
201    ) -> *const Char16,
202    pub convert_device_path_to_text: unsafe extern "efiapi" fn(
203        device_path: *const DevicePathProtocol,
204        display_only: Boolean,
205        allow_shortcuts: Boolean,
206    ) -> *const Char16,
207}
208
209impl DevicePathToTextProtocol {
210    pub const GUID: Guid = guid!("8b843e20-8132-4852-90cc-551a4e4a7f1c");
211}
212
213#[derive(Debug)]
214#[repr(C)]
215pub struct DevicePathFromTextProtocol {
216    pub convert_text_to_device_node:
217        unsafe extern "efiapi" fn(text_device_node: *const Char16) -> *const DevicePathProtocol,
218    pub convert_text_to_device_path:
219        unsafe extern "efiapi" fn(text_device_path: *const Char16) -> *const DevicePathProtocol,
220}
221
222impl DevicePathFromTextProtocol {
223    pub const GUID: Guid = guid!("05c99a21-c70f-4ad2-8a5f-35df3343f51e");
224}
225
226#[derive(Debug)]
227#[repr(C)]
228pub struct DevicePathUtilitiesProtocol {
229    pub get_device_path_size:
230        unsafe extern "efiapi" fn(device_path: *const DevicePathProtocol) -> usize,
231    pub duplicate_device_path: unsafe extern "efiapi" fn(
232        device_path: *const DevicePathProtocol,
233    ) -> *const DevicePathProtocol,
234    pub append_device_path: unsafe extern "efiapi" fn(
235        src1: *const DevicePathProtocol,
236        src2: *const DevicePathProtocol,
237    ) -> *const DevicePathProtocol,
238    pub append_device_node: unsafe extern "efiapi" fn(
239        device_path: *const DevicePathProtocol,
240        device_node: *const DevicePathProtocol,
241    ) -> *const DevicePathProtocol,
242    pub append_device_path_instance: unsafe extern "efiapi" fn(
243        device_path: *const DevicePathProtocol,
244        device_path_instance: *const DevicePathProtocol,
245    ) -> *const DevicePathProtocol,
246    pub get_next_device_path_instance: unsafe extern "efiapi" fn(
247        device_path_instance: *mut *const DevicePathProtocol,
248        device_path_instance_size: *mut usize,
249    ) -> *const DevicePathProtocol,
250    pub is_device_path_multi_instance:
251        unsafe extern "efiapi" fn(device_path: *const DevicePathProtocol) -> bool,
252    pub create_device_node: unsafe extern "efiapi" fn(
253        node_type: DeviceType,
254        node_sub_type: DeviceSubType,
255        node_length: u16,
256    ) -> *const DevicePathProtocol,
257}
258
259impl DevicePathUtilitiesProtocol {
260    pub const GUID: Guid = guid!("0379be4e-d706-437d-b037-edb82fb772a4");
261}
262
263#[cfg(test)]
264mod tests {
265    use super::*;
266    use core::mem;
267
268    /// Test that ensures the struct is packed. Thus, we don't need to
269    /// explicitly specify `packed`.
270    #[test]
271    fn abi() {
272        assert_eq!(mem::size_of::<DevicePathProtocol>(), 4);
273        assert_eq!(mem::align_of::<DevicePathProtocol>(), 1);
274    }
275}