From: vanjeff Date: Wed, 16 Jan 2008 09:04:43 +0000 (+0000) Subject: Port PlatformDriOverrideDxe into R9. X-Git-Tag: edk2-stable201903~21601 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=b290614d493ff72fc2a4410d169314e501b7e79e Port PlatformDriOverrideDxe into R9. 1. Add one OverrideVariableGuid in MdeModulePkg 2. Add one library PlatDriOverLib used by PlatformDriOverrideDxe. 3. Add PlatformDriOverrideDxe in MdeModulePkg git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4557 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/MdeModulePkg/Include/Guid/OverrideVariable.h b/MdeModulePkg/Include/Guid/OverrideVariable.h new file mode 100644 index 0000000000..673813a580 --- /dev/null +++ b/MdeModulePkg/Include/Guid/OverrideVariable.h @@ -0,0 +1,34 @@ +/*++ + +Copyright (c) 2008, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + OverrideVariable.h + +Abstract: + + Platform Override Variable Guid definitions + +--*/ + +#ifndef __EFI_OVERRIDE_VARIABLE_GUID_H__ +#define __EFI_OVERRIDE_VARIABLE_GUID_H__ + +// +// This guid is used for a platform driver override variable +// +#define EFI_OVERRIDE_VARIABLE_GUID \ + { 0x8e3d4ad5, 0xf762, 0x438a, { 0xa1, 0xc1, 0x5b, 0x9f, 0xe6, 0x8c, 0x6b, 0x15 }} + +extern EFI_GUID gEfiOverrideVariableGuid; + + +#endif // #ifndef __EFI_OVERRIDE_VARIABLE_GUID_H__ diff --git a/MdeModulePkg/Include/Library/PlatDriOverLib.h b/MdeModulePkg/Include/Library/PlatDriOverLib.h new file mode 100644 index 0000000000..8e6ab174d7 --- /dev/null +++ b/MdeModulePkg/Include/Library/PlatDriOverLib.h @@ -0,0 +1,255 @@ +/** @file + +Copyright (c) 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PlatDriOverLib.h + +Abstract: + + +**/ + +#ifndef _PLAT_DRI_OVER_LIB_H_ +#define _PLAT_DRI_OVER_LIB_H_ + +#include +#include +#include +#include + +#include + +/** + Install the Platform Driver Override Protocol, and ensure there is only one Platform Driver Override Protocol + in the system. + + @param gPlatformDriverOverride PlatformDriverOverride protocol interface which + needs to be installed + + @retval EFI_ALREADY_STARTED There has been a Platform Driver Override + Protocol in the system, cannot install it again. + @retval Other Returned by InstallProtocolInterface + +**/ +EFI_STATUS +EFIAPI +InstallPlatformDriverOverrideProtocol ( + EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *gPlatformDriverOverride + ); + +/** + Free all the mapping database memory resource and initialize the mapping list entry + + @param MappingDataBase Mapping database list entry pointer + + @retval EFI_INVALID_PARAMETER mapping database list entry is NULL + @retval EFI_SUCCESS Free success + +**/ +EFI_STATUS +EFIAPI +FreeMappingDatabase ( + IN OUT LIST_ENTRY *MappingDataBase + ); + +/** + Read the environment variable(s) that contain the override mappings from Controller Device Path to + a set of Driver Device Paths, and create the mapping database in memory with those variable info. + VariableLayout{ + // + // NotEnd indicate whether the variable is the last one, and has no subsequent variable need to load. + // Each variable has MaximumVariableSize limitation, so we maybe need multi variables to store + // large mapping infos. + // The variable(s) name rule is PlatDriOver, PlatDriOver1, PlatDriOver2, .... + // + UINT32 NotEnd; + // + // The entry which contains the mapping that Controller Device Path to a set of Driver Device Paths + // There are often multi mapping entries in a variable. + // + UINT32 SIGNATURE; //EFI_SIGNATURE_32('p','d','o','i') + UINT32 DriverNum; + EFI_DEVICE_PATH_PROTOCOL ControllerDevicePath[]; + EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[]; + EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[]; + EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[]; + ...... + UINT32 SIGNATURE; + UINT32 DriverNum; + EFI_DEVICE_PATH_PROTOCOL ControllerDevicePath[]; + EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[]; + EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[]; + EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[]; + ...... + } + typedef struct _PLATFORM_OVERRIDE_ITEM{ + UINTN Signature; //EFI_SIGNATURE_32('p','d','o','i') + LIST_ENTRY Link; + UINT32 DriverInfoNum; + EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath; + LIST_ENTRY DriverInfoList; //DRIVER_IMAGE_INFO List + } PLATFORM_OVERRIDE_ITEM; + typedef struct _DRIVER_IMAGE_INFO{ + UINTN Signature; //EFI_SIGNATURE_32('p','d','i','i') + LIST_ENTRY Link; + EFI_HANDLE ImageHandle; + EFI_DEVICE_PATH_PROTOCOL *DriverImagePath; + BOOLEAN UnLoadable; + BOOLEAN UnStartable; + } DRIVER_IMAGE_INFO; + + @param MappingDataBase Mapping database list entry pointer + + @retval EFI_INVALID_PARAMETER MappingDataBase pointer is null + @retval EFI_NOT_FOUND Cannot find the 'PlatDriOver' NV variable + @retval EFI_VOLUME_CORRUPTED The found NV variable is corrupted + @retval EFI_SUCCESS Create the mapping database in memory + successfully + +**/ +EFI_STATUS +EFIAPI +InitOverridesMapping ( + OUT LIST_ENTRY *MappingDataBase + ); + +/** + Save the memory mapping database into NV environment variable(s) + + @param MappingDataBase Mapping database list entry pointer + + @retval EFI_INVALID_PARAMETER MappingDataBase pointer is null + @retval EFI_SUCCESS Save memory mapping database successfully + +**/ +EFI_STATUS +EFIAPI +SaveOverridesMapping ( + IN LIST_ENTRY *MappingDataBase + ); + +/** + Retrieves the image handle of the platform override driver for a controller in the system from the memory mapping database. + + @param This A pointer to the + EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL instance. + @param ControllerHandle The device handle of the controller to check if + a driver override exists. + @param DriverImageHandle On output, a pointer to the next driver handle. + Passing in a pointer to NULL, will return the + first driver handle for ControllerHandle. + @param MappingDataBase MappingDataBase - Mapping database list entry + pointer + @param CallerImageHandle The caller driver's image handle, for + UpdateFvFileDevicePath use. + + @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is not + a valid handle. Or DriverImagePath is not a + device path that was returned on a previous call + to GetDriverPath(). + @retval EFI_NOT_FOUND A driver override for ControllerHandle was not + found. + @retval EFI_UNSUPPORTED The operation is not supported. + @retval EFI_SUCCESS The driver override for ControllerHandle was + returned in DriverImagePath. + +**/ +EFI_STATUS +EFIAPI +GetDriverFromMapping ( + IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL * This, + IN EFI_HANDLE ControllerHandle, + IN OUT EFI_HANDLE * DriverImageHandle, + IN LIST_ENTRY * MappingDataBase, + IN EFI_HANDLE CallerImageHandle + ); + +EFI_STATUS +EFIAPI +DeleteOverridesVariables ( + VOID + ); + +/** + Check mapping database whether already has the mapping info which + records the input Controller to input DriverImage. + If has, the controller's total override driver number and input DriverImage's order number is return. + + @param ControllerDevicePath The controller device path need to add a + override driver image item + @param DriverImageDevicePath The driver image device path need to be insert + @param MappingDataBase Mapping database list entry pointer + @param DriverInfoNum the controller's total override driver number + @param DriverImageNO The inserted order number + + @return EFI_INVALID_PARAMETER + @return EFI_NOT_FOUND + @return EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +CheckMapping ( + IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath, + IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath, + IN LIST_ENTRY * MappingDataBase, + OUT UINT32 *DriverInfoNum, + OUT UINT32 *DriverImageNO + ); + +/** + Insert a driver image as a controller's override driver into the mapping database. + The driver image's order number is indicated by DriverImageNO. + + @param ControllerDevicePath The controller device path need to add a + override driver image item + @param DriverImageDevicePath The driver image device path need to be insert + @param MappingDataBase Mapping database list entry pointer + @param DriverImageNO The inserted order number + + @return EFI_INVALID_PARAMETER + @return EFI_ALREADY_STARTED + @return EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +InsertDriverImage ( + IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath, + IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath, + IN LIST_ENTRY *MappingDataBase, + IN UINT32 DriverImageNO + ); + +/** + Delete a controller's override driver from the mapping database. + + @param ControllerDevicePath The controller device path need to add a + override driver image item + @param DriverImageDevicePath The driver image device path need to be insert + @param MappingDataBase Mapping database list entry pointer + @param DriverImageNO The inserted order number + + @return EFI_INVALID_PARAMETER + @return EFI_NOT_FOUND + @return EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +DeleteDriverImage ( + IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath, + IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath, + IN LIST_ENTRY *MappingDataBase + ); + +#endif diff --git a/MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.inf b/MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.inf new file mode 100644 index 0000000000..1ba2d7887b --- /dev/null +++ b/MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.inf @@ -0,0 +1,65 @@ +#/** @file +# Component name for module PlatDriOverLib +# +# FIX ME! +# Copyright (c) 2007, Intel Corporation. All rights reserved. +# +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PlatDriOverLib + FILE_GUID = 8bd8d711-2736-46d7-8c81-5de68e0a9e88 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = PlatDriOverLib + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources.common] + PlatDriOver.h + PlatDriOverLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + DxeServicesTableLib + MemoryAllocationLib + DevicePathLib + BaseLib + UefiLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + BaseMemoryLib + DebugLib + PrintLib + +[Guids] + gEfiOverrideVariableGuid # ALWAYS_CONSUMED + +[Protocols] + gEfiFirmwareVolume2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiLoadedImageProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiPlatformDriverOverrideProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiBusSpecificDriverOverrideProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiDriverBindingProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED + diff --git a/MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.msa b/MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.msa new file mode 100644 index 0000000000..f01088e875 --- /dev/null +++ b/MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.msa @@ -0,0 +1,94 @@ + + + PlatDriOverLib + DXE_DRIVER + 8bd8d711-2736-46d7-8c81-5de68e0a9e88 + 1.0 + Component name for module PlatDriOverLib + FIX ME! + Copyright (c) 2007, Intel Corporation. All rights reserved. + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + PlatDriOverLib + + + + PlatDriOverLib + + + PrintLib + + + DebugLib + + + BaseMemoryLib + + + UefiRuntimeServicesTableLib + + + UefiBootServicesTableLib + + + UefiLib + + + BaseLib + + + DevicePathLib + + + MemoryAllocationLib + + + DxeServicesTableLib + + + + PlatDriOverLib.c + PlatDriOver.h + + + + + + + + gEfiDevicePathProtocolGuid + + + gEfiDriverBindingProtocolGuid + + + gEfiBusSpecificDriverOverrideProtocolGuid + + + gEfiPlatformDriverOverrideProtocolGuid + + + gEfiLoadedImageProtocolGuid + + + gEfiFirmwareVolumeProtocolGuid + + + gEfiFirmwareVolume2ProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + \ No newline at end of file diff --git a/MdeModulePkg/Library/DxePlatDriOverLib/PlatDriOver.h b/MdeModulePkg/Library/DxePlatDriOverLib/PlatDriOver.h new file mode 100644 index 0000000000..331a9bc5cc --- /dev/null +++ b/MdeModulePkg/Library/DxePlatDriOverLib/PlatDriOver.h @@ -0,0 +1,121 @@ +/** @file + +Copyright (c) 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PlatDriOver.h + +Abstract: + + +**/ + +#ifndef _PLAT_DRI_OVER_H_ +#define _PLAT_DRI_OVER_H_ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define PLATFORM_OVERRIDE_ITEM_SIGNATURE EFI_SIGNATURE_32('p','d','o','i') + typedef struct _PLATFORM_OVERRIDE_ITEM{ + UINTN Signature; + LIST_ENTRY Link; + UINT32 DriverInfoNum; + EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath; + LIST_ENTRY DriverInfoList; //DRIVER_IMAGE_INFO List + EFI_HANDLE LastReturnedImageHandle; +} PLATFORM_OVERRIDE_ITEM; + +#define DRIVER_IMAGE_INFO_SIGNATURE EFI_SIGNATURE_32('p','d','i','i') +typedef struct _DRIVER_IMAGE_INFO{ + UINTN Signature; + LIST_ENTRY Link; + EFI_HANDLE ImageHandle; + EFI_DEVICE_PATH_PROTOCOL *DriverImagePath; + BOOLEAN UnLoadable; + BOOLEAN UnStartable; +} DRIVER_IMAGE_INFO; + +#define DEVICE_PATH_STACK_ITEM_SIGNATURE EFI_SIGNATURE_32('d','p','s','i') +typedef struct _DEVICE_PATH_STACK_ITEM{ + UINTN Signature; + LIST_ENTRY Link; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; +} DEVICE_PATH_STACK_ITEM; + +EFI_STATUS +EFIAPI +PushDevPathStack ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +EFI_STATUS +EFIAPI +PopDevPathStack ( + OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath + ); + +BOOLEAN +EFIAPI +CheckExistInStack ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ); + +EFI_STATUS +EFIAPI +UpdateFvFileDevicePath ( + IN OUT EFI_DEVICE_PATH_PROTOCOL ** DevicePath, + IN EFI_GUID *FileGuid, + IN EFI_HANDLE CallerImageHandle + ); + +VOID * +GetVariableAndSize ( + IN CHAR16 *Name, + IN EFI_GUID *VendorGuid, + OUT UINTN *VariableSize + ); + +EFI_STATUS +ConnectDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect + ); + +EFI_STATUS +BdsConnectDeviceByPciClassType ( + UINT8 ClassType, + UINT8 SubClassCode, + UINT8 PI, + BOOLEAN Recursive + ); + +#endif diff --git a/MdeModulePkg/Library/DxePlatDriOverLib/PlatDriOverLib.c b/MdeModulePkg/Library/DxePlatDriOverLib/PlatDriOverLib.c new file mode 100644 index 0000000000..d32715bb40 --- /dev/null +++ b/MdeModulePkg/Library/DxePlatDriOverLib/PlatDriOverLib.c @@ -0,0 +1,1800 @@ +/** @file + +Copyright (c) 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PlatDriOverLib.c + +Abstract: + + +**/ + +#include "PlatDriOver.h" + +STATIC LIST_ENTRY mDevicePathStack = INITIALIZE_LIST_HEAD_VARIABLE (mDevicePathStack); + + +/** + Install the Platform Driver Override Protocol, and ensure there is only one Platform Driver Override Protocol + in the system. + + @param gPlatformDriverOverride PlatformDriverOverride protocol interface which + needs to be installed + + @retval EFI_ALREADY_STARTED There has been a Platform Driver Override + Protocol in the system, cannot install it again. + @retval Other Returned by InstallProtocolInterface + +**/ +EFI_STATUS +EFIAPI +InstallPlatformDriverOverrideProtocol ( + EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *gPlatformDriverOverride + ) +{ + EFI_HANDLE Handle; + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + + // + // There will be only one platform driver override protocol in the system + // If there is another out there, someone is trying to install us again, + // Fail that scenario. + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiPlatformDriverOverrideProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + // + // If there was no error, assume there is an installation and return error + // + if (!EFI_ERROR (Status)) { + if (HandleBuffer != NULL) { + gBS->FreePool (HandleBuffer); + } + return EFI_ALREADY_STARTED; + } + + // + // Install platform driver override protocol + // + Handle = NULL; + Status = gBS->InstallProtocolInterface ( + &Handle, + &gEfiPlatformDriverOverrideProtocolGuid, + EFI_NATIVE_INTERFACE, + gPlatformDriverOverride + ); + return Status; +} + + +/** + Free all the mapping database memory resource and initialize the mapping list entry + + @param MappingDataBase Mapping database list entry pointer + + @retval EFI_INVALID_PARAMETER mapping database list entry is NULL + @retval EFI_SUCCESS Free success + +**/ +EFI_STATUS +EFIAPI +FreeMappingDatabase ( + IN OUT LIST_ENTRY *MappingDataBase + ) +{ + LIST_ENTRY *OverrideItemListIndex; + LIST_ENTRY *ImageInfoListIndex; + PLATFORM_OVERRIDE_ITEM *OverrideItem; + DRIVER_IMAGE_INFO *DriverImageInfo; + + if (MappingDataBase == NULL) { + return EFI_INVALID_PARAMETER; + } + + OverrideItemListIndex = MappingDataBase->ForwardLink; + while (OverrideItemListIndex != MappingDataBase){ + OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE); + // + // Free PLATFORM_OVERRIDE_ITEM.ControllerDevicePath[] + // + if (OverrideItem->ControllerDevicePath != NULL){ + FreePool(OverrideItem->ControllerDevicePath); + } + + ImageInfoListIndex = OverrideItem->DriverInfoList.ForwardLink; + while (ImageInfoListIndex != &OverrideItem->DriverInfoList){ + // + // Free all DRIVER_IMAGE_INFO.DriverImagePath[] + // + DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE); + if (DriverImageInfo->DriverImagePath != NULL) { + FreePool(DriverImageInfo->DriverImagePath); + } + // + // Free DRIVER_IMAGE_INFO itself + // + ImageInfoListIndex = ImageInfoListIndex->ForwardLink; + RemoveEntryList (&DriverImageInfo->Link); + FreePool (DriverImageInfo); + } + // + // Free PLATFORM_OVERRIDE_ITEM itself + // + OverrideItemListIndex = OverrideItemListIndex->ForwardLink; + RemoveEntryList (&OverrideItem->Link); + FreePool (OverrideItem); + } + + InitializeListHead (MappingDataBase); + return EFI_SUCCESS; +} + + +/** + Read the environment variable(s) that contain the override mappings from Controller Device Path to + a set of Driver Device Paths, and create the mapping database in memory with those variable info. + VariableLayout{ + // + // NotEnd indicate whether the variable is the last one, and has no subsequent variable need to load. + // Each variable has MaximumVariableSize limitation, so we maybe need multi variables to store + // large mapping infos. + // The variable(s) name rule is PlatDriOver, PlatDriOver1, PlatDriOver2, .... + // + UINT32 NotEnd; + // + // The entry which contains the mapping that Controller Device Path to a set of Driver Device Paths + // There are often multi mapping entries in a variable. + // + UINT32 SIGNATURE; //EFI_SIGNATURE_32('p','d','o','i') + UINT32 DriverNum; + EFI_DEVICE_PATH_PROTOCOL ControllerDevicePath[]; + EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[]; + EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[]; + EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[]; + ...... + UINT32 SIGNATURE; + UINT32 DriverNum; + EFI_DEVICE_PATH_PROTOCOL ControllerDevicePath[]; + EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[]; + EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[]; + EFI_DEVICE_PATH_PROTOCOL DriverDevicePath[]; + ...... + } + typedef struct _PLATFORM_OVERRIDE_ITEM{ + UINTN Signature; //EFI_SIGNATURE_32('p','d','o','i') + LIST_ENTRY Link; + UINT32 DriverInfoNum; + EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath; + LIST_ENTRY DriverInfoList; //DRIVER_IMAGE_INFO List + } PLATFORM_OVERRIDE_ITEM; + typedef struct _DRIVER_IMAGE_INFO{ + UINTN Signature; //EFI_SIGNATURE_32('p','d','i','i') + LIST_ENTRY Link; + EFI_HANDLE ImageHandle; + EFI_DEVICE_PATH_PROTOCOL *DriverImagePath; + BOOLEAN UnLoadable; + BOOLEAN UnStartable; + } DRIVER_IMAGE_INFO; + + @param MappingDataBase Mapping database list entry pointer + + @retval EFI_INVALID_PARAMETER MappingDataBase pointer is null + @retval EFI_NOT_FOUND Cannot find the 'PlatDriOver' NV variable + @retval EFI_VOLUME_CORRUPTED The found NV variable is corrupted + @retval EFI_SUCCESS Create the mapping database in memory + successfully + +**/ +EFI_STATUS +EFIAPI +InitOverridesMapping ( + OUT LIST_ENTRY *MappingDataBase + ) +{ + UINTN BufferSize; + VOID *VariableBuffer; + UINT8 *VariableIndex; + UINTN VariableNum; + CHAR16 OverrideVariableName[40]; + UINT32 NotEnd; + UINT32 DriverNumber; + PLATFORM_OVERRIDE_ITEM *OverrideItem; + DRIVER_IMAGE_INFO *DriverImageInfo; + BOOLEAN Corrupted; + UINT32 Signature; + EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath; + EFI_DEVICE_PATH_PROTOCOL *DriverDevicePath; + UINTN Index; + + if (MappingDataBase == NULL) { + return EFI_INVALID_PARAMETER; + } + + VariableNum = 0; + Corrupted = FALSE; + // + // Check the environment variable(s) that contain the override mappings . + // + VariableBuffer = GetVariableAndSize (L"PlatDriOver", &gEfiOverrideVariableGuid, &BufferSize); + ASSERT ((UINTN) VariableBuffer % sizeof(UINTN) == 0); + VariableNum ++; + if (VariableBuffer == NULL) { + return EFI_NOT_FOUND; + } + + do { + VariableIndex = VariableBuffer; + NotEnd = *(UINT32*) VariableIndex; + VariableIndex = VariableIndex + sizeof (UINT32); + while (VariableIndex < ((UINT8 *)VariableBuffer + BufferSize)) { + OverrideItem = AllocateZeroPool (sizeof (PLATFORM_OVERRIDE_ITEM)); + ASSERT (OverrideItem != NULL); + OverrideItem->Signature = PLATFORM_OVERRIDE_ITEM_SIGNATURE; + InitializeListHead (&OverrideItem->DriverInfoList); + // + // Check SIGNATURE + // + Signature = *(UINT32 *) VariableIndex; + VariableIndex = VariableIndex + sizeof (UINT32); + if (Signature != PLATFORM_OVERRIDE_ITEM_SIGNATURE) { + FreePool (OverrideItem); + Corrupted = TRUE; + break; + } + // + // Get DriverNum + // + DriverNumber = *(UINT32*) VariableIndex; + OverrideItem->DriverInfoNum = DriverNumber; + VariableIndex = VariableIndex + sizeof (UINT32); + // + // Get ControllerDevicePath[] + // + ControllerDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) VariableIndex; + OverrideItem->ControllerDevicePath = DuplicateDevicePath (ControllerDevicePath); + VariableIndex = VariableIndex + GetDevicePathSize (ControllerDevicePath); + // + // Align the VariableIndex since the controller device path may not be aligned, refer to the SaveOverridesMapping() + // + VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1)); + + // + // Get all DriverDevicePath[] + // + for (Index = 0; Index < DriverNumber; Index++) { + DriverImageInfo = AllocateZeroPool (sizeof (DRIVER_IMAGE_INFO)); + ASSERT (DriverImageInfo != NULL); + DriverImageInfo->Signature = DRIVER_IMAGE_INFO_SIGNATURE; + + DriverDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) VariableIndex; + DriverImageInfo->DriverImagePath = DuplicateDevicePath (DriverDevicePath); + VariableIndex = VariableIndex + GetDevicePathSize (DriverDevicePath); + // + // Align the VariableIndex since the driver image device path may not be aligned, refer to the SaveOverridesMapping() + // + VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1)); + + InsertTailList (&OverrideItem->DriverInfoList, &DriverImageInfo->Link); + } + InsertTailList (MappingDataBase, &OverrideItem->Link); + } + + FreePool (VariableBuffer); + if (Corrupted) { + FreeMappingDatabase (MappingDataBase); + return EFI_VOLUME_CORRUPTED; + } + + // + // If has other variable(PlatDriOver1, PlatDriOver2, PlatDriOver3.....), get them. + // NotEnd indicate whether current variable is the end variable. + // + if (NotEnd != 0) { + UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver%d", VariableNum); + VariableBuffer = GetVariableAndSize (OverrideVariableName, &gEfiOverrideVariableGuid, &BufferSize); + ASSERT ((UINTN) VariableBuffer % sizeof(UINTN) == 0); + VariableNum ++; + if (VariableBuffer == NULL) { + FreeMappingDatabase (MappingDataBase); + return EFI_VOLUME_CORRUPTED; + } + } + + } while (NotEnd != 0); + + return EFI_SUCCESS; +} + + +/** + Calculate the needed size in NV variable for recording a specific PLATFORM_OVERRIDE_ITEM info + + @param OverrideItemListIndex a list entry point to a specific + PLATFORM_OVERRIDE_ITEM + + @return The needed size number + +**/ +UINTN +EFIAPI +GetOneItemNeededSize ( + IN LIST_ENTRY *OverrideItemListIndex + ) +{ + UINTN NeededSize; + PLATFORM_OVERRIDE_ITEM *OverrideItem; + LIST_ENTRY *ImageInfoListIndex; + DRIVER_IMAGE_INFO *DriverImageInfo; + + + NeededSize = 0; + OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE); + NeededSize += sizeof (UINT32); //UINT32 SIGNATURE; + NeededSize += sizeof (UINT32); //UINT32 DriverNum; + NeededSize += GetDevicePathSize (OverrideItem->ControllerDevicePath); // ControllerDevicePath + // + // Align the controller device path + // + NeededSize += ((sizeof(UINT32) - ((UINTN) GetDevicePathSize (OverrideItem->ControllerDevicePath))) \ + & (sizeof(UINT32) - 1)); + ImageInfoListIndex = OverrideItem->DriverInfoList.ForwardLink; + while (ImageInfoListIndex != &OverrideItem->DriverInfoList){ + DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE); + NeededSize += GetDevicePathSize (DriverImageInfo->DriverImagePath); //DriverDevicePath + // + // Align the driver image device path + // + NeededSize += ((sizeof(UINT32) - ((UINTN) GetDevicePathSize (DriverImageInfo->DriverImagePath))) \ + & (sizeof(UINT32) - 1)); + ImageInfoListIndex = ImageInfoListIndex->ForwardLink; + } + + return NeededSize; +} + + + +/** + Save the memory mapping database into NV environment variable(s) + + @param MappingDataBase Mapping database list entry pointer + + @retval EFI_INVALID_PARAMETER MappingDataBase pointer is null + @retval EFI_SUCCESS Save memory mapping database successfully + +**/ +EFI_STATUS +EFIAPI +SaveOverridesMapping ( + IN LIST_ENTRY *MappingDataBase + ) +{ + EFI_STATUS Status; + VOID *VariableBuffer; + UINT8 *VariableIndex; + UINTN NumIndex; + CHAR16 OverrideVariableName[40]; + UINT32 NotEnd; + PLATFORM_OVERRIDE_ITEM *OverrideItem; + DRIVER_IMAGE_INFO *DriverImageInfo; + LIST_ENTRY *OverrideItemListIndex; + LIST_ENTRY *ItemIndex; + LIST_ENTRY *ImageInfoListIndex; + UINTN VariableNeededSize; + UINTN SavedSize; + UINT64 MaximumVariableStorageSize; + UINT64 RemainingVariableStorageSize; + UINT64 MaximumVariableSize; + UINTN OneItemNeededSize; + + if (MappingDataBase == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (MappingDataBase->ForwardLink == MappingDataBase) { + Status = DeleteOverridesVariables (); + return EFI_SUCCESS; + } + + // + // Get the the maximum size of an individual EFI variable in current system + // + gRT->QueryVariableInfo ( + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + &MaximumVariableStorageSize, + &RemainingVariableStorageSize, + &MaximumVariableSize + ); + + NumIndex = 0; + OverrideItemListIndex = MappingDataBase->ForwardLink; + while (OverrideItemListIndex != MappingDataBase) { + // + // Try to find the most proper variable size which <= MaximumVariableSize, but can contain mapping info as much as possible + // + VariableNeededSize = 0; + VariableNeededSize += sizeof (UINT32); //BOOLEAN NotEnd; + ItemIndex = OverrideItemListIndex; + NotEnd = FALSE; + + while (ItemIndex != MappingDataBase){ + OneItemNeededSize = GetOneItemNeededSize (ItemIndex); + if ((VariableNeededSize + + OneItemNeededSize + + sizeof (VARIABLE_HEADER) + + StrSize (L"PlatDriOver ") + ) >= MaximumVariableSize + ) { + NotEnd = TRUE; + break; + } + + VariableNeededSize += GetOneItemNeededSize (ItemIndex); + ItemIndex = ItemIndex->ForwardLink; + } + + if (NotEnd) { + if (VariableNeededSize == sizeof (UINT32)) { + // + // If an individual EFI variable cannot contain a single Item, return error + // + return EFI_OUT_OF_RESOURCES; + } + } + + // + // VariableNeededSize is the most proper variable size, allocate variable buffer + // ItemIndex now points to the next PLATFORM_OVERRIDE_ITEM which is not covered by VariableNeededSize + // + VariableBuffer = AllocateZeroPool (VariableNeededSize); + ASSERT ((UINTN) VariableBuffer % sizeof(UINTN) == 0); + + // + // Fill the variable buffer according to MappingDataBase + // + SavedSize = 0; + VariableIndex = VariableBuffer; + *(UINT32 *) VariableIndex = NotEnd; + VariableIndex += sizeof (UINT32); // pass NoEnd + SavedSize += sizeof (UINT32); + // + // ItemIndex points to the next PLATFORM_OVERRIDE_ITEM which is not covered by VariableNeededSize + // + while (OverrideItemListIndex != ItemIndex){ + *(UINT32 *) VariableIndex = PLATFORM_OVERRIDE_ITEM_SIGNATURE; + VariableIndex += sizeof (UINT32); // pass SIGNATURE + SavedSize += sizeof (UINT32); + + OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE); + *(UINT32 *) VariableIndex = OverrideItem->DriverInfoNum; + VariableIndex += sizeof (UINT32); // pass DriverNum + SavedSize += sizeof (UINT32); + + CopyMem (VariableIndex, OverrideItem->ControllerDevicePath, GetDevicePathSize (OverrideItem->ControllerDevicePath)); + VariableIndex += GetDevicePathSize (OverrideItem->ControllerDevicePath); // pass ControllerDevicePath + SavedSize += GetDevicePathSize (OverrideItem->ControllerDevicePath); + + // + // Align the VariableIndex since the controller device path may not be aligned + // + SavedSize += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1)); + VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1)); + + ImageInfoListIndex = OverrideItem->DriverInfoList.ForwardLink; + while (ImageInfoListIndex != &OverrideItem->DriverInfoList){ + DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE); + CopyMem (VariableIndex, DriverImageInfo->DriverImagePath, GetDevicePathSize (DriverImageInfo->DriverImagePath)); + VariableIndex += GetDevicePathSize (DriverImageInfo->DriverImagePath); // pass DriverImageDevicePath + SavedSize += GetDevicePathSize (DriverImageInfo->DriverImagePath); + // + // Align the VariableIndex since the driver image device path may not be aligned + // + SavedSize += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1)); + VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1)); + ImageInfoListIndex = ImageInfoListIndex->ForwardLink; + } + + OverrideItemListIndex = OverrideItemListIndex->ForwardLink; + } + + ASSERT (SavedSize == VariableNeededSize); + + if (NumIndex == 0) { + UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver"); + } else { + UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver%d", NumIndex ); + } + + Status = gRT->SetVariable ( + OverrideVariableName, + &gEfiOverrideVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + VariableNeededSize, + VariableBuffer + ); + ASSERT (!EFI_ERROR(Status)); + + NumIndex ++; + FreePool (VariableBuffer); + } + + return EFI_SUCCESS; +} + + +/** + Retrieves the image handle of the platform override driver for a controller in the system from the memory mapping database. + + @param This A pointer to the + EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL instance. + @param ControllerHandle The device handle of the controller to check if + a driver override exists. + @param DriverImageHandle On output, a pointer to the next driver handle. + Passing in a pointer to NULL, will return the + first driver handle for ControllerHandle. + @param MappingDataBase MappingDataBase - Mapping database list entry + pointer + @param CallerImageHandle The caller driver's image handle, for + UpdateFvFileDevicePath use. + + @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is not + a valid handle. Or DriverImagePath is not a + device path that was returned on a previous call + to GetDriverPath(). + @retval EFI_NOT_FOUND A driver override for ControllerHandle was not + found. + @retval EFI_UNSUPPORTED The operation is not supported. + @retval EFI_SUCCESS The driver override for ControllerHandle was + returned in DriverImagePath. + +**/ +EFI_STATUS +EFIAPI +GetDriverFromMapping ( + IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL * This, + IN EFI_HANDLE ControllerHandle, + IN OUT EFI_HANDLE * DriverImageHandle, + IN LIST_ENTRY * MappingDataBase, + IN EFI_HANDLE CallerImageHandle + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath; + BOOLEAN ControllerFound; + BOOLEAN ImageFound; + EFI_HANDLE *ImageHandleBuffer; + UINTN ImageHandleCount; + UINTN Index; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; + BOOLEAN FoundLastReturned; + PLATFORM_OVERRIDE_ITEM *OverrideItem; + DRIVER_IMAGE_INFO *DriverImageInfo; + LIST_ENTRY *OverrideItemListIndex; + LIST_ENTRY *ImageInfoListIndex; + EFI_DEVICE_PATH_PROTOCOL *TempDriverImagePath; + EFI_HANDLE ImageHandle; + EFI_HANDLE Handle; + EFI_DEVICE_PATH_PROTOCOL *LoadedImageHandleDevicePath; + EFI_DEVICE_PATH_PROTOCOL *TatalFilePath; + EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride; + UINTN DevicePathSize; + + // + // Check that ControllerHandle is a valid handle + // + if (ControllerHandle == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = gBS->HandleProtocol ( + ControllerHandle, + &gEfiDevicePathProtocolGuid, + (VOID **) &ControllerDevicePath + ); + if (EFI_ERROR (Status) || ControllerDevicePath == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Search ControllerDevicePath in MappingDataBase + // + OverrideItem = NULL; + ControllerFound = FALSE; + OverrideItemListIndex = MappingDataBase->ForwardLink; + while (OverrideItemListIndex != MappingDataBase){ + OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE); + DevicePathSize = GetDevicePathSize (ControllerDevicePath); + if (DevicePathSize == GetDevicePathSize (OverrideItem->ControllerDevicePath)) { + if (CompareMem ( + ControllerDevicePath, + OverrideItem->ControllerDevicePath, + GetDevicePathSize (OverrideItem->ControllerDevicePath) + ) == 0 + ) { + ControllerFound = TRUE; + break; + } + + } + OverrideItemListIndex = OverrideItemListIndex->ForwardLink; + } + + if (!ControllerFound) { + return EFI_NOT_FOUND; + } + // + // Passing in a pointer to NULL, will return the first driver device path for ControllerHandle. + // Check whether the driverImagePath is not a device path that was returned on a previous call to GetDriverPath(). + // + if (*DriverImageHandle != NULL) { + if (*DriverImageHandle != OverrideItem->LastReturnedImageHandle) { + return EFI_INVALID_PARAMETER; + } + } + // + // The GetDriverPath() maybe called recursively, because it use ConnectDevicePath() internally, + // so should check whether there is a dead loop. + // Here use a controller device path stack to record all processed controller device path during a GetDriverPath() call, + // and check the controller device path whether appear again during the GetDriverPath() call. + // + if (CheckExistInStack(OverrideItem->ControllerDevicePath)) { + // + // There is a dependecy dead loop if the ControllerDevicePath appear in stack twice + // + return EFI_UNSUPPORTED; + } + PushDevPathStack (OverrideItem->ControllerDevicePath); + + // + // Check every override driver, try to load and start them + // + ImageInfoListIndex = OverrideItem->DriverInfoList.ForwardLink; + while (ImageInfoListIndex != &OverrideItem->DriverInfoList){ + DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE); + if (DriverImageInfo->ImageHandle == NULL) { + // + // Skip if the image is unloadable or unstartable + // + if ((!DriverImageInfo->UnLoadable) && ((!DriverImageInfo->UnStartable))) { + TempDriverImagePath = DriverImageInfo->DriverImagePath; + // + // If the image device path contain a FV node, check the Fv file device path is valid. If it is invalid, try to return the valid device path. + // FV address maybe changes for memory layout adjust from time to time, use this funciton could promise the Fv file device path is right. + // + Status = UpdateFvFileDevicePath (&TempDriverImagePath, NULL, CallerImageHandle); + if (!EFI_ERROR (Status)) { + FreePool(DriverImageInfo->DriverImagePath); + DriverImageInfo->DriverImagePath = TempDriverImagePath; + } + // + // Get all Loaded Image protocol to check whether the driver image has been loaded and started + // + ImageFound = FALSE; + ImageHandleCount = 0; + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiLoadedImageProtocolGuid, + NULL, + &ImageHandleCount, + &ImageHandleBuffer + ); + if (EFI_ERROR (Status) || (ImageHandleCount == 0)) { + return EFI_NOT_FOUND; + } + + for(Index = 0; Index < ImageHandleCount; Index ++) { + Status = gBS->HandleProtocol ( + ImageHandleBuffer[Index], + &gEfiLoadedImageProtocolGuid, + (VOID **) &LoadedImage + ); + if (EFI_ERROR (Status)) { + continue; + } + + // + // Get the driver image total file path + // + LoadedImageHandleDevicePath = NULL; + Status = gBS->HandleProtocol ( + LoadedImage->DeviceHandle, + &gEfiDevicePathProtocolGuid, + (VOID **) &LoadedImageHandleDevicePath + ); + if (EFI_ERROR (Status)) { + // + // Maybe Not all LoadedImage->DeviceHandle has valid value. Skip the invalid image. + // + continue; + } + + TatalFilePath = AppendDevicePath (LoadedImageHandleDevicePath, LoadedImage->FilePath); + + DevicePathSize = GetDevicePathSize (DriverImageInfo->DriverImagePath); + if (DevicePathSize == GetDevicePathSize (TatalFilePath)) { + if (CompareMem ( + DriverImageInfo->DriverImagePath, + TatalFilePath, + GetDevicePathSize (TatalFilePath) + ) == 0 + ) { + ImageFound = TRUE; + break; + } + } + } + + if (ImageFound) { + Status = gBS->HandleProtocol ( + ImageHandleBuffer[Index], + &gEfiDriverBindingProtocolGuid, + (VOID **) &DriverBinding + ); + ASSERT (!EFI_ERROR (Status)); + DriverImageInfo->ImageHandle = ImageHandleBuffer[Index]; + } else { + // + // The driver image has not been loaded and started, need try to load and start it now + // Try to connect all device in the driver image path + // + Status = ConnectDevicePath (DriverImageInfo->DriverImagePath); + // + // check whether it points to a PCI Option Rom image, and try to use bus override protocol to get its first option rom image driver + // + TempDriverImagePath = DriverImageInfo->DriverImagePath; + gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &TempDriverImagePath, &Handle); + // + // Get the Bus Specific Driver Override Protocol instance on the Controller Handle + // + Status = gBS->HandleProtocol( + Handle, + &gEfiBusSpecificDriverOverrideProtocolGuid, + (VOID **) &BusSpecificDriverOverride + ); + if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) { + ImageHandle = NULL; + Status = BusSpecificDriverOverride->GetDriver ( + BusSpecificDriverOverride, + &ImageHandle + ); + if (!EFI_ERROR (Status)) { + Status = gBS->HandleProtocol ( + ImageHandle, + &gEfiDriverBindingProtocolGuid, + (VOID **) &DriverBinding + ); + ASSERT (!EFI_ERROR (Status)); + DriverImageInfo->ImageHandle = ImageHandle; + } + } + // + // Skip if any device cannot be connected now, future passes through GetDriver() may be able to load that driver. + // Only file path media or FwVol Device Path Node remain if all device is connected + // + TempDriverImagePath = DriverImageInfo->DriverImagePath; + gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &TempDriverImagePath, &Handle); + if (((DevicePathType (TempDriverImagePath) == MEDIA_DEVICE_PATH) && + (DevicePathSubType (TempDriverImagePath) == MEDIA_FILEPATH_DP)) || + (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) TempDriverImagePath) != NULL) + ) { + // + // Try to load the driver + // + TempDriverImagePath = DriverImageInfo->DriverImagePath; + Status = gBS->LoadImage ( + FALSE, + CallerImageHandle, + TempDriverImagePath, + NULL, + 0, + &ImageHandle + ); + if (!EFI_ERROR (Status)) { + // + // Try to start the driver + // + Status = gBS->StartImage (ImageHandle, NULL, NULL); + if (EFI_ERROR (Status)){ + DriverImageInfo->UnStartable = TRUE; + DriverImageInfo->ImageHandle = NULL; + } else { + Status = gBS->HandleProtocol ( + ImageHandle, + &gEfiDriverBindingProtocolGuid, + (VOID **) &DriverBinding + ); + ASSERT (!EFI_ERROR (Status)); + DriverImageInfo->ImageHandle = ImageHandle; + } + } else { + DriverImageInfo->UnLoadable = TRUE; + DriverImageInfo->ImageHandle = NULL; + } + } + } + FreePool (ImageHandleBuffer); + } + } + ImageInfoListIndex = ImageInfoListIndex->ForwardLink; + } + // + // Finish try to load and start the override driver of a controller, popup the controller's device path + // + PopDevPathStack (NULL); + + // + // return the DriverImageHandle for ControllerHandle + // + FoundLastReturned = FALSE; + ImageInfoListIndex = OverrideItem->DriverInfoList.ForwardLink; + while (ImageInfoListIndex != &OverrideItem->DriverInfoList){ + DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE); + if (DriverImageInfo->ImageHandle != NULL) { + if ((*DriverImageHandle == NULL) || FoundLastReturned) { + OverrideItem->LastReturnedImageHandle = DriverImageInfo->ImageHandle; + *DriverImageHandle = DriverImageInfo->ImageHandle; + return EFI_SUCCESS; + } else if (*DriverImageHandle == DriverImageInfo->ImageHandle){ + FoundLastReturned = TRUE; + } + } + ImageInfoListIndex = ImageInfoListIndex->ForwardLink; + } + + return EFI_NOT_FOUND; +} + + +/** + Check mapping database whether already has the mapping info which + records the input Controller to input DriverImage. + If has, the controller's total override driver number and input DriverImage's order number is return. + + @param ControllerDevicePath The controller device path need to add a + override driver image item + @param DriverImageDevicePath The driver image device path need to be insert + @param MappingDataBase Mapping database list entry pointer + @param DriverInfoNum the controller's total override driver number + @param DriverImageNO The inserted order number + + @return EFI_INVALID_PARAMETER + @return EFI_NOT_FOUND + @return EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +CheckMapping ( + IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath, + IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath, + IN LIST_ENTRY * MappingDataBase, + OUT UINT32 *DriverInfoNum, + OUT UINT32 *DriverImageNO + ) +{ + LIST_ENTRY *OverrideItemListIndex; + PLATFORM_OVERRIDE_ITEM *OverrideItem; + LIST_ENTRY *ImageInfoListIndex; + DRIVER_IMAGE_INFO *DriverImageInfo; + BOOLEAN Found; + UINT32 ImageNO; + UINTN DevicePathSize; + + // + // Check that ControllerHandle is a valid handle + // + if (ControllerDevicePath == NULL) { + return EFI_INVALID_PARAMETER; + } + if (MappingDataBase == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Search ControllerDevicePath in MappingDataBase + // + Found = FALSE; + OverrideItem = NULL; + OverrideItemListIndex = MappingDataBase->ForwardLink; + while (OverrideItemListIndex != MappingDataBase){ + OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE); + DevicePathSize = GetDevicePathSize (ControllerDevicePath); + if (DevicePathSize == GetDevicePathSize (OverrideItem->ControllerDevicePath)) { + if (CompareMem ( + ControllerDevicePath, + OverrideItem->ControllerDevicePath, + GetDevicePathSize (OverrideItem->ControllerDevicePath) + ) == 0 + ) { + Found = TRUE; + break; + } + } + OverrideItemListIndex = OverrideItemListIndex->ForwardLink; + } + + if (!Found) { + return EFI_NOT_FOUND; + } + + ASSERT (OverrideItem->DriverInfoNum != 0); + if (DriverInfoNum != NULL) { + *DriverInfoNum = OverrideItem->DriverInfoNum; + } + + + if (DriverImageDevicePath == NULL) { + return EFI_SUCCESS; + } + // + // return the DriverImageHandle for ControllerHandle + // + ImageNO = 0; + Found = FALSE; + ImageInfoListIndex = OverrideItem->DriverInfoList.ForwardLink; + while (ImageInfoListIndex != &OverrideItem->DriverInfoList){ + DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE); + ImageNO++; + DevicePathSize = GetDevicePathSize (DriverImageDevicePath); + if (DevicePathSize == GetDevicePathSize (DriverImageInfo->DriverImagePath)) { + if (CompareMem ( + DriverImageDevicePath, + DriverImageInfo->DriverImagePath, + GetDevicePathSize (DriverImageInfo->DriverImagePath) + ) == 0 + ) { + Found = TRUE; + break; + } + } + ImageInfoListIndex = ImageInfoListIndex->ForwardLink; + } + + if (!Found) { + return EFI_NOT_FOUND; + } else { + if (DriverImageNO != NULL) { + *DriverImageNO = ImageNO; + } + return EFI_SUCCESS; + } + +} + + +/** + Insert a driver image as a controller's override driver into the mapping database. + The driver image's order number is indicated by DriverImageNO. + + @param ControllerDevicePath The controller device path need to add a + override driver image item + @param DriverImageDevicePath The driver image device path need to be insert + @param MappingDataBase Mapping database list entry pointer + @param DriverImageNO The inserted order number + + @return EFI_INVALID_PARAMETER + @return EFI_ALREADY_STARTED + @return EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +InsertDriverImage ( + IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath, + IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath, + IN LIST_ENTRY *MappingDataBase, + IN UINT32 DriverImageNO + ) +{ + EFI_STATUS Status; + LIST_ENTRY *OverrideItemListIndex; + PLATFORM_OVERRIDE_ITEM *OverrideItem; + LIST_ENTRY *ImageInfoListIndex; + DRIVER_IMAGE_INFO *DriverImageInfo; + BOOLEAN Found; + UINT32 ImageNO; + UINTN DevicePathSize; + + // + // Check that ControllerHandle is a valid handle + // + if (ControllerDevicePath == NULL) { + return EFI_INVALID_PARAMETER; + } + if (DriverImageDevicePath == NULL) { + return EFI_INVALID_PARAMETER; + } + if (MappingDataBase == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = CheckMapping ( + ControllerDevicePath, + DriverImageDevicePath, + MappingDataBase, + NULL, + NULL + ); + if (Status == EFI_SUCCESS) { + return EFI_ALREADY_STARTED; + } + + // + // Search the input ControllerDevicePath in MappingDataBase + // + Found = FALSE; + OverrideItem = NULL; + OverrideItemListIndex = MappingDataBase->ForwardLink; + while (OverrideItemListIndex != MappingDataBase){ + OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE); + DevicePathSize = GetDevicePathSize (ControllerDevicePath); + if (DevicePathSize == GetDevicePathSize (OverrideItem->ControllerDevicePath)) { + if (CompareMem ( + ControllerDevicePath, + OverrideItem->ControllerDevicePath, + GetDevicePathSize (OverrideItem->ControllerDevicePath) + ) == 0 + ) { + Found = TRUE; + break; + } + } + OverrideItemListIndex = OverrideItemListIndex->ForwardLink; + } + // + // If cannot find, this is a new controller item + // Add the Controller related PLATFORM_OVERRIDE_ITEM structrue in mapping data base + // + if (!Found) { + OverrideItem = AllocateZeroPool (sizeof (PLATFORM_OVERRIDE_ITEM)); + ASSERT (OverrideItem != NULL); + OverrideItem->Signature = PLATFORM_OVERRIDE_ITEM_SIGNATURE; + OverrideItem->ControllerDevicePath = DuplicateDevicePath (ControllerDevicePath); + InitializeListHead (&OverrideItem->DriverInfoList); + InsertTailList (MappingDataBase, &OverrideItem->Link); + } + + // + // Prepare the driver image related DRIVER_IMAGE_INFO structure. + // + DriverImageInfo = AllocateZeroPool (sizeof (DRIVER_IMAGE_INFO)); + ASSERT (DriverImageInfo != NULL); + DriverImageInfo->Signature = DRIVER_IMAGE_INFO_SIGNATURE; + DriverImageInfo->DriverImagePath = DuplicateDevicePath (DriverImageDevicePath); + // + // Find the driver image wantted order location + // + ImageNO = 0; + Found = FALSE; + ImageInfoListIndex = OverrideItem->DriverInfoList.ForwardLink; + while (ImageInfoListIndex != &OverrideItem->DriverInfoList){ + if (ImageNO == (DriverImageNO - 1)) { + // + // find the wantted order location, insert it + // + InsertTailList (ImageInfoListIndex, &DriverImageInfo->Link); + OverrideItem->DriverInfoNum ++; + Found = TRUE; + break; + } + //DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE); + ImageNO++; + ImageInfoListIndex = ImageInfoListIndex->ForwardLink; + } + + if (!Found) { + // + // if not find the wantted order location, add it as last item of the controller mapping item + // + InsertTailList (&OverrideItem->DriverInfoList, &DriverImageInfo->Link); + OverrideItem->DriverInfoNum ++; + } + + return EFI_SUCCESS; +} + + +/** + Delete a controller's override driver from the mapping database. + + @param ControllerDevicePath The controller device path need to add a + override driver image item + @param DriverImageDevicePath The driver image device path need to be insert + @param MappingDataBase Mapping database list entry pointer + @param DriverImageNO The inserted order number + + @return EFI_INVALID_PARAMETER + @return EFI_NOT_FOUND + @return EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +DeleteDriverImage ( + IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath, + IN EFI_DEVICE_PATH_PROTOCOL *DriverImageDevicePath, + IN LIST_ENTRY *MappingDataBase + ) +{ + EFI_STATUS Status; + LIST_ENTRY *OverrideItemListIndex; + PLATFORM_OVERRIDE_ITEM *OverrideItem; + LIST_ENTRY *ImageInfoListIndex; + DRIVER_IMAGE_INFO *DriverImageInfo; + BOOLEAN Found; + UINTN DevicePathSize; + + // + // Check that ControllerHandle is a valid handle + // + if (ControllerDevicePath == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (MappingDataBase == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = CheckMapping ( + ControllerDevicePath, + DriverImageDevicePath, + MappingDataBase, + NULL, + NULL + ); + if (Status == EFI_NOT_FOUND) { + return EFI_NOT_FOUND; + } + + // + // Search ControllerDevicePath in MappingDataBase + // + Found = FALSE; + OverrideItem = NULL; + OverrideItemListIndex = MappingDataBase->ForwardLink; + while (OverrideItemListIndex != MappingDataBase){ + OverrideItem = CR(OverrideItemListIndex, PLATFORM_OVERRIDE_ITEM, Link, PLATFORM_OVERRIDE_ITEM_SIGNATURE); + DevicePathSize = GetDevicePathSize (ControllerDevicePath); + if (DevicePathSize == GetDevicePathSize (OverrideItem->ControllerDevicePath)) { + if (CompareMem ( + ControllerDevicePath, + OverrideItem->ControllerDevicePath, + GetDevicePathSize (OverrideItem->ControllerDevicePath) + ) == 0 + ) { + Found = TRUE; + break; + } + } + OverrideItemListIndex = OverrideItemListIndex->ForwardLink; + } + + ASSERT (Found); + ASSERT (OverrideItem->DriverInfoNum != 0); + // + // + // + Found = FALSE; + ImageInfoListIndex = OverrideItem->DriverInfoList.ForwardLink; + while (ImageInfoListIndex != &OverrideItem->DriverInfoList){ + DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE); + ImageInfoListIndex = ImageInfoListIndex->ForwardLink; + if (DriverImageDevicePath != NULL) { + DevicePathSize = GetDevicePathSize (DriverImageDevicePath); + if (DevicePathSize == GetDevicePathSize (DriverImageInfo->DriverImagePath)) { + if (CompareMem ( + DriverImageDevicePath, + DriverImageInfo->DriverImagePath, + GetDevicePathSize (DriverImageInfo->DriverImagePath) + ) == 0 + ) { + Found = TRUE; + FreePool(DriverImageInfo->DriverImagePath); + RemoveEntryList (&DriverImageInfo->Link); + OverrideItem->DriverInfoNum --; + break; + } + } + } else { + Found = TRUE; + FreePool(DriverImageInfo->DriverImagePath); + RemoveEntryList (&DriverImageInfo->Link); + OverrideItem->DriverInfoNum --; + } + } + + if (DriverImageDevicePath == NULL) { + ASSERT (OverrideItem->DriverInfoNum == 0); + } + + if (OverrideItem->DriverInfoNum == 0) { + FreePool(OverrideItem->ControllerDevicePath); + RemoveEntryList (&OverrideItem->Link); + FreePool (OverrideItem); + } + + if (!Found) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + + +/** + Deletes all environment variable(s) that contain the override mappings from Controller Device Path to + a set of Driver Device Paths. + + None + + @return EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +DeleteOverridesVariables ( + VOID + ) +{ + EFI_STATUS Status; + VOID *VariableBuffer; + UINTN VariableNum; + UINTN BufferSize; + UINTN Index; + CHAR16 OverrideVariableName[40]; + + // + // Get environment variable(s) number + // + VariableNum =0; + VariableBuffer = GetVariableAndSize (L"PlatDriOver", &gEfiOverrideVariableGuid, &BufferSize); + VariableNum ++; + if (VariableBuffer == NULL) { + return EFI_NOT_FOUND; + } + // + // Check NotEnd to get all PlatDriOverX variable(s) + // + while (*(UINT32*)VariableBuffer) { + UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver%d", VariableNum); + VariableBuffer = GetVariableAndSize (OverrideVariableName, &gEfiOverrideVariableGuid, &BufferSize); + VariableNum ++; + ASSERT (VariableBuffer != NULL); + } + + Status = gRT->SetVariable ( + L"PlatDriOver", + &gEfiOverrideVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + 0, + NULL + ); + ASSERT (!EFI_ERROR (Status)); + for (Index = 1; Index < VariableNum; Index++) { + UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver%d", Index); + Status = gRT->SetVariable ( + OverrideVariableName, + &gEfiOverrideVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + 0, + NULL + ); + ASSERT (!EFI_ERROR (Status)); + } + return EFI_SUCCESS; +} + + +/** + Push a controller device path into a globle device path list + + @param ControllerDevicePath The controller device path need to push into + stack + + @return EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +PushDevPathStack ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + DEVICE_PATH_STACK_ITEM *DevicePathStackItem; + + DevicePathStackItem = AllocateZeroPool (sizeof (DEVICE_PATH_STACK_ITEM)); + ASSERT (DevicePathStackItem != NULL); + DevicePathStackItem->Signature = DEVICE_PATH_STACK_ITEM_SIGNATURE; + DevicePathStackItem->DevicePath = DuplicateDevicePath (DevicePath); + InsertTailList (&mDevicePathStack, &DevicePathStackItem->Link); + return EFI_SUCCESS; +} + + +/** + Pop a controller device path from a globle device path list + + @param ControllerDevicePath The controller device path retrieved from stack + + @return EFI_SUCCESS + @return EFI_NOT_FOUND + +**/ +EFI_STATUS +EFIAPI +PopDevPathStack ( + OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath + ) +{ + DEVICE_PATH_STACK_ITEM *DevicePathStackItem; + LIST_ENTRY *ItemListIndex; + + ItemListIndex = mDevicePathStack.BackLink; + if (ItemListIndex != &mDevicePathStack){ + DevicePathStackItem = CR(ItemListIndex, DEVICE_PATH_STACK_ITEM, Link, DEVICE_PATH_STACK_ITEM_SIGNATURE); + if (DevicePath != NULL) { + *DevicePath = DuplicateDevicePath (DevicePathStackItem->DevicePath); + } + FreePool (DevicePathStackItem->DevicePath); + RemoveEntryList (&DevicePathStackItem->Link); + FreePool (DevicePathStackItem); + return EFI_SUCCESS; + } + return EFI_NOT_FOUND; +} + + +/** + Check whether a controller device path is in a globle device path list + + @param ControllerDevicePath The controller device path need to check + + @return True + @return False + +**/ +BOOLEAN +EFIAPI +CheckExistInStack ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + DEVICE_PATH_STACK_ITEM *DevicePathStackItem; + LIST_ENTRY *ItemListIndex; + BOOLEAN Found; + UINTN DevicePathSize; + + Found = FALSE; + ItemListIndex = mDevicePathStack.BackLink; + while (ItemListIndex != &mDevicePathStack){ + DevicePathStackItem = CR(ItemListIndex, DEVICE_PATH_STACK_ITEM, Link, DEVICE_PATH_STACK_ITEM_SIGNATURE); + DevicePathSize = GetDevicePathSize (DevicePath); + if (DevicePathSize == GetDevicePathSize (DevicePathStackItem->DevicePath)) { + if (CompareMem ( + DevicePath, + DevicePathStackItem->DevicePath, + GetDevicePathSize (DevicePathStackItem->DevicePath) + ) == 0 + ) { + Found = TRUE; + break; + } + } + ItemListIndex = ItemListIndex->BackLink; + } + + return Found; +} + + +/** + According to a file guild, check a Fv file device path is valid. If it is invalid, + try to return the valid device path. + FV address maybe changes for memory layout adjust from time to time, use this funciton + could promise the Fv file device path is right. + + @param DevicePath on input, the Fv file device path need to check + on output, the updated valid Fv file device path + @param FileGuid the Fv file guild + @param CallerImageHandle + + @retval EFI_INVALID_PARAMETER the input DevicePath or FileGuid is invalid + parameter + @retval EFI_UNSUPPORTED the input DevicePath does not contain Fv file + guild at all + @retval EFI_ALREADY_STARTED the input DevicePath has pointed to Fv file, it + is valid + @retval EFI_SUCCESS has successfully updated the invalid DevicePath, + and return the updated device path in DevicePath + +**/ +EFI_STATUS +EFIAPI +UpdateFvFileDevicePath ( + IN OUT EFI_DEVICE_PATH_PROTOCOL ** DevicePath, + IN EFI_GUID *FileGuid, + IN EFI_HANDLE CallerImageHandle + ) +{ + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode; + EFI_STATUS Status; + EFI_GUID *GuidPoint; + UINTN Index; + UINTN FvHandleCount; + EFI_HANDLE *FvHandleBuffer; + EFI_FV_FILETYPE Type; + UINTN Size; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINT32 AuthenticationStatus; + BOOLEAN FindFvFile; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileNode; + EFI_HANDLE FoundFvHandle; + EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + BOOLEAN HasFVNode; + + if ((DevicePath == NULL) || (*DevicePath == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Check whether the device path point to the default the input Fv file + // + TempDevicePath = *DevicePath; + LastDeviceNode = TempDevicePath; + while (!EfiIsDevicePathEnd (TempDevicePath)) { + LastDeviceNode = TempDevicePath; + TempDevicePath = EfiNextDevicePathNode (TempDevicePath); + } + GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode ( + (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode + ); + if (GuidPoint == NULL) { + // + // if this option does not points to a Fv file, just return EFI_UNSUPPORTED + // + return EFI_UNSUPPORTED; + } + + if (FileGuid != NULL) { + if (!CompareGuid (GuidPoint, FileGuid)) { + // + // If the Fv file is not the input file guid, just return EFI_UNSUPPORTED + // + return EFI_UNSUPPORTED; + } + } else { + FileGuid = GuidPoint; + } + + // + // Check to see if the device path contain memory map node + // + TempDevicePath = *DevicePath; + HasFVNode = FALSE; + while (!EfiIsDevicePathEnd (TempDevicePath)) { + // + // Use old Device Path + // + if (DevicePathType (TempDevicePath) == HARDWARE_DEVICE_PATH && + DevicePathSubType (TempDevicePath) == HW_MEMMAP_DP) { + HasFVNode = TRUE; + break; + } + TempDevicePath = EfiNextDevicePathNode (TempDevicePath); + } + + if (!HasFVNode) { + return EFI_UNSUPPORTED; + } + + // + // Check whether the input Fv file device path is valid + // + TempDevicePath = *DevicePath; + FoundFvHandle = NULL; + Status = gBS->LocateDevicePath ( + &gEfiFirmwareVolume2ProtocolGuid, + &TempDevicePath, + &FoundFvHandle + ); + if (!EFI_ERROR (Status)) { + Status = gBS->HandleProtocol ( + FoundFvHandle, + &gEfiFirmwareVolume2ProtocolGuid, + (VOID **) &Fv + ); + if (!EFI_ERROR (Status)) { + // + // Set FV ReadFile Buffer as NULL, only need to check whether input Fv file exist there + // + Status = Fv->ReadFile ( + Fv, + FileGuid, + NULL, + &Size, + &Type, + &Attributes, + &AuthenticationStatus + ); + if (!EFI_ERROR (Status)) { + return EFI_ALREADY_STARTED; + } + } + } + + // + // Look for the input wanted FV file in current FV + // First, try to look for in Caller own FV. Caller and input wanted FV file usually are in the same FV + // + FindFvFile = FALSE; + FoundFvHandle = NULL; + Status = gBS->HandleProtocol ( + CallerImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **) &LoadedImage + ); + if (!EFI_ERROR (Status)) { + Status = gBS->HandleProtocol ( + LoadedImage->DeviceHandle, + &gEfiFirmwareVolume2ProtocolGuid, + (VOID **) &Fv + ); + if (!EFI_ERROR (Status)) { + Status = Fv->ReadFile ( + Fv, + FileGuid, + NULL, + &Size, + &Type, + &Attributes, + &AuthenticationStatus + ); + if (!EFI_ERROR (Status)) { + FindFvFile = TRUE; + FoundFvHandle = LoadedImage->DeviceHandle; + } + } + } + // + // Second, if fail to find, try to enumerate all FV + // + if (!FindFvFile) { + gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolume2ProtocolGuid, + NULL, + &FvHandleCount, + &FvHandleBuffer + ); + for (Index = 0; Index < FvHandleCount; Index++) { + gBS->HandleProtocol ( + FvHandleBuffer[Index], + &gEfiFirmwareVolume2ProtocolGuid, + (VOID **) &Fv + ); + + Status = Fv->ReadFile ( + Fv, + FileGuid, + NULL, + &Size, + &Type, + &Attributes, + &AuthenticationStatus + ); + if (EFI_ERROR (Status)) { + // + // Skip if input Fv file not in the FV + // + continue; + } + FindFvFile = TRUE; + FoundFvHandle = FvHandleBuffer[Index]; + break; + } + } + + if (FindFvFile) { + // + // Build the shell device path + // + NewDevicePath = DevicePathFromHandle (FoundFvHandle); + EfiInitializeFwVolDevicepathNode (&FvFileNode, FileGuid); + NewDevicePath = AppendDevicePathNode (NewDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &FvFileNode); + *DevicePath = NewDevicePath; + return EFI_SUCCESS; + } + return EFI_NOT_FOUND; +} + + +/** + Read the EFI variable (VendorGuid/Name) and return a dynamically allocated + buffer, and the size of the buffer. If failure return NULL. + + @param Name String part of EFI variable name + @param VendorGuid GUID part of EFI variable name + @param VariableSize Returns the size of the EFI variable that was + read + + @return Dynamically allocated memory that contains a copy of the EFI variable. + @return Caller is responsible freeing the buffer. + @retval NULL Variable was not read + +**/ +VOID * +EFIAPI +GetVariableAndSize ( + IN CHAR16 *Name, + IN EFI_GUID *VendorGuid, + OUT UINTN *VariableSize + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + VOID *Buffer; + + Buffer = NULL; + + // + // Pass in a zero size buffer to find the required buffer size. + // + BufferSize = 0; + Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer); + if (Status == EFI_BUFFER_TOO_SMALL) { + // + // Allocate the buffer to return + // + Buffer = AllocateZeroPool (BufferSize); + if (Buffer == NULL) { + return NULL; + } + // + // Read variable into the allocated buffer. + // + Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer); + if (EFI_ERROR (Status)) { + BufferSize = 0; + } + } + + *VariableSize = BufferSize; + return Buffer; +} + + +/** + This function will create all handles associate with every device + path node. If the handle associate with one device path node can not + be created success, then still give one chance to do the dispatch, + which load the missing drivers if possible. + + @param DevicePathToConnect The device path which will be connected, it can + be a multi-instance device path + + @retval EFI_SUCCESS All handles associate with every device path + node have been created + @retval EFI_OUT_OF_RESOURCES There is no resource to create new handles + @retval EFI_NOT_FOUND Create the handle associate with one device + path node failed + +**/ +EFI_STATUS +EFIAPI +ConnectDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath; + EFI_DEVICE_PATH_PROTOCOL *Instance; + EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; + EFI_DEVICE_PATH_PROTOCOL *Next; + EFI_HANDLE Handle; + EFI_HANDLE PreviousHandle; + UINTN Size; + + if (DevicePathToConnect == NULL) { + return EFI_SUCCESS; + } + + DevicePath = DuplicateDevicePath (DevicePathToConnect); + CopyOfDevicePath = DevicePath; + if (DevicePath == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + do { + // + // The outer loop handles multi instance device paths. + // Only console variables contain multiple instance device paths. + // + // After this call DevicePath points to the next Instance + // + Instance = GetNextDevicePathInstance (&DevicePath, &Size); + Next = Instance; + while (!IsDevicePathEndType (Next)) { + Next = NextDevicePathNode (Next); + } + + SetDevicePathEndNode (Next); + + // + // Start the real work of connect with RemainingDevicePath + // + PreviousHandle = NULL; + do { + // + // Find the handle that best matches the Device Path. If it is only a + // partial match the remaining part of the device path is returned in + // RemainingDevicePath. + // + RemainingDevicePath = Instance; + Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle); + + if (!EFI_ERROR (Status)) { + if (Handle == PreviousHandle) { + // + // If no forward progress is made try invoking the Dispatcher. + // A new FV may have been added to the system an new drivers + // may now be found. + // Status == EFI_SUCCESS means a driver was dispatched + // Status == EFI_NOT_FOUND means no new drivers were dispatched + // + Status = gDS->Dispatch (); + } + + if (!EFI_ERROR (Status)) { + PreviousHandle = Handle; + // + // Connect all drivers that apply to Handle and RemainingDevicePath, + // the Recursive flag is FALSE so only one level will be expanded. + // + // Do not check the connect status here, if the connect controller fail, + // then still give the chance to do dispatch, because partial + // RemainingDevicepath may be in the new FV + // + // 1. If the connect fail, RemainingDevicepath and handle will not + // change, so next time will do the dispatch, then dispatch's status + // will take effect + // 2. If the connect success, the RemainingDevicepath and handle will + // change, then avoid the dispatch, we have chance to continue the + // next connection + // + gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE); + } + } + // + // Loop until RemainingDevicePath is an empty device path + // + } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath)); + + } while (DevicePath != NULL); + + if (CopyOfDevicePath != NULL) { + FreePool (CopyOfDevicePath); + } + // + // All handle with DevicePath exists in the handle database + // + return Status; +} diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index dadf7a698c..f182323a45 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -2,7 +2,7 @@ # Mde Module Package Reference Implementations # # This module provides headers and libraries that conform to EFI/PI Industry standards. -# Copyright (c) 2007, Intel Corporation. +# Copyright (c) 2007 - 2008, Intel Corporation. # # All rights reserved. # This program and the accompanying materials are licensed and made available under @@ -33,6 +33,7 @@ UdpIoLib|Include/Library/UdpIoLib.h S3Lib|Include/Library/S3Lib.h RecoveryLib|Include/Library/RecoveryLib.h + PlatDriOverLib|Include/Library/PlatDriOverLib.h [Guids.common] @@ -64,6 +65,7 @@ gEfiPeiPeCoffLoaderGuid = { 0xD8117CFF, 0x94A6, 0x11D4, { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }} gEfiVariableInfoGuid = { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }} gSimpleTextInExNotifyGuid = { 0x856f2def, 0x4e93, 0x4d6b, { 0x94, 0xce, 0x1c, 0xfe, 0x47, 0x01, 0x3e, 0xa5 }} + gEfiOverrideVariableGuid = { 0x8e3d4ad5, 0xf762, 0x438a, { 0xa1, 0xc1, 0x5b, 0x9f, 0xe6, 0x8c, 0x6b, 0x15 }} [Protocols.common] @@ -97,7 +99,7 @@ ##gPeiFlashMapPpiGuid will be removed in future gPeiFlashMapPpiGuid = { 0xf34c2fa0, 0xde88, 0x4270, {0x84, 0x14, 0x96, 0x12, 0x22, 0xf4, 0x52, 0x1c } } - + gPeiOperatorPresencePpiGuid = { 0x20a7378c, 0xaa83, 0x4ce1, {0x82, 0x1f, 0x47, 0x40, 0xee, 0x1b, 0x3f, 0x9f } } [PcdsFeatureFlag.common] diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 5f53c67b2c..637cdfbe80 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -72,6 +72,7 @@ DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + PlatDriOverLib|MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.inf [LibraryClasses.IA32] IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf @@ -255,6 +256,8 @@ MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf + MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.inf + MdeModulePkg/Library/PeiS3LibNull/PeiS3LibNull.inf MdeModulePkg/Library/PeiRecoveryLibNull/PeiRecoveryLibNull.inf @@ -274,6 +277,8 @@ MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf + MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf + MdeModulePkg/Application/HelloWorld/HelloWorld.inf MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf diff --git a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverride.c b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverride.c new file mode 100644 index 0000000000..2a189138ed --- /dev/null +++ b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverride.c @@ -0,0 +1,186 @@ +/** @file + +Copyright (c) 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PlatformDriOverride.c + +Abstract: + + +**/ + + +#include "PlatformDriOverride.h" + +EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL gPlatformDriverOverride = { + GetDriver, + GetDriverPath, + DriverLoaded +}; + +STATIC LIST_ENTRY mMappingDataBase = INITIALIZE_LIST_HEAD_VARIABLE (mMappingDataBase); +STATIC BOOLEAN mEnvironmentVariableRead = FALSE; +STATIC EFI_HANDLE mCallerImageHandle; + + +EFI_STATUS +EFIAPI +PlatformDriverOverrideEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + Platform Driver Override driver entry point, install the Platform Driver Override Protocol + +Arguments: + (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT) + +Returns: + EFI_STATUS + +--*/ +{ + mEnvironmentVariableRead = FALSE; + mCallerImageHandle = ImageHandle; + InitializeListHead (&mMappingDataBase); + return InstallPlatformDriverOverrideProtocol (&gPlatformDriverOverride); +} + + +/** + Retrieves the image handle of the platform override driver for a controller in the system. + + @param This A pointer to the + EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL instance. + @param ControllerHandle The device handle of the controller to check if a + driver override exists. + @param DriverImageHandle On input, a pointer to the previous driver image + handle returned by GetDriver(). On output, a + pointer to the next driver image handle. Passing + in a NULL, will return the first driver image + handle for ControllerHandle. + + @retval EFI_SUCCESS The driver override for ControllerHandle was + returned in DriverImageHandle. + @retval EFI_NOT_FOUND A driver override for ControllerHandle was not + found. + @retval EFI_INVALID_PARAMETER The handle specified by ControllerHandle is not a + valid handle. DriverImageHandle is not a handle + that was returned on a previous call to + GetDriver(). + +**/ +STATIC +EFI_STATUS +EFIAPI +GetDriver ( + IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL * This, + IN EFI_HANDLE ControllerHandle, + IN OUT EFI_HANDLE * DriverImageHandle + ) +{ + EFI_STATUS Status; + // + // Check that ControllerHandle is a valid handle + // + if (ControllerHandle == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Read the environment variable(s) that contain the override mappings from Controller Device Path to + // a set of Driver Device Paths, and initialize in memory database of the overrides that map Controller + // Device Paths to an ordered set of Driver Device Paths and Driver Handles. This action is only performed + // once and finished in first call. + // + if (!mEnvironmentVariableRead) { + mEnvironmentVariableRead = TRUE; + + Status = InitOverridesMapping (&mMappingDataBase); + if (Status == EFI_NOT_FOUND) { + InitializeListHead (&mMappingDataBase); + return EFI_NOT_FOUND; + } else if (Status == EFI_VOLUME_CORRUPTED){ + DEBUG ((DEBUG_ERROR, "Platform Driver Override Variable is corrupt\n")); + // + // The environment variable(s) that contain the override mappings from Controller Device Path to + // a set of Driver Device Paths is corrupted, platform code can use LibDeleteOverridesVariables to + // delete all orverride variables as a policy. Here can be IBV/OEM customized. + // + + //LibDeleteOverridesVariables(); + InitializeListHead (&mMappingDataBase); + return EFI_NOT_FOUND; + } else if (EFI_ERROR (Status)){ + InitializeListHead (&mMappingDataBase); + return EFI_NOT_FOUND; + } + } + // + // if the environment variable does not exist or the variable appears to be corrupt, just return not found + // + if (IsListEmpty (&mMappingDataBase)) { + return EFI_NOT_FOUND; + } + + return GetDriverFromMapping ( + This, + ControllerHandle, + DriverImageHandle, + &mMappingDataBase, + mCallerImageHandle + ); + +} + + +/** + For the use of the ControllerHandle parameter in the GetDriverPath() and DriverLoaded() APIs + makes those APIs very difficult to use, so not support. + + + +**/ +STATIC +EFI_STATUS +EFIAPI +GetDriverPath ( + IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL * This, + IN EFI_HANDLE ControllerHandle, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DriverImagePath + ) +{ + return EFI_UNSUPPORTED; +} + + +/** + For the use of the ControllerHandle parameter in the GetDriverPath() and DriverLoaded() APIs + makes those APIs very difficult to use, so not support. + + + +**/ +STATIC +EFI_STATUS +EFIAPI +DriverLoaded ( + IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL * This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL * DriverImagePath, + IN EFI_HANDLE DriverImageHandle + ) +{ + return EFI_UNSUPPORTED; +} diff --git a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverride.h b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverride.h new file mode 100644 index 0000000000..5a5b276451 --- /dev/null +++ b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverride.h @@ -0,0 +1,58 @@ +/** @file + +Copyright (c) 2007, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + PlatformDriOverride.h + +Abstract: + + +**/ + +#ifndef PLATFORM_DRI_OVERRIDE_H_ +#define PLATFORM_DRI_OVERRIDE_H_ + +#include + +#include +#include +#include +#include + +STATIC +EFI_STATUS +EFIAPI +GetDriver ( + IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL * This, + IN EFI_HANDLE ControllerHandle, + IN OUT EFI_HANDLE * DriverImageHandle + ); + +STATIC +EFI_STATUS +EFIAPI +GetDriverPath ( + IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL * This, + IN EFI_HANDLE ControllerHandle, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DriverImagePath + ); + +STATIC +EFI_STATUS +EFIAPI +DriverLoaded ( + IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL * This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL * DriverImagePath, + IN EFI_HANDLE DriverImageHandle + ); +#endif diff --git a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf new file mode 100644 index 0000000000..dbc9f0ecb7 --- /dev/null +++ b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf @@ -0,0 +1,48 @@ +#/** @file +# Component name for module PlatformDriOverride +# +# FIX ME! +# Copyright (c) 2007, Intel Corporation. All rights reserved. +# +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PlatformDriOverrideDxe + FILE_GUID = 35034CE2-A6E5-4fb4-BABE-A0156E9B2549 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = PlatformDriverOverrideEntry + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources.common] + PlatformDriOverride.c + PlatformDriOverride.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + UefiDriverEntryPoint + DebugLib + PlatDriOverLib + diff --git a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.msa b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.msa new file mode 100644 index 0000000000..6e1645af35 --- /dev/null +++ b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.msa @@ -0,0 +1,50 @@ + + + PlatformDriOverrideDxe + DXE_DRIVER + 35034CE2-A6E5-4fb4-BABE-A0156E9B2549 + 1.0 + Component name for module PlatformDriOverride + FIX ME! + Copyright (c) 2007, Intel Corporation. All rights reserved. + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + PlatformDriOverrideDxe + + + + DebugLib + + + UefiDriverEntryPoint + + + BaseLib + + + + PlatformDriOverride.h + PlatformDriOverride.c + + + + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + PlatformDriverOverrideEntry + + + \ No newline at end of file