]> git.proxmox.com Git - mirror_edk2.git/commitdiff
1. Create PlatformDriverOverride in Universal directory.
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 9 Apr 2008 02:09:51 +0000 (02:09 +0000)
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 9 Apr 2008 02:09:51 +0000 (02:09 +0000)
2. Move PlatformDriOverrideDxe and PlatOverMngr to this directory.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5011 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/PlatOverMngr.c [new file with mode: 0644]
MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/PlatOverMngr.h [new file with mode: 0644]
MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/PlatOverMngr.inf [new file with mode: 0644]
MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/Vfr.vfr [new file with mode: 0644]
MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/VfrStrings.uni [new file with mode: 0644]
MdeModulePkg/Universal/PlatformDriverOverride/PlatformDriOverrideDxe/PlatformDriOverride.c [new file with mode: 0644]
MdeModulePkg/Universal/PlatformDriverOverride/PlatformDriOverrideDxe/PlatformDriOverride.h [new file with mode: 0644]
MdeModulePkg/Universal/PlatformDriverOverride/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf [new file with mode: 0644]
MdeModulePkg/Universal/PlatformDriverOverride/PlatformDriOverrideDxe/PlatformDriOverrideDxe.msa [new file with mode: 0644]

diff --git a/MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/PlatOverMngr.c b/MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/PlatOverMngr.c
new file mode 100644 (file)
index 0000000..11b3d32
--- /dev/null
@@ -0,0 +1,1424 @@
+/** @file\r
+\r
+Copyright (c) 2007 - 2008, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+  PlatOverMngr.c\r
+\r
+Abstract:\r
+\r
+  A UI driver to offer a UI interface in device manager to let user configue\r
+  platform override protocol to override the default algorithm for matching\r
+  drivers to controllers.\r
+\r
+  The main flow:\r
+  1. The UI driver dynamicly locate all controller device path.\r
+  2. The UI driver dynamicly locate all drivers which support binding protocol.\r
+  3. The UI driver export and dynamicly update two  menu to let user select the\r
+     mapping between drivers to controllers.\r
+  4. The UI driver save all the mapping info in NV variables which will be consumed\r
+     by platform override protocol driver to publish the platform override protocol.\r
+\r
+**/\r
+\r
+#include "PlatOverMngr.h"\r
+\r
+STATIC  EFI_GUID      mPlatformOverridesManagerGuid = PLAT_OVER_MNGR_GUID;\r
+\r
+STATIC  LIST_ENTRY    mMappingDataBase = INITIALIZE_LIST_HEAD_VARIABLE (mMappingDataBase);\r
+\r
+STATIC  EFI_HANDLE    *mDevicePathHandleBuffer;\r
+STATIC  EFI_HANDLE    *mDriverImageHandleBuffer;\r
+STATIC  EFI_HANDLE    mSelectedCtrDPHandle;\r
+\r
+STATIC CFG_PROTOCOL_INVOKER_CHOICE mChoice[MAX_CHOICE_NUM];\r
+\r
+STATIC UINTN         mSelectedCtrIndex;\r
+STATIC EFI_STRING_ID mControllerToken[MAX_CHOICE_NUM];\r
+\r
+STATIC UINTN                        mDriverImageHandleCount;\r
+STATIC EFI_STRING_ID                mDriverImageToken[MAX_CHOICE_NUM];\r
+STATIC EFI_STRING_ID                mDriverImageFilePathToken[MAX_CHOICE_NUM];\r
+STATIC EFI_LOADED_IMAGE_PROTOCOL    *mDriverImageProtocol[MAX_CHOICE_NUM];\r
+STATIC EFI_DEVICE_PATH_PROTOCOL     *mControllerDevicePathProtocol[MAX_CHOICE_NUM];\r
+STATIC UINTN                        mSelectedDriverImageNum;\r
+STATIC UINTN                        mLastSavedDriverImageNum;\r
+STATIC CHAR8                        mLanguage[RFC_3066_ENTRY_SIZE];\r
+STATIC UINT16                       mCurrentPage;\r
+\r
+/**\r
+  The driver Entry Point. The funciton will export a disk device class formset and\r
+  its callback function to hii database.\r
+\r
+  @param  ImageHandle    The firmware allocated handle for the EFI image.\r
+  @param  SystemTable    A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS    The entry point is executed successfully.\r
+  @retval other          Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PlatOverMngrInit (\r
+  IN EFI_HANDLE                   ImageHandle,\r
+  IN EFI_SYSTEM_TABLE             *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_HII_DATABASE_PROTOCOL   *HiiDatabase;\r
+  EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
+  EFI_CALLBACK_INFO           *CallbackInfo;\r
+  EFI_HANDLE                  DriverHandle;\r
+  EFI_FORM_BROWSER2_PROTOCOL       *FormBrowser2;\r
+\r
+  //\r
+  // There should only be one HII protocol\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiHiiDatabaseProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &HiiDatabase\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status ;\r
+  }\r
+\r
+\r
+  //\r
+  // There should only be one Form Configuration protocol\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                 &gEfiFormBrowser2ProtocolGuid,\r
+                 NULL,\r
+                 (VOID **) &FormBrowser2\r
+                 );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;;\r
+  }\r
+\r
+\r
+  CallbackInfo = AllocateZeroPool (sizeof (EFI_CALLBACK_INFO));\r
+  if (CallbackInfo == NULL) {\r
+    return EFI_BAD_BUFFER_SIZE;\r
+  }\r
+\r
+  CallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;\r
+  CallbackInfo->ConfigAccess.ExtractConfig = PlatOverMngrExtractConfig;\r
+  CallbackInfo->ConfigAccess.RouteConfig   = PlatOverMngrRouteConfig;\r
+  CallbackInfo->ConfigAccess.Callback      = PlatOverMngrCallback;\r
+\r
+  //\r
+  // Create driver handle used by HII database\r
+  //\r
+  Status = HiiLibCreateHiiDriverHandle (&DriverHandle);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  CallbackInfo->DriverHandle = DriverHandle;\r
+\r
+  //\r
+  // Install Config Access protocol to driver handle\r
+  //\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &DriverHandle,\r
+                  &gEfiHiiConfigAccessProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  &CallbackInfo->ConfigAccess\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Publish our HII data\r
+  //\r
+  PackageList = HiiLibPreparePackageList (\r
+                  2,\r
+                  &mPlatformOverridesManagerGuid,\r
+                  VfrBin,\r
+                  PlatOverMngrStrings\r
+                  );\r
+  ASSERT (PackageList != NULL);\r
+\r
+  Status = HiiDatabase->NewPackageList (\r
+                           HiiDatabase,\r
+                           PackageList,\r
+                           DriverHandle,\r
+                           &CallbackInfo->RegisteredHandle\r
+                           );\r
+  gBS->FreePool (PackageList);\r
+\r
+  //\r
+  // Locate ConfigRouting protocol\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiHiiConfigRoutingProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &CallbackInfo->HiiConfigRouting\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Clear all the globle variable\r
+  //\r
+  mDriverImageHandleCount = 0;\r
+  mCurrentPage = 0;\r
+  ZeroMem (mDriverImageToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
+  ZeroMem (mDriverImageFilePathToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
+  ZeroMem (mControllerToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
+  ZeroMem (mDriverImageProtocol, MAX_CHOICE_NUM * sizeof (EFI_LOADED_IMAGE_PROTOCOL *));\r
+\r
+  //\r
+  // Show the page\r
+  //\r
+  Status = FormBrowser2->SendForm (\r
+                           FormBrowser2,\r
+                           &CallbackInfo->RegisteredHandle,\r
+                           1,\r
+                           NULL,\r
+                           0,\r
+                           NULL,\r
+                           NULL\r
+                           );\r
+\r
+  Status = HiiDatabase->RemovePackageList (HiiDatabase, CallbackInfo->RegisteredHandle);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Do some convertion for the ComponentName2 supported language. It do\r
+  the convertion just for english language code currently.\r
+\r
+  @param ComponentName    Pointer to the ComponentName2 protocl pointer.\r
+  @param Language         The language string.\r
+\r
+  @return   Return the duplication of Language if it is not english otherwise return\r
+            the supported english language code.\r
+\r
+**/\r
+CHAR8 *\r
+ConvertComponentName2SupportLanguage (\r
+  IN EFI_COMPONENT_NAME2_PROTOCOL    *ComponentName,\r
+  IN CHAR8                           *Language\r
+  )\r
+{\r
+  CHAR8                              *SupportedLanguages;\r
+  CHAR8                              *LangCode;\r
+  UINTN                              Index;\r
+\r
+  LangCode           = NULL;\r
+  SupportedLanguages = NULL;\r
+\r
+  //\r
+  // treat all the english language code (en-xx or eng) equally\r
+  //\r
+  if ((AsciiStrnCmp (Language, "en-", 3) == 0) || (AsciiStrCmp (Language, "eng") == 0)) {\r
+    SupportedLanguages = AsciiStrStr (ComponentName->SupportedLanguages, "en");\r
+    if (SupportedLanguages == NULL) {\r
+      SupportedLanguages = AsciiStrStr (ComponentName->SupportedLanguages, "eng");\r
+    }\r
+  }\r
+\r
+  //\r
+  // duplicate the Language if it is not english\r
+  //\r
+  if (SupportedLanguages == NULL) {\r
+    SupportedLanguages = Language;\r
+  }\r
+\r
+  //\r
+  // duplicate the returned language code.\r
+  //\r
+  if (AsciiStrStr (SupportedLanguages, "-") != NULL) {\r
+    LangCode = AllocateZeroPool(32);\r
+    for(Index = 0; (Index < 31) && (SupportedLanguages[Index] != '\0') && (SupportedLanguages[Index] != ';'); Index++) {\r
+      LangCode[Index] = SupportedLanguages[Index];\r
+    }\r
+    LangCode[Index] = '\0';\r
+  } else {\r
+    LangCode = AllocateZeroPool(4);\r
+    for(Index = 0; (Index < 3) && (SupportedLanguages[Index] != '\0'); Index++) {\r
+      LangCode[Index] = SupportedLanguages[Index];\r
+    }\r
+    LangCode[Index] = '\0';\r
+  }\r
+  return LangCode;\r
+}\r
+\r
+/**\r
+  Get the ComponentName or ComponentName2 protocol according to the driver binding handle\r
+\r
+  @param DriverBindingHandle  The Handle of DriverBinding.\r
+\r
+  @retval !NULL               Pointer into the image name if the image name is found,\r
+  @retval NULL                Pointer to NULL if the image name is not found.\r
+\r
+**/\r
+CHAR16 *\r
+GetComponentName (\r
+  IN EFI_HANDLE                      DriverBindingHandle\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  EFI_COMPONENT_NAME_PROTOCOL  *ComponentName;\r
+  EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2;\r
+  CHAR8                        *SupportedLanguage;\r
+  CHAR16                       *DriverName;\r
+\r
+  ComponentName  = NULL;\r
+  ComponentName2 = NULL;\r
+  Status = gBS->OpenProtocol (\r
+                 DriverBindingHandle,\r
+                 &gEfiComponentName2ProtocolGuid,\r
+                 (VOID **) &ComponentName2,\r
+                 NULL,\r
+                 NULL,\r
+                 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                 );\r
+  if (EFI_ERROR(Status)) {\r
+    Status = gBS->OpenProtocol (\r
+                   DriverBindingHandle,\r
+                   &gEfiComponentNameProtocolGuid,\r
+                   (VOID **) &ComponentName,\r
+                   NULL,\r
+                   NULL,\r
+                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                   );\r
+  }\r
+\r
+  Status     = EFI_SUCCESS;\r
+  DriverName = NULL;\r
+  if (ComponentName != NULL) {\r
+    if (ComponentName->GetDriverName != NULL) {\r
+      Status = ComponentName->GetDriverName (\r
+                                ComponentName,\r
+                                mLanguage,\r
+                                &DriverName\r
+                                );\r
+    }\r
+  } else if (ComponentName2 != NULL) {\r
+    if (ComponentName2->GetDriverName != NULL) {\r
+      SupportedLanguage = ConvertComponentName2SupportLanguage (ComponentName2, mLanguage);\r
+      Status = ComponentName2->GetDriverName (\r
+                                 ComponentName2,\r
+                                 SupportedLanguage,\r
+                                 &DriverName\r
+                                 );\r
+        gBS->FreePool (SupportedLanguage);\r
+    }\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    return NULL;\r
+  }\r
+\r
+  return DriverName;\r
+}\r
+\r
+/**\r
+  Get the image name\r
+\r
+  @param Image            Image to search.\r
+\r
+  @retval !NULL           Pointer into the image name if the image name is found,\r
+  @retval NULL            Pointer to NULL if the image name is not found.\r
+\r
+**/\r
+CHAR16 *\r
+GetImageName (\r
+  EFI_LOADED_IMAGE_PROTOCOL *Image\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_DEVICE_PATH_PROTOCOL          *DevPath;\r
+  EFI_DEVICE_PATH_PROTOCOL          *DevPathNode;\r
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;\r
+  VOID                              *Buffer;\r
+  UINTN                             BufferSize;\r
+  UINT32                            AuthenticationStatus;\r
+  EFI_GUID                          *NameGuid;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL     *FV2;\r
+\r
+  FV2         = NULL;\r
+  Buffer      = NULL;\r
+  BufferSize  = 0;\r
+\r
+  if (Image->FilePath == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  DevPath     = UnpackDevicePath (Image->FilePath);\r
+\r
+  if (DevPath == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  DevPathNode = DevPath;\r
+\r
+  while (!IsDevicePathEnd (DevPathNode)) {\r
+    //\r
+    // Find the Fv File path\r
+    //\r
+    NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)DevPathNode);\r
+    if (NameGuid != NULL) {\r
+      FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevPathNode;\r
+      Status = gBS->HandleProtocol (\r
+                    Image->DeviceHandle,\r
+                    &gEfiFirmwareVolume2ProtocolGuid,\r
+                    (VOID **) &FV2\r
+                    );\r
+      if (!EFI_ERROR (Status)) {\r
+        Status = FV2->ReadSection (\r
+                        FV2,\r
+                        &FvFilePath->FvFileName,\r
+                        EFI_SECTION_USER_INTERFACE,\r
+                        0,\r
+                        &Buffer,\r
+                        &BufferSize,\r
+                        &AuthenticationStatus\r
+                        );\r
+        if (!EFI_ERROR (Status)) {\r
+          break;\r
+        }\r
+        Buffer = NULL;\r
+      }\r
+    }\r
+    //\r
+    // Next device path node\r
+    //\r
+    DevPathNode = NextDevicePathNode (DevPathNode);\r
+  }\r
+\r
+    gBS->FreePool (DevPath);\r
+  return Buffer;\r
+}\r
+\r
+/**\r
+  Prepare the first page to let user select the device controller which need to\r
+  add mapping drivers.\r
+\r
+  @param  Private        Pointer to EFI_CALLBACK_INFO.\r
+  @param  KeyValue       The callback key value of device controller item in first page.\r
+  @param  FakeNvData     Pointer to PLAT_OVER_MNGR_DATA.\r
+\r
+  @retval EFI_SUCCESS    Always returned.\r
+\r
+**/\r
+EFI_STATUS\r
+UpdateDeviceSelectPage (\r
+  IN EFI_CALLBACK_INFO                *Private,\r
+  IN UINT16                           KeyValue,\r
+  IN PLAT_OVER_MNGR_DATA              *FakeNvData\r
+  )\r
+{\r
+  EFI_HII_UPDATE_DATA                       UpdateData;\r
+  EFI_STATUS                                Status;\r
+  UINTN                                     LangSize;\r
+  UINTN                                     Index;\r
+  UINTN                                     DevicePathHandleCount;\r
+  CHAR16                                    *NewString;\r
+  EFI_STRING_ID                             NewStringToken;\r
+  CHAR16                                    *ControllerName;\r
+  EFI_DEVICE_PATH_PROTOCOL                  *ControllerDevicePath;\r
+  EFI_PCI_IO_PROTOCOL                       *PciIo;\r
+  EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;\r
+  UINTN                                     Len;\r
+\r
+  mCurrentPage = FORM_ID_DEVICE;\r
+  //\r
+  // Following code will be run if user select 'Refresh' in first page\r
+  // During first page, user will see all currnet controller device path in system,\r
+  // select any device path will go to second page to select its overrides drivers\r
+  //\r
+\r
+  LangSize = RFC_3066_ENTRY_SIZE;\r
+  Status = gRT->GetVariable (\r
+              L"PlatformLang",\r
+              &gEfiGlobalVariableGuid,\r
+              NULL,\r
+              &LangSize,\r
+              mLanguage\r
+              );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Initial the mapping database in memory\r
+  //\r
+  FreeMappingDatabase (&mMappingDataBase);\r
+  Status = InitOverridesMapping (&mMappingDataBase);\r
+\r
+  //\r
+  // Clear all the content in the first page\r
+  //\r
+  UpdateData.BufferSize = UPDATE_DATA_SIZE;\r
+  UpdateData.Offset = 0;\r
+  UpdateData.Data = AllocateZeroPool (UPDATE_DATA_SIZE);\r
+  ASSERT (UpdateData.Data != NULL);\r
+  //\r
+  // Clear first page form\r
+  //\r
+  IfrLibUpdateForm (\r
+    Private->RegisteredHandle,\r
+    &mPlatformOverridesManagerGuid,\r
+    FORM_ID_DEVICE,\r
+    FORM_ID_DEVICE,\r
+    FALSE,\r
+    &UpdateData\r
+    );\r
+\r
+  //\r
+  // When user enter the page at first time, the 'first refresh' string is given to notify user to refresh all the drivers,\r
+  // then the 'first refresh' string will be replaced by the 'refresh' string, and the two strings content are  same after the replacement\r
+  //\r
+  NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH);\r
+  HiiLibGetStringFromHandle (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH), &NewString);\r
+  ASSERT (NewString != NULL);\r
+  Status = HiiLibSetString (Private->RegisteredHandle, NewStringToken, NewString);\r
+  ASSERT_EFI_ERROR (Status);\r
+  gBS->FreePool (NewString);\r
+\r
+  NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH_HELP);\r
+  HiiLibGetStringFromHandle (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH_HELP), &NewString);\r
+  ASSERT (NewString != NULL);\r
+  Status = HiiLibSetString (Private->RegisteredHandle, NewStringToken, NewString);\r
+  ASSERT_EFI_ERROR (Status);\r
+  gBS->FreePool (NewString);\r
+  //\r
+  // created needed controller device item in first page\r
+  //\r
+  DevicePathHandleCount  = 0;\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  NULL,\r
+                  &DevicePathHandleCount,\r
+                  &mDevicePathHandleBuffer\r
+                  );\r
+  if (EFI_ERROR (Status) || (DevicePathHandleCount == 0)) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  for (Index = 0; Index < DevicePathHandleCount; Index++) {\r
+    if (FakeNvData->PciDeviceFilter == 0x01) {\r
+      //\r
+      // Only care PCI device which contain efi driver in its option rom.\r
+      //\r
+\r
+      //\r
+      // Check whether it is a pci device\r
+      //\r
+      ControllerDevicePath = NULL;\r
+      Status = gBS->OpenProtocol (\r
+                      mDevicePathHandleBuffer[Index],\r
+                      &gEfiPciIoProtocolGuid,\r
+                      (VOID **) &PciIo,\r
+                      NULL,\r
+                      NULL,\r
+                      EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        continue;\r
+      }\r
+      //\r
+      // Check whether it contain efi driver in its option rom\r
+      //\r
+      Status = gBS->HandleProtocol(\r
+                       mDevicePathHandleBuffer[Index],\r
+                       &gEfiBusSpecificDriverOverrideProtocolGuid,\r
+                       (VOID **) &BusSpecificDriverOverride\r
+                       );\r
+      if (EFI_ERROR (Status) || BusSpecificDriverOverride == NULL) {\r
+        continue;\r
+      }\r
+    }\r
+\r
+    ControllerDevicePath = NULL;\r
+    Status = gBS->OpenProtocol (\r
+                    mDevicePathHandleBuffer[Index],\r
+                    &gEfiDevicePathProtocolGuid,\r
+                    (VOID **) &ControllerDevicePath,\r
+                    NULL,\r
+                    NULL,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+    ASSERT_EFI_ERROR (Status);\r
+    //\r
+    // Save the device path protocol interface\r
+    //\r
+    mControllerDevicePathProtocol[Index] = ControllerDevicePath;\r
+\r
+    //\r
+    // Get the driver name\r
+    //\r
+    ControllerName = DevicePathToStr (ControllerDevicePath);\r
+\r
+    //\r
+    // Export the driver name string and create item in set options page\r
+    //\r
+    Len = StrSize (ControllerName);\r
+    NewString = AllocateZeroPool (Len + StrSize (L"--"));\r
+    if (EFI_ERROR (CheckMapping (ControllerDevicePath,NULL, &mMappingDataBase, NULL, NULL))) {\r
+      StrCat (NewString, L"--");\r
+    } else {\r
+      StrCat (NewString, L"**");\r
+    }\r
+    StrCat (NewString, ControllerName);\r
+\r
+    NewStringToken = mControllerToken[Index];\r
+    if (NewStringToken == 0) {\r
+      Status = HiiLibNewString (Private->RegisteredHandle, &NewStringToken, NewString);\r
+    } else {\r
+      Status = HiiLibSetString (Private->RegisteredHandle, NewStringToken, NewString);\r
+    }\r
+    ASSERT_EFI_ERROR (Status);\r
+    gBS->FreePool (NewString);\r
+    //\r
+    // Save the device path string toke for next access use\r
+    //\r
+    mControllerToken[Index] = NewStringToken;\r
+\r
+    CreateGotoOpCode (\r
+      FORM_ID_DRIVER,\r
+      NewStringToken,\r
+      STRING_TOKEN (STR_GOTO_HELP_DRIVER),\r
+      EFI_IFR_FLAG_CALLBACK,\r
+      (UINT16) (Index + KEY_VALUE_DEVICE_OFFSET),\r
+      &UpdateData\r
+      );\r
+  }\r
+\r
+  //\r
+  // Update first page form\r
+  //\r
+  IfrLibUpdateForm (\r
+    Private->RegisteredHandle,\r
+    &mPlatformOverridesManagerGuid,\r
+    FORM_ID_DEVICE,\r
+    FORM_ID_DEVICE,\r
+    FALSE,\r
+    &UpdateData\r
+    );\r
+\r
+  gBS->FreePool (UpdateData.Data);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Prepare to let user select the drivers which need mapping with the device controller\r
+  selected in first page.\r
+\r
+  @param  Private        Pointer to EFI_CALLBACK_INFO.\r
+  @param  KeyValue       The callback key value of device controller item in first page.\r
+  @param  FakeNvData     Pointer to PLAT_OVER_MNGR_DATA.\r
+\r
+  @retval EFI_SUCCESS    Always returned.\r
+\r
+**/\r
+EFI_STATUS\r
+UpdateBindingDriverSelectPage (\r
+  IN EFI_CALLBACK_INFO                *Private,\r
+  IN UINT16                           KeyValue,\r
+  IN PLAT_OVER_MNGR_DATA              *FakeNvData\r
+  )\r
+{\r
+  EFI_HII_UPDATE_DATA                       UpdateData;\r
+  EFI_STATUS                                Status;\r
+  UINTN                                     Index;\r
+\r
+  CHAR16                                    *NewString;\r
+  EFI_STRING_ID                             NewStringToken;\r
+  EFI_STRING_ID                             NewStringHelpToken;\r
+  UINTN                                     DriverImageHandleCount;\r
+\r
+  EFI_DRIVER_BINDING_PROTOCOL               *DriverBindingInterface;\r
+  EFI_LOADED_IMAGE_PROTOCOL                 *LoadedImage;\r
+  CHAR16                                    *DriverName;\r
+  BOOLEAN                                   FreeDriverName;\r
+\r
+  EFI_DEVICE_PATH_PROTOCOL                  *LoadedImageDevicePath;\r
+  EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;\r
+  EFI_HANDLE                                DriverBindingHandle;\r
+  //\r
+  // If user select a controller item in the first page  the following code will be run.\r
+  // During second page, user will see all currnet driver bind protocol driver, the driver name and its device path will be shown\r
+  //\r
+  //First acquire the list of Loaded Image Protocols, and then when  want the name of the driver, look up all the Driver Binding Protocols\r
+  // and find the first one whose ImageHandle field matches the image handle of the Loaded Image Protocol.\r
+  // then use the Component Name Protocol on the same handle as the first matching Driver Binding Protocol to look up the name of the driver.\r
+  //\r
+\r
+  mCurrentPage = FORM_ID_DRIVER;\r
+  //\r
+  // Switch the item callback key value to its NO. in mDevicePathHandleBuffer\r
+  //\r
+  mSelectedCtrIndex = KeyValue - 0x100;\r
+  ASSERT (mSelectedCtrIndex < MAX_CHOICE_NUM);\r
+  mLastSavedDriverImageNum = 0;\r
+  //\r
+  // Clear all the content in dynamic page\r
+  //\r
+  UpdateData.BufferSize = UPDATE_DATA_SIZE;\r
+  UpdateData.Offset = 0;\r
+  UpdateData.Data = AllocateZeroPool (UPDATE_DATA_SIZE);\r
+  ASSERT (UpdateData.Data != NULL);\r
+  //\r
+  // Clear second page form\r
+  //\r
+  IfrLibUpdateForm (\r
+    Private->RegisteredHandle,\r
+    &mPlatformOverridesManagerGuid,\r
+    FORM_ID_DRIVER,\r
+    FORM_ID_DRIVER,\r
+    FALSE,\r
+    &UpdateData\r
+    );\r
+\r
+  //\r
+  // Show all driver which support loaded image protocol in second page\r
+  //\r
+  DriverImageHandleCount  = 0;\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiLoadedImageProtocolGuid,\r
+                  NULL,\r
+                  &DriverImageHandleCount,\r
+                  &mDriverImageHandleBuffer\r
+                  );\r
+  if (EFI_ERROR (Status) || (DriverImageHandleCount == 0)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  mDriverImageHandleCount = DriverImageHandleCount;\r
+  for (Index = 0; Index < DriverImageHandleCount; Index++) {\r
+    //\r
+    // Step1: Get the driver image total file path for help string and the driver name.\r
+    //\r
+\r
+    //\r
+    // Find driver's Loaded Image protocol\r
+    //\r
+    LoadedImage =NULL;\r
+\r
+    Status = gBS->OpenProtocol (\r
+                    mDriverImageHandleBuffer[Index],\r
+                    &gEfiLoadedImageProtocolGuid,\r
+                    (VOID **) &LoadedImage,\r
+                    NULL,\r
+                    NULL,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      FakeNvData->DriSelection[Index] = 0x00;\r
+      continue;\r
+    }\r
+    mDriverImageProtocol[Index] = LoadedImage;\r
+    //\r
+    // Find its related driver binding protocol\r
+    //\r
+    DriverBindingInterface = NULL;\r
+    DriverBindingHandle = NULL;\r
+    DriverBindingInterface = GetBindingProtocolFromImageHandle (\r
+                                mDriverImageHandleBuffer[Index],\r
+                                &DriverBindingHandle\r
+                                );\r
+    if (DriverBindingInterface == NULL) {\r
+      FakeNvData->DriSelection[Index] = 0x00;\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Get the EFI Loaded Image Device Path Protocol\r
+    //\r
+    LoadedImageDevicePath = NULL;\r
+    Status = gBS->HandleProtocol (\r
+                        mDriverImageHandleBuffer[Index],\r
+                        &gEfiLoadedImageDevicePathProtocolGuid,\r
+                        (VOID **) &LoadedImageDevicePath\r
+                        );\r
+    if (LoadedImageDevicePath == NULL) {\r
+      FakeNvData->DriSelection[Index] = 0x00;\r
+      continue;\r
+    }\r
+\r
+    if (FakeNvData->PciDeviceFilter == 0x01) {\r
+      //\r
+      // only care the driver which is in a Pci device option rom,\r
+      // and the driver's LoadedImage->DeviceHandle must point to a pci device which has efi option rom\r
+      //\r
+      if (!EFI_ERROR (Status)) {\r
+        Status = gBS->HandleProtocol(\r
+                         LoadedImage->DeviceHandle,\r
+                         &gEfiBusSpecificDriverOverrideProtocolGuid,\r
+                         (VOID **) &BusSpecificDriverOverride\r
+                         );\r
+        if (EFI_ERROR (Status) || BusSpecificDriverOverride == NULL) {\r
+          FakeNvData->DriSelection[Index] = 0x00;\r
+          continue;\r
+        }\r
+      } else {\r
+        FakeNvData->DriSelection[Index] = 0x00;\r
+        continue;\r
+      }\r
+    }\r
+\r
+    //\r
+    // For driver name, try to get its component name, if fail, get its image name,\r
+    // if also fail, give a default name.\r
+    //\r
+    FreeDriverName = FALSE;\r
+    DriverName = GetComponentName (DriverBindingHandle);\r
+    if (DriverName == NULL) {\r
+      //\r
+      // get its image name\r
+      //\r
+      DriverName = GetImageName (LoadedImage);\r
+    }\r
+    if (DriverName == NULL) {\r
+      //\r
+      // give a default name\r
+      //\r
+      HiiLibGetStringFromHandle (Private->RegisteredHandle, STRING_TOKEN (STR_DRIVER_DEFAULT_NAME), &DriverName);\r
+      ASSERT (DriverName != NULL);\r
+      FreeDriverName = TRUE;  // the DriverName string need to free pool\r
+    }\r
+\r
+\r
+    //\r
+    // Step2 Export the driver name string and create check box item in second page\r
+    //\r
+\r
+    //\r
+    // First create the driver image name\r
+    //\r
+    NewString = AllocateZeroPool (StrSize (DriverName));\r
+    if (EFI_ERROR (CheckMapping (mControllerDevicePathProtocol[mSelectedCtrIndex], LoadedImageDevicePath, &mMappingDataBase, NULL, NULL))) {\r
+      FakeNvData->DriSelection[Index] = 0x00;\r
+    } else {\r
+      FakeNvData->DriSelection[Index] = 0x01;\r
+      mLastSavedDriverImageNum++;\r
+    }\r
+    StrCat (NewString, DriverName);\r
+    NewStringToken = mDriverImageToken[Index];\r
+    if (NewStringToken == 0) {\r
+      Status = HiiLibNewString (Private->RegisteredHandle, &NewStringToken, NewString);\r
+    } else {\r
+      Status = HiiLibSetString (Private->RegisteredHandle, NewStringToken, NewString);\r
+    }\r
+    mDriverImageToken[Index] = NewStringToken;\r
+    ASSERT_EFI_ERROR (Status);\r
+    gBS->FreePool (NewString);\r
+    if (FreeDriverName) {\r
+      gBS->FreePool (DriverName);\r
+    }\r
+\r
+    //\r
+    // Second create the driver image device path as item help string\r
+    //\r
+    DriverName = DevicePathToStr (LoadedImageDevicePath);\r
+\r
+    NewString = AllocateZeroPool (StrSize (DriverName));\r
+    StrCat (NewString, DriverName);\r
+    NewStringHelpToken = mDriverImageFilePathToken[Index];\r
+    if (NewStringHelpToken == 0) {\r
+      Status = HiiLibNewString (Private->RegisteredHandle, &NewStringHelpToken, NewString);\r
+    } else {\r
+      Status = HiiLibSetString (Private->RegisteredHandle, NewStringHelpToken, NewString);\r
+    }\r
+    mDriverImageFilePathToken[Index] = NewStringHelpToken;\r
+    ASSERT_EFI_ERROR (Status);\r
+    gBS->FreePool (NewString);\r
+    gBS->FreePool (DriverName);\r
+\r
+    CreateCheckBoxOpCode (\r
+      (UINT16) (DRIVER_SELECTION_QUESTION_ID + Index),\r
+      VARSTORE_ID_PLAT_OVER_MNGR,\r
+      (UINT16) (DRIVER_SELECTION_VAR_OFFSET + Index),\r
+      NewStringToken,\r
+      NewStringHelpToken,\r
+      0,\r
+      0,\r
+      &UpdateData\r
+      );\r
+  }\r
+\r
+  //\r
+  // Update second page form\r
+  //\r
+  IfrLibUpdateForm (\r
+    Private->RegisteredHandle,\r
+    &mPlatformOverridesManagerGuid,\r
+    FORM_ID_DRIVER,\r
+    FORM_ID_DRIVER,\r
+    FALSE,\r
+    &UpdateData\r
+    );\r
+\r
+  gBS->FreePool (UpdateData.Data);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Prepare to let user select the priority order of the drivers which are\r
+  selected in second page.\r
+\r
+  @param  Private        Pointer to EFI_CALLBACK_INFO.\r
+  @param  KeyValue       The callback key value of device controller item in first page.\r
+  @param  FakeNvData     Pointer to PLAT_OVER_MNGR_DATA.\r
+\r
+  @retval EFI_SUCCESS    Always returned.\r
+\r
+**/\r
+EFI_STATUS\r
+UpdatePrioritySelectPage (\r
+  IN EFI_CALLBACK_INFO                *Private,\r
+  IN UINT16                           KeyValue,\r
+  IN PLAT_OVER_MNGR_DATA              *FakeNvData\r
+  )\r
+{\r
+  EFI_HII_UPDATE_DATA                       UpdateData;\r
+  UINTN                                     Index;\r
+\r
+  EFI_DEVICE_PATH_PROTOCOL                  *LoadedImageDevicePath;\r
+\r
+  IFR_OPTION                                *IfrOptionList;\r
+  UINTN                                     SelectedDriverImageNum;\r
+  UINT32                                    DriverImageNO;\r
+  UINTN                                     MinNO;\r
+  UINTN                                     Index1;\r
+  UINTN                                     TempNO[100];\r
+\r
+  //\r
+  // Following code will be run if user select 'order ... priority' item in second page\r
+  // Prepare third page.  In third page, user will order the  drivers priority which are selected in second page\r
+  //\r
+  mCurrentPage = FORM_ID_ORDER;\r
+\r
+  UpdateData.BufferSize = UPDATE_DATA_SIZE;\r
+  UpdateData.Offset = 0;\r
+  UpdateData.Data = AllocateZeroPool (UPDATE_DATA_SIZE);\r
+  ASSERT (UpdateData.Data != NULL);\r
+  //\r
+  // Clear third page form\r
+  //\r
+  IfrLibUpdateForm (\r
+    Private->RegisteredHandle,\r
+    &mPlatformOverridesManagerGuid,\r
+    FORM_ID_ORDER,\r
+    FORM_ID_ORDER,\r
+    FALSE,\r
+    &UpdateData\r
+    );\r
+\r
+  //\r
+  // Check how many drivers have been selected\r
+  //\r
+  SelectedDriverImageNum = 0;\r
+  for (Index = 0; Index < mDriverImageHandleCount; Index++) {\r
+    if (FakeNvData->DriSelection[Index] != 0) {\r
+      SelectedDriverImageNum ++;\r
+    }\r
+  }\r
+\r
+  mSelectedDriverImageNum = SelectedDriverImageNum;\r
+  if (SelectedDriverImageNum == 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  IfrOptionList = AllocateZeroPool (0x200);\r
+  ASSERT_EFI_ERROR (IfrOptionList != NULL);\r
+  //\r
+  // Create order list for those selected drivers\r
+  //\r
+  SelectedDriverImageNum = 0;\r
+  for (Index = 0; Index < mDriverImageHandleCount; Index++) {\r
+    if (FakeNvData->DriSelection[Index] != 0) {\r
+      IfrOptionList[SelectedDriverImageNum].StringToken = mDriverImageToken[Index];\r
+      //\r
+      // Use the NO. in driver binding buffer as value, will use it later\r
+      //\r
+      IfrOptionList[SelectedDriverImageNum].Value.u8 = (UINT8) (Index + 1);\r
+      IfrOptionList[SelectedDriverImageNum].Flags = 0;\r
+\r
+      //\r
+      // Get the EFI Loaded Image Device Path Protocol\r
+      //\r
+      LoadedImageDevicePath = NULL;\r
+      gBS->HandleProtocol (\r
+                 mDriverImageHandleBuffer[Index],\r
+                 &gEfiLoadedImageDevicePathProtocolGuid,\r
+                 (VOID **) &LoadedImageDevicePath\r
+                 );\r
+      ASSERT (LoadedImageDevicePath != NULL);\r
+\r
+      //\r
+      // Check the driver DriverImage's order number in mapping database\r
+      //\r
+      DriverImageNO = 0;\r
+      CheckMapping (\r
+              mControllerDevicePathProtocol[mSelectedCtrIndex],\r
+              LoadedImageDevicePath,\r
+              &mMappingDataBase,\r
+              NULL,\r
+              &DriverImageNO\r
+              );\r
+      if (DriverImageNO == 0) {\r
+        DriverImageNO = (UINT32) mLastSavedDriverImageNum + 1;\r
+        mLastSavedDriverImageNum++;\r
+      }\r
+      TempNO[SelectedDriverImageNum] = DriverImageNO;\r
+      SelectedDriverImageNum ++;\r
+    }\r
+  }\r
+\r
+  ASSERT (SelectedDriverImageNum == mSelectedDriverImageNum);\r
+  //\r
+  // NvRamMap Must be clear firstly\r
+  //\r
+  ZeroMem (FakeNvData->DriOrder, 100);\r
+\r
+  //\r
+  // Order the selected drivers according to the info already in mapping database\r
+  // the less order number in mapping database the less order number in NvRamMap\r
+  //\r
+  for (Index=0; Index < SelectedDriverImageNum; Index++) {\r
+    //\r
+    // Find the minimal order number in TempNO array,  its index in TempNO is same as IfrOptionList array\r
+    //\r
+    MinNO = 0;\r
+    for (Index1=0; Index1 < SelectedDriverImageNum; Index1++) {\r
+      if (TempNO[Index1] < TempNO[MinNO]) {\r
+        MinNO = Index1;\r
+      }\r
+    }\r
+    //\r
+    // the IfrOptionList[MinNO].Value = the driver NO. in driver binding buffer\r
+    //\r
+    FakeNvData->DriOrder[Index] =IfrOptionList[MinNO].Value.u8;\r
+    TempNO[MinNO] = 101;\r
+  }\r
+\r
+  CreateOrderedListOpCode (\r
+    (UINT16) DRIVER_ORDER_QUESTION_ID,\r
+    VARSTORE_ID_PLAT_OVER_MNGR,\r
+    (UINT16) DRIVER_ORDER_VAR_OFFSET,\r
+    mControllerToken[mSelectedCtrIndex],\r
+    mControllerToken[mSelectedCtrIndex],\r
+    EFI_IFR_FLAG_RESET_REQUIRED,\r
+    0,\r
+    EFI_IFR_NUMERIC_SIZE_1,\r
+    100,\r
+    IfrOptionList,\r
+    SelectedDriverImageNum,\r
+    &UpdateData\r
+    );\r
+\r
+  //\r
+  // Update third page form\r
+  //\r
+  IfrLibUpdateForm (\r
+    Private->RegisteredHandle,\r
+    &mPlatformOverridesManagerGuid,\r
+    FORM_ID_ORDER,\r
+    FORM_ID_ORDER,\r
+    FALSE,\r
+    &UpdateData\r
+    );\r
+\r
+  gBS->FreePool (IfrOptionList);\r
+  gBS->FreePool (UpdateData.Data);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Save the save the mapping database to NV variable.\r
+\r
+  @param  Private        Pointer to EFI_CALLBACK_INFO.\r
+  @param  KeyValue       The callback key value of device controller item in first page.\r
+  @param  FakeNvData     Pointer to PLAT_OVER_MNGR_DATA.\r
+\r
+  @retval EFI_SUCCESS    Always returned.\r
+\r
+**/\r
+EFI_STATUS\r
+CommintChanges (\r
+  IN EFI_CALLBACK_INFO                *Private,\r
+  IN UINT16                           KeyValue,\r
+  IN PLAT_OVER_MNGR_DATA              *FakeNvData\r
+  )\r
+{\r
+  EFI_STATUS                                Status;\r
+  UINTN                                     Index;\r
+  UINTN                                     SelectedDriverImageNum;\r
+  EFI_DEVICE_PATH_PROTOCOL                  *LoadedImageDevicePath;\r
+  //\r
+  //  Following code will be run if user select 'commint changes' in third page\r
+  //  user enter 'Commit Changes' to save the mapping database\r
+  //\r
+  DeleteDriverImage (mControllerDevicePathProtocol[mSelectedCtrIndex], NULL, &mMappingDataBase);\r
+  for (SelectedDriverImageNum = 0; SelectedDriverImageNum < mSelectedDriverImageNum; SelectedDriverImageNum++) {\r
+    //\r
+    // DriOrder[SelectedDriverImageNum] = the driver NO. in driver binding buffer\r
+    //\r
+    Index = FakeNvData->DriOrder[SelectedDriverImageNum] - 1;\r
+\r
+    //\r
+    // Get the EFI Loaded Image Device Path Protocol\r
+    //\r
+    LoadedImageDevicePath = NULL;\r
+    Status = gBS->HandleProtocol (\r
+                        mDriverImageHandleBuffer[Index],\r
+                        &gEfiLoadedImageDevicePathProtocolGuid,\r
+                        (VOID **) &LoadedImageDevicePath\r
+                        );\r
+    ASSERT (LoadedImageDevicePath != NULL);\r
+\r
+    InsertDriverImage (\r
+            mControllerDevicePathProtocol[mSelectedCtrIndex],\r
+            LoadedImageDevicePath,\r
+            &mMappingDataBase,\r
+            (UINT32)SelectedDriverImageNum + 1\r
+            );\r
+  }\r
+  Status = SaveOverridesMapping (&mMappingDataBase);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function allows a caller to extract the current configuration for one\r
+  or more named elements from the target driver.\r
+\r
+  @param  This         Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param  Request      A null-terminated Unicode string in <ConfigRequest> format.\r
+  @param  Progress     On return, points to a character in the Request string.\r
+                       Points to the string's null terminator if request was successful.\r
+                       Points to the most recent '&' before the first failing name/value\r
+                       pair (or the beginning of the string if the failure is in the\r
+                       first name/value pair) if the request was not successful.\r
+  @param  Results      A null-terminated Unicode string in <ConfigAltResp> format which\r
+                       has all values filled in for the names in the Request string.\r
+                       String to be allocated by the called function.\r
+\r
+  @retval EFI_SUCCESS            The Results is filled with the requested values.\r
+  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.\r
+  @retval EFI_INVALID_PARAMETER  Request is NULL, illegal syntax, or unknown name.\r
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PlatOverMngrExtractConfig (\r
+ IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  CONST EFI_STRING                       Request,\r
+  OUT EFI_STRING                             *Progress,\r
+  OUT EFI_STRING                             *Results\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  EFI_CALLBACK_INFO                *Private;\r
+  EFI_HII_CONFIG_ROUTING_PROTOCOL  *HiiConfigRouting;\r
+\r
+  Private = EFI_CALLBACK_INFO_FROM_THIS (This);\r
+  HiiConfigRouting = Private->HiiConfigRouting;\r
+\r
+  //\r
+  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
+  //\r
+  Status = HiiConfigRouting->BlockToConfig (\r
+                                HiiConfigRouting,\r
+                                Request,\r
+                                (UINT8 *) &Private->FakeNvData,\r
+                                sizeof (PLAT_OVER_MNGR_DATA),\r
+                                Results,\r
+                                Progress\r
+                                );\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+  @param  This         Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param  Request      A null-terminated Unicode string in <ConfigRequest> format.\r
+  @param  Progress     A pointer to a string filled in with the offset of the most\r
+                       recent '&' before the first failing name/value pair (or the\r
+                       beginning of the string if the failure is in the first\r
+                       name/value pair) or the terminating NULL if all was successful.\r
+\r
+  @retval EFI_SUCCESS            The Results is processed successfully.\r
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.\r
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PlatOverMngrRouteConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  CONST EFI_STRING                       Configuration,\r
+  OUT EFI_STRING                             *Progress\r
+  )\r
+{\r
+  EFI_CALLBACK_INFO                         *Private;\r
+  EFI_STATUS                                Status;\r
+  UINT16                                    KeyValue;\r
+  UINTN                                     BufferSize;\r
+  PLAT_OVER_MNGR_DATA                       *FakeNvData;\r
+\r
+  Private     = EFI_CALLBACK_INFO_FROM_THIS (This);\r
+\r
+  FakeNvData = &Private->FakeNvData;\r
+  BufferSize = sizeof (PLAT_OVER_MNGR_DATA);\r
+  Status = GetBrowserData (NULL, NULL, &BufferSize, (UINT8 *) FakeNvData);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (mCurrentPage == FORM_ID_DRIVER) {\r
+    KeyValue = KEY_VALUE_DRIVER_GOTO_ORDER;\r
+    UpdatePrioritySelectPage (Private, KeyValue, FakeNvData);\r
+    KeyValue = KEY_VALUE_ORDER_SAVE_AND_EXIT;\r
+    CommintChanges (Private, KeyValue, FakeNvData);\r
+    //\r
+    // Since UpdatePrioritySelectPage will change mCurrentPage,\r
+    // should ensure the mCurrentPage still indicate the second page here\r
+    //\r
+    mCurrentPage = FORM_ID_DRIVER;\r
+  }\r
+\r
+  if (mCurrentPage == FORM_ID_ORDER) {\r
+    KeyValue = KEY_VALUE_ORDER_SAVE_AND_EXIT;\r
+    CommintChanges (Private, KeyValue, FakeNvData);\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This is the function that is called to provide results data to the driver.  This data\r
+  consists of a unique key which is used to identify what data is either being passed back\r
+  or being asked for.\r
+\r
+  @param  This           Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param  Action         A null-terminated Unicode string in <ConfigRequest> format.\r
+  @param  KeyValue       A unique Goto OpCode callback value which record user's selection.\r
+                         0x100 <= KeyValue <0x500 : user select a controller item in the first page;\r
+                         KeyValue == 0x1234       : user select 'Refresh' in first page, or user select 'Go to Previous Menu' in second page\r
+                         KeyValue == 0x1235       : user select 'Pci device filter' in first page\r
+                         KeyValue == 0x1500       : user select 'order ... priority' item in second page\r
+                         KeyValue == 0x1800       : user select 'commint changes' in third page\r
+                         KeyValue == 0x2000       : user select 'Go to Previous Menu' in third page\r
+  @param  Type           The type of value for the question.\r
+  @param  Value          A pointer to the data being sent to the original exporting driver.\r
+  @param  ActionRequest  On return, points to the action requested by the callback function.\r
+\r
+  @retval EFI_SUCCESS    Always returned.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PlatOverMngrCallback (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  EFI_BROWSER_ACTION                     Action,\r
+  IN  EFI_QUESTION_ID                        KeyValue,\r
+  IN  UINT8                                  Type,\r
+  IN  EFI_IFR_TYPE_VALUE                     *Value,\r
+  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest\r
+  )\r
+{\r
+  EFI_CALLBACK_INFO                         *Private;\r
+  EFI_STATUS                                Status;\r
+  EFI_STRING_ID                             NewStringToken;\r
+  UINTN                                     BufferSize;\r
+  PLAT_OVER_MNGR_DATA                       *FakeNvData;\r
+  EFI_INPUT_KEY                             Key;\r
+\r
+  Private = EFI_CALLBACK_INFO_FROM_THIS (This);\r
+\r
+  FakeNvData = &Private->FakeNvData;\r
+  BufferSize = sizeof (PLAT_OVER_MNGR_DATA);\r
+  Status = GetBrowserData (NULL, NULL, &BufferSize, (UINT8 *) FakeNvData);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (KeyValue == KEY_VALUE_DEVICE_REFRESH ||\r
+      KeyValue == KEY_VALUE_DEVICE_FILTER ||\r
+      KeyValue == KEY_VALUE_DRIVER_GOTO_PREVIOUS\r
+      ) {\r
+    UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);\r
+    //\r
+    // Update page title string\r
+    //\r
+    NewStringToken = STRING_TOKEN (STR_TITLE);\r
+    Status = HiiLibSetString (Private->RegisteredHandle, NewStringToken, L"First, Select the controller by device path");\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  if (((KEY_VALUE_DEVICE_OFFSET <= KeyValue) && (KeyValue < KEY_VALUE_DEVICE_MAX)) || (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS)) {\r
+    if (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS) {\r
+      KeyValue = (EFI_QUESTION_ID) (mSelectedCtrIndex + 0x100);\r
+    }\r
+    UpdateBindingDriverSelectPage (Private, KeyValue, FakeNvData);\r
+    //\r
+    // Update page title string\r
+    //\r
+    NewStringToken = STRING_TOKEN (STR_TITLE);\r
+    Status = HiiLibSetString (Private->RegisteredHandle, NewStringToken, L"Second, Select drivers for the previous selected controller");\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  if (KeyValue == KEY_VALUE_DRIVER_GOTO_ORDER) {\r
+    UpdatePrioritySelectPage (Private, KeyValue, FakeNvData);\r
+    //\r
+    // Update page title string\r
+    //\r
+    NewStringToken = STRING_TOKEN (STR_TITLE);\r
+    Status = HiiLibSetString (Private->RegisteredHandle, NewStringToken, L"Finally, Set the priority order for the drivers and save them");\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  if (KeyValue == KEY_VALUE_ORDER_SAVE_AND_EXIT) {\r
+    Status = CommintChanges (Private, KeyValue, FakeNvData);\r
+    *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
+    if (EFI_ERROR (Status)) {\r
+      IfrLibCreatePopUp (1, &Key, L"Single Override Info too large, Saving Error!");\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+  }\r
+\r
+  if (KeyValue == KEY_VALUE_DEVICE_CLEAR) {\r
+    //\r
+    // Deletes all environment variable(s) that contain the override mappings info\r
+    //\r
+    FreeMappingDatabase (&mMappingDataBase);\r
+    Status = SaveOverridesMapping (&mMappingDataBase);\r
+    UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);\r
+  }\r
+  //\r
+  // Pass changed uncommitted data back to Form Browser\r
+  //\r
+  BufferSize = sizeof (PLAT_OVER_MNGR_DATA);\r
+  Status = SetBrowserData (NULL, NULL, BufferSize, (UINT8 *) FakeNvData, NULL);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Function unpacks a device path data structure so that all the nodes\r
+  of a device path are naturally aligned.\r
+\r
+  @param  DevPath  A pointer to a device path data structure\r
+\r
+  @return If the memory for the device path is successfully allocated, then a\r
+  @return pointer to the new device path is returned.  Otherwise, NULL is returned.\r
+\r
+**/\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+UnpackDevicePath (\r
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath\r
+  )\r
+{\r
+  EFI_DEVICE_PATH_PROTOCOL  *Src;\r
+  EFI_DEVICE_PATH_PROTOCOL  *Dest;\r
+  EFI_DEVICE_PATH_PROTOCOL  *NewPath;\r
+  UINTN                     Size;\r
+\r
+  //\r
+  // Walk device path and round sizes to valid boundries\r
+  //\r
+  Src   = DevPath;\r
+  Size  = 0;\r
+  for (;;) {\r
+    Size += DevicePathNodeLength (Src);\r
+    Size += ALIGN_SIZE (Size);\r
+\r
+    if (IsDevicePathEnd (Src)) {\r
+      break;\r
+    }\r
+\r
+    Src = NextDevicePathNode (Src);\r
+  }\r
+  //\r
+  // Allocate space for the unpacked path\r
+  //\r
+  NewPath = AllocateZeroPool (Size);\r
+  if (NewPath) {\r
+\r
+    ASSERT (((UINTN) NewPath) % MIN_ALIGNMENT_SIZE == 0);\r
+\r
+    //\r
+    // Copy each node\r
+    //\r
+    Src   = DevPath;\r
+    Dest  = NewPath;\r
+    for (;;) {\r
+      Size = DevicePathNodeLength (Src);\r
+      CopyMem (Dest, Src, Size);\r
+      Size += ALIGN_SIZE (Size);\r
+      SetDevicePathNodeLength (Dest, Size);\r
+      Dest->Type |= EFI_DP_TYPE_UNPACKED;\r
+      Dest = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) Dest) + Size);\r
+\r
+      if (IsDevicePathEnd (Src)) {\r
+        break;\r
+      }\r
+\r
+      Src = NextDevicePathNode (Src);\r
+    }\r
+  }\r
+\r
+  return NewPath;\r
+}\r
+\r
+\r
+/**\r
+  Get the description string by device path.\r
+\r
+  @param  DevPath     The input device path.\r
+\r
+  @retval !NULL       The description string retured.\r
+  @retval  NULL       The description string cannot be found.\r
+\r
+**/\r
+CHAR16 *\r
+DevicePathToStr (\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  CHAR16                           *ToText;\r
+  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;\r
+\r
+  if (DevPath == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiDevicePathToTextProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &DevPathToText\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    ToText = DevPathToText->ConvertDevicePathToText (\r
+                              DevPath,\r
+                              FALSE,\r
+                              TRUE\r
+                              );\r
+    ASSERT (ToText != NULL);\r
+    return ToText;\r
+  }\r
+\r
+  return NULL;\r
+}\r
diff --git a/MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/PlatOverMngr.h b/MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/PlatOverMngr.h
new file mode 100644 (file)
index 0000000..2c19eff
--- /dev/null
@@ -0,0 +1,184 @@
+/** @file\r
+\r
+Copyright (c) 2007 - 2008, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+  PlatOverMngr.h\r
+\r
+Abstract:\r
+\r
+  Function prototype for platform driver override manager driver\r
+\r
+**/\r
+\r
+#ifndef _PLAT_OVER_MNGR_H_\r
+#define _PLAT_OVER_MNGR_H_\r
+\r
+#include <Uefi.h>\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/HiiConfigAccess.h>\r
+#include <Protocol/HiiConfigRouting.h>\r
+#include <Protocol/HiiDatabase.h>\r
+#include <Protocol/LoadedImage.h>\r
+#include <Protocol/FirmwareVolumeBlock.h>\r
+#include <Protocol/FirmwareVolume2.h>\r
+#include <Protocol/PciIo.h>\r
+#include <Protocol/BusSpecificDriverOverride.h>\r
+#include <Protocol/ComponentName2.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Protocol/DevicePathToText.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiApplicationEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/PlatDriOverLib.h>\r
+#include <Library/IfrSupportLib.h>\r
+#include <Library/ExtendedIfrSupportLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/ExtendedHiiLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/DevicePathLib.h>\r
+\r
+\r
+#define MIN_ALIGNMENT_SIZE  4\r
+#define ALIGN_SIZE(a)       ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)\r
+\r
+\r
+#define EFI_CALLBACK_INFO_SIGNATURE EFI_SIGNATURE_32 ('C', 'l', 'b', 'k')\r
+#define EFI_CALLBACK_INFO_FROM_THIS(a)  CR (a, EFI_CALLBACK_INFO, ConfigAccess, EFI_CALLBACK_INFO_SIGNATURE)\r
+#define MAX_CHOICE_NUM    0x100\r
+#define UPDATE_DATA_SIZE  0x1000\r
+\r
+\r
+extern UINT8  VfrBin[];\r
+\r
+extern UINT8  PlatOverMngrStrings[];\r
+\r
+//\r
+// Following definition is the same as in vfr file\r
+//\r
+#define PLAT_OVER_MNGR_GUID \\r
+  { \\r
+    0x8614567d, 0x35be, 0x4415, 0x8d, 0x88, 0xbd, 0x7d, 0xc, 0x9c, 0x70, 0xc0 \\r
+  }\r
+\r
+typedef struct {\r
+  UINT8   DriSelection[100];\r
+  UINT8   DriOrder[100];\r
+  UINT8   PciDeviceFilter;\r
+} PLAT_OVER_MNGR_DATA;\r
+\r
+#define FORM_ID_DEVICE                 0x1234\r
+#define FORM_ID_DRIVER                 0x1200\r
+#define FORM_ID_ORDER                  0x1500\r
+\r
+#define KEY_VALUE_DEVICE_OFFSET        0x0100\r
+#define KEY_VALUE_DEVICE_MAX           0x04ff\r
+\r
+#define QUESTION_ID_OFFSET             0x0500\r
+\r
+#define KEY_VALUE_DEVICE_REFRESH       0x1234\r
+#define KEY_VALUE_DEVICE_FILTER        0x1235\r
+#define KEY_VALUE_DEVICE_CLEAR         0x1236\r
+\r
+#define KEY_VALUE_DRIVER_GOTO_PREVIOUS 0x1300\r
+#define KEY_VALUE_DRIVER_GOTO_ORDER    0x1301\r
+\r
+#define KEY_VALUE_ORDER_GOTO_PREVIOUS  0x2000\r
+#define KEY_VALUE_ORDER_SAVE_AND_EXIT  0x1800\r
+\r
+#define VARSTORE_ID_PLAT_OVER_MNGR     0x1000\r
+\r
+//\r
+// Question Id start from 1, so define an offset for it\r
+//\r
+#define VAR_OFFSET(Field)              ((UINTN) &(((PLAT_OVER_MNGR_DATA *) 0)->Field))\r
+\r
+#define DRIVER_SELECTION_VAR_OFFSET     (VAR_OFFSET (DriSelection))\r
+#define DRIVER_ORDER_VAR_OFFSET         (VAR_OFFSET (DriOrder))\r
+\r
+#define DRIVER_SELECTION_QUESTION_ID    (VAR_OFFSET (DriSelection) + QUESTION_ID_OFFSET)\r
+#define DRIVER_ORDER_QUESTION_ID        (VAR_OFFSET (DriOrder) + QUESTION_ID_OFFSET)\r
+\r
+typedef struct {\r
+  UINTN                           Signature;\r
+\r
+  EFI_HANDLE                      DriverHandle;\r
+  EFI_HII_HANDLE                  RegisteredHandle;\r
+  PLAT_OVER_MNGR_DATA             FakeNvData;\r
+\r
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
+\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL  ConfigAccess;\r
+} EFI_CALLBACK_INFO;\r
+\r
+typedef struct {\r
+  EFI_DRIVER_CONFIGURATION_PROTOCOL         *DriverConfiguration;\r
+  EFI_HANDLE                                DriverImageHandle;\r
+  EFI_HANDLE                                ControllerHandle;\r
+  EFI_HANDLE                                ChildControllerHandle;\r
+  //\r
+  // To avoid created string leak in Hii database, use this token to reuse every token created by the driver\r
+  //\r
+  EFI_STRING_ID                             DescriptionToken;\r
+} CFG_PROTOCOL_INVOKER_CHOICE;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PlatOverMngrExtractConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  CONST EFI_STRING                       Request,\r
+  OUT EFI_STRING                             *Progress,\r
+  OUT EFI_STRING                             *Results\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PlatOverMngrRouteConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  CONST EFI_STRING                       Configuration,\r
+  OUT EFI_STRING                             *Progress\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PlatOverMngrCallback (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  EFI_BROWSER_ACTION                     Action,\r
+  IN  EFI_QUESTION_ID                        KeyValue,\r
+  IN  UINT8                                  Type,\r
+  IN  EFI_IFR_TYPE_VALUE                     *Value,\r
+  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest\r
+  );\r
+\r
+CHAR16 *\r
+GetImageName (\r
+  IN  EFI_LOADED_IMAGE_PROTOCOL *Image\r
+  );\r
+\r
+CHAR16  *\r
+DevicePathToStr (\r
+  EFI_DEVICE_PATH_PROTOCOL     *DevPath\r
+  );\r
+\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+UnpackDevicePath (\r
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath\r
+  );\r
+\r
+#endif\r
diff --git a/MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/PlatOverMngr.inf b/MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/PlatOverMngr.inf
new file mode 100644 (file)
index 0000000..9fb499a
--- /dev/null
@@ -0,0 +1,73 @@
+#/** @file\r
+# Component description file for PlatOverMngr driver\r
+#\r
+# FIX ME!\r
+# Copyright (c) 2007 - 2008, Intel Corporation. All rights reserved.\r
+#\r
+#  All rights reserved. This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution. The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PlatOverMngr\r
+  FILE_GUID                      = 56D95BFE-F991-4898-B3BE-B8F37C927F48\r
+  MODULE_TYPE                    = UEFI_APPLICATION\r
+  VERSION_STRING                 = 1.0\r
+  EDK_RELEASE_VERSION            = 0x00020000\r
+  EFI_SPECIFICATION_VERSION      = 0x00020000\r
+\r
+  ENTRY_POINT                    = PlatOverMngrInit\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  VfrStrings.uni\r
+  Vfr.vfr\r
+  PlatOverMngr.c\r
+  PlatOverMngr.h\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  UefiBootServicesTableLib\r
+  UefiApplicationEntryPoint\r
+  UefiLib\r
+  DebugLib\r
+  PlatDriOverLib\r
+  IfrSupportLib\r
+  ExtendedIfrSupportLib\r
+  BaseMemoryLib\r
+  MemoryAllocationLib\r
+  HiiLib\r
+  ExtendedHiiLib\r
+  UefiRuntimeServicesTableLib\r
+  DevicePathLib\r
+\r
+[Protocols]\r
+  gEfiLoadedImageProtocolGuid                   # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiPciIoProtocolGuid                         # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiBusSpecificDriverOverrideProtocolGuid     # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiComponentName2ProtocolGuid                # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiComponentNameProtocolGuid                 # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiHiiConfigAccessProtocolGuid               # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiDevicePathToTextProtocolGuid              # PROTOCOL ALWAYS_CONSUMED\r
+\r
+[Depex]\r
+  gEfiHiiDatabaseProtocolGuid\r
diff --git a/MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/Vfr.vfr b/MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/Vfr.vfr
new file mode 100644 (file)
index 0000000..f5514d8
--- /dev/null
@@ -0,0 +1,141 @@
+// *++\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
+//   Vfr.vfr\r
+//\r
+// Abstract:\r
+//\r
+//   Platform driver Override manager formset\r
+//\r
+//\r
+// --*/\r
+\r
+#define PLAT_OVER_MNGR_GUID \\r
+  { \\r
+    0x8614567d, 0x35be, 0x4415, 0x8d, 0x88, 0xbd, 0x7d, 0xc, 0x9c, 0x70, 0xc0 \\r
+  }\r
+\r
+typedef struct {\r
+  UINT8   DriSelection[100];\r
+  UINT8   DriOrder[100];\r
+  UINT8   PciDeviceFilter;\r
+} PLAT_OVER_MNGR_DATA;\r
+\r
+#define FORM_ID_DEVICE                 0x1234\r
+#define FORM_ID_DRIVER                 0x1200\r
+#define FORM_ID_ORDER                  0x1500\r
+\r
+#define KEY_VALUE_DEVICE_OFFSET        0x0100\r
+#define KEY_VALUE_DEVICE_MAX           0x04ff\r
+\r
+#define QUESTION_ID_OFFSET             0x0500\r
+\r
+#define KEY_VALUE_DEVICE_REFRESH       0x1234\r
+#define KEY_VALUE_DEVICE_FILTER        0x1235\r
+#define KEY_VALUE_DEVICE_CLEAR         0x1236\r
+\r
+#define KEY_VALUE_DRIVER_GOTO_PREVIOUS 0x1300\r
+#define KEY_VALUE_DRIVER_GOTO_ORDER    0x1301\r
+\r
+#define KEY_VALUE_ORDER_GOTO_PREVIOUS  0x2000\r
+#define KEY_VALUE_ORDER_SAVE_AND_EXIT  0x1800\r
+\r
+#define VARSTORE_ID_PLAT_OVER_MNGR     0x1000\r
+\r
+\r
+#define EFI_DISK_DEVICE_CLASS          0x01\r
+#define LABEL_END                      0xffff\r
+\r
+formset\r
+  guid     = PLAT_OVER_MNGR_GUID,\r
+  title    = STRING_TOKEN(STR_ENTRY_TITLE),\r
+  help     = STRING_TOKEN(STR_TITLE_HELP),\r
+  class    = EFI_DISK_DEVICE_CLASS,\r
+  subclass = 0xff,\r
+\r
+  varstore PLAT_OVER_MNGR_DATA,\r
+    varid = VARSTORE_ID_PLAT_OVER_MNGR,\r
+    name  = Data,\r
+    guid  = PLAT_OVER_MNGR_GUID;\r
+\r
+  form formid = FORM_ID_DEVICE,\r
+       title = STRING_TOKEN(STR_TITLE);\r
+\r
+    text\r
+      help   = STRING_TOKEN(STR_FIRST_REFRESH_HELP),\r
+      text   = STRING_TOKEN(STR_FIRST_REFRESH),\r
+      text   = STRING_TOKEN(STR_NULL_STRING),\r
+      flags  = INTERACTIVE,\r
+      key    = KEY_VALUE_DEVICE_REFRESH;\r
+\r
+    checkbox varid = Data.PciDeviceFilter,\r
+      prompt   = STRING_TOKEN(STR_PCI_DEVICE_FILTER_PROMPT),\r
+      help     = STRING_TOKEN(STR_PCI_DEVICE_FILTER_HELP),\r
+      flags    = INTERACTIVE,\r
+      key      = KEY_VALUE_DEVICE_FILTER,\r
+    endcheckbox;\r
+\r
+    label FORM_ID_DEVICE;\r
+    label LABEL_END;\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL_STRING);\r
+\r
+    goto FORM_ID_DEVICE,\r
+      prompt  = STRING_TOKEN(STR_CLEAR_ALL),\r
+      help    = STRING_TOKEN(STR_CLEAR_ALL_HELP),\r
+      flags   = INTERACTIVE | RESET_REQUIRED,\r
+      key     = KEY_VALUE_DEVICE_CLEAR;\r
+  endform;\r
+\r
+  form formid = FORM_ID_DRIVER,\r
+       title = STRING_TOKEN(STR_TITLE);\r
+\r
+    goto FORM_ID_DEVICE,\r
+      prompt  = STRING_TOKEN(STR_GOTO_PREVIOUS),\r
+      help    = STRING_TOKEN(STR_NULL_STRING),\r
+      flags   = INTERACTIVE,\r
+      key     = KEY_VALUE_DRIVER_GOTO_PREVIOUS;\r
+\r
+    goto FORM_ID_ORDER,\r
+      prompt  = STRING_TOKEN(STR_TITLE_ORDER),\r
+      help    = STRING_TOKEN(STR_TITLE_ORDER_HELP),\r
+      flags   = INTERACTIVE,\r
+      key     = KEY_VALUE_DRIVER_GOTO_ORDER;\r
+\r
+    label FORM_ID_DRIVER;\r
+    label LABEL_END;\r
+\r
+  endform;\r
+\r
+  form formid = FORM_ID_ORDER,\r
+       title = STRING_TOKEN(STR_TITLE);\r
+\r
+    goto FORM_ID_DRIVER,\r
+      prompt  = STRING_TOKEN(STR_GOTO_PREVIOUS),\r
+      help    = STRING_TOKEN(STR_NULL_STRING),\r
+      flags   = INTERACTIVE,\r
+      key     = KEY_VALUE_ORDER_GOTO_PREVIOUS;\r
+\r
+    label FORM_ID_ORDER;\r
+    label LABEL_END;\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL_STRING);\r
+\r
+    goto FORM_ID_ORDER,\r
+      prompt  = STRING_TOKEN(STR_SAVE_AND_EXIT),\r
+      help    = STRING_TOKEN(STR_NULL_STRING),\r
+      flags   = INTERACTIVE | RESET_REQUIRED,\r
+      key     = KEY_VALUE_ORDER_SAVE_AND_EXIT;\r
+  endform;\r
+\r
+endformset;\r
diff --git a/MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/VfrStrings.uni b/MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/VfrStrings.uni
new file mode 100644 (file)
index 0000000..fe14d30
Binary files /dev/null and b/MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/VfrStrings.uni differ
diff --git a/MdeModulePkg/Universal/PlatformDriverOverride/PlatformDriOverrideDxe/PlatformDriOverride.c b/MdeModulePkg/Universal/PlatformDriverOverride/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/PlatformDriverOverride/PlatformDriOverrideDxe/PlatformDriOverride.h b/MdeModulePkg/Universal/PlatformDriverOverride/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/PlatformDriverOverride/PlatformDriOverrideDxe/PlatformDriOverrideDxe.inf b/MdeModulePkg/Universal/PlatformDriverOverride/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/PlatformDriverOverride/PlatformDriOverrideDxe/PlatformDriOverrideDxe.msa b/MdeModulePkg/Universal/PlatformDriverOverride/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