2 This file also installs UEFI PLATFORM_DRIVER_OVERRIDE_PROTOCOL.
4 The main code offers a UI interface in device manager to let user configure
5 platform override protocol to override the default algorithm for matching
6 drivers to controllers.
9 1. It dynamicly locate all controller device path.
10 2. It dynamicly locate all drivers which support binding protocol.
11 3. It export and dynamicly update two menu to let user select the
12 mapping between drivers to controllers.
13 4. It save all the mapping info in NV variables which will be consumed
14 by platform override protocol driver to publish the platform override protocol.
16 Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
17 SPDX-License-Identifier: BSD-2-Clause-Patent
21 #include "InternalPlatDriOverrideDxe.h"
22 #include "PlatOverMngr.h"
24 #define EFI_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('C', 'l', 'b', 'k')
25 #define EFI_CALLBACK_INFO_FROM_THIS(a) CR (a, EFI_CALLBACK_INFO, ConfigAccess, EFI_CALLBACK_INFO_SIGNATURE)
29 EFI_HANDLE DriverHandle
;
30 EFI_HII_HANDLE RegisteredHandle
;
31 PLAT_OVER_MNGR_DATA FakeNvData
;
32 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
33 EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess
;
34 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL PlatformDriverOverride
;
40 /// HII specific Vendor Device Path definition.
43 VENDOR_DEVICE_PATH VendorDevicePath
;
44 EFI_DEVICE_PATH_PROTOCOL End
;
45 } HII_VENDOR_DEVICE_PATH
;
50 // uni string and Vfr Binary data.
52 extern UINT8 VfrBin
[];
53 extern UINT8 PlatDriOverrideDxeStrings
[];
58 CHAR16 mVariableName
[] = L
"Data";
59 LIST_ENTRY mMappingDataBase
= INITIALIZE_LIST_HEAD_VARIABLE (mMappingDataBase
);
60 BOOLEAN mEnvironmentVariableRead
= FALSE
;
61 EFI_HANDLE mCallerImageHandle
= NULL
;
63 EFI_HANDLE
*mDevicePathHandleBuffer
;
64 EFI_HANDLE
*mDriverImageHandleBuffer
;
66 INTN mSelectedCtrIndex
;
67 EFI_STRING_ID
*mControllerToken
;
68 UINTN mDriverImageHandleCount
;
69 EFI_STRING_ID
*mDriverImageToken
;
70 EFI_DEVICE_PATH_PROTOCOL
**mControllerDevicePathProtocol
;
71 UINTN mSelectedDriverImageNum
;
72 UINTN mLastSavedDriverImageNum
;
74 EFI_CALLBACK_INFO
*mCallbackInfo
;
75 BOOLEAN
*mDriSelection
;
76 UINTN mMaxDeviceCount
;
78 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath
= {
84 (UINT8
)(sizeof (VENDOR_DEVICE_PATH
)),
85 (UINT8
)((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
92 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
94 (UINT8
)(END_DEVICE_PATH_LENGTH
),
95 (UINT8
)((END_DEVICE_PATH_LENGTH
) >> 8)
101 Converting a given device to an unicode string.
103 @param DevPath Given device path instance
105 @return Converted string from given device path.
106 @retval L"?" Converting failed.
110 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
115 Text
= ConvertDevicePathToText (
121 Text
= AllocateCopyPool (sizeof (L
"?"), L
"?");
122 ASSERT (Text
!= NULL
);
129 Worker function to get the driver name by ComponentName or ComponentName2 protocol
130 according to the driver binding handle.
132 @param DriverBindingHandle The Handle of DriverBinding.
133 @param ProtocolGuid The pointer to Component Name (2) protocol GUID.
134 @param VariableName The name of the RFC 4646 or ISO 639-2 language variable.
136 @retval !NULL Pointer into the image name if the image name is found,
137 @retval NULL Pointer to NULL if the image name is not found.
141 GetComponentNameWorker (
142 IN EFI_HANDLE DriverBindingHandle
,
143 IN EFI_GUID
*ProtocolGuid
,
144 IN CONST CHAR16
*VariableName
148 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
153 Status
= gBS
->OpenProtocol (
156 (VOID
*)&ComponentName
,
159 EFI_OPEN_PROTOCOL_GET_PROTOCOL
161 if (EFI_ERROR (Status
)) {
166 // Find the best matching language.
168 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Language
, NULL
);
169 BestLanguage
= GetBestLanguage (
170 ComponentName
->SupportedLanguages
,
171 (BOOLEAN
)(ProtocolGuid
== &gEfiComponentNameProtocolGuid
),
177 if (BestLanguage
!= NULL
) {
178 ComponentName
->GetDriverName (
183 FreePool (BestLanguage
);
186 if (Language
!= NULL
) {
194 Get the driver name by ComponentName or ComponentName2 protocol
195 according to the driver binding handle
197 @param DriverBindingHandle The Handle of DriverBinding.
199 @retval !NULL Pointer into the image name if the image name is found,
200 @retval NULL Pointer to NULL if the image name is not found.
205 IN EFI_HANDLE DriverBindingHandle
211 // Try RFC 4646 Component Name 2 protocol first.
213 DriverName
= GetComponentNameWorker (DriverBindingHandle
, &gEfiComponentName2ProtocolGuid
, L
"PlatformLang");
214 if (DriverName
== NULL
) {
216 // If we can not get driver name from Component Name 2 protocol, we can try ISO 639-2 Component Name protocol.
218 DriverName
= GetComponentNameWorker (DriverBindingHandle
, &gEfiComponentNameProtocolGuid
, L
"Lang");
225 Get the image name from EFI UI section.
226 Get FV protocol by its loaded image protocol to abstract EFI UI section.
228 @param Image Pointer to the loaded image protocol
230 @retval !NULL Pointer to the image name if the image name is found,
231 @retval NULL NULL if the image name is not found.
236 IN EFI_LOADED_IMAGE_PROTOCOL
*Image
240 EFI_DEVICE_PATH_PROTOCOL
*DevPathNode
;
241 EFI_DEVICE_PATH_PROTOCOL
*AlignedDevPathNode
;
242 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FvFilePath
;
245 UINT32 AuthenticationStatus
;
247 EFI_FIRMWARE_VOLUME2_PROTOCOL
*Fv2
;
253 if (Image
->FilePath
== NULL
) {
257 DevPathNode
= Image
->FilePath
;
259 while (!IsDevicePathEnd (DevPathNode
)) {
261 // Make sure device path node is aligned when accessing it's FV Name Guid field.
263 AlignedDevPathNode
= AllocateCopyPool (DevicePathNodeLength (DevPathNode
), DevPathNode
);
266 // Find the Fv File path
268 NameGuid
= EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*)AlignedDevPathNode
);
269 if (NameGuid
!= NULL
) {
270 FvFilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*)AlignedDevPathNode
;
271 Status
= gBS
->HandleProtocol (
273 &gEfiFirmwareVolume2ProtocolGuid
,
277 // Locate Image EFI UI section to get the image name.
279 if (!EFI_ERROR (Status
)) {
280 Status
= Fv2
->ReadSection (
282 &FvFilePath
->FvFileName
,
283 EFI_SECTION_USER_INTERFACE
,
287 &AuthenticationStatus
289 if (!EFI_ERROR (Status
)) {
290 FreePool (AlignedDevPathNode
);
298 FreePool (AlignedDevPathNode
);
301 // Next device path node
303 DevPathNode
= NextDevicePathNode (DevPathNode
);
310 Prepare the first page to let user select the device controller which need to
311 add mapping drivers if user select 'Refresh' in first page.
312 During first page, user will see all currnet controller device path in system,
313 select any device path will go to second page to select its overrides drivers.
315 @param Private Pointer to EFI_CALLBACK_INFO.
316 @param KeyValue The callback key value of device controller item in first page.
317 @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.
319 @retval EFI_SUCCESS Always returned.
323 UpdateDeviceSelectPage (
324 IN EFI_CALLBACK_INFO
*Private
,
326 IN PLAT_OVER_MNGR_DATA
*FakeNvData
331 UINTN DevicePathHandleCount
;
334 EFI_STRING_ID NewStringToken
;
335 CHAR16
*ControllerName
;
336 EFI_DEVICE_PATH_PROTOCOL
*ControllerDevicePath
;
337 EFI_PCI_IO_PROTOCOL
*PciIo
;
338 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
*BusSpecificDriverOverride
;
340 VOID
*StartOpCodeHandle
;
341 VOID
*EndOpCodeHandle
;
342 EFI_IFR_GUID_LABEL
*StartLabel
;
343 EFI_IFR_GUID_LABEL
*EndLabel
;
346 // Set current page form ID.
348 mCurrentPage
= FORM_ID_DEVICE
;
351 // Initial the mapping database in memory
353 FreeMappingDatabase (&mMappingDataBase
);
354 InitOverridesMapping (&mMappingDataBase
);
357 // Init OpCode Handle
359 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
360 ASSERT (StartOpCodeHandle
!= NULL
);
362 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
363 ASSERT (EndOpCodeHandle
!= NULL
);
366 // Create Hii Extend Label OpCode as the start opcode
368 StartLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
369 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
370 StartLabel
->Number
= FORM_ID_DEVICE
;
373 // Create Hii Extend Label OpCode as the end opcode
375 EndLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
376 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
377 EndLabel
->Number
= LABEL_END
;
380 // Clear first page form
383 Private
->RegisteredHandle
,
384 &gPlatformOverridesManagerGuid
,
386 StartOpCodeHandle
, // Label FORM_ID_DEVICE
387 EndOpCodeHandle
// LABEL_END
391 // When user enter the page at first time, the 'first refresh' string is given to notify user to refresh all the drivers,
392 // then the 'first refresh' string will be replaced by the 'refresh' string, and the two strings content are same after the replacement
394 NewStringToken
= STRING_TOKEN (STR_FIRST_REFRESH
);
395 NewString
= HiiGetString (Private
->RegisteredHandle
, STRING_TOKEN (STR_REFRESH
), NULL
);
396 ASSERT (NewString
!= NULL
);
397 if (HiiSetString (Private
->RegisteredHandle
, NewStringToken
, NewString
, NULL
) == 0) {
401 FreePool (NewString
);
403 NewStringToken
= STRING_TOKEN (STR_FIRST_REFRESH_HELP
);
404 NewString
= HiiGetString (Private
->RegisteredHandle
, STRING_TOKEN (STR_REFRESH_HELP
), NULL
);
405 ASSERT (NewString
!= NULL
);
406 if (HiiSetString (Private
->RegisteredHandle
, NewStringToken
, NewString
, NULL
) == 0) {
410 FreePool (NewString
);
413 // created needed controller device item in first page
415 DevicePathHandleCount
= 0;
416 Status
= gBS
->LocateHandleBuffer (
418 &gEfiDevicePathProtocolGuid
,
420 &DevicePathHandleCount
,
421 &mDevicePathHandleBuffer
423 if (EFI_ERROR (Status
) || (DevicePathHandleCount
== 0)) {
427 mMaxDeviceCount
= DevicePathHandleCount
;
428 mControllerDevicePathProtocol
= AllocateZeroPool (DevicePathHandleCount
* sizeof (EFI_DEVICE_PATH_PROTOCOL
*));
429 ASSERT (mControllerDevicePathProtocol
!= NULL
);
430 mControllerToken
= AllocateZeroPool (DevicePathHandleCount
* sizeof (EFI_STRING_ID
));
431 ASSERT (mControllerToken
!= NULL
);
433 for (Index
= 0; Index
< DevicePathHandleCount
; Index
++) {
434 if (FakeNvData
->PciDeviceFilter
== 0x01) {
436 // Only care PCI device which contain efi driver in its option rom.
440 // Check whether it is a pci device
442 ControllerDevicePath
= NULL
;
443 Status
= gBS
->OpenProtocol (
444 mDevicePathHandleBuffer
[Index
],
445 &gEfiPciIoProtocolGuid
,
449 EFI_OPEN_PROTOCOL_GET_PROTOCOL
451 if (EFI_ERROR (Status
)) {
456 // Check whether it contain efi driver in its option rom
458 Status
= gBS
->HandleProtocol (
459 mDevicePathHandleBuffer
[Index
],
460 &gEfiBusSpecificDriverOverrideProtocolGuid
,
461 (VOID
**)&BusSpecificDriverOverride
463 if (EFI_ERROR (Status
) || (BusSpecificDriverOverride
== NULL
)) {
468 ControllerDevicePath
= NULL
;
469 Status
= gBS
->OpenProtocol (
470 mDevicePathHandleBuffer
[Index
],
471 &gEfiDevicePathProtocolGuid
,
472 (VOID
**)&ControllerDevicePath
,
475 EFI_OPEN_PROTOCOL_GET_PROTOCOL
477 ASSERT_EFI_ERROR (Status
);
479 // Save the device path protocol interface
481 mControllerDevicePathProtocol
[Index
] = ControllerDevicePath
;
484 // Get the driver name
486 ControllerName
= DevicePathToStr (ControllerDevicePath
);
489 // Export the driver name string and create item in set options page
491 Len
= StrSize (ControllerName
);
492 NewStrSize
= Len
+ StrSize (L
"--");
493 NewString
= AllocateZeroPool (NewStrSize
);
494 ASSERT (NewString
!= NULL
);
495 if (EFI_ERROR (CheckMapping (ControllerDevicePath
, NULL
, &mMappingDataBase
, NULL
, NULL
))) {
496 StrCatS (NewString
, NewStrSize
/sizeof (CHAR16
), L
"--");
498 StrCatS (NewString
, NewStrSize
/sizeof (CHAR16
), L
"**");
501 StrCatS (NewString
, NewStrSize
/sizeof (CHAR16
), ControllerName
);
503 NewStringToken
= HiiSetString (Private
->RegisteredHandle
, mControllerToken
[Index
], NewString
, NULL
);
504 ASSERT (NewStringToken
!= 0);
505 FreePool (NewString
);
507 // Save the device path string toke for next access use
509 mControllerToken
[Index
] = NewStringToken
;
511 HiiCreateGotoOpCode (
515 STRING_TOKEN (STR_GOTO_HELP_DRIVER
),
516 EFI_IFR_FLAG_CALLBACK
,
517 (UINT16
)(Index
+ KEY_VALUE_DEVICE_OFFSET
)
522 // Update first page form
525 Private
->RegisteredHandle
,
526 &gPlatformOverridesManagerGuid
,
528 StartOpCodeHandle
, // Label FORM_ID_DEVICE
529 EndOpCodeHandle
// LABEL_END
532 HiiFreeOpCodeHandle (StartOpCodeHandle
);
533 HiiFreeOpCodeHandle (EndOpCodeHandle
);
539 Get the first Driver Binding handle which has the specific image handle.
541 @param ImageHandle The Image handle
543 @return Handle to Driver binding
544 @retval NULL The parameter is not valid or the driver binding handle is not found.
548 GetDriverBindingHandleFromImageHandle (
549 IN EFI_HANDLE ImageHandle
554 UINTN DriverBindingHandleCount
;
555 EFI_HANDLE
*DriverBindingHandleBuffer
;
556 EFI_DRIVER_BINDING_PROTOCOL
*DriverBindingInterface
;
557 EFI_HANDLE DriverBindingHandle
;
559 DriverBindingHandle
= NULL
;
561 if (ImageHandle
== NULL
) {
566 // Get all drivers which support driver binding protocol
568 DriverBindingHandleCount
= 0;
569 Status
= gBS
->LocateHandleBuffer (
571 &gEfiDriverBindingProtocolGuid
,
573 &DriverBindingHandleCount
,
574 &DriverBindingHandleBuffer
576 if (EFI_ERROR (Status
) || (DriverBindingHandleCount
== 0)) {
581 // Get the first Driver Binding handle which has the specific image handle.
583 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
584 DriverBindingInterface
= NULL
;
585 Status
= gBS
->OpenProtocol (
586 DriverBindingHandleBuffer
[Index
],
587 &gEfiDriverBindingProtocolGuid
,
588 (VOID
**)&DriverBindingInterface
,
591 EFI_OPEN_PROTOCOL_GET_PROTOCOL
593 if (EFI_ERROR (Status
)) {
597 if (DriverBindingInterface
->ImageHandle
== ImageHandle
) {
598 DriverBindingHandle
= DriverBindingHandleBuffer
[Index
];
603 FreePool (DriverBindingHandleBuffer
);
604 return DriverBindingHandle
;
608 Prepare to let user select the drivers which need mapping with the device controller
609 selected in first page.
611 @param Private Pointer to EFI_CALLBACK_INFO.
612 @param KeyValue The callback key value of device controller item in first page.
613 KeyValue is larger than or equal to KEY_VALUE_DEVICE_OFFSET.
614 @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.
616 @retval EFI_SUCCESS Always returned.
620 UpdateBindingDriverSelectPage (
621 IN EFI_CALLBACK_INFO
*Private
,
623 IN PLAT_OVER_MNGR_DATA
*FakeNvData
630 EFI_STRING_ID NewStringToken
;
631 EFI_STRING_ID NewStringHelpToken
;
632 UINTN DriverImageHandleCount
;
633 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
635 BOOLEAN FreeDriverName
;
636 EFI_DEVICE_PATH_PROTOCOL
*LoadedImageDevicePath
;
637 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
*BusSpecificDriverOverride
;
638 EFI_HANDLE DriverBindingHandle
;
639 VOID
*StartOpCodeHandle
;
640 VOID
*EndOpCodeHandle
;
641 EFI_IFR_GUID_LABEL
*StartLabel
;
642 EFI_IFR_GUID_LABEL
*EndLabel
;
643 EFI_LOADED_IMAGE_PROTOCOL
**DriverImageProtocol
;
644 EFI_STRING_ID
*DriverImageFilePathToken
;
648 // If user select a controller item in the first page the following code will be run.
649 // During second page, user will see all currnet driver bind protocol driver, the driver name and its device path will be shown
651 // First acquire the list of Loaded Image Protocols, and then when want the name of the driver, look up all the Driver Binding Protocols
652 // and find the first one whose ImageHandle field matches the image handle of the Loaded Image Protocol.
653 // then use the Component Name Protocol on the same handle as the first matching Driver Binding Protocol to look up the name of the driver.
656 mCurrentPage
= FORM_ID_DRIVER
;
658 // Switch the item callback key value to its NO. in mDevicePathHandleBuffer
660 mSelectedCtrIndex
= KeyValue
- KEY_VALUE_DEVICE_OFFSET
;
661 ASSERT (mSelectedCtrIndex
>= 0 && mSelectedCtrIndex
< MAX_CHOICE_NUM
);
663 mLastSavedDriverImageNum
= 0;
666 // Init OpCode Handle
668 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
669 ASSERT (StartOpCodeHandle
!= NULL
);
671 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
672 ASSERT (EndOpCodeHandle
!= NULL
);
675 // Create Hii Extend Label OpCode as the start opcode
677 StartLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
678 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
679 StartLabel
->Number
= FORM_ID_DRIVER
;
682 // Create Hii Extend Label OpCode as the end opcode
684 EndLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
685 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
686 EndLabel
->Number
= LABEL_END
;
689 // Clear second page form
692 Private
->RegisteredHandle
,
693 &gPlatformOverridesManagerGuid
,
700 // Show all driver which support loaded image protocol in second page
702 DriverImageHandleCount
= 0;
703 Status
= gBS
->LocateHandleBuffer (
705 &gEfiLoadedImageProtocolGuid
,
707 &DriverImageHandleCount
,
708 &mDriverImageHandleBuffer
710 if (EFI_ERROR (Status
) || (DriverImageHandleCount
== 0)) {
711 return EFI_NOT_FOUND
;
714 mDriverImageToken
= AllocateZeroPool (DriverImageHandleCount
* sizeof (EFI_STRING_ID
));
715 ASSERT (mDriverImageToken
!= NULL
);
716 mDriSelection
= AllocateZeroPool (DriverImageHandleCount
* sizeof (BOOLEAN
));
717 ASSERT (mDriSelection
!= NULL
);
719 DriverImageProtocol
= AllocateZeroPool (DriverImageHandleCount
* sizeof (EFI_LOADED_IMAGE_PROTOCOL
*));
720 ASSERT (DriverImageProtocol
!= NULL
);
721 DriverImageFilePathToken
= AllocateZeroPool (DriverImageHandleCount
* sizeof (EFI_STRING_ID
));
722 ASSERT (DriverImageFilePathToken
!= NULL
);
724 mDriverImageHandleCount
= DriverImageHandleCount
;
725 for (Index
= 0; Index
< DriverImageHandleCount
; Index
++) {
727 // Step1: Get the driver image total file path for help string and the driver name.
731 // Find driver's Loaded Image protocol
735 Status
= gBS
->OpenProtocol (
736 mDriverImageHandleBuffer
[Index
],
737 &gEfiLoadedImageProtocolGuid
,
738 (VOID
**)&LoadedImage
,
741 EFI_OPEN_PROTOCOL_GET_PROTOCOL
743 if (EFI_ERROR (Status
)) {
744 mDriSelection
[Index
] = FALSE
;
748 DriverImageProtocol
[Index
] = LoadedImage
;
750 // Find its related driver binding protocol
752 DriverBindingHandle
= GetDriverBindingHandleFromImageHandle (mDriverImageHandleBuffer
[Index
]);
753 if (DriverBindingHandle
== NULL
) {
754 mDriSelection
[Index
] = FALSE
;
759 // Get the EFI Loaded Image Device Path Protocol
761 LoadedImageDevicePath
= NULL
;
762 Status
= gBS
->HandleProtocol (
763 mDriverImageHandleBuffer
[Index
],
764 &gEfiLoadedImageDevicePathProtocolGuid
,
765 (VOID
**)&LoadedImageDevicePath
767 if (LoadedImageDevicePath
== NULL
) {
768 mDriSelection
[Index
] = FALSE
;
772 if (FakeNvData
->PciDeviceFilter
== 0x01) {
774 // only care the driver which is in a Pci device option rom,
775 // and the driver's LoadedImage->DeviceHandle must point to a pci device which has efi option rom
777 if (!EFI_ERROR (Status
)) {
778 Status
= gBS
->HandleProtocol (
779 LoadedImage
->DeviceHandle
,
780 &gEfiBusSpecificDriverOverrideProtocolGuid
,
781 (VOID
**)&BusSpecificDriverOverride
783 if (EFI_ERROR (Status
) || (BusSpecificDriverOverride
== NULL
)) {
784 mDriSelection
[Index
] = FALSE
;
788 mDriSelection
[Index
] = FALSE
;
794 // For driver name, try to get its component name, if fail, get its image name,
795 // if also fail, give a default name.
797 FreeDriverName
= FALSE
;
798 DriverName
= GetComponentName (DriverBindingHandle
);
799 if (DriverName
== NULL
) {
801 // get its image name
803 DriverName
= GetImageName (LoadedImage
);
806 if (DriverName
== NULL
) {
808 // give a default name
810 DriverName
= HiiGetString (Private
->RegisteredHandle
, STRING_TOKEN (STR_DRIVER_DEFAULT_NAME
), NULL
);
811 ASSERT (DriverName
!= NULL
);
812 FreeDriverName
= TRUE
; // the DriverName string need to free pool
816 // Step2 Export the driver name string and create check box item in second page
820 // First create the driver image name
822 NewStrSize
= StrSize (DriverName
);
823 NewString
= AllocateZeroPool (NewStrSize
);
824 ASSERT (NewString
!= NULL
);
825 if (EFI_ERROR (CheckMapping (mControllerDevicePathProtocol
[mSelectedCtrIndex
], LoadedImageDevicePath
, &mMappingDataBase
, NULL
, NULL
))) {
826 mDriSelection
[Index
] = FALSE
;
828 mDriSelection
[Index
] = TRUE
;
829 mLastSavedDriverImageNum
++;
832 StrCatS (NewString
, NewStrSize
/sizeof (CHAR16
), DriverName
);
833 NewStringToken
= HiiSetString (Private
->RegisteredHandle
, mDriverImageToken
[Index
], NewString
, NULL
);
834 ASSERT (NewStringToken
!= 0);
835 mDriverImageToken
[Index
] = NewStringToken
;
836 FreePool (NewString
);
837 if (FreeDriverName
) {
838 FreePool (DriverName
);
842 // Second create the driver image device path as item help string
844 DriverName
= DevicePathToStr (LoadedImageDevicePath
);
846 NewStrSize
= StrSize (DriverName
);
847 NewString
= AllocateZeroPool (NewStrSize
);
848 ASSERT (NewString
!= NULL
);
849 StrCatS (NewString
, NewStrSize
/sizeof (CHAR16
), DriverName
);
850 NewStringHelpToken
= HiiSetString (Private
->RegisteredHandle
, DriverImageFilePathToken
[Index
], NewString
, NULL
);
851 ASSERT (NewStringHelpToken
!= 0);
852 DriverImageFilePathToken
[Index
] = NewStringHelpToken
;
853 FreePool (NewString
);
854 FreePool (DriverName
);
857 if (mDriSelection
[Index
]) {
858 CheckFlags
|= EFI_IFR_CHECKBOX_DEFAULT
;
861 HiiCreateCheckBoxOpCode (
863 (UINT16
)(KEY_VALUE_DRIVER_OFFSET
+ Index
),
868 EFI_IFR_FLAG_CALLBACK
,
875 // Update second page form
878 Private
->RegisteredHandle
,
879 &gPlatformOverridesManagerGuid
,
881 StartOpCodeHandle
, // Label FORM_ID_DRIVER
882 EndOpCodeHandle
// LABEL_END
885 HiiFreeOpCodeHandle (StartOpCodeHandle
);
886 HiiFreeOpCodeHandle (EndOpCodeHandle
);
888 if (DriverImageProtocol
!= NULL
) {
889 FreePool (DriverImageProtocol
);
892 if (DriverImageFilePathToken
!= NULL
) {
893 FreePool (DriverImageFilePathToken
);
900 Prepare to let user select the priority order of the drivers which are
901 selected in second page.
903 @param Private Pointer to EFI_CALLBACK_INFO.
904 @param KeyValue The callback key value of device controller item in first page.
905 @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.
907 @retval EFI_SUCCESS Always returned.
911 UpdatePrioritySelectPage (
912 IN EFI_CALLBACK_INFO
*Private
,
914 IN PLAT_OVER_MNGR_DATA
*FakeNvData
918 EFI_DEVICE_PATH_PROTOCOL
*LoadedImageDevicePath
;
919 UINTN SelectedDriverImageNum
;
920 UINT32 DriverImageNO
;
925 VOID
*StartOpCodeHandle
;
926 VOID
*EndOpCodeHandle
;
927 VOID
*OptionsOpCodeHandle
;
928 EFI_IFR_GUID_LABEL
*StartLabel
;
929 EFI_IFR_GUID_LABEL
*EndLabel
;
932 // Following code will be run if user select 'order ... priority' item in second page
933 // Prepare third page. In third page, user will order the drivers priority which are selected in second page
935 mCurrentPage
= FORM_ID_ORDER
;
938 // Init OpCode Handle
940 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
941 ASSERT (StartOpCodeHandle
!= NULL
);
943 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
944 ASSERT (EndOpCodeHandle
!= NULL
);
947 // Create Hii Extend Label OpCode as the start opcode
949 StartLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
950 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
951 StartLabel
->Number
= FORM_ID_ORDER
;
954 // Create Hii Extend Label OpCode as the end opcode
956 EndLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
957 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
958 EndLabel
->Number
= LABEL_END
;
961 // Clear third page form
964 Private
->RegisteredHandle
,
965 &gPlatformOverridesManagerGuid
,
972 // Check how many drivers have been selected
974 SelectedDriverImageNum
= 0;
975 for (Index
= 0; Index
< mDriverImageHandleCount
; Index
++) {
976 if (mDriSelection
[Index
]) {
977 SelectedDriverImageNum
++;
981 mSelectedDriverImageNum
= SelectedDriverImageNum
;
982 if (SelectedDriverImageNum
== 0) {
986 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
987 ASSERT (OptionsOpCodeHandle
!= NULL
);
990 // Create order list for those selected drivers
992 SelectedDriverImageNum
= 0;
993 for (Index
= 0; Index
< mDriverImageHandleCount
; Index
++) {
994 if (mDriSelection
[Index
]) {
996 // Use the NO. in driver binding buffer as value, will use it later
998 HiiCreateOneOfOptionOpCode (
1000 mDriverImageToken
[Index
],
1002 EFI_IFR_NUMERIC_SIZE_1
,
1007 // Get the EFI Loaded Image Device Path Protocol
1009 LoadedImageDevicePath
= NULL
;
1010 gBS
->HandleProtocol (
1011 mDriverImageHandleBuffer
[Index
],
1012 &gEfiLoadedImageDevicePathProtocolGuid
,
1013 (VOID
**)&LoadedImageDevicePath
1015 ASSERT (LoadedImageDevicePath
!= NULL
);
1018 // Check the driver DriverImage's order number in mapping database
1022 mControllerDevicePathProtocol
[mSelectedCtrIndex
],
1023 LoadedImageDevicePath
,
1028 if (DriverImageNO
== 0) {
1029 DriverImageNO
= (UINT32
)mLastSavedDriverImageNum
+ 1;
1030 mLastSavedDriverImageNum
++;
1033 TempNO
[SelectedDriverImageNum
] = DriverImageNO
;
1034 OrderNO
[SelectedDriverImageNum
] = Index
+ 1;
1035 SelectedDriverImageNum
++;
1039 ASSERT (SelectedDriverImageNum
== mSelectedDriverImageNum
);
1041 // NvRamMap Must be clear firstly
1043 ZeroMem (FakeNvData
->DriOrder
, sizeof (FakeNvData
->DriOrder
));
1046 // Order the selected drivers according to the info already in mapping database
1047 // the less order number in mapping database the less order number in NvRamMap
1049 for (Index
= 0; Index
< SelectedDriverImageNum
; Index
++) {
1051 // Find the minimal order number in TempNO array, its index in TempNO is same as IfrOptionList array
1054 for (Index1
= 0; Index1
< SelectedDriverImageNum
; Index1
++) {
1055 if (TempNO
[Index1
] < TempNO
[MinNO
]) {
1061 // the IfrOptionList[MinNO].Value = the driver NO. in driver binding buffer
1063 FakeNvData
->DriOrder
[Index
] = (UINT8
)OrderNO
[MinNO
];
1064 TempNO
[MinNO
] = MAX_CHOICE_NUM
+ 1;
1068 // Create Order List OpCode
1070 HiiCreateOrderedListOpCode (
1072 (UINT16
)DRIVER_ORDER_QUESTION_ID
,
1073 VARSTORE_ID_PLAT_OVER_MNGR
,
1074 (UINT16
)DRIVER_ORDER_VAR_OFFSET
,
1075 mControllerToken
[mSelectedCtrIndex
],
1076 mControllerToken
[mSelectedCtrIndex
],
1077 EFI_IFR_FLAG_RESET_REQUIRED
,
1079 EFI_IFR_NUMERIC_SIZE_1
,
1080 (UINT8
)MAX_CHOICE_NUM
,
1081 OptionsOpCodeHandle
,
1086 // Update third page form
1089 Private
->RegisteredHandle
,
1090 &gPlatformOverridesManagerGuid
,
1092 StartOpCodeHandle
, // Label FORM_ID_ORDER
1093 EndOpCodeHandle
// LABEL_END
1096 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1097 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1098 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
1104 Save the save the mapping database to NV variable.
1106 @param Private Pointer to EFI_CALLBACK_INFO.
1107 @param KeyValue The callback key value of device controller item in first page.
1108 @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.
1110 @retval EFI_SUCCESS Always returned.
1115 IN EFI_CALLBACK_INFO
*Private
,
1117 IN PLAT_OVER_MNGR_DATA
*FakeNvData
1122 UINTN SelectedDriverImageNum
;
1123 EFI_DEVICE_PATH_PROTOCOL
*LoadedImageDevicePath
;
1126 // Following code will be run if user select 'commint changes' in third page
1127 // user enter 'Commit Changes' to save the mapping database
1129 DeleteDriverImage (mControllerDevicePathProtocol
[mSelectedCtrIndex
], NULL
, &mMappingDataBase
);
1130 for (SelectedDriverImageNum
= 0; SelectedDriverImageNum
< mSelectedDriverImageNum
; SelectedDriverImageNum
++) {
1132 // DriOrder[SelectedDriverImageNum] = the driver NO. in driver binding buffer
1134 Index
= FakeNvData
->DriOrder
[SelectedDriverImageNum
] - 1;
1137 // Get the EFI Loaded Image Device Path Protocol
1139 LoadedImageDevicePath
= NULL
;
1140 Status
= gBS
->HandleProtocol (
1141 mDriverImageHandleBuffer
[Index
],
1142 &gEfiLoadedImageDevicePathProtocolGuid
,
1143 (VOID
**)&LoadedImageDevicePath
1145 ASSERT (LoadedImageDevicePath
!= NULL
);
1148 mControllerDevicePathProtocol
[mSelectedCtrIndex
],
1149 LoadedImageDevicePath
,
1151 (UINT32
)SelectedDriverImageNum
+ 1
1155 Status
= SaveOverridesMapping (&mMappingDataBase
);
1161 This function allows a caller to extract the current configuration for one
1162 or more named elements from the target driver.
1164 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1165 @param Request A null-terminated Unicode string in <ConfigRequest> format.
1166 @param Progress On return, points to a character in the Request string.
1167 Points to the string's null terminator if request was successful.
1168 Points to the most recent '&' before the first failing name/value
1169 pair (or the beginning of the string if the failure is in the
1170 first name/value pair) if the request was not successful.
1171 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
1172 has all values filled in for the names in the Request string.
1173 String to be allocated by the called function.
1175 @retval EFI_SUCCESS The Results is filled with the requested values.
1176 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
1177 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
1178 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
1183 PlatOverMngrExtractConfig (
1184 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1185 IN CONST EFI_STRING Request
,
1186 OUT EFI_STRING
*Progress
,
1187 OUT EFI_STRING
*Results
1191 EFI_CALLBACK_INFO
*Private
;
1192 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1193 EFI_STRING ConfigRequestHdr
;
1194 EFI_STRING ConfigRequest
;
1195 BOOLEAN AllocatedRequest
;
1199 if ((Progress
== NULL
) || (Results
== NULL
)) {
1200 return EFI_INVALID_PARAMETER
;
1203 *Progress
= Request
;
1204 if ((Request
!= NULL
) && !HiiIsConfigHdrMatch (Request
, &gPlatformOverridesManagerGuid
, mVariableName
)) {
1205 return EFI_NOT_FOUND
;
1208 ConfigRequestHdr
= NULL
;
1209 ConfigRequest
= NULL
;
1211 AllocatedRequest
= FALSE
;
1213 Private
= EFI_CALLBACK_INFO_FROM_THIS (This
);
1214 HiiConfigRouting
= Private
->HiiConfigRouting
;
1215 ConfigRequest
= Request
;
1216 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
1218 // Request has no request element, construct full request string.
1219 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1220 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
1222 ConfigRequestHdr
= HiiConstructConfigHdr (&gPlatformOverridesManagerGuid
, mVariableName
, Private
->DriverHandle
);
1223 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
1224 ConfigRequest
= AllocateZeroPool (Size
);
1225 ASSERT (ConfigRequest
!= NULL
);
1226 AllocatedRequest
= TRUE
;
1227 BufferSize
= sizeof (PLAT_OVER_MNGR_DATA
);
1228 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
1229 FreePool (ConfigRequestHdr
);
1233 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
1235 Status
= HiiConfigRouting
->BlockToConfig (
1238 (UINT8
*)&Private
->FakeNvData
,
1239 sizeof (PLAT_OVER_MNGR_DATA
),
1245 // Free the allocated config request string.
1247 if (AllocatedRequest
) {
1248 FreePool (ConfigRequest
);
1249 ConfigRequest
= NULL
;
1253 // Set Progress string to the original request string.
1255 if (Request
== NULL
) {
1257 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
1258 *Progress
= Request
+ StrLen (Request
);
1265 This function processes the results of changes in configuration.
1267 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1268 @param Configuration A null-terminated Unicode string in <ConfigRequest> format.
1269 @param Progress A pointer to a string filled in with the offset of the most
1270 recent '&' before the first failing name/value pair (or the
1271 beginning of the string if the failure is in the first
1272 name/value pair) or the terminating NULL if all was successful.
1274 @retval EFI_SUCCESS The Results is processed successfully.
1275 @retval EFI_INVALID_PARAMETER Configuration is NULL.
1276 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
1281 PlatOverMngrRouteConfig (
1282 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1283 IN CONST EFI_STRING Configuration
,
1284 OUT EFI_STRING
*Progress
1287 EFI_CALLBACK_INFO
*Private
;
1289 PLAT_OVER_MNGR_DATA
*FakeNvData
;
1292 if ((Configuration
== NULL
) || (Progress
== NULL
)) {
1293 return EFI_INVALID_PARAMETER
;
1296 *Progress
= Configuration
;
1298 if (!HiiIsConfigHdrMatch (Configuration
, &gPlatformOverridesManagerGuid
, mVariableName
)) {
1299 return EFI_NOT_FOUND
;
1302 *Progress
= Configuration
+ StrLen (Configuration
);
1303 Private
= EFI_CALLBACK_INFO_FROM_THIS (This
);
1304 FakeNvData
= &Private
->FakeNvData
;
1305 if (!HiiGetBrowserData (&gPlatformOverridesManagerGuid
, mVariableName
, sizeof (PLAT_OVER_MNGR_DATA
), (UINT8
*)FakeNvData
)) {
1307 // FakeNvData can't be got from SetupBrowser, which doesn't need to be set.
1312 Status
= EFI_SUCCESS
;
1314 if (mCurrentPage
== FORM_ID_ORDER
) {
1315 KeyValue
= KEY_VALUE_ORDER_SAVE_AND_EXIT
;
1316 Status
= CommitChanges (Private
, KeyValue
, FakeNvData
);
1323 This is the function that is called to provide results data to the driver. This data
1324 consists of a unique key which is used to identify what data is either being passed back
1327 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1328 @param Action A null-terminated Unicode string in <ConfigRequest> format.
1329 @param KeyValue A unique Goto OpCode callback value which record user's selection.
1330 0x100 <= KeyValue <0x500 : user select a controller item in the first page;
1331 KeyValue == 0x1234 : user select 'Refresh' in first page, or user select 'Go to Previous Menu' in second page
1332 KeyValue == 0x1235 : user select 'Pci device filter' in first page
1333 KeyValue == 0x1500 : user select 'order ... priority' item in second page
1334 KeyValue == 0x1800 : user select 'commint changes' in third page
1335 KeyValue == 0x2000 : user select 'Go to Previous Menu' in third page
1336 @param Type The type of value for the question.
1337 @param Value A pointer to the data being sent to the original exporting driver.
1338 @param ActionRequest On return, points to the action requested by the callback function.
1340 @retval EFI_SUCCESS Always returned.
1345 PlatOverMngrCallback (
1346 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1347 IN EFI_BROWSER_ACTION Action
,
1348 IN EFI_QUESTION_ID KeyValue
,
1350 IN EFI_IFR_TYPE_VALUE
*Value
,
1351 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1354 EFI_CALLBACK_INFO
*Private
;
1356 EFI_STRING_ID NewStringToken
;
1358 PLAT_OVER_MNGR_DATA
*FakeNvData
;
1360 if ((Action
!= EFI_BROWSER_ACTION_CHANGING
) && (Action
!= EFI_BROWSER_ACTION_CHANGED
)) {
1362 // All other action return unsupported.
1364 return EFI_UNSUPPORTED
;
1367 Private
= EFI_CALLBACK_INFO_FROM_THIS (This
);
1368 FakeNvData
= &Private
->FakeNvData
;
1369 if (!HiiGetBrowserData (&gPlatformOverridesManagerGuid
, mVariableName
, sizeof (PLAT_OVER_MNGR_DATA
), (UINT8
*)FakeNvData
)) {
1370 return EFI_NOT_FOUND
;
1373 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
1374 if (Value
== NULL
) {
1375 return EFI_INVALID_PARAMETER
;
1378 if (KeyValue
== KEY_VALUE_DRIVER_GOTO_PREVIOUS
) {
1379 UpdateDeviceSelectPage (Private
, KeyValue
, FakeNvData
);
1381 // Update page title string
1383 NewStringToken
= STRING_TOKEN (STR_TITLE
);
1384 if (HiiSetString (Private
->RegisteredHandle
, NewStringToken
, L
"First, Select the controller by device path", NULL
) == 0) {
1389 if (((KeyValue
>= KEY_VALUE_DEVICE_OFFSET
) && (KeyValue
< KEY_VALUE_DEVICE_OFFSET
+ mMaxDeviceCount
)) || (KeyValue
== KEY_VALUE_ORDER_GOTO_PREVIOUS
)) {
1390 if (KeyValue
== KEY_VALUE_ORDER_GOTO_PREVIOUS
) {
1391 KeyValue
= (EFI_QUESTION_ID
)(mSelectedCtrIndex
+ KEY_VALUE_DEVICE_OFFSET
);
1394 UpdateBindingDriverSelectPage (Private
, KeyValue
, FakeNvData
);
1396 // Update page title string
1398 NewStringToken
= STRING_TOKEN (STR_TITLE
);
1399 if (HiiSetString (Private
->RegisteredHandle
, NewStringToken
, L
"Second, Select drivers for the previous selected controller", NULL
) == 0) {
1404 if (KeyValue
== KEY_VALUE_DRIVER_GOTO_ORDER
) {
1405 UpdatePrioritySelectPage (Private
, KeyValue
, FakeNvData
);
1407 // Update page title string
1409 NewStringToken
= STRING_TOKEN (STR_TITLE
);
1410 if (HiiSetString (Private
->RegisteredHandle
, NewStringToken
, L
"Finally, Set the priority order for the drivers and save them", NULL
) == 0) {
1415 if (KeyValue
== KEY_VALUE_DEVICE_CLEAR
) {
1417 // Deletes all environment variable(s) that contain the override mappings info
1419 FreeMappingDatabase (&mMappingDataBase
);
1420 Status
= SaveOverridesMapping (&mMappingDataBase
);
1421 UpdateDeviceSelectPage (Private
, KeyValue
, FakeNvData
);
1423 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1424 if ((KeyValue
>= KEY_VALUE_DRIVER_OFFSET
) && (KeyValue
< KEY_VALUE_DRIVER_OFFSET
+ mDriverImageHandleCount
)) {
1425 mDriSelection
[KeyValue
- KEY_VALUE_DRIVER_OFFSET
] = Value
->b
;
1428 case KEY_VALUE_DEVICE_REFRESH
:
1429 case KEY_VALUE_DEVICE_FILTER
:
1430 UpdateDeviceSelectPage (Private
, KeyValue
, FakeNvData
);
1432 // Update page title string
1434 NewStringToken
= STRING_TOKEN (STR_TITLE
);
1435 if (HiiSetString (Private
->RegisteredHandle
, NewStringToken
, L
"First, Select the controller by device path", NULL
) == 0) {
1441 case KEY_VALUE_ORDER_SAVE_AND_EXIT
:
1442 Status
= CommitChanges (Private
, KeyValue
, FakeNvData
);
1443 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1444 if (EFI_ERROR (Status
)) {
1445 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Single Override Info too large, Saving Error!", NULL
);
1446 return EFI_DEVICE_ERROR
;
1458 // Pass changed uncommitted data back to Form Browser
1460 HiiSetBrowserData (&gPlatformOverridesManagerGuid
, mVariableName
, sizeof (PLAT_OVER_MNGR_DATA
), (UINT8
*)FakeNvData
, NULL
);
1466 Retrieves the image handle of the platform override driver for a controller in the system.
1468 @param This A pointer to the
1469 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL instance.
1470 @param ControllerHandle The device handle of the controller to check if a
1471 driver override exists.
1472 @param DriverImageHandle On input, a pointer to the previous driver image
1473 handle returned by GetDriver(). On output, a
1474 pointer to the next driver image handle. Passing
1475 in a NULL, will return the first driver image
1476 handle for ControllerHandle.
1478 @retval EFI_SUCCESS The driver override for ControllerHandle was
1479 returned in DriverImageHandle.
1480 @retval EFI_NOT_FOUND A driver override for ControllerHandle was not
1482 @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is NULL.
1483 DriverImageHandle is not a handle that was returned
1484 on a previous call to GetDriver().
1490 IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*This
,
1491 IN EFI_HANDLE ControllerHandle
,
1492 IN OUT EFI_HANDLE
*DriverImageHandle
1498 // Check that ControllerHandle is a valid handle
1500 if (ControllerHandle
== NULL
) {
1501 return EFI_INVALID_PARAMETER
;
1505 // Read the environment variable(s) that contain the override mappings from Controller Device Path to
1506 // a set of Driver Device Paths, and initialize in memory database of the overrides that map Controller
1507 // Device Paths to an ordered set of Driver Device Paths and Driver Handles. This action is only performed
1508 // once and finished in first call.
1510 if (!mEnvironmentVariableRead
) {
1511 mEnvironmentVariableRead
= TRUE
;
1513 Status
= InitOverridesMapping (&mMappingDataBase
);
1514 if (EFI_ERROR (Status
)) {
1515 DEBUG ((DEBUG_INFO
, "The status to Get Platform Driver Override Variable is %r\n", Status
));
1516 InitializeListHead (&mMappingDataBase
);
1517 return EFI_NOT_FOUND
;
1522 // if the environment variable does not exist, just return not found
1524 if (IsListEmpty (&mMappingDataBase
)) {
1525 return EFI_NOT_FOUND
;
1528 return GetDriverFromMapping (
1537 Retrieves the device path of the platform override driver for a controller in the system.
1538 This driver doesn't support this API.
1540 @param This A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_
1542 @param ControllerHandle The device handle of the controller to check if a driver override
1544 @param DriverImagePath On input, a pointer to the previous driver device path returned by
1545 GetDriverPath(). On output, a pointer to the next driver
1546 device path. Passing in a pointer to NULL, will return the first
1547 driver device path for ControllerHandle.
1549 @retval EFI_UNSUPPORTED
1554 IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*This
,
1555 IN EFI_HANDLE ControllerHandle
,
1556 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DriverImagePath
1559 return EFI_UNSUPPORTED
;
1563 Used to associate a driver image handle with a device path that was returned on a prior call to the
1564 GetDriverPath() service. This driver image handle will then be available through the
1565 GetDriver() service. This driver doesn't support this API.
1567 @param This A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_
1569 @param ControllerHandle The device handle of the controller.
1570 @param DriverImagePath A pointer to the driver device path that was returned in a prior
1571 call to GetDriverPath().
1572 @param DriverImageHandle The driver image handle that was returned by LoadImage()
1573 when the driver specified by DriverImagePath was loaded
1576 @retval EFI_UNSUPPORTED
1581 IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*This
,
1582 IN EFI_HANDLE ControllerHandle
,
1583 IN EFI_DEVICE_PATH_PROTOCOL
*DriverImagePath
,
1584 IN EFI_HANDLE DriverImageHandle
1587 return EFI_UNSUPPORTED
;
1591 The driver Entry Point. The function will export a disk device class formset and
1592 its callback function to hii database.
1594 @param ImageHandle The firmware allocated handle for the EFI image.
1595 @param SystemTable A pointer to the EFI System Table.
1597 @retval EFI_SUCCESS The entry point is executed successfully.
1598 @retval other Some error occurs when executing this entry point.
1603 PlatDriOverrideDxeInit (
1604 IN EFI_HANDLE ImageHandle
,
1605 IN EFI_SYSTEM_TABLE
*SystemTable
1609 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
1613 // There should only be one Form Configuration protocol
1615 Status
= gBS
->LocateProtocol (
1616 &gEfiFormBrowser2ProtocolGuid
,
1618 (VOID
**)&FormBrowser2
1620 if (EFI_ERROR (Status
)) {
1625 // According to UEFI spec, there can be at most a single instance
1626 // in the system of the EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL.
1627 // So here we check the existence.
1629 Status
= gBS
->LocateProtocol (
1630 &gEfiPlatformDriverOverrideProtocolGuid
,
1635 // If there was no error, assume there is an installation and return error
1637 if (!EFI_ERROR (Status
)) {
1638 return EFI_ALREADY_STARTED
;
1641 mCallerImageHandle
= ImageHandle
;
1642 mCallbackInfo
= AllocateZeroPool (sizeof (EFI_CALLBACK_INFO
));
1643 if (mCallbackInfo
== NULL
) {
1644 return EFI_BAD_BUFFER_SIZE
;
1647 mCallbackInfo
->Signature
= EFI_CALLBACK_INFO_SIGNATURE
;
1648 mCallbackInfo
->ConfigAccess
.ExtractConfig
= PlatOverMngrExtractConfig
;
1649 mCallbackInfo
->ConfigAccess
.RouteConfig
= PlatOverMngrRouteConfig
;
1650 mCallbackInfo
->ConfigAccess
.Callback
= PlatOverMngrCallback
;
1651 mCallbackInfo
->PlatformDriverOverride
.GetDriver
= GetDriver
;
1652 mCallbackInfo
->PlatformDriverOverride
.GetDriverPath
= GetDriverPath
;
1653 mCallbackInfo
->PlatformDriverOverride
.DriverLoaded
= DriverLoaded
;
1656 // Locate ConfigRouting protocol
1658 Status
= gBS
->LocateProtocol (
1659 &gEfiHiiConfigRoutingProtocolGuid
,
1661 (VOID
**)&mCallbackInfo
->HiiConfigRouting
1663 if (EFI_ERROR (Status
)) {
1668 // Install Device Path Protocol and Config Access protocol to driver handle
1669 // Install Platform Driver Override Protocol to driver handle
1671 Status
= gBS
->InstallMultipleProtocolInterfaces (
1672 &mCallbackInfo
->DriverHandle
,
1673 &gEfiDevicePathProtocolGuid
,
1674 &mHiiVendorDevicePath
,
1675 &gEfiHiiConfigAccessProtocolGuid
,
1676 &mCallbackInfo
->ConfigAccess
,
1677 &gEfiPlatformDriverOverrideProtocolGuid
,
1678 &mCallbackInfo
->PlatformDriverOverride
,
1681 if (EFI_ERROR (Status
)) {
1686 // Publish our HII data
1688 mCallbackInfo
->RegisteredHandle
= HiiAddPackages (
1689 &gPlatformOverridesManagerGuid
,
1690 mCallbackInfo
->DriverHandle
,
1692 PlatDriOverrideDxeStrings
,
1695 if (mCallbackInfo
->RegisteredHandle
== NULL
) {
1696 Status
= EFI_OUT_OF_RESOURCES
;
1701 // Clear all the globle variable
1703 mDriverImageHandleCount
= 0;
1709 PlatDriOverrideDxeUnload (ImageHandle
);
1715 Unload its installed protocol.
1717 @param[in] ImageHandle Handle that identifies the image to be unloaded.
1719 @retval EFI_SUCCESS The image has been unloaded.
1723 PlatDriOverrideDxeUnload (
1724 IN EFI_HANDLE ImageHandle
1727 ASSERT (mCallbackInfo
!= NULL
);
1729 if (mCallbackInfo
->DriverHandle
!= NULL
) {
1730 gBS
->UninstallMultipleProtocolInterfaces (
1731 mCallbackInfo
->DriverHandle
,
1732 &gEfiDevicePathProtocolGuid
,
1733 &mHiiVendorDevicePath
,
1734 &gEfiHiiConfigAccessProtocolGuid
,
1735 &mCallbackInfo
->ConfigAccess
,
1736 &gEfiPlatformDriverOverrideProtocolGuid
,
1737 &mCallbackInfo
->PlatformDriverOverride
,
1742 if (mCallbackInfo
->RegisteredHandle
!= NULL
) {
1743 HiiRemovePackages (mCallbackInfo
->RegisteredHandle
);
1746 FreePool (mCallbackInfo
);
1748 if (mControllerToken
!= NULL
) {
1749 FreePool (mControllerToken
);
1752 if (mControllerDevicePathProtocol
!= NULL
) {
1753 FreePool (mControllerDevicePathProtocol
);
1756 if (mDriverImageToken
!= NULL
) {
1757 FreePool (mDriverImageToken
);