TianoCore EDK2 master
Loading...
Searching...
No Matches
ConPlatform.c
Go to the documentation of this file.
1
10#include "ConPlatform.h"
11
12EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextInDriverBinding = {
16 0xa,
17 NULL,
18 NULL
19};
20
21EFI_DRIVER_BINDING_PROTOCOL gConPlatformTextOutDriverBinding = {
25 0xa,
26 NULL,
27 NULL
28};
29
30//
31// Values from Usb Inteface Association Descriptor Device
32// Class Code and Usage Model specification (iadclasscode_r10.pdf)
33// from Usb.org
34//
35#define USB_BASE_CLASS_MISCELLANEOUS 0xEF
36#define USB_MISCELLANEOUS_SUBCLASS_COMMON 0x02
37#define USB_MISCELLANEOUS_PROTOCOL_IAD 0x01
38
52EFIAPI
54 IN EFI_HANDLE ImageHandle,
55 IN EFI_SYSTEM_TABLE *SystemTable
56 )
57{
58 EFI_STATUS Status;
59
61 ImageHandle,
62 SystemTable,
63 &gConPlatformTextInDriverBinding,
64 ImageHandle,
65 &gConPlatformComponentName,
66 &gConPlatformComponentName2
67 );
68 ASSERT_EFI_ERROR (Status);
69
71 ImageHandle,
72 SystemTable,
73 &gConPlatformTextOutDriverBinding,
74 NULL,
75 &gConPlatformComponentName,
76 &gConPlatformComponentName2
77 );
78 ASSERT_EFI_ERROR (Status);
79
80 return EFI_SUCCESS;
81}
82
96EFIAPI
99 IN EFI_HANDLE ControllerHandle,
100 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
101 )
102{
104 This,
105 ControllerHandle,
106 &gEfiSimpleTextInProtocolGuid
107 );
108}
109
123EFIAPI
126 IN EFI_HANDLE ControllerHandle,
127 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
128 )
129{
131 This,
132 ControllerHandle,
133 &gEfiSimpleTextOutProtocolGuid
134 );
135}
136
151 IN EFI_HANDLE ControllerHandle,
152 IN EFI_GUID *ProtocolGuid
153 )
154{
155 EFI_STATUS Status;
156 VOID *Interface;
157
158 //
159 // Test to see if this is a physical device by checking if
160 // it has a Device Path Protocol.
161 //
162 Status = gBS->OpenProtocol (
163 ControllerHandle,
164 &gEfiDevicePathProtocolGuid,
165 NULL,
166 This->DriverBindingHandle,
167 ControllerHandle,
168 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
169 );
170 if (EFI_ERROR (Status)) {
171 return Status;
172 }
173
174 //
175 // Test to see if this device supports the specified Protocol.
176 //
177 Status = gBS->OpenProtocol (
178 ControllerHandle,
179 ProtocolGuid,
180 (VOID **)&Interface,
181 This->DriverBindingHandle,
182 ControllerHandle,
183 EFI_OPEN_PROTOCOL_BY_DRIVER
184 );
185 if (EFI_ERROR (Status)) {
186 return Status;
187 }
188
189 gBS->CloseProtocol (
190 ControllerHandle,
191 ProtocolGuid,
192 This->DriverBindingHandle,
193 ControllerHandle
194 );
195
196 return EFI_SUCCESS;
197}
198
218EFIAPI
221 IN EFI_HANDLE ControllerHandle,
222 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
223 )
224{
225 EFI_STATUS Status;
226 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
228 BOOLEAN IsInConInVariable;
229
230 //
231 // Get the Device Path Protocol so the environment variables can be updated
232 //
233 Status = gBS->OpenProtocol (
234 ControllerHandle,
235 &gEfiDevicePathProtocolGuid,
236 (VOID **)&DevicePath,
237 This->DriverBindingHandle,
238 ControllerHandle,
239 EFI_OPEN_PROTOCOL_GET_PROTOCOL
240 );
241 if (EFI_ERROR (Status)) {
242 return Status;
243 }
244
245 //
246 // Open the Simple Text Input Protocol BY_DRIVER
247 //
248 Status = gBS->OpenProtocol (
249 ControllerHandle,
250 &gEfiSimpleTextInProtocolGuid,
251 (VOID **)&TextIn,
252 This->DriverBindingHandle,
253 ControllerHandle,
254 EFI_OPEN_PROTOCOL_BY_DRIVER
255 );
256 if (EFI_ERROR (Status)) {
257 return Status;
258 }
259
260 //
261 // Check if the device path is in ConIn Variable
262 //
263 IsInConInVariable = FALSE;
265 L"ConIn",
266 DevicePath,
267 Check
268 );
269 if (!EFI_ERROR (Status)) {
270 IsInConInVariable = TRUE;
271 }
272
273 //
274 // Append the device path to the ConInDev environment variable
275 //
277 L"ConInDev",
278 DevicePath,
279 Append
280 );
281
282 //
283 // If the device path is an instance in the ConIn environment variable,
284 // then install EfiConsoleInDeviceGuid onto ControllerHandle
285 //
286 if (IsInConInVariable) {
287 gBS->InstallMultipleProtocolInterfaces (
288 &ControllerHandle,
289 &gEfiConsoleInDeviceGuid,
290 NULL,
291 NULL
292 );
293 } else {
294 gBS->CloseProtocol (
295 ControllerHandle,
296 &gEfiSimpleTextInProtocolGuid,
297 This->DriverBindingHandle,
298 ControllerHandle
299 );
300 }
301
302 return EFI_SUCCESS;
303}
304
325EFIAPI
328 IN EFI_HANDLE ControllerHandle,
329 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
330 )
331{
332 EFI_STATUS Status;
333 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
335 BOOLEAN NeedClose;
336 BOOLEAN IsInConOutVariable;
337 BOOLEAN IsInErrOutVariable;
338
339 NeedClose = TRUE;
340
341 //
342 // Get the Device Path Protocol so the environment variables can be updated
343 //
344 Status = gBS->OpenProtocol (
345 ControllerHandle,
346 &gEfiDevicePathProtocolGuid,
347 (VOID **)&DevicePath,
348 This->DriverBindingHandle,
349 ControllerHandle,
350 EFI_OPEN_PROTOCOL_GET_PROTOCOL
351 );
352 if (EFI_ERROR (Status)) {
353 return Status;
354 }
355
356 //
357 // Open the Simple Text Output Protocol BY_DRIVER
358 //
359 Status = gBS->OpenProtocol (
360 ControllerHandle,
361 &gEfiSimpleTextOutProtocolGuid,
362 (VOID **)&TextOut,
363 This->DriverBindingHandle,
364 ControllerHandle,
365 EFI_OPEN_PROTOCOL_BY_DRIVER
366 );
367 if (EFI_ERROR (Status)) {
368 return Status;
369 }
370
371 //
372 // Check if the device path is in ConOut & ErrOut Variable
373 //
374 IsInConOutVariable = FALSE;
376 L"ConOut",
377 DevicePath,
378 Check
379 );
380 if (!EFI_ERROR (Status)) {
381 IsInConOutVariable = TRUE;
382 }
383
384 IsInErrOutVariable = FALSE;
386 L"ErrOut",
387 DevicePath,
388 Check
389 );
390 if (!EFI_ERROR (Status)) {
391 IsInErrOutVariable = TRUE;
392 }
393
394 //
395 // Append the device path to the ConOutDev and ErrOutDev environment variable.
396 // For GOP device path, append the sibling device path as well.
397 //
398 if (!ConPlatformUpdateGopCandidate (DevicePath)) {
400 L"ConOutDev",
401 DevicePath,
402 Append
403 );
404 //
405 // Then append the device path to the ErrOutDev environment variable
406 //
408 L"ErrOutDev",
409 DevicePath,
410 Append
411 );
412 }
413
414 //
415 // If the device path is an instance in the ConOut environment variable,
416 // then install EfiConsoleOutDeviceGuid onto ControllerHandle
417 //
418 if (IsInConOutVariable) {
419 NeedClose = FALSE;
420 Status = gBS->InstallMultipleProtocolInterfaces (
421 &ControllerHandle,
422 &gEfiConsoleOutDeviceGuid,
423 NULL,
424 NULL
425 );
426 }
427
428 //
429 // If the device path is an instance in the ErrOut environment variable,
430 // then install EfiStandardErrorDeviceGuid onto ControllerHandle
431 //
432 if (IsInErrOutVariable) {
433 NeedClose = FALSE;
434 gBS->InstallMultipleProtocolInterfaces (
435 &ControllerHandle,
436 &gEfiStandardErrorDeviceGuid,
437 NULL,
438 NULL
439 );
440 }
441
442 if (NeedClose) {
443 gBS->CloseProtocol (
444 ControllerHandle,
445 &gEfiSimpleTextOutProtocolGuid,
446 This->DriverBindingHandle,
447 ControllerHandle
448 );
449 }
450
451 return EFI_SUCCESS;
452}
453
469EFIAPI
472 IN EFI_HANDLE ControllerHandle,
473 IN UINTN NumberOfChildren,
474 IN EFI_HANDLE *ChildHandleBuffer
475 )
476{
477 EFI_STATUS Status;
478 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
479
480 //
481 // Get the Device Path Protocol firstly
482 //
483 Status = gBS->OpenProtocol (
484 ControllerHandle,
485 &gEfiDevicePathProtocolGuid,
486 (VOID **)&DevicePath,
487 This->DriverBindingHandle,
488 ControllerHandle,
489 EFI_OPEN_PROTOCOL_GET_PROTOCOL
490 );
491 //
492 // If there is device path on ControllerHandle
493 //
494 if (!EFI_ERROR (Status)) {
495 //
496 // Remove DevicePath from ConInDev if exists.
497 //
499 L"ConInDev",
500 DevicePath,
501 Delete
502 );
503 }
504
505 //
506 // Uninstall the Console Device GUIDs from Controller Handle
507 //
509 This,
510 ControllerHandle,
511 &gEfiConsoleInDeviceGuid
512 );
513
514 //
515 // Close the Simple Text Input Protocol
516 //
517 gBS->CloseProtocol (
518 ControllerHandle,
519 &gEfiSimpleTextInProtocolGuid,
520 This->DriverBindingHandle,
521 ControllerHandle
522 );
523
524 return EFI_SUCCESS;
525}
526
542EFIAPI
545 IN EFI_HANDLE ControllerHandle,
546 IN UINTN NumberOfChildren,
547 IN EFI_HANDLE *ChildHandleBuffer
548 )
549{
550 EFI_STATUS Status;
551 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
552
553 //
554 // Get the Device Path Protocol firstly
555 //
556 Status = gBS->OpenProtocol (
557 ControllerHandle,
558 &gEfiDevicePathProtocolGuid,
559 (VOID **)&DevicePath,
560 This->DriverBindingHandle,
561 ControllerHandle,
562 EFI_OPEN_PROTOCOL_GET_PROTOCOL
563 );
564 if (!EFI_ERROR (Status)) {
565 //
566 // Remove DevicePath from ConOutDev and ErrOutDev if exists.
567 //
569 L"ConOutDev",
570 DevicePath,
571 Delete
572 );
574 L"ErrOutDev",
575 DevicePath,
576 Delete
577 );
578 }
579
580 //
581 // Uninstall the Console Device GUIDs from Controller Handle
582 //
584 This,
585 ControllerHandle,
586 &gEfiConsoleOutDeviceGuid
587 );
588
590 This,
591 ControllerHandle,
592 &gEfiStandardErrorDeviceGuid
593 );
594
595 //
596 // Close the Simple Text Output Protocol
597 //
598 gBS->CloseProtocol (
599 ControllerHandle,
600 &gEfiSimpleTextOutProtocolGuid,
601 This->DriverBindingHandle,
602 ControllerHandle
603 );
604
605 return EFI_SUCCESS;
606}
607
616VOID
619 IN EFI_HANDLE Handle,
620 IN EFI_GUID *ProtocolGuid
621 )
622{
623 EFI_STATUS Status;
624
625 Status = gBS->OpenProtocol (
626 Handle,
627 ProtocolGuid,
628 NULL,
629 This->DriverBindingHandle,
630 Handle,
631 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
632 );
633
634 if (!EFI_ERROR (Status)) {
635 gBS->UninstallMultipleProtocolInterfaces (
636 Handle,
637 ProtocolGuid,
638 NULL,
639 NULL
640 );
641 }
642
643 return;
644}
645
660VOID *
662 IN CHAR16 *Name
663 )
664{
665 EFI_STATUS Status;
666 VOID *Buffer;
667 UINTN BufferSize;
668
669 BufferSize = 0;
670 Buffer = NULL;
671
672 //
673 // Test to see if the variable exists. If it doesn't, return NULL.
674 //
675 Status = gRT->GetVariable (
676 Name,
677 &gEfiGlobalVariableGuid,
678 NULL,
679 &BufferSize,
680 Buffer
681 );
682
683 if (Status == EFI_BUFFER_TOO_SMALL) {
684 //
685 // Allocate the buffer to return
686 //
687 Buffer = AllocatePool (BufferSize);
688 if (Buffer == NULL) {
689 return NULL;
690 }
691
692 //
693 // Read variable into the allocated buffer.
694 //
695 Status = gRT->GetVariable (
696 Name,
697 &gEfiGlobalVariableGuid,
698 NULL,
699 &BufferSize,
700 Buffer
701 );
702 if (EFI_ERROR (Status)) {
703 FreePool (Buffer);
704 //
705 // To make sure Buffer is NULL if any error occurs.
706 //
707 Buffer = NULL;
708 }
709 }
710
711 return Buffer;
712}
713
725BOOLEAN
729 )
730{
731 EFI_DEVICE_PATH_PROTOCOL *NodeLeft;
732 EFI_DEVICE_PATH_PROTOCOL *NodeRight;
733
734 for (NodeLeft = Left; !IsDevicePathEndType (NodeLeft); NodeLeft = NextDevicePathNode (NodeLeft)) {
735 if (((DevicePathType (NodeLeft) == ACPI_DEVICE_PATH) && (DevicePathSubType (NodeLeft) == ACPI_ADR_DP)) ||
736 ((DevicePathType (NodeLeft) == HARDWARE_DEVICE_PATH) && (DevicePathSubType (NodeLeft) == HW_CONTROLLER_DP) &&
738 {
739 break;
740 }
741 }
742
743 if (IsDevicePathEndType (NodeLeft)) {
744 return FALSE;
745 }
746
747 for (NodeRight = Right; !IsDevicePathEndType (NodeRight); NodeRight = NextDevicePathNode (NodeRight)) {
748 if (((DevicePathType (NodeRight) == ACPI_DEVICE_PATH) && (DevicePathSubType (NodeRight) == ACPI_ADR_DP)) ||
749 ((DevicePathType (NodeRight) == HARDWARE_DEVICE_PATH) && (DevicePathSubType (NodeRight) == HW_CONTROLLER_DP) &&
751 {
752 break;
753 }
754 }
755
756 if (IsDevicePathEndType (NodeRight)) {
757 return FALSE;
758 }
759
760 if (((UINTN)NodeLeft - (UINTN)Left) != ((UINTN)NodeRight - (UINTN)Right)) {
761 return FALSE;
762 }
763
764 return (BOOLEAN)(CompareMem (Left, Right, (UINTN)NodeLeft - (UINTN)Left) == 0);
765}
766
778BOOLEAN
780 IN EFI_USB_IO_PROTOCOL *UsbIo,
781 IN USB_CLASS_DEVICE_PATH *UsbClass
782 )
783{
784 EFI_STATUS Status;
787 UINT8 DeviceClass;
788 UINT8 DeviceSubClass;
789 UINT8 DeviceProtocol;
790
791 if ((DevicePathType (UsbClass) != MESSAGING_DEVICE_PATH) ||
792 (DevicePathSubType (UsbClass) != MSG_USB_CLASS_DP))
793 {
794 return FALSE;
795 }
796
797 //
798 // Check Vendor Id and Product Id.
799 //
800 Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc);
801 if (EFI_ERROR (Status)) {
802 return FALSE;
803 }
804
805 if ((UsbClass->VendorId != 0xffff) &&
806 (UsbClass->VendorId != DevDesc.IdVendor))
807 {
808 return FALSE;
809 }
810
811 if ((UsbClass->ProductId != 0xffff) &&
812 (UsbClass->ProductId != DevDesc.IdProduct))
813 {
814 return FALSE;
815 }
816
817 DeviceClass = DevDesc.DeviceClass;
818 DeviceSubClass = DevDesc.DeviceSubClass;
819 DeviceProtocol = DevDesc.DeviceProtocol;
820
821 if ((DeviceClass == 0) ||
822 ((DeviceClass == USB_BASE_CLASS_MISCELLANEOUS) &&
823 (DeviceSubClass == USB_MISCELLANEOUS_SUBCLASS_COMMON) &&
824 (DeviceProtocol == USB_MISCELLANEOUS_PROTOCOL_IAD)))
825 {
826 //
827 // If Class in Device Descriptor is set to 0 (Device), or
828 // Class/SubClass/Protocol is 0xEF/0x02/0x01 (IAD), use the Class, SubClass
829 // and Protocol in Interface Descriptor instead.
830 //
831 Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc);
832 if (EFI_ERROR (Status)) {
833 return FALSE;
834 }
835
836 DeviceClass = IfDesc.InterfaceClass;
837 DeviceSubClass = IfDesc.InterfaceSubClass;
838 DeviceProtocol = IfDesc.InterfaceProtocol;
839 }
840
841 //
842 // Check Class, SubClass and Protocol.
843 //
844 if ((UsbClass->DeviceClass != 0xff) &&
845 (UsbClass->DeviceClass != DeviceClass))
846 {
847 return FALSE;
848 }
849
850 if ((UsbClass->DeviceSubClass != 0xff) &&
851 (UsbClass->DeviceSubClass != DeviceSubClass))
852 {
853 return FALSE;
854 }
855
856 if ((UsbClass->DeviceProtocol != 0xff) &&
857 (UsbClass->DeviceProtocol != DeviceProtocol))
858 {
859 return FALSE;
860 }
861
862 return TRUE;
863}
864
876BOOLEAN
878 IN EFI_USB_IO_PROTOCOL *UsbIo,
879 IN USB_WWID_DEVICE_PATH *UsbWwid
880 )
881{
882 EFI_STATUS Status;
885 UINT16 *LangIdTable;
886 UINT16 TableSize;
887 UINT16 Index;
888 CHAR16 *CompareStr;
889 UINTN CompareLen;
890 CHAR16 *SerialNumberStr;
891 UINTN Length;
892
893 if ((DevicePathType (UsbWwid) != MESSAGING_DEVICE_PATH) ||
894 (DevicePathSubType (UsbWwid) != MSG_USB_WWID_DP))
895 {
896 return FALSE;
897 }
898
899 //
900 // Check Vendor Id and Product Id.
901 //
902 Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc);
903 if (EFI_ERROR (Status)) {
904 return FALSE;
905 }
906
907 if ((DevDesc.IdVendor != UsbWwid->VendorId) ||
908 (DevDesc.IdProduct != UsbWwid->ProductId))
909 {
910 return FALSE;
911 }
912
913 //
914 // Check Interface Number.
915 //
916 Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc);
917 if (EFI_ERROR (Status)) {
918 return FALSE;
919 }
920
921 if (IfDesc.InterfaceNumber != UsbWwid->InterfaceNumber) {
922 return FALSE;
923 }
924
925 //
926 // Check Serial Number.
927 //
928 if (DevDesc.StrSerialNumber == 0) {
929 return FALSE;
930 }
931
932 //
933 // Get all supported languages.
934 //
935 TableSize = 0;
936 LangIdTable = NULL;
937 Status = UsbIo->UsbGetSupportedLanguages (UsbIo, &LangIdTable, &TableSize);
938 if (EFI_ERROR (Status) || (TableSize == 0) || (LangIdTable == NULL)) {
939 return FALSE;
940 }
941
942 //
943 // Serial number in USB WWID device path is the last 64-or-less UTF-16 characters.
944 //
945 CompareStr = (CHAR16 *)(UINTN)(UsbWwid + 1);
946 CompareLen = (DevicePathNodeLength (UsbWwid) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16);
947 if (CompareStr[CompareLen - 1] == L'\0') {
948 CompareLen--;
949 }
950
951 //
952 // Compare serial number in each supported language.
953 //
954 for (Index = 0; Index < TableSize / sizeof (UINT16); Index++) {
955 SerialNumberStr = NULL;
956 Status = UsbIo->UsbGetStringDescriptor (
957 UsbIo,
958 LangIdTable[Index],
959 DevDesc.StrSerialNumber,
960 &SerialNumberStr
961 );
962 if (EFI_ERROR (Status) || (SerialNumberStr == NULL)) {
963 continue;
964 }
965
966 Length = StrLen (SerialNumberStr);
967 if ((Length >= CompareLen) &&
968 (CompareMem (SerialNumberStr + Length - CompareLen, CompareStr, CompareLen * sizeof (CHAR16)) == 0))
969 {
970 FreePool (SerialNumberStr);
971 return TRUE;
972 }
973
974 FreePool (SerialNumberStr);
975 }
976
977 return FALSE;
978}
979
989BOOLEAN
992 IN EFI_DEVICE_PATH_PROTOCOL *ShortformPath
993 )
994{
995 EFI_STATUS Status;
996 EFI_DEVICE_PATH_PROTOCOL *ShortformNode;
997 UINTN ParentDevicePathSize;
998 EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
999 EFI_USB_IO_PROTOCOL *UsbIo;
1000 EFI_HANDLE Handle;
1001
1002 for ( ShortformNode = ShortformPath
1003 ; !IsDevicePathEnd (ShortformNode)
1004 ; ShortformNode = NextDevicePathNode (ShortformNode)
1005 )
1006 {
1007 if ((DevicePathType (ShortformNode) == MESSAGING_DEVICE_PATH) &&
1008 ((DevicePathSubType (ShortformNode) == MSG_USB_CLASS_DP) ||
1009 (DevicePathSubType (ShortformNode) == MSG_USB_WWID_DP))
1010 )
1011 {
1012 break;
1013 }
1014 }
1015
1016 //
1017 // Skip further compare when it's not a shortform device path.
1018 //
1019 if (IsDevicePathEnd (ShortformNode)) {
1020 return FALSE;
1021 }
1022
1023 //
1024 // Compare the parent device path when the ShortformPath doesn't start with short-form node.
1025 //
1026 ParentDevicePathSize = (UINTN)ShortformNode - (UINTN)ShortformPath;
1027 RemainingDevicePath = FullPath;
1028 Status = gBS->LocateDevicePath (&gEfiUsbIoProtocolGuid, &RemainingDevicePath, &Handle);
1029 if (EFI_ERROR (Status)) {
1030 return FALSE;
1031 }
1032
1033 if (ParentDevicePathSize != 0) {
1034 if ((ParentDevicePathSize > (UINTN)RemainingDevicePath - (UINTN)FullPath) ||
1035 (CompareMem (FullPath, ShortformPath, ParentDevicePathSize) != 0))
1036 {
1037 return FALSE;
1038 }
1039 }
1040
1041 //
1042 // Compar the USB layer.
1043 //
1044 Status = gBS->HandleProtocol (
1045 Handle,
1046 &gEfiUsbIoProtocolGuid,
1047 (VOID **)&UsbIo
1048 );
1049 ASSERT_EFI_ERROR (Status);
1050
1051 return MatchUsbClass (UsbIo, (USB_CLASS_DEVICE_PATH *)ShortformNode) ||
1052 MatchUsbWwid (UsbIo, (USB_WWID_DEVICE_PATH *)ShortformNode);
1053}
1054
1079 OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath OPTIONAL,
1080 IN BOOLEAN Delete
1081 )
1082{
1083 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
1084 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath1;
1085 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath2;
1086 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
1087 UINTN Size;
1088
1089 //
1090 // The passed in DevicePath should not be NULL
1091 //
1092 if ((Multi == NULL) || (Single == NULL)) {
1093 return EFI_INVALID_PARAMETER;
1094 }
1095
1096 //
1097 // If performing Delete operation, the NewDevicePath must not be NULL.
1098 //
1099 if (Delete) {
1100 if (NewDevicePath == NULL) {
1101 return EFI_INVALID_PARAMETER;
1102 }
1103 }
1104
1105 TempDevicePath1 = NULL;
1106
1107 DevicePath = Multi;
1108 DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
1109
1110 //
1111 // Search for the match of 'Single' in 'Multi'
1112 //
1113 while (DevicePathInst != NULL) {
1114 if ((CompareMem (Single, DevicePathInst, Size) == 0) ||
1115 IsGopSibling (Single, DevicePathInst) || MatchUsbShortformDevicePath (Single, DevicePathInst))
1116 {
1117 if (!Delete) {
1118 //
1119 // If Delete is FALSE, return EFI_SUCCESS if Single is found in Multi.
1120 //
1121 FreePool (DevicePathInst);
1122 return EFI_SUCCESS;
1123 }
1124 } else {
1125 if (Delete) {
1126 //
1127 // If the node of Multi does not match Single, then added it back to the result.
1128 // That is, the node matching Single will be dropped and deleted from result.
1129 //
1130 TempDevicePath2 = AppendDevicePathInstance (
1131 TempDevicePath1,
1132 DevicePathInst
1133 );
1134 if (TempDevicePath1 != NULL) {
1135 FreePool (TempDevicePath1);
1136 }
1137
1138 TempDevicePath1 = TempDevicePath2;
1139 }
1140 }
1141
1142 FreePool (DevicePathInst);
1143 DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
1144 }
1145
1146 if (Delete) {
1147 //
1148 // Return the new device path data structure with specified node deleted.
1149 //
1150 *NewDevicePath = TempDevicePath1;
1151 return EFI_SUCCESS;
1152 }
1153
1154 return EFI_NOT_FOUND;
1155}
1156
1172 IN CHAR16 *VariableName,
1173 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
1174 IN CONPLATFORM_VAR_OPERATION Operation
1175 )
1176{
1177 EFI_STATUS Status;
1178 EFI_DEVICE_PATH_PROTOCOL *VariableDevicePath;
1179 EFI_DEVICE_PATH_PROTOCOL *NewVariableDevicePath;
1180
1181 VariableDevicePath = NULL;
1182 NewVariableDevicePath = NULL;
1183
1184 //
1185 // Get Variable according to variable name.
1186 // The memory for Variable is allocated within ConPlatformGetVarible(),
1187 // it is the caller's responsibility to free the memory before return.
1188 //
1189 VariableDevicePath = ConPlatformGetVariable (VariableName);
1190
1191 if (Operation != Delete) {
1192 //
1193 // Match specified DevicePath in Console Variable.
1194 //
1196 VariableDevicePath,
1197 DevicePath,
1198 NULL,
1199 FALSE
1200 );
1201
1202 if ((Operation == Check) || (!EFI_ERROR (Status))) {
1203 //
1204 // Branch here includes 2 cases:
1205 // 1. Operation is CHECK, simply return Status.
1206 // 2. Operation is APPEND, and device path already exists in variable, also return.
1207 //
1208 if (VariableDevicePath != NULL) {
1209 FreePool (VariableDevicePath);
1210 }
1211
1212 return Status;
1213 }
1214
1215 //
1216 // We reach here to append a device path that does not exist in variable.
1217 //
1218 Status = EFI_SUCCESS;
1219 NewVariableDevicePath = AppendDevicePathInstance (
1220 VariableDevicePath,
1221 DevicePath
1222 );
1223 if (NewVariableDevicePath == NULL) {
1224 Status = EFI_OUT_OF_RESOURCES;
1225 }
1226 } else {
1227 //
1228 // We reach here to remove DevicePath from the environment variable that
1229 // is a multi-instance device path.
1230 //
1232 VariableDevicePath,
1233 DevicePath,
1234 &NewVariableDevicePath,
1235 TRUE
1236 );
1237 }
1238
1239 if (VariableDevicePath != NULL) {
1240 FreePool (VariableDevicePath);
1241 }
1242
1243 if (EFI_ERROR (Status)) {
1244 return Status;
1245 }
1246
1247 if (NewVariableDevicePath != NULL) {
1248 //
1249 // Update Console Environment Variable.
1250 //
1251 Status = gRT->SetVariable (
1252 VariableName,
1253 &gEfiGlobalVariableGuid,
1254 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
1255 GetDevicePathSize (NewVariableDevicePath),
1256 NewVariableDevicePath
1257 );
1258
1259 FreePool (NewVariableDevicePath);
1260 }
1261
1262 return Status;
1263}
1264
1275BOOLEAN
1277 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
1278 )
1279{
1280 EFI_STATUS Status;
1281 EFI_HANDLE PciHandle;
1282 EFI_HANDLE GopHandle;
1283 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
1284
1285 //
1286 // Check whether it's a GOP device.
1287 //
1288 TempDevicePath = DevicePath;
1289 Status = gBS->LocateDevicePath (&gEfiGraphicsOutputProtocolGuid, &TempDevicePath, &GopHandle);
1290 if (EFI_ERROR (Status)) {
1291 return FALSE;
1292 }
1293
1294 //
1295 // Get the parent PciIo handle in order to find all the children
1296 //
1297 Status = gBS->LocateDevicePath (&gEfiPciIoProtocolGuid, &DevicePath, &PciHandle);
1298 if (EFI_ERROR (Status)) {
1299 return FALSE;
1300 }
1301
1302 TempDevicePath = EfiBootManagerGetGopDevicePath (PciHandle);
1303 if (TempDevicePath != NULL) {
1304 ConPlatformUpdateDeviceVariable (L"ConOutDev", TempDevicePath, Append);
1305 ConPlatformUpdateDeviceVariable (L"ErrOutDev", TempDevicePath, Append);
1306 }
1307
1308 return TRUE;
1309}
UINT64 UINTN
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_STATUS EFIAPI ConPlatformTextInDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: ConPlatform.c:470
BOOLEAN IsGopSibling(IN EFI_DEVICE_PATH_PROTOCOL *Left, IN EFI_DEVICE_PATH_PROTOCOL *Right)
Definition: ConPlatform.c:726
VOID * ConPlatformGetVariable(IN CHAR16 *Name)
Definition: ConPlatform.c:661
BOOLEAN MatchUsbClass(IN EFI_USB_IO_PROTOCOL *UsbIo, IN USB_CLASS_DEVICE_PATH *UsbClass)
Definition: ConPlatform.c:779
EFI_STATUS EFIAPI InitializeConPlatform(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: ConPlatform.c:53
BOOLEAN MatchUsbWwid(IN EFI_USB_IO_PROTOCOL *UsbIo, IN USB_WWID_DEVICE_PATH *UsbWwid)
Definition: ConPlatform.c:877
VOID ConPlatformUnInstallProtocol(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Handle, IN EFI_GUID *ProtocolGuid)
Definition: ConPlatform.c:617
EFI_STATUS ConPlatformMatchDevicePaths(IN EFI_DEVICE_PATH_PROTOCOL *Multi, IN EFI_DEVICE_PATH_PROTOCOL *Single, OUT EFI_DEVICE_PATH_PROTOCOL **NewDevicePath OPTIONAL, IN BOOLEAN Delete)
Definition: ConPlatform.c:1076
EFI_STATUS EFIAPI ConPlatformTextOutDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: ConPlatform.c:326
EFI_STATUS EFIAPI ConPlatformTextInDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: ConPlatform.c:219
EFI_STATUS EFIAPI ConPlatformTextInDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: ConPlatform.c:97
EFI_STATUS ConPlatformDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_GUID *ProtocolGuid)
Definition: ConPlatform.c:149
EFI_STATUS EFIAPI ConPlatformTextOutDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: ConPlatform.c:124
EFI_STATUS EFIAPI ConPlatformTextOutDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: ConPlatform.c:543
EFI_STATUS ConPlatformUpdateDeviceVariable(IN CHAR16 *VariableName, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CONPLATFORM_VAR_OPERATION Operation)
Definition: ConPlatform.c:1171
BOOLEAN ConPlatformUpdateGopCandidate(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
Definition: ConPlatform.c:1276
BOOLEAN MatchUsbShortformDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *FullPath, IN EFI_DEVICE_PATH_PROTOCOL *ShortformPath)
Definition: ConPlatform.c:990
#define HARDWARE_DEVICE_PATH
Definition: DevicePath.h:68
#define ACPI_DEVICE_PATH
Definition: DevicePath.h:190
#define MSG_USB_WWID_DP
Definition: DevicePath.h:467
#define MSG_USB_CLASS_DP
Definition: DevicePath.h:434
#define MESSAGING_DEVICE_PATH
Definition: DevicePath.h:321
#define HW_CONTROLLER_DP
Definition: DevicePath.h:154
#define ACPI_ADR_DP
Definition: DevicePath.h:264
UINT8 EFIAPI DevicePathType(IN CONST VOID *Node)
UINTN EFIAPI DevicePathNodeLength(IN CONST VOID *Node)
UINT8 EFIAPI DevicePathSubType(IN CONST VOID *Node)
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathInstance(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI GetNextDevicePathInstance(IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, OUT UINTN *Size)
UINTN EFIAPI GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
BOOLEAN EFIAPI IsDevicePathEndType(IN CONST VOID *Node)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_DEVICE_PATH_PROTOCOL *EFIAPI EfiBootManagerGetGopDevicePath(IN EFI_HANDLE VideoController)
Definition: BmConsole.c:117
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
Definition: Base.h:213