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 EFI_GUID mEfiWinNtThunkProtocolGuid
= EFI_WIN_NT_THUNK_PROTOCOL_GUID
;
24 EFI_GUID mEfiWinNtUgaGuid
= EFI_WIN_NT_UGA_GUID
;
25 EFI_GUID mEfiWinNtGopGuid
= EFI_WIN_NT_GOP_GUID
;
26 EFI_GUID mEfiWinNtSerialPortGuid
= EFI_WIN_NT_SERIAL_PORT_GUID
;
27 EFI_GUID mEfiMsgPcAnsiGuid
= DEVICE_PATH_MESSAGING_PC_ANSI
;
28 EFI_GUID mEfiMsgVt100Guid
= DEVICE_PATH_MESSAGING_VT_100
;
29 EFI_GUID mEfiMsgVt100PlusGuid
= DEVICE_PATH_MESSAGING_VT_100_PLUS
;
30 EFI_GUID mEfiMsgVt100Utf8Guid
= DEVICE_PATH_MESSAGING_VT_UTF8
;
42 Adjusts the size of a previously allocated buffer.
46 OldPool - A pointer to the buffer whose size is being adjusted.
48 OldSize - The size of the current buffer.
50 NewSize - The size of the new buffer.
54 EFI_SUCEESS - The requested number of bytes were allocated.
56 EFI_OUT_OF_RESOURCES - The pool requested could not be allocated.
58 EFI_INVALID_PARAMETER - The buffer was invalid.
66 NewPool
= AllocateZeroPool (NewSize
);
71 CopyMem (NewPool
, OldPool
, OldSize
< NewSize
? OldSize
: NewSize
);
82 IN OUT POOL_PRINT
*Str
,
90 Concatenates a formatted unicode string to allocated pool.
91 The caller must free the resulting buffer.
95 Str - Tracks the allocated pool, size in use, and
96 amount of pool allocated.
98 fmt - The format string
102 Allocated buffer with the formatted string printed in it.
103 The caller must free the allocated buffer. The buffer
104 allocation is not packed.
112 AppendStr
= AllocateZeroPool (0x1000);
113 if (AppendStr
== NULL
) {
117 VA_START (args
, fmt
);
118 UnicodeVSPrint (AppendStr
, 0x1000, fmt
, args
);
120 if (NULL
== Str
->str
) {
121 strsize
= StrSize (AppendStr
);
122 Str
->str
= AllocateZeroPool (strsize
);
123 ASSERT (Str
->str
!= NULL
);
125 strsize
= StrSize (AppendStr
) + StrSize (Str
->str
) - sizeof (UINT16
);
126 Str
->str
= ReallocatePool (
131 ASSERT (Str
->str
!= NULL
);
134 Str
->maxlen
= MAX_CHAR
* sizeof (UINT16
);
135 if (strsize
< Str
->maxlen
) {
136 StrCat (Str
->str
, AppendStr
);
137 Str
->len
= strsize
- sizeof (UINT16
);
140 FreePool (AppendStr
);
144 EFI_DEVICE_PATH_PROTOCOL
*
145 BdsLibUnpackDevicePath (
146 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
152 Function unpacks a device path data structure so that all the nodes
153 of a device path are naturally aligned.
157 DevPath - A pointer to a device path data structure
161 If the memory for the device path is successfully allocated, then a
162 pointer to the new device path is returned. Otherwise, NULL is returned.
166 EFI_DEVICE_PATH_PROTOCOL
*Src
;
167 EFI_DEVICE_PATH_PROTOCOL
*Dest
;
168 EFI_DEVICE_PATH_PROTOCOL
*NewPath
;
172 // Walk device path and round sizes to valid boundries
177 Size
+= DevicePathNodeLength (Src
);
178 Size
+= ALIGN_SIZE (Size
);
180 if (IsDevicePathEnd (Src
)) {
184 Src
= NextDevicePathNode (Src
);
187 // Allocate space for the unpacked path
189 NewPath
= AllocateZeroPool (Size
);
192 ASSERT (((UINTN
) NewPath
) % MIN_ALIGNMENT_SIZE
== 0);
200 Size
= DevicePathNodeLength (Src
);
201 CopyMem (Dest
, Src
, Size
);
202 Size
+= ALIGN_SIZE (Size
);
203 SetDevicePathNodeLength (Dest
, Size
);
204 Dest
->Type
|= EFI_DP_TYPE_UNPACKED
;
205 Dest
= (EFI_DEVICE_PATH_PROTOCOL
*) (((UINT8
*) Dest
) + Size
);
207 if (IsDevicePathEnd (Src
)) {
211 Src
= NextDevicePathNode (Src
);
220 IN OUT POOL_PRINT
*Str
,
224 PCI_DEVICE_PATH
*Pci
;
227 CatPrint (Str
, L
"Pci(%x|%x)", Pci
->Device
, Pci
->Function
);
232 IN OUT POOL_PRINT
*Str
,
236 PCCARD_DEVICE_PATH
*Pccard
;
239 CatPrint (Str
, L
"Pcmcia(Function%x)", Pccard
->FunctionNumber
);
244 IN OUT POOL_PRINT
*Str
,
248 MEMMAP_DEVICE_PATH
*MemMap
;
253 L
"MemMap(%d:%.lx-%.lx)",
255 MemMap
->StartingAddress
,
256 MemMap
->EndingAddress
262 IN OUT POOL_PRINT
*Str
,
266 CONTROLLER_DEVICE_PATH
*Controller
;
268 Controller
= DevPath
;
269 CatPrint (Str
, L
"Ctrl(%d)", Controller
->ControllerNumber
);
274 IN OUT POOL_PRINT
*Str
,
281 Convert Vendor device path to device name
285 Str - The buffer store device name
286 DevPath - Pointer to vendor device path
290 When it return, the device name have been stored in *Str.
294 VENDOR_DEVICE_PATH
*Vendor
;
299 Temp
= (INT32
*) (&Vendor
->Guid
);
301 switch (DevicePathType (&Vendor
->Header
)) {
302 case HARDWARE_DEVICE_PATH
:
304 // If the device is a winntbus device, we will give it a readable device name.
306 if (CompareGuid (&Vendor
->Guid
, &mEfiWinNtThunkProtocolGuid
)) {
307 CatPrint (Str
, L
"%s", L
"WinNtBus");
309 } else if (CompareGuid (&Vendor
->Guid
, &mEfiWinNtUgaGuid
)) {
310 CatPrint (Str
, L
"%s", L
"UGA");
312 } else if (CompareGuid (&Vendor
->Guid
, &mEfiWinNtGopGuid
)) {
313 CatPrint (Str
, L
"%s", L
"GOP");
315 } else if (CompareGuid (&Vendor
->Guid
, &mEfiWinNtSerialPortGuid
)) {
316 CatPrint (Str
, L
"%s", L
"Serial");
323 case MESSAGING_DEVICE_PATH
:
325 // If the device is a winntbus device, we will give it a readable device name.
327 if (CompareGuid (&Vendor
->Guid
, &mEfiMsgPcAnsiGuid
)) {
328 CatPrint (Str
, L
"%s", L
"PC-ANSI");
330 } else if (CompareGuid (&Vendor
->Guid
, &mEfiMsgVt100Guid
)) {
331 CatPrint (Str
, L
"%s", L
"VT100");
333 } else if (CompareGuid (&Vendor
->Guid
, &mEfiMsgVt100PlusGuid
)) {
334 CatPrint (Str
, L
"%s", L
"VT100+");
336 } else if (CompareGuid (&Vendor
->Guid
, &mEfiMsgVt100Utf8Guid
)) {
337 CatPrint (Str
, L
"%s", L
"VT100-UTF8");
344 case MEDIA_DEVICE_PATH
:
353 CatPrint (Str
, L
"Ven%s(%g)", Type
, &Vendor
->Guid
);
358 IN OUT POOL_PRINT
*Str
,
362 ACPI_HID_DEVICE_PATH
*Acpi
;
365 if ((Acpi
->HID
& PNP_EISA_ID_MASK
) == PNP_EISA_ID_CONST
) {
366 CatPrint (Str
, L
"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi
->HID
), Acpi
->UID
);
368 CatPrint (Str
, L
"Acpi(%08x,%x)", Acpi
->HID
, Acpi
->UID
);
373 DevPathExtendedAcpi (
374 IN OUT POOL_PRINT
*Str
,
378 ACPI_EXTENDED_HID_DEVICE_PATH
*ExtendedAcpi
;
380 // Index for HID, UID and CID strings, 0 for non-exist
390 ASSERT (Str
!= NULL
);
391 ASSERT (DevPath
!= NULL
);
396 ExtendedAcpi
= DevPath
;
397 Length
= DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) ExtendedAcpi
);
399 ASSERT (Length
>= 19);
400 AsChar8Array
= (CHAR8
*) ExtendedAcpi
;
406 for (Index
= Anchor
; Index
< Length
&& AsChar8Array
[Index
]; Index
++) {
409 if (Index
> Anchor
) {
416 for (Index
= Anchor
; Index
< Length
&& AsChar8Array
[Index
]; Index
++) {
419 if (Index
> Anchor
) {
426 for (Index
= Anchor
; Index
< Length
&& AsChar8Array
[Index
]; Index
++) {
429 if (Index
> Anchor
) {
433 if (HIDSTRIdx
== 0 && CIDSTRIdx
== 0 && ExtendedAcpi
->UID
== 0) {
434 CatPrint (Str
, L
"AcpiExp(");
435 if ((ExtendedAcpi
->HID
& PNP_EISA_ID_MASK
) == PNP_EISA_ID_CONST
) {
436 CatPrint (Str
, L
"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi
->HID
));
438 CatPrint (Str
, L
"%08x,", ExtendedAcpi
->HID
);
440 if ((ExtendedAcpi
->CID
& PNP_EISA_ID_MASK
) == PNP_EISA_ID_CONST
) {
441 CatPrint (Str
, L
"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi
->CID
));
443 CatPrint (Str
, L
"%08x,", ExtendedAcpi
->CID
);
445 if (UIDSTRIdx
!= 0) {
446 CatPrint (Str
, L
"%a)", AsChar8Array
+ UIDSTRIdx
);
448 CatPrint (Str
, L
"\"\")");
451 CatPrint (Str
, L
"AcpiEx(");
452 if ((ExtendedAcpi
->HID
& PNP_EISA_ID_MASK
) == PNP_EISA_ID_CONST
) {
453 CatPrint (Str
, L
"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi
->HID
));
455 CatPrint (Str
, L
"%08x,", ExtendedAcpi
->HID
);
457 if ((ExtendedAcpi
->CID
& PNP_EISA_ID_MASK
) == PNP_EISA_ID_CONST
) {
458 CatPrint (Str
, L
"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi
->CID
));
460 CatPrint (Str
, L
"%08x,", ExtendedAcpi
->CID
);
462 CatPrint (Str
, L
"%x,", ExtendedAcpi
->UID
);
464 if (HIDSTRIdx
!= 0) {
465 CatPrint (Str
, L
"%a,", AsChar8Array
+ HIDSTRIdx
);
467 CatPrint (Str
, L
"\"\",");
469 if (CIDSTRIdx
!= 0) {
470 CatPrint (Str
, L
"%a,", AsChar8Array
+ CIDSTRIdx
);
472 CatPrint (Str
, L
"\"\",");
474 if (UIDSTRIdx
!= 0) {
475 CatPrint (Str
, L
"%a)", AsChar8Array
+ UIDSTRIdx
);
477 CatPrint (Str
, L
"\"\")");
485 IN OUT POOL_PRINT
*Str
,
489 ACPI_ADR_DEVICE_PATH
*AcpiAdr
;
492 UINT16 AdditionalAdrCount
;
495 Length
= DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) AcpiAdr
);
496 AdditionalAdrCount
= (Length
- 8) / 4;
498 CatPrint (Str
, L
"AcpiAdr(%x", AcpiAdr
->ADR
);
499 for (Index
= 0; Index
< AdditionalAdrCount
; Index
++) {
500 CatPrint (Str
, L
",%x", *(UINT32
*) ((UINT8
*) AcpiAdr
+ 8 + Index
* 4));
502 CatPrint (Str
, L
")");
507 IN OUT POOL_PRINT
*Str
,
511 ATAPI_DEVICE_PATH
*Atapi
;
517 Atapi
->PrimarySecondary
? L
"Secondary" : L
"Primary",
518 Atapi
->SlaveMaster
? L
"Slave" : L
"Master"
524 IN OUT POOL_PRINT
*Str
,
528 SCSI_DEVICE_PATH
*Scsi
;
531 CatPrint (Str
, L
"Scsi(Pun%x,Lun%x)", Scsi
->Pun
, Scsi
->Lun
);
536 IN OUT POOL_PRINT
*Str
,
540 FIBRECHANNEL_DEVICE_PATH
*Fibre
;
543 CatPrint (Str
, L
"Fibre(Wwn%lx,Lun%x)", Fibre
->WWN
, Fibre
->Lun
);
548 IN OUT POOL_PRINT
*Str
,
552 F1394_DEVICE_PATH
*F1394
;
555 CatPrint (Str
, L
"1394(%g)", &F1394
->Guid
);
560 IN OUT POOL_PRINT
*Str
,
564 USB_DEVICE_PATH
*Usb
;
567 CatPrint (Str
, L
"Usb(%x, %x)", Usb
->ParentPortNumber
, Usb
->InterfaceNumber
);
572 IN OUT POOL_PRINT
*Str
,
576 USB_CLASS_DEVICE_PATH
*UsbClass
;
581 L
"Usb Class(%x, %x, %x, %x, %x)",
584 UsbClass
->DeviceClass
,
585 UsbClass
->DeviceSubClass
,
586 UsbClass
->DeviceProtocol
592 IN OUT POOL_PRINT
*Str
,
596 I2O_DEVICE_PATH
*I2O
;
599 CatPrint (Str
, L
"I2O(%x)", I2O
->Tid
);
604 IN OUT POOL_PRINT
*Str
,
608 MAC_ADDR_DEVICE_PATH
*MAC
;
614 HwAddressSize
= sizeof (EFI_MAC_ADDRESS
);
615 if (MAC
->IfType
== 0x01 || MAC
->IfType
== 0x00) {
619 CatPrint (Str
, L
"Mac(");
621 for (Index
= 0; Index
< HwAddressSize
; Index
++) {
622 CatPrint (Str
, L
"%02x", MAC
->MacAddress
.Addr
[Index
]);
625 CatPrint (Str
, L
")");
630 IN OUT POOL_PRINT
*Str
,
634 IPv4_DEVICE_PATH
*IP
;
639 L
"IPv4(%d.%d.%d.%d:%d)",
640 IP
->RemoteIpAddress
.Addr
[0],
641 IP
->RemoteIpAddress
.Addr
[1],
642 IP
->RemoteIpAddress
.Addr
[2],
643 IP
->RemoteIpAddress
.Addr
[3],
650 IN OUT POOL_PRINT
*Str
,
654 IPv6_DEVICE_PATH
*IP
;
657 CatPrint (Str
, L
"IP-v6(not-done)");
662 IN OUT POOL_PRINT
*Str
,
666 INFINIBAND_DEVICE_PATH
*InfiniBand
;
668 InfiniBand
= DevPath
;
669 CatPrint (Str
, L
"InfiniBand(not-done)");
674 IN OUT POOL_PRINT
*Str
,
678 UART_DEVICE_PATH
*Uart
;
682 switch (Uart
->Parity
) {
712 if (Uart
->BaudRate
== 0) {
713 CatPrint (Str
, L
"Uart(DEFAULT %c", Parity
);
715 CatPrint (Str
, L
"Uart(%d %c", Uart
->BaudRate
, Parity
);
718 if (Uart
->DataBits
== 0) {
719 CatPrint (Str
, L
"D");
721 CatPrint (Str
, L
"%d", Uart
->DataBits
);
724 switch (Uart
->StopBits
) {
726 CatPrint (Str
, L
"D)");
730 CatPrint (Str
, L
"1)");
734 CatPrint (Str
, L
"1.5)");
738 CatPrint (Str
, L
"2)");
742 CatPrint (Str
, L
"x)");
749 IN OUT POOL_PRINT
*Str
,
753 HARDDRIVE_DEVICE_PATH
*Hd
;
756 switch (Hd
->SignatureType
) {
757 case SIGNATURE_TYPE_MBR
:
760 L
"HD(Part%d,Sig%08x)",
762 *((UINT32
*) (&(Hd
->Signature
[0])))
766 case SIGNATURE_TYPE_GUID
:
771 (EFI_GUID
*) &(Hd
->Signature
[0])
778 L
"HD(Part%d,MBRType=%02x,SigType=%02x)",
789 IN OUT POOL_PRINT
*Str
,
793 CDROM_DEVICE_PATH
*Cd
;
796 CatPrint (Str
, L
"CDROM(Entry%x)", Cd
->BootEntry
);
801 IN OUT POOL_PRINT
*Str
,
805 FILEPATH_DEVICE_PATH
*Fp
;
808 CatPrint (Str
, L
"%s", Fp
->PathName
);
812 DevPathMediaProtocol (
813 IN OUT POOL_PRINT
*Str
,
817 MEDIA_PROTOCOL_DEVICE_PATH
*MediaProt
;
820 CatPrint (Str
, L
"%g", &MediaProt
->Protocol
);
825 IN OUT POOL_PRINT
*Str
,
829 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FvFilePath
;
831 FvFilePath
= DevPath
;
832 CatPrint (Str
, L
"%g", &FvFilePath
->NameGuid
);
837 IN OUT POOL_PRINT
*Str
,
841 BBS_BBS_DEVICE_PATH
*Bbs
;
845 switch (Bbs
->DeviceType
) {
846 case BBS_TYPE_FLOPPY
:
850 case BBS_TYPE_HARDDRIVE
:
858 case BBS_TYPE_PCMCIA
:
866 case BBS_TYPE_EMBEDDED_NETWORK
:
875 // Since current Print function hasn't implemented %a (for ansi string)
876 // we will only print Unicode strings.
878 CatPrint (Str
, L
"Legacy-%s", Type
);
883 IN OUT POOL_PRINT
*Str
,
887 CatPrint (Str
, L
",");
892 IN OUT POOL_PRINT
*Str
,
896 CatPrint (Str
, L
"?");
899 DEVICE_PATH_STRING_TABLE DevPathTable
[] = {
900 HARDWARE_DEVICE_PATH
,
903 HARDWARE_DEVICE_PATH
,
906 HARDWARE_DEVICE_PATH
,
909 HARDWARE_DEVICE_PATH
,
912 HARDWARE_DEVICE_PATH
,
924 MESSAGING_DEVICE_PATH
,
927 MESSAGING_DEVICE_PATH
,
930 MESSAGING_DEVICE_PATH
,
933 MESSAGING_DEVICE_PATH
,
936 MESSAGING_DEVICE_PATH
,
939 MESSAGING_DEVICE_PATH
,
942 MESSAGING_DEVICE_PATH
,
945 MESSAGING_DEVICE_PATH
,
948 MESSAGING_DEVICE_PATH
,
951 MESSAGING_DEVICE_PATH
,
954 MESSAGING_DEVICE_PATH
,
957 MESSAGING_DEVICE_PATH
,
960 MESSAGING_DEVICE_PATH
,
977 DevPathMediaProtocol
,
981 END_DEVICE_PATH_TYPE
,
982 END_INSTANCE_DEVICE_PATH_SUBTYPE
,
991 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
995 Turns the Device Path into a printable string. Allcoates
996 the string from pool. The caller must SafeFreePool the returned
1002 EFI_DEVICE_PATH_PROTOCOL
*DevPathNode
;
1003 VOID (*DumpNode
) (POOL_PRINT
*, VOID
*);
1008 ZeroMem (&Str
, sizeof (Str
));
1010 if (DevPath
== NULL
) {
1014 // Unpacked the device path
1016 DevPath
= BdsLibUnpackDevicePath (DevPath
);
1020 // Process each device path node
1022 DevPathNode
= DevPath
;
1023 while (!IsDevicePathEnd (DevPathNode
)) {
1025 // Find the handler to dump this device path node
1028 for (Index
= 0; DevPathTable
[Index
].Function
; Index
+= 1) {
1030 if (DevicePathType (DevPathNode
) == DevPathTable
[Index
].Type
&&
1031 DevicePathSubType (DevPathNode
) == DevPathTable
[Index
].SubType
1033 DumpNode
= DevPathTable
[Index
].Function
;
1038 // If not found, use a generic function
1041 DumpNode
= DevPathNodeUnknown
;
1044 // Put a path seperator in if needed
1046 if (Str
.len
&& DumpNode
!= DevPathEndInstance
) {
1047 CatPrint (&Str
, L
"/");
1050 // Print this node of the device path
1052 DumpNode (&Str
, DevPathNode
);
1055 // Next device path node
1057 DevPathNode
= NextDevicePathNode (DevPathNode
);
1060 // Shrink pool used for string allocation
1065 NewSize
= (Str
.len
+ 1) * sizeof (CHAR16
);
1066 Str
.str
= ReallocatePool (Str
.str
, NewSize
, NewSize
);
1067 ASSERT (Str
.str
!= NULL
);
1068 Str
.str
[Str
.len
] = 0;
1072 EFI_DEVICE_PATH_PROTOCOL
*
1073 LibDuplicateDevicePathInstance (
1074 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
1078 Routine Description:
1080 Function creates a device path data structure that identically matches the
1081 device path passed in.
1085 DevPath - A pointer to a device path data structure.
1089 The new copy of DevPath is created to identically match the input.
1090 Otherwise, NULL is returned.
1094 EFI_DEVICE_PATH_PROTOCOL
*NewDevPath
;
1095 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
1096 EFI_DEVICE_PATH_PROTOCOL
*Temp
;
1100 // get the size of an instance from the input
1103 DevicePathInst
= GetNextDevicePathInstance (&Temp
, &Size
);
1110 NewDevPath
= AllocateZeroPool (Size
);
1111 ASSERT (NewDevPath
!= NULL
);
1115 CopyMem (NewDevPath
, DevicePathInst
, Size
);