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 *
DevicePathFromHandle(IN EFI_HANDLE Handle)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 *
DevicePathInstance(IN OUT EFI_DEVICE_PATH ** DevicePath,OUT UINTN * Size)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
DevicePathInstanceCount(IN EFI_DEVICE_PATH * DevicePath)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 *
AppendDevicePath(IN EFI_DEVICE_PATH * Src1,IN EFI_DEVICE_PATH * Src2)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 *
AppendDevicePathNode(IN EFI_DEVICE_PATH * Src1,IN EFI_DEVICE_PATH * Src2)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 *
FileDevicePath(IN EFI_HANDLE Device OPTIONAL,IN CHAR16 * FileName)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
DevicePathSize(IN EFI_DEVICE_PATH * DevPath)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 *
DuplicateDevicePath(IN EFI_DEVICE_PATH * DevPath)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 *
UnpackDevicePath(IN EFI_DEVICE_PATH * DevPath)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*
AppendDevicePathInstance(IN EFI_DEVICE_PATH * Src,IN EFI_DEVICE_PATH * Instance)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
LibDevicePathToInterface(IN EFI_GUID * Protocol,IN EFI_DEVICE_PATH * FilePath,OUT VOID ** Interface)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
_DevPathPci(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathPccard(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathMemMap(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathController(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathVendor(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathAcpi(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathAtapi(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathScsi(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathFibre(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPath1394(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathUsb(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathI2O(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathMacAddr(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathIPv4(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathIPv6(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathInfiniBand(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathUart(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathHardDrive(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathCDROM(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathFilePath(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathMediaProtocol(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathBssBss(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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
_DevPathEndInstance(IN OUT POOL_PRINT * Str,IN VOID * DevPath)843 _DevPathEndInstance (
844 IN OUT POOL_PRINT *Str,
845 IN VOID *DevPath
846 )
847 {
848 CatPrint(Str, L",");
849 }
850
851 VOID
_DevPathNodeUnknown(IN OUT POOL_PRINT * Str,IN VOID * DevPath)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 *
DevicePathToStr(EFI_DEVICE_PATH * DevPath)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
LibMatchDevicePaths(IN EFI_DEVICE_PATH * Multi,IN EFI_DEVICE_PATH * Single)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 *
LibDuplicateDevicePathInstance(IN EFI_DEVICE_PATH * DevPath)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