+++ /dev/null
-/** @file\r
-\r
- A UI application to offer a UI interface in device manager to let user configure\r
- platform override protocol to override the default algorithm for matching\r
- drivers to controllers.\r
-\r
- The main flow:\r
- 1. The UI application dynamicly locate all controller device path.\r
- 2. The UI application dynamicly locate all drivers which support binding protocol.\r
- 3. The UI application export and dynamicly update two menu to let user select the\r
- mapping between drivers to controllers.\r
- 4. The UI application save all the mapping info in NV variables which will be consumed\r
- by platform override protocol driver to publish the platform override protocol.\r
-\r
-Copyright (c) 2007 - 2008, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include <PiDxe.h>\r
-\r
-#include <Protocol/HiiConfigAccess.h>\r
-#include <Protocol/HiiConfigRouting.h>\r
-#include <Protocol/HiiDatabase.h>\r
-#include <Protocol/FormBrowser2.h>\r
-#include <Protocol/LoadedImage.h>\r
-#include <Protocol/FirmwareVolume2.h>\r
-#include <Protocol/PciIo.h>\r
-#include <Protocol/BusSpecificDriverOverride.h>\r
-#include <Protocol/ComponentName2.h>\r
-#include <Protocol/ComponentName.h>\r
-#include <Protocol/DriverBinding.h>\r
-#include <Protocol/DevicePathToText.h>\r
-#include <Protocol/DevicePath.h>\r
-#include <Guid/MdeModuleHii.h>\r
-\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/UefiApplicationEntryPoint.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/PlatformDriverOverrideLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/HiiLib.h>\r
-\r
-#include "PlatOverMngr.h"\r
-\r
-#define EFI_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('C', 'l', 'b', 'k')\r
-#define EFI_CALLBACK_INFO_FROM_THIS(a) CR (a, EFI_CALLBACK_INFO, ConfigAccess, EFI_CALLBACK_INFO_SIGNATURE)\r
-\r
-typedef struct {\r
- UINTN Signature;\r
- EFI_HANDLE DriverHandle;\r
- EFI_HII_HANDLE RegisteredHandle;\r
- PLAT_OVER_MNGR_DATA FakeNvData;\r
- EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
- EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;\r
-} EFI_CALLBACK_INFO;\r
-\r
-#pragma pack(1)\r
-\r
-///\r
-/// HII specific Vendor Device Path definition.\r
-///\r
-typedef struct {\r
- VENDOR_DEVICE_PATH VendorDevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL End;\r
-} HII_VENDOR_DEVICE_PATH;\r
-\r
-#pragma pack()\r
-\r
-//\r
-// uni string and Vfr Binary data.\r
-//\r
-extern UINT8 VfrBin[];\r
-extern UINT8 PlatOverMngrStrings[];\r
-\r
-//\r
-// module global data\r
-//\r
-EFI_GUID mPlatformOverridesManagerGuid = PLAT_OVER_MNGR_GUID;\r
-CHAR16 mVariableName[] = L"Data";\r
-LIST_ENTRY mMappingDataBase = INITIALIZE_LIST_HEAD_VARIABLE (mMappingDataBase);\r
-\r
-EFI_HANDLE *mDevicePathHandleBuffer;\r
-EFI_HANDLE *mDriverImageHandleBuffer;\r
-\r
-INTN mSelectedCtrIndex;\r
-EFI_STRING_ID mControllerToken[MAX_CHOICE_NUM];\r
-UINTN mDriverImageHandleCount;\r
-EFI_STRING_ID mDriverImageToken[MAX_CHOICE_NUM];\r
-EFI_STRING_ID mDriverImageFilePathToken[MAX_CHOICE_NUM];\r
-EFI_LOADED_IMAGE_PROTOCOL *mDriverImageProtocol[MAX_CHOICE_NUM];\r
-EFI_DEVICE_PATH_PROTOCOL *mControllerDevicePathProtocol[MAX_CHOICE_NUM];\r
-UINTN mSelectedDriverImageNum;\r
-UINTN mLastSavedDriverImageNum;\r
-UINT16 mCurrentPage;\r
-EFI_CALLBACK_INFO *mCallbackInfo;\r
-\r
-HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {\r
- {\r
- {\r
- HARDWARE_DEVICE_PATH,\r
- HW_VENDOR_DP,\r
- {\r
- (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
- (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
- }\r
- },\r
- EFI_CALLER_ID_GUID\r
- },\r
- {\r
- END_DEVICE_PATH_TYPE,\r
- END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
- { \r
- (UINT8) (END_DEVICE_PATH_LENGTH),\r
- (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
- }\r
- }\r
-};\r
-\r
-/**\r
- Converting a given device to an unicode string. \r
- \r
- This function will dependent on gEfiDevicePathToTextProtocolGuid, if protocol\r
- does not installed, then return unknown device path L"?" directly.\r
- \r
- @param DevPath Given device path instance\r
- \r
- @return Converted string from given device path.\r
- @retval L"?" Can not locate gEfiDevicePathToTextProtocolGuid protocol for converting.\r
-**/\r
-CHAR16 *\r
-DevicePathToStr (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
- );\r
-\r
-/**\r
- Worker function to get the driver name by ComponentName or ComponentName2 protocol \r
- according to the driver binding handle.\r
-\r
- @param DriverBindingHandle The Handle of DriverBinding.\r
- @param ProtocolGuid The pointer to Component Name (2) protocol GUID.\r
- @param VariableName The name of the RFC 4646 or ISO 639-2 language variable.\r
-\r
- @retval !NULL Pointer into the image name if the image name is found,\r
- @retval NULL Pointer to NULL if the image name is not found.\r
-\r
-**/\r
-CHAR16 *\r
-GetComponentNameWorker (\r
- IN EFI_HANDLE DriverBindingHandle,\r
- IN EFI_GUID *ProtocolGuid,\r
- IN CONST CHAR16 *VariableName\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_COMPONENT_NAME_PROTOCOL *ComponentName;\r
- CHAR16 *DriverName;\r
- CHAR8 *Language;\r
- CHAR8 *BestLanguage;\r
-\r
- Status = gBS->OpenProtocol (\r
- DriverBindingHandle,\r
- ProtocolGuid,\r
- (VOID *) &ComponentName,\r
- NULL,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return NULL;\r
- }\r
-\r
- //\r
- // Find the best matching language.\r
- //\r
- Language = GetEfiGlobalVariable (VariableName);\r
- BestLanguage = GetBestLanguage (\r
- ComponentName->SupportedLanguages,\r
- (BOOLEAN) (ProtocolGuid == &gEfiComponentNameProtocolGuid),\r
- Language,\r
- NULL\r
- );\r
-\r
- DriverName = NULL;\r
- if (BestLanguage != NULL) {\r
- ComponentName->GetDriverName (\r
- ComponentName,\r
- BestLanguage,\r
- &DriverName\r
- );\r
- FreePool (BestLanguage);\r
- }\r
-\r
- if (Language != NULL) {\r
- FreePool (Language);\r
- }\r
-\r
- return DriverName;\r
-}\r
-\r
-\r
-/**\r
- Get the driver name by ComponentName or ComponentName2 protocol \r
- according to the driver binding handle\r
-\r
- @param DriverBindingHandle The Handle of DriverBinding.\r
-\r
- @retval !NULL Pointer into the image name if the image name is found,\r
- @retval NULL Pointer to NULL if the image name is not found.\r
-\r
-**/\r
-CHAR16 *\r
-GetComponentName (\r
- IN EFI_HANDLE DriverBindingHandle\r
- )\r
-{\r
- CHAR16 *DriverName;\r
-\r
- //\r
- // Try RFC 4646 Component Name 2 protocol first.\r
- //\r
- DriverName = GetComponentNameWorker (DriverBindingHandle, &gEfiComponentName2ProtocolGuid, L"PlatformLang");\r
- if (DriverName == NULL) {\r
- //\r
- // If we can not get driver name from Component Name 2 protocol, we can try ISO 639-2 Component Name protocol. \r
- //\r
- DriverName = GetComponentNameWorker (DriverBindingHandle, &gEfiComponentNameProtocolGuid, L"Lang");\r
- }\r
-\r
- return DriverName;\r
-}\r
-\r
-/**\r
- Get the image name from EFI UI section.\r
- Get FV protocol by its loaded image protocol to abstract EFI UI section.\r
-\r
- @param Image Pointer to the loaded image protocol\r
-\r
- @retval !NULL Pointer to the image name if the image name is found,\r
- @retval NULL NULL if the image name is not found.\r
-\r
-**/\r
-CHAR16 *\r
-GetImageName (\r
- IN EFI_LOADED_IMAGE_PROTOCOL *Image\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH_PROTOCOL *DevPathNode;\r
- EFI_DEVICE_PATH_PROTOCOL *AlignedDevPathNode;\r
- MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;\r
- VOID *Buffer;\r
- UINTN BufferSize;\r
- UINT32 AuthenticationStatus;\r
- EFI_GUID *NameGuid;\r
- EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2;\r
-\r
- Fv2 = NULL;\r
- Buffer = NULL;\r
- BufferSize = 0;\r
-\r
- if (Image->FilePath == NULL) {\r
- return NULL;\r
- }\r
- DevPathNode = Image->FilePath;\r
-\r
- while (!IsDevicePathEnd (DevPathNode)) {\r
- //\r
- // Make sure device path node is aligned when accessing it's FV Name Guid field.\r
- //\r
- AlignedDevPathNode = AllocateCopyPool (DevicePathNodeLength(DevPathNode), DevPathNode);\r
- \r
- //\r
- // Find the Fv File path\r
- //\r
- NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)AlignedDevPathNode);\r
- if (NameGuid != NULL) {\r
- FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) AlignedDevPathNode;\r
- Status = gBS->HandleProtocol (\r
- Image->DeviceHandle,\r
- &gEfiFirmwareVolume2ProtocolGuid,\r
- (VOID **) &Fv2\r
- );\r
- //\r
- // Locate Image EFI UI section to get the image name.\r
- //\r
- if (!EFI_ERROR (Status)) {\r
- Status = Fv2->ReadSection (\r
- Fv2,\r
- &FvFilePath->FvFileName,\r
- EFI_SECTION_USER_INTERFACE,\r
- 0,\r
- &Buffer,\r
- &BufferSize,\r
- &AuthenticationStatus\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- FreePool (AlignedDevPathNode);\r
- break;\r
- }\r
- Buffer = NULL;\r
- }\r
- }\r
- \r
- FreePool (AlignedDevPathNode);\r
- \r
- //\r
- // Next device path node\r
- //\r
- DevPathNode = NextDevicePathNode (DevPathNode);\r
- }\r
-\r
- return Buffer;\r
-}\r
-\r
-/**\r
- Prepare the first page to let user select the device controller which need to\r
- add mapping drivers if user select 'Refresh' in first page.\r
- During first page, user will see all currnet controller device path in system,\r
- select any device path will go to second page to select its overrides drivers.\r
-\r
- @param Private Pointer to EFI_CALLBACK_INFO.\r
- @param KeyValue The callback key value of device controller item in first page.\r
- @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.\r
-\r
- @retval EFI_SUCCESS Always returned.\r
-\r
-**/\r
-EFI_STATUS\r
-UpdateDeviceSelectPage (\r
- IN EFI_CALLBACK_INFO *Private,\r
- IN UINT16 KeyValue,\r
- IN PLAT_OVER_MNGR_DATA *FakeNvData\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- UINTN DevicePathHandleCount;\r
- CHAR16 *NewString;\r
- EFI_STRING_ID NewStringToken;\r
- CHAR16 *ControllerName;\r
- EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;\r
- UINTN Len;\r
- VOID *StartOpCodeHandle;\r
- VOID *EndOpCodeHandle;\r
- EFI_IFR_GUID_LABEL *StartLabel;\r
- EFI_IFR_GUID_LABEL *EndLabel; \r
-\r
- //\r
- // Set current page form ID.\r
- //\r
- mCurrentPage = FORM_ID_DEVICE; \r
- \r
- //\r
- // Initial the mapping database in memory\r
- //\r
- FreeMappingDatabase (&mMappingDataBase);\r
- InitOverridesMapping (&mMappingDataBase);\r
-\r
- //\r
- // Init OpCode Handle\r
- //\r
- StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
- ASSERT (StartOpCodeHandle != NULL);\r
-\r
- EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
- ASSERT (EndOpCodeHandle != NULL);\r
-\r
- //\r
- // Create Hii Extend Label OpCode as the start opcode\r
- //\r
- StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
- StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
- StartLabel->Number = FORM_ID_DEVICE;\r
-\r
- //\r
- // Create Hii Extend Label OpCode as the end opcode\r
- //\r
- EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
- EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
- EndLabel->Number = LABEL_END;\r
-\r
- //\r
- // Clear first page form\r
- //\r
- HiiUpdateForm (\r
- Private->RegisteredHandle,\r
- &mPlatformOverridesManagerGuid,\r
- FORM_ID_DEVICE,\r
- StartOpCodeHandle, // Label FORM_ID_DEVICE\r
- EndOpCodeHandle // LABEL_END\r
- );\r
-\r
- //\r
- // When user enter the page at first time, the 'first refresh' string is given to notify user to refresh all the drivers,\r
- // then the 'first refresh' string will be replaced by the 'refresh' string, and the two strings content are same after the replacement\r
- //\r
- NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH);\r
- NewString = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH), NULL);\r
- ASSERT (NewString != NULL);\r
- if (HiiSetString (Private->RegisteredHandle, NewStringToken, NewString, NULL) == 0) {\r
- ASSERT (FALSE);\r
- }\r
- FreePool (NewString);\r
-\r
- NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH_HELP);\r
- NewString = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH_HELP), NULL);\r
- ASSERT (NewString != NULL);\r
- if (HiiSetString (Private->RegisteredHandle, NewStringToken, NewString, NULL) == 0) {\r
- ASSERT (FALSE);\r
- }\r
- FreePool (NewString);\r
-\r
- //\r
- // created needed controller device item in first page\r
- //\r
- DevicePathHandleCount = 0;\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiDevicePathProtocolGuid,\r
- NULL,\r
- &DevicePathHandleCount,\r
- &mDevicePathHandleBuffer\r
- );\r
- if (EFI_ERROR (Status) || (DevicePathHandleCount == 0)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- for (Index = 0; Index < DevicePathHandleCount; Index++) {\r
- if (FakeNvData->PciDeviceFilter == 0x01) {\r
- //\r
- // Only care PCI device which contain efi driver in its option rom.\r
- //\r
-\r
- //\r
- // Check whether it is a pci device\r
- //\r
- ControllerDevicePath = NULL;\r
- Status = gBS->OpenProtocol (\r
- mDevicePathHandleBuffer[Index],\r
- &gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo,\r
- NULL,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
- //\r
- // Check whether it contain efi driver in its option rom\r
- //\r
- Status = gBS->HandleProtocol(\r
- mDevicePathHandleBuffer[Index],\r
- &gEfiBusSpecificDriverOverrideProtocolGuid,\r
- (VOID **) &BusSpecificDriverOverride\r
- );\r
- if (EFI_ERROR (Status) || BusSpecificDriverOverride == NULL) {\r
- continue;\r
- }\r
- }\r
-\r
- ControllerDevicePath = NULL;\r
- Status = gBS->OpenProtocol (\r
- mDevicePathHandleBuffer[Index],\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &ControllerDevicePath,\r
- NULL,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- //\r
- // Save the device path protocol interface\r
- //\r
- mControllerDevicePathProtocol[Index] = ControllerDevicePath;\r
-\r
- //\r
- // Get the driver name\r
- //\r
- ControllerName = DevicePathToStr (ControllerDevicePath);\r
-\r
- //\r
- // Export the driver name string and create item in set options page\r
- //\r
- Len = StrSize (ControllerName);\r
- NewString = AllocateZeroPool (Len + StrSize (L"--"));\r
- ASSERT (NewString != NULL);\r
- if (EFI_ERROR (CheckMapping (ControllerDevicePath,NULL, &mMappingDataBase, NULL, NULL))) {\r
- StrCat (NewString, L"--");\r
- } else {\r
- StrCat (NewString, L"**");\r
- }\r
- StrCat (NewString, ControllerName);\r
-\r
- NewStringToken = HiiSetString (Private->RegisteredHandle, mControllerToken[Index], NewString, NULL);\r
- ASSERT (NewStringToken != 0);\r
- FreePool (NewString);\r
- //\r
- // Save the device path string toke for next access use\r
- //\r
- mControllerToken[Index] = NewStringToken;\r
- \r
- HiiCreateGotoOpCode (\r
- StartOpCodeHandle,\r
- FORM_ID_DRIVER,\r
- NewStringToken,\r
- STRING_TOKEN (STR_GOTO_HELP_DRIVER),\r
- EFI_IFR_FLAG_CALLBACK,\r
- (UINT16) (Index + KEY_VALUE_DEVICE_OFFSET)\r
- );\r
- }\r
-\r
- //\r
- // Update first page form\r
- //\r
- HiiUpdateForm (\r
- Private->RegisteredHandle,\r
- &mPlatformOverridesManagerGuid,\r
- FORM_ID_DEVICE,\r
- StartOpCodeHandle, // Label FORM_ID_DEVICE\r
- EndOpCodeHandle // LABEL_END\r
- );\r
-\r
- HiiFreeOpCodeHandle (StartOpCodeHandle);\r
- HiiFreeOpCodeHandle (EndOpCodeHandle);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Get the first Driver Binding handle which has the specific image handle.\r
-\r
- @param ImageHandle The Image handle\r
-\r
- @return Handle to Driver binding\r
- @retval NULL The paramter is not valid or the driver binding handle is not found.\r
-\r
-**/\r
-EFI_HANDLE\r
-GetDriverBindingHandleFromImageHandle (\r
- IN EFI_HANDLE ImageHandle\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- UINTN DriverBindingHandleCount;\r
- EFI_HANDLE *DriverBindingHandleBuffer;\r
- EFI_DRIVER_BINDING_PROTOCOL *DriverBindingInterface;\r
- EFI_HANDLE DriverBindingHandle;\r
-\r
- DriverBindingHandle = NULL;\r
-\r
- if (ImageHandle == NULL) {\r
- return NULL;\r
- }\r
- //\r
- // Get all drivers which support driver binding protocol\r
- //\r
- DriverBindingHandleCount = 0;\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiDriverBindingProtocolGuid,\r
- NULL,\r
- &DriverBindingHandleCount,\r
- &DriverBindingHandleBuffer\r
- );\r
- if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {\r
- return NULL;\r
- }\r
- \r
- //\r
- // Get the first Driver Binding handle which has the specific image handle.\r
- //\r
- for (Index = 0; Index < DriverBindingHandleCount; Index++) {\r
- DriverBindingInterface = NULL;\r
- Status = gBS->OpenProtocol (\r
- DriverBindingHandleBuffer[Index],\r
- &gEfiDriverBindingProtocolGuid,\r
- (VOID **) &DriverBindingInterface,\r
- NULL,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- if (DriverBindingInterface->ImageHandle == ImageHandle) {\r
- DriverBindingHandle = DriverBindingHandleBuffer[Index];\r
- break;\r
- }\r
- }\r
-\r
- FreePool (DriverBindingHandleBuffer);\r
- return DriverBindingHandle;\r
-}\r
-\r
-/**\r
- Prepare to let user select the drivers which need mapping with the device controller\r
- selected in first page.\r
-\r
- @param Private Pointer to EFI_CALLBACK_INFO.\r
- @param KeyValue The callback key value of device controller item in first page.\r
- KeyValue is larger than or equal to KEY_VALUE_DEVICE_OFFSET.\r
- @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.\r
-\r
- @retval EFI_SUCCESS Always returned.\r
-\r
-**/\r
-EFI_STATUS\r
-UpdateBindingDriverSelectPage (\r
- IN EFI_CALLBACK_INFO *Private,\r
- IN UINT16 KeyValue,\r
- IN PLAT_OVER_MNGR_DATA *FakeNvData\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- CHAR16 *NewString;\r
- EFI_STRING_ID NewStringToken;\r
- EFI_STRING_ID NewStringHelpToken;\r
- UINTN DriverImageHandleCount;\r
- EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
- CHAR16 *DriverName;\r
- BOOLEAN FreeDriverName;\r
- EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;\r
- EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;\r
- EFI_HANDLE DriverBindingHandle;\r
- VOID *StartOpCodeHandle;\r
- VOID *EndOpCodeHandle;\r
- EFI_IFR_GUID_LABEL *StartLabel;\r
- EFI_IFR_GUID_LABEL *EndLabel;\r
-\r
- //\r
- // If user select a controller item in the first page the following code will be run.\r
- // During second page, user will see all currnet driver bind protocol driver, the driver name and its device path will be shown\r
- //\r
- //First acquire the list of Loaded Image Protocols, and then when want the name of the driver, look up all the Driver Binding Protocols\r
- // and find the first one whose ImageHandle field matches the image handle of the Loaded Image Protocol.\r
- // 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.\r
- //\r
-\r
- mCurrentPage = FORM_ID_DRIVER;\r
- //\r
- // Switch the item callback key value to its NO. in mDevicePathHandleBuffer\r
- //\r
- mSelectedCtrIndex = KeyValue - KEY_VALUE_DEVICE_OFFSET;\r
- ASSERT (mSelectedCtrIndex < MAX_CHOICE_NUM);\r
-\r
- mLastSavedDriverImageNum = 0;\r
-\r
- //\r
- // Init OpCode Handle\r
- //\r
- StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
- ASSERT (StartOpCodeHandle != NULL);\r
-\r
- EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
- ASSERT (EndOpCodeHandle != NULL);\r
-\r
- //\r
- // Create Hii Extend Label OpCode as the start opcode\r
- //\r
- StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
- StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
- StartLabel->Number = FORM_ID_DRIVER;\r
-\r
- //\r
- // Create Hii Extend Label OpCode as the end opcode\r
- //\r
- EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
- EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
- EndLabel->Number = LABEL_END;\r
-\r
- //\r
- // Clear second page form\r
- //\r
- HiiUpdateForm (\r
- Private->RegisteredHandle,\r
- &mPlatformOverridesManagerGuid,\r
- FORM_ID_DRIVER,\r
- StartOpCodeHandle,\r
- EndOpCodeHandle\r
- );\r
-\r
- //\r
- // Show all driver which support loaded image protocol in second page\r
- //\r
- DriverImageHandleCount = 0;\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiLoadedImageProtocolGuid,\r
- NULL,\r
- &DriverImageHandleCount,\r
- &mDriverImageHandleBuffer\r
- );\r
- if (EFI_ERROR (Status) || (DriverImageHandleCount == 0)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- mDriverImageHandleCount = DriverImageHandleCount;\r
- for (Index = 0; Index < DriverImageHandleCount; Index++) {\r
- //\r
- // Step1: Get the driver image total file path for help string and the driver name.\r
- //\r
-\r
- //\r
- // Find driver's Loaded Image protocol\r
- //\r
- LoadedImage =NULL;\r
-\r
- Status = gBS->OpenProtocol (\r
- mDriverImageHandleBuffer[Index],\r
- &gEfiLoadedImageProtocolGuid,\r
- (VOID **) &LoadedImage,\r
- NULL,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- FakeNvData->DriSelection[Index] = 0x00;\r
- continue;\r
- }\r
- mDriverImageProtocol[Index] = LoadedImage;\r
- //\r
- // Find its related driver binding protocol\r
- //\r
- DriverBindingHandle = GetDriverBindingHandleFromImageHandle (mDriverImageHandleBuffer[Index]);\r
- if (DriverBindingHandle == NULL) {\r
- FakeNvData->DriSelection[Index] = 0x00;\r
- continue;\r
- }\r
-\r
- //\r
- // Get the EFI Loaded Image Device Path Protocol\r
- //\r
- LoadedImageDevicePath = NULL;\r
- Status = gBS->HandleProtocol (\r
- mDriverImageHandleBuffer[Index],\r
- &gEfiLoadedImageDevicePathProtocolGuid,\r
- (VOID **) &LoadedImageDevicePath\r
- );\r
- if (LoadedImageDevicePath == NULL) {\r
- FakeNvData->DriSelection[Index] = 0x00;\r
- continue;\r
- }\r
-\r
- if (FakeNvData->PciDeviceFilter == 0x01) {\r
- //\r
- // only care the driver which is in a Pci device option rom,\r
- // and the driver's LoadedImage->DeviceHandle must point to a pci device which has efi option rom\r
- //\r
- if (!EFI_ERROR (Status)) {\r
- Status = gBS->HandleProtocol(\r
- LoadedImage->DeviceHandle,\r
- &gEfiBusSpecificDriverOverrideProtocolGuid,\r
- (VOID **) &BusSpecificDriverOverride\r
- );\r
- if (EFI_ERROR (Status) || BusSpecificDriverOverride == NULL) {\r
- FakeNvData->DriSelection[Index] = 0x00;\r
- continue;\r
- }\r
- } else {\r
- FakeNvData->DriSelection[Index] = 0x00;\r
- continue;\r
- }\r
- }\r
-\r
- //\r
- // For driver name, try to get its component name, if fail, get its image name,\r
- // if also fail, give a default name.\r
- //\r
- FreeDriverName = FALSE;\r
- DriverName = GetComponentName (DriverBindingHandle);\r
- if (DriverName == NULL) {\r
- //\r
- // get its image name\r
- //\r
- DriverName = GetImageName (LoadedImage);\r
- }\r
- if (DriverName == NULL) {\r
- //\r
- // give a default name\r
- //\r
- DriverName = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_DRIVER_DEFAULT_NAME), NULL);\r
- ASSERT (DriverName != NULL);\r
- FreeDriverName = TRUE; // the DriverName string need to free pool\r
- }\r
-\r
-\r
- //\r
- // Step2 Export the driver name string and create check box item in second page\r
- //\r
-\r
- //\r
- // First create the driver image name\r
- //\r
- NewString = AllocateZeroPool (StrSize (DriverName));\r
- ASSERT (NewString != NULL); \r
- if (EFI_ERROR (CheckMapping (mControllerDevicePathProtocol[mSelectedCtrIndex], LoadedImageDevicePath, &mMappingDataBase, NULL, NULL))) {\r
- FakeNvData->DriSelection[Index] = 0x00;\r
- } else {\r
- FakeNvData->DriSelection[Index] = 0x01;\r
- mLastSavedDriverImageNum++;\r
- }\r
- StrCat (NewString, DriverName);\r
- NewStringToken = HiiSetString (Private->RegisteredHandle, mDriverImageToken[Index], NewString, NULL);\r
- ASSERT (NewStringToken != 0);\r
- mDriverImageToken[Index] = NewStringToken;\r
- FreePool (NewString);\r
- if (FreeDriverName) {\r
- FreePool (DriverName);\r
- }\r
-\r
- //\r
- // Second create the driver image device path as item help string\r
- //\r
- DriverName = DevicePathToStr (LoadedImageDevicePath);\r
-\r
- NewString = AllocateZeroPool (StrSize (DriverName));\r
- ASSERT (NewString != NULL); \r
- StrCat (NewString, DriverName);\r
- NewStringHelpToken = HiiSetString (Private->RegisteredHandle, mDriverImageFilePathToken[Index], NewString, NULL);\r
- ASSERT (NewStringHelpToken != 0);\r
- mDriverImageFilePathToken[Index] = NewStringHelpToken;\r
- FreePool (NewString);\r
- FreePool (DriverName);\r
-\r
- HiiCreateCheckBoxOpCode (\r
- StartOpCodeHandle,\r
- (UINT16) (DRIVER_SELECTION_QUESTION_ID + Index),\r
- VARSTORE_ID_PLAT_OVER_MNGR,\r
- (UINT16) (DRIVER_SELECTION_VAR_OFFSET + Index),\r
- NewStringToken,\r
- NewStringHelpToken,\r
- 0,\r
- 0,\r
- NULL\r
- );\r
- }\r
-\r
- //\r
- // Update second page form\r
- //\r
- HiiUpdateForm (\r
- Private->RegisteredHandle,\r
- &mPlatformOverridesManagerGuid,\r
- FORM_ID_DRIVER,\r
- StartOpCodeHandle, // Label FORM_ID_DRIVER\r
- EndOpCodeHandle // LABEL_END\r
- );\r
-\r
- HiiFreeOpCodeHandle (StartOpCodeHandle);\r
- HiiFreeOpCodeHandle (EndOpCodeHandle);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Prepare to let user select the priority order of the drivers which are\r
- selected in second page.\r
-\r
- @param Private Pointer to EFI_CALLBACK_INFO.\r
- @param KeyValue The callback key value of device controller item in first page.\r
- @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.\r
-\r
- @retval EFI_SUCCESS Always returned.\r
-\r
-**/\r
-EFI_STATUS\r
-UpdatePrioritySelectPage (\r
- IN EFI_CALLBACK_INFO *Private,\r
- IN UINT16 KeyValue,\r
- IN PLAT_OVER_MNGR_DATA *FakeNvData\r
- )\r
-{\r
- UINTN Index;\r
- EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;\r
- UINTN SelectedDriverImageNum;\r
- UINT32 DriverImageNO;\r
- UINTN MinNO;\r
- UINTN Index1;\r
- UINTN TempNO[100];\r
- UINTN OrderNO[100];\r
- VOID *StartOpCodeHandle;\r
- VOID *EndOpCodeHandle;\r
- VOID *OptionsOpCodeHandle;\r
- EFI_IFR_GUID_LABEL *StartLabel;\r
- EFI_IFR_GUID_LABEL *EndLabel;\r
-\r
- //\r
- // Following code will be run if user select 'order ... priority' item in second page\r
- // Prepare third page. In third page, user will order the drivers priority which are selected in second page\r
- //\r
- mCurrentPage = FORM_ID_ORDER;\r
-\r
- //\r
- // Init OpCode Handle\r
- //\r
- StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
- ASSERT (StartOpCodeHandle != NULL);\r
-\r
- EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
- ASSERT (EndOpCodeHandle != NULL);\r
-\r
- //\r
- // Create Hii Extend Label OpCode as the start opcode\r
- //\r
- StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
- StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
- StartLabel->Number = FORM_ID_ORDER;\r
-\r
- //\r
- // Create Hii Extend Label OpCode as the end opcode\r
- //\r
- EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
- EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
- EndLabel->Number = LABEL_END;\r
-\r
- //\r
- // Clear third page form\r
- //\r
- HiiUpdateForm (\r
- Private->RegisteredHandle,\r
- &mPlatformOverridesManagerGuid,\r
- FORM_ID_ORDER,\r
- StartOpCodeHandle,\r
- EndOpCodeHandle\r
- );\r
-\r
- //\r
- // Check how many drivers have been selected\r
- //\r
- SelectedDriverImageNum = 0;\r
- for (Index = 0; Index < mDriverImageHandleCount; Index++) {\r
- if (FakeNvData->DriSelection[Index] != 0) {\r
- SelectedDriverImageNum ++;\r
- }\r
- }\r
-\r
- mSelectedDriverImageNum = SelectedDriverImageNum;\r
- if (SelectedDriverImageNum == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();\r
- ASSERT (OptionsOpCodeHandle != NULL);\r
-\r
- //\r
- // Create order list for those selected drivers\r
- //\r
- SelectedDriverImageNum = 0;\r
- for (Index = 0; Index < mDriverImageHandleCount; Index++) {\r
- if (FakeNvData->DriSelection[Index] != 0) {\r
- //\r
- // Use the NO. in driver binding buffer as value, will use it later\r
- //\r
- HiiCreateOneOfOptionOpCode (\r
- OptionsOpCodeHandle,\r
- mDriverImageToken[Index],\r
- 0,\r
- EFI_IFR_NUMERIC_SIZE_1,\r
- Index + 1\r
- );\r
-\r
- //\r
- // Get the EFI Loaded Image Device Path Protocol\r
- //\r
- LoadedImageDevicePath = NULL;\r
- gBS->HandleProtocol (\r
- mDriverImageHandleBuffer[Index],\r
- &gEfiLoadedImageDevicePathProtocolGuid,\r
- (VOID **) &LoadedImageDevicePath\r
- );\r
- ASSERT (LoadedImageDevicePath != NULL);\r
-\r
- //\r
- // Check the driver DriverImage's order number in mapping database\r
- //\r
- DriverImageNO = 0;\r
- CheckMapping (\r
- mControllerDevicePathProtocol[mSelectedCtrIndex],\r
- LoadedImageDevicePath,\r
- &mMappingDataBase,\r
- NULL,\r
- &DriverImageNO\r
- );\r
- if (DriverImageNO == 0) {\r
- DriverImageNO = (UINT32) mLastSavedDriverImageNum + 1;\r
- mLastSavedDriverImageNum++;\r
- }\r
- TempNO[SelectedDriverImageNum] = DriverImageNO;\r
- OrderNO[SelectedDriverImageNum] = Index + 1;\r
- SelectedDriverImageNum ++;\r
- }\r
- }\r
-\r
- ASSERT (SelectedDriverImageNum == mSelectedDriverImageNum);\r
- //\r
- // NvRamMap Must be clear firstly\r
- //\r
- ZeroMem (FakeNvData->DriOrder, sizeof (FakeNvData->DriOrder));\r
-\r
- //\r
- // Order the selected drivers according to the info already in mapping database\r
- // the less order number in mapping database the less order number in NvRamMap\r
- //\r
- for (Index=0; Index < SelectedDriverImageNum; Index++) {\r
- //\r
- // Find the minimal order number in TempNO array, its index in TempNO is same as IfrOptionList array\r
- //\r
- MinNO = 0;\r
- for (Index1=0; Index1 < SelectedDriverImageNum; Index1++) {\r
- if (TempNO[Index1] < TempNO[MinNO]) {\r
- MinNO = Index1;\r
- }\r
- }\r
- //\r
- // the IfrOptionList[MinNO].Value = the driver NO. in driver binding buffer\r
- //\r
- FakeNvData->DriOrder[Index] = (UINT8) OrderNO[MinNO];\r
- TempNO[MinNO] = MAX_CHOICE_NUM + 1;\r
- }\r
- \r
- //\r
- // Create Order List OpCode\r
- //\r
- HiiCreateOrderedListOpCode (\r
- StartOpCodeHandle,\r
- (UINT16) DRIVER_ORDER_QUESTION_ID,\r
- VARSTORE_ID_PLAT_OVER_MNGR,\r
- (UINT16) DRIVER_ORDER_VAR_OFFSET,\r
- mControllerToken[mSelectedCtrIndex],\r
- mControllerToken[mSelectedCtrIndex],\r
- EFI_IFR_FLAG_RESET_REQUIRED,\r
- 0,\r
- EFI_IFR_NUMERIC_SIZE_1,\r
- (UINT8) MAX_CHOICE_NUM,\r
- OptionsOpCodeHandle,\r
- NULL\r
- );\r
-\r
- //\r
- // Update third page form\r
- //\r
- HiiUpdateForm (\r
- Private->RegisteredHandle,\r
- &mPlatformOverridesManagerGuid,\r
- FORM_ID_ORDER,\r
- StartOpCodeHandle, // Label FORM_ID_ORDER\r
- EndOpCodeHandle // LABEL_END\r
- );\r
-\r
- HiiFreeOpCodeHandle (StartOpCodeHandle);\r
- HiiFreeOpCodeHandle (EndOpCodeHandle);\r
- HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Save the save the mapping database to NV variable.\r
-\r
- @param Private Pointer to EFI_CALLBACK_INFO.\r
- @param KeyValue The callback key value of device controller item in first page.\r
- @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.\r
-\r
- @retval EFI_SUCCESS Always returned.\r
-\r
-**/\r
-EFI_STATUS\r
-CommintChanges (\r
- IN EFI_CALLBACK_INFO *Private,\r
- IN UINT16 KeyValue,\r
- IN PLAT_OVER_MNGR_DATA *FakeNvData\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- UINTN SelectedDriverImageNum;\r
- EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;\r
- //\r
- // Following code will be run if user select 'commint changes' in third page\r
- // user enter 'Commit Changes' to save the mapping database\r
- //\r
- DeleteDriverImage (mControllerDevicePathProtocol[mSelectedCtrIndex], NULL, &mMappingDataBase);\r
- for (SelectedDriverImageNum = 0; SelectedDriverImageNum < mSelectedDriverImageNum; SelectedDriverImageNum++) {\r
- //\r
- // DriOrder[SelectedDriverImageNum] = the driver NO. in driver binding buffer\r
- //\r
- Index = FakeNvData->DriOrder[SelectedDriverImageNum] - 1;\r
-\r
- //\r
- // Get the EFI Loaded Image Device Path Protocol\r
- //\r
- LoadedImageDevicePath = NULL;\r
- Status = gBS->HandleProtocol (\r
- mDriverImageHandleBuffer[Index],\r
- &gEfiLoadedImageDevicePathProtocolGuid,\r
- (VOID **) &LoadedImageDevicePath\r
- );\r
- ASSERT (LoadedImageDevicePath != NULL);\r
-\r
- InsertDriverImage (\r
- mControllerDevicePathProtocol[mSelectedCtrIndex],\r
- LoadedImageDevicePath,\r
- &mMappingDataBase,\r
- (UINT32)SelectedDriverImageNum + 1\r
- );\r
- }\r
- Status = SaveOverridesMapping (&mMappingDataBase);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- This function allows a caller to extract the current configuration for one\r
- or more named elements from the target driver.\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
- @param Progress On return, points to a character in the Request string.\r
- Points to the string's null terminator if request was successful.\r
- Points to the most recent '&' before the first failing name/value\r
- pair (or the beginning of the string if the failure is in the\r
- first name/value pair) if the request was not successful.\r
- @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
- has all values filled in for the names in the Request string.\r
- String to be allocated by the called function.\r
-\r
- @retval EFI_SUCCESS The Results is filled with the requested values.\r
- @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
- @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.\r
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PlatOverMngrExtractConfig (\r
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- IN CONST EFI_STRING Request,\r
- OUT EFI_STRING *Progress,\r
- OUT EFI_STRING *Results\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_CALLBACK_INFO *Private;\r
- EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
- \r
- if (Request == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Private = EFI_CALLBACK_INFO_FROM_THIS (This);\r
- HiiConfigRouting = Private->HiiConfigRouting;\r
-\r
- //\r
- // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
- //\r
- Status = HiiConfigRouting->BlockToConfig (\r
- HiiConfigRouting,\r
- Request,\r
- (UINT8 *) &Private->FakeNvData,\r
- sizeof (PLAT_OVER_MNGR_DATA),\r
- Results,\r
- Progress\r
- );\r
- return Status;\r
-}\r
-\r
-/**\r
- This function processes the results of changes in configuration.\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Configuration A null-terminated Unicode string in <ConfigRequest> format.\r
- @param Progress A pointer to a string filled in with the offset of the most\r
- recent '&' before the first failing name/value pair (or the\r
- beginning of the string if the failure is in the first\r
- name/value pair) or the terminating NULL if all was successful.\r
-\r
- @retval EFI_SUCCESS The Results is processed successfully.\r
- @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
- @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PlatOverMngrRouteConfig (\r
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- IN CONST EFI_STRING Configuration,\r
- OUT EFI_STRING *Progress\r
- )\r
-{\r
- EFI_CALLBACK_INFO *Private;\r
- UINT16 KeyValue;\r
- PLAT_OVER_MNGR_DATA *FakeNvData;\r
-\r
- Private = EFI_CALLBACK_INFO_FROM_THIS (This);\r
- FakeNvData = (PLAT_OVER_MNGR_DATA *) HiiGetBrowserData (&mPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA));\r
- if (FakeNvData == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if (mCurrentPage == FORM_ID_DRIVER) {\r
- KeyValue = KEY_VALUE_DRIVER_GOTO_ORDER;\r
- UpdatePrioritySelectPage (Private, KeyValue, FakeNvData);\r
- KeyValue = KEY_VALUE_ORDER_SAVE_AND_EXIT;\r
- CommintChanges (Private, KeyValue, FakeNvData);\r
- //\r
- // Since UpdatePrioritySelectPage will change mCurrentPage,\r
- // should ensure the mCurrentPage still indicate the second page here\r
- //\r
- mCurrentPage = FORM_ID_DRIVER;\r
- }\r
-\r
- if (mCurrentPage == FORM_ID_ORDER) {\r
- KeyValue = KEY_VALUE_ORDER_SAVE_AND_EXIT;\r
- CommintChanges (Private, KeyValue, FakeNvData);\r
- }\r
-\r
- if (FakeNvData != NULL) {\r
- FreePool (FakeNvData);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This is the function that is called to provide results data to the driver. This data\r
- consists of a unique key which is used to identify what data is either being passed back\r
- or being asked for.\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Action A null-terminated Unicode string in <ConfigRequest> format.\r
- @param KeyValue A unique Goto OpCode callback value which record user's selection.\r
- 0x100 <= KeyValue <0x500 : user select a controller item in the first page;\r
- KeyValue == 0x1234 : user select 'Refresh' in first page, or user select 'Go to Previous Menu' in second page\r
- KeyValue == 0x1235 : user select 'Pci device filter' in first page\r
- KeyValue == 0x1500 : user select 'order ... priority' item in second page\r
- KeyValue == 0x1800 : user select 'commint changes' in third page\r
- KeyValue == 0x2000 : user select 'Go to Previous Menu' in third page\r
- @param Type The type of value for the question.\r
- @param Value A pointer to the data being sent to the original exporting driver.\r
- @param ActionRequest On return, points to the action requested by the callback function.\r
-\r
- @retval EFI_SUCCESS Always returned.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PlatOverMngrCallback (\r
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- IN EFI_BROWSER_ACTION Action,\r
- IN EFI_QUESTION_ID KeyValue,\r
- IN UINT8 Type,\r
- IN EFI_IFR_TYPE_VALUE *Value,\r
- OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
- )\r
-{\r
- EFI_CALLBACK_INFO *Private;\r
- EFI_STATUS Status;\r
- EFI_STRING_ID NewStringToken;\r
- EFI_INPUT_KEY Key;\r
- PLAT_OVER_MNGR_DATA *FakeNvData;\r
- \r
- Private = EFI_CALLBACK_INFO_FROM_THIS (This);\r
- FakeNvData = (PLAT_OVER_MNGR_DATA *) HiiGetBrowserData (&mPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA));\r
- if (FakeNvData == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- if (KeyValue == KEY_VALUE_DEVICE_REFRESH ||\r
- KeyValue == KEY_VALUE_DEVICE_FILTER ||\r
- KeyValue == KEY_VALUE_DRIVER_GOTO_PREVIOUS\r
- ) {\r
- UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);\r
- //\r
- // Update page title string\r
- //\r
- NewStringToken = STRING_TOKEN (STR_TITLE);\r
- if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"First, Select the controller by device path", NULL) == 0) {\r
- ASSERT (FALSE);\r
- }\r
- }\r
-\r
- if (((KeyValue >= KEY_VALUE_DEVICE_OFFSET) && (KeyValue < KEY_VALUE_DEVICE_MAX)) || (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS)) {\r
- if (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS) {\r
- KeyValue = (EFI_QUESTION_ID) (mSelectedCtrIndex + KEY_VALUE_DEVICE_OFFSET);\r
- }\r
- UpdateBindingDriverSelectPage (Private, KeyValue, FakeNvData);\r
- //\r
- // Update page title string\r
- //\r
- NewStringToken = STRING_TOKEN (STR_TITLE);\r
- if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"Second, Select drivers for the previous selected controller", NULL) == 0) {\r
- ASSERT (FALSE);\r
- }\r
- }\r
-\r
- if (KeyValue == KEY_VALUE_DRIVER_GOTO_ORDER) {\r
- UpdatePrioritySelectPage (Private, KeyValue, FakeNvData);\r
- //\r
- // Update page title string\r
- //\r
- NewStringToken = STRING_TOKEN (STR_TITLE);\r
- if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"Finally, Set the priority order for the drivers and save them", NULL) == 0) {\r
- ASSERT (FALSE);\r
- }\r
- }\r
-\r
- if (KeyValue == KEY_VALUE_ORDER_SAVE_AND_EXIT) {\r
- Status = CommintChanges (Private, KeyValue, FakeNvData);\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
- if (EFI_ERROR (Status)) {\r
- CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Single Override Info too large, Saving Error!", NULL);\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
-\r
- if (KeyValue == KEY_VALUE_DEVICE_CLEAR) {\r
- //\r
- // Deletes all environment variable(s) that contain the override mappings info\r
- //\r
- FreeMappingDatabase (&mMappingDataBase);\r
- Status = SaveOverridesMapping (&mMappingDataBase);\r
- UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);\r
- }\r
- //\r
- // Pass changed uncommitted data back to Form Browser\r
- //\r
- HiiSetBrowserData (&mPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *) FakeNvData, NULL);\r
- \r
- //\r
- // Update local configuration buffer.\r
- //\r
- CopyMem (&Private->FakeNvData, FakeNvData, sizeof (PLAT_OVER_MNGR_DATA));\r
- if (FakeNvData != NULL) {\r
- FreePool (FakeNvData);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- The driver Entry Point. The funciton will export a disk device class formset and\r
- its callback function to hii database.\r
-\r
- @param ImageHandle The firmware allocated handle for the EFI image.\r
- @param SystemTable A pointer to the EFI System Table.\r
-\r
- @retval EFI_SUCCESS The entry point is executed successfully.\r
- @retval other Some error occurs when executing this entry point.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PlatOverMngrInit (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;\r
- \r
- //\r
- // There should only be one Form Configuration protocol\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiFormBrowser2ProtocolGuid,\r
- NULL,\r
- (VOID **) &FormBrowser2\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- mCallbackInfo = AllocateZeroPool (sizeof (EFI_CALLBACK_INFO));\r
- if (mCallbackInfo == NULL) {\r
- return EFI_BAD_BUFFER_SIZE;\r
- }\r
-\r
- mCallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;\r
- mCallbackInfo->ConfigAccess.ExtractConfig = PlatOverMngrExtractConfig;\r
- mCallbackInfo->ConfigAccess.RouteConfig = PlatOverMngrRouteConfig;\r
- mCallbackInfo->ConfigAccess.Callback = PlatOverMngrCallback;\r
-\r
- //\r
- // Install Device Path Protocol and Config Access protocol to driver handle\r
- //\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &mCallbackInfo->DriverHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- &mHiiVendorDevicePath,\r
- &gEfiHiiConfigAccessProtocolGuid,\r
- &mCallbackInfo->ConfigAccess,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto Finish;\r
- }\r
-\r
- //\r
- // Publish our HII data\r
- //\r
- mCallbackInfo->RegisteredHandle = HiiAddPackages (\r
- &mPlatformOverridesManagerGuid,\r
- mCallbackInfo->DriverHandle,\r
- VfrBin,\r
- PlatOverMngrStrings,\r
- NULL\r
- );\r
- if (mCallbackInfo->RegisteredHandle == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Finish;\r
- }\r
-\r
- //\r
- // Locate ConfigRouting protocol\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiHiiConfigRoutingProtocolGuid,\r
- NULL,\r
- (VOID **) &mCallbackInfo->HiiConfigRouting\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto Finish;\r
- }\r
-\r
- //\r
- // Clear all the globle variable\r
- //\r
- mDriverImageHandleCount = 0;\r
- mCurrentPage = 0;\r
- ZeroMem (mDriverImageToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
- ZeroMem (mDriverImageFilePathToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
- ZeroMem (mControllerToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
- ZeroMem (mDriverImageProtocol, MAX_CHOICE_NUM * sizeof (EFI_LOADED_IMAGE_PROTOCOL *));\r
-\r
- //\r
- // Show the page\r
- //\r
- Status = FormBrowser2->SendForm (\r
- FormBrowser2,\r
- &mCallbackInfo->RegisteredHandle,\r
- 1,\r
- NULL,\r
- 0,\r
- NULL,\r
- NULL\r
- );\r
-\r
- HiiRemovePackages (mCallbackInfo->RegisteredHandle);\r
- Status = EFI_SUCCESS;\r
-\r
-Finish:\r
- if (mCallbackInfo->DriverHandle != NULL) {\r
- gBS->UninstallMultipleProtocolInterfaces (\r
- mCallbackInfo->DriverHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- &mHiiVendorDevicePath,\r
- &gEfiHiiConfigAccessProtocolGuid,\r
- &mCallbackInfo->ConfigAccess,\r
- NULL\r
- );\r
- }\r
-\r
- if (mCallbackInfo != NULL) {\r
- FreePool (mCallbackInfo);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Converting a given device to an unicode string. \r
- \r
- This function will dependent on gEfiDevicePathToTextProtocolGuid, if protocol\r
- does not installed, then return unknown device path L"?" directly.\r
- \r
- @param DevPath Given device path instance\r
- \r
- @return Converted string from given device path.\r
- @retval L"?" Can not locate gEfiDevicePathToTextProtocolGuid protocol for converting.\r
-**/\r
-CHAR16 *\r
-DevicePathToStr (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;\r
- CHAR16 *ToText;\r
- \r
- if (DevPath == NULL) {\r
- return L"";\r
- }\r
- \r
- Status = gBS->LocateProtocol (\r
- &gEfiDevicePathToTextProtocolGuid,\r
- NULL,\r
- (VOID **) &DevPathToText\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- ToText = DevPathToText->ConvertDevicePathToText (\r
- DevPath,\r
- FALSE,\r
- TRUE\r
- );\r
- ASSERT (ToText != NULL);\r
- return ToText;\r
- }\r
-\r
- return L"?";\r
-}\r
+++ /dev/null
-/** @file\r
- \r
- The defintions are required both by Source code and Vfr file.\r
- The PLAT_OVER_MNGR_DATA structure, form guid and Ifr question ID are defined. \r
-\r
-Copyright (c) 2007 - 2008, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#ifndef _PLAT_OVER_MNGR_H_\r
-#define _PLAT_OVER_MNGR_H_\r
-\r
-#define PLAT_OVER_MNGR_GUID \\r
- { \\r
- 0x8614567d, 0x35be, 0x4415, {0x8d, 0x88, 0xbd, 0x7d, 0xc, 0x9c, 0x70, 0xc0} \\r
- }\r
-\r
-//\r
-// The max number of the supported driver list.\r
-//\r
-#define MAX_CHOICE_NUM 0x00ff\r
-#define UPDATE_DATA_SIZE 0x1000\r
-\r
-#define FORM_ID_DEVICE 0x1100\r
-#define FORM_ID_DRIVER 0x1200\r
-#define FORM_ID_ORDER 0x1500\r
-\r
-#define KEY_VALUE_DEVICE_OFFSET 0x0100\r
-#define KEY_VALUE_DEVICE_MAX (KEY_VALUE_DEVICE_OFFSET + MAX_CHOICE_NUM)\r
-\r
-#define KEY_VALUE_DEVICE_REFRESH 0x1234\r
-#define KEY_VALUE_DEVICE_FILTER 0x1235\r
-#define KEY_VALUE_DEVICE_CLEAR 0x1236\r
-\r
-#define KEY_VALUE_DRIVER_GOTO_PREVIOUS 0x1300\r
-#define KEY_VALUE_DRIVER_GOTO_ORDER 0x1301\r
-\r
-#define KEY_VALUE_ORDER_GOTO_PREVIOUS 0x2000\r
-#define KEY_VALUE_ORDER_SAVE_AND_EXIT 0x1800\r
-\r
-#define VARSTORE_ID_PLAT_OVER_MNGR 0x1000\r
-\r
-#define LABEL_END 0xffff\r
-\r
-typedef struct {\r
- UINT8 DriSelection[MAX_CHOICE_NUM];\r
- UINT8 DriOrder[MAX_CHOICE_NUM];\r
- UINT8 PciDeviceFilter;\r
-} PLAT_OVER_MNGR_DATA;\r
-\r
-//\r
-// Field offset of structure PLAT_OVER_MNGR_DATA\r
-//\r
-#define VAR_OFFSET(Field) ((UINTN) &(((PLAT_OVER_MNGR_DATA *) 0)->Field))\r
-#define DRIVER_SELECTION_VAR_OFFSET (VAR_OFFSET (DriSelection))\r
-#define DRIVER_ORDER_VAR_OFFSET (VAR_OFFSET (DriOrder))\r
-\r
-//\r
-// Tool automatic generated Question Id start from 1\r
-// In order to avoid to conflict them, the Driver Selection and Order QuestionID offset is defined from 0x0500.\r
-//\r
-#define QUESTION_ID_OFFSET 0x0500\r
-#define DRIVER_SELECTION_QUESTION_ID (VAR_OFFSET (DriSelection) + QUESTION_ID_OFFSET)\r
-#define DRIVER_ORDER_QUESTION_ID (VAR_OFFSET (DriOrder) + QUESTION_ID_OFFSET)\r
-\r
-#endif\r
+++ /dev/null
-#/** @file\r
-#\r
-# A UI application to offer an UI interface in device manager to let user configure\r
-# platform override protocol to override the default algorithm for matching\r
-# drivers to controllers.\r
-#\r
-# The main flow:\r
-# 1. The UI application dynamicly locate all controller device path.\r
-# 2. The UI application dynamicly locate all drivers which support binding protocol.\r
-# 3. The UI application export and dynamicly update two menu to let user select the\r
-# mapping between drivers to controllers.\r
-# 4. The UI application save all the mapping info in NV variables for the following boot, \r
-# which will be consumed by platform override protocol driver to publish the platform override protocol.\r
-#\r
-# Copyright (c) 2007 - 2009, Intel Corporation. All rights reserved.\r
-#\r
-# All rights reserved. This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-#\r
-#**/\r
-\r
-[Defines]\r
- INF_VERSION = 0x00010005\r
- BASE_NAME = PlatOverMngr\r
- FILE_GUID = 56D95BFE-F991-4898-B3BE-B8F37C927F48\r
- MODULE_TYPE = UEFI_APPLICATION\r
- VERSION_STRING = 1.0\r
- ENTRY_POINT = PlatOverMngrInit\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
-#\r
-\r
-[Sources.common]\r
- VfrStrings.uni\r
- Vfr.vfr\r
- PlatOverMngr.c\r
- PlatOverMngr.h\r
-\r
-[Packages]\r
- MdePkg/MdePkg.dec\r
- MdeModulePkg/MdeModulePkg.dec\r
-\r
-[LibraryClasses]\r
- BaseLib\r
- DebugLib\r
- UefiLib\r
- UefiApplicationEntryPoint\r
- UefiBootServicesTableLib\r
- PlatformDriverOverrideLib\r
- HiiLib\r
- BaseMemoryLib\r
- MemoryAllocationLib\r
- DevicePathLib\r
- \r
-[Guids]\r
-## This GUID C Name is not required for build since it is from UefiLib and not directly used by this module source.\r
-## gEfiGlobalVariableGuid ## SOMETIMES_CONSUMED ## Variable:L"PlatformLang" this variable specifies the platform supported language string (RFC 4646 format)\r
-## gEfiGlobalVariableGuid ## SOMETIMES_CONSUMED ## Variable:L"Lang" this variable specifies the platform supported language string (ISO 639-2 format)\r
- gEfiIfrTianoGuid ## CONSUMES ## Guid\r
-\r
-[Protocols]\r
- gEfiComponentName2ProtocolGuid ## SOMETIMES_CONSUMED (Get Driver Name if ComponentName2Protocol exists)\r
- gEfiComponentNameProtocolGuid ## SOMETIMES_CONSUMED (Get Driver Name if ComponentNameProtocol exists and ComponentName2Protocol doesn't exist)\r
- gEfiFirmwareVolume2ProtocolGuid ## SOMETIMES_CONSUMED (Get Driver Name from EFI UI section if ComponentName2Protocol and ComponentNameProtocol don't exist)\r
- gEfiPciIoProtocolGuid ## SOMETIMES_CONSUMED (Find the PCI device if PciIo protocol is installed)\r
- gEfiBusSpecificDriverOverrideProtocolGuid ## SOMETIMES_CONSUMED (Check whether the PCI device contains one or more efi drivers in its option rom by this protocol) \r
-\r
- gEfiDriverBindingProtocolGuid ## SOMETIMES_CONSUMED\r
- gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMED\r
- gEfiLoadedImageDevicePathProtocolGuid ## SOMETIMES_CONSUMED (Show the drivers in the second page that support DriverBindingProtocol, LoadedImageProtocol and LoadedImageDevicePathProtocol)\r
- gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMED (Show the controller device in the first page that support DevicePathProtocol)\r
-\r
- gEfiHiiDatabaseProtocolGuid ## CONSUMED\r
- gEfiFormBrowser2ProtocolGuid ## CONSUMED\r
- gEfiHiiConfigRoutingProtocolGuid ## CONSUMED\r
- gEfiHiiConfigAccessProtocolGuid ## PRODUCED\r
- gEfiDevicePathToTextProtocolGuid ## CONSUMED\r
+++ /dev/null
-// *++\r
-//\r
-// Copyright (c) 2007 - 2008, Intel Corporation\r
-// All rights reserved. This program and the accompanying materials\r
-// are licensed and made available under the terms and conditions of the BSD License\r
-// which accompanies this distribution. The full text of the license may be found at\r
-// http://opensource.org/licenses/bsd-license.php\r
-//\r
-// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-//\r
-// Module Name:\r
-//\r
-// Vfr.vfr\r
-//\r
-// Abstract:\r
-//\r
-// Platform driver Override manager formset\r
-//\r
-//\r
-// --*/\r
-\r
-#include "PlatOverMngr.h"\r
-\r
-#define EFI_DISK_DEVICE_CLASS 0x01\r
-\r
-formset\r
- guid = PLAT_OVER_MNGR_GUID,\r
- title = STRING_TOKEN(STR_ENTRY_TITLE),\r
- help = STRING_TOKEN(STR_TITLE_HELP),\r
- class = EFI_DISK_DEVICE_CLASS,\r
- subclass = 0xff,\r
-\r
- varstore PLAT_OVER_MNGR_DATA,\r
- varid = VARSTORE_ID_PLAT_OVER_MNGR,\r
- name = Data,\r
- guid = PLAT_OVER_MNGR_GUID;\r
-\r
- form formid = FORM_ID_DEVICE,\r
- title = STRING_TOKEN(STR_TITLE);\r
-\r
- text\r
- help = STRING_TOKEN(STR_FIRST_REFRESH_HELP),\r
- text = STRING_TOKEN(STR_FIRST_REFRESH),\r
- text = STRING_TOKEN(STR_NULL_STRING),\r
- flags = INTERACTIVE,\r
- key = KEY_VALUE_DEVICE_REFRESH;\r
-\r
- checkbox varid = Data.PciDeviceFilter,\r
- prompt = STRING_TOKEN(STR_PCI_DEVICE_FILTER_PROMPT),\r
- help = STRING_TOKEN(STR_PCI_DEVICE_FILTER_HELP),\r
- flags = INTERACTIVE,\r
- key = KEY_VALUE_DEVICE_FILTER,\r
- endcheckbox;\r
-\r
- label FORM_ID_DEVICE;\r
- label LABEL_END;\r
-\r
- subtitle text = STRING_TOKEN(STR_NULL_STRING);\r
-\r
- goto FORM_ID_DEVICE,\r
- prompt = STRING_TOKEN(STR_CLEAR_ALL),\r
- help = STRING_TOKEN(STR_CLEAR_ALL_HELP),\r
- flags = INTERACTIVE | RESET_REQUIRED,\r
- key = KEY_VALUE_DEVICE_CLEAR;\r
- endform;\r
-\r
- form formid = FORM_ID_DRIVER,\r
- title = STRING_TOKEN(STR_TITLE);\r
-\r
- goto FORM_ID_DEVICE,\r
- prompt = STRING_TOKEN(STR_GOTO_PREVIOUS),\r
- help = STRING_TOKEN(STR_NULL_STRING),\r
- flags = INTERACTIVE,\r
- key = KEY_VALUE_DRIVER_GOTO_PREVIOUS;\r
-\r
- goto FORM_ID_ORDER,\r
- prompt = STRING_TOKEN(STR_TITLE_ORDER),\r
- help = STRING_TOKEN(STR_TITLE_ORDER_HELP),\r
- flags = INTERACTIVE,\r
- key = KEY_VALUE_DRIVER_GOTO_ORDER;\r
-\r
- label FORM_ID_DRIVER;\r
- label LABEL_END;\r
-\r
- endform;\r
-\r
- form formid = FORM_ID_ORDER,\r
- title = STRING_TOKEN(STR_TITLE);\r
-\r
- goto FORM_ID_DRIVER,\r
- prompt = STRING_TOKEN(STR_GOTO_PREVIOUS),\r
- help = STRING_TOKEN(STR_NULL_STRING),\r
- flags = INTERACTIVE,\r
- key = KEY_VALUE_ORDER_GOTO_PREVIOUS;\r
-\r
- label FORM_ID_ORDER;\r
- label LABEL_END;\r
-\r
- subtitle text = STRING_TOKEN(STR_NULL_STRING);\r
-\r
- goto FORM_ID_ORDER,\r
- prompt = STRING_TOKEN(STR_SAVE_AND_EXIT),\r
- help = STRING_TOKEN(STR_NULL_STRING),\r
- flags = INTERACTIVE | RESET_REQUIRED,\r
- key = KEY_VALUE_ORDER_SAVE_AND_EXIT;\r
- endform;\r
-\r
-endformset;\r
+++ /dev/null
-/** @file\r
- This file defines the platform driver override variable name and variable guid.\r
- The variable(s) contain the override mappings from Controller Device Path to a set of Driver Device Paths.\r
- \r
- VariableLayout {\r
- //\r
- // NotEnd indicate whether the variable is the last one, and has no subsequent variable need to load.\r
- // Each variable has MaximumVariableSize limitation, so multiple variables are required to store\r
- // large mapping infos.\r
- // The variable(s) name rule is PlatDriOver, PlatDriOver1, PlatDriOver2, ....\r
- //\r
- UINT32 NotEnd; //Zero is the last one.\r
- //\r
- // The entry which contains the mapping that Controller Device Path to a set of Driver Device Paths\r
- // There are often multi mapping entries in a variable.\r
- //\r
- UINT32 SIGNATURE; //SIGNATURE_32('p','d','o','i')\r
- UINT32 DriverNum;\r
- EFI_DEVICE_PATH_PROTOCOL ControllerDevicePath[];\r
- EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
- EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
- EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
- ......\r
- UINT32 NotEnd; //Zero is the last one.\r
- UINT32 SIGNATURE;\r
- UINT32 DriverNum;\r
- EFI_DEVICE_PATH_PROTOCOL ControllerDevicePath[];\r
- EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
- EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
- EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
- ......\r
- }\r
-\r
-Copyright (c) 2008 - 2009, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#ifndef __EFI_OVERRIDE_VARIABLE_GUID_H__\r
-#define __EFI_OVERRIDE_VARIABLE_GUID_H__\r
-\r
-///\r
-/// This guid is used for a platform driver override variable\r
-///\r
-#define EFI_OVERRIDE_VARIABLE_GUID \\r
- { 0x8e3d4ad5, 0xf762, 0x438a, { 0xa1, 0xc1, 0x5b, 0x9f, 0xe6, 0x8c, 0x6b, 0x15 }}\r
-\r
-#define EFI_PLATFORM_OVERRIDE_VARIABLE_NAME L"PlatDriOver"\r
-\r
-extern EFI_GUID gEfiOverrideVariableGuid;\r
-\r
-#endif // #ifndef __EFI_OVERRIDE_VARIABLE_GUID_H__\r
+++ /dev/null
-/** @file\r
- Ihis library is only intended to be used by Platform Driver Override Dxe Driver and Application.\r
- It provides basic platform driver override functions.\r
-\r
-Copyright (c) 2007 - 2009, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#ifndef _PLATFORM_DRIVER_OVERRIDE_LIB_H_\r
-#define _PLATFORM_DRIVER_OVERRIDE_LIB_H_\r
-\r
-#include <Protocol/DevicePath.h>\r
-\r
-/**\r
- Free all the mapping database memory resource and initialize the mapping list entry.\r
-\r
- @param MappingDataBase Mapping database list entry pointer\r
-\r
- @retval EFI_INVALID_PARAMETER mapping database list entry is NULL\r
- @retval EFI_SUCCESS Free success\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FreeMappingDatabase (\r
- IN OUT LIST_ENTRY *MappingDataBase\r
- )\r
-;
-\r
-/**\r
- Read the NV environment variable(s) that contain the override mappings from Controller Device Path to\r
- a set of Driver Device Paths, and create the mapping database in memory to contain these variable info.\r
-\r
- @param MappingDataBase Mapping database list entry pointer\r
-\r
- @retval EFI_INVALID_PARAMETER MappingDataBase pointer is null\r
- @retval EFI_NOT_FOUND Cannot find the 'PlatDriOver' NV variable\r
- @retval EFI_VOLUME_CORRUPTED The found NV variable is corrupted\r
- @retval EFI_SUCCESS Create the mapping database in memory successfully\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitOverridesMapping (\r
- OUT LIST_ENTRY *MappingDataBase\r
- )\r
-;
-\r
-/**\r
- Save the memory mapping database into NV environment variable(s).\r
- If MappingDataBase list is empty, then delete all platform override NV variables.\r
-\r
- @param MappingDataBase Mapping database list entry pointer\r
-\r
- @retval EFI_INVALID_PARAMETER MappingDataBase pointer is null\r
- @retval EFI_SUCCESS Save memory mapping database successfully\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SaveOverridesMapping (\r
- IN LIST_ENTRY *MappingDataBase\r
- )\r
-;
-\r
-/**\r
- Retrieves the image handle of the platform override driver for a controller in the system from the memory mapping database.\r
-\r
- @param ControllerHandle The device handle of the controller to check if\r
- a driver override exists.\r
- @param DriverImageHandle On output, a pointer to the next driver handle.\r
- Passing in a pointer to NULL, will return the\r
- first driver handle for ControllerHandle.\r
- @param MappingDataBase MappingDataBase - Mapping database list entry\r
- pointer\r
- @param CallerImageHandle The caller driver's image handle, for\r
- UpdateFvFileDevicePath use.\r
-\r
- @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is not\r
- a valid handle. Or DriverImagePath is not a\r
- device path that was returned on a previous call\r
- to GetDriverPath().\r
- @retval EFI_NOT_FOUND A driver override for ControllerHandle was not\r
- found.\r
- @retval EFI_UNSUPPORTED The operation is not supported.\r
- @retval EFI_SUCCESS The driver override for ControllerHandle was\r
- returned in DriverImagePath.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetDriverFromMapping (\r
- IN EFI_HANDLE ControllerHandle,\r
- IN OUT EFI_HANDLE *DriverImageHandle,\r
- IN LIST_ENTRY *MappingDataBase,\r
- IN EFI_HANDLE CallerImageHandle\r
- )\r
-;
-\r
-/**\r
- Check mapping database whether already has the mapping info which\r
- records the input Controller to input DriverImage.\r
-\r
- @param ControllerDevicePath The controller device path is to be check.\r
- @param DriverImageDevicePath The driver image device path is to be check.\r
- @param MappingDataBase Mapping database list entry pointer\r
- @param DriverInfoNum the controller's total override driver number\r
- @param DriverImageNO The driver order number for the input DriverImage.\r
- If the DriverImageDevicePath is NULL, DriverImageNO is not set.\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerDevicePath or MappingDataBase is NULL.\r
- @retval EFI_NOT_FOUND ControllerDevicePath is not found in MappingDataBase or\r
- DriverImageDevicePath is not found in the found DriverImage Info list. \r
- @retval EFI_SUCCESS The controller's total override driver number and \r
- input DriverImage's order number is correctly return.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CheckMapping (\r
- IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath OPTIONAL,\r
- IN LIST_ENTRY *MappingDataBase,\r
- OUT UINT32 *DriverInfoNum OPTIONAL,\r
- OUT UINT32 *DriverImageNO OPTIONAL\r
- )\r
-;
-\r
-/**\r
- Insert a driver image as a controller's override driver into the mapping database.\r
- The driver image's order number is indicated by DriverImageNO.\r
-\r
- @param ControllerDevicePath The controller device path need to add a\r
- override driver image item\r
- @param DriverImageDevicePath The driver image device path need to be insert\r
- @param MappingDataBase Mapping database list entry pointer\r
- @param DriverImageNO The inserted order number. If this number is taken, \r
- the larger available number will be used.\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerDevicePath is NULL, or DriverImageDevicePath is NULL\r
- or MappingDataBase is NULL\r
- @retval EFI_ALREADY_STARTED The input Controller to input DriverImage has been \r
- recorded into the mapping database.\r
- @retval EFI_SUCCESS The Controller and DriverImage are inserted into \r
- the mapping database successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InsertDriverImage (\r
- IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath,\r
- IN LIST_ENTRY *MappingDataBase,\r
- IN UINT32 DriverImageNO\r
- )\r
-;
-\r
-/**\r
- Delete a controller's override driver from the mapping database.\r
-\r
- @param ControllerDevicePath The controller device path will be deleted \r
- when all drivers images on it are removed.\r
- @param DriverImageDevicePath The driver image device path will be delete.\r
- If NULL, all driver image will be delete.\r
- @param MappingDataBase Mapping database list entry pointer\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerDevicePath is NULL, or MappingDataBase is NULL\r
- @retval EFI_NOT_FOUND ControllerDevicePath is not found in MappingDataBase or\r
- DriverImageDevicePath is not found in the found DriverImage Info list. \r
- @retval EFI_SUCCESS Delete the specified driver successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DeleteDriverImage (\r
- IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath,\r
- IN LIST_ENTRY *MappingDataBase\r
- )\r
-;
-\r
-#endif\r
+++ /dev/null
-#/** @file\r
-# Instance of Platform Driver Override Library to manage driver overriding relationship.\r
-#\r
-# This library instance provides functions to manage the database of overriding relationship\r
-# between controllers and drivers. Each entry of the database contains the mapping that Controller\r
-# Device Path to a set of Driver Device Paths. The database is stored in non-volatile variables.\r
-#\r
-# Copyright (c) 2007 - 2008, Intel Corporation. All rights reserved.\r
-#\r
-# All rights reserved. This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution. The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-#\r
-#**/\r
-\r
-[Defines]\r
- INF_VERSION = 0x00010005\r
- BASE_NAME = PlatDriOverLib\r
- FILE_GUID = 8bd8d711-2736-46d7-8c81-5de68e0a9e88\r
- MODULE_TYPE = DXE_DRIVER\r
- VERSION_STRING = 1.0\r
- LIBRARY_CLASS = PlatformDriverOverrideLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
-#\r
-\r
-[Sources.common]\r
- PlatDriOver.h\r
- PlatDriOverLib.c\r
-\r
-[Packages]\r
- MdePkg/MdePkg.dec\r
- MdeModulePkg/MdeModulePkg.dec\r
-\r
-[LibraryClasses]\r
- DxeServicesTableLib\r
- MemoryAllocationLib\r
- DevicePathLib\r
- BaseLib\r
- UefiLib\r
- UefiBootServicesTableLib\r
- UefiRuntimeServicesTableLib\r
- BaseMemoryLib\r
- DebugLib\r
- PrintLib\r
-\r
-[Guids]\r
- ##\r
- # There could be more than one variables, from PlatDriOver, PlatDriOver1, PlatDriOver2,...\r
- #\r
- gEfiOverrideVariableGuid ## CONSUMES ## Variable:L"PlatDriOver"\r
-\r
-[Protocols]\r
- gEfiFirmwareVolume2ProtocolGuid ## CONSUMES\r
- gEfiLoadedImageProtocolGuid ## CONSUMES\r
- gEfiBusSpecificDriverOverrideProtocolGuid ## CONSUMES\r
- gEfiDriverBindingProtocolGuid ## CONSUMES\r
- gEfiDevicePathProtocolGuid ## CONSUMES\r
- gEfiLoadedImageDevicePathProtocolGuid ## CONSUMES\r
+++ /dev/null
-/** @file\r
- Internal include file for Platform Driver Override Library implementation.\r
- \r
- Copyright (c) 2007 - 2008, Intel Corporation\r
- All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#ifndef _PLAT_DRI_OVER_H_\r
-#define _PLAT_DRI_OVER_H_\r
-\r
-#include <PiDxe.h>\r
-\r
-#include <Protocol/FirmwareVolume2.h>\r
-#include <Protocol/LoadedImage.h>\r
-#include <Protocol/DevicePath.h>\r
-#include <Protocol/BusSpecificDriverOverride.h>\r
-#include <Protocol/DriverBinding.h>\r
-\r
-#include <Library/BaseLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/PrintLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/DxeServicesTableLib.h>\r
-#include <Library/PlatformDriverOverrideLib.h>\r
-\r
-#include <Guid/OverrideVariable.h>\r
-#include <Guid/VariableFormat.h>\r
-\r
-\r
-#define PLATFORM_OVERRIDE_ITEM_SIGNATURE SIGNATURE_32('p','d','o','i')\r
- typedef struct _PLATFORM_OVERRIDE_ITEM {\r
- UINTN Signature;\r
- LIST_ENTRY Link;\r
- UINT32 DriverInfoNum;\r
- EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;\r
- ///\r
- /// List of DRIVER_IMAGE_INFO\r
- ///\r
- LIST_ENTRY DriverInfoList;\r
- EFI_HANDLE LastReturnedImageHandle;\r
-} PLATFORM_OVERRIDE_ITEM;\r
-\r
-#define DRIVER_IMAGE_INFO_SIGNATURE SIGNATURE_32('p','d','i','i')\r
-typedef struct _DRIVER_IMAGE_INFO {\r
- UINTN Signature;\r
- LIST_ENTRY Link;\r
- EFI_HANDLE ImageHandle;\r
- EFI_DEVICE_PATH_PROTOCOL *DriverImagePath;\r
- BOOLEAN UnLoadable;\r
- BOOLEAN UnStartable;\r
-} DRIVER_IMAGE_INFO;\r
-\r
-#define DEVICE_PATH_STACK_ITEM_SIGNATURE SIGNATURE_32('d','p','s','i')\r
-typedef struct _DEVICE_PATH_STACK_ITEM{\r
- UINTN Signature;\r
- LIST_ENTRY Link;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
-} DEVICE_PATH_STACK_ITEM;\r
-\r
-/**\r
- Push a controller device path into a globle device path list.\r
-\r
- @param DevicePath The controller device path to push into stack\r
-\r
- @retval EFI_SUCCESS Device path successfully pushed into the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PushDevPathStack (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- );\r
-\r
-/**\r
- Pop a controller device path from a globle device path list\r
-\r
- @param DevicePath The controller device path popped from stack\r
-\r
- @retval EFI_SUCCESS Controller device path successfully popped.\r
- @retval EFI_NOT_FOUND Stack is empty.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PopDevPathStack (\r
- OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
- );\r
-\r
-/**\r
- Check whether a controller device path is in a globle device path list\r
-\r
- @param DevicePath The controller device path to check\r
-\r
- @retval TRUE DevicePath exists in the stack.\r
- @retval FALSE DevicePath does not exist in the stack.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-CheckExistInStack (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- );\r
-\r
-/**\r
- Update the FV file device path if it is not valid.\r
-\r
- According to a file GUID, check a Fv file device path is valid. If it is invalid,\r
- try to return the valid device path.\r
- FV address maybe changes for memory layout adjust from time to time, use this funciton\r
- could promise the Fv file device path is right.\r
-\r
- @param DevicePath On input, the FV file device path to check\r
- On output, the updated valid FV file device path\r
- @param FileGuid The FV file GUID\r
- @param CallerImageHandle Image handle of the caller\r
-\r
- @retval EFI_INVALID_PARAMETER the input DevicePath or FileGuid is invalid\r
- parameter\r
- @retval EFI_UNSUPPORTED the input DevicePath does not contain FV file\r
- GUID at all\r
- @retval EFI_ALREADY_STARTED the input DevicePath has pointed to FV file, it\r
- is valid\r
- @retval EFI_SUCCESS Successfully updated the invalid DevicePath,\r
- and return the updated device path in DevicePath\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UpdateFvFileDevicePath (\r
- IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,\r
- IN EFI_GUID *FileGuid,\r
- IN EFI_HANDLE CallerImageHandle\r
- );\r
-\r
-/**\r
- Gets the data and size of a variable.\r
-\r
- Read the EFI variable (VendorGuid/Name) and return a dynamically allocated\r
- buffer, and the size of the buffer. If failure return NULL.\r
-\r
- @param Name String part of EFI variable name\r
- @param VendorGuid GUID part of EFI variable name\r
- @param VariableSize Returns the size of the EFI variable that was\r
- read\r
-\r
- @return Dynamically allocated memory that contains a copy of the EFI variable.\r
- Caller is responsible freeing the buffer.\r
- @retval NULL Variable was not read\r
-\r
-**/\r
-VOID *\r
-EFIAPI\r
-GetVariableAndSize (\r
- IN CHAR16 *Name,\r
- IN EFI_GUID *VendorGuid,\r
- OUT UINTN *VariableSize\r
- );\r
-\r
-/**\r
- Connect to the handle to a device on the device path.\r
-\r
- This function will create all handles associate with every device\r
- path node. If the handle associate with one device path node can not\r
- be created success, then still give one chance to do the dispatch,\r
- which load the missing drivers if possible.\r
-\r
- @param DevicePathToConnect The device path which will be connected, it can\r
- be a multi-instance device path\r
-\r
- @retval EFI_SUCCESS All handles associate with every device path\r
- node have been created\r
- @retval EFI_OUT_OF_RESOURCES There is no resource to create new handles\r
- @retval EFI_NOT_FOUND Create the handle associate with one device\r
- path node failed\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ConnectDevicePath (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect\r
- );\r
-\r
-#endif\r
+++ /dev/null
-/** @file\r
- Implementation of Platform Driver Override Library.\r
-\r
- Copyright (c) 2007 - 2008, Intel Corporation\r
- All rights reserved. This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "PlatDriOver.h"\r
-\r
-LIST_ENTRY mDevicePathStack = INITIALIZE_LIST_HEAD_VARIABLE (mDevicePathStack);\r
-\r
-/**\r
- Free all the mapping database memory resource and initialize the mapping list entry.\r
-\r
- @param MappingDataBase Mapping database list entry pointer\r
-\r
- @retval EFI_SUCCESS Mapping database successfully freed\r
- @retval EFI_INVALID_PARAMETER MappingDataBase is NULL\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FreeMappingDatabase (\r
- IN OUT LIST_ENTRY *MappingDataBase\r
- )\r
-{\r
- LIST_ENTRY *OverrideItemListIndex;\r
- LIST_ENTRY *ImageInfoListIndex;\r
- PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
- DRIVER_IMAGE_INFO *DriverImageInfo;\r
-\r
- if (MappingDataBase == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- OverrideItemListIndex = GetFirstNode (MappingDataBase);\r
- while (!IsNull (MappingDataBase, OverrideItemListIndex)) {\r
- OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE);\r
- //\r
- // Free PLATFORM_OVERRIDE_ITEM.ControllerDevicePath[]\r
- //\r
- if (OverrideItem->ControllerDevicePath != NULL){\r
- FreePool (OverrideItem->ControllerDevicePath);\r
- }\r
-\r
- ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
- while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
- //\r
- // Free DRIVER_IMAGE_INFO.DriverImagePath[]\r
- //\r
- DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
- if (DriverImageInfo->DriverImagePath != NULL) {\r
- FreePool(DriverImageInfo->DriverImagePath);\r
- }\r
- //\r
- // Free DRIVER_IMAGE_INFO itself\r
- //\r
- ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
- RemoveEntryList (&DriverImageInfo->Link);\r
- FreePool (DriverImageInfo);\r
- }\r
- //\r
- // Free PLATFORM_OVERRIDE_ITEM itself\r
- //\r
- OverrideItemListIndex = GetNextNode (MappingDataBase, OverrideItemListIndex);\r
- RemoveEntryList (&OverrideItem->Link);\r
- FreePool (OverrideItem);\r
- }\r
-\r
- InitializeListHead (MappingDataBase);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Create the mapping database according to variable.\r
-\r
- Read the environment variable(s) that contain the override mappings from Controller Device Path to\r
- a set of Driver Device Paths, and create the mapping database in memory with those variable info.\r
- VariableLayout{\r
- //\r
- // NotEnd indicate whether the variable is the last one, and has no subsequent variable need to load.\r
- // Each variable has MaximumVariableSize limitation, so we maybe need multiple variables to store\r
- // large mapping infos.\r
- // The variable(s) name rule is PlatDriOver, PlatDriOver1, PlatDriOver2, ....\r
- //\r
- UINT32 NotEnd; //Zero is the last one.\r
- //\r
- // The entry which contains the mapping that Controller Device Path to a set of Driver Device Paths\r
- // There are often multi mapping entries in a variable.\r
- //\r
- UINT32 SIGNATURE; //SIGNATURE_32('p','d','o','i')\r
- UINT32 DriverNum;\r
- EFI_DEVICE_PATH_PROTOCOL ControllerDevicePath[];\r
- EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
- EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
- EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
- ......\r
- UINT32 NotEnd; //Zero is the last one.\r
- UINT32 SIGNATURE;\r
- UINT32 DriverNum;\r
- EFI_DEVICE_PATH_PROTOCOL ControllerDevicePath[];\r
- EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
- EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
- EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
- ......\r
- }\r
-\r
- @param MappingDataBase Mapping database list entry pointer\r
-\r
- @retval EFI_SUCCESS Create the mapping database in memory successfully\r
- @retval EFI_INVALID_PARAMETER MappingDataBase pointer is null\r
- @retval EFI_NOT_FOUND Cannot find the 'PlatDriOver' NV variable\r
- @retval EFI_VOLUME_CORRUPTED The found NV variable is corrupted\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitOverridesMapping (\r
- OUT LIST_ENTRY *MappingDataBase\r
- )\r
-{\r
- UINTN BufferSize;\r
- VOID *VariableBuffer;\r
- UINT8 *VariableIndex;\r
- UINTN VariableNum;\r
- CHAR16 OverrideVariableName[40];\r
- UINT32 NotEnd;\r
- UINT32 DriverNumber;\r
- PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
- DRIVER_IMAGE_INFO *DriverImageInfo;\r
- BOOLEAN Corrupted;\r
- UINT32 Signature;\r
- EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL *DriverDevicePath;\r
- UINTN Index;\r
-\r
- if (MappingDataBase == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Check the environment variable(s) that contain the override mappings .\r
- //\r
- VariableBuffer = GetVariableAndSize (L"PlatDriOver", &gEfiOverrideVariableGuid, &BufferSize);\r
- ASSERT ((UINTN) VariableBuffer % sizeof(UINTN) == 0);\r
- if (VariableBuffer == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Traverse all variables.\r
- //\r
- VariableNum = 1;\r
- Corrupted = FALSE;\r
- do {\r
- VariableIndex = VariableBuffer;\r
- //\r
- // End flag\r
- //\r
- NotEnd = *(UINT32*) VariableIndex;\r
- //\r
- // Traverse the entries containing the mapping that Controller Device Path\r
- // to a set of Driver Device Paths within this variable.\r
- //\r
- VariableIndex = VariableIndex + sizeof (UINT32);\r
- while (VariableIndex < ((UINT8 *)VariableBuffer + BufferSize)) {\r
- //\r
- // Check signature of this entry\r
- //\r
- Signature = *(UINT32 *) VariableIndex;\r
- if (Signature != PLATFORM_OVERRIDE_ITEM_SIGNATURE) {\r
- Corrupted = TRUE;\r
- break;\r
- }\r
- //\r
- // Create PLATFORM_OVERRIDE_ITEM for this mapping\r
- //\r
- OverrideItem = AllocateZeroPool (sizeof (PLATFORM_OVERRIDE_ITEM));\r
- ASSERT (OverrideItem != NULL);\r
- OverrideItem->Signature = PLATFORM_OVERRIDE_ITEM_SIGNATURE;\r
- InitializeListHead (&OverrideItem->DriverInfoList);\r
- VariableIndex = VariableIndex + sizeof (UINT32);\r
- //\r
- // Get DriverNum\r
- //\r
- DriverNumber = *(UINT32*) VariableIndex;\r
- OverrideItem->DriverInfoNum = DriverNumber;\r
- VariableIndex = VariableIndex + sizeof (UINT32);\r
- //\r
- // Get ControllerDevicePath[]\r
- //\r
- ControllerDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) VariableIndex;\r
- OverrideItem->ControllerDevicePath = DuplicateDevicePath (ControllerDevicePath);\r
- VariableIndex = VariableIndex + GetDevicePathSize (ControllerDevicePath);\r
- //\r
- // Align the VariableIndex since the controller device path may not be aligned, refer to the SaveOverridesMapping()\r
- //\r
- VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1));\r
-\r
- //\r
- // Get all DriverImageDevicePath[]\r
- //\r
- for (Index = 0; Index < DriverNumber; Index++) {\r
- //\r
- // Create DRIVER_IMAGE_INFO for this DriverDevicePath[]\r
- //\r
- DriverImageInfo = AllocateZeroPool (sizeof (DRIVER_IMAGE_INFO));\r
- ASSERT (DriverImageInfo != NULL);\r
- DriverImageInfo->Signature = DRIVER_IMAGE_INFO_SIGNATURE;\r
-\r
- DriverDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) VariableIndex;\r
- DriverImageInfo->DriverImagePath = DuplicateDevicePath (DriverDevicePath);\r
- VariableIndex = VariableIndex + GetDevicePathSize (DriverDevicePath);\r
- //\r
- // Align the VariableIndex since the driver image device path may not be aligned, refer to the SaveOverridesMapping()\r
- //\r
- VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1));\r
-\r
- InsertTailList (&OverrideItem->DriverInfoList, &DriverImageInfo->Link);\r
- }\r
- InsertTailList (MappingDataBase, &OverrideItem->Link);\r
- }\r
-\r
- FreePool (VariableBuffer);\r
- if (Corrupted) {\r
- FreeMappingDatabase (MappingDataBase);\r
- return EFI_VOLUME_CORRUPTED;\r
- }\r
-\r
- //\r
- // If there are additional variables (PlatDriOver1, PlatDriOver2, PlatDriOver3.....), get them.\r
- // NotEnd indicates whether current variable is the end variable.\r
- //\r
- if (NotEnd != 0) {\r
- UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver%d", VariableNum++);\r
- VariableBuffer = GetVariableAndSize (OverrideVariableName, &gEfiOverrideVariableGuid, &BufferSize);\r
- ASSERT ((UINTN) VariableBuffer % sizeof(UINTN) == 0);\r
- if (VariableBuffer == NULL) {\r
- FreeMappingDatabase (MappingDataBase);\r
- return EFI_VOLUME_CORRUPTED;\r
- }\r
- }\r
-\r
- } while (NotEnd != 0);\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Calculate the needed size in NV variable for recording a specific PLATFORM_OVERRIDE_ITEM info.\r
-\r
- @param OverrideItemListIndex Pointer to the list of a specific PLATFORM_OVERRIDE_ITEM\r
-\r
- @return The needed size number\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-GetOneItemNeededSize (\r
- IN LIST_ENTRY *OverrideItemListIndex\r
- )\r
-{\r
- UINTN NeededSize;\r
- PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
- LIST_ENTRY *ImageInfoListIndex;\r
- DRIVER_IMAGE_INFO *DriverImageInfo;\r
- UINTN DevicePathSize;\r
-\r
- NeededSize = 0;\r
- OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE);\r
- NeededSize += sizeof (UINT32); //UINT32 SIGNATURE;\r
- NeededSize += sizeof (UINT32); //UINT32 DriverNum;\r
- DevicePathSize = GetDevicePathSize (OverrideItem->ControllerDevicePath);\r
- NeededSize += DevicePathSize; // ControllerDevicePath\r
- //\r
- // Align the controller device path\r
- //\r
- NeededSize += ((sizeof(UINT32) - DevicePathSize) & (sizeof(UINT32) - 1));\r
- //\r
- // Traverse the Driver Info List of this Override Item\r
- //\r
- ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
- while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
- DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
- DevicePathSize = GetDevicePathSize (DriverImageInfo->DriverImagePath);\r
- NeededSize += DevicePathSize; //DriverDevicePath\r
- //\r
- // Align the driver image device path\r
- //\r
- NeededSize += ((sizeof(UINT32) - DevicePathSize) & (sizeof(UINT32) - 1));\r
- ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
- }\r
-\r
- return NeededSize;\r
-}\r
-\r
-/**\r
- Deletes all environment variable(s) that contain the override mappings from Controller Device Path to\r
- a set of Driver Device Paths.\r
-\r
- @retval EFI_SUCCESS Delete all variable(s) successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DeleteOverridesVariables (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- VOID *VariableBuffer;\r
- UINTN VariableNum;\r
- UINTN BufferSize;\r
- UINTN Index;\r
- CHAR16 OverrideVariableName[40];\r
-\r
- //\r
- // Get environment variable(s) number\r
- //\r
- VariableNum = 0;\r
- VariableBuffer = GetVariableAndSize (L"PlatDriOver", &gEfiOverrideVariableGuid, &BufferSize);\r
- VariableNum++;\r
- if (VariableBuffer == NULL) {\r
- return EFI_NOT_FOUND;\r
- }\r
- //\r
- // Check NotEnd to get all PlatDriOverX variable(s)\r
- //\r
- while ((*(UINT32*)VariableBuffer) != 0) {\r
- UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver%d", VariableNum);\r
- VariableBuffer = GetVariableAndSize (OverrideVariableName, &gEfiOverrideVariableGuid, &BufferSize);\r
- VariableNum++;\r
- ASSERT (VariableBuffer != NULL);\r
- }\r
-\r
- //\r
- // Delete PlatDriOver and all additional variables, if exist.\r
- //\r
- Status = gRT->SetVariable (\r
- L"PlatDriOver",\r
- &gEfiOverrideVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- 0,\r
- NULL\r
- );\r
- ASSERT (!EFI_ERROR (Status));\r
- for (Index = 1; Index < VariableNum; Index++) {\r
- UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver%d", Index);\r
- Status = gRT->SetVariable (\r
- OverrideVariableName,\r
- &gEfiOverrideVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- 0,\r
- NULL\r
- );\r
- ASSERT (!EFI_ERROR (Status));\r
- }\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Save the memory mapping database into NV environment variable(s).\r
-\r
- @param MappingDataBase Mapping database list entry pointer\r
-\r
- @retval EFI_SUCCESS Save memory mapping database successfully\r
- @retval EFI_INVALID_PARAMETER MappingDataBase pointer is null\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SaveOverridesMapping (\r
- IN LIST_ENTRY *MappingDataBase\r
- )\r
-{\r
- EFI_STATUS Status;\r
- VOID *VariableBuffer;\r
- UINT8 *VariableIndex;\r
- UINTN NumIndex;\r
- CHAR16 OverrideVariableName[40];\r
- UINT32 NotEnd;\r
- PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
- DRIVER_IMAGE_INFO *DriverImageInfo;\r
- LIST_ENTRY *OverrideItemListIndex;\r
- LIST_ENTRY *ItemIndex;\r
- LIST_ENTRY *ImageInfoListIndex;\r
- UINTN VariableNeededSize;\r
- UINT64 MaximumVariableStorageSize;\r
- UINT64 RemainingVariableStorageSize;\r
- UINT64 MaximumVariableSize;\r
- UINTN OneItemNeededSize;\r
-\r
- if (MappingDataBase == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (IsListEmpty (MappingDataBase)) {\r
- Status = DeleteOverridesVariables ();\r
- ASSERT_EFI_ERROR (Status);\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Get the the maximum size of an individual EFI variable in current system\r
- //\r
- gRT->QueryVariableInfo (\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- &MaximumVariableStorageSize,\r
- &RemainingVariableStorageSize,\r
- &MaximumVariableSize\r
- );\r
-\r
- NumIndex = 0;\r
- OverrideItemListIndex = GetFirstNode (MappingDataBase);\r
- while (!IsNull (MappingDataBase, OverrideItemListIndex)) {\r
- //\r
- // Try to find the most proper variable size which <= MaximumVariableSize,\r
- // but can contain mapping info as much as possible\r
- //\r
- VariableNeededSize = sizeof (UINT32); // NotEnd;\r
- ItemIndex = OverrideItemListIndex;\r
- NotEnd = FALSE;\r
- //\r
- // Traverse all PLATFORM_OVERRIDE_ITEMs and get the total size.\r
- //\r
- while (!IsNull (MappingDataBase, ItemIndex)) {\r
- OneItemNeededSize = GetOneItemNeededSize (ItemIndex);\r
- //\r
- // If the total size exceeds the MaximumVariableSize, then we must use\r
- // multiple variables.\r
- //\r
- if ((VariableNeededSize +\r
- OneItemNeededSize +\r
- sizeof (VARIABLE_HEADER) +\r
- StrSize (L"PlatDriOver ")\r
- ) >= MaximumVariableSize\r
- ) {\r
- NotEnd = TRUE;\r
- break;\r
- }\r
-\r
- VariableNeededSize += OneItemNeededSize;\r
- ItemIndex = GetNextNode (MappingDataBase, ItemIndex);\r
- }\r
-\r
- if (NotEnd != 0) {\r
- if (VariableNeededSize == sizeof (UINT32)) {\r
- //\r
- // If an individual EFI variable cannot contain a single Item, return error\r
- //\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- }\r
-\r
- //\r
- // VariableNeededSize is the most proper variable size, allocate variable buffer\r
- // ItemIndex now points to the next PLATFORM_OVERRIDE_ITEM which is not covered by VariableNeededSize\r
- //\r
- VariableBuffer = AllocateZeroPool (VariableNeededSize);\r
- ASSERT (VariableBuffer != NULL);\r
- ASSERT ((UINTN) VariableBuffer % sizeof(UINTN) == 0);\r
-\r
- //\r
- // Fill the variable buffer according to MappingDataBase\r
- //\r
- VariableIndex = VariableBuffer;\r
- *(UINT32 *) VariableIndex = NotEnd;\r
- VariableIndex += sizeof (UINT32); // pass NotEnd\r
- //\r
- // ItemIndex points to the next PLATFORM_OVERRIDE_ITEM which is not covered by VariableNeededSize\r
- //\r
- while (OverrideItemListIndex != ItemIndex){\r
- *(UINT32 *) VariableIndex = PLATFORM_OVERRIDE_ITEM_SIGNATURE;\r
- VariableIndex += sizeof (UINT32); // pass SIGNATURE\r
-\r
- OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE);\r
- *(UINT32 *) VariableIndex = OverrideItem->DriverInfoNum;\r
- VariableIndex += sizeof (UINT32); // pass DriverNum\r
-\r
- CopyMem (VariableIndex, OverrideItem->ControllerDevicePath, GetDevicePathSize (OverrideItem->ControllerDevicePath));\r
- VariableIndex += GetDevicePathSize (OverrideItem->ControllerDevicePath); // pass ControllerDevicePath\r
-\r
- //\r
- // Align the VariableIndex since the controller device path may not be aligned\r
- //\r
- VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1));\r
- //\r
- // Save the Driver Info List of this PLATFORM_OVERRIDE_ITEM\r
- //\r
- ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
- while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
- DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
- CopyMem (VariableIndex, DriverImageInfo->DriverImagePath, GetDevicePathSize (DriverImageInfo->DriverImagePath));\r
- VariableIndex += GetDevicePathSize (DriverImageInfo->DriverImagePath); // pass DriverImageDevicePath\r
- //\r
- // Align the VariableIndex since the driver image device path may not be aligned\r
- //\r
- VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1));\r
- ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
- }\r
-\r
- OverrideItemListIndex = GetNextNode (MappingDataBase, OverrideItemListIndex);\r
- }\r
-\r
- ASSERT (((UINTN)VariableIndex - (UINTN)VariableBuffer) == VariableNeededSize);\r
-\r
- if (NumIndex == 0) {\r
- UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver");\r
- } else {\r
- UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver%d", NumIndex );\r
- }\r
-\r
- Status = gRT->SetVariable (\r
- OverrideVariableName,\r
- &gEfiOverrideVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- VariableNeededSize,\r
- VariableBuffer\r
- );\r
- ASSERT (!EFI_ERROR(Status));\r
-\r
- NumIndex ++;\r
- FreePool (VariableBuffer);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Get the first Binding protocol which has the specific image handle.\r
-\r
- @param ImageHandle The Image handle\r
- @param BindingHandle The BindingHandle of the found Driver Binding protocol.\r
- If Binding protocol is not found, it is set to NULL. \r
-\r
- @return Pointer into the Binding Protocol interface\r
- @retval NULL The paramter is not valid or the binding protocol is not found.\r
-\r
-**/\r
-EFI_DRIVER_BINDING_PROTOCOL *\r
-EFIAPI\r
-GetBindingProtocolFromImageHandle (\r
- IN EFI_HANDLE ImageHandle,\r
- OUT EFI_HANDLE *BindingHandle\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- UINTN DriverBindingHandleCount;\r
- EFI_HANDLE *DriverBindingHandleBuffer;\r
- EFI_DRIVER_BINDING_PROTOCOL *DriverBindingInterface;\r
-\r
- if (BindingHandle == NULL || ImageHandle == NULL) {\r
- return NULL;\r
- }\r
- //\r
- // Get all drivers which support driver binding protocol\r
- //\r
- DriverBindingHandleCount = 0;\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiDriverBindingProtocolGuid,\r
- NULL,\r
- &DriverBindingHandleCount,\r
- &DriverBindingHandleBuffer\r
- );\r
- if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {\r
- return NULL;\r
- }\r
-\r
- for (Index = 0; Index < DriverBindingHandleCount; Index++) {\r
- DriverBindingInterface = NULL;\r
- Status = gBS->OpenProtocol (\r
- DriverBindingHandleBuffer[Index],\r
- &gEfiDriverBindingProtocolGuid,\r
- (VOID **) &DriverBindingInterface,\r
- NULL,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- if (DriverBindingInterface->ImageHandle == ImageHandle) {\r
- *BindingHandle = DriverBindingHandleBuffer[Index];\r
- FreePool (DriverBindingHandleBuffer);\r
- return DriverBindingInterface;\r
- }\r
- }\r
-\r
- //\r
- // If no Driver Binding Protocol instance is found\r
- //\r
- FreePool (DriverBindingHandleBuffer);\r
- *BindingHandle = NULL;\r
- return NULL;\r
-}\r
-\r
-/**\r
- Return the current TPL.\r
-\r
- @return Current TPL\r
-\r
-**/\r
-EFI_TPL\r
-GetCurrentTpl (\r
- VOID\r
- )\r
-{\r
- EFI_TPL Tpl;\r
-\r
- Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
- gBS->RestoreTPL (Tpl);\r
-\r
- return Tpl;\r
-}\r
-\r
-\r
-/**\r
- Retrieves the image handle of the platform override driver for a controller in\r
- the system from the memory mapping database.\r
-\r
- @param ControllerHandle The device handle of the controller to check if\r
- a driver override exists.\r
- @param DriverImageHandle On input, the previously returnd driver image handle.\r
- On output, a pointer to the next driver handle.\r
- Passing in a pointer to NULL, will return the\r
- first driver handle for ControllerHandle.\r
- @param MappingDataBase Mapping database list entry pointer\r
- @param CallerImageHandle The caller driver's image handle, for\r
- UpdateFvFileDevicePath use.\r
-\r
- @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is not\r
- a valid handle. Or DriverImagePath is not a\r
- device path that was returned on a previous call\r
- to GetDriverPath().\r
- @retval EFI_NOT_FOUND A driver override for ControllerHandle was not\r
- found.\r
- @retval EFI_UNSUPPORTED The operation is not supported.\r
- @retval EFI_SUCCESS The driver override for ControllerHandle was\r
- returned in DriverImagePath.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetDriverFromMapping (\r
- IN EFI_HANDLE ControllerHandle,\r
- IN OUT EFI_HANDLE *DriverImageHandle,\r
- IN LIST_ENTRY *MappingDataBase,\r
- IN EFI_HANDLE CallerImageHandle\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;\r
- BOOLEAN ControllerFound;\r
- BOOLEAN ImageFound;\r
- EFI_HANDLE *ImageHandleBuffer;\r
- UINTN ImageHandleCount;\r
- UINTN Index;\r
- EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
- EFI_HANDLE DriverBindingHandle;\r
- BOOLEAN FoundLastReturned;\r
- PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
- DRIVER_IMAGE_INFO *DriverImageInfo;\r
- LIST_ENTRY *OverrideItemListIndex;\r
- LIST_ENTRY *ImageInfoListIndex;\r
- EFI_DEVICE_PATH_PROTOCOL *TempDriverImagePath;\r
- EFI_HANDLE ImageHandle;\r
- EFI_HANDLE Handle;\r
- EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;\r
- EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;\r
- UINTN DevicePathSize;\r
-\r
- //\r
- // Check that ControllerHandle is a valid handle\r
- //\r
- if (ControllerHandle == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Get the device path of ControllerHandle\r
- //\r
- Status = gBS->HandleProtocol (\r
- ControllerHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &ControllerDevicePath\r
- );\r
- if (EFI_ERROR (Status) || ControllerDevicePath == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Search ControllerDevicePath in MappingDataBase\r
- //\r
- OverrideItem = NULL;\r
- ControllerFound = FALSE;\r
- DevicePathSize = GetDevicePathSize (ControllerDevicePath);\r
-\r
- OverrideItemListIndex = GetFirstNode (MappingDataBase);\r
- while (!IsNull (MappingDataBase, OverrideItemListIndex)) {\r
- OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE);\r
- if (DevicePathSize == GetDevicePathSize (OverrideItem->ControllerDevicePath)) {\r
- if (CompareMem (\r
- ControllerDevicePath,\r
- OverrideItem->ControllerDevicePath,\r
- DevicePathSize\r
- ) == 0\r
- ) {\r
- ControllerFound = TRUE;\r
- break;\r
- }\r
- }\r
- OverrideItemListIndex = GetNextNode (MappingDataBase, OverrideItemListIndex);\r
- }\r
-\r
- if (!ControllerFound) {\r
- return EFI_NOT_FOUND;\r
- }\r
- //\r
- // Passing in a pointer to NULL, will return the first driver device path for ControllerHandle.\r
- // Check whether the driverImagePath is not a device path that was returned on a previous call to GetDriverPath().\r
- //\r
- if (*DriverImageHandle != NULL) {\r
- if (*DriverImageHandle != OverrideItem->LastReturnedImageHandle) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- //\r
- // The GetDriverPath() may be called recursively, because it use ConnectDevicePath() internally,\r
- // so should check whether there is a dead loop.\r
- // Here use a controller device path stack to record all processed controller device path during a GetDriverPath() call,\r
- // and check the controller device path whether appear again during the GetDriverPath() call.\r
- //\r
- if (CheckExistInStack (OverrideItem->ControllerDevicePath)) {\r
- //\r
- // There is a dependecy dead loop if the ControllerDevicePath appear in stack twice\r
- //\r
- return EFI_UNSUPPORTED;\r
- }\r
- PushDevPathStack (OverrideItem->ControllerDevicePath);\r
-\r
- //\r
- // Check every override driver, try to load and start them\r
- //\r
- ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
- while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
- DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
- if (DriverImageInfo->ImageHandle == NULL) {\r
- //\r
- // Skip if the image is unloadable or unstartable\r
- //\r
- if ((!DriverImageInfo->UnLoadable) && ((!DriverImageInfo->UnStartable))) {\r
- TempDriverImagePath = DriverImageInfo->DriverImagePath;\r
- //\r
- // If the image device path contains an FV node, check the FV file device path is valid.\r
- // If it is invalid, try to return the valid device path.\r
- // FV address maybe changes for memory layout adjust from time to time,\r
- // use this funciton could promise the FV file device path is right.\r
- //\r
- Status = UpdateFvFileDevicePath (&TempDriverImagePath, NULL, CallerImageHandle);\r
- if (!EFI_ERROR (Status)) {\r
- FreePool (DriverImageInfo->DriverImagePath);\r
- DriverImageInfo->DriverImagePath = TempDriverImagePath;\r
- }\r
- //\r
- // Get all Loaded Image protocol to check whether the driver image has been loaded and started\r
- //\r
- ImageFound = FALSE;\r
- ImageHandleCount = 0;\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiLoadedImageProtocolGuid,\r
- NULL,\r
- &ImageHandleCount,\r
- &ImageHandleBuffer\r
- );\r
- if (EFI_ERROR (Status) || (ImageHandleCount == 0)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- for(Index = 0; Index < ImageHandleCount; Index ++) {\r
- //\r
- // Get the EFI Loaded Image Device Path Protocol\r
- //\r
- LoadedImageDevicePath = NULL;\r
- Status = gBS->HandleProtocol (\r
- ImageHandleBuffer[Index],\r
- &gEfiLoadedImageDevicePathProtocolGuid,\r
- (VOID **) &LoadedImageDevicePath\r
- );\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Maybe not all EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL existed.\r
- //\r
- continue;\r
- }\r
-\r
- DevicePathSize = GetDevicePathSize (DriverImageInfo->DriverImagePath);\r
- if (DevicePathSize == GetDevicePathSize (LoadedImageDevicePath)) {\r
- if (CompareMem (\r
- DriverImageInfo->DriverImagePath,\r
- LoadedImageDevicePath,\r
- GetDevicePathSize (LoadedImageDevicePath)\r
- ) == 0\r
- ) {\r
- ImageFound = TRUE;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- if (ImageFound) {\r
- //\r
- // Find its related driver binding protocol\r
- // Driver binding handle may be different with its driver's Image Handle.\r
- //\r
- DriverBindingHandle = NULL;\r
- DriverBinding = GetBindingProtocolFromImageHandle (\r
- ImageHandleBuffer[Index],\r
- &DriverBindingHandle\r
- );\r
- ASSERT (DriverBinding != NULL);\r
- DriverImageInfo->ImageHandle = ImageHandleBuffer[Index];\r
- } else if (GetCurrentTpl() <= TPL_CALLBACK){\r
- //\r
- // The driver image has not been loaded and started. Try to load and start it now.\r
- // Try to connect all device in the driver image path.\r
- //\r
- // Note: LoadImage() and StartImage() should be called under CALLBACK TPL in theory, but\r
- // since many device need to be connected in CALLBACK level environment( e.g. Usb devices )\r
- // and the Fat and Patition driver can endure executing in CALLBACK level in fact, so here permit\r
- // to use LoadImage() and StartImage() in CALLBACK TPL.\r
- //\r
- Status = ConnectDevicePath (DriverImageInfo->DriverImagePath);\r
- //\r
- // check whether it points to a PCI Option Rom image,\r
- // and try to use bus override protocol to get its first option rom image driver\r
- //\r
- TempDriverImagePath = DriverImageInfo->DriverImagePath;\r
- gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &TempDriverImagePath, &Handle);\r
- //\r
- // Get the Bus Specific Driver Override Protocol instance on the Controller Handle\r
- //\r
- Status = gBS->HandleProtocol(\r
- Handle,\r
- &gEfiBusSpecificDriverOverrideProtocolGuid,\r
- (VOID **) &BusSpecificDriverOverride\r
- );\r
- if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) {\r
- ImageHandle = NULL;\r
- Status = BusSpecificDriverOverride->GetDriver (\r
- BusSpecificDriverOverride,\r
- &ImageHandle\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Find its related driver binding protocol\r
- // Driver binding handle may be different with its driver's Image handle\r
- //\r
- DriverBindingHandle = NULL;\r
- DriverBinding = GetBindingProtocolFromImageHandle (\r
- ImageHandle,\r
- &DriverBindingHandle\r
- );\r
- ASSERT (DriverBinding != NULL);\r
- DriverImageInfo->ImageHandle = ImageHandle;\r
- }\r
- }\r
- //\r
- // Skip if any device cannot be connected now, future passes through GetDriver() may be able to load that driver.\r
- // Only file path media or FwVol Device Path Node remain if all device is connected\r
- //\r
- TempDriverImagePath = DriverImageInfo->DriverImagePath;\r
- gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &TempDriverImagePath, &Handle);\r
- if (((DevicePathType (TempDriverImagePath) == MEDIA_DEVICE_PATH) &&\r
- (DevicePathSubType (TempDriverImagePath) == MEDIA_FILEPATH_DP)) ||\r
- (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) TempDriverImagePath) != NULL)\r
- ) {\r
- //\r
- // Try to load the driver\r
- //\r
- TempDriverImagePath = DriverImageInfo->DriverImagePath;\r
- Status = gBS->LoadImage (\r
- FALSE,\r
- CallerImageHandle,\r
- TempDriverImagePath,\r
- NULL,\r
- 0,\r
- &ImageHandle\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Try to start the driver\r
- //\r
- Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
- if (EFI_ERROR (Status)){\r
- DriverImageInfo->UnStartable = TRUE;\r
- DriverImageInfo->ImageHandle = NULL;\r
- } else {\r
- //\r
- // Find its related driver binding protocol\r
- // Driver binding handle may be different with its driver's Image handle\r
- //\r
- DriverBindingHandle = NULL;\r
- DriverBinding = GetBindingProtocolFromImageHandle (\r
- ImageHandle,\r
- &DriverBindingHandle\r
- );\r
- ASSERT (DriverBinding != NULL);\r
- DriverImageInfo->ImageHandle = ImageHandle;\r
- }\r
- } else {\r
- DriverImageInfo->UnLoadable = TRUE;\r
- DriverImageInfo->ImageHandle = NULL;\r
- }\r
- }\r
- }\r
- FreePool (ImageHandleBuffer);\r
- }\r
- }\r
- ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
- }\r
- //\r
- // Finish try to load and start the override driver of a controller, popup the controller's device path\r
- //\r
- PopDevPathStack (NULL);\r
-\r
- //\r
- // return the DriverImageHandle for ControllerHandle\r
- //\r
- FoundLastReturned = FALSE;\r
- ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
- while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
- DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
- if (DriverImageInfo->ImageHandle != NULL) {\r
- if ((*DriverImageHandle == NULL) || FoundLastReturned) {\r
- //\r
- // If DriverImageHandle is NULL, then we just need to return the first driver.\r
- // If FoundLastReturned, this means we have just encountered the previously returned driver.\r
- // For both cases, we just return the image handle of this driver.\r
- //\r
- OverrideItem->LastReturnedImageHandle = DriverImageInfo->ImageHandle;\r
- *DriverImageHandle = DriverImageInfo->ImageHandle;\r
- return EFI_SUCCESS;\r
- } else if (*DriverImageHandle == DriverImageInfo->ImageHandle){\r
- //\r
- // We have found the previously returned driver.\r
- //\r
- FoundLastReturned = TRUE;\r
- }\r
- }\r
- ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
- }\r
-\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-\r
-/**\r
- Check mapping database whether already has the mapping info which\r
- records the input Controller to input DriverImage.\r
-\r
- @param ControllerDevicePath The controller device path is to be check.\r
- @param DriverImageDevicePath The driver image device path is to be check.\r
- @param MappingDataBase Mapping database list entry pointer\r
- @param DriverInfoNum the controller's total override driver number\r
- @param DriverImageNO The driver order number for the input DriverImage.\r
- If the DriverImageDevicePath is NULL, DriverImageNO is not set.\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerDevicePath or MappingDataBase is NULL.\r
- @retval EFI_NOT_FOUND ControllerDevicePath is not found in MappingDataBase or\r
- DriverImageDevicePath is not found in the found DriverImage Info list. \r
- @retval EFI_SUCCESS The controller's total override driver number and \r
- input DriverImage's order number is correctly return.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CheckMapping (\r
- IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath OPTIONAL,\r
- IN LIST_ENTRY *MappingDataBase,\r
- OUT UINT32 *DriverInfoNum OPTIONAL,\r
- OUT UINT32 *DriverImageNO OPTIONAL\r
- )\r
-{\r
- LIST_ENTRY *OverrideItemListIndex;\r
- PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
- LIST_ENTRY *ImageInfoListIndex;\r
- DRIVER_IMAGE_INFO *DriverImageInfo;\r
- BOOLEAN Found;\r
- UINT32 ImageNO;\r
- UINTN DevicePathSize;\r
-\r
- if (ControllerDevicePath == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- if (MappingDataBase == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Search ControllerDevicePath in MappingDataBase\r
- //\r
- Found = FALSE;\r
- OverrideItem = NULL;\r
- OverrideItemListIndex = GetFirstNode (MappingDataBase);\r
- while (!IsNull (MappingDataBase, OverrideItemListIndex)) {\r
- OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE);\r
- DevicePathSize = GetDevicePathSize (ControllerDevicePath);\r
- if (DevicePathSize == GetDevicePathSize (OverrideItem->ControllerDevicePath)) {\r
- if (CompareMem (\r
- ControllerDevicePath,\r
- OverrideItem->ControllerDevicePath,\r
- DevicePathSize\r
- ) == 0\r
- ) {\r
- Found = TRUE;\r
- break;\r
- }\r
- }\r
- OverrideItemListIndex = GetNextNode (MappingDataBase, OverrideItemListIndex);\r
- }\r
-\r
- if (!Found) {\r
- //\r
- // ControllerDevicePath is not in MappingDataBase\r
- //\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- ASSERT (OverrideItem->DriverInfoNum != 0);\r
- if (DriverInfoNum != NULL) {\r
- *DriverInfoNum = OverrideItem->DriverInfoNum;\r
- }\r
-\r
- //\r
- // If DriverImageDevicePath is NULL, skip checking DriverImageDevicePath\r
- // in the controller's Driver Image Info List\r
- //\r
- if (DriverImageDevicePath == NULL) {\r
- return EFI_SUCCESS;\r
- }\r
- //\r
- // return the DriverImageHandle for ControllerHandle\r
- //\r
- ImageNO = 0;\r
- Found = FALSE;\r
- ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
- while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
- DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
- ImageNO++;\r
- DevicePathSize = GetDevicePathSize (DriverImageDevicePath);\r
- if (DevicePathSize == GetDevicePathSize (DriverImageInfo->DriverImagePath)) {\r
- if (CompareMem (\r
- DriverImageDevicePath,\r
- DriverImageInfo->DriverImagePath,\r
- GetDevicePathSize (DriverImageInfo->DriverImagePath)\r
- ) == 0\r
- ) {\r
- Found = TRUE;\r
- break;\r
- }\r
- }\r
- ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
- }\r
-\r
- if (!Found) {\r
- //\r
- // DriverImageDevicePath is not found in the controller's Driver Image Info List\r
- //\r
- return EFI_NOT_FOUND;\r
- } else {\r
- if (DriverImageNO != NULL) {\r
- *DriverImageNO = ImageNO;\r
- }\r
- return EFI_SUCCESS;\r
- }\r
-}\r
-\r
-\r
-/**\r
- Insert a driver image as a controller's override driver into the mapping database.\r
- The driver image's order number is indicated by DriverImageNO.\r
-\r
- @param ControllerDevicePath The controller device path need to add a\r
- override driver image item\r
- @param DriverImageDevicePath The driver image device path need to be insert\r
- @param MappingDataBase Mapping database list entry pointer\r
- @param DriverImageNO The inserted order number. If this number is taken, \r
- the larger available number will be used.\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerDevicePath is NULL, or DriverImageDevicePath is NULL\r
- or MappingDataBase is NULL\r
- @retval EFI_ALREADY_STARTED The input Controller to input DriverImage has been \r
- recorded into the mapping database.\r
- @retval EFI_SUCCESS The Controller and DriverImage are inserted into \r
- the mapping database successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InsertDriverImage (\r
- IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath,\r
- IN LIST_ENTRY *MappingDataBase,\r
- IN UINT32 DriverImageNO\r
- )\r
-{\r
- EFI_STATUS Status;\r
- LIST_ENTRY *OverrideItemListIndex;\r
- PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
- LIST_ENTRY *ImageInfoListIndex;\r
- DRIVER_IMAGE_INFO *DriverImageInfo;\r
- BOOLEAN Found;\r
- UINT32 ImageNO;\r
- UINTN DevicePathSize;\r
-\r
- if (ControllerDevicePath == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- if (DriverImageDevicePath == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- if (MappingDataBase == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // If the driver is already in the controller's Driver Image Info List,\r
- // just return EFI_ALREADY_STARTED.\r
- //\r
- Status = CheckMapping (\r
- ControllerDevicePath,\r
- DriverImageDevicePath,\r
- MappingDataBase,\r
- NULL,\r
- NULL\r
- );\r
- if (Status == EFI_SUCCESS) {\r
- return EFI_ALREADY_STARTED;\r
- }\r
-\r
- //\r
- // Search the input ControllerDevicePath in MappingDataBase\r
- //\r
- Found = FALSE;\r
- OverrideItem = NULL;\r
- OverrideItemListIndex = GetFirstNode (MappingDataBase);\r
- while (!IsNull (MappingDataBase, OverrideItemListIndex)) {\r
- OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE);\r
- DevicePathSize = GetDevicePathSize (ControllerDevicePath);\r
- if (DevicePathSize == GetDevicePathSize (OverrideItem->ControllerDevicePath)) {\r
- if (CompareMem (\r
- ControllerDevicePath,\r
- OverrideItem->ControllerDevicePath,\r
- DevicePathSize\r
- ) == 0\r
- ) {\r
- Found = TRUE;\r
- break;\r
- }\r
- }\r
- OverrideItemListIndex = GetNextNode (MappingDataBase, OverrideItemListIndex);\r
- }\r
- //\r
- // If cannot find, this is a new controller item\r
- // Add the Controller related PLATFORM_OVERRIDE_ITEM structrue in mapping data base\r
- //\r
- if (!Found) {\r
- OverrideItem = AllocateZeroPool (sizeof (PLATFORM_OVERRIDE_ITEM));\r
- ASSERT (OverrideItem != NULL);\r
- OverrideItem->Signature = PLATFORM_OVERRIDE_ITEM_SIGNATURE;\r
- OverrideItem->ControllerDevicePath = DuplicateDevicePath (ControllerDevicePath);\r
- InitializeListHead (&OverrideItem->DriverInfoList);\r
- InsertTailList (MappingDataBase, &OverrideItem->Link);\r
- }\r
-\r
- //\r
- // Prepare the driver image related DRIVER_IMAGE_INFO structure.\r
- //\r
- DriverImageInfo = AllocateZeroPool (sizeof (DRIVER_IMAGE_INFO));\r
- ASSERT (DriverImageInfo != NULL);\r
- DriverImageInfo->Signature = DRIVER_IMAGE_INFO_SIGNATURE;\r
- DriverImageInfo->DriverImagePath = DuplicateDevicePath (DriverImageDevicePath);\r
- //\r
- // Find the driver image wanted order location\r
- //\r
- ImageNO = 0;\r
- Found = FALSE;\r
- ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
- while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
- if (ImageNO == (DriverImageNO - 1)) {\r
- //\r
- // find the wanted order location, insert it\r
- //\r
- InsertTailList (ImageInfoListIndex, &DriverImageInfo->Link);\r
- OverrideItem->DriverInfoNum ++;\r
- Found = TRUE;\r
- break;\r
- }\r
- ImageNO++;\r
- ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
- }\r
-\r
- if (!Found) {\r
- //\r
- // if not find the wanted order location, add it as last item of the controller mapping item\r
- //\r
- InsertTailList (&OverrideItem->DriverInfoList, &DriverImageInfo->Link);\r
- OverrideItem->DriverInfoNum ++;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Delete a controller's override driver from the mapping database.\r
-\r
- @param ControllerDevicePath The controller device path will be deleted \r
- when all drivers images on it are removed.\r
- @param DriverImageDevicePath The driver image device path will be delete.\r
- If NULL, all driver image will be delete.\r
- @param MappingDataBase Mapping database list entry pointer\r
-\r
- @retval EFI_INVALID_PARAMETER ControllerDevicePath is NULL, or MappingDataBase is NULL\r
- @retval EFI_NOT_FOUND ControllerDevicePath is not found in MappingDataBase or\r
- DriverImageDevicePath is not found in the found DriverImage Info list. \r
- @retval EFI_SUCCESS Delete the specified driver successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DeleteDriverImage (\r
- IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath,\r
- IN LIST_ENTRY *MappingDataBase\r
- )\r
-{\r
- EFI_STATUS Status;\r
- LIST_ENTRY *OverrideItemListIndex;\r
- PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
- LIST_ENTRY *ImageInfoListIndex;\r
- DRIVER_IMAGE_INFO *DriverImageInfo;\r
- BOOLEAN Found;\r
- UINTN DevicePathSize;\r
-\r
- if (ControllerDevicePath == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (MappingDataBase == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // If ControllerDevicePath is not found in mapping database, return EFI_NOT_FOUND.\r
- //\r
- Status = CheckMapping (\r
- ControllerDevicePath,\r
- DriverImageDevicePath,\r
- MappingDataBase,\r
- NULL,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Search ControllerDevicePath in MappingDataBase\r
- //\r
- Found = FALSE;\r
- OverrideItem = NULL;\r
- OverrideItemListIndex = GetFirstNode (MappingDataBase);\r
- while (!IsNull (MappingDataBase, OverrideItemListIndex)) {\r
- OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE);\r
- DevicePathSize = GetDevicePathSize (ControllerDevicePath);\r
- if (DevicePathSize == GetDevicePathSize (OverrideItem->ControllerDevicePath)) {\r
- if (CompareMem (\r
- ControllerDevicePath,\r
- OverrideItem->ControllerDevicePath,\r
- DevicePathSize\r
- ) == 0\r
- ) {\r
- Found = TRUE;\r
- break;\r
- }\r
- }\r
- OverrideItemListIndex = GetNextNode (MappingDataBase, OverrideItemListIndex);\r
- }\r
-\r
- ASSERT (Found);\r
- ASSERT (OverrideItem->DriverInfoNum != 0);\r
-\r
- Found = FALSE;\r
- ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
- while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
- DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
- ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
- if (DriverImageDevicePath != NULL) {\r
- //\r
- // Search for the specified DriverImageDevicePath and remove it, then break.\r
- //\r
- DevicePathSize = GetDevicePathSize (DriverImageDevicePath);\r
- if (DevicePathSize == GetDevicePathSize (DriverImageInfo->DriverImagePath)) {\r
- if (CompareMem (\r
- DriverImageDevicePath,\r
- DriverImageInfo->DriverImagePath,\r
- GetDevicePathSize (DriverImageInfo->DriverImagePath)\r
- ) == 0\r
- ) {\r
- Found = TRUE;\r
- FreePool(DriverImageInfo->DriverImagePath);\r
- RemoveEntryList (&DriverImageInfo->Link);\r
- OverrideItem->DriverInfoNum --;\r
- break;\r
- }\r
- }\r
- } else {\r
- //\r
- // Remove all existing driver image info entries, so no break here.\r
- //\r
- Found = TRUE;\r
- FreePool(DriverImageInfo->DriverImagePath);\r
- RemoveEntryList (&DriverImageInfo->Link);\r
- OverrideItem->DriverInfoNum --;\r
- }\r
- }\r
-\r
- //\r
- // Confirm all driver image info entries have been removed,\r
- // if DriverImageDevicePath is NULL.\r
- //\r
- if (DriverImageDevicePath == NULL) {\r
- ASSERT (OverrideItem->DriverInfoNum == 0);\r
- }\r
- //\r
- // If Override Item has no driver image info entry, then delete this item.\r
- //\r
- if (OverrideItem->DriverInfoNum == 0) {\r
- FreePool(OverrideItem->ControllerDevicePath);\r
- RemoveEntryList (&OverrideItem->Link);\r
- FreePool (OverrideItem);\r
- }\r
-\r
- if (!Found) {\r
- //\r
- // DriverImageDevicePath is not NULL and cannot be found in the controller's\r
- // driver image info list.\r
- //\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Push a controller device path into a globle device path list.\r
-\r
- @param DevicePath The controller device path to push into stack\r
-\r
- @retval EFI_SUCCESS Device path successfully pushed into the stack.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PushDevPathStack (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- )\r
-{\r
- DEVICE_PATH_STACK_ITEM *DevicePathStackItem;\r
-\r
- DevicePathStackItem = AllocateZeroPool (sizeof (DEVICE_PATH_STACK_ITEM));\r
- ASSERT (DevicePathStackItem != NULL);\r
- DevicePathStackItem->Signature = DEVICE_PATH_STACK_ITEM_SIGNATURE;\r
- DevicePathStackItem->DevicePath = DuplicateDevicePath (DevicePath);\r
- InsertTailList (&mDevicePathStack, &DevicePathStackItem->Link);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Pop a controller device path from a globle device path list\r
-\r
- @param DevicePath The controller device path popped from stack\r
-\r
- @retval EFI_SUCCESS Controller device path successfully popped.\r
- @retval EFI_NOT_FOUND Stack is empty.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PopDevPathStack (\r
- OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
- )\r
-{\r
- DEVICE_PATH_STACK_ITEM *DevicePathStackItem;\r
- LIST_ENTRY *ItemListIndex;\r
-\r
- ItemListIndex = mDevicePathStack.BackLink;\r
- //\r
- // Check if the stack is empty\r
- //\r
- if (ItemListIndex != &mDevicePathStack){\r
- DevicePathStackItem = CR(ItemListIndex, DEVICE_PATH_STACK_ITEM, Link, DEVICE_PATH_STACK_ITEM_SIGNATURE);\r
- if (DevicePath != NULL) {\r
- *DevicePath = DuplicateDevicePath (DevicePathStackItem->DevicePath);\r
- }\r
- FreePool (DevicePathStackItem->DevicePath);\r
- RemoveEntryList (&DevicePathStackItem->Link);\r
- FreePool (DevicePathStackItem);\r
- return EFI_SUCCESS;\r
- }\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-\r
-/**\r
- Check whether a controller device path is in a globle device path list\r
-\r
- @param DevicePath The controller device path to check\r
-\r
- @retval TRUE DevicePath exists in the stack.\r
- @retval FALSE DevicePath does not exist in the stack.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-CheckExistInStack (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
- )\r
-{\r
- DEVICE_PATH_STACK_ITEM *DevicePathStackItem;\r
- LIST_ENTRY *ItemListIndex;\r
- UINTN DevicePathSize;\r
-\r
- ItemListIndex = mDevicePathStack.BackLink;\r
- while (ItemListIndex != &mDevicePathStack){\r
- DevicePathStackItem = CR(ItemListIndex, DEVICE_PATH_STACK_ITEM, Link, DEVICE_PATH_STACK_ITEM_SIGNATURE);\r
- DevicePathSize = GetDevicePathSize (DevicePath);\r
- if (DevicePathSize == GetDevicePathSize (DevicePathStackItem->DevicePath)) {\r
- if (CompareMem (DevicePath, DevicePathStackItem->DevicePath, DevicePathSize) == 0) {\r
- return TRUE;\r
- }\r
- }\r
- ItemListIndex = ItemListIndex->BackLink;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-\r
-/**\r
- Update the FV file device path if it is not valid.\r
-\r
- According to a file GUID, check a Fv file device path is valid. If it is invalid,\r
- try to return the valid device path.\r
- FV address maybe changes for memory layout adjust from time to time, use this funciton\r
- could promise the Fv file device path is right.\r
-\r
- @param DevicePath On input, the FV file device path to check\r
- On output, the updated valid FV file device path\r
- @param FileGuid The FV file GUID\r
- @param CallerImageHandle Image handle of the caller\r
-\r
- @retval EFI_INVALID_PARAMETER the input DevicePath or FileGuid is invalid\r
- parameter\r
- @retval EFI_UNSUPPORTED the input DevicePath does not contain FV file\r
- GUID at all\r
- @retval EFI_ALREADY_STARTED the input DevicePath has pointed to FV file, it\r
- is valid\r
- @retval EFI_SUCCESS Successfully updated the invalid DevicePath,\r
- and return the updated device path in DevicePath\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UpdateFvFileDevicePath (\r
- IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,\r
- IN EFI_GUID *FileGuid,\r
- IN EFI_HANDLE CallerImageHandle\r
- )\r
-{\r
- EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode;\r
- EFI_STATUS Status;\r
- EFI_GUID *GuidPoint;\r
- UINTN Index;\r
- UINTN FvHandleCount;\r
- EFI_HANDLE *FvHandleBuffer;\r
- EFI_FV_FILETYPE Type;\r
- UINTN Size;\r
- EFI_FV_FILE_ATTRIBUTES Attributes;\r
- UINT32 AuthenticationStatus;\r
- BOOLEAN FindFvFile;\r
- EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
- EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
- MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileNode;\r
- EFI_HANDLE FoundFvHandle;\r
- EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
- BOOLEAN HasFvNode;\r
-\r
- if (DevicePath == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (*DevicePath == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Check whether the device path points to the default the input FV file\r
- //\r
- TempDevicePath = *DevicePath;\r
- LastDeviceNode = TempDevicePath;\r
- while (!IsDevicePathEnd (TempDevicePath)) {\r
- LastDeviceNode = TempDevicePath;\r
- TempDevicePath = NextDevicePathNode (TempDevicePath);\r
- }\r
- GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode);\r
- if (GuidPoint == NULL) {\r
- //\r
- // If this option does not point to a FV file, just return EFI_UNSUPPORTED.\r
- //\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (FileGuid != NULL) {\r
- if (!CompareGuid (GuidPoint, FileGuid)) {\r
- //\r
- // If the FV file is not the input file GUID, just return EFI_UNSUPPORTED\r
- //\r
- return EFI_UNSUPPORTED;\r
- }\r
- } else {\r
- FileGuid = GuidPoint;\r
- }\r
-\r
- //\r
- // Check to see if the device path contains memory map node\r
- //\r
- TempDevicePath = *DevicePath;\r
- HasFvNode = FALSE;\r
- while (!IsDevicePathEnd (TempDevicePath)) {\r
- //\r
- // Use old Device Path\r
- //\r
- if (DevicePathType (TempDevicePath) == HARDWARE_DEVICE_PATH &&\r
- DevicePathSubType (TempDevicePath) == HW_MEMMAP_DP) {\r
- HasFvNode = TRUE;\r
- break;\r
- }\r
- TempDevicePath = NextDevicePathNode (TempDevicePath);\r
- }\r
-\r
- if (!HasFvNode) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Check whether the input Fv file device path is valid\r
- //\r
- TempDevicePath = *DevicePath;\r
- FoundFvHandle = NULL;\r
- Status = gBS->LocateDevicePath (\r
- &gEfiFirmwareVolume2ProtocolGuid,\r
- &TempDevicePath,\r
- &FoundFvHandle\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = gBS->HandleProtocol (\r
- FoundFvHandle,\r
- &gEfiFirmwareVolume2ProtocolGuid,\r
- (VOID **) &Fv\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Set FV ReadFile Buffer as NULL, only need to check whether input Fv file exist there\r
- //\r
- Status = Fv->ReadFile (\r
- Fv,\r
- FileGuid,\r
- NULL,\r
- &Size,\r
- &Type,\r
- &Attributes,\r
- &AuthenticationStatus\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- return EFI_ALREADY_STARTED;\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Look for the input wanted FV file in current FV\r
- // First, try to look for in Caller own FV. Caller and input wanted FV file usually are in the same FV\r
- //\r
- FindFvFile = FALSE;\r
- FoundFvHandle = NULL;\r
- Status = gBS->HandleProtocol (\r
- CallerImageHandle,\r
- &gEfiLoadedImageProtocolGuid,\r
- (VOID **) &LoadedImage\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = gBS->HandleProtocol (\r
- LoadedImage->DeviceHandle,\r
- &gEfiFirmwareVolume2ProtocolGuid,\r
- (VOID **) &Fv\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- Status = Fv->ReadFile (\r
- Fv,\r
- FileGuid,\r
- NULL,\r
- &Size,\r
- &Type,\r
- &Attributes,\r
- &AuthenticationStatus\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- FindFvFile = TRUE;\r
- FoundFvHandle = LoadedImage->DeviceHandle;\r
- }\r
- }\r
- }\r
- //\r
- // Second, if fail to find, try to enumerate all FV\r
- //\r
- if (!FindFvFile) {\r
- gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiFirmwareVolume2ProtocolGuid,\r
- NULL,\r
- &FvHandleCount,\r
- &FvHandleBuffer\r
- );\r
- for (Index = 0; Index < FvHandleCount; Index++) {\r
- gBS->HandleProtocol (\r
- FvHandleBuffer[Index],\r
- &gEfiFirmwareVolume2ProtocolGuid,\r
- (VOID **) &Fv\r
- );\r
-\r
- Status = Fv->ReadFile (\r
- Fv,\r
- FileGuid,\r
- NULL,\r
- &Size,\r
- &Type,\r
- &Attributes,\r
- &AuthenticationStatus\r
- );\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // Skip if input Fv file not in the FV\r
- //\r
- continue;\r
- }\r
- FindFvFile = TRUE;\r
- FoundFvHandle = FvHandleBuffer[Index];\r
- break;\r
- }\r
- }\r
-\r
- if (FindFvFile) {\r
- //\r
- // Build the shell device path\r
- //\r
- NewDevicePath = DevicePathFromHandle (FoundFvHandle);\r
- EfiInitializeFwVolDevicepathNode (&FvFileNode, FileGuid);\r
- NewDevicePath = AppendDevicePathNode (NewDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &FvFileNode);\r
- *DevicePath = NewDevicePath;\r
- return EFI_SUCCESS;\r
- }\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-\r
-/**\r
- Gets the data and size of a variable.\r
-\r
- Read the EFI variable (VendorGuid/Name) and return a dynamically allocated\r
- buffer, and the size of the buffer. If failure return NULL.\r
-\r
- @param Name String part of EFI variable name\r
- @param VendorGuid GUID part of EFI variable name\r
- @param VariableSize Returns the size of the EFI variable that was\r
- read\r
-\r
- @return Dynamically allocated memory that contains a copy of the EFI variable.\r
- Caller is responsible freeing the buffer.\r
- @retval NULL Variable was not read\r
-\r
-**/\r
-VOID *\r
-EFIAPI\r
-GetVariableAndSize (\r
- IN CHAR16 *Name,\r
- IN EFI_GUID *VendorGuid,\r
- OUT UINTN *VariableSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN BufferSize;\r
- VOID *Buffer;\r
-\r
- Buffer = NULL;\r
-\r
- //\r
- // Pass in a zero size buffer to find the required buffer size.\r
- //\r
- BufferSize = 0;\r
- Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- //\r
- // Allocate the buffer to return\r
- //\r
- Buffer = AllocateZeroPool (BufferSize);\r
- if (Buffer == NULL) {\r
- return NULL;\r
- }\r
- //\r
- // Read variable into the allocated buffer.\r
- //\r
- Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
- if (EFI_ERROR (Status)) {\r
- BufferSize = 0;\r
- }\r
- }\r
-\r
- *VariableSize = BufferSize;\r
- return Buffer;\r
-}\r
-\r
-\r
-/**\r
- Connect to the handle to a device on the device path.\r
-\r
- This function will create all handles associate with every device\r
- path node. If the handle associate with one device path node can not\r
- be created success, then still give one chance to do the dispatch,\r
- which load the missing drivers if possible.\r
-\r
- @param DevicePathToConnect The device path which will be connected, it can\r
- be a multi-instance device path\r
-\r
- @retval EFI_SUCCESS All handles associate with every device path\r
- node have been created\r
- @retval EFI_OUT_OF_RESOURCES There is no resource to create new handles\r
- @retval EFI_NOT_FOUND Create the handle associate with one device\r
- path node failed\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ConnectDevicePath (\r
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL *Instance;\r
- EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL *Next;\r
- EFI_HANDLE Handle;\r
- EFI_HANDLE PreviousHandle;\r
- UINTN Size;\r
-\r
- if (DevicePathToConnect == NULL) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- DevicePath = DuplicateDevicePath (DevicePathToConnect);\r
- CopyOfDevicePath = DevicePath;\r
- if (DevicePath == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- do {\r
- //\r
- // The outer loop handles multi instance device paths.\r
- // Only console variables contain multiple instance device paths.\r
- //\r
- // After this call DevicePath points to the next Instance\r
- //\r
- Instance = GetNextDevicePathInstance (&DevicePath, &Size);\r
- ASSERT (Instance != NULL);\r
-\r
- Next = Instance;\r
- while (!IsDevicePathEndType (Next)) {\r
- Next = NextDevicePathNode (Next);\r
- }\r
-\r
- SetDevicePathEndNode (Next);\r
-\r
- //\r
- // Start the real work of connect with RemainingDevicePath\r
- //\r
- PreviousHandle = NULL;\r
- do {\r
- //\r
- // Find the handle that best matches the Device Path. If it is only a\r
- // partial match the remaining part of the device path is returned in\r
- // RemainingDevicePath.\r
- //\r
- RemainingDevicePath = Instance;\r
- Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle);\r
-\r
- if (!EFI_ERROR (Status)) {\r
- if (Handle == PreviousHandle) {\r
- //\r
- // If no forward progress is made try invoking the Dispatcher.\r
- // A new FV may have been added to the system an new drivers\r
- // may now be found.\r
- // Status == EFI_SUCCESS means a driver was dispatched\r
- // Status == EFI_NOT_FOUND means no new drivers were dispatched\r
- //\r
- Status = gDS->Dispatch ();\r
- }\r
-\r
- if (!EFI_ERROR (Status)) {\r
- PreviousHandle = Handle;\r
- //\r
- // Connect all drivers that apply to Handle and RemainingDevicePath,\r
- // the Recursive flag is FALSE so only one level will be expanded.\r
- //\r
- // Do not check the connect status here, if the connect controller fail,\r
- // then still give the chance to do dispatch, because partial\r
- // RemainingDevicepath may be in the new FV\r
- //\r
- // 1. If the connect fails, RemainingDevicepath and handle will not\r
- // change, so next time will do the dispatch, then dispatch's status\r
- // will take effect\r
- // 2. If the connect succeeds, the RemainingDevicepath and handle will\r
- // change, then avoid the dispatch, we have chance to continue the\r
- // next connection\r
- //\r
- gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);\r
- }\r
- }\r
- //\r
- // Loop until RemainingDevicePath is an empty device path\r
- //\r
- } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));\r
-\r
- } while (DevicePath != NULL);\r
-\r
- if (CopyOfDevicePath != NULL) {\r
- FreePool (CopyOfDevicePath);\r
- }\r
- //\r
- // All handle with DevicePath exists in the handle database\r
- //\r
- return Status;\r
-}\r
## @libraryclass Defines a set of methods related recovery mode.\r
RecoveryLib|Include/Library/RecoveryLib.h\r
\r
- ## @libraryclass Basic platform driver override functions.\r
- # This library is only intended to be used by Platform Driver Override Dxe Driver and Application.\r
- PlatformDriverOverrideLib|Include/Library/PlatformDriverOverrideLib.h\r
-\r
## @libraryclass Provides HII related functions.\r
HiiLib|Include/Library/HiiLib.h\r
\r
## Include/Guid/VariableFormat.h\r
gEfiVariableGuid = { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}\r
\r
- ## Platform Override Variable guid\r
- ## Include/Guid/OverrideVariable.h\r
- gEfiOverrideVariableGuid = { 0x8e3d4ad5, 0xf762, 0x438a, { 0xa1, 0xc1, 0x5b, 0x9f, 0xe6, 0x8c, 0x6b, 0x15 }}\r
- \r
## Performance protocol guid that also acts as the performance HOB guid and performance variable GUID\r
## Include/Guid/Performance.h\r
gPerformanceProtocolGuid = { 0x76B6BDFA, 0x2ACD, 0x4462, { 0x9E, 0x3F, 0xCB, 0x58, 0xC9, 0x69, 0xD9, 0x37 }}\r
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf\r
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf\r
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf\r
- PlatformDriverOverrideLib|MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.inf\r
HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf\r
ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf\r
MemoryTestLib|MdeModulePkg/Library/BaseMemoryTestLibNull/BaseMemoryTestLibNull.inf\r
MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf\r
MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf\r
MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf\r
- MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.inf\r
MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf\r
MdeModulePkg/Library/DxePrintLibPrint2Protocol/DxePrintLibPrint2Protocol.inf\r
MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf\r
MdeModulePkg/Universal/PCD/Dxe/Pcd.inf\r
MdeModulePkg/Universal/PCD/Pei/Pcd.inf\r
MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf\r
- MdeModulePkg/Application/PlatOverMngr/PlatOverMngr.inf\r
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf\r
MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
MdeModulePkg/Application/VariableInfo/VariableInfo.inf\r
--- /dev/null
+/** @file\r
+ Ihe internal heder file includes the required Protocol/Guid/Library\r
+ and the shared function APIs.\r
+\r
+Copyright (c) 2007 - 2009, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _INTERNAL_PLATFORM_DRIVER_OVERRIDE_H_\r
+#define _INTERNAL_PLATFORM_DRIVER_OVERRIDE_H_\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/HiiConfigAccess.h>\r
+#include <Protocol/HiiConfigRouting.h>\r
+#include <Protocol/HiiDatabase.h>\r
+#include <Protocol/FormBrowser2.h>\r
+#include <Protocol/LoadedImage.h>\r
+#include <Protocol/FirmwareVolume2.h>\r
+#include <Protocol/PciIo.h>\r
+#include <Protocol/BusSpecificDriverOverride.h>\r
+#include <Protocol/ComponentName2.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/DevicePathToText.h>\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/PlatformDriverOverride.h>\r
+#include <Guid/MdeModuleHii.h>\r
+#include <Guid/VariableFormat.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/DxeServicesTableLib.h>\r
+#include <Library/HiiLib.h>\r
+\r
+/**\r
+ Free all the mapping database memory resource and initialize the mapping list entry.\r
+\r
+ @param MappingDataBase Mapping database list entry pointer\r
+\r
+ @retval EFI_INVALID_PARAMETER mapping database list entry is NULL\r
+ @retval EFI_SUCCESS Free success\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FreeMappingDatabase (\r
+ IN OUT LIST_ENTRY *MappingDataBase\r
+ )\r
+;
+\r
+/**\r
+ Read the NV environment variable(s) that contain the override mappings from Controller Device Path to\r
+ a set of Driver Device Paths, and create the mapping database in memory to contain these variable info.\r
+\r
+ @param MappingDataBase Mapping database list entry pointer\r
+\r
+ @retval EFI_INVALID_PARAMETER MappingDataBase pointer is null\r
+ @retval EFI_NOT_FOUND Cannot find the 'PlatDriOver' NV variable\r
+ @retval EFI_VOLUME_CORRUPTED The found NV variable is corrupted\r
+ @retval EFI_SUCCESS Create the mapping database in memory successfully\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitOverridesMapping (\r
+ OUT LIST_ENTRY *MappingDataBase\r
+ )\r
+;
+\r
+/**\r
+ Save the memory mapping database into NV environment variable(s).\r
+ If MappingDataBase list is empty, then delete all platform override NV variables.\r
+\r
+ @param MappingDataBase Mapping database list entry pointer\r
+\r
+ @retval EFI_INVALID_PARAMETER MappingDataBase pointer is null\r
+ @retval EFI_SUCCESS Save memory mapping database successfully\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SaveOverridesMapping (\r
+ IN LIST_ENTRY *MappingDataBase\r
+ )\r
+;
+\r
+/**\r
+ Retrieves the image handle of the platform override driver for a controller in the system from the memory mapping database.\r
+\r
+ @param ControllerHandle The device handle of the controller to check if\r
+ a driver override exists.\r
+ @param DriverImageHandle On output, a pointer to the next driver handle.\r
+ Passing in a pointer to NULL, will return the\r
+ first driver handle for ControllerHandle.\r
+ @param MappingDataBase MappingDataBase - Mapping database list entry\r
+ pointer\r
+ @param CallerImageHandle The caller driver's image handle, for\r
+ UpdateFvFileDevicePath use.\r
+\r
+ @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is not\r
+ a valid handle. Or DriverImagePath is not a\r
+ device path that was returned on a previous call\r
+ to GetDriverPath().\r
+ @retval EFI_NOT_FOUND A driver override for ControllerHandle was not\r
+ found.\r
+ @retval EFI_UNSUPPORTED The operation is not supported.\r
+ @retval EFI_SUCCESS The driver override for ControllerHandle was\r
+ returned in DriverImagePath.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetDriverFromMapping (\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN OUT EFI_HANDLE *DriverImageHandle,\r
+ IN LIST_ENTRY *MappingDataBase,\r
+ IN EFI_HANDLE CallerImageHandle\r
+ )\r
+;
+\r
+/**\r
+ Check mapping database whether already has the mapping info which\r
+ records the input Controller to input DriverImage.\r
+\r
+ @param ControllerDevicePath The controller device path is to be check.\r
+ @param DriverImageDevicePath The driver image device path is to be check.\r
+ @param MappingDataBase Mapping database list entry pointer\r
+ @param DriverInfoNum the controller's total override driver number\r
+ @param DriverImageNO The driver order number for the input DriverImage.\r
+ If the DriverImageDevicePath is NULL, DriverImageNO is not set.\r
+\r
+ @retval EFI_INVALID_PARAMETER ControllerDevicePath or MappingDataBase is NULL.\r
+ @retval EFI_NOT_FOUND ControllerDevicePath is not found in MappingDataBase or\r
+ DriverImageDevicePath is not found in the found DriverImage Info list. \r
+ @retval EFI_SUCCESS The controller's total override driver number and \r
+ input DriverImage's order number is correctly return.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CheckMapping (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath OPTIONAL,\r
+ IN LIST_ENTRY *MappingDataBase,\r
+ OUT UINT32 *DriverInfoNum OPTIONAL,\r
+ OUT UINT32 *DriverImageNO OPTIONAL\r
+ )\r
+;
+\r
+/**\r
+ Insert a driver image as a controller's override driver into the mapping database.\r
+ The driver image's order number is indicated by DriverImageNO.\r
+\r
+ @param ControllerDevicePath The controller device path need to add a\r
+ override driver image item\r
+ @param DriverImageDevicePath The driver image device path need to be insert\r
+ @param MappingDataBase Mapping database list entry pointer\r
+ @param DriverImageNO The inserted order number. If this number is taken, \r
+ the larger available number will be used.\r
+\r
+ @retval EFI_INVALID_PARAMETER ControllerDevicePath is NULL, or DriverImageDevicePath is NULL\r
+ or MappingDataBase is NULL\r
+ @retval EFI_ALREADY_STARTED The input Controller to input DriverImage has been \r
+ recorded into the mapping database.\r
+ @retval EFI_SUCCESS The Controller and DriverImage are inserted into \r
+ the mapping database successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InsertDriverImage (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath,\r
+ IN LIST_ENTRY *MappingDataBase,\r
+ IN UINT32 DriverImageNO\r
+ )\r
+;
+\r
+/**\r
+ Delete a controller's override driver from the mapping database.\r
+\r
+ @param ControllerDevicePath The controller device path will be deleted \r
+ when all drivers images on it are removed.\r
+ @param DriverImageDevicePath The driver image device path will be delete.\r
+ If NULL, all driver image will be delete.\r
+ @param MappingDataBase Mapping database list entry pointer\r
+\r
+ @retval EFI_INVALID_PARAMETER ControllerDevicePath is NULL, or MappingDataBase is NULL\r
+ @retval EFI_NOT_FOUND ControllerDevicePath is not found in MappingDataBase or\r
+ DriverImageDevicePath is not found in the found DriverImage Info list. \r
+ @retval EFI_SUCCESS Delete the specified driver successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DeleteDriverImage (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath,\r
+ IN LIST_ENTRY *MappingDataBase\r
+ )\r
+;
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ This file also installs UEFI PLATFORM_DRIVER_OVERRIDE_PROTOCOL.\r
+ \r
+ The main code offers a UI interface in device manager to let user configure\r
+ platform override protocol to override the default algorithm for matching\r
+ drivers to controllers.\r
+\r
+ The main flow:\r
+ 1. It dynamicly locate all controller device path.\r
+ 2. It dynamicly locate all drivers which support binding protocol.\r
+ 3. It export and dynamicly update two menu to let user select the\r
+ mapping between drivers to controllers.\r
+ 4. It save all the mapping info in NV variables which will be consumed\r
+ by platform override protocol driver to publish the platform override protocol.\r
+\r
+Copyright (c) 2007 - 2009, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalPlatDriOverrideDxe.h"\r
+#include "PlatOverMngr.h"\r
+\r
+#define EFI_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('C', 'l', 'b', 'k')\r
+#define EFI_CALLBACK_INFO_FROM_THIS(a) CR (a, EFI_CALLBACK_INFO, ConfigAccess, EFI_CALLBACK_INFO_SIGNATURE)\r
+\r
+typedef struct {\r
+ UINTN Signature;\r
+ EFI_HANDLE DriverHandle;\r
+ EFI_HII_HANDLE RegisteredHandle;\r
+ PLAT_OVER_MNGR_DATA FakeNvData;\r
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
+ EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;\r
+ EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL PlatformDriverOverride;\r
+} EFI_CALLBACK_INFO;\r
+\r
+#pragma pack(1)\r
+\r
+///\r
+/// HII specific Vendor Device Path definition.\r
+///\r
+typedef struct {\r
+ VENDOR_DEVICE_PATH VendorDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL End;\r
+} HII_VENDOR_DEVICE_PATH;\r
+\r
+#pragma pack()\r
+\r
+//\r
+// uni string and Vfr Binary data.\r
+//\r
+extern UINT8 VfrBin[];\r
+extern UINT8 PlatDriOverrideDxeStrings[];\r
+\r
+//\r
+// module global data\r
+//\r
+EFI_GUID mPlatformOverridesManagerGuid = PLAT_OVER_MNGR_GUID;\r
+CHAR16 mVariableName[] = L"Data";\r
+LIST_ENTRY mMappingDataBase = INITIALIZE_LIST_HEAD_VARIABLE (mMappingDataBase);\r
+BOOLEAN mEnvironmentVariableRead = FALSE;\r
+EFI_HANDLE mCallerImageHandle = NULL;\r
+\r
+EFI_HANDLE *mDevicePathHandleBuffer;\r
+EFI_HANDLE *mDriverImageHandleBuffer;\r
+\r
+INTN mSelectedCtrIndex;\r
+EFI_STRING_ID mControllerToken[MAX_CHOICE_NUM];\r
+UINTN mDriverImageHandleCount;\r
+EFI_STRING_ID mDriverImageToken[MAX_CHOICE_NUM];\r
+EFI_STRING_ID mDriverImageFilePathToken[MAX_CHOICE_NUM];\r
+EFI_LOADED_IMAGE_PROTOCOL *mDriverImageProtocol[MAX_CHOICE_NUM];\r
+EFI_DEVICE_PATH_PROTOCOL *mControllerDevicePathProtocol[MAX_CHOICE_NUM];\r
+UINTN mSelectedDriverImageNum;\r
+UINTN mLastSavedDriverImageNum;\r
+UINT16 mCurrentPage;\r
+EFI_CALLBACK_INFO *mCallbackInfo;\r
+\r
+HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {\r
+ {\r
+ {\r
+ HARDWARE_DEVICE_PATH,\r
+ HW_VENDOR_DP,\r
+ {\r
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
+ }\r
+ },\r
+ EFI_CALLER_ID_GUID\r
+ },\r
+ {\r
+ END_DEVICE_PATH_TYPE,\r
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+ { \r
+ (UINT8) (END_DEVICE_PATH_LENGTH),\r
+ (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
+ }\r
+ }\r
+};\r
+\r
+/**\r
+ Converting a given device to an unicode string. \r
+ \r
+ This function will dependent on gEfiDevicePathToTextProtocolGuid, if protocol\r
+ does not installed, then return unknown device path L"?" directly.\r
+ \r
+ @param DevPath Given device path instance\r
+ \r
+ @return Converted string from given device path.\r
+ @retval L"?" Can not locate gEfiDevicePathToTextProtocolGuid protocol for converting.\r
+**/\r
+CHAR16 *\r
+DevicePathToStr (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;\r
+ CHAR16 *ToText;\r
+ \r
+ if (DevPath == NULL) {\r
+ return L"";\r
+ }\r
+ \r
+ Status = gBS->LocateProtocol (\r
+ &gEfiDevicePathToTextProtocolGuid,\r
+ NULL,\r
+ (VOID **) &DevPathToText\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ ToText = DevPathToText->ConvertDevicePathToText (\r
+ DevPath,\r
+ FALSE,\r
+ TRUE\r
+ );\r
+ ASSERT (ToText != NULL);\r
+ return ToText;\r
+ }\r
+\r
+ return L"?";\r
+}\r
+\r
+/**\r
+ Worker function to get the driver name by ComponentName or ComponentName2 protocol \r
+ according to the driver binding handle.\r
+\r
+ @param DriverBindingHandle The Handle of DriverBinding.\r
+ @param ProtocolGuid The pointer to Component Name (2) protocol GUID.\r
+ @param VariableName The name of the RFC 4646 or ISO 639-2 language variable.\r
+\r
+ @retval !NULL Pointer into the image name if the image name is found,\r
+ @retval NULL Pointer to NULL if the image name is not found.\r
+\r
+**/\r
+CHAR16 *\r
+GetComponentNameWorker (\r
+ IN EFI_HANDLE DriverBindingHandle,\r
+ IN EFI_GUID *ProtocolGuid,\r
+ IN CONST CHAR16 *VariableName\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_COMPONENT_NAME_PROTOCOL *ComponentName;\r
+ CHAR16 *DriverName;\r
+ CHAR8 *Language;\r
+ CHAR8 *BestLanguage;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ DriverBindingHandle,\r
+ ProtocolGuid,\r
+ (VOID *) &ComponentName,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Find the best matching language.\r
+ //\r
+ Language = GetEfiGlobalVariable (VariableName);\r
+ BestLanguage = GetBestLanguage (\r
+ ComponentName->SupportedLanguages,\r
+ (BOOLEAN) (ProtocolGuid == &gEfiComponentNameProtocolGuid),\r
+ Language,\r
+ NULL\r
+ );\r
+\r
+ DriverName = NULL;\r
+ if (BestLanguage != NULL) {\r
+ ComponentName->GetDriverName (\r
+ ComponentName,\r
+ BestLanguage,\r
+ &DriverName\r
+ );\r
+ FreePool (BestLanguage);\r
+ }\r
+\r
+ if (Language != NULL) {\r
+ FreePool (Language);\r
+ }\r
+\r
+ return DriverName;\r
+}\r
+\r
+\r
+/**\r
+ Get the driver name by ComponentName or ComponentName2 protocol \r
+ according to the driver binding handle\r
+\r
+ @param DriverBindingHandle The Handle of DriverBinding.\r
+\r
+ @retval !NULL Pointer into the image name if the image name is found,\r
+ @retval NULL Pointer to NULL if the image name is not found.\r
+\r
+**/\r
+CHAR16 *\r
+GetComponentName (\r
+ IN EFI_HANDLE DriverBindingHandle\r
+ )\r
+{\r
+ CHAR16 *DriverName;\r
+\r
+ //\r
+ // Try RFC 4646 Component Name 2 protocol first.\r
+ //\r
+ DriverName = GetComponentNameWorker (DriverBindingHandle, &gEfiComponentName2ProtocolGuid, L"PlatformLang");\r
+ if (DriverName == NULL) {\r
+ //\r
+ // If we can not get driver name from Component Name 2 protocol, we can try ISO 639-2 Component Name protocol. \r
+ //\r
+ DriverName = GetComponentNameWorker (DriverBindingHandle, &gEfiComponentNameProtocolGuid, L"Lang");\r
+ }\r
+\r
+ return DriverName;\r
+}\r
+\r
+/**\r
+ Get the image name from EFI UI section.\r
+ Get FV protocol by its loaded image protocol to abstract EFI UI section.\r
+\r
+ @param Image Pointer to the loaded image protocol\r
+\r
+ @retval !NULL Pointer to the image name if the image name is found,\r
+ @retval NULL NULL if the image name is not found.\r
+\r
+**/\r
+CHAR16 *\r
+GetImageName (\r
+ IN EFI_LOADED_IMAGE_PROTOCOL *Image\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode;\r
+ EFI_DEVICE_PATH_PROTOCOL *AlignedDevPathNode;\r
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;\r
+ VOID *Buffer;\r
+ UINTN BufferSize;\r
+ UINT32 AuthenticationStatus;\r
+ EFI_GUID *NameGuid;\r
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv2;\r
+\r
+ Fv2 = NULL;\r
+ Buffer = NULL;\r
+ BufferSize = 0;\r
+\r
+ if (Image->FilePath == NULL) {\r
+ return NULL;\r
+ }\r
+ DevPathNode = Image->FilePath;\r
+\r
+ while (!IsDevicePathEnd (DevPathNode)) {\r
+ //\r
+ // Make sure device path node is aligned when accessing it's FV Name Guid field.\r
+ //\r
+ AlignedDevPathNode = AllocateCopyPool (DevicePathNodeLength(DevPathNode), DevPathNode);\r
+ \r
+ //\r
+ // Find the Fv File path\r
+ //\r
+ NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)AlignedDevPathNode);\r
+ if (NameGuid != NULL) {\r
+ FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) AlignedDevPathNode;\r
+ Status = gBS->HandleProtocol (\r
+ Image->DeviceHandle,\r
+ &gEfiFirmwareVolume2ProtocolGuid,\r
+ (VOID **) &Fv2\r
+ );\r
+ //\r
+ // Locate Image EFI UI section to get the image name.\r
+ //\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = Fv2->ReadSection (\r
+ Fv2,\r
+ &FvFilePath->FvFileName,\r
+ EFI_SECTION_USER_INTERFACE,\r
+ 0,\r
+ &Buffer,\r
+ &BufferSize,\r
+ &AuthenticationStatus\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ FreePool (AlignedDevPathNode);\r
+ break;\r
+ }\r
+ Buffer = NULL;\r
+ }\r
+ }\r
+ \r
+ FreePool (AlignedDevPathNode);\r
+ \r
+ //\r
+ // Next device path node\r
+ //\r
+ DevPathNode = NextDevicePathNode (DevPathNode);\r
+ }\r
+\r
+ return Buffer;\r
+}\r
+\r
+/**\r
+ Prepare the first page to let user select the device controller which need to\r
+ add mapping drivers if user select 'Refresh' in first page.\r
+ During first page, user will see all currnet controller device path in system,\r
+ select any device path will go to second page to select its overrides drivers.\r
+\r
+ @param Private Pointer to EFI_CALLBACK_INFO.\r
+ @param KeyValue The callback key value of device controller item in first page.\r
+ @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.\r
+\r
+ @retval EFI_SUCCESS Always returned.\r
+\r
+**/\r
+EFI_STATUS\r
+UpdateDeviceSelectPage (\r
+ IN EFI_CALLBACK_INFO *Private,\r
+ IN UINT16 KeyValue,\r
+ IN PLAT_OVER_MNGR_DATA *FakeNvData\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ UINTN DevicePathHandleCount;\r
+ CHAR16 *NewString;\r
+ EFI_STRING_ID NewStringToken;\r
+ CHAR16 *ControllerName;\r
+ EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;\r
+ UINTN Len;\r
+ VOID *StartOpCodeHandle;\r
+ VOID *EndOpCodeHandle;\r
+ EFI_IFR_GUID_LABEL *StartLabel;\r
+ EFI_IFR_GUID_LABEL *EndLabel; \r
+\r
+ //\r
+ // Set current page form ID.\r
+ //\r
+ mCurrentPage = FORM_ID_DEVICE; \r
+ \r
+ //\r
+ // Initial the mapping database in memory\r
+ //\r
+ FreeMappingDatabase (&mMappingDataBase);\r
+ InitOverridesMapping (&mMappingDataBase);\r
+\r
+ //\r
+ // Init OpCode Handle\r
+ //\r
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+ ASSERT (StartOpCodeHandle != NULL);\r
+\r
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+ ASSERT (EndOpCodeHandle != NULL);\r
+\r
+ //\r
+ // Create Hii Extend Label OpCode as the start opcode\r
+ //\r
+ StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+ StartLabel->Number = FORM_ID_DEVICE;\r
+\r
+ //\r
+ // Create Hii Extend Label OpCode as the end opcode\r
+ //\r
+ EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+ EndLabel->Number = LABEL_END;\r
+\r
+ //\r
+ // Clear first page form\r
+ //\r
+ HiiUpdateForm (\r
+ Private->RegisteredHandle,\r
+ &mPlatformOverridesManagerGuid,\r
+ FORM_ID_DEVICE,\r
+ StartOpCodeHandle, // Label FORM_ID_DEVICE\r
+ EndOpCodeHandle // LABEL_END\r
+ );\r
+\r
+ //\r
+ // When user enter the page at first time, the 'first refresh' string is given to notify user to refresh all the drivers,\r
+ // then the 'first refresh' string will be replaced by the 'refresh' string, and the two strings content are same after the replacement\r
+ //\r
+ NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH);\r
+ NewString = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH), NULL);\r
+ ASSERT (NewString != NULL);\r
+ if (HiiSetString (Private->RegisteredHandle, NewStringToken, NewString, NULL) == 0) {\r
+ ASSERT (FALSE);\r
+ }\r
+ FreePool (NewString);\r
+\r
+ NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH_HELP);\r
+ NewString = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH_HELP), NULL);\r
+ ASSERT (NewString != NULL);\r
+ if (HiiSetString (Private->RegisteredHandle, NewStringToken, NewString, NULL) == 0) {\r
+ ASSERT (FALSE);\r
+ }\r
+ FreePool (NewString);\r
+\r
+ //\r
+ // created needed controller device item in first page\r
+ //\r
+ DevicePathHandleCount = 0;\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiDevicePathProtocolGuid,\r
+ NULL,\r
+ &DevicePathHandleCount,\r
+ &mDevicePathHandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status) || (DevicePathHandleCount == 0)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ for (Index = 0; Index < DevicePathHandleCount; Index++) {\r
+ if (FakeNvData->PciDeviceFilter == 0x01) {\r
+ //\r
+ // Only care PCI device which contain efi driver in its option rom.\r
+ //\r
+\r
+ //\r
+ // Check whether it is a pci device\r
+ //\r
+ ControllerDevicePath = NULL;\r
+ Status = gBS->OpenProtocol (\r
+ mDevicePathHandleBuffer[Index],\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+ //\r
+ // Check whether it contain efi driver in its option rom\r
+ //\r
+ Status = gBS->HandleProtocol(\r
+ mDevicePathHandleBuffer[Index],\r
+ &gEfiBusSpecificDriverOverrideProtocolGuid,\r
+ (VOID **) &BusSpecificDriverOverride\r
+ );\r
+ if (EFI_ERROR (Status) || BusSpecificDriverOverride == NULL) {\r
+ continue;\r
+ }\r
+ }\r
+\r
+ ControllerDevicePath = NULL;\r
+ Status = gBS->OpenProtocol (\r
+ mDevicePathHandleBuffer[Index],\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ControllerDevicePath,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ //\r
+ // Save the device path protocol interface\r
+ //\r
+ mControllerDevicePathProtocol[Index] = ControllerDevicePath;\r
+\r
+ //\r
+ // Get the driver name\r
+ //\r
+ ControllerName = DevicePathToStr (ControllerDevicePath);\r
+\r
+ //\r
+ // Export the driver name string and create item in set options page\r
+ //\r
+ Len = StrSize (ControllerName);\r
+ NewString = AllocateZeroPool (Len + StrSize (L"--"));\r
+ ASSERT (NewString != NULL);\r
+ if (EFI_ERROR (CheckMapping (ControllerDevicePath,NULL, &mMappingDataBase, NULL, NULL))) {\r
+ StrCat (NewString, L"--");\r
+ } else {\r
+ StrCat (NewString, L"**");\r
+ }\r
+ StrCat (NewString, ControllerName);\r
+\r
+ NewStringToken = HiiSetString (Private->RegisteredHandle, mControllerToken[Index], NewString, NULL);\r
+ ASSERT (NewStringToken != 0);\r
+ FreePool (NewString);\r
+ //\r
+ // Save the device path string toke for next access use\r
+ //\r
+ mControllerToken[Index] = NewStringToken;\r
+ \r
+ HiiCreateGotoOpCode (\r
+ StartOpCodeHandle,\r
+ FORM_ID_DRIVER,\r
+ NewStringToken,\r
+ STRING_TOKEN (STR_GOTO_HELP_DRIVER),\r
+ EFI_IFR_FLAG_CALLBACK,\r
+ (UINT16) (Index + KEY_VALUE_DEVICE_OFFSET)\r
+ );\r
+ }\r
+\r
+ //\r
+ // Update first page form\r
+ //\r
+ HiiUpdateForm (\r
+ Private->RegisteredHandle,\r
+ &mPlatformOverridesManagerGuid,\r
+ FORM_ID_DEVICE,\r
+ StartOpCodeHandle, // Label FORM_ID_DEVICE\r
+ EndOpCodeHandle // LABEL_END\r
+ );\r
+\r
+ HiiFreeOpCodeHandle (StartOpCodeHandle);\r
+ HiiFreeOpCodeHandle (EndOpCodeHandle);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Get the first Driver Binding handle which has the specific image handle.\r
+\r
+ @param ImageHandle The Image handle\r
+\r
+ @return Handle to Driver binding\r
+ @retval NULL The paramter is not valid or the driver binding handle is not found.\r
+\r
+**/\r
+EFI_HANDLE\r
+GetDriverBindingHandleFromImageHandle (\r
+ IN EFI_HANDLE ImageHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ UINTN DriverBindingHandleCount;\r
+ EFI_HANDLE *DriverBindingHandleBuffer;\r
+ EFI_DRIVER_BINDING_PROTOCOL *DriverBindingInterface;\r
+ EFI_HANDLE DriverBindingHandle;\r
+\r
+ DriverBindingHandle = NULL;\r
+\r
+ if (ImageHandle == NULL) {\r
+ return NULL;\r
+ }\r
+ //\r
+ // Get all drivers which support driver binding protocol\r
+ //\r
+ DriverBindingHandleCount = 0;\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiDriverBindingProtocolGuid,\r
+ NULL,\r
+ &DriverBindingHandleCount,\r
+ &DriverBindingHandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {\r
+ return NULL;\r
+ }\r
+ \r
+ //\r
+ // Get the first Driver Binding handle which has the specific image handle.\r
+ //\r
+ for (Index = 0; Index < DriverBindingHandleCount; Index++) {\r
+ DriverBindingInterface = NULL;\r
+ Status = gBS->OpenProtocol (\r
+ DriverBindingHandleBuffer[Index],\r
+ &gEfiDriverBindingProtocolGuid,\r
+ (VOID **) &DriverBindingInterface,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ if (DriverBindingInterface->ImageHandle == ImageHandle) {\r
+ DriverBindingHandle = DriverBindingHandleBuffer[Index];\r
+ break;\r
+ }\r
+ }\r
+\r
+ FreePool (DriverBindingHandleBuffer);\r
+ return DriverBindingHandle;\r
+}\r
+\r
+/**\r
+ Prepare to let user select the drivers which need mapping with the device controller\r
+ selected in first page.\r
+\r
+ @param Private Pointer to EFI_CALLBACK_INFO.\r
+ @param KeyValue The callback key value of device controller item in first page.\r
+ KeyValue is larger than or equal to KEY_VALUE_DEVICE_OFFSET.\r
+ @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.\r
+\r
+ @retval EFI_SUCCESS Always returned.\r
+\r
+**/\r
+EFI_STATUS\r
+UpdateBindingDriverSelectPage (\r
+ IN EFI_CALLBACK_INFO *Private,\r
+ IN UINT16 KeyValue,\r
+ IN PLAT_OVER_MNGR_DATA *FakeNvData\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ CHAR16 *NewString;\r
+ EFI_STRING_ID NewStringToken;\r
+ EFI_STRING_ID NewStringHelpToken;\r
+ UINTN DriverImageHandleCount;\r
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
+ CHAR16 *DriverName;\r
+ BOOLEAN FreeDriverName;\r
+ EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;\r
+ EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;\r
+ EFI_HANDLE DriverBindingHandle;\r
+ VOID *StartOpCodeHandle;\r
+ VOID *EndOpCodeHandle;\r
+ EFI_IFR_GUID_LABEL *StartLabel;\r
+ EFI_IFR_GUID_LABEL *EndLabel;\r
+\r
+ //\r
+ // If user select a controller item in the first page the following code will be run.\r
+ // During second page, user will see all currnet driver bind protocol driver, the driver name and its device path will be shown\r
+ //\r
+ //First acquire the list of Loaded Image Protocols, and then when want the name of the driver, look up all the Driver Binding Protocols\r
+ // and find the first one whose ImageHandle field matches the image handle of the Loaded Image Protocol.\r
+ // 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.\r
+ //\r
+\r
+ mCurrentPage = FORM_ID_DRIVER;\r
+ //\r
+ // Switch the item callback key value to its NO. in mDevicePathHandleBuffer\r
+ //\r
+ mSelectedCtrIndex = KeyValue - KEY_VALUE_DEVICE_OFFSET;\r
+ ASSERT (mSelectedCtrIndex < MAX_CHOICE_NUM);\r
+\r
+ mLastSavedDriverImageNum = 0;\r
+\r
+ //\r
+ // Init OpCode Handle\r
+ //\r
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+ ASSERT (StartOpCodeHandle != NULL);\r
+\r
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+ ASSERT (EndOpCodeHandle != NULL);\r
+\r
+ //\r
+ // Create Hii Extend Label OpCode as the start opcode\r
+ //\r
+ StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+ StartLabel->Number = FORM_ID_DRIVER;\r
+\r
+ //\r
+ // Create Hii Extend Label OpCode as the end opcode\r
+ //\r
+ EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+ EndLabel->Number = LABEL_END;\r
+\r
+ //\r
+ // Clear second page form\r
+ //\r
+ HiiUpdateForm (\r
+ Private->RegisteredHandle,\r
+ &mPlatformOverridesManagerGuid,\r
+ FORM_ID_DRIVER,\r
+ StartOpCodeHandle,\r
+ EndOpCodeHandle\r
+ );\r
+\r
+ //\r
+ // Show all driver which support loaded image protocol in second page\r
+ //\r
+ DriverImageHandleCount = 0;\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiLoadedImageProtocolGuid,\r
+ NULL,\r
+ &DriverImageHandleCount,\r
+ &mDriverImageHandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status) || (DriverImageHandleCount == 0)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ mDriverImageHandleCount = DriverImageHandleCount;\r
+ for (Index = 0; Index < DriverImageHandleCount; Index++) {\r
+ //\r
+ // Step1: Get the driver image total file path for help string and the driver name.\r
+ //\r
+\r
+ //\r
+ // Find driver's Loaded Image protocol\r
+ //\r
+ LoadedImage =NULL;\r
+\r
+ Status = gBS->OpenProtocol (\r
+ mDriverImageHandleBuffer[Index],\r
+ &gEfiLoadedImageProtocolGuid,\r
+ (VOID **) &LoadedImage,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ FakeNvData->DriSelection[Index] = 0x00;\r
+ continue;\r
+ }\r
+ mDriverImageProtocol[Index] = LoadedImage;\r
+ //\r
+ // Find its related driver binding protocol\r
+ //\r
+ DriverBindingHandle = GetDriverBindingHandleFromImageHandle (mDriverImageHandleBuffer[Index]);\r
+ if (DriverBindingHandle == NULL) {\r
+ FakeNvData->DriSelection[Index] = 0x00;\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Get the EFI Loaded Image Device Path Protocol\r
+ //\r
+ LoadedImageDevicePath = NULL;\r
+ Status = gBS->HandleProtocol (\r
+ mDriverImageHandleBuffer[Index],\r
+ &gEfiLoadedImageDevicePathProtocolGuid,\r
+ (VOID **) &LoadedImageDevicePath\r
+ );\r
+ if (LoadedImageDevicePath == NULL) {\r
+ FakeNvData->DriSelection[Index] = 0x00;\r
+ continue;\r
+ }\r
+\r
+ if (FakeNvData->PciDeviceFilter == 0x01) {\r
+ //\r
+ // only care the driver which is in a Pci device option rom,\r
+ // and the driver's LoadedImage->DeviceHandle must point to a pci device which has efi option rom\r
+ //\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->HandleProtocol(\r
+ LoadedImage->DeviceHandle,\r
+ &gEfiBusSpecificDriverOverrideProtocolGuid,\r
+ (VOID **) &BusSpecificDriverOverride\r
+ );\r
+ if (EFI_ERROR (Status) || BusSpecificDriverOverride == NULL) {\r
+ FakeNvData->DriSelection[Index] = 0x00;\r
+ continue;\r
+ }\r
+ } else {\r
+ FakeNvData->DriSelection[Index] = 0x00;\r
+ continue;\r
+ }\r
+ }\r
+\r
+ //\r
+ // For driver name, try to get its component name, if fail, get its image name,\r
+ // if also fail, give a default name.\r
+ //\r
+ FreeDriverName = FALSE;\r
+ DriverName = GetComponentName (DriverBindingHandle);\r
+ if (DriverName == NULL) {\r
+ //\r
+ // get its image name\r
+ //\r
+ DriverName = GetImageName (LoadedImage);\r
+ }\r
+ if (DriverName == NULL) {\r
+ //\r
+ // give a default name\r
+ //\r
+ DriverName = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_DRIVER_DEFAULT_NAME), NULL);\r
+ ASSERT (DriverName != NULL);\r
+ FreeDriverName = TRUE; // the DriverName string need to free pool\r
+ }\r
+\r
+\r
+ //\r
+ // Step2 Export the driver name string and create check box item in second page\r
+ //\r
+\r
+ //\r
+ // First create the driver image name\r
+ //\r
+ NewString = AllocateZeroPool (StrSize (DriverName));\r
+ ASSERT (NewString != NULL); \r
+ if (EFI_ERROR (CheckMapping (mControllerDevicePathProtocol[mSelectedCtrIndex], LoadedImageDevicePath, &mMappingDataBase, NULL, NULL))) {\r
+ FakeNvData->DriSelection[Index] = 0x00;\r
+ } else {\r
+ FakeNvData->DriSelection[Index] = 0x01;\r
+ mLastSavedDriverImageNum++;\r
+ }\r
+ StrCat (NewString, DriverName);\r
+ NewStringToken = HiiSetString (Private->RegisteredHandle, mDriverImageToken[Index], NewString, NULL);\r
+ ASSERT (NewStringToken != 0);\r
+ mDriverImageToken[Index] = NewStringToken;\r
+ FreePool (NewString);\r
+ if (FreeDriverName) {\r
+ FreePool (DriverName);\r
+ }\r
+\r
+ //\r
+ // Second create the driver image device path as item help string\r
+ //\r
+ DriverName = DevicePathToStr (LoadedImageDevicePath);\r
+\r
+ NewString = AllocateZeroPool (StrSize (DriverName));\r
+ ASSERT (NewString != NULL); \r
+ StrCat (NewString, DriverName);\r
+ NewStringHelpToken = HiiSetString (Private->RegisteredHandle, mDriverImageFilePathToken[Index], NewString, NULL);\r
+ ASSERT (NewStringHelpToken != 0);\r
+ mDriverImageFilePathToken[Index] = NewStringHelpToken;\r
+ FreePool (NewString);\r
+ FreePool (DriverName);\r
+\r
+ HiiCreateCheckBoxOpCode (\r
+ StartOpCodeHandle,\r
+ (UINT16) (DRIVER_SELECTION_QUESTION_ID + Index),\r
+ VARSTORE_ID_PLAT_OVER_MNGR,\r
+ (UINT16) (DRIVER_SELECTION_VAR_OFFSET + Index),\r
+ NewStringToken,\r
+ NewStringHelpToken,\r
+ 0,\r
+ 0,\r
+ NULL\r
+ );\r
+ }\r
+\r
+ //\r
+ // Update second page form\r
+ //\r
+ HiiUpdateForm (\r
+ Private->RegisteredHandle,\r
+ &mPlatformOverridesManagerGuid,\r
+ FORM_ID_DRIVER,\r
+ StartOpCodeHandle, // Label FORM_ID_DRIVER\r
+ EndOpCodeHandle // LABEL_END\r
+ );\r
+\r
+ HiiFreeOpCodeHandle (StartOpCodeHandle);\r
+ HiiFreeOpCodeHandle (EndOpCodeHandle);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Prepare to let user select the priority order of the drivers which are\r
+ selected in second page.\r
+\r
+ @param Private Pointer to EFI_CALLBACK_INFO.\r
+ @param KeyValue The callback key value of device controller item in first page.\r
+ @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.\r
+\r
+ @retval EFI_SUCCESS Always returned.\r
+\r
+**/\r
+EFI_STATUS\r
+UpdatePrioritySelectPage (\r
+ IN EFI_CALLBACK_INFO *Private,\r
+ IN UINT16 KeyValue,\r
+ IN PLAT_OVER_MNGR_DATA *FakeNvData\r
+ )\r
+{\r
+ UINTN Index;\r
+ EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;\r
+ UINTN SelectedDriverImageNum;\r
+ UINT32 DriverImageNO;\r
+ UINTN MinNO;\r
+ UINTN Index1;\r
+ UINTN TempNO[100];\r
+ UINTN OrderNO[100];\r
+ VOID *StartOpCodeHandle;\r
+ VOID *EndOpCodeHandle;\r
+ VOID *OptionsOpCodeHandle;\r
+ EFI_IFR_GUID_LABEL *StartLabel;\r
+ EFI_IFR_GUID_LABEL *EndLabel;\r
+\r
+ //\r
+ // Following code will be run if user select 'order ... priority' item in second page\r
+ // Prepare third page. In third page, user will order the drivers priority which are selected in second page\r
+ //\r
+ mCurrentPage = FORM_ID_ORDER;\r
+\r
+ //\r
+ // Init OpCode Handle\r
+ //\r
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+ ASSERT (StartOpCodeHandle != NULL);\r
+\r
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+ ASSERT (EndOpCodeHandle != NULL);\r
+\r
+ //\r
+ // Create Hii Extend Label OpCode as the start opcode\r
+ //\r
+ StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+ StartLabel->Number = FORM_ID_ORDER;\r
+\r
+ //\r
+ // Create Hii Extend Label OpCode as the end opcode\r
+ //\r
+ EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+ EndLabel->Number = LABEL_END;\r
+\r
+ //\r
+ // Clear third page form\r
+ //\r
+ HiiUpdateForm (\r
+ Private->RegisteredHandle,\r
+ &mPlatformOverridesManagerGuid,\r
+ FORM_ID_ORDER,\r
+ StartOpCodeHandle,\r
+ EndOpCodeHandle\r
+ );\r
+\r
+ //\r
+ // Check how many drivers have been selected\r
+ //\r
+ SelectedDriverImageNum = 0;\r
+ for (Index = 0; Index < mDriverImageHandleCount; Index++) {\r
+ if (FakeNvData->DriSelection[Index] != 0) {\r
+ SelectedDriverImageNum ++;\r
+ }\r
+ }\r
+\r
+ mSelectedDriverImageNum = SelectedDriverImageNum;\r
+ if (SelectedDriverImageNum == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+ ASSERT (OptionsOpCodeHandle != NULL);\r
+\r
+ //\r
+ // Create order list for those selected drivers\r
+ //\r
+ SelectedDriverImageNum = 0;\r
+ for (Index = 0; Index < mDriverImageHandleCount; Index++) {\r
+ if (FakeNvData->DriSelection[Index] != 0) {\r
+ //\r
+ // Use the NO. in driver binding buffer as value, will use it later\r
+ //\r
+ HiiCreateOneOfOptionOpCode (\r
+ OptionsOpCodeHandle,\r
+ mDriverImageToken[Index],\r
+ 0,\r
+ EFI_IFR_NUMERIC_SIZE_1,\r
+ Index + 1\r
+ );\r
+\r
+ //\r
+ // Get the EFI Loaded Image Device Path Protocol\r
+ //\r
+ LoadedImageDevicePath = NULL;\r
+ gBS->HandleProtocol (\r
+ mDriverImageHandleBuffer[Index],\r
+ &gEfiLoadedImageDevicePathProtocolGuid,\r
+ (VOID **) &LoadedImageDevicePath\r
+ );\r
+ ASSERT (LoadedImageDevicePath != NULL);\r
+\r
+ //\r
+ // Check the driver DriverImage's order number in mapping database\r
+ //\r
+ DriverImageNO = 0;\r
+ CheckMapping (\r
+ mControllerDevicePathProtocol[mSelectedCtrIndex],\r
+ LoadedImageDevicePath,\r
+ &mMappingDataBase,\r
+ NULL,\r
+ &DriverImageNO\r
+ );\r
+ if (DriverImageNO == 0) {\r
+ DriverImageNO = (UINT32) mLastSavedDriverImageNum + 1;\r
+ mLastSavedDriverImageNum++;\r
+ }\r
+ TempNO[SelectedDriverImageNum] = DriverImageNO;\r
+ OrderNO[SelectedDriverImageNum] = Index + 1;\r
+ SelectedDriverImageNum ++;\r
+ }\r
+ }\r
+\r
+ ASSERT (SelectedDriverImageNum == mSelectedDriverImageNum);\r
+ //\r
+ // NvRamMap Must be clear firstly\r
+ //\r
+ ZeroMem (FakeNvData->DriOrder, sizeof (FakeNvData->DriOrder));\r
+\r
+ //\r
+ // Order the selected drivers according to the info already in mapping database\r
+ // the less order number in mapping database the less order number in NvRamMap\r
+ //\r
+ for (Index=0; Index < SelectedDriverImageNum; Index++) {\r
+ //\r
+ // Find the minimal order number in TempNO array, its index in TempNO is same as IfrOptionList array\r
+ //\r
+ MinNO = 0;\r
+ for (Index1=0; Index1 < SelectedDriverImageNum; Index1++) {\r
+ if (TempNO[Index1] < TempNO[MinNO]) {\r
+ MinNO = Index1;\r
+ }\r
+ }\r
+ //\r
+ // the IfrOptionList[MinNO].Value = the driver NO. in driver binding buffer\r
+ //\r
+ FakeNvData->DriOrder[Index] = (UINT8) OrderNO[MinNO];\r
+ TempNO[MinNO] = MAX_CHOICE_NUM + 1;\r
+ }\r
+ \r
+ //\r
+ // Create Order List OpCode\r
+ //\r
+ HiiCreateOrderedListOpCode (\r
+ StartOpCodeHandle,\r
+ (UINT16) DRIVER_ORDER_QUESTION_ID,\r
+ VARSTORE_ID_PLAT_OVER_MNGR,\r
+ (UINT16) DRIVER_ORDER_VAR_OFFSET,\r
+ mControllerToken[mSelectedCtrIndex],\r
+ mControllerToken[mSelectedCtrIndex],\r
+ EFI_IFR_FLAG_RESET_REQUIRED,\r
+ 0,\r
+ EFI_IFR_NUMERIC_SIZE_1,\r
+ (UINT8) MAX_CHOICE_NUM,\r
+ OptionsOpCodeHandle,\r
+ NULL\r
+ );\r
+\r
+ //\r
+ // Update third page form\r
+ //\r
+ HiiUpdateForm (\r
+ Private->RegisteredHandle,\r
+ &mPlatformOverridesManagerGuid,\r
+ FORM_ID_ORDER,\r
+ StartOpCodeHandle, // Label FORM_ID_ORDER\r
+ EndOpCodeHandle // LABEL_END\r
+ );\r
+\r
+ HiiFreeOpCodeHandle (StartOpCodeHandle);\r
+ HiiFreeOpCodeHandle (EndOpCodeHandle);\r
+ HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Save the save the mapping database to NV variable.\r
+\r
+ @param Private Pointer to EFI_CALLBACK_INFO.\r
+ @param KeyValue The callback key value of device controller item in first page.\r
+ @param FakeNvData Pointer to PLAT_OVER_MNGR_DATA.\r
+\r
+ @retval EFI_SUCCESS Always returned.\r
+\r
+**/\r
+EFI_STATUS\r
+CommintChanges (\r
+ IN EFI_CALLBACK_INFO *Private,\r
+ IN UINT16 KeyValue,\r
+ IN PLAT_OVER_MNGR_DATA *FakeNvData\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ UINTN SelectedDriverImageNum;\r
+ EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;\r
+ //\r
+ // Following code will be run if user select 'commint changes' in third page\r
+ // user enter 'Commit Changes' to save the mapping database\r
+ //\r
+ DeleteDriverImage (mControllerDevicePathProtocol[mSelectedCtrIndex], NULL, &mMappingDataBase);\r
+ for (SelectedDriverImageNum = 0; SelectedDriverImageNum < mSelectedDriverImageNum; SelectedDriverImageNum++) {\r
+ //\r
+ // DriOrder[SelectedDriverImageNum] = the driver NO. in driver binding buffer\r
+ //\r
+ Index = FakeNvData->DriOrder[SelectedDriverImageNum] - 1;\r
+\r
+ //\r
+ // Get the EFI Loaded Image Device Path Protocol\r
+ //\r
+ LoadedImageDevicePath = NULL;\r
+ Status = gBS->HandleProtocol (\r
+ mDriverImageHandleBuffer[Index],\r
+ &gEfiLoadedImageDevicePathProtocolGuid,\r
+ (VOID **) &LoadedImageDevicePath\r
+ );\r
+ ASSERT (LoadedImageDevicePath != NULL);\r
+\r
+ InsertDriverImage (\r
+ mControllerDevicePathProtocol[mSelectedCtrIndex],\r
+ LoadedImageDevicePath,\r
+ &mMappingDataBase,\r
+ (UINT32)SelectedDriverImageNum + 1\r
+ );\r
+ }\r
+ Status = SaveOverridesMapping (&mMappingDataBase);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This function allows a caller to extract the current configuration for one\r
+ or more named elements from the target driver.\r
+\r
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+ @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
+ @param Progress On return, points to a character in the Request string.\r
+ Points to the string's null terminator if request was successful.\r
+ Points to the most recent '&' before the first failing name/value\r
+ pair (or the beginning of the string if the failure is in the\r
+ first name/value pair) if the request was not successful.\r
+ @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
+ has all values filled in for the names in the Request string.\r
+ String to be allocated by the called function.\r
+\r
+ @retval EFI_SUCCESS The Results is filled with the requested values.\r
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
+ @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.\r
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PlatOverMngrExtractConfig (\r
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
+ IN CONST EFI_STRING Request,\r
+ OUT EFI_STRING *Progress,\r
+ OUT EFI_STRING *Results\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_CALLBACK_INFO *Private;\r
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
+ \r
+ if (Request == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Private = EFI_CALLBACK_INFO_FROM_THIS (This);\r
+ HiiConfigRouting = Private->HiiConfigRouting;\r
+\r
+ //\r
+ // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
+ //\r
+ Status = HiiConfigRouting->BlockToConfig (\r
+ HiiConfigRouting,\r
+ Request,\r
+ (UINT8 *) &Private->FakeNvData,\r
+ sizeof (PLAT_OVER_MNGR_DATA),\r
+ Results,\r
+ Progress\r
+ );\r
+ return Status;\r
+}\r
+\r
+/**\r
+ This function processes the results of changes in configuration.\r
+\r
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+ @param Configuration A null-terminated Unicode string in <ConfigRequest> format.\r
+ @param Progress A pointer to a string filled in with the offset of the most\r
+ recent '&' before the first failing name/value pair (or the\r
+ beginning of the string if the failure is in the first\r
+ name/value pair) or the terminating NULL if all was successful.\r
+\r
+ @retval EFI_SUCCESS The Results is processed successfully.\r
+ @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PlatOverMngrRouteConfig (\r
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
+ IN CONST EFI_STRING Configuration,\r
+ OUT EFI_STRING *Progress\r
+ )\r
+{\r
+ EFI_CALLBACK_INFO *Private;\r
+ UINT16 KeyValue;\r
+ PLAT_OVER_MNGR_DATA *FakeNvData;\r
+\r
+ Private = EFI_CALLBACK_INFO_FROM_THIS (This);\r
+ FakeNvData = (PLAT_OVER_MNGR_DATA *) HiiGetBrowserData (&mPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA));\r
+ if (FakeNvData == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ if (mCurrentPage == FORM_ID_DRIVER) {\r
+ KeyValue = KEY_VALUE_DRIVER_GOTO_ORDER;\r
+ UpdatePrioritySelectPage (Private, KeyValue, FakeNvData);\r
+ KeyValue = KEY_VALUE_ORDER_SAVE_AND_EXIT;\r
+ CommintChanges (Private, KeyValue, FakeNvData);\r
+ //\r
+ // Since UpdatePrioritySelectPage will change mCurrentPage,\r
+ // should ensure the mCurrentPage still indicate the second page here\r
+ //\r
+ mCurrentPage = FORM_ID_DRIVER;\r
+ }\r
+\r
+ if (mCurrentPage == FORM_ID_ORDER) {\r
+ KeyValue = KEY_VALUE_ORDER_SAVE_AND_EXIT;\r
+ CommintChanges (Private, KeyValue, FakeNvData);\r
+ }\r
+\r
+ if (FakeNvData != NULL) {\r
+ FreePool (FakeNvData);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ This is the function that is called to provide results data to the driver. This data\r
+ consists of a unique key which is used to identify what data is either being passed back\r
+ or being asked for.\r
+\r
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+ @param Action A null-terminated Unicode string in <ConfigRequest> format.\r
+ @param KeyValue A unique Goto OpCode callback value which record user's selection.\r
+ 0x100 <= KeyValue <0x500 : user select a controller item in the first page;\r
+ KeyValue == 0x1234 : user select 'Refresh' in first page, or user select 'Go to Previous Menu' in second page\r
+ KeyValue == 0x1235 : user select 'Pci device filter' in first page\r
+ KeyValue == 0x1500 : user select 'order ... priority' item in second page\r
+ KeyValue == 0x1800 : user select 'commint changes' in third page\r
+ KeyValue == 0x2000 : user select 'Go to Previous Menu' in third page\r
+ @param Type The type of value for the question.\r
+ @param Value A pointer to the data being sent to the original exporting driver.\r
+ @param ActionRequest On return, points to the action requested by the callback function.\r
+\r
+ @retval EFI_SUCCESS Always returned.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PlatOverMngrCallback (\r
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
+ IN EFI_BROWSER_ACTION Action,\r
+ IN EFI_QUESTION_ID KeyValue,\r
+ IN UINT8 Type,\r
+ IN EFI_IFR_TYPE_VALUE *Value,\r
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
+ )\r
+{\r
+ EFI_CALLBACK_INFO *Private;\r
+ EFI_STATUS Status;\r
+ EFI_STRING_ID NewStringToken;\r
+ EFI_INPUT_KEY Key;\r
+ PLAT_OVER_MNGR_DATA *FakeNvData;\r
+ \r
+ Private = EFI_CALLBACK_INFO_FROM_THIS (This);\r
+ FakeNvData = (PLAT_OVER_MNGR_DATA *) HiiGetBrowserData (&mPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA));\r
+ if (FakeNvData == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ if (KeyValue == KEY_VALUE_DEVICE_REFRESH ||\r
+ KeyValue == KEY_VALUE_DEVICE_FILTER ||\r
+ KeyValue == KEY_VALUE_DRIVER_GOTO_PREVIOUS\r
+ ) {\r
+ UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);\r
+ //\r
+ // Update page title string\r
+ //\r
+ NewStringToken = STRING_TOKEN (STR_TITLE);\r
+ if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"First, Select the controller by device path", NULL) == 0) {\r
+ ASSERT (FALSE);\r
+ }\r
+ }\r
+\r
+ if (((KeyValue >= KEY_VALUE_DEVICE_OFFSET) && (KeyValue < KEY_VALUE_DEVICE_MAX)) || (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS)) {\r
+ if (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS) {\r
+ KeyValue = (EFI_QUESTION_ID) (mSelectedCtrIndex + KEY_VALUE_DEVICE_OFFSET);\r
+ }\r
+ UpdateBindingDriverSelectPage (Private, KeyValue, FakeNvData);\r
+ //\r
+ // Update page title string\r
+ //\r
+ NewStringToken = STRING_TOKEN (STR_TITLE);\r
+ if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"Second, Select drivers for the previous selected controller", NULL) == 0) {\r
+ ASSERT (FALSE);\r
+ }\r
+ }\r
+\r
+ if (KeyValue == KEY_VALUE_DRIVER_GOTO_ORDER) {\r
+ UpdatePrioritySelectPage (Private, KeyValue, FakeNvData);\r
+ //\r
+ // Update page title string\r
+ //\r
+ NewStringToken = STRING_TOKEN (STR_TITLE);\r
+ if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"Finally, Set the priority order for the drivers and save them", NULL) == 0) {\r
+ ASSERT (FALSE);\r
+ }\r
+ }\r
+\r
+ if (KeyValue == KEY_VALUE_ORDER_SAVE_AND_EXIT) {\r
+ Status = CommintChanges (Private, KeyValue, FakeNvData);\r
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
+ if (EFI_ERROR (Status)) {\r
+ CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Single Override Info too large, Saving Error!", NULL);\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ }\r
+\r
+ if (KeyValue == KEY_VALUE_DEVICE_CLEAR) {\r
+ //\r
+ // Deletes all environment variable(s) that contain the override mappings info\r
+ //\r
+ FreeMappingDatabase (&mMappingDataBase);\r
+ Status = SaveOverridesMapping (&mMappingDataBase);\r
+ UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);\r
+ }\r
+ //\r
+ // Pass changed uncommitted data back to Form Browser\r
+ //\r
+ HiiSetBrowserData (&mPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *) FakeNvData, NULL);\r
+ \r
+ //\r
+ // Update local configuration buffer.\r
+ //\r
+ CopyMem (&Private->FakeNvData, FakeNvData, sizeof (PLAT_OVER_MNGR_DATA));\r
+ if (FakeNvData != NULL) {\r
+ FreePool (FakeNvData);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Retrieves the image handle of the platform override driver for a controller in the system.\r
+\r
+ @param This A pointer to the\r
+ EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL instance.\r
+ @param ControllerHandle The device handle of the controller to check if a\r
+ driver override exists.\r
+ @param DriverImageHandle On input, a pointer to the previous driver image\r
+ handle returned by GetDriver(). On output, a\r
+ pointer to the next driver image handle. Passing\r
+ in a NULL, will return the first driver image\r
+ handle for ControllerHandle.\r
+\r
+ @retval EFI_SUCCESS The driver override for ControllerHandle was\r
+ returned in DriverImageHandle.\r
+ @retval EFI_NOT_FOUND A driver override for ControllerHandle was not\r
+ found.\r
+ @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is not a\r
+ valid handle. DriverImageHandle is not a handle\r
+ that was returned on a previous call to\r
+ GetDriver().\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetDriver (\r
+ IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN OUT EFI_HANDLE *DriverImageHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Check that ControllerHandle is a valid handle\r
+ //\r
+ if (ControllerHandle == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Read the environment variable(s) that contain the override mappings from Controller Device Path to\r
+ // a set of Driver Device Paths, and initialize in memory database of the overrides that map Controller\r
+ // Device Paths to an ordered set of Driver Device Paths and Driver Handles. This action is only performed\r
+ // once and finished in first call.\r
+ //\r
+ if (!mEnvironmentVariableRead) {\r
+ mEnvironmentVariableRead = TRUE;\r
+\r
+ Status = InitOverridesMapping (&mMappingDataBase);\r
+ if (EFI_ERROR (Status)){\r
+ DEBUG ((DEBUG_ERROR, "The status to Get Platform Driver Override Variable is %r\n", Status));\r
+ InitializeListHead (&mMappingDataBase);\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ }\r
+\r
+ //\r
+ // if the environment variable does not exist, just return not found\r
+ //\r
+ if (IsListEmpty (&mMappingDataBase)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ return GetDriverFromMapping (\r
+ ControllerHandle,\r
+ DriverImageHandle,\r
+ &mMappingDataBase,\r
+ mCallerImageHandle\r
+ );\r
+}\r
+\r
+/**\r
+ Retrieves the device path of the platform override driver for a controller in the system.\r
+ This driver doesn't support this API.\r
+\r
+ @param This A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_\r
+ PROTOCOL instance. \r
+ @param ControllerHandle The device handle of the controller to check if a driver override\r
+ exists. \r
+ @param DriverImagePath On input, a pointer to the previous driver device path returned by\r
+ GetDriverPath(). On output, a pointer to the next driver\r
+ device path. Passing in a pointer to NULL, will return the first\r
+ driver device path for ControllerHandle.\r
+ \r
+ @retval EFI_UNSUPPORTED\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetDriverPath (\r
+ IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DriverImagePath\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+\r
+/**\r
+ Used to associate a driver image handle with a device path that was returned on a prior call to the\r
+ GetDriverPath() service. This driver image handle will then be available through the \r
+ GetDriver() service. This driver doesn't support this API.\r
+\r
+ @param This A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_\r
+ PROTOCOL instance. \r
+ @param ControllerHandle The device handle of the controller. \r
+ @param DriverImagePath A pointer to the driver device path that was returned in a prior\r
+ call to GetDriverPath(). \r
+ @param DriverImageHandle The driver image handle that was returned by LoadImage()\r
+ when the driver specified by DriverImagePath was loaded \r
+ into memory. \r
+ \r
+ @retval EFI_UNSUPPORTED\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverLoaded (\r
+ IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath,\r
+ IN EFI_HANDLE DriverImageHandle\r
+ )\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+ The driver Entry Point. The funciton will export a disk device class formset and\r
+ its callback function to hii database.\r
+\r
+ @param ImageHandle The firmware allocated handle for the EFI image.\r
+ @param SystemTable A pointer to the EFI System Table.\r
+\r
+ @retval EFI_SUCCESS The entry point is executed successfully.\r
+ @retval other Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PlatDriOverrideDxeInit (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;\r
+ VOID *Instance;\r
+ \r
+ //\r
+ // There should only be one Form Configuration protocol\r
+ //\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiFormBrowser2ProtocolGuid,\r
+ NULL,\r
+ (VOID **) &FormBrowser2\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // According to UEFI spec, there can be at most a single instance\r
+ // in the system of the EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL.\r
+ // So here we check the existence.\r
+ //\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiPlatformDriverOverrideProtocolGuid,\r
+ NULL,\r
+ &Instance\r
+ );\r
+ //\r
+ // If there was no error, assume there is an installation and return error\r
+ //\r
+ if (!EFI_ERROR (Status)) {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+ \r
+ mCallerImageHandle = ImageHandle;\r
+ mCallbackInfo = AllocateZeroPool (sizeof (EFI_CALLBACK_INFO));\r
+ if (mCallbackInfo == NULL) {\r
+ return EFI_BAD_BUFFER_SIZE;\r
+ }\r
+\r
+ mCallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;\r
+ mCallbackInfo->ConfigAccess.ExtractConfig = PlatOverMngrExtractConfig;\r
+ mCallbackInfo->ConfigAccess.RouteConfig = PlatOverMngrRouteConfig;\r
+ mCallbackInfo->ConfigAccess.Callback = PlatOverMngrCallback;\r
+ mCallbackInfo->PlatformDriverOverride.GetDriver = GetDriver;\r
+ mCallbackInfo->PlatformDriverOverride.GetDriverPath = GetDriverPath;\r
+ mCallbackInfo->PlatformDriverOverride.DriverLoaded = DriverLoaded;\r
+ //\r
+ // Install Device Path Protocol and Config Access protocol to driver handle\r
+ // Install Platform Driver Override Protocol to driver handle\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &mCallbackInfo->DriverHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ &mHiiVendorDevicePath,\r
+ &gEfiHiiConfigAccessProtocolGuid,\r
+ &mCallbackInfo->ConfigAccess,\r
+ &gEfiPlatformDriverOverrideProtocolGuid,\r
+ &mCallbackInfo->PlatformDriverOverride,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Finish;\r
+ }\r
+\r
+ //\r
+ // Publish our HII data\r
+ //\r
+ mCallbackInfo->RegisteredHandle = HiiAddPackages (\r
+ &mPlatformOverridesManagerGuid,\r
+ mCallbackInfo->DriverHandle,\r
+ VfrBin,\r
+ PlatDriOverrideDxeStrings,\r
+ NULL\r
+ );\r
+ if (mCallbackInfo->RegisteredHandle == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Finish;\r
+ }\r
+\r
+ //\r
+ // Locate ConfigRouting protocol\r
+ //\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiHiiConfigRoutingProtocolGuid,\r
+ NULL,\r
+ (VOID **) &mCallbackInfo->HiiConfigRouting\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Finish;\r
+ }\r
+\r
+ //\r
+ // Clear all the globle variable\r
+ //\r
+ mDriverImageHandleCount = 0;\r
+ mCurrentPage = 0;\r
+ ZeroMem (mDriverImageToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
+ ZeroMem (mDriverImageFilePathToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
+ ZeroMem (mControllerToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
+ ZeroMem (mDriverImageProtocol, MAX_CHOICE_NUM * sizeof (EFI_LOADED_IMAGE_PROTOCOL *));\r
+ \r
+ return EFI_SUCCESS;\r
+\r
+Finish:\r
+ if (mCallbackInfo->DriverHandle != NULL) {\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ mCallbackInfo->DriverHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ &mHiiVendorDevicePath,\r
+ &gEfiHiiConfigAccessProtocolGuid,\r
+ &mCallbackInfo->ConfigAccess,\r
+ &gEfiPlatformDriverOverrideProtocolGuid,\r
+ &mCallbackInfo->PlatformDriverOverride,\r
+ NULL\r
+ );\r
+ }\r
+ \r
+ if (mCallbackInfo->RegisteredHandle != NULL) {\r
+ HiiRemovePackages (mCallbackInfo->RegisteredHandle);\r
+ }\r
+\r
+ if (mCallbackInfo != NULL) {\r
+ FreePool (mCallbackInfo);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Unload its installed protocol.\r
+\r
+ @param[in] ImageHandle Handle that identifies the image to be unloaded.\r
+\r
+ @retval EFI_SUCCESS The image has been unloaded.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PlatDriOverrideDxeUnload (\r
+ IN EFI_HANDLE ImageHandle\r
+ )\r
+{\r
+ if (mCallbackInfo->DriverHandle != NULL) {\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ mCallbackInfo->DriverHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ &mHiiVendorDevicePath,\r
+ &gEfiHiiConfigAccessProtocolGuid,\r
+ &mCallbackInfo->ConfigAccess,\r
+ &gEfiPlatformDriverOverrideProtocolGuid,\r
+ &mCallbackInfo->PlatformDriverOverride,\r
+ NULL\r
+ );\r
+ }\r
+\r
+ if (mCallbackInfo->RegisteredHandle != NULL) {\r
+ HiiRemovePackages (mCallbackInfo->RegisteredHandle);\r
+ }\r
+\r
+ if (mCallbackInfo != NULL) {\r
+ FreePool (mCallbackInfo);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/** @file\r
+ Implementation of the shared functions to do the platform driver vverride mapping.\r
+\r
+ Copyright (c) 2007 - 2009, Intel Corporation\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "InternalPlatDriOverrideDxe.h"\r
+\r
+#define PLATFORM_OVERRIDE_ITEM_SIGNATURE SIGNATURE_32('p','d','o','i')\r
+ typedef struct _PLATFORM_OVERRIDE_ITEM {\r
+ UINTN Signature;\r
+ LIST_ENTRY Link;\r
+ UINT32 DriverInfoNum;\r
+ EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;\r
+ ///\r
+ /// List of DRIVER_IMAGE_INFO\r
+ ///\r
+ LIST_ENTRY DriverInfoList;\r
+ EFI_HANDLE LastReturnedImageHandle;\r
+} PLATFORM_OVERRIDE_ITEM;\r
+\r
+#define DRIVER_IMAGE_INFO_SIGNATURE SIGNATURE_32('p','d','i','i')\r
+typedef struct _DRIVER_IMAGE_INFO {\r
+ UINTN Signature;\r
+ LIST_ENTRY Link;\r
+ EFI_HANDLE ImageHandle;\r
+ EFI_DEVICE_PATH_PROTOCOL *DriverImagePath;\r
+ BOOLEAN UnLoadable;\r
+ BOOLEAN UnStartable;\r
+} DRIVER_IMAGE_INFO;\r
+\r
+#define DEVICE_PATH_STACK_ITEM_SIGNATURE SIGNATURE_32('d','p','s','i')\r
+typedef struct _DEVICE_PATH_STACK_ITEM{\r
+ UINTN Signature;\r
+ LIST_ENTRY Link;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+} DEVICE_PATH_STACK_ITEM;\r
+\r
+\r
+LIST_ENTRY mDevicePathStack = INITIALIZE_LIST_HEAD_VARIABLE (mDevicePathStack);\r
+\r
+/**\r
+ Push a controller device path into a globle device path list.\r
+\r
+ @param DevicePath The controller device path to push into stack\r
+\r
+ @retval EFI_SUCCESS Device path successfully pushed into the stack.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PushDevPathStack (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
+ )\r
+{\r
+ DEVICE_PATH_STACK_ITEM *DevicePathStackItem;\r
+\r
+ DevicePathStackItem = AllocateZeroPool (sizeof (DEVICE_PATH_STACK_ITEM));\r
+ ASSERT (DevicePathStackItem != NULL);\r
+ DevicePathStackItem->Signature = DEVICE_PATH_STACK_ITEM_SIGNATURE;\r
+ DevicePathStackItem->DevicePath = DuplicateDevicePath (DevicePath);\r
+ InsertTailList (&mDevicePathStack, &DevicePathStackItem->Link);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Pop a controller device path from a globle device path list\r
+\r
+ @param DevicePath The controller device path popped from stack\r
+\r
+ @retval EFI_SUCCESS Controller device path successfully popped.\r
+ @retval EFI_NOT_FOUND Stack is empty.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PopDevPathStack (\r
+ OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
+ )\r
+{\r
+ DEVICE_PATH_STACK_ITEM *DevicePathStackItem;\r
+ LIST_ENTRY *ItemListIndex;\r
+\r
+ ItemListIndex = mDevicePathStack.BackLink;\r
+ //\r
+ // Check if the stack is empty\r
+ //\r
+ if (ItemListIndex != &mDevicePathStack){\r
+ DevicePathStackItem = CR(ItemListIndex, DEVICE_PATH_STACK_ITEM, Link, DEVICE_PATH_STACK_ITEM_SIGNATURE);\r
+ if (DevicePath != NULL) {\r
+ *DevicePath = DuplicateDevicePath (DevicePathStackItem->DevicePath);\r
+ }\r
+ FreePool (DevicePathStackItem->DevicePath);\r
+ RemoveEntryList (&DevicePathStackItem->Link);\r
+ FreePool (DevicePathStackItem);\r
+ return EFI_SUCCESS;\r
+ }\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+/**\r
+ Check whether a controller device path is in a globle device path list\r
+\r
+ @param DevicePath The controller device path to check\r
+\r
+ @retval TRUE DevicePath exists in the stack.\r
+ @retval FALSE DevicePath does not exist in the stack.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+CheckExistInStack (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
+ )\r
+{\r
+ DEVICE_PATH_STACK_ITEM *DevicePathStackItem;\r
+ LIST_ENTRY *ItemListIndex;\r
+ UINTN DevicePathSize;\r
+\r
+ ItemListIndex = mDevicePathStack.BackLink;\r
+ while (ItemListIndex != &mDevicePathStack){\r
+ DevicePathStackItem = CR(ItemListIndex, DEVICE_PATH_STACK_ITEM, Link, DEVICE_PATH_STACK_ITEM_SIGNATURE);\r
+ DevicePathSize = GetDevicePathSize (DevicePath);\r
+ if (DevicePathSize == GetDevicePathSize (DevicePathStackItem->DevicePath)) {\r
+ if (CompareMem (DevicePath, DevicePathStackItem->DevicePath, DevicePathSize) == 0) {\r
+ return TRUE;\r
+ }\r
+ }\r
+ ItemListIndex = ItemListIndex->BackLink;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Update the FV file device path if it is not valid.\r
+\r
+ According to a file GUID, check a Fv file device path is valid. If it is invalid,\r
+ try to return the valid device path.\r
+ FV address maybe changes for memory layout adjust from time to time, use this funciton\r
+ could promise the Fv file device path is right.\r
+\r
+ @param DevicePath On input, the FV file device path to check\r
+ On output, the updated valid FV file device path\r
+ @param FileGuid The FV file GUID\r
+ @param CallerImageHandle Image handle of the caller\r
+\r
+ @retval EFI_INVALID_PARAMETER the input DevicePath or FileGuid is invalid\r
+ parameter\r
+ @retval EFI_UNSUPPORTED the input DevicePath does not contain FV file\r
+ GUID at all\r
+ @retval EFI_ALREADY_STARTED the input DevicePath has pointed to FV file, it\r
+ is valid\r
+ @retval EFI_SUCCESS Successfully updated the invalid DevicePath,\r
+ and return the updated device path in DevicePath\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UpdateFvFileDevicePath (\r
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,\r
+ IN EFI_GUID *FileGuid,\r
+ IN EFI_HANDLE CallerImageHandle\r
+ )\r
+{\r
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode;\r
+ EFI_STATUS Status;\r
+ EFI_GUID *GuidPoint;\r
+ UINTN Index;\r
+ UINTN FvHandleCount;\r
+ EFI_HANDLE *FvHandleBuffer;\r
+ EFI_FV_FILETYPE Type;\r
+ UINTN Size;\r
+ EFI_FV_FILE_ATTRIBUTES Attributes;\r
+ UINT32 AuthenticationStatus;\r
+ BOOLEAN FindFvFile;\r
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileNode;\r
+ EFI_HANDLE FoundFvHandle;\r
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
+ BOOLEAN HasFvNode;\r
+\r
+ if (DevicePath == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (*DevicePath == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Check whether the device path points to the default the input FV file\r
+ //\r
+ TempDevicePath = *DevicePath;\r
+ LastDeviceNode = TempDevicePath;\r
+ while (!IsDevicePathEnd (TempDevicePath)) {\r
+ LastDeviceNode = TempDevicePath;\r
+ TempDevicePath = NextDevicePathNode (TempDevicePath);\r
+ }\r
+ GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode);\r
+ if (GuidPoint == NULL) {\r
+ //\r
+ // If this option does not point to a FV file, just return EFI_UNSUPPORTED.\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if (FileGuid != NULL) {\r
+ if (!CompareGuid (GuidPoint, FileGuid)) {\r
+ //\r
+ // If the FV file is not the input file GUID, just return EFI_UNSUPPORTED\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ } else {\r
+ FileGuid = GuidPoint;\r
+ }\r
+\r
+ //\r
+ // Check to see if the device path contains memory map node\r
+ //\r
+ TempDevicePath = *DevicePath;\r
+ HasFvNode = FALSE;\r
+ while (!IsDevicePathEnd (TempDevicePath)) {\r
+ //\r
+ // Use old Device Path\r
+ //\r
+ if (DevicePathType (TempDevicePath) == HARDWARE_DEVICE_PATH &&\r
+ DevicePathSubType (TempDevicePath) == HW_MEMMAP_DP) {\r
+ HasFvNode = TRUE;\r
+ break;\r
+ }\r
+ TempDevicePath = NextDevicePathNode (TempDevicePath);\r
+ }\r
+\r
+ if (!HasFvNode) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Check whether the input Fv file device path is valid\r
+ //\r
+ TempDevicePath = *DevicePath;\r
+ FoundFvHandle = NULL;\r
+ Status = gBS->LocateDevicePath (\r
+ &gEfiFirmwareVolume2ProtocolGuid,\r
+ &TempDevicePath,\r
+ &FoundFvHandle\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->HandleProtocol (\r
+ FoundFvHandle,\r
+ &gEfiFirmwareVolume2ProtocolGuid,\r
+ (VOID **) &Fv\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Set FV ReadFile Buffer as NULL, only need to check whether input Fv file exist there\r
+ //\r
+ Status = Fv->ReadFile (\r
+ Fv,\r
+ FileGuid,\r
+ NULL,\r
+ &Size,\r
+ &Type,\r
+ &Attributes,\r
+ &AuthenticationStatus\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Look for the input wanted FV file in current FV\r
+ // First, try to look for in Caller own FV. Caller and input wanted FV file usually are in the same FV\r
+ //\r
+ FindFvFile = FALSE;\r
+ FoundFvHandle = NULL;\r
+ Status = gBS->HandleProtocol (\r
+ CallerImageHandle,\r
+ &gEfiLoadedImageProtocolGuid,\r
+ (VOID **) &LoadedImage\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->HandleProtocol (\r
+ LoadedImage->DeviceHandle,\r
+ &gEfiFirmwareVolume2ProtocolGuid,\r
+ (VOID **) &Fv\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = Fv->ReadFile (\r
+ Fv,\r
+ FileGuid,\r
+ NULL,\r
+ &Size,\r
+ &Type,\r
+ &Attributes,\r
+ &AuthenticationStatus\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ FindFvFile = TRUE;\r
+ FoundFvHandle = LoadedImage->DeviceHandle;\r
+ }\r
+ }\r
+ }\r
+ //\r
+ // Second, if fail to find, try to enumerate all FV\r
+ //\r
+ if (!FindFvFile) {\r
+ gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiFirmwareVolume2ProtocolGuid,\r
+ NULL,\r
+ &FvHandleCount,\r
+ &FvHandleBuffer\r
+ );\r
+ for (Index = 0; Index < FvHandleCount; Index++) {\r
+ gBS->HandleProtocol (\r
+ FvHandleBuffer[Index],\r
+ &gEfiFirmwareVolume2ProtocolGuid,\r
+ (VOID **) &Fv\r
+ );\r
+\r
+ Status = Fv->ReadFile (\r
+ Fv,\r
+ FileGuid,\r
+ NULL,\r
+ &Size,\r
+ &Type,\r
+ &Attributes,\r
+ &AuthenticationStatus\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Skip if input Fv file not in the FV\r
+ //\r
+ continue;\r
+ }\r
+ FindFvFile = TRUE;\r
+ FoundFvHandle = FvHandleBuffer[Index];\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (FindFvFile) {\r
+ //\r
+ // Build the shell device path\r
+ //\r
+ NewDevicePath = DevicePathFromHandle (FoundFvHandle);\r
+ EfiInitializeFwVolDevicepathNode (&FvFileNode, FileGuid);\r
+ NewDevicePath = AppendDevicePathNode (NewDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &FvFileNode);\r
+ *DevicePath = NewDevicePath;\r
+ return EFI_SUCCESS;\r
+ }\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+ Gets the data and size of a variable.\r
+\r
+ Read the EFI variable (VendorGuid/Name) and return a dynamically allocated\r
+ buffer, and the size of the buffer. If failure return NULL.\r
+\r
+ @param Name String part of EFI variable name\r
+ @param VendorGuid GUID part of EFI variable name\r
+ @param VariableSize Returns the size of the EFI variable that was\r
+ read\r
+\r
+ @return Dynamically allocated memory that contains a copy of the EFI variable.\r
+ Caller is responsible freeing the buffer.\r
+ @retval NULL Variable was not read\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetVariableAndSize (\r
+ IN CHAR16 *Name,\r
+ IN EFI_GUID *VendorGuid,\r
+ OUT UINTN *VariableSize\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN BufferSize;\r
+ VOID *Buffer;\r
+\r
+ Buffer = NULL;\r
+\r
+ //\r
+ // Pass in a zero size buffer to find the required buffer size.\r
+ //\r
+ BufferSize = 0;\r
+ Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ //\r
+ // Allocate the buffer to return\r
+ //\r
+ Buffer = AllocateZeroPool (BufferSize);\r
+ if (Buffer == NULL) {\r
+ return NULL;\r
+ }\r
+ //\r
+ // Read variable into the allocated buffer.\r
+ //\r
+ Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);\r
+ if (EFI_ERROR (Status)) {\r
+ BufferSize = 0;\r
+ }\r
+ }\r
+\r
+ *VariableSize = BufferSize;\r
+ return Buffer;\r
+}\r
+\r
+/**\r
+ Connect to the handle to a device on the device path.\r
+\r
+ This function will create all handles associate with every device\r
+ path node. If the handle associate with one device path node can not\r
+ be created success, then still give one chance to do the dispatch,\r
+ which load the missing drivers if possible.\r
+\r
+ @param DevicePathToConnect The device path which will be connected, it can\r
+ be a multi-instance device path\r
+\r
+ @retval EFI_SUCCESS All handles associate with every device path\r
+ node have been created\r
+ @retval EFI_OUT_OF_RESOURCES There is no resource to create new handles\r
+ @retval EFI_NOT_FOUND Create the handle associate with one device\r
+ path node failed\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ConnectDevicePath (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *Instance;\r
+ EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *Next;\r
+ EFI_HANDLE Handle;\r
+ EFI_HANDLE PreviousHandle;\r
+ UINTN Size;\r
+\r
+ if (DevicePathToConnect == NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ DevicePath = DuplicateDevicePath (DevicePathToConnect);\r
+ CopyOfDevicePath = DevicePath;\r
+ if (DevicePath == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ do {\r
+ //\r
+ // The outer loop handles multi instance device paths.\r
+ // Only console variables contain multiple instance device paths.\r
+ //\r
+ // After this call DevicePath points to the next Instance\r
+ //\r
+ Instance = GetNextDevicePathInstance (&DevicePath, &Size);\r
+ ASSERT (Instance != NULL);\r
+\r
+ Next = Instance;\r
+ while (!IsDevicePathEndType (Next)) {\r
+ Next = NextDevicePathNode (Next);\r
+ }\r
+\r
+ SetDevicePathEndNode (Next);\r
+\r
+ //\r
+ // Start the real work of connect with RemainingDevicePath\r
+ //\r
+ PreviousHandle = NULL;\r
+ do {\r
+ //\r
+ // Find the handle that best matches the Device Path. If it is only a\r
+ // partial match the remaining part of the device path is returned in\r
+ // RemainingDevicePath.\r
+ //\r
+ RemainingDevicePath = Instance;\r
+ Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle);\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ if (Handle == PreviousHandle) {\r
+ //\r
+ // If no forward progress is made try invoking the Dispatcher.\r
+ // A new FV may have been added to the system an new drivers\r
+ // may now be found.\r
+ // Status == EFI_SUCCESS means a driver was dispatched\r
+ // Status == EFI_NOT_FOUND means no new drivers were dispatched\r
+ //\r
+ Status = gDS->Dispatch ();\r
+ }\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ PreviousHandle = Handle;\r
+ //\r
+ // Connect all drivers that apply to Handle and RemainingDevicePath,\r
+ // the Recursive flag is FALSE so only one level will be expanded.\r
+ //\r
+ // Do not check the connect status here, if the connect controller fail,\r
+ // then still give the chance to do dispatch, because partial\r
+ // RemainingDevicepath may be in the new FV\r
+ //\r
+ // 1. If the connect fails, RemainingDevicepath and handle will not\r
+ // change, so next time will do the dispatch, then dispatch's status\r
+ // will take effect\r
+ // 2. If the connect succeeds, the RemainingDevicepath and handle will\r
+ // change, then avoid the dispatch, we have chance to continue the\r
+ // next connection\r
+ //\r
+ gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);\r
+ }\r
+ }\r
+ //\r
+ // Loop until RemainingDevicePath is an empty device path\r
+ //\r
+ } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));\r
+\r
+ } while (DevicePath != NULL);\r
+\r
+ if (CopyOfDevicePath != NULL) {\r
+ FreePool (CopyOfDevicePath);\r
+ }\r
+ //\r
+ // All handle with DevicePath exists in the handle database\r
+ //\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Free all the mapping database memory resource and initialize the mapping list entry.\r
+\r
+ @param MappingDataBase Mapping database list entry pointer\r
+\r
+ @retval EFI_SUCCESS Mapping database successfully freed\r
+ @retval EFI_INVALID_PARAMETER MappingDataBase is NULL\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FreeMappingDatabase (\r
+ IN OUT LIST_ENTRY *MappingDataBase\r
+ )\r
+{\r
+ LIST_ENTRY *OverrideItemListIndex;\r
+ LIST_ENTRY *ImageInfoListIndex;\r
+ PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
+ DRIVER_IMAGE_INFO *DriverImageInfo;\r
+\r
+ if (MappingDataBase == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ OverrideItemListIndex = GetFirstNode (MappingDataBase);\r
+ while (!IsNull (MappingDataBase, OverrideItemListIndex)) {\r
+ OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE);\r
+ //\r
+ // Free PLATFORM_OVERRIDE_ITEM.ControllerDevicePath[]\r
+ //\r
+ if (OverrideItem->ControllerDevicePath != NULL){\r
+ FreePool (OverrideItem->ControllerDevicePath);\r
+ }\r
+\r
+ ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
+ while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
+ //\r
+ // Free DRIVER_IMAGE_INFO.DriverImagePath[]\r
+ //\r
+ DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
+ if (DriverImageInfo->DriverImagePath != NULL) {\r
+ FreePool(DriverImageInfo->DriverImagePath);\r
+ }\r
+ //\r
+ // Free DRIVER_IMAGE_INFO itself\r
+ //\r
+ ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
+ RemoveEntryList (&DriverImageInfo->Link);\r
+ FreePool (DriverImageInfo);\r
+ }\r
+ //\r
+ // Free PLATFORM_OVERRIDE_ITEM itself\r
+ //\r
+ OverrideItemListIndex = GetNextNode (MappingDataBase, OverrideItemListIndex);\r
+ RemoveEntryList (&OverrideItem->Link);\r
+ FreePool (OverrideItem);\r
+ }\r
+\r
+ InitializeListHead (MappingDataBase);\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Create the mapping database according to variable.\r
+\r
+ Read the environment variable(s) that contain the override mappings from Controller Device Path to\r
+ a set of Driver Device Paths, and create the mapping database in memory with those variable info.\r
+ VariableLayout{\r
+ //\r
+ // NotEnd indicate whether the variable is the last one, and has no subsequent variable need to load.\r
+ // Each variable has MaximumVariableSize limitation, so we maybe need multiple variables to store\r
+ // large mapping infos.\r
+ // The variable(s) name rule is PlatDriOver, PlatDriOver1, PlatDriOver2, ....\r
+ //\r
+ UINT32 NotEnd; //Zero is the last one.\r
+ //\r
+ // The entry which contains the mapping that Controller Device Path to a set of Driver Device Paths\r
+ // There are often multi mapping entries in a variable.\r
+ //\r
+ UINT32 SIGNATURE; //SIGNATURE_32('p','d','o','i')\r
+ UINT32 DriverNum;\r
+ EFI_DEVICE_PATH_PROTOCOL ControllerDevicePath[];\r
+ EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
+ EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
+ EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
+ ......\r
+ UINT32 NotEnd; //Zero is the last one.\r
+ UINT32 SIGNATURE;\r
+ UINT32 DriverNum;\r
+ EFI_DEVICE_PATH_PROTOCOL ControllerDevicePath[];\r
+ EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
+ EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
+ EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[];\r
+ ......\r
+ }\r
+\r
+ @param MappingDataBase Mapping database list entry pointer\r
+\r
+ @retval EFI_SUCCESS Create the mapping database in memory successfully\r
+ @retval EFI_INVALID_PARAMETER MappingDataBase pointer is null\r
+ @retval EFI_NOT_FOUND Cannot find the 'PlatDriOver' NV variable\r
+ @retval EFI_VOLUME_CORRUPTED The found NV variable is corrupted\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitOverridesMapping (\r
+ OUT LIST_ENTRY *MappingDataBase\r
+ )\r
+{\r
+ UINTN BufferSize;\r
+ VOID *VariableBuffer;\r
+ UINT8 *VariableIndex;\r
+ UINTN VariableNum;\r
+ CHAR16 OverrideVariableName[40];\r
+ UINT32 NotEnd;\r
+ UINT32 DriverNumber;\r
+ PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
+ DRIVER_IMAGE_INFO *DriverImageInfo;\r
+ BOOLEAN Corrupted;\r
+ UINT32 Signature;\r
+ EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *DriverDevicePath;\r
+ UINTN Index;\r
+\r
+ if (MappingDataBase == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Check the environment variable(s) that contain the override mappings .\r
+ //\r
+ VariableBuffer = GetVariableAndSize (L"PlatDriOver", &gEfiCallerIdGuid, &BufferSize);\r
+ ASSERT ((UINTN) VariableBuffer % sizeof(UINTN) == 0);\r
+ if (VariableBuffer == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Traverse all variables.\r
+ //\r
+ VariableNum = 1;\r
+ Corrupted = FALSE;\r
+ do {\r
+ VariableIndex = VariableBuffer;\r
+ //\r
+ // End flag\r
+ //\r
+ NotEnd = *(UINT32*) VariableIndex;\r
+ //\r
+ // Traverse the entries containing the mapping that Controller Device Path\r
+ // to a set of Driver Device Paths within this variable.\r
+ //\r
+ VariableIndex = VariableIndex + sizeof (UINT32);\r
+ while (VariableIndex < ((UINT8 *)VariableBuffer + BufferSize)) {\r
+ //\r
+ // Check signature of this entry\r
+ //\r
+ Signature = *(UINT32 *) VariableIndex;\r
+ if (Signature != PLATFORM_OVERRIDE_ITEM_SIGNATURE) {\r
+ Corrupted = TRUE;\r
+ break;\r
+ }\r
+ //\r
+ // Create PLATFORM_OVERRIDE_ITEM for this mapping\r
+ //\r
+ OverrideItem = AllocateZeroPool (sizeof (PLATFORM_OVERRIDE_ITEM));\r
+ ASSERT (OverrideItem != NULL);\r
+ OverrideItem->Signature = PLATFORM_OVERRIDE_ITEM_SIGNATURE;\r
+ InitializeListHead (&OverrideItem->DriverInfoList);\r
+ VariableIndex = VariableIndex + sizeof (UINT32);\r
+ //\r
+ // Get DriverNum\r
+ //\r
+ DriverNumber = *(UINT32*) VariableIndex;\r
+ OverrideItem->DriverInfoNum = DriverNumber;\r
+ VariableIndex = VariableIndex + sizeof (UINT32);\r
+ //\r
+ // Get ControllerDevicePath[]\r
+ //\r
+ ControllerDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) VariableIndex;\r
+ OverrideItem->ControllerDevicePath = DuplicateDevicePath (ControllerDevicePath);\r
+ VariableIndex = VariableIndex + GetDevicePathSize (ControllerDevicePath);\r
+ //\r
+ // Align the VariableIndex since the controller device path may not be aligned, refer to the SaveOverridesMapping()\r
+ //\r
+ VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1));\r
+\r
+ //\r
+ // Get all DriverImageDevicePath[]\r
+ //\r
+ for (Index = 0; Index < DriverNumber; Index++) {\r
+ //\r
+ // Create DRIVER_IMAGE_INFO for this DriverDevicePath[]\r
+ //\r
+ DriverImageInfo = AllocateZeroPool (sizeof (DRIVER_IMAGE_INFO));\r
+ ASSERT (DriverImageInfo != NULL);\r
+ DriverImageInfo->Signature = DRIVER_IMAGE_INFO_SIGNATURE;\r
+\r
+ DriverDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) VariableIndex;\r
+ DriverImageInfo->DriverImagePath = DuplicateDevicePath (DriverDevicePath);\r
+ VariableIndex = VariableIndex + GetDevicePathSize (DriverDevicePath);\r
+ //\r
+ // Align the VariableIndex since the driver image device path may not be aligned, refer to the SaveOverridesMapping()\r
+ //\r
+ VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1));\r
+\r
+ InsertTailList (&OverrideItem->DriverInfoList, &DriverImageInfo->Link);\r
+ }\r
+ InsertTailList (MappingDataBase, &OverrideItem->Link);\r
+ }\r
+\r
+ FreePool (VariableBuffer);\r
+ if (Corrupted) {\r
+ FreeMappingDatabase (MappingDataBase);\r
+ return EFI_VOLUME_CORRUPTED;\r
+ }\r
+\r
+ //\r
+ // If there are additional variables (PlatDriOver1, PlatDriOver2, PlatDriOver3.....), get them.\r
+ // NotEnd indicates whether current variable is the end variable.\r
+ //\r
+ if (NotEnd != 0) {\r
+ UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver%d", VariableNum++);\r
+ VariableBuffer = GetVariableAndSize (OverrideVariableName, &gEfiCallerIdGuid, &BufferSize);\r
+ ASSERT ((UINTN) VariableBuffer % sizeof(UINTN) == 0);\r
+ if (VariableBuffer == NULL) {\r
+ FreeMappingDatabase (MappingDataBase);\r
+ return EFI_VOLUME_CORRUPTED;\r
+ }\r
+ }\r
+\r
+ } while (NotEnd != 0);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Calculate the needed size in NV variable for recording a specific PLATFORM_OVERRIDE_ITEM info.\r
+\r
+ @param OverrideItemListIndex Pointer to the list of a specific PLATFORM_OVERRIDE_ITEM\r
+\r
+ @return The needed size number\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+GetOneItemNeededSize (\r
+ IN LIST_ENTRY *OverrideItemListIndex\r
+ )\r
+{\r
+ UINTN NeededSize;\r
+ PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
+ LIST_ENTRY *ImageInfoListIndex;\r
+ DRIVER_IMAGE_INFO *DriverImageInfo;\r
+ UINTN DevicePathSize;\r
+\r
+ NeededSize = 0;\r
+ OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE);\r
+ NeededSize += sizeof (UINT32); //UINT32 SIGNATURE;\r
+ NeededSize += sizeof (UINT32); //UINT32 DriverNum;\r
+ DevicePathSize = GetDevicePathSize (OverrideItem->ControllerDevicePath);\r
+ NeededSize += DevicePathSize; // ControllerDevicePath\r
+ //\r
+ // Align the controller device path\r
+ //\r
+ NeededSize += ((sizeof(UINT32) - DevicePathSize) & (sizeof(UINT32) - 1));\r
+ //\r
+ // Traverse the Driver Info List of this Override Item\r
+ //\r
+ ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
+ while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
+ DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
+ DevicePathSize = GetDevicePathSize (DriverImageInfo->DriverImagePath);\r
+ NeededSize += DevicePathSize; //DriverDevicePath\r
+ //\r
+ // Align the driver image device path\r
+ //\r
+ NeededSize += ((sizeof(UINT32) - DevicePathSize) & (sizeof(UINT32) - 1));\r
+ ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
+ }\r
+\r
+ return NeededSize;\r
+}\r
+\r
+/**\r
+ Deletes all environment variable(s) that contain the override mappings from Controller Device Path to\r
+ a set of Driver Device Paths.\r
+\r
+ @retval EFI_SUCCESS Delete all variable(s) successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DeleteOverridesVariables (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VOID *VariableBuffer;\r
+ UINTN VariableNum;\r
+ UINTN BufferSize;\r
+ UINTN Index;\r
+ CHAR16 OverrideVariableName[40];\r
+\r
+ //\r
+ // Get environment variable(s) number\r
+ //\r
+ VariableNum = 0;\r
+ VariableBuffer = GetVariableAndSize (L"PlatDriOver", &gEfiCallerIdGuid, &BufferSize);\r
+ VariableNum++;\r
+ if (VariableBuffer == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ //\r
+ // Check NotEnd to get all PlatDriOverX variable(s)\r
+ //\r
+ while ((*(UINT32*)VariableBuffer) != 0) {\r
+ UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver%d", VariableNum);\r
+ VariableBuffer = GetVariableAndSize (OverrideVariableName, &gEfiCallerIdGuid, &BufferSize);\r
+ VariableNum++;\r
+ ASSERT (VariableBuffer != NULL);\r
+ }\r
+\r
+ //\r
+ // Delete PlatDriOver and all additional variables, if exist.\r
+ //\r
+ Status = gRT->SetVariable (\r
+ L"PlatDriOver",\r
+ &gEfiCallerIdGuid,\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+ 0,\r
+ NULL\r
+ );\r
+ ASSERT (!EFI_ERROR (Status));\r
+ for (Index = 1; Index < VariableNum; Index++) {\r
+ UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver%d", Index);\r
+ Status = gRT->SetVariable (\r
+ OverrideVariableName,\r
+ &gEfiCallerIdGuid,\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+ 0,\r
+ NULL\r
+ );\r
+ ASSERT (!EFI_ERROR (Status));\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Save the memory mapping database into NV environment variable(s).\r
+\r
+ @param MappingDataBase Mapping database list entry pointer\r
+\r
+ @retval EFI_SUCCESS Save memory mapping database successfully\r
+ @retval EFI_INVALID_PARAMETER MappingDataBase pointer is null\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SaveOverridesMapping (\r
+ IN LIST_ENTRY *MappingDataBase\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VOID *VariableBuffer;\r
+ UINT8 *VariableIndex;\r
+ UINTN NumIndex;\r
+ CHAR16 OverrideVariableName[40];\r
+ UINT32 NotEnd;\r
+ PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
+ DRIVER_IMAGE_INFO *DriverImageInfo;\r
+ LIST_ENTRY *OverrideItemListIndex;\r
+ LIST_ENTRY *ItemIndex;\r
+ LIST_ENTRY *ImageInfoListIndex;\r
+ UINTN VariableNeededSize;\r
+ UINT64 MaximumVariableStorageSize;\r
+ UINT64 RemainingVariableStorageSize;\r
+ UINT64 MaximumVariableSize;\r
+ UINTN OneItemNeededSize;\r
+\r
+ if (MappingDataBase == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (IsListEmpty (MappingDataBase)) {\r
+ Status = DeleteOverridesVariables ();\r
+ ASSERT_EFI_ERROR (Status);\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Get the the maximum size of an individual EFI variable in current system\r
+ //\r
+ gRT->QueryVariableInfo (\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+ &MaximumVariableStorageSize,\r
+ &RemainingVariableStorageSize,\r
+ &MaximumVariableSize\r
+ );\r
+\r
+ NumIndex = 0;\r
+ OverrideItemListIndex = GetFirstNode (MappingDataBase);\r
+ while (!IsNull (MappingDataBase, OverrideItemListIndex)) {\r
+ //\r
+ // Try to find the most proper variable size which <= MaximumVariableSize,\r
+ // but can contain mapping info as much as possible\r
+ //\r
+ VariableNeededSize = sizeof (UINT32); // NotEnd;\r
+ ItemIndex = OverrideItemListIndex;\r
+ NotEnd = FALSE;\r
+ //\r
+ // Traverse all PLATFORM_OVERRIDE_ITEMs and get the total size.\r
+ //\r
+ while (!IsNull (MappingDataBase, ItemIndex)) {\r
+ OneItemNeededSize = GetOneItemNeededSize (ItemIndex);\r
+ //\r
+ // If the total size exceeds the MaximumVariableSize, then we must use\r
+ // multiple variables.\r
+ //\r
+ if ((VariableNeededSize +\r
+ OneItemNeededSize +\r
+ sizeof (VARIABLE_HEADER) +\r
+ StrSize (L"PlatDriOver ")\r
+ ) >= MaximumVariableSize\r
+ ) {\r
+ NotEnd = TRUE;\r
+ break;\r
+ }\r
+\r
+ VariableNeededSize += OneItemNeededSize;\r
+ ItemIndex = GetNextNode (MappingDataBase, ItemIndex);\r
+ }\r
+\r
+ if (NotEnd != 0) {\r
+ if (VariableNeededSize == sizeof (UINT32)) {\r
+ //\r
+ // If an individual EFI variable cannot contain a single Item, return error\r
+ //\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ }\r
+\r
+ //\r
+ // VariableNeededSize is the most proper variable size, allocate variable buffer\r
+ // ItemIndex now points to the next PLATFORM_OVERRIDE_ITEM which is not covered by VariableNeededSize\r
+ //\r
+ VariableBuffer = AllocateZeroPool (VariableNeededSize);\r
+ ASSERT (VariableBuffer != NULL);\r
+ ASSERT ((UINTN) VariableBuffer % sizeof(UINTN) == 0);\r
+\r
+ //\r
+ // Fill the variable buffer according to MappingDataBase\r
+ //\r
+ VariableIndex = VariableBuffer;\r
+ *(UINT32 *) VariableIndex = NotEnd;\r
+ VariableIndex += sizeof (UINT32); // pass NotEnd\r
+ //\r
+ // ItemIndex points to the next PLATFORM_OVERRIDE_ITEM which is not covered by VariableNeededSize\r
+ //\r
+ while (OverrideItemListIndex != ItemIndex){\r
+ *(UINT32 *) VariableIndex = PLATFORM_OVERRIDE_ITEM_SIGNATURE;\r
+ VariableIndex += sizeof (UINT32); // pass SIGNATURE\r
+\r
+ OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE);\r
+ *(UINT32 *) VariableIndex = OverrideItem->DriverInfoNum;\r
+ VariableIndex += sizeof (UINT32); // pass DriverNum\r
+\r
+ CopyMem (VariableIndex, OverrideItem->ControllerDevicePath, GetDevicePathSize (OverrideItem->ControllerDevicePath));\r
+ VariableIndex += GetDevicePathSize (OverrideItem->ControllerDevicePath); // pass ControllerDevicePath\r
+\r
+ //\r
+ // Align the VariableIndex since the controller device path may not be aligned\r
+ //\r
+ VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1));\r
+ //\r
+ // Save the Driver Info List of this PLATFORM_OVERRIDE_ITEM\r
+ //\r
+ ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
+ while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
+ DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
+ CopyMem (VariableIndex, DriverImageInfo->DriverImagePath, GetDevicePathSize (DriverImageInfo->DriverImagePath));\r
+ VariableIndex += GetDevicePathSize (DriverImageInfo->DriverImagePath); // pass DriverImageDevicePath\r
+ //\r
+ // Align the VariableIndex since the driver image device path may not be aligned\r
+ //\r
+ VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1));\r
+ ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
+ }\r
+\r
+ OverrideItemListIndex = GetNextNode (MappingDataBase, OverrideItemListIndex);\r
+ }\r
+\r
+ ASSERT (((UINTN)VariableIndex - (UINTN)VariableBuffer) == VariableNeededSize);\r
+\r
+ if (NumIndex == 0) {\r
+ UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver");\r
+ } else {\r
+ UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver%d", NumIndex );\r
+ }\r
+\r
+ Status = gRT->SetVariable (\r
+ OverrideVariableName,\r
+ &gEfiCallerIdGuid,\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+ VariableNeededSize,\r
+ VariableBuffer\r
+ );\r
+ ASSERT (!EFI_ERROR(Status));\r
+\r
+ NumIndex ++;\r
+ FreePool (VariableBuffer);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Get the first Binding protocol which has the specific image handle.\r
+\r
+ @param ImageHandle The Image handle\r
+ @param BindingHandle The BindingHandle of the found Driver Binding protocol.\r
+ If Binding protocol is not found, it is set to NULL. \r
+\r
+ @return Pointer into the Binding Protocol interface\r
+ @retval NULL The paramter is not valid or the binding protocol is not found.\r
+\r
+**/\r
+EFI_DRIVER_BINDING_PROTOCOL *\r
+EFIAPI\r
+GetBindingProtocolFromImageHandle (\r
+ IN EFI_HANDLE ImageHandle,\r
+ OUT EFI_HANDLE *BindingHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ UINTN DriverBindingHandleCount;\r
+ EFI_HANDLE *DriverBindingHandleBuffer;\r
+ EFI_DRIVER_BINDING_PROTOCOL *DriverBindingInterface;\r
+\r
+ if (BindingHandle == NULL || ImageHandle == NULL) {\r
+ return NULL;\r
+ }\r
+ //\r
+ // Get all drivers which support driver binding protocol\r
+ //\r
+ DriverBindingHandleCount = 0;\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiDriverBindingProtocolGuid,\r
+ NULL,\r
+ &DriverBindingHandleCount,\r
+ &DriverBindingHandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {\r
+ return NULL;\r
+ }\r
+\r
+ for (Index = 0; Index < DriverBindingHandleCount; Index++) {\r
+ DriverBindingInterface = NULL;\r
+ Status = gBS->OpenProtocol (\r
+ DriverBindingHandleBuffer[Index],\r
+ &gEfiDriverBindingProtocolGuid,\r
+ (VOID **) &DriverBindingInterface,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ if (DriverBindingInterface->ImageHandle == ImageHandle) {\r
+ *BindingHandle = DriverBindingHandleBuffer[Index];\r
+ FreePool (DriverBindingHandleBuffer);\r
+ return DriverBindingInterface;\r
+ }\r
+ }\r
+\r
+ //\r
+ // If no Driver Binding Protocol instance is found\r
+ //\r
+ FreePool (DriverBindingHandleBuffer);\r
+ *BindingHandle = NULL;\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Return the current TPL.\r
+\r
+ @return Current TPL\r
+\r
+**/\r
+EFI_TPL\r
+GetCurrentTpl (\r
+ VOID\r
+ )\r
+{\r
+ EFI_TPL Tpl;\r
+\r
+ Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+ gBS->RestoreTPL (Tpl);\r
+\r
+ return Tpl;\r
+}\r
+\r
+\r
+/**\r
+ Retrieves the image handle of the platform override driver for a controller in\r
+ the system from the memory mapping database.\r
+\r
+ @param ControllerHandle The device handle of the controller to check if\r
+ a driver override exists.\r
+ @param DriverImageHandle On input, the previously returnd driver image handle.\r
+ On output, a pointer to the next driver handle.\r
+ Passing in a pointer to NULL, will return the\r
+ first driver handle for ControllerHandle.\r
+ @param MappingDataBase Mapping database list entry pointer\r
+ @param CallerImageHandle The caller driver's image handle, for\r
+ UpdateFvFileDevicePath use.\r
+\r
+ @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is not\r
+ a valid handle. Or DriverImagePath is not a\r
+ device path that was returned on a previous call\r
+ to GetDriverPath().\r
+ @retval EFI_NOT_FOUND A driver override for ControllerHandle was not\r
+ found.\r
+ @retval EFI_UNSUPPORTED The operation is not supported.\r
+ @retval EFI_SUCCESS The driver override for ControllerHandle was\r
+ returned in DriverImagePath.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetDriverFromMapping (\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN OUT EFI_HANDLE *DriverImageHandle,\r
+ IN LIST_ENTRY *MappingDataBase,\r
+ IN EFI_HANDLE CallerImageHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath;\r
+ BOOLEAN ControllerFound;\r
+ BOOLEAN ImageFound;\r
+ EFI_HANDLE *ImageHandleBuffer;\r
+ UINTN ImageHandleCount;\r
+ UINTN Index;\r
+ EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
+ EFI_HANDLE DriverBindingHandle;\r
+ BOOLEAN FoundLastReturned;\r
+ PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
+ DRIVER_IMAGE_INFO *DriverImageInfo;\r
+ LIST_ENTRY *OverrideItemListIndex;\r
+ LIST_ENTRY *ImageInfoListIndex;\r
+ EFI_DEVICE_PATH_PROTOCOL *TempDriverImagePath;\r
+ EFI_HANDLE ImageHandle;\r
+ EFI_HANDLE Handle;\r
+ EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;\r
+ EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;\r
+ UINTN DevicePathSize;\r
+\r
+ //\r
+ // Check that ControllerHandle is a valid handle\r
+ //\r
+ if (ControllerHandle == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ //\r
+ // Get the device path of ControllerHandle\r
+ //\r
+ Status = gBS->HandleProtocol (\r
+ ControllerHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ControllerDevicePath\r
+ );\r
+ if (EFI_ERROR (Status) || ControllerDevicePath == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Search ControllerDevicePath in MappingDataBase\r
+ //\r
+ OverrideItem = NULL;\r
+ ControllerFound = FALSE;\r
+ DevicePathSize = GetDevicePathSize (ControllerDevicePath);\r
+\r
+ OverrideItemListIndex = GetFirstNode (MappingDataBase);\r
+ while (!IsNull (MappingDataBase, OverrideItemListIndex)) {\r
+ OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE);\r
+ if (DevicePathSize == GetDevicePathSize (OverrideItem->ControllerDevicePath)) {\r
+ if (CompareMem (\r
+ ControllerDevicePath,\r
+ OverrideItem->ControllerDevicePath,\r
+ DevicePathSize\r
+ ) == 0\r
+ ) {\r
+ ControllerFound = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ OverrideItemListIndex = GetNextNode (MappingDataBase, OverrideItemListIndex);\r
+ }\r
+\r
+ if (!ControllerFound) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ //\r
+ // Passing in a pointer to NULL, will return the first driver device path for ControllerHandle.\r
+ // Check whether the driverImagePath is not a device path that was returned on a previous call to GetDriverPath().\r
+ //\r
+ if (*DriverImageHandle != NULL) {\r
+ if (*DriverImageHandle != OverrideItem->LastReturnedImageHandle) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+ //\r
+ // The GetDriverPath() may be called recursively, because it use ConnectDevicePath() internally,\r
+ // so should check whether there is a dead loop.\r
+ // Here use a controller device path stack to record all processed controller device path during a GetDriverPath() call,\r
+ // and check the controller device path whether appear again during the GetDriverPath() call.\r
+ //\r
+ if (CheckExistInStack (OverrideItem->ControllerDevicePath)) {\r
+ //\r
+ // There is a dependecy dead loop if the ControllerDevicePath appear in stack twice\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ PushDevPathStack (OverrideItem->ControllerDevicePath);\r
+\r
+ //\r
+ // Check every override driver, try to load and start them\r
+ //\r
+ ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
+ while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
+ DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
+ if (DriverImageInfo->ImageHandle == NULL) {\r
+ //\r
+ // Skip if the image is unloadable or unstartable\r
+ //\r
+ if ((!DriverImageInfo->UnLoadable) && ((!DriverImageInfo->UnStartable))) {\r
+ TempDriverImagePath = DriverImageInfo->DriverImagePath;\r
+ //\r
+ // If the image device path contains an FV node, check the FV file device path is valid.\r
+ // If it is invalid, try to return the valid device path.\r
+ // FV address maybe changes for memory layout adjust from time to time,\r
+ // use this funciton could promise the FV file device path is right.\r
+ //\r
+ Status = UpdateFvFileDevicePath (&TempDriverImagePath, NULL, CallerImageHandle);\r
+ if (!EFI_ERROR (Status)) {\r
+ FreePool (DriverImageInfo->DriverImagePath);\r
+ DriverImageInfo->DriverImagePath = TempDriverImagePath;\r
+ }\r
+ //\r
+ // Get all Loaded Image protocol to check whether the driver image has been loaded and started\r
+ //\r
+ ImageFound = FALSE;\r
+ ImageHandleCount = 0;\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiLoadedImageProtocolGuid,\r
+ NULL,\r
+ &ImageHandleCount,\r
+ &ImageHandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status) || (ImageHandleCount == 0)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ for(Index = 0; Index < ImageHandleCount; Index ++) {\r
+ //\r
+ // Get the EFI Loaded Image Device Path Protocol\r
+ //\r
+ LoadedImageDevicePath = NULL;\r
+ Status = gBS->HandleProtocol (\r
+ ImageHandleBuffer[Index],\r
+ &gEfiLoadedImageDevicePathProtocolGuid,\r
+ (VOID **) &LoadedImageDevicePath\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Maybe not all EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL existed.\r
+ //\r
+ continue;\r
+ }\r
+\r
+ DevicePathSize = GetDevicePathSize (DriverImageInfo->DriverImagePath);\r
+ if (DevicePathSize == GetDevicePathSize (LoadedImageDevicePath)) {\r
+ if (CompareMem (\r
+ DriverImageInfo->DriverImagePath,\r
+ LoadedImageDevicePath,\r
+ GetDevicePathSize (LoadedImageDevicePath)\r
+ ) == 0\r
+ ) {\r
+ ImageFound = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (ImageFound) {\r
+ //\r
+ // Find its related driver binding protocol\r
+ // Driver binding handle may be different with its driver's Image Handle.\r
+ //\r
+ DriverBindingHandle = NULL;\r
+ DriverBinding = GetBindingProtocolFromImageHandle (\r
+ ImageHandleBuffer[Index],\r
+ &DriverBindingHandle\r
+ );\r
+ ASSERT (DriverBinding != NULL);\r
+ DriverImageInfo->ImageHandle = ImageHandleBuffer[Index];\r
+ } else if (GetCurrentTpl() <= TPL_CALLBACK){\r
+ //\r
+ // The driver image has not been loaded and started. Try to load and start it now.\r
+ // Try to connect all device in the driver image path.\r
+ //\r
+ // Note: LoadImage() and StartImage() should be called under CALLBACK TPL in theory, but\r
+ // since many device need to be connected in CALLBACK level environment( e.g. Usb devices )\r
+ // and the Fat and Patition driver can endure executing in CALLBACK level in fact, so here permit\r
+ // to use LoadImage() and StartImage() in CALLBACK TPL.\r
+ //\r
+ Status = ConnectDevicePath (DriverImageInfo->DriverImagePath);\r
+ //\r
+ // check whether it points to a PCI Option Rom image,\r
+ // and try to use bus override protocol to get its first option rom image driver\r
+ //\r
+ TempDriverImagePath = DriverImageInfo->DriverImagePath;\r
+ gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &TempDriverImagePath, &Handle);\r
+ //\r
+ // Get the Bus Specific Driver Override Protocol instance on the Controller Handle\r
+ //\r
+ Status = gBS->HandleProtocol(\r
+ Handle,\r
+ &gEfiBusSpecificDriverOverrideProtocolGuid,\r
+ (VOID **) &BusSpecificDriverOverride\r
+ );\r
+ if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) {\r
+ ImageHandle = NULL;\r
+ Status = BusSpecificDriverOverride->GetDriver (\r
+ BusSpecificDriverOverride,\r
+ &ImageHandle\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Find its related driver binding protocol\r
+ // Driver binding handle may be different with its driver's Image handle\r
+ //\r
+ DriverBindingHandle = NULL;\r
+ DriverBinding = GetBindingProtocolFromImageHandle (\r
+ ImageHandle,\r
+ &DriverBindingHandle\r
+ );\r
+ ASSERT (DriverBinding != NULL);\r
+ DriverImageInfo->ImageHandle = ImageHandle;\r
+ }\r
+ }\r
+ //\r
+ // Skip if any device cannot be connected now, future passes through GetDriver() may be able to load that driver.\r
+ // Only file path media or FwVol Device Path Node remain if all device is connected\r
+ //\r
+ TempDriverImagePath = DriverImageInfo->DriverImagePath;\r
+ gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &TempDriverImagePath, &Handle);\r
+ if (((DevicePathType (TempDriverImagePath) == MEDIA_DEVICE_PATH) &&\r
+ (DevicePathSubType (TempDriverImagePath) == MEDIA_FILEPATH_DP)) ||\r
+ (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) TempDriverImagePath) != NULL)\r
+ ) {\r
+ //\r
+ // Try to load the driver\r
+ //\r
+ TempDriverImagePath = DriverImageInfo->DriverImagePath;\r
+ Status = gBS->LoadImage (\r
+ FALSE,\r
+ CallerImageHandle,\r
+ TempDriverImagePath,\r
+ NULL,\r
+ 0,\r
+ &ImageHandle\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Try to start the driver\r
+ //\r
+ Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
+ if (EFI_ERROR (Status)){\r
+ DriverImageInfo->UnStartable = TRUE;\r
+ DriverImageInfo->ImageHandle = NULL;\r
+ } else {\r
+ //\r
+ // Find its related driver binding protocol\r
+ // Driver binding handle may be different with its driver's Image handle\r
+ //\r
+ DriverBindingHandle = NULL;\r
+ DriverBinding = GetBindingProtocolFromImageHandle (\r
+ ImageHandle,\r
+ &DriverBindingHandle\r
+ );\r
+ ASSERT (DriverBinding != NULL);\r
+ DriverImageInfo->ImageHandle = ImageHandle;\r
+ }\r
+ } else {\r
+ DriverImageInfo->UnLoadable = TRUE;\r
+ DriverImageInfo->ImageHandle = NULL;\r
+ }\r
+ }\r
+ }\r
+ FreePool (ImageHandleBuffer);\r
+ }\r
+ }\r
+ ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
+ }\r
+ //\r
+ // Finish try to load and start the override driver of a controller, popup the controller's device path\r
+ //\r
+ PopDevPathStack (NULL);\r
+\r
+ //\r
+ // return the DriverImageHandle for ControllerHandle\r
+ //\r
+ FoundLastReturned = FALSE;\r
+ ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
+ while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
+ DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
+ if (DriverImageInfo->ImageHandle != NULL) {\r
+ if ((*DriverImageHandle == NULL) || FoundLastReturned) {\r
+ //\r
+ // If DriverImageHandle is NULL, then we just need to return the first driver.\r
+ // If FoundLastReturned, this means we have just encountered the previously returned driver.\r
+ // For both cases, we just return the image handle of this driver.\r
+ //\r
+ OverrideItem->LastReturnedImageHandle = DriverImageInfo->ImageHandle;\r
+ *DriverImageHandle = DriverImageInfo->ImageHandle;\r
+ return EFI_SUCCESS;\r
+ } else if (*DriverImageHandle == DriverImageInfo->ImageHandle){\r
+ //\r
+ // We have found the previously returned driver.\r
+ //\r
+ FoundLastReturned = TRUE;\r
+ }\r
+ }\r
+ ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
+ }\r
+\r
+ return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+/**\r
+ Check mapping database whether already has the mapping info which\r
+ records the input Controller to input DriverImage.\r
+\r
+ @param ControllerDevicePath The controller device path is to be check.\r
+ @param DriverImageDevicePath The driver image device path is to be check.\r
+ @param MappingDataBase Mapping database list entry pointer\r
+ @param DriverInfoNum the controller's total override driver number\r
+ @param DriverImageNO The driver order number for the input DriverImage.\r
+ If the DriverImageDevicePath is NULL, DriverImageNO is not set.\r
+\r
+ @retval EFI_INVALID_PARAMETER ControllerDevicePath or MappingDataBase is NULL.\r
+ @retval EFI_NOT_FOUND ControllerDevicePath is not found in MappingDataBase or\r
+ DriverImageDevicePath is not found in the found DriverImage Info list. \r
+ @retval EFI_SUCCESS The controller's total override driver number and \r
+ input DriverImage's order number is correctly return.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CheckMapping (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath OPTIONAL,\r
+ IN LIST_ENTRY *MappingDataBase,\r
+ OUT UINT32 *DriverInfoNum OPTIONAL,\r
+ OUT UINT32 *DriverImageNO OPTIONAL\r
+ )\r
+{\r
+ LIST_ENTRY *OverrideItemListIndex;\r
+ PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
+ LIST_ENTRY *ImageInfoListIndex;\r
+ DRIVER_IMAGE_INFO *DriverImageInfo;\r
+ BOOLEAN Found;\r
+ UINT32 ImageNO;\r
+ UINTN DevicePathSize;\r
+\r
+ if (ControllerDevicePath == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if (MappingDataBase == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Search ControllerDevicePath in MappingDataBase\r
+ //\r
+ Found = FALSE;\r
+ OverrideItem = NULL;\r
+ OverrideItemListIndex = GetFirstNode (MappingDataBase);\r
+ while (!IsNull (MappingDataBase, OverrideItemListIndex)) {\r
+ OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE);\r
+ DevicePathSize = GetDevicePathSize (ControllerDevicePath);\r
+ if (DevicePathSize == GetDevicePathSize (OverrideItem->ControllerDevicePath)) {\r
+ if (CompareMem (\r
+ ControllerDevicePath,\r
+ OverrideItem->ControllerDevicePath,\r
+ DevicePathSize\r
+ ) == 0\r
+ ) {\r
+ Found = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ OverrideItemListIndex = GetNextNode (MappingDataBase, OverrideItemListIndex);\r
+ }\r
+\r
+ if (!Found) {\r
+ //\r
+ // ControllerDevicePath is not in MappingDataBase\r
+ //\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ ASSERT (OverrideItem->DriverInfoNum != 0);\r
+ if (DriverInfoNum != NULL) {\r
+ *DriverInfoNum = OverrideItem->DriverInfoNum;\r
+ }\r
+\r
+ //\r
+ // If DriverImageDevicePath is NULL, skip checking DriverImageDevicePath\r
+ // in the controller's Driver Image Info List\r
+ //\r
+ if (DriverImageDevicePath == NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ //\r
+ // return the DriverImageHandle for ControllerHandle\r
+ //\r
+ ImageNO = 0;\r
+ Found = FALSE;\r
+ ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
+ while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
+ DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
+ ImageNO++;\r
+ DevicePathSize = GetDevicePathSize (DriverImageDevicePath);\r
+ if (DevicePathSize == GetDevicePathSize (DriverImageInfo->DriverImagePath)) {\r
+ if (CompareMem (\r
+ DriverImageDevicePath,\r
+ DriverImageInfo->DriverImagePath,\r
+ GetDevicePathSize (DriverImageInfo->DriverImagePath)\r
+ ) == 0\r
+ ) {\r
+ Found = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
+ }\r
+\r
+ if (!Found) {\r
+ //\r
+ // DriverImageDevicePath is not found in the controller's Driver Image Info List\r
+ //\r
+ return EFI_NOT_FOUND;\r
+ } else {\r
+ if (DriverImageNO != NULL) {\r
+ *DriverImageNO = ImageNO;\r
+ }\r
+ return EFI_SUCCESS;\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ Insert a driver image as a controller's override driver into the mapping database.\r
+ The driver image's order number is indicated by DriverImageNO.\r
+\r
+ @param ControllerDevicePath The controller device path need to add a\r
+ override driver image item\r
+ @param DriverImageDevicePath The driver image device path need to be insert\r
+ @param MappingDataBase Mapping database list entry pointer\r
+ @param DriverImageNO The inserted order number. If this number is taken, \r
+ the larger available number will be used.\r
+\r
+ @retval EFI_INVALID_PARAMETER ControllerDevicePath is NULL, or DriverImageDevicePath is NULL\r
+ or MappingDataBase is NULL\r
+ @retval EFI_ALREADY_STARTED The input Controller to input DriverImage has been \r
+ recorded into the mapping database.\r
+ @retval EFI_SUCCESS The Controller and DriverImage are inserted into \r
+ the mapping database successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InsertDriverImage (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath,\r
+ IN LIST_ENTRY *MappingDataBase,\r
+ IN UINT32 DriverImageNO\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *OverrideItemListIndex;\r
+ PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
+ LIST_ENTRY *ImageInfoListIndex;\r
+ DRIVER_IMAGE_INFO *DriverImageInfo;\r
+ BOOLEAN Found;\r
+ UINT32 ImageNO;\r
+ UINTN DevicePathSize;\r
+\r
+ if (ControllerDevicePath == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if (DriverImageDevicePath == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ if (MappingDataBase == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // If the driver is already in the controller's Driver Image Info List,\r
+ // just return EFI_ALREADY_STARTED.\r
+ //\r
+ Status = CheckMapping (\r
+ ControllerDevicePath,\r
+ DriverImageDevicePath,\r
+ MappingDataBase,\r
+ NULL,\r
+ NULL\r
+ );\r
+ if (Status == EFI_SUCCESS) {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+\r
+ //\r
+ // Search the input ControllerDevicePath in MappingDataBase\r
+ //\r
+ Found = FALSE;\r
+ OverrideItem = NULL;\r
+ OverrideItemListIndex = GetFirstNode (MappingDataBase);\r
+ while (!IsNull (MappingDataBase, OverrideItemListIndex)) {\r
+ OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE);\r
+ DevicePathSize = GetDevicePathSize (ControllerDevicePath);\r
+ if (DevicePathSize == GetDevicePathSize (OverrideItem->ControllerDevicePath)) {\r
+ if (CompareMem (\r
+ ControllerDevicePath,\r
+ OverrideItem->ControllerDevicePath,\r
+ DevicePathSize\r
+ ) == 0\r
+ ) {\r
+ Found = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ OverrideItemListIndex = GetNextNode (MappingDataBase, OverrideItemListIndex);\r
+ }\r
+ //\r
+ // If cannot find, this is a new controller item\r
+ // Add the Controller related PLATFORM_OVERRIDE_ITEM structrue in mapping data base\r
+ //\r
+ if (!Found) {\r
+ OverrideItem = AllocateZeroPool (sizeof (PLATFORM_OVERRIDE_ITEM));\r
+ ASSERT (OverrideItem != NULL);\r
+ OverrideItem->Signature = PLATFORM_OVERRIDE_ITEM_SIGNATURE;\r
+ OverrideItem->ControllerDevicePath = DuplicateDevicePath (ControllerDevicePath);\r
+ InitializeListHead (&OverrideItem->DriverInfoList);\r
+ InsertTailList (MappingDataBase, &OverrideItem->Link);\r
+ }\r
+\r
+ //\r
+ // Prepare the driver image related DRIVER_IMAGE_INFO structure.\r
+ //\r
+ DriverImageInfo = AllocateZeroPool (sizeof (DRIVER_IMAGE_INFO));\r
+ ASSERT (DriverImageInfo != NULL);\r
+ DriverImageInfo->Signature = DRIVER_IMAGE_INFO_SIGNATURE;\r
+ DriverImageInfo->DriverImagePath = DuplicateDevicePath (DriverImageDevicePath);\r
+ //\r
+ // Find the driver image wanted order location\r
+ //\r
+ ImageNO = 0;\r
+ Found = FALSE;\r
+ ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
+ while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
+ if (ImageNO == (DriverImageNO - 1)) {\r
+ //\r
+ // find the wanted order location, insert it\r
+ //\r
+ InsertTailList (ImageInfoListIndex, &DriverImageInfo->Link);\r
+ OverrideItem->DriverInfoNum ++;\r
+ Found = TRUE;\r
+ break;\r
+ }\r
+ ImageNO++;\r
+ ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
+ }\r
+\r
+ if (!Found) {\r
+ //\r
+ // if not find the wanted order location, add it as last item of the controller mapping item\r
+ //\r
+ InsertTailList (&OverrideItem->DriverInfoList, &DriverImageInfo->Link);\r
+ OverrideItem->DriverInfoNum ++;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Delete a controller's override driver from the mapping database.\r
+\r
+ @param ControllerDevicePath The controller device path will be deleted \r
+ when all drivers images on it are removed.\r
+ @param DriverImageDevicePath The driver image device path will be delete.\r
+ If NULL, all driver image will be delete.\r
+ @param MappingDataBase Mapping database list entry pointer\r
+\r
+ @retval EFI_INVALID_PARAMETER ControllerDevicePath is NULL, or MappingDataBase is NULL\r
+ @retval EFI_NOT_FOUND ControllerDevicePath is not found in MappingDataBase or\r
+ DriverImageDevicePath is not found in the found DriverImage Info list. \r
+ @retval EFI_SUCCESS Delete the specified driver successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DeleteDriverImage (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath,\r
+ IN LIST_ENTRY *MappingDataBase\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *OverrideItemListIndex;\r
+ PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
+ LIST_ENTRY *ImageInfoListIndex;\r
+ DRIVER_IMAGE_INFO *DriverImageInfo;\r
+ BOOLEAN Found;\r
+ UINTN DevicePathSize;\r
+\r
+ if (ControllerDevicePath == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (MappingDataBase == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // If ControllerDevicePath is not found in mapping database, return EFI_NOT_FOUND.\r
+ //\r
+ Status = CheckMapping (\r
+ ControllerDevicePath,\r
+ DriverImageDevicePath,\r
+ MappingDataBase,\r
+ NULL,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Search ControllerDevicePath in MappingDataBase\r
+ //\r
+ Found = FALSE;\r
+ OverrideItem = NULL;\r
+ OverrideItemListIndex = GetFirstNode (MappingDataBase);\r
+ while (!IsNull (MappingDataBase, OverrideItemListIndex)) {\r
+ OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE);\r
+ DevicePathSize = GetDevicePathSize (ControllerDevicePath);\r
+ if (DevicePathSize == GetDevicePathSize (OverrideItem->ControllerDevicePath)) {\r
+ if (CompareMem (\r
+ ControllerDevicePath,\r
+ OverrideItem->ControllerDevicePath,\r
+ DevicePathSize\r
+ ) == 0\r
+ ) {\r
+ Found = TRUE;\r
+ break;\r
+ }\r
+ }\r
+ OverrideItemListIndex = GetNextNode (MappingDataBase, OverrideItemListIndex);\r
+ }\r
+\r
+ ASSERT (Found);\r
+ ASSERT (OverrideItem->DriverInfoNum != 0);\r
+\r
+ Found = FALSE;\r
+ ImageInfoListIndex = GetFirstNode (&OverrideItem->DriverInfoList);\r
+ while (!IsNull (&OverrideItem->DriverInfoList, ImageInfoListIndex)) {\r
+ DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
+ ImageInfoListIndex = GetNextNode (&OverrideItem->DriverInfoList, ImageInfoListIndex);\r
+ if (DriverImageDevicePath != NULL) {\r
+ //\r
+ // Search for the specified DriverImageDevicePath and remove it, then break.\r
+ //\r
+ DevicePathSize = GetDevicePathSize (DriverImageDevicePath);\r
+ if (DevicePathSize == GetDevicePathSize (DriverImageInfo->DriverImagePath)) {\r
+ if (CompareMem (\r
+ DriverImageDevicePath,\r
+ DriverImageInfo->DriverImagePath,\r
+ GetDevicePathSize (DriverImageInfo->DriverImagePath)\r
+ ) == 0\r
+ ) {\r
+ Found = TRUE;\r
+ FreePool(DriverImageInfo->DriverImagePath);\r
+ RemoveEntryList (&DriverImageInfo->Link);\r
+ OverrideItem->DriverInfoNum --;\r
+ break;\r
+ }\r
+ }\r
+ } else {\r
+ //\r
+ // Remove all existing driver image info entries, so no break here.\r
+ //\r
+ Found = TRUE;\r
+ FreePool(DriverImageInfo->DriverImagePath);\r
+ RemoveEntryList (&DriverImageInfo->Link);\r
+ OverrideItem->DriverInfoNum --;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Confirm all driver image info entries have been removed,\r
+ // if DriverImageDevicePath is NULL.\r
+ //\r
+ if (DriverImageDevicePath == NULL) {\r
+ ASSERT (OverrideItem->DriverInfoNum == 0);\r
+ }\r
+ //\r
+ // If Override Item has no driver image info entry, then delete this item.\r
+ //\r
+ if (OverrideItem->DriverInfoNum == 0) {\r
+ FreePool(OverrideItem->ControllerDevicePath);\r
+ RemoveEntryList (&OverrideItem->Link);\r
+ FreePool (OverrideItem);\r
+ }\r
+\r
+ if (!Found) {\r
+ //\r
+ // DriverImageDevicePath is not NULL and cannot be found in the controller's\r
+ // driver image info list.\r
+ //\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/** @file\r
+ \r
+ The defintions are required both by Source code and Vfr file.\r
+ The PLAT_OVER_MNGR_DATA structure, form guid and Ifr question ID are defined. \r
+\r
+Copyright (c) 2007 - 2008, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _PLAT_OVER_MNGR_H_\r
+#define _PLAT_OVER_MNGR_H_\r
+\r
+#define PLAT_OVER_MNGR_GUID \\r
+ { \\r
+ 0x8614567d, 0x35be, 0x4415, {0x8d, 0x88, 0xbd, 0x7d, 0xc, 0x9c, 0x70, 0xc0} \\r
+ }\r
+\r
+//\r
+// The max number of the supported driver list.\r
+//\r
+#define MAX_CHOICE_NUM 0x00ff\r
+#define UPDATE_DATA_SIZE 0x1000\r
+\r
+#define FORM_ID_DEVICE 0x1100\r
+#define FORM_ID_DRIVER 0x1200\r
+#define FORM_ID_ORDER 0x1500\r
+\r
+#define KEY_VALUE_DEVICE_OFFSET 0x0100\r
+#define KEY_VALUE_DEVICE_MAX (KEY_VALUE_DEVICE_OFFSET + MAX_CHOICE_NUM)\r
+\r
+#define KEY_VALUE_DEVICE_REFRESH 0x1234\r
+#define KEY_VALUE_DEVICE_FILTER 0x1235\r
+#define KEY_VALUE_DEVICE_CLEAR 0x1236\r
+\r
+#define KEY_VALUE_DRIVER_GOTO_PREVIOUS 0x1300\r
+#define KEY_VALUE_DRIVER_GOTO_ORDER 0x1301\r
+\r
+#define KEY_VALUE_ORDER_GOTO_PREVIOUS 0x2000\r
+#define KEY_VALUE_ORDER_SAVE_AND_EXIT 0x1800\r
+\r
+#define VARSTORE_ID_PLAT_OVER_MNGR 0x1000\r
+\r
+#define LABEL_END 0xffff\r
+\r
+typedef struct {\r
+ UINT8 DriSelection[MAX_CHOICE_NUM];\r
+ UINT8 DriOrder[MAX_CHOICE_NUM];\r
+ UINT8 PciDeviceFilter;\r
+} PLAT_OVER_MNGR_DATA;\r
+\r
+//\r
+// Field offset of structure PLAT_OVER_MNGR_DATA\r
+//\r
+#define VAR_OFFSET(Field) ((UINTN) &(((PLAT_OVER_MNGR_DATA *) 0)->Field))\r
+#define DRIVER_SELECTION_VAR_OFFSET (VAR_OFFSET (DriSelection))\r
+#define DRIVER_ORDER_VAR_OFFSET (VAR_OFFSET (DriOrder))\r
+\r
+//\r
+// Tool automatic generated Question Id start from 1\r
+// In order to avoid to conflict them, the Driver Selection and Order QuestionID offset is defined from 0x0500.\r
+//\r
+#define QUESTION_ID_OFFSET 0x0500\r
+#define DRIVER_SELECTION_QUESTION_ID (VAR_OFFSET (DriSelection) + QUESTION_ID_OFFSET)\r
+#define DRIVER_ORDER_QUESTION_ID (VAR_OFFSET (DriOrder) + QUESTION_ID_OFFSET)\r
+\r
+#endif\r
+++ /dev/null
-/** @file\r
-\r
-Copyright (c) 2007 - 2009, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include <Uefi.h>\r
-\r
-#include <Library/BaseLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/PlatformDriverOverrideLib.h>\r
-#include <Protocol/PlatformDriverOverride.h>\r
-\r
-LIST_ENTRY mMappingDataBase = INITIALIZE_LIST_HEAD_VARIABLE (mMappingDataBase);\r
-BOOLEAN mEnvironmentVariableRead = FALSE;\r
-EFI_HANDLE mCallerImageHandle = NULL;\r
-\r
-/**\r
- Retrieves the image handle of the platform override driver for a controller in the system.\r
-\r
- @param This A pointer to the\r
- EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL instance.\r
- @param ControllerHandle The device handle of the controller to check if a\r
- driver override exists.\r
- @param DriverImageHandle On input, a pointer to the previous driver image\r
- handle returned by GetDriver(). On output, a\r
- pointer to the next driver image handle. Passing\r
- in a NULL, will return the first driver image\r
- handle for ControllerHandle.\r
-\r
- @retval EFI_SUCCESS The driver override for ControllerHandle was\r
- returned in DriverImageHandle.\r
- @retval EFI_NOT_FOUND A driver override for ControllerHandle was not\r
- found.\r
- @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is not a\r
- valid handle. DriverImageHandle is not a handle\r
- that was returned on a previous call to\r
- GetDriver().\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetDriver (\r
- IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN OUT EFI_HANDLE *DriverImageHandle\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // Check that ControllerHandle is a valid handle\r
- //\r
- if (ControllerHandle == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Read the environment variable(s) that contain the override mappings from Controller Device Path to\r
- // a set of Driver Device Paths, and initialize in memory database of the overrides that map Controller\r
- // Device Paths to an ordered set of Driver Device Paths and Driver Handles. This action is only performed\r
- // once and finished in first call.\r
- //\r
- if (!mEnvironmentVariableRead) {\r
- mEnvironmentVariableRead = TRUE;\r
-\r
- Status = InitOverridesMapping (&mMappingDataBase);\r
- if (EFI_ERROR (Status)){\r
- DEBUG ((DEBUG_ERROR, "The status to Get Platform Driver Override Variable is %r\n", Status));\r
- InitializeListHead (&mMappingDataBase);\r
- return EFI_NOT_FOUND;\r
- }\r
- }\r
-\r
- //\r
- // if the environment variable does not exist, just return not found\r
- //\r
- if (IsListEmpty (&mMappingDataBase)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- return GetDriverFromMapping (\r
- ControllerHandle,\r
- DriverImageHandle,\r
- &mMappingDataBase,\r
- mCallerImageHandle\r
- );\r
-}\r
-\r
-/**\r
- Retrieves the device path of the platform override driver for a controller in the system.\r
- This driver doesn't support this API.\r
-\r
- @param This A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_\r
- PROTOCOL instance. \r
- @param ControllerHandle The device handle of the controller to check if a driver override\r
- exists. \r
- @param DriverImagePath On input, a pointer to the previous driver device path returned by\r
- GetDriverPath(). On output, a pointer to the next driver\r
- device path. Passing in a pointer to NULL, will return the first\r
- driver device path for ControllerHandle.\r
- \r
- @retval EFI_UNSUPPORTED\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetDriverPath (\r
- IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN OUT EFI_DEVICE_PATH_PROTOCOL **DriverImagePath\r
- )\r
-{\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-\r
-/**\r
- Used to associate a driver image handle with a device path that was returned on a prior call to the\r
- GetDriverPath() service. This driver image handle will then be available through the \r
- GetDriver() service. This driver doesn't support this API.\r
-\r
- @param This A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_\r
- PROTOCOL instance. \r
- @param ControllerHandle The device handle of the controller. \r
- @param DriverImagePath A pointer to the driver device path that was returned in a prior\r
- call to GetDriverPath(). \r
- @param DriverImageHandle The driver image handle that was returned by LoadImage()\r
- when the driver specified by DriverImagePath was loaded \r
- into memory. \r
- \r
- @retval EFI_UNSUPPORTED\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DriverLoaded (\r
- IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath,\r
- IN EFI_HANDLE DriverImageHandle\r
- )\r
-{\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL mPlatformDriverOverride = {\r
- GetDriver,\r
- GetDriverPath,\r
- DriverLoaded\r
-};\r
-\r
-/**\r
- Platform Driver Override driver entry point, install the Platform Driver Override Protocol\r
-\r
- @param ImageHandle ImageHandle of the loaded driver.\r
- @param SystemTable Pointer to the EFI System Table.\r
-\r
- @retval EFI_SUCCESS The DXE Driver, DXE Runtime Driver, DXE SMM Driver,\r
- or UEFI Driver exited normally.\r
- @retval EFI_ALREADY_STARTED A protocol instance has been installed. Not need install again.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PlatformDriverOverrideEntry (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_HANDLE Handle;\r
- EFI_STATUS Status;\r
- VOID *Instance;\r
-\r
- mCallerImageHandle = ImageHandle;\r
-\r
- //\r
- // According to UEFI spec, there can be at most a single instance\r
- // in the system of the EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL.\r
- // So here we check the existence.\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiPlatformDriverOverrideProtocolGuid,\r
- NULL,\r
- &Instance\r
- );\r
- //\r
- // If there was no error, assume there is an installation and return error\r
- //\r
- if (!EFI_ERROR (Status)) {\r
- return EFI_ALREADY_STARTED;\r
- }\r
-\r
- //\r
- // Install platform driver override protocol\r
- //\r
- Handle = NULL;\r
- Status = gBS->InstallProtocolInterface (\r
- &Handle,\r
- &gEfiPlatformDriverOverrideProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &mPlatformDriverOverride\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- return EFI_SUCCESS;\r
-}\r
#/** @file\r
-# This driver produces UEFI PLATFORM_DRIVER_OVERRIDE_PROTOCOL if this protocol doesn't exist.\r
-# It doesn't install again if this protocol exists.\r
-# It only implements one interface GetDriver of PLATFORM_DRIVER_OVERRIDE_PROTOCOL protocol \r
-# and doesn't support other two interfaces GetDriverPath, DriverLoaded. \r
+# This driver produces UEFI PLATFORM_DRIVER_OVERRIDE_PROTOCOL if this protocol doesn't exist.\r
+# It doesn't install again if this protocol exists.\r
+# It only implements one interface GetDriver of PLATFORM_DRIVER_OVERRIDE_PROTOCOL protocol \r
+# and doesn't support other two interfaces GetDriverPath, DriverLoaded. \r
# \r
+# This driver also offers an UI interface in device manager to let user configure\r
+# platform override protocol to override the default algorithm for matching\r
+# drivers to controllers.\r
+#\r
+# The main flow:\r
+# 1. It dynamicly locate all controller device path.\r
+# 2. It dynamicly locate all drivers which support binding protocol.\r
+# 3. It export and dynamicly update two menu to let user select the\r
+# mapping between drivers to controllers.\r
+# 4. It save all the mapping info in NV variables for the following boot, \r
+# which will be consumed by GetDriver API of the produced the platform override protocol.\r
+#\r
# Copyright (c) 2007 - 2009, Intel Corporation. All rights reserved.\r
#\r
# All rights reserved. This program and the accompanying materials\r
\r
[Defines]\r
INF_VERSION = 0x00010005\r
- BASE_NAME = PlatformDriOverrideDxe\r
+ BASE_NAME = PlatDriOverrideDxe\r
FILE_GUID = 35034CE2-A6E5-4fb4-BABE-A0156E9B2549\r
- MODULE_TYPE = UEFI_DRIVER\r
+ MODULE_TYPE = DXE_DRIVER\r
VERSION_STRING = 1.0\r
- ENTRY_POINT = PlatformDriverOverrideEntry\r
+ ENTRY_POINT = PlatDriOverrideDxeInit\r
+ UNLOAD_IMAGE = PlatDriOverrideDxeUnload\r
\r
#\r
# The following information is for reference only and not required by the build tools.\r
#\r
\r
[Sources.common]\r
- PlatformDriOverride.c\r
+ VfrStrings.uni\r
+ Vfr.vfr\r
+ PlatDriOverrideDxe.c\r
+ PlatOverMngr.h\r
+ PlatDriOverrideLib.c\r
+ InternalPlatDriOverrideDxe.h\r
\r
[Packages]\r
MdePkg/MdePkg.dec\r
\r
[LibraryClasses]\r
BaseLib\r
- UefiDriverEntryPoint\r
DebugLib\r
- PlatformDriverOverrideLib\r
+ UefiLib\r
+ UefiDriverEntryPoint\r
UefiBootServicesTableLib\r
+ HiiLib\r
+ BaseMemoryLib\r
+ MemoryAllocationLib\r
+ DevicePathLib\r
+ DxeServicesTableLib\r
+ UefiRuntimeServicesTableLib\r
+ PrintLib \r
+ \r
+[Guids]\r
+ ## This GUID C Name is not required for build since it is from UefiLib and not directly used by this module source.\r
+ ## gEfiGlobalVariableGuid ## SOMETIMES_CONSUMED ## Variable:L"PlatformLang" this variable specifies the platform supported language string (RFC 4646 format)\r
+ ## gEfiGlobalVariableGuid ## SOMETIMES_CONSUMED ## Variable:L"Lang" this variable specifies the platform supported language string (ISO 639-2 format)\r
+ ##\r
+ # There could be more than one variables, from PlatDriOver, PlatDriOver1, PlatDriOver2,...\r
+ #\r
+ # gEfiCallerIdGuid ## Private ## Variable:L"PlatDriOver"\r
+ gEfiIfrTianoGuid ## CONSUMES ## Guid\r
\r
[Protocols]\r
- gEfiPlatformDriverOverrideProtocolGuid ## PRODUCED\r
-
\ No newline at end of file
+ gEfiComponentName2ProtocolGuid ## SOMETIMES_CONSUMED (Get Driver Name if ComponentName2Protocol exists)\r
+ gEfiComponentNameProtocolGuid ## SOMETIMES_CONSUMED (Get Driver Name if ComponentNameProtocol exists and ComponentName2Protocol doesn't exist)\r
+ gEfiFirmwareVolume2ProtocolGuid ## SOMETIMES_CONSUMED (Get Driver Name from EFI UI section if ComponentName2Protocol and ComponentNameProtocol don't exist)\r
+ gEfiPciIoProtocolGuid ## SOMETIMES_CONSUMED (Find the PCI device if PciIo protocol is installed)\r
+ gEfiBusSpecificDriverOverrideProtocolGuid ## SOMETIMES_CONSUMED (Check whether the PCI device contains one or more efi drivers in its option rom by this protocol) \r
+\r
+ gEfiDriverBindingProtocolGuid ## SOMETIMES_CONSUMED\r
+ gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMED\r
+ gEfiLoadedImageDevicePathProtocolGuid ## SOMETIMES_CONSUMED (Show the drivers in the second page that support DriverBindingProtocol, LoadedImageProtocol and LoadedImageDevicePathProtocol)\r
+ gEfiDevicePathProtocolGuid ## SOMETIMES_CONSUMED (Show the controller device in the first page that support DevicePathProtocol)\r
+\r
+ gEfiHiiDatabaseProtocolGuid ## CONSUMED\r
+ gEfiFormBrowser2ProtocolGuid ## CONSUMED\r
+ gEfiHiiConfigRoutingProtocolGuid ## CONSUMED\r
+ gEfiHiiConfigAccessProtocolGuid ## PRODUCED\r
+ gEfiDevicePathToTextProtocolGuid ## CONSUMED\r
+ gEfiPlatformDriverOverrideProtocolGuid ## PRODUCED\r
--- /dev/null
+// *++\r
+//\r
+// Copyright (c) 2009, Intel Corporation\r
+// All rights reserved. This program and the accompanying materials\r
+// are licensed and made available under the terms and conditions of the BSD License\r
+// which accompanies this distribution. The full text of the license may be found at\r
+// http://opensource.org/licenses/bsd-license.php\r
+//\r
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+//\r
+// Module Name:\r
+//\r
+// Vfr.vfr\r
+//\r
+// Abstract:\r
+//\r
+// Platform driver Override manager formset\r
+//\r
+//\r
+// --*/\r
+\r
+#include "PlatOverMngr.h"\r
+\r
+#define EFI_DISK_DEVICE_CLASS 0x01\r
+\r
+formset\r
+ guid = PLAT_OVER_MNGR_GUID,\r
+ title = STRING_TOKEN(STR_ENTRY_TITLE),\r
+ help = STRING_TOKEN(STR_TITLE_HELP),\r
+ class = EFI_DISK_DEVICE_CLASS,\r
+ subclass = 0xff,\r
+\r
+ varstore PLAT_OVER_MNGR_DATA,\r
+ varid = VARSTORE_ID_PLAT_OVER_MNGR,\r
+ name = Data,\r
+ guid = PLAT_OVER_MNGR_GUID;\r
+\r
+ form formid = FORM_ID_DEVICE,\r
+ title = STRING_TOKEN(STR_TITLE);\r
+\r
+ text\r
+ help = STRING_TOKEN(STR_FIRST_REFRESH_HELP),\r
+ text = STRING_TOKEN(STR_FIRST_REFRESH),\r
+ text = STRING_TOKEN(STR_NULL_STRING),\r
+ flags = INTERACTIVE,\r
+ key = KEY_VALUE_DEVICE_REFRESH;\r
+\r
+ checkbox varid = Data.PciDeviceFilter,\r
+ prompt = STRING_TOKEN(STR_PCI_DEVICE_FILTER_PROMPT),\r
+ help = STRING_TOKEN(STR_PCI_DEVICE_FILTER_HELP),\r
+ flags = INTERACTIVE,\r
+ key = KEY_VALUE_DEVICE_FILTER,\r
+ endcheckbox;\r
+\r
+ label FORM_ID_DEVICE;\r
+ label LABEL_END;\r
+\r
+ subtitle text = STRING_TOKEN(STR_NULL_STRING);\r
+\r
+ goto FORM_ID_DEVICE,\r
+ prompt = STRING_TOKEN(STR_CLEAR_ALL),\r
+ help = STRING_TOKEN(STR_CLEAR_ALL_HELP),\r
+ flags = INTERACTIVE | RESET_REQUIRED,\r
+ key = KEY_VALUE_DEVICE_CLEAR;\r
+ endform;\r
+\r
+ form formid = FORM_ID_DRIVER,\r
+ title = STRING_TOKEN(STR_TITLE);\r
+\r
+ goto FORM_ID_DEVICE,\r
+ prompt = STRING_TOKEN(STR_GOTO_PREVIOUS),\r
+ help = STRING_TOKEN(STR_NULL_STRING),\r
+ flags = INTERACTIVE,\r
+ key = KEY_VALUE_DRIVER_GOTO_PREVIOUS;\r
+\r
+ goto FORM_ID_ORDER,\r
+ prompt = STRING_TOKEN(STR_TITLE_ORDER),\r
+ help = STRING_TOKEN(STR_TITLE_ORDER_HELP),\r
+ flags = INTERACTIVE,\r
+ key = KEY_VALUE_DRIVER_GOTO_ORDER;\r
+\r
+ label FORM_ID_DRIVER;\r
+ label LABEL_END;\r
+\r
+ endform;\r
+\r
+ form formid = FORM_ID_ORDER,\r
+ title = STRING_TOKEN(STR_TITLE);\r
+\r
+ goto FORM_ID_DRIVER,\r
+ prompt = STRING_TOKEN(STR_GOTO_PREVIOUS),\r
+ help = STRING_TOKEN(STR_NULL_STRING),\r
+ flags = INTERACTIVE,\r
+ key = KEY_VALUE_ORDER_GOTO_PREVIOUS;\r
+\r
+ label FORM_ID_ORDER;\r
+ label LABEL_END;\r
+\r
+ subtitle text = STRING_TOKEN(STR_NULL_STRING);\r
+\r
+ goto FORM_ID_ORDER,\r
+ prompt = STRING_TOKEN(STR_SAVE_AND_EXIT),\r
+ help = STRING_TOKEN(STR_NULL_STRING),\r
+ flags = INTERACTIVE | RESET_REQUIRED,\r
+ key = KEY_VALUE_ORDER_SAVE_AND_EXIT;\r
+ endform;\r
+\r
+endformset;\r
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf\r
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf\r
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf\r
- PlatformDriverOverrideLib|MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.inf\r
\r
[LibraryClasses.common.USER_DEFINED]\r
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf\r
MdeModulePkg/Application/VariableInfo/VariableInfo.inf\r
\r
MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf\r
- MdeModulePkg/Application/PlatOverMngr/PlatOverMngr.inf\r
\r
[BuildOptions]\r
DEBUG_*_IA32_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /ALIGN:4096 /SUBSYSTEM:CONSOLE\r