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