3 Copyright (c) 2006 - 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
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.
18 BDS internal function define the default device path string, it can be
19 replaced by platform device path.
23 #include <EdkGenericBdsLibInternal.h>
25 EFI_GUID mEfiWinNtThunkProtocolGuid
= EFI_WIN_NT_THUNK_PROTOCOL_GUID
;
26 EFI_GUID mEfiWinNtUgaGuid
= EFI_WIN_NT_UGA_GUID
;
27 EFI_GUID mEfiWinNtGopGuid
= EFI_WIN_NT_GOP_GUID
;
28 EFI_GUID mEfiWinNtSerialPortGuid
= EFI_WIN_NT_SERIAL_PORT_GUID
;
29 EFI_GUID mEfiMsgPcAnsiGuid
= DEVICE_PATH_MESSAGING_PC_ANSI
;
30 EFI_GUID mEfiMsgVt100Guid
= DEVICE_PATH_MESSAGING_VT_100
;
31 EFI_GUID mEfiMsgVt100PlusGuid
= DEVICE_PATH_MESSAGING_VT_100_PLUS
;
32 EFI_GUID mEfiMsgVt100Utf8Guid
= DEVICE_PATH_MESSAGING_VT_UTF8
;
44 Adjusts the size of a previously allocated buffer.
48 OldPool - A pointer to the buffer whose size is being adjusted.
50 OldSize - The size of the current buffer.
52 NewSize - The size of the new buffer.
56 EFI_SUCEESS - The requested number of bytes were allocated.
58 EFI_OUT_OF_RESOURCES - The pool requested could not be allocated.
60 EFI_INVALID_PARAMETER - The buffer was invalid.
68 NewPool
= AllocateZeroPool (NewSize
);
73 CopyMem (NewPool
, OldPool
, OldSize
< NewSize
? OldSize
: NewSize
);
84 IN OUT POOL_PRINT
*Str
,
92 Concatenates a formatted unicode string to allocated pool.
93 The caller must free the resulting buffer.
97 Str - Tracks the allocated pool, size in use, and
98 amount of pool allocated.
100 fmt - The format string
104 Allocated buffer with the formatted string printed in it.
105 The caller must free the allocated buffer. The buffer
106 allocation is not packed.
114 AppendStr
= AllocateZeroPool (0x1000);
115 if (AppendStr
== NULL
) {
119 VA_START (args
, fmt
);
120 UnicodeVSPrint (AppendStr
, 0x1000, fmt
, args
);
122 if (NULL
== Str
->str
) {
123 strsize
= StrSize (AppendStr
);
124 Str
->str
= AllocateZeroPool (strsize
);
125 ASSERT (Str
->str
!= NULL
);
127 strsize
= StrSize (AppendStr
) + StrSize (Str
->str
) - sizeof (UINT16
);
128 Str
->str
= ReallocatePool (
133 ASSERT (Str
->str
!= NULL
);
136 Str
->maxlen
= MAX_CHAR
* sizeof (UINT16
);
137 if (strsize
< Str
->maxlen
) {
138 StrCat (Str
->str
, AppendStr
);
139 Str
->len
= strsize
- sizeof (UINT16
);
142 FreePool (AppendStr
);
146 EFI_DEVICE_PATH_PROTOCOL
*
147 BdsLibUnpackDevicePath (
148 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
154 Function unpacks a device path data structure so that all the nodes
155 of a device path are naturally aligned.
159 DevPath - A pointer to a device path data structure
163 If the memory for the device path is successfully allocated, then a
164 pointer to the new device path is returned. Otherwise, NULL is returned.
168 EFI_DEVICE_PATH_PROTOCOL
*Src
;
169 EFI_DEVICE_PATH_PROTOCOL
*Dest
;
170 EFI_DEVICE_PATH_PROTOCOL
*NewPath
;
174 // Walk device path and round sizes to valid boundries
179 Size
+= DevicePathNodeLength (Src
);
180 Size
+= ALIGN_SIZE (Size
);
182 if (IsDevicePathEnd (Src
)) {
186 Src
= NextDevicePathNode (Src
);
189 // Allocate space for the unpacked path
191 NewPath
= AllocateZeroPool (Size
);
194 ASSERT (((UINTN
) NewPath
) % MIN_ALIGNMENT_SIZE
== 0);
202 Size
= DevicePathNodeLength (Src
);
203 CopyMem (Dest
, Src
, Size
);
204 Size
+= ALIGN_SIZE (Size
);
205 SetDevicePathNodeLength (Dest
, Size
);
206 Dest
->Type
|= EFI_DP_TYPE_UNPACKED
;
207 Dest
= (EFI_DEVICE_PATH_PROTOCOL
*) (((UINT8
*) Dest
) + Size
);
209 if (IsDevicePathEnd (Src
)) {
213 Src
= NextDevicePathNode (Src
);
222 IN OUT POOL_PRINT
*Str
,
226 PCI_DEVICE_PATH
*Pci
;
229 CatPrint (Str
, L
"Pci(%x|%x)", Pci
->Device
, Pci
->Function
);
234 IN OUT POOL_PRINT
*Str
,
238 PCCARD_DEVICE_PATH
*Pccard
;
241 CatPrint (Str
, L
"Pcmcia(Function%x)", Pccard
->FunctionNumber
);
246 IN OUT POOL_PRINT
*Str
,
250 MEMMAP_DEVICE_PATH
*MemMap
;
255 L
"MemMap(%d:%.lx-%.lx)",
257 MemMap
->StartingAddress
,
258 MemMap
->EndingAddress
264 IN OUT POOL_PRINT
*Str
,
268 CONTROLLER_DEVICE_PATH
*Controller
;
270 Controller
= DevPath
;
271 CatPrint (Str
, L
"Ctrl(%d)", Controller
->ControllerNumber
);
276 IN OUT POOL_PRINT
*Str
,
283 Convert Vendor device path to device name
287 Str - The buffer store device name
288 DevPath - Pointer to vendor device path
292 When it return, the device name have been stored in *Str.
296 VENDOR_DEVICE_PATH
*Vendor
;
301 Temp
= (INT32
*) (&Vendor
->Guid
);
303 switch (DevicePathType (&Vendor
->Header
)) {
304 case HARDWARE_DEVICE_PATH
:
306 // If the device is a winntbus device, we will give it a readable device name.
308 if (CompareGuid (&Vendor
->Guid
, &mEfiWinNtThunkProtocolGuid
)) {
309 CatPrint (Str
, L
"%s", L
"WinNtBus");
311 } else if (CompareGuid (&Vendor
->Guid
, &mEfiWinNtUgaGuid
)) {
312 CatPrint (Str
, L
"%s", L
"UGA");
314 } else if (CompareGuid (&Vendor
->Guid
, &mEfiWinNtGopGuid
)) {
315 CatPrint (Str
, L
"%s", L
"GOP");
317 } else if (CompareGuid (&Vendor
->Guid
, &mEfiWinNtSerialPortGuid
)) {
318 CatPrint (Str
, L
"%s", L
"Serial");
325 case MESSAGING_DEVICE_PATH
:
327 // If the device is a winntbus device, we will give it a readable device name.
329 if (CompareGuid (&Vendor
->Guid
, &mEfiMsgPcAnsiGuid
)) {
330 CatPrint (Str
, L
"%s", L
"PC-ANSI");
332 } else if (CompareGuid (&Vendor
->Guid
, &mEfiMsgVt100Guid
)) {
333 CatPrint (Str
, L
"%s", L
"VT100");
335 } else if (CompareGuid (&Vendor
->Guid
, &mEfiMsgVt100PlusGuid
)) {
336 CatPrint (Str
, L
"%s", L
"VT100+");
338 } else if (CompareGuid (&Vendor
->Guid
, &mEfiMsgVt100Utf8Guid
)) {
339 CatPrint (Str
, L
"%s", L
"VT100-UTF8");
346 case MEDIA_DEVICE_PATH
:
355 CatPrint (Str
, L
"Ven%s(%g)", Type
, &Vendor
->Guid
);
360 IN OUT POOL_PRINT
*Str
,
364 ACPI_HID_DEVICE_PATH
*Acpi
;
367 if ((Acpi
->HID
& PNP_EISA_ID_MASK
) == PNP_EISA_ID_CONST
) {
368 CatPrint (Str
, L
"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi
->HID
), Acpi
->UID
);
370 CatPrint (Str
, L
"Acpi(%08x,%x)", Acpi
->HID
, Acpi
->UID
);
375 DevPathExtendedAcpi (
376 IN OUT POOL_PRINT
*Str
,
380 ACPI_EXTENDED_HID_DEVICE_PATH
*ExtendedAcpi
;
382 // Index for HID, UID and CID strings, 0 for non-exist
392 ASSERT (Str
!= NULL
);
393 ASSERT (DevPath
!= NULL
);
398 ExtendedAcpi
= DevPath
;
399 Length
= DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) ExtendedAcpi
);
401 ASSERT (Length
>= 19);
402 AsChar8Array
= (CHAR8
*) ExtendedAcpi
;
408 for (Index
= Anchor
; Index
< Length
&& AsChar8Array
[Index
]; Index
++) {
411 if (Index
> Anchor
) {
418 for (Index
= Anchor
; Index
< Length
&& AsChar8Array
[Index
]; Index
++) {
421 if (Index
> Anchor
) {
428 for (Index
= Anchor
; Index
< Length
&& AsChar8Array
[Index
]; Index
++) {
431 if (Index
> Anchor
) {
435 if (HIDSTRIdx
== 0 && CIDSTRIdx
== 0 && ExtendedAcpi
->UID
== 0) {
436 CatPrint (Str
, L
"AcpiExp(");
437 if ((ExtendedAcpi
->HID
& PNP_EISA_ID_MASK
) == PNP_EISA_ID_CONST
) {
438 CatPrint (Str
, L
"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi
->HID
));
440 CatPrint (Str
, L
"%08x,", ExtendedAcpi
->HID
);
442 if ((ExtendedAcpi
->CID
& PNP_EISA_ID_MASK
) == PNP_EISA_ID_CONST
) {
443 CatPrint (Str
, L
"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi
->CID
));
445 CatPrint (Str
, L
"%08x,", ExtendedAcpi
->CID
);
447 if (UIDSTRIdx
!= 0) {
448 CatPrint (Str
, L
"%a)", AsChar8Array
+ UIDSTRIdx
);
450 CatPrint (Str
, L
"\"\")");
453 CatPrint (Str
, L
"AcpiEx(");
454 if ((ExtendedAcpi
->HID
& PNP_EISA_ID_MASK
) == PNP_EISA_ID_CONST
) {
455 CatPrint (Str
, L
"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi
->HID
));
457 CatPrint (Str
, L
"%08x,", ExtendedAcpi
->HID
);
459 if ((ExtendedAcpi
->CID
& PNP_EISA_ID_MASK
) == PNP_EISA_ID_CONST
) {
460 CatPrint (Str
, L
"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi
->CID
));
462 CatPrint (Str
, L
"%08x,", ExtendedAcpi
->CID
);
464 CatPrint (Str
, L
"%x,", ExtendedAcpi
->UID
);
466 if (HIDSTRIdx
!= 0) {
467 CatPrint (Str
, L
"%a,", AsChar8Array
+ HIDSTRIdx
);
469 CatPrint (Str
, L
"\"\",");
471 if (CIDSTRIdx
!= 0) {
472 CatPrint (Str
, L
"%a,", AsChar8Array
+ CIDSTRIdx
);
474 CatPrint (Str
, L
"\"\",");
476 if (UIDSTRIdx
!= 0) {
477 CatPrint (Str
, L
"%a)", AsChar8Array
+ UIDSTRIdx
);
479 CatPrint (Str
, L
"\"\")");
487 IN OUT POOL_PRINT
*Str
,
491 ACPI_ADR_DEVICE_PATH
*AcpiAdr
;
494 UINT16 AdditionalAdrCount
;
497 Length
= DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) AcpiAdr
);
498 AdditionalAdrCount
= (Length
- 8) / 4;
500 CatPrint (Str
, L
"AcpiAdr(%x", AcpiAdr
->ADR
);
501 for (Index
= 0; Index
< AdditionalAdrCount
; Index
++) {
502 CatPrint (Str
, L
",%x", *(UINT32
*) ((UINT8
*) AcpiAdr
+ 8 + Index
* 4));
504 CatPrint (Str
, L
")");
509 IN OUT POOL_PRINT
*Str
,
513 ATAPI_DEVICE_PATH
*Atapi
;
519 Atapi
->PrimarySecondary
? L
"Secondary" : L
"Primary",
520 Atapi
->SlaveMaster
? L
"Slave" : L
"Master"
526 IN OUT POOL_PRINT
*Str
,
530 SCSI_DEVICE_PATH
*Scsi
;
533 CatPrint (Str
, L
"Scsi(Pun%x,Lun%x)", Scsi
->Pun
, Scsi
->Lun
);
538 IN OUT POOL_PRINT
*Str
,
542 FIBRECHANNEL_DEVICE_PATH
*Fibre
;
545 CatPrint (Str
, L
"Fibre(Wwn%lx,Lun%x)", Fibre
->WWN
, Fibre
->Lun
);
550 IN OUT POOL_PRINT
*Str
,
554 F1394_DEVICE_PATH
*F1394
;
557 CatPrint (Str
, L
"1394(%g)", &F1394
->Guid
);
562 IN OUT POOL_PRINT
*Str
,
566 USB_DEVICE_PATH
*Usb
;
569 CatPrint (Str
, L
"Usb(%x, %x)", Usb
->ParentPortNumber
, Usb
->InterfaceNumber
);
574 IN OUT POOL_PRINT
*Str
,
578 USB_CLASS_DEVICE_PATH
*UsbClass
;
583 L
"Usb Class(%x, %x, %x, %x, %x)",
586 UsbClass
->DeviceClass
,
587 UsbClass
->DeviceSubClass
,
588 UsbClass
->DeviceProtocol
594 IN OUT POOL_PRINT
*Str
,
598 I2O_DEVICE_PATH
*I2O
;
601 CatPrint (Str
, L
"I2O(%x)", I2O
->Tid
);
606 IN OUT POOL_PRINT
*Str
,
610 MAC_ADDR_DEVICE_PATH
*MAC
;
616 HwAddressSize
= sizeof (EFI_MAC_ADDRESS
);
617 if (MAC
->IfType
== 0x01 || MAC
->IfType
== 0x00) {
621 CatPrint (Str
, L
"Mac(");
623 for (Index
= 0; Index
< HwAddressSize
; Index
++) {
624 CatPrint (Str
, L
"%02x", MAC
->MacAddress
.Addr
[Index
]);
627 CatPrint (Str
, L
")");
632 IN OUT POOL_PRINT
*Str
,
636 IPv4_DEVICE_PATH
*IP
;
641 L
"IPv4(%d.%d.%d.%d:%d)",
642 IP
->RemoteIpAddress
.Addr
[0],
643 IP
->RemoteIpAddress
.Addr
[1],
644 IP
->RemoteIpAddress
.Addr
[2],
645 IP
->RemoteIpAddress
.Addr
[3],
652 IN OUT POOL_PRINT
*Str
,
656 IPv6_DEVICE_PATH
*IP
;
659 CatPrint (Str
, L
"IP-v6(not-done)");
664 IN OUT POOL_PRINT
*Str
,
668 INFINIBAND_DEVICE_PATH
*InfiniBand
;
670 InfiniBand
= DevPath
;
671 CatPrint (Str
, L
"InfiniBand(not-done)");
676 IN OUT POOL_PRINT
*Str
,
680 UART_DEVICE_PATH
*Uart
;
684 switch (Uart
->Parity
) {
714 if (Uart
->BaudRate
== 0) {
715 CatPrint (Str
, L
"Uart(DEFAULT %c", Parity
);
717 CatPrint (Str
, L
"Uart(%d %c", Uart
->BaudRate
, Parity
);
720 if (Uart
->DataBits
== 0) {
721 CatPrint (Str
, L
"D");
723 CatPrint (Str
, L
"%d", Uart
->DataBits
);
726 switch (Uart
->StopBits
) {
728 CatPrint (Str
, L
"D)");
732 CatPrint (Str
, L
"1)");
736 CatPrint (Str
, L
"1.5)");
740 CatPrint (Str
, L
"2)");
744 CatPrint (Str
, L
"x)");
751 IN OUT POOL_PRINT
*Str
,
755 HARDDRIVE_DEVICE_PATH
*Hd
;
758 switch (Hd
->SignatureType
) {
759 case SIGNATURE_TYPE_MBR
:
762 L
"HD(Part%d,Sig%08x)",
764 *((UINT32
*) (&(Hd
->Signature
[0])))
768 case SIGNATURE_TYPE_GUID
:
773 (EFI_GUID
*) &(Hd
->Signature
[0])
780 L
"HD(Part%d,MBRType=%02x,SigType=%02x)",
791 IN OUT POOL_PRINT
*Str
,
795 CDROM_DEVICE_PATH
*Cd
;
798 CatPrint (Str
, L
"CDROM(Entry%x)", Cd
->BootEntry
);
803 IN OUT POOL_PRINT
*Str
,
807 FILEPATH_DEVICE_PATH
*Fp
;
810 CatPrint (Str
, L
"%s", Fp
->PathName
);
814 DevPathMediaProtocol (
815 IN OUT POOL_PRINT
*Str
,
819 MEDIA_PROTOCOL_DEVICE_PATH
*MediaProt
;
822 CatPrint (Str
, L
"%g", &MediaProt
->Protocol
);
827 IN OUT POOL_PRINT
*Str
,
831 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FvFilePath
;
833 FvFilePath
= DevPath
;
834 CatPrint (Str
, L
"%g", &FvFilePath
->FvFileName
);
839 IN OUT POOL_PRINT
*Str
,
843 BBS_BBS_DEVICE_PATH
*Bbs
;
847 switch (Bbs
->DeviceType
) {
848 case BBS_TYPE_FLOPPY
:
852 case BBS_TYPE_HARDDRIVE
:
860 case BBS_TYPE_PCMCIA
:
868 case BBS_TYPE_EMBEDDED_NETWORK
:
877 // Since current Print function hasn't implemented %a (for ansi string)
878 // we will only print Unicode strings.
880 CatPrint (Str
, L
"Legacy-%s", Type
);
885 IN OUT POOL_PRINT
*Str
,
889 CatPrint (Str
, L
",");
894 IN OUT POOL_PRINT
*Str
,
898 CatPrint (Str
, L
"?");
901 DEVICE_PATH_STRING_TABLE DevPathTable
[] = {
902 HARDWARE_DEVICE_PATH
,
905 HARDWARE_DEVICE_PATH
,
908 HARDWARE_DEVICE_PATH
,
911 HARDWARE_DEVICE_PATH
,
914 HARDWARE_DEVICE_PATH
,
926 MESSAGING_DEVICE_PATH
,
929 MESSAGING_DEVICE_PATH
,
932 MESSAGING_DEVICE_PATH
,
935 MESSAGING_DEVICE_PATH
,
938 MESSAGING_DEVICE_PATH
,
941 MESSAGING_DEVICE_PATH
,
944 MESSAGING_DEVICE_PATH
,
947 MESSAGING_DEVICE_PATH
,
950 MESSAGING_DEVICE_PATH
,
953 MESSAGING_DEVICE_PATH
,
956 MESSAGING_DEVICE_PATH
,
959 MESSAGING_DEVICE_PATH
,
962 MESSAGING_DEVICE_PATH
,
979 DevPathMediaProtocol
,
983 END_DEVICE_PATH_TYPE
,
984 END_INSTANCE_DEVICE_PATH_SUBTYPE
,
993 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
997 Turns the Device Path into a printable string. Allcoates
998 the string from pool. The caller must SafeFreePool the returned
1004 EFI_DEVICE_PATH_PROTOCOL
*DevPathNode
;
1005 VOID (*DumpNode
) (POOL_PRINT
*, VOID
*);
1010 ZeroMem (&Str
, sizeof (Str
));
1012 if (DevPath
== NULL
) {
1016 // Unpacked the device path
1018 DevPath
= BdsLibUnpackDevicePath (DevPath
);
1022 // Process each device path node
1024 DevPathNode
= DevPath
;
1025 while (!IsDevicePathEnd (DevPathNode
)) {
1027 // Find the handler to dump this device path node
1030 for (Index
= 0; DevPathTable
[Index
].Function
; Index
+= 1) {
1032 if (DevicePathType (DevPathNode
) == DevPathTable
[Index
].Type
&&
1033 DevicePathSubType (DevPathNode
) == DevPathTable
[Index
].SubType
1035 DumpNode
= DevPathTable
[Index
].Function
;
1040 // If not found, use a generic function
1043 DumpNode
= DevPathNodeUnknown
;
1046 // Put a path seperator in if needed
1048 if (Str
.len
&& DumpNode
!= DevPathEndInstance
) {
1049 CatPrint (&Str
, L
"/");
1052 // Print this node of the device path
1054 DumpNode (&Str
, DevPathNode
);
1057 // Next device path node
1059 DevPathNode
= NextDevicePathNode (DevPathNode
);
1062 // Shrink pool used for string allocation
1067 NewSize
= (Str
.len
+ 1) * sizeof (CHAR16
);
1068 Str
.str
= ReallocatePool (Str
.str
, NewSize
, NewSize
);
1069 ASSERT (Str
.str
!= NULL
);
1070 Str
.str
[Str
.len
] = 0;
1074 EFI_DEVICE_PATH_PROTOCOL
*
1075 LibDuplicateDevicePathInstance (
1076 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
1080 Routine Description:
1082 Function creates a device path data structure that identically matches the
1083 device path passed in.
1087 DevPath - A pointer to a device path data structure.
1091 The new copy of DevPath is created to identically match the input.
1092 Otherwise, NULL is returned.
1096 EFI_DEVICE_PATH_PROTOCOL
*NewDevPath
;
1097 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
1098 EFI_DEVICE_PATH_PROTOCOL
*Temp
;
1102 // get the size of an instance from the input
1105 DevicePathInst
= GetNextDevicePathInstance (&Temp
, &Size
);
1112 NewDevPath
= AllocateZeroPool (Size
);
1113 ASSERT (NewDevPath
!= NULL
);
1117 CopyMem (NewDevPath
, DevicePathInst
, Size
);