master
1const std = @import("../../std.zig");
2const assert = std.debug.assert;
3const uefi = std.os.uefi;
4const Guid = uefi.Guid;
5
6pub const DevicePath = union(Type) {
7 hardware: Hardware,
8 acpi: Acpi,
9 messaging: Messaging,
10 media: Media,
11 bios_boot_specification: BiosBootSpecification,
12 end: End,
13
14 pub const Type = enum(u8) {
15 hardware = 0x01,
16 acpi = 0x02,
17 messaging = 0x03,
18 media = 0x04,
19 bios_boot_specification = 0x05,
20 end = 0x7f,
21 _,
22 };
23
24 pub const Hardware = union(Subtype) {
25 pci: *const PciDevicePath,
26 pc_card: *const PcCardDevicePath,
27 memory_mapped: *const MemoryMappedDevicePath,
28 vendor: *const VendorDevicePath,
29 controller: *const ControllerDevicePath,
30 bmc: *const BmcDevicePath,
31
32 pub const Subtype = enum(u8) {
33 pci = 1,
34 pc_card = 2,
35 memory_mapped = 3,
36 vendor = 4,
37 controller = 5,
38 bmc = 6,
39 _,
40 };
41
42 pub const PciDevicePath = extern struct {
43 type: DevicePath.Type,
44 subtype: Subtype,
45 length: u16 align(1),
46 function: u8,
47 device: u8,
48 };
49
50 comptime {
51 assert(6 == @sizeOf(PciDevicePath));
52 assert(1 == @alignOf(PciDevicePath));
53
54 assert(0 == @offsetOf(PciDevicePath, "type"));
55 assert(1 == @offsetOf(PciDevicePath, "subtype"));
56 assert(2 == @offsetOf(PciDevicePath, "length"));
57 assert(4 == @offsetOf(PciDevicePath, "function"));
58 assert(5 == @offsetOf(PciDevicePath, "device"));
59 }
60
61 pub const PcCardDevicePath = extern struct {
62 type: DevicePath.Type,
63 subtype: Subtype,
64 length: u16 align(1),
65 function_number: u8,
66 };
67
68 comptime {
69 assert(5 == @sizeOf(PcCardDevicePath));
70 assert(1 == @alignOf(PcCardDevicePath));
71
72 assert(0 == @offsetOf(PcCardDevicePath, "type"));
73 assert(1 == @offsetOf(PcCardDevicePath, "subtype"));
74 assert(2 == @offsetOf(PcCardDevicePath, "length"));
75 assert(4 == @offsetOf(PcCardDevicePath, "function_number"));
76 }
77
78 pub const MemoryMappedDevicePath = extern struct {
79 type: DevicePath.Type,
80 subtype: Subtype,
81 length: u16 align(1),
82 memory_type: u32 align(1),
83 start_address: u64 align(1),
84 end_address: u64 align(1),
85 };
86
87 comptime {
88 assert(24 == @sizeOf(MemoryMappedDevicePath));
89 assert(1 == @alignOf(MemoryMappedDevicePath));
90
91 assert(0 == @offsetOf(MemoryMappedDevicePath, "type"));
92 assert(1 == @offsetOf(MemoryMappedDevicePath, "subtype"));
93 assert(2 == @offsetOf(MemoryMappedDevicePath, "length"));
94 assert(4 == @offsetOf(MemoryMappedDevicePath, "memory_type"));
95 assert(8 == @offsetOf(MemoryMappedDevicePath, "start_address"));
96 assert(16 == @offsetOf(MemoryMappedDevicePath, "end_address"));
97 }
98
99 pub const VendorDevicePath = extern struct {
100 type: DevicePath.Type,
101 subtype: Subtype,
102 length: u16 align(1),
103 vendor_guid: Guid align(1),
104 };
105
106 comptime {
107 assert(20 == @sizeOf(VendorDevicePath));
108 assert(1 == @alignOf(VendorDevicePath));
109
110 assert(0 == @offsetOf(VendorDevicePath, "type"));
111 assert(1 == @offsetOf(VendorDevicePath, "subtype"));
112 assert(2 == @offsetOf(VendorDevicePath, "length"));
113 assert(4 == @offsetOf(VendorDevicePath, "vendor_guid"));
114 }
115
116 pub const ControllerDevicePath = extern struct {
117 type: DevicePath.Type,
118 subtype: Subtype,
119 length: u16 align(1),
120 controller_number: u32 align(1),
121 };
122
123 comptime {
124 assert(8 == @sizeOf(ControllerDevicePath));
125 assert(1 == @alignOf(ControllerDevicePath));
126
127 assert(0 == @offsetOf(ControllerDevicePath, "type"));
128 assert(1 == @offsetOf(ControllerDevicePath, "subtype"));
129 assert(2 == @offsetOf(ControllerDevicePath, "length"));
130 assert(4 == @offsetOf(ControllerDevicePath, "controller_number"));
131 }
132
133 pub const BmcDevicePath = extern struct {
134 type: DevicePath.Type,
135 subtype: Subtype,
136 length: u16 align(1),
137 interface_type: u8,
138 base_address: u64 align(1),
139 };
140
141 comptime {
142 assert(13 == @sizeOf(BmcDevicePath));
143 assert(1 == @alignOf(BmcDevicePath));
144
145 assert(0 == @offsetOf(BmcDevicePath, "type"));
146 assert(1 == @offsetOf(BmcDevicePath, "subtype"));
147 assert(2 == @offsetOf(BmcDevicePath, "length"));
148 assert(4 == @offsetOf(BmcDevicePath, "interface_type"));
149 assert(5 == @offsetOf(BmcDevicePath, "base_address"));
150 }
151 };
152
153 pub const Acpi = union(Subtype) {
154 acpi: *const BaseAcpiDevicePath,
155 expanded_acpi: *const ExpandedAcpiDevicePath,
156 adr: *const AdrDevicePath,
157
158 pub const Subtype = enum(u8) {
159 acpi = 1,
160 expanded_acpi = 2,
161 adr = 3,
162 _,
163 };
164
165 pub const BaseAcpiDevicePath = extern struct {
166 type: DevicePath.Type,
167 subtype: Subtype,
168 length: u16 align(1),
169 hid: u32 align(1),
170 uid: u32 align(1),
171 };
172
173 comptime {
174 assert(12 == @sizeOf(BaseAcpiDevicePath));
175 assert(1 == @alignOf(BaseAcpiDevicePath));
176
177 assert(0 == @offsetOf(BaseAcpiDevicePath, "type"));
178 assert(1 == @offsetOf(BaseAcpiDevicePath, "subtype"));
179 assert(2 == @offsetOf(BaseAcpiDevicePath, "length"));
180 assert(4 == @offsetOf(BaseAcpiDevicePath, "hid"));
181 assert(8 == @offsetOf(BaseAcpiDevicePath, "uid"));
182 }
183
184 pub const ExpandedAcpiDevicePath = extern struct {
185 type: DevicePath.Type,
186 subtype: Subtype,
187 length: u16 align(1),
188 hid: u32 align(1),
189 uid: u32 align(1),
190 cid: u32 align(1),
191 // variable length u16[*:0] strings
192 // hid_str, uid_str, cid_str
193 };
194
195 comptime {
196 assert(16 == @sizeOf(ExpandedAcpiDevicePath));
197 assert(1 == @alignOf(ExpandedAcpiDevicePath));
198
199 assert(0 == @offsetOf(ExpandedAcpiDevicePath, "type"));
200 assert(1 == @offsetOf(ExpandedAcpiDevicePath, "subtype"));
201 assert(2 == @offsetOf(ExpandedAcpiDevicePath, "length"));
202 assert(4 == @offsetOf(ExpandedAcpiDevicePath, "hid"));
203 assert(8 == @offsetOf(ExpandedAcpiDevicePath, "uid"));
204 assert(12 == @offsetOf(ExpandedAcpiDevicePath, "cid"));
205 }
206
207 pub const AdrDevicePath = extern struct {
208 type: DevicePath.Type,
209 subtype: Subtype,
210 length: u16 align(1),
211 adr: u32 align(1),
212
213 // multiple adr entries can optionally follow
214 pub fn adrs(self: *const AdrDevicePath) []align(1) const u32 {
215 // self.length is a minimum of 8 with one adr which is size 4.
216 const entries = (self.length - 4) / @sizeOf(u32);
217 return @as([*]align(1) const u32, @ptrCast(&self.adr))[0..entries];
218 }
219 };
220
221 comptime {
222 assert(8 == @sizeOf(AdrDevicePath));
223 assert(1 == @alignOf(AdrDevicePath));
224
225 assert(0 == @offsetOf(AdrDevicePath, "type"));
226 assert(1 == @offsetOf(AdrDevicePath, "subtype"));
227 assert(2 == @offsetOf(AdrDevicePath, "length"));
228 assert(4 == @offsetOf(AdrDevicePath, "adr"));
229 }
230 };
231
232 pub const Messaging = union(Subtype) {
233 atapi: *const AtapiDevicePath,
234 scsi: *const ScsiDevicePath,
235 fibre_channel: *const FibreChannelDevicePath,
236 fibre_channel_ex: *const FibreChannelExDevicePath,
237 @"1394": *const F1394DevicePath,
238 usb: *const UsbDevicePath,
239 sata: *const SataDevicePath,
240 usb_wwid: *const UsbWwidDevicePath,
241 lun: *const DeviceLogicalUnitDevicePath,
242 usb_class: *const UsbClassDevicePath,
243 i2o: *const I2oDevicePath,
244 mac_address: *const MacAddressDevicePath,
245 ipv4: *const Ipv4DevicePath,
246 ipv6: *const Ipv6DevicePath,
247 vlan: *const VlanDevicePath,
248 infini_band: *const InfiniBandDevicePath,
249 uart: *const UartDevicePath,
250 vendor: *const VendorDefinedDevicePath,
251
252 pub const Subtype = enum(u8) {
253 atapi = 1,
254 scsi = 2,
255 fibre_channel = 3,
256 fibre_channel_ex = 21,
257 @"1394" = 4,
258 usb = 5,
259 sata = 18,
260 usb_wwid = 16,
261 lun = 17,
262 usb_class = 15,
263 i2o = 6,
264 mac_address = 11,
265 ipv4 = 12,
266 ipv6 = 13,
267 vlan = 20,
268 infini_band = 9,
269 uart = 14,
270 vendor = 10,
271 _,
272 };
273
274 pub const AtapiDevicePath = extern struct {
275 pub const Role = enum(u8) {
276 master = 0,
277 slave = 1,
278 };
279
280 pub const Rank = enum(u8) {
281 primary = 0,
282 secondary = 1,
283 };
284
285 type: DevicePath.Type,
286 subtype: Subtype,
287 length: u16 align(1),
288 primary_secondary: Rank,
289 slave_master: Role,
290 logical_unit_number: u16 align(1),
291 };
292
293 comptime {
294 assert(8 == @sizeOf(AtapiDevicePath));
295 assert(1 == @alignOf(AtapiDevicePath));
296
297 assert(0 == @offsetOf(AtapiDevicePath, "type"));
298 assert(1 == @offsetOf(AtapiDevicePath, "subtype"));
299 assert(2 == @offsetOf(AtapiDevicePath, "length"));
300 assert(4 == @offsetOf(AtapiDevicePath, "primary_secondary"));
301 assert(5 == @offsetOf(AtapiDevicePath, "slave_master"));
302 assert(6 == @offsetOf(AtapiDevicePath, "logical_unit_number"));
303 }
304
305 pub const ScsiDevicePath = extern struct {
306 type: DevicePath.Type,
307 subtype: Subtype,
308 length: u16 align(1),
309 target_id: u16 align(1),
310 logical_unit_number: u16 align(1),
311 };
312
313 comptime {
314 assert(8 == @sizeOf(ScsiDevicePath));
315 assert(1 == @alignOf(ScsiDevicePath));
316
317 assert(0 == @offsetOf(ScsiDevicePath, "type"));
318 assert(1 == @offsetOf(ScsiDevicePath, "subtype"));
319 assert(2 == @offsetOf(ScsiDevicePath, "length"));
320 assert(4 == @offsetOf(ScsiDevicePath, "target_id"));
321 assert(6 == @offsetOf(ScsiDevicePath, "logical_unit_number"));
322 }
323
324 pub const FibreChannelDevicePath = extern struct {
325 type: DevicePath.Type,
326 subtype: Subtype,
327 length: u16 align(1),
328 reserved: u32 align(1),
329 world_wide_name: u64 align(1),
330 logical_unit_number: u64 align(1),
331 };
332
333 comptime {
334 assert(24 == @sizeOf(FibreChannelDevicePath));
335 assert(1 == @alignOf(FibreChannelDevicePath));
336
337 assert(0 == @offsetOf(FibreChannelDevicePath, "type"));
338 assert(1 == @offsetOf(FibreChannelDevicePath, "subtype"));
339 assert(2 == @offsetOf(FibreChannelDevicePath, "length"));
340 assert(4 == @offsetOf(FibreChannelDevicePath, "reserved"));
341 assert(8 == @offsetOf(FibreChannelDevicePath, "world_wide_name"));
342 assert(16 == @offsetOf(FibreChannelDevicePath, "logical_unit_number"));
343 }
344
345 pub const FibreChannelExDevicePath = extern struct {
346 type: DevicePath.Type,
347 subtype: Subtype,
348 length: u16 align(1),
349 reserved: u32 align(1),
350 world_wide_name: u64 align(1),
351 logical_unit_number: u64 align(1),
352 };
353
354 comptime {
355 assert(24 == @sizeOf(FibreChannelExDevicePath));
356 assert(1 == @alignOf(FibreChannelExDevicePath));
357
358 assert(0 == @offsetOf(FibreChannelExDevicePath, "type"));
359 assert(1 == @offsetOf(FibreChannelExDevicePath, "subtype"));
360 assert(2 == @offsetOf(FibreChannelExDevicePath, "length"));
361 assert(4 == @offsetOf(FibreChannelExDevicePath, "reserved"));
362 assert(8 == @offsetOf(FibreChannelExDevicePath, "world_wide_name"));
363 assert(16 == @offsetOf(FibreChannelExDevicePath, "logical_unit_number"));
364 }
365
366 pub const F1394DevicePath = extern struct {
367 type: DevicePath.Type,
368 subtype: Subtype,
369 length: u16 align(1),
370 reserved: u32 align(1),
371 guid: u64 align(1),
372 };
373
374 comptime {
375 assert(16 == @sizeOf(F1394DevicePath));
376 assert(1 == @alignOf(F1394DevicePath));
377
378 assert(0 == @offsetOf(F1394DevicePath, "type"));
379 assert(1 == @offsetOf(F1394DevicePath, "subtype"));
380 assert(2 == @offsetOf(F1394DevicePath, "length"));
381 assert(4 == @offsetOf(F1394DevicePath, "reserved"));
382 assert(8 == @offsetOf(F1394DevicePath, "guid"));
383 }
384
385 pub const UsbDevicePath = extern struct {
386 type: DevicePath.Type,
387 subtype: Subtype,
388 length: u16 align(1),
389 parent_port_number: u8,
390 interface_number: u8,
391 };
392
393 comptime {
394 assert(6 == @sizeOf(UsbDevicePath));
395 assert(1 == @alignOf(UsbDevicePath));
396
397 assert(0 == @offsetOf(UsbDevicePath, "type"));
398 assert(1 == @offsetOf(UsbDevicePath, "subtype"));
399 assert(2 == @offsetOf(UsbDevicePath, "length"));
400 assert(4 == @offsetOf(UsbDevicePath, "parent_port_number"));
401 assert(5 == @offsetOf(UsbDevicePath, "interface_number"));
402 }
403
404 pub const SataDevicePath = extern struct {
405 type: DevicePath.Type,
406 subtype: Subtype,
407 length: u16 align(1),
408 hba_port_number: u16 align(1),
409 port_multiplier_port_number: u16 align(1),
410 logical_unit_number: u16 align(1),
411 };
412
413 comptime {
414 assert(10 == @sizeOf(SataDevicePath));
415 assert(1 == @alignOf(SataDevicePath));
416
417 assert(0 == @offsetOf(SataDevicePath, "type"));
418 assert(1 == @offsetOf(SataDevicePath, "subtype"));
419 assert(2 == @offsetOf(SataDevicePath, "length"));
420 assert(4 == @offsetOf(SataDevicePath, "hba_port_number"));
421 assert(6 == @offsetOf(SataDevicePath, "port_multiplier_port_number"));
422 assert(8 == @offsetOf(SataDevicePath, "logical_unit_number"));
423 }
424
425 pub const UsbWwidDevicePath = extern struct {
426 type: DevicePath.Type,
427 subtype: Subtype,
428 length: u16 align(1),
429 interface_number: u16 align(1),
430 device_vendor_id: u16 align(1),
431 device_product_id: u16 align(1),
432
433 pub fn serial_number(self: *const UsbWwidDevicePath) []align(1) const u16 {
434 const serial_len = (self.length - @sizeOf(UsbWwidDevicePath)) / @sizeOf(u16);
435 return @as([*]align(1) const u16, @ptrCast(@as([*]const u8, @ptrCast(self)) + @sizeOf(UsbWwidDevicePath)))[0..serial_len];
436 }
437 };
438
439 comptime {
440 assert(10 == @sizeOf(UsbWwidDevicePath));
441 assert(1 == @alignOf(UsbWwidDevicePath));
442
443 assert(0 == @offsetOf(UsbWwidDevicePath, "type"));
444 assert(1 == @offsetOf(UsbWwidDevicePath, "subtype"));
445 assert(2 == @offsetOf(UsbWwidDevicePath, "length"));
446 assert(4 == @offsetOf(UsbWwidDevicePath, "interface_number"));
447 assert(6 == @offsetOf(UsbWwidDevicePath, "device_vendor_id"));
448 assert(8 == @offsetOf(UsbWwidDevicePath, "device_product_id"));
449 }
450
451 pub const DeviceLogicalUnitDevicePath = extern struct {
452 type: DevicePath.Type,
453 subtype: Subtype,
454 length: u16 align(1),
455 lun: u8,
456 };
457
458 comptime {
459 assert(5 == @sizeOf(DeviceLogicalUnitDevicePath));
460 assert(1 == @alignOf(DeviceLogicalUnitDevicePath));
461
462 assert(0 == @offsetOf(DeviceLogicalUnitDevicePath, "type"));
463 assert(1 == @offsetOf(DeviceLogicalUnitDevicePath, "subtype"));
464 assert(2 == @offsetOf(DeviceLogicalUnitDevicePath, "length"));
465 assert(4 == @offsetOf(DeviceLogicalUnitDevicePath, "lun"));
466 }
467
468 pub const UsbClassDevicePath = extern struct {
469 type: DevicePath.Type,
470 subtype: Subtype,
471 length: u16 align(1),
472 vendor_id: u16 align(1),
473 product_id: u16 align(1),
474 device_class: u8,
475 device_subclass: u8,
476 device_protocol: u8,
477 };
478
479 comptime {
480 assert(11 == @sizeOf(UsbClassDevicePath));
481 assert(1 == @alignOf(UsbClassDevicePath));
482
483 assert(0 == @offsetOf(UsbClassDevicePath, "type"));
484 assert(1 == @offsetOf(UsbClassDevicePath, "subtype"));
485 assert(2 == @offsetOf(UsbClassDevicePath, "length"));
486 assert(4 == @offsetOf(UsbClassDevicePath, "vendor_id"));
487 assert(6 == @offsetOf(UsbClassDevicePath, "product_id"));
488 assert(8 == @offsetOf(UsbClassDevicePath, "device_class"));
489 assert(9 == @offsetOf(UsbClassDevicePath, "device_subclass"));
490 assert(10 == @offsetOf(UsbClassDevicePath, "device_protocol"));
491 }
492
493 pub const I2oDevicePath = extern struct {
494 type: DevicePath.Type,
495 subtype: Subtype,
496 length: u16 align(1),
497 tid: u32 align(1),
498 };
499
500 comptime {
501 assert(8 == @sizeOf(I2oDevicePath));
502 assert(1 == @alignOf(I2oDevicePath));
503
504 assert(0 == @offsetOf(I2oDevicePath, "type"));
505 assert(1 == @offsetOf(I2oDevicePath, "subtype"));
506 assert(2 == @offsetOf(I2oDevicePath, "length"));
507 assert(4 == @offsetOf(I2oDevicePath, "tid"));
508 }
509
510 pub const MacAddressDevicePath = extern struct {
511 type: DevicePath.Type,
512 subtype: Subtype,
513 length: u16 align(1),
514 mac_address: uefi.MacAddress,
515 if_type: u8,
516 };
517
518 comptime {
519 assert(37 == @sizeOf(MacAddressDevicePath));
520 assert(1 == @alignOf(MacAddressDevicePath));
521
522 assert(0 == @offsetOf(MacAddressDevicePath, "type"));
523 assert(1 == @offsetOf(MacAddressDevicePath, "subtype"));
524 assert(2 == @offsetOf(MacAddressDevicePath, "length"));
525 assert(4 == @offsetOf(MacAddressDevicePath, "mac_address"));
526 assert(36 == @offsetOf(MacAddressDevicePath, "if_type"));
527 }
528
529 pub const Ipv4DevicePath = extern struct {
530 pub const IpType = enum(u8) {
531 dhcp = 0,
532 static = 1,
533 };
534
535 type: DevicePath.Type,
536 subtype: Subtype,
537 length: u16 align(1),
538 local_ip_address: uefi.Ipv4Address align(1),
539 remote_ip_address: uefi.Ipv4Address align(1),
540 local_port: u16 align(1),
541 remote_port: u16 align(1),
542 network_protocol: u16 align(1),
543 static_ip_address: IpType,
544 gateway_ip_address: u32 align(1),
545 subnet_mask: u32 align(1),
546 };
547
548 comptime {
549 assert(27 == @sizeOf(Ipv4DevicePath));
550 assert(1 == @alignOf(Ipv4DevicePath));
551
552 assert(0 == @offsetOf(Ipv4DevicePath, "type"));
553 assert(1 == @offsetOf(Ipv4DevicePath, "subtype"));
554 assert(2 == @offsetOf(Ipv4DevicePath, "length"));
555 assert(4 == @offsetOf(Ipv4DevicePath, "local_ip_address"));
556 assert(8 == @offsetOf(Ipv4DevicePath, "remote_ip_address"));
557 assert(12 == @offsetOf(Ipv4DevicePath, "local_port"));
558 assert(14 == @offsetOf(Ipv4DevicePath, "remote_port"));
559 assert(16 == @offsetOf(Ipv4DevicePath, "network_protocol"));
560 assert(18 == @offsetOf(Ipv4DevicePath, "static_ip_address"));
561 assert(19 == @offsetOf(Ipv4DevicePath, "gateway_ip_address"));
562 assert(23 == @offsetOf(Ipv4DevicePath, "subnet_mask"));
563 }
564
565 pub const Ipv6DevicePath = extern struct {
566 pub const Origin = enum(u8) {
567 manual = 0,
568 assigned_stateless = 1,
569 assigned_stateful = 2,
570 };
571
572 type: DevicePath.Type,
573 subtype: Subtype,
574 length: u16 align(1),
575 local_ip_address: uefi.Ipv6Address,
576 remote_ip_address: uefi.Ipv6Address,
577 local_port: u16 align(1),
578 remote_port: u16 align(1),
579 protocol: u16 align(1),
580 ip_address_origin: Origin,
581 prefix_length: u8,
582 gateway_ip_address: uefi.Ipv6Address,
583 };
584
585 comptime {
586 assert(60 == @sizeOf(Ipv6DevicePath));
587 assert(1 == @alignOf(Ipv6DevicePath));
588
589 assert(0 == @offsetOf(Ipv6DevicePath, "type"));
590 assert(1 == @offsetOf(Ipv6DevicePath, "subtype"));
591 assert(2 == @offsetOf(Ipv6DevicePath, "length"));
592 assert(4 == @offsetOf(Ipv6DevicePath, "local_ip_address"));
593 assert(20 == @offsetOf(Ipv6DevicePath, "remote_ip_address"));
594 assert(36 == @offsetOf(Ipv6DevicePath, "local_port"));
595 assert(38 == @offsetOf(Ipv6DevicePath, "remote_port"));
596 assert(40 == @offsetOf(Ipv6DevicePath, "protocol"));
597 assert(42 == @offsetOf(Ipv6DevicePath, "ip_address_origin"));
598 assert(43 == @offsetOf(Ipv6DevicePath, "prefix_length"));
599 assert(44 == @offsetOf(Ipv6DevicePath, "gateway_ip_address"));
600 }
601
602 pub const VlanDevicePath = extern struct {
603 type: DevicePath.Type,
604 subtype: Subtype,
605 length: u16 align(1),
606 vlan_id: u16 align(1),
607 };
608
609 comptime {
610 assert(6 == @sizeOf(VlanDevicePath));
611 assert(1 == @alignOf(VlanDevicePath));
612
613 assert(0 == @offsetOf(VlanDevicePath, "type"));
614 assert(1 == @offsetOf(VlanDevicePath, "subtype"));
615 assert(2 == @offsetOf(VlanDevicePath, "length"));
616 assert(4 == @offsetOf(VlanDevicePath, "vlan_id"));
617 }
618
619 pub const InfiniBandDevicePath = extern struct {
620 pub const ResourceFlags = packed struct(u32) {
621 pub const ControllerType = enum(u1) {
622 ioc = 0,
623 service = 1,
624 };
625
626 ioc_or_service: ControllerType,
627 extend_boot_environment: bool,
628 console_protocol: bool,
629 storage_protocol: bool,
630 network_protocol: bool,
631
632 // u1 + 4 * bool = 5 bits, we need a total of 32 bits
633 reserved: u27,
634 };
635
636 type: DevicePath.Type,
637 subtype: Subtype,
638 length: u16 align(1),
639 resource_flags: ResourceFlags align(1),
640 port_gid: [16]u8,
641 service_id: u64 align(1),
642 target_port_id: u64 align(1),
643 device_id: u64 align(1),
644 };
645
646 comptime {
647 assert(48 == @sizeOf(InfiniBandDevicePath));
648 assert(1 == @alignOf(InfiniBandDevicePath));
649
650 assert(0 == @offsetOf(InfiniBandDevicePath, "type"));
651 assert(1 == @offsetOf(InfiniBandDevicePath, "subtype"));
652 assert(2 == @offsetOf(InfiniBandDevicePath, "length"));
653 assert(4 == @offsetOf(InfiniBandDevicePath, "resource_flags"));
654 assert(8 == @offsetOf(InfiniBandDevicePath, "port_gid"));
655 assert(24 == @offsetOf(InfiniBandDevicePath, "service_id"));
656 assert(32 == @offsetOf(InfiniBandDevicePath, "target_port_id"));
657 assert(40 == @offsetOf(InfiniBandDevicePath, "device_id"));
658 }
659
660 pub const UartDevicePath = extern struct {
661 pub const Parity = enum(u8) {
662 default = 0,
663 none = 1,
664 even = 2,
665 odd = 3,
666 mark = 4,
667 space = 5,
668 _,
669 };
670
671 pub const StopBits = enum(u8) {
672 default = 0,
673 one = 1,
674 one_and_a_half = 2,
675 two = 3,
676 _,
677 };
678
679 type: DevicePath.Type,
680 subtype: Subtype,
681 length: u16 align(1),
682 reserved: u32 align(1),
683 baud_rate: u64 align(1),
684 data_bits: u8,
685 parity: Parity,
686 stop_bits: StopBits,
687 };
688
689 comptime {
690 assert(19 == @sizeOf(UartDevicePath));
691 assert(1 == @alignOf(UartDevicePath));
692
693 assert(0 == @offsetOf(UartDevicePath, "type"));
694 assert(1 == @offsetOf(UartDevicePath, "subtype"));
695 assert(2 == @offsetOf(UartDevicePath, "length"));
696 assert(4 == @offsetOf(UartDevicePath, "reserved"));
697 assert(8 == @offsetOf(UartDevicePath, "baud_rate"));
698 assert(16 == @offsetOf(UartDevicePath, "data_bits"));
699 assert(17 == @offsetOf(UartDevicePath, "parity"));
700 assert(18 == @offsetOf(UartDevicePath, "stop_bits"));
701 }
702
703 pub const VendorDefinedDevicePath = extern struct {
704 type: DevicePath.Type,
705 subtype: Subtype,
706 length: u16 align(1),
707 vendor_guid: Guid align(1),
708 };
709
710 comptime {
711 assert(20 == @sizeOf(VendorDefinedDevicePath));
712 assert(1 == @alignOf(VendorDefinedDevicePath));
713
714 assert(0 == @offsetOf(VendorDefinedDevicePath, "type"));
715 assert(1 == @offsetOf(VendorDefinedDevicePath, "subtype"));
716 assert(2 == @offsetOf(VendorDefinedDevicePath, "length"));
717 assert(4 == @offsetOf(VendorDefinedDevicePath, "vendor_guid"));
718 }
719 };
720
721 pub const Media = union(Subtype) {
722 hard_drive: *const HardDriveDevicePath,
723 cdrom: *const CdromDevicePath,
724 vendor: *const VendorDevicePath,
725 file_path: *const FilePathDevicePath,
726 media_protocol: *const MediaProtocolDevicePath,
727 piwg_firmware_file: *const PiwgFirmwareFileDevicePath,
728 piwg_firmware_volume: *const PiwgFirmwareVolumeDevicePath,
729 relative_offset_range: *const RelativeOffsetRangeDevicePath,
730 ram_disk: *const RamDiskDevicePath,
731
732 pub const Subtype = enum(u8) {
733 hard_drive = 1,
734 cdrom = 2,
735 vendor = 3,
736 file_path = 4,
737 media_protocol = 5,
738 piwg_firmware_file = 6,
739 piwg_firmware_volume = 7,
740 relative_offset_range = 8,
741 ram_disk = 9,
742 _,
743 };
744
745 pub const HardDriveDevicePath = extern struct {
746 pub const Format = enum(u8) {
747 legacy_mbr = 0x01,
748 guid_partition_table = 0x02,
749 };
750
751 pub const SignatureType = enum(u8) {
752 no_signature = 0x00,
753 /// "32-bit signature from address 0x1b8 of the type 0x01 MBR"
754 mbr_signature = 0x01,
755 guid_signature = 0x02,
756 };
757
758 type: DevicePath.Type,
759 subtype: Subtype,
760 length: u16 align(1),
761 partition_number: u32 align(1),
762 partition_start: u64 align(1),
763 partition_size: u64 align(1),
764 partition_signature: [16]u8,
765 partition_format: Format,
766 signature_type: SignatureType,
767 };
768
769 comptime {
770 assert(42 == @sizeOf(HardDriveDevicePath));
771 assert(1 == @alignOf(HardDriveDevicePath));
772
773 assert(0 == @offsetOf(HardDriveDevicePath, "type"));
774 assert(1 == @offsetOf(HardDriveDevicePath, "subtype"));
775 assert(2 == @offsetOf(HardDriveDevicePath, "length"));
776 assert(4 == @offsetOf(HardDriveDevicePath, "partition_number"));
777 assert(8 == @offsetOf(HardDriveDevicePath, "partition_start"));
778 assert(16 == @offsetOf(HardDriveDevicePath, "partition_size"));
779 assert(24 == @offsetOf(HardDriveDevicePath, "partition_signature"));
780 assert(40 == @offsetOf(HardDriveDevicePath, "partition_format"));
781 assert(41 == @offsetOf(HardDriveDevicePath, "signature_type"));
782 }
783
784 pub const CdromDevicePath = extern struct {
785 type: DevicePath.Type,
786 subtype: Subtype,
787 length: u16 align(1),
788 boot_entry: u32 align(1),
789 partition_start: u64 align(1),
790 partition_size: u64 align(1),
791 };
792
793 comptime {
794 assert(24 == @sizeOf(CdromDevicePath));
795 assert(1 == @alignOf(CdromDevicePath));
796
797 assert(0 == @offsetOf(CdromDevicePath, "type"));
798 assert(1 == @offsetOf(CdromDevicePath, "subtype"));
799 assert(2 == @offsetOf(CdromDevicePath, "length"));
800 assert(4 == @offsetOf(CdromDevicePath, "boot_entry"));
801 assert(8 == @offsetOf(CdromDevicePath, "partition_start"));
802 assert(16 == @offsetOf(CdromDevicePath, "partition_size"));
803 }
804
805 pub const VendorDevicePath = extern struct {
806 type: DevicePath.Type,
807 subtype: Subtype,
808 length: u16 align(1),
809 guid: Guid align(1),
810 };
811
812 comptime {
813 assert(20 == @sizeOf(VendorDevicePath));
814 assert(1 == @alignOf(VendorDevicePath));
815
816 assert(0 == @offsetOf(VendorDevicePath, "type"));
817 assert(1 == @offsetOf(VendorDevicePath, "subtype"));
818 assert(2 == @offsetOf(VendorDevicePath, "length"));
819 assert(4 == @offsetOf(VendorDevicePath, "guid"));
820 }
821
822 pub const FilePathDevicePath = extern struct {
823 type: DevicePath.Type,
824 subtype: Subtype,
825 length: u16 align(1),
826
827 pub fn getPath(self: *const FilePathDevicePath) [*:0]align(1) const u16 {
828 return @as([*:0]align(1) const u16, @ptrCast(@as([*]const u8, @ptrCast(self)) + @sizeOf(FilePathDevicePath)));
829 }
830 };
831
832 comptime {
833 assert(4 == @sizeOf(FilePathDevicePath));
834 assert(1 == @alignOf(FilePathDevicePath));
835
836 assert(0 == @offsetOf(FilePathDevicePath, "type"));
837 assert(1 == @offsetOf(FilePathDevicePath, "subtype"));
838 assert(2 == @offsetOf(FilePathDevicePath, "length"));
839 }
840
841 pub const MediaProtocolDevicePath = extern struct {
842 type: DevicePath.Type,
843 subtype: Subtype,
844 length: u16 align(1),
845 guid: Guid align(1),
846 };
847
848 comptime {
849 assert(20 == @sizeOf(MediaProtocolDevicePath));
850 assert(1 == @alignOf(MediaProtocolDevicePath));
851
852 assert(0 == @offsetOf(MediaProtocolDevicePath, "type"));
853 assert(1 == @offsetOf(MediaProtocolDevicePath, "subtype"));
854 assert(2 == @offsetOf(MediaProtocolDevicePath, "length"));
855 assert(4 == @offsetOf(MediaProtocolDevicePath, "guid"));
856 }
857
858 pub const PiwgFirmwareFileDevicePath = extern struct {
859 type: DevicePath.Type,
860 subtype: Subtype,
861 length: u16 align(1),
862 fv_filename: Guid align(1),
863 };
864
865 comptime {
866 assert(20 == @sizeOf(PiwgFirmwareFileDevicePath));
867 assert(1 == @alignOf(PiwgFirmwareFileDevicePath));
868
869 assert(0 == @offsetOf(PiwgFirmwareFileDevicePath, "type"));
870 assert(1 == @offsetOf(PiwgFirmwareFileDevicePath, "subtype"));
871 assert(2 == @offsetOf(PiwgFirmwareFileDevicePath, "length"));
872 assert(4 == @offsetOf(PiwgFirmwareFileDevicePath, "fv_filename"));
873 }
874
875 pub const PiwgFirmwareVolumeDevicePath = extern struct {
876 type: DevicePath.Type,
877 subtype: Subtype,
878 length: u16 align(1),
879 fv_name: Guid align(1),
880 };
881
882 comptime {
883 assert(20 == @sizeOf(PiwgFirmwareVolumeDevicePath));
884 assert(1 == @alignOf(PiwgFirmwareVolumeDevicePath));
885
886 assert(0 == @offsetOf(PiwgFirmwareVolumeDevicePath, "type"));
887 assert(1 == @offsetOf(PiwgFirmwareVolumeDevicePath, "subtype"));
888 assert(2 == @offsetOf(PiwgFirmwareVolumeDevicePath, "length"));
889 assert(4 == @offsetOf(PiwgFirmwareVolumeDevicePath, "fv_name"));
890 }
891
892 pub const RelativeOffsetRangeDevicePath = extern struct {
893 type: DevicePath.Type,
894 subtype: Subtype,
895 length: u16 align(1),
896 reserved: u32 align(1),
897 start: u64 align(1),
898 end: u64 align(1),
899 };
900
901 comptime {
902 assert(24 == @sizeOf(RelativeOffsetRangeDevicePath));
903 assert(1 == @alignOf(RelativeOffsetRangeDevicePath));
904
905 assert(0 == @offsetOf(RelativeOffsetRangeDevicePath, "type"));
906 assert(1 == @offsetOf(RelativeOffsetRangeDevicePath, "subtype"));
907 assert(2 == @offsetOf(RelativeOffsetRangeDevicePath, "length"));
908 assert(4 == @offsetOf(RelativeOffsetRangeDevicePath, "reserved"));
909 assert(8 == @offsetOf(RelativeOffsetRangeDevicePath, "start"));
910 assert(16 == @offsetOf(RelativeOffsetRangeDevicePath, "end"));
911 }
912
913 pub const RamDiskDevicePath = extern struct {
914 type: DevicePath.Type,
915 subtype: Subtype,
916 length: u16 align(1),
917 start: u64 align(1),
918 end: u64 align(1),
919 disk_type: Guid align(1),
920 instance: u16 align(1),
921 };
922
923 comptime {
924 assert(38 == @sizeOf(RamDiskDevicePath));
925 assert(1 == @alignOf(RamDiskDevicePath));
926
927 assert(0 == @offsetOf(RamDiskDevicePath, "type"));
928 assert(1 == @offsetOf(RamDiskDevicePath, "subtype"));
929 assert(2 == @offsetOf(RamDiskDevicePath, "length"));
930 assert(4 == @offsetOf(RamDiskDevicePath, "start"));
931 assert(12 == @offsetOf(RamDiskDevicePath, "end"));
932 assert(20 == @offsetOf(RamDiskDevicePath, "disk_type"));
933 assert(36 == @offsetOf(RamDiskDevicePath, "instance"));
934 }
935 };
936
937 pub const BiosBootSpecification = union(Subtype) {
938 bbs101: *const BBS101DevicePath,
939
940 pub const Subtype = enum(u8) {
941 bbs101 = 1,
942 _,
943 };
944
945 pub const BBS101DevicePath = extern struct {
946 type: DevicePath.Type,
947 subtype: Subtype,
948 length: u16 align(1),
949 device_type: u16 align(1),
950 status_flag: u16 align(1),
951
952 pub fn getDescription(self: *const BBS101DevicePath) [*:0]const u8 {
953 return @as([*:0]const u8, @ptrCast(self)) + @sizeOf(BBS101DevicePath);
954 }
955 };
956
957 comptime {
958 assert(8 == @sizeOf(BBS101DevicePath));
959 assert(1 == @alignOf(BBS101DevicePath));
960
961 assert(0 == @offsetOf(BBS101DevicePath, "type"));
962 assert(1 == @offsetOf(BBS101DevicePath, "subtype"));
963 assert(2 == @offsetOf(BBS101DevicePath, "length"));
964 assert(4 == @offsetOf(BBS101DevicePath, "device_type"));
965 assert(6 == @offsetOf(BBS101DevicePath, "status_flag"));
966 }
967 };
968
969 pub const End = union(Subtype) {
970 end_entire: *const EndEntireDevicePath,
971 end_this_instance: *const EndThisInstanceDevicePath,
972
973 pub const Subtype = enum(u8) {
974 end_entire = 0xff,
975 end_this_instance = 0x01,
976 _,
977 };
978
979 pub const EndEntireDevicePath = extern struct {
980 type: DevicePath.Type,
981 subtype: Subtype,
982 length: u16 align(1),
983 };
984
985 comptime {
986 assert(4 == @sizeOf(EndEntireDevicePath));
987 assert(1 == @alignOf(EndEntireDevicePath));
988
989 assert(0 == @offsetOf(EndEntireDevicePath, "type"));
990 assert(1 == @offsetOf(EndEntireDevicePath, "subtype"));
991 assert(2 == @offsetOf(EndEntireDevicePath, "length"));
992 }
993
994 pub const EndThisInstanceDevicePath = extern struct {
995 type: DevicePath.Type,
996 subtype: Subtype,
997 length: u16 align(1),
998 };
999
1000 comptime {
1001 assert(4 == @sizeOf(EndEntireDevicePath));
1002 assert(1 == @alignOf(EndEntireDevicePath));
1003
1004 assert(0 == @offsetOf(EndEntireDevicePath, "type"));
1005 assert(1 == @offsetOf(EndEntireDevicePath, "subtype"));
1006 assert(2 == @offsetOf(EndEntireDevicePath, "length"));
1007 }
1008 };
1009};