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.
24 // Include common header file for this module.
26 #include "CommonHeader.h"
28 EFI_GUID mEfiWinNtThunkProtocolGuid
= EFI_WIN_NT_THUNK_PROTOCOL_GUID
;
29 EFI_GUID mEfiWinNtUgaGuid
= EFI_WIN_NT_UGA_GUID
;
30 EFI_GUID mEfiWinNtGopGuid
= EFI_WIN_NT_GOP_GUID
;
31 EFI_GUID mEfiWinNtSerialPortGuid
= EFI_WIN_NT_SERIAL_PORT_GUID
;
32 EFI_GUID mEfiMsgPcAnsiGuid
= DEVICE_PATH_MESSAGING_PC_ANSI
;
33 EFI_GUID mEfiMsgVt100Guid
= DEVICE_PATH_MESSAGING_VT_100
;
34 EFI_GUID mEfiMsgVt100PlusGuid
= DEVICE_PATH_MESSAGING_VT_100_PLUS
;
35 EFI_GUID mEfiMsgVt100Utf8Guid
= DEVICE_PATH_MESSAGING_VT_UTF8
;
47 Adjusts the size of a previously allocated buffer.
51 OldPool - A pointer to the buffer whose size is being adjusted.
53 OldSize - The size of the current buffer.
55 NewSize - The size of the new buffer.
59 EFI_SUCEESS - The requested number of bytes were allocated.
61 EFI_OUT_OF_RESOURCES - The pool requested could not be allocated.
63 EFI_INVALID_PARAMETER - The buffer was invalid.
71 NewPool
= AllocateZeroPool (NewSize
);
76 CopyMem (NewPool
, OldPool
, OldSize
< NewSize
? OldSize
: NewSize
);
87 IN OUT POOL_PRINT
*Str
,
95 Concatenates a formatted unicode string to allocated pool.
96 The caller must free the resulting buffer.
100 Str - Tracks the allocated pool, size in use, and
101 amount of pool allocated.
103 fmt - The format string
107 Allocated buffer with the formatted string printed in it.
108 The caller must free the allocated buffer. The buffer
109 allocation is not packed.
117 AppendStr
= AllocateZeroPool (0x1000);
118 if (AppendStr
== NULL
) {
122 VA_START (args
, fmt
);
123 UnicodeVSPrint (AppendStr
, 0x1000, fmt
, args
);
125 if (NULL
== Str
->str
) {
126 strsize
= StrSize (AppendStr
);
127 Str
->str
= AllocateZeroPool (strsize
);
128 ASSERT (Str
->str
!= NULL
);
130 strsize
= StrSize (AppendStr
) + StrSize (Str
->str
) - sizeof (UINT16
);
131 Str
->str
= ReallocatePool (
136 ASSERT (Str
->str
!= NULL
);
139 Str
->maxlen
= MAX_CHAR
* sizeof (UINT16
);
140 if (strsize
< Str
->maxlen
) {
141 StrCat (Str
->str
, AppendStr
);
142 Str
->len
= strsize
- sizeof (UINT16
);
145 FreePool (AppendStr
);
149 EFI_DEVICE_PATH_PROTOCOL
*
150 BdsLibUnpackDevicePath (
151 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
157 Function unpacks a device path data structure so that all the nodes
158 of a device path are naturally aligned.
162 DevPath - A pointer to a device path data structure
166 If the memory for the device path is successfully allocated, then a
167 pointer to the new device path is returned. Otherwise, NULL is returned.
171 EFI_DEVICE_PATH_PROTOCOL
*Src
;
172 EFI_DEVICE_PATH_PROTOCOL
*Dest
;
173 EFI_DEVICE_PATH_PROTOCOL
*NewPath
;
177 // Walk device path and round sizes to valid boundries
182 Size
+= DevicePathNodeLength (Src
);
183 Size
+= ALIGN_SIZE (Size
);
185 if (IsDevicePathEnd (Src
)) {
189 Src
= NextDevicePathNode (Src
);
192 // Allocate space for the unpacked path
194 NewPath
= AllocateZeroPool (Size
);
197 ASSERT (((UINTN
) NewPath
) % MIN_ALIGNMENT_SIZE
== 0);
205 Size
= DevicePathNodeLength (Src
);
206 CopyMem (Dest
, Src
, Size
);
207 Size
+= ALIGN_SIZE (Size
);
208 SetDevicePathNodeLength (Dest
, Size
);
209 Dest
->Type
|= EFI_DP_TYPE_UNPACKED
;
210 Dest
= (EFI_DEVICE_PATH_PROTOCOL
*) (((UINT8
*) Dest
) + Size
);
212 if (IsDevicePathEnd (Src
)) {
216 Src
= NextDevicePathNode (Src
);
225 IN OUT POOL_PRINT
*Str
,
229 PCI_DEVICE_PATH
*Pci
;
232 CatPrint (Str
, L
"Pci(%x|%x)", Pci
->Device
, Pci
->Function
);
237 IN OUT POOL_PRINT
*Str
,
241 PCCARD_DEVICE_PATH
*Pccard
;
244 CatPrint (Str
, L
"Pcmcia(Function%x)", Pccard
->FunctionNumber
);
249 IN OUT POOL_PRINT
*Str
,
253 MEMMAP_DEVICE_PATH
*MemMap
;
258 L
"MemMap(%d:%.lx-%.lx)",
260 MemMap
->StartingAddress
,
261 MemMap
->EndingAddress
267 IN OUT POOL_PRINT
*Str
,
271 CONTROLLER_DEVICE_PATH
*Controller
;
273 Controller
= DevPath
;
274 CatPrint (Str
, L
"Ctrl(%d)", Controller
->ControllerNumber
);
279 IN OUT POOL_PRINT
*Str
,
286 Convert Vendor device path to device name
290 Str - The buffer store device name
291 DevPath - Pointer to vendor device path
295 When it return, the device name have been stored in *Str.
299 VENDOR_DEVICE_PATH
*Vendor
;
304 Temp
= (INT32
*) (&Vendor
->Guid
);
306 switch (DevicePathType (&Vendor
->Header
)) {
307 case HARDWARE_DEVICE_PATH
:
309 // If the device is a winntbus device, we will give it a readable device name.
311 if (CompareGuid (&Vendor
->Guid
, &mEfiWinNtThunkProtocolGuid
)) {
312 CatPrint (Str
, L
"%s", L
"WinNtBus");
314 } else if (CompareGuid (&Vendor
->Guid
, &mEfiWinNtUgaGuid
)) {
315 CatPrint (Str
, L
"%s", L
"UGA");
317 } else if (CompareGuid (&Vendor
->Guid
, &mEfiWinNtGopGuid
)) {
318 CatPrint (Str
, L
"%s", L
"GOP");
320 } else if (CompareGuid (&Vendor
->Guid
, &mEfiWinNtSerialPortGuid
)) {
321 CatPrint (Str
, L
"%s", L
"Serial");
328 case MESSAGING_DEVICE_PATH
:
330 // If the device is a winntbus device, we will give it a readable device name.
332 if (CompareGuid (&Vendor
->Guid
, &mEfiMsgPcAnsiGuid
)) {
333 CatPrint (Str
, L
"%s", L
"PC-ANSI");
335 } else if (CompareGuid (&Vendor
->Guid
, &mEfiMsgVt100Guid
)) {
336 CatPrint (Str
, L
"%s", L
"VT100");
338 } else if (CompareGuid (&Vendor
->Guid
, &mEfiMsgVt100PlusGuid
)) {
339 CatPrint (Str
, L
"%s", L
"VT100+");
341 } else if (CompareGuid (&Vendor
->Guid
, &mEfiMsgVt100Utf8Guid
)) {
342 CatPrint (Str
, L
"%s", L
"VT100-UTF8");
349 case MEDIA_DEVICE_PATH
:
358 CatPrint (Str
, L
"Ven%s(%g)", Type
, &Vendor
->Guid
);
363 IN OUT POOL_PRINT
*Str
,
367 ACPI_HID_DEVICE_PATH
*Acpi
;
370 if ((Acpi
->HID
& PNP_EISA_ID_MASK
) == PNP_EISA_ID_CONST
) {
371 CatPrint (Str
, L
"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi
->HID
), Acpi
->UID
);
373 CatPrint (Str
, L
"Acpi(%08x,%x)", Acpi
->HID
, Acpi
->UID
);
378 DevPathExtendedAcpi (
379 IN OUT POOL_PRINT
*Str
,
383 ACPI_EXTENDED_HID_DEVICE_PATH
*ExtendedAcpi
;
385 // Index for HID, UID and CID strings, 0 for non-exist
395 ASSERT (Str
!= NULL
);
396 ASSERT (DevPath
!= NULL
);
401 ExtendedAcpi
= DevPath
;
402 Length
= DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) ExtendedAcpi
);
404 ASSERT (Length
>= 19);
405 AsChar8Array
= (CHAR8
*) ExtendedAcpi
;
411 for (Index
= Anchor
; Index
< Length
&& AsChar8Array
[Index
]; Index
++) {
414 if (Index
> Anchor
) {
421 for (Index
= Anchor
; Index
< Length
&& AsChar8Array
[Index
]; Index
++) {
424 if (Index
> Anchor
) {
431 for (Index
= Anchor
; Index
< Length
&& AsChar8Array
[Index
]; Index
++) {
434 if (Index
> Anchor
) {
438 if (HIDSTRIdx
== 0 && CIDSTRIdx
== 0 && ExtendedAcpi
->UID
== 0) {
439 CatPrint (Str
, L
"AcpiExp(");
440 if ((ExtendedAcpi
->HID
& PNP_EISA_ID_MASK
) == PNP_EISA_ID_CONST
) {
441 CatPrint (Str
, L
"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi
->HID
));
443 CatPrint (Str
, L
"%08x,", ExtendedAcpi
->HID
);
445 if ((ExtendedAcpi
->CID
& PNP_EISA_ID_MASK
) == PNP_EISA_ID_CONST
) {
446 CatPrint (Str
, L
"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi
->CID
));
448 CatPrint (Str
, L
"%08x,", ExtendedAcpi
->CID
);
450 if (UIDSTRIdx
!= 0) {
451 CatPrint (Str
, L
"%a)", AsChar8Array
+ UIDSTRIdx
);
453 CatPrint (Str
, L
"\"\")");
456 CatPrint (Str
, L
"AcpiEx(");
457 if ((ExtendedAcpi
->HID
& PNP_EISA_ID_MASK
) == PNP_EISA_ID_CONST
) {
458 CatPrint (Str
, L
"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi
->HID
));
460 CatPrint (Str
, L
"%08x,", ExtendedAcpi
->HID
);
462 if ((ExtendedAcpi
->CID
& PNP_EISA_ID_MASK
) == PNP_EISA_ID_CONST
) {
463 CatPrint (Str
, L
"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi
->CID
));
465 CatPrint (Str
, L
"%08x,", ExtendedAcpi
->CID
);
467 CatPrint (Str
, L
"%x,", ExtendedAcpi
->UID
);
469 if (HIDSTRIdx
!= 0) {
470 CatPrint (Str
, L
"%a,", AsChar8Array
+ HIDSTRIdx
);
472 CatPrint (Str
, L
"\"\",");
474 if (CIDSTRIdx
!= 0) {
475 CatPrint (Str
, L
"%a,", AsChar8Array
+ CIDSTRIdx
);
477 CatPrint (Str
, L
"\"\",");
479 if (UIDSTRIdx
!= 0) {
480 CatPrint (Str
, L
"%a)", AsChar8Array
+ UIDSTRIdx
);
482 CatPrint (Str
, L
"\"\")");
490 IN OUT POOL_PRINT
*Str
,
494 ACPI_ADR_DEVICE_PATH
*AcpiAdr
;
497 UINT16 AdditionalAdrCount
;
500 Length
= DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) AcpiAdr
);
501 AdditionalAdrCount
= (Length
- 8) / 4;
503 CatPrint (Str
, L
"AcpiAdr(%x", AcpiAdr
->ADR
);
504 for (Index
= 0; Index
< AdditionalAdrCount
; Index
++) {
505 CatPrint (Str
, L
",%x", *(UINT32
*) ((UINT8
*) AcpiAdr
+ 8 + Index
* 4));
507 CatPrint (Str
, L
")");
512 IN OUT POOL_PRINT
*Str
,
516 ATAPI_DEVICE_PATH
*Atapi
;
522 Atapi
->PrimarySecondary
? L
"Secondary" : L
"Primary",
523 Atapi
->SlaveMaster
? L
"Slave" : L
"Master"
529 IN OUT POOL_PRINT
*Str
,
533 SCSI_DEVICE_PATH
*Scsi
;
536 CatPrint (Str
, L
"Scsi(Pun%x,Lun%x)", Scsi
->Pun
, Scsi
->Lun
);
541 IN OUT POOL_PRINT
*Str
,
545 FIBRECHANNEL_DEVICE_PATH
*Fibre
;
548 CatPrint (Str
, L
"Fibre(Wwn%lx,Lun%x)", Fibre
->WWN
, Fibre
->Lun
);
553 IN OUT POOL_PRINT
*Str
,
557 F1394_DEVICE_PATH
*F1394
;
560 CatPrint (Str
, L
"1394(%g)", &F1394
->Guid
);
565 IN OUT POOL_PRINT
*Str
,
569 USB_DEVICE_PATH
*Usb
;
572 CatPrint (Str
, L
"Usb(%x, %x)", Usb
->ParentPortNumber
, Usb
->InterfaceNumber
);
577 IN OUT POOL_PRINT
*Str
,
581 USB_CLASS_DEVICE_PATH
*UsbClass
;
586 L
"Usb Class(%x, %x, %x, %x, %x)",
589 UsbClass
->DeviceClass
,
590 UsbClass
->DeviceSubClass
,
591 UsbClass
->DeviceProtocol
597 IN OUT POOL_PRINT
*Str
,
601 I2O_DEVICE_PATH
*I2O
;
604 CatPrint (Str
, L
"I2O(%x)", I2O
->Tid
);
609 IN OUT POOL_PRINT
*Str
,
613 MAC_ADDR_DEVICE_PATH
*MAC
;
619 HwAddressSize
= sizeof (EFI_MAC_ADDRESS
);
620 if (MAC
->IfType
== 0x01 || MAC
->IfType
== 0x00) {
624 CatPrint (Str
, L
"Mac(");
626 for (Index
= 0; Index
< HwAddressSize
; Index
++) {
627 CatPrint (Str
, L
"%02x", MAC
->MacAddress
.Addr
[Index
]);
630 CatPrint (Str
, L
")");
635 IN OUT POOL_PRINT
*Str
,
639 IPv4_DEVICE_PATH
*IP
;
644 L
"IPv4(%d.%d.%d.%d:%d)",
645 IP
->RemoteIpAddress
.Addr
[0],
646 IP
->RemoteIpAddress
.Addr
[1],
647 IP
->RemoteIpAddress
.Addr
[2],
648 IP
->RemoteIpAddress
.Addr
[3],
655 IN OUT POOL_PRINT
*Str
,
659 IPv6_DEVICE_PATH
*IP
;
662 CatPrint (Str
, L
"IP-v6(not-done)");
667 IN OUT POOL_PRINT
*Str
,
671 INFINIBAND_DEVICE_PATH
*InfiniBand
;
673 InfiniBand
= DevPath
;
674 CatPrint (Str
, L
"InfiniBand(not-done)");
679 IN OUT POOL_PRINT
*Str
,
683 UART_DEVICE_PATH
*Uart
;
687 switch (Uart
->Parity
) {
717 if (Uart
->BaudRate
== 0) {
718 CatPrint (Str
, L
"Uart(DEFAULT %c", Parity
);
720 CatPrint (Str
, L
"Uart(%d %c", Uart
->BaudRate
, Parity
);
723 if (Uart
->DataBits
== 0) {
724 CatPrint (Str
, L
"D");
726 CatPrint (Str
, L
"%d", Uart
->DataBits
);
729 switch (Uart
->StopBits
) {
731 CatPrint (Str
, L
"D)");
735 CatPrint (Str
, L
"1)");
739 CatPrint (Str
, L
"1.5)");
743 CatPrint (Str
, L
"2)");
747 CatPrint (Str
, L
"x)");
754 IN OUT POOL_PRINT
*Str
,
758 HARDDRIVE_DEVICE_PATH
*Hd
;
761 switch (Hd
->SignatureType
) {
762 case SIGNATURE_TYPE_MBR
:
765 L
"HD(Part%d,Sig%08x)",
767 *((UINT32
*) (&(Hd
->Signature
[0])))
771 case SIGNATURE_TYPE_GUID
:
776 (EFI_GUID
*) &(Hd
->Signature
[0])
783 L
"HD(Part%d,MBRType=%02x,SigType=%02x)",
794 IN OUT POOL_PRINT
*Str
,
798 CDROM_DEVICE_PATH
*Cd
;
801 CatPrint (Str
, L
"CDROM(Entry%x)", Cd
->BootEntry
);
806 IN OUT POOL_PRINT
*Str
,
810 FILEPATH_DEVICE_PATH
*Fp
;
813 CatPrint (Str
, L
"%s", Fp
->PathName
);
817 DevPathMediaProtocol (
818 IN OUT POOL_PRINT
*Str
,
822 MEDIA_PROTOCOL_DEVICE_PATH
*MediaProt
;
825 CatPrint (Str
, L
"%g", &MediaProt
->Protocol
);
830 IN OUT POOL_PRINT
*Str
,
834 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FvFilePath
;
836 FvFilePath
= DevPath
;
837 CatPrint (Str
, L
"%g", &FvFilePath
->FvFileName
);
842 IN OUT POOL_PRINT
*Str
,
846 BBS_BBS_DEVICE_PATH
*Bbs
;
850 switch (Bbs
->DeviceType
) {
851 case BBS_TYPE_FLOPPY
:
855 case BBS_TYPE_HARDDRIVE
:
863 case BBS_TYPE_PCMCIA
:
871 case BBS_TYPE_EMBEDDED_NETWORK
:
880 // Since current Print function hasn't implemented %a (for ansi string)
881 // we will only print Unicode strings.
883 CatPrint (Str
, L
"Legacy-%s", Type
);
888 IN OUT POOL_PRINT
*Str
,
892 CatPrint (Str
, L
",");
897 IN OUT POOL_PRINT
*Str
,
901 CatPrint (Str
, L
"?");
904 DEVICE_PATH_STRING_TABLE DevPathTable
[] = {
905 HARDWARE_DEVICE_PATH
,
908 HARDWARE_DEVICE_PATH
,
911 HARDWARE_DEVICE_PATH
,
914 HARDWARE_DEVICE_PATH
,
917 HARDWARE_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
,
965 MESSAGING_DEVICE_PATH
,
982 DevPathMediaProtocol
,
986 END_DEVICE_PATH_TYPE
,
987 END_INSTANCE_DEVICE_PATH_SUBTYPE
,
996 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
1000 Turns the Device Path into a printable string. Allcoates
1001 the string from pool. The caller must SafeFreePool the returned
1007 EFI_DEVICE_PATH_PROTOCOL
*DevPathNode
;
1008 VOID (*DumpNode
) (POOL_PRINT
*, VOID
*);
1013 ZeroMem (&Str
, sizeof (Str
));
1015 if (DevPath
== NULL
) {
1019 // Unpacked the device path
1021 DevPath
= BdsLibUnpackDevicePath (DevPath
);
1025 // Process each device path node
1027 DevPathNode
= DevPath
;
1028 while (!IsDevicePathEnd (DevPathNode
)) {
1030 // Find the handler to dump this device path node
1033 for (Index
= 0; DevPathTable
[Index
].Function
; Index
+= 1) {
1035 if (DevicePathType (DevPathNode
) == DevPathTable
[Index
].Type
&&
1036 DevicePathSubType (DevPathNode
) == DevPathTable
[Index
].SubType
1038 DumpNode
= DevPathTable
[Index
].Function
;
1043 // If not found, use a generic function
1046 DumpNode
= DevPathNodeUnknown
;
1049 // Put a path seperator in if needed
1051 if (Str
.len
&& DumpNode
!= DevPathEndInstance
) {
1052 CatPrint (&Str
, L
"/");
1055 // Print this node of the device path
1057 DumpNode (&Str
, DevPathNode
);
1060 // Next device path node
1062 DevPathNode
= NextDevicePathNode (DevPathNode
);
1065 // Shrink pool used for string allocation
1070 NewSize
= (Str
.len
+ 1) * sizeof (CHAR16
);
1071 Str
.str
= ReallocatePool (Str
.str
, NewSize
, NewSize
);
1072 ASSERT (Str
.str
!= NULL
);
1073 Str
.str
[Str
.len
] = 0;
1077 EFI_DEVICE_PATH_PROTOCOL
*
1078 LibDuplicateDevicePathInstance (
1079 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
1083 Routine Description:
1085 Function creates a device path data structure that identically matches the
1086 device path passed in.
1090 DevPath - A pointer to a device path data structure.
1094 The new copy of DevPath is created to identically match the input.
1095 Otherwise, NULL is returned.
1099 EFI_DEVICE_PATH_PROTOCOL
*NewDevPath
;
1100 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
1101 EFI_DEVICE_PATH_PROTOCOL
*Temp
;
1105 // get the size of an instance from the input
1108 DevicePathInst
= GetNextDevicePathInstance (&Temp
, &Size
);
1115 NewDevPath
= AllocateZeroPool (Size
);
1116 ASSERT (NewDevPath
!= NULL
);
1120 CopyMem (NewDevPath
, DevicePathInst
, Size
);