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}