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 - 2012, Intel Corporation. All rights reserved.<BR>
17 This program and the accompanying materials
18 are licensed and made available under the terms and conditions of the BSD License
19 which accompanies this distribution. The full text of the license may be found at
20 http://opensource.org/licenses/bsd-license.php
22 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
23 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
27 #include "InternalPlatDriOverrideDxe.h"
28 #include "PlatOverMngr.h"
30 #define EFI_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('C', 'l', 'b', 'k')
31 #define EFI_CALLBACK_INFO_FROM_THIS(a) CR (a, EFI_CALLBACK_INFO, ConfigAccess, EFI_CALLBACK_INFO_SIGNATURE)
35 EFI_HANDLE DriverHandle
;
36 EFI_HII_HANDLE RegisteredHandle
;
37 PLAT_OVER_MNGR_DATA FakeNvData
;
38 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
39 EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess
;
40 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL PlatformDriverOverride
;
46 /// HII specific Vendor Device Path definition.
49 VENDOR_DEVICE_PATH VendorDevicePath
;
50 EFI_DEVICE_PATH_PROTOCOL End
;
51 } HII_VENDOR_DEVICE_PATH
;
56 // uni string and Vfr Binary data.
58 extern UINT8 VfrBin
[];
59 extern UINT8 PlatDriOverrideDxeStrings
[];
64 CHAR16 mVariableName
[] = L
"Data";
65 LIST_ENTRY mMappingDataBase
= INITIALIZE_LIST_HEAD_VARIABLE (mMappingDataBase
);
66 BOOLEAN mEnvironmentVariableRead
= FALSE
;
67 EFI_HANDLE mCallerImageHandle
= NULL
;
69 EFI_HANDLE
*mDevicePathHandleBuffer
;
70 EFI_HANDLE
*mDriverImageHandleBuffer
;
72 INTN mSelectedCtrIndex
;
73 EFI_STRING_ID mControllerToken
[MAX_CHOICE_NUM
];
74 UINTN mDriverImageHandleCount
;
75 EFI_STRING_ID mDriverImageToken
[MAX_CHOICE_NUM
];
76 EFI_STRING_ID mDriverImageFilePathToken
[MAX_CHOICE_NUM
];
77 EFI_LOADED_IMAGE_PROTOCOL
*mDriverImageProtocol
[MAX_CHOICE_NUM
];
78 EFI_DEVICE_PATH_PROTOCOL
*mControllerDevicePathProtocol
[MAX_CHOICE_NUM
];
79 UINTN mSelectedDriverImageNum
;
80 UINTN mLastSavedDriverImageNum
;
82 EFI_CALLBACK_INFO
*mCallbackInfo
;
84 HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath
= {
90 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
91 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
98 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
100 (UINT8
) (END_DEVICE_PATH_LENGTH
),
101 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
107 Converting a given device to an unicode string.
109 This function will dependent on gEfiDevicePathToTextProtocolGuid, if protocol
110 does not installed, then return unknown device path L"?" directly.
112 @param DevPath Given device path instance
114 @return Converted string from given device path.
115 @retval L"?" Can not locate gEfiDevicePathToTextProtocolGuid protocol for converting.
119 IN EFI_DEVICE_PATH_PROTOCOL
*DevPath
123 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL
*DevPathToText
;
126 if (DevPath
== NULL
) {
130 Status
= gBS
->LocateProtocol (
131 &gEfiDevicePathToTextProtocolGuid
,
133 (VOID
**) &DevPathToText
135 if (!EFI_ERROR (Status
)) {
136 ToText
= DevPathToText
->ConvertDevicePathToText (
141 ASSERT (ToText
!= NULL
);
149 Worker function to get the driver name by ComponentName or ComponentName2 protocol
150 according to the driver binding handle.
152 @param DriverBindingHandle The Handle of DriverBinding.
153 @param ProtocolGuid The pointer to Component Name (2) protocol GUID.
154 @param VariableName The name of the RFC 4646 or ISO 639-2 language variable.
156 @retval !NULL Pointer into the image name if the image name is found,
157 @retval NULL Pointer to NULL if the image name is not found.
161 GetComponentNameWorker (
162 IN EFI_HANDLE DriverBindingHandle
,
163 IN EFI_GUID
*ProtocolGuid
,
164 IN CONST CHAR16
*VariableName
168 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
173 Status
= gBS
->OpenProtocol (
176 (VOID
*) &ComponentName
,
179 EFI_OPEN_PROTOCOL_GET_PROTOCOL
181 if (EFI_ERROR (Status
)) {
186 // Find the best matching language.
188 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Language
, NULL
);
189 BestLanguage
= GetBestLanguage (
190 ComponentName
->SupportedLanguages
,
191 (BOOLEAN
) (ProtocolGuid
== &gEfiComponentNameProtocolGuid
),
197 if (BestLanguage
!= NULL
) {
198 ComponentName
->GetDriverName (
203 FreePool (BestLanguage
);
206 if (Language
!= NULL
) {
215 Get the driver name by ComponentName or ComponentName2 protocol
216 according to the driver binding handle
218 @param DriverBindingHandle The Handle of DriverBinding.
220 @retval !NULL Pointer into the image name if the image name is found,
221 @retval NULL Pointer to NULL if the image name is not found.
226 IN EFI_HANDLE DriverBindingHandle
232 // Try RFC 4646 Component Name 2 protocol first.
234 DriverName
= GetComponentNameWorker (DriverBindingHandle
, &gEfiComponentName2ProtocolGuid
, L
"PlatformLang");
235 if (DriverName
== NULL
) {
237 // If we can not get driver name from Component Name 2 protocol, we can try ISO 639-2 Component Name protocol.
239 DriverName
= GetComponentNameWorker (DriverBindingHandle
, &gEfiComponentNameProtocolGuid
, L
"Lang");
246 Get the image name from EFI UI section.
247 Get FV protocol by its loaded image protocol to abstract EFI UI section.
249 @param Image Pointer to the loaded image protocol
251 @retval !NULL Pointer to the image name if the image name is found,
252 @retval NULL NULL if the image name is not found.
257 IN EFI_LOADED_IMAGE_PROTOCOL
*Image
261 EFI_DEVICE_PATH_PROTOCOL
*DevPathNode
;
262 EFI_DEVICE_PATH_PROTOCOL
*AlignedDevPathNode
;
263 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FvFilePath
;
266 UINT32 AuthenticationStatus
;
268 EFI_FIRMWARE_VOLUME2_PROTOCOL
*Fv2
;
274 if (Image
->FilePath
== NULL
) {
277 DevPathNode
= Image
->FilePath
;
279 while (!IsDevicePathEnd (DevPathNode
)) {
281 // Make sure device path node is aligned when accessing it's FV Name Guid field.
283 AlignedDevPathNode
= AllocateCopyPool (DevicePathNodeLength(DevPathNode
), DevPathNode
);
286 // Find the Fv File path
288 NameGuid
= EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*)AlignedDevPathNode
);
289 if (NameGuid
!= NULL
) {
290 FvFilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) AlignedDevPathNode
;
291 Status
= gBS
->HandleProtocol (
293 &gEfiFirmwareVolume2ProtocolGuid
,
297 // Locate Image EFI UI section to get the image name.
299 if (!EFI_ERROR (Status
)) {
300 Status
= Fv2
->ReadSection (
302 &FvFilePath
->FvFileName
,
303 EFI_SECTION_USER_INTERFACE
,
307 &AuthenticationStatus
309 if (!EFI_ERROR (Status
)) {
310 FreePool (AlignedDevPathNode
);
317 FreePool (AlignedDevPathNode
);
320 // Next device path node
322 DevPathNode
= NextDevicePathNode (DevPathNode
);
329 Prepare the first page to let user select the device controller which need to
330 add mapping drivers if user select 'Refresh' in first page.
331 During first page, user will see all currnet controller device path in system,
332 select any device path will go to second page to select its overrides drivers.
334 @param Private Pointer to EFI_CALLBACK_INFO.
335 @param KeyValue The callback key value of device controller item in first page.
336 @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.
338 @retval EFI_SUCCESS Always returned.
342 UpdateDeviceSelectPage (
343 IN EFI_CALLBACK_INFO
*Private
,
345 IN PLAT_OVER_MNGR_DATA
*FakeNvData
350 UINTN DevicePathHandleCount
;
352 EFI_STRING_ID NewStringToken
;
353 CHAR16
*ControllerName
;
354 EFI_DEVICE_PATH_PROTOCOL
*ControllerDevicePath
;
355 EFI_PCI_IO_PROTOCOL
*PciIo
;
356 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
*BusSpecificDriverOverride
;
358 VOID
*StartOpCodeHandle
;
359 VOID
*EndOpCodeHandle
;
360 EFI_IFR_GUID_LABEL
*StartLabel
;
361 EFI_IFR_GUID_LABEL
*EndLabel
;
364 // Set current page form ID.
366 mCurrentPage
= FORM_ID_DEVICE
;
369 // Initial the mapping database in memory
371 FreeMappingDatabase (&mMappingDataBase
);
372 InitOverridesMapping (&mMappingDataBase
);
375 // Init OpCode Handle
377 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
378 ASSERT (StartOpCodeHandle
!= NULL
);
380 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
381 ASSERT (EndOpCodeHandle
!= NULL
);
384 // Create Hii Extend Label OpCode as the start opcode
386 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
387 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
388 StartLabel
->Number
= FORM_ID_DEVICE
;
391 // Create Hii Extend Label OpCode as the end opcode
393 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
394 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
395 EndLabel
->Number
= LABEL_END
;
398 // Clear first page form
401 Private
->RegisteredHandle
,
402 &gPlatformOverridesManagerGuid
,
404 StartOpCodeHandle
, // Label FORM_ID_DEVICE
405 EndOpCodeHandle
// LABEL_END
409 // When user enter the page at first time, the 'first refresh' string is given to notify user to refresh all the drivers,
410 // then the 'first refresh' string will be replaced by the 'refresh' string, and the two strings content are same after the replacement
412 NewStringToken
= STRING_TOKEN (STR_FIRST_REFRESH
);
413 NewString
= HiiGetString (Private
->RegisteredHandle
, STRING_TOKEN (STR_REFRESH
), NULL
);
414 ASSERT (NewString
!= NULL
);
415 if (HiiSetString (Private
->RegisteredHandle
, NewStringToken
, NewString
, NULL
) == 0) {
418 FreePool (NewString
);
420 NewStringToken
= STRING_TOKEN (STR_FIRST_REFRESH_HELP
);
421 NewString
= HiiGetString (Private
->RegisteredHandle
, STRING_TOKEN (STR_REFRESH_HELP
), NULL
);
422 ASSERT (NewString
!= NULL
);
423 if (HiiSetString (Private
->RegisteredHandle
, NewStringToken
, NewString
, NULL
) == 0) {
426 FreePool (NewString
);
429 // created needed controller device item in first page
431 DevicePathHandleCount
= 0;
432 Status
= gBS
->LocateHandleBuffer (
434 &gEfiDevicePathProtocolGuid
,
436 &DevicePathHandleCount
,
437 &mDevicePathHandleBuffer
439 if (EFI_ERROR (Status
) || (DevicePathHandleCount
== 0)) {
443 for (Index
= 0; Index
< DevicePathHandleCount
; Index
++) {
444 if (FakeNvData
->PciDeviceFilter
== 0x01) {
446 // Only care PCI device which contain efi driver in its option rom.
450 // Check whether it is a pci device
452 ControllerDevicePath
= NULL
;
453 Status
= gBS
->OpenProtocol (
454 mDevicePathHandleBuffer
[Index
],
455 &gEfiPciIoProtocolGuid
,
459 EFI_OPEN_PROTOCOL_GET_PROTOCOL
461 if (EFI_ERROR (Status
)) {
465 // Check whether it contain efi driver in its option rom
467 Status
= gBS
->HandleProtocol(
468 mDevicePathHandleBuffer
[Index
],
469 &gEfiBusSpecificDriverOverrideProtocolGuid
,
470 (VOID
**) &BusSpecificDriverOverride
472 if (EFI_ERROR (Status
) || BusSpecificDriverOverride
== NULL
) {
477 ControllerDevicePath
= NULL
;
478 Status
= gBS
->OpenProtocol (
479 mDevicePathHandleBuffer
[Index
],
480 &gEfiDevicePathProtocolGuid
,
481 (VOID
**) &ControllerDevicePath
,
484 EFI_OPEN_PROTOCOL_GET_PROTOCOL
486 ASSERT_EFI_ERROR (Status
);
488 // Save the device path protocol interface
490 mControllerDevicePathProtocol
[Index
] = ControllerDevicePath
;
493 // Get the driver name
495 ControllerName
= DevicePathToStr (ControllerDevicePath
);
498 // Export the driver name string and create item in set options page
500 Len
= StrSize (ControllerName
);
501 NewString
= AllocateZeroPool (Len
+ StrSize (L
"--"));
502 ASSERT (NewString
!= NULL
);
503 if (EFI_ERROR (CheckMapping (ControllerDevicePath
,NULL
, &mMappingDataBase
, NULL
, NULL
))) {
504 StrCat (NewString
, L
"--");
506 StrCat (NewString
, L
"**");
508 StrCat (NewString
, ControllerName
);
510 NewStringToken
= HiiSetString (Private
->RegisteredHandle
, mControllerToken
[Index
], NewString
, NULL
);
511 ASSERT (NewStringToken
!= 0);
512 FreePool (NewString
);
514 // Save the device path string toke for next access use
516 mControllerToken
[Index
] = NewStringToken
;
518 HiiCreateGotoOpCode (
522 STRING_TOKEN (STR_GOTO_HELP_DRIVER
),
523 EFI_IFR_FLAG_CALLBACK
,
524 (UINT16
) (Index
+ KEY_VALUE_DEVICE_OFFSET
)
529 // Update first page form
532 Private
->RegisteredHandle
,
533 &gPlatformOverridesManagerGuid
,
535 StartOpCodeHandle
, // Label FORM_ID_DEVICE
536 EndOpCodeHandle
// LABEL_END
539 HiiFreeOpCodeHandle (StartOpCodeHandle
);
540 HiiFreeOpCodeHandle (EndOpCodeHandle
);
546 Get the first Driver Binding handle which has the specific image handle.
548 @param ImageHandle The Image handle
550 @return Handle to Driver binding
551 @retval NULL The paramter is not valid or the driver binding handle is not found.
555 GetDriverBindingHandleFromImageHandle (
556 IN EFI_HANDLE ImageHandle
561 UINTN DriverBindingHandleCount
;
562 EFI_HANDLE
*DriverBindingHandleBuffer
;
563 EFI_DRIVER_BINDING_PROTOCOL
*DriverBindingInterface
;
564 EFI_HANDLE DriverBindingHandle
;
566 DriverBindingHandle
= NULL
;
568 if (ImageHandle
== NULL
) {
572 // Get all drivers which support driver binding protocol
574 DriverBindingHandleCount
= 0;
575 Status
= gBS
->LocateHandleBuffer (
577 &gEfiDriverBindingProtocolGuid
,
579 &DriverBindingHandleCount
,
580 &DriverBindingHandleBuffer
582 if (EFI_ERROR (Status
) || (DriverBindingHandleCount
== 0)) {
587 // Get the first Driver Binding handle which has the specific image handle.
589 for (Index
= 0; Index
< DriverBindingHandleCount
; Index
++) {
590 DriverBindingInterface
= NULL
;
591 Status
= gBS
->OpenProtocol (
592 DriverBindingHandleBuffer
[Index
],
593 &gEfiDriverBindingProtocolGuid
,
594 (VOID
**) &DriverBindingInterface
,
597 EFI_OPEN_PROTOCOL_GET_PROTOCOL
599 if (EFI_ERROR (Status
)) {
603 if (DriverBindingInterface
->ImageHandle
== ImageHandle
) {
604 DriverBindingHandle
= DriverBindingHandleBuffer
[Index
];
609 FreePool (DriverBindingHandleBuffer
);
610 return DriverBindingHandle
;
614 Prepare to let user select the drivers which need mapping with the device controller
615 selected in first page.
617 @param Private Pointer to EFI_CALLBACK_INFO.
618 @param KeyValue The callback key value of device controller item in first page.
619 KeyValue is larger than or equal to KEY_VALUE_DEVICE_OFFSET.
620 @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.
622 @retval EFI_SUCCESS Always returned.
626 UpdateBindingDriverSelectPage (
627 IN EFI_CALLBACK_INFO
*Private
,
629 IN PLAT_OVER_MNGR_DATA
*FakeNvData
635 EFI_STRING_ID NewStringToken
;
636 EFI_STRING_ID NewStringHelpToken
;
637 UINTN DriverImageHandleCount
;
638 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
640 BOOLEAN FreeDriverName
;
641 EFI_DEVICE_PATH_PROTOCOL
*LoadedImageDevicePath
;
642 EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
*BusSpecificDriverOverride
;
643 EFI_HANDLE DriverBindingHandle
;
644 VOID
*StartOpCodeHandle
;
645 VOID
*EndOpCodeHandle
;
646 EFI_IFR_GUID_LABEL
*StartLabel
;
647 EFI_IFR_GUID_LABEL
*EndLabel
;
650 // If user select a controller item in the first page the following code will be run.
651 // During second page, user will see all currnet driver bind protocol driver, the driver name and its device path will be shown
653 //First acquire the list of Loaded Image Protocols, and then when want the name of the driver, look up all the Driver Binding Protocols
654 // and find the first one whose ImageHandle field matches the image handle of the Loaded Image Protocol.
655 // 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.
658 mCurrentPage
= FORM_ID_DRIVER
;
660 // Switch the item callback key value to its NO. in mDevicePathHandleBuffer
662 mSelectedCtrIndex
= KeyValue
- KEY_VALUE_DEVICE_OFFSET
;
663 ASSERT (mSelectedCtrIndex
>= 0 && mSelectedCtrIndex
< MAX_CHOICE_NUM
);
665 mLastSavedDriverImageNum
= 0;
668 // Init OpCode Handle
670 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
671 ASSERT (StartOpCodeHandle
!= NULL
);
673 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
674 ASSERT (EndOpCodeHandle
!= NULL
);
677 // Create Hii Extend Label OpCode as the start opcode
679 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
680 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
681 StartLabel
->Number
= FORM_ID_DRIVER
;
684 // Create Hii Extend Label OpCode as the end opcode
686 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
687 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
688 EndLabel
->Number
= LABEL_END
;
691 // Clear second page form
694 Private
->RegisteredHandle
,
695 &gPlatformOverridesManagerGuid
,
702 // Show all driver which support loaded image protocol in second page
704 DriverImageHandleCount
= 0;
705 Status
= gBS
->LocateHandleBuffer (
707 &gEfiLoadedImageProtocolGuid
,
709 &DriverImageHandleCount
,
710 &mDriverImageHandleBuffer
712 if (EFI_ERROR (Status
) || (DriverImageHandleCount
== 0)) {
713 return EFI_NOT_FOUND
;
716 mDriverImageHandleCount
= DriverImageHandleCount
;
717 for (Index
= 0; Index
< DriverImageHandleCount
; Index
++) {
719 // Step1: Get the driver image total file path for help string and the driver name.
723 // Find driver's Loaded Image protocol
727 Status
= gBS
->OpenProtocol (
728 mDriverImageHandleBuffer
[Index
],
729 &gEfiLoadedImageProtocolGuid
,
730 (VOID
**) &LoadedImage
,
733 EFI_OPEN_PROTOCOL_GET_PROTOCOL
735 if (EFI_ERROR (Status
)) {
736 FakeNvData
->DriSelection
[Index
] = 0x00;
739 mDriverImageProtocol
[Index
] = LoadedImage
;
741 // Find its related driver binding protocol
743 DriverBindingHandle
= GetDriverBindingHandleFromImageHandle (mDriverImageHandleBuffer
[Index
]);
744 if (DriverBindingHandle
== NULL
) {
745 FakeNvData
->DriSelection
[Index
] = 0x00;
750 // Get the EFI Loaded Image Device Path Protocol
752 LoadedImageDevicePath
= NULL
;
753 Status
= gBS
->HandleProtocol (
754 mDriverImageHandleBuffer
[Index
],
755 &gEfiLoadedImageDevicePathProtocolGuid
,
756 (VOID
**) &LoadedImageDevicePath
758 if (LoadedImageDevicePath
== NULL
) {
759 FakeNvData
->DriSelection
[Index
] = 0x00;
763 if (FakeNvData
->PciDeviceFilter
== 0x01) {
765 // only care the driver which is in a Pci device option rom,
766 // and the driver's LoadedImage->DeviceHandle must point to a pci device which has efi option rom
768 if (!EFI_ERROR (Status
)) {
769 Status
= gBS
->HandleProtocol(
770 LoadedImage
->DeviceHandle
,
771 &gEfiBusSpecificDriverOverrideProtocolGuid
,
772 (VOID
**) &BusSpecificDriverOverride
774 if (EFI_ERROR (Status
) || BusSpecificDriverOverride
== NULL
) {
775 FakeNvData
->DriSelection
[Index
] = 0x00;
779 FakeNvData
->DriSelection
[Index
] = 0x00;
785 // For driver name, try to get its component name, if fail, get its image name,
786 // if also fail, give a default name.
788 FreeDriverName
= FALSE
;
789 DriverName
= GetComponentName (DriverBindingHandle
);
790 if (DriverName
== NULL
) {
792 // get its image name
794 DriverName
= GetImageName (LoadedImage
);
796 if (DriverName
== NULL
) {
798 // give a default name
800 DriverName
= HiiGetString (Private
->RegisteredHandle
, STRING_TOKEN (STR_DRIVER_DEFAULT_NAME
), NULL
);
801 ASSERT (DriverName
!= NULL
);
802 FreeDriverName
= TRUE
; // the DriverName string need to free pool
807 // Step2 Export the driver name string and create check box item in second page
811 // First create the driver image name
813 NewString
= AllocateZeroPool (StrSize (DriverName
));
814 ASSERT (NewString
!= NULL
);
815 if (EFI_ERROR (CheckMapping (mControllerDevicePathProtocol
[mSelectedCtrIndex
], LoadedImageDevicePath
, &mMappingDataBase
, NULL
, NULL
))) {
816 FakeNvData
->DriSelection
[Index
] = 0x00;
818 FakeNvData
->DriSelection
[Index
] = 0x01;
819 mLastSavedDriverImageNum
++;
821 StrCat (NewString
, DriverName
);
822 NewStringToken
= HiiSetString (Private
->RegisteredHandle
, mDriverImageToken
[Index
], NewString
, NULL
);
823 ASSERT (NewStringToken
!= 0);
824 mDriverImageToken
[Index
] = NewStringToken
;
825 FreePool (NewString
);
826 if (FreeDriverName
) {
827 FreePool (DriverName
);
831 // Second create the driver image device path as item help string
833 DriverName
= DevicePathToStr (LoadedImageDevicePath
);
835 NewString
= AllocateZeroPool (StrSize (DriverName
));
836 ASSERT (NewString
!= NULL
);
837 StrCat (NewString
, DriverName
);
838 NewStringHelpToken
= HiiSetString (Private
->RegisteredHandle
, mDriverImageFilePathToken
[Index
], NewString
, NULL
);
839 ASSERT (NewStringHelpToken
!= 0);
840 mDriverImageFilePathToken
[Index
] = NewStringHelpToken
;
841 FreePool (NewString
);
842 FreePool (DriverName
);
844 HiiCreateCheckBoxOpCode (
846 (UINT16
) (DRIVER_SELECTION_QUESTION_ID
+ Index
),
847 VARSTORE_ID_PLAT_OVER_MNGR
,
848 (UINT16
) (DRIVER_SELECTION_VAR_OFFSET
+ Index
),
858 // Update second page form
861 Private
->RegisteredHandle
,
862 &gPlatformOverridesManagerGuid
,
864 StartOpCodeHandle
, // Label FORM_ID_DRIVER
865 EndOpCodeHandle
// LABEL_END
868 HiiFreeOpCodeHandle (StartOpCodeHandle
);
869 HiiFreeOpCodeHandle (EndOpCodeHandle
);
874 Prepare to let user select the priority order of the drivers which are
875 selected in second page.
877 @param Private Pointer to EFI_CALLBACK_INFO.
878 @param KeyValue The callback key value of device controller item in first page.
879 @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.
881 @retval EFI_SUCCESS Always returned.
885 UpdatePrioritySelectPage (
886 IN EFI_CALLBACK_INFO
*Private
,
888 IN PLAT_OVER_MNGR_DATA
*FakeNvData
892 EFI_DEVICE_PATH_PROTOCOL
*LoadedImageDevicePath
;
893 UINTN SelectedDriverImageNum
;
894 UINT32 DriverImageNO
;
899 VOID
*StartOpCodeHandle
;
900 VOID
*EndOpCodeHandle
;
901 VOID
*OptionsOpCodeHandle
;
902 EFI_IFR_GUID_LABEL
*StartLabel
;
903 EFI_IFR_GUID_LABEL
*EndLabel
;
906 // Following code will be run if user select 'order ... priority' item in second page
907 // Prepare third page. In third page, user will order the drivers priority which are selected in second page
909 mCurrentPage
= FORM_ID_ORDER
;
912 // Init OpCode Handle
914 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
915 ASSERT (StartOpCodeHandle
!= NULL
);
917 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
918 ASSERT (EndOpCodeHandle
!= NULL
);
921 // Create Hii Extend Label OpCode as the start opcode
923 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
924 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
925 StartLabel
->Number
= FORM_ID_ORDER
;
928 // Create Hii Extend Label OpCode as the end opcode
930 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
931 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
932 EndLabel
->Number
= LABEL_END
;
935 // Clear third page form
938 Private
->RegisteredHandle
,
939 &gPlatformOverridesManagerGuid
,
946 // Check how many drivers have been selected
948 SelectedDriverImageNum
= 0;
949 for (Index
= 0; Index
< mDriverImageHandleCount
; Index
++) {
950 if (FakeNvData
->DriSelection
[Index
] != 0) {
951 SelectedDriverImageNum
++;
955 mSelectedDriverImageNum
= SelectedDriverImageNum
;
956 if (SelectedDriverImageNum
== 0) {
960 OptionsOpCodeHandle
= HiiAllocateOpCodeHandle ();
961 ASSERT (OptionsOpCodeHandle
!= NULL
);
964 // Create order list for those selected drivers
966 SelectedDriverImageNum
= 0;
967 for (Index
= 0; Index
< mDriverImageHandleCount
; Index
++) {
968 if (FakeNvData
->DriSelection
[Index
] != 0) {
970 // Use the NO. in driver binding buffer as value, will use it later
972 HiiCreateOneOfOptionOpCode (
974 mDriverImageToken
[Index
],
976 EFI_IFR_NUMERIC_SIZE_1
,
981 // Get the EFI Loaded Image Device Path Protocol
983 LoadedImageDevicePath
= NULL
;
984 gBS
->HandleProtocol (
985 mDriverImageHandleBuffer
[Index
],
986 &gEfiLoadedImageDevicePathProtocolGuid
,
987 (VOID
**) &LoadedImageDevicePath
989 ASSERT (LoadedImageDevicePath
!= NULL
);
992 // Check the driver DriverImage's order number in mapping database
996 mControllerDevicePathProtocol
[mSelectedCtrIndex
],
997 LoadedImageDevicePath
,
1002 if (DriverImageNO
== 0) {
1003 DriverImageNO
= (UINT32
) mLastSavedDriverImageNum
+ 1;
1004 mLastSavedDriverImageNum
++;
1006 TempNO
[SelectedDriverImageNum
] = DriverImageNO
;
1007 OrderNO
[SelectedDriverImageNum
] = Index
+ 1;
1008 SelectedDriverImageNum
++;
1012 ASSERT (SelectedDriverImageNum
== mSelectedDriverImageNum
);
1014 // NvRamMap Must be clear firstly
1016 ZeroMem (FakeNvData
->DriOrder
, sizeof (FakeNvData
->DriOrder
));
1019 // Order the selected drivers according to the info already in mapping database
1020 // the less order number in mapping database the less order number in NvRamMap
1022 for (Index
=0; Index
< SelectedDriverImageNum
; Index
++) {
1024 // Find the minimal order number in TempNO array, its index in TempNO is same as IfrOptionList array
1027 for (Index1
=0; Index1
< SelectedDriverImageNum
; Index1
++) {
1028 if (TempNO
[Index1
] < TempNO
[MinNO
]) {
1033 // the IfrOptionList[MinNO].Value = the driver NO. in driver binding buffer
1035 FakeNvData
->DriOrder
[Index
] = (UINT8
) OrderNO
[MinNO
];
1036 TempNO
[MinNO
] = MAX_CHOICE_NUM
+ 1;
1040 // Create Order List OpCode
1042 HiiCreateOrderedListOpCode (
1044 (UINT16
) DRIVER_ORDER_QUESTION_ID
,
1045 VARSTORE_ID_PLAT_OVER_MNGR
,
1046 (UINT16
) DRIVER_ORDER_VAR_OFFSET
,
1047 mControllerToken
[mSelectedCtrIndex
],
1048 mControllerToken
[mSelectedCtrIndex
],
1049 EFI_IFR_FLAG_RESET_REQUIRED
,
1051 EFI_IFR_NUMERIC_SIZE_1
,
1052 (UINT8
) MAX_CHOICE_NUM
,
1053 OptionsOpCodeHandle
,
1058 // Update third page form
1061 Private
->RegisteredHandle
,
1062 &gPlatformOverridesManagerGuid
,
1064 StartOpCodeHandle
, // Label FORM_ID_ORDER
1065 EndOpCodeHandle
// LABEL_END
1068 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1069 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1070 HiiFreeOpCodeHandle (OptionsOpCodeHandle
);
1076 Save the save the mapping database to NV variable.
1078 @param Private Pointer to EFI_CALLBACK_INFO.
1079 @param KeyValue The callback key value of device controller item in first page.
1080 @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.
1082 @retval EFI_SUCCESS Always returned.
1087 IN EFI_CALLBACK_INFO
*Private
,
1089 IN PLAT_OVER_MNGR_DATA
*FakeNvData
1094 UINTN SelectedDriverImageNum
;
1095 EFI_DEVICE_PATH_PROTOCOL
*LoadedImageDevicePath
;
1097 // Following code will be run if user select 'commint changes' in third page
1098 // user enter 'Commit Changes' to save the mapping database
1100 DeleteDriverImage (mControllerDevicePathProtocol
[mSelectedCtrIndex
], NULL
, &mMappingDataBase
);
1101 for (SelectedDriverImageNum
= 0; SelectedDriverImageNum
< mSelectedDriverImageNum
; SelectedDriverImageNum
++) {
1103 // DriOrder[SelectedDriverImageNum] = the driver NO. in driver binding buffer
1105 Index
= FakeNvData
->DriOrder
[SelectedDriverImageNum
] - 1;
1108 // Get the EFI Loaded Image Device Path Protocol
1110 LoadedImageDevicePath
= NULL
;
1111 Status
= gBS
->HandleProtocol (
1112 mDriverImageHandleBuffer
[Index
],
1113 &gEfiLoadedImageDevicePathProtocolGuid
,
1114 (VOID
**) &LoadedImageDevicePath
1116 ASSERT (LoadedImageDevicePath
!= NULL
);
1119 mControllerDevicePathProtocol
[mSelectedCtrIndex
],
1120 LoadedImageDevicePath
,
1122 (UINT32
)SelectedDriverImageNum
+ 1
1125 Status
= SaveOverridesMapping (&mMappingDataBase
);
1131 This function allows a caller to extract the current configuration for one
1132 or more named elements from the target driver.
1134 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1135 @param Request A null-terminated Unicode string in <ConfigRequest> format.
1136 @param Progress On return, points to a character in the Request string.
1137 Points to the string's null terminator if request was successful.
1138 Points to the most recent '&' before the first failing name/value
1139 pair (or the beginning of the string if the failure is in the
1140 first name/value pair) if the request was not successful.
1141 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
1142 has all values filled in for the names in the Request string.
1143 String to be allocated by the called function.
1145 @retval EFI_SUCCESS The Results is filled with the requested values.
1146 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
1147 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
1148 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
1153 PlatOverMngrExtractConfig (
1154 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1155 IN CONST EFI_STRING Request
,
1156 OUT EFI_STRING
*Progress
,
1157 OUT EFI_STRING
*Results
1161 EFI_CALLBACK_INFO
*Private
;
1162 EFI_HII_CONFIG_ROUTING_PROTOCOL
*HiiConfigRouting
;
1163 EFI_STRING ConfigRequestHdr
;
1164 EFI_STRING ConfigRequest
;
1165 BOOLEAN AllocatedRequest
;
1169 if (Progress
== NULL
|| Results
== NULL
) {
1170 return EFI_INVALID_PARAMETER
;
1173 *Progress
= Request
;
1174 if ((Request
!= NULL
) && !HiiIsConfigHdrMatch (Request
, &gPlatformOverridesManagerGuid
, mVariableName
)) {
1175 return EFI_NOT_FOUND
;
1178 ConfigRequestHdr
= NULL
;
1179 ConfigRequest
= NULL
;
1181 AllocatedRequest
= FALSE
;
1183 Private
= EFI_CALLBACK_INFO_FROM_THIS (This
);
1184 HiiConfigRouting
= Private
->HiiConfigRouting
;
1185 ConfigRequest
= Request
;
1186 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
1188 // Request has no request element, construct full request string.
1189 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1190 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
1192 ConfigRequestHdr
= HiiConstructConfigHdr (&gPlatformOverridesManagerGuid
, mVariableName
, Private
->DriverHandle
);
1193 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
1194 ConfigRequest
= AllocateZeroPool (Size
);
1195 ASSERT (ConfigRequest
!= NULL
);
1196 AllocatedRequest
= TRUE
;
1197 BufferSize
= sizeof (PLAT_OVER_MNGR_DATA
);
1198 UnicodeSPrint (ConfigRequest
, Size
, L
"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr
, (UINT64
)BufferSize
);
1199 FreePool (ConfigRequestHdr
);
1203 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
1205 Status
= HiiConfigRouting
->BlockToConfig (
1208 (UINT8
*) &Private
->FakeNvData
,
1209 sizeof (PLAT_OVER_MNGR_DATA
),
1215 // Free the allocated config request string.
1217 if (AllocatedRequest
) {
1218 FreePool (ConfigRequest
);
1219 ConfigRequest
= NULL
;
1222 // Set Progress string to the original request string.
1224 if (Request
== NULL
) {
1226 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
1227 *Progress
= Request
+ StrLen (Request
);
1234 This function processes the results of changes in configuration.
1236 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1237 @param Configuration A null-terminated Unicode string in <ConfigRequest> format.
1238 @param Progress A pointer to a string filled in with the offset of the most
1239 recent '&' before the first failing name/value pair (or the
1240 beginning of the string if the failure is in the first
1241 name/value pair) or the terminating NULL if all was successful.
1243 @retval EFI_SUCCESS The Results is processed successfully.
1244 @retval EFI_INVALID_PARAMETER Configuration is NULL.
1245 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
1250 PlatOverMngrRouteConfig (
1251 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1252 IN CONST EFI_STRING Configuration
,
1253 OUT EFI_STRING
*Progress
1256 EFI_CALLBACK_INFO
*Private
;
1258 PLAT_OVER_MNGR_DATA
*FakeNvData
;
1260 if (Configuration
== NULL
|| Progress
== NULL
) {
1261 return EFI_INVALID_PARAMETER
;
1263 *Progress
= Configuration
;
1265 if (!HiiIsConfigHdrMatch (Configuration
, &gPlatformOverridesManagerGuid
, mVariableName
)) {
1266 return EFI_NOT_FOUND
;
1269 *Progress
= Configuration
+ StrLen (Configuration
);
1270 Private
= EFI_CALLBACK_INFO_FROM_THIS (This
);
1271 FakeNvData
= &Private
->FakeNvData
;
1272 if (!HiiGetBrowserData (&gPlatformOverridesManagerGuid
, mVariableName
, sizeof (PLAT_OVER_MNGR_DATA
), (UINT8
*) FakeNvData
)) {
1274 // FakeNvData can't be got from SetupBrowser, which doesn't need to be set.
1279 if (mCurrentPage
== FORM_ID_DRIVER
) {
1280 KeyValue
= KEY_VALUE_DRIVER_GOTO_ORDER
;
1281 UpdatePrioritySelectPage (Private
, KeyValue
, FakeNvData
);
1282 KeyValue
= KEY_VALUE_ORDER_SAVE_AND_EXIT
;
1283 CommintChanges (Private
, KeyValue
, FakeNvData
);
1285 // Since UpdatePrioritySelectPage will change mCurrentPage,
1286 // should ensure the mCurrentPage still indicate the second page here
1288 mCurrentPage
= FORM_ID_DRIVER
;
1291 if (mCurrentPage
== FORM_ID_ORDER
) {
1292 KeyValue
= KEY_VALUE_ORDER_SAVE_AND_EXIT
;
1293 CommintChanges (Private
, KeyValue
, FakeNvData
);
1300 This is the function that is called to provide results data to the driver. This data
1301 consists of a unique key which is used to identify what data is either being passed back
1304 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1305 @param Action A null-terminated Unicode string in <ConfigRequest> format.
1306 @param KeyValue A unique Goto OpCode callback value which record user's selection.
1307 0x100 <= KeyValue <0x500 : user select a controller item in the first page;
1308 KeyValue == 0x1234 : user select 'Refresh' in first page, or user select 'Go to Previous Menu' in second page
1309 KeyValue == 0x1235 : user select 'Pci device filter' in first page
1310 KeyValue == 0x1500 : user select 'order ... priority' item in second page
1311 KeyValue == 0x1800 : user select 'commint changes' in third page
1312 KeyValue == 0x2000 : user select 'Go to Previous Menu' in third page
1313 @param Type The type of value for the question.
1314 @param Value A pointer to the data being sent to the original exporting driver.
1315 @param ActionRequest On return, points to the action requested by the callback function.
1317 @retval EFI_SUCCESS Always returned.
1322 PlatOverMngrCallback (
1323 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1324 IN EFI_BROWSER_ACTION Action
,
1325 IN EFI_QUESTION_ID KeyValue
,
1327 IN EFI_IFR_TYPE_VALUE
*Value
,
1328 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1331 EFI_CALLBACK_INFO
*Private
;
1333 EFI_STRING_ID NewStringToken
;
1335 PLAT_OVER_MNGR_DATA
*FakeNvData
;
1337 if ((Action
!= EFI_BROWSER_ACTION_CHANGING
) && (Action
!= EFI_BROWSER_ACTION_CHANGED
)) {
1339 // All other action return unsupported.
1341 return EFI_UNSUPPORTED
;
1344 Private
= EFI_CALLBACK_INFO_FROM_THIS (This
);
1345 FakeNvData
= &Private
->FakeNvData
;
1346 if (!HiiGetBrowserData (&gPlatformOverridesManagerGuid
, mVariableName
, sizeof (PLAT_OVER_MNGR_DATA
), (UINT8
*) FakeNvData
)) {
1347 return EFI_NOT_FOUND
;
1350 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
1351 if (Value
== NULL
) {
1352 return EFI_INVALID_PARAMETER
;
1355 if (KeyValue
== KEY_VALUE_DRIVER_GOTO_PREVIOUS
) {
1356 UpdateDeviceSelectPage (Private
, KeyValue
, FakeNvData
);
1358 // Update page title string
1360 NewStringToken
= STRING_TOKEN (STR_TITLE
);
1361 if (HiiSetString (Private
->RegisteredHandle
, NewStringToken
, L
"First, Select the controller by device path", NULL
) == 0) {
1366 if (((KeyValue
>= KEY_VALUE_DEVICE_OFFSET
) && (KeyValue
< KEY_VALUE_DEVICE_MAX
)) || (KeyValue
== KEY_VALUE_ORDER_GOTO_PREVIOUS
)) {
1367 if (KeyValue
== KEY_VALUE_ORDER_GOTO_PREVIOUS
) {
1368 KeyValue
= (EFI_QUESTION_ID
) (mSelectedCtrIndex
+ KEY_VALUE_DEVICE_OFFSET
);
1370 UpdateBindingDriverSelectPage (Private
, KeyValue
, FakeNvData
);
1372 // Update page title string
1374 NewStringToken
= STRING_TOKEN (STR_TITLE
);
1375 if (HiiSetString (Private
->RegisteredHandle
, NewStringToken
, L
"Second, Select drivers for the previous selected controller", NULL
) == 0) {
1380 if (KeyValue
== KEY_VALUE_DRIVER_GOTO_ORDER
) {
1381 UpdatePrioritySelectPage (Private
, KeyValue
, FakeNvData
);
1383 // Update page title string
1385 NewStringToken
= STRING_TOKEN (STR_TITLE
);
1386 if (HiiSetString (Private
->RegisteredHandle
, NewStringToken
, L
"Finally, Set the priority order for the drivers and save them", NULL
) == 0) {
1391 if (KeyValue
== KEY_VALUE_DEVICE_CLEAR
) {
1393 // Deletes all environment variable(s) that contain the override mappings info
1395 FreeMappingDatabase (&mMappingDataBase
);
1396 Status
= SaveOverridesMapping (&mMappingDataBase
);
1397 UpdateDeviceSelectPage (Private
, KeyValue
, FakeNvData
);
1399 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1401 case KEY_VALUE_DEVICE_REFRESH
:
1402 case KEY_VALUE_DEVICE_FILTER
:
1403 UpdateDeviceSelectPage (Private
, KeyValue
, FakeNvData
);
1405 // Update page title string
1407 NewStringToken
= STRING_TOKEN (STR_TITLE
);
1408 if (HiiSetString (Private
->RegisteredHandle
, NewStringToken
, L
"First, Select the controller by device path", NULL
) == 0) {
1413 case KEY_VALUE_ORDER_SAVE_AND_EXIT
:
1414 Status
= CommintChanges (Private
, KeyValue
, FakeNvData
);
1415 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1416 if (EFI_ERROR (Status
)) {
1417 CreatePopUp (EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
, &Key
, L
"Single Override Info too large, Saving Error!", NULL
);
1418 return EFI_DEVICE_ERROR
;
1428 // Pass changed uncommitted data back to Form Browser
1430 HiiSetBrowserData (&gPlatformOverridesManagerGuid
, mVariableName
, sizeof (PLAT_OVER_MNGR_DATA
), (UINT8
*) FakeNvData
, NULL
);
1436 Retrieves the image handle of the platform override driver for a controller in the system.
1438 @param This A pointer to the
1439 EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL instance.
1440 @param ControllerHandle The device handle of the controller to check if a
1441 driver override exists.
1442 @param DriverImageHandle On input, a pointer to the previous driver image
1443 handle returned by GetDriver(). On output, a
1444 pointer to the next driver image handle. Passing
1445 in a NULL, will return the first driver image
1446 handle for ControllerHandle.
1448 @retval EFI_SUCCESS The driver override for ControllerHandle was
1449 returned in DriverImageHandle.
1450 @retval EFI_NOT_FOUND A driver override for ControllerHandle was not
1452 @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is NULL.
1453 DriverImageHandle is not a handle that was returned
1454 on a previous call to GetDriver().
1460 IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*This
,
1461 IN EFI_HANDLE ControllerHandle
,
1462 IN OUT EFI_HANDLE
*DriverImageHandle
1468 // Check that ControllerHandle is a valid handle
1470 if (ControllerHandle
== NULL
) {
1471 return EFI_INVALID_PARAMETER
;
1475 // Read the environment variable(s) that contain the override mappings from Controller Device Path to
1476 // a set of Driver Device Paths, and initialize in memory database of the overrides that map Controller
1477 // Device Paths to an ordered set of Driver Device Paths and Driver Handles. This action is only performed
1478 // once and finished in first call.
1480 if (!mEnvironmentVariableRead
) {
1481 mEnvironmentVariableRead
= TRUE
;
1483 Status
= InitOverridesMapping (&mMappingDataBase
);
1484 if (EFI_ERROR (Status
)){
1485 DEBUG ((DEBUG_ERROR
, "The status to Get Platform Driver Override Variable is %r\n", Status
));
1486 InitializeListHead (&mMappingDataBase
);
1487 return EFI_NOT_FOUND
;
1492 // if the environment variable does not exist, just return not found
1494 if (IsListEmpty (&mMappingDataBase
)) {
1495 return EFI_NOT_FOUND
;
1498 return GetDriverFromMapping (
1507 Retrieves the device path of the platform override driver for a controller in the system.
1508 This driver doesn't support this API.
1510 @param This A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_
1512 @param ControllerHandle The device handle of the controller to check if a driver override
1514 @param DriverImagePath On input, a pointer to the previous driver device path returned by
1515 GetDriverPath(). On output, a pointer to the next driver
1516 device path. Passing in a pointer to NULL, will return the first
1517 driver device path for ControllerHandle.
1519 @retval EFI_UNSUPPORTED
1524 IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*This
,
1525 IN EFI_HANDLE ControllerHandle
,
1526 IN OUT EFI_DEVICE_PATH_PROTOCOL
**DriverImagePath
1529 return EFI_UNSUPPORTED
;
1534 Used to associate a driver image handle with a device path that was returned on a prior call to the
1535 GetDriverPath() service. This driver image handle will then be available through the
1536 GetDriver() service. This driver doesn't support this API.
1538 @param This A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_
1540 @param ControllerHandle The device handle of the controller.
1541 @param DriverImagePath A pointer to the driver device path that was returned in a prior
1542 call to GetDriverPath().
1543 @param DriverImageHandle The driver image handle that was returned by LoadImage()
1544 when the driver specified by DriverImagePath was loaded
1547 @retval EFI_UNSUPPORTED
1552 IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL
*This
,
1553 IN EFI_HANDLE ControllerHandle
,
1554 IN EFI_DEVICE_PATH_PROTOCOL
*DriverImagePath
,
1555 IN EFI_HANDLE DriverImageHandle
1558 return EFI_UNSUPPORTED
;
1562 The driver Entry Point. The funciton will export a disk device class formset and
1563 its callback function to hii database.
1565 @param ImageHandle The firmware allocated handle for the EFI image.
1566 @param SystemTable A pointer to the EFI System Table.
1568 @retval EFI_SUCCESS The entry point is executed successfully.
1569 @retval other Some error occurs when executing this entry point.
1574 PlatDriOverrideDxeInit (
1575 IN EFI_HANDLE ImageHandle
,
1576 IN EFI_SYSTEM_TABLE
*SystemTable
1580 EFI_FORM_BROWSER2_PROTOCOL
*FormBrowser2
;
1584 // There should only be one Form Configuration protocol
1586 Status
= gBS
->LocateProtocol (
1587 &gEfiFormBrowser2ProtocolGuid
,
1589 (VOID
**) &FormBrowser2
1591 if (EFI_ERROR (Status
)) {
1596 // According to UEFI spec, there can be at most a single instance
1597 // in the system of the EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL.
1598 // So here we check the existence.
1600 Status
= gBS
->LocateProtocol (
1601 &gEfiPlatformDriverOverrideProtocolGuid
,
1606 // If there was no error, assume there is an installation and return error
1608 if (!EFI_ERROR (Status
)) {
1609 return EFI_ALREADY_STARTED
;
1612 mCallerImageHandle
= ImageHandle
;
1613 mCallbackInfo
= AllocateZeroPool (sizeof (EFI_CALLBACK_INFO
));
1614 if (mCallbackInfo
== NULL
) {
1615 return EFI_BAD_BUFFER_SIZE
;
1618 mCallbackInfo
->Signature
= EFI_CALLBACK_INFO_SIGNATURE
;
1619 mCallbackInfo
->ConfigAccess
.ExtractConfig
= PlatOverMngrExtractConfig
;
1620 mCallbackInfo
->ConfigAccess
.RouteConfig
= PlatOverMngrRouteConfig
;
1621 mCallbackInfo
->ConfigAccess
.Callback
= PlatOverMngrCallback
;
1622 mCallbackInfo
->PlatformDriverOverride
.GetDriver
= GetDriver
;
1623 mCallbackInfo
->PlatformDriverOverride
.GetDriverPath
= GetDriverPath
;
1624 mCallbackInfo
->PlatformDriverOverride
.DriverLoaded
= DriverLoaded
;
1626 // Install Device Path Protocol and Config Access protocol to driver handle
1627 // Install Platform Driver Override Protocol to driver handle
1629 Status
= gBS
->InstallMultipleProtocolInterfaces (
1630 &mCallbackInfo
->DriverHandle
,
1631 &gEfiDevicePathProtocolGuid
,
1632 &mHiiVendorDevicePath
,
1633 &gEfiHiiConfigAccessProtocolGuid
,
1634 &mCallbackInfo
->ConfigAccess
,
1635 &gEfiPlatformDriverOverrideProtocolGuid
,
1636 &mCallbackInfo
->PlatformDriverOverride
,
1639 if (EFI_ERROR (Status
)) {
1644 // Publish our HII data
1646 mCallbackInfo
->RegisteredHandle
= HiiAddPackages (
1647 &gPlatformOverridesManagerGuid
,
1648 mCallbackInfo
->DriverHandle
,
1650 PlatDriOverrideDxeStrings
,
1653 if (mCallbackInfo
->RegisteredHandle
== NULL
) {
1654 Status
= EFI_OUT_OF_RESOURCES
;
1659 // Locate ConfigRouting protocol
1661 Status
= gBS
->LocateProtocol (
1662 &gEfiHiiConfigRoutingProtocolGuid
,
1664 (VOID
**) &mCallbackInfo
->HiiConfigRouting
1666 if (EFI_ERROR (Status
)) {
1671 // Clear all the globle variable
1673 mDriverImageHandleCount
= 0;
1675 ZeroMem (mDriverImageToken
, MAX_CHOICE_NUM
* sizeof (EFI_STRING_ID
));
1676 ZeroMem (mDriverImageFilePathToken
, MAX_CHOICE_NUM
* sizeof (EFI_STRING_ID
));
1677 ZeroMem (mControllerToken
, MAX_CHOICE_NUM
* sizeof (EFI_STRING_ID
));
1678 ZeroMem (mDriverImageProtocol
, MAX_CHOICE_NUM
* sizeof (EFI_LOADED_IMAGE_PROTOCOL
*));
1683 PlatDriOverrideDxeUnload (ImageHandle
);
1689 Unload its installed protocol.
1691 @param[in] ImageHandle Handle that identifies the image to be unloaded.
1693 @retval EFI_SUCCESS The image has been unloaded.
1697 PlatDriOverrideDxeUnload (
1698 IN EFI_HANDLE ImageHandle
1701 ASSERT (mCallbackInfo
!= NULL
);
1703 if (mCallbackInfo
->DriverHandle
!= NULL
) {
1704 gBS
->UninstallMultipleProtocolInterfaces (
1705 mCallbackInfo
->DriverHandle
,
1706 &gEfiDevicePathProtocolGuid
,
1707 &mHiiVendorDevicePath
,
1708 &gEfiHiiConfigAccessProtocolGuid
,
1709 &mCallbackInfo
->ConfigAccess
,
1710 &gEfiPlatformDriverOverrideProtocolGuid
,
1711 &mCallbackInfo
->PlatformDriverOverride
,
1716 if (mCallbackInfo
->RegisteredHandle
!= NULL
) {
1717 HiiRemovePackages (mCallbackInfo
->RegisteredHandle
);
1720 FreePool (mCallbackInfo
);