1 /*++ 2 3 Copyright (c) 1998 Intel Corporation 4 5 Module Name: 6 7 dpath.c 8 9 Abstract: 10 MBR & Device Path functions 11 12 13 14 Revision History 15 16 --*/ 17 18 #include "lib.h" 19 20 #define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0) 21 22 23 24 EFI_DEVICE_PATH * 25 DevicePathFromHandle ( 26 IN EFI_HANDLE Handle 27 ) 28 { 29 EFI_STATUS Status; 30 EFI_DEVICE_PATH *DevicePath; 31 32 Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handle, &DevicePathProtocol, (VOID*)&DevicePath); 33 if (EFI_ERROR(Status)) { 34 DevicePath = NULL; 35 } 36 37 return DevicePath; 38 } 39 40 41 EFI_DEVICE_PATH * 42 DevicePathInstance ( 43 IN OUT EFI_DEVICE_PATH **DevicePath, 44 OUT UINTN *Size 45 ) 46 { 47 EFI_DEVICE_PATH *Start, *Next, *DevPath; 48 UINTN Count; 49 50 DevPath = *DevicePath; 51 Start = DevPath; 52 53 if (!DevPath) { 54 return NULL; 55 } 56 57 // 58 // Check for end of device path type 59 // 60 61 for (Count = 0; ; Count++) { 62 Next = NextDevicePathNode(DevPath); 63 64 if (IsDevicePathEndType(DevPath)) { 65 break; 66 } 67 68 if (Count > 01000) { 69 // 70 // BugBug: Debug code to catch bogus device paths 71 // 72 DEBUG((D_ERROR, "DevicePathInstance: DevicePath %x Size %d", *DevicePath, ((UINT8 *) DevPath) - ((UINT8 *) Start) )); 73 DumpHex (0, 0, ((UINT8 *) DevPath) - ((UINT8 *) Start), Start); 74 break; 75 } 76 77 DevPath = Next; 78 } 79 80 ASSERT (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE || 81 DevicePathSubType(DevPath) == END_INSTANCE_DEVICE_PATH_SUBTYPE); 82 83 // 84 // Set next position 85 // 86 87 if (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) { 88 Next = NULL; 89 } 90 91 *DevicePath = Next; 92 93 // 94 // Return size and start of device path instance 95 // 96 97 *Size = ((UINT8 *) DevPath) - ((UINT8 *) Start); 98 return Start; 99 } 100 101 UINTN 102 DevicePathInstanceCount ( 103 IN EFI_DEVICE_PATH *DevicePath 104 ) 105 { 106 UINTN Count, Size; 107 108 Count = 0; 109 while (DevicePathInstance(&DevicePath, &Size)) { 110 Count += 1; 111 } 112 113 return Count; 114 } 115 116 117 EFI_DEVICE_PATH * 118 AppendDevicePath ( 119 IN EFI_DEVICE_PATH *Src1, 120 IN EFI_DEVICE_PATH *Src2 121 ) 122 // Src1 may have multiple "instances" and each instance is appended 123 // Src2 is appended to each instance is Src1. (E.g., it's possible 124 // to append a new instance to the complete device path by passing 125 // it in Src2) 126 { 127 UINTN Src1Size, Src1Inst, Src2Size, Size; 128 EFI_DEVICE_PATH *Dst, *Inst; 129 UINT8 *DstPos; 130 131 // 132 // If there's only 1 path, just duplicate it 133 // 134 135 if (!Src1) { 136 ASSERT (!IsDevicePathUnpacked (Src2)); 137 return DuplicateDevicePath (Src2); 138 } 139 140 if (!Src2) { 141 ASSERT (!IsDevicePathUnpacked (Src1)); 142 return DuplicateDevicePath (Src1); 143 } 144 145 // 146 // Verify we're not working with unpacked paths 147 // 148 149 // ASSERT (!IsDevicePathUnpacked (Src1)); 150 // ASSERT (!IsDevicePathUnpacked (Src2)); 151 152 // 153 // Append Src2 to every instance in Src1 154 // 155 156 Src1Size = DevicePathSize(Src1); 157 Src1Inst = DevicePathInstanceCount(Src1); 158 Src2Size = DevicePathSize(Src2); 159 Size = Src1Size * Src1Inst + Src2Size; 160 161 Dst = AllocatePool (Size); 162 if (Dst) { 163 DstPos = (UINT8 *) Dst; 164 165 // 166 // Copy all device path instances 167 // 168 169 while ((Inst = DevicePathInstance (&Src1, &Size))) { 170 171 CopyMem(DstPos, Inst, Size); 172 DstPos += Size; 173 174 CopyMem(DstPos, Src2, Src2Size); 175 DstPos += Src2Size; 176 177 CopyMem(DstPos, EndInstanceDevicePath, sizeof(EFI_DEVICE_PATH)); 178 DstPos += sizeof(EFI_DEVICE_PATH); 179 } 180 181 // Change last end marker 182 DstPos -= sizeof(EFI_DEVICE_PATH); 183 CopyMem(DstPos, EndDevicePath, sizeof(EFI_DEVICE_PATH)); 184 } 185 186 return Dst; 187 } 188 189 190 EFI_DEVICE_PATH * 191 AppendDevicePathNode ( 192 IN EFI_DEVICE_PATH *Src1, 193 IN EFI_DEVICE_PATH *Src2 194 ) 195 // Src1 may have multiple "instances" and each instance is appended 196 // Src2 is a signal device path node (without a terminator) that is 197 // appended to each instance is Src1. 198 { 199 EFI_DEVICE_PATH *Temp, *Eop; 200 UINTN Length; 201 202 // 203 // Build a Src2 that has a terminator on it 204 // 205 206 Length = DevicePathNodeLength(Src2); 207 Temp = AllocatePool (Length + sizeof(EFI_DEVICE_PATH)); 208 if (!Temp) { 209 return NULL; 210 } 211 212 CopyMem (Temp, Src2, Length); 213 Eop = NextDevicePathNode(Temp); 214 SetDevicePathEndNode(Eop); 215 216 // 217 // Append device paths 218 // 219 220 Src1 = AppendDevicePath (Src1, Temp); 221 FreePool (Temp); 222 return Src1; 223 } 224 225 226 EFI_DEVICE_PATH * 227 FileDevicePath ( 228 IN EFI_HANDLE Device OPTIONAL, 229 IN CHAR16 *FileName 230 ) 231 /*++ 232 233 N.B. Results are allocated from pool. The caller must FreePool 234 the resulting device path structure 235 236 --*/ 237 { 238 UINTN Size; 239 FILEPATH_DEVICE_PATH *FilePath; 240 EFI_DEVICE_PATH *Eop, *DevicePath; 241 242 Size = StrSize(FileName); 243 FilePath = AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof(EFI_DEVICE_PATH)); 244 DevicePath = NULL; 245 246 if (FilePath) { 247 248 // 249 // Build a file path 250 // 251 252 FilePath->Header.Type = MEDIA_DEVICE_PATH; 253 FilePath->Header.SubType = MEDIA_FILEPATH_DP; 254 SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH); 255 CopyMem (FilePath->PathName, FileName, Size); 256 Eop = NextDevicePathNode(&FilePath->Header); 257 SetDevicePathEndNode(Eop); 258 259 // 260 // Append file path to device's device path 261 // 262 263 DevicePath = (EFI_DEVICE_PATH *) FilePath; 264 if (Device) { 265 DevicePath = AppendDevicePath ( 266 DevicePathFromHandle(Device), 267 DevicePath 268 ); 269 270 FreePool(FilePath); 271 } 272 } 273 274 return DevicePath; 275 } 276 277 278 279 UINTN 280 DevicePathSize ( 281 IN EFI_DEVICE_PATH *DevPath 282 ) 283 { 284 EFI_DEVICE_PATH *Start; 285 286 // 287 // Search for the end of the device path structure 288 // 289 290 Start = DevPath; 291 while (!IsDevicePathEnd(DevPath)) { 292 DevPath = NextDevicePathNode(DevPath); 293 } 294 295 // 296 // Compute the size 297 // 298 299 return ((UINTN) DevPath - (UINTN) Start) + sizeof(EFI_DEVICE_PATH); 300 } 301 302 EFI_DEVICE_PATH * 303 DuplicateDevicePath ( 304 IN EFI_DEVICE_PATH *DevPath 305 ) 306 { 307 EFI_DEVICE_PATH *NewDevPath; 308 UINTN Size; 309 310 311 // 312 // Compute the size 313 // 314 315 Size = DevicePathSize (DevPath); 316 317 // 318 // Make a copy 319 // 320 321 NewDevPath = AllocatePool (Size); 322 if (NewDevPath) { 323 CopyMem (NewDevPath, DevPath, Size); 324 } 325 326 return NewDevPath; 327 } 328 329 EFI_DEVICE_PATH * 330 UnpackDevicePath ( 331 IN EFI_DEVICE_PATH *DevPath 332 ) 333 { 334 EFI_DEVICE_PATH *Src, *Dest, *NewPath; 335 UINTN Size; 336 337 // 338 // Walk device path and round sizes to valid boundries 339 // 340 341 Src = DevPath; 342 Size = 0; 343 for (; ;) { 344 Size += DevicePathNodeLength(Src); 345 Size += ALIGN_SIZE(Size); 346 347 if (IsDevicePathEnd(Src)) { 348 break; 349 } 350 351 Src = NextDevicePathNode(Src); 352 } 353 354 355 // 356 // Allocate space for the unpacked path 357 // 358 359 NewPath = AllocateZeroPool (Size); 360 if (NewPath) { 361 362 ASSERT (((UINTN)NewPath) % MIN_ALIGNMENT_SIZE == 0); 363 364 // 365 // Copy each node 366 // 367 368 Src = DevPath; 369 Dest = NewPath; 370 for (; ;) { 371 Size = DevicePathNodeLength(Src); 372 CopyMem (Dest, Src, Size); 373 Size += ALIGN_SIZE(Size); 374 SetDevicePathNodeLength (Dest, Size); 375 Dest->Type |= EFI_DP_TYPE_UNPACKED; 376 Dest = (EFI_DEVICE_PATH *) (((UINT8 *) Dest) + Size); 377 378 if (IsDevicePathEnd(Src)) { 379 break; 380 } 381 382 Src = NextDevicePathNode(Src); 383 } 384 } 385 386 return NewPath; 387 } 388 389 390 EFI_DEVICE_PATH* 391 AppendDevicePathInstance ( 392 IN EFI_DEVICE_PATH *Src, 393 IN EFI_DEVICE_PATH *Instance 394 ) 395 { 396 UINT8 *Ptr; 397 EFI_DEVICE_PATH *DevPath; 398 UINTN SrcSize; 399 UINTN InstanceSize; 400 401 if (Src == NULL) { 402 return DuplicateDevicePath (Instance); 403 } 404 SrcSize = DevicePathSize(Src); 405 InstanceSize = DevicePathSize(Instance); 406 Ptr = AllocatePool (SrcSize + InstanceSize); 407 DevPath = (EFI_DEVICE_PATH *)Ptr; 408 ASSERT(DevPath); 409 410 CopyMem (Ptr, Src, SrcSize); 411 // FreePool (Src); 412 413 while (!IsDevicePathEnd(DevPath)) { 414 DevPath = NextDevicePathNode(DevPath); 415 } 416 // 417 // Convert the End to an End Instance, since we are 418 // appending another instacne after this one its a good 419 // idea. 420 // 421 DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; 422 423 DevPath = NextDevicePathNode(DevPath); 424 CopyMem (DevPath, Instance, InstanceSize); 425 return (EFI_DEVICE_PATH *)Ptr; 426 } 427 428 EFI_STATUS 429 LibDevicePathToInterface ( 430 IN EFI_GUID *Protocol, 431 IN EFI_DEVICE_PATH *FilePath, 432 OUT VOID **Interface 433 ) 434 { 435 EFI_STATUS Status; 436 EFI_HANDLE Device; 437 438 Status = uefi_call_wrapper(BS->LocateDevicePath, 3, Protocol, &FilePath, &Device); 439 440 if (!EFI_ERROR(Status)) { 441 442 // If we didn't get a direct match return not found 443 Status = EFI_NOT_FOUND; 444 445 if (IsDevicePathEnd(FilePath)) { 446 447 // 448 // It was a direct match, lookup the protocol interface 449 // 450 451 Status =uefi_call_wrapper(BS->HandleProtocol, 3, Device, Protocol, Interface); 452 } 453 } 454 455 // 456 // If there was an error, do not return an interface 457 // 458 459 if (EFI_ERROR(Status)) { 460 *Interface = NULL; 461 } 462 463 return Status; 464 } 465 466 VOID 467 _DevPathPci ( 468 IN OUT POOL_PRINT *Str, 469 IN VOID *DevPath 470 ) 471 { 472 PCI_DEVICE_PATH *Pci; 473 474 Pci = DevPath; 475 CatPrint(Str, L"Pci(%x|%x)", Pci->Device, Pci->Function); 476 } 477 478 VOID 479 _DevPathPccard ( 480 IN OUT POOL_PRINT *Str, 481 IN VOID *DevPath 482 ) 483 { 484 PCCARD_DEVICE_PATH *Pccard; 485 486 Pccard = DevPath; 487 CatPrint(Str, L"Pccard(Socket%x)", Pccard->SocketNumber); 488 } 489 490 VOID 491 _DevPathMemMap ( 492 IN OUT POOL_PRINT *Str, 493 IN VOID *DevPath 494 ) 495 { 496 MEMMAP_DEVICE_PATH *MemMap; 497 498 MemMap = DevPath; 499 CatPrint(Str, L"MemMap(%d:%x-%x)", 500 MemMap->MemoryType, 501 MemMap->StartingAddress, 502 MemMap->EndingAddress 503 ); 504 } 505 506 VOID 507 _DevPathController ( 508 IN OUT POOL_PRINT *Str, 509 IN VOID *DevPath 510 ) 511 { 512 CONTROLLER_DEVICE_PATH *Controller; 513 514 Controller = DevPath; 515 CatPrint(Str, L"Ctrl(%d)", 516 Controller->Controller 517 ); 518 } 519 520 VOID 521 _DevPathVendor ( 522 IN OUT POOL_PRINT *Str, 523 IN VOID *DevPath 524 ) 525 { 526 VENDOR_DEVICE_PATH *Vendor; 527 CHAR16 *Type; 528 UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownDevPath; 529 530 Vendor = DevPath; 531 switch (DevicePathType(&Vendor->Header)) { 532 case HARDWARE_DEVICE_PATH: Type = L"Hw"; break; 533 case MESSAGING_DEVICE_PATH: Type = L"Msg"; break; 534 case MEDIA_DEVICE_PATH: Type = L"Media"; break; 535 default: Type = L"?"; break; 536 } 537 538 CatPrint(Str, L"Ven%s(%g", Type, &Vendor->Guid); 539 if (CompareGuid (&Vendor->Guid, &UnknownDevice) == 0) { 540 // 541 // GUID used by EFI to enumerate an EDD 1.1 device 542 // 543 UnknownDevPath = (UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *)Vendor; 544 CatPrint(Str, L":%02x)", UnknownDevPath->LegacyDriveLetter); 545 } else { 546 CatPrint(Str, L")"); 547 } 548 } 549 550 551 VOID 552 _DevPathAcpi ( 553 IN OUT POOL_PRINT *Str, 554 IN VOID *DevPath 555 ) 556 { 557 ACPI_HID_DEVICE_PATH *Acpi; 558 559 Acpi = DevPath; 560 if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) { 561 CatPrint(Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID); 562 } else { 563 CatPrint(Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID); 564 } 565 } 566 567 568 VOID 569 _DevPathAtapi ( 570 IN OUT POOL_PRINT *Str, 571 IN VOID *DevPath 572 ) 573 { 574 ATAPI_DEVICE_PATH *Atapi; 575 576 Atapi = DevPath; 577 CatPrint(Str, L"Ata(%s,%s)", 578 Atapi->PrimarySecondary ? L"Secondary" : L"Primary", 579 Atapi->SlaveMaster ? L"Slave" : L"Master" 580 ); 581 } 582 583 VOID 584 _DevPathScsi ( 585 IN OUT POOL_PRINT *Str, 586 IN VOID *DevPath 587 ) 588 { 589 SCSI_DEVICE_PATH *Scsi; 590 591 Scsi = DevPath; 592 CatPrint(Str, L"Scsi(Pun%x,Lun%x)", Scsi->Pun, Scsi->Lun); 593 } 594 595 596 VOID 597 _DevPathFibre ( 598 IN OUT POOL_PRINT *Str, 599 IN VOID *DevPath 600 ) 601 { 602 FIBRECHANNEL_DEVICE_PATH *Fibre; 603 604 Fibre = DevPath; 605 CatPrint(Str, L"Fibre(%lx)", Fibre->WWN); 606 } 607 608 VOID 609 _DevPath1394 ( 610 IN OUT POOL_PRINT *Str, 611 IN VOID *DevPath 612 ) 613 { 614 F1394_DEVICE_PATH *F1394; 615 616 F1394 = DevPath; 617 CatPrint(Str, L"1394(%g)", &F1394->Guid); 618 } 619 620 621 622 VOID 623 _DevPathUsb ( 624 IN OUT POOL_PRINT *Str, 625 IN VOID *DevPath 626 ) 627 { 628 USB_DEVICE_PATH *Usb; 629 630 Usb = DevPath; 631 CatPrint(Str, L"Usb(%x)", Usb->Port); 632 } 633 634 635 VOID 636 _DevPathI2O ( 637 IN OUT POOL_PRINT *Str, 638 IN VOID *DevPath 639 ) 640 { 641 I2O_DEVICE_PATH *I2O; 642 643 I2O = DevPath; 644 CatPrint(Str, L"I2O(%x)", I2O->Tid); 645 } 646 647 VOID 648 _DevPathMacAddr ( 649 IN OUT POOL_PRINT *Str, 650 IN VOID *DevPath 651 ) 652 { 653 MAC_ADDR_DEVICE_PATH *MAC; 654 UINTN HwAddressSize; 655 UINTN Index; 656 657 MAC = DevPath; 658 659 HwAddressSize = sizeof(EFI_MAC_ADDRESS); 660 if (MAC->IfType == 0x01 || MAC->IfType == 0x00) { 661 HwAddressSize = 6; 662 } 663 664 CatPrint(Str, L"Mac("); 665 666 for(Index = 0; Index < HwAddressSize; Index++) { 667 CatPrint(Str, L"%02x",MAC->MacAddress.Addr[Index]); 668 } 669 CatPrint(Str, L")"); 670 } 671 672 VOID 673 _DevPathIPv4 ( 674 IN OUT POOL_PRINT *Str, 675 IN VOID *DevPath 676 ) 677 { 678 IPv4_DEVICE_PATH *IP; 679 680 IP = DevPath; 681 CatPrint(Str, L"IPv4(not-done)"); 682 } 683 684 VOID 685 _DevPathIPv6 ( 686 IN OUT POOL_PRINT *Str, 687 IN VOID *DevPath 688 ) 689 { 690 IPv6_DEVICE_PATH *IP; 691 692 IP = DevPath; 693 CatPrint(Str, L"IP-v6(not-done)"); 694 } 695 696 VOID 697 _DevPathInfiniBand ( 698 IN OUT POOL_PRINT *Str, 699 IN VOID *DevPath 700 ) 701 { 702 INFINIBAND_DEVICE_PATH *InfiniBand; 703 704 InfiniBand = DevPath; 705 CatPrint(Str, L"InfiniBand(not-done)"); 706 } 707 708 VOID 709 _DevPathUart ( 710 IN OUT POOL_PRINT *Str, 711 IN VOID *DevPath 712 ) 713 { 714 UART_DEVICE_PATH *Uart; 715 CHAR8 Parity; 716 717 Uart = DevPath; 718 switch (Uart->Parity) { 719 case 0 : Parity = 'D'; break; 720 case 1 : Parity = 'N'; break; 721 case 2 : Parity = 'E'; break; 722 case 3 : Parity = 'O'; break; 723 case 4 : Parity = 'M'; break; 724 case 5 : Parity = 'S'; break; 725 default : Parity = 'x'; break; 726 } 727 728 if (Uart->BaudRate == 0) { 729 CatPrint(Str, L"Uart(DEFAULT %c",Uart->BaudRate,Parity); 730 } else { 731 CatPrint(Str, L"Uart(%d %c",Uart->BaudRate,Parity); 732 } 733 734 if (Uart->DataBits == 0) { 735 CatPrint(Str, L"D"); 736 } else { 737 CatPrint(Str, L"%d",Uart->DataBits); 738 } 739 740 switch (Uart->StopBits) { 741 case 0 : CatPrint(Str, L"D)"); break; 742 case 1 : CatPrint(Str, L"1)"); break; 743 case 2 : CatPrint(Str, L"1.5)"); break; 744 case 3 : CatPrint(Str, L"2)"); break; 745 default : CatPrint(Str, L"x)"); break; 746 } 747 } 748 749 750 VOID 751 _DevPathHardDrive ( 752 IN OUT POOL_PRINT *Str, 753 IN VOID *DevPath 754 ) 755 { 756 HARDDRIVE_DEVICE_PATH *Hd; 757 758 Hd = DevPath; 759 switch (Hd->SignatureType) { 760 case SIGNATURE_TYPE_MBR: 761 CatPrint(Str, L"HD(Part%d,Sig%08X)", 762 Hd->PartitionNumber, 763 *((UINT32 *)(&(Hd->Signature[0]))) 764 ); 765 break; 766 case SIGNATURE_TYPE_GUID: 767 CatPrint(Str, L"HD(Part%d,Sig%g)", 768 Hd->PartitionNumber, 769 (EFI_GUID *) &(Hd->Signature[0]) 770 ); 771 break; 772 default: 773 CatPrint(Str, L"HD(Part%d,MBRType=%02x,SigType=%02x)", 774 Hd->PartitionNumber, 775 Hd->MBRType, 776 Hd->SignatureType 777 ); 778 break; 779 } 780 } 781 782 VOID 783 _DevPathCDROM ( 784 IN OUT POOL_PRINT *Str, 785 IN VOID *DevPath 786 ) 787 { 788 CDROM_DEVICE_PATH *Cd; 789 790 Cd = DevPath; 791 CatPrint(Str, L"CDROM(Entry%x)", Cd->BootEntry); 792 } 793 794 VOID 795 _DevPathFilePath ( 796 IN OUT POOL_PRINT *Str, 797 IN VOID *DevPath 798 ) 799 { 800 FILEPATH_DEVICE_PATH *Fp; 801 802 Fp = DevPath; 803 CatPrint(Str, L"%s", Fp->PathName); 804 } 805 806 VOID 807 _DevPathMediaProtocol ( 808 IN OUT POOL_PRINT *Str, 809 IN VOID *DevPath 810 ) 811 { 812 MEDIA_PROTOCOL_DEVICE_PATH *MediaProt; 813 814 MediaProt = DevPath; 815 CatPrint(Str, L"%g", &MediaProt->Protocol); 816 } 817 818 VOID 819 _DevPathBssBss ( 820 IN OUT POOL_PRINT *Str, 821 IN VOID *DevPath 822 ) 823 { 824 BBS_BBS_DEVICE_PATH *Bss; 825 CHAR16 *Type; 826 827 Bss = DevPath; 828 switch (Bss->DeviceType) { 829 case BBS_TYPE_FLOPPY: Type = L"Floppy"; break; 830 case BBS_TYPE_HARDDRIVE: Type = L"Harddrive"; break; 831 case BBS_TYPE_CDROM: Type = L"CDROM"; break; 832 case BBS_TYPE_PCMCIA: Type = L"PCMCIA"; break; 833 case BBS_TYPE_USB: Type = L"Usb"; break; 834 case BBS_TYPE_EMBEDDED_NETWORK: Type = L"Net"; break; 835 default: Type = L"?"; break; 836 } 837 838 CatPrint(Str, L"Bss-%s(%a)", Type, Bss->String); 839 } 840 841 842 VOID 843 _DevPathEndInstance ( 844 IN OUT POOL_PRINT *Str, 845 IN VOID *DevPath 846 ) 847 { 848 CatPrint(Str, L","); 849 } 850 851 VOID 852 _DevPathNodeUnknown ( 853 IN OUT POOL_PRINT *Str, 854 IN VOID *DevPath 855 ) 856 { 857 CatPrint(Str, L"?"); 858 } 859 860 861 struct { 862 UINT8 Type; 863 UINT8 SubType; 864 VOID (*Function)(POOL_PRINT *, VOID *); 865 } DevPathTable[] = { 866 { HARDWARE_DEVICE_PATH, HW_PCI_DP, _DevPathPci}, 867 { HARDWARE_DEVICE_PATH, HW_PCCARD_DP, _DevPathPccard}, 868 { HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, _DevPathMemMap}, 869 { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, _DevPathVendor}, 870 { HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, _DevPathController}, 871 { ACPI_DEVICE_PATH, ACPI_DP, _DevPathAcpi}, 872 { MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, _DevPathAtapi}, 873 { MESSAGING_DEVICE_PATH, MSG_SCSI_DP, _DevPathScsi}, 874 { MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, _DevPathFibre}, 875 { MESSAGING_DEVICE_PATH, MSG_1394_DP, _DevPath1394}, 876 { MESSAGING_DEVICE_PATH, MSG_USB_DP, _DevPathUsb}, 877 { MESSAGING_DEVICE_PATH, MSG_I2O_DP, _DevPathI2O}, 878 { MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, _DevPathMacAddr}, 879 { MESSAGING_DEVICE_PATH, MSG_IPv4_DP, _DevPathIPv4}, 880 { MESSAGING_DEVICE_PATH, MSG_IPv6_DP, _DevPathIPv6}, 881 { MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, _DevPathInfiniBand}, 882 { MESSAGING_DEVICE_PATH, MSG_UART_DP, _DevPathUart}, 883 { MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, _DevPathVendor}, 884 { MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, _DevPathHardDrive}, 885 { MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, _DevPathCDROM}, 886 { MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, _DevPathVendor}, 887 { MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, _DevPathFilePath}, 888 { MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, _DevPathMediaProtocol}, 889 { BBS_DEVICE_PATH, BBS_BBS_DP, _DevPathBssBss}, 890 { END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, _DevPathEndInstance}, 891 { 0, 0, NULL} 892 }; 893 894 895 CHAR16 * 896 DevicePathToStr ( 897 EFI_DEVICE_PATH *DevPath 898 ) 899 /*++ 900 901 Turns the Device Path into a printable string. Allcoates 902 the string from pool. The caller must FreePool the returned 903 string. 904 905 --*/ 906 { 907 POOL_PRINT Str; 908 EFI_DEVICE_PATH *DevPathNode; 909 VOID (*DumpNode)(POOL_PRINT *, VOID *); 910 UINTN Index, NewSize; 911 912 ZeroMem(&Str, sizeof(Str)); 913 914 // 915 // Unpacked the device path 916 // 917 918 DevPath = UnpackDevicePath(DevPath); 919 ASSERT (DevPath); 920 921 922 // 923 // Process each device path node 924 // 925 926 DevPathNode = DevPath; 927 while (!IsDevicePathEnd(DevPathNode)) { 928 // 929 // Find the handler to dump this device path node 930 // 931 932 DumpNode = NULL; 933 for (Index = 0; DevPathTable[Index].Function; Index += 1) { 934 935 if (DevicePathType(DevPathNode) == DevPathTable[Index].Type && 936 DevicePathSubType(DevPathNode) == DevPathTable[Index].SubType) { 937 DumpNode = DevPathTable[Index].Function; 938 break; 939 } 940 } 941 942 // 943 // If not found, use a generic function 944 // 945 946 if (!DumpNode) { 947 DumpNode = _DevPathNodeUnknown; 948 } 949 950 // 951 // Put a path seperator in if needed 952 // 953 954 if (Str.len && DumpNode != _DevPathEndInstance) { 955 CatPrint (&Str, L"/"); 956 } 957 958 // 959 // Print this node of the device path 960 // 961 962 DumpNode (&Str, DevPathNode); 963 964 // 965 // Next device path node 966 // 967 968 DevPathNode = NextDevicePathNode(DevPathNode); 969 } 970 971 // 972 // Shrink pool used for string allocation 973 // 974 975 FreePool (DevPath); 976 NewSize = (Str.len + 1) * sizeof(CHAR16); 977 Str.str = ReallocatePool (Str.str, NewSize, NewSize); 978 Str.str[Str.len] = 0; 979 return Str.str; 980 } 981 982 BOOLEAN 983 LibMatchDevicePaths ( 984 IN EFI_DEVICE_PATH *Multi, 985 IN EFI_DEVICE_PATH *Single 986 ) 987 { 988 EFI_DEVICE_PATH *DevicePath, *DevicePathInst; 989 UINTN Size; 990 991 if (!Multi || !Single) { 992 return FALSE; 993 } 994 995 DevicePath = Multi; 996 while ((DevicePathInst = DevicePathInstance (&DevicePath, &Size))) { 997 if (CompareMem (Single, DevicePathInst, Size) == 0) { 998 return TRUE; 999 } 1000 } 1001 return FALSE; 1002 } 1003 1004 EFI_DEVICE_PATH * 1005 LibDuplicateDevicePathInstance ( 1006 IN EFI_DEVICE_PATH *DevPath 1007 ) 1008 { 1009 EFI_DEVICE_PATH *NewDevPath,*DevicePathInst,*Temp; 1010 UINTN Size = 0; 1011 1012 // 1013 // get the size of an instance from the input 1014 // 1015 1016 Temp = DevPath; 1017 DevicePathInst = DevicePathInstance (&Temp, &Size); 1018 1019 // 1020 // Make a copy and set proper end type 1021 // 1022 NewDevPath = NULL; 1023 if (Size) { 1024 NewDevPath = AllocatePool (Size + sizeof(EFI_DEVICE_PATH)); 1025 } 1026 1027 if (NewDevPath) { 1028 CopyMem (NewDevPath, DevicePathInst, Size); 1029 Temp = NextDevicePathNode(NewDevPath); 1030 SetDevicePathEndNode(Temp); 1031 } 1032 1033 return NewDevPath; 1034 } 1035 1036