1 1.3 jmcneill /* $NetBSD: dpath.c,v 1.4 2021/09/30 19:02:48 jmcneill Exp $ */ 2 1.1 jakllsch 3 1.1 jakllsch /*++ 4 1.1 jakllsch 5 1.1 jakllsch Copyright (c) 1998 Intel Corporation 6 1.1 jakllsch 7 1.1 jakllsch Module Name: 8 1.1 jakllsch 9 1.1 jakllsch dpath.c 10 1.1 jakllsch 11 1.1 jakllsch Abstract: 12 1.1 jakllsch MBR & Device Path functions 13 1.1 jakllsch 14 1.1 jakllsch 15 1.1 jakllsch 16 1.1 jakllsch Revision History 17 1.1 jakllsch 18 1.3 jmcneill 2014/04 B.Burette - updated device path text representation, conforming to 19 1.3 jmcneill UEFI specification 2.4 (dec. 2013). More specifically: 20 1.3 jmcneill - 9.3.5: added some media types ie. Sata() 21 1.3 jmcneill - 9.6.1.2: Acpi(PNP0A03,0) makes more sense when displayed as PciRoot(0) 22 1.3 jmcneill - 9.6.1.5: use commas (instead of '|') between option specific parameters 23 1.3 jmcneill - 9.6.1.6: hex values in device paths must be preceded by "0x" or "0X" 24 1.3 jmcneill 25 1.1 jakllsch --*/ 26 1.1 jakllsch 27 1.1 jakllsch #include "lib.h" 28 1.1 jakllsch 29 1.1 jakllsch #define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0) 30 1.1 jakllsch 31 1.1 jakllsch 32 1.1 jakllsch 33 1.1 jakllsch EFI_DEVICE_PATH * 34 1.1 jakllsch DevicePathFromHandle ( 35 1.1 jakllsch IN EFI_HANDLE Handle 36 1.1 jakllsch ) 37 1.1 jakllsch { 38 1.1 jakllsch EFI_STATUS Status; 39 1.1 jakllsch EFI_DEVICE_PATH *DevicePath; 40 1.1 jakllsch 41 1.1 jakllsch Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handle, &DevicePathProtocol, (VOID*)&DevicePath); 42 1.1 jakllsch if (EFI_ERROR(Status)) { 43 1.1 jakllsch DevicePath = NULL; 44 1.1 jakllsch } 45 1.1 jakllsch 46 1.1 jakllsch return DevicePath; 47 1.1 jakllsch } 48 1.1 jakllsch 49 1.1 jakllsch 50 1.1 jakllsch EFI_DEVICE_PATH * 51 1.1 jakllsch DevicePathInstance ( 52 1.1 jakllsch IN OUT EFI_DEVICE_PATH **DevicePath, 53 1.1 jakllsch OUT UINTN *Size 54 1.1 jakllsch ) 55 1.1 jakllsch { 56 1.1 jakllsch EFI_DEVICE_PATH *Start, *Next, *DevPath; 57 1.1 jakllsch UINTN Count; 58 1.1 jakllsch 59 1.1 jakllsch DevPath = *DevicePath; 60 1.1 jakllsch Start = DevPath; 61 1.1 jakllsch 62 1.1 jakllsch if (!DevPath) { 63 1.1 jakllsch return NULL; 64 1.1 jakllsch } 65 1.1 jakllsch 66 1.1 jakllsch // 67 1.1 jakllsch // Check for end of device path type 68 1.3 jmcneill // 69 1.1 jakllsch 70 1.1 jakllsch for (Count = 0; ; Count++) { 71 1.1 jakllsch Next = NextDevicePathNode(DevPath); 72 1.1 jakllsch 73 1.1 jakllsch if (IsDevicePathEndType(DevPath)) { 74 1.1 jakllsch break; 75 1.1 jakllsch } 76 1.1 jakllsch 77 1.1 jakllsch if (Count > 01000) { 78 1.1 jakllsch // 79 1.1 jakllsch // BugBug: Debug code to catch bogus device paths 80 1.1 jakllsch // 81 1.1 jakllsch DEBUG((D_ERROR, "DevicePathInstance: DevicePath %x Size %d", *DevicePath, ((UINT8 *) DevPath) - ((UINT8 *) Start) )); 82 1.1 jakllsch DumpHex (0, 0, ((UINT8 *) DevPath) - ((UINT8 *) Start), Start); 83 1.1 jakllsch break; 84 1.1 jakllsch } 85 1.1 jakllsch 86 1.1 jakllsch DevPath = Next; 87 1.1 jakllsch } 88 1.1 jakllsch 89 1.1 jakllsch ASSERT (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE || 90 1.1 jakllsch DevicePathSubType(DevPath) == END_INSTANCE_DEVICE_PATH_SUBTYPE); 91 1.1 jakllsch 92 1.1 jakllsch // 93 1.1 jakllsch // Set next position 94 1.1 jakllsch // 95 1.1 jakllsch 96 1.1 jakllsch if (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) { 97 1.1 jakllsch Next = NULL; 98 1.1 jakllsch } 99 1.1 jakllsch 100 1.1 jakllsch *DevicePath = Next; 101 1.1 jakllsch 102 1.1 jakllsch // 103 1.1 jakllsch // Return size and start of device path instance 104 1.1 jakllsch // 105 1.1 jakllsch 106 1.1 jakllsch *Size = ((UINT8 *) DevPath) - ((UINT8 *) Start); 107 1.1 jakllsch return Start; 108 1.1 jakllsch } 109 1.1 jakllsch 110 1.1 jakllsch UINTN 111 1.1 jakllsch DevicePathInstanceCount ( 112 1.1 jakllsch IN EFI_DEVICE_PATH *DevicePath 113 1.1 jakllsch ) 114 1.1 jakllsch { 115 1.1 jakllsch UINTN Count, Size; 116 1.1 jakllsch 117 1.1 jakllsch Count = 0; 118 1.1 jakllsch while (DevicePathInstance(&DevicePath, &Size)) { 119 1.1 jakllsch Count += 1; 120 1.1 jakllsch } 121 1.1 jakllsch 122 1.1 jakllsch return Count; 123 1.1 jakllsch } 124 1.1 jakllsch 125 1.1 jakllsch 126 1.1 jakllsch EFI_DEVICE_PATH * 127 1.1 jakllsch AppendDevicePath ( 128 1.1 jakllsch IN EFI_DEVICE_PATH *Src1, 129 1.1 jakllsch IN EFI_DEVICE_PATH *Src2 130 1.1 jakllsch ) 131 1.1 jakllsch // Src1 may have multiple "instances" and each instance is appended 132 1.1 jakllsch // Src2 is appended to each instance is Src1. (E.g., it's possible 133 1.3 jmcneill // to append a new instance to the complete device path by passing 134 1.1 jakllsch // it in Src2) 135 1.1 jakllsch { 136 1.1 jakllsch UINTN Src1Size, Src1Inst, Src2Size, Size; 137 1.1 jakllsch EFI_DEVICE_PATH *Dst, *Inst; 138 1.1 jakllsch UINT8 *DstPos; 139 1.1 jakllsch 140 1.1 jakllsch // 141 1.1 jakllsch // If there's only 1 path, just duplicate it 142 1.1 jakllsch // 143 1.1 jakllsch 144 1.1 jakllsch if (!Src1) { 145 1.1 jakllsch ASSERT (!IsDevicePathUnpacked (Src2)); 146 1.1 jakllsch return DuplicateDevicePath (Src2); 147 1.1 jakllsch } 148 1.1 jakllsch 149 1.1 jakllsch if (!Src2) { 150 1.1 jakllsch ASSERT (!IsDevicePathUnpacked (Src1)); 151 1.1 jakllsch return DuplicateDevicePath (Src1); 152 1.1 jakllsch } 153 1.1 jakllsch 154 1.1 jakllsch // 155 1.1 jakllsch // Verify we're not working with unpacked paths 156 1.1 jakllsch // 157 1.1 jakllsch 158 1.1 jakllsch // ASSERT (!IsDevicePathUnpacked (Src1)); 159 1.1 jakllsch // ASSERT (!IsDevicePathUnpacked (Src2)); 160 1.1 jakllsch 161 1.1 jakllsch // 162 1.1 jakllsch // Append Src2 to every instance in Src1 163 1.1 jakllsch // 164 1.1 jakllsch 165 1.1 jakllsch Src1Size = DevicePathSize(Src1); 166 1.1 jakllsch Src1Inst = DevicePathInstanceCount(Src1); 167 1.1 jakllsch Src2Size = DevicePathSize(Src2); 168 1.1 jakllsch Size = Src1Size * Src1Inst + Src2Size; 169 1.3 jmcneill 170 1.1 jakllsch Dst = AllocatePool (Size); 171 1.1 jakllsch if (Dst) { 172 1.1 jakllsch DstPos = (UINT8 *) Dst; 173 1.1 jakllsch 174 1.1 jakllsch // 175 1.1 jakllsch // Copy all device path instances 176 1.1 jakllsch // 177 1.1 jakllsch 178 1.1 jakllsch while ((Inst = DevicePathInstance (&Src1, &Size))) { 179 1.1 jakllsch 180 1.1 jakllsch CopyMem(DstPos, Inst, Size); 181 1.1 jakllsch DstPos += Size; 182 1.1 jakllsch 183 1.1 jakllsch CopyMem(DstPos, Src2, Src2Size); 184 1.1 jakllsch DstPos += Src2Size; 185 1.1 jakllsch 186 1.1 jakllsch CopyMem(DstPos, EndInstanceDevicePath, sizeof(EFI_DEVICE_PATH)); 187 1.1 jakllsch DstPos += sizeof(EFI_DEVICE_PATH); 188 1.1 jakllsch } 189 1.1 jakllsch 190 1.1 jakllsch // Change last end marker 191 1.1 jakllsch DstPos -= sizeof(EFI_DEVICE_PATH); 192 1.1 jakllsch CopyMem(DstPos, EndDevicePath, sizeof(EFI_DEVICE_PATH)); 193 1.1 jakllsch } 194 1.1 jakllsch 195 1.1 jakllsch return Dst; 196 1.1 jakllsch } 197 1.1 jakllsch 198 1.1 jakllsch 199 1.1 jakllsch EFI_DEVICE_PATH * 200 1.1 jakllsch AppendDevicePathNode ( 201 1.1 jakllsch IN EFI_DEVICE_PATH *Src1, 202 1.1 jakllsch IN EFI_DEVICE_PATH *Src2 203 1.1 jakllsch ) 204 1.1 jakllsch // Src1 may have multiple "instances" and each instance is appended 205 1.1 jakllsch // Src2 is a signal device path node (without a terminator) that is 206 1.1 jakllsch // appended to each instance is Src1. 207 1.1 jakllsch { 208 1.1 jakllsch EFI_DEVICE_PATH *Temp, *Eop; 209 1.1 jakllsch UINTN Length; 210 1.1 jakllsch 211 1.1 jakllsch // 212 1.1 jakllsch // Build a Src2 that has a terminator on it 213 1.1 jakllsch // 214 1.1 jakllsch 215 1.1 jakllsch Length = DevicePathNodeLength(Src2); 216 1.1 jakllsch Temp = AllocatePool (Length + sizeof(EFI_DEVICE_PATH)); 217 1.1 jakllsch if (!Temp) { 218 1.1 jakllsch return NULL; 219 1.1 jakllsch } 220 1.1 jakllsch 221 1.1 jakllsch CopyMem (Temp, Src2, Length); 222 1.3 jmcneill Eop = NextDevicePathNode(Temp); 223 1.1 jakllsch SetDevicePathEndNode(Eop); 224 1.1 jakllsch 225 1.1 jakllsch // 226 1.1 jakllsch // Append device paths 227 1.1 jakllsch // 228 1.1 jakllsch 229 1.1 jakllsch Src1 = AppendDevicePath (Src1, Temp); 230 1.1 jakllsch FreePool (Temp); 231 1.1 jakllsch return Src1; 232 1.1 jakllsch } 233 1.1 jakllsch 234 1.1 jakllsch 235 1.1 jakllsch EFI_DEVICE_PATH * 236 1.1 jakllsch FileDevicePath ( 237 1.1 jakllsch IN EFI_HANDLE Device OPTIONAL, 238 1.1 jakllsch IN CHAR16 *FileName 239 1.1 jakllsch ) 240 1.1 jakllsch /*++ 241 1.1 jakllsch 242 1.1 jakllsch N.B. Results are allocated from pool. The caller must FreePool 243 1.1 jakllsch the resulting device path structure 244 1.1 jakllsch 245 1.1 jakllsch --*/ 246 1.1 jakllsch { 247 1.1 jakllsch UINTN Size; 248 1.1 jakllsch FILEPATH_DEVICE_PATH *FilePath; 249 1.3 jmcneill EFI_DEVICE_PATH *Eop, *DevicePath; 250 1.1 jakllsch 251 1.1 jakllsch Size = StrSize(FileName); 252 1.1 jakllsch FilePath = AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof(EFI_DEVICE_PATH)); 253 1.1 jakllsch DevicePath = NULL; 254 1.1 jakllsch 255 1.1 jakllsch if (FilePath) { 256 1.1 jakllsch 257 1.1 jakllsch // 258 1.1 jakllsch // Build a file path 259 1.1 jakllsch // 260 1.1 jakllsch 261 1.1 jakllsch FilePath->Header.Type = MEDIA_DEVICE_PATH; 262 1.1 jakllsch FilePath->Header.SubType = MEDIA_FILEPATH_DP; 263 1.1 jakllsch SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH); 264 1.1 jakllsch CopyMem (FilePath->PathName, FileName, Size); 265 1.1 jakllsch Eop = NextDevicePathNode(&FilePath->Header); 266 1.1 jakllsch SetDevicePathEndNode(Eop); 267 1.1 jakllsch 268 1.1 jakllsch // 269 1.1 jakllsch // Append file path to device's device path 270 1.1 jakllsch // 271 1.1 jakllsch 272 1.1 jakllsch DevicePath = (EFI_DEVICE_PATH *) FilePath; 273 1.1 jakllsch if (Device) { 274 1.1 jakllsch DevicePath = AppendDevicePath ( 275 1.1 jakllsch DevicePathFromHandle(Device), 276 1.1 jakllsch DevicePath 277 1.1 jakllsch ); 278 1.1 jakllsch 279 1.1 jakllsch FreePool(FilePath); 280 1.1 jakllsch } 281 1.1 jakllsch } 282 1.1 jakllsch 283 1.1 jakllsch return DevicePath; 284 1.1 jakllsch } 285 1.1 jakllsch 286 1.1 jakllsch 287 1.1 jakllsch 288 1.1 jakllsch UINTN 289 1.1 jakllsch DevicePathSize ( 290 1.1 jakllsch IN EFI_DEVICE_PATH *DevPath 291 1.1 jakllsch ) 292 1.1 jakllsch { 293 1.1 jakllsch EFI_DEVICE_PATH *Start; 294 1.1 jakllsch 295 1.1 jakllsch // 296 1.1 jakllsch // Search for the end of the device path structure 297 1.3 jmcneill // 298 1.1 jakllsch 299 1.1 jakllsch Start = DevPath; 300 1.1 jakllsch while (!IsDevicePathEnd(DevPath)) { 301 1.1 jakllsch DevPath = NextDevicePathNode(DevPath); 302 1.1 jakllsch } 303 1.1 jakllsch 304 1.1 jakllsch // 305 1.1 jakllsch // Compute the size 306 1.1 jakllsch // 307 1.1 jakllsch 308 1.1 jakllsch return ((UINTN) DevPath - (UINTN) Start) + sizeof(EFI_DEVICE_PATH); 309 1.1 jakllsch } 310 1.1 jakllsch 311 1.1 jakllsch EFI_DEVICE_PATH * 312 1.1 jakllsch DuplicateDevicePath ( 313 1.1 jakllsch IN EFI_DEVICE_PATH *DevPath 314 1.1 jakllsch ) 315 1.1 jakllsch { 316 1.1 jakllsch EFI_DEVICE_PATH *NewDevPath; 317 1.3 jmcneill UINTN Size; 318 1.1 jakllsch 319 1.1 jakllsch 320 1.1 jakllsch // 321 1.1 jakllsch // Compute the size 322 1.1 jakllsch // 323 1.1 jakllsch 324 1.1 jakllsch Size = DevicePathSize (DevPath); 325 1.1 jakllsch 326 1.1 jakllsch // 327 1.1 jakllsch // Make a copy 328 1.1 jakllsch // 329 1.1 jakllsch 330 1.1 jakllsch NewDevPath = AllocatePool (Size); 331 1.1 jakllsch if (NewDevPath) { 332 1.1 jakllsch CopyMem (NewDevPath, DevPath, Size); 333 1.1 jakllsch } 334 1.1 jakllsch 335 1.1 jakllsch return NewDevPath; 336 1.1 jakllsch } 337 1.1 jakllsch 338 1.1 jakllsch EFI_DEVICE_PATH * 339 1.1 jakllsch UnpackDevicePath ( 340 1.1 jakllsch IN EFI_DEVICE_PATH *DevPath 341 1.1 jakllsch ) 342 1.1 jakllsch { 343 1.1 jakllsch EFI_DEVICE_PATH *Src, *Dest, *NewPath; 344 1.1 jakllsch UINTN Size; 345 1.3 jmcneill 346 1.1 jakllsch // 347 1.1 jakllsch // Walk device path and round sizes to valid boundries 348 1.3 jmcneill // 349 1.1 jakllsch 350 1.1 jakllsch Src = DevPath; 351 1.1 jakllsch Size = 0; 352 1.1 jakllsch for (; ;) { 353 1.1 jakllsch Size += DevicePathNodeLength(Src); 354 1.1 jakllsch Size += ALIGN_SIZE(Size); 355 1.1 jakllsch 356 1.1 jakllsch if (IsDevicePathEnd(Src)) { 357 1.1 jakllsch break; 358 1.1 jakllsch } 359 1.1 jakllsch 360 1.1 jakllsch Src = NextDevicePathNode(Src); 361 1.1 jakllsch } 362 1.1 jakllsch 363 1.1 jakllsch 364 1.1 jakllsch // 365 1.1 jakllsch // Allocate space for the unpacked path 366 1.1 jakllsch // 367 1.1 jakllsch 368 1.1 jakllsch NewPath = AllocateZeroPool (Size); 369 1.1 jakllsch if (NewPath) { 370 1.1 jakllsch 371 1.1 jakllsch ASSERT (((UINTN)NewPath) % MIN_ALIGNMENT_SIZE == 0); 372 1.1 jakllsch 373 1.1 jakllsch // 374 1.1 jakllsch // Copy each node 375 1.1 jakllsch // 376 1.1 jakllsch 377 1.1 jakllsch Src = DevPath; 378 1.1 jakllsch Dest = NewPath; 379 1.1 jakllsch for (; ;) { 380 1.1 jakllsch Size = DevicePathNodeLength(Src); 381 1.1 jakllsch CopyMem (Dest, Src, Size); 382 1.1 jakllsch Size += ALIGN_SIZE(Size); 383 1.1 jakllsch SetDevicePathNodeLength (Dest, Size); 384 1.1 jakllsch Dest->Type |= EFI_DP_TYPE_UNPACKED; 385 1.1 jakllsch Dest = (EFI_DEVICE_PATH *) (((UINT8 *) Dest) + Size); 386 1.1 jakllsch 387 1.1 jakllsch if (IsDevicePathEnd(Src)) { 388 1.1 jakllsch break; 389 1.1 jakllsch } 390 1.1 jakllsch 391 1.1 jakllsch Src = NextDevicePathNode(Src); 392 1.1 jakllsch } 393 1.1 jakllsch } 394 1.1 jakllsch 395 1.1 jakllsch return NewPath; 396 1.1 jakllsch } 397 1.1 jakllsch 398 1.1 jakllsch 399 1.1 jakllsch EFI_DEVICE_PATH* 400 1.1 jakllsch AppendDevicePathInstance ( 401 1.1 jakllsch IN EFI_DEVICE_PATH *Src, 402 1.1 jakllsch IN EFI_DEVICE_PATH *Instance 403 1.1 jakllsch ) 404 1.1 jakllsch { 405 1.1 jakllsch UINT8 *Ptr; 406 1.1 jakllsch EFI_DEVICE_PATH *DevPath; 407 1.1 jakllsch UINTN SrcSize; 408 1.1 jakllsch UINTN InstanceSize; 409 1.1 jakllsch 410 1.1 jakllsch if (Src == NULL) { 411 1.1 jakllsch return DuplicateDevicePath (Instance); 412 1.1 jakllsch } 413 1.1 jakllsch SrcSize = DevicePathSize(Src); 414 1.1 jakllsch InstanceSize = DevicePathSize(Instance); 415 1.1 jakllsch Ptr = AllocatePool (SrcSize + InstanceSize); 416 1.1 jakllsch DevPath = (EFI_DEVICE_PATH *)Ptr; 417 1.1 jakllsch ASSERT(DevPath); 418 1.1 jakllsch 419 1.1 jakllsch CopyMem (Ptr, Src, SrcSize); 420 1.1 jakllsch // FreePool (Src); 421 1.3 jmcneill 422 1.1 jakllsch while (!IsDevicePathEnd(DevPath)) { 423 1.1 jakllsch DevPath = NextDevicePathNode(DevPath); 424 1.1 jakllsch } 425 1.1 jakllsch // 426 1.1 jakllsch // Convert the End to an End Instance, since we are 427 1.1 jakllsch // appending another instacne after this one its a good 428 1.1 jakllsch // idea. 429 1.1 jakllsch // 430 1.1 jakllsch DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; 431 1.3 jmcneill 432 1.1 jakllsch DevPath = NextDevicePathNode(DevPath); 433 1.1 jakllsch CopyMem (DevPath, Instance, InstanceSize); 434 1.1 jakllsch return (EFI_DEVICE_PATH *)Ptr; 435 1.1 jakllsch } 436 1.1 jakllsch 437 1.1 jakllsch EFI_STATUS 438 1.1 jakllsch LibDevicePathToInterface ( 439 1.1 jakllsch IN EFI_GUID *Protocol, 440 1.1 jakllsch IN EFI_DEVICE_PATH *FilePath, 441 1.1 jakllsch OUT VOID **Interface 442 1.1 jakllsch ) 443 1.1 jakllsch { 444 1.1 jakllsch EFI_STATUS Status; 445 1.1 jakllsch EFI_HANDLE Device; 446 1.1 jakllsch 447 1.1 jakllsch Status = uefi_call_wrapper(BS->LocateDevicePath, 3, Protocol, &FilePath, &Device); 448 1.1 jakllsch 449 1.1 jakllsch if (!EFI_ERROR(Status)) { 450 1.1 jakllsch 451 1.1 jakllsch // If we didn't get a direct match return not found 452 1.1 jakllsch Status = EFI_NOT_FOUND; 453 1.1 jakllsch 454 1.1 jakllsch if (IsDevicePathEnd(FilePath)) { 455 1.1 jakllsch 456 1.1 jakllsch // 457 1.1 jakllsch // It was a direct match, lookup the protocol interface 458 1.1 jakllsch // 459 1.1 jakllsch 460 1.1 jakllsch Status =uefi_call_wrapper(BS->HandleProtocol, 3, Device, Protocol, Interface); 461 1.1 jakllsch } 462 1.1 jakllsch } 463 1.1 jakllsch 464 1.1 jakllsch // 465 1.1 jakllsch // If there was an error, do not return an interface 466 1.1 jakllsch // 467 1.1 jakllsch 468 1.1 jakllsch if (EFI_ERROR(Status)) { 469 1.1 jakllsch *Interface = NULL; 470 1.1 jakllsch } 471 1.1 jakllsch 472 1.1 jakllsch return Status; 473 1.1 jakllsch } 474 1.1 jakllsch 475 1.3 jmcneill static VOID 476 1.1 jakllsch _DevPathPci ( 477 1.1 jakllsch IN OUT POOL_PRINT *Str, 478 1.1 jakllsch IN VOID *DevPath 479 1.1 jakllsch ) 480 1.1 jakllsch { 481 1.1 jakllsch PCI_DEVICE_PATH *Pci; 482 1.1 jakllsch 483 1.1 jakllsch Pci = DevPath; 484 1.3 jmcneill CatPrint(Str, L"Pci(0x%x,0x%x)", Pci->Device, Pci->Function); 485 1.1 jakllsch } 486 1.1 jakllsch 487 1.3 jmcneill static VOID 488 1.1 jakllsch _DevPathPccard ( 489 1.1 jakllsch IN OUT POOL_PRINT *Str, 490 1.1 jakllsch IN VOID *DevPath 491 1.1 jakllsch ) 492 1.1 jakllsch { 493 1.1 jakllsch PCCARD_DEVICE_PATH *Pccard; 494 1.1 jakllsch 495 1.3 jmcneill Pccard = DevPath; 496 1.3 jmcneill CatPrint(Str, L"Pccard(0x%x)", Pccard-> FunctionNumber ); 497 1.1 jakllsch } 498 1.1 jakllsch 499 1.3 jmcneill static VOID 500 1.1 jakllsch _DevPathMemMap ( 501 1.1 jakllsch IN OUT POOL_PRINT *Str, 502 1.1 jakllsch IN VOID *DevPath 503 1.1 jakllsch ) 504 1.1 jakllsch { 505 1.1 jakllsch MEMMAP_DEVICE_PATH *MemMap; 506 1.1 jakllsch 507 1.3 jmcneill MemMap = DevPath; 508 1.3 jmcneill CatPrint(Str, L"MemMap(%d,0x%x,0x%x)", 509 1.1 jakllsch MemMap->MemoryType, 510 1.1 jakllsch MemMap->StartingAddress, 511 1.1 jakllsch MemMap->EndingAddress 512 1.1 jakllsch ); 513 1.1 jakllsch } 514 1.1 jakllsch 515 1.3 jmcneill static VOID 516 1.1 jakllsch _DevPathController ( 517 1.1 jakllsch IN OUT POOL_PRINT *Str, 518 1.1 jakllsch IN VOID *DevPath 519 1.1 jakllsch ) 520 1.1 jakllsch { 521 1.1 jakllsch CONTROLLER_DEVICE_PATH *Controller; 522 1.1 jakllsch 523 1.1 jakllsch Controller = DevPath; 524 1.1 jakllsch CatPrint(Str, L"Ctrl(%d)", 525 1.1 jakllsch Controller->Controller 526 1.1 jakllsch ); 527 1.1 jakllsch } 528 1.1 jakllsch 529 1.3 jmcneill static VOID 530 1.1 jakllsch _DevPathVendor ( 531 1.1 jakllsch IN OUT POOL_PRINT *Str, 532 1.1 jakllsch IN VOID *DevPath 533 1.1 jakllsch ) 534 1.1 jakllsch { 535 1.1 jakllsch VENDOR_DEVICE_PATH *Vendor; 536 1.1 jakllsch CHAR16 *Type; 537 1.1 jakllsch UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownDevPath; 538 1.1 jakllsch 539 1.1 jakllsch Vendor = DevPath; 540 1.1 jakllsch switch (DevicePathType(&Vendor->Header)) { 541 1.1 jakllsch case HARDWARE_DEVICE_PATH: Type = L"Hw"; break; 542 1.1 jakllsch case MESSAGING_DEVICE_PATH: Type = L"Msg"; break; 543 1.1 jakllsch case MEDIA_DEVICE_PATH: Type = L"Media"; break; 544 1.1 jakllsch default: Type = L"?"; break; 545 1.3 jmcneill } 546 1.1 jakllsch 547 1.1 jakllsch CatPrint(Str, L"Ven%s(%g", Type, &Vendor->Guid); 548 1.1 jakllsch if (CompareGuid (&Vendor->Guid, &UnknownDevice) == 0) { 549 1.1 jakllsch // 550 1.1 jakllsch // GUID used by EFI to enumerate an EDD 1.1 device 551 1.1 jakllsch // 552 1.1 jakllsch UnknownDevPath = (UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *)Vendor; 553 1.1 jakllsch CatPrint(Str, L":%02x)", UnknownDevPath->LegacyDriveLetter); 554 1.1 jakllsch } else { 555 1.1 jakllsch CatPrint(Str, L")"); 556 1.1 jakllsch } 557 1.1 jakllsch } 558 1.1 jakllsch 559 1.1 jakllsch 560 1.3 jmcneill /* 561 1.3 jmcneill Type: 2 (ACPI Device Path) SubType: 1 (ACPI Device Path) 562 1.3 jmcneill */ 563 1.3 jmcneill static VOID 564 1.1 jakllsch _DevPathAcpi ( 565 1.1 jakllsch IN OUT POOL_PRINT *Str, 566 1.1 jakllsch IN VOID *DevPath 567 1.1 jakllsch ) 568 1.1 jakllsch { 569 1.1 jakllsch ACPI_HID_DEVICE_PATH *Acpi; 570 1.1 jakllsch 571 1.1 jakllsch Acpi = DevPath; 572 1.1 jakllsch if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) { 573 1.3 jmcneill switch ( EISA_ID_TO_NUM( Acpi-> HID ) ) { 574 1.3 jmcneill case 0x301 : { 575 1.3 jmcneill CatPrint( Str , L"Keyboard(%d)" , Acpi-> UID ) ; 576 1.3 jmcneill break ; 577 1.3 jmcneill } 578 1.3 jmcneill case 0x401 : { 579 1.3 jmcneill CatPrint( Str , L"ParallelPort(%d)" , Acpi-> UID ) ; 580 1.3 jmcneill break ; 581 1.3 jmcneill } 582 1.3 jmcneill case 0x501 : { 583 1.3 jmcneill CatPrint( Str , L"Serial(%d)" , Acpi-> UID ) ; 584 1.3 jmcneill break ; 585 1.3 jmcneill } 586 1.3 jmcneill case 0x604 : { 587 1.3 jmcneill CatPrint( Str , L"Floppy(%d)" , Acpi-> UID ) ; 588 1.3 jmcneill break ; 589 1.3 jmcneill } 590 1.3 jmcneill case 0xa03 : { 591 1.3 jmcneill CatPrint( Str , L"PciRoot(%d)" , Acpi-> UID ) ; 592 1.3 jmcneill break ; 593 1.3 jmcneill } 594 1.3 jmcneill case 0xa08 : { 595 1.3 jmcneill CatPrint( Str , L"PcieRoot(%d)" , Acpi-> UID ) ; 596 1.3 jmcneill break ; 597 1.3 jmcneill } 598 1.3 jmcneill default : { 599 1.3 jmcneill CatPrint( Str , L"Acpi(PNP%04x" , EISA_ID_TO_NUM( Acpi-> HID ) ) ; 600 1.3 jmcneill if ( Acpi-> UID ) CatPrint( Str , L",%d" , Acpi-> UID ) ; 601 1.3 jmcneill CatPrint( Str , L")" ) ; 602 1.3 jmcneill break ; 603 1.3 jmcneill } 604 1.3 jmcneill } 605 1.1 jakllsch } else { 606 1.3 jmcneill CatPrint( Str , L"Acpi(0x%X" , Acpi-> HID ) ; 607 1.3 jmcneill if ( Acpi-> UID ) CatPrint( Str , L",%d" , Acpi-> UID ) ; 608 1.3 jmcneill CatPrint( Str , L")" , Acpi-> HID , Acpi-> UID ) ; 609 1.1 jakllsch } 610 1.1 jakllsch } 611 1.1 jakllsch 612 1.1 jakllsch 613 1.3 jmcneill static VOID 614 1.1 jakllsch _DevPathAtapi ( 615 1.1 jakllsch IN OUT POOL_PRINT *Str, 616 1.1 jakllsch IN VOID *DevPath 617 1.1 jakllsch ) 618 1.1 jakllsch { 619 1.1 jakllsch ATAPI_DEVICE_PATH *Atapi; 620 1.1 jakllsch 621 1.1 jakllsch Atapi = DevPath; 622 1.3 jmcneill CatPrint(Str, L"Ata(%s,%s)", 623 1.1 jakllsch Atapi->PrimarySecondary ? L"Secondary" : L"Primary", 624 1.1 jakllsch Atapi->SlaveMaster ? L"Slave" : L"Master" 625 1.1 jakllsch ); 626 1.1 jakllsch } 627 1.1 jakllsch 628 1.3 jmcneill static VOID 629 1.1 jakllsch _DevPathScsi ( 630 1.1 jakllsch IN OUT POOL_PRINT *Str, 631 1.1 jakllsch IN VOID *DevPath 632 1.1 jakllsch ) 633 1.1 jakllsch { 634 1.1 jakllsch SCSI_DEVICE_PATH *Scsi; 635 1.1 jakllsch 636 1.1 jakllsch Scsi = DevPath; 637 1.3 jmcneill CatPrint(Str, L"Scsi(%d,%d)", Scsi->Pun, Scsi->Lun); 638 1.1 jakllsch } 639 1.1 jakllsch 640 1.1 jakllsch 641 1.3 jmcneill static VOID 642 1.1 jakllsch _DevPathFibre ( 643 1.1 jakllsch IN OUT POOL_PRINT *Str, 644 1.1 jakllsch IN VOID *DevPath 645 1.1 jakllsch ) 646 1.1 jakllsch { 647 1.1 jakllsch FIBRECHANNEL_DEVICE_PATH *Fibre; 648 1.1 jakllsch 649 1.1 jakllsch Fibre = DevPath; 650 1.3 jmcneill CatPrint( Str , L"Fibre%s(0x%016lx,0x%016lx)" , 651 1.3 jmcneill DevicePathType( & Fibre-> Header ) == MSG_FIBRECHANNEL_DP ? L"" : L"Ex" , 652 1.3 jmcneill Fibre-> WWN , Fibre-> Lun ) ; 653 1.1 jakllsch } 654 1.1 jakllsch 655 1.3 jmcneill static VOID 656 1.1 jakllsch _DevPath1394 ( 657 1.1 jakllsch IN OUT POOL_PRINT *Str, 658 1.1 jakllsch IN VOID *DevPath 659 1.1 jakllsch ) 660 1.1 jakllsch { 661 1.1 jakllsch F1394_DEVICE_PATH *F1394; 662 1.1 jakllsch 663 1.1 jakllsch F1394 = DevPath; 664 1.4 jmcneill // Guid has format of IEEE-EUI64 665 1.4 jmcneill CatPrint(Str, L"I1394(%016lx)", F1394->Guid); 666 1.1 jakllsch } 667 1.1 jakllsch 668 1.1 jakllsch 669 1.1 jakllsch 670 1.3 jmcneill static VOID 671 1.1 jakllsch _DevPathUsb ( 672 1.1 jakllsch IN OUT POOL_PRINT *Str, 673 1.1 jakllsch IN VOID *DevPath 674 1.1 jakllsch ) 675 1.1 jakllsch { 676 1.1 jakllsch USB_DEVICE_PATH *Usb; 677 1.1 jakllsch 678 1.1 jakllsch Usb = DevPath; 679 1.3 jmcneill CatPrint( Str , L"Usb(0x%x,0x%x)" , Usb-> Port , Usb-> Endpoint ) ; 680 1.1 jakllsch } 681 1.1 jakllsch 682 1.1 jakllsch 683 1.3 jmcneill static VOID 684 1.1 jakllsch _DevPathI2O ( 685 1.1 jakllsch IN OUT POOL_PRINT *Str, 686 1.1 jakllsch IN VOID *DevPath 687 1.1 jakllsch ) 688 1.1 jakllsch { 689 1.1 jakllsch I2O_DEVICE_PATH *I2O; 690 1.1 jakllsch 691 1.1 jakllsch I2O = DevPath; 692 1.3 jmcneill CatPrint(Str, L"I2O(0x%X)", I2O->Tid); 693 1.1 jakllsch } 694 1.1 jakllsch 695 1.3 jmcneill static VOID 696 1.1 jakllsch _DevPathMacAddr ( 697 1.1 jakllsch IN OUT POOL_PRINT *Str, 698 1.1 jakllsch IN VOID *DevPath 699 1.1 jakllsch ) 700 1.1 jakllsch { 701 1.1 jakllsch MAC_ADDR_DEVICE_PATH *MAC; 702 1.1 jakllsch UINTN HwAddressSize; 703 1.1 jakllsch UINTN Index; 704 1.1 jakllsch 705 1.1 jakllsch MAC = DevPath; 706 1.1 jakllsch 707 1.3 jmcneill /* HwAddressSize = sizeof(EFI_MAC_ADDRESS); */ 708 1.3 jmcneill HwAddressSize = DevicePathNodeLength( & MAC-> Header ) ; 709 1.3 jmcneill HwAddressSize -= sizeof( MAC-> Header ) ; 710 1.3 jmcneill HwAddressSize -= sizeof( MAC-> IfType ) ; 711 1.1 jakllsch if (MAC->IfType == 0x01 || MAC->IfType == 0x00) { 712 1.1 jakllsch HwAddressSize = 6; 713 1.1 jakllsch } 714 1.3 jmcneill 715 1.1 jakllsch CatPrint(Str, L"Mac("); 716 1.1 jakllsch 717 1.1 jakllsch for(Index = 0; Index < HwAddressSize; Index++) { 718 1.1 jakllsch CatPrint(Str, L"%02x",MAC->MacAddress.Addr[Index]); 719 1.1 jakllsch } 720 1.3 jmcneill if ( MAC-> IfType != 0 ) { 721 1.3 jmcneill CatPrint(Str, L",%d" , MAC-> IfType ) ; 722 1.3 jmcneill } 723 1.1 jakllsch CatPrint(Str, L")"); 724 1.1 jakllsch } 725 1.1 jakllsch 726 1.3 jmcneill static VOID 727 1.3 jmcneill CatPrintIPv4( 728 1.3 jmcneill IN OUT POOL_PRINT * Str , 729 1.3 jmcneill IN EFI_IPv4_ADDRESS * Address 730 1.3 jmcneill ) 731 1.3 jmcneill { 732 1.3 jmcneill CatPrint( Str , L"%d.%d.%d.%d" , Address-> Addr[ 0 ] , Address-> Addr[ 1 ] , 733 1.3 jmcneill Address-> Addr[ 2 ] , Address-> Addr[ 3 ] ) ; 734 1.3 jmcneill } 735 1.3 jmcneill 736 1.3 jmcneill static BOOLEAN 737 1.3 jmcneill IsNotNullIPv4( 738 1.3 jmcneill IN EFI_IPv4_ADDRESS * Address 739 1.3 jmcneill ) 740 1.3 jmcneill { 741 1.3 jmcneill UINT8 val ; 742 1.3 jmcneill val = Address-> Addr[ 0 ] | Address-> Addr[ 1 ] ; 743 1.3 jmcneill val |= Address-> Addr[ 2 ] | Address-> Addr[ 3 ] ; 744 1.3 jmcneill return val != 0 ; 745 1.3 jmcneill } 746 1.3 jmcneill 747 1.3 jmcneill static VOID 748 1.3 jmcneill CatPrintNetworkProtocol( 749 1.3 jmcneill IN OUT POOL_PRINT * Str , 750 1.3 jmcneill IN UINT16 Proto 751 1.3 jmcneill ) 752 1.3 jmcneill { 753 1.3 jmcneill if ( Proto == 6 ) { 754 1.3 jmcneill CatPrint( Str , L"TCP" ) ; 755 1.3 jmcneill } else if ( Proto == 17 ) { 756 1.3 jmcneill CatPrint( Str , L"UDP" ) ; 757 1.3 jmcneill } else { 758 1.3 jmcneill CatPrint( Str , L"%d" , Proto ) ; 759 1.3 jmcneill } 760 1.3 jmcneill } 761 1.3 jmcneill 762 1.3 jmcneill static VOID 763 1.1 jakllsch _DevPathIPv4 ( 764 1.1 jakllsch IN OUT POOL_PRINT *Str, 765 1.1 jakllsch IN VOID *DevPath 766 1.1 jakllsch ) 767 1.1 jakllsch { 768 1.2 mlelstv IPv4_DEVICE_PATH *IP __unused; 769 1.3 jmcneill BOOLEAN show ; 770 1.1 jakllsch 771 1.1 jakllsch IP = DevPath; 772 1.3 jmcneill CatPrint( Str , L"IPv4(") ; 773 1.3 jmcneill CatPrintIPv4( Str , & IP-> RemoteIpAddress ) ; 774 1.3 jmcneill CatPrint( Str , L",") ; 775 1.3 jmcneill CatPrintNetworkProtocol( Str , IP-> Protocol ) ; 776 1.3 jmcneill CatPrint( Str , L",%s" , IP-> StaticIpAddress ? L"Static" : L"DHCP" ) ; 777 1.3 jmcneill show = IsNotNullIPv4( & IP-> LocalIpAddress ) ; 778 1.3 jmcneill if ( ! show && DevicePathNodeLength( & IP-> Header ) == sizeof( IPv4_DEVICE_PATH ) ) { 779 1.3 jmcneill /* only version 2 includes gateway and netmask */ 780 1.3 jmcneill show |= IsNotNullIPv4( & IP-> GatewayIpAddress ) ; 781 1.3 jmcneill show |= IsNotNullIPv4( & IP-> SubnetMask ) ; 782 1.3 jmcneill } 783 1.3 jmcneill if ( show ) { 784 1.3 jmcneill CatPrint( Str , L"," ) ; 785 1.3 jmcneill CatPrintIPv4( Str , & IP-> LocalIpAddress ) ; 786 1.3 jmcneill if ( DevicePathNodeLength( & IP-> Header ) == sizeof( IPv4_DEVICE_PATH ) ) { 787 1.3 jmcneill /* only version 2 includes gateway and netmask */ 788 1.3 jmcneill show = IsNotNullIPv4( & IP-> GatewayIpAddress ) ; 789 1.3 jmcneill show |= IsNotNullIPv4( & IP-> SubnetMask ) ; 790 1.3 jmcneill if ( show ) { 791 1.3 jmcneill CatPrint( Str , L",") ; 792 1.3 jmcneill CatPrintIPv4( Str , & IP-> GatewayIpAddress ) ; 793 1.3 jmcneill if ( IsNotNullIPv4( & IP-> SubnetMask ) ) { 794 1.3 jmcneill CatPrint( Str , L",") ; 795 1.3 jmcneill CatPrintIPv4( Str , & IP-> SubnetMask ) ; 796 1.3 jmcneill } 797 1.3 jmcneill } 798 1.3 jmcneill } 799 1.3 jmcneill } 800 1.3 jmcneill CatPrint( Str , L")") ; 801 1.1 jakllsch } 802 1.1 jakllsch 803 1.3 jmcneill #define CatPrintIPv6_ADD( x , y ) ( ( (UINT16) ( x ) ) << 8 | ( y ) ) 804 1.3 jmcneill static VOID 805 1.3 jmcneill CatPrintIPv6( 806 1.3 jmcneill IN OUT POOL_PRINT * Str , 807 1.3 jmcneill IN EFI_IPv6_ADDRESS * Address 808 1.3 jmcneill ) 809 1.3 jmcneill { 810 1.3 jmcneill CatPrint( Str , L"%x:%x:%x:%x:%x:%x:%x:%x" , 811 1.3 jmcneill CatPrintIPv6_ADD( Address-> Addr[ 0 ] , Address-> Addr[ 1 ] ) , 812 1.3 jmcneill CatPrintIPv6_ADD( Address-> Addr[ 2 ] , Address-> Addr[ 3 ] ) , 813 1.3 jmcneill CatPrintIPv6_ADD( Address-> Addr[ 4 ] , Address-> Addr[ 5 ] ) , 814 1.3 jmcneill CatPrintIPv6_ADD( Address-> Addr[ 6 ] , Address-> Addr[ 7 ] ) , 815 1.3 jmcneill CatPrintIPv6_ADD( Address-> Addr[ 8 ] , Address-> Addr[ 9 ] ) , 816 1.3 jmcneill CatPrintIPv6_ADD( Address-> Addr[ 10 ] , Address-> Addr[ 11 ] ) , 817 1.3 jmcneill CatPrintIPv6_ADD( Address-> Addr[ 12 ] , Address-> Addr[ 13 ] ) , 818 1.3 jmcneill CatPrintIPv6_ADD( Address-> Addr[ 14 ] , Address-> Addr[ 15 ] ) ) ; 819 1.3 jmcneill } 820 1.3 jmcneill 821 1.3 jmcneill static VOID 822 1.1 jakllsch _DevPathIPv6 ( 823 1.1 jakllsch IN OUT POOL_PRINT *Str, 824 1.1 jakllsch IN VOID *DevPath 825 1.1 jakllsch ) 826 1.1 jakllsch { 827 1.2 mlelstv IPv6_DEVICE_PATH *IP __unused; 828 1.1 jakllsch 829 1.1 jakllsch IP = DevPath; 830 1.3 jmcneill CatPrint( Str , L"IPv6(") ; 831 1.3 jmcneill CatPrintIPv6( Str , & IP-> RemoteIpAddress ) ; 832 1.3 jmcneill CatPrint( Str , L",") ; 833 1.3 jmcneill CatPrintNetworkProtocol( Str, IP-> Protocol ) ; 834 1.3 jmcneill CatPrint( Str , L",%s," , IP-> IPAddressOrigin ? 835 1.3 jmcneill ( IP-> IPAddressOrigin == 1 ? L"StatelessAutoConfigure" : 836 1.3 jmcneill L"StatefulAutoConfigure" ) : L"Static" ) ; 837 1.3 jmcneill CatPrintIPv6( Str , & IP-> LocalIpAddress ) ; 838 1.3 jmcneill if ( DevicePathNodeLength( & IP-> Header ) == sizeof( IPv6_DEVICE_PATH ) ) { 839 1.3 jmcneill CatPrint( Str , L",") ; 840 1.3 jmcneill CatPrintIPv6( Str , & IP-> GatewayIpAddress ) ; 841 1.3 jmcneill CatPrint( Str , L",") ; 842 1.3 jmcneill CatPrint( Str , L"%d" , & IP-> PrefixLength ) ; 843 1.3 jmcneill } 844 1.3 jmcneill CatPrint( Str , L")") ; 845 1.1 jakllsch } 846 1.1 jakllsch 847 1.3 jmcneill static VOID 848 1.3 jmcneill _DevPathUri ( 849 1.3 jmcneill IN OUT POOL_PRINT *Str, 850 1.3 jmcneill IN VOID *DevPath 851 1.3 jmcneill ) 852 1.3 jmcneill { 853 1.3 jmcneill URI_DEVICE_PATH *Uri; 854 1.3 jmcneill 855 1.3 jmcneill Uri = DevPath; 856 1.3 jmcneill 857 1.3 jmcneill CatPrint( Str, L"Uri(%a)", Uri->Uri ); 858 1.3 jmcneill } 859 1.3 jmcneill 860 1.3 jmcneill static VOID 861 1.1 jakllsch _DevPathInfiniBand ( 862 1.1 jakllsch IN OUT POOL_PRINT *Str, 863 1.1 jakllsch IN VOID *DevPath 864 1.1 jakllsch ) 865 1.1 jakllsch { 866 1.2 mlelstv INFINIBAND_DEVICE_PATH *InfiniBand __unused; 867 1.1 jakllsch 868 1.1 jakllsch InfiniBand = DevPath; 869 1.4 jmcneill CatPrint(Str, L"Infiniband(0x%x,%g,0x%lx,0x%lx,0x%lx)", 870 1.4 jmcneill InfiniBand->ResourceFlags, InfiniBand->PortGid, InfiniBand->ServiceId, 871 1.4 jmcneill InfiniBand->TargetPortId, InfiniBand->DeviceId); 872 1.1 jakllsch } 873 1.1 jakllsch 874 1.3 jmcneill static VOID 875 1.1 jakllsch _DevPathUart ( 876 1.1 jakllsch IN OUT POOL_PRINT *Str, 877 1.1 jakllsch IN VOID *DevPath 878 1.1 jakllsch ) 879 1.1 jakllsch { 880 1.1 jakllsch UART_DEVICE_PATH *Uart; 881 1.1 jakllsch CHAR8 Parity; 882 1.1 jakllsch 883 1.1 jakllsch Uart = DevPath; 884 1.1 jakllsch switch (Uart->Parity) { 885 1.1 jakllsch case 0 : Parity = 'D'; break; 886 1.1 jakllsch case 1 : Parity = 'N'; break; 887 1.1 jakllsch case 2 : Parity = 'E'; break; 888 1.1 jakllsch case 3 : Parity = 'O'; break; 889 1.1 jakllsch case 4 : Parity = 'M'; break; 890 1.1 jakllsch case 5 : Parity = 'S'; break; 891 1.1 jakllsch default : Parity = 'x'; break; 892 1.1 jakllsch } 893 1.1 jakllsch 894 1.1 jakllsch if (Uart->BaudRate == 0) { 895 1.4 jmcneill CatPrint(Str, L"Uart(DEFAULT,"); 896 1.1 jakllsch } else { 897 1.4 jmcneill CatPrint(Str, L"Uart(%ld,", Uart->BaudRate); 898 1.1 jakllsch } 899 1.1 jakllsch 900 1.1 jakllsch if (Uart->DataBits == 0) { 901 1.4 jmcneill CatPrint(Str, L"DEFAULT,"); 902 1.1 jakllsch } else { 903 1.4 jmcneill CatPrint(Str, L"%d,", Uart->DataBits); 904 1.1 jakllsch } 905 1.1 jakllsch 906 1.4 jmcneill CatPrint(Str, L"%c,", Parity); 907 1.4 jmcneill 908 1.1 jakllsch switch (Uart->StopBits) { 909 1.1 jakllsch case 0 : CatPrint(Str, L"D)"); break; 910 1.1 jakllsch case 1 : CatPrint(Str, L"1)"); break; 911 1.1 jakllsch case 2 : CatPrint(Str, L"1.5)"); break; 912 1.1 jakllsch case 3 : CatPrint(Str, L"2)"); break; 913 1.1 jakllsch default : CatPrint(Str, L"x)"); break; 914 1.1 jakllsch } 915 1.1 jakllsch } 916 1.1 jakllsch 917 1.3 jmcneill static VOID 918 1.3 jmcneill _DevPathSata ( 919 1.3 jmcneill IN OUT POOL_PRINT *Str, 920 1.3 jmcneill IN VOID *DevPath 921 1.3 jmcneill ) 922 1.3 jmcneill { 923 1.3 jmcneill SATA_DEVICE_PATH * Sata ; 924 1.3 jmcneill 925 1.3 jmcneill Sata = DevPath; 926 1.3 jmcneill CatPrint( Str , L"Sata(0x%x,0x%x,0x%x)" , Sata-> HBAPortNumber , 927 1.3 jmcneill Sata-> PortMultiplierPortNumber , Sata-> Lun ) ; 928 1.3 jmcneill } 929 1.1 jakllsch 930 1.3 jmcneill static VOID 931 1.1 jakllsch _DevPathHardDrive ( 932 1.1 jakllsch IN OUT POOL_PRINT *Str, 933 1.1 jakllsch IN VOID *DevPath 934 1.1 jakllsch ) 935 1.1 jakllsch { 936 1.1 jakllsch HARDDRIVE_DEVICE_PATH *Hd; 937 1.1 jakllsch 938 1.1 jakllsch Hd = DevPath; 939 1.1 jakllsch switch (Hd->SignatureType) { 940 1.1 jakllsch case SIGNATURE_TYPE_MBR: 941 1.4 jmcneill CatPrint(Str, L"HD(%d,MBR,0x%08x)", 942 1.1 jakllsch Hd->PartitionNumber, 943 1.1 jakllsch *((UINT32 *)(&(Hd->Signature[0]))) 944 1.1 jakllsch ); 945 1.1 jakllsch break; 946 1.1 jakllsch case SIGNATURE_TYPE_GUID: 947 1.4 jmcneill CatPrint(Str, L"HD(%d,GPT,%g)", 948 1.1 jakllsch Hd->PartitionNumber, 949 1.3 jmcneill (EFI_GUID *) &(Hd->Signature[0]) 950 1.1 jakllsch ); 951 1.1 jakllsch break; 952 1.1 jakllsch default: 953 1.4 jmcneill CatPrint(Str, L"HD(%d,%d,0)", 954 1.1 jakllsch Hd->PartitionNumber, 955 1.1 jakllsch Hd->SignatureType 956 1.1 jakllsch ); 957 1.1 jakllsch break; 958 1.1 jakllsch } 959 1.1 jakllsch } 960 1.1 jakllsch 961 1.3 jmcneill static VOID 962 1.1 jakllsch _DevPathCDROM ( 963 1.1 jakllsch IN OUT POOL_PRINT *Str, 964 1.1 jakllsch IN VOID *DevPath 965 1.1 jakllsch ) 966 1.1 jakllsch { 967 1.1 jakllsch CDROM_DEVICE_PATH *Cd; 968 1.1 jakllsch 969 1.1 jakllsch Cd = DevPath; 970 1.3 jmcneill CatPrint( Str , L"CDROM(0x%x)" , Cd-> BootEntry ) ; 971 1.1 jakllsch } 972 1.1 jakllsch 973 1.3 jmcneill static VOID 974 1.1 jakllsch _DevPathFilePath ( 975 1.1 jakllsch IN OUT POOL_PRINT *Str, 976 1.1 jakllsch IN VOID *DevPath 977 1.1 jakllsch ) 978 1.1 jakllsch { 979 1.3 jmcneill FILEPATH_DEVICE_PATH *Fp; 980 1.1 jakllsch 981 1.1 jakllsch Fp = DevPath; 982 1.1 jakllsch CatPrint(Str, L"%s", Fp->PathName); 983 1.1 jakllsch } 984 1.1 jakllsch 985 1.3 jmcneill static VOID 986 1.1 jakllsch _DevPathMediaProtocol ( 987 1.1 jakllsch IN OUT POOL_PRINT *Str, 988 1.1 jakllsch IN VOID *DevPath 989 1.1 jakllsch ) 990 1.1 jakllsch { 991 1.1 jakllsch MEDIA_PROTOCOL_DEVICE_PATH *MediaProt; 992 1.1 jakllsch 993 1.1 jakllsch MediaProt = DevPath; 994 1.1 jakllsch CatPrint(Str, L"%g", &MediaProt->Protocol); 995 1.1 jakllsch } 996 1.1 jakllsch 997 1.3 jmcneill static VOID 998 1.1 jakllsch _DevPathBssBss ( 999 1.1 jakllsch IN OUT POOL_PRINT *Str, 1000 1.1 jakllsch IN VOID *DevPath 1001 1.1 jakllsch ) 1002 1.1 jakllsch { 1003 1.1 jakllsch BBS_BBS_DEVICE_PATH *Bss; 1004 1.1 jakllsch CHAR16 *Type; 1005 1.1 jakllsch 1006 1.1 jakllsch Bss = DevPath; 1007 1.1 jakllsch switch (Bss->DeviceType) { 1008 1.1 jakllsch case BBS_TYPE_FLOPPY: Type = L"Floppy"; break; 1009 1.1 jakllsch case BBS_TYPE_HARDDRIVE: Type = L"Harddrive"; break; 1010 1.1 jakllsch case BBS_TYPE_CDROM: Type = L"CDROM"; break; 1011 1.1 jakllsch case BBS_TYPE_PCMCIA: Type = L"PCMCIA"; break; 1012 1.1 jakllsch case BBS_TYPE_USB: Type = L"Usb"; break; 1013 1.1 jakllsch case BBS_TYPE_EMBEDDED_NETWORK: Type = L"Net"; break; 1014 1.1 jakllsch default: Type = L"?"; break; 1015 1.1 jakllsch } 1016 1.1 jakllsch 1017 1.1 jakllsch CatPrint(Str, L"Bss-%s(%a)", Type, Bss->String); 1018 1.1 jakllsch } 1019 1.1 jakllsch 1020 1.1 jakllsch 1021 1.3 jmcneill static VOID 1022 1.1 jakllsch _DevPathEndInstance ( 1023 1.1 jakllsch IN OUT POOL_PRINT *Str, 1024 1.3 jmcneill IN VOID *DevPath EFI_UNUSED 1025 1.1 jakllsch ) 1026 1.1 jakllsch { 1027 1.1 jakllsch CatPrint(Str, L","); 1028 1.1 jakllsch } 1029 1.1 jakllsch 1030 1.3 jmcneill /** 1031 1.3 jmcneill * Print unknown device node. 1032 1.3 jmcneill * UEFI 2.4 9.6.1.6 table 89. 1033 1.3 jmcneill */ 1034 1.3 jmcneill 1035 1.3 jmcneill static VOID 1036 1.1 jakllsch _DevPathNodeUnknown ( 1037 1.1 jakllsch IN OUT POOL_PRINT *Str, 1038 1.1 jakllsch IN VOID *DevPath 1039 1.1 jakllsch ) 1040 1.1 jakllsch { 1041 1.3 jmcneill EFI_DEVICE_PATH * Path ; 1042 1.3 jmcneill UINT8 * value ; 1043 1.3 jmcneill int length , index ; 1044 1.3 jmcneill Path = DevPath ; 1045 1.3 jmcneill value = DevPath ; 1046 1.3 jmcneill value += 4 ; 1047 1.3 jmcneill switch ( Path-> Type ) { 1048 1.3 jmcneill case HARDWARE_DEVICE_PATH : { /* Unknown Hardware Device Path */ 1049 1.3 jmcneill CatPrint( Str , L"HardwarePath(%d" , Path-> SubType ) ; 1050 1.3 jmcneill break ; 1051 1.3 jmcneill } 1052 1.3 jmcneill case ACPI_DEVICE_PATH : { /* Unknown ACPI Device Path */ 1053 1.3 jmcneill CatPrint( Str , L"AcpiPath(%d" , Path-> SubType ) ; 1054 1.3 jmcneill break ; 1055 1.3 jmcneill } 1056 1.3 jmcneill case MESSAGING_DEVICE_PATH : { /* Unknown Messaging Device Path */ 1057 1.3 jmcneill CatPrint( Str , L"Msg(%d" , Path-> SubType ) ; 1058 1.3 jmcneill break ; 1059 1.3 jmcneill } 1060 1.3 jmcneill case MEDIA_DEVICE_PATH : { /* Unknown Media Device Path */ 1061 1.3 jmcneill CatPrint( Str , L"MediaPath(%d" , Path-> SubType ) ; 1062 1.3 jmcneill break ; 1063 1.3 jmcneill } 1064 1.3 jmcneill case BBS_DEVICE_PATH : { /* Unknown BIOS Boot Specification Device Path */ 1065 1.3 jmcneill CatPrint( Str , L"BbsPath(%d" , Path-> SubType ) ; 1066 1.3 jmcneill break ; 1067 1.3 jmcneill } 1068 1.3 jmcneill default : { /* Unknown Device Path */ 1069 1.3 jmcneill CatPrint( Str , L"Path(%d,%d" , Path-> Type , Path-> SubType ) ; 1070 1.3 jmcneill break ; 1071 1.3 jmcneill } 1072 1.3 jmcneill } 1073 1.3 jmcneill length = DevicePathNodeLength( Path ) ; 1074 1.3 jmcneill for ( index = 0 ; index < length ; index ++ ) { 1075 1.3 jmcneill if ( index == 0 ) CatPrint( Str , L",0x" ) ; 1076 1.3 jmcneill CatPrint( Str , L"%02x" , * value ) ; 1077 1.3 jmcneill value ++ ; 1078 1.3 jmcneill } 1079 1.3 jmcneill CatPrint( Str , L")" ) ; 1080 1.1 jakllsch } 1081 1.1 jakllsch 1082 1.1 jakllsch 1083 1.3 jmcneill /* 1084 1.3 jmcneill * Table to convert "Type" and "SubType" to a "convert to text" function/ 1085 1.3 jmcneill * Entries hold "Type" and "SubType" for know values. 1086 1.3 jmcneill * Special "SubType" 0 is used as default for known type with unknown subtype. 1087 1.3 jmcneill */ 1088 1.1 jakllsch struct { 1089 1.1 jakllsch UINT8 Type; 1090 1.1 jakllsch UINT8 SubType; 1091 1.3 jmcneill VOID (*Function)(POOL_PRINT *, VOID *); 1092 1.1 jakllsch } DevPathTable[] = { 1093 1.1 jakllsch { HARDWARE_DEVICE_PATH, HW_PCI_DP, _DevPathPci}, 1094 1.1 jakllsch { HARDWARE_DEVICE_PATH, HW_PCCARD_DP, _DevPathPccard}, 1095 1.1 jakllsch { HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, _DevPathMemMap}, 1096 1.1 jakllsch { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, _DevPathVendor}, 1097 1.1 jakllsch { HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, _DevPathController}, 1098 1.1 jakllsch { ACPI_DEVICE_PATH, ACPI_DP, _DevPathAcpi}, 1099 1.1 jakllsch { MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, _DevPathAtapi}, 1100 1.1 jakllsch { MESSAGING_DEVICE_PATH, MSG_SCSI_DP, _DevPathScsi}, 1101 1.1 jakllsch { MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, _DevPathFibre}, 1102 1.1 jakllsch { MESSAGING_DEVICE_PATH, MSG_1394_DP, _DevPath1394}, 1103 1.1 jakllsch { MESSAGING_DEVICE_PATH, MSG_USB_DP, _DevPathUsb}, 1104 1.1 jakllsch { MESSAGING_DEVICE_PATH, MSG_I2O_DP, _DevPathI2O}, 1105 1.1 jakllsch { MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, _DevPathMacAddr}, 1106 1.1 jakllsch { MESSAGING_DEVICE_PATH, MSG_IPv4_DP, _DevPathIPv4}, 1107 1.1 jakllsch { MESSAGING_DEVICE_PATH, MSG_IPv6_DP, _DevPathIPv6}, 1108 1.3 jmcneill { MESSAGING_DEVICE_PATH, MSG_URI_DP, _DevPathUri}, 1109 1.1 jakllsch { MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, _DevPathInfiniBand}, 1110 1.1 jakllsch { MESSAGING_DEVICE_PATH, MSG_UART_DP, _DevPathUart}, 1111 1.3 jmcneill { MESSAGING_DEVICE_PATH , MSG_SATA_DP , _DevPathSata } , 1112 1.1 jakllsch { MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, _DevPathVendor}, 1113 1.1 jakllsch { MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, _DevPathHardDrive}, 1114 1.1 jakllsch { MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, _DevPathCDROM}, 1115 1.1 jakllsch { MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, _DevPathVendor}, 1116 1.1 jakllsch { MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, _DevPathFilePath}, 1117 1.1 jakllsch { MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, _DevPathMediaProtocol}, 1118 1.1 jakllsch { BBS_DEVICE_PATH, BBS_BBS_DP, _DevPathBssBss}, 1119 1.1 jakllsch { END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, _DevPathEndInstance}, 1120 1.1 jakllsch { 0, 0, NULL} 1121 1.1 jakllsch }; 1122 1.1 jakllsch 1123 1.1 jakllsch 1124 1.1 jakllsch CHAR16 * 1125 1.1 jakllsch DevicePathToStr ( 1126 1.1 jakllsch EFI_DEVICE_PATH *DevPath 1127 1.1 jakllsch ) 1128 1.1 jakllsch /*++ 1129 1.1 jakllsch 1130 1.1 jakllsch Turns the Device Path into a printable string. Allcoates 1131 1.1 jakllsch the string from pool. The caller must FreePool the returned 1132 1.1 jakllsch string. 1133 1.1 jakllsch 1134 1.1 jakllsch --*/ 1135 1.1 jakllsch { 1136 1.1 jakllsch POOL_PRINT Str; 1137 1.1 jakllsch EFI_DEVICE_PATH *DevPathNode; 1138 1.3 jmcneill VOID (*DumpNode)(POOL_PRINT *, VOID *); 1139 1.1 jakllsch UINTN Index, NewSize; 1140 1.1 jakllsch 1141 1.1 jakllsch ZeroMem(&Str, sizeof(Str)); 1142 1.1 jakllsch 1143 1.1 jakllsch // 1144 1.1 jakllsch // Unpacked the device path 1145 1.1 jakllsch // 1146 1.1 jakllsch 1147 1.1 jakllsch DevPath = UnpackDevicePath(DevPath); 1148 1.1 jakllsch ASSERT (DevPath); 1149 1.1 jakllsch 1150 1.1 jakllsch 1151 1.1 jakllsch // 1152 1.1 jakllsch // Process each device path node 1153 1.3 jmcneill // 1154 1.1 jakllsch 1155 1.1 jakllsch DevPathNode = DevPath; 1156 1.1 jakllsch while (!IsDevicePathEnd(DevPathNode)) { 1157 1.1 jakllsch // 1158 1.1 jakllsch // Find the handler to dump this device path node 1159 1.1 jakllsch // 1160 1.1 jakllsch 1161 1.1 jakllsch DumpNode = NULL; 1162 1.1 jakllsch for (Index = 0; DevPathTable[Index].Function; Index += 1) { 1163 1.1 jakllsch 1164 1.1 jakllsch if (DevicePathType(DevPathNode) == DevPathTable[Index].Type && 1165 1.1 jakllsch DevicePathSubType(DevPathNode) == DevPathTable[Index].SubType) { 1166 1.1 jakllsch DumpNode = DevPathTable[Index].Function; 1167 1.1 jakllsch break; 1168 1.1 jakllsch } 1169 1.1 jakllsch } 1170 1.1 jakllsch 1171 1.1 jakllsch // 1172 1.1 jakllsch // If not found, use a generic function 1173 1.1 jakllsch // 1174 1.1 jakllsch 1175 1.1 jakllsch if (!DumpNode) { 1176 1.1 jakllsch DumpNode = _DevPathNodeUnknown; 1177 1.1 jakllsch } 1178 1.1 jakllsch 1179 1.1 jakllsch // 1180 1.1 jakllsch // Put a path seperator in if needed 1181 1.1 jakllsch // 1182 1.1 jakllsch 1183 1.1 jakllsch if (Str.len && DumpNode != _DevPathEndInstance) { 1184 1.1 jakllsch CatPrint (&Str, L"/"); 1185 1.1 jakllsch } 1186 1.1 jakllsch 1187 1.1 jakllsch // 1188 1.1 jakllsch // Print this node of the device path 1189 1.1 jakllsch // 1190 1.1 jakllsch 1191 1.1 jakllsch DumpNode (&Str, DevPathNode); 1192 1.1 jakllsch 1193 1.1 jakllsch // 1194 1.1 jakllsch // Next device path node 1195 1.1 jakllsch // 1196 1.1 jakllsch 1197 1.1 jakllsch DevPathNode = NextDevicePathNode(DevPathNode); 1198 1.1 jakllsch } 1199 1.1 jakllsch 1200 1.1 jakllsch // 1201 1.1 jakllsch // Shrink pool used for string allocation 1202 1.1 jakllsch // 1203 1.1 jakllsch 1204 1.1 jakllsch FreePool (DevPath); 1205 1.1 jakllsch NewSize = (Str.len + 1) * sizeof(CHAR16); 1206 1.1 jakllsch Str.str = ReallocatePool (Str.str, NewSize, NewSize); 1207 1.1 jakllsch Str.str[Str.len] = 0; 1208 1.1 jakllsch return Str.str; 1209 1.1 jakllsch } 1210 1.1 jakllsch 1211 1.1 jakllsch BOOLEAN 1212 1.1 jakllsch LibMatchDevicePaths ( 1213 1.1 jakllsch IN EFI_DEVICE_PATH *Multi, 1214 1.1 jakllsch IN EFI_DEVICE_PATH *Single 1215 1.1 jakllsch ) 1216 1.1 jakllsch { 1217 1.1 jakllsch EFI_DEVICE_PATH *DevicePath, *DevicePathInst; 1218 1.1 jakllsch UINTN Size; 1219 1.1 jakllsch 1220 1.1 jakllsch if (!Multi || !Single) { 1221 1.1 jakllsch return FALSE; 1222 1.1 jakllsch } 1223 1.1 jakllsch 1224 1.1 jakllsch DevicePath = Multi; 1225 1.1 jakllsch while ((DevicePathInst = DevicePathInstance (&DevicePath, &Size))) { 1226 1.1 jakllsch if (CompareMem (Single, DevicePathInst, Size) == 0) { 1227 1.1 jakllsch return TRUE; 1228 1.1 jakllsch } 1229 1.1 jakllsch } 1230 1.1 jakllsch return FALSE; 1231 1.1 jakllsch } 1232 1.1 jakllsch 1233 1.1 jakllsch EFI_DEVICE_PATH * 1234 1.1 jakllsch LibDuplicateDevicePathInstance ( 1235 1.1 jakllsch IN EFI_DEVICE_PATH *DevPath 1236 1.1 jakllsch ) 1237 1.1 jakllsch { 1238 1.1 jakllsch EFI_DEVICE_PATH *NewDevPath,*DevicePathInst,*Temp; 1239 1.3 jmcneill UINTN Size = 0; 1240 1.1 jakllsch 1241 1.1 jakllsch // 1242 1.1 jakllsch // get the size of an instance from the input 1243 1.1 jakllsch // 1244 1.1 jakllsch 1245 1.1 jakllsch Temp = DevPath; 1246 1.1 jakllsch DevicePathInst = DevicePathInstance (&Temp, &Size); 1247 1.3 jmcneill 1248 1.1 jakllsch // 1249 1.1 jakllsch // Make a copy and set proper end type 1250 1.1 jakllsch // 1251 1.1 jakllsch NewDevPath = NULL; 1252 1.3 jmcneill if (Size) { 1253 1.1 jakllsch NewDevPath = AllocatePool (Size + sizeof(EFI_DEVICE_PATH)); 1254 1.1 jakllsch } 1255 1.1 jakllsch 1256 1.1 jakllsch if (NewDevPath) { 1257 1.1 jakllsch CopyMem (NewDevPath, DevicePathInst, Size); 1258 1.3 jmcneill Temp = NextDevicePathNode(NewDevPath); 1259 1.1 jakllsch SetDevicePathEndNode(Temp); 1260 1.1 jakllsch } 1261 1.1 jakllsch 1262 1.1 jakllsch return NewDevPath; 1263 1.1 jakllsch } 1264 1.1 jakllsch 1265