Skip to main content

uefi_raw/protocol/
device_path.rs

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