]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/GenericBdsLib/DevicePath.c
UEFI HII: Merge UEFI HII support changes from branch.
[mirror_edk2.git] / MdeModulePkg / Library / GenericBdsLib / DevicePath.c
1 /** @file
2
3 Copyright (c) 2004 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 DevicePath.c
15
16 Abstract:
17
18 BDS internal function define the default device path string, it can be
19 replaced by platform device path.
20
21
22 **/
23
24 #include "InternalBdsLib.h"
25
26 //
27 // Platform Code should implement the Vendor specific Device Path display routine.
28 //
29 extern
30 VOID
31 DevPathVendor (
32 IN OUT POOL_PRINT *Str,
33 IN VOID *DevPath
34 )
35 ;
36
37 EFI_GUID mEfiDevicePathMessagingUartFlowControlGuid = DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL;
38
39 EFI_GUID mEfiDevicePathMessagingSASGuid = DEVICE_PATH_MESSAGING_SAS;
40
41
42 VOID *
43 ReallocatePool (
44 IN VOID *OldPool,
45 IN UINTN OldSize,
46 IN UINTN NewSize
47 )
48 /*++
49
50 Routine Description:
51
52 Adjusts the size of a previously allocated buffer.
53
54 Arguments:
55
56 OldPool - A pointer to the buffer whose size is being adjusted.
57
58 OldSize - The size of the current buffer.
59
60 NewSize - The size of the new buffer.
61
62 Returns:
63
64 EFI_SUCEESS - The requested number of bytes were allocated.
65
66 EFI_OUT_OF_RESOURCES - The pool requested could not be allocated.
67
68 EFI_INVALID_PARAMETER - The buffer was invalid.
69
70 --*/
71 {
72 VOID *NewPool;
73
74 NewPool = NULL;
75 if (NewSize) {
76 NewPool = AllocateZeroPool (NewSize);
77 }
78
79 if (OldPool) {
80 if (NewPool) {
81 CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
82 }
83
84 gBS->FreePool (OldPool);
85 }
86
87 return NewPool;
88 }
89
90
91 /**
92 Concatenates a formatted unicode string to allocated pool.
93 The caller must free the resulting buffer.
94
95 @param Str Tracks the allocated pool, size in use, and amount of pool
96 allocated.
97 @param fmt The format string
98
99 @return Allocated buffer with the formatted string printed in it.
100 @return The caller must free the allocated buffer. The buffer
101 @return allocation is not packed.
102
103 **/
104 CHAR16 *
105 CatPrint (
106 IN OUT POOL_PRINT *Str,
107 IN CHAR16 *fmt,
108 ...
109 )
110 {
111 UINT16 *AppendStr;
112 VA_LIST args;
113 UINTN strsize;
114
115 AppendStr = AllocateZeroPool (0x1000);
116 if (AppendStr == NULL) {
117 return Str->str;
118 }
119
120 VA_START (args, fmt);
121 UnicodeVSPrint (AppendStr, 0x1000, fmt, args);
122 VA_END (args);
123 if (NULL == Str->str) {
124 strsize = StrSize (AppendStr);
125 Str->str = AllocateZeroPool (strsize);
126 ASSERT (Str->str != NULL);
127 } else {
128 strsize = StrSize (AppendStr);
129 strsize += (StrSize (Str->str) - sizeof (UINT16));
130
131 Str->str = ReallocatePool (
132 Str->str,
133 StrSize (Str->str),
134 strsize
135 );
136 ASSERT (Str->str != NULL);
137 }
138
139 Str->maxlen = MAX_CHAR * sizeof (UINT16);
140 if (strsize < Str->maxlen) {
141 StrCat (Str->str, AppendStr);
142 Str->len = strsize - sizeof (UINT16);
143 }
144
145 gBS->FreePool (AppendStr);
146 return Str->str;
147 }
148
149
150 /**
151 Function unpacks a device path data structure so that all the nodes
152 of a device path are naturally aligned.
153
154 @param DevPath A pointer to a device path data structure
155
156 @return If the memory for the device path is successfully allocated, then a
157 @return pointer to the new device path is returned. Otherwise, NULL is returned.
158
159 **/
160 EFI_DEVICE_PATH_PROTOCOL *
161 BdsLibUnpackDevicePath (
162 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
163 )
164 {
165 EFI_DEVICE_PATH_PROTOCOL *Src;
166 EFI_DEVICE_PATH_PROTOCOL *Dest;
167 EFI_DEVICE_PATH_PROTOCOL *NewPath;
168 UINTN Size;
169
170 //
171 // Walk device path and round sizes to valid boundries
172 //
173 Src = DevPath;
174 Size = 0;
175 for (;;) {
176 Size += DevicePathNodeLength (Src);
177 Size += ALIGN_SIZE (Size);
178
179 if (IsDevicePathEnd (Src)) {
180 break;
181 }
182
183 Src = NextDevicePathNode (Src);
184 }
185 //
186 // Allocate space for the unpacked path
187 //
188 NewPath = AllocateZeroPool (Size);
189 if (NewPath) {
190
191 ASSERT (((UINTN) NewPath) % MIN_ALIGNMENT_SIZE == 0);
192
193 //
194 // Copy each node
195 //
196 Src = DevPath;
197 Dest = NewPath;
198 for (;;) {
199 Size = DevicePathNodeLength (Src);
200 CopyMem (Dest, Src, Size);
201 Size += ALIGN_SIZE (Size);
202 SetDevicePathNodeLength (Dest, Size);
203 Dest->Type |= EFI_DP_TYPE_UNPACKED;
204 Dest = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) Dest) + Size);
205
206 if (IsDevicePathEnd (Src)) {
207 break;
208 }
209
210 Src = NextDevicePathNode (Src);
211 }
212 }
213
214 return NewPath;
215 }
216
217 VOID
218 DevPathPci (
219 IN OUT POOL_PRINT *Str,
220 IN VOID *DevPath
221 )
222 {
223 PCI_DEVICE_PATH *Pci;
224
225 Pci = DevPath;
226 CatPrint (Str, L"Pci(%x|%x)", (UINTN) Pci->Device, (UINTN) Pci->Function);
227 }
228
229 VOID
230 DevPathPccard (
231 IN OUT POOL_PRINT *Str,
232 IN VOID *DevPath
233 )
234 {
235 PCCARD_DEVICE_PATH *Pccard;
236
237 Pccard = DevPath;
238 CatPrint (Str, L"Pcmcia(Function%x)", (UINTN) Pccard->FunctionNumber);
239 }
240
241 VOID
242 DevPathMemMap (
243 IN OUT POOL_PRINT *Str,
244 IN VOID *DevPath
245 )
246 {
247 MEMMAP_DEVICE_PATH *MemMap;
248
249 MemMap = DevPath;
250 CatPrint (
251 Str,
252 L"MemMap(%d:%lx-%lx)",
253 MemMap->MemoryType,
254 MemMap->StartingAddress,
255 MemMap->EndingAddress
256 );
257 }
258
259 VOID
260 DevPathController (
261 IN OUT POOL_PRINT *Str,
262 IN VOID *DevPath
263 )
264 {
265 CONTROLLER_DEVICE_PATH *Controller;
266
267 Controller = DevPath;
268 CatPrint (Str, L"Ctrl(%d)", (UINTN) Controller->ControllerNumber);
269 }
270
271
272 /**
273 Convert Vendor device path to device name
274
275 @param Str The buffer store device name
276 @param DevPath Pointer to vendor device path
277
278 @return When it return, the device name have been stored in *Str.
279
280 **/
281 VOID
282 DevPathVendor (
283 IN OUT POOL_PRINT *Str,
284 IN VOID *DevPath
285 )
286 {
287 VENDOR_DEVICE_PATH *Vendor;
288 CHAR16 *Type;
289 UINTN DataLength;
290 UINTN Index;
291 UINT32 FlowControlMap;
292
293 UINT16 Info;
294
295 Vendor = DevPath;
296
297 switch (DevicePathType (&Vendor->Header)) {
298 case HARDWARE_DEVICE_PATH:
299 Type = L"Hw";
300 // bugbug: nt 32 specific definition
301 #if 0
302 //
303 // If the device is a winntbus device, we will give it a readable device name.
304 //
305 if (CompareGuid (&Vendor->Guid, &mEfiWinNtThunkProtocolGuid)) {
306 CatPrint (Str, L"%s", L"WinNtBus");
307 return ;
308 } else if (CompareGuid (&Vendor->Guid, &mEfiWinNtGopGuid)) {
309 CatPrint (Str, L"%s", L"GOP");
310 return ;
311 } else if (CompareGuid (&Vendor->Guid, &mEfiWinNtSerialPortGuid)) {
312 CatPrint (Str, L"%s", L"Serial");
313 return ;
314 }
315 #endif
316 break;
317
318 case MESSAGING_DEVICE_PATH:
319 Type = L"Msg";
320 if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {
321 CatPrint (Str, L"VenPcAnsi()");
322 return ;
323 } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {
324 CatPrint (Str, L"VenVt100()");
325 return ;
326 } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {
327 CatPrint (Str, L"VenVt100Plus()");
328 return ;
329 } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {
330 CatPrint (Str, L"VenUft8()");
331 return ;
332 } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingUartFlowControlGuid)) {
333 FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);
334 switch (FlowControlMap & 0x00000003) {
335 case 0:
336 CatPrint (Str, L"UartFlowCtrl(%s)", L"None");
337 break;
338
339 case 1:
340 CatPrint (Str, L"UartFlowCtrl(%s)", L"Hardware");
341 break;
342
343 case 2:
344 CatPrint (Str, L"UartFlowCtrl(%s)", L"XonXoff");
345 break;
346
347 default:
348 break;
349 }
350
351 return ;
352
353 } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingSASGuid)) {
354 CatPrint (
355 Str,
356 L"SAS(%lx,%lx,%x,",
357 ((SAS_DEVICE_PATH *) Vendor)->SasAddress,
358 ((SAS_DEVICE_PATH *) Vendor)->Lun,
359 ((SAS_DEVICE_PATH *) Vendor)->RelativeTargetPort
360 );
361 Info = (((SAS_DEVICE_PATH *) Vendor)->DeviceTopology);
362 if ((Info & 0x0f) == 0) {
363 CatPrint (Str, L"NoTopology,0,0,0,");
364 } else if (((Info & 0x0f) == 1) || ((Info & 0x0f) == 2)) {
365 CatPrint (
366 Str,
367 L"%s,%s,%s,",
368 (Info & (0x1 << 4)) ? L"SATA" : L"SAS",
369 (Info & (0x1 << 5)) ? L"External" : L"Internal",
370 (Info & (0x1 << 6)) ? L"Expanded" : L"Direct"
371 );
372 if ((Info & 0x0f) == 1) {
373 CatPrint (Str, L"0,");
374 } else {
375 CatPrint (Str, L"%x,", (UINTN) ((Info >> 8) & 0xff));
376 }
377 } else {
378 CatPrint (Str, L"0,0,0,0,");
379 }
380
381 CatPrint (Str, L"%x)", (UINTN) ((SAS_DEVICE_PATH *) Vendor)->Reserved);
382 return ;
383
384 } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {
385 CatPrint (Str, L"DebugPort()");
386 return ;
387 }
388 break;
389
390 case MEDIA_DEVICE_PATH:
391 Type = L"Media";
392 break;
393
394 default:
395 Type = L"?";
396 break;
397 }
398
399 CatPrint (Str, L"Ven%s(%g", Type, &Vendor->Guid);
400 DataLength = DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH);
401 if (DataLength > 0) {
402 CatPrint (Str, L",");
403 for (Index = 0; Index < DataLength; Index++) {
404 CatPrint (Str, L"%02x", (UINTN) ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);
405 }
406 }
407 CatPrint (Str, L")");
408 }
409
410
411 VOID
412 DevPathAcpi (
413 IN OUT POOL_PRINT *Str,
414 IN VOID *DevPath
415 )
416 {
417 ACPI_HID_DEVICE_PATH *Acpi;
418
419 Acpi = DevPath;
420 if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
421 CatPrint (Str, L"Acpi(PNP%04x,%x)", (UINTN) EISA_ID_TO_NUM (Acpi->HID), (UINTN) Acpi->UID);
422 } else {
423 CatPrint (Str, L"Acpi(%08x,%x)", (UINTN) Acpi->HID, (UINTN) Acpi->UID);
424 }
425 }
426
427 VOID
428 DevPathExtendedAcpi (
429 IN OUT POOL_PRINT *Str,
430 IN VOID *DevPath
431 )
432 {
433 ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi;
434 //
435 // Index for HID, UID and CID strings, 0 for non-exist
436 //
437 UINT16 HIDSTRIdx;
438 UINT16 UIDSTRIdx;
439 UINT16 CIDSTRIdx;
440 UINT16 Index;
441 UINT16 Length;
442 UINT16 Anchor;
443 CHAR8 *AsChar8Array;
444
445 ASSERT (Str != NULL);
446 ASSERT (DevPath != NULL);
447
448 HIDSTRIdx = 0;
449 UIDSTRIdx = 0;
450 CIDSTRIdx = 0;
451 ExtendedAcpi = DevPath;
452 Length = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) ExtendedAcpi);
453
454 ASSERT (Length >= 19);
455 AsChar8Array = (CHAR8 *) ExtendedAcpi;
456
457 //
458 // find HIDSTR
459 //
460 Anchor = 16;
461 for (Index = Anchor; Index < Length && AsChar8Array[Index]; Index++) {
462 ;
463 }
464 if (Index > Anchor) {
465 HIDSTRIdx = Anchor;
466 }
467 //
468 // find UIDSTR
469 //
470 Anchor = (UINT16) (Index + 1);
471 for (Index = Anchor; Index < Length && AsChar8Array[Index]; Index++) {
472 ;
473 }
474 if (Index > Anchor) {
475 UIDSTRIdx = Anchor;
476 }
477 //
478 // find CIDSTR
479 //
480 Anchor = (UINT16) (Index + 1);
481 for (Index = Anchor; Index < Length && AsChar8Array[Index]; Index++) {
482 ;
483 }
484 if (Index > Anchor) {
485 CIDSTRIdx = Anchor;
486 }
487
488 if (HIDSTRIdx == 0 && CIDSTRIdx == 0 && ExtendedAcpi->UID == 0) {
489 CatPrint (Str, L"AcpiExp(");
490 if ((ExtendedAcpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
491 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->HID));
492 } else {
493 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->HID);
494 }
495 if ((ExtendedAcpi->CID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
496 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->CID));
497 } else {
498 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->CID);
499 }
500 if (UIDSTRIdx != 0) {
501 CatPrint (Str, L"%a)", AsChar8Array + UIDSTRIdx);
502 } else {
503 CatPrint (Str, L"\"\")");
504 }
505 } else {
506 CatPrint (Str, L"AcpiEx(");
507 if ((ExtendedAcpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
508 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->HID));
509 } else {
510 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->HID);
511 }
512 if ((ExtendedAcpi->CID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
513 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->CID));
514 } else {
515 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->CID);
516 }
517 CatPrint (Str, L"%x,", (UINTN) ExtendedAcpi->UID);
518
519 if (HIDSTRIdx != 0) {
520 CatPrint (Str, L"%a,", AsChar8Array + HIDSTRIdx);
521 } else {
522 CatPrint (Str, L"\"\",");
523 }
524 if (CIDSTRIdx != 0) {
525 CatPrint (Str, L"%a,", AsChar8Array + CIDSTRIdx);
526 } else {
527 CatPrint (Str, L"\"\",");
528 }
529 if (UIDSTRIdx != 0) {
530 CatPrint (Str, L"%a)", AsChar8Array + UIDSTRIdx);
531 } else {
532 CatPrint (Str, L"\"\")");
533 }
534 }
535
536 }
537
538 VOID
539 DevPathAdrAcpi (
540 IN OUT POOL_PRINT *Str,
541 IN VOID *DevPath
542 )
543 {
544 ACPI_ADR_DEVICE_PATH *AcpiAdr;
545 UINT16 Index;
546 UINT16 Length;
547 UINT16 AdditionalAdrCount;
548
549 AcpiAdr = DevPath;
550 Length = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr);
551 AdditionalAdrCount = (UINT16) ((Length - 8) / 4);
552
553 CatPrint (Str, L"AcpiAdr(%x", (UINTN) AcpiAdr->ADR);
554 for (Index = 0; Index < AdditionalAdrCount; Index++) {
555 CatPrint (Str, L",%x", (UINTN) *(UINT32 *) ((UINT8 *) AcpiAdr + 8 + Index * 4));
556 }
557 CatPrint (Str, L")");
558 }
559
560 VOID
561 DevPathAtapi (
562 IN OUT POOL_PRINT *Str,
563 IN VOID *DevPath
564 )
565 {
566 ATAPI_DEVICE_PATH *Atapi;
567
568 Atapi = DevPath;
569 CatPrint (
570 Str,
571 L"Ata(%s,%s)",
572 Atapi->PrimarySecondary ? L"Secondary" : L"Primary",
573 Atapi->SlaveMaster ? L"Slave" : L"Master"
574 );
575 }
576
577 VOID
578 DevPathScsi (
579 IN OUT POOL_PRINT *Str,
580 IN VOID *DevPath
581 )
582 {
583 SCSI_DEVICE_PATH *Scsi;
584
585 Scsi = DevPath;
586 CatPrint (Str, L"Scsi(Pun%x,Lun%x)", (UINTN) Scsi->Pun, (UINTN) Scsi->Lun);
587 }
588
589 VOID
590 DevPathFibre (
591 IN OUT POOL_PRINT *Str,
592 IN VOID *DevPath
593 )
594 {
595 FIBRECHANNEL_DEVICE_PATH *Fibre;
596
597 Fibre = DevPath;
598 CatPrint (Str, L"Fibre(Wwn%lx,Lun%x)", Fibre->WWN, Fibre->Lun);
599 }
600
601 VOID
602 DevPath1394 (
603 IN OUT POOL_PRINT *Str,
604 IN VOID *DevPath
605 )
606 {
607 F1394_DEVICE_PATH *F1394;
608
609 F1394 = DevPath;
610 CatPrint (Str, L"1394(%g)", &F1394->Guid);
611 }
612
613 VOID
614 DevPathUsb (
615 IN OUT POOL_PRINT *Str,
616 IN VOID *DevPath
617 )
618 {
619 USB_DEVICE_PATH *Usb;
620
621 Usb = DevPath;
622 CatPrint (Str, L"Usb(%x,%x)", (UINTN) Usb->ParentPortNumber, (UINTN) Usb->InterfaceNumber);
623 }
624
625 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
626 VOID
627 DevPathUsbWWID (
628 IN OUT POOL_PRINT *Str,
629 IN VOID *DevPath
630 )
631 {
632 USB_WWID_DEVICE_PATH *UsbWWId;
633
634 UsbWWId = DevPath;
635 CatPrint (
636 Str,
637 L"UsbWwid(%x,%x,%x,\"WWID\")",
638 (UINTN) UsbWWId->VendorId,
639 (UINTN) UsbWWId->ProductId,
640 (UINTN) UsbWWId->InterfaceNumber
641 );
642 }
643
644 VOID
645 DevPathLogicalUnit (
646 IN OUT POOL_PRINT *Str,
647 IN VOID *DevPath
648 )
649 {
650 DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
651
652 LogicalUnit = DevPath;
653 CatPrint (Str, L"Unit(%x)", (UINTN) LogicalUnit->Lun);
654 }
655 #endif
656
657 VOID
658 DevPathUsbClass (
659 IN OUT POOL_PRINT *Str,
660 IN VOID *DevPath
661 )
662 {
663 USB_CLASS_DEVICE_PATH *UsbClass;
664
665 UsbClass = DevPath;
666 CatPrint (
667 Str,
668 L"Usb Class(%x,%x,%x,%x,%x)",
669 (UINTN) UsbClass->VendorId,
670 (UINTN) UsbClass->ProductId,
671 (UINTN) UsbClass->DeviceClass,
672 (UINTN) UsbClass->DeviceSubClass,
673 (UINTN) UsbClass->DeviceProtocol
674 );
675 }
676
677 VOID
678 DevPathSata (
679 IN OUT POOL_PRINT *Str,
680 IN VOID *DevPath
681 )
682 {
683 SATA_DEVICE_PATH *Sata;
684
685 Sata = DevPath;
686 CatPrint (
687 Str,
688 L"Sata(%x,%x,%x)",
689 (UINTN) Sata->HBAPortNumber,
690 (UINTN) Sata->PortMultiplierPortNumber,
691 (UINTN) Sata->Lun
692 );
693 }
694
695 VOID
696 DevPathI2O (
697 IN OUT POOL_PRINT *Str,
698 IN VOID *DevPath
699 )
700 {
701 I2O_DEVICE_PATH *I2O;
702
703 I2O = DevPath;
704 CatPrint (Str, L"I2O(%x)", (UINTN) I2O->Tid);
705 }
706
707 VOID
708 DevPathMacAddr (
709 IN OUT POOL_PRINT *Str,
710 IN VOID *DevPath
711 )
712 {
713 MAC_ADDR_DEVICE_PATH *MAC;
714 UINTN HwAddressSize;
715 UINTN Index;
716
717 MAC = DevPath;
718
719 HwAddressSize = sizeof (EFI_MAC_ADDRESS);
720 if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
721 HwAddressSize = 6;
722 }
723
724 CatPrint (Str, L"Mac(");
725
726 for (Index = 0; Index < HwAddressSize; Index++) {
727 CatPrint (Str, L"%02x", (UINTN) MAC->MacAddress.Addr[Index]);
728 }
729
730 CatPrint (Str, L")");
731 }
732
733 VOID
734 DevPathIPv4 (
735 IN OUT POOL_PRINT *Str,
736 IN VOID *DevPath
737 )
738 {
739 IPv4_DEVICE_PATH *IP;
740
741 IP = DevPath;
742 CatPrint (
743 Str,
744 L"IPv4(%d.%d.%d.%d:%d)",
745 (UINTN) IP->RemoteIpAddress.Addr[0],
746 (UINTN) IP->RemoteIpAddress.Addr[1],
747 (UINTN) IP->RemoteIpAddress.Addr[2],
748 (UINTN) IP->RemoteIpAddress.Addr[3],
749 (UINTN) IP->RemotePort
750 );
751 }
752
753 VOID
754 DevPathIPv6 (
755 IN OUT POOL_PRINT *Str,
756 IN VOID *DevPath
757 )
758 {
759 IPv6_DEVICE_PATH *IP;
760
761 IP = DevPath;
762 CatPrint (
763 Str,
764 L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",
765 (UINTN) IP->RemoteIpAddress.Addr[0],
766 (UINTN) IP->RemoteIpAddress.Addr[1],
767 (UINTN) IP->RemoteIpAddress.Addr[2],
768 (UINTN) IP->RemoteIpAddress.Addr[3],
769 (UINTN) IP->RemoteIpAddress.Addr[4],
770 (UINTN) IP->RemoteIpAddress.Addr[5],
771 (UINTN) IP->RemoteIpAddress.Addr[6],
772 (UINTN) IP->RemoteIpAddress.Addr[7],
773 (UINTN) IP->RemoteIpAddress.Addr[8],
774 (UINTN) IP->RemoteIpAddress.Addr[9],
775 (UINTN) IP->RemoteIpAddress.Addr[10],
776 (UINTN) IP->RemoteIpAddress.Addr[11],
777 (UINTN) IP->RemoteIpAddress.Addr[12],
778 (UINTN) IP->RemoteIpAddress.Addr[13],
779 (UINTN) IP->RemoteIpAddress.Addr[14],
780 (UINTN) IP->RemoteIpAddress.Addr[15]
781 );
782 }
783
784 VOID
785 DevPathInfiniBand (
786 IN OUT POOL_PRINT *Str,
787 IN VOID *DevPath
788 )
789 {
790 INFINIBAND_DEVICE_PATH *InfiniBand;
791
792 InfiniBand = DevPath;
793 CatPrint (
794 Str,
795 L"Infiniband(%x,%g,%lx,%lx,%lx)",
796 (UINTN) InfiniBand->ResourceFlags,
797 InfiniBand->PortGid,
798 InfiniBand->ServiceId,
799 InfiniBand->TargetPortId,
800 InfiniBand->DeviceId
801 );
802 }
803
804 VOID
805 DevPathUart (
806 IN OUT POOL_PRINT *Str,
807 IN VOID *DevPath
808 )
809 {
810 UART_DEVICE_PATH *Uart;
811 CHAR8 Parity;
812
813 Uart = DevPath;
814 switch (Uart->Parity) {
815 case 0:
816 Parity = 'D';
817 break;
818
819 case 1:
820 Parity = 'N';
821 break;
822
823 case 2:
824 Parity = 'E';
825 break;
826
827 case 3:
828 Parity = 'O';
829 break;
830
831 case 4:
832 Parity = 'M';
833 break;
834
835 case 5:
836 Parity = 'S';
837 break;
838
839 default:
840 Parity = 'x';
841 break;
842 }
843
844 if (Uart->BaudRate == 0) {
845 CatPrint (Str, L"Uart(DEFAULT,%c,", Parity);
846 } else {
847 CatPrint (Str, L"Uart(%d,%c,", Uart->BaudRate, Parity);
848 }
849
850 if (Uart->DataBits == 0) {
851 CatPrint (Str, L"D,");
852 } else {
853 CatPrint (Str, L"%d,", (UINTN) Uart->DataBits);
854 }
855
856 switch (Uart->StopBits) {
857 case 0:
858 CatPrint (Str, L"D)");
859 break;
860
861 case 1:
862 CatPrint (Str, L"1)");
863 break;
864
865 case 2:
866 CatPrint (Str, L"1.5)");
867 break;
868
869 case 3:
870 CatPrint (Str, L"2)");
871 break;
872
873 default:
874 CatPrint (Str, L"x)");
875 break;
876 }
877 }
878
879 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
880 VOID
881 DevPathiSCSI (
882 IN OUT POOL_PRINT *Str,
883 IN VOID *DevPath
884 )
885 {
886 ISCSI_DEVICE_PATH_WITH_NAME *iSCSI;
887 UINT16 Options;
888
889 ASSERT (Str != NULL);
890 ASSERT (DevPath != NULL);
891
892 iSCSI = DevPath;
893 CatPrint (
894 Str,
895 L"iSCSI(%s,%x,%lx,",
896 iSCSI->iSCSITargetName,
897 iSCSI->TargetPortalGroupTag,
898 iSCSI->Lun
899 );
900
901 Options = iSCSI->LoginOption;
902 CatPrint (Str, L"%s,", ((Options >> 1) & 0x0001) ? L"CRC32C" : L"None");
903 CatPrint (Str, L"%s,", ((Options >> 3) & 0x0001) ? L"CRC32C" : L"None");
904 if ((Options >> 11) & 0x0001) {
905 CatPrint (Str, L"%s,", L"None");
906 } else if ((Options >> 12) & 0x0001) {
907 CatPrint (Str, L"%s,", L"CHAP_UNI");
908 } else {
909 CatPrint (Str, L"%s,", L"CHAP_BI");
910
911 }
912
913 CatPrint (Str, L"%s)", (iSCSI->NetworkProtocol == 0) ? L"TCP" : L"reserved");
914 }
915 #endif
916
917 VOID
918 DevPathHardDrive (
919 IN OUT POOL_PRINT *Str,
920 IN VOID *DevPath
921 )
922 {
923 HARDDRIVE_DEVICE_PATH *Hd;
924
925 Hd = DevPath;
926 switch (Hd->SignatureType) {
927 case SIGNATURE_TYPE_MBR:
928 CatPrint (
929 Str,
930 L"HD(Part%d,Sig%08x)",
931 (UINTN) Hd->PartitionNumber,
932 (UINTN) *((UINT32 *) (&(Hd->Signature[0])))
933 );
934 break;
935
936 case SIGNATURE_TYPE_GUID:
937 CatPrint (
938 Str,
939 L"HD(Part%d,Sig%g)",
940 (UINTN) Hd->PartitionNumber,
941 (EFI_GUID *) &(Hd->Signature[0])
942 );
943 break;
944
945 default:
946 CatPrint (
947 Str,
948 L"HD(Part%d,MBRType=%02x,SigType=%02x)",
949 (UINTN) Hd->PartitionNumber,
950 (UINTN) Hd->MBRType,
951 (UINTN) Hd->SignatureType
952 );
953 break;
954 }
955 }
956
957 VOID
958 DevPathCDROM (
959 IN OUT POOL_PRINT *Str,
960 IN VOID *DevPath
961 )
962 {
963 CDROM_DEVICE_PATH *Cd;
964
965 Cd = DevPath;
966 CatPrint (Str, L"CDROM(Entry%x)", (UINTN) Cd->BootEntry);
967 }
968
969 VOID
970 DevPathFilePath (
971 IN OUT POOL_PRINT *Str,
972 IN VOID *DevPath
973 )
974 {
975 FILEPATH_DEVICE_PATH *Fp;
976
977 Fp = DevPath;
978 CatPrint (Str, L"%s", Fp->PathName);
979 }
980
981 VOID
982 DevPathMediaProtocol (
983 IN OUT POOL_PRINT *Str,
984 IN VOID *DevPath
985 )
986 {
987 MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;
988
989 MediaProt = DevPath;
990 CatPrint (Str, L"Media(%g)", &MediaProt->Protocol);
991 }
992
993 VOID
994 DevPathFvFilePath (
995 IN OUT POOL_PRINT *Str,
996 IN VOID *DevPath
997 )
998 {
999 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;
1000
1001 FvFilePath = DevPath;
1002 CatPrint (Str, L"%g", &FvFilePath->FvFileName);
1003 }
1004
1005 VOID
1006 DevPathBssBss (
1007 IN OUT POOL_PRINT *Str,
1008 IN VOID *DevPath
1009 )
1010 {
1011 BBS_BBS_DEVICE_PATH *Bbs;
1012 CHAR16 *Type;
1013
1014 Bbs = DevPath;
1015 switch (Bbs->DeviceType) {
1016 case BBS_TYPE_FLOPPY:
1017 Type = L"Floppy";
1018 break;
1019
1020 case BBS_TYPE_HARDDRIVE:
1021 Type = L"Harddrive";
1022 break;
1023
1024 case BBS_TYPE_CDROM:
1025 Type = L"CDROM";
1026 break;
1027
1028 case BBS_TYPE_PCMCIA:
1029 Type = L"PCMCIA";
1030 break;
1031
1032 case BBS_TYPE_USB:
1033 Type = L"Usb";
1034 break;
1035
1036 case BBS_TYPE_EMBEDDED_NETWORK:
1037 Type = L"Net";
1038 break;
1039
1040 case BBS_TYPE_BEV:
1041 Type = L"BEV";
1042 break;
1043
1044 default:
1045 Type = L"?";
1046 break;
1047 }
1048 CatPrint (Str, L"Legacy-%s", Type);
1049 }
1050
1051 VOID
1052 DevPathEndInstance (
1053 IN OUT POOL_PRINT *Str,
1054 IN VOID *DevPath
1055 )
1056 {
1057 CatPrint (Str, L",");
1058 }
1059
1060 VOID
1061 DevPathNodeUnknown (
1062 IN OUT POOL_PRINT *Str,
1063 IN VOID *DevPath
1064 )
1065 {
1066 CatPrint (Str, L"?");
1067 }
1068
1069 DEVICE_PATH_STRING_TABLE DevPathTable[] = {
1070 HARDWARE_DEVICE_PATH,
1071 HW_PCI_DP,
1072 DevPathPci,
1073 HARDWARE_DEVICE_PATH,
1074 HW_PCCARD_DP,
1075 DevPathPccard,
1076 HARDWARE_DEVICE_PATH,
1077 HW_MEMMAP_DP,
1078 DevPathMemMap,
1079 HARDWARE_DEVICE_PATH,
1080 HW_VENDOR_DP,
1081 DevPathVendor,
1082 HARDWARE_DEVICE_PATH,
1083 HW_CONTROLLER_DP,
1084 DevPathController,
1085 ACPI_DEVICE_PATH,
1086 ACPI_DP,
1087 DevPathAcpi,
1088 ACPI_DEVICE_PATH,
1089 ACPI_EXTENDED_DP,
1090 DevPathExtendedAcpi,
1091 ACPI_DEVICE_PATH,
1092 ACPI_ADR_DP,
1093 DevPathAdrAcpi,
1094 MESSAGING_DEVICE_PATH,
1095 MSG_ATAPI_DP,
1096 DevPathAtapi,
1097 MESSAGING_DEVICE_PATH,
1098 MSG_SCSI_DP,
1099 DevPathScsi,
1100 MESSAGING_DEVICE_PATH,
1101 MSG_FIBRECHANNEL_DP,
1102 DevPathFibre,
1103 MESSAGING_DEVICE_PATH,
1104 MSG_1394_DP,
1105 DevPath1394,
1106 MESSAGING_DEVICE_PATH,
1107 MSG_USB_DP,
1108 DevPathUsb,
1109 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
1110 MESSAGING_DEVICE_PATH,
1111 MSG_USB_WWID_DP,
1112 DevPathUsbWWID,
1113 MESSAGING_DEVICE_PATH,
1114 MSG_DEVICE_LOGICAL_UNIT_DP,
1115 DevPathLogicalUnit,
1116 #endif
1117 MESSAGING_DEVICE_PATH,
1118 MSG_USB_CLASS_DP,
1119 DevPathUsbClass,
1120 MESSAGING_DEVICE_PATH,
1121 MSG_SATA_DP,
1122 DevPathSata,
1123 MESSAGING_DEVICE_PATH,
1124 MSG_I2O_DP,
1125 DevPathI2O,
1126 MESSAGING_DEVICE_PATH,
1127 MSG_MAC_ADDR_DP,
1128 DevPathMacAddr,
1129 MESSAGING_DEVICE_PATH,
1130 MSG_IPv4_DP,
1131 DevPathIPv4,
1132 MESSAGING_DEVICE_PATH,
1133 MSG_IPv6_DP,
1134 DevPathIPv6,
1135 MESSAGING_DEVICE_PATH,
1136 MSG_INFINIBAND_DP,
1137 DevPathInfiniBand,
1138 MESSAGING_DEVICE_PATH,
1139 MSG_UART_DP,
1140 DevPathUart,
1141 MESSAGING_DEVICE_PATH,
1142 MSG_VENDOR_DP,
1143 DevPathVendor,
1144 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
1145 MESSAGING_DEVICE_PATH,
1146 MSG_ISCSI_DP,
1147 DevPathiSCSI,
1148 #endif
1149 MEDIA_DEVICE_PATH,
1150 MEDIA_HARDDRIVE_DP,
1151 DevPathHardDrive,
1152 MEDIA_DEVICE_PATH,
1153 MEDIA_CDROM_DP,
1154 DevPathCDROM,
1155 MEDIA_DEVICE_PATH,
1156 MEDIA_VENDOR_DP,
1157 DevPathVendor,
1158 MEDIA_DEVICE_PATH,
1159 MEDIA_FILEPATH_DP,
1160 DevPathFilePath,
1161 MEDIA_DEVICE_PATH,
1162 MEDIA_PROTOCOL_DP,
1163 DevPathMediaProtocol,
1164 #if (EFI_SPECIFICATION_VERSION != 0x00020000)
1165 MEDIA_DEVICE_PATH,
1166 MEDIA_PIWG_FW_FILE_DP,
1167 DevPathFvFilePath,
1168 #endif
1169 BBS_DEVICE_PATH,
1170 BBS_BBS_DP,
1171 DevPathBssBss,
1172 END_DEVICE_PATH_TYPE,
1173 END_INSTANCE_DEVICE_PATH_SUBTYPE,
1174 DevPathEndInstance,
1175 0,
1176 0,
1177 NULL
1178 };
1179
1180
1181 /**
1182
1183 **/
1184 CHAR16 *
1185 DevicePathToStr (
1186 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
1187 )
1188 {
1189 POOL_PRINT Str;
1190 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
1191 VOID (*DumpNode) (POOL_PRINT *, VOID *);
1192
1193 UINTN Index;
1194 UINTN NewSize;
1195
1196 EFI_STATUS Status;
1197 CHAR16 *ToText;
1198 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;
1199
1200 ZeroMem (&Str, sizeof (Str));
1201
1202 if (DevPath == NULL) {
1203 goto Done;
1204 }
1205
1206 Status = gBS->LocateProtocol (
1207 &gEfiDevicePathToTextProtocolGuid,
1208 NULL,
1209 (VOID **) &DevPathToText
1210 );
1211 if (!EFI_ERROR (Status)) {
1212 ToText = DevPathToText->ConvertDevicePathToText (
1213 DevPath,
1214 FALSE,
1215 TRUE
1216 );
1217 ASSERT (ToText != NULL);
1218 return ToText;
1219 }
1220
1221 //
1222 // Unpacked the device path
1223 //
1224 DevPath = BdsLibUnpackDevicePath (DevPath);
1225 ASSERT (DevPath);
1226
1227 //
1228 // Process each device path node
1229 //
1230 DevPathNode = DevPath;
1231 while (!IsDevicePathEnd (DevPathNode)) {
1232 //
1233 // Find the handler to dump this device path node
1234 //
1235 DumpNode = NULL;
1236 for (Index = 0; DevPathTable[Index].Function; Index += 1) {
1237
1238 if (DevicePathType (DevPathNode) == DevPathTable[Index].Type &&
1239 DevicePathSubType (DevPathNode) == DevPathTable[Index].SubType
1240 ) {
1241 DumpNode = DevPathTable[Index].Function;
1242 break;
1243 }
1244 }
1245 //
1246 // If not found, use a generic function
1247 //
1248 if (!DumpNode) {
1249 DumpNode = DevPathNodeUnknown;
1250 }
1251 //
1252 // Put a path seperator in if needed
1253 //
1254 if (Str.len && DumpNode != DevPathEndInstance) {
1255 CatPrint (&Str, L"/");
1256 }
1257 //
1258 // Print this node of the device path
1259 //
1260 DumpNode (&Str, DevPathNode);
1261
1262 //
1263 // Next device path node
1264 //
1265 DevPathNode = NextDevicePathNode (DevPathNode);
1266 }
1267 //
1268 // Shrink pool used for string allocation
1269 //
1270 gBS->FreePool (DevPath);
1271
1272 Done:
1273 NewSize = (Str.len + 1) * sizeof (CHAR16);
1274 Str.str = ReallocatePool (Str.str, NewSize, NewSize);
1275 ASSERT (Str.str != NULL);
1276 Str.str[Str.len] = 0;
1277 return Str.str;
1278 }
1279
1280
1281 /**
1282 Function creates a device path data structure that identically matches the
1283 device path passed in.
1284
1285 @param DevPath A pointer to a device path data structure.
1286
1287 @return The new copy of DevPath is created to identically match the input.
1288 @return Otherwise, NULL is returned.
1289
1290 **/
1291 EFI_DEVICE_PATH_PROTOCOL *
1292 LibDuplicateDevicePathInstance (
1293 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
1294 )
1295 {
1296 EFI_DEVICE_PATH_PROTOCOL *NewDevPath;
1297 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
1298 EFI_DEVICE_PATH_PROTOCOL *Temp;
1299 UINTN Size;
1300
1301 //
1302 // get the size of an instance from the input
1303 //
1304 Temp = DevPath;
1305 DevicePathInst = GetNextDevicePathInstance (&Temp, &Size);
1306
1307 //
1308 // Make a copy
1309 //
1310 NewDevPath = NULL;
1311 if (Size) {
1312 NewDevPath = AllocateZeroPool (Size);
1313 ASSERT (NewDevPath != NULL);
1314 }
1315
1316 if (NewDevPath) {
1317 CopyMem (NewDevPath, DevicePathInst, Size);
1318 }
1319
1320 return NewDevPath;
1321 }