1const uefi = @import("std").os.uefi; 2const Guid = uefi.Guid; 3 4pub const DevicePathProtocol = packed struct { 5 type: DevicePathType, 6 subtype: u8, 7 length: u16, 8 9 pub const guid align(8) = Guid{ 10 .time_low = 0x09576e91, 11 .time_mid = 0x6d3f, 12 .time_high_and_version = 0x11d2, 13 .clock_seq_high_and_reserved = 0x8e, 14 .clock_seq_low = 0x39, 15 .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b }, 16 }; 17 18 pub fn getDevicePath(self: *const DevicePathProtocol) ?DevicePath { 19 return switch (self.type) { 20 .Hardware => blk: { 21 const hardware: ?HardwareDevicePath = switch (@intToEnum(HardwareDevicePath.Subtype, self.subtype)) { 22 .Pci => .{ .Pci = @ptrCast(*const HardwareDevicePath.PciDevicePath, self) }, 23 .PcCard => .{ .PcCard = @ptrCast(*const HardwareDevicePath.PcCardDevicePath, self) }, 24 .MemoryMapped => .{ .MemoryMapped = @ptrCast(*const HardwareDevicePath.MemoryMappedDevicePath, self) }, 25 .Vendor => .{ .Vendor = @ptrCast(*const HardwareDevicePath.VendorDevicePath, self) }, 26 .Controller => .{ .Controller = @ptrCast(*const HardwareDevicePath.ControllerDevicePath, self) }, 27 .Bmc => .{ .Bmc = @ptrCast(*const HardwareDevicePath.BmcDevicePath, self) }, 28 _ => null, 29 }; 30 break :blk if (hardware) |h| .{ .Hardware = h } else null; 31 }, 32 .Acpi => blk: { 33 const acpi: ?AcpiDevicePath = switch (@intToEnum(AcpiDevicePath.Subtype, self.subtype)) { 34 else => null, // TODO 35 }; 36 break :blk if (acpi) |a| .{ .Acpi = a } else null; 37 }, 38 .Messaging => blk: { 39 const messaging: ?MessagingDevicePath = switch (@intToEnum(MessagingDevicePath.Subtype, self.subtype)) { 40 else => null, // TODO 41 }; 42 break :blk if (messaging) |m| .{ .Messaging = m } else null; 43 }, 44 .Media => blk: { 45 const media: ?MediaDevicePath = switch (@intToEnum(MediaDevicePath.Subtype, self.subtype)) { 46 .HardDrive => .{ .HardDrive = @ptrCast(*const MediaDevicePath.HardDriveDevicePath, self) }, 47 .Cdrom => .{ .Cdrom = @ptrCast(*const MediaDevicePath.CdromDevicePath, self) }, 48 .Vendor => .{ .Vendor = @ptrCast(*const MediaDevicePath.VendorDevicePath, self) }, 49 .FilePath => .{ .FilePath = @ptrCast(*const MediaDevicePath.FilePathDevicePath, self) }, 50 .MediaProtocol => .{ .MediaProtocol = @ptrCast(*const MediaDevicePath.MediaProtocolDevicePath, self) }, 51 .PiwgFirmwareFile => .{ .PiwgFirmwareFile = @ptrCast(*const MediaDevicePath.PiwgFirmwareFileDevicePath, self) }, 52 .PiwgFirmwareVolume => .{ .PiwgFirmwareVolume = @ptrCast(*const MediaDevicePath.PiwgFirmwareVolumeDevicePath, self) }, 53 .RelativeOffsetRange => .{ .RelativeOffsetRange = @ptrCast(*const MediaDevicePath.RelativeOffsetRangeDevicePath, self) }, 54 .RamDisk => .{ .RamDisk = @ptrCast(*const MediaDevicePath.RamDiskDevicePath, self) }, 55 _ => null, 56 }; 57 break :blk if (media) |m| .{ .Media = m } else null; 58 }, 59 .BiosBootSpecification => blk: { 60 const bbs: ?BiosBootSpecificationDevicePath = switch (@intToEnum(BiosBootSpecificationDevicePath.Subtype, self.subtype)) { 61 .BBS101 => .{ .BBS101 = @ptrCast(*const BiosBootSpecificationDevicePath.BBS101DevicePath, self) }, 62 _ => null, 63 }; 64 break :blk if (bbs) |b| .{ .BiosBootSpecification = b } else null; 65 }, 66 .End => blk: { 67 const end: ?EndDevicePath = switch (@intToEnum(EndDevicePath.Subtype, self.subtype)) { 68 .EndEntire => .{ .EndEntire = @ptrCast(*const EndDevicePath.EndEntireDevicePath, self) }, 69 .EndThisInstance => .{ .EndThisInstance = @ptrCast(*const EndDevicePath.EndThisInstanceDevicePath, self) }, 70 _ => null, 71 }; 72 break :blk if (end) |e| .{ .End = e } else null; 73 }, 74 _ => null, 75 }; 76 } 77}; 78 79pub const DevicePath = union(DevicePathType) { 80 Hardware: HardwareDevicePath, 81 Acpi: AcpiDevicePath, 82 Messaging: MessagingDevicePath, 83 Media: MediaDevicePath, 84 BiosBootSpecification: BiosBootSpecificationDevicePath, 85 End: EndDevicePath, 86}; 87 88pub const DevicePathType = enum(u8) { 89 Hardware = 0x01, 90 Acpi = 0x02, 91 Messaging = 0x03, 92 Media = 0x04, 93 BiosBootSpecification = 0x05, 94 End = 0x7f, 95 _, 96}; 97 98pub const HardwareDevicePath = union(Subtype) { 99 Pci: *const PciDevicePath, 100 PcCard: *const PcCardDevicePath, 101 MemoryMapped: *const MemoryMappedDevicePath, 102 Vendor: *const VendorDevicePath, 103 Controller: *const ControllerDevicePath, 104 Bmc: *const BmcDevicePath, 105 106 pub const Subtype = enum(u8) { 107 Pci = 1, 108 PcCard = 2, 109 MemoryMapped = 3, 110 Vendor = 4, 111 Controller = 5, 112 Bmc = 6, 113 _, 114 }; 115 116 pub const PciDevicePath = packed struct { 117 type: DevicePathType, 118 subtype: Subtype, 119 length: u16, 120 // TODO 121 }; 122 123 pub const PcCardDevicePath = packed struct { 124 type: DevicePathType, 125 subtype: Subtype, 126 length: u16, 127 // TODO 128 }; 129 130 pub const MemoryMappedDevicePath = packed struct { 131 type: DevicePathType, 132 subtype: Subtype, 133 length: u16, 134 // TODO 135 }; 136 137 pub const VendorDevicePath = packed struct { 138 type: DevicePathType, 139 subtype: Subtype, 140 length: u16, 141 // TODO 142 }; 143 144 pub const ControllerDevicePath = packed struct { 145 type: DevicePathType, 146 subtype: Subtype, 147 length: u16, 148 // TODO 149 }; 150 151 pub const BmcDevicePath = packed struct { 152 type: DevicePathType, 153 subtype: Subtype, 154 length: u16, 155 // TODO 156 }; 157}; 158 159pub const AcpiDevicePath = union(Subtype) { 160 Acpi: void, // TODO 161 ExpandedAcpi: void, // TODO 162 Adr: void, // TODO 163 Nvdimm: void, // TODO 164 165 pub const Subtype = enum(u8) { 166 Acpi = 1, 167 ExpandedAcpi = 2, 168 Adr = 3, 169 Nvdimm = 4, 170 _, 171 }; 172}; 173 174pub const MessagingDevicePath = union(Subtype) { 175 Atapi: void, // TODO 176 Scsi: void, // TODO 177 FibreChannel: void, // TODO 178 FibreChannelEx: void, // TODO 179 @"1394": void, // TODO 180 Usb: void, // TODO 181 Sata: void, // TODO 182 UsbWwid: void, // TODO 183 Lun: void, // TODO 184 UsbClass: void, // TODO 185 I2o: void, // TODO 186 MacAddress: void, // TODO 187 Ipv4: void, // TODO 188 Ipv6: void, // TODO 189 Vlan: void, // TODO 190 InfiniBand: void, // TODO 191 Uart: void, // TODO 192 Vendor: void, // TODO 193 194 pub const Subtype = enum(u8) { 195 Atapi = 1, 196 Scsi = 2, 197 FibreChannel = 3, 198 FibreChannelEx = 21, 199 @"1394" = 4, 200 Usb = 5, 201 Sata = 18, 202 UsbWwid = 16, 203 Lun = 17, 204 UsbClass = 15, 205 I2o = 6, 206 MacAddress = 11, 207 Ipv4 = 12, 208 Ipv6 = 13, 209 Vlan = 20, 210 InfiniBand = 9, 211 Uart = 14, 212 Vendor = 10, 213 _, 214 }; 215}; 216 217pub const MediaDevicePath = union(Subtype) { 218 HardDrive: *const HardDriveDevicePath, 219 Cdrom: *const CdromDevicePath, 220 Vendor: *const VendorDevicePath, 221 FilePath: *const FilePathDevicePath, 222 MediaProtocol: *const MediaProtocolDevicePath, 223 PiwgFirmwareFile: *const PiwgFirmwareFileDevicePath, 224 PiwgFirmwareVolume: *const PiwgFirmwareVolumeDevicePath, 225 RelativeOffsetRange: *const RelativeOffsetRangeDevicePath, 226 RamDisk: *const RamDiskDevicePath, 227 228 pub const Subtype = enum(u8) { 229 HardDrive = 1, 230 Cdrom = 2, 231 Vendor = 3, 232 FilePath = 4, 233 MediaProtocol = 5, 234 PiwgFirmwareFile = 6, 235 PiwgFirmwareVolume = 7, 236 RelativeOffsetRange = 8, 237 RamDisk = 9, 238 _, 239 }; 240 241 pub const HardDriveDevicePath = packed struct { 242 type: DevicePathType, 243 subtype: Subtype, 244 length: u16, 245 // TODO 246 }; 247 248 pub const CdromDevicePath = packed struct { 249 type: DevicePathType, 250 subtype: Subtype, 251 length: u16, 252 // TODO 253 }; 254 255 pub const VendorDevicePath = packed struct { 256 type: DevicePathType, 257 subtype: Subtype, 258 length: u16, 259 // TODO 260 }; 261 262 pub const FilePathDevicePath = packed struct { 263 type: DevicePathType, 264 subtype: Subtype, 265 length: u16, 266 267 pub fn getPath(self: *const FilePathDevicePath) [*:0]const u16 { 268 return @ptrCast([*:0]const u16, @alignCast(2, @ptrCast([*]const u8, self)) + @sizeOf(FilePathDevicePath)); 269 } 270 }; 271 272 pub const MediaProtocolDevicePath = packed struct { 273 type: DevicePathType, 274 subtype: Subtype, 275 length: u16, 276 // TODO 277 }; 278 279 pub const PiwgFirmwareFileDevicePath = packed struct { 280 type: DevicePathType, 281 subtype: Subtype, 282 length: u16, 283 }; 284 285 pub const PiwgFirmwareVolumeDevicePath = packed struct { 286 type: DevicePathType, 287 subtype: Subtype, 288 length: u16, 289 }; 290 291 pub const RelativeOffsetRangeDevicePath = packed struct { 292 type: DevicePathType, 293 subtype: Subtype, 294 length: u16, 295 reserved: u32, 296 start: u64, 297 end: u64, 298 }; 299 300 pub const RamDiskDevicePath = packed struct { 301 type: DevicePathType, 302 subtype: Subtype, 303 length: u16, 304 start: u64, 305 end: u64, 306 disk_type: uefi.Guid, 307 instance: u16, 308 }; 309}; 310 311pub const BiosBootSpecificationDevicePath = union(Subtype) { 312 BBS101: *const BBS101DevicePath, 313 314 pub const Subtype = enum(u8) { 315 BBS101 = 1, 316 _, 317 }; 318 319 pub const BBS101DevicePath = packed struct { 320 type: DevicePathType, 321 subtype: Subtype, 322 length: u16, 323 device_type: u16, 324 status_flag: u16, 325 326 pub fn getDescription(self: *const BBS101DevicePath) [*:0]const u8 { 327 return @ptrCast([*:0]const u8, self) + @sizeOf(BBS101DevicePath); 328 } 329 }; 330}; 331 332pub const EndDevicePath = union(Subtype) { 333 EndEntire: *const EndEntireDevicePath, 334 EndThisInstance: *const EndThisInstanceDevicePath, 335 336 pub const Subtype = enum(u8) { 337 EndEntire = 0xff, 338 EndThisInstance = 0x01, 339 _, 340 }; 341 342 pub const EndEntireDevicePath = packed struct { 343 type: DevicePathType, 344 subtype: Subtype, 345 length: u16, 346 }; 347 348 pub const EndThisInstanceDevicePath = packed struct { 349 type: DevicePathType, 350 subtype: Subtype, 351 length: u16, 352 }; 353}; 354