]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Port PlatformDriOverrideDxe into R9.
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 16 Jan 2008 09:04:43 +0000 (09:04 +0000)
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 16 Jan 2008 09:04:43 +0000 (09:04 +0000)
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

12 files changed:
MdeModulePkg/Include/Guid/OverrideVariable.h [new file with mode: 0644]
MdeModulePkg/Include/Library/PlatDriOverLib.h [new file with mode: 0644]
MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.inf [new file with mode: 0644]
MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.msa [new file with mode: 0644]
MdeModulePkg/Library/DxePlatDriOverLib/PlatDriOver.h [new file with mode: 0644]
MdeModulePkg/Library/DxePlatDriOverLib/PlatDriOverLib.c [new file with mode: 0644]
MdeModulePkg/MdeModulePkg.dec
MdeModulePkg/MdeModulePkg.dsc
MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverride.c [new file with mode: 0644]
MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverride.h [new file with mode: 0644]
MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf [new file with mode: 0644]
MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.msa [new file with mode: 0644]

diff --git a/MdeModulePkg/Include/Guid/OverrideVariable.h b/MdeModulePkg/Include/Guid/OverrideVariable.h
new file mode 100644 (file)
index 0000000..673813a
--- /dev/null
@@ -0,0 +1,34 @@
+/*++\r
+\r
+Copyright (c) 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
+  OverrideVariable.h\r
+\r
+Abstract:\r
+\r
+  Platform Override Variable Guid definitions\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
+extern EFI_GUID gEfiOverrideVariableGuid;\r
+\r
+\r
+#endif // #ifndef __EFI_OVERRIDE_VARIABLE_GUID_H__\r
diff --git a/MdeModulePkg/Include/Library/PlatDriOverLib.h b/MdeModulePkg/Include/Library/PlatDriOverLib.h
new file mode 100644 (file)
index 0000000..8e6ab17
--- /dev/null
@@ -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 <PiDxe.h>
+#include <Protocol/PlatformDriverOverride.h>
+#include <Protocol/DevicePath.h>
+#include <Library/BaseLib.h>
+
+#include <VariableFormat.h>
+
+/**\r
+  Install the Platform Driver Override Protocol, and ensure there is only one Platform Driver Override Protocol\r
+  in the system.\r
+\r
+  @param  gPlatformDriverOverride  PlatformDriverOverride protocol interface which\r
+                                   needs to be installed\r
+\r
+  @retval EFI_ALREADY_STARTED      There has been a Platform Driver Override\r
+                                   Protocol in the system, cannot install it again.\r
+  @retval Other                    Returned by InstallProtocolInterface\r
+\r
+**/
+EFI_STATUS
+EFIAPI
+InstallPlatformDriverOverrideProtocol (
+  EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *gPlatformDriverOverride
+  );
+
+/**\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
+**/
+EFI_STATUS
+EFIAPI
+FreeMappingDatabase (
+  IN  OUT  LIST_ENTRY            *MappingDataBase
+  );
+
+/**\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 multi variables to store\r
+  // large mapping infos.\r
+  // The variable(s) name rule is PlatDriOver, PlatDriOver1, PlatDriOver2, ....\r
+  //\r
+  UINT32                         NotEnd;\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;            //EFI_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                         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
+  typedef struct _PLATFORM_OVERRIDE_ITEM{\r
+  UINTN                          Signature;                  //EFI_SIGNATURE_32('p','d','o','i')\r
+  LIST_ENTRY                     Link;\r
+  UINT32                         DriverInfoNum;\r
+  EFI_DEVICE_PATH_PROTOCOL       *ControllerDevicePath;\r
+  LIST_ENTRY                     DriverInfoList;         //DRIVER_IMAGE_INFO List\r
+  } PLATFORM_OVERRIDE_ITEM;\r
+  typedef struct _DRIVER_IMAGE_INFO{\r
+  UINTN                          Signature;                  //EFI_SIGNATURE_32('p','d','i','i')\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
+  @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\r
+                                   successfully\r
+\r
+**/
+EFI_STATUS
+EFIAPI
+InitOverridesMapping (
+  OUT  LIST_ENTRY            *MappingDataBase
+  );
+
+/**\r
+  Save the memory mapping database into NV environment variable(s)\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
+**/
+EFI_STATUS
+EFIAPI
+SaveOverridesMapping (
+  IN  LIST_ENTRY              *MappingDataBase
+  );
+
+/**\r
+  Retrieves the image handle of the platform override driver for a controller in the system from the memory mapping database.\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\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
+**/
+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
+  );
+
+/**\r
+  Check mapping database whether already has the  mapping info which\r
+  records the input Controller to input DriverImage.\r
+  If has, the controller's total override driver number and input DriverImage's order number is return.\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  DriverInfoNum            the controller's total override driver number\r
+  @param  DriverImageNO            The inserted order number\r
+\r
+  @return EFI_INVALID_PARAMETER\r
+  @return EFI_NOT_FOUND\r
+  @return EFI_SUCCESS\r
+\r
+**/
+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
+  );
+
+/**\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\r
+\r
+  @return EFI_INVALID_PARAMETER\r
+  @return EFI_ALREADY_STARTED\r
+  @return EFI_SUCCESS\r
+\r
+**/
+EFI_STATUS
+EFIAPI
+InsertDriverImage (
+  IN     EFI_DEVICE_PATH_PROTOCOL                       *ControllerDevicePath,
+  IN     EFI_DEVICE_PATH_PROTOCOL                       *DriverImageDevicePath,
+  IN     LIST_ENTRY                                     *MappingDataBase,
+  IN     UINT32                                         DriverImageNO
+  );
+
+/**\r
+  Delete a controller's override driver from the mapping database.\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\r
+\r
+  @return EFI_INVALID_PARAMETER\r
+  @return EFI_NOT_FOUND\r
+  @return EFI_SUCCESS\r
+\r
+**/
+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 (file)
index 0000000..1ba2d78
--- /dev/null
@@ -0,0 +1,65 @@
+#/** @file\r
+# Component name for module PlatDriOverLib\r
+#\r
+# FIX ME!\r
+# Copyright (c) 2007, 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                  = PlatDriOverLib\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\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
+  gEfiOverrideVariableGuid                      # ALWAYS_CONSUMED\r
+\r
+[Protocols]\r
+  gEfiFirmwareVolume2ProtocolGuid               # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiLoadedImageProtocolGuid                   # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiPlatformDriverOverrideProtocolGuid        # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiBusSpecificDriverOverrideProtocolGuid     # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiDriverBindingProtocolGuid                 # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiDevicePathProtocolGuid                    # PROTOCOL ALWAYS_CONSUMED\r
+\r
diff --git a/MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.msa b/MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.msa
new file mode 100644 (file)
index 0000000..f01088e
--- /dev/null
@@ -0,0 +1,94 @@
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+  <MsaHeader>\r
+    <ModuleName>PlatDriOverLib</ModuleName>\r
+    <ModuleType>DXE_DRIVER</ModuleType>\r
+    <GuidValue>8bd8d711-2736-46d7-8c81-5de68e0a9e88</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component name for module PlatDriOverLib</Abstract>\r
+    <Description>FIX ME!</Description>\r
+    <Copyright>Copyright (c) 2007, Intel Corporation. All rights reserved.</Copyright>\r
+    <License>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.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>PlatDriOverLib</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_PRODUCED">\r
+      <Keyword>PlatDriOverLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>PrintLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DebugLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiRuntimeServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DevicePathLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>MemoryAllocationLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DxeServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>PlatDriOverLib.c</Filename>\r
+    <Filename>PlatDriOver.h</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiDriverBindingProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiBusSpecificDriverOverrideProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiPlatformDriverOverrideProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiLoadedImageProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiFirmwareVolumeProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiFirmwareVolume2ProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+  </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file
diff --git a/MdeModulePkg/Library/DxePlatDriOverLib/PlatDriOver.h b/MdeModulePkg/Library/DxePlatDriOverLib/PlatDriOver.h
new file mode 100644 (file)
index 0000000..331a9bc
--- /dev/null
@@ -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 <PiDxe.h>
+
+#include <Protocol/FirmwareVolume2.h>\r
+#include <Protocol/LoadedImage.h>\r
+#include <Protocol/PlatformDriverOverride.h>\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/BusSpecificDriverOverride.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>
+#include <Library/PlatDriOverLib.h>\r
+
+#include <Guid/OverrideVariable.h>
+
+
+#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 (file)
index 0000000..d32715b
--- /dev/null
@@ -0,0 +1,1800 @@
+/** @file\r
+\r
+Copyright (c) 2007, 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
+    PlatDriOverLib.c\r
+\r
+Abstract:\r
+\r
+\r
+**/\r
+\r
+#include "PlatDriOver.h"\r
+\r
+STATIC LIST_ENTRY   mDevicePathStack = INITIALIZE_LIST_HEAD_VARIABLE (mDevicePathStack);\r
+\r
+\r
+/**\r
+  Install the Platform Driver Override Protocol, and ensure there is only one Platform Driver Override Protocol\r
+  in the system.\r
+\r
+  @param  gPlatformDriverOverride  PlatformDriverOverride protocol interface which\r
+                                   needs to be installed\r
+\r
+  @retval EFI_ALREADY_STARTED      There has been a Platform Driver Override\r
+                                   Protocol in the system, cannot install it again.\r
+  @retval Other                    Returned by InstallProtocolInterface\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InstallPlatformDriverOverrideProtocol (\r
+  EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *gPlatformDriverOverride\r
+  )\r
+{\r
+  EFI_HANDLE          Handle;\r
+  EFI_STATUS          Status;\r
+  UINTN               HandleCount;\r
+  EFI_HANDLE          *HandleBuffer;\r
+\r
+  //\r
+  // There will be only one platform driver override protocol in the system\r
+  // If there is another out there, someone is trying to install us again,\r
+  // Fail that scenario.\r
+  //\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiPlatformDriverOverrideProtocolGuid,\r
+                  NULL,\r
+                  &HandleCount,\r
+                  &HandleBuffer\r
+                  );\r
+  //\r
+  // If there was no error, assume there is an installation and return error\r
+  //\r
+  if (!EFI_ERROR (Status)) {\r
+    if (HandleBuffer != NULL) {\r
+      gBS->FreePool (HandleBuffer);\r
+    }\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
+                  gPlatformDriverOverride\r
+                  );\r
+  return Status;\r
+}\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_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
+  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 = MappingDataBase->ForwardLink;\r
+  while (OverrideItemListIndex != MappingDataBase){\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 =  OverrideItem->DriverInfoList.ForwardLink;\r
+    while (ImageInfoListIndex != &OverrideItem->DriverInfoList){\r
+      //\r
+      // Free all 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 = ImageInfoListIndex->ForwardLink;\r
+      RemoveEntryList (&DriverImageInfo->Link);\r
+      FreePool (DriverImageInfo);\r
+    }\r
+    //\r
+    // Free PLATFORM_OVERRIDE_ITEM itself\r
+    //\r
+    OverrideItemListIndex =  OverrideItemListIndex->ForwardLink;\r
+    RemoveEntryList (&OverrideItem->Link);\r
+    FreePool (OverrideItem);\r
+  }\r
+\r
+  InitializeListHead (MappingDataBase);\r
+  return EFI_SUCCESS;\r
+}\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 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 multi variables to store\r
+  // large mapping infos.\r
+  // The variable(s) name rule is PlatDriOver, PlatDriOver1, PlatDriOver2, ....\r
+  //\r
+  UINT32                         NotEnd;\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;            //EFI_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                         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
+  typedef struct _PLATFORM_OVERRIDE_ITEM{\r
+  UINTN                          Signature;                  //EFI_SIGNATURE_32('p','d','o','i')\r
+  LIST_ENTRY                     Link;\r
+  UINT32                         DriverInfoNum;\r
+  EFI_DEVICE_PATH_PROTOCOL       *ControllerDevicePath;\r
+  LIST_ENTRY                     DriverInfoList;         //DRIVER_IMAGE_INFO List\r
+  } PLATFORM_OVERRIDE_ITEM;\r
+  typedef struct _DRIVER_IMAGE_INFO{\r
+  UINTN                          Signature;                  //EFI_SIGNATURE_32('p','d','i','i')\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
+  @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\r
+                                   successfully\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
+  VariableNum = 0;\r
+  Corrupted = FALSE;\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
+  VariableNum ++;\r
+  if (VariableBuffer == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  do {\r
+    VariableIndex = VariableBuffer;\r
+    NotEnd = *(UINT32*) VariableIndex;\r
+    VariableIndex = VariableIndex + sizeof (UINT32);\r
+    while (VariableIndex < ((UINT8 *)VariableBuffer + BufferSize)) {\r
+      OverrideItem = AllocateZeroPool (sizeof (PLATFORM_OVERRIDE_ITEM));\r
+      ASSERT (OverrideItem != NULL);\r
+      OverrideItem->Signature = PLATFORM_OVERRIDE_ITEM_SIGNATURE;\r
+      InitializeListHead (&OverrideItem->DriverInfoList);\r
+      //\r
+      // Check SIGNATURE\r
+      //\r
+      Signature = *(UINT32 *) VariableIndex;\r
+      VariableIndex = VariableIndex + sizeof (UINT32);\r
+      if (Signature != PLATFORM_OVERRIDE_ITEM_SIGNATURE) {\r
+        FreePool (OverrideItem);\r
+        Corrupted = TRUE;\r
+        break;\r
+      }\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 DriverDevicePath[]\r
+      //\r
+      for (Index = 0; Index < DriverNumber; Index++) {\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 has other variable(PlatDriOver1, PlatDriOver2, PlatDriOver3.....), get them.\r
+    // NotEnd indicate 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
+      VariableNum ++;\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    a list entry point to a specific\r
+                                   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
+\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
+  NeededSize += GetDevicePathSize (OverrideItem->ControllerDevicePath); // ControllerDevicePath\r
+  //\r
+  // Align the controller device path\r
+  //\r
+  NeededSize += ((sizeof(UINT32) - ((UINTN) GetDevicePathSize (OverrideItem->ControllerDevicePath))) \\r
+                  & (sizeof(UINT32) - 1));\r
+  ImageInfoListIndex =  OverrideItem->DriverInfoList.ForwardLink;\r
+  while (ImageInfoListIndex != &OverrideItem->DriverInfoList){\r
+    DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
+    NeededSize += GetDevicePathSize (DriverImageInfo->DriverImagePath); //DriverDevicePath\r
+    //\r
+    // Align the driver image device path\r
+    //\r
+    NeededSize += ((sizeof(UINT32) - ((UINTN) GetDevicePathSize (DriverImageInfo->DriverImagePath))) \\r
+                    & (sizeof(UINT32) - 1));\r
+    ImageInfoListIndex = ImageInfoListIndex->ForwardLink;\r
+  }\r
+\r
+  return NeededSize;\r
+}\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_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
+  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
+  UINTN                       SavedSize;\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 (MappingDataBase->ForwardLink == MappingDataBase) {\r
+    Status = DeleteOverridesVariables ();\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 = MappingDataBase->ForwardLink;\r
+  while (OverrideItemListIndex != MappingDataBase) {\r
+    //\r
+    // Try to find the most proper variable size which <= MaximumVariableSize, but can contain mapping info as much as possible\r
+    //\r
+    VariableNeededSize = 0;\r
+    VariableNeededSize += sizeof (UINT32); //BOOLEAN  NotEnd;\r
+    ItemIndex = OverrideItemListIndex;\r
+    NotEnd = FALSE;\r
+\r
+    while (ItemIndex != MappingDataBase){\r
+      OneItemNeededSize = GetOneItemNeededSize (ItemIndex);\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 += GetOneItemNeededSize (ItemIndex);\r
+      ItemIndex =  ItemIndex->ForwardLink;\r
+    }\r
+\r
+    if (NotEnd) {\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 ((UINTN) VariableBuffer % sizeof(UINTN) == 0);\r
+\r
+    //\r
+    // Fill the variable buffer according to MappingDataBase\r
+    //\r
+    SavedSize = 0;\r
+    VariableIndex = VariableBuffer;\r
+    *(UINT32 *) VariableIndex = NotEnd;\r
+    VariableIndex += sizeof (UINT32); // pass NoEnd\r
+    SavedSize += sizeof (UINT32);\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
+      SavedSize += sizeof (UINT32);\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
+      SavedSize += sizeof (UINT32);\r
+\r
+      CopyMem (VariableIndex, OverrideItem->ControllerDevicePath, GetDevicePathSize (OverrideItem->ControllerDevicePath));\r
+      VariableIndex += GetDevicePathSize (OverrideItem->ControllerDevicePath); // pass ControllerDevicePath\r
+      SavedSize += GetDevicePathSize (OverrideItem->ControllerDevicePath);\r
+\r
+      //\r
+      // Align the VariableIndex since the controller device path may not be aligned\r
+      //\r
+      SavedSize += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1));\r
+      VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1));\r
+\r
+      ImageInfoListIndex =  OverrideItem->DriverInfoList.ForwardLink;\r
+      while (ImageInfoListIndex != &OverrideItem->DriverInfoList){\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
+        SavedSize += GetDevicePathSize (DriverImageInfo->DriverImagePath);\r
+        //\r
+        // Align the VariableIndex since the driver image device path may not be aligned\r
+        //\r
+        SavedSize += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1));\r
+        VariableIndex += ((sizeof(UINT32) - ((UINTN) (VariableIndex))) & (sizeof(UINT32) - 1));\r
+        ImageInfoListIndex = ImageInfoListIndex->ForwardLink;\r
+      }\r
+\r
+      OverrideItemListIndex =  OverrideItemListIndex->ForwardLink;\r
+    }\r
+\r
+    ASSERT (SavedSize == 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
+/**\r
+  Retrieves the image handle of the platform override driver for a controller in the system from the memory mapping database.\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\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_PLATFORM_DRIVER_OVERRIDE_PROTOCOL              * This,\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_LOADED_IMAGE_PROTOCOL   *LoadedImage;\r
+  EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\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    *LoadedImageHandleDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL    *TatalFilePath;\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
+  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
+  OverrideItemListIndex = MappingDataBase->ForwardLink;\r
+  while (OverrideItemListIndex != MappingDataBase){\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
+            GetDevicePathSize (OverrideItem->ControllerDevicePath)\r
+            ) == 0\r
+          ) {\r
+        ControllerFound = TRUE;\r
+        break;\r
+      }\r
+\r
+    }\r
+    OverrideItemListIndex =  OverrideItemListIndex->ForwardLink;\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() maybe 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 =  OverrideItem->DriverInfoList.ForwardLink;\r
+  while (ImageInfoListIndex != &OverrideItem->DriverInfoList){\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 contain a FV node, check the Fv file device path is valid. If it is invalid, try to return the valid device path.\r
+        // FV address maybe changes for memory layout adjust from time to time, 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
+          Status = gBS->HandleProtocol (\r
+                          ImageHandleBuffer[Index],\r
+                          &gEfiLoadedImageProtocolGuid,\r
+                          (VOID **) &LoadedImage\r
+                          );\r
+          if (EFI_ERROR (Status)) {\r
+            continue;\r
+          }\r
+\r
+          //\r
+          // Get the driver image total file path\r
+          //\r
+          LoadedImageHandleDevicePath = NULL;\r
+          Status = gBS->HandleProtocol (\r
+                              LoadedImage->DeviceHandle,\r
+                              &gEfiDevicePathProtocolGuid,\r
+                              (VOID **) &LoadedImageHandleDevicePath\r
+                              );\r
+          if (EFI_ERROR (Status)) {\r
+            //\r
+            // Maybe Not all  LoadedImage->DeviceHandle has valid value.  Skip the invalid image.\r
+            //\r
+            continue;\r
+          }\r
+\r
+          TatalFilePath = AppendDevicePath (LoadedImageHandleDevicePath, LoadedImage->FilePath);\r
+\r
+          DevicePathSize = GetDevicePathSize (DriverImageInfo->DriverImagePath);\r
+          if (DevicePathSize == GetDevicePathSize (TatalFilePath)) {\r
+            if (CompareMem (\r
+                  DriverImageInfo->DriverImagePath,\r
+                  TatalFilePath,\r
+                  GetDevicePathSize (TatalFilePath)\r
+                  ) == 0\r
+                ) {\r
+              ImageFound = TRUE;\r
+              break;\r
+            }\r
+          }\r
+        }\r
+\r
+        if (ImageFound) {\r
+          Status = gBS->HandleProtocol (\r
+                          ImageHandleBuffer[Index],\r
+                          &gEfiDriverBindingProtocolGuid,\r
+                          (VOID **) &DriverBinding\r
+                          );\r
+          ASSERT (!EFI_ERROR (Status));\r
+          DriverImageInfo->ImageHandle = ImageHandleBuffer[Index];\r
+        } else {\r
+          //\r
+          // The driver image has not been loaded and started, need try to load and start it now\r
+          // Try to connect all device in the driver image path\r
+          //\r
+          Status = ConnectDevicePath (DriverImageInfo->DriverImagePath);\r
+          //\r
+          // 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\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
+              Status = gBS->HandleProtocol (\r
+                              ImageHandle,\r
+                              &gEfiDriverBindingProtocolGuid,\r
+                              (VOID **) &DriverBinding\r
+                              );\r
+              ASSERT (!EFI_ERROR (Status));\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
+                Status = gBS->HandleProtocol (\r
+                                ImageHandle,\r
+                                &gEfiDriverBindingProtocolGuid,\r
+                                (VOID **) &DriverBinding\r
+                                );\r
+                ASSERT (!EFI_ERROR (Status));\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 = ImageInfoListIndex->ForwardLink;\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 =  OverrideItem->DriverInfoList.ForwardLink;\r
+  while (ImageInfoListIndex != &OverrideItem->DriverInfoList){\r
+    DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
+    if (DriverImageInfo->ImageHandle != NULL) {\r
+      if ((*DriverImageHandle == NULL) || FoundLastReturned) {\r
+        OverrideItem->LastReturnedImageHandle = DriverImageInfo->ImageHandle;\r
+        *DriverImageHandle = DriverImageInfo->ImageHandle;\r
+        return EFI_SUCCESS;\r
+      } else if (*DriverImageHandle == DriverImageInfo->ImageHandle){\r
+        FoundLastReturned = TRUE;\r
+      }\r
+    }\r
+    ImageInfoListIndex = ImageInfoListIndex->ForwardLink;\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
+  If has, the controller's total override driver number and input DriverImage's order number is return.\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  DriverInfoNum            the controller's total override driver number\r
+  @param  DriverImageNO            The inserted order number\r
+\r
+  @return EFI_INVALID_PARAMETER\r
+  @return EFI_NOT_FOUND\r
+  @return EFI_SUCCESS\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+CheckMapping (\r
+  IN     EFI_DEVICE_PATH_PROTOCOL                       *ControllerDevicePath,\r
+  IN     EFI_DEVICE_PATH_PROTOCOL                       *DriverImageDevicePath,\r
+  IN     LIST_ENTRY                                     * MappingDataBase,\r
+  OUT    UINT32                                         *DriverInfoNum,\r
+  OUT    UINT32                                         *DriverImageNO\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
+  //\r
+  // Check that ControllerHandle is a valid handle\r
+  //\r
+  if (ControllerDevicePath == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  if (MappingDataBase == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // Search ControllerDevicePath in MappingDataBase\r
+  //\r
+  Found = FALSE;\r
+  OverrideItem = NULL;\r
+  OverrideItemListIndex = MappingDataBase->ForwardLink;\r
+  while (OverrideItemListIndex != MappingDataBase){\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
+            GetDevicePathSize (OverrideItem->ControllerDevicePath)\r
+            ) == 0\r
+          ) {\r
+        Found = TRUE;\r
+        break;\r
+      }\r
+    }\r
+    OverrideItemListIndex =  OverrideItemListIndex->ForwardLink;\r
+  }\r
+\r
+  if (!Found) {\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 == NULL) {\r
+    return EFI_SUCCESS;\r
+  }\r
+  //\r
+  // return the DriverImageHandle for ControllerHandle\r
+  //\r
+  ImageNO = 0;\r
+  Found = FALSE;\r
+  ImageInfoListIndex =  OverrideItem->DriverInfoList.ForwardLink;\r
+  while (ImageInfoListIndex != &OverrideItem->DriverInfoList){\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 = ImageInfoListIndex->ForwardLink;\r
+  }\r
+\r
+  if (!Found) {\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
+/**\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\r
+\r
+  @return EFI_INVALID_PARAMETER\r
+  @return EFI_ALREADY_STARTED\r
+  @return EFI_SUCCESS\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
+  //\r
+  // Check that ControllerHandle is a valid handle\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
+  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 = MappingDataBase->ForwardLink;\r
+  while (OverrideItemListIndex != MappingDataBase){\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
+            GetDevicePathSize (OverrideItem->ControllerDevicePath)\r
+            ) == 0\r
+          ) {\r
+        Found = TRUE;\r
+        break;\r
+      }\r
+    }\r
+    OverrideItemListIndex =  OverrideItemListIndex->ForwardLink;\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 wantted order location\r
+  //\r
+  ImageNO = 0;\r
+  Found = FALSE;\r
+  ImageInfoListIndex =  OverrideItem->DriverInfoList.ForwardLink;\r
+  while (ImageInfoListIndex != &OverrideItem->DriverInfoList){\r
+    if (ImageNO == (DriverImageNO - 1)) {\r
+      //\r
+      // find the wantted order location, insert it\r
+      //\r
+      InsertTailList (ImageInfoListIndex, &DriverImageInfo->Link);\r
+      OverrideItem->DriverInfoNum ++;\r
+      Found = TRUE;\r
+      break;\r
+    }\r
+    //DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
+    ImageNO++;\r
+    ImageInfoListIndex = ImageInfoListIndex->ForwardLink;\r
+  }\r
+\r
+  if (!Found) {\r
+    //\r
+    // if not find the wantted 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 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\r
+\r
+  @return EFI_INVALID_PARAMETER\r
+  @return EFI_NOT_FOUND\r
+  @return EFI_SUCCESS\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
+  //\r
+  // Check that ControllerHandle is a valid handle\r
+  //\r
+  if (ControllerDevicePath == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (MappingDataBase == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+   Status = CheckMapping (\r
+              ControllerDevicePath,\r
+              DriverImageDevicePath,\r
+              MappingDataBase,\r
+              NULL,\r
+              NULL\r
+              );\r
+  if (Status == EFI_NOT_FOUND) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Search ControllerDevicePath in MappingDataBase\r
+  //\r
+  Found = FALSE;\r
+  OverrideItem = NULL;\r
+  OverrideItemListIndex = MappingDataBase->ForwardLink;\r
+  while (OverrideItemListIndex != MappingDataBase){\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
+            GetDevicePathSize (OverrideItem->ControllerDevicePath)\r
+            ) == 0\r
+          ) {\r
+        Found = TRUE;\r
+        break;\r
+      }\r
+    }\r
+    OverrideItemListIndex =  OverrideItemListIndex->ForwardLink;\r
+  }\r
+\r
+  ASSERT (Found);\r
+  ASSERT (OverrideItem->DriverInfoNum != 0);\r
+  //\r
+  //\r
+  //\r
+  Found = FALSE;\r
+  ImageInfoListIndex =  OverrideItem->DriverInfoList.ForwardLink;\r
+  while (ImageInfoListIndex != &OverrideItem->DriverInfoList){\r
+    DriverImageInfo = CR(ImageInfoListIndex, DRIVER_IMAGE_INFO, Link, DRIVER_IMAGE_INFO_SIGNATURE);\r
+    ImageInfoListIndex = ImageInfoListIndex->ForwardLink;\r
+    if (DriverImageDevicePath != NULL) {\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
+      Found = TRUE;\r
+      FreePool(DriverImageInfo->DriverImagePath);\r
+      RemoveEntryList (&DriverImageInfo->Link);\r
+      OverrideItem->DriverInfoNum --;\r
+    }\r
+  }\r
+\r
+  if (DriverImageDevicePath == NULL) {\r
+    ASSERT (OverrideItem->DriverInfoNum == 0);\r
+  }\r
+\r
+  if (OverrideItem->DriverInfoNum == 0) {\r
+    FreePool(OverrideItem->ControllerDevicePath);\r
+    RemoveEntryList (&OverrideItem->Link);\r
+    FreePool (OverrideItem);\r
+  }\r
+\r
+  if (!Found) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\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
+  None\r
+\r
+  @return EFI_SUCCESS\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) {\r
+    UnicodeSPrint (OverrideVariableName, sizeof (OverrideVariableName), L"PlatDriOver%d", VariableNum);\r
+    VariableBuffer = GetVariableAndSize (OverrideVariableName, &gEfiOverrideVariableGuid, &BufferSize);\r
+    VariableNum ++;\r
+    ASSERT (VariableBuffer != NULL);\r
+  }\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
+  Push a controller device path into a globle device path list\r
+\r
+  @param  ControllerDevicePath     The controller device path need to push into\r
+                                   stack\r
+\r
+  @return EFI_SUCCESS\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  ControllerDevicePath     The controller device path retrieved from stack\r
+\r
+  @return EFI_SUCCESS\r
+  @return EFI_NOT_FOUND\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
+  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  ControllerDevicePath     The controller device path need to check\r
+\r
+  @return True\r
+  @return False\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
+  BOOLEAN                 Found;\r
+  UINTN                   DevicePathSize;\r
+\r
+  Found = FALSE;\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 (\r
+            DevicePath,\r
+            DevicePathStackItem->DevicePath,\r
+            GetDevicePathSize (DevicePathStackItem->DevicePath)\r
+            ) == 0\r
+          ) {\r
+        Found = TRUE;\r
+        break;\r
+      }\r
+    }\r
+    ItemListIndex = ItemListIndex->BackLink;\r
+  }\r
+\r
+  return Found;\r
+}\r
+\r
+\r
+/**\r
+  According to a file guild, 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 need to check\r
+                                   on output, the updated valid Fv file device path\r
+  @param  FileGuid                 the Fv file guild\r
+  @param  CallerImageHandle\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
+                                   guild at all\r
+  @retval EFI_ALREADY_STARTED      the input DevicePath has pointed to Fv file, it\r
+                                   is valid\r
+  @retval EFI_SUCCESS              has 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) || (*DevicePath == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Check whether the device path point to the default the input Fv file\r
+  //\r
+  TempDevicePath = *DevicePath;\r
+  LastDeviceNode = TempDevicePath;\r
+  while (!EfiIsDevicePathEnd (TempDevicePath)) {\r
+     LastDeviceNode = TempDevicePath;\r
+     TempDevicePath = EfiNextDevicePathNode (TempDevicePath);\r
+  }\r
+  GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode (\r
+                (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode\r
+                );\r
+  if (GuidPoint == NULL) {\r
+    //\r
+    // if this option does not points 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 contain memory map node\r
+  //\r
+  TempDevicePath = *DevicePath;\r
+  HasFVNode = FALSE;\r
+  while (!EfiIsDevicePathEnd (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 = EfiNextDevicePathNode (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
+  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
+  @return 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
+  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
+    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 fail, 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 success, 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
index dadf7a698ca2545e530ed11ac7c6d59ae74a6035..f182323a451f3e768af0c075c472ca000290ce3e 100644 (file)
@@ -2,7 +2,7 @@
 # Mde Module Package Reference Implementations\r
 #\r
 # This module provides headers and libraries that conform to EFI/PI Industry standards.\r
 # Mde Module Package Reference Implementations\r
 #\r
 # This module provides headers and libraries that conform to EFI/PI Industry standards.\r
-# Copyright (c) 2007, Intel Corporation.\r
+# Copyright (c) 2007 - 2008, Intel Corporation.\r
 #\r
 # All rights reserved.\r
 #    This program and the accompanying materials are licensed and made available under\r
 #\r
 # All rights reserved.\r
 #    This program and the accompanying materials are licensed and made available under\r
@@ -33,6 +33,7 @@
   UdpIoLib|Include/Library/UdpIoLib.h\r
   S3Lib|Include/Library/S3Lib.h\r
   RecoveryLib|Include/Library/RecoveryLib.h\r
   UdpIoLib|Include/Library/UdpIoLib.h\r
   S3Lib|Include/Library/S3Lib.h\r
   RecoveryLib|Include/Library/RecoveryLib.h\r
+  PlatDriOverLib|Include/Library/PlatDriOverLib.h\r
 \r
 [Guids.common]\r
 \r
 \r
 [Guids.common]\r
 \r
@@ -64,6 +65,7 @@
   gEfiPeiPeCoffLoaderGuid        = { 0xD8117CFF, 0x94A6, 0x11D4, { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}\r
   gEfiVariableInfoGuid           = { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}\r
   gSimpleTextInExNotifyGuid      = { 0x856f2def, 0x4e93, 0x4d6b, { 0x94, 0xce, 0x1c, 0xfe, 0x47, 0x01, 0x3e, 0xa5 }}\r
   gEfiPeiPeCoffLoaderGuid        = { 0xD8117CFF, 0x94A6, 0x11D4, { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}\r
   gEfiVariableInfoGuid           = { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}\r
   gSimpleTextInExNotifyGuid      = { 0x856f2def, 0x4e93, 0x4d6b, { 0x94, 0xce, 0x1c, 0xfe, 0x47, 0x01, 0x3e, 0xa5 }}\r
+  gEfiOverrideVariableGuid       = { 0x8e3d4ad5, 0xf762, 0x438a, { 0xa1, 0xc1, 0x5b, 0x9f, 0xe6, 0x8c, 0x6b, 0x15 }}\r
 \r
 [Protocols.common]\r
 \r
 \r
 [Protocols.common]\r
 \r
@@ -97,7 +99,7 @@
 \r
   ##gPeiFlashMapPpiGuid will be removed in future\r
   gPeiFlashMapPpiGuid            = { 0xf34c2fa0, 0xde88, 0x4270, {0x84, 0x14, 0x96, 0x12, 0x22, 0xf4, 0x52, 0x1c } }\r
 \r
   ##gPeiFlashMapPpiGuid will be removed in future\r
   gPeiFlashMapPpiGuid            = { 0xf34c2fa0, 0xde88, 0x4270, {0x84, 0x14, 0x96, 0x12, 0x22, 0xf4, 0x52, 0x1c } }\r
-  \r
+\r
   gPeiOperatorPresencePpiGuid    = { 0x20a7378c, 0xaa83, 0x4ce1, {0x82, 0x1f, 0x47, 0x40, 0xee, 0x1b, 0x3f, 0x9f } }\r
 \r
 [PcdsFeatureFlag.common]\r
   gPeiOperatorPresencePpiGuid    = { 0x20a7378c, 0xaa83, 0x4ce1, {0x82, 0x1f, 0x47, 0x40, 0xee, 0x1b, 0x3f, 0x9f } }\r
 \r
 [PcdsFeatureFlag.common]\r
index 5f53c67b2c4deee953351769c9af4050008cf503..637cdfbe80b7e85b9a80ddd641e8bc2146067667 100644 (file)
@@ -72,6 +72,7 @@
   DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf\r
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
   CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf\r
   DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf\r
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
   CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf\r
+  PlatDriOverLib|MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.inf\r
 \r
 [LibraryClasses.IA32]\r
   IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf\r
 \r
 [LibraryClasses.IA32]\r
   IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf\r
   MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf\r
   MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf\r
 \r
   MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf\r
   MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf\r
 \r
+  MdeModulePkg/Library/DxePlatDriOverLib/DxePlatDriOverLib.inf\r
+\r
   MdeModulePkg/Library/PeiS3LibNull/PeiS3LibNull.inf\r
   MdeModulePkg/Library/PeiRecoveryLibNull/PeiRecoveryLibNull.inf\r
 \r
   MdeModulePkg/Library/PeiS3LibNull/PeiS3LibNull.inf\r
   MdeModulePkg/Library/PeiRecoveryLibNull/PeiRecoveryLibNull.inf\r
 \r
   MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf\r
   MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf\r
 \r
   MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf\r
   MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf\r
 \r
+  MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf\r
+\r
   MdeModulePkg/Application/HelloWorld/HelloWorld.inf\r
 \r
   MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf\r
   MdeModulePkg/Application/HelloWorld/HelloWorld.inf\r
 \r
   MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf\r
diff --git a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverride.c b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverride.c
new file mode 100644 (file)
index 0000000..2a18913
--- /dev/null
@@ -0,0 +1,186 @@
+/** @file\r
+\r
+Copyright (c) 2007, 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
+    PlatformDriOverride.c\r
+\r
+Abstract:\r
+\r
+\r
+**/\r
+\r
+\r
+#include "PlatformDriOverride.h"\r
+\r
+EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL gPlatformDriverOverride = {\r
+  GetDriver,\r
+  GetDriverPath,\r
+  DriverLoaded\r
+};\r
+\r
+STATIC  LIST_ENTRY      mMappingDataBase = INITIALIZE_LIST_HEAD_VARIABLE (mMappingDataBase);\r
+STATIC  BOOLEAN         mEnvironmentVariableRead = FALSE;\r
+STATIC  EFI_HANDLE      mCallerImageHandle;\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PlatformDriverOverrideEntry (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+   Platform Driver Override driver entry point, install the Platform Driver Override Protocol\r
+\r
+Arguments:\r
+  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
+\r
+Returns:\r
+  EFI_STATUS\r
+\r
+--*/\r
+{\r
+  mEnvironmentVariableRead = FALSE;\r
+  mCallerImageHandle = ImageHandle;\r
+  InitializeListHead (&mMappingDataBase);\r
+  return InstallPlatformDriverOverrideProtocol (&gPlatformDriverOverride);\r
+}\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
+STATIC\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
+  // 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 (Status == EFI_NOT_FOUND) {\r
+      InitializeListHead (&mMappingDataBase);\r
+      return EFI_NOT_FOUND;\r
+    } else if (Status == EFI_VOLUME_CORRUPTED){\r
+      DEBUG ((DEBUG_ERROR, "Platform Driver Override Variable is corrupt\n"));\r
+      //\r
+      // The environment variable(s) that contain the override mappings from Controller Device Path to\r
+      //  a set of Driver Device Paths is corrupted,  platform code can use LibDeleteOverridesVariables to\r
+      //  delete all orverride variables as a policy. Here can be IBV/OEM customized.\r
+      //\r
+\r
+      //LibDeleteOverridesVariables();\r
+      InitializeListHead (&mMappingDataBase);\r
+      return EFI_NOT_FOUND;\r
+    } else if (EFI_ERROR (Status)){\r
+      InitializeListHead (&mMappingDataBase);\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  }\r
+  //\r
+  // if the environment variable does not exist or the variable appears to be corrupt, just return not found\r
+  //\r
+  if (IsListEmpty (&mMappingDataBase)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  return GetDriverFromMapping (\r
+            This,\r
+            ControllerHandle,\r
+            DriverImageHandle,\r
+            &mMappingDataBase,\r
+            mCallerImageHandle\r
+            );\r
+\r
+}\r
+\r
+\r
+/**\r
+  For the use of the ControllerHandle parameter in the GetDriverPath() and DriverLoaded() APIs\r
+  makes those APIs very difficult to use, so not support.\r
+\r
+\r
+\r
+**/\r
+STATIC\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
+  For the use of the ControllerHandle parameter in the GetDriverPath() and DriverLoaded() APIs\r
+  makes those APIs very difficult to use, so not support.\r
+\r
+\r
+\r
+**/\r
+STATIC\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
diff --git a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverride.h b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverride.h
new file mode 100644 (file)
index 0000000..5a5b276
--- /dev/null
@@ -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 <PiDxe.h>
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/PlatDriOverLib.h>
+
+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 (file)
index 0000000..dbc9f0e
--- /dev/null
@@ -0,0 +1,48 @@
+#/** @file\r
+# Component name for module PlatformDriOverride\r
+#\r
+# FIX ME!\r
+# Copyright (c) 2007, 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                      = PlatformDriOverrideDxe\r
+  FILE_GUID                      = 35034CE2-A6E5-4fb4-BABE-A0156E9B2549\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = PlatformDriverOverrideEntry\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
+  PlatformDriOverride.c\r
+  PlatformDriOverride.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  UefiDriverEntryPoint\r
+  DebugLib\r
+  PlatDriOverLib\r
+\r
diff --git a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.msa b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatformDriOverrideDxe.msa
new file mode 100644 (file)
index 0000000..6e1645a
--- /dev/null
@@ -0,0 +1,50 @@
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+  <MsaHeader>\r
+    <ModuleName>PlatformDriOverrideDxe</ModuleName>\r
+    <ModuleType>DXE_DRIVER</ModuleType>\r
+    <GuidValue>35034CE2-A6E5-4fb4-BABE-A0156E9B2549</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component name for module PlatformDriOverride</Abstract>\r
+    <Description>FIX ME!</Description>\r
+    <Copyright>Copyright (c) 2007, Intel Corporation. All rights reserved.</Copyright>\r
+    <License>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.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>PlatformDriOverrideDxe</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DebugLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>PlatformDriOverride.h</Filename>\r
+    <Filename>PlatformDriOverride.c</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>\r
+  </PackageDependencies>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <ModuleEntryPoint>PlatformDriverOverrideEntry</ModuleEntryPoint>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file