]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Legacy Boot Maintenance UI part code split from IntelFrameworkModulePkg/Universal...
authorEric Dong <eric.dong@intel.com>
Thu, 30 Jul 2015 03:43:14 +0000 (03:43 +0000)
committerydong10 <ydong10@Edk2>
Thu, 30 Jul 2015 03:43:14 +0000 (03:43 +0000)
This is the legacy part of the old BdsDxe driver.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18112 6f19259b-4bc3-4df7-8a09-765794883524

IntelFrameworkModulePkg/IntelFrameworkModulePkg.dsc
IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUi.c [new file with mode: 0644]
IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUi.h [new file with mode: 0644]
IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiLib.inf [new file with mode: 0644]
IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiStrings.uni [new file with mode: 0644]
IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiVfr.Vfr [new file with mode: 0644]
IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiVfr.h [new file with mode: 0644]

index 20e016d363d5797dda902605ef75e59f3e461928..3e1297cd2b8f7835c6a0d4ce2a93c79fdfee11a6 100644 (file)
   IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf\r
   IntelFrameworkModulePkg/Library/DxeCapsuleLib/DxeCapsuleLib.inf\r
   IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBootManagerLib.inf\r
+  IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiLib.inf\r
 \r
   IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/IdeBusDxe.inf\r
   IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf\r
diff --git a/IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUi.c b/IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUi.c
new file mode 100644 (file)
index 0000000..a56c700
--- /dev/null
@@ -0,0 +1,1465 @@
+/** @file\r
+  Legacy Boot Maintainence UI implementation.\r
+\r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+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
+#include "LegacyBootMaintUi.h"\r
+\r
+LEGACY_BOOT_OPTION_CALLBACK_DATA  *mLegacyBootOptionPrivate;\r
+EFI_GUID  mLegacyBootOptionGuid     = LEGACY_BOOT_OPTION_FORMSET_GUID;\r
+CHAR16    mLegacyBootStorageName[]  = L"LegacyBootData";\r
+BBS_TYPE  mBbsType[] = {BBS_FLOPPY, BBS_HARDDISK, BBS_CDROM, BBS_EMBED_NETWORK, BBS_BEV_DEVICE, BBS_UNKNOWN};\r
+\r
+\r
+///\r
+/// Legacy FD Info from LegacyBios.GetBbsInfo()\r
+///\r
+LEGACY_MENU_OPTION      LegacyFDMenu = {\r
+  LEGACY_MENU_OPTION_SIGNATURE,\r
+  {NULL},\r
+  0\r
+};\r
+\r
+///\r
+/// Legacy HD Info from LegacyBios.GetBbsInfo()\r
+///\r
+LEGACY_MENU_OPTION      LegacyHDMenu = {\r
+  LEGACY_MENU_OPTION_SIGNATURE,\r
+  {NULL},\r
+  0\r
+};\r
+\r
+///\r
+/// Legacy CD Info from LegacyBios.GetBbsInfo()\r
+///\r
+LEGACY_MENU_OPTION      LegacyCDMenu = {\r
+  LEGACY_MENU_OPTION_SIGNATURE,\r
+  {NULL},\r
+  0\r
+};\r
+\r
+///\r
+/// Legacy NET Info from LegacyBios.GetBbsInfo()\r
+///\r
+LEGACY_MENU_OPTION      LegacyNETMenu = {\r
+  LEGACY_MENU_OPTION_SIGNATURE,\r
+  {NULL},\r
+  0\r
+};\r
+\r
+///\r
+/// Legacy NET Info from LegacyBios.GetBbsInfo()\r
+///\r
+LEGACY_MENU_OPTION      LegacyBEVMenu = {\r
+  LEGACY_MENU_OPTION_SIGNATURE,\r
+  {NULL},\r
+  0\r
+};\r
+\r
+\r
+VOID                *mLegacyStartOpCodeHandle = NULL;\r
+VOID                *mLegacyEndOpCodeHandle = NULL;\r
+EFI_IFR_GUID_LABEL  *mLegacyStartLabel = NULL;\r
+EFI_IFR_GUID_LABEL  *mLegacyEndLabel = NULL;\r
+\r
+\r
+HII_VENDOR_DEVICE_PATH  mLegacyBootOptionHiiVendorDevicePath = {\r
+  {\r
+    {\r
+      HARDWARE_DEVICE_PATH,\r
+      HW_VENDOR_DP,\r
+      {\r
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
+      }\r
+    }, \r
+    { 0x6bc75598, 0x89b4, 0x483d, { 0x91, 0x60, 0x7f, 0x46, 0x9a, 0x96, 0x35, 0x31 } }\r
+  },\r
+  {\r
+    END_DEVICE_PATH_TYPE,\r
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+    { \r
+      (UINT8) (END_DEVICE_PATH_LENGTH),\r
+      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
+    }\r
+  }\r
+};\r
+\r
+\r
+/**\r
+  Re-order the Boot Option according to the DevOrder.\r
+\r
+  The routine re-orders the Boot Option in BootOption array according to\r
+  the order specified by DevOrder.\r
+\r
+  @param DevOrder           Pointer to buffer containing the BBS Index,\r
+                            high 8-bit value 0xFF indicating a disabled boot option\r
+  @param DevOrderCount      Count of the BBS Index\r
+  @param EnBootOption       Callee allocated buffer containing the enabled Boot Option Numbers\r
+  @param EnBootOptionCount  Count of the enabled Boot Option Numbers\r
+  @param DisBootOption      Callee allocated buffer containing the disabled Boot Option Numbers\r
+  @param DisBootOptionCount Count of the disabled Boot Option Numbers\r
+**/\r
+VOID\r
+OrderLegacyBootOption4SameType (\r
+  UINT16                   *DevOrder,\r
+  UINTN                    DevOrderCount,\r
+  UINT16                   **EnBootOption,\r
+  UINTN                    *EnBootOptionCount,\r
+  UINT16                   **DisBootOption,\r
+  UINTN                    *DisBootOptionCount\r
+  )\r
+{\r
+  EFI_STATUS               Status;\r
+  UINT16                   *NewBootOption;\r
+  UINT16                   *BootOrder;\r
+  UINTN                    BootOrderSize;\r
+  UINTN                    Index;\r
+  UINTN                    StartPosition;\r
+  \r
+  EFI_BOOT_MANAGER_LOAD_OPTION    BootOption;\r
+  \r
+  CHAR16                           OptionName[sizeof ("Boot####")];\r
+  UINT16                   *BbsIndexArray;\r
+  UINT16                   *DeviceTypeArray;\r
+\r
+  GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrder, &BootOrderSize);\r
+  ASSERT (BootOrder != NULL);\r
+\r
+  BbsIndexArray       = AllocatePool (BootOrderSize);\r
+  DeviceTypeArray     = AllocatePool (BootOrderSize);\r
+  *EnBootOption       = AllocatePool (BootOrderSize);\r
+  *DisBootOption      = AllocatePool (BootOrderSize);\r
+  *DisBootOptionCount = 0;\r
+  *EnBootOptionCount  = 0;\r
+  Index               = 0;\r
+\r
+  ASSERT (*EnBootOption != NULL);\r
+  ASSERT (*DisBootOption != NULL);\r
+\r
+  for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
+  \r
+    UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);\r
+    Status = EfiBootManagerVariableToLoadOption (OptionName, &BootOption);\r
+    ASSERT_EFI_ERROR (Status);\r
+    \r
+    if ((DevicePathType (BootOption.FilePath) == BBS_DEVICE_PATH) &&\r
+        (DevicePathSubType (BootOption.FilePath) == BBS_BBS_DP)) {\r
+      //\r
+      // Legacy Boot Option\r
+      //\r
+      ASSERT (BootOption.OptionalDataSize == sizeof (LEGACY_BOOT_OPTION_BBS_DATA));\r
+\r
+      DeviceTypeArray[Index] = ((BBS_BBS_DEVICE_PATH *) BootOption.FilePath)->DeviceType;\r
+      BbsIndexArray  [Index] = ((LEGACY_BOOT_OPTION_BBS_DATA *) BootOption.OptionalData)->BbsIndex;\r
+    } else {\r
+      DeviceTypeArray[Index] = BBS_TYPE_UNKNOWN;\r
+      BbsIndexArray  [Index] = 0xFFFF;\r
+    }\r
+    EfiBootManagerFreeLoadOption (&BootOption);\r
+  }\r
+\r
+  //\r
+  // Record the corresponding Boot Option Numbers according to the DevOrder\r
+  // Record the EnBootOption and DisBootOption according to the DevOrder\r
+  //\r
+  StartPosition = BootOrderSize / sizeof (UINT16);\r
+  NewBootOption = AllocatePool (DevOrderCount * sizeof (UINT16));\r
+  while (DevOrderCount-- != 0) {\r
+    for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
+      if (BbsIndexArray[Index] == (DevOrder[DevOrderCount] & 0xFF)) {\r
+        StartPosition = MIN (StartPosition, Index);\r
+        NewBootOption[DevOrderCount] = BootOrder[Index];\r
+        \r
+        if ((DevOrder[DevOrderCount] & 0xFF00) == 0xFF00) {\r
+          (*DisBootOption)[*DisBootOptionCount] = BootOrder[Index];\r
+          (*DisBootOptionCount)++;\r
+        } else {\r
+          (*EnBootOption)[*EnBootOptionCount] = BootOrder[Index];\r
+          (*EnBootOptionCount)++;\r
+        }\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Overwrite the old BootOption\r
+  //\r
+  CopyMem (&BootOrder[StartPosition], NewBootOption, (*DisBootOptionCount + *EnBootOptionCount) * sizeof (UINT16));\r
+  Status = gRT->SetVariable (\r
+                  L"BootOrder",\r
+                  &gEfiGlobalVariableGuid,\r
+                  VAR_FLAG,\r
+                  BootOrderSize,\r
+                  BootOrder\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  FreePool (NewBootOption);\r
+  FreePool (DeviceTypeArray);\r
+  FreePool (BbsIndexArray);\r
+}\r
+\r
+/**\r
+  Update the legacy BBS boot option. L"LegacyDevOrder" and gEfiLegacyDevOrderVariableGuid EFI Variable\r
+  is udpated with the new Legacy Boot order. The EFI Variable of "Boot####" and gEfiGlobalVariableGuid\r
+  is also updated.\r
+\r
+  @param CallbackData    The context data for BMM.\r
+\r
+  @return EFI_SUCCESS           The function completed successfully.\r
+  @retval EFI_NOT_FOUND         If L"LegacyDevOrder" and gEfiLegacyDevOrderVariableGuid EFI Variable can be found.\r
+  @retval EFI_OUT_OF_RESOURCES  Fail to allocate memory resource\r
+**/\r
+EFI_STATUS\r
+UpdateBBSOption (\r
+  IN LEGACY_BOOT_NV_DATA            *NVMapData\r
+  )\r
+{\r
+  UINTN                       Index;\r
+  UINTN                       Index2;\r
+  UINTN                       CurrentType;\r
+  VOID                        *BootOptionVar;\r
+  CHAR16                      VarName[100];\r
+  UINTN                       OptionSize;\r
+  EFI_STATUS                  Status;\r
+  UINT32                      *Attribute;\r
+  LEGACY_MENU_OPTION          *OptionMenu;\r
+  UINT16                      *LegacyDev;\r
+  UINT16                      *InitialLegacyDev;\r
+  UINT8                       *VarData;\r
+  UINTN                       VarSize;\r
+  LEGACY_DEV_ORDER_ENTRY      *DevOrder;\r
+  UINT8                       *OriginalPtr;\r
+  UINT8                       *DisMap;\r
+  UINTN                       Pos;\r
+  UINTN                       Bit;\r
+  UINT16                      *NewOrder;\r
+  UINT16                      Tmp;\r
+  UINT16                      *EnBootOption;\r
+  UINTN                       EnBootOptionCount;\r
+  UINT16                      *DisBootOption;\r
+  UINTN                       DisBootOptionCount;\r
+  UINTN                       BufferSize;\r
+  \r
+\r
+  DisMap              = NULL;\r
+  NewOrder            = NULL;\r
+  CurrentType         = 0;\r
+\r
+  \r
+  DisMap  = mLegacyBootOptionPrivate->MaintainMapData->DisableMap;\r
+  Status  = EFI_SUCCESS;\r
+\r
+  //\r
+  // Update the Variable "LegacyDevOrder"\r
+  //\r
+  GetVariable2 (VAR_LEGACY_DEV_ORDER, &gEfiLegacyDevOrderVariableGuid, (VOID **) &VarData, &VarSize);\r
+  if (VarData == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  OriginalPtr = VarData;\r
+\r
+  while (mBbsType[CurrentType] != BBS_UNKNOWN) {\r
+    switch (mBbsType[CurrentType]) {\r
+    case BBS_FLOPPY:\r
+      OptionMenu            = (LEGACY_MENU_OPTION *) &LegacyFDMenu;\r
+      LegacyDev             = NVMapData->LegacyFD;\r
+      InitialLegacyDev     = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyFD;\r
+      BufferSize            = sizeof (NVMapData->LegacyFD);\r
+      break;\r
+\r
+    case BBS_HARDDISK:\r
+      OptionMenu            = (LEGACY_MENU_OPTION *) &LegacyHDMenu;\r
+      LegacyDev             = NVMapData->LegacyHD;\r
+      InitialLegacyDev     = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyHD;\r
+\r
+      BufferSize            = sizeof (NVMapData->LegacyHD);\r
+      break;\r
+\r
+    case BBS_CDROM:\r
+      OptionMenu            = (LEGACY_MENU_OPTION *) &LegacyCDMenu;\r
+      LegacyDev             = NVMapData->LegacyCD;\r
+      InitialLegacyDev     = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyCD;\r
+      BufferSize            = sizeof (NVMapData->LegacyCD);\r
+      break;\r
+\r
+    case BBS_EMBED_NETWORK:\r
+      OptionMenu            = (LEGACY_MENU_OPTION *) &LegacyNETMenu;\r
+      LegacyDev             = NVMapData->LegacyNET;\r
+      InitialLegacyDev     = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyNET;\r
+      BufferSize            = sizeof (NVMapData->LegacyNET);\r
+      break;\r
+\r
+    default:\r
+      ASSERT (mBbsType[CurrentType] == BBS_BEV_DEVICE);\r
+      OptionMenu            = (LEGACY_MENU_OPTION *) &LegacyBEVMenu;\r
+      LegacyDev             = NVMapData->LegacyBEV;\r
+      InitialLegacyDev     = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyBEV;\r
+      BufferSize            = sizeof (NVMapData->LegacyBEV);\r
+      break;\r
+    }\r
+\r
+    //\r
+    // Check whether has value changed.\r
+    //\r
+    if (CompareMem (LegacyDev, InitialLegacyDev, BufferSize) == 0) {\r
+      CurrentType++;\r
+      continue;\r
+    }\r
+\r
+    DevOrder    = (LEGACY_DEV_ORDER_ENTRY *) OriginalPtr;\r
+    while (VarData < OriginalPtr + VarSize) {\r
+      if (DevOrder->BbsType == mBbsType[CurrentType]) {\r
+        break;\r
+      }\r
+\r
+      VarData += sizeof (BBS_TYPE) + DevOrder->Length;\r
+      DevOrder = (LEGACY_DEV_ORDER_ENTRY *) VarData;\r
+    }\r
+\r
+    if (VarData >= OriginalPtr + VarSize) {\r
+      FreePool (OriginalPtr);\r
+      return EFI_NOT_FOUND;\r
+    }\r
+\r
+    NewOrder = AllocateZeroPool (DevOrder->Length - sizeof (DevOrder->Length));\r
+    if (NewOrder == NULL) {\r
+      FreePool (OriginalPtr);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {\r
+      if (0xFF == LegacyDev[Index]) {\r
+        break;\r
+      }\r
+\r
+      NewOrder[Index] = LegacyDev[Index];\r
+    }\r
+\r
+    //\r
+    // Only the enable/disable state of each boot device with same device type can be changed,\r
+    // so we can count on the index information in DevOrder.\r
+    // DisMap bit array is the only reliable source to check a device's en/dis state,\r
+    // so we use DisMap to set en/dis state of each item in NewOrder array\r
+    //\r
+    for (Index2 = 0; Index2 < OptionMenu->MenuNumber; Index2++) {\r
+      Tmp = (UINT16) (DevOrder->Data[Index2] & 0xFF);\r
+      Pos = Tmp / 8;\r
+      Bit = 7 - (Tmp % 8);\r
+      if ((DisMap[Pos] & (1 << Bit)) != 0) {\r
+        NewOrder[Index] = (UINT16) (0xFF00 | Tmp);\r
+        Index++;\r
+      }\r
+    }\r
+\r
+    CopyMem (\r
+      DevOrder->Data,\r
+      NewOrder,\r
+      DevOrder->Length - sizeof (DevOrder->Length)\r
+      );\r
+    FreePool (NewOrder);\r
+\r
+    //\r
+    // Update BootOrder and Boot####.Attribute\r
+    //\r
+    // 1. Re-order the Option Number in BootOrder according to Legacy Dev Order\r
+    //\r
+    ASSERT (OptionMenu->MenuNumber == DevOrder->Length / sizeof (UINT16) - 1);\r
+\r
+    OrderLegacyBootOption4SameType (\r
+      DevOrder->Data,\r
+      DevOrder->Length / sizeof (UINT16) - 1,\r
+      &EnBootOption,\r
+      &EnBootOptionCount,\r
+      &DisBootOption,\r
+      &DisBootOptionCount\r
+      );\r
+\r
+    //\r
+    // 2. Deactivate the DisBootOption and activate the EnBootOption\r
+    //\r
+    for (Index = 0; Index < DisBootOptionCount; Index++) {\r
+      UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", DisBootOption[Index]);\r
+      GetEfiGlobalVariable2 (VarName, (VOID **) &BootOptionVar, &OptionSize);\r
+      if (BootOptionVar != NULL) {\r
+        Attribute   = (UINT32 *) BootOptionVar;\r
+        *Attribute &= ~LOAD_OPTION_ACTIVE;\r
+\r
+        Status = gRT->SetVariable (\r
+                        VarName,\r
+                        &gEfiGlobalVariableGuid,\r
+                        VAR_FLAG,\r
+                        OptionSize,\r
+                        BootOptionVar\r
+                        );\r
+\r
+        FreePool (BootOptionVar);\r
+      }\r
+    }\r
+\r
+    for (Index = 0; Index < EnBootOptionCount; Index++) {\r
+      UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", EnBootOption[Index]);\r
+      GetEfiGlobalVariable2 (VarName, (VOID **) &BootOptionVar, &OptionSize);\r
+      if (BootOptionVar != NULL) {\r
+        Attribute   = (UINT32 *) BootOptionVar;\r
+        *Attribute |= LOAD_OPTION_ACTIVE;\r
+\r
+        Status = gRT->SetVariable (\r
+                        VarName,\r
+                        &gEfiGlobalVariableGuid,\r
+                        VAR_FLAG,\r
+                        OptionSize,\r
+                        BootOptionVar\r
+                        );\r
+\r
+        FreePool (BootOptionVar);\r
+      }\r
+    }\r
+\r
+\r
+    FreePool (EnBootOption);\r
+    FreePool (DisBootOption);\r
+\r
+    CurrentType++;\r
+  }\r
+  \r
+  Status = gRT->SetVariable (\r
+                  VAR_LEGACY_DEV_ORDER,\r
+                  &gEfiLegacyDevOrderVariableGuid,\r
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                  VarSize,\r
+                  OriginalPtr\r
+                  );\r
+\r
+  FreePool (OriginalPtr);\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
+\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 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
+LegacyBootOptionExtractConfig (\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
+  if (Progress == NULL || Results == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  *Progress = Request;\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+\r
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Configuration   A null-terminated Unicode string in <ConfigResp> 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
+LegacyBootOptionRouteConfig (\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                      Status;\r
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;\r
+  LEGACY_BOOT_NV_DATA             *CurrentNVMapData;\r
+  UINTN                           BufferSize;\r
+\r
+\r
+  if (Configuration == NULL || Progress == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Check routing data in <ConfigHdr>.\r
+  // Note: there is no name for Name/Value storage, only GUID will be checked\r
+  //\r
+  if (!HiiIsConfigHdrMatch (Configuration, &mLegacyBootOptionGuid, mLegacyBootStorageName)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiHiiConfigRoutingProtocolGuid, \r
+                  NULL, \r
+                  &ConfigRouting\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
+  //\r
+  CurrentNVMapData = &mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData;\r
+  Status = ConfigRouting->ConfigToBlock (\r
+                            ConfigRouting,\r
+                            Configuration,\r
+                            (UINT8 *) CurrentNVMapData,\r
+                            &BufferSize,\r
+                            Progress\r
+                            );\r
+  ASSERT_EFI_ERROR (Status);    \r
+\r
+  Status = UpdateBBSOption (CurrentNVMapData);\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Refresh the global UpdateData structure.\r
+\r
+**/\r
+VOID\r
+RefreshLegacyUpdateData (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Free current updated date\r
+  //\r
+  if (mLegacyStartOpCodeHandle != NULL) {\r
+    HiiFreeOpCodeHandle (mLegacyStartOpCodeHandle);\r
+  }\r
+  if (mLegacyEndOpCodeHandle != NULL) {\r
+    HiiFreeOpCodeHandle (mLegacyEndOpCodeHandle);\r
+  }\r
+\r
+  //\r
+  // Create new OpCode Handle\r
+  //\r
+  mLegacyStartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+  mLegacyEndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+\r
+  //\r
+  // Create Hii Extend Label OpCode as the start opcode\r
+  //\r
+  mLegacyStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
+                                         mLegacyStartOpCodeHandle,\r
+                                         &gEfiIfrTianoGuid,\r
+                                         NULL,\r
+                                         sizeof (EFI_IFR_GUID_LABEL)\r
+                                         );\r
+  mLegacyStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+\r
+  mLegacyStartLabel->Number = FORM_BOOT_LEGACY_DEVICE_ID;\r
+\r
+  //\r
+  // Create Hii Extend Label OpCode as the start opcode\r
+  //\r
+  mLegacyEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
+                                         mLegacyEndOpCodeHandle,\r
+                                         &gEfiIfrTianoGuid,\r
+                                         NULL,\r
+                                         sizeof (EFI_IFR_GUID_LABEL)\r
+                                         );\r
+  mLegacyEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+\r
+  mLegacyEndLabel->Number = FORM_BOOT_LEGACY_LABEL_END;\r
+\r
+}\r
+\r
+/**\r
+  Get the Menu Entry from the list in Menu Entry List.\r
+\r
+  If MenuNumber is great or equal to the number of Menu\r
+  Entry in the list, then ASSERT.\r
+\r
+  @param MenuOption      The Menu Entry List to read the menu entry.\r
+  @param MenuNumber      The index of Menu Entry.\r
+\r
+  @return The Menu Entry.\r
+\r
+**/\r
+LEGACY_MENU_ENTRY *\r
+GetMenuEntry (\r
+  LEGACY_MENU_OPTION      *MenuOption,\r
+  UINTN                   MenuNumber\r
+  )\r
+{\r
+  LEGACY_MENU_ENTRY   *NewMenuEntry;\r
+  UINTN               Index;\r
+  LIST_ENTRY          *List;\r
+\r
+  ASSERT (MenuNumber < MenuOption->MenuNumber);\r
+\r
+  List = MenuOption->Head.ForwardLink;\r
+  for (Index = 0; Index < MenuNumber; Index++) {\r
+    List = List->ForwardLink;\r
+  }\r
+\r
+  NewMenuEntry = CR (List, LEGACY_MENU_ENTRY, Link, LEGACY_MENU_ENTRY_SIGNATURE);\r
+\r
+  return NewMenuEntry;\r
+}\r
+\r
+/**\r
+  Create string tokens for a menu from its help strings and display strings\r
+  \r
+  @param HiiHandle          Hii Handle of the package to be updated.\r
+  @param MenuOption         The Menu whose string tokens need to be created\r
+\r
+  @retval  EFI_SUCCESS      String tokens created successfully\r
+  @retval  others           contain some errors\r
+**/\r
+VOID\r
+CreateLegacyMenuStringToken (\r
+  IN EFI_HII_HANDLE                   HiiHandle,\r
+  IN LEGACY_MENU_OPTION               *MenuOption\r
+  )\r
+{\r
+  LEGACY_MENU_ENTRY *NewMenuEntry;\r
+  UINTN             Index;\r
+\r
+  for (Index = 0; Index < MenuOption->MenuNumber; Index++) {\r
+    NewMenuEntry = GetMenuEntry (MenuOption, Index);\r
+\r
+    NewMenuEntry->DisplayStringToken = HiiSetString (\r
+                                         HiiHandle,\r
+                                         0,\r
+                                         NewMenuEntry->DisplayString,\r
+                                         NULL\r
+                                         );\r
+\r
+    if (NULL == NewMenuEntry->HelpString) {\r
+      NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;\r
+    } else {\r
+      NewMenuEntry->HelpStringToken = HiiSetString (\r
+                                        HiiHandle,\r
+                                        0,\r
+                                        NewMenuEntry->HelpString,\r
+                                        NULL\r
+                                        );\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Create a dynamic page so that Legacy Device boot order\r
+  can be set for specified device type.\r
+\r
+  @param UpdatePageId    The form ID. It also spefies the legacy device type.\r
+\r
+\r
+**/\r
+VOID\r
+UpdateLegacyDeviceOrderPage (\r
+  IN UINT16                           UpdatePageId\r
+  )\r
+{\r
+  LEGACY_MENU_OPTION          *OptionMenu;\r
+  LEGACY_MENU_ENTRY           *NewMenuEntry;\r
+  EFI_STRING_ID               StrRef;\r
+  EFI_STRING_ID               StrRefHelp;\r
+  BBS_TYPE                    BbsType;\r
+  UINT16                      *Default;\r
+  UINT16                      Index;\r
+  UINT16                      Key;\r
+  CHAR16                      String[100];\r
+  CHAR16                      *TypeStr;\r
+  CHAR16                      *TypeStrHelp;\r
+  CHAR16                      *FormTitle;\r
+  VOID                        *OptionsOpCodeHandle;\r
+  VOID                        *DefaultOpCodeHandle;\r
+\r
+  Key         = 0;\r
+  StrRef      = 0;\r
+  StrRefHelp  = 0;\r
+  OptionMenu  = NULL;\r
+  TypeStr     = NULL;\r
+  TypeStrHelp = NULL;\r
+  Default     = NULL;\r
+  BbsType     = BBS_FLOPPY;\r
+\r
+  RefreshLegacyUpdateData();\r
+\r
+  //\r
+  // Create oneof option list\r
+  //\r
+  switch (UpdatePageId) {\r
+  case FORM_FLOPPY_BOOT_ID:\r
+    OptionMenu  = (LEGACY_MENU_OPTION *) &LegacyFDMenu;\r
+    Key         = (UINT16) LEGACY_FD_QUESTION_ID;\r
+    TypeStr     = STR_FLOPPY;\r
+    TypeStrHelp = STR_FLOPPY_HELP;\r
+    FormTitle   = STR_FLOPPY_TITLE;\r
+    BbsType     = BBS_FLOPPY;\r
+    Default     = mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData.LegacyFD;\r
+    break;\r
+\r
+  case FORM_HARDDISK_BOOT_ID:\r
+    OptionMenu  = (LEGACY_MENU_OPTION *) &LegacyHDMenu;\r
+    Key         = (UINT16) LEGACY_HD_QUESTION_ID;\r
+    TypeStr     = STR_HARDDISK;\r
+    TypeStrHelp = STR_HARDDISK_HELP;\r
+    FormTitle   = STR_HARDDISK_TITLE;\r
+    BbsType     = BBS_HARDDISK;\r
+    Default     = mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData.LegacyHD;\r
+    break;\r
+\r
+  case FORM_CDROM_BOOT_ID:\r
+    OptionMenu  = (LEGACY_MENU_OPTION *) &LegacyCDMenu;\r
+    Key         = (UINT16) LEGACY_CD_QUESTION_ID;\r
+    TypeStr     = STR_CDROM;\r
+    TypeStrHelp = STR_CDROM_HELP;\r
+    FormTitle   = STR_CDROM_TITLE;\r
+    BbsType     = BBS_CDROM;\r
+    Default     = mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData.LegacyCD;\r
+    break;\r
+\r
+  case FORM_NET_BOOT_ID:\r
+    OptionMenu  = (LEGACY_MENU_OPTION *) &LegacyNETMenu;\r
+    Key         = (UINT16) LEGACY_NET_QUESTION_ID;\r
+    TypeStr     = STR_NET;\r
+    TypeStrHelp = STR_NET_HELP;\r
+    FormTitle   = STR_NET_TITLE;\r
+    BbsType     = BBS_EMBED_NETWORK;\r
+    Default     = mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData.LegacyNET;\r
+    break;\r
+\r
+  case FORM_BEV_BOOT_ID:\r
+    OptionMenu  = (LEGACY_MENU_OPTION *) &LegacyBEVMenu;\r
+    Key         = (UINT16) LEGACY_BEV_QUESTION_ID;\r
+    TypeStr     = STR_BEV;\r
+    TypeStrHelp = STR_BEV_HELP;\r
+    FormTitle   = STR_BEV_TITLE;\r
+    BbsType     = BBS_BEV_DEVICE;\r
+    Default     = mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData.LegacyBEV;\r
+    break;\r
+\r
+  default:\r
+    DEBUG ((EFI_D_ERROR, "Invalid command ID for updating page!\n"));\r
+    return;\r
+  }\r
+  \r
+  HiiSetString (mLegacyBootOptionPrivate->HiiHandle, STRING_TOKEN(STR_ORDER_CHANGE_PROMPT), FormTitle, NULL);\r
+\r
+  CreateLegacyMenuStringToken (mLegacyBootOptionPrivate->HiiHandle, OptionMenu);\r
+\r
+  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+  ASSERT (OptionsOpCodeHandle != NULL);\r
+\r
+\r
+  for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {\r
+    NewMenuEntry = GetMenuEntry (OptionMenu, Index);\r
+    //\r
+    // Create OneOf for each legacy device\r
+    //\r
+    HiiCreateOneOfOptionOpCode (\r
+      OptionsOpCodeHandle,\r
+      NewMenuEntry->DisplayStringToken,\r
+      0,\r
+      EFI_IFR_TYPE_NUM_SIZE_16,\r
+      ((LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext)->BbsIndex\r
+      );\r
+  }\r
+\r
+  //\r
+  // Create OneOf for item "Disabled"\r
+  //\r
+  HiiCreateOneOfOptionOpCode (\r
+    OptionsOpCodeHandle,\r
+    STRING_TOKEN (STR_DISABLE_LEGACY_DEVICE),\r
+    0,\r
+    EFI_IFR_TYPE_NUM_SIZE_16,\r
+    0xFF\r
+    );\r
+\r
+  //\r
+  // Create oneof tag here for FD/HD/CD #1 #2\r
+  //\r
+  for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {\r
+    DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+    ASSERT (DefaultOpCodeHandle != NULL);\r
+\r
+    HiiCreateDefaultOpCode (\r
+      DefaultOpCodeHandle, \r
+      EFI_HII_DEFAULT_CLASS_STANDARD, \r
+      EFI_IFR_TYPE_NUM_SIZE_16, \r
+      *Default++\r
+      );\r
+  \r
+    //\r
+    // Create the string for oneof tag\r
+    //\r
+    UnicodeSPrint (String, sizeof (String), TypeStr, Index);\r
+    StrRef = HiiSetString (mLegacyBootOptionPrivate->HiiHandle, 0, String, NULL);\r
+\r
+    UnicodeSPrint (String, sizeof (String), TypeStrHelp, Index);\r
+    StrRefHelp = HiiSetString (mLegacyBootOptionPrivate->HiiHandle, 0, String, NULL);\r
+\r
+    HiiCreateOneOfOpCode (\r
+      mLegacyStartOpCodeHandle,\r
+      (EFI_QUESTION_ID) (Key + Index),\r
+      VARSTORE_ID_LEGACY_BOOT,\r
+      (UINT16) (Key + Index * 2 - CONFIG_OPTION_OFFSET),\r
+      StrRef,\r
+      StrRefHelp,\r
+      EFI_IFR_FLAG_CALLBACK,\r
+      EFI_IFR_NUMERIC_SIZE_2,\r
+      OptionsOpCodeHandle,\r
+      DefaultOpCodeHandle //NULL //\r
+      );\r
+      \r
+    HiiFreeOpCodeHandle (DefaultOpCodeHandle);\r
+  }\r
+\r
+  HiiUpdateForm (\r
+    mLegacyBootOptionPrivate->HiiHandle,\r
+    &mLegacyBootOptionGuid,\r
+    LEGACY_ORDER_CHANGE_FORM_ID,\r
+    mLegacyStartOpCodeHandle, \r
+    mLegacyEndOpCodeHandle   \r
+    );\r
+\r
+  HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
+}\r
+\r
+\r
+/**\r
+  Adjust question value when one question value has been changed.\r
+\r
+  @param QuestionId    The question id for the value changed question.\r
+  @param Value         The value for the changed question.\r
+\r
+**/\r
+VOID\r
+AdjustOptionValue (\r
+  IN  UINT16                                 QuestionId,\r
+  IN  EFI_IFR_TYPE_VALUE                     *Value\r
+  )\r
+{\r
+  UINTN                       Number;\r
+  BBS_TYPE                    BbsType;\r
+  LEGACY_DEV_ORDER_ENTRY      *DevOrder;\r
+  UINT16                      *Default;\r
+  LEGACY_BOOT_NV_DATA         *CurrentNVMap;\r
+  UINT16                      *CurrentVal;\r
+  UINTN                       Index;\r
+  UINTN                       Index2;\r
+  UINTN                       Index3;\r
+  UINTN                       NewValuePos;\r
+  UINTN                       OldValue;\r
+  UINTN                       NewValue;\r
+  UINT8                       *DisMap;\r
+  UINTN                       Pos;\r
+  UINTN                       Bit;\r
+\r
+  Number = 0;\r
+  BbsType = BBS_UNKNOWN;\r
+  CurrentVal = 0;\r
+  DevOrder = NULL;\r
+  Default = NULL;\r
+  NewValue = 0;\r
+  NewValuePos = 0;\r
+\r
+  //\r
+  // Update Select FD/HD/CD/NET/BEV Order Form\r
+  //\r
+  ASSERT ((QuestionId >= LEGACY_FD_QUESTION_ID) && (QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER));\r
+\r
+  CurrentNVMap = &mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData;\r
+  HiiGetBrowserData (&mLegacyBootOptionGuid, mLegacyBootStorageName, sizeof (LEGACY_BOOT_NV_DATA), (UINT8 *) CurrentNVMap);\r
+  DisMap  = mLegacyBootOptionPrivate->MaintainMapData->DisableMap;\r
+\r
+  if (QuestionId >= LEGACY_FD_QUESTION_ID && QuestionId < LEGACY_FD_QUESTION_ID + MAX_MENU_NUMBER) {\r
+    Number      = (UINT16) LegacyFDMenu.MenuNumber;\r
+    BbsType     = BBS_FLOPPY;\r
+    CurrentVal  = CurrentNVMap->LegacyFD;\r
+    Default     = mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData.LegacyFD;\r
+  } else if (QuestionId >= LEGACY_HD_QUESTION_ID && QuestionId < LEGACY_HD_QUESTION_ID + MAX_MENU_NUMBER) {\r
+    Number      = (UINT16) LegacyHDMenu.MenuNumber;\r
+    BbsType     = BBS_HARDDISK;\r
+    CurrentVal  = CurrentNVMap->LegacyHD;\r
+    Default     = mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData.LegacyHD;\r
+  } else if (QuestionId >= LEGACY_CD_QUESTION_ID && QuestionId < LEGACY_CD_QUESTION_ID + MAX_MENU_NUMBER) {\r
+    Number      = (UINT16) LegacyCDMenu.MenuNumber;\r
+    BbsType     = BBS_CDROM;\r
+    CurrentVal  = CurrentNVMap->LegacyCD;\r
+    Default     = mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData.LegacyCD;\r
+  } else if (QuestionId >= LEGACY_NET_QUESTION_ID && QuestionId < LEGACY_NET_QUESTION_ID + MAX_MENU_NUMBER) {\r
+    Number      = (UINT16) LegacyNETMenu.MenuNumber;\r
+    BbsType     = BBS_EMBED_NETWORK;\r
+    CurrentVal  = CurrentNVMap->LegacyNET;\r
+    Default     = mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData.LegacyNET;\r
+  } else if (QuestionId >= LEGACY_BEV_QUESTION_ID && QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER) {\r
+    Number      = (UINT16) LegacyBEVMenu.MenuNumber;\r
+    BbsType     = BBS_BEV_DEVICE;\r
+    CurrentVal  = CurrentNVMap->LegacyBEV;\r
+    Default     = mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData.LegacyBEV;\r
+  }\r
+  \r
+  //\r
+  //  First, find the different position\r
+  //  if there is change, it should be only one\r
+  //\r
+  for (Index = 0; Index < Number; Index++) {\r
+    if (CurrentVal[Index] != Default[Index]) {\r
+      OldValue  = Default[Index];\r
+      NewValue  = CurrentVal[Index];\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (Index != Number) {\r
+    //\r
+    // there is change, now process\r
+    //\r
+    if (0xFF == NewValue) {\r
+      //\r
+      // This item will be disable\r
+      // Just move the items behind this forward to overlap it\r
+      //\r
+      Pos = OldValue / 8;\r
+      Bit = 7 - (OldValue % 8);\r
+      DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));\r
+      for (Index2 = Index; Index2 < Number - 1; Index2++) {\r
+        CurrentVal[Index2] = CurrentVal[Index2 + 1];\r
+      }\r
+\r
+      CurrentVal[Index2] = 0xFF;\r
+    } else {\r
+      for (Index2 = 0; Index2 < Number; Index2++) {\r
+        if (Index2 == Index) {\r
+          continue;\r
+        }\r
+\r
+        if (Default[Index2] == NewValue) {\r
+          //\r
+          // If NewValue is in OldLegacyDev array\r
+          // remember its old position\r
+          //\r
+          NewValuePos = Index2;\r
+          break;\r
+        }\r
+      }\r
+\r
+      if (Index2 != Number) {\r
+        //\r
+        // We will change current item to an existing item\r
+        // (It's hard to describe here, please read code, it's like a cycle-moving)\r
+        //\r
+        for (Index2 = NewValuePos; Index2 != Index;) {\r
+          if (NewValuePos < Index) {\r
+            CurrentVal[Index2] = Default[Index2 + 1];\r
+            Index2++;\r
+          } else {\r
+            CurrentVal[Index2] = Default[Index2 - 1];\r
+            Index2--;\r
+          }\r
+        }\r
+      } else {\r
+        //\r
+        // If NewValue is not in OldlegacyDev array, we are changing to a disabled item\r
+        // so we should modify DisMap to reflect the change\r
+        //\r
+        Pos = NewValue / 8;\r
+        Bit = 7 - (NewValue % 8);\r
+        DisMap[Pos] = (UINT8) (DisMap[Pos] & (~ (UINT8) (1 << Bit)));\r
+        if (0xFF != OldValue) {\r
+          //\r
+          // Because NewValue is a item that was disabled before\r
+          // so after changing the OldValue should be disabled\r
+          // actually we are doing a swap of enable-disable states of two items\r
+          //\r
+          Pos = OldValue / 8;\r
+          Bit = 7 - (OldValue % 8);\r
+          DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));\r
+        }\r
+      }\r
+    }\r
+    //\r
+    // To prevent DISABLE appears in the middle of the list\r
+    // we should perform a re-ordering\r
+    //\r
+    Index3 = Index;\r
+    Index = 0;\r
+    while (Index < Number) {\r
+      if (0xFF != CurrentVal[Index]) {\r
+        Index++;\r
+        continue;\r
+      }\r
+\r
+      Index2 = Index;\r
+      Index2++;\r
+      while (Index2 < Number) {\r
+        if (0xFF != CurrentVal[Index2]) {\r
+          break;\r
+        }\r
+\r
+        Index2++;\r
+      }\r
+\r
+      if (Index2 < Number) {\r
+        CurrentVal[Index]   = CurrentVal[Index2];\r
+        CurrentVal[Index2]  = 0xFF;\r
+      }\r
+\r
+      Index++;\r
+    }\r
+\r
+    //\r
+    // Return correct question value.\r
+    //\r
+    Value->u16 = CurrentVal[Index3];\r
+    CopyMem (Default, CurrentVal, sizeof (UINT16) * Number);\r
+  }\r
+\r
+  //\r
+  // Pass changed uncommitted data back to Form Browser\r
+  //\r
+  HiiSetBrowserData (&mLegacyBootOptionGuid, mLegacyBootStorageName, sizeof (LEGACY_BOOT_NV_DATA), (UINT8 *) CurrentNVMap, NULL);\r
+}\r
+\r
+/**\r
+  This call back function is registered with Boot Manager formset.\r
+  When user selects a boot option, this call back function will\r
+  be triggered. The boot option is saved for later processing.\r
+\r
+\r
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Action          Specifies the type of action taken by the browser.\r
+  @param QuestionId      A unique value which is sent to the original exporting driver\r
+                         so that it can identify the type of data to expect.\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           The callback successfully handled the action.\r
+  @retval  EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LegacyBootOptionCallback (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  EFI_BROWSER_ACTION                     Action,\r
+  IN  EFI_QUESTION_ID                        QuestionId,\r
+  IN  UINT8                                  Type,\r
+  IN  EFI_IFR_TYPE_VALUE                     *Value,\r
+  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest\r
+  )\r
+{\r
+  if (Action != EFI_BROWSER_ACTION_CHANGED && Action != EFI_BROWSER_ACTION_CHANGING) {\r
+    //\r
+    // Do nothing for other UEFI Action. Only do call back when data is changed.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if ((Value == NULL) || (ActionRequest == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
+    switch (QuestionId) {\r
+    case FORM_FLOPPY_BOOT_ID:\r
+    case FORM_HARDDISK_BOOT_ID:\r
+    case FORM_CDROM_BOOT_ID:\r
+    case FORM_NET_BOOT_ID:\r
+    case FORM_BEV_BOOT_ID:\r
+      UpdateLegacyDeviceOrderPage (QuestionId);\r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
+    if ((Value == NULL) || (ActionRequest == NULL)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if ((QuestionId >= LEGACY_FD_QUESTION_ID) && (QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER)) {\r
+      AdjustOptionValue(QuestionId, Value);\r
+    }\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Create a menu entry by given menu type.\r
+\r
+  @param MenuType        The Menu type to be created.\r
+\r
+  @retval NULL           If failed to create the menu.\r
+  @return the new menu entry.\r
+\r
+**/\r
+LEGACY_MENU_ENTRY *\r
+CreateMenuEntry (\r
+  VOID\r
+  )\r
+{\r
+  LEGACY_MENU_ENTRY *MenuEntry;\r
+\r
+  //\r
+  // Create new menu entry\r
+  //\r
+  MenuEntry = AllocateZeroPool (sizeof (LEGACY_MENU_ENTRY));\r
+  if (MenuEntry == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  MenuEntry->VariableContext = AllocateZeroPool (sizeof (LEGACY_DEVICE_CONTEXT));\r
+  if (MenuEntry->VariableContext == NULL) {\r
+    FreePool (MenuEntry);\r
+    return NULL;\r
+  }\r
+\r
+  MenuEntry->Signature        = LEGACY_MENU_ENTRY_SIGNATURE;\r
+  return MenuEntry;\r
+}\r
+\r
+/**\r
+\r
+  Base on the L"LegacyDevOrder" variable to build the current order data.\r
+\r
+**/\r
+VOID\r
+GetLegacyOptionsOrder (\r
+  VOID\r
+  )\r
+{\r
+  UINTN                       VarSize;\r
+  UINT8                       *VarData;\r
+  UINT8                       *VarTmp;\r
+  LEGACY_DEV_ORDER_ENTRY      *DevOrder;\r
+  UINT16                      *LegacyDev;\r
+  UINTN                       Index;\r
+  LEGACY_MENU_OPTION          *OptionMenu;\r
+  UINT16                      VarDevOrder;\r
+  UINTN                       Pos;\r
+  UINTN                       Bit;\r
+  UINT8                       *DisMap;\r
+\r
+  DisMap = ZeroMem (mLegacyBootOptionPrivate->MaintainMapData->DisableMap, sizeof (mLegacyBootOptionPrivate->MaintainMapData->DisableMap));\r
+\r
+  //\r
+  // Get Device Order from variable\r
+  //\r
+  GetVariable2 (VAR_LEGACY_DEV_ORDER, &gEfiLegacyDevOrderVariableGuid, (VOID **) &VarData, &VarSize);\r
+  VarTmp = VarData;\r
+  if (NULL != VarData) {\r
+    DevOrder    = (LEGACY_DEV_ORDER_ENTRY *) VarData;\r
+    while (VarData < VarTmp + VarSize) {\r
+      switch (DevOrder->BbsType) {\r
+      case BBS_FLOPPY:\r
+        LegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyFD;\r
+        OptionMenu = &LegacyFDMenu;\r
+        break;\r
+      \r
+      case BBS_HARDDISK:\r
+        LegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyHD;\r
+        OptionMenu = &LegacyHDMenu;\r
+        break;\r
+      \r
+      case BBS_CDROM:\r
+        LegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyCD;\r
+        OptionMenu = &LegacyCDMenu;\r
+        break;\r
+      \r
+      case BBS_EMBED_NETWORK:\r
+        LegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyNET;\r
+        OptionMenu = &LegacyNETMenu;\r
+        break;\r
+      \r
+      case BBS_BEV_DEVICE:\r
+        LegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyBEV;\r
+        OptionMenu = &LegacyBEVMenu;\r
+        break;\r
+      \r
+      case BBS_UNKNOWN:\r
+      default:\r
+        ASSERT (FALSE);\r
+        DEBUG ((DEBUG_ERROR, "Unsupported device type found!\n"));\r
+        break;\r
+      }\r
+\r
+      //\r
+      // Create oneof tag here for FD/HD/CD #1 #2\r
+      //\r
+      for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {  \r
+        VarDevOrder = *(UINT16 *) ((UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + Index * sizeof (UINT16));\r
+      \r
+        if (0xFF00 == (VarDevOrder & 0xFF00)) {\r
+          LegacyDev[Index]  = 0xFF;\r
+          Pos               = (VarDevOrder & 0xFF) / 8;\r
+          Bit               = 7 - ((VarDevOrder & 0xFF) % 8);\r
+          DisMap[Pos]       = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));\r
+        } else {\r
+          LegacyDev[Index] = VarDevOrder & 0xFF;\r
+        }\r
+      }\r
+\r
+      VarData += sizeof (BBS_TYPE);\r
+      VarData += *(UINT16 *) VarData;\r
+      DevOrder = (LEGACY_DEV_ORDER_ENTRY *) VarData;\r
+    }\r
+  }\r
+\r
+  CopyMem (&mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData, &mLegacyBootOptionPrivate->MaintainMapData->InitialNvData, sizeof (LEGACY_BOOT_NV_DATA));\r
+  CopyMem (&mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData, &mLegacyBootOptionPrivate->MaintainMapData->InitialNvData, sizeof (LEGACY_BOOT_NV_DATA));\r
+}\r
+\r
+/**\r
+\r
+  Build the LegacyFDMenu LegacyHDMenu LegacyCDMenu according to LegacyBios.GetBbsInfo().\r
+\r
+**/\r
+VOID\r
+GetLegacyOptions (\r
+  VOID\r
+  )\r
+{\r
+  LEGACY_MENU_ENTRY             *NewMenuEntry;\r
+  LEGACY_DEVICE_CONTEXT         *NewLegacyDevContext;\r
+  EFI_BOOT_MANAGER_LOAD_OPTION  *BootOption;\r
+  UINTN                         BootOptionCount;\r
+  UINT16                        Index;\r
+  UINTN                         FDNum;\r
+  UINTN                         HDNum;\r
+  UINTN                         CDNum;\r
+  UINTN                         NETNum;\r
+  UINTN                         BEVNum;\r
+\r
+  //\r
+  // Initialize Bbs Table Context from BBS info data\r
+  //\r
+  InitializeListHead (&LegacyFDMenu.Head);\r
+  InitializeListHead (&LegacyHDMenu.Head);\r
+  InitializeListHead (&LegacyCDMenu.Head);\r
+  InitializeListHead (&LegacyNETMenu.Head);\r
+  InitializeListHead (&LegacyBEVMenu.Head);\r
+\r
+  FDNum   = 0;\r
+  HDNum   = 0;\r
+  CDNum   = 0;\r
+  NETNum  = 0;\r
+  BEVNum  = 0;\r
+\r
+  EfiBootManagerConnectAll ();\r
+  \r
+  //\r
+  // for better user experience\r
+  // 1. User changes HD configuration (e.g.: unplug HDD), here we have a chance to remove the HDD boot option\r
+  // 2. User enables/disables UEFI PXE, here we have a chance to add/remove EFI Network boot option\r
+  //\r
+  EfiBootManagerRefreshAllBootOption ();\r
+\r
+  BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
+  for (Index = 0; Index < BootOptionCount; Index++) {\r
+    if ((DevicePathType (BootOption[Index].FilePath) != BBS_DEVICE_PATH) ||\r
+        (DevicePathSubType (BootOption[Index].FilePath) != BBS_BBS_DP)\r
+       ) {\r
+      continue;\r
+    }\r
+    ASSERT (BootOption[Index].OptionalDataSize == sizeof (LEGACY_BOOT_OPTION_BBS_DATA));\r
+    NewMenuEntry = CreateMenuEntry ();\r
+    ASSERT (NewMenuEntry != NULL);\r
+\r
+    NewLegacyDevContext              = (LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;\r
+    NewLegacyDevContext->BbsIndex    = ((LEGACY_BOOT_OPTION_BBS_DATA *) BootOption[Index].OptionalData)->BbsIndex;\r
+    NewLegacyDevContext->Description = AllocateCopyPool (StrSize (BootOption[Index].Description), BootOption[Index].Description);\r
+    ASSERT (NewLegacyDevContext->Description != NULL);\r
+\r
+    NewMenuEntry->DisplayString = NewLegacyDevContext->Description;\r
+    NewMenuEntry->HelpString    = NULL;\r
+\r
+    switch (((BBS_BBS_DEVICE_PATH *) BootOption[Index].FilePath)->DeviceType) {\r
+    case BBS_TYPE_FLOPPY:\r
+      InsertTailList (&LegacyFDMenu.Head, &NewMenuEntry->Link);\r
+      FDNum++;\r
+      break;\r
+\r
+    case BBS_TYPE_HARDDRIVE:\r
+      InsertTailList (&LegacyHDMenu.Head, &NewMenuEntry->Link);\r
+      HDNum++;\r
+      break;\r
+\r
+    case BBS_TYPE_CDROM:\r
+      InsertTailList (&LegacyCDMenu.Head, &NewMenuEntry->Link);\r
+      CDNum++;\r
+      break;\r
+\r
+    case BBS_TYPE_EMBEDDED_NETWORK:\r
+      InsertTailList (&LegacyNETMenu.Head, &NewMenuEntry->Link);\r
+      NETNum++;\r
+      break;\r
+\r
+    case BBS_TYPE_BEV:\r
+      InsertTailList (&LegacyBEVMenu.Head, &NewMenuEntry->Link);\r
+      BEVNum++;\r
+      break;\r
+    }\r
+  }\r
+\r
+  EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount);\r
+\r
+  LegacyFDMenu.MenuNumber   = FDNum;\r
+  LegacyHDMenu.MenuNumber   = HDNum;\r
+  LegacyCDMenu.MenuNumber   = CDNum;\r
+  LegacyNETMenu.MenuNumber  = NETNum;\r
+  LegacyBEVMenu.MenuNumber  = BEVNum;\r
+}\r
+\r
+\r
+/**\r
+\r
+  Install Boot Manager Menu driver.\r
+\r
+  @param ImageHandle     The image handle.\r
+  @param SystemTable     The system table.\r
+\r
+  @retval  EFI_SUCEESS  Install Boot manager menu success.\r
+  @retval  Other        Return error status.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LegacyBootMaintUiLibConstructor (\r
+  IN EFI_HANDLE                            ImageHandle,\r
+  IN EFI_SYSTEM_TABLE                      *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_LEGACY_BIOS_PROTOCOL          *LegacyBios;\r
+  LEGACY_BOOT_OPTION_CALLBACK_DATA  *LegacyBootOptionData;\r
+\r
+  Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Create LegacyBootOptionData structures for Driver Callback\r
+    //\r
+    LegacyBootOptionData = AllocateZeroPool (sizeof (LEGACY_BOOT_OPTION_CALLBACK_DATA));\r
+    ASSERT (LegacyBootOptionData != NULL);\r
+    \r
+    LegacyBootOptionData->MaintainMapData = AllocateZeroPool (sizeof (LEGACY_BOOT_MAINTAIN_DATA));\r
+    ASSERT (LegacyBootOptionData->MaintainMapData != NULL);\r
+\r
+    LegacyBootOptionData->ConfigAccess.ExtractConfig = LegacyBootOptionExtractConfig;\r
+    LegacyBootOptionData->ConfigAccess.RouteConfig   = LegacyBootOptionRouteConfig;\r
+    LegacyBootOptionData->ConfigAccess.Callback      = LegacyBootOptionCallback;\r
+\r
+    //\r
+    // Install Device Path Protocol and Config Access protocol to driver handle\r
+    //\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
+                    &LegacyBootOptionData->DriverHandle,\r
+                    &gEfiDevicePathProtocolGuid,\r
+                    &mLegacyBootOptionHiiVendorDevicePath,\r
+                    &gEfiHiiConfigAccessProtocolGuid,\r
+                    &LegacyBootOptionData->ConfigAccess,\r
+                    NULL\r
+                    );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Publish our HII data\r
+    //\r
+    LegacyBootOptionData->HiiHandle = HiiAddPackages (\r
+                                      &mLegacyBootOptionGuid,\r
+                                      LegacyBootOptionData->DriverHandle,\r
+                                      LegacyBootMaintUiVfrBin,\r
+                                      LegacyBootMaintUiLibStrings,\r
+                                      NULL\r
+                                      );\r
+    ASSERT (LegacyBootOptionData->HiiHandle != NULL);\r
+\r
+    mLegacyBootOptionPrivate = LegacyBootOptionData;\r
+\r
+    GetLegacyOptions ();\r
+\r
+    GetLegacyOptionsOrder();\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Destructor of Customized Display Library Instance.\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 destructor completed successfully.\r
+  @retval Other value   The destructor did not complete successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LegacyBootMaintUiLibDestructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  if (mLegacyBootOptionPrivate->DriverHandle != NULL) {\r
+    Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                    mLegacyBootOptionPrivate->DriverHandle,\r
+                    &gEfiDevicePathProtocolGuid,\r
+                    &mLegacyBootOptionHiiVendorDevicePath,\r
+                    &gEfiHiiConfigAccessProtocolGuid,\r
+                    &mLegacyBootOptionPrivate->ConfigAccess,\r
+                    NULL\r
+                    );\r
+    ASSERT_EFI_ERROR (Status);\r
+    \r
+    HiiRemovePackages (mLegacyBootOptionPrivate->HiiHandle);\r
+\r
+    FreePool (mLegacyBootOptionPrivate->MaintainMapData);\r
+    FreePool (mLegacyBootOptionPrivate);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUi.h b/IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUi.h
new file mode 100644 (file)
index 0000000..26a112b
--- /dev/null
@@ -0,0 +1,255 @@
+/** @file\r
+  Legacy boot maintainence Ui definition.\r
+\r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+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
+#ifndef _EFI_LEGACY_BOOT_OPTION_H_\r
+#define _EFI_LEGACY_BOOT_OPTION_H_\r
+\r
+#include <PiDxe.h>\r
+\r
+\r
+#include <Guid/GlobalVariable.h>\r
+#include <Guid/LegacyDevOrder.h>\r
+#include <Guid/MdeModuleHii.h>\r
+\r
+#include <Protocol/HiiConfigAccess.h>\r
+#include <Protocol/HiiConfigRouting.h>\r
+\r
+#include <Protocol/HiiDatabase.h>\r
+#include <Protocol/LegacyBios.h>\r
+\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/UefiBootManagerLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+\r
+#include "LegacyBootMaintUiVfr.h"\r
+\r
+#define CONFIG_OPTION_OFFSET    0x1200\r
+\r
+//\r
+// VarOffset that will be used to create question\r
+// all these values are computed from the structure\r
+// defined below\r
+//\r
+#define VAR_OFFSET(Field)              ((UINT16) ((UINTN) &(((LEGACY_BOOT_NV_DATA *) 0)->Field)))\r
+\r
+//\r
+// Question Id of Zero is invalid, so add an offset to it\r
+//\r
+#define QUESTION_ID(Field)             (VAR_OFFSET (Field) + CONFIG_OPTION_OFFSET)\r
+\r
+\r
+#define LEGACY_FD_QUESTION_ID           QUESTION_ID (LegacyFD)\r
+#define LEGACY_HD_QUESTION_ID           QUESTION_ID (LegacyHD)\r
+#define LEGACY_CD_QUESTION_ID           QUESTION_ID (LegacyCD)\r
+#define LEGACY_NET_QUESTION_ID          QUESTION_ID (LegacyNET)\r
+#define LEGACY_BEV_QUESTION_ID          QUESTION_ID (LegacyBEV)\r
+\r
+\r
+//\r
+// String Contant\r
+//\r
+#define STR_FLOPPY          L"Floppy Drive #%02x"\r
+#define STR_HARDDISK        L"HardDisk Drive #%02x"\r
+#define STR_CDROM           L"ATAPI CDROM Drive #%02x"\r
+#define STR_NET             L"NET Drive #%02x"\r
+#define STR_BEV             L"BEV Drive #%02x"\r
+\r
+#define STR_FLOPPY_HELP     L"Select Floppy Drive #%02x"\r
+#define STR_HARDDISK_HELP   L"Select HardDisk Drive #%02x"\r
+#define STR_CDROM_HELP      L"Select ATAPI CDROM Drive #%02x"\r
+#define STR_NET_HELP        L"NET Drive #%02x"\r
+#define STR_BEV_HELP        L"BEV Drive #%02x"\r
+\r
+#define STR_FLOPPY_TITLE    L"Set Legacy Floppy Drive Order"\r
+#define STR_HARDDISK_TITLE  L"Set Legacy HardDisk Drive Order"\r
+#define STR_CDROM_TITLE     L"Set Legacy CDROM Drive Order"\r
+#define STR_NET_TITLE       L"Set Legacy NET Drive Order"\r
+#define STR_BEV_TITLE       L"Set Legacy BEV Drive Order"\r
+\r
+//\r
+// These are the VFR compiler generated data representing our VFR data.\r
+//\r
+extern UINT8 LegacyBootMaintUiVfrBin[];\r
+\r
+#pragma pack(1)\r
+\r
+///\r
+/// HII specific Vendor Device Path definition.\r
+///\r
+typedef struct {\r
+  VENDOR_DEVICE_PATH             VendorDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL       End;\r
+} HII_VENDOR_DEVICE_PATH;\r
+\r
+\r
+\r
+//\r
+// Variable created with this flag will be "Efi:...."\r
+//\r
+#define VAR_FLAG  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE\r
+\r
+\r
+#define LEGACY_BOOT_OPTION_CALLBACK_DATA_SIGNATURE  SIGNATURE_32 ('L', 'G', 'C', 'B')\r
+\r
+typedef struct {\r
+  UINTN                            Signature;\r
+\r
+  //\r
+  // HII relative handles\r
+  //\r
+  EFI_HII_HANDLE                   HiiHandle;\r
+  EFI_HANDLE                       DriverHandle;\r
+\r
+  //\r
+  // Produced protocols\r
+  //\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL   ConfigAccess;\r
+\r
+  //\r
+  // Maintain the data.\r
+  //\r
+  LEGACY_BOOT_MAINTAIN_DATA        *MaintainMapData;\r
+} LEGACY_BOOT_OPTION_CALLBACK_DATA;\r
+\r
+//\r
+// All of the signatures that will be used in list structure\r
+//\r
+#define LEGACY_MENU_OPTION_SIGNATURE      SIGNATURE_32 ('m', 'e', 'n', 'u')\r
+#define LEGACY_MENU_ENTRY_SIGNATURE       SIGNATURE_32 ('e', 'n', 't', 'r')\r
+\r
+#define LEGACY_LEGACY_DEV_CONTEXT_SELECT  0x9\r
+\r
+typedef struct {\r
+  UINTN           Signature;\r
+  LIST_ENTRY      Head;\r
+  UINTN           MenuNumber;\r
+} LEGACY_MENU_OPTION;\r
+\r
+typedef struct {\r
+  UINT16    BbsIndex;\r
+  CHAR16    *Description;\r
+} LEGACY_DEVICE_CONTEXT;\r
+\r
+typedef struct {\r
+  UINTN           Signature;\r
+  LIST_ENTRY      Link;\r
+  UINTN           OptionNumber;\r
+  UINT16          *DisplayString;\r
+  UINT16          *HelpString;\r
+  EFI_STRING_ID   DisplayStringToken;\r
+  EFI_STRING_ID   HelpStringToken;\r
+  VOID            *VariableContext;\r
+} LEGACY_MENU_ENTRY;\r
+\r
+typedef struct {\r
+  UINT16     BbsIndex;\r
+} LEGACY_BOOT_OPTION_BBS_DATA;\r
+\r
+#pragma pack()\r
+\r
+/**\r
+  This call back function is registered with Boot Manager formset.\r
+  When user selects a boot option, this call back function will\r
+  be triggered. The boot option is saved for later processing.\r
+\r
+\r
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Action          Specifies the type of action taken by the browser.\r
+  @param QuestionId      A unique value which is sent to the original exporting driver\r
+                         so that it can identify the type of data to expect.\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           The callback successfully handled the action.\r
+  @retval  EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LegacyBootOptionCallback (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  EFI_BROWSER_ACTION                     Action,\r
+  IN  EFI_QUESTION_ID                        QuestionId,\r
+  IN  UINT8                                  Type,\r
+  IN  EFI_IFR_TYPE_VALUE                     *Value,\r
+  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest\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
+\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
+LegacyBootOptionExtractConfig (\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
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+\r
+  @param This            - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Configuration   - A null-terminated Unicode string in <ConfigResp> 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
+LegacyBootOptionRouteConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  CONST EFI_STRING                       Configuration,\r
+  OUT EFI_STRING                             *Progress\r
+  );\r
+\r
+#endif\r
diff --git a/IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiLib.inf b/IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiLib.inf
new file mode 100644 (file)
index 0000000..3109071
--- /dev/null
@@ -0,0 +1,68 @@
+## @file\r
+#  Legacy Boot Maintainence UI module is library for BDS phase.\r
+#\r
+#  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+#  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
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = LegacyBootMaintUiLib\r
+  FILE_GUID                      = e6f7f038-3ed9-401a-af1f-5ea7bf644d34\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = NULL|DXE_DRIVER UEFI_APPLICATION\r
+  CONSTRUCTOR                    = LegacyBootMaintUiLibConstructor\r
+  DESTRUCTOR                     = LegacyBootMaintUiLibDestructor\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]\r
+  LegacyBootMaintUiVfr.h\r
+  LegacyBootMaintUi.h\r
+  LegacyBootMaintUiVfr.Vfr\r
+  LegacyBootMaintUiStrings.uni\r
+  LegacyBootMaintUi.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec\r
+  IntelFrameworkPkg/IntelFrameworkPkg.dec\r
+\r
+[LibraryClasses]\r
+  DevicePathLib\r
+  BaseLib\r
+  UefiRuntimeServicesTableLib\r
+  UefiBootServicesTableLib\r
+  DebugLib\r
+  HiiLib\r
+  MemoryAllocationLib\r
+  UefiBootManagerLib\r
+  UefiLib\r
+  PrintLib\r
+  BaseMemoryLib\r
+\r
+[Guids]\r
+  gEfiIfrTianoGuid\r
+  gEfiIfrBootMaintenanceGuid\r
+  gEfiLegacyDevOrderVariableGuid\r
+\r
+[Protocols]\r
+  gEfiHiiConfigAccessProtocolGuid               ## PROTOCOL CONSUMES\r
+  gEfiLegacyBiosProtocolGuid\r
+  gEfiHiiConfigRoutingProtocolGuid\r
+\r
+[Depex]\r
+  gEfiHiiDatabaseProtocolGuid\r
+\r
diff --git a/IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiStrings.uni b/IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiStrings.uni
new file mode 100644 (file)
index 0000000..3cdfbdb
Binary files /dev/null and b/IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiStrings.uni differ
diff --git a/IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiVfr.Vfr b/IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiVfr.Vfr
new file mode 100644 (file)
index 0000000..882da99
--- /dev/null
@@ -0,0 +1,73 @@
+///** @file\r
+//  \r
+//    Browser formset.\r
+//  \r
+//  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+//  This program and the accompanying materials\r
+//  are licensed and made available under the terms and conditions of the BSD License\r
+//  which accompanies this distribution.  The full text of the license may be found at\r
+//  http://opensource.org/licenses/bsd-license.php\r
+//  \r
+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+//  \r
+//**/\r
+\r
+#include "LegacyBootMaintUiVfr.h"\r
+\r
+\r
+formset\r
+  guid      = LEGACY_BOOT_OPTION_FORMSET_GUID,\r
+  title     = STRING_TOKEN(STR_LEGACY_BOOT_PROMPT),\r
+  help      = STRING_TOKEN(STR_LEGACY_BOOT_HELP),\r
+  classguid = EFI_IFR_BOOT_MAINTENANCE_GUID,\r
+  \r
+  varstore LEGACY_BOOT_NV_DATA,\r
+    varid = VARSTORE_ID_LEGACY_BOOT,\r
+    name = LegacyBootData,\r
+    guid = LEGACY_BOOT_OPTION_FORMSET_GUID;\r
+    \r
+  form formid = LEGACY_BOOT_FORM_ID,\r
+       title  = STRING_TOKEN(STR_LEGACY_BOOT_PROMPT);\r
+       \r
+    goto LEGACY_ORDER_CHANGE_FORM_ID,\r
+         prompt = STRING_TOKEN(STR_FORM_FLOPPY_BOOT_TITLE),\r
+         help = STRING_TOKEN(STR_FORM_FLOPPY_BOOT_HELP),\r
+         flags = INTERACTIVE,\r
+         key = FORM_FLOPPY_BOOT_ID;\r
+\r
+    goto LEGACY_ORDER_CHANGE_FORM_ID,\r
+         prompt = STRING_TOKEN(STR_FORM_HARDDISK_BOOT_TITLE),\r
+         help = STRING_TOKEN(STR_FORM_HARDDISK_BOOT_HELP),\r
+         flags = INTERACTIVE,\r
+         key = FORM_HARDDISK_BOOT_ID;\r
+\r
+    goto LEGACY_ORDER_CHANGE_FORM_ID,\r
+         prompt = STRING_TOKEN(STR_FORM_CDROM_BOOT_TITLE),\r
+         help = STRING_TOKEN(STR_FORM_CDROM_BOOT_HELP),\r
+         flags = INTERACTIVE,\r
+         key = FORM_CDROM_BOOT_ID;\r
+\r
+    goto LEGACY_ORDER_CHANGE_FORM_ID,\r
+         prompt = STRING_TOKEN(STR_FORM_NET_BOOT_TITLE),\r
+         help = STRING_TOKEN(STR_FORM_NET_BOOT_HELP),\r
+         flags = INTERACTIVE,\r
+         key = FORM_NET_BOOT_ID;\r
+\r
+    goto LEGACY_ORDER_CHANGE_FORM_ID,\r
+         prompt = STRING_TOKEN(STR_FORM_BEV_BOOT_TITLE),\r
+         help = STRING_TOKEN(STR_FORM_BEV_BOOT_HELP),\r
+         flags = INTERACTIVE,\r
+         key = FORM_BEV_BOOT_ID;\r
+         \r
+  endform;\r
+\r
+  form formid = LEGACY_ORDER_CHANGE_FORM_ID,\r
+       title  = STRING_TOKEN(STR_ORDER_CHANGE_PROMPT);\r
+       \r
+       label FORM_BOOT_LEGACY_DEVICE_ID;\r
+       label FORM_BOOT_LEGACY_LABEL_END;\r
+         \r
+  endform;\r
+\r
+endformset;\r
diff --git a/IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiVfr.h b/IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiVfr.h
new file mode 100644 (file)
index 0000000..afa72b8
--- /dev/null
@@ -0,0 +1,85 @@
+/** @file\r
+  Legacy Boot Maintainence UI definition.\r
+\r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+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
+#ifndef _EFI_LEGACY_BOOT_OPTION_VFR_H_\r
+#define _EFI_LEGACY_BOOT_OPTION_VFR_H_\r
+\r
+#include <Guid/HiiBootMaintenanceFormset.h>\r
+\r
+#define MAX_MENU_NUMBER 100\r
+\r
+#define LEGACY_BOOT_OPTION_FORMSET_GUID  { 0x6bc75598, 0x89b4, 0x483d, 0x91, 0x60, 0x7f, 0x46, 0x9a, 0x96, 0x35, 0x31 }\r
+\r
+#define VARSTORE_ID_LEGACY_BOOT      0x0001\r
+\r
+\r
+#define LEGACY_BOOT_FORM_ID          0x1000\r
+#define LEGACY_ORDER_CHANGE_FORM_ID  0x1001\r
+\r
+\r
+#define FORM_FLOPPY_BOOT_ID          0x2000\r
+#define FORM_HARDDISK_BOOT_ID        0x2001\r
+#define FORM_CDROM_BOOT_ID           0x2002\r
+#define FORM_NET_BOOT_ID             0x2003\r
+#define FORM_BEV_BOOT_ID             0x2004\r
+\r
+\r
+\r
+#define FORM_BOOT_LEGACY_DEVICE_ID   0x9000\r
+#define FORM_BOOT_LEGACY_LABEL_END   0x9001\r
+\r
+\r
+#pragma pack(1)\r
+\r
+///\r
+/// This is the structure that will be used to store the\r
+/// question's current value. Use it at initialize time to\r
+/// set default value for each question. When using at run\r
+/// time, this map is returned by the callback function,\r
+/// so dynamically changing the question's value will be\r
+/// possible through this mechanism\r
+///\r
+typedef struct {\r
+  //\r
+  // Legacy Device Order Selection Storage\r
+  //\r
+  UINT16   LegacyFD[MAX_MENU_NUMBER];\r
+  UINT16   LegacyHD[MAX_MENU_NUMBER];\r
+  UINT16   LegacyCD[MAX_MENU_NUMBER];\r
+  UINT16   LegacyNET[MAX_MENU_NUMBER];\r
+  UINT16   LegacyBEV[MAX_MENU_NUMBER];\r
+} LEGACY_BOOT_NV_DATA;\r
+\r
+///\r
+/// This is the structure that will be used to store the\r
+/// question's current value. Use it at initialize time to\r
+/// set default value for each question. When using at run\r
+/// time, this map is returned by the callback function,\r
+/// so dynamically changing the question's value will be\r
+/// possible through this mechanism\r
+///\r
+typedef struct {\r
+  //\r
+  // Legacy Device Order Selection Storage\r
+  //\r
+  LEGACY_BOOT_NV_DATA   InitialNvData;\r
+  LEGACY_BOOT_NV_DATA   CurrentNvData;\r
+  LEGACY_BOOT_NV_DATA   LastTimeNvData;\r
+  UINT8                 DisableMap[32];\r
+} LEGACY_BOOT_MAINTAIN_DATA;\r
+\r
+#pragma pack()\r
+\r
+#endif\r